< prev index next >

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

Print this page




  54         Accessors(final Object getter, final Object setter) {
  55             set(getter, setter);
  56         }
  57 
  58         final void set(final Object getter, final Object setter) {
  59             this.getter = getter;
  60             this.setter = setter;
  61         }
  62 
  63         @Override
  64         public String toString() {
  65             return "[getter=" + getter + " setter=" + setter + ']';
  66         }
  67     }
  68 
  69     private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
  70 
  71     /** Getter method handle */
  72     private final static MethodHandle INVOKE_OBJECT_GETTER = findOwnMH_S("invokeObjectGetter", Object.class, Accessors.class, MethodHandle.class, Object.class);
  73     private final static MethodHandle INVOKE_INT_GETTER  = findOwnMH_S("invokeIntGetter", int.class, Accessors.class, MethodHandle.class, int.class, Object.class);
  74     private final static MethodHandle INVOKE_LONG_GETTER  = findOwnMH_S("invokeLongGetter", long.class, Accessors.class, MethodHandle.class, int.class, Object.class);
  75     private final static MethodHandle INVOKE_NUMBER_GETTER  = findOwnMH_S("invokeNumberGetter", double.class, Accessors.class, MethodHandle.class, int.class, Object.class);
  76 
  77     /** Setter method handle */
  78     private final static MethodHandle INVOKE_OBJECT_SETTER = findOwnMH_S("invokeObjectSetter", void.class, Accessors.class, MethodHandle.class, String.class, Object.class, Object.class);
  79     private final static MethodHandle INVOKE_INT_SETTER = findOwnMH_S("invokeIntSetter", void.class, Accessors.class, MethodHandle.class, String.class, Object.class, int.class);
  80     private final static MethodHandle INVOKE_LONG_SETTER = findOwnMH_S("invokeLongSetter", void.class, Accessors.class, MethodHandle.class, String.class, Object.class, long.class);
  81     private final static MethodHandle INVOKE_NUMBER_SETTER = findOwnMH_S("invokeNumberSetter", void.class, Accessors.class, MethodHandle.class, String.class, Object.class, double.class);
  82 
  83     private static final Object OBJECT_GETTER_INVOKER_KEY = new Object();
  84     private static MethodHandle getObjectGetterInvoker() {
  85         return Context.getGlobal().getDynamicInvoker(OBJECT_GETTER_INVOKER_KEY, new Callable<MethodHandle>() {
  86             @Override
  87             public MethodHandle call() throws Exception {
  88                 return getINVOKE_UA_GETTER(Object.class, INVALID_PROGRAM_POINT);
  89             }
  90         });
  91     }
  92 
  93     static MethodHandle getINVOKE_UA_GETTER(final Class<?> returnType, final int programPoint) {
  94         if (UnwarrantedOptimismException.isValid(programPoint)) {
  95             final int flags = NashornCallSiteDescriptor.CALLSITE_OPTIMISTIC | programPoint << CALLSITE_PROGRAM_POINT_SHIFT;
  96             return Bootstrap.createDynamicInvoker("dyn:call", flags, returnType, Object.class, Object.class);
  97         } else {
  98             return Bootstrap.createDynamicInvoker("dyn:call", Object.class, Object.class, Object.class);
  99         }
 100     }


 171     protected Class<?> getLocalType() {
 172         return Object.class;
 173     }
 174 
 175     @Override
 176     public boolean hasGetterFunction(final ScriptObject sobj) {
 177         return getAccessors(sobj).getter != null;
 178     }
 179 
 180     @Override
 181     public boolean hasSetterFunction(final ScriptObject sobj) {
 182         return getAccessors(sobj).setter != null;
 183     }
 184 
 185     @Override
 186     public int getIntValue(final ScriptObject self, final ScriptObject owner) {
 187         return (int)getObjectValue(self, owner);
 188     }
 189 
 190     @Override
 191     public long getLongValue(final ScriptObject self, final ScriptObject owner) {
 192         return (long)getObjectValue(self, owner);
 193     }
 194 
 195     @Override
 196     public double getDoubleValue(final ScriptObject self, final ScriptObject owner) {
 197         return (double)getObjectValue(self, owner);
 198     }
 199 
 200     @Override
 201     public Object getObjectValue(final ScriptObject self, final ScriptObject owner) {
 202         try {
 203             return invokeObjectGetter(getAccessors((owner != null) ? owner : self), getObjectGetterInvoker(), self);
 204         } catch (final Error | RuntimeException t) {
 205             throw t;
 206         } catch (final Throwable t) {
 207             throw new RuntimeException(t);
 208         }
 209     }
 210 
 211     @Override
 212     public void setValue(final ScriptObject self, final ScriptObject owner, final int value, final boolean strict) {
 213         setValue(self, owner, (Object) value, strict);
 214     }
 215 
 216     @Override
 217     public void setValue(final ScriptObject self, final ScriptObject owner, final long value, final boolean strict) {
 218         setValue(self, owner, (Object) value, strict);
 219     }
 220 
 221     @Override
 222     public void setValue(final ScriptObject self, final ScriptObject owner, final double value, final boolean strict) {
 223         setValue(self, owner, (Object) value, strict);
 224     }
 225 
 226     @Override
 227     public void setValue(final ScriptObject self, final ScriptObject owner, final Object value, final boolean strict) {
 228         try {
 229             invokeObjectSetter(getAccessors((owner != null) ? owner : self), getObjectSetterInvoker(), strict ? getKey() : null, self, value);
 230         } catch (final Error | RuntimeException t) {
 231             throw t;
 232         } catch (final Throwable t) {
 233             throw new RuntimeException(t);
 234         }
 235     }
 236 
 237     @Override
 238     public MethodHandle getGetter(final Class<?> type) {
 239         //this returns a getter on the format (Accessors, Object receiver)
 240         return Lookup.filterReturnType(INVOKE_OBJECT_GETTER, type);
 241     }
 242 
 243     @Override
 244     public MethodHandle getOptimisticGetter(final Class<?> type, final int programPoint) {
 245         if (type == int.class) {
 246             return INVOKE_INT_GETTER;
 247         } else if (type == long.class) {
 248             return INVOKE_LONG_GETTER;
 249         } else if (type == double.class) {
 250             return INVOKE_NUMBER_GETTER;
 251         } else {
 252             assert type == Object.class;
 253             return INVOKE_OBJECT_GETTER;
 254         }
 255     }
 256 
 257     @Override
 258     void initMethodHandles(final Class<?> structure) {
 259         throw new UnsupportedOperationException();
 260     }
 261 
 262     @Override
 263     public ScriptFunction getGetterFunction(final ScriptObject sobj) {
 264         final Object value = getAccessors(sobj).getter;
 265         return (value instanceof ScriptFunction) ? (ScriptFunction)value : null;
 266     }
 267 
 268     @Override
 269     public MethodHandle getSetter(final Class<?> type, final PropertyMap currentMap) {
 270         if (type == int.class) {
 271             return INVOKE_INT_SETTER;
 272         } else if (type == long.class) {
 273             return INVOKE_LONG_SETTER;
 274         } else if (type == double.class) {
 275             return INVOKE_NUMBER_SETTER;
 276         } else {
 277             assert type == Object.class;
 278             return INVOKE_OBJECT_SETTER;
 279         }
 280     }
 281 
 282     @Override
 283     public ScriptFunction getSetterFunction(final ScriptObject sobj) {
 284         final Object value = getAccessors(sobj).setter;
 285         return (value instanceof ScriptFunction) ? (ScriptFunction)value : null;
 286     }
 287 
 288     /**
 289      * Get the getter for the {@code Accessors} object.
 290      * This is the the super {@code Object} type getter with {@code Accessors} return type.
 291      *
 292      * @return The getter handle for the Accessors
 293      */


 303     private static Object invokeObjectGetter(final Accessors gs, final MethodHandle invoker, final Object self) throws Throwable {
 304         final Object func = gs.getter;
 305         if (func instanceof ScriptFunction) {
 306             return invoker.invokeExact(func, self);
 307         }
 308 
 309         return UNDEFINED;
 310     }
 311 
 312     @SuppressWarnings("unused")
 313     private static int invokeIntGetter(final Accessors gs, final MethodHandle invoker, final int programPoint, final Object self) throws Throwable {
 314         final Object func = gs.getter;
 315         if (func instanceof ScriptFunction) {
 316             return (int) invoker.invokeExact(func, self);
 317         }
 318 
 319         throw new UnwarrantedOptimismException(UNDEFINED, programPoint);
 320     }
 321 
 322     @SuppressWarnings("unused")
 323     private static long invokeLongGetter(final Accessors gs, final MethodHandle invoker, final int programPoint, final Object self) throws Throwable {
 324         final Object func = gs.getter;
 325         if (func instanceof ScriptFunction) {
 326             return (long) invoker.invokeExact(func, self);
 327         }
 328 
 329         throw new UnwarrantedOptimismException(UNDEFINED, programPoint);
 330     }
 331 
 332     @SuppressWarnings("unused")
 333     private static double invokeNumberGetter(final Accessors gs, final MethodHandle invoker, final int programPoint, final Object self) throws Throwable {
 334         final Object func = gs.getter;
 335         if (func instanceof ScriptFunction) {
 336             return (double) invoker.invokeExact(func, self);
 337         }
 338 
 339         throw new UnwarrantedOptimismException(UNDEFINED, programPoint);
 340     }
 341 
 342     @SuppressWarnings("unused")
 343     private static void invokeObjectSetter(final Accessors gs, final MethodHandle invoker, final String name, final Object self, final Object value) throws Throwable {
 344         final Object func = gs.setter;
 345         if (func instanceof ScriptFunction) {
 346             invoker.invokeExact(func, self, value);
 347         } else if (name != null) {
 348             throw typeError("property.has.no.setter", name, ScriptRuntime.safeToString(self));
 349         }
 350     }
 351 
 352     @SuppressWarnings("unused")
 353     private static void invokeIntSetter(final Accessors gs, final MethodHandle invoker, final String name, final Object self, final int value) throws Throwable {
 354         final Object func = gs.setter;
 355         if (func instanceof ScriptFunction) {
 356             invoker.invokeExact(func, self, value);
 357         } else if (name != null) {
 358             throw typeError("property.has.no.setter", name, ScriptRuntime.safeToString(self));
 359         }
 360     }
 361 
 362     @SuppressWarnings("unused")
 363     private static void invokeLongSetter(final Accessors gs, final MethodHandle invoker, final String name, final Object self, final long value) throws Throwable {
 364         final Object func = gs.setter;
 365         if (func instanceof ScriptFunction) {
 366             invoker.invokeExact(func, self, value);
 367         } else if (name != null) {
 368             throw typeError("property.has.no.setter", name, ScriptRuntime.safeToString(self));
 369         }
 370     }
 371 
 372     @SuppressWarnings("unused")
 373     private static void invokeNumberSetter(final Accessors gs, final MethodHandle invoker, final String name, final Object self, final double value) throws Throwable {
 374         final Object func = gs.setter;
 375         if (func instanceof ScriptFunction) {
 376             invoker.invokeExact(func, self, value);
 377         } else if (name != null) {
 378             throw typeError("property.has.no.setter", name, ScriptRuntime.safeToString(self));
 379         }
 380     }
 381 
 382     private static MethodHandle findOwnMH_S(final String name, final Class<?> rtype, final Class<?>... types) {
 383         return MH.findStatic(LOOKUP, UserAccessorProperty.class, name, MH.type(rtype, types));


  54         Accessors(final Object getter, final Object setter) {
  55             set(getter, setter);
  56         }
  57 
  58         final void set(final Object getter, final Object setter) {
  59             this.getter = getter;
  60             this.setter = setter;
  61         }
  62 
  63         @Override
  64         public String toString() {
  65             return "[getter=" + getter + " setter=" + setter + ']';
  66         }
  67     }
  68 
  69     private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
  70 
  71     /** Getter method handle */
  72     private final static MethodHandle INVOKE_OBJECT_GETTER = findOwnMH_S("invokeObjectGetter", Object.class, Accessors.class, MethodHandle.class, Object.class);
  73     private final static MethodHandle INVOKE_INT_GETTER  = findOwnMH_S("invokeIntGetter", int.class, Accessors.class, MethodHandle.class, int.class, Object.class);

  74     private final static MethodHandle INVOKE_NUMBER_GETTER  = findOwnMH_S("invokeNumberGetter", double.class, Accessors.class, MethodHandle.class, int.class, Object.class);
  75 
  76     /** Setter method handle */
  77     private final static MethodHandle INVOKE_OBJECT_SETTER = findOwnMH_S("invokeObjectSetter", void.class, Accessors.class, MethodHandle.class, String.class, Object.class, Object.class);
  78     private final static MethodHandle INVOKE_INT_SETTER = findOwnMH_S("invokeIntSetter", void.class, Accessors.class, MethodHandle.class, String.class, Object.class, int.class);

  79     private final static MethodHandle INVOKE_NUMBER_SETTER = findOwnMH_S("invokeNumberSetter", void.class, Accessors.class, MethodHandle.class, String.class, Object.class, double.class);
  80 
  81     private static final Object OBJECT_GETTER_INVOKER_KEY = new Object();
  82     private static MethodHandle getObjectGetterInvoker() {
  83         return Context.getGlobal().getDynamicInvoker(OBJECT_GETTER_INVOKER_KEY, new Callable<MethodHandle>() {
  84             @Override
  85             public MethodHandle call() throws Exception {
  86                 return getINVOKE_UA_GETTER(Object.class, INVALID_PROGRAM_POINT);
  87             }
  88         });
  89     }
  90 
  91     static MethodHandle getINVOKE_UA_GETTER(final Class<?> returnType, final int programPoint) {
  92         if (UnwarrantedOptimismException.isValid(programPoint)) {
  93             final int flags = NashornCallSiteDescriptor.CALLSITE_OPTIMISTIC | programPoint << CALLSITE_PROGRAM_POINT_SHIFT;
  94             return Bootstrap.createDynamicInvoker("dyn:call", flags, returnType, Object.class, Object.class);
  95         } else {
  96             return Bootstrap.createDynamicInvoker("dyn:call", Object.class, Object.class, Object.class);
  97         }
  98     }


 169     protected Class<?> getLocalType() {
 170         return Object.class;
 171     }
 172 
 173     @Override
 174     public boolean hasGetterFunction(final ScriptObject sobj) {
 175         return getAccessors(sobj).getter != null;
 176     }
 177 
 178     @Override
 179     public boolean hasSetterFunction(final ScriptObject sobj) {
 180         return getAccessors(sobj).setter != null;
 181     }
 182 
 183     @Override
 184     public int getIntValue(final ScriptObject self, final ScriptObject owner) {
 185         return (int)getObjectValue(self, owner);
 186     }
 187 
 188     @Override





 189     public double getDoubleValue(final ScriptObject self, final ScriptObject owner) {
 190         return (double)getObjectValue(self, owner);
 191     }
 192 
 193     @Override
 194     public Object getObjectValue(final ScriptObject self, final ScriptObject owner) {
 195         try {
 196             return invokeObjectGetter(getAccessors((owner != null) ? owner : self), getObjectGetterInvoker(), self);
 197         } catch (final Error | RuntimeException t) {
 198             throw t;
 199         } catch (final Throwable t) {
 200             throw new RuntimeException(t);
 201         }
 202     }
 203 
 204     @Override
 205     public void setValue(final ScriptObject self, final ScriptObject owner, final int value, final boolean strict) {
 206         setValue(self, owner, (Object) value, strict);
 207     }
 208 
 209     @Override





 210     public void setValue(final ScriptObject self, final ScriptObject owner, final double value, final boolean strict) {
 211         setValue(self, owner, (Object) value, strict);
 212     }
 213 
 214     @Override
 215     public void setValue(final ScriptObject self, final ScriptObject owner, final Object value, final boolean strict) {
 216         try {
 217             invokeObjectSetter(getAccessors((owner != null) ? owner : self), getObjectSetterInvoker(), strict ? getKey() : null, self, value);
 218         } catch (final Error | RuntimeException t) {
 219             throw t;
 220         } catch (final Throwable t) {
 221             throw new RuntimeException(t);
 222         }
 223     }
 224 
 225     @Override
 226     public MethodHandle getGetter(final Class<?> type) {
 227         //this returns a getter on the format (Accessors, Object receiver)
 228         return Lookup.filterReturnType(INVOKE_OBJECT_GETTER, type);
 229     }
 230 
 231     @Override
 232     public MethodHandle getOptimisticGetter(final Class<?> type, final int programPoint) {
 233         if (type == int.class) {
 234             return INVOKE_INT_GETTER;


 235         } else if (type == double.class) {
 236             return INVOKE_NUMBER_GETTER;
 237         } else {
 238             assert type == Object.class;
 239             return INVOKE_OBJECT_GETTER;
 240         }
 241     }
 242 
 243     @Override
 244     void initMethodHandles(final Class<?> structure) {
 245         throw new UnsupportedOperationException();
 246     }
 247 
 248     @Override
 249     public ScriptFunction getGetterFunction(final ScriptObject sobj) {
 250         final Object value = getAccessors(sobj).getter;
 251         return (value instanceof ScriptFunction) ? (ScriptFunction)value : null;
 252     }
 253 
 254     @Override
 255     public MethodHandle getSetter(final Class<?> type, final PropertyMap currentMap) {
 256         if (type == int.class) {
 257             return INVOKE_INT_SETTER;


 258         } else if (type == double.class) {
 259             return INVOKE_NUMBER_SETTER;
 260         } else {
 261             assert type == Object.class;
 262             return INVOKE_OBJECT_SETTER;
 263         }
 264     }
 265 
 266     @Override
 267     public ScriptFunction getSetterFunction(final ScriptObject sobj) {
 268         final Object value = getAccessors(sobj).setter;
 269         return (value instanceof ScriptFunction) ? (ScriptFunction)value : null;
 270     }
 271 
 272     /**
 273      * Get the getter for the {@code Accessors} object.
 274      * This is the the super {@code Object} type getter with {@code Accessors} return type.
 275      *
 276      * @return The getter handle for the Accessors
 277      */


 287     private static Object invokeObjectGetter(final Accessors gs, final MethodHandle invoker, final Object self) throws Throwable {
 288         final Object func = gs.getter;
 289         if (func instanceof ScriptFunction) {
 290             return invoker.invokeExact(func, self);
 291         }
 292 
 293         return UNDEFINED;
 294     }
 295 
 296     @SuppressWarnings("unused")
 297     private static int invokeIntGetter(final Accessors gs, final MethodHandle invoker, final int programPoint, final Object self) throws Throwable {
 298         final Object func = gs.getter;
 299         if (func instanceof ScriptFunction) {
 300             return (int) invoker.invokeExact(func, self);
 301         }
 302 
 303         throw new UnwarrantedOptimismException(UNDEFINED, programPoint);
 304     }
 305 
 306     @SuppressWarnings("unused")










 307     private static double invokeNumberGetter(final Accessors gs, final MethodHandle invoker, final int programPoint, final Object self) throws Throwable {
 308         final Object func = gs.getter;
 309         if (func instanceof ScriptFunction) {
 310             return (double) invoker.invokeExact(func, self);
 311         }
 312 
 313         throw new UnwarrantedOptimismException(UNDEFINED, programPoint);
 314     }
 315 
 316     @SuppressWarnings("unused")
 317     private static void invokeObjectSetter(final Accessors gs, final MethodHandle invoker, final String name, final Object self, final Object value) throws Throwable {
 318         final Object func = gs.setter;
 319         if (func instanceof ScriptFunction) {
 320             invoker.invokeExact(func, self, value);
 321         } else if (name != null) {
 322             throw typeError("property.has.no.setter", name, ScriptRuntime.safeToString(self));
 323         }
 324     }
 325 
 326     @SuppressWarnings("unused")
 327     private static void invokeIntSetter(final Accessors gs, final MethodHandle invoker, final String name, final Object self, final int value) throws Throwable {










 328         final Object func = gs.setter;
 329         if (func instanceof ScriptFunction) {
 330             invoker.invokeExact(func, self, value);
 331         } else if (name != null) {
 332             throw typeError("property.has.no.setter", name, ScriptRuntime.safeToString(self));
 333         }
 334     }
 335 
 336     @SuppressWarnings("unused")
 337     private static void invokeNumberSetter(final Accessors gs, final MethodHandle invoker, final String name, final Object self, final double value) throws Throwable {
 338         final Object func = gs.setter;
 339         if (func instanceof ScriptFunction) {
 340             invoker.invokeExact(func, self, value);
 341         } else if (name != null) {
 342             throw typeError("property.has.no.setter", name, ScriptRuntime.safeToString(self));
 343         }
 344     }
 345 
 346     private static MethodHandle findOwnMH_S(final String name, final Class<?> rtype, final Class<?>... types) {
 347         return MH.findStatic(LOOKUP, UserAccessorProperty.class, name, MH.type(rtype, types));
< prev index next >