JVM IR: introduce global serialization bindings for convenience
In the old JVM backend, JvmSerializationBindings are created per ClassBuilder, and special care must be taken to make sure that JVM-specific metadata ends up in the correct bindings. This is especially relevant for declarations whose metadata is moved to other classes away from the place where the original declaration lies, for example properties moved from companion object to the outer class, or synthetic methods for annotation properties in interfaces moved to DefaultImpls, or const properties in multifile parts moved to the facade. In the JVM IR backend, this seems not necessary and actually it's complicated to ensure that we use the correct ClassBuilder for bindings (see the code simplification in ClassCodegen). Therefore, in case we don't have an easy way to retrieve the correct ClassBuilder instance, we now write all JVM-specific metadata to the new _global_ bindings map in GenerationState, which is used by JvmSerializerExtension as a fallback if the ClassBuilder's local map has no relevant key.
This commit is contained in:
+20
-16
@@ -38,6 +38,7 @@ import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||
|
||||
class JvmSerializerExtension(private val bindings: JvmSerializationBindings, state: GenerationState) : SerializerExtension() {
|
||||
private val globalBindings = state.globalSerializationBindings
|
||||
private val codegenBinding = state.bindingContext
|
||||
private val typeMapper = state.typeMapper
|
||||
override val stringTable = JvmCodegenStringTable(typeMapper)
|
||||
@@ -151,10 +152,10 @@ class JvmSerializerExtension(private val bindings: JvmSerializationBindings, sta
|
||||
}
|
||||
}
|
||||
|
||||
override fun serializeConstructor(descriptor: ConstructorDescriptor,
|
||||
proto: ProtoBuf.Constructor.Builder,
|
||||
childSerializer: DescriptorSerializer) {
|
||||
val method = bindings.get(METHOD_FOR_FUNCTION, descriptor)
|
||||
override fun serializeConstructor(
|
||||
descriptor: ConstructorDescriptor, proto: ProtoBuf.Constructor.Builder, childSerializer: DescriptorSerializer
|
||||
) {
|
||||
val method = getBinding(METHOD_FOR_FUNCTION, descriptor)
|
||||
if (method != null) {
|
||||
val signature = SignatureSerializer().methodSignature(descriptor, method)
|
||||
if (signature != null) {
|
||||
@@ -163,10 +164,10 @@ class JvmSerializerExtension(private val bindings: JvmSerializationBindings, sta
|
||||
}
|
||||
}
|
||||
|
||||
override fun serializeFunction(descriptor: FunctionDescriptor,
|
||||
proto: ProtoBuf.Function.Builder,
|
||||
childSerializer: DescriptorSerializer) {
|
||||
val method = bindings.get(METHOD_FOR_FUNCTION, descriptor)
|
||||
override fun serializeFunction(
|
||||
descriptor: FunctionDescriptor, proto: ProtoBuf.Function.Builder, childSerializer: DescriptorSerializer
|
||||
) {
|
||||
val method = getBinding(METHOD_FOR_FUNCTION, descriptor)
|
||||
if (method != null) {
|
||||
val signature = SignatureSerializer().methodSignature(descriptor, method)
|
||||
if (signature != null) {
|
||||
@@ -176,20 +177,20 @@ class JvmSerializerExtension(private val bindings: JvmSerializationBindings, sta
|
||||
}
|
||||
|
||||
override fun serializeProperty(
|
||||
descriptor: PropertyDescriptor,
|
||||
proto: ProtoBuf.Property.Builder,
|
||||
versionRequirementTable: MutableVersionRequirementTable?,
|
||||
childSerializer: DescriptorSerializer
|
||||
descriptor: PropertyDescriptor,
|
||||
proto: ProtoBuf.Property.Builder,
|
||||
versionRequirementTable: MutableVersionRequirementTable?,
|
||||
childSerializer: DescriptorSerializer
|
||||
) {
|
||||
val signatureSerializer = SignatureSerializer()
|
||||
|
||||
val getter = descriptor.getter
|
||||
val setter = descriptor.setter
|
||||
val getterMethod = if (getter == null) null else bindings.get(METHOD_FOR_FUNCTION, getter)
|
||||
val setterMethod = if (setter == null) null else bindings.get(METHOD_FOR_FUNCTION, setter)
|
||||
val getterMethod = if (getter == null) null else getBinding(METHOD_FOR_FUNCTION, getter)
|
||||
val setterMethod = if (setter == null) null else getBinding(METHOD_FOR_FUNCTION, setter)
|
||||
|
||||
val field = bindings.get(FIELD_FOR_PROPERTY, descriptor)
|
||||
val syntheticMethod = bindings.get(SYNTHETIC_METHOD_FOR_PROPERTY, descriptor)
|
||||
val field = getBinding(FIELD_FOR_PROPERTY, descriptor)
|
||||
val syntheticMethod = getBinding(SYNTHETIC_METHOD_FOR_PROPERTY, descriptor)
|
||||
|
||||
val signature = signatureSerializer.propertySignature(
|
||||
descriptor,
|
||||
@@ -232,6 +233,9 @@ class JvmSerializerExtension(private val bindings: JvmSerializationBindings, sta
|
||||
super.serializeErrorType(type, builder)
|
||||
}
|
||||
|
||||
private fun <K, V> getBinding(slice: SerializationMappingSlice<K, V>, key: K): V? =
|
||||
bindings.get(slice, key) ?: globalBindings.get(slice, key)
|
||||
|
||||
private inner class SignatureSerializer {
|
||||
fun methodSignature(descriptor: FunctionDescriptor?, method: Method): JvmProtoBuf.JvmMethodSignature? {
|
||||
val builder = JvmProtoBuf.JvmMethodSignature.newBuilder()
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.codegen.inline.GlobalInlineContext
|
||||
import org.jetbrains.kotlin.codegen.inline.InlineCache
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
||||
import org.jetbrains.kotlin.codegen.optimization.OptimizationClassBuilderFactory
|
||||
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings
|
||||
import org.jetbrains.kotlin.config.*
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ScriptDescriptor
|
||||
@@ -256,6 +257,8 @@ class GenerationState private constructor(
|
||||
|
||||
val metadataVersion = configuration.get(CommonConfigurationKeys.METADATA_VERSION) ?: JvmMetadataVersion.INSTANCE
|
||||
|
||||
val globalSerializationBindings = JvmSerializationBindings()
|
||||
|
||||
init {
|
||||
this.interceptedBuilderFactory = builderFactory
|
||||
.wrapWith(
|
||||
|
||||
Reference in New Issue
Block a user