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:
igor%mir2.org 2003-02-15 17:47:13 +00:00
parent 26439e1139
commit c914122b03
2 changed files with 82 additions and 74 deletions

View File

@ -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;
}

View File

@ -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 {