From 8fe8419ad415b76c57e078c303d256ad2d8dd6ee Mon Sep 17 00:00:00 2001 From: Anton Bannykh Date: Fri, 2 Apr 2021 17:56:06 +0300 Subject: [PATCH] JS IR: serialize declarations without mutable state --- .../serialization/IrBodyDeserializer.kt | 2 + .../IrDeclarationDeserializer.kt | 111 ++++---- .../common/serialization/IrFileSerializer.kt | 242 +++++++++++------- .../serialization/ir/JsIrFileSerializer.kt | 7 +- 4 files changed, 217 insertions(+), 145 deletions(-) diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrBodyDeserializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrBodyDeserializer.kt index 2cc2279d0a3..1842e3c43cc 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrBodyDeserializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrBodyDeserializer.kt @@ -567,6 +567,8 @@ class IrBodyDeserializer( IrTypeOperator.SAM_CONVERSION ProtoTypeOperator.IMPLICIT_DYNAMIC_CAST -> IrTypeOperator.IMPLICIT_DYNAMIC_CAST + ProtoTypeOperator.REINTERPRET_CAST -> + IrTypeOperator.REINTERPRET_CAST } private fun deserializeTypeOp(proto: ProtoTypeOp, start: Int, end: Int, type: IrType): IrTypeOperatorCall { diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrDeclarationDeserializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrDeclarationDeserializer.kt index a9a294d13dd..edb24a5ad41 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrDeclarationDeserializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrDeclarationDeserializer.kt @@ -62,12 +62,13 @@ class IrDeclarationDeserializer( private val allowErrorNodes: Boolean, private val deserializeInlineFunctions: Boolean, private var deserializeBodies: Boolean, - private val symbolDeserializer: IrSymbolDeserializer, + val symbolDeserializer: IrSymbolDeserializer, private val platformFakeOverrideClassFilter: FakeOverrideClassFilter, private val fakeOverrideBuilder: FakeOverrideBuilder, + private val skipMutableState: Boolean = false, ) { - private val bodyDeserializer = IrBodyDeserializer(builtIns, allowErrorNodes, irFactory, fileReader, this) + val bodyDeserializer = IrBodyDeserializer(builtIns, allowErrorNodes, irFactory, fileReader, this) private fun deserializeName(index: Int): Name { val name = fileReader.deserializeString(index) @@ -83,7 +84,7 @@ class IrDeclarationDeserializer( return ProtoType.parseFrom(readType(index), ExtensionRegistryLite.newInstance()) } - internal fun deserializeIrType(index: Int): IrType { + fun deserializeIrType(index: Int): IrType { return irTypeCache.getOrPut(index) { val typeData = loadTypeProto(index) deserializeIrTypeData(typeData) @@ -216,7 +217,9 @@ class IrDeclarationDeserializer( deserializeIrDeclarationOrigin(proto.originName), proto.flags ) result.annotations += deserializeAnnotations(proto.annotationList) - result.parent = currentParent + if (!skipMutableState) { + result.parent = currentParent + } return result } finally { eraseDelegatedSymbol(s) @@ -305,19 +308,19 @@ class IrDeclarationDeserializer( flags.isFun, ) }.usingParent { - typeParameters = deserializeTypeParameters(proto.typeParameterList, true) + if (!skipMutableState) { + typeParameters = deserializeTypeParameters(proto.typeParameterList, true) - superTypes = proto.superTypeList.map { deserializeIrType(it) } + superTypes = proto.superTypeList.map { deserializeIrType(it) } - withExternalValue(isExternal) { - proto.declarationList + withExternalValue(isExternal) {proto.declarationList .filterNot { isSkippableFakeOverride(it, this) } - .mapTo(declarations) { deserializeDeclaration(it) } + .mapTo(declarations) { deserializeDeclaration(it) }} + + thisReceiver = deserializeIrValueParameter(proto.thisReceiver, -1) + + fakeOverrideBuilder.enqueueClass(this, signature) } - - thisReceiver = deserializeIrValueParameter(proto.thisReceiver, -1) - - fakeOverrideBuilder.enqueueClass(this, signature) } } @@ -337,7 +340,9 @@ class IrDeclarationDeserializer( origin ) }.usingParent { - typeParameters = deserializeTypeParameters(proto.typeParameterList, true) + if (!skipMutableState) { + typeParameters = deserializeTypeParameters(proto.typeParameterList, true) + } } } @@ -437,7 +442,7 @@ class IrDeclarationDeserializer( return ProtoExpression.parseFrom(readBody(index), ExtensionRegistryLite.newInstance()) } - private fun deserializeExpressionBody(index: Int): IrExpressionBody { + fun deserializeExpressionBody(index: Int): IrExpressionBody { return irFactory.createExpressionBody( if (deserializeBodies) { val bodyData = loadExpressionBodyProto(index) @@ -449,7 +454,7 @@ class IrDeclarationDeserializer( ) } - private fun deserializeStatementBody(index: Int): IrElement { + fun deserializeStatementBody(index: Int): IrElement { return if (deserializeBodies) { val bodyData = loadStatementBodyProto(index) bodyDeserializer.deserializeStatement(bodyData) @@ -467,18 +472,20 @@ class IrDeclarationDeserializer( ): T = withDeserializedIrDeclarationBase(proto.base) { symbol, idSig, startOffset, endOffset, origin, fcode -> symbolTable.withScope(symbol) { block(symbol as IrFunctionSymbol, idSig, startOffset, endOffset, origin, fcode).usingParent { - typeParameters = deserializeTypeParameters(proto.typeParameterList, false) - val nameType = BinaryNameAndType.decode(proto.nameType) - returnType = deserializeIrType(nameType.typeIndex) + if (!skipMutableState) { + typeParameters = deserializeTypeParameters(proto.typeParameterList, false) + val nameType = BinaryNameAndType.decode(proto.nameType) + returnType = deserializeIrType(nameType.typeIndex) - withBodyGuard { - valueParameters = deserializeValueParameters(proto.valueParameterList) - if (proto.hasDispatchReceiver()) - dispatchReceiverParameter = deserializeIrValueParameter(proto.dispatchReceiver, -1) - if (proto.hasExtensionReceiver()) - extensionReceiverParameter = deserializeIrValueParameter(proto.extensionReceiver, -1) - if (proto.hasBody()) { - body = deserializeStatementBody(proto.body) as IrBody + withBodyGuard { + valueParameters = deserializeValueParameters(proto.valueParameterList) + if (proto.hasDispatchReceiver()) + dispatchReceiverParameter = deserializeIrValueParameter(proto.dispatchReceiver, -1) + if (proto.hasExtensionReceiver()) + extensionReceiverParameter = deserializeIrValueParameter(proto.extensionReceiver, -1) + if (proto.hasBody()) { + body = deserializeStatementBody(proto.body) as IrBody + } } } } @@ -512,7 +519,7 @@ class IrDeclarationDeserializer( } } - internal fun deserializeIrVariable(proto: ProtoVariable): IrVariable = + fun deserializeIrVariable(proto: ProtoVariable): IrVariable = withDeserializedIrDeclarationBase(proto.base) { symbol, _, startOffset, endOffset, origin, fcode -> val flags = LocalVariableFlags.decode(fcode) val nameType = BinaryNameAndType.decode(proto.nameType) @@ -535,10 +542,12 @@ class IrDeclarationDeserializer( symbolTable.declareEnumEntry(uniqId, { symbol as IrEnumEntrySymbol }) { irFactory.createEnumEntry(startOffset, endOffset, origin, it, deserializeName(proto.name)) }.apply { - if (proto.hasCorrespondingClass()) - correspondingClass = deserializeIrClass(proto.correspondingClass) - if (proto.hasInitializer()) - initializerExpression = deserializeExpressionBody(proto.initializer) + if (!skipMutableState) { + if (proto.hasCorrespondingClass()) + correspondingClass = deserializeIrClass(proto.correspondingClass) + if (proto.hasInitializer()) + initializerExpression = deserializeExpressionBody(proto.initializer) + } } } @@ -607,10 +616,12 @@ class IrDeclarationDeserializer( deserializeIrType(nameAndType.typeIndex), flags.isVar ).apply { - delegate = deserializeIrVariable(proto.delegate) - getter = deserializeIrFunction(proto.getter) - if (proto.hasSetter()) - setter = deserializeIrFunction(proto.setter) + if (!skipMutableState) { + delegate = deserializeIrVariable(proto.delegate) + getter = deserializeIrFunction(proto.getter) + if (proto.hasSetter()) + setter = deserializeIrFunction(proto.setter) + } } } @@ -634,20 +645,22 @@ class IrDeclarationDeserializer( flags.isFakeOverride ) }.apply { - withExternalValue(isExternal) { - if (proto.hasGetter()) { - getter = deserializeIrFunction(proto.getter).also { - it.correspondingPropertySymbol = symbol + if (!skipMutableState) { + withExternalValue(isExternal) { + if (proto.hasGetter()) { + getter = deserializeIrFunction(proto.getter).also { + it.correspondingPropertySymbol = symbol + } } - } - if (proto.hasSetter()) { - setter = deserializeIrFunction(proto.setter).also { - it.correspondingPropertySymbol = symbol + if (proto.hasSetter()) { + setter = deserializeIrFunction(proto.setter).also { + it.correspondingPropertySymbol = symbol + } } - } - if (proto.hasBackingField()) { - backingField = deserializeIrField(proto.backingField).also { - it.correspondingPropertySymbol = symbol + if (proto.hasBackingField()) { + backingField = deserializeIrField(proto.backingField).also { + it.correspondingPropertySymbol = symbol + } } } } @@ -661,7 +674,7 @@ class IrDeclarationDeserializer( allKnownDeclarationOrigins.map { it.objectInstance as IrDeclarationOriginImpl }.associateBy { it.name } } - private fun deserializeIrDeclarationOrigin(protoName: Int): IrDeclarationOriginImpl { + fun deserializeIrDeclarationOrigin(protoName: Int): IrDeclarationOriginImpl { val originName = fileReader.deserializeString(protoName) return declarationOriginIndex[originName] ?: object : IrDeclarationOriginImpl(originName) {} } diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt index 697d702a3c4..36aeeb9ee31 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt @@ -24,7 +24,6 @@ import org.jetbrains.kotlin.library.impl.IrMemoryDeclarationWriter import org.jetbrains.kotlin.library.impl.IrMemoryStringWriter import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.types.Variance -import org.jetbrains.kotlin.backend.common.serialization.proto.AccessorIdSignature as ProtoAccessorIdSignature import org.jetbrains.kotlin.backend.common.serialization.proto.Actual as ProtoActual import org.jetbrains.kotlin.backend.common.serialization.proto.FieldAccessCommon as ProtoFieldAccessCommon import org.jetbrains.kotlin.backend.common.serialization.proto.FileEntry as ProtoFileEntry @@ -53,9 +52,9 @@ import org.jetbrains.kotlin.backend.common.serialization.proto.IrDynamicOperator import org.jetbrains.kotlin.backend.common.serialization.proto.IrDynamicType as ProtoDynamicType import org.jetbrains.kotlin.backend.common.serialization.proto.IrEnumConstructorCall as ProtoEnumConstructorCall import org.jetbrains.kotlin.backend.common.serialization.proto.IrEnumEntry as ProtoEnumEntry -import org.jetbrains.kotlin.backend.common.serialization.proto.IrErrorCallExpression as ProtoErrorCallExpression import org.jetbrains.kotlin.backend.common.serialization.proto.IrErrorDeclaration as ProtoErrorDeclaration import org.jetbrains.kotlin.backend.common.serialization.proto.IrErrorExpression as ProtoErrorExpression +import org.jetbrains.kotlin.backend.common.serialization.proto.IrErrorCallExpression as ProtoErrorCallExpression import org.jetbrains.kotlin.backend.common.serialization.proto.IrErrorType as ProtoErrorType import org.jetbrains.kotlin.backend.common.serialization.proto.IrExpression as ProtoExpression import org.jetbrains.kotlin.backend.common.serialization.proto.IrField as ProtoField @@ -102,13 +101,15 @@ import org.jetbrains.kotlin.backend.common.serialization.proto.Loop as ProtoLoop import org.jetbrains.kotlin.backend.common.serialization.proto.MemberAccessCommon as ProtoMemberAccessCommon import org.jetbrains.kotlin.backend.common.serialization.proto.NullableIrExpression as ProtoNullableIrExpression import org.jetbrains.kotlin.backend.common.serialization.proto.PublicIdSignature as ProtoPublicIdSignature +import org.jetbrains.kotlin.backend.common.serialization.proto.AccessorIdSignature as ProtoAccessorIdSignature open class IrFileSerializer( val messageLogger: IrMessageLogger, private val declarationTable: DeclarationTable, private val expectDescriptorToSymbol: MutableMap, private val bodiesOnlyForInlines: Boolean = false, - private val skipExpects: Boolean = false + private val skipExpects: Boolean = false, + private val skipMutableState: Boolean = false, // required for JS IC caches ) { private val loopIndex = mutableMapOf() private var currentLoopIndex = 0 @@ -154,19 +155,19 @@ open class IrFileSerializer( } } - private fun serializeIrExpressionBody(expression: IrExpression): Int { + fun serializeIrExpressionBody(expression: IrExpression): Int { protoBodyArray.add(XStatementOrExpression.XExpression(serializeExpression(expression))) return protoBodyArray.size - 1 } - private fun serializeIrStatementBody(statement: IrElement): Int { + fun serializeIrStatementBody(statement: IrElement): Int { protoBodyArray.add(XStatementOrExpression.XStatement(serializeStatement(statement))) return protoBodyArray.size - 1 } /* ------- Common fields ---------------------------------------------------- */ - private fun serializeIrDeclarationOrigin(origin: IrDeclarationOrigin): Int = serializeString((origin as IrDeclarationOriginImpl).name) + fun serializeIrDeclarationOrigin(origin: IrDeclarationOrigin): Int = serializeString((origin as IrDeclarationOriginImpl).name) private fun serializeIrStatementOrigin(origin: IrStatementOrigin): Int = serializeString((origin as IrStatementOriginImpl).debugName) @@ -238,7 +239,7 @@ open class IrFileSerializer( return protoIdSignature(idSig) } - private fun protoIdSignature(idSig: IdSignature): Int { + fun protoIdSignature(idSig: IdSignature): Int { return protoIdSignatureMap.getOrPut(idSig) { protoIdSignatureArray.add(serializeIdSignature(idSig)) protoIdSignatureArray.size - 1 @@ -247,41 +248,43 @@ open class IrFileSerializer( /* ------- IrSymbols -------------------------------------------------------- */ - private fun protoSymbolKind(symbol: IrSymbol): BinarySymbolData.SymbolKind = when (symbol) { - is IrAnonymousInitializerSymbol -> - BinarySymbolData.SymbolKind.ANONYMOUS_INIT_SYMBOL - is IrClassSymbol -> - BinarySymbolData.SymbolKind.CLASS_SYMBOL - is IrConstructorSymbol -> - BinarySymbolData.SymbolKind.CONSTRUCTOR_SYMBOL - is IrTypeParameterSymbol -> - BinarySymbolData.SymbolKind.TYPE_PARAMETER_SYMBOL - is IrEnumEntrySymbol -> - BinarySymbolData.SymbolKind.ENUM_ENTRY_SYMBOL - is IrVariableSymbol -> - BinarySymbolData.SymbolKind.VARIABLE_SYMBOL - is IrValueParameterSymbol -> - if (symbol.descriptor is ReceiverParameterDescriptor) // TODO: we use descriptor here. - BinarySymbolData.SymbolKind.RECEIVER_PARAMETER_SYMBOL - else - BinarySymbolData.SymbolKind.VALUE_PARAMETER_SYMBOL - is IrSimpleFunctionSymbol -> - BinarySymbolData.SymbolKind.FUNCTION_SYMBOL - is IrReturnableBlockSymbol -> - BinarySymbolData.SymbolKind.RETURNABLE_BLOCK_SYMBOL - is IrFieldSymbol -> - if (symbol.owner.correspondingPropertySymbol?.owner.let { it == null || it.isDelegated }) - BinarySymbolData.SymbolKind.STANDALONE_FIELD_SYMBOL - else - BinarySymbolData.SymbolKind.FIELD_SYMBOL - is IrPropertySymbol -> - BinarySymbolData.SymbolKind.PROPERTY_SYMBOL - is IrLocalDelegatedPropertySymbol -> - BinarySymbolData.SymbolKind.LOCAL_DELEGATED_PROPERTY_SYMBOL - is IrTypeAliasSymbol -> - BinarySymbolData.SymbolKind.TYPEALIAS_SYMBOL - else -> - TODO("Unexpected symbol kind: $symbol") + companion object { + fun protoSymbolKind(symbol: IrSymbol): BinarySymbolData.SymbolKind = when (symbol) { + is IrAnonymousInitializerSymbol -> + BinarySymbolData.SymbolKind.ANONYMOUS_INIT_SYMBOL + is IrClassSymbol -> + BinarySymbolData.SymbolKind.CLASS_SYMBOL + is IrConstructorSymbol -> + BinarySymbolData.SymbolKind.CONSTRUCTOR_SYMBOL + is IrTypeParameterSymbol -> + BinarySymbolData.SymbolKind.TYPE_PARAMETER_SYMBOL + is IrEnumEntrySymbol -> + BinarySymbolData.SymbolKind.ENUM_ENTRY_SYMBOL + is IrVariableSymbol -> + BinarySymbolData.SymbolKind.VARIABLE_SYMBOL + is IrValueParameterSymbol -> + if (symbol.descriptor is ReceiverParameterDescriptor) // TODO: we use descriptor here. + BinarySymbolData.SymbolKind.RECEIVER_PARAMETER_SYMBOL + else + BinarySymbolData.SymbolKind.VALUE_PARAMETER_SYMBOL + is IrSimpleFunctionSymbol -> + BinarySymbolData.SymbolKind.FUNCTION_SYMBOL + is IrReturnableBlockSymbol -> + BinarySymbolData.SymbolKind.RETURNABLE_BLOCK_SYMBOL + is IrFieldSymbol -> + if (symbol.owner.correspondingPropertySymbol?.owner.let { it == null || it.isDelegated }) + BinarySymbolData.SymbolKind.STANDALONE_FIELD_SYMBOL + else + BinarySymbolData.SymbolKind.FIELD_SYMBOL + is IrPropertySymbol -> + BinarySymbolData.SymbolKind.PROPERTY_SYMBOL + is IrLocalDelegatedPropertySymbol -> + BinarySymbolData.SymbolKind.LOCAL_DELEGATED_PROPERTY_SYMBOL + is IrTypeAliasSymbol -> + BinarySymbolData.SymbolKind.TYPEALIAS_SYMBOL + else -> + TODO("Unexpected symbol kind: $symbol") + } } fun serializeIrSymbol(symbol: IrSymbol): Long { @@ -412,7 +415,7 @@ open class IrFileSerializer( type = (this as? IrTypeProjection)?.type?.toIrTypeKey ) - private fun serializeIrType(type: IrType) = protoTypeMap.getOrPut(type.toIrTypeKey) { + fun serializeIrType(type: IrType) = protoTypeMap.getOrPut(type.toIrTypeKey) { protoTypeArray.add(serializeIrTypeData(type)) protoTypeArray.size - 1 } @@ -518,7 +521,7 @@ open class IrFileSerializer( return proto.build() } - private fun serializeConstructorCall(call: IrConstructorCall): ProtoConstructorCall = + fun serializeConstructorCall(call: IrConstructorCall): ProtoConstructorCall = ProtoConstructorCall.newBuilder().apply { symbol = serializeIrSymbol(call.symbol) constructorTypeArgumentsCount = call.constructorTypeArgumentsCount @@ -741,7 +744,7 @@ open class IrFileSerializer( IrTypeOperator.IMPLICIT_DYNAMIC_CAST -> ProtoTypeOperator.IMPLICIT_DYNAMIC_CAST IrTypeOperator.REINTERPRET_CAST -> - error("Unreachable execution") + ProtoTypeOperator.REINTERPRET_CAST } private fun serializeTypeOp(expression: IrTypeOperatorCall): ProtoTypeOp { @@ -1024,8 +1027,10 @@ open class IrFileSerializer( .setBase(serializeIrDeclarationBase(parameter, ValueParameterFlags.encode(parameter))) .setNameType(serializeNameAndType(parameter.name, parameter.type)) - parameter.varargElementType?.let { proto.setVarargElementType(serializeIrType(it)) } - parameter.defaultValue?.let { proto.setDefaultValue(serializeIrExpressionBody(it.expression)) } + if (!skipMutableState) { + parameter.varargElementType?.let { proto.setVarargElementType(serializeIrType(it)) } + parameter.defaultValue?.let { proto.setDefaultValue(serializeIrExpressionBody(it.expression)) } + } return proto.build() } @@ -1045,18 +1050,21 @@ open class IrFileSerializer( .setBase(serializeIrDeclarationBase(function, flags)) .setNameType(serializeNameAndType(function.name, function.returnType)) - function.typeParameters.forEach { - proto.addTypeParameter(serializeIrTypeParameter(it)) + if (!skipMutableState) { + function.typeParameters.forEach { + proto.addTypeParameter(serializeIrTypeParameter(it)) + } + function.dispatchReceiverParameter?.let { proto.setDispatchReceiver(serializeIrValueParameter(it)) } + function.extensionReceiverParameter?.let { proto.setExtensionReceiver(serializeIrValueParameter(it)) } + function.valueParameters.forEach { + proto.addValueParameter(serializeIrValueParameter(it)) + } + + if (!bodiesOnlyForInlines || function.isInline) { + function.body?.let { proto.body = serializeIrStatementBody(it) } + } } - function.dispatchReceiverParameter?.let { proto.setDispatchReceiver(serializeIrValueParameter(it)) } - function.extensionReceiverParameter?.let { proto.setExtensionReceiver(serializeIrValueParameter(it)) } - function.valueParameters.forEach { - proto.addValueParameter(serializeIrValueParameter(it)) - } - if (!bodiesOnlyForInlines || function.isInline) { - function.body?.let { proto.body = serializeIrStatementBody(it) } - } return proto.build() } @@ -1076,20 +1084,27 @@ open class IrFileSerializer( return proto.build() } - private fun serializeIrAnonymousInit(declaration: IrAnonymousInitializer) = - ProtoAnonymousInit.newBuilder() + private fun serializeIrAnonymousInit(declaration: IrAnonymousInitializer): ProtoAnonymousInit { + val proto = ProtoAnonymousInit.newBuilder() .setBase(serializeIrDeclarationBase(declaration, null)) - .setBody(serializeIrStatementBody(declaration.body)) - .build() + + if (!skipMutableState) { + proto.setBody(serializeIrStatementBody(declaration.body)) + } + + return proto.build() + } private fun serializeIrLocalDelegatedProperty(variable: IrLocalDelegatedProperty): ProtoLocalDelegatedProperty { val proto = ProtoLocalDelegatedProperty.newBuilder() .setBase(serializeIrDeclarationBase(variable, LocalVariableFlags.encode(variable))) .setNameType(serializeNameAndType(variable.name, variable.type)) - .setDelegate(serializeIrVariable(variable.delegate)) - .setGetter(serializeIrFunction(variable.getter)) - variable.setter?.let { proto.setSetter(serializeIrFunction(it)) } + if (!skipMutableState) { + proto.delegate = serializeIrVariable(variable.delegate) + proto.getter = serializeIrFunction(variable.getter) + variable.setter?.let { proto.setSetter(serializeIrFunction(it)) } + } return proto.build() } @@ -1099,15 +1114,11 @@ open class IrFileSerializer( .setBase(serializeIrDeclarationBase(property, PropertyFlags.encode(property))) .setName(serializeName(property.name)) - val backingField = property.backingField - val getter = property.getter - val setter = property.setter - if (backingField != null) - proto.backingField = serializeIrField(backingField) - if (getter != null) - proto.getter = serializeIrFunction(getter) - if (setter != null) - proto.setter = serializeIrFunction(setter) + if (!skipMutableState) { + property.backingField?.let { proto.backingField = serializeIrField(it) } + property.getter?.let { proto.getter = serializeIrFunction(it) } + property.setter?.let { proto.setter = serializeIrFunction(it) } + } return proto.build() } @@ -1116,14 +1127,16 @@ open class IrFileSerializer( val proto = ProtoField.newBuilder() .setBase(serializeIrDeclarationBase(field, FieldFlags.encode(field))) .setNameType(serializeNameAndType(field.name, field.type)) - val initializer = field.initializer?.expression - if (initializer != null) { - proto.initializer = serializeIrExpressionBody(initializer) + if (!skipMutableState) { + val initializer = field.initializer?.expression + if (initializer != null) { + proto.initializer = serializeIrExpressionBody(initializer) + } } return proto.build() } - private fun serializeIrVariable(variable: IrVariable): ProtoVariable { + fun serializeIrVariable(variable: IrVariable): ProtoVariable { val proto = ProtoVariable.newBuilder() .setBase(serializeIrDeclarationBase(variable, LocalVariableFlags.encode(variable))) .setNameType(serializeNameAndType(variable.name, variable.type)) @@ -1136,19 +1149,21 @@ open class IrFileSerializer( .setBase(serializeIrDeclarationBase(clazz, ClassFlags.encode(clazz))) .setName(serializeName(clazz.name)) - clazz.declarations.forEach { - if (memberNeedsSerialization(it)) proto.addDeclaration(serializeDeclaration(it)) - } + if (!skipMutableState) { + clazz.declarations.forEach { + if (memberNeedsSerialization(it)) proto.addDeclaration(serializeDeclaration(it)) + } - clazz.typeParameters.forEach { - proto.addTypeParameter(serializeIrTypeParameter(it)) - } + clazz.typeParameters.forEach { + proto.addTypeParameter(serializeIrTypeParameter(it)) + } - clazz.superTypes.forEach { - proto.addSuperType(serializeIrType(it)) - } + clazz.thisReceiver?.let { proto.thisReceiver = serializeIrValueParameter(it) } - clazz.thisReceiver?.let { proto.thisReceiver = serializeIrValueParameter(it) } + clazz.superTypes.forEach { + proto.addSuperType(serializeIrType(it)) + } + } return proto.build() } @@ -1160,7 +1175,9 @@ open class IrFileSerializer( .setNameType(serializeNameAndType(typeAlias.name, typeAlias.expandedType)) typeAlias.typeParameters.forEach { - proto.addTypeParameter(serializeIrTypeParameter(it)) + if (!skipMutableState) { + proto.addTypeParameter(serializeIrTypeParameter(it)) + } } return proto.build() @@ -1177,16 +1194,18 @@ open class IrFileSerializer( .setBase(serializeIrDeclarationBase(enumEntry, null)) .setName(serializeName(enumEntry.name)) - enumEntry.initializerExpression?.let { - proto.initializer = serializeIrExpressionBody(it.expression) - } - enumEntry.correspondingClass?.let { - proto.correspondingClass = serializeIrClass(it) + if (!skipMutableState) { + enumEntry.initializerExpression?.let { + proto.initializer = serializeIrExpressionBody(it.expression) + } + enumEntry.correspondingClass?.let { + proto.correspondingClass = serializeIrClass(it) + } } return proto.build() } - private fun serializeDeclaration(declaration: IrDeclaration): ProtoDeclaration { + fun serializeDeclaration(declaration: IrDeclaration): ProtoDeclaration { val proto = ProtoDeclaration.newBuilder() when (declaration) { @@ -1279,6 +1298,41 @@ open class IrFileSerializer( } } + fun serializeDeclarationsForIC(file: IrFile, declarations: Iterable): SerializedIrFile { + val proto = ProtoFile.newBuilder() + .setFileEntry(serializeFileEntry(file.fileEntry)) + .addAllFqName(serializeFqName(file.fqName.asString())) + + val topLevelDeclarations = mutableListOf() + + for (declaration in declarations) { + val byteArray = serializeDeclaration(declaration).toByteArray() + val idSig = declarationTable.signatureByDeclaration(declaration) + + // TODO: keep order similar + // ^ TODO what does that mean? + val sigIndex = protoIdSignatureMap[idSig] + ?: if (declaration is IrErrorDeclaration) protoIdSignature(idSig) else error("Not found ID for $idSig (${declaration.render()})") + + topLevelDeclarations.add(TopLevelDeclaration(sigIndex, idSig.toString(), byteArray)) + } + + topLevelDeclarations.forEach { + proto.addDeclarationId(it.id) + } + + return SerializedIrFile( + proto.build().toByteArray(), + file.fqName.asString(), + file.path, + IrMemoryArrayWriter(protoTypeArray.map { it.toByteArray() }).writeIntoMemory(), + IrMemoryArrayWriter(protoIdSignatureArray.map { it.toByteArray() }).writeIntoMemory(), + IrMemoryArrayWriter(protoStringArray.map { it.toByteArray() }).writeIntoMemory(), + IrMemoryArrayWriter(protoBodyArray.map { it.toByteArray() }).writeIntoMemory(), + IrMemoryDeclarationWriter(topLevelDeclarations).writeIntoMemory() + ) + } + fun serializeIrFile(file: IrFile): SerializedIrFile { val topLevelDeclarations = mutableListOf() diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrFileSerializer.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrFileSerializer.kt index c5c28cff376..84a81912402 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrFileSerializer.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrFileSerializer.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.serialization.DeclarationTable import org.jetbrains.kotlin.backend.common.serialization.IrFileSerializer import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.ir.declarations.IrAnnotationContainer +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.ir.util.hasAnnotation @@ -19,13 +20,15 @@ class JsIrFileSerializer( declarationTable: DeclarationTable, expectDescriptorToSymbol: MutableMap, skipExpects: Boolean, - bodiesOnlyForInlines: Boolean = false + bodiesOnlyForInlines: Boolean = false, + icMode: Boolean = false, ) : IrFileSerializer( messageLogger, declarationTable, expectDescriptorToSymbol, bodiesOnlyForInlines = bodiesOnlyForInlines, - skipExpects = skipExpects + skipExpects = skipExpects, + skipMutableState = icMode, ) { companion object { private val JS_EXPORT_FQN = FqName("kotlin.js.JsExport")