Fix bug found by Andrew Wason (see below).

Problem was that one transformation of a node to GETVAR wasn't protected by a check of inWithStatement().

======================================
Subject:
        multiple scopes
   Date:
        Fri, 01 Oct 1999 12:39:14 -0400
   From:
        Andrew Wason <aw@softcom.com>
     To:
        norris@netscape.com
    CC:
        Howard Lin <howard@softcom.com>




When I create two scopes, and one scope evaulates a string in the other
scope, it works.  However, if I do this while handling an exception thrown
within a JavaAdapter method, it fails with an exception.

Run the attached Java program with the two script files.  scope1.js
evaluates a string "printMessage" in the scope of scope2.js.  This returns
a function object which is then invoked.  This works in 3 cases, but fails
in the 4th (in the catch in the JavaAdapter).  Even in the 4th case where
it fails, printing the function object looks normal.

Am I doing something wrong, or is there a bug here?

java CrossScope scope1.js scope2.js

Outside of JavaAdapter
works before exception
works after exception
Inside of JavaAdapter
works before exception
Caught exception
pma=
function printMessage(msg) {
     java.lang.System.out.println(msg);
}

Exception in thread "main" org.mozilla.javascript.JavaScriptException:
org.mozilla.javascript.EvaluatorException: The undefined value has no
properties.
         at
org.mozilla.javascript.JavaScriptException.wrapException(JavaScriptException
.java:61)
         at
org.mozilla.javascript.NativeJavaMethod.call(NativeJavaMethod.java,
Compiled Code)
         at org.mozilla.javascript.ScriptRuntime.call(ScriptRuntime.java:1256)
         at org.mozilla.javascript.Interpreter.interpret(Interpreter.java,
Compiled Code)
         at
org.mozilla.javascript.InterpretedScript.call(InterpretedScript.java:49)
         at
org.mozilla.javascript.InterpretedScript.exec(InterpretedScript.java:37)
         at org.mozilla.javascript.Context.evaluateReader(Context.java:697)
         at CrossScope.<init>(CrossScope.java:30)
         at CrossScope.main(CrossScope.java:10)


Thanks,
Andrew

import java.io.*;
import org.mozilla.javascript.*;

public class CrossScope {
	private Context m_jsContext;
	private Scriptable m_scope1;
	private Scriptable m_scope2;

	public static void main(String args[]) throws Exception {
		new CrossScope(args[0], args[1]);
	}

	private CrossScope(String strFile1, String strFile2) throws Exception {
		// Associate Context with main thread
		m_jsContext = Context.enter();
                m_jsContext.setOptimizationLevel(-1);

		// Init scope1, expose Scope object
  		m_scope1 = m_jsContext.initStandardObjects(new ImporterTopLevel());
		m_scope1.put("Scope", m_scope1, this);

		// Init scope2
		m_scope2 = m_jsContext.initStandardObjects(new ImporterTopLevel());

		// Run script in scope2
		Reader r2 = new FileReader(strFile2);
		m_jsContext.evaluateReader(m_scope2, r2, strFile2, 1, null);

		// Eval input JS in scope1 - it can in turn eval JS over in scope2
		Reader r1 = new FileReader(strFile1);
		Object obj = m_jsContext.evaluateReader(m_scope1, r1, strFile1, 1, null);
		if (obj instanceof Throwable)
			((Throwable)obj).printStackTrace();

		m_jsContext.exit();
	}

	public Object scope1Eval(String str) throws JavaScriptException {
			Context cx = Context.enter(m_jsContext);
			Object objResult = cx.evaluateString(m_scope1, str, "scope1EvalString", 1, null);
			cx.exit();
			return objResult;
	}

	public Object scope2Eval(String str) throws JavaScriptException {
			Context cx = Context.enter(m_jsContext);
			Object objResult = cx.evaluateString(m_scope2, str, "scope2EvalString", 1, null);
			cx.exit();
			return objResult;
	}
}


// Scope1

importPackage(java.lang);

System.out.println("Outside of JavaAdapter");

try {
	var pm = Scope.scope2Eval("printMessage");
	pm("works before exception");
	System.arraycopy(null, 5, null, 5, 100);
} catch (e) {
	var pma = Scope.scope2Eval("printMessage");
	pma("works after exception");
}

var obj = new Runnable() {
	run: function() {
		System.out.println("Inside of JavaAdapter");
		try {
			var pm = Scope.scope2Eval("printMessage");
			pm("works before exception");
			System.arraycopy(null, 5, null, 5, 100);
		} catch (e) {
			System.out.println("Caught exception");
			var pma = Scope.scope2Eval("printMessage");
			System.out.println("pma=" + pma);
			pma("works after exception");
		}
	}
};

obj.run();



// Scope2

function printMessage(msg) {
	java.lang.System.out.println(msg);
}
This commit is contained in:
norris%netscape.com 1999-10-04 18:27:30 +00:00
parent 14751442af
commit b1ecbb62ba
2 changed files with 4 additions and 4 deletions

View File

@ -463,7 +463,7 @@ public class NodeTransformer {
break;
String name = node.getString();
if (name.equals("arguments")) {
// Use of "arguments" requires a an activation object.
// Use of "arguments" requires an activation object.
((FunctionNode) tree).setRequiresActivation(true);
}
VariableTable vars = getVariableTable(tree);
@ -541,7 +541,7 @@ public class NodeTransformer {
if (left.getType() == TokenStream.NAME) {
VariableTable vars = getVariableTable(tree);
String name = left.getString();
if (inFunction && vars.get(name) != null) {
if (inFunction && vars.get(name) != null && !inWithStatement()) {
// call to a var. Transform to Call(GetVar("a"), b, c)
left.setType(TokenStream.GETVAR);
// fall through to code to add GetParent

View File

@ -463,7 +463,7 @@ public class NodeTransformer {
break;
String name = node.getString();
if (name.equals("arguments")) {
// Use of "arguments" requires a an activation object.
// Use of "arguments" requires an activation object.
((FunctionNode) tree).setRequiresActivation(true);
}
VariableTable vars = getVariableTable(tree);
@ -541,7 +541,7 @@ public class NodeTransformer {
if (left.getType() == TokenStream.NAME) {
VariableTable vars = getVariableTable(tree);
String name = left.getString();
if (inFunction && vars.get(name) != null) {
if (inFunction && vars.get(name) != null && !inWithStatement()) {
// call to a var. Transform to Call(GetVar("a"), b, c)
left.setType(TokenStream.GETVAR);
// fall through to code to add GetParent