mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-26 23:23:33 +00:00
Decoupling JavaAdapter from ClassRepository logic: JavaAdapter.createAdapterClass is replaced by JavaAdapter.createAdapterCode which just generates byte array with the adapter class file code and Codegen then passes this array to ClassRepository to save the class if necessary. In this way if repository do not need to load classes, adapter class will not be loaded at all.
This commit is contained in:
parent
26439e1139
commit
c914122b03
@ -129,9 +129,10 @@ public class JavaAdapter extends ScriptableObject {
|
||||
synchronized (generatedClasses) {
|
||||
adapterName = "adapter" + serial++;
|
||||
}
|
||||
adapterClass = createAdapterClass(cx, obj, adapterName,
|
||||
superClass, interfaces,
|
||||
null, null);
|
||||
byte[] code = createAdapterCode(cx, obj, adapterName,
|
||||
superClass, interfaces, null);
|
||||
|
||||
adapterClass = loadAdapterClass(cx, adapterName, code);
|
||||
generatedClasses.put(sig, adapterClass);
|
||||
}
|
||||
|
||||
@ -157,9 +158,9 @@ public class JavaAdapter extends ScriptableObject {
|
||||
}
|
||||
Context cx = Context.enter();
|
||||
try {
|
||||
adapterClass = createAdapterClass(cx, obj,
|
||||
adapterName, superClass,
|
||||
interfaces, null, null);
|
||||
byte[] code = createAdapterCode(cx, obj, adapterName,
|
||||
superClass, interfaces, null);
|
||||
adapterClass = loadAdapterClass(cx, adapterName, code);
|
||||
generatedClasses.put(sig, adapterClass);
|
||||
} finally {
|
||||
Context.exit();
|
||||
@ -180,12 +181,10 @@ public class JavaAdapter extends ScriptableObject {
|
||||
throw new ClassNotFoundException("adapter");
|
||||
}
|
||||
|
||||
public static Class createAdapterClass(Context cx, Scriptable jsObj,
|
||||
String adapterName, Class superClass,
|
||||
Class[] interfaces,
|
||||
String scriptClassName,
|
||||
ClassRepository repository)
|
||||
throws ClassNotFoundException
|
||||
public static byte[]
|
||||
createAdapterCode(Context cx, Scriptable jsObj, String adapterName,
|
||||
Class superClass, Class[] interfaces,
|
||||
String scriptClassName)
|
||||
{
|
||||
ClassFileWriter cfw = new ClassFileWriter(adapterName,
|
||||
superClass.getName(),
|
||||
@ -317,18 +316,12 @@ public class JavaAdapter extends ScriptableObject {
|
||||
generateMethod(cfw, adapterName, id, parms, Object.class);
|
||||
}
|
||||
}
|
||||
byte[] bytes = cfw.toByteArray();
|
||||
|
||||
if (repository != null) {
|
||||
try {
|
||||
if (!repository.storeClass(adapterName, bytes, true)) {
|
||||
return null;
|
||||
}
|
||||
} catch(IOException iox) {
|
||||
throw WrappedException.wrapException(iox);
|
||||
}
|
||||
}
|
||||
return cfw.toByteArray();
|
||||
}
|
||||
|
||||
private static Class
|
||||
loadAdapterClass(Context cx, String className, byte[] classBytes)
|
||||
{
|
||||
ClassLoader parentLoader = cx.getClass().getClassLoader();
|
||||
GeneratedClassLoader loader;
|
||||
SecurityController sc = cx.getSecurityController();
|
||||
@ -338,7 +331,7 @@ public class JavaAdapter extends ScriptableObject {
|
||||
Object securityDomain = sc.getDynamicSecurityDomain(null);
|
||||
loader = sc.createClassLoader(parentLoader, securityDomain);
|
||||
}
|
||||
Class result = loader.defineClass(adapterName, bytes);
|
||||
Class result = loader.defineClass(className, classBytes);
|
||||
loader.linkClass(result);
|
||||
return result;
|
||||
}
|
||||
|
@ -82,7 +82,65 @@ public class Codegen extends Interpreter {
|
||||
{
|
||||
ObjArray classFiles = new ObjArray();
|
||||
ObjArray names = new ObjArray();
|
||||
String generatedName = null;
|
||||
if (cx.getOptimizationLevel() > 0) {
|
||||
(new Optimizer()).optimize(tree, cx.getOptimizationLevel());
|
||||
}
|
||||
generateCode(tree, names, classFiles);
|
||||
String generatedName = name;
|
||||
|
||||
boolean onlySave = false;
|
||||
ClassRepository repository = nameHelper.getClassRepository();
|
||||
if (repository != null) {
|
||||
for (int i=0; i < names.size(); i++) {
|
||||
String className = (String) names.get(i);
|
||||
byte[] classFile = (byte[]) classFiles.get(i);
|
||||
boolean isTopLevel = className.equals(generatedName);
|
||||
try {
|
||||
if (!repository.storeClass(className, classFile,
|
||||
isTopLevel))
|
||||
{
|
||||
onlySave = true;
|
||||
}
|
||||
} catch (IOException iox) {
|
||||
throw WrappedException.wrapException(iox);
|
||||
}
|
||||
}
|
||||
|
||||
Class[] interfaces = nameHelper.getTargetImplements();
|
||||
Class superClass = nameHelper.getTargetExtends();
|
||||
if (interfaces != null || superClass != null) {
|
||||
String adapterClassName = getScriptClassName(null, true);
|
||||
ScriptableObject obj = new NativeObject();
|
||||
for (Node cursor = tree.getFirstChild(); cursor != null;
|
||||
cursor = cursor.getNext())
|
||||
{
|
||||
if (cursor.getType() == TokenStream.FUNCTION) {
|
||||
OptFunctionNode fnNode
|
||||
= (OptFunctionNode)cursor.
|
||||
getProp(Node.FUNCTION_PROP);
|
||||
obj.put(fnNode.getFunctionName(), obj, fnNode);
|
||||
}
|
||||
}
|
||||
if (superClass == null) {
|
||||
superClass = Object.class;
|
||||
}
|
||||
byte[] classFile = JavaAdapter.createAdapterCode(
|
||||
cx, obj, adapterClassName,
|
||||
superClass, interfaces,
|
||||
generatedName);
|
||||
try {
|
||||
if (!repository.storeClass(adapterClassName, classFile,
|
||||
true))
|
||||
{
|
||||
onlySave = true;
|
||||
}
|
||||
} catch (IOException iox) {
|
||||
throw WrappedException.wrapException(iox);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (onlySave) { return null; }
|
||||
|
||||
Exception e = null;
|
||||
Class result = null;
|
||||
@ -95,35 +153,21 @@ public class Codegen extends Interpreter {
|
||||
securityDomain);
|
||||
}
|
||||
|
||||
ClassRepository repository = nameHelper.getClassRepository();
|
||||
try {
|
||||
if (cx.getOptimizationLevel() > 0) {
|
||||
(new Optimizer()).optimize(tree, cx.getOptimizationLevel());
|
||||
}
|
||||
generatedName = generateCode(tree, names, classFiles);
|
||||
|
||||
for (int i=0; i < names.size(); i++) {
|
||||
String name = (String) names.get(i);
|
||||
String className = (String) names.get(i);
|
||||
byte[] classFile = (byte[]) classFiles.get(i);
|
||||
boolean isTopLevel = name.equals(generatedName);
|
||||
boolean isTopLevel = className.equals(generatedName);
|
||||
try {
|
||||
if (repository == null
|
||||
|| repository.storeClass(name, classFile, isTopLevel))
|
||||
{
|
||||
Class cl = loader.defineClass(name, classFile);
|
||||
if (isTopLevel) {
|
||||
result = cl;
|
||||
}
|
||||
Class cl = loader.defineClass(className, classFile);
|
||||
if (isTopLevel) {
|
||||
result = cl;
|
||||
}
|
||||
} catch (ClassFormatError ex) {
|
||||
throw new RuntimeException(ex.toString());
|
||||
} catch (IOException iox) {
|
||||
throw WrappedException.wrapException(iox);
|
||||
}
|
||||
}
|
||||
if (result != null) {
|
||||
loader.linkClass(result);
|
||||
}
|
||||
loader.linkClass(result);
|
||||
} catch (SecurityException x) {
|
||||
e = x;
|
||||
} catch (IllegalArgumentException x) {
|
||||
@ -132,35 +176,6 @@ public class Codegen extends Interpreter {
|
||||
if (e != null)
|
||||
throw new RuntimeException("Malformed optimizer package " + e);
|
||||
|
||||
Class[] interfaces = nameHelper.getTargetImplements();
|
||||
Class superClass = nameHelper.getTargetExtends();
|
||||
if (interfaces != null || superClass != null) {
|
||||
String name = getScriptClassName(null, true);
|
||||
ScriptableObject obj = new NativeObject();
|
||||
for (Node cursor = tree.getFirstChild(); cursor != null;
|
||||
cursor = cursor.getNext())
|
||||
{
|
||||
if (cursor.getType() == TokenStream.FUNCTION) {
|
||||
OptFunctionNode fnNode
|
||||
= (OptFunctionNode)cursor.getProp(Node.FUNCTION_PROP);
|
||||
obj.put(fnNode.getFunctionName(), obj, fnNode);
|
||||
}
|
||||
}
|
||||
if (superClass == null)
|
||||
superClass = Object.class;
|
||||
try {
|
||||
JavaAdapter.createAdapterClass(cx, obj, name,
|
||||
superClass,
|
||||
interfaces,
|
||||
generatedName,
|
||||
repository);
|
||||
} catch (ClassNotFoundException exn) {
|
||||
// should never happen
|
||||
throw new Error(exn.toString());
|
||||
}
|
||||
}
|
||||
if (result == null)
|
||||
return null;
|
||||
if (tree instanceof OptFunctionNode) {
|
||||
NativeFunction f;
|
||||
try {
|
||||
|
Loading…
x
Reference in New Issue
Block a user