[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.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 <T> 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<SimpleFunctionDescriptor> =
|
||||
fun findFunctions(memberScope: MemberScope, name: Name): List<SimpleFunctionDescriptor> =
|
||||
memberScope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND).toList()
|
||||
|
||||
interface InlineClassesUtils {
|
||||
|
||||
@@ -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)))
|
||||
}
|
||||
}
|
||||
+4
-14
@@ -68,6 +68,7 @@ class JsIrBackendContext(
|
||||
val extractedLocalClasses: MutableSet<IrClass> = 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<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 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.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<IrProperty>()
|
||||
}
|
||||
|
||||
private val primitiveClassFunctionClass by lazy {
|
||||
primitiveClassesObject.owner.declarations
|
||||
.filterIsInstance<IrSimpleFunction>()
|
||||
.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<IrSimpleFunction>().single { it.name == Name.special("<get-$name>") }
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -71,7 +71,7 @@ fun IrDeclaration.hasStaticDispatch() = when (this) {
|
||||
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)
|
||||
|
||||
return IrCallImpl(
|
||||
|
||||
Reference in New Issue
Block a user