4040 */
4141package com .oracle .truffle .js .nodes .interop ;
4242
43+ import com .oracle .truffle .api .dsl .Bind ;
4344import com .oracle .truffle .api .dsl .Cached ;
4445import com .oracle .truffle .api .dsl .GenerateUncached ;
4546import com .oracle .truffle .api .dsl .Specialization ;
47+ import com .oracle .truffle .api .library .CachedLibrary ;
4648import com .oracle .truffle .api .object .DynamicObject ;
49+ import com .oracle .truffle .api .object .DynamicObjectLibrary ;
50+ import com .oracle .truffle .api .object .Property ;
4751import com .oracle .truffle .js .nodes .JavaScriptBaseNode ;
4852import com .oracle .truffle .js .nodes .access .GetPrototypeNode ;
4953import com .oracle .truffle .js .nodes .access .IsExtensibleNode ;
5054import com .oracle .truffle .js .nodes .unary .IsCallableNode ;
5155import com .oracle .truffle .js .runtime .builtins .JSProxy ;
56+ import com .oracle .truffle .js .runtime .objects .Accessor ;
5257import com .oracle .truffle .js .runtime .objects .JSObject ;
58+ import com .oracle .truffle .js .runtime .objects .JSProperty ;
5359import com .oracle .truffle .js .runtime .objects .Null ;
5460import com .oracle .truffle .js .runtime .objects .PropertyDescriptor ;
5561import 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 ,
0 commit comments