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; |