package org.simantics.scl.compiler.runtime;
+import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.List;
import java.util.Map;
import org.simantics.scl.compiler.constants.Constant;
import org.simantics.scl.compiler.environment.GlobalOnlyEnvironment;
import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator;
import org.simantics.scl.compiler.internal.codegen.utils.JavaNamingPolicy;
+import org.simantics.scl.compiler.internal.codegen.utils.LoggingOutputStream;
+import org.simantics.scl.compiler.internal.codegen.utils.LoggingOutputStream.LogLevel;
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.Module;
+import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
import org.simantics.scl.compiler.top.ValueNotFound;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import gnu.trove.map.hash.THashMap;
public class RuntimeModule {
+ 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 synchronized void addClass(String name, byte[] class_) {
if(TRACE_CLASS_CREATION)
- System.out.println("addClass " + name + " (" + class_.length + " bytes)");
+ LOGGER.info("addClass " + name + " (" + class_.length + " bytes)");
if(VALIDATE_CLASS_NAMES)
validateClassName(name);
localClasses.put(name, class_);
public synchronized void addClasses(Map<String, byte[]> classes) {
if(TRACE_CLASS_CREATION)
for(String name : classes.keySet())
- System.out.println("addClass " + name + " (" + classes.get(name).length + " bytes)");
+ LOGGER.info("addClass " + name + " (" + classes.get(name).length + " bytes)");
if(VALIDATE_CLASS_NAMES)
for(String name : classes.keySet())
validateClassName(name);
}
private void validateClassName(String name) {
- //System.out.println(name);
+ //LOGGER.info(name);
/*if(!name.startsWith(SCL_PACKAGE_PREFIX) || !extractClassLoaderId(name).equals(moduleName))
throw new IllegalArgumentException("Class name " + name + " does not start with '" +
SCL_PACKAGE_PREFIX + moduleName + "$'.");
*/
}
+ @Override
public byte[] getBytes(String name) {
// Non-SCL classes are not handled here
if(!name.startsWith(SCL_PACKAGE_PREFIX))
return parentModule.classLoader.getBytes(name);
}
}
-
+
synchronized Class<?> getLocalClass(String name) throws ClassNotFoundException {
// Is class already loaded
Class<?> clazz = findLoadedClass(name);
bytes = localClasses.get(internalName);
if(bytes == null)
throw new ClassNotFoundException(name);
- }
+ }
+ if(SCLCompilerConfiguration.SHOW_DECOMPILED_BYTECODE && SCLCompilerConfiguration.debugFilter(moduleName))
+ showDecompiledBytecode(internalName);
return defineClass(name, bytes, 0, bytes.length);
}
private Class<?> getClass(String name) throws ClassNotFoundException {
- //System.out.println("getClass " + name);
+ //LOGGER.info("getClass " + name);
// If the class is not generated from SCL, use parent class loader
if(!name.startsWith(SCL_PACKAGE_PREFIX)) {
{
RuntimeModule parentModule = parentModuleMap.get(requestedModuleName);
if(parentModule == null) {
- System.err.println("requestedModuleName = " + requestedModuleName);
- System.err.println("this.moduleName = " + this.moduleName);
+ LOGGER.error("requestedModuleName = " + requestedModuleName);
+ LOGGER.error("this.moduleName = " + this.moduleName);
throw new ClassNotFoundException(name);
}
}
public Module getModule(String moduleName) {
- //System.out.println("ModuleClassLoader.getModule(" + moduleName + ")");
+ //LOGGER.info("ModuleClassLoader.getModule(" + moduleName + ")");
if(moduleName.equals(this.moduleName))
return module;
else {
public ClassLoader getClassLoader() {
return this;
}
+
+ private void showDecompiledBytecode(String className) {
+ IDecompiler decompiler = DecompilerFactory.getDecompiler();
+ if(decompiler == null)
+ return;
+ decompiler.decompile(this, className, new OutputStreamWriter(new LoggingOutputStream(LOGGER, LogLevel.INFO)));
+ }
}
@Override
public void collectRules(Collection<TransformationRule> rules) {
}
+ @Override
+ public List<Constant> getFieldAccessors(String name) {
+ // TODO Not clear if this is needed.
+ return null;
+ }
};
public RuntimeModule(Module module, RuntimeModuleMap parentModuleMap,