Merge
This commit is contained in:
commit
e39a0f47d0
@ -77,7 +77,7 @@ $(NASHORN_OUTPUTDIR)/classes/_the.nasgen.run: $(BUILD_NASGEN)
|
|||||||
$(RM) -rf $(@D)/jdk $(@D)/netscape
|
$(RM) -rf $(@D)/jdk $(@D)/netscape
|
||||||
$(CP) -R -p $(NASHORN_OUTPUTDIR)/nashorn_classes/* $(@D)/
|
$(CP) -R -p $(NASHORN_OUTPUTDIR)/nashorn_classes/* $(@D)/
|
||||||
$(FIXPATH) $(JAVA) \
|
$(FIXPATH) $(JAVA) \
|
||||||
-cp "$(NASHORN_OUTPUTDIR)/nasgen_classes$(PATH_SEP)$(NASHORN_OUTPUTDIR)/nashorn_classes" \
|
-Xbootclasspath/p:"$(NASHORN_OUTPUTDIR)/nasgen_classes$(PATH_SEP)$(NASHORN_OUTPUTDIR)/nashorn_classes" \
|
||||||
jdk.nashorn.internal.tools.nasgen.Main $(@D) jdk.nashorn.internal.objects $(@D)
|
jdk.nashorn.internal.tools.nasgen.Main $(@D) jdk.nashorn.internal.objects $(@D)
|
||||||
$(TOUCH) $@
|
$(TOUCH) $@
|
||||||
|
|
||||||
|
@ -125,6 +125,7 @@
|
|||||||
<compilerarg value="-Xlint:unchecked"/>
|
<compilerarg value="-Xlint:unchecked"/>
|
||||||
<compilerarg value="-Xlint:deprecation"/>
|
<compilerarg value="-Xlint:deprecation"/>
|
||||||
<compilerarg value="-XDignore.symbol.file"/>
|
<compilerarg value="-XDignore.symbol.file"/>
|
||||||
|
<compilerarg value="-Xdiags:verbose"/>
|
||||||
</javac>
|
</javac>
|
||||||
<copy todir="${build.classes.dir}/META-INF/services">
|
<copy todir="${build.classes.dir}/META-INF/services">
|
||||||
<fileset dir="${meta.inf.dir}/services/"/>
|
<fileset dir="${meta.inf.dir}/services/"/>
|
||||||
@ -243,6 +244,7 @@
|
|||||||
<compilerarg value="-J-Djava.ext.dirs="/>
|
<compilerarg value="-J-Djava.ext.dirs="/>
|
||||||
<compilerarg value="-Xlint:unchecked"/>
|
<compilerarg value="-Xlint:unchecked"/>
|
||||||
<compilerarg value="-Xlint:deprecation"/>
|
<compilerarg value="-Xlint:deprecation"/>
|
||||||
|
<compilerarg value="-Xdiags:verbose"/>
|
||||||
</javac>
|
</javac>
|
||||||
|
|
||||||
<copy todir="${build.test.classes.dir}/META-INF/services">
|
<copy todir="${build.test.classes.dir}/META-INF/services">
|
||||||
@ -253,6 +255,10 @@
|
|||||||
<fileset dir="${test.src.dir}/jdk/nashorn/internal/runtime/resources"/>
|
<fileset dir="${test.src.dir}/jdk/nashorn/internal/runtime/resources"/>
|
||||||
</copy>
|
</copy>
|
||||||
|
|
||||||
|
<copy todir="${build.test.classes.dir}/jdk/nashorn/api/scripting/resources">
|
||||||
|
<fileset dir="${test.src.dir}/jdk/nashorn/api/scripting/resources"/>
|
||||||
|
</copy>
|
||||||
|
|
||||||
<!-- tests that check nashorn internals and internal API -->
|
<!-- tests that check nashorn internals and internal API -->
|
||||||
<jar jarfile="${nashorn.internal.tests.jar}">
|
<jar jarfile="${nashorn.internal.tests.jar}">
|
||||||
<fileset dir="${build.test.classes.dir}" excludes="**/api/**"/>
|
<fileset dir="${build.test.classes.dir}" excludes="**/api/**"/>
|
||||||
|
@ -206,7 +206,7 @@ test262-test-sys-prop.test.failed.list.file=${build.dir}/test/failedTests
|
|||||||
|
|
||||||
# test262 test frameworks
|
# test262 test frameworks
|
||||||
test262-test-sys-prop.test.js.framework=\
|
test262-test-sys-prop.test.js.framework=\
|
||||||
--class-cache-size=0 \
|
--class-cache-size=10 \
|
||||||
--no-java \
|
--no-java \
|
||||||
--no-typed-arrays \
|
--no-typed-arrays \
|
||||||
-timezone=PST \
|
-timezone=PST \
|
||||||
|
@ -57,9 +57,9 @@ import javax.script.ScriptEngine;
|
|||||||
import javax.script.ScriptEngineFactory;
|
import javax.script.ScriptEngineFactory;
|
||||||
import javax.script.ScriptException;
|
import javax.script.ScriptException;
|
||||||
import javax.script.SimpleBindings;
|
import javax.script.SimpleBindings;
|
||||||
|
import jdk.nashorn.internal.objects.Global;
|
||||||
import jdk.nashorn.internal.runtime.Context;
|
import jdk.nashorn.internal.runtime.Context;
|
||||||
import jdk.nashorn.internal.runtime.ErrorManager;
|
import jdk.nashorn.internal.runtime.ErrorManager;
|
||||||
import jdk.nashorn.internal.runtime.GlobalObject;
|
|
||||||
import jdk.nashorn.internal.runtime.Property;
|
import jdk.nashorn.internal.runtime.Property;
|
||||||
import jdk.nashorn.internal.runtime.ScriptFunction;
|
import jdk.nashorn.internal.runtime.ScriptFunction;
|
||||||
import jdk.nashorn.internal.runtime.ScriptObject;
|
import jdk.nashorn.internal.runtime.ScriptObject;
|
||||||
@ -99,7 +99,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
|||||||
private final boolean _global_per_engine;
|
private final boolean _global_per_engine;
|
||||||
// This is the initial default Nashorn global object.
|
// This is the initial default Nashorn global object.
|
||||||
// This is used as "shared" global if above option is true.
|
// This is used as "shared" global if above option is true.
|
||||||
private final ScriptObject global;
|
private final Global global;
|
||||||
// initialized bit late to be made 'final'.
|
// initialized bit late to be made 'final'.
|
||||||
// Property object for "context" property of global object.
|
// Property object for "context" property of global object.
|
||||||
private volatile Property contextProperty;
|
private volatile Property contextProperty;
|
||||||
@ -264,7 +264,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
|||||||
public Object __noSuchProperty__(final Object self, final ScriptContext ctxt, final String name) {
|
public Object __noSuchProperty__(final Object self, final ScriptContext ctxt, final String name) {
|
||||||
if (ctxt != null) {
|
if (ctxt != null) {
|
||||||
final int scope = ctxt.getAttributesScope(name);
|
final int scope = ctxt.getAttributesScope(name);
|
||||||
final ScriptObject ctxtGlobal = getNashornGlobalFrom(ctxt);
|
final Global ctxtGlobal = getNashornGlobalFrom(ctxt);
|
||||||
if (scope != -1) {
|
if (scope != -1) {
|
||||||
return ScriptObjectMirror.unwrap(ctxt.getAttribute(name, scope), ctxtGlobal);
|
return ScriptObjectMirror.unwrap(ctxt.getAttribute(name, scope), ctxtGlobal);
|
||||||
}
|
}
|
||||||
@ -317,7 +317,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
|||||||
}
|
}
|
||||||
|
|
||||||
ScriptObject realSelf = null;
|
ScriptObject realSelf = null;
|
||||||
ScriptObject realGlobal = null;
|
Global realGlobal = null;
|
||||||
if(thiz == null) {
|
if(thiz == null) {
|
||||||
// making interface out of global functions
|
// making interface out of global functions
|
||||||
realSelf = realGlobal = getNashornGlobalFrom(context);
|
realSelf = realGlobal = getNashornGlobalFrom(context);
|
||||||
@ -346,7 +346,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final ScriptObject oldGlobal = Context.getGlobal();
|
final Global oldGlobal = Context.getGlobal();
|
||||||
final boolean globalChanged = (oldGlobal != realGlobal);
|
final boolean globalChanged = (oldGlobal != realGlobal);
|
||||||
try {
|
try {
|
||||||
if (globalChanged) {
|
if (globalChanged) {
|
||||||
@ -371,7 +371,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve nashorn Global object for a given ScriptContext object
|
// Retrieve nashorn Global object for a given ScriptContext object
|
||||||
private ScriptObject getNashornGlobalFrom(final ScriptContext ctxt) {
|
private Global getNashornGlobalFrom(final ScriptContext ctxt) {
|
||||||
if (_global_per_engine) {
|
if (_global_per_engine) {
|
||||||
// shared single global object for all ENGINE_SCOPE Bindings
|
// shared single global object for all ENGINE_SCOPE Bindings
|
||||||
return global;
|
return global;
|
||||||
@ -380,18 +380,18 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
|||||||
final Bindings bindings = ctxt.getBindings(ScriptContext.ENGINE_SCOPE);
|
final Bindings bindings = ctxt.getBindings(ScriptContext.ENGINE_SCOPE);
|
||||||
// is this Nashorn's own Bindings implementation?
|
// is this Nashorn's own Bindings implementation?
|
||||||
if (bindings instanceof ScriptObjectMirror) {
|
if (bindings instanceof ScriptObjectMirror) {
|
||||||
final ScriptObject sobj = globalFromMirror((ScriptObjectMirror)bindings);
|
final Global glob = globalFromMirror((ScriptObjectMirror)bindings);
|
||||||
if (sobj != null) {
|
if (glob != null) {
|
||||||
return sobj;
|
return glob;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Arbitrary user Bindings implementation. Look for NASHORN_GLOBAL in it!
|
// Arbitrary user Bindings implementation. Look for NASHORN_GLOBAL in it!
|
||||||
Object scope = bindings.get(NASHORN_GLOBAL);
|
Object scope = bindings.get(NASHORN_GLOBAL);
|
||||||
if (scope instanceof ScriptObjectMirror) {
|
if (scope instanceof ScriptObjectMirror) {
|
||||||
final ScriptObject sobj = globalFromMirror((ScriptObjectMirror)scope);
|
final Global glob = globalFromMirror((ScriptObjectMirror)scope);
|
||||||
if (sobj != null) {
|
if (glob != null) {
|
||||||
return sobj;
|
return glob;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -399,14 +399,14 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
|||||||
// Create new global instance mirror and associate with the Bindings.
|
// Create new global instance mirror and associate with the Bindings.
|
||||||
final ScriptObjectMirror mirror = createGlobalMirror(ctxt);
|
final ScriptObjectMirror mirror = createGlobalMirror(ctxt);
|
||||||
bindings.put(NASHORN_GLOBAL, mirror);
|
bindings.put(NASHORN_GLOBAL, mirror);
|
||||||
return mirror.getScriptObject();
|
return mirror.getHomeGlobal();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve nashorn Global object from a given ScriptObjectMirror
|
// Retrieve nashorn Global object from a given ScriptObjectMirror
|
||||||
private ScriptObject globalFromMirror(final ScriptObjectMirror mirror) {
|
private Global globalFromMirror(final ScriptObjectMirror mirror) {
|
||||||
ScriptObject sobj = mirror.getScriptObject();
|
ScriptObject sobj = mirror.getScriptObject();
|
||||||
if (sobj instanceof GlobalObject && isOfContext(sobj, nashornContext)) {
|
if (sobj instanceof Global && isOfContext((Global)sobj, nashornContext)) {
|
||||||
return sobj;
|
return (Global)sobj;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@ -414,15 +414,15 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
|||||||
|
|
||||||
// Create a new ScriptObjectMirror wrapping a newly created Nashorn Global object
|
// Create a new ScriptObjectMirror wrapping a newly created Nashorn Global object
|
||||||
private ScriptObjectMirror createGlobalMirror(final ScriptContext ctxt) {
|
private ScriptObjectMirror createGlobalMirror(final ScriptContext ctxt) {
|
||||||
final ScriptObject newGlobal = createNashornGlobal(ctxt);
|
final Global newGlobal = createNashornGlobal(ctxt);
|
||||||
return new ScriptObjectMirror(newGlobal, newGlobal);
|
return new ScriptObjectMirror(newGlobal, newGlobal);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new Nashorn Global object
|
// Create a new Nashorn Global object
|
||||||
private ScriptObject createNashornGlobal(final ScriptContext ctxt) {
|
private Global createNashornGlobal(final ScriptContext ctxt) {
|
||||||
final ScriptObject newGlobal = AccessController.doPrivileged(new PrivilegedAction<ScriptObject>() {
|
final Global newGlobal = AccessController.doPrivileged(new PrivilegedAction<Global>() {
|
||||||
@Override
|
@Override
|
||||||
public ScriptObject run() {
|
public Global run() {
|
||||||
try {
|
try {
|
||||||
return nashornContext.newGlobal();
|
return nashornContext.newGlobal();
|
||||||
} catch (final RuntimeException e) {
|
} catch (final RuntimeException e) {
|
||||||
@ -460,7 +460,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
|||||||
}
|
}
|
||||||
|
|
||||||
// scripts should see "context" and "engine" as variables in the given global object
|
// scripts should see "context" and "engine" as variables in the given global object
|
||||||
private void setContextVariables(final ScriptObject ctxtGlobal, final ScriptContext ctxt) {
|
private void setContextVariables(final Global ctxtGlobal, final ScriptContext ctxt) {
|
||||||
// set "context" global variable via contextProperty - because this
|
// set "context" global variable via contextProperty - because this
|
||||||
// property is non-writable
|
// property is non-writable
|
||||||
contextProperty.setObjectValue(ctxtGlobal, ctxtGlobal, ctxt, false);
|
contextProperty.setObjectValue(ctxtGlobal, ctxtGlobal, ctxt, false);
|
||||||
@ -470,7 +470,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
|||||||
}
|
}
|
||||||
// if no arguments passed, expose it
|
// if no arguments passed, expose it
|
||||||
if (! (args instanceof ScriptObject)) {
|
if (! (args instanceof ScriptObject)) {
|
||||||
args = ((GlobalObject)ctxtGlobal).wrapAsObject(args);
|
args = ctxtGlobal.wrapAsObject(args);
|
||||||
ctxtGlobal.set("arguments", args, false);
|
ctxtGlobal.set("arguments", args, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -478,7 +478,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
|||||||
private Object invokeImpl(final Object selfObject, final String name, final Object... args) throws ScriptException, NoSuchMethodException {
|
private Object invokeImpl(final Object selfObject, final String name, final Object... args) throws ScriptException, NoSuchMethodException {
|
||||||
name.getClass(); // null check
|
name.getClass(); // null check
|
||||||
|
|
||||||
ScriptObject invokeGlobal = null;
|
Global invokeGlobal = null;
|
||||||
ScriptObjectMirror selfMirror = null;
|
ScriptObjectMirror selfMirror = null;
|
||||||
if (selfObject instanceof ScriptObjectMirror) {
|
if (selfObject instanceof ScriptObjectMirror) {
|
||||||
selfMirror = (ScriptObjectMirror)selfObject;
|
selfMirror = (ScriptObjectMirror)selfObject;
|
||||||
@ -489,7 +489,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
|||||||
} else if (selfObject instanceof ScriptObject) {
|
} else if (selfObject instanceof ScriptObject) {
|
||||||
// invokeMethod called from script code - in which case we may get 'naked' ScriptObject
|
// invokeMethod called from script code - in which case we may get 'naked' ScriptObject
|
||||||
// Wrap it with oldGlobal to make a ScriptObjectMirror for the same.
|
// Wrap it with oldGlobal to make a ScriptObjectMirror for the same.
|
||||||
final ScriptObject oldGlobal = Context.getGlobal();
|
final Global oldGlobal = Context.getGlobal();
|
||||||
invokeGlobal = oldGlobal;
|
invokeGlobal = oldGlobal;
|
||||||
if (oldGlobal == null) {
|
if (oldGlobal == null) {
|
||||||
throw new IllegalArgumentException(getMessage("no.current.nashorn.global"));
|
throw new IllegalArgumentException(getMessage("no.current.nashorn.global"));
|
||||||
@ -502,7 +502,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
|||||||
selfMirror = (ScriptObjectMirror)ScriptObjectMirror.wrap(selfObject, oldGlobal);
|
selfMirror = (ScriptObjectMirror)ScriptObjectMirror.wrap(selfObject, oldGlobal);
|
||||||
} else if (selfObject == null) {
|
} else if (selfObject == null) {
|
||||||
// selfObject is null => global function call
|
// selfObject is null => global function call
|
||||||
final ScriptObject ctxtGlobal = getNashornGlobalFrom(context);
|
final Global ctxtGlobal = getNashornGlobalFrom(context);
|
||||||
invokeGlobal = ctxtGlobal;
|
invokeGlobal = ctxtGlobal;
|
||||||
selfMirror = (ScriptObjectMirror)ScriptObjectMirror.wrap(ctxtGlobal, ctxtGlobal);
|
selfMirror = (ScriptObjectMirror)ScriptObjectMirror.wrap(ctxtGlobal, ctxtGlobal);
|
||||||
}
|
}
|
||||||
@ -532,11 +532,11 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
|||||||
return evalImpl(script, ctxt, getNashornGlobalFrom(ctxt));
|
return evalImpl(script, ctxt, getNashornGlobalFrom(ctxt));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt, final ScriptObject ctxtGlobal) throws ScriptException {
|
private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt, final Global ctxtGlobal) throws ScriptException {
|
||||||
if (script == null) {
|
if (script == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final ScriptObject oldGlobal = Context.getGlobal();
|
final Global oldGlobal = Context.getGlobal();
|
||||||
final boolean globalChanged = (oldGlobal != ctxtGlobal);
|
final boolean globalChanged = (oldGlobal != ctxtGlobal);
|
||||||
try {
|
try {
|
||||||
if (globalChanged) {
|
if (globalChanged) {
|
||||||
@ -558,7 +558,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void throwAsScriptException(final Exception e, final ScriptObject global) throws ScriptException {
|
private static void throwAsScriptException(final Exception e, final Global global) throws ScriptException {
|
||||||
if (e instanceof ScriptException) {
|
if (e instanceof ScriptException) {
|
||||||
throw (ScriptException)e;
|
throw (ScriptException)e;
|
||||||
} else if (e instanceof NashornException) {
|
} else if (e instanceof NashornException) {
|
||||||
@ -582,7 +582,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
|||||||
return new CompiledScript() {
|
return new CompiledScript() {
|
||||||
@Override
|
@Override
|
||||||
public Object eval(final ScriptContext ctxt) throws ScriptException {
|
public Object eval(final ScriptContext ctxt) throws ScriptException {
|
||||||
final ScriptObject globalObject = getNashornGlobalFrom(ctxt);
|
final Global globalObject = getNashornGlobalFrom(ctxt);
|
||||||
// Are we running the script in the correct global?
|
// Are we running the script in the correct global?
|
||||||
if (func.getScope() == globalObject) {
|
if (func.getScope() == globalObject) {
|
||||||
return evalImpl(func, ctxt, globalObject);
|
return evalImpl(func, ctxt, globalObject);
|
||||||
@ -602,8 +602,8 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
|||||||
return compileImpl(source, getNashornGlobalFrom(ctxt));
|
return compileImpl(source, getNashornGlobalFrom(ctxt));
|
||||||
}
|
}
|
||||||
|
|
||||||
private ScriptFunction compileImpl(final Source source, final ScriptObject newGlobal) throws ScriptException {
|
private ScriptFunction compileImpl(final Source source, final Global newGlobal) throws ScriptException {
|
||||||
final ScriptObject oldGlobal = Context.getGlobal();
|
final Global oldGlobal = Context.getGlobal();
|
||||||
final boolean globalChanged = (oldGlobal != newGlobal);
|
final boolean globalChanged = (oldGlobal != newGlobal);
|
||||||
try {
|
try {
|
||||||
if (globalChanged) {
|
if (globalChanged) {
|
||||||
@ -641,8 +641,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isOfContext(final ScriptObject global, final Context context) {
|
private static boolean isOfContext(final Global global, final Context context) {
|
||||||
assert global instanceof GlobalObject: "Not a Global object";
|
return global.isOfContext(context);
|
||||||
return ((GlobalObject)global).isOfContext(context);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,10 +42,10 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import javax.script.Bindings;
|
import javax.script.Bindings;
|
||||||
|
import jdk.nashorn.internal.objects.Global;
|
||||||
import jdk.nashorn.internal.runtime.arrays.ArrayData;
|
import jdk.nashorn.internal.runtime.arrays.ArrayData;
|
||||||
import jdk.nashorn.internal.runtime.ConsString;
|
import jdk.nashorn.internal.runtime.ConsString;
|
||||||
import jdk.nashorn.internal.runtime.Context;
|
import jdk.nashorn.internal.runtime.Context;
|
||||||
import jdk.nashorn.internal.runtime.GlobalObject;
|
|
||||||
import jdk.nashorn.internal.runtime.JSType;
|
import jdk.nashorn.internal.runtime.JSType;
|
||||||
import jdk.nashorn.internal.runtime.ScriptFunction;
|
import jdk.nashorn.internal.runtime.ScriptFunction;
|
||||||
import jdk.nashorn.internal.runtime.ScriptObject;
|
import jdk.nashorn.internal.runtime.ScriptObject;
|
||||||
@ -64,7 +64,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
|
|||||||
private static final AccessControlContext GET_CONTEXT_ACC_CTXT = getContextAccCtxt();
|
private static final AccessControlContext GET_CONTEXT_ACC_CTXT = getContextAccCtxt();
|
||||||
|
|
||||||
private final ScriptObject sobj;
|
private final ScriptObject sobj;
|
||||||
private final ScriptObject global;
|
private final Global global;
|
||||||
private final boolean strict;
|
private final boolean strict;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -95,7 +95,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object call(final Object thiz, final Object... args) {
|
public Object call(final Object thiz, final Object... args) {
|
||||||
final ScriptObject oldGlobal = Context.getGlobal();
|
final Global oldGlobal = Context.getGlobal();
|
||||||
final boolean globalChanged = (oldGlobal != global);
|
final boolean globalChanged = (oldGlobal != global);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -125,7 +125,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object newObject(final Object... args) {
|
public Object newObject(final Object... args) {
|
||||||
final ScriptObject oldGlobal = Context.getGlobal();
|
final Global oldGlobal = Context.getGlobal();
|
||||||
final boolean globalChanged = (oldGlobal != global);
|
final boolean globalChanged = (oldGlobal != global);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -171,7 +171,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
|
|||||||
|
|
||||||
public Object callMember(final String functionName, final Object... args) {
|
public Object callMember(final String functionName, final Object... args) {
|
||||||
functionName.getClass(); // null check
|
functionName.getClass(); // null check
|
||||||
final ScriptObject oldGlobal = Context.getGlobal();
|
final Global oldGlobal = Context.getGlobal();
|
||||||
final boolean globalChanged = (oldGlobal != global);
|
final boolean globalChanged = (oldGlobal != global);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -642,7 +642,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
|
|||||||
*/
|
*/
|
||||||
public static Object wrap(final Object obj, final Object homeGlobal) {
|
public static Object wrap(final Object obj, final Object homeGlobal) {
|
||||||
if(obj instanceof ScriptObject) {
|
if(obj instanceof ScriptObject) {
|
||||||
return homeGlobal instanceof ScriptObject ? new ScriptObjectMirror((ScriptObject)obj, (ScriptObject)homeGlobal) : obj;
|
return homeGlobal instanceof Global ? new ScriptObjectMirror((ScriptObject)obj, (Global)homeGlobal) : obj;
|
||||||
}
|
}
|
||||||
if(obj instanceof ConsString) {
|
if(obj instanceof ConsString) {
|
||||||
return obj.toString();
|
return obj.toString();
|
||||||
@ -710,13 +710,13 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
|
|||||||
|
|
||||||
// package-privates below this.
|
// package-privates below this.
|
||||||
|
|
||||||
ScriptObjectMirror(final ScriptObject sobj, final ScriptObject global) {
|
ScriptObjectMirror(final ScriptObject sobj, final Global global) {
|
||||||
assert sobj != null : "ScriptObjectMirror on null!";
|
assert sobj != null : "ScriptObjectMirror on null!";
|
||||||
assert global instanceof GlobalObject : "global is not a GlobalObject";
|
assert global != null : "home Global is null";
|
||||||
|
|
||||||
this.sobj = sobj;
|
this.sobj = sobj;
|
||||||
this.global = global;
|
this.global = global;
|
||||||
this.strict = ((GlobalObject)global).isStrictContext();
|
this.strict = global.isStrictContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
// accessors for script engine
|
// accessors for script engine
|
||||||
@ -724,7 +724,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
|
|||||||
return sobj;
|
return sobj;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptObject getHomeGlobal() {
|
Global getHomeGlobal() {
|
||||||
return global;
|
return global;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -734,7 +734,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
|
|||||||
|
|
||||||
// internals only below this.
|
// internals only below this.
|
||||||
private <V> V inGlobal(final Callable<V> callable) {
|
private <V> V inGlobal(final Callable<V> callable) {
|
||||||
final ScriptObject oldGlobal = Context.getGlobal();
|
final Global oldGlobal = Context.getGlobal();
|
||||||
final boolean globalChanged = (oldGlobal != global);
|
final boolean globalChanged = (oldGlobal != global);
|
||||||
if (globalChanged) {
|
if (globalChanged) {
|
||||||
Context.setGlobal(global);
|
Context.setGlobal(global);
|
||||||
|
@ -375,10 +375,11 @@ final class Attr extends NodeOperatorVisitor<LexicalContext> {
|
|||||||
* @return Symbol for given name or null for redefinition.
|
* @return Symbol for given name or null for redefinition.
|
||||||
*/
|
*/
|
||||||
private Symbol defineSymbol(final Block block, final String name, final int symbolFlags) {
|
private Symbol defineSymbol(final Block block, final String name, final int symbolFlags) {
|
||||||
int flags = symbolFlags;
|
int flags = symbolFlags;
|
||||||
Symbol symbol = findSymbol(block, name); // Locate symbol.
|
Symbol symbol = findSymbol(block, name); // Locate symbol.
|
||||||
|
boolean isGlobal = (flags & KINDMASK) == IS_GLOBAL;
|
||||||
|
|
||||||
if ((flags & KINDMASK) == IS_GLOBAL) {
|
if (isGlobal) {
|
||||||
flags |= IS_SCOPE;
|
flags |= IS_SCOPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -414,6 +415,8 @@ final class Attr extends NodeOperatorVisitor<LexicalContext> {
|
|||||||
// Determine where to create it.
|
// Determine where to create it.
|
||||||
if ((flags & Symbol.KINDMASK) == IS_VAR && ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & IS_LET) == IS_LET)) {
|
if ((flags & Symbol.KINDMASK) == IS_VAR && ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & IS_LET) == IS_LET)) {
|
||||||
symbolBlock = block; //internal vars are always defined in the block closest to them
|
symbolBlock = block; //internal vars are always defined in the block closest to them
|
||||||
|
} else if (isGlobal) {
|
||||||
|
symbolBlock = lc.getOutermostFunction().getBody();
|
||||||
} else {
|
} else {
|
||||||
symbolBlock = lc.getFunctionBody(function);
|
symbolBlock = lc.getFunctionBody(function);
|
||||||
}
|
}
|
||||||
|
@ -685,7 +685,7 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
|
|||||||
private void scopeCall(final IdentNode node, final int flags) {
|
private void scopeCall(final IdentNode node, final int flags) {
|
||||||
load(node, Type.OBJECT); // Type.OBJECT as foo() makes no sense if foo == 3
|
load(node, Type.OBJECT); // Type.OBJECT as foo() makes no sense if foo == 3
|
||||||
// ScriptFunction will see CALLSITE_SCOPE and will bind scope accordingly.
|
// ScriptFunction will see CALLSITE_SCOPE and will bind scope accordingly.
|
||||||
method.loadNull(); //the 'this'
|
method.loadUndefined(Type.OBJECT); //the 'this' object
|
||||||
method.dynamicCall(callNodeType, 2 + loadArgs(args), flags);
|
method.dynamicCall(callNodeType, 2 + loadArgs(args), flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -818,7 +818,7 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
|
|||||||
protected boolean enterDefault(final Node node) {
|
protected boolean enterDefault(final Node node) {
|
||||||
// Load up function.
|
// Load up function.
|
||||||
load(function, Type.OBJECT); //TODO, e.g. booleans can be used as functions
|
load(function, Type.OBJECT); //TODO, e.g. booleans can be used as functions
|
||||||
method.loadNull(); // ScriptFunction will figure out the correct this when it sees CALLSITE_SCOPE
|
method.loadUndefined(Type.OBJECT); // ScriptFunction will figure out the correct this when it sees CALLSITE_SCOPE
|
||||||
method.dynamicCall(callNodeType, 2 + loadArgs(args), getCallSiteFlags() | CALLSITE_SCOPE);
|
method.dynamicCall(callNodeType, 2 + loadArgs(args), getCallSiteFlags() | CALLSITE_SCOPE);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -156,7 +156,7 @@ class SharedScopeCall {
|
|||||||
if (isCall) {
|
if (isCall) {
|
||||||
method.convert(Type.OBJECT);
|
method.convert(Type.OBJECT);
|
||||||
// ScriptFunction will see CALLSITE_SCOPE and will bind scope accordingly.
|
// ScriptFunction will see CALLSITE_SCOPE and will bind scope accordingly.
|
||||||
method.loadNull();
|
method.loadUndefined(Type.OBJECT);
|
||||||
int slot = 2;
|
int slot = 2;
|
||||||
for (final Type type : paramTypes) {
|
for (final Type type : paramTypes) {
|
||||||
method.load(type, slot++);
|
method.load(type, slot++);
|
||||||
|
@ -164,11 +164,11 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
|
|||||||
public static final int HAS_EVAL = 1 << 5;
|
public static final int HAS_EVAL = 1 << 5;
|
||||||
|
|
||||||
/** Does a nested function contain eval? If it does, then all variables in this function might be get/set by it. */
|
/** Does a nested function contain eval? If it does, then all variables in this function might be get/set by it. */
|
||||||
public static final int HAS_NESTED_EVAL = 1 << 6;
|
public static final int HAS_NESTED_EVAL = 1 << 6;
|
||||||
|
|
||||||
/** Does this function have any blocks that create a scope? This is used to determine if the function needs to
|
/** Does this function have any blocks that create a scope? This is used to determine if the function needs to
|
||||||
* have a local variable slot for the scope symbol. */
|
* have a local variable slot for the scope symbol. */
|
||||||
public static final int HAS_SCOPE_BLOCK = 1 << 7;
|
public static final int HAS_SCOPE_BLOCK = 1 << 7;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag this function as one that defines the identifier "arguments" as a function parameter or nested function
|
* Flag this function as one that defines the identifier "arguments" as a function parameter or nested function
|
||||||
@ -197,6 +197,9 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
|
|||||||
/** Can this function be specialized? */
|
/** Can this function be specialized? */
|
||||||
public static final int CAN_SPECIALIZE = 1 << 14;
|
public static final int CAN_SPECIALIZE = 1 << 14;
|
||||||
|
|
||||||
|
/** Does this function use the "this" keyword? */
|
||||||
|
public static final int USES_THIS = 1 << 15;
|
||||||
|
|
||||||
/** Does this function or any nested functions contain an eval? */
|
/** Does this function or any nested functions contain an eval? */
|
||||||
private static final int HAS_DEEP_EVAL = HAS_EVAL | HAS_NESTED_EVAL;
|
private static final int HAS_DEEP_EVAL = HAS_EVAL | HAS_NESTED_EVAL;
|
||||||
|
|
||||||
@ -590,6 +593,15 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
|
|||||||
return needsParentScope() || needsSelfSymbol() || isSplit() || (needsArguments() && !isStrict());
|
return needsParentScope() || needsSelfSymbol() || isSplit() || (needsArguments() && !isStrict());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return {@code true} if this function makes use of the {@code this} object.
|
||||||
|
*
|
||||||
|
* @return true if function uses {@code this} object
|
||||||
|
*/
|
||||||
|
public boolean usesThis() {
|
||||||
|
return getFlag(USES_THIS);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the identifier for this function, this is its symbol.
|
* Get the identifier for this function, this is its symbol.
|
||||||
* @return the identifier as an IdentityNode
|
* @return the identifier as an IdentityNode
|
||||||
|
@ -67,12 +67,8 @@ public final class AccessorPropertyDescriptor extends ScriptObject implements Pr
|
|||||||
// initialized by nasgen
|
// initialized by nasgen
|
||||||
private static PropertyMap $nasgenmap$;
|
private static PropertyMap $nasgenmap$;
|
||||||
|
|
||||||
static PropertyMap getInitialMap() {
|
|
||||||
return $nasgenmap$;
|
|
||||||
}
|
|
||||||
|
|
||||||
AccessorPropertyDescriptor(final boolean configurable, final boolean enumerable, final Object get, final Object set, final Global global) {
|
AccessorPropertyDescriptor(final boolean configurable, final boolean enumerable, final Object get, final Object set, final Global global) {
|
||||||
super(global.getObjectPrototype(), getInitialMap());
|
super(global.getObjectPrototype(), $nasgenmap$);
|
||||||
this.configurable = configurable;
|
this.configurable = configurable;
|
||||||
this.enumerable = enumerable;
|
this.enumerable = enumerable;
|
||||||
this.get = get;
|
this.get = get;
|
||||||
|
@ -42,12 +42,8 @@ abstract class ArrayBufferView extends ScriptObject {
|
|||||||
// initialized by nasgen
|
// initialized by nasgen
|
||||||
private static PropertyMap $nasgenmap$;
|
private static PropertyMap $nasgenmap$;
|
||||||
|
|
||||||
static PropertyMap getInitialMap() {
|
|
||||||
return $nasgenmap$;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ArrayBufferView(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength, final Global global) {
|
private ArrayBufferView(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength, final Global global) {
|
||||||
super(getInitialMap());
|
super($nasgenmap$);
|
||||||
checkConstructorArgs(buffer, byteOffset, elementLength);
|
checkConstructorArgs(buffer, byteOffset, elementLength);
|
||||||
this.setProto(getPrototype(global));
|
this.setProto(getPrototype(global));
|
||||||
this.setArray(factory().createArrayData(buffer, byteOffset, elementLength));
|
this.setArray(factory().createArrayData(buffer, byteOffset, elementLength));
|
||||||
|
@ -64,12 +64,8 @@ public final class DataPropertyDescriptor extends ScriptObject implements Proper
|
|||||||
// initialized by nasgen
|
// initialized by nasgen
|
||||||
private static PropertyMap $nasgenmap$;
|
private static PropertyMap $nasgenmap$;
|
||||||
|
|
||||||
static PropertyMap getInitialMap() {
|
|
||||||
return $nasgenmap$;
|
|
||||||
}
|
|
||||||
|
|
||||||
DataPropertyDescriptor(final boolean configurable, final boolean enumerable, final boolean writable, final Object value, final Global global) {
|
DataPropertyDescriptor(final boolean configurable, final boolean enumerable, final boolean writable, final Object value, final Global global) {
|
||||||
super(global.getObjectPrototype(), getInitialMap());
|
super(global.getObjectPrototype(), $nasgenmap$);
|
||||||
this.configurable = configurable;
|
this.configurable = configurable;
|
||||||
this.enumerable = enumerable;
|
this.enumerable = enumerable;
|
||||||
this.writable = writable;
|
this.writable = writable;
|
||||||
|
@ -55,12 +55,8 @@ public final class GenericPropertyDescriptor extends ScriptObject implements Pro
|
|||||||
// initialized by nasgen
|
// initialized by nasgen
|
||||||
private static PropertyMap $nasgenmap$;
|
private static PropertyMap $nasgenmap$;
|
||||||
|
|
||||||
static PropertyMap getInitialMap() {
|
|
||||||
return $nasgenmap$;
|
|
||||||
}
|
|
||||||
|
|
||||||
GenericPropertyDescriptor(final boolean configurable, final boolean enumerable, final Global global) {
|
GenericPropertyDescriptor(final boolean configurable, final boolean enumerable, final Global global) {
|
||||||
super(global.getObjectPrototype(), getInitialMap());
|
super(global.getObjectPrototype(), $nasgenmap$);
|
||||||
this.configurable = configurable;
|
this.configurable = configurable;
|
||||||
this.enumerable = enumerable;
|
this.enumerable = enumerable;
|
||||||
}
|
}
|
||||||
|
@ -33,11 +33,8 @@ import java.io.IOException;
|
|||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.lang.ref.ReferenceQueue;
|
|
||||||
import java.lang.ref.SoftReference;
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
@ -51,7 +48,6 @@ import jdk.nashorn.internal.objects.annotations.ScriptClass;
|
|||||||
import jdk.nashorn.internal.runtime.ConsString;
|
import jdk.nashorn.internal.runtime.ConsString;
|
||||||
import jdk.nashorn.internal.runtime.Context;
|
import jdk.nashorn.internal.runtime.Context;
|
||||||
import jdk.nashorn.internal.runtime.GlobalFunctions;
|
import jdk.nashorn.internal.runtime.GlobalFunctions;
|
||||||
import jdk.nashorn.internal.runtime.GlobalObject;
|
|
||||||
import jdk.nashorn.internal.runtime.JSType;
|
import jdk.nashorn.internal.runtime.JSType;
|
||||||
import jdk.nashorn.internal.runtime.NativeJavaPackage;
|
import jdk.nashorn.internal.runtime.NativeJavaPackage;
|
||||||
import jdk.nashorn.internal.runtime.PropertyDescriptor;
|
import jdk.nashorn.internal.runtime.PropertyDescriptor;
|
||||||
@ -59,10 +55,10 @@ import jdk.nashorn.internal.runtime.PropertyMap;
|
|||||||
import jdk.nashorn.internal.runtime.Scope;
|
import jdk.nashorn.internal.runtime.Scope;
|
||||||
import jdk.nashorn.internal.runtime.ScriptEnvironment;
|
import jdk.nashorn.internal.runtime.ScriptEnvironment;
|
||||||
import jdk.nashorn.internal.runtime.ScriptFunction;
|
import jdk.nashorn.internal.runtime.ScriptFunction;
|
||||||
|
import jdk.nashorn.internal.runtime.ScriptFunctionData;
|
||||||
import jdk.nashorn.internal.runtime.ScriptObject;
|
import jdk.nashorn.internal.runtime.ScriptObject;
|
||||||
import jdk.nashorn.internal.runtime.ScriptRuntime;
|
import jdk.nashorn.internal.runtime.ScriptRuntime;
|
||||||
import jdk.nashorn.internal.runtime.ScriptingFunctions;
|
import jdk.nashorn.internal.runtime.ScriptingFunctions;
|
||||||
import jdk.nashorn.internal.runtime.Source;
|
|
||||||
import jdk.nashorn.internal.runtime.arrays.ArrayData;
|
import jdk.nashorn.internal.runtime.arrays.ArrayData;
|
||||||
import jdk.nashorn.internal.runtime.linker.Bootstrap;
|
import jdk.nashorn.internal.runtime.linker.Bootstrap;
|
||||||
import jdk.nashorn.internal.runtime.linker.InvokeByName;
|
import jdk.nashorn.internal.runtime.linker.InvokeByName;
|
||||||
@ -73,7 +69,7 @@ import jdk.nashorn.internal.scripts.JO;
|
|||||||
* Representation of global scope.
|
* Representation of global scope.
|
||||||
*/
|
*/
|
||||||
@ScriptClass("Global")
|
@ScriptClass("Global")
|
||||||
public final class Global extends ScriptObject implements GlobalObject, Scope {
|
public final class Global extends ScriptObject implements Scope {
|
||||||
private final InvokeByName TO_STRING = new InvokeByName("toString", ScriptObject.class);
|
private final InvokeByName TO_STRING = new InvokeByName("toString", ScriptObject.class);
|
||||||
private final InvokeByName VALUE_OF = new InvokeByName("valueOf", ScriptObject.class);
|
private final InvokeByName VALUE_OF = new InvokeByName("valueOf", ScriptObject.class);
|
||||||
|
|
||||||
@ -229,6 +225,10 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
|||||||
@Property(name = "ArrayBuffer", attributes = Attribute.NOT_ENUMERABLE)
|
@Property(name = "ArrayBuffer", attributes = Attribute.NOT_ENUMERABLE)
|
||||||
public volatile Object arrayBuffer;
|
public volatile Object arrayBuffer;
|
||||||
|
|
||||||
|
/** DataView object */
|
||||||
|
@Property(name = "DataView", attributes = Attribute.NOT_ENUMERABLE)
|
||||||
|
public volatile Object dataView;
|
||||||
|
|
||||||
/** TypedArray (int8) */
|
/** TypedArray (int8) */
|
||||||
@Property(name = "Int8Array", attributes = Attribute.NOT_ENUMERABLE)
|
@Property(name = "Int8Array", attributes = Attribute.NOT_ENUMERABLE)
|
||||||
public volatile Object int8Array;
|
public volatile Object int8Array;
|
||||||
@ -355,6 +355,7 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
|||||||
private ScriptObject builtinJavaImporter;
|
private ScriptObject builtinJavaImporter;
|
||||||
private ScriptObject builtinJavaApi;
|
private ScriptObject builtinJavaApi;
|
||||||
private ScriptObject builtinArrayBuffer;
|
private ScriptObject builtinArrayBuffer;
|
||||||
|
private ScriptObject builtinDataView;
|
||||||
private ScriptObject builtinInt8Array;
|
private ScriptObject builtinInt8Array;
|
||||||
private ScriptObject builtinUint8Array;
|
private ScriptObject builtinUint8Array;
|
||||||
private ScriptObject builtinUint8ClampedArray;
|
private ScriptObject builtinUint8ClampedArray;
|
||||||
@ -373,9 +374,6 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
|||||||
// Flag to indicate that a split method issued a return statement
|
// Flag to indicate that a split method issued a return statement
|
||||||
private int splitState = -1;
|
private int splitState = -1;
|
||||||
|
|
||||||
// class cache
|
|
||||||
private ClassCache classCache;
|
|
||||||
|
|
||||||
// Used to store the last RegExp result to support deprecated RegExp constructor properties
|
// Used to store the last RegExp result to support deprecated RegExp constructor properties
|
||||||
private RegExpResult lastRegExpResult;
|
private RegExpResult lastRegExpResult;
|
||||||
|
|
||||||
@ -426,11 +424,6 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
|||||||
super(checkAndGetMap(context));
|
super(checkAndGetMap(context));
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.setIsScope();
|
this.setIsScope();
|
||||||
|
|
||||||
final int cacheSize = context.getEnv()._class_cache_size;
|
|
||||||
if (cacheSize > 0) {
|
|
||||||
classCache = new ClassCache(cacheSize);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -439,11 +432,9 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
|||||||
* @return the global singleton
|
* @return the global singleton
|
||||||
*/
|
*/
|
||||||
public static Global instance() {
|
public static Global instance() {
|
||||||
ScriptObject global = Context.getGlobal();
|
Global global = Context.getGlobal();
|
||||||
if (! (global instanceof Global)) {
|
global.getClass(); // null check
|
||||||
throw new IllegalStateException("no current global instance");
|
return global;
|
||||||
}
|
|
||||||
return (Global)global;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -464,19 +455,30 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
|||||||
return instance().getContext();
|
return instance().getContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
// GlobalObject interface implementation
|
// Runtime interface to Global
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
|
* Is this global of the given Context?
|
||||||
|
* @param ctxt the context
|
||||||
|
* @return true if this global belongs to the given Context
|
||||||
|
*/
|
||||||
public boolean isOfContext(final Context ctxt) {
|
public boolean isOfContext(final Context ctxt) {
|
||||||
return this.context == ctxt;
|
return this.context == ctxt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
|
* Does this global belong to a strict Context?
|
||||||
|
* @return true if this global belongs to a strict Context
|
||||||
|
*/
|
||||||
public boolean isStrictContext() {
|
public boolean isStrictContext() {
|
||||||
return context.getEnv()._strict;
|
return context.getEnv()._strict;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
|
* Initialize standard builtin objects like "Object", "Array", "Function" etc.
|
||||||
|
* as well as our extension builtin objects like "Java", "JSAdapter" as properties
|
||||||
|
* of the global scope object.
|
||||||
|
*/
|
||||||
public void initBuiltinObjects() {
|
public void initBuiltinObjects() {
|
||||||
if (this.builtinObject != null) {
|
if (this.builtinObject != null) {
|
||||||
// already initialized, just return
|
// already initialized, just return
|
||||||
@ -486,12 +488,26 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
|||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
|
* Create a new ScriptFunction object
|
||||||
|
*
|
||||||
|
* @param name function name
|
||||||
|
* @param handle invocation handle for function
|
||||||
|
* @param scope the scope
|
||||||
|
* @param strict are we in strict mode
|
||||||
|
*
|
||||||
|
* @return new script function
|
||||||
|
*/
|
||||||
public ScriptFunction newScriptFunction(final String name, final MethodHandle handle, final ScriptObject scope, final boolean strict) {
|
public ScriptFunction newScriptFunction(final String name, final MethodHandle handle, final ScriptObject scope, final boolean strict) {
|
||||||
return new ScriptFunctionImpl(name, handle, scope, null, strict, false, true);
|
return new ScriptFunctionImpl(name, handle, scope, null, strict ? ScriptFunctionData.IS_STRICT_CONSTRUCTOR : ScriptFunctionData.IS_CONSTRUCTOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
|
* Wrap a Java object as corresponding script object
|
||||||
|
*
|
||||||
|
* @param obj object to wrap
|
||||||
|
* @return wrapped object
|
||||||
|
*/
|
||||||
public Object wrapAsObject(final Object obj) {
|
public Object wrapAsObject(final Object obj) {
|
||||||
if (obj instanceof Boolean) {
|
if (obj instanceof Boolean) {
|
||||||
return new NativeBoolean((Boolean)obj, this);
|
return new NativeBoolean((Boolean)obj, this);
|
||||||
@ -513,7 +529,14 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
|
* Lookup helper for JS primitive types
|
||||||
|
*
|
||||||
|
* @param request the link request for the dynamic call site.
|
||||||
|
* @param self self reference
|
||||||
|
*
|
||||||
|
* @return guarded invocation
|
||||||
|
*/
|
||||||
public GuardedInvocation primitiveLookup(final LinkRequest request, final Object self) {
|
public GuardedInvocation primitiveLookup(final LinkRequest request, final Object self) {
|
||||||
if (self instanceof String || self instanceof ConsString) {
|
if (self instanceof String || self instanceof ConsString) {
|
||||||
return NativeString.lookupPrimitive(request, self);
|
return NativeString.lookupPrimitive(request, self);
|
||||||
@ -525,12 +548,23 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
|||||||
throw new IllegalArgumentException("Unsupported primitive: " + self);
|
throw new IllegalArgumentException("Unsupported primitive: " + self);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
|
* Create a new empty script object
|
||||||
|
*
|
||||||
|
* @return the new ScriptObject
|
||||||
|
*/
|
||||||
public ScriptObject newObject() {
|
public ScriptObject newObject() {
|
||||||
return new JO(getObjectPrototype(), JO.getInitialMap());
|
return new JO(getObjectPrototype(), JO.getInitialMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
|
* Default value of given type
|
||||||
|
*
|
||||||
|
* @param sobj script object
|
||||||
|
* @param typeHint type hint
|
||||||
|
*
|
||||||
|
* @return default value
|
||||||
|
*/
|
||||||
public Object getDefaultValue(final ScriptObject sobj, final Class<?> typeHint) {
|
public Object getDefaultValue(final ScriptObject sobj, final Class<?> typeHint) {
|
||||||
// When the [[DefaultValue]] internal method of O is called with no hint,
|
// When the [[DefaultValue]] internal method of O is called with no hint,
|
||||||
// then it behaves as if the hint were Number, unless O is a Date object
|
// then it behaves as if the hint were Number, unless O is a Date object
|
||||||
@ -590,7 +624,12 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
|||||||
return UNDEFINED;
|
return UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
|
* Is the given ScriptObject an ECMAScript Error object?
|
||||||
|
*
|
||||||
|
* @param sobj the object being checked
|
||||||
|
* @return true if sobj is an Error object
|
||||||
|
*/
|
||||||
public boolean isError(final ScriptObject sobj) {
|
public boolean isError(final ScriptObject sobj) {
|
||||||
final ScriptObject errorProto = getErrorPrototype();
|
final ScriptObject errorProto = getErrorPrototype();
|
||||||
ScriptObject proto = sobj.getProto();
|
ScriptObject proto = sobj.getProto();
|
||||||
@ -603,52 +642,108 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
|
* Create a new ECMAScript Error object.
|
||||||
|
*
|
||||||
|
* @param msg error message
|
||||||
|
* @return newly created Error object
|
||||||
|
*/
|
||||||
public ScriptObject newError(final String msg) {
|
public ScriptObject newError(final String msg) {
|
||||||
return new NativeError(msg, this);
|
return new NativeError(msg, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
|
* Create a new ECMAScript EvalError object.
|
||||||
|
*
|
||||||
|
* @param msg error message
|
||||||
|
* @return newly created EvalError object
|
||||||
|
*/
|
||||||
public ScriptObject newEvalError(final String msg) {
|
public ScriptObject newEvalError(final String msg) {
|
||||||
return new NativeEvalError(msg, this);
|
return new NativeEvalError(msg, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
|
* Create a new ECMAScript RangeError object.
|
||||||
|
*
|
||||||
|
* @param msg error message
|
||||||
|
* @return newly created RangeError object
|
||||||
|
*/
|
||||||
public ScriptObject newRangeError(final String msg) {
|
public ScriptObject newRangeError(final String msg) {
|
||||||
return new NativeRangeError(msg, this);
|
return new NativeRangeError(msg, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
|
* Create a new ECMAScript ReferenceError object.
|
||||||
|
*
|
||||||
|
* @param msg error message
|
||||||
|
* @return newly created ReferenceError object
|
||||||
|
*/
|
||||||
public ScriptObject newReferenceError(final String msg) {
|
public ScriptObject newReferenceError(final String msg) {
|
||||||
return new NativeReferenceError(msg, this);
|
return new NativeReferenceError(msg, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
|
* Create a new ECMAScript SyntaxError object.
|
||||||
|
*
|
||||||
|
* @param msg error message
|
||||||
|
* @return newly created SyntaxError object
|
||||||
|
*/
|
||||||
public ScriptObject newSyntaxError(final String msg) {
|
public ScriptObject newSyntaxError(final String msg) {
|
||||||
return new NativeSyntaxError(msg, this);
|
return new NativeSyntaxError(msg, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
|
* Create a new ECMAScript TypeError object.
|
||||||
|
*
|
||||||
|
* @param msg error message
|
||||||
|
* @return newly created TypeError object
|
||||||
|
*/
|
||||||
public ScriptObject newTypeError(final String msg) {
|
public ScriptObject newTypeError(final String msg) {
|
||||||
return new NativeTypeError(msg, this);
|
return new NativeTypeError(msg, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
|
* Create a new ECMAScript URIError object.
|
||||||
|
*
|
||||||
|
* @param msg error message
|
||||||
|
* @return newly created URIError object
|
||||||
|
*/
|
||||||
public ScriptObject newURIError(final String msg) {
|
public ScriptObject newURIError(final String msg) {
|
||||||
return new NativeURIError(msg, this);
|
return new NativeURIError(msg, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
|
* Create a new ECMAScript GenericDescriptor object.
|
||||||
|
*
|
||||||
|
* @param configurable is the property configurable?
|
||||||
|
* @param enumerable is the property enumerable?
|
||||||
|
* @return newly created GenericDescriptor object
|
||||||
|
*/
|
||||||
public PropertyDescriptor newGenericDescriptor(final boolean configurable, final boolean enumerable) {
|
public PropertyDescriptor newGenericDescriptor(final boolean configurable, final boolean enumerable) {
|
||||||
return new GenericPropertyDescriptor(configurable, enumerable, this);
|
return new GenericPropertyDescriptor(configurable, enumerable, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
|
* Create a new ECMAScript DatePropertyDescriptor object.
|
||||||
|
*
|
||||||
|
* @param value of the data property
|
||||||
|
* @param configurable is the property configurable?
|
||||||
|
* @param enumerable is the property enumerable?
|
||||||
|
* @return newly created DataPropertyDescriptor object
|
||||||
|
*/
|
||||||
public PropertyDescriptor newDataDescriptor(final Object value, final boolean configurable, final boolean enumerable, final boolean writable) {
|
public PropertyDescriptor newDataDescriptor(final Object value, final boolean configurable, final boolean enumerable, final boolean writable) {
|
||||||
return new DataPropertyDescriptor(configurable, enumerable, writable, value, this);
|
return new DataPropertyDescriptor(configurable, enumerable, writable, value, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
|
* Create a new ECMAScript AccessorPropertyDescriptor object.
|
||||||
|
*
|
||||||
|
* @param get getter function of the user accessor property
|
||||||
|
* @param set setter function of the user accessor property
|
||||||
|
* @param configurable is the property configurable?
|
||||||
|
* @param enumerable is the property enumerable?
|
||||||
|
* @return newly created AccessorPropertyDescriptor object
|
||||||
|
*/
|
||||||
public PropertyDescriptor newAccessorDescriptor(final Object get, final Object set, final boolean configurable, final boolean enumerable) {
|
public PropertyDescriptor newAccessorDescriptor(final Object get, final Object set, final boolean configurable, final boolean enumerable) {
|
||||||
final AccessorPropertyDescriptor desc = new AccessorPropertyDescriptor(configurable, enumerable, get == null ? UNDEFINED : get, set == null ? UNDEFINED : set, this);
|
final AccessorPropertyDescriptor desc = new AccessorPropertyDescriptor(configurable, enumerable, get == null ? UNDEFINED : get, set == null ? UNDEFINED : set, this);
|
||||||
|
|
||||||
@ -664,62 +759,6 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cache for compiled script classes.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("serial")
|
|
||||||
private static class ClassCache extends LinkedHashMap<Source, ClassReference> {
|
|
||||||
private final int size;
|
|
||||||
private final ReferenceQueue<Class<?>> queue;
|
|
||||||
|
|
||||||
ClassCache(int size) {
|
|
||||||
super(size, 0.75f, true);
|
|
||||||
this.size = size;
|
|
||||||
this.queue = new ReferenceQueue<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
void cache(final Source source, final Class<?> clazz) {
|
|
||||||
put(source, new ClassReference(clazz, queue, source));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean removeEldestEntry(final Map.Entry<Source, ClassReference> eldest) {
|
|
||||||
return size() > size;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ClassReference get(Object key) {
|
|
||||||
for (ClassReference ref; (ref = (ClassReference)queue.poll()) != null; ) {
|
|
||||||
remove(ref.source);
|
|
||||||
}
|
|
||||||
return super.get(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class ClassReference extends SoftReference<Class<?>> {
|
|
||||||
private final Source source;
|
|
||||||
|
|
||||||
ClassReference(final Class<?> clazz, final ReferenceQueue<Class<?>> queue, final Source source) {
|
|
||||||
super(clazz, queue);
|
|
||||||
this.source = source;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Class cache management
|
|
||||||
@Override
|
|
||||||
public Class<?> findCachedClass(final Source source) {
|
|
||||||
assert classCache != null : "Class cache used without being initialized";
|
|
||||||
ClassReference ref = classCache.get(source);
|
|
||||||
return ref != null ? ref.get() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void cacheClass(final Source source, final Class<?> clazz) {
|
|
||||||
assert classCache != null : "Class cache used without being initialized";
|
|
||||||
classCache.cache(source, clazz);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static <T> T getLazilyCreatedValue(final Object key, final Callable<T> creator, final Map<Object, T> map) {
|
private static <T> T getLazilyCreatedValue(final Object key, final Callable<T> creator, final Map<Object, T> map) {
|
||||||
final T obj = map.get(key);
|
final T obj = map.get(key);
|
||||||
if (obj != null) {
|
if (obj != null) {
|
||||||
@ -737,14 +776,25 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
|||||||
|
|
||||||
private final Map<Object, InvokeByName> namedInvokers = new ConcurrentHashMap<>();
|
private final Map<Object, InvokeByName> namedInvokers = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@Override
|
|
||||||
|
/**
|
||||||
|
* Get cached InvokeByName object for the given key
|
||||||
|
* @param key key to be associated with InvokeByName object
|
||||||
|
* @param creator if InvokeByName is absent 'creator' is called to make one (lazy init)
|
||||||
|
* @return InvokeByName object associated with the key.
|
||||||
|
*/
|
||||||
public InvokeByName getInvokeByName(final Object key, final Callable<InvokeByName> creator) {
|
public InvokeByName getInvokeByName(final Object key, final Callable<InvokeByName> creator) {
|
||||||
return getLazilyCreatedValue(key, creator, namedInvokers);
|
return getLazilyCreatedValue(key, creator, namedInvokers);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Map<Object, MethodHandle> dynamicInvokers = new ConcurrentHashMap<>();
|
private final Map<Object, MethodHandle> dynamicInvokers = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
|
* Get cached dynamic method handle for the given key
|
||||||
|
* @param key key to be associated with dynamic method handle
|
||||||
|
* @param creator if method handle is absent 'creator' is called to make one (lazy init)
|
||||||
|
* @return dynamic method handle associated with the key.
|
||||||
|
*/
|
||||||
public MethodHandle getDynamicInvoker(final Object key, final Callable<MethodHandle> creator) {
|
public MethodHandle getDynamicInvoker(final Object key, final Callable<MethodHandle> creator) {
|
||||||
return getLazilyCreatedValue(key, creator, dynamicInvokers);
|
return getLazilyCreatedValue(key, creator, dynamicInvokers);
|
||||||
}
|
}
|
||||||
@ -933,6 +983,10 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
|||||||
return ScriptFunction.getPrototype(builtinArrayBuffer);
|
return ScriptFunction.getPrototype(builtinArrayBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ScriptObject getDataViewPrototype() {
|
||||||
|
return ScriptFunction.getPrototype(builtinDataView);
|
||||||
|
}
|
||||||
|
|
||||||
ScriptObject getInt8ArrayPrototype() {
|
ScriptObject getInt8ArrayPrototype() {
|
||||||
return ScriptFunction.getPrototype(builtinInt8Array);
|
return ScriptFunction.getPrototype(builtinInt8Array);
|
||||||
}
|
}
|
||||||
@ -1701,6 +1755,7 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
|||||||
|
|
||||||
private void initTypedArray() {
|
private void initTypedArray() {
|
||||||
this.builtinArrayBuffer = initConstructor("ArrayBuffer");
|
this.builtinArrayBuffer = initConstructor("ArrayBuffer");
|
||||||
|
this.builtinDataView = initConstructor("DataView");
|
||||||
this.builtinInt8Array = initConstructor("Int8Array");
|
this.builtinInt8Array = initConstructor("Int8Array");
|
||||||
this.builtinUint8Array = initConstructor("Uint8Array");
|
this.builtinUint8Array = initConstructor("Uint8Array");
|
||||||
this.builtinUint8ClampedArray = initConstructor("Uint8ClampedArray");
|
this.builtinUint8ClampedArray = initConstructor("Uint8ClampedArray");
|
||||||
@ -1741,6 +1796,7 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
|||||||
this.typeError = this.builtinTypeError;
|
this.typeError = this.builtinTypeError;
|
||||||
this.uriError = this.builtinURIError;
|
this.uriError = this.builtinURIError;
|
||||||
this.arrayBuffer = this.builtinArrayBuffer;
|
this.arrayBuffer = this.builtinArrayBuffer;
|
||||||
|
this.dataView = this.builtinDataView;
|
||||||
this.int8Array = this.builtinInt8Array;
|
this.int8Array = this.builtinInt8Array;
|
||||||
this.uint8Array = this.builtinUint8Array;
|
this.uint8Array = this.builtinUint8Array;
|
||||||
this.uint8ClampedArray = this.builtinUint8ClampedArray;
|
this.uint8ClampedArray = this.builtinUint8ClampedArray;
|
||||||
@ -1838,7 +1894,7 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
|||||||
anon.deleteOwnProperty(anon.getMap().findProperty("prototype"));
|
anon.deleteOwnProperty(anon.getMap().findProperty("prototype"));
|
||||||
|
|
||||||
// use "getter" so that [[ThrowTypeError]] function's arity is 0 - as specified in step 10 of section 13.2.3
|
// use "getter" so that [[ThrowTypeError]] function's arity is 0 - as specified in step 10 of section 13.2.3
|
||||||
this.typeErrorThrower = new ScriptFunctionImpl("TypeErrorThrower", Lookup.TYPE_ERROR_THROWER_GETTER, null, null, false, false, false);
|
this.typeErrorThrower = new ScriptFunctionImpl("TypeErrorThrower", Lookup.TYPE_ERROR_THROWER_GETTER, null, null, 0);
|
||||||
typeErrorThrower.setPrototype(UNDEFINED);
|
typeErrorThrower.setPrototype(UNDEFINED);
|
||||||
// Non-constructor built-in functions do not have "prototype" property
|
// Non-constructor built-in functions do not have "prototype" property
|
||||||
typeErrorThrower.deleteOwnProperty(typeErrorThrower.getMap().findProperty("prototype"));
|
typeErrorThrower.deleteOwnProperty(typeErrorThrower.getMap().findProperty("prototype"));
|
||||||
|
@ -156,10 +156,6 @@ public final class NativeArray extends ScriptObject {
|
|||||||
// initialized by nasgen
|
// initialized by nasgen
|
||||||
private static PropertyMap $nasgenmap$;
|
private static PropertyMap $nasgenmap$;
|
||||||
|
|
||||||
static PropertyMap getInitialMap() {
|
|
||||||
return $nasgenmap$;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Constructors.
|
* Constructors.
|
||||||
*/
|
*/
|
||||||
@ -208,7 +204,7 @@ public final class NativeArray extends ScriptObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
NativeArray(final ArrayData arrayData, final Global global) {
|
NativeArray(final ArrayData arrayData, final Global global) {
|
||||||
super(global.getArrayPrototype(), getInitialMap());
|
super(global.getArrayPrototype(), $nasgenmap$);
|
||||||
this.setArray(arrayData);
|
this.setArray(arrayData);
|
||||||
this.setIsArray();
|
this.setIsArray();
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
package jdk.nashorn.internal.objects;
|
package jdk.nashorn.internal.objects;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import jdk.nashorn.internal.objects.annotations.Attribute;
|
import jdk.nashorn.internal.objects.annotations.Attribute;
|
||||||
import jdk.nashorn.internal.objects.annotations.Constructor;
|
import jdk.nashorn.internal.objects.annotations.Constructor;
|
||||||
@ -43,10 +44,6 @@ final class NativeArrayBuffer extends ScriptObject {
|
|||||||
// initialized by nasgen
|
// initialized by nasgen
|
||||||
private static PropertyMap $nasgenmap$;
|
private static PropertyMap $nasgenmap$;
|
||||||
|
|
||||||
static PropertyMap getInitialMap() {
|
|
||||||
return $nasgenmap$;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Constructor(arity = 1)
|
@Constructor(arity = 1)
|
||||||
public static Object constructor(final boolean newObj, final Object self, final Object... args) {
|
public static Object constructor(final boolean newObj, final Object self, final Object... args) {
|
||||||
if (args.length == 0) {
|
if (args.length == 0) {
|
||||||
@ -57,7 +54,7 @@ final class NativeArrayBuffer extends ScriptObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected NativeArrayBuffer(final byte[] byteArray, final Global global) {
|
protected NativeArrayBuffer(final byte[] byteArray, final Global global) {
|
||||||
super(global.getArrayBufferPrototype(), getInitialMap());
|
super(global.getArrayBufferPrototype(), $nasgenmap$);
|
||||||
this.buffer = byteArray;
|
this.buffer = byteArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,4 +125,16 @@ final class NativeArrayBuffer extends ScriptObject {
|
|||||||
public int getByteLength() {
|
public int getByteLength() {
|
||||||
return buffer.length;
|
return buffer.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ByteBuffer getBuffer() {
|
||||||
|
return ByteBuffer.wrap(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteBuffer getBuffer(final int offset) {
|
||||||
|
return ByteBuffer.wrap(buffer, offset, buffer.length - offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteBuffer getBuffer(final int offset, final int length) {
|
||||||
|
return ByteBuffer.wrap(buffer, offset, length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ import static jdk.nashorn.internal.lookup.Lookup.MH;
|
|||||||
|
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.invoke.MethodType;
|
||||||
import jdk.internal.dynalink.linker.GuardedInvocation;
|
import jdk.internal.dynalink.linker.GuardedInvocation;
|
||||||
import jdk.internal.dynalink.linker.LinkRequest;
|
import jdk.internal.dynalink.linker.LinkRequest;
|
||||||
import jdk.nashorn.internal.objects.annotations.Attribute;
|
import jdk.nashorn.internal.objects.annotations.Attribute;
|
||||||
@ -50,22 +51,21 @@ import jdk.nashorn.internal.runtime.linker.PrimitiveLookup;
|
|||||||
public final class NativeBoolean extends ScriptObject {
|
public final class NativeBoolean extends ScriptObject {
|
||||||
private final boolean value;
|
private final boolean value;
|
||||||
|
|
||||||
final static MethodHandle WRAPFILTER = findWrapFilter();
|
// Method handle to create an object wrapper for a primitive boolean
|
||||||
|
private static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", MH.type(NativeBoolean.class, Object.class));
|
||||||
|
// Method handle to retrieve the Boolean prototype object
|
||||||
|
private static final MethodHandle PROTOFILTER = findOwnMH("protoFilter", MH.type(Object.class, Object.class));
|
||||||
|
|
||||||
// initialized by nasgen
|
// initialized by nasgen
|
||||||
private static PropertyMap $nasgenmap$;
|
private static PropertyMap $nasgenmap$;
|
||||||
|
|
||||||
static PropertyMap getInitialMap() {
|
|
||||||
return $nasgenmap$;
|
|
||||||
}
|
|
||||||
|
|
||||||
private NativeBoolean(final boolean value, final ScriptObject proto, final PropertyMap map) {
|
private NativeBoolean(final boolean value, final ScriptObject proto, final PropertyMap map) {
|
||||||
super(proto, map);
|
super(proto, map);
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
NativeBoolean(final boolean flag, final Global global) {
|
NativeBoolean(final boolean flag, final Global global) {
|
||||||
this(flag, global.getBooleanPrototype(), getInitialMap());
|
this(flag, global.getBooleanPrototype(), $nasgenmap$);
|
||||||
}
|
}
|
||||||
|
|
||||||
NativeBoolean(final boolean flag) {
|
NativeBoolean(final boolean flag) {
|
||||||
@ -164,7 +164,7 @@ public final class NativeBoolean extends ScriptObject {
|
|||||||
* @return Link to be invoked at call site.
|
* @return Link to be invoked at call site.
|
||||||
*/
|
*/
|
||||||
public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Object receiver) {
|
public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Object receiver) {
|
||||||
return PrimitiveLookup.lookupPrimitive(request, Boolean.class, new NativeBoolean((Boolean)receiver), WRAPFILTER);
|
return PrimitiveLookup.lookupPrimitive(request, Boolean.class, new NativeBoolean((Boolean)receiver), WRAPFILTER, PROTOFILTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -178,7 +178,12 @@ public final class NativeBoolean extends ScriptObject {
|
|||||||
return new NativeBoolean((Boolean)receiver);
|
return new NativeBoolean((Boolean)receiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MethodHandle findWrapFilter() {
|
@SuppressWarnings("unused")
|
||||||
return MH.findStatic(MethodHandles.lookup(), NativeBoolean.class, "wrapFilter", MH.type(NativeBoolean.class, Object.class));
|
private static Object protoFilter(final Object object) {
|
||||||
|
return Global.instance().getBooleanPrototype();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MethodHandle findOwnMH(final String name, final MethodType type) {
|
||||||
|
return MH.findStatic(MethodHandles.lookup(), NativeBoolean.class, name, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1015
nashorn/src/jdk/nashorn/internal/objects/NativeDataView.java
Normal file
1015
nashorn/src/jdk/nashorn/internal/objects/NativeDataView.java
Normal file
File diff suppressed because it is too large
Load Diff
@ -114,10 +114,6 @@ public final class NativeDate extends ScriptObject {
|
|||||||
// initialized by nasgen
|
// initialized by nasgen
|
||||||
private static PropertyMap $nasgenmap$;
|
private static PropertyMap $nasgenmap$;
|
||||||
|
|
||||||
static PropertyMap getInitialMap() {
|
|
||||||
return $nasgenmap$;
|
|
||||||
}
|
|
||||||
|
|
||||||
private NativeDate(final double time, final ScriptObject proto, final PropertyMap map) {
|
private NativeDate(final double time, final ScriptObject proto, final PropertyMap map) {
|
||||||
super(proto, map);
|
super(proto, map);
|
||||||
final ScriptEnvironment env = Global.getEnv();
|
final ScriptEnvironment env = Global.getEnv();
|
||||||
@ -127,7 +123,7 @@ public final class NativeDate extends ScriptObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
NativeDate(final double time, final Global global) {
|
NativeDate(final double time, final Global global) {
|
||||||
this(time, global.getDatePrototype(), getInitialMap());
|
this(time, global.getDatePrototype(), $nasgenmap$);
|
||||||
}
|
}
|
||||||
|
|
||||||
private NativeDate (final double time) {
|
private NativeDate (final double time) {
|
||||||
|
@ -92,10 +92,6 @@ public final class NativeError extends ScriptObject {
|
|||||||
// initialized by nasgen
|
// initialized by nasgen
|
||||||
private static PropertyMap $nasgenmap$;
|
private static PropertyMap $nasgenmap$;
|
||||||
|
|
||||||
static PropertyMap getInitialMap() {
|
|
||||||
return $nasgenmap$;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("LeakingThisInConstructor")
|
@SuppressWarnings("LeakingThisInConstructor")
|
||||||
private NativeError(final Object msg, final ScriptObject proto, final PropertyMap map) {
|
private NativeError(final Object msg, final ScriptObject proto, final PropertyMap map) {
|
||||||
super(proto, map);
|
super(proto, map);
|
||||||
@ -108,7 +104,7 @@ public final class NativeError extends ScriptObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
NativeError(final Object msg, final Global global) {
|
NativeError(final Object msg, final Global global) {
|
||||||
this(msg, global.getErrorPrototype(), getInitialMap());
|
this(msg, global.getErrorPrototype(), $nasgenmap$);
|
||||||
}
|
}
|
||||||
|
|
||||||
private NativeError(final Object msg) {
|
private NativeError(final Object msg) {
|
||||||
|
@ -62,10 +62,6 @@ public final class NativeEvalError extends ScriptObject {
|
|||||||
// initialized by nasgen
|
// initialized by nasgen
|
||||||
private static PropertyMap $nasgenmap$;
|
private static PropertyMap $nasgenmap$;
|
||||||
|
|
||||||
static PropertyMap getInitialMap() {
|
|
||||||
return $nasgenmap$;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("LeakingThisInConstructor")
|
@SuppressWarnings("LeakingThisInConstructor")
|
||||||
private NativeEvalError(final Object msg, final ScriptObject proto, final PropertyMap map) {
|
private NativeEvalError(final Object msg, final ScriptObject proto, final PropertyMap map) {
|
||||||
super(proto, map);
|
super(proto, map);
|
||||||
@ -78,7 +74,7 @@ public final class NativeEvalError extends ScriptObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
NativeEvalError(final Object msg, final Global global) {
|
NativeEvalError(final Object msg, final Global global) {
|
||||||
this(msg, global.getEvalErrorPrototype(), getInitialMap());
|
this(msg, global.getEvalErrorPrototype(), $nasgenmap$);
|
||||||
}
|
}
|
||||||
|
|
||||||
private NativeEvalError(final Object msg) {
|
private NativeEvalError(final Object msg) {
|
||||||
|
@ -146,10 +146,6 @@ public final class NativeJSAdapter extends ScriptObject {
|
|||||||
// initialized by nasgen
|
// initialized by nasgen
|
||||||
private static PropertyMap $nasgenmap$;
|
private static PropertyMap $nasgenmap$;
|
||||||
|
|
||||||
static PropertyMap getInitialMap() {
|
|
||||||
return $nasgenmap$;
|
|
||||||
}
|
|
||||||
|
|
||||||
NativeJSAdapter(final Object overrides, final ScriptObject adaptee, final ScriptObject proto, final PropertyMap map) {
|
NativeJSAdapter(final Object overrides, final ScriptObject adaptee, final ScriptObject proto, final PropertyMap map) {
|
||||||
super(proto, map);
|
super(proto, map);
|
||||||
this.adaptee = wrapAdaptee(adaptee);
|
this.adaptee = wrapAdaptee(adaptee);
|
||||||
@ -577,7 +573,7 @@ public final class NativeJSAdapter extends ScriptObject {
|
|||||||
proto = global.getJSAdapterPrototype();
|
proto = global.getJSAdapterPrototype();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new NativeJSAdapter(overrides, (ScriptObject)adaptee, (ScriptObject)proto, getInitialMap());
|
return new NativeJSAdapter(overrides, (ScriptObject)adaptee, (ScriptObject)proto, $nasgenmap$);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -622,7 +618,7 @@ public final class NativeJSAdapter extends ScriptObject {
|
|||||||
case "getMethod":
|
case "getMethod":
|
||||||
final FindProperty find = adaptee.findProperty(__call__, true);
|
final FindProperty find = adaptee.findProperty(__call__, true);
|
||||||
if (find != null) {
|
if (find != null) {
|
||||||
final Object value = getObjectValue(find);
|
final Object value = find.getObjectValue();
|
||||||
if (value instanceof ScriptFunction) {
|
if (value instanceof ScriptFunction) {
|
||||||
final ScriptFunctionImpl func = (ScriptFunctionImpl)value;
|
final ScriptFunctionImpl func = (ScriptFunctionImpl)value;
|
||||||
// TODO: It's a shame we need to produce a function bound to this and name, when we'd only need it bound
|
// TODO: It's a shame we need to produce a function bound to this and name, when we'd only need it bound
|
||||||
@ -691,7 +687,7 @@ public final class NativeJSAdapter extends ScriptObject {
|
|||||||
final MethodType type = desc.getMethodType();
|
final MethodType type = desc.getMethodType();
|
||||||
if (findData != null) {
|
if (findData != null) {
|
||||||
final String name = desc.getNameTokenCount() > 2 ? desc.getNameToken(2) : null;
|
final String name = desc.getNameTokenCount() > 2 ? desc.getNameToken(2) : null;
|
||||||
final Object value = getObjectValue(findData);
|
final Object value = findData.getObjectValue();
|
||||||
if (value instanceof ScriptFunction) {
|
if (value instanceof ScriptFunction) {
|
||||||
final ScriptFunction func = (ScriptFunction)value;
|
final ScriptFunction func = (ScriptFunction)value;
|
||||||
|
|
||||||
|
@ -60,17 +60,13 @@ public final class NativeJavaImporter extends ScriptObject {
|
|||||||
// initialized by nasgen
|
// initialized by nasgen
|
||||||
private static PropertyMap $nasgenmap$;
|
private static PropertyMap $nasgenmap$;
|
||||||
|
|
||||||
static PropertyMap getInitialMap() {
|
|
||||||
return $nasgenmap$;
|
|
||||||
}
|
|
||||||
|
|
||||||
private NativeJavaImporter(final Object[] args, final ScriptObject proto, final PropertyMap map) {
|
private NativeJavaImporter(final Object[] args, final ScriptObject proto, final PropertyMap map) {
|
||||||
super(proto, map);
|
super(proto, map);
|
||||||
this.args = args;
|
this.args = args;
|
||||||
}
|
}
|
||||||
|
|
||||||
private NativeJavaImporter(final Object[] args, final Global global) {
|
private NativeJavaImporter(final Object[] args, final Global global) {
|
||||||
this(args, global.getJavaImporterPrototype(), getInitialMap());
|
this(args, global.getJavaImporterPrototype(), $nasgenmap$);
|
||||||
}
|
}
|
||||||
|
|
||||||
private NativeJavaImporter(final Object[] args) {
|
private NativeJavaImporter(final Object[] args) {
|
||||||
|
@ -34,6 +34,7 @@ import static jdk.nashorn.internal.lookup.Lookup.MH;
|
|||||||
|
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.invoke.MethodType;
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import jdk.internal.dynalink.linker.GuardedInvocation;
|
import jdk.internal.dynalink.linker.GuardedInvocation;
|
||||||
@ -57,7 +58,10 @@ import jdk.nashorn.internal.runtime.linker.PrimitiveLookup;
|
|||||||
@ScriptClass("Number")
|
@ScriptClass("Number")
|
||||||
public final class NativeNumber extends ScriptObject {
|
public final class NativeNumber extends ScriptObject {
|
||||||
|
|
||||||
static final MethodHandle WRAPFILTER = findWrapFilter();
|
// Method handle to create an object wrapper for a primitive number
|
||||||
|
private static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", MH.type(NativeNumber.class, Object.class));
|
||||||
|
// Method handle to retrieve the Number prototype object
|
||||||
|
private static final MethodHandle PROTOFILTER = findOwnMH("protoFilter", MH.type(Object.class, Object.class));
|
||||||
|
|
||||||
/** ECMA 15.7.3.2 largest positive finite value */
|
/** ECMA 15.7.3.2 largest positive finite value */
|
||||||
@Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT, where = Where.CONSTRUCTOR)
|
@Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT, where = Where.CONSTRUCTOR)
|
||||||
@ -86,10 +90,6 @@ public final class NativeNumber extends ScriptObject {
|
|||||||
// initialized by nasgen
|
// initialized by nasgen
|
||||||
private static PropertyMap $nasgenmap$;
|
private static PropertyMap $nasgenmap$;
|
||||||
|
|
||||||
static PropertyMap getInitialMap() {
|
|
||||||
return $nasgenmap$;
|
|
||||||
}
|
|
||||||
|
|
||||||
private NativeNumber(final double value, final ScriptObject proto, final PropertyMap map) {
|
private NativeNumber(final double value, final ScriptObject proto, final PropertyMap map) {
|
||||||
super(proto, map);
|
super(proto, map);
|
||||||
this.value = value;
|
this.value = value;
|
||||||
@ -98,7 +98,7 @@ public final class NativeNumber extends ScriptObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
NativeNumber(final double value, final Global global) {
|
NativeNumber(final double value, final Global global) {
|
||||||
this(value, global.getNumberPrototype(), getInitialMap());
|
this(value, global.getNumberPrototype(), $nasgenmap$);
|
||||||
}
|
}
|
||||||
|
|
||||||
private NativeNumber(final double value) {
|
private NativeNumber(final double value) {
|
||||||
@ -322,7 +322,7 @@ public final class NativeNumber extends ScriptObject {
|
|||||||
* @return Link to be invoked at call site.
|
* @return Link to be invoked at call site.
|
||||||
*/
|
*/
|
||||||
public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Object receiver) {
|
public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Object receiver) {
|
||||||
return PrimitiveLookup.lookupPrimitive(request, Number.class, new NativeNumber(((Number)receiver).doubleValue()), WRAPFILTER);
|
return PrimitiveLookup.lookupPrimitive(request, Number.class, new NativeNumber(((Number)receiver).doubleValue()), WRAPFILTER, PROTOFILTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@ -330,6 +330,11 @@ public final class NativeNumber extends ScriptObject {
|
|||||||
return new NativeNumber(((Number)receiver).doubleValue());
|
return new NativeNumber(((Number)receiver).doubleValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private static Object protoFilter(final Object object) {
|
||||||
|
return Global.instance().getNumberPrototype();
|
||||||
|
}
|
||||||
|
|
||||||
private static double getNumberValue(final Object self) {
|
private static double getNumberValue(final Object self) {
|
||||||
if (self instanceof Number) {
|
if (self instanceof Number) {
|
||||||
return ((Number)self).doubleValue();
|
return ((Number)self).doubleValue();
|
||||||
@ -378,7 +383,7 @@ public final class NativeNumber extends ScriptObject {
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MethodHandle findWrapFilter() {
|
private static MethodHandle findOwnMH(final String name, final MethodType type) {
|
||||||
return MH.findStatic(MethodHandles.lookup(), NativeNumber.class, "wrapFilter", MH.type(NativeNumber.class, Object.class));
|
return MH.findStatic(MethodHandles.lookup(), NativeNumber.class, name, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,10 +62,6 @@ public final class NativeRangeError extends ScriptObject {
|
|||||||
// initialized by nasgen
|
// initialized by nasgen
|
||||||
private static PropertyMap $nasgenmap$;
|
private static PropertyMap $nasgenmap$;
|
||||||
|
|
||||||
static PropertyMap getInitialMap() {
|
|
||||||
return $nasgenmap$;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("LeakingThisInConstructor")
|
@SuppressWarnings("LeakingThisInConstructor")
|
||||||
private NativeRangeError(final Object msg, final ScriptObject proto, final PropertyMap map) {
|
private NativeRangeError(final Object msg, final ScriptObject proto, final PropertyMap map) {
|
||||||
super(proto, map);
|
super(proto, map);
|
||||||
@ -78,7 +74,7 @@ public final class NativeRangeError extends ScriptObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
NativeRangeError(final Object msg, final Global global) {
|
NativeRangeError(final Object msg, final Global global) {
|
||||||
this(msg, global.getRangeErrorPrototype(), getInitialMap());
|
this(msg, global.getRangeErrorPrototype(), $nasgenmap$);
|
||||||
}
|
}
|
||||||
|
|
||||||
private NativeRangeError(final Object msg) {
|
private NativeRangeError(final Object msg) {
|
||||||
|
@ -62,10 +62,6 @@ public final class NativeReferenceError extends ScriptObject {
|
|||||||
// initialized by nasgen
|
// initialized by nasgen
|
||||||
private static PropertyMap $nasgenmap$;
|
private static PropertyMap $nasgenmap$;
|
||||||
|
|
||||||
static PropertyMap getInitialMap() {
|
|
||||||
return $nasgenmap$;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("LeakingThisInConstructor")
|
@SuppressWarnings("LeakingThisInConstructor")
|
||||||
private NativeReferenceError(final Object msg, final ScriptObject proto, final PropertyMap map) {
|
private NativeReferenceError(final Object msg, final ScriptObject proto, final PropertyMap map) {
|
||||||
super(proto, map);
|
super(proto, map);
|
||||||
@ -78,7 +74,7 @@ public final class NativeReferenceError extends ScriptObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
NativeReferenceError(final Object msg, final Global global) {
|
NativeReferenceError(final Object msg, final Global global) {
|
||||||
this(msg, global.getReferenceErrorPrototype(), getInitialMap());
|
this(msg, global.getReferenceErrorPrototype(), $nasgenmap$);
|
||||||
}
|
}
|
||||||
|
|
||||||
private NativeReferenceError(final Object msg) {
|
private NativeReferenceError(final Object msg) {
|
||||||
|
@ -70,12 +70,8 @@ public final class NativeRegExp extends ScriptObject {
|
|||||||
// initialized by nasgen
|
// initialized by nasgen
|
||||||
private static PropertyMap $nasgenmap$;
|
private static PropertyMap $nasgenmap$;
|
||||||
|
|
||||||
static PropertyMap getInitialMap() {
|
|
||||||
return $nasgenmap$;
|
|
||||||
}
|
|
||||||
|
|
||||||
private NativeRegExp(final Global global) {
|
private NativeRegExp(final Global global) {
|
||||||
super(global.getRegExpPrototype(), getInitialMap());
|
super(global.getRegExpPrototype(), $nasgenmap$);
|
||||||
this.globalObject = global;
|
this.globalObject = global;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,12 +53,8 @@ public final class NativeRegExpExecResult extends ScriptObject {
|
|||||||
// initialized by nasgen
|
// initialized by nasgen
|
||||||
private static PropertyMap $nasgenmap$;
|
private static PropertyMap $nasgenmap$;
|
||||||
|
|
||||||
static PropertyMap getInitialMap() {
|
|
||||||
return $nasgenmap$;
|
|
||||||
}
|
|
||||||
|
|
||||||
NativeRegExpExecResult(final RegExpResult result, final Global global) {
|
NativeRegExpExecResult(final RegExpResult result, final Global global) {
|
||||||
super(global.getArrayPrototype(), getInitialMap());
|
super(global.getArrayPrototype(), $nasgenmap$);
|
||||||
setIsArray();
|
setIsArray();
|
||||||
this.setArray(ArrayData.allocate(result.getGroups().clone()));
|
this.setArray(ArrayData.allocate(result.getGroups().clone()));
|
||||||
this.index = result.getIndex();
|
this.index = result.getIndex();
|
||||||
|
@ -32,6 +32,7 @@ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
|
|||||||
|
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.invoke.MethodType;
|
||||||
import java.text.Collator;
|
import java.text.Collator;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -69,21 +70,20 @@ public final class NativeString extends ScriptObject {
|
|||||||
|
|
||||||
private final CharSequence value;
|
private final CharSequence value;
|
||||||
|
|
||||||
static final MethodHandle WRAPFILTER = findWrapFilter();
|
// Method handle to create an object wrapper for a primitive string
|
||||||
|
private static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", MH.type(NativeString.class, Object.class));
|
||||||
|
// Method handle to retrieve the String prototype object
|
||||||
|
private static final MethodHandle PROTOFILTER = findOwnMH("protoFilter", MH.type(Object.class, Object.class));
|
||||||
|
|
||||||
// initialized by nasgen
|
// initialized by nasgen
|
||||||
private static PropertyMap $nasgenmap$;
|
private static PropertyMap $nasgenmap$;
|
||||||
|
|
||||||
static PropertyMap getInitialMap() {
|
|
||||||
return $nasgenmap$;
|
|
||||||
}
|
|
||||||
|
|
||||||
private NativeString(final CharSequence value) {
|
private NativeString(final CharSequence value) {
|
||||||
this(value, Global.instance());
|
this(value, Global.instance());
|
||||||
}
|
}
|
||||||
|
|
||||||
NativeString(final CharSequence value, final Global global) {
|
NativeString(final CharSequence value, final Global global) {
|
||||||
this(value, global.getStringPrototype(), getInitialMap());
|
this(value, global.getStringPrototype(), $nasgenmap$);
|
||||||
}
|
}
|
||||||
|
|
||||||
private NativeString(final CharSequence value, final ScriptObject proto, final PropertyMap map) {
|
private NativeString(final CharSequence value, final ScriptObject proto, final PropertyMap map) {
|
||||||
@ -1199,7 +1199,7 @@ public final class NativeString extends ScriptObject {
|
|||||||
*/
|
*/
|
||||||
public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Object receiver) {
|
public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Object receiver) {
|
||||||
final MethodHandle guard = NashornGuards.getInstanceOf2Guard(String.class, ConsString.class);
|
final MethodHandle guard = NashornGuards.getInstanceOf2Guard(String.class, ConsString.class);
|
||||||
return PrimitiveLookup.lookupPrimitive(request, guard, new NativeString((CharSequence)receiver), WRAPFILTER);
|
return PrimitiveLookup.lookupPrimitive(request, guard, new NativeString((CharSequence)receiver), WRAPFILTER, PROTOFILTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@ -1207,6 +1207,11 @@ public final class NativeString extends ScriptObject {
|
|||||||
return new NativeString((CharSequence)receiver);
|
return new NativeString((CharSequence)receiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private static Object protoFilter(final Object object) {
|
||||||
|
return Global.instance().getStringPrototype();
|
||||||
|
}
|
||||||
|
|
||||||
private static CharSequence getCharSequence(final Object self) {
|
private static CharSequence getCharSequence(final Object self) {
|
||||||
if (self instanceof String || self instanceof ConsString) {
|
if (self instanceof String || self instanceof ConsString) {
|
||||||
return (CharSequence)self;
|
return (CharSequence)self;
|
||||||
@ -1254,7 +1259,7 @@ public final class NativeString extends ScriptObject {
|
|||||||
return key >= 0 && key < value.length();
|
return key >= 0 && key < value.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MethodHandle findWrapFilter() {
|
private static MethodHandle findOwnMH(final String name, final MethodType type) {
|
||||||
return MH.findStatic(MethodHandles.lookup(), NativeString.class, "wrapFilter", MH.type(NativeString.class, Object.class));
|
return MH.findStatic(MethodHandles.lookup(), NativeString.class, name, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,13 +62,9 @@ public final class NativeSyntaxError extends ScriptObject {
|
|||||||
// initialized by nasgen
|
// initialized by nasgen
|
||||||
private static PropertyMap $nasgenmap$;
|
private static PropertyMap $nasgenmap$;
|
||||||
|
|
||||||
static PropertyMap getInitialMap() {
|
|
||||||
return $nasgenmap$;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("LeakingThisInConstructor")
|
@SuppressWarnings("LeakingThisInConstructor")
|
||||||
NativeSyntaxError(final Object msg, final Global global) {
|
NativeSyntaxError(final Object msg, final Global global) {
|
||||||
super(global.getSyntaxErrorPrototype(), getInitialMap());
|
super(global.getSyntaxErrorPrototype(), $nasgenmap$);
|
||||||
if (msg != UNDEFINED) {
|
if (msg != UNDEFINED) {
|
||||||
this.instMessage = JSType.toString(msg);
|
this.instMessage = JSType.toString(msg);
|
||||||
} else {
|
} else {
|
||||||
|
@ -62,13 +62,9 @@ public final class NativeTypeError extends ScriptObject {
|
|||||||
// initialized by nasgen
|
// initialized by nasgen
|
||||||
private static PropertyMap $nasgenmap$;
|
private static PropertyMap $nasgenmap$;
|
||||||
|
|
||||||
static PropertyMap getInitialMap() {
|
|
||||||
return $nasgenmap$;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("LeakingThisInConstructor")
|
@SuppressWarnings("LeakingThisInConstructor")
|
||||||
NativeTypeError(final Object msg, final Global global) {
|
NativeTypeError(final Object msg, final Global global) {
|
||||||
super(global.getTypeErrorPrototype(), getInitialMap());
|
super(global.getTypeErrorPrototype(), $nasgenmap$);
|
||||||
if (msg != UNDEFINED) {
|
if (msg != UNDEFINED) {
|
||||||
this.instMessage = JSType.toString(msg);
|
this.instMessage = JSType.toString(msg);
|
||||||
} else {
|
} else {
|
||||||
|
@ -61,13 +61,9 @@ public final class NativeURIError extends ScriptObject {
|
|||||||
// initialized by nasgen
|
// initialized by nasgen
|
||||||
private static PropertyMap $nasgenmap$;
|
private static PropertyMap $nasgenmap$;
|
||||||
|
|
||||||
static PropertyMap getInitialMap() {
|
|
||||||
return $nasgenmap$;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("LeakingThisInConstructor")
|
@SuppressWarnings("LeakingThisInConstructor")
|
||||||
NativeURIError(final Object msg, final Global global) {
|
NativeURIError(final Object msg, final Global global) {
|
||||||
super(global.getURIErrorPrototype(), getInitialMap());
|
super(global.getURIErrorPrototype(), $nasgenmap$);
|
||||||
if (msg != UNDEFINED) {
|
if (msg != UNDEFINED) {
|
||||||
this.instMessage = JSType.toString(msg);
|
this.instMessage = JSType.toString(msg);
|
||||||
} else {
|
} else {
|
||||||
|
@ -57,10 +57,6 @@ public class PrototypeObject extends ScriptObject {
|
|||||||
map$ = PropertyMap.newMap(properties);
|
map$ = PropertyMap.newMap(properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PropertyMap getInitialMap() {
|
|
||||||
return map$;
|
|
||||||
}
|
|
||||||
|
|
||||||
private PrototypeObject(final Global global, final PropertyMap map) {
|
private PrototypeObject(final Global global, final PropertyMap map) {
|
||||||
super(global.getObjectPrototype(), map != map$? map.addAll(map$) : map$);
|
super(global.getObjectPrototype(), map != map$? map.addAll(map$) : map$);
|
||||||
}
|
}
|
||||||
|
@ -55,27 +55,11 @@ public class ScriptFunctionImpl extends ScriptFunction {
|
|||||||
// property map for non-strict, non-bound functions.
|
// property map for non-strict, non-bound functions.
|
||||||
private static final PropertyMap map$;
|
private static final PropertyMap map$;
|
||||||
|
|
||||||
static PropertyMap getInitialMap() {
|
|
||||||
return map$;
|
|
||||||
}
|
|
||||||
|
|
||||||
static PropertyMap getInitialAnonymousMap() {
|
|
||||||
return AnonymousFunction.getInitialMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
static PropertyMap getInitialStrictMap() {
|
|
||||||
return strictmodemap$;
|
|
||||||
}
|
|
||||||
|
|
||||||
static PropertyMap getInitialBoundMap() {
|
|
||||||
return boundfunctionmap$;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Marker object for lazily initialized prototype object
|
// Marker object for lazily initialized prototype object
|
||||||
private static final Object LAZY_PROTOTYPE = new Object();
|
private static final Object LAZY_PROTOTYPE = new Object();
|
||||||
|
|
||||||
private ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final MethodHandle[] specs, final Global global) {
|
private ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final MethodHandle[] specs, final Global global) {
|
||||||
super(name, invokeHandle, getInitialMap(), null, specs, false, true, true);
|
super(name, invokeHandle, map$, null, specs, ScriptFunctionData.IS_BUILTIN_CONSTRUCTOR);
|
||||||
init(global);
|
init(global);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,7 +76,7 @@ public class ScriptFunctionImpl extends ScriptFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final PropertyMap map, final MethodHandle[] specs, final Global global) {
|
private ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final PropertyMap map, final MethodHandle[] specs, final Global global) {
|
||||||
super(name, invokeHandle, map.addAll(getInitialMap()), null, specs, false, true, true);
|
super(name, invokeHandle, map.addAll(map$), null, specs, ScriptFunctionData.IS_BUILTIN_CONSTRUCTOR);
|
||||||
init(global);
|
init(global);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,8 +93,8 @@ public class ScriptFunctionImpl extends ScriptFunction {
|
|||||||
this(name, invokeHandle, map, specs, Global.instance());
|
this(name, invokeHandle, map, specs, Global.instance());
|
||||||
}
|
}
|
||||||
|
|
||||||
private ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final MethodHandle[] specs, final boolean isStrict, final boolean isBuiltin, final boolean isConstructor, final Global global) {
|
private ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final MethodHandle[] specs, final int flags, final Global global) {
|
||||||
super(name, methodHandle, getMap(global, isStrict), scope, specs, isStrict, isBuiltin, isConstructor);
|
super(name, methodHandle, getMap(isStrict(flags)), scope, specs, flags);
|
||||||
init(global);
|
init(global);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,16 +105,14 @@ public class ScriptFunctionImpl extends ScriptFunction {
|
|||||||
* @param methodHandle handle for invocation
|
* @param methodHandle handle for invocation
|
||||||
* @param scope scope object
|
* @param scope scope object
|
||||||
* @param specs specialized versions of this method, if available, null otherwise
|
* @param specs specialized versions of this method, if available, null otherwise
|
||||||
* @param isStrict are we in strict mode
|
* @param flags {@link ScriptFunctionData} flags
|
||||||
* @param isBuiltin is this a built-in function
|
|
||||||
* @param isConstructor can the function be used as a constructor (most can; some built-ins are restricted).
|
|
||||||
*/
|
*/
|
||||||
ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final MethodHandle[] specs, final boolean isStrict, final boolean isBuiltin, final boolean isConstructor) {
|
ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final MethodHandle[] specs, final int flags) {
|
||||||
this(name, methodHandle, scope, specs, isStrict, isBuiltin, isConstructor, Global.instance());
|
this(name, methodHandle, scope, specs, flags, Global.instance());
|
||||||
}
|
}
|
||||||
|
|
||||||
private ScriptFunctionImpl(final RecompilableScriptFunctionData data, final ScriptObject scope, final Global global) {
|
private ScriptFunctionImpl(final RecompilableScriptFunctionData data, final ScriptObject scope, final Global global) {
|
||||||
super(data, getMap(global, data.isStrict()), scope);
|
super(data, getMap(data.isStrict()), scope);
|
||||||
init(global);
|
init(global);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +132,7 @@ public class ScriptFunctionImpl extends ScriptFunction {
|
|||||||
* @param global the global object
|
* @param global the global object
|
||||||
*/
|
*/
|
||||||
ScriptFunctionImpl(final ScriptFunctionData data, final Global global) {
|
ScriptFunctionImpl(final ScriptFunctionData data, final Global global) {
|
||||||
super(data, getInitialBoundMap(), null);
|
super(data, boundfunctionmap$, null);
|
||||||
init(global);
|
init(global);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,9 +155,13 @@ public class ScriptFunctionImpl extends ScriptFunction {
|
|||||||
return newMap;
|
return newMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isStrict(final int flags) {
|
||||||
|
return (flags & ScriptFunctionData.IS_STRICT) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Choose the map based on strict mode!
|
// Choose the map based on strict mode!
|
||||||
private static PropertyMap getMap(final Global global, final boolean strict) {
|
private static PropertyMap getMap(final boolean strict) {
|
||||||
return strict ? getInitialStrictMap() : getInitialMap();
|
return strict ? strictmodemap$ : map$;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PropertyMap createBoundFunctionMap(final PropertyMap strictModeMap) {
|
private static PropertyMap createBoundFunctionMap(final PropertyMap strictModeMap) {
|
||||||
@ -189,12 +175,8 @@ public class ScriptFunctionImpl extends ScriptFunction {
|
|||||||
private static class AnonymousFunction extends ScriptFunctionImpl {
|
private static class AnonymousFunction extends ScriptFunctionImpl {
|
||||||
private static final PropertyMap anonmap$ = PropertyMap.newMap();
|
private static final PropertyMap anonmap$ = PropertyMap.newMap();
|
||||||
|
|
||||||
static PropertyMap getInitialMap() {
|
|
||||||
return anonmap$;
|
|
||||||
}
|
|
||||||
|
|
||||||
AnonymousFunction(final Global global) {
|
AnonymousFunction(final Global global) {
|
||||||
super("", GlobalFunctions.ANONYMOUS, getInitialAnonymousMap(), null);
|
super("", GlobalFunctions.ANONYMOUS, anonmap$, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,7 +193,7 @@ public class ScriptFunctionImpl extends ScriptFunction {
|
|||||||
* @return new ScriptFunction
|
* @return new ScriptFunction
|
||||||
*/
|
*/
|
||||||
static ScriptFunction makeFunction(final String name, final MethodHandle methodHandle, final MethodHandle[] specs) {
|
static ScriptFunction makeFunction(final String name, final MethodHandle methodHandle, final MethodHandle[] specs) {
|
||||||
final ScriptFunctionImpl func = new ScriptFunctionImpl(name, methodHandle, null, specs, false, true, false);
|
final ScriptFunctionImpl func = new ScriptFunctionImpl(name, methodHandle, null, specs, ScriptFunctionData.IS_BUILTIN);
|
||||||
func.setPrototype(UNDEFINED);
|
func.setPrototype(UNDEFINED);
|
||||||
// Non-constructor built-in functions do not have "prototype" property
|
// Non-constructor built-in functions do not have "prototype" property
|
||||||
func.deleteOwnProperty(func.getMap().findProperty("prototype"));
|
func.deleteOwnProperty(func.getMap().findProperty("prototype"));
|
||||||
|
@ -1799,6 +1799,7 @@ loop:
|
|||||||
case THIS:
|
case THIS:
|
||||||
final String name = type.getName();
|
final String name = type.getName();
|
||||||
next();
|
next();
|
||||||
|
lc.setFlag(lc.getCurrentFunction(), FunctionNode.USES_THIS);
|
||||||
return new IdentNode(primaryToken, finish, name);
|
return new IdentNode(primaryToken, finish, name);
|
||||||
case IDENT:
|
case IDENT:
|
||||||
final IdentNode ident = getIdent();
|
final IdentNode ident = getIdent();
|
||||||
|
@ -141,10 +141,12 @@ public final class AccessorProperty extends Property {
|
|||||||
private Class<?> currentType;
|
private Class<?> currentType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delegate constructor. This is used when adding properties to the Global scope, which
|
* Delegate constructor for bound properties. This is used for properties created by
|
||||||
* is necessary for outermost levels in a script (the ScriptObject is represented by
|
* {@link ScriptRuntime#mergeScope} and the Nashorn {@code Object.bindProperties} method.
|
||||||
* a JO-prefixed ScriptObject class, but the properties need to be in the Global scope
|
* The former is used to add a script's defined globals to the current global scope while
|
||||||
* and are thus rebound with that as receiver
|
* still storing them in a JO-prefixed ScriptObject class.
|
||||||
|
*
|
||||||
|
* <p>All properties created by this constructor have the {@link #IS_BOUND} flag set.</p>
|
||||||
*
|
*
|
||||||
* @param property accessor property to rebind
|
* @param property accessor property to rebind
|
||||||
* @param delegate delegate object to rebind receiver to
|
* @param delegate delegate object to rebind receiver to
|
||||||
@ -157,6 +159,8 @@ public final class AccessorProperty extends Property {
|
|||||||
this.objectGetter = bindTo(property.ensureObjectGetter(), delegate);
|
this.objectGetter = bindTo(property.ensureObjectGetter(), delegate);
|
||||||
this.objectSetter = bindTo(property.ensureObjectSetter(), delegate);
|
this.objectSetter = bindTo(property.ensureObjectSetter(), delegate);
|
||||||
|
|
||||||
|
// Properties created this way are bound to a delegate
|
||||||
|
this.flags |= IS_BOUND;
|
||||||
setCurrentType(property.getCurrentType());
|
setCurrentType(property.getCurrentType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +36,8 @@ import java.io.IOException;
|
|||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.ref.ReferenceQueue;
|
||||||
|
import java.lang.ref.SoftReference;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
@ -46,6 +48,7 @@ import java.security.CodeSource;
|
|||||||
import java.security.Permissions;
|
import java.security.Permissions;
|
||||||
import java.security.PrivilegedAction;
|
import java.security.PrivilegedAction;
|
||||||
import java.security.ProtectionDomain;
|
import java.security.ProtectionDomain;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import jdk.internal.org.objectweb.asm.ClassReader;
|
import jdk.internal.org.objectweb.asm.ClassReader;
|
||||||
@ -153,16 +156,19 @@ public final class Context {
|
|||||||
/** Is Context global debug mode enabled ? */
|
/** Is Context global debug mode enabled ? */
|
||||||
public static final boolean DEBUG = Options.getBooleanProperty("nashorn.debug");
|
public static final boolean DEBUG = Options.getBooleanProperty("nashorn.debug");
|
||||||
|
|
||||||
private static final ThreadLocal<ScriptObject> currentGlobal = new ThreadLocal<>();
|
private static final ThreadLocal<Global> currentGlobal = new ThreadLocal<>();
|
||||||
|
|
||||||
|
// class cache
|
||||||
|
private ClassCache classCache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current global scope
|
* Get the current global scope
|
||||||
* @return the current global scope
|
* @return the current global scope
|
||||||
*/
|
*/
|
||||||
public static ScriptObject getGlobal() {
|
public static Global getGlobal() {
|
||||||
// This class in a package.access protected package.
|
// This class in a package.access protected package.
|
||||||
// Trusted code only can call this method.
|
// Trusted code only can call this method.
|
||||||
return getGlobalTrusted();
|
return currentGlobal.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -171,10 +177,19 @@ public final class Context {
|
|||||||
*/
|
*/
|
||||||
public static void setGlobal(final ScriptObject global) {
|
public static void setGlobal(final ScriptObject global) {
|
||||||
if (global != null && !(global instanceof Global)) {
|
if (global != null && !(global instanceof Global)) {
|
||||||
throw new IllegalArgumentException("global is not an instance of Global!");
|
throw new IllegalArgumentException("not a global!");
|
||||||
}
|
}
|
||||||
|
setGlobal((Global)global);
|
||||||
|
}
|
||||||
|
|
||||||
setGlobalTrusted(global);
|
/**
|
||||||
|
* Set the current global scope
|
||||||
|
* @param global the global scope
|
||||||
|
*/
|
||||||
|
public static void setGlobal(final Global global) {
|
||||||
|
// This class in a package.access protected package.
|
||||||
|
// Trusted code only can call this method.
|
||||||
|
currentGlobal.set(global);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -195,7 +210,7 @@ public final class Context {
|
|||||||
* @return error writer of the current context
|
* @return error writer of the current context
|
||||||
*/
|
*/
|
||||||
public static PrintWriter getCurrentErr() {
|
public static PrintWriter getCurrentErr() {
|
||||||
final ScriptObject global = getGlobalTrusted();
|
final ScriptObject global = getGlobal();
|
||||||
return (global != null)? global.getContext().getErr() : new PrintWriter(System.err);
|
return (global != null)? global.getContext().getErr() : new PrintWriter(System.err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -348,6 +363,11 @@ public final class Context {
|
|||||||
this.classPathLoader = null;
|
this.classPathLoader = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final int cacheSize = env._class_cache_size;
|
||||||
|
if (cacheSize > 0) {
|
||||||
|
classCache = new ClassCache(cacheSize);
|
||||||
|
}
|
||||||
|
|
||||||
// print version info if asked.
|
// print version info if asked.
|
||||||
if (env._version) {
|
if (env._version) {
|
||||||
getErr().println("nashorn " + Version.version());
|
getErr().println("nashorn " + Version.version());
|
||||||
@ -395,7 +415,7 @@ public final class Context {
|
|||||||
* @return the property map of the current global scope
|
* @return the property map of the current global scope
|
||||||
*/
|
*/
|
||||||
public static PropertyMap getGlobalMap() {
|
public static PropertyMap getGlobalMap() {
|
||||||
return Context.getGlobalTrusted().getMap();
|
return Context.getGlobal().getMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -425,7 +445,7 @@ public final class Context {
|
|||||||
final String file = (location == UNDEFINED || location == null) ? "<eval>" : location.toString();
|
final String file = (location == UNDEFINED || location == null) ? "<eval>" : location.toString();
|
||||||
final Source source = new Source(file, string);
|
final Source source = new Source(file, string);
|
||||||
final boolean directEval = location != UNDEFINED; // is this direct 'eval' call or indirectly invoked eval?
|
final boolean directEval = location != UNDEFINED; // is this direct 'eval' call or indirectly invoked eval?
|
||||||
final ScriptObject global = Context.getGlobalTrusted();
|
final Global global = Context.getGlobal();
|
||||||
|
|
||||||
ScriptObject scope = initialScope;
|
ScriptObject scope = initialScope;
|
||||||
|
|
||||||
@ -457,7 +477,7 @@ public final class Context {
|
|||||||
// in the caller's environment. A new environment is created!
|
// in the caller's environment. A new environment is created!
|
||||||
if (strictFlag) {
|
if (strictFlag) {
|
||||||
// Create a new scope object
|
// Create a new scope object
|
||||||
final ScriptObject strictEvalScope = ((GlobalObject)global).newObject();
|
final ScriptObject strictEvalScope = global.newObject();
|
||||||
|
|
||||||
// bless it as a "scope"
|
// bless it as a "scope"
|
||||||
strictEvalScope.setIsScope();
|
strictEvalScope.setIsScope();
|
||||||
@ -582,10 +602,10 @@ public final class Context {
|
|||||||
* @throws IOException if source cannot be found or loaded
|
* @throws IOException if source cannot be found or loaded
|
||||||
*/
|
*/
|
||||||
public Object loadWithNewGlobal(final Object from, final Object...args) throws IOException {
|
public Object loadWithNewGlobal(final Object from, final Object...args) throws IOException {
|
||||||
final ScriptObject oldGlobal = getGlobalTrusted();
|
final Global oldGlobal = getGlobal();
|
||||||
final ScriptObject newGlobal = AccessController.doPrivileged(new PrivilegedAction<ScriptObject>() {
|
final Global newGlobal = AccessController.doPrivileged(new PrivilegedAction<Global>() {
|
||||||
@Override
|
@Override
|
||||||
public ScriptObject run() {
|
public Global run() {
|
||||||
try {
|
try {
|
||||||
return newGlobal();
|
return newGlobal();
|
||||||
} catch (final RuntimeException e) {
|
} catch (final RuntimeException e) {
|
||||||
@ -598,17 +618,17 @@ public final class Context {
|
|||||||
}, CREATE_GLOBAL_ACC_CTXT);
|
}, CREATE_GLOBAL_ACC_CTXT);
|
||||||
// initialize newly created Global instance
|
// initialize newly created Global instance
|
||||||
initGlobal(newGlobal);
|
initGlobal(newGlobal);
|
||||||
setGlobalTrusted(newGlobal);
|
setGlobal(newGlobal);
|
||||||
|
|
||||||
final Object[] wrapped = args == null? ScriptRuntime.EMPTY_ARRAY : ScriptObjectMirror.wrapArray(args, oldGlobal);
|
final Object[] wrapped = args == null? ScriptRuntime.EMPTY_ARRAY : ScriptObjectMirror.wrapArray(args, oldGlobal);
|
||||||
newGlobal.put("arguments", ((GlobalObject)newGlobal).wrapAsObject(wrapped), env._strict);
|
newGlobal.put("arguments", newGlobal.wrapAsObject(wrapped), env._strict);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// wrap objects from newGlobal's world as mirrors - but if result
|
// wrap objects from newGlobal's world as mirrors - but if result
|
||||||
// is from oldGlobal's world, unwrap it!
|
// is from oldGlobal's world, unwrap it!
|
||||||
return ScriptObjectMirror.unwrap(ScriptObjectMirror.wrap(load(newGlobal, from), newGlobal), oldGlobal);
|
return ScriptObjectMirror.unwrap(ScriptObjectMirror.wrap(load(newGlobal, from), newGlobal), oldGlobal);
|
||||||
} finally {
|
} finally {
|
||||||
setGlobalTrusted(oldGlobal);
|
setGlobal(oldGlobal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -637,7 +657,7 @@ public final class Context {
|
|||||||
* Checks that the given Class can be accessed from no permissions context.
|
* Checks that the given Class can be accessed from no permissions context.
|
||||||
*
|
*
|
||||||
* @param clazz Class object
|
* @param clazz Class object
|
||||||
* @throw SecurityException if not accessible
|
* @throws SecurityException if not accessible
|
||||||
*/
|
*/
|
||||||
public static void checkPackageAccess(final Class<?> clazz) {
|
public static void checkPackageAccess(final Class<?> clazz) {
|
||||||
final SecurityManager sm = System.getSecurityManager();
|
final SecurityManager sm = System.getSecurityManager();
|
||||||
@ -654,12 +674,12 @@ public final class Context {
|
|||||||
* Checks that the given package name can be accessed from no permissions context.
|
* Checks that the given package name can be accessed from no permissions context.
|
||||||
*
|
*
|
||||||
* @param pkgName package name
|
* @param pkgName package name
|
||||||
* @throw SecurityException if not accessible
|
* @throws SecurityException if not accessible
|
||||||
*/
|
*/
|
||||||
public static void checkPackageAccess(final String pkgName) {
|
public static void checkPackageAccess(final String pkgName) {
|
||||||
final SecurityManager sm = System.getSecurityManager();
|
final SecurityManager sm = System.getSecurityManager();
|
||||||
if (sm != null) {
|
if (sm != null) {
|
||||||
checkPackageAccess(sm, pkgName.endsWith(".")? pkgName : pkgName + ".");
|
checkPackageAccess(sm, pkgName.endsWith(".") ? pkgName : pkgName + ".");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -783,7 +803,7 @@ public final class Context {
|
|||||||
*
|
*
|
||||||
* @return the initialized global scope object.
|
* @return the initialized global scope object.
|
||||||
*/
|
*/
|
||||||
public ScriptObject createGlobal() {
|
public Global createGlobal() {
|
||||||
return initGlobal(newGlobal());
|
return initGlobal(newGlobal());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -791,7 +811,7 @@ public final class Context {
|
|||||||
* Create a new uninitialized global scope object
|
* Create a new uninitialized global scope object
|
||||||
* @return the global script object
|
* @return the global script object
|
||||||
*/
|
*/
|
||||||
public ScriptObject newGlobal() {
|
public Global newGlobal() {
|
||||||
return new Global(this);
|
return new Global(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -801,20 +821,16 @@ public final class Context {
|
|||||||
* @param global the global
|
* @param global the global
|
||||||
* @return the initialized global scope object.
|
* @return the initialized global scope object.
|
||||||
*/
|
*/
|
||||||
public ScriptObject initGlobal(final ScriptObject global) {
|
public Global initGlobal(final Global global) {
|
||||||
if (! (global instanceof GlobalObject)) {
|
|
||||||
throw new IllegalArgumentException("not a global object!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Need only minimal global object, if we are just compiling.
|
// Need only minimal global object, if we are just compiling.
|
||||||
if (!env._compile_only) {
|
if (!env._compile_only) {
|
||||||
final ScriptObject oldGlobal = Context.getGlobalTrusted();
|
final Global oldGlobal = Context.getGlobal();
|
||||||
try {
|
try {
|
||||||
Context.setGlobalTrusted(global);
|
Context.setGlobal(global);
|
||||||
// initialize global scope with builtin global objects
|
// initialize global scope with builtin global objects
|
||||||
((GlobalObject)global).initBuiltinObjects();
|
global.initBuiltinObjects();
|
||||||
} finally {
|
} finally {
|
||||||
Context.setGlobalTrusted(oldGlobal);
|
Context.setGlobal(oldGlobal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -822,30 +838,15 @@ public final class Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trusted variants - package-private
|
* Trusted variant - package-private
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the current global scope
|
|
||||||
* @return current global scope
|
|
||||||
*/
|
|
||||||
static ScriptObject getGlobalTrusted() {
|
|
||||||
return currentGlobal.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the current global scope
|
|
||||||
*/
|
|
||||||
static void setGlobalTrusted(ScriptObject global) {
|
|
||||||
currentGlobal.set(global);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the current global's context
|
* Return the current global's context
|
||||||
* @return current global's context
|
* @return current global's context
|
||||||
*/
|
*/
|
||||||
static Context getContextTrusted() {
|
static Context getContextTrusted() {
|
||||||
return Context.getGlobalTrusted().getContext();
|
return ((ScriptObject)Context.getGlobal()).getContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -914,7 +915,7 @@ public final class Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Package as a JavaScript function and pass function back to shell.
|
// Package as a JavaScript function and pass function back to shell.
|
||||||
return ((GlobalObject)Context.getGlobalTrusted()).newScriptFunction(RUN_SCRIPT.symbolName(), runMethodHandle, scope, strict);
|
return Context.getGlobal().newScriptFunction(RUN_SCRIPT.symbolName(), runMethodHandle, scope, strict);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ScriptFunction compileScript(final Source source, final ScriptObject scope, final ErrorManager errMan) {
|
private ScriptFunction compileScript(final Source source, final ScriptObject scope, final ErrorManager errMan) {
|
||||||
@ -925,16 +926,10 @@ public final class Context {
|
|||||||
// start with no errors, no warnings.
|
// start with no errors, no warnings.
|
||||||
errMan.reset();
|
errMan.reset();
|
||||||
|
|
||||||
GlobalObject global = null;
|
Class<?> script = findCachedClass(source);
|
||||||
Class<?> script;
|
if (script != null) {
|
||||||
|
Compiler.LOG.fine("Code cache hit for ", source, " avoiding recompile.");
|
||||||
if (env._class_cache_size > 0) {
|
return script;
|
||||||
global = (GlobalObject)Context.getGlobalTrusted();
|
|
||||||
script = global.findCachedClass(source);
|
|
||||||
if (script != null) {
|
|
||||||
Compiler.LOG.fine("Code cache hit for ", source, " avoiding recompile.");
|
|
||||||
return script;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final FunctionNode functionNode = new Parser(env, source, errMan, strict).parse();
|
final FunctionNode functionNode = new Parser(env, source, errMan, strict).parse();
|
||||||
@ -963,10 +958,7 @@ public final class Context {
|
|||||||
|
|
||||||
final FunctionNode newFunctionNode = compiler.compile(functionNode);
|
final FunctionNode newFunctionNode = compiler.compile(functionNode);
|
||||||
script = compiler.install(newFunctionNode);
|
script = compiler.install(newFunctionNode);
|
||||||
|
cacheClass(source, script);
|
||||||
if (global != null) {
|
|
||||||
global.cacheClass(source, script);
|
|
||||||
}
|
|
||||||
|
|
||||||
return script;
|
return script;
|
||||||
}
|
}
|
||||||
@ -988,4 +980,60 @@ public final class Context {
|
|||||||
private long getUniqueScriptId() {
|
private long getUniqueScriptId() {
|
||||||
return uniqueScriptId.getAndIncrement();
|
return uniqueScriptId.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cache for compiled script classes.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
private static class ClassCache extends LinkedHashMap<Source, ClassReference> {
|
||||||
|
private final int size;
|
||||||
|
private final ReferenceQueue<Class<?>> queue;
|
||||||
|
|
||||||
|
ClassCache(int size) {
|
||||||
|
super(size, 0.75f, true);
|
||||||
|
this.size = size;
|
||||||
|
this.queue = new ReferenceQueue<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cache(final Source source, final Class<?> clazz) {
|
||||||
|
put(source, new ClassReference(clazz, queue, source));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean removeEldestEntry(final Map.Entry<Source, ClassReference> eldest) {
|
||||||
|
return size() > size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClassReference get(Object key) {
|
||||||
|
for (ClassReference ref; (ref = (ClassReference)queue.poll()) != null; ) {
|
||||||
|
remove(ref.source);
|
||||||
|
}
|
||||||
|
return super.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ClassReference extends SoftReference<Class<?>> {
|
||||||
|
private final Source source;
|
||||||
|
|
||||||
|
ClassReference(final Class<?> clazz, final ReferenceQueue<Class<?>> queue, final Source source) {
|
||||||
|
super(clazz, queue);
|
||||||
|
this.source = source;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Class cache management
|
||||||
|
private Class<?> findCachedClass(final Source source) {
|
||||||
|
ClassReference ref = classCache == null ? null : classCache.get(source);
|
||||||
|
return ref != null ? ref.get() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cacheClass(final Source source, final Class<?> clazz) {
|
||||||
|
if (classCache != null) {
|
||||||
|
classCache.cache(source, clazz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ final class DebuggerSupport {
|
|||||||
* @return context global.
|
* @return context global.
|
||||||
*/
|
*/
|
||||||
static Object getGlobal() {
|
static Object getGlobal() {
|
||||||
return Context.getGlobalTrusted();
|
return Context.getGlobal();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -87,7 +87,7 @@ final class DebuggerSupport {
|
|||||||
* @return Result of eval as string, or, an exception or null depending on returnException.
|
* @return Result of eval as string, or, an exception or null depending on returnException.
|
||||||
*/
|
*/
|
||||||
static Object eval(final ScriptObject scope, final Object self, final String string, final boolean returnException) {
|
static Object eval(final ScriptObject scope, final Object self, final String string, final boolean returnException) {
|
||||||
final ScriptObject global = Context.getGlobalTrusted();
|
final ScriptObject global = Context.getGlobal();
|
||||||
final ScriptObject initialScope = scope != null ? scope : global;
|
final ScriptObject initialScope = scope != null ? scope : global;
|
||||||
final Object callThis = self != null ? self : global;
|
final Object callThis = self != null ? self : global;
|
||||||
final Context context = global.getContext();
|
final Context context = global.getContext();
|
||||||
|
@ -31,6 +31,7 @@ import java.util.ResourceBundle;
|
|||||||
import jdk.nashorn.api.scripting.NashornException;
|
import jdk.nashorn.api.scripting.NashornException;
|
||||||
import jdk.nashorn.internal.scripts.JS;
|
import jdk.nashorn.internal.scripts.JS;
|
||||||
import jdk.nashorn.internal.codegen.CompilerConstants;
|
import jdk.nashorn.internal.codegen.CompilerConstants;
|
||||||
|
import jdk.nashorn.internal.objects.Global;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class to throw various standard "ECMA error" exceptions such as Error, ReferenceError, TypeError etc.
|
* Helper class to throw various standard "ECMA error" exceptions such as Error, ReferenceError, TypeError etc.
|
||||||
@ -66,7 +67,7 @@ public final class ECMAErrors {
|
|||||||
* @return the resulting {@link ECMAException}
|
* @return the resulting {@link ECMAException}
|
||||||
*/
|
*/
|
||||||
public static ECMAException asEcmaException(final ParserException e) {
|
public static ECMAException asEcmaException(final ParserException e) {
|
||||||
return asEcmaException(Context.getGlobalTrusted(), e);
|
return asEcmaException(Context.getGlobal(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -78,11 +79,11 @@ public final class ECMAErrors {
|
|||||||
*
|
*
|
||||||
* @return the resulting {@link ECMAException}
|
* @return the resulting {@link ECMAException}
|
||||||
*/
|
*/
|
||||||
public static ECMAException asEcmaException(final ScriptObject global, final ParserException e) {
|
public static ECMAException asEcmaException(final Global global, final ParserException e) {
|
||||||
final JSErrorType errorType = e.getErrorType();
|
final JSErrorType errorType = e.getErrorType();
|
||||||
assert errorType != null : "error type for " + e + " was null";
|
assert errorType != null : "error type for " + e + " was null";
|
||||||
|
|
||||||
final GlobalObject globalObj = (GlobalObject)global;
|
final Global globalObj = global;
|
||||||
final String msg = e.getMessage();
|
final String msg = e.getMessage();
|
||||||
|
|
||||||
// translate to ECMAScript Error object using error type
|
// translate to ECMAScript Error object using error type
|
||||||
@ -116,7 +117,7 @@ public final class ECMAErrors {
|
|||||||
* @return the resulting {@link ECMAException}
|
* @return the resulting {@link ECMAException}
|
||||||
*/
|
*/
|
||||||
public static ECMAException syntaxError(final String msgId, final String... args) {
|
public static ECMAException syntaxError(final String msgId, final String... args) {
|
||||||
return syntaxError(Context.getGlobalTrusted(), msgId, args);
|
return syntaxError(Context.getGlobal(), msgId, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -128,7 +129,7 @@ public final class ECMAErrors {
|
|||||||
*
|
*
|
||||||
* @return the resulting {@link ECMAException}
|
* @return the resulting {@link ECMAException}
|
||||||
*/
|
*/
|
||||||
public static ECMAException syntaxError(final ScriptObject global, final String msgId, final String... args) {
|
public static ECMAException syntaxError(final Global global, final String msgId, final String... args) {
|
||||||
return syntaxError(global, null, msgId, args);
|
return syntaxError(global, null, msgId, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,7 +143,7 @@ public final class ECMAErrors {
|
|||||||
* @return the resulting {@link ECMAException}
|
* @return the resulting {@link ECMAException}
|
||||||
*/
|
*/
|
||||||
public static ECMAException syntaxError(final Throwable cause, final String msgId, final String... args) {
|
public static ECMAException syntaxError(final Throwable cause, final String msgId, final String... args) {
|
||||||
return syntaxError(Context.getGlobalTrusted(), cause, msgId, args);
|
return syntaxError(Context.getGlobal(), cause, msgId, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -155,9 +156,9 @@ public final class ECMAErrors {
|
|||||||
*
|
*
|
||||||
* @return the resulting {@link ECMAException}
|
* @return the resulting {@link ECMAException}
|
||||||
*/
|
*/
|
||||||
public static ECMAException syntaxError(final ScriptObject global, final Throwable cause, final String msgId, final String... args) {
|
public static ECMAException syntaxError(final Global global, final Throwable cause, final String msgId, final String... args) {
|
||||||
final String msg = getMessage("syntax.error." + msgId, args);
|
final String msg = getMessage("syntax.error." + msgId, args);
|
||||||
return error(((GlobalObject)global).newSyntaxError(msg), cause);
|
return error(global.newSyntaxError(msg), cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -169,7 +170,7 @@ public final class ECMAErrors {
|
|||||||
* @return the resulting {@link ECMAException}
|
* @return the resulting {@link ECMAException}
|
||||||
*/
|
*/
|
||||||
public static ECMAException typeError(final String msgId, final String... args) {
|
public static ECMAException typeError(final String msgId, final String... args) {
|
||||||
return typeError(Context.getGlobalTrusted(), msgId, args);
|
return typeError(Context.getGlobal(), msgId, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -181,7 +182,7 @@ public final class ECMAErrors {
|
|||||||
*
|
*
|
||||||
* @return the resulting {@link ECMAException}
|
* @return the resulting {@link ECMAException}
|
||||||
*/
|
*/
|
||||||
public static ECMAException typeError(final ScriptObject global, final String msgId, final String... args) {
|
public static ECMAException typeError(final Global global, final String msgId, final String... args) {
|
||||||
return typeError(global, null, msgId, args);
|
return typeError(global, null, msgId, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,7 +196,7 @@ public final class ECMAErrors {
|
|||||||
* @return the resulting {@link ECMAException}
|
* @return the resulting {@link ECMAException}
|
||||||
*/
|
*/
|
||||||
public static ECMAException typeError(final Throwable cause, final String msgId, final String... args) {
|
public static ECMAException typeError(final Throwable cause, final String msgId, final String... args) {
|
||||||
return typeError(Context.getGlobalTrusted(), cause, msgId, args);
|
return typeError(Context.getGlobal(), cause, msgId, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -208,9 +209,9 @@ public final class ECMAErrors {
|
|||||||
*
|
*
|
||||||
* @return the resulting {@link ECMAException}
|
* @return the resulting {@link ECMAException}
|
||||||
*/
|
*/
|
||||||
public static ECMAException typeError(final ScriptObject global, final Throwable cause, final String msgId, final String... args) {
|
public static ECMAException typeError(final Global global, final Throwable cause, final String msgId, final String... args) {
|
||||||
final String msg = getMessage("type.error." + msgId, args);
|
final String msg = getMessage("type.error." + msgId, args);
|
||||||
return error(((GlobalObject)global).newTypeError(msg), cause);
|
return error(global.newTypeError(msg), cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -222,7 +223,7 @@ public final class ECMAErrors {
|
|||||||
* @return the resulting {@link ECMAException}
|
* @return the resulting {@link ECMAException}
|
||||||
*/
|
*/
|
||||||
public static ECMAException rangeError(final String msgId, final String... args) {
|
public static ECMAException rangeError(final String msgId, final String... args) {
|
||||||
return rangeError(Context.getGlobalTrusted(), msgId, args);
|
return rangeError(Context.getGlobal(), msgId, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -234,7 +235,7 @@ public final class ECMAErrors {
|
|||||||
*
|
*
|
||||||
* @return the resulting {@link ECMAException}
|
* @return the resulting {@link ECMAException}
|
||||||
*/
|
*/
|
||||||
public static ECMAException rangeError(final ScriptObject global, final String msgId, final String... args) {
|
public static ECMAException rangeError(final Global global, final String msgId, final String... args) {
|
||||||
return rangeError(global, null, msgId, args);
|
return rangeError(global, null, msgId, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,7 +249,7 @@ public final class ECMAErrors {
|
|||||||
* @return the resulting {@link ECMAException}
|
* @return the resulting {@link ECMAException}
|
||||||
*/
|
*/
|
||||||
public static ECMAException rangeError(final Throwable cause, final String msgId, final String... args) {
|
public static ECMAException rangeError(final Throwable cause, final String msgId, final String... args) {
|
||||||
return rangeError(Context.getGlobalTrusted(), cause, msgId, args);
|
return rangeError(Context.getGlobal(), cause, msgId, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -261,9 +262,9 @@ public final class ECMAErrors {
|
|||||||
*
|
*
|
||||||
* @return the resulting {@link ECMAException}
|
* @return the resulting {@link ECMAException}
|
||||||
*/
|
*/
|
||||||
public static ECMAException rangeError(final ScriptObject global, final Throwable cause, final String msgId, final String... args) {
|
public static ECMAException rangeError(final Global global, final Throwable cause, final String msgId, final String... args) {
|
||||||
final String msg = getMessage("range.error." + msgId, args);
|
final String msg = getMessage("range.error." + msgId, args);
|
||||||
return error(((GlobalObject)global).newRangeError(msg), cause);
|
return error(global.newRangeError(msg), cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -275,7 +276,7 @@ public final class ECMAErrors {
|
|||||||
* @return the resulting {@link ECMAException}
|
* @return the resulting {@link ECMAException}
|
||||||
*/
|
*/
|
||||||
public static ECMAException referenceError(final String msgId, final String... args) {
|
public static ECMAException referenceError(final String msgId, final String... args) {
|
||||||
return referenceError(Context.getGlobalTrusted(), msgId, args);
|
return referenceError(Context.getGlobal(), msgId, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -287,7 +288,7 @@ public final class ECMAErrors {
|
|||||||
*
|
*
|
||||||
* @return the resulting {@link ECMAException}
|
* @return the resulting {@link ECMAException}
|
||||||
*/
|
*/
|
||||||
public static ECMAException referenceError(final ScriptObject global, final String msgId, final String... args) {
|
public static ECMAException referenceError(final Global global, final String msgId, final String... args) {
|
||||||
return referenceError(global, null, msgId, args);
|
return referenceError(global, null, msgId, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,7 +302,7 @@ public final class ECMAErrors {
|
|||||||
* @return the resulting {@link ECMAException}
|
* @return the resulting {@link ECMAException}
|
||||||
*/
|
*/
|
||||||
public static ECMAException referenceError(final Throwable cause, final String msgId, final String... args) {
|
public static ECMAException referenceError(final Throwable cause, final String msgId, final String... args) {
|
||||||
return referenceError(Context.getGlobalTrusted(), cause, msgId, args);
|
return referenceError(Context.getGlobal(), cause, msgId, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -314,9 +315,9 @@ public final class ECMAErrors {
|
|||||||
*
|
*
|
||||||
* @return the resulting {@link ECMAException}
|
* @return the resulting {@link ECMAException}
|
||||||
*/
|
*/
|
||||||
public static ECMAException referenceError(final ScriptObject global, final Throwable cause, final String msgId, final String... args) {
|
public static ECMAException referenceError(final Global global, final Throwable cause, final String msgId, final String... args) {
|
||||||
final String msg = getMessage("reference.error." + msgId, args);
|
final String msg = getMessage("reference.error." + msgId, args);
|
||||||
return error(((GlobalObject)global).newReferenceError(msg), cause);
|
return error(global.newReferenceError(msg), cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -328,7 +329,7 @@ public final class ECMAErrors {
|
|||||||
* @return the resulting {@link ECMAException}
|
* @return the resulting {@link ECMAException}
|
||||||
*/
|
*/
|
||||||
public static ECMAException uriError(final String msgId, final String... args) {
|
public static ECMAException uriError(final String msgId, final String... args) {
|
||||||
return uriError(Context.getGlobalTrusted(), msgId, args);
|
return uriError(Context.getGlobal(), msgId, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -340,7 +341,7 @@ public final class ECMAErrors {
|
|||||||
*
|
*
|
||||||
* @return the resulting {@link ECMAException}
|
* @return the resulting {@link ECMAException}
|
||||||
*/
|
*/
|
||||||
public static ECMAException uriError(final ScriptObject global, final String msgId, final String... args) {
|
public static ECMAException uriError(final Global global, final String msgId, final String... args) {
|
||||||
return uriError(global, null, msgId, args);
|
return uriError(global, null, msgId, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,7 +355,7 @@ public final class ECMAErrors {
|
|||||||
* @return the resulting {@link ECMAException}
|
* @return the resulting {@link ECMAException}
|
||||||
*/
|
*/
|
||||||
public static ECMAException uriError(final Throwable cause, final String msgId, final String... args) {
|
public static ECMAException uriError(final Throwable cause, final String msgId, final String... args) {
|
||||||
return uriError(Context.getGlobalTrusted(), cause, msgId, args);
|
return uriError(Context.getGlobal(), cause, msgId, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -367,9 +368,9 @@ public final class ECMAErrors {
|
|||||||
*
|
*
|
||||||
* @return the resulting {@link ECMAException}
|
* @return the resulting {@link ECMAException}
|
||||||
*/
|
*/
|
||||||
public static ECMAException uriError(final ScriptObject global, final Throwable cause, final String msgId, final String... args) {
|
public static ECMAException uriError(final Global global, final Throwable cause, final String msgId, final String... args) {
|
||||||
final String msg = getMessage("uri.error." + msgId, args);
|
final String msg = getMessage("uri.error." + msgId, args);
|
||||||
return error(((GlobalObject)global).newURIError(msg), cause);
|
return error(global.newURIError(msg), cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,31 +38,27 @@ final class FinalScriptFunctionData extends ScriptFunctionData {
|
|||||||
/**
|
/**
|
||||||
* Constructor - used for bind
|
* Constructor - used for bind
|
||||||
*
|
*
|
||||||
* @param name name
|
* @param name name
|
||||||
* @param arity arity
|
* @param arity arity
|
||||||
* @param functions precompiled code
|
* @param functions precompiled code
|
||||||
* @param isStrict strict
|
* @param flags {@link ScriptFunctionData} flags
|
||||||
* @param isBuiltin builtin
|
|
||||||
* @param isConstructor constructor
|
|
||||||
*/
|
*/
|
||||||
FinalScriptFunctionData(final String name, int arity, CompiledFunctions functions, final boolean isStrict, final boolean isBuiltin, final boolean isConstructor) {
|
FinalScriptFunctionData(final String name, final int arity, final CompiledFunctions functions, final int flags) {
|
||||||
super(name, arity, isStrict, isBuiltin, isConstructor);
|
super(name, arity, flags);
|
||||||
code.addAll(functions);
|
code.addAll(functions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor - used from ScriptFunction. This assumes that we have code alraedy for the
|
* Constructor - used from ScriptFunction. This assumes that we have code already for the
|
||||||
* method (typically a native method) and possibly specializations.
|
* method (typically a native method) and possibly specializations.
|
||||||
*
|
*
|
||||||
* @param name name
|
* @param name name
|
||||||
* @param mh method handle for generic version of method
|
* @param mh method handle for generic version of method
|
||||||
* @param specs specializations
|
* @param specs specializations
|
||||||
* @param isStrict strict
|
* @param flags {@link ScriptFunctionData} flags
|
||||||
* @param isBuiltin builtin
|
|
||||||
* @param isConstructor constructor
|
|
||||||
*/
|
*/
|
||||||
FinalScriptFunctionData(final String name, final MethodHandle mh, final MethodHandle[] specs, final boolean isStrict, final boolean isBuiltin, final boolean isConstructor) {
|
FinalScriptFunctionData(final String name, final MethodHandle mh, final MethodHandle[] specs, final int flags) {
|
||||||
super(name, arity(mh), isStrict, isBuiltin, isConstructor);
|
super(name, arity(mh), flags);
|
||||||
|
|
||||||
addInvoker(mh);
|
addInvoker(mh);
|
||||||
if (specs != null) {
|
if (specs != null) {
|
||||||
|
@ -1,244 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package jdk.nashorn.internal.runtime;
|
|
||||||
|
|
||||||
import java.lang.invoke.MethodHandle;
|
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import jdk.internal.dynalink.linker.GuardedInvocation;
|
|
||||||
import jdk.internal.dynalink.linker.LinkRequest;
|
|
||||||
import jdk.nashorn.internal.runtime.linker.InvokeByName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Runtime interface to the global scope objects.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public interface GlobalObject {
|
|
||||||
/**
|
|
||||||
* Is this global of the given Context?
|
|
||||||
* @param ctxt the context
|
|
||||||
* @return true if this global belongs to the given Context
|
|
||||||
*/
|
|
||||||
public boolean isOfContext(final Context ctxt);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Does this global belong to a strict Context?
|
|
||||||
* @return true if this global belongs to a strict Context
|
|
||||||
*/
|
|
||||||
public boolean isStrictContext();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize standard builtin objects like "Object", "Array", "Function" etc.
|
|
||||||
* as well as our extension builtin objects like "Java", "JSAdapter" as properties
|
|
||||||
* of the global scope object.
|
|
||||||
*/
|
|
||||||
public void initBuiltinObjects();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper for {@link jdk.nashorn.internal.objects.Global#newScriptFunction(String, MethodHandle, ScriptObject, boolean)}
|
|
||||||
*
|
|
||||||
* @param name function name
|
|
||||||
* @param handle invocation handle for function
|
|
||||||
* @param scope the scope
|
|
||||||
* @param strict are we in strict mode
|
|
||||||
*
|
|
||||||
* @return new script function
|
|
||||||
*/
|
|
||||||
public ScriptFunction newScriptFunction(String name, MethodHandle handle, ScriptObject scope, boolean strict);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper for {@link jdk.nashorn.internal.objects.Global#wrapAsObject(Object)}
|
|
||||||
*
|
|
||||||
* @param obj object to wrap
|
|
||||||
* @return wrapped object
|
|
||||||
*/
|
|
||||||
public Object wrapAsObject(Object obj);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper for {@link jdk.nashorn.internal.objects.Global#primitiveLookup(LinkRequest, Object)}
|
|
||||||
*
|
|
||||||
* @param request the link request for the dynamic call site.
|
|
||||||
* @param self self reference
|
|
||||||
*
|
|
||||||
* @return guarded invocation
|
|
||||||
*/
|
|
||||||
public GuardedInvocation primitiveLookup(LinkRequest request, Object self);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper for {@link jdk.nashorn.internal.objects.Global#newObject()}
|
|
||||||
*
|
|
||||||
* @return the new ScriptObject
|
|
||||||
*/
|
|
||||||
public ScriptObject newObject();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper for {@link jdk.nashorn.internal.objects.Global#isError(ScriptObject)}
|
|
||||||
*
|
|
||||||
* @param sobj to check if it is an error object
|
|
||||||
* @return true if error object
|
|
||||||
*/
|
|
||||||
public boolean isError(ScriptObject sobj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper for {@link jdk.nashorn.internal.objects.Global#newError(String)}
|
|
||||||
*
|
|
||||||
* @param msg the error message
|
|
||||||
*
|
|
||||||
* @return the new ScriptObject representing the error
|
|
||||||
*/
|
|
||||||
public ScriptObject newError(String msg);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper for {@link jdk.nashorn.internal.objects.Global#newEvalError(String)}
|
|
||||||
*
|
|
||||||
* @param msg the error message
|
|
||||||
*
|
|
||||||
* @return the new ScriptObject representing the eval error
|
|
||||||
*/
|
|
||||||
public ScriptObject newEvalError(String msg);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper for {@link jdk.nashorn.internal.objects.Global#newRangeError(String)}
|
|
||||||
*
|
|
||||||
* @param msg the error message
|
|
||||||
*
|
|
||||||
* @return the new ScriptObject representing the range error
|
|
||||||
*/
|
|
||||||
public ScriptObject newRangeError(String msg);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper for {@link jdk.nashorn.internal.objects.Global#newReferenceError(String)}
|
|
||||||
*
|
|
||||||
* @param msg the error message
|
|
||||||
*
|
|
||||||
* @return the new ScriptObject representing the reference error
|
|
||||||
*/
|
|
||||||
public ScriptObject newReferenceError(String msg);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper for {@link jdk.nashorn.internal.objects.Global#newSyntaxError(String)}
|
|
||||||
*
|
|
||||||
* @param msg the error message
|
|
||||||
*
|
|
||||||
* @return the new ScriptObject representing the syntax error
|
|
||||||
*/
|
|
||||||
public ScriptObject newSyntaxError(String msg);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper for {@link jdk.nashorn.internal.objects.Global#newTypeError(String)}
|
|
||||||
*
|
|
||||||
* @param msg the error message
|
|
||||||
*
|
|
||||||
* @return the new ScriptObject representing the type error
|
|
||||||
*/
|
|
||||||
public ScriptObject newTypeError(String msg);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper for {@link jdk.nashorn.internal.objects.Global#newURIError(String)}
|
|
||||||
*
|
|
||||||
* @param msg the error message
|
|
||||||
*
|
|
||||||
* @return the new ScriptObject representing the URI error
|
|
||||||
*/
|
|
||||||
public ScriptObject newURIError(String msg);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper for {@link jdk.nashorn.internal.objects.Global#newGenericDescriptor(boolean, boolean)}
|
|
||||||
*
|
|
||||||
* @param configurable is the described property configurable
|
|
||||||
* @param enumerable is the described property enumerable
|
|
||||||
*
|
|
||||||
* @return property descriptor
|
|
||||||
*/
|
|
||||||
public PropertyDescriptor newGenericDescriptor(boolean configurable, boolean enumerable);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper for {@link jdk.nashorn.internal.objects.Global#newDataDescriptor(Object, boolean, boolean, boolean)}
|
|
||||||
*
|
|
||||||
* @param value data value
|
|
||||||
* @param configurable is the described property configurable
|
|
||||||
* @param enumerable is the described property enumerable
|
|
||||||
* @param writable is the described property writable
|
|
||||||
*
|
|
||||||
* @return property descriptor
|
|
||||||
*/
|
|
||||||
public PropertyDescriptor newDataDescriptor(Object value, boolean configurable, boolean enumerable, boolean writable);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper for {@link jdk.nashorn.internal.objects.Global#newAccessorDescriptor(Object, Object, boolean, boolean)}
|
|
||||||
*
|
|
||||||
* @param get property getter, or null if none
|
|
||||||
* @param set property setter, or null if none
|
|
||||||
* @param configurable is the described property configurable
|
|
||||||
* @param enumerable is the described property enumerable
|
|
||||||
*
|
|
||||||
* @return property descriptor
|
|
||||||
*/
|
|
||||||
public PropertyDescriptor newAccessorDescriptor(Object get, Object set, boolean configurable, boolean enumerable);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper for {@link jdk.nashorn.internal.objects.Global#getDefaultValue(ScriptObject, Class)}
|
|
||||||
*
|
|
||||||
* @param sobj script object
|
|
||||||
* @param typeHint type hint
|
|
||||||
*
|
|
||||||
* @return default value
|
|
||||||
*/
|
|
||||||
public Object getDefaultValue(ScriptObject sobj, Class<?> typeHint);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find the compiled Class for the given script source, if available
|
|
||||||
*
|
|
||||||
* @param source Source object of the script
|
|
||||||
* @return compiled Class object or null
|
|
||||||
*/
|
|
||||||
public Class<?> findCachedClass(Source source);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Put the Source associated Class object in the Source-to-Class cache
|
|
||||||
*
|
|
||||||
* @param source Source of the script
|
|
||||||
* @param clazz compiled Class object for the source
|
|
||||||
*/
|
|
||||||
public void cacheClass(Source source, Class<?> clazz);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get cached InvokeByName object for the given key
|
|
||||||
* @param key key to be associated with InvokeByName object
|
|
||||||
* @param creator if InvokeByName is absent 'creator' is called to make one (lazy init)
|
|
||||||
* @return InvokeByName object associated with the key.
|
|
||||||
*/
|
|
||||||
public InvokeByName getInvokeByName(final Object key, final Callable<InvokeByName> creator);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get cached dynamic method handle for the given key
|
|
||||||
* @param key key to be associated with dynamic method handle
|
|
||||||
* @param creator if method handle is absent 'creator' is called to make one (lazy init)
|
|
||||||
* @return dynamic method handle associated with the key.
|
|
||||||
*/
|
|
||||||
public MethodHandle getDynamicInvoker(final Object key, final Callable<MethodHandle> creator);
|
|
||||||
}
|
|
@ -33,6 +33,7 @@ import jdk.nashorn.internal.ir.Node;
|
|||||||
import jdk.nashorn.internal.ir.ObjectNode;
|
import jdk.nashorn.internal.ir.ObjectNode;
|
||||||
import jdk.nashorn.internal.ir.PropertyNode;
|
import jdk.nashorn.internal.ir.PropertyNode;
|
||||||
import jdk.nashorn.internal.ir.UnaryNode;
|
import jdk.nashorn.internal.ir.UnaryNode;
|
||||||
|
import jdk.nashorn.internal.objects.Global;
|
||||||
import jdk.nashorn.internal.parser.JSONParser;
|
import jdk.nashorn.internal.parser.JSONParser;
|
||||||
import jdk.nashorn.internal.parser.TokenType;
|
import jdk.nashorn.internal.parser.TokenType;
|
||||||
import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
|
import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
|
||||||
@ -47,7 +48,7 @@ public final class JSONFunctions {
|
|||||||
private static final Object REVIVER_INVOKER = new Object();
|
private static final Object REVIVER_INVOKER = new Object();
|
||||||
|
|
||||||
private static MethodHandle getREVIVER_INVOKER() {
|
private static MethodHandle getREVIVER_INVOKER() {
|
||||||
return ((GlobalObject)Context.getGlobal()).getDynamicInvoker(REVIVER_INVOKER,
|
return Context.getGlobal().getDynamicInvoker(REVIVER_INVOKER,
|
||||||
new Callable<MethodHandle>() {
|
new Callable<MethodHandle>() {
|
||||||
@Override
|
@Override
|
||||||
public MethodHandle call() {
|
public MethodHandle call() {
|
||||||
@ -88,7 +89,7 @@ public final class JSONFunctions {
|
|||||||
throw ECMAErrors.syntaxError(e, "invalid.json", e.getMessage());
|
throw ECMAErrors.syntaxError(e, "invalid.json", e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
final ScriptObject global = Context.getGlobalTrusted();
|
final Global global = Context.getGlobal();
|
||||||
Object unfiltered = convertNode(global, node);
|
Object unfiltered = convertNode(global, node);
|
||||||
return applyReviver(global, unfiltered, reviver);
|
return applyReviver(global, unfiltered, reviver);
|
||||||
}
|
}
|
||||||
@ -98,10 +99,10 @@ public final class JSONFunctions {
|
|||||||
// parse helpers
|
// parse helpers
|
||||||
|
|
||||||
// apply 'reviver' function if available
|
// apply 'reviver' function if available
|
||||||
private static Object applyReviver(final ScriptObject global, final Object unfiltered, final Object reviver) {
|
private static Object applyReviver(final Global global, final Object unfiltered, final Object reviver) {
|
||||||
if (reviver instanceof ScriptFunction) {
|
if (reviver instanceof ScriptFunction) {
|
||||||
assert global instanceof GlobalObject;
|
assert global instanceof Global;
|
||||||
final ScriptObject root = ((GlobalObject)global).newObject();
|
final ScriptObject root = global.newObject();
|
||||||
root.addOwnProperty("", Property.WRITABLE_ENUMERABLE_CONFIGURABLE, unfiltered);
|
root.addOwnProperty("", Property.WRITABLE_ENUMERABLE_CONFIGURABLE, unfiltered);
|
||||||
return walk(root, "", (ScriptFunction)reviver);
|
return walk(root, "", (ScriptFunction)reviver);
|
||||||
}
|
}
|
||||||
@ -138,8 +139,8 @@ public final class JSONFunctions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Converts IR node to runtime value
|
// Converts IR node to runtime value
|
||||||
private static Object convertNode(final ScriptObject global, final Node node) {
|
private static Object convertNode(final Global global, final Node node) {
|
||||||
assert global instanceof GlobalObject;
|
assert global instanceof Global;
|
||||||
|
|
||||||
if (node instanceof LiteralNode) {
|
if (node instanceof LiteralNode) {
|
||||||
// check for array literal
|
// check for array literal
|
||||||
@ -157,7 +158,7 @@ public final class JSONFunctions {
|
|||||||
for (final Node elem : elements) {
|
for (final Node elem : elements) {
|
||||||
values[index++] = JSType.toNumber(convertNode(global, elem));
|
values[index++] = JSType.toNumber(convertNode(global, elem));
|
||||||
}
|
}
|
||||||
return ((GlobalObject)global).wrapAsObject(values);
|
return global.wrapAsObject(values);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Object[] values = new Object[elements.length];
|
final Object[] values = new Object[elements.length];
|
||||||
@ -167,14 +168,14 @@ public final class JSONFunctions {
|
|||||||
values[index++] = convertNode(global, elem);
|
values[index++] = convertNode(global, elem);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ((GlobalObject)global).wrapAsObject(values);
|
return global.wrapAsObject(values);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ((LiteralNode<?>)node).getValue();
|
return ((LiteralNode<?>)node).getValue();
|
||||||
|
|
||||||
} else if (node instanceof ObjectNode) {
|
} else if (node instanceof ObjectNode) {
|
||||||
final ObjectNode objNode = (ObjectNode) node;
|
final ObjectNode objNode = (ObjectNode) node;
|
||||||
final ScriptObject object = ((GlobalObject)global).newObject();
|
final ScriptObject object = global.newObject();
|
||||||
|
|
||||||
for (final PropertyNode pNode: objNode.getElements()) {
|
for (final PropertyNode pNode: objNode.getElements()) {
|
||||||
final Node valueNode = pNode.getValue();
|
final Node valueNode = pNode.getValue();
|
||||||
|
@ -36,6 +36,7 @@ import java.util.List;
|
|||||||
import jdk.internal.dynalink.beans.StaticClass;
|
import jdk.internal.dynalink.beans.StaticClass;
|
||||||
import jdk.nashorn.api.scripting.JSObject;
|
import jdk.nashorn.api.scripting.JSObject;
|
||||||
import jdk.nashorn.internal.codegen.CompilerConstants.Call;
|
import jdk.nashorn.internal.codegen.CompilerConstants.Call;
|
||||||
|
import jdk.nashorn.internal.objects.Global;
|
||||||
import jdk.nashorn.internal.parser.Lexer;
|
import jdk.nashorn.internal.parser.Lexer;
|
||||||
import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator;
|
import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator;
|
||||||
import jdk.nashorn.internal.runtime.linker.Bootstrap;
|
import jdk.nashorn.internal.runtime.linker.Bootstrap;
|
||||||
@ -852,7 +853,7 @@ public enum JSType {
|
|||||||
* @return the wrapped object
|
* @return the wrapped object
|
||||||
*/
|
*/
|
||||||
public static Object toScriptObject(final Object obj) {
|
public static Object toScriptObject(final Object obj) {
|
||||||
return toScriptObject(Context.getGlobalTrusted(), obj);
|
return toScriptObject(Context.getGlobal(), obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -865,7 +866,7 @@ public enum JSType {
|
|||||||
*
|
*
|
||||||
* @return the wrapped object
|
* @return the wrapped object
|
||||||
*/
|
*/
|
||||||
public static Object toScriptObject(final ScriptObject global, final Object obj) {
|
public static Object toScriptObject(final Global global, final Object obj) {
|
||||||
if (nullOrUndefined(obj)) {
|
if (nullOrUndefined(obj)) {
|
||||||
throw typeError(global, "not.an.object", ScriptRuntime.safeToString(obj));
|
throw typeError(global, "not.an.object", ScriptRuntime.safeToString(obj));
|
||||||
}
|
}
|
||||||
@ -874,7 +875,7 @@ public enum JSType {
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ((GlobalObject)global).wrapAsObject(obj);
|
return global.wrapAsObject(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -984,7 +985,7 @@ public enum JSType {
|
|||||||
if (obj instanceof ScriptObject) {
|
if (obj instanceof ScriptObject) {
|
||||||
if (safe) {
|
if (safe) {
|
||||||
final ScriptObject sobj = (ScriptObject)obj;
|
final ScriptObject sobj = (ScriptObject)obj;
|
||||||
final GlobalObject gobj = (GlobalObject)Context.getGlobalTrusted();
|
final Global gobj = Context.getGlobal();
|
||||||
return gobj.isError(sobj) ?
|
return gobj.isError(sobj) ?
|
||||||
ECMAException.safeToString(sobj) :
|
ECMAException.safeToString(sobj) :
|
||||||
sobj.safeToString();
|
sobj.safeToString();
|
||||||
|
@ -34,6 +34,7 @@ import java.util.RandomAccess;
|
|||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import jdk.nashorn.api.scripting.JSObject;
|
import jdk.nashorn.api.scripting.JSObject;
|
||||||
import jdk.nashorn.api.scripting.ScriptObjectMirror;
|
import jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||||
|
import jdk.nashorn.internal.objects.Global;
|
||||||
import jdk.nashorn.internal.runtime.linker.Bootstrap;
|
import jdk.nashorn.internal.runtime.linker.Bootstrap;
|
||||||
import jdk.nashorn.internal.runtime.linker.InvokeByName;
|
import jdk.nashorn.internal.runtime.linker.InvokeByName;
|
||||||
|
|
||||||
@ -54,7 +55,7 @@ public abstract class ListAdapter extends AbstractList<Object> implements Random
|
|||||||
// These add to the back and front of the list
|
// These add to the back and front of the list
|
||||||
private static final Object PUSH = new Object();
|
private static final Object PUSH = new Object();
|
||||||
private static InvokeByName getPUSH() {
|
private static InvokeByName getPUSH() {
|
||||||
return ((GlobalObject)Context.getGlobal()).getInvokeByName(PUSH,
|
return Context.getGlobal().getInvokeByName(PUSH,
|
||||||
new Callable<InvokeByName>() {
|
new Callable<InvokeByName>() {
|
||||||
@Override
|
@Override
|
||||||
public InvokeByName call() {
|
public InvokeByName call() {
|
||||||
@ -65,7 +66,7 @@ public abstract class ListAdapter extends AbstractList<Object> implements Random
|
|||||||
|
|
||||||
private static final Object UNSHIFT = new Object();
|
private static final Object UNSHIFT = new Object();
|
||||||
private static InvokeByName getUNSHIFT() {
|
private static InvokeByName getUNSHIFT() {
|
||||||
return ((GlobalObject)Context.getGlobal()).getInvokeByName(UNSHIFT,
|
return Context.getGlobal().getInvokeByName(UNSHIFT,
|
||||||
new Callable<InvokeByName>() {
|
new Callable<InvokeByName>() {
|
||||||
@Override
|
@Override
|
||||||
public InvokeByName call() {
|
public InvokeByName call() {
|
||||||
@ -77,7 +78,7 @@ public abstract class ListAdapter extends AbstractList<Object> implements Random
|
|||||||
// These remove from the back and front of the list
|
// These remove from the back and front of the list
|
||||||
private static final Object POP = new Object();
|
private static final Object POP = new Object();
|
||||||
private static InvokeByName getPOP() {
|
private static InvokeByName getPOP() {
|
||||||
return ((GlobalObject)Context.getGlobal()).getInvokeByName(POP,
|
return Context.getGlobal().getInvokeByName(POP,
|
||||||
new Callable<InvokeByName>() {
|
new Callable<InvokeByName>() {
|
||||||
@Override
|
@Override
|
||||||
public InvokeByName call() {
|
public InvokeByName call() {
|
||||||
@ -88,7 +89,7 @@ public abstract class ListAdapter extends AbstractList<Object> implements Random
|
|||||||
|
|
||||||
private static final Object SHIFT = new Object();
|
private static final Object SHIFT = new Object();
|
||||||
private static InvokeByName getSHIFT() {
|
private static InvokeByName getSHIFT() {
|
||||||
return ((GlobalObject)Context.getGlobal()).getInvokeByName(SHIFT,
|
return Context.getGlobal().getInvokeByName(SHIFT,
|
||||||
new Callable<InvokeByName>() {
|
new Callable<InvokeByName>() {
|
||||||
@Override
|
@Override
|
||||||
public InvokeByName call() {
|
public InvokeByName call() {
|
||||||
@ -100,7 +101,7 @@ public abstract class ListAdapter extends AbstractList<Object> implements Random
|
|||||||
// These insert and remove in the middle of the list
|
// These insert and remove in the middle of the list
|
||||||
private static final Object SPLICE_ADD = new Object();
|
private static final Object SPLICE_ADD = new Object();
|
||||||
private static InvokeByName getSPLICE_ADD() {
|
private static InvokeByName getSPLICE_ADD() {
|
||||||
return ((GlobalObject)Context.getGlobal()).getInvokeByName(SPLICE_ADD,
|
return Context.getGlobal().getInvokeByName(SPLICE_ADD,
|
||||||
new Callable<InvokeByName>() {
|
new Callable<InvokeByName>() {
|
||||||
@Override
|
@Override
|
||||||
public InvokeByName call() {
|
public InvokeByName call() {
|
||||||
@ -111,7 +112,7 @@ public abstract class ListAdapter extends AbstractList<Object> implements Random
|
|||||||
|
|
||||||
private static final Object SPLICE_REMOVE = new Object();
|
private static final Object SPLICE_REMOVE = new Object();
|
||||||
private static InvokeByName getSPLICE_REMOVE() {
|
private static InvokeByName getSPLICE_REMOVE() {
|
||||||
return ((GlobalObject)Context.getGlobal()).getInvokeByName(SPLICE_REMOVE,
|
return Context.getGlobal().getInvokeByName(SPLICE_REMOVE,
|
||||||
new Callable<InvokeByName>() {
|
new Callable<InvokeByName>() {
|
||||||
@Override
|
@Override
|
||||||
public InvokeByName call() {
|
public InvokeByName call() {
|
||||||
|
@ -35,7 +35,6 @@ import jdk.internal.dynalink.linker.LinkRequest;
|
|||||||
import jdk.internal.dynalink.support.Guards;
|
import jdk.internal.dynalink.support.Guards;
|
||||||
import jdk.nashorn.internal.lookup.MethodHandleFactory;
|
import jdk.nashorn.internal.lookup.MethodHandleFactory;
|
||||||
import jdk.nashorn.internal.lookup.MethodHandleFunctionality;
|
import jdk.nashorn.internal.lookup.MethodHandleFunctionality;
|
||||||
import jdk.nashorn.internal.objects.NativeJava;
|
|
||||||
import jdk.nashorn.internal.objects.annotations.Attribute;
|
import jdk.nashorn.internal.objects.annotations.Attribute;
|
||||||
import jdk.nashorn.internal.objects.annotations.Function;
|
import jdk.nashorn.internal.objects.annotations.Function;
|
||||||
|
|
||||||
@ -52,7 +51,7 @@ import jdk.nashorn.internal.objects.annotations.Function;
|
|||||||
* var ArrayList = java.util.ArrayList
|
* var ArrayList = java.util.ArrayList
|
||||||
* var list = new ArrayList
|
* var list = new ArrayList
|
||||||
* </pre>
|
* </pre>
|
||||||
* You can also use {@link NativeJava#type(Object, Object)} to access Java classes. These two statements are mostly
|
* You can also use {@link jdk.nashorn.internal.objects.NativeJava#type(Object, Object)} to access Java classes. These two statements are mostly
|
||||||
* equivalent:
|
* equivalent:
|
||||||
* <pre>
|
* <pre>
|
||||||
* var listType1 = java.util.ArrayList
|
* var listType1 = java.util.ArrayList
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
package jdk.nashorn.internal.runtime;
|
package jdk.nashorn.internal.runtime;
|
||||||
|
|
||||||
import jdk.nashorn.api.scripting.NashornException;
|
import jdk.nashorn.api.scripting.NashornException;
|
||||||
|
import jdk.nashorn.internal.objects.Global;
|
||||||
import jdk.nashorn.internal.parser.Token;
|
import jdk.nashorn.internal.parser.Token;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -110,7 +111,7 @@ public final class ParserException extends NashornException {
|
|||||||
* Throw this {@code ParserException} as one of the 7 native JavaScript errors
|
* Throw this {@code ParserException} as one of the 7 native JavaScript errors
|
||||||
* @param global global scope object
|
* @param global global scope object
|
||||||
*/
|
*/
|
||||||
public void throwAsEcmaException(final ScriptObject global) {
|
public void throwAsEcmaException(final Global global) {
|
||||||
throw ECMAErrors.asEcmaException(global, this);
|
throw ECMAErrors.asEcmaException(global, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,9 +84,13 @@ public abstract class Property {
|
|||||||
/** Can this property be undefined? */
|
/** Can this property be undefined? */
|
||||||
public static final int CAN_BE_UNDEFINED = 1 << 8;
|
public static final int CAN_BE_UNDEFINED = 1 << 8;
|
||||||
|
|
||||||
/* Is this a function declaration property ? */
|
/** Is this a function declaration property ? */
|
||||||
public static final int IS_FUNCTION_DECLARATION = 1 << 9;
|
public static final int IS_FUNCTION_DECLARATION = 1 << 9;
|
||||||
|
|
||||||
|
/** Is this property bound to a receiver? This means get/set operations will be delegated to
|
||||||
|
* a statically defined object instead of the object passed as callsite parameter. */
|
||||||
|
public static final int IS_BOUND = 1 << 10;
|
||||||
|
|
||||||
/** Property key. */
|
/** Property key. */
|
||||||
private final String key;
|
private final String key;
|
||||||
|
|
||||||
@ -251,6 +255,16 @@ public abstract class Property {
|
|||||||
return (flags & IS_SPILL) == IS_SPILL;
|
return (flags & IS_SPILL) == IS_SPILL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this property bound to a receiver? If this method returns {@code true} get and set operations
|
||||||
|
* will be delegated to a statically bound object instead of the object passed as parameter.
|
||||||
|
*
|
||||||
|
* @return true if this is a bound property
|
||||||
|
*/
|
||||||
|
public boolean isBound() {
|
||||||
|
return (flags & IS_BOUND) == IS_BOUND;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does this property use any slots in the spill array described in
|
* Does this property use any slots in the spill array described in
|
||||||
* {@link Property#isSpill}? In that case how many. Currently a property
|
* {@link Property#isSpill}? In that case how many. Currently a property
|
||||||
|
@ -103,9 +103,7 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData {
|
|||||||
public RecompilableScriptFunctionData(final FunctionNode functionNode, final CodeInstaller<ScriptEnvironment> installer, final String allocatorClassName, final PropertyMap allocatorMap) {
|
public RecompilableScriptFunctionData(final FunctionNode functionNode, final CodeInstaller<ScriptEnvironment> installer, final String allocatorClassName, final PropertyMap allocatorMap) {
|
||||||
super(functionName(functionNode),
|
super(functionName(functionNode),
|
||||||
functionNode.getParameters().size(),
|
functionNode.getParameters().size(),
|
||||||
functionNode.isStrict(),
|
getFlags(functionNode));
|
||||||
false,
|
|
||||||
true);
|
|
||||||
|
|
||||||
this.functionNode = functionNode;
|
this.functionNode = functionNode;
|
||||||
this.source = functionNode.getSource();
|
this.source = functionNode.getSource();
|
||||||
@ -129,10 +127,11 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData {
|
|||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
if (source != null) {
|
if (source != null) {
|
||||||
sb.append(source.getName())
|
sb.append(source.getName());
|
||||||
.append(':')
|
if (functionNode != null) {
|
||||||
.append(functionNode.getLineNumber())
|
sb.append(':').append(functionNode.getLineNumber());
|
||||||
.append(' ');
|
}
|
||||||
|
sb.append(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
return sb.toString() + super.toString();
|
return sb.toString() + super.toString();
|
||||||
@ -159,6 +158,20 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData {
|
|||||||
return Token.toDesc(TokenType.FUNCTION, position, length);
|
return Token.toDesc(TokenType.FUNCTION, position, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int getFlags(final FunctionNode functionNode) {
|
||||||
|
int flags = IS_CONSTRUCTOR;
|
||||||
|
if (functionNode.isStrict()) {
|
||||||
|
flags |= IS_STRICT;
|
||||||
|
}
|
||||||
|
if (functionNode.needsCallee()) {
|
||||||
|
flags |= NEEDS_CALLEE;
|
||||||
|
}
|
||||||
|
if (functionNode.usesThis() || functionNode.hasEval()) {
|
||||||
|
flags |= USES_THIS;
|
||||||
|
}
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
ScriptObject allocate(final PropertyMap map) {
|
ScriptObject allocate(final PropertyMap map) {
|
||||||
try {
|
try {
|
||||||
@ -182,41 +195,42 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData {
|
|||||||
return allocatorMap;
|
return allocatorMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void ensureCompiled() {
|
||||||
|
if (functionNode != null && functionNode.isLazy()) {
|
||||||
|
Compiler.LOG.info("Trampoline hit: need to do lazy compilation of '", functionNode.getName(), "'");
|
||||||
|
final Compiler compiler = new Compiler(installer);
|
||||||
|
functionNode = compiler.compile(functionNode);
|
||||||
|
assert !functionNode.isLazy();
|
||||||
|
compiler.install(functionNode);
|
||||||
|
flags = getFlags(functionNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected synchronized void ensureCodeGenerated() {
|
protected synchronized void ensureCodeGenerated() {
|
||||||
if (!code.isEmpty()) {
|
if (!code.isEmpty()) {
|
||||||
return; // nothing to do, we have code, at least some.
|
return; // nothing to do, we have code, at least some.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (functionNode.isLazy()) {
|
ensureCompiled();
|
||||||
Compiler.LOG.info("Trampoline hit: need to do lazy compilation of '", functionNode.getName(), "'");
|
|
||||||
final Compiler compiler = new Compiler(installer);
|
|
||||||
functionNode = compiler.compile(functionNode);
|
|
||||||
assert !functionNode.isLazy();
|
|
||||||
compiler.install(functionNode);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We don't need to update any flags - varArgs and needsCallee are instrincic
|
* We can't get to this program point unless we have bytecode, either from
|
||||||
* in the function world we need to get a destination node from the compile instead
|
* eager compilation or from running a lazy compile on the lines above
|
||||||
* and replace it with our function node. TODO
|
*/
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
assert functionNode.hasState(CompilationState.EMITTED) : functionNode.getName() + " " + functionNode.getState() + " " + Debug.id(functionNode);
|
||||||
* We can't get to this program point unless we have bytecode, either from
|
|
||||||
* eager compilation or from running a lazy compile on the lines above
|
|
||||||
*/
|
|
||||||
|
|
||||||
assert functionNode.hasState(CompilationState.EMITTED) : functionNode.getName() + " " + functionNode.getState() + " " + Debug.id(functionNode);
|
// code exists - look it up and add it into the automatically sorted invoker list
|
||||||
|
addCode(functionNode);
|
||||||
|
|
||||||
// code exists - look it up and add it into the automatically sorted invoker list
|
if (! functionNode.canSpecialize()) {
|
||||||
addCode(functionNode);
|
// allow GC to claim IR stuff that is not needed anymore
|
||||||
|
functionNode = null;
|
||||||
if (! functionNode.canSpecialize()) {
|
installer = null;
|
||||||
// allow GC to claim IR stuff that is not needed anymore
|
}
|
||||||
functionNode = null;
|
|
||||||
installer = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private MethodHandle addCode(final FunctionNode fn) {
|
private MethodHandle addCode(final FunctionNode fn) {
|
||||||
|
@ -38,6 +38,7 @@ import jdk.internal.dynalink.linker.GuardedInvocation;
|
|||||||
import jdk.internal.dynalink.linker.LinkRequest;
|
import jdk.internal.dynalink.linker.LinkRequest;
|
||||||
import jdk.nashorn.internal.codegen.CompilerConstants.Call;
|
import jdk.nashorn.internal.codegen.CompilerConstants.Call;
|
||||||
import jdk.nashorn.internal.lookup.MethodHandleFactory;
|
import jdk.nashorn.internal.lookup.MethodHandleFactory;
|
||||||
|
import jdk.nashorn.internal.objects.Global;
|
||||||
import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
|
import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
|
||||||
import jdk.nashorn.internal.runtime.linker.NashornGuards;
|
import jdk.nashorn.internal.runtime.linker.NashornGuards;
|
||||||
|
|
||||||
@ -66,6 +67,8 @@ public abstract class ScriptFunction extends ScriptObject {
|
|||||||
|
|
||||||
private static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", Object.class, Object.class);
|
private static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", Object.class, Object.class);
|
||||||
|
|
||||||
|
private static final MethodHandle GLOBALFILTER = findOwnMH("globalFilter", Object.class, Object.class);
|
||||||
|
|
||||||
/** method handle to scope getter for this ScriptFunction */
|
/** method handle to scope getter for this ScriptFunction */
|
||||||
public static final Call GET_SCOPE = virtualCallNoLookup(ScriptFunction.class, "getScope", ScriptObject.class);
|
public static final Call GET_SCOPE = virtualCallNoLookup(ScriptFunction.class, "getScope", ScriptObject.class);
|
||||||
|
|
||||||
@ -91,9 +94,7 @@ public abstract class ScriptFunction extends ScriptObject {
|
|||||||
* @param map property map
|
* @param map property map
|
||||||
* @param scope scope
|
* @param scope scope
|
||||||
* @param specs specialized version of this function - other method handles
|
* @param specs specialized version of this function - other method handles
|
||||||
* @param strict is this a strict mode function?
|
* @param flags {@link ScriptFunctionData} flags
|
||||||
* @param builtin is this a built in function?
|
|
||||||
* @param isConstructor is this a constructor?
|
|
||||||
*/
|
*/
|
||||||
protected ScriptFunction(
|
protected ScriptFunction(
|
||||||
final String name,
|
final String name,
|
||||||
@ -101,11 +102,9 @@ public abstract class ScriptFunction extends ScriptObject {
|
|||||||
final PropertyMap map,
|
final PropertyMap map,
|
||||||
final ScriptObject scope,
|
final ScriptObject scope,
|
||||||
final MethodHandle[] specs,
|
final MethodHandle[] specs,
|
||||||
final boolean strict,
|
final int flags) {
|
||||||
final boolean builtin,
|
|
||||||
final boolean isConstructor) {
|
|
||||||
|
|
||||||
this(new FinalScriptFunctionData(name, methodHandle, specs, strict, builtin, isConstructor), map, scope);
|
this(new FinalScriptFunctionData(name, methodHandle, specs, flags), map, scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -477,7 +476,14 @@ public abstract class ScriptFunction extends ScriptObject {
|
|||||||
if (obj instanceof ScriptObject || !ScriptFunctionData.isPrimitiveThis(obj)) {
|
if (obj instanceof ScriptObject || !ScriptFunctionData.isPrimitiveThis(obj)) {
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
return ((GlobalObject)Context.getGlobalTrusted()).wrapAsObject(obj);
|
return Context.getGlobal().wrapAsObject(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private static Object globalFilter(final Object object) {
|
||||||
|
// replace whatever we get with the current global object
|
||||||
|
return Context.getGlobal();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -495,11 +501,11 @@ public abstract class ScriptFunction extends ScriptObject {
|
|||||||
@Override
|
@Override
|
||||||
protected GuardedInvocation findCallMethod(final CallSiteDescriptor desc, final LinkRequest request) {
|
protected GuardedInvocation findCallMethod(final CallSiteDescriptor desc, final LinkRequest request) {
|
||||||
final MethodType type = desc.getMethodType();
|
final MethodType type = desc.getMethodType();
|
||||||
|
final boolean scopeCall = NashornCallSiteDescriptor.isScope(desc);
|
||||||
|
|
||||||
if (request.isCallSiteUnstable()) {
|
if (request.isCallSiteUnstable()) {
|
||||||
// (this, callee, args...) => (this, callee, args[])
|
// (callee, this, args...) => (callee, this, args[])
|
||||||
final MethodHandle collector = MH.asCollector(ScriptRuntime.APPLY.methodHandle(), Object[].class,
|
final MethodHandle collector = MH.asCollector(ScriptRuntime.APPLY.methodHandle(), Object[].class, type.parameterCount() - 2);
|
||||||
type.parameterCount() - 2);
|
|
||||||
|
|
||||||
// If call site is statically typed to take a ScriptFunction, we don't need a guard, otherwise we need a
|
// If call site is statically typed to take a ScriptFunction, we don't need a guard, otherwise we need a
|
||||||
// generic "is this a ScriptFunction?" guard.
|
// generic "is this a ScriptFunction?" guard.
|
||||||
@ -510,17 +516,12 @@ public abstract class ScriptFunction extends ScriptObject {
|
|||||||
MethodHandle boundHandle;
|
MethodHandle boundHandle;
|
||||||
MethodHandle guard = null;
|
MethodHandle guard = null;
|
||||||
|
|
||||||
final boolean scopeCall = NashornCallSiteDescriptor.isScope(desc);
|
|
||||||
|
|
||||||
if (data.needsCallee()) {
|
if (data.needsCallee()) {
|
||||||
final MethodHandle callHandle = getBestInvoker(type, request.getArguments());
|
final MethodHandle callHandle = getBestInvoker(type, request.getArguments());
|
||||||
if (scopeCall) {
|
if (scopeCall && needsWrappedThis()) {
|
||||||
// Make a handle that drops the passed "this" argument and substitutes either Global or Undefined
|
// Make a handle that drops the passed "this" argument and substitutes either Global or Undefined
|
||||||
// (callee, this, args...) => (callee, args...)
|
// (callee, this, args...) => (callee, [this], args...)
|
||||||
boundHandle = MH.insertArguments(callHandle, 1, needsWrappedThis() ? Context.getGlobalTrusted() : ScriptRuntime.UNDEFINED);
|
boundHandle = MH.filterArguments(callHandle, 1, GLOBALFILTER);
|
||||||
// (callee, args...) => (callee, [this], args...)
|
|
||||||
boundHandle = MH.dropArguments(boundHandle, 1, Object.class);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// It's already (callee, this, args...), just what we need
|
// It's already (callee, this, args...), just what we need
|
||||||
boundHandle = callHandle;
|
boundHandle = callHandle;
|
||||||
@ -531,12 +532,12 @@ public abstract class ScriptFunction extends ScriptObject {
|
|||||||
// NOTE: the only built-in named "extend" is NativeJava.extend. As a special-case we're binding the
|
// NOTE: the only built-in named "extend" is NativeJava.extend. As a special-case we're binding the
|
||||||
// current lookup as its "this" so it can do security-sensitive creation of adapter classes.
|
// current lookup as its "this" so it can do security-sensitive creation of adapter classes.
|
||||||
boundHandle = MH.dropArguments(MH.bindTo(callHandle, desc.getLookup()), 0, Object.class, Object.class);
|
boundHandle = MH.dropArguments(MH.bindTo(callHandle, desc.getLookup()), 0, Object.class, Object.class);
|
||||||
} else if (scopeCall) {
|
} else if (scopeCall && needsWrappedThis()) {
|
||||||
// Make a handle that drops the passed "this" argument and substitutes either Global or Undefined
|
// Make a handle that drops the passed "this" argument and substitutes either Global or Undefined
|
||||||
// (this, args...) => (args...)
|
// (this, args...) => ([this], args...)
|
||||||
boundHandle = MH.bindTo(callHandle, needsWrappedThis() ? Context.getGlobalTrusted() : ScriptRuntime.UNDEFINED);
|
boundHandle = MH.filterArguments(callHandle, 0, GLOBALFILTER);
|
||||||
// (args...) => ([callee], [this], args...)
|
// ([this], args...) => ([callee], [this], args...)
|
||||||
boundHandle = MH.dropArguments(boundHandle, 0, Object.class, Object.class);
|
boundHandle = MH.dropArguments(boundHandle, 0, Object.class);
|
||||||
} else {
|
} else {
|
||||||
// (this, args...) => ([callee], this, args...)
|
// (this, args...) => ([callee], this, args...)
|
||||||
boundHandle = MH.dropArguments(callHandle, 0, Object.class);
|
boundHandle = MH.dropArguments(callHandle, 0, Object.class);
|
||||||
|
@ -32,6 +32,7 @@ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
|
|||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.lang.invoke.MethodType;
|
import java.lang.invoke.MethodType;
|
||||||
|
import jdk.nashorn.internal.objects.Global;
|
||||||
import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory;
|
import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -47,33 +48,44 @@ public abstract class ScriptFunctionData {
|
|||||||
/** All versions of this function that have been generated to code */
|
/** All versions of this function that have been generated to code */
|
||||||
protected final CompiledFunctions code;
|
protected final CompiledFunctions code;
|
||||||
|
|
||||||
|
/** Function flags */
|
||||||
|
protected int flags;
|
||||||
|
|
||||||
private int arity;
|
private int arity;
|
||||||
|
|
||||||
private final boolean isStrict;
|
|
||||||
|
|
||||||
private final boolean isBuiltin;
|
|
||||||
|
|
||||||
private final boolean isConstructor;
|
|
||||||
|
|
||||||
private static final MethodHandle NEWFILTER = findOwnMH("newFilter", Object.class, Object.class, Object.class);
|
private static final MethodHandle NEWFILTER = findOwnMH("newFilter", Object.class, Object.class, Object.class);
|
||||||
private static final MethodHandle BIND_VAR_ARGS = findOwnMH("bindVarArgs", Object[].class, Object[].class, Object[].class);
|
private static final MethodHandle BIND_VAR_ARGS = findOwnMH("bindVarArgs", Object[].class, Object[].class, Object[].class);
|
||||||
|
|
||||||
|
/** Is this a strict mode function? */
|
||||||
|
public static final int IS_STRICT = 1 << 0;
|
||||||
|
/** Is this a built-in function? */
|
||||||
|
public static final int IS_BUILTIN = 1 << 1;
|
||||||
|
/** Is this a constructor function? */
|
||||||
|
public static final int IS_CONSTRUCTOR = 1 << 2;
|
||||||
|
/** Does this function expect a callee argument? */
|
||||||
|
public static final int NEEDS_CALLEE = 1 << 3;
|
||||||
|
/** Does this function make use of the this-object argument? */
|
||||||
|
public static final int USES_THIS = 1 << 4;
|
||||||
|
|
||||||
|
/** Flag for strict or built-in functions */
|
||||||
|
public static final int IS_STRICT_OR_BUILTIN = IS_STRICT | IS_BUILTIN;
|
||||||
|
/** Flag for built-in constructors */
|
||||||
|
public static final int IS_BUILTIN_CONSTRUCTOR = IS_BUILTIN | IS_CONSTRUCTOR;
|
||||||
|
/** Flag for strict constructors */
|
||||||
|
public static final int IS_STRICT_CONSTRUCTOR = IS_STRICT | IS_CONSTRUCTOR;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param name script function name
|
* @param name script function name
|
||||||
* @param arity arity
|
* @param arity arity
|
||||||
* @param isStrict is the function strict
|
* @param flags the function flags
|
||||||
* @param isBuiltin is the function built in
|
|
||||||
* @param isConstructor is the function a constructor
|
|
||||||
*/
|
*/
|
||||||
ScriptFunctionData(final String name, final int arity, final boolean isStrict, final boolean isBuiltin, final boolean isConstructor) {
|
ScriptFunctionData(final String name, final int arity, final int flags) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.arity = arity;
|
this.arity = arity;
|
||||||
this.code = new CompiledFunctions();
|
this.code = new CompiledFunctions();
|
||||||
this.isStrict = isStrict;
|
this.flags = flags;
|
||||||
this.isBuiltin = isBuiltin;
|
|
||||||
this.isConstructor = isConstructor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final int getArity() {
|
final int getArity() {
|
||||||
@ -105,21 +117,21 @@ public abstract class ScriptFunctionData {
|
|||||||
* @return true if strict, false otherwise
|
* @return true if strict, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean isStrict() {
|
public boolean isStrict() {
|
||||||
return isStrict;
|
return (flags & IS_STRICT) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isBuiltin() {
|
boolean isBuiltin() {
|
||||||
return isBuiltin;
|
return (flags & IS_BUILTIN) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isConstructor() {
|
boolean isConstructor() {
|
||||||
return isConstructor;
|
return (flags & IS_CONSTRUCTOR) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean needsCallee() {
|
boolean needsCallee() {
|
||||||
// we don't know if we need a callee or not unless we are generated
|
// we don't know if we need a callee or not unless code has been compiled
|
||||||
ensureCodeGenerated();
|
ensureCompiled();
|
||||||
return code.needsCallee();
|
return (flags & NEEDS_CALLEE) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -128,7 +140,7 @@ public abstract class ScriptFunctionData {
|
|||||||
* @return true if this argument must be an object
|
* @return true if this argument must be an object
|
||||||
*/
|
*/
|
||||||
boolean needsWrappedThis() {
|
boolean needsWrappedThis() {
|
||||||
return !isStrict && !isBuiltin;
|
return (flags & USES_THIS) != 0 && (flags & IS_STRICT_OR_BUILTIN) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
String toSource() {
|
String toSource() {
|
||||||
@ -201,6 +213,15 @@ public abstract class ScriptFunctionData {
|
|||||||
//empty
|
//empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If we can have lazy code generation, this is a hook to ensure that the code has been compiled.
|
||||||
|
* This does not guarantee the code been installed in this {@code ScriptFunctionData} instance;
|
||||||
|
* use {@link #ensureCodeGenerated()} to install the actual method handles.
|
||||||
|
*/
|
||||||
|
protected void ensureCompiled() {
|
||||||
|
//empty
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a generic Object/Object invoker for this method. It will ensure code
|
* Return a generic Object/Object invoker for this method. It will ensure code
|
||||||
* is generated, get the most generic of all versions of this function and adapt it
|
* is generated, get the most generic of all versions of this function and adapt it
|
||||||
@ -259,6 +280,8 @@ public abstract class ScriptFunctionData {
|
|||||||
|
|
||||||
final Object[] allArgs = args == null ? ScriptRuntime.EMPTY_ARRAY : args;
|
final Object[] allArgs = args == null ? ScriptRuntime.EMPTY_ARRAY : args;
|
||||||
final int length = args == null ? 0 : args.length;
|
final int length = args == null ? 0 : args.length;
|
||||||
|
// Clear the callee and this flags
|
||||||
|
final int boundFlags = flags & ~NEEDS_CALLEE & ~USES_THIS;
|
||||||
|
|
||||||
CompiledFunctions boundList = new CompiledFunctions();
|
CompiledFunctions boundList = new CompiledFunctions();
|
||||||
if (code.size() == 1) {
|
if (code.size() == 1) {
|
||||||
@ -273,8 +296,7 @@ public abstract class ScriptFunctionData {
|
|||||||
boundList.add(bind(inv, fn, self, allArgs));
|
boundList.add(bind(inv, fn, self, allArgs));
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptFunctionData boundData = new FinalScriptFunctionData(name, arity == -1 ? -1 : Math.max(0, arity - length), boundList, isStrict(), isBuiltin(), isConstructor());
|
return new FinalScriptFunctionData(name, arity == -1 ? -1 : Math.max(0, arity - length), boundList, boundFlags);
|
||||||
return boundData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -351,11 +373,11 @@ public abstract class ScriptFunctionData {
|
|||||||
private Object convertThisObject(final Object thiz) {
|
private Object convertThisObject(final Object thiz) {
|
||||||
if (!(thiz instanceof ScriptObject) && needsWrappedThis()) {
|
if (!(thiz instanceof ScriptObject) && needsWrappedThis()) {
|
||||||
if (JSType.nullOrUndefined(thiz)) {
|
if (JSType.nullOrUndefined(thiz)) {
|
||||||
return Context.getGlobalTrusted();
|
return Context.getGlobal();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isPrimitiveThis(thiz)) {
|
if (isPrimitiveThis(thiz)) {
|
||||||
return ((GlobalObject)Context.getGlobalTrusted()).wrapAsObject(thiz);
|
return Context.getGlobal().wrapAsObject(thiz);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,6 +66,7 @@ import jdk.nashorn.internal.lookup.Lookup;
|
|||||||
import jdk.nashorn.internal.lookup.MethodHandleFactory;
|
import jdk.nashorn.internal.lookup.MethodHandleFactory;
|
||||||
import jdk.nashorn.internal.objects.AccessorPropertyDescriptor;
|
import jdk.nashorn.internal.objects.AccessorPropertyDescriptor;
|
||||||
import jdk.nashorn.internal.objects.DataPropertyDescriptor;
|
import jdk.nashorn.internal.objects.DataPropertyDescriptor;
|
||||||
|
import jdk.nashorn.internal.objects.Global;
|
||||||
import jdk.nashorn.internal.runtime.arrays.ArrayData;
|
import jdk.nashorn.internal.runtime.arrays.ArrayData;
|
||||||
import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
|
import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
|
||||||
import jdk.nashorn.internal.runtime.linker.Bootstrap;
|
import jdk.nashorn.internal.runtime.linker.Bootstrap;
|
||||||
@ -131,7 +132,8 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
|
|
||||||
static final MethodHandle GETPROTO = findOwnMH("getProto", ScriptObject.class);
|
static final MethodHandle GETPROTO = findOwnMH("getProto", ScriptObject.class);
|
||||||
static final MethodHandle SETPROTOCHECK = findOwnMH("setProtoCheck", void.class, Object.class);
|
static final MethodHandle SETPROTOCHECK = findOwnMH("setProtoCheck", void.class, Object.class);
|
||||||
static final MethodHandle MEGAMORPHIC_GET = findOwnMH("megamorphicGet", Object.class, String.class, boolean.class);
|
static final MethodHandle MEGAMORPHIC_GET = findOwnMH("megamorphicGet", Object.class, String.class, boolean.class, boolean.class);
|
||||||
|
static final MethodHandle GLOBALFILTER = findOwnMH("globalFilter", Object.class, Object.class);
|
||||||
|
|
||||||
static final MethodHandle SETFIELD = findOwnMH("setField", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, MethodHandle.class, Object.class, Object.class);
|
static final MethodHandle SETFIELD = findOwnMH("setField", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, MethodHandle.class, Object.class, Object.class);
|
||||||
static final MethodHandle SETSPILL = findOwnMH("setSpill", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class);
|
static final MethodHandle SETSPILL = findOwnMH("setSpill", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class);
|
||||||
@ -225,6 +227,7 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
final Property oldProp = newMap.findProperty(key);
|
final Property oldProp = newMap.findProperty(key);
|
||||||
if (oldProp == null) {
|
if (oldProp == null) {
|
||||||
if (property instanceof UserAccessorProperty) {
|
if (property instanceof UserAccessorProperty) {
|
||||||
|
// Note: we copy accessor functions to this object which is semantically different from binding.
|
||||||
final UserAccessorProperty prop = this.newUserAccessors(key, property.getFlags(), property.getGetterFunction(source), property.getSetterFunction(source));
|
final UserAccessorProperty prop = this.newUserAccessors(key, property.getFlags(), property.getGetterFunction(source), property.getSetterFunction(source));
|
||||||
newMap = newMap.addPropertyNoHistory(prop);
|
newMap = newMap.addPropertyNoHistory(prop);
|
||||||
} else {
|
} else {
|
||||||
@ -322,18 +325,18 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
* @return property descriptor
|
* @return property descriptor
|
||||||
*/
|
*/
|
||||||
public final PropertyDescriptor toPropertyDescriptor() {
|
public final PropertyDescriptor toPropertyDescriptor() {
|
||||||
final GlobalObject global = (GlobalObject) Context.getGlobalTrusted();
|
final Global global = Context.getGlobal();
|
||||||
|
|
||||||
final PropertyDescriptor desc;
|
final PropertyDescriptor desc;
|
||||||
if (isDataDescriptor()) {
|
if (isDataDescriptor()) {
|
||||||
if (has(SET) || has(GET)) {
|
if (has(SET) || has(GET)) {
|
||||||
throw typeError((ScriptObject)global, "inconsistent.property.descriptor");
|
throw typeError(global, "inconsistent.property.descriptor");
|
||||||
}
|
}
|
||||||
|
|
||||||
desc = global.newDataDescriptor(UNDEFINED, false, false, false);
|
desc = global.newDataDescriptor(UNDEFINED, false, false, false);
|
||||||
} else if (isAccessorDescriptor()) {
|
} else if (isAccessorDescriptor()) {
|
||||||
if (has(VALUE) || has(WRITABLE)) {
|
if (has(VALUE) || has(WRITABLE)) {
|
||||||
throw typeError((ScriptObject)global, "inconsistent.property.descriptor");
|
throw typeError(global, "inconsistent.property.descriptor");
|
||||||
}
|
}
|
||||||
|
|
||||||
desc = global.newAccessorDescriptor(UNDEFINED, UNDEFINED, false, false);
|
desc = global.newAccessorDescriptor(UNDEFINED, UNDEFINED, false, false);
|
||||||
@ -352,7 +355,7 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
*
|
*
|
||||||
* @return property descriptor
|
* @return property descriptor
|
||||||
*/
|
*/
|
||||||
public static PropertyDescriptor toPropertyDescriptor(final ScriptObject global, final Object obj) {
|
public static PropertyDescriptor toPropertyDescriptor(final Global global, final Object obj) {
|
||||||
if (obj instanceof ScriptObject) {
|
if (obj instanceof ScriptObject) {
|
||||||
return ((ScriptObject)obj).toPropertyDescriptor();
|
return ((ScriptObject)obj).toPropertyDescriptor();
|
||||||
}
|
}
|
||||||
@ -371,7 +374,7 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
public Object getOwnPropertyDescriptor(final String key) {
|
public Object getOwnPropertyDescriptor(final String key) {
|
||||||
final Property property = getMap().findProperty(key);
|
final Property property = getMap().findProperty(key);
|
||||||
|
|
||||||
final GlobalObject global = (GlobalObject)Context.getGlobalTrusted();
|
final Global global = Context.getGlobal();
|
||||||
|
|
||||||
if (property != null) {
|
if (property != null) {
|
||||||
final ScriptFunction get = property.getGetterFunction(this);
|
final ScriptFunction get = property.getGetterFunction(this);
|
||||||
@ -436,7 +439,7 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
* @return true if property was successfully defined
|
* @return true if property was successfully defined
|
||||||
*/
|
*/
|
||||||
public boolean defineOwnProperty(final String key, final Object propertyDesc, final boolean reject) {
|
public boolean defineOwnProperty(final String key, final Object propertyDesc, final boolean reject) {
|
||||||
final ScriptObject global = Context.getGlobalTrusted();
|
final Global global = Context.getGlobal();
|
||||||
final PropertyDescriptor desc = toPropertyDescriptor(global, propertyDesc);
|
final PropertyDescriptor desc = toPropertyDescriptor(global, propertyDesc);
|
||||||
final Object current = getOwnPropertyDescriptor(key);
|
final Object current = getOwnPropertyDescriptor(key);
|
||||||
final String name = JSType.toString(key);
|
final String name = JSType.toString(key);
|
||||||
@ -634,7 +637,7 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
final int propFlags = Property.toFlags(pdesc);
|
final int propFlags = Property.toFlags(pdesc);
|
||||||
|
|
||||||
if (pdesc.type() == PropertyDescriptor.GENERIC) {
|
if (pdesc.type() == PropertyDescriptor.GENERIC) {
|
||||||
final GlobalObject global = (GlobalObject) Context.getGlobalTrusted();
|
final Global global = Context.getGlobal();
|
||||||
final PropertyDescriptor dDesc = global.newDataDescriptor(UNDEFINED, false, false, false);
|
final PropertyDescriptor dDesc = global.newDataDescriptor(UNDEFINED, false, false, false);
|
||||||
|
|
||||||
dDesc.fillFrom((ScriptObject)pdesc);
|
dDesc.fillFrom((ScriptObject)pdesc);
|
||||||
@ -974,17 +977,6 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
return ObjectClassGenerator.UNDEFINED_DOUBLE;
|
return ObjectClassGenerator.UNDEFINED_DOUBLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the object value of a property
|
|
||||||
*
|
|
||||||
* @param find {@link FindProperty} lookup result
|
|
||||||
*
|
|
||||||
* @return the value of the property
|
|
||||||
*/
|
|
||||||
protected static Object getObjectValue(final FindProperty find) {
|
|
||||||
return find.getObjectValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return methodHandle of value function for call.
|
* Return methodHandle of value function for call.
|
||||||
*
|
*
|
||||||
@ -995,7 +987,7 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
* @return value of property as a MethodHandle or null.
|
* @return value of property as a MethodHandle or null.
|
||||||
*/
|
*/
|
||||||
protected MethodHandle getCallMethodHandle(final FindProperty find, final MethodType type, final String bindName) {
|
protected MethodHandle getCallMethodHandle(final FindProperty find, final MethodType type, final String bindName) {
|
||||||
return getCallMethodHandle(getObjectValue(find), type, bindName);
|
return getCallMethodHandle(find.getObjectValue(), type, bindName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1019,7 +1011,7 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
* @return Value of property.
|
* @return Value of property.
|
||||||
*/
|
*/
|
||||||
public final Object getWithProperty(final Property property) {
|
public final Object getWithProperty(final Property property) {
|
||||||
return getObjectValue(new FindProperty(this, this, property));
|
return new FindProperty(this, this, property).getObjectValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1158,7 +1150,7 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
}
|
}
|
||||||
setProto((ScriptObject)newProto);
|
setProto((ScriptObject)newProto);
|
||||||
} else {
|
} else {
|
||||||
final ScriptObject global = Context.getGlobalTrusted();
|
final Global global = Context.getGlobal();
|
||||||
final Object newProtoObject = JSType.toScriptObject(global, newProto);
|
final Object newProtoObject = JSType.toScriptObject(global, newProto);
|
||||||
|
|
||||||
if (newProtoObject instanceof ScriptObject) {
|
if (newProtoObject instanceof ScriptObject) {
|
||||||
@ -1248,11 +1240,11 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
* @return the default value
|
* @return the default value
|
||||||
*/
|
*/
|
||||||
public Object getDefaultValue(final Class<?> typeHint) {
|
public Object getDefaultValue(final Class<?> typeHint) {
|
||||||
// We delegate to GlobalObject, as the implementation uses dynamic call sites to invoke object's "toString" and
|
// We delegate to Global, as the implementation uses dynamic call sites to invoke object's "toString" and
|
||||||
// "valueOf" methods, and in order to avoid those call sites from becoming megamorphic when multiple contexts
|
// "valueOf" methods, and in order to avoid those call sites from becoming megamorphic when multiple contexts
|
||||||
// are being executed in a long-running program, we move the code and their associated dynamic call sites
|
// are being executed in a long-running program, we move the code and their associated dynamic call sites
|
||||||
// (Global.TO_STRING and Global.VALUE_OF) into per-context code.
|
// (Global.TO_STRING and Global.VALUE_OF) into per-context code.
|
||||||
return ((GlobalObject)Context.getGlobalTrusted()).getDefaultValue(this, typeHint);
|
return Context.getGlobal().getDefaultValue(this, typeHint);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1740,7 +1732,7 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operator) {
|
protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operator) {
|
||||||
final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
|
final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
|
||||||
if (request.isCallSiteUnstable() || hasWithScope()) {
|
if (request.isCallSiteUnstable() || hasWithScope()) {
|
||||||
return findMegaMorphicGetMethod(desc, name, "getMethod".equals(operator));
|
return findMegaMorphicGetMethod(desc, name, "getMethod".equals(operator), isScope() && NashornCallSiteDescriptor.isScope(desc));
|
||||||
}
|
}
|
||||||
|
|
||||||
final FindProperty find = findProperty(name, true);
|
final FindProperty find = findProperty(name, true);
|
||||||
@ -1765,9 +1757,8 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
final Property property = find.getProperty();
|
final Property property = find.getProperty();
|
||||||
methodHandle = find.getGetter(returnType);
|
methodHandle = find.getGetter(returnType);
|
||||||
|
|
||||||
final boolean noGuard = ObjectClassGenerator.OBJECT_FIELDS_ONLY && NashornCallSiteDescriptor.isFastScope(desc) && !property.canChangeType();
|
// Get the appropriate guard for this callsite and property.
|
||||||
// getMap() is fine as we have the prototype switchpoint depending on where the property was found
|
final MethodHandle guard = NashornGuards.getGuard(this, property, desc);
|
||||||
final MethodHandle guard = noGuard ? null : NashornGuards.getMapGuard(getMap());
|
|
||||||
final ScriptObject owner = find.getOwner();
|
final ScriptObject owner = find.getOwner();
|
||||||
|
|
||||||
if (methodHandle != null) {
|
if (methodHandle != null) {
|
||||||
@ -1777,31 +1768,32 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!property.hasGetterFunction(owner)) {
|
if (!property.hasGetterFunction(owner)) {
|
||||||
// If not a scope bind to actual prototype as changing prototype will change the property map.
|
// Add a filter that replaces the self object with the prototype owning the property.
|
||||||
// For scopes we install a filter that replaces the self object with the prototype owning the property.
|
methodHandle = addProtoFilter(methodHandle, find.getProtoChainLength());
|
||||||
methodHandle = isScope() ?
|
|
||||||
addProtoFilter(methodHandle, find.getProtoChainLength()) :
|
|
||||||
bindTo(methodHandle, owner);
|
|
||||||
}
|
}
|
||||||
return new GuardedInvocation(methodHandle, noGuard ? null : getProtoSwitchPoint(name, owner), guard);
|
return new GuardedInvocation(methodHandle, guard == null ? null : getProtoSwitchPoint(name, owner), guard);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert !NashornCallSiteDescriptor.isFastScope(desc);
|
assert !NashornCallSiteDescriptor.isFastScope(desc);
|
||||||
return new GuardedInvocation(Lookup.emptyGetter(returnType), getProtoSwitchPoint(name, owner), guard);
|
return new GuardedInvocation(Lookup.emptyGetter(returnType), getProtoSwitchPoint(name, owner), guard);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name, final boolean isMethod) {
|
private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name,
|
||||||
final MethodHandle invoker = MH.insertArguments(MEGAMORPHIC_GET, 1, name, isMethod);
|
final boolean isMethod, final boolean isScope) {
|
||||||
|
final MethodHandle invoker = MH.insertArguments(MEGAMORPHIC_GET, 1, name, isMethod, isScope);
|
||||||
final MethodHandle guard = getScriptObjectGuard(desc.getMethodType());
|
final MethodHandle guard = getScriptObjectGuard(desc.getMethodType());
|
||||||
return new GuardedInvocation(invoker, guard);
|
return new GuardedInvocation(invoker, guard);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private Object megamorphicGet(final String key, final boolean isMethod) {
|
private Object megamorphicGet(final String key, final boolean isMethod, final boolean isScope) {
|
||||||
final FindProperty find = findProperty(key, true);
|
final FindProperty find = findProperty(key, true);
|
||||||
|
|
||||||
if (find != null) {
|
if (find != null) {
|
||||||
return getObjectValue(find);
|
return find.getObjectValue();
|
||||||
|
}
|
||||||
|
if (isScope) {
|
||||||
|
throw referenceError("not.defined", key);
|
||||||
}
|
}
|
||||||
|
|
||||||
return isMethod ? getNoSuchMethod(key) : invokeNoSuchProperty(key);
|
return isMethod ? getNoSuchMethod(key) : invokeNoSuchProperty(key);
|
||||||
@ -1996,6 +1988,15 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private static Object globalFilter(final Object object) {
|
||||||
|
ScriptObject sobj = (ScriptObject) object;
|
||||||
|
while (sobj != null && !(sobj instanceof Global)) {
|
||||||
|
sobj = sobj.getProto();
|
||||||
|
}
|
||||||
|
return sobj;
|
||||||
|
}
|
||||||
|
|
||||||
private static GuardedInvocation findMegaMorphicSetMethod(final CallSiteDescriptor desc, final String name) {
|
private static GuardedInvocation findMegaMorphicSetMethod(final CallSiteDescriptor desc, final String name) {
|
||||||
final MethodType type = desc.getMethodType().insertParameterTypes(1, Object.class);
|
final MethodType type = desc.getMethodType().insertParameterTypes(1, Object.class);
|
||||||
final GuardedInvocation inv = findSetIndexMethod(type, NashornCallSiteDescriptor.isStrict(desc));
|
final GuardedInvocation inv = findSetIndexMethod(type, NashornCallSiteDescriptor.isStrict(desc));
|
||||||
@ -2041,7 +2042,7 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
return noSuchProperty(desc, request);
|
return noSuchProperty(desc, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Object value = getObjectValue(find);
|
final Object value = find.getObjectValue();
|
||||||
if (! (value instanceof ScriptFunction)) {
|
if (! (value instanceof ScriptFunction)) {
|
||||||
return createEmptyGetter(desc, name);
|
return createEmptyGetter(desc, name);
|
||||||
}
|
}
|
||||||
@ -2067,7 +2068,7 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
final boolean scopeAccess = isScope() && NashornCallSiteDescriptor.isScope(desc);
|
final boolean scopeAccess = isScope() && NashornCallSiteDescriptor.isScope(desc);
|
||||||
|
|
||||||
if (find != null) {
|
if (find != null) {
|
||||||
final Object value = getObjectValue(find);
|
final Object value = find.getObjectValue();
|
||||||
ScriptFunction func = null;
|
ScriptFunction func = null;
|
||||||
MethodHandle methodHandle = null;
|
MethodHandle methodHandle = null;
|
||||||
|
|
||||||
@ -2102,7 +2103,7 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
final FindProperty find = findProperty(NO_SUCH_PROPERTY_NAME, true);
|
final FindProperty find = findProperty(NO_SUCH_PROPERTY_NAME, true);
|
||||||
|
|
||||||
if (find != null) {
|
if (find != null) {
|
||||||
final Object func = getObjectValue(find);
|
final Object func = find.getObjectValue();
|
||||||
|
|
||||||
if (func instanceof ScriptFunction) {
|
if (func instanceof ScriptFunction) {
|
||||||
return ScriptRuntime.apply((ScriptFunction)func, this, name);
|
return ScriptRuntime.apply((ScriptFunction)func, this, name);
|
||||||
@ -2124,7 +2125,7 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
return invokeNoSuchProperty(name);
|
return invokeNoSuchProperty(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Object value = getObjectValue(find);
|
final Object value = find.getObjectValue();
|
||||||
if (! (value instanceof ScriptFunction)) {
|
if (! (value instanceof ScriptFunction)) {
|
||||||
return UNDEFINED;
|
return UNDEFINED;
|
||||||
}
|
}
|
||||||
@ -2664,7 +2665,7 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
final FindProperty find = object.findProperty(key, false, false, this);
|
final FindProperty find = object.findProperty(key, false, false, this);
|
||||||
|
|
||||||
if (find != null) {
|
if (find != null) {
|
||||||
return getObjectValue(find);
|
return find.getObjectValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2682,7 +2683,7 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
final FindProperty find = findProperty(key, true);
|
final FindProperty find = findProperty(key, true);
|
||||||
|
|
||||||
if (find != null) {
|
if (find != null) {
|
||||||
return getObjectValue(find);
|
return find.getObjectValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2823,7 +2824,15 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
throw typeError("object.non.extensible", key, ScriptRuntime.safeToString(this));
|
throw typeError("object.non.extensible", key, ScriptRuntime.safeToString(this));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
spill(key, value);
|
ScriptObject sobj = this;
|
||||||
|
// undefined scope properties are set in the global object.
|
||||||
|
if (isScope()) {
|
||||||
|
while (sobj != null && !(sobj instanceof Global)) {
|
||||||
|
sobj = sobj.getProto();
|
||||||
|
}
|
||||||
|
assert sobj != null : "no parent global object in scope";
|
||||||
|
}
|
||||||
|
sobj.spill(key, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -474,7 +474,7 @@ public final class ScriptRuntime {
|
|||||||
* @return {@link WithObject} that is the new scope
|
* @return {@link WithObject} that is the new scope
|
||||||
*/
|
*/
|
||||||
public static ScriptObject openWith(final ScriptObject scope, final Object expression) {
|
public static ScriptObject openWith(final ScriptObject scope, final Object expression) {
|
||||||
final ScriptObject global = Context.getGlobalTrusted();
|
final Global global = Context.getGlobal();
|
||||||
if (expression == UNDEFINED) {
|
if (expression == UNDEFINED) {
|
||||||
throw typeError(global, "cant.apply.with.to.undefined");
|
throw typeError(global, "cant.apply.with.to.undefined");
|
||||||
} else if (expression == null) {
|
} else if (expression == null) {
|
||||||
|
@ -31,7 +31,6 @@ import static jdk.nashorn.internal.lookup.Lookup.MH;
|
|||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import jdk.internal.dynalink.CallSiteDescriptor;
|
import jdk.internal.dynalink.CallSiteDescriptor;
|
||||||
import jdk.internal.dynalink.linker.GuardedInvocation;
|
import jdk.internal.dynalink.linker.GuardedInvocation;
|
||||||
import jdk.nashorn.internal.codegen.ObjectClassGenerator;
|
|
||||||
import jdk.nashorn.internal.lookup.Lookup;
|
import jdk.nashorn.internal.lookup.Lookup;
|
||||||
import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
|
import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
|
||||||
import jdk.nashorn.internal.runtime.linker.NashornGuards;
|
import jdk.nashorn.internal.runtime.linker.NashornGuards;
|
||||||
@ -104,21 +103,9 @@ final class SetMethodCreator {
|
|||||||
* @return the composed guarded invocation that represents the dynamic setter method for the property.
|
* @return the composed guarded invocation that represents the dynamic setter method for the property.
|
||||||
*/
|
*/
|
||||||
GuardedInvocation createGuardedInvocation() {
|
GuardedInvocation createGuardedInvocation() {
|
||||||
return new GuardedInvocation(methodHandle, getGuard());
|
return new GuardedInvocation(methodHandle, NashornGuards.getGuard(sobj, property, desc));
|
||||||
}
|
}
|
||||||
|
|
||||||
private MethodHandle getGuard() {
|
|
||||||
return needsNoGuard() ? null : NashornGuards.getMapGuard(getMap());
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean needsNoGuard() {
|
|
||||||
return NashornCallSiteDescriptor.isFastScope(desc) &&
|
|
||||||
(ObjectClassGenerator.OBJECT_FIELDS_ONLY || isPropertyTypeStable());
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isPropertyTypeStable() {
|
|
||||||
return property == null || !property.canChangeType();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private SetMethod createSetMethod() {
|
private SetMethod createSetMethod() {
|
||||||
@ -153,10 +140,7 @@ final class SetMethodCreator {
|
|||||||
|
|
||||||
final MethodHandle boundHandle;
|
final MethodHandle boundHandle;
|
||||||
if (!property.hasSetterFunction(find.getOwner()) && find.isInherited()) {
|
if (!property.hasSetterFunction(find.getOwner()) && find.isInherited()) {
|
||||||
// Bind or add prototype filter depending on whether this is a scope object.
|
boundHandle = ScriptObject.addProtoFilter(methodHandle, find.getProtoChainLength());
|
||||||
boundHandle = sobj.isScope() ?
|
|
||||||
ScriptObject.addProtoFilter(methodHandle, find.getProtoChainLength()):
|
|
||||||
ScriptObject.bindTo(methodHandle, find.getOwner());
|
|
||||||
} else {
|
} else {
|
||||||
boundHandle = methodHandle;
|
boundHandle = methodHandle;
|
||||||
}
|
}
|
||||||
@ -164,8 +148,8 @@ final class SetMethodCreator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private SetMethod createGlobalPropertySetter() {
|
private SetMethod createGlobalPropertySetter() {
|
||||||
final ScriptObject global = Context.getGlobalTrusted();
|
final ScriptObject global = Context.getGlobal();
|
||||||
return new SetMethod(ScriptObject.bindTo(global.addSpill(getName()), global), null);
|
return new SetMethod(MH.filterArguments(global.addSpill(getName()), 0, ScriptObject.GLOBALFILTER), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SetMethod createNewPropertySetter() {
|
private SetMethod createNewPropertySetter() {
|
||||||
|
@ -34,6 +34,7 @@ import jdk.nashorn.internal.lookup.Lookup;
|
|||||||
import jdk.nashorn.internal.runtime.linker.Bootstrap;
|
import jdk.nashorn.internal.runtime.linker.Bootstrap;
|
||||||
|
|
||||||
import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
|
import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
|
||||||
|
import jdk.nashorn.internal.objects.Global;
|
||||||
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
|
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
|
||||||
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
|
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
|
||||||
|
|
||||||
@ -73,7 +74,7 @@ public final class UserAccessorProperty extends Property {
|
|||||||
|
|
||||||
private static MethodHandle getINVOKE_UA_GETTER() {
|
private static MethodHandle getINVOKE_UA_GETTER() {
|
||||||
|
|
||||||
return ((GlobalObject)Context.getGlobal()).getDynamicInvoker(INVOKE_UA_GETTER,
|
return Context.getGlobal().getDynamicInvoker(INVOKE_UA_GETTER,
|
||||||
new Callable<MethodHandle>() {
|
new Callable<MethodHandle>() {
|
||||||
@Override
|
@Override
|
||||||
public MethodHandle call() {
|
public MethodHandle call() {
|
||||||
@ -86,7 +87,7 @@ public final class UserAccessorProperty extends Property {
|
|||||||
/** Dynamic invoker for setter */
|
/** Dynamic invoker for setter */
|
||||||
private static Object INVOKE_UA_SETTER = new Object();
|
private static Object INVOKE_UA_SETTER = new Object();
|
||||||
private static MethodHandle getINVOKE_UA_SETTER() {
|
private static MethodHandle getINVOKE_UA_SETTER() {
|
||||||
return ((GlobalObject)Context.getGlobal()).getDynamicInvoker(INVOKE_UA_SETTER,
|
return Context.getGlobal().getDynamicInvoker(INVOKE_UA_SETTER,
|
||||||
new Callable<MethodHandle>() {
|
new Callable<MethodHandle>() {
|
||||||
@Override
|
@Override
|
||||||
public MethodHandle call() {
|
public MethodHandle call() {
|
||||||
|
@ -88,6 +88,11 @@ public final class WithObject extends ScriptObject implements Scope {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GuardedInvocation lookup(final CallSiteDescriptor desc, final LinkRequest request) {
|
public GuardedInvocation lookup(final CallSiteDescriptor desc, final LinkRequest request) {
|
||||||
|
if (request.isCallSiteUnstable()) {
|
||||||
|
// Fall back to megamorphic invocation which performs a complete lookup each time without further relinking.
|
||||||
|
return super.lookup(desc, request);
|
||||||
|
}
|
||||||
|
|
||||||
// With scopes can never be observed outside of Nashorn code, so all call sites that can address it will of
|
// With scopes can never be observed outside of Nashorn code, so all call sites that can address it will of
|
||||||
// necessity have a Nashorn descriptor - it is safe to cast.
|
// necessity have a Nashorn descriptor - it is safe to cast.
|
||||||
final NashornCallSiteDescriptor ndesc = (NashornCallSiteDescriptor)desc;
|
final NashornCallSiteDescriptor ndesc = (NashornCallSiteDescriptor)desc;
|
||||||
@ -265,7 +270,7 @@ public final class WithObject extends ScriptObject implements Scope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static MethodHandle filter(final MethodHandle mh, final MethodHandle filter) {
|
private static MethodHandle filter(final MethodHandle mh, final MethodHandle filter) {
|
||||||
return MH.filterArguments(mh, 0, filter);
|
return MH.filterArguments(mh, 0, filter.asType(filter.type().changeReturnType(mh.type().parameterType(0))));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,7 +27,7 @@ package jdk.nashorn.internal.runtime.arrays;
|
|||||||
|
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import jdk.nashorn.internal.runtime.GlobalObject;
|
import jdk.nashorn.internal.objects.Global;
|
||||||
import jdk.nashorn.internal.runtime.JSType;
|
import jdk.nashorn.internal.runtime.JSType;
|
||||||
import jdk.nashorn.internal.runtime.PropertyDescriptor;
|
import jdk.nashorn.internal.runtime.PropertyDescriptor;
|
||||||
|
|
||||||
@ -399,7 +399,7 @@ public abstract class ArrayData {
|
|||||||
*
|
*
|
||||||
* @return property descriptor for element
|
* @return property descriptor for element
|
||||||
*/
|
*/
|
||||||
public PropertyDescriptor getDescriptor(final GlobalObject global, final int index) {
|
public PropertyDescriptor getDescriptor(final Global global, final int index) {
|
||||||
return global.newDataDescriptor(getObject(index), true, true, true);
|
return global.newDataDescriptor(getObject(index), true, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ package jdk.nashorn.internal.runtime.arrays;
|
|||||||
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
|
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import jdk.nashorn.internal.runtime.GlobalObject;
|
import jdk.nashorn.internal.objects.Global;
|
||||||
import jdk.nashorn.internal.runtime.PropertyDescriptor;
|
import jdk.nashorn.internal.runtime.PropertyDescriptor;
|
||||||
import jdk.nashorn.internal.runtime.ScriptRuntime;
|
import jdk.nashorn.internal.runtime.ScriptRuntime;
|
||||||
|
|
||||||
@ -60,7 +60,8 @@ final class ByteBufferArrayData extends ArrayData {
|
|||||||
*
|
*
|
||||||
* @return property descriptor for element
|
* @return property descriptor for element
|
||||||
*/
|
*/
|
||||||
public PropertyDescriptor getDescriptor(final GlobalObject global, final int index) {
|
@Override
|
||||||
|
public PropertyDescriptor getDescriptor(final Global global, final int index) {
|
||||||
// make the index properties not configurable
|
// make the index properties not configurable
|
||||||
return global.newDataDescriptor(getObject(index), false, true, true);
|
return global.newDataDescriptor(getObject(index), false, true, true);
|
||||||
}
|
}
|
||||||
|
@ -25,9 +25,9 @@
|
|||||||
|
|
||||||
package jdk.nashorn.internal.runtime.arrays;
|
package jdk.nashorn.internal.runtime.arrays;
|
||||||
|
|
||||||
|
import jdk.nashorn.internal.objects.Global;
|
||||||
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
|
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
|
||||||
|
|
||||||
import jdk.nashorn.internal.runtime.GlobalObject;
|
|
||||||
import jdk.nashorn.internal.runtime.PropertyDescriptor;
|
import jdk.nashorn.internal.runtime.PropertyDescriptor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,7 +44,7 @@ final class FrozenArrayFilter extends SealedArrayFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PropertyDescriptor getDescriptor(final GlobalObject global, final int index) {
|
public PropertyDescriptor getDescriptor(final Global global, final int index) {
|
||||||
return global.newDataDescriptor(getObject(index), false, true, false);
|
return global.newDataDescriptor(getObject(index), false, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,9 +25,9 @@
|
|||||||
|
|
||||||
package jdk.nashorn.internal.runtime.arrays;
|
package jdk.nashorn.internal.runtime.arrays;
|
||||||
|
|
||||||
|
import jdk.nashorn.internal.objects.Global;
|
||||||
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
|
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
|
||||||
|
|
||||||
import jdk.nashorn.internal.runtime.GlobalObject;
|
|
||||||
import jdk.nashorn.internal.runtime.PropertyDescriptor;
|
import jdk.nashorn.internal.runtime.PropertyDescriptor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -62,7 +62,7 @@ class SealedArrayFilter extends ArrayFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PropertyDescriptor getDescriptor(final GlobalObject global, final int index) {
|
public PropertyDescriptor getDescriptor(final Global global, final int index) {
|
||||||
return global.newDataDescriptor(getObject(index), false, true, true);
|
return global.newDataDescriptor(getObject(index), false, true, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,7 @@ import jdk.internal.org.objectweb.asm.Label;
|
|||||||
import jdk.internal.org.objectweb.asm.Opcodes;
|
import jdk.internal.org.objectweb.asm.Opcodes;
|
||||||
import jdk.internal.org.objectweb.asm.Type;
|
import jdk.internal.org.objectweb.asm.Type;
|
||||||
import jdk.internal.org.objectweb.asm.commons.InstructionAdapter;
|
import jdk.internal.org.objectweb.asm.commons.InstructionAdapter;
|
||||||
|
import jdk.nashorn.internal.objects.Global;
|
||||||
import jdk.nashorn.internal.runtime.Context;
|
import jdk.nashorn.internal.runtime.Context;
|
||||||
import jdk.nashorn.internal.runtime.ScriptFunction;
|
import jdk.nashorn.internal.runtime.ScriptFunction;
|
||||||
import jdk.nashorn.internal.runtime.ScriptObject;
|
import jdk.nashorn.internal.runtime.ScriptObject;
|
||||||
@ -134,6 +135,7 @@ final class JavaAdapterBytecodeGenerator {
|
|||||||
static final Type CONTEXT_TYPE = Type.getType(Context.class);
|
static final Type CONTEXT_TYPE = Type.getType(Context.class);
|
||||||
static final Type OBJECT_TYPE = Type.getType(Object.class);
|
static final Type OBJECT_TYPE = Type.getType(Object.class);
|
||||||
static final Type SCRIPT_OBJECT_TYPE = Type.getType(ScriptObject.class);
|
static final Type SCRIPT_OBJECT_TYPE = Type.getType(ScriptObject.class);
|
||||||
|
static final Type GLOBAL_TYPE = Type.getType(Global.class);
|
||||||
|
|
||||||
static final String CONTEXT_TYPE_NAME = CONTEXT_TYPE.getInternalName();
|
static final String CONTEXT_TYPE_NAME = CONTEXT_TYPE.getInternalName();
|
||||||
static final String OBJECT_TYPE_NAME = OBJECT_TYPE.getInternalName();
|
static final String OBJECT_TYPE_NAME = OBJECT_TYPE.getInternalName();
|
||||||
@ -143,8 +145,10 @@ final class JavaAdapterBytecodeGenerator {
|
|||||||
static final String GLOBAL_FIELD_NAME = "global";
|
static final String GLOBAL_FIELD_NAME = "global";
|
||||||
|
|
||||||
static final String SCRIPT_OBJECT_TYPE_DESCRIPTOR = SCRIPT_OBJECT_TYPE.getDescriptor();
|
static final String SCRIPT_OBJECT_TYPE_DESCRIPTOR = SCRIPT_OBJECT_TYPE.getDescriptor();
|
||||||
|
static final String GLOBAL_TYPE_DESCRIPTOR = GLOBAL_TYPE.getDescriptor();
|
||||||
|
|
||||||
static final String SET_GLOBAL_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.VOID_TYPE, SCRIPT_OBJECT_TYPE);
|
|
||||||
|
static final String SET_GLOBAL_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.VOID_TYPE, GLOBAL_TYPE);
|
||||||
static final String VOID_NOARG_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.VOID_TYPE);
|
static final String VOID_NOARG_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.VOID_TYPE);
|
||||||
|
|
||||||
private static final Type SCRIPT_FUNCTION_TYPE = Type.getType(ScriptFunction.class);
|
private static final Type SCRIPT_FUNCTION_TYPE = Type.getType(ScriptFunction.class);
|
||||||
@ -167,7 +171,7 @@ final class JavaAdapterBytecodeGenerator {
|
|||||||
private static final String UNSUPPORTED_OPERATION_TYPE_NAME = UNSUPPORTED_OPERATION_TYPE.getInternalName();
|
private static final String UNSUPPORTED_OPERATION_TYPE_NAME = UNSUPPORTED_OPERATION_TYPE.getInternalName();
|
||||||
|
|
||||||
private static final String METHOD_HANDLE_TYPE_DESCRIPTOR = METHOD_HANDLE_TYPE.getDescriptor();
|
private static final String METHOD_HANDLE_TYPE_DESCRIPTOR = METHOD_HANDLE_TYPE.getDescriptor();
|
||||||
private static final String GET_GLOBAL_METHOD_DESCRIPTOR = Type.getMethodDescriptor(SCRIPT_OBJECT_TYPE);
|
private static final String GET_GLOBAL_METHOD_DESCRIPTOR = Type.getMethodDescriptor(GLOBAL_TYPE);
|
||||||
private static final String GET_CLASS_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.getType(Class.class));
|
private static final String GET_CLASS_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.getType(Class.class));
|
||||||
|
|
||||||
// Package used when the adapter can't be defined in the adaptee's package (either because it's sealed, or because
|
// Package used when the adapter can't be defined in the adaptee's package (either because it's sealed, or because
|
||||||
@ -259,7 +263,7 @@ final class JavaAdapterBytecodeGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void generateGlobalFields() {
|
private void generateGlobalFields() {
|
||||||
cw.visitField(ACC_PRIVATE | ACC_FINAL | (classOverride ? ACC_STATIC : 0), GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR, null, null).visitEnd();
|
cw.visitField(ACC_PRIVATE | ACC_FINAL | (classOverride ? ACC_STATIC : 0), GLOBAL_FIELD_NAME, GLOBAL_TYPE_DESCRIPTOR, null, null).visitEnd();
|
||||||
usedFieldNames.add(GLOBAL_FIELD_NAME);
|
usedFieldNames.add(GLOBAL_FIELD_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,7 +367,7 @@ final class JavaAdapterBytecodeGenerator {
|
|||||||
}
|
}
|
||||||
// Assign "global = Context.getGlobal()"
|
// Assign "global = Context.getGlobal()"
|
||||||
invokeGetGlobalWithNullCheck(mv);
|
invokeGetGlobalWithNullCheck(mv);
|
||||||
mv.putstatic(generatedClassName, GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
|
mv.putstatic(generatedClassName, GLOBAL_FIELD_NAME, GLOBAL_TYPE_DESCRIPTOR);
|
||||||
|
|
||||||
endInitMethod(mv);
|
endInitMethod(mv);
|
||||||
}
|
}
|
||||||
@ -508,7 +512,7 @@ final class JavaAdapterBytecodeGenerator {
|
|||||||
// Assign "this.global = Context.getGlobal()"
|
// Assign "this.global = Context.getGlobal()"
|
||||||
mv.visitVarInsn(ALOAD, 0);
|
mv.visitVarInsn(ALOAD, 0);
|
||||||
invokeGetGlobalWithNullCheck(mv);
|
invokeGetGlobalWithNullCheck(mv);
|
||||||
mv.putfield(generatedClassName, GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
|
mv.putfield(generatedClassName, GLOBAL_FIELD_NAME, GLOBAL_TYPE_DESCRIPTOR);
|
||||||
|
|
||||||
endInitMethod(mv);
|
endInitMethod(mv);
|
||||||
}
|
}
|
||||||
@ -652,10 +656,10 @@ final class JavaAdapterBytecodeGenerator {
|
|||||||
// Load the creatingGlobal object
|
// Load the creatingGlobal object
|
||||||
if(classOverride) {
|
if(classOverride) {
|
||||||
// If class handle is defined, load the static defining global
|
// If class handle is defined, load the static defining global
|
||||||
mv.getstatic(generatedClassName, GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
|
mv.getstatic(generatedClassName, GLOBAL_FIELD_NAME, GLOBAL_TYPE_DESCRIPTOR);
|
||||||
} else {
|
} else {
|
||||||
mv.visitVarInsn(ALOAD, 0);
|
mv.visitVarInsn(ALOAD, 0);
|
||||||
mv.getfield(generatedClassName, GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
|
mv.getfield(generatedClassName, GLOBAL_FIELD_NAME, GLOBAL_TYPE_DESCRIPTOR);
|
||||||
}
|
}
|
||||||
// stack: [creatingGlobal, handle]
|
// stack: [creatingGlobal, handle]
|
||||||
final Label setupGlobal = new Label();
|
final Label setupGlobal = new Label();
|
||||||
@ -674,7 +678,7 @@ final class JavaAdapterBytecodeGenerator {
|
|||||||
// stack: [creatingGlobal, creatingGlobal, handle]
|
// stack: [creatingGlobal, creatingGlobal, handle]
|
||||||
|
|
||||||
// Emit code for switching to the creating global
|
// Emit code for switching to the creating global
|
||||||
// ScriptObject currentGlobal = Context.getGlobal();
|
// Global currentGlobal = Context.getGlobal();
|
||||||
invokeGetGlobal(mv);
|
invokeGetGlobal(mv);
|
||||||
mv.dup();
|
mv.dup();
|
||||||
|
|
||||||
@ -744,7 +748,7 @@ final class JavaAdapterBytecodeGenerator {
|
|||||||
final Label methodEnd = new Label();
|
final Label methodEnd = new Label();
|
||||||
mv.visitLabel(methodEnd);
|
mv.visitLabel(methodEnd);
|
||||||
|
|
||||||
mv.visitLocalVariable("currentGlobal", SCRIPT_OBJECT_TYPE_DESCRIPTOR, null, setupGlobal, methodEnd, currentGlobalVar);
|
mv.visitLocalVariable("currentGlobal", GLOBAL_TYPE_DESCRIPTOR, null, setupGlobal, methodEnd, currentGlobalVar);
|
||||||
mv.visitLocalVariable("globalsDiffer", Type.INT_TYPE.getDescriptor(), null, setupGlobal, methodEnd, globalsDifferVar);
|
mv.visitLocalVariable("globalsDiffer", Type.INT_TYPE.getDescriptor(), null, setupGlobal, methodEnd, globalsDifferVar);
|
||||||
|
|
||||||
if(throwableDeclared) {
|
if(throwableDeclared) {
|
||||||
|
@ -48,7 +48,6 @@ import java.util.Map;
|
|||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import jdk.internal.dynalink.beans.StaticClass;
|
import jdk.internal.dynalink.beans.StaticClass;
|
||||||
import jdk.internal.dynalink.support.LinkRequestImpl;
|
import jdk.internal.dynalink.support.LinkRequestImpl;
|
||||||
import jdk.nashorn.internal.objects.NativeJava;
|
|
||||||
import jdk.nashorn.internal.runtime.Context;
|
import jdk.nashorn.internal.runtime.Context;
|
||||||
import jdk.nashorn.internal.runtime.ECMAException;
|
import jdk.nashorn.internal.runtime.ECMAException;
|
||||||
import jdk.nashorn.internal.runtime.ScriptFunction;
|
import jdk.nashorn.internal.runtime.ScriptFunction;
|
||||||
@ -68,8 +67,8 @@ import jdk.nashorn.internal.runtime.ScriptObject;
|
|||||||
* generate the adapter class itself; see its documentation for details about the generated class.
|
* generate the adapter class itself; see its documentation for details about the generated class.
|
||||||
* </p><p>
|
* </p><p>
|
||||||
* You normally don't use this class directly, but rather either create adapters from script using
|
* You normally don't use this class directly, but rather either create adapters from script using
|
||||||
* {@link NativeJava#extend(Object, Object...)}, using the {@code new} operator on abstract classes and interfaces (see
|
* {@link jdk.nashorn.internal.objects.NativeJava#extend(Object, Object...)}, using the {@code new} operator on abstract classes and interfaces (see
|
||||||
* {@link NativeJava#type(Object, Object)}), or implicitly when passing script functions to Java methods expecting SAM
|
* {@link jdk.nashorn.internal.objects.NativeJava#type(Object, Object)}), or implicitly when passing script functions to Java methods expecting SAM
|
||||||
* types.
|
* types.
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
@ -337,6 +336,7 @@ public final class JavaAdapterFactory {
|
|||||||
private static ProtectionDomain createMinimalPermissionDomain() {
|
private static ProtectionDomain createMinimalPermissionDomain() {
|
||||||
// Generated classes need to have at least the permission to access Nashorn runtime and runtime.linker packages.
|
// Generated classes need to have at least the permission to access Nashorn runtime and runtime.linker packages.
|
||||||
final Permissions permissions = new Permissions();
|
final Permissions permissions = new Permissions();
|
||||||
|
permissions.add(new RuntimePermission("accessClassInPackage.jdk.nashorn.internal.objects"));
|
||||||
permissions.add(new RuntimePermission("accessClassInPackage.jdk.nashorn.internal.runtime"));
|
permissions.add(new RuntimePermission("accessClassInPackage.jdk.nashorn.internal.runtime"));
|
||||||
permissions.add(new RuntimePermission("accessClassInPackage.jdk.nashorn.internal.runtime.linker"));
|
permissions.add(new RuntimePermission("accessClassInPackage.jdk.nashorn.internal.runtime.linker"));
|
||||||
return new ProtectionDomain(new CodeSource(null, (CodeSigner[])null), permissions);
|
return new ProtectionDomain(new CodeSource(null, (CodeSigner[])null), permissions);
|
||||||
|
@ -29,6 +29,11 @@ import static jdk.nashorn.internal.lookup.Lookup.MH;
|
|||||||
|
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import jdk.internal.dynalink.CallSiteDescriptor;
|
||||||
|
import jdk.nashorn.internal.codegen.ObjectClassGenerator;
|
||||||
|
import jdk.nashorn.internal.objects.Global;
|
||||||
|
import jdk.nashorn.internal.runtime.Property;
|
||||||
import jdk.nashorn.internal.runtime.PropertyMap;
|
import jdk.nashorn.internal.runtime.PropertyMap;
|
||||||
import jdk.nashorn.internal.runtime.ScriptFunction;
|
import jdk.nashorn.internal.runtime.ScriptFunction;
|
||||||
import jdk.nashorn.internal.runtime.ScriptObject;
|
import jdk.nashorn.internal.runtime.ScriptObject;
|
||||||
@ -40,6 +45,7 @@ public final class NashornGuards {
|
|||||||
private static final MethodHandle IS_SCRIPTOBJECT = findOwnMH("isScriptObject", boolean.class, Object.class);
|
private static final MethodHandle IS_SCRIPTOBJECT = findOwnMH("isScriptObject", boolean.class, Object.class);
|
||||||
private static final MethodHandle IS_SCRIPTFUNCTION = findOwnMH("isScriptFunction", boolean.class, Object.class);
|
private static final MethodHandle IS_SCRIPTFUNCTION = findOwnMH("isScriptFunction", boolean.class, Object.class);
|
||||||
private static final MethodHandle IS_MAP = findOwnMH("isMap", boolean.class, Object.class, PropertyMap.class);
|
private static final MethodHandle IS_MAP = findOwnMH("isMap", boolean.class, Object.class, PropertyMap.class);
|
||||||
|
private static final MethodHandle SAME_OBJECT = findOwnMH("sameObject", boolean.class, Object.class, WeakReference.class);
|
||||||
private static final MethodHandle IS_INSTANCEOF_2 = findOwnMH("isInstanceOf2", boolean.class, Object.class, Class.class, Class.class);
|
private static final MethodHandle IS_INSTANCEOF_2 = findOwnMH("isInstanceOf2", boolean.class, Object.class, Class.class, Class.class);
|
||||||
|
|
||||||
// don't create me!
|
// don't create me!
|
||||||
@ -74,6 +80,55 @@ public final class NashornGuards {
|
|||||||
return MH.insertArguments(IS_MAP, 1, map);
|
return MH.insertArguments(IS_MAP, 1, map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the given callsite needs a guard.
|
||||||
|
* @param property the property, or null
|
||||||
|
* @param desc the callsite descriptor
|
||||||
|
* @return true if a guard should be used for this callsite
|
||||||
|
*/
|
||||||
|
static boolean needsGuard(final Property property, final CallSiteDescriptor desc) {
|
||||||
|
return property == null || property.isConfigurable()
|
||||||
|
|| property.isBound() || !ObjectClassGenerator.OBJECT_FIELDS_ONLY
|
||||||
|
|| !NashornCallSiteDescriptor.isFastScope(desc) || property.canChangeType();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the guard for a property access. This returns an identity guard for non-configurable global properties
|
||||||
|
* and a map guard for everything else.
|
||||||
|
*
|
||||||
|
* @param sobj the first object in the prototype chain
|
||||||
|
* @param property the property
|
||||||
|
* @param desc the callsite descriptor
|
||||||
|
* @return method handle for guard
|
||||||
|
*/
|
||||||
|
public static MethodHandle getGuard(final ScriptObject sobj, final Property property, final CallSiteDescriptor desc) {
|
||||||
|
if (!needsGuard(property, desc)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (NashornCallSiteDescriptor.isScope(desc)) {
|
||||||
|
if (property != null && property.isBound()) {
|
||||||
|
// This is a declared top level variables in main script or eval, use identity guard.
|
||||||
|
return getIdentityGuard(sobj);
|
||||||
|
}
|
||||||
|
if (!(sobj instanceof Global) && (property == null || property.isConfigurable())) {
|
||||||
|
// Undeclared variables in nested evals need stronger guards
|
||||||
|
return combineGuards(getIdentityGuard(sobj), getMapGuard(sobj.getMap()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return getMapGuard(sobj.getMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a guard that checks referential identity of the current object.
|
||||||
|
*
|
||||||
|
* @param sobj the self object
|
||||||
|
* @return true if same self object instance
|
||||||
|
*/
|
||||||
|
public static MethodHandle getIdentityGuard(final ScriptObject sobj) {
|
||||||
|
return MH.insertArguments(SAME_OBJECT, 1, new WeakReference<>(sobj));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a guard that checks if in item is an instance of either of two classes.
|
* Get a guard that checks if in item is an instance of either of two classes.
|
||||||
*
|
*
|
||||||
@ -111,6 +166,11 @@ public final class NashornGuards {
|
|||||||
return self instanceof ScriptObject && ((ScriptObject)self).getMap() == map;
|
return self instanceof ScriptObject && ((ScriptObject)self).getMap() == map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private static boolean sameObject(final Object self, final WeakReference<ScriptObject> ref) {
|
||||||
|
return self == ref.get();
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private static boolean isInstanceOf2(final Object self, final Class<?> class1, final Class<?> class2) {
|
private static boolean isInstanceOf2(final Object self, final Class<?> class1, final Class<?> class2) {
|
||||||
return class1.isInstance(self) || class2.isInstance(self);
|
return class1.isInstance(self) || class2.isInstance(self);
|
||||||
|
@ -37,9 +37,9 @@ import jdk.internal.dynalink.linker.LinkRequest;
|
|||||||
import jdk.internal.dynalink.linker.LinkerServices;
|
import jdk.internal.dynalink.linker.LinkerServices;
|
||||||
import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
|
import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
|
||||||
import jdk.internal.dynalink.support.TypeUtilities;
|
import jdk.internal.dynalink.support.TypeUtilities;
|
||||||
|
import jdk.nashorn.internal.objects.Global;
|
||||||
import jdk.nashorn.internal.runtime.ConsString;
|
import jdk.nashorn.internal.runtime.ConsString;
|
||||||
import jdk.nashorn.internal.runtime.Context;
|
import jdk.nashorn.internal.runtime.Context;
|
||||||
import jdk.nashorn.internal.runtime.GlobalObject;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal linker for String, Boolean, and Number objects, only ever used by Nashorn engine and not exposed to other
|
* Internal linker for String, Boolean, and Number objects, only ever used by Nashorn engine and not exposed to other
|
||||||
@ -62,7 +62,7 @@ final class NashornPrimitiveLinker implements TypeBasedGuardingDynamicLinker, Gu
|
|||||||
final LinkRequest request = origRequest.withoutRuntimeContext(); // Nashorn has no runtime context
|
final LinkRequest request = origRequest.withoutRuntimeContext(); // Nashorn has no runtime context
|
||||||
|
|
||||||
final Object self = request.getReceiver();
|
final Object self = request.getReceiver();
|
||||||
final GlobalObject global = (GlobalObject) Context.getGlobal();
|
final Global global = Context.getGlobal();
|
||||||
final NashornCallSiteDescriptor desc = (NashornCallSiteDescriptor) request.getCallSiteDescriptor();
|
final NashornCallSiteDescriptor desc = (NashornCallSiteDescriptor) request.getCallSiteDescriptor();
|
||||||
|
|
||||||
return Bootstrap.asType(global.primitiveLookup(request, self), linkerServices, desc);
|
return Bootstrap.asType(global.primitiveLookup(request, self), linkerServices, desc);
|
||||||
|
@ -35,6 +35,7 @@ import jdk.internal.dynalink.linker.LinkRequest;
|
|||||||
import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
|
import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
|
||||||
import jdk.internal.dynalink.support.Guards;
|
import jdk.internal.dynalink.support.Guards;
|
||||||
import jdk.nashorn.internal.lookup.Lookup;
|
import jdk.nashorn.internal.lookup.Lookup;
|
||||||
|
import jdk.nashorn.internal.runtime.FindProperty;
|
||||||
import jdk.nashorn.internal.runtime.ScriptObject;
|
import jdk.nashorn.internal.runtime.ScriptObject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -61,8 +62,9 @@ public final class PrimitiveLookup {
|
|||||||
* type {@code receiverClass}.
|
* type {@code receiverClass}.
|
||||||
*/
|
*/
|
||||||
public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Class<?> receiverClass,
|
public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Class<?> receiverClass,
|
||||||
final ScriptObject wrappedReceiver, final MethodHandle wrapFilter) {
|
final ScriptObject wrappedReceiver, final MethodHandle wrapFilter,
|
||||||
return lookupPrimitive(request, Guards.getInstanceOfGuard(receiverClass), wrappedReceiver, wrapFilter);
|
final MethodHandle protoFilter) {
|
||||||
|
return lookupPrimitive(request, Guards.getInstanceOfGuard(receiverClass), wrappedReceiver, wrapFilter, protoFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -79,7 +81,8 @@ public final class PrimitiveLookup {
|
|||||||
* type (that is implied by both {@code guard} and {@code wrappedReceiver}).
|
* type (that is implied by both {@code guard} and {@code wrappedReceiver}).
|
||||||
*/
|
*/
|
||||||
public static GuardedInvocation lookupPrimitive(final LinkRequest request, final MethodHandle guard,
|
public static GuardedInvocation lookupPrimitive(final LinkRequest request, final MethodHandle guard,
|
||||||
final ScriptObject wrappedReceiver, final MethodHandle wrapFilter) {
|
final ScriptObject wrappedReceiver, final MethodHandle wrapFilter,
|
||||||
|
final MethodHandle protoFilter) {
|
||||||
final CallSiteDescriptor desc = request.getCallSiteDescriptor();
|
final CallSiteDescriptor desc = request.getCallSiteDescriptor();
|
||||||
final String operator = CallSiteDescriptorFactory.tokenizeOperators(desc).get(0);
|
final String operator = CallSiteDescriptorFactory.tokenizeOperators(desc).get(0);
|
||||||
if ("setProp".equals(operator) || "setElem".equals(operator)) {
|
if ("setProp".equals(operator) || "setElem".equals(operator)) {
|
||||||
@ -93,9 +96,23 @@ public final class PrimitiveLookup {
|
|||||||
|
|
||||||
if(desc.getNameTokenCount() > 2) {
|
if(desc.getNameTokenCount() > 2) {
|
||||||
final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
|
final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
|
||||||
if(wrappedReceiver.findProperty(name, true) == null) {
|
final FindProperty find = wrappedReceiver.findProperty(name, true);
|
||||||
|
if(find == null) {
|
||||||
// Give up early, give chance to BeanLinker and NashornBottomLinker to deal with it.
|
// Give up early, give chance to BeanLinker and NashornBottomLinker to deal with it.
|
||||||
return null;
|
return null;
|
||||||
|
} else if (find.isInherited() && !find.getProperty().hasGetterFunction(find.getOwner())) {
|
||||||
|
// If property is found in the prototype object bind the method handle directly to
|
||||||
|
// the proto filter instead of going through wrapper instantiation below.
|
||||||
|
final ScriptObject proto = wrappedReceiver.getProto();
|
||||||
|
final GuardedInvocation link = proto.lookup(desc, request);
|
||||||
|
|
||||||
|
if (link != null) {
|
||||||
|
final MethodHandle invocation = link.getInvocation();
|
||||||
|
final MethodHandle adaptedInvocation = MH.asType(invocation, invocation.type().changeParameterType(0, Object.class));
|
||||||
|
final MethodHandle method = MH.filterArguments(adaptedInvocation, 0, protoFilter);
|
||||||
|
final MethodHandle protoGuard = MH.filterArguments(link.getGuard(), 0, protoFilter);
|
||||||
|
return new GuardedInvocation(method, NashornGuards.combineGuards(guard, protoGuard));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final GuardedInvocation link = wrappedReceiver.lookup(desc, request);
|
final GuardedInvocation link = wrappedReceiver.lookup(desc, request);
|
||||||
|
@ -79,6 +79,7 @@ type.error.not.a.function={0} is not a function
|
|||||||
type.error.not.a.constructor={0} is not a constructor function
|
type.error.not.a.constructor={0} is not a constructor function
|
||||||
type.error.not.a.file={0} is not a File
|
type.error.not.a.file={0} is not a File
|
||||||
type.error.not.a.bytebuffer={0} is not a java.nio.ByteBuffer
|
type.error.not.a.bytebuffer={0} is not a java.nio.ByteBuffer
|
||||||
|
type.error.not.an.arraybuffer.in.dataview=First arg to DataView constructor must be an ArrayBuffer
|
||||||
|
|
||||||
# operations not permitted on undefined
|
# operations not permitted on undefined
|
||||||
type.error.cant.call.undefined=Cannot call undefined
|
type.error.cant.call.undefined=Cannot call undefined
|
||||||
@ -137,6 +138,9 @@ type.error.no.method.matches.args=Can not invoke method {0} with the passed argu
|
|||||||
type.error.method.not.constructor=Java method {0} can't be used as a constructor.
|
type.error.method.not.constructor=Java method {0} can't be used as a constructor.
|
||||||
type.error.env.not.object=$ENV must be an Object.
|
type.error.env.not.object=$ENV must be an Object.
|
||||||
type.error.unsupported.java.to.type=Unsupported Java.to target type {0}.
|
type.error.unsupported.java.to.type=Unsupported Java.to target type {0}.
|
||||||
|
|
||||||
|
range.error.dataview.constructor.offset=Wrong offset or length in DataView constructor
|
||||||
|
range.error.dataview.offset=Offset is outside the bounds of the DataView
|
||||||
range.error.inappropriate.array.length=inappropriate array length: {0}
|
range.error.inappropriate.array.length=inappropriate array length: {0}
|
||||||
range.error.inappropriate.array.buffer.length=inappropriate array buffer length: {0}
|
range.error.inappropriate.array.buffer.length=inappropriate array buffer length: {0}
|
||||||
range.error.invalid.fraction.digits=fractionDigits argument to {0} must be in [0, 20]
|
range.error.invalid.fraction.digits=fractionDigits argument to {0} must be in [0, 20]
|
||||||
|
@ -42,6 +42,7 @@ import jdk.nashorn.internal.codegen.Compiler;
|
|||||||
import jdk.nashorn.internal.ir.FunctionNode;
|
import jdk.nashorn.internal.ir.FunctionNode;
|
||||||
import jdk.nashorn.internal.ir.debug.ASTWriter;
|
import jdk.nashorn.internal.ir.debug.ASTWriter;
|
||||||
import jdk.nashorn.internal.ir.debug.PrintVisitor;
|
import jdk.nashorn.internal.ir.debug.PrintVisitor;
|
||||||
|
import jdk.nashorn.internal.objects.Global;
|
||||||
import jdk.nashorn.internal.parser.Parser;
|
import jdk.nashorn.internal.parser.Parser;
|
||||||
import jdk.nashorn.internal.runtime.Context;
|
import jdk.nashorn.internal.runtime.Context;
|
||||||
import jdk.nashorn.internal.runtime.ErrorManager;
|
import jdk.nashorn.internal.runtime.ErrorManager;
|
||||||
@ -148,7 +149,7 @@ public class Shell {
|
|||||||
return COMMANDLINE_ERROR;
|
return COMMANDLINE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
final ScriptObject global = context.createGlobal();
|
final Global global = context.createGlobal();
|
||||||
final ScriptEnvironment env = context.getEnv();
|
final ScriptEnvironment env = context.getEnv();
|
||||||
final List<String> files = env.getFiles();
|
final List<String> files = env.getFiles();
|
||||||
if (files.isEmpty()) {
|
if (files.isEmpty()) {
|
||||||
@ -231,8 +232,8 @@ public class Shell {
|
|||||||
* @return error code
|
* @return error code
|
||||||
* @throws IOException when any script file read results in I/O error
|
* @throws IOException when any script file read results in I/O error
|
||||||
*/
|
*/
|
||||||
private static int compileScripts(final Context context, final ScriptObject global, final List<String> files) throws IOException {
|
private static int compileScripts(final Context context, final Global global, final List<String> files) throws IOException {
|
||||||
final ScriptObject oldGlobal = Context.getGlobal();
|
final Global oldGlobal = Context.getGlobal();
|
||||||
final boolean globalChanged = (oldGlobal != global);
|
final boolean globalChanged = (oldGlobal != global);
|
||||||
final ScriptEnvironment env = context.getEnv();
|
final ScriptEnvironment env = context.getEnv();
|
||||||
try {
|
try {
|
||||||
@ -281,8 +282,8 @@ public class Shell {
|
|||||||
* @return error code
|
* @return error code
|
||||||
* @throws IOException when any script file read results in I/O error
|
* @throws IOException when any script file read results in I/O error
|
||||||
*/
|
*/
|
||||||
private int runScripts(final Context context, final ScriptObject global, final List<String> files) throws IOException {
|
private int runScripts(final Context context, final Global global, final List<String> files) throws IOException {
|
||||||
final ScriptObject oldGlobal = Context.getGlobal();
|
final Global oldGlobal = Context.getGlobal();
|
||||||
final boolean globalChanged = (oldGlobal != global);
|
final boolean globalChanged = (oldGlobal != global);
|
||||||
try {
|
try {
|
||||||
if (globalChanged) {
|
if (globalChanged) {
|
||||||
@ -339,8 +340,8 @@ public class Shell {
|
|||||||
* @return error code
|
* @return error code
|
||||||
* @throws IOException when any script file read results in I/O error
|
* @throws IOException when any script file read results in I/O error
|
||||||
*/
|
*/
|
||||||
private static int runFXScripts(final Context context, final ScriptObject global, final List<String> files) throws IOException {
|
private static int runFXScripts(final Context context, final Global global, final List<String> files) throws IOException {
|
||||||
final ScriptObject oldGlobal = Context.getGlobal();
|
final Global oldGlobal = Context.getGlobal();
|
||||||
final boolean globalChanged = (oldGlobal != global);
|
final boolean globalChanged = (oldGlobal != global);
|
||||||
try {
|
try {
|
||||||
if (globalChanged) {
|
if (globalChanged) {
|
||||||
@ -389,11 +390,11 @@ public class Shell {
|
|||||||
* @return return code
|
* @return return code
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("resource")
|
@SuppressWarnings("resource")
|
||||||
private static int readEvalPrint(final Context context, final ScriptObject global) {
|
private static int readEvalPrint(final Context context, final Global global) {
|
||||||
final String prompt = bundle.getString("shell.prompt");
|
final String prompt = bundle.getString("shell.prompt");
|
||||||
final BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
|
final BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
|
||||||
final PrintWriter err = context.getErr();
|
final PrintWriter err = context.getErr();
|
||||||
final ScriptObject oldGlobal = Context.getGlobal();
|
final Global oldGlobal = Context.getGlobal();
|
||||||
final boolean globalChanged = (oldGlobal != global);
|
final boolean globalChanged = (oldGlobal != global);
|
||||||
final ScriptEnvironment env = context.getEnv();
|
final ScriptEnvironment env = context.getEnv();
|
||||||
|
|
||||||
|
55
nashorn/test/script/basic/JDK-8034055.js
Normal file
55
nashorn/test/script/basic/JDK-8034055.js
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JDK-8034055: delete on global object not properly guarded
|
||||||
|
*
|
||||||
|
* @test
|
||||||
|
* @run
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
var global = this;
|
||||||
|
var x;
|
||||||
|
|
||||||
|
function test(defineGlobals) {
|
||||||
|
if (defineGlobals) {
|
||||||
|
global.x = 1;
|
||||||
|
global.y = 2;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
print(x);
|
||||||
|
print(y);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
} finally {
|
||||||
|
print(delete global.x);
|
||||||
|
print(delete global.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Repeatedly set and delete global variables
|
||||||
|
test(true);
|
||||||
|
test(false);
|
||||||
|
test(true);
|
||||||
|
test(false);
|
16
nashorn/test/script/basic/JDK-8034055.js.EXPECTED
Normal file
16
nashorn/test/script/basic/JDK-8034055.js.EXPECTED
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
1
|
||||||
|
2
|
||||||
|
false
|
||||||
|
true
|
||||||
|
1
|
||||||
|
ReferenceError: "y" is not defined
|
||||||
|
false
|
||||||
|
true
|
||||||
|
1
|
||||||
|
2
|
||||||
|
false
|
||||||
|
true
|
||||||
|
1
|
||||||
|
ReferenceError: "y" is not defined
|
||||||
|
false
|
||||||
|
true
|
70
nashorn/test/script/basic/dataview_endian.js
Normal file
70
nashorn/test/script/basic/dataview_endian.js
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JDK-8015958: DataView constructor is not defined
|
||||||
|
*
|
||||||
|
* @test
|
||||||
|
* @run
|
||||||
|
*/
|
||||||
|
|
||||||
|
// set/get endianess checks
|
||||||
|
|
||||||
|
var buffer = new ArrayBuffer(4);
|
||||||
|
var dv = new DataView(buffer);
|
||||||
|
|
||||||
|
// write (default) big endian, read big/little endian
|
||||||
|
dv.setUint16(0, 0xABCD);
|
||||||
|
Assert.assertEquals(dv.getUint16(0), 0xABCD);
|
||||||
|
Assert.assertEquals(dv.getUint16(0, false), 0xABCD);
|
||||||
|
Assert.assertEquals(dv.getUint16(0, true), 0xCDAB);
|
||||||
|
|
||||||
|
// write little endian, read big/little endian
|
||||||
|
dv.setUint16(0, 0xABCD, true);
|
||||||
|
Assert.assertEquals(dv.getUint16(0), 0xCDAB);
|
||||||
|
Assert.assertEquals(dv.getUint16(0, false), 0xCDAB);
|
||||||
|
Assert.assertEquals(dv.getUint16(0, true), 0xABCD);
|
||||||
|
|
||||||
|
// write explicit big endian, read big/little endian
|
||||||
|
dv.setUint16(0, 0xABCD, false);
|
||||||
|
Assert.assertEquals(dv.getUint16(0), 0xABCD);
|
||||||
|
Assert.assertEquals(dv.getUint16(0, false), 0xABCD);
|
||||||
|
Assert.assertEquals(dv.getUint16(0, true), 0xCDAB);
|
||||||
|
|
||||||
|
// write (default) big endian, read big/little endian
|
||||||
|
dv.setUint32(0, 0xABCDEF89);
|
||||||
|
Assert.assertEquals(dv.getUint32(0), 0xABCDEF89);
|
||||||
|
Assert.assertEquals(dv.getUint32(0, false), 0xABCDEF89);
|
||||||
|
Assert.assertEquals(dv.getUint32(0, true), 0x89EFCDAB);
|
||||||
|
|
||||||
|
// write little endian, read big/little endian
|
||||||
|
dv.setUint32(0, 0xABCDEF89, true);
|
||||||
|
Assert.assertEquals(dv.getUint32(0), 0x89EFCDAB);
|
||||||
|
Assert.assertEquals(dv.getUint32(0, false), 0x89EFCDAB);
|
||||||
|
Assert.assertEquals(dv.getUint32(0, true), 0xABCDEF89);
|
||||||
|
|
||||||
|
// write explicit big endian, read big/little endian
|
||||||
|
dv.setUint32(0, 0xABCDEF89, false);
|
||||||
|
Assert.assertEquals(dv.getUint32(0), 0xABCDEF89);
|
||||||
|
Assert.assertEquals(dv.getUint32(0, false), 0xABCDEF89);
|
||||||
|
Assert.assertEquals(dv.getUint32(0, true), 0x89EFCDAB);
|
93
nashorn/test/script/basic/dataview_getset.js
Normal file
93
nashorn/test/script/basic/dataview_getset.js
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JDK-8015958: DataView constructor is not defined
|
||||||
|
*
|
||||||
|
* @test
|
||||||
|
* @run
|
||||||
|
*/
|
||||||
|
|
||||||
|
// checking get/set of values of various types
|
||||||
|
// Also basic endianess check.
|
||||||
|
|
||||||
|
var Float = Java.type("java.lang.Float");
|
||||||
|
var Double = Java.type("java.lang.Double");
|
||||||
|
|
||||||
|
var DOUBLE_MIN = Double.MIN_VALUE;
|
||||||
|
var DOUBLE_MIN_NORMAL = Double.MIN_NORMAL;
|
||||||
|
var FLOAT_MIN = Float.MIN_VALUE;
|
||||||
|
var FLOAT_MIN_NORMAL = Float.MIN_NORMAL;
|
||||||
|
|
||||||
|
var buffer = new ArrayBuffer(12);
|
||||||
|
var dv = new DataView(buffer);
|
||||||
|
|
||||||
|
dv.setInt8(1, 123);
|
||||||
|
Assert.assertEquals(dv.getInt8(1), 123);
|
||||||
|
dv.setInt8(1, 123, true);
|
||||||
|
Assert.assertEquals(dv.getInt8(1, true), 123);
|
||||||
|
|
||||||
|
dv.setUint8(1, 255);
|
||||||
|
Assert.assertEquals(dv.getUint8(1), 255);
|
||||||
|
dv.setUint8(1, 255, true);
|
||||||
|
Assert.assertEquals(dv.getUint8(1, true), 255);
|
||||||
|
|
||||||
|
dv.setInt16(1, 1234);
|
||||||
|
Assert.assertEquals(dv.getInt16(1), 1234);
|
||||||
|
dv.setInt16(1, 1234, true);
|
||||||
|
Assert.assertEquals(dv.getInt16(1, true), 1234);
|
||||||
|
|
||||||
|
dv.setUint16(1, 65535);
|
||||||
|
Assert.assertEquals(dv.getUint16(1), 65535);
|
||||||
|
dv.setUint16(1, 65535, true);
|
||||||
|
Assert.assertEquals(dv.getUint16(1, true), 65535);
|
||||||
|
|
||||||
|
dv.setInt32(1, 1234);
|
||||||
|
Assert.assertEquals(dv.getInt32(1), 1234);
|
||||||
|
dv.setInt32(1, 1234, true);
|
||||||
|
Assert.assertEquals(dv.getInt32(1, true), 1234);
|
||||||
|
|
||||||
|
dv.setUint32(1, 4294967295);
|
||||||
|
Assert.assertEquals(dv.getUint32(1), 4294967295);
|
||||||
|
dv.setUint32(1, 4294967295, true);
|
||||||
|
Assert.assertEquals(dv.getUint32(1, true), 4294967295);
|
||||||
|
|
||||||
|
dv.setFloat64(1, Math.PI);
|
||||||
|
Assert.assertEquals(dv.getFloat64(1), Math.PI, DOUBLE_MIN);
|
||||||
|
dv.setFloat64(1, Math.PI, true);
|
||||||
|
Assert.assertEquals(dv.getFloat64(1, true), Math.PI, DOUBLE_MIN);
|
||||||
|
|
||||||
|
dv.setFloat64(1, DOUBLE_MIN_NORMAL);
|
||||||
|
Assert.assertEquals(dv.getFloat64(1), DOUBLE_MIN_NORMAL, DOUBLE_MIN);
|
||||||
|
dv.setFloat64(1, DOUBLE_MIN_NORMAL, true);
|
||||||
|
Assert.assertEquals(dv.getFloat64(1, true), DOUBLE_MIN_NORMAL, DOUBLE_MIN);
|
||||||
|
|
||||||
|
dv.setFloat32(1, 1.414);
|
||||||
|
Assert["assertEquals(float, float, float)"](dv.getFloat32(1), 1.414, FLOAT_MIN);
|
||||||
|
dv.setFloat32(1, 1.414, true);
|
||||||
|
Assert["assertEquals(float, float, float)"](dv.getFloat32(1, true), 1.414, FLOAT_MIN);
|
||||||
|
|
||||||
|
dv.setFloat32(1, FLOAT_MIN_NORMAL);
|
||||||
|
Assert["assertEquals(float, float, float)"](dv.getFloat32(1), FLOAT_MIN_NORMAL, FLOAT_MIN);
|
||||||
|
dv.setFloat32(1, FLOAT_MIN_NORMAL, true);
|
||||||
|
Assert["assertEquals(float, float, float)"](dv.getFloat32(1, true), FLOAT_MIN_NORMAL, FLOAT_MIN);
|
71
nashorn/test/script/basic/dataview_new.js
Normal file
71
nashorn/test/script/basic/dataview_new.js
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JDK-8015958: DataView constructor is not defined
|
||||||
|
*
|
||||||
|
* @test
|
||||||
|
* @run
|
||||||
|
*/
|
||||||
|
|
||||||
|
// basic DataView constructor checks.
|
||||||
|
|
||||||
|
// check ArrayBufferView property values of DataView instance
|
||||||
|
function check(dv, buf, offset, length) {
|
||||||
|
if (dv.buffer !== buf) {
|
||||||
|
fail("DataView.buffer is wrong");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dv.byteOffset != offset) {
|
||||||
|
fail("DataView.byteOffset = " + dv.byteOffset + ", expected " + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dv.byteLength != length) {
|
||||||
|
fail("DataView.byteLength = " + dv.byteLength + ", expected " + length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var buffer = new ArrayBuffer(12);
|
||||||
|
check(new DataView(buffer), buffer, 0, 12);
|
||||||
|
check(new DataView(buffer, 2), buffer, 2, 10);
|
||||||
|
check(new DataView(buffer, 4, 8), buffer, 4, 8);
|
||||||
|
|
||||||
|
// make sure expected error is thrown
|
||||||
|
function checkError(callback, ErrorType) {
|
||||||
|
try {
|
||||||
|
callback();
|
||||||
|
fail("Should have thrown " + ErrorType.name);
|
||||||
|
} catch (e) {
|
||||||
|
if (! (e instanceof ErrorType)) {
|
||||||
|
fail("Expected " + ErrorType.name + " got " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// non ArrayBuffer as first arg
|
||||||
|
checkError(function() { new DataView(344) }, TypeError);
|
||||||
|
|
||||||
|
// illegal offset/length values
|
||||||
|
checkError(function() { new DataView(buffer, -1) }, RangeError);
|
||||||
|
checkError(function() { new DataView(buffer, 15) }, RangeError);
|
||||||
|
checkError(function() { new DataView(buffer, 1, 32) }, RangeError);
|
@ -245,4 +245,320 @@ public class ScopeTest {
|
|||||||
sb.put("x", "newX");
|
sb.put("x", "newX");
|
||||||
assertTrue(e.eval("x", ctx).equals("newX"));
|
assertTrue(e.eval("x", ctx).equals("newX"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test multi-threaded access to defined global variables for shared script classes with multiple globals.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public static void multiThreadedVarTest() throws ScriptException, InterruptedException {
|
||||||
|
final ScriptEngineManager m = new ScriptEngineManager();
|
||||||
|
final ScriptEngine e = m.getEngineByName("nashorn");
|
||||||
|
final Bindings b = e.createBindings();
|
||||||
|
final ScriptContext origContext = e.getContext();
|
||||||
|
final ScriptContext newCtxt = new SimpleScriptContext();
|
||||||
|
newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
|
||||||
|
final String sharedScript = "foo";
|
||||||
|
|
||||||
|
assertEquals(e.eval("var foo = 'original context';", origContext), null);
|
||||||
|
assertEquals(e.eval("var foo = 'new context';", newCtxt), null);
|
||||||
|
|
||||||
|
final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
|
||||||
|
final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000));
|
||||||
|
t1.start();
|
||||||
|
t2.start();
|
||||||
|
t1.join();
|
||||||
|
t2.join();
|
||||||
|
|
||||||
|
assertEquals(e.eval("var foo = 'newer context';", newCtxt), null);
|
||||||
|
final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
|
||||||
|
final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000));
|
||||||
|
|
||||||
|
t3.start();
|
||||||
|
t4.start();
|
||||||
|
t3.join();
|
||||||
|
t4.join();
|
||||||
|
|
||||||
|
assertEquals(e.eval(sharedScript), "original context");
|
||||||
|
assertEquals(e.eval(sharedScript, newCtxt), "newer context");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test multi-threaded access to undefined global variables for shared script classes with multiple globals.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public static void multiThreadedGlobalTest() throws ScriptException, InterruptedException {
|
||||||
|
final ScriptEngineManager m = new ScriptEngineManager();
|
||||||
|
final ScriptEngine e = m.getEngineByName("nashorn");
|
||||||
|
final Bindings b = e.createBindings();
|
||||||
|
final ScriptContext origContext = e.getContext();
|
||||||
|
final ScriptContext newCtxt = new SimpleScriptContext();
|
||||||
|
newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
|
||||||
|
|
||||||
|
assertEquals(e.eval("foo = 'original context';", origContext), "original context");
|
||||||
|
assertEquals(e.eval("foo = 'new context';", newCtxt), "new context");
|
||||||
|
final String sharedScript = "foo";
|
||||||
|
|
||||||
|
final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
|
||||||
|
final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000));
|
||||||
|
t1.start();
|
||||||
|
t2.start();
|
||||||
|
t1.join();
|
||||||
|
t2.join();
|
||||||
|
|
||||||
|
Object obj3 = e.eval("delete foo; foo = 'newer context';", newCtxt);
|
||||||
|
assertEquals(obj3, "newer context");
|
||||||
|
final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
|
||||||
|
final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000));
|
||||||
|
|
||||||
|
t3.start();
|
||||||
|
t4.start();
|
||||||
|
t3.join();
|
||||||
|
t4.join();
|
||||||
|
|
||||||
|
Assert.assertEquals(e.eval(sharedScript), "original context");
|
||||||
|
Assert.assertEquals(e.eval(sharedScript, newCtxt), "newer context");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test multi-threaded access using the postfix ++ operator for shared script classes with multiple globals.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public static void multiThreadedIncTest() throws ScriptException, InterruptedException {
|
||||||
|
final ScriptEngineManager m = new ScriptEngineManager();
|
||||||
|
final ScriptEngine e = m.getEngineByName("nashorn");
|
||||||
|
final Bindings b = e.createBindings();
|
||||||
|
final ScriptContext origContext = e.getContext();
|
||||||
|
final ScriptContext newCtxt = new SimpleScriptContext();
|
||||||
|
newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
|
||||||
|
|
||||||
|
assertEquals(e.eval("var x = 0;", origContext), null);
|
||||||
|
assertEquals(e.eval("var x = 2;", newCtxt), null);
|
||||||
|
final String sharedScript = "x++;";
|
||||||
|
|
||||||
|
final Thread t1 = new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
for (int i = 0; i < 1000; i++) {
|
||||||
|
assertEquals(e.eval(sharedScript, origContext), (double)i);
|
||||||
|
}
|
||||||
|
} catch (ScriptException se) {
|
||||||
|
fail(se.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
final Thread t2 = new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
for (int i = 2; i < 1000; i++) {
|
||||||
|
assertEquals(e.eval(sharedScript, newCtxt), (double)i);
|
||||||
|
}
|
||||||
|
} catch (ScriptException se) {
|
||||||
|
fail(se.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
t1.start();
|
||||||
|
t2.start();
|
||||||
|
t1.join();
|
||||||
|
t2.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test multi-threaded access to primitive prototype properties for shared script classes with multiple globals.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public static void multiThreadedPrimitiveTest() throws ScriptException, InterruptedException {
|
||||||
|
final ScriptEngineManager m = new ScriptEngineManager();
|
||||||
|
final ScriptEngine e = m.getEngineByName("nashorn");
|
||||||
|
final Bindings b = e.createBindings();
|
||||||
|
final ScriptContext origContext = e.getContext();
|
||||||
|
final ScriptContext newCtxt = new SimpleScriptContext();
|
||||||
|
newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
|
||||||
|
|
||||||
|
Object obj1 = e.eval("String.prototype.foo = 'original context';", origContext);
|
||||||
|
Object obj2 = e.eval("String.prototype.foo = 'new context';", newCtxt);
|
||||||
|
assertEquals(obj1, "original context");
|
||||||
|
assertEquals(obj2, "new context");
|
||||||
|
final String sharedScript = "''.foo";
|
||||||
|
|
||||||
|
final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
|
||||||
|
final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000));
|
||||||
|
t1.start();
|
||||||
|
t2.start();
|
||||||
|
t1.join();
|
||||||
|
t2.join();
|
||||||
|
|
||||||
|
Object obj3 = e.eval("delete String.prototype.foo; Object.prototype.foo = 'newer context';", newCtxt);
|
||||||
|
assertEquals(obj3, "newer context");
|
||||||
|
final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
|
||||||
|
final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000));
|
||||||
|
|
||||||
|
t3.start();
|
||||||
|
t4.start();
|
||||||
|
t3.join();
|
||||||
|
t4.join();
|
||||||
|
|
||||||
|
Assert.assertEquals(e.eval(sharedScript), "original context");
|
||||||
|
Assert.assertEquals(e.eval(sharedScript, newCtxt), "newer context");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test multi-threaded scope function invocation for shared script classes with multiple globals.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public static void multiThreadedFunctionTest() throws ScriptException, InterruptedException {
|
||||||
|
final ScriptEngineManager m = new ScriptEngineManager();
|
||||||
|
final ScriptEngine e = m.getEngineByName("nashorn");
|
||||||
|
final Bindings b = e.createBindings();
|
||||||
|
final ScriptContext origContext = e.getContext();
|
||||||
|
final ScriptContext newCtxt = new SimpleScriptContext();
|
||||||
|
newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
|
||||||
|
|
||||||
|
e.eval(new URLReader(ScopeTest.class.getResource("resources/func.js")), origContext);
|
||||||
|
assertEquals(origContext.getAttribute("scopeVar"), 1);
|
||||||
|
assertEquals(e.eval("scopeTest()"), 1);
|
||||||
|
|
||||||
|
e.eval(new URLReader(ScopeTest.class.getResource("resources/func.js")), newCtxt);
|
||||||
|
assertEquals(newCtxt.getAttribute("scopeVar"), 1);
|
||||||
|
assertEquals(e.eval("scopeTest();", newCtxt), 1);
|
||||||
|
|
||||||
|
assertEquals(e.eval("scopeVar = 3;", newCtxt), 3);
|
||||||
|
assertEquals(newCtxt.getAttribute("scopeVar"), 3);
|
||||||
|
|
||||||
|
|
||||||
|
final Thread t1 = new Thread(new ScriptRunner(e, origContext, "scopeTest()", 1, 1000));
|
||||||
|
final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, "scopeTest()", 3, 1000));
|
||||||
|
|
||||||
|
t1.start();
|
||||||
|
t2.start();
|
||||||
|
t1.join();
|
||||||
|
t2.join();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test multi-threaded access to global getters and setters for shared script classes with multiple globals.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public static void getterSetterTest() throws ScriptException, InterruptedException {
|
||||||
|
final ScriptEngineManager m = new ScriptEngineManager();
|
||||||
|
final ScriptEngine e = m.getEngineByName("nashorn");
|
||||||
|
final Bindings b = e.createBindings();
|
||||||
|
final ScriptContext origContext = e.getContext();
|
||||||
|
final ScriptContext newCtxt = new SimpleScriptContext();
|
||||||
|
newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
|
||||||
|
final String sharedScript = "accessor1";
|
||||||
|
|
||||||
|
e.eval(new URLReader(ScopeTest.class.getResource("resources/gettersetter.js")), origContext);
|
||||||
|
assertEquals(e.eval("accessor1 = 1;"), 1);
|
||||||
|
assertEquals(e.eval(sharedScript), 1);
|
||||||
|
|
||||||
|
e.eval(new URLReader(ScopeTest.class.getResource("resources/gettersetter.js")), newCtxt);
|
||||||
|
assertEquals(e.eval("accessor1 = 2;", newCtxt), 2);
|
||||||
|
assertEquals(e.eval(sharedScript, newCtxt), 2);
|
||||||
|
|
||||||
|
|
||||||
|
final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, 1, 1000));
|
||||||
|
final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, 2, 1000));
|
||||||
|
|
||||||
|
t1.start();
|
||||||
|
t2.start();
|
||||||
|
t1.join();
|
||||||
|
t2.join();
|
||||||
|
|
||||||
|
assertEquals(e.eval(sharedScript), 1);
|
||||||
|
assertEquals(e.eval(sharedScript, newCtxt), 2);
|
||||||
|
assertEquals(e.eval("v"), 1);
|
||||||
|
assertEquals(e.eval("v", newCtxt), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test multi-threaded access to global getters and setters for shared script classes with multiple globals.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public static void getterSetter2Test() throws ScriptException, InterruptedException {
|
||||||
|
final ScriptEngineManager m = new ScriptEngineManager();
|
||||||
|
final ScriptEngine e = m.getEngineByName("nashorn");
|
||||||
|
final Bindings b = e.createBindings();
|
||||||
|
final ScriptContext origContext = e.getContext();
|
||||||
|
final ScriptContext newCtxt = new SimpleScriptContext();
|
||||||
|
newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
|
||||||
|
final String sharedScript = "accessor2";
|
||||||
|
|
||||||
|
e.eval(new URLReader(ScopeTest.class.getResource("resources/gettersetter.js")), origContext);
|
||||||
|
assertEquals(e.eval("accessor2 = 1;"), 1);
|
||||||
|
assertEquals(e.eval(sharedScript), 1);
|
||||||
|
|
||||||
|
e.eval(new URLReader(ScopeTest.class.getResource("resources/gettersetter.js")), newCtxt);
|
||||||
|
assertEquals(e.eval("accessor2 = 2;", newCtxt), 2);
|
||||||
|
assertEquals(e.eval(sharedScript, newCtxt), 2);
|
||||||
|
|
||||||
|
|
||||||
|
final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, 1, 1000));
|
||||||
|
final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, 2, 1000));
|
||||||
|
|
||||||
|
t1.start();
|
||||||
|
t2.start();
|
||||||
|
t1.join();
|
||||||
|
t2.join();
|
||||||
|
|
||||||
|
assertEquals(e.eval(sharedScript), 1);
|
||||||
|
assertEquals(e.eval(sharedScript, newCtxt), 2);
|
||||||
|
assertEquals(e.eval("x"), 1);
|
||||||
|
assertEquals(e.eval("x", newCtxt), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test "slow" scopes involving {@code with} and {@code eval} statements for shared script classes with multiple globals.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public static void testSlowScope() throws ScriptException, InterruptedException {
|
||||||
|
final ScriptEngineManager m = new ScriptEngineManager();
|
||||||
|
final ScriptEngine e = m.getEngineByName("nashorn");
|
||||||
|
|
||||||
|
for (int i = 0; i < 100; i++) {
|
||||||
|
final Bindings b = e.createBindings();
|
||||||
|
final ScriptContext ctxt = new SimpleScriptContext();
|
||||||
|
ctxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
|
||||||
|
|
||||||
|
e.eval(new URLReader(ScopeTest.class.getResource("resources/witheval.js")), ctxt);
|
||||||
|
assertEquals(e.eval("a", ctxt), 1);
|
||||||
|
assertEquals(b.get("a"), 1);
|
||||||
|
assertEquals(e.eval("b", ctxt), 3);
|
||||||
|
assertEquals(b.get("b"), 3);
|
||||||
|
assertEquals(e.eval("c", ctxt), 10);
|
||||||
|
assertEquals(b.get("c"), 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ScriptRunner implements Runnable {
|
||||||
|
|
||||||
|
final ScriptEngine engine;
|
||||||
|
final ScriptContext context;
|
||||||
|
final String source;
|
||||||
|
final Object expected;
|
||||||
|
final int iterations;
|
||||||
|
|
||||||
|
ScriptRunner(final ScriptEngine engine, final ScriptContext context, final String source, final Object expected, final int iterations) {
|
||||||
|
this.engine = engine;
|
||||||
|
this.context = context;
|
||||||
|
this.source = source;
|
||||||
|
this.expected = expected;
|
||||||
|
this.iterations = iterations;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
for (int i = 0; i < iterations; i++) {
|
||||||
|
assertEquals(engine.eval(source, context), expected);
|
||||||
|
}
|
||||||
|
} catch (ScriptException se) {
|
||||||
|
throw new RuntimeException(se);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
42
nashorn/test/src/jdk/nashorn/api/scripting/resources/func.js
Normal file
42
nashorn/test/src/jdk/nashorn/api/scripting/resources/func.js
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// This script is loaded from jdk.nashorn.api.scripting.ScopeTest to test script class sharing and reuse.
|
||||||
|
|
||||||
|
var scopeVar = 1;
|
||||||
|
var global = this;
|
||||||
|
undefGlobal = this;
|
||||||
|
|
||||||
|
function scopeTest() {
|
||||||
|
if (this !== global) {
|
||||||
|
throw new Error("this !== global");
|
||||||
|
}
|
||||||
|
if (this !== undefGlobal) {
|
||||||
|
throw new Error("this !== undefinedGlobal")
|
||||||
|
}
|
||||||
|
return scopeVar;
|
||||||
|
}
|
||||||
|
|
||||||
|
scopeTest();
|
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// This script is loaded from jdk.nashorn.api.scripting.ScopeTest to test script class sharing and reuse.
|
||||||
|
|
||||||
|
var v;
|
||||||
|
|
||||||
|
Object.defineProperty(this, "accessor1", {
|
||||||
|
get: function() { return v; },
|
||||||
|
set: function(n) { v = n; }
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.defineProperty(this, "accessor2", {
|
||||||
|
get: function() { return x; },
|
||||||
|
set: function(n) { x = n; }
|
||||||
|
});
|
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// This script is loaded from jdk.nashorn.api.scripting.ScopeTest to test script class sharing and reuse.
|
||||||
|
|
||||||
|
var a;
|
||||||
|
|
||||||
|
function outer(p, e) {
|
||||||
|
eval(e);
|
||||||
|
with(p) {
|
||||||
|
function inner() {
|
||||||
|
a = 1;
|
||||||
|
c = 10;
|
||||||
|
if (a !== 1) {
|
||||||
|
throw new Error("a !== 1");
|
||||||
|
}
|
||||||
|
if (b !== 3) {
|
||||||
|
throw new Error("b !== 3");
|
||||||
|
}
|
||||||
|
if (c !== 10) {
|
||||||
|
throw new Error("c !== 10");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inner();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
outer({}, "b = 3;");
|
||||||
|
|
||||||
|
if (a !== 1) {
|
||||||
|
throw new Error("a !== 1");
|
||||||
|
}
|
||||||
|
if (b !== 3) {
|
||||||
|
throw new Error("b !== 3");
|
||||||
|
}
|
||||||
|
if (c !== 10) {
|
||||||
|
throw new Error("c !== 10");
|
||||||
|
}
|
@ -28,6 +28,7 @@ package jdk.nashorn.internal.codegen;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
|
import jdk.nashorn.internal.objects.Global;
|
||||||
import jdk.nashorn.internal.runtime.Context;
|
import jdk.nashorn.internal.runtime.Context;
|
||||||
import jdk.nashorn.internal.runtime.ErrorManager;
|
import jdk.nashorn.internal.runtime.ErrorManager;
|
||||||
import jdk.nashorn.internal.runtime.ScriptFunction;
|
import jdk.nashorn.internal.runtime.ScriptFunction;
|
||||||
@ -58,7 +59,7 @@ public class CompilerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Context context;
|
private Context context;
|
||||||
private ScriptObject global;
|
private Global global;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public void setupTest() {
|
public void setupTest() {
|
||||||
@ -146,7 +147,7 @@ public class CompilerTest {
|
|||||||
log("Begin compiling " + file.getAbsolutePath());
|
log("Begin compiling " + file.getAbsolutePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
final ScriptObject oldGlobal = Context.getGlobal();
|
final Global oldGlobal = Context.getGlobal();
|
||||||
final boolean globalChanged = (oldGlobal != global);
|
final boolean globalChanged = (oldGlobal != global);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -31,9 +31,9 @@ import java.util.concurrent.ExecutionException;
|
|||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
import jdk.nashorn.internal.objects.Global;
|
||||||
import jdk.nashorn.internal.runtime.Context;
|
import jdk.nashorn.internal.runtime.Context;
|
||||||
import jdk.nashorn.internal.runtime.ScriptFunction;
|
import jdk.nashorn.internal.runtime.ScriptFunction;
|
||||||
import jdk.nashorn.internal.runtime.ScriptObject;
|
|
||||||
import jdk.nashorn.internal.runtime.ScriptRuntime;
|
import jdk.nashorn.internal.runtime.ScriptRuntime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -89,7 +89,7 @@ public class PerformanceWrapper extends jdk.nashorn.tools.Shell {
|
|||||||
@Override
|
@Override
|
||||||
protected Object apply(final ScriptFunction target, final Object self) {
|
protected Object apply(final ScriptFunction target, final Object self) {
|
||||||
if (_runsPerIteration == 0 && _numberOfIterations == 0) {
|
if (_runsPerIteration == 0 && _numberOfIterations == 0) {
|
||||||
final ScriptObject global = jdk.nashorn.internal.runtime.Context.getGlobal();
|
final Global global = jdk.nashorn.internal.runtime.Context.getGlobal();
|
||||||
final ScriptFunction _target = target;
|
final ScriptFunction _target = target;
|
||||||
final Object _self = self;
|
final Object _self = self;
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ import static org.testng.Assert.assertEquals;
|
|||||||
import static org.testng.Assert.assertTrue;
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import jdk.nashorn.internal.objects.Global;
|
||||||
import jdk.nashorn.internal.runtime.options.Options;
|
import jdk.nashorn.internal.runtime.options.Options;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
@ -45,7 +46,7 @@ public class ContextTest {
|
|||||||
final Options options = new Options("");
|
final Options options = new Options("");
|
||||||
final ErrorManager errors = new ErrorManager();
|
final ErrorManager errors = new ErrorManager();
|
||||||
final Context cx = new Context(options, errors, Thread.currentThread().getContextClassLoader());
|
final Context cx = new Context(options, errors, Thread.currentThread().getContextClassLoader());
|
||||||
final ScriptObject oldGlobal = Context.getGlobal();
|
final Global oldGlobal = Context.getGlobal();
|
||||||
Context.setGlobal(cx.createGlobal());
|
Context.setGlobal(cx.createGlobal());
|
||||||
try {
|
try {
|
||||||
String code = "22 + 10";
|
String code = "22 + 10";
|
||||||
@ -65,7 +66,7 @@ public class ContextTest {
|
|||||||
final ErrorManager errors = new ErrorManager();
|
final ErrorManager errors = new ErrorManager();
|
||||||
final Context cx = new Context(options, errors, Thread.currentThread().getContextClassLoader());
|
final Context cx = new Context(options, errors, Thread.currentThread().getContextClassLoader());
|
||||||
final boolean strict = cx.getEnv()._strict;
|
final boolean strict = cx.getEnv()._strict;
|
||||||
final ScriptObject oldGlobal = Context.getGlobal();
|
final Global oldGlobal = Context.getGlobal();
|
||||||
Context.setGlobal(cx.createGlobal());
|
Context.setGlobal(cx.createGlobal());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -0,0 +1,133 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
package jdk.nashorn.internal.runtime;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import static org.testng.Assert.fail;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import javax.script.ScriptContext;
|
||||||
|
import javax.script.ScriptEngine;
|
||||||
|
import javax.script.ScriptEngineFactory;
|
||||||
|
import javax.script.ScriptEngineManager;
|
||||||
|
import javax.script.SimpleScriptContext;
|
||||||
|
import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @bug 8037378
|
||||||
|
* @summary Sanity tests for no persistence caching
|
||||||
|
* @run testng/othervm jdk.nashorn.internal.runtime.NoPersistenceCachingTest
|
||||||
|
*/
|
||||||
|
public class NoPersistenceCachingTest {
|
||||||
|
|
||||||
|
private ScriptEngine engine;
|
||||||
|
private ScriptContext context1, context2, context3;
|
||||||
|
private ByteArrayOutputStream stderr;
|
||||||
|
private PrintStream prevStderr;
|
||||||
|
private final String script = "print('Hello')";
|
||||||
|
|
||||||
|
public void setupTest() {
|
||||||
|
stderr = new ByteArrayOutputStream();
|
||||||
|
prevStderr = System.err;
|
||||||
|
System.setErr(new PrintStream(stderr));
|
||||||
|
NashornScriptEngineFactory nashornFactory = null;
|
||||||
|
ScriptEngineManager sm = new ScriptEngineManager();
|
||||||
|
for (ScriptEngineFactory fac : sm.getEngineFactories()) {
|
||||||
|
if (fac instanceof NashornScriptEngineFactory) {
|
||||||
|
nashornFactory = (NashornScriptEngineFactory) fac;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nashornFactory == null) {
|
||||||
|
fail("Cannot find nashorn factory!");
|
||||||
|
}
|
||||||
|
String[] options = new String[]{"--log=compiler:finest"};
|
||||||
|
engine = nashornFactory.getScriptEngine(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setErrTest() {
|
||||||
|
System.setErr(prevStderr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void runTest(int numberOfContext, String expectedOutputPattern,
|
||||||
|
int expectedPatternOccurrence) {
|
||||||
|
setupTest();
|
||||||
|
try {
|
||||||
|
switch (numberOfContext) {
|
||||||
|
case 2:
|
||||||
|
context1 = engine.getContext();
|
||||||
|
context2 = new SimpleScriptContext();
|
||||||
|
context2.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE);
|
||||||
|
engine.eval(script, context1);
|
||||||
|
engine.eval(script, context2);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
context1 = engine.getContext();
|
||||||
|
context2 = new SimpleScriptContext();
|
||||||
|
context2.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE);
|
||||||
|
context3 = new SimpleScriptContext();
|
||||||
|
context3.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE);
|
||||||
|
engine.eval(script, context1);
|
||||||
|
engine.eval(script, context2);
|
||||||
|
engine.eval(script, context3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (final Exception se) {
|
||||||
|
se.printStackTrace();
|
||||||
|
fail(se.getMessage());
|
||||||
|
}
|
||||||
|
Pattern deoptimizing = Pattern.compile(expectedOutputPattern);
|
||||||
|
Matcher matcher = deoptimizing.matcher(stderr.toString());
|
||||||
|
int matches = 0;
|
||||||
|
while (matcher.find()) {
|
||||||
|
matches++;
|
||||||
|
}
|
||||||
|
if (matches != expectedPatternOccurrence) {
|
||||||
|
fail("Number of cache hit is not correct, expected: "
|
||||||
|
+ expectedPatternOccurrence + " and found: " + matches + "\n"
|
||||||
|
+ stderr);
|
||||||
|
}
|
||||||
|
setErrTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getCodeCachePattern() {
|
||||||
|
return ("\\[compiler\\]\\sCode\\scache\\shit\\sfor\\s<eval>\\savoiding\\srecompile.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void twoContextTest() {
|
||||||
|
runTest(2, getCodeCachePattern(), 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void threeContextTest() {
|
||||||
|
runTest(3, getCodeCachePattern(), 2);
|
||||||
|
}
|
||||||
|
}
|
@ -34,10 +34,10 @@ import java.io.IOException;
|
|||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import jdk.nashorn.api.scripting.NashornException;
|
import jdk.nashorn.api.scripting.NashornException;
|
||||||
|
import jdk.nashorn.internal.objects.Global;
|
||||||
import jdk.nashorn.internal.runtime.Context;
|
import jdk.nashorn.internal.runtime.Context;
|
||||||
import jdk.nashorn.internal.runtime.ErrorManager;
|
import jdk.nashorn.internal.runtime.ErrorManager;
|
||||||
import jdk.nashorn.internal.runtime.ScriptFunction;
|
import jdk.nashorn.internal.runtime.ScriptFunction;
|
||||||
import jdk.nashorn.internal.runtime.ScriptObject;
|
|
||||||
import jdk.nashorn.internal.runtime.ScriptRuntime;
|
import jdk.nashorn.internal.runtime.ScriptRuntime;
|
||||||
import jdk.nashorn.internal.runtime.Source;
|
import jdk.nashorn.internal.runtime.Source;
|
||||||
import jdk.nashorn.internal.runtime.options.Options;
|
import jdk.nashorn.internal.runtime.options.Options;
|
||||||
@ -110,12 +110,12 @@ public final class SharedContextEvaluator implements ScriptEvaluator {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int run(final OutputStream out, final OutputStream err, final String[] args) throws IOException {
|
public int run(final OutputStream out, final OutputStream err, final String[] args) throws IOException {
|
||||||
final ScriptObject oldGlobal = Context.getGlobal();
|
final Global oldGlobal = Context.getGlobal();
|
||||||
try {
|
try {
|
||||||
ctxOut.setDelegatee(out);
|
ctxOut.setDelegatee(out);
|
||||||
ctxErr.setDelegatee(err);
|
ctxErr.setDelegatee(err);
|
||||||
final ErrorManager errors = context.getErrorManager();
|
final ErrorManager errors = context.getErrorManager();
|
||||||
final ScriptObject global = context.createGlobal();
|
final Global global = context.createGlobal();
|
||||||
Context.setGlobal(global);
|
Context.setGlobal(global);
|
||||||
|
|
||||||
// For each file on the command line.
|
// For each file on the command line.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user