use of org.jetbrains.org.objectweb.asm.commons.Method in project kotlin by JetBrains.
the class JvmSignatureWriter method makeJvmMethodSignature.
@NotNull
public JvmMethodGenericSignature makeJvmMethodSignature(@NotNull String name) {
List<Type> types = new ArrayList<Type>(kotlinParameterTypes.size());
for (JvmMethodParameterSignature parameter : kotlinParameterTypes) {
types.add(parameter.getAsmType());
}
Method asmMethod = new Method(name, jvmReturnType, types.toArray(new Type[types.size()]));
return new JvmMethodGenericSignature(asmMethod, kotlinParameterTypes, makeJavaGenericSignature());
}
use of org.jetbrains.org.objectweb.asm.commons.Method in project kotlin by JetBrains.
the class FunctionCodegen method generateMethodBody.
public static void generateMethodBody(@NotNull MethodVisitor mv, @NotNull FunctionDescriptor functionDescriptor, @NotNull MethodContext context, @NotNull JvmMethodSignature signature, @NotNull FunctionGenerationStrategy strategy, @NotNull MemberCodegen<?> parentCodegen) {
mv.visitCode();
Label methodBegin = new Label();
mv.visitLabel(methodBegin);
KotlinTypeMapper typeMapper = parentCodegen.typeMapper;
if (BuiltinSpecialBridgesUtil.shouldHaveTypeSafeBarrier(functionDescriptor, getSignatureMapper(typeMapper))) {
generateTypeCheckBarrierIfNeeded(new InstructionAdapter(mv), functionDescriptor, signature.getReturnType(), /* delegateParameterTypes = */
null);
}
Label methodEnd;
int functionFakeIndex = -1;
int lambdaFakeIndex = -1;
if (context.getParentContext() instanceof MultifileClassFacadeContext) {
generateFacadeDelegateMethodBody(mv, signature.getAsmMethod(), (MultifileClassFacadeContext) context.getParentContext());
methodEnd = new Label();
} else if (OwnerKind.DEFAULT_IMPLS == context.getContextKind() && isJvm8InterfaceWithDefaultsMember(functionDescriptor, parentCodegen.state)) {
int flags = AsmUtil.getMethodAsmFlags(functionDescriptor, OwnerKind.DEFAULT_IMPLS, context.getState());
assert (flags & Opcodes.ACC_ABSTRACT) == 0 : "Interface method with body should be non-abstract" + functionDescriptor;
Type type = typeMapper.mapOwner(functionDescriptor);
Method asmMethod = typeMapper.mapAsmMethod(functionDescriptor, OwnerKind.DEFAULT_IMPLS);
generateDelegateToStaticMethodBody(true, mv, new Method(asmMethod.getName() + JvmAbi.DEFAULT_IMPLS_DELEGATE_SUFFIX, asmMethod.getDescriptor()), type.getInternalName());
methodEnd = new Label();
} else {
FrameMap frameMap = createFrameMap(parentCodegen.state, functionDescriptor, signature, isStaticMethod(context.getContextKind(), functionDescriptor));
if (context.isInlineMethodContext()) {
functionFakeIndex = frameMap.enterTemp(Type.INT_TYPE);
}
if (context instanceof InlineLambdaContext) {
lambdaFakeIndex = frameMap.enterTemp(Type.INT_TYPE);
}
Label methodEntry = new Label();
mv.visitLabel(methodEntry);
context.setMethodStartLabel(methodEntry);
if (!KotlinTypeMapper.isAccessor(functionDescriptor)) {
genNotNullAssertionsForParameters(new InstructionAdapter(mv), parentCodegen.state, functionDescriptor, frameMap);
}
parentCodegen.beforeMethodBody(mv);
methodEnd = new Label();
context.setMethodEndLabel(methodEnd);
strategy.generateBody(mv, frameMap, signature, context, parentCodegen);
}
mv.visitLabel(methodEnd);
Type thisType = getThisTypeForFunction(functionDescriptor, context, typeMapper);
generateLocalVariableTable(mv, signature, functionDescriptor, thisType, methodBegin, methodEnd, context.getContextKind(), typeMapper, (functionFakeIndex >= 0 ? 1 : 0) + (lambdaFakeIndex >= 0 ? 1 : 0));
//TODO: it's best to move all below logic to 'generateLocalVariableTable' method
if (context.isInlineMethodContext() && functionFakeIndex != -1) {
mv.visitLocalVariable(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION + typeMapper.mapAsmMethod(functionDescriptor).getName(), Type.INT_TYPE.getDescriptor(), null, methodBegin, methodEnd, functionFakeIndex);
}
if (context instanceof InlineLambdaContext && thisType != null && lambdaFakeIndex != -1) {
String name = thisType.getClassName();
int indexOfLambdaOrdinal = name.lastIndexOf("$");
if (indexOfLambdaOrdinal > 0) {
int lambdaOrdinal = Integer.parseInt(name.substring(indexOfLambdaOrdinal + 1));
KtPureElement functionArgument = parentCodegen.element;
String functionName = "unknown";
if (functionArgument instanceof KtFunction) {
ValueParameterDescriptor inlineArgumentDescriptor = InlineUtil.getInlineArgumentDescriptor((KtFunction) functionArgument, parentCodegen.bindingContext);
if (inlineArgumentDescriptor != null) {
functionName = inlineArgumentDescriptor.getContainingDeclaration().getName().asString();
}
}
mv.visitLocalVariable(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_ARGUMENT + lambdaOrdinal + "$" + functionName, Type.INT_TYPE.getDescriptor(), null, methodBegin, methodEnd, lambdaFakeIndex);
}
}
}
use of org.jetbrains.org.objectweb.asm.commons.Method in project kotlin by JetBrains.
the class MemberCodegen method writeOuterClassAndEnclosingMethod.
protected void writeOuterClassAndEnclosingMethod() {
CodegenContext context = this.context.getParentContext();
while (context instanceof InlineLambdaContext) {
// If this is a lambda which will be inlined, skip its MethodContext and enclosing ClosureContext
//noinspection ConstantConditions
context = context.getParentContext().getParentContext();
}
assert context != null : "Outermost context can't be null: " + this.context;
Type enclosingAsmType = computeOuterClass(context);
if (enclosingAsmType != null) {
Method method = computeEnclosingMethod(context);
v.visitOuterClass(enclosingAsmType.getInternalName(), method == null ? null : method.getName(), method == null ? null : method.getDescriptor());
}
}
use of org.jetbrains.org.objectweb.asm.commons.Method in project kotlin by JetBrains.
the class MemberCodegen method genTypeAliasAnnotationsMethodIfRequired.
private void genTypeAliasAnnotationsMethodIfRequired(TypeAliasDescriptor typeAliasDescriptor) {
boolean isAnnotationsMethodOwner = CodegenContextUtil.isImplClassOwner(context);
Annotations annotations = typeAliasDescriptor.getAnnotations();
if (!isAnnotationsMethodOwner || annotations.getAllAnnotations().isEmpty())
return;
String name = JvmAbi.getSyntheticMethodNameForAnnotatedTypeAlias(typeAliasDescriptor.getName());
generateSyntheticAnnotationsMethod(typeAliasDescriptor, new Method(name, "()V"), annotations, null);
}
use of org.jetbrains.org.objectweb.asm.commons.Method in project kotlin by JetBrains.
the class FunctionCodegen method generateBridges.
public void generateBridges(@NotNull FunctionDescriptor descriptor) {
if (descriptor instanceof ConstructorDescriptor)
return;
if (owner.getContextKind() == OwnerKind.DEFAULT_IMPLS)
return;
if (isAnnotationOrJvmInterfaceWithoutDefaults(descriptor.getContainingDeclaration(), state))
return;
// equals(Any?), hashCode(), toString() never need bridges
if (isMethodOfAny(descriptor))
return;
boolean isSpecial = SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(descriptor) != null;
Set<Bridge<Method>> bridgesToGenerate;
if (!isSpecial) {
bridgesToGenerate = ImplKt.generateBridgesForFunctionDescriptor(descriptor, getSignatureMapper(typeMapper), IS_PURE_INTERFACE_CHECKER);
if (!bridgesToGenerate.isEmpty()) {
PsiElement origin = descriptor.getKind() == DECLARATION ? getSourceFromDescriptor(descriptor) : null;
boolean isSpecialBridge = BuiltinMethodsWithSpecialGenericSignature.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(descriptor) != null;
for (Bridge<Method> bridge : bridgesToGenerate) {
generateBridge(origin, descriptor, bridge.getFrom(), bridge.getTo(), isSpecialBridge, false);
}
}
} else {
Set<BridgeForBuiltinSpecial<Method>> specials = BuiltinSpecialBridgesUtil.generateBridgesForBuiltinSpecial(descriptor, getSignatureMapper(typeMapper), IS_PURE_INTERFACE_CHECKER);
if (!specials.isEmpty()) {
PsiElement origin = descriptor.getKind() == DECLARATION ? getSourceFromDescriptor(descriptor) : null;
for (BridgeForBuiltinSpecial<Method> bridge : specials) {
generateBridge(origin, descriptor, bridge.getFrom(), bridge.getTo(), bridge.isSpecial(), bridge.isDelegateToSuper());
}
}
if (!descriptor.getKind().isReal() && isAbstractMethod(descriptor, OwnerKind.IMPLEMENTATION, state)) {
CallableDescriptor overridden = SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(descriptor);
assert overridden != null;
if (!isThereOverriddenInKotlinClass(descriptor)) {
Method method = typeMapper.mapAsmMethod(descriptor);
int flags = ACC_ABSTRACT | getVisibilityAccessFlag(descriptor);
v.newMethod(JvmDeclarationOriginKt.OtherOrigin(overridden), flags, method.getName(), method.getDescriptor(), null, null);
}
}
}
}
Aggregations