Write local variable for inline function and inline argument

This commit is contained in:
Natalia Ukhorskaya
2015-09-28 16:43:02 +03:00
parent 3452fc8d02
commit 9168572b8c
10 changed files with 54 additions and 7 deletions
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget;
import org.jetbrains.kotlin.jvm.RuntimeAssertionInfo;
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
import org.jetbrains.kotlin.load.java.SpecialBuiltinMembers;
import org.jetbrains.kotlin.load.kotlin.nativeDeclarations.NativeKt;
@@ -57,10 +58,7 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
import org.jetbrains.kotlin.types.JetType;
import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
import org.jetbrains.org.objectweb.asm.Label;
import org.jetbrains.org.objectweb.asm.MethodVisitor;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.*;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import org.jetbrains.org.objectweb.asm.commons.Method;
import org.jetbrains.org.objectweb.asm.util.TraceMethodVisitor;
@@ -355,6 +353,10 @@ public class FunctionCodegen {
JetTypeMapper typeMapper = parentCodegen.typeMapper;
Label methodEnd;
int functionFakeIndex = -1;
int lambdaFakeIndex = -1;
if (context.getParentContext() instanceof DelegatingFacadeContext) {
generateFacadeDelegateMethodBody(mv, signature.getAsmMethod(), (DelegatingFacadeContext) context.getParentContext());
methodEnd = new Label();
@@ -362,6 +364,13 @@ public class FunctionCodegen {
else {
FrameMap frameMap = createFrameMap(parentCodegen.state, functionDescriptor, signature, isStaticMethod(context.getContextKind(),
functionDescriptor));
if (context.isInlineFunction()) {
functionFakeIndex = frameMap.enterTemp(Type.INT_TYPE);
}
if (context.isInliningLambda()) {
lambdaFakeIndex = frameMap.enterTemp(Type.INT_TYPE);
}
Label methodEntry = new Label();
mv.visitLabel(methodEntry);
@@ -379,6 +388,27 @@ public class FunctionCodegen {
Type thisType = getThisTypeForFunction(functionDescriptor, context, typeMapper);
generateLocalVariableTable(mv, signature, functionDescriptor, thisType, methodBegin, methodEnd, context.getContextKind());
if (context.isInlineFunction() && functionFakeIndex != -1) {
mv.visitLocalVariable(
JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION + functionDescriptor.getName().asString(),
Type.INT_TYPE.getDescriptor(), null,
methodBegin, methodEnd,
functionFakeIndex);
}
if (context.isInliningLambda() && thisType != null && lambdaFakeIndex != -1) {
String name = thisType.getClassName();
int indexOfLambdaOrdinal = name.lastIndexOf("$");
if (indexOfLambdaOrdinal > 0) {
int lambdaOrdinal = Integer.parseInt(name.substring(indexOfLambdaOrdinal + 1));
mv.visitLocalVariable(
JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_ARGUMENT + lambdaOrdinal,
Type.INT_TYPE.getDescriptor(), null,
methodBegin, methodEnd,
lambdaFakeIndex);
}
}
}
private static void generateLocalVariableTable(
@@ -14,4 +14,6 @@ class A {
// METHOD : A.foo()V
// VARIABLE : NAME=zzz TYPE=I INDEX=3
// VARIABLE : NAME=it TYPE=I INDEX=2
// VARIABLE : NAME=$i$a$1 TYPE=I INDEX=4
// VARIABLE : NAME=$i$f$inlineFun TYPE=I INDEX=5
// VARIABLE : NAME=this TYPE=LA; INDEX=0
@@ -16,7 +16,10 @@ class A {
// METHOD : A.foo()V
// VARIABLE : NAME=zzz TYPE=I INDEX=4
// VARIABLE : NAME=l TYPE=I INDEX=3
// VARIABLE : NAME=$i$a$1 TYPE=I INDEX=5
// VARIABLE : NAME=zzz TYPE=I INDEX=4
// VARIABLE : NAME=l TYPE=I INDEX=3
// VARIABLE : NAME=$i$a$1 TYPE=I INDEX=5
// VARIABLE : NAME=p TYPE=I INDEX=2
// VARIABLE : NAME=$i$f$inlineFun TYPE=I INDEX=6
// VARIABLE : NAME=this TYPE=LA; INDEX=0
@@ -14,5 +14,7 @@ class A {
// METHOD : A.foo()V
// VARIABLE : NAME=zzz TYPE=I INDEX=3
// VARIABLE : NAME=$i$a$1 TYPE=I INDEX=4
// VARIABLE : NAME=$i$f$inlineFun TYPE=I INDEX=5
// VARIABLE : NAME=s TYPE=I INDEX=1
// VARIABLE : NAME=this TYPE=LA; INDEX=0
@@ -19,6 +19,10 @@ class A {
// METHOD : A.foo()V
// VARIABLE : NAME=zz2 TYPE=I INDEX=5
// VARIABLE : NAME=$i$a$1 TYPE=I INDEX=6
// VARIABLE : NAME=$i$f$inlineFun TYPE=I INDEX=7
// VARIABLE : NAME=z TYPE=I INDEX=3
// VARIABLE : NAME=$i$a$1 TYPE=I INDEX=8
// VARIABLE : NAME=$i$f$inlineFun TYPE=I INDEX=9
// VARIABLE : NAME=s TYPE=I INDEX=1
// VARIABLE : NAME=this TYPE=LA; INDEX=0
@@ -12,5 +12,5 @@ fun foo() : String {
// 8 ALOAD
// 2 LSTORE
// 6 LLOAD
// 1 MAXLOCALS = 9
// 1 MAXLOCALS = 10
// 0 InlineMarker
@@ -12,5 +12,6 @@ fun test() {
// 3 ILOAD
// 2 ASTORE
// 7 ALOAD
// 3 MAXLOCALS = 3
// 2 MAXLOCALS = 3
// 1 MAXLOCALS = 4
// 0 InlineMarker
@@ -7,5 +7,5 @@ fun foo() : String {
// 6 ASTORE
// 21 ALOAD
// 1 MAXLOCALS = 5
// 1 MAXLOCALS = 7
// 0 InlineMarker
@@ -57,6 +57,9 @@ public final class JvmAbi {
public static final String DEFAULT_MODULE_NAME = "main";
public static final ClassId REFLECTION_FACTORY_IMPL = ClassId.topLevel(new FqName("kotlin.reflect.jvm.internal.ReflectionFactoryImpl"));
public static final String LOCAL_VARIABLE_NAME_PREFIX_INLINE_ARGUMENT = "$i$a$";
public static final String LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION = "$i$f$";
@NotNull
public static String getSyntheticMethodNameForAnnotatedProperty(@NotNull Name propertyName) {
return propertyName.asString() + ANNOTATED_PROPERTY_METHOD_NAME_SUFFIX;
@@ -25,6 +25,8 @@ inline fun foo(f: () -> Unit) {
local = args: java.lang.String[] = {java.lang.String[0]@uniqueID} (sp = frameSharedVarLocalVar.kt, 3)
local = var1: kotlin.jvm.internal.Ref$IntRef = {kotlin.jvm.internal.Ref$IntRef@uniqueID}1 (sp = frameSharedVarLocalVar.kt, 4)
field = element: int = 1 (sp = Ref.!EXT!)
local = $i$a$1: int = 0 (sp = null)
local = $i$f$foo: int = 0 (sp = null)
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
Process finished with exit code 0