src/jdk/nashorn/internal/objects/NativeString.java

Print this page
rev 755 : 8035948: Redesign property listeners for shared classes
Reviewed-by: sundar, lagergren
rev 758 : 8021350: Share script classes between threads/globals within context
Reviewed-by: lagergren, sundar
rev 760 : 8037400: Remove getInitialMap getters and GlobalObject interface
Reviewed-by: lagergren, jlaskey, attila


  15  * accompanied this code).
  16  *
  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.objects;
  27 
  28 import static jdk.nashorn.internal.lookup.Lookup.MH;
  29 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
  30 import static jdk.nashorn.internal.runtime.JSType.isRepresentableAsInt;
  31 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
  32 
  33 import java.lang.invoke.MethodHandle;
  34 import java.lang.invoke.MethodHandles;

  35 import java.text.Collator;
  36 import java.util.ArrayList;
  37 import java.util.Arrays;
  38 import java.util.LinkedList;
  39 import java.util.List;
  40 import java.util.Locale;
  41 import jdk.internal.dynalink.CallSiteDescriptor;
  42 import jdk.internal.dynalink.linker.GuardedInvocation;
  43 import jdk.internal.dynalink.linker.LinkRequest;
  44 import jdk.nashorn.internal.lookup.MethodHandleFactory.LookupException;
  45 import jdk.nashorn.internal.objects.annotations.Attribute;
  46 import jdk.nashorn.internal.objects.annotations.Constructor;
  47 import jdk.nashorn.internal.objects.annotations.Function;
  48 import jdk.nashorn.internal.objects.annotations.Getter;
  49 import jdk.nashorn.internal.objects.annotations.ScriptClass;
  50 import jdk.nashorn.internal.objects.annotations.SpecializedConstructor;
  51 import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
  52 import jdk.nashorn.internal.objects.annotations.Where;
  53 import jdk.nashorn.internal.runtime.ConsString;
  54 import jdk.nashorn.internal.runtime.JSType;
  55 import jdk.nashorn.internal.runtime.PropertyMap;
  56 import jdk.nashorn.internal.runtime.ScriptFunction;
  57 import jdk.nashorn.internal.runtime.ScriptObject;
  58 import jdk.nashorn.internal.runtime.ScriptRuntime;
  59 import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
  60 import jdk.nashorn.internal.runtime.linker.NashornGuards;
  61 import jdk.nashorn.internal.runtime.linker.PrimitiveLookup;
  62 
  63 
  64 /**
  65  * ECMA 15.5 String Objects.
  66  */
  67 @ScriptClass("String")
  68 public final class NativeString extends ScriptObject {
  69 
  70     private final CharSequence value;
  71 
  72     static final MethodHandle WRAPFILTER = findWrapFilter();



  73 
  74     // initialized by nasgen
  75     private static PropertyMap $nasgenmap$;
  76 
  77     static PropertyMap getInitialMap() {
  78         return $nasgenmap$;
  79     }
  80 
  81     private NativeString(final CharSequence value) {
  82         this(value, Global.instance());
  83     }
  84 
  85     NativeString(final CharSequence value, final Global global) {
  86         this(value, global.getStringPrototype(), global.getStringMap());
  87     }
  88 
  89     private NativeString(final CharSequence value, final ScriptObject proto, final PropertyMap map) {
  90         super(proto, map);
  91         assert value instanceof String || value instanceof ConsString;
  92         this.value = value;
  93     }
  94 
  95     @Override
  96     public String safeToString() {
  97         return "[String " + toString() + "]";
  98     }
  99 
 100     @Override
 101     public String toString() {
 102         return getStringValue();
 103     }
 104 
 105     @Override
 106     public boolean equals(final Object other) {


1182      * @param self   self reference
1183      * @param arg    the arg
1184      *
1185      * @return new NativeString containing the string representation of the arg
1186      */
1187     @SpecializedConstructor
1188     public static Object constructor(final boolean newObj, final Object self, final int arg) {
1189         final String str = JSType.toString(arg);
1190         return newObj ? newObj(self, str) : str;
1191     }
1192 
1193     /**
1194      * Lookup the appropriate method for an invoke dynamic call.
1195      *
1196      * @param request  the link request
1197      * @param receiver receiver of call
1198      * @return Link to be invoked at call site.
1199      */
1200     public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Object receiver) {
1201         final MethodHandle guard = NashornGuards.getInstanceOf2Guard(String.class, ConsString.class);
1202         return PrimitiveLookup.lookupPrimitive(request, guard, new NativeString((CharSequence)receiver), WRAPFILTER);
1203     }
1204 
1205     @SuppressWarnings("unused")
1206     private static NativeString wrapFilter(final Object receiver) {
1207         return new NativeString((CharSequence)receiver);
1208     }
1209 





1210     private static CharSequence getCharSequence(final Object self) {
1211         if (self instanceof String || self instanceof ConsString) {
1212             return (CharSequence)self;
1213         } else if (self instanceof NativeString) {
1214             return ((NativeString)self).getValue();
1215         } else if (self != null && self == Global.instance().getStringPrototype()) {
1216             return "";
1217         } else {
1218             throw typeError("not.a.string", ScriptRuntime.safeToString(self));
1219         }
1220     }
1221 
1222     private static String getString(final Object self) {
1223         if (self instanceof String) {
1224             return (String)self;
1225         } else if (self instanceof ConsString) {
1226             return self.toString();
1227         } else if (self instanceof NativeString) {
1228             return ((NativeString)self).getStringValue();
1229         } else if (self != null && self == Global.instance().getStringPrototype()) {


1237      * Combines ECMA 9.10 CheckObjectCoercible and ECMA 9.8 ToString with a shortcut for strings.
1238      *
1239      * @param self the object
1240      * @return the object as string
1241      */
1242     private static String checkObjectToString(final Object self) {
1243         if (self instanceof String) {
1244             return (String)self;
1245         } else if (self instanceof ConsString) {
1246             return self.toString();
1247         } else {
1248             Global.checkObjectCoercible(self);
1249             return JSType.toString(self);
1250         }
1251     }
1252 
1253     private boolean isValid(final int key) {
1254         return key >= 0 && key < value.length();
1255     }
1256 
1257     private static MethodHandle findWrapFilter() {
1258         return MH.findStatic(MethodHandles.lookup(), NativeString.class, "wrapFilter", MH.type(NativeString.class, Object.class));
1259     }
1260 }


  15  * accompanied this code).
  16  *
  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.objects;
  27 
  28 import static jdk.nashorn.internal.lookup.Lookup.MH;
  29 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
  30 import static jdk.nashorn.internal.runtime.JSType.isRepresentableAsInt;
  31 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
  32 
  33 import java.lang.invoke.MethodHandle;
  34 import java.lang.invoke.MethodHandles;
  35 import java.lang.invoke.MethodType;
  36 import java.text.Collator;
  37 import java.util.ArrayList;
  38 import java.util.Arrays;
  39 import java.util.LinkedList;
  40 import java.util.List;
  41 import java.util.Locale;
  42 import jdk.internal.dynalink.CallSiteDescriptor;
  43 import jdk.internal.dynalink.linker.GuardedInvocation;
  44 import jdk.internal.dynalink.linker.LinkRequest;
  45 import jdk.nashorn.internal.lookup.MethodHandleFactory.LookupException;
  46 import jdk.nashorn.internal.objects.annotations.Attribute;
  47 import jdk.nashorn.internal.objects.annotations.Constructor;
  48 import jdk.nashorn.internal.objects.annotations.Function;
  49 import jdk.nashorn.internal.objects.annotations.Getter;
  50 import jdk.nashorn.internal.objects.annotations.ScriptClass;
  51 import jdk.nashorn.internal.objects.annotations.SpecializedConstructor;
  52 import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
  53 import jdk.nashorn.internal.objects.annotations.Where;
  54 import jdk.nashorn.internal.runtime.ConsString;
  55 import jdk.nashorn.internal.runtime.JSType;
  56 import jdk.nashorn.internal.runtime.PropertyMap;
  57 import jdk.nashorn.internal.runtime.ScriptFunction;
  58 import jdk.nashorn.internal.runtime.ScriptObject;
  59 import jdk.nashorn.internal.runtime.ScriptRuntime;
  60 import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
  61 import jdk.nashorn.internal.runtime.linker.NashornGuards;
  62 import jdk.nashorn.internal.runtime.linker.PrimitiveLookup;
  63 
  64 
  65 /**
  66  * ECMA 15.5 String Objects.
  67  */
  68 @ScriptClass("String")
  69 public final class NativeString extends ScriptObject {
  70 
  71     private final CharSequence value;
  72 
  73     // Method handle to create an object wrapper for a primitive string
  74     private static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", MH.type(NativeString.class, Object.class));
  75     // Method handle to retrieve the String prototype object
  76     private static final MethodHandle PROTOFILTER = findOwnMH("protoFilter", MH.type(Object.class, Object.class));
  77 
  78     // initialized by nasgen
  79     private static PropertyMap $nasgenmap$;
  80 




  81     private NativeString(final CharSequence value) {
  82         this(value, Global.instance());
  83     }
  84 
  85     NativeString(final CharSequence value, final Global global) {
  86         this(value, global.getStringPrototype(), $nasgenmap$);
  87     }
  88 
  89     private NativeString(final CharSequence value, final ScriptObject proto, final PropertyMap map) {
  90         super(proto, map);
  91         assert value instanceof String || value instanceof ConsString;
  92         this.value = value;
  93     }
  94 
  95     @Override
  96     public String safeToString() {
  97         return "[String " + toString() + "]";
  98     }
  99 
 100     @Override
 101     public String toString() {
 102         return getStringValue();
 103     }
 104 
 105     @Override
 106     public boolean equals(final Object other) {


1182      * @param self   self reference
1183      * @param arg    the arg
1184      *
1185      * @return new NativeString containing the string representation of the arg
1186      */
1187     @SpecializedConstructor
1188     public static Object constructor(final boolean newObj, final Object self, final int arg) {
1189         final String str = JSType.toString(arg);
1190         return newObj ? newObj(self, str) : str;
1191     }
1192 
1193     /**
1194      * Lookup the appropriate method for an invoke dynamic call.
1195      *
1196      * @param request  the link request
1197      * @param receiver receiver of call
1198      * @return Link to be invoked at call site.
1199      */
1200     public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Object receiver) {
1201         final MethodHandle guard = NashornGuards.getInstanceOf2Guard(String.class, ConsString.class);
1202         return PrimitiveLookup.lookupPrimitive(request, guard, new NativeString((CharSequence)receiver), WRAPFILTER, PROTOFILTER);
1203     }
1204 
1205     @SuppressWarnings("unused")
1206     private static NativeString wrapFilter(final Object receiver) {
1207         return new NativeString((CharSequence)receiver);
1208     }
1209 
1210     @SuppressWarnings("unused")
1211     private static Object protoFilter(final Object object) {
1212         return Global.instance().getStringPrototype();
1213     }
1214 
1215     private static CharSequence getCharSequence(final Object self) {
1216         if (self instanceof String || self instanceof ConsString) {
1217             return (CharSequence)self;
1218         } else if (self instanceof NativeString) {
1219             return ((NativeString)self).getValue();
1220         } else if (self != null && self == Global.instance().getStringPrototype()) {
1221             return "";
1222         } else {
1223             throw typeError("not.a.string", ScriptRuntime.safeToString(self));
1224         }
1225     }
1226 
1227     private static String getString(final Object self) {
1228         if (self instanceof String) {
1229             return (String)self;
1230         } else if (self instanceof ConsString) {
1231             return self.toString();
1232         } else if (self instanceof NativeString) {
1233             return ((NativeString)self).getStringValue();
1234         } else if (self != null && self == Global.instance().getStringPrototype()) {


1242      * Combines ECMA 9.10 CheckObjectCoercible and ECMA 9.8 ToString with a shortcut for strings.
1243      *
1244      * @param self the object
1245      * @return the object as string
1246      */
1247     private static String checkObjectToString(final Object self) {
1248         if (self instanceof String) {
1249             return (String)self;
1250         } else if (self instanceof ConsString) {
1251             return self.toString();
1252         } else {
1253             Global.checkObjectCoercible(self);
1254             return JSType.toString(self);
1255         }
1256     }
1257 
1258     private boolean isValid(final int key) {
1259         return key >= 0 && key < value.length();
1260     }
1261 
1262     private static MethodHandle findOwnMH(final String name, final MethodType type) {
1263         return MH.findStatic(MethodHandles.lookup(), NativeString.class, name, type);
1264     }
1265 }