Skip to content

Commit

Permalink
[Wasm] Fix invalid Associated Object for interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
igoriakovlev authored and qodana-bot committed Sep 21, 2024
1 parent 49fbf89 commit 2c594f0
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class WasmCompiledModuleFragment(
private val serviceCodeLocation = SourceLocation.NoLocation("Generated service code")
private val parameterlessNoReturnFunctionType = WasmFunctionType(emptyList(), emptyList())
private val canonicalFunctionTypes = LinkedHashMap<WasmFunctionType, WasmFunctionType>()
private val classIds = mutableMapOf<IdSignature, Int>()
private val typeIds = mutableMapOf<IdSignature, Int>()
private val data = mutableListOf<WasmData>()
private val exports = mutableListOf<WasmExport<*>>()
private val fieldInitializerFunction = WasmFunction.Defined("_fieldInitialize", WasmSymbol(parameterlessNoReturnFunctionType))
Expand Down Expand Up @@ -376,13 +376,13 @@ class WasmCompiledModuleFragment(
with(WasmIrExpressionBuilder(tryGetAssociatedObject.instructions)) {
wasmCompiledFileFragments.forEach { fragment ->
for ((klass, associatedObjectsInstanceGetters) in fragment.classAssociatedObjectsInstanceGetters) {
val klassId = classIds[klass]!!
val klassId = typeIds[klass]!!
buildGetLocal(WasmLocal(0, "classId", WasmI32, true), serviceCodeLocation)
buildConstI32(klassId, serviceCodeLocation)
buildInstr(WasmOp.I32_EQ, serviceCodeLocation)
buildIf("Class matches")
associatedObjectsInstanceGetters.forEach { (obj, getter, isExternal) ->
val keyId = classIds[obj]!!
val keyId = typeIds[obj]!!
buildGetLocal(WasmLocal(1, "keyId", WasmI32, true), serviceCodeLocation)
buildConstI32(keyId, serviceCodeLocation)
buildInstr(WasmOp.I32_EQ, serviceCodeLocation)
Expand Down Expand Up @@ -447,7 +447,7 @@ class WasmCompiledModuleFragment(
fragment.typeInfo.forEach { (referenceKey, typeInfo) ->
val instructions = mutableListOf<WasmInstr>()
WasmIrExpressionBuilder(instructions).buildConstI32(
classIds.getValue(referenceKey),
typeIds.getValue(referenceKey),
SourceLocation.NoLocation("Compile time data per class")
)
val typeData = WasmData(
Expand All @@ -468,8 +468,7 @@ class WasmCompiledModuleFragment(
bindFileFragments(wasmCompiledFileFragments, { it.globalClassITables.unbound }, { it.globalClassITables.defined })
bindFileFragments(wasmCompiledFileFragments, { it.functionTypes.unbound }, { it.functionTypes.defined })
bindUnboundFunctionTypes()
bindInterfaceIds()
bindClassIds()
bindTypeIds()
bindScratchMemAddr()
bindStringPoolSymbols()
bindConstantArrayDataSegmentIds()
Expand Down Expand Up @@ -511,26 +510,26 @@ class WasmCompiledModuleFragment(
}
}

private fun bindInterfaceIds() {
var interfaceId = 0
wasmCompiledFileFragments.forEach { fragment ->
fragment.interfaceIds.unbound.values.forEach { wasmSymbol ->
wasmSymbol.bind(interfaceId--)
}
}
}

private fun bindClassIds() {
classIds.clear()
private fun bindTypeIds() {
typeIds.clear()
currentDataSectionAddress = 0
wasmCompiledFileFragments.forEach { fragment ->
fragment.typeInfo.forEach { (referenceKey, dataElement) ->
classIds[referenceKey] = currentDataSectionAddress
typeIds[referenceKey] = currentDataSectionAddress
currentDataSectionAddress += dataElement.sizeInBytes
}
}

wasmCompiledFileFragments.forEach { fragment ->
bind(fragment.classIds.unbound, typeIds)
}

var interfaceId = 0
wasmCompiledFileFragments.forEach { fragment ->
bind(fragment.classIds.unbound, classIds)
fragment.interfaceIds.unbound.forEach { (signature, symbol) ->
val id = typeIds.getOrPut(signature) { interfaceId-- }
symbol.bind(id)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ private object I1Impl : I1 {
@Associated1(I1Impl::class)
private class I1ImplHolder

@Associated1(I1Impl::class)
private interface I1ImplInterfaceHolder

private interface I2 {
fun foo(): Int
}
Expand Down Expand Up @@ -97,5 +100,8 @@ fun box(): String {

if (10::class.findAssociatedObject<Associated2>() != null) return "fail 12"

val i3 = I1ImplInterfaceHolder::class.findAssociatedObject<Associated1>() as I1
if (i3.foo() != 42) return "fail 13"

return "OK"
}

0 comments on commit 2c594f0

Please sign in to comment.