These changes add the cache optimization to the has methods and remove cache update from the put methods under the assumption that newly assigned properties would not be used immediately.
hi Norris,
in our product, which makes heavy use of Rhino, we have many Java Objects
we wrap with ECMAScript wrappers, which extend the ScriptableObject class
and implement the Wrapper interface. Those wrappers automagically wrap the
native Java object with the help of a WrapHandler implementation.
we now ran into a problem :
we have a java class with two overloaded static methods like this :
public class Test {
public static String create(File f) {}
public static String create(Custom c) {}
}
The Custom class exists as a native Java implementation like
public class Custom {}
and a accompanying ECMAScript wrapper like
public class CustomWrapper
extends ScriptableObject
implements Wrapper {}
in our ECMAScripts we make the wrapper class known as a host object along
the lines of
defineClass("CustomWrapper");
and can then use the object as a normal ECMAScript host object. no big deal
and working great.
but : the code
var s = Test.creat( new Custom( "xyz") );
fails with the information, that the methods are ambiguous, which of course
they are not.
Looking at the code of NativeJavaMethod.findFunction() and the helpers in
NativeJavaObject it seems, that the fact of the Custom host object being a
Wrapper is not taken into account. in an easy fix of
NativeJavaMethod.findFunction(), i simply replace all arguments, which are
Wrapper imlpementation by the wrapped object. this solves my problem, but
of course i'm not sure on side effects.
i attach the testcase as well as the fixed NativeJavaMethod class in the
jar file. to run the test with and without the fix, extract the jar and do
ant test
please let me know, what you think of this.
regards and thanks, f.
Felix Meschberger
I think there's a small problem with Igor's changes. The modifed Interpreter.java
seems to create unnecessary activation objects for InterpretedScripts. You can
see this in the debugger (local variables are present even for top level scripts).
I believe the attached change will fix the problem.
Regards,
Chris
VariableModel.java:220:30:220:40: Caution: This try block cannot throw a "checked exception" (JLS section 14.7) that can be caught here. You may have intended to catch a RuntimeException instead of an Exception.
Changes to omj.tools.debugger are mostly due to renames and refactoring, the new code is limited to ContextData class which contains simplified version of the code for DebugFrame stack from the current DebuggableEngineImplementation and FrameHelper class implementing DebugFrame.
...
The idea is to make Debugger responsible for creation of DebugFrame in
Interpreter.interpret which gives simple way for a Debugger implementation to
observe function enter/exit while completely removing the need to have code
for debug frame stack in the Rhino core as the Debugger implementation can
easily support this on its own when necessary. So I suggest to have:
public interface Debugger { ... }
and
public interface DebugFrame { ... }
which eliminates omj.InterpreterFrame and as DebuggableEngine shrinks down to
3 methods set/getDebugger and getDebuggerContextData, I simply moved them to
Context. The 3rd method is useful to refer to per Context debug data from a
Debugger implementation, but it can be removed as well as the same effect can
be achieved via Context.set/getThreadLocal.
non-ScriptableObject implementations of Scriptable.
I checked in fixes for the problems of serializing objects with FunctionObjects or
GetterSlots. With Foo.class in the current directory, I can now do:
[rhino] java -classpath 'build/rhino1_5R4pre/js.jar;.' org.mozilla.javascript.tools.shell.Main
Rhino 1.5 release 4 0000 00 00 (in progress)
js> defineClass("Foo")
js> f = new Foo
[object Foo]
js> print(f.counter)
0
js> print(f.counter)
1
js> serialize(f, "f.ser")
js> quit()
[rhino] java -classpath 'build/rhino1_5R4pre/js.jar;.' org.mozilla.javascript.tools.shell.Main
Rhino 1.5 release 4 0000 00 00 (in progress)
js> f = deserialize("f.ser")
[object Foo]
js> f.counter
2
js> f.counter
3
Hi Norris,
I encountered the following exception with the below script in compiled
mode with RhinoLatest.zip:
java.lang.NullPointerException
at
org.mozilla.javascript.optimizer.Codegen.visitCall(Codegen.java:1790)
at
org.mozilla.javascript.optimizer.Codegen.generateCodeFromNode(Codegen.java:567)
at
org.mozilla.javascript.optimizer.Codegen.visitReturn(Codegen.java:2283)
at
org.mozilla.javascript.optimizer.Codegen.generateCodeFromNode(Codegen.java:592)
at
org.mozilla.javascript.optimizer.Codegen.generateCodeFromNode(Codegen.java:546)
at
org.mozilla.javascript.optimizer.Codegen.generateCodeFromNode(Codegen.java:546)
at
org.mozilla.javascript.optimizer.Codegen.generateCodeFromNode(Codegen.java:546)
at
org.mozilla.javascript.optimizer.Codegen.generateCode(Codegen.java:497)
at
org.mozilla.javascript.optimizer.Codegen.generateFunctionInits(Codegen.java:1292)
at
org.mozilla.javascript.optimizer.Codegen.generateInit(Codegen.java:1186)
at
org.mozilla.javascript.optimizer.Codegen.generateCode(Codegen.java:481)
at org.mozilla.javascript.optimizer.Codegen.compile(Codegen.java:88)
at org.mozilla.javascript.Context.compile(Context.java:1965)
at org.mozilla.javascript.Context.compile(Context.java:1874)
at org.mozilla.javascript.Context.compileReader(Context.java:895)
at org.mozilla.javascript.Context.evaluateReader(Context.java:813)
at
org.mozilla.javascript.tools.shell.Main.evaluateReader(Main.java:318)
at org.mozilla.javascript.tools.shell.Main.processFile(Main.java:309)
at org.mozilla.javascript.tools.shell.Main.processSource(Main.java:248)
at org.mozilla.javascript.tools.shell.Main.exec(Main.java:95)
at org.mozilla.javascript.tools.shell.Main.main(Main.java:68)
Exception in thread "main"
function tak(x, y, z, k) {
if (!(y < x)) {
return k(z);
} else {
return tak(x - 1,
y,
z,
function(v1) {
return tak(y - 1,
z,
x,
function(v2) {
return tak(z - 1,
x,
y,
function(v3) {
return tak(v1, v2, v3, k);
});
});
});
}
}
function cpstak(x, y, z) {
return tak(x, y, z, function(a) {return a;});
}
//;;; call: (cpstak 18 12 6)
//(run-benchmark "CPSTAK" (lambda () (cpstak 18 12 6)))
var start = new Date();
var res = cpstak(18, 12, 6);
var end = new Date();
print(res +": elapsed: " + (end - start));
Hi Norris,
Would you mind checking in the attached changes to the debugger. The
attached files include the following changes:
1) Use ScriptableObject.getAllIds to obtain an object's properties (if
the object extends ScriptableObject). This makes non-enumerable
properties visible in the debugger for ScriptableObject's.
2) Made the coding style more consistent with the rest of Rhino.
3) Better support for displaying and stepping through eval-ed code.
As Igor suggested to me once, it might be a good idea to define a new
interface to similarly support debugging host objects that don't extend
ScriptableObject, something like the following:
public interface Debuggable extends Scriptable {
public Object[] getAllIds();
}
The debugger could check for this interface and if a host object chose
to implement it, the debugger would be able to display its
non-enumerable properties.
Chris