Skip to content

Commit 2609acd

Browse files
committed
[GR-43097] Fix isMemberInvocable check for module namespace object properties.
1 parent 85968fc commit 2609acd

File tree

9 files changed

+70
-38
lines changed

9 files changed

+70
-38
lines changed

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/nodes/access/JSGetOwnPropertyNode.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ private Object getDataPropertyValue(JSDynamicObject thisObj, Property prop) {
229229
if (JSProperty.isProxy(prop)) {
230230
return getPropertyProxyValue(thisObj, value);
231231
} else {
232+
assert !JSProperty.isDataSpecial(prop) : prop;
232233
return value;
233234
}
234235
}

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/nodes/access/PropertyGetNode.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,7 @@ public static final class ObjectPropertyGetNode extends LinkedPropertyGetNode {
562562

563563
public ObjectPropertyGetNode(Property property, ReceiverCheckNode receiverCheck) {
564564
super(receiverCheck);
565-
assert JSProperty.isData(property) && !JSProperty.isProxy(property);
565+
assert JSProperty.isData(property) && !JSProperty.isDataSpecial(property);
566566
this.location = property.getLocation();
567567
}
568568

@@ -1844,7 +1844,7 @@ protected GetCacheNode createCachedPropertyNode(Property property, Object thisOb
18441844
JSDynamicObject thisJSObj = (JSDynamicObject) thisObj;
18451845
Shape cacheShape = thisJSObj.getShape();
18461846

1847-
if ((JSProperty.isData(property) && !JSProperty.isProxy(property) || JSProperty.isAccessor(property)) &&
1847+
if (((JSProperty.isData(property) && !JSProperty.isDataSpecial(property)) || JSProperty.isAccessor(property)) &&
18481848
property.getLocation().isAssumedFinal()) {
18491849
/**
18501850
* if property is final and: <br>
@@ -1874,7 +1874,7 @@ protected GetCacheNode createCachedPropertyNode(Property property, Object thisOb
18741874
isConstantObjectFinal = false;
18751875
}
18761876

1877-
if (JSProperty.isData(property) && !JSProperty.isProxy(property)) {
1877+
if (JSProperty.isData(property) && !JSProperty.isDataSpecial(property)) {
18781878
if (isEligibleForFinalSpecialization(cacheShape, thisJSObj, depth, isConstantObjectFinal)) {
18791879
return createFinalDataPropertySpecialization(property, cacheShape, thisJSObj, depth, isConstantObjectFinal);
18801880
}
@@ -1938,6 +1938,7 @@ private GetCacheNode createCachedPropertyNodeNotJSObject(Property property, Obje
19381938
}
19391939

19401940
private static GetCacheNode createSpecializationFromDataProperty(Property property, ReceiverCheckNode receiverCheck, JSContext context) {
1941+
assert JSProperty.isData(property);
19411942
if (property.getLocation() instanceof com.oracle.truffle.api.object.IntLocation) {
19421943
return new IntPropertyGetNode(property, receiverCheck);
19431944
} else if (property.getLocation() instanceof com.oracle.truffle.api.object.DoubleLocation) {
@@ -1968,6 +1969,7 @@ private static GetCacheNode createSpecializationFromDataProperty(Property proper
19681969
return new ProxyPropertyGetNode(property, receiverCheck);
19691970
}
19701971
} else {
1972+
assert !JSProperty.isDataSpecial(property);
19711973
return new ObjectPropertyGetNode(property, receiverCheck);
19721974
}
19731975
}
@@ -2150,16 +2152,15 @@ protected GetCacheNode createTruffleObjectPropertyNode() {
21502152
@Override
21512153
protected boolean canCombineShapeCheck(Shape parentShape, Shape cacheShape, Object thisObj, int depth, Object value, Property property) {
21522154
assert shapesHaveCommonLayoutForKey(parentShape, cacheShape);
2153-
if (JSDynamicObject.isJSDynamicObject(thisObj) && JSProperty.isData(property)) {
2154-
if (!JSProperty.isAccessor(property) && !JSProperty.isProxy(property)) {
2155-
return !property.getLocation().isAssumedFinal();
2156-
}
2155+
if (JSObject.isJSObject(thisObj) && JSProperty.isData(property) && !JSProperty.isDataSpecial(property)) {
2156+
return !property.getLocation().isAssumedFinal();
21572157
}
21582158
return false;
21592159
}
21602160

21612161
@Override
21622162
protected GetCacheNode createCombinedIcPropertyNode(Shape parentShape, Shape cacheShape, Object thisObj, int depth, Object value, Property property) {
2163+
assert JSProperty.isData(property) && !JSProperty.isDataSpecial(property) : property;
21632164
CombinedShapeCheckNode receiverCheck = new CombinedShapeCheckNode(parentShape, cacheShape);
21642165

21652166
if (property.getLocation() instanceof com.oracle.truffle.api.object.IntLocation) {
@@ -2171,7 +2172,6 @@ protected GetCacheNode createCombinedIcPropertyNode(Shape parentShape, Shape cac
21712172
} else if (property.getLocation() instanceof com.oracle.truffle.api.object.LongLocation) {
21722173
return new LongPropertyGetNode(property, receiverCheck);
21732174
} else {
2174-
assert !JSProperty.isProxy(property);
21752175
return new ObjectPropertyGetNode(property, receiverCheck);
21762176
}
21772177
}

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/nodes/access/PropertySetNode.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ public static final class ObjectPropertySetNode extends LinkedPropertySetNode {
402402
public ObjectPropertySetNode(Property property, ReceiverCheckNode shapeCheck) {
403403
super(shapeCheck);
404404
this.location = property.getLocation();
405-
assert JSProperty.isData(property) && JSProperty.isWritable(property) && !JSProperty.isProxy(property) : property;
405+
assert JSProperty.isData(property) && JSProperty.isWritable(property) && !JSProperty.isDataSpecial(property) : property;
406406
}
407407

408408
@Override
@@ -1058,7 +1058,7 @@ private SetCacheNode createCachedDataPropertyNodeJSObject(JSDynamicObject thisOb
10581058
}
10591059
return new PropertyProxySetNode(property, shapeCheck, isStrict());
10601060
} else {
1061-
assert JSProperty.isWritable(property) && !JSProperty.isModuleNamespaceExport(property) && depth == 0 && !JSProperty.isProxy(property);
1061+
assert JSProperty.isWritable(property) && !JSProperty.isDataSpecial(property) && depth == 0;
10621062
if (property.getLocation().isConstant() || !property.getLocation().canStore(value)) {
10631063
return createRedefinePropertyNode(key, shapeCheck, shapeCheck.getShape(), property);
10641064
}
@@ -1195,16 +1195,16 @@ protected void setPropertyAssumptionCheckEnabled(boolean value) {
11951195
@Override
11961196
protected boolean canCombineShapeCheck(Shape parentShape, Shape cacheShape, Object thisObj, int depth, Object value, Property property) {
11971197
assert shapesHaveCommonLayoutForKey(parentShape, cacheShape);
1198-
if (JSDynamicObject.isJSDynamicObject(thisObj) && JSProperty.isData(property)) {
1199-
if (JSProperty.isWritable(property) && depth == 0 && !superProperty && !JSProperty.isProxy(property)) {
1200-
return !property.getLocation().isConstant() && property.getLocation().canStore(value);
1201-
}
1198+
if (JSObject.isJSObject(thisObj) && JSProperty.isData(property) && !JSProperty.isDataSpecial(property) && JSProperty.isWritable(property) &&
1199+
depth == 0 && !superProperty) {
1200+
return !property.getLocation().isConstant() && property.getLocation().canStore(value);
12021201
}
12031202
return false;
12041203
}
12051204

12061205
@Override
12071206
protected SetCacheNode createCombinedIcPropertyNode(Shape parentShape, Shape cacheShape, Object thisObj, int depth, Object value, Property property) {
1207+
assert JSProperty.isData(property) && !JSProperty.isDataSpecial(property) : property;
12081208
PropertyGetNode.CombinedShapeCheckNode shapeCheck = new PropertyGetNode.CombinedShapeCheckNode(parentShape, cacheShape);
12091209

12101210
if (property.getLocation() instanceof com.oracle.truffle.api.object.IntLocation) {

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/nodes/interop/KeyInfoNode.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,10 @@
5656
import com.oracle.truffle.js.nodes.unary.IsCallableNode;
5757
import com.oracle.truffle.js.runtime.Properties;
5858
import com.oracle.truffle.js.runtime.Strings;
59+
import com.oracle.truffle.js.runtime.builtins.JSModuleNamespace;
5960
import com.oracle.truffle.js.runtime.builtins.JSProxy;
6061
import com.oracle.truffle.js.runtime.objects.Accessor;
62+
import com.oracle.truffle.js.runtime.objects.ExportResolution;
6163
import com.oracle.truffle.js.runtime.objects.JSDynamicObject;
6264
import com.oracle.truffle.js.runtime.objects.JSObject;
6365
import com.oracle.truffle.js.runtime.objects.JSProperty;
@@ -93,7 +95,8 @@ static boolean cachedOwnProperty(JSDynamicObject target, @SuppressWarnings("unus
9395
@Bind("fromJavaString(fromJavaStringNode, key)") TruffleString tStringKey,
9496
@Bind("objectLibrary.getProperty(target, tStringKey)") Property property,
9597
@Cached IsCallableNode isCallable,
96-
@Cached BranchProfile proxyBranch) {
98+
@Cached BranchProfile proxyBranch,
99+
@Cached BranchProfile moduleNamespaceBranch) {
97100
if (JSProperty.isAccessor(property)) {
98101
Accessor accessor = (Accessor) Properties.getOrDefault(objectLibrary, target, tStringKey, null);
99102
if ((query & READABLE) != 0 && accessor.hasGetter()) {
@@ -122,9 +125,15 @@ static boolean cachedOwnProperty(JSDynamicObject target, @SuppressWarnings("unus
122125
}
123126
if ((query & INVOCABLE) != 0) {
124127
Object value = Properties.getOrDefault(objectLibrary, target, tStringKey, Undefined.instance);
125-
if (JSProperty.isProxy(property)) {
126-
proxyBranch.enter();
127-
value = ((PropertyProxy) value).get(target);
128+
if (JSProperty.isDataSpecial(property)) {
129+
if (JSProperty.isProxy(property)) {
130+
proxyBranch.enter();
131+
value = ((PropertyProxy) value).get(target);
132+
} else {
133+
assert JSProperty.isModuleNamespaceExport(property) : property;
134+
moduleNamespaceBranch.enter();
135+
value = JSModuleNamespace.getBindingValue((ExportResolution) value);
136+
}
128137
}
129138
if (isCallable.executeBoolean(value)) {
130139
return true;

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/runtime/builtins/JSDictionary.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ private static PropertyDescriptor toPropertyDescriptor(Property p, Object value)
459459
desc.setConfigurable(JSProperty.isConfigurable(p));
460460
desc.setEnumerable(JSProperty.isEnumerable(p));
461461
} else {
462-
assert JSProperty.isData(p);
462+
assert JSProperty.isData(p) && !JSProperty.isDataSpecial(p) : p;
463463
desc = PropertyDescriptor.createData(value, JSProperty.isEnumerable(p), JSProperty.isWritable(p), JSProperty.isConfigurable(p));
464464
}
465465
return desc;

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/runtime/builtins/JSModuleNamespace.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,8 @@ public Object getOwnHelper(JSDynamicObject store, Object thisObj, Object key, No
162162
}
163163
}
164164

165-
static Object getBindingValue(ExportResolution binding) {
166-
CompilerAsserts.neverPartOfCompilation();
165+
@TruffleBoundary
166+
public static Object getBindingValue(ExportResolution binding) {
167167
TruffleString bindingName = binding.getBindingName();
168168
JSModuleRecord targetModule = binding.getModule();
169169
MaterializedFrame targetEnv = targetModule.getEnvironment();

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/runtime/builtins/JSNonProxy.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,8 @@ public static PropertyDescriptor ordinaryGetOwnPropertyIntl(JSDynamicObject this
470470
Object value = JSDynamicObject.getOrNull(thisObj, key);
471471
if (JSProperty.isProxy(prop)) {
472472
value = ((PropertyProxy) value).get(thisObj);
473+
} else {
474+
assert !JSProperty.isDataSpecial(prop) : prop;
473475
}
474476
desc = PropertyDescriptor.createData(value);
475477
desc.setWritable(JSProperty.isWritable(prop));

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/runtime/objects/JSProperty.java

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -56,21 +56,32 @@
5656
* Property objects represent the mapping between low-level stores and high-level data. The simplest
5757
* Property could be nothing more than a map of one index to one property's value, but abstracting
5858
* the interface allows for getter/setter methods, type-checked properties, and other such
59-
* specialized and language-specific behavior. ECMAScript[8.6.1]
59+
* specialized and language-specific behavior.
60+
*
61+
* @see JSAttributes
6062
*/
61-
public class JSProperty {
62-
/** Is this property an accessor or data property? */
63+
public final class JSProperty {
64+
65+
/** JS accessor property (implies not a data property). */
6366
public static final int ACCESSOR = 1 << 3;
6467

65-
/** Is this property a proxy property? */
68+
/** Special JS data property using internal {@link PropertyProxy} accessor. */
6669
public static final int PROXY = 1 << 4;
6770

71+
/** Used for global scope const bindings. */
6872
public static final int CONST = 1 << 5;
6973

70-
public static final int MODULE_NAMESPACE_EXPORT = 1 << 6 | PROXY;
74+
/** Module namespace object export binding (special data property). */
75+
public static final int MODULE_NAMESPACE_EXPORT = 1 << 6;
76+
77+
/** A special data property with internal accessor-like semantics. */
78+
private static final int DATA_SPECIAL = PROXY | MODULE_NAMESPACE_EXPORT;
79+
80+
private JSProperty() {
81+
}
7182

7283
@TruffleBoundary
73-
public String toString(Property property) {
84+
public static String toString(Property property) {
7485
return "\"" + property.getKey() + "\"" + getAttributeString(property) + ":" + property.getLocation();
7586
}
7687

@@ -98,7 +109,7 @@ public static Object getValue(Property property, JSDynamicObject store, Object t
98109
} else if (isProxy(property)) {
99110
return ((PropertyProxy) value).get(store);
100111
} else {
101-
assert isData(property);
112+
assert isData(property) && !isDataSpecial(property) : property;
102113
return value;
103114
}
104115
}
@@ -128,8 +139,8 @@ public static boolean setValue(Property property, JSDynamicObject store, Object
128139
if (isProxy(property)) {
129140
return setValueProxy(property, store, thisObj, value, isStrict);
130141
} else {
131-
assert isData(property);
132-
assert !(value instanceof Accessor || value instanceof PropertyProxy);
142+
assert isData(property) && !isDataSpecial(property) : property;
143+
assert !(value instanceof Accessor || value instanceof PropertyProxy || value instanceof ExportResolution);
133144
boolean success = Properties.putIfPresentUncached(store, property.getKey(), value);
134145
assert success;
135146
return true;
@@ -164,37 +175,41 @@ private static boolean setValueProxy(Property property, JSDynamicObject store, O
164175
}
165176

166177
public static boolean isConfigurable(Property property) {
167-
return (property.getFlags() & NOT_CONFIGURABLE) == 0;
178+
return isConfigurable(property.getFlags());
168179
}
169180

170181
public static boolean isEnumerable(Property property) {
171-
return (property.getFlags() & NOT_ENUMERABLE) == 0;
182+
return isEnumerable(property.getFlags());
172183
}
173184

174185
public static boolean isWritable(Property property) {
175-
return (property.getFlags() & NOT_WRITABLE) == 0;
186+
return isWritable(property.getFlags());
176187
}
177188

178189
public static boolean isProxy(Property property) {
179-
return (property.getFlags() & PROXY) != 0;
190+
return isProxy(property.getFlags());
180191
}
181192

182193
public static boolean isAccessor(Property property) {
183-
return (property.getFlags() & ACCESSOR) != 0;
194+
return isAccessor(property.getFlags());
184195
}
185196

186197
public static boolean isData(Property property) {
187-
return (property.getFlags() & ACCESSOR) == 0;
198+
return isData(property.getFlags());
188199
}
189200

190201
public static boolean isConst(Property property) {
191-
return (property.getFlags() & CONST) != 0;
202+
return isConst(property.getFlags());
192203
}
193204

194205
public static boolean isModuleNamespaceExport(Property property) {
195206
return isModuleNamespaceExport(property.getFlags());
196207
}
197208

209+
public static boolean isDataSpecial(Property property) {
210+
return isDataSpecial(property.getFlags());
211+
}
212+
198213
public static boolean isConfigurable(int flags) {
199214
return (flags & NOT_CONFIGURABLE) == 0;
200215
}
@@ -224,7 +239,11 @@ public static boolean isConst(int flags) {
224239
}
225240

226241
public static boolean isModuleNamespaceExport(int flags) {
227-
return (flags & MODULE_NAMESPACE_EXPORT) == MODULE_NAMESPACE_EXPORT;
242+
return (flags & MODULE_NAMESPACE_EXPORT) != 0;
243+
}
244+
245+
public static boolean isDataSpecial(int flags) {
246+
return (flags & DATA_SPECIAL) != 0;
228247
}
229248

230249
public static PropertyProxy getConstantProxy(Property proxyProperty) {

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/runtime/util/DefinePropertyUtil.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ private static boolean definePropertyExisting(JSDynamicObject thisObj, Object ke
200200
return true;
201201
}
202202
Property currentProperty = getPropertyByKey(thisObj, key);
203+
assert !JSProperty.isDataSpecial(currentProperty) || JSProperty.isProxy(currentProperty) : currentProperty;
203204

204205
if (JSProperty.isProxy(currentProperty) && descriptor.isDataDescriptor()) {
205206
PropertyProxy proxy = (PropertyProxy) JSDynamicObject.getOrNull(thisObj, key);

0 commit comments

Comments
 (0)