1 Context cx = Context.enter();
2 Scriptable instanceScope =
cx.newObject(sharedScope);
3 instanceScope.setPrototype(sharedScope);
4 instanceScope.setParentScope(null);
5 cx.evaluateString(instanceScope, "myscriptsource",
"instanceScript", 1, null);
In my code I did not use a separate thread for this standalone task.
It failed to find variable definition x defined in the instance scope
when calling function f which is defined in the shared scope.
Basically dynamic scope did not work.
function f () { var y = x.property; return y;} // x is only defined
in the local scope.
In debugging it I found that since there was only 1 thread thus
cx.topCallScope=the_original_script_scope and hence cx.topCallScope !=
null when the dynamic scope code was executed thus it did not call
ScriptRuntime.doToCall() and failed: "x" is not defined.
Here are my questions:
1). In InterpretedFunction.exec():
if (!ScriptRuntime.hasTopCall(cx)) {
// It will go through "call" path. but they are equivalent
return ScriptRuntime.doTopCall(
this, cx, scope, scope, ScriptRuntime.emptyArgs);
}
return Interpreter.interpret(
this, cx, scope, scope, ScriptRuntime.emptyArgs);
The comment says that "they are equivalent" but
ScriptRuntime.doTopCall() and Interpreter.interpret() yielded
different results in my tests. It looked like that only
ScriptRuntime.doTopCall() supports Dynamic Scope. Why can't we always
use doTopCall()?
2). In Rihno document it says
"You can create a scope using one Context and then evaluate a script
using that scope and another Context ..."
so I switched line 5 with the following:
(new Context()).evaluateString(threadScope, "myscriptsource",
"threadScript", 1, null);
The Dynamic Scope worked in my setup. This is at odd with the
statement "There should be one and only one Context associated with
each thread that will be executing JavaScript." Was it wrong with my
change?
3). When I launch a new thread for the Dynamic Code script it worked
without using the trick listed in 2). My question is that should I
always run the dynamic scope code in a separate thread if the Context
associated to the current thread could be "contaminated" by other
javascript processes?
Any help or clarification is appreciated.
Thanks,
Scott
It did not seem that I have to use the context from the running thread
in evaluating my script. The following worked in my tests:
(new Context()).evaluateString(threadScope, "myscriptsource",
"threadScript", 1, null);
This was based on the understanding that "You can create a scope using
one Context and then evaluate a script using that scope and another
Context ...".
Does this have any side effects?
Thanks,
Scott
I "think" that this 'new Context()' does not make any sense and
corrupts your test case. AFAIK you can't run code against arbitrary
Contexts, you must properly enter/exit them since some place will
refer to the related thread local variable.
That is:
Context cx = ContextFactory.enter(); // new in 1.7rc1, as
Context.enter() before
try {
cx.evaluateString(...)
}
finally { cx.exit(); }
> This was based on the understanding that "You can create a scope using
> one Context and then evaluate a script using that scope and another
> Context ...".
Yes, this seems to work fine for me. Just make sure that the 'other
Context' is always the one attached to the current Java thread.
Greets,
Helge
--
http://www.helgehess.eu/