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)
I removed deprecated since 1.5R3 omj.ClassOutput and moved some of code from omj/ClassNameHelper.java to omj/optimizer/OptClassNameHelper so if one does not need the optimizer package, the jar will be smaller.
Initialize invoker in FunctionObject constructor, not during first call and catch possible SecurityException. In this way initialization will happen without script code on java stack which may not have permissions to create class loaders.