src/jdk/nashorn/internal/runtime/UserAccessorProperty.java

Print this page




  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;