[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
|
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.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
|
// Equality
|
||||||
val jsEqeq = irBuiltIns.binOpBool("jsEqeq")
|
val jsEqeq = binOpBool("jsEqeq")
|
||||||
val jsNotEq = irBuiltIns.binOpBool("jsNotEq")
|
val jsNotEq = binOpBool("jsNotEq")
|
||||||
val jsEqeqeq = irBuiltIns.binOpBool("jsEqeqeq")
|
val jsEqeqeq = binOpBool("jsEqeqeq")
|
||||||
val jsNotEqeq = irBuiltIns.binOpBool("jsNotEqeq")
|
val jsNotEqeq = binOpBool("jsNotEqeq")
|
||||||
|
|
||||||
// Unary operations
|
// Unary operations
|
||||||
val jsNot = irBuiltIns.unOpBool("jsNot")
|
val jsNot = unOpBool("jsNot")
|
||||||
|
|
||||||
// Binary operations
|
// Binary operations
|
||||||
val jsPlus = irBuiltIns.binOp("jsPlus")
|
val jsPlus = binOp("jsPlus")
|
||||||
val jsMinus = irBuiltIns.binOp("jsMinus")
|
val jsMinus = binOp("jsMinus")
|
||||||
val jsMult = irBuiltIns.binOp("jsMult")
|
val jsMult = binOp("jsMult")
|
||||||
val jsDiv = irBuiltIns.binOp("jsDiv")
|
val jsDiv = binOp("jsDiv")
|
||||||
val jsMod = irBuiltIns.binOp("jsMod")
|
val jsMod = binOp("jsMod")
|
||||||
}
|
|
||||||
|
|
||||||
private fun IrBuiltIns.unOpBool(name: String) = defineOperator(name, bool, listOf(anyN, anyN))
|
val jsObjectCreate: IrSimpleFunction = defineObjectCreateIntrinsic()
|
||||||
private fun IrBuiltIns.binOpBool(name: String) = defineOperator(name, bool, listOf(anyN, anyN))
|
|
||||||
private fun IrBuiltIns.unOp(name: String) = defineOperator(name, anyN, listOf(anyN, anyN))
|
// Helpers:
|
||||||
private fun IrBuiltIns.binOp(name: String) = defineOperator(name, anyN, listOf(anyN, anyN))
|
|
||||||
|
// 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.ReflectionTypes
|
||||||
import org.jetbrains.kotlin.backend.common.ir.Ir
|
import org.jetbrains.kotlin.backend.common.ir.Ir
|
||||||
import org.jetbrains.kotlin.backend.common.ir.Symbols
|
import org.jetbrains.kotlin.backend.common.ir.Symbols
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl
|
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
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.descriptors.IrBuiltIns
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
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.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
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||||
import org.jetbrains.kotlin.types.KotlinTypeFactory
|
|
||||||
import org.jetbrains.kotlin.types.Variance
|
|
||||||
|
|
||||||
class JsIrBackendContext(
|
class JsIrBackendContext(
|
||||||
val module: ModuleDescriptor,
|
val module: ModuleDescriptor,
|
||||||
@@ -38,7 +33,7 @@ class JsIrBackendContext(
|
|||||||
symbolTable: SymbolTable
|
symbolTable: SymbolTable
|
||||||
) : CommonBackendContext {
|
) : CommonBackendContext {
|
||||||
|
|
||||||
val intrinsics = JsIntrinsics(irBuiltIns)
|
val intrinsics = JsIntrinsics(module, irBuiltIns, symbolTable)
|
||||||
|
|
||||||
override val builtIns = module.builtIns
|
override val builtIns = module.builtIns
|
||||||
override val sharedVariablesManager = JsSharedVariablesManager(builtIns)
|
override val sharedVariablesManager = JsSharedVariablesManager(builtIns)
|
||||||
@@ -97,37 +92,6 @@ class JsIrBackendContext(
|
|||||||
|
|
||||||
val secondaryConstructorsMap = mutableMapOf<IrConstructorSymbol, SecondaryCtorPair>()
|
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 {
|
private fun find(memberScope: MemberScope, className: String): ClassDescriptor {
|
||||||
return find(memberScope, Name.identifier(className))
|
return find(memberScope, Name.identifier(className))
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -232,7 +232,7 @@ class SecondaryCtorLowering(val context: JsIrBackendContext) : IrElementTransfor
|
|||||||
ctorOrig.origin, functionSymbol
|
ctorOrig.origin, functionSymbol
|
||||||
)
|
)
|
||||||
|
|
||||||
val createFunctionIntrinsic = context.objectCreate
|
val createFunctionIntrinsic = context.intrinsics.jsObjectCreate
|
||||||
val irBuilder = context.createIrBuilder(functionSymbol, ctorOrig.startOffset, ctorOrig.endOffset).irBlockBody {
|
val irBuilder = context.createIrBuilder(functionSymbol, ctorOrig.startOffset, ctorOrig.endOffset).irBlockBody {
|
||||||
val thisVar = irTemporaryVar(
|
val thisVar = irTemporaryVar(
|
||||||
IrCallImpl(
|
IrCallImpl(
|
||||||
|
|||||||
-8
@@ -83,14 +83,6 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitCall(expression: IrCall, context: JsGenerationContext): JsExpression {
|
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 symbol = expression.symbol
|
||||||
|
|
||||||
val dispatchReceiver = expression.dispatchReceiver?.accept(this, context)
|
val dispatchReceiver = expression.dispatchReceiver?.accept(this, context)
|
||||||
|
|||||||
+12
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
|
package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
|
||||||
|
|
||||||
import org.jetbrains.kotlin.ir.backend.js.JsIntrinsics
|
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.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
@@ -32,12 +33,23 @@ class JsIntrinsicTransformers(intrinsics: JsIntrinsics) {
|
|||||||
binOp(intrinsics.jsMult, JsBinaryOperator.MUL)
|
binOp(intrinsics.jsMult, JsBinaryOperator.MUL)
|
||||||
binOp(intrinsics.jsDiv, JsBinaryOperator.DIV)
|
binOp(intrinsics.jsDiv, JsBinaryOperator.DIV)
|
||||||
binOp(intrinsics.jsMod, JsBinaryOperator.MOD)
|
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]
|
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) {
|
private fun MutableMap<IrSymbol, IrCallTransformer>.binOp(function: IrFunction, op: JsBinaryOperator) {
|
||||||
put(function.symbol, { _, args -> JsBinaryOperation(op, args[0], args[1]) })
|
put(function.symbol, { _, args -> JsBinaryOperation(op, args[0], args[1]) })
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user