Avoid descriptors usage in IrFunction flag calculation

This commit is contained in:
Mikhael Bogdanov
2018-05-15 13:20:42 +02:00
parent e9216625f0
commit f4f01efd1f
5 changed files with 42 additions and 14 deletions
@@ -258,13 +258,18 @@ public class AsmUtil {
return specialCase; return specialCase;
} }
Visibility visibility = descriptor.getVisibility(); Visibility visibility = descriptor.getVisibility();
Integer defaultMapping = visibilityToAccessFlag.get(visibility); Integer defaultMapping = getVisibilityAccessFlag(visibility);
if (defaultMapping == null) { if (defaultMapping == null) {
throw new IllegalStateException(visibility + " is not a valid visibility in backend for " + DescriptorRenderer.DEBUG_TEXT.render(descriptor)); throw new IllegalStateException(visibility + " is not a valid visibility in backend for " + DescriptorRenderer.DEBUG_TEXT.render(descriptor));
} }
return defaultMapping; return defaultMapping;
} }
@Nullable
public static Integer getVisibilityAccessFlag(Visibility visibility) {
return visibilityToAccessFlag.get(visibility);
}
/* /*
Use this method to get visibility flag for class to define it in byte code (v.defineClass method). Use this method to get visibility flag for class to define it in byte code (v.defineClass method).
For other cases use getVisibilityAccessFlag(MemberDescriptor descriptor) For other cases use getVisibilityAccessFlag(MemberDescriptor descriptor)
@@ -27,9 +27,11 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrTypeParameterImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.source.PsiSourceElement import org.jetbrains.kotlin.resolve.source.PsiSourceElement
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
@@ -276,4 +278,11 @@ val IrClass.isEnumClass get() = kind == ClassKind.ENUM_CLASS
val IrClass.isEnumEntry get() = kind == ClassKind.ENUM_ENTRY val IrClass.isEnumEntry get() = kind == ClassKind.ENUM_ENTRY
val IrClass.isInterface get() = kind == ClassKind.INTERFACE val IrClass.isInterface get() = kind == ClassKind.INTERFACE
val IrClass.isClass get() = kind == ClassKind.CLASS val IrClass.isClass get() = kind == ClassKind.CLASS
val IrClass.isObject get() = kind == ClassKind.OBJECT val IrClass.isObject get() = kind == ClassKind.OBJECT
val IrDeclaration.parentAsClass get() = parent as IrClass
fun IrAnnotationContainer.hasAnnotation(name: FqName) =
annotations.any {
it.symbol.owner.parentAsClass.descriptor.fqNameSafe == name
}
@@ -18,13 +18,14 @@ package org.jetbrains.kotlin.backend.jvm.codegen
import org.jetbrains.kotlin.backend.common.lower.DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER import org.jetbrains.kotlin.backend.common.lower.DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmDescriptorWithExtraFlags import org.jetbrains.kotlin.backend.jvm.descriptors.JvmDescriptorWithExtraFlags
import org.jetbrains.kotlin.backend.common.lower.InitializersLowering
import org.jetbrains.kotlin.codegen.* import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.FunctionCodegen import org.jetbrains.kotlin.codegen.FunctionCodegen
import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrConstructor import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.util.dump import org.jetbrains.kotlin.ir.util.dump
import org.jetbrains.kotlin.ir.util.isAnnotationClass import org.jetbrains.kotlin.ir.util.isAnnotationClass
import org.jetbrains.kotlin.psi.KtParameter import org.jetbrains.kotlin.psi.KtParameter
@@ -77,15 +78,26 @@ open class FunctionCodegen(private val irFunction: IrFunction, private val class
} }
} }
var flags = AsmUtil.getMethodAsmFlags(descriptor, OwnerKind.IMPLEMENTATION, state).or(if (isStatic) Opcodes.ACC_STATIC else 0).xor( val visibility = AsmUtil.getVisibilityAccessFlag(irFunction.visibility) ?: error("Unmapped visibility ${irFunction.visibility}")
if (classCodegen.irClass.isAnnotationClass) Opcodes.ACC_FINAL else 0/*TODO*/ val staticFlag = if (isStatic) Opcodes.ACC_STATIC else 0
).or(if (descriptor is JvmDescriptorWithExtraFlags) descriptor.extraFlags else 0) val varargFlag = if (irFunction.valueParameters.any { it.varargElementType != null }) Opcodes.ACC_VARARGS else 0
val deprecation = 0 //TODO
if (classCodegen.irClass.isJvmInterface && InitializersLowering.clinitName == irFunction.name) { val bridgeFlag = 0 //TODO
//reset abstract flag for <clinit> val modalityFlag = when ((irFunction as? IrSimpleFunction)?.modality) {
flags = flags.xor(Opcodes.ACC_ABSTRACT) Modality.FINAL -> if (!classCodegen.irClass.isAnnotationClass) Opcodes.ACC_FINAL else 0
Modality.ABSTRACT -> Opcodes.ACC_ABSTRACT
else -> if (classCodegen.irClass.isJvmInterface) Opcodes.ACC_ABSTRACT else 0 //TODO transform interface modality on lowering to DefaultImpls
} }
return flags val nativeFlag = if (irFunction.isExternal) Opcodes.ACC_NATIVE else 0
return visibility or
modalityFlag or
staticFlag or
varargFlag or
deprecation or
nativeFlag or
bridgeFlag or
(if (descriptor is JvmDescriptorWithExtraFlags) descriptor.extraFlags else 0)
} }
protected open fun createMethod(flags: Int, signature: JvmMethodGenericSignature): MethodVisitor { protected open fun createMethod(flags: Int, signature: JvmMethodGenericSignature): MethodVisitor {
@@ -11,14 +11,15 @@ import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner
import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.util.isAnnotationClass import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.util.isInterface import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
class IrFrameMap : FrameMapBase<IrSymbol>() class IrFrameMap : FrameMapBase<IrSymbol>()
internal val IrFunction.isStatic internal val IrFunction.isStatic
get() = this.dispatchReceiverParameter == null && this !is IrConstructor get() = (this.dispatchReceiverParameter == null && this !is IrConstructor) ||
(parentAsClass.isObject && this.hasAnnotation(JVM_STATIC_ANNOTATION_FQ_NAME)) //TODO add lowering
fun IrFrameMap.enter(irDeclaration: IrSymbolOwner, type: Type): Int { fun IrFrameMap.enter(irDeclaration: IrSymbolOwner, type: Type): Int {
return enter(irDeclaration.symbol, type) return enter(irDeclaration.symbol, type)
@@ -69,6 +69,7 @@ class InterfaceLowering(val state: GenerationState) : IrElementTransformerVoid()
createDefaultImplFunDescriptor(defaultImplsDescriptor, descriptor, interfaceDescriptor, state.typeMapper) createDefaultImplFunDescriptor(defaultImplsDescriptor, descriptor, interfaceDescriptor, state.typeMapper)
members.add(functionDescriptorImpl.createFunctionAndMapVariables(it, it.visibility)) members.add(functionDescriptorImpl.createFunctionAndMapVariables(it, it.visibility))
it.body = null it.body = null
//TODO reset modality to abstract
} }
} }