Skip to content
This repository was archived by the owner on Jul 12, 2024. It is now read-only.

Commit e2a87b4

Browse files
committed
Fix #75: Use WebAssembly.JSTag as our exception tag.
This allows us to actually catch exceptions thrown by JavaScript code.
1 parent aac88e6 commit e2a87b4

File tree

7 files changed

+28
-14
lines changed

7 files changed

+28
-14
lines changed

build.sbt

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -228,15 +228,14 @@ lazy val IgnoredTestNames: Set[String] = {
228228
Set(
229229
// reflective call: should be throw an exception when reflective proxy not found
230230
"org.scalajs.testsuite.compiler.WasPublicBeforeTyperTestScala2",
231-
// Various run-time errors and JS exceptions
232-
"org.scalajs.testsuite.compiler.InteroperabilityTest",
231+
// javaLangClassGetNameRenamedThroughSemantics failed: org.junit.ComparisonFailure:
232+
// expected:<[renamed.test.]Class> but was:<[org.scalajs.testsuite.compiler.ReflectionTest$RenamedTest]Class>
233233
"org.scalajs.testsuite.compiler.ReflectionTest",
234-
"org.scalajs.testsuite.compiler.RegressionJSTest",
235-
"org.scalajs.testsuite.jsinterop.FunctionTest",
236-
"org.scalajs.testsuite.jsinterop.MiscInteropTest",
237-
"org.scalajs.testsuite.jsinterop.NonNativeJSTypeTest",
238-
"org.scalajs.testsuite.jsinterop.SpecialTest",
234+
// wellKnownSymbolIterator/testToString failed: scala.scalajs.js.JavaScriptException: TypeError: Cannot convert a Symbol value to a string
239235
"org.scalajs.testsuite.jsinterop.SymbolTest",
236+
// Cannot call wasmObject.toString() from JavaScript:
237+
// boxValueClassesGivenToJSInteropMethod failed: scala.scalajs.js.JavaScriptException: TypeError: vc.toString is not a function
238+
"org.scalajs.testsuite.compiler.InteroperabilityTest",
240239
// TypeError: WebAssembly objects are opaque
241240
"org.scalajs.testsuite.javalib.lang.SystemJSTest",
242241
// throwablesAreTrueErrors failed: org.junit.ComparisonFailure: expected:<[object [Error]]> but was:<[object [Object]]>

wasm/src/main/scala/ir2wasm/HelperFunctions.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,7 @@ object HelperFunctions {
690690
)
691691
instrs += CALL(WasmFunctionName.jsArrayPush)
692692
instrs += CALL(WasmFunctionName.jsNew)
693+
instrs += EXTERN_CONVERT_ANY
693694
instrs += THROW(ctx.exceptionTagName)
694695
}
695696
) { () =>

wasm/src/main/scala/ir2wasm/LoaderContent.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ const linkingInfo = Object.freeze({
6565
});
6666

6767
const scalaJSHelpers = {
68+
// JSTag
69+
JSTag: WebAssembly.JSTag,
70+
6871
// BinaryOp.===
6972
is: Object.is,
7073

wasm/src/main/scala/ir2wasm/WasmExpressionBuilder.scala

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1712,27 +1712,29 @@ private class WasmExpressionBuilder private (
17121712
genTree(t.block, t.tpe)
17131713
instrs += CATCH(ctx.exceptionTagName)
17141714
fctx.withNewLocal(t.errVar.name, Types.WasmRefType.anyref) { exceptionLocal =>
1715+
instrs += ANY_CONVERT_EXTERN
17151716
instrs += LOCAL_SET(exceptionLocal)
17161717
genTree(t.handler, t.tpe)
17171718
}
17181719
instrs += END
17191720
} else {
17201721
fctx.block(resultType) { doneLabel =>
1721-
fctx.block(Types.WasmRefType.anyref) { catchLabel =>
1722-
/* We used to have `resultType` as result of the try_table, wich the
1722+
fctx.block(Types.WasmRefType.externref) { catchLabel =>
1723+
/* We used to have `resultType` as result of the try_table, with the
17231724
* `BR(doneLabel)` outside of the try_table. Unfortunately it seems
17241725
* V8 cannot handle try_table with a result type that is `(ref ...)`.
1725-
* The current encoding with `anyref` as result type (to match the
1726+
* The current encoding with `externref` as result type (to match the
17261727
* enclosing block) and the `br` *inside* the `try_table` works.
17271728
*/
1728-
fctx.tryTable(Types.WasmRefType.anyref)(
1729+
fctx.tryTable(Types.WasmRefType.externref)(
17291730
List(CatchClause.Catch(ctx.exceptionTagName, catchLabel))
17301731
) {
17311732
genTree(t.block, t.tpe)
17321733
instrs += BR(doneLabel)
17331734
}
17341735
} // end block $catch
17351736
fctx.withNewLocal(t.errVar.name, Types.WasmRefType.anyref) { exceptionLocal =>
1737+
instrs += ANY_CONVERT_EXTERN
17361738
instrs += LOCAL_SET(exceptionLocal)
17371739
genTree(t.handler, t.tpe)
17381740
}
@@ -1790,6 +1792,7 @@ private class WasmExpressionBuilder private (
17901792

17911793
private def genThrow(tree: IRTrees.Throw): IRTypes.Type = {
17921794
genTree(tree.expr, IRTypes.AnyType)
1795+
instrs += EXTERN_CONVERT_ANY
17931796
instrs += THROW(ctx.exceptionTagName)
17941797

17951798
IRTypes.NothingType

wasm/src/main/scala/wasm4s/Instructions.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,9 @@ object WasmInstr {
305305
*/
306306
case class REF_FUNC(i: WasmFunctionName) extends WasmFuncInstr("ref.func", 0xD2, i)
307307

308+
case object ANY_CONVERT_EXTERN extends WasmSimpleInstr("any.convert_extern", 0xFB1A)
309+
case object EXTERN_CONVERT_ANY extends WasmSimpleInstr("extern.convert_any", 0xFB1B)
310+
308311
case object REF_I31 extends WasmSimpleInstr("ref.i31", 0xFB1C)
309312
case object I31_GET_S extends WasmSimpleInstr("i31.get_s", 0xFB1D)
310313
case object I31_GET_U extends WasmSimpleInstr("i31.get_u", 0xFB1E)

wasm/src/main/scala/wasm4s/Types.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ object Types {
5454
/** `(ref extern)`. */
5555
val extern: WasmRefType = apply(WasmHeapType.Extern)
5656

57+
/** `(ref null extern)`, i.e., `externref`. */
58+
val externref: WasmRefType = nullable(WasmHeapType.Extern)
59+
5760
/** `(ref null exn)`, i.e., `exnref`. */
5861
val exnref: WasmRefType = nullable(WasmHeapType.Exn)
5962

wasm/src/main/scala/wasm4s/WasmContext.scala

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -335,9 +335,11 @@ class WasmContext(val module: WasmModule) extends TypeDefinableWasmContext {
335335
val exceptionTagName: WasmTagName = WasmTagName("exception")
336336

337337
locally {
338-
val exceptionSig = WasmFunctionSignature(List(anyref), Nil)
339-
val exceptionFunType = addFunctionType(exceptionSig)
340-
module.addTag(WasmTag(exceptionTagName, exceptionFunType))
338+
val exceptionSig = WasmFunctionSignature(List(WasmRefType.externref), Nil)
339+
val typ = WasmFunctionType(addFunctionType(exceptionSig), exceptionSig)
340+
module.addImport(
341+
WasmImport("__scalaJSHelpers", "JSTag", WasmImportDesc.Tag(exceptionTagName, typ))
342+
)
341343
}
342344

343345
private def addHelperImport(

0 commit comments

Comments
 (0)