src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/Global.java

Print this page




  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.referenceError;
  30 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
  31 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
  32 
  33 import java.io.IOException;
  34 import java.io.PrintWriter;
  35 import java.lang.invoke.MethodHandle;
  36 import java.lang.invoke.MethodHandles;

  37 import java.lang.invoke.SwitchPoint;
  38 import java.lang.reflect.Field;
  39 import java.util.ArrayList;
  40 import java.util.Arrays;
  41 import java.util.List;
  42 import java.util.Map;
  43 import java.util.concurrent.Callable;
  44 import java.util.concurrent.ConcurrentHashMap;
  45 import javax.script.ScriptContext;
  46 import javax.script.ScriptEngine;

  47 import jdk.internal.dynalink.linker.GuardedInvocation;
  48 import jdk.internal.dynalink.linker.LinkRequest;
  49 import jdk.nashorn.api.scripting.ClassFilter;
  50 import jdk.nashorn.api.scripting.ScriptObjectMirror;
  51 import jdk.nashorn.internal.lookup.Lookup;
  52 import jdk.nashorn.internal.objects.annotations.Attribute;
  53 import jdk.nashorn.internal.objects.annotations.Property;
  54 import jdk.nashorn.internal.objects.annotations.ScriptClass;
  55 import jdk.nashorn.internal.runtime.ConsString;
  56 import jdk.nashorn.internal.runtime.Context;


  57 import jdk.nashorn.internal.runtime.GlobalFunctions;
  58 import jdk.nashorn.internal.runtime.JSType;
  59 import jdk.nashorn.internal.runtime.NativeJavaPackage;
  60 import jdk.nashorn.internal.runtime.PropertyDescriptor;
  61 import jdk.nashorn.internal.runtime.PropertyMap;
  62 import jdk.nashorn.internal.runtime.Scope;
  63 import jdk.nashorn.internal.runtime.ScriptEnvironment;
  64 import jdk.nashorn.internal.runtime.ScriptFunction;
  65 import jdk.nashorn.internal.runtime.ScriptObject;
  66 import jdk.nashorn.internal.runtime.ScriptRuntime;
  67 import jdk.nashorn.internal.runtime.ScriptingFunctions;
  68 import jdk.nashorn.internal.runtime.Specialization;
  69 import jdk.nashorn.internal.runtime.arrays.ArrayData;
  70 import jdk.nashorn.internal.runtime.linker.Bootstrap;
  71 import jdk.nashorn.internal.runtime.linker.InvokeByName;

  72 import jdk.nashorn.internal.runtime.regexp.RegExpResult;
  73 import jdk.nashorn.internal.scripts.JO;
  74 
  75 /**
  76  * Representation of global scope.
  77  */
  78 @ScriptClass("Global")
  79 public final class Global extends ScriptObject implements Scope {
  80     // Placeholder value used in place of a location property (__FILE__, __DIR__, __LINE__)
  81     private static final Object LOCATION_PROPERTY_PLACEHOLDER = new Object();
  82     private final InvokeByName TO_STRING = new InvokeByName("toString", ScriptObject.class);
  83     private final InvokeByName VALUE_OF  = new InvokeByName("valueOf",  ScriptObject.class);
  84 
  85     /**
  86      * Optimistic builtin names that require switchpoint invalidation
  87      * upon assignment. Overly conservative, but works for now, to avoid
  88      * any complicated scope checks and especially heavy weight guards
  89      * like
  90      *
  91      * <pre>


 398     private ScriptFunction builtinUint32Array;
 399     private ScriptFunction builtinFloat32Array;
 400     private ScriptFunction builtinFloat64Array;
 401 
 402     /*
 403      * ECMA section 13.2.3 The [[ThrowTypeError]] Function Object
 404      */
 405     private ScriptFunction typeErrorThrower;
 406 
 407     // Flag to indicate that a split method issued a return statement
 408     private int splitState = -1;
 409 
 410     // Used to store the last RegExp result to support deprecated RegExp constructor properties
 411     private RegExpResult lastRegExpResult;
 412 
 413     private static final MethodHandle EVAL              = findOwnMH_S("eval",                Object.class, Object.class, Object.class);
 414     private static final MethodHandle NO_SUCH_PROPERTY  = findOwnMH_S(NO_SUCH_PROPERTY_NAME, Object.class, Object.class, Object.class);
 415     private static final MethodHandle PRINT             = findOwnMH_S("print",               Object.class, Object.class, Object[].class);
 416     private static final MethodHandle PRINTLN           = findOwnMH_S("println",             Object.class, Object.class, Object[].class);
 417     private static final MethodHandle LOAD              = findOwnMH_S("load",                Object.class, Object.class, Object.class);
 418     private static final MethodHandle LOADWITHNEWGLOBAL = findOwnMH_S("loadWithNewGlobal",   Object.class, Object.class, Object[].class);
 419     private static final MethodHandle EXIT              = findOwnMH_S("exit",                Object.class, Object.class, Object.class);

 420 
 421     // initialized by nasgen
 422     private static PropertyMap $nasgenmap$;
 423 
 424     // context to which this global belongs to
 425     private final Context context;
 426 
 427     // current ScriptContext to use - can be null.
 428     private ScriptContext scontext;
 429     // current ScriptEngine associated - can be null.
 430     private ScriptEngine engine;
 431 






 432     /**
 433      * Set the current script context
 434      * @param scontext script context
 435      */
 436     public void setScriptContext(final ScriptContext scontext) {
 437         this.scontext = scontext;
 438     }
 439 
 440     @Override
 441     protected Context getContext() {
 442         return context;
 443     }
 444 
 445     // performs initialization checks for Global constructor and returns the
 446     // PropertyMap, if everything is fine.
 447     private static PropertyMap checkAndGetMap(final Context context) {
 448         // security check first
 449         final SecurityManager sm = System.getSecurityManager();
 450         if (sm != null) {
 451             sm.checkPermission(new RuntimePermission(Context.NASHORN_CREATE_GLOBAL));
 452         }
 453 
 454         // null check on context
 455         context.getClass();
 456 
 457         return $nasgenmap$;
 458     }
 459 
 460     /**
 461      * Constructor
 462      *
 463      * @param context the context
 464      */
 465     public Global(final Context context) {
 466         super(checkAndGetMap(context));
 467         this.context = context;
 468         this.setIsScope();

 469     }
 470 
 471     /**
 472      * Script access to "current" Global instance
 473      *
 474      * @return the global singleton
 475      */
 476     public static Global instance() {
 477         final Global global = Context.getGlobal();
 478         global.getClass(); // null check
 479         return global;
 480     }
 481 
 482     private static Global instanceFrom(final Object self) {
 483         return self instanceof Global? (Global)self : instance();
 484     }
 485 
 486     /**
 487      * Check if we have a Global instance
 488      * @return true if one exists


1676     /**
1677      * Get the current split state.
1678      *
1679      * @return current split state
1680      */
1681     @Override
1682     public int getSplitState() {
1683         return splitState;
1684     }
1685 
1686     /**
1687      * Set the current split state.
1688      *
1689      * @param state current split state
1690      */
1691     @Override
1692     public void setSplitState(final int state) {
1693         splitState = state;
1694     }
1695 































































































































1696     private <T extends ScriptObject> T initConstructorAndSwitchPoint(final String name, final Class<T> clazz) {
1697         final T func = initConstructor(name, clazz);
1698         tagBuiltinProperties(name, func);
1699         return func;
1700     }
1701 
1702     private void init(final ScriptEngine eng) {
1703         assert Context.getGlobal() == this : "this global is not set as current";
1704 
1705         final ScriptEnvironment env = getContext().getEnv();
1706 
1707         // initialize Function and Object constructor
1708         initFunctionAndObject();
1709 
1710         // Now fix Global's own proto.
1711         this.setInitialProto(getObjectPrototype());
1712 
1713         // initialize global function properties
1714         this.eval = this.builtinEval = ScriptFunctionImpl.makeFunction("eval", EVAL);
1715 


1720                     new Specialization(GlobalFunctions.PARSEINT_J),
1721                     new Specialization(GlobalFunctions.PARSEINT_OI),
1722                     new Specialization(GlobalFunctions.PARSEINT_O) });
1723         this.parseFloat = ScriptFunctionImpl.makeFunction("parseFloat", GlobalFunctions.PARSEFLOAT);
1724         this.isNaN = ScriptFunctionImpl.makeFunction("isNaN",   GlobalFunctions.IS_NAN,
1725                    new Specialization[] {
1726                         new Specialization(GlobalFunctions.IS_NAN_I),
1727                         new Specialization(GlobalFunctions.IS_NAN_J),
1728                         new Specialization(GlobalFunctions.IS_NAN_D) });
1729         this.parseFloat         = ScriptFunctionImpl.makeFunction("parseFloat", GlobalFunctions.PARSEFLOAT);
1730         this.isNaN              = ScriptFunctionImpl.makeFunction("isNaN",      GlobalFunctions.IS_NAN);
1731         this.isFinite           = ScriptFunctionImpl.makeFunction("isFinite",   GlobalFunctions.IS_FINITE);
1732         this.encodeURI          = ScriptFunctionImpl.makeFunction("encodeURI",  GlobalFunctions.ENCODE_URI);
1733         this.encodeURIComponent = ScriptFunctionImpl.makeFunction("encodeURIComponent", GlobalFunctions.ENCODE_URICOMPONENT);
1734         this.decodeURI          = ScriptFunctionImpl.makeFunction("decodeURI",  GlobalFunctions.DECODE_URI);
1735         this.decodeURIComponent = ScriptFunctionImpl.makeFunction("decodeURIComponent", GlobalFunctions.DECODE_URICOMPONENT);
1736         this.escape             = ScriptFunctionImpl.makeFunction("escape",     GlobalFunctions.ESCAPE);
1737         this.unescape           = ScriptFunctionImpl.makeFunction("unescape",   GlobalFunctions.UNESCAPE);
1738         this.print              = ScriptFunctionImpl.makeFunction("print",      env._print_no_newline ? PRINT : PRINTLN);
1739         this.load               = ScriptFunctionImpl.makeFunction("load",       LOAD);
1740         this.loadWithNewGlobal  = ScriptFunctionImpl.makeFunction("loadWithNewGlobal", LOADWITHNEWGLOBAL);
1741         this.exit               = ScriptFunctionImpl.makeFunction("exit",       EXIT);
1742         this.quit               = ScriptFunctionImpl.makeFunction("quit",       EXIT);
1743 
1744         // built-in constructors
1745         this.builtinArray     = initConstructorAndSwitchPoint("Array", ScriptFunction.class);
1746         this.builtinBoolean   = initConstructorAndSwitchPoint("Boolean", ScriptFunction.class);
1747         this.builtinDate      = initConstructorAndSwitchPoint("Date", ScriptFunction.class);
1748         this.builtinJSON      = initConstructorAndSwitchPoint("JSON", ScriptObject.class);
1749         this.builtinJSAdapter = initConstructorAndSwitchPoint("JSAdapter", ScriptFunction.class);
1750         this.builtinMath      = initConstructorAndSwitchPoint("Math", ScriptObject.class);
1751         this.builtinNumber    = initConstructorAndSwitchPoint("Number", ScriptFunction.class);
1752         this.builtinRegExp    = initConstructorAndSwitchPoint("RegExp", ScriptFunction.class);
1753         this.builtinString    = initConstructorAndSwitchPoint("String", ScriptFunction.class);
1754 
1755         // initialize String.prototype.length to 0
1756         // add String.prototype.length
1757         final ScriptObject stringPrototype = getStringPrototype();
1758         stringPrototype.addOwnProperty("length", Attribute.NON_ENUMERABLE_CONSTANT, 0.0);
1759 
1760         // set isArray flag on Array.prototype


2186         tagBuiltinProperties("Function", builtinFunction);
2187         tagBuiltinProperties("Function", anon);
2188     }
2189 
2190     private static MethodHandle findOwnMH_S(final String name, final Class<?> rtype, final Class<?>... types) {
2191         return MH.findStatic(MethodHandles.lookup(), Global.class, name, MH.type(rtype, types));
2192     }
2193 
2194     RegExpResult getLastRegExpResult() {
2195         return lastRegExpResult;
2196     }
2197 
2198     void setLastRegExpResult(final RegExpResult regExpResult) {
2199         this.lastRegExpResult = regExpResult;
2200     }
2201 
2202     @Override
2203     protected boolean isGlobal() {
2204         return true;
2205     }
































2206 }


  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.referenceError;
  30 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
  31 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
  32 
  33 import java.io.IOException;
  34 import java.io.PrintWriter;
  35 import java.lang.invoke.MethodHandle;
  36 import java.lang.invoke.MethodHandles;
  37 import java.lang.invoke.MethodType;
  38 import java.lang.invoke.SwitchPoint;
  39 import java.lang.reflect.Field;
  40 import java.util.ArrayList;
  41 import java.util.Arrays;
  42 import java.util.List;
  43 import java.util.Map;
  44 import java.util.concurrent.Callable;
  45 import java.util.concurrent.ConcurrentHashMap;
  46 import javax.script.ScriptContext;
  47 import javax.script.ScriptEngine;
  48 import jdk.internal.dynalink.CallSiteDescriptor;
  49 import jdk.internal.dynalink.linker.GuardedInvocation;
  50 import jdk.internal.dynalink.linker.LinkRequest;
  51 import jdk.nashorn.api.scripting.ClassFilter;
  52 import jdk.nashorn.api.scripting.ScriptObjectMirror;
  53 import jdk.nashorn.internal.lookup.Lookup;
  54 import jdk.nashorn.internal.objects.annotations.Attribute;
  55 import jdk.nashorn.internal.objects.annotations.Property;
  56 import jdk.nashorn.internal.objects.annotations.ScriptClass;
  57 import jdk.nashorn.internal.runtime.ConsString;
  58 import jdk.nashorn.internal.runtime.Context;
  59 import jdk.nashorn.internal.runtime.ECMAErrors;
  60 import jdk.nashorn.internal.runtime.GlobalConstants;
  61 import jdk.nashorn.internal.runtime.GlobalFunctions;
  62 import jdk.nashorn.internal.runtime.JSType;
  63 import jdk.nashorn.internal.runtime.NativeJavaPackage;
  64 import jdk.nashorn.internal.runtime.PropertyDescriptor;
  65 import jdk.nashorn.internal.runtime.PropertyMap;
  66 import jdk.nashorn.internal.runtime.Scope;
  67 import jdk.nashorn.internal.runtime.ScriptEnvironment;
  68 import jdk.nashorn.internal.runtime.ScriptFunction;
  69 import jdk.nashorn.internal.runtime.ScriptObject;
  70 import jdk.nashorn.internal.runtime.ScriptRuntime;
  71 import jdk.nashorn.internal.runtime.ScriptingFunctions;
  72 import jdk.nashorn.internal.runtime.Specialization;
  73 import jdk.nashorn.internal.runtime.arrays.ArrayData;
  74 import jdk.nashorn.internal.runtime.linker.Bootstrap;
  75 import jdk.nashorn.internal.runtime.linker.InvokeByName;
  76 import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
  77 import jdk.nashorn.internal.runtime.regexp.RegExpResult;
  78 import jdk.nashorn.internal.scripts.JO;
  79 
  80 /**
  81  * Representation of global scope.
  82  */
  83 @ScriptClass("Global")
  84 public final class Global extends ScriptObject implements Scope {
  85     // Placeholder value used in place of a location property (__FILE__, __DIR__, __LINE__)
  86     private static final Object LOCATION_PROPERTY_PLACEHOLDER = new Object();
  87     private final InvokeByName TO_STRING = new InvokeByName("toString", ScriptObject.class);
  88     private final InvokeByName VALUE_OF  = new InvokeByName("valueOf",  ScriptObject.class);
  89 
  90     /**
  91      * Optimistic builtin names that require switchpoint invalidation
  92      * upon assignment. Overly conservative, but works for now, to avoid
  93      * any complicated scope checks and especially heavy weight guards
  94      * like
  95      *
  96      * <pre>


 403     private ScriptFunction builtinUint32Array;
 404     private ScriptFunction builtinFloat32Array;
 405     private ScriptFunction builtinFloat64Array;
 406 
 407     /*
 408      * ECMA section 13.2.3 The [[ThrowTypeError]] Function Object
 409      */
 410     private ScriptFunction typeErrorThrower;
 411 
 412     // Flag to indicate that a split method issued a return statement
 413     private int splitState = -1;
 414 
 415     // Used to store the last RegExp result to support deprecated RegExp constructor properties
 416     private RegExpResult lastRegExpResult;
 417 
 418     private static final MethodHandle EVAL                 = findOwnMH_S("eval",                Object.class, Object.class, Object.class);
 419     private static final MethodHandle NO_SUCH_PROPERTY     = findOwnMH_S(NO_SUCH_PROPERTY_NAME, Object.class, Object.class, Object.class);
 420     private static final MethodHandle PRINT                = findOwnMH_S("print",               Object.class, Object.class, Object[].class);
 421     private static final MethodHandle PRINTLN              = findOwnMH_S("println",             Object.class, Object.class, Object[].class);
 422     private static final MethodHandle LOAD                 = findOwnMH_S("load",                Object.class, Object.class, Object.class);
 423     private static final MethodHandle LOAD_WITH_NEW_GLOBAL = findOwnMH_S("loadWithNewGlobal",   Object.class, Object.class, Object[].class);
 424     private static final MethodHandle EXIT                 = findOwnMH_S("exit",                Object.class, Object.class, Object.class);
 425     private static final MethodHandle LEXICAL_SCOPE_FILTER = findOwnMH_S("lexicalScopeFilter", Object.class, Object.class);
 426 
 427     // initialized by nasgen
 428     private static PropertyMap $nasgenmap$;
 429 
 430     // context to which this global belongs to
 431     private final Context context;
 432 
 433     // current ScriptContext to use - can be null.
 434     private ScriptContext scontext;
 435     // current ScriptEngine associated - can be null.
 436     private ScriptEngine engine;
 437 
 438     // ES6 global lexical scope.
 439     private final LexicalScope lexicalScope;
 440 
 441     // Switchpoint for non-constant global callsites in the presence of ES6 lexical scope.
 442     private SwitchPoint lexicalScopeSwitchPoint;
 443 
 444     /**
 445      * Set the current script context
 446      * @param scontext script context
 447      */
 448     public void setScriptContext(final ScriptContext scontext) {
 449         this.scontext = scontext;
 450     }
 451 
 452     @Override
 453     protected Context getContext() {
 454         return context;
 455     }
 456 
 457     // performs initialization checks for Global constructor and returns the
 458     // PropertyMap, if everything is fine.
 459     private static PropertyMap checkAndGetMap(final Context context) {
 460         // security check first
 461         final SecurityManager sm = System.getSecurityManager();
 462         if (sm != null) {
 463             sm.checkPermission(new RuntimePermission(Context.NASHORN_CREATE_GLOBAL));
 464         }
 465 
 466         // null check on context
 467         context.getClass();
 468 
 469         return $nasgenmap$;
 470     }
 471 
 472     /**
 473      * Constructor
 474      *
 475      * @param context the context
 476      */
 477     public Global(final Context context) {
 478         super(checkAndGetMap(context));
 479         this.context = context;
 480         this.setIsScope();
 481         this.lexicalScope = context.getEnv()._es6 ? new LexicalScope(this) : null;
 482     }
 483 
 484     /**
 485      * Script access to "current" Global instance
 486      *
 487      * @return the global singleton
 488      */
 489     public static Global instance() {
 490         final Global global = Context.getGlobal();
 491         global.getClass(); // null check
 492         return global;
 493     }
 494 
 495     private static Global instanceFrom(final Object self) {
 496         return self instanceof Global? (Global)self : instance();
 497     }
 498 
 499     /**
 500      * Check if we have a Global instance
 501      * @return true if one exists


1689     /**
1690      * Get the current split state.
1691      *
1692      * @return current split state
1693      */
1694     @Override
1695     public int getSplitState() {
1696         return splitState;
1697     }
1698 
1699     /**
1700      * Set the current split state.
1701      *
1702      * @param state current split state
1703      */
1704     @Override
1705     public void setSplitState(final int state) {
1706         splitState = state;
1707     }
1708 
1709     /**
1710      * Return the ES6 global scope for lexically declared bindings.
1711      * @return the ES6 lexical global scope.
1712      */
1713     public final ScriptObject getLexicalScope() {
1714         assert context.getEnv()._es6;
1715         return lexicalScope;
1716     }
1717 
1718     @Override
1719     public void addBoundProperties(final ScriptObject source, final jdk.nashorn.internal.runtime.Property[] properties) {
1720         PropertyMap ownMap = getMap();
1721         LexicalScope lexicalScope = null;
1722         PropertyMap lexicalMap = null;
1723         boolean hasLexicalDefinitions = false;
1724 
1725         if (context.getEnv()._es6) {
1726             lexicalScope = (LexicalScope) getLexicalScope();
1727             lexicalMap = lexicalScope.getMap();
1728 
1729             for (final jdk.nashorn.internal.runtime.Property property : properties) {
1730                 if (property.isLexicalBinding()) {
1731                     hasLexicalDefinitions = true;
1732                 }
1733                 // ES6 15.1.8 steps 6. and 7.
1734                 final jdk.nashorn.internal.runtime.Property globalProperty = ownMap.findProperty(property.getKey());
1735                 if (globalProperty != null && !globalProperty.isConfigurable() && property.isLexicalBinding()) {
1736                     throw ECMAErrors.syntaxError("redeclare.variable", property.getKey());
1737                 }
1738                 final jdk.nashorn.internal.runtime.Property lexicalProperty = lexicalMap.findProperty(property.getKey());
1739                 if (lexicalProperty != null && !property.isConfigurable()) {
1740                     throw ECMAErrors.syntaxError("redeclare.variable", property.getKey());
1741                 }
1742             }
1743         }
1744 
1745         for (final jdk.nashorn.internal.runtime.Property property : properties) {
1746             if (property.isLexicalBinding()) {
1747                 assert lexicalScope != null;
1748                 lexicalMap = lexicalScope.addBoundProperty(lexicalMap, source, property);
1749 
1750                 if (ownMap.findProperty(property.getKey()) != null) {
1751                     // If property exists in the global object invalidate any global constant call sites.
1752                     invalidateGlobalConstant(property.getKey());
1753                 }
1754             } else {
1755                 ownMap = addBoundProperty(ownMap, source, property);
1756             }
1757         }
1758 
1759         setMap(ownMap);
1760 
1761         if (hasLexicalDefinitions) {
1762             lexicalScope.setMap(lexicalMap);
1763             invalidateLexicalSwitchPoint();
1764         }
1765     }
1766 
1767     @Override
1768     public GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operator) {
1769         final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
1770         final boolean isScope = NashornCallSiteDescriptor.isScope(desc);
1771 
1772         if (lexicalScope != null && isScope && !NashornCallSiteDescriptor.isApplyToCall(desc)) {
1773             if (lexicalScope.hasOwnProperty(name)) {
1774                 return lexicalScope.findGetMethod(desc, request, operator);
1775             }
1776         }
1777 
1778         final GuardedInvocation invocation =  super.findGetMethod(desc, request, operator);
1779 
1780         // We want to avoid adding our generic lexical scope switchpoint to global constant invocations,
1781         // because those are invalidated per-key in the addBoundProperties method above.
1782         // We therefor check if the invocation does already have a switchpoint and the property is non-inherited,
1783         // assuming this only applies to global constants. If other non-inherited properties will
1784         // start using switchpoints some time in the future we'll have to revisit this.
1785         if (isScope && context.getEnv()._es6 && (invocation.getSwitchPoints() == null || !hasOwnProperty(name))) {
1786             return invocation.addSwitchPoint(getLexicalScopeSwitchPoint());
1787         }
1788 
1789         return invocation;
1790     }
1791 
1792     @Override
1793     public GuardedInvocation findSetMethod(final CallSiteDescriptor desc, final LinkRequest request) {
1794         final boolean isScope = NashornCallSiteDescriptor.isScope(desc);
1795 
1796         if (lexicalScope != null && isScope) {
1797             final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
1798             if (lexicalScope.hasOwnProperty(name)) {
1799                 return lexicalScope.findSetMethod(desc, request);
1800             }
1801         }
1802 
1803         final GuardedInvocation invocation = super.findSetMethod(desc, request);
1804 
1805         if (isScope && context.getEnv()._es6) {
1806             return invocation.addSwitchPoint(getLexicalScopeSwitchPoint());
1807         }
1808 
1809         return invocation;
1810     }
1811 
1812     private synchronized SwitchPoint getLexicalScopeSwitchPoint() {
1813         SwitchPoint switchPoint = lexicalScopeSwitchPoint;
1814         if (switchPoint == null || switchPoint.hasBeenInvalidated()) {
1815             switchPoint = lexicalScopeSwitchPoint = new SwitchPoint();
1816         }
1817         return switchPoint;
1818     }
1819 
1820     private synchronized void invalidateLexicalSwitchPoint() {
1821         if (lexicalScopeSwitchPoint != null) {
1822             context.getLogger(GlobalConstants.class).info("Invalidating non-constant globals on lexical scope update");
1823             SwitchPoint.invalidateAll(new SwitchPoint[]{ lexicalScopeSwitchPoint });
1824         }
1825     }
1826 
1827 
1828     @SuppressWarnings("unused")
1829     private static Object lexicalScopeFilter(final Object self) {
1830         if (self instanceof Global) {
1831             return ((Global) self).getLexicalScope();
1832         }
1833         return self;
1834     }
1835 
1836     private <T extends ScriptObject> T initConstructorAndSwitchPoint(final String name, final Class<T> clazz) {
1837         final T func = initConstructor(name, clazz);
1838         tagBuiltinProperties(name, func);
1839         return func;
1840     }
1841 
1842     private void init(final ScriptEngine eng) {
1843         assert Context.getGlobal() == this : "this global is not set as current";
1844 
1845         final ScriptEnvironment env = getContext().getEnv();
1846 
1847         // initialize Function and Object constructor
1848         initFunctionAndObject();
1849 
1850         // Now fix Global's own proto.
1851         this.setInitialProto(getObjectPrototype());
1852 
1853         // initialize global function properties
1854         this.eval = this.builtinEval = ScriptFunctionImpl.makeFunction("eval", EVAL);
1855 


1860                     new Specialization(GlobalFunctions.PARSEINT_J),
1861                     new Specialization(GlobalFunctions.PARSEINT_OI),
1862                     new Specialization(GlobalFunctions.PARSEINT_O) });
1863         this.parseFloat = ScriptFunctionImpl.makeFunction("parseFloat", GlobalFunctions.PARSEFLOAT);
1864         this.isNaN = ScriptFunctionImpl.makeFunction("isNaN",   GlobalFunctions.IS_NAN,
1865                    new Specialization[] {
1866                         new Specialization(GlobalFunctions.IS_NAN_I),
1867                         new Specialization(GlobalFunctions.IS_NAN_J),
1868                         new Specialization(GlobalFunctions.IS_NAN_D) });
1869         this.parseFloat         = ScriptFunctionImpl.makeFunction("parseFloat", GlobalFunctions.PARSEFLOAT);
1870         this.isNaN              = ScriptFunctionImpl.makeFunction("isNaN",      GlobalFunctions.IS_NAN);
1871         this.isFinite           = ScriptFunctionImpl.makeFunction("isFinite",   GlobalFunctions.IS_FINITE);
1872         this.encodeURI          = ScriptFunctionImpl.makeFunction("encodeURI",  GlobalFunctions.ENCODE_URI);
1873         this.encodeURIComponent = ScriptFunctionImpl.makeFunction("encodeURIComponent", GlobalFunctions.ENCODE_URICOMPONENT);
1874         this.decodeURI          = ScriptFunctionImpl.makeFunction("decodeURI",  GlobalFunctions.DECODE_URI);
1875         this.decodeURIComponent = ScriptFunctionImpl.makeFunction("decodeURIComponent", GlobalFunctions.DECODE_URICOMPONENT);
1876         this.escape             = ScriptFunctionImpl.makeFunction("escape",     GlobalFunctions.ESCAPE);
1877         this.unescape           = ScriptFunctionImpl.makeFunction("unescape",   GlobalFunctions.UNESCAPE);
1878         this.print              = ScriptFunctionImpl.makeFunction("print",      env._print_no_newline ? PRINT : PRINTLN);
1879         this.load               = ScriptFunctionImpl.makeFunction("load",       LOAD);
1880         this.loadWithNewGlobal  = ScriptFunctionImpl.makeFunction("loadWithNewGlobal", LOAD_WITH_NEW_GLOBAL);
1881         this.exit               = ScriptFunctionImpl.makeFunction("exit",       EXIT);
1882         this.quit               = ScriptFunctionImpl.makeFunction("quit",       EXIT);
1883 
1884         // built-in constructors
1885         this.builtinArray     = initConstructorAndSwitchPoint("Array", ScriptFunction.class);
1886         this.builtinBoolean   = initConstructorAndSwitchPoint("Boolean", ScriptFunction.class);
1887         this.builtinDate      = initConstructorAndSwitchPoint("Date", ScriptFunction.class);
1888         this.builtinJSON      = initConstructorAndSwitchPoint("JSON", ScriptObject.class);
1889         this.builtinJSAdapter = initConstructorAndSwitchPoint("JSAdapter", ScriptFunction.class);
1890         this.builtinMath      = initConstructorAndSwitchPoint("Math", ScriptObject.class);
1891         this.builtinNumber    = initConstructorAndSwitchPoint("Number", ScriptFunction.class);
1892         this.builtinRegExp    = initConstructorAndSwitchPoint("RegExp", ScriptFunction.class);
1893         this.builtinString    = initConstructorAndSwitchPoint("String", ScriptFunction.class);
1894 
1895         // initialize String.prototype.length to 0
1896         // add String.prototype.length
1897         final ScriptObject stringPrototype = getStringPrototype();
1898         stringPrototype.addOwnProperty("length", Attribute.NON_ENUMERABLE_CONSTANT, 0.0);
1899 
1900         // set isArray flag on Array.prototype


2326         tagBuiltinProperties("Function", builtinFunction);
2327         tagBuiltinProperties("Function", anon);
2328     }
2329 
2330     private static MethodHandle findOwnMH_S(final String name, final Class<?> rtype, final Class<?>... types) {
2331         return MH.findStatic(MethodHandles.lookup(), Global.class, name, MH.type(rtype, types));
2332     }
2333 
2334     RegExpResult getLastRegExpResult() {
2335         return lastRegExpResult;
2336     }
2337 
2338     void setLastRegExpResult(final RegExpResult regExpResult) {
2339         this.lastRegExpResult = regExpResult;
2340     }
2341 
2342     @Override
2343     protected boolean isGlobal() {
2344         return true;
2345     }
2346 
2347     /**
2348      * A class representing the ES6 global lexical scope.
2349      */
2350     private static class LexicalScope extends ScriptObject {
2351 
2352         LexicalScope(final ScriptObject proto) {
2353             super(proto, PropertyMap.newMap());
2354         }
2355 
2356         @Override
2357         protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operator) {
2358             return filterInvocation(super.findGetMethod(desc, request, operator));
2359         }
2360 
2361         @Override
2362         protected GuardedInvocation findSetMethod(final CallSiteDescriptor desc, final LinkRequest request) {
2363             return filterInvocation(super.findSetMethod(desc, request));
2364         }
2365 
2366         @Override
2367         protected PropertyMap addBoundProperty(final PropertyMap propMap, final ScriptObject source, final jdk.nashorn.internal.runtime.Property property) {
2368             // We override this method just to make it callable by Global
2369             return super.addBoundProperty(propMap, source, property);
2370         }
2371 
2372         private static GuardedInvocation filterInvocation(final GuardedInvocation invocation) {
2373             final MethodType type = invocation.getInvocation().type();
2374             return invocation.asType(type.changeParameterType(0, Object.class)).filterArguments(0, LEXICAL_SCOPE_FILTER);
2375         }
2376     }
2377 
2378 }