[WASM] New VTable format

This commit is contained in:
Igor Yakovlev
2022-03-22 18:43:26 +01:00
parent 8bc5508f5c
commit 8da6ab7a04
22 changed files with 619 additions and 525 deletions
@@ -14,9 +14,8 @@ internal const val TYPE_INFO_TYPE_PACKAGE_NAME_PRT_OFFSET = TYPE_INFO_TYPE_PACKA
internal const val TYPE_INFO_TYPE_SIMPLE_NAME_LENGTH_OFFSET = TYPE_INFO_TYPE_PACKAGE_NAME_PRT_OFFSET + TYPE_INFO_ELEMENT_SIZE
internal const val TYPE_INFO_TYPE_SIMPLE_NAME_PRT_OFFSET = TYPE_INFO_TYPE_SIMPLE_NAME_LENGTH_OFFSET + TYPE_INFO_ELEMENT_SIZE
internal const val TYPE_INFO_SUPER_TYPE_OFFSET = TYPE_INFO_TYPE_SIMPLE_NAME_PRT_OFFSET + TYPE_INFO_ELEMENT_SIZE
internal const val TYPE_INFO_ITABLE_PTR_OFFSET = TYPE_INFO_SUPER_TYPE_OFFSET + TYPE_INFO_ELEMENT_SIZE
internal const val TYPE_INFO_VTABLE_LENGTH_OFFSET = TYPE_INFO_ITABLE_PTR_OFFSET + TYPE_INFO_ELEMENT_SIZE
internal const val TYPE_INFO_VTABLE_OFFSET = TYPE_INFO_VTABLE_LENGTH_OFFSET + TYPE_INFO_ELEMENT_SIZE
internal const val TYPE_INFO_ITABLE_SIZE_OFFSET = TYPE_INFO_SUPER_TYPE_OFFSET + TYPE_INFO_ELEMENT_SIZE
internal const val TYPE_INFO_ITABLE_OFFSET = TYPE_INFO_ITABLE_SIZE_OFFSET + TYPE_INFO_ELEMENT_SIZE
internal class TypeInfoData(val typeId: Int, val isInterface: Boolean, val packageName: String, val typeName: String)
@@ -33,45 +32,24 @@ internal fun getTypeInfoTypeDataByPtr(typeInfoPtr: Int): TypeInfoData {
internal fun getSuperTypeId(typeInfoPtr: Int): Int =
wasm_i32_load(typeInfoPtr + TYPE_INFO_SUPER_TYPE_OFFSET)
internal fun getVtablePtr(obj: Any): Int =
obj.typeInfo + TYPE_INFO_VTABLE_OFFSET
internal fun getVtableLength(obj: Any): Int =
wasm_i32_load(obj.typeInfo + TYPE_INFO_VTABLE_LENGTH_OFFSET)
internal fun getItablePtr(obj: Any): Int =
wasm_i32_load(obj.typeInfo + TYPE_INFO_ITABLE_PTR_OFFSET)
internal fun getInterfaceListLength(itablePtr: Int): Int =
wasm_i32_load(itablePtr + TYPE_INFO_VTABLE_LENGTH_OFFSET)
internal fun getVirtualMethodId(obj: Any, virtualFunctionSlot: Int): Int {
val vtablePtr = getVtablePtr(obj)
val methodIdPtr = vtablePtr + virtualFunctionSlot * TYPE_INFO_ELEMENT_SIZE
return wasm_i32_load(methodIdPtr)
}
// Returns -1 if obj does not implement interface
internal fun getInterfaceImplId(obj: Any, interfaceId: Int): Int {
val interfaceListSizePtr = getItablePtr(obj)
val interfaceListPtr = interfaceListSizePtr + TYPE_INFO_ELEMENT_SIZE
val interfaceListSize = wasm_i32_load(interfaceListSizePtr)
internal fun isInterfaceById(obj: Any, interfaceId: Int): Boolean {
val interfaceListSize = wasm_i32_load(obj.typeInfo + TYPE_INFO_ITABLE_SIZE_OFFSET)
val interfaceListPtr = obj.typeInfo + TYPE_INFO_ITABLE_OFFSET
var interfaceSlot = 0
while (interfaceSlot < interfaceListSize) {
val supportedInterface = wasm_i32_load(interfaceListPtr + interfaceSlot * TYPE_INFO_ELEMENT_SIZE)
if (supportedInterface == interfaceId) {
return wasm_i32_load(interfaceListPtr + interfaceListSize * TYPE_INFO_ELEMENT_SIZE + interfaceSlot * TYPE_INFO_ELEMENT_SIZE)
return true
}
interfaceSlot++
}
return -1
return false
}
internal fun isInterface(obj: Any, interfaceId: Int): Boolean {
return getInterfaceImplId(obj, interfaceId) != -1
}
@ExcludedFromCodegen
internal fun <T> isInterface(obj: Any): Boolean =
implementedAsIntrinsic
@ExcludedFromCodegen
internal fun <T> wasmClassId(): Int =
@@ -7,7 +7,7 @@ package kotlin.reflect.wasm.internal
import kotlin.reflect.*
import kotlin.wasm.internal.TypeInfoData
import kotlin.wasm.internal.getSuperTypeId
import kotlin.wasm.internal.isInterface
import kotlin.wasm.internal.isInterfaceById
internal object NothingKClassImpl : KClass<Nothing> {
override val simpleName: String = "Nothing"
@@ -38,7 +38,7 @@ internal class KClassImpl<T : Any>(private val typeData: TypeInfoData) : KClass<
}
override fun isInstance(value: Any?): Boolean = value?.let {
if (typeData.isInterface) isInterface(it, typeData.typeId) else checkSuperTypeInstance(it)
if (typeData.isInterface) isInterfaceById(it, typeData.typeId) else checkSuperTypeInstance(it)
} ?: false
override fun equals(other: Any?): Boolean =