From 38fc4b0c59fcd3d4ba5f3d1afc2898f96f01743d Mon Sep 17 00:00:00 2001 From: Svyatoslav Kuzmich Date: Tue, 2 Apr 2019 20:43:25 +0300 Subject: [PATCH] [JS IR BE] Hack irRuntime js function usage to compensate for implementation shortcomings --- libraries/stdlib/js/irRuntime/misc.kt | 4 +- .../stdlib/js/irRuntime/noPackageHacks.kt | 10 ++--- .../stdlib/js/irRuntime/typeCheckUtils.kt | 40 ++++++++++--------- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/libraries/stdlib/js/irRuntime/misc.kt b/libraries/stdlib/js/irRuntime/misc.kt index 2ff3966103e..f3c963d40d2 100644 --- a/libraries/stdlib/js/irRuntime/misc.kt +++ b/libraries/stdlib/js/irRuntime/misc.kt @@ -6,5 +6,5 @@ package kotlin.js // TODO: Polyfill -internal fun imul(a: Int, b: Int) = - js("((a & 0xffff0000) * (b & 0xffff) + (a & 0xffff) * (b | 0)) | 0").unsafeCast() \ No newline at end of file +internal fun imul(a_local: Int, b_local: Int) = + js("((a_local & 0xffff0000) * (b_local & 0xffff) + (a_local & 0xffff) * (b_local | 0)) | 0").unsafeCast() \ No newline at end of file diff --git a/libraries/stdlib/js/irRuntime/noPackageHacks.kt b/libraries/stdlib/js/irRuntime/noPackageHacks.kt index 42cf8360adc..5d011a8cfe8 100644 --- a/libraries/stdlib/js/irRuntime/noPackageHacks.kt +++ b/libraries/stdlib/js/irRuntime/noPackageHacks.kt @@ -24,21 +24,21 @@ internal fun arrayConcat(vararg args: T): T { */ @PublishedApi internal fun primitiveArrayConcat(vararg args: T): T { - var size = 0 + var size_local = 0 for (i in 0 .. (args.size - 1)) { - size += args[i].unsafeCast>().size + size_local += args[i].unsafeCast>().size } val a = args[0] - val result = js("new a.constructor(size)").unsafeCast>() + val result = js("new a.constructor(size_local)").unsafeCast>() if (a.asDynamic().`$type$` != null) { withType(a.asDynamic().`$type$`, result) } - size = 0 + size_local = 0 for (i in 0 .. (args.size - 1)) { val arr = args[i].unsafeCast>() for (j in 0 .. (arr.size - 1)) { - result[size++] = arr[j] + result[size_local++] = arr[j] } } return result.unsafeCast() diff --git a/libraries/stdlib/js/irRuntime/typeCheckUtils.kt b/libraries/stdlib/js/irRuntime/typeCheckUtils.kt index b0263b2df3b..83339538cce 100644 --- a/libraries/stdlib/js/irRuntime/typeCheckUtils.kt +++ b/libraries/stdlib/js/irRuntime/typeCheckUtils.kt @@ -5,27 +5,31 @@ package kotlin.js -private fun isInterfaceImpl(ctor: dynamic, iface: dynamic): Boolean { - if (ctor === iface) return true; +private external interface Metadata { + val interfaces: Array +} - val self = ::isInterfaceImpl - return js( - """ - var metadata = ctor.${"$"}metadata${"$"}; +private external interface Ctor { + val `$metadata$`: Metadata? + val prototype: Ctor? +} + +private fun isInterfaceImpl(ctor: Ctor, iface: dynamic): Boolean { + if (ctor === iface) return true + + val metadata = ctor.`$metadata$` if (metadata != null) { - var interfaces = metadata.interfaces; - for (var i = 0; i < interfaces.length; i++) { - if (self_0(interfaces[i], iface)) { - return true; + val interfaces = metadata.interfaces + for (i in interfaces) { + if (isInterfaceImpl(i, iface)) { + return true } } } - var superPrototype = ctor.prototype != null ? Object.getPrototypeOf(ctor.prototype) : null; - var superConstructor = superPrototype != null ? superPrototype.constructor : null; - return superConstructor != null && self_0(superConstructor, iface); - """ - ).unsafeCast() + val superPrototype = if (ctor.prototype != null) js("Object").getPrototypeOf(ctor.prototype) else null + val superConstructor: Ctor? = if (superPrototype != null) superPrototype.constructor else null + return superConstructor != null && isInterfaceImpl(superConstructor, iface) } public fun isInterface(obj: dynamic, iface: dynamic): Boolean { @@ -74,9 +78,9 @@ public fun isInterface(ctor: dynamic, IType: dynamic): Boolean { fun typeOf(obj: dynamic): String = js("typeof obj").unsafeCast() -fun jsTypeOf(a: Any?): String = js("typeof a").unsafeCast() +fun jsTypeOf(obj: Any?): String = js("typeof obj").unsafeCast() -fun instanceOf(obj: dynamic, jsClass: dynamic) = js("obj instanceof jsClass").unsafeCast() +fun instanceOf(obj: dynamic, jsClass_local: dynamic) = js("obj instanceof jsClass_local").unsafeCast() fun isObject(obj: dynamic): Boolean { val objTypeOf = typeOf(obj) @@ -118,7 +122,7 @@ public fun isLongArray(a: dynamic): Boolean = isJsArray(a) && a.`$type$` == "Lon internal fun jsIn(x: String, y: dynamic): Boolean = js("x in y") -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 { if (jsClass === js("Object")) {