[JS IR BE] move intrinsic for Object.create calls to JsIntrinsics
This commit is contained in:
@@ -5,27 +5,73 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.backend.js
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.js.resolve.JsPlatform.builtIns
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinTypeFactory
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
class JsIntrinsics(private val module: ModuleDescriptor, private val irBuiltIns: IrBuiltIns, symbolTable: SymbolTable) {
|
||||
|
||||
private val stubBuilder = DeclarationStubGenerator(symbolTable, JsLoweredDeclarationOrigin.JS_INTRINSICS_STUB)
|
||||
|
||||
class JsIntrinsics(irBuiltIns: IrBuiltIns) {
|
||||
// Equality
|
||||
val jsEqeq = irBuiltIns.binOpBool("jsEqeq")
|
||||
val jsNotEq = irBuiltIns.binOpBool("jsNotEq")
|
||||
val jsEqeqeq = irBuiltIns.binOpBool("jsEqeqeq")
|
||||
val jsNotEqeq = irBuiltIns.binOpBool("jsNotEqeq")
|
||||
val jsEqeq = binOpBool("jsEqeq")
|
||||
val jsNotEq = binOpBool("jsNotEq")
|
||||
val jsEqeqeq = binOpBool("jsEqeqeq")
|
||||
val jsNotEqeq = binOpBool("jsNotEqeq")
|
||||
|
||||
// Unary operations
|
||||
val jsNot = irBuiltIns.unOpBool("jsNot")
|
||||
val jsNot = unOpBool("jsNot")
|
||||
|
||||
// Binary operations
|
||||
val jsPlus = irBuiltIns.binOp("jsPlus")
|
||||
val jsMinus = irBuiltIns.binOp("jsMinus")
|
||||
val jsMult = irBuiltIns.binOp("jsMult")
|
||||
val jsDiv = irBuiltIns.binOp("jsDiv")
|
||||
val jsMod = irBuiltIns.binOp("jsMod")
|
||||
}
|
||||
val jsPlus = binOp("jsPlus")
|
||||
val jsMinus = binOp("jsMinus")
|
||||
val jsMult = binOp("jsMult")
|
||||
val jsDiv = binOp("jsDiv")
|
||||
val jsMod = binOp("jsMod")
|
||||
|
||||
private fun IrBuiltIns.unOpBool(name: String) = defineOperator(name, bool, listOf(anyN, anyN))
|
||||
private fun IrBuiltIns.binOpBool(name: String) = defineOperator(name, bool, listOf(anyN, anyN))
|
||||
private fun IrBuiltIns.unOp(name: String) = defineOperator(name, anyN, listOf(anyN, anyN))
|
||||
private fun IrBuiltIns.binOp(name: String) = defineOperator(name, anyN, listOf(anyN, anyN))
|
||||
val jsObjectCreate: IrSimpleFunction = defineObjectCreateIntrinsic()
|
||||
|
||||
// Helpers:
|
||||
|
||||
// TODO: unify how we create intrinsic symbols
|
||||
private fun defineObjectCreateIntrinsic(): IrSimpleFunction {
|
||||
|
||||
val typeParam = TypeParameterDescriptorImpl.createWithDefaultBound(
|
||||
builtIns.any,
|
||||
Annotations.EMPTY,
|
||||
true,
|
||||
Variance.INVARIANT,
|
||||
Name.identifier("T"),
|
||||
0
|
||||
)
|
||||
|
||||
val returnType = KotlinTypeFactory.simpleType(Annotations.EMPTY, typeParam.typeConstructor, emptyList(), false)
|
||||
|
||||
val desc = SimpleFunctionDescriptorImpl.create(
|
||||
module,
|
||||
Annotations.EMPTY,
|
||||
Name.identifier("Object\$create"),
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
SourceElement.NO_SOURCE
|
||||
).apply {
|
||||
initialize(null, null, listOf(typeParam), emptyList(), returnType, Modality.FINAL, Visibilities.PUBLIC)
|
||||
isInline = true
|
||||
}
|
||||
|
||||
return stubBuilder.generateFunctionStub(desc)
|
||||
}
|
||||
|
||||
private fun unOpBool(name: String) = irBuiltIns.run { defineOperator(name, bool, listOf(anyN, anyN)) }
|
||||
private fun binOpBool(name: String) = irBuiltIns.run { defineOperator(name, bool, listOf(anyN, anyN)) }
|
||||
private fun unOp(name: String) = irBuiltIns.run { defineOperator(name, anyN, listOf(anyN, anyN)) }
|
||||
private fun binOp(name: String) = irBuiltIns.run { defineOperator(name, anyN, listOf(anyN, anyN)) }
|
||||
}
|
||||
|
||||
+4
-40
@@ -9,27 +9,22 @@ import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.ReflectionTypes
|
||||
import org.jetbrains.kotlin.backend.common.ir.Ir
|
||||
import org.jetbrains.kotlin.backend.common.ir.Symbols
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.types.KotlinTypeFactory
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
class JsIrBackendContext(
|
||||
val module: ModuleDescriptor,
|
||||
@@ -38,7 +33,7 @@ class JsIrBackendContext(
|
||||
symbolTable: SymbolTable
|
||||
) : CommonBackendContext {
|
||||
|
||||
val intrinsics = JsIntrinsics(irBuiltIns)
|
||||
val intrinsics = JsIntrinsics(module, irBuiltIns, symbolTable)
|
||||
|
||||
override val builtIns = module.builtIns
|
||||
override val sharedVariablesManager = JsSharedVariablesManager(builtIns)
|
||||
@@ -97,37 +92,6 @@ class JsIrBackendContext(
|
||||
|
||||
val secondaryConstructorsMap = mutableMapOf<IrConstructorSymbol, SecondaryCtorPair>()
|
||||
|
||||
private val stubBuilder = DeclarationStubGenerator(symbolTable, JsLoweredDeclarationOrigin.JS_INTRINSICS_STUB)
|
||||
|
||||
val objectCreate: IrSimpleFunction = defineObjectCreateIntrinsic()
|
||||
|
||||
private fun defineObjectCreateIntrinsic(): IrSimpleFunction {
|
||||
|
||||
val typeParam = TypeParameterDescriptorImpl.createWithDefaultBound(
|
||||
builtIns.any,
|
||||
Annotations.EMPTY,
|
||||
true,
|
||||
Variance.INVARIANT,
|
||||
Name.identifier("T"),
|
||||
0
|
||||
)
|
||||
|
||||
val returnType = KotlinTypeFactory.simpleType(Annotations.EMPTY, typeParam.typeConstructor, emptyList(), false)
|
||||
|
||||
val desc = SimpleFunctionDescriptorImpl.create(
|
||||
module,
|
||||
Annotations.EMPTY,
|
||||
Name.identifier("Object\$create"),
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
SourceElement.NO_SOURCE
|
||||
).apply {
|
||||
initialize(null, null, listOf(typeParam), emptyList(), returnType, Modality.FINAL, Visibilities.PUBLIC)
|
||||
isInline = true
|
||||
}
|
||||
|
||||
return stubBuilder.generateFunctionStub(desc)
|
||||
}
|
||||
|
||||
private fun find(memberScope: MemberScope, className: String): ClassDescriptor {
|
||||
return find(memberScope, Name.identifier(className))
|
||||
}
|
||||
|
||||
+1
-1
@@ -232,7 +232,7 @@ class SecondaryCtorLowering(val context: JsIrBackendContext) : IrElementTransfor
|
||||
ctorOrig.origin, functionSymbol
|
||||
)
|
||||
|
||||
val createFunctionIntrinsic = context.objectCreate
|
||||
val createFunctionIntrinsic = context.intrinsics.jsObjectCreate
|
||||
val irBuilder = context.createIrBuilder(functionSymbol, ctorOrig.startOffset, ctorOrig.endOffset).irBlockBody {
|
||||
val thisVar = irTemporaryVar(
|
||||
IrCallImpl(
|
||||
|
||||
-8
@@ -83,14 +83,6 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
|
||||
}
|
||||
|
||||
override fun visitCall(expression: IrCall, context: JsGenerationContext): JsExpression {
|
||||
if (expression.symbol == context.staticContext.backendContext.objectCreate.symbol) {
|
||||
// TODO: temporary workaround until there is no an intrinsic infrastructure
|
||||
assert(expression.typeArgumentsCount == 1 && expression.valueArgumentsCount == 0)
|
||||
val classToCreate = expression.getTypeArgument(0)!!
|
||||
val prototype = prototypeOf(classToCreate.constructor.declarationDescriptor!!.name.toJsName().makeRef())
|
||||
return JsInvocation(Namer.JS_OBJECT_CREATE_FUNCTION, prototype)
|
||||
}
|
||||
|
||||
val symbol = expression.symbol
|
||||
|
||||
val dispatchReceiver = expression.dispatchReceiver?.accept(this, context)
|
||||
|
||||
+12
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
|
||||
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIntrinsics
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.Namer
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
@@ -32,12 +33,23 @@ class JsIntrinsicTransformers(intrinsics: JsIntrinsics) {
|
||||
binOp(intrinsics.jsMult, JsBinaryOperator.MUL)
|
||||
binOp(intrinsics.jsDiv, JsBinaryOperator.DIV)
|
||||
binOp(intrinsics.jsMod, JsBinaryOperator.MOD)
|
||||
|
||||
add(intrinsics.jsObjectCreate) { call, _ ->
|
||||
val classToCreate = call.getTypeArgument(0)!!
|
||||
val prototype = prototypeOf(classToCreate.constructor.declarationDescriptor!!.name.toJsName().makeRef())
|
||||
JsInvocation(Namer.JS_OBJECT_CREATE_FUNCTION, prototype)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
operator fun get(symbol: IrSymbol): IrCallTransformer? = transformers[symbol]
|
||||
}
|
||||
|
||||
private fun MutableMap<IrSymbol, IrCallTransformer>.add(function: IrFunction, t: IrCallTransformer) {
|
||||
put(function.symbol, t)
|
||||
}
|
||||
|
||||
private fun MutableMap<IrSymbol, IrCallTransformer>.binOp(function: IrFunction, op: JsBinaryOperator) {
|
||||
put(function.symbol, { _, args -> JsBinaryOperation(op, args[0], args[1]) })
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user