@NotNull
  private InlineResult inlineMethod(
      @NotNull AnonymousObjectGeneration anonymousObjectGen,
      @NotNull FieldRemapper parentRemapper,
      @NotNull MethodVisitor deferringVisitor,
      @NotNull MethodNode sourceNode,
      @NotNull ParametersBuilder capturedBuilder,
      boolean isConstructor) {
    ReifiedTypeParametersUsages typeParametersToReify =
        inliningContext.reifedTypeInliner.reifyInstructions(sourceNode);
    Parameters parameters =
        isConstructor
            ? capturedBuilder.buildParameters()
            : getMethodParametersWithCaptured(capturedBuilder, sourceNode);

    RegeneratedLambdaFieldRemapper remapper =
        new RegeneratedLambdaFieldRemapper(
            oldObjectType.getInternalName(),
            newLambdaType.getInternalName(),
            parameters,
            anonymousObjectGen.getCapturedLambdasToInline(),
            parentRemapper,
            isConstructor);

    MethodInliner inliner =
        new MethodInliner(
            sourceNode,
            parameters,
            inliningContext.subInline(inliningContext.nameGenerator.subGenerator("lambda")),
            remapper,
            isSameModule,
            "Transformer for " + anonymousObjectGen.getOwnerInternalName(),
            sourceMapper,
            new InlineCallSiteInfo(
                anonymousObjectGen.getOwnerInternalName(),
                sourceNode.name,
                isConstructor
                    ? anonymousObjectGen.getNewConstructorDescriptor()
                    : sourceNode.desc));

    InlineResult result =
        inliner.doInline(
            deferringVisitor,
            new LocalVarRemapper(parameters, 0),
            false,
            LabelOwner.NOT_APPLICABLE);
    result.getReifiedTypeParametersUsages().mergeAll(typeParametersToReify);
    deferringVisitor.visitMaxs(-1, -1);
    return result;
  }
예제 #2
0
  private InlineResult inlineCall(SMAPAndMethodNode nodeAndSmap) {
    MethodNode node = nodeAndSmap.getNode();
    ReifiedTypeParametersUsages reificationResult =
        reifiedTypeInliner.reifyInstructions(node.instructions);
    generateClosuresBodies();

    // through generation captured parameters will be added to invocationParamBuilder
    putClosureParametersOnStack();

    addInlineMarker(codegen.v, true);

    Parameters parameters = invocationParamBuilder.buildParameters();

    InliningContext info =
        new RootInliningContext(
            expressionMap,
            state,
            codegen.getInlineNameGenerator().subGenerator(functionDescriptor.getName().asString()),
            codegen.getContext(),
            callElement,
            codegen.getParentCodegen().getClassName(),
            reifiedTypeInliner);

    MethodInliner inliner =
        new MethodInliner(
            node,
            parameters,
            info,
            new FieldRemapper(null, null, parameters),
            isSameModule,
            "Method inlining " + callElement.getText(),
            createNestedSourceMapper(nodeAndSmap)); // with captured

    LocalVarRemapper remapper = new LocalVarRemapper(parameters, initialFrameSize);

    MethodNode adapter = InlineCodegenUtil.createEmptyMethodNode();
    // hack to keep linenumber info, otherwise jdi will skip begin of linenumber chain
    adapter.visitInsn(Opcodes.NOP);

    InlineResult result = inliner.doInline(adapter, remapper, true, LabelOwner.SKIP_ALL);
    result.getReifiedTypeParametersUsages().mergeAll(reificationResult);

    CallableMemberDescriptor descriptor = codegen.getContext().getContextDescriptor();
    final Set<String> labels =
        getDeclarationLabels(
            DescriptorToSourceUtils.descriptorToDeclaration(descriptor), descriptor);
    LabelOwner labelOwner =
        new LabelOwner() {
          @Override
          public boolean isMyLabel(@NotNull String name) {
            return labels.contains(name);
          }
        };

    List<MethodInliner.PointForExternalFinallyBlocks> infos =
        MethodInliner.processReturns(adapter, labelOwner, true, null);
    generateAndInsertFinallyBlocks(
        adapter,
        infos,
        ((StackValue.Local) remapper.remap(parameters.totalSize() + 1).value).index);
    removeFinallyMarkers(adapter);

    adapter.accept(new InliningInstructionAdapter(codegen.v));

    addInlineMarker(codegen.v, false);

    return result;
  }