[Wasm] Replace ClassId and InterfaceId with single TypeId
This commit is contained in:
committed by
Space Team
parent
5a46cb1c40
commit
49beec33b4
@@ -63,6 +63,7 @@ class WasmSymbols(
|
||||
override val primitiveClassesObject = getInternalClass("PrimitiveClasses")
|
||||
override val kTypeClass: IrClassSymbol = getIrClass(FqName("kotlin.reflect.KClass"))
|
||||
|
||||
val getTypeInfoTypeDataByPtr: IrSimpleFunctionSymbol = getInternalFunction("getTypeInfoTypeDataByPtr")
|
||||
val wasmTypeInfoData: IrClassSymbol = getInternalClass("TypeInfoData")
|
||||
}
|
||||
|
||||
@@ -208,8 +209,7 @@ class WasmSymbols(
|
||||
val suiteFun = maybeGetFunction("suite", kotlinTestPackage)
|
||||
val startUnitTests = maybeGetFunction("startUnitTests", kotlinTestPackage)
|
||||
|
||||
val wasmClassId = getInternalFunction("wasmClassId")
|
||||
val wasmInterfaceId = getInternalFunction("wasmInterfaceId")
|
||||
val wasmTypeId = getInternalFunction("wasmTypeId")
|
||||
|
||||
val wasmIsInterface = getInternalFunction("wasmIsInterface")
|
||||
|
||||
|
||||
+1
-2
@@ -56,8 +56,7 @@ internal class WasmUsefulDeclarationProcessor(
|
||||
true
|
||||
}
|
||||
|
||||
context.wasmSymbols.wasmClassId,
|
||||
context.wasmSymbols.wasmInterfaceId,
|
||||
context.wasmSymbols.wasmTypeId,
|
||||
context.wasmSymbols.refCastNull,
|
||||
context.wasmSymbols.refTest,
|
||||
context.wasmSymbols.boxIntrinsic,
|
||||
|
||||
+5
-13
@@ -317,7 +317,7 @@ class BodyGenerator(
|
||||
body.buildRefNull(WasmHeapType.Simple.Data, location)
|
||||
}
|
||||
|
||||
body.buildConstI32Symbol(context.referenceClassId(klassSymbol), location)
|
||||
body.buildConstI32Symbol(context.referenceTypeId(klassSymbol), location)
|
||||
body.buildConstI32(0, location) // Any::_hashCode
|
||||
body.commentGroupEnd()
|
||||
}
|
||||
@@ -519,23 +519,15 @@ class BodyGenerator(
|
||||
val location = call.getSourceLocation()
|
||||
|
||||
when (function.symbol) {
|
||||
wasmSymbols.wasmClassId -> {
|
||||
wasmSymbols.wasmTypeId -> {
|
||||
val klass = call.getTypeArgument(0)!!.getClass()
|
||||
?: error("No class given for wasmClassId intrinsic")
|
||||
assert(!klass.isInterface)
|
||||
body.buildConstI32Symbol(context.referenceClassId(klass.symbol), location)
|
||||
}
|
||||
|
||||
wasmSymbols.wasmInterfaceId -> {
|
||||
val irInterface = call.getTypeArgument(0)!!.getClass()
|
||||
?: error("No interface given for wasmInterfaceId intrinsic")
|
||||
assert(irInterface.isInterface)
|
||||
body.buildConstI32Symbol(context.referenceInterfaceId(irInterface.symbol), location)
|
||||
?: error("No class given for wasmTypeId intrinsic")
|
||||
body.buildConstI32Symbol(context.referenceTypeId(klass.symbol), location)
|
||||
}
|
||||
|
||||
wasmSymbols.wasmIsInterface -> {
|
||||
val irInterface = call.getTypeArgument(0)!!.getClass()
|
||||
?: error("No interface given for wasmInterfaceId intrinsic")
|
||||
?: error("No interface given for wasmIsInterface intrinsic")
|
||||
assert(irInterface.isInterface)
|
||||
if (irInterface.symbol in hierarchyDisjointUnions) {
|
||||
val classITable = context.referenceClassITableGcType(irInterface.symbol)
|
||||
|
||||
+2
-2
@@ -416,7 +416,7 @@ class DeclarationGenerator(
|
||||
|
||||
val superClass = classMetadata.klass.getSuperClass(context.backendContext.irBuiltIns)
|
||||
val superTypeId = superClass?.let {
|
||||
ConstantDataIntField("SuperTypeId", context.referenceClassId(it.symbol))
|
||||
ConstantDataIntField("SuperTypeId", context.referenceTypeId(it.symbol))
|
||||
} ?: ConstantDataIntField("SuperTypeId", -1)
|
||||
|
||||
val typeInfoContent = mutableListOf(typeInfo, superTypeId)
|
||||
@@ -435,7 +435,7 @@ class DeclarationGenerator(
|
||||
val size = ConstantDataIntField("size", interfaces.size)
|
||||
val interfaceIds = ConstantDataIntArray(
|
||||
"interfaceIds",
|
||||
interfaces.map { context.referenceInterfaceId(it.symbol) },
|
||||
interfaces.map { context.referenceTypeId(it.symbol) },
|
||||
)
|
||||
|
||||
return ConstantDataStruct(
|
||||
|
||||
+27
-26
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.ir.declarations.IrExternalPackageFragment
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||
import org.jetbrains.kotlin.ir.util.getPackageFragment
|
||||
import org.jetbrains.kotlin.ir.util.isInterface
|
||||
import org.jetbrains.kotlin.wasm.ir.*
|
||||
import org.jetbrains.kotlin.wasm.ir.source.location.SourceLocation
|
||||
|
||||
@@ -33,9 +34,7 @@ class WasmCompiledModuleFragment(val irBuiltIns: IrBuiltIns) {
|
||||
ReferencableAndDefinable<IrClassSymbol, WasmTypeDeclaration>()
|
||||
val classITableInterfaceSlot =
|
||||
ReferencableAndDefinable<IrClassSymbol, Int>()
|
||||
val classIds =
|
||||
ReferencableElements<IrClassSymbol, Int>()
|
||||
val interfaceId =
|
||||
val typeIds =
|
||||
ReferencableElements<IrClassSymbol, Int>()
|
||||
val stringLiteralAddress =
|
||||
ReferencableElements<String, Int>()
|
||||
@@ -119,20 +118,20 @@ class WasmCompiledModuleFragment(val irBuiltIns: IrBuiltIns) {
|
||||
wasmSymbol.bind(canonicalFunctionTypes.getValue(functionTypes.defined.getValue(irSymbol)))
|
||||
}
|
||||
|
||||
val klassIds = mutableMapOf<IrClassSymbol, Int>()
|
||||
var currentDataSectionAddress = 0
|
||||
for (typeInfoElement in typeInfo.elements) {
|
||||
val ir = typeInfo.wasmToIr.getValue(typeInfoElement)
|
||||
klassIds[ir] = currentDataSectionAddress
|
||||
currentDataSectionAddress += typeInfoElement.sizeInBytes
|
||||
var interfaceId = 0
|
||||
typeIds.unbound.forEach { (klassSymbol, wasmSymbol) ->
|
||||
if (klassSymbol.owner.isInterface) {
|
||||
interfaceId--
|
||||
wasmSymbol.bind(interfaceId)
|
||||
} else {
|
||||
wasmSymbol.bind(currentDataSectionAddress)
|
||||
currentDataSectionAddress += typeInfo.defined.getValue(klassSymbol).sizeInBytes
|
||||
}
|
||||
}
|
||||
|
||||
currentDataSectionAddress = alignUp(currentDataSectionAddress, INT_SIZE_BYTES)
|
||||
scratchMemAddr.bind(currentDataSectionAddress)
|
||||
|
||||
bind(classIds.unbound, klassIds)
|
||||
interfaceId.unbound.onEachIndexed { index, entry -> entry.value.bind(index) }
|
||||
|
||||
val stringDataSectionBytes = mutableListOf<Byte>()
|
||||
var stringDataSectionStart = 0
|
||||
var stringLiteralCount = 0
|
||||
@@ -160,9 +159,23 @@ class WasmCompiledModuleFragment(val irBuiltIns: IrBuiltIns) {
|
||||
val constData = ConstantDataIntegerArray("constant_array", constantArraySegment.first, integerSize)
|
||||
data.add(WasmData(WasmDataMode.Passive, constData.toBytes()))
|
||||
}
|
||||
typeInfo.buildData(data, address = { klassIds.getValue(it) })
|
||||
|
||||
val masterInitFunctionType = WasmFunctionType(emptyList(), emptyList())
|
||||
typeIds.unbound.forEach { (klassSymbol, typeId) ->
|
||||
if (!klassSymbol.owner.isInterface) {
|
||||
val instructions = mutableListOf<WasmInstr>()
|
||||
WasmIrExpressionBuilder(instructions).buildConstI32(
|
||||
typeId.owner,
|
||||
SourceLocation.NoLocation("Compile time data per class")
|
||||
)
|
||||
val typeData = WasmData(
|
||||
WasmDataMode.Active(0, instructions),
|
||||
typeInfo.defined.getValue(klassSymbol).toBytes()
|
||||
)
|
||||
data.add(typeData)
|
||||
}
|
||||
}
|
||||
|
||||
val masterInitFunctionType = WasmFunctionType(emptyList(), emptyList())
|
||||
val masterInitFunction = WasmFunction.Defined("__init", WasmSymbol(masterInitFunctionType))
|
||||
with(WasmIrExpressionBuilder(masterInitFunction.instructions)) {
|
||||
initFunctions.sortedBy { it.priority }.forEach {
|
||||
@@ -250,18 +263,6 @@ private fun irSymbolDebugDump(symbol: Any?): String =
|
||||
else -> symbol.toString()
|
||||
}
|
||||
|
||||
inline fun WasmCompiledModuleFragment.ReferencableAndDefinable<IrClassSymbol, ConstantDataElement>.buildData(
|
||||
into: MutableList<WasmData>,
|
||||
address: (IrClassSymbol) -> Int
|
||||
) {
|
||||
elements.mapTo(into) {
|
||||
val id = address(wasmToIr.getValue(it))
|
||||
val offset = mutableListOf<WasmInstr>()
|
||||
WasmIrExpressionBuilder(offset).buildConstI32(id, SourceLocation.NoLocation("Compile time data per class"))
|
||||
WasmData(WasmDataMode.Active(0, offset), it.toBytes())
|
||||
}
|
||||
}
|
||||
|
||||
fun alignUp(x: Int, alignment: Int): Int {
|
||||
assert(alignment and (alignment - 1) == 0) { "power of 2 expected" }
|
||||
return (x + alignment - 1) and (alignment - 1).inv()
|
||||
|
||||
+2
-6
@@ -177,12 +177,8 @@ class WasmModuleCodegenContext(
|
||||
fun referenceFunctionType(irFunction: IrFunctionSymbol): WasmSymbol<WasmFunctionType> =
|
||||
wasmFragment.functionTypes.reference(irFunction)
|
||||
|
||||
fun referenceClassId(irClass: IrClassSymbol): WasmSymbol<Int> =
|
||||
wasmFragment.classIds.reference(irClass)
|
||||
|
||||
fun referenceInterfaceId(irInterface: IrClassSymbol): WasmSymbol<Int> {
|
||||
return wasmFragment.interfaceId.reference(irInterface)
|
||||
}
|
||||
fun referenceTypeId(irClass: IrClassSymbol): WasmSymbol<Int> =
|
||||
wasmFragment.typeIds.reference(irClass)
|
||||
|
||||
fun getStructFieldRef(field: IrField): WasmSymbol<Int> {
|
||||
val klass = field.parentAsClass
|
||||
|
||||
+2
-6
@@ -90,19 +90,15 @@ private fun IrBuilderWithScope.createAssociatedObjectAdd(
|
||||
0,
|
||||
irGet(wasmSymbols.initAssociatedObjects.owner.valueParameters[0])
|
||||
)
|
||||
val classIdGetter = when (targetClass.owner.isInterface) {
|
||||
true -> wasmSymbols.wasmInterfaceId
|
||||
false -> wasmSymbols.wasmClassId
|
||||
}
|
||||
addCall.putValueArgument(
|
||||
1,
|
||||
irCall(classIdGetter, irBuiltIns.intType).also {
|
||||
irCall(wasmSymbols.wasmTypeId, irBuiltIns.intType).also {
|
||||
it.putTypeArgument(0, targetClass.defaultType)
|
||||
}
|
||||
)
|
||||
addCall.putValueArgument(
|
||||
2,
|
||||
irCall(wasmSymbols.wasmClassId, irBuiltIns.intType).also {
|
||||
irCall(wasmSymbols.wasmTypeId, irBuiltIns.intType).also {
|
||||
it.putTypeArgument(0, keyAnnotation.defaultType)
|
||||
}
|
||||
)
|
||||
|
||||
+21
-16
@@ -150,26 +150,31 @@ class BuiltInsLowering(val context: WasmBackendContext) : FileLoweringPass {
|
||||
return irCall(call, newSymbol, argumentsAsReceivers = true)
|
||||
}
|
||||
symbols.reflectionSymbols.getClassData -> {
|
||||
val infoDataCtor = symbols.reflectionSymbols.wasmTypeInfoData.constructors.first()
|
||||
val type = call.getTypeArgument(0)!!
|
||||
val isInterface = type.isInterface()
|
||||
val fqName = type.classFqName!!
|
||||
val fqnShouldBeEmitted =
|
||||
context.configuration.languageVersionSettings.getFlag(AnalysisFlags.allowFullyQualifiedNameInKClass)
|
||||
val packageName = if (fqnShouldBeEmitted) fqName.parentOrNull()?.asString() ?: "" else ""
|
||||
val typeName = fqName.shortName().asString()
|
||||
val klass = type.classOrNull?.owner ?: error("Invalid type")
|
||||
|
||||
return with(builder) {
|
||||
val wasmIdGetter = if (type.isInterface()) symbols.wasmInterfaceId else symbols.wasmClassId
|
||||
val typeId = irCall(wasmIdGetter).also {
|
||||
it.putTypeArgument(0, type)
|
||||
}
|
||||
val typeId = builder.irCall(symbols.wasmTypeId).also {
|
||||
it.putTypeArgument(0, type)
|
||||
}
|
||||
|
||||
irCallConstructor(infoDataCtor, emptyList()).also {
|
||||
if (!klass.isInterface) {
|
||||
return builder.irCall(context.wasmSymbols.reflectionSymbols.getTypeInfoTypeDataByPtr).also {
|
||||
it.putValueArgument(0, typeId)
|
||||
it.putValueArgument(1, isInterface.toIrConst(context.irBuiltIns.booleanType))
|
||||
it.putValueArgument(2, packageName.toIrConst(context.irBuiltIns.stringType))
|
||||
it.putValueArgument(3, typeName.toIrConst(context.irBuiltIns.stringType))
|
||||
}
|
||||
} else {
|
||||
val infoDataCtor = symbols.reflectionSymbols.wasmTypeInfoData.constructors.first()
|
||||
val fqName = type.classFqName!!
|
||||
val fqnShouldBeEmitted =
|
||||
context.configuration.languageVersionSettings.getFlag(AnalysisFlags.allowFullyQualifiedNameInKClass)
|
||||
val packageName = if (fqnShouldBeEmitted) fqName.parentOrNull()?.asString() ?: "" else ""
|
||||
val typeName = fqName.shortName().asString()
|
||||
|
||||
return with(builder) {
|
||||
irCallConstructor(infoDataCtor, emptyList()).also {
|
||||
it.putValueArgument(0, typeId)
|
||||
it.putValueArgument(1, packageName.toIrConst(context.irBuiltIns.stringType))
|
||||
it.putValueArgument(2, typeName.toIrConst(context.irBuiltIns.stringType))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user