Search in sources :

Example 1 with JvmMethodSignature

use of org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature in project kotlin by JetBrains.

the class KotlinTypeMapper method mapToCallableMethod.

@NotNull
public CallableMethod mapToCallableMethod(@NotNull FunctionDescriptor descriptor, boolean superCall) {
    if (descriptor instanceof ConstructorDescriptor) {
        JvmMethodSignature method = mapSignatureSkipGeneric(descriptor.getOriginal());
        Type owner = mapOwner(descriptor);
        String defaultImplDesc = mapDefaultMethod(descriptor.getOriginal(), OwnerKind.IMPLEMENTATION).getDescriptor();
        return new CallableMethod(owner, owner, defaultImplDesc, method, INVOKESPECIAL, null, null, null, false);
    }
    if (descriptor instanceof LocalVariableAccessorDescriptor) {
        ResolvedCall<FunctionDescriptor> delegateAccessorResolvedCall = bindingContext.get(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, (VariableAccessorDescriptor) descriptor);
        //noinspection ConstantConditions
        return mapToCallableMethod(delegateAccessorResolvedCall.getResultingDescriptor(), false);
    }
    DeclarationDescriptor functionParent = descriptor.getOriginal().getContainingDeclaration();
    FunctionDescriptor functionDescriptor = findSuperDeclaration(descriptor.getOriginal(), superCall);
    JvmMethodSignature signature;
    Type owner;
    Type ownerForDefaultImpl;
    FunctionDescriptor baseMethodDescriptor;
    int invokeOpcode;
    Type thisClass;
    boolean isInterfaceMember = false;
    if (functionParent instanceof ClassDescriptor) {
        FunctionDescriptor declarationFunctionDescriptor = findAnyDeclaration(functionDescriptor);
        ClassDescriptor currentOwner = (ClassDescriptor) functionParent;
        ClassDescriptor declarationOwner = (ClassDescriptor) declarationFunctionDescriptor.getContainingDeclaration();
        boolean originalIsInterface = isJvmInterface(declarationOwner);
        boolean currentIsInterface = isJvmInterface(currentOwner);
        boolean isInterface = currentIsInterface && originalIsInterface;
        baseMethodDescriptor = findBaseDeclaration(functionDescriptor).getOriginal();
        ClassDescriptor ownerForDefault = (ClassDescriptor) baseMethodDescriptor.getContainingDeclaration();
        ownerForDefaultImpl = isJvmInterface(ownerForDefault) && !isJvm8InterfaceWithDefaults(ownerForDefault) ? mapDefaultImpls(ownerForDefault) : mapClass(ownerForDefault);
        if (isInterface && (superCall || descriptor.getVisibility() == Visibilities.PRIVATE || isAccessor(descriptor))) {
            thisClass = mapClass(currentOwner);
            if (declarationOwner instanceof JavaClassDescriptor || isJvm8InterfaceWithDefaults(declarationOwner)) {
                invokeOpcode = INVOKESPECIAL;
                signature = mapSignatureSkipGeneric(functionDescriptor);
                owner = thisClass;
                isInterfaceMember = true;
            } else {
                invokeOpcode = INVOKESTATIC;
                signature = mapSignatureSkipGeneric(descriptor.getOriginal(), OwnerKind.DEFAULT_IMPLS);
                owner = mapDefaultImpls(currentOwner);
            }
        } else {
            boolean isStaticInvocation = (isStaticDeclaration(functionDescriptor) && !(functionDescriptor instanceof ImportedFromObjectCallableDescriptor)) || isStaticAccessor(functionDescriptor) || CodegenUtilKt.isJvmStaticInObjectOrClass(functionDescriptor);
            if (isStaticInvocation) {
                invokeOpcode = INVOKESTATIC;
                isInterfaceMember = currentIsInterface && currentOwner instanceof JavaClassDescriptor;
            } else if (isInterface) {
                invokeOpcode = INVOKEINTERFACE;
                isInterfaceMember = true;
            } else {
                boolean isPrivateFunInvocation = Visibilities.isPrivate(functionDescriptor.getVisibility());
                invokeOpcode = superCall || isPrivateFunInvocation ? INVOKESPECIAL : INVOKEVIRTUAL;
                isInterfaceMember = superCall && currentIsInterface;
            }
            FunctionDescriptor overriddenSpecialBuiltinFunction = SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(functionDescriptor.getOriginal());
            FunctionDescriptor functionToCall = overriddenSpecialBuiltinFunction != null && !superCall ? overriddenSpecialBuiltinFunction.getOriginal() : functionDescriptor.getOriginal();
            signature = mapSignatureSkipGeneric(functionToCall);
            ClassDescriptor receiver = (currentIsInterface && !originalIsInterface) || currentOwner instanceof FunctionClassDescriptor ? declarationOwner : currentOwner;
            owner = mapClass(receiver);
            thisClass = owner;
        }
    } else {
        signature = mapSignatureSkipGeneric(functionDescriptor.getOriginal());
        owner = mapOwner(functionDescriptor);
        ownerForDefaultImpl = owner;
        baseMethodDescriptor = functionDescriptor;
        if (functionParent instanceof PackageFragmentDescriptor) {
            invokeOpcode = INVOKESTATIC;
            thisClass = null;
        } else if (functionDescriptor instanceof ConstructorDescriptor) {
            invokeOpcode = INVOKESPECIAL;
            thisClass = null;
        } else {
            invokeOpcode = INVOKEVIRTUAL;
            thisClass = owner;
        }
    }
    Type calleeType = isLocalFunction(functionDescriptor) ? owner : null;
    Type receiverParameterType;
    ReceiverParameterDescriptor receiverParameter = functionDescriptor.getOriginal().getExtensionReceiverParameter();
    if (receiverParameter != null) {
        receiverParameterType = mapType(receiverParameter.getType());
    } else {
        receiverParameterType = null;
    }
    String defaultImplDesc = mapDefaultMethod(baseMethodDescriptor, getKindForDefaultImplCall(baseMethodDescriptor)).getDescriptor();
    return new CallableMethod(owner, ownerForDefaultImpl, defaultImplDesc, signature, invokeOpcode, thisClass, receiverParameterType, calleeType, isJvm8Target ? isInterfaceMember : invokeOpcode == INVOKEINTERFACE);
}
Also used : LocalVariableAccessorDescriptor(org.jetbrains.kotlin.descriptors.impl.LocalVariableAccessorDescriptor) DeserializedClassDescriptor(org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor) FunctionClassDescriptor(org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor) JavaClassDescriptor(org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor) TypeAliasConstructorDescriptor(org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor) IrBuiltinsPackageFragmentDescriptor(org.jetbrains.kotlin.ir.descriptors.IrBuiltinsPackageFragmentDescriptor) JvmMethodSignature(org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature) FunctionClassDescriptor(org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor) Type(org.jetbrains.org.objectweb.asm.Type) JavaClassDescriptor(org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor) NotNull(org.jetbrains.annotations.NotNull)

Example 2 with JvmMethodSignature

use of org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature in project kotlin by JetBrains.

the class InlineCodegen method generateLambdaBody.

@NotNull
private SMAPAndMethodNode generateLambdaBody(@NotNull LambdaInfo info) {
    KtExpression declaration = info.getFunctionWithBodyOrCallableReference();
    FunctionDescriptor descriptor = info.getFunctionDescriptor();
    ClassContext closureContext = info.isPropertyReference() ? codegen.getContext().intoAnonymousClass(info.getClassDescriptor(), codegen, OwnerKind.IMPLEMENTATION) : codegen.getContext().intoClosure(descriptor, codegen, typeMapper);
    MethodContext context = closureContext.intoInlinedLambda(descriptor, info.isCrossInline, info.isPropertyReference());
    JvmMethodSignature jvmMethodSignature = typeMapper.mapSignatureSkipGeneric(descriptor);
    Method asmMethod = jvmMethodSignature.getAsmMethod();
    MethodNode methodNode = new MethodNode(InlineCodegenUtil.API, getMethodAsmFlags(descriptor, context.getContextKind(), state), asmMethod.getName(), asmMethod.getDescriptor(), null, null);
    MethodVisitor adapter = InlineCodegenUtil.wrapWithMaxLocalCalc(methodNode);
    SMAP smap = generateMethodBody(adapter, descriptor, context, declaration, jvmMethodSignature, codegen, info);
    adapter.visitMaxs(-1, -1);
    return new SMAPAndMethodNode(methodNode, smap);
}
Also used : JvmMethodSignature(org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature) MethodNode(org.jetbrains.org.objectweb.asm.tree.MethodNode) Method(org.jetbrains.org.objectweb.asm.commons.Method) MethodVisitor(org.jetbrains.org.objectweb.asm.MethodVisitor) NotNull(org.jetbrains.annotations.NotNull)

Example 3 with JvmMethodSignature

use of org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature in project kotlin by JetBrains.

the class InlineCodegen method getInlineCallSiteInfo.

@NotNull
private InlineCallSiteInfo getInlineCallSiteInfo() {
    MethodContext context = codegen.getContext();
    MemberCodegen<?> parentCodegen = codegen.getParentCodegen();
    while (context instanceof InlineLambdaContext) {
        CodegenContext closureContext = context.getParentContext();
        assert closureContext instanceof ClosureContext : "Parent context of inline lambda should be closure context";
        assert closureContext.getParentContext() instanceof MethodContext : "Closure context should appear in method context";
        context = (MethodContext) closureContext.getParentContext();
        assert parentCodegen instanceof FakeMemberCodegen : "Parent codegen of inlined lambda should be FakeMemberCodegen";
        parentCodegen = ((FakeMemberCodegen) parentCodegen).delegate;
    }
    JvmMethodSignature signature = typeMapper.mapSignatureSkipGeneric(context.getFunctionDescriptor(), context.getContextKind());
    return new InlineCallSiteInfo(parentCodegen.getClassName(), signature.getAsmMethod().getName(), signature.getAsmMethod().getDescriptor());
}
Also used : JvmMethodSignature(org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature) NotNull(org.jetbrains.annotations.NotNull)

Example 4 with JvmMethodSignature

use of org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature in project kotlin by JetBrains.

the class FunctionCodegen method generateDefaultImplBody.

public static void generateDefaultImplBody(@NotNull MethodContext methodContext, @NotNull FunctionDescriptor functionDescriptor, @NotNull MethodVisitor mv, @NotNull DefaultParameterValueLoader loadStrategy, @Nullable KtNamedFunction function, @NotNull MemberCodegen<?> parentCodegen, @NotNull Method defaultMethod) {
    GenerationState state = parentCodegen.state;
    JvmMethodSignature signature = state.getTypeMapper().mapSignatureWithGeneric(functionDescriptor, methodContext.getContextKind());
    boolean isStatic = isStaticMethod(methodContext.getContextKind(), functionDescriptor);
    FrameMap frameMap = createFrameMap(state, functionDescriptor, signature, isStatic);
    ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, signature.getReturnType(), methodContext, state, parentCodegen);
    CallGenerator generator = codegen.getOrCreateCallGeneratorForDefaultImplBody(functionDescriptor, function);
    InstructionAdapter iv = new InstructionAdapter(mv);
    genDefaultSuperCallCheckIfNeeded(iv, functionDescriptor, defaultMethod);
    List<JvmMethodParameterSignature> mappedParameters = signature.getValueParameters();
    int capturedArgumentsCount = 0;
    while (capturedArgumentsCount < mappedParameters.size() && mappedParameters.get(capturedArgumentsCount).getKind() != JvmMethodParameterKind.VALUE) {
        capturedArgumentsCount++;
    }
    int maskIndex = 0;
    List<ValueParameterDescriptor> valueParameters = functionDescriptor.getValueParameters();
    for (int index = 0; index < valueParameters.size(); index++) {
        if (index % Integer.SIZE == 0) {
            maskIndex = frameMap.enterTemp(Type.INT_TYPE);
        }
        ValueParameterDescriptor parameterDescriptor = valueParameters.get(index);
        Type type = mappedParameters.get(capturedArgumentsCount + index).getAsmType();
        int parameterIndex = frameMap.getIndex(parameterDescriptor);
        if (parameterDescriptor.declaresDefaultValue()) {
            iv.load(maskIndex, Type.INT_TYPE);
            iv.iconst(1 << (index % Integer.SIZE));
            iv.and(Type.INT_TYPE);
            Label loadArg = new Label();
            iv.ifeq(loadArg);
            StackValue.local(parameterIndex, type).store(loadStrategy.genValue(parameterDescriptor, codegen), iv);
            iv.mark(loadArg);
        }
    }
    // load arguments after defaults generation to avoid redundant stack normalization operations
    loadExplicitArgumentsOnStack(OBJECT_TYPE, isStatic, signature, generator);
    for (int index = 0; index < valueParameters.size(); index++) {
        ValueParameterDescriptor parameterDescriptor = valueParameters.get(index);
        Type type = mappedParameters.get(capturedArgumentsCount + index).getAsmType();
        int parameterIndex = frameMap.getIndex(parameterDescriptor);
        generator.putValueIfNeeded(type, StackValue.local(parameterIndex, type));
    }
    CallableMethod method = state.getTypeMapper().mapToCallableMethod(functionDescriptor, false);
    generator.genCall(method, null, false, codegen);
    iv.areturn(signature.getReturnType());
}
Also used : JvmMethodParameterSignature(org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature) GenerationState(org.jetbrains.kotlin.codegen.state.GenerationState) JvmMethodSignature(org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature) KotlinType(org.jetbrains.kotlin.types.KotlinType) InstructionAdapter(org.jetbrains.org.objectweb.asm.commons.InstructionAdapter)

Example 5 with JvmMethodSignature

use of org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature in project kotlin by JetBrains.

the class ImplementationBodyCodegen method generatePrimaryConstructor.

private void generatePrimaryConstructor(final DelegationFieldsInfo delegationFieldsInfo) {
    if (isInterface(descriptor) || isAnnotationClass(descriptor))
        return;
    final ClassConstructorDescriptor constructorDescriptor = descriptor.getUnsubstitutedPrimaryConstructor();
    if (constructorDescriptor == null)
        return;
    ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor);
    final KtPrimaryConstructor primaryConstructor = myClass.getPrimaryConstructor();
    JvmDeclarationOrigin origin = JvmDeclarationOriginKt.OtherOrigin(primaryConstructor != null ? primaryConstructor : myClass.getPsiOrParent(), constructorDescriptor);
    functionCodegen.generateMethod(origin, constructorDescriptor, constructorContext, new FunctionGenerationStrategy.CodegenBased(state) {

        @Override
        public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
            generatePrimaryConstructorImpl(constructorDescriptor, codegen, delegationFieldsInfo, primaryConstructor);
        }
    });
    functionCodegen.generateDefaultIfNeeded(constructorContext, constructorDescriptor, OwnerKind.IMPLEMENTATION, DefaultParameterValueLoader.DEFAULT, null);
    new DefaultParameterValueSubstitutor(state).generatePrimaryConstructorOverloadsIfNeeded(constructorDescriptor, v, this, kind, myClass);
}
Also used : JvmMethodSignature(org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature) JvmDeclarationOrigin(org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin)

Aggregations

JvmMethodSignature (org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature)7 NotNull (org.jetbrains.annotations.NotNull)3 KotlinType (org.jetbrains.kotlin.types.KotlinType)2 MethodVisitor (org.jetbrains.org.objectweb.asm.MethodVisitor)2 Type (org.jetbrains.org.objectweb.asm.Type)2 InstructionAdapter (org.jetbrains.org.objectweb.asm.commons.InstructionAdapter)2 Method (org.jetbrains.org.objectweb.asm.commons.Method)2 FunctionClassDescriptor (org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor)1 GenerationState (org.jetbrains.kotlin.codegen.state.GenerationState)1 ClassDescriptor (org.jetbrains.kotlin.descriptors.ClassDescriptor)1 ConstructorDescriptor (org.jetbrains.kotlin.descriptors.ConstructorDescriptor)1 ScriptDescriptor (org.jetbrains.kotlin.descriptors.ScriptDescriptor)1 ValueParameterDescriptor (org.jetbrains.kotlin.descriptors.ValueParameterDescriptor)1 LocalVariableAccessorDescriptor (org.jetbrains.kotlin.descriptors.impl.LocalVariableAccessorDescriptor)1 TypeAliasConstructorDescriptor (org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor)1 IrBuiltinsPackageFragmentDescriptor (org.jetbrains.kotlin.ir.descriptors.IrBuiltinsPackageFragmentDescriptor)1 JavaClassDescriptor (org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor)1 JvmDeclarationOrigin (org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin)1 JvmMethodGenericSignature (org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature)1 JvmMethodParameterSignature (org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature)1