Remove finally marker at inlining
This commit is contained in:
@@ -1804,13 +1804,13 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
Label finallyStart = new Label();
|
||||
v.mark(finallyStart);
|
||||
finallyBlockStackElement.addGapLabel(finallyStart);
|
||||
if (context.isInlineFunction() || context.isInliningLambda()) {
|
||||
if (InlineCodegenUtil.isFinallyMarkerRequired(context)) {
|
||||
InlineCodegenUtil.generateFinallyMarker(v, finallyDeep, true);
|
||||
}
|
||||
//noinspection ConstantConditions
|
||||
gen(jetTryExpression.getFinallyBlock().getFinalExpression(), Type.VOID_TYPE);
|
||||
|
||||
if (context.isInlineFunction() || context.isInliningLambda()) {
|
||||
if (InlineCodegenUtil.isFinallyMarkerRequired(context)) {
|
||||
InlineCodegenUtil.generateFinallyMarker(v, finallyDeep, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ import org.jetbrains.org.objectweb.asm.Opcodes;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method;
|
||||
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode;
|
||||
import org.jetbrains.org.objectweb.asm.tree.InsnList;
|
||||
import org.jetbrains.org.objectweb.asm.tree.LabelNode;
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
@@ -62,6 +63,7 @@ import static org.jetbrains.kotlin.codegen.AsmUtil.getMethodAsmFlags;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive;
|
||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.CLASS_FOR_SCRIPT;
|
||||
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.addInlineMarker;
|
||||
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.getConstant;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isFunctionLiteral;
|
||||
import static org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage.getResolvedCallWithAssert;
|
||||
|
||||
@@ -290,6 +292,7 @@ public class InlineCodegen extends CallGenerator {
|
||||
|
||||
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));
|
||||
|
||||
@@ -647,8 +650,8 @@ public class InlineCodegen extends CallGenerator {
|
||||
|
||||
|
||||
public void generateAndInsertFinallyBlocks(
|
||||
MethodNode intoNode,
|
||||
List<MethodInliner.PointForExternalFinallyBlocks> insertPoints,
|
||||
@NotNull MethodNode intoNode,
|
||||
@NotNull List<MethodInliner.PointForExternalFinallyBlocks> insertPoints,
|
||||
int offsetForFinallyLocalVar
|
||||
) {
|
||||
if (!codegen.hasFinallyBlocks()) return;
|
||||
@@ -667,7 +670,7 @@ public class InlineCodegen extends CallGenerator {
|
||||
processor.processInstruction(curInstr, true);
|
||||
if (InlineCodegenUtil.isFinallyStart(curInstr)) {
|
||||
//TODO deep index calc could be more precise
|
||||
curFinallyDeep = InlineCodegenUtil.getConstant(curInstr.getPrevious());
|
||||
curFinallyDeep = getConstant(curInstr.getPrevious());
|
||||
}
|
||||
|
||||
MethodInliner.PointForExternalFinallyBlocks extension = extensionPoints.get(curInstr);
|
||||
@@ -709,6 +712,25 @@ public class InlineCodegen extends CallGenerator {
|
||||
//processor.substituteLocalVarTable(intoNode);
|
||||
}
|
||||
|
||||
public void removeFinallyMarkers(@NotNull MethodNode intoNode) {
|
||||
if (InlineCodegenUtil.isFinallyMarkerRequired(codegen.getContext())) return;
|
||||
|
||||
InsnList instructions = intoNode.instructions;
|
||||
AbstractInsnNode curInstr = instructions.getFirst();
|
||||
while (curInstr != null) {
|
||||
if (InlineCodegenUtil.isFinallyMarker(curInstr)) {
|
||||
//just to assert
|
||||
AbstractInsnNode marker = curInstr;
|
||||
getConstant(marker.getPrevious());
|
||||
curInstr = curInstr.getNext();
|
||||
instructions.remove(marker.getPrevious());
|
||||
instructions.remove(marker);
|
||||
continue;
|
||||
}
|
||||
curInstr = curInstr.getNext();
|
||||
}
|
||||
}
|
||||
|
||||
private SourceMapper createNestedSourceMapper(@NotNull SMAPAndMethodNode nodeAndSmap) {
|
||||
return new NestedSourceMapper(sourceMapper, nodeAndSmap.getRanges(), nodeAndSmap.getClassSMAP().getSourceInfo());
|
||||
}
|
||||
|
||||
@@ -427,12 +427,21 @@ public class InlineCodegenUtil {
|
||||
return INLINE_MARKER_CLASS_NAME.equals(method.owner) && name.equals(method.name);
|
||||
}
|
||||
|
||||
public static boolean isFinallyMarkerRequired(@NotNull MethodContext context) {
|
||||
return context.isInlineFunction() || context.isInliningLambda();
|
||||
}
|
||||
|
||||
public static int getConstant(AbstractInsnNode ins) {
|
||||
int opcode = ins.getOpcode();
|
||||
Integer value;
|
||||
if (opcode >= Opcodes.ICONST_0 && opcode <= Opcodes.ICONST_5) {
|
||||
value = opcode - Opcodes.ICONST_0;
|
||||
} else {
|
||||
}
|
||||
else if (opcode == Opcodes.BIPUSH || opcode == Opcodes.SIPUSH) {
|
||||
IntInsnNode index = (IntInsnNode) ins;
|
||||
value = index.operand;
|
||||
}
|
||||
else {
|
||||
LdcInsnNode index = (LdcInsnNode) ins;
|
||||
value = (Integer) index.cst;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
inline fun test(s: ()->Int){
|
||||
var i = 0;
|
||||
try {
|
||||
i = s()
|
||||
i = i + 10
|
||||
} finally {
|
||||
//finallyStart
|
||||
i
|
||||
//finallyEnd
|
||||
//and same markers in default catch handler
|
||||
}
|
||||
}
|
||||
|
||||
fun box() : String {
|
||||
var p: Int = 1
|
||||
test {
|
||||
try {
|
||||
p = 1
|
||||
return "OK"
|
||||
} catch(e: Exception) {
|
||||
p = -1;
|
||||
p
|
||||
} finally {
|
||||
p++
|
||||
}
|
||||
|
||||
}
|
||||
return "fail"
|
||||
}
|
||||
|
||||
// 2 InlineMarker.finallyStart
|
||||
// 2 InlineMarker.finallyEnd
|
||||
// 4 InlineMarker
|
||||
@@ -499,6 +499,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("removedFinallyMarkers.kt")
|
||||
public void testRemovedFinallyMarkers() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inline/removedFinallyMarkers.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("splitedExceptionTable.kt")
|
||||
public void testSplitedExceptionTable() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inline/splitedExceptionTable.kt");
|
||||
|
||||
Reference in New Issue
Block a user