Skip to content

Commit 5e95b35

Browse files
committed
Improve isMember*: Add cached specialization for ordinary own properties.
1 parent 38bd251 commit 5e95b35

File tree

2 files changed

+57
-2
lines changed

2 files changed

+57
-2
lines changed

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

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,22 @@
4040
*/
4141
package com.oracle.truffle.js.nodes.interop;
4242

43+
import com.oracle.truffle.api.dsl.Bind;
4344
import com.oracle.truffle.api.dsl.Cached;
4445
import com.oracle.truffle.api.dsl.GenerateUncached;
4546
import com.oracle.truffle.api.dsl.Specialization;
47+
import com.oracle.truffle.api.library.CachedLibrary;
4648
import com.oracle.truffle.api.object.DynamicObject;
49+
import com.oracle.truffle.api.object.DynamicObjectLibrary;
50+
import com.oracle.truffle.api.object.Property;
4751
import com.oracle.truffle.js.nodes.JavaScriptBaseNode;
4852
import com.oracle.truffle.js.nodes.access.GetPrototypeNode;
4953
import com.oracle.truffle.js.nodes.access.IsExtensibleNode;
5054
import com.oracle.truffle.js.nodes.unary.IsCallableNode;
5155
import com.oracle.truffle.js.runtime.builtins.JSProxy;
56+
import com.oracle.truffle.js.runtime.objects.Accessor;
5257
import com.oracle.truffle.js.runtime.objects.JSObject;
58+
import com.oracle.truffle.js.runtime.objects.JSProperty;
5359
import com.oracle.truffle.js.runtime.objects.Null;
5460
import com.oracle.truffle.js.runtime.objects.PropertyDescriptor;
5561
import com.oracle.truffle.js.runtime.objects.Undefined;
@@ -73,7 +79,48 @@ public abstract class KeyInfoNode extends JavaScriptBaseNode {
7379

7480
public abstract boolean execute(DynamicObject receiver, String key, int query);
7581

76-
@Specialization
82+
@Specialization(guards = {"!isJSProxy(target)", "property != null"}, limit = "2")
83+
static boolean cachedOwnProperty(DynamicObject target, String key, int query,
84+
@CachedLibrary("target") DynamicObjectLibrary objectLibrary,
85+
@Bind("objectLibrary.getProperty(target, key)") Property property,
86+
@Cached IsCallableNode isCallable) {
87+
if (JSProperty.isAccessor(property)) {
88+
Accessor accessor = (Accessor) objectLibrary.getOrDefault(target, key, null);
89+
if ((query & READABLE) != 0 && accessor.hasGetter()) {
90+
return true;
91+
}
92+
if ((query & MODIFIABLE) != 0 && accessor.hasSetter()) {
93+
return true;
94+
}
95+
if ((query & READ_SIDE_EFFECTS) != 0 && accessor.hasGetter()) {
96+
return true;
97+
}
98+
if ((query & WRITE_SIDE_EFFECTS) != 0 && accessor.hasSetter()) {
99+
return true;
100+
}
101+
if ((query & REMOVABLE) != 0 && JSProperty.isConfigurable(property)) {
102+
return true;
103+
}
104+
return false;
105+
} else {
106+
assert JSProperty.isData(property);
107+
if ((query & READABLE) != 0) {
108+
return true;
109+
}
110+
if ((query & MODIFIABLE) != 0 && JSProperty.isWritable(property)) {
111+
return true;
112+
}
113+
if ((query & INVOCABLE) != 0 && isCallable.executeBoolean(objectLibrary.getOrDefault(target, key, Undefined.instance))) {
114+
return true;
115+
}
116+
if ((query & REMOVABLE) != 0 && JSProperty.isConfigurable(property)) {
117+
return true;
118+
}
119+
return false;
120+
}
121+
}
122+
123+
@Specialization(replaces = "cachedOwnProperty")
77124
static boolean member(DynamicObject target, String key, int query,
78125
@Cached GetPrototypeNode getPrototype,
79126
@Cached IsCallableNode isCallable,

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
*/
4141
package com.oracle.truffle.js.runtime.objects;
4242

43-
import com.oracle.truffle.api.object.*;
43+
import com.oracle.truffle.api.object.DynamicObject;
4444

4545
public final class Accessor {
4646
private final DynamicObject getter;
@@ -58,4 +58,12 @@ public DynamicObject getGetter() {
5858
public DynamicObject getSetter() {
5959
return setter;
6060
}
61+
62+
public boolean hasGetter() {
63+
return getter != Undefined.instance;
64+
}
65+
66+
public boolean hasSetter() {
67+
return setter != Undefined.instance;
68+
}
6169
}

0 commit comments

Comments
 (0)