コード例 #1
0
ファイル: InlineCodegen.java プロジェクト: grigala/kotlin
  public InlineCodegen(
      @NotNull ExpressionCodegen codegen,
      @NotNull GenerationState state,
      @NotNull SimpleFunctionDescriptor functionDescriptor,
      @NotNull JetElement callElement,
      @Nullable ReifiedTypeParameterMappings typeParameterMappings) {
    assert InlineUtil.isInline(functionDescriptor)
        : "InlineCodegen could inline only inline function: " + functionDescriptor;

    this.state = state;
    this.typeMapper = state.getTypeMapper();
    this.codegen = codegen;
    this.callElement = callElement;
    this.functionDescriptor = functionDescriptor.getOriginal();

    reifiedTypeInliner = new ReifiedTypeInliner(typeParameterMappings);

    initialFrameSize = codegen.getFrameMap().getCurrentSize();

    context = (MethodContext) getContext(functionDescriptor, state);
    jvmSignature = typeMapper.mapSignature(functionDescriptor, context.getContextKind());

    // TODO: implement AS_FUNCTION inline strategy
    InlineStrategy inlineStrategy = InlineUtil.getInlineStrategy(functionDescriptor);
    this.asFunctionInline = false;

    isSameModule =
        JvmCodegenUtil.isCallInsideSameModuleAsDeclared(
            functionDescriptor, codegen.getContext(), state.getOutDirectory());

    sourceMapper = codegen.getParentCodegen().getOrCreateSourceMapper();
    reportIncrementalInfo(
        functionDescriptor, codegen.getContext().getFunctionDescriptor().getOriginal());
  }
コード例 #2
0
ファイル: InlineCodegen.java プロジェクト: grigala/kotlin
 public void leaveTemps() {
   FrameMap frameMap = codegen.getFrameMap();
   List<ParameterInfo> infos = invocationParamBuilder.listAllParams();
   for (ListIterator<? extends ParameterInfo> iterator = infos.listIterator(infos.size());
       iterator.hasPrevious(); ) {
     ParameterInfo param = iterator.previous();
     if (!param.isSkippedOrRemapped()) {
       frameMap.leaveTemp(param.type);
     }
   }
 }
コード例 #3
0
ファイル: InlineCodegen.java プロジェクト: grigala/kotlin
  private void putParameterOnStack(ParameterInfo... infos) {
    int[] index = new int[infos.length];
    for (int i = 0; i < infos.length; i++) {
      ParameterInfo info = infos[i];
      if (!info.isSkippedOrRemapped()) {
        index[i] = codegen.getFrameMap().enterTemp(info.getType());
      } else {
        index[i] = -1;
      }
    }

    for (int i = infos.length - 1; i >= 0; i--) {
      ParameterInfo info = infos[i];
      if (!info.isSkippedOrRemapped()) {
        Type type = info.type;
        StackValue.local(index[i], type).store(StackValue.onStack(type), codegen.v);
      }
    }
  }
コード例 #4
0
ファイル: InlineCodegen.java プロジェクト: grigala/kotlin
  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);
  }