[JS IR BE] Support calls, property accesses and most of operators on expressions with dynamic type
This commit is contained in:
@@ -65,6 +65,12 @@ class JsIntrinsics(
|
|||||||
val jsDiv = binOp("jsDiv")
|
val jsDiv = binOp("jsDiv")
|
||||||
val jsMod = binOp("jsMod")
|
val jsMod = binOp("jsMod")
|
||||||
|
|
||||||
|
val jsPlusAssign = binOp("jsPlusAssign")
|
||||||
|
val jsMinusAssign = binOp("jsMinusAssign")
|
||||||
|
val jsMultAssign = binOp("jsMultAssign")
|
||||||
|
val jsDivAssign = binOp("jsDivAssign")
|
||||||
|
val jsModAssign = binOp("jsModAssign")
|
||||||
|
|
||||||
val jsAnd = binOp("jsAnd")
|
val jsAnd = binOp("jsAnd")
|
||||||
val jsOr = binOp("jsOr")
|
val jsOr = binOp("jsOr")
|
||||||
|
|
||||||
|
|||||||
+46
-1
@@ -41,11 +41,13 @@ class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileL
|
|||||||
private val memberToTransformer: MemberToTransformer
|
private val memberToTransformer: MemberToTransformer
|
||||||
private val symbolToTransformer: SymbolToTransformer
|
private val symbolToTransformer: SymbolToTransformer
|
||||||
private val nameToTransformer: Map<Name, (IrCall) -> IrExpression>
|
private val nameToTransformer: Map<Name, (IrCall) -> IrExpression>
|
||||||
|
private val dynamicCallOriginToIrFunction: Map<IrStatementOrigin, IrSimpleFunction>
|
||||||
|
|
||||||
init {
|
init {
|
||||||
symbolToTransformer = mutableMapOf()
|
symbolToTransformer = mutableMapOf()
|
||||||
memberToTransformer = mutableMapOf()
|
memberToTransformer = mutableMapOf()
|
||||||
nameToTransformer = mutableMapOf()
|
nameToTransformer = mutableMapOf()
|
||||||
|
dynamicCallOriginToIrFunction = mutableMapOf()
|
||||||
|
|
||||||
val primitiveNumbers = context.irBuiltIns.run { listOf(intType, shortType, byteType, floatType, doubleType) }
|
val primitiveNumbers = context.irBuiltIns.run { listOf(intType, shortType, byteType, floatType, doubleType) }
|
||||||
|
|
||||||
@@ -222,6 +224,43 @@ class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileL
|
|||||||
|
|
||||||
put(Name.identifier("equals"), ::transformEqualsMethodCall)
|
put(Name.identifier("equals"), ::transformEqualsMethodCall)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dynamicCallOriginToIrFunction.run {
|
||||||
|
put(IrStatementOrigin.EXCL, context.intrinsics.jsNot)
|
||||||
|
|
||||||
|
put(IrStatementOrigin.LT, context.intrinsics.jsLt)
|
||||||
|
put(IrStatementOrigin.GT, context.intrinsics.jsGt)
|
||||||
|
put(IrStatementOrigin.LTEQ, context.intrinsics.jsLtEq)
|
||||||
|
put(IrStatementOrigin.GTEQ, context.intrinsics.jsGtEq)
|
||||||
|
|
||||||
|
put(IrStatementOrigin.EQEQ, context.intrinsics.jsEqeq)
|
||||||
|
put(IrStatementOrigin.EQEQEQ, context.intrinsics.jsEqeqeq)
|
||||||
|
put(IrStatementOrigin.EXCLEQ, context.intrinsics.jsNotEq)
|
||||||
|
put(IrStatementOrigin.EXCLEQEQ, context.intrinsics.jsNotEqeq)
|
||||||
|
|
||||||
|
put(IrStatementOrigin.ANDAND, context.intrinsics.jsAnd)
|
||||||
|
put(IrStatementOrigin.OROR, context.intrinsics.jsOr)
|
||||||
|
|
||||||
|
put(IrStatementOrigin.UMINUS, context.intrinsics.jsUnaryMinus)
|
||||||
|
put(IrStatementOrigin.UPLUS, context.intrinsics.jsUnaryPlus)
|
||||||
|
|
||||||
|
put(IrStatementOrigin.PLUS, context.intrinsics.jsPlus)
|
||||||
|
put(IrStatementOrigin.MINUS, context.intrinsics.jsMinus)
|
||||||
|
put(IrStatementOrigin.MUL, context.intrinsics.jsMult)
|
||||||
|
put(IrStatementOrigin.DIV, context.intrinsics.jsDiv)
|
||||||
|
put(IrStatementOrigin.PERC, context.intrinsics.jsMod)
|
||||||
|
|
||||||
|
put(IrStatementOrigin.PLUSEQ, context.intrinsics.jsPlusAssign)
|
||||||
|
put(IrStatementOrigin.MINUSEQ, context.intrinsics.jsMinusAssign)
|
||||||
|
put(IrStatementOrigin.MULTEQ, context.intrinsics.jsMultAssign)
|
||||||
|
put(IrStatementOrigin.DIVEQ, context.intrinsics.jsDivAssign)
|
||||||
|
put(IrStatementOrigin.PERCEQ, context.intrinsics.jsModAssign)
|
||||||
|
|
||||||
|
put(IrStatementOrigin.PREFIX_INCR, context.intrinsics.jsPrefixInc)
|
||||||
|
put(IrStatementOrigin.PREFIX_DECR, context.intrinsics.jsPrefixDec)
|
||||||
|
put(IrStatementOrigin.POSTFIX_INCR, context.intrinsics.jsPostfixInc)
|
||||||
|
put(IrStatementOrigin.POSTFIX_DECR, context.intrinsics.jsPostfixDec)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun lower(irFile: IrFile) {
|
override fun lower(irFile: IrFile) {
|
||||||
@@ -261,7 +300,7 @@ class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileL
|
|||||||
if (call is IrCall) {
|
if (call is IrCall) {
|
||||||
val symbol = call.symbol
|
val symbol = call.symbol
|
||||||
|
|
||||||
if (symbol.isEffectivelyExternal()) {
|
if (symbol.isDynamic() || symbol.isEffectivelyExternal()) {
|
||||||
when (call.origin) {
|
when (call.origin) {
|
||||||
IrStatementOrigin.GET_PROPERTY -> {
|
IrStatementOrigin.GET_PROPERTY -> {
|
||||||
val fieldSymbol = IrFieldSymbolImpl((symbol.descriptor as PropertyAccessorDescriptor).correspondingProperty)
|
val fieldSymbol = IrFieldSymbolImpl((symbol.descriptor as PropertyAccessorDescriptor).correspondingProperty)
|
||||||
@@ -277,6 +316,12 @@ class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileL
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (symbol.isDynamic()) {
|
||||||
|
dynamicCallOriginToIrFunction[call.origin]?.let {
|
||||||
|
return irCall(call, it.symbol, dispatchReceiverAsFirstArgument = true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
symbolToTransformer[symbol]?.let {
|
symbolToTransformer[symbol]?.let {
|
||||||
return it(call)
|
return it(call)
|
||||||
}
|
}
|
||||||
|
|||||||
+6
@@ -53,6 +53,12 @@ class JsIntrinsicTransformers(backendContext: JsIrBackendContext) {
|
|||||||
binOp(intrinsics.jsDiv, JsBinaryOperator.DIV)
|
binOp(intrinsics.jsDiv, JsBinaryOperator.DIV)
|
||||||
binOp(intrinsics.jsMod, JsBinaryOperator.MOD)
|
binOp(intrinsics.jsMod, JsBinaryOperator.MOD)
|
||||||
|
|
||||||
|
binOp(intrinsics.jsPlusAssign, JsBinaryOperator.ASG_ADD)
|
||||||
|
binOp(intrinsics.jsMinusAssign, JsBinaryOperator.ASG_SUB)
|
||||||
|
binOp(intrinsics.jsMultAssign, JsBinaryOperator.ASG_MUL)
|
||||||
|
binOp(intrinsics.jsDivAssign, JsBinaryOperator.ASG_DIV)
|
||||||
|
binOp(intrinsics.jsModAssign, JsBinaryOperator.ASG_MOD)
|
||||||
|
|
||||||
binOp(intrinsics.jsBitAnd, JsBinaryOperator.BIT_AND)
|
binOp(intrinsics.jsBitAnd, JsBinaryOperator.BIT_AND)
|
||||||
binOp(intrinsics.jsBitOr, JsBinaryOperator.BIT_OR)
|
binOp(intrinsics.jsBitOr, JsBinaryOperator.BIT_OR)
|
||||||
binOp(intrinsics.jsBitXor, JsBinaryOperator.BIT_XOR)
|
binOp(intrinsics.jsBitXor, JsBinaryOperator.BIT_XOR)
|
||||||
|
|||||||
+5
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
|||||||
import org.jetbrains.kotlin.js.backend.ast.JsName
|
import org.jetbrains.kotlin.js.backend.ast.JsName
|
||||||
import org.jetbrains.kotlin.js.naming.isES5IdentifierPart
|
import org.jetbrains.kotlin.js.naming.isES5IdentifierPart
|
||||||
import org.jetbrains.kotlin.js.naming.isES5IdentifierStart
|
import org.jetbrains.kotlin.js.naming.isES5IdentifierStart
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
|
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver
|
||||||
@@ -31,6 +32,10 @@ class SimpleNameGenerator : NameGenerator {
|
|||||||
nameCache.getOrPut(descriptor) {
|
nameCache.getOrPut(descriptor) {
|
||||||
var nameDeclarator: (String) -> JsName = context.currentScope::declareName
|
var nameDeclarator: (String) -> JsName = context.currentScope::declareName
|
||||||
|
|
||||||
|
if (descriptor.isDynamic()) {
|
||||||
|
return@getOrPut nameDeclarator(descriptor.name.asString())
|
||||||
|
}
|
||||||
|
|
||||||
if (descriptor is MemberDescriptor && descriptor.isEffectivelyExternal()) {
|
if (descriptor is MemberDescriptor && descriptor.isEffectivelyExternal()) {
|
||||||
val descriptorForName = when (descriptor) {
|
val descriptorForName = when (descriptor) {
|
||||||
is ConstructorDescriptor -> descriptor.constructedClass
|
is ConstructorDescriptor -> descriptor.constructedClass
|
||||||
|
|||||||
+3
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
|
|||||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
|
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
@@ -53,3 +54,5 @@ fun CallableMemberDescriptor.isFakeOverriddenFromAny(): Boolean {
|
|||||||
fun IrDeclaration.isEffectivelyExternal() = descriptor.isEffectivelyExternal()
|
fun IrDeclaration.isEffectivelyExternal() = descriptor.isEffectivelyExternal()
|
||||||
|
|
||||||
fun IrSymbol.isEffectivelyExternal() = descriptor.isEffectivelyExternal()
|
fun IrSymbol.isEffectivelyExternal() = descriptor.isEffectivelyExternal()
|
||||||
|
|
||||||
|
fun IrSymbol.isDynamic() = descriptor.isDynamic()
|
||||||
|
|||||||
@@ -20,8 +20,17 @@ import java.io.File
|
|||||||
|
|
||||||
private val runtimeSources = listOfKtFilesFrom(
|
private val runtimeSources = listOfKtFilesFrom(
|
||||||
"libraries/stdlib/js/src/kotlin/core.kt",
|
"libraries/stdlib/js/src/kotlin/core.kt",
|
||||||
|
"libraries/stdlib/js/src/kotlin/js.core.kt",
|
||||||
|
"libraries/stdlib/js/src/kotlin/jsTypeOf.kt",
|
||||||
|
"libraries/stdlib/js/src/kotlin/dynamic.kt",
|
||||||
|
"libraries/stdlib/js/src/kotlin/annotations.kt",
|
||||||
|
|
||||||
|
"libraries/stdlib/src/kotlin/internal/Annotations.kt",
|
||||||
|
|
||||||
|
"core/builtins/native/kotlin/Annotation.kt",
|
||||||
"core/builtins/native/kotlin/Number.kt",
|
"core/builtins/native/kotlin/Number.kt",
|
||||||
"core/builtins/native/kotlin/Comparable.kt",
|
"core/builtins/native/kotlin/Comparable.kt",
|
||||||
|
"core/builtins/src/kotlin/Annotations.kt",
|
||||||
"core/builtins/src/kotlin/internal/InternalAnnotations.kt",
|
"core/builtins/src/kotlin/internal/InternalAnnotations.kt",
|
||||||
"core/builtins/src/kotlin/internal/progressionUtil.kt",
|
"core/builtins/src/kotlin/internal/progressionUtil.kt",
|
||||||
"core/builtins/src/kotlin/Iterators.kt",
|
"core/builtins/src/kotlin/Iterators.kt",
|
||||||
@@ -32,6 +41,7 @@ private val runtimeSources = listOfKtFilesFrom(
|
|||||||
"core/builtins/src/kotlin/Unit.kt",
|
"core/builtins/src/kotlin/Unit.kt",
|
||||||
"core/builtins/native/kotlin/Collections.kt",
|
"core/builtins/native/kotlin/Collections.kt",
|
||||||
"core/builtins/native/kotlin/Iterator.kt",
|
"core/builtins/native/kotlin/Iterator.kt",
|
||||||
|
|
||||||
"libraries/stdlib/js/irRuntime",
|
"libraries/stdlib/js/irRuntime",
|
||||||
BasicBoxTest.COMMON_FILES_DIR_PATH
|
BasicBoxTest.COMMON_FILES_DIR_PATH
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 JetBrains s.r.o. 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
|
|
||||||
|
|
||||||
interface Annotation
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 JetBrains s.r.o. 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.internal
|
|
||||||
|
|
||||||
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY)
|
|
||||||
@Retention(AnnotationRetention.BINARY)
|
|
||||||
internal annotation class DynamicExtension
|
|
||||||
@@ -5,9 +5,6 @@
|
|||||||
|
|
||||||
package kotlin.js
|
package kotlin.js
|
||||||
|
|
||||||
@kotlin.internal.DynamicExtension
|
|
||||||
public inline fun <T> dynamic.unsafeCast(): T = this
|
|
||||||
|
|
||||||
private fun isInterfaceImpl(ctor: dynamic, iface: dynamic): Boolean {
|
private fun isInterfaceImpl(ctor: dynamic, iface: dynamic): Boolean {
|
||||||
if (ctor === iface) return true;
|
if (ctor === iface) return true;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user