< prev index next >

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

Print this page




 204      * to the constructor, and the rest are created from those. Used e.g. by Nasgen classes
 205      *
 206      * @param key    the property key
 207      * @param flags  the property flags
 208      * @param slot   the property field number or spill slot
 209      * @param getter the property getter
 210      * @param setter the property setter or null if non writable, non configurable
 211      */
 212     private AccessorProperty(final String key, final int flags, final int slot, final MethodHandle getter, final MethodHandle setter) {
 213         super(key, flags | IS_BUILTIN | DUAL_FIELDS | (getter.type().returnType().isPrimitive() ? IS_NASGEN_PRIMITIVE : 0), slot);
 214         assert !isSpill();
 215 
 216         // we don't need to prep the setters these will never be invalidated as this is a nasgen
 217         // or known type getter/setter. No invalidations will take place
 218 
 219         final Class<?> getterType = getter.type().returnType();
 220         final Class<?> setterType = setter == null ? null : setter.type().parameterType(1);
 221 
 222         assert setterType == null || setterType == getterType;
 223 
 224         if (getterType == int.class || getterType == long.class) {
 225             primitiveGetter = MH.asType(getter, Lookup.GET_PRIMITIVE_TYPE);
 226             primitiveSetter = setter == null ? null : MH.asType(setter, Lookup.SET_PRIMITIVE_TYPE);
 227         } else if (getterType == double.class) {
 228             primitiveGetter = MH.asType(MH.filterReturnValue(getter, ObjectClassGenerator.PACK_DOUBLE), Lookup.GET_PRIMITIVE_TYPE);
 229             primitiveSetter = setter == null ? null : MH.asType(MH.filterArguments(setter, 1, ObjectClassGenerator.UNPACK_DOUBLE), Lookup.SET_PRIMITIVE_TYPE);
 230         } else {
 231             primitiveGetter = primitiveSetter = null;
 232         }
 233 
 234         assert primitiveGetter == null || primitiveGetter.type() == Lookup.GET_PRIMITIVE_TYPE : primitiveGetter + "!=" + Lookup.GET_PRIMITIVE_TYPE;
 235         assert primitiveSetter == null || primitiveSetter.type() == Lookup.SET_PRIMITIVE_TYPE : primitiveSetter;
 236 
 237         objectGetter  = getter.type() != Lookup.GET_OBJECT_TYPE ? MH.asType(getter, Lookup.GET_OBJECT_TYPE) : getter;
 238         objectSetter  = setter != null && setter.type() != Lookup.SET_OBJECT_TYPE ? MH.asType(setter, Lookup.SET_OBJECT_TYPE) : setter;
 239 
 240         setType(getterType);
 241     }
 242 
 243     /**
 244      * Normal ACCESS PROPERTY constructor given a structure class.


 384         return new AccessorProperty(this);
 385     }
 386 
 387     @Override
 388     public Property copy(final Class<?> newType) {
 389         return new AccessorProperty(this, newType);
 390     }
 391 
 392     @Override
 393     public int getIntValue(final ScriptObject self, final ScriptObject owner) {
 394         try {
 395             return (int)getGetter(int.class).invokeExact((Object)self);
 396         } catch (final Error | RuntimeException e) {
 397             throw e;
 398         } catch (final Throwable e) {
 399             throw new RuntimeException(e);
 400         }
 401      }
 402 
 403     @Override
 404     public long getLongValue(final ScriptObject self, final ScriptObject owner) {
 405         try {
 406             return (long)getGetter(long.class).invokeExact((Object)self);
 407         } catch (final Error | RuntimeException e) {
 408             throw e;
 409         } catch (final Throwable e) {
 410             throw new RuntimeException(e);
 411         }
 412     }
 413 
 414      @Override
 415      public double getDoubleValue(final ScriptObject self, final ScriptObject owner) {
 416         try {
 417             return (double)getGetter(double.class).invokeExact((Object)self);
 418         } catch (final Error | RuntimeException e) {
 419             throw e;
 420         } catch (final Throwable e) {
 421             throw new RuntimeException(e);
 422         }
 423     }
 424 
 425      @Override
 426      public Object getObjectValue(final ScriptObject self, final ScriptObject owner) {
 427         try {
 428             return getGetter(Object.class).invokeExact((Object)self);
 429         } catch (final Error | RuntimeException e) {
 430             throw e;
 431         } catch (final Throwable e) {
 432             throw new RuntimeException(e);
 433         }
 434     }


 436      /**
 437       * Invoke setter for this property with a value
 438       * @param self  owner
 439       * @param value value
 440       */
 441     protected final void invokeSetter(final ScriptObject self, final int value) {
 442         try {
 443             getSetter(int.class, self.getMap()).invokeExact((Object)self, value);
 444         } catch (final Error | RuntimeException e) {
 445             throw e;
 446         } catch (final Throwable e) {
 447             throw new RuntimeException(e);
 448         }
 449     }
 450 
 451     /**
 452      * Invoke setter for this property with a value
 453      * @param self  owner
 454      * @param value value
 455      */
 456     protected final void invokeSetter(final ScriptObject self, final long value) {
 457         try {
 458             getSetter(long.class, self.getMap()).invokeExact((Object)self, value);
 459         } catch (final Error | RuntimeException e) {
 460             throw e;
 461         } catch (final Throwable e) {
 462             throw new RuntimeException(e);
 463         }
 464     }
 465 
 466     /**
 467      * Invoke setter for this property with a value
 468      * @param self  owner
 469      * @param value value
 470      */
 471     protected final void invokeSetter(final ScriptObject self, final double value) {
 472         try {
 473             getSetter(double.class, self.getMap()).invokeExact((Object)self, value);
 474         } catch (final Error | RuntimeException e) {
 475             throw e;
 476         } catch (final Throwable e) {
 477             throw new RuntimeException(e);
 478         }
 479     }
 480 
 481     /**
 482      * Invoke setter for this property with a value
 483      * @param self  owner
 484      * @param value value
 485      */
 486     protected final void invokeSetter(final ScriptObject self, final Object value) {
 487         try {
 488             getSetter(Object.class, self.getMap()).invokeExact((Object)self, value);
 489         } catch (final Error | RuntimeException e) {
 490             throw e;
 491         } catch (final Throwable e) {
 492             throw new RuntimeException(e);
 493         }
 494     }
 495 
 496     @Override
 497     public void setValue(final ScriptObject self, final ScriptObject owner, final int value, final boolean strict)  {
 498         assert isConfigurable() || isWritable() : getKey() + " is not writable or configurable";
 499         invokeSetter(self, value);
 500     }
 501 
 502     @Override
 503     public void setValue(final ScriptObject self, final ScriptObject owner, final long value, final boolean strict)  {
 504         assert isConfigurable() || isWritable() : getKey() + " is not writable or configurable";
 505         invokeSetter(self, value);
 506     }
 507 
 508     @Override
 509     public void setValue(final ScriptObject self, final ScriptObject owner, final double value, final boolean strict)  {
 510         assert isConfigurable() || isWritable() : getKey() + " is not writable or configurable";
 511         invokeSetter(self, value);
 512     }
 513 
 514     @Override
 515     public void setValue(final ScriptObject self, final ScriptObject owner, final Object value, final boolean strict)  {
 516         //this is sometimes used for bootstrapping, hence no assert. ugly.
 517         invokeSetter(self, value);
 518     }
 519 
 520     @Override
 521     void initMethodHandles(final Class<?> structure) {
 522         // sanity check for structure class
 523         if (!ScriptObject.class.isAssignableFrom(structure) || !StructureLoader.isStructureClass(structure.getName())) {
 524             throw new IllegalArgumentException();
 525         }
 526         // this method is overridden in SpillProperty
 527         assert !isSpill();
 528         initGetterSetter(structure);
 529     }
 530 
 531     @Override
 532     public MethodHandle getGetter(final Class<?> type) {
 533         final int i = getAccessorTypeIndex(type);
 534 
 535         assert type == int.class ||
 536                 type == long.class ||
 537                 type == double.class ||
 538                 type == Object.class :
 539                 "invalid getter type " + type + " for " + getKey();
 540 
 541         checkUndeclared();
 542 
 543         //all this does is add a return value filter for object fields only
 544         final MethodHandle[] getterCache = GETTER_CACHE;
 545         final MethodHandle cachedGetter = getterCache[i];
 546         final MethodHandle getter;
 547         if (cachedGetter != null) {
 548             getter = cachedGetter;
 549         } else {
 550             getter = debug(
 551                 createGetter(
 552                     getLocalType(),
 553                     type,
 554                     primitiveGetter,
 555                     objectGetter,
 556                     INVALID_PROGRAM_POINT),




 204      * to the constructor, and the rest are created from those. Used e.g. by Nasgen classes
 205      *
 206      * @param key    the property key
 207      * @param flags  the property flags
 208      * @param slot   the property field number or spill slot
 209      * @param getter the property getter
 210      * @param setter the property setter or null if non writable, non configurable
 211      */
 212     private AccessorProperty(final String key, final int flags, final int slot, final MethodHandle getter, final MethodHandle setter) {
 213         super(key, flags | IS_BUILTIN | DUAL_FIELDS | (getter.type().returnType().isPrimitive() ? IS_NASGEN_PRIMITIVE : 0), slot);
 214         assert !isSpill();
 215 
 216         // we don't need to prep the setters these will never be invalidated as this is a nasgen
 217         // or known type getter/setter. No invalidations will take place
 218 
 219         final Class<?> getterType = getter.type().returnType();
 220         final Class<?> setterType = setter == null ? null : setter.type().parameterType(1);
 221 
 222         assert setterType == null || setterType == getterType;
 223 
 224         if (getterType == int.class) {
 225             primitiveGetter = MH.asType(getter, Lookup.GET_PRIMITIVE_TYPE);
 226             primitiveSetter = setter == null ? null : MH.asType(setter, Lookup.SET_PRIMITIVE_TYPE);
 227         } else if (getterType == double.class) {
 228             primitiveGetter = MH.asType(MH.filterReturnValue(getter, ObjectClassGenerator.PACK_DOUBLE), Lookup.GET_PRIMITIVE_TYPE);
 229             primitiveSetter = setter == null ? null : MH.asType(MH.filterArguments(setter, 1, ObjectClassGenerator.UNPACK_DOUBLE), Lookup.SET_PRIMITIVE_TYPE);
 230         } else {
 231             primitiveGetter = primitiveSetter = null;
 232         }
 233 
 234         assert primitiveGetter == null || primitiveGetter.type() == Lookup.GET_PRIMITIVE_TYPE : primitiveGetter + "!=" + Lookup.GET_PRIMITIVE_TYPE;
 235         assert primitiveSetter == null || primitiveSetter.type() == Lookup.SET_PRIMITIVE_TYPE : primitiveSetter;
 236 
 237         objectGetter  = getter.type() != Lookup.GET_OBJECT_TYPE ? MH.asType(getter, Lookup.GET_OBJECT_TYPE) : getter;
 238         objectSetter  = setter != null && setter.type() != Lookup.SET_OBJECT_TYPE ? MH.asType(setter, Lookup.SET_OBJECT_TYPE) : setter;
 239 
 240         setType(getterType);
 241     }
 242 
 243     /**
 244      * Normal ACCESS PROPERTY constructor given a structure class.


 384         return new AccessorProperty(this);
 385     }
 386 
 387     @Override
 388     public Property copy(final Class<?> newType) {
 389         return new AccessorProperty(this, newType);
 390     }
 391 
 392     @Override
 393     public int getIntValue(final ScriptObject self, final ScriptObject owner) {
 394         try {
 395             return (int)getGetter(int.class).invokeExact((Object)self);
 396         } catch (final Error | RuntimeException e) {
 397             throw e;
 398         } catch (final Throwable e) {
 399             throw new RuntimeException(e);
 400         }
 401      }
 402 
 403      @Override











 404      public double getDoubleValue(final ScriptObject self, final ScriptObject owner) {
 405         try {
 406             return (double)getGetter(double.class).invokeExact((Object)self);
 407         } catch (final Error | RuntimeException e) {
 408             throw e;
 409         } catch (final Throwable e) {
 410             throw new RuntimeException(e);
 411         }
 412     }
 413 
 414      @Override
 415      public Object getObjectValue(final ScriptObject self, final ScriptObject owner) {
 416         try {
 417             return getGetter(Object.class).invokeExact((Object)self);
 418         } catch (final Error | RuntimeException e) {
 419             throw e;
 420         } catch (final Throwable e) {
 421             throw new RuntimeException(e);
 422         }
 423     }


 425      /**
 426       * Invoke setter for this property with a value
 427       * @param self  owner
 428       * @param value value
 429       */
 430     protected final void invokeSetter(final ScriptObject self, final int value) {
 431         try {
 432             getSetter(int.class, self.getMap()).invokeExact((Object)self, value);
 433         } catch (final Error | RuntimeException e) {
 434             throw e;
 435         } catch (final Throwable e) {
 436             throw new RuntimeException(e);
 437         }
 438     }
 439 
 440     /**
 441      * Invoke setter for this property with a value
 442      * @param self  owner
 443      * @param value value
 444      */















 445     protected final void invokeSetter(final ScriptObject self, final double value) {
 446         try {
 447             getSetter(double.class, self.getMap()).invokeExact((Object)self, value);
 448         } catch (final Error | RuntimeException e) {
 449             throw e;
 450         } catch (final Throwable e) {
 451             throw new RuntimeException(e);
 452         }
 453     }
 454 
 455     /**
 456      * Invoke setter for this property with a value
 457      * @param self  owner
 458      * @param value value
 459      */
 460     protected final void invokeSetter(final ScriptObject self, final Object value) {
 461         try {
 462             getSetter(Object.class, self.getMap()).invokeExact((Object)self, value);
 463         } catch (final Error | RuntimeException e) {
 464             throw e;
 465         } catch (final Throwable e) {
 466             throw new RuntimeException(e);
 467         }
 468     }
 469 
 470     @Override
 471     public void setValue(final ScriptObject self, final ScriptObject owner, final int value, final boolean strict)  {
 472         assert isConfigurable() || isWritable() : getKey() + " is not writable or configurable";
 473         invokeSetter(self, value);
 474     }
 475 
 476     @Override






 477     public void setValue(final ScriptObject self, final ScriptObject owner, final double value, final boolean strict)  {
 478         assert isConfigurable() || isWritable() : getKey() + " is not writable or configurable";
 479         invokeSetter(self, value);
 480     }
 481 
 482     @Override
 483     public void setValue(final ScriptObject self, final ScriptObject owner, final Object value, final boolean strict)  {
 484         //this is sometimes used for bootstrapping, hence no assert. ugly.
 485         invokeSetter(self, value);
 486     }
 487 
 488     @Override
 489     void initMethodHandles(final Class<?> structure) {
 490         // sanity check for structure class
 491         if (!ScriptObject.class.isAssignableFrom(structure) || !StructureLoader.isStructureClass(structure.getName())) {
 492             throw new IllegalArgumentException();
 493         }
 494         // this method is overridden in SpillProperty
 495         assert !isSpill();
 496         initGetterSetter(structure);
 497     }
 498 
 499     @Override
 500     public MethodHandle getGetter(final Class<?> type) {
 501         final int i = getAccessorTypeIndex(type);
 502 
 503         assert type == int.class ||

 504                 type == double.class ||
 505                 type == Object.class :
 506                 "invalid getter type " + type + " for " + getKey();
 507 
 508         checkUndeclared();
 509 
 510         //all this does is add a return value filter for object fields only
 511         final MethodHandle[] getterCache = GETTER_CACHE;
 512         final MethodHandle cachedGetter = getterCache[i];
 513         final MethodHandle getter;
 514         if (cachedGetter != null) {
 515             getter = cachedGetter;
 516         } else {
 517             getter = debug(
 518                 createGetter(
 519                     getLocalType(),
 520                     type,
 521                     primitiveGetter,
 522                     objectGetter,
 523                     INVALID_PROGRAM_POINT),


< prev index next >