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 java.lang.invoke.MethodHandle;
29 import java.lang.invoke.MethodHandles;
30 import java.util.concurrent.Callable;
31
32 import jdk.nashorn.internal.codegen.CompilerConstants;
33 import jdk.nashorn.internal.lookup.Lookup;
34 import jdk.nashorn.internal.runtime.linker.Bootstrap;
35
36 import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
37 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
38 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
39
40 /**
41 * Property with user defined getters/setters. Actual getter and setter
42 * functions are stored in underlying ScriptObject. Only the 'slot' info is
43 * stored in the property.
44 *
45 * The slots here denote either ScriptObject embed field number or spill
46 * array index. For spill array index, we use slot value of
47 * (index + ScriptObject.embedSize). See also ScriptObject.getEmbedOrSpill
48 * method. Negative slot value means that the corresponding getter or setter
49 * is null. Note that always two slots are allocated in ScriptObject - but
50 * negative (less by 1) slot number is stored for null getter or setter.
51 * This is done so that when the property is redefined with a different
52 * getter and setter (say, both non-null), we'll have spill slots to store
53 * those. When a slot is negative, (-slot - 1) is the embed/spill index.
54 */
55 public final class UserAccessorProperty extends Property {
56
57 /** User defined getter function slot. */
58 private final int getterSlot;
59
60 /** User defined setter function slot. */
61 private final int setterSlot;
62
63 /** Getter method handle */
64 private final static CompilerConstants.Call USER_ACCESSOR_GETTER = staticCall(MethodHandles.lookup(), UserAccessorProperty.class,
65 "userAccessorGetter", Object.class, ScriptObject.class, int.class, Object.class);
66
67 /** Setter method handle */
68 private final static CompilerConstants.Call USER_ACCESSOR_SETTER = staticCall(MethodHandles.lookup(), UserAccessorProperty.class,
69 "userAccessorSetter", void.class, ScriptObject.class, int.class, String.class, Object.class, Object.class);
70
71 /** Dynamic invoker for getter */
72 private static final Object INVOKE_UA_GETTER = new Object();
73
74 private static MethodHandle getINVOKE_UA_GETTER() {
75
76 return ((GlobalObject)Context.getGlobal()).getDynamicInvoker(INVOKE_UA_GETTER,
77 new Callable<MethodHandle>() {
78 @Override
79 public MethodHandle call() {
80 return Bootstrap.createDynamicInvoker("dyn:call", Object.class,
81 Object.class, Object.class);
82 }
83 });
84 }
85
86 /** Dynamic invoker for setter */
87 private static Object INVOKE_UA_SETTER = new Object();
88 private static MethodHandle getINVOKE_UA_SETTER() {
89 return ((GlobalObject)Context.getGlobal()).getDynamicInvoker(INVOKE_UA_SETTER,
90 new Callable<MethodHandle>() {
91 @Override
92 public MethodHandle call() {
93 return Bootstrap.createDynamicInvoker("dyn:call", void.class,
94 Object.class, Object.class, Object.class);
95 }
96 });
97 }
98
99 /**
100 * Constructor
101 *
102 * @param key property key
103 * @param flags property flags
104 * @param getterSlot getter slot, starting at first embed
105 * @param setterSlot setter slot, starting at first embed
106 */
107 UserAccessorProperty(final String key, final int flags, final int getterSlot, final int setterSlot) {
108 super(key, flags, -1);
109 this.getterSlot = getterSlot;
|
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 java.lang.invoke.MethodHandle;
29 import java.lang.invoke.MethodHandles;
30 import java.util.concurrent.Callable;
31
32 import jdk.nashorn.internal.codegen.CompilerConstants;
33 import jdk.nashorn.internal.lookup.Lookup;
34 import jdk.nashorn.internal.runtime.linker.Bootstrap;
35
36 import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
37 import jdk.nashorn.internal.objects.Global;
38 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
39 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
40
41 /**
42 * Property with user defined getters/setters. Actual getter and setter
43 * functions are stored in underlying ScriptObject. Only the 'slot' info is
44 * stored in the property.
45 *
46 * The slots here denote either ScriptObject embed field number or spill
47 * array index. For spill array index, we use slot value of
48 * (index + ScriptObject.embedSize). See also ScriptObject.getEmbedOrSpill
49 * method. Negative slot value means that the corresponding getter or setter
50 * is null. Note that always two slots are allocated in ScriptObject - but
51 * negative (less by 1) slot number is stored for null getter or setter.
52 * This is done so that when the property is redefined with a different
53 * getter and setter (say, both non-null), we'll have spill slots to store
54 * those. When a slot is negative, (-slot - 1) is the embed/spill index.
55 */
56 public final class UserAccessorProperty extends Property {
57
58 /** User defined getter function slot. */
59 private final int getterSlot;
60
61 /** User defined setter function slot. */
62 private final int setterSlot;
63
64 /** Getter method handle */
65 private final static CompilerConstants.Call USER_ACCESSOR_GETTER = staticCall(MethodHandles.lookup(), UserAccessorProperty.class,
66 "userAccessorGetter", Object.class, ScriptObject.class, int.class, Object.class);
67
68 /** Setter method handle */
69 private final static CompilerConstants.Call USER_ACCESSOR_SETTER = staticCall(MethodHandles.lookup(), UserAccessorProperty.class,
70 "userAccessorSetter", void.class, ScriptObject.class, int.class, String.class, Object.class, Object.class);
71
72 /** Dynamic invoker for getter */
73 private static final Object INVOKE_UA_GETTER = new Object();
74
75 private static MethodHandle getINVOKE_UA_GETTER() {
76
77 return Context.getGlobal().getDynamicInvoker(INVOKE_UA_GETTER,
78 new Callable<MethodHandle>() {
79 @Override
80 public MethodHandle call() {
81 return Bootstrap.createDynamicInvoker("dyn:call", Object.class,
82 Object.class, Object.class);
83 }
84 });
85 }
86
87 /** Dynamic invoker for setter */
88 private static Object INVOKE_UA_SETTER = new Object();
89 private static MethodHandle getINVOKE_UA_SETTER() {
90 return Context.getGlobal().getDynamicInvoker(INVOKE_UA_SETTER,
91 new Callable<MethodHandle>() {
92 @Override
93 public MethodHandle call() {
94 return Bootstrap.createDynamicInvoker("dyn:call", void.class,
95 Object.class, Object.class, Object.class);
96 }
97 });
98 }
99
100 /**
101 * Constructor
102 *
103 * @param key property key
104 * @param flags property flags
105 * @param getterSlot getter slot, starting at first embed
106 * @param setterSlot setter slot, starting at first embed
107 */
108 UserAccessorProperty(final String key, final int flags, final int getterSlot, final int setterSlot) {
109 super(key, flags, -1);
110 this.getterSlot = getterSlot;
|