import org.junit.Test;
import org.mozilla.javascript.ContextFactory;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
public class ObjectSurprise {
@Test
public void showBug(){
ContextFactory factory = new ContextFactory();
Context cx1 = factory.enterContext();
Context cx2 = factory.enterContext();
final Scriptable scope1 = cx1.initStandardObjects();
cx1.evaluateString(scope1,
"tryMe = function(){return {};}",
"tryMe", 1, null);
Scriptable result = (Scriptable)
ScriptableObject.callMethod(scope1, "tryMe", new Object[]
{});
String throwIfNotObject =
"isObject = function(obj){ if( !(obj instanceof
Object)) throw('not an object');}";
cx1.evaluateString(scope1, throwIfNotObject, "isObject", 1,
null);
Object [] arg = { result };
//doesn't throw, as expected
ScriptableObject.callMethod(scope1, "isObject", arg);
Context.exit();
final Scriptable scope2 = cx2.initStandardObjects();
cx2.evaluateString(scope2, throwIfNotObject, "isObject", 1,
null);
//throws -- unexpected
ScriptableObject.callMethod(scope2, "isObject", arg);
Context.exit();
}
}
You're right: instanceof just walks up the prototype chain looking for
the object. Mixing objects from two separate initStandardObject calls
is problematic in general; why do you need to do this?
--N
A
we didn't hurt this problem until now, but in the case of HtmlUnit,
mixing objects of two separate initStandardObject calls is natural as
each Window is a top scope and windows have access to child and parent
windows.
Cheers,
Marc.
--
Web: http://www.efficient-webtesting.com
Blog: http://mguillem.wordpress.com
I just saw a post about this bug: https://bugzilla.mozilla.org/show_bug.cgi?id=374918
Seems like it's related, huh?
A
no, this is totally different.
As primitive aren't Scriptable, they don't hold information about their
scope. Rhino takes the Context's top scope what is incorrect and causes
errors when many scopes are involved.