[WASM] Implementation of Class references
This commit is contained in:
committed by
TeamCityServer
parent
d9f2bd7963
commit
ce360bb10b
+11
-4
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.ir.backend.js
|
|||||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||||
import org.jetbrains.kotlin.backend.common.atMostOne
|
import org.jetbrains.kotlin.backend.common.atMostOne
|
||||||
import org.jetbrains.kotlin.backend.common.ir.Symbols
|
|
||||||
import org.jetbrains.kotlin.backend.common.ir.isOverridableOrOverrides
|
import org.jetbrains.kotlin.backend.common.ir.isOverridableOrOverrides
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
@@ -17,7 +16,9 @@ import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
|||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.ir.backend.js.utils.isDispatchReceiver
|
import org.jetbrains.kotlin.ir.backend.js.utils.isDispatchReceiver
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.types.IrDynamicType
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||||
import org.jetbrains.kotlin.ir.util.getPropertyGetter
|
import org.jetbrains.kotlin.ir.util.getPropertyGetter
|
||||||
@@ -29,10 +30,16 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
|||||||
interface JsCommonBackendContext : CommonBackendContext {
|
interface JsCommonBackendContext : CommonBackendContext {
|
||||||
override val mapping: JsMapping
|
override val mapping: JsMapping
|
||||||
|
|
||||||
|
val intrinsics: Intrinsics
|
||||||
|
|
||||||
|
val dynamicType: IrDynamicType
|
||||||
|
|
||||||
val inlineClassesUtils: InlineClassesUtils
|
val inlineClassesUtils: InlineClassesUtils
|
||||||
|
|
||||||
val coroutineSymbols: JsCommonCoroutineSymbols
|
val coroutineSymbols: JsCommonCoroutineSymbols
|
||||||
|
|
||||||
|
val primitiveClassesObject: IrClassSymbol
|
||||||
|
|
||||||
val catchAllThrowableType: IrType
|
val catchAllThrowableType: IrType
|
||||||
get() = irBuiltIns.throwableType
|
get() = irBuiltIns.throwableType
|
||||||
|
|
||||||
@@ -50,7 +57,7 @@ internal fun <T> BackendContext.lazy2(fn: () -> T) = lazy { irFactory.stageContr
|
|||||||
|
|
||||||
class JsCommonCoroutineSymbols(
|
class JsCommonCoroutineSymbols(
|
||||||
symbolTable: SymbolTable,
|
symbolTable: SymbolTable,
|
||||||
module: ModuleDescriptor,
|
val module: ModuleDescriptor,
|
||||||
val context: JsCommonBackendContext
|
val context: JsCommonBackendContext
|
||||||
) {
|
) {
|
||||||
val coroutinePackage = module.getPackage(COROUTINE_PACKAGE_FQNAME)
|
val coroutinePackage = module.getPackage(COROUTINE_PACKAGE_FQNAME)
|
||||||
@@ -114,10 +121,10 @@ class JsCommonCoroutineSymbols(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun findClass(memberScope: MemberScope, name: Name): ClassDescriptor =
|
fun findClass(memberScope: MemberScope, name: Name): ClassDescriptor =
|
||||||
memberScope.getContributedClassifier(name, NoLookupLocation.FROM_BACKEND) as ClassDescriptor
|
memberScope.getContributedClassifier(name, NoLookupLocation.FROM_BACKEND) as ClassDescriptor
|
||||||
|
|
||||||
internal fun findFunctions(memberScope: MemberScope, name: Name): List<SimpleFunctionDescriptor> =
|
fun findFunctions(memberScope: MemberScope, name: Name): List<SimpleFunctionDescriptor> =
|
||||||
memberScope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND).toList()
|
memberScope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND).toList()
|
||||||
|
|
||||||
interface InlineClassesUtils {
|
interface InlineClassesUtils {
|
||||||
|
|||||||
@@ -21,7 +21,21 @@ import org.jetbrains.kotlin.psi2ir.findSingleFunction
|
|||||||
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
|
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendContext) {
|
interface Intrinsics {
|
||||||
|
val jsGetKClassFromExpression: IrSimpleFunctionSymbol
|
||||||
|
val jsGetKClass: IrSimpleFunctionSymbol
|
||||||
|
val jsClass: IrSimpleFunctionSymbol
|
||||||
|
val createKType: IrSimpleFunctionSymbol?
|
||||||
|
val createDynamicKType: IrSimpleFunctionSymbol?
|
||||||
|
val createKTypeParameter: IrSimpleFunctionSymbol?
|
||||||
|
val getStarKTypeProjection: IrSimpleFunctionSymbol?
|
||||||
|
val createCovariantKTypeProjection: IrSimpleFunctionSymbol?
|
||||||
|
val createInvariantKTypeProjection: IrSimpleFunctionSymbol?
|
||||||
|
val createContravariantKTypeProjection: IrSimpleFunctionSymbol?
|
||||||
|
val arrayLiteral: IrSimpleFunctionSymbol
|
||||||
|
}
|
||||||
|
|
||||||
|
class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendContext) : Intrinsics {
|
||||||
|
|
||||||
// TODO: Should we drop operator intrinsics in favor of IrDynamicOperatorExpression?
|
// TODO: Should we drop operator intrinsics in favor of IrDynamicOperatorExpression?
|
||||||
|
|
||||||
@@ -169,10 +183,10 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
|
|||||||
getInternalWithoutPackage("kotlin.coroutines.intrinsics.invokeSuspendSuperTypeWithReceiver")
|
getInternalWithoutPackage("kotlin.coroutines.intrinsics.invokeSuspendSuperTypeWithReceiver")
|
||||||
val jsInvokeSuspendSuperTypeWithReceiverAndParam =
|
val jsInvokeSuspendSuperTypeWithReceiverAndParam =
|
||||||
getInternalWithoutPackage("kotlin.coroutines.intrinsics.invokeSuspendSuperTypeWithReceiverAndParam")
|
getInternalWithoutPackage("kotlin.coroutines.intrinsics.invokeSuspendSuperTypeWithReceiverAndParam")
|
||||||
val jsGetKClass = getInternalWithoutPackage("getKClass")
|
|
||||||
val jsGetKClassFromExpression = getInternalWithoutPackage("getKClassFromExpression")
|
|
||||||
|
|
||||||
val jsClass = getInternalFunction("jsClassIntrinsic")
|
override val jsGetKClass = getInternalWithoutPackage("getKClass")
|
||||||
|
override val jsGetKClassFromExpression = getInternalWithoutPackage("getKClassFromExpression")
|
||||||
|
override val jsClass = getInternalFunction("jsClassIntrinsic")
|
||||||
|
|
||||||
val jsNumberRangeToNumber = getInternalFunction("numberRangeToNumber")
|
val jsNumberRangeToNumber = getInternalFunction("numberRangeToNumber")
|
||||||
val jsNumberRangeToLong = getInternalFunction("numberRangeToLong")
|
val jsNumberRangeToLong = getInternalFunction("numberRangeToLong")
|
||||||
@@ -235,7 +249,7 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
|
|||||||
val jsPrimitiveArrayIteratorFunctions =
|
val jsPrimitiveArrayIteratorFunctions =
|
||||||
PrimitiveType.values().associate { it to getInternalFunction("${it.typeName.asString().toLowerCaseAsciiOnly()}ArrayIterator") }
|
PrimitiveType.values().associate { it to getInternalFunction("${it.typeName.asString().toLowerCaseAsciiOnly()}ArrayIterator") }
|
||||||
|
|
||||||
val arrayLiteral = getInternalFunction("arrayLiteral")
|
override val arrayLiteral = getInternalFunction("arrayLiteral")
|
||||||
|
|
||||||
val primitiveToTypedArrayMap = EnumMap(
|
val primitiveToTypedArrayMap = EnumMap(
|
||||||
mapOf(
|
mapOf(
|
||||||
@@ -247,13 +261,13 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
val createKType = getInternalWithoutPackageOrNull("createKType")
|
override val createKType = getInternalWithoutPackageOrNull("createKType")
|
||||||
val createDynamicKType = getInternalWithoutPackageOrNull("createDynamicKType")
|
override val createDynamicKType = getInternalWithoutPackageOrNull("createDynamicKType")
|
||||||
val createKTypeParameter = getInternalWithoutPackageOrNull("createKTypeParameter")
|
override val createKTypeParameter = getInternalWithoutPackageOrNull("createKTypeParameter")
|
||||||
val getStarKTypeProjection = getInternalWithoutPackageOrNull("getStarKTypeProjection")
|
override val getStarKTypeProjection = getInternalWithoutPackageOrNull("getStarKTypeProjection")
|
||||||
val createCovariantKTypeProjection = getInternalWithoutPackageOrNull("createCovariantKTypeProjection")
|
override val createCovariantKTypeProjection = getInternalWithoutPackageOrNull("createCovariantKTypeProjection")
|
||||||
val createInvariantKTypeProjection = getInternalWithoutPackageOrNull("createInvariantKTypeProjection")
|
override val createInvariantKTypeProjection = getInternalWithoutPackageOrNull("createInvariantKTypeProjection")
|
||||||
val createContravariantKTypeProjection = getInternalWithoutPackageOrNull("createContravariantKTypeProjection")
|
override val createContravariantKTypeProjection = getInternalWithoutPackageOrNull("createContravariantKTypeProjection")
|
||||||
|
|
||||||
val primitiveToSizeConstructor =
|
val primitiveToSizeConstructor =
|
||||||
PrimitiveType.values().associate { type ->
|
PrimitiveType.values().associate { type ->
|
||||||
@@ -315,8 +329,6 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
|
|||||||
|
|
||||||
val jsUndefined = getInternalFunction("jsUndefined")
|
val jsUndefined = getInternalFunction("jsUndefined")
|
||||||
|
|
||||||
// Helpers:
|
|
||||||
|
|
||||||
private fun getInternalFunction(name: String) =
|
private fun getInternalFunction(name: String) =
|
||||||
context.symbolTable.referenceSimpleFunction(context.getJsInternalFunction(name))
|
context.symbolTable.referenceSimpleFunction(context.getJsInternalFunction(name))
|
||||||
|
|
||||||
@@ -333,4 +345,4 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
|
|||||||
|
|
||||||
private fun getInternalClassWithoutPackage(fqName: String) =
|
private fun getInternalClassWithoutPackage(fqName: String) =
|
||||||
context.symbolTable.referenceClass(context.getClass(FqName(fqName)))
|
context.symbolTable.referenceClass(context.getClass(FqName(fqName)))
|
||||||
}
|
}
|
||||||
+4
-14
@@ -68,6 +68,7 @@ class JsIrBackendContext(
|
|||||||
val extractedLocalClasses: MutableSet<IrClass> = hashSetOf()
|
val extractedLocalClasses: MutableSet<IrClass> = hashSetOf()
|
||||||
|
|
||||||
override val builtIns = module.builtIns
|
override val builtIns = module.builtIns
|
||||||
|
|
||||||
override val typeSystem: IrTypeSystemContext = IrTypeSystemContextImpl(irBuiltIns)
|
override val typeSystem: IrTypeSystemContext = IrTypeSystemContextImpl(irBuiltIns)
|
||||||
|
|
||||||
override val irFactory: IrFactory = symbolTable.irFactory
|
override val irFactory: IrFactory = symbolTable.irFactory
|
||||||
@@ -156,9 +157,8 @@ class JsIrBackendContext(
|
|||||||
|
|
||||||
private val internalPackage = module.getPackage(JS_PACKAGE_FQNAME)
|
private val internalPackage = module.getPackage(JS_PACKAGE_FQNAME)
|
||||||
|
|
||||||
|
override val dynamicType: IrDynamicType = IrDynamicTypeImpl(null, emptyList(), Variance.INVARIANT)
|
||||||
val dynamicType: IrDynamicType = IrDynamicTypeImpl(null, emptyList(), Variance.INVARIANT)
|
override val intrinsics = JsIntrinsics(irBuiltIns, this)
|
||||||
val intrinsics = JsIntrinsics(irBuiltIns, this)
|
|
||||||
|
|
||||||
override val catchAllThrowableType: IrType
|
override val catchAllThrowableType: IrType
|
||||||
get() = dynamicType
|
get() = dynamicType
|
||||||
@@ -284,7 +284,7 @@ class JsIrBackendContext(
|
|||||||
val errorCodeSymbol: IrSimpleFunctionSymbol? =
|
val errorCodeSymbol: IrSimpleFunctionSymbol? =
|
||||||
if (errorPolicy.allowErrors) symbolTable.referenceSimpleFunction(getJsInternalFunction("errorCode")) else null
|
if (errorPolicy.allowErrors) symbolTable.referenceSimpleFunction(getJsInternalFunction("errorCode")) else null
|
||||||
|
|
||||||
val primitiveClassesObject = getIrClass(FqName("kotlin.reflect.js.internal.PrimitiveClasses"))
|
override val primitiveClassesObject = getIrClass(FqName("kotlin.reflect.js.internal.PrimitiveClasses"))
|
||||||
|
|
||||||
val throwableClass = getIrClass(JsIrBackendContext.KOTLIN_PACKAGE_FQN.child(Name.identifier("Throwable")))
|
val throwableClass = getIrClass(JsIrBackendContext.KOTLIN_PACKAGE_FQN.child(Name.identifier("Throwable")))
|
||||||
|
|
||||||
@@ -323,16 +323,6 @@ class JsIrBackendContext(
|
|||||||
override val suiteFun = getFunctions(FqName("kotlin.test.suite")).singleOrNull()?.let { symbolTable.referenceSimpleFunction(it) }
|
override val suiteFun = getFunctions(FqName("kotlin.test.suite")).singleOrNull()?.let { symbolTable.referenceSimpleFunction(it) }
|
||||||
override val testFun = getFunctions(FqName("kotlin.test.test")).singleOrNull()?.let { symbolTable.referenceSimpleFunction(it) }
|
override val testFun = getFunctions(FqName("kotlin.test.test")).singleOrNull()?.let { symbolTable.referenceSimpleFunction(it) }
|
||||||
|
|
||||||
val primitiveClassProperties by lazy2 {
|
|
||||||
primitiveClassesObject.owner.declarations.filterIsInstance<IrProperty>()
|
|
||||||
}
|
|
||||||
|
|
||||||
val primitiveClassFunctionClass by lazy2 {
|
|
||||||
primitiveClassesObject.owner.declarations
|
|
||||||
.filterIsInstance<IrSimpleFunction>()
|
|
||||||
.find { it.name == Name.identifier("functionClass") }!!
|
|
||||||
}
|
|
||||||
|
|
||||||
val throwableConstructors by lazy2 { throwableClass.owner.declarations.filterIsInstance<IrConstructor>().map { it.symbol } }
|
val throwableConstructors by lazy2 { throwableClass.owner.declarations.filterIsInstance<IrConstructor>().map { it.symbol } }
|
||||||
val defaultThrowableCtor by lazy2 { throwableConstructors.single { !it.owner.isPrimary && it.owner.valueParameters.size == 0 } }
|
val defaultThrowableCtor by lazy2 { throwableConstructors.single { !it.owner.isPrimary && it.owner.valueParameters.size == 0 } }
|
||||||
|
|
||||||
|
|||||||
+17
-11
@@ -8,8 +8,7 @@ package org.jetbrains.kotlin.ir.backend.js.lower
|
|||||||
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
||||||
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
||||||
import org.jetbrains.kotlin.backend.common.ir.Symbols
|
import org.jetbrains.kotlin.backend.common.ir.Symbols
|
||||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
import org.jetbrains.kotlin.ir.backend.js.*
|
||||||
import org.jetbrains.kotlin.ir.backend.js.JsLoweredDeclarationOrigin
|
|
||||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||||
import org.jetbrains.kotlin.ir.backend.js.utils.toJsArrayLiteral
|
import org.jetbrains.kotlin.ir.backend.js.utils.toJsArrayLiteral
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
@@ -24,13 +23,20 @@ import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
|||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
|
|
||||||
class ClassReferenceLowering(val context: JsIrBackendContext) : BodyLoweringPass {
|
class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLoweringPass {
|
||||||
private val intrinsics = context.intrinsics
|
|
||||||
|
private val primitiveClassProperties by lazy {
|
||||||
|
primitiveClassesObject.owner.declarations.filterIsInstance<IrProperty>()
|
||||||
|
}
|
||||||
|
|
||||||
|
private val primitiveClassFunctionClass by lazy {
|
||||||
|
primitiveClassesObject.owner.declarations
|
||||||
|
.filterIsInstance<IrSimpleFunction>()
|
||||||
|
.find { it.name == Name.identifier("functionClass") }!!
|
||||||
|
}
|
||||||
|
|
||||||
private val primitiveClassesObject = context.primitiveClassesObject
|
private val primitiveClassesObject = context.primitiveClassesObject
|
||||||
|
|
||||||
private val primitiveClassProperties = context.primitiveClassProperties
|
|
||||||
|
|
||||||
private fun primitiveClassProperty(name: String) =
|
private fun primitiveClassProperty(name: String) =
|
||||||
primitiveClassProperties.singleOrNull { it.name == Name.identifier(name) }?.getter
|
primitiveClassProperties.singleOrNull { it.name == Name.identifier(name) }?.getter
|
||||||
?: primitiveClassesObject.owner.declarations.filterIsInstance<IrSimpleFunction>().single { it.name == Name.special("<get-$name>") }
|
?: primitiveClassesObject.owner.declarations.filterIsInstance<IrSimpleFunction>().single { it.name == Name.special("<get-$name>") }
|
||||||
@@ -74,7 +80,7 @@ class ClassReferenceLowering(val context: JsIrBackendContext) : BodyLoweringPass
|
|||||||
if (primitiveKClass != null)
|
if (primitiveKClass != null)
|
||||||
return JsIrBuilder.buildBlock(returnType, listOf(argument, primitiveKClass))
|
return JsIrBuilder.buildBlock(returnType, listOf(argument, primitiveKClass))
|
||||||
|
|
||||||
return JsIrBuilder.buildCall(intrinsics.jsGetKClassFromExpression, returnType, listOf(typeArgument)).apply {
|
return JsIrBuilder.buildCall(context.intrinsics.jsGetKClassFromExpression, returnType, listOf(typeArgument)).apply {
|
||||||
putValueArgument(0, argument)
|
putValueArgument(0, argument)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,7 +109,7 @@ class ClassReferenceLowering(val context: JsIrBackendContext) : BodyLoweringPass
|
|||||||
if (typeArgument.isFunction()) {
|
if (typeArgument.isFunction()) {
|
||||||
val functionInterface = typeArgument.getClass()!!
|
val functionInterface = typeArgument.getClass()!!
|
||||||
val arity = functionInterface.typeParameters.size - 1
|
val arity = functionInterface.typeParameters.size - 1
|
||||||
return getPrimitiveClass(context.primitiveClassFunctionClass, returnType).apply {
|
return getPrimitiveClass(primitiveClassFunctionClass, returnType).apply {
|
||||||
putValueArgument(0, JsIrBuilder.buildInt(context.irBuiltIns.intType, arity))
|
putValueArgument(0, JsIrBuilder.buildInt(context.irBuiltIns.intType, arity))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -112,7 +118,7 @@ class ClassReferenceLowering(val context: JsIrBackendContext) : BodyLoweringPass
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun callGetKClass(
|
private fun callGetKClass(
|
||||||
returnType: IrType = intrinsics.jsGetKClass.owner.returnType,
|
returnType: IrType = context.intrinsics.jsGetKClass.owner.returnType,
|
||||||
typeArgument: IrType
|
typeArgument: IrType
|
||||||
): IrCall {
|
): IrCall {
|
||||||
val primitiveKClass =
|
val primitiveKClass =
|
||||||
@@ -121,7 +127,7 @@ class ClassReferenceLowering(val context: JsIrBackendContext) : BodyLoweringPass
|
|||||||
if (primitiveKClass != null)
|
if (primitiveKClass != null)
|
||||||
return primitiveKClass
|
return primitiveKClass
|
||||||
|
|
||||||
return JsIrBuilder.buildCall(intrinsics.jsGetKClass, returnType, listOf(typeArgument))
|
return JsIrBuilder.buildCall(context.intrinsics.jsGetKClass, returnType, listOf(typeArgument))
|
||||||
.apply {
|
.apply {
|
||||||
putValueArgument(0, callJsClass(typeArgument))
|
putValueArgument(0, callJsClass(typeArgument))
|
||||||
}
|
}
|
||||||
@@ -129,7 +135,7 @@ class ClassReferenceLowering(val context: JsIrBackendContext) : BodyLoweringPass
|
|||||||
|
|
||||||
private fun callJsClass(type: IrType) =
|
private fun callJsClass(type: IrType) =
|
||||||
JsIrBuilder.buildCall(
|
JsIrBuilder.buildCall(
|
||||||
intrinsics.jsClass,
|
context.intrinsics.jsClass,
|
||||||
typeArguments = listOf(type),
|
typeArguments = listOf(type),
|
||||||
origin = JsLoweredDeclarationOrigin.CLASS_REFERENCE
|
origin = JsLoweredDeclarationOrigin.CLASS_REFERENCE
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ fun IrDeclaration.hasStaticDispatch() = when (this) {
|
|||||||
else -> true
|
else -> true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun List<IrExpression>.toJsArrayLiteral(context: JsIrBackendContext, arrayType: IrType, elementType: IrType): IrExpression {
|
fun List<IrExpression>.toJsArrayLiteral(context: JsCommonBackendContext, arrayType: IrType, elementType: IrType): IrExpression {
|
||||||
val irVararg = IrVarargImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, arrayType, elementType, this)
|
val irVararg = IrVarargImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, arrayType, elementType, this)
|
||||||
|
|
||||||
return IrCallImpl(
|
return IrCallImpl(
|
||||||
|
|||||||
+34
-2
@@ -24,17 +24,42 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
|
|||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.DescriptorlessExternalPackageFragmentSymbol
|
import org.jetbrains.kotlin.ir.symbols.impl.DescriptorlessExternalPackageFragmentSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.types.IrDynamicType
|
||||||
import org.jetbrains.kotlin.ir.types.IrTypeSystemContext
|
import org.jetbrains.kotlin.ir.types.IrTypeSystemContext
|
||||||
import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl
|
import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl
|
||||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
|
class WasmIntrinsics(private val context: WasmBackendContext) : Intrinsics {
|
||||||
|
|
||||||
|
override val jsGetKClass: IrSimpleFunctionSymbol get() = context.wasmSymbols.jsGetKClass
|
||||||
|
override val jsGetKClassFromExpression: IrSimpleFunctionSymbol get() = context.wasmSymbols.jsGetKClassFromExpression
|
||||||
|
override val jsClass: IrSimpleFunctionSymbol get() = context.wasmSymbols.jsClass
|
||||||
|
|
||||||
|
override val createKType: IrSimpleFunctionSymbol?
|
||||||
|
get() = TODO("Not yet implemented")
|
||||||
|
override val createDynamicKType: IrSimpleFunctionSymbol?
|
||||||
|
get() = TODO("Not yet implemented")
|
||||||
|
override val createKTypeParameter: IrSimpleFunctionSymbol?
|
||||||
|
get() = TODO("Not yet implemented")
|
||||||
|
override val getStarKTypeProjection: IrSimpleFunctionSymbol?
|
||||||
|
get() = TODO("Not yet implemented")
|
||||||
|
override val createCovariantKTypeProjection: IrSimpleFunctionSymbol?
|
||||||
|
get() = TODO("Not yet implemented")
|
||||||
|
override val createInvariantKTypeProjection: IrSimpleFunctionSymbol?
|
||||||
|
get() = TODO("Not yet implemented")
|
||||||
|
override val createContravariantKTypeProjection: IrSimpleFunctionSymbol?
|
||||||
|
get() = TODO("Not yet implemented")
|
||||||
|
override val arrayLiteral: IrSimpleFunctionSymbol
|
||||||
|
get() = TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
class WasmBackendContext(
|
class WasmBackendContext(
|
||||||
val module: ModuleDescriptor,
|
val module: ModuleDescriptor,
|
||||||
override val irBuiltIns: IrBuiltIns,
|
override val irBuiltIns: IrBuiltIns,
|
||||||
symbolTable: SymbolTable,
|
val symbolTable: SymbolTable,
|
||||||
irModuleFragment: IrModuleFragment,
|
val irModuleFragment: IrModuleFragment,
|
||||||
override val configuration: CompilerConfiguration,
|
override val configuration: CompilerConfiguration,
|
||||||
) : JsCommonBackendContext {
|
) : JsCommonBackendContext {
|
||||||
override val builtIns = module.builtIns
|
override val builtIns = module.builtIns
|
||||||
@@ -43,6 +68,11 @@ class WasmBackendContext(
|
|||||||
override val scriptMode = false
|
override val scriptMode = false
|
||||||
override val irFactory: IrFactory = symbolTable.irFactory
|
override val irFactory: IrFactory = symbolTable.irFactory
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
override val dynamicType: IrDynamicType get() = TODO()
|
||||||
|
override val primitiveClassesObject get() = wasmSymbols.primitiveClassesObject
|
||||||
|
//TODO!!!
|
||||||
|
|
||||||
// Place to store declarations excluded from code generation
|
// Place to store declarations excluded from code generation
|
||||||
private val excludedDeclarations = mutableMapOf<FqName, IrPackageFragment>()
|
private val excludedDeclarations = mutableMapOf<FqName, IrPackageFragment>()
|
||||||
|
|
||||||
@@ -169,4 +199,6 @@ class WasmBackendContext(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val intrinsics: Intrinsics = WasmIntrinsics(this)
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-2
@@ -416,6 +416,12 @@ private val staticMembersLoweringPhase = makeWasmModulePhase(
|
|||||||
description = "Move static member declarations to top-level"
|
description = "Move static member declarations to top-level"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private val classReferenceLoweringPhase = makeWasmModulePhase(
|
||||||
|
::ClassReferenceLowering,
|
||||||
|
name = "ClassReferenceLowering",
|
||||||
|
description = "Handle class references"
|
||||||
|
)
|
||||||
|
|
||||||
private val wasmVarargExpressionLoweringPhase = makeWasmModulePhase(
|
private val wasmVarargExpressionLoweringPhase = makeWasmModulePhase(
|
||||||
::WasmVarargExpressionLowering,
|
::WasmVarargExpressionLowering,
|
||||||
name = "WasmVarargExpressionLowering",
|
name = "WasmVarargExpressionLowering",
|
||||||
@@ -521,6 +527,8 @@ val wasmPhases = NamedCompilerPhase(
|
|||||||
wrapInlineDeclarationsWithReifiedTypeParametersPhase then
|
wrapInlineDeclarationsWithReifiedTypeParametersPhase then
|
||||||
|
|
||||||
functionInliningPhase then
|
functionInliningPhase then
|
||||||
|
removeInlineDeclarationsWithReifiedTypeParametersLoweringPhase then
|
||||||
|
|
||||||
lateinitNullableFieldsPhase then
|
lateinitNullableFieldsPhase then
|
||||||
lateinitDeclarationLoweringPhase then
|
lateinitDeclarationLoweringPhase then
|
||||||
lateinitUsageLoweringPhase then
|
lateinitUsageLoweringPhase then
|
||||||
@@ -577,11 +585,10 @@ val wasmPhases = NamedCompilerPhase(
|
|||||||
defaultArgumentPatchOverridesPhase then
|
defaultArgumentPatchOverridesPhase then
|
||||||
defaultParameterInjectorPhase then
|
defaultParameterInjectorPhase then
|
||||||
defaultParameterCleanerPhase then
|
defaultParameterCleanerPhase then
|
||||||
removeInlineDeclarationsWithReifiedTypeParametersLoweringPhase then
|
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// multipleCatchesLoweringPhase then
|
// multipleCatchesLoweringPhase then
|
||||||
// classReferenceLoweringPhase then
|
classReferenceLoweringPhase then
|
||||||
|
|
||||||
wasmVarargExpressionLoweringPhase then
|
wasmVarargExpressionLoweringPhase then
|
||||||
inlineClassDeclarationLoweringPhase then
|
inlineClassDeclarationLoweringPhase then
|
||||||
|
|||||||
@@ -45,6 +45,12 @@ class WasmSymbols(
|
|||||||
private val kotlinTestPackage: PackageViewDescriptor =
|
private val kotlinTestPackage: PackageViewDescriptor =
|
||||||
context.module.getPackage(FqName("kotlin.test"))
|
context.module.getPackage(FqName("kotlin.test"))
|
||||||
|
|
||||||
|
val jsGetKClass: IrSimpleFunctionSymbol = getInternalFunction("getKClass")
|
||||||
|
val jsGetKClassFromExpression: IrSimpleFunctionSymbol = getInternalFunction("getKClassFromExpression")
|
||||||
|
val jsClass: IrSimpleFunctionSymbol = getInternalFunction("wasmGetTypeInfoData")
|
||||||
|
val wasmTypeInfoData: IrClassSymbol = getInternalClass("TypeInfoData")
|
||||||
|
val primitiveClassesObject = getInternalClass("PrimitiveClasses")
|
||||||
|
|
||||||
override val throwNullPointerException = getInternalFunction("THROW_NPE")
|
override val throwNullPointerException = getInternalFunction("THROW_NPE")
|
||||||
override val throwISE = getInternalFunction("THROW_ISE")
|
override val throwISE = getInternalFunction("THROW_ISE")
|
||||||
override val throwTypeCastException = getInternalFunction("THROW_CCE")
|
override val throwTypeCastException = getInternalFunction("THROW_CCE")
|
||||||
@@ -145,6 +151,7 @@ class WasmSymbols(
|
|||||||
|
|
||||||
val wasmClassId = getInternalFunction("wasmClassId")
|
val wasmClassId = getInternalFunction("wasmClassId")
|
||||||
val wasmInterfaceId = getInternalFunction("wasmInterfaceId")
|
val wasmInterfaceId = getInternalFunction("wasmInterfaceId")
|
||||||
|
val wasmTypeId = getInternalFunction("wasmTypeId")
|
||||||
|
|
||||||
val getVirtualMethodId = getInternalFunction("getVirtualMethodId")
|
val getVirtualMethodId = getInternalFunction("getVirtualMethodId")
|
||||||
val getInterfaceImplId = getInternalFunction("getInterfaceImplId")
|
val getInterfaceImplId = getInternalFunction("getInterfaceImplId")
|
||||||
|
|||||||
+7
@@ -348,6 +348,13 @@ class BodyGenerator(val context: WasmFunctionCodegenContext) : IrElementVisitorV
|
|||||||
body.buildConstI32Symbol(context.referenceInterfaceId(irInterface.symbol))
|
body.buildConstI32Symbol(context.referenceInterfaceId(irInterface.symbol))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wasmSymbols.wasmTypeId -> {
|
||||||
|
val type = call.getTypeArgument(0)!!.getClass()
|
||||||
|
?: error("No class given for wasmClassId intrinsic")
|
||||||
|
val id = if (type.isInterface) context.referenceInterfaceId(type.symbol) else context.referenceClassId(type.symbol)
|
||||||
|
body.buildConstI32Symbol(id)
|
||||||
|
}
|
||||||
|
|
||||||
wasmSymbols.wasmRefCast -> {
|
wasmSymbols.wasmRefCast -> {
|
||||||
val toType = call.getTypeArgument(0)!!
|
val toType = call.getTypeArgument(0)!!
|
||||||
generateTypeRTT(toType)
|
generateTypeRTT(toType)
|
||||||
|
|||||||
+21
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
|||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||||
|
import org.jetbrains.kotlin.name.parentOrNull
|
||||||
import org.jetbrains.kotlin.wasm.ir.*
|
import org.jetbrains.kotlin.wasm.ir.*
|
||||||
|
|
||||||
class DeclarationGenerator(val context: WasmModuleCodegenContext) : IrElementVisitorVoid {
|
class DeclarationGenerator(val context: WasmModuleCodegenContext) : IrElementVisitorVoid {
|
||||||
@@ -274,6 +275,24 @@ class DeclarationGenerator(val context: WasmModuleCodegenContext) : IrElementVis
|
|||||||
|
|
||||||
private fun binaryDataStruct(classMetadata: ClassMetadata): ConstantDataStruct {
|
private fun binaryDataStruct(classMetadata: ClassMetadata): ConstantDataStruct {
|
||||||
val invalidIndex = -1
|
val invalidIndex = -1
|
||||||
|
|
||||||
|
val packageName = classMetadata.klass.kotlinFqName.parentOrNull()?.asString() ?: ""
|
||||||
|
val simpleName = classMetadata.klass.kotlinFqName.shortName().asString()
|
||||||
|
val typeInfo = ConstantDataStruct(
|
||||||
|
"TypeInfo",
|
||||||
|
listOf(
|
||||||
|
ConstantDataIntField("TypePackageNameLength", packageName.length),
|
||||||
|
ConstantDataIntField("TypePackageNamePtr", context.referenceStringLiteral(packageName)),
|
||||||
|
ConstantDataIntField("TypeNameLength", simpleName.length),
|
||||||
|
ConstantDataIntField("TypeNamePtr", context.referenceStringLiteral(simpleName))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
val superClass = classMetadata.klass.getSuperClass(context.backendContext.irBuiltIns)
|
||||||
|
val superTypeId = superClass?.let {
|
||||||
|
ConstantDataIntField("SuperTypeId", context.referenceClassId(it.symbol))
|
||||||
|
} ?: ConstantDataIntField("SuperTypeId", -1)
|
||||||
|
|
||||||
val vtableSizeField = ConstantDataIntField(
|
val vtableSizeField = ConstantDataIntField(
|
||||||
"V-table length",
|
"V-table length",
|
||||||
classMetadata.virtualMethods.size
|
classMetadata.virtualMethods.size
|
||||||
@@ -298,6 +317,8 @@ class DeclarationGenerator(val context: WasmModuleCodegenContext) : IrElementVis
|
|||||||
return ConstantDataStruct(
|
return ConstantDataStruct(
|
||||||
"Class TypeInfo: ${classMetadata.klass.fqNameWhenAvailable} ",
|
"Class TypeInfo: ${classMetadata.klass.fqNameWhenAvailable} ",
|
||||||
listOf(
|
listOf(
|
||||||
|
typeInfo,
|
||||||
|
superTypeId,
|
||||||
interfaceTablePtr,
|
interfaceTablePtr,
|
||||||
vtableSizeField,
|
vtableSizeField,
|
||||||
vtableArray,
|
vtableArray,
|
||||||
|
|||||||
+23
-1
@@ -12,18 +12,21 @@ import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
|||||||
import org.jetbrains.kotlin.backend.wasm.WasmBackendContext
|
import org.jetbrains.kotlin.backend.wasm.WasmBackendContext
|
||||||
import org.jetbrains.kotlin.ir.backend.js.utils.isEqualsInheritedFromAny
|
import org.jetbrains.kotlin.ir.backend.js.utils.isEqualsInheritedFromAny
|
||||||
import org.jetbrains.kotlin.ir.builders.irCall
|
import org.jetbrains.kotlin.ir.builders.irCall
|
||||||
|
import org.jetbrains.kotlin.ir.builders.irCallConstructor
|
||||||
import org.jetbrains.kotlin.ir.builders.irComposite
|
import org.jetbrains.kotlin.ir.builders.irComposite
|
||||||
import org.jetbrains.kotlin.ir.builders.irInt
|
import org.jetbrains.kotlin.ir.builders.irInt
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
|
import org.jetbrains.kotlin.ir.interpreter.toIrConst
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
|
import org.jetbrains.kotlin.ir.types.classFqName
|
||||||
import org.jetbrains.kotlin.ir.types.getClass
|
import org.jetbrains.kotlin.ir.types.getClass
|
||||||
import org.jetbrains.kotlin.ir.types.isNullable
|
import org.jetbrains.kotlin.ir.types.isNullable
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.name.parentOrNull
|
||||||
|
|
||||||
class BuiltInsLowering(val context: WasmBackendContext) : FileLoweringPass {
|
class BuiltInsLowering(val context: WasmBackendContext) : FileLoweringPass {
|
||||||
private val irBuiltins = context.irBuiltIns
|
private val irBuiltins = context.irBuiltIns
|
||||||
@@ -125,6 +128,25 @@ class BuiltInsLowering(val context: WasmBackendContext) : FileLoweringPass {
|
|||||||
val newSymbol = irBuiltins.suspendFunctionN(arity).getSimpleFunction("invoke")!!
|
val newSymbol = irBuiltins.suspendFunctionN(arity).getSimpleFunction("invoke")!!
|
||||||
return irCall(call, newSymbol, argumentsAsReceivers = true)
|
return irCall(call, newSymbol, argumentsAsReceivers = true)
|
||||||
}
|
}
|
||||||
|
symbols.jsClass -> {
|
||||||
|
val infoDataCtor = symbols.wasmTypeInfoData.constructors.first()
|
||||||
|
val type = call.getTypeArgument(0)!!
|
||||||
|
val fqName = type.classFqName!!
|
||||||
|
val packageName = fqName.parentOrNull()?.asString() ?: ""
|
||||||
|
val typeName = fqName.shortName().asString()
|
||||||
|
|
||||||
|
return with(builder) {
|
||||||
|
val typeId = irCall(symbols.wasmTypeId).also {
|
||||||
|
it.putTypeArgument(0, type)
|
||||||
|
}
|
||||||
|
|
||||||
|
irCallConstructor(infoDataCtor, emptyList()).also {
|
||||||
|
it.putValueArgument(0, typeId)
|
||||||
|
it.putValueArgument(1, packageName.toIrConst(context.irBuiltIns.stringType))
|
||||||
|
it.putValueArgument(2, typeName.toIrConst(context.irBuiltIns.stringType))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return call
|
return call
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: CLASS_REFERENCES
|
|
||||||
class Generic<P : Any>(val p: P)
|
class Generic<P : Any>(val p: P)
|
||||||
|
|
||||||
class Host {
|
class Host {
|
||||||
|
|||||||
-2
@@ -1,5 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: CLASS_REFERENCES
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// WITH_REFLECT
|
// WITH_REFLECT
|
||||||
|
|
||||||
|
|||||||
Vendored
-2
@@ -1,5 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: CLASS_REFERENCES
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// WITH_REFLECT
|
// WITH_REFLECT
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: CLASS_REFERENCES
|
|
||||||
// IGNORE_BACKEND: JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
// IGNORE_BACKEND: JS_IR_ES6
|
// IGNORE_BACKEND: JS_IR_ES6
|
||||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: CLASS_REFERENCES
|
|
||||||
// IGNORE_BACKEND: JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
// IGNORE_BACKEND: JS_IR_ES6
|
// IGNORE_BACKEND: JS_IR_ES6
|
||||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||||
|
|||||||
Vendored
-2
@@ -1,5 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: KOTLIN_TEST_LIB
|
|
||||||
// IGNORE_BACKEND: JS, JS_IR
|
// IGNORE_BACKEND: JS, JS_IR
|
||||||
// IGNORE_BACKEND: JS_IR_ES6
|
// IGNORE_BACKEND: JS_IR_ES6
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|||||||
-2
@@ -1,5 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: CLASS_REFERENCES
|
|
||||||
// IGNORE_BACKEND: NATIVE
|
// IGNORE_BACKEND: NATIVE
|
||||||
// WITH_REFLECT
|
// WITH_REFLECT
|
||||||
// WITH_COROUTINES
|
// WITH_COROUTINES
|
||||||
|
|||||||
-2
@@ -1,5 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: CLASS_REFERENCES
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// WITH_COROUTINES
|
// WITH_COROUTINES
|
||||||
// WITH_REFLECT
|
// WITH_REFLECT
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: CLASS_REFERENCES
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// WITH_COROUTINES
|
// WITH_COROUTINES
|
||||||
// WITH_REFLECT
|
// WITH_REFLECT
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: CLASS_REFERENCES
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// WITH_COROUTINES
|
// WITH_COROUTINES
|
||||||
import helpers.*
|
import helpers.*
|
||||||
|
|||||||
-2
@@ -1,5 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: CLASS_REFERENCES
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// WITH_COROUTINES
|
// WITH_COROUTINES
|
||||||
import helpers.*
|
import helpers.*
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: CLASS_REFERENCES
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// WITH_COROUTINES
|
// WITH_COROUTINES
|
||||||
import kotlin.coroutines.*
|
import kotlin.coroutines.*
|
||||||
|
|||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
fun nonGenericId(x: Any?) = x
|
fun nonGenericId(x: Any?) = x
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: CLASS_REFERENCES
|
|
||||||
class Q<TT> {
|
class Q<TT> {
|
||||||
fun <T> qz(x: T, block: (T) -> String) = block(x)
|
fun <T> qz(x: T, block: (T) -> String) = block(x)
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: REFLECTION
|
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
lateinit var str: String
|
lateinit var str: String
|
||||||
try {
|
try {
|
||||||
|
|||||||
Vendored
-3
@@ -1,8 +1,5 @@
|
|||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: REFLECTION
|
|
||||||
|
|
||||||
import kotlin.UninitializedPropertyAccessException
|
import kotlin.UninitializedPropertyAccessException
|
||||||
|
|
||||||
fun runNoInline(f: () -> Unit) = f()
|
fun runNoInline(f: () -> Unit) = f()
|
||||||
|
|||||||
-2
@@ -1,6 +1,4 @@
|
|||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: REFLECTION
|
// WASM_MUTE_REASON: REFLECTION
|
||||||
|
|
||||||
import kotlin.UninitializedPropertyAccessException
|
import kotlin.UninitializedPropertyAccessException
|
||||||
|
|||||||
-3
@@ -1,8 +1,5 @@
|
|||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: REFLECTION
|
|
||||||
|
|
||||||
import kotlin.UninitializedPropertyAccessException
|
import kotlin.UninitializedPropertyAccessException
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: REFLECTION
|
|
||||||
|
|
||||||
import kotlin.UninitializedPropertyAccessException
|
import kotlin.UninitializedPropertyAccessException
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
|
|||||||
-2
@@ -1,6 +1,4 @@
|
|||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: REFLECTION
|
|
||||||
|
|
||||||
// FILE: lateinit.kt
|
// FILE: lateinit.kt
|
||||||
|
|
||||||
|
|||||||
-3
@@ -1,8 +1,5 @@
|
|||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: REFLECTION
|
|
||||||
|
|
||||||
import kotlin.UninitializedPropertyAccessException
|
import kotlin.UninitializedPropertyAccessException
|
||||||
|
|
||||||
lateinit var str: String
|
lateinit var str: String
|
||||||
|
|||||||
-3
@@ -1,8 +1,5 @@
|
|||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: REFLECTION
|
|
||||||
|
|
||||||
import kotlin.UninitializedPropertyAccessException
|
import kotlin.UninitializedPropertyAccessException
|
||||||
|
|
||||||
lateinit var str: String
|
lateinit var str: String
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: IGNORED_IN_JS
|
|
||||||
// IGNORE_BACKEND: JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
// IGNORE_BACKEND: JS_IR_ES6
|
// IGNORE_BACKEND: JS_IR_ES6
|
||||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
// IGNORE_BACKEND: WASM
|
||||||
// WASM_MUTE_REASON: CLASS_REFERENCES
|
// WASM_MUTE_REASON: TYPEOF
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
// See KT-37163
|
// See KT-37163
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
// IGNORE_BACKEND: WASM
|
||||||
// WASM_MUTE_REASON: CLASS_REFERENCES
|
// WASM_MUTE_REASON: TYPEOF
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
// See KT-37163
|
// See KT-37163
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
// IGNORE_BACKEND: WASM
|
||||||
// WASM_MUTE_REASON: CLASS_REFERENCES
|
// WASM_MUTE_REASON: TYPEOF
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
// See KT-37163
|
// See KT-37163
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: CLASS_REFERENCES
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
// See KT-37128
|
// See KT-37128
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
// IGNORE_BACKEND: WASM
|
||||||
// WASM_MUTE_REASON: CLASS_REFERENCES
|
// WASM_MUTE_REASON: ULONG_TOSTRING
|
||||||
// KJS_WITH_FULL_RUNTIME
|
// KJS_WITH_FULL_RUNTIME
|
||||||
// WITH_REFLECT
|
// WITH_REFLECT
|
||||||
|
|
||||||
|
|||||||
@@ -9,11 +9,30 @@ package kotlin.wasm.internal
|
|||||||
|
|
||||||
internal const val TYPE_INFO_ELEMENT_SIZE = 4
|
internal const val TYPE_INFO_ELEMENT_SIZE = 4
|
||||||
|
|
||||||
|
internal const val TYPE_INFO_TYPE_PACKAGE_NAME_LENGTH_OFFSET = 0
|
||||||
internal const val TYPE_INFO_ITABLE_PTR_OFFSET = 0
|
internal const val TYPE_INFO_TYPE_PACKAGE_NAME_PRT_OFFSET = TYPE_INFO_TYPE_PACKAGE_NAME_LENGTH_OFFSET + TYPE_INFO_ELEMENT_SIZE
|
||||||
|
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_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_VTABLE_OFFSET = TYPE_INFO_VTABLE_LENGTH_OFFSET + TYPE_INFO_ELEMENT_SIZE
|
||||||
|
|
||||||
|
internal class TypeInfoData(val typeId: Int, val packageName: String, val typeName: String)
|
||||||
|
|
||||||
|
internal fun getTypeInfoTypeDataByPtr(typeInfoPtr: Int): TypeInfoData {
|
||||||
|
val fqNameLength = wasm_i32_load(typeInfoPtr + TYPE_INFO_TYPE_PACKAGE_NAME_LENGTH_OFFSET)
|
||||||
|
val fqNameLengthPtr = wasm_i32_load(typeInfoPtr + TYPE_INFO_TYPE_PACKAGE_NAME_PRT_OFFSET)
|
||||||
|
val simpleNameLength = wasm_i32_load(typeInfoPtr + TYPE_INFO_TYPE_SIMPLE_NAME_LENGTH_OFFSET)
|
||||||
|
val simpleNamePtr = wasm_i32_load(typeInfoPtr + TYPE_INFO_TYPE_SIMPLE_NAME_PRT_OFFSET)
|
||||||
|
val packageName = stringLiteral(fqNameLengthPtr, fqNameLength)
|
||||||
|
val simpleName = stringLiteral(simpleNamePtr, simpleNameLength)
|
||||||
|
return TypeInfoData(typeInfoPtr, packageName, simpleName)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun getSuperTypeId(typeInfoPtr: Int): Int =
|
||||||
|
wasm_i32_load(typeInfoPtr + TYPE_INFO_SUPER_TYPE_OFFSET)
|
||||||
|
|
||||||
internal fun getVtablePtr(obj: Any): Int =
|
internal fun getVtablePtr(obj: Any): Int =
|
||||||
obj.typeInfo + TYPE_INFO_VTABLE_OFFSET
|
obj.typeInfo + TYPE_INFO_VTABLE_OFFSET
|
||||||
|
|
||||||
@@ -60,4 +79,12 @@ internal fun <T> wasmClassId(): Int =
|
|||||||
|
|
||||||
@ExcludedFromCodegen
|
@ExcludedFromCodegen
|
||||||
internal fun <T> wasmInterfaceId(): Int =
|
internal fun <T> wasmInterfaceId(): Int =
|
||||||
|
implementedAsIntrinsic
|
||||||
|
|
||||||
|
@ExcludedFromCodegen
|
||||||
|
internal fun <T> wasmGetTypeInfoData(): TypeInfoData =
|
||||||
|
implementedAsIntrinsic
|
||||||
|
|
||||||
|
@ExcludedFromCodegen
|
||||||
|
internal fun <T> wasmTypeId(): Int =
|
||||||
implementedAsIntrinsic
|
implementedAsIntrinsic
|
||||||
@@ -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>())
|
||||||
Reference in New Issue
Block a user