/**
   * For debugging, it's useful to dump the content of the generated classes along with the
   * exception that was generated.
   *
   * <p>However to make it work you need to pull in the org.objectweb.asm.util.TraceClassVisitor
   * class and associated utilities which are found in the ASM source jar. Since we don't want that
   * dependency in the source code, we only put it manually for development and access the
   * TraceClassVisitor via reflection if present.
   *
   * @param t The exception thrown by {@link ClassLoader2#testModifiedInstance()}
   * @param cl2 The {@link ClassLoader2} instance with the generated bytecode.
   * @return Either original {@code t} or a new wrapper {@link Throwable}
   */
  private Throwable dumpGeneratedClass(Throwable t, ClassLoader2 cl2) {
    try {
      // For debugging, dump the bytecode of the class in case of unexpected error
      // if we can find the TraceClassVisitor class.
      Class<?> tcvClass = Class.forName("org.objectweb.asm.util.TraceClassVisitor");

      StringBuilder sb = new StringBuilder();
      sb.append('\n').append(t.getClass().getCanonicalName());
      if (t.getMessage() != null) {
        sb.append(": ").append(t.getMessage());
      }

      for (Entry<String, byte[]> entry : cl2.getByteCode()) {
        String className = entry.getKey();
        byte[] bytes = entry.getValue();

        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        // next 2 lines do: TraceClassVisitor tcv = new TraceClassVisitor(pw);
        Constructor<?> cons = tcvClass.getConstructor(new Class<?>[] {pw.getClass()});
        Object tcv = cons.newInstance(new Object[] {pw});
        ClassReader cr2 = new ClassReader(bytes);
        cr2.accept((ClassVisitor) tcv, 0 /* flags */);

        sb.append("\nBytecode dump: <").append(className).append(">:\n").append(sw.toString());
      }

      // Re-throw exception with new message
      RuntimeException ex = new RuntimeException(sb.toString(), t);
      return ex;
    } catch (Throwable ignore) {
      // In case of problem, just throw the original exception as-is.
      return t;
    }
  }
Example #2
0
 public void setWriter(WriterKind kind, PrintWriter pw) {
   pw.getClass();
   switch (kind) {
     case NOTICE:
       noticeWriter = pw;
       break;
     case WARNING:
       warnWriter = pw;
       break;
     case ERROR:
       errWriter = pw;
       break;
     default:
       throw new IllegalArgumentException();
   }
 }
Example #3
0
 public static void main(String args[]) {
   outLog = new PrintWriter(System.out);
   outLog.println("Starting pickle compile");
   try {
     args = argsParse(args);
     if (args.length < 1) {
       outLog.println(
           "usage java pickle.Compiler ((-l log) | (-p piDir) | (-r prDir) | (-f piFile))* infile (((-l log)? (-o outDir)?) generator)+");
       System.exit(1);
     }
     Application application;
     if (combine == true) {
       outLog.println("Combining");
       String code = combineFileReader(args[0]);
       if (pickleFileName.length() > 0) {
         FileWriter fileWriter = new FileWriter(pickleFileName);
         PrintWriter writer = new PrintWriter(fileWriter);
         writer.println(code);
         writer.flush();
         writer.close();
         fileWriter.close();
       }
       StringReader reader = new StringReader(code);
       application = Pickle.run(reader, outLog);
     } else {
       outLog.println("Compiling file " + args[0]);
       application = Pickle.run(args[0], outLog);
       outLog.println("Compile completed of " + args[0]);
     }
     if (application == null) {
       outLog.println("Error: Compile aborted due to errors");
       outLog.flush();
       System.exit(1);
     }
     String output = "";
     for (int i = 1; i < args.length; i++) {
       if (args[i].equals("-o")) {
         if (i + 1 < args.length) {
           output = args[++i];
           char term = '\\';
           if (output.indexOf('/') != -1) term = '/';
           char ch = output.charAt(output.length() - 1);
           if (ch != term) output = output + term;
           mkPath(output);
           outLog.println("Generating to " + output);
         }
         continue;
       } else if (args[i].equals("-l")) {
         if (i + 1 < args.length) {
           String log = args[++i];
           mkFilesPath(log);
           OutputStream outFile = new FileOutputStream(log);
           outLog.flush();
           outLog = new PrintWriter(outFile);
         }
         continue;
       }
       outLog.println(args[i]);
       Class<?> c = Class.forName("vlab.pickle." + args[i]);
       Class<?> d[] = {application.getClass(), output.getClass(), outLog.getClass()};
       Method m = c.getMethod("generate", d);
       Object o[] = {application, output, outLog};
       m.invoke(application, o);
     }
     outLog.flush();
   } catch (Exception e) {
     outLog.println("Error: " + e);
     e.printStackTrace();
     outLog.flush();
     System.exit(1);
   }
   System.exit(0);
 }
Example #4
0
 public void setWriters(PrintWriter pw) {
   pw.getClass();
   noticeWriter = warnWriter = errWriter = pw;
 }