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;
}
Visibility visibility = descriptor.getVisibility();
Integer defaultMapping = visibilityToAccessFlag.get(visibility);
Integer defaultMapping = getVisibilityAccessFlag(visibility);
if (defaultMapping == null) {
throw new IllegalStateException(visibility + " is not a valid visibility in backend for " + DescriptorRenderer.DEBUG_TEXT.render(descriptor));
}
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).
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.expressions.*
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.psiUtil.endOffset
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.types.KotlinType
@@ -276,4 +278,11 @@ val IrClass.isEnumClass get() = kind == ClassKind.ENUM_CLASS
val IrClass.isEnumEntry get() = kind == ClassKind.ENUM_ENTRY
val IrClass.isInterface get() = kind == ClassKind.INTERFACE
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.jvm.descriptors.JvmDescriptorWithExtraFlags
import org.jetbrains.kotlin.backend.common.lower.InitializersLowering
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.FunctionCodegen
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.IrConstructor
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.isAnnotationClass
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(
if (classCodegen.irClass.isAnnotationClass) Opcodes.ACC_FINAL else 0/*TODO*/
).or(if (descriptor is JvmDescriptorWithExtraFlags) descriptor.extraFlags else 0)
if (classCodegen.irClass.isJvmInterface && InitializersLowering.clinitName == irFunction.name) {
//reset abstract flag for <clinit>
flags = flags.xor(Opcodes.ACC_ABSTRACT)
val visibility = AsmUtil.getVisibilityAccessFlag(irFunction.visibility) ?: error("Unmapped visibility ${irFunction.visibility}")
val staticFlag = if (isStatic) Opcodes.ACC_STATIC else 0
val varargFlag = if (irFunction.valueParameters.any { it.varargElementType != null }) Opcodes.ACC_VARARGS else 0
val deprecation = 0 //TODO
val bridgeFlag = 0 //TODO
val modalityFlag = when ((irFunction as? IrSimpleFunction)?.modality) {
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 {
@@ -11,14 +11,15 @@ import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.util.isAnnotationClass
import org.jetbrains.kotlin.ir.util.isInterface
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME
import org.jetbrains.org.objectweb.asm.Type
class IrFrameMap : FrameMapBase<IrSymbol>()
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 {
return enter(irDeclaration.symbol, type)
@@ -69,6 +69,7 @@ class InterfaceLowering(val state: GenerationState) : IrElementTransformerVoid()
createDefaultImplFunDescriptor(defaultImplsDescriptor, descriptor, interfaceDescriptor, state.typeMapper)
members.add(functionDescriptorImpl.createFunctionAndMapVariables(it, it.visibility))
it.body = null
//TODO reset modality to abstract
}
}