author | lagergren |
Fri, 26 Sep 2014 18:47:20 +0200 | |
changeset 26886 | 18c744ab4df2 |
parent 26768 | 751b0f427090 |
child 27209 | 30d8609b9561 |
permissions | -rw-r--r-- |
16147 | 1 |
/* |
16151 | 2 |
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. |
16147 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
7 |
* published by the Free Software Foundation. Oracle designates this |
|
8 |
* particular file as subject to the "Classpath" exception as provided |
|
9 |
* by Oracle in the LICENSE file that accompanied this code. |
|
10 |
* |
|
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
24 |
*/ |
|
25 |
||
26 |
package jdk.nashorn.internal.runtime; |
|
27 |
||
24751 | 28 |
import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup; |
16147 | 29 |
import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCall; |
30 |
import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup; |
|
24719 | 31 |
import static jdk.nashorn.internal.codegen.ObjectClassGenerator.OBJECT_FIELDS_ONLY; |
17239
6dd68632cdcd
8011065: Problems when script implements an interface with variadic methods
attila
parents:
17236
diff
changeset
|
32 |
import static jdk.nashorn.internal.lookup.Lookup.MH; |
16147 | 33 |
import static jdk.nashorn.internal.runtime.ECMAErrors.referenceError; |
34 |
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; |
|
24719 | 35 |
import static jdk.nashorn.internal.runtime.JSType.UNDEFINED_DOUBLE; |
36 |
import static jdk.nashorn.internal.runtime.JSType.UNDEFINED_INT; |
|
37 |
import static jdk.nashorn.internal.runtime.JSType.UNDEFINED_LONG; |
|
16147 | 38 |
import static jdk.nashorn.internal.runtime.PropertyDescriptor.CONFIGURABLE; |
39 |
import static jdk.nashorn.internal.runtime.PropertyDescriptor.ENUMERABLE; |
|
40 |
import static jdk.nashorn.internal.runtime.PropertyDescriptor.GET; |
|
41 |
import static jdk.nashorn.internal.runtime.PropertyDescriptor.SET; |
|
42 |
import static jdk.nashorn.internal.runtime.PropertyDescriptor.VALUE; |
|
43 |
import static jdk.nashorn.internal.runtime.PropertyDescriptor.WRITABLE; |
|
44 |
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; |
|
24719 | 45 |
import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT; |
46 |
import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.isValid; |
|
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
47 |
import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndex; |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
48 |
import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex; |
24720 | 49 |
import static jdk.nashorn.internal.runtime.linker.NashornGuards.explicitInstanceOfCheck; |
16147 | 50 |
import java.lang.invoke.MethodHandle; |
51 |
import java.lang.invoke.MethodHandles; |
|
52 |
import java.lang.invoke.MethodType; |
|
23084
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
53 |
import java.lang.invoke.SwitchPoint; |
16147 | 54 |
import java.util.AbstractMap; |
55 |
import java.util.ArrayList; |
|
56 |
import java.util.Arrays; |
|
57 |
import java.util.Collection; |
|
58 |
import java.util.Collections; |
|
59 |
import java.util.HashSet; |
|
60 |
import java.util.Iterator; |
|
61 |
import java.util.LinkedHashSet; |
|
62 |
import java.util.List; |
|
63 |
import java.util.Map; |
|
64 |
import java.util.Set; |
|
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
16226
diff
changeset
|
65 |
import jdk.internal.dynalink.CallSiteDescriptor; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
16226
diff
changeset
|
66 |
import jdk.internal.dynalink.linker.GuardedInvocation; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
16226
diff
changeset
|
67 |
import jdk.internal.dynalink.linker.LinkRequest; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
16226
diff
changeset
|
68 |
import jdk.internal.dynalink.support.CallSiteDescriptorFactory; |
16147 | 69 |
import jdk.nashorn.internal.codegen.CompilerConstants.Call; |
16240
e1468b33e201
8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
16234
diff
changeset
|
70 |
import jdk.nashorn.internal.codegen.ObjectClassGenerator; |
24719 | 71 |
import jdk.nashorn.internal.codegen.types.Type; |
17239
6dd68632cdcd
8011065: Problems when script implements an interface with variadic methods
attila
parents:
17236
diff
changeset
|
72 |
import jdk.nashorn.internal.lookup.Lookup; |
16147 | 73 |
import jdk.nashorn.internal.objects.AccessorPropertyDescriptor; |
74 |
import jdk.nashorn.internal.objects.DataPropertyDescriptor; |
|
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
75 |
import jdk.nashorn.internal.objects.Global; |
24719 | 76 |
import jdk.nashorn.internal.objects.NativeArray; |
16147 | 77 |
import jdk.nashorn.internal.runtime.arrays.ArrayData; |
18318
5e4244619d79
8012291: NativeArray is inconsistent in using long for length and index in some places and int for the same in other places
hannesw
parents:
17978
diff
changeset
|
78 |
import jdk.nashorn.internal.runtime.arrays.ArrayIndex; |
16147 | 79 |
import jdk.nashorn.internal.runtime.linker.Bootstrap; |
17239
6dd68632cdcd
8011065: Problems when script implements an interface with variadic methods
attila
parents:
17236
diff
changeset
|
80 |
import jdk.nashorn.internal.runtime.linker.LinkerCallSite; |
16147 | 81 |
import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor; |
82 |
import jdk.nashorn.internal.runtime.linker.NashornGuards; |
|
83 |
||
84 |
/** |
|
85 |
* Base class for generic JavaScript objects. |
|
86 |
* <p> |
|
87 |
* Notes: |
|
88 |
* <ul> |
|
89 |
* <li>The map is used to identify properties in the object.</li> |
|
90 |
* <li>If the map is modified then it must be cloned and replaced. This notifies |
|
91 |
* any code that made assumptions about the object that things have changed. |
|
92 |
* Ex. CallSites that have been validated must check to see if the map has |
|
93 |
* changed (or a map from a different object type) and hence relink the method |
|
94 |
* to call.</li> |
|
95 |
* <li>Modifications of the map include adding/deleting attributes or changing a |
|
96 |
* function field value.</li> |
|
97 |
* </ul> |
|
98 |
*/ |
|
99 |
||
23084
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
100 |
public abstract class ScriptObject implements PropertyAccess { |
24281 | 101 |
/** __proto__ special property name inside object literals. ES6 draft. */ |
19881
d92851923f86
8024174: Setting __proto__ property in Object literal should be supported
sundar
parents:
19880
diff
changeset
|
102 |
public static final String PROTO_PROPERTY_NAME = "__proto__"; |
16147 | 103 |
|
104 |
/** Search fall back routine name for "no such method" */ |
|
25422
199a23bee487
8049524: Global object initialization via javax.script API should be minimal
sundar
parents:
25421
diff
changeset
|
105 |
public static final String NO_SUCH_METHOD_NAME = "__noSuchMethod__"; |
16147 | 106 |
|
107 |
/** Search fall back routine name for "no such property" */ |
|
25422
199a23bee487
8049524: Global object initialization via javax.script API should be minimal
sundar
parents:
25421
diff
changeset
|
108 |
public static final String NO_SUCH_PROPERTY_NAME = "__noSuchProperty__"; |
16147 | 109 |
|
110 |
/** Per ScriptObject flag - is this a scope object? */ |
|
24720 | 111 |
public static final int IS_SCOPE = 1 << 0; |
16147 | 112 |
|
113 |
/** Per ScriptObject flag - is this an array object? */ |
|
24720 | 114 |
public static final int IS_ARRAY = 1 << 1; |
16147 | 115 |
|
116 |
/** Per ScriptObject flag - is this an arguments object? */ |
|
24720 | 117 |
public static final int IS_ARGUMENTS = 1 << 2; |
16147 | 118 |
|
18328
ebd24057f163
8015355: Array.prototype functions don't honour non-writable length and / or index properties
sundar
parents:
18318
diff
changeset
|
119 |
/** Is length property not-writable? */ |
24727 | 120 |
public static final int IS_LENGTH_NOT_WRITABLE = 1 << 3; |
18328
ebd24057f163
8015355: Array.prototype functions don't honour non-writable length and / or index properties
sundar
parents:
18318
diff
changeset
|
121 |
|
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
122 |
/** Is this a builtin object? */ |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
123 |
public static final int IS_BUILTIN = 1 << 4; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
124 |
|
24719 | 125 |
/** |
126 |
* Spill growth rate - by how many elements does {@link ScriptObject#primitiveSpill} and |
|
127 |
* {@link ScriptObject#objectSpill} when full |
|
128 |
*/ |
|
16147 | 129 |
public static final int SPILL_RATE = 8; |
130 |
||
131 |
/** Map to property information and accessor functions. Ordered by insertion. */ |
|
132 |
private PropertyMap map; |
|
133 |
||
17513 | 134 |
/** objects proto. */ |
135 |
private ScriptObject proto; |
|
136 |
||
16147 | 137 |
/** Object flags. */ |
138 |
private int flags; |
|
139 |
||
24719 | 140 |
/** Area for primitive properties added to object after instantiation, see {@link AccessorProperty} */ |
141 |
protected long[] primitiveSpill; |
|
142 |
||
143 |
/** Area for reference properties added to object after instantiation, see {@link AccessorProperty} */ |
|
144 |
protected Object[] objectSpill; |
|
145 |
||
146 |
/** |
|
147 |
* Number of elements in the spill. This may be less than the spill array lengths, if not all of |
|
148 |
* the allocated memory is in use |
|
149 |
*/ |
|
150 |
private int spillLength; |
|
16147 | 151 |
|
152 |
/** Indexed array data. */ |
|
153 |
private ArrayData arrayData; |
|
154 |
||
24769 | 155 |
/** Method handle to retrieve prototype of this object */ |
156 |
public static final MethodHandle GETPROTO = findOwnMH_V("getProto", ScriptObject.class); |
|
157 |
||
24777
ed1974940ff4
8044750: megamorphic getter for scope objects does not call __noSuchProperty__ hook
sundar
parents:
24772
diff
changeset
|
158 |
static final MethodHandle MEGAMORPHIC_GET = findOwnMH_V("megamorphicGet", Object.class, String.class, boolean.class); |
24727 | 159 |
static final MethodHandle GLOBALFILTER = findOwnMH_S("globalFilter", Object.class, Object.class); |
26377
028dad61662f
8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents:
26068
diff
changeset
|
160 |
static final MethodHandle DECLARE_AND_SET = findOwnMH_V("declareAndSet", void.class, String.class, Object.class); |
24719 | 161 |
|
162 |
private static final MethodHandle TRUNCATINGFILTER = findOwnMH_S("truncatingFilter", Object[].class, int.class, Object[].class); |
|
25421
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
163 |
private static final MethodHandle KNOWNFUNCPROPGUARDSELF = findOwnMH_S("knownFunctionPropertyGuardSelf", boolean.class, Object.class, PropertyMap.class, MethodHandle.class, ScriptFunction.class); |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
164 |
private static final MethodHandle KNOWNFUNCPROPGUARDPROTO = findOwnMH_S("knownFunctionPropertyGuardProto", boolean.class, Object.class, PropertyMap.class, MethodHandle.class, int.class, ScriptFunction.class); |
24719 | 165 |
|
166 |
private static final ArrayList<MethodHandle> PROTO_FILTERS = new ArrayList<>(); |
|
167 |
||
168 |
/** Method handle for getting the array data */ |
|
169 |
public static final Call GET_ARRAY = virtualCall(MethodHandles.lookup(), ScriptObject.class, "getArray", ArrayData.class); |
|
170 |
||
24725
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24721
diff
changeset
|
171 |
/** Method handle for getting the property map - debugging purposes */ |
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24721
diff
changeset
|
172 |
public static final Call GET_MAP = virtualCall(MethodHandles.lookup(), ScriptObject.class, "getMap", PropertyMap.class); |
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24721
diff
changeset
|
173 |
|
24719 | 174 |
/** Method handle for setting the array data */ |
175 |
public static final Call SET_ARRAY = virtualCall(MethodHandles.lookup(), ScriptObject.class, "setArray", void.class, ArrayData.class); |
|
22377 | 176 |
|
16147 | 177 |
/** Method handle for getting a function argument at a given index. Used from MapCreator */ |
19460
1b6d8e7b1cdf
8022782: publicLookup access failures in ScriptObject, ScriptFunction and ScriptFunction
sundar
parents:
19101
diff
changeset
|
178 |
public static final Call GET_ARGUMENT = virtualCall(MethodHandles.lookup(), ScriptObject.class, "getArgument", Object.class, int.class); |
16147 | 179 |
|
180 |
/** Method handle for setting a function argument at a given index. Used from MapCreator */ |
|
19460
1b6d8e7b1cdf
8022782: publicLookup access failures in ScriptObject, ScriptFunction and ScriptFunction
sundar
parents:
19101
diff
changeset
|
181 |
public static final Call SET_ARGUMENT = virtualCall(MethodHandles.lookup(), ScriptObject.class, "setArgument", void.class, int.class, Object.class); |
16147 | 182 |
|
16240
e1468b33e201
8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
16234
diff
changeset
|
183 |
/** Method handle for getting the proto of a ScriptObject */ |
16147 | 184 |
public static final Call GET_PROTO = virtualCallNoLookup(ScriptObject.class, "getProto", ScriptObject.class); |
185 |
||
24725
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24721
diff
changeset
|
186 |
/** Method handle for getting the proto of a ScriptObject */ |
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24721
diff
changeset
|
187 |
public static final Call GET_PROTO_DEPTH = virtualCallNoLookup(ScriptObject.class, "getProto", ScriptObject.class, int.class); |
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24721
diff
changeset
|
188 |
|
16240
e1468b33e201
8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
16234
diff
changeset
|
189 |
/** Method handle for setting the proto of a ScriptObject */ |
24751 | 190 |
public static final Call SET_GLOBAL_OBJECT_PROTO = staticCallNoLookup(ScriptObject.class, "setGlobalObjectProto", void.class, ScriptObject.class); |
16147 | 191 |
|
19881
d92851923f86
8024174: Setting __proto__ property in Object literal should be supported
sundar
parents:
19880
diff
changeset
|
192 |
/** Method handle for setting the proto of a ScriptObject after checking argument */ |
24772
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
193 |
public static final Call SET_PROTO_FROM_LITERAL = virtualCallNoLookup(ScriptObject.class, "setProtoFromLiteral", void.class, Object.class); |
19881
d92851923f86
8024174: Setting __proto__ property in Object literal should be supported
sundar
parents:
19880
diff
changeset
|
194 |
|
16240
e1468b33e201
8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
16234
diff
changeset
|
195 |
/** Method handle for setting the user accessors of a ScriptObject */ |
24719 | 196 |
//TODO fastpath this |
19460
1b6d8e7b1cdf
8022782: publicLookup access failures in ScriptObject, ScriptFunction and ScriptFunction
sundar
parents:
19101
diff
changeset
|
197 |
public static final Call SET_USER_ACCESSORS = virtualCall(MethodHandles.lookup(), ScriptObject.class, "setUserAccessors", void.class, String.class, ScriptFunction.class, ScriptFunction.class); |
16147 | 198 |
|
24719 | 199 |
static final MethodHandle[] SET_SLOW = new MethodHandle[] { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
200 |
findOwnMH_V("set", void.class, Object.class, int.class, int.class), |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
201 |
findOwnMH_V("set", void.class, Object.class, long.class, int.class), |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
202 |
findOwnMH_V("set", void.class, Object.class, double.class, int.class), |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
203 |
findOwnMH_V("set", void.class, Object.class, Object.class, int.class) |
24719 | 204 |
}; |
205 |
||
206 |
/** Method handle to reset the map of this ScriptObject */ |
|
207 |
public static final Call SET_MAP = virtualCallNoLookup(ScriptObject.class, "setMap", void.class, PropertyMap.class); |
|
208 |
||
209 |
static final MethodHandle CAS_MAP = findOwnMH_V("compareAndSetMap", boolean.class, PropertyMap.class, PropertyMap.class); |
|
210 |
static final MethodHandle EXTENSION_CHECK = findOwnMH_V("extensionCheck", boolean.class, boolean.class, String.class); |
|
211 |
static final MethodHandle ENSURE_SPILL_SIZE = findOwnMH_V("ensureSpillSize", Object.class, int.class); |
|
212 |
||
16147 | 213 |
/** |
214 |
* Constructor |
|
215 |
*/ |
|
216 |
public ScriptObject() { |
|
217 |
this(null); |
|
218 |
} |
|
219 |
||
220 |
/** |
|
221 |
* Constructor |
|
222 |
* |
|
223 |
* @param map {@link PropertyMap} used to create the initial object |
|
224 |
*/ |
|
225 |
public ScriptObject(final PropertyMap map) { |
|
226 |
if (Context.DEBUG) { |
|
227 |
ScriptObject.count++; |
|
228 |
} |
|
229 |
this.arrayData = ArrayData.EMPTY_ARRAY; |
|
18852
604c1d681b6f
8017084: Use spill properties for large object literals
hannesw
parents:
18851
diff
changeset
|
230 |
this.setMap(map == null ? PropertyMap.newMap() : map); |
18618
136279c4cbe6
8019157: Avoid calling ScriptObject.setProto() if possible
hannesw
parents:
18617
diff
changeset
|
231 |
} |
136279c4cbe6
8019157: Avoid calling ScriptObject.setProto() if possible
hannesw
parents:
18617
diff
changeset
|
232 |
|
136279c4cbe6
8019157: Avoid calling ScriptObject.setProto() if possible
hannesw
parents:
18617
diff
changeset
|
233 |
/** |
136279c4cbe6
8019157: Avoid calling ScriptObject.setProto() if possible
hannesw
parents:
18617
diff
changeset
|
234 |
* Constructor that directly sets the prototype to {@code proto} and property map to |
136279c4cbe6
8019157: Avoid calling ScriptObject.setProto() if possible
hannesw
parents:
18617
diff
changeset
|
235 |
* {@code map} without invalidating the map as calling {@link #setProto(ScriptObject)} |
136279c4cbe6
8019157: Avoid calling ScriptObject.setProto() if possible
hannesw
parents:
18617
diff
changeset
|
236 |
* would do. This should only be used for objects that are always constructed with the |
136279c4cbe6
8019157: Avoid calling ScriptObject.setProto() if possible
hannesw
parents:
18617
diff
changeset
|
237 |
* same combination of prototype and property map. |
136279c4cbe6
8019157: Avoid calling ScriptObject.setProto() if possible
hannesw
parents:
18617
diff
changeset
|
238 |
* |
136279c4cbe6
8019157: Avoid calling ScriptObject.setProto() if possible
hannesw
parents:
18617
diff
changeset
|
239 |
* @param proto the prototype object |
136279c4cbe6
8019157: Avoid calling ScriptObject.setProto() if possible
hannesw
parents:
18617
diff
changeset
|
240 |
* @param map intial {@link PropertyMap} |
136279c4cbe6
8019157: Avoid calling ScriptObject.setProto() if possible
hannesw
parents:
18617
diff
changeset
|
241 |
*/ |
136279c4cbe6
8019157: Avoid calling ScriptObject.setProto() if possible
hannesw
parents:
18617
diff
changeset
|
242 |
protected ScriptObject(final ScriptObject proto, final PropertyMap map) { |
24719 | 243 |
this(map); |
18618
136279c4cbe6
8019157: Avoid calling ScriptObject.setProto() if possible
hannesw
parents:
18617
diff
changeset
|
244 |
this.proto = proto; |
16147 | 245 |
} |
246 |
||
247 |
/** |
|
24719 | 248 |
* Constructor used to instantiate spill properties directly. Used from |
249 |
* SpillObjectCreator. |
|
250 |
* |
|
251 |
* @param map property maps |
|
252 |
* @param primitiveSpill primitive spills |
|
253 |
* @param objectSpill reference spills |
|
254 |
*/ |
|
255 |
public ScriptObject(final PropertyMap map, final long[] primitiveSpill, final Object[] objectSpill) { |
|
256 |
this(map); |
|
257 |
this.primitiveSpill = primitiveSpill; |
|
258 |
this.objectSpill = objectSpill; |
|
259 |
assert primitiveSpill.length == objectSpill.length : " primitive spill pool size is not the same length as object spill pool size"; |
|
260 |
this.spillLength = spillAllocationLength(primitiveSpill.length); |
|
261 |
} |
|
262 |
||
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
263 |
/** |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
264 |
* Check whether this is a global object |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
265 |
* @return true if global |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
266 |
*/ |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
267 |
protected boolean isGlobal() { |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
268 |
return false; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
269 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
270 |
|
24719 | 271 |
private static int alignUp(final int size, final int alignment) { |
24720 | 272 |
return size + alignment - 1 & ~(alignment - 1); |
24719 | 273 |
} |
274 |
||
275 |
/** |
|
276 |
* Given a number of properties, return the aligned to SPILL_RATE |
|
277 |
* buffer size required for the smallest spill pool needed to |
|
278 |
* house them |
|
279 |
* @param nProperties number of properties |
|
280 |
* @return property buffer length, a multiple of SPILL_RATE |
|
281 |
*/ |
|
282 |
public static int spillAllocationLength(final int nProperties) { |
|
283 |
return alignUp(nProperties, SPILL_RATE); |
|
284 |
} |
|
285 |
||
286 |
/** |
|
16147 | 287 |
* Copy all properties from the source object with their receiver bound to the source. |
288 |
* This function was known as mergeMap |
|
289 |
* |
|
290 |
* @param source The source object to copy from. |
|
291 |
*/ |
|
292 |
public void addBoundProperties(final ScriptObject source) { |
|
18860
e387fde9322a
8014785: Ability to extend global instance by binding properties of another object
sundar
parents:
18855
diff
changeset
|
293 |
addBoundProperties(source, source.getMap().getProperties()); |
e387fde9322a
8014785: Ability to extend global instance by binding properties of another object
sundar
parents:
18855
diff
changeset
|
294 |
} |
e387fde9322a
8014785: Ability to extend global instance by binding properties of another object
sundar
parents:
18855
diff
changeset
|
295 |
|
e387fde9322a
8014785: Ability to extend global instance by binding properties of another object
sundar
parents:
18855
diff
changeset
|
296 |
/** |
e387fde9322a
8014785: Ability to extend global instance by binding properties of another object
sundar
parents:
18855
diff
changeset
|
297 |
* Copy all properties from the array with their receiver bound to the source. |
e387fde9322a
8014785: Ability to extend global instance by binding properties of another object
sundar
parents:
18855
diff
changeset
|
298 |
* |
e387fde9322a
8014785: Ability to extend global instance by binding properties of another object
sundar
parents:
18855
diff
changeset
|
299 |
* @param source The source object to copy from. |
e387fde9322a
8014785: Ability to extend global instance by binding properties of another object
sundar
parents:
18855
diff
changeset
|
300 |
* @param properties The array of properties to copy. |
e387fde9322a
8014785: Ability to extend global instance by binding properties of another object
sundar
parents:
18855
diff
changeset
|
301 |
*/ |
e387fde9322a
8014785: Ability to extend global instance by binding properties of another object
sundar
parents:
18855
diff
changeset
|
302 |
public void addBoundProperties(final ScriptObject source, final Property[] properties) { |
16147 | 303 |
PropertyMap newMap = this.getMap(); |
304 |
||
18860
e387fde9322a
8014785: Ability to extend global instance by binding properties of another object
sundar
parents:
18855
diff
changeset
|
305 |
for (final Property property : properties) { |
16147 | 306 |
final String key = property.getKey(); |
21685
ff0187bbe5c0
8027700: function redeclaration checks missing for declaration binding instantiation
sundar
parents:
21441
diff
changeset
|
307 |
final Property oldProp = newMap.findProperty(key); |
ff0187bbe5c0
8027700: function redeclaration checks missing for declaration binding instantiation
sundar
parents:
21441
diff
changeset
|
308 |
if (oldProp == null) { |
16147 | 309 |
if (property instanceof UserAccessorProperty) { |
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
310 |
// Note: we copy accessor functions to this object which is semantically different from binding. |
16147 | 311 |
final UserAccessorProperty prop = this.newUserAccessors(key, property.getFlags(), property.getGetterFunction(source), property.getSetterFunction(source)); |
23084
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
312 |
newMap = newMap.addPropertyNoHistory(prop); |
16147 | 313 |
} else { |
18855
408663ef8f66
8020015: shared PropertyMaps should not be used without duplication
sundar
parents:
18852
diff
changeset
|
314 |
newMap = newMap.addPropertyBind((AccessorProperty)property, source); |
16147 | 315 |
} |
21685
ff0187bbe5c0
8027700: function redeclaration checks missing for declaration binding instantiation
sundar
parents:
21441
diff
changeset
|
316 |
} else { |
ff0187bbe5c0
8027700: function redeclaration checks missing for declaration binding instantiation
sundar
parents:
21441
diff
changeset
|
317 |
// See ECMA section 10.5 Declaration Binding Instantiation |
ff0187bbe5c0
8027700: function redeclaration checks missing for declaration binding instantiation
sundar
parents:
21441
diff
changeset
|
318 |
// step 5 processing each function declaration. |
ff0187bbe5c0
8027700: function redeclaration checks missing for declaration binding instantiation
sundar
parents:
21441
diff
changeset
|
319 |
if (property.isFunctionDeclaration() && !oldProp.isConfigurable()) { |
ff0187bbe5c0
8027700: function redeclaration checks missing for declaration binding instantiation
sundar
parents:
21441
diff
changeset
|
320 |
if (oldProp instanceof UserAccessorProperty || |
ff0187bbe5c0
8027700: function redeclaration checks missing for declaration binding instantiation
sundar
parents:
21441
diff
changeset
|
321 |
!(oldProp.isWritable() && oldProp.isEnumerable())) { |
ff0187bbe5c0
8027700: function redeclaration checks missing for declaration binding instantiation
sundar
parents:
21441
diff
changeset
|
322 |
throw typeError("cant.redefine.property", key, ScriptRuntime.safeToString(this)); |
ff0187bbe5c0
8027700: function redeclaration checks missing for declaration binding instantiation
sundar
parents:
21441
diff
changeset
|
323 |
} |
ff0187bbe5c0
8027700: function redeclaration checks missing for declaration binding instantiation
sundar
parents:
21441
diff
changeset
|
324 |
} |
16147 | 325 |
} |
326 |
} |
|
327 |
||
328 |
this.setMap(newMap); |
|
329 |
} |
|
330 |
||
331 |
/** |
|
18860
e387fde9322a
8014785: Ability to extend global instance by binding properties of another object
sundar
parents:
18855
diff
changeset
|
332 |
* Copy all properties from the array with their receiver bound to the source. |
e387fde9322a
8014785: Ability to extend global instance by binding properties of another object
sundar
parents:
18855
diff
changeset
|
333 |
* |
e387fde9322a
8014785: Ability to extend global instance by binding properties of another object
sundar
parents:
18855
diff
changeset
|
334 |
* @param source The source object to copy from. |
e387fde9322a
8014785: Ability to extend global instance by binding properties of another object
sundar
parents:
18855
diff
changeset
|
335 |
* @param properties The collection of accessor properties to copy. |
e387fde9322a
8014785: Ability to extend global instance by binding properties of another object
sundar
parents:
18855
diff
changeset
|
336 |
*/ |
e387fde9322a
8014785: Ability to extend global instance by binding properties of another object
sundar
parents:
18855
diff
changeset
|
337 |
public void addBoundProperties(final Object source, final AccessorProperty[] properties) { |
e387fde9322a
8014785: Ability to extend global instance by binding properties of another object
sundar
parents:
18855
diff
changeset
|
338 |
PropertyMap newMap = this.getMap(); |
e387fde9322a
8014785: Ability to extend global instance by binding properties of another object
sundar
parents:
18855
diff
changeset
|
339 |
|
e387fde9322a
8014785: Ability to extend global instance by binding properties of another object
sundar
parents:
18855
diff
changeset
|
340 |
for (final AccessorProperty property : properties) { |
e387fde9322a
8014785: Ability to extend global instance by binding properties of another object
sundar
parents:
18855
diff
changeset
|
341 |
final String key = property.getKey(); |
e387fde9322a
8014785: Ability to extend global instance by binding properties of another object
sundar
parents:
18855
diff
changeset
|
342 |
|
e387fde9322a
8014785: Ability to extend global instance by binding properties of another object
sundar
parents:
18855
diff
changeset
|
343 |
if (newMap.findProperty(key) == null) { |
e387fde9322a
8014785: Ability to extend global instance by binding properties of another object
sundar
parents:
18855
diff
changeset
|
344 |
newMap = newMap.addPropertyBind(property, source); |
e387fde9322a
8014785: Ability to extend global instance by binding properties of another object
sundar
parents:
18855
diff
changeset
|
345 |
} |
e387fde9322a
8014785: Ability to extend global instance by binding properties of another object
sundar
parents:
18855
diff
changeset
|
346 |
} |
e387fde9322a
8014785: Ability to extend global instance by binding properties of another object
sundar
parents:
18855
diff
changeset
|
347 |
|
e387fde9322a
8014785: Ability to extend global instance by binding properties of another object
sundar
parents:
18855
diff
changeset
|
348 |
this.setMap(newMap); |
e387fde9322a
8014785: Ability to extend global instance by binding properties of another object
sundar
parents:
18855
diff
changeset
|
349 |
} |
e387fde9322a
8014785: Ability to extend global instance by binding properties of another object
sundar
parents:
18855
diff
changeset
|
350 |
|
e387fde9322a
8014785: Ability to extend global instance by binding properties of another object
sundar
parents:
18855
diff
changeset
|
351 |
/** |
16159 | 352 |
* Bind the method handle to the specified receiver, while preserving its original type (it will just ignore the |
353 |
* first argument in lieu of the bound argument). |
|
16147 | 354 |
* @param methodHandle Method handle to bind to. |
355 |
* @param receiver Object to bind. |
|
356 |
* @return Bound method handle. |
|
357 |
*/ |
|
16159 | 358 |
static MethodHandle bindTo(final MethodHandle methodHandle, final Object receiver) { |
359 |
return MH.dropArguments(MH.bindTo(methodHandle, receiver), 0, methodHandle.type().parameterType(0)); |
|
16147 | 360 |
} |
361 |
||
362 |
/** |
|
363 |
* Return a property iterator. |
|
364 |
* @return Property iterator. |
|
365 |
*/ |
|
366 |
public Iterator<String> propertyIterator() { |
|
367 |
return new KeyIterator(this); |
|
368 |
} |
|
369 |
||
370 |
/** |
|
371 |
* Return a property value iterator. |
|
372 |
* @return Property value iterator. |
|
373 |
*/ |
|
374 |
public Iterator<Object> valueIterator() { |
|
375 |
return new ValueIterator(this); |
|
376 |
} |
|
377 |
||
378 |
/** |
|
379 |
* ECMA 8.10.1 IsAccessorDescriptor ( Desc ) |
|
380 |
* @return true if this has a {@link AccessorPropertyDescriptor} with a getter or a setter |
|
381 |
*/ |
|
382 |
public final boolean isAccessorDescriptor() { |
|
383 |
return has(GET) || has(SET); |
|
384 |
} |
|
385 |
||
386 |
/** |
|
387 |
* ECMA 8.10.2 IsDataDescriptor ( Desc ) |
|
388 |
* @return true if this has a {@link DataPropertyDescriptor}, i.e. the object has a property value and is writable |
|
389 |
*/ |
|
390 |
public final boolean isDataDescriptor() { |
|
391 |
return has(VALUE) || has(WRITABLE); |
|
392 |
} |
|
393 |
||
394 |
/** |
|
395 |
* ECMA 8.10.3 IsGenericDescriptor ( Desc ) |
|
396 |
* @return true if this has a descriptor describing an {@link AccessorPropertyDescriptor} or {@link DataPropertyDescriptor} |
|
397 |
*/ |
|
398 |
public final boolean isGenericDescriptor() { |
|
399 |
return isAccessorDescriptor() || isDataDescriptor(); |
|
400 |
} |
|
401 |
||
402 |
/** |
|
403 |
* ECMA 8.10.5 ToPropertyDescriptor ( Obj ) |
|
404 |
* |
|
405 |
* @return property descriptor |
|
406 |
*/ |
|
407 |
public final PropertyDescriptor toPropertyDescriptor() { |
|
23375
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23372
diff
changeset
|
408 |
final Global global = Context.getGlobal(); |
16147 | 409 |
|
410 |
final PropertyDescriptor desc; |
|
411 |
if (isDataDescriptor()) { |
|
412 |
if (has(SET) || has(GET)) { |
|
23375
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23372
diff
changeset
|
413 |
throw typeError(global, "inconsistent.property.descriptor"); |
16147 | 414 |
} |
415 |
||
416 |
desc = global.newDataDescriptor(UNDEFINED, false, false, false); |
|
417 |
} else if (isAccessorDescriptor()) { |
|
418 |
if (has(VALUE) || has(WRITABLE)) { |
|
23375
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23372
diff
changeset
|
419 |
throw typeError(global, "inconsistent.property.descriptor"); |
16147 | 420 |
} |
421 |
||
422 |
desc = global.newAccessorDescriptor(UNDEFINED, UNDEFINED, false, false); |
|
423 |
} else { |
|
424 |
desc = global.newGenericDescriptor(false, false); |
|
425 |
} |
|
426 |
||
427 |
return desc.fillFrom(this); |
|
428 |
} |
|
429 |
||
430 |
/** |
|
431 |
* ECMA 8.10.5 ToPropertyDescriptor ( Obj ) |
|
432 |
* |
|
433 |
* @param global global scope object |
|
434 |
* @param obj object to create property descriptor from |
|
435 |
* |
|
436 |
* @return property descriptor |
|
437 |
*/ |
|
23375
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23372
diff
changeset
|
438 |
public static PropertyDescriptor toPropertyDescriptor(final Global global, final Object obj) { |
16147 | 439 |
if (obj instanceof ScriptObject) { |
440 |
return ((ScriptObject)obj).toPropertyDescriptor(); |
|
441 |
} |
|
442 |
||
16256
f2d9a0c49914
8007002: Replace implicit exception throwing methods with explicit throws - simplify control flow and remove useless code
lagergren
parents:
16240
diff
changeset
|
443 |
throw typeError(global, "not.an.object", ScriptRuntime.safeToString(obj)); |
16147 | 444 |
} |
445 |
||
446 |
/** |
|
447 |
* ECMA 8.12.1 [[GetOwnProperty]] (P) |
|
448 |
* |
|
449 |
* @param key property key |
|
450 |
* |
|
451 |
* @return Returns the Property Descriptor of the named own property of this |
|
452 |
* object, or undefined if absent. |
|
453 |
*/ |
|
454 |
public Object getOwnPropertyDescriptor(final String key) { |
|
455 |
final Property property = getMap().findProperty(key); |
|
456 |
||
23375
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23372
diff
changeset
|
457 |
final Global global = Context.getGlobal(); |
16147 | 458 |
|
459 |
if (property != null) { |
|
460 |
final ScriptFunction get = property.getGetterFunction(this); |
|
461 |
final ScriptFunction set = property.getSetterFunction(this); |
|
462 |
||
463 |
final boolean configurable = property.isConfigurable(); |
|
464 |
final boolean enumerable = property.isEnumerable(); |
|
465 |
final boolean writable = property.isWritable(); |
|
466 |
||
467 |
if (property instanceof UserAccessorProperty) { |
|
468 |
return global.newAccessorDescriptor( |
|
24720 | 469 |
get != null ? |
16147 | 470 |
get : |
471 |
UNDEFINED, |
|
24720 | 472 |
set != null ? |
16147 | 473 |
set : |
474 |
UNDEFINED, |
|
475 |
configurable, |
|
476 |
enumerable); |
|
477 |
} |
|
478 |
||
479 |
return global.newDataDescriptor(getWithProperty(property), configurable, enumerable, writable); |
|
480 |
} |
|
481 |
||
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
482 |
final int index = getArrayIndex(key); |
16147 | 483 |
final ArrayData array = getArray(); |
484 |
||
485 |
if (array.has(index)) { |
|
486 |
return array.getDescriptor(global, index); |
|
487 |
} |
|
488 |
||
489 |
return UNDEFINED; |
|
490 |
} |
|
491 |
||
492 |
/** |
|
493 |
* ECMA 8.12.2 [[GetProperty]] (P) |
|
494 |
* |
|
495 |
* @param key property key |
|
496 |
* |
|
497 |
* @return Returns the fully populated Property Descriptor of the named property |
|
498 |
* of this object, or undefined if absent. |
|
499 |
*/ |
|
500 |
public Object getPropertyDescriptor(final String key) { |
|
501 |
final Object res = getOwnPropertyDescriptor(key); |
|
502 |
||
503 |
if (res != UNDEFINED) { |
|
504 |
return res; |
|
505 |
} else if (getProto() != null) { |
|
506 |
return getProto().getOwnPropertyDescriptor(key); |
|
507 |
} else { |
|
508 |
return UNDEFINED; |
|
509 |
} |
|
510 |
} |
|
511 |
||
512 |
/** |
|
513 |
* ECMA 8.12.9 [[DefineOwnProperty]] (P, Desc, Throw) |
|
514 |
* |
|
515 |
* @param key the property key |
|
516 |
* @param propertyDesc the property descriptor |
|
517 |
* @param reject is the property extensible - true means new definitions are rejected |
|
518 |
* |
|
519 |
* @return true if property was successfully defined |
|
520 |
*/ |
|
521 |
public boolean defineOwnProperty(final String key, final Object propertyDesc, final boolean reject) { |
|
23375
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23372
diff
changeset
|
522 |
final Global global = Context.getGlobal(); |
16147 | 523 |
final PropertyDescriptor desc = toPropertyDescriptor(global, propertyDesc); |
524 |
final Object current = getOwnPropertyDescriptor(key); |
|
525 |
final String name = JSType.toString(key); |
|
526 |
||
527 |
if (current == UNDEFINED) { |
|
528 |
if (isExtensible()) { |
|
529 |
// add a new own property |
|
530 |
addOwnProperty(key, desc); |
|
531 |
return true; |
|
532 |
} |
|
533 |
// new property added to non-extensible object |
|
534 |
if (reject) { |
|
16256
f2d9a0c49914
8007002: Replace implicit exception throwing methods with explicit throws - simplify control flow and remove useless code
lagergren
parents:
16240
diff
changeset
|
535 |
throw typeError(global, "object.non.extensible", name, ScriptRuntime.safeToString(this)); |
16147 | 536 |
} |
537 |
return false; |
|
538 |
} |
|
24719 | 539 |
|
16147 | 540 |
// modifying an existing property |
24719 | 541 |
final PropertyDescriptor currentDesc = (PropertyDescriptor)current; |
16147 | 542 |
final PropertyDescriptor newDesc = desc; |
543 |
||
24719 | 544 |
if (newDesc.type() == PropertyDescriptor.GENERIC && !newDesc.has(CONFIGURABLE) && !newDesc.has(ENUMERABLE)) { |
16147 | 545 |
// every descriptor field is absent |
546 |
return true; |
|
547 |
} |
|
548 |
||
23083
8c74590d5df1
8030197: Nashorn: Object.defineProperty() can be lured to change fixed NaN property
sundar
parents:
22386
diff
changeset
|
549 |
if (newDesc.hasAndEquals(currentDesc)) { |
16147 | 550 |
// every descriptor field of the new is same as the current |
551 |
return true; |
|
552 |
} |
|
553 |
||
24719 | 554 |
if (!currentDesc.isConfigurable()) { |
16147 | 555 |
if (newDesc.has(CONFIGURABLE) && newDesc.isConfigurable()) { |
556 |
// not configurable can not be made configurable |
|
557 |
if (reject) { |
|
16256
f2d9a0c49914
8007002: Replace implicit exception throwing methods with explicit throws - simplify control flow and remove useless code
lagergren
parents:
16240
diff
changeset
|
558 |
throw typeError(global, "cant.redefine.property", name, ScriptRuntime.safeToString(this)); |
16147 | 559 |
} |
560 |
return false; |
|
561 |
} |
|
562 |
||
563 |
if (newDesc.has(ENUMERABLE) && |
|
564 |
currentDesc.isEnumerable() != newDesc.isEnumerable()) { |
|
565 |
// cannot make non-enumerable as enumerable or vice-versa |
|
566 |
if (reject) { |
|
16256
f2d9a0c49914
8007002: Replace implicit exception throwing methods with explicit throws - simplify control flow and remove useless code
lagergren
parents:
16240
diff
changeset
|
567 |
throw typeError(global, "cant.redefine.property", name, ScriptRuntime.safeToString(this)); |
16147 | 568 |
} |
569 |
return false; |
|
570 |
} |
|
571 |
} |
|
572 |
||
573 |
int propFlags = Property.mergeFlags(currentDesc, newDesc); |
|
574 |
Property property = getMap().findProperty(key); |
|
575 |
||
576 |
if (currentDesc.type() == PropertyDescriptor.DATA && |
|
24719 | 577 |
(newDesc.type() == PropertyDescriptor.DATA || |
578 |
newDesc.type() == PropertyDescriptor.GENERIC)) { |
|
579 |
if (!currentDesc.isConfigurable() && !currentDesc.isWritable()) { |
|
16147 | 580 |
if (newDesc.has(WRITABLE) && newDesc.isWritable() || |
24719 | 581 |
newDesc.has(VALUE) && !ScriptRuntime.sameValue(currentDesc.getValue(), newDesc.getValue())) { |
16147 | 582 |
if (reject) { |
16256
f2d9a0c49914
8007002: Replace implicit exception throwing methods with explicit throws - simplify control flow and remove useless code
lagergren
parents:
16240
diff
changeset
|
583 |
throw typeError(global, "cant.redefine.property", name, ScriptRuntime.safeToString(this)); |
16147 | 584 |
} |
585 |
return false; |
|
586 |
} |
|
587 |
} |
|
588 |
||
589 |
final boolean newValue = newDesc.has(VALUE); |
|
24719 | 590 |
final Object value = newValue ? newDesc.getValue() : currentDesc.getValue(); |
591 |
||
16147 | 592 |
if (newValue && property != null) { |
593 |
// Temporarily clear flags. |
|
594 |
property = modifyOwnProperty(property, 0); |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
595 |
set(key, value, 0); |
24719 | 596 |
//this might change the map if we change types of the property |
597 |
//hence we need to read it again. note that we should probably |
|
598 |
//have the setter return the new property throughout and in |
|
599 |
//general respect Property return values from modify and add |
|
600 |
//functions - which we don't seem to do at all here :-( |
|
601 |
//There is already a bug filed to generify PropertyAccess so we |
|
602 |
//can have the setter return e.g. a Property |
|
603 |
property = getMap().findProperty(key); |
|
16147 | 604 |
} |
605 |
||
606 |
if (property == null) { |
|
607 |
// promoting an arrayData value to actual property |
|
608 |
addOwnProperty(key, propFlags, value); |
|
21441
0b98be59e3cb
8026858: Array length does not handle defined properties correctly
hannesw
parents:
21438
diff
changeset
|
609 |
checkIntegerKey(key); |
16147 | 610 |
} else { |
611 |
// Now set the new flags |
|
612 |
modifyOwnProperty(property, propFlags); |
|
613 |
} |
|
614 |
} else if (currentDesc.type() == PropertyDescriptor.ACCESSOR && |
|
615 |
(newDesc.type() == PropertyDescriptor.ACCESSOR || |
|
616 |
newDesc.type() == PropertyDescriptor.GENERIC)) { |
|
24719 | 617 |
if (!currentDesc.isConfigurable()) { |
618 |
if (newDesc.has(PropertyDescriptor.GET) && !ScriptRuntime.sameValue(currentDesc.getGetter(), newDesc.getGetter()) || |
|
619 |
newDesc.has(PropertyDescriptor.SET) && !ScriptRuntime.sameValue(currentDesc.getSetter(), newDesc.getSetter())) { |
|
16147 | 620 |
if (reject) { |
16256
f2d9a0c49914
8007002: Replace implicit exception throwing methods with explicit throws - simplify control flow and remove useless code
lagergren
parents:
16240
diff
changeset
|
621 |
throw typeError(global, "cant.redefine.property", name, ScriptRuntime.safeToString(this)); |
16147 | 622 |
} |
623 |
return false; |
|
624 |
} |
|
625 |
} |
|
626 |
// New set the new features. |
|
627 |
modifyOwnProperty(property, propFlags, |
|
628 |
newDesc.has(GET) ? newDesc.getGetter() : currentDesc.getGetter(), |
|
629 |
newDesc.has(SET) ? newDesc.getSetter() : currentDesc.getSetter()); |
|
630 |
} else { |
|
631 |
// changing descriptor type |
|
24719 | 632 |
if (!currentDesc.isConfigurable()) { |
16147 | 633 |
// not configurable can not be made configurable |
634 |
if (reject) { |
|
16256
f2d9a0c49914
8007002: Replace implicit exception throwing methods with explicit throws - simplify control flow and remove useless code
lagergren
parents:
16240
diff
changeset
|
635 |
throw typeError(global, "cant.redefine.property", name, ScriptRuntime.safeToString(this)); |
16147 | 636 |
} |
637 |
return false; |
|
638 |
} |
|
639 |
||
640 |
propFlags = 0; |
|
641 |
||
642 |
// Preserve only configurable and enumerable from current desc |
|
643 |
// if those are not overridden in the new property descriptor. |
|
24719 | 644 |
boolean value = newDesc.has(CONFIGURABLE) ? newDesc.isConfigurable() : currentDesc.isConfigurable(); |
16147 | 645 |
if (!value) { |
646 |
propFlags |= Property.NOT_CONFIGURABLE; |
|
647 |
} |
|
648 |
value = newDesc.has(ENUMERABLE)? newDesc.isEnumerable() : currentDesc.isEnumerable(); |
|
649 |
if (!value) { |
|
650 |
propFlags |= Property.NOT_ENUMERABLE; |
|
651 |
} |
|
652 |
||
653 |
final int type = newDesc.type(); |
|
654 |
if (type == PropertyDescriptor.DATA) { |
|
655 |
// get writable from the new descriptor |
|
656 |
value = newDesc.has(WRITABLE) && newDesc.isWritable(); |
|
24719 | 657 |
if (!value) { |
16147 | 658 |
propFlags |= Property.NOT_WRITABLE; |
659 |
} |
|
660 |
||
661 |
// delete the old property |
|
662 |
deleteOwnProperty(property); |
|
663 |
// add new data property |
|
664 |
addOwnProperty(key, propFlags, newDesc.getValue()); |
|
665 |
} else if (type == PropertyDescriptor.ACCESSOR) { |
|
666 |
if (property == null) { |
|
667 |
addOwnProperty(key, propFlags, |
|
668 |
newDesc.has(GET) ? newDesc.getGetter() : null, |
|
669 |
newDesc.has(SET) ? newDesc.getSetter() : null); |
|
670 |
} else { |
|
671 |
// Modify old property with the new features. |
|
672 |
modifyOwnProperty(property, propFlags, |
|
673 |
newDesc.has(GET) ? newDesc.getGetter() : null, |
|
674 |
newDesc.has(SET) ? newDesc.getSetter() : null); |
|
675 |
} |
|
676 |
} |
|
677 |
} |
|
678 |
||
679 |
checkIntegerKey(key); |
|
680 |
||
681 |
return true; |
|
682 |
} |
|
683 |
||
684 |
/** |
|
23761
5f351bdb2317
8037562: Nashorn: JSON.parse comes up with nonexistent entries if there are gaps between the keys
sundar
parents:
23375
diff
changeset
|
685 |
* Almost like defineOwnProperty(int,Object) for arrays this one does |
5f351bdb2317
8037562: Nashorn: JSON.parse comes up with nonexistent entries if there are gaps between the keys
sundar
parents:
23375
diff
changeset
|
686 |
* not add 'gap' elements (like the array one does). |
16147 | 687 |
* |
18318
5e4244619d79
8012291: NativeArray is inconsistent in using long for length and index in some places and int for the same in other places
hannesw
parents:
17978
diff
changeset
|
688 |
* @param index key for property |
16147 | 689 |
* @param value value to define |
690 |
*/ |
|
23761
5f351bdb2317
8037562: Nashorn: JSON.parse comes up with nonexistent entries if there are gaps between the keys
sundar
parents:
23375
diff
changeset
|
691 |
public void defineOwnProperty(final int index, final Object value) { |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
692 |
assert isValidArrayIndex(index) : "invalid array index"; |
18318
5e4244619d79
8012291: NativeArray is inconsistent in using long for length and index in some places and int for the same in other places
hannesw
parents:
17978
diff
changeset
|
693 |
final long longIndex = ArrayIndex.toLongIndex(index); |
24769 | 694 |
doesNotHaveEnsureDelete(longIndex, getArray().length(), false); |
25248
f3681ebb1f21
8048718: JSON.parse('{"0":0, "64":0}') throws ArrayindexOutOfBoundsException
sundar
parents:
25237
diff
changeset
|
695 |
setArray(getArray().ensure(longIndex)); |
16147 | 696 |
setArray(getArray().set(index, value, false)); |
697 |
} |
|
698 |
||
699 |
private void checkIntegerKey(final String key) { |
|
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
700 |
final int index = getArrayIndex(key); |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
701 |
|
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
702 |
if (isValidArrayIndex(index)) { |
16147 | 703 |
final ArrayData data = getArray(); |
704 |
||
705 |
if (data.has(index)) { |
|
706 |
setArray(data.delete(index)); |
|
707 |
} |
|
708 |
} |
|
709 |
} |
|
710 |
||
711 |
/** |
|
712 |
* Add a new property to the object. |
|
713 |
* |
|
714 |
* @param key property key |
|
715 |
* @param propertyDesc property descriptor for property |
|
716 |
*/ |
|
717 |
public final void addOwnProperty(final String key, final PropertyDescriptor propertyDesc) { |
|
718 |
// Already checked that there is no own property with that key. |
|
719 |
PropertyDescriptor pdesc = propertyDesc; |
|
720 |
||
721 |
final int propFlags = Property.toFlags(pdesc); |
|
722 |
||
723 |
if (pdesc.type() == PropertyDescriptor.GENERIC) { |
|
23375
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23372
diff
changeset
|
724 |
final Global global = Context.getGlobal(); |
16147 | 725 |
final PropertyDescriptor dDesc = global.newDataDescriptor(UNDEFINED, false, false, false); |
726 |
||
727 |
dDesc.fillFrom((ScriptObject)pdesc); |
|
728 |
pdesc = dDesc; |
|
729 |
} |
|
730 |
||
731 |
final int type = pdesc.type(); |
|
732 |
if (type == PropertyDescriptor.DATA) { |
|
733 |
addOwnProperty(key, propFlags, pdesc.getValue()); |
|
734 |
} else if (type == PropertyDescriptor.ACCESSOR) { |
|
735 |
addOwnProperty(key, propFlags, |
|
736 |
pdesc.has(GET) ? pdesc.getGetter() : null, |
|
737 |
pdesc.has(SET) ? pdesc.getSetter() : null); |
|
738 |
} |
|
739 |
||
740 |
checkIntegerKey(key); |
|
741 |
} |
|
742 |
||
743 |
/** |
|
744 |
* Low level property API (not using property descriptors) |
|
745 |
* <p> |
|
746 |
* Find a property in the prototype hierarchy. Note: this is final and not |
|
747 |
* a good idea to override. If you have to, use |
|
748 |
* {jdk.nashorn.internal.objects.NativeArray{@link #getProperty(String)} or |
|
749 |
* {jdk.nashorn.internal.objects.NativeArray{@link #getPropertyDescriptor(String)} as the |
|
750 |
* overriding way to find array properties |
|
751 |
* |
|
752 |
* @see jdk.nashorn.internal.objects.NativeArray |
|
753 |
* |
|
754 |
* @param key Property key. |
|
755 |
* @param deep Whether the search should look up proto chain. |
|
756 |
* |
|
757 |
* @return FindPropertyData or null if not found. |
|
758 |
*/ |
|
759 |
public final FindProperty findProperty(final String key, final boolean deep) { |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
760 |
return findProperty(key, deep, this); |
16161
0ebfaec3a45b
8005848: assigning to global toString variable affects Object.prototype.toString
sundar
parents:
16159
diff
changeset
|
761 |
} |
0ebfaec3a45b
8005848: assigning to global toString variable affects Object.prototype.toString
sundar
parents:
16159
diff
changeset
|
762 |
|
0ebfaec3a45b
8005848: assigning to global toString variable affects Object.prototype.toString
sundar
parents:
16159
diff
changeset
|
763 |
/** |
0ebfaec3a45b
8005848: assigning to global toString variable affects Object.prototype.toString
sundar
parents:
16159
diff
changeset
|
764 |
* Low level property API (not using property descriptors) |
0ebfaec3a45b
8005848: assigning to global toString variable affects Object.prototype.toString
sundar
parents:
16159
diff
changeset
|
765 |
* <p> |
16264
e0c3c97cd93e
8006984: Introducing local into a function inside with statement confuses its scope
attila
parents:
16256
diff
changeset
|
766 |
* Find a property in the prototype hierarchy. Note: this is not a good idea |
e0c3c97cd93e
8006984: Introducing local into a function inside with statement confuses its scope
attila
parents:
16256
diff
changeset
|
767 |
* to override except as it was done in {@link WithObject}. |
e0c3c97cd93e
8006984: Introducing local into a function inside with statement confuses its scope
attila
parents:
16256
diff
changeset
|
768 |
* If you have to, use |
16161
0ebfaec3a45b
8005848: assigning to global toString variable affects Object.prototype.toString
sundar
parents:
16159
diff
changeset
|
769 |
* {jdk.nashorn.internal.objects.NativeArray{@link #getProperty(String)} or |
0ebfaec3a45b
8005848: assigning to global toString variable affects Object.prototype.toString
sundar
parents:
16159
diff
changeset
|
770 |
* {jdk.nashorn.internal.objects.NativeArray{@link #getPropertyDescriptor(String)} as the |
0ebfaec3a45b
8005848: assigning to global toString variable affects Object.prototype.toString
sundar
parents:
16159
diff
changeset
|
771 |
* overriding way to find array properties |
0ebfaec3a45b
8005848: assigning to global toString variable affects Object.prototype.toString
sundar
parents:
16159
diff
changeset
|
772 |
* |
0ebfaec3a45b
8005848: assigning to global toString variable affects Object.prototype.toString
sundar
parents:
16159
diff
changeset
|
773 |
* @see jdk.nashorn.internal.objects.NativeArray |
0ebfaec3a45b
8005848: assigning to global toString variable affects Object.prototype.toString
sundar
parents:
16159
diff
changeset
|
774 |
* |
0ebfaec3a45b
8005848: assigning to global toString variable affects Object.prototype.toString
sundar
parents:
16159
diff
changeset
|
775 |
* @param key Property key. |
0ebfaec3a45b
8005848: assigning to global toString variable affects Object.prototype.toString
sundar
parents:
16159
diff
changeset
|
776 |
* @param deep Whether the search should look up proto chain. |
16264
e0c3c97cd93e
8006984: Introducing local into a function inside with statement confuses its scope
attila
parents:
16256
diff
changeset
|
777 |
* @param start the object on which the lookup was originally initiated |
16161
0ebfaec3a45b
8005848: assigning to global toString variable affects Object.prototype.toString
sundar
parents:
16159
diff
changeset
|
778 |
* |
0ebfaec3a45b
8005848: assigning to global toString variable affects Object.prototype.toString
sundar
parents:
16159
diff
changeset
|
779 |
* @return FindPropertyData or null if not found. |
0ebfaec3a45b
8005848: assigning to global toString variable affects Object.prototype.toString
sundar
parents:
16159
diff
changeset
|
780 |
*/ |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
781 |
FindProperty findProperty(final String key, final boolean deep, final ScriptObject start) { |
16264
e0c3c97cd93e
8006984: Introducing local into a function inside with statement confuses its scope
attila
parents:
16256
diff
changeset
|
782 |
|
e0c3c97cd93e
8006984: Introducing local into a function inside with statement confuses its scope
attila
parents:
16256
diff
changeset
|
783 |
final PropertyMap selfMap = getMap(); |
e0c3c97cd93e
8006984: Introducing local into a function inside with statement confuses its scope
attila
parents:
16256
diff
changeset
|
784 |
final Property property = selfMap.findProperty(key); |
e0c3c97cd93e
8006984: Introducing local into a function inside with statement confuses its scope
attila
parents:
16256
diff
changeset
|
785 |
|
e0c3c97cd93e
8006984: Introducing local into a function inside with statement confuses its scope
attila
parents:
16256
diff
changeset
|
786 |
if (property != null) { |
e0c3c97cd93e
8006984: Introducing local into a function inside with statement confuses its scope
attila
parents:
16256
diff
changeset
|
787 |
return new FindProperty(start, this, property); |
e0c3c97cd93e
8006984: Introducing local into a function inside with statement confuses its scope
attila
parents:
16256
diff
changeset
|
788 |
} |
e0c3c97cd93e
8006984: Introducing local into a function inside with statement confuses its scope
attila
parents:
16256
diff
changeset
|
789 |
|
e0c3c97cd93e
8006984: Introducing local into a function inside with statement confuses its scope
attila
parents:
16256
diff
changeset
|
790 |
if (deep) { |
17518
2225a4f929c0
8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents:
17514
diff
changeset
|
791 |
final ScriptObject myProto = getProto(); |
2225a4f929c0
8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents:
17514
diff
changeset
|
792 |
if (myProto != null) { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
793 |
return myProto.findProperty(key, deep, start); |
16161
0ebfaec3a45b
8005848: assigning to global toString variable affects Object.prototype.toString
sundar
parents:
16159
diff
changeset
|
794 |
} |
16264
e0c3c97cd93e
8006984: Introducing local into a function inside with statement confuses its scope
attila
parents:
16256
diff
changeset
|
795 |
} |
16147 | 796 |
|
797 |
return null; |
|
798 |
} |
|
799 |
||
800 |
/** |
|
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
801 |
* Low level property API. This is similar to {@link #findProperty(String, boolean)} but returns a |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
802 |
* {@code boolean} value instead of a {@link FindProperty} object. |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
803 |
* @param key Property key. |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
804 |
* @param deep Whether the search should look up proto chain. |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
805 |
* @return true if the property was found. |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
806 |
*/ |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
807 |
boolean hasProperty(final String key, final boolean deep) { |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
808 |
if (getMap().findProperty(key) != null) { |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
809 |
return true; |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
810 |
} |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
811 |
|
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
812 |
if (deep) { |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
813 |
final ScriptObject myProto = getProto(); |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
814 |
if (myProto != null) { |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
815 |
return myProto.hasProperty(key, deep); |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
816 |
} |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
817 |
} |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
818 |
|
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
819 |
return false; |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
820 |
} |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
821 |
|
26768
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
822 |
private SwitchPoint findBuiltinSwitchPoint(final String key) { |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
823 |
for (ScriptObject myProto = getProto(); myProto != null; myProto = myProto.getProto()) { |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
824 |
final Property prop = myProto.getMap().findProperty(key); |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
825 |
if (prop != null) { |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
826 |
final SwitchPoint sp = prop.getBuiltinSwitchPoint(); |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
827 |
if (sp != null && !sp.hasBeenInvalidated()) { |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
828 |
return sp; |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
829 |
} |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
830 |
} |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
831 |
} |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
832 |
return null; |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
833 |
} |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
834 |
|
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
835 |
/** |
16147 | 836 |
* Add a new property to the object. |
837 |
* <p> |
|
838 |
* This a more "low level" way that doesn't involve {@link PropertyDescriptor}s |
|
839 |
* |
|
840 |
* @param key Property key. |
|
841 |
* @param propertyFlags Property flags. |
|
842 |
* @param getter Property getter, or null if not defined |
|
843 |
* @param setter Property setter, or null if not defined |
|
844 |
* |
|
845 |
* @return New property. |
|
846 |
*/ |
|
847 |
public final Property addOwnProperty(final String key, final int propertyFlags, final ScriptFunction getter, final ScriptFunction setter) { |
|
848 |
return addOwnProperty(newUserAccessors(key, propertyFlags, getter, setter)); |
|
849 |
} |
|
850 |
||
851 |
/** |
|
852 |
* Add a new property to the object. |
|
853 |
* <p> |
|
854 |
* This a more "low level" way that doesn't involve {@link PropertyDescriptor}s |
|
855 |
* |
|
856 |
* @param key Property key. |
|
857 |
* @param propertyFlags Property flags. |
|
858 |
* @param value Value of property |
|
859 |
* |
|
860 |
* @return New property. |
|
861 |
*/ |
|
862 |
public final Property addOwnProperty(final String key, final int propertyFlags, final Object value) { |
|
24719 | 863 |
return addSpillProperty(key, propertyFlags, value, true); |
16147 | 864 |
} |
865 |
||
866 |
/** |
|
867 |
* Add a new property to the object. |
|
868 |
* <p> |
|
869 |
* This a more "low level" way that doesn't involve {@link PropertyDescriptor}s |
|
870 |
* |
|
871 |
* @param newProperty property to add |
|
872 |
* |
|
873 |
* @return New property. |
|
874 |
*/ |
|
875 |
public final Property addOwnProperty(final Property newProperty) { |
|
876 |
PropertyMap oldMap = getMap(); |
|
877 |
while (true) { |
|
878 |
final PropertyMap newMap = oldMap.addProperty(newProperty); |
|
879 |
if (!compareAndSetMap(oldMap, newMap)) { |
|
880 |
oldMap = getMap(); |
|
881 |
final Property oldProperty = oldMap.findProperty(newProperty.getKey()); |
|
882 |
||
883 |
if (oldProperty != null) { |
|
884 |
return oldProperty; |
|
885 |
} |
|
886 |
} else { |
|
887 |
return newProperty; |
|
888 |
} |
|
889 |
} |
|
890 |
} |
|
891 |
||
892 |
private void erasePropertyValue(final Property property) { |
|
893 |
// Erase the property field value with undefined. If the property is defined |
|
894 |
// by user-defined accessors, we don't want to call the setter!! |
|
895 |
if (!(property instanceof UserAccessorProperty)) { |
|
24719 | 896 |
assert property != null; |
897 |
property.setValue(this, this, UNDEFINED, false); |
|
16147 | 898 |
} |
899 |
} |
|
900 |
||
901 |
/** |
|
902 |
* Delete a property from the object. |
|
903 |
* |
|
904 |
* @param property Property to delete. |
|
905 |
* |
|
906 |
* @return true if deleted. |
|
907 |
*/ |
|
908 |
public final boolean deleteOwnProperty(final Property property) { |
|
909 |
erasePropertyValue(property); |
|
910 |
PropertyMap oldMap = getMap(); |
|
911 |
||
912 |
while (true) { |
|
913 |
final PropertyMap newMap = oldMap.deleteProperty(property); |
|
914 |
||
915 |
if (newMap == null) { |
|
916 |
return false; |
|
917 |
} |
|
918 |
||
919 |
if (!compareAndSetMap(oldMap, newMap)) { |
|
920 |
oldMap = getMap(); |
|
921 |
} else { |
|
922 |
// delete getter and setter function references so that we don't leak |
|
923 |
if (property instanceof UserAccessorProperty) { |
|
24719 | 924 |
((UserAccessorProperty)property).setAccessors(this, getMap(), null); |
16147 | 925 |
} |
24745
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
926 |
Global.getConstants().delete(property.getKey()); |
16147 | 927 |
return true; |
928 |
} |
|
929 |
} |
|
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
930 |
|
16147 | 931 |
} |
932 |
||
933 |
/** |
|
24719 | 934 |
* Fast initialization functions for ScriptFunctions that are strict, to avoid |
935 |
* creating setters that probably aren't used. Inject directly into the spill pool |
|
936 |
* the defaults for "arguments" and "caller" |
|
937 |
* |
|
26886
18c744ab4df2
8059211: Changed ArrayData.length accessor to use the protected field and fixed javadoc warnings related to this
lagergren
parents:
26768
diff
changeset
|
938 |
* @param key property key |
18c744ab4df2
8059211: Changed ArrayData.length accessor to use the protected field and fixed javadoc warnings related to this
lagergren
parents:
26768
diff
changeset
|
939 |
* @param propertyFlags flags |
18c744ab4df2
8059211: Changed ArrayData.length accessor to use the protected field and fixed javadoc warnings related to this
lagergren
parents:
26768
diff
changeset
|
940 |
* @param getter getter for {@link UserAccessorProperty}, null if not present or N/A |
18c744ab4df2
8059211: Changed ArrayData.length accessor to use the protected field and fixed javadoc warnings related to this
lagergren
parents:
26768
diff
changeset
|
941 |
* @param setter setter for {@link UserAccessorProperty}, null if not present or N/A |
24719 | 942 |
*/ |
943 |
protected final void initUserAccessors(final String key, final int propertyFlags, final ScriptFunction getter, final ScriptFunction setter) { |
|
944 |
final int slot = spillLength; |
|
945 |
ensureSpillSize(spillLength); //arguments=slot0, caller=slot0 |
|
946 |
objectSpill[slot] = new UserAccessorProperty.Accessors(getter, setter); |
|
24720 | 947 |
final PropertyMap oldMap = getMap(); |
24719 | 948 |
Property newProperty; |
949 |
PropertyMap newMap; |
|
950 |
do { |
|
951 |
newProperty = new UserAccessorProperty(key, propertyFlags, slot); |
|
952 |
newMap = oldMap.addProperty(newProperty); |
|
953 |
} while (!compareAndSetMap(oldMap, newMap)); |
|
16147 | 954 |
} |
955 |
||
956 |
/** |
|
957 |
* Modify a property in the object |
|
958 |
* |
|
959 |
* @param oldProperty property to modify |
|
960 |
* @param propertyFlags new property flags |
|
961 |
* @param getter getter for {@link UserAccessorProperty}, null if not present or N/A |
|
962 |
* @param setter setter for {@link UserAccessorProperty}, null if not present or N/A |
|
963 |
* |
|
964 |
* @return new property |
|
965 |
*/ |
|
966 |
public final Property modifyOwnProperty(final Property oldProperty, final int propertyFlags, final ScriptFunction getter, final ScriptFunction setter) { |
|
967 |
Property newProperty; |
|
24719 | 968 |
|
16147 | 969 |
if (oldProperty instanceof UserAccessorProperty) { |
24719 | 970 |
final UserAccessorProperty uc = (UserAccessorProperty)oldProperty; |
971 |
final int slot = uc.getSlot(); |
|
972 |
||
973 |
assert uc.getCurrentType() == Object.class; |
|
974 |
if (slot >= spillLength) { |
|
975 |
uc.setAccessors(this, getMap(), new UserAccessorProperty.Accessors(getter, setter)); |
|
976 |
} else { |
|
977 |
final UserAccessorProperty.Accessors gs = uc.getAccessors(this); //this crashes |
|
978 |
if (gs == null) { |
|
979 |
uc.setAccessors(this, getMap(), new UserAccessorProperty.Accessors(getter, setter)); |
|
980 |
} else { |
|
981 |
//reuse existing getter setter for speed |
|
982 |
gs.set(getter, setter); |
|
983 |
if (uc.getFlags() == propertyFlags) { |
|
984 |
return oldProperty; |
|
985 |
} |
|
986 |
} |
|
16147 | 987 |
} |
24719 | 988 |
newProperty = new UserAccessorProperty(uc.getKey(), propertyFlags, slot); |
16147 | 989 |
} else { |
990 |
// erase old property value and create new user accessor property |
|
991 |
erasePropertyValue(oldProperty); |
|
992 |
newProperty = newUserAccessors(oldProperty.getKey(), propertyFlags, getter, setter); |
|
993 |
} |
|
994 |
||
995 |
return modifyOwnProperty(oldProperty, newProperty); |
|
996 |
} |
|
997 |
||
998 |
/** |
|
999 |
* Modify a property in the object |
|
1000 |
* |
|
1001 |
* @param oldProperty property to modify |
|
1002 |
* @param propertyFlags new property flags |
|
1003 |
* |
|
1004 |
* @return new property |
|
1005 |
*/ |
|
1006 |
public final Property modifyOwnProperty(final Property oldProperty, final int propertyFlags) { |
|
1007 |
return modifyOwnProperty(oldProperty, oldProperty.setFlags(propertyFlags)); |
|
1008 |
} |
|
1009 |
||
1010 |
/** |
|
1011 |
* Modify a property in the object, replacing a property with a new one |
|
1012 |
* |
|
1013 |
* @param oldProperty property to replace |
|
1014 |
* @param newProperty property to replace it with |
|
1015 |
* |
|
1016 |
* @return new property |
|
1017 |
*/ |
|
1018 |
private Property modifyOwnProperty(final Property oldProperty, final Property newProperty) { |
|
24719 | 1019 |
if (oldProperty == newProperty) { |
1020 |
return newProperty; //nop |
|
1021 |
} |
|
1022 |
||
16147 | 1023 |
assert newProperty.getKey().equals(oldProperty.getKey()) : "replacing property with different key"; |
1024 |
||
1025 |
PropertyMap oldMap = getMap(); |
|
1026 |
||
1027 |
while (true) { |
|
1028 |
final PropertyMap newMap = oldMap.replaceProperty(oldProperty, newProperty); |
|
1029 |
||
1030 |
if (!compareAndSetMap(oldMap, newMap)) { |
|
1031 |
oldMap = getMap(); |
|
1032 |
final Property oldPropertyLookup = oldMap.findProperty(oldProperty.getKey()); |
|
1033 |
||
1034 |
if (oldPropertyLookup != null && oldPropertyLookup.equals(newProperty)) { |
|
1035 |
return oldPropertyLookup; |
|
1036 |
} |
|
1037 |
} else { |
|
1038 |
return newProperty; |
|
1039 |
} |
|
1040 |
} |
|
1041 |
} |
|
1042 |
||
1043 |
/** |
|
1044 |
* Update getter and setter in an object literal. |
|
1045 |
* |
|
1046 |
* @param key Property key. |
|
1047 |
* @param getter {@link UserAccessorProperty} defined getter, or null if none |
|
1048 |
* @param setter {@link UserAccessorProperty} defined setter, or null if none |
|
1049 |
*/ |
|
1050 |
public final void setUserAccessors(final String key, final ScriptFunction getter, final ScriptFunction setter) { |
|
1051 |
final Property oldProperty = getMap().findProperty(key); |
|
18617
f6fe338f62c3
8008458: Strict functions dont share property map
jlaskey
parents:
18334
diff
changeset
|
1052 |
if (oldProperty instanceof UserAccessorProperty) { |
18620 | 1053 |
modifyOwnProperty(oldProperty, oldProperty.getFlags(), getter, setter); |
16147 | 1054 |
} else { |
18617
f6fe338f62c3
8008458: Strict functions dont share property map
jlaskey
parents:
18334
diff
changeset
|
1055 |
addOwnProperty(newUserAccessors(key, oldProperty != null ? oldProperty.getFlags() : 0, getter, setter)); |
16147 | 1056 |
} |
1057 |
} |
|
1058 |
||
24719 | 1059 |
private static int getIntValue(final FindProperty find, final int programPoint) { |
26508
b40ef4386b01
8057021: UserAccessorProperty guards fail with multiple globals
hannesw
parents:
26377
diff
changeset
|
1060 |
final MethodHandle getter = find.getGetter(int.class, programPoint, null); |
16147 | 1061 |
if (getter != null) { |
1062 |
try { |
|
17234
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
1063 |
return (int)getter.invokeExact((Object)find.getGetterReceiver()); |
16147 | 1064 |
} catch (final Error|RuntimeException e) { |
1065 |
throw e; |
|
1066 |
} catch (final Throwable e) { |
|
1067 |
throw new RuntimeException(e); |
|
1068 |
} |
|
1069 |
} |
|
1070 |
||
24719 | 1071 |
return UNDEFINED_INT; |
16147 | 1072 |
} |
1073 |
||
24719 | 1074 |
private static long getLongValue(final FindProperty find, final int programPoint) { |
26508
b40ef4386b01
8057021: UserAccessorProperty guards fail with multiple globals
hannesw
parents:
26377
diff
changeset
|
1075 |
final MethodHandle getter = find.getGetter(long.class, programPoint, null); |
16147 | 1076 |
if (getter != null) { |
1077 |
try { |
|
17234
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
1078 |
return (long)getter.invokeExact((Object)find.getGetterReceiver()); |
16147 | 1079 |
} catch (final Error|RuntimeException e) { |
1080 |
throw e; |
|
1081 |
} catch (final Throwable e) { |
|
1082 |
throw new RuntimeException(e); |
|
1083 |
} |
|
1084 |
} |
|
1085 |
||
24719 | 1086 |
return UNDEFINED_LONG; |
16147 | 1087 |
} |
1088 |
||
24719 | 1089 |
private static double getDoubleValue(final FindProperty find, final int programPoint) { |
26508
b40ef4386b01
8057021: UserAccessorProperty guards fail with multiple globals
hannesw
parents:
26377
diff
changeset
|
1090 |
final MethodHandle getter = find.getGetter(double.class, programPoint, null); |
16147 | 1091 |
if (getter != null) { |
1092 |
try { |
|
17234
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
1093 |
return (double)getter.invokeExact((Object)find.getGetterReceiver()); |
16147 | 1094 |
} catch (final Error|RuntimeException e) { |
1095 |
throw e; |
|
1096 |
} catch (final Throwable e) { |
|
1097 |
throw new RuntimeException(e); |
|
1098 |
} |
|
1099 |
} |
|
1100 |
||
24719 | 1101 |
return UNDEFINED_DOUBLE; |
16147 | 1102 |
} |
1103 |
||
1104 |
/** |
|
1105 |
* Return methodHandle of value function for call. |
|
1106 |
* |
|
1107 |
* @param find data from find property. |
|
1108 |
* @param type method type of function. |
|
1109 |
* @param bindName null or name to bind to second argument (property not found method.) |
|
1110 |
* |
|
1111 |
* @return value of property as a MethodHandle or null. |
|
1112 |
*/ |
|
1113 |
protected MethodHandle getCallMethodHandle(final FindProperty find, final MethodType type, final String bindName) { |
|
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
1114 |
return getCallMethodHandle(find.getObjectValue(), type, bindName); |
16147 | 1115 |
} |
1116 |
||
1117 |
/** |
|
1118 |
* Return methodHandle of value function for call. |
|
1119 |
* |
|
1120 |
* @param value value of receiver, it not a {@link ScriptFunction} this will return null. |
|
1121 |
* @param type method type of function. |
|
1122 |
* @param bindName null or name to bind to second argument (property not found method.) |
|
1123 |
* |
|
1124 |
* @return value of property as a MethodHandle or null. |
|
1125 |
*/ |
|
1126 |
protected static MethodHandle getCallMethodHandle(final Object value, final MethodType type, final String bindName) { |
|
1127 |
return value instanceof ScriptFunction ? ((ScriptFunction)value).getCallMethodHandle(type, bindName) : null; |
|
1128 |
} |
|
1129 |
||
1130 |
/** |
|
1131 |
* Get value using found property. |
|
1132 |
* |
|
1133 |
* @param property Found property. |
|
1134 |
* |
|
1135 |
* @return Value of property. |
|
1136 |
*/ |
|
1137 |
public final Object getWithProperty(final Property property) { |
|
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
1138 |
return new FindProperty(this, this, property).getObjectValue(); |
16147 | 1139 |
} |
1140 |
||
1141 |
/** |
|
1142 |
* Get a property given a key |
|
1143 |
* |
|
1144 |
* @param key property key |
|
1145 |
* |
|
1146 |
* @return property for key |
|
1147 |
*/ |
|
1148 |
public final Property getProperty(final String key) { |
|
1149 |
return getMap().findProperty(key); |
|
1150 |
} |
|
1151 |
||
1152 |
/** |
|
1153 |
* Overridden by {@link jdk.nashorn.internal.objects.NativeArguments} class (internal use.) |
|
1154 |
* Used for argument access in a vararg function using parameter name. |
|
1155 |
* Returns the argument at a given key (index) |
|
1156 |
* |
|
1157 |
* @param key argument index |
|
1158 |
* |
|
1159 |
* @return the argument at the given position, or undefined if not present |
|
1160 |
*/ |
|
1161 |
public Object getArgument(final int key) { |
|
1162 |
return get(key); |
|
1163 |
} |
|
1164 |
||
1165 |
/** |
|
1166 |
* Overridden by {@link jdk.nashorn.internal.objects.NativeArguments} class (internal use.) |
|
1167 |
* Used for argument access in a vararg function using parameter name. |
|
1168 |
* Returns the argument at a given key (index) |
|
1169 |
* |
|
1170 |
* @param key argument index |
|
1171 |
* @param value the value to write at the given index |
|
1172 |
*/ |
|
1173 |
public void setArgument(final int key, final Object value) { |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
1174 |
set(key, value, 0); |
16147 | 1175 |
} |
1176 |
||
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1177 |
/** |
16147 | 1178 |
* Return the current context from the object's map. |
1179 |
* @return Current context. |
|
1180 |
*/ |
|
19884
1bacbaa1bfc7
8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents:
19881
diff
changeset
|
1181 |
protected Context getContext() { |
1bacbaa1bfc7
8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents:
19881
diff
changeset
|
1182 |
return Context.fromClass(getClass()); |
18851
bdb92c95f886
8019947: inherited property invalidation does not work with two globals in same context
sundar
parents:
18620
diff
changeset
|
1183 |
} |
bdb92c95f886
8019947: inherited property invalidation does not work with two globals in same context
sundar
parents:
18620
diff
changeset
|
1184 |
|
bdb92c95f886
8019947: inherited property invalidation does not work with two globals in same context
sundar
parents:
18620
diff
changeset
|
1185 |
/** |
16147 | 1186 |
* Return the map of an object. |
1187 |
* @return PropertyMap object. |
|
1188 |
*/ |
|
1189 |
public final PropertyMap getMap() { |
|
1190 |
return map; |
|
1191 |
} |
|
1192 |
||
1193 |
/** |
|
1194 |
* Set the initial map. |
|
1195 |
* @param map Initial map. |
|
1196 |
*/ |
|
1197 |
public final void setMap(final PropertyMap map) { |
|
1198 |
this.map = map; |
|
1199 |
} |
|
1200 |
||
1201 |
/** |
|
1202 |
* Conditionally set the new map if the old map is the same. |
|
1203 |
* @param oldMap Map prior to manipulation. |
|
1204 |
* @param newMap Replacement map. |
|
1205 |
* @return true if the operation succeeded. |
|
1206 |
*/ |
|
24719 | 1207 |
protected final boolean compareAndSetMap(final PropertyMap oldMap, final PropertyMap newMap) { |
1208 |
if (oldMap == this.map) { |
|
16147 | 1209 |
this.map = newMap; |
24719 | 1210 |
return true; |
16147 | 1211 |
} |
24719 | 1212 |
return false; |
16147 | 1213 |
} |
1214 |
||
1215 |
/** |
|
1216 |
* Return the __proto__ of an object. |
|
1217 |
* @return __proto__ object. |
|
1218 |
*/ |
|
1219 |
public final ScriptObject getProto() { |
|
17513 | 1220 |
return proto; |
16147 | 1221 |
} |
1222 |
||
1223 |
/** |
|
24725
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24721
diff
changeset
|
1224 |
* Get the proto of a specific depth |
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24721
diff
changeset
|
1225 |
* @param n depth |
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24721
diff
changeset
|
1226 |
* @return proto at given depth |
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24721
diff
changeset
|
1227 |
*/ |
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24721
diff
changeset
|
1228 |
public final ScriptObject getProto(final int n) { |
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24721
diff
changeset
|
1229 |
assert n > 0; |
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24721
diff
changeset
|
1230 |
ScriptObject p = getProto(); |
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24721
diff
changeset
|
1231 |
for (int i = n; i-- > 0;) { |
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24721
diff
changeset
|
1232 |
p = p.getProto(); |
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24721
diff
changeset
|
1233 |
} |
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24721
diff
changeset
|
1234 |
return p; |
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24721
diff
changeset
|
1235 |
} |
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24721
diff
changeset
|
1236 |
|
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24721
diff
changeset
|
1237 |
/** |
16147 | 1238 |
* Set the __proto__ of an object. |
1239 |
* @param newProto new __proto__ to set. |
|
1240 |
*/ |
|
24719 | 1241 |
public final void setProto(final ScriptObject newProto) { |
17513 | 1242 |
final ScriptObject oldProto = proto; |
23084
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
1243 |
|
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
1244 |
if (oldProto != newProto) { |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
1245 |
proto = newProto; |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
1246 |
|
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
1247 |
// Let current listeners know that the protototype has changed and set our map |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
1248 |
final PropertyListeners listeners = getMap().getListeners(); |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
1249 |
if (listeners != null) { |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
1250 |
listeners.protoChanged(); |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
1251 |
} |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
1252 |
// Replace our current allocator map with one that is associated with the new prototype. |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
1253 |
setMap(getMap().changeProto(newProto)); |
17513 | 1254 |
} |
23084
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
1255 |
} |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
1256 |
|
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
1257 |
/** |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
1258 |
* Set the initial __proto__ of this object. This should be used instead of |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
1259 |
* {@link #setProto} if it is known that the current property map will not be |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
1260 |
* used on a new object with any other parent property map, so we can pass over |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
1261 |
* property map invalidation/evolution. |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
1262 |
* |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
1263 |
* @param initialProto the initial __proto__ to set. |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
1264 |
*/ |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
1265 |
public void setInitialProto(final ScriptObject initialProto) { |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
1266 |
this.proto = initialProto; |
16147 | 1267 |
} |
1268 |
||
1269 |
/** |
|
24751 | 1270 |
* Invoked from generated bytecode to initialize the prototype of object literals to the global Object prototype. |
1271 |
* @param obj the object literal that needs to have its prototype initialized to the global Object prototype. |
|
1272 |
*/ |
|
1273 |
public static void setGlobalObjectProto(final ScriptObject obj) { |
|
1274 |
obj.setInitialProto(Global.objectPrototype()); |
|
1275 |
} |
|
1276 |
||
1277 |
/** |
|
16147 | 1278 |
* Set the __proto__ of an object with checks. |
24772
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1279 |
* This is the built-in operation [[SetPrototypeOf]] |
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1280 |
* See ES6 draft spec: 9.1.2 [[SetPrototypeOf]] (V) |
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1281 |
* |
16147 | 1282 |
* @param newProto Prototype to set. |
1283 |
*/ |
|
24772
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1284 |
public final void setPrototypeOf(final Object newProto) { |
16147 | 1285 |
if (newProto == null || newProto instanceof ScriptObject) { |
24772
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1286 |
if (! isExtensible()) { |
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1287 |
// okay to set same proto again - even if non-extensible |
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1288 |
|
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1289 |
if (newProto == getProto()) { |
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1290 |
return; |
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1291 |
} |
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1292 |
throw typeError("__proto__.set.non.extensible", ScriptRuntime.safeToString(this)); |
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1293 |
} |
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1294 |
|
19619
4085b74056ee
8023368: Instance __proto__ property should exist and be writable.
sundar
parents:
19472
diff
changeset
|
1295 |
// check for circularity |
19630
99f53f31008e
8023550: -d option was broken for any dir but '.'. Fixed Java warnings.
lagergren
parents:
19621
diff
changeset
|
1296 |
ScriptObject p = (ScriptObject)newProto; |
99f53f31008e
8023550: -d option was broken for any dir but '.'. Fixed Java warnings.
lagergren
parents:
19621
diff
changeset
|
1297 |
while (p != null) { |
99f53f31008e
8023550: -d option was broken for any dir but '.'. Fixed Java warnings.
lagergren
parents:
19621
diff
changeset
|
1298 |
if (p == this) { |
19619
4085b74056ee
8023368: Instance __proto__ property should exist and be writable.
sundar
parents:
19472
diff
changeset
|
1299 |
throw typeError("circular.__proto__.set", ScriptRuntime.safeToString(this)); |
4085b74056ee
8023368: Instance __proto__ property should exist and be writable.
sundar
parents:
19472
diff
changeset
|
1300 |
} |
19630
99f53f31008e
8023550: -d option was broken for any dir but '.'. Fixed Java warnings.
lagergren
parents:
19621
diff
changeset
|
1301 |
p = p.getProto(); |
19619
4085b74056ee
8023368: Instance __proto__ property should exist and be writable.
sundar
parents:
19472
diff
changeset
|
1302 |
} |
16147 | 1303 |
setProto((ScriptObject)newProto); |
1304 |
} else { |
|
24772
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1305 |
throw typeError("cant.set.proto.to.non.object", ScriptRuntime.safeToString(this), ScriptRuntime.safeToString(newProto)); |
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1306 |
} |
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1307 |
} |
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1308 |
|
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1309 |
/** |
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1310 |
* Set the __proto__ of an object from an object literal. |
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1311 |
* See ES6 draft spec: B.3.1 __proto__ Property Names in |
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1312 |
* Object Initializers. Step 6 handling of "__proto__". |
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1313 |
* |
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1314 |
* @param newProto Prototype to set. |
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1315 |
*/ |
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1316 |
public final void setProtoFromLiteral(final Object newProto) { |
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1317 |
if (newProto == null || newProto instanceof ScriptObject) { |
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1318 |
setPrototypeOf(newProto); |
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1319 |
} else { |
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1320 |
// Some non-object, non-null. Then, we need to set |
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1321 |
// Object.prototype as the new __proto__ |
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1322 |
// |
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1323 |
// var obj = { __proto__ : 34 }; |
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1324 |
// print(obj.__proto__ === Object.prototype); // => true |
0fc1013a1785
8044520: Nashorn cannot execute node.js's express module
sundar
parents:
24769
diff
changeset
|
1325 |
setPrototypeOf(Global.objectPrototype()); |
16147 | 1326 |
} |
1327 |
} |
|
1328 |
||
1329 |
/** |
|
18334
47413e8d71b5
8016618: script mirror object access should be improved
sundar
parents:
18328
diff
changeset
|
1330 |
* return an array of own property keys associated with the object. |
47413e8d71b5
8016618: script mirror object access should be improved
sundar
parents:
18328
diff
changeset
|
1331 |
* |
16147 | 1332 |
* @param all True if to include non-enumerable keys. |
1333 |
* @return Array of keys. |
|
1334 |
*/ |
|
26058
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
1335 |
public final String[] getOwnKeys(final boolean all) { |
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
1336 |
return getOwnKeys(all, null); |
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
1337 |
} |
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
1338 |
|
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
1339 |
/** |
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
1340 |
* return an array of own property keys associated with the object. |
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
1341 |
* |
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
1342 |
* @param all True if to include non-enumerable keys. |
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
1343 |
* @param nonEnumerable set of non-enumerable properties seen already.Used |
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
1344 |
to filter out shadowed, but enumerable properties from proto children. |
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
1345 |
* @return Array of keys. |
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
1346 |
*/ |
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
1347 |
protected String[] getOwnKeys(final boolean all, final Set<String> nonEnumerable) { |
16147 | 1348 |
final List<Object> keys = new ArrayList<>(); |
1349 |
final PropertyMap selfMap = this.getMap(); |
|
1350 |
||
1351 |
final ArrayData array = getArray(); |
|
1352 |
final long length = array.length(); |
|
1353 |
||
1354 |
for (long i = 0; i < length; i = array.nextIndex(i)) { |
|
1355 |
if (array.has((int)i)) { |
|
1356 |
keys.add(JSType.toString(i)); |
|
1357 |
} |
|
1358 |
} |
|
1359 |
||
1360 |
for (final Property property : selfMap.getProperties()) { |
|
26058
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
1361 |
final boolean enumerable = property.isEnumerable(); |
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
1362 |
final String key = property.getKey(); |
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
1363 |
if (all) { |
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
1364 |
keys.add(key); |
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
1365 |
} else if (enumerable) { |
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
1366 |
// either we don't have non-enumerable filter set or filter set |
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
1367 |
// does not contain the current property. |
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
1368 |
if (nonEnumerable == null || !nonEnumerable.contains(key)) { |
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
1369 |
keys.add(key); |
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
1370 |
} |
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
1371 |
} else { |
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
1372 |
// store this non-enumerable property for later proto walk |
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
1373 |
if (nonEnumerable != null) { |
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
1374 |
nonEnumerable.add(key); |
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
1375 |
} |
16147 | 1376 |
} |
1377 |
} |
|
1378 |
||
1379 |
return keys.toArray(new String[keys.size()]); |
|
1380 |
} |
|
1381 |
||
1382 |
/** |
|
1383 |
* Check if this ScriptObject has array entries. This means that someone has |
|
1384 |
* set values with numeric keys in the object. |
|
1385 |
* |
|
1386 |
* @return true if array entries exists. |
|
1387 |
*/ |
|
1388 |
public boolean hasArrayEntries() { |
|
21441
0b98be59e3cb
8026858: Array length does not handle defined properties correctly
hannesw
parents:
21438
diff
changeset
|
1389 |
return getArray().length() > 0 || getMap().containsArrayKeys(); |
16147 | 1390 |
} |
1391 |
||
1392 |
/** |
|
1393 |
* Return the valid JavaScript type name descriptor |
|
1394 |
* |
|
1395 |
* @return "Object" |
|
1396 |
*/ |
|
1397 |
public String getClassName() { |
|
1398 |
return "Object"; |
|
1399 |
} |
|
1400 |
||
1401 |
/** |
|
1402 |
* {@code length} is a well known property. This is its getter. |
|
1403 |
* Note that this *may* be optimized by other classes |
|
1404 |
* |
|
1405 |
* @return length property value for this ScriptObject |
|
1406 |
*/ |
|
1407 |
public Object getLength() { |
|
1408 |
return get("length"); |
|
1409 |
} |
|
1410 |
||
1411 |
/** |
|
1412 |
* Stateless toString for ScriptObjects. |
|
1413 |
* |
|
1414 |
* @return string description of this object, e.g. {@code [object Object]} |
|
1415 |
*/ |
|
1416 |
public String safeToString() { |
|
1417 |
return "[object " + getClassName() + "]"; |
|
1418 |
} |
|
1419 |
||
1420 |
/** |
|
1421 |
* Return the default value of the object with a given preferred type hint. |
|
1422 |
* The preferred type hints are String.class for type String, Number.class |
|
1423 |
* for type Number. <p> |
|
1424 |
* |
|
1425 |
* A <code>hint</code> of null means "no hint". |
|
1426 |
* |
|
1427 |
* ECMA 8.12.8 [[DefaultValue]](hint) |
|
1428 |
* |
|
1429 |
* @param typeHint the preferred type hint |
|
1430 |
* @return the default value |
|
1431 |
*/ |
|
1432 |
public Object getDefaultValue(final Class<?> typeHint) { |
|
23375
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23372
diff
changeset
|
1433 |
// We delegate to Global, as the implementation uses dynamic call sites to invoke object's "toString" and |
16147 | 1434 |
// "valueOf" methods, and in order to avoid those call sites from becoming megamorphic when multiple contexts |
1435 |
// are being executed in a long-running program, we move the code and their associated dynamic call sites |
|
1436 |
// (Global.TO_STRING and Global.VALUE_OF) into per-context code. |
|
23375
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23372
diff
changeset
|
1437 |
return Context.getGlobal().getDefaultValue(this, typeHint); |
16147 | 1438 |
} |
1439 |
||
1440 |
/** |
|
1441 |
* Checking whether a script object is an instance of another. Used |
|
1442 |
* in {@link ScriptFunction} for hasInstance implementation, walks |
|
1443 |
* the proto chain |
|
1444 |
* |
|
1445 |
* @param instance instace to check |
|
18334
47413e8d71b5
8016618: script mirror object access should be improved
sundar
parents:
18328
diff
changeset
|
1446 |
* @return true if 'instance' is an instance of this object |
16147 | 1447 |
*/ |
1448 |
public boolean isInstance(final ScriptObject instance) { |
|
1449 |
return false; |
|
1450 |
} |
|
1451 |
||
1452 |
/** |
|
1453 |
* Flag this ScriptObject as non extensible |
|
1454 |
* |
|
1455 |
* @return the object after being made non extensible |
|
1456 |
*/ |
|
1457 |
public ScriptObject preventExtensions() { |
|
1458 |
PropertyMap oldMap = getMap(); |
|
24720 | 1459 |
while (!compareAndSetMap(oldMap, getMap().preventExtensions())) { |
1460 |
oldMap = getMap(); |
|
16147 | 1461 |
} |
24720 | 1462 |
|
1463 |
//invalidate any fast array setters |
|
1464 |
final ArrayData array = getArray(); |
|
1465 |
if (array != null) { |
|
1466 |
array.invalidateSetters(); |
|
1467 |
} |
|
1468 |
return this; |
|
16147 | 1469 |
} |
1470 |
||
1471 |
/** |
|
1472 |
* Check whether if an Object (not just a ScriptObject) represents JavaScript array |
|
1473 |
* |
|
1474 |
* @param obj object to check |
|
1475 |
* |
|
1476 |
* @return true if array |
|
1477 |
*/ |
|
1478 |
public static boolean isArray(final Object obj) { |
|
24720 | 1479 |
return obj instanceof ScriptObject && ((ScriptObject)obj).isArray(); |
16147 | 1480 |
} |
1481 |
||
1482 |
/** |
|
1483 |
* Check if this ScriptObject is an array |
|
1484 |
* @return true if array |
|
1485 |
*/ |
|
1486 |
public final boolean isArray() { |
|
1487 |
return (flags & IS_ARRAY) != 0; |
|
1488 |
} |
|
1489 |
||
1490 |
/** |
|
1491 |
* Flag this ScriptObject as being an array |
|
1492 |
*/ |
|
1493 |
public final void setIsArray() { |
|
1494 |
flags |= IS_ARRAY; |
|
1495 |
} |
|
1496 |
||
1497 |
/** |
|
1498 |
* Check if this ScriptObject is an {@code arguments} vector |
|
1499 |
* @return true if arguments vector |
|
1500 |
*/ |
|
1501 |
public final boolean isArguments() { |
|
1502 |
return (flags & IS_ARGUMENTS) != 0; |
|
1503 |
} |
|
1504 |
||
1505 |
/** |
|
1506 |
* Flag this ScriptObject as being an {@code arguments} vector |
|
1507 |
*/ |
|
1508 |
public final void setIsArguments() { |
|
1509 |
flags |= IS_ARGUMENTS; |
|
1510 |
} |
|
1511 |
||
1512 |
/** |
|
18328
ebd24057f163
8015355: Array.prototype functions don't honour non-writable length and / or index properties
sundar
parents:
18318
diff
changeset
|
1513 |
* Check if this object has non-writable length property |
ebd24057f163
8015355: Array.prototype functions don't honour non-writable length and / or index properties
sundar
parents:
18318
diff
changeset
|
1514 |
* |
ebd24057f163
8015355: Array.prototype functions don't honour non-writable length and / or index properties
sundar
parents:
18318
diff
changeset
|
1515 |
* @return {@code true} if 'length' property is non-writable |
ebd24057f163
8015355: Array.prototype functions don't honour non-writable length and / or index properties
sundar
parents:
18318
diff
changeset
|
1516 |
*/ |
ebd24057f163
8015355: Array.prototype functions don't honour non-writable length and / or index properties
sundar
parents:
18318
diff
changeset
|
1517 |
public final boolean isLengthNotWritable() { |
ebd24057f163
8015355: Array.prototype functions don't honour non-writable length and / or index properties
sundar
parents:
18318
diff
changeset
|
1518 |
return (flags & IS_LENGTH_NOT_WRITABLE) != 0; |
ebd24057f163
8015355: Array.prototype functions don't honour non-writable length and / or index properties
sundar
parents:
18318
diff
changeset
|
1519 |
} |
ebd24057f163
8015355: Array.prototype functions don't honour non-writable length and / or index properties
sundar
parents:
18318
diff
changeset
|
1520 |
|
ebd24057f163
8015355: Array.prototype functions don't honour non-writable length and / or index properties
sundar
parents:
18318
diff
changeset
|
1521 |
/** |
ebd24057f163
8015355: Array.prototype functions don't honour non-writable length and / or index properties
sundar
parents:
18318
diff
changeset
|
1522 |
* Flag this object as having non-writable length property |
ebd24057f163
8015355: Array.prototype functions don't honour non-writable length and / or index properties
sundar
parents:
18318
diff
changeset
|
1523 |
*/ |
ebd24057f163
8015355: Array.prototype functions don't honour non-writable length and / or index properties
sundar
parents:
18318
diff
changeset
|
1524 |
public void setIsLengthNotWritable() { |
ebd24057f163
8015355: Array.prototype functions don't honour non-writable length and / or index properties
sundar
parents:
18318
diff
changeset
|
1525 |
flags |= IS_LENGTH_NOT_WRITABLE; |
ebd24057f163
8015355: Array.prototype functions don't honour non-writable length and / or index properties
sundar
parents:
18318
diff
changeset
|
1526 |
} |
ebd24057f163
8015355: Array.prototype functions don't honour non-writable length and / or index properties
sundar
parents:
18318
diff
changeset
|
1527 |
|
ebd24057f163
8015355: Array.prototype functions don't honour non-writable length and / or index properties
sundar
parents:
18318
diff
changeset
|
1528 |
/** |
26768
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
1529 |
* Get the {@link ArrayData}, for this ScriptObject, ensuring it is of a type |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
1530 |
* that can handle elementType |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
1531 |
* @param elementType elementType |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
1532 |
* @return array data |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
1533 |
*/ |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
1534 |
public final ArrayData getArray(final Class<?> elementType) { |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
1535 |
if (elementType == null) { |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
1536 |
return arrayData; |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
1537 |
} |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
1538 |
final ArrayData newArrayData = arrayData.convert(elementType); |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
1539 |
if (newArrayData != arrayData) { |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
1540 |
arrayData = newArrayData; |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
1541 |
} |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
1542 |
return newArrayData; |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
1543 |
} |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
1544 |
|
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
1545 |
/** |
16147 | 1546 |
* Get the {@link ArrayData} for this ScriptObject if it is an array |
1547 |
* @return array data |
|
1548 |
*/ |
|
1549 |
public final ArrayData getArray() { |
|
1550 |
return arrayData; |
|
1551 |
} |
|
1552 |
||
1553 |
/** |
|
1554 |
* Set the {@link ArrayData} for this ScriptObject if it is to be an array |
|
1555 |
* @param arrayData the array data |
|
1556 |
*/ |
|
1557 |
public final void setArray(final ArrayData arrayData) { |
|
1558 |
this.arrayData = arrayData; |
|
1559 |
} |
|
1560 |
||
1561 |
/** |
|
1562 |
* Check if this ScriptObject is extensible |
|
1563 |
* @return true if extensible |
|
1564 |
*/ |
|
1565 |
public boolean isExtensible() { |
|
1566 |
return getMap().isExtensible(); |
|
1567 |
} |
|
1568 |
||
1569 |
/** |
|
1570 |
* ECMAScript 15.2.3.8 - seal implementation |
|
1571 |
* @return the sealed ScriptObject |
|
1572 |
*/ |
|
1573 |
public ScriptObject seal() { |
|
1574 |
PropertyMap oldMap = getMap(); |
|
1575 |
||
1576 |
while (true) { |
|
1577 |
final PropertyMap newMap = getMap().seal(); |
|
1578 |
||
1579 |
if (!compareAndSetMap(oldMap, newMap)) { |
|
1580 |
oldMap = getMap(); |
|
1581 |
} else { |
|
1582 |
setArray(ArrayData.seal(getArray())); |
|
1583 |
return this; |
|
1584 |
} |
|
1585 |
} |
|
1586 |
} |
|
1587 |
||
1588 |
/** |
|
1589 |
* Check whether this ScriptObject is sealed |
|
1590 |
* @return true if sealed |
|
1591 |
*/ |
|
1592 |
public boolean isSealed() { |
|
1593 |
return getMap().isSealed(); |
|
1594 |
} |
|
1595 |
||
1596 |
/** |
|
1597 |
* ECMA 15.2.39 - freeze implementation. Freeze this ScriptObject |
|
1598 |
* @return the frozen ScriptObject |
|
1599 |
*/ |
|
1600 |
public ScriptObject freeze() { |
|
1601 |
PropertyMap oldMap = getMap(); |
|
1602 |
||
1603 |
while (true) { |
|
1604 |
final PropertyMap newMap = getMap().freeze(); |
|
1605 |
||
1606 |
if (!compareAndSetMap(oldMap, newMap)) { |
|
1607 |
oldMap = getMap(); |
|
1608 |
} else { |
|
1609 |
setArray(ArrayData.freeze(getArray())); |
|
1610 |
return this; |
|
1611 |
} |
|
1612 |
} |
|
1613 |
} |
|
1614 |
||
1615 |
/** |
|
1616 |
* Check whether this ScriptObject is frozen |
|
18334
47413e8d71b5
8016618: script mirror object access should be improved
sundar
parents:
18328
diff
changeset
|
1617 |
* @return true if frozen |
16147 | 1618 |
*/ |
1619 |
public boolean isFrozen() { |
|
1620 |
return getMap().isFrozen(); |
|
1621 |
} |
|
1622 |
||
1623 |
||
1624 |
/** |
|
1625 |
* Flag this ScriptObject as scope |
|
1626 |
*/ |
|
1627 |
public final void setIsScope() { |
|
1628 |
if (Context.DEBUG) { |
|
1629 |
scopeCount++; |
|
1630 |
} |
|
1631 |
flags |= IS_SCOPE; |
|
1632 |
} |
|
1633 |
||
1634 |
/** |
|
1635 |
* Check whether this ScriptObject is scope |
|
1636 |
* @return true if scope |
|
1637 |
*/ |
|
1638 |
public final boolean isScope() { |
|
1639 |
return (flags & IS_SCOPE) != 0; |
|
1640 |
} |
|
1641 |
||
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1642 |
/** |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
1643 |
* Tag this script object as built in |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
1644 |
*/ |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
1645 |
public final void setIsBuiltin() { |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
1646 |
flags |= IS_BUILTIN; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
1647 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
1648 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
1649 |
/** |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
1650 |
* Check if this script object is built in |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
1651 |
* @return true if build in |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
1652 |
*/ |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
1653 |
public final boolean isBuiltin() { |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
1654 |
return (flags & IS_BUILTIN) != 0; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
1655 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
1656 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
1657 |
/** |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1658 |
* Clears the properties from a ScriptObject |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1659 |
* (java.util.Map-like method to help ScriptObjectMirror implementation) |
19884
1bacbaa1bfc7
8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents:
19881
diff
changeset
|
1660 |
* |
1bacbaa1bfc7
8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents:
19881
diff
changeset
|
1661 |
* @param strict strict mode or not |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1662 |
*/ |
19884
1bacbaa1bfc7
8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents:
19881
diff
changeset
|
1663 |
public void clear(final boolean strict) { |
16147 | 1664 |
final Iterator<String> iter = propertyIterator(); |
1665 |
while (iter.hasNext()) { |
|
1666 |
delete(iter.next(), strict); |
|
1667 |
} |
|
1668 |
} |
|
1669 |
||
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1670 |
/** |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1671 |
* Checks if a property with a given key is present in a ScriptObject |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1672 |
* (java.util.Map-like method to help ScriptObjectMirror implementation) |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1673 |
* |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1674 |
* @param key the key to check for |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1675 |
* @return true if a property with the given key exists, false otherwise |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1676 |
*/ |
16147 | 1677 |
public boolean containsKey(final Object key) { |
1678 |
return has(key); |
|
1679 |
} |
|
1680 |
||
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1681 |
/** |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1682 |
* Checks if a property with a given value is present in a ScriptObject |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1683 |
* (java.util.Map-like method to help ScriptObjectMirror implementation) |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1684 |
* |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1685 |
* @param value value to check for |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1686 |
* @return true if a property with the given value exists, false otherwise |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1687 |
*/ |
16147 | 1688 |
public boolean containsValue(final Object value) { |
1689 |
final Iterator<Object> iter = valueIterator(); |
|
1690 |
while (iter.hasNext()) { |
|
1691 |
if (iter.next().equals(value)) { |
|
1692 |
return true; |
|
1693 |
} |
|
1694 |
} |
|
1695 |
return false; |
|
1696 |
} |
|
1697 |
||
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1698 |
/** |
16272 | 1699 |
* Returns the set of {@literal <property, value>} entries that make up this |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1700 |
* ScriptObject's properties |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1701 |
* (java.util.Map-like method to help ScriptObjectMirror implementation) |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1702 |
* |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1703 |
* @return an entry set of all the properties in this object |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1704 |
*/ |
16147 | 1705 |
public Set<Map.Entry<Object, Object>> entrySet() { |
1706 |
final Iterator<String> iter = propertyIterator(); |
|
1707 |
final Set<Map.Entry<Object, Object>> entries = new HashSet<>(); |
|
1708 |
while (iter.hasNext()) { |
|
1709 |
final Object key = iter.next(); |
|
1710 |
entries.add(new AbstractMap.SimpleImmutableEntry<>(key, get(key))); |
|
1711 |
} |
|
1712 |
return Collections.unmodifiableSet(entries); |
|
1713 |
} |
|
1714 |
||
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1715 |
/** |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1716 |
* Check whether a ScriptObject contains no properties |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1717 |
* (java.util.Map-like method to help ScriptObjectMirror implementation) |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1718 |
* |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1719 |
* @return true if object has no properties |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1720 |
*/ |
16147 | 1721 |
public boolean isEmpty() { |
1722 |
return !propertyIterator().hasNext(); |
|
1723 |
} |
|
1724 |
||
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1725 |
/** |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1726 |
* Return the set of keys (property names) for all properties |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1727 |
* in this ScriptObject |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1728 |
* (java.util.Map-like method to help ScriptObjectMirror implementation) |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1729 |
* |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1730 |
* @return keySet of this ScriptObject |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1731 |
*/ |
16147 | 1732 |
public Set<Object> keySet() { |
1733 |
final Iterator<String> iter = propertyIterator(); |
|
1734 |
final Set<Object> keySet = new HashSet<>(); |
|
1735 |
while (iter.hasNext()) { |
|
1736 |
keySet.add(iter.next()); |
|
1737 |
} |
|
1738 |
return Collections.unmodifiableSet(keySet); |
|
1739 |
} |
|
1740 |
||
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1741 |
/** |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1742 |
* Put a property in the ScriptObject |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1743 |
* (java.util.Map-like method to help ScriptObjectMirror implementation) |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1744 |
* |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1745 |
* @param key property key |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1746 |
* @param value property value |
19884
1bacbaa1bfc7
8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents:
19881
diff
changeset
|
1747 |
* @param strict strict mode or not |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1748 |
* @return oldValue if property with same key existed already |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1749 |
*/ |
19884
1bacbaa1bfc7
8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents:
19881
diff
changeset
|
1750 |
public Object put(final Object key, final Object value, final boolean strict) { |
16147 | 1751 |
final Object oldValue = get(key); |
26886
18c744ab4df2
8059211: Changed ArrayData.length accessor to use the protected field and fixed javadoc warnings related to this
lagergren
parents:
26768
diff
changeset
|
1752 |
final int scriptObjectFlags = strict ? NashornCallSiteDescriptor.CALLSITE_STRICT : 0; |
18c744ab4df2
8059211: Changed ArrayData.length accessor to use the protected field and fixed javadoc warnings related to this
lagergren
parents:
26768
diff
changeset
|
1753 |
set(key, value, scriptObjectFlags); |
16147 | 1754 |
return oldValue; |
1755 |
} |
|
1756 |
||
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1757 |
/** |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1758 |
* Put several properties in the ScriptObject given a mapping |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1759 |
* of their keys to their values |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1760 |
* (java.util.Map-like method to help ScriptObjectMirror implementation) |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1761 |
* |
16272 | 1762 |
* @param otherMap a {@literal <key,value>} map of properties to add |
19884
1bacbaa1bfc7
8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents:
19881
diff
changeset
|
1763 |
* @param strict strict mode or not |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1764 |
*/ |
19884
1bacbaa1bfc7
8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents:
19881
diff
changeset
|
1765 |
public void putAll(final Map<?, ?> otherMap, final boolean strict) { |
26886
18c744ab4df2
8059211: Changed ArrayData.length accessor to use the protected field and fixed javadoc warnings related to this
lagergren
parents:
26768
diff
changeset
|
1766 |
final int scriptObjectFlags = strict ? NashornCallSiteDescriptor.CALLSITE_STRICT : 0; |
16147 | 1767 |
for (final Map.Entry<?, ?> entry : otherMap.entrySet()) { |
26886
18c744ab4df2
8059211: Changed ArrayData.length accessor to use the protected field and fixed javadoc warnings related to this
lagergren
parents:
26768
diff
changeset
|
1768 |
set(entry.getKey(), entry.getValue(), scriptObjectFlags); |
16147 | 1769 |
} |
1770 |
} |
|
1771 |
||
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1772 |
/** |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1773 |
* Remove a property from the ScriptObject. |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1774 |
* (java.util.Map-like method to help ScriptObjectMirror implementation) |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1775 |
* |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1776 |
* @param key the key of the property |
19884
1bacbaa1bfc7
8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents:
19881
diff
changeset
|
1777 |
* @param strict strict mode or not |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1778 |
* @return the oldValue of the removed property |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1779 |
*/ |
19884
1bacbaa1bfc7
8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents:
19881
diff
changeset
|
1780 |
public Object remove(final Object key, final boolean strict) { |
16147 | 1781 |
final Object oldValue = get(key); |
19884
1bacbaa1bfc7
8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents:
19881
diff
changeset
|
1782 |
delete(key, strict); |
16147 | 1783 |
return oldValue; |
1784 |
} |
|
1785 |
||
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1786 |
/** |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1787 |
* Return the size of the ScriptObject - i.e. the number of properties |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1788 |
* it contains |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1789 |
* (java.util.Map-like method to help ScriptObjectMirror implementation) |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1790 |
* |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1791 |
* @return number of properties in ScriptObject |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1792 |
*/ |
16147 | 1793 |
public int size() { |
1794 |
int n = 0; |
|
1795 |
for (final Iterator<String> iter = propertyIterator(); iter.hasNext(); iter.next()) { |
|
1796 |
n++; |
|
1797 |
} |
|
1798 |
return n; |
|
1799 |
} |
|
1800 |
||
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1801 |
/** |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1802 |
* Return the values of the properties in the ScriptObject |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1803 |
* (java.util.Map-like method to help ScriptObjectMirror implementation) |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1804 |
* |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1805 |
* @return collection of values for the properties in this ScriptObject |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16195
diff
changeset
|
1806 |
*/ |
16147 | 1807 |
public Collection<Object> values() { |
1808 |
final List<Object> values = new ArrayList<>(size()); |
|
1809 |
final Iterator<Object> iter = valueIterator(); |
|
1810 |
while (iter.hasNext()) { |
|
1811 |
values.add(iter.next()); |
|
1812 |
} |
|
1813 |
return Collections.unmodifiableList(values); |
|
1814 |
} |
|
1815 |
||
1816 |
/** |
|
1817 |
* Lookup method that, given a CallSiteDescriptor, looks up the target |
|
1818 |
* MethodHandle and creates a GuardedInvocation |
|
1819 |
* with the appropriate guard(s). |
|
1820 |
* |
|
1821 |
* @param desc call site descriptor |
|
16195
3f6c0ab2597a
8006766: Array-like access to characters of a string is slow
hannesw
parents:
16194
diff
changeset
|
1822 |
* @param request the link request |
16147 | 1823 |
* |
1824 |
* @return GuardedInvocation for the callsite |
|
1825 |
*/ |
|
16195
3f6c0ab2597a
8006766: Array-like access to characters of a string is slow
hannesw
parents:
16194
diff
changeset
|
1826 |
public GuardedInvocation lookup(final CallSiteDescriptor desc, final LinkRequest request) { |
16147 | 1827 |
final int c = desc.getNameTokenCount(); |
1828 |
// JavaScript is "immune" to all currently defined Dynalink composite operation - getProp is the same as getElem |
|
1829 |
// is the same as getMethod as JavaScript objects have a single namespace for all three. Therefore, we don't |
|
1830 |
// care about them, and just link to whatever is the first operation. |
|
1831 |
final String operator = CallSiteDescriptorFactory.tokenizeOperators(desc).get(0); |
|
1832 |
// NOTE: we support getElem and setItem as JavaScript doesn't distinguish items from properties. Nashorn itself |
|
1833 |
// emits "dyn:getProp:identifier" for "<expr>.<identifier>" and "dyn:getElem" for "<expr>[<expr>]", but we are |
|
1834 |
// more flexible here and dispatch not on operation name (getProp vs. getElem), but rather on whether the |
|
1835 |
// operation has an associated name or not. |
|
1836 |
switch (operator) { |
|
1837 |
case "getProp": |
|
1838 |
case "getElem": |
|
1839 |
case "getMethod": |
|
16195
3f6c0ab2597a
8006766: Array-like access to characters of a string is slow
hannesw
parents:
16194
diff
changeset
|
1840 |
return c > 2 ? findGetMethod(desc, request, operator) : findGetIndexMethod(desc, request); |
16147 | 1841 |
case "setProp": |
1842 |
case "setElem": |
|
24719 | 1843 |
return c > 2 ? findSetMethod(desc, request) : findSetIndexMethod(desc, request); |
16147 | 1844 |
case "call": |
16195
3f6c0ab2597a
8006766: Array-like access to characters of a string is slow
hannesw
parents:
16194
diff
changeset
|
1845 |
return findCallMethod(desc, request); |
16147 | 1846 |
case "new": |
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24733
diff
changeset
|
1847 |
return findNewMethod(desc, request); |
16147 | 1848 |
case "callMethod": |
16195
3f6c0ab2597a
8006766: Array-like access to characters of a string is slow
hannesw
parents:
16194
diff
changeset
|
1849 |
return findCallMethodMethod(desc, request); |
16147 | 1850 |
default: |
1851 |
return null; |
|
1852 |
} |
|
1853 |
} |
|
1854 |
||
1855 |
/** |
|
1856 |
* Find the appropriate New method for an invoke dynamic call. |
|
1857 |
* |
|
1858 |
* @param desc The invoke dynamic call site descriptor. |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24733
diff
changeset
|
1859 |
* @param request The link request |
16147 | 1860 |
* |
1861 |
* @return GuardedInvocation to be invoked at call site. |
|
1862 |
*/ |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24733
diff
changeset
|
1863 |
protected GuardedInvocation findNewMethod(final CallSiteDescriptor desc, final LinkRequest request) { |
16147 | 1864 |
return notAFunction(); |
1865 |
} |
|
1866 |
||
1867 |
/** |
|
1868 |
* Find the appropriate CALL method for an invoke dynamic call. |
|
1869 |
* This generates "not a function" always |
|
1870 |
* |
|
16195
3f6c0ab2597a
8006766: Array-like access to characters of a string is slow
hannesw
parents:
16194
diff
changeset
|
1871 |
* @param desc the call site descriptor. |
3f6c0ab2597a
8006766: Array-like access to characters of a string is slow
hannesw
parents:
16194
diff
changeset
|
1872 |
* @param request the link request |
16147 | 1873 |
* |
1874 |
* @return GuardedInvocation to be invoed at call site. |
|
1875 |
*/ |
|
16195
3f6c0ab2597a
8006766: Array-like access to characters of a string is slow
hannesw
parents:
16194
diff
changeset
|
1876 |
protected GuardedInvocation findCallMethod(final CallSiteDescriptor desc, final LinkRequest request) { |
16147 | 1877 |
return notAFunction(); |
1878 |
} |
|
1879 |
||
1880 |
private GuardedInvocation notAFunction() { |
|
16256
f2d9a0c49914
8007002: Replace implicit exception throwing methods with explicit throws - simplify control flow and remove useless code
lagergren
parents:
16240
diff
changeset
|
1881 |
throw typeError("not.a.function", ScriptRuntime.safeToString(this)); |
16147 | 1882 |
} |
1883 |
||
1884 |
/** |
|
16173 | 1885 |
* Find an implementation for a "dyn:callMethod" operation. Note that Nashorn internally never uses |
1886 |
* "dyn:callMethod", but instead always emits two call sites in bytecode, one for "dyn:getMethod", and then another |
|
1887 |
* one for "dyn:call". Explicit support for "dyn:callMethod" is provided for the benefit of potential external |
|
1888 |
* callers. The implementation itself actually folds a "dyn:getMethod" method handle into a "dyn:call" method handle. |
|
16147 | 1889 |
* |
16195
3f6c0ab2597a
8006766: Array-like access to characters of a string is slow
hannesw
parents:
16194
diff
changeset
|
1890 |
* @param desc the call site descriptor. |
3f6c0ab2597a
8006766: Array-like access to characters of a string is slow
hannesw
parents:
16194
diff
changeset
|
1891 |
* @param request the link request |
16147 | 1892 |
* |
1893 |
* @return GuardedInvocation to be invoked at call site. |
|
1894 |
*/ |
|
16195
3f6c0ab2597a
8006766: Array-like access to characters of a string is slow
hannesw
parents:
16194
diff
changeset
|
1895 |
protected GuardedInvocation findCallMethodMethod(final CallSiteDescriptor desc, final LinkRequest request) { |
16173 | 1896 |
// R(P0, P1, ...) |
1897 |
final MethodType callType = desc.getMethodType(); |
|
1898 |
// use type Object(P0) for the getter |
|
1899 |
final CallSiteDescriptor getterType = desc.changeMethodType(MethodType.methodType(Object.class, callType.parameterType(0))); |
|
16195
3f6c0ab2597a
8006766: Array-like access to characters of a string is slow
hannesw
parents:
16194
diff
changeset
|
1900 |
final GuardedInvocation getter = findGetMethod(getterType, request, "getMethod"); |
16173 | 1901 |
|
1902 |
// Object(P0) => Object(P0, P1, ...) |
|
1903 |
final MethodHandle argDroppingGetter = MH.dropArguments(getter.getInvocation(), 1, callType.parameterList().subList(1, callType.parameterCount())); |
|
1904 |
// R(Object, P0, P1, ...) |
|
1905 |
final MethodHandle invoker = Bootstrap.createDynamicInvoker("dyn:call", callType.insertParameterTypes(0, argDroppingGetter.type().returnType())); |
|
1906 |
// Fold Object(P0, P1, ...) into R(Object, P0, P1, ...) => R(P0, P1, ...) |
|
1907 |
return getter.replaceMethods(MH.foldArguments(invoker, argDroppingGetter), getter.getGuard()); |
|
16147 | 1908 |
} |
1909 |
||
1910 |
/** |
|
22377 | 1911 |
* Test whether this object contains in its prototype chain or is itself a with-object. |
1912 |
* @return true if a with-object was found |
|
1913 |
*/ |
|
1914 |
final boolean hasWithScope() { |
|
1915 |
if (isScope()) { |
|
1916 |
for (ScriptObject obj = this; obj != null; obj = obj.getProto()) { |
|
1917 |
if (obj instanceof WithObject) { |
|
1918 |
return true; |
|
1919 |
} |
|
1920 |
} |
|
1921 |
} |
|
1922 |
return false; |
|
1923 |
} |
|
1924 |
||
1925 |
/** |
|
1926 |
* Add a filter to the first argument of {@code methodHandle} that calls its {@link #getProto()} method |
|
1927 |
* {@code depth} times. |
|
1928 |
* @param methodHandle a method handle |
|
1929 |
* @param depth distance to target prototype |
|
1930 |
* @return the filtered method handle |
|
1931 |
*/ |
|
1932 |
static MethodHandle addProtoFilter(final MethodHandle methodHandle, final int depth) { |
|
1933 |
if (depth == 0) { |
|
1934 |
return methodHandle; |
|
1935 |
} |
|
1936 |
final int listIndex = depth - 1; // We don't need 0-deep walker |
|
24719 | 1937 |
MethodHandle filter = listIndex < PROTO_FILTERS.size() ? PROTO_FILTERS.get(listIndex) : null; |
22377 | 1938 |
|
24721
81f70e23cd3b
8036127: Prototype filter needs to be applied to getter guard as well, not just getter
lagergren
parents:
24720
diff
changeset
|
1939 |
if (filter == null) { |
22377 | 1940 |
filter = addProtoFilter(GETPROTO, depth - 1); |
24719 | 1941 |
PROTO_FILTERS.add(null); |
1942 |
PROTO_FILTERS.set(listIndex, filter); |
|
22377 | 1943 |
} |
1944 |
||
1945 |
return MH.filterArguments(methodHandle, 0, filter.asType(filter.type().changeReturnType(methodHandle.type().parameterType(0)))); |
|
1946 |
} |
|
1947 |
||
1948 |
/** |
|
16147 | 1949 |
* Find the appropriate GET method for an invoke dynamic call. |
1950 |
* |
|
16195
3f6c0ab2597a
8006766: Array-like access to characters of a string is slow
hannesw
parents:
16194
diff
changeset
|
1951 |
* @param desc the call site descriptor |
3f6c0ab2597a
8006766: Array-like access to characters of a string is slow
hannesw
parents:
16194
diff
changeset
|
1952 |
* @param request the link request |
3f6c0ab2597a
8006766: Array-like access to characters of a string is slow
hannesw
parents:
16194
diff
changeset
|
1953 |
* @param operator operator for get: getProp, getMethod, getElem etc |
16147 | 1954 |
* |
1955 |
* @return GuardedInvocation to be invoked at call site. |
|
1956 |
*/ |
|
16195
3f6c0ab2597a
8006766: Array-like access to characters of a string is slow
hannesw
parents:
16194
diff
changeset
|
1957 |
protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operator) { |
24720 | 1958 |
final boolean explicitInstanceOfCheck = explicitInstanceOfCheck(desc, request); |
26768
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
1959 |
|
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
1960 |
String name; |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
1961 |
name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND); |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
1962 |
if (NashornCallSiteDescriptor.isApplyToCall(desc)) { |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
1963 |
if (Global.isBuiltinFunctionPrototypeApply()) { |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
1964 |
name = "call"; |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
1965 |
} |
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24733
diff
changeset
|
1966 |
} |
24720 | 1967 |
|
22377 | 1968 |
if (request.isCallSiteUnstable() || hasWithScope()) { |
24777
ed1974940ff4
8044750: megamorphic getter for scope objects does not call __noSuchProperty__ hook
sundar
parents:
24772
diff
changeset
|
1969 |
return findMegaMorphicGetMethod(desc, name, "getMethod".equals(operator)); |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
1970 |
} |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
1971 |
|
16147 | 1972 |
final FindProperty find = findProperty(name, true); |
24720 | 1973 |
MethodHandle mh; |
16147 | 1974 |
|
1975 |
if (find == null) { |
|
24719 | 1976 |
switch (operator) { |
1977 |
case "getProp": |
|
16195
3f6c0ab2597a
8006766: Array-like access to characters of a string is slow
hannesw
parents:
16194
diff
changeset
|
1978 |
return noSuchProperty(desc, request); |
24719 | 1979 |
case "getMethod": |
16195
3f6c0ab2597a
8006766: Array-like access to characters of a string is slow
hannesw
parents:
16194
diff
changeset
|
1980 |
return noSuchMethod(desc, request); |
24719 | 1981 |
case "getElem": |
24720 | 1982 |
return createEmptyGetter(desc, explicitInstanceOfCheck, name); |
24719 | 1983 |
default: |
24720 | 1984 |
throw new AssertionError(operator); // never invoked with any other operation |
16147 | 1985 |
} |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
1986 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
1987 |
|
26511
65722244e6b2
8058179: Global constants get in the way of self-modifying properties
hannesw
parents:
26508
diff
changeset
|
1988 |
final GuardedInvocation cinv = Global.getConstants().findGetMethod(find, this, desc); |
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24733
diff
changeset
|
1989 |
if (cinv != null) { |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24733
diff
changeset
|
1990 |
return cinv; |
16147 | 1991 |
} |
1992 |
||
1993 |
final Class<?> returnType = desc.getMethodType().returnType(); |
|
24720 | 1994 |
final Property property = find.getProperty(); |
24719 | 1995 |
|
1996 |
final int programPoint = NashornCallSiteDescriptor.isOptimistic(desc) ? |
|
1997 |
NashornCallSiteDescriptor.getProgramPoint(desc) : |
|
1998 |
UnwarrantedOptimismException.INVALID_PROGRAM_POINT; |
|
24720 | 1999 |
|
26508
b40ef4386b01
8057021: UserAccessorProperty guards fail with multiple globals
hannesw
parents:
26377
diff
changeset
|
2000 |
mh = find.getGetter(returnType, programPoint, request); |
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
2001 |
// Get the appropriate guard for this callsite and property. |
24731
ab0c8fc915ae
8038406: Testability: as a first step of moving loggers away from the process global space, the Debug object now supports logging POJOs from log entries as an event queue, which can be introspected from test scripts. This is way better than screen scraping brittle and subject-to-change log output.
lagergren
parents:
24729
diff
changeset
|
2002 |
final MethodHandle guard = NashornGuards.getGuard(this, property, desc, explicitInstanceOfCheck); |
23084
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
2003 |
final ScriptObject owner = find.getOwner(); |
24727 | 2004 |
final Class<ClassCastException> exception = explicitInstanceOfCheck ? null : ClassCastException.class; |
24720 | 2005 |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24733
diff
changeset
|
2006 |
final SwitchPoint protoSwitchPoint; |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24733
diff
changeset
|
2007 |
|
24720 | 2008 |
if (mh == null) { |
2009 |
mh = Lookup.emptyGetter(returnType); |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24733
diff
changeset
|
2010 |
protoSwitchPoint = getProtoSwitchPoint(name, owner); |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24733
diff
changeset
|
2011 |
} else if (!find.isSelf()) { |
26508
b40ef4386b01
8057021: UserAccessorProperty guards fail with multiple globals
hannesw
parents:
26377
diff
changeset
|
2012 |
assert mh.type().returnType().equals(returnType) : |
b40ef4386b01
8057021: UserAccessorProperty guards fail with multiple globals
hannesw
parents:
26377
diff
changeset
|
2013 |
"return type mismatch for getter " + mh.type().returnType() + " != " + returnType; |
b40ef4386b01
8057021: UserAccessorProperty guards fail with multiple globals
hannesw
parents:
26377
diff
changeset
|
2014 |
if (!(property instanceof UserAccessorProperty)) { |
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
2015 |
// Add a filter that replaces the self object with the prototype owning the property. |
24727 | 2016 |
mh = addProtoFilter(mh, find.getProtoChainLength()); |
16147 | 2017 |
} |
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24733
diff
changeset
|
2018 |
protoSwitchPoint = getProtoSwitchPoint(name, owner); |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24733
diff
changeset
|
2019 |
} else { |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24733
diff
changeset
|
2020 |
protoSwitchPoint = null; |
16147 | 2021 |
} |
2022 |
||
24720 | 2023 |
assert OBJECT_FIELDS_ONLY || guard != null : "we always need a map guard here"; |
2024 |
||
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24733
diff
changeset
|
2025 |
final GuardedInvocation inv = new GuardedInvocation(mh, guard, protoSwitchPoint, exception); |
26768
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
2026 |
return inv.addSwitchPoint(findBuiltinSwitchPoint(name)); |
16147 | 2027 |
} |
2028 |
||
24777
ed1974940ff4
8044750: megamorphic getter for scope objects does not call __noSuchProperty__ hook
sundar
parents:
24772
diff
changeset
|
2029 |
private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name, final boolean isMethod) { |
24745
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
2030 |
Context.getContextTrusted().getLogger(ObjectClassGenerator.class).warning("Megamorphic getter: " + desc + " " + name + " " +isMethod); |
24777
ed1974940ff4
8044750: megamorphic getter for scope objects does not call __noSuchProperty__ hook
sundar
parents:
24772
diff
changeset
|
2031 |
final MethodHandle invoker = MH.insertArguments(MEGAMORPHIC_GET, 1, name, isMethod); |
24731
ab0c8fc915ae
8038406: Testability: as a first step of moving loggers away from the process global space, the Debug object now supports logging POJOs from log entries as an event queue, which can be introspected from test scripts. This is way better than screen scraping brittle and subject-to-change log output.
lagergren
parents:
24729
diff
changeset
|
2032 |
final MethodHandle guard = getScriptObjectGuard(desc.getMethodType(), true); |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
2033 |
return new GuardedInvocation(invoker, guard); |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
2034 |
} |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
2035 |
|
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
2036 |
@SuppressWarnings("unused") |
24777
ed1974940ff4
8044750: megamorphic getter for scope objects does not call __noSuchProperty__ hook
sundar
parents:
24772
diff
changeset
|
2037 |
private Object megamorphicGet(final String key, final boolean isMethod) { |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
2038 |
final FindProperty find = findProperty(key, true); |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
2039 |
if (find != null) { |
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
2040 |
return find.getObjectValue(); |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
2041 |
} |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
2042 |
|
24719 | 2043 |
return isMethod ? getNoSuchMethod(key, INVALID_PROGRAM_POINT) : invokeNoSuchProperty(key, INVALID_PROGRAM_POINT); |
16147 | 2044 |
} |
2045 |
||
26377
028dad61662f
8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents:
26068
diff
changeset
|
2046 |
// Marks a property as declared and sets its value. Used as slow path for block-scoped LET and CONST |
028dad61662f
8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents:
26068
diff
changeset
|
2047 |
@SuppressWarnings("unused") |
028dad61662f
8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents:
26068
diff
changeset
|
2048 |
private void declareAndSet(final String key, final Object value) { |
26886
18c744ab4df2
8059211: Changed ArrayData.length accessor to use the protected field and fixed javadoc warnings related to this
lagergren
parents:
26768
diff
changeset
|
2049 |
final PropertyMap oldMap = getMap(); |
26377
028dad61662f
8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents:
26068
diff
changeset
|
2050 |
final FindProperty find = findProperty(key, false); |
028dad61662f
8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents:
26068
diff
changeset
|
2051 |
assert find != null; |
028dad61662f
8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents:
26068
diff
changeset
|
2052 |
|
028dad61662f
8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents:
26068
diff
changeset
|
2053 |
final Property property = find.getProperty(); |
028dad61662f
8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents:
26068
diff
changeset
|
2054 |
assert property != null; |
028dad61662f
8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents:
26068
diff
changeset
|
2055 |
assert property.needsDeclaration(); |
028dad61662f
8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents:
26068
diff
changeset
|
2056 |
|
26886
18c744ab4df2
8059211: Changed ArrayData.length accessor to use the protected field and fixed javadoc warnings related to this
lagergren
parents:
26768
diff
changeset
|
2057 |
final PropertyMap newMap = oldMap.replaceProperty(property, property.removeFlags(Property.NEEDS_DECLARATION)); |
26377
028dad61662f
8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents:
26068
diff
changeset
|
2058 |
setMap(newMap); |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
2059 |
set(key, value, 0); |
26377
028dad61662f
8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents:
26068
diff
changeset
|
2060 |
} |
028dad61662f
8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents:
26068
diff
changeset
|
2061 |
|
16147 | 2062 |
/** |
2063 |
* Find the appropriate GETINDEX method for an invoke dynamic call. |
|
2064 |
* |
|
16195
3f6c0ab2597a
8006766: Array-like access to characters of a string is slow
hannesw
parents:
16194
diff
changeset
|
2065 |
* @param desc the call site descriptor |
3f6c0ab2597a
8006766: Array-like access to characters of a string is slow
hannesw
parents:
16194
diff
changeset
|
2066 |
* @param request the link request |
16147 | 2067 |
* |
2068 |
* @return GuardedInvocation to be invoked at call site. |
|
2069 |
*/ |
|
16195
3f6c0ab2597a
8006766: Array-like access to characters of a string is slow
hannesw
parents:
16194
diff
changeset
|
2070 |
protected GuardedInvocation findGetIndexMethod(final CallSiteDescriptor desc, final LinkRequest request) { |
24720 | 2071 |
final MethodType callType = desc.getMethodType(); |
2072 |
final Class<?> returnType = callType.returnType(); |
|
2073 |
final Class<?> returnClass = returnType.isPrimitive() ? returnType : Object.class; |
|
2074 |
final Class<?> keyClass = callType.parameterType(1); |
|
2075 |
final boolean explicitInstanceOfCheck = explicitInstanceOfCheck(desc, request); |
|
24719 | 2076 |
|
2077 |
final String name; |
|
2078 |
if (returnClass.isPrimitive()) { |
|
2079 |
//turn e.g. get with a double into getDouble |
|
2080 |
final String returnTypeName = returnClass.getName(); |
|
2081 |
name = "get" + Character.toUpperCase(returnTypeName.charAt(0)) + returnTypeName.substring(1, returnTypeName.length()); |
|
2082 |
} else { |
|
2083 |
name = "get"; |
|
2084 |
} |
|
2085 |
||
2086 |
final MethodHandle mh = findGetIndexMethodHandle(returnClass, name, keyClass, desc); |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24733
diff
changeset
|
2087 |
return new GuardedInvocation(mh, getScriptObjectGuard(callType, explicitInstanceOfCheck), (SwitchPoint)null, explicitInstanceOfCheck ? null : ClassCastException.class); |
24721
81f70e23cd3b
8036127: Prototype filter needs to be applied to getter guard as well, not just getter
lagergren
parents:
24720
diff
changeset
|
2088 |
} |
81f70e23cd3b
8036127: Prototype filter needs to be applied to getter guard as well, not just getter
lagergren
parents:
24720
diff
changeset
|
2089 |
|
81f70e23cd3b
8036127: Prototype filter needs to be applied to getter guard as well, not just getter
lagergren
parents:
24720
diff
changeset
|
2090 |
private static MethodHandle getScriptObjectGuard(final MethodType type, final boolean explicitInstanceOfCheck) { |
81f70e23cd3b
8036127: Prototype filter needs to be applied to getter guard as well, not just getter
lagergren
parents:
24720
diff
changeset
|
2091 |
return ScriptObject.class.isAssignableFrom(type.parameterType(0)) ? null : NashornGuards.getScriptObjectGuard(explicitInstanceOfCheck); |
16147 | 2092 |
} |
2093 |
||
2094 |
/** |
|
24719 | 2095 |
* Find a handle for a getIndex method |
2096 |
* @param returnType return type for getter |
|
2097 |
* @param name name |
|
2098 |
* @param elementType index type for getter |
|
2099 |
* @param desc call site descriptor |
|
2100 |
* @return method handle for getter |
|
16147 | 2101 |
*/ |
24720 | 2102 |
protected MethodHandle findGetIndexMethodHandle(final Class<?> returnType, final String name, final Class<?> elementType, final CallSiteDescriptor desc) { |
24719 | 2103 |
if (!returnType.isPrimitive()) { |
2104 |
return findOwnMH_V(getClass(), name, returnType, elementType); |
|
16147 | 2105 |
} |
2106 |
||
24719 | 2107 |
return MH.insertArguments( |
2108 |
findOwnMH_V(getClass(), name, returnType, elementType, int.class), |
|
2109 |
2, |
|
2110 |
NashornCallSiteDescriptor.isOptimistic(desc) ? |
|
2111 |
NashornCallSiteDescriptor.getProgramPoint(desc) : |
|
2112 |
INVALID_PROGRAM_POINT); |
|
16147 | 2113 |
} |
2114 |
||
2115 |
/** |
|
23084
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
2116 |
* Get a switch point for a property with the given {@code name} that will be invalidated when |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
2117 |
* the property definition is changed in this object's prototype chain. Returns {@code null} if |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
2118 |
* the property is defined in this object itself. |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
2119 |
* |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
2120 |
* @param name the property name |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
2121 |
* @param owner the property owner, null if property is not defined |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
2122 |
* @return a SwitchPoint or null |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
2123 |
*/ |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
2124 |
public final SwitchPoint getProtoSwitchPoint(final String name, final ScriptObject owner) { |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
2125 |
if (owner == this || getProto() == null) { |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
2126 |
return null; |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
2127 |
} |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
2128 |
|
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
2129 |
for (ScriptObject obj = this; obj != owner && obj.getProto() != null; obj = obj.getProto()) { |
24731
ab0c8fc915ae
8038406: Testability: as a first step of moving loggers away from the process global space, the Debug object now supports logging POJOs from log entries as an event queue, which can be introspected from test scripts. This is way better than screen scraping brittle and subject-to-change log output.
lagergren
parents:
24729
diff
changeset
|
2130 |
final ScriptObject parent = obj.getProto(); |
23084
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
2131 |
parent.getMap().addListener(name, obj.getMap()); |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
2132 |
} |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
2133 |
|
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
2134 |
return getMap().getSwitchPoint(name); |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
2135 |
} |
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
2136 |
|
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
2137 |
/** |
16147 | 2138 |
* Find the appropriate SET method for an invoke dynamic call. |
2139 |
* |
|
16195
3f6c0ab2597a
8006766: Array-like access to characters of a string is slow
hannesw
parents:
16194
diff
changeset
|
2140 |
* @param desc the call site descriptor |
3f6c0ab2597a
8006766: Array-like access to characters of a string is slow
hannesw
parents:
16194
diff
changeset
|
2141 |
* @param request the link request |
16147 | 2142 |
* |
2143 |
* @return GuardedInvocation to be invoked at call site. |
|
2144 |
*/ |
|
16195
3f6c0ab2597a
8006766: Array-like access to characters of a string is slow
hannesw
parents:
16194
diff
changeset
|
2145 |
protected GuardedInvocation findSetMethod(final CallSiteDescriptor desc, final LinkRequest request) { |
16159 | 2146 |
final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND); |
24721
81f70e23cd3b
8036127: Prototype filter needs to be applied to getter guard as well, not just getter
lagergren
parents:
24720
diff
changeset
|
2147 |
|
22377 | 2148 |
if (request.isCallSiteUnstable() || hasWithScope()) { |
16147 | 2149 |
return findMegaMorphicSetMethod(desc, name); |
2150 |
} |
|
2151 |
||
24721
81f70e23cd3b
8036127: Prototype filter needs to be applied to getter guard as well, not just getter
lagergren
parents:
24720
diff
changeset
|
2152 |
final boolean explicitInstanceOfCheck = explicitInstanceOfCheck(desc, request); |
24720 | 2153 |
|
16161
0ebfaec3a45b
8005848: assigning to global toString variable affects Object.prototype.toString
sundar
parents:
16159
diff
changeset
|
2154 |
/* |
0ebfaec3a45b
8005848: assigning to global toString variable affects Object.prototype.toString
sundar
parents:
16159
diff
changeset
|
2155 |
* If doing property set on a scope object, we should stop proto search on the first |
16264
e0c3c97cd93e
8006984: Introducing local into a function inside with statement confuses its scope
attila
parents:
16256
diff
changeset
|
2156 |
* non-scope object. Without this, for example, when assigning "toString" on global scope, |
16161
0ebfaec3a45b
8005848: assigning to global toString variable affects Object.prototype.toString
sundar
parents:
16159
diff
changeset
|
2157 |
* we'll end up assigning it on it's proto - which is Object.prototype.toString !! |
0ebfaec3a45b
8005848: assigning to global toString variable affects Object.prototype.toString
sundar
parents:
16159
diff
changeset
|
2158 |
* |
0ebfaec3a45b
8005848: assigning to global toString variable affects Object.prototype.toString
sundar
parents:
16159
diff
changeset
|
2159 |
* toString = function() { print("global toString"); } // don't affect Object.prototype.toString |
0ebfaec3a45b
8005848: assigning to global toString variable affects Object.prototype.toString
sundar
parents:
16159
diff
changeset
|
2160 |
*/ |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
2161 |
FindProperty find = findProperty(name, true, this); |
19880
ba17a955c28b
8024120: Setting __proto__ to null removes the __proto__ property
sundar
parents:
19630
diff
changeset
|
2162 |
|
16159 | 2163 |
// If it's not a scope search, then we don't want any inherited properties except those with user defined accessors. |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
2164 |
if (find != null && find.isInherited() && !(find.getProperty() instanceof UserAccessorProperty)) { |
16159 | 2165 |
// We should still check if inherited data property is not writable |
16224
0c49ad4e3b55
8006222: Move slot from SpillProperty to Property
jlaskey
parents:
16223
diff
changeset
|
2166 |
if (isExtensible() && !find.getProperty().isWritable()) { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
2167 |
return createEmptySetMethod(desc, explicitInstanceOfCheck, "property.not.writable", true); |
16147 | 2168 |
} |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
2169 |
// Otherwise, forget the found property unless this is a scope callsite and the owner is a scope object as well. |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
2170 |
if (!NashornCallSiteDescriptor.isScope(desc) || !find.getOwner().isScope()) { |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
2171 |
find = null; |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
2172 |
} |
16147 | 2173 |
} |
2174 |
||
2175 |
if (find != null) { |
|
26377
028dad61662f
8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents:
26068
diff
changeset
|
2176 |
if (!find.getProperty().isWritable() && !NashornCallSiteDescriptor.isDeclaration(desc)) { |
16159 | 2177 |
// Existing, non-writable property |
24720 | 2178 |
return createEmptySetMethod(desc, explicitInstanceOfCheck, "property.not.writable", true); |
16147 | 2179 |
} |
19880
ba17a955c28b
8024120: Setting __proto__ to null removes the __proto__ property
sundar
parents:
19630
diff
changeset
|
2180 |
} else { |
24769 | 2181 |
if (!isExtensible()) { |
24720 | 2182 |
return createEmptySetMethod(desc, explicitInstanceOfCheck, "object.non.extensible", false); |
19880
ba17a955c28b
8024120: Setting __proto__ to null removes the __proto__ property
sundar
parents:
19630
diff
changeset
|
2183 |
} |
16147 | 2184 |
} |
2185 |
||
26768
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
2186 |
final GuardedInvocation inv = new SetMethodCreator(this, find, desc, request).createGuardedInvocation(findBuiltinSwitchPoint(name)); |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
2187 |
|
24745
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
2188 |
final GuardedInvocation cinv = Global.getConstants().findSetMethod(find, this, inv, desc, request); |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
2189 |
if (cinv != null) { |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
2190 |
return cinv; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
2191 |
} |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
2192 |
|
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
2193 |
return inv; |
16147 | 2194 |
} |
2195 |
||
24720 | 2196 |
private GuardedInvocation createEmptySetMethod(final CallSiteDescriptor desc, final boolean explicitInstanceOfCheck, final String strictErrorMessage, final boolean canBeFastScope) { |
2197 |
final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND); |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
2198 |
if (NashornCallSiteDescriptor.isStrict(desc)) { |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
2199 |
throw typeError(strictErrorMessage, name, ScriptRuntime.safeToString(this)); |
16147 | 2200 |
} |
24720 | 2201 |
assert canBeFastScope || !NashornCallSiteDescriptor.isFastScope(desc); |
2202 |
return new GuardedInvocation( |
|
2203 |
Lookup.EMPTY_SETTER, |
|
24727 | 2204 |
NashornGuards.getMapGuard(getMap(), explicitInstanceOfCheck), |
2205 |
getProtoSwitchPoint(name, null), |
|
24720 | 2206 |
explicitInstanceOfCheck ? null : ClassCastException.class); |
16147 | 2207 |
} |
2208 |
||
2209 |
@SuppressWarnings("unused") |
|
24719 | 2210 |
private boolean extensionCheck(final boolean isStrict, final String name) { |
2211 |
if (isExtensible()) { |
|
2212 |
return true; //go on and do the set. this is our guard |
|
2213 |
} else if (isStrict) { |
|
2214 |
//throw an error for attempting to do the set in strict mode |
|
2215 |
throw typeError("object.non.extensible", name, ScriptRuntime.safeToString(this)); |
|
16147 | 2216 |
} else { |
24719 | 2217 |
//not extensible, non strict - this is a nop |
16147 | 2218 |
return false; |
2219 |
} |
|
2220 |
} |
|
2221 |
||
24719 | 2222 |
private GuardedInvocation findMegaMorphicSetMethod(final CallSiteDescriptor desc, final String name) { |
24720 | 2223 |
final MethodType type = desc.getMethodType().insertParameterTypes(1, Object.class); |
2224 |
//never bother with ClassCastExceptionGuard for megamorphic callsites |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
2225 |
final GuardedInvocation inv = findSetIndexMethod(getClass(), desc, false, type); |
16147 | 2226 |
return inv.replaceMethods(MH.insertArguments(inv.getInvocation(), 1, name), inv.getGuard()); |
2227 |
} |
|
2228 |
||
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
2229 |
@SuppressWarnings("unused") |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
2230 |
private static Object globalFilter(final Object object) { |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
2231 |
ScriptObject sobj = (ScriptObject) object; |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
2232 |
while (sobj != null && !(sobj instanceof Global)) { |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
2233 |
sobj = sobj.getProto(); |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
2234 |
} |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
2235 |
return sobj; |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
2236 |
} |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
2237 |
|
24719 | 2238 |
/** |
2239 |
* Lookup function for the set index method, available for subclasses as well, e.g. {@link NativeArray} |
|
2240 |
* provides special quick accessor linkage for continuous arrays that are represented as Java arrays |
|
2241 |
* |
|
2242 |
* @param desc call site descriptor |
|
2243 |
* @param request link request |
|
2244 |
* |
|
2245 |
* @return GuardedInvocation to be invoked at call site. |
|
2246 |
*/ |
|
2247 |
protected GuardedInvocation findSetIndexMethod(final CallSiteDescriptor desc, final LinkRequest request) { // array, index, value |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
2248 |
return findSetIndexMethod(getClass(), desc, explicitInstanceOfCheck(desc, request), desc.getMethodType()); |
16147 | 2249 |
} |
2250 |
||
2251 |
/** |
|
2252 |
* Find the appropriate SETINDEX method for an invoke dynamic call. |
|
2253 |
* |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
2254 |
* @param clazz the receiver class |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
2255 |
* @param desc the call site descriptor |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
2256 |
* @param explicitInstanceOfCheck add an explicit instanceof check? |
16147 | 2257 |
* @param callType the method type at the call site |
2258 |
* |
|
2259 |
* @return GuardedInvocation to be invoked at call site. |
|
2260 |
*/ |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
2261 |
private static GuardedInvocation findSetIndexMethod(final Class<? extends ScriptObject> clazz, final CallSiteDescriptor desc, final boolean explicitInstanceOfCheck, final MethodType callType) { |
16147 | 2262 |
assert callType.parameterCount() == 3; |
24720 | 2263 |
final Class<?> keyClass = callType.parameterType(1); |
2264 |
final Class<?> valueClass = callType.parameterType(2); |
|
16147 | 2265 |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
2266 |
MethodHandle methodHandle = findOwnMH_V(clazz, "set", void.class, keyClass, valueClass, int.class); |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
2267 |
methodHandle = MH.insertArguments(methodHandle, 3, NashornCallSiteDescriptor.getFlags(desc)); |
16147 | 2268 |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24733
diff
changeset
|
2269 |
return new GuardedInvocation(methodHandle, getScriptObjectGuard(callType, explicitInstanceOfCheck), (SwitchPoint)null, explicitInstanceOfCheck ? null : ClassCastException.class); |
16147 | 2270 |
} |
2271 |
||
2272 |
/** |
|
2273 |
* Fall back if a function property is not found. |
|
2274 |
* @param desc The call site descriptor |
|
16195
3f6c0ab2597a
8006766: Array-like access to characters of a string is slow
hannesw
parents:
16194
diff
changeset
|
2275 |
* @param request the link request |
16147 | 2276 |
* @return GuardedInvocation to be invoked at call site. |
2277 |
*/ |
|
16195
3f6c0ab2597a
8006766: Array-like access to characters of a string is slow
hannesw
parents:
16194
diff
changeset
|
2278 |
public GuardedInvocation noSuchMethod(final CallSiteDescriptor desc, final LinkRequest request) { |
16147 | 2279 |
final String name = desc.getNameToken(2); |
2280 |
final FindProperty find = findProperty(NO_SUCH_METHOD_NAME, true); |
|
2281 |
final boolean scopeCall = isScope() && NashornCallSiteDescriptor.isScope(desc); |
|
2282 |
||
2283 |
if (find == null) { |
|
16205
93fda2507e35
8007286: Add JavaAdapter and importPackage to compatibility script
sundar
parents:
16201
diff
changeset
|
2284 |
return noSuchProperty(desc, request); |
16147 | 2285 |
} |
2286 |
||
24720 | 2287 |
final boolean explicitInstanceOfCheck = explicitInstanceOfCheck(desc, request); |
2288 |
||
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
2289 |
final Object value = find.getObjectValue(); |
24720 | 2290 |
if (!(value instanceof ScriptFunction)) { |
2291 |
return createEmptyGetter(desc, explicitInstanceOfCheck, name); |
|
18871
a27c6a5b999c
8020223: ClassCastException: String can not be casted to ScriptFunction
sundar
parents:
18860
diff
changeset
|
2292 |
} |
a27c6a5b999c
8020223: ClassCastException: String can not be casted to ScriptFunction
sundar
parents:
18860
diff
changeset
|
2293 |
|
a27c6a5b999c
8020223: ClassCastException: String can not be casted to ScriptFunction
sundar
parents:
18860
diff
changeset
|
2294 |
final ScriptFunction func = (ScriptFunction)value; |
24720 | 2295 |
final Object thiz = scopeCall && func.isStrict() ? ScriptRuntime.UNDEFINED : this; |
16147 | 2296 |
// TODO: It'd be awesome if we could bind "name" without binding "this". |
24720 | 2297 |
return new GuardedInvocation( |
2298 |
MH.dropArguments( |
|
2299 |
MH.constant( |
|
2300 |
ScriptFunction.class, |
|
2301 |
func.makeBoundFunction(thiz, new Object[] { name })), |
|
2302 |
0, |
|
2303 |
Object.class), |
|
2304 |
NashornGuards.getMapGuard(getMap(), explicitInstanceOfCheck), |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24733
diff
changeset
|
2305 |
(SwitchPoint)null, |
24720 | 2306 |
explicitInstanceOfCheck ? null : ClassCastException.class); |
16147 | 2307 |
} |
2308 |
||
2309 |
/** |
|
2310 |
* Fall back if a property is not found. |
|
2311 |
* @param desc the call site descriptor. |
|
16195
3f6c0ab2597a
8006766: Array-like access to characters of a string is slow
hannesw
parents:
16194
diff
changeset
|
2312 |
* @param request the link request |
16147 | 2313 |
* @return GuardedInvocation to be invoked at call site. |
2314 |
*/ |
|
16195
3f6c0ab2597a
8006766: Array-like access to characters of a string is slow
hannesw
parents:
16194
diff
changeset
|
2315 |
public GuardedInvocation noSuchProperty(final CallSiteDescriptor desc, final LinkRequest request) { |
24720 | 2316 |
final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND); |
2317 |
final FindProperty find = findProperty(NO_SUCH_PROPERTY_NAME, true); |
|
2318 |
final boolean scopeAccess = isScope() && NashornCallSiteDescriptor.isScope(desc); |
|
16147 | 2319 |
|
2320 |
if (find != null) { |
|
24759
31aed7d9c02a
8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents:
24751
diff
changeset
|
2321 |
final Object value = find.getObjectValue(); |
31aed7d9c02a
8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents:
24751
diff
changeset
|
2322 |
ScriptFunction func = null; |
31aed7d9c02a
8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents:
24751
diff
changeset
|
2323 |
MethodHandle mh = null; |
19472
9476460521b3
8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents:
19460
diff
changeset
|
2324 |
|
18871
a27c6a5b999c
8020223: ClassCastException: String can not be casted to ScriptFunction
sundar
parents:
18860
diff
changeset
|
2325 |
if (value instanceof ScriptFunction) { |
a27c6a5b999c
8020223: ClassCastException: String can not be casted to ScriptFunction
sundar
parents:
18860
diff
changeset
|
2326 |
func = (ScriptFunction)value; |
24759
31aed7d9c02a
8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents:
24751
diff
changeset
|
2327 |
mh = getCallMethodHandle(func, desc.getMethodType(), name); |
18871
a27c6a5b999c
8020223: ClassCastException: String can not be casted to ScriptFunction
sundar
parents:
18860
diff
changeset
|
2328 |
} |
16147 | 2329 |
|
24759
31aed7d9c02a
8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents:
24751
diff
changeset
|
2330 |
if (mh != null) { |
31aed7d9c02a
8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents:
24751
diff
changeset
|
2331 |
assert func != null; |
24993
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24777
diff
changeset
|
2332 |
if (scopeAccess && func.isStrict()) { |
24759
31aed7d9c02a
8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents:
24751
diff
changeset
|
2333 |
mh = bindTo(mh, UNDEFINED); |
16147 | 2334 |
} |
25421
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
2335 |
|
24719 | 2336 |
return new GuardedInvocation( |
24759
31aed7d9c02a
8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents:
24751
diff
changeset
|
2337 |
mh, |
25421
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
2338 |
find.isSelf()? |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
2339 |
getKnownFunctionPropertyGuardSelf( |
24720 | 2340 |
getMap(), |
26508
b40ef4386b01
8057021: UserAccessorProperty guards fail with multiple globals
hannesw
parents:
26377
diff
changeset
|
2341 |
find.getGetter(Object.class, INVALID_PROGRAM_POINT, request), |
25421
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
2342 |
func) |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
2343 |
: |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
2344 |
//TODO this always does a scriptobject check |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
2345 |
getKnownFunctionPropertyGuardProto( |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
2346 |
getMap(), |
26508
b40ef4386b01
8057021: UserAccessorProperty guards fail with multiple globals
hannesw
parents:
26377
diff
changeset
|
2347 |
find.getGetter(Object.class, INVALID_PROGRAM_POINT, request), |
25421
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
2348 |
find.getProtoChainLength(), |
24720 | 2349 |
func), |
23084
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
2350 |
getProtoSwitchPoint(NO_SUCH_PROPERTY_NAME, find.getOwner()), |
24720 | 2351 |
//TODO this doesn't need a ClassCastException as guard always checks script object |
2352 |
null); |
|
16147 | 2353 |
} |
2354 |
} |
|
2355 |
||
2356 |
if (scopeAccess) { |
|
16256
f2d9a0c49914
8007002: Replace implicit exception throwing methods with explicit throws - simplify control flow and remove useless code
lagergren
parents:
16240
diff
changeset
|
2357 |
throw referenceError("not.defined", name); |
16147 | 2358 |
} |
2359 |
||
24720 | 2360 |
return createEmptyGetter(desc, explicitInstanceOfCheck(desc, request), name); |
16147 | 2361 |
} |
22386
b421b9049d11
8031715: Indexed access to java package not working
sundar
parents:
22377
diff
changeset
|
2362 |
|
17234
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2363 |
/** |
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2364 |
* Invoke fall back if a property is not found. |
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2365 |
* @param name Name of property. |
24720 | 2366 |
* @param programPoint program point |
17234
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2367 |
* @return Result from call. |
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2368 |
*/ |
24719 | 2369 |
protected Object invokeNoSuchProperty(final String name, final int programPoint) { |
17234
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2370 |
final FindProperty find = findProperty(NO_SUCH_PROPERTY_NAME, true); |
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2371 |
|
24719 | 2372 |
Object ret = UNDEFINED; |
2373 |
||
17234
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2374 |
if (find != null) { |
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
2375 |
final Object func = find.getObjectValue(); |
17234
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2376 |
|
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2377 |
if (func instanceof ScriptFunction) { |
24719 | 2378 |
ret = ScriptRuntime.apply((ScriptFunction)func, this, name); |
17234
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2379 |
} |
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2380 |
} |
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2381 |
|
24719 | 2382 |
if (isValid(programPoint)) { |
2383 |
throw new UnwarrantedOptimismException(ret, programPoint); |
|
2384 |
} |
|
2385 |
||
2386 |
return ret; |
|
17234
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2387 |
} |
16147 | 2388 |
|
24719 | 2389 |
|
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
2390 |
/** |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
2391 |
* Get __noSuchMethod__ as a function bound to this object and {@code name} if it is defined. |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
2392 |
* @param name the method name |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
2393 |
* @return the bound function, or undefined |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
2394 |
*/ |
24719 | 2395 |
private Object getNoSuchMethod(final String name, final int programPoint) { |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
2396 |
final FindProperty find = findProperty(NO_SUCH_METHOD_NAME, true); |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
2397 |
|
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
2398 |
if (find == null) { |
24719 | 2399 |
return invokeNoSuchProperty(name, programPoint); |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
2400 |
} |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
2401 |
|
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
2402 |
final Object value = find.getObjectValue(); |
24719 | 2403 |
if (!(value instanceof ScriptFunction)) { |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
2404 |
return UNDEFINED; |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
2405 |
} |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
2406 |
|
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
2407 |
return ((ScriptFunction)value).makeBoundFunction(this, new Object[] {name}); |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
2408 |
} |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
2409 |
|
24720 | 2410 |
private GuardedInvocation createEmptyGetter(final CallSiteDescriptor desc, final boolean explicitInstanceOfCheck, final String name) { |
2411 |
if (NashornCallSiteDescriptor.isOptimistic(desc)) { |
|
24719 | 2412 |
throw new UnwarrantedOptimismException(UNDEFINED, NashornCallSiteDescriptor.getProgramPoint(desc), Type.OBJECT); |
2413 |
} |
|
24720 | 2414 |
|
23084
6c5c02d1023a
8035948: Redesign property listeners for shared classes
hannesw
parents:
23083
diff
changeset
|
2415 |
return new GuardedInvocation(Lookup.emptyGetter(desc.getMethodType().returnType()), |
24727 | 2416 |
NashornGuards.getMapGuard(getMap(), explicitInstanceOfCheck), getProtoSwitchPoint(name, null), |
2417 |
explicitInstanceOfCheck ? null : ClassCastException.class); |
|
16147 | 2418 |
} |
2419 |
||
2420 |
private abstract static class ScriptObjectIterator <T extends Object> implements Iterator<T> { |
|
2421 |
protected T[] values; |
|
2422 |
protected final ScriptObject object; |
|
2423 |
private int index; |
|
2424 |
||
2425 |
ScriptObjectIterator(final ScriptObject object) { |
|
2426 |
this.object = object; |
|
2427 |
} |
|
2428 |
||
2429 |
protected abstract void init(); |
|
2430 |
||
2431 |
@Override |
|
2432 |
public boolean hasNext() { |
|
2433 |
if (values == null) { |
|
2434 |
init(); |
|
2435 |
} |
|
2436 |
return index < values.length; |
|
2437 |
} |
|
2438 |
||
2439 |
@Override |
|
2440 |
public T next() { |
|
2441 |
if (values == null) { |
|
2442 |
init(); |
|
2443 |
} |
|
2444 |
return values[index++]; |
|
2445 |
} |
|
2446 |
||
2447 |
@Override |
|
2448 |
public void remove() { |
|
26768
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26765
diff
changeset
|
2449 |
throw new UnsupportedOperationException("remove"); |
16147 | 2450 |
} |
2451 |
} |
|
2452 |
||
2453 |
private static class KeyIterator extends ScriptObjectIterator<String> { |
|
2454 |
KeyIterator(final ScriptObject object) { |
|
2455 |
super(object); |
|
2456 |
} |
|
2457 |
||
2458 |
@Override |
|
2459 |
protected void init() { |
|
2460 |
final Set<String> keys = new LinkedHashSet<>(); |
|
26058
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
2461 |
final Set<String> nonEnumerable = new HashSet<>(); |
16147 | 2462 |
for (ScriptObject self = object; self != null; self = self.getProto()) { |
26058
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
2463 |
keys.addAll(Arrays.asList(self.getOwnKeys(false, nonEnumerable))); |
16147 | 2464 |
} |
2465 |
this.values = keys.toArray(new String[keys.size()]); |
|
2466 |
} |
|
2467 |
} |
|
2468 |
||
2469 |
private static class ValueIterator extends ScriptObjectIterator<Object> { |
|
2470 |
ValueIterator(final ScriptObject object) { |
|
2471 |
super(object); |
|
2472 |
} |
|
2473 |
||
2474 |
@Override |
|
2475 |
protected void init() { |
|
2476 |
final ArrayList<Object> valueList = new ArrayList<>(); |
|
26058
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
2477 |
final Set<String> nonEnumerable = new HashSet<>(); |
16147 | 2478 |
for (ScriptObject self = object; self != null; self = self.getProto()) { |
26058
17acdbe290b2
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
sundar
parents:
25821
diff
changeset
|
2479 |
for (final String key : self.getOwnKeys(false, nonEnumerable)) { |
16147 | 2480 |
valueList.add(self.get(key)); |
2481 |
} |
|
2482 |
} |
|
2483 |
this.values = valueList.toArray(new Object[valueList.size()]); |
|
2484 |
} |
|
2485 |
} |
|
2486 |
||
2487 |
/** |
|
2488 |
* Add a spill property for the given key. |
|
2489 |
* @param key Property key. |
|
2490 |
* @param propertyFlags Property flags. |
|
2491 |
* @return Added property. |
|
2492 |
*/ |
|
24719 | 2493 |
private Property addSpillProperty(final String key, final int propertyFlags, final Object value, final boolean hasInitialValue) { |
2494 |
final PropertyMap propertyMap = getMap(); |
|
26060 | 2495 |
final int fieldSlot = propertyMap.getFreeFieldSlot(); |
24719 | 2496 |
|
17513 | 2497 |
Property property; |
26060 | 2498 |
if (fieldSlot > -1) { |
24719 | 2499 |
property = hasInitialValue ? |
26060 | 2500 |
new AccessorProperty(key, propertyFlags, fieldSlot, this, value) : |
2501 |
new AccessorProperty(key, propertyFlags, getClass(), fieldSlot); |
|
17513 | 2502 |
property = addOwnProperty(property); |
2503 |
} else { |
|
26060 | 2504 |
final int spillSlot = propertyMap.getFreeSpillSlot(); |
24719 | 2505 |
property = hasInitialValue ? |
26060 | 2506 |
new SpillProperty(key, propertyFlags, spillSlot, this, value) : |
2507 |
new SpillProperty(key, propertyFlags, spillSlot); |
|
17513 | 2508 |
property = addOwnProperty(property); |
24719 | 2509 |
ensureSpillSize(property.getSlot()); |
16147 | 2510 |
} |
17513 | 2511 |
return property; |
16147 | 2512 |
} |
2513 |
||
2514 |
/** |
|
2515 |
* Add a spill entry for the given key. |
|
17770 | 2516 |
* @param key Property key. |
16147 | 2517 |
* @return Setter method handle. |
2518 |
*/ |
|
24719 | 2519 |
MethodHandle addSpill(final Class<?> type, final String key) { |
2520 |
return addSpillProperty(key, 0, null, false).getSetter(OBJECT_FIELDS_ONLY ? Object.class : type, getMap()); |
|
16147 | 2521 |
} |
2522 |
||
2523 |
/** |
|
2524 |
* Make sure arguments are paired correctly, with respect to more parameters than declared, |
|
2525 |
* fewer parameters than declared and other things that JavaScript allows. This might involve |
|
2526 |
* creating collectors. |
|
2527 |
* |
|
2528 |
* @param methodHandle method handle for invoke |
|
2529 |
* @param callType type of the call |
|
2530 |
* |
|
2531 |
* @return method handle with adjusted arguments |
|
2532 |
*/ |
|
2533 |
protected static MethodHandle pairArguments(final MethodHandle methodHandle, final MethodType callType) { |
|
2534 |
return pairArguments(methodHandle, callType, null); |
|
2535 |
} |
|
2536 |
||
2537 |
/** |
|
2538 |
* Make sure arguments are paired correctly, with respect to more parameters than declared, |
|
2539 |
* fewer parameters than declared and other things that JavaScript allows. This might involve |
|
2540 |
* creating collectors. |
|
2541 |
* |
|
2542 |
* Make sure arguments are paired correctly. |
|
2543 |
* @param methodHandle MethodHandle to adjust. |
|
17239
6dd68632cdcd
8011065: Problems when script implements an interface with variadic methods
attila
parents:
17236
diff
changeset
|
2544 |
* @param callType MethodType of the call site. |
6dd68632cdcd
8011065: Problems when script implements an interface with variadic methods
attila
parents:
17236
diff
changeset
|
2545 |
* @param callerVarArg true if the caller is vararg, false otherwise, null if it should be inferred from the |
6dd68632cdcd
8011065: Problems when script implements an interface with variadic methods
attila
parents:
17236
diff
changeset
|
2546 |
* {@code callType}; basically, if the last parameter type of the call site is an array, it'll be considered a |
6dd68632cdcd
8011065: Problems when script implements an interface with variadic methods
attila
parents:
17236
diff
changeset
|
2547 |
* variable arity call site. These are ordinarily rare; Nashorn code generator creates variable arity call sites |
6dd68632cdcd
8011065: Problems when script implements an interface with variadic methods
attila
parents:
17236
diff
changeset
|
2548 |
* when the call has more than {@link LinkerCallSite#ARGLIMIT} parameters. |
16147 | 2549 |
* |
2550 |
* @return method handle with adjusted arguments |
|
2551 |
*/ |
|
2552 |
public static MethodHandle pairArguments(final MethodHandle methodHandle, final MethodType callType, final Boolean callerVarArg) { |
|
2553 |
final MethodType methodType = methodHandle.type(); |
|
24719 | 2554 |
if (methodType.equals(callType.changeReturnType(methodType.returnType()))) { |
16147 | 2555 |
return methodHandle; |
2556 |
} |
|
2557 |
||
2558 |
final int parameterCount = methodType.parameterCount(); |
|
2559 |
final int callCount = callType.parameterCount(); |
|
2560 |
||
16194
3d0b930f4b47
8006857: ClassCastException when interface implementing function uses arguments object
sundar
parents:
16188
diff
changeset
|
2561 |
final boolean isCalleeVarArg = parameterCount > 0 && methodType.parameterType(parameterCount - 1).isArray(); |
24720 | 2562 |
final boolean isCallerVarArg = callerVarArg != null ? callerVarArg.booleanValue() : callCount > 0 && |
2563 |
callType.parameterType(callCount - 1).isArray(); |
|
16147 | 2564 |
|
2565 |
if (isCalleeVarArg) { |
|
2566 |
return isCallerVarArg ? |
|
2567 |
methodHandle : |
|
2568 |
MH.asCollector(methodHandle, Object[].class, callCount - parameterCount + 1); |
|
2569 |
} |
|
2570 |
||
2571 |
if (isCallerVarArg) { |
|
25237 | 2572 |
return adaptHandleToVarArgCallSite(methodHandle, callCount); |
16147 | 2573 |
} |
2574 |
||
24719 | 2575 |
if (callCount < parameterCount) { |
2576 |
final int missingArgs = parameterCount - callCount; |
|
2577 |
final Object[] fillers = new Object[missingArgs]; |
|
2578 |
||
2579 |
Arrays.fill(fillers, UNDEFINED); |
|
2580 |
||
2581 |
if (isCalleeVarArg) { |
|
2582 |
fillers[missingArgs - 1] = ScriptRuntime.EMPTY_ARRAY; |
|
2583 |
} |
|
2584 |
||
2585 |
return MH.insertArguments( |
|
2586 |
methodHandle, |
|
2587 |
parameterCount - missingArgs, |
|
2588 |
fillers); |
|
2589 |
} |
|
2590 |
||
16147 | 2591 |
if (callCount > parameterCount) { |
2592 |
final int discardedArgs = callCount - parameterCount; |
|
2593 |
||
2594 |
final Class<?>[] discards = new Class<?>[discardedArgs]; |
|
2595 |
Arrays.fill(discards, Object.class); |
|
2596 |
||
2597 |
return MH.dropArguments(methodHandle, callCount - discardedArgs, discards); |
|
2598 |
} |
|
2599 |
||
2600 |
return methodHandle; |
|
2601 |
} |
|
2602 |
||
25237 | 2603 |
static MethodHandle adaptHandleToVarArgCallSite(final MethodHandle mh, final int callSiteParamCount) { |
2604 |
final int spreadArgs = mh.type().parameterCount() - callSiteParamCount + 1; |
|
2605 |
return MH.filterArguments( |
|
2606 |
MH.asSpreader( |
|
2607 |
mh, |
|
2608 |
Object[].class, |
|
2609 |
spreadArgs), |
|
2610 |
callSiteParamCount - 1, |
|
2611 |
MH.insertArguments( |
|
2612 |
TRUNCATINGFILTER, |
|
2613 |
0, |
|
2614 |
spreadArgs) |
|
2615 |
); |
|
2616 |
} |
|
2617 |
||
16147 | 2618 |
@SuppressWarnings("unused") |
2619 |
private static Object[] truncatingFilter(final int n, final Object[] array) { |
|
2620 |
final int length = array == null ? 0 : array.length; |
|
2621 |
if (n == length) { |
|
24719 | 2622 |
return array == null ? ScriptRuntime.EMPTY_ARRAY : array; |
16147 | 2623 |
} |
2624 |
||
2625 |
final Object[] newArray = new Object[n]; |
|
2626 |
||
2627 |
if (array != null) { |
|
24719 | 2628 |
System.arraycopy(array, 0, newArray, 0, Math.min(n, length)); |
16147 | 2629 |
} |
2630 |
||
2631 |
if (length < n) { |
|
2632 |
final Object fill = UNDEFINED; |
|
2633 |
||
2634 |
for (int i = length; i < n; i++) { |
|
2635 |
newArray[i] = fill; |
|
2636 |
} |
|
2637 |
} |
|
2638 |
||
2639 |
return newArray; |
|
2640 |
} |
|
2641 |
||
2642 |
/** |
|
2643 |
* Numeric length setter for length property |
|
2644 |
* |
|
2645 |
* @param newLength new length to set |
|
2646 |
*/ |
|
2647 |
public final void setLength(final long newLength) { |
|
2648 |
final long arrayLength = getArray().length(); |
|
2649 |
if (newLength == arrayLength) { |
|
2650 |
return; |
|
2651 |
} |
|
2652 |
||
2653 |
if (newLength > arrayLength) { |
|
2654 |
setArray(getArray().ensure(newLength - 1)); |
|
24720 | 2655 |
if (getArray().canDelete(arrayLength, newLength - 1, false)) { |
2656 |
setArray(getArray().delete(arrayLength, newLength - 1)); |
|
16147 | 2657 |
} |
2658 |
return; |
|
2659 |
} |
|
2660 |
||
2661 |
if (newLength < arrayLength) { |
|
21441
0b98be59e3cb
8026858: Array length does not handle defined properties correctly
hannesw
parents:
21438
diff
changeset
|
2662 |
long actualLength = newLength; |
0b98be59e3cb
8026858: Array length does not handle defined properties correctly
hannesw
parents:
21438
diff
changeset
|
2663 |
|
0b98be59e3cb
8026858: Array length does not handle defined properties correctly
hannesw
parents:
21438
diff
changeset
|
2664 |
// Check for numeric keys in property map and delete them or adjust length, depending on whether |
0b98be59e3cb
8026858: Array length does not handle defined properties correctly
hannesw
parents:
21438
diff
changeset
|
2665 |
// they're defined as configurable. See ES5 #15.4.5.2 |
0b98be59e3cb
8026858: Array length does not handle defined properties correctly
hannesw
parents:
21438
diff
changeset
|
2666 |
if (getMap().containsArrayKeys()) { |
0b98be59e3cb
8026858: Array length does not handle defined properties correctly
hannesw
parents:
21438
diff
changeset
|
2667 |
|
0b98be59e3cb
8026858: Array length does not handle defined properties correctly
hannesw
parents:
21438
diff
changeset
|
2668 |
for (long l = arrayLength - 1; l >= newLength; l--) { |
0b98be59e3cb
8026858: Array length does not handle defined properties correctly
hannesw
parents:
21438
diff
changeset
|
2669 |
final FindProperty find = findProperty(JSType.toString(l), false); |
0b98be59e3cb
8026858: Array length does not handle defined properties correctly
hannesw
parents:
21438
diff
changeset
|
2670 |
|
0b98be59e3cb
8026858: Array length does not handle defined properties correctly
hannesw
parents:
21438
diff
changeset
|
2671 |
if (find != null) { |
0b98be59e3cb
8026858: Array length does not handle defined properties correctly
hannesw
parents:
21438
diff
changeset
|
2672 |
|
0b98be59e3cb
8026858: Array length does not handle defined properties correctly
hannesw
parents:
21438
diff
changeset
|
2673 |
if (find.getProperty().isConfigurable()) { |
0b98be59e3cb
8026858: Array length does not handle defined properties correctly
hannesw
parents:
21438
diff
changeset
|
2674 |
deleteOwnProperty(find.getProperty()); |
0b98be59e3cb
8026858: Array length does not handle defined properties correctly
hannesw
parents:
21438
diff
changeset
|
2675 |
} else { |
0b98be59e3cb
8026858: Array length does not handle defined properties correctly
hannesw
parents:
21438
diff
changeset
|
2676 |
actualLength = l + 1; |
0b98be59e3cb
8026858: Array length does not handle defined properties correctly
hannesw
parents:
21438
diff
changeset
|
2677 |
break; |
0b98be59e3cb
8026858: Array length does not handle defined properties correctly
hannesw
parents:
21438
diff
changeset
|
2678 |
} |
0b98be59e3cb
8026858: Array length does not handle defined properties correctly
hannesw
parents:
21438
diff
changeset
|
2679 |
} |
0b98be59e3cb
8026858: Array length does not handle defined properties correctly
hannesw
parents:
21438
diff
changeset
|
2680 |
} |
0b98be59e3cb
8026858: Array length does not handle defined properties correctly
hannesw
parents:
21438
diff
changeset
|
2681 |
} |
0b98be59e3cb
8026858: Array length does not handle defined properties correctly
hannesw
parents:
21438
diff
changeset
|
2682 |
|
0b98be59e3cb
8026858: Array length does not handle defined properties correctly
hannesw
parents:
21438
diff
changeset
|
2683 |
setArray(getArray().shrink(actualLength)); |
0b98be59e3cb
8026858: Array length does not handle defined properties correctly
hannesw
parents:
21438
diff
changeset
|
2684 |
getArray().setLength(actualLength); |
16147 | 2685 |
} |
17234
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2686 |
} |
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2687 |
|
24719 | 2688 |
private int getInt(final int index, final String key, final int programPoint) { |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
2689 |
if (isValidArrayIndex(index)) { |
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
2690 |
for (ScriptObject object = this; ; ) { |
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
2691 |
if (object.getMap().containsArrayKeys()) { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
2692 |
final FindProperty find = object.findProperty(key, false, this); |
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
2693 |
|
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
2694 |
if (find != null) { |
24719 | 2695 |
return getIntValue(find, programPoint); |
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
2696 |
} |
17250 | 2697 |
} |
2698 |
||
2699 |
if ((object = object.getProto()) == null) { |
|
2700 |
break; |
|
2701 |
} |
|
2702 |
||
2703 |
final ArrayData array = object.getArray(); |
|
2704 |
||
2705 |
if (array.has(index)) { |
|
24719 | 2706 |
return isValid(programPoint) ? |
2707 |
array.getIntOptimistic(index, programPoint) : |
|
2708 |
array.getInt(index); |
|
17250 | 2709 |
} |
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
2710 |
} |
17250 | 2711 |
} else { |
2712 |
final FindProperty find = findProperty(key, true); |
|
17234
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2713 |
|
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2714 |
if (find != null) { |
24719 | 2715 |
return getIntValue(find, programPoint); |
17234
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2716 |
} |
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2717 |
} |
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2718 |
|
24719 | 2719 |
return JSType.toInt32(invokeNoSuchProperty(key, programPoint)); |
17234
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2720 |
} |
16147 | 2721 |
|
2722 |
@Override |
|
24719 | 2723 |
public int getInt(final Object key, final int programPoint) { |
2724 |
final Object primitiveKey = JSType.toPrimitive(key, String.class); |
|
2725 |
final int index = getArrayIndex(primitiveKey); |
|
2726 |
final ArrayData array = getArray(); |
|
17250 | 2727 |
|
2728 |
if (array.has(index)) { |
|
24719 | 2729 |
return isValid(programPoint) ? array.getIntOptimistic(index, programPoint) : array.getInt(index); |
17250 | 2730 |
} |
2731 |
||
24719 | 2732 |
return getInt(index, JSType.toString(primitiveKey), programPoint); |
16147 | 2733 |
} |
2734 |
||
2735 |
@Override |
|
24719 | 2736 |
public int getInt(final double key, final int programPoint) { |
2737 |
final int index = getArrayIndex(key); |
|
17250 | 2738 |
final ArrayData array = getArray(); |
2739 |
||
2740 |
if (array.has(index)) { |
|
24719 | 2741 |
return isValid(programPoint) ? array.getIntOptimistic(index, programPoint) : array.getInt(index); |
17250 | 2742 |
} |
2743 |
||
24719 | 2744 |
return getInt(index, JSType.toString(key), programPoint); |
16147 | 2745 |
} |
2746 |
||
2747 |
@Override |
|
24719 | 2748 |
public int getInt(final long key, final int programPoint) { |
2749 |
final int index = getArrayIndex(key); |
|
17250 | 2750 |
final ArrayData array = getArray(); |
2751 |
||
2752 |
if (array.has(index)) { |
|
24719 | 2753 |
return isValid(programPoint) ? array.getIntOptimistic(index, programPoint) : array.getInt(index); |
17250 | 2754 |
} |
2755 |
||
24719 | 2756 |
return getInt(index, JSType.toString(key), programPoint); |
16147 | 2757 |
} |
2758 |
||
2759 |
@Override |
|
24719 | 2760 |
public int getInt(final int key, final int programPoint) { |
2761 |
final int index = getArrayIndex(key); |
|
17250 | 2762 |
final ArrayData array = getArray(); |
2763 |
||
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
2764 |
if (array.has(index)) { |
24719 | 2765 |
return isValid(programPoint) ? array.getIntOptimistic(key, programPoint) : array.getInt(key); |
17250 | 2766 |
} |
2767 |
||
24719 | 2768 |
return getInt(index, JSType.toString(key), programPoint); |
17234
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2769 |
} |
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2770 |
|
24719 | 2771 |
private long getLong(final int index, final String key, final int programPoint) { |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
2772 |
if (isValidArrayIndex(index)) { |
17250 | 2773 |
for (ScriptObject object = this; ; ) { |
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
2774 |
if (object.getMap().containsArrayKeys()) { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
2775 |
final FindProperty find = object.findProperty(key, false, this); |
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
2776 |
if (find != null) { |
24719 | 2777 |
return getLongValue(find, programPoint); |
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
2778 |
} |
17250 | 2779 |
} |
2780 |
||
2781 |
if ((object = object.getProto()) == null) { |
|
2782 |
break; |
|
2783 |
} |
|
2784 |
||
2785 |
final ArrayData array = object.getArray(); |
|
2786 |
||
2787 |
if (array.has(index)) { |
|
24719 | 2788 |
return isValid(programPoint) ? |
2789 |
array.getLongOptimistic(index, programPoint) : |
|
2790 |
array.getLong(index); |
|
17250 | 2791 |
} |
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
2792 |
} |
17250 | 2793 |
} else { |
2794 |
final FindProperty find = findProperty(key, true); |
|
17234
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2795 |
|
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2796 |
if (find != null) { |
24719 | 2797 |
return getLongValue(find, programPoint); |
17234
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2798 |
} |
16147 | 2799 |
} |
2800 |
||
24719 | 2801 |
return JSType.toLong(invokeNoSuchProperty(key, programPoint)); |
16147 | 2802 |
} |
2803 |
||
2804 |
@Override |
|
24719 | 2805 |
public long getLong(final Object key, final int programPoint) { |
2806 |
final Object primitiveKey = JSType.toPrimitive(key, String.class); |
|
2807 |
final int index = getArrayIndex(primitiveKey); |
|
2808 |
final ArrayData array = getArray(); |
|
17250 | 2809 |
|
2810 |
if (array.has(index)) { |
|
24719 | 2811 |
return isValid(programPoint) ? array.getLongOptimistic(index, programPoint) : array.getLong(index); |
17250 | 2812 |
} |
2813 |
||
24719 | 2814 |
return getLong(index, JSType.toString(primitiveKey), programPoint); |
16147 | 2815 |
} |
2816 |
||
2817 |
@Override |
|
24719 | 2818 |
public long getLong(final double key, final int programPoint) { |
2819 |
final int index = getArrayIndex(key); |
|
17250 | 2820 |
final ArrayData array = getArray(); |
2821 |
||
2822 |
if (array.has(index)) { |
|
24719 | 2823 |
return isValid(programPoint) ? array.getLongOptimistic(index, programPoint) : array.getLong(index); |
17250 | 2824 |
} |
2825 |
||
24719 | 2826 |
return getLong(index, JSType.toString(key), programPoint); |
16147 | 2827 |
} |
2828 |
||
2829 |
@Override |
|
24719 | 2830 |
public long getLong(final long key, final int programPoint) { |
2831 |
final int index = getArrayIndex(key); |
|
17250 | 2832 |
final ArrayData array = getArray(); |
2833 |
||
2834 |
if (array.has(index)) { |
|
24719 | 2835 |
return isValid(programPoint) ? array.getLongOptimistic(index, programPoint) : array.getLong(index); |
17250 | 2836 |
} |
2837 |
||
24719 | 2838 |
return getLong(index, JSType.toString(key), programPoint); |
16147 | 2839 |
} |
2840 |
||
2841 |
@Override |
|
24719 | 2842 |
public long getLong(final int key, final int programPoint) { |
2843 |
final int index = getArrayIndex(key); |
|
17250 | 2844 |
final ArrayData array = getArray(); |
2845 |
||
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
2846 |
if (array.has(index)) { |
24719 | 2847 |
return isValid(programPoint) ? array.getLongOptimistic(key, programPoint) : array.getLong(key); |
17250 | 2848 |
} |
2849 |
||
24719 | 2850 |
return getLong(index, JSType.toString(key), programPoint); |
17234
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2851 |
} |
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2852 |
|
24719 | 2853 |
private double getDouble(final int index, final String key, final int programPoint) { |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
2854 |
if (isValidArrayIndex(index)) { |
17250 | 2855 |
for (ScriptObject object = this; ; ) { |
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
2856 |
if (object.getMap().containsArrayKeys()) { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
2857 |
final FindProperty find = object.findProperty(key, false, this); |
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
2858 |
if (find != null) { |
24719 | 2859 |
return getDoubleValue(find, programPoint); |
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
2860 |
} |
17250 | 2861 |
} |
2862 |
||
2863 |
if ((object = object.getProto()) == null) { |
|
2864 |
break; |
|
2865 |
} |
|
2866 |
||
2867 |
final ArrayData array = object.getArray(); |
|
2868 |
||
2869 |
if (array.has(index)) { |
|
24719 | 2870 |
return isValid(programPoint) ? |
2871 |
array.getDoubleOptimistic(index, programPoint) : |
|
2872 |
array.getDouble(index); |
|
17250 | 2873 |
} |
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
2874 |
} |
17250 | 2875 |
} else { |
2876 |
final FindProperty find = findProperty(key, true); |
|
17234
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2877 |
|
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2878 |
if (find != null) { |
24719 | 2879 |
return getDoubleValue(find, programPoint); |
17234
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2880 |
} |
16147 | 2881 |
} |
2882 |
||
24719 | 2883 |
return JSType.toNumber(invokeNoSuchProperty(key, INVALID_PROGRAM_POINT)); |
16147 | 2884 |
} |
2885 |
||
2886 |
@Override |
|
24719 | 2887 |
public double getDouble(final Object key, final int programPoint) { |
2888 |
final Object primitiveKey = JSType.toPrimitive(key, String.class); |
|
2889 |
final int index = getArrayIndex(primitiveKey); |
|
2890 |
final ArrayData array = getArray(); |
|
17250 | 2891 |
|
2892 |
if (array.has(index)) { |
|
24719 | 2893 |
return isValid(programPoint) ? array.getDoubleOptimistic(index, programPoint) : array.getDouble(index); |
17250 | 2894 |
} |
2895 |
||
24719 | 2896 |
return getDouble(index, JSType.toString(primitiveKey), programPoint); |
16147 | 2897 |
} |
2898 |
||
2899 |
@Override |
|
24719 | 2900 |
public double getDouble(final double key, final int programPoint) { |
2901 |
final int index = getArrayIndex(key); |
|
17250 | 2902 |
final ArrayData array = getArray(); |
2903 |
||
2904 |
if (array.has(index)) { |
|
24719 | 2905 |
return isValid(programPoint) ? array.getDoubleOptimistic(index, programPoint) : array.getDouble(index); |
17250 | 2906 |
} |
2907 |
||
24719 | 2908 |
return getDouble(index, JSType.toString(key), programPoint); |
16147 | 2909 |
} |
2910 |
||
2911 |
@Override |
|
24719 | 2912 |
public double getDouble(final long key, final int programPoint) { |
2913 |
final int index = getArrayIndex(key); |
|
17250 | 2914 |
final ArrayData array = getArray(); |
2915 |
||
2916 |
if (array.has(index)) { |
|
24719 | 2917 |
return isValid(programPoint) ? array.getDoubleOptimistic(index, programPoint) : array.getDouble(index); |
17250 | 2918 |
} |
2919 |
||
24719 | 2920 |
return getDouble(index, JSType.toString(key), programPoint); |
16147 | 2921 |
} |
2922 |
||
2923 |
@Override |
|
24719 | 2924 |
public double getDouble(final int key, final int programPoint) { |
2925 |
final int index = getArrayIndex(key); |
|
17250 | 2926 |
final ArrayData array = getArray(); |
2927 |
||
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
2928 |
if (array.has(index)) { |
24719 | 2929 |
return isValid(programPoint) ? array.getDoubleOptimistic(key, programPoint) : array.getDouble(key); |
17250 | 2930 |
} |
2931 |
||
24719 | 2932 |
return getDouble(index, JSType.toString(key), programPoint); |
17234
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2933 |
} |
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2934 |
|
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2935 |
private Object get(final int index, final String key) { |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
2936 |
if (isValidArrayIndex(index)) { |
17250 | 2937 |
for (ScriptObject object = this; ; ) { |
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
2938 |
if (object.getMap().containsArrayKeys()) { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
2939 |
final FindProperty find = object.findProperty(key, false, this); |
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
2940 |
|
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
2941 |
if (find != null) { |
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
2942 |
return find.getObjectValue(); |
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
2943 |
} |
17250 | 2944 |
} |
2945 |
||
2946 |
if ((object = object.getProto()) == null) { |
|
2947 |
break; |
|
2948 |
} |
|
2949 |
||
2950 |
final ArrayData array = object.getArray(); |
|
2951 |
||
2952 |
if (array.has(index)) { |
|
2953 |
return array.getObject(index); |
|
2954 |
} |
|
17234
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2955 |
} |
17250 | 2956 |
} else { |
2957 |
final FindProperty find = findProperty(key, true); |
|
17234
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2958 |
|
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2959 |
if (find != null) { |
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
2960 |
return find.getObjectValue(); |
17234
7eda96a52c27
8011578: -Dnashorn.unstable.relink.threshold=1 causes tests to fail.
jlaskey
parents:
16277
diff
changeset
|
2961 |
} |
16147 | 2962 |
} |
2963 |
||
24719 | 2964 |
return invokeNoSuchProperty(key, INVALID_PROGRAM_POINT); |
16147 | 2965 |
} |
2966 |
||
2967 |
@Override |
|
2968 |
public Object get(final Object key) { |
|
24719 | 2969 |
final Object primitiveKey = JSType.toPrimitive(key, String.class); |
2970 |
final int index = getArrayIndex(primitiveKey); |
|
2971 |
final ArrayData array = getArray(); |
|
17250 | 2972 |
|
2973 |
if (array.has(index)) { |
|
2974 |
return array.getObject(index); |
|
2975 |
} |
|
2976 |
||
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
2977 |
return get(index, JSType.toString(primitiveKey)); |
16147 | 2978 |
} |
2979 |
||
2980 |
@Override |
|
2981 |
public Object get(final double key) { |
|
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
2982 |
final int index = getArrayIndex(key); |
17250 | 2983 |
final ArrayData array = getArray(); |
2984 |
||
2985 |
if (array.has(index)) { |
|
2986 |
return array.getObject(index); |
|
2987 |
} |
|
2988 |
||
19621
1b2a79d8924c
8023531: new RegExp('').toString() should return '/(?:)/'
hannesw
parents:
19619
diff
changeset
|
2989 |
return get(index, JSType.toString(key)); |
16147 | 2990 |
} |
2991 |
||
2992 |
@Override |
|
2993 |
public Object get(final long key) { |
|
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
2994 |
final int index = getArrayIndex(key); |
17250 | 2995 |
final ArrayData array = getArray(); |
2996 |
||
2997 |
if (array.has(index)) { |
|
2998 |
return array.getObject(index); |
|
2999 |
} |
|
3000 |
||
19621
1b2a79d8924c
8023531: new RegExp('').toString() should return '/(?:)/'
hannesw
parents:
19619
diff
changeset
|
3001 |
return get(index, JSType.toString(key)); |
16147 | 3002 |
} |
3003 |
||
3004 |
@Override |
|
3005 |
public Object get(final int key) { |
|
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3006 |
final int index = getArrayIndex(key); |
17250 | 3007 |
final ArrayData array = getArray(); |
3008 |
||
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3009 |
if (array.has(index)) { |
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3010 |
return array.getObject(index); |
17250 | 3011 |
} |
3012 |
||
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3013 |
return get(index, JSType.toString(key)); |
16147 | 3014 |
} |
3015 |
||
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3016 |
private boolean doesNotHaveCheckArrayKeys(final long longIndex, final int value, final int callSiteFlags) { |
21441
0b98be59e3cb
8026858: Array length does not handle defined properties correctly
hannesw
parents:
21438
diff
changeset
|
3017 |
if (getMap().containsArrayKeys()) { |
24719 | 3018 |
final String key = JSType.toString(longIndex); |
16147 | 3019 |
final FindProperty find = findProperty(key, true); |
24719 | 3020 |
if (find != null) { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3021 |
setObject(find, callSiteFlags, key, value); |
24719 | 3022 |
return true; |
3023 |
} |
|
3024 |
} |
|
3025 |
return false; |
|
3026 |
} |
|
3027 |
||
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3028 |
private boolean doesNotHaveCheckArrayKeys(final long longIndex, final long value, final int callSiteFlags) { |
24719 | 3029 |
if (getMap().containsArrayKeys()) { |
3030 |
final String key = JSType.toString(longIndex); |
|
3031 |
final FindProperty find = findProperty(key, true); |
|
16147 | 3032 |
if (find != null) { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3033 |
setObject(find, callSiteFlags, key, value); |
24719 | 3034 |
return true; |
3035 |
} |
|
3036 |
} |
|
3037 |
return false; |
|
3038 |
} |
|
3039 |
||
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3040 |
private boolean doesNotHaveCheckArrayKeys(final long longIndex, final double value, final int callSiteFlags) { |
24719 | 3041 |
if (getMap().containsArrayKeys()) { |
3042 |
final String key = JSType.toString(longIndex); |
|
3043 |
final FindProperty find = findProperty(key, true); |
|
3044 |
if (find != null) { |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3045 |
setObject(find, callSiteFlags, key, value); |
24719 | 3046 |
return true; |
16147 | 3047 |
} |
3048 |
} |
|
24719 | 3049 |
return false; |
23761
5f351bdb2317
8037562: Nashorn: JSON.parse comes up with nonexistent entries if there are gaps between the keys
sundar
parents:
23375
diff
changeset
|
3050 |
} |
5f351bdb2317
8037562: Nashorn: JSON.parse comes up with nonexistent entries if there are gaps between the keys
sundar
parents:
23375
diff
changeset
|
3051 |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3052 |
private boolean doesNotHaveCheckArrayKeys(final long longIndex, final Object value, final int callSiteFlags) { |
24719 | 3053 |
if (getMap().containsArrayKeys()) { |
3054 |
final String key = JSType.toString(longIndex); |
|
3055 |
final FindProperty find = findProperty(key, true); |
|
3056 |
if (find != null) { |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3057 |
setObject(find, callSiteFlags, key, value); |
24719 | 3058 |
return true; |
3059 |
} |
|
3060 |
} |
|
3061 |
return false; |
|
3062 |
} |
|
3063 |
||
3064 |
//value agnostic |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3065 |
private boolean doesNotHaveEnsureLength(final long longIndex, final long oldLength, final int callSiteFlags) { |
16147 | 3066 |
if (longIndex >= oldLength) { |
3067 |
if (!isExtensible()) { |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3068 |
if (NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)) { |
24719 | 3069 |
throw typeError("object.non.extensible", JSType.toString(longIndex), ScriptRuntime.safeToString(this)); |
16147 | 3070 |
} |
24719 | 3071 |
return true; |
16147 | 3072 |
} |
3073 |
setArray(getArray().ensure(longIndex)); |
|
3074 |
} |
|
24719 | 3075 |
return false; |
3076 |
} |
|
3077 |
||
3078 |
private void doesNotHaveEnsureDelete(final long longIndex, final long oldLength, final boolean strict) { |
|
16147 | 3079 |
if (longIndex > oldLength) { |
3080 |
ArrayData array = getArray(); |
|
24720 | 3081 |
if (array.canDelete(oldLength, longIndex - 1, strict)) { |
3082 |
array = array.delete(oldLength, longIndex - 1); |
|
16147 | 3083 |
} |
3084 |
setArray(array); |
|
3085 |
} |
|
3086 |
} |
|
3087 |
||
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3088 |
private void doesNotHave(final int index, final int value, final int callSiteFlags) { |
24719 | 3089 |
final long oldLength = getArray().length(); |
3090 |
final long longIndex = ArrayIndex.toLongIndex(index); |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3091 |
if (!doesNotHaveCheckArrayKeys(longIndex, value, callSiteFlags) && !doesNotHaveEnsureLength(longIndex, oldLength, callSiteFlags)) { |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3092 |
final boolean strict = NashornCallSiteDescriptor.isStrictFlag(callSiteFlags); |
24719 | 3093 |
setArray(getArray().set(index, value, strict)); |
3094 |
doesNotHaveEnsureDelete(longIndex, oldLength, strict); |
|
3095 |
} |
|
3096 |
} |
|
3097 |
||
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3098 |
private void doesNotHave(final int index, final long value, final int callSiteFlags) { |
24719 | 3099 |
final long oldLength = getArray().length(); |
3100 |
final long longIndex = ArrayIndex.toLongIndex(index); |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3101 |
if (!doesNotHaveCheckArrayKeys(longIndex, value, callSiteFlags) && !doesNotHaveEnsureLength(longIndex, oldLength, callSiteFlags)) { |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3102 |
final boolean strict = NashornCallSiteDescriptor.isStrictFlag(callSiteFlags); |
24719 | 3103 |
setArray(getArray().set(index, value, strict)); |
3104 |
doesNotHaveEnsureDelete(longIndex, oldLength, strict); |
|
3105 |
} |
|
3106 |
} |
|
3107 |
||
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3108 |
private void doesNotHave(final int index, final double value, final int callSiteFlags) { |
24719 | 3109 |
final long oldLength = getArray().length(); |
3110 |
final long longIndex = ArrayIndex.toLongIndex(index); |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3111 |
if (!doesNotHaveCheckArrayKeys(longIndex, value, callSiteFlags) && !doesNotHaveEnsureLength(longIndex, oldLength, callSiteFlags)) { |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3112 |
final boolean strict = NashornCallSiteDescriptor.isStrictFlag(callSiteFlags); |
24719 | 3113 |
setArray(getArray().set(index, value, strict)); |
3114 |
doesNotHaveEnsureDelete(longIndex, oldLength, strict); |
|
3115 |
} |
|
3116 |
} |
|
3117 |
||
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3118 |
private void doesNotHave(final int index, final Object value, final int callSiteFlags) { |
24719 | 3119 |
final long oldLength = getArray().length(); |
3120 |
final long longIndex = ArrayIndex.toLongIndex(index); |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3121 |
if (!doesNotHaveCheckArrayKeys(longIndex, value, callSiteFlags) && !doesNotHaveEnsureLength(longIndex, oldLength, callSiteFlags)) { |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3122 |
final boolean strict = NashornCallSiteDescriptor.isStrictFlag(callSiteFlags); |
24719 | 3123 |
setArray(getArray().set(index, value, strict)); |
3124 |
doesNotHaveEnsureDelete(longIndex, oldLength, strict); |
|
3125 |
} |
|
3126 |
} |
|
3127 |
||
16147 | 3128 |
/** |
3129 |
* This is the most generic of all Object setters. Most of the others use this in some form. |
|
3130 |
* TODO: should be further specialized |
|
3131 |
* |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3132 |
* @param find found property |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3133 |
* @param callSiteFlags callsite flags |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3134 |
* @param key property key |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3135 |
* @param value property value |
16147 | 3136 |
*/ |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3137 |
public final void setObject(final FindProperty find, final int callSiteFlags, final String key, final Object value) { |
16147 | 3138 |
FindProperty f = find; |
3139 |
||
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3140 |
if (f != null && f.isInherited() && !(f.getProperty() instanceof UserAccessorProperty)) { |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3141 |
final boolean isScope = NashornCallSiteDescriptor.isScopeFlag(callSiteFlags); |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3142 |
// If the start object of the find is not this object it means the property was found inside a |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3143 |
// 'with' statement expression (see WithObject.findProperty()). In this case we forward the 'set' |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3144 |
// to the 'with' object. |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3145 |
// Note that although a 'set' operation involving a with statement follows scope rules outside |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3146 |
// the 'with' expression (the 'set' operation is performed on the owning prototype if it exists), |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3147 |
// it follows non-scope rules inside the 'with' expression (set is performed on the top level object). |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3148 |
// This is why we clear the callsite flags and FindProperty in the forward call to the 'with' object. |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3149 |
if (isScope && f.getSelf() != this) { |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3150 |
f.getSelf().setObject(null, 0, key, value); |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3151 |
return; |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3152 |
} |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3153 |
// Setting a property should not modify the property in prototype unless this is a scope callsite |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3154 |
// and the owner is a scope object as well (with the exception of 'with' statement handled above). |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3155 |
if (!isScope || !f.getOwner().isScope()) { |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3156 |
f = null; |
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3157 |
} |
16147 | 3158 |
} |
3159 |
||
3160 |
if (f != null) { |
|
16224
0c49ad4e3b55
8006222: Move slot from SpillProperty to Property
jlaskey
parents:
16223
diff
changeset
|
3161 |
if (!f.getProperty().isWritable()) { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3162 |
if (NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)) { |
16256
f2d9a0c49914
8007002: Replace implicit exception throwing methods with explicit throws - simplify control flow and remove useless code
lagergren
parents:
16240
diff
changeset
|
3163 |
throw typeError("property.not.writable", key, ScriptRuntime.safeToString(this)); |
16147 | 3164 |
} |
3165 |
||
3166 |
return; |
|
3167 |
} |
|
3168 |
||
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3169 |
f.setValue(value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)); |
17770 | 3170 |
|
16147 | 3171 |
} else if (!isExtensible()) { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3172 |
if (NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)) { |
16256
f2d9a0c49914
8007002: Replace implicit exception throwing methods with explicit throws - simplify control flow and remove useless code
lagergren
parents:
16240
diff
changeset
|
3173 |
throw typeError("object.non.extensible", key, ScriptRuntime.safeToString(this)); |
16147 | 3174 |
} |
3175 |
} else { |
|
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
3176 |
ScriptObject sobj = this; |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
3177 |
// undefined scope properties are set in the global object. |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
3178 |
if (isScope()) { |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
3179 |
while (sobj != null && !(sobj instanceof Global)) { |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
3180 |
sobj = sobj.getProto(); |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
3181 |
} |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
3182 |
assert sobj != null : "no parent global object in scope"; |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23084
diff
changeset
|
3183 |
} |
24719 | 3184 |
//this will unbox any Number object to its primitive type in case the |
24729
2b13051f2122
8037534: Use scope types to determine optimistic types
attila
parents:
24727
diff
changeset
|
3185 |
//property supports primitive types, so it doesn't matter that it comes |
24719 | 3186 |
//in as an Object. |
24727 | 3187 |
sobj.addSpillProperty(key, 0, value, true); |
16147 | 3188 |
} |
3189 |
} |
|
3190 |
||
3191 |
@Override |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3192 |
public void set(final Object key, final int value, final int callSiteFlags) { |
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3193 |
final Object primitiveKey = JSType.toPrimitive(key, String.class); |
24719 | 3194 |
final int index = getArrayIndex(primitiveKey); |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3195 |
|
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3196 |
if (isValidArrayIndex(index)) { |
16147 | 3197 |
if (getArray().has(index)) { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3198 |
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); |
16147 | 3199 |
} else { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3200 |
doesNotHave(index, value, callSiteFlags); |
16147 | 3201 |
} |
3202 |
||
3203 |
return; |
|
3204 |
} |
|
3205 |
||
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3206 |
final String propName = JSType.toString(primitiveKey); |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3207 |
setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value)); |
16147 | 3208 |
} |
3209 |
||
3210 |
@Override |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3211 |
public void set(final Object key, final long value, final int callSiteFlags) { |
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3212 |
final Object primitiveKey = JSType.toPrimitive(key, String.class); |
24719 | 3213 |
final int index = getArrayIndex(primitiveKey); |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3214 |
|
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3215 |
if (isValidArrayIndex(index)) { |
16147 | 3216 |
if (getArray().has(index)) { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3217 |
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); |
16147 | 3218 |
} else { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3219 |
doesNotHave(index, value, callSiteFlags); |
16147 | 3220 |
} |
3221 |
||
3222 |
return; |
|
3223 |
} |
|
3224 |
||
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3225 |
final String propName = JSType.toString(primitiveKey); |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3226 |
setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value)); |
16147 | 3227 |
} |
3228 |
||
3229 |
@Override |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3230 |
public void set(final Object key, final double value, final int callSiteFlags) { |
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3231 |
final Object primitiveKey = JSType.toPrimitive(key, String.class); |
24719 | 3232 |
final int index = getArrayIndex(primitiveKey); |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3233 |
|
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3234 |
if (isValidArrayIndex(index)) { |
16147 | 3235 |
if (getArray().has(index)) { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3236 |
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); |
16147 | 3237 |
} else { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3238 |
doesNotHave(index, value, callSiteFlags); |
16147 | 3239 |
} |
3240 |
||
3241 |
return; |
|
3242 |
} |
|
3243 |
||
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3244 |
final String propName = JSType.toString(primitiveKey); |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3245 |
setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value)); |
16147 | 3246 |
} |
3247 |
||
3248 |
@Override |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3249 |
public void set(final Object key, final Object value, final int callSiteFlags) { |
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3250 |
final Object primitiveKey = JSType.toPrimitive(key, String.class); |
24719 | 3251 |
final int index = getArrayIndex(primitiveKey); |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3252 |
|
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3253 |
if (isValidArrayIndex(index)) { |
16147 | 3254 |
if (getArray().has(index)) { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3255 |
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); |
16147 | 3256 |
} else { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3257 |
doesNotHave(index, value, callSiteFlags); |
16147 | 3258 |
} |
3259 |
||
3260 |
return; |
|
3261 |
} |
|
3262 |
||
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3263 |
final String propName = JSType.toString(primitiveKey); |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3264 |
setObject(findProperty(propName, true), callSiteFlags, propName, value); |
16147 | 3265 |
} |
3266 |
||
3267 |
@Override |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3268 |
public void set(final double key, final int value, final int callSiteFlags) { |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3269 |
final int index = getArrayIndex(key); |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3270 |
|
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3271 |
if (isValidArrayIndex(index)) { |
16147 | 3272 |
if (getArray().has(index)) { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3273 |
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); |
16147 | 3274 |
} else { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3275 |
doesNotHave(index, value, callSiteFlags); |
16147 | 3276 |
} |
3277 |
||
3278 |
return; |
|
3279 |
} |
|
3280 |
||
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3281 |
final String propName = JSType.toString(key); |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3282 |
setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value)); |
16147 | 3283 |
} |
3284 |
||
3285 |
@Override |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3286 |
public void set(final double key, final long value, final int callSiteFlags) { |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3287 |
final int index = getArrayIndex(key); |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3288 |
|
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3289 |
if (isValidArrayIndex(index)) { |
16147 | 3290 |
if (getArray().has(index)) { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3291 |
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); |
16147 | 3292 |
} else { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3293 |
doesNotHave(index, value, callSiteFlags); |
16147 | 3294 |
} |
3295 |
||
3296 |
return; |
|
3297 |
} |
|
3298 |
||
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3299 |
final String propName = JSType.toString(key); |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3300 |
setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value)); |
16147 | 3301 |
} |
3302 |
||
3303 |
@Override |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3304 |
public void set(final double key, final double value, final int callSiteFlags) { |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3305 |
final int index = getArrayIndex(key); |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3306 |
|
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3307 |
if (isValidArrayIndex(index)) { |
16147 | 3308 |
if (getArray().has(index)) { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3309 |
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); |
16147 | 3310 |
} else { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3311 |
doesNotHave(index, value, callSiteFlags); |
16147 | 3312 |
} |
3313 |
||
3314 |
return; |
|
3315 |
} |
|
3316 |
||
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3317 |
final String propName = JSType.toString(key); |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3318 |
setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value)); |
16147 | 3319 |
} |
3320 |
||
3321 |
@Override |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3322 |
public void set(final double key, final Object value, final int callSiteFlags) { |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3323 |
final int index = getArrayIndex(key); |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3324 |
|
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3325 |
if (isValidArrayIndex(index)) { |
16147 | 3326 |
if (getArray().has(index)) { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3327 |
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); |
16147 | 3328 |
} else { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3329 |
doesNotHave(index, value, callSiteFlags); |
16147 | 3330 |
} |
3331 |
||
3332 |
return; |
|
3333 |
} |
|
3334 |
||
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3335 |
final String propName = JSType.toString(key); |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3336 |
setObject(findProperty(propName, true), callSiteFlags, propName, value); |
16147 | 3337 |
} |
3338 |
||
3339 |
@Override |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3340 |
public void set(final long key, final int value, final int callSiteFlags) { |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3341 |
final int index = getArrayIndex(key); |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3342 |
|
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3343 |
if (isValidArrayIndex(index)) { |
16147 | 3344 |
if (getArray().has(index)) { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3345 |
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); |
16147 | 3346 |
} else { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3347 |
doesNotHave(index, value, callSiteFlags); |
16147 | 3348 |
} |
3349 |
||
3350 |
return; |
|
3351 |
} |
|
3352 |
||
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3353 |
final String propName = JSType.toString(key); |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3354 |
setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value)); |
16147 | 3355 |
} |
3356 |
||
3357 |
@Override |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3358 |
public void set(final long key, final long value, final int callSiteFlags) { |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3359 |
final int index = getArrayIndex(key); |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3360 |
|
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3361 |
if (isValidArrayIndex(index)) { |
16147 | 3362 |
if (getArray().has(index)) { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3363 |
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); |
16147 | 3364 |
} else { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3365 |
doesNotHave(index, value, callSiteFlags); |
16147 | 3366 |
} |
3367 |
||
3368 |
return; |
|
3369 |
} |
|
3370 |
||
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3371 |
final String propName = JSType.toString(key); |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3372 |
setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value)); |
16147 | 3373 |
} |
3374 |
||
3375 |
@Override |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3376 |
public void set(final long key, final double value, final int callSiteFlags) { |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3377 |
final int index = getArrayIndex(key); |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3378 |
|
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3379 |
if (isValidArrayIndex(index)) { |
16147 | 3380 |
if (getArray().has(index)) { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3381 |
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); |
16147 | 3382 |
} else { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3383 |
doesNotHave(index, value, callSiteFlags); |
16147 | 3384 |
} |
3385 |
||
3386 |
return; |
|
3387 |
} |
|
3388 |
||
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3389 |
final String propName = JSType.toString(key); |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3390 |
setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value)); |
16147 | 3391 |
} |
3392 |
||
3393 |
@Override |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3394 |
public void set(final long key, final Object value, final int callSiteFlags) { |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3395 |
final int index = getArrayIndex(key); |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3396 |
|
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3397 |
if (isValidArrayIndex(index)) { |
16147 | 3398 |
if (getArray().has(index)) { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3399 |
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); |
16147 | 3400 |
} else { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3401 |
doesNotHave(index, value, callSiteFlags); |
16147 | 3402 |
} |
3403 |
||
3404 |
return; |
|
3405 |
} |
|
3406 |
||
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3407 |
final String propName = JSType.toString(key); |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3408 |
setObject(findProperty(propName, true), callSiteFlags, propName, value); |
16147 | 3409 |
} |
3410 |
||
3411 |
@Override |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3412 |
public void set(final int key, final int value, final int callSiteFlags) { |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3413 |
final int index = getArrayIndex(key); |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3414 |
if (isValidArrayIndex(index)) { |
16147 | 3415 |
if (getArray().has(index)) { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3416 |
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); |
16147 | 3417 |
} else { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3418 |
doesNotHave(index, value, callSiteFlags); |
16147 | 3419 |
} |
3420 |
return; |
|
3421 |
} |
|
3422 |
||
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3423 |
final String propName = JSType.toString(key); |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3424 |
setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value)); |
16147 | 3425 |
} |
3426 |
||
3427 |
@Override |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3428 |
public void set(final int key, final long value, final int callSiteFlags) { |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3429 |
final int index = getArrayIndex(key); |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3430 |
|
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3431 |
if (isValidArrayIndex(index)) { |
16147 | 3432 |
if (getArray().has(index)) { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3433 |
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); |
16147 | 3434 |
} else { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3435 |
doesNotHave(index, value, callSiteFlags); |
16147 | 3436 |
} |
3437 |
||
3438 |
return; |
|
3439 |
} |
|
3440 |
||
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3441 |
final String propName = JSType.toString(key); |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3442 |
setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value)); |
16147 | 3443 |
} |
3444 |
||
3445 |
@Override |
|
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3446 |
public void set(final int key, final double value, final int callSiteFlags) { |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3447 |
final int index = getArrayIndex(key); |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3448 |
|
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3449 |
if (isValidArrayIndex(index)) { |
16147 | 3450 |
if (getArray().has(index)) { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3451 |
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); |
16147 | 3452 |
} else { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3453 |
doesNotHave(index, value, callSiteFlags); |
16147 | 3454 |
} |
3455 |
||
3456 |
return; |
|
3457 |
} |
|
3458 |
||
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3459 |
final String propName = JSType.toString(key); |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3460 |
setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value)); |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3461 |
} |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3462 |
|
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3463 |
@Override |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3464 |
public void set(final int key, final Object value, final int callSiteFlags) { |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3465 |
final int index = getArrayIndex(key); |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3466 |
|
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3467 |
if (isValidArrayIndex(index)) { |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3468 |
if (getArray().has(index)) { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3469 |
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3470 |
} else { |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3471 |
doesNotHave(index, value, callSiteFlags); |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3472 |
} |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3473 |
|
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3474 |
return; |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3475 |
} |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3476 |
|
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3477 |
final String propName = JSType.toString(key); |
26765
97501edd2979
8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents:
26511
diff
changeset
|
3478 |
setObject(findProperty(propName, true), callSiteFlags, propName, value); |
16147 | 3479 |
} |
3480 |
||
3481 |
@Override |
|
3482 |
public boolean has(final Object key) { |
|
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3483 |
final Object primitiveKey = JSType.toPrimitive(key); |
24719 | 3484 |
final int index = getArrayIndex(primitiveKey); |
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3485 |
return isValidArrayIndex(index) ? hasArrayProperty(index) : hasProperty(JSType.toString(primitiveKey), true); |
16147 | 3486 |
} |
3487 |
||
3488 |
@Override |
|
3489 |
public boolean has(final double key) { |
|
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3490 |
final int index = getArrayIndex(key); |
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3491 |
return isValidArrayIndex(index) ? hasArrayProperty(index) : hasProperty(JSType.toString(key), true); |
16147 | 3492 |
} |
3493 |
||
3494 |
@Override |
|
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3495 |
public boolean has(final long key) { |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3496 |
final int index = getArrayIndex(key); |
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3497 |
return isValidArrayIndex(index) ? hasArrayProperty(index) : hasProperty(JSType.toString(key), true); |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3498 |
} |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3499 |
|
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3500 |
@Override |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3501 |
public boolean has(final int key) { |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3502 |
final int index = getArrayIndex(key); |
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3503 |
return isValidArrayIndex(index) ? hasArrayProperty(index) : hasProperty(JSType.toString(key), true); |
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3504 |
} |
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3505 |
|
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3506 |
private boolean hasArrayProperty(final int index) { |
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3507 |
boolean hasArrayKeys = false; |
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3508 |
|
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3509 |
for (ScriptObject self = this; self != null; self = self.getProto()) { |
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3510 |
if (self.getArray().has(index)) { |
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3511 |
return true; |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3512 |
} |
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3513 |
hasArrayKeys = hasArrayKeys || self.getMap().containsArrayKeys(); |
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3514 |
} |
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3515 |
|
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3516 |
return hasArrayKeys && hasProperty(ArrayIndex.toKey(index), true); |
16147 | 3517 |
} |
3518 |
||
3519 |
@Override |
|
3520 |
public boolean hasOwnProperty(final Object key) { |
|
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3521 |
final Object primitiveKey = JSType.toPrimitive(key, String.class); |
24719 | 3522 |
final int index = getArrayIndex(primitiveKey); |
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3523 |
return isValidArrayIndex(index) ? hasOwnArrayProperty(index) : hasProperty(JSType.toString(primitiveKey), false); |
16147 | 3524 |
} |
3525 |
||
3526 |
@Override |
|
3527 |
public boolean hasOwnProperty(final int key) { |
|
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3528 |
final int index = getArrayIndex(key); |
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3529 |
return isValidArrayIndex(index) ? hasOwnArrayProperty(index) : hasProperty(JSType.toString(key), false); |
16147 | 3530 |
} |
3531 |
||
3532 |
@Override |
|
3533 |
public boolean hasOwnProperty(final long key) { |
|
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3534 |
final int index = getArrayIndex(key); |
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3535 |
return isValidArrayIndex(index) ? hasOwnArrayProperty(index) : hasProperty(JSType.toString(key), false); |
16147 | 3536 |
} |
3537 |
||
3538 |
@Override |
|
3539 |
public boolean hasOwnProperty(final double key) { |
|
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3540 |
final int index = getArrayIndex(key); |
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3541 |
return isValidArrayIndex(index) ? hasOwnArrayProperty(index) : hasProperty(JSType.toString(key), false); |
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3542 |
} |
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3543 |
|
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3544 |
private boolean hasOwnArrayProperty(final int index) { |
24720 | 3545 |
return getArray().has(index) || getMap().containsArrayKeys() && hasProperty(ArrayIndex.toKey(index), false); |
16147 | 3546 |
} |
3547 |
||
3548 |
@Override |
|
3549 |
public boolean delete(final int key, final boolean strict) { |
|
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3550 |
final int index = getArrayIndex(key); |
16147 | 3551 |
final ArrayData array = getArray(); |
3552 |
||
3553 |
if (array.has(index)) { |
|
3554 |
if (array.canDelete(index, strict)) { |
|
3555 |
setArray(array.delete(index)); |
|
3556 |
return true; |
|
3557 |
} |
|
3558 |
return false; |
|
3559 |
} |
|
3560 |
||
3561 |
return deleteObject(JSType.toObject(key), strict); |
|
3562 |
} |
|
3563 |
||
3564 |
@Override |
|
3565 |
public boolean delete(final long key, final boolean strict) { |
|
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3566 |
final int index = getArrayIndex(key); |
16147 | 3567 |
final ArrayData array = getArray(); |
3568 |
||
3569 |
if (array.has(index)) { |
|
3570 |
if (array.canDelete(index, strict)) { |
|
3571 |
setArray(array.delete(index)); |
|
3572 |
return true; |
|
3573 |
} |
|
3574 |
return false; |
|
3575 |
} |
|
3576 |
||
3577 |
return deleteObject(JSType.toObject(key), strict); |
|
3578 |
} |
|
3579 |
||
3580 |
@Override |
|
3581 |
public boolean delete(final double key, final boolean strict) { |
|
20943
183832541ef7
8026016: too many relinks dominate avatar.js http benchmark
hannesw
parents:
19884
diff
changeset
|
3582 |
final int index = getArrayIndex(key); |
16147 | 3583 |
final ArrayData array = getArray(); |
3584 |
||
3585 |
if (array.has(index)) { |
|
3586 |
if (array.canDelete(index, strict)) { |
|
3587 |
setArray(array.delete(index)); |
|
3588 |
return true; |
|
3589 |
} |
|
3590 |
return false; |
|
3591 |
} |
|
3592 |
||
3593 |
return deleteObject(JSType.toObject(key), strict); |
|
3594 |
} |
|
3595 |
||
3596 |
@Override |
|
3597 |
public boolean delete(final Object key, final boolean strict) { |
|
24719 | 3598 |
final Object primitiveKey = JSType.toPrimitive(key, String.class); |
3599 |
final int index = getArrayIndex(primitiveKey); |
|
3600 |
final ArrayData array = getArray(); |
|
16147 | 3601 |
|
3602 |
if (array.has(index)) { |
|
3603 |
if (array.canDelete(index, strict)) { |
|
3604 |
setArray(array.delete(index)); |
|
3605 |
return true; |
|
3606 |
} |
|
3607 |
return false; |
|
3608 |
} |
|
3609 |
||
21867
4e5ee0aeb468
8028210: Missing conversions on array index expression
hannesw
parents:
21685
diff
changeset
|
3610 |
return deleteObject(primitiveKey, strict); |
16147 | 3611 |
} |
3612 |
||
3613 |
private boolean deleteObject(final Object key, final boolean strict) { |
|
19621
1b2a79d8924c
8023531: new RegExp('').toString() should return '/(?:)/'
hannesw
parents:
19619
diff
changeset
|
3614 |
final String propName = JSType.toString(key); |
16147 | 3615 |
final FindProperty find = findProperty(propName, false); |
3616 |
||
3617 |
if (find == null) { |
|
3618 |
return true; |
|
3619 |
} |
|
3620 |
||
16224
0c49ad4e3b55
8006222: Move slot from SpillProperty to Property
jlaskey
parents:
16223
diff
changeset
|
3621 |
if (!find.getProperty().isConfigurable()) { |
16147 | 3622 |
if (strict) { |
16256
f2d9a0c49914
8007002: Replace implicit exception throwing methods with explicit throws - simplify control flow and remove useless code
lagergren
parents:
16240
diff
changeset
|
3623 |
throw typeError("cant.delete.property", propName, ScriptRuntime.safeToString(this)); |
16147 | 3624 |
} |
3625 |
return false; |
|
3626 |
} |
|
3627 |
||
3628 |
final Property prop = find.getProperty(); |
|
3629 |
deleteOwnProperty(prop); |
|
3630 |
||
3631 |
return true; |
|
3632 |
} |
|
3633 |
||
19097
f544a2ea40ef
8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents:
18871
diff
changeset
|
3634 |
/** |
16147 | 3635 |
* Make a new UserAccessorProperty property. getter and setter functions are stored in |
3636 |
* this ScriptObject and slot values are used in property object. |
|
19097
f544a2ea40ef
8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents:
18871
diff
changeset
|
3637 |
* |
f544a2ea40ef
8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents:
18871
diff
changeset
|
3638 |
* @param key the property name |
f544a2ea40ef
8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents:
18871
diff
changeset
|
3639 |
* @param propertyFlags attribute flags of the property |
f544a2ea40ef
8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents:
18871
diff
changeset
|
3640 |
* @param getter getter function for the property |
f544a2ea40ef
8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents:
18871
diff
changeset
|
3641 |
* @param setter setter function for the property |
f544a2ea40ef
8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents:
18871
diff
changeset
|
3642 |
* @return the newly created UserAccessorProperty |
16147 | 3643 |
*/ |
18617
f6fe338f62c3
8008458: Strict functions dont share property map
jlaskey
parents:
18334
diff
changeset
|
3644 |
protected final UserAccessorProperty newUserAccessors(final String key, final int propertyFlags, final ScriptFunction getter, final ScriptFunction setter) { |
24719 | 3645 |
final UserAccessorProperty uc = getMap().newUserAccessors(key, propertyFlags); |
3646 |
//property.getSetter(Object.class, getMap()); |
|
3647 |
uc.setAccessors(this, getMap(), new UserAccessorProperty.Accessors(getter, setter)); |
|
3648 |
return uc; |
|
16147 | 3649 |
} |
3650 |
||
24719 | 3651 |
Object ensureSpillSize(final int slot) { |
3652 |
if (slot < spillLength) { |
|
3653 |
return this; |
|
16147 | 3654 |
} |
24719 | 3655 |
final int newLength = alignUp(slot + 1, SPILL_RATE); |
3656 |
final Object[] newObjectSpill = new Object[newLength]; |
|
3657 |
final long[] newPrimitiveSpill = OBJECT_FIELDS_ONLY ? null : new long[newLength]; |
|
3658 |
||
3659 |
if (objectSpill != null) { |
|
3660 |
System.arraycopy(objectSpill, 0, newObjectSpill, 0, spillLength); |
|
3661 |
if (!OBJECT_FIELDS_ONLY) { |
|
3662 |
System.arraycopy(primitiveSpill, 0, newPrimitiveSpill, 0, spillLength); |
|
3663 |
} |
|
16147 | 3664 |
} |
18617
f6fe338f62c3
8008458: Strict functions dont share property map
jlaskey
parents:
18334
diff
changeset
|
3665 |
|
24719 | 3666 |
this.primitiveSpill = newPrimitiveSpill; |
3667 |
this.objectSpill = newObjectSpill; |
|
3668 |
this.spillLength = newLength; |
|
3669 |
||
3670 |
return this; |
|
16147 | 3671 |
} |
3672 |
||
24719 | 3673 |
private static MethodHandle findOwnMH_V(final Class<? extends ScriptObject> clazz, final String name, final Class<?> rtype, final Class<?>... types) { |
24727 | 3674 |
// TODO: figure out how can it work for NativeArray$Prototype etc. |
24719 | 3675 |
return MH.findVirtual(MethodHandles.lookup(), ScriptObject.class, name, MH.type(rtype, types)); |
16147 | 3676 |
} |
3677 |
||
24719 | 3678 |
private static MethodHandle findOwnMH_V(final String name, final Class<?> rtype, final Class<?>... types) { |
24727 | 3679 |
return findOwnMH_V(ScriptObject.class, name, rtype, types); |
24719 | 3680 |
} |
3681 |
||
3682 |
private static MethodHandle findOwnMH_S(final String name, final Class<?> rtype, final Class<?>... types) { |
|
3683 |
return MH.findStatic(MethodHandles.lookup(), ScriptObject.class, name, MH.type(rtype, types)); |
|
16147 | 3684 |
} |
3685 |
||
25421
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3686 |
private static MethodHandle getKnownFunctionPropertyGuardSelf(final PropertyMap map, final MethodHandle getter, final ScriptFunction func) { |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3687 |
return MH.insertArguments(KNOWNFUNCPROPGUARDSELF, 1, map, getter, func); |
16147 | 3688 |
} |
3689 |
||
3690 |
@SuppressWarnings("unused") |
|
25421
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3691 |
private static boolean knownFunctionPropertyGuardSelf(final Object self, final PropertyMap map, final MethodHandle getter, final ScriptFunction func) { |
16147 | 3692 |
if (self instanceof ScriptObject && ((ScriptObject)self).getMap() == map) { |
3693 |
try { |
|
25421
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3694 |
return getter.invokeExact(self) == func; |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3695 |
} catch (final RuntimeException | Error e) { |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3696 |
throw e; |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3697 |
} catch (final Throwable t) { |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3698 |
throw new RuntimeException(t); |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3699 |
} |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3700 |
} |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3701 |
|
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3702 |
return false; |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3703 |
} |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3704 |
|
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3705 |
private static MethodHandle getKnownFunctionPropertyGuardProto(final PropertyMap map, final MethodHandle getter, final int depth, final ScriptFunction func) { |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3706 |
return MH.insertArguments(KNOWNFUNCPROPGUARDPROTO, 1, map, getter, depth, func); |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3707 |
} |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3708 |
|
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3709 |
private static ScriptObject getProto(final ScriptObject self, final int depth) { |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3710 |
ScriptObject proto = self; |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3711 |
for (int d = 0; d < depth; d++) { |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3712 |
proto = proto.getProto(); |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3713 |
if (proto == null) { |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3714 |
return null; |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3715 |
} |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3716 |
} |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3717 |
|
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3718 |
return proto; |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3719 |
} |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3720 |
|
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3721 |
@SuppressWarnings("unused") |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3722 |
private static boolean knownFunctionPropertyGuardProto(final Object self, final PropertyMap map, final MethodHandle getter, final int depth, final ScriptFunction func) { |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3723 |
if (self instanceof ScriptObject && ((ScriptObject)self).getMap() == map) { |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3724 |
final ScriptObject proto = getProto((ScriptObject)self, depth); |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3725 |
if (proto == null) { |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3726 |
return false; |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3727 |
} |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3728 |
try { |
a1df2de833a2
8044760: Avoid PropertyMap duplicate for global instances
sundar
parents:
25248
diff
changeset
|
3729 |
return getter.invokeExact((Object)proto) == func; |
16147 | 3730 |
} catch (final RuntimeException | Error e) { |
3731 |
throw e; |
|
3732 |
} catch (final Throwable t) { |
|
3733 |
throw new RuntimeException(t); |
|
3734 |
} |
|
3735 |
} |
|
3736 |
||
3737 |
return false; |
|
3738 |
} |
|
3739 |
||
3740 |
/** This is updated only in debug mode - counts number of {@code ScriptObject} instances created */ |
|
16205
93fda2507e35
8007286: Add JavaAdapter and importPackage to compatibility script
sundar
parents:
16201
diff
changeset
|
3741 |
private static int count; |
16147 | 3742 |
|
3743 |
/** This is updated only in debug mode - counts number of {@code ScriptObject} instances created that are scope */ |
|
16205
93fda2507e35
8007286: Add JavaAdapter and importPackage to compatibility script
sundar
parents:
16201
diff
changeset
|
3744 |
private static int scopeCount; |
16147 | 3745 |
|
3746 |
/** |
|
3747 |
* Get number of {@code ScriptObject} instances created. If not running in debug |
|
3748 |
* mode this is always 0 |
|
3749 |
* |
|
3750 |
* @return number of ScriptObjects created |
|
3751 |
*/ |
|
3752 |
public static int getCount() { |
|
3753 |
return count; |
|
3754 |
} |
|
3755 |
||
3756 |
/** |
|
3757 |
* Get number of scope {@code ScriptObject} instances created. If not running in debug |
|
3758 |
* mode this is always 0 |
|
3759 |
* |
|
3760 |
* @return number of scope ScriptObjects created |
|
3761 |
*/ |
|
3762 |
public static int getScopeCount() { |
|
3763 |
return scopeCount; |
|
3764 |
} |
|
3765 |
||
3766 |
} |