nashorn/src/jdk/nashorn/internal/objects/NativeString.java
changeset 24719 f726e9d67629
parent 21867 4e5ee0aeb468
child 24720 75f8388b79df
equal deleted inserted replaced
23083:8c74590d5df1 24719:f726e9d67629
   153         final Object self = request.getReceiver();
   153         final Object self = request.getReceiver();
   154         final Class<?> returnType = desc.getMethodType().returnType();
   154         final Class<?> returnType = desc.getMethodType().returnType();
   155 
   155 
   156         if (returnType == Object.class && (self instanceof String || self instanceof ConsString)) {
   156         if (returnType == Object.class && (self instanceof String || self instanceof ConsString)) {
   157             try {
   157             try {
   158                 MethodHandle mh = MH.findStatic(MethodHandles.lookup(), NativeString.class, "get", desc.getMethodType());
   158                 return new GuardedInvocation(MH.findStatic(MethodHandles.lookup(), NativeString.class, "get", desc.getMethodType()), NashornGuards.getInstanceOf2Guard(String.class, ConsString.class));
   159                 return new GuardedInvocation(mh, NashornGuards.getInstanceOf2Guard(String.class, ConsString.class));
       
   160             } catch (final LookupException e) {
   159             } catch (final LookupException e) {
   161                 // Shouldn't happen. Fall back to super
   160                 //empty. Shouldn't happen. Fall back to super
   162             }
   161             }
   163         }
   162         }
   164         return super.findGetIndexMethod(desc, request);
   163         return super.findGetIndexMethod(desc, request);
   165     }
   164     }
   166 
   165 
   234         }
   233         }
   235         return super.get(key);
   234         return super.get(key);
   236     }
   235     }
   237 
   236 
   238     @Override
   237     @Override
   239     public int getInt(final Object key) {
   238     public int getInt(final Object key, final int programPoint) {
   240         return JSType.toInt32(get(key));
   239         return JSType.toInt32MaybeOptimistic(get(key), programPoint);
   241     }
   240     }
   242 
   241 
   243     @Override
   242     @Override
   244     public int getInt(final double key) {
   243     public int getInt(final double key, final int programPoint) {
   245         return JSType.toInt32(get(key));
   244         return JSType.toInt32MaybeOptimistic(get(key), programPoint);
   246     }
   245     }
   247 
   246 
   248     @Override
   247     @Override
   249     public int getInt(final long key) {
   248     public int getInt(final long key, final int programPoint) {
   250         return JSType.toInt32(get(key));
   249         return JSType.toInt32MaybeOptimistic(get(key), programPoint);
   251     }
   250     }
   252 
   251 
   253     @Override
   252     @Override
   254     public int getInt(final int key) {
   253     public int getInt(final int key, final int programPoint) {
   255         return JSType.toInt32(get(key));
   254         return JSType.toInt32MaybeOptimistic(get(key), programPoint);
   256     }
   255     }
   257 
   256 
   258     @Override
   257     @Override
   259     public long getLong(final Object key) {
   258     public long getLong(final Object key, final int programPoint) {
   260         return JSType.toUint32(get(key));
   259         return JSType.toLongMaybeOptimistic(get(key), programPoint);
   261     }
   260     }
   262 
   261 
   263     @Override
   262     @Override
   264     public long getLong(final double key) {
   263     public long getLong(final double key, final int programPoint) {
   265         return JSType.toUint32(get(key));
   264         return JSType.toLongMaybeOptimistic(get(key), programPoint);
   266     }
   265     }
   267 
   266 
   268     @Override
   267     @Override
   269     public long getLong(final long key) {
   268     public long getLong(final long key, final int programPoint) {
   270         return JSType.toUint32(get(key));
   269         return JSType.toLongMaybeOptimistic(get(key), programPoint);
   271     }
   270     }
   272 
   271 
   273     @Override
   272     @Override
   274     public long getLong(final int key) {
   273     public long getLong(final int key, final int programPoint) {
   275         return JSType.toUint32(get(key));
   274         return JSType.toLongMaybeOptimistic(get(key), programPoint);
   276     }
   275     }
   277 
   276 
   278     @Override
   277     @Override
   279     public double getDouble(final Object key) {
   278     public double getDouble(final Object key, final int programPoint) {
   280         return JSType.toNumber(get(key));
   279         return JSType.toNumberMaybeOptimistic(get(key), programPoint);
   281     }
   280     }
   282 
   281 
   283     @Override
   282     @Override
   284     public double getDouble(final double key) {
   283     public double getDouble(final double key, final int programPoint) {
   285         return JSType.toNumber(get(key));
   284         return JSType.toNumberMaybeOptimistic(get(key), programPoint);
   286     }
   285     }
   287 
   286 
   288     @Override
   287     @Override
   289     public double getDouble(final long key) {
   288     public double getDouble(final long key, final int programPoint) {
   290         return JSType.toNumber(get(key));
   289         return JSType.toNumberMaybeOptimistic(get(key), programPoint);
   291     }
   290     }
   292 
   291 
   293     @Override
   292     @Override
   294     public double getDouble(final int key) {
   293     public double getDouble(final int key, final int programPoint) {
   295         return JSType.toNumber(get(key));
   294         return JSType.toNumberMaybeOptimistic(get(key), programPoint);
   296     }
   295     }
   297 
   296 
   298     @Override
   297     @Override
   299     public boolean has(final Object key) {
   298     public boolean has(final Object key) {
   300         final Object primitiveKey = JSType.toPrimitive(key, String.class);
   299         final Object primitiveKey = JSType.toPrimitive(key, String.class);
   301         final int index = ArrayIndex.getArrayIndex(primitiveKey);
   300         final int index = ArrayIndex.getArrayIndex(primitiveKey);
   302         return isValid(index) || super.has(primitiveKey);
   301         return isValidStringIndex(index) || super.has(primitiveKey);
   303     }
   302     }
   304 
   303 
   305     @Override
   304     @Override
   306     public boolean has(final int key) {
   305     public boolean has(final int key) {
   307         return isValid(key) || super.has(key);
   306         return isValidStringIndex(key) || super.has(key);
   308     }
   307     }
   309 
   308 
   310     @Override
   309     @Override
   311     public boolean has(final long key) {
   310     public boolean has(final long key) {
   312         final int index = ArrayIndex.getArrayIndex(key);
   311         final int index = ArrayIndex.getArrayIndex(key);
   313         return isValid(index) || super.has(key);
   312         return isValidStringIndex(index) || super.has(key);
   314     }
   313     }
   315 
   314 
   316     @Override
   315     @Override
   317     public boolean has(final double key) {
   316     public boolean has(final double key) {
   318         final int index = ArrayIndex.getArrayIndex(key);
   317         final int index = ArrayIndex.getArrayIndex(key);
   319         return isValid(index) || super.has(key);
   318         return isValidStringIndex(index) || super.has(key);
   320     }
   319     }
   321 
   320 
   322     @Override
   321     @Override
   323     public boolean hasOwnProperty(final Object key) {
   322     public boolean hasOwnProperty(final Object key) {
   324         final Object primitiveKey = JSType.toPrimitive(key, String.class);
   323         final Object primitiveKey = JSType.toPrimitive(key, String.class);
   325         final int index = ArrayIndex.getArrayIndex(primitiveKey);
   324         final int index = ArrayIndex.getArrayIndex(primitiveKey);
   326         return isValid(index) || super.hasOwnProperty(primitiveKey);
   325         return isValidStringIndex(index) || super.hasOwnProperty(primitiveKey);
   327     }
   326     }
   328 
   327 
   329     @Override
   328     @Override
   330     public boolean hasOwnProperty(final int key) {
   329     public boolean hasOwnProperty(final int key) {
   331         return isValid(key) || super.hasOwnProperty(key);
   330         return isValidStringIndex(key) || super.hasOwnProperty(key);
   332     }
   331     }
   333 
   332 
   334     @Override
   333     @Override
   335     public boolean hasOwnProperty(final long key) {
   334     public boolean hasOwnProperty(final long key) {
   336         final int index = ArrayIndex.getArrayIndex(key);
   335         final int index = ArrayIndex.getArrayIndex(key);
   337         return isValid(index) || super.hasOwnProperty(key);
   336         return isValidStringIndex(index) || super.hasOwnProperty(key);
   338     }
   337     }
   339 
   338 
   340     @Override
   339     @Override
   341     public boolean hasOwnProperty(final double key) {
   340     public boolean hasOwnProperty(final double key) {
   342         final int index = ArrayIndex.getArrayIndex(key);
   341         final int index = ArrayIndex.getArrayIndex(key);
   343         return isValid(index) || super.hasOwnProperty(key);
   342         return isValidStringIndex(index) || super.hasOwnProperty(key);
   344     }
   343     }
   345 
   344 
   346     @Override
   345     @Override
   347     public boolean delete(final int key, final boolean strict) {
   346     public boolean delete(final int key, final boolean strict) {
   348         return checkDeleteIndex(key, strict)? false : super.delete(key, strict);
   347         return checkDeleteIndex(key, strict)? false : super.delete(key, strict);
   366         final int index = ArrayIndex.getArrayIndex(primitiveKey);
   365         final int index = ArrayIndex.getArrayIndex(primitiveKey);
   367         return checkDeleteIndex(index, strict)? false : super.delete(primitiveKey, strict);
   366         return checkDeleteIndex(index, strict)? false : super.delete(primitiveKey, strict);
   368     }
   367     }
   369 
   368 
   370     private boolean checkDeleteIndex(final int index, final boolean strict) {
   369     private boolean checkDeleteIndex(final int index, final boolean strict) {
   371         if (isValid(index)) {
   370         if (isValidStringIndex(index)) {
   372             if (strict) {
   371             if (strict) {
   373                 throw typeError("cant.delete.property", Integer.toString(index), ScriptRuntime.safeToString(this));
   372                 throw typeError("cant.delete.property", Integer.toString(index), ScriptRuntime.safeToString(this));
   374             }
   373             }
   375             return true;
   374             return true;
   376         }
   375         }
   440      * @param value one argument to be interpreted as char
   439      * @param value one argument to be interpreted as char
   441      * @return string with one charcode
   440      * @return string with one charcode
   442      */
   441      */
   443     @SpecializedFunction
   442     @SpecializedFunction
   444     public static Object fromCharCode(final Object self, final Object value) {
   443     public static Object fromCharCode(final Object self, final Object value) {
   445         try {
   444         if (value instanceof Integer) {
   446             return "" + (char)JSType.toUint16(((Number)value).doubleValue());
   445             return fromCharCode(self, (int)value);
   447         } catch (final ClassCastException e) {
   446         } else if (value instanceof String) {
   448             return fromCharCode(self, new Object[] { value });
   447             return "" + (char)JSType.toUint16(value);
   449         }
   448         }
       
   449         return fromCharCode(self, new Object[] { value });
       
   450     }
       
   451 
       
   452     /**
       
   453      * fromCharCode specialization
       
   454      *
       
   455      * @param self  self reference
       
   456      * @param value one argument to be interpreted as char
       
   457      * @return string with one charcode
       
   458      */
       
   459     @SpecializedFunction
       
   460     public static Object fromCharCode(final Object self, final String value) {
       
   461         return fromCharCode(self, new Object[] { value });
   450     }
   462     }
   451 
   463 
   452     /**
   464     /**
   453      * ECMA 15.5.3.2 - specialization for one char of int type
   465      * ECMA 15.5.3.2 - specialization for one char of int type
   454      * @param self  self reference
   466      * @param self  self reference
   741      * ECMA 15.5.4.11 String.prototype.replace (searchValue, replaceValue)
   753      * ECMA 15.5.4.11 String.prototype.replace (searchValue, replaceValue)
   742      * @param self        self reference
   754      * @param self        self reference
   743      * @param string      item to replace
   755      * @param string      item to replace
   744      * @param replacement item to replace it with
   756      * @param replacement item to replace it with
   745      * @return string after replacement
   757      * @return string after replacement
   746      */
   758      * @throws Throwable if replacement fails
   747     @Function(attributes = Attribute.NOT_ENUMERABLE)
   759      */
   748     public static Object replace(final Object self, final Object string, final Object replacement) {
   760     @Function(attributes = Attribute.NOT_ENUMERABLE)
       
   761     public static Object replace(final Object self, final Object string, final Object replacement) throws Throwable {
   749 
   762 
   750         final String str = checkObjectToString(self);
   763         final String str = checkObjectToString(self);
   751 
   764 
   752         final NativeRegExp nativeRegExp;
   765         final NativeRegExp nativeRegExp;
   753         if (string instanceof NativeRegExp) {
   766         if (string instanceof NativeRegExp) {
  1184      *
  1197      *
  1185      * @return new NativeString containing the string representation of the arg
  1198      * @return new NativeString containing the string representation of the arg
  1186      */
  1199      */
  1187     @SpecializedConstructor
  1200     @SpecializedConstructor
  1188     public static Object constructor(final boolean newObj, final Object self, final int arg) {
  1201     public static Object constructor(final boolean newObj, final Object self, final int arg) {
       
  1202         final String str = JSType.toString(arg);
       
  1203         return newObj ? newObj(self, str) : str;
       
  1204     }
       
  1205 
       
  1206     /**
       
  1207      * ECMA 15.5.2.1 new String ( [ value ] ) - special version with exactly one {@code boolean} arg
       
  1208      *
       
  1209      * Constructor
       
  1210      *
       
  1211      * @param newObj is this constructor invoked with the new operator
       
  1212      * @param self   self reference
       
  1213      * @param arg    the arg
       
  1214      *
       
  1215      * @return new NativeString containing the string representation of the arg
       
  1216      */
       
  1217     @SpecializedConstructor
       
  1218     public static Object constructor(final boolean newObj, final Object self, final boolean arg) {
  1189         final String str = JSType.toString(arg);
  1219         final String str = JSType.toString(arg);
  1190         return newObj ? newObj(self, str) : str;
  1220         return newObj ? newObj(self, str) : str;
  1191     }
  1221     }
  1192 
  1222 
  1193     /**
  1223     /**
  1248             Global.checkObjectCoercible(self);
  1278             Global.checkObjectCoercible(self);
  1249             return JSType.toString(self);
  1279             return JSType.toString(self);
  1250         }
  1280         }
  1251     }
  1281     }
  1252 
  1282 
  1253     private boolean isValid(final int key) {
  1283     private boolean isValidStringIndex(final int key) {
  1254         return key >= 0 && key < value.length();
  1284         return key >= 0 && key < value.length();
  1255     }
  1285     }
  1256 
  1286 
  1257     private static MethodHandle findWrapFilter() {
  1287     private static MethodHandle findWrapFilter() {
  1258         return MH.findStatic(MethodHandles.lookup(), NativeString.class, "wrapFilter", MH.type(NativeString.class, Object.class));
  1288         return MH.findStatic(MethodHandles.lookup(), NativeString.class, "wrapFilter", MH.type(NativeString.class, Object.class));
  1259     }
  1289     }
       
  1290 
  1260 }
  1291 }