]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/runtime/RuntimeModule.java
Make it possible to debug SCL compiler in production builds
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / runtime / RuntimeModule.java
index aeb21ffa63b333a5aae9cd1b018c75aad4549e29..4893f684084a0479d48f241c35ddd21a3a9bbdc5 100644 (file)
@@ -1,5 +1,6 @@
 package org.simantics.scl.compiler.runtime;
 
+import java.io.OutputStreamWriter;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
@@ -12,13 +13,22 @@ import org.simantics.scl.compiler.environment.Environment;
 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;
     
@@ -42,7 +52,7 @@ public class RuntimeModule {
         
         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_);
@@ -51,7 +61,7 @@ public class RuntimeModule {
         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);
@@ -59,13 +69,14 @@ public class RuntimeModule {
         }
         
         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))
@@ -93,7 +104,7 @@ public class RuntimeModule {
                 return parentModule.classLoader.getBytes(name);
             }
         }
-        
+
         synchronized Class<?> getLocalClass(String name) throws ClassNotFoundException {
             // Is class already loaded
             Class<?> clazz = findLoadedClass(name);
@@ -107,12 +118,14 @@ public class RuntimeModule {
                 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)) {
@@ -139,8 +152,8 @@ public class RuntimeModule {
             {
                 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);
                 }
 
@@ -158,7 +171,7 @@ public class RuntimeModule {
         }
         
         public Module getModule(String moduleName) {
-            //System.out.println("ModuleClassLoader.getModule(" + moduleName + ")");
+            //LOGGER.info("ModuleClassLoader.getModule(" + moduleName + ")");
             if(moduleName.equals(this.moduleName))
                 return module;
             else {
@@ -187,6 +200,13 @@ public class RuntimeModule {
         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)));
+        }
     }