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 ac47c283a76..154dc5f5d97 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 @@ -65,6 +65,12 @@ class JsIntrinsics( val jsDiv = binOp("jsDiv") 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 jsOr = binOp("jsOr") diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/IntrinsicifyCallsLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/IntrinsicifyCallsLowering.kt index 70bb41239ff..688a1ff201e 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/IntrinsicifyCallsLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/IntrinsicifyCallsLowering.kt @@ -41,11 +41,13 @@ class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileL private val memberToTransformer: MemberToTransformer private val symbolToTransformer: SymbolToTransformer private val nameToTransformer: Map IrExpression> + private val dynamicCallOriginToIrFunction: Map init { symbolToTransformer = mutableMapOf() memberToTransformer = mutableMapOf() nameToTransformer = mutableMapOf() + dynamicCallOriginToIrFunction = mutableMapOf() 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) } + + 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) { @@ -261,7 +300,7 @@ class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileL if (call is IrCall) { val symbol = call.symbol - if (symbol.isEffectivelyExternal()) { + if (symbol.isDynamic() || symbol.isEffectivelyExternal()) { when (call.origin) { IrStatementOrigin.GET_PROPERTY -> { 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 { return it(call) } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIntrinsicTransformers.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIntrinsicTransformers.kt index d6fae12ea3a..e7b50bcd416 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIntrinsicTransformers.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIntrinsicTransformers.kt @@ -53,6 +53,12 @@ class JsIntrinsicTransformers(backendContext: JsIrBackendContext) { binOp(intrinsics.jsDiv, JsBinaryOperator.DIV) 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.jsBitOr, JsBinaryOperator.BIT_OR) binOp(intrinsics.jsBitXor, JsBinaryOperator.BIT_XOR) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/SimpleNameGenerator.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/SimpleNameGenerator.kt index 4eadec8a0ca..7ab2aed9fb7 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/SimpleNameGenerator.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/SimpleNameGenerator.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.js.backend.ast.JsName import org.jetbrains.kotlin.js.naming.isES5IdentifierPart 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.isEffectivelyExternal import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver @@ -31,6 +32,10 @@ class SimpleNameGenerator : NameGenerator { nameCache.getOrPut(descriptor) { var nameDeclarator: (String) -> JsName = context.currentScope::declareName + if (descriptor.isDynamic()) { + return@getOrPut nameDeclarator(descriptor.name.asString()) + } + if (descriptor is MemberDescriptor && descriptor.isEffectivelyExternal()) { val descriptorForName = when (descriptor) { is ConstructorDescriptor -> descriptor.constructedClass diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/descriptorBasedUtils.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/descriptorBasedUtils.kt index 709937d0879..c46efe166d6 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/descriptorBasedUtils.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/descriptorBasedUtils.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.ir.declarations.IrTypeParameter import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol 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.types.KotlinType @@ -53,3 +54,5 @@ fun CallableMemberDescriptor.isFakeOverriddenFromAny(): Boolean { fun IrDeclaration.isEffectivelyExternal() = descriptor.isEffectivelyExternal() fun IrSymbol.isEffectivelyExternal() = descriptor.isEffectivelyExternal() + +fun IrSymbol.isDynamic() = descriptor.isDynamic() diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicIrBoxTest.kt b/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicIrBoxTest.kt index d969a79899e..47b21d386ef 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicIrBoxTest.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicIrBoxTest.kt @@ -20,8 +20,17 @@ import java.io.File private val runtimeSources = listOfKtFilesFrom( "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/Comparable.kt", + "core/builtins/src/kotlin/Annotations.kt", "core/builtins/src/kotlin/internal/InternalAnnotations.kt", "core/builtins/src/kotlin/internal/progressionUtil.kt", "core/builtins/src/kotlin/Iterators.kt", @@ -32,6 +41,7 @@ private val runtimeSources = listOfKtFilesFrom( "core/builtins/src/kotlin/Unit.kt", "core/builtins/native/kotlin/Collections.kt", "core/builtins/native/kotlin/Iterator.kt", + "libraries/stdlib/js/irRuntime", BasicBoxTest.COMMON_FILES_DIR_PATH ) diff --git a/libraries/stdlib/js/irRuntime/annotations.kt b/libraries/stdlib/js/irRuntime/annotations.kt deleted file mode 100644 index 7fedf93f688..00000000000 --- a/libraries/stdlib/js/irRuntime/annotations.kt +++ /dev/null @@ -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 \ No newline at end of file diff --git a/libraries/stdlib/js/irRuntime/internalAnnotations.kt b/libraries/stdlib/js/irRuntime/internalAnnotations.kt deleted file mode 100644 index 48688d47fc7..00000000000 --- a/libraries/stdlib/js/irRuntime/internalAnnotations.kt +++ /dev/null @@ -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 \ No newline at end of file diff --git a/libraries/stdlib/js/irRuntime/typeCheckUtils.kt b/libraries/stdlib/js/irRuntime/typeCheckUtils.kt index f857ab662f8..d1ac6d70099 100644 --- a/libraries/stdlib/js/irRuntime/typeCheckUtils.kt +++ b/libraries/stdlib/js/irRuntime/typeCheckUtils.kt @@ -5,9 +5,6 @@ package kotlin.js -@kotlin.internal.DynamicExtension -public inline fun dynamic.unsafeCast(): T = this - private fun isInterfaceImpl(ctor: dynamic, iface: dynamic): Boolean { if (ctor === iface) return true;