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