diff options
author | Heejin Ahn <aheejin@gmail.com> | 2019-08-13 00:29:26 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-08-13 00:29:26 +0900 |
commit | e2f49d8227f2b71e4dede5cf4074bb9f65e3d77f (patch) | |
tree | 30b132b02824839d1d7718ed32c6b90cc0828151 /src/js/binaryen.js-post.js | |
parent | 69ad1e8a8d2e1d395e30230433742f4f5668563b (diff) | |
download | binaryen-e2f49d8227f2b71e4dede5cf4074bb9f65e3d77f.tar.gz binaryen-e2f49d8227f2b71e4dede5cf4074bb9f65e3d77f.tar.bz2 binaryen-e2f49d8227f2b71e4dede5cf4074bb9f65e3d77f.zip |
Add basic exception handling support (#2282)
This adds basic support for exception handling instructions, according
to the spec:
https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md
This PR includes support for:
- Binary reading/writing
- Wast reading/writing
- Stack IR
- Validation
- binaryen.js + C API
- Few IR routines: branch-utils, type-updating, etc
- Few passes: just enough to make `wasm-opt -O` pass
- Tests
This PR does not include support for many optimization passes, fuzzer,
or interpreter. They will be follow-up PRs.
Try-catch construct is modeled in Binaryen IR in a similar manner to
that of if-else: each of try body and catch body will contain a block,
which can be omitted if there is only a single instruction. This block
will not be emitted in wast or binary, as in if-else. As in if-else,
`class Try` contains two expressions each for try body and catch body,
and `catch` is not modeled as an instruction. `exnref` value pushed by
`catch` is get by `pop` instruction.
`br_on_exn` is special: it returns different types of values when taken
and not taken. We make `exnref`, the type `br_on_exn` pushes if not
taken, as `br_on_exn`'s type.
Diffstat (limited to 'src/js/binaryen.js-post.js')
-rw-r--r-- | src/js/binaryen.js-post.js | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js index e08d3cf4d..a09ad76ab 100644 --- a/src/js/binaryen.js-post.js +++ b/src/js/binaryen.js-post.js @@ -78,6 +78,10 @@ Module['MemoryInitId'] = Module['_BinaryenMemoryInitId'](); Module['DataDropId'] = Module['_BinaryenDataDropId'](); Module['MemoryCopyId'] = Module['_BinaryenMemoryCopyId'](); Module['MemoryFillId'] = Module['_BinaryenMemoryFillId'](); +Module['TryId'] = Module['_BinaryenTryId'](); +Module['ThrowId'] = Module['_BinaryenThrowId'](); +Module['RethrowId'] = Module['_BinaryenRethrowId'](); +Module['BrOnExnId'] = Module['_BinaryenBrOnExnId'](); Module['PushId'] = Module['_BinaryenPushId'](); Module['PopId'] = Module['_BinaryenPopId'](); @@ -1771,6 +1775,22 @@ function wrapModule(module, self) { self['notify'] = function(ptr, notifyCount) { return Module['_BinaryenAtomicNotify'](module, ptr, notifyCount); }; + self['try'] = function(body, catchBody) { + return Module['_BinaryenTry'](module, body, catchBody); + }; + self['throw'] = function(event_, operands) { + return preserveStack(function() { + return Module['_BinaryenThrow'](module, strToStack(event_), i32sToStack(operands), operands.length); + }); + }; + self['rethrow'] = function(exnref) { + return Module['_BinaryenRethrow'](module, exnref); + }; + self['br_on_exn'] = function(label, event_, exnref) { + return preserveStack(function() { + return Module['_BinaryenBrOnExn'](module, strToStack(label), strToStack(event_), exnref); + }); + }; self['push'] = function(value) { return Module['_BinaryenPush'](module, value); }; @@ -2376,6 +2396,34 @@ Module['getExpressionInfo'] = function(expr) { 'value': Module['_BinaryenMemoryFillGetValue'](expr), 'size': Module['_BinaryenMemoryFillGetSize'](expr) }; + case Module['TryId']: + return { + 'id': id, + 'type': type, + 'body': Module['_BinaryenTryGetBody'](expr), + 'catchBody': Module['_BinaryenTryGetCatchBody'](expr) + }; + case Module['ThrowId']: + return { + 'id': id, + 'type': type, + 'event': UTF8ToString(Module['_BinaryenThrowGetEvent'](expr)), + 'operands': getAllNested(expr, Module['_BinaryenThrowGetNumOperands'], Module['_BinaryenThrowGetOperand']) + }; + case Module['RethrowId']: + return { + 'id': id, + 'type': type, + 'exnref': Module['_BinaryenRethrowGetExnref'](expr) + }; + case Module['BrOnExnId']: + return { + 'id': id, + 'type': type, + 'name': UTF8ToString(Module['_BinaryenBrOnExnGetName'](expr)), + 'event': UTF8ToString(Module['_BinaryenBrOnExnGetEvent'](expr)), + 'exnref': Module['_BinaryenBrOnExnGetExnref'](expr) + }; case Module['PushId']: return { 'id': id, |