예제 #1
0
  private String sourceMap(Script script) {
    if (!compilerOptions.contains(Option.SourceMap)) {
      return null;
    }
    String sourceFile = script.getSourceFile();
    Path path;
    try {
      path = Paths.get(sourceFile);
    } catch (InvalidPathException e) {
      // return here if 'sourceFile' is not a valid path
      return null;
    }
    // line numbers are limited to uint16 in bytecode, valid line count not needed for smap
    final int maxLineCount = 0xffff;
    try (Formatter smap = new Formatter(Locale.ROOT)) {
      // Header
      // - ID
      smap.format("SMAP%n");
      // - OutputFileName
      smap.format("%s%n", script.getSourceFile());
      // - DefaultStratumId
      smap.format("Script%n");
      // Section
      // - StratumSection
      smap.format("*S Script%n");
      // - FileSection
      smap.format("*F%n");
      // -- FileInfo
      smap.format("+ 1 %s%n%s%n", path.getFileName(), path);
      // - LineSection
      smap.format("*L%n");
      // -- LineInfo
      smap.format("%d#1,%d:%d%n", script.getBeginLine(), maxLineCount, script.getBeginLine());
      // EndSection
      smap.format("*E%n");

      return smap.toString();
    }
  }
예제 #2
0
  public CompiledScript compile(Script script, String className) {
    try (CodeSizeAnalysis analysis = new CodeSizeAnalysis()) {
      analysis.submit(script);
    } catch (CodeSizeException e) {
      e.printStackTrace();
      throw new CompilationException(e.getMessage());
    }

    // set-up
    // prepend '#' to mark generated classes, cf. ErrorPrototype
    String clazzName = "#" + className;
    String superClassName = Types.CompiledScript.getInternalName();
    Code code = new Code(clazzName, superClassName, script.getSourceFile(), sourceMap(script));

    // generate code
    try (CodeGenerator codegen = new CodeGenerator(code, script.getOptions())) {
      codegen.compile(script);
    }

    // finalize
    CodeLoader loader = new CodeLoader();
    List<ClassCode> classes = code.getClasses();
    for (ClassCode classCode : classes) {
      byte[] bytes = classCode.toByteArray();
      if (compilerOptions.contains(Option.Debug)) {
        debug(bytes);
      }
      // System.out.printf("define class '%s'%n", classCode.className);
      loader.defineClass(classCode.className, bytes);
    }

    try {
      Class<?> c = loader.loadClass(clazzName);
      return (CompiledScript) c.newInstance();
    } catch (ReflectiveOperationException e) {
      throw new RuntimeException(e);
    }
  }