[KLIB] Pass containsErrorCode flag from library/IC cache into deserializer

- Make deserializer track whether error node are allowed.
This commit is contained in:
Roman Artemev
2020-09-29 14:41:59 +03:00
parent 28c6d17ab4
commit a4945878aa
6 changed files with 43 additions and 22 deletions
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.library.IrLibrary
import org.jetbrains.kotlin.library.SerializedIrFile import org.jetbrains.kotlin.library.SerializedIrFile
import org.jetbrains.kotlin.library.impl.* import org.jetbrains.kotlin.library.impl.*
class ICData(val icData: List<SerializedIrFile>, val containsErrorCode: Boolean)
class ICKotlinLibrary(private val icData: List<SerializedIrFile>) : IrLibrary { class ICKotlinLibrary(private val icData: List<SerializedIrFile>) : IrLibrary {
override val dataFlowGraph: ByteArray? = null override val dataFlowGraph: ByteArray? = null
@@ -114,7 +114,8 @@ abstract class IrFileDeserializer(
val symbolTable: SymbolTable, val symbolTable: SymbolTable,
protected var deserializeBodies: Boolean, protected var deserializeBodies: Boolean,
private val deserializeFakeOverrides: Boolean, private val deserializeFakeOverrides: Boolean,
private val fakeOverrideQueue: MutableList<IrClass> private val fakeOverrideQueue: MutableList<IrClass>,
private val allowErrorNodes: Boolean
) { ) {
protected val irFactory: IrFactory get() = symbolTable.irFactory protected val irFactory: IrFactory get() = symbolTable.irFactory
@@ -202,6 +203,7 @@ abstract class IrFileDeserializer(
} }
private fun deserializeErrorType(proto: ProtoErrorType): IrErrorType { private fun deserializeErrorType(proto: ProtoErrorType): IrErrorType {
require(allowErrorNodes) { "IrErrorType found but error code is not allowed" }
val annotations = deserializeAnnotations(proto.annotationList) val annotations = deserializeAnnotations(proto.annotationList)
return IrErrorTypeImpl(null, annotations, Variance.INVARIANT) return IrErrorTypeImpl(null, annotations, Variance.INVARIANT)
} }
@@ -468,6 +470,9 @@ abstract class IrFileDeserializer(
proto: ProtoErrorExpression, proto: ProtoErrorExpression,
start: Int, end: Int, type: IrType start: Int, end: Int, type: IrType
): IrErrorExpression { ): IrErrorExpression {
require(allowErrorNodes) {
"IrErrorExpression($start, $end, \"${deserializeString(proto.description)}\") found but error code is not allowed"
}
return IrErrorExpressionImpl(start, end, type, deserializeString(proto.description)) return IrErrorExpressionImpl(start, end, type, deserializeString(proto.description))
} }
@@ -475,6 +480,9 @@ abstract class IrFileDeserializer(
proto: ProtoErrorCallExpression, proto: ProtoErrorCallExpression,
start: Int, end: Int, type: IrType start: Int, end: Int, type: IrType
): IrErrorCallExpression { ): IrErrorCallExpression {
require(allowErrorNodes) {
"IrErrorCallExpressionImpl($start, $end, \"${deserializeString(proto.description)}\") found but error code is not allowed"
}
return IrErrorCallExpressionImpl(start, end, type, deserializeString(proto.description)).apply { return IrErrorCallExpressionImpl(start, end, type, deserializeString(proto.description)).apply {
if (proto.hasReceiver()) { if (proto.hasReceiver()) {
explicitReceiver = deserializeExpression(proto.receiver) explicitReceiver = deserializeExpression(proto.receiver)
@@ -1110,6 +1118,7 @@ abstract class IrFileDeserializer(
} }
private fun deserializeErrorDeclaration(proto: ProtoErrorDeclaration): IrErrorDeclaration { private fun deserializeErrorDeclaration(proto: ProtoErrorDeclaration): IrErrorDeclaration {
require(allowErrorNodes) { "IrErrorDeclaration found but error code is not allowed" }
val coordinates = BinaryCoordinates.decode(proto.coordinates) val coordinates = BinaryCoordinates.decode(proto.coordinates)
val descriptor = WrappedErrorDescriptor() val descriptor = WrappedErrorDescriptor()
return irFactory.createErrorDeclaration(coordinates.startOffset, coordinates.endOffset, descriptor).also { return irFactory.createErrorDeclaration(coordinates.startOffset, coordinates.endOffset, descriptor).also {
@@ -77,7 +77,7 @@ abstract class KotlinIrLinker(
private lateinit var linkerExtensions: Collection<IrDeserializer.IrLinkerExtension> private lateinit var linkerExtensions: Collection<IrDeserializer.IrLinkerExtension>
abstract inner class BasicIrModuleDeserializer(moduleDescriptor: ModuleDescriptor, override val klib: IrLibrary, override val strategy: DeserializationStrategy) : abstract inner class BasicIrModuleDeserializer(moduleDescriptor: ModuleDescriptor, override val klib: IrLibrary, override val strategy: DeserializationStrategy, private val containsErrorCode: Boolean = false) :
IrModuleDeserializer(moduleDescriptor) { IrModuleDeserializer(moduleDescriptor) {
private val fileToDeserializerMap = mutableMapOf<IrFile, IrDeserializerForFile>() private val fileToDeserializerMap = mutableMapOf<IrFile, IrDeserializerForFile>()
@@ -122,7 +122,7 @@ abstract class KotlinIrLinker(
for (i in 0 until fileCount) { for (i in 0 until fileCount) {
val fileStream = klib.file(i).codedInputStream val fileStream = klib.file(i).codedInputStream
files.add(deserializeIrFile(ProtoFile.parseFrom(fileStream, newInstance()), i, delegate)) files.add(deserializeIrFile(ProtoFile.parseFrom(fileStream, newInstance()), i, delegate, containsErrorCode))
} }
moduleFragment.files.addAll(files) moduleFragment.files.addAll(files)
@@ -155,20 +155,22 @@ abstract class KotlinIrLinker(
override val moduleFragment: IrModuleFragment = IrModuleFragmentImpl(moduleDescriptor, builtIns, emptyList()) override val moduleFragment: IrModuleFragment = IrModuleFragmentImpl(moduleDescriptor, builtIns, emptyList())
private fun deserializeIrFile(fileProto: ProtoFile, fileIndex: Int, moduleDeserializer: IrModuleDeserializer): IrFile { private fun deserializeIrFile(fileProto: ProtoFile, fileIndex: Int, moduleDeserializer: IrModuleDeserializer, allowErrorNodes: Boolean): IrFile {
val fileName = fileProto.fileEntry.name val fileName = fileProto.fileEntry.name
val fileEntry = NaiveSourceBasedFileEntryImpl(fileName, fileProto.fileEntry.lineStartOffsetsList.toIntArray()) val fileEntry = NaiveSourceBasedFileEntryImpl(fileName, fileProto.fileEntry.lineStartOffsetsList.toIntArray())
val fileDeserializer = val fileDeserializer =
IrDeserializerForFile(fileProto.annotationList, IrDeserializerForFile(
fileProto.actualsList, fileProto.annotationList,
fileIndex, fileProto.actualsList,
!strategy.needBodies, fileIndex,
strategy.inlineBodies, !strategy.needBodies,
deserializeFakeOverrides, strategy.inlineBodies,
moduleDeserializer).apply { deserializeFakeOverrides,
moduleDeserializer, allowErrorNodes
).apply {
// Explicitly exported declarations (e.g. top-level initializers) must be deserialized before all other declarations. // Explicitly exported declarations (e.g. top-level initializers) must be deserialized before all other declarations.
// Thus we schedule their deserialization in deserializer's constructor. // Thus we schedule their deserialization in deserializer's constructor.
@@ -230,8 +232,9 @@ abstract class KotlinIrLinker(
onlyHeaders: Boolean, onlyHeaders: Boolean,
inlineBodies: Boolean, inlineBodies: Boolean,
deserializeFakeOverrides: Boolean, deserializeFakeOverrides: Boolean,
private val moduleDeserializer: IrModuleDeserializer private val moduleDeserializer: IrModuleDeserializer,
) : IrFileDeserializer(logger, builtIns, symbolTable, !onlyHeaders, deserializeFakeOverrides, fakeOverrideClassQueue) { allowErrorNodes: Boolean
) : IrFileDeserializer(logger, builtIns, symbolTable, !onlyHeaders, deserializeFakeOverrides, fakeOverrideClassQueue, allowErrorNodes) {
private var fileLoops = mutableMapOf<Int, IrLoop>() private var fileLoops = mutableMapOf<Int, IrLoop>()
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContextImpl import org.jetbrains.kotlin.backend.common.extensions.IrPluginContextImpl
import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideChecker import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideChecker
import org.jetbrains.kotlin.backend.common.serialization.DeserializationStrategy import org.jetbrains.kotlin.backend.common.serialization.DeserializationStrategy
import org.jetbrains.kotlin.backend.common.serialization.ICData
import org.jetbrains.kotlin.backend.common.serialization.KlibIrVersion import org.jetbrains.kotlin.backend.common.serialization.KlibIrVersion
import org.jetbrains.kotlin.backend.common.serialization.knownBuiltins import org.jetbrains.kotlin.backend.common.serialization.knownBuiltins
import org.jetbrains.kotlin.backend.common.serialization.mangle.ManglerChecker import org.jetbrains.kotlin.backend.common.serialization.mangle.ManglerChecker
@@ -160,7 +161,7 @@ fun generateKLib(
psi2IrContext.symbolTable, psi2IrContext.symbolTable,
functionFactory, functionFactory,
feContext, feContext,
serializedIrFiles, serializedIrFiles?.let { ICData(it, errorPolicy.allowErrors) },
deserializeFakeOverrides deserializeFakeOverrides
) )
@@ -19,14 +19,15 @@ import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable
import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.ir.util.TypeTranslator import org.jetbrains.kotlin.ir.util.TypeTranslator
import org.jetbrains.kotlin.library.IrLibrary import org.jetbrains.kotlin.library.IrLibrary
import org.jetbrains.kotlin.library.SerializedIrFile import org.jetbrains.kotlin.library.KotlinLibrary
import org.jetbrains.kotlin.library.containsErrorCode
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
class JsIrLinker( class JsIrLinker(
private val currentModule: ModuleDescriptor?, logger: LoggingContext, builtIns: IrBuiltIns, symbolTable: SymbolTable, private val currentModule: ModuleDescriptor?, logger: LoggingContext, builtIns: IrBuiltIns, symbolTable: SymbolTable,
override val functionalInterfaceFactory: IrAbstractFunctionFactory, override val functionalInterfaceFactory: IrAbstractFunctionFactory,
override val translationPluginContext: TranslationPluginContext?, override val translationPluginContext: TranslationPluginContext?,
private val icData: List<SerializedIrFile>? = null, private val icData: ICData? = null,
deserializeFakeOverrides: Boolean = FakeOverrideControl.deserializeFakeOverrides deserializeFakeOverrides: Boolean = FakeOverrideControl.deserializeFakeOverrides
) : KotlinIrLinker(currentModule, logger, builtIns, symbolTable, emptyList(), deserializeFakeOverrides) { ) : KotlinIrLinker(currentModule, logger, builtIns, symbolTable, emptyList(), deserializeFakeOverrides) {
@@ -35,17 +36,20 @@ class JsIrLinker(
override fun isBuiltInModule(moduleDescriptor: ModuleDescriptor): Boolean = override fun isBuiltInModule(moduleDescriptor: ModuleDescriptor): Boolean =
moduleDescriptor === moduleDescriptor.builtIns.builtInsModule moduleDescriptor === moduleDescriptor.builtIns.builtInsModule
override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary?, strategy: DeserializationStrategy): IrModuleDeserializer = private val IrLibrary.libContainsErrorCode: Boolean
JsModuleDeserializer(moduleDescriptor, klib ?: error("Expecting kotlin library"), strategy) get() = this is KotlinLibrary && this.containsErrorCode
private inner class JsModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, strategy: DeserializationStrategy) : override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary?, strategy: DeserializationStrategy): IrModuleDeserializer =
KotlinIrLinker.BasicIrModuleDeserializer(moduleDescriptor, klib, strategy) JsModuleDeserializer(moduleDescriptor, klib ?: error("Expecting kotlin library"), strategy, klib.libContainsErrorCode)
private inner class JsModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, strategy: DeserializationStrategy, allowErrorCode: Boolean) :
KotlinIrLinker.BasicIrModuleDeserializer(moduleDescriptor, klib, strategy, allowErrorCode)
override fun createCurrentModuleDeserializer(moduleFragment: IrModuleFragment, dependencies: Collection<IrModuleDeserializer>): IrModuleDeserializer { override fun createCurrentModuleDeserializer(moduleFragment: IrModuleFragment, dependencies: Collection<IrModuleDeserializer>): IrModuleDeserializer {
val currentModuleDeserializer = super.createCurrentModuleDeserializer(moduleFragment, dependencies) val currentModuleDeserializer = super.createCurrentModuleDeserializer(moduleFragment, dependencies)
icData?.let { icData?.let {
return CurrentModuleWithICDeserializer(currentModuleDeserializer, symbolTable, builtIns, it) { lib -> return CurrentModuleWithICDeserializer(currentModuleDeserializer, symbolTable, builtIns, it.icData) { lib ->
JsModuleDeserializer(currentModuleDeserializer.moduleDescriptor, lib, currentModuleDeserializer.strategy) JsModuleDeserializer(currentModuleDeserializer.moduleDescriptor, lib, currentModuleDeserializer.strategy, it.containsErrorCode)
} }
} }
return currentModuleDeserializer return currentModuleDeserializer
@@ -78,3 +78,6 @@ val KotlinLibrary.exportForwardDeclarations: List<String>
val BaseKotlinLibrary.nativeTargets: List<String> val BaseKotlinLibrary.nativeTargets: List<String>
get() = manifestProperties.propertyList(KLIB_PROPERTY_NATIVE_TARGETS) get() = manifestProperties.propertyList(KLIB_PROPERTY_NATIVE_TARGETS)
val KotlinLibrary.containsErrorCode: Boolean
get() = manifestProperties.getProperty(KLIB_PROPERTY_CONTAINS_ERROR_CODE) == "true"