8150219: ReferenceError in 1.8.0_72

Reviewed-by: attila, sundar
This commit is contained in:
Hannes Wallnöfer 2016-06-20 11:44:29 +02:00
parent 05e93094b7
commit acd4bf8777
3 changed files with 44 additions and 1 deletions

View File

@ -318,6 +318,9 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
// Create new global instance mirror and associate with the Bindings.
final ScriptObjectMirror mirror = createGlobalMirror();
bindings.put(NASHORN_GLOBAL, mirror);
// Since we created this global explicitly for the non-default script context we set the
// current script context in global permanently so that invokes work as expected. See JDK-8150219
mirror.getHomeGlobal().setInitScriptContext(ctxt);
return mirror.getHomeGlobal();
}

View File

@ -1087,6 +1087,8 @@ public final class Global extends Scope {
private ThreadLocal<ScriptContext> scontext;
// current ScriptEngine associated - can be null.
private ScriptEngine engine;
// initial ScriptContext - usually null and only used for special case
private volatile ScriptContext initscontext;
// ES6 global lexical scope.
private final LexicalScope lexicalScope;
@ -1112,9 +1114,22 @@ public final class Global extends Scope {
return scontext.get();
}
/**
* Set the initial script context
* @param ctxt initial script context
*/
public void setInitScriptContext(final ScriptContext ctxt) {
this.initscontext = ctxt;
}
private ScriptContext currentContext() {
final ScriptContext sc = scontext != null? scontext.get() : null;
return (sc != null)? sc : (engine != null? engine.getContext() : null);
if (sc != null) {
return sc;
} else if (initscontext != null) {
return initscontext;
}
return engine != null? engine.getContext() : null;
}
@Override

View File

@ -30,6 +30,8 @@ import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
import javax.script.Bindings;
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.Invocable;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
@ -911,4 +913,27 @@ public class ScopeTest {
Object value = ((Invocable)engine).invokeFunction("newfunc");
assertTrue(((Number)value).intValue() == 42);
}
// @bug 8150219 ReferenceError in 1.8.0_72
// When we create a Global for a non-default ScriptContext that needs one keep the
// ScriptContext associated with the Global so that invoke methods work as expected.
@Test
public void invokeFunctionWithCustomScriptContextTest() throws Exception {
final ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
// create an engine and a ScriptContext, but don't set it as default
ScriptContext scriptContext = new SimpleScriptContext();
// Set some value in the context
scriptContext.setAttribute("myString", "foo", ScriptContext.ENGINE_SCOPE);
// Evaluate script with custom context and get back a function
final String script = "function (c) { return myString.indexOf(c); }";
CompiledScript compiledScript = ((Compilable)engine).compile(script);
Object func = compiledScript.eval(scriptContext);
// Invoked function should be able to see context it was evaluated with
Object result = ((Invocable) engine).invokeMethod(func, "call", func, "o", null);
assertTrue(((Number)result).intValue() == 1);
}
}