nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/Global.java
changeset 36023 528cc67f1289
parent 35794 049749629dbe
child 36479 560761a8e879
equal deleted inserted replaced
35814:6c644cca3f3f 36023:528cc67f1289
    93     // This special value is used to flag a lazily initialized global property.
    93     // This special value is used to flag a lazily initialized global property.
    94     // This also serves as placeholder value used in place of a location property
    94     // This also serves as placeholder value used in place of a location property
    95     // (__FILE__, __DIR__, __LINE__)
    95     // (__FILE__, __DIR__, __LINE__)
    96     private static final Object LAZY_SENTINEL = new Object();
    96     private static final Object LAZY_SENTINEL = new Object();
    97 
    97 
       
    98     private static final String PACKAGE_PREFIX = "jdk.nashorn.internal.objects.";
       
    99 
    98     private InvokeByName TO_STRING;
   100     private InvokeByName TO_STRING;
    99     private InvokeByName VALUE_OF;
   101     private InvokeByName VALUE_OF;
   100 
   102 
   101     /**
   103     /**
   102      * Optimistic builtin names that require switchpoint invalidation
   104      * Optimistic builtin names that require switchpoint invalidation
   220 
   222 
   221     /** ECMA 15.1.4.6 - Number constructor */
   223     /** ECMA 15.1.4.6 - Number constructor */
   222     @Property(name = "Number", attributes = Attribute.NOT_ENUMERABLE)
   224     @Property(name = "Number", attributes = Attribute.NOT_ENUMERABLE)
   223     public volatile Object number;
   225     public volatile Object number;
   224 
   226 
   225     /** ECMA 2016 19.4.1 - Symbol constructor */
       
   226     @Property(name = "Symbol", attributes = Attribute.NOT_ENUMERABLE)
       
   227     public volatile Object symbol;
       
   228 
   227 
   229     /**
   228     /**
   230      * Getter for ECMA 15.1.4.7 Date property
   229      * Getter for ECMA 15.1.4.7 Date property
   231      *
   230      *
   232      * @param self self reference
   231      * @param self self reference
   745         final Global global = Global.instanceFrom(self);
   744         final Global global = Global.instanceFrom(self);
   746         global.float64Array = value;
   745         global.float64Array = value;
   747     }
   746     }
   748 
   747 
   749     private volatile Object float64Array;
   748     private volatile Object float64Array;
       
   749 
       
   750 
       
   751     /**
       
   752      * Getter for the Symbol property.
       
   753      *
       
   754      * @param self self reference
       
   755      * @return  the value of the Symbol property
       
   756      */
       
   757     @Getter(name = "Symbol", attributes = Attribute.NOT_ENUMERABLE)
       
   758     public static Object getSymbol(final Object self) {
       
   759         final Global global = Global.instanceFrom(self);
       
   760         if (global.symbol == LAZY_SENTINEL) {
       
   761             global.symbol = global.getBuiltinSymbol();
       
   762         }
       
   763         return global.symbol;
       
   764     }
       
   765 
       
   766     /**
       
   767      * Setter for the Symbol property.
       
   768      *
       
   769      * @param self self reference
       
   770      * @param value value of the Symbol property
       
   771      */
       
   772     @Setter(name = "Symbol", attributes = Attribute.NOT_ENUMERABLE)
       
   773     public static void setSymbol(final Object self, final Object value) {
       
   774         Global.instanceFrom(self).symbol = value;
       
   775     }
       
   776 
       
   777     private volatile Object symbol;
       
   778 
       
   779     /**
       
   780      * Getter for the Map property.
       
   781      *
       
   782      * @param self self reference
       
   783      * @return  the value of the Map property
       
   784      */
       
   785     @Getter(name = "Map", attributes = Attribute.NOT_ENUMERABLE)
       
   786     public static Object getMap(final Object self) {
       
   787         final Global global = Global.instanceFrom(self);
       
   788         if (global.map == LAZY_SENTINEL) {
       
   789             global.map = global.getBuiltinMap();
       
   790         }
       
   791         return global.map;
       
   792     }
       
   793 
       
   794     /**
       
   795      * Setter for the Map property.
       
   796      *
       
   797      * @param self self reference
       
   798      * @param value value of the Map property
       
   799      */
       
   800     @Setter(name = "Map", attributes = Attribute.NOT_ENUMERABLE)
       
   801     public static void setMap(final Object self, final Object value) {
       
   802         Global.instanceFrom(self).map = value;
       
   803     }
       
   804 
       
   805     private volatile Object map;
       
   806 
       
   807     /**
       
   808      * Getter for the WeakMap property.
       
   809      *
       
   810      * @param self self reference
       
   811      * @return  the value of the WeakMap property
       
   812      */
       
   813     @Getter(name = "WeakMap", attributes = Attribute.NOT_ENUMERABLE)
       
   814     public static Object getWeakMap(final Object self) {
       
   815         final Global global = Global.instanceFrom(self);
       
   816         if (global.weakMap == LAZY_SENTINEL) {
       
   817             global.weakMap = global.getBuiltinWeakMap();
       
   818         }
       
   819         return global.weakMap;
       
   820     }
       
   821 
       
   822     /**
       
   823      * Setter for the WeakMap property.
       
   824      *
       
   825      * @param self self reference
       
   826      * @param value value of the WeakMap property
       
   827      */
       
   828     @Setter(name = "WeakMap", attributes = Attribute.NOT_ENUMERABLE)
       
   829     public static void setWeakMap(final Object self, final Object value) {
       
   830         Global.instanceFrom(self).weakMap = value;
       
   831     }
       
   832 
       
   833     private volatile Object weakMap;
       
   834 
       
   835     /**
       
   836      * Getter for the Set property.
       
   837      *
       
   838      * @param self self reference
       
   839      * @return  the value of the Set property
       
   840      */
       
   841     @Getter(name = "Set", attributes = Attribute.NOT_ENUMERABLE)
       
   842     public static Object getSet(final Object self) {
       
   843         final Global global = Global.instanceFrom(self);
       
   844         if (global.set == LAZY_SENTINEL) {
       
   845             global.set = global.getBuiltinSet();
       
   846         }
       
   847         return global.set;
       
   848     }
       
   849 
       
   850     /**
       
   851      * Setter for the Set property.
       
   852      *
       
   853      * @param self self reference
       
   854      * @param value value of the Set property
       
   855      */
       
   856     @Setter(name = "Set", attributes = Attribute.NOT_ENUMERABLE)
       
   857     public static void setSet(final Object self, final Object value) {
       
   858         Global.instanceFrom(self).set = value;
       
   859     }
       
   860 
       
   861     private volatile Object set;
       
   862 
       
   863     /**
       
   864      * Getter for the WeakSet property.
       
   865      *
       
   866      * @param self self reference
       
   867      * @return  the value of the WeakSet property
       
   868      */
       
   869     @Getter(name = "WeakSet", attributes = Attribute.NOT_ENUMERABLE)
       
   870     public static Object getWeakSet(final Object self) {
       
   871         final Global global = Global.instanceFrom(self);
       
   872         if (global.weakSet == LAZY_SENTINEL) {
       
   873             global.weakSet = global.getBuiltinWeakSet();
       
   874         }
       
   875         return global.weakSet;
       
   876     }
       
   877 
       
   878     /**
       
   879      * Setter for the WeakSet property.
       
   880      *
       
   881      * @param self self reference
       
   882      * @param value value of the WeakSet property
       
   883      */
       
   884     @Setter(name = "WeakSet", attributes = Attribute.NOT_ENUMERABLE)
       
   885     public static void setWeakSet(final Object self, final Object value) {
       
   886         Global.instanceFrom(self).weakSet = value;
       
   887     }
       
   888 
       
   889     private volatile Object weakSet;
   750 
   890 
   751     /** Nashorn extension: Java access - global.Packages */
   891     /** Nashorn extension: Java access - global.Packages */
   752     @Property(name = "Packages", attributes = Attribute.NOT_ENUMERABLE)
   892     @Property(name = "Packages", attributes = Attribute.NOT_ENUMERABLE)
   753     public volatile Object packages;
   893     public volatile Object packages;
   754 
   894 
   905     private ScriptFunction builtinInt32Array;
  1045     private ScriptFunction builtinInt32Array;
   906     private ScriptFunction builtinUint32Array;
  1046     private ScriptFunction builtinUint32Array;
   907     private ScriptFunction builtinFloat32Array;
  1047     private ScriptFunction builtinFloat32Array;
   908     private ScriptFunction builtinFloat64Array;
  1048     private ScriptFunction builtinFloat64Array;
   909     private ScriptFunction builtinSymbol;
  1049     private ScriptFunction builtinSymbol;
       
  1050     private ScriptFunction builtinMap;
       
  1051     private ScriptFunction builtinWeakMap;
       
  1052     private ScriptFunction builtinSet;
       
  1053     private ScriptFunction builtinWeakSet;
       
  1054     private ScriptObject   builtinIteratorPrototype;
       
  1055     private ScriptObject   builtinMapIteratorPrototype;
       
  1056     private ScriptObject   builtinSetIteratorPrototype;
       
  1057     private ScriptObject   builtinArrayIteratorPrototype;
       
  1058     private ScriptObject   builtinStringIteratorPrototype;
   910 
  1059 
   911     /*
  1060     /*
   912      * ECMA section 13.2.3 The [[ThrowTypeError]] Function Object
  1061      * ECMA section 13.2.3 The [[ThrowTypeError]] Function Object
   913      */
  1062      */
   914     private ScriptFunction typeErrorThrower;
  1063     private ScriptFunction typeErrorThrower;
  1671     ScriptObject getJSAdapterPrototype() {
  1820     ScriptObject getJSAdapterPrototype() {
  1672         return ScriptFunction.getPrototype(getBuiltinJSAdapter());
  1821         return ScriptFunction.getPrototype(getBuiltinJSAdapter());
  1673     }
  1822     }
  1674 
  1823 
  1675     ScriptObject getSymbolPrototype() {
  1824     ScriptObject getSymbolPrototype() {
  1676         return ScriptFunction.getPrototype(builtinSymbol);
  1825         return ScriptFunction.getPrototype(getBuiltinSymbol());
       
  1826     }
       
  1827 
       
  1828     ScriptObject getMapPrototype() {
       
  1829         return ScriptFunction.getPrototype(getBuiltinMap());
       
  1830     }
       
  1831 
       
  1832     ScriptObject getWeakMapPrototype() {
       
  1833         return ScriptFunction.getPrototype(getBuiltinWeakMap());
       
  1834     }
       
  1835 
       
  1836     ScriptObject getSetPrototype() {
       
  1837         return ScriptFunction.getPrototype(getBuiltinSet());
       
  1838     }
       
  1839 
       
  1840     ScriptObject getWeakSetPrototype() {
       
  1841         return ScriptFunction.getPrototype(getBuiltinWeakSet());
       
  1842     }
       
  1843 
       
  1844     ScriptObject getIteratorPrototype() {
       
  1845         if (builtinIteratorPrototype == null) {
       
  1846             builtinIteratorPrototype = initPrototype("AbstractIterator", getObjectPrototype());
       
  1847         }
       
  1848         return builtinIteratorPrototype;
       
  1849     }
       
  1850 
       
  1851     ScriptObject getMapIteratorPrototype() {
       
  1852         if (builtinMapIteratorPrototype == null) {
       
  1853             builtinMapIteratorPrototype = initPrototype("MapIterator", getIteratorPrototype());
       
  1854         }
       
  1855         return builtinMapIteratorPrototype;
       
  1856     }
       
  1857 
       
  1858     ScriptObject getSetIteratorPrototype() {
       
  1859         if (builtinSetIteratorPrototype == null) {
       
  1860             builtinSetIteratorPrototype = initPrototype("SetIterator", getIteratorPrototype());
       
  1861         }
       
  1862         return builtinSetIteratorPrototype;
       
  1863     }
       
  1864 
       
  1865     ScriptObject getArrayIteratorPrototype() {
       
  1866         if (builtinArrayIteratorPrototype == null) {
       
  1867             builtinArrayIteratorPrototype = initPrototype("ArrayIterator", getIteratorPrototype());
       
  1868         }
       
  1869         return builtinArrayIteratorPrototype;
       
  1870     }
       
  1871 
       
  1872     ScriptObject getStringIteratorPrototype() {
       
  1873         if (builtinStringIteratorPrototype == null) {
       
  1874             builtinStringIteratorPrototype = initPrototype("StringIterator", getIteratorPrototype());
       
  1875         }
       
  1876         return builtinStringIteratorPrototype;
  1677     }
  1877     }
  1678 
  1878 
  1679     private synchronized ScriptFunction getBuiltinArrayBuffer() {
  1879     private synchronized ScriptFunction getBuiltinArrayBuffer() {
  1680         if (this.builtinArrayBuffer == null) {
  1880         if (this.builtinArrayBuffer == null) {
  1681             this.builtinArrayBuffer = initConstructorAndSwitchPoint("ArrayBuffer", ScriptFunction.class);
  1881             this.builtinArrayBuffer = initConstructorAndSwitchPoint("ArrayBuffer", ScriptFunction.class);
  1912     private synchronized ScriptFunction getBuiltinURIError() {
  2112     private synchronized ScriptFunction getBuiltinURIError() {
  1913         if (this.builtinURIError == null) {
  2113         if (this.builtinURIError == null) {
  1914             this.builtinURIError = initErrorSubtype("URIError", getErrorPrototype());
  2114             this.builtinURIError = initErrorSubtype("URIError", getErrorPrototype());
  1915         }
  2115         }
  1916         return this.builtinURIError;
  2116         return this.builtinURIError;
       
  2117     }
       
  2118 
       
  2119     private synchronized ScriptFunction getBuiltinSymbol() {
       
  2120         if (this.builtinSymbol == null) {
       
  2121             this.builtinSymbol = initConstructorAndSwitchPoint("Symbol", ScriptFunction.class);
       
  2122         }
       
  2123         return this.builtinSymbol;
       
  2124     }
       
  2125 
       
  2126     private synchronized ScriptFunction getBuiltinMap() {
       
  2127         if (this.builtinMap == null) {
       
  2128             this.builtinMap = initConstructorAndSwitchPoint("Map", ScriptFunction.class);
       
  2129         }
       
  2130         return this.builtinMap;
       
  2131     }
       
  2132 
       
  2133     private synchronized ScriptFunction getBuiltinWeakMap() {
       
  2134         if (this.builtinWeakMap == null) {
       
  2135             this.builtinWeakMap = initConstructorAndSwitchPoint("WeakMap", ScriptFunction.class);
       
  2136         }
       
  2137         return this.builtinWeakMap;
       
  2138     }
       
  2139 
       
  2140     private synchronized ScriptFunction getBuiltinSet() {
       
  2141         if (this.builtinSet == null) {
       
  2142             this.builtinSet = initConstructorAndSwitchPoint("Set", ScriptFunction.class);
       
  2143         }
       
  2144         return this.builtinSet;
       
  2145     }
       
  2146 
       
  2147     private synchronized ScriptFunction getBuiltinWeakSet() {
       
  2148         if (this.builtinWeakSet == null) {
       
  2149             this.builtinWeakSet = initConstructorAndSwitchPoint("WeakSet", ScriptFunction.class);
       
  2150         }
       
  2151         return this.builtinWeakSet;
  1917     }
  2152     }
  1918 
  2153 
  1919     @Override
  2154     @Override
  1920     public String getClassName() {
  2155     public String getClassName() {
  1921         return "global";
  2156         return "global";
  2309         this.builtinBoolean   = initConstructorAndSwitchPoint("Boolean", ScriptFunction.class);
  2544         this.builtinBoolean   = initConstructorAndSwitchPoint("Boolean", ScriptFunction.class);
  2310         this.builtinNumber    = initConstructorAndSwitchPoint("Number", ScriptFunction.class);
  2545         this.builtinNumber    = initConstructorAndSwitchPoint("Number", ScriptFunction.class);
  2311         this.builtinString    = initConstructorAndSwitchPoint("String", ScriptFunction.class);
  2546         this.builtinString    = initConstructorAndSwitchPoint("String", ScriptFunction.class);
  2312         this.builtinMath      = initConstructorAndSwitchPoint("Math", ScriptObject.class);
  2547         this.builtinMath      = initConstructorAndSwitchPoint("Math", ScriptObject.class);
  2313 
  2548 
  2314         if (env._es6) {
       
  2315             this.builtinSymbol = initConstructorAndSwitchPoint("Symbol", ScriptFunction.class);
       
  2316         } else {
       
  2317             // We need to manually delete nasgen-generated properties we don't want
       
  2318             this.delete("Symbol", false);
       
  2319             this.builtinObject.delete("getOwnPropertySymbols", false);
       
  2320         }
       
  2321 
       
  2322         // initialize String.prototype.length to 0
  2549         // initialize String.prototype.length to 0
  2323         // add String.prototype.length
  2550         // add String.prototype.length
  2324         final ScriptObject stringPrototype = getStringPrototype();
  2551         final ScriptObject stringPrototype = getStringPrototype();
  2325         stringPrototype.addOwnProperty("length", Attribute.NON_ENUMERABLE_CONSTANT, 0.0);
  2552         stringPrototype.addOwnProperty("length", Attribute.NON_ENUMERABLE_CONSTANT, 0.0);
  2326 
  2553 
  2327         // set isArray flag on Array.prototype
  2554         // set isArray flag on Array.prototype
  2328         final ScriptObject arrayPrototype = getArrayPrototype();
  2555         final ScriptObject arrayPrototype = getArrayPrototype();
  2329         arrayPrototype.setIsArray();
  2556         arrayPrototype.setIsArray();
       
  2557 
       
  2558         if (env._es6) {
       
  2559             this.symbol   = LAZY_SENTINEL;
       
  2560             this.map      = LAZY_SENTINEL;
       
  2561             this.weakMap  = LAZY_SENTINEL;
       
  2562             this.set      = LAZY_SENTINEL;
       
  2563             this.weakSet  = LAZY_SENTINEL;
       
  2564         } else {
       
  2565             // We need to manually delete nasgen-generated properties we don't want
       
  2566             this.delete("Symbol", false);
       
  2567             this.delete("Map", false);
       
  2568             this.delete("WeakMap", false);
       
  2569             this.delete("Set", false);
       
  2570             this.delete("WeakSet", false);
       
  2571             builtinObject.delete("getOwnPropertySymbols", false);
       
  2572             arrayPrototype.delete("entries", false);
       
  2573             arrayPrototype.delete("keys", false);
       
  2574             arrayPrototype.delete("values", false);
       
  2575         }
  2330 
  2576 
  2331         // Error stuff
  2577         // Error stuff
  2332         initErrorObjects();
  2578         initErrorObjects();
  2333 
  2579 
  2334         // java access
  2580         // java access
  2520         this.packages          = this.builtinPackages;
  2766         this.packages          = this.builtinPackages;
  2521         this.referenceError    = this.builtinReferenceError;
  2767         this.referenceError    = this.builtinReferenceError;
  2522         this.string            = this.builtinString;
  2768         this.string            = this.builtinString;
  2523         this.syntaxError       = this.builtinSyntaxError;
  2769         this.syntaxError       = this.builtinSyntaxError;
  2524         this.typeError         = this.builtinTypeError;
  2770         this.typeError         = this.builtinTypeError;
  2525         this.symbol            = this.builtinSymbol;
       
  2526     }
  2771     }
  2527 
  2772 
  2528     private void initDebug() {
  2773     private void initDebug() {
  2529         this.addOwnProperty("Debug", Attribute.NOT_ENUMERABLE, initConstructor("Debug", ScriptObject.class));
  2774         this.addOwnProperty("Debug", Attribute.NOT_ENUMERABLE, initConstructor("Debug", ScriptObject.class));
  2530     }
  2775     }
  2556     }
  2801     }
  2557 
  2802 
  2558     private <T extends ScriptObject> T initConstructor(final String name, final Class<T> clazz) {
  2803     private <T extends ScriptObject> T initConstructor(final String name, final Class<T> clazz) {
  2559         try {
  2804         try {
  2560             // Assuming class name pattern for built-in JS constructors.
  2805             // Assuming class name pattern for built-in JS constructors.
  2561             final StringBuilder sb = new StringBuilder("jdk.nashorn.internal.objects.");
  2806             final StringBuilder sb = new StringBuilder(PACKAGE_PREFIX);
  2562 
  2807 
  2563             sb.append("Native");
  2808             sb.append("Native");
  2564             sb.append(name);
  2809             sb.append(name);
  2565             sb.append("$Constructor");
  2810             sb.append("$Constructor");
  2566 
  2811 
  2578                 res.setInitialProto(getObjectPrototype());
  2823                 res.setInitialProto(getObjectPrototype());
  2579             }
  2824             }
  2580 
  2825 
  2581             res.setIsBuiltin();
  2826             res.setIsBuiltin();
  2582 
  2827 
       
  2828             return res;
       
  2829         } catch (final ClassNotFoundException | InstantiationException | IllegalAccessException e) {
       
  2830             throw new RuntimeException(e);
       
  2831         }
       
  2832     }
       
  2833 
       
  2834     private ScriptObject initPrototype(final String name, final ScriptObject prototype) {
       
  2835         try {
       
  2836             // Assuming class name pattern for JS prototypes
       
  2837             final String className = PACKAGE_PREFIX + name + "$Prototype";
       
  2838 
       
  2839             final Class<?> funcClass = Class.forName(className);
       
  2840             final ScriptObject res = (ScriptObject) funcClass.newInstance();
       
  2841 
       
  2842             res.setIsBuiltin();
       
  2843             res.setInitialProto(prototype);
  2583             return res;
  2844             return res;
  2584         } catch (final ClassNotFoundException | InstantiationException | IllegalAccessException e) {
  2845         } catch (final ClassNotFoundException | InstantiationException | IllegalAccessException e) {
  2585             throw new RuntimeException(e);
  2846             throw new RuntimeException(e);
  2586         }
  2847         }
  2587     }
  2848     }