JS IR: hide runtime helpers from users

This commit is contained in:
Anton Bannykh
2020-04-22 19:31:48 +03:00
parent 9f20e65595
commit e8a6ddceaa
8 changed files with 50 additions and 47 deletions
+2 -1
View File
@@ -7,7 +7,8 @@ package kotlin.js
import withType import withType
external fun <T> Array(size: Int): Array<T> @PublishedApi
internal external fun <T> Array(size: Int): Array<T>
@PublishedApi @PublishedApi
internal fun <T> fillArrayVal(array: Array<T>, initValue: T): Array<T> { internal fun <T> fillArrayVal(array: Array<T>, initValue: T): Array<T> {
+3 -3
View File
@@ -8,7 +8,7 @@ package kotlin.js
// Adopted from misc.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 { "number" -> when {
jsTypeOf(b) == "number" -> jsTypeOf(b) == "number" ->
doubleCompareTo(a, b) doubleCompareTo(a, b)
@@ -27,14 +27,14 @@ fun compareTo(a: dynamic, b: dynamic): Int = when (jsTypeOf(a)) {
private fun <T : Comparable<T>> compareToDoNotIntrinsicify(a: Comparable<T>, b: T) = private fun <T : Comparable<T>> compareToDoNotIntrinsicify(a: Comparable<T>, b: T) =
a.compareTo(b) a.compareTo(b)
fun primitiveCompareTo(a: dynamic, b: dynamic): Int = internal fun primitiveCompareTo(a: dynamic, b: dynamic): Int =
when { when {
a < b -> -1 a < b -> -1
a > b -> 1 a > b -> 1
else -> 0 else -> 0
} }
fun doubleCompareTo(a: dynamic, b: dynamic): Int = internal fun doubleCompareTo(a: dynamic, b: dynamic): Int =
when { when {
a < b -> -1 a < b -> -1
a > b -> 1 a > b -> 1
@@ -5,7 +5,7 @@
package kotlin.js package kotlin.js
fun equals(obj1: dynamic, obj2: dynamic): Boolean { internal fun equals(obj1: dynamic, obj2: dynamic): Boolean {
if (obj1 == null) { if (obj1 == null) {
return obj2 == null return obj2 == null
} }
@@ -27,20 +27,20 @@ fun equals(obj1: dynamic, obj2: dynamic): Boolean {
return obj1 === obj2 return obj1 === obj2
} }
fun toString(o: dynamic): String = when { internal fun toString(o: dynamic): String = when {
o == null -> "null" o == null -> "null"
isArrayish(o) -> "[...]" isArrayish(o) -> "[...]"
else -> (o.toString)().unsafeCast<String>() else -> (o.toString)().unsafeCast<String>()
} }
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 { private fun hasOwnPrototypeProperty(o: Any, name: String): Boolean {
return JsObject.getPrototypeOf(o).hasOwnProperty(name).unsafeCast<Boolean>() return JsObject.getPrototypeOf(o).hasOwnProperty(name).unsafeCast<Boolean>()
} }
fun hashCode(obj: dynamic): Int { internal fun hashCode(obj: dynamic): Int {
if (obj == null) if (obj == null)
return 0 return 0
@@ -56,7 +56,7 @@ fun hashCode(obj: dynamic): Int {
private const val POW_2_32 = 4294967296.0 private const val POW_2_32 = 4294967296.0
private const val OBJECT_HASH_CODE_PROPERTY_NAME = "kotlinHashCodeValue$" 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)) { if (!jsIn(OBJECT_HASH_CODE_PROPERTY_NAME, obj)) {
var hash = jsBitwiseOr(js("Math").random() * POW_2_32, 0) // Make 32-bit singed integer. var hash = jsBitwiseOr(js("Math").random() * POW_2_32, 0) // Make 32-bit singed integer.
var descriptor = js("new Object()") var descriptor = js("new Object()")
@@ -67,7 +67,7 @@ fun getObjectHashCode(obj: dynamic): Int {
return obj[OBJECT_HASH_CODE_PROPERTY_NAME].unsafeCast<Int>(); return obj[OBJECT_HASH_CODE_PROPERTY_NAME].unsafeCast<Int>();
} }
fun getStringHashCode(str: String): Int { internal fun getStringHashCode(str: String): Int {
var hash = 0 var hash = 0
val length: Int = str.length // TODO: Implement WString.length val length: Int = str.length // TODO: Implement WString.length
for (i in 0..length-1) { for (i in 0..length-1) {
@@ -77,7 +77,7 @@ fun getStringHashCode(str: String): Int {
return hash return hash
} }
fun identityHashCode(obj: Any?): Int = getObjectHashCode(obj) internal fun identityHashCode(obj: Any?): Int = getObjectHashCode(obj)
internal fun captureStack(instance: Throwable) { internal fun captureStack(instance: Throwable) {
if (js("Error").captureStackTrace != null) { if (js("Error").captureStackTrace != null) {
+8 -6
View File
@@ -15,18 +15,20 @@ internal fun throwKotlinNothingValueException(): Nothing =
internal fun noWhenBranchMatchedException(): Nothing = throw NoWhenBranchMatchedException() internal fun noWhenBranchMatchedException(): Nothing = throw NoWhenBranchMatchedException()
internal fun THROW_ISE(): Nothing {
fun THROW_ISE(): Nothing {
throw IllegalStateException() throw IllegalStateException()
} }
fun THROW_CCE(): Nothing {
internal fun THROW_CCE(): Nothing {
throw ClassCastException() throw ClassCastException()
} }
fun THROW_NPE(): Nothing {
internal fun THROW_NPE(): Nothing {
throw NullPointerException() throw NullPointerException()
} }
fun THROW_IAE(msg: String): Nothing {
internal fun THROW_IAE(msg: String): Nothing {
throw IllegalArgumentException(msg) throw IllegalArgumentException(msg)
} }
fun <T:Any> ensureNotNull(v: T?): T = if (v == null) THROW_NPE() else v internal fun <T:Any> ensureNotNull(v: T?): T = if (v == null) THROW_NPE() else v
+1 -1
View File
@@ -384,7 +384,7 @@ private val MIN_VALUE = Long(0, 1 shl 31)
private val TWO_PWR_24_ = fromInt(1 shl 24) private val TWO_PWR_24_ = fromInt(1 shl 24)
@JsName("Math") @JsName("Math")
external object JsMath { internal external object JsMath {
fun max(lhs: Number, rhs: Number): Double fun max(lhs: Number, rhs: Number): Double
fun floor(x: Number): Double fun floor(x: Number): Double
fun ceil(x: Number): Double fun ceil(x: Number): Double
@@ -5,26 +5,26 @@
package kotlin.js 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<Double>() internal fun numberToDouble(a: dynamic): Double = js("+a").unsafeCast<Double>()
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 // << and >> shifts are used to preserve sign of the number
fun toByte(a: dynamic): Byte = js("a << 24 >> 24").unsafeCast<Byte>() internal fun toByte(a: dynamic): Byte = js("a << 24 >> 24").unsafeCast<Byte>()
fun toShort(a: dynamic): Short = js("a << 16 >> 16").unsafeCast<Short>() internal fun toShort(a: dynamic): Short = js("a << 16 >> 16").unsafeCast<Short>()
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 > 2147483647 -> 2147483647
a < -2147483648 -> -2147483648 a < -2147483648 -> -2147483648
else -> jsBitwiseOr(a, 0) else -> jsBitwiseOr(a, 0)
} }
fun numberToChar(a: dynamic) = Char(numberToInt(a) and 0xFFFF) internal fun numberToChar(a: dynamic) = Char(numberToInt(a) and 0xFFFF)
+2 -2
View File
@@ -6,10 +6,10 @@
package kotlin.js package kotlin.js
// Creates IntRange for {Byte, Short, Int}.rangeTo(x: {Byte, Short, Int}) // 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) IntRange(start, endInclusive)
// Create LongRange for {Byte, Short, Int}.rangeTo(x: Long) // Create LongRange for {Byte, Short, Int}.rangeTo(x: Long)
// Long.rangeTo(x: *) should be implemented in Long class // 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) LongRange(numberToLong(start), endInclusive)
@@ -33,7 +33,7 @@ private fun isInterfaceImpl(ctor: Ctor, iface: dynamic): Boolean {
return superConstructor != null && isInterfaceImpl(superConstructor, iface) 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 val ctor = obj.constructor ?: return false
return isInterfaceImpl(ctor, iface) return isInterfaceImpl(ctor, iface)
@@ -82,7 +82,7 @@ internal fun isSuspendFunction(obj: dynamic, arity: Int): Boolean {
return false return false
} }
fun isObject(obj: dynamic): Boolean { internal fun isObject(obj: dynamic): Boolean {
val objTypeOf = jsTypeOf(obj) val objTypeOf = jsTypeOf(obj)
return when (objTypeOf) { return when (objTypeOf) {
@@ -98,32 +98,32 @@ private fun isJsArray(obj: Any): Boolean {
return js("Array").isArray(obj).unsafeCast<Boolean>() return js("Array").isArray(obj).unsafeCast<Boolean>()
} }
public fun isArray(obj: Any): Boolean { internal fun isArray(obj: Any): Boolean {
return isJsArray(obj) && !(obj.asDynamic().`$type$`) return isJsArray(obj) && !(obj.asDynamic().`$type$`)
} }
public fun isArrayish(o: dynamic) = internal fun isArrayish(o: dynamic) =
isJsArray(o) || js("ArrayBuffer").isView(o).unsafeCast<Boolean>() isJsArray(o) || js("ArrayBuffer").isView(o).unsafeCast<Boolean>()
public fun isChar(c: Any): Boolean { internal fun isChar(c: Any): Boolean {
error("isChar is not implemented") error("isChar is not implemented")
} }
// TODO: Distinguish Boolean/Byte and Short/Char // TODO: Distinguish Boolean/Byte and Short/Char
public fun isBooleanArray(a: dynamic): Boolean = isJsArray(a) && a.`$type$` === "BooleanArray" internal fun isBooleanArray(a: dynamic): Boolean = isJsArray(a) && a.`$type$` === "BooleanArray"
public fun isByteArray(a: dynamic): Boolean = jsInstanceOf(a, js("Int8Array")) internal fun isByteArray(a: dynamic): Boolean = jsInstanceOf(a, js("Int8Array"))
public fun isShortArray(a: dynamic): Boolean = jsInstanceOf(a, js("Int16Array")) internal fun isShortArray(a: dynamic): Boolean = jsInstanceOf(a, js("Int16Array"))
public fun isCharArray(a: dynamic): Boolean = isJsArray(a) && a.`$type$` === "CharArray" internal fun isCharArray(a: dynamic): Boolean = isJsArray(a) && a.`$type$` === "CharArray"
public fun isIntArray(a: dynamic): Boolean = jsInstanceOf(a, js("Int32Array")) internal fun isIntArray(a: dynamic): Boolean = jsInstanceOf(a, js("Int32Array"))
public fun isFloatArray(a: dynamic): Boolean = jsInstanceOf(a, js("Float32Array")) internal fun isFloatArray(a: dynamic): Boolean = jsInstanceOf(a, js("Float32Array"))
public fun isDoubleArray(a: dynamic): Boolean = jsInstanceOf(a, js("Float64Array")) internal fun isDoubleArray(a: dynamic): Boolean = jsInstanceOf(a, js("Float64Array"))
public fun isLongArray(a: dynamic): Boolean = isJsArray(a) && a.`$type$` === "LongArray" internal fun isLongArray(a: dynamic): Boolean = isJsArray(a) && a.`$type$` === "LongArray"
internal fun jsGetPrototypeOf(jsClass: dynamic) = js("Object").getPrototypeOf(jsClass) 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")) { if (jsClass === js("Object")) {
return isObject(obj) return isObject(obj)
} }
@@ -159,9 +159,9 @@ public fun jsIsType(obj: dynamic, jsClass: dynamic): Boolean {
return false 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) var type = jsTypeOf(value)
return type == "string" || return type == "string" ||
@@ -170,5 +170,5 @@ fun isComparable(value: dynamic): Boolean {
isInterface(value, Comparable::class.js) isInterface(value, Comparable::class.js)
} }
fun isCharSequence(value: dynamic): Boolean = internal fun isCharSequence(value: dynamic): Boolean =
jsTypeOf(value) == "string" || isInterface(value, CharSequence::class.js) jsTypeOf(value) == "string" || isInterface(value, CharSequence::class.js)