New helper class JIFunction for easy implementation of JS functions in Java without using reflection and its usage in ImporterTopLevel and NativeJavaPackage
While you are messing arround with JavaScriptException, is it possible to add
if(value instanceof Throwable) {
initCause((Throwable) value);
}
I know it's a Java 1.4 feature and not directly connected to this bug and don't
know what's the Rhino's policy of supported Java versions, but it in the end it
could be done with method.invoke() or something similar.
This would help debugging a lot.
Using (x instanceof Wrapper) instead of (x instanceof NativeJavaObject) which replaces the previous fix of unwrapping NativeJavaObject.call arguments for the custom wrappers problem.
1. Reorganization of BaseFunction.construct to always call createObject to avoid the need to re-implement construct in IdFunction and FunctionObject when much simpler code for subclassing createObject will do the job.
2. Throwing TypeError in IdFunction.createObject if it is not marked explicitly as constructor to satisfy EcmaScript standard:
first page of ECMAScript Edition 3, chapter 15: "None of the built-in
functions described in this section shall implement the internal
[[Construct]] method unless otherwise specified ...."
For more details, see http://bugzilla.mozilla.org/show_bug.cgi?id=202019
To fix the issue I moved away from generateCodeFromNode code to merge boolean
checks and conditional jumps into separated generateIfJump method that tries to
apply this optimization and if it is not possible, it calls
generateCodeFromNode and adds a generic jump.
The static type argument to toObject is effectively never used since it always assumes that instances of String, Number and Boolean represent primitive JS values and handled via ScriptRuntime.newObject and in the rest of cases static type was not checked by WrapFactory.
Such optimization wins very little with modern JVMs if cast succeeds and produces very big overhead if cast fails. Moreover, it may prevent jits from doing more aggressive optimizations and makes class files bigger.
The change also made code in many places smaller since insanceof check take ensure that object is not null as well and with ClassCastException such check had to be done explicitly.
1. Disable invoker optimization for methods with variable number of arguments since currently to call optimized invoker a new argument array has to be allocated in any case which makes the optimization irrelevant.
2. Never modify elements of the args array in constructor, instead avoid allocation of the new argument array iff all js argument can be passed to java without type conversion.
I added Context.getApplicationClassLoader() that is now used in all
cases as a parent loader for generated classes and as the default class loader
for NativeJavaPackage. The default implementation tries to use
Thread.getContextClassLoader, but only when it is available and if Rhino
classes is available through it. Otherwise the loader for Context instance is
used. In this way if Rhino is loaded through a custom loader, it will be used,
and if Rhino classes are placed in lib/ext, Thread.getContextClassLoader still
give the application loader.
And if this default policy would not work in a particular application,
Context.getApplicationClassLoader() can be overridden to in that application.
use IdFunction.initAsConstructor to initialize Error constructors in
NativeGlobal.init and remove setFunctionType and corresponding getFunctionType in IdFunction and use a simple private boolean field there to mark functions that can be called as constructors since NativeGlobal.init was the only place that used that.
Use toObject() in ScriptRuntime.delete to convert non-Scriptable delete target to Object which required to pass Context and scope to the method and update Interpreter and optimizer/Codegen accordingly.
if (val != null && val != Undefined.instance && val instanceof Scriptable) ...
by code to generate:
if (val instanceof Scriptable && val != Undefined.instance) ...
since (val instanceof Scriptable) => (val != null)