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);
}
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);
}
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());
}
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());
}
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);
}
Aggregations