JVM_IR: JvmIrSerializer

This commit is contained in:
Georgy Bronnikov
2021-02-20 10:49:32 +03:00
committed by TeamCityServer
parent 113d2653aa
commit 9efd0d7589
5 changed files with 3411 additions and 7 deletions

View File

@@ -139,17 +139,17 @@ open class IrFileSerializer(
// The same type can be used multiple times in a file
// so use this index to store type data only once.
private val protoTypeMap = mutableMapOf<IrTypeKey, Int>()
private val protoTypeArray = arrayListOf<ProtoType>()
protected val protoTypeArray = arrayListOf<ProtoType>()
private val protoStringMap = mutableMapOf<String, Int>()
private val protoStringArray = arrayListOf<String>()
protected val protoStringArray = arrayListOf<String>()
// The same signature could be used multiple times in a file
// so use this index to store signature only once.
private val protoIdSignatureMap = mutableMapOf<IdSignature, Int>()
private val protoIdSignatureArray = arrayListOf<ProtoIdSignature>()
protected val protoIdSignatureArray = arrayListOf<ProtoIdSignature>()
private val protoBodyArray = mutableListOf<XStatementOrExpression>()
protected val protoBodyArray = mutableListOf<XStatementOrExpression>()
private val protoDebugInfoArray = arrayListOf<String>()
@@ -394,10 +394,10 @@ open class IrFileSerializer(
/* ------- IrTypes ---------------------------------------------------------- */
private fun serializeAnnotations(annotations: List<IrConstructorCall>) =
protected fun serializeAnnotations(annotations: List<IrConstructorCall>) =
annotations.map { serializeConstructorCall(it) }
private fun serializeFqName(fqName: String): List<Int> = fqName.split(".").map(::serializeString)
protected fun serializeFqName(fqName: String): List<Int> = fqName.split(".").map(::serializeString)
private fun serializeIrStarProjection() = BinaryTypeProjection.STAR_CODE
@@ -1307,7 +1307,7 @@ open class IrFileSerializer(
return proto.build()
}
private fun serializeIrClass(clazz: IrClass): ProtoClass {
protected fun serializeIrClass(clazz: IrClass): ProtoClass {
val proto = ProtoClass.newBuilder()
.setBase(serializeIrDeclarationBase(clazz, ClassFlags.encode(clazz)))
.setName(serializeName(clazz.name))

View File

@@ -0,0 +1,82 @@
syntax = "proto2";
package org.jetbrains.kotlin.backend.jvm.serialization.proto;
import "compiler/ir/serialization.common/src/KotlinIr.proto";
option java_outer_classname = "JvmIr";
option optimize_for = LITE_RUNTIME;
/* Stored in JVM .class annotations */
//message UniqIdInfo {
// required fixed64 id = 1;
// repeated int32 toplevel_fq_name = 2;
//}
//message SignatureTable {
// repeated common.serialization.proto.IrSignature signature = 1;
//}
//
//message TypeTable {
// repeated common.serialization.proto.IrType type = 1;
//}
//message UniqIdTable {
// repeated UniqIdInfo infos = 1;
//}
//message StringTable {
// repeated string string = 1;
//}
message XStatementOrExpression {
oneof kind {
common.serialization.proto.IrStatement statement = 1;
common.serialization.proto.IrExpression expression = 2;
}
}
//message StatementsAndExpressionsTable {
// repeated XStatementOrExpression statement_or_expression = 1;
//}
//message ExternalReference {
// required fixed64 id = 1;
// required int32 index = 2; /* index into the table of packages in ExternalRefs */
//}
//
//message JvmExternalPackage {
// repeated int32 fq_name = 1;
// required common.serialization.proto.IrDeclarationContainer declaration_container = 2;
//}
//message ExternalRefs {
// repeated JvmExternalPackage package = 1;
// repeated ExternalReference reference = 2;
//}
message AuxTables {
repeated common.serialization.proto.IrType type = 1;
repeated common.serialization.proto.IdSignature signature = 2;
repeated string string = 3;
repeated XStatementOrExpression body = 4;
// required TypeTable type_table = 2;
// required SignatureTable signature_table = 1;
// required StringTable string_table = 3;
// required StatementsAndExpressionsTable statements_and_expressions_table = 4;
// required ExternalRefs external_refs = 5;
// required UniqIdTable uniq_id_table = 6;
}
message JvmIrFile {
repeated common.serialization.proto.IrDeclaration declaration = 1;
repeated common.serialization.proto.IrConstructorCall annotation = 2;
repeated int32 facade_fq_name = 3;
required AuxTables aux_tables = 4;
}
message JvmIrClass {
required common.serialization.proto.IrClass ir_class = 1;
required AuxTables aux_tables = 2;
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.backend.jvm.serialization
import org.jetbrains.kotlin.backend.common.serialization.DeclarationTable
import org.jetbrains.kotlin.backend.common.serialization.IrFileSerializer
import org.jetbrains.kotlin.backend.jvm.serialization.proto.JvmIr
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.util.IrMessageLogger
import org.jetbrains.kotlin.protobuf.ByteString
class JvmIrSerializer(
messageLogger: IrMessageLogger,
declarationTable: DeclarationTable,
expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>,
externallyVisibleOnly: Boolean = true,
skipExpects: Boolean = false,
) : IrFileSerializer(messageLogger, declarationTable, expectDescriptorToSymbol, externallyVisibleOnly, skipExpects) {
// Usage protocol: construct an instance, call only one of `serializeIrFile()` and `serializeTopLevelClass()` only once.
fun serializeJvmIrFile(irFile: IrFile): JvmIr.JvmIrFile {
val proto = JvmIr.JvmIrFile.newBuilder()
irFile.declarations.filter { it !is IrClass }.forEach { declaration ->
proto.addDeclaration(serializeDeclaration(declaration))
}
proto.addAllAnnotation(serializeAnnotations(irFile.annotations))
proto.auxTables = serializeAuxTables()
return proto.build()
}
fun serializeTopLevelClass(irClass: IrClass): JvmIr.JvmIrClass {
val proto = JvmIr.JvmIrClass.newBuilder()
proto.irClass = serializeIrClass(irClass)
proto.auxTables = serializeAuxTables()
return proto.build()
}
private fun serializeAuxTables(): JvmIr.AuxTables {
val proto = JvmIr.AuxTables.newBuilder()
proto.addAllType(protoTypeArray)
proto.addAllSignature(protoIdSignatureArray)
proto.addAllString(protoStringArray)
for (body in protoBodyArray) {
val bodyProto = JvmIr.XStatementOrExpression.newBuilder()
when (body) {
is XStatementOrExpression.XStatement -> bodyProto.statement = body.toProtoStatement()
is XStatementOrExpression.XExpression -> bodyProto.expression = body.toProtoExpression()
}
proto.addBody(bodyProto.build())
}
return proto.build()
}
}

View File

@@ -53,6 +53,7 @@ val PROTO_PATHS: List<ProtoPath> = listOf(
ProtoPath("compiler/util-klib-metadata/src/KlibMetadataProtoBuf.proto"),
ProtoPath("compiler/ir/serialization.common/src/KotlinIr.proto", false),
ProtoPath("compiler/ir/serialization.common/src/KotlinPirCarriers.proto", false),
ProtoPath("compiler/ir/serialization.jvm/src/JvmIr.proto", false),
ProtoPath("plugins/kotlin-serialization/kotlin-serialization-compiler/src/class_extensions.proto", generateDebug = false)
)