Convert InlineCodegenUtil to Kotlin
This commit is contained in:
@@ -20,7 +20,6 @@ import com.intellij.psi.PsiElement;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.codegen.inline.FileMapping;
|
import org.jetbrains.kotlin.codegen.inline.FileMapping;
|
||||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil;
|
|
||||||
import org.jetbrains.kotlin.codegen.inline.SMAPBuilder;
|
import org.jetbrains.kotlin.codegen.inline.SMAPBuilder;
|
||||||
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings;
|
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
||||||
@@ -29,6 +28,8 @@ import org.jetbrains.org.objectweb.asm.*;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.GENERATE_SMAP;
|
||||||
|
|
||||||
public abstract class AbstractClassBuilder implements ClassBuilder {
|
public abstract class AbstractClassBuilder implements ClassBuilder {
|
||||||
protected static final MethodVisitor EMPTY_METHOD_VISITOR = new MethodVisitor(Opcodes.ASM5) {};
|
protected static final MethodVisitor EMPTY_METHOD_VISITOR = new MethodVisitor(Opcodes.ASM5) {};
|
||||||
protected static final FieldVisitor EMPTY_FIELD_VISITOR = new FieldVisitor(Opcodes.ASM5) {};
|
protected static final FieldVisitor EMPTY_FIELD_VISITOR = new FieldVisitor(Opcodes.ASM5) {};
|
||||||
@@ -105,7 +106,7 @@ public abstract class AbstractClassBuilder implements ClassBuilder {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void done() {
|
public void done() {
|
||||||
if (!fileMappings.isEmpty() && InlineCodegenUtil.GENERATE_SMAP) {
|
if (!fileMappings.isEmpty() && GENERATE_SMAP) {
|
||||||
FileMapping origin = fileMappings.get(0);
|
FileMapping origin = fileMappings.get(0);
|
||||||
assert sourceName == null || origin.getName().equals(sourceName) : "Error " + origin.getName() + " != " + sourceName;
|
assert sourceName == null || origin.getName().equals(sourceName) : "Error " + origin.getName() + " != " + sourceName;
|
||||||
getVisitor().visitSource(origin.getName(), new SMAPBuilder(origin.getName(), origin.getPath(), fileMappings).build());
|
getVisitor().visitSource(origin.getName(), new SMAPBuilder(origin.getName(), origin.getPath(), fileMappings).build());
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ import org.jetbrains.kotlin.codegen.binding.CalculatedClosure;
|
|||||||
import org.jetbrains.kotlin.codegen.context.ClosureContext;
|
import org.jetbrains.kotlin.codegen.context.ClosureContext;
|
||||||
import org.jetbrains.kotlin.codegen.context.EnclosedValueDescriptor;
|
import org.jetbrains.kotlin.codegen.context.EnclosedValueDescriptor;
|
||||||
import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt;
|
import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt;
|
||||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil;
|
|
||||||
import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension;
|
import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension;
|
||||||
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
|
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
|
||||||
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter;
|
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter;
|
||||||
@@ -60,6 +59,7 @@ import java.util.List;
|
|||||||
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
||||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConst;
|
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConst;
|
||||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.CLOSURE;
|
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.CLOSURE;
|
||||||
|
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.initDefaultSourceMappingIfNeeded;
|
||||||
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION;
|
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION;
|
||||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
|
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
|
||||||
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
|
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
|
||||||
@@ -158,7 +158,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
|||||||
superInterfaceAsmTypes
|
superInterfaceAsmTypes
|
||||||
);
|
);
|
||||||
|
|
||||||
InlineCodegenUtil.initDefaultSourceMappingIfNeeded(context, this, state);
|
initDefaultSourceMappingIfNeeded(context, this, state);
|
||||||
|
|
||||||
v.visitSource(element.getContainingFile().getName(), null);
|
v.visitSource(element.getContainingFile().getName(), null);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isInt;
|
|||||||
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
||||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*;
|
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*;
|
||||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.*;
|
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.*;
|
||||||
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.addInlineMarker;
|
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.*;
|
||||||
import static org.jetbrains.kotlin.resolve.BindingContext.*;
|
import static org.jetbrains.kotlin.resolve.BindingContext.*;
|
||||||
import static org.jetbrains.kotlin.resolve.BindingContextUtils.getDelegationConstructorCall;
|
import static org.jetbrains.kotlin.resolve.BindingContextUtils.getDelegationConstructorCall;
|
||||||
import static org.jetbrains.kotlin.resolve.BindingContextUtils.isVarCapturedInClosure;
|
import static org.jetbrains.kotlin.resolve.BindingContextUtils.isVarCapturedInClosure;
|
||||||
@@ -1414,14 +1414,14 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
Label finallyStart = new Label();
|
Label finallyStart = new Label();
|
||||||
v.mark(finallyStart);
|
v.mark(finallyStart);
|
||||||
finallyBlockStackElement.addGapLabel(finallyStart);
|
finallyBlockStackElement.addGapLabel(finallyStart);
|
||||||
if (InlineCodegenUtil.isFinallyMarkerRequired(context)) {
|
if (isFinallyMarkerRequired(context)) {
|
||||||
InlineCodegenUtil.generateFinallyMarker(v, finallyDepth, true);
|
generateFinallyMarker(v, finallyDepth, true);
|
||||||
}
|
}
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
gen(jetTryExpression.getFinallyBlock().getFinalExpression(), Type.VOID_TYPE);
|
gen(jetTryExpression.getFinallyBlock().getFinalExpression(), Type.VOID_TYPE);
|
||||||
|
|
||||||
if (InlineCodegenUtil.isFinallyMarkerRequired(context)) {
|
if (isFinallyMarkerRequired(context)) {
|
||||||
InlineCodegenUtil.generateFinallyMarker(v, finallyDepth, false);
|
generateFinallyMarker(v, finallyDepth, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1464,7 +1464,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
generateFinallyBlocksIfNeeded(returnType, afterReturnLabel);
|
generateFinallyBlocksIfNeeded(returnType, afterReturnLabel);
|
||||||
|
|
||||||
if (isNonLocalReturn) {
|
if (isNonLocalReturn) {
|
||||||
InlineCodegenUtil.generateGlobalReturnFlag(v, nonLocalReturn.labelName);
|
generateGlobalReturnFlag(v, nonLocalReturn.labelName);
|
||||||
v.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
|
v.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1502,7 +1502,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
FunctionDescriptor containingFunction =
|
FunctionDescriptor containingFunction =
|
||||||
BindingContextUtils.getContainingFunctionSkipFunctionLiterals(descriptor, true).getFirst();
|
BindingContextUtils.getContainingFunctionSkipFunctionLiterals(descriptor, true).getFirst();
|
||||||
//FIRST_FUN_LABEL to prevent clashing with existing labels
|
//FIRST_FUN_LABEL to prevent clashing with existing labels
|
||||||
return new NonLocalReturnInfo(typeMapper.mapReturnType(containingFunction), InlineCodegenUtil.FIRST_FUN_LABEL);
|
return new NonLocalReturnInfo(typeMapper.mapReturnType(containingFunction), FIRST_FUN_LABEL);
|
||||||
} else {
|
} else {
|
||||||
//local
|
//local
|
||||||
return null;
|
return null;
|
||||||
@@ -4217,8 +4217,8 @@ The "returned" value of try expression with no finally is either the last expres
|
|||||||
public NameGenerator getInlineNameGenerator() {
|
public NameGenerator getInlineNameGenerator() {
|
||||||
NameGenerator nameGenerator = getParentCodegen().getInlineNameGenerator();
|
NameGenerator nameGenerator = getParentCodegen().getInlineNameGenerator();
|
||||||
Name name = context.getContextDescriptor().getName();
|
Name name = context.getContextDescriptor().getName();
|
||||||
String inlinedName = name.isSpecial() ? InlineCodegenUtil.SPECIAL_TRANSFORMATION_NAME : name.asString();
|
String inlinedName = name.isSpecial() ? SPECIAL_TRANSFORMATION_NAME : name.asString();
|
||||||
return nameGenerator.subGenerator(inlinedName + InlineCodegenUtil.INLINE_CALL_TRANSFORMATION_SUFFIX);
|
return nameGenerator.subGenerator(inlinedName + INLINE_CALL_TRANSFORMATION_SUFFIX);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type getReturnType() {
|
public Type getReturnType() {
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
|||||||
import org.jetbrains.kotlin.codegen.binding.MutableClosure;
|
import org.jetbrains.kotlin.codegen.binding.MutableClosure;
|
||||||
import org.jetbrains.kotlin.codegen.context.*;
|
import org.jetbrains.kotlin.codegen.context.*;
|
||||||
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension;
|
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension;
|
||||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil;
|
|
||||||
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
|
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
|
||||||
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter;
|
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter;
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||||
@@ -79,6 +78,7 @@ import static org.jetbrains.kotlin.codegen.CodegenUtilKt.isGenericToArray;
|
|||||||
import static org.jetbrains.kotlin.codegen.CodegenUtilKt.isNonGenericToArray;
|
import static org.jetbrains.kotlin.codegen.CodegenUtilKt.isNonGenericToArray;
|
||||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*;
|
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*;
|
||||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.enumEntryNeedSubclass;
|
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.enumEntryNeedSubclass;
|
||||||
|
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.initDefaultSourceMappingIfNeeded;
|
||||||
import static org.jetbrains.kotlin.resolve.BindingContextUtils.getDelegationConstructorCall;
|
import static org.jetbrains.kotlin.resolve.BindingContextUtils.getDelegationConstructorCall;
|
||||||
import static org.jetbrains.kotlin.resolve.BindingContextUtils.getNotNull;
|
import static org.jetbrains.kotlin.resolve.BindingContextUtils.getNotNull;
|
||||||
import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.descriptorToDeclaration;
|
import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.descriptorToDeclaration;
|
||||||
@@ -217,7 +217,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
v.visitSource(myClass.getContainingKtFile().getName(), null);
|
v.visitSource(myClass.getContainingKtFile().getName(), null);
|
||||||
|
|
||||||
InlineCodegenUtil.initDefaultSourceMappingIfNeeded(context, this, state);
|
initDefaultSourceMappingIfNeeded(context, this, state);
|
||||||
|
|
||||||
writeEnclosingMethod();
|
writeEnclosingMethod();
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,10 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
||||||
import org.jetbrains.kotlin.codegen.annotation.AnnotatedSimple;
|
import org.jetbrains.kotlin.codegen.annotation.AnnotatedSimple;
|
||||||
import org.jetbrains.kotlin.codegen.context.*;
|
import org.jetbrains.kotlin.codegen.context.*;
|
||||||
import org.jetbrains.kotlin.codegen.inline.*;
|
import org.jetbrains.kotlin.codegen.inline.DefaultSourceMapper;
|
||||||
|
import org.jetbrains.kotlin.codegen.inline.NameGenerator;
|
||||||
|
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeParametersUsages;
|
||||||
|
import org.jetbrains.kotlin.codegen.inline.SourceMapper;
|
||||||
import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension;
|
import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension;
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||||
@@ -71,6 +74,7 @@ import java.util.*;
|
|||||||
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
||||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvm8InterfaceWithDefaultsMember;
|
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvm8InterfaceWithDefaultsMember;
|
||||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isNonDefaultInterfaceMember;
|
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isNonDefaultInterfaceMember;
|
||||||
|
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.getInlineName;
|
||||||
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED;
|
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED;
|
||||||
import static org.jetbrains.kotlin.resolve.BindingContext.*;
|
import static org.jetbrains.kotlin.resolve.BindingContext.*;
|
||||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
||||||
@@ -437,7 +441,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
|||||||
@NotNull
|
@NotNull
|
||||||
public NameGenerator getInlineNameGenerator() {
|
public NameGenerator getInlineNameGenerator() {
|
||||||
if (inlineNameGenerator == null) {
|
if (inlineNameGenerator == null) {
|
||||||
String prefix = InlineCodegenUtil.getInlineName(context, typeMapper, fileClassesProvider);
|
String prefix = getInlineName(context, typeMapper, fileClassesProvider);
|
||||||
inlineNameGenerator = new NameGenerator(prefix);
|
inlineNameGenerator = new NameGenerator(prefix);
|
||||||
}
|
}
|
||||||
return inlineNameGenerator;
|
return inlineNameGenerator;
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.codegen;
|
|||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil;
|
|
||||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes;
|
import org.jetbrains.org.objectweb.asm.Opcodes;
|
||||||
import org.jetbrains.org.objectweb.asm.tree.LocalVariableNode;
|
import org.jetbrains.org.objectweb.asm.tree.LocalVariableNode;
|
||||||
@@ -29,6 +28,9 @@ import org.jetbrains.org.objectweb.asm.util.TraceMethodVisitor;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.getNodeText;
|
||||||
|
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.wrapWithMaxLocalCalc;
|
||||||
|
|
||||||
public abstract class TransformationMethodVisitor extends MethodVisitor {
|
public abstract class TransformationMethodVisitor extends MethodVisitor {
|
||||||
|
|
||||||
private final MethodNode methodNode;
|
private final MethodNode methodNode;
|
||||||
@@ -46,7 +48,7 @@ public abstract class TransformationMethodVisitor extends MethodVisitor {
|
|||||||
this.delegate = delegate;
|
this.delegate = delegate;
|
||||||
this.methodNode = new MethodNode(access, name, desc, signature, exceptions);
|
this.methodNode = new MethodNode(access, name, desc, signature, exceptions);
|
||||||
this.methodNode.localVariables = new ArrayList<>(5);
|
this.methodNode.localVariables = new ArrayList<>(5);
|
||||||
this.mv = InlineCodegenUtil.wrapWithMaxLocalCalc(methodNode);
|
this.mv = wrapWithMaxLocalCalc(methodNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -83,7 +85,7 @@ public abstract class TransformationMethodVisitor extends MethodVisitor {
|
|||||||
delegate.visitEnd();
|
delegate.visitEnd();
|
||||||
}
|
}
|
||||||
catch (Throwable t) {
|
catch (Throwable t) {
|
||||||
throw new CompilationException("Couldn't transform method node: " + InlineCodegenUtil.getNodeText(methodNode), t, null);
|
throw new CompilationException("Couldn't transform method node: " + getNodeText(methodNode), t, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -21,8 +21,8 @@ import org.jetbrains.kotlin.codegen.AsmUtil
|
|||||||
import org.jetbrains.kotlin.codegen.ClassBuilder
|
import org.jetbrains.kotlin.codegen.ClassBuilder
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
import org.jetbrains.kotlin.codegen.StackValue
|
||||||
import org.jetbrains.kotlin.codegen.TransformationMethodVisitor
|
import org.jetbrains.kotlin.codegen.TransformationMethodVisitor
|
||||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil
|
|
||||||
import org.jetbrains.kotlin.codegen.inline.MaxStackFrameSizeAndLocalsCalculator
|
import org.jetbrains.kotlin.codegen.inline.MaxStackFrameSizeAndLocalsCalculator
|
||||||
|
import org.jetbrains.kotlin.codegen.inline.isInlineMarker
|
||||||
import org.jetbrains.kotlin.codegen.optimization.DeadCodeEliminationMethodTransformer
|
import org.jetbrains.kotlin.codegen.optimization.DeadCodeEliminationMethodTransformer
|
||||||
import org.jetbrains.kotlin.codegen.optimization.common.*
|
import org.jetbrains.kotlin.codegen.optimization.common.*
|
||||||
import org.jetbrains.kotlin.codegen.optimization.fixStack.FixStackMethodTransformer
|
import org.jetbrains.kotlin.codegen.optimization.fixStack.FixStackMethodTransformer
|
||||||
@@ -681,7 +681,7 @@ private fun findSafelyReachableReturns(methodNode: MethodNode): Array<Set<Int>?>
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!insn.isMeaningful || insn.opcode in SAFE_OPCODES || insn.isInvisibleInDebugVarInsn(methodNode) ||
|
if (!insn.isMeaningful || insn.opcode in SAFE_OPCODES || insn.isInvisibleInDebugVarInsn(methodNode) ||
|
||||||
InlineCodegenUtil.isInlineMarker(insn)) {
|
isInlineMarker(insn)) {
|
||||||
setOf()
|
setOf()
|
||||||
}
|
}
|
||||||
else null
|
else null
|
||||||
|
|||||||
+10
-11
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.codegen.AsmUtil
|
|||||||
import org.jetbrains.kotlin.codegen.ClassBuilder
|
import org.jetbrains.kotlin.codegen.ClassBuilder
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
import org.jetbrains.kotlin.codegen.StackValue
|
||||||
import org.jetbrains.kotlin.codegen.coroutines.COROUTINE_IMPL_ASM_TYPE
|
import org.jetbrains.kotlin.codegen.coroutines.COROUTINE_IMPL_ASM_TYPE
|
||||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.isThis0
|
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.Companion.NO_ORIGIN
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.Companion.NO_ORIGIN
|
||||||
import org.jetbrains.org.objectweb.asm.*
|
import org.jetbrains.org.objectweb.asm.*
|
||||||
@@ -49,7 +48,7 @@ class AnonymousObjectTransformer(
|
|||||||
val classBuilder = createRemappingClassBuilderViaFactory(inliningContext)
|
val classBuilder = createRemappingClassBuilderViaFactory(inliningContext)
|
||||||
val methodsToTransform = ArrayList<MethodNode>()
|
val methodsToTransform = ArrayList<MethodNode>()
|
||||||
|
|
||||||
createClassReader().accept(object : ClassVisitor(InlineCodegenUtil.API, classBuilder.visitor) {
|
createClassReader().accept(object : ClassVisitor(API, classBuilder.visitor) {
|
||||||
override fun visit(version: Int, access: Int, name: String, signature: String?, superName: String, interfaces: Array<String>) {
|
override fun visit(version: Int, access: Int, name: String, signature: String?, superName: String, interfaces: Array<String>) {
|
||||||
classBuilder.defineClass(null, version, access, name, signature, superName, interfaces)
|
classBuilder.defineClass(null, version, access, name, signature, superName, interfaces)
|
||||||
if (COROUTINE_IMPL_ASM_TYPE.internalName == superName) {
|
if (COROUTINE_IMPL_ASM_TYPE.internalName == superName) {
|
||||||
@@ -79,7 +78,7 @@ class AnonymousObjectTransformer(
|
|||||||
|
|
||||||
override fun visitField(access: Int, name: String, desc: String, signature: String?, value: Any?): FieldVisitor? {
|
override fun visitField(access: Int, name: String, desc: String, signature: String?, value: Any?): FieldVisitor? {
|
||||||
addUniqueField(name)
|
addUniqueField(name)
|
||||||
if (InlineCodegenUtil.isCapturedFieldName(name)) {
|
if (isCapturedFieldName(name)) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -103,7 +102,7 @@ class AnonymousObjectTransformer(
|
|||||||
//seems we can't do any clever mapping cause we don't know any about original class name
|
//seems we can't do any clever mapping cause we don't know any about original class name
|
||||||
sourceMapper = IdenticalSourceMapper
|
sourceMapper = IdenticalSourceMapper
|
||||||
}
|
}
|
||||||
if (sourceInfo != null && !InlineCodegenUtil.GENERATE_SMAP) {
|
if (sourceInfo != null && !GENERATE_SMAP) {
|
||||||
classBuilder.visitSource(sourceInfo!!, debugInfo)
|
classBuilder.visitSource(sourceInfo!!, debugInfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -139,7 +138,7 @@ class AnonymousObjectTransformer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
deferringMethods.forEach { method ->
|
deferringMethods.forEach { method ->
|
||||||
InlineCodegenUtil.removeFinallyMarkers(method.intermediate)
|
removeFinallyMarkers(method.intermediate)
|
||||||
method.visitEnd()
|
method.visitEnd()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,7 +285,7 @@ class AnonymousObjectTransformer(
|
|||||||
|
|
||||||
val intermediateMethodNode = MethodNode(constructor!!.access, "<init>", constructorDescriptor, null, ArrayUtil.EMPTY_STRING_ARRAY)
|
val intermediateMethodNode = MethodNode(constructor!!.access, "<init>", constructorDescriptor, null, ArrayUtil.EMPTY_STRING_ARRAY)
|
||||||
inlineMethodAndUpdateGlobalResult(parentRemapper, intermediateMethodNode, constructor!!, constructorInlineBuilder, true)
|
inlineMethodAndUpdateGlobalResult(parentRemapper, intermediateMethodNode, constructor!!, constructorInlineBuilder, true)
|
||||||
InlineCodegenUtil.removeFinallyMarkers(intermediateMethodNode)
|
removeFinallyMarkers(intermediateMethodNode)
|
||||||
|
|
||||||
val first = intermediateMethodNode.instructions.first
|
val first = intermediateMethodNode.instructions.first
|
||||||
val oldStartLabel = if (first is LabelNode) first.label else null
|
val oldStartLabel = if (first is LabelNode) first.label else null
|
||||||
@@ -429,8 +428,8 @@ class AnonymousObjectTransformer(
|
|||||||
val parent = parentFieldRemapper.parent as? RegeneratedLambdaFieldRemapper ?:
|
val parent = parentFieldRemapper.parent as? RegeneratedLambdaFieldRemapper ?:
|
||||||
throw AssertionError("Expecting RegeneratedLambdaFieldRemapper, but ${parentFieldRemapper.parent}")
|
throw AssertionError("Expecting RegeneratedLambdaFieldRemapper, but ${parentFieldRemapper.parent}")
|
||||||
val ownerType = Type.getObjectType(parent.originalLambdaInternalName)
|
val ownerType = Type.getObjectType(parent.originalLambdaInternalName)
|
||||||
val desc = CapturedParamDesc(ownerType, InlineCodegenUtil.THIS, ownerType)
|
val desc = CapturedParamDesc(ownerType, THIS, ownerType)
|
||||||
val recapturedParamInfo = capturedParamBuilder.addCapturedParam(desc, InlineCodegenUtil.`THIS$0`/*outer lambda/object*/, false)
|
val recapturedParamInfo = capturedParamBuilder.addCapturedParam(desc, THIS_0/*outer lambda/object*/, false)
|
||||||
val composed = StackValue.LOCAL_0
|
val composed = StackValue.LOCAL_0
|
||||||
recapturedParamInfo.remapValue = composed
|
recapturedParamInfo.remapValue = composed
|
||||||
allRecapturedParameters.add(desc)
|
allRecapturedParameters.add(desc)
|
||||||
@@ -458,16 +457,16 @@ class AnonymousObjectTransformer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getNewFieldName(oldName: String, originalField: Boolean): String {
|
private fun getNewFieldName(oldName: String, originalField: Boolean): String {
|
||||||
if (InlineCodegenUtil.`THIS$0` == oldName) {
|
if (THIS_0 == oldName) {
|
||||||
if (!originalField) {
|
if (!originalField) {
|
||||||
return oldName
|
return oldName
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//rename original 'this$0' in declaration site lambda (inside inline function) to use this$0 only for outer lambda/object access on call site
|
//rename original 'this$0' in declaration site lambda (inside inline function) to use this$0 only for outer lambda/object access on call site
|
||||||
return addUniqueField(oldName + InlineCodegenUtil.INLINE_FUN_THIS_0_SUFFIX)
|
return addUniqueField(oldName + INLINE_FUN_THIS_0_SUFFIX)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return addUniqueField(oldName + InlineCodegenUtil.INLINE_TRANSFORMATION_SUFFIX)
|
return addUniqueField(oldName + INLINE_TRANSFORMATION_SUFFIX)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addUniqueField(name: String): String {
|
private fun addUniqueField(name: String): String {
|
||||||
|
|||||||
+1
-1
@@ -38,7 +38,7 @@ abstract class CoveringTryCatchNodeProcessor(parameterSize: Int) {
|
|||||||
|
|
||||||
open fun processInstruction(curInstr: AbstractInsnNode, directOrder: Boolean) {
|
open fun processInstruction(curInstr: AbstractInsnNode, directOrder: Boolean) {
|
||||||
if (curInstr is VarInsnNode || curInstr is IincInsnNode) {
|
if (curInstr is VarInsnNode || curInstr is IincInsnNode) {
|
||||||
val argSize = InlineCodegenUtil.getLoadStoreArgSize(curInstr.opcode)
|
val argSize = getLoadStoreArgSize(curInstr.opcode)
|
||||||
val varIndex = if (curInstr is VarInsnNode) curInstr.`var` else (curInstr as IincInsnNode).`var`
|
val varIndex = if (curInstr is VarInsnNode) curInstr.`var` else (curInstr as IincInsnNode).`var`
|
||||||
nextFreeLocalIndex = Math.max(nextFreeLocalIndex, varIndex + argSize)
|
nextFreeLocalIndex = Math.max(nextFreeLocalIndex, varIndex + argSize)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
|||||||
class DeferredMethodVisitor(
|
class DeferredMethodVisitor(
|
||||||
val intermediate: MethodNode,
|
val intermediate: MethodNode,
|
||||||
val resultNode: () -> MethodVisitor
|
val resultNode: () -> MethodVisitor
|
||||||
) : MethodVisitor(InlineCodegenUtil.API, intermediate) {
|
) : MethodVisitor(API, intermediate) {
|
||||||
|
|
||||||
override fun visitEnd() {
|
override fun visitEnd() {
|
||||||
super.visitEnd()
|
super.visitEnd()
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ open class FieldRemapper(
|
|||||||
protected open fun canProcess(fieldOwner: String, fieldName: String, isFolding: Boolean): Boolean {
|
protected open fun canProcess(fieldOwner: String, fieldName: String, isFolding: Boolean): Boolean {
|
||||||
return fieldOwner == originalLambdaInternalName &&
|
return fieldOwner == originalLambdaInternalName &&
|
||||||
//don't process general field of anonymous objects
|
//don't process general field of anonymous objects
|
||||||
InlineCodegenUtil.isCapturedFieldName(fieldName)
|
isCapturedFieldName(fieldName)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun foldFieldAccessChainIfNeeded(capturedFieldAccess: List<AbstractInsnNode>, node: MethodNode): AbstractInsnNode? =
|
fun foldFieldAccessChainIfNeeded(capturedFieldAccess: List<AbstractInsnNode>, node: MethodNode): AbstractInsnNode? =
|
||||||
@@ -68,7 +68,7 @@ open class FieldRemapper(
|
|||||||
|
|
||||||
val insnNode = capturedFieldAccess[currentInstruction] as FieldInsnNode
|
val insnNode = capturedFieldAccess[currentInstruction] as FieldInsnNode
|
||||||
if (canProcess(insnNode.owner, insnNode.name, true)) {
|
if (canProcess(insnNode.owner, insnNode.name, true)) {
|
||||||
insnNode.name = InlineCodegenUtil.CAPTURED_FIELD_FOLD_PREFIX + getFieldNameForFolding(insnNode)
|
insnNode.name = CAPTURED_FIELD_FOLD_PREFIX + getFieldNameForFolding(insnNode)
|
||||||
insnNode.opcode = Opcodes.GETSTATIC
|
insnNode.opcode = Opcodes.GETSTATIC
|
||||||
|
|
||||||
node.remove(InsnSequence(capturedFieldAccess[0], insnNode))
|
node.remove(InsnSequence(capturedFieldAccess[0], insnNode))
|
||||||
|
|||||||
@@ -25,7 +25,9 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.getLoadStoreArgSize;
|
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.API;
|
||||||
|
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.GENERATE_SMAP;
|
||||||
|
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.getLoadStoreArgSize;
|
||||||
|
|
||||||
public class InlineAdapter extends InstructionAdapter {
|
public class InlineAdapter extends InstructionAdapter {
|
||||||
private final SourceMapper sourceMapper;
|
private final SourceMapper sourceMapper;
|
||||||
@@ -36,7 +38,7 @@ public class InlineAdapter extends InstructionAdapter {
|
|||||||
private int nextLocalIndexBeforeInline = -1;
|
private int nextLocalIndexBeforeInline = -1;
|
||||||
|
|
||||||
public InlineAdapter(@NotNull MethodVisitor mv, int localsSize, @NotNull SourceMapper sourceMapper) {
|
public InlineAdapter(@NotNull MethodVisitor mv, int localsSize, @NotNull SourceMapper sourceMapper) {
|
||||||
super(InlineCodegenUtil.API, mv);
|
super(API, mv);
|
||||||
this.nextLocalIndex = localsSize;
|
this.nextLocalIndex = localsSize;
|
||||||
this.sourceMapper = sourceMapper;
|
this.sourceMapper = sourceMapper;
|
||||||
}
|
}
|
||||||
@@ -86,7 +88,7 @@ public class InlineAdapter extends InstructionAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitLineNumber(int line, @NotNull Label start) {
|
public void visitLineNumber(int line, @NotNull Label start) {
|
||||||
if (InlineCodegenUtil.GENERATE_SMAP) {
|
if (GENERATE_SMAP) {
|
||||||
line = sourceMapper.mapLineNumber(line);
|
line = sourceMapper.mapLineNumber(line);
|
||||||
}
|
}
|
||||||
//skip not mapped lines
|
//skip not mapped lines
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive
|
|||||||
import org.jetbrains.kotlin.codegen.context.*
|
import org.jetbrains.kotlin.codegen.context.*
|
||||||
import org.jetbrains.kotlin.codegen.coroutines.createMethodNodeForSuspendCoroutineOrReturn
|
import org.jetbrains.kotlin.codegen.coroutines.createMethodNodeForSuspendCoroutineOrReturn
|
||||||
import org.jetbrains.kotlin.codegen.coroutines.isBuiltInSuspendCoroutineOrReturnInJvm
|
import org.jetbrains.kotlin.codegen.coroutines.isBuiltInSuspendCoroutineOrReturnInJvm
|
||||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.*
|
|
||||||
import org.jetbrains.kotlin.codegen.intrinsics.bytecode
|
import org.jetbrains.kotlin.codegen.intrinsics.bytecode
|
||||||
import org.jetbrains.kotlin.codegen.intrinsics.classId
|
import org.jetbrains.kotlin.codegen.intrinsics.classId
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
@@ -168,7 +167,7 @@ class InlineCodegen(
|
|||||||
"Couldn't inline method call '" + functionDescriptor.name + "' into\n" +
|
"Couldn't inline method call '" + functionDescriptor.name + "' into\n" +
|
||||||
DescriptorRenderer.DEBUG_TEXT.render(contextDescriptor) + "\n" +
|
DescriptorRenderer.DEBUG_TEXT.render(contextDescriptor) + "\n" +
|
||||||
(element?.text ?: "<no source>") +
|
(element?.text ?: "<no source>") +
|
||||||
if (generateNodeText) "\nCause: " + InlineCodegenUtil.getNodeText(node) else "",
|
if (generateNodeText) "\nCause: " + getNodeText(node) else "",
|
||||||
e, callElement
|
e, callElement
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -230,7 +229,7 @@ class InlineCodegen(
|
|||||||
|
|
||||||
val remapper = LocalVarRemapper(parameters, initialFrameSize)
|
val remapper = LocalVarRemapper(parameters, initialFrameSize)
|
||||||
|
|
||||||
val adapter = InlineCodegenUtil.createEmptyMethodNode()
|
val adapter = createEmptyMethodNode()
|
||||||
//hack to keep linenumber info, otherwise jdi will skip begin of linenumber chain
|
//hack to keep linenumber info, otherwise jdi will skip begin of linenumber chain
|
||||||
adapter.visitInsn(Opcodes.NOP)
|
adapter.visitInsn(Opcodes.NOP)
|
||||||
|
|
||||||
@@ -245,8 +244,8 @@ class InlineCodegen(
|
|||||||
adapter, infos, (remapper.remap(parameters.argsSizeOnStack + 1).value as StackValue.Local).index
|
adapter, infos, (remapper.remap(parameters.argsSizeOnStack + 1).value as StackValue.Local).index
|
||||||
)
|
)
|
||||||
removeStaticInitializationTrigger(adapter)
|
removeStaticInitializationTrigger(adapter)
|
||||||
if (!InlineCodegenUtil.isFinallyMarkerRequired(codegen.getContext())) {
|
if (!isFinallyMarkerRequired(codegen.getContext())) {
|
||||||
InlineCodegenUtil.removeFinallyMarkers(adapter)
|
removeFinallyMarkers(adapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
adapter.accept(MethodBodyVisitor(codegen.v))
|
adapter.accept(MethodBodyVisitor(codegen.v))
|
||||||
@@ -539,7 +538,7 @@ class InlineCodegen(
|
|||||||
var curInstr: AbstractInsnNode? = intoNode.instructions.first
|
var curInstr: AbstractInsnNode? = intoNode.instructions.first
|
||||||
while (curInstr != null) {
|
while (curInstr != null) {
|
||||||
processor.processInstruction(curInstr, true)
|
processor.processInstruction(curInstr, true)
|
||||||
if (InlineCodegenUtil.isFinallyStart(curInstr)) {
|
if (isFinallyStart(curInstr)) {
|
||||||
//TODO depth index calc could be more precise
|
//TODO depth index calc could be more precise
|
||||||
curFinallyDepth = getConstant(curInstr.previous)
|
curFinallyDepth = getConstant(curInstr.previous)
|
||||||
}
|
}
|
||||||
@@ -548,7 +547,7 @@ class InlineCodegen(
|
|||||||
if (extension != null) {
|
if (extension != null) {
|
||||||
val start = Label()
|
val start = Label()
|
||||||
|
|
||||||
val finallyNode = InlineCodegenUtil.createEmptyMethodNode()
|
val finallyNode = createEmptyMethodNode()
|
||||||
finallyNode.visitLabel(start)
|
finallyNode.visitLabel(start)
|
||||||
|
|
||||||
val finallyCodegen = ExpressionCodegen(finallyNode, codegen.frameMap, codegen.returnType,
|
val finallyCodegen = ExpressionCodegen(finallyNode, codegen.frameMap, codegen.returnType,
|
||||||
@@ -569,7 +568,7 @@ class InlineCodegen(
|
|||||||
finallyCodegen.generateFinallyBlocksIfNeeded(extension.returnType, extension.finallyIntervalEnd.label)
|
finallyCodegen.generateFinallyBlocksIfNeeded(extension.returnType, extension.finallyIntervalEnd.label)
|
||||||
|
|
||||||
//Exception table for external try/catch/finally blocks will be generated in original codegen after exiting this method
|
//Exception table for external try/catch/finally blocks will be generated in original codegen after exiting this method
|
||||||
InlineCodegenUtil.insertNodeBefore(finallyNode, intoNode, curInstr)
|
insertNodeBefore(finallyNode, intoNode, curInstr)
|
||||||
|
|
||||||
val splitBy = SimpleInterval(start.info as LabelNode, extension.finallyIntervalEnd)
|
val splitBy = SimpleInterval(start.info as LabelNode, extension.finallyIntervalEnd)
|
||||||
processor.tryBlocksMetaInfo.splitCurrentIntervals(splitBy, true)
|
processor.tryBlocksMetaInfo.splitCurrentIntervals(splitBy, true)
|
||||||
@@ -620,12 +619,12 @@ class InlineCodegen(
|
|||||||
callDefault: Boolean,
|
callDefault: Boolean,
|
||||||
resolvedCall: ResolvedCall<*>?
|
resolvedCall: ResolvedCall<*>?
|
||||||
): SMAPAndMethodNode {
|
): SMAPAndMethodNode {
|
||||||
if (InlineCodegenUtil.isSpecialEnumMethod(functionDescriptor)) {
|
if (isSpecialEnumMethod(functionDescriptor)) {
|
||||||
assert(resolvedCall != null) { "Resolved call for $functionDescriptor should be not null" }
|
assert(resolvedCall != null) { "Resolved call for $functionDescriptor should be not null" }
|
||||||
val arguments = resolvedCall!!.typeArguments
|
val arguments = resolvedCall!!.typeArguments
|
||||||
assert(arguments.size == 1) { "Resolved call for $functionDescriptor should have 1 type argument" }
|
assert(arguments.size == 1) { "Resolved call for $functionDescriptor should have 1 type argument" }
|
||||||
|
|
||||||
val node = InlineCodegenUtil.createSpecialEnumMethodBody(
|
val node = createSpecialEnumMethodBody(
|
||||||
codegen,
|
codegen,
|
||||||
functionDescriptor.name.asString(),
|
functionDescriptor.name.asString(),
|
||||||
arguments.keys.iterator().next().defaultType,
|
arguments.keys.iterator().next().defaultType,
|
||||||
@@ -689,7 +688,7 @@ class InlineCodegen(
|
|||||||
if (isBuiltInArrayIntrinsic(callableDescriptor)) {
|
if (isBuiltInArrayIntrinsic(callableDescriptor)) {
|
||||||
val classId = classId
|
val classId = classId
|
||||||
val bytes = state.inlineCache.classBytes.getOrPut(classId) { bytecode }
|
val bytes = state.inlineCache.classBytes.getOrPut(classId) { bytecode }
|
||||||
return InlineCodegenUtil.getMethodNode(bytes, asmMethod.name, asmMethod.descriptor, classId.asString())
|
return getMethodNode(bytes, asmMethod.name, asmMethod.descriptor, classId.asString())
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(callableDescriptor is DeserializedCallableMemberDescriptor) { "Not a deserialized function or proper: " + callableDescriptor }
|
assert(callableDescriptor is DeserializedCallableMemberDescriptor) { "Not a deserialized function or proper: " + callableDescriptor }
|
||||||
@@ -699,7 +698,7 @@ class InlineCodegen(
|
|||||||
val containerId = containingClasses.implClassId
|
val containerId = containingClasses.implClassId
|
||||||
|
|
||||||
val bytes = state.inlineCache.classBytes.getOrPut(containerId) {
|
val bytes = state.inlineCache.classBytes.getOrPut(containerId) {
|
||||||
val file = InlineCodegenUtil.findVirtualFile(state, containerId) ?: throw IllegalStateException("Couldn't find declaration file for " + containerId)
|
val file = findVirtualFile(state, containerId) ?: throw IllegalStateException("Couldn't find declaration file for " + containerId)
|
||||||
try {
|
try {
|
||||||
file.contentsToByteArray()
|
file.contentsToByteArray()
|
||||||
}
|
}
|
||||||
@@ -708,7 +707,7 @@ class InlineCodegen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return InlineCodegenUtil.getMethodNode(bytes, asmMethod.name, asmMethod.descriptor, containerId.asString())
|
return getMethodNode(bytes, asmMethod.name, asmMethod.descriptor, containerId.asString())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun doCreateMethodNodeFromSource(
|
private fun doCreateMethodNodeFromSource(
|
||||||
@@ -728,14 +727,14 @@ class InlineCodegen(
|
|||||||
val inliningFunction = element as KtDeclarationWithBody?
|
val inliningFunction = element as KtDeclarationWithBody?
|
||||||
|
|
||||||
val node = MethodNode(
|
val node = MethodNode(
|
||||||
InlineCodegenUtil.API,
|
API,
|
||||||
getMethodAsmFlags(callableDescriptor, context.contextKind, state) or if (callDefault) Opcodes.ACC_STATIC else 0,
|
getMethodAsmFlags(callableDescriptor, context.contextKind, state) or if (callDefault) Opcodes.ACC_STATIC else 0,
|
||||||
asmMethod.name,
|
asmMethod.name,
|
||||||
asmMethod.descriptor, null, null
|
asmMethod.descriptor, null, null
|
||||||
)
|
)
|
||||||
|
|
||||||
//for maxLocals calculation
|
//for maxLocals calculation
|
||||||
val maxCalcAdapter = InlineCodegenUtil.wrapWithMaxLocalCalc(node)
|
val maxCalcAdapter = wrapWithMaxLocalCalc(node)
|
||||||
val parentContext = context.parentContext ?: error("Context has no parent: " + context)
|
val parentContext = context.parentContext ?: error("Context has no parent: " + context)
|
||||||
val methodContext = parentContext.intoFunction(callableDescriptor)
|
val methodContext = parentContext.intoFunction(callableDescriptor)
|
||||||
|
|
||||||
@@ -919,7 +918,7 @@ class InlineCodegen(
|
|||||||
if (!descriptor.name.isSpecial) {
|
if (!descriptor.name.isSpecial) {
|
||||||
result.add(descriptor.name.asString())
|
result.add(descriptor.name.asString())
|
||||||
}
|
}
|
||||||
result.add(InlineCodegenUtil.FIRST_FUN_LABEL)
|
result.add(FIRST_FUN_LABEL)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
+8
-9
@@ -22,7 +22,6 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.annotations.ReadOnly;
|
import org.jetbrains.annotations.ReadOnly;
|
||||||
import org.jetbrains.annotations.TestOnly;
|
import org.jetbrains.annotations.TestOnly;
|
||||||
import org.jetbrains.kotlin.codegen.optimization.common.UtilKt;
|
|
||||||
import org.jetbrains.org.objectweb.asm.Label;
|
import org.jetbrains.org.objectweb.asm.Label;
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes;
|
import org.jetbrains.org.objectweb.asm.Opcodes;
|
||||||
import org.jetbrains.org.objectweb.asm.Type;
|
import org.jetbrains.org.objectweb.asm.Type;
|
||||||
@@ -34,7 +33,7 @@ import java.io.PrintWriter;
|
|||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.*;
|
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.*;
|
||||||
import static org.jetbrains.kotlin.codegen.inline.MethodInlinerUtilKt.getNextMeaningful;
|
import static org.jetbrains.kotlin.codegen.inline.MethodInlinerUtilKt.getNextMeaningful;
|
||||||
|
|
||||||
public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
|
public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
|
||||||
@@ -106,7 +105,7 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
|
|||||||
|
|
||||||
private int initAndGetVarIndexForNonLocalReturnValue() {
|
private int initAndGetVarIndexForNonLocalReturnValue() {
|
||||||
MaxLocalsCalculator tempCalcNode = new MaxLocalsCalculator(
|
MaxLocalsCalculator tempCalcNode = new MaxLocalsCalculator(
|
||||||
InlineCodegenUtil.API,
|
API,
|
||||||
inlineFun.access, inlineFun.desc, null
|
inlineFun.access, inlineFun.desc, null
|
||||||
);
|
);
|
||||||
inlineFun.accept(tempCalcNode);
|
inlineFun.accept(tempCalcNode);
|
||||||
@@ -126,8 +125,8 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
|
|||||||
processInstruction(curIns, false);
|
processInstruction(curIns, false);
|
||||||
|
|
||||||
//At this point only global return is possible, local one already substituted with: goto endLabel
|
//At this point only global return is possible, local one already substituted with: goto endLabel
|
||||||
if (!InlineCodegenUtil.isReturnOpcode(curIns.getOpcode()) ||
|
if (!isReturnOpcode(curIns.getOpcode()) ||
|
||||||
!InlineCodegenUtil.isMarkedReturn(curIns)) {
|
!isMarkedReturn(curIns)) {
|
||||||
curIns = curIns.getPrevious();
|
curIns = curIns.getPrevious();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -147,7 +146,7 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
|
|||||||
AbstractInsnNode nextPrev = instrInsertFinallyBefore.getPrevious();
|
AbstractInsnNode nextPrev = instrInsertFinallyBefore.getPrevious();
|
||||||
assert markedReturn.getNext() instanceof LabelNode : "Label should be occurred after non-local return";
|
assert markedReturn.getNext() instanceof LabelNode : "Label should be occurred after non-local return";
|
||||||
LabelNode newFinallyEnd = (LabelNode) markedReturn.getNext();
|
LabelNode newFinallyEnd = (LabelNode) markedReturn.getNext();
|
||||||
Type nonLocalReturnType = InlineCodegenUtil.getReturnType(markedReturn.getOpcode());
|
Type nonLocalReturnType = getReturnType(markedReturn.getOpcode());
|
||||||
|
|
||||||
//Generally there could be several tryCatch blocks (group) on one code interval (same start and end labels, but maybe different handlers) -
|
//Generally there could be several tryCatch blocks (group) on one code interval (same start and end labels, but maybe different handlers) -
|
||||||
// all of them refer to one try/*catches*/finally or try/catches.
|
// all of them refer to one try/*catches*/finally or try/catches.
|
||||||
@@ -216,7 +215,7 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
|
|||||||
finallyBlockCopy.visitLabel(insertedBlockEnd);
|
finallyBlockCopy.visitLabel(insertedBlockEnd);
|
||||||
|
|
||||||
//Copying finally body before non-local return instruction
|
//Copying finally body before non-local return instruction
|
||||||
InlineCodegenUtil.insertNodeBefore(finallyBlockCopy, inlineFun, instrInsertFinallyBefore);
|
insertNodeBefore(finallyBlockCopy, inlineFun, instrInsertFinallyBefore);
|
||||||
|
|
||||||
updateExceptionTable(clusterBlocks, newFinallyStart, newFinallyEnd,
|
updateExceptionTable(clusterBlocks, newFinallyStart, newFinallyEnd,
|
||||||
tryCatchBlockInlinedInFinally, labelsInsideFinally, (LabelNode) insertedBlockEnd.info);
|
tryCatchBlockInlinedInFinally, labelsInsideFinally, (LabelNode) insertedBlockEnd.info);
|
||||||
@@ -251,7 +250,7 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
|
|||||||
int depthShift
|
int depthShift
|
||||||
) {
|
) {
|
||||||
if (isInsOrJumpInsideFinally) {
|
if (isInsOrJumpInsideFinally) {
|
||||||
if (InlineCodegenUtil.isFinallyMarker(currentIns.getNext())) {
|
if (isFinallyMarker(currentIns.getNext())) {
|
||||||
Integer constant = getConstant(currentIns);
|
Integer constant = getConstant(currentIns);
|
||||||
finallyBlockCopy.visitLdcInsn(constant + depthShift);
|
finallyBlockCopy.visitLdcInsn(constant + depthShift);
|
||||||
} else {
|
} else {
|
||||||
@@ -455,7 +454,7 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
|
|||||||
AbstractInsnNode current = meaningful.getNext();
|
AbstractInsnNode current = meaningful.getNext();
|
||||||
while (endFinallyChainExclusive != current) {
|
while (endFinallyChainExclusive != current) {
|
||||||
current = current.getNext();
|
current = current.getNext();
|
||||||
if (InlineCodegenUtil.isFinallyEnd(current)) {
|
if (isFinallyEnd(current)) {
|
||||||
Integer currentDepth = getConstant(current.getPrevious());
|
Integer currentDepth = getConstant(current.getPrevious());
|
||||||
if (currentDepth.equals(finallyDepth)) {
|
if (currentDepth.equals(finallyDepth)) {
|
||||||
endFinallyChainExclusive = current.getNext();
|
endFinallyChainExclusive = current.getNext();
|
||||||
|
|||||||
@@ -106,10 +106,10 @@ class DefaultLambda(
|
|||||||
override fun isMyLabel(name: String): Boolean = false
|
override fun isMyLabel(name: String): Boolean = false
|
||||||
|
|
||||||
override fun generateLambdaBody(codegen: ExpressionCodegen, reifiedTypeInliner: ReifiedTypeInliner) {
|
override fun generateLambdaBody(codegen: ExpressionCodegen, reifiedTypeInliner: ReifiedTypeInliner) {
|
||||||
val classReader = InlineCodegenUtil.buildClassReaderByInternalName(codegen.state, lambdaClassType.internalName)
|
val classReader = buildClassReaderByInternalName(codegen.state, lambdaClassType.internalName)
|
||||||
var isPropertyReference = false
|
var isPropertyReference = false
|
||||||
var isFunctionReference = false
|
var isFunctionReference = false
|
||||||
classReader.accept(object: ClassVisitor(InlineCodegenUtil.API){
|
classReader.accept(object: ClassVisitor(API){
|
||||||
override fun visit(version: Int, access: Int, name: String, signature: String?, superName: String?, interfaces: Array<out String>?) {
|
override fun visit(version: Int, access: Int, name: String, signature: String?, superName: String?, interfaces: Array<out String>?) {
|
||||||
isPropertyReference = superName?.startsWith("kotlin/jvm/internal/PropertyReference") ?: false
|
isPropertyReference = superName?.startsWith("kotlin/jvm/internal/PropertyReference") ?: false
|
||||||
isFunctionReference = "kotlin/jvm/internal/FunctionReference" == superName
|
isFunctionReference = "kotlin/jvm/internal/FunctionReference" == superName
|
||||||
@@ -128,7 +128,7 @@ class DefaultLambda(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val descriptor = Type.getMethodDescriptor(Type.VOID_TYPE, *capturedArgs)
|
val descriptor = Type.getMethodDescriptor(Type.VOID_TYPE, *capturedArgs)
|
||||||
val constructor = InlineCodegenUtil.getMethodNode(
|
val constructor = getMethodNode(
|
||||||
classReader.b,
|
classReader.b,
|
||||||
"<init>",
|
"<init>",
|
||||||
descriptor,
|
descriptor,
|
||||||
@@ -156,7 +156,7 @@ class DefaultLambda(
|
|||||||
codegen.state.typeMapper.mapSignatureSkipGeneric(invokeMethodDescriptor).asmMethod.descriptor
|
codegen.state.typeMapper.mapSignatureSkipGeneric(invokeMethodDescriptor).asmMethod.descriptor
|
||||||
)
|
)
|
||||||
|
|
||||||
node = InlineCodegenUtil.getMethodNode(
|
node = getMethodNode(
|
||||||
classReader.b,
|
classReader.b,
|
||||||
invokeMethod.name,
|
invokeMethod.name,
|
||||||
invokeMethod.descriptor,
|
invokeMethod.descriptor,
|
||||||
@@ -271,11 +271,11 @@ class ExpressionLambda(
|
|||||||
val jvmMethodSignature = typeMapper.mapSignatureSkipGeneric(invokeMethodDescriptor)
|
val jvmMethodSignature = typeMapper.mapSignatureSkipGeneric(invokeMethodDescriptor)
|
||||||
val asmMethod = jvmMethodSignature.asmMethod
|
val asmMethod = jvmMethodSignature.asmMethod
|
||||||
val methodNode = MethodNode(
|
val methodNode = MethodNode(
|
||||||
InlineCodegenUtil.API, AsmUtil.getMethodAsmFlags(invokeMethodDescriptor, context.contextKind, codegen.state),
|
API, AsmUtil.getMethodAsmFlags(invokeMethodDescriptor, context.contextKind, codegen.state),
|
||||||
asmMethod.name, asmMethod.descriptor, null, null
|
asmMethod.name, asmMethod.descriptor, null, null
|
||||||
)
|
)
|
||||||
|
|
||||||
node = InlineCodegenUtil.wrapWithMaxLocalCalc(methodNode).let { adapter ->
|
node = wrapWithMaxLocalCalc(methodNode).let { adapter ->
|
||||||
val smap = InlineCodegen.generateMethodBody(
|
val smap = InlineCodegen.generateMethodBody(
|
||||||
adapter, invokeMethodDescriptor, context, functionWithBodyOrCallableReference, jvmMethodSignature, codegen, this
|
adapter, invokeMethodDescriptor, context, functionWithBodyOrCallableReference, jvmMethodSignature, codegen, this
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ class LocalVarRemapper(private val params: Parameters, private val additionalShi
|
|||||||
val remapInfo = remap(`var`)
|
val remapInfo = remap(`var`)
|
||||||
val value = remapInfo.value
|
val value = remapInfo.value
|
||||||
if (value is StackValue.Local) {
|
if (value is StackValue.Local) {
|
||||||
val isStore = InlineCodegenUtil.isStoreInstruction(opcode)
|
val isStore = isStoreInstruction(opcode)
|
||||||
if (remapInfo.parameterInfo != null) {
|
if (remapInfo.parameterInfo != null) {
|
||||||
//All remapped value parameters can't be rewritten except case of default ones.
|
//All remapped value parameters can't be rewritten except case of default ones.
|
||||||
//On remapping default parameter to actual value there is only one instruction that writes to it according to mask value
|
//On remapping default parameter to actual value there is only one instruction that writes to it according to mask value
|
||||||
|
|||||||
@@ -23,10 +23,12 @@ import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
|||||||
import org.jetbrains.org.objectweb.asm.TypePath;
|
import org.jetbrains.org.objectweb.asm.TypePath;
|
||||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||||
|
|
||||||
|
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.API;
|
||||||
|
|
||||||
public class MethodBodyVisitor extends InstructionAdapter {
|
public class MethodBodyVisitor extends InstructionAdapter {
|
||||||
|
|
||||||
public MethodBodyVisitor(MethodVisitor mv) {
|
public MethodBodyVisitor(MethodVisitor mv) {
|
||||||
super(InlineCodegenUtil.API, mv);
|
super(API, mv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.codegen.inline
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.ClosureCodegen
|
import org.jetbrains.kotlin.codegen.ClosureCodegen
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
import org.jetbrains.kotlin.codegen.StackValue
|
||||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.*
|
|
||||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
||||||
import org.jetbrains.kotlin.codegen.optimization.FixStackWithLabelNormalizationMethodTransformer
|
import org.jetbrains.kotlin.codegen.optimization.FixStackWithLabelNormalizationMethodTransformer
|
||||||
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
|
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
|
||||||
@@ -87,7 +86,7 @@ class MethodInliner(
|
|||||||
transformedNode.instructions.resetLabels()
|
transformedNode.instructions.resetLabels()
|
||||||
|
|
||||||
val resultNode = MethodNode(
|
val resultNode = MethodNode(
|
||||||
InlineCodegenUtil.API, transformedNode.access, transformedNode.name, transformedNode.desc,
|
API, transformedNode.access, transformedNode.name, transformedNode.desc,
|
||||||
transformedNode.signature, transformedNode.exceptions?.toTypedArray()
|
transformedNode.signature, transformedNode.exceptions?.toTypedArray()
|
||||||
)
|
)
|
||||||
val visitor = RemapVisitor(resultNode, remapper, nodeRemapper)
|
val visitor = RemapVisitor(resultNode, remapper, nodeRemapper)
|
||||||
@@ -130,7 +129,7 @@ class MethodInliner(
|
|||||||
AsmTypeRemapper(remapper, result)
|
AsmTypeRemapper(remapper, result)
|
||||||
)
|
)
|
||||||
|
|
||||||
val markerShift = InlineCodegenUtil.calcMarkerShift(parameters, node)
|
val markerShift = calcMarkerShift(parameters, node)
|
||||||
val lambdaInliner = object : InlineAdapter(remappingMethodAdapter, parameters.argsSizeOnStack, sourceMapper) {
|
val lambdaInliner = object : InlineAdapter(remappingMethodAdapter, parameters.argsSizeOnStack, sourceMapper) {
|
||||||
private var transformationInfo: TransformationInfo? = null
|
private var transformationInfo: TransformationInfo? = null
|
||||||
|
|
||||||
@@ -312,11 +311,11 @@ class MethodInliner(
|
|||||||
val realParametersSize = parameters.realParametersSizeOnStack
|
val realParametersSize = parameters.realParametersSizeOnStack
|
||||||
|
|
||||||
val transformedNode = object : MethodNode(
|
val transformedNode = object : MethodNode(
|
||||||
InlineCodegenUtil.API, node.access, node.name,
|
API, node.access, node.name,
|
||||||
Type.getMethodDescriptor(Type.getReturnType(node.desc), *(Type.getArgumentTypes(node.desc) + parameters.capturedTypes)),
|
Type.getMethodDescriptor(Type.getReturnType(node.desc), *(Type.getArgumentTypes(node.desc) + parameters.capturedTypes)),
|
||||||
node.signature, node.exceptions?.toTypedArray()
|
node.signature, node.exceptions?.toTypedArray()
|
||||||
) {
|
) {
|
||||||
private val GENERATE_DEBUG_INFO = InlineCodegenUtil.GENERATE_SMAP && inlineOnlySmapSkipper == null
|
private val GENERATE_DEBUG_INFO = GENERATE_SMAP && inlineOnlySmapSkipper == null
|
||||||
|
|
||||||
private val isInliningLambda = nodeRemapper.isInsideInliningLambda
|
private val isInliningLambda = nodeRemapper.isInsideInliningLambda
|
||||||
|
|
||||||
@@ -343,8 +342,8 @@ class MethodInliner(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitMethodInsn(opcode: Int, owner: String, name: String, desc: String, itf: Boolean) {
|
override fun visitMethodInsn(opcode: Int, owner: String, name: String, desc: String, itf: Boolean) {
|
||||||
if (InlineCodegenUtil.DEFAULT_LAMBDA_FAKE_CALL == owner) {
|
if (DEFAULT_LAMBDA_FAKE_CALL == owner) {
|
||||||
val index = name.substringAfter(InlineCodegenUtil.DEFAULT_LAMBDA_FAKE_CALL).toInt()
|
val index = name.substringAfter(DEFAULT_LAMBDA_FAKE_CALL).toInt()
|
||||||
val lambda = getLambdaIfExists(index) as DefaultLambda
|
val lambda = getLambdaIfExists(index) as DefaultLambda
|
||||||
lambda.parameterOffsetsInDefault.zip(lambda.capturedVars).asReversed().forEach {
|
lambda.parameterOffsetsInDefault.zip(lambda.capturedVars).asReversed().forEach {
|
||||||
(_, captured) ->
|
(_, captured) ->
|
||||||
@@ -362,7 +361,7 @@ class MethodInliner(
|
|||||||
name: String, desc: String, signature: String?, start: Label, end: Label, index: Int
|
name: String, desc: String, signature: String?, start: Label, end: Label, index: Int
|
||||||
) {
|
) {
|
||||||
if (isInliningLambda || GENERATE_DEBUG_INFO) {
|
if (isInliningLambda || GENERATE_DEBUG_INFO) {
|
||||||
val varSuffix = if (inliningContext.isRoot && !InlineCodegenUtil.isFakeLocalVariableForInline(name)) INLINE_FUN_VAR_SUFFIX else ""
|
val varSuffix = if (inliningContext.isRoot && !isFakeLocalVariableForInline(name)) INLINE_FUN_VAR_SUFFIX else ""
|
||||||
val varName = if (!varSuffix.isEmpty() && name == "this") name + "_" else name
|
val varName = if (!varSuffix.isEmpty() && name == "this") name + "_" else name
|
||||||
super.visitLocalVariable(varName + varSuffix, desc, signature, start, end, getNewIndex(index))
|
super.visitLocalVariable(varName + varSuffix, desc, signature, start, end, getNewIndex(index))
|
||||||
}
|
}
|
||||||
@@ -400,9 +399,9 @@ class MethodInliner(
|
|||||||
awaitClassReification = true
|
awaitClassReification = true
|
||||||
}
|
}
|
||||||
else if (cur is MethodInsnNode) {
|
else if (cur is MethodInsnNode) {
|
||||||
if (InlineCodegenUtil.isFinallyStart(cur)) {
|
if (isFinallyStart(cur)) {
|
||||||
//TODO deep index calc could be more precise
|
//TODO deep index calc could be more precise
|
||||||
currentFinallyDeep = InlineCodegenUtil.getConstant(cur.previous)
|
currentFinallyDeep = getConstant(cur.previous)
|
||||||
}
|
}
|
||||||
|
|
||||||
val owner = cur.owner
|
val owner = cur.owner
|
||||||
@@ -668,7 +667,7 @@ class MethodInliner(
|
|||||||
insertBeforeInsn: AbstractInsnNode,
|
insertBeforeInsn: AbstractInsnNode,
|
||||||
sourceValueFrame: Frame<SourceValue>
|
sourceValueFrame: Frame<SourceValue>
|
||||||
) {
|
) {
|
||||||
assert(InlineCodegenUtil.isReturnOpcode(returnInsn.opcode)) { "return instruction expected" }
|
assert(isReturnOpcode(returnInsn.opcode)) { "return instruction expected" }
|
||||||
assert(returnOpcode < 0 || returnOpcode == returnInsn.opcode) { "Return op should be " + Printer.OPCODES[returnOpcode] + ", got " + Printer.OPCODES[returnInsn.opcode] }
|
assert(returnOpcode < 0 || returnOpcode == returnInsn.opcode) { "Return op should be " + Printer.OPCODES[returnOpcode] + ", got " + Printer.OPCODES[returnInsn.opcode] }
|
||||||
returnOpcode = returnInsn.opcode
|
returnOpcode = returnInsn.opcode
|
||||||
|
|
||||||
@@ -771,9 +770,9 @@ class MethodInliner(
|
|||||||
|
|
||||||
var cur: AbstractInsnNode? = node.instructions.first
|
var cur: AbstractInsnNode? = node.instructions.first
|
||||||
while (cur != null) {
|
while (cur != null) {
|
||||||
if (cur is MethodInsnNode && InlineCodegenUtil.isFinallyMarker(cur)) {
|
if (cur is MethodInsnNode && isFinallyMarker(cur)) {
|
||||||
val constant = cur.previous
|
val constant = cur.previous
|
||||||
val curDeep = InlineCodegenUtil.getConstant(constant)
|
val curDeep = getConstant(constant)
|
||||||
node.instructions.insert(constant, LdcInsnNode(curDeep + finallyDeepShift))
|
node.instructions.insert(constant, LdcInsnNode(curDeep + finallyDeepShift))
|
||||||
node.instructions.remove(constant)
|
node.instructions.remove(constant)
|
||||||
}
|
}
|
||||||
@@ -829,9 +828,9 @@ class MethodInliner(
|
|||||||
val instructions = node.instructions
|
val instructions = node.instructions
|
||||||
var insnNode: AbstractInsnNode? = instructions.first
|
var insnNode: AbstractInsnNode? = instructions.first
|
||||||
while (insnNode != null) {
|
while (insnNode != null) {
|
||||||
if (InlineCodegenUtil.isReturnOpcode(insnNode.opcode)) {
|
if (isReturnOpcode(insnNode.opcode)) {
|
||||||
var isLocalReturn = true
|
var isLocalReturn = true
|
||||||
val labelName = InlineCodegenUtil.getMarkedReturnLabelOrNull(insnNode)
|
val labelName = getMarkedReturnLabelOrNull(insnNode)
|
||||||
|
|
||||||
if (labelName != null) {
|
if (labelName != null) {
|
||||||
isLocalReturn = labelOwner.isMyLabel(labelName)
|
isLocalReturn = labelOwner.isMyLabel(labelName)
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ fun MethodNode.findCapturedFieldAssignmentInstructions(): Sequence<FieldInsnNode
|
|||||||
val prevPrev = fieldNode.previous?.previous as? VarInsnNode
|
val prevPrev = fieldNode.previous?.previous as? VarInsnNode
|
||||||
|
|
||||||
fieldNode.opcode == Opcodes.PUTFIELD &&
|
fieldNode.opcode == Opcodes.PUTFIELD &&
|
||||||
InlineCodegenUtil.isCapturedFieldName(fieldNode.name) &&
|
isCapturedFieldName(fieldNode.name) &&
|
||||||
fieldNode.previous is VarInsnNode && prevPrev != null && prevPrev.`var` == 0
|
fieldNode.previous is VarInsnNode && prevPrev != null && prevPrev.`var` == 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ abstract class ObjectTransformer<out T : TransformationInfo>(@JvmField val trans
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun createClassReader(): ClassReader {
|
fun createClassReader(): ClassReader {
|
||||||
return InlineCodegenUtil.buildClassReaderByInternalName(state, transformationInfo.oldClassName)
|
return buildClassReaderByInternalName(state, transformationInfo.oldClassName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ class WhenMappingTransformer(
|
|||||||
/*MAPPING File could contains mappings for several enum classes, we should filter one*/
|
/*MAPPING File could contains mappings for several enum classes, we should filter one*/
|
||||||
val methodNodes = arrayListOf<MethodNode>()
|
val methodNodes = arrayListOf<MethodNode>()
|
||||||
val fieldNode = transformationInfo.fieldNode
|
val fieldNode = transformationInfo.fieldNode
|
||||||
classReader.accept(object : ClassVisitor(InlineCodegenUtil.API, classBuilder.visitor) {
|
classReader.accept(object : ClassVisitor(API, classBuilder.visitor) {
|
||||||
override fun visit(version: Int, access: Int, name: String, signature: String?, superName: String, interfaces: Array<String>) {
|
override fun visit(version: Int, access: Int, name: String, signature: String?, superName: String, interfaces: Array<String>) {
|
||||||
classBuilder.defineClass(null, version, access, name, signature, superName, interfaces)
|
classBuilder.defineClass(null, version, access, name, signature, superName, interfaces)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-3
@@ -17,8 +17,6 @@
|
|||||||
package org.jetbrains.kotlin.codegen.inline
|
package org.jetbrains.kotlin.codegen.inline
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
import org.jetbrains.kotlin.codegen.StackValue
|
||||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.CAPTURED_FIELD_FOLD_PREFIX
|
|
||||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.THIS
|
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode
|
import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode
|
||||||
@@ -67,7 +65,7 @@ class RegeneratedLambdaFieldRemapper(
|
|||||||
val field = findFieldInSuper(fin) ?:
|
val field = findFieldInSuper(fin) ?:
|
||||||
//search in parent
|
//search in parent
|
||||||
findFieldInSuper(FieldInsnNode(
|
findFieldInSuper(FieldInsnNode(
|
||||||
Opcodes.GETSTATIC, originalLambdaInternalName, InlineCodegenUtil.`THIS$0`,
|
Opcodes.GETSTATIC, originalLambdaInternalName, THIS_0,
|
||||||
Type.getObjectType(parent!!.originalLambdaInternalName!!).descriptor
|
Type.getObjectType(parent!!.originalLambdaInternalName!!).descriptor
|
||||||
))?.also { fromParent = true } ?:
|
))?.also { fromParent = true } ?:
|
||||||
throw AssertionError("Couldn't find captured this $originalLambdaInternalName for $fieldName")
|
throw AssertionError("Couldn't find captured this $originalLambdaInternalName for $fieldName")
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?)
|
|||||||
) = rewriteNextTypeInsn(insn, Opcodes.CHECKCAST) { stubCheckcast: AbstractInsnNode ->
|
) = rewriteNextTypeInsn(insn, Opcodes.CHECKCAST) { stubCheckcast: AbstractInsnNode ->
|
||||||
if (stubCheckcast !is TypeInsnNode) return false
|
if (stubCheckcast !is TypeInsnNode) return false
|
||||||
|
|
||||||
val newMethodNode = MethodNode(InlineCodegenUtil.API)
|
val newMethodNode = MethodNode(API)
|
||||||
generateAsCast(InstructionAdapter(newMethodNode), kotlinType, asmType, safe)
|
generateAsCast(InstructionAdapter(newMethodNode), kotlinType, asmType, safe)
|
||||||
|
|
||||||
instructions.insert(insn, newMethodNode.instructions)
|
instructions.insert(insn, newMethodNode.instructions)
|
||||||
@@ -189,7 +189,7 @@ class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?)
|
|||||||
) = rewriteNextTypeInsn(insn, Opcodes.INSTANCEOF) { stubInstanceOf: AbstractInsnNode ->
|
) = rewriteNextTypeInsn(insn, Opcodes.INSTANCEOF) { stubInstanceOf: AbstractInsnNode ->
|
||||||
if (stubInstanceOf !is TypeInsnNode) return false
|
if (stubInstanceOf !is TypeInsnNode) return false
|
||||||
|
|
||||||
val newMethodNode = MethodNode(InlineCodegenUtil.API)
|
val newMethodNode = MethodNode(API)
|
||||||
generateIsCheck(InstructionAdapter(newMethodNode), kotlinType, asmType)
|
generateIsCheck(InstructionAdapter(newMethodNode), kotlinType, asmType)
|
||||||
|
|
||||||
instructions.insert(insn, newMethodNode.instructions)
|
instructions.insert(insn, newMethodNode.instructions)
|
||||||
@@ -231,14 +231,14 @@ class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?)
|
|||||||
if (next3 is MethodInsnNode && next3.name == "valueOf") {
|
if (next3 is MethodInsnNode && next3.name == "valueOf") {
|
||||||
instructions.remove(next1)
|
instructions.remove(next1)
|
||||||
next3.owner = parameter.internalName
|
next3.owner = parameter.internalName
|
||||||
next3.desc = InlineCodegenUtil.getSpecialEnumFunDescriptor(parameter, true)
|
next3.desc = getSpecialEnumFunDescriptor(parameter, true)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (next1.opcode == Opcodes.ICONST_0 && next2.opcode == Opcodes.ANEWARRAY) {
|
else if (next1.opcode == Opcodes.ICONST_0 && next2.opcode == Opcodes.ANEWARRAY) {
|
||||||
instructions.remove(next1)
|
instructions.remove(next1)
|
||||||
instructions.remove(next2)
|
instructions.remove(next2)
|
||||||
val desc = InlineCodegenUtil.getSpecialEnumFunDescriptor(parameter, false)
|
val desc = getSpecialEnumFunDescriptor(parameter, false)
|
||||||
instructions.insert(insn, MethodInsnNode(Opcodes.INVOKESTATIC, parameter.internalName, "values", desc, false))
|
instructions.insert(insn, MethodInsnNode(Opcodes.INVOKESTATIC, parameter.internalName, "values", desc, false))
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ import org.jetbrains.org.objectweb.asm.Opcodes;
|
|||||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||||
import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode;
|
import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode;
|
||||||
|
|
||||||
|
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.CAPTURED_FIELD_FOLD_PREFIX;
|
||||||
|
|
||||||
public class RemapVisitor extends MethodBodyVisitor {
|
public class RemapVisitor extends MethodBodyVisitor {
|
||||||
private final LocalVarRemapper remapper;
|
private final LocalVarRemapper remapper;
|
||||||
private final FieldRemapper nodeRemapper;
|
private final FieldRemapper nodeRemapper;
|
||||||
@@ -59,7 +61,7 @@ public class RemapVisitor extends MethodBodyVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitFieldInsn(int opcode, @NotNull String owner, @NotNull String name, @NotNull String desc) {
|
public void visitFieldInsn(int opcode, @NotNull String owner, @NotNull String name, @NotNull String desc) {
|
||||||
if (name.startsWith(InlineCodegenUtil.CAPTURED_FIELD_FOLD_PREFIX) &&
|
if (name.startsWith(CAPTURED_FIELD_FOLD_PREFIX) &&
|
||||||
(nodeRemapper instanceof RegeneratedLambdaFieldRemapper || nodeRemapper.isRoot())) {
|
(nodeRemapper instanceof RegeneratedLambdaFieldRemapper || nodeRemapper.isRoot())) {
|
||||||
FieldInsnNode fin = new FieldInsnNode(opcode, owner, name, desc);
|
FieldInsnNode fin = new FieldInsnNode(opcode, owner, name, desc);
|
||||||
StackValue inline = nodeRemapper.getFieldForInline(fin, null);
|
StackValue inline = nodeRemapper.getFieldForInline(fin, null);
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.inline
|
package org.jetbrains.kotlin.codegen.inline
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.firstLabelInChain
|
|
||||||
import org.jetbrains.org.objectweb.asm.tree.LabelNode
|
import org.jetbrains.org.objectweb.asm.tree.LabelNode
|
||||||
import org.jetbrains.org.objectweb.asm.tree.TryCatchBlockNode
|
import org.jetbrains.org.objectweb.asm.tree.TryCatchBlockNode
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,6 @@ package org.jetbrains.kotlin.codegen.inline
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||||
import org.jetbrains.kotlin.codegen.OwnerKind
|
import org.jetbrains.kotlin.codegen.OwnerKind
|
||||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.DEFAULT_LAMBDA_FAKE_CALL
|
|
||||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.getConstant
|
|
||||||
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner.Companion.isNeedClassReificationMarker
|
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner.Companion.isNeedClassReificationMarker
|
||||||
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
|
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
|
||||||
import org.jetbrains.kotlin.codegen.optimization.common.asSequence
|
import org.jetbrains.kotlin.codegen.optimization.common.asSequence
|
||||||
|
|||||||
+4
-3
@@ -17,7 +17,8 @@
|
|||||||
package org.jetbrains.kotlin.codegen.optimization.boxing
|
package org.jetbrains.kotlin.codegen.optimization.boxing
|
||||||
|
|
||||||
import com.intellij.openapi.util.Pair
|
import com.intellij.openapi.util.Pair
|
||||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil
|
import org.jetbrains.kotlin.codegen.inline.getInsnOpcodeText
|
||||||
|
import org.jetbrains.kotlin.codegen.inline.getInsnText
|
||||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
||||||
import org.jetbrains.kotlin.codegen.optimization.common.StrictBasicValue
|
import org.jetbrains.kotlin.codegen.optimization.common.StrictBasicValue
|
||||||
import org.jetbrains.kotlin.codegen.optimization.common.*
|
import org.jetbrains.kotlin.codegen.optimization.common.*
|
||||||
@@ -324,7 +325,7 @@ class RedundantBoxingMethodTransformer : MethodTransformer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun throwCannotAdaptInstruction(insn: AbstractInsnNode): Nothing =
|
private fun throwCannotAdaptInstruction(insn: AbstractInsnNode): Nothing =
|
||||||
throw AssertionError("Cannot adapt instruction: ${InlineCodegenUtil.getInsnText(insn)}")
|
throw AssertionError("Cannot adapt instruction: ${getInsnText(insn)}")
|
||||||
|
|
||||||
private fun adaptAreEqualIntrinsic(
|
private fun adaptAreEqualIntrinsic(
|
||||||
node: MethodNode,
|
node: MethodNode,
|
||||||
@@ -392,7 +393,7 @@ class RedundantBoxingMethodTransformer : MethodTransformer() {
|
|||||||
next.getOpcode() == Opcodes.IFNE ->
|
next.getOpcode() == Opcodes.IFNE ->
|
||||||
insertBefore(insn, JumpInsnNode(ifNotEqualOpcode, nextLabel))
|
insertBefore(insn, JumpInsnNode(ifNotEqualOpcode, nextLabel))
|
||||||
else ->
|
else ->
|
||||||
throw AssertionError("IFEQ or IFNE expected: " + InlineCodegenUtil.getInsnOpcodeText(next))
|
throw AssertionError("IFEQ or IFNE expected: " + getInsnOpcodeText(next))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.optimization.common
|
package org.jetbrains.kotlin.codegen.optimization.common
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil
|
import org.jetbrains.kotlin.codegen.inline.getInsnText
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
import org.jetbrains.org.objectweb.asm.tree.*
|
import org.jetbrains.org.objectweb.asm.tree.*
|
||||||
@@ -146,10 +146,10 @@ open class MethodAnalyzer<V : Value>(
|
|||||||
|
|
||||||
}
|
}
|
||||||
catch (e: AnalyzerException) {
|
catch (e: AnalyzerException) {
|
||||||
throw AnalyzerException(e.node, "Error at instruction #" + insn + " ${InlineCodegenUtil.getInsnText(insnNode)}: " + e.message, e)
|
throw AnalyzerException(e.node, "Error at instruction #" + insn + " ${getInsnText(insnNode)}: " + e.message, e)
|
||||||
}
|
}
|
||||||
catch (e: Exception) {
|
catch (e: Exception) {
|
||||||
throw AnalyzerException(insnNode, "Error at instruction #" + insn + " ${InlineCodegenUtil.getInsnText(insnNode)}: " + e.message, e)
|
throw AnalyzerException(insnNode, "Error at instruction #" + insn + " ${getInsnText(insnNode)}: " + e.message, e)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.codegen.optimization.common;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.codegen.AsmUtil;
|
import org.jetbrains.kotlin.codegen.AsmUtil;
|
||||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil;
|
|
||||||
import org.jetbrains.org.objectweb.asm.Handle;
|
import org.jetbrains.org.objectweb.asm.Handle;
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes;
|
import org.jetbrains.org.objectweb.asm.Opcodes;
|
||||||
import org.jetbrains.org.objectweb.asm.Type;
|
import org.jetbrains.org.objectweb.asm.Type;
|
||||||
@@ -30,6 +29,7 @@ import org.jetbrains.org.objectweb.asm.tree.analysis.Interpreter;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.getInsnOpcodeText;
|
||||||
import static org.jetbrains.kotlin.codegen.optimization.common.StrictBasicValue.*;
|
import static org.jetbrains.kotlin.codegen.optimization.common.StrictBasicValue.*;
|
||||||
|
|
||||||
public class OptimizationBasicInterpreter extends Interpreter<BasicValue> implements Opcodes {
|
public class OptimizationBasicInterpreter extends Interpreter<BasicValue> implements Opcodes {
|
||||||
@@ -137,7 +137,7 @@ public class OptimizationBasicInterpreter extends Interpreter<BasicValue> implem
|
|||||||
case NEW:
|
case NEW:
|
||||||
return newValue(Type.getObjectType(((TypeInsnNode) insn).desc));
|
return newValue(Type.getObjectType(((TypeInsnNode) insn).desc));
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Unexpected instruction: " + InlineCodegenUtil.getInsnOpcodeText(insn));
|
throw new IllegalArgumentException("Unexpected instruction: " + getInsnOpcodeText(insn));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,7 +222,7 @@ public class OptimizationBasicInterpreter extends Interpreter<BasicValue> implem
|
|||||||
case PUTFIELD:
|
case PUTFIELD:
|
||||||
return null;
|
return null;
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Unexpected instruction: " + InlineCodegenUtil.getInsnOpcodeText(insn));
|
throw new IllegalArgumentException("Unexpected instruction: " + getInsnOpcodeText(insn));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -341,7 +341,7 @@ public class OptimizationBasicInterpreter extends Interpreter<BasicValue> implem
|
|||||||
case IFNONNULL:
|
case IFNONNULL:
|
||||||
return null;
|
return null;
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Unexpected instruction: " + InlineCodegenUtil.getInsnOpcodeText(insn));
|
throw new IllegalArgumentException("Unexpected instruction: " + getInsnOpcodeText(insn));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.optimization.common
|
package org.jetbrains.kotlin.codegen.optimization.common
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil
|
import org.jetbrains.kotlin.codegen.inline.getInsnText
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
||||||
@@ -176,7 +176,7 @@ fun insnListOf(vararg insns: AbstractInsnNode) = InsnList().apply { insns.forEac
|
|||||||
fun AbstractInsnNode.isStoreOperation(): Boolean = opcode in Opcodes.ISTORE..Opcodes.ASTORE
|
fun AbstractInsnNode.isStoreOperation(): Boolean = opcode in Opcodes.ISTORE..Opcodes.ASTORE
|
||||||
fun AbstractInsnNode.isLoadOperation(): Boolean = opcode in Opcodes.ILOAD..Opcodes.ALOAD
|
fun AbstractInsnNode.isLoadOperation(): Boolean = opcode in Opcodes.ILOAD..Opcodes.ALOAD
|
||||||
|
|
||||||
val AbstractInsnNode?.insnText get() = InlineCodegenUtil.getInsnText(this)
|
val AbstractInsnNode?.insnText get() = getInsnText(this)
|
||||||
val AbstractInsnNode?.debugText get() =
|
val AbstractInsnNode?.debugText get() =
|
||||||
if (this == null) "<null>" else "${this::class.java.simpleName}: $insnText"
|
if (this == null) "<null>" else "${this::class.java.simpleName}: $insnText"
|
||||||
|
|
||||||
|
|||||||
+6
-4
@@ -17,7 +17,9 @@
|
|||||||
package org.jetbrains.kotlin.codegen.optimization.fixStack
|
package org.jetbrains.kotlin.codegen.optimization.fixStack
|
||||||
|
|
||||||
import com.intellij.util.containers.Stack
|
import com.intellij.util.containers.Stack
|
||||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil
|
import org.jetbrains.kotlin.codegen.inline.isAfterInlineMarker
|
||||||
|
import org.jetbrains.kotlin.codegen.inline.isBeforeInlineMarker
|
||||||
|
import org.jetbrains.kotlin.codegen.inline.isMarkedReturn
|
||||||
import org.jetbrains.kotlin.codegen.optimization.common.MethodAnalyzer
|
import org.jetbrains.kotlin.codegen.optimization.common.MethodAnalyzer
|
||||||
import org.jetbrains.kotlin.codegen.optimization.common.OptimizationBasicInterpreter
|
import org.jetbrains.kotlin.codegen.optimization.common.OptimizationBasicInterpreter
|
||||||
import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsn
|
import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsn
|
||||||
@@ -103,11 +105,11 @@ internal class FixStackAnalyzer(
|
|||||||
executeSaveStackBeforeTry(insn)
|
executeSaveStackBeforeTry(insn)
|
||||||
PseudoInsn.RESTORE_STACK_IN_TRY_CATCH.isa(insn) ->
|
PseudoInsn.RESTORE_STACK_IN_TRY_CATCH.isa(insn) ->
|
||||||
executeRestoreStackInTryCatch(insn)
|
executeRestoreStackInTryCatch(insn)
|
||||||
InlineCodegenUtil.isBeforeInlineMarker(insn) ->
|
isBeforeInlineMarker(insn) ->
|
||||||
executeBeforeInlineCallMarker(insn)
|
executeBeforeInlineCallMarker(insn)
|
||||||
InlineCodegenUtil.isAfterInlineMarker(insn) ->
|
isAfterInlineMarker(insn) ->
|
||||||
executeAfterInlineCallMarker(insn)
|
executeAfterInlineCallMarker(insn)
|
||||||
InlineCodegenUtil.isMarkedReturn(insn) -> {
|
isMarkedReturn(insn) -> {
|
||||||
// KT-9644: might throw "Incompatible return type" on non-local return, in fact we don't care.
|
// KT-9644: might throw "Incompatible return type" on non-local return, in fact we don't care.
|
||||||
if (insn.opcode == Opcodes.RETURN) return
|
if (insn.opcode == Opcodes.RETURN) return
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-3
@@ -18,7 +18,8 @@ package org.jetbrains.kotlin.codegen.optimization.fixStack
|
|||||||
|
|
||||||
import com.intellij.util.SmartList
|
import com.intellij.util.SmartList
|
||||||
import com.intellij.util.containers.Stack
|
import com.intellij.util.containers.Stack
|
||||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil
|
import org.jetbrains.kotlin.codegen.inline.isAfterInlineMarker
|
||||||
|
import org.jetbrains.kotlin.codegen.inline.isBeforeInlineMarker
|
||||||
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
|
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
|
||||||
import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsn
|
import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsn
|
||||||
import org.jetbrains.kotlin.codegen.pseudoInsns.parsePseudoInsnOrNull
|
import org.jetbrains.kotlin.codegen.pseudoInsns.parsePseudoInsnOrNull
|
||||||
@@ -56,10 +57,10 @@ internal class FixStackContext(val methodNode: MethodNode) {
|
|||||||
visitFakeAlwaysTrueIfeq(insnNode)
|
visitFakeAlwaysTrueIfeq(insnNode)
|
||||||
pseudoInsn == PseudoInsn.FAKE_ALWAYS_FALSE_IFEQ ->
|
pseudoInsn == PseudoInsn.FAKE_ALWAYS_FALSE_IFEQ ->
|
||||||
visitFakeAlwaysFalseIfeq(insnNode)
|
visitFakeAlwaysFalseIfeq(insnNode)
|
||||||
InlineCodegenUtil.isBeforeInlineMarker(insnNode) -> {
|
isBeforeInlineMarker(insnNode) -> {
|
||||||
inlineMarkersStack.push(insnNode)
|
inlineMarkersStack.push(insnNode)
|
||||||
}
|
}
|
||||||
InlineCodegenUtil.isAfterInlineMarker(insnNode) -> {
|
isAfterInlineMarker(insnNode) -> {
|
||||||
assert(inlineMarkersStack.isNotEmpty()) { "Mismatching after inline method marker at ${indexOf(insnNode)}" }
|
assert(inlineMarkersStack.isNotEmpty()) { "Mismatching after inline method marker at ${indexOf(insnNode)}" }
|
||||||
openingInlineMethodMarker[insnNode] = inlineMarkersStack.pop()
|
openingInlineMethodMarker[insnNode] = inlineMarkersStack.pop()
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-4
@@ -16,7 +16,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.optimization.fixStack
|
package org.jetbrains.kotlin.codegen.optimization.fixStack
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil
|
import org.jetbrains.kotlin.codegen.inline.isAfterInlineMarker
|
||||||
|
import org.jetbrains.kotlin.codegen.inline.isBeforeInlineMarker
|
||||||
|
import org.jetbrains.kotlin.codegen.inline.isInlineMarker
|
||||||
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
|
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
|
||||||
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
|
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
|
||||||
import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsn
|
import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsn
|
||||||
@@ -33,7 +35,7 @@ class FixStackMethodTransformer : MethodTransformer() {
|
|||||||
// If inline method markers are inconsistent, remove them now
|
// If inline method markers are inconsistent, remove them now
|
||||||
if (!context.consistentInlineMarkers) {
|
if (!context.consistentInlineMarkers) {
|
||||||
InsnSequence(methodNode.instructions).forEach { insnNode ->
|
InsnSequence(methodNode.instructions).forEach { insnNode ->
|
||||||
if (InlineCodegenUtil.isInlineMarker(insnNode))
|
if (isInlineMarker(insnNode))
|
||||||
methodNode.instructions.remove(insnNode)
|
methodNode.instructions.remove(insnNode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -131,9 +133,9 @@ class FixStackMethodTransformer : MethodTransformer() {
|
|||||||
transformSaveStackMarker(methodNode, actions, analyzer, marker, localVariablesManager)
|
transformSaveStackMarker(methodNode, actions, analyzer, marker, localVariablesManager)
|
||||||
pseudoInsn == PseudoInsn.RESTORE_STACK_IN_TRY_CATCH ->
|
pseudoInsn == PseudoInsn.RESTORE_STACK_IN_TRY_CATCH ->
|
||||||
transformRestoreStackMarker(methodNode, actions, marker, localVariablesManager)
|
transformRestoreStackMarker(methodNode, actions, marker, localVariablesManager)
|
||||||
InlineCodegenUtil.isBeforeInlineMarker(marker) ->
|
isBeforeInlineMarker(marker) ->
|
||||||
transformBeforeInlineCallMarker(methodNode, actions, analyzer, marker, localVariablesManager)
|
transformBeforeInlineCallMarker(methodNode, actions, analyzer, marker, localVariablesManager)
|
||||||
InlineCodegenUtil.isAfterInlineMarker(marker) ->
|
isAfterInlineMarker(marker) ->
|
||||||
transformAfterInlineCallMarker(methodNode, actions, analyzer, marker, localVariablesManager)
|
transformAfterInlineCallMarker(methodNode, actions, analyzer, marker, localVariablesManager)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.codegen
|
|||||||
import com.intellij.openapi.util.io.FileUtil
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
import com.intellij.openapi.util.text.StringUtil
|
import com.intellij.openapi.util.text.StringUtil
|
||||||
import org.jetbrains.kotlin.backend.common.output.OutputFile
|
import org.jetbrains.kotlin.backend.common.output.OutputFile
|
||||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil
|
import org.jetbrains.kotlin.codegen.inline.GENERATE_SMAP
|
||||||
import org.jetbrains.kotlin.codegen.inline.RangeMapping
|
import org.jetbrains.kotlin.codegen.inline.RangeMapping
|
||||||
import org.jetbrains.kotlin.codegen.inline.SMAPParser
|
import org.jetbrains.kotlin.codegen.inline.SMAPParser
|
||||||
import org.jetbrains.kotlin.codegen.inline.toRange
|
import org.jetbrains.kotlin.codegen.inline.toRange
|
||||||
@@ -61,7 +61,7 @@ object SMAPTestUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun checkSMAP(inputFiles: List<CodegenTestCase.TestFile>, outputFiles: Iterable<OutputFile>) {
|
fun checkSMAP(inputFiles: List<CodegenTestCase.TestFile>, outputFiles: Iterable<OutputFile>) {
|
||||||
if (!InlineCodegenUtil.GENERATE_SMAP) return
|
if (!GENERATE_SMAP) return
|
||||||
|
|
||||||
val sourceData = inputFiles.mapNotNull { extractSmapFromTestDataFile(it) }
|
val sourceData = inputFiles.mapNotNull { extractSmapFromTestDataFile(it) }
|
||||||
val compiledSmaps = extractSMAPFromClasses(outputFiles)
|
val compiledSmaps = extractSMAPFromClasses(outputFiles)
|
||||||
|
|||||||
+2
-2
@@ -29,7 +29,7 @@ import org.jetbrains.kotlin.cli.js.K2JSCompiler
|
|||||||
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
|
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil
|
import org.jetbrains.kotlin.codegen.inline.GENERATE_SMAP
|
||||||
import org.jetbrains.kotlin.config.KotlinCompilerVersion.TEST_IS_PRE_RELEASE_SYSTEM_PROPERTY
|
import org.jetbrains.kotlin.config.KotlinCompilerVersion.TEST_IS_PRE_RELEASE_SYSTEM_PROPERTY
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
|
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
|
||||||
@@ -433,7 +433,7 @@ class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() {
|
|||||||
*E
|
*E
|
||||||
""".trimIndent() + "\n"
|
""".trimIndent() + "\n"
|
||||||
|
|
||||||
if (InlineCodegenUtil.GENERATE_SMAP) {
|
if (GENERATE_SMAP) {
|
||||||
assertEquals(expected, debugInfo)
|
assertEquals(expected, debugInfo)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -21,12 +21,12 @@ import com.intellij.debugger.jdi.LocalVariableProxyImpl
|
|||||||
import com.intellij.debugger.jdi.StackFrameProxyImpl
|
import com.intellij.debugger.jdi.StackFrameProxyImpl
|
||||||
import com.intellij.debugger.ui.impl.watch.MethodsTracker
|
import com.intellij.debugger.ui.impl.watch.MethodsTracker
|
||||||
import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl
|
import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl
|
||||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil
|
import org.jetbrains.kotlin.codegen.inline.isFakeLocalVariableForInline
|
||||||
|
|
||||||
class KotlinStackFrame(frame: StackFrameProxyImpl) : JavaStackFrame(StackFrameDescriptorImpl(frame, MethodsTracker()), true) {
|
class KotlinStackFrame(frame: StackFrameProxyImpl) : JavaStackFrame(StackFrameDescriptorImpl(frame, MethodsTracker()), true) {
|
||||||
override fun getVisibleVariables(): List<LocalVariableProxyImpl>? {
|
override fun getVisibleVariables(): List<LocalVariableProxyImpl>? {
|
||||||
return super.getVisibleVariables().filter {
|
return super.getVisibleVariables().filter {
|
||||||
!InlineCodegenUtil.isFakeLocalVariableForInline(it.name())
|
!isFakeLocalVariableForInline(it.name())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -29,7 +29,7 @@ import com.intellij.util.containers.ConcurrentWeakFactoryMap
|
|||||||
import com.intellij.util.containers.ContainerUtil
|
import com.intellij.util.containers.ContainerUtil
|
||||||
import com.sun.jdi.Location
|
import com.sun.jdi.Location
|
||||||
import com.sun.jdi.ReferenceType
|
import com.sun.jdi.ReferenceType
|
||||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil
|
import org.jetbrains.kotlin.codegen.inline.API
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.idea.debugger.evaluate.KotlinDebuggerCaches
|
import org.jetbrains.kotlin.idea.debugger.evaluate.KotlinDebuggerCaches
|
||||||
import org.jetbrains.kotlin.idea.refactoring.getLineCount
|
import org.jetbrains.kotlin.idea.refactoring.getLineCount
|
||||||
@@ -199,7 +199,7 @@ private fun findClassFileByPath(packageName: String, className: String, outputDi
|
|||||||
private fun readLineNumberTableMapping(bytes: ByteArray): Map<BytecodeMethodKey, Map<String, Set<Int>>> {
|
private fun readLineNumberTableMapping(bytes: ByteArray): Map<BytecodeMethodKey, Map<String, Set<Int>>> {
|
||||||
val lineNumberMapping = HashMap<BytecodeMethodKey, Map<String, Set<Int>>>()
|
val lineNumberMapping = HashMap<BytecodeMethodKey, Map<String, Set<Int>>>()
|
||||||
|
|
||||||
ClassReader(bytes).accept(object : ClassVisitor(InlineCodegenUtil.API) {
|
ClassReader(bytes).accept(object : ClassVisitor(API) {
|
||||||
override fun visitMethod(access: Int, name: String?, desc: String?, signature: String?, exceptions: Array<out String>?): MethodVisitor? {
|
override fun visitMethod(access: Int, name: String?, desc: String?, signature: String?, exceptions: Array<out String>?): MethodVisitor? {
|
||||||
if (name == null || desc == null) {
|
if (name == null || desc == null) {
|
||||||
return null
|
return null
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ import org.jetbrains.eval4j.jdi.asJdiValue
|
|||||||
import org.jetbrains.eval4j.jdi.asValue
|
import org.jetbrains.eval4j.jdi.asValue
|
||||||
import org.jetbrains.eval4j.obj
|
import org.jetbrains.eval4j.obj
|
||||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil
|
import org.jetbrains.kotlin.codegen.inline.INLINE_FUN_VAR_SUFFIX
|
||||||
|
import org.jetbrains.kotlin.codegen.inline.NUMBERED_FUNCTION_PREFIX
|
||||||
import org.jetbrains.kotlin.idea.debugger.isInsideInlineFunctionBody
|
import org.jetbrains.kotlin.idea.debugger.isInsideInlineFunctionBody
|
||||||
import org.jetbrains.kotlin.idea.debugger.numberOfInlinedFunctions
|
import org.jetbrains.kotlin.idea.debugger.numberOfInlinedFunctions
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
@@ -128,12 +129,12 @@ class FrameVisitor(context: EvaluationContextImpl) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun findLocalVariableForInlineArgument(name: String, number: Int, asmType: Type?, checkType: Boolean): Value? {
|
private fun findLocalVariableForInlineArgument(name: String, number: Int, asmType: Type?, checkType: Boolean): Value? {
|
||||||
return findLocalVariable(name + InlineCodegenUtil.INLINE_FUN_VAR_SUFFIX.repeat(number), asmType, checkType)
|
return findLocalVariable(name + INLINE_FUN_VAR_SUFFIX.repeat(number), asmType, checkType)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isFunctionType(type: Type?): Boolean {
|
private fun isFunctionType(type: Type?): Boolean {
|
||||||
return type?.sort == Type.OBJECT &&
|
return type?.sort == Type.OBJECT &&
|
||||||
type.internalName.startsWith(InlineCodegenUtil.NUMBERED_FUNCTION_PREFIX)
|
type.internalName.startsWith(NUMBERED_FUNCTION_PREFIX)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findLocalVariable(name: String, asmType: Type?, checkType: Boolean): Value? {
|
private fun findLocalVariable(name: String, asmType: Type?, checkType: Boolean): Value? {
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ package org.jetbrains.kotlin.idea.debugger
|
|||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import org.jetbrains.kotlin.codegen.inline.API
|
||||||
import org.jetbrains.kotlin.codegen.inline.FileMapping
|
import org.jetbrains.kotlin.codegen.inline.FileMapping
|
||||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil
|
|
||||||
import org.jetbrains.kotlin.codegen.inline.SMAP
|
import org.jetbrains.kotlin.codegen.inline.SMAP
|
||||||
import org.jetbrains.kotlin.codegen.inline.SMAPParser
|
import org.jetbrains.kotlin.codegen.inline.SMAPParser
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
@@ -62,7 +62,7 @@ fun mapStacktraceLineToSource(smapData: SmapData,
|
|||||||
fun readDebugInfo(bytes: ByteArray): SmapData? {
|
fun readDebugInfo(bytes: ByteArray): SmapData? {
|
||||||
val cr = ClassReader(bytes)
|
val cr = ClassReader(bytes)
|
||||||
var debugInfo: String? = null
|
var debugInfo: String? = null
|
||||||
cr.accept(object : ClassVisitor(InlineCodegenUtil.API) {
|
cr.accept(object : ClassVisitor(API) {
|
||||||
override fun visitSource(source: String?, debug: String?) {
|
override fun visitSource(source: String?, debug: String?) {
|
||||||
debugInfo = debug
|
debugInfo = debug
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user