diff --git a/CHANGELOG.md b/CHANGELOG.md index cc458ac1902..16e6d9c4792 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,14 @@ Current Trunk Rename old lists to be clearer and more consistent with that, so now there is "remove list" to remove, "add list" to add, and "only list" which if set means that only those functions should be instrumented and nothing else. +- Renamed various ambiguous C-API functions for consistency: + - `BinaryenBlockGetChild` to `BinaryenBlockGetChildAt` + - `BinaryenSwitchGetName` to `BinaryenSwitchGetNameAt` + - `BinaryenCallGetOperand` to `BinaryenCallGetOperandAt` + - `BinaryenCallIndirectGetOperand` to `BinaryenCallIndirectGetOperandAt` + - `BinaryenHostGetOperand` to `BinaryenHostGetOperandAt` + - `BinaryenThrowGetOperand` to `BinaryenThrowGetOperandAt` + - `BinaryenTupleMakeGetOperand` to `BinaryenTupleMakeGetOperandAt` v94 --- diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index f4df69737cc..517ed42a60b 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -1167,6 +1167,7 @@ BinaryenExpressionRef BinaryenSIMDShuffle(BinaryenModuleRef module, BinaryenExpressionRef left, BinaryenExpressionRef right, const uint8_t mask_[16]) { + assert(mask_); // nullptr would be wrong std::array mask; memcpy(mask.data(), mask_, 16); return static_cast( @@ -1307,7 +1308,7 @@ BinaryenExpressionRef BinaryenBrOnExn(BinaryenModuleRef module, const char* eventName, BinaryenExpressionRef exnref) { auto* wasm = (Module*)module; - Event* event = wasm->getEventOrNull(eventName); + auto* event = wasm->getEventOrNull(eventName); assert(event && "br_on_exn's event must exist"); return static_cast( Builder(*wasm).makeBrOnExn(name, event, (Expression*)exnref)); @@ -1321,10 +1322,16 @@ BinaryenExpressionId BinaryenExpressionGetId(BinaryenExpressionRef expr) { BinaryenType BinaryenExpressionGetType(BinaryenExpressionRef expr) { return ((Expression*)expr)->type.getID(); } +void BinaryenExpressionSetType(BinaryenExpressionRef expr, BinaryenType type) { + ((Expression*)expr)->type = Type(type); +} void BinaryenExpressionPrint(BinaryenExpressionRef expr) { WasmPrinter::printExpression((Expression*)expr, std::cout); std::cout << '\n'; } +void BinaryenExpressionFinalize(BinaryenExpressionRef expr) { + ReFinalizeNode().visit((Expression*)expr); +} BinaryenExpressionRef BinaryenExpressionCopy(BinaryenExpressionRef expr, BinaryenModuleRef module) { @@ -1339,702 +1346,1690 @@ const char* BinaryenBlockGetName(BinaryenExpressionRef expr) { assert(expression->is()); return static_cast(expression)->name.c_str(); } +void BinaryenBlockSetName(BinaryenExpressionRef expr, const char* name) { + auto* expression = (Expression*)expr; + assert(expression->is()); + // may be null or empty + static_cast(expression)->name = name; +} BinaryenIndex BinaryenBlockGetNumChildren(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->list.size(); } -BinaryenExpressionRef BinaryenBlockGetChild(BinaryenExpressionRef expr, - BinaryenIndex index) { +BinaryenExpressionRef BinaryenBlockGetChildAt(BinaryenExpressionRef expr, + BinaryenIndex index) { auto* expression = (Expression*)expr; assert(expression->is()); assert(index < static_cast(expression)->list.size()); return static_cast(expression)->list[index]; } +void BinaryenBlockSetChildAt(BinaryenExpressionRef expr, + BinaryenIndex index, + BinaryenExpressionRef childExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(childExpr); + auto& list = static_cast(expression)->list; + assert(index < list.size()); + list[index] = (Expression*)childExpr; +} +BinaryenIndex BinaryenBlockAppendChild(BinaryenExpressionRef expr, + BinaryenExpressionRef childExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(childExpr); + auto& list = static_cast(expression)->list; + auto index = list.size(); + list.push_back((Expression*)childExpr); + return index; +} +void BinaryenBlockInsertChildAt(BinaryenExpressionRef expr, + BinaryenIndex index, + BinaryenExpressionRef childExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(childExpr); + static_cast(expression)->list.insertAt(index, (Expression*)childExpr); +} +BinaryenExpressionRef BinaryenBlockRemoveChildAt(BinaryenExpressionRef expr, + BinaryenIndex index) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->list.removeAt(index); +} // If BinaryenExpressionRef BinaryenIfGetCondition(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->condition; } +void BinaryenIfSetCondition(BinaryenExpressionRef expr, + BinaryenExpressionRef condExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(condExpr); + static_cast(expression)->condition = (Expression*)condExpr; +} BinaryenExpressionRef BinaryenIfGetIfTrue(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->ifTrue; } +void BinaryenIfSetIfTrue(BinaryenExpressionRef expr, + BinaryenExpressionRef ifTrueExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(ifTrueExpr); + static_cast(expression)->ifTrue = (Expression*)ifTrueExpr; +} BinaryenExpressionRef BinaryenIfGetIfFalse(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->ifFalse; } +void BinaryenIfSetIfFalse(BinaryenExpressionRef expr, + BinaryenExpressionRef ifFalseExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + // may be null + static_cast(expression)->ifFalse = (Expression*)ifFalseExpr; +} // Loop const char* BinaryenLoopGetName(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->name.c_str(); } +void BinaryenLoopSetName(BinaryenExpressionRef expr, const char* name) { + auto* expression = (Expression*)expr; + assert(expression->is()); + // may be null or empty + static_cast(expression)->name = name; +} BinaryenExpressionRef BinaryenLoopGetBody(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->body; } +void BinaryenLoopSetBody(BinaryenExpressionRef expr, + BinaryenExpressionRef bodyExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(bodyExpr); + static_cast(expression)->body = (Expression*)bodyExpr; +} // Break const char* BinaryenBreakGetName(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->name.c_str(); } +void BinaryenBreakSetName(BinaryenExpressionRef expr, const char* name) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(name); + static_cast(expression)->name = name; +} BinaryenExpressionRef BinaryenBreakGetCondition(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->condition; } +void BinaryenBreakSetCondition(BinaryenExpressionRef expr, + BinaryenExpressionRef condExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + // may be null (br) + static_cast(expression)->condition = (Expression*)condExpr; +} BinaryenExpressionRef BinaryenBreakGetValue(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->value; } +void BinaryenBreakSetValue(BinaryenExpressionRef expr, + BinaryenExpressionRef valueExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + // may be null + static_cast(expression)->value = (Expression*)valueExpr; +} // Switch BinaryenIndex BinaryenSwitchGetNumNames(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->targets.size(); } -const char* BinaryenSwitchGetName(BinaryenExpressionRef expr, - BinaryenIndex index) { +const char* BinaryenSwitchGetNameAt(BinaryenExpressionRef expr, + BinaryenIndex index) { auto* expression = (Expression*)expr; assert(expression->is()); assert(index < static_cast(expression)->targets.size()); return static_cast(expression)->targets[index].c_str(); } +void BinaryenSwitchSetNameAt(BinaryenExpressionRef expr, + BinaryenIndex index, + const char* name) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(index < static_cast(expression)->targets.size()); + assert(name); + static_cast(expression)->targets[index] = name; +} +BinaryenIndex BinaryenSwitchAppendName(BinaryenExpressionRef expr, + const char* name) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(name); + auto& list = static_cast(expression)->targets; + auto index = list.size(); + list.push_back(name); + return index; +} +void BinaryenSwitchInsertNameAt(BinaryenExpressionRef expr, + BinaryenIndex index, + const char* name) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(name); + static_cast(expression)->targets.insertAt(index, name); +} +const char* BinaryenSwitchRemoveNameAt(BinaryenExpressionRef expr, + BinaryenIndex index) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->targets.removeAt(index).c_str(); +} const char* BinaryenSwitchGetDefaultName(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->default_.c_str(); } +void BinaryenSwitchSetDefaultName(BinaryenExpressionRef expr, + const char* name) { + auto* expression = (Expression*)expr; + assert(expression->is()); + // may be null or empty + static_cast(expression)->default_ = name; +} BinaryenExpressionRef BinaryenSwitchGetCondition(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->condition; } +void BinaryenSwitchSetCondition(BinaryenExpressionRef expr, + BinaryenExpressionRef condExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(condExpr); + static_cast(expression)->condition = (Expression*)condExpr; +} BinaryenExpressionRef BinaryenSwitchGetValue(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->value; } -// Call -int BinaryenCallIsReturn(BinaryenExpressionRef expr) { +void BinaryenSwitchSetValue(BinaryenExpressionRef expr, + BinaryenExpressionRef valueExpr) { auto* expression = (Expression*)expr; - assert(expression->is()); - return static_cast(expression)->isReturn; + assert(expression->is()); + // may be null + static_cast(expression)->value = (Expression*)valueExpr; } +// Call const char* BinaryenCallGetTarget(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->target.c_str(); } +void BinaryenCallSetTarget(BinaryenExpressionRef expr, const char* target) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(target); + static_cast(expression)->target = target; +} BinaryenIndex BinaryenCallGetNumOperands(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->operands.size(); } -BinaryenExpressionRef BinaryenCallGetOperand(BinaryenExpressionRef expr, - BinaryenIndex index) { +BinaryenExpressionRef BinaryenCallGetOperandAt(BinaryenExpressionRef expr, + BinaryenIndex index) { auto* expression = (Expression*)expr; assert(expression->is()); assert(index < static_cast(expression)->operands.size()); return static_cast(expression)->operands[index]; } -// CallIndirect -int BinaryenCallIndirectIsReturn(BinaryenExpressionRef expr) { +void BinaryenCallSetOperandAt(BinaryenExpressionRef expr, + BinaryenIndex index, + BinaryenExpressionRef operandExpr) { auto* expression = (Expression*)expr; - assert(expression->is()); - return static_cast(expression)->isReturn; + assert(expression->is()); + assert(index < static_cast(expression)->operands.size()); + assert(operandExpr); + static_cast(expression)->operands[index] = (Expression*)operandExpr; +} +BinaryenIndex BinaryenCallAppendOperand(BinaryenExpressionRef expr, + BinaryenExpressionRef operandExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(operandExpr); + auto& list = static_cast(expression)->operands; + auto index = list.size(); + list.push_back((Expression*)operandExpr); + return index; +} +void BinaryenCallInsertOperandAt(BinaryenExpressionRef expr, + BinaryenIndex index, + BinaryenExpressionRef operandExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(operandExpr); + static_cast(expression) + ->operands.insertAt(index, (Expression*)operandExpr); +} +BinaryenExpressionRef BinaryenCallRemoveOperandAt(BinaryenExpressionRef expr, + BinaryenIndex index) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->operands.removeAt(index); +} +int BinaryenCallIsReturn(BinaryenExpressionRef expr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->isReturn; } +void BinaryenCallSetReturn(BinaryenExpressionRef expr, int isReturn) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->isReturn = isReturn != 0; +} +// CallIndirect BinaryenExpressionRef BinaryenCallIndirectGetTarget(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->target; } +void BinaryenCallIndirectSetTarget(BinaryenExpressionRef expr, + BinaryenExpressionRef targetExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(targetExpr); + static_cast(expression)->target = (Expression*)targetExpr; +} BinaryenIndex BinaryenCallIndirectGetNumOperands(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->operands.size(); } -BinaryenExpressionRef BinaryenCallIndirectGetOperand(BinaryenExpressionRef expr, - BinaryenIndex index) { +BinaryenExpressionRef +BinaryenCallIndirectGetOperandAt(BinaryenExpressionRef expr, + BinaryenIndex index) { auto* expression = (Expression*)expr; assert(expression->is()); assert(index < static_cast(expression)->operands.size()); return static_cast(expression)->operands[index]; } +void BinaryenCallIndirectSetOperandAt(BinaryenExpressionRef expr, + BinaryenIndex index, + BinaryenExpressionRef operandExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(index < static_cast(expression)->operands.size()); + assert(operandExpr); + static_cast(expression)->operands[index] = + (Expression*)operandExpr; +} +BinaryenIndex +BinaryenCallIndirectAppendOperand(BinaryenExpressionRef expr, + BinaryenExpressionRef operandExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(operandExpr); + auto& list = static_cast(expression)->operands; + auto index = list.size(); + list.push_back((Expression*)operandExpr); + return index; +} +void BinaryenCallIndirectInsertOperandAt(BinaryenExpressionRef expr, + BinaryenIndex index, + BinaryenExpressionRef operandExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(operandExpr); + static_cast(expression) + ->operands.insertAt(index, (Expression*)operandExpr); +} +BinaryenExpressionRef +BinaryenCallIndirectRemoveOperandAt(BinaryenExpressionRef expr, + BinaryenIndex index) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->operands.removeAt(index); +} +int BinaryenCallIndirectIsReturn(BinaryenExpressionRef expr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->isReturn; +} +void BinaryenCallIndirectSetReturn(BinaryenExpressionRef expr, int isReturn) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->isReturn = isReturn != 0; +} +BinaryenType BinaryenCallIndirectGetParams(BinaryenExpressionRef expr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->sig.params.getID(); +} +void BinaryenCallIndirectSetParams(BinaryenExpressionRef expr, + BinaryenType params) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->sig.params = Type(params); +} +BinaryenType BinaryenCallIndirectGetResults(BinaryenExpressionRef expr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->sig.results.getID(); +} +void BinaryenCallIndirectSetResults(BinaryenExpressionRef expr, + BinaryenType results) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->sig.results = Type(results); +} // LocalGet BinaryenIndex BinaryenLocalGetGetIndex(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->index; } +void BinaryenLocalGetSetIndex(BinaryenExpressionRef expr, BinaryenIndex index) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->index = index; +} // LocalSet int BinaryenLocalSetIsTee(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->isTee(); + // has no setter } BinaryenIndex BinaryenLocalSetGetIndex(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->index; } +void BinaryenLocalSetSetIndex(BinaryenExpressionRef expr, BinaryenIndex index) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->index = index; +} BinaryenExpressionRef BinaryenLocalSetGetValue(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->value; } +void BinaryenLocalSetSetValue(BinaryenExpressionRef expr, + BinaryenExpressionRef valueExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(valueExpr); + static_cast(expression)->value = (Expression*)valueExpr; +} // GlobalGet const char* BinaryenGlobalGetGetName(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->name.c_str(); } +void BinaryenGlobalGetSetName(BinaryenExpressionRef expr, const char* name) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(name); + static_cast(expression)->name = name; +} // GlobalSet const char* BinaryenGlobalSetGetName(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->name.c_str(); } +void BinaryenGlobalSetSetName(BinaryenExpressionRef expr, const char* name) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(name); + static_cast(expression)->name = name; +} BinaryenExpressionRef BinaryenGlobalSetGetValue(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->value; } +void BinaryenGlobalSetSetValue(BinaryenExpressionRef expr, + BinaryenExpressionRef valueExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(valueExpr); + static_cast(expression)->value = (Expression*)valueExpr; +} // Host BinaryenOp BinaryenHostGetOp(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->op; } +void BinaryenHostSetOp(BinaryenExpressionRef expr, BinaryenOp op) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->op = (HostOp)op; +} const char* BinaryenHostGetNameOperand(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->nameOperand.c_str(); } +void BinaryenHostSetNameOperand(BinaryenExpressionRef expr, const char* name) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->nameOperand = name ? name : ""; +} BinaryenIndex BinaryenHostGetNumOperands(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->operands.size(); } -BinaryenExpressionRef BinaryenHostGetOperand(BinaryenExpressionRef expr, - BinaryenIndex index) { +BinaryenExpressionRef BinaryenHostGetOperandAt(BinaryenExpressionRef expr, + BinaryenIndex index) { auto* expression = (Expression*)expr; assert(expression->is()); assert(index < static_cast(expression)->operands.size()); return static_cast(expression)->operands[index]; } +void BinaryenHostSetOperandAt(BinaryenExpressionRef expr, + BinaryenIndex index, + BinaryenExpressionRef operandExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(index < static_cast(expression)->operands.size()); + assert(operandExpr); + static_cast(expression)->operands[index] = (Expression*)operandExpr; +} +BinaryenIndex BinaryenHostAppendOperand(BinaryenExpressionRef expr, + BinaryenExpressionRef operandExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(operandExpr); + auto& list = static_cast(expression)->operands; + auto index = list.size(); + list.push_back((Expression*)operandExpr); + return index; +} +void BinaryenHostInsertOperandAt(BinaryenExpressionRef expr, + BinaryenIndex index, + BinaryenExpressionRef operandExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(operandExpr); + static_cast(expression) + ->operands.insertAt(index, (Expression*)operandExpr); +} +BinaryenExpressionRef BinaryenHostRemoveOperandAt(BinaryenExpressionRef expr, + BinaryenIndex index) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->operands.removeAt(index); +} // Load int BinaryenLoadIsAtomic(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->isAtomic; } +void BinaryenLoadSetAtomic(BinaryenExpressionRef expr, int isAtomic) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->isAtomic = isAtomic != 0; +} int BinaryenLoadIsSigned(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->signed_; } +void BinaryenLoadSetSigned(BinaryenExpressionRef expr, int isSigned) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->signed_ = isSigned != 0; +} uint32_t BinaryenLoadGetBytes(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->bytes; } +void BinaryenLoadSetBytes(BinaryenExpressionRef expr, uint32_t bytes) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->bytes = bytes; +} uint32_t BinaryenLoadGetOffset(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->offset; } +void BinaryenLoadSetOffset(BinaryenExpressionRef expr, uint32_t offset) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->offset = offset; +} uint32_t BinaryenLoadGetAlign(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->align; } +void BinaryenLoadSetAlign(BinaryenExpressionRef expr, uint32_t align) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->align = align; +} BinaryenExpressionRef BinaryenLoadGetPtr(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->ptr; } +void BinaryenLoadSetPtr(BinaryenExpressionRef expr, + BinaryenExpressionRef ptrExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(ptrExpr); + static_cast(expression)->ptr = (Expression*)ptrExpr; +} // Store int BinaryenStoreIsAtomic(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->isAtomic; } +void BinaryenStoreSetAtomic(BinaryenExpressionRef expr, int isAtomic) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->isAtomic = isAtomic != 0; +} uint32_t BinaryenStoreGetBytes(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->bytes; } +void BinaryenStoreSetBytes(BinaryenExpressionRef expr, uint32_t bytes) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->bytes = bytes; +} uint32_t BinaryenStoreGetOffset(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->offset; } +void BinaryenStoreSetOffset(BinaryenExpressionRef expr, uint32_t offset) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->offset = offset; +} uint32_t BinaryenStoreGetAlign(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->align; } +void BinaryenStoreSetAlign(BinaryenExpressionRef expr, uint32_t align) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->align = align; +} BinaryenExpressionRef BinaryenStoreGetPtr(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->ptr; } +void BinaryenStoreSetPtr(BinaryenExpressionRef expr, + BinaryenExpressionRef ptrExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(ptrExpr); + static_cast(expression)->ptr = (Expression*)ptrExpr; +} BinaryenExpressionRef BinaryenStoreGetValue(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->value; } +void BinaryenStoreSetValue(BinaryenExpressionRef expr, + BinaryenExpressionRef valueExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(valueExpr); + static_cast(expression)->value = (Expression*)valueExpr; +} +BinaryenType BinaryenStoreGetValueType(BinaryenExpressionRef expr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->valueType.getID(); +} +void BinaryenStoreSetValueType(BinaryenExpressionRef expr, + BinaryenType valueType) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->valueType = Type(valueType); +} // Const int32_t BinaryenConstGetValueI32(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->value.geti32(); } +void BinaryenConstSetValueI32(BinaryenExpressionRef expr, int32_t value) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->value = Literal(value); +} int64_t BinaryenConstGetValueI64(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->value.geti64(); } +void BinaryenConstSetValueI64(BinaryenExpressionRef expr, int64_t value) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->value = Literal(value); +} int32_t BinaryenConstGetValueI64Low(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return (int32_t)(static_cast(expression)->value.geti64() & 0xffffffff); } +void BinaryenConstSetValueI64Low(BinaryenExpressionRef expr, int32_t valueLow) { + auto* expression = (Expression*)expr; + assert(expression->is()); + auto& value = static_cast(expression)->value; + int64_t valueI64 = value.type == Type::i64 ? value.geti64() : 0; + static_cast(expression)->value = + Literal((valueI64 & ~0xffffffff) | (int64_t(valueLow) & 0xffffffff)); +} int32_t BinaryenConstGetValueI64High(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return (int32_t)(static_cast(expression)->value.geti64() >> 32); } +void BinaryenConstSetValueI64High(BinaryenExpressionRef expr, + int32_t valueHigh) { + auto* expression = (Expression*)expr; + assert(expression->is()); + auto& value = static_cast(expression)->value; + int64_t valueI64 = value.type == Type::i64 ? value.geti64() : 0; + static_cast(expression)->value = + Literal((int64_t(valueHigh) << 32) | (valueI64 & 0xffffffff)); +} float BinaryenConstGetValueF32(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->value.getf32(); } +void BinaryenConstSetValueF32(BinaryenExpressionRef expr, float value) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->value = Literal(value); +} double BinaryenConstGetValueF64(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->value.getf64(); } +void BinaryenConstSetValueF64(BinaryenExpressionRef expr, double value) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->value = Literal(value); +} void BinaryenConstGetValueV128(BinaryenExpressionRef expr, uint8_t* out) { auto* expression = (Expression*)expr; assert(expression->is()); memcpy(out, static_cast(expression)->value.getv128().data(), 16); } +void BinaryenConstSetValueV128(BinaryenExpressionRef expr, + const uint8_t value[16]) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(value); // nullptr would be wrong + static_cast(expression)->value = Literal(value); +} // Unary BinaryenOp BinaryenUnaryGetOp(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->op; } +void BinaryenUnarySetOp(BinaryenExpressionRef expr, BinaryenOp op) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->op = UnaryOp(op); +} BinaryenExpressionRef BinaryenUnaryGetValue(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->value; } +void BinaryenUnarySetValue(BinaryenExpressionRef expr, + BinaryenExpressionRef valueExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(valueExpr); + static_cast(expression)->value = (Expression*)valueExpr; +} // Binary BinaryenOp BinaryenBinaryGetOp(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->op; } +void BinaryenBinarySetOp(BinaryenExpressionRef expr, BinaryenOp op) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->op = BinaryOp(op); +} BinaryenExpressionRef BinaryenBinaryGetLeft(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->left; } +void BinaryenBinarySetLeft(BinaryenExpressionRef expr, + BinaryenExpressionRef leftExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(leftExpr); + static_cast(expression)->left = (Expression*)leftExpr; +} BinaryenExpressionRef BinaryenBinaryGetRight(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->right; } +void BinaryenBinarySetRight(BinaryenExpressionRef expr, + BinaryenExpressionRef rightExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(rightExpr); + static_cast(expression)->right = (Expression*)rightExpr; +} // Select BinaryenExpressionRef BinaryenSelectGetIfTrue(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); + assert(ifTrueExpr); + static_cast(expression)->ifTrue = (Expression*)ifTrueExpr; +} BinaryenExpressionRef BinaryenSelectGetIfFalse(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); + assert(ifFalseExpr); + static_cast(expression)->ifFalse = (Expression*)ifFalseExpr; +} BinaryenExpressionRef BinaryenSelectGetCondition(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); + assert(condExpr); + static_cast(expression)->condition = (Expression*)condExpr; +} // Drop BinaryenExpressionRef BinaryenDropGetValue(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->value; } +void BinaryenDropSetValue(BinaryenExpressionRef expr, + BinaryenExpressionRef valueExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(valueExpr); + static_cast(expression)->value = (Expression*)valueExpr; +} // Return BinaryenExpressionRef BinaryenReturnGetValue(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->value; } +void BinaryenReturnSetValue(BinaryenExpressionRef expr, + BinaryenExpressionRef valueExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + // may be null + static_cast(expression)->value = (Expression*)valueExpr; +} // AtomicRMW BinaryenOp BinaryenAtomicRMWGetOp(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->op; } +void BinaryenAtomicRMWSetOp(BinaryenExpressionRef expr, BinaryenOp op) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->op = AtomicRMWOp(op); +} uint32_t BinaryenAtomicRMWGetBytes(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->bytes; } +void BinaryenAtomicRMWSetBytes(BinaryenExpressionRef expr, uint32_t bytes) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->bytes = bytes; +} uint32_t BinaryenAtomicRMWGetOffset(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->offset; } +void BinaryenAtomicRMWSetOffset(BinaryenExpressionRef expr, uint32_t offset) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->offset = offset; +} BinaryenExpressionRef BinaryenAtomicRMWGetPtr(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->ptr; } +void BinaryenAtomicRMWSetPtr(BinaryenExpressionRef expr, + BinaryenExpressionRef ptrExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(ptrExpr); + static_cast(expression)->ptr = (Expression*)ptrExpr; +} BinaryenExpressionRef BinaryenAtomicRMWGetValue(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->value; } +void BinaryenAtomicRMWSetValue(BinaryenExpressionRef expr, + BinaryenExpressionRef valueExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(valueExpr); + static_cast(expression)->value = (Expression*)valueExpr; +} // AtomicCmpxchg uint32_t BinaryenAtomicCmpxchgGetBytes(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->bytes; } +void BinaryenAtomicCmpxchgSetBytes(BinaryenExpressionRef expr, uint32_t bytes) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->bytes = bytes; +} uint32_t BinaryenAtomicCmpxchgGetOffset(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->offset; } +void BinaryenAtomicCmpxchgSetOffset(BinaryenExpressionRef expr, + uint32_t offset) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->offset = offset; +} BinaryenExpressionRef BinaryenAtomicCmpxchgGetPtr(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->ptr; } +void BinaryenAtomicCmpxchgSetPtr(BinaryenExpressionRef expr, + BinaryenExpressionRef ptrExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(ptrExpr); + static_cast(expression)->ptr = (Expression*)ptrExpr; +} BinaryenExpressionRef BinaryenAtomicCmpxchgGetExpected(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->expected; } +void BinaryenAtomicCmpxchgSetExpected(BinaryenExpressionRef expr, + BinaryenExpressionRef expectedExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(expectedExpr); + static_cast(expression)->expected = (Expression*)expectedExpr; +} BinaryenExpressionRef BinaryenAtomicCmpxchgGetReplacement(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->replacement; } +void BinaryenAtomicCmpxchgSetReplacement( + BinaryenExpressionRef expr, BinaryenExpressionRef replacementExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(replacementExpr); + static_cast(expression)->replacement = + (Expression*)replacementExpr; +} // AtomicWait BinaryenExpressionRef BinaryenAtomicWaitGetPtr(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->ptr; } +void BinaryenAtomicWaitSetPtr(BinaryenExpressionRef expr, + BinaryenExpressionRef ptrExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(ptrExpr); + static_cast(expression)->ptr = (Expression*)ptrExpr; +} BinaryenExpressionRef BinaryenAtomicWaitGetExpected(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->expected; } +void BinaryenAtomicWaitSetExpected(BinaryenExpressionRef expr, + BinaryenExpressionRef expectedExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(expectedExpr); + static_cast(expression)->expected = (Expression*)expectedExpr; +} BinaryenExpressionRef BinaryenAtomicWaitGetTimeout(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->timeout; } +void BinaryenAtomicWaitSetTimeout(BinaryenExpressionRef expr, + BinaryenExpressionRef timeoutExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(timeoutExpr); + static_cast(expression)->timeout = (Expression*)timeoutExpr; +} BinaryenType BinaryenAtomicWaitGetExpectedType(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->expectedType.getID(); } +void BinaryenAtomicWaitSetExpectedType(BinaryenExpressionRef expr, + BinaryenType expectedType) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->expectedType = Type(expectedType); +} // AtomicNotify BinaryenExpressionRef BinaryenAtomicNotifyGetPtr(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->ptr; } +void BinaryenAtomicNotifySetPtr(BinaryenExpressionRef expr, + BinaryenExpressionRef ptrExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(ptrExpr); + static_cast(expression)->ptr = (Expression*)ptrExpr; +} BinaryenExpressionRef BinaryenAtomicNotifyGetNotifyCount(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->notifyCount; } +void BinaryenAtomicNotifySetNotifyCount(BinaryenExpressionRef expr, + BinaryenExpressionRef notifyCountExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(notifyCountExpr); + static_cast(expression)->notifyCount = + (Expression*)notifyCountExpr; +} // AtomicFence uint8_t BinaryenAtomicFenceGetOrder(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->order; } +void BinaryenAtomicFenceSetOrder(BinaryenExpressionRef expr, uint8_t order) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->order = order; +} // SIMDExtract BinaryenOp BinaryenSIMDExtractGetOp(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->op; } +void BinaryenSIMDExtractSetOp(BinaryenExpressionRef expr, BinaryenOp op) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->op = SIMDExtractOp(op); +} BinaryenExpressionRef BinaryenSIMDExtractGetVec(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->vec; } +void BinaryenSIMDExtractSetVec(BinaryenExpressionRef expr, + BinaryenExpressionRef vecExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(vecExpr); + static_cast(expression)->vec = (Expression*)vecExpr; +} uint8_t BinaryenSIMDExtractGetIndex(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->index; } +void BinaryenSIMDExtractSetIndex(BinaryenExpressionRef expr, uint8_t index) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->index = index; +} // SIMDReplace BinaryenOp BinaryenSIMDReplaceGetOp(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->op; } +void BinaryenSIMDReplaceSetOp(BinaryenExpressionRef expr, BinaryenOp op) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->op = SIMDReplaceOp(op); +} BinaryenExpressionRef BinaryenSIMDReplaceGetVec(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->vec; } +void BinaryenSIMDReplaceSetVec(BinaryenExpressionRef expr, + BinaryenExpressionRef vecExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(vecExpr); + static_cast(expression)->vec = (Expression*)vecExpr; +} uint8_t BinaryenSIMDReplaceGetIndex(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->index; } +void BinaryenSIMDReplaceSetIndex(BinaryenExpressionRef expr, uint8_t index) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->index = index; +} BinaryenExpressionRef BinaryenSIMDReplaceGetValue(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->value; } +void BinaryenSIMDReplaceSetValue(BinaryenExpressionRef expr, + BinaryenExpressionRef valueExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(valueExpr); + static_cast(expression)->value = (Expression*)valueExpr; +} // SIMDShuffle BinaryenExpressionRef BinaryenSIMDShuffleGetLeft(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->left; } +void BinaryenSIMDShuffleSetLeft(BinaryenExpressionRef expr, + BinaryenExpressionRef leftExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(leftExpr); + static_cast(expression)->left = (Expression*)leftExpr; +} BinaryenExpressionRef BinaryenSIMDShuffleGetRight(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->right; } +void BinaryenSIMDShuffleSetRight(BinaryenExpressionRef expr, + BinaryenExpressionRef rightExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(rightExpr); + static_cast(expression)->right = (Expression*)rightExpr; +} void BinaryenSIMDShuffleGetMask(BinaryenExpressionRef expr, uint8_t* mask) { auto* expression = (Expression*)expr; assert(expression->is()); + assert(mask); // nullptr would be wrong memcpy(mask, static_cast(expression)->mask.data(), 16); } +void BinaryenSIMDShuffleSetMask(BinaryenExpressionRef expr, + const uint8_t mask_[16]) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(mask_); // nullptr would be wrong + auto& mask = static_cast(expression)->mask; + memcpy(mask.data(), mask_, 16); +} // SIMDTernary BinaryenOp BinaryenSIMDTernaryGetOp(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->op; } +void BinaryenSIMDTernarySetOp(BinaryenExpressionRef expr, BinaryenOp op) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->op = SIMDTernaryOp(op); +} BinaryenExpressionRef BinaryenSIMDTernaryGetA(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->a; } +void BinaryenSIMDTernarySetA(BinaryenExpressionRef expr, + BinaryenExpressionRef aExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(aExpr); + static_cast(expression)->a = (Expression*)aExpr; +} BinaryenExpressionRef BinaryenSIMDTernaryGetB(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->b; } +void BinaryenSIMDTernarySetB(BinaryenExpressionRef expr, + BinaryenExpressionRef bExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(bExpr); + static_cast(expression)->b = (Expression*)bExpr; +} BinaryenExpressionRef BinaryenSIMDTernaryGetC(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->c; } +void BinaryenSIMDTernarySetC(BinaryenExpressionRef expr, + BinaryenExpressionRef cExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(cExpr); + static_cast(expression)->c = (Expression*)cExpr; +} // SIMDShift BinaryenOp BinaryenSIMDShiftGetOp(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->op; } +void BinaryenSIMDShiftSetOp(BinaryenExpressionRef expr, BinaryenOp op) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->op = SIMDShiftOp(op); +} BinaryenExpressionRef BinaryenSIMDShiftGetVec(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->vec; } +void BinaryenSIMDShiftSetVec(BinaryenExpressionRef expr, + BinaryenExpressionRef vecExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(vecExpr); + static_cast(expression)->vec = (Expression*)vecExpr; +} BinaryenExpressionRef BinaryenSIMDShiftGetShift(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->shift; } +void BinaryenSIMDShiftSetShift(BinaryenExpressionRef expr, + BinaryenExpressionRef shiftExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(shiftExpr); + static_cast(expression)->shift = (Expression*)shiftExpr; +} // SIMDLoad BinaryenOp BinaryenSIMDLoadGetOp(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->op; } +void BinaryenSIMDLoadSetOp(BinaryenExpressionRef expr, BinaryenOp op) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->op = SIMDLoadOp(op); +} uint32_t BinaryenSIMDLoadGetOffset(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->offset; } +void BinaryenSIMDLoadSetOffset(BinaryenExpressionRef expr, uint32_t offset) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->offset = offset; +} uint32_t BinaryenSIMDLoadGetAlign(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->align; } +void BinaryenSIMDLoadSetAlign(BinaryenExpressionRef expr, uint32_t align) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->align = align; +} BinaryenExpressionRef BinaryenSIMDLoadGetPtr(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->ptr; } +void BinaryenSIMDLoadSetPtr(BinaryenExpressionRef expr, + BinaryenExpressionRef ptrExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(ptrExpr); + static_cast(expression)->ptr = (Expression*)ptrExpr; +} // MemoryInit uint32_t BinaryenMemoryInitGetSegment(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->segment; } +void BinaryenMemoryInitSetSegment(BinaryenExpressionRef expr, + uint32_t segment) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->segment = segment; +} BinaryenExpressionRef BinaryenMemoryInitGetDest(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->dest; } +void BinaryenMemoryInitSetDest(BinaryenExpressionRef expr, + BinaryenExpressionRef destExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(destExpr); + static_cast(expression)->dest = (Expression*)destExpr; +} BinaryenExpressionRef BinaryenMemoryInitGetOffset(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->offset; } +void BinaryenMemoryInitSetOffset(BinaryenExpressionRef expr, + BinaryenExpressionRef offsetExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(offsetExpr); + static_cast(expression)->offset = (Expression*)offsetExpr; +} BinaryenExpressionRef BinaryenMemoryInitGetSize(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->size; } +void BinaryenMemoryInitSetSize(BinaryenExpressionRef expr, + BinaryenExpressionRef sizeExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(sizeExpr); + static_cast(expression)->size = (Expression*)sizeExpr; +} // DataDrop uint32_t BinaryenDataDropGetSegment(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->segment; } +void BinaryenDataDropSetSegment(BinaryenExpressionRef expr, uint32_t segment) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->segment = segment; +} // MemoryCopy BinaryenExpressionRef BinaryenMemoryCopyGetDest(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->dest; } +void BinaryenMemoryCopySetDest(BinaryenExpressionRef expr, + BinaryenExpressionRef destExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(destExpr); + static_cast(expression)->dest = (Expression*)destExpr; +} BinaryenExpressionRef BinaryenMemoryCopyGetSource(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->source; } +void BinaryenMemoryCopySetSource(BinaryenExpressionRef expr, + BinaryenExpressionRef sourceExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(sourceExpr); + static_cast(expression)->source = (Expression*)sourceExpr; +} BinaryenExpressionRef BinaryenMemoryCopyGetSize(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->size; } +void BinaryenMemoryCopySetSize(BinaryenExpressionRef expr, + BinaryenExpressionRef sizeExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(sizeExpr); + static_cast(expression)->size = (Expression*)sizeExpr; +} // MemoryFill BinaryenExpressionRef BinaryenMemoryFillGetDest(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->dest; } +void BinaryenMemoryFillSetDest(BinaryenExpressionRef expr, + BinaryenExpressionRef destExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(destExpr); + static_cast(expression)->dest = (Expression*)destExpr; +} BinaryenExpressionRef BinaryenMemoryFillGetValue(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->value; } +void BinaryenMemoryFillSetValue(BinaryenExpressionRef expr, + BinaryenExpressionRef valueExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(valueExpr); + static_cast(expression)->value = (Expression*)valueExpr; +} BinaryenExpressionRef BinaryenMemoryFillGetSize(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->size; } +void BinaryenMemoryFillSetSize(BinaryenExpressionRef expr, + BinaryenExpressionRef sizeExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(sizeExpr); + static_cast(expression)->size = (Expression*)sizeExpr; +} // RefIsNull BinaryenExpressionRef BinaryenRefIsNullGetValue(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->value; } +void BinaryenRefIsNullSetValue(BinaryenExpressionRef expr, + BinaryenExpressionRef valueExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(valueExpr); + static_cast(expression)->value = (Expression*)valueExpr; +} // RefFunc const char* BinaryenRefFuncGetFunc(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->func.c_str(); } +void BinaryenRefFuncSetFunc(BinaryenExpressionRef expr, const char* funcName) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->func = funcName; +} // Try BinaryenExpressionRef BinaryenTryGetBody(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->body; } +void BinaryenTrySetBody(BinaryenExpressionRef expr, + BinaryenExpressionRef bodyExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(bodyExpr); + static_cast(expression)->body = (Expression*)bodyExpr; +} BinaryenExpressionRef BinaryenTryGetCatchBody(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->catchBody; } +void BinaryenTrySetCatchBody(BinaryenExpressionRef expr, + BinaryenExpressionRef catchBodyExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(catchBodyExpr); + static_cast(expression)->catchBody = (Expression*)catchBodyExpr; +} // Throw const char* BinaryenThrowGetEvent(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->event.c_str(); } -BinaryenExpressionRef BinaryenThrowGetOperand(BinaryenExpressionRef expr, - BinaryenIndex index) { +void BinaryenThrowSetEvent(BinaryenExpressionRef expr, const char* eventName) { auto* expression = (Expression*)expr; assert(expression->is()); - assert(index < static_cast(expression)->operands.size()); - return static_cast(expression)->operands[index]; + static_cast(expression)->event = eventName; } BinaryenIndex BinaryenThrowGetNumOperands(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->operands.size(); } +BinaryenExpressionRef BinaryenThrowGetOperandAt(BinaryenExpressionRef expr, + BinaryenIndex index) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(index < static_cast(expression)->operands.size()); + return static_cast(expression)->operands[index]; +} +void BinaryenThrowSetOperandAt(BinaryenExpressionRef expr, + BinaryenIndex index, + BinaryenExpressionRef operandExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(index < static_cast(expression)->operands.size()); + assert(operandExpr); + static_cast(expression)->operands[index] = (Expression*)operandExpr; +} +BinaryenIndex BinaryenThrowAppendOperand(BinaryenExpressionRef expr, + BinaryenExpressionRef operandExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(operandExpr); + auto& list = static_cast(expression)->operands; + auto index = list.size(); + list.push_back((Expression*)operandExpr); + return index; +} +void BinaryenThrowInsertOperandAt(BinaryenExpressionRef expr, + BinaryenIndex index, + BinaryenExpressionRef operandExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(operandExpr); + static_cast(expression) + ->operands.insertAt(index, (Expression*)operandExpr); +} +BinaryenExpressionRef BinaryenThrowRemoveOperandAt(BinaryenExpressionRef expr, + BinaryenIndex index) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->operands.removeAt(index); +} // Rethrow BinaryenExpressionRef BinaryenRethrowGetExnref(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->exnref; } +void BinaryenRethrowSetExnref(BinaryenExpressionRef expr, + BinaryenExpressionRef exnrefExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(exnrefExpr); + static_cast(expression)->exnref = (Expression*)exnrefExpr; +} // BrOnExn const char* BinaryenBrOnExnGetEvent(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->event.c_str(); } +void BinaryenBrOnExnSetEvent(BinaryenExpressionRef expr, + const char* eventName) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->event = eventName; +} const char* BinaryenBrOnExnGetName(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->name.c_str(); } +void BinaryenBrOnExnSetName(BinaryenExpressionRef expr, const char* name) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->name = name; +} BinaryenExpressionRef BinaryenBrOnExnGetExnref(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->exnref; } +void BinaryenBrOnExnSetExnref(BinaryenExpressionRef expr, + BinaryenExpressionRef exnrefExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(exnrefExpr); + static_cast(expression)->exnref = (Expression*)exnrefExpr; +} // TupleMake BinaryenIndex BinaryenTupleMakeGetNumOperands(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->operands.size(); } -BinaryenExpressionRef BinaryenTupleMakeGetOperand(BinaryenExpressionRef expr, - BinaryenIndex index) { +BinaryenExpressionRef BinaryenTupleMakeGetOperandAt(BinaryenExpressionRef expr, + BinaryenIndex index) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->operands[index]; } +void BinaryenTupleMakeSetOperandAt(BinaryenExpressionRef expr, + BinaryenIndex index, + BinaryenExpressionRef operandExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(index < static_cast(expression)->operands.size()); + assert(operandExpr); + static_cast(expression)->operands[index] = + (Expression*)operandExpr; +} +BinaryenIndex +BinaryenTupleMakeAppendOperand(BinaryenExpressionRef expr, + BinaryenExpressionRef operandExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(operandExpr); + auto& list = static_cast(expression)->operands; + auto index = list.size(); + list.push_back((Expression*)operandExpr); + return index; +} +void BinaryenTupleMakeInsertOperandAt(BinaryenExpressionRef expr, + BinaryenIndex index, + BinaryenExpressionRef operandExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(operandExpr); + static_cast(expression) + ->operands.insertAt(index, (Expression*)operandExpr); +} +BinaryenExpressionRef +BinaryenTupleMakeRemoveOperandAt(BinaryenExpressionRef expr, + BinaryenIndex index) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->operands.removeAt(index); +} + // TupleExtract BinaryenExpressionRef BinaryenTupleExtractGetTuple(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->tuple; } +void BinaryenTupleExtractSetTuple(BinaryenExpressionRef expr, + BinaryenExpressionRef tupleExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(tupleExpr); + static_cast(expression)->tuple = (Expression*)tupleExpr; +} BinaryenIndex BinaryenTupleExtractGetIndex(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); return static_cast(expression)->index; } +void BinaryenTupleExtractSetIndex(BinaryenExpressionRef expr, + BinaryenIndex index) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->index = index; +} // Functions @@ -2440,7 +3435,7 @@ void BinaryenModulePrintAsmjs(BinaryenModuleRef module) { auto* wasm = (Module*)module; Wasm2JSBuilder::Flags flags; Wasm2JSBuilder wasm2js(flags, globalPassOptions); - Ref asmjs = wasm2js.processWasm(wasm); + auto asmjs = wasm2js.processWasm(wasm); JSPrinter jser(true, true, asmjs); Output out("", Flags::Text); // stdout Wasm2JSGlue glue(*wasm, out, flags, "asmFunc"); @@ -2700,6 +3695,11 @@ BinaryenType BinaryenFunctionGetVar(BinaryenFunctionRef func, BinaryenExpressionRef BinaryenFunctionGetBody(BinaryenFunctionRef func) { return ((Function*)func)->body; } +void BinaryenFunctionSetBody(BinaryenFunctionRef func, + BinaryenExpressionRef body) { + assert(body); + ((Function*)func)->body = (Expression*)body; +} void BinaryenFunctionOptimize(BinaryenFunctionRef func, BinaryenModuleRef module) { PassRunner passRunner((Module*)module); diff --git a/src/binaryen-c.h b/src/binaryen-c.h index b153a28e98d..b749937806d 100644 --- a/src/binaryen-c.h +++ b/src/binaryen-c.h @@ -854,261 +854,1010 @@ BINARYEN_API BinaryenExpressionRef BinaryenTupleExtract( BINARYEN_API BinaryenExpressionRef BinaryenPop(BinaryenModuleRef module, BinaryenType type); +// Expression + +// Gets the id (kind) of the given expression. BINARYEN_API BinaryenExpressionId BinaryenExpressionGetId(BinaryenExpressionRef expr); +// Gets the type of the given expression. BINARYEN_API BinaryenType BinaryenExpressionGetType(BinaryenExpressionRef expr); +// Sets the type of the given expression. +BINARYEN_API void BinaryenExpressionSetType(BinaryenExpressionRef expr, + BinaryenType type); +// Prints text format of the given expression to stdout. BINARYEN_API void BinaryenExpressionPrint(BinaryenExpressionRef expr); +// Re-finalizes an expression after it has been modified. +BINARYEN_API void BinaryenExpressionFinalize(BinaryenExpressionRef expr); +// Makes a deep copy of the given expression. BINARYEN_API BinaryenExpressionRef BinaryenExpressionCopy(BinaryenExpressionRef expr, BinaryenModuleRef module); +// Block + +// Gets the name (label) of a `block` expression. BINARYEN_API const char* BinaryenBlockGetName(BinaryenExpressionRef expr); +// Sets the name (label) of a `block` expression. +BINARYEN_API void BinaryenBlockSetName(BinaryenExpressionRef expr, + const char* name); +// Gets the number of child expressions of a `block` expression. BINARYEN_API BinaryenIndex BinaryenBlockGetNumChildren(BinaryenExpressionRef expr); -BINARYEN_API BinaryenExpressionRef -BinaryenBlockGetChild(BinaryenExpressionRef expr, BinaryenIndex index); - +// Gets the child expression at the specified index of a `block` expression. +BINARYEN_API BinaryenExpressionRef +BinaryenBlockGetChildAt(BinaryenExpressionRef expr, BinaryenIndex index); +// Sets (replaces) the child expression at the specified index of a `block` +// expression. +BINARYEN_API void BinaryenBlockSetChildAt(BinaryenExpressionRef expr, + BinaryenIndex index, + BinaryenExpressionRef childExpr); +// Appends a child expression to a `block` expression, returning its insertion +// index. +BINARYEN_API BinaryenIndex BinaryenBlockAppendChild( + BinaryenExpressionRef expr, BinaryenExpressionRef childExpr); +// Inserts a child expression at the specified index of a `block` expression, +// moving existing children including the one previously at that index one index +// up. +BINARYEN_API void BinaryenBlockInsertChildAt(BinaryenExpressionRef expr, + BinaryenIndex index, + BinaryenExpressionRef childExpr); +// Removes the child expression at the specified index of a `block` expression, +// moving all subsequent children one index down. Returns the child expression. +BINARYEN_API BinaryenExpressionRef +BinaryenBlockRemoveChildAt(BinaryenExpressionRef expr, BinaryenIndex index); + +// If + +// Gets the condition expression of an `if` expression. BINARYEN_API BinaryenExpressionRef BinaryenIfGetCondition(BinaryenExpressionRef expr); +// Sets the condition expression of an `if` expression. +BINARYEN_API void BinaryenIfSetCondition(BinaryenExpressionRef expr, + BinaryenExpressionRef condExpr); +// Gets the ifTrue (then) expression of an `if` expression. BINARYEN_API BinaryenExpressionRef BinaryenIfGetIfTrue(BinaryenExpressionRef expr); +// Sets the ifTrue (then) expression of an `if` expression. +BINARYEN_API void BinaryenIfSetIfTrue(BinaryenExpressionRef expr, + BinaryenExpressionRef ifTrueExpr); +// Gets the ifFalse (else) expression, if any, of an `if` expression. BINARYEN_API BinaryenExpressionRef BinaryenIfGetIfFalse(BinaryenExpressionRef expr); +// Sets the ifFalse (else) expression, if any, of an `if` expression. +BINARYEN_API void BinaryenIfSetIfFalse(BinaryenExpressionRef expr, + BinaryenExpressionRef ifFalseExpr); + +// Loop +// Gets the name (label) of a `loop` expression. BINARYEN_API const char* BinaryenLoopGetName(BinaryenExpressionRef expr); +// Sets the name (label) of a `loop` expression. +BINARYEN_API void BinaryenLoopSetName(BinaryenExpressionRef expr, + const char* name); +// Gets the body expression of a `loop` expression. BINARYEN_API BinaryenExpressionRef BinaryenLoopGetBody(BinaryenExpressionRef expr); +// Sets the body expression of a `loop` expression. +BINARYEN_API void BinaryenLoopSetBody(BinaryenExpressionRef expr, + BinaryenExpressionRef bodyExpr); + +// Break +// Gets the name (target label) of a `br` or `br_if` expression. BINARYEN_API const char* BinaryenBreakGetName(BinaryenExpressionRef expr); +// Sets the name (target label) of a `br` or `br_if` expression. +BINARYEN_API void BinaryenBreakSetName(BinaryenExpressionRef expr, + const char* name); +// Gets the condition expression, if any, of a `br_if` expression. No condition +// indicates a `br` expression. BINARYEN_API BinaryenExpressionRef BinaryenBreakGetCondition(BinaryenExpressionRef expr); +// Sets the condition expression, if any, of a `br_if` expression. No condition +// makes it a `br` expression. +BINARYEN_API void BinaryenBreakSetCondition(BinaryenExpressionRef expr, + BinaryenExpressionRef condExpr); +// Gets the value expression, if any, of a `br` or `br_if` expression. BINARYEN_API BinaryenExpressionRef BinaryenBreakGetValue(BinaryenExpressionRef expr); +// Sets the value expression, if any, of a `br` or `br_if` expression. +BINARYEN_API void BinaryenBreakSetValue(BinaryenExpressionRef expr, + BinaryenExpressionRef valueExpr); + +// Switch +// Gets the number of names (target labels) of a `br_table` expression. BINARYEN_API BinaryenIndex BinaryenSwitchGetNumNames(BinaryenExpressionRef expr); -BINARYEN_API const char* BinaryenSwitchGetName(BinaryenExpressionRef expr, - BinaryenIndex index); +// Gets the name (target label) at the specified index of a `br_table` +// expression. +BINARYEN_API const char* BinaryenSwitchGetNameAt(BinaryenExpressionRef expr, + BinaryenIndex index); +// Sets the name (target label) at the specified index of a `br_table` +// expression. +BINARYEN_API void BinaryenSwitchSetNameAt(BinaryenExpressionRef expr, + BinaryenIndex index, + const char* name); +// Appends a name to a `br_table` expression, returning its insertion index. +BINARYEN_API BinaryenIndex BinaryenSwitchAppendName(BinaryenExpressionRef expr, + const char* name); +// Inserts a name at the specified index of a `br_table` expression, moving +// existing names including the one previously at that index one index up. +BINARYEN_API void BinaryenSwitchInsertNameAt(BinaryenExpressionRef expr, + BinaryenIndex index, + const char* name); +// Removes the name at the specified index of a `br_table` expression, moving +// all subsequent names one index down. Returns the name. +BINARYEN_API const char* BinaryenSwitchRemoveNameAt(BinaryenExpressionRef expr, + BinaryenIndex index); +// Gets the default name (target label), if any, of a `br_table` expression. BINARYEN_API const char* BinaryenSwitchGetDefaultName(BinaryenExpressionRef expr); +// Sets the default name (target label), if any, of a `br_table` expression. +BINARYEN_API void BinaryenSwitchSetDefaultName(BinaryenExpressionRef expr, + const char* name); +// Gets the condition expression of a `br_table` expression. BINARYEN_API BinaryenExpressionRef BinaryenSwitchGetCondition(BinaryenExpressionRef expr); +// Sets the condition expression of a `br_table` expression. +BINARYEN_API void BinaryenSwitchSetCondition(BinaryenExpressionRef expr, + BinaryenExpressionRef condExpr); +// Gets the value expression, if any, of a `br_table` expression. BINARYEN_API BinaryenExpressionRef BinaryenSwitchGetValue(BinaryenExpressionRef expr); +// Sets the value expression, if any, of a `br_table` expression. +BINARYEN_API void BinaryenSwitchSetValue(BinaryenExpressionRef expr, + BinaryenExpressionRef valueExpr); -BINARYEN_API int BinaryenCallIsReturn(BinaryenExpressionRef expr); +// Call + +// Gets the target function name of a `call` expression. BINARYEN_API const char* BinaryenCallGetTarget(BinaryenExpressionRef expr); +// Sets the target function name of a `call` expression. +BINARYEN_API void BinaryenCallSetTarget(BinaryenExpressionRef expr, + const char* target); +// Gets the number of operands of a `call` expression. BINARYEN_API BinaryenIndex BinaryenCallGetNumOperands(BinaryenExpressionRef expr); -BINARYEN_API BinaryenExpressionRef -BinaryenCallGetOperand(BinaryenExpressionRef expr, BinaryenIndex index); +// Gets the operand expression at the specified index of a `call` expression. +BINARYEN_API BinaryenExpressionRef +BinaryenCallGetOperandAt(BinaryenExpressionRef expr, BinaryenIndex index); +// Sets the operand expression at the specified index of a `call` expression. +BINARYEN_API void BinaryenCallSetOperandAt(BinaryenExpressionRef expr, + BinaryenIndex index, + BinaryenExpressionRef operandExpr); +// Appends an operand expression to a `call` expression, returning its insertion +// index. +BINARYEN_API BinaryenIndex BinaryenCallAppendOperand( + BinaryenExpressionRef expr, BinaryenExpressionRef operandExpr); +// Inserts an operand expression at the specified index of a `call` expression, +// moving existing operands including the one previously at that index one index +// up. +BINARYEN_API void +BinaryenCallInsertOperandAt(BinaryenExpressionRef expr, + BinaryenIndex index, + BinaryenExpressionRef operandExpr); +// Removes the operand expression at the specified index of a `call` expression, +// moving all subsequent operands one index down. Returns the operand +// expression. +BINARYEN_API BinaryenExpressionRef +BinaryenCallRemoveOperandAt(BinaryenExpressionRef expr, BinaryenIndex index); +// Gets whether the specified `call` expression is a tail call. +BINARYEN_API int BinaryenCallIsReturn(BinaryenExpressionRef expr); +// Sets whether the specified `call` expression is a tail call. +BINARYEN_API void BinaryenCallSetReturn(BinaryenExpressionRef expr, + int isReturn); -BINARYEN_API int BinaryenCallIndirectIsReturn(BinaryenExpressionRef expr); +// CallIndirect + +// Gets the target expression of a `call_indirect` expression. BINARYEN_API BinaryenExpressionRef BinaryenCallIndirectGetTarget(BinaryenExpressionRef expr); +// Sets the target expression of a `call_indirect` expression. +BINARYEN_API void +BinaryenCallIndirectSetTarget(BinaryenExpressionRef expr, + BinaryenExpressionRef targetExpr); +// Gets the number of operands of a `call_indirect` expression. BINARYEN_API BinaryenIndex BinaryenCallIndirectGetNumOperands(BinaryenExpressionRef expr); -BINARYEN_API BinaryenExpressionRef -BinaryenCallIndirectGetOperand(BinaryenExpressionRef expr, BinaryenIndex index); +// Gets the operand expression at the specified index of a `call_indirect` +// expression. +BINARYEN_API BinaryenExpressionRef BinaryenCallIndirectGetOperandAt( + BinaryenExpressionRef expr, BinaryenIndex index); +// Sets the operand expression at the specified index of a `call_indirect` +// expression. +BINARYEN_API void +BinaryenCallIndirectSetOperandAt(BinaryenExpressionRef expr, + BinaryenIndex index, + BinaryenExpressionRef operandExpr); +// Appends an operand expression to a `call_indirect` expression, returning its +// insertion index. +BINARYEN_API BinaryenIndex BinaryenCallIndirectAppendOperand( + BinaryenExpressionRef expr, BinaryenExpressionRef operandExpr); +// Inserts an operand expression at the specified index of a `call_indirect` +// expression, moving existing operands including the one previously at that +// index one index up. +BINARYEN_API void +BinaryenCallIndirectInsertOperandAt(BinaryenExpressionRef expr, + BinaryenIndex index, + BinaryenExpressionRef operandExpr); +// Removes the operand expression at the specified index of a `call_indirect` +// expression, moving all subsequent operands one index down. Returns the +// operand expression. +BINARYEN_API BinaryenExpressionRef BinaryenCallIndirectRemoveOperandAt( + BinaryenExpressionRef expr, BinaryenIndex index); +// Gets whether the specified `call_indirect` expression is a tail call. +BINARYEN_API int BinaryenCallIndirectIsReturn(BinaryenExpressionRef expr); +// Sets whether the specified `call_indirect` expression is a tail call. +BINARYEN_API void BinaryenCallIndirectSetReturn(BinaryenExpressionRef expr, + int isReturn); +// Gets the parameter types of the specified `call_indirect` expression. +BINARYEN_API BinaryenType +BinaryenCallIndirectGetParams(BinaryenExpressionRef expr); +// Sets the parameter types of the specified `call_indirect` expression. +BINARYEN_API void BinaryenCallIndirectSetParams(BinaryenExpressionRef expr, + BinaryenType params); +// Gets the result types of the specified `call_indirect` expression. +BINARYEN_API BinaryenType +BinaryenCallIndirectGetResults(BinaryenExpressionRef expr); +// Sets the result types of the specified `call_indirect` expression. +BINARYEN_API void BinaryenCallIndirectSetResults(BinaryenExpressionRef expr, + BinaryenType params); + +// LocalGet +// Gets the local index of a `local.get` expression. BINARYEN_API BinaryenIndex BinaryenLocalGetGetIndex(BinaryenExpressionRef expr); +// Sets the local index of a `local.get` expression. +BINARYEN_API void BinaryenLocalGetSetIndex(BinaryenExpressionRef expr, + BinaryenIndex index); +// LocalSet + +// Gets whether a `local.set` tees its value (is a `local.tee`). True if the +// expression has a type other than `none`. BINARYEN_API int BinaryenLocalSetIsTee(BinaryenExpressionRef expr); +// Gets the local index of a `local.set` or `local.tee` expression. BINARYEN_API BinaryenIndex BinaryenLocalSetGetIndex(BinaryenExpressionRef expr); +// Sets the local index of a `local.set` or `local.tee` expression. +BINARYEN_API void BinaryenLocalSetSetIndex(BinaryenExpressionRef expr, + BinaryenIndex index); +// Gets the value expression of a `local.set` or `local.tee` expression. BINARYEN_API BinaryenExpressionRef BinaryenLocalSetGetValue(BinaryenExpressionRef expr); +// Sets the value expression of a `local.set` or `local.tee` expression. +BINARYEN_API void BinaryenLocalSetSetValue(BinaryenExpressionRef expr, + BinaryenExpressionRef valueExpr); + +// GlobalGet +// Gets the name of the global being accessed by a `global.get` expression. BINARYEN_API const char* BinaryenGlobalGetGetName(BinaryenExpressionRef expr); +// Sets the name of the global being accessed by a `global.get` expression. +BINARYEN_API void BinaryenGlobalGetSetName(BinaryenExpressionRef expr, + const char* name); +// GlobalSet + +// Gets the name of the global being accessed by a `global.set` expression. BINARYEN_API const char* BinaryenGlobalSetGetName(BinaryenExpressionRef expr); +// Sets the name of the global being accessed by a `global.set` expression. +BINARYEN_API void BinaryenGlobalSetSetName(BinaryenExpressionRef expr, + const char* name); +// Gets the value expression of a `global.set` expression. BINARYEN_API BinaryenExpressionRef BinaryenGlobalSetGetValue(BinaryenExpressionRef expr); +// Sets the value expression of a `global.set` expression. +BINARYEN_API void BinaryenGlobalSetSetValue(BinaryenExpressionRef expr, + BinaryenExpressionRef valueExpr); + +// Host +// Gets the operation being performed by a host expression. BINARYEN_API BinaryenOp BinaryenHostGetOp(BinaryenExpressionRef expr); +// Sets the operation being performed by a host expression. +BINARYEN_API void BinaryenHostSetOp(BinaryenExpressionRef expr, BinaryenOp op); +// Gets the name operand, if any, of a host expression. BINARYEN_API const char* BinaryenHostGetNameOperand(BinaryenExpressionRef expr); +// Sets the name operand, if any, of a host expression. +BINARYEN_API void BinaryenHostSetNameOperand(BinaryenExpressionRef expr, + const char* nameOperand); +// Gets the number of operands of a host expression. BINARYEN_API BinaryenIndex BinaryenHostGetNumOperands(BinaryenExpressionRef expr); -BINARYEN_API BinaryenExpressionRef -BinaryenHostGetOperand(BinaryenExpressionRef expr, BinaryenIndex index); - +// Gets the operand at the specified index of a host expression. +BINARYEN_API BinaryenExpressionRef +BinaryenHostGetOperandAt(BinaryenExpressionRef expr, BinaryenIndex index); +// Sets the operand at the specified index of a host expression. +BINARYEN_API void BinaryenHostSetOperandAt(BinaryenExpressionRef expr, + BinaryenIndex index, + BinaryenExpressionRef operandExpr); +// Appends an operand expression to a host expression, returning its insertion +// index. +BINARYEN_API BinaryenIndex BinaryenHostAppendOperand( + BinaryenExpressionRef expr, BinaryenExpressionRef operandExpr); +// Inserts an operand expression at the specified index of a host expression, +// moving existing operands including the one previously at that index one index +// up. +BINARYEN_API void +BinaryenHostInsertOperandAt(BinaryenExpressionRef expr, + BinaryenIndex index, + BinaryenExpressionRef operandExpr); +// Removes the operand expression at the specified index of a host expression, +// moving all subsequent operands one index down. Returns the operand +// expression. +BINARYEN_API BinaryenExpressionRef +BinaryenHostRemoveOperandAt(BinaryenExpressionRef expr, BinaryenIndex index); + +// Load + +// Gets whether a `load` expression is atomic (is an `atomic.load`). BINARYEN_API int BinaryenLoadIsAtomic(BinaryenExpressionRef expr); +// Sets whether a `load` expression is atomic (is an `atomic.load`). +BINARYEN_API void BinaryenLoadSetAtomic(BinaryenExpressionRef expr, + int isAtomic); +// Gets whether a `load` expression operates on a signed value (`_s`). BINARYEN_API int BinaryenLoadIsSigned(BinaryenExpressionRef expr); +// Sets whether a `load` expression operates on a signed value (`_s`). +BINARYEN_API void BinaryenLoadSetSigned(BinaryenExpressionRef expr, + int isSigned); +// Gets the constant offset of a `load` expression. BINARYEN_API uint32_t BinaryenLoadGetOffset(BinaryenExpressionRef expr); +// Sets the constant offset of a `load` expression. +BINARYEN_API void BinaryenLoadSetOffset(BinaryenExpressionRef expr, + uint32_t offset); +// Gets the number of bytes loaded by a `load` expression. BINARYEN_API uint32_t BinaryenLoadGetBytes(BinaryenExpressionRef expr); +// Sets the number of bytes loaded by a `load` expression. +BINARYEN_API void BinaryenLoadSetBytes(BinaryenExpressionRef expr, + uint32_t bytes); +// Gets the byte alignment of a `load` expression. BINARYEN_API uint32_t BinaryenLoadGetAlign(BinaryenExpressionRef expr); +// Sets the byte alignment of a `load` expression. +BINARYEN_API void BinaryenLoadSetAlign(BinaryenExpressionRef expr, + uint32_t align); +// Gets the pointer expression of a `load` expression. BINARYEN_API BinaryenExpressionRef BinaryenLoadGetPtr(BinaryenExpressionRef expr); +// Sets the pointer expression of a `load` expression. +BINARYEN_API void BinaryenLoadSetPtr(BinaryenExpressionRef expr, + BinaryenExpressionRef ptrExpr); +// Store + +// Gets whether a `store` expression is atomic (is an `atomic.store`). BINARYEN_API int BinaryenStoreIsAtomic(BinaryenExpressionRef expr); +// Sets whether a `store` expression is atomic (is an `atomic.store`). +BINARYEN_API void BinaryenStoreSetAtomic(BinaryenExpressionRef expr, + int isAtomic); +// Gets the number of bytes stored by a `store` expression. BINARYEN_API uint32_t BinaryenStoreGetBytes(BinaryenExpressionRef expr); +// Sets the number of bytes stored by a `store` expression. +BINARYEN_API void BinaryenStoreSetBytes(BinaryenExpressionRef expr, + uint32_t bytes); +// Gets the constant offset of a `store` expression. BINARYEN_API uint32_t BinaryenStoreGetOffset(BinaryenExpressionRef expr); +// Sets the constant offset of a `store` expression. +BINARYEN_API void BinaryenStoreSetOffset(BinaryenExpressionRef expr, + uint32_t offset); +// Gets the byte alignment of a `store` expression. BINARYEN_API uint32_t BinaryenStoreGetAlign(BinaryenExpressionRef expr); +// Sets the byte alignment of a `store` expression. +BINARYEN_API void BinaryenStoreSetAlign(BinaryenExpressionRef expr, + uint32_t align); +// Gets the pointer expression of a `store` expression. BINARYEN_API BinaryenExpressionRef BinaryenStoreGetPtr(BinaryenExpressionRef expr); +// Sets the pointer expression of a `store` expression. +BINARYEN_API void BinaryenStoreSetPtr(BinaryenExpressionRef expr, + BinaryenExpressionRef ptrExpr); +// Gets the value expression of a `store` expression. BINARYEN_API BinaryenExpressionRef BinaryenStoreGetValue(BinaryenExpressionRef expr); - +// Sets the value expression of a `store` expression. +BINARYEN_API void BinaryenStoreSetValue(BinaryenExpressionRef expr, + BinaryenExpressionRef valueExpr); +// Gets the value type of a `store` expression. +BINARYEN_API BinaryenType BinaryenStoreGetValueType(BinaryenExpressionRef expr); +// Sets the value type of a `store` expression. +BINARYEN_API void BinaryenStoreSetValueType(BinaryenExpressionRef expr, + BinaryenType valueType); + +// Const + +// Gets the 32-bit integer value of an `i32.const` expression. BINARYEN_API int32_t BinaryenConstGetValueI32(BinaryenExpressionRef expr); +// Sets the 32-bit integer value of an `i32.const` expression. +BINARYEN_API void BinaryenConstSetValueI32(BinaryenExpressionRef expr, + int32_t value); +// Gets the 64-bit integer value of an `i64.const` expression. BINARYEN_API int64_t BinaryenConstGetValueI64(BinaryenExpressionRef expr); +// Sets the 64-bit integer value of an `i64.const` expression. +BINARYEN_API void BinaryenConstSetValueI64(BinaryenExpressionRef expr, + int64_t value); +// Gets the low 32-bits of the 64-bit integer value of an `i64.const` +// expression. BINARYEN_API int32_t BinaryenConstGetValueI64Low(BinaryenExpressionRef expr); +// Sets the low 32-bits of the 64-bit integer value of an `i64.const` +// expression. +BINARYEN_API void BinaryenConstSetValueI64Low(BinaryenExpressionRef expr, + int32_t valueLow); +// Gets the high 32-bits of the 64-bit integer value of an `i64.const` +// expression. BINARYEN_API int32_t BinaryenConstGetValueI64High(BinaryenExpressionRef expr); +// Sets the high 32-bits of the 64-bit integer value of an `i64.const` +// expression. +BINARYEN_API void BinaryenConstSetValueI64High(BinaryenExpressionRef expr, + int32_t valueHigh); +// Gets the 32-bit float value of a `f32.const` expression. BINARYEN_API float BinaryenConstGetValueF32(BinaryenExpressionRef expr); +// Sets the 32-bit float value of a `f32.const` expression. +BINARYEN_API void BinaryenConstSetValueF32(BinaryenExpressionRef expr, + float value); +// Gets the 64-bit float (double) value of a `f64.const` expression. BINARYEN_API double BinaryenConstGetValueF64(BinaryenExpressionRef expr); +// Sets the 64-bit float (double) value of a `f64.const` expression. +BINARYEN_API void BinaryenConstSetValueF64(BinaryenExpressionRef expr, + double value); +// Reads the 128-bit vector value of a `v128.const` expression. BINARYEN_API void BinaryenConstGetValueV128(BinaryenExpressionRef expr, uint8_t* out); +// Sets the 128-bit vector value of a `v128.const` expression. +BINARYEN_API void BinaryenConstSetValueV128(BinaryenExpressionRef expr, + const uint8_t value[16]); +// Unary + +// Gets the operation being performed by a unary expression. BINARYEN_API BinaryenOp BinaryenUnaryGetOp(BinaryenExpressionRef expr); +// Sets the operation being performed by a unary expression. +BINARYEN_API void BinaryenUnarySetOp(BinaryenExpressionRef expr, BinaryenOp op); +// Gets the value expression of a unary expression. BINARYEN_API BinaryenExpressionRef BinaryenUnaryGetValue(BinaryenExpressionRef expr); +// Sets the value expression of a unary expression. +BINARYEN_API void BinaryenUnarySetValue(BinaryenExpressionRef expr, + BinaryenExpressionRef valueExpr); + +// Binary +// Gets the operation being performed by a binary expression. BINARYEN_API BinaryenOp BinaryenBinaryGetOp(BinaryenExpressionRef expr); +// Sets the operation being performed by a binary expression. +BINARYEN_API void BinaryenBinarySetOp(BinaryenExpressionRef expr, + BinaryenOp op); +// Gets the left expression of a binary expression. BINARYEN_API BinaryenExpressionRef BinaryenBinaryGetLeft(BinaryenExpressionRef expr); +// Sets the left expression of a binary expression. +BINARYEN_API void BinaryenBinarySetLeft(BinaryenExpressionRef expr, + BinaryenExpressionRef leftExpr); +// Gets the right expression of a binary expression. BINARYEN_API BinaryenExpressionRef BinaryenBinaryGetRight(BinaryenExpressionRef expr); +// Sets the right expression of a binary expression. +BINARYEN_API void BinaryenBinarySetRight(BinaryenExpressionRef expr, + BinaryenExpressionRef rightExpr); +// Select + +// Gets the expression becoming selected by a `select` expression if the +// condition turns out true. BINARYEN_API BinaryenExpressionRef BinaryenSelectGetIfTrue(BinaryenExpressionRef expr); +// Sets the expression becoming selected by a `select` expression if the +// condition turns out true. +BINARYEN_API void BinaryenSelectSetIfTrue(BinaryenExpressionRef expr, + BinaryenExpressionRef ifTrueExpr); +// Gets the expression becoming selected by a `select` expression if the +// condition turns out false. BINARYEN_API BinaryenExpressionRef BinaryenSelectGetIfFalse(BinaryenExpressionRef expr); +// Sets the expression becoming selected by a `select` expression if the +// condition turns out false. +BINARYEN_API void BinaryenSelectSetIfFalse(BinaryenExpressionRef expr, + BinaryenExpressionRef ifFalseExpr); +// Gets the condition expression of a `select` expression. BINARYEN_API BinaryenExpressionRef BinaryenSelectGetCondition(BinaryenExpressionRef expr); +// Sets the condition expression of a `select` expression. +BINARYEN_API void BinaryenSelectSetCondition(BinaryenExpressionRef expr, + BinaryenExpressionRef condExpr); + +// Drop +// Gets the value expression being dropped by a `drop` expression. BINARYEN_API BinaryenExpressionRef BinaryenDropGetValue(BinaryenExpressionRef expr); +// Sets the value expression being dropped by a `drop` expression. +BINARYEN_API void BinaryenDropSetValue(BinaryenExpressionRef expr, + BinaryenExpressionRef valueExpr); +// Return + +// Gets the value expression, if any, being returned by a `return` expression. BINARYEN_API BinaryenExpressionRef BinaryenReturnGetValue(BinaryenExpressionRef expr); +// Sets the value expression, if any, being returned by a `return` expression. +BINARYEN_API void BinaryenReturnSetValue(BinaryenExpressionRef expr, + BinaryenExpressionRef valueExpr); + +// AtomicRMW +// Gets the operation being performed by an atomic read-modify-write expression. BINARYEN_API BinaryenOp BinaryenAtomicRMWGetOp(BinaryenExpressionRef expr); +// Sets the operation being performed by an atomic read-modify-write expression. +BINARYEN_API void BinaryenAtomicRMWSetOp(BinaryenExpressionRef expr, + BinaryenOp op); +// Gets the number of bytes affected by an atomic read-modify-write expression. BINARYEN_API uint32_t BinaryenAtomicRMWGetBytes(BinaryenExpressionRef expr); +// Sets the number of bytes affected by an atomic read-modify-write expression. +BINARYEN_API void BinaryenAtomicRMWSetBytes(BinaryenExpressionRef expr, + uint32_t bytes); +// Gets the constant offset of an atomic read-modify-write expression. BINARYEN_API uint32_t BinaryenAtomicRMWGetOffset(BinaryenExpressionRef expr); +// Sets the constant offset of an atomic read-modify-write expression. +BINARYEN_API void BinaryenAtomicRMWSetOffset(BinaryenExpressionRef expr, + uint32_t offset); +// Gets the pointer expression of an atomic read-modify-write expression. BINARYEN_API BinaryenExpressionRef BinaryenAtomicRMWGetPtr(BinaryenExpressionRef expr); +// Sets the pointer expression of an atomic read-modify-write expression. +BINARYEN_API void BinaryenAtomicRMWSetPtr(BinaryenExpressionRef expr, + BinaryenExpressionRef ptrExpr); +// Gets the value expression of an atomic read-modify-write expression. BINARYEN_API BinaryenExpressionRef BinaryenAtomicRMWGetValue(BinaryenExpressionRef expr); +// Sets the value expression of an atomic read-modify-write expression. +BINARYEN_API void BinaryenAtomicRMWSetValue(BinaryenExpressionRef expr, + BinaryenExpressionRef valueExpr); +// AtomicCmpxchg + +// Gets the number of bytes affected by an atomic compare and exchange +// expression. BINARYEN_API uint32_t BinaryenAtomicCmpxchgGetBytes(BinaryenExpressionRef expr); +// Sets the number of bytes affected by an atomic compare and exchange +// expression. +BINARYEN_API void BinaryenAtomicCmpxchgSetBytes(BinaryenExpressionRef expr, + uint32_t bytes); +// Gets the constant offset of an atomic compare and exchange expression. BINARYEN_API uint32_t BinaryenAtomicCmpxchgGetOffset(BinaryenExpressionRef expr); +// Sets the constant offset of an atomic compare and exchange expression. +BINARYEN_API void BinaryenAtomicCmpxchgSetOffset(BinaryenExpressionRef expr, + uint32_t offset); +// Gets the pointer expression of an atomic compare and exchange expression. BINARYEN_API BinaryenExpressionRef BinaryenAtomicCmpxchgGetPtr(BinaryenExpressionRef expr); +// Sets the pointer expression of an atomic compare and exchange expression. +BINARYEN_API void BinaryenAtomicCmpxchgSetPtr(BinaryenExpressionRef expr, + BinaryenExpressionRef ptrExpr); +// Gets the expression representing the expected value of an atomic compare and +// exchange expression. BINARYEN_API BinaryenExpressionRef BinaryenAtomicCmpxchgGetExpected(BinaryenExpressionRef expr); +// Sets the expression representing the expected value of an atomic compare and +// exchange expression. +BINARYEN_API void +BinaryenAtomicCmpxchgSetExpected(BinaryenExpressionRef expr, + BinaryenExpressionRef expectedExpr); +// Gets the replacement expression of an atomic compare and exchange expression. BINARYEN_API BinaryenExpressionRef BinaryenAtomicCmpxchgGetReplacement(BinaryenExpressionRef expr); +// Sets the replacement expression of an atomic compare and exchange expression. +BINARYEN_API void +BinaryenAtomicCmpxchgSetReplacement(BinaryenExpressionRef expr, + BinaryenExpressionRef replacementExpr); + +// AtomicWait +// Gets the pointer expression of an `atomic.wait` expression. BINARYEN_API BinaryenExpressionRef BinaryenAtomicWaitGetPtr(BinaryenExpressionRef expr); +// Sets the pointer expression of an `atomic.wait` expression. +BINARYEN_API void BinaryenAtomicWaitSetPtr(BinaryenExpressionRef expr, + BinaryenExpressionRef ptrExpr); +// Gets the expression representing the expected value of an `atomic.wait` +// expression. BINARYEN_API BinaryenExpressionRef BinaryenAtomicWaitGetExpected(BinaryenExpressionRef expr); +// Sets the expression representing the expected value of an `atomic.wait` +// expression. +BINARYEN_API void +BinaryenAtomicWaitSetExpected(BinaryenExpressionRef expr, + BinaryenExpressionRef expectedExpr); +// Gets the timeout expression of an `atomic.wait` expression. BINARYEN_API BinaryenExpressionRef BinaryenAtomicWaitGetTimeout(BinaryenExpressionRef expr); +// Sets the timeout expression of an `atomic.wait` expression. +BINARYEN_API void +BinaryenAtomicWaitSetTimeout(BinaryenExpressionRef expr, + BinaryenExpressionRef timeoutExpr); +// Gets the expected type of an `atomic.wait` expression. BINARYEN_API BinaryenType BinaryenAtomicWaitGetExpectedType(BinaryenExpressionRef expr); +// Sets the expected type of an `atomic.wait` expression. +BINARYEN_API void BinaryenAtomicWaitSetExpectedType(BinaryenExpressionRef expr, + BinaryenType expectedType); +// AtomicNotify + +// Gets the pointer expression of an `atomic.notify` expression. BINARYEN_API BinaryenExpressionRef BinaryenAtomicNotifyGetPtr(BinaryenExpressionRef expr); +// Sets the pointer expression of an `atomic.notify` expression. +BINARYEN_API void BinaryenAtomicNotifySetPtr(BinaryenExpressionRef expr, + BinaryenExpressionRef ptrExpr); +// Gets the notify count expression of an `atomic.notify` expression. BINARYEN_API BinaryenExpressionRef BinaryenAtomicNotifyGetNotifyCount(BinaryenExpressionRef expr); +// Sets the notify count expression of an `atomic.notify` expression. +BINARYEN_API void +BinaryenAtomicNotifySetNotifyCount(BinaryenExpressionRef expr, + BinaryenExpressionRef notifyCountExpr); + +// AtomicFence +// Gets the order of an `atomic.fence` expression. BINARYEN_API uint8_t BinaryenAtomicFenceGetOrder(BinaryenExpressionRef expr); +// Sets the order of an `atomic.fence` expression. +BINARYEN_API void BinaryenAtomicFenceSetOrder(BinaryenExpressionRef expr, + uint8_t order); +// SIMDExtract + +// Gets the operation being performed by a SIMD extract expression. BINARYEN_API BinaryenOp BinaryenSIMDExtractGetOp(BinaryenExpressionRef expr); +// Sets the operation being performed by a SIMD extract expression. +BINARYEN_API void BinaryenSIMDExtractSetOp(BinaryenExpressionRef expr, + BinaryenOp op); +// Gets the vector expression a SIMD extract expression extracts from. BINARYEN_API BinaryenExpressionRef BinaryenSIMDExtractGetVec(BinaryenExpressionRef expr); +// Sets the vector expression a SIMD extract expression extracts from. +BINARYEN_API void BinaryenSIMDExtractSetVec(BinaryenExpressionRef expr, + BinaryenExpressionRef vecExpr); +// Gets the index of the extracted lane of a SIMD extract expression. BINARYEN_API uint8_t BinaryenSIMDExtractGetIndex(BinaryenExpressionRef expr); +// Sets the index of the extracted lane of a SIMD extract expression. +BINARYEN_API void BinaryenSIMDExtractSetIndex(BinaryenExpressionRef expr, + uint8_t index); + +// SIMDReplace +// Gets the operation being performed by a SIMD replace expression. BINARYEN_API BinaryenOp BinaryenSIMDReplaceGetOp(BinaryenExpressionRef expr); +// Sets the operation being performed by a SIMD replace expression. +BINARYEN_API void BinaryenSIMDReplaceSetOp(BinaryenExpressionRef expr, + BinaryenOp op); +// Gets the vector expression a SIMD replace expression replaces in. BINARYEN_API BinaryenExpressionRef BinaryenSIMDReplaceGetVec(BinaryenExpressionRef expr); +// Sets the vector expression a SIMD replace expression replaces in. +BINARYEN_API void BinaryenSIMDReplaceSetVec(BinaryenExpressionRef expr, + BinaryenExpressionRef vecExpr); +// Gets the index of the replaced lane of a SIMD replace expression. BINARYEN_API uint8_t BinaryenSIMDReplaceGetIndex(BinaryenExpressionRef expr); +// Sets the index of the replaced lane of a SIMD replace expression. +BINARYEN_API void BinaryenSIMDReplaceSetIndex(BinaryenExpressionRef expr, + uint8_t index); +// Gets the value expression a SIMD replace expression replaces with. BINARYEN_API BinaryenExpressionRef BinaryenSIMDReplaceGetValue(BinaryenExpressionRef expr); +// Sets the value expression a SIMD replace expression replaces with. +BINARYEN_API void BinaryenSIMDReplaceSetValue(BinaryenExpressionRef expr, + BinaryenExpressionRef valueExpr); +// SIMDShuffle + +// Gets the left expression of a SIMD shuffle expression. BINARYEN_API BinaryenExpressionRef BinaryenSIMDShuffleGetLeft(BinaryenExpressionRef expr); +// Sets the left expression of a SIMD shuffle expression. +BINARYEN_API void BinaryenSIMDShuffleSetLeft(BinaryenExpressionRef expr, + BinaryenExpressionRef leftExpr); +// Gets the right expression of a SIMD shuffle expression. BINARYEN_API BinaryenExpressionRef BinaryenSIMDShuffleGetRight(BinaryenExpressionRef expr); +// Sets the right expression of a SIMD shuffle expression. +BINARYEN_API void BinaryenSIMDShuffleSetRight(BinaryenExpressionRef expr, + BinaryenExpressionRef rightExpr); +// Gets the 128-bit mask of a SIMD shuffle expression. BINARYEN_API void BinaryenSIMDShuffleGetMask(BinaryenExpressionRef expr, uint8_t* mask); +// Sets the 128-bit mask of a SIMD shuffle expression. +BINARYEN_API void BinaryenSIMDShuffleSetMask(BinaryenExpressionRef expr, + const uint8_t mask[16]); + +// SIMDTernary +// Gets the operation being performed by a SIMD ternary expression. BINARYEN_API BinaryenOp BinaryenSIMDTernaryGetOp(BinaryenExpressionRef expr); +// Sets the operation being performed by a SIMD ternary expression. +BINARYEN_API void BinaryenSIMDTernarySetOp(BinaryenExpressionRef expr, + BinaryenOp op); +// Gets the first operand expression of a SIMD ternary expression. BINARYEN_API BinaryenExpressionRef BinaryenSIMDTernaryGetA(BinaryenExpressionRef expr); +// Sets the first operand expression of a SIMD ternary expression. +BINARYEN_API void BinaryenSIMDTernarySetA(BinaryenExpressionRef expr, + BinaryenExpressionRef aExpr); +// Gets the second operand expression of a SIMD ternary expression. BINARYEN_API BinaryenExpressionRef BinaryenSIMDTernaryGetB(BinaryenExpressionRef expr); +// Sets the second operand expression of a SIMD ternary expression. +BINARYEN_API void BinaryenSIMDTernarySetB(BinaryenExpressionRef expr, + BinaryenExpressionRef bExpr); +// Gets the third operand expression of a SIMD ternary expression. BINARYEN_API BinaryenExpressionRef BinaryenSIMDTernaryGetC(BinaryenExpressionRef expr); +// Sets the third operand expression of a SIMD ternary expression. +BINARYEN_API void BinaryenSIMDTernarySetC(BinaryenExpressionRef expr, + BinaryenExpressionRef cExpr); +// SIMDShift + +// Gets the operation being performed by a SIMD shift expression. BINARYEN_API BinaryenOp BinaryenSIMDShiftGetOp(BinaryenExpressionRef expr); +// Sets the operation being performed by a SIMD shift expression. +BINARYEN_API void BinaryenSIMDShiftSetOp(BinaryenExpressionRef expr, + BinaryenOp op); +// Gets the expression being shifted by a SIMD shift expression. BINARYEN_API BinaryenExpressionRef BinaryenSIMDShiftGetVec(BinaryenExpressionRef expr); +// Sets the expression being shifted by a SIMD shift expression. +BINARYEN_API void BinaryenSIMDShiftSetVec(BinaryenExpressionRef expr, + BinaryenExpressionRef vecExpr); +// Gets the expression representing the shift of a SIMD shift expression. BINARYEN_API BinaryenExpressionRef BinaryenSIMDShiftGetShift(BinaryenExpressionRef expr); +// Sets the expression representing the shift of a SIMD shift expression. +BINARYEN_API void BinaryenSIMDShiftSetShift(BinaryenExpressionRef expr, + BinaryenExpressionRef shiftExpr); + +// SIMDLoad +// Gets the operation being performed by a SIMD load expression. BINARYEN_API BinaryenOp BinaryenSIMDLoadGetOp(BinaryenExpressionRef expr); +// Sets the operation being performed by a SIMD load expression. +BINARYEN_API void BinaryenSIMDLoadSetOp(BinaryenExpressionRef expr, + BinaryenOp op); +// Gets the constant offset of a SIMD load expression. BINARYEN_API uint32_t BinaryenSIMDLoadGetOffset(BinaryenExpressionRef expr); +// Sets the constant offset of a SIMD load expression. +BINARYEN_API void BinaryenSIMDLoadSetOffset(BinaryenExpressionRef expr, + uint32_t offset); +// Gets the byte alignment of a SIMD load expression. BINARYEN_API uint32_t BinaryenSIMDLoadGetAlign(BinaryenExpressionRef expr); +// Sets the byte alignment of a SIMD load expression. +BINARYEN_API void BinaryenSIMDLoadSetAlign(BinaryenExpressionRef expr, + uint32_t align); +// Gets the pointer expression of a SIMD load expression. BINARYEN_API BinaryenExpressionRef BinaryenSIMDLoadGetPtr(BinaryenExpressionRef expr); +// Sets the pointer expression of a SIMD load expression. +BINARYEN_API void BinaryenSIMDLoadSetPtr(BinaryenExpressionRef expr, + BinaryenExpressionRef ptrExpr); +// MemoryInit + +// Gets the index of the segment being initialized by a `memory.init` +// expression. BINARYEN_API uint32_t BinaryenMemoryInitGetSegment(BinaryenExpressionRef expr); +// Sets the index of the segment being initialized by a `memory.init` +// expression. +BINARYEN_API void BinaryenMemoryInitSetSegment(BinaryenExpressionRef expr, + uint32_t segmentIndex); +// Gets the destination expression of a `memory.init` expression. BINARYEN_API BinaryenExpressionRef BinaryenMemoryInitGetDest(BinaryenExpressionRef expr); +// Sets the destination expression of a `memory.init` expression. +BINARYEN_API void BinaryenMemoryInitSetDest(BinaryenExpressionRef expr, + BinaryenExpressionRef destExpr); +// Gets the offset expression of a `memory.init` expression. BINARYEN_API BinaryenExpressionRef BinaryenMemoryInitGetOffset(BinaryenExpressionRef expr); +// Sets the offset expression of a `memory.init` expression. +BINARYEN_API void BinaryenMemoryInitSetOffset(BinaryenExpressionRef expr, + BinaryenExpressionRef offsetExpr); +// Gets the size expression of a `memory.init` expression. BINARYEN_API BinaryenExpressionRef BinaryenMemoryInitGetSize(BinaryenExpressionRef expr); +// Sets the size expression of a `memory.init` expression. +BINARYEN_API void BinaryenMemoryInitSetSize(BinaryenExpressionRef expr, + BinaryenExpressionRef sizeExpr); + +// DataDrop +// Gets the index of the segment being dropped by a `memory.drop` expression. BINARYEN_API uint32_t BinaryenDataDropGetSegment(BinaryenExpressionRef expr); +// Sets the index of the segment being dropped by a `memory.drop` expression. +BINARYEN_API void BinaryenDataDropSetSegment(BinaryenExpressionRef expr, + uint32_t segmentIndex); +// MemoryCopy + +// Gets the destination expression of a `memory.copy` expression. BINARYEN_API BinaryenExpressionRef BinaryenMemoryCopyGetDest(BinaryenExpressionRef expr); +// Sets the destination expression of a `memory.copy` expression. +BINARYEN_API void BinaryenMemoryCopySetDest(BinaryenExpressionRef expr, + BinaryenExpressionRef destExpr); +// Gets the source expression of a `memory.copy` expression. BINARYEN_API BinaryenExpressionRef BinaryenMemoryCopyGetSource(BinaryenExpressionRef expr); +// Sets the source expression of a `memory.copy` expression. +BINARYEN_API void BinaryenMemoryCopySetSource(BinaryenExpressionRef expr, + BinaryenExpressionRef sourceExpr); +// Gets the size expression (number of bytes copied) of a `memory.copy` +// expression. BINARYEN_API BinaryenExpressionRef BinaryenMemoryCopyGetSize(BinaryenExpressionRef expr); +// Sets the size expression (number of bytes copied) of a `memory.copy` +// expression. +BINARYEN_API void BinaryenMemoryCopySetSize(BinaryenExpressionRef expr, + BinaryenExpressionRef sizeExpr); + +// MemoryFill +// Gets the destination expression of a `memory.fill` expression. BINARYEN_API BinaryenExpressionRef BinaryenMemoryFillGetDest(BinaryenExpressionRef expr); +// Sets the destination expression of a `memory.fill` expression. +BINARYEN_API void BinaryenMemoryFillSetDest(BinaryenExpressionRef expr, + BinaryenExpressionRef destExpr); +// Gets the value expression of a `memory.fill` expression. BINARYEN_API BinaryenExpressionRef BinaryenMemoryFillGetValue(BinaryenExpressionRef expr); +// Sets the value expression of a `memory.fill` expression. +BINARYEN_API void BinaryenMemoryFillSetValue(BinaryenExpressionRef expr, + BinaryenExpressionRef valueExpr); +// Gets the size expression (number of bytes filled) of a `memory.fill` +// expression. BINARYEN_API BinaryenExpressionRef BinaryenMemoryFillGetSize(BinaryenExpressionRef expr); +// Sets the size expression (number of bytes filled) of a `memory.fill` +// expression. +BINARYEN_API void BinaryenMemoryFillSetSize(BinaryenExpressionRef expr, + BinaryenExpressionRef sizeExpr); +// RefIsNull + +// Gets the value expression tested to be null of a `ref.is_null` expression. BINARYEN_API BinaryenExpressionRef BinaryenRefIsNullGetValue(BinaryenExpressionRef expr); +// Sets the value expression tested to be null of a `ref.is_null` expression. +BINARYEN_API void BinaryenRefIsNullSetValue(BinaryenExpressionRef expr, + BinaryenExpressionRef valueExpr); + +// RefFunc +// Gets the name of the function being wrapped by a `ref.func` expression. BINARYEN_API const char* BinaryenRefFuncGetFunc(BinaryenExpressionRef expr); +// Sets the name of the function being wrapped by a `ref.func` expression. +BINARYEN_API void BinaryenRefFuncSetFunc(BinaryenExpressionRef expr, + const char* funcName); +// Try + +// Gets the body expression of a `try` expression. BINARYEN_API BinaryenExpressionRef BinaryenTryGetBody(BinaryenExpressionRef expr); +// Sets the body expression of a `try` expression. +BINARYEN_API void BinaryenTrySetBody(BinaryenExpressionRef expr, + BinaryenExpressionRef bodyExpr); +// Gets the catch body expression of a `try` expression. BINARYEN_API BinaryenExpressionRef BinaryenTryGetCatchBody(BinaryenExpressionRef expr); +// Sets the catch body expression of a `try` expression. +BINARYEN_API void BinaryenTrySetCatchBody(BinaryenExpressionRef expr, + BinaryenExpressionRef catchBodyExpr); + +// Throw +// Gets the name of the event being thrown by a `throw` expression. BINARYEN_API const char* BinaryenThrowGetEvent(BinaryenExpressionRef expr); -BINARYEN_API BinaryenExpressionRef -BinaryenThrowGetOperand(BinaryenExpressionRef expr, BinaryenIndex index); +// Sets the name of the event being thrown by a `throw` expression. +BINARYEN_API void BinaryenThrowSetEvent(BinaryenExpressionRef expr, + const char* eventName); +// Gets the number of operands of a `throw` expression. BINARYEN_API BinaryenIndex BinaryenThrowGetNumOperands(BinaryenExpressionRef expr); - +// Gets the operand at the specified index of a `throw` expression. +BINARYEN_API BinaryenExpressionRef +BinaryenThrowGetOperandAt(BinaryenExpressionRef expr, BinaryenIndex index); +// Sets the operand at the specified index of a `throw` expression. +BINARYEN_API void BinaryenThrowSetOperandAt(BinaryenExpressionRef expr, + BinaryenIndex index, + BinaryenExpressionRef operandExpr); +// Appends an operand expression to a `throw` expression, returning its +// insertion index. +BINARYEN_API BinaryenIndex BinaryenThrowAppendOperand( + BinaryenExpressionRef expr, BinaryenExpressionRef operandExpr); +// Inserts an operand expression at the specified index of a `throw` expression, +// moving existing operands including the one previously at that index one index +// up. +BINARYEN_API void +BinaryenThrowInsertOperandAt(BinaryenExpressionRef expr, + BinaryenIndex index, + BinaryenExpressionRef operandExpr); +// Removes the operand expression at the specified index of a `throw` +// expression, moving all subsequent operands one index down. Returns the +// operand expression. +BINARYEN_API BinaryenExpressionRef +BinaryenThrowRemoveOperandAt(BinaryenExpressionRef expr, BinaryenIndex index); + +// Rethrow + +// Gets the exception reference expression of a `rethrow` expression. BINARYEN_API BinaryenExpressionRef BinaryenRethrowGetExnref(BinaryenExpressionRef expr); +// Sets the exception reference expression of a `rethrow` expression. +BINARYEN_API void BinaryenRethrowSetExnref(BinaryenExpressionRef expr, + BinaryenExpressionRef exnrefExpr); +// BrOnExn + +// Gets the name of the event triggering a `br_on_exn` expression. BINARYEN_API const char* BinaryenBrOnExnGetEvent(BinaryenExpressionRef expr); +// Sets the name of the event triggering a `br_on_exn` expression. +BINARYEN_API void BinaryenBrOnExnSetEvent(BinaryenExpressionRef expr, + const char* eventName); +// Gets the name (target label) of a `br_on_exn` expression. BINARYEN_API const char* BinaryenBrOnExnGetName(BinaryenExpressionRef expr); +// Sets the name (target label) of a `br_on_exn` expression. +BINARYEN_API void BinaryenBrOnExnSetName(BinaryenExpressionRef expr, + const char* name); +// Gets the expression reference expression of a `br_on_exn` expression. BINARYEN_API BinaryenExpressionRef BinaryenBrOnExnGetExnref(BinaryenExpressionRef expr); +// Sets the expression reference expression of a `br_on_exn` expression. +BINARYEN_API void BinaryenBrOnExnSetExnref(BinaryenExpressionRef expr, + BinaryenExpressionRef exnrefExpr); +// TupleMake + +// Gets the number of operands of a `tuple.make` expression. BINARYEN_API BinaryenIndex BinaryenTupleMakeGetNumOperands(BinaryenExpressionRef expr); -BINARYEN_API BinaryenExpressionRef -BinaryenTupleMakeGetOperand(BinaryenExpressionRef expr, BinaryenIndex index); - +// Gets the operand at the specified index of a `tuple.make` expression. +BINARYEN_API BinaryenExpressionRef +BinaryenTupleMakeGetOperandAt(BinaryenExpressionRef expr, BinaryenIndex index); +// Sets the operand at the specified index of a `tuple.make` expression. +BINARYEN_API void +BinaryenTupleMakeSetOperandAt(BinaryenExpressionRef expr, + BinaryenIndex index, + BinaryenExpressionRef operandExpr); +// Appends an operand expression to a `tuple.make` expression, returning its +// insertion index. +BINARYEN_API BinaryenIndex BinaryenTupleMakeAppendOperand( + BinaryenExpressionRef expr, BinaryenExpressionRef operandExpr); +// Inserts an operand expression at the specified index of a `tuple.make` +// expression, moving existing operands including the one previously at that +// index one index up. +BINARYEN_API void +BinaryenTupleMakeInsertOperandAt(BinaryenExpressionRef expr, + BinaryenIndex index, + BinaryenExpressionRef operandExpr); +// Removes the operand expression at the specified index of a `tuple.make` +// expression, moving all subsequent operands one index down. Returns the +// operand expression. +BINARYEN_API BinaryenExpressionRef BinaryenTupleMakeRemoveOperandAt( + BinaryenExpressionRef expr, BinaryenIndex index); + +// TupleExtract + +// Gets the tuple extracted from of a `tuple.extract` expression. BINARYEN_API BinaryenExpressionRef BinaryenTupleExtractGetTuple(BinaryenExpressionRef expr); +// Sets the tuple extracted from of a `tuple.extract` expression. +BINARYEN_API void BinaryenTupleExtractSetTuple(BinaryenExpressionRef expr, + BinaryenExpressionRef tupleExpr); +// Gets the index extracted at of a `tuple.extract` expression. BINARYEN_API BinaryenIndex BinaryenTupleExtractGetIndex(BinaryenExpressionRef expr); +// Sets the index extracted at of a `tuple.extract` expression. +BINARYEN_API void BinaryenTupleExtractSetIndex(BinaryenExpressionRef expr, + BinaryenIndex index); // Functions @@ -1479,6 +2228,9 @@ BINARYEN_API BinaryenType BinaryenFunctionGetVar(BinaryenFunctionRef func, // Gets the body of the specified `Function`. BINARYEN_API BinaryenExpressionRef BinaryenFunctionGetBody(BinaryenFunctionRef func); +// Sets the body of the specified `Function`. +BINARYEN_API void BinaryenFunctionSetBody(BinaryenFunctionRef func, + BinaryenExpressionRef body); // Runs the standard optimization passes on the function. Uses the currently set // global optimize and shrink level. diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js index 99fb54350ac..123bf4a1a18 100644 --- a/src/js/binaryen.js-post.js +++ b/src/js/binaryen.js-post.js @@ -2534,7 +2534,7 @@ Module['getExpressionInfo'] = function(expr) { 'id': id, 'type': type, 'name': UTF8ToString(Module['_BinaryenBlockGetName'](expr)), - 'children': getAllNested(expr, Module['_BinaryenBlockGetNumChildren'], Module['_BinaryenBlockGetChild']) + 'children': getAllNested(expr, Module['_BinaryenBlockGetNumChildren'], Module['_BinaryenBlockGetChildAt']) }; case Module['IfId']: return { @@ -2563,7 +2563,7 @@ Module['getExpressionInfo'] = function(expr) { return { 'id': id, 'type': type, - 'names': getAllNested(expr, Module['_BinaryenSwitchGetNumNames'], Module['_BinaryenSwitchGetName']).map(function (p) { + 'names': getAllNested(expr, Module['_BinaryenSwitchGetNumNames'], Module['_BinaryenSwitchGetNameAt']).map(function (p) { // Do not pass the index as the second parameter to UTF8ToString as that will cut off the string. return UTF8ToString(p); }), @@ -2577,7 +2577,7 @@ Module['getExpressionInfo'] = function(expr) { 'type': type, 'isReturn': Boolean(Module['_BinaryenCallIsReturn'](expr)), 'target': UTF8ToString(Module['_BinaryenCallGetTarget'](expr)), - 'operands': getAllNested(expr, Module[ '_BinaryenCallGetNumOperands'], Module['_BinaryenCallGetOperand']) + 'operands': getAllNested(expr, Module[ '_BinaryenCallGetNumOperands'], Module['_BinaryenCallGetOperandAt']) }; case Module['CallIndirectId']: return { @@ -2585,7 +2585,7 @@ Module['getExpressionInfo'] = function(expr) { 'type': type, 'isReturn': Boolean(Module['_BinaryenCallIndirectIsReturn'](expr)), 'target': Module['_BinaryenCallIndirectGetTarget'](expr), - 'operands': getAllNested(expr, Module['_BinaryenCallIndirectGetNumOperands'], Module['_BinaryenCallIndirectGetOperand']) + 'operands': getAllNested(expr, Module['_BinaryenCallIndirectGetNumOperands'], Module['_BinaryenCallIndirectGetOperandAt']) }; case Module['LocalGetId']: return { @@ -2710,7 +2710,7 @@ Module['getExpressionInfo'] = function(expr) { 'type': type, 'op': Module['_BinaryenHostGetOp'](expr), 'nameOperand': UTF8ToString(Module['_BinaryenHostGetNameOperand'](expr)), - 'operands': getAllNested(expr, Module['_BinaryenHostGetNumOperands'], Module['_BinaryenHostGetOperand']) + 'operands': getAllNested(expr, Module['_BinaryenHostGetNumOperands'], Module['_BinaryenHostGetOperandAt']) }; case Module['AtomicRMWId']: return { @@ -2869,7 +2869,7 @@ Module['getExpressionInfo'] = function(expr) { 'id': id, 'type': type, 'event': UTF8ToString(Module['_BinaryenThrowGetEvent'](expr)), - 'operands': getAllNested(expr, Module['_BinaryenThrowGetNumOperands'], Module['_BinaryenThrowGetOperand']) + 'operands': getAllNested(expr, Module['_BinaryenThrowGetNumOperands'], Module['_BinaryenThrowGetOperandAt']) }; case Module['RethrowId']: return { @@ -2889,7 +2889,7 @@ Module['getExpressionInfo'] = function(expr) { return { 'id': id, 'type': type, - 'operands': getAllNested(expr, Module['_BinaryenTupleMakeGetNumOperands'], Module['_BinaryenTupleMakeGetOperand']) + 'operands': getAllNested(expr, Module['_BinaryenTupleMakeGetNumOperands'], Module['_BinaryenTupleMakeGetOperandAt']) }; case Module['TupleExtractId']: return { @@ -3103,6 +3103,1285 @@ Module['setOneCallerInlineMaxSize'] = function(size) { Module['_BinaryenSetOneCallerInlineMaxSize'](size); }; +// Expression wrappers + +// Makes a wrapper class with the specified static members while +// automatically deriving instance methods and accessors. +function makeExpressionWrapper(ownStaticMembers) { + function SpecificExpression(expr) { + // can call the constructor without `new` + if (!(this instanceof SpecificExpression)) { + if (!expr) return null; + return new SpecificExpression(expr); + } + Expression.call(this, expr); + } + // inherit static members of Expression + Object.assign(SpecificExpression, Expression); + // add own static members + Object.assign(SpecificExpression, ownStaticMembers); + // inherit from Expression + (SpecificExpression.prototype = Object.create(Expression.prototype)).constructor = SpecificExpression; + // make own instance members + makeExpressionWrapperInstanceMembers(SpecificExpression.prototype, ownStaticMembers); + return SpecificExpression; +} + +// Makes instance members from the given static members +function makeExpressionWrapperInstanceMembers(prototype, staticMembers) { + Object.keys(staticMembers).forEach(function(memberName) { + var member = staticMembers[memberName]; + if (typeof member === "function") { + // Instance method calls the respective static method + prototype[memberName] = function(/* arguments */) { + var numArgs = arguments.length; + var args = new Array(1 + numArgs); + args[0] = this['expr']; + for (var i = 0; i < numArgs; ++i) { + args[1 + i] = arguments[i]; + } + return this.constructor[memberName].apply(null, args); + }; + // Instance accessor calls the respective static methods + var match; + if (member.length === 1 && (match = memberName.match(/^(get|is)/))) { + (function(propertyName, getter, setterIfAny) { + Object.defineProperty(prototype, propertyName, { + get: function() { + return getter(this['expr']); + }, + set: function(value) { + if (setterIfAny) setterIfAny(this['expr'], value); + else throw Error("property '" + propertyName + "' has no setter"); + } + }); + })( + memberName.charAt(match[1].length).toLowerCase() + memberName.substring(match[1].length + 1), + staticMembers[memberName], + staticMembers["set" + memberName.substring(match[1].length)] + ); + } + } + }); +} + +// Base class of all expression wrappers +function Expression(expr) { + if (!expr) throw Error("expression reference must not be null"); + this['expr'] = expr; +} +Expression['getId'] = function(expr) { + return Module['_BinaryenExpressionGetId'](expr); +}; +Expression['getType'] = function(expr) { + return Module['_BinaryenExpressionGetType'](expr); +}; +Expression['setType'] = function(expr, type) { + Module['_BinaryenExpressionSetType'](expr, type); +}; +Expression['finalize'] = function(expr) { + return Module['_BinaryenExpressionFinalize'](expr); +}; +Expression['toText'] = function(expr) { + return Module['emitText'](expr); +}; +makeExpressionWrapperInstanceMembers(Expression.prototype, Expression); +Expression.prototype['valueOf'] = function() { + return this['expr']; +}; + +Module['Expression'] = Expression; + +Module['Block'] = makeExpressionWrapper({ + 'getName': function(expr) { + var name = Module['_BinaryenBlockGetName'](expr); + return name ? UTF8ToString(name) : null; + }, + 'setName': function(expr, name) { + preserveStack(function() { + Module['_BinaryenBlockSetName'](expr, strToStack(name)); + }); + }, + 'getNumChildren': function(expr) { + return Module['_BinaryenBlockGetNumChildren'](expr); + }, + 'getChildren': function(expr) { + var numChildren = Module['_BinaryenBlockGetNumChildren'](expr); + var children = new Array(numChildren); + var index = 0; + while (index < numChildren) { + children[index] = Module['_BinaryenBlockGetChildAt'](expr, index++); + } + return children; + }, + 'setChildren': function(expr, children) { + var numChildren = children.length; + var prevNumChildren = Module['_BinaryenBlockGetNumChildren'](expr); + var index = 0; + while (index < numChildren) { + if (index < prevNumChildren) { + Module['_BinaryenBlockSetChildAt'](expr, index, children[index]); + } else { + Module['_BinaryenBlockAppendChild'](expr, children[index]); + } + ++index; + } + while (prevNumChildren > index) { + Module['_BinaryenBlockRemoveChildAt'](expr, --prevNumChildren); + } + }, + 'getChildAt': function(expr, index) { + return Module['_BinaryenBlockGetChildAt'](expr, index); + }, + 'setChildAt': function(expr, index, childExpr) { + Module['_BinaryenBlockSetChildAt'](expr, index, childExpr); + }, + 'appendChild': function(expr, childExpr) { + return Module['_BinaryenBlockAppendChild'](expr, childExpr); + }, + 'insertChildAt': function(expr, index, childExpr) { + Module['_BinaryenBlockInsertChildAt'](expr, index, childExpr); + }, + 'removeChildAt': function(expr, index) { + return Module['_BinaryenBlockRemoveChildAt'](expr, index); + } +}); + +Module['If'] = makeExpressionWrapper({ + 'getCondition': function(expr) { + return Module['_BinaryenIfGetCondition'](expr); + }, + 'setCondition': function(expr, condExpr) { + Module['_BinaryenIfSetCondition'](expr, condExpr); + }, + 'getIfTrue': function(expr) { + return Module['_BinaryenIfGetIfTrue'](expr); + }, + 'setIfTrue': function(expr, ifTrueExpr) { + Module['_BinaryenIfSetIfTrue'](expr, ifTrueExpr); + }, + 'getIfFalse': function(expr) { + return Module['_BinaryenIfGetIfFalse'](expr); + }, + 'setIfFalse': function(expr, ifFalseExpr) { + Module['_BinaryenIfSetIfFalse'](expr, ifFalseExpr); + } +}); + +Module['Loop'] = makeExpressionWrapper({ + 'getName': function(expr) { + var name = Module['_BinaryenLoopGetName'](expr); + return name ? UTF8ToString(name) : null; + }, + 'setName': function(expr, name) { + preserveStack(function() { + Module['_BinaryenLoopSetName'](expr, strToStack(name)); + }); + }, + 'getBody': function(expr) { + return Module['_BinaryenLoopGetBody'](expr); + }, + 'setBody': function(expr, bodyExpr) { + Module['_BinaryenLoopSetBody'](expr, bodyExpr); + } +}); + +Module['Break'] = makeExpressionWrapper({ + 'getName': function(expr) { + var name = Module['_BinaryenBreakGetName'](expr); + return name ? UTF8ToString(name) : null; + }, + 'setName': function(expr, name) { + preserveStack(function() { + Module['_BinaryenBreakSetName'](expr, strToStack(name)); + }); + }, + 'getCondition': function(expr) { + return Module['_BinaryenBreakGetCondition'](expr); + }, + 'setCondition': function(expr, condExpr) { + Module['_BinaryenBreakSetCondition'](expr, condExpr); + }, + 'getValue': function(expr) { + return Module['_BinaryenBreakGetValue'](expr); + }, + 'setValue': function(expr, valueExpr) { + Module['_BinaryenBreakSetValue'](expr, valueExpr); + } +}); + +Module['Switch'] = makeExpressionWrapper({ + 'getNumNames': function(expr) { + return Module['_BinaryenSwitchGetNumNames'](expr); + }, + 'getNames': function(expr) { + var numNames = Module['_BinaryenSwitchGetNumNames'](expr); + var names = new Array(numNames); + var index = 0; + while (index < numNames) { + names[index] = UTF8ToString(Module['_BinaryenSwitchGetNameAt'](expr, index++)); + } + return names; + }, + 'setNames': function(expr, names) { + var numNames = names.length; + var prevNumNames = Module['_BinaryenSwitchGetNumNames'](expr); + var index = 0; + while (index < numNames) { + preserveStack(function() { + if (index < prevNumNames) { + Module['_BinaryenSwitchSetNameAt'](expr, index, strToStack(names[index])); + } else { + Module['_BinaryenSwitchAppendName'](expr, strToStack(names[index])); + } + }); + ++index; + } + while (prevNumNames > index) { + Module['_BinaryenSwitchRemoveNameAt'](expr, --prevNumNames); + } + }, + 'getDefaultName': function(expr) { + var name = Module['_BinaryenSwitchGetDefaultName'](expr); + return name ? UTF8ToString(name) : null; + }, + 'setDefaultName': function(expr, defaultName) { + preserveStack(function() { + Module['_BinaryenSwitchSetDefaultName'](expr, strToStack(defaultName)); + }); + }, + 'getCondition': function(expr) { + return Module['_BinaryenSwitchGetCondition'](expr); + }, + 'setCondition': function(expr, condExpr) { + Module['_BinaryenSwitchSetCondition'](expr, condExpr); + }, + 'getValue': function(expr) { + return Module['_BinaryenSwitchGetValue'](expr); + }, + 'setValue': function(expr, valueExpr) { + Module['_BinaryenSwitchSetValue'](expr, valueExpr); + }, + 'getNameAt': function(expr, index) { + return UTF8ToString(Module['_BinaryenSwitchGetNameAt'](expr, index)); + }, + 'setNameAt': function(expr, index, name) { + preserveStack(function() { + Module['_BinaryenSwitchSetNameAt'](expr, index, strToStack(name)); + }); + }, + 'appendName': function(expr, name) { + preserveStack(function() { + return Module['_BinaryenSwitchAppendName'](expr, strToStack(name)); + }); + }, + 'insertNameAt': function(expr, index, name) { + preserveStack(function() { + Module['_BinaryenSwitchInsertNameAt'](expr, index, strToStack(name)); + }); + }, + 'removeNameAt': function(expr, index) { + return UTF8ToString(Module['_BinaryenSwitchRemoveNameAt'](expr, index)); + }, +}); + +Module['Call'] = makeExpressionWrapper({ + 'getTarget': function(expr) { + return UTF8ToString(Module['_BinaryenCallGetTarget'](expr)); + }, + 'setTarget': function(expr, targetName) { + preserveStack(function() { + Module['_BinaryenCallSetTarget'](expr, strToStack(targetName)); + }); + }, + 'getNumOperands': function(expr) { + return Module['_BinaryenCallGetNumOperands'](expr); + }, + 'getOperands': function(expr) { + var numOperands = Module['_BinaryenCallGetNumOperands'](expr); + var operands = new Array(numOperands); + var index = 0; + while (index < numOperands) { + operands[index] = Module['_BinaryenCallGetOperandAt'](expr, index++); + } + return operands; + }, + 'setOperands': function(expr, operands) { + var numOperands = operands.length; + var prevNumOperands = Module['_BinaryenCallGetNumOperands'](expr); + var index = 0; + while (index < numOperands) { + if (index < prevNumOperands) { + Module['_BinaryenCallSetOperandAt'](expr, index, operands[index]); + } else { + Module['_BinaryenCallAppendOperand'](expr, operands[index]); + } + ++index; + } + while (prevNumOperands > index) { + Module['_BinaryenCallRemoveOperandAt'](expr, --prevNumOperands); + } + }, + 'getOperandAt': function(expr, index) { + return Module['_BinaryenCallGetOperandAt'](expr, index); + }, + 'setOperandAt': function(expr, index, operandExpr) { + Module['_BinaryenCallSetOperandAt'](expr, index, operandExpr); + }, + 'appendOperand': function(expr, operandExpr) { + return Module['_BinaryenCallAppendOperand'](expr, operandExpr); + }, + 'insertOperandAt': function(expr, index, operandExpr) { + Module['_BinaryenCallInsertOperandAt'](expr, index, operandExpr); + }, + 'removeOperandAt': function(expr, index) { + return Module['_BinaryenCallRemoveOperandAt'](expr, index); + }, + 'isReturn': function(expr) { + return Boolean(Module['_BinaryenCallIsReturn'](expr)); + }, + 'setReturn': function(expr, isReturn) { + Module['_BinaryenCallSetReturn'](expr, isReturn); + } +}); + +Module['CallIndirect'] = makeExpressionWrapper({ + 'getTarget': function(expr) { + return Module['_BinaryenCallIndirectGetTarget'](expr); + }, + 'setTarget': function(expr, targetExpr) { + Module['_BinaryenCallIndirectSetTarget'](expr, targetExpr); + }, + 'getNumOperands': function(expr) { + return Module['_BinaryenCallIndirectGetNumOperands'](expr); + }, + 'getOperands': function(expr) { + var numOperands = Module['_BinaryenCallIndirectGetNumOperands'](expr); + var operands = new Array(numOperands); + var index = 0; + while (index < numOperands) { + operands[index] = Module['_BinaryenCallIndirectGetOperandAt'](expr, index++); + } + return operands; + }, + 'setOperands': function(expr, operands) { + var numOperands = operands.length; + var prevNumOperands = Module['_BinaryenCallIndirectGetNumOperands'](expr); + var index = 0; + while (index < numOperands) { + if (index < prevNumOperands) { + Module['_BinaryenCallIndirectSetOperandAt'](expr, index, operands[index]); + } else { + Module['_BinaryenCallIndirectAppendOperand'](expr, operands[index]); + } + ++index; + } + while (prevNumOperands > index) { + Module['_BinaryenCallIndirectRemoveOperandAt'](expr, --prevNumOperands); + } + }, + 'getOperandAt': function(expr, index) { + return Module['_BinaryenCallIndirectGetOperandAt'](expr, index); + }, + 'setOperandAt': function(expr, index, operandExpr) { + Module['_BinaryenCallIndirectSetOperandAt'](expr, index, operandExpr); + }, + 'appendOperand': function(expr, operandExpr) { + return Module['_BinaryenCallIndirectAppendOperand'](expr, operandExpr); + }, + 'insertOperandAt': function(expr, index, operandExpr) { + Module['_BinaryenCallIndirectInsertOperandAt'](expr, index, operandExpr); + }, + 'removeOperandAt': function(expr, index) { + return Module['_BinaryenCallIndirectRemoveOperandAt'](expr, index); + }, + 'isReturn': function(expr) { + return Boolean(Module['_BinaryenCallIndirectIsReturn'](expr)); + }, + 'setReturn': function(expr, isReturn) { + Module['_BinaryenCallIndirectSetReturn'](expr, isReturn); + }, + 'getParams': function(expr) { + return Module['_BinaryenCallIndirectGetParams'](expr); + }, + 'setParams': function(expr, params) { + Module['_BinaryenCallIndirectSetParams'](expr, params); + }, + 'getResults': function(expr) { + return Module['_BinaryenCallIndirectGetResults'](expr); + }, + 'setResults': function(expr, results) { + Module['_BinaryenCallIndirectSetResults'](expr, results); + } +}); + +Module['LocalGet'] = makeExpressionWrapper({ + 'getIndex': function(expr) { + return Module['_BinaryenLocalGetGetIndex'](expr); + }, + 'setIndex': function(expr, index) { + Module['_BinaryenLocalGetSetIndex'](expr, index); + } +}); + +Module['LocalSet'] = makeExpressionWrapper({ + 'getIndex': function(expr) { + return Module['_BinaryenLocalSetGetIndex'](expr); + }, + 'setIndex': function(expr, index) { + Module['_BinaryenLocalSetSetIndex'](expr, index); + }, + 'isTee': function(expr) { + return Boolean(Module['_BinaryenLocalSetIsTee'](expr)); + }, + 'getValue': function(expr) { + return Module['_BinaryenLocalSetGetValue'](expr); + }, + 'setValue': function(expr, valueExpr) { + Module['_BinaryenLocalSetSetValue'](expr, valueExpr); + } +}); + +Module['GlobalGet'] = makeExpressionWrapper({ + 'getName': function(expr) { + return UTF8ToString(Module['_BinaryenGlobalGetGetName'](expr)); + }, + 'setName': function(expr, name) { + preserveStack(function() { + Module['_BinaryenGlobalGetSetName'](expr, strToStack(name)); + }); + } +}); + +Module['GlobalSet'] = makeExpressionWrapper({ + 'getName': function(expr) { + return UTF8ToString(Module['_BinaryenGlobalSetGetName'](expr)); + }, + 'setName': function(expr, name) { + preserveStack(function() { + Module['_BinaryenGlobalSetSetName'](expr, strToStack(name)); + }); + }, + 'getValue': function(expr) { + return Module['_BinaryenGlobalSetGetValue'](expr); + }, + 'setValue': function(expr, valueExpr) { + Module['_BinaryenGlobalSetSetValue'](expr, valueExpr); + } +}); + +Module['Host'] = makeExpressionWrapper({ + 'getOp': function(expr) { + return Module['_BinaryenHostGetOp'](expr); + }, + 'setOp': function(expr, op) { + Module['_BinaryenHostSetOp'](expr, op); + }, + 'getNameOperand': function(expr) { + var name = Module['_BinaryenHostGetNameOperand'](expr); + return name ? UTF8ToString(name) : null; + }, + 'setNameOperand': function(expr, name) { + preserveStack(function() { + Module['_BinaryenHostSetNameOperand'](expr, strToStack(name)); + }); + }, + 'getNumOperands': function(expr) { + return Module['_BinaryenHostGetNumOperands'](expr); + }, + 'getOperands': function(expr) { + var numOperands = Module['_BinaryenHostGetNumOperands'](expr); + var operands = new Array(numOperands); + var index = 0; + while (index < numOperands) { + operands[index] = Module['_BinaryenHostGetOperandAt'](expr, index++); + } + return operands; + }, + 'setOperands': function(expr, operands) { + var numOperands = operands.length; + var prevNumOperands = Module['_BinaryenHostGetNumOperands'](expr); + var index = 0; + while (index < numOperands) { + if (index < prevNumOperands) { + Module['_BinaryenHostSetOperandAt'](expr, index, operands[index]); + } else { + Module['_BinaryenHostAppendOperand'](expr, operands[index]); + } + ++index; + } + while (prevNumOperands > index) { + Module['_BinaryenHostRemoveOperandAt'](expr, --prevNumOperands); + } + }, + 'getOperandAt': function(expr, index) { + return Module['_BinaryenHostGetOperandAt'](expr, index); + }, + 'setOperandAt': function(expr, index, operandExpr) { + Module['_BinaryenHostSetOperandAt'](expr, index, operandExpr); + }, + 'appendOperand': function(expr, operandExpr) { + return Module['_BinaryenHostAppendOperand'](expr, operandExpr); + }, + 'insertOperandAt': function(expr, index, operandExpr) { + Module['_BinaryenHostInsertOperandAt'](expr, index, operandExpr); + }, + 'removeOperandAt': function(expr, index) { + return Module['_BinaryenHostRemoveOperandAt'](expr, index); + }, +}); + +Module['Load'] = makeExpressionWrapper({ + 'isAtomic': function(expr) { + return Boolean(Module['_BinaryenLoadIsAtomic'](expr)); + }, + 'setAtomic': function(expr, isAtomic) { + Module['_BinaryenLoadSetAtomic'](expr, isAtomic); + }, + 'isSigned': function(expr) { + return Boolean(Module['_BinaryenLoadIsSigned'](expr)); + }, + 'setSigned': function(expr, isSigned) { + Module['_BinaryenLoadSetSigned'](expr, isSigned); + }, + 'getOffset': function(expr) { + return Module['_BinaryenLoadGetOffset'](expr); + }, + 'setOffset': function(expr, offset) { + Module['_BinaryenLoadSetOffset'](expr, offset); + }, + 'getBytes': function(expr) { + return Module['_BinaryenLoadGetBytes'](expr); + }, + 'setBytes': function(expr, bytes) { + Module['_BinaryenLoadSetBytes'](expr, bytes); + }, + 'getAlign': function(expr) { + return Module['_BinaryenLoadGetAlign'](expr); + }, + 'setAlign': function(expr, align) { + Module['_BinaryenLoadSetAlign'](expr, align); + }, + 'getPtr': function(expr) { + return Module['_BinaryenLoadGetPtr'](expr); + }, + 'setPtr': function(expr, ptrExpr) { + Module['_BinaryenLoadSetPtr'](expr, ptrExpr); + } +}); + +Module['Store'] = makeExpressionWrapper({ + 'isAtomic': function(expr) { + return Boolean(Module['_BinaryenStoreIsAtomic'](expr)); + }, + 'setAtomic': function(expr, isAtomic) { + Module['_BinaryenStoreSetAtomic'](expr, isAtomic); + }, + 'getBytes': function(expr) { + return Module['_BinaryenStoreGetBytes'](expr); + }, + 'setBytes': function(expr, bytes) { + Module['_BinaryenStoreSetBytes'](expr, bytes); + }, + 'getOffset': function(expr) { + return Module['_BinaryenStoreGetOffset'](expr); + }, + 'setOffset': function(expr, offset) { + Module['_BinaryenStoreSetOffset'](expr, offset); + }, + 'getAlign': function(expr) { + return Module['_BinaryenStoreGetAlign'](expr); + }, + 'setAlign': function(expr, align) { + Module['_BinaryenStoreSetAlign'](expr, align); + }, + 'getPtr': function(expr) { + return Module['_BinaryenStoreGetPtr'](expr); + }, + 'setPtr': function(expr, ptrExpr) { + Module['_BinaryenStoreSetPtr'](expr, ptrExpr); + }, + 'getValue': function(expr) { + return Module['_BinaryenStoreGetValue'](expr); + }, + 'setValue': function(expr, valueExpr) { + Module['_BinaryenStoreSetValue'](expr, valueExpr); + }, + 'getValueType': function(expr) { + return Module['_BinaryenStoreGetValueType'](expr); + }, + 'setValueType': function(expr, valueType) { + Module['_BinaryenStoreSetValueType'](expr, valueType); + } +}); + +Module['Const'] = makeExpressionWrapper({ + 'getValueI32': function(expr) { + return Module['_BinaryenConstGetValueI32'](expr); + }, + 'setValueI32': function(expr, value) { + Module['_BinaryenConstSetValueI32'](expr, value); + }, + 'getValueI64Low': function(expr) { + return Module['_BinaryenConstGetValueI64Low'](expr); + }, + 'setValueI64Low': function(expr, value) { + Module['_BinaryenConstSetValueI64Low'](expr, value); + }, + 'getValueI64High': function(expr) { + return Module['_BinaryenConstGetValueI64High'](expr); + }, + 'setValueI64High': function(expr, value) { + Module['_BinaryenConstSetValueI64High'](expr, value); + }, + 'getValueF32': function(expr) { + return Module['_BinaryenConstGetValueF32'](expr); + }, + 'setValueF32': function(expr, value) { + Module['_BinaryenConstSetValueF32'](expr, value); + }, + 'getValueF64': function(expr) { + return Module['_BinaryenConstGetValueF64'](expr); + }, + 'setValueF64': function(expr, value) { + Module['_BinaryenConstSetValueF64'](expr, value); + }, + 'getValueV128': function(expr) { + var value; + preserveStack(function() { + var tempBuffer = stackAlloc(16); + Module['_BinaryenConstGetValueV128'](expr, tempBuffer); + value = new Array(16); + for (var i = 0 ; i < 16; ++i) { + value[i] = HEAPU8[tempBuffer + i]; + } + }); + return value; + }, + 'setValueV128': function(expr, value) { + preserveStack(function() { + var tempBuffer = stackAlloc(16); + for (var i = 0 ; i < 16; ++i) { + HEAPU8[tempBuffer + i] = value[i]; + } + Module['_BinaryenConstSetValueV128'](expr, tempBuffer); + }); + } +}); + +Module['Unary'] = makeExpressionWrapper({ + 'getOp': function(expr) { + return Module['_BinaryenUnaryGetOp'](expr); + }, + 'setOp': function(expr, op) { + Module['_BinaryenUnarySetOp'](expr, op); + }, + 'getValue': function(expr) { + return Module['_BinaryenUnaryGetValue'](expr); + }, + 'setValue': function(expr, valueExpr) { + Module['_BinaryenUnarySetValue'](expr, valueExpr); + } +}); + +Module['Binary'] = makeExpressionWrapper({ + 'getOp': function(expr) { + return Module['_BinaryenBinaryGetOp'](expr); + }, + 'setOp': function(expr, op) { + Module['_BinaryenBinarySetOp'](expr, op); + }, + 'getLeft': function(expr) { + return Module['_BinaryenBinaryGetLeft'](expr); + }, + 'setLeft': function(expr, leftExpr) { + Module['_BinaryenBinarySetLeft'](expr, leftExpr); + }, + 'getRight': function(expr) { + return Module['_BinaryenBinaryGetRight'](expr); + }, + 'setRight': function(expr, rightExpr) { + Module['_BinaryenBinarySetRight'](expr, rightExpr); + } +}); + +Module['Select'] = makeExpressionWrapper({ + 'getIfTrue': function(expr) { + return Module['_BinaryenSelectGetIfTrue'](expr); + }, + 'setIfTrue': function(expr, ifTrueExpr) { + Module['_BinaryenSelectSetIfTrue'](expr, ifTrueExpr); + }, + 'getIfFalse': function(expr) { + return Module['_BinaryenSelectGetIfFalse'](expr); + }, + 'setIfFalse': function(expr, ifFalseExpr) { + Module['_BinaryenSelectSetIfFalse'](expr, ifFalseExpr); + }, + 'getCondition': function(expr) { + return Module['_BinaryenSelectGetCondition'](expr); + }, + 'setCondition': function(expr, condExpr) { + Module['_BinaryenSelectSetCondition'](expr, condExpr); + } +}); + +Module['Drop'] = makeExpressionWrapper({ + 'getValue': function(expr) { + return Module['_BinaryenDropGetValue'](expr); + }, + 'setValue': function(expr, valueExpr) { + Module['_BinaryenDropSetValue'](expr, valueExpr); + } +}); + +Module['Return'] = makeExpressionWrapper({ + 'getValue': function(expr) { + return Module['_BinaryenReturnGetValue'](expr); + }, + 'setValue': function(expr, valueExpr) { + Module['_BinaryenReturnSetValue'](expr, valueExpr); + } +}); + +Module['AtomicRMW'] = makeExpressionWrapper({ + 'getOp': function(expr) { + return Module['_BinaryenAtomicRMWGetOp'](expr); + }, + 'setOp': function(expr, op) { + Module['_BinaryenAtomicRMWSetOp'](expr, op); + }, + 'getBytes': function(expr) { + return Module['_BinaryenAtomicRMWGetBytes'](expr); + }, + 'setBytes': function(expr, bytes) { + Module['_BinaryenAtomicRMWSetBytes'](expr, bytes); + }, + 'getOffset': function(expr) { + return Module['_BinaryenAtomicRMWGetOffset'](expr); + }, + 'setOffset': function(expr, offset) { + Module['_BinaryenAtomicRMWSetOffset'](expr, offset); + }, + 'getPtr': function(expr) { + return Module['_BinaryenAtomicRMWGetPtr'](expr); + }, + 'setPtr': function(expr, ptrExpr) { + Module['_BinaryenAtomicRMWSetPtr'](expr, ptrExpr); + }, + 'getValue': function(expr) { + return Module['_BinaryenAtomicRMWGetValue'](expr); + }, + 'setValue': function(expr, valueExpr) { + Module['_BinaryenAtomicRMWSetValue'](expr, valueExpr); + } +}); + +Module['AtomicCmpxchg'] = makeExpressionWrapper({ + 'getBytes': function(expr) { + return Module['_BinaryenAtomicCmpxchgGetBytes'](expr); + }, + 'setBytes': function(expr, bytes) { + Module['_BinaryenAtomicCmpxchgSetBytes'](expr, bytes); + }, + 'getOffset': function(expr) { + return Module['_BinaryenAtomicCmpxchgGetOffset'](expr); + }, + 'setOffset': function(expr, offset) { + Module['_BinaryenAtomicCmpxchgSetOffset'](expr, offset); + }, + 'getPtr': function(expr) { + return Module['_BinaryenAtomicCmpxchgGetPtr'](expr); + }, + 'setPtr': function(expr, ptrExpr) { + Module['_BinaryenAtomicCmpxchgSetPtr'](expr, ptrExpr); + }, + 'getExpected': function(expr) { + return Module['_BinaryenAtomicCmpxchgGetExpected'](expr); + }, + 'setExpected': function(expr, expectedExpr) { + Module['_BinaryenAtomicCmpxchgSetExpected'](expr, expectedExpr); + }, + 'getReplacement': function(expr) { + return Module['_BinaryenAtomicCmpxchgGetReplacement'](expr); + }, + 'setReplacement': function(expr, replacementExpr) { + Module['_BinaryenAtomicCmpxchgSetReplacement'](expr, replacementExpr); + } +}); + +Module['AtomicWait'] = makeExpressionWrapper({ + 'getPtr': function(expr) { + return Module['_BinaryenAtomicWaitGetPtr'](expr); + }, + 'setPtr': function(expr, ptrExpr) { + Module['_BinaryenAtomicWaitSetPtr'](expr, ptrExpr); + }, + 'getExpected': function(expr) { + return Module['_BinaryenAtomicWaitGetExpected'](expr); + }, + 'setExpected': function(expr, expectedExpr) { + Module['_BinaryenAtomicWaitSetExpected'](expr, expectedExpr); + }, + 'getTimeout': function(expr) { + return Module['_BinaryenAtomicWaitGetTimeout'](expr); + }, + 'setTimeout': function(expr, timeoutExpr) { + Module['_BinaryenAtomicWaitSetTimeout'](expr, timeoutExpr); + }, + 'getExpectedType': function(expr) { + return Module['_BinaryenAtomicWaitGetExpectedType'](expr); + }, + 'setExpectedType': function(expr, expectedType) { + Module['_BinaryenAtomicWaitSetExpectedType'](expr, expectedType); + } +}); + +Module['AtomicNotify'] = makeExpressionWrapper({ + 'getPtr': function(expr) { + return Module['_BinaryenAtomicNotifyGetPtr'](expr); + }, + 'setPtr': function(expr, ptrExpr) { + Module['_BinaryenAtomicNotifySetPtr'](expr, ptrExpr); + }, + 'getNotifyCount': function(expr) { + return Module['_BinaryenAtomicNotifyGetNotifyCount'](expr); + }, + 'setNotifyCount': function(expr, notifyCountExpr) { + Module['_BinaryenAtomicNotifySetNotifyCount'](expr, notifyCountExpr); + } +}); + +Module['AtomicFence'] = makeExpressionWrapper({ + 'getOrder': function(expr) { + return Module['_BinaryenAtomicFenceGetOrder'](expr); + }, + 'setOrder': function(expr, order) { + Module['_BinaryenAtomicFenceSetOrder'](expr, order); + } +}); + +Module['SIMDExtract'] = makeExpressionWrapper({ + 'getOp': function(expr) { + return Module['_BinaryenSIMDExtractGetOp'](expr); + }, + 'setOp': function(expr, op) { + Module['_BinaryenSIMDExtractSetOp'](expr, op); + }, + 'getVec': function(expr) { + return Module['_BinaryenSIMDExtractGetVec'](expr); + }, + 'setVec': function(expr, vecExpr) { + Module['_BinaryenSIMDExtractSetVec'](expr, vecExpr); + }, + 'getIndex': function(expr) { + return Module['_BinaryenSIMDExtractGetIndex'](expr); + }, + 'setIndex': function(expr, index) { + Module['_BinaryenSIMDExtractSetIndex'](expr, index) + } +}); + +Module['SIMDReplace'] = makeExpressionWrapper({ + 'getOp': function(expr) { + return Module['_BinaryenSIMDReplaceGetOp'](expr); + }, + 'setOp': function(expr, op) { + Module['_BinaryenSIMDReplaceSetOp'](expr, op); + }, + 'getVec': function(expr) { + return Module['_BinaryenSIMDReplaceGetVec'](expr); + }, + 'setVec': function(expr, vecExpr) { + Module['_BinaryenSIMDReplaceSetVec'](expr, vecExpr); + }, + 'getIndex': function(expr) { + return Module['_BinaryenSIMDReplaceGetIndex'](expr); + }, + 'setIndex': function(expr, index) { + Module['_BinaryenSIMDReplaceSetIndex'](expr, index); + }, + 'getValue': function(expr) { + return Module['_BinaryenSIMDReplaceGetValue'](expr); + }, + 'setValue': function(expr, valueExpr) { + Module['_BinaryenSIMDReplaceSetValue'](expr, valueExpr); + } +}); + +Module['SIMDShuffle'] = makeExpressionWrapper({ + 'getLeft': function(expr) { + return Module['_BinaryenSIMDShuffleGetLeft'](expr); + }, + 'setLeft': function(expr, leftExpr) { + Module['_BinaryenSIMDShuffleSetLeft'](expr, leftExpr) + }, + 'getRight': function(expr) { + return Module['_BinaryenSIMDShuffleGetRight'](expr); + }, + 'setRight': function(expr, rightExpr) { + Module['_BinaryenSIMDShuffleSetRight'](expr, rightExpr); + }, + 'getMask': function(expr) { + var mask; + preserveStack(function() { + var tempBuffer = stackAlloc(16); + Module['_BinaryenSIMDShuffleGetMask'](expr, tempBuffer); + mask = new Array(16); + for (var i = 0 ; i < 16; ++i) { + mask[i] = HEAPU8[tempBuffer + i]; + } + }); + return mask; + }, + 'setMask': function(expr, mask) { + preserveStack(function() { + var tempBuffer = stackAlloc(16); + for (var i = 0 ; i < 16; ++i) { + HEAPU8[tempBuffer + i] = mask[i]; + } + Module['_BinaryenSIMDShuffleSetMask'](expr, tempBuffer); + }); + } +}); + +Module['SIMDTernary'] = makeExpressionWrapper({ + 'getOp': function(expr) { + return Module['_BinaryenSIMDTernaryGetOp'](expr); + }, + 'setOp': function(expr, op) { + Module['_BinaryenSIMDTernarySetOp'](expr, op); + }, + 'getA': function(expr) { + return Module['_BinaryenSIMDTernaryGetA'](expr); + }, + 'setA': function(expr, aExpr) { + Module['_BinaryenSIMDTernarySetA'](expr, aExpr); + }, + 'getB': function(expr) { + return Module['_BinaryenSIMDTernaryGetB'](expr); + }, + 'setB': function(expr, bExpr) { + Module['_BinaryenSIMDTernarySetB'](expr, bExpr); + }, + 'getC': function(expr) { + return Module['_BinaryenSIMDTernaryGetC'](expr); + }, + 'setC': function(expr, cExpr) { + Module['_BinaryenSIMDTernarySetC'](expr, cExpr); + } +}); + +Module['SIMDShift'] = makeExpressionWrapper({ + 'getOp': function(expr) { + return Module['_BinaryenSIMDShiftGetOp'](expr); + }, + 'setOp': function(expr, op) { + Module['_BinaryenSIMDShiftSetOp'](expr, op); + }, + 'getVec': function(expr) { + return Module['_BinaryenSIMDShiftGetVec'](expr); + }, + 'setVec': function(expr, vecExpr) { + Module['_BinaryenSIMDShiftSetVec'](expr, vecExpr); + }, + 'getShift': function(expr) { + return Module['_BinaryenSIMDShiftGetShift'](expr); + }, + 'setShift': function(expr, shiftExpr) { + Module['_BinaryenSIMDShiftSetShift'](expr, shiftExpr); + } +}); + +Module['SIMDLoad'] = makeExpressionWrapper({ + 'getOp': function(expr) { + return Module['_BinaryenSIMDLoadGetOp'](expr); + }, + 'setOp': function(expr, op) { + Module['_BinaryenSIMDLoadSetOp'](expr, op); + }, + 'getOffset': function(expr) { + return Module['_BinaryenSIMDLoadGetOffset'](expr); + }, + 'setOffset': function(expr, offset) { + Module['_BinaryenSIMDLoadSetOffset'](expr, offset); + }, + 'getAlign': function(expr) { + return Module['_BinaryenSIMDLoadGetAlign'](expr); + }, + 'setAlign': function(expr, align) { + Module['_BinaryenSIMDLoadSetAlign'](expr, align); + }, + 'getPtr': function(expr) { + return Module['_BinaryenSIMDLoadGetPtr'](expr); + }, + 'setPtr': function(expr, ptrExpr) { + Module['_BinaryenSIMDLoadSetPtr'](expr, ptrExpr); + } +}); + +Module['MemoryInit'] = makeExpressionWrapper({ + 'getSegment': function(expr) { + return Module['_BinaryenMemoryInitGetSegment'](expr); + }, + 'setSegment': function(expr, segmentIndex) { + Module['_BinaryenMemoryInitSetSegment'](expr, segmentIndex); + }, + 'getDest': function(expr) { + return Module['_BinaryenMemoryInitGetDest'](expr); + }, + 'setDest': function(expr, destExpr) { + Module['_BinaryenMemoryInitSetDest'](expr, destExpr); + }, + 'getOffset': function(expr) { + return Module['_BinaryenMemoryInitGetOffset'](expr); + }, + 'setOffset': function(expr, offset) { + Module['_BinaryenMemoryInitSetOffset'](expr, offset); + }, + 'getSize': function(expr) { + return Module['_BinaryenMemoryInitGetSize'](expr); + }, + 'setSize': function(expr, sizeExpr) { + Module['_BinaryenMemoryInitSetSize'](expr, sizeExpr); + } +}); + +Module['DataDrop'] = makeExpressionWrapper({ + 'getSegment': function(expr) { + return Module['_BinaryenDataDropGetSegment'](expr); + }, + 'setSegment': function(expr, segmentIndex) { + Module['_BinaryenDataDropSetSegment'](expr, segmentIndex); + } +}); + +Module['MemoryCopy'] = makeExpressionWrapper({ + 'getDest': function(expr) { + return Module['_BinaryenMemoryCopyGetDest'](expr); + }, + 'setDest': function(expr, destExpr) { + Module['_BinaryenMemoryCopySetDest'](expr, destExpr); + }, + 'getSource': function(expr) { + return Module['_BinaryenMemoryCopyGetSource'](expr); + }, + 'setSource': function(expr, sourceExpr) { + Module['_BinaryenMemoryCopySetSource'](expr, sourceExpr); + }, + 'getSize': function(expr) { + return Module['_BinaryenMemoryCopyGetSize'](expr); + }, + 'setSize': function(expr, sizeExpr) { + Module['_BinaryenMemoryCopySetSize'](expr, sizeExpr); + } +}); + +Module['MemoryFill'] = makeExpressionWrapper({ + 'getDest': function(expr) { + return Module['_BinaryenMemoryFillGetDest'](expr); + }, + 'setDest': function(expr, destExpr) { + Module['_BinaryenMemoryFillSetDest'](expr, destExpr); + }, + 'getValue': function(expr) { + return Module['_BinaryenMemoryFillGetValue'](expr); + }, + 'setValue': function(expr, valueExpr) { + Module['_BinaryenMemoryFillSetValue'](expr, valueExpr); + }, + 'getSize': function(expr) { + return Module['_BinaryenMemoryFillGetSize'](expr); + }, + 'setSize': function(expr, sizeExpr) { + Module['_BinaryenMemoryFillSetSize'](expr, sizeExpr); + } +}); + +Module['RefIsNull'] = makeExpressionWrapper({ + 'getValue': function(expr) { + return Module['_BinaryenRefIsNullGetValue'](expr); + }, + 'setValue': function(expr, valueExpr) { + Module['_BinaryenRefIsNullSetValue'](expr, valueExpr); + } +}); + +Module['RefFunc'] = makeExpressionWrapper({ + 'getFunc': function(expr) { + return UTF8ToString(Module['_BinaryenRefFuncGetFunc'](expr)); + }, + 'setFunc': function(expr, funcName) { + preserveStack(function() { + Module['_BinaryenRefFuncSetFunc'](expr, strToStack(funcName)); + }); + } +}); + +Module['Try'] = makeExpressionWrapper({ + 'getBody': function(expr) { + return Module['_BinaryenTryGetBody'](expr); + }, + 'setBody': function(expr, bodyExpr) { + Module['_BinaryenTrySetBody'](expr, bodyExpr); + }, + 'getCatchBody': function(expr) { + return Module['_BinaryenTryGetCatchBody'](expr); + }, + 'setCatchBody': function(expr, catchBodyExpr) { + Module['_BinaryenTrySetCatchBody'](expr, catchBodyExpr); + } +}); + +Module['Throw'] = makeExpressionWrapper({ + 'getEvent': function(expr) { + return UTF8ToString(Module['_BinaryenThrowGetEvent'](expr)); + }, + 'setEvent': function(expr, eventName) { + preserveStack(function() { + Module['_BinaryenThrowSetEvent'](expr, strToStack(eventName)); + }); + }, + 'getNumOperands': function(expr) { + return Module['_BinaryenThrowGetNumOperands'](expr); + }, + 'getOperands': function(expr) { + var numOperands = Module['_BinaryenThrowGetNumOperands'](expr); + var operands = new Array(numOperands); + var index = 0; + while (index < numOperands) { + operands[index] = Module['_BinaryenThrowGetOperandAt'](expr, index++); + } + return operands; + }, + 'setOperands': function(expr, operands) { + var numOperands = operands.length; + var prevNumOperands = Module['_BinaryenThrowGetNumOperands'](expr); + var index = 0; + while (index < numOperands) { + if (index < prevNumOperands) { + Module['_BinaryenThrowSetOperandAt'](expr, index, operands[index]); + } else { + Module['_BinaryenThrowAppendOperand'](expr, operands[index]); + } + ++index; + } + while (prevNumOperands > index) { + Module['_BinaryenThrowRemoveOperandAt'](expr, --prevNumOperands); + } + }, + 'getOperandAt': function(expr, index) { + return Module['_BinaryenThrowGetOperandAt'](expr, index); + }, + 'setOperandAt': function(expr, index, operandExpr) { + Module['_BinaryenThrowSetOperandAt'](expr, index, operandExpr); + }, + 'appendOperand': function(expr, operandExpr) { + return Module['_BinaryenThrowAppendOperand'](expr, operandExpr); + }, + 'insertOperandAt': function(expr, index, operandExpr) { + Module['_BinaryenThrowInsertOperandAt'](expr, index, operandExpr); + }, + 'removeOperandAt': function(expr, index) { + return Module['_BinaryenThrowRemoveOperandAt'](expr, index); + }, +}); + +Module['Rethrow'] = makeExpressionWrapper({ + 'getExnref': function(expr) { + return Module['_BinaryenRethrowGetExnref'](expr); + }, + 'setExnref': function(expr, exnrefExpr) { + Module['_BinaryenRethrowSetExnref'](expr, exnrefExpr); + } +}); + +Module['BrOnExn'] = makeExpressionWrapper({ + 'getEvent': function(expr) { + return UTF8ToString(Module['_BinaryenBrOnExnGetEvent'](expr)); + }, + 'setEvent': function(expr, eventName) { + preserveStack(function() { + Module['_BinaryenBrOnExnSetEvent'](expr, strToStack(eventName)); + }); + }, + 'getName': function(expr) { + return UTF8ToString(Module['_BinaryenBrOnExnGetName'](expr)); + }, + 'setName': function(expr, name) { + preserveStack(function() { + Module['_BinaryenBrOnExnSetName'](expr, strToStack(name)); + }); + }, + 'getExnref': function(expr) { + return Module['_BinaryenBrOnExnGetExnref'](expr); + }, + 'setExnref': function(expr, exnrefExpr) { + Module['_BinaryenBrOnExnSetExnref'](expr, exnrefExpr); + } +}); + +Module['TupleMake'] = makeExpressionWrapper({ + 'getNumOperands': function(expr) { + return Module['_BinaryenTupleMakeGetNumOperands'](expr); + }, + 'getOperands': function(expr) { + var numOperands = Module['_BinaryenTupleMakeGetNumOperands'](expr); + var operands = new Array(numOperands); + var index = 0; + while (index < numOperands) { + operands[index] = Module['_BinaryenTupleMakeGetOperandAt'](expr, index++); + } + return operands; + }, + 'setOperands': function(expr, operands) { + var numOperands = operands.length; + var prevNumOperands = Module['_BinaryenTupleMakeGetNumOperands'](expr); + var index = 0; + while (index < numOperands) { + if (index < prevNumOperands) { + Module['_BinaryenTupleMakeSetOperandAt'](expr, index, operands[index]); + } else { + Module['_BinaryenTupleMakeAppendOperand'](expr, operands[index]); + } + ++index; + } + while (prevNumOperands > index) { + Module['_BinaryenTupleMakeRemoveOperandAt'](expr, --prevNumOperands); + } + }, + 'getOperandAt': function(expr, index) { + return Module['_BinaryenTupleMakeGetOperandAt'](expr, index); + }, + 'setOperandAt': function(expr, index, operandExpr) { + Module['_BinaryenTupleMakeSetOperandAt'](expr, index, operandExpr); + }, + 'appendOperand': function(expr, operandExpr) { + return Module['_BinaryenTupleMakeAppendOperand'](expr, operandExpr); + }, + 'insertOperandAt': function(expr, index, operandExpr) { + Module['_BinaryenTupleMakeInsertOperandAt'](expr, index, operandExpr); + }, + 'removeOperandAt': function(expr, index) { + return Module['_BinaryenTupleMakeRemoveOperandAt'](expr, index); + } +}); + +Module['TupleExtract'] = makeExpressionWrapper({ + 'getTuple': function(expr) { + return Module['_BinaryenTupleExtractGetTuple'](expr); + }, + 'setTuple': function(expr, tupleExpr) { + Module['_BinaryenTupleExtractSetTuple'](expr, tupleExpr); + }, + 'getIndex': function(expr) { + return Module['_BinaryenTupleExtractGetIndex'](expr); + }, + 'setIndex': function(expr, index) { + Module['_BinaryenTupleExtractSetIndex'](expr, index); + } +}); + // Additional customizations Module['exit'] = function(status) { diff --git a/src/mixed_arena.h b/src/mixed_arena.h index 079ce9028a3..9ae19f94d5c 100644 --- a/src/mixed_arena.h +++ b/src/mixed_arena.h @@ -364,6 +364,27 @@ template class ArenaVectorBase { void allocate(size_t size) { abort(); // must be implemented in children } + + // C-API + + void insertAt(size_t index, T item) { + assert(index <= usedElements); // appending is ok + resize(usedElements + 1); + for (auto i = usedElements; i > index; --i) { + data[i] = data[i - 1]; + } + data[index] = item; + } + + T removeAt(size_t index) { + assert(index < usedElements); + auto item = data[index]; + for (auto i = index; i < usedElements - 1; ++i) { + data[i] = data[i + 1]; + } + resize(usedElements - 1); + return item; + } }; // A vector that has an allocator for arena allocation diff --git a/src/wasm.h b/src/wasm.h index b52e7539baf..fafb03d412b 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -862,6 +862,8 @@ class AtomicFence : public SpecificExpression { // other orderings may be added in the future. This field is reserved for // that, and currently set to 0. uint8_t order = 0; + + void finalize(); }; class SIMDExtract : public SpecificExpression { diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index f1d51bbca6f..adaa818386b 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -522,6 +522,8 @@ void AtomicNotify::finalize() { } } +void AtomicFence::finalize() { type = Type::none; } + void SIMDExtract::finalize() { assert(vec); switch (op) { diff --git a/test/binaryen.js/expressions.js b/test/binaryen.js/expressions.js new file mode 100644 index 00000000000..a0f3e6d4b8d --- /dev/null +++ b/test/binaryen.js/expressions.js @@ -0,0 +1,1605 @@ +function assertDeepEqual(x, y) { + if (typeof x === "object") { + for (let i in x) assertDeepEqual(x[i], y[i]); + for (let i in y) assertDeepEqual(x[i], y[i]); + } else { + assert(x === y); + } +} + +console.log("# Expression"); +(function testWrapper() { + var theExpression = binaryen.Block(42); // works without new + assert(theExpression instanceof binaryen.Block); + assert(theExpression instanceof binaryen.Expression); + assert(theExpression.constructor === binaryen.Block); + assert(typeof binaryen.Block.getId === "function"); // proto + assert(typeof binaryen.Block.getName === "function"); // own + assert(typeof theExpression.getId === "function"); // proto + assert(typeof theExpression.getName === "function"); // own + assert(theExpression.expr === 42); + assert((theExpression | 0) === 42); // via valueOf +})(); + +console.log("# Block"); +(function testBlock() { + const module = new binaryen.Module(); + + const theBlock = binaryen.Block(module.block(null, [])); + assert(theBlock instanceof binaryen.Block); + assert(theBlock instanceof binaryen.Expression); + assert(theBlock.id === binaryen.BlockId); + assert(theBlock.name === null); + assert(theBlock.type === binaryen.none); + + theBlock.name ="theName"; + assert(theBlock.name === "theName"); + theBlock.type = binaryen.i32; + assert(theBlock.type === binaryen.i32); + assert(theBlock.numChildren === 0); + assertDeepEqual(theBlock.children, []); + + var child1 = module.i32.const(1); + theBlock.appendChild(child1); + assert(theBlock.numChildren === 1); + assert(theBlock.getChildAt(0) === child1); + var child2 = module.i32.const(2); + theBlock.insertChildAt(1, child2); + assert(theBlock.numChildren === 2); + assert(theBlock.getChildAt(0) === child1); + assert(theBlock.getChildAt(1) === child2); + var child0 = module.i32.const(0); + theBlock.insertChildAt(0, child0); + assert(theBlock.numChildren === 3); + assert(theBlock.getChildAt(0) === child0); + assert(theBlock.getChildAt(1) === child1); + assert(theBlock.getChildAt(2) === child2); + var newChild1 = module.i32.const(11); + theBlock.setChildAt(1, newChild1); + assert(theBlock.numChildren === 3); + assert(theBlock.getChildAt(0) === child0); + assert(theBlock.getChildAt(1) === newChild1); + assert(theBlock.getChildAt(2) === child2); + theBlock.removeChildAt(1); + assert(theBlock.numChildren === 2); + assert(theBlock.getChildAt(0) === child0); + assert(theBlock.getChildAt(1) === child2); + theBlock.removeChildAt(1); + assert(theBlock.numChildren === 1); + assert(theBlock.getChildAt(0) === child0); + theBlock.finalize(); + + console.log(theBlock.toText()); + assert( + theBlock.toText() + == + "(block $theName (result i32)\n (i32.const 0)\n)\n" + ); + theBlock.removeChildAt(0); + assert(theBlock.numChildren === 0); + + module.dispose(); +})(); + +console.log("# If"); +(function testIf() { + const module = new binaryen.Module(); + + var condition = module.i32.const(1); + var ifTrue = module.i32.const(2); + var ifFalse = module.i32.const(3); + const theIf = binaryen.If(module.if(condition, ifTrue, ifFalse)); + assert(theIf instanceof binaryen.If); + assert(theIf instanceof binaryen.Expression); + assert(theIf.id === binaryen.IfId); + assert(theIf.condition === condition); + assert(theIf.ifTrue === ifTrue); + assert(theIf.ifFalse === ifFalse); + assert(theIf.type == binaryen.i32); + + theIf.condition = condition = module.i32.const(4); + assert(theIf.condition === condition); + theIf.ifTrue = ifTrue = module.i32.const(5); + assert(theIf.ifTrue === ifTrue); + theIf.ifFalse = ifFalse = module.i32.const(6); + assert(theIf.ifFalse === ifFalse); + theIf.finalize(); + + console.log(theIf.toText()); + assert( + theIf.toText() + == + "(if (result i32)\n (i32.const 4)\n (i32.const 5)\n (i32.const 6)\n)\n" + ); + + theIf.ifFalse = null; + assert(!theIf.ifFalse); + console.log(theIf.toText()); + assert( + theIf.toText() + == + "(if (result i32)\n (i32.const 4)\n (i32.const 5)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# Loop"); +(function testLoop() { + const module = new binaryen.Module(); + + var name = null; + var body = module.i32.const(1); + const theLoop = binaryen.Loop(module.loop(name, body)); + assert(theLoop instanceof binaryen.Loop); + assert(theLoop instanceof binaryen.Expression); + assert(theLoop.id === binaryen.LoopId); + assert(theLoop.name === name); + assert(theLoop.body === body); + assert(theLoop.type === binaryen.i32); + + theLoop.name = name = "theName"; + assert(theLoop.name === name); + theLoop.body = body = module.drop(body); + assert(theLoop.body === body); + theLoop.finalize(); + assert(theLoop.type === binaryen.none); + + console.log(theLoop.toText()); + assert( + theLoop.toText() + == + "(loop $theName\n (drop\n (i32.const 1)\n )\n)\n" + ); + + module.dispose(); +})(); + +console.log("# Break"); +(function testBreak() { + const module = new binaryen.Module(); + + var name = "theName"; + var condition = module.i32.const(1); + var value = module.i32.const(2); + const theBreak = binaryen.Break(module.br(name, condition, value)); + assert(theBreak instanceof binaryen.Break); + assert(theBreak instanceof binaryen.Expression); + assert(theBreak.name === name); + assert(theBreak.condition === condition); + assert(theBreak.value === value); + assert(theBreak.type === binaryen.i32); + + theBreak.name = name = "theNewName"; + assert(theBreak.name === "theNewName"); + theBreak.condition = condition = module.i32.const(3); + assert(theBreak.condition === condition); + theBreak.value = value = module.i32.const(4); + assert(theBreak.value === value); + theBreak.finalize(); + + console.log(theBreak.toText()); + assert( + theBreak.toText() + == + "(br_if $theNewName\n (i32.const 4)\n (i32.const 3)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# Switch"); +(function testSwitch() { + const module = new binaryen.Module(); + + var names = ["a", "b"]; + var defaultName = "c"; + var condition = module.i32.const(1); + var value = module.i32.const(2); + const theSwitch = binaryen.Switch(module.switch(names, defaultName, condition, value)); + assert(theSwitch instanceof binaryen.Switch); + assert(theSwitch instanceof binaryen.Expression); + assert(theSwitch.numNames === 2); + assertDeepEqual(theSwitch.names, names); + assert(theSwitch.defaultName === defaultName); + assert(theSwitch.condition === condition); + assert(theSwitch.value === value); + assert(theSwitch.type === binaryen.unreachable); + + theSwitch.names = names = [ + "1", // set + "2", // set + "3" // append + ]; + assertDeepEqual(theSwitch.names, names); + theSwitch.names = names = [ + "x", // set + // remove + // remove + ]; + assertDeepEqual(theSwitch.names, names); + theSwitch.insertNameAt(1, "y"); + theSwitch.condition = condition = module.i32.const(3); + assert(theSwitch.condition === condition); + theSwitch.value = value = module.i32.const(4); + assert(theSwitch.value === value); + theSwitch.finalize(); + + console.log(theSwitch.toText()); + assert( + theSwitch.toText() + == + "(br_table $x $y $c\n (i32.const 4)\n (i32.const 3)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# Call"); +(function testCall() { + const module = new binaryen.Module(); + + var target = "foo"; + var operands = [ + module.i32.const(1), + module.i32.const(2) + ]; + const theCall = binaryen.Call(module.call(target, operands, binaryen.i32)); + assert(theCall instanceof binaryen.Call); + assert(theCall instanceof binaryen.Expression); + assert(theCall.target === target); + assertDeepEqual(theCall.operands, operands); + assert(theCall.return === false); + assert(theCall.type === binaryen.i32); + + theCall.target = "bar"; + assert(theCall.target === "bar"); + theCall.operands = operands = [ + module.i32.const(3), // set + module.i32.const(4), // set + module.i32.const(5) // append + ]; + assertDeepEqual(theCall.operands, operands); + theCall.operands = operands = [ + module.i32.const(6) // set + // remove + // remove + ]; + assertDeepEqual(theCall.operands, operands); + theCall.insertOperandAt(0, module.i32.const(7)); + theCall.return = true; + assert(theCall.return === true); + theCall.finalize(); + assert(theCall.type === binaryen.unreachable); // finalized tail call + + theCall.return = false; + theCall.type = binaryen.i32; + theCall.finalize(); + assert(theCall.type === binaryen.i32); // finalized call + + console.log(theCall.toText()); + assert( + theCall.toText() + == + "(call $bar\n (i32.const 7)\n (i32.const 6)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# CallIndirect"); +(function testCallIndirect() { + const module = new binaryen.Module(); + + var target = module.i32.const(42); + var params = binaryen.none; + var results = binaryen.none; + var operands = [ + module.i32.const(1), + module.i32.const(2) + ]; + const theCallIndirect = binaryen.CallIndirect(module.call_indirect(target, operands, params, results)); + assert(theCallIndirect instanceof binaryen.CallIndirect); + assert(theCallIndirect instanceof binaryen.Expression); + assert(theCallIndirect.target === target); + assertDeepEqual(theCallIndirect.operands, operands); + assert(theCallIndirect.params === params); + assert(theCallIndirect.results === results); + assert(theCallIndirect.return === false); + assert(theCallIndirect.type === theCallIndirect.results); + + theCallIndirect.target = target = module.i32.const(9000); + assert(theCallIndirect.target === target); + theCallIndirect.operands = operands = [ + module.i32.const(3), // set + module.i32.const(4), // set + module.i32.const(5) // append + ]; + assertDeepEqual(theCallIndirect.operands, operands); + theCallIndirect.operands = operands = [ + module.i32.const(6) // set + // remove + // remove + ]; + assertDeepEqual(theCallIndirect.operands, operands); + theCallIndirect.insertOperandAt(0, module.i32.const(7)); + theCallIndirect.return = true; + assert(theCallIndirect.return === true); + theCallIndirect.params = params = binaryen.createType([ binaryen.i32, binaryen.i32 ]); + assert(theCallIndirect.params === params); + theCallIndirect.results = results = binaryen.i32; + assert(theCallIndirect.results === results); + theCallIndirect.finalize(); + assert(theCallIndirect.type === binaryen.unreachable); // finalized tail call + + theCallIndirect.return = false; + theCallIndirect.finalize(); + assert(theCallIndirect.type === results); // finalized call + + console.log(theCallIndirect.toText()); + assert( + theCallIndirect.toText() + == + "(call_indirect (type $i32_i32_=>_i32)\n (i32.const 7)\n (i32.const 6)\n (i32.const 9000)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# LocalGet"); +(function testLocalGet() { + const module = new binaryen.Module(); + + var index = 1; + var type = binaryen.i32; + const theLocalGet = binaryen.LocalGet(module.local.get(index, type)); + assert(theLocalGet instanceof binaryen.LocalGet); + assert(theLocalGet instanceof binaryen.Expression); + assert(theLocalGet.index === index); + assert(theLocalGet.type === type); + + theLocalGet.index = index = 2; + assert(theLocalGet.index === index); + theLocalGet.type = type = binaryen.f64; + assert(theLocalGet.type === type); + theLocalGet.finalize(); + + console.log(theLocalGet.toText()); + assert( + theLocalGet.toText() + == + "(local.get $2)\n" + ); + + module.dispose(); +})(); + +console.log("# LocalSet"); +(function testLocalSet() { + const module = new binaryen.Module(); + + var index = 1; + var value = module.i32.const(1); + const theLocalSet = binaryen.LocalSet(module.local.set(index, value)); + assert(theLocalSet instanceof binaryen.LocalSet); + assert(theLocalSet instanceof binaryen.Expression); + assert(theLocalSet.index === index); + assert(theLocalSet.value === value); + assert(theLocalSet.tee === false); + assert(theLocalSet.type == binaryen.none); + + theLocalSet.index = index = 2; + assert(theLocalSet.index === index); + theLocalSet.value = value = module.i32.const(3); + assert(theLocalSet.value === value); + theLocalSet.type = binaryen.i32; + assert(theLocalSet.type === binaryen.i32); + assert(theLocalSet.tee === true); + theLocalSet.type = binaryen.none; + theLocalSet.finalize(); + + console.log(theLocalSet.toText()); + assert( + theLocalSet.toText() + == + "(local.set $2\n (i32.const 3)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# GlobalGet"); +(function testGlobalGet() { + const module = new binaryen.Module(); + + var name = "a"; + var type = binaryen.i32; + const theGlobalGet = binaryen.GlobalGet(module.global.get(name, type)); + assert(theGlobalGet instanceof binaryen.GlobalGet); + assert(theGlobalGet instanceof binaryen.Expression); + assert(theGlobalGet.name === name); + assert(theGlobalGet.type === type); + + theGlobalGet.name = name = "b"; + assert(theGlobalGet.name === name); + theGlobalGet.type = type = binaryen.f64; + assert(theGlobalGet.type === type); + theGlobalGet.finalize(); + + console.log(theGlobalGet.toText()); + assert( + theGlobalGet.toText() + == + "(global.get $b)\n" + ); + + module.dispose(); +})(); + +console.log("# GlobalSet"); +(function testGlobalSet() { + const module = new binaryen.Module(); + + var name = "a"; + var value = module.i32.const(1); + const theGlobalSet = binaryen.GlobalSet(module.global.set(name, value)); + assert(theGlobalSet instanceof binaryen.GlobalSet); + assert(theGlobalSet instanceof binaryen.Expression); + assert(theGlobalSet.name === name); + assert(theGlobalSet.value === value); + assert(theGlobalSet.type == binaryen.none); + + theGlobalSet.name = name = "b"; + assert(theGlobalSet.name === name); + theGlobalSet.value = value = module.f64.const(3); + assert(theGlobalSet.value === value); + theGlobalSet.finalize(); + + console.log(theGlobalSet.toText()); + assert( + theGlobalSet.toText() + == + "(global.set $b\n (f64.const 3)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# Host"); +(function testHost() { + const module = new binaryen.Module(); + + var op = binaryen.Operations.MemorySize; + var nameOp = null; + var operands = []; + const theHost = binaryen.Host(module.memory.size()); + assert(theHost instanceof binaryen.Host); + assert(theHost instanceof binaryen.Expression); + assert(theHost.op === op); + assert(theHost.nameOperand === nameOp); + assertDeepEqual(theHost.operands, operands); + assert(theHost.type === binaryen.i32); + + theHost.op = op = binaryen.Operations.MemoryGrow; + assert(theHost.op === op); + theHost.nameOperand = nameOp = "a"; + assert(theHost.nameOperand === nameOp); + theHost.nameOperand = null; + theHost.operands = operands = [ + module.i32.const(1) + ]; + assertDeepEqual(theHost.operands, operands); + theHost.type = binaryen.f64; + theHost.finalize(); + assert(theHost.type === binaryen.i32); + + console.log(theHost.toText()); + assert( + theHost.toText() + == + "(memory.grow\n (i32.const 1)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# Load"); +(function testLoad() { + const module = new binaryen.Module(); + + var offset = 16; + var align = 2; + var ptr = module.i32.const(64); + const theLoad = binaryen.Load(module.i32.load(offset, align, ptr)); + assert(theLoad instanceof binaryen.Load); + assert(theLoad instanceof binaryen.Expression); + assert(theLoad.offset === offset); + assert(theLoad.align === align); + assert(theLoad.ptr === ptr); + assert(theLoad.bytes === 4); + assert(theLoad.signed === true); + assert(theLoad.atomic === false); + assert(theLoad.type == binaryen.i32); + + theLoad.offset = offset = 32; + assert(theLoad.offset === offset); + theLoad.align = align = 4; + assert(theLoad.align === align); + theLoad.ptr = ptr = module.i32.const(128); + assert(theLoad.ptr === ptr); + theLoad.type = binaryen.i64; + assert(theLoad.type === binaryen.i64); + theLoad.signed = false; + assert(theLoad.signed === false); + theLoad.bytes = 8; + assert(theLoad.bytes === 8); + theLoad.atomic = true; + assert(theLoad.atomic === true); + theLoad.finalize(); + assert(theLoad.align === 4); + + console.log(theLoad.toText()); + assert( + theLoad.toText() + == + "(i64.atomic.load offset=32 align=4\n (i32.const 128)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# Store"); +(function testStore() { + const module = new binaryen.Module(); + + var offset = 16; + var align = 2; + var ptr = module.i32.const(64); + var value = module.i32.const(1); + const theStore = binaryen.Store(module.i32.store(offset, align, ptr, value)); + assert(theStore instanceof binaryen.Store); + assert(theStore instanceof binaryen.Expression); + assert(theStore.offset === offset); + assert(theStore.align === align); + assert(theStore.ptr === ptr); + assert(theStore.value === value); + assert(theStore.bytes === 4); + assert(theStore.atomic === false); + assert(theStore.valueType === binaryen.i32); + assert(theStore.type === binaryen.none); + + theStore.offset = offset = 32; + assert(theStore.offset === offset); + theStore.align = align = 4; + assert(theStore.align === align); + theStore.ptr = ptr = module.i32.const(128); + assert(theStore.ptr === ptr); + theStore.value = value = module.i32.const(2); + assert(theStore.value === value); + theStore.signed = false; + assert(theStore.signed === false); + theStore.valueType = binaryen.i64; + assert(theStore.valueType === binaryen.i64); + theStore.bytes = 8; + assert(theStore.bytes === 8); + theStore.atomic = true; + assert(theStore.atomic === true); + theStore.finalize(); + assert(theStore.align === 4); + + console.log(theStore.toText()); + assert( + theStore.toText() + == + "(i64.atomic.store offset=32 align=4\n (i32.const 128)\n (i32.const 2)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# Const"); +(function testConst() { + const module = new binaryen.Module(); + + const theConst = binaryen.Const(module.i32.const(1)); + assert(theConst instanceof binaryen.Const); + assert(theConst instanceof binaryen.Expression); + assert(theConst.valueI32 === 1); + theConst.valueI32 = 2; + assert(theConst.valueI32 === 2); + assert(theConst.type === binaryen.i32); + + theConst.valueI64Low = 3; + assert(theConst.valueI64Low === 3); + theConst.valueI64High = 4; + assert(theConst.valueI64High === 4); + theConst.finalize(); + assert(theConst.type == binaryen.i64); + + theConst.valueF32 = 5; + assert(theConst.valueF32 === 5); + theConst.finalize(); + assert(theConst.type === binaryen.f32); + + theConst.valueF64 = 6; + assert(theConst.valueF64 === 6); + theConst.finalize(); + assert(theConst.type === binaryen.f64); + + theConst.valueV128 = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]; + assertDeepEqual(theConst.valueV128, [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]); + theConst.finalize(); + assert(theConst.type === binaryen.v128); + + console.log(theConst.toText()); + assert( + theConst.toText() + == + "(v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)\n" + ); + + module.dispose(); +})(); + +console.log("# Unary"); +(function testUnary() { + const module = new binaryen.Module(); + + var op = binaryen.Operations.EqZInt32; + var value = module.i32.const(1); + const theUnary = binaryen.Unary(module.i32.eqz(value)); + assert(theUnary instanceof binaryen.Unary); + assert(theUnary instanceof binaryen.Expression); + assert(theUnary.op === op); + assert(theUnary.value === value); + assert(theUnary.type === binaryen.i32); + + theUnary.op = op = binaryen.Operations.EqZInt64; + assert(theUnary.op === op); + theUnary.value = value = module.i64.const(2); + assert(theUnary.value === value); + theUnary.type = binaryen.f32; + theUnary.finalize(); + assert(theUnary.type === binaryen.i32); + + console.log(theUnary.toText()); + assert( + theUnary.toText() + == + "(i64.eqz\n (i64.const 2)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# Binary"); +(function testBinary() { + const module = new binaryen.Module(); + + var op = binaryen.Operations.AddInt32; + var left = module.i32.const(1); + var right = module.i32.const(2); + const theBinary = binaryen.Binary(module.i32.add(left, right)); + assert(theBinary instanceof binaryen.Binary); + assert(theBinary instanceof binaryen.Expression); + assert(theBinary.op === op); + assert(theBinary.left === left); + assert(theBinary.right === right); + assert(theBinary.type === binaryen.i32); + + theBinary.op = op = binaryen.Operations.AddInt64; + assert(theBinary.op === op); + theBinary.left = left = module.i64.const(3); + assert(theBinary.left === left); + theBinary.right = right = module.i64.const(4); + assert(theBinary.right === right); + theBinary.type = binaryen.f32; + theBinary.finalize(); + assert(theBinary.type === binaryen.i64); + + console.log(theBinary.toText()); + assert( + theBinary.toText() + == + "(i64.add\n (i64.const 3)\n (i64.const 4)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# Select"); +(function testSelect() { + const module = new binaryen.Module(); + + var condition = module.i32.const(1); + var ifTrue = module.i32.const(2); + var ifFalse = module.i32.const(3); + const theSelect = binaryen.Select(module.select(condition, ifTrue, ifFalse)); assert(theSelect.ifTrue === ifTrue); + assert(theSelect instanceof binaryen.Select); + assert(theSelect instanceof binaryen.Expression); + assert(theSelect.condition === condition); + assert(theSelect.ifTrue === ifTrue); + assert(theSelect.ifFalse === ifFalse); + assert(theSelect.type === binaryen.i32); + + theSelect.condition = condition = module.i32.const(4); + assert(theSelect.condition === condition); + theSelect.ifTrue = ifTrue = module.i64.const(5); + assert(theSelect.ifTrue === ifTrue); + theSelect.ifFalse = ifFalse = module.i64.const(6); + assert(theSelect.ifFalse === ifFalse); + theSelect.finalize(); + assert(theSelect.type === binaryen.i64); + + console.log(theSelect.toText()); + assert( + theSelect.toText() + == + "(select\n (i64.const 5)\n (i64.const 6)\n (i32.const 4)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# Drop"); +(function testDrop() { + const module = new binaryen.Module(); + + var value = module.i32.const(1); + const theDrop = binaryen.Drop(module.drop(value)); + assert(theDrop instanceof binaryen.Drop); + assert(theDrop instanceof binaryen.Expression); + assert(theDrop.value === value); + assert(theDrop.type === binaryen.none); + + theDrop.value = value = module.i32.const(2); + assert(theDrop.value === value); + + theDrop.finalize(); + assert(theDrop.type === binaryen.none); + + console.log(theDrop.toText()); + assert( + theDrop.toText() + == + "(drop\n (i32.const 2)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# Return"); +(function testReturn() { + const module = new binaryen.Module(); + + var value = module.i32.const(1); + const theReturn = binaryen.Return(module.return(value)); + assert(theReturn instanceof binaryen.Return); + assert(theReturn instanceof binaryen.Expression); + assert(theReturn.value === value); + assert(theReturn.type === binaryen.unreachable); + + theReturn.value = value = module.i32.const(2); + assert(theReturn.value === value); + + theReturn.finalize(); + assert(theReturn.type === binaryen.unreachable); + + console.log(theReturn.toText()); + assert( + theReturn.toText() + == + "(return\n (i32.const 2)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# AtomicRMW"); +(function testAtomicRMW() { + const module = new binaryen.Module(); + + var op = binaryen.Operations.AtomicRMWAdd; + var offset = 8; + var ptr = module.i32.const(2); + var value = module.i32.const(3); + const theAtomicRMW = binaryen.AtomicRMW(module.i32.atomic.rmw.add(offset, ptr, value)); + assert(theAtomicRMW instanceof binaryen.AtomicRMW); + assert(theAtomicRMW instanceof binaryen.Expression); + assert(theAtomicRMW.op === op); + assert(theAtomicRMW.bytes === 4); + assert(theAtomicRMW.offset === offset); + assert(theAtomicRMW.ptr === ptr); + assert(theAtomicRMW.value === value); + assert(theAtomicRMW.type === binaryen.i32); + + theAtomicRMW.op = op = binaryen.Operations.AtomicRMWSub; + assert(theAtomicRMW.op === op); + theAtomicRMW.bytes = 2; + assert(theAtomicRMW.bytes === 2); + theAtomicRMW.offset = offset = 16; + assert(theAtomicRMW.offset === offset); + theAtomicRMW.ptr = ptr = module.i32.const(4); + assert(theAtomicRMW.ptr === ptr); + theAtomicRMW.value = value = module.i64.const(5); + assert(theAtomicRMW.value === value); + theAtomicRMW.type = binaryen.i64; + theAtomicRMW.finalize(); + assert(theAtomicRMW.type === binaryen.i64); + + console.log(theAtomicRMW.toText()); + assert( + theAtomicRMW.toText() + == + "(i64.atomic.rmw16.sub_u offset=16\n (i32.const 4)\n (i64.const 5)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# AtomicCmpxchg"); +(function testAtomicCmpxchg() { + const module = new binaryen.Module(); + + var offset = 8; + var ptr = module.i32.const(2); + var expected = module.i32.const(3); + var replacement = module.i32.const(4); + const theAtomicCmpxchg = binaryen.AtomicCmpxchg(module.i32.atomic.rmw.cmpxchg(offset, ptr, expected, replacement)); + assert(theAtomicCmpxchg instanceof binaryen.AtomicCmpxchg); + assert(theAtomicCmpxchg instanceof binaryen.Expression); + assert(theAtomicCmpxchg.bytes === 4); + assert(theAtomicCmpxchg.offset === offset); + assert(theAtomicCmpxchg.ptr === ptr); + assert(theAtomicCmpxchg.expected === expected); + assert(theAtomicCmpxchg.replacement === replacement); + assert(theAtomicCmpxchg.type === binaryen.i32); + + theAtomicCmpxchg.bytes = 2; + assert(theAtomicCmpxchg.bytes === 2); + theAtomicCmpxchg.offset = offset = 16; + assert(theAtomicCmpxchg.offset === offset); + theAtomicCmpxchg.ptr = ptr = module.i32.const(5); + assert(theAtomicCmpxchg.ptr === ptr); + theAtomicCmpxchg.expected = expected = module.i64.const(6); + assert(theAtomicCmpxchg.expected === expected); + theAtomicCmpxchg.replacement = replacement = module.i64.const(7); + assert(theAtomicCmpxchg.replacement === replacement); + theAtomicCmpxchg.type = binaryen.i64; + theAtomicCmpxchg.finalize(); + assert(theAtomicCmpxchg.type === binaryen.i64); + + console.log(theAtomicCmpxchg.toText()); + assert( + theAtomicCmpxchg.toText() + == + "(i64.atomic.rmw16.cmpxchg_u offset=16\n (i32.const 5)\n (i64.const 6)\n (i64.const 7)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# AtomicWait"); +(function testAtomicWait() { + const module = new binaryen.Module(); + + var ptr = module.i32.const(2); + var expected = module.i32.const(3); + var timeout = module.i64.const(4); + const theAtomicWait = binaryen.AtomicWait(module.i32.atomic.wait(ptr, expected, timeout)); + assert(theAtomicWait instanceof binaryen.AtomicWait); + assert(theAtomicWait instanceof binaryen.Expression); + assert(theAtomicWait.ptr === ptr); + assert(theAtomicWait.expected === expected); + assert(theAtomicWait.expectedType === binaryen.i32); + assert(theAtomicWait.timeout === timeout); + assert(theAtomicWait.type === binaryen.i32); + + theAtomicWait.ptr = ptr = module.i32.const(5); + assert(theAtomicWait.ptr === ptr); + theAtomicWait.expected = expected = module.i32.const(6); + assert(theAtomicWait.expected === expected); + theAtomicWait.expectedType = binaryen.i64; + assert(theAtomicWait.expectedType === binaryen.i64); + theAtomicWait.timeout = timeout = module.i64.const(7); + assert(theAtomicWait.timeout === timeout); + theAtomicWait.type = binaryen.f64; + theAtomicWait.finalize(); + assert(theAtomicWait.type === binaryen.i32); + + console.log(theAtomicWait.toText()); + assert( + theAtomicWait.toText() + == + "(i64.atomic.wait\n (i32.const 5)\n (i32.const 6)\n (i64.const 7)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# AtomicNotify"); +(function testAtomicNotify() { + const module = new binaryen.Module(); + + var ptr = module.i32.const(1); + var notifyCount = module.i32.const(2); + const theAtomicNotify = binaryen.AtomicNotify(module.atomic.notify(ptr, notifyCount)); + assert(theAtomicNotify instanceof binaryen.AtomicNotify); + assert(theAtomicNotify instanceof binaryen.Expression); + assert(theAtomicNotify.ptr === ptr); + assert(theAtomicNotify.notifyCount === notifyCount); + assert(theAtomicNotify.type === binaryen.i32); + + theAtomicNotify.ptr = ptr = module.i32.const(3); + assert(theAtomicNotify.ptr === ptr); + theAtomicNotify.notifyCount = notifyCount = module.i32.const(4); + assert(theAtomicNotify.notifyCount === notifyCount); + theAtomicNotify.type = binaryen.f64; + theAtomicNotify.finalize(); + assert(theAtomicNotify.type === binaryen.i32); + + console.log(theAtomicNotify.toText()); + assert( + theAtomicNotify.toText() + == + "(atomic.notify\n (i32.const 3)\n (i32.const 4)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# AtomicFence"); +(function testAtomicFence() { + const module = new binaryen.Module(); + + const theAtomicFence = binaryen.AtomicFence(module.atomic.fence()); + assert(theAtomicFence instanceof binaryen.AtomicFence); + assert(theAtomicFence instanceof binaryen.Expression); + assert(theAtomicFence.order === 0); // reserved, not yet used + assert(theAtomicFence.type === binaryen.none); + + theAtomicFence.order = 1; + assert(theAtomicFence.order === 1); + theAtomicFence.type = binaryen.f64; + theAtomicFence.finalize(); + assert(theAtomicFence.type === binaryen.none); + + console.log(theAtomicFence.toText()); + assert( + theAtomicFence.toText() + == + "(atomic.fence)\n" + ); + + module.dispose(); +})(); + +console.log("# SIMDExtract"); +(function testSIMDExtract() { + const module = new binaryen.Module(); + + var op = binaryen.Operations.ExtractLaneSVecI8x16; + var vec = module.v128.const([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]); + var index = 0; + const theSIMDExtract = binaryen.SIMDExtract(module.i8x16.extract_lane_s(vec, index)); + assert(theSIMDExtract instanceof binaryen.SIMDExtract); + assert(theSIMDExtract instanceof binaryen.Expression); + assert(theSIMDExtract.op === op); + assert(theSIMDExtract.vec === vec); + assert(theSIMDExtract.index === index); + assert(theSIMDExtract.type === binaryen.i32); + + theSIMDExtract.op = op = binaryen.Operations.ExtractLaneSVecI16x8; + assert(theSIMDExtract.op === op); + theSIMDExtract.vec = vec = module.v128.const([1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]); + assert(theSIMDExtract.vec === vec); + theSIMDExtract.index = index = 1; + assert(theSIMDExtract.index === index); + theSIMDExtract.type = binaryen.f64; + theSIMDExtract.finalize(); + assert(theSIMDExtract.type === binaryen.i32); + + console.log(theSIMDExtract.toText()); + assert( + theSIMDExtract.toText() + == + "(i16x8.extract_lane_s 1\n (v128.const i32x4 0x01010101 0x01010101 0x01010101 0x01010101)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# SIMDReplace"); +(function testSIMDReplace() { + const module = new binaryen.Module(); + + var op = binaryen.Operations.ReplaceLaneVecI8x16; + var vec = module.v128.const([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]); + var index = 0; + var value = module.i32.const(1); + const theSIMDReplace = binaryen.SIMDReplace(module.i8x16.replace_lane(vec, index, value)); + assert(theSIMDReplace instanceof binaryen.SIMDReplace); + assert(theSIMDReplace instanceof binaryen.Expression); + assert(theSIMDReplace.op === op); + assert(theSIMDReplace.vec === vec); + assert(theSIMDReplace.index === index); + assert(theSIMDReplace.value === value); + assert(theSIMDReplace.type === binaryen.v128); + + theSIMDReplace.op = op = binaryen.Operations.ReplaceLaneVecI16x8; + assert(theSIMDReplace.op === op); + theSIMDReplace.vec = vec = module.v128.const([1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]); + assert(theSIMDReplace.vec === vec); + theSIMDReplace.index = index = 1; + assert(theSIMDReplace.index === index); + theSIMDReplace.value = value = module.i32.const(2); + assert(theSIMDReplace.value === value); + theSIMDReplace.type = binaryen.f64; + theSIMDReplace.finalize(); + assert(theSIMDReplace.type === binaryen.v128); + + console.log(theSIMDReplace.toText()); + assert( + theSIMDReplace.toText() + == + "(i16x8.replace_lane 1\n (v128.const i32x4 0x01010101 0x01010101 0x01010101 0x01010101)\n (i32.const 2)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# SIMDShuffle"); +(function testSIMDShuffle() { + const module = new binaryen.Module(); + + var left = module.v128.const([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]); + var right = module.v128.const([2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]); + var mask = [3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]; + const theSIMDShuffle = binaryen.SIMDShuffle(module.v8x16.shuffle(left, right, mask)); + assert(theSIMDShuffle instanceof binaryen.SIMDShuffle); + assert(theSIMDShuffle instanceof binaryen.Expression); + assert(theSIMDShuffle.left === left); + assert(theSIMDShuffle.right === right); + assertDeepEqual(theSIMDShuffle.mask, mask); + assert(theSIMDShuffle.type === binaryen.v128); + + theSIMDShuffle.left = left = module.v128.const([1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]); + assert(theSIMDShuffle.left === left); + theSIMDShuffle.right = right = module.v128.const([2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2]); + assert(theSIMDShuffle.right === right); + theSIMDShuffle.mask = mask = [3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3]; + assertDeepEqual(theSIMDShuffle.mask, mask); + theSIMDShuffle.type = binaryen.f64; + theSIMDShuffle.finalize(); + assert(theSIMDShuffle.type === binaryen.v128); + + console.log(theSIMDShuffle.toText()); + assert( + theSIMDShuffle.toText() + == + "(v8x16.shuffle 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n (v128.const i32x4 0x01010101 0x01010101 0x01010101 0x01010101)\n (v128.const i32x4 0x02020202 0x02020202 0x02020202 0x02020202)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# SIMDTernary"); +(function testSIMDTernary() { + const module = new binaryen.Module(); + + var op = binaryen.Operations.BitselectVec128; + var a = module.v128.const([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]); + var b = module.v128.const([2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]); + var c = module.v128.const([3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]); + const theSIMDTernary = binaryen.SIMDTernary(module.v128.bitselect(a, b, c)); + assert(theSIMDTernary instanceof binaryen.SIMDTernary); + assert(theSIMDTernary instanceof binaryen.Expression); + assert(theSIMDTernary.op === op); + assert(theSIMDTernary.a === a); + assert(theSIMDTernary.b === b); + assert(theSIMDTernary.c === c); + assert(theSIMDTernary.type === binaryen.v128); + + theSIMDTernary.op = op = binaryen.Operations.QFMAVecF64x2; + assert(theSIMDTernary.op === op); + theSIMDTernary.a = a = module.v128.const([1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]); + assert(theSIMDTernary.a === a); + theSIMDTernary.b = b = module.v128.const([2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2]); + assert(theSIMDTernary.b === b); + theSIMDTernary.c = c = module.v128.const([3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3]); + assert(theSIMDTernary.c === c); + theSIMDTernary.type = binaryen.f64; + theSIMDTernary.finalize(); + assert(theSIMDTernary.type === binaryen.v128); + + console.log(theSIMDTernary.toText()); + assert( + theSIMDTernary.toText() + == + "(f64x2.qfma\n (v128.const i32x4 0x01010101 0x01010101 0x01010101 0x01010101)\n (v128.const i32x4 0x02020202 0x02020202 0x02020202 0x02020202)\n (v128.const i32x4 0x03030303 0x03030303 0x03030303 0x03030303)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# SIMDShift"); +(function testSIMDShift() { + const module = new binaryen.Module(); + + var op = binaryen.Operations.BitselectVec128; + var vec = module.v128.const([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]); + var shift = module.i32.const(1); + const theSIMDShift = binaryen.SIMDShift(module.i8x16.shl(vec, shift)); + assert(theSIMDShift instanceof binaryen.SIMDShift); + assert(theSIMDShift instanceof binaryen.Expression); + assert(theSIMDShift.op === op); + assert(theSIMDShift.vec === vec); + assert(theSIMDShift.shift === shift); + assert(theSIMDShift.type === binaryen.v128); + + theSIMDShift.op = op = binaryen.Operations.ShrSVecI8x16; + assert(theSIMDShift.op === op); + theSIMDShift.vec = vec = module.v128.const([1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]); + assert(theSIMDShift.vec === vec); + theSIMDShift.shift = shift = module.i32.const(2); + assert(theSIMDShift.shift === shift); + theSIMDShift.type = binaryen.f64; + theSIMDShift.finalize(); + assert(theSIMDShift.type === binaryen.v128); + + console.log(theSIMDShift.toText()); + assert( + theSIMDShift.toText() + == + "(i8x16.shr_s\n (v128.const i32x4 0x01010101 0x01010101 0x01010101 0x01010101)\n (i32.const 2)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# SIMDLoad"); +(function testSIMDLoad() { + const module = new binaryen.Module(); + + var op = binaryen.Operations.LoadExtSVec8x8ToVecI16x8; + var offset = 16; + var align = 2; + var ptr = module.i32.const(1); + const theSIMDLoad = binaryen.SIMDLoad(module.i16x8.load8x8_s(offset, align, ptr)); + assert(theSIMDLoad instanceof binaryen.SIMDLoad); + assert(theSIMDLoad instanceof binaryen.Expression); + assert(theSIMDLoad.offset === offset); + assert(theSIMDLoad.align === align); + assert(theSIMDLoad.ptr === ptr); + assert(theSIMDLoad.type === binaryen.v128); + + theSIMDLoad.op = op = binaryen.Operations.LoadSplatVec8x16; + assert(theSIMDLoad.op === op); + theSIMDLoad.offset = offset = 32; + assert(theSIMDLoad.offset === offset); + theSIMDLoad.align = align = 4; + assert(theSIMDLoad.align === align); + theSIMDLoad.ptr = ptr = module.i32.const(2); + assert(theSIMDLoad.ptr === ptr); + theSIMDLoad.type = binaryen.f64; + theSIMDLoad.finalize(); + assert(theSIMDLoad.type === binaryen.v128); + + console.log(theSIMDLoad.toText()); + assert( + theSIMDLoad.toText() + == + "(v8x16.load_splat offset=32 align=4\n (i32.const 2)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# MemoryInit"); +(function testMemoryInit() { + const module = new binaryen.Module(); + + var segment = 1; + var dest = module.i32.const(2); + var offset = module.i32.const(3); + var size = module.i32.const(4); + const theMemoryInit = binaryen.MemoryInit(module.memory.init(segment, dest, offset, size)); + assert(theMemoryInit instanceof binaryen.MemoryInit); + assert(theMemoryInit instanceof binaryen.Expression); + assert(theMemoryInit.segment === segment); + assert(theMemoryInit.dest === dest); + assert(theMemoryInit.offset === offset); + assert(theMemoryInit.size === size); + assert(theMemoryInit.type === binaryen.none); + + theMemoryInit.segment = segment = 5; + assert(theMemoryInit.segment === 5); + theMemoryInit.dest = dest = module.i32.const(6); + assert(theMemoryInit.dest === dest); + theMemoryInit.offset = offset = module.i32.const(7); + assert(theMemoryInit.offset === offset); + theMemoryInit.size = size = module.i32.const(8); + assert(theMemoryInit.size === size); + theMemoryInit.type = binaryen.f64; + theMemoryInit.finalize(); + assert(theMemoryInit.type === binaryen.none); + + console.log(theMemoryInit.toText()); + assert( + theMemoryInit.toText() + == + "(memory.init 5\n (i32.const 6)\n (i32.const 7)\n (i32.const 8)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# DataDrop"); +(function testDataDrop() { + const module = new binaryen.Module(); + + var segment = 1; + const theDataDrop = binaryen.DataDrop(module.data.drop(segment)); + assert(theDataDrop instanceof binaryen.DataDrop); + assert(theDataDrop instanceof binaryen.Expression); + assert(theDataDrop.segment === segment); + assert(theDataDrop.type === binaryen.none); + + theDataDrop.segment = segment = 2; + assert(theDataDrop.segment === 2); + theDataDrop.type = binaryen.f64; + theDataDrop.finalize(); + assert(theDataDrop.type === binaryen.none); + + console.log(theDataDrop.toText()); + assert( + theDataDrop.toText() + == + "(data.drop 2)\n" + ); + + module.dispose(); +})(); + +console.log("# MemoryCopy"); +(function testMemoryCopy() { + const module = new binaryen.Module(); + + var dest = module.i32.const(1); + var source = module.i32.const(2); + var size = module.i32.const(3); + const theMemoryCopy = binaryen.MemoryCopy(module.memory.copy(dest, source, size)); + assert(theMemoryCopy instanceof binaryen.MemoryCopy); + assert(theMemoryCopy instanceof binaryen.Expression); + assert(theMemoryCopy.dest === dest); + assert(theMemoryCopy.source === source); + assert(theMemoryCopy.size === size); + assert(theMemoryCopy.type === binaryen.none); + + theMemoryCopy.dest = dest = module.i32.const(4); + assert(theMemoryCopy.dest === dest); + theMemoryCopy.source = source = module.i32.const(5); + assert(theMemoryCopy.source === source); + theMemoryCopy.size = size = module.i32.const(6); + assert(theMemoryCopy.size === size); + theMemoryCopy.type = binaryen.f64; + theMemoryCopy.finalize(); + assert(theMemoryCopy.type === binaryen.none); + + console.log(theMemoryCopy.toText()); + assert( + theMemoryCopy.toText() + == + "(memory.copy\n (i32.const 4)\n (i32.const 5)\n (i32.const 6)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# MemoryFill"); +(function testMemoryFill() { + const module = new binaryen.Module(); + + var dest = module.i32.const(1); + var value = module.i32.const(2); + var size = module.i32.const(3); + const theMemoryFill = binaryen.MemoryFill(module.memory.fill(dest, value, size)); + assert(theMemoryFill instanceof binaryen.MemoryFill); + assert(theMemoryFill instanceof binaryen.Expression); + assert(theMemoryFill.dest === dest); + assert(theMemoryFill.value === value); + assert(theMemoryFill.size === size); + assert(theMemoryFill.type === binaryen.none); + + theMemoryFill.dest = dest = module.i32.const(4); + assert(theMemoryFill.dest === dest); + theMemoryFill.value = value = module.i32.const(5); + assert(theMemoryFill.value === value); + theMemoryFill.size = size = module.i32.const(6); + assert(theMemoryFill.size === size); + theMemoryFill.type = binaryen.f64; + theMemoryFill.finalize(); + assert(theMemoryFill.type === binaryen.none); + + console.log(theMemoryFill.toText()); + assert( + theMemoryFill.toText() + == + "(memory.fill\n (i32.const 4)\n (i32.const 5)\n (i32.const 6)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# RefIsNull"); +(function testRefIsNull() { + const module = new binaryen.Module(); + + var value = module.local.get(1, binaryen.externref); + const theRefIsNull = binaryen.RefIsNull(module.ref.is_null(value)); + assert(theRefIsNull instanceof binaryen.RefIsNull); + assert(theRefIsNull instanceof binaryen.Expression); + assert(theRefIsNull.value === value); + assert(theRefIsNull.type === binaryen.i32); + + theRefIsNull.value = value = module.local.get(2, binaryen.externref); + assert(theRefIsNull.value === value); + theRefIsNull.type = binaryen.f64; + theRefIsNull.finalize(); + assert(theRefIsNull.type === binaryen.i32); + + console.log(theRefIsNull.toText()); + assert( + theRefIsNull.toText() + == + "(ref.is_null\n (local.get $2)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# RefFunc"); +(function testRefFunc() { + const module = new binaryen.Module(); + + var func = "a"; + const theRefFunc = binaryen.RefFunc(module.ref.func(func)); + assert(theRefFunc instanceof binaryen.RefFunc); + assert(theRefFunc instanceof binaryen.Expression); + assert(theRefFunc.func === func); + assert(theRefFunc.type === binaryen.funcref); + + theRefFunc.func = func = "b"; + assert(theRefFunc.func === func); + theRefFunc.type = binaryen.f64; + theRefFunc.finalize(); + assert(theRefFunc.type === binaryen.funcref); + + console.log(theRefFunc.toText()); + assert( + theRefFunc.toText() + == + "(ref.func $b)\n" + ); + + module.dispose(); +})(); + +console.log("# Try"); +(function testTry() { + const module = new binaryen.Module(); + + var body = module.i32.const(1); + var catchBody = module.i32.const(2); + const theTry = binaryen.Try(module.try(body, catchBody)); + assert(theTry instanceof binaryen.Try); + assert(theTry instanceof binaryen.Expression); + assert(theTry.body === body); + assert(theTry.catchBody === catchBody); + assert(theTry.type === binaryen.i32); + + theTry.body = body = module.i32.const(3); + assert(theTry.body === body); + theTry.catchBody = catchBody = module.i32.const(4); + assert(theTry.catchBody === catchBody); + theTry.type = binaryen.f64; + theTry.finalize(); + assert(theTry.type === binaryen.i32); + + console.log(theTry.toText()); + assert( + theTry.toText() + == + "(try (result i32)\n (do\n (i32.const 3)\n )\n (catch\n (i32.const 4)\n )\n)\n" + ); + + module.dispose(); +})(); + +console.log("# Throw"); +(function testThrow() { + const module = new binaryen.Module(); + + var event = "foo"; + var operands = [ + module.i32.const(1), + module.i32.const(2) + ]; + const theThrow = binaryen.Throw(module.throw(event, operands)); + assert(theThrow instanceof binaryen.Throw); + assert(theThrow instanceof binaryen.Expression); + assert(theThrow.event === event); + assertDeepEqual(theThrow.operands, operands); + assert(theThrow.type === binaryen.unreachable); + + theThrow.event = "bar"; + assert(theThrow.event === "bar"); + theThrow.operands = operands = [ + module.i32.const(3), // set + module.i32.const(4), // set + module.i32.const(5) // append + ]; + assertDeepEqual(theThrow.operands, operands); + theThrow.operands = operands = [ + module.i32.const(6) // set + // remove + // remove + ]; + assertDeepEqual(theThrow.operands, operands); + theThrow.insertOperandAt(1, module.i32.const(7)); + theThrow.type = binaryen.f64; + theThrow.finalize(); + assert(theThrow.type === binaryen.unreachable); + + console.log(theThrow.toText()); + assert( + theThrow.toText() + == + "(throw $bar\n (i32.const 6)\n (i32.const 7)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# Rethrow"); +(function testRethrow() { + const module = new binaryen.Module(); + + var exnref = module.local.get(1, binaryen.exnref); + const theRethrow = binaryen.Rethrow(module.rethrow(exnref)); + assert(theRethrow instanceof binaryen.Rethrow); + assert(theRethrow instanceof binaryen.Expression); + assert(theRethrow.exnref === exnref); + assert(theRethrow.type === binaryen.unreachable); + + theRethrow.exnref = exnref = module.local.get(2, binaryen.exnref); + assert(theRethrow.exnref === exnref); + theRethrow.type = binaryen.f64; + theRethrow.finalize(); + assert(theRethrow.type === binaryen.unreachable); + + console.log(theRethrow.toText()); + assert( + theRethrow.toText() + == + "(rethrow\n (local.get $2)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# BrOnExn"); +(function testBrOnExn() { + const module = new binaryen.Module(); + module.addEvent("event1", 0, binaryen.none, binaryen.none); + module.addEvent("event2", 0, binaryen.none, binaryen.none); + + var name = "foo"; + var event = "event1"; + var exnref = module.local.get(1, binaryen.exnref); + const theBrOnExn = binaryen.BrOnExn(module.br_on_exn(name, event, exnref)); + assert(theBrOnExn instanceof binaryen.BrOnExn); + assert(theBrOnExn instanceof binaryen.Expression); + assert(theBrOnExn.name === name); + assert(theBrOnExn.event === event); + assert(theBrOnExn.exnref === exnref); + assert(theBrOnExn.type === binaryen.exnref); + + theBrOnExn.name = name = "bar"; + assert(theBrOnExn.name === name); + theBrOnExn.event = event = "event2"; + assert(theBrOnExn.event === event); + theBrOnExn.exnref = exnref = module.local.get(2, binaryen.exnref); + assert(theBrOnExn.exnref === exnref); + theBrOnExn.type = binaryen.f64; + theBrOnExn.finalize(); + assert(theBrOnExn.type === binaryen.exnref); + + console.log(theBrOnExn.toText()); + assert( + theBrOnExn.toText() + == + "(br_on_exn $bar $event2\n (local.get $2)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# TupleMake"); +(function testTupleMake() { + const module = new binaryen.Module(); + + var operands = [ + module.i32.const(1), + module.i32.const(2) + ]; + var type = binaryen.createType([ binaryen.i32, binaryen.i32 ]); + const theTupleMake = binaryen.TupleMake(module.tuple.make(operands)); + assert(theTupleMake instanceof binaryen.TupleMake); + assert(theTupleMake instanceof binaryen.Expression); + assertDeepEqual(theTupleMake.operands, operands); + assert(theTupleMake.type === type); + + theTupleMake.operands = operands = [ + module.i32.const(3), // set + module.i32.const(4), // set + module.i32.const(5) // append + ]; + assertDeepEqual(theTupleMake.operands, operands); + theTupleMake.operands = operands = [ + module.i32.const(6) // set + // remove + // remove + ]; + assertDeepEqual(theTupleMake.operands, operands); + theTupleMake.insertOperandAt(1, module.i32.const(7)); + theTupleMake.type = binaryen.f64; + theTupleMake.finalize(); + assert(theTupleMake.type === type); + + console.log(theTupleMake.toText()); + assert( + theTupleMake.toText() + == + "(tuple.make\n (i32.const 6)\n (i32.const 7)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# TupleExtract"); +(function testTupleExtract() { + const module = new binaryen.Module(); + + var tuple = module.tuple.make([ + module.i32.const(1), + module.i32.const(2) + ]); + var index = 1; + const theTupleExtract = binaryen.TupleExtract(module.tuple.extract(tuple, index)); + assert(theTupleExtract instanceof binaryen.TupleExtract); + assert(theTupleExtract instanceof binaryen.Expression); + assert(theTupleExtract.tuple === tuple); + assert(theTupleExtract.index === index); + assert(theTupleExtract.type === binaryen.i32); + + theTupleExtract.tuple = tuple = module.tuple.make([ + module.f64.const(3), + module.f64.const(4) + ]); + assert(theTupleExtract.tuple === tuple); + theTupleExtract.index = index = 0; + assert(theTupleExtract.index === index); + theTupleExtract.type = binaryen.i32; + theTupleExtract.finalize(); + assert(theTupleExtract.type === binaryen.f64); + + console.log(theTupleExtract.toText()); + assert( + theTupleExtract.toText() + == + "(tuple.extract 0\n (tuple.make\n (f64.const 3)\n (f64.const 4)\n )\n)\n" + ); + + module.dispose(); +})(); diff --git a/test/binaryen.js/expressions.js.txt b/test/binaryen.js/expressions.js.txt new file mode 100644 index 00000000000..239498b1f92 --- /dev/null +++ b/test/binaryen.js/expressions.js.txt @@ -0,0 +1,249 @@ +# Expression +# Block +(block $theName (result i32) + (i32.const 0) +) + +# If +(if (result i32) + (i32.const 4) + (i32.const 5) + (i32.const 6) +) + +(if (result i32) + (i32.const 4) + (i32.const 5) +) + +# Loop +(loop $theName + (drop + (i32.const 1) + ) +) + +# Break +(br_if $theNewName + (i32.const 4) + (i32.const 3) +) + +# Switch +(br_table $x $y $c + (i32.const 4) + (i32.const 3) +) + +# Call +(call $bar + (i32.const 7) + (i32.const 6) +) + +# CallIndirect +(call_indirect (type $i32_i32_=>_i32) + (i32.const 7) + (i32.const 6) + (i32.const 9000) +) + +# LocalGet +(local.get $2) + +# LocalSet +(local.set $2 + (i32.const 3) +) + +# GlobalGet +(global.get $b) + +# GlobalSet +(global.set $b + (f64.const 3) +) + +# Host +(memory.grow + (i32.const 1) +) + +# Load +(i64.atomic.load offset=32 align=4 + (i32.const 128) +) + +# Store +(i64.atomic.store offset=32 align=4 + (i32.const 128) + (i32.const 2) +) + +# Const +(v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) + +# Unary +(i64.eqz + (i64.const 2) +) + +# Binary +(i64.add + (i64.const 3) + (i64.const 4) +) + +# Select +(select + (i64.const 5) + (i64.const 6) + (i32.const 4) +) + +# Drop +(drop + (i32.const 2) +) + +# Return +(return + (i32.const 2) +) + +# AtomicRMW +(i64.atomic.rmw16.sub_u offset=16 + (i32.const 4) + (i64.const 5) +) + +# AtomicCmpxchg +(i64.atomic.rmw16.cmpxchg_u offset=16 + (i32.const 5) + (i64.const 6) + (i64.const 7) +) + +# AtomicWait +(i64.atomic.wait + (i32.const 5) + (i32.const 6) + (i64.const 7) +) + +# AtomicNotify +(atomic.notify + (i32.const 3) + (i32.const 4) +) + +# AtomicFence +(atomic.fence) + +# SIMDExtract +(i16x8.extract_lane_s 1 + (v128.const i32x4 0x01010101 0x01010101 0x01010101 0x01010101) +) + +# SIMDReplace +(i16x8.replace_lane 1 + (v128.const i32x4 0x01010101 0x01010101 0x01010101 0x01010101) + (i32.const 2) +) + +# SIMDShuffle +(v8x16.shuffle 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + (v128.const i32x4 0x01010101 0x01010101 0x01010101 0x01010101) + (v128.const i32x4 0x02020202 0x02020202 0x02020202 0x02020202) +) + +# SIMDTernary +(f64x2.qfma + (v128.const i32x4 0x01010101 0x01010101 0x01010101 0x01010101) + (v128.const i32x4 0x02020202 0x02020202 0x02020202 0x02020202) + (v128.const i32x4 0x03030303 0x03030303 0x03030303 0x03030303) +) + +# SIMDShift +(i8x16.shr_s + (v128.const i32x4 0x01010101 0x01010101 0x01010101 0x01010101) + (i32.const 2) +) + +# SIMDLoad +(v8x16.load_splat offset=32 align=4 + (i32.const 2) +) + +# MemoryInit +(memory.init 5 + (i32.const 6) + (i32.const 7) + (i32.const 8) +) + +# DataDrop +(data.drop 2) + +# MemoryCopy +(memory.copy + (i32.const 4) + (i32.const 5) + (i32.const 6) +) + +# MemoryFill +(memory.fill + (i32.const 4) + (i32.const 5) + (i32.const 6) +) + +# RefIsNull +(ref.is_null + (local.get $2) +) + +# RefFunc +(ref.func $b) + +# Try +(try (result i32) + (do + (i32.const 3) + ) + (catch + (i32.const 4) + ) +) + +# Throw +(throw $bar + (i32.const 6) + (i32.const 7) +) + +# Rethrow +(rethrow + (local.get $2) +) + +# BrOnExn +(br_on_exn $bar $event2 + (local.get $2) +) + +# TupleMake +(tuple.make + (i32.const 6) + (i32.const 7) +) + +# TupleExtract +(tuple.extract 0 + (tuple.make + (f64.const 3) + (f64.const 4) + ) +) +