import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.commons.ClassRemapper;
+import org.objectweb.asm.commons.Remapper;
import org.simantics.scl.compiler.constants.Constant;
import org.simantics.scl.compiler.elaboration.modules.SCLValue;
import org.simantics.scl.compiler.elaboration.rules.TransformationRule;
import org.simantics.scl.compiler.internal.codegen.utils.TransientClassBuilder;
import org.simantics.scl.compiler.internal.decompilation.DecompilerFactory;
import org.simantics.scl.compiler.internal.decompilation.IDecompiler;
+import org.simantics.scl.compiler.module.ConcreteModule;
import org.simantics.scl.compiler.module.Module;
import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
import org.simantics.scl.compiler.top.ValueNotFound;
private static final Logger LOGGER = LoggerFactory.getLogger(RuntimeModule.class);
public static final boolean VALIDATE_CLASS_NAMES = true;
- public static final boolean TRACE_CLASS_CREATION = false;
+ public static final boolean TRACE_CLASS_CREATION = true;
Module module;
ModuleClassLoader classLoader;
}
private Class<?> getClass(String name) throws ClassNotFoundException {
- //System.out.println("getClass " + name);
+
+ System.out.println(moduleName + ":getClass " + name);
// If the class is not generated from SCL, use parent class loader
if(!name.startsWith(SCL_PACKAGE_PREFIX)) {
}
}
+// protected Class<?> loadClass(String name, boolean resolve)
+// throws ClassNotFoundException
+// {
+// synchronized (getClassLoadingLock(name)) {
+// // First, check if the class has already been loaded
+// Class<?> c = findLoadedClass(name);
+// if (c == null) {
+// c = getClass(name);
+// }
+// if (resolve) {
+// resolveClass(c);
+// }
+// return c;
+// }
+// }
+
@Override
public synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
Class<?> clazz = getClass(name);
return clazz;
}
+ @Override
+ public Class<?> loadClass(String name) throws ClassNotFoundException {
+ return super.loadClass(name);
+ }
+
public Module getModule(String moduleName) {
//System.out.println("ModuleClassLoader.getModule(" + moduleName + ")");
if(moduleName.equals(this.moduleName))
classLoader = null;
classBuilder = null;
}
+
+ public class ClassNameRecordingRemapper extends Remapper {
+
+ private final Set<? super String> classNames;
+
+ public ClassNameRecordingRemapper(Set<? super String> classNames) {
+ this.classNames = classNames;
+ }
+
+ @Override
+ public String map(String typeName) {
+ classNames.add(typeName);
+ return super.map(typeName);
+ }
+
+ @Override
+ public String mapDesc(String desc) {
+ //classNames.add(desc);
+ return super.mapDesc(desc);
+ }
+ @Override
+ public String mapFieldName(String owner, String name, String desc) {
+ return super.mapFieldName(owner, name, desc);
+ }
+ @Override
+ public String mapInvokeDynamicMethodName(String name, String desc) {
+ // TODO Auto-generated method stub
+ return super.mapInvokeDynamicMethodName(name, desc);
+ }
+ @Override
+ public String mapMethodDesc(String desc) {
+ //classNames.add(desc);
+ return super.mapMethodDesc(desc);
+ }
+ @Override
+ public String mapMethodName(String owner, String name, String desc) {
+ // TODO Auto-generated method stub
+ return super.mapMethodName(owner, name, desc);
+ }
+ @Override
+ public String mapSignature(String signature, boolean typeSignature) {
+ //classNames.add(signature);
+ return super.mapSignature(signature, typeSignature);
+ }
+ @Override
+ public String mapType(String type) {
+ classNames.add(type);
+ return super.mapType(type);
+ }
+ @Override
+ public String[] mapTypes(String[] types) {
+ for(String type : types)
+ classNames.add(type);
+ // TODO Auto-generated method stub
+ return super.mapTypes(types);
+ }
+ @Override
+ public Object mapValue(Object value) {
+ //classNames.add(value.toString());
+ // TODO Auto-generated method stub
+ return super.mapValue(value);
+ }
+ }
+
+ public Set<String> classReferences(String className) {
+ try {
+ HashSet<String> referencedClasses = new HashSet<>();
+ ClassNameRecordingRemapper m = new ClassNameRecordingRemapper(referencedClasses);
+ ClassReader cr = new ClassReader(module.getClass(className));
+ int ASM5 = 5 << 16 | 0 << 8 | 0;
+ //TraceClassVisitor tcv = new TraceClassVisitor(null, new PrintWriter(System.err));
+ ClassVisitor cv1 = new ClassVisitor(ASM5) {};
+ ClassVisitor cv = new ClassRemapper(cv1, m);
+ cr.accept(cv, ClassReader.SKIP_DEBUG);
+ System.err.println(className + " refs: " + referencedClasses);
+ return referencedClasses;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public void loadReferences() {
+ ConcreteModule cm = (ConcreteModule)module;
+ try {
+ for(String className : cm.getClasses().keySet()) {
+ Set<String> refs = classReferences(className);
+ for(String s : refs) {
+ String internalName = s.replace('/', '.');
+ try {
+ classLoader.loadClass(internalName);
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+
}
\ No newline at end of file