From e8a6ddceaa332bc26b4b966601522cecdfa360c2 Mon Sep 17 00:00:00 2001 From: Anton Bannykh Date: Wed, 22 Apr 2020 19:31:48 +0300 Subject: [PATCH] JS IR: hide runtime helpers from users --- libraries/stdlib/js-ir/runtime/arrays.kt | 3 +- libraries/stdlib/js-ir/runtime/compareTo.kt | 6 ++-- libraries/stdlib/js-ir/runtime/coreRuntime.kt | 14 ++++---- libraries/stdlib/js-ir/runtime/hacks.kt | 14 ++++---- libraries/stdlib/js-ir/runtime/longjs.kt | 2 +- .../stdlib/js-ir/runtime/numberConversion.kt | 20 +++++------ libraries/stdlib/js-ir/runtime/rangeTo.kt | 4 +-- .../stdlib/js-ir/runtime/typeCheckUtils.kt | 34 +++++++++---------- 8 files changed, 50 insertions(+), 47 deletions(-) diff --git a/libraries/stdlib/js-ir/runtime/arrays.kt b/libraries/stdlib/js-ir/runtime/arrays.kt index 36c38a394d4..11f2ac129e4 100644 --- a/libraries/stdlib/js-ir/runtime/arrays.kt +++ b/libraries/stdlib/js-ir/runtime/arrays.kt @@ -7,7 +7,8 @@ package kotlin.js import withType -external fun Array(size: Int): Array +@PublishedApi +internal external fun Array(size: Int): Array @PublishedApi internal fun fillArrayVal(array: Array, initValue: T): Array { diff --git a/libraries/stdlib/js-ir/runtime/compareTo.kt b/libraries/stdlib/js-ir/runtime/compareTo.kt index dc1e1f53f08..7a6aa4ced3b 100644 --- a/libraries/stdlib/js-ir/runtime/compareTo.kt +++ b/libraries/stdlib/js-ir/runtime/compareTo.kt @@ -8,7 +8,7 @@ package kotlin.js // Adopted from misc.js -fun compareTo(a: dynamic, b: dynamic): Int = when (jsTypeOf(a)) { +internal fun compareTo(a: dynamic, b: dynamic): Int = when (jsTypeOf(a)) { "number" -> when { jsTypeOf(b) == "number" -> doubleCompareTo(a, b) @@ -27,14 +27,14 @@ fun compareTo(a: dynamic, b: dynamic): Int = when (jsTypeOf(a)) { private fun > compareToDoNotIntrinsicify(a: Comparable, b: T) = a.compareTo(b) -fun primitiveCompareTo(a: dynamic, b: dynamic): Int = +internal fun primitiveCompareTo(a: dynamic, b: dynamic): Int = when { a < b -> -1 a > b -> 1 else -> 0 } -fun doubleCompareTo(a: dynamic, b: dynamic): Int = +internal fun doubleCompareTo(a: dynamic, b: dynamic): Int = when { a < b -> -1 a > b -> 1 diff --git a/libraries/stdlib/js-ir/runtime/coreRuntime.kt b/libraries/stdlib/js-ir/runtime/coreRuntime.kt index e2ee9735641..7c5e88e9f4c 100644 --- a/libraries/stdlib/js-ir/runtime/coreRuntime.kt +++ b/libraries/stdlib/js-ir/runtime/coreRuntime.kt @@ -5,7 +5,7 @@ package kotlin.js -fun equals(obj1: dynamic, obj2: dynamic): Boolean { +internal fun equals(obj1: dynamic, obj2: dynamic): Boolean { if (obj1 == null) { return obj2 == null } @@ -27,20 +27,20 @@ fun equals(obj1: dynamic, obj2: dynamic): Boolean { return obj1 === obj2 } -fun toString(o: dynamic): String = when { +internal fun toString(o: dynamic): String = when { o == null -> "null" isArrayish(o) -> "[...]" else -> (o.toString)().unsafeCast() } -fun anyToString(o: dynamic): String = js("Object").prototype.toString.call(o) +internal fun anyToString(o: dynamic): String = js("Object").prototype.toString.call(o) private fun hasOwnPrototypeProperty(o: Any, name: String): Boolean { return JsObject.getPrototypeOf(o).hasOwnProperty(name).unsafeCast() } -fun hashCode(obj: dynamic): Int { +internal fun hashCode(obj: dynamic): Int { if (obj == null) return 0 @@ -56,7 +56,7 @@ fun hashCode(obj: dynamic): Int { private const val POW_2_32 = 4294967296.0 private const val OBJECT_HASH_CODE_PROPERTY_NAME = "kotlinHashCodeValue$" -fun getObjectHashCode(obj: dynamic): Int { +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. var descriptor = js("new Object()") @@ -67,7 +67,7 @@ fun getObjectHashCode(obj: dynamic): Int { return obj[OBJECT_HASH_CODE_PROPERTY_NAME].unsafeCast(); } -fun getStringHashCode(str: String): Int { +internal fun getStringHashCode(str: String): Int { var hash = 0 val length: Int = str.length // TODO: Implement WString.length for (i in 0..length-1) { @@ -77,7 +77,7 @@ fun getStringHashCode(str: String): Int { return hash } -fun identityHashCode(obj: Any?): Int = getObjectHashCode(obj) +internal fun identityHashCode(obj: Any?): Int = getObjectHashCode(obj) internal fun captureStack(instance: Throwable) { if (js("Error").captureStackTrace != null) { diff --git a/libraries/stdlib/js-ir/runtime/hacks.kt b/libraries/stdlib/js-ir/runtime/hacks.kt index 0ef97818825..48272f514d7 100644 --- a/libraries/stdlib/js-ir/runtime/hacks.kt +++ b/libraries/stdlib/js-ir/runtime/hacks.kt @@ -15,18 +15,20 @@ internal fun throwKotlinNothingValueException(): Nothing = internal fun noWhenBranchMatchedException(): Nothing = throw NoWhenBranchMatchedException() - -fun THROW_ISE(): Nothing { +internal fun THROW_ISE(): Nothing { throw IllegalStateException() } -fun THROW_CCE(): Nothing { + +internal fun THROW_CCE(): Nothing { throw ClassCastException() } -fun THROW_NPE(): Nothing { + +internal fun THROW_NPE(): Nothing { throw NullPointerException() } -fun THROW_IAE(msg: String): Nothing { + +internal fun THROW_IAE(msg: String): Nothing { throw IllegalArgumentException(msg) } -fun ensureNotNull(v: T?): T = if (v == null) THROW_NPE() else v \ No newline at end of file +internal fun ensureNotNull(v: T?): T = if (v == null) THROW_NPE() else v \ No newline at end of file diff --git a/libraries/stdlib/js-ir/runtime/longjs.kt b/libraries/stdlib/js-ir/runtime/longjs.kt index f374bc40c0c..c006f998515 100644 --- a/libraries/stdlib/js-ir/runtime/longjs.kt +++ b/libraries/stdlib/js-ir/runtime/longjs.kt @@ -384,7 +384,7 @@ private val MIN_VALUE = Long(0, 1 shl 31) private val TWO_PWR_24_ = fromInt(1 shl 24) @JsName("Math") -external object JsMath { +internal external object JsMath { fun max(lhs: Number, rhs: Number): Double fun floor(x: Number): Double fun ceil(x: Number): Double diff --git a/libraries/stdlib/js-ir/runtime/numberConversion.kt b/libraries/stdlib/js-ir/runtime/numberConversion.kt index 70ee5076da7..52452dffa50 100644 --- a/libraries/stdlib/js-ir/runtime/numberConversion.kt +++ b/libraries/stdlib/js-ir/runtime/numberConversion.kt @@ -5,26 +5,26 @@ package kotlin.js -fun numberToByte(a: dynamic): Byte = toByte(numberToInt(a)) +internal fun numberToByte(a: dynamic): Byte = toByte(numberToInt(a)) -fun numberToDouble(a: dynamic): Double = js("+a").unsafeCast() +internal fun numberToDouble(a: dynamic): Double = js("+a").unsafeCast() -fun numberToInt(a: dynamic): Int = if (a is Long) a.toInt() else doubleToInt(a) +internal fun numberToInt(a: dynamic): Int = if (a is Long) a.toInt() else doubleToInt(a) -fun numberToShort(a: dynamic): Short = toShort(numberToInt(a)) +internal fun numberToShort(a: dynamic): Short = toShort(numberToInt(a)) // << and >> shifts are used to preserve sign of the number -fun toByte(a: dynamic): Byte = js("a << 24 >> 24").unsafeCast() -fun toShort(a: dynamic): Short = js("a << 16 >> 16").unsafeCast() +internal fun toByte(a: dynamic): Byte = js("a << 24 >> 24").unsafeCast() +internal fun toShort(a: dynamic): Short = js("a << 16 >> 16").unsafeCast() -fun numberToLong(a: dynamic): Long = if (a is Long) a else fromNumber(a) +internal fun numberToLong(a: dynamic): Long = if (a is Long) a else fromNumber(a) -fun toLong(a: dynamic): Long = fromInt(a) +internal fun toLong(a: dynamic): Long = fromInt(a) -fun doubleToInt(a: Double): Int = when { +internal fun doubleToInt(a: Double): Int = when { a > 2147483647 -> 2147483647 a < -2147483648 -> -2147483648 else -> jsBitwiseOr(a, 0) } -fun numberToChar(a: dynamic) = Char(numberToInt(a) and 0xFFFF) \ No newline at end of file +internal fun numberToChar(a: dynamic) = Char(numberToInt(a) and 0xFFFF) \ No newline at end of file diff --git a/libraries/stdlib/js-ir/runtime/rangeTo.kt b/libraries/stdlib/js-ir/runtime/rangeTo.kt index 09c65da062d..e197fdb36d8 100644 --- a/libraries/stdlib/js-ir/runtime/rangeTo.kt +++ b/libraries/stdlib/js-ir/runtime/rangeTo.kt @@ -6,10 +6,10 @@ package kotlin.js // Creates IntRange for {Byte, Short, Int}.rangeTo(x: {Byte, Short, Int}) -fun numberRangeToNumber(start: dynamic, endInclusive: dynamic) = +internal fun numberRangeToNumber(start: dynamic, endInclusive: dynamic) = IntRange(start, endInclusive) // Create LongRange for {Byte, Short, Int}.rangeTo(x: Long) // Long.rangeTo(x: *) should be implemented in Long class -fun numberRangeToLong(start: dynamic, endInclusive: dynamic) = +internal fun numberRangeToLong(start: dynamic, endInclusive: dynamic) = LongRange(numberToLong(start), endInclusive) diff --git a/libraries/stdlib/js-ir/runtime/typeCheckUtils.kt b/libraries/stdlib/js-ir/runtime/typeCheckUtils.kt index 6067afa6187..0b8ff0d96ed 100644 --- a/libraries/stdlib/js-ir/runtime/typeCheckUtils.kt +++ b/libraries/stdlib/js-ir/runtime/typeCheckUtils.kt @@ -33,7 +33,7 @@ private fun isInterfaceImpl(ctor: Ctor, iface: dynamic): Boolean { return superConstructor != null && isInterfaceImpl(superConstructor, iface) } -public fun isInterface(obj: dynamic, iface: dynamic): Boolean { +internal fun isInterface(obj: dynamic, iface: dynamic): Boolean { val ctor = obj.constructor ?: return false return isInterfaceImpl(ctor, iface) @@ -82,7 +82,7 @@ internal fun isSuspendFunction(obj: dynamic, arity: Int): Boolean { return false } -fun isObject(obj: dynamic): Boolean { +internal fun isObject(obj: dynamic): Boolean { val objTypeOf = jsTypeOf(obj) return when (objTypeOf) { @@ -98,32 +98,32 @@ private fun isJsArray(obj: Any): Boolean { return js("Array").isArray(obj).unsafeCast() } -public fun isArray(obj: Any): Boolean { +internal fun isArray(obj: Any): Boolean { return isJsArray(obj) && !(obj.asDynamic().`$type$`) } -public fun isArrayish(o: dynamic) = +internal fun isArrayish(o: dynamic) = isJsArray(o) || js("ArrayBuffer").isView(o).unsafeCast() -public fun isChar(c: Any): Boolean { +internal fun isChar(c: Any): Boolean { error("isChar is not implemented") } // TODO: Distinguish Boolean/Byte and Short/Char -public fun isBooleanArray(a: dynamic): Boolean = isJsArray(a) && a.`$type$` === "BooleanArray" -public fun isByteArray(a: dynamic): Boolean = jsInstanceOf(a, js("Int8Array")) -public fun isShortArray(a: dynamic): Boolean = jsInstanceOf(a, js("Int16Array")) -public fun isCharArray(a: dynamic): Boolean = isJsArray(a) && a.`$type$` === "CharArray" -public fun isIntArray(a: dynamic): Boolean = jsInstanceOf(a, js("Int32Array")) -public fun isFloatArray(a: dynamic): Boolean = jsInstanceOf(a, js("Float32Array")) -public fun isDoubleArray(a: dynamic): Boolean = jsInstanceOf(a, js("Float64Array")) -public fun isLongArray(a: dynamic): Boolean = isJsArray(a) && a.`$type$` === "LongArray" +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")) +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")) +internal fun isLongArray(a: dynamic): Boolean = isJsArray(a) && a.`$type$` === "LongArray" internal fun jsGetPrototypeOf(jsClass: dynamic) = js("Object").getPrototypeOf(jsClass) -public fun jsIsType(obj: dynamic, jsClass: dynamic): Boolean { +internal fun jsIsType(obj: dynamic, jsClass: dynamic): Boolean { if (jsClass === js("Object")) { return isObject(obj) } @@ -159,9 +159,9 @@ public fun jsIsType(obj: dynamic, jsClass: dynamic): Boolean { return false } -fun isNumber(a: dynamic) = jsTypeOf(a) == "number" || a is Long +internal fun isNumber(a: dynamic) = jsTypeOf(a) == "number" || a is Long -fun isComparable(value: dynamic): Boolean { +internal fun isComparable(value: dynamic): Boolean { var type = jsTypeOf(value) return type == "string" || @@ -170,5 +170,5 @@ fun isComparable(value: dynamic): Boolean { isInterface(value, Comparable::class.js) } -fun isCharSequence(value: dynamic): Boolean = +internal fun isCharSequence(value: dynamic): Boolean = jsTypeOf(value) == "string" || isInterface(value, CharSequence::class.js)