author | hannesw |
Wed, 21 Mar 2018 16:55:34 +0100 | |
changeset 49275 | c639a6b33c5c |
parent 47216 | 71c04702a3d5 |
child 58379 | 8511c662083b |
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 |
||
28 |
import static jdk.nashorn.internal.runtime.PropertyDescriptor.CONFIGURABLE; |
|
29 |
import static jdk.nashorn.internal.runtime.PropertyDescriptor.ENUMERABLE; |
|
30 |
import static jdk.nashorn.internal.runtime.PropertyDescriptor.WRITABLE; |
|
23767 | 31 |
import java.io.Serializable; |
16147 | 32 |
import java.lang.invoke.MethodHandle; |
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24727
diff
changeset
|
33 |
import java.lang.invoke.SwitchPoint; |
16147 | 34 |
import java.util.Objects; |
16240
e1468b33e201
8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
16224
diff
changeset
|
35 |
import jdk.nashorn.internal.codegen.ObjectClassGenerator; |
16147 | 36 |
|
37 |
/** |
|
38 |
* This is the abstract superclass representing a JavaScript Property. |
|
39 |
* The {@link PropertyMap} map links keys to properties, and consequently |
|
40 |
* instances of this class make up the values in the PropertyMap |
|
41 |
* |
|
42 |
* @see PropertyMap |
|
43 |
* @see AccessorProperty |
|
44 |
* @see UserAccessorProperty |
|
45 |
*/ |
|
23767 | 46 |
public abstract class Property implements Serializable { |
16147 | 47 |
/* |
48 |
* ECMA 8.6.1 Property Attributes |
|
49 |
* |
|
50 |
* We use negative flags because most properties are expected to |
|
51 |
* be 'writable', 'configurable' and 'enumerable'. With negative flags, |
|
52 |
* we can use leave flag byte initialized with (the default) zero value. |
|
53 |
*/ |
|
54 |
||
17774
0407501fa563
8014219: Make the run-octane harness more deterministic by not measuring elapsed time every iteration. Also got rid of most of the run logic in base.js and call benchmarks directly for the same purpose
lagergren
parents:
17771
diff
changeset
|
55 |
/** Mask for property being both writable, enumerable and configurable */ |
17771
9fedae4933e4
8015354: JSON.parse should not use [[Put]] but use [[DefineOwnProperty]] instead
sundar
parents:
17770
diff
changeset
|
56 |
public static final int WRITABLE_ENUMERABLE_CONFIGURABLE = 0b0000_0000_0000; |
9fedae4933e4
8015354: JSON.parse should not use [[Put]] but use [[DefineOwnProperty]] instead
sundar
parents:
17770
diff
changeset
|
57 |
|
16147 | 58 |
/** ECMA 8.6.1 - Is this property not writable? */ |
21685
ff0187bbe5c0
8027700: function redeclaration checks missing for declaration binding instantiation
sundar
parents:
19105
diff
changeset
|
59 |
public static final int NOT_WRITABLE = 1 << 0; |
16147 | 60 |
|
61 |
/** ECMA 8.6.1 - Is this property not enumerable? */ |
|
21685
ff0187bbe5c0
8027700: function redeclaration checks missing for declaration binding instantiation
sundar
parents:
19105
diff
changeset
|
62 |
public static final int NOT_ENUMERABLE = 1 << 1; |
16147 | 63 |
|
64 |
/** ECMA 8.6.1 - Is this property not configurable? */ |
|
21685
ff0187bbe5c0
8027700: function redeclaration checks missing for declaration binding instantiation
sundar
parents:
19105
diff
changeset
|
65 |
public static final int NOT_CONFIGURABLE = 1 << 2; |
16147 | 66 |
|
24720 | 67 |
private static final int MODIFY_MASK = NOT_WRITABLE | NOT_ENUMERABLE | NOT_CONFIGURABLE; |
16147 | 68 |
|
16224
0c49ad4e3b55
8006222: Move slot from SpillProperty to Property
jlaskey
parents:
16151
diff
changeset
|
69 |
/** Is this a function parameter? */ |
24719 | 70 |
public static final int IS_PARAMETER = 1 << 3; |
16147 | 71 |
|
16224
0c49ad4e3b55
8006222: Move slot from SpillProperty to Property
jlaskey
parents:
16151
diff
changeset
|
72 |
/** Is parameter accessed thru arguments? */ |
24719 | 73 |
public static final int HAS_ARGUMENTS = 1 << 4; |
21685
ff0187bbe5c0
8027700: function redeclaration checks missing for declaration binding instantiation
sundar
parents:
19105
diff
changeset
|
74 |
|
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
21685
diff
changeset
|
75 |
/** Is this a function declaration property ? */ |
24751 | 76 |
public static final int IS_FUNCTION_DECLARATION = 1 << 5; |
21685
ff0187bbe5c0
8027700: function redeclaration checks missing for declaration binding instantiation
sundar
parents:
19105
diff
changeset
|
77 |
|
24719 | 78 |
/** |
79 |
* Is this is a primitive field given to us by Nasgen, i.e. |
|
80 |
* something we can be sure remains a constant whose type |
|
81 |
* is narrower than object, e.g. Math.PI which is declared |
|
82 |
* as a double |
|
83 |
*/ |
|
26377
028dad61662f
8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents:
26068
diff
changeset
|
84 |
public static final int IS_NASGEN_PRIMITIVE = 1 << 6; |
16147 | 85 |
|
26768
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26646
diff
changeset
|
86 |
/** Is this a builtin property, e.g. Function.prototype.apply */ |
27814
96427359f4fe
8057691: Nashorn: let & const declarations are not shared between scripts
hannesw
parents:
27307
diff
changeset
|
87 |
public static final int IS_BUILTIN = 1 << 7; |
26768
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26646
diff
changeset
|
88 |
|
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
21685
diff
changeset
|
89 |
/** Is this property bound to a receiver? This means get/set operations will be delegated to |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
21685
diff
changeset
|
90 |
* a statically defined object instead of the object passed as callsite parameter. */ |
27814
96427359f4fe
8057691: Nashorn: let & const declarations are not shared between scripts
hannesw
parents:
27307
diff
changeset
|
91 |
public static final int IS_BOUND = 1 << 8; |
26377
028dad61662f
8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents:
26068
diff
changeset
|
92 |
|
028dad61662f
8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents:
26068
diff
changeset
|
93 |
/** Is this a lexically scoped LET or CONST variable that is dead until it is declared. */ |
27814
96427359f4fe
8057691: Nashorn: let & const declarations are not shared between scripts
hannesw
parents:
27307
diff
changeset
|
94 |
public static final int NEEDS_DECLARATION = 1 << 9; |
96427359f4fe
8057691: Nashorn: let & const declarations are not shared between scripts
hannesw
parents:
27307
diff
changeset
|
95 |
|
96427359f4fe
8057691: Nashorn: let & const declarations are not shared between scripts
hannesw
parents:
27307
diff
changeset
|
96 |
/** Is this property an ES6 lexical binding? */ |
96427359f4fe
8057691: Nashorn: let & const declarations are not shared between scripts
hannesw
parents:
27307
diff
changeset
|
97 |
public static final int IS_LEXICAL_BINDING = 1 << 10; |
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
21685
diff
changeset
|
98 |
|
29834
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
27814
diff
changeset
|
99 |
/** Does this property support dual field representation? */ |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
27814
diff
changeset
|
100 |
public static final int DUAL_FIELDS = 1 << 11; |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
27814
diff
changeset
|
101 |
|
36023 | 102 |
/** Is this an accessor property as as defined in ES5 8.6.1? */ |
103 |
public static final int IS_ACCESSOR_PROPERTY = 1 << 12; |
|
104 |
||
16147 | 105 |
/** Property key. */ |
33690 | 106 |
private final Object key; |
16147 | 107 |
|
108 |
/** Property flags. */ |
|
24719 | 109 |
private int flags; |
16147 | 110 |
|
17513 | 111 |
/** Property field number or spill slot. */ |
16224
0c49ad4e3b55
8006222: Move slot from SpillProperty to Property
jlaskey
parents:
16151
diff
changeset
|
112 |
private final int slot; |
0c49ad4e3b55
8006222: Move slot from SpillProperty to Property
jlaskey
parents:
16151
diff
changeset
|
113 |
|
27307
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
114 |
/** |
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
115 |
* Current type of this object, in object only mode, this is an Object.class. In dual-fields mode |
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
116 |
* null means undefined, and primitive types are allowed. The reason a special type is used for |
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
117 |
* undefined, is that are no bits left to represent it in primitive types |
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
118 |
*/ |
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
119 |
private Class<?> type; |
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
120 |
|
24742
a9afb384e654
8040655: When processing a RewriteException debug object, the return value has already been reset to null. We need to catch this value before that.
lagergren
parents:
24738
diff
changeset
|
121 |
/** SwitchPoint that is invalidated when property is changed, optional */ |
26768
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26646
diff
changeset
|
122 |
protected transient SwitchPoint builtinSwitchPoint; |
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24727
diff
changeset
|
123 |
|
23767 | 124 |
private static final long serialVersionUID = 2099814273074501176L; |
125 |
||
16147 | 126 |
/** |
127 |
* Constructor |
|
128 |
* |
|
129 |
* @param key property key |
|
130 |
* @param flags property flags |
|
16224
0c49ad4e3b55
8006222: Move slot from SpillProperty to Property
jlaskey
parents:
16151
diff
changeset
|
131 |
* @param slot property field number or spill slot |
16147 | 132 |
*/ |
33690 | 133 |
Property(final Object key, final int flags, final int slot) { |
16224
0c49ad4e3b55
8006222: Move slot from SpillProperty to Property
jlaskey
parents:
16151
diff
changeset
|
134 |
assert key != null; |
16147 | 135 |
this.key = key; |
136 |
this.flags = flags; |
|
16224
0c49ad4e3b55
8006222: Move slot from SpillProperty to Property
jlaskey
parents:
16151
diff
changeset
|
137 |
this.slot = slot; |
16147 | 138 |
} |
139 |
||
140 |
/** |
|
141 |
* Copy constructor |
|
142 |
* |
|
143 |
* @param property source property |
|
144 |
*/ |
|
24727 | 145 |
Property(final Property property, final int flags) { |
26768
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26646
diff
changeset
|
146 |
this.key = property.key; |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26646
diff
changeset
|
147 |
this.slot = property.slot; |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26646
diff
changeset
|
148 |
this.builtinSwitchPoint = property.builtinSwitchPoint; |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26646
diff
changeset
|
149 |
this.flags = flags; |
16147 | 150 |
} |
151 |
||
152 |
/** |
|
153 |
* Copy function |
|
154 |
* |
|
155 |
* @return cloned property |
|
156 |
*/ |
|
24719 | 157 |
public abstract Property copy(); |
158 |
||
159 |
/** |
|
160 |
* Copy function |
|
161 |
* |
|
162 |
* @param newType new type |
|
163 |
* @return cloned property with new type |
|
164 |
*/ |
|
165 |
public abstract Property copy(final Class<?> newType); |
|
16147 | 166 |
|
167 |
/** |
|
168 |
* Property flag utility method for {@link PropertyDescriptor}s. Given two property descriptors, |
|
169 |
* return the result of merging their flags. |
|
170 |
* |
|
171 |
* @param oldDesc first property descriptor |
|
172 |
* @param newDesc second property descriptor |
|
173 |
* @return merged flags. |
|
174 |
*/ |
|
175 |
static int mergeFlags(final PropertyDescriptor oldDesc, final PropertyDescriptor newDesc) { |
|
176 |
int propFlags = 0; |
|
177 |
boolean value; |
|
178 |
||
179 |
value = newDesc.has(CONFIGURABLE) ? newDesc.isConfigurable() : oldDesc.isConfigurable(); |
|
180 |
if (!value) { |
|
181 |
propFlags |= NOT_CONFIGURABLE; |
|
182 |
} |
|
183 |
||
184 |
value = newDesc.has(ENUMERABLE) ? newDesc.isEnumerable() : oldDesc.isEnumerable(); |
|
185 |
if (!value) { |
|
186 |
propFlags |= NOT_ENUMERABLE; |
|
187 |
} |
|
188 |
||
189 |
value = newDesc.has(WRITABLE) ? newDesc.isWritable() : oldDesc.isWritable(); |
|
190 |
if (!value) { |
|
191 |
propFlags |= NOT_WRITABLE; |
|
192 |
} |
|
193 |
||
194 |
return propFlags; |
|
195 |
} |
|
196 |
||
197 |
/** |
|
24742
a9afb384e654
8040655: When processing a RewriteException debug object, the return value has already been reset to null. We need to catch this value before that.
lagergren
parents:
24738
diff
changeset
|
198 |
* Set the change callback for this property, i.e. a SwitchPoint |
a9afb384e654
8040655: When processing a RewriteException debug object, the return value has already been reset to null. We need to catch this value before that.
lagergren
parents:
24738
diff
changeset
|
199 |
* that will be invalidated when the value of the property is |
a9afb384e654
8040655: When processing a RewriteException debug object, the return value has already been reset to null. We need to catch this value before that.
lagergren
parents:
24738
diff
changeset
|
200 |
* changed |
a9afb384e654
8040655: When processing a RewriteException debug object, the return value has already been reset to null. We need to catch this value before that.
lagergren
parents:
24738
diff
changeset
|
201 |
* @param sp SwitchPoint to use for change callback |
a9afb384e654
8040655: When processing a RewriteException debug object, the return value has already been reset to null. We need to catch this value before that.
lagergren
parents:
24738
diff
changeset
|
202 |
*/ |
26768
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26646
diff
changeset
|
203 |
public final void setBuiltinSwitchPoint(final SwitchPoint sp) { |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26646
diff
changeset
|
204 |
this.builtinSwitchPoint = sp; |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26646
diff
changeset
|
205 |
} |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26646
diff
changeset
|
206 |
|
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26646
diff
changeset
|
207 |
/** |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26646
diff
changeset
|
208 |
* Builtin properties have an invalidation switchpoint that is |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26646
diff
changeset
|
209 |
* invalidated when they are set, this is a getter for it |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26646
diff
changeset
|
210 |
* @return builtin switchpoint, or null if none |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26646
diff
changeset
|
211 |
*/ |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26646
diff
changeset
|
212 |
public final SwitchPoint getBuiltinSwitchPoint() { |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26646
diff
changeset
|
213 |
return builtinSwitchPoint; |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26646
diff
changeset
|
214 |
} |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26646
diff
changeset
|
215 |
|
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26646
diff
changeset
|
216 |
/** |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26646
diff
changeset
|
217 |
* Checks if this is a builtin property, this means that it has |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26646
diff
changeset
|
218 |
* a builtin switchpoint that hasn't been invalidated by a setter |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26646
diff
changeset
|
219 |
* @return true if builtin, untouched (unset) property |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26646
diff
changeset
|
220 |
*/ |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26646
diff
changeset
|
221 |
public boolean isBuiltin() { |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26646
diff
changeset
|
222 |
return builtinSwitchPoint != null && !builtinSwitchPoint.hasBeenInvalidated(); |
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24727
diff
changeset
|
223 |
} |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24727
diff
changeset
|
224 |
|
16147 | 225 |
/** |
226 |
* Property flag utility method for {@link PropertyDescriptor}. Get the property flags |
|
227 |
* conforming to any Property using this PropertyDescriptor |
|
228 |
* |
|
229 |
* @param desc property descriptor |
|
230 |
* @return flags for properties that conform to property descriptor |
|
231 |
*/ |
|
232 |
static int toFlags(final PropertyDescriptor desc) { |
|
233 |
int propFlags = 0; |
|
234 |
||
235 |
if (!desc.isConfigurable()) { |
|
236 |
propFlags |= NOT_CONFIGURABLE; |
|
237 |
} |
|
238 |
if (!desc.isEnumerable()) { |
|
239 |
propFlags |= NOT_ENUMERABLE; |
|
240 |
} |
|
241 |
if (!desc.isWritable()) { |
|
242 |
propFlags |= NOT_WRITABLE; |
|
243 |
} |
|
244 |
||
245 |
return propFlags; |
|
246 |
} |
|
247 |
||
248 |
/** |
|
249 |
* Check whether this property has a user defined getter function. See {@link UserAccessorProperty} |
|
18617
f6fe338f62c3
8008458: Strict functions dont share property map
jlaskey
parents:
18615
diff
changeset
|
250 |
* @param obj object containing getter |
16147 | 251 |
* @return true if getter function exists, false is default |
252 |
*/ |
|
18617
f6fe338f62c3
8008458: Strict functions dont share property map
jlaskey
parents:
18615
diff
changeset
|
253 |
public boolean hasGetterFunction(final ScriptObject obj) { |
16147 | 254 |
return false; |
255 |
} |
|
256 |
||
257 |
/** |
|
258 |
* Check whether this property has a user defined setter function. See {@link UserAccessorProperty} |
|
18617
f6fe338f62c3
8008458: Strict functions dont share property map
jlaskey
parents:
18615
diff
changeset
|
259 |
* @param obj object containing setter |
16147 | 260 |
* @return true if getter function exists, false is default |
261 |
*/ |
|
18617
f6fe338f62c3
8008458: Strict functions dont share property map
jlaskey
parents:
18615
diff
changeset
|
262 |
public boolean hasSetterFunction(final ScriptObject obj) { |
16147 | 263 |
return false; |
264 |
} |
|
265 |
||
266 |
/** |
|
267 |
* Check whether this property is writable (see ECMA 8.6.1) |
|
268 |
* @return true if writable |
|
269 |
*/ |
|
270 |
public boolean isWritable() { |
|
271 |
return (flags & NOT_WRITABLE) == 0; |
|
272 |
} |
|
273 |
||
274 |
/** |
|
275 |
* Check whether this property is writable (see ECMA 8.6.1) |
|
276 |
* @return true if configurable |
|
277 |
*/ |
|
278 |
public boolean isConfigurable() { |
|
279 |
return (flags & NOT_CONFIGURABLE) == 0; |
|
280 |
} |
|
281 |
||
282 |
/** |
|
283 |
* Check whether this property is enumerable (see ECMA 8.6.1) |
|
284 |
* @return true if enumerable |
|
285 |
*/ |
|
286 |
public boolean isEnumerable() { |
|
287 |
return (flags & NOT_ENUMERABLE) == 0; |
|
288 |
} |
|
289 |
||
290 |
/** |
|
291 |
* Check whether this property is used as a function parameter |
|
292 |
* @return true if parameter |
|
293 |
*/ |
|
294 |
public boolean isParameter() { |
|
29834
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
27814
diff
changeset
|
295 |
return (flags & IS_PARAMETER) != 0; |
16147 | 296 |
} |
297 |
||
298 |
/** |
|
16224
0c49ad4e3b55
8006222: Move slot from SpillProperty to Property
jlaskey
parents:
16151
diff
changeset
|
299 |
* Check whether this property is in an object with arguments field |
0c49ad4e3b55
8006222: Move slot from SpillProperty to Property
jlaskey
parents:
16151
diff
changeset
|
300 |
* @return true if has arguments |
0c49ad4e3b55
8006222: Move slot from SpillProperty to Property
jlaskey
parents:
16151
diff
changeset
|
301 |
*/ |
0c49ad4e3b55
8006222: Move slot from SpillProperty to Property
jlaskey
parents:
16151
diff
changeset
|
302 |
public boolean hasArguments() { |
29834
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
27814
diff
changeset
|
303 |
return (flags & HAS_ARGUMENTS) != 0; |
16224
0c49ad4e3b55
8006222: Move slot from SpillProperty to Property
jlaskey
parents:
16151
diff
changeset
|
304 |
} |
0c49ad4e3b55
8006222: Move slot from SpillProperty to Property
jlaskey
parents:
16151
diff
changeset
|
305 |
|
0c49ad4e3b55
8006222: Move slot from SpillProperty to Property
jlaskey
parents:
16151
diff
changeset
|
306 |
/** |
16147 | 307 |
* Check whether this is a spill property, i.e. one that will not |
308 |
* be stored in a specially generated field in the property class. |
|
309 |
* The spill pool is maintained separately, as a growing Object array |
|
310 |
* in the {@link ScriptObject}. |
|
311 |
* |
|
312 |
* @return true if spill property |
|
313 |
*/ |
|
314 |
public boolean isSpill() { |
|
24719 | 315 |
return false; |
16147 | 316 |
} |
317 |
||
318 |
/** |
|
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
21685
diff
changeset
|
319 |
* Is this property bound to a receiver? If this method returns {@code true} get and set operations |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
21685
diff
changeset
|
320 |
* will be delegated to a statically bound object instead of the object passed as parameter. |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
21685
diff
changeset
|
321 |
* |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
21685
diff
changeset
|
322 |
* @return true if this is a bound property |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
21685
diff
changeset
|
323 |
*/ |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
21685
diff
changeset
|
324 |
public boolean isBound() { |
29834
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
27814
diff
changeset
|
325 |
return (flags & IS_BOUND) != 0; |
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
21685
diff
changeset
|
326 |
} |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
21685
diff
changeset
|
327 |
|
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
21685
diff
changeset
|
328 |
/** |
26377
028dad61662f
8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents:
26068
diff
changeset
|
329 |
* Is this a LET or CONST property that needs to see its declaration before being usable? |
028dad61662f
8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents:
26068
diff
changeset
|
330 |
* |
028dad61662f
8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents:
26068
diff
changeset
|
331 |
* @return true if this is a block-scoped variable |
028dad61662f
8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents:
26068
diff
changeset
|
332 |
*/ |
028dad61662f
8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents:
26068
diff
changeset
|
333 |
public boolean needsDeclaration() { |
29834
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
27814
diff
changeset
|
334 |
return (flags & NEEDS_DECLARATION) != 0; |
26377
028dad61662f
8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents:
26068
diff
changeset
|
335 |
} |
028dad61662f
8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents:
26068
diff
changeset
|
336 |
|
028dad61662f
8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents:
26068
diff
changeset
|
337 |
/** |
16147 | 338 |
* Add more property flags to the property. Properties are immutable here, |
339 |
* so any property change that results in a larger flag set results in the |
|
340 |
* property being cloned. Use only the return value |
|
341 |
* |
|
342 |
* @param propertyFlags flags to be OR:ed to the existing property flags |
|
343 |
* @return new property if property set was changed, {@code this} otherwise |
|
344 |
*/ |
|
345 |
public Property addFlags(final int propertyFlags) { |
|
346 |
if ((this.flags & propertyFlags) != propertyFlags) { |
|
347 |
final Property cloned = this.copy(); |
|
348 |
cloned.flags |= propertyFlags; |
|
349 |
return cloned; |
|
350 |
} |
|
351 |
return this; |
|
352 |
} |
|
353 |
||
354 |
/** |
|
355 |
* Get the flags for this property |
|
356 |
* @return property flags |
|
357 |
*/ |
|
358 |
public int getFlags() { |
|
359 |
return flags; |
|
360 |
} |
|
361 |
||
362 |
/** |
|
363 |
* Remove property flags from the property. Properties are immutable here, |
|
364 |
* so any property change that results in a smaller flag set results in the |
|
365 |
* property being cloned. Use only the return value |
|
366 |
* |
|
367 |
* @param propertyFlags flags to be subtracted from the existing property flags |
|
368 |
* @return new property if property set was changed, {@code this} otherwise |
|
369 |
*/ |
|
370 |
public Property removeFlags(final int propertyFlags) { |
|
371 |
if ((this.flags & propertyFlags) != 0) { |
|
372 |
final Property cloned = this.copy(); |
|
373 |
cloned.flags &= ~propertyFlags; |
|
374 |
return cloned; |
|
375 |
} |
|
376 |
return this; |
|
377 |
} |
|
378 |
||
379 |
/** |
|
380 |
* Reset the property for this property. Properties are immutable here, |
|
381 |
* so any property change that results in a different flag sets results in the |
|
382 |
* property being cloned. Use only the return value |
|
383 |
* |
|
384 |
* @param propertyFlags flags that are replacing from the existing property flags |
|
385 |
* @return new property if property set was changed, {@code this} otherwise |
|
386 |
*/ |
|
387 |
public Property setFlags(final int propertyFlags) { |
|
388 |
if (this.flags != propertyFlags) { |
|
389 |
final Property cloned = this.copy(); |
|
390 |
cloned.flags &= ~MODIFY_MASK; |
|
391 |
cloned.flags |= propertyFlags & MODIFY_MASK; |
|
392 |
return cloned; |
|
393 |
} |
|
394 |
return this; |
|
395 |
} |
|
396 |
||
397 |
/** |
|
398 |
* Abstract method for retrieving the getter for the property. We do not know |
|
399 |
* anything about the internal representation when we request the getter, we only |
|
400 |
* know that the getter will return the property as the given type. |
|
401 |
* |
|
402 |
* @param type getter return value type |
|
403 |
* @return a getter for this property as {@code type} |
|
404 |
*/ |
|
405 |
public abstract MethodHandle getGetter(final Class<?> type); |
|
406 |
||
407 |
/** |
|
24719 | 408 |
* Get an optimistic getter that throws an exception if type is not the known given one |
409 |
* @param type type |
|
410 |
* @param programPoint program point |
|
411 |
* @return getter |
|
412 |
*/ |
|
413 |
public abstract MethodHandle getOptimisticGetter(final Class<?> type, final int programPoint); |
|
414 |
||
415 |
/** |
|
23767 | 416 |
* Hook to initialize method handles after deserialization. |
417 |
* |
|
418 |
* @param structure the structure class |
|
419 |
*/ |
|
420 |
abstract void initMethodHandles(final Class<?> structure); |
|
421 |
||
422 |
/** |
|
16147 | 423 |
* Get the key for this property. This key is an ordinary string. The "name". |
424 |
* @return key for property |
|
425 |
*/ |
|
33690 | 426 |
public Object getKey() { |
16147 | 427 |
return key; |
428 |
} |
|
429 |
||
430 |
/** |
|
17513 | 431 |
* Get the field number or spill slot |
432 |
* @return number/slot, -1 if none exists |
|
433 |
*/ |
|
434 |
public int getSlot() { |
|
435 |
return slot; |
|
436 |
} |
|
437 |
||
438 |
/** |
|
24719 | 439 |
* get the Object value of this property from {@code owner}. This allows to bypass creation of the |
440 |
* getter MethodHandle for spill and user accessor properties. |
|
441 |
* |
|
442 |
* @param self the this object |
|
443 |
* @param owner the owner of the property |
|
444 |
* @return the property value |
|
445 |
*/ |
|
446 |
public abstract int getIntValue(final ScriptObject self, final ScriptObject owner); |
|
447 |
||
448 |
/** |
|
449 |
* get the Object value of this property from {@code owner}. This allows to bypass creation of the |
|
450 |
* getter MethodHandle for spill and user accessor properties. |
|
451 |
* |
|
452 |
* @param self the this object |
|
453 |
* @param owner the owner of the property |
|
454 |
* @return the property value |
|
455 |
*/ |
|
456 |
public abstract double getDoubleValue(final ScriptObject self, final ScriptObject owner); |
|
457 |
||
458 |
/** |
|
459 |
* get the Object value of this property from {@code owner}. This allows to bypass creation of the |
|
460 |
* getter MethodHandle for spill and user accessor properties. |
|
461 |
* |
|
462 |
* @param self the this object |
|
463 |
* @param owner the owner of the property |
|
464 |
* @return the property value |
|
465 |
*/ |
|
466 |
public abstract Object getObjectValue(final ScriptObject self, final ScriptObject owner); |
|
467 |
||
468 |
/** |
|
17770 | 469 |
* Set the value of this property in {@code owner}. This allows to bypass creation of the |
470 |
* setter MethodHandle for spill and user accessor properties. |
|
471 |
* |
|
472 |
* @param self the this object |
|
473 |
* @param owner the owner object |
|
474 |
* @param value the new property value |
|
17774
0407501fa563
8014219: Make the run-octane harness more deterministic by not measuring elapsed time every iteration. Also got rid of most of the run logic in base.js and call benchmarks directly for the same purpose
lagergren
parents:
17771
diff
changeset
|
475 |
* @param strict is this a strict setter? |
17770 | 476 |
*/ |
24719 | 477 |
public abstract void setValue(final ScriptObject self, final ScriptObject owner, final int value, final boolean strict); |
17770 | 478 |
|
479 |
/** |
|
24719 | 480 |
* Set the value of this property in {@code owner}. This allows to bypass creation of the |
481 |
* setter MethodHandle for spill and user accessor properties. |
|
17770 | 482 |
* |
483 |
* @param self the this object |
|
484 |
* @param owner the owner object |
|
24719 | 485 |
* @param value the new property value |
486 |
* @param strict is this a strict setter? |
|
17770 | 487 |
*/ |
24719 | 488 |
public abstract void setValue(final ScriptObject self, final ScriptObject owner, final double value, final boolean strict); |
489 |
||
490 |
/** |
|
491 |
* Set the value of this property in {@code owner}. This allows to bypass creation of the |
|
492 |
* setter MethodHandle for spill and user accessor properties. |
|
493 |
* |
|
494 |
* @param self the this object |
|
495 |
* @param owner the owner object |
|
496 |
* @param value the new property value |
|
497 |
* @param strict is this a strict setter? |
|
498 |
*/ |
|
499 |
public abstract void setValue(final ScriptObject self, final ScriptObject owner, final Object value, final boolean strict); |
|
17770 | 500 |
|
501 |
/** |
|
36023 | 502 |
* Returns true if this property has a low-level setter handle. This can be used to determine whether a |
503 |
* nasgen-generated accessor property should be treated as non-writable. For user-created accessor properties |
|
504 |
* {@link #hasSetterFunction(ScriptObject)} should be used to find whether a setter function exists in |
|
505 |
* a given object. |
|
506 |
* |
|
507 |
* @return true if a native setter handle exists |
|
508 |
*/ |
|
509 |
public abstract boolean hasNativeSetter(); |
|
510 |
||
511 |
/** |
|
16147 | 512 |
* Abstract method for retrieving the setter for the property. We do not know |
513 |
* anything about the internal representation when we request the setter, we only |
|
514 |
* know that the setter will take the property as a parameter of the given type. |
|
515 |
* <p> |
|
516 |
* Note that we have to pass the current property map from which we retrieved |
|
517 |
* the property here. This is necessary for map guards if, e.g. the internal |
|
518 |
* representation of the field, and consequently also the setter, changes. Then |
|
519 |
* we automatically get a map guard that relinks the call site so that the |
|
520 |
* older setter will never be used again. |
|
521 |
* <p> |
|
522 |
* see {@link ObjectClassGenerator#createSetter(Class, Class, MethodHandle, MethodHandle)} |
|
523 |
* if you are interested in the internal details of this. Note that if you |
|
27307
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
524 |
* are running with {@code -Dnashorn.fields.objects=true}, the setters |
16147 | 525 |
* will currently never change, as all properties are represented as Object field, |
526 |
* the Object fields are Initialized to {@code ScriptRuntime.UNDEFINED} and primitives are |
|
527 |
* boxed/unboxed upon every access, which is not necessarily optimal |
|
528 |
* |
|
529 |
* @param type setter parameter type |
|
530 |
* @param currentMap current property map for property |
|
531 |
* @return a getter for this property as {@code type} |
|
532 |
*/ |
|
533 |
public abstract MethodHandle getSetter(final Class<?> type, final PropertyMap currentMap); |
|
534 |
||
535 |
/** |
|
536 |
* Get the user defined getter function if one exists. Only {@link UserAccessorProperty} instances |
|
537 |
* can have user defined getters |
|
538 |
* @param obj the script object |
|
539 |
* @return user defined getter function, or {@code null} if none exists |
|
540 |
*/ |
|
541 |
public ScriptFunction getGetterFunction(final ScriptObject obj) { |
|
542 |
return null; |
|
543 |
} |
|
544 |
||
545 |
/** |
|
546 |
* Get the user defined setter function if one exists. Only {@link UserAccessorProperty} instances |
|
547 |
* can have user defined getters |
|
548 |
* @param obj the script object |
|
549 |
* @return user defined getter function, or {@code null} if none exists |
|
550 |
*/ |
|
551 |
public ScriptFunction getSetterFunction(final ScriptObject obj) { |
|
552 |
return null; |
|
553 |
} |
|
554 |
||
555 |
@Override |
|
556 |
public int hashCode() { |
|
31548
d158ec7e1e30
8130663: 6 fields can be static fields in Global class
sundar
parents:
29834
diff
changeset
|
557 |
final Class<?> t = getLocalType(); |
d158ec7e1e30
8130663: 6 fields can be static fields in Global class
sundar
parents:
29834
diff
changeset
|
558 |
return Objects.hashCode(this.key) ^ flags ^ getSlot() ^ (t == null ? 0 : t.hashCode()); |
16147 | 559 |
} |
560 |
||
561 |
@Override |
|
562 |
public boolean equals(final Object other) { |
|
563 |
if (this == other) { |
|
564 |
return true; |
|
565 |
} |
|
566 |
||
16224
0c49ad4e3b55
8006222: Move slot from SpillProperty to Property
jlaskey
parents:
16151
diff
changeset
|
567 |
if (other == null || this.getClass() != other.getClass()) { |
16147 | 568 |
return false; |
569 |
} |
|
570 |
||
571 |
final Property otherProperty = (Property)other; |
|
572 |
||
24719 | 573 |
return equalsWithoutType(otherProperty) && |
27307
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
574 |
getLocalType() == otherProperty.getLocalType(); |
24719 | 575 |
} |
576 |
||
577 |
boolean equalsWithoutType(final Property otherProperty) { |
|
578 |
return getFlags() == otherProperty.getFlags() && |
|
579 |
getSlot() == otherProperty.getSlot() && |
|
580 |
getKey().equals(otherProperty.getKey()); |
|
16147 | 581 |
} |
582 |
||
31548
d158ec7e1e30
8130663: 6 fields can be static fields in Global class
sundar
parents:
29834
diff
changeset
|
583 |
private static String type(final Class<?> type) { |
24719 | 584 |
if (type == null) { |
585 |
return "undef"; |
|
586 |
} else if (type == int.class) { |
|
587 |
return "i"; |
|
588 |
} else if (type == double.class) { |
|
589 |
return "d"; |
|
590 |
} else { |
|
591 |
return "o"; |
|
592 |
} |
|
593 |
} |
|
594 |
||
595 |
/** |
|
596 |
* Short toString version |
|
597 |
* @return short toString |
|
598 |
*/ |
|
599 |
public final String toStringShort() { |
|
600 |
final StringBuilder sb = new StringBuilder(); |
|
31548
d158ec7e1e30
8130663: 6 fields can be static fields in Global class
sundar
parents:
29834
diff
changeset
|
601 |
final Class<?> t = getLocalType(); |
d158ec7e1e30
8130663: 6 fields can be static fields in Global class
sundar
parents:
29834
diff
changeset
|
602 |
sb.append(getKey()).append(" (").append(type(t)).append(')'); |
24719 | 603 |
return sb.toString(); |
16147 | 604 |
} |
605 |
||
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:
24720
diff
changeset
|
606 |
private static String indent(final String str, final int indent) { |
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:
24720
diff
changeset
|
607 |
final StringBuilder sb = new StringBuilder(); |
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:
24720
diff
changeset
|
608 |
sb.append(str); |
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:
24720
diff
changeset
|
609 |
for (int i = 0; i < indent - str.length(); i++) { |
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:
24720
diff
changeset
|
610 |
sb.append(' '); |
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:
24720
diff
changeset
|
611 |
} |
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:
24720
diff
changeset
|
612 |
return sb.toString(); |
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:
24720
diff
changeset
|
613 |
} |
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:
24720
diff
changeset
|
614 |
|
16147 | 615 |
@Override |
616 |
public String toString() { |
|
617 |
final StringBuilder sb = new StringBuilder(); |
|
31548
d158ec7e1e30
8130663: 6 fields can be static fields in Global class
sundar
parents:
29834
diff
changeset
|
618 |
final Class<?> t = getLocalType(); |
16147 | 619 |
|
33690 | 620 |
sb.append(indent(getKey().toString(), 20)). |
24719 | 621 |
append(" id="). |
622 |
append(Debug.id(this)). |
|
623 |
append(" (0x"). |
|
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:
24720
diff
changeset
|
624 |
append(indent(Integer.toHexString(flags), 4)). |
16147 | 625 |
append(") "). |
626 |
append(getClass().getSimpleName()). |
|
627 |
append(" {"). |
|
31548
d158ec7e1e30
8130663: 6 fields can be static fields in Global class
sundar
parents:
29834
diff
changeset
|
628 |
append(indent(type(t), 5)). |
16147 | 629 |
append('}'); |
630 |
||
16224
0c49ad4e3b55
8006222: Move slot from SpillProperty to Property
jlaskey
parents:
16151
diff
changeset
|
631 |
if (slot != -1) { |
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:
24720
diff
changeset
|
632 |
sb.append(" ["). |
24719 | 633 |
append("slot="). |
634 |
append(slot). |
|
635 |
append(']'); |
|
16224
0c49ad4e3b55
8006222: Move slot from SpillProperty to Property
jlaskey
parents:
16151
diff
changeset
|
636 |
} |
0c49ad4e3b55
8006222: Move slot from SpillProperty to Property
jlaskey
parents:
16151
diff
changeset
|
637 |
|
16147 | 638 |
return sb.toString(); |
639 |
} |
|
640 |
||
641 |
/** |
|
27307
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
642 |
* Get the current type of this property. If you are running with object fields enabled, |
16147 | 643 |
* this will always be Object.class. See the value representation explanation in |
644 |
* {@link Property#getSetter(Class, PropertyMap)} and {@link ObjectClassGenerator} |
|
645 |
* for more information. |
|
646 |
* |
|
27307
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
647 |
* <p>Note that for user accessor properties, this returns the type of the last observed |
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
648 |
* value passed to or returned by a user accessor. Use {@link #getLocalType()} to always get |
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
649 |
* the type of the actual value stored in the property slot.</p> |
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
650 |
* |
16147 | 651 |
* @return current type of property, null means undefined |
652 |
*/ |
|
27307
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
653 |
public final Class<?> getType() { |
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
654 |
return type; |
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
655 |
} |
24719 | 656 |
|
657 |
/** |
|
27307
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
658 |
* Set the type of this property. |
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
659 |
* @param type new type |
24719 | 660 |
*/ |
27307
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
661 |
public final void setType(final Class<?> type) { |
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
662 |
assert type != boolean.class : "no boolean storage support yet - fix this"; |
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
663 |
this.type = type == null ? null : type.isPrimitive() ? type : Object.class; |
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
664 |
} |
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
665 |
|
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
666 |
/** |
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
667 |
* Get the type of the value in the local property slot. This returns the same as |
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
668 |
* {@link #getType()} for normal properties, but always returns {@code Object.class} |
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
669 |
* for {@link UserAccessorProperty}s as their local type is a pair of accessor references. |
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
670 |
* |
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
671 |
* @return the local property type |
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
672 |
*/ |
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
673 |
protected Class<?> getLocalType() { |
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
674 |
return getType(); |
62ed492cbe63
8062401: User accessors require boxing and do not support optimistic types
hannesw
parents:
26768
diff
changeset
|
675 |
} |
16147 | 676 |
|
677 |
/** |
|
678 |
* Check whether this Property can ever change its type. The default is false, and if |
|
679 |
* you are not running with dual fields, the type is always object and can never change |
|
680 |
* @return true if this property can change types |
|
681 |
*/ |
|
682 |
public boolean canChangeType() { |
|
683 |
return false; |
|
684 |
} |
|
685 |
||
686 |
/** |
|
21685
ff0187bbe5c0
8027700: function redeclaration checks missing for declaration binding instantiation
sundar
parents:
19105
diff
changeset
|
687 |
* Check whether this property represents a function declaration. |
ff0187bbe5c0
8027700: function redeclaration checks missing for declaration binding instantiation
sundar
parents:
19105
diff
changeset
|
688 |
* @return whether this property is a function declaration or not. |
ff0187bbe5c0
8027700: function redeclaration checks missing for declaration binding instantiation
sundar
parents:
19105
diff
changeset
|
689 |
*/ |
ff0187bbe5c0
8027700: function redeclaration checks missing for declaration binding instantiation
sundar
parents:
19105
diff
changeset
|
690 |
public boolean isFunctionDeclaration() { |
29834
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
27814
diff
changeset
|
691 |
return (flags & IS_FUNCTION_DECLARATION) != 0; |
21685
ff0187bbe5c0
8027700: function redeclaration checks missing for declaration binding instantiation
sundar
parents:
19105
diff
changeset
|
692 |
} |
27814
96427359f4fe
8057691: Nashorn: let & const declarations are not shared between scripts
hannesw
parents:
27307
diff
changeset
|
693 |
|
96427359f4fe
8057691: Nashorn: let & const declarations are not shared between scripts
hannesw
parents:
27307
diff
changeset
|
694 |
/** |
96427359f4fe
8057691: Nashorn: let & const declarations are not shared between scripts
hannesw
parents:
27307
diff
changeset
|
695 |
* Is this a property defined by ES6 let or const? |
96427359f4fe
8057691: Nashorn: let & const declarations are not shared between scripts
hannesw
parents:
27307
diff
changeset
|
696 |
* @return true if this property represents a lexical binding. |
96427359f4fe
8057691: Nashorn: let & const declarations are not shared between scripts
hannesw
parents:
27307
diff
changeset
|
697 |
*/ |
96427359f4fe
8057691: Nashorn: let & const declarations are not shared between scripts
hannesw
parents:
27307
diff
changeset
|
698 |
public boolean isLexicalBinding() { |
29834
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
27814
diff
changeset
|
699 |
return (flags & IS_LEXICAL_BINDING) != 0; |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
27814
diff
changeset
|
700 |
} |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
27814
diff
changeset
|
701 |
|
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
27814
diff
changeset
|
702 |
/** |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
27814
diff
changeset
|
703 |
* Does this property support dual fields for both primitive and object values? |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
27814
diff
changeset
|
704 |
* @return true if supports dual fields |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
27814
diff
changeset
|
705 |
*/ |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
27814
diff
changeset
|
706 |
public boolean hasDualFields() { |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
27814
diff
changeset
|
707 |
return (flags & DUAL_FIELDS) != 0; |
27814
96427359f4fe
8057691: Nashorn: let & const declarations are not shared between scripts
hannesw
parents:
27307
diff
changeset
|
708 |
} |
36023 | 709 |
|
710 |
/** |
|
711 |
* Is this an accessor property as defined in ES5 8.6.1? |
|
712 |
* @return true if this is an accessor property |
|
713 |
*/ |
|
714 |
public boolean isAccessorProperty() { |
|
715 |
return (flags & IS_ACCESSOR_PROPERTY) != 0; |
|
716 |
} |
|
16147 | 717 |
} |