JS IR: Long
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 592fc5b..2d7deb9 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
@@ -14,7 +14,9 @@
 import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
 import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
 import org.jetbrains.kotlin.js.resolve.JsPlatform.builtIns
+import org.jetbrains.kotlin.name.FqName
 import org.jetbrains.kotlin.name.Name
+import org.jetbrains.kotlin.psi2ir.findSingleFunction
 import org.jetbrains.kotlin.types.KotlinType
 import org.jetbrains.kotlin.types.KotlinTypeFactory
 import org.jetbrains.kotlin.types.Variance
@@ -96,8 +98,10 @@
     val jsNumberToDouble = getInternalFunction("numberToDouble")
     val jsNumberToInt = getInternalFunction("numberToInt")
     val jsNumberToShort = getInternalFunction("numberToShort")
+    val jsNumberToLong = getInternalFunction("numberToLong")
     val jsToByte = getInternalFunction("toByte")
     val jsToShort = getInternalFunction("toShort")
+    val jsToLong = getInternalFunction("toLong")
 
 
     // Other:
@@ -112,6 +116,9 @@
     val jsEquals = getInternalFunction("equals")
 
 
+    val longConstructor= context.symbolTable.referenceConstructor(context.getClass(FqName("kotlin.Long")).constructors.single())
+    val longToDouble= context.symbolTable.referenceSimpleFunction(context.getClass(FqName("kotlin.Long")).unsubstitutedMemberScope.findSingleFunction(Name.identifier("toDouble")))
+    val longToFloat= context.symbolTable.referenceSimpleFunction(context.getClass(FqName("kotlin.Long")).unsubstitutedMemberScope.findSingleFunction(Name.identifier("toFloat")))
 
     // Helpers:
 
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 e206d69..9316950 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
@@ -17,9 +17,7 @@
 import org.jetbrains.kotlin.ir.declarations.IrFile
 import org.jetbrains.kotlin.ir.declarations.IrFunction
 import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
-import org.jetbrains.kotlin.ir.expressions.IrCall
-import org.jetbrains.kotlin.ir.expressions.IrExpression
-import org.jetbrains.kotlin.ir.expressions.copyTypeArgumentsFrom
+import org.jetbrains.kotlin.ir.expressions.*
 import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
 import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
 import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
@@ -83,7 +81,7 @@
             }
 
             // Conversion rules are ported from NumberAndCharConversionFIF
-            // TODO: Add Char, Long and Number conversions
+            // TODO: Add Char and Number conversions
 
             irBuiltIns.byteType.let {
                 op(it, ConversionNames.TO_BYTE, intrinsics.jsAsIs)
@@ -91,6 +89,7 @@
                 op(it, ConversionNames.TO_FLOAT, intrinsics.jsAsIs)
                 op(it, ConversionNames.TO_INT, intrinsics.jsAsIs)
                 op(it, ConversionNames.TO_SHORT, intrinsics.jsAsIs)
+                op(it, ConversionNames.TO_LONG, intrinsics.jsToLong)
             }
 
             for (type in listOf(irBuiltIns.floatType, irBuiltIns.doubleType)) {
@@ -99,6 +98,7 @@
                 op(type, ConversionNames.TO_FLOAT, intrinsics.jsAsIs)
                 op(type, ConversionNames.TO_INT, intrinsics.jsNumberToInt)
                 op(type, ConversionNames.TO_SHORT, intrinsics.jsNumberToShort)
+                op(type, ConversionNames.TO_LONG, intrinsics.jsNumberToLong)
             }
 
             irBuiltIns.intType.let {
@@ -107,6 +107,7 @@
                 op(it, ConversionNames.TO_FLOAT, intrinsics.jsAsIs)
                 op(it, ConversionNames.TO_INT, intrinsics.jsAsIs)
                 op(it, ConversionNames.TO_SHORT, intrinsics.jsToShort)
+                op(it, ConversionNames.TO_LONG, intrinsics.jsToLong)
             }
 
             irBuiltIns.shortType.let {
@@ -115,13 +116,14 @@
                 op(it, ConversionNames.TO_FLOAT, intrinsics.jsAsIs)
                 op(it, ConversionNames.TO_INT, intrinsics.jsAsIs)
                 op(it, ConversionNames.TO_SHORT, intrinsics.jsAsIs)
+                op(it, ConversionNames.TO_LONG, intrinsics.jsToLong)
             }
         }
 
         symbolToIrFunction.run {
             add(irBuiltIns.eqeqeqSymbol, intrinsics.jsEqeqeq)
             // TODO: implement it a right way
-            add(irBuiltIns.eqeqSymbol, intrinsics.jsEqeq)
+            add(irBuiltIns.eqeqSymbol, intrinsics.jsEquals.owner)
             // TODO: implement it a right way
             add(irBuiltIns.ieee754equalsFunByOperandType, intrinsics.jsEqeqeq)
 
@@ -189,12 +191,40 @@
 
     override fun lower(irFile: IrFile) {
         irFile.transform(object : IrElementTransformerVoid() {
+            override fun <T> visitConst(expression: IrConst<T>): IrExpression {
+                if (expression.kind is IrConstKind.Long) {
+                    val value = IrConstKind.Long.valueOf(expression)
+                    val high = (value shr 32).toInt()
+                    val low = value.toInt()
+                    return IrCallImpl(
+                        expression.startOffset,
+                        expression.endOffset,
+                        context.intrinsics.longConstructor
+                    ).apply {
+                        putValueArgument(0, JsIrBuilder.buildInt(context.irBuiltIns.int, low))
+                        putValueArgument(1, JsIrBuilder.buildInt(context.irBuiltIns.int, high))
+                    }
+                }
+                return super.visitConst(expression)
+            }
+
             override fun visitCall(expression: IrCall): IrExpression {
                 val call = super.visitCall(expression)
 
                 if (call is IrCall) {
                     val symbol = call.symbol
 
+                    if (symbol == irBuiltIns.eqeqSymbol) {
+                        val lhs = call.getValueArgument(0)!!
+                        val rhs = call.getValueArgument(1)!!
+
+                        return when (translateEquals(lhs.type, rhs.type)) {
+                            is IdentityOperator -> irCall(call, intrinsics.jsEqeqeq.symbol)
+                            is EqualityOperator -> irCall(call, intrinsics.jsEqeq.symbol)
+                            else -> irCall(call, intrinsics.jsEquals)
+                        }
+                    }
+
                     symbolToIrFunction[symbol]?.let {
                         return irCall(call, it.symbol)
                     }
@@ -210,6 +240,43 @@
                                     return call.dispatchReceiver!!
                                 }
                                 // TODO: don't apply intrinsics when type of receiver or argument is Long
+                                if (call.valueArgumentsCount == 1) {
+                                    call.getValueArgument(0)?.let { arg ->
+                                        if (arg.type.isLong()) {
+                                            call.dispatchReceiver?.type?.let {
+                                                if (it.isDouble()) {
+                                                    call.putValueArgument(0, IrCallImpl(
+                                                        call.startOffset,
+                                                        call.endOffset,
+                                                        context.intrinsics.longToDouble
+                                                    ).apply {
+                                                        dispatchReceiver = arg
+                                                    })
+                                                } else if (it.isFloat()) {
+                                                    call.putValueArgument(0, IrCallImpl(
+                                                        call.startOffset,
+                                                        call.endOffset,
+                                                        context.intrinsics.longToFloat
+                                                    ).apply {
+                                                        dispatchReceiver = arg
+                                                    })
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+
+
+                                if (call.valueArgumentsCount == 1 && call.getValueArgument(0)!!.type.isLong()) {
+                                    call.dispatchReceiver = IrCallImpl(
+                                        call.startOffset,
+                                        call.endOffset,
+                                        intrinsics.jsNumberToLong
+                                    ).apply {
+                                        putValueArgument(0, call.dispatchReceiver)
+                                    }
+                                    return call
+                                }
                                 return irCall(call, it, dispatchReceiverAsFirstArgument = true)
                             }
 
@@ -309,6 +376,7 @@
 class RuntimeOrMethodCall : EqualityLoweringType()
 
 fun translateEquals(lhs: IrType, rhs: IrType): EqualityLoweringType = when {
+    lhs.isNullableNothing() || lhs.isDynamic() -> EqualityOperator()
     lhs.isJsNumber() -> translateEqualsForJsNumber(rhs)
     lhs.isNullableJsNumber() -> translateEqualsForNullableJsNumber(rhs)
     lhs.isLong() -> translateEqualsForLong(rhs)
@@ -434,7 +502,11 @@
     put(from, to)
 }
 
-private fun <K> MutableMap<K, (IrCall) -> IrExpression>.addWithPredicate(from: K, predicate: (IrCall) -> Boolean, action: (IrCall) -> IrExpression) {
+private fun <K> MutableMap<K, (IrCall) -> IrExpression>.addWithPredicate(
+    from: K,
+    predicate: (IrCall) -> Boolean,
+    action: (IrCall) -> IrExpression
+) {
     put(from) { call: IrCall -> select({ predicate(call) }, { action(call) }, { call }) }
 }
 
diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsExpressionTransformer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsExpressionTransformer.kt
index a1e27e9..dbf9566 100644
--- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsExpressionTransformer.kt
+++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsExpressionTransformer.kt
@@ -82,8 +82,8 @@
             is IrConstKind.Byte -> JsIntLiteral(kind.valueOf(expression).toInt())
             is IrConstKind.Short -> JsIntLiteral(kind.valueOf(expression).toInt())
             is IrConstKind.Int -> JsIntLiteral(kind.valueOf(expression))
-            is IrConstKind.Long,
-            is IrConstKind.Char -> super.visitConst(expression, context)
+            is IrConstKind.Long -> TODO("Long const")
+            is IrConstKind.Char -> TODO("Char const")
             is IrConstKind.Float -> JsDoubleLiteral(kind.valueOf(expression).toDouble())
             is IrConstKind.Double -> JsDoubleLiteral(kind.valueOf(expression))
         }
diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/OperatorNames.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/OperatorNames.kt
index 7248a0c..a17e103 100644
--- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/OperatorNames.kt
+++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/OperatorNames.kt
@@ -26,7 +26,7 @@
 
     val SHL = Name.identifier("shl")
     val SHR = Name.identifier("shr")
-    val SHRU = Name.identifier("shru")
+    val SHRU = Name.identifier("ushr")
 
     val NOT = OperatorNameConventions.NOT
 
diff --git a/compiler/testData/codegen/box/argumentOrder/captured.kt b/compiler/testData/codegen/box/argumentOrder/captured.kt
index c5e1d0b..0dfb6b5 100644
--- a/compiler/testData/codegen/box/argumentOrder/captured.kt
+++ b/compiler/testData/codegen/box/argumentOrder/captured.kt
@@ -1,5 +1,4 @@
 // IGNORE_BACKEND: JVM_IR
-// IGNORE_BACKEND: JS_IR
 fun box(): String {
     var invokeOrder = "";
     val expectedResult = "0_1_9"
diff --git a/compiler/testData/codegen/box/argumentOrder/capturedInExtension.kt b/compiler/testData/codegen/box/argumentOrder/capturedInExtension.kt
index 642a70f..ce31df7 100644
--- a/compiler/testData/codegen/box/argumentOrder/capturedInExtension.kt
+++ b/compiler/testData/codegen/box/argumentOrder/capturedInExtension.kt
@@ -1,5 +1,4 @@
 // IGNORE_BACKEND: JVM_IR
-// IGNORE_BACKEND: JS_IR
 fun box(): String {
     var invokeOrder = "";
     val expectedResult = "1_0_1_9"
diff --git a/compiler/testData/codegen/box/argumentOrder/extension.kt b/compiler/testData/codegen/box/argumentOrder/extension.kt
index 454da92..c38a817 100644
--- a/compiler/testData/codegen/box/argumentOrder/extension.kt
+++ b/compiler/testData/codegen/box/argumentOrder/extension.kt
@@ -1,5 +1,4 @@
 // IGNORE_BACKEND: JVM_IR
-// IGNORE_BACKEND: JS_IR
 fun box(): String {
     var invokeOrder = "";
     val expectedResult = "1_0_1_L"
diff --git a/compiler/testData/codegen/box/argumentOrder/extensionInClass.kt b/compiler/testData/codegen/box/argumentOrder/extensionInClass.kt
index 25397bc..ba4ec46 100644
--- a/compiler/testData/codegen/box/argumentOrder/extensionInClass.kt
+++ b/compiler/testData/codegen/box/argumentOrder/extensionInClass.kt
@@ -1,5 +1,4 @@
 // IGNORE_BACKEND: JVM_IR
-// IGNORE_BACKEND: JS_IR
 fun box(): String {
     return Z().test()
 }
diff --git a/compiler/testData/codegen/box/boxingOptimization/boxedPrimitivesAreEqual.kt b/compiler/testData/codegen/box/boxingOptimization/boxedPrimitivesAreEqual.kt
index 3f6d867..2bd8eda 100644
--- a/compiler/testData/codegen/box/boxingOptimization/boxedPrimitivesAreEqual.kt
+++ b/compiler/testData/codegen/box/boxingOptimization/boxedPrimitivesAreEqual.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 inline fun eq(a: Any, b: Any) = a == b
 inline fun ne(a: Any, b: Any) = a != b
 
diff --git a/compiler/testData/codegen/box/callableReference/property/simpleMutableTopLevel.kt b/compiler/testData/codegen/box/callableReference/property/simpleMutableTopLevel.kt
index bd180e2..25d5147 100644
--- a/compiler/testData/codegen/box/callableReference/property/simpleMutableTopLevel.kt
+++ b/compiler/testData/codegen/box/callableReference/property/simpleMutableTopLevel.kt
@@ -1,5 +1,4 @@
 // IGNORE_BACKEND: JVM_IR
-// IGNORE_BACKEND: JS_IR
 data class Box(val value: String)
 
 var pr = Box("first")
diff --git a/compiler/testData/codegen/box/callableReference/property/simpleTopLevel.kt b/compiler/testData/codegen/box/callableReference/property/simpleTopLevel.kt
index 6c1f378..a2ef382 100644
--- a/compiler/testData/codegen/box/callableReference/property/simpleTopLevel.kt
+++ b/compiler/testData/codegen/box/callableReference/property/simpleTopLevel.kt
@@ -1,5 +1,4 @@
 // IGNORE_BACKEND: JVM_IR
-// IGNORE_BACKEND: JS_IR
 data class Box(val value: String)
 
 val foo = Box("lol")
diff --git a/compiler/testData/codegen/box/casts/isNullablePrimitive.kt b/compiler/testData/codegen/box/casts/isNullablePrimitive.kt
index f8baca9..f2b407c 100644
--- a/compiler/testData/codegen/box/casts/isNullablePrimitive.kt
+++ b/compiler/testData/codegen/box/casts/isNullablePrimitive.kt
@@ -1,5 +1,4 @@
 // IGNORE_BACKEND: JVM_IR
-// IGNORE_BACKEND: JS_IR
 fun box(): String {
     val n: Any? = null
 
diff --git a/compiler/testData/codegen/box/casts/literalExpressionAsGenericArgument/parenthesizedExpressionCast.kt b/compiler/testData/codegen/box/casts/literalExpressionAsGenericArgument/parenthesizedExpressionCast.kt
index 361c7db..a70372d 100644
--- a/compiler/testData/codegen/box/casts/literalExpressionAsGenericArgument/parenthesizedExpressionCast.kt
+++ b/compiler/testData/codegen/box/casts/literalExpressionAsGenericArgument/parenthesizedExpressionCast.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 class Box<T>(val value: T)
 
 fun box() : String {
diff --git a/compiler/testData/codegen/box/casts/literalExpressionAsGenericArgument/superConstructor.kt b/compiler/testData/codegen/box/casts/literalExpressionAsGenericArgument/superConstructor.kt
index b5a83ff..f896fd0 100644
--- a/compiler/testData/codegen/box/casts/literalExpressionAsGenericArgument/superConstructor.kt
+++ b/compiler/testData/codegen/box/casts/literalExpressionAsGenericArgument/superConstructor.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 open class Base<T>(val value: T)
 class Box(): Base<Long>(-1)
 
diff --git a/compiler/testData/codegen/box/casts/literalExpressionAsGenericArgument/unaryExpressionCast.kt b/compiler/testData/codegen/box/casts/literalExpressionAsGenericArgument/unaryExpressionCast.kt
index 9729307..6f253b6 100644
--- a/compiler/testData/codegen/box/casts/literalExpressionAsGenericArgument/unaryExpressionCast.kt
+++ b/compiler/testData/codegen/box/casts/literalExpressionAsGenericArgument/unaryExpressionCast.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 class Box<T>(val value: T)
 
 fun box() : String {
diff --git a/compiler/testData/codegen/box/classes/kt6816.kt b/compiler/testData/codegen/box/classes/kt6816.kt
index bc587e5..ed081c6 100644
--- a/compiler/testData/codegen/box/classes/kt6816.kt
+++ b/compiler/testData/codegen/box/classes/kt6816.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 public class CalculatorConstants(
         val id: Long = 0,
         val detour: Double = 0.0,
diff --git a/compiler/testData/codegen/box/closures/capturedVarsOptimization/kt17200.kt b/compiler/testData/codegen/box/closures/capturedVarsOptimization/kt17200.kt
index f503a34..0d223fc 100644
--- a/compiler/testData/codegen/box/closures/capturedVarsOptimization/kt17200.kt
+++ b/compiler/testData/codegen/box/closures/capturedVarsOptimization/kt17200.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 inline fun inlineCall(action: () -> Unit) {
     action()
 }
diff --git a/compiler/testData/codegen/box/compatibility/dataClassEqualsHashCodeToString.kt b/compiler/testData/codegen/box/compatibility/dataClassEqualsHashCodeToString.kt
index 0ee17ba..d95ddb8 100644
--- a/compiler/testData/codegen/box/compatibility/dataClassEqualsHashCodeToString.kt
+++ b/compiler/testData/codegen/box/compatibility/dataClassEqualsHashCodeToString.kt
@@ -1,5 +1,4 @@
 // IGNORE_BACKEND: JVM_IR
-// IGNORE_BACKEND: JS_IR
 // LANGUAGE_VERSION: 1.0
 
 data class Foo(val s: String)
diff --git a/compiler/testData/codegen/box/constants/long.kt b/compiler/testData/codegen/box/constants/long.kt
index 62b962d..7fa2eaf 100644
--- a/compiler/testData/codegen/box/constants/long.kt
+++ b/compiler/testData/codegen/box/constants/long.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 fun box(): String {
     if (1L != 1.toLong()) return "fail 1"
     if (0x1L != 0x1.toLong()) return "fail 2"
diff --git a/compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/popSizes.kt b/compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/popSizes.kt
index 97af15a..8c736e5 100644
--- a/compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/popSizes.kt
+++ b/compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/popSizes.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 fun foo(x: Long, y: Int, z: Double, s: String) {}
 
 fun box(): String {
diff --git a/compiler/testData/codegen/box/controlStructures/kt1441.kt b/compiler/testData/codegen/box/controlStructures/kt1441.kt
index 27c70f6..7e50990 100644
--- a/compiler/testData/codegen/box/controlStructures/kt1441.kt
+++ b/compiler/testData/codegen/box/controlStructures/kt1441.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 class Foo {
   var rnd = 10
 
diff --git a/compiler/testData/codegen/box/controlStructures/kt17590_long.kt b/compiler/testData/codegen/box/controlStructures/kt17590_long.kt
index 8cd7e1b..521c7fd 100644
--- a/compiler/testData/codegen/box/controlStructures/kt17590_long.kt
+++ b/compiler/testData/codegen/box/controlStructures/kt17590_long.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 fun foo(x: Any?, y: Any?) = 0L
 
 inline fun test(value: Any?): Long {
diff --git a/compiler/testData/codegen/box/dataClasses/genericParam.kt b/compiler/testData/codegen/box/dataClasses/genericParam.kt
index aabcb57..5bf58f5 100644
--- a/compiler/testData/codegen/box/dataClasses/genericParam.kt
+++ b/compiler/testData/codegen/box/dataClasses/genericParam.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 data class A<T>(val x: T)
 
 fun box(): String {
diff --git a/compiler/testData/codegen/box/dataClasses/hashCode/long.kt b/compiler/testData/codegen/box/dataClasses/hashCode/long.kt
index d55bdcc..067593c 100644
--- a/compiler/testData/codegen/box/dataClasses/hashCode/long.kt
+++ b/compiler/testData/codegen/box/dataClasses/hashCode/long.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 data class A(val a: Long)
 
 fun box() : String {
diff --git a/compiler/testData/codegen/box/dataClasses/toString/genericParam.kt b/compiler/testData/codegen/box/dataClasses/toString/genericParam.kt
index b238f20..794bad5 100644
--- a/compiler/testData/codegen/box/dataClasses/toString/genericParam.kt
+++ b/compiler/testData/codegen/box/dataClasses/toString/genericParam.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 data class A<T>(val x: T)
 
 fun box(): String {
diff --git a/compiler/testData/codegen/box/defaultArguments/function/mixingNamedAndPositioned.kt b/compiler/testData/codegen/box/defaultArguments/function/mixingNamedAndPositioned.kt
index 443114d..7b3aebe 100644
--- a/compiler/testData/codegen/box/defaultArguments/function/mixingNamedAndPositioned.kt
+++ b/compiler/testData/codegen/box/defaultArguments/function/mixingNamedAndPositioned.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 fun foo(a: String = "Companion", b: Int = 1, c: Long = 2): String {
   return "$a $b $c"
 }
diff --git a/compiler/testData/codegen/box/delegatedProperty/genericSetValueViaSyntheticAccessor.kt b/compiler/testData/codegen/box/delegatedProperty/genericSetValueViaSyntheticAccessor.kt
index 7afae41..f047ec4 100644
--- a/compiler/testData/codegen/box/delegatedProperty/genericSetValueViaSyntheticAccessor.kt
+++ b/compiler/testData/codegen/box/delegatedProperty/genericSetValueViaSyntheticAccessor.kt
@@ -1,5 +1,4 @@
 // IGNORE_BACKEND: JVM_IR
-// IGNORE_BACKEND: JS_IR
 // FILE: Var.kt
 package pvar
 
diff --git a/compiler/testData/codegen/box/elvis/primitive.kt b/compiler/testData/codegen/box/elvis/primitive.kt
index 946ed09..bd3edd1 100644
--- a/compiler/testData/codegen/box/elvis/primitive.kt
+++ b/compiler/testData/codegen/box/elvis/primitive.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 fun box(): String {
     if ((42 ?: 239) != 42) return "Fail Int"
     if ((42.toLong() ?: 239.toLong()) != 42.toLong()) return "Fail Long"
diff --git a/compiler/testData/codegen/box/exclExcl/primitive.kt b/compiler/testData/codegen/box/exclExcl/primitive.kt
index fd4397a..d781575 100644
--- a/compiler/testData/codegen/box/exclExcl/primitive.kt
+++ b/compiler/testData/codegen/box/exclExcl/primitive.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 fun box(): String {
     42!!
     42.toLong()!!
diff --git a/compiler/testData/codegen/box/extensionFunctions/kt5467.kt b/compiler/testData/codegen/box/extensionFunctions/kt5467.kt
index 9cadba8..5d5ab04 100644
--- a/compiler/testData/codegen/box/extensionFunctions/kt5467.kt
+++ b/compiler/testData/codegen/box/extensionFunctions/kt5467.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 fun String.foo() : String {
     fun Int.bar() : String {
         fun Long.baz() : String {
diff --git a/compiler/testData/codegen/box/extensionProperties/inClassLongTypeInReceiver.kt b/compiler/testData/codegen/box/extensionProperties/inClassLongTypeInReceiver.kt
index 401ffb9..f4a3c12 100644
--- a/compiler/testData/codegen/box/extensionProperties/inClassLongTypeInReceiver.kt
+++ b/compiler/testData/codegen/box/extensionProperties/inClassLongTypeInReceiver.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 class Test {
     var doubleStorage = "fail"
     var longStorage = "fail"
diff --git a/compiler/testData/codegen/box/extensionProperties/topLevelLongTypeInReceiver.kt b/compiler/testData/codegen/box/extensionProperties/topLevelLongTypeInReceiver.kt
index 96b266e..b002884 100644
--- a/compiler/testData/codegen/box/extensionProperties/topLevelLongTypeInReceiver.kt
+++ b/compiler/testData/codegen/box/extensionProperties/topLevelLongTypeInReceiver.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 var fooStorage = "Fail"
 var barStorage = "Fail"
 
diff --git a/compiler/testData/codegen/box/functions/defaultargs2.kt b/compiler/testData/codegen/box/functions/defaultargs2.kt
index 2f69654..710cc12 100644
--- a/compiler/testData/codegen/box/functions/defaultargs2.kt
+++ b/compiler/testData/codegen/box/functions/defaultargs2.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 class T4(
   val c1: Boolean,
   val c2: Boolean,
diff --git a/compiler/testData/codegen/box/functions/kt873.kt b/compiler/testData/codegen/box/functions/kt873.kt
index 06f14e0..21c3dcd 100644
--- a/compiler/testData/codegen/box/functions/kt873.kt
+++ b/compiler/testData/codegen/box/functions/kt873.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 fun box() : String {
   val fps  : Double = 1.toDouble()
   var mspf : Long
diff --git a/compiler/testData/codegen/box/ieee754/smartCastToDifferentTypesWithNumericPromotion_properIeeeComparisons.kt b/compiler/testData/codegen/box/ieee754/smartCastToDifferentTypesWithNumericPromotion_properIeeeComparisons.kt
index ff92b37..5f0ad6a 100644
--- a/compiler/testData/codegen/box/ieee754/smartCastToDifferentTypesWithNumericPromotion_properIeeeComparisons.kt
+++ b/compiler/testData/codegen/box/ieee754/smartCastToDifferentTypesWithNumericPromotion_properIeeeComparisons.kt
@@ -1,5 +1,4 @@
 // !LANGUAGE: +ProperIeee754Comparisons
-// IGNORE_BACKEND: JS_IR
 
 fun eqDI(x: Any?, y: Any?) = x is Double?   && y is Int?        && x == y
 fun eqDL(x: Any?, y: Any?) = x is Double?   && y is Long?       && x == y
diff --git a/compiler/testData/codegen/box/ieee754/smartCastToDoubleAndComparableToDouble.kt b/compiler/testData/codegen/box/ieee754/smartCastToDoubleAndComparableToDouble.kt
index 45f641b..f6ad5a1 100644
--- a/compiler/testData/codegen/box/ieee754/smartCastToDoubleAndComparableToDouble.kt
+++ b/compiler/testData/codegen/box/ieee754/smartCastToDoubleAndComparableToDouble.kt
@@ -1,5 +1,4 @@
 // !LANGUAGE: +ProperIeee754Comparisons
-// IGNORE_BACKEND: JS_IR
 
 val minus: Any = -0.0
 
diff --git a/compiler/testData/codegen/box/increment/classWithGetSet.kt b/compiler/testData/codegen/box/increment/classWithGetSet.kt
index 58e07eb..97d2925 100644
--- a/compiler/testData/codegen/box/increment/classWithGetSet.kt
+++ b/compiler/testData/codegen/box/increment/classWithGetSet.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 class AByte(var value: Byte) {
     operator fun get(i: Int) = value
 
diff --git a/compiler/testData/codegen/box/increment/extOnLong.kt b/compiler/testData/codegen/box/increment/extOnLong.kt
index 7550ebf..9dce4e9 100644
--- a/compiler/testData/codegen/box/increment/extOnLong.kt
+++ b/compiler/testData/codegen/box/increment/extOnLong.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 operator fun Long.get(i: Int) = this
 operator fun Long.set(i: Int, newValue: Long) {}
 
diff --git a/compiler/testData/codegen/box/increment/genericClassWithGetSet.kt b/compiler/testData/codegen/box/increment/genericClassWithGetSet.kt
index 16eb662..04825a3 100644
--- a/compiler/testData/codegen/box/increment/genericClassWithGetSet.kt
+++ b/compiler/testData/codegen/box/increment/genericClassWithGetSet.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 class A<T>(var value: T) {
     operator fun get(i: Int) = value
 
diff --git a/compiler/testData/codegen/box/increment/nullable.kt b/compiler/testData/codegen/box/increment/nullable.kt
index c4f8e62..4802b8a 100644
--- a/compiler/testData/codegen/box/increment/nullable.kt
+++ b/compiler/testData/codegen/box/increment/nullable.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 fun box(): String {
     var aByte: Byte? = 0
     var bByte: Byte = 0
diff --git a/compiler/testData/codegen/box/inlineClasses/checkLambdaWithInlineClassesInFunctionalType.kt b/compiler/testData/codegen/box/inlineClasses/checkLambdaWithInlineClassesInFunctionalType.kt
index 6748ef4..73dd0b2 100644
--- a/compiler/testData/codegen/box/inlineClasses/checkLambdaWithInlineClassesInFunctionalType.kt
+++ b/compiler/testData/codegen/box/inlineClasses/checkLambdaWithInlineClassesInFunctionalType.kt
@@ -1,6 +1,5 @@
 // !LANGUAGE: +InlineClasses
 // IGNORE_BACKEND: JVM_IR
-// IGNORE_BACKEND: JS_IR
 
 inline class UInt(val value: Int)
 inline class ULong(val value: Long)
diff --git a/compiler/testData/codegen/box/innerNested/createNestedClass.kt b/compiler/testData/codegen/box/innerNested/createNestedClass.kt
index 405581b..b5cd0e7 100644
--- a/compiler/testData/codegen/box/innerNested/createNestedClass.kt
+++ b/compiler/testData/codegen/box/innerNested/createNestedClass.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 class A {
     class B1
     class B2(val x: Int)
diff --git a/compiler/testData/codegen/box/innerNested/superConstructorCall/deepInnerHierarchy.kt b/compiler/testData/codegen/box/innerNested/superConstructorCall/deepInnerHierarchy.kt
index b8c2345..03c2959 100644
--- a/compiler/testData/codegen/box/innerNested/superConstructorCall/deepInnerHierarchy.kt
+++ b/compiler/testData/codegen/box/innerNested/superConstructorCall/deepInnerHierarchy.kt
@@ -1,5 +1,4 @@
 // IGNORE_BACKEND: JVM_IR
-// IGNORE_BACKEND: JS_IR
 open class A(val s: String) {
     open inner class B(s: String): A(s)
 
diff --git a/compiler/testData/codegen/box/instructions/swap/swapRefToSharedVarLong.kt b/compiler/testData/codegen/box/instructions/swap/swapRefToSharedVarLong.kt
index 668c3a4..7340eb1 100644
--- a/compiler/testData/codegen/box/instructions/swap/swapRefToSharedVarLong.kt
+++ b/compiler/testData/codegen/box/instructions/swap/swapRefToSharedVarLong.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 //KT-3042 Attempt to split long or double on the stack excepion
 
 fun box(): String {
diff --git a/compiler/testData/codegen/box/localClasses/localClassCaptureExtensionReceiver.kt b/compiler/testData/codegen/box/localClasses/localClassCaptureExtensionReceiver.kt
index 7ddc3ec..732a25e 100644
--- a/compiler/testData/codegen/box/localClasses/localClassCaptureExtensionReceiver.kt
+++ b/compiler/testData/codegen/box/localClasses/localClassCaptureExtensionReceiver.kt
@@ -1,5 +1,4 @@
 // IGNORE_BACKEND: JVM_IR
-// IGNORE_BACKEND: JS_IR
 class Outer {
     fun String.id(): String {
         class Local(unused: Long) {
diff --git a/compiler/testData/codegen/box/multiDecl/forRange/explicitRangeToWithDot/long/MultiDeclForComponentExtensions.kt b/compiler/testData/codegen/box/multiDecl/forRange/explicitRangeToWithDot/long/MultiDeclForComponentExtensions.kt
index c8bc4ce..aed0268 100644
--- a/compiler/testData/codegen/box/multiDecl/forRange/explicitRangeToWithDot/long/MultiDeclForComponentExtensions.kt
+++ b/compiler/testData/codegen/box/multiDecl/forRange/explicitRangeToWithDot/long/MultiDeclForComponentExtensions.kt
@@ -1,3 +1,5 @@
+// IGNORE_BACKEND: JS_IR
+
 fun f(l : Long) {
   l.rangeTo(l)
 }
diff --git a/compiler/testData/codegen/box/operatorConventions/compareTo/comparable.kt b/compiler/testData/codegen/box/operatorConventions/compareTo/comparable.kt
index cc88476..957816c 100644
--- a/compiler/testData/codegen/box/operatorConventions/compareTo/comparable.kt
+++ b/compiler/testData/codegen/box/operatorConventions/compareTo/comparable.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 interface A : Comparable<A>
 
 class B(val x: Int) : A {
diff --git a/compiler/testData/codegen/box/operatorConventions/compareTo/longDouble.kt b/compiler/testData/codegen/box/operatorConventions/compareTo/longDouble.kt
index 4130e81..90e43d4 100644
--- a/compiler/testData/codegen/box/operatorConventions/compareTo/longDouble.kt
+++ b/compiler/testData/codegen/box/operatorConventions/compareTo/longDouble.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 fun checkLess(x: Long, y: Double) = when {
     x >= y    -> "Fail $x >= $y"
     !(x < y)  -> "Fail !($x < $y)"
diff --git a/compiler/testData/codegen/box/operatorConventions/compareTo/longInt.kt b/compiler/testData/codegen/box/operatorConventions/compareTo/longInt.kt
index d066c825f..623a3a4 100644
--- a/compiler/testData/codegen/box/operatorConventions/compareTo/longInt.kt
+++ b/compiler/testData/codegen/box/operatorConventions/compareTo/longInt.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 fun checkLess(x: Long, y: Int) = when {
     x >= y    -> "Fail $x >= $y"
     !(x < y)  -> "Fail !($x < $y)"
diff --git a/compiler/testData/codegen/box/operatorConventions/incDecOnObject.kt b/compiler/testData/codegen/box/operatorConventions/incDecOnObject.kt
index 0599819..0717061 100644
--- a/compiler/testData/codegen/box/operatorConventions/incDecOnObject.kt
+++ b/compiler/testData/codegen/box/operatorConventions/incDecOnObject.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 class X(var value: Long)
 
 operator fun X.inc(): X {
diff --git a/compiler/testData/codegen/box/operatorConventions/kt20387.kt b/compiler/testData/codegen/box/operatorConventions/kt20387.kt
index edfaef8..95fcaa7 100644
--- a/compiler/testData/codegen/box/operatorConventions/kt20387.kt
+++ b/compiler/testData/codegen/box/operatorConventions/kt20387.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 // FILE: test.kt
 import base.*
 
diff --git a/compiler/testData/codegen/box/package/boxPrimitiveTypeInClinit.kt b/compiler/testData/codegen/box/package/boxPrimitiveTypeInClinit.kt
index 128e66d..8b8377d 100644
--- a/compiler/testData/codegen/box/package/boxPrimitiveTypeInClinit.kt
+++ b/compiler/testData/codegen/box/package/boxPrimitiveTypeInClinit.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 var xi = 0
 var xin : Int? = 0
 var xinn : Int? = null
diff --git a/compiler/testData/codegen/box/package/checkCast.kt b/compiler/testData/codegen/box/package/checkCast.kt
index c522a1c..ffdfa30 100644
--- a/compiler/testData/codegen/box/package/checkCast.kt
+++ b/compiler/testData/codegen/box/package/checkCast.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 class C(val x: Int) {
   override fun equals(rhs: Any?): Boolean {
     if (rhs is C) {
diff --git a/compiler/testData/codegen/box/primitiveTypes/equalityWithObject/boxedLongEqualsLong.kt b/compiler/testData/codegen/box/primitiveTypes/equalityWithObject/boxedLongEqualsLong.kt
index ff26c9abd..9f589c7 100644
--- a/compiler/testData/codegen/box/primitiveTypes/equalityWithObject/boxedLongEqualsLong.kt
+++ b/compiler/testData/codegen/box/primitiveTypes/equalityWithObject/boxedLongEqualsLong.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 val x: Long = 0L
 
 fun box(): String {
diff --git a/compiler/testData/codegen/box/primitiveTypes/equalityWithObject/generated/boxedEqPrimitiveLong.kt b/compiler/testData/codegen/box/primitiveTypes/equalityWithObject/generated/boxedEqPrimitiveLong.kt
index 629a22f..57253df 100644
--- a/compiler/testData/codegen/box/primitiveTypes/equalityWithObject/generated/boxedEqPrimitiveLong.kt
+++ b/compiler/testData/codegen/box/primitiveTypes/equalityWithObject/generated/boxedEqPrimitiveLong.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 // Auto-generated by GeneratePrimitiveVsObjectEqualityTestData. Do not edit!
 
 val nx: Long? = 0L
diff --git a/compiler/testData/codegen/box/primitiveTypes/equalityWithObject/generated/primitiveEqBoxedLong.kt b/compiler/testData/codegen/box/primitiveTypes/equalityWithObject/generated/primitiveEqBoxedLong.kt
index 3def092..e2eccb0 100644
--- a/compiler/testData/codegen/box/primitiveTypes/equalityWithObject/generated/primitiveEqBoxedLong.kt
+++ b/compiler/testData/codegen/box/primitiveTypes/equalityWithObject/generated/primitiveEqBoxedLong.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 // Auto-generated by GeneratePrimitiveVsObjectEqualityTestData. Do not edit!
 
 val nx: Long? = 0L
diff --git a/compiler/testData/codegen/box/primitiveTypes/equalityWithObject/generated/primitiveEqObjectLong.kt b/compiler/testData/codegen/box/primitiveTypes/equalityWithObject/generated/primitiveEqObjectLong.kt
index 1d4e0d8..ddfdcad 100644
--- a/compiler/testData/codegen/box/primitiveTypes/equalityWithObject/generated/primitiveEqObjectLong.kt
+++ b/compiler/testData/codegen/box/primitiveTypes/equalityWithObject/generated/primitiveEqObjectLong.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 // Auto-generated by GeneratePrimitiveVsObjectEqualityTestData. Do not edit!
 
 val nx: Any? = 0L
diff --git a/compiler/testData/codegen/box/primitiveTypes/equalityWithObject/objectWithAsymmetricEqualsEqPrimitive.kt b/compiler/testData/codegen/box/primitiveTypes/equalityWithObject/objectWithAsymmetricEqualsEqPrimitive.kt
index f9e2ca5..c042662 100644
--- a/compiler/testData/codegen/box/primitiveTypes/equalityWithObject/objectWithAsymmetricEqualsEqPrimitive.kt
+++ b/compiler/testData/codegen/box/primitiveTypes/equalityWithObject/objectWithAsymmetricEqualsEqPrimitive.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 // Strictly speaking, asymmetric equals violates contract for 'Object#equals'.
 // However, we don't rely on this contract so far.
 class FakeInt(val value: Int) {
diff --git a/compiler/testData/codegen/box/primitiveTypes/equalityWithObject/whenNullableBoxed.kt b/compiler/testData/codegen/box/primitiveTypes/equalityWithObject/whenNullableBoxed.kt
index b358a56..ff03f15 100644
--- a/compiler/testData/codegen/box/primitiveTypes/equalityWithObject/whenNullableBoxed.kt
+++ b/compiler/testData/codegen/box/primitiveTypes/equalityWithObject/whenNullableBoxed.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 class CInt(val value: Int)
 val nCInt3: CInt? = CInt(3)
 
diff --git a/compiler/testData/codegen/box/primitiveTypes/kt6590_identityEquals.kt b/compiler/testData/codegen/box/primitiveTypes/kt6590_identityEquals.kt
index f5e6e56..f21a8f1 100644
--- a/compiler/testData/codegen/box/primitiveTypes/kt6590_identityEquals.kt
+++ b/compiler/testData/codegen/box/primitiveTypes/kt6590_identityEquals.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 fun box(): String {
     val i: Int = 10000
     if (!(i === i)) return "Fail int ==="
diff --git a/compiler/testData/codegen/box/primitiveTypes/kt665.kt b/compiler/testData/codegen/box/primitiveTypes/kt665.kt
index b1bbbf9..b8bd69b 100644
--- a/compiler/testData/codegen/box/primitiveTypes/kt665.kt
+++ b/compiler/testData/codegen/box/primitiveTypes/kt665.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 fun f(x: Long, zzz: Long = 1): Long
 {
     return if (x <= 1) zzz
diff --git a/compiler/testData/codegen/box/primitiveTypes/kt887.kt b/compiler/testData/codegen/box/primitiveTypes/kt887.kt
index 52709a1..c03be7c 100644
--- a/compiler/testData/codegen/box/primitiveTypes/kt887.kt
+++ b/compiler/testData/codegen/box/primitiveTypes/kt887.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 class Book(val name: String) : Comparable<Book> {
   override fun compareTo(other: Book) = name.compareTo(other.name)
 }
diff --git a/compiler/testData/codegen/box/properties/kt1165.kt b/compiler/testData/codegen/box/properties/kt1165.kt
index 7aec2c6..0a32a58 100644
--- a/compiler/testData/codegen/box/properties/kt1165.kt
+++ b/compiler/testData/codegen/box/properties/kt1165.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 public abstract class VirtualFile() {
     public abstract val size : Long
 }
diff --git a/compiler/testData/codegen/box/properties/kt613.kt b/compiler/testData/codegen/box/properties/kt613.kt
index 5140bf9..4f55c04 100644
--- a/compiler/testData/codegen/box/properties/kt613.kt
+++ b/compiler/testData/codegen/box/properties/kt613.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 package name
 
 class Test() {
diff --git a/compiler/testData/codegen/box/regressions/kt14447.kt b/compiler/testData/codegen/box/regressions/kt14447.kt
index 195630a..7aab4c5 100644
--- a/compiler/testData/codegen/box/regressions/kt14447.kt
+++ b/compiler/testData/codegen/box/regressions/kt14447.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 class ImpulsMigration
 {
     fun migrate(oldVersion: Long)
diff --git a/compiler/testData/codegen/box/regressions/kt7401.kt b/compiler/testData/codegen/box/regressions/kt7401.kt
index 1f1c879..16294c5 100644
--- a/compiler/testData/codegen/box/regressions/kt7401.kt
+++ b/compiler/testData/codegen/box/regressions/kt7401.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 fun foo(): Long {
     var n = 2L
     if (n > 0L) {
diff --git a/compiler/testData/codegen/box/safeCall/primitive.kt b/compiler/testData/codegen/box/safeCall/primitive.kt
index 2541481..64decc4 100644
--- a/compiler/testData/codegen/box/safeCall/primitive.kt
+++ b/compiler/testData/codegen/box/safeCall/primitive.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 fun Int.foo() = 239
 fun Long.bar() = 239.toLong()
 
diff --git a/compiler/testData/codegen/box/safeCall/safeCallOnLong.kt b/compiler/testData/codegen/box/safeCall/safeCallOnLong.kt
index e3a082ce0..0236f0a 100644
--- a/compiler/testData/codegen/box/safeCall/safeCallOnLong.kt
+++ b/compiler/testData/codegen/box/safeCall/safeCallOnLong.kt
@@ -1,5 +1,4 @@
 // IGNORE_BACKEND: JVM_IR
-// IGNORE_BACKEND: JS_IR
 fun f(b : Long.(Long)->Long) = 1L?.b(2L)
 
 fun box(): String {
diff --git a/compiler/testData/codegen/box/secondaryConstructors/defaultArgs.kt b/compiler/testData/codegen/box/secondaryConstructors/defaultArgs.kt
index 10b0be1..3c9d312 100644
--- a/compiler/testData/codegen/box/secondaryConstructors/defaultArgs.kt
+++ b/compiler/testData/codegen/box/secondaryConstructors/defaultArgs.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 val global = "OK"
 class A {
     val prop: String
diff --git a/compiler/testData/codegen/box/secondaryConstructors/delegateWithComplexExpression.kt b/compiler/testData/codegen/box/secondaryConstructors/delegateWithComplexExpression.kt
index 18b91c5..999d944 100644
--- a/compiler/testData/codegen/box/secondaryConstructors/delegateWithComplexExpression.kt
+++ b/compiler/testData/codegen/box/secondaryConstructors/delegateWithComplexExpression.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 var log = ""
 
 open class Base(val s: String)
diff --git a/compiler/testData/codegen/box/super/superConstructor/kt18356.kt b/compiler/testData/codegen/box/super/superConstructor/kt18356.kt
index 0c0d371..5372f4fa 100644
--- a/compiler/testData/codegen/box/super/superConstructor/kt18356.kt
+++ b/compiler/testData/codegen/box/super/superConstructor/kt18356.kt
@@ -1,5 +1,4 @@
 // IGNORE_BACKEND: JVM_IR
-// IGNORE_BACKEND: JS_IR
 open class Base(val addr: Long, val name: String)
 
 fun box(): String {
diff --git a/compiler/testData/codegen/box/syntheticAccessors/accessorForGenericConstructor.kt b/compiler/testData/codegen/box/syntheticAccessors/accessorForGenericConstructor.kt
index 93dfad2..9a97980 100644
--- a/compiler/testData/codegen/box/syntheticAccessors/accessorForGenericConstructor.kt
+++ b/compiler/testData/codegen/box/syntheticAccessors/accessorForGenericConstructor.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 fun box(): String {
     A.Nested().nestedA()
     A.Nested().Inner().innerA()
diff --git a/compiler/testData/codegen/box/syntheticAccessors/accessorForGenericMethod.kt b/compiler/testData/codegen/box/syntheticAccessors/accessorForGenericMethod.kt
index 9ce1001..a6ef85a 100644
--- a/compiler/testData/codegen/box/syntheticAccessors/accessorForGenericMethod.kt
+++ b/compiler/testData/codegen/box/syntheticAccessors/accessorForGenericMethod.kt
@@ -1,5 +1,4 @@
 // IGNORE_BACKEND: JVM_IR
-// IGNORE_BACKEND: JS_IR
 // FILE: test.kt
 import b.B
 
diff --git a/compiler/testData/codegen/box/syntheticAccessors/accessorForGenericMethodWithDefaults.kt b/compiler/testData/codegen/box/syntheticAccessors/accessorForGenericMethodWithDefaults.kt
index 5391183..a70010d 100644
--- a/compiler/testData/codegen/box/syntheticAccessors/accessorForGenericMethodWithDefaults.kt
+++ b/compiler/testData/codegen/box/syntheticAccessors/accessorForGenericMethodWithDefaults.kt
@@ -1,5 +1,4 @@
 // IGNORE_BACKEND: JVM_IR
-// IGNORE_BACKEND: JS_IR
 // FILE: test.kt
 import b.B
 
diff --git a/compiler/testData/codegen/box/unaryOp/intrinsic.kt b/compiler/testData/codegen/box/unaryOp/intrinsic.kt
index 28cbb08..30bd7d9 100644
--- a/compiler/testData/codegen/box/unaryOp/intrinsic.kt
+++ b/compiler/testData/codegen/box/unaryOp/intrinsic.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 fun box(): String {
     val a1: Byte = -1
     val a2: Short = -1
diff --git a/compiler/testData/codegen/box/unaryOp/intrinsicNullable.kt b/compiler/testData/codegen/box/unaryOp/intrinsicNullable.kt
index f17dc2e..0463bcd 100644
--- a/compiler/testData/codegen/box/unaryOp/intrinsicNullable.kt
+++ b/compiler/testData/codegen/box/unaryOp/intrinsicNullable.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 fun box(): String {
     val a1: Byte? = -1
     val a2: Short? = -1
diff --git a/compiler/testData/codegen/box/when/longInRange.kt b/compiler/testData/codegen/box/when/longInRange.kt
index 2332367..c73169f 100644
--- a/compiler/testData/codegen/box/when/longInRange.kt
+++ b/compiler/testData/codegen/box/when/longInRange.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 class LongR {
   operator fun contains(l : Long): Boolean = l == 5.toLong()
 }
diff --git a/compiler/testData/codegen/boxInline/callableReference/bound/kt18728_4.kt b/compiler/testData/codegen/boxInline/callableReference/bound/kt18728_4.kt
index 02c8cd4..c86c79d 100644
--- a/compiler/testData/codegen/boxInline/callableReference/bound/kt18728_4.kt
+++ b/compiler/testData/codegen/boxInline/callableReference/bound/kt18728_4.kt
@@ -1,5 +1,4 @@
 // IGNORE_BACKEND: JVM_IR
-// IGNORE_BACKEND: JS_IR
 // FILE: 1.kt
 
 package test
diff --git a/compiler/testData/codegen/boxInline/defaultValues/kt14564.kt b/compiler/testData/codegen/boxInline/defaultValues/kt14564.kt
index 22d6d66..5b4b857 100644
--- a/compiler/testData/codegen/boxInline/defaultValues/kt14564.kt
+++ b/compiler/testData/codegen/boxInline/defaultValues/kt14564.kt
@@ -1,5 +1,4 @@
 // IGNORE_BACKEND: JVM_IR
-// IGNORE_BACKEND: JS_IR
 // FILE: 1.kt
 //NO_CHECK_LAMBDA_INLINING
 
diff --git a/compiler/testData/codegen/boxInline/defaultValues/kt14564_2.kt b/compiler/testData/codegen/boxInline/defaultValues/kt14564_2.kt
index c256a13..5f17862 100644
--- a/compiler/testData/codegen/boxInline/defaultValues/kt14564_2.kt
+++ b/compiler/testData/codegen/boxInline/defaultValues/kt14564_2.kt
@@ -1,5 +1,4 @@
 // IGNORE_BACKEND: JVM_IR
-// IGNORE_BACKEND: JS_IR
 // FILE: 1.kt
 
 package test
diff --git a/compiler/testData/codegen/boxInline/defaultValues/kt18689_4.kt b/compiler/testData/codegen/boxInline/defaultValues/kt18689_4.kt
index 8fb797a..a6e93dc 100644
--- a/compiler/testData/codegen/boxInline/defaultValues/kt18689_4.kt
+++ b/compiler/testData/codegen/boxInline/defaultValues/kt18689_4.kt
@@ -1,5 +1,4 @@
 // IGNORE_BACKEND: JVM_IR
-// IGNORE_BACKEND: JS_IR
 // FILE: 1.kt
 
 package test
diff --git a/compiler/testData/codegen/boxInline/defaultValues/kt5685.kt b/compiler/testData/codegen/boxInline/defaultValues/kt5685.kt
index f594db7..af78d70 100644
--- a/compiler/testData/codegen/boxInline/defaultValues/kt5685.kt
+++ b/compiler/testData/codegen/boxInline/defaultValues/kt5685.kt
@@ -1,5 +1,4 @@
 // IGNORE_BACKEND: JVM_IR
-// IGNORE_BACKEND: JS_IR
 // FILE: 1.kt
 
 package test
diff --git a/compiler/testData/codegen/boxInline/defaultValues/lambdaInlining/callableReferences/boundPropertyReferenceOnLong.kt b/compiler/testData/codegen/boxInline/defaultValues/lambdaInlining/callableReferences/boundPropertyReferenceOnLong.kt
index c777a4a..ddbff9c 100644
--- a/compiler/testData/codegen/boxInline/defaultValues/lambdaInlining/callableReferences/boundPropertyReferenceOnLong.kt
+++ b/compiler/testData/codegen/boxInline/defaultValues/lambdaInlining/callableReferences/boundPropertyReferenceOnLong.kt
@@ -1,5 +1,4 @@
 // IGNORE_BACKEND: JVM_IR
-// IGNORE_BACKEND: JS_IR
 // FILE: 1.kt
 // LANGUAGE_VERSION: 1.2
 // SKIP_INLINE_CHECK_IN: inlineFun$default
diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/longReturn.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/longReturn.kt
index 4bf5605..b19bad3cb 100644
--- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/longReturn.kt
+++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/declSite/longReturn.kt
@@ -1,5 +1,4 @@
 // IGNORE_BACKEND: JVM_IR
-// IGNORE_BACKEND: JS_IR
 // FILE: 1.kt
 
 package test
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 950a955..b9c50421 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
@@ -46,13 +46,17 @@
         val runtime = listOf(
             "libraries/stdlib/js/src/kotlin/core.kt",
             "libraries/stdlib/js/irRuntime/core.kt",
+            "libraries/stdlib/js/irRuntime/long.kt",
+            "libraries/stdlib/js/irRuntime/longjs.kt",
             "libraries/stdlib/js/irRuntime/numberConversion.kt",
             "libraries/stdlib/js/irRuntime/compareTo.kt",
             "libraries/stdlib/js/irRuntime/annotations.kt",
             "libraries/stdlib/js/irRuntime/DefaultConstructorMarker.kt",
             "libraries/stdlib/js/irRuntime/exceptions.kt",
             "libraries/stdlib/js/irRuntime/internalAnnotations.kt",
-            "libraries/stdlib/js/irRuntime/typeCheckUtils.kt"
+            "libraries/stdlib/js/irRuntime/typeCheckUtils.kt",
+            "core/builtins/native/kotlin/Number.kt",
+            "core/builtins/native/kotlin/Comparable.kt"
         ).map { createPsiFile(it) }
 
         val filesToIgnore = listOf(
diff --git a/js/js.translator/testData/box/callableReference/property/simpleMutableTopLevel.kt b/js/js.translator/testData/box/callableReference/property/simpleMutableTopLevel.kt
index 86a1171..7652ee7 100644
--- a/js/js.translator/testData/box/callableReference/property/simpleMutableTopLevel.kt
+++ b/js/js.translator/testData/box/callableReference/property/simpleMutableTopLevel.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 // EXPECTED_REACHABLE_NODES: 1121
 // This test was adapted from compiler/testData/codegen/box/callableReference/property/.
 package foo
diff --git a/js/js.translator/testData/box/callableReference/property/simpleTopLevel.kt b/js/js.translator/testData/box/callableReference/property/simpleTopLevel.kt
index 6d9a572..a2a4161 100644
--- a/js/js.translator/testData/box/callableReference/property/simpleTopLevel.kt
+++ b/js/js.translator/testData/box/callableReference/property/simpleTopLevel.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 // EXPECTED_REACHABLE_NODES: 1121
 // This test was adapted from compiler/testData/codegen/box/callableReference/property/.
 package foo
diff --git a/js/js.translator/testData/box/dataClass/equals.kt b/js/js.translator/testData/box/dataClass/equals.kt
index 803e2ed..9871251 100644
--- a/js/js.translator/testData/box/dataClass/equals.kt
+++ b/js/js.translator/testData/box/dataClass/equals.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 // EXPECTED_REACHABLE_NODES: 1144
 package foo
 
diff --git a/js/js.translator/testData/box/dataClass/override.kt b/js/js.translator/testData/box/dataClass/override.kt
index 5a6fc9b..38ce45e 100644
--- a/js/js.translator/testData/box/dataClass/override.kt
+++ b/js/js.translator/testData/box/dataClass/override.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 // EXPECTED_REACHABLE_NODES: 1123
 package foo
 
diff --git a/js/js.translator/testData/box/defaultArguments/constructorCallWithDefArg2.kt b/js/js.translator/testData/box/defaultArguments/constructorCallWithDefArg2.kt
index 77ca4dd..b722e7e 100644
--- a/js/js.translator/testData/box/defaultArguments/constructorCallWithDefArg2.kt
+++ b/js/js.translator/testData/box/defaultArguments/constructorCallWithDefArg2.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 // EXPECTED_REACHABLE_NODES: 1113
 package foo
 
diff --git a/js/js.translator/testData/box/expression/cast/primitiveToClass.kt b/js/js.translator/testData/box/expression/cast/primitiveToClass.kt
index 962105c..6238cfd 100644
--- a/js/js.translator/testData/box/expression/cast/primitiveToClass.kt
+++ b/js/js.translator/testData/box/expression/cast/primitiveToClass.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 // EXPECTED_REACHABLE_NODES: 1118
 package foo
 
diff --git a/js/js.translator/testData/box/expression/equals/customEqualsMethod.kt b/js/js.translator/testData/box/expression/equals/customEqualsMethod.kt
index 589165c..fa4159c 100644
--- a/js/js.translator/testData/box/expression/equals/customEqualsMethod.kt
+++ b/js/js.translator/testData/box/expression/equals/customEqualsMethod.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 // EXPECTED_REACHABLE_NODES: 1113
 package foo
 
diff --git a/js/js.translator/testData/box/expression/equals/customEqualsMethodOnAny.kt b/js/js.translator/testData/box/expression/equals/customEqualsMethodOnAny.kt
index aa1b949..e2ef668 100644
--- a/js/js.translator/testData/box/expression/equals/customEqualsMethodOnAny.kt
+++ b/js/js.translator/testData/box/expression/equals/customEqualsMethodOnAny.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 // EXPECTED_REACHABLE_NODES: 1113
 package foo
 
diff --git a/js/js.translator/testData/box/expression/stringClass/stringNotEqualToNumber.kt b/js/js.translator/testData/box/expression/stringClass/stringNotEqualToNumber.kt
index 6f30713..861551c 100644
--- a/js/js.translator/testData/box/expression/stringClass/stringNotEqualToNumber.kt
+++ b/js/js.translator/testData/box/expression/stringClass/stringNotEqualToNumber.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 // EXPECTED_REACHABLE_NODES: 1108
 package foo
 
diff --git a/js/js.translator/testData/box/inline/inlineMethod.kt b/js/js.translator/testData/box/inline/inlineMethod.kt
index 598360f..169c3d6 100644
--- a/js/js.translator/testData/box/inline/inlineMethod.kt
+++ b/js/js.translator/testData/box/inline/inlineMethod.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 // EXPECTED_REACHABLE_NODES: 1127
 package foo
 
diff --git a/js/js.translator/testData/box/inline/lambdaReassignmentWithCapture.kt b/js/js.translator/testData/box/inline/lambdaReassignmentWithCapture.kt
index 7152233..34c9fd9 100644
--- a/js/js.translator/testData/box/inline/lambdaReassignmentWithCapture.kt
+++ b/js/js.translator/testData/box/inline/lambdaReassignmentWithCapture.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 // EXPECTED_REACHABLE_NODES: 1125
 package foo
 
diff --git a/js/js.translator/testData/box/number/hexadecimalConstant.kt b/js/js.translator/testData/box/number/hexadecimalConstant.kt
index 03b416b..4e9c1dd 100644
--- a/js/js.translator/testData/box/number/hexadecimalConstant.kt
+++ b/js/js.translator/testData/box/number/hexadecimalConstant.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 // EXPECTED_REACHABLE_NODES: 1108
 package foo
 
diff --git a/js/js.translator/testData/box/number/longBitOperations.kt b/js/js.translator/testData/box/number/longBitOperations.kt
index 08e923d..0644b09 100644
--- a/js/js.translator/testData/box/number/longBitOperations.kt
+++ b/js/js.translator/testData/box/number/longBitOperations.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 // EXPECTED_REACHABLE_NODES: 1112
 package foo
 
diff --git a/js/js.translator/testData/box/number/longCompareToIntrinsic.kt b/js/js.translator/testData/box/number/longCompareToIntrinsic.kt
index 81a235f9..351c34a 100644
--- a/js/js.translator/testData/box/number/longCompareToIntrinsic.kt
+++ b/js/js.translator/testData/box/number/longCompareToIntrinsic.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 // EXPECTED_REACHABLE_NODES: 1114
 package foo
 
diff --git a/js/js.translator/testData/box/number/longEqualsIntrinsic.kt b/js/js.translator/testData/box/number/longEqualsIntrinsic.kt
index 5e6aafb..10df9d3 100644
--- a/js/js.translator/testData/box/number/longEqualsIntrinsic.kt
+++ b/js/js.translator/testData/box/number/longEqualsIntrinsic.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 // EXPECTED_REACHABLE_NODES: 1112
 package foo
 
diff --git a/js/js.translator/testData/box/number/longHashCode.kt b/js/js.translator/testData/box/number/longHashCode.kt
index abe8323..8926575 100644
--- a/js/js.translator/testData/box/number/longHashCode.kt
+++ b/js/js.translator/testData/box/number/longHashCode.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 // EXPECTED_REACHABLE_NODES: 1112
 package foo
 
diff --git a/js/js.translator/testData/box/number/longUnaryOperations.kt b/js/js.translator/testData/box/number/longUnaryOperations.kt
index 62976a4..1098dbf 100644
--- a/js/js.translator/testData/box/number/longUnaryOperations.kt
+++ b/js/js.translator/testData/box/number/longUnaryOperations.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JS_IR
 // EXPECTED_REACHABLE_NODES: 1112
 package foo
 
diff --git a/libraries/stdlib/js/irRuntime/core.kt b/libraries/stdlib/js/irRuntime/core.kt
index a899b79..70dff9c 100644
--- a/libraries/stdlib/js/irRuntime/core.kt
+++ b/libraries/stdlib/js/irRuntime/core.kt
@@ -6,17 +6,18 @@
 package kotlin.js
 
 fun equals(obj1: dynamic, obj2: dynamic): Boolean {
-    if (obj1 == null) {
-        return obj2 == null
-    }
 
+    if (obj1 == null) {
+        return obj2 == null;
+    }
     if (obj2 == null) {
-        return false
+        return false;
     }
 
     return js("""
-    if (typeof obj1 === "object" && typeof obj1.equals === "function") {
-        return obj1.equals(obj2);
+
+    if (typeof obj1 === "object" && typeof obj1.equals_Any_ === "function") {
+        return obj1.equals_Any_(obj2);
     }
 
     if (obj1 !== obj1) {
@@ -31,7 +32,7 @@
 }
 
 fun toString(o: dynamic): String = when {
-    o == null -> "null"
+    o === null -> "null"
     isArrayish(o) -> "[...]"
     else -> js("o.toString()").unsafeCast<String>()
 }
diff --git a/libraries/stdlib/js/irRuntime/long.kt b/libraries/stdlib/js/irRuntime/long.kt
new file mode 100644
index 0000000..f8766a4
--- /dev/null
+++ b/libraries/stdlib/js/irRuntime/long.kt
@@ -0,0 +1,253 @@
+/*
+ * 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
+
+/**
+ * Represents a 64-bit signed integer.
+ */
+public class Long internal constructor(
+    internal val low: Int,
+    internal val high: Int
+) : Number(), Comparable<Long> {
+
+    companion object {
+        /**
+         * A constant holding the minimum value an instance of Long can have.
+         */
+        public const val MIN_VALUE: Long = -9223372036854775807L - 1L
+
+        /**
+         * A constant holding the maximum value an instance of Long can have.
+         */
+        public const val MAX_VALUE: Long = 9223372036854775807L
+    }
+
+    /**
+     * Compares this value with the specified value for order.
+     * Returns zero if this value is equal to the specified other value, a negative number if it's less than other,
+     * or a positive number if it's greater than other.
+     */
+    public inline operator fun compareTo(other: Byte): Int = compareTo(other.toLong())
+
+    /**
+     * Compares this value with the specified value for order.
+     * Returns zero if this value is equal to the specified other value, a negative number if it's less than other,
+     * or a positive number if it's greater than other.
+     */
+    public inline operator fun compareTo(other: Short): Int = compareTo(other.toLong())
+
+    /**
+     * Compares this value with the specified value for order.
+     * Returns zero if this value is equal to the specified other value, a negative number if it's less than other,
+     * or a positive number if it's greater than other.
+     */
+    public inline operator fun compareTo(other: Int): Int = compareTo(other.toLong())
+
+    /**
+     * Compares this value with the specified value for order.
+     * Returns zero if this value is equal to the specified other value, a negative number if it's less than other,
+     * or a positive number if it's greater than other.
+     */
+    public override operator fun compareTo(other: Long): Int = compare(other)
+
+    /**
+     * Compares this value with the specified value for order.
+     * Returns zero if this value is equal to the specified other value, a negative number if it's less than other,
+     * or a positive number if it's greater than other.
+     */
+    public inline operator fun compareTo(other: Float): Int = toFloat().compareTo(other)
+
+    /**
+     * Compares this value with the specified value for order.
+     * Returns zero if this value is equal to the specified other value, a negative number if it's less than other,
+     * or a positive number if it's greater than other.
+     */
+    public inline operator fun compareTo(other: Double): Int = toDouble().compareTo(other)
+
+    /** Adds the other value to this value. */
+    public inline operator fun plus(other: Byte): Long = plus(other.toLong())
+
+    /** Adds the other value to this value. */
+    public inline operator fun plus(other: Short): Long = plus(other.toLong())
+
+    /** Adds the other value to this value. */
+    public inline operator fun plus(other: Int): Long = plus(other.toLong())
+
+    /** Adds the other value to this value. */
+    public operator fun plus(other: Long): Long = add(other)
+
+    /** Adds the other value to this value. */
+    public inline operator fun plus(other: Float): Float = toFloat() + other
+
+    /** Adds the other value to this value. */
+    public inline operator fun plus(other: Double): Double = toDouble() + other
+
+    /** Subtracts the other value from this value. */
+    public inline operator fun minus(other: Byte): Long = minus(other.toLong())
+
+    /** Subtracts the other value from this value. */
+    public inline operator fun minus(other: Short): Long = minus(other.toLong())
+
+    /** Subtracts the other value from this value. */
+    public inline operator fun minus(other: Int): Long = minus(other.toLong())
+
+    /** Subtracts the other value from this value. */
+    public operator fun minus(other: Long): Long = subtract(other)
+
+    /** Subtracts the other value from this value. */
+    public inline operator fun minus(other: Float): Float = toFloat() - other
+
+    /** Subtracts the other value from this value. */
+    public inline operator fun minus(other: Double): Double = toDouble() - other
+
+    /** Multiplies this value by the other value. */
+    public inline operator fun times(other: Byte): Long = times(other.toLong())
+
+    /** Multiplies this value by the other value. */
+    public inline operator fun times(other: Short): Long = times(other.toLong())
+
+    /** Multiplies this value by the other value. */
+    public inline operator fun times(other: Int): Long = times(other.toLong())
+
+    /** Multiplies this value by the other value. */
+    public operator fun times(other: Long): Long = multiply(other)
+
+    /** Multiplies this value by the other value. */
+    public inline operator fun times(other: Float): Float = toFloat() * other
+
+    /** Multiplies this value by the other value. */
+    public inline operator fun times(other: Double): Double = toDouble() * other
+
+    /** Divides this value by the other value. */
+    public inline operator fun div(other: Byte): Long = div(other.toLong())
+
+    /** Divides this value by the other value. */
+    public inline operator fun div(other: Short): Long = div(other.toLong())
+
+    /** Divides this value by the other value. */
+    public inline operator fun div(other: Int): Long = div(other.toLong())
+
+    /** Divides this value by the other value. */
+    public operator fun div(other: Long): Long = divide(other)
+
+    /** Divides this value by the other value. */
+    public inline operator fun div(other: Float): Float = toFloat() / other
+
+    /** Divides this value by the other value. */
+    public inline operator fun div(other: Double): Double = toDouble() / other
+
+    /** Calculates the remainder of dividing this value by the other value. */
+    @Deprecated("Use rem(other) instead", ReplaceWith("rem(other)"), DeprecationLevel.WARNING)
+    public inline operator fun mod(other: Byte): Long = rem(other)
+
+    /** Calculates the remainder of dividing this value by the other value. */
+    @Deprecated("Use rem(other) instead", ReplaceWith("rem(other)"), DeprecationLevel.WARNING)
+    public inline operator fun mod(other: Short): Long = rem(other)
+
+    /** Calculates the remainder of dividing this value by the other value. */
+    @Deprecated("Use rem(other) instead", ReplaceWith("rem(other)"), DeprecationLevel.WARNING)
+    public inline operator fun mod(other: Int): Long = rem(other)
+
+    /** Calculates the remainder of dividing this value by the other value. */
+    @Deprecated("Use rem(other) instead", ReplaceWith("rem(other)"), DeprecationLevel.WARNING)
+    public inline operator fun mod(other: Long): Long = rem(other)
+
+    /** Calculates the remainder of dividing this value by the other value. */
+    @Deprecated("Use rem(other) instead", ReplaceWith("rem(other)"), DeprecationLevel.WARNING)
+    public inline operator fun mod(other: Float): Float = rem(other)
+
+    /** Calculates the remainder of dividing this value by the other value. */
+    @Deprecated("Use rem(other) instead", ReplaceWith("rem(other)"), DeprecationLevel.WARNING)
+    public inline operator fun mod(other: Double): Double = rem(other)
+
+    /** Calculates the remainder of dividing this value by the other value. */
+    @SinceKotlin("1.1")
+    public inline operator fun rem(other: Byte): Long = rem(other.toLong())
+
+    /** Calculates the remainder of dividing this value by the other value. */
+    @SinceKotlin("1.1")
+    public inline operator fun rem(other: Short): Long = rem(other.toLong())
+
+    /** Calculates the remainder of dividing this value by the other value. */
+    @SinceKotlin("1.1")
+    public inline operator fun rem(other: Int): Long = rem(other.toLong())
+
+    /** Calculates the remainder of dividing this value by the other value. */
+    @SinceKotlin("1.1")
+    public operator fun rem(other: Long): Long = modulo(other)
+
+    /** Calculates the remainder of dividing this value by the other value. */
+    @SinceKotlin("1.1")
+    public inline operator fun rem(other: Float): Float = toFloat() % other
+
+    /** Calculates the remainder of dividing this value by the other value. */
+    @SinceKotlin("1.1")
+    public inline operator fun rem(other: Double): Double = toDouble() % other
+
+    /** Increments this value. */
+    public operator fun inc(): Long = this + 1L
+
+    /** Decrements this value. */
+    public operator fun dec(): Long = this - 1L
+
+    /** Returns this value. */
+    public inline operator fun unaryPlus(): Long = this
+
+    /** Returns the negative of this value. */
+    public operator fun unaryMinus(): Long = inv() + 1L
+
+/*  TODO
+    /** Creates a range from this value to the specified [other] value. */
+    public operator fun rangeTo(other: Byte): LongRange
+
+    /** Creates a range from this value to the specified [other] value. */
+    public operator fun rangeTo(other: Short): LongRange
+
+    /** Creates a range from this value to the specified [other] value. */
+    public operator fun rangeTo(other: Int): LongRange
+
+    /** Creates a range from this value to the specified [other] value. */
+    public operator fun rangeTo(other: Long): LongRange
+*/
+
+    /** Shifts this value left by the [bitCount] number of bits. */
+    public infix fun shl(bitCount: Int): Long = shiftLeft(bitCount)
+
+    /** Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with copies of the sign bit. */
+    public infix fun shr(bitCount: Int): Long = shiftRight(bitCount)
+
+    /** Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with zeros. */
+    public infix fun ushr(bitCount: Int): Long = shiftRightUnsigned(bitCount)
+
+    /** Performs a bitwise AND operation between the two values. */
+    public infix fun and(other: Long): Long = Long(low and other.low, high and other.high)
+
+    /** Performs a bitwise OR operation between the two values. */
+    public infix fun or(other: Long): Long = Long(low or other.low, high or other.high)
+
+    /** Performs a bitwise XOR operation between the two values. */
+    public infix fun xor(other: Long): Long = Long(low xor other.low, high xor other.high)
+
+    /** Inverts the bits in this value. */
+    public fun inv(): Long = Long(low.inv(), high.inv())
+
+    public override fun toByte(): Byte = low.toByte()
+    public override fun toChar(): Char = low.toChar()
+    public override fun toShort(): Short = low.toShort()
+    public override fun toInt(): Int = low
+    public override fun toLong(): Long = this
+    public override fun toFloat(): Float = toDouble().toFloat()
+    public override fun toDouble(): Double = toNumber()
+
+    // TODO: is it still needed?
+    private fun valueOf() = toDouble()
+
+    override fun equals(other: Any?): Boolean = other is Long && equalsLong(other)
+
+    override fun hashCode(): Int = hashCode(this)
+
+    override fun toString(): String = toString(10)
+}
\ No newline at end of file
diff --git a/libraries/stdlib/js/irRuntime/longjs.kt b/libraries/stdlib/js/irRuntime/longjs.kt
new file mode 100644
index 0000000..684cc31
--- /dev/null
+++ b/libraries/stdlib/js/irRuntime/longjs.kt
@@ -0,0 +1,380 @@
+/*
+ * 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.
+ */
+
+
+// Copyright 2009 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+package kotlin
+
+internal fun Long.toNumber() = high * TWO_PWR_32_DBL_ + getLowBitsUnsigned()
+
+internal fun Long.getLowBitsUnsigned() = if (low >= 0) low.toDouble() else TWO_PWR_32_DBL_ + low
+
+internal fun hashCode(l: Long) = l.low xor l.high
+
+internal fun Long.toString(radix: Int): String {
+    if (radix < 2 || 36 < radix) {
+        throw Exception("radix out of range: $radix")
+    }
+
+    if (isZero()) {
+        return "0"
+    }
+
+    if (isNegative()) {
+        if (equalsLong(MIN_VALUE)) {
+            // We need to change the Long value before it can be negated, so we remove
+            // the bottom-most digit in this base and then recurse to do the rest.
+            val radixLong = fromInt(radix)
+            val div = div(radixLong)
+            val rem = div.multiply(radixLong).subtract(this).toInt();
+            return js("div.toString(radix) + rem.toString(radix)")
+        } else {
+            return "-${negate().toString()}"
+        }
+    }
+
+    // Do several (6) digits each time through the loop, so as to
+    // minimize the calls to the very expensive emulated div.
+    val radixToPower = fromNumber(js("Math.pow(radix, 6)").unsafeCast<Double>())
+
+    var rem = this
+    var result = ""
+    while (true) {
+        val remDiv = rem.div(radixToPower)
+        val intval = rem.subtract(remDiv.multiply(radixToPower)).toInt()
+        var digits = js("intval.toString(radix)").unsafeCast<String>()
+
+        rem = remDiv
+        if (rem.isZero()) {
+            return digits + result
+        } else {
+            while (digits.length < 6) {
+                digits = "0" + digits
+            }
+            result = digits + result
+        }
+    }
+}
+
+internal fun Long.negate() = unaryMinus()
+
+internal fun Long.isZero() = high == 0 && low == 0
+
+internal fun Long.isNegative() = high < 0
+
+internal fun Long.isOdd() = low and 1 == 1
+
+internal fun Long.equalsLong(other: Long) = high == other.high && low == other.low
+
+internal fun Long.lessThan(other: Long) = compare(other) < 0
+
+internal fun Long.lessThanOrEqual(other: Long) = compare(other) <= 0
+
+internal fun Long.greaterThan(other: Long) = compare(other) > 0
+
+internal fun Long.greaterThanOrEqual(other: Long) = compare(other) >= 0
+
+internal fun Long.compare(other: Long): Int {
+    if (equalsLong(other)) {
+        return 0;
+    }
+
+    val thisNeg = isNegative();
+    val otherNeg = other.isNegative();
+
+    return when {
+        thisNeg && !otherNeg -> -1
+        !thisNeg && otherNeg -> 1
+    // at this point, the signs are the same, so subtraction will not overflow
+        subtract(other).isNegative() -> -1
+        else -> 1
+    }
+}
+
+internal fun Long.add(other: Long): Long {
+    // Divide each number into 4 chunks of 16 bits, and then sum the chunks.
+
+    val a48 = high ushr 16
+    val a32 = high and 0xFFFF
+    val a16 = high ushr 16
+    val a00 = low and 0xFFFF
+
+    val b48 = other.high ushr 16
+    val b32 = other.high and 0xFFFF
+    val b16 = other.low ushr 16
+    val b00 = other.low and 0xFFFF
+
+    var c48 = 0
+    var c32 = 0
+    var c16 = 0
+    var c00 = 0
+    c00 += a00 + b00
+    c16 += c00 ushr 16
+    c00 = c00 and 0xFFFF
+    c16 += a16 + b16
+    c32 += c16 ushr 16
+    c16 = c16 and 0xFFFF
+    c32 += a32 + b32
+    c48 += c32 ushr 16
+    c32 = c32 and 0xFFFF
+    c48 += a48 + b48
+    c48 = c48 and 0xFFFF
+    return Long((c16 shl 16) or c00, (c48 shl 16) or c32)
+}
+
+internal fun Long.subtract(other: Long) = add(other.unaryMinus())
+
+internal fun Long.multiply(other: Long): Long {
+    if (isZero()) {
+        return ZERO
+    } else if (other.isZero()) {
+        return ZERO
+    }
+
+    if (equalsLong(MIN_VALUE)) {
+        return if (other.isOdd()) MIN_VALUE else ZERO
+    } else if (other.equalsLong(MIN_VALUE)) {
+        return if (isOdd()) MIN_VALUE else ZERO
+    }
+
+    if (isNegative()) {
+        return if (other.isNegative()) {
+            negate().multiply(other.negate())
+        } else {
+            negate().multiply(other).negate()
+        }
+    } else if (other.isNegative()) {
+        return multiply(other.negate()).negate()
+    }
+
+    // If both longs are small, use float multiplication
+    if (lessThan(TWO_PWR_24_) && other.lessThan(TWO_PWR_24_)) {
+        return fromNumber(toNumber() * other.toNumber())
+    }
+
+    // Divide each long into 4 chunks of 16 bits, and then add up 4x4 products.
+    // We can skip products that would overflow.
+
+    val a48 = high ushr 16
+    val a32 = high and 0xFFFF
+    val a16 = low ushr 16
+    val a00 = low and 0xFFFF
+
+    val b48 = other.high ushr 16
+    val b32 = other.high and 0xFFFF
+    val b16 = other.low ushr 16
+    val b00 = other.low and 0xFFFF
+
+    var c48 = 0
+    var c32 = 0
+    var c16 = 0
+    var c00 = 0
+    c00 += a00 * b00
+    c16 += c00 ushr 16
+    c00 = c00 and 0xFFFF
+    c16 += a16 * b00
+    c32 += c16 ushr 16
+    c16 = c16 and 0xFFFF
+    c16 += a00 * b16
+    c32 += c16 ushr 16
+    c16 = c16 and 0xFFFF
+    c32 += a32 * b00
+    c48 += c32 ushr 16
+    c32 = c32 and 0xFFFF
+    c32 += a16 * b16
+    c48 += c32 ushr 16
+    c32 = c32 and 0xFFFF
+    c32 += a00 * b32
+    c48 += c32 ushr 16
+    c32 = c32 and 0xFFFF
+    c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48
+    c48 = c48 and 0xFFFF
+    return Long(c16 shl 16 or c00, c48 shl 16 or c32)
+}
+
+fun Long.divide(other: Long): Long {
+    if (other.isZero()) {
+        throw Exception("division by zero")
+    } else if (isZero()) {
+        return ZERO
+    }
+
+    if (equalsLong(MIN_VALUE)) {
+        if (other.equalsLong(ONE) || other.equalsLong(NEG_ONE)) {
+            return MIN_VALUE  // recall that -MIN_VALUE == MIN_VALUE
+        } else if (other.equalsLong(MIN_VALUE)) {
+            return ONE
+        } else {
+            // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|.
+            val halfThis = shiftRight(1)
+            val approx = halfThis.div(other).shiftLeft(1)
+            if (approx.equalsLong(ZERO)) {
+                return if (other.isNegative()) ONE else NEG_ONE
+            } else {
+                val rem = subtract(other.multiply(approx))
+                return approx.add(rem.div(other))
+            }
+        }
+    } else if (other.equalsLong(MIN_VALUE)) {
+        return ZERO
+    }
+
+    if (isNegative()) {
+        return if (other.isNegative()) {
+            negate().div(other.negate())
+        } else {
+            negate().div(other).negate()
+        }
+    } else if (other.isNegative()) {
+        return div(other.negate()).negate()
+    }
+
+    // Repeat the following until the remainder is less than other:  find a
+    // floating-point that approximates remainder / other *from below*, add this
+    // into the result, and subtract it from the remainder.  It is critical that
+    // the approximate value is less than or equal to the real value so that the
+    // remainder never becomes negative.
+    var res = ZERO
+    var rem = this
+    while (rem.greaterThanOrEqual(other)) {
+        // Approximate the result of division. This may be a little greater or
+        // smaller than the actual value.
+        val approxDouble = rem.toNumber() / other.toNumber()
+        var approx = js("Math.max(1, Math.floor(approxDouble))").unsafeCast<Double>()
+
+        // We will tweak the approximate result by changing it in the 48-th digit or
+        // the smallest non-fractional digit, whichever is larger.
+        val log2 = js("Math.ceil(Math.log(approx) / Math.LN2)").unsafeCast<Int>()
+        val delta = if (log2 <= 48) 1.0 else js("Math.pow(2, log2 - 48)").unsafeCast<Double>()
+
+        // Decrease the approximation until it is smaller than the remainder.  Note
+        // that if it is too large, the product overflows and is negative.
+        var approxRes = fromNumber(approx)
+        var approxRem = approxRes.multiply(other)
+        while (approxRem.isNegative() || approxRem.greaterThan(rem)) {
+            approx -= delta
+            approxRes = fromNumber(approx)
+            approxRem = approxRes.multiply(other)
+        }
+
+        // We know the answer can't be zero... and actually, zero would cause
+        // infinite recursion since we would make no progress.
+        if (approxRes.isZero()) {
+            approxRes = ONE
+        }
+
+        res = res.add(approxRes)
+        rem = rem.subtract(approxRem)
+    }
+    return res
+}
+
+internal fun Long.modulo(other: Long) = subtract(div(other).multiply(other))
+
+internal fun Long.shiftLeft(numBits: Int): Long {
+    val numBits = numBits and 63
+    if (numBits == 0) {
+        return this
+    } else {
+        if (numBits < 32) {
+            return Long(low shl numBits, (high shl numBits) or (low ushr (32 - numBits)))
+        } else {
+            return Long(0, low shl (numBits - 32))
+        }
+    }
+}
+
+internal fun Long.shiftRight(numBits: Int): Long {
+    val numBits = numBits and 63
+    if (numBits == 0) {
+        return this
+    } else {
+        if (numBits < 32) {
+            return Long((low ushr numBits) or (high shl (32 - numBits)), high shr numBits)
+        } else {
+            return Long(high shr (numBits - 32), if (high >= 0) 0 else -1)
+        }
+    }
+}
+
+internal fun Long.shiftRightUnsigned(numBits: Int): Long {
+    val numBits = numBits and 63
+    if (numBits == 0) {
+        return this
+    } else {
+        if (numBits < 32) {
+            return Long((low ushr numBits) or (high shl (32 - numBits)), high ushr numBits)
+        } else return if (numBits == 32) {
+            Long(high, 0)
+        } else {
+            Long(high ushr (numBits - 32), 0)
+        }
+    }
+}
+
+/**
+ * Returns a Long representing the given (32-bit) integer value.
+ * @param {number} value The 32-bit integer in question.
+ * @return {!Kotlin.Long} The corresponding Long value.
+ */
+// TODO: cache
+internal fun fromInt(value: Int) = Long(value, if (value < 0) -1 else 0)
+
+/**
+ * Returns a Long representing the given value, provided that it is a finite
+ * number.  Otherwise, zero is returned.
+ * @param {number} value The number in question.
+ * @return {!Kotlin.Long} The corresponding Long value.
+ */
+internal fun fromNumber(value: Double): Long {
+    if (js("isNaN(value)").unsafeCast<Boolean>() || !js("isFinite(value)").unsafeCast<Boolean>()) {
+        return ZERO;
+    } else if (value <= -TWO_PWR_63_DBL_) {
+        return MIN_VALUE;
+    } else if (value + 1 >= TWO_PWR_63_DBL_) {
+        return MAX_VALUE;
+    } else if (value < 0) {
+        return fromNumber(-value).negate();
+    } else {
+        val twoPwr32 = TWO_PWR_32_DBL_
+        return Long(
+            js("(value % twoPwr32) | 0").unsafeCast<Int>(),
+            js("(value / twoPwr32) | 0").unsafeCast<Int>()
+        )
+    }
+}
+
+private val TWO_PWR_16_DBL_ = (1 shl 16).toDouble()
+
+private val TWO_PWR_24_DBL_ = (1 shl 24).toDouble()
+
+private val TWO_PWR_32_DBL_ = TWO_PWR_16_DBL_ * TWO_PWR_16_DBL_
+
+private val TWO_PWR_64_DBL_ = TWO_PWR_32_DBL_ * TWO_PWR_32_DBL_
+
+private val TWO_PWR_63_DBL_ = TWO_PWR_64_DBL_ / 2
+
+private val ZERO = fromInt(0)
+
+private val ONE = fromInt(1)
+
+private val NEG_ONE = fromInt(-1)
+
+private val MAX_VALUE = Long(-1, -1 ushr 1)
+
+private val MIN_VALUE = Long(0, 1 shl 31)
+
+private val TWO_PWR_24_ = fromInt(1 shl 24)
diff --git a/libraries/stdlib/js/irRuntime/numberConversion.kt b/libraries/stdlib/js/irRuntime/numberConversion.kt
index 41c3d99..4c2fe41 100644
--- a/libraries/stdlib/js/irRuntime/numberConversion.kt
+++ b/libraries/stdlib/js/irRuntime/numberConversion.kt
@@ -19,6 +19,10 @@
 fun toByte(a: dynamic): Byte = js("a << 24 >> 24").unsafeCast<Byte>()
 fun toShort(a: dynamic): Short = js("a << 16 >> 16").unsafeCast<Short>()
 
+fun numberToLong(a: dynamic): Long = fromNumber(a)
+
+fun toLong(a: dynamic): Long = fromInt(a)
+
 fun doubleToInt(a: dynamic) = js("""
     if (a > 2147483647) return 2147483647;
     if (a < -2147483648) return -2147483648;
diff --git a/libraries/stdlib/js/irRuntime/typeCheckUtils.kt b/libraries/stdlib/js/irRuntime/typeCheckUtils.kt
index dba0d06..f943bc0 100644
--- a/libraries/stdlib/js/irRuntime/typeCheckUtils.kt
+++ b/libraries/stdlib/js/irRuntime/typeCheckUtils.kt
@@ -6,7 +6,7 @@
 package kotlin.js
 
 @kotlin.internal.DynamicExtension
-public fun <T> dynamic.unsafeCast(): T = this
+public inline fun <T> dynamic.unsafeCast(): T = this
 
 private fun isInterfaceImpl(ctor: dynamic, iface: dynamic): Boolean {
     if (ctor === iface) return true;