use of org.jetbrains.org.objectweb.asm.commons.Method in project kotlin by JetBrains.
the class FunctionCodegen method generateMethod.
public void generateMethod(@NotNull JvmDeclarationOrigin origin, @NotNull FunctionDescriptor functionDescriptor, @NotNull MethodContext methodContext, @NotNull FunctionGenerationStrategy strategy) {
OwnerKind contextKind = methodContext.getContextKind();
if (isInterface(functionDescriptor.getContainingDeclaration()) && functionDescriptor.getVisibility() == Visibilities.PRIVATE && !processInterfaceMember(functionDescriptor, contextKind, state)) {
return;
}
JvmMethodGenericSignature jvmSignature = typeMapper.mapSignatureWithGeneric(functionDescriptor, contextKind);
Method asmMethod = jvmSignature.getAsmMethod();
int flags = getMethodAsmFlags(functionDescriptor, contextKind, state);
if (origin.getOriginKind() == JvmDeclarationOriginKind.SAM_DELEGATION) {
flags |= ACC_SYNTHETIC;
}
if (functionDescriptor.isExternal() && owner instanceof MultifileClassFacadeContext) {
// Native methods are only defined in facades and do not need package part implementations
return;
}
MethodVisitor mv = v.newMethod(origin, flags, asmMethod.getName(), asmMethod.getDescriptor(), jvmSignature.getGenericsSignature(), getThrownExceptions(functionDescriptor, typeMapper));
if (CodegenContextUtil.isImplClassOwner(owner)) {
v.getSerializationBindings().put(METHOD_FOR_FUNCTION, CodegenUtilKt.<FunctionDescriptor>unwrapFrontendVersion(functionDescriptor), asmMethod);
}
generateMethodAnnotations(functionDescriptor, asmMethod, mv);
JvmMethodSignature signature = typeMapper.mapSignatureSkipGeneric(functionDescriptor);
generateParameterAnnotations(functionDescriptor, mv, signature);
GenerateJava8ParameterNamesKt.generateParameterNames(functionDescriptor, mv, signature, state, (flags & ACC_SYNTHETIC) != 0);
generateBridges(functionDescriptor);
if (isJvm8InterfaceWithDefaultsMember(functionDescriptor, state) && contextKind != OwnerKind.DEFAULT_IMPLS && state.getGenerateDefaultImplsForJvm8()) {
generateDelegateForDefaultImpl(functionDescriptor, origin.getElement());
}
boolean staticInCompanionObject = CodegenUtilKt.isJvmStaticInCompanionObject(functionDescriptor);
if (staticInCompanionObject) {
ImplementationBodyCodegen parentBodyCodegen = (ImplementationBodyCodegen) memberCodegen.getParentCodegen();
parentBodyCodegen.addAdditionalTask(new JvmStaticInCompanionObjectGenerator(functionDescriptor, origin, state, parentBodyCodegen));
}
if (!state.getClassBuilderMode().generateBodies || isAbstractMethod(functionDescriptor, contextKind, state)) {
generateLocalVariableTable(mv, jvmSignature, functionDescriptor, getThisTypeForFunction(functionDescriptor, methodContext, typeMapper), new Label(), new Label(), contextKind, typeMapper, 0);
mv.visitEnd();
return;
}
if (!functionDescriptor.isExternal()) {
generateMethodBody(mv, functionDescriptor, methodContext, jvmSignature, strategy, memberCodegen);
} else if (staticInCompanionObject) {
// native @JvmStatic foo() in companion object should delegate to the static native function moved to the outer class
mv.visitCode();
FunctionDescriptor staticFunctionDescriptor = JvmStaticInCompanionObjectGenerator.createStaticFunctionDescriptor(functionDescriptor);
Method accessorMethod = typeMapper.mapAsmMethod(memberCodegen.getContext().accessibleDescriptor(staticFunctionDescriptor, null));
Type owningType = typeMapper.mapClass((ClassifierDescriptor) staticFunctionDescriptor.getContainingDeclaration());
generateDelegateToStaticMethodBody(false, mv, accessorMethod, owningType.getInternalName());
}
endVisit(mv, null, origin.getElement());
}
use of org.jetbrains.org.objectweb.asm.commons.Method in project kotlin by JetBrains.
the class ExpressionCodegen method visitObjectLiteralExpression.
@Override
public StackValue visitObjectLiteralExpression(@NotNull KtObjectLiteralExpression expression, StackValue receiver) {
final ObjectLiteralResult objectLiteralResult = generateObjectLiteral(expression);
final ClassDescriptor classDescriptor = objectLiteralResult.classDescriptor;
final Type type = typeMapper.mapType(classDescriptor);
return StackValue.operation(type, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter v) {
if (objectLiteralResult.wereReifiedMarkers) {
ReifiedTypeInliner.putNeedClassReificationMarker(v);
}
v.anew(type);
v.dup();
pushClosureOnStack(classDescriptor, true, defaultCallGenerator, /* functionReferenceReceiver = */
null);
ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor();
assert primaryConstructor != null : "There should be primary constructor for object literal";
ResolvedCall<ConstructorDescriptor> superCall = getDelegationConstructorCall(bindingContext, primaryConstructor);
if (superCall != null) {
// For an anonymous object, we should also generate all non-default arguments that it captures for its super call
ConstructorDescriptor superConstructor = superCall.getResultingDescriptor();
ConstructorDescriptor constructorToCall = SamCodegenUtil.resolveSamAdapter(superConstructor);
List<ValueParameterDescriptor> superValueParameters = superConstructor.getValueParameters();
int params = superValueParameters.size();
List<Type> superMappedTypes = typeMapper.mapToCallableMethod(constructorToCall, false).getValueParameterTypes();
assert superMappedTypes.size() >= params : String.format("Incorrect number of mapped parameters vs arguments: %d < %d for %s", superMappedTypes.size(), params, classDescriptor);
List<ResolvedValueArgument> valueArguments = new ArrayList<ResolvedValueArgument>(params);
List<ValueParameterDescriptor> valueParameters = new ArrayList<ValueParameterDescriptor>(params);
List<Type> mappedTypes = new ArrayList<Type>(params);
for (ValueParameterDescriptor parameter : superValueParameters) {
ResolvedValueArgument argument = superCall.getValueArguments().get(parameter);
if (!(argument instanceof DefaultValueArgument)) {
valueArguments.add(argument);
valueParameters.add(parameter);
mappedTypes.add(superMappedTypes.get(parameter.getIndex()));
}
}
ArgumentGenerator argumentGenerator = new CallBasedArgumentGenerator(ExpressionCodegen.this, defaultCallGenerator, valueParameters, mappedTypes);
argumentGenerator.generate(valueArguments, valueArguments, null);
}
Collection<ClassConstructorDescriptor> constructors = classDescriptor.getConstructors();
assert constructors.size() == 1 : "Unexpected number of constructors for class: " + classDescriptor + " " + constructors;
ConstructorDescriptor constructorDescriptor = CollectionsKt.single(constructors);
Method constructor = typeMapper.mapAsmMethod(SamCodegenUtil.resolveSamAdapter(constructorDescriptor));
v.invokespecial(type.getInternalName(), "<init>", constructor.getDescriptor(), false);
return Unit.INSTANCE;
}
});
}
use of org.jetbrains.org.objectweb.asm.commons.Method in project kotlin by JetBrains.
the class SignaturesPropagationData method getSuperFunctionsForMethod.
private static List<FunctionDescriptor> getSuperFunctionsForMethod(@NotNull JavaMethod method, @NotNull JavaMethodDescriptor autoMethodDescriptor, @NotNull ClassDescriptor containingClass) {
List<FunctionDescriptor> superFunctions = Lists.newArrayList();
// TODO: Add propagation for other kotlin descriptors (KT-3621)
Name name = method.getName();
Method autoSignature = null;
boolean autoMethodContainsVararg = SignaturePropagationUtilKt.containsVarargs(autoMethodDescriptor);
for (KotlinType supertype : containingClass.getTypeConstructor().getSupertypes()) {
Collection<SimpleFunctionDescriptor> superFunctionCandidates = supertype.getMemberScope().getContributedFunctions(name, NoLookupLocation.WHEN_GET_SUPER_MEMBERS);
if (!autoMethodContainsVararg && !SignaturePropagationUtilKt.containsAnyNotTrivialSignature(superFunctionCandidates))
continue;
if (autoSignature == null) {
autoSignature = SIGNATURE_MAPPER.mapToJvmMethodSignature(autoMethodDescriptor);
}
for (FunctionDescriptor candidate : superFunctionCandidates) {
// TODO: remove this continue when KT-15747 is fixed
if (candidate.isSuspend())
continue;
Method candidateSignature = SIGNATURE_MAPPER.mapToJvmMethodSignature(candidate);
if (KotlinToJvmSignatureMapperKt.erasedSignaturesEqualIgnoringReturnTypes(autoSignature, candidateSignature)) {
superFunctions.add(candidate);
}
}
}
// sorting for diagnostic stability
Collections.sort(superFunctions, new Comparator<FunctionDescriptor>() {
@Override
public int compare(@NotNull FunctionDescriptor fun1, @NotNull FunctionDescriptor fun2) {
FqNameUnsafe fqName1 = getFqName(fun1.getContainingDeclaration());
FqNameUnsafe fqName2 = getFqName(fun2.getContainingDeclaration());
return fqName1.asString().compareTo(fqName2.asString());
}
});
return superFunctions;
}
use of org.jetbrains.org.objectweb.asm.commons.Method in project kotlin by JetBrains.
the class ClosureCodegen method generateKotlinMetadataAnnotation.
@Override
protected void generateKotlinMetadataAnnotation() {
FunctionDescriptor frontendFunDescriptor = CodegenUtilKt.unwrapFrontendVersion(funDescriptor);
FunctionDescriptor freeLambdaDescriptor = createFreeLambdaDescriptor(frontendFunDescriptor);
Method method = v.getSerializationBindings().get(METHOD_FOR_FUNCTION, frontendFunDescriptor);
assert method != null : "No method for " + frontendFunDescriptor;
v.getSerializationBindings().put(METHOD_FOR_FUNCTION, freeLambdaDescriptor, method);
final DescriptorSerializer serializer = DescriptorSerializer.createForLambda(new JvmSerializerExtension(v.getSerializationBindings(), state));
final ProtoBuf.Function functionProto = serializer.functionProto(freeLambdaDescriptor).build();
WriteAnnotationUtilKt.writeKotlinMetadata(v, state, KotlinClassHeader.Kind.SYNTHETIC_CLASS, 0, new Function1<AnnotationVisitor, Unit>() {
@Override
public Unit invoke(AnnotationVisitor av) {
writeAnnotationData(av, serializer, functionProto);
return Unit.INSTANCE;
}
});
}
use of org.jetbrains.org.objectweb.asm.commons.Method in project kotlin by JetBrains.
the class ClosureCodegen method generateConstructor.
@NotNull
protected Method generateConstructor() {
List<FieldInfo> args = calculateConstructorParameters(typeMapper, closure, asmType);
Type[] argTypes = fieldListToTypeArray(args);
Method constructor = new Method("<init>", Type.VOID_TYPE, argTypes);
MethodVisitor mv = v.newMethod(JvmDeclarationOriginKt.OtherOrigin(element, funDescriptor), visibilityFlag, "<init>", constructor.getDescriptor(), null, ArrayUtil.EMPTY_STRING_ARRAY);
if (state.getClassBuilderMode().generateBodies) {
mv.visitCode();
InstructionAdapter iv = new InstructionAdapter(mv);
Pair<Integer, Type> receiverIndexAndType = CallableReferenceUtilKt.generateClosureFieldsInitializationFromParameters(iv, closure, args);
if (shouldHaveBoundReferenceReceiver && receiverIndexAndType == null) {
throw new AssertionError("No bound reference receiver in constructor parameters: " + args);
}
int boundReferenceReceiverParameterIndex = shouldHaveBoundReferenceReceiver ? receiverIndexAndType.getFirst() : -1;
Type boundReferenceReceiverType = shouldHaveBoundReferenceReceiver ? receiverIndexAndType.getSecond() : null;
iv.load(0, superClassAsmType);
String superClassConstructorDescriptor;
if (superClassAsmType.equals(LAMBDA) || superClassAsmType.equals(FUNCTION_REFERENCE) || superClassAsmType.equals(CoroutineCodegenUtilKt.COROUTINE_IMPL_ASM_TYPE)) {
int arity = calculateArity();
iv.iconst(arity);
if (shouldHaveBoundReferenceReceiver) {
CallableReferenceUtilKt.loadBoundReferenceReceiverParameter(iv, boundReferenceReceiverParameterIndex, boundReferenceReceiverType);
superClassConstructorDescriptor = "(ILjava/lang/Object;)V";
} else {
superClassConstructorDescriptor = "(I)V";
}
} else {
assert !shouldHaveBoundReferenceReceiver : "Unexpected bound reference with supertype " + superClassAsmType;
superClassConstructorDescriptor = "()V";
}
iv.invokespecial(superClassAsmType.getInternalName(), "<init>", superClassConstructorDescriptor, false);
iv.visitInsn(RETURN);
FunctionCodegen.endVisit(iv, "constructor", element);
}
return constructor;
}
Aggregations