diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsCommonBackendContext.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsCommonBackendContext.kt index 206280367e7..45d30d6d39e 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsCommonBackendContext.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsCommonBackendContext.kt @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.ir.backend.js import org.jetbrains.kotlin.backend.common.BackendContext import org.jetbrains.kotlin.backend.common.CommonBackendContext 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.descriptors.ClassDescriptor 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.ir.backend.js.utils.isDispatchReceiver 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.types.IrDynamicType import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.ir.util.getPropertyGetter @@ -29,10 +30,16 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope interface JsCommonBackendContext : CommonBackendContext { override val mapping: JsMapping + val intrinsics: Intrinsics + + val dynamicType: IrDynamicType + val inlineClassesUtils: InlineClassesUtils val coroutineSymbols: JsCommonCoroutineSymbols + val primitiveClassesObject: IrClassSymbol + val catchAllThrowableType: IrType get() = irBuiltIns.throwableType @@ -50,7 +57,7 @@ internal fun BackendContext.lazy2(fn: () -> T) = lazy { irFactory.stageContr class JsCommonCoroutineSymbols( symbolTable: SymbolTable, - module: ModuleDescriptor, + val module: ModuleDescriptor, val context: JsCommonBackendContext ) { 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 -internal fun findFunctions(memberScope: MemberScope, name: Name): List = +fun findFunctions(memberScope: MemberScope, name: Name): List = memberScope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND).toList() interface InlineClassesUtils { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIntrinsics.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIntrinsics.kt index 45816b44981..1a7c0766b4a 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIntrinsics.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIntrinsics.kt @@ -21,7 +21,21 @@ import org.jetbrains.kotlin.psi2ir.findSingleFunction import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly 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? @@ -169,10 +183,10 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC getInternalWithoutPackage("kotlin.coroutines.intrinsics.invokeSuspendSuperTypeWithReceiver") val jsInvokeSuspendSuperTypeWithReceiverAndParam = 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 jsNumberRangeToLong = getInternalFunction("numberRangeToLong") @@ -235,7 +249,7 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC val jsPrimitiveArrayIteratorFunctions = PrimitiveType.values().associate { it to getInternalFunction("${it.typeName.asString().toLowerCaseAsciiOnly()}ArrayIterator") } - val arrayLiteral = getInternalFunction("arrayLiteral") + override val arrayLiteral = getInternalFunction("arrayLiteral") val primitiveToTypedArrayMap = EnumMap( mapOf( @@ -247,13 +261,13 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC ) ) - val createKType = getInternalWithoutPackageOrNull("createKType") - val createDynamicKType = getInternalWithoutPackageOrNull("createDynamicKType") - val createKTypeParameter = getInternalWithoutPackageOrNull("createKTypeParameter") - val getStarKTypeProjection = getInternalWithoutPackageOrNull("getStarKTypeProjection") - val createCovariantKTypeProjection = getInternalWithoutPackageOrNull("createCovariantKTypeProjection") - val createInvariantKTypeProjection = getInternalWithoutPackageOrNull("createInvariantKTypeProjection") - val createContravariantKTypeProjection = getInternalWithoutPackageOrNull("createContravariantKTypeProjection") + override val createKType = getInternalWithoutPackageOrNull("createKType") + override val createDynamicKType = getInternalWithoutPackageOrNull("createDynamicKType") + override val createKTypeParameter = getInternalWithoutPackageOrNull("createKTypeParameter") + override val getStarKTypeProjection = getInternalWithoutPackageOrNull("getStarKTypeProjection") + override val createCovariantKTypeProjection = getInternalWithoutPackageOrNull("createCovariantKTypeProjection") + override val createInvariantKTypeProjection = getInternalWithoutPackageOrNull("createInvariantKTypeProjection") + override val createContravariantKTypeProjection = getInternalWithoutPackageOrNull("createContravariantKTypeProjection") val primitiveToSizeConstructor = PrimitiveType.values().associate { type -> @@ -315,8 +329,6 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC val jsUndefined = getInternalFunction("jsUndefined") - // Helpers: - private fun getInternalFunction(name: String) = context.symbolTable.referenceSimpleFunction(context.getJsInternalFunction(name)) @@ -333,4 +345,4 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC private fun getInternalClassWithoutPackage(fqName: String) = context.symbolTable.referenceClass(context.getClass(FqName(fqName))) -} +} \ No newline at end of file diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt index 26a1b4815f8..999ef102c82 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt @@ -68,6 +68,7 @@ class JsIrBackendContext( val extractedLocalClasses: MutableSet = hashSetOf() override val builtIns = module.builtIns + override val typeSystem: IrTypeSystemContext = IrTypeSystemContextImpl(irBuiltIns) override val irFactory: IrFactory = symbolTable.irFactory @@ -156,9 +157,8 @@ class JsIrBackendContext( private val internalPackage = module.getPackage(JS_PACKAGE_FQNAME) - - val dynamicType: IrDynamicType = IrDynamicTypeImpl(null, emptyList(), Variance.INVARIANT) - val intrinsics = JsIntrinsics(irBuiltIns, this) + override val dynamicType: IrDynamicType = IrDynamicTypeImpl(null, emptyList(), Variance.INVARIANT) + override val intrinsics = JsIntrinsics(irBuiltIns, this) override val catchAllThrowableType: IrType get() = dynamicType @@ -284,7 +284,7 @@ class JsIrBackendContext( val errorCodeSymbol: IrSimpleFunctionSymbol? = 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"))) @@ -323,16 +323,6 @@ class JsIrBackendContext( 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) } - val primitiveClassProperties by lazy2 { - primitiveClassesObject.owner.declarations.filterIsInstance() - } - - val primitiveClassFunctionClass by lazy2 { - primitiveClassesObject.owner.declarations - .filterIsInstance() - .find { it.name == Name.identifier("functionClass") }!! - } - val throwableConstructors by lazy2 { throwableClass.owner.declarations.filterIsInstance().map { it.symbol } } val defaultThrowableCtor by lazy2 { throwableConstructors.single { !it.owner.isPrimary && it.owner.valueParameters.size == 0 } } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ClassReferenceLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ClassReferenceLowering.kt index 176bb02796e..bdbae7cfa6e 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ClassReferenceLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ClassReferenceLowering.kt @@ -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.IrElementTransformerVoidWithContext import org.jetbrains.kotlin.backend.common.ir.Symbols -import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext -import org.jetbrains.kotlin.ir.backend.js.JsLoweredDeclarationOrigin +import org.jetbrains.kotlin.ir.backend.js.* import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder import org.jetbrains.kotlin.ir.backend.js.utils.toJsArrayLiteral 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.types.* -class ClassReferenceLowering(val context: JsIrBackendContext) : BodyLoweringPass { - private val intrinsics = context.intrinsics +class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLoweringPass { + + private val primitiveClassProperties by lazy { + primitiveClassesObject.owner.declarations.filterIsInstance() + } + + private val primitiveClassFunctionClass by lazy { + primitiveClassesObject.owner.declarations + .filterIsInstance() + .find { it.name == Name.identifier("functionClass") }!! + } private val primitiveClassesObject = context.primitiveClassesObject - private val primitiveClassProperties = context.primitiveClassProperties - private fun primitiveClassProperty(name: String) = primitiveClassProperties.singleOrNull { it.name == Name.identifier(name) }?.getter ?: primitiveClassesObject.owner.declarations.filterIsInstance().single { it.name == Name.special("") } @@ -74,7 +80,7 @@ class ClassReferenceLowering(val context: JsIrBackendContext) : BodyLoweringPass if (primitiveKClass != null) 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) } } @@ -103,7 +109,7 @@ class ClassReferenceLowering(val context: JsIrBackendContext) : BodyLoweringPass if (typeArgument.isFunction()) { val functionInterface = typeArgument.getClass()!! 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)) } } @@ -112,7 +118,7 @@ class ClassReferenceLowering(val context: JsIrBackendContext) : BodyLoweringPass } private fun callGetKClass( - returnType: IrType = intrinsics.jsGetKClass.owner.returnType, + returnType: IrType = context.intrinsics.jsGetKClass.owner.returnType, typeArgument: IrType ): IrCall { val primitiveKClass = @@ -121,7 +127,7 @@ class ClassReferenceLowering(val context: JsIrBackendContext) : BodyLoweringPass if (primitiveKClass != null) return primitiveKClass - return JsIrBuilder.buildCall(intrinsics.jsGetKClass, returnType, listOf(typeArgument)) + return JsIrBuilder.buildCall(context.intrinsics.jsGetKClass, returnType, listOf(typeArgument)) .apply { putValueArgument(0, callJsClass(typeArgument)) } @@ -129,7 +135,7 @@ class ClassReferenceLowering(val context: JsIrBackendContext) : BodyLoweringPass private fun callJsClass(type: IrType) = JsIrBuilder.buildCall( - intrinsics.jsClass, + context.intrinsics.jsClass, typeArguments = listOf(type), origin = JsLoweredDeclarationOrigin.CLASS_REFERENCE ) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/misc.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/misc.kt index 793da41b988..799e06248d0 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/misc.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/misc.kt @@ -71,7 +71,7 @@ fun IrDeclaration.hasStaticDispatch() = when (this) { else -> true } -fun List.toJsArrayLiteral(context: JsIrBackendContext, arrayType: IrType, elementType: IrType): IrExpression { +fun List.toJsArrayLiteral(context: JsCommonBackendContext, arrayType: IrType, elementType: IrType): IrExpression { val irVararg = IrVarargImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, arrayType, elementType, this) return IrCallImpl( diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmBackendContext.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmBackendContext.kt index e0090ea7e9e..a8295b92458 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmBackendContext.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmBackendContext.kt @@ -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.symbols.IrSimpleFunctionSymbol 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.IrTypeSystemContextImpl import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.name.FqName 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( val module: ModuleDescriptor, override val irBuiltIns: IrBuiltIns, - symbolTable: SymbolTable, - irModuleFragment: IrModuleFragment, + val symbolTable: SymbolTable, + val irModuleFragment: IrModuleFragment, override val configuration: CompilerConfiguration, ) : JsCommonBackendContext { override val builtIns = module.builtIns @@ -43,6 +68,11 @@ class WasmBackendContext( override val scriptMode = false 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 private val excludedDeclarations = mutableMapOf() @@ -169,4 +199,6 @@ class WasmBackendContext( } } } + + override val intrinsics: Intrinsics = WasmIntrinsics(this) } diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmLoweringPhases.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmLoweringPhases.kt index def400042b3..adf03b7849f 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmLoweringPhases.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmLoweringPhases.kt @@ -416,6 +416,12 @@ private val staticMembersLoweringPhase = makeWasmModulePhase( description = "Move static member declarations to top-level" ) +private val classReferenceLoweringPhase = makeWasmModulePhase( + ::ClassReferenceLowering, + name = "ClassReferenceLowering", + description = "Handle class references" +) + private val wasmVarargExpressionLoweringPhase = makeWasmModulePhase( ::WasmVarargExpressionLowering, name = "WasmVarargExpressionLowering", @@ -521,6 +527,8 @@ val wasmPhases = NamedCompilerPhase( wrapInlineDeclarationsWithReifiedTypeParametersPhase then functionInliningPhase then + removeInlineDeclarationsWithReifiedTypeParametersLoweringPhase then + lateinitNullableFieldsPhase then lateinitDeclarationLoweringPhase then lateinitUsageLoweringPhase then @@ -577,11 +585,10 @@ val wasmPhases = NamedCompilerPhase( defaultArgumentPatchOverridesPhase then defaultParameterInjectorPhase then defaultParameterCleanerPhase then - removeInlineDeclarationsWithReifiedTypeParametersLoweringPhase then // TODO: // multipleCatchesLoweringPhase then -// classReferenceLoweringPhase then + classReferenceLoweringPhase then wasmVarargExpressionLoweringPhase then inlineClassDeclarationLoweringPhase then diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmSymbols.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmSymbols.kt index 5febd359d4c..6a453914dc5 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmSymbols.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmSymbols.kt @@ -45,6 +45,12 @@ class WasmSymbols( private val kotlinTestPackage: PackageViewDescriptor = 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 throwISE = getInternalFunction("THROW_ISE") override val throwTypeCastException = getInternalFunction("THROW_CCE") @@ -145,6 +151,7 @@ class WasmSymbols( val wasmClassId = getInternalFunction("wasmClassId") val wasmInterfaceId = getInternalFunction("wasmInterfaceId") + val wasmTypeId = getInternalFunction("wasmTypeId") val getVirtualMethodId = getInternalFunction("getVirtualMethodId") val getInterfaceImplId = getInternalFunction("getInterfaceImplId") diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/BodyGenerator.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/BodyGenerator.kt index 6cbef3c7236..aa2f3d52aea 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/BodyGenerator.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/BodyGenerator.kt @@ -348,6 +348,13 @@ class BodyGenerator(val context: WasmFunctionCodegenContext) : IrElementVisitorV 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 -> { val toType = call.getTypeArgument(0)!! generateTypeRTT(toType) diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/DeclarationGenerator.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/DeclarationGenerator.kt index 93f091514d4..d0a45858614 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/DeclarationGenerator.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/DeclarationGenerator.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid +import org.jetbrains.kotlin.name.parentOrNull import org.jetbrains.kotlin.wasm.ir.* class DeclarationGenerator(val context: WasmModuleCodegenContext) : IrElementVisitorVoid { @@ -274,6 +275,24 @@ class DeclarationGenerator(val context: WasmModuleCodegenContext) : IrElementVis private fun binaryDataStruct(classMetadata: ClassMetadata): ConstantDataStruct { 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( "V-table length", classMetadata.virtualMethods.size @@ -298,6 +317,8 @@ class DeclarationGenerator(val context: WasmModuleCodegenContext) : IrElementVis return ConstantDataStruct( "Class TypeInfo: ${classMetadata.klass.fqNameWhenAvailable} ", listOf( + typeInfo, + superTypeId, interfaceTablePtr, vtableSizeField, vtableArray, diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/BuiltInsLowering.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/BuiltInsLowering.kt index 26540d9f63a..db59a614482 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/BuiltInsLowering.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/BuiltInsLowering.kt @@ -12,18 +12,21 @@ import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.wasm.WasmBackendContext import org.jetbrains.kotlin.ir.backend.js.utils.isEqualsInheritedFromAny 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.irInt import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.expressions.IrCall 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.classFqName import org.jetbrains.kotlin.ir.types.getClass import org.jetbrains.kotlin.ir.types.isNullable import org.jetbrains.kotlin.ir.util.* 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 { private val irBuiltins = context.irBuiltIns @@ -125,6 +128,25 @@ class BuiltInsLowering(val context: WasmBackendContext) : FileLoweringPass { val newSymbol = irBuiltins.suspendFunctionN(arity).getSimpleFunction("invoke")!! 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 diff --git a/compiler/testData/codegen/box/callableReference/bound/genericValOnLHS.kt b/compiler/testData/codegen/box/callableReference/bound/genericValOnLHS.kt index cdf63748d35..8911473c689 100644 --- a/compiler/testData/codegen/box/callableReference/bound/genericValOnLHS.kt +++ b/compiler/testData/codegen/box/callableReference/bound/genericValOnLHS.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: CLASS_REFERENCES class Generic

(val p: P) class Host { diff --git a/compiler/testData/codegen/box/callableReference/function/genericCallableReferencesWithNullableTypes.kt b/compiler/testData/codegen/box/callableReference/function/genericCallableReferencesWithNullableTypes.kt index 19cd6091d5a..59896ac53f8 100644 --- a/compiler/testData/codegen/box/callableReference/function/genericCallableReferencesWithNullableTypes.kt +++ b/compiler/testData/codegen/box/callableReference/function/genericCallableReferencesWithNullableTypes.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: CLASS_REFERENCES // WITH_RUNTIME // WITH_REFLECT diff --git a/compiler/testData/codegen/box/callableReference/function/genericCallableReferencesWithOverload.kt b/compiler/testData/codegen/box/callableReference/function/genericCallableReferencesWithOverload.kt index 9da0f3d8762..874f41cac3c 100644 --- a/compiler/testData/codegen/box/callableReference/function/genericCallableReferencesWithOverload.kt +++ b/compiler/testData/codegen/box/callableReference/function/genericCallableReferencesWithOverload.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: CLASS_REFERENCES // WITH_RUNTIME // WITH_REFLECT diff --git a/compiler/testData/codegen/box/casts/functions/asFunKBig.kt b/compiler/testData/codegen/box/casts/functions/asFunKBig.kt index 857b6c39825..0c170a05a5d 100644 --- a/compiler/testData/codegen/box/casts/functions/asFunKBig.kt +++ b/compiler/testData/codegen/box/casts/functions/asFunKBig.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: CLASS_REFERENCES // IGNORE_BACKEND: JS_IR // IGNORE_BACKEND: JS_IR_ES6 // TODO: muted automatically, investigate should it be ran for JS or not diff --git a/compiler/testData/codegen/box/casts/functions/reifiedAsFunKBig.kt b/compiler/testData/codegen/box/casts/functions/reifiedAsFunKBig.kt index 5820c0e753f..d780181d747 100644 --- a/compiler/testData/codegen/box/casts/functions/reifiedAsFunKBig.kt +++ b/compiler/testData/codegen/box/casts/functions/reifiedAsFunKBig.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: CLASS_REFERENCES // IGNORE_BACKEND: JS_IR // IGNORE_BACKEND: JS_IR_ES6 // TODO: muted automatically, investigate should it be ran for JS or not diff --git a/compiler/testData/codegen/box/coroutines/doubleColonExpressionsGenerationInBuilderInference.kt b/compiler/testData/codegen/box/coroutines/doubleColonExpressionsGenerationInBuilderInference.kt index dea0f8e4e18..f5f0b878cfb 100644 --- a/compiler/testData/codegen/box/coroutines/doubleColonExpressionsGenerationInBuilderInference.kt +++ b/compiler/testData/codegen/box/coroutines/doubleColonExpressionsGenerationInBuilderInference.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: KOTLIN_TEST_LIB // IGNORE_BACKEND: JS, JS_IR // IGNORE_BACKEND: JS_IR_ES6 // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/function/genericCallableReferencesWithNullableTypes.kt b/compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/function/genericCallableReferencesWithNullableTypes.kt index f84f0f3871c..3f9a13de024 100644 --- a/compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/function/genericCallableReferencesWithNullableTypes.kt +++ b/compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/function/genericCallableReferencesWithNullableTypes.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: CLASS_REFERENCES // IGNORE_BACKEND: NATIVE // WITH_REFLECT // WITH_COROUTINES diff --git a/compiler/testData/codegen/box/coroutines/inlineGenericFunCalledFromSubclass.kt b/compiler/testData/codegen/box/coroutines/inlineGenericFunCalledFromSubclass.kt index e3d43a6d838..bfbf7d3055d 100644 --- a/compiler/testData/codegen/box/coroutines/inlineGenericFunCalledFromSubclass.kt +++ b/compiler/testData/codegen/box/coroutines/inlineGenericFunCalledFromSubclass.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: CLASS_REFERENCES // WITH_RUNTIME // WITH_COROUTINES // WITH_REFLECT diff --git a/compiler/testData/codegen/box/coroutines/inlineSuspendFunction.kt b/compiler/testData/codegen/box/coroutines/inlineSuspendFunction.kt index c7fe5a64e4e..a3be99db7be 100644 --- a/compiler/testData/codegen/box/coroutines/inlineSuspendFunction.kt +++ b/compiler/testData/codegen/box/coroutines/inlineSuspendFunction.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: CLASS_REFERENCES // WITH_RUNTIME // WITH_COROUTINES // WITH_REFLECT diff --git a/compiler/testData/codegen/box/coroutines/instanceOfContinuation.kt b/compiler/testData/codegen/box/coroutines/instanceOfContinuation.kt index 2e53b1b6e1b..28c33ee5317 100644 --- a/compiler/testData/codegen/box/coroutines/instanceOfContinuation.kt +++ b/compiler/testData/codegen/box/coroutines/instanceOfContinuation.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: CLASS_REFERENCES // WITH_RUNTIME // WITH_COROUTINES import helpers.* diff --git a/compiler/testData/codegen/box/coroutines/stackUnwinding/inlineSuspendFunction.kt b/compiler/testData/codegen/box/coroutines/stackUnwinding/inlineSuspendFunction.kt index a95a593ac85..a83b52f2a2f 100644 --- a/compiler/testData/codegen/box/coroutines/stackUnwinding/inlineSuspendFunction.kt +++ b/compiler/testData/codegen/box/coroutines/stackUnwinding/inlineSuspendFunction.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: CLASS_REFERENCES // WITH_RUNTIME // WITH_COROUTINES import helpers.* diff --git a/compiler/testData/codegen/box/coroutines/varSpilling/fakeInlinerVariables.kt b/compiler/testData/codegen/box/coroutines/varSpilling/fakeInlinerVariables.kt index 287a3961d18..eafd0f0613e 100644 --- a/compiler/testData/codegen/box/coroutines/varSpilling/fakeInlinerVariables.kt +++ b/compiler/testData/codegen/box/coroutines/varSpilling/fakeInlinerVariables.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: CLASS_REFERENCES // WITH_RUNTIME // WITH_COROUTINES import kotlin.coroutines.* diff --git a/compiler/testData/codegen/box/inference/builderInference/callableReferencesProperCompletion.kt b/compiler/testData/codegen/box/inference/builderInference/callableReferencesProperCompletion.kt index b4423ab99cb..74e29a552b4 100644 --- a/compiler/testData/codegen/box/inference/builderInference/callableReferencesProperCompletion.kt +++ b/compiler/testData/codegen/box/inference/builderInference/callableReferencesProperCompletion.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: WASM // WITH_RUNTIME fun nonGenericId(x: Any?) = x diff --git a/compiler/testData/codegen/box/localClasses/localGenericWithTypeParameters.kt b/compiler/testData/codegen/box/localClasses/localGenericWithTypeParameters.kt index a9f2ce9b515..769b77915ef 100644 --- a/compiler/testData/codegen/box/localClasses/localGenericWithTypeParameters.kt +++ b/compiler/testData/codegen/box/localClasses/localGenericWithTypeParameters.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: CLASS_REFERENCES class Q { fun qz(x: T, block: (T) -> String) = block(x) diff --git a/compiler/testData/codegen/box/properties/lateinit/local/kt23260.kt b/compiler/testData/codegen/box/properties/lateinit/local/kt23260.kt index 0ea211d1679..422a501ba6d 100644 --- a/compiler/testData/codegen/box/properties/lateinit/local/kt23260.kt +++ b/compiler/testData/codegen/box/properties/lateinit/local/kt23260.kt @@ -1,8 +1,5 @@ // WITH_RUNTIME -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: REFLECTION - fun box(): String { lateinit var str: String try { diff --git a/compiler/testData/codegen/box/properties/lateinit/local/uninitializedCapturedMemberAccess.kt b/compiler/testData/codegen/box/properties/lateinit/local/uninitializedCapturedMemberAccess.kt index 41999e6b919..8735a8ec7e2 100644 --- a/compiler/testData/codegen/box/properties/lateinit/local/uninitializedCapturedMemberAccess.kt +++ b/compiler/testData/codegen/box/properties/lateinit/local/uninitializedCapturedMemberAccess.kt @@ -1,8 +1,5 @@ // WITH_RUNTIME -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: REFLECTION - import kotlin.UninitializedPropertyAccessException fun runNoInline(f: () -> Unit) = f() diff --git a/compiler/testData/codegen/box/properties/lateinit/local/uninitializedCapturedRead.kt b/compiler/testData/codegen/box/properties/lateinit/local/uninitializedCapturedRead.kt index baafb4cbf4d..5e119eaeccf 100644 --- a/compiler/testData/codegen/box/properties/lateinit/local/uninitializedCapturedRead.kt +++ b/compiler/testData/codegen/box/properties/lateinit/local/uninitializedCapturedRead.kt @@ -1,6 +1,4 @@ // WITH_RUNTIME - -// IGNORE_BACKEND: WASM // WASM_MUTE_REASON: REFLECTION import kotlin.UninitializedPropertyAccessException diff --git a/compiler/testData/codegen/box/properties/lateinit/local/uninitializedMemberAccess.kt b/compiler/testData/codegen/box/properties/lateinit/local/uninitializedMemberAccess.kt index f8d260ebc7e..d3d8acc31e5 100644 --- a/compiler/testData/codegen/box/properties/lateinit/local/uninitializedMemberAccess.kt +++ b/compiler/testData/codegen/box/properties/lateinit/local/uninitializedMemberAccess.kt @@ -1,8 +1,5 @@ // WITH_RUNTIME -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: REFLECTION - import kotlin.UninitializedPropertyAccessException fun box(): String { diff --git a/compiler/testData/codegen/box/properties/lateinit/local/uninitializedRead.kt b/compiler/testData/codegen/box/properties/lateinit/local/uninitializedRead.kt index aa2888302ef..9a58e3280b3 100644 --- a/compiler/testData/codegen/box/properties/lateinit/local/uninitializedRead.kt +++ b/compiler/testData/codegen/box/properties/lateinit/local/uninitializedRead.kt @@ -1,8 +1,5 @@ // WITH_RUNTIME -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: REFLECTION - import kotlin.UninitializedPropertyAccessException fun box(): String { diff --git a/compiler/testData/codegen/box/properties/lateinit/topLevel/accessorException.kt b/compiler/testData/codegen/box/properties/lateinit/topLevel/accessorException.kt index d4b30d811eb..949145290af 100644 --- a/compiler/testData/codegen/box/properties/lateinit/topLevel/accessorException.kt +++ b/compiler/testData/codegen/box/properties/lateinit/topLevel/accessorException.kt @@ -1,6 +1,4 @@ // WITH_RUNTIME -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: REFLECTION // FILE: lateinit.kt diff --git a/compiler/testData/codegen/box/properties/lateinit/topLevel/uninitializedMemberAccess.kt b/compiler/testData/codegen/box/properties/lateinit/topLevel/uninitializedMemberAccess.kt index 7a33dda8bf9..ac24a14335f 100644 --- a/compiler/testData/codegen/box/properties/lateinit/topLevel/uninitializedMemberAccess.kt +++ b/compiler/testData/codegen/box/properties/lateinit/topLevel/uninitializedMemberAccess.kt @@ -1,8 +1,5 @@ // WITH_RUNTIME -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: REFLECTION - import kotlin.UninitializedPropertyAccessException lateinit var str: String diff --git a/compiler/testData/codegen/box/properties/lateinit/topLevel/uninitializedRead.kt b/compiler/testData/codegen/box/properties/lateinit/topLevel/uninitializedRead.kt index 9f4c900259e..9cc162d805c 100644 --- a/compiler/testData/codegen/box/properties/lateinit/topLevel/uninitializedRead.kt +++ b/compiler/testData/codegen/box/properties/lateinit/topLevel/uninitializedRead.kt @@ -1,8 +1,5 @@ // WITH_RUNTIME -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: REFLECTION - import kotlin.UninitializedPropertyAccessException lateinit var str: String diff --git a/compiler/testData/codegen/box/ranges/safeCallRangeTo.kt b/compiler/testData/codegen/box/ranges/safeCallRangeTo.kt index 3b07ad86aa0..524f5d21000 100644 --- a/compiler/testData/codegen/box/ranges/safeCallRangeTo.kt +++ b/compiler/testData/codegen/box/ranges/safeCallRangeTo.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: IGNORED_IN_JS // IGNORE_BACKEND: JS_IR // IGNORE_BACKEND: JS_IR_ES6 // TODO: muted automatically, investigate should it be ran for JS or not diff --git a/compiler/testData/codegen/box/reified/reifiedIntersectionTypeArgument.kt b/compiler/testData/codegen/box/reified/reifiedIntersectionTypeArgument.kt index 9439606c71a..bfcdbdfa5cc 100644 --- a/compiler/testData/codegen/box/reified/reifiedIntersectionTypeArgument.kt +++ b/compiler/testData/codegen/box/reified/reifiedIntersectionTypeArgument.kt @@ -1,5 +1,5 @@ // IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: CLASS_REFERENCES +// WASM_MUTE_REASON: TYPEOF // WITH_RUNTIME // See KT-37163 diff --git a/compiler/testData/codegen/box/reified/reifiedIntersectionTypeArgumentCrossModule.kt b/compiler/testData/codegen/box/reified/reifiedIntersectionTypeArgumentCrossModule.kt index fbc1c8ec2c9..18b2692268a 100644 --- a/compiler/testData/codegen/box/reified/reifiedIntersectionTypeArgumentCrossModule.kt +++ b/compiler/testData/codegen/box/reified/reifiedIntersectionTypeArgumentCrossModule.kt @@ -1,5 +1,5 @@ // IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: CLASS_REFERENCES +// WASM_MUTE_REASON: TYPEOF // WITH_RUNTIME // See KT-37163 diff --git a/compiler/testData/codegen/box/reified/reifiedTypeArgumentWithIntersectionTypeAsTypeArgument.kt b/compiler/testData/codegen/box/reified/reifiedTypeArgumentWithIntersectionTypeAsTypeArgument.kt index 7049e221552..445047a035a 100644 --- a/compiler/testData/codegen/box/reified/reifiedTypeArgumentWithIntersectionTypeAsTypeArgument.kt +++ b/compiler/testData/codegen/box/reified/reifiedTypeArgumentWithIntersectionTypeAsTypeArgument.kt @@ -1,5 +1,5 @@ // IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: CLASS_REFERENCES +// WASM_MUTE_REASON: TYPEOF // WITH_RUNTIME // See KT-37163 diff --git a/compiler/testData/codegen/box/reified/reifiedTypeArgumentWithRecursion.kt b/compiler/testData/codegen/box/reified/reifiedTypeArgumentWithRecursion.kt index 9393853a5fe..c64af9e2047 100644 --- a/compiler/testData/codegen/box/reified/reifiedTypeArgumentWithRecursion.kt +++ b/compiler/testData/codegen/box/reified/reifiedTypeArgumentWithRecursion.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: CLASS_REFERENCES // WITH_RUNTIME // See KT-37128 diff --git a/compiler/testData/codegen/box/unsignedTypes/unsignedTypePrefixIncrementDecrementBoxing.kt b/compiler/testData/codegen/box/unsignedTypes/unsignedTypePrefixIncrementDecrementBoxing.kt index b8f4a21a2d5..ef87af97f33 100644 --- a/compiler/testData/codegen/box/unsignedTypes/unsignedTypePrefixIncrementDecrementBoxing.kt +++ b/compiler/testData/codegen/box/unsignedTypes/unsignedTypePrefixIncrementDecrementBoxing.kt @@ -1,5 +1,5 @@ // IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: CLASS_REFERENCES +// WASM_MUTE_REASON: ULONG_TOSTRING // KJS_WITH_FULL_RUNTIME // WITH_REFLECT diff --git a/libraries/stdlib/wasm/internal/kotlin/wasm/internal/TypeInfo.kt b/libraries/stdlib/wasm/internal/kotlin/wasm/internal/TypeInfo.kt index 1e0102e95f3..124893bcd9b 100644 --- a/libraries/stdlib/wasm/internal/kotlin/wasm/internal/TypeInfo.kt +++ b/libraries/stdlib/wasm/internal/kotlin/wasm/internal/TypeInfo.kt @@ -9,11 +9,30 @@ package kotlin.wasm.internal internal const val TYPE_INFO_ELEMENT_SIZE = 4 - -internal const val TYPE_INFO_ITABLE_PTR_OFFSET = 0 +internal const val TYPE_INFO_TYPE_PACKAGE_NAME_LENGTH_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_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 = obj.typeInfo + TYPE_INFO_VTABLE_OFFSET @@ -60,4 +79,12 @@ internal fun wasmClassId(): Int = @ExcludedFromCodegen internal fun wasmInterfaceId(): Int = + implementedAsIntrinsic + +@ExcludedFromCodegen +internal fun wasmGetTypeInfoData(): TypeInfoData = + implementedAsIntrinsic + +@ExcludedFromCodegen +internal fun wasmTypeId(): Int = implementedAsIntrinsic \ No newline at end of file diff --git a/libraries/stdlib/wasm/src/kotlin/reflect/KClassImpl.kt b/libraries/stdlib/wasm/src/kotlin/reflect/KClassImpl.kt new file mode 100644 index 00000000000..67dc1dc820a --- /dev/null +++ b/libraries/stdlib/wasm/src/kotlin/reflect/KClassImpl.kt @@ -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 { + 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 { + 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(private val typeData: TypeInfoData) : KClass { + 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 +} \ No newline at end of file diff --git a/libraries/stdlib/wasm/src/kotlin/reflect/primitives.kt b/libraries/stdlib/wasm/src/kotlin/reflect/primitives.kt new file mode 100644 index 00000000000..c4d76b13abf --- /dev/null +++ b/libraries/stdlib/wasm/src/kotlin/reflect/primitives.kt @@ -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() + val numberClass = wasmGetKClass() + val booleanClass = wasmGetKClass() + val byteClass = wasmGetKClass() + val shortClass = wasmGetKClass() + val intClass = wasmGetKClass() + val floatClass = wasmGetKClass() + val doubleClass = wasmGetKClass() + val arrayClass = wasmGetKClass>() + val stringClass = wasmGetKClass() + + val throwableClass = wasmGetKClass() + val booleanArrayClass = wasmGetKClass() + val charArrayClass = wasmGetKClass() + val byteArrayClass = wasmGetKClass() + val shortArrayClass = wasmGetKClass() + val intArrayClass = wasmGetKClass() + val longArrayClass = wasmGetKClass() + val floatArrayClass = wasmGetKClass() + val doubleArrayClass = wasmGetKClass() + + fun functionClass(arity: Int): KClassImpl { + //TODO FunctionN + return (if (arity == 0) wasmGetKClass>() else ErrorKClass) as KClassImpl + } +} \ No newline at end of file diff --git a/libraries/stdlib/wasm/src/kotlin/reflect/reflection.kt b/libraries/stdlib/wasm/src/kotlin/reflect/reflection.kt new file mode 100644 index 00000000000..144bc0d4aa7 --- /dev/null +++ b/libraries/stdlib/wasm/src/kotlin/reflect/reflection.kt @@ -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 getKClass(typeInfoData: TypeInfoData): KClass { +// return if (js("Array").isArray(jClass)) { +// getKClassM(jClass.unsafeCast>>()) +// } else { +// getKClass1(jClass.unsafeCast>()) +// } + + return getKClass1(typeInfoData) +} + +internal fun getKClassM(jClasses: Array): KClass = when (jClasses.size) { + 1 -> getKClass1(jClasses[0]) + 0 -> NothingKClassImpl as KClass + else -> ErrorKClass as KClass +} + +internal fun getKClassFromExpression(e: T): KClass = + 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 + +internal fun getKClass1(infoData: TypeInfoData): KClass { + return KClassImpl(infoData) +} + +@Suppress("REIFIED_TYPE_PARAMETER_NO_INLINE") +internal inline fun wasmGetKClass(): KClass = + KClassImpl(wasmGetTypeInfoData())