[WASM] Implementation of Class references

This commit is contained in:
Igor Yakovlev
2021-10-26 19:26:17 +02:00
committed by TeamCityServer
parent d9f2bd7963
commit ce360bb10b
43 changed files with 350 additions and 109 deletions
@@ -0,0 +1,55 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package kotlin.reflect.wasm.internal
import kotlin.reflect.*
import kotlin.wasm.internal.TypeInfoData
import kotlin.wasm.internal.getInterfaceImplId
import kotlin.wasm.internal.getSuperTypeId
internal object NothingKClassImpl : KClass<Nothing> {
override val simpleName: String = "Nothing"
override val qualifiedName: String get() = "kotlin.Nothing"
override fun isInstance(value: Any?): Boolean = false
override fun equals(other: Any?): Boolean = other === this
override fun hashCode(): Int = -1
}
internal object ErrorKClass : KClass<Nothing> {
override val simpleName: String get() = error("Unknown simpleName for ErrorKClass")
override val qualifiedName: String get() = error("Unknown qualifiedName for ErrorKClass")
override fun isInstance(value: Any?): Boolean = error("Can's check isInstance on ErrorKClass")
override fun equals(other: Any?): Boolean = other === this
override fun hashCode(): Int = 0
}
internal class KClassImpl<T : Any>(private val typeData: TypeInfoData) : KClass<T> {
override val simpleName: String get() = typeData.typeName
override val qualifiedName: String =
if (typeData.packageName.isEmpty()) typeData.typeName else "${typeData.packageName}.${typeData.typeName}"
private fun checkSuperTypeInstance(obj: Any): Boolean {
var typeId = obj.typeInfo
while (typeId != -1) {
if (typeData.typeId == typeId) return true
typeId = getSuperTypeId(typeId)
}
return false
}
override fun isInstance(value: Any?): Boolean =
value != null && (checkSuperTypeInstance(value) || getInterfaceImplId(value, typeData.typeId) != -1)
override fun equals(other: Any?): Boolean =
(this === other) || (other is KClassImpl<*> && other.typeInfo == typeData.typeId)
override fun hashCode(): Int = typeData.typeId
}
@@ -0,0 +1,40 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package kotlin.wasm.internal
import kotlin.reflect.KFunction
import kotlin.reflect.wasm.internal.*
internal object PrimitiveClasses {
val nothingClass = NothingKClassImpl
val anyClass = wasmGetKClass<Any>()
val numberClass = wasmGetKClass<Number>()
val booleanClass = wasmGetKClass<Boolean>()
val byteClass = wasmGetKClass<Byte>()
val shortClass = wasmGetKClass<Short>()
val intClass = wasmGetKClass<Int>()
val floatClass = wasmGetKClass<Float>()
val doubleClass = wasmGetKClass<Double>()
val arrayClass = wasmGetKClass<Array<*>>()
val stringClass = wasmGetKClass<String>()
val throwableClass = wasmGetKClass<Throwable>()
val booleanArrayClass = wasmGetKClass<BooleanArray>()
val charArrayClass = wasmGetKClass<CharArray>()
val byteArrayClass = wasmGetKClass<ByteArray>()
val shortArrayClass = wasmGetKClass<ShortArray>()
val intArrayClass = wasmGetKClass<IntArray>()
val longArrayClass = wasmGetKClass<LongArray>()
val floatArrayClass = wasmGetKClass<FloatArray>()
val doubleArrayClass = wasmGetKClass<DoubleArray>()
fun functionClass(arity: Int): KClassImpl<Any> {
//TODO FunctionN
return (if (arity == 0) wasmGetKClass<KFunction<*>>() else ErrorKClass) as KClassImpl<Any>
}
}
@@ -0,0 +1,61 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
// a package is omitted to get declarations directly under the module
package kotlin.wasm.internal
import kotlin.reflect.*
import kotlin.reflect.wasm.internal.*
internal fun <T : Any> getKClass(typeInfoData: TypeInfoData): KClass<T> {
// return if (js("Array").isArray(jClass)) {
// getKClassM(jClass.unsafeCast<Array<JsClass<T>>>())
// } else {
// getKClass1(jClass.unsafeCast<JsClass<T>>())
// }
return getKClass1(typeInfoData)
}
internal fun <T : Any> getKClassM(jClasses: Array<TypeInfoData>): KClass<T> = when (jClasses.size) {
1 -> getKClass1(jClasses[0])
0 -> NothingKClassImpl as KClass<T>
else -> ErrorKClass as KClass<T>
}
internal fun <T : Any> getKClassFromExpression(e: T): KClass<T> =
when (e) {
is String -> PrimitiveClasses.stringClass
is Int -> PrimitiveClasses.intClass
is Byte -> PrimitiveClasses.byteClass
is Float -> PrimitiveClasses.floatClass
is Boolean -> PrimitiveClasses.booleanClass
is Double -> PrimitiveClasses.doubleClass
is Number -> PrimitiveClasses.numberClass
is BooleanArray -> PrimitiveClasses.booleanArrayClass
is CharArray -> PrimitiveClasses.charArrayClass
is ByteArray -> PrimitiveClasses.byteArrayClass
is ShortArray -> PrimitiveClasses.shortArrayClass
is IntArray -> PrimitiveClasses.intArrayClass
is LongArray -> PrimitiveClasses.longArrayClass
is FloatArray -> PrimitiveClasses.floatArrayClass
is DoubleArray -> PrimitiveClasses.doubleArrayClass
is KClass<*> -> KClass::class
is Array<*> -> PrimitiveClasses.arrayClass
is Function<*> -> PrimitiveClasses.functionClass(0) //TODO
else -> {
getKClass1(getTypeInfoTypeDataByPtr(e.typeInfo))
}
} as KClass<T>
internal fun <T : Any> getKClass1(infoData: TypeInfoData): KClass<T> {
return KClassImpl(infoData)
}
@Suppress("REIFIED_TYPE_PARAMETER_NO_INLINE")
internal inline fun <reified T : Any> wasmGetKClass(): KClass<T> =
KClassImpl(wasmGetTypeInfoData<T>())