Search in sources :

Example 56 with Type

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

the class InlineCodegen method generateMethodBody.

@NotNull
private static SMAP generateMethodBody(@NotNull MethodVisitor adapter, @NotNull FunctionDescriptor descriptor, @NotNull MethodContext context, @NotNull KtExpression expression, @NotNull JvmMethodSignature jvmMethodSignature, @NotNull ExpressionCodegen codegen, @Nullable LambdaInfo lambdaInfo) {
    boolean isLambda = lambdaInfo != null;
    GenerationState state = codegen.getState();
    // Wrapping for preventing marking actual parent codegen as containing reified markers
    FakeMemberCodegen parentCodegen = new FakeMemberCodegen(codegen.getParentCodegen(), expression, (FieldOwnerContext) context.getParentContext(), isLambda ? codegen.getParentCodegen().getClassName() : state.getTypeMapper().mapImplementationOwner(descriptor).getInternalName());
    FunctionGenerationStrategy strategy;
    if (expression instanceof KtCallableReferenceExpression) {
        KtCallableReferenceExpression callableReferenceExpression = (KtCallableReferenceExpression) expression;
        KtExpression receiverExpression = callableReferenceExpression.getReceiverExpression();
        Type receiverType = receiverExpression != null && codegen.getBindingContext().getType(receiverExpression) != null ? codegen.getState().getTypeMapper().mapType(codegen.getBindingContext().getType(receiverExpression)) : null;
        if (isLambda && lambdaInfo.isPropertyReference()) {
            Type asmType = state.getTypeMapper().mapClass(lambdaInfo.getClassDescriptor());
            PropertyReferenceInfo info = lambdaInfo.getPropertyReferenceInfo();
            strategy = new PropertyReferenceCodegen.PropertyReferenceGenerationStrategy(true, info.getGetFunction(), info.getTarget(), asmType, receiverType, lambdaInfo.expression, state, true);
        } else {
            strategy = new FunctionReferenceGenerationStrategy(state, descriptor, CallUtilKt.getResolvedCallWithAssert(callableReferenceExpression.getCallableReference(), codegen.getBindingContext()), receiverType, null, true);
        }
    } else if (expression instanceof KtFunctionLiteral) {
        strategy = new ClosureGenerationStrategy(state, (KtDeclarationWithBody) expression);
    } else if (descriptor.isSuspend() && expression instanceof KtFunction) {
        strategy = new SuspendFunctionGenerationStrategy(state, CoroutineCodegenUtilKt.<FunctionDescriptor>unwrapInitialDescriptorForSuspendFunction(descriptor), (KtFunction) expression);
    } else {
        strategy = new FunctionGenerationStrategy.FunctionDefault(state, (KtDeclarationWithBody) expression);
    }
    FunctionCodegen.generateMethodBody(adapter, descriptor, context, jvmMethodSignature, strategy, parentCodegen);
    if (isLambda) {
        codegen.propagateChildReifiedTypeParametersUsages(parentCodegen.getReifiedTypeParametersUsages());
    }
    return createSMAPWithDefaultMapping(expression, parentCodegen.getOrCreateSourceMapper().getResultMappings());
}
Also used : SuspendFunctionGenerationStrategy(org.jetbrains.kotlin.codegen.coroutines.SuspendFunctionGenerationStrategy) GenerationState(org.jetbrains.kotlin.codegen.state.GenerationState) Type(org.jetbrains.org.objectweb.asm.Type) KotlinType(org.jetbrains.kotlin.types.KotlinType) SuspendFunctionGenerationStrategy(org.jetbrains.kotlin.codegen.coroutines.SuspendFunctionGenerationStrategy) NotNull(org.jetbrains.annotations.NotNull)

Example 57 with Type

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

the class InlineCodegen method doCreateMethodNodeFromSource.

@NotNull
private static SMAPAndMethodNode doCreateMethodNodeFromSource(@NotNull FunctionDescriptor callableDescriptor, @NotNull JvmMethodSignature jvmSignature, @NotNull ExpressionCodegen codegen, @NotNull CodegenContext context, boolean callDefault, @NotNull GenerationState state, @NotNull Method asmMethod) {
    PsiElement element = DescriptorToSourceUtils.descriptorToDeclaration(callableDescriptor);
    if (!(element instanceof KtNamedFunction || element instanceof KtPropertyAccessor)) {
        throw new IllegalStateException("Couldn't find declaration for function " + callableDescriptor);
    }
    KtDeclarationWithBody inliningFunction = (KtDeclarationWithBody) element;
    MethodNode node = new MethodNode(InlineCodegenUtil.API, getMethodAsmFlags(callableDescriptor, context.getContextKind(), state) | (callDefault ? Opcodes.ACC_STATIC : 0), asmMethod.getName(), asmMethod.getDescriptor(), null, null);
    //for maxLocals calculation
    MethodVisitor maxCalcAdapter = InlineCodegenUtil.wrapWithMaxLocalCalc(node);
    CodegenContext parentContext = context.getParentContext();
    assert parentContext != null : "Context has no parent: " + context;
    MethodContext methodContext = parentContext.intoFunction(callableDescriptor);
    SMAP smap;
    if (callDefault) {
        Type implementationOwner = state.getTypeMapper().mapImplementationOwner(callableDescriptor);
        FakeMemberCodegen parentCodegen = new FakeMemberCodegen(codegen.getParentCodegen(), inliningFunction, (FieldOwnerContext) methodContext.getParentContext(), implementationOwner.getInternalName());
        if (!(element instanceof KtNamedFunction)) {
            throw new IllegalStateException("Propertiy accessors with default parameters not supported " + callableDescriptor);
        }
        FunctionCodegen.generateDefaultImplBody(methodContext, callableDescriptor, maxCalcAdapter, DefaultParameterValueLoader.DEFAULT, (KtNamedFunction) inliningFunction, parentCodegen, asmMethod);
        smap = createSMAPWithDefaultMapping(inliningFunction, parentCodegen.getOrCreateSourceMapper().getResultMappings());
    } else {
        smap = generateMethodBody(maxCalcAdapter, callableDescriptor, methodContext, inliningFunction, jvmSignature, codegen, null);
    }
    maxCalcAdapter.visitMaxs(-1, -1);
    maxCalcAdapter.visitEnd();
    return new SMAPAndMethodNode(node, smap);
}
Also used : MethodVisitor(org.jetbrains.org.objectweb.asm.MethodVisitor) Type(org.jetbrains.org.objectweb.asm.Type) KotlinType(org.jetbrains.kotlin.types.KotlinType) MethodNode(org.jetbrains.org.objectweb.asm.tree.MethodNode) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 58 with Type

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

the class SamWrapperCodegen method genWrapper.

@NotNull
public Type genWrapper(@NotNull KtFile file) {
    // Name for generated class, in form of whatever$1
    FqName fqName = getWrapperName(file);
    Type asmType = asmTypeByFqNameWithoutInnerClasses(fqName);
    // e.g. (T, T) -> Int
    KotlinType functionType = samType.getKotlinFunctionType();
    ClassDescriptor classDescriptor = new ClassDescriptorImpl(samType.getJavaClassDescriptor().getContainingDeclaration(), fqName.shortName(), Modality.FINAL, ClassKind.CLASS, Collections.singleton(samType.getType()), SourceElement.NO_SOURCE, /* isExternal = */
    false);
    // e.g. compare(T, T)
    SimpleFunctionDescriptor erasedInterfaceFunction = samType.getAbstractMethod().getOriginal().copy(classDescriptor, Modality.FINAL, Visibilities.PUBLIC, CallableMemberDescriptor.Kind.SYNTHESIZED, /*copyOverrides=*/
    false);
    ClassBuilder cv = state.getFactory().newVisitor(JvmDeclarationOriginKt.OtherOrigin(erasedInterfaceFunction), asmType, file);
    cv.defineClass(file, state.getClassFileVersion(), ACC_FINAL | ACC_SUPER | visibility, asmType.getInternalName(), null, OBJECT_TYPE.getInternalName(), new String[] { typeMapper.mapType(samType.getType()).getInternalName() });
    cv.visitSource(file.getName(), null);
    WriteAnnotationUtilKt.writeSyntheticClassMetadata(cv, state);
    // e.g. ASM type for Function2
    Type functionAsmType = typeMapper.mapType(functionType);
    cv.newField(JvmDeclarationOriginKt.OtherOrigin(erasedInterfaceFunction), ACC_SYNTHETIC | ACC_PRIVATE | ACC_FINAL, FUNCTION_FIELD_NAME, functionAsmType.getDescriptor(), null, null);
    generateConstructor(asmType, functionAsmType, cv);
    generateMethod(asmType, functionAsmType, cv, erasedInterfaceFunction, functionType);
    cv.done();
    return asmType;
}
Also used : KotlinType(org.jetbrains.kotlin.types.KotlinType) Type(org.jetbrains.org.objectweb.asm.Type) JavaClassDescriptor(org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor) FqName(org.jetbrains.kotlin.name.FqName) KotlinType(org.jetbrains.kotlin.types.KotlinType) ClassDescriptorImpl(org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl) NotNull(org.jetbrains.annotations.NotNull)

Example 59 with Type

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

the class ScriptCodegen method genConstructor.

private void genConstructor(@NotNull ScriptDescriptor scriptDescriptor, @NotNull ClassBuilder classBuilder, @NotNull MethodContext methodContext) {
    JvmMethodSignature jvmSignature = typeMapper.mapScriptSignature(scriptDescriptor, context.getEarlierScripts());
    if (state.getReplSpecific().getShouldGenerateScriptResultValue()) {
        FieldInfo resultFieldInfo = context.getResultFieldInfo();
        classBuilder.newField(JvmDeclarationOrigin.NO_ORIGIN, ACC_PUBLIC | ACC_FINAL, resultFieldInfo.getFieldName(), resultFieldInfo.getFieldType().getDescriptor(), null, null);
    }
    MethodVisitor mv = classBuilder.newMethod(JvmDeclarationOriginKt.OtherOrigin(scriptDeclaration, scriptDescriptor.getUnsubstitutedPrimaryConstructor()), ACC_PUBLIC, jvmSignature.getAsmMethod().getName(), jvmSignature.getAsmMethod().getDescriptor(), null, null);
    if (state.getClassBuilderMode().generateBodies) {
        mv.visitCode();
        InstructionAdapter iv = new InstructionAdapter(mv);
        Type classType = typeMapper.mapType(scriptDescriptor);
        ClassDescriptor superclass = DescriptorUtilsKt.getSuperClassNotAny(scriptDescriptor);
        if (superclass == null) {
            iv.load(0, classType);
            iv.invokespecial("java/lang/Object", "<init>", "()V", false);
        } else {
            ConstructorDescriptor ctorDesc = superclass.getUnsubstitutedPrimaryConstructor();
            if (ctorDesc == null)
                throw new RuntimeException("Primary constructor not found for script template " + superclass.toString());
            iv.load(0, classType);
            int valueParamStart = context.getEarlierScripts().size() + 1;
            List<ValueParameterDescriptor> valueParameters = scriptDescriptor.getUnsubstitutedPrimaryConstructor().getValueParameters();
            for (ValueParameterDescriptor superclassParam : ctorDesc.getValueParameters()) {
                ValueParameterDescriptor valueParam = null;
                for (ValueParameterDescriptor vpd : valueParameters) {
                    if (vpd.getName().equals(superclassParam.getName())) {
                        valueParam = vpd;
                        break;
                    }
                }
                assert valueParam != null;
                iv.load(valueParam.getIndex() + valueParamStart, typeMapper.mapType(valueParam.getType()));
            }
            CallableMethod ctorMethod = typeMapper.mapToCallableMethod(ctorDesc, false);
            String sig = ctorMethod.getAsmMethod().getDescriptor();
            iv.invokespecial(typeMapper.mapSupertype(superclass.getDefaultType(), null).getInternalName(), "<init>", sig, false);
        }
        iv.load(0, classType);
        FrameMap frameMap = new FrameMap();
        frameMap.enterTemp(OBJECT_TYPE);
        for (ScriptDescriptor importedScript : context.getEarlierScripts()) {
            frameMap.enter(importedScript, OBJECT_TYPE);
        }
        int offset = 1;
        for (ScriptDescriptor earlierScript : context.getEarlierScripts()) {
            Type earlierClassType = typeMapper.mapClass(earlierScript);
            iv.load(0, classType);
            iv.load(offset, earlierClassType);
            offset += earlierClassType.getSize();
            iv.putfield(classType.getInternalName(), context.getScriptFieldName(earlierScript), earlierClassType.getDescriptor());
        }
        final ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, methodContext, state, this);
        generateInitializers(new Function0<ExpressionCodegen>() {

            @Override
            public ExpressionCodegen invoke() {
                return codegen;
            }
        });
        iv.areturn(Type.VOID_TYPE);
    }
    mv.visitMaxs(-1, -1);
    mv.visitEnd();
}
Also used : ClassDescriptor(org.jetbrains.kotlin.descriptors.ClassDescriptor) ConstructorDescriptor(org.jetbrains.kotlin.descriptors.ConstructorDescriptor) ScriptDescriptor(org.jetbrains.kotlin.descriptors.ScriptDescriptor) MethodVisitor(org.jetbrains.org.objectweb.asm.MethodVisitor) JvmMethodSignature(org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature) Type(org.jetbrains.org.objectweb.asm.Type) InstructionAdapter(org.jetbrains.org.objectweb.asm.commons.InstructionAdapter) ValueParameterDescriptor(org.jetbrains.kotlin.descriptors.ValueParameterDescriptor)

Example 60 with Type

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

the class ScriptCodegen method genFieldsForParameters.

private void genFieldsForParameters(@NotNull ClassBuilder classBuilder) {
    for (ScriptDescriptor earlierScript : context.getEarlierScripts()) {
        Type earlierClassName = typeMapper.mapType(earlierScript);
        int access = ACC_PUBLIC | ACC_FINAL;
        classBuilder.newField(NO_ORIGIN, access, context.getScriptFieldName(earlierScript), earlierClassName.getDescriptor(), null, null);
    }
}
Also used : Type(org.jetbrains.org.objectweb.asm.Type) ScriptDescriptor(org.jetbrains.kotlin.descriptors.ScriptDescriptor)

Aggregations

Type (org.jetbrains.org.objectweb.asm.Type)104 KotlinType (org.jetbrains.kotlin.types.KotlinType)66 IElementType (com.intellij.psi.tree.IElementType)45 NotNull (org.jetbrains.annotations.NotNull)23 InstructionAdapter (org.jetbrains.org.objectweb.asm.commons.InstructionAdapter)16 Label (org.jetbrains.org.objectweb.asm.Label)12 Type.getObjectType (org.jetbrains.org.objectweb.asm.Type.getObjectType)10 Method (org.jetbrains.org.objectweb.asm.commons.Method)9 Unit (kotlin.Unit)8 LocalVariableDescriptor (org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor)7 ArrayList (java.util.ArrayList)5 JavaClassDescriptor (org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor)5 MethodVisitor (org.jetbrains.org.objectweb.asm.MethodVisitor)5 PrimitiveType (org.jetbrains.kotlin.builtins.PrimitiveType)4 ValueParameterDescriptor (org.jetbrains.kotlin.descriptors.ValueParameterDescriptor)4 List (java.util.List)3 Nullable (org.jetbrains.annotations.Nullable)3 ScriptDescriptor (org.jetbrains.kotlin.descriptors.ScriptDescriptor)3 InOut (com.intellij.codeInspection.bytecodeAnalysis.Direction.InOut)2 FunctionClassDescriptor (org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor)2