Пример #1
0
  public void generateAndInsertFinallyBlocks(
      @NotNull MethodNode intoNode,
      @NotNull List<MethodInliner.PointForExternalFinallyBlocks> insertPoints,
      int offsetForFinallyLocalVar) {
    if (!codegen.hasFinallyBlocks()) return;

    Map<AbstractInsnNode, MethodInliner.PointForExternalFinallyBlocks> extensionPoints =
        new HashMap<AbstractInsnNode, MethodInliner.PointForExternalFinallyBlocks>();
    for (MethodInliner.PointForExternalFinallyBlocks insertPoint : insertPoints) {
      extensionPoints.put(insertPoint.beforeIns, insertPoint);
    }

    DefaultProcessor processor = new DefaultProcessor(intoNode, offsetForFinallyLocalVar);

    int curFinallyDepth = 0;
    AbstractInsnNode curInstr = intoNode.instructions.getFirst();
    while (curInstr != null) {
      processor.processInstruction(curInstr, true);
      if (InlineCodegenUtil.isFinallyStart(curInstr)) {
        // TODO depth index calc could be more precise
        curFinallyDepth = getConstant(curInstr.getPrevious());
      }

      MethodInliner.PointForExternalFinallyBlocks extension = extensionPoints.get(curInstr);
      if (extension != null) {
        Label start = new Label();

        MethodNode finallyNode = InlineCodegenUtil.createEmptyMethodNode();
        finallyNode.visitLabel(start);

        ExpressionCodegen finallyCodegen =
            new ExpressionCodegen(
                finallyNode,
                codegen.getFrameMap(),
                codegen.getReturnType(),
                codegen.getContext(),
                codegen.getState(),
                codegen.getParentCodegen());
        finallyCodegen.addBlockStackElementsForNonLocalReturns(
            codegen.getBlockStackElements(), curFinallyDepth);

        FrameMap frameMap = finallyCodegen.getFrameMap();
        FrameMap.Mark mark = frameMap.mark();
        while (frameMap.getCurrentSize() < processor.getNextFreeLocalIndex()) {
          frameMap.enterTemp(Type.INT_TYPE);
        }

        finallyCodegen.generateFinallyBlocksIfNeeded(
            extension.returnType, extension.finallyIntervalEnd.getLabel());

        // Exception table for external try/catch/finally blocks will be generated in original
        // codegen after exiting this method
        InlineCodegenUtil.insertNodeBefore(finallyNode, intoNode, curInstr);

        SimpleInterval splitBy =
            new SimpleInterval((LabelNode) start.info, extension.finallyIntervalEnd);
        processor.getTryBlocksMetaInfo().splitCurrentIntervals(splitBy, true);

        // processor.getLocalVarsMetaInfo().splitAndRemoveIntervalsFromCurrents(splitBy);

        mark.dropTo();
      }

      curInstr = curInstr.getNext();
    }

    processor.substituteTryBlockNodes(intoNode);

    // processor.substituteLocalVarTable(intoNode);
  }
  public static boolean compileModules(
      @NotNull KotlinCoreEnvironment environment,
      @NotNull CompilerConfiguration configuration,
      @NotNull List<Module> chunk,
      @NotNull File directory,
      @Nullable File jarPath,
      @NotNull List<String> friendPaths,
      boolean jarRuntime) {
    Map<Module, ClassFileFactory> outputFiles = Maps.newHashMap();

    ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();

    ModuleVisibilityManager moduleVisibilityManager =
        ModuleVisibilityManager.SERVICE.getInstance(environment.getProject());

    for (Module module : chunk) {
      moduleVisibilityManager.addModule(module);
    }

    for (String path : friendPaths) {
      moduleVisibilityManager.addFriendPath(path);
    }

    String targetDescription =
        "in targets ["
            + Joiner.on(", ")
                .join(
                    Collections2.transform(
                        chunk,
                        new Function<Module, String>() {
                          @Override
                          public String apply(@Nullable Module input) {
                            return input != null
                                ? input.getModuleName() + "-" + input.getModuleType()
                                : "<null>";
                          }
                        }))
            + "] ";
    AnalysisResult result = analyze(environment, targetDescription);
    if (result == null) {
      return false;
    }

    ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();

    result.throwIfError();

    for (Module module : chunk) {
      ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
      List<KtFile> jetFiles =
          CompileEnvironmentUtil.getKtFiles(
              environment.getProject(),
              getAbsolutePaths(directory, module),
              new Function1<String, Unit>() {
                @Override
                public Unit invoke(String s) {
                  throw new IllegalStateException("Should have been checked before: " + s);
                }
              });
      File moduleOutputDirectory = new File(module.getOutputDirectory());
      GenerationState generationState =
          generate(
              environment, result, jetFiles, module, moduleOutputDirectory, module.getModuleName());
      outputFiles.put(module, generationState.getFactory());
    }

    for (Module module : chunk) {
      ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
      writeOutput(
          configuration,
          outputFiles.get(module),
          new File(module.getOutputDirectory()),
          jarPath,
          jarRuntime,
          null);
    }
    return true;
  }