diff options
author | Heejin Ahn <aheejin@gmail.com> | 2019-07-24 23:57:04 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-07-24 23:57:04 -0700 |
commit | 443c0069df34bac9640ed75e396c8b76d3870ae0 (patch) | |
tree | 95869cd8599bf83689b7329a5ecc180622091a17 /src | |
parent | 7bf827d38eb710069662b99eed6ba9ece20775c1 (diff) | |
download | binaryen-443c0069df34bac9640ed75e396c8b76d3870ae0.tar.gz binaryen-443c0069df34bac9640ed75e396c8b76d3870ae0.tar.bz2 binaryen-443c0069df34bac9640ed75e396c8b76d3870ae0.zip |
More push/pop support (#2260)
This adds
- `push`/`pop` support for other types: v128 and exnref
- `push`/`pop` support for binaryen.js
Because binaryen.js follows Binaryen's AST structure, without `pop` in
binaryen.js, EH instructions cannot be represented in binaryen.js.
Diffstat (limited to 'src')
-rw-r--r-- | src/binaryen-c.cpp | 27 | ||||
-rw-r--r-- | src/binaryen-c.h | 7 | ||||
-rw-r--r-- | src/gen-s-parser.inc | 17 | ||||
-rw-r--r-- | src/js/binaryen.js-post.js | 32 |
4 files changed, 80 insertions, 3 deletions
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index b34a28e5b..81eff0c8a 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -354,6 +354,8 @@ BinaryenExpressionId BinaryenMemoryCopyId(void) { BinaryenExpressionId BinaryenMemoryFillId(void) { return Expression::Id::MemoryFillId; } +BinaryenExpressionId BinaryenPushId(void) { return Expression::Id::PushId; } +BinaryenExpressionId BinaryenPopId(void) { return Expression::Id::PopId; } // External kinds @@ -1573,6 +1575,21 @@ BinaryenExpressionRef BinaryenMemoryFill(BinaryenModuleRef module, } return static_cast<Expression*>(ret); } +BinaryenExpressionRef BinaryenPush(BinaryenModuleRef module, + BinaryenExpressionRef value) { + auto* ret = Builder(*(Module*)module).makePush((Expression*)value); + if (tracing) { + traceExpression(ret, "BinaryenPush", value); + } + return static_cast<Expression*>(ret); +} +BinaryenExpressionRef BinaryenPop(BinaryenModuleRef module, BinaryenType type) { + auto* ret = Builder(*(Module*)module).makePop(Type(type)); + if (tracing) { + traceExpression(ret, "BinaryenPop", type); + } + return static_cast<Expression*>(ret); +} // Expression utility @@ -2704,6 +2721,16 @@ BinaryenExpressionRef BinaryenMemoryFillGetSize(BinaryenExpressionRef expr) { assert(expression->is<MemoryFill>()); return static_cast<MemoryFill*>(expression)->size; } +BinaryenExpressionRef BinaryenPushGetValue(BinaryenExpressionRef expr) { + if (tracing) { + std::cout << " BinaryenPushGetValue(expressions[" << expressions[expr] + << "]);\n"; + } + + auto* expression = (Expression*)expr; + assert(expression->is<Push>()); + return static_cast<Push*>(expression)->value; +} // Functions diff --git a/src/binaryen-c.h b/src/binaryen-c.h index db49c45c9..dc5d50fef 100644 --- a/src/binaryen-c.h +++ b/src/binaryen-c.h @@ -127,6 +127,8 @@ BinaryenExpressionId BinaryenMemoryInitId(void); BinaryenExpressionId BinaryenDataDropId(void); BinaryenExpressionId BinaryenMemoryCopyId(void); BinaryenExpressionId BinaryenMemoryFillId(void); +BinaryenExpressionId BinaryenPushId(void); +BinaryenExpressionId BinaryenPopId(void); // External kinds (call to get the value of each; you can cache them) @@ -699,6 +701,9 @@ BinaryenExpressionRef BinaryenMemoryFill(BinaryenModuleRef module, BinaryenExpressionRef dest, BinaryenExpressionRef value, BinaryenExpressionRef size); +BinaryenExpressionRef BinaryenPush(BinaryenModuleRef module, + BinaryenExpressionRef value); +BinaryenExpressionRef BinaryenPop(BinaryenModuleRef module, BinaryenType type); BinaryenExpressionId BinaryenExpressionGetId(BinaryenExpressionRef expr); BinaryenType BinaryenExpressionGetType(BinaryenExpressionRef expr); @@ -850,6 +855,8 @@ BinaryenExpressionRef BinaryenMemoryFillGetDest(BinaryenExpressionRef expr); BinaryenExpressionRef BinaryenMemoryFillGetValue(BinaryenExpressionRef expr); BinaryenExpressionRef BinaryenMemoryFillGetSize(BinaryenExpressionRef expr); +BinaryenExpressionRef BinaryenPushGetValue(BinaryenExpressionRef expr); + // Functions typedef void* BinaryenFunctionRef; diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc index 93d2f7578..3fcb18000 100644 --- a/src/gen-s-parser.inc +++ b/src/gen-s-parser.inc @@ -59,9 +59,17 @@ switch (op[0]) { default: goto parse_error; } } - case 'e': - if (strcmp(op, "else") == 0) { return makeThenOrElse(s); } - goto parse_error; + case 'e': { + switch (op[1]) { + case 'l': + if (strcmp(op, "else") == 0) { return makeThenOrElse(s); } + goto parse_error; + case 'x': + if (strcmp(op, "exnref.pop") == 0) { return makePop(exnref); } + goto parse_error; + default: goto parse_error; + } + } case 'f': { switch (op[1]) { case '3': { @@ -2278,6 +2286,9 @@ switch (op[0]) { case 'o': if (strcmp(op, "v128.or") == 0) { return makeBinary(s, BinaryOp::OrVec128); } goto parse_error; + case 'p': + if (strcmp(op, "v128.pop") == 0) { return makePop(v128); } + goto parse_error; case 's': if (strcmp(op, "v128.store") == 0) { return makeStore(s, v128, /*isAtomic=*/false); } goto parse_error; diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js index 5b24f3a8f..e08d3cf4d 100644 --- a/src/js/binaryen.js-post.js +++ b/src/js/binaryen.js-post.js @@ -78,6 +78,8 @@ Module['MemoryInitId'] = Module['_BinaryenMemoryInitId'](); Module['DataDropId'] = Module['_BinaryenDataDropId'](); Module['MemoryCopyId'] = Module['_BinaryenMemoryCopyId'](); Module['MemoryFillId'] = Module['_BinaryenMemoryFillId'](); +Module['PushId'] = Module['_BinaryenPushId'](); +Module['PopId'] = Module['_BinaryenPopId'](); // External kinds Module['ExternalFunction'] = Module['_BinaryenExternalFunction'](); @@ -761,6 +763,9 @@ function wrapModule(module, self) { 'wait': function(ptr, expected, timeout) { return Module['_BinaryenAtomicWait'](module, ptr, expected, timeout, Module['i32']); }, + 'pop': function() { + return Module['_BinaryenPop'](module, Module['i32']); + } }; self['i64'] = { @@ -1062,6 +1067,9 @@ function wrapModule(module, self) { 'wait': function(ptr, expected, timeout) { return Module['_BinaryenAtomicWait'](module, ptr, expected, timeout, Module['i64']); }, + 'pop': function() { + return Module['_BinaryenPop'](module, Module['i64']); + } }; self['f32'] = { @@ -1167,6 +1175,9 @@ function wrapModule(module, self) { 'ge': function(left, right) { return Module['_BinaryenBinary'](module, Module['GeFloat32'], left, right); }, + 'pop': function() { + return Module['_BinaryenPop'](module, Module['f32']); + } }; self['f64'] = { @@ -1272,6 +1283,9 @@ function wrapModule(module, self) { 'ge': function(left, right) { return Module['_BinaryenBinary'](module, Module['GeFloat64'], left, right); }, + 'pop': function() { + return Module['_BinaryenPop'](module, Module['f64']); + } }; self['v128'] = { @@ -1302,6 +1316,9 @@ function wrapModule(module, self) { }, 'bitselect': function(left, right, cond) { return Module['_BinaryenSIMDBitselect'](module, left, right, cond); + }, + 'pop': function() { + return Module['_BinaryenPop'](module, Module['v128']); } }; @@ -1724,6 +1741,12 @@ function wrapModule(module, self) { }, }; + self['exnref'] = { + 'pop': function() { + return Module['_BinaryenPop'](module, Module['exnref']); + } + }; + self['select'] = function(condition, ifTrue, ifFalse) { return Module['_BinaryenSelect'](module, condition, ifTrue, ifFalse); }; @@ -1748,6 +1771,9 @@ function wrapModule(module, self) { self['notify'] = function(ptr, notifyCount) { return Module['_BinaryenAtomicNotify'](module, ptr, notifyCount); }; + self['push'] = function(value) { + return Module['_BinaryenPush'](module, value); + }; // 'Module' operations self['addFunctionType'] = function(name, result, paramTypes) { @@ -2225,6 +2251,7 @@ Module['getExpressionInfo'] = function(expr) { }; case Module['NopId']: case Module['UnreachableId']: + case Module['PopId']: return { 'id': id, 'type': type @@ -2349,6 +2376,11 @@ Module['getExpressionInfo'] = function(expr) { 'value': Module['_BinaryenMemoryFillGetValue'](expr), 'size': Module['_BinaryenMemoryFillGetSize'](expr) }; + case Module['PushId']: + return { + 'id': id, + 'value': Module['_BinaryenPushGetValue'](expr) + }; default: throw Error('unexpected id: ' + id); |