[Wasm] Restrict types allowed in JS interop
- Prohibit Any, Array and other unsupported non-external types in JS interop context - Add K1 diagnostic - Update BE testdata ^KT-57136 Fixed
This commit is contained in:
committed by
Space Team
parent
bb05c8528f
commit
1e91fe155b
@@ -53,7 +53,7 @@ external class C {
|
||||
val x1: Int
|
||||
val x2: Int
|
||||
fun foo(x3: Int = definedExternally, x4: Int = definedExternally): String
|
||||
fun bar(x5: C = definedExternally, x6: Any = definedExternally) : String
|
||||
fun bar(x5: C = definedExternally, x6: C = definedExternally) : String
|
||||
}
|
||||
|
||||
open external class Writable: WritableStream {
|
||||
|
||||
+15
-13
@@ -88,7 +88,7 @@ function createJsLambda() {
|
||||
|
||||
// FILE: externals.kt
|
||||
|
||||
external fun createJsLambda(): (Boolean, Byte, Short, Char, Int, Long, Float, Double, String, EI, DC, (DC) -> Int) -> Int
|
||||
external fun createJsLambda(): (Boolean, Byte, Short, Char, Int, Long, Float, Double, String, EI, JSDC, (JSDC) -> Int) -> Int
|
||||
|
||||
external fun apply7(f: (String) -> ((String) -> ((String) -> ((String) -> ((String) -> ((String) -> ((String) -> String))))))): String
|
||||
|
||||
@@ -98,10 +98,11 @@ external fun is123Array(x: EI): Boolean
|
||||
external fun create123Array(): EI
|
||||
|
||||
data class DC(val x: Int, val y: Int)
|
||||
typealias JSDC = JsHandle<DC>
|
||||
|
||||
external fun extenalWithLambda(
|
||||
x: (Boolean, Byte, Short, Char, Int, Long, Float, Double, String, EI, DC) -> Unit,
|
||||
dc: DC,
|
||||
x: (Boolean, Byte, Short, Char, Int, Long, Float, Double, String, EI, JSDC) -> Unit,
|
||||
dc: JSDC,
|
||||
)
|
||||
|
||||
external fun externalWithLambdas2(
|
||||
@@ -115,8 +116,8 @@ external fun externalWithLambdas2(
|
||||
double: () -> Double,
|
||||
string: () -> String,
|
||||
ei: () -> EI,
|
||||
dc: () -> DC,
|
||||
dcGetY: (DC) -> Int,
|
||||
dc: () -> JSDC,
|
||||
dcGetY: (JSDC) -> Int,
|
||||
): Int
|
||||
|
||||
@JsExport
|
||||
@@ -165,7 +166,8 @@ fun box(): String {
|
||||
double: Double,
|
||||
string: String,
|
||||
ei: EI,
|
||||
dc: DC ->
|
||||
jsdc: JSDC ->
|
||||
val dc = jsdc.get()
|
||||
test(bool == true)
|
||||
test(byte == 1.toByte())
|
||||
test(short == 2.toShort())
|
||||
@@ -177,7 +179,7 @@ fun box(): String {
|
||||
test(string == "S")
|
||||
test(is123Array(ei))
|
||||
test(dc.x == 100 && dc.y == 200)
|
||||
}, DC(100, 200))
|
||||
}, DC(100, 200).toJsHandle())
|
||||
|
||||
|
||||
if (extenalWithLambdasCount != 11) return "Fail 1"
|
||||
@@ -193,8 +195,8 @@ fun box(): String {
|
||||
double = { 600.5 },
|
||||
string = { "700" },
|
||||
ei = { create123Array() },
|
||||
dc = { DC(800, 800) },
|
||||
dcGetY = { it.y }
|
||||
dc = { DC(800, 800).toJsHandle() },
|
||||
dcGetY = { it.get().y }
|
||||
)
|
||||
if (externalWithLambdas2Count != 11) return "Fail externalWithLambdas2"
|
||||
|
||||
@@ -210,8 +212,8 @@ fun box(): String {
|
||||
{ 600.5 },
|
||||
{ "700" },
|
||||
{ create123Array() },
|
||||
{ DC(800, 800) },
|
||||
{ it.y }
|
||||
{ DC(800, 800).toJsHandle() },
|
||||
{ it.get().y }
|
||||
)
|
||||
if (externalWithLambdas2RefCount != 11) return "Fail externalWithLambdas2"
|
||||
|
||||
@@ -228,8 +230,8 @@ fun box(): String {
|
||||
600.5,
|
||||
"700",
|
||||
create123Array(),
|
||||
DC(800, 800),
|
||||
{ it.y }
|
||||
DC(800, 800).toJsHandle(),
|
||||
{ it.get().y }
|
||||
)
|
||||
if (jsLambdaCount != 11)
|
||||
return "Fail 3"
|
||||
|
||||
+5
-4
@@ -1,13 +1,14 @@
|
||||
// TARGET_BACKEND: WASM
|
||||
// MODULE: main
|
||||
// FILE: externals.kt
|
||||
|
||||
class C(val x: Int)
|
||||
|
||||
@JsExport
|
||||
fun makeC(x: Int): C = C(x)
|
||||
fun makeC(x: Int): JsHandle<C> = C(x).toJsHandle()
|
||||
|
||||
@JsExport
|
||||
fun getX(c: C): Int = c.x
|
||||
fun getX(c: JsHandle<C>): Int = c.get().x
|
||||
|
||||
@JsExport
|
||||
fun getString(s: String): String = "Test string $s";
|
||||
@@ -18,10 +19,10 @@ fun isEven(x: Int): Boolean = x % 2 == 0
|
||||
external interface EI
|
||||
|
||||
@JsExport
|
||||
fun eiAsAny(ei: EI): Any = ei
|
||||
fun eiAsAny(ei: EI): JsHandle<Any> = ei.toJsHandle()
|
||||
|
||||
@JsExport
|
||||
fun anyAsEI(any: Any): EI = any as EI
|
||||
fun anyAsEI(any: JsHandle<Any>): EI = any.get() as EI
|
||||
|
||||
fun box(): String = "OK"
|
||||
|
||||
|
||||
@@ -43,7 +43,8 @@ fun testExterRef() {
|
||||
check(null2ExternRef() == null)
|
||||
}
|
||||
|
||||
class DataRef
|
||||
class DataRefImpl
|
||||
typealias DataRef = JsHandle<DataRefImpl>
|
||||
|
||||
fun notNullDataRef(x: DataRef): DataRef = js("x")
|
||||
|
||||
@@ -54,7 +55,7 @@ fun nullDataRef(x: DataRef): DataRef? = js("x")
|
||||
fun null2DataRef(x: DataRef): DataRef? = js("null")
|
||||
|
||||
fun testDataRef() {
|
||||
val dataRef = DataRef()
|
||||
val dataRef = DataRefImpl().toJsHandle()
|
||||
check(notNullDataRef(dataRef) == dataRef)
|
||||
checkNPE { notNull2DataRef(dataRef) }
|
||||
check (nullDataRef(dataRef) == dataRef)
|
||||
@@ -121,22 +122,6 @@ fun testFloat() {
|
||||
check(null2Float() == null)
|
||||
}
|
||||
|
||||
|
||||
fun notNullNumber(): Number = js("123.5")
|
||||
|
||||
fun notNull2Number(): Number = js("null")
|
||||
|
||||
fun nullNumber(): Number? = js("123.5")
|
||||
|
||||
fun null2Number(): Number? = js("null")
|
||||
|
||||
fun testNumber() {
|
||||
check(notNullNumber() == 123.5)
|
||||
check(notNull2Number() == 0.0)
|
||||
check(nullNumber() == 123.5)
|
||||
check(null2Number() == null)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
testString()
|
||||
testExterRef()
|
||||
@@ -145,6 +130,5 @@ fun box(): String {
|
||||
testBoolean()
|
||||
testShort()
|
||||
testFloat()
|
||||
testNumber()
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -40,27 +40,6 @@ fun testExterRef() {
|
||||
null2ExternRef(null)
|
||||
}
|
||||
|
||||
class DataRef
|
||||
|
||||
fun notNullDataRef(x: DataRef) {
|
||||
js("if (x === null) throw 'error'")
|
||||
}
|
||||
|
||||
fun nullDataRef(x: DataRef?) {
|
||||
js("if (x === null) throw 'error'")
|
||||
}
|
||||
|
||||
fun null2DataRef(x: DataRef?) {
|
||||
js("if (x !== null) throw 'error'")
|
||||
}
|
||||
|
||||
fun testDataRef() {
|
||||
val dataRef = DataRef()
|
||||
notNullDataRef(dataRef)
|
||||
nullDataRef(dataRef)
|
||||
null2DataRef(null)
|
||||
}
|
||||
|
||||
fun notNullInt(x: Int) {
|
||||
js("if (x !== 123) throw 'error'")
|
||||
}
|
||||
@@ -133,47 +112,12 @@ fun testFloat() {
|
||||
null2Float(null)
|
||||
}
|
||||
|
||||
fun notNullNumber(x: Number) {
|
||||
js("if (x !== 123.5) throw 'error'")
|
||||
}
|
||||
|
||||
fun nullNumber(x: Number?) {
|
||||
js("if (x !== 123.5) throw 'error'")
|
||||
}
|
||||
|
||||
fun null2Number(x: Number?) {
|
||||
js("if (x !== null) throw 'error'")
|
||||
}
|
||||
|
||||
fun byte2Number(x: Number) {
|
||||
js("if (x !== 123) throw 'error'")
|
||||
}
|
||||
|
||||
fun notNullByte2Number(x: Number?) {
|
||||
js("if (x !== 123) throw 'error'")
|
||||
}
|
||||
|
||||
fun nullByte2Number(x: Number?) {
|
||||
js("if (x !== null) throw 'error'")
|
||||
}
|
||||
|
||||
fun testNumber() {
|
||||
notNullNumber(123.5)
|
||||
nullNumber(123.5)
|
||||
null2Number(null)
|
||||
byte2Number(123)
|
||||
notNullByte2Number(123)
|
||||
nullByte2Number(null)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
testString()
|
||||
testExterRef()
|
||||
testDataRef()
|
||||
testInt()
|
||||
testBoolean()
|
||||
testShort()
|
||||
testFloat()
|
||||
testNumber()
|
||||
return "OK"
|
||||
}
|
||||
@@ -72,10 +72,8 @@ external fun getFalseBoolean(): Boolean
|
||||
|
||||
external interface EI
|
||||
|
||||
external fun createJsObjectAsAny(): Any
|
||||
external fun createJsObjectAsExternalInterface(): EI
|
||||
external fun getObjectValueEI(x: EI): String
|
||||
external fun getObjectValueAny(x: Any): String
|
||||
|
||||
fun box(): String {
|
||||
// Strings
|
||||
@@ -98,15 +96,6 @@ fun box(): String {
|
||||
val objAsEI: EI = createJsObjectAsExternalInterface()
|
||||
if (getObjectValueEI(objAsEI) != "object created by createJsObjectAsExternalInterface")
|
||||
return "Fail createJsObjectAsExternalInterface + getObjectValueEI"
|
||||
if (getObjectValueAny(objAsEI) != "object created by createJsObjectAsExternalInterface")
|
||||
return "Fail createJsObjectAsExternalInterface + getObjectValueAny"
|
||||
|
||||
// Any
|
||||
val objAsAny: Any = createJsObjectAsAny()
|
||||
if (getObjectValueAny(objAsAny) != "object created by createJsObjectAsAny")
|
||||
return "Fail createJsObjectAsAny + getObjectValueAny"
|
||||
if (getObjectValueEI(objAsAny as EI) != "object created by createJsObjectAsAny")
|
||||
return "Fail createJsObjectAsAny + getObjectValueEI"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Reference in New Issue
Block a user