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 }
|