JS IR: use compiler intrinsics in stdlib

This reverts commit 6540421f
diff --git a/libraries/stdlib/js-ir/runtime/bitUtils.kt b/libraries/stdlib/js-ir/runtime/bitUtils.kt
index 25af2ae..6b6f2f9 100644
--- a/libraries/stdlib/js-ir/runtime/bitUtils.kt
+++ b/libraries/stdlib/js-ir/runtime/bitUtils.kt
@@ -52,9 +52,10 @@
     return bufInt32[highIndex] and Int.MIN_VALUE
 }
 
+@OptIn(JsIntrinsic::class)
 internal fun getNumberHashCode(obj: Double): Int {
     @Suppress("DEPRECATED_IDENTITY_EQUALS")
-    if (jsBitwiseOr(obj, 0).unsafeCast<Double>() === obj) {
+    if (jsBitOr(obj, 0).unsafeCast<Double>() === obj) {
         return obj.toInt()
     }
 
diff --git a/libraries/stdlib/js-ir/runtime/compareTo.kt b/libraries/stdlib/js-ir/runtime/compareTo.kt
index 7a6aa4c..efd163b 100644
--- a/libraries/stdlib/js-ir/runtime/compareTo.kt
+++ b/libraries/stdlib/js-ir/runtime/compareTo.kt
@@ -8,6 +8,7 @@
 
 // Adopted from misc.js
 
+@OptIn(JsIntrinsic::class)
 internal fun compareTo(a: dynamic, b: dynamic): Int = when (jsTypeOf(a)) {
     "number" -> when {
         jsTypeOf(b) == "number" ->
diff --git a/libraries/stdlib/js-ir/runtime/coreRuntime.kt b/libraries/stdlib/js-ir/runtime/coreRuntime.kt
index e9bd9d3..c917d85 100644
--- a/libraries/stdlib/js-ir/runtime/coreRuntime.kt
+++ b/libraries/stdlib/js-ir/runtime/coreRuntime.kt
@@ -5,6 +5,7 @@
 
 package kotlin.js
 
+@OptIn(JsIntrinsic::class)
 internal fun equals(obj1: dynamic, obj2: dynamic): Boolean {
     if (obj1 == null) {
         return obj2 == null
@@ -40,6 +41,7 @@
     return JsObject.getPrototypeOf(o).hasOwnProperty(name).unsafeCast<Boolean>()
 }
 
+@OptIn(JsIntrinsic::class)
 internal fun hashCode(obj: dynamic): Int {
     if (obj == null)
         return 0
@@ -56,9 +58,10 @@
 private const val POW_2_32 = 4294967296.0
 private const val OBJECT_HASH_CODE_PROPERTY_NAME = "kotlinHashCodeValue$"
 
+@OptIn(JsIntrinsic::class)
 internal fun getObjectHashCode(obj: dynamic): Int {
-    if (!jsIn(OBJECT_HASH_CODE_PROPERTY_NAME, obj)) {
-        var hash = jsBitwiseOr(js("Math").random() * POW_2_32, 0) // Make 32-bit singed integer.
+    if (!jsInIntrinsic(OBJECT_HASH_CODE_PROPERTY_NAME, obj)) {
+        var hash = jsBitOr(js("Math").random() * POW_2_32, 0) // Make 32-bit singed integer.
         var descriptor = js("new Object()")
         descriptor.value = hash
         descriptor.enumerable = false
diff --git a/libraries/stdlib/js-ir/runtime/longjs.kt b/libraries/stdlib/js-ir/runtime/longjs.kt
index a9e5796..43b9908 100644
--- a/libraries/stdlib/js-ir/runtime/longjs.kt
+++ b/libraries/stdlib/js-ir/runtime/longjs.kt
@@ -342,6 +342,7 @@
  * Returns zero if this `Double` value is `NaN`, [Long.MIN_VALUE] if it's less than `Long.MIN_VALUE`,
  * [Long.MAX_VALUE] if it's bigger than `Long.MAX_VALUE`.
  */
+@OptIn(JsIntrinsic::class)
 internal fun fromNumber(value: Double): Long {
     if (value.isNaN()) {
         return ZERO;
@@ -354,8 +355,8 @@
     } else {
         val twoPwr32 = TWO_PWR_32_DBL_
         return Long(
-            jsBitwiseOr(value.rem(twoPwr32), 0),
-            jsBitwiseOr(value / twoPwr32, 0)
+            jsBitOr(value.rem(twoPwr32), 0),
+            jsBitOr(value / twoPwr32, 0)
         )
     }
 }
diff --git a/libraries/stdlib/js-ir/runtime/misc.kt b/libraries/stdlib/js-ir/runtime/misc.kt
index 3eb9122..ae267fc 100644
--- a/libraries/stdlib/js-ir/runtime/misc.kt
+++ b/libraries/stdlib/js-ir/runtime/misc.kt
@@ -6,8 +6,9 @@
 package kotlin.js
 
 // TODO: Polyfill
+@OptIn(JsIntrinsic::class)
 internal fun imul(a_local: Int, b_local: Int): Int {
-    val lhs = jsBitwiseAnd(a_local, js("0xffff0000")).toDouble() * jsBitwiseAnd(b_local, 0xffff).toDouble()
-    val rhs = jsBitwiseAnd(a_local, 0xffff).toDouble() * b_local.toDouble()
-    return jsBitwiseOr(lhs + rhs, 0)
+    val lhs = jsBitAnd(a_local, js("0xffff0000")).toDouble() * jsBitAnd(b_local, 0xffff).toDouble()
+    val rhs = jsBitAnd(a_local, 0xffff).toDouble() * b_local.toDouble()
+    return jsBitOr(lhs + rhs, 0)
 }
diff --git a/libraries/stdlib/js-ir/runtime/numberConversion.kt b/libraries/stdlib/js-ir/runtime/numberConversion.kt
index 6d88786..68309dc 100644
--- a/libraries/stdlib/js-ir/runtime/numberConversion.kt
+++ b/libraries/stdlib/js-ir/runtime/numberConversion.kt
@@ -21,10 +21,11 @@
 
 internal fun toLong(a: dynamic): Long = fromInt(a)
 
+@OptIn(JsIntrinsic::class)
 internal fun doubleToInt(a: Double): Int = when {
     a > 2147483647 -> 2147483647
     a < -2147483648 -> -2147483648
-    else -> jsBitwiseOr(a, 0)
+    else -> jsBitOr(a, 0)
 }
 
 internal fun numberToChar(a: dynamic) = Char(numberToInt(a).toUShort())
\ No newline at end of file
diff --git a/libraries/stdlib/js-ir/runtime/typeCheckUtils.kt b/libraries/stdlib/js-ir/runtime/typeCheckUtils.kt
index af03153..2e4f53d 100644
--- a/libraries/stdlib/js-ir/runtime/typeCheckUtils.kt
+++ b/libraries/stdlib/js-ir/runtime/typeCheckUtils.kt
@@ -74,6 +74,7 @@
 }
 */
 
+@OptIn(JsIntrinsic::class)
 internal fun isSuspendFunction(obj: dynamic, arity: Int): Boolean {
     if (jsTypeOf(obj) == "function") {
         @Suppress("DEPRECATED_IDENTITY_EQUALS")
@@ -83,6 +84,7 @@
     return false
 }
 
+@OptIn(JsIntrinsic::class)
 internal fun isObject(obj: dynamic): Boolean {
     val objTypeOf = jsTypeOf(obj)
 
@@ -91,7 +93,7 @@
         "number" -> true
         "boolean" -> true
         "function" -> true
-        else -> jsInstanceOf(obj, js("Object"))
+        else -> jsInstanceOfIntrinsic(obj, js("Object"))
     }
 }
 
@@ -113,17 +115,30 @@
 
 // TODO: Distinguish Boolean/Byte and Short/Char
 internal fun isBooleanArray(a: dynamic): Boolean = isJsArray(a) && a.`$type$` === "BooleanArray"
-internal fun isByteArray(a: dynamic): Boolean = jsInstanceOf(a, js("Int8Array"))
-internal fun isShortArray(a: dynamic): Boolean = jsInstanceOf(a, js("Int16Array"))
+
+@OptIn(JsIntrinsic::class)
+internal fun isByteArray(a: dynamic): Boolean = jsInstanceOfIntrinsic(a, js("Int8Array"))
+
+@OptIn(JsIntrinsic::class)
+internal fun isShortArray(a: dynamic): Boolean = jsInstanceOfIntrinsic(a, js("Int16Array"))
+
 internal fun isCharArray(a: dynamic): Boolean = isJsArray(a) && a.`$type$` === "CharArray"
-internal fun isIntArray(a: dynamic): Boolean = jsInstanceOf(a, js("Int32Array"))
-internal fun isFloatArray(a: dynamic): Boolean = jsInstanceOf(a, js("Float32Array"))
-internal fun isDoubleArray(a: dynamic): Boolean = jsInstanceOf(a, js("Float64Array"))
+
+@OptIn(JsIntrinsic::class)
+internal fun isIntArray(a: dynamic): Boolean = jsInstanceOfIntrinsic(a, js("Int32Array"))
+
+@OptIn(JsIntrinsic::class)
+internal fun isFloatArray(a: dynamic): Boolean = jsInstanceOfIntrinsic(a, js("Float32Array"))
+
+@OptIn(JsIntrinsic::class)
+internal fun isDoubleArray(a: dynamic): Boolean = jsInstanceOfIntrinsic(a, js("Float64Array"))
+
 internal fun isLongArray(a: dynamic): Boolean = isJsArray(a) && a.`$type$` === "LongArray"
 
 
 internal fun jsGetPrototypeOf(jsClass: dynamic) = js("Object").getPrototypeOf(jsClass)
 
+@OptIn(JsIntrinsic::class)
 internal fun jsIsType(obj: dynamic, jsClass: dynamic): Boolean {
     if (jsClass === js("Object")) {
         return isObject(obj)
@@ -133,13 +148,13 @@
         return false
     }
 
-    if (jsTypeOf(jsClass) == "function" && jsInstanceOf(obj, jsClass)) {
+    if (jsTypeOf(jsClass) == "function" && jsInstanceOfIntrinsic(obj, jsClass)) {
         return true
     }
 
     var proto = jsGetPrototypeOf(jsClass)
     var constructor = proto?.constructor
-    if (constructor != null && jsIn("${'$'}metadata${'$'}", constructor)) {
+    if (constructor != null && jsInIntrinsic("${'$'}metadata${'$'}", constructor)) {
         var metadata = constructor.`$metadata$`
         if (metadata.kind === "object") {
             return obj === jsClass
@@ -150,7 +165,7 @@
 
     // In WebKit (JavaScriptCore) for some interfaces from DOM typeof returns "object", nevertheless they can be used in RHS of instanceof
     if (klassMetadata == null) {
-        return jsInstanceOf(obj, jsClass)
+        return jsInstanceOfIntrinsic(obj, jsClass)
     }
 
     if (klassMetadata.kind === "interface" && obj.constructor != null) {
@@ -160,8 +175,10 @@
     return false
 }
 
+@OptIn(JsIntrinsic::class)
 internal fun isNumber(a: dynamic) = jsTypeOf(a) == "number" || a is Long
 
+@OptIn(JsIntrinsic::class)
 internal fun isComparable(value: dynamic): Boolean {
     var type = jsTypeOf(value)
 
@@ -171,5 +188,6 @@
            isInterface(value, Comparable::class.js)
 }
 
+@OptIn(JsIntrinsic::class)
 internal fun isCharSequence(value: dynamic): Boolean =
     jsTypeOf(value) == "string" || isInterface(value, CharSequence::class.js)
diff --git a/libraries/stdlib/js-ir/src/kotlin/jsOperators.kt b/libraries/stdlib/js-ir/src/kotlin/jsOperators.kt
index a97d5e9..fdc6bfa 100644
--- a/libraries/stdlib/js-ir/src/kotlin/jsOperators.kt
+++ b/libraries/stdlib/js-ir/src/kotlin/jsOperators.kt
@@ -3,12 +3,11 @@
  * that can be found in the license/LICENSE.txt file.
  */
 
-@file:Suppress("UNUSED_PARAMETER")
+@file:Suppress("UNUSED_PARAMETER", "NOTHING_TO_INLINE")
 
 package kotlin.js
 
 // Parameters are suffixed with `_hack` as a workaround for Namer.
-// TODO: Implemet as compiler intrinsics
 
 /**
  * Function corresponding to JavaScript's `typeof` operator
@@ -16,20 +15,11 @@
 public fun jsTypeOf(value_hack: Any?): String =
     js("typeof value_hack").unsafeCast<String>()
 
-internal fun jsDeleteProperty(obj_hack: Any, property_hack: Any) {
-    js("delete obj_hack[property_hack]")
+@OptIn(JsIntrinsic::class)
+internal inline fun jsDeleteProperty(obj: Any, property: Any) {
+    jsDelete(obj.asDynamic()[property])
 }
 
-internal fun jsBitwiseOr(lhs_hack: Any?, rhs_hack: Any?): Int =
-    js("lhs_hack | rhs_hack").unsafeCast<Int>()
-
-internal fun jsBitwiseAnd(lhs_hack: Any?, rhs_hack: Any?): Int =
-    js("lhs_hack & rhs_hack").unsafeCast<Int>()
-
-internal fun jsInstanceOf(obj_hack: Any?, jsClass_hack: Any?): Boolean =
-    js("obj_hack instanceof jsClass_hack").unsafeCast<Boolean>()
-
-// Returns true if the specified property is in the specified object or its prototype chain.
-internal fun jsIn(lhs_hack: Any?, rhs_hack: Any): Boolean =
-    js("lhs_hack in rhs_hack").unsafeCast<Boolean>()
-
+// Used in common stdlib code (reflection.kt)
+@OptIn(JsIntrinsic::class)
+internal inline fun jsBitwiseOr(lhs: Any?, rhs: Any?): Int = jsBitOr(lhs, rhs)
\ No newline at end of file