Search in sources :

Example 1 with InstructionAdapter

use of org.jetbrains.org.objectweb.asm.commons.InstructionAdapter in project kotlin by JetBrains.

the class RedundantBoxingMethodTransformer method adaptCastInstruction.

private static void adaptCastInstruction(@NotNull MethodNode node, @NotNull BoxedValueDescriptor value, @NotNull Pair<AbstractInsnNode, Type> castWithType) {
    AbstractInsnNode castInsn = castWithType.getFirst();
    MethodNode castInsnsListener = new MethodNode(Opcodes.ASM5);
    new InstructionAdapter(castInsnsListener).cast(value.getUnboxedType(), castWithType.getSecond());
    for (AbstractInsnNode insn : castInsnsListener.instructions.toArray()) {
        node.instructions.insertBefore(castInsn, insn);
    }
    node.instructions.remove(castInsn);
}
Also used : InstructionAdapter(org.jetbrains.org.objectweb.asm.commons.InstructionAdapter)

Example 2 with InstructionAdapter

use of org.jetbrains.org.objectweb.asm.commons.InstructionAdapter in project kotlin by JetBrains.

the class AnonymousObjectTransformer method generateConstructorAndFields.

private void generateConstructorAndFields(@NotNull ClassBuilder classBuilder, @NotNull ParametersBuilder allCapturedBuilder, @NotNull ParametersBuilder constructorInlineBuilder, @NotNull FieldRemapper parentRemapper, @NotNull List<CapturedParamInfo> constructorAdditionalFakeParams) {
    List<Type> descTypes = new ArrayList<Type>();
    Parameters constructorParams = constructorInlineBuilder.buildParameters();
    int[] capturedIndexes = new int[constructorParams.getParameters().size()];
    int index = 0;
    int size = 0;
    //complex processing cause it could have super constructor call params
    for (ParameterInfo info : constructorParams) {
        if (!info.isSkipped) {
            //not inlined
            if (info.isCaptured() || info instanceof CapturedParamInfo) {
                capturedIndexes[index] = size;
                index++;
            }
            if (size != 0) {
                //skip this
                descTypes.add(info.getType());
            }
            size += info.getType().getSize();
        }
    }
    String constructorDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, descTypes.toArray(new Type[descTypes.size()]));
    //TODO for inline method make public class
    transformationInfo.setNewConstructorDescriptor(constructorDescriptor);
    MethodVisitor constructorVisitor = classBuilder.newMethod(NO_ORIGIN, constructor.access, "<init>", constructorDescriptor, null, ArrayUtil.EMPTY_STRING_ARRAY);
    final Label newBodyStartLabel = new Label();
    constructorVisitor.visitLabel(newBodyStartLabel);
    //initialize captured fields
    List<NewJavaField> newFieldsWithSkipped = TransformationUtilsKt.getNewFieldsToGenerate(allCapturedBuilder.listCaptured());
    List<FieldInfo> fieldInfoWithSkipped = TransformationUtilsKt.transformToFieldInfo(Type.getObjectType(transformationInfo.getNewClassName()), newFieldsWithSkipped);
    int paramIndex = 0;
    InstructionAdapter capturedFieldInitializer = new InstructionAdapter(constructorVisitor);
    for (int i = 0; i < fieldInfoWithSkipped.size(); i++) {
        FieldInfo fieldInfo = fieldInfoWithSkipped.get(i);
        if (!newFieldsWithSkipped.get(i).getSkip()) {
            AsmUtil.genAssignInstanceFieldFromParam(fieldInfo, capturedIndexes[paramIndex], capturedFieldInitializer);
        }
        paramIndex++;
    }
    //so we need to add them to captured params
    for (CapturedParamInfo info : constructorAdditionalFakeParams) {
        CapturedParamInfo fake = constructorInlineBuilder.addCapturedParamCopy(info);
        if (fake.getLambda() != null) {
            //set remap value to skip this fake (captured with lambda already skipped)
            StackValue composed = StackValue.field(fake.getType(), oldObjectType, fake.getNewFieldName(), false, StackValue.LOCAL_0);
            fake.setRemapValue(composed);
        }
    }
    MethodNode intermediateMethodNode = new MethodNode(constructor.access, "<init>", constructorDescriptor, null, ArrayUtil.EMPTY_STRING_ARRAY);
    inlineMethodAndUpdateGlobalResult(parentRemapper, intermediateMethodNode, constructor, constructorInlineBuilder, true);
    InlineCodegenUtil.removeFinallyMarkers(intermediateMethodNode);
    AbstractInsnNode first = intermediateMethodNode.instructions.getFirst();
    final Label oldStartLabel = first instanceof LabelNode ? ((LabelNode) first).getLabel() : null;
    intermediateMethodNode.accept(new MethodBodyVisitor(capturedFieldInitializer) {

        @Override
        public void visitLocalVariable(@NotNull String name, @NotNull String desc, String signature, @NotNull Label start, @NotNull Label end, int index) {
            if (oldStartLabel == start) {
                //patch for jack&jill
                start = newBodyStartLabel;
            }
            super.visitLocalVariable(name, desc, signature, start, end, index);
        }
    });
    constructorVisitor.visitEnd();
    AsmUtil.genClosureFields(TransformationUtilsKt.toNameTypePair(TransformationUtilsKt.filterSkipped(newFieldsWithSkipped)), classBuilder);
}
Also used : StackValue(org.jetbrains.kotlin.codegen.StackValue) InstructionAdapter(org.jetbrains.org.objectweb.asm.commons.InstructionAdapter) FieldInfo(org.jetbrains.kotlin.codegen.FieldInfo)

Example 3 with InstructionAdapter

use of org.jetbrains.org.objectweb.asm.commons.InstructionAdapter in project kotlin by JetBrains.

the class InlineCodegenUtil method createSpecialEnumMethodBody.

public static MethodNode createSpecialEnumMethodBody(@NotNull ExpressionCodegen codegen, @NotNull String name, @NotNull KotlinType type, @NotNull KotlinTypeMapper typeMapper) {
    boolean isValueOf = "enumValueOf".equals(name);
    Type invokeType = typeMapper.mapType(type);
    String desc = getSpecialEnumFunDescriptor(invokeType, isValueOf);
    MethodNode node = new MethodNode(API, Opcodes.ACC_STATIC, "fake", desc, null, null);
    codegen.putReifiedOperationMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.OperationKind.ENUM_REIFIED, new InstructionAdapter(node));
    if (isValueOf) {
        node.visitInsn(Opcodes.ACONST_NULL);
        node.visitVarInsn(Opcodes.ALOAD, 0);
        node.visitMethodInsn(Opcodes.INVOKESTATIC, ENUM_TYPE.getInternalName(), "valueOf", Type.getMethodDescriptor(ENUM_TYPE, JAVA_CLASS_TYPE, AsmTypes.JAVA_STRING_TYPE), false);
    } else {
        node.visitInsn(Opcodes.ICONST_0);
        node.visitTypeInsn(Opcodes.ANEWARRAY, ENUM_TYPE.getInternalName());
    }
    node.visitInsn(Opcodes.ARETURN);
    node.visitMaxs(isValueOf ? 3 : 2, isValueOf ? 1 : 0);
    return node;
}
Also used : KotlinType(org.jetbrains.kotlin.types.KotlinType) InstructionAdapter(org.jetbrains.org.objectweb.asm.commons.InstructionAdapter)

Example 4 with InstructionAdapter

use of org.jetbrains.org.objectweb.asm.commons.InstructionAdapter in project kotlin by JetBrains.

the class ImplementationBodyCodegen method generateSecondaryConstructorImpl.

private void generateSecondaryConstructorImpl(@NotNull ClassConstructorDescriptor constructorDescriptor, @NotNull ExpressionCodegen codegen) {
    InstructionAdapter iv = codegen.v;
    KtSecondaryConstructor constructor = (KtSecondaryConstructor) DescriptorToSourceUtils.descriptorToDeclaration(constructorDescriptor);
    markLineNumberForConstructor(constructorDescriptor, constructor, codegen);
    ResolvedCall<ConstructorDescriptor> constructorDelegationCall = getDelegationConstructorCall(bindingContext, constructorDescriptor);
    ConstructorDescriptor delegateConstructor = constructorDelegationCall == null ? null : constructorDelegationCall.getResultingDescriptor();
    generateDelegatorToConstructorCall(iv, codegen, constructorDescriptor, constructorDelegationCall);
    if (!isSameClassConstructor(delegateConstructor)) {
        // Initialization happens only for constructors delegating to super
        generateClosureInitialization(iv);
        generateInitializers(codegen);
    }
    assert constructor != null;
    if (constructor.hasBody()) {
        codegen.gen(constructor.getBodyExpression(), Type.VOID_TYPE);
    }
    iv.visitInsn(RETURN);
}
Also used : InstructionAdapter(org.jetbrains.org.objectweb.asm.commons.InstructionAdapter)

Example 5 with InstructionAdapter

use of org.jetbrains.org.objectweb.asm.commons.InstructionAdapter in project kotlin by JetBrains.

the class MemberCodegen method generateConstInstance.

protected void generateConstInstance(@NotNull Type thisAsmType, @NotNull Type fieldAsmType) {
    v.newField(JvmDeclarationOriginKt.OtherOrigin(element), ACC_STATIC | ACC_FINAL | ACC_PUBLIC, JvmAbi.INSTANCE_FIELD, fieldAsmType.getDescriptor(), null, null);
    if (state.getClassBuilderMode().generateBodies) {
        InstructionAdapter iv = createOrGetClInitCodegen().v;
        iv.anew(thisAsmType);
        iv.dup();
        iv.invokespecial(thisAsmType.getInternalName(), "<init>", "()V", false);
        iv.putstatic(thisAsmType.getInternalName(), JvmAbi.INSTANCE_FIELD, fieldAsmType.getDescriptor());
    }
}
Also used : InstructionAdapter(org.jetbrains.org.objectweb.asm.commons.InstructionAdapter)

Aggregations

InstructionAdapter (org.jetbrains.org.objectweb.asm.commons.InstructionAdapter)35 KotlinType (org.jetbrains.kotlin.types.KotlinType)23 Type (org.jetbrains.org.objectweb.asm.Type)16 IElementType (com.intellij.psi.tree.IElementType)10 Unit (kotlin.Unit)10 MethodVisitor (org.jetbrains.org.objectweb.asm.MethodVisitor)7 Label (org.jetbrains.org.objectweb.asm.Label)5 Method (org.jetbrains.org.objectweb.asm.commons.Method)5 JavaClassDescriptor (org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor)4 NotNull (org.jetbrains.annotations.NotNull)3 Type.getObjectType (org.jetbrains.org.objectweb.asm.Type.getObjectType)3 Nullable (org.jetbrains.annotations.Nullable)2 PrimitiveType (org.jetbrains.kotlin.builtins.PrimitiveType)2 JvmPrimitiveType (org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType)2 JvmMethodSignature (org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature)2 TypeUtils.isNullableType (org.jetbrains.kotlin.types.TypeUtils.isNullableType)2 TraceMethodVisitor (org.jetbrains.org.objectweb.asm.util.TraceMethodVisitor)2 Method (java.lang.reflect.Method)1 KotlinBuiltIns (org.jetbrains.kotlin.builtins.KotlinBuiltIns)1 AsmUtil.getVisibilityForBackingField (org.jetbrains.kotlin.codegen.AsmUtil.getVisibilityForBackingField)1