summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeejin Ahn <aheejin@gmail.com>2019-08-27 16:40:59 -0700
committerGitHub <noreply@github.com>2019-08-27 16:40:59 -0700
commitcb0b31a2d185f18662814c9f3c9158b2eea74760 (patch)
tree4fe23ff2abb08af7a804f6e6755b07454f79f45d
parentf070e8c10a15a02735fbd9b88c4c569a8c786933 (diff)
downloadbinaryen-cb0b31a2d185f18662814c9f3c9158b2eea74760.tar.gz
binaryen-cb0b31a2d185f18662814c9f3c9158b2eea74760.tar.bz2
binaryen-cb0b31a2d185f18662814c9f3c9158b2eea74760.zip
Add atomic.fence instruction (#2307)
This adds `atomic.fence` instruction: https://github.com/WebAssembly/threads/blob/master/proposals/threads/Overview.md#fence-operator This also fix bugs in `atomic.wait` and `atomic.notify` instructions in binaryen.js and adds tests for them.
-rw-r--r--CHANGELOG.md5
-rwxr-xr-xbuild-js.sh5
-rwxr-xr-xscripts/gen-s-parser.py1
-rw-r--r--src/binaryen-c.cpp23
-rw-r--r--src/binaryen-c.h4
-rw-r--r--src/gen-s-parser.inc14
-rw-r--r--src/ir/ExpressionAnalyzer.cpp1
-rw-r--r--src/ir/ExpressionManipulator.cpp3
-rw-r--r--src/ir/ReFinalize.cpp1
-rw-r--r--src/ir/effects.h9
-rw-r--r--src/ir/utils.h2
-rw-r--r--src/js/binaryen.js-post.js36
-rw-r--r--src/passes/DeadCodeElimination.cpp2
-rw-r--r--src/passes/Print.cpp6
-rw-r--r--src/passes/RemoveUnusedModuleElements.cpp1
-rw-r--r--src/tools/fuzzing.h6
-rw-r--r--src/wasm-binary.h2
-rw-r--r--src/wasm-builder.h1
-rw-r--r--src/wasm-interpreter.h6
-rw-r--r--src/wasm-s-parser.h1
-rw-r--r--src/wasm-stack.h7
-rw-r--r--src/wasm-traversal.h16
-rw-r--r--src/wasm.h14
-rw-r--r--src/wasm/wasm-binary.cpp17
-rw-r--r--src/wasm/wasm-s-parser.cpp4
-rw-r--r--src/wasm/wasm-stack.cpp5
-rw-r--r--src/wasm/wasm-validator.cpp16
-rw-r--r--src/wasm/wasm.cpp2
-rw-r--r--src/wasm2js.h4
-rw-r--r--test/atomics.wast3
-rw-r--r--test/atomics.wast.from-wast3
-rw-r--r--test/atomics.wast.fromBinary3
-rw-r--r--test/atomics.wast.fromBinary.noDebugInfo3
-rw-r--r--test/binaryen.js/atomics.js25
-rw-r--r--test/binaryen.js/atomics.js.txt21
-rw-r--r--test/binaryen.js/exception-handling.js.txt8
-rw-r--r--test/binaryen.js/kitchen-sink.js24
-rw-r--r--test/binaryen.js/kitchen-sink.js.txt228
-rw-r--r--test/binaryen.js/push-pop.js.txt14
-rw-r--r--test/example/c-api-kitchen-sink.c12
-rw-r--r--test/example/c-api-kitchen-sink.txt91
-rw-r--r--test/example/c-api-kitchen-sink.txt.txt22
-rw-r--r--test/passes/translate-to-fuzz_all-features.txt344
-rw-r--r--test/passes/translate-to-fuzz_no-fuzz-nans_all-features.txt1352
-rw-r--r--test/spec/atomics.wast8
45 files changed, 1558 insertions, 817 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9f3dd2dd6..b904af9f2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,11 @@ full changeset diff at the end of each section.
Current Trunk
-------------
+- Binaryen.js instruction API changes:
+ - `notify` -> `atomic.notify`
+ - `i32.wait` / `i64.wait` -> `i32.atomic.wait` / `i64.atomic.wait`
+- Binaryen.js: `flags` argument in `setMemory` function is removed.
+- `atomic.fence` instruction support is added.
- wasm-emscripten-finalize: Don't realy on name section being present in the
input. Use the exported names for things instead.
diff --git a/build-js.sh b/build-js.sh
index 861aceefd..d05304bca 100755
--- a/build-js.sh
+++ b/build-js.sh
@@ -219,6 +219,7 @@ export_function "_BinaryenAtomicCmpxchgId"
export_function "_BinaryenAtomicRMWId"
export_function "_BinaryenAtomicWaitId"
export_function "_BinaryenAtomicNotifyId"
+export_function "_BinaryenAtomicFenceId"
export_function "_BinaryenSIMDExtractId"
export_function "_BinaryenSIMDReplaceId"
export_function "_BinaryenSIMDShuffleId"
@@ -575,6 +576,7 @@ export_function "_BinaryenAtomicRMW"
export_function "_BinaryenAtomicCmpxchg"
export_function "_BinaryenAtomicWait"
export_function "_BinaryenAtomicNotify"
+export_function "_BinaryenAtomicFence"
export_function "_BinaryenSIMDExtract"
export_function "_BinaryenSIMDReplace"
export_function "_BinaryenSIMDShuffle"
@@ -721,6 +723,9 @@ export_function "_BinaryenAtomicWaitGetExpectedType"
export_function "_BinaryenAtomicNotifyGetPtr"
export_function "_BinaryenAtomicNotifyGetNotifyCount"
+# 'AtomicFence' expression operations
+export_function "_BinaryenAtomicFenceGetOrder"
+
# 'SIMDExtract' expression operations
export_function "_BinaryenSIMDExtractGetOp"
export_function "_BinaryenSIMDExtractGetVec"
diff --git a/scripts/gen-s-parser.py b/scripts/gen-s-parser.py
index d6653e112..29f822f50 100755
--- a/scripts/gen-s-parser.py
+++ b/scripts/gen-s-parser.py
@@ -211,6 +211,7 @@ instructions = [
("atomic.notify", "makeAtomicNotify(s)"),
("i32.atomic.wait", "makeAtomicWait(s, i32)"),
("i64.atomic.wait", "makeAtomicWait(s, i64)"),
+ ("atomic.fence", "makeAtomicFence(s)"),
("i32.atomic.load8_u", "makeLoad(s, i32, /*isAtomic=*/true)"),
("i32.atomic.load16_u", "makeLoad(s, i32, /*isAtomic=*/true)"),
("i32.atomic.load", "makeLoad(s, i32, /*isAtomic=*/true)"),
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp
index d8f8163c4..a06e32d87 100644
--- a/src/binaryen-c.cpp
+++ b/src/binaryen-c.cpp
@@ -331,6 +331,9 @@ BinaryenExpressionId BinaryenAtomicWaitId(void) {
BinaryenExpressionId BinaryenAtomicNotifyId(void) {
return Expression::Id::AtomicNotifyId;
}
+BinaryenExpressionId BinaryenAtomicFenceId(void) {
+ return Expression::Id::AtomicFenceId;
+}
BinaryenExpressionId BinaryenSIMDExtractId(void) {
return Expression::Id::SIMDExtractId;
}
@@ -1466,6 +1469,15 @@ BinaryenExpressionRef BinaryenAtomicNotify(BinaryenModuleRef module,
return static_cast<Expression*>(ret);
}
+BinaryenExpressionRef BinaryenAtomicFence(BinaryenModuleRef module) {
+ auto* ret = Builder(*(Module*)module).makeAtomicFence();
+
+ if (tracing) {
+ traceExpression(ret, "BinaryenAtomicFence");
+ }
+
+ return static_cast<Expression*>(ret);
+}
BinaryenExpressionRef BinaryenSIMDExtract(BinaryenModuleRef module,
BinaryenOp op,
BinaryenExpressionRef vec,
@@ -2520,6 +2532,17 @@ BinaryenAtomicNotifyGetNotifyCount(BinaryenExpressionRef expr) {
assert(expression->is<AtomicNotify>());
return static_cast<AtomicNotify*>(expression)->notifyCount;
}
+// AtomicFence
+uint8_t BinaryenAtomicFenceGetOrder(BinaryenExpressionRef expr) {
+ if (tracing) {
+ std::cout << " BinaryenAtomicFenceGetOrder(expressions["
+ << expressions[expr] << "]);\n";
+ }
+
+ auto* expression = (Expression*)expr;
+ assert(expression->is<AtomicFence>());
+ return static_cast<AtomicFence*>(expression)->order;
+}
// SIMDExtract
BinaryenOp BinaryenSIMDExtractGetOp(BinaryenExpressionRef expr) {
if (tracing) {
diff --git a/src/binaryen-c.h b/src/binaryen-c.h
index b7c99ed1a..0637b65b0 100644
--- a/src/binaryen-c.h
+++ b/src/binaryen-c.h
@@ -119,6 +119,7 @@ BinaryenExpressionId BinaryenAtomicCmpxchgId(void);
BinaryenExpressionId BinaryenAtomicRMWId(void);
BinaryenExpressionId BinaryenAtomicWaitId(void);
BinaryenExpressionId BinaryenAtomicNotifyId(void);
+BinaryenExpressionId BinaryenAtomicFenceId(void);
BinaryenExpressionId BinaryenSIMDExtractId(void);
BinaryenExpressionId BinaryenSIMDReplaceId(void);
BinaryenExpressionId BinaryenSIMDShuffleId(void);
@@ -670,6 +671,7 @@ BinaryenExpressionRef BinaryenAtomicWait(BinaryenModuleRef module,
BinaryenExpressionRef BinaryenAtomicNotify(BinaryenModuleRef module,
BinaryenExpressionRef ptr,
BinaryenExpressionRef notifyCount);
+BinaryenExpressionRef BinaryenAtomicFence(BinaryenModuleRef module);
BinaryenExpressionRef BinaryenSIMDExtract(BinaryenModuleRef module,
BinaryenOp op,
BinaryenExpressionRef vec,
@@ -837,6 +839,8 @@ BinaryenExpressionRef BinaryenAtomicNotifyGetPtr(BinaryenExpressionRef expr);
BinaryenExpressionRef
BinaryenAtomicNotifyGetNotifyCount(BinaryenExpressionRef expr);
+uint8_t BinaryenAtomicFenceGetOrder(BinaryenExpressionRef expr);
+
BinaryenOp BinaryenSIMDExtractGetOp(BinaryenExpressionRef expr);
BinaryenExpressionRef BinaryenSIMDExtractGetVec(BinaryenExpressionRef expr);
uint8_t BinaryenSIMDExtractGetIndex(BinaryenExpressionRef expr);
diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc
index 15a73cdf2..68a8140a6 100644
--- a/src/gen-s-parser.inc
+++ b/src/gen-s-parser.inc
@@ -7,9 +7,17 @@
char op[27] = {'\0'};
strncpy(op, s[0]->c_str(), 26);
switch (op[0]) {
- case 'a':
- if (strcmp(op, "atomic.notify") == 0) { return makeAtomicNotify(s); }
- goto parse_error;
+ case 'a': {
+ switch (op[7]) {
+ case 'f':
+ if (strcmp(op, "atomic.fence") == 0) { return makeAtomicFence(s); }
+ goto parse_error;
+ case 'n':
+ if (strcmp(op, "atomic.notify") == 0) { return makeAtomicNotify(s); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
case 'b': {
switch (op[1]) {
case 'l':
diff --git a/src/ir/ExpressionAnalyzer.cpp b/src/ir/ExpressionAnalyzer.cpp
index f8f96d5c8..a52d7af90 100644
--- a/src/ir/ExpressionAnalyzer.cpp
+++ b/src/ir/ExpressionAnalyzer.cpp
@@ -180,6 +180,7 @@ template<typename T> void visitImmediates(Expression* curr, T& visitor) {
void visitAtomicNotify(AtomicNotify* curr) {
visitor.visitAddress(curr->offset);
}
+ void visitAtomicFence(AtomicFence* curr) { visitor.visitInt(curr->order); }
void visitSIMDExtract(SIMDExtract* curr) {
visitor.visitInt(curr->op);
visitor.visitInt(curr->index);
diff --git a/src/ir/ExpressionManipulator.cpp b/src/ir/ExpressionManipulator.cpp
index e650f40a7..7b0ee29d7 100644
--- a/src/ir/ExpressionManipulator.cpp
+++ b/src/ir/ExpressionManipulator.cpp
@@ -157,6 +157,9 @@ flexibleCopy(Expression* original, Module& wasm, CustomCopier custom) {
return builder.makeAtomicNotify(
copy(curr->ptr), copy(curr->notifyCount), curr->offset);
}
+ Expression* visitAtomicFence(AtomicFence* curr) {
+ return builder.makeAtomicFence();
+ }
Expression* visitSIMDExtract(SIMDExtract* curr) {
return builder.makeSIMDExtract(curr->op, copy(curr->vec), curr->index);
}
diff --git a/src/ir/ReFinalize.cpp b/src/ir/ReFinalize.cpp
index 05abb76e1..49b70684b 100644
--- a/src/ir/ReFinalize.cpp
+++ b/src/ir/ReFinalize.cpp
@@ -141,6 +141,7 @@ void ReFinalize::visitAtomicRMW(AtomicRMW* curr) { curr->finalize(); }
void ReFinalize::visitAtomicCmpxchg(AtomicCmpxchg* curr) { curr->finalize(); }
void ReFinalize::visitAtomicWait(AtomicWait* curr) { curr->finalize(); }
void ReFinalize::visitAtomicNotify(AtomicNotify* curr) { curr->finalize(); }
+void ReFinalize::visitAtomicFence(AtomicFence* curr) { curr->finalize(); }
void ReFinalize::visitSIMDExtract(SIMDExtract* curr) { curr->finalize(); }
void ReFinalize::visitSIMDReplace(SIMDReplace* curr) { curr->finalize(); }
void ReFinalize::visitSIMDShuffle(SIMDShuffle* curr) { curr->finalize(); }
diff --git a/src/ir/effects.h b/src/ir/effects.h
index e3997f5d2..c175bed85 100644
--- a/src/ir/effects.h
+++ b/src/ir/effects.h
@@ -294,7 +294,14 @@ struct EffectAnalyzer
if (!ignoreImplicitTraps) {
implicitTrap = true;
}
- };
+ }
+ void visitAtomicFence(AtomicFence* curr) {
+ // AtomicFence should not be reordered with any memory operations, so we set
+ // these to true.
+ readsMemory = true;
+ writesMemory = true;
+ isAtomic = true;
+ }
void visitSIMDExtract(SIMDExtract* curr) {}
void visitSIMDReplace(SIMDReplace* curr) {}
void visitSIMDShuffle(SIMDShuffle* curr) {}
diff --git a/src/ir/utils.h b/src/ir/utils.h
index 5c6a09290..43ba2fdde 100644
--- a/src/ir/utils.h
+++ b/src/ir/utils.h
@@ -128,6 +128,7 @@ struct ReFinalize
void visitAtomicCmpxchg(AtomicCmpxchg* curr);
void visitAtomicWait(AtomicWait* curr);
void visitAtomicNotify(AtomicNotify* curr);
+ void visitAtomicFence(AtomicFence* curr);
void visitSIMDExtract(SIMDExtract* curr);
void visitSIMDReplace(SIMDReplace* curr);
void visitSIMDShuffle(SIMDShuffle* curr);
@@ -191,6 +192,7 @@ struct ReFinalizeNode : public OverriddenVisitor<ReFinalizeNode> {
void visitAtomicCmpxchg(AtomicCmpxchg* curr) { curr->finalize(); }
void visitAtomicWait(AtomicWait* curr) { curr->finalize(); }
void visitAtomicNotify(AtomicNotify* curr) { curr->finalize(); }
+ void visitAtomicFence(AtomicFence* curr) { curr->finalize(); }
void visitSIMDExtract(SIMDExtract* curr) { curr->finalize(); }
void visitSIMDReplace(SIMDReplace* curr) { curr->finalize(); }
void visitSIMDShuffle(SIMDShuffle* curr) { curr->finalize(); }
diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js
index 635a10577..799cb30e4 100644
--- a/src/js/binaryen.js-post.js
+++ b/src/js/binaryen.js-post.js
@@ -70,6 +70,7 @@ Module['AtomicCmpxchgId'] = Module['_BinaryenAtomicCmpxchgId']();
Module['AtomicRMWId'] = Module['_BinaryenAtomicRMWId']();
Module['AtomicWaitId'] = Module['_BinaryenAtomicWaitId']();
Module['AtomicNotifyId'] = Module['_BinaryenAtomicNotifyId']();
+Module['AtomicFenceId'] = Module['_BinaryenAtomicFenceId']();
Module['SIMDExtractId'] = Module['_BinaryenSIMDExtractId']();
Module['SIMDReplaceId'] = Module['_BinaryenSIMDReplaceId']();
Module['SIMDShuffleId'] = Module['_BinaryenSIMDShuffleId']();
@@ -676,7 +677,7 @@ function wrapModule(module, self) {
'ge_u': function(left, right) {
return Module['_BinaryenBinary'](module, Module['GeUInt32'], left, right);
},
- 'atomic':{
+ 'atomic': {
'load': function(offset, ptr) {
return Module['_BinaryenAtomicLoad'](module, 4, offset, Module['i32'], ptr);
},
@@ -764,9 +765,9 @@ function wrapModule(module, self) {
return Module['_BinaryenAtomicCmpxchg'](module, 2, offset, ptr, expected, replacement, Module['i32'])
},
},
- },
- 'wait': function(ptr, expected, timeout) {
- return Module['_BinaryenAtomicWait'](module, ptr, expected, timeout, Module['i32']);
+ 'wait': function(ptr, expected, timeout) {
+ return Module['_BinaryenAtomicWait'](module, ptr, expected, timeout, Module['i32']);
+ }
},
'pop': function() {
return Module['_BinaryenPop'](module, Module['i32']);
@@ -951,7 +952,7 @@ function wrapModule(module, self) {
'ge_u': function(left, right) {
return Module['_BinaryenBinary'](module, Module['GeUInt64'], left, right);
},
- 'atomic':{
+ 'atomic': {
'load': function(offset, ptr) {
return Module['_BinaryenAtomicLoad'](module, 8, offset, Module['i64'], ptr);
},
@@ -1068,9 +1069,9 @@ function wrapModule(module, self) {
return Module['_BinaryenAtomicCmpxchg'](module, 4, offset, ptr, expected, replacement, Module['i64'])
},
},
- },
- 'wait': function(ptr, expected, timeout) {
- return Module['_BinaryenAtomicWait'](module, ptr, expected, timeout, Module['i64']);
+ 'wait': function(ptr, expected, timeout) {
+ return Module['_BinaryenAtomicWait'](module, ptr, expected, timeout, Module['i64']);
+ }
},
'pop': function() {
return Module['_BinaryenPop'](module, Module['i64']);
@@ -1773,9 +1774,16 @@ function wrapModule(module, self) {
self['unreachable'] = function() {
return Module['_BinaryenUnreachable'](module);
};
- self['notify'] = function(ptr, notifyCount) {
- return Module['_BinaryenAtomicNotify'](module, ptr, notifyCount);
+
+ self['atomic'] = {
+ 'notify': function(ptr, notifyCount) {
+ return Module['_BinaryenAtomicNotify'](module, ptr, notifyCount);
+ },
+ 'fence': function() {
+ return Module['_BinaryenAtomicFence'](module);
+ }
};
+
self['try'] = function(body, catchBody) {
return Module['_BinaryenTry'](module, body, catchBody);
};
@@ -1925,7 +1933,7 @@ function wrapModule(module, self) {
);
});
};
- self['setMemory'] = function(initial, maximum, exportName, segments, flags, shared) {
+ self['setMemory'] = function(initial, maximum, exportName, segments, shared) {
// segments are assumed to be { passive: bool, offset: expression ref, data: array of 8-bit data }
if (!segments) segments = [];
return preserveStack(function() {
@@ -2321,6 +2329,12 @@ Module['getExpressionInfo'] = function(expr) {
'ptr': Module['_BinaryenAtomicNotifyGetPtr'](expr),
'notifyCount': Module['_BinaryenAtomicNotifyGetNotifyCount'](expr)
};
+ case Module['AtomicFenceId']:
+ return {
+ 'id': id,
+ 'type': type,
+ 'order': Module['_BinaryenAtomicFenceGetOrder'](expr)
+ };
case Module['SIMDExtractId']:
return {
'id': id,
diff --git a/src/passes/DeadCodeElimination.cpp b/src/passes/DeadCodeElimination.cpp
index f913c5a93..464451763 100644
--- a/src/passes/DeadCodeElimination.cpp
+++ b/src/passes/DeadCodeElimination.cpp
@@ -298,6 +298,8 @@ struct DeadCodeElimination
DELEGATE(AtomicWait);
case Expression::Id::AtomicNotifyId:
DELEGATE(AtomicNotify);
+ case Expression::Id::AtomicFenceId:
+ DELEGATE(AtomicFence);
case Expression::Id::SIMDExtractId:
DELEGATE(SIMDExtract);
case Expression::Id::SIMDReplaceId:
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index 0bf61e784..b1e1240ae 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -268,6 +268,7 @@ struct PrintExpressionContents
o << " offset=" << curr->offset;
}
}
+ void visitAtomicFence(AtomicFence* curr) { printMedium(o, "atomic.fence"); }
void visitSIMDExtract(SIMDExtract* curr) {
prepareColor(o);
switch (curr->op) {
@@ -1505,6 +1506,11 @@ struct PrintSExpression : public OverriddenVisitor<PrintSExpression> {
printFullLine(curr->notifyCount);
decIndent();
}
+ void visitAtomicFence(AtomicFence* curr) {
+ o << '(';
+ PrintExpressionContents(currFunction, o).visit(curr);
+ o << ')';
+ }
void visitSIMDExtract(SIMDExtract* curr) {
o << '(';
PrintExpressionContents(currFunction, o).visit(curr);
diff --git a/src/passes/RemoveUnusedModuleElements.cpp b/src/passes/RemoveUnusedModuleElements.cpp
index 20c30d271..d4c6d5a5d 100644
--- a/src/passes/RemoveUnusedModuleElements.cpp
+++ b/src/passes/RemoveUnusedModuleElements.cpp
@@ -106,6 +106,7 @@ struct ReachabilityAnalyzer : public PostWalker<ReachabilityAnalyzer> {
void visitAtomicRMW(AtomicRMW* curr) { usesMemory = true; }
void visitAtomicWait(AtomicWait* curr) { usesMemory = true; }
void visitAtomicNotify(AtomicNotify* curr) { usesMemory = true; }
+ void visitAtomicFence(AtomicFence* curr) { usesMemory = true; }
void visitMemoryInit(MemoryInit* curr) { usesMemory = true; }
void visitDataDrop(DataDrop* curr) { usesMemory = true; }
void visitMemoryCopy(MemoryCopy* curr) { usesMemory = true; }
diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h
index baf42336d..dde8a0de7 100644
--- a/src/tools/fuzzing.h
+++ b/src/tools/fuzzing.h
@@ -953,7 +953,8 @@ private:
&Self::makeDrop,
&Self::makeNop,
&Self::makeGlobalSet)
- .add(FeatureSet::BulkMemory, &Self::makeBulkMemory);
+ .add(FeatureSet::BulkMemory, &Self::makeBulkMemory)
+ .add(FeatureSet::Atomics, &Self::makeAtomic);
return (this->*pick(options))(none);
}
@@ -2240,6 +2241,9 @@ private:
return makeTrivial(type);
}
wasm.memory.shared = true;
+ if (type == none) {
+ return builder.makeAtomicFence();
+ }
if (type == i32 && oneIn(2)) {
if (ATOMIC_WAITS && oneIn(2)) {
auto* ptr = makePointer();
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index d01502e9b..b3ac336ee 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -627,6 +627,7 @@ enum ASTNodes {
AtomicNotify = 0x00,
I32AtomicWait = 0x01,
I64AtomicWait = 0x02,
+ AtomicFence = 0x03,
I32AtomicLoad = 0x10,
I64AtomicLoad = 0x11,
@@ -1232,6 +1233,7 @@ public:
bool maybeVisitAtomicCmpxchg(Expression*& out, uint8_t code);
bool maybeVisitAtomicWait(Expression*& out, uint8_t code);
bool maybeVisitAtomicNotify(Expression*& out, uint8_t code);
+ bool maybeVisitAtomicFence(Expression*& out, uint8_t code);
bool maybeVisitConst(Expression*& out, uint8_t code);
bool maybeVisitUnary(Expression*& out, uint8_t code);
bool maybeVisitBinary(Expression*& out, uint8_t code);
diff --git a/src/wasm-builder.h b/src/wasm-builder.h
index 4258b9336..3e61b1a36 100644
--- a/src/wasm-builder.h
+++ b/src/wasm-builder.h
@@ -309,6 +309,7 @@ public:
notify->finalize();
return notify;
}
+ AtomicFence* makeAtomicFence() { return allocator.alloc<AtomicFence>(); }
Store* makeStore(unsigned bytes,
uint32_t offset,
unsigned align,
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index 05d00ed10..d854b20d3 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -1029,6 +1029,12 @@ public:
return Literal(uint64_t(val));
}
}
+ Flow visitAtomicFence(AtomicFence*) {
+ // Wasm currently supports only sequentially consistent atomics, in which
+ // case atomic_fence can be lowered to nothing.
+ NOTE_ENTER("AtomicFence");
+ return Flow();
+ }
Flow visitCall(Call*) { WASM_UNREACHABLE(); }
Flow visitCallIndirect(CallIndirect*) { WASM_UNREACHABLE(); }
diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h
index d6ec89319..b6ef320d5 100644
--- a/src/wasm-s-parser.h
+++ b/src/wasm-s-parser.h
@@ -194,6 +194,7 @@ private:
makeAtomicCmpxchg(Element& s, Type type, uint8_t bytes, const char* extra);
Expression* makeAtomicWait(Element& s, Type type);
Expression* makeAtomicNotify(Element& s);
+ Expression* makeAtomicFence(Element& s);
Expression* makeSIMDExtract(Element& s, SIMDExtractOp op, size_t lanes);
Expression* makeSIMDReplace(Element& s, SIMDReplaceOp op, size_t lanes);
Expression* makeSIMDShuffle(Element& s);
diff --git a/src/wasm-stack.h b/src/wasm-stack.h
index 562a00684..3a7d7c38e 100644
--- a/src/wasm-stack.h
+++ b/src/wasm-stack.h
@@ -103,6 +103,7 @@ public:
void visitAtomicCmpxchg(AtomicCmpxchg* curr);
void visitAtomicWait(AtomicWait* curr);
void visitAtomicNotify(AtomicNotify* curr);
+ void visitAtomicFence(AtomicFence* curr);
void visitSIMDExtract(SIMDExtract* curr);
void visitSIMDReplace(SIMDReplace* curr);
void visitSIMDShuffle(SIMDShuffle* curr);
@@ -178,6 +179,7 @@ public:
void visitAtomicCmpxchg(AtomicCmpxchg* curr);
void visitAtomicWait(AtomicWait* curr);
void visitAtomicNotify(AtomicNotify* curr);
+ void visitAtomicFence(AtomicFence* curr);
void visitSIMDExtract(SIMDExtract* curr);
void visitSIMDReplace(SIMDReplace* curr);
void visitSIMDShuffle(SIMDShuffle* curr);
@@ -526,6 +528,11 @@ void BinaryenIRWriter<SubType>::visitAtomicNotify(AtomicNotify* curr) {
}
template<typename SubType>
+void BinaryenIRWriter<SubType>::visitAtomicFence(AtomicFence* curr) {
+ emit(curr);
+}
+
+template<typename SubType>
void BinaryenIRWriter<SubType>::visitSIMDExtract(SIMDExtract* curr) {
visit(curr->vec);
if (curr->type == unreachable) {
diff --git a/src/wasm-traversal.h b/src/wasm-traversal.h
index 5e9925b63..202d136c8 100644
--- a/src/wasm-traversal.h
+++ b/src/wasm-traversal.h
@@ -54,6 +54,7 @@ template<typename SubType, typename ReturnType = void> struct Visitor {
ReturnType visitAtomicCmpxchg(AtomicCmpxchg* curr) { return ReturnType(); }
ReturnType visitAtomicWait(AtomicWait* curr) { return ReturnType(); }
ReturnType visitAtomicNotify(AtomicNotify* curr) { return ReturnType(); }
+ ReturnType visitAtomicFence(AtomicFence* curr) { return ReturnType(); }
ReturnType visitSIMDExtract(SIMDExtract* curr) { return ReturnType(); }
ReturnType visitSIMDReplace(SIMDReplace* curr) { return ReturnType(); }
ReturnType visitSIMDShuffle(SIMDShuffle* curr) { return ReturnType(); }
@@ -130,6 +131,8 @@ template<typename SubType, typename ReturnType = void> struct Visitor {
DELEGATE(AtomicWait);
case Expression::Id::AtomicNotifyId:
DELEGATE(AtomicNotify);
+ case Expression::Id::AtomicFenceId:
+ DELEGATE(AtomicFence);
case Expression::Id::SIMDExtractId:
DELEGATE(SIMDExtract);
case Expression::Id::SIMDReplaceId:
@@ -218,6 +221,7 @@ struct OverriddenVisitor {
UNIMPLEMENTED(AtomicCmpxchg);
UNIMPLEMENTED(AtomicWait);
UNIMPLEMENTED(AtomicNotify);
+ UNIMPLEMENTED(AtomicFence);
UNIMPLEMENTED(SIMDExtract);
UNIMPLEMENTED(SIMDReplace);
UNIMPLEMENTED(SIMDShuffle);
@@ -295,6 +299,8 @@ struct OverriddenVisitor {
DELEGATE(AtomicWait);
case Expression::Id::AtomicNotifyId:
DELEGATE(AtomicNotify);
+ case Expression::Id::AtomicFenceId:
+ DELEGATE(AtomicFence);
case Expression::Id::SIMDExtractId:
DELEGATE(SIMDExtract);
case Expression::Id::SIMDReplaceId:
@@ -412,6 +418,9 @@ struct UnifiedExpressionVisitor : public Visitor<SubType, ReturnType> {
ReturnType visitAtomicNotify(AtomicNotify* curr) {
return static_cast<SubType*>(this)->visitExpression(curr);
}
+ ReturnType visitAtomicFence(AtomicFence* curr) {
+ return static_cast<SubType*>(this)->visitExpression(curr);
+ }
ReturnType visitSIMDExtract(SIMDExtract* curr) {
return static_cast<SubType*>(this)->visitExpression(curr);
}
@@ -711,6 +720,9 @@ struct Walker : public VisitorType {
static void doVisitAtomicNotify(SubType* self, Expression** currp) {
self->visitAtomicNotify((*currp)->cast<AtomicNotify>());
}
+ static void doVisitAtomicFence(SubType* self, Expression** currp) {
+ self->visitAtomicFence((*currp)->cast<AtomicFence>());
+ }
static void doVisitSIMDExtract(SubType* self, Expression** currp) {
self->visitSIMDExtract((*currp)->cast<SIMDExtract>());
}
@@ -913,6 +925,10 @@ struct PostWalker : public Walker<SubType, VisitorType> {
self->pushTask(SubType::scan, &curr->cast<AtomicNotify>()->ptr);
break;
}
+ case Expression::Id::AtomicFenceId: {
+ self->pushTask(SubType::doVisitAtomicFence, currp);
+ break;
+ }
case Expression::Id::SIMDExtractId: {
self->pushTask(SubType::doVisitSIMDExtract, currp);
self->pushTask(SubType::scan, &curr->cast<SIMDExtract>()->vec);
diff --git a/src/wasm.h b/src/wasm.h
index d4441259e..e7d83ace3 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -468,6 +468,7 @@ public:
AtomicCmpxchgId,
AtomicWaitId,
AtomicNotifyId,
+ AtomicFenceId,
SIMDExtractId,
SIMDReplaceId,
SIMDShuffleId,
@@ -785,6 +786,17 @@ public:
void finalize();
};
+class AtomicFence : public SpecificExpression<Expression::AtomicFenceId> {
+public:
+ AtomicFence() = default;
+ AtomicFence(MixedArena& allocator) : AtomicFence() {}
+
+ // Current wasm threads only supports sequentialy consistent atomics, but
+ // other orderings may be added in the future. This field is reserved for
+ // that, and currently set to 0.
+ uint8_t order = 0;
+};
+
class SIMDExtract : public SpecificExpression<Expression::SIMDExtractId> {
public:
SIMDExtract() = default;
@@ -1243,7 +1255,7 @@ class Event : public Importable {
public:
Name name;
// Kind of event. Currently only WASM_EVENT_ATTRIBUTE_EXCEPTION is possible.
- uint32_t attribute;
+ uint32_t attribute = WASM_EVENT_ATTRIBUTE_EXCEPTION;
// Type string in the format of function type. Return type is considered as a
// void type. So if you have an event whose type is (i32, i32), the type
// string will be "vii".
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index d75973ab0..b7daeda5a 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -2302,6 +2302,9 @@ BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) {
if (maybeVisitAtomicNotify(curr, code)) {
break;
}
+ if (maybeVisitAtomicFence(curr, code)) {
+ break;
+ }
throwError("invalid code after atomic prefix: " + std::to_string(code));
break;
}
@@ -3172,6 +3175,20 @@ bool WasmBinaryBuilder::maybeVisitAtomicNotify(Expression*& out, uint8_t code) {
return true;
}
+bool WasmBinaryBuilder::maybeVisitAtomicFence(Expression*& out, uint8_t code) {
+ if (code != BinaryConsts::AtomicFence) {
+ return false;
+ }
+ auto* curr = allocator.alloc<AtomicFence>();
+ if (debug) {
+ std::cerr << "zz node: AtomicFence" << std::endl;
+ }
+ curr->order = getU32LEB();
+ curr->finalize();
+ out = curr;
+ return true;
+}
+
bool WasmBinaryBuilder::maybeVisitConst(Expression*& out, uint8_t code) {
Const* curr;
if (debug) {
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index 39f6b0a9f..3a1e0db09 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -1421,6 +1421,10 @@ Expression* SExpressionWasmBuilder::makeAtomicNotify(Element& s) {
return ret;
}
+Expression* SExpressionWasmBuilder::makeAtomicFence(Element& s) {
+ return allocator.alloc<AtomicFence>();
+}
+
static uint8_t parseLaneIndex(const Element* s, size_t lanes) {
const char* str = s->c_str();
char* end;
diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp
index cb60c50f9..faa06330b 100644
--- a/src/wasm/wasm-stack.cpp
+++ b/src/wasm/wasm-stack.cpp
@@ -422,6 +422,11 @@ void BinaryInstWriter::visitAtomicNotify(AtomicNotify* curr) {
emitMemoryAccess(4, 4, 0);
}
+void BinaryInstWriter::visitAtomicFence(AtomicFence* curr) {
+ o << int8_t(BinaryConsts::AtomicPrefix) << int8_t(BinaryConsts::AtomicFence)
+ << int8_t(curr->order);
+}
+
void BinaryInstWriter::visitSIMDExtract(SIMDExtract* curr) {
o << int8_t(BinaryConsts::SIMDPrefix);
switch (curr->op) {
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index 339ad6f68..9b1220371 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -270,6 +270,7 @@ public:
void visitAtomicCmpxchg(AtomicCmpxchg* curr);
void visitAtomicWait(AtomicWait* curr);
void visitAtomicNotify(AtomicNotify* curr);
+ void visitAtomicFence(AtomicFence* curr);
void visitSIMDExtract(SIMDExtract* curr);
void visitSIMDReplace(SIMDReplace* curr);
void visitSIMDShuffle(SIMDShuffle* curr);
@@ -917,6 +918,21 @@ void FunctionValidator::visitAtomicNotify(AtomicNotify* curr) {
"AtomicNotify notifyCount type must be i32");
}
+void FunctionValidator::visitAtomicFence(AtomicFence* curr) {
+ shouldBeTrue(
+ getModule()->memory.exists, curr, "Memory operations require a memory");
+ shouldBeTrue(getModule()->features.hasAtomics(),
+ curr,
+ "Atomic operation (atomics are disabled)");
+ shouldBeFalse(!getModule()->memory.shared,
+ curr,
+ "Atomic operation with non-shared memory");
+ shouldBeTrue(curr->order == 0,
+ curr,
+ "Currently only sequentially consistent atomics are supported, "
+ "so AtomicFence's order should be 0");
+}
+
void FunctionValidator::visitSIMDExtract(SIMDExtract* curr) {
shouldBeTrue(
getModule()->features.hasSIMD(), curr, "SIMD operation (SIMD is disabled)");
diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp
index f8791286c..b13797c89 100644
--- a/src/wasm/wasm.cpp
+++ b/src/wasm/wasm.cpp
@@ -147,6 +147,8 @@ const char* getExpressionName(Expression* curr) {
return "atomic_wait";
case Expression::Id::AtomicNotifyId:
return "atomic_notify";
+ case Expression::Id::AtomicFenceId:
+ return "atomic_fence";
case Expression::Id::SIMDExtractId:
return "simd_extract";
case Expression::Id::SIMDReplaceId:
diff --git a/src/wasm2js.h b/src/wasm2js.h
index 624847f7d..54a06578f 100644
--- a/src/wasm2js.h
+++ b/src/wasm2js.h
@@ -1816,6 +1816,10 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m,
unimplemented(curr);
WASM_UNREACHABLE();
}
+ Ref visitAtomicFence(AtomicFence* curr) {
+ // Sequentially consistent fences can be lowered to no operation
+ return ValueBuilder::makeToplevel();
+ }
Ref visitSIMDExtract(SIMDExtract* curr) {
unimplemented(curr);
WASM_UNREACHABLE();
diff --git a/test/atomics.wast b/test/atomics.wast
index 2dcad6459..8ba9906c5 100644
--- a/test/atomics.wast
+++ b/test/atomics.wast
@@ -158,4 +158,7 @@
)
)
)
+ (func $atomic-fence (type $0)
+ (atomic.fence)
+ )
)
diff --git a/test/atomics.wast.from-wast b/test/atomics.wast.from-wast
index 2869d5da4..c3fdd375d 100644
--- a/test/atomics.wast.from-wast
+++ b/test/atomics.wast.from-wast
@@ -158,4 +158,7 @@
)
)
)
+ (func $atomic-fence (; 4 ;) (type $0)
+ (atomic.fence)
+ )
)
diff --git a/test/atomics.wast.fromBinary b/test/atomics.wast.fromBinary
index dc5cb0145..78d086a0c 100644
--- a/test/atomics.wast.fromBinary
+++ b/test/atomics.wast.fromBinary
@@ -158,5 +158,8 @@
)
)
)
+ (func $atomic-fence (; 4 ;) (type $0)
+ (atomic.fence)
+ )
)
diff --git a/test/atomics.wast.fromBinary.noDebugInfo b/test/atomics.wast.fromBinary.noDebugInfo
index 77fb51917..86860c907 100644
--- a/test/atomics.wast.fromBinary.noDebugInfo
+++ b/test/atomics.wast.fromBinary.noDebugInfo
@@ -158,5 +158,8 @@
)
)
)
+ (func $4 (; 4 ;) (type $0)
+ (atomic.fence)
+ )
)
diff --git a/test/binaryen.js/atomics.js b/test/binaryen.js/atomics.js
index a1f8fc842..40c3ea0ab 100644
--- a/test/binaryen.js/atomics.js
+++ b/test/binaryen.js/atomics.js
@@ -60,7 +60,30 @@ module.addFunction("main", signature, [], module.block("", [
module.i64.atomic.load32_u(0,
module.i32.const(0)
)
- )
+ ),
+ // wait and notify
+ module.drop(
+ module.i32.atomic.wait(
+ module.i32.const(0),
+ module.i32.const(0),
+ module.i64.const(0)
+ )
+ ),
+ module.drop(
+ module.i64.atomic.wait(
+ module.i32.const(0),
+ module.i64.const(0),
+ module.i64.const(0)
+ )
+ ),
+ module.drop(
+ module.atomic.notify(
+ module.i32.const(0),
+ module.i32.const(0)
+ )
+ ),
+ // fence
+ module.atomic.fence()
]));
module.setFeatures(Binaryen.Features.Atomics);
diff --git a/test/binaryen.js/atomics.js.txt b/test/binaryen.js/atomics.js.txt
index 177ba34a6..0a8659acf 100644
--- a/test/binaryen.js/atomics.js.txt
+++ b/test/binaryen.js/atomics.js.txt
@@ -44,6 +44,27 @@
(i32.const 0)
)
)
+ (drop
+ (i32.atomic.wait
+ (i32.const 0)
+ (i32.const 0)
+ (i64.const 0)
+ )
+ )
+ (drop
+ (i64.atomic.wait
+ (i32.const 0)
+ (i64.const 0)
+ (i64.const 0)
+ )
+ )
+ (drop
+ (atomic.notify
+ (i32.const 0)
+ (i32.const 0)
+ )
+ )
+ (atomic.fence)
)
)
diff --git a/test/binaryen.js/exception-handling.js.txt b/test/binaryen.js/exception-handling.js.txt
index cdf45aeaa..463743ff6 100644
--- a/test/binaryen.js/exception-handling.js.txt
+++ b/test/binaryen.js/exception-handling.js.txt
@@ -26,7 +26,7 @@
)
)
-getExpressionInfo(throw) = {"id":39,"type":8,"event":"e"}
-getExpressionInfo(br_on_exn) = {"id":41,"type":7,"name":"l","event":"e"}
-getExpressionInfo(rethrow) = {"id":40,"type":8}
-getExpressionInfo(try) = {"id":38,"type":0}
+getExpressionInfo(throw) = {"id":40,"type":8,"event":"e"}
+getExpressionInfo(br_on_exn) = {"id":42,"type":7,"name":"l","event":"e"}
+getExpressionInfo(rethrow) = {"id":41,"type":8}
+getExpressionInfo(try) = {"id":39,"type":0}
diff --git a/test/binaryen.js/kitchen-sink.js b/test/binaryen.js/kitchen-sink.js
index f2a78ab34..89e7fdfc6 100644
--- a/test/binaryen.js/kitchen-sink.js
+++ b/test/binaryen.js/kitchen-sink.js
@@ -428,6 +428,28 @@ function test_core() {
)
),
+ // Atomics
+ module.i32.atomic.store(0,
+ module.i32.const(0),
+ module.i32.atomic.load(0,
+ module.i32.const(0)
+ )
+ ),
+ module.drop(
+ module.i32.atomic.wait(
+ module.i32.const(0),
+ module.i32.const(0),
+ module.i64.const(0)
+ )
+ ),
+ module.drop(
+ module.atomic.notify(
+ module.i32.const(0),
+ module.i32.const(0)
+ )
+ ),
+ module.atomic.fence(),
+
// Push and pop
module.push(module.i32.pop()),
module.push(module.i64.pop()),
@@ -492,7 +514,7 @@ function test_core() {
offset: null,
data: "I am passive".split('').map(function(x) { return x.charCodeAt(0) })
}
- ]);
+ ], true);
// Start function. One per module
diff --git a/test/binaryen.js/kitchen-sink.js.txt b/test/binaryen.js/kitchen-sink.js.txt
index b1f269a30..d4ca83b1c 100644
--- a/test/binaryen.js/kitchen-sink.js.txt
+++ b/test/binaryen.js/kitchen-sink.js.txt
@@ -44,21 +44,21 @@ BinaryenAtomicCmpxchgId: 24
BinaryenAtomicRMWId: 23
BinaryenAtomicWaitId: 25
BinaryenAtomicNotifyId: 26
-BinaryenSIMDExtractId: 27
-BinaryenSIMDReplaceId: 28
-BinaryenSIMDShuffleId: 29
-BinaryenSIMDBitselectId: 30
-BinaryenSIMDShiftId: 31
-MemoryInitId: 32
-DataDropId: 33
-MemoryCopyId: 34
-MemoryFillId: 35
-TryId: 38
-ThrowId: 39
-RethrowId: 40
-BrOnExnId: 41
-PushId: 36
-PopId: 37
+BinaryenSIMDExtractId: 28
+BinaryenSIMDReplaceId: 29
+BinaryenSIMDShuffleId: 30
+BinaryenSIMDBitselectId: 31
+BinaryenSIMDShiftId: 32
+MemoryInitId: 33
+DataDropId: 34
+MemoryCopyId: 35
+MemoryFillId: 36
+TryId: 39
+ThrowId: 40
+RethrowId: 41
+BrOnExnId: 42
+PushId: 37
+PopId: 38
getExpressionInfo={"id":15,"type":3,"op":6}
(f32.neg
(f32.const -33.61199951171875)
@@ -77,7 +77,7 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5}
(import "module" "base" (global $a-global-imp i32))
(import "module" "base" (func $an-imported (param i32 f64) (result f32)))
(import "module" "base" (event $a-event-imp (attr 0) (param i32)))
- (memory $0 1 256)
+ (memory $0 (shared 1 256))
(data (i32.const 10) "hello, world")
(data passive "I am passive")
(table $0 1 funcref)
@@ -1456,6 +1456,26 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5}
)
)
)
+ (i32.atomic.store
+ (i32.const 0)
+ (i32.atomic.load
+ (i32.const 0)
+ )
+ )
+ (drop
+ (i32.atomic.wait
+ (i32.const 0)
+ (i32.const 0)
+ (i64.const 0)
+ )
+ )
+ (drop
+ (atomic.notify
+ (i32.const 0)
+ (i32.const 0)
+ )
+ )
+ (atomic.fence)
(push
(i32.pop)
)
@@ -1496,7 +1516,7 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5}
(import "module" "base" (global $a-global-imp i32))
(import "module" "base" (func $an-imported (param i32 f64) (result f32)))
(import "module" "base" (event $a-event-imp (attr 0) (param i32)))
- (memory $0 1 256)
+ (memory $0 (shared 1 256))
(data (i32.const 10) "hello, world")
(data passive "I am passive")
(table $0 1 funcref)
@@ -2875,6 +2895,26 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5}
)
)
)
+ (i32.atomic.store
+ (i32.const 0)
+ (i32.atomic.load
+ (i32.const 0)
+ )
+ )
+ (drop
+ (i32.atomic.wait
+ (i32.const 0)
+ (i32.const 0)
+ (i64.const 0)
+ )
+ )
+ (drop
+ (atomic.notify
+ (i32.const 0)
+ (i32.const 0)
+ )
+ )
+ (atomic.fence)
(push
(i32.pop)
)
@@ -4775,20 +4815,34 @@ int main() {
expressions[665] = BinaryenBlock(the_module, NULL, children, 2, 0);
}
expressions[666] = BinaryenTry(the_module, expressions[657], expressions[665]);
- expressions[667] = BinaryenPop(the_module, 1);
- expressions[668] = BinaryenPush(the_module, expressions[667]);
- expressions[669] = BinaryenPop(the_module, 2);
- expressions[670] = BinaryenPush(the_module, expressions[669]);
- expressions[671] = BinaryenPop(the_module, 3);
- expressions[672] = BinaryenPush(the_module, expressions[671]);
- expressions[673] = BinaryenPop(the_module, 4);
- expressions[674] = BinaryenPush(the_module, expressions[673]);
- expressions[675] = BinaryenPop(the_module, 5);
- expressions[676] = BinaryenPush(the_module, expressions[675]);
- expressions[677] = BinaryenPop(the_module, 7);
- expressions[678] = BinaryenPush(the_module, expressions[677]);
- expressions[679] = BinaryenNop(the_module);
- expressions[680] = BinaryenUnreachable(the_module);
+ expressions[667] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
+ expressions[668] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
+ expressions[669] = BinaryenAtomicLoad(the_module, 4, 0, 1, expressions[668]);
+ expressions[670] = BinaryenAtomicStore(the_module, 4, 0, expressions[667], expressions[669], 1);
+ expressions[671] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
+ expressions[672] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
+ expressions[673] = BinaryenConst(the_module, BinaryenLiteralInt64(0));
+ expressions[674] = BinaryenAtomicWait(the_module, expressions[671], expressions[672], expressions[673], 1);
+ expressions[675] = BinaryenDrop(the_module, expressions[674]);
+ expressions[676] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
+ expressions[677] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
+ expressions[678] = BinaryenAtomicNotify(the_module, expressions[676], expressions[677]);
+ expressions[679] = BinaryenDrop(the_module, expressions[678]);
+ expressions[680] = BinaryenAtomicFence(the_module);
+ expressions[681] = BinaryenPop(the_module, 1);
+ expressions[682] = BinaryenPush(the_module, expressions[681]);
+ expressions[683] = BinaryenPop(the_module, 2);
+ expressions[684] = BinaryenPush(the_module, expressions[683]);
+ expressions[685] = BinaryenPop(the_module, 3);
+ expressions[686] = BinaryenPush(the_module, expressions[685]);
+ expressions[687] = BinaryenPop(the_module, 4);
+ expressions[688] = BinaryenPush(the_module, expressions[687]);
+ expressions[689] = BinaryenPop(the_module, 5);
+ expressions[690] = BinaryenPush(the_module, expressions[689]);
+ expressions[691] = BinaryenPop(the_module, 7);
+ expressions[692] = BinaryenPush(the_module, expressions[691]);
+ expressions[693] = BinaryenNop(the_module);
+ expressions[694] = BinaryenUnreachable(the_module);
BinaryenExpressionGetId(expressions[30]);
BinaryenExpressionGetType(expressions[30]);
BinaryenUnaryGetOp(expressions[30]);
@@ -4799,26 +4853,26 @@ getExpressionInfo={"id":15,"type":3,"op":6}
(f32.const -33.61199951171875)
)
- expressions[681] = BinaryenConst(the_module, BinaryenLiteralInt32(5));
- BinaryenExpressionGetId(expressions[681]);
- BinaryenExpressionGetType(expressions[681]);
- BinaryenConstGetValueI32(expressions[681]);
+ expressions[695] = BinaryenConst(the_module, BinaryenLiteralInt32(5));
+ BinaryenExpressionGetId(expressions[695]);
+ BinaryenExpressionGetType(expressions[695]);
+ BinaryenConstGetValueI32(expressions[695]);
getExpressionInfo(i32.const)={"id":14,"type":1,"value":5}
- expressions[682] = BinaryenConst(the_module, BinaryenLiteralInt64(30064771078));
- BinaryenExpressionGetId(expressions[682]);
- BinaryenExpressionGetType(expressions[682]);
- BinaryenConstGetValueI64Low(expressions[682]);
- BinaryenConstGetValueI64High(expressions[682]);
+ expressions[696] = BinaryenConst(the_module, BinaryenLiteralInt64(30064771078));
+ BinaryenExpressionGetId(expressions[696]);
+ BinaryenExpressionGetType(expressions[696]);
+ BinaryenConstGetValueI64Low(expressions[696]);
+ BinaryenConstGetValueI64High(expressions[696]);
getExpressionInfo(i64.const)={"id":14,"type":2,"value":{"low":6,"high":7}}
- expressions[683] = BinaryenConst(the_module, BinaryenLiteralFloat32(8.5));
- BinaryenExpressionGetId(expressions[683]);
- BinaryenExpressionGetType(expressions[683]);
- BinaryenConstGetValueF32(expressions[683]);
+ expressions[697] = BinaryenConst(the_module, BinaryenLiteralFloat32(8.5));
+ BinaryenExpressionGetId(expressions[697]);
+ BinaryenExpressionGetType(expressions[697]);
+ BinaryenConstGetValueF32(expressions[697]);
getExpressionInfo(f32.const)={"id":14,"type":3,"value":8.5}
- expressions[684] = BinaryenConst(the_module, BinaryenLiteralFloat64(9.5));
- BinaryenExpressionGetId(expressions[684]);
- BinaryenExpressionGetType(expressions[684]);
- BinaryenConstGetValueF64(expressions[684]);
+ expressions[698] = BinaryenConst(the_module, BinaryenLiteralFloat64(9.5));
+ BinaryenExpressionGetId(expressions[698]);
+ BinaryenExpressionGetType(expressions[698]);
+ BinaryenConstGetValueF64(expressions[698]);
getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5}
{
BinaryenExpressionRef children[] = { expressions[24], expressions[26], expressions[28], expressions[30], expressions[32],
@@ -4862,26 +4916,26 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5}
expressions[606], expressions[612], expressions[617], expressions[624], expressions[626], expressions[628],
expressions[631], expressions[633], expressions[635], expressions[637], expressions[639], expressions[640],
expressions[641], expressions[642], expressions[644], expressions[649], expressions[655], expressions[666],
- expressions[668], expressions[670], expressions[672], expressions[674], expressions[676], expressions[678],
- expressions[679], expressions[680] };
- expressions[685] = BinaryenBlock(the_module, "the-value", children, 253, 0);
+ expressions[670], expressions[675], expressions[679], expressions[680], expressions[682], expressions[684],
+ expressions[686], expressions[688], expressions[690], expressions[692], expressions[693], expressions[694] };
+ expressions[699] = BinaryenBlock(the_module, "the-value", children, 257, 0);
}
- expressions[686] = BinaryenDrop(the_module, expressions[685]);
+ expressions[700] = BinaryenDrop(the_module, expressions[699]);
{
- BinaryenExpressionRef children[] = { expressions[686] };
- expressions[687] = BinaryenBlock(the_module, "the-nothing", children, 1, 0);
+ BinaryenExpressionRef children[] = { expressions[700] };
+ expressions[701] = BinaryenBlock(the_module, "the-nothing", children, 1, 0);
}
- expressions[688] = BinaryenConst(the_module, BinaryenLiteralInt32(42));
+ expressions[702] = BinaryenConst(the_module, BinaryenLiteralInt32(42));
{
- BinaryenExpressionRef children[] = { expressions[687], expressions[688] };
- expressions[689] = BinaryenBlock(the_module, "the-body", children, 2, 0);
+ BinaryenExpressionRef children[] = { expressions[701], expressions[702] };
+ expressions[703] = BinaryenBlock(the_module, "the-body", children, 2, 0);
}
{
BinaryenType varTypes[] = { 1, 7 };
- functions[0] = BinaryenAddFunction(the_module, "kitchen()sinker", functionTypes[1], varTypes, 2, expressions[689]);
+ functions[0] = BinaryenAddFunction(the_module, "kitchen()sinker", functionTypes[1], varTypes, 2, expressions[703]);
}
- expressions[690] = BinaryenConst(the_module, BinaryenLiteralInt32(1));
- globals[0] = BinaryenAddGlobal(the_module, "a-global", 1, 0, expressions[690]);
+ expressions[704] = BinaryenConst(the_module, BinaryenLiteralInt32(1));
+ globals[0] = BinaryenAddGlobal(the_module, "a-global", 1, 0, expressions[704]);
{
BinaryenType paramTypes[] = { 1, 4 };
functionTypes[2] = BinaryenAddFunctionType(the_module, "fiF", 3, paramTypes, 2);
@@ -4910,24 +4964,24 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5}
const char* funcNames[] = { "kitchen()sinker" };
BinaryenSetFunctionTable(the_module, 1, 4294967295, funcNames, 1);
}
- expressions[691] = BinaryenConst(the_module, BinaryenLiteralInt32(10));
+ expressions[705] = BinaryenConst(the_module, BinaryenLiteralInt32(10));
{
const char segment0[] = { 104, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100 };
const char segment1[] = { 73, 32, 97, 109, 32, 112, 97, 115, 115, 105, 118, 101 };
const char* segments[] = { segment0, segment1 };
int8_t segmentPassive[] = { 0, 1 };
- BinaryenExpressionRef segmentOffsets[] = { expressions[691], expressions[0] };
+ BinaryenExpressionRef segmentOffsets[] = { expressions[705], expressions[0] };
BinaryenIndex segmentSizes[] = { 12, 12 };
- BinaryenSetMemory(the_module, 1, 256, "mem", segments, segmentPassive, segmentOffsets, segmentSizes, 2, 0);
+ BinaryenSetMemory(the_module, 1, 256, "mem", segments, segmentPassive, segmentOffsets, segmentSizes, 2, 1);
}
{
BinaryenType paramTypes[] = { 0 };
functionTypes[3] = BinaryenAddFunctionType(the_module, "v", 0, paramTypes, 0);
}
- expressions[692] = BinaryenNop(the_module);
+ expressions[706] = BinaryenNop(the_module);
{
BinaryenType varTypes[] = { 0 };
- functions[1] = BinaryenAddFunction(the_module, "starter", functionTypes[3], varTypes, 0, expressions[692]);
+ functions[1] = BinaryenAddFunction(the_module, "starter", functionTypes[3], varTypes, 0, expressions[706]);
}
BinaryenSetStart(the_module, functions[1]);
{
@@ -4947,7 +5001,7 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5}
(import "module" "base" (global $a-global-imp i32))
(import "module" "base" (func $an-imported (param i32 f64) (result f32)))
(import "module" "base" (event $a-event-imp (attr 0) (param i32)))
- (memory $0 1 256)
+ (memory $0 (shared 1 256))
(data (i32.const 10) "hello, world")
(data passive "I am passive")
(table $0 1 funcref)
@@ -6326,6 +6380,26 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5}
)
)
)
+ (i32.atomic.store
+ (i32.const 0)
+ (i32.atomic.load
+ (i32.const 0)
+ )
+ )
+ (drop
+ (i32.atomic.wait
+ (i32.const 0)
+ (i32.const 0)
+ (i64.const 0)
+ )
+ )
+ (drop
+ (atomic.notify
+ (i32.const 0)
+ (i32.const 0)
+ )
+ )
+ (atomic.fence)
(push
(i32.pop)
)
@@ -6368,7 +6442,7 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5}
(import "module" "base" (global $a-global-imp i32))
(import "module" "base" (func $an-imported (param i32 f64) (result f32)))
(import "module" "base" (event $a-event-imp (attr 0) (param i32)))
- (memory $0 1 256)
+ (memory $0 (shared 1 256))
(data (i32.const 10) "hello, world")
(data passive "I am passive")
(table $0 1 funcref)
@@ -7747,6 +7821,26 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5}
)
)
)
+ (i32.atomic.store
+ (i32.const 0)
+ (i32.atomic.load
+ (i32.const 0)
+ )
+ )
+ (drop
+ (i32.atomic.wait
+ (i32.const 0)
+ (i32.const 0)
+ (i64.const 0)
+ )
+ )
+ (drop
+ (atomic.notify
+ (i32.const 0)
+ (i32.const 0)
+ )
+ )
+ (atomic.fence)
(push
(i32.pop)
)
diff --git a/test/binaryen.js/push-pop.js.txt b/test/binaryen.js/push-pop.js.txt
index c9689831f..80166906a 100644
--- a/test/binaryen.js/push-pop.js.txt
+++ b/test/binaryen.js/push-pop.js.txt
@@ -22,10 +22,10 @@
)
)
-getExpressionInfo(i32.pop) = {"id":37,"type":1}
-getExpressionInfo(i64.pop) = {"id":37,"type":2}
-getExpressionInfo(f32.pop) = {"id":37,"type":3}
-getExpressionInfo(f64.pop) = {"id":37,"type":4}
-getExpressionInfo(v128.pop) = {"id":37,"type":5}
-getExpressionInfo(exnref.pop) = {"id":37,"type":7}
-getExpressionInfo(push) = {"id":36}
+getExpressionInfo(i32.pop) = {"id":38,"type":1}
+getExpressionInfo(i64.pop) = {"id":38,"type":2}
+getExpressionInfo(f32.pop) = {"id":38,"type":3}
+getExpressionInfo(f64.pop) = {"id":38,"type":4}
+getExpressionInfo(v128.pop) = {"id":38,"type":5}
+getExpressionInfo(exnref.pop) = {"id":38,"type":7}
+getExpressionInfo(push) = {"id":37}
diff --git a/test/example/c-api-kitchen-sink.c b/test/example/c-api-kitchen-sink.c
index 3d9d42fa1..77349529b 100644
--- a/test/example/c-api-kitchen-sink.c
+++ b/test/example/c-api-kitchen-sink.c
@@ -520,6 +520,16 @@ void test_core() {
module, makeInt32(module, 2449), callOperands4b, 4, "iiIfF"),
// Exception handling
BinaryenTry(module, tryBody, catchBody),
+ // Atomics
+ BinaryenAtomicStore(module, 4, 0, temp6,
+ BinaryenAtomicLoad(module, 4, 0, BinaryenTypeInt32(), temp6),
+ BinaryenTypeInt32()
+ ),
+ BinaryenDrop(module,
+ BinaryenAtomicWait(module, temp6, temp6, temp16, BinaryenTypeInt32())
+ ),
+ BinaryenDrop(module, BinaryenAtomicNotify(module, temp6, temp6)),
+ BinaryenAtomicFence(module),
// TODO: Host
BinaryenNop(module),
@@ -565,7 +575,7 @@ void test_core() {
int8_t segmentPassive[] = { 0, 1 };
BinaryenExpressionRef segmentOffsets[] = { BinaryenConst(module, BinaryenLiteralInt32(10)), NULL };
BinaryenIndex segmentSizes[] = { 12, 12 };
- BinaryenSetMemory(module, 1, 256, "mem", segments, segmentPassive, segmentOffsets, segmentSizes, 2, 0);
+ BinaryenSetMemory(module, 1, 256, "mem", segments, segmentPassive, segmentOffsets, segmentSizes, 2, 1);
// Start function. One per module
diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt
index a46190fb4..a5c300653 100644
--- a/test/example/c-api-kitchen-sink.txt
+++ b/test/example/c-api-kitchen-sink.txt
@@ -27,7 +27,7 @@ BinaryenFeatureAll: 511
(type $v (func))
(type $4 (func))
(import "module" "base" (func $an-imported (param i32 f64) (result f32)))
- (memory $0 1 256)
+ (memory $0 (shared 1 256))
(data (i32.const 10) "hello, world")
(data passive "I am passive")
(table $0 1 1 funcref)
@@ -1414,6 +1414,26 @@ BinaryenFeatureAll: 511
)
)
)
+ (i32.atomic.store
+ (i32.const 0)
+ (i32.atomic.load
+ (i32.const 0)
+ )
+ )
+ (drop
+ (i32.atomic.wait
+ (i32.const 0)
+ (i32.const 0)
+ (i64.const 111)
+ )
+ )
+ (drop
+ (atomic.notify
+ (i32.const 0)
+ (i32.const 0)
+ )
+ )
+ (atomic.fence)
(nop)
(unreachable)
)
@@ -3310,8 +3330,15 @@ int main() {
expressions[658] = BinaryenReturnCallIndirect(the_module, expressions[657], operands, 4, "iiIfF");
}
expressions[659] = BinaryenTry(the_module, expressions[35], expressions[43]);
- expressions[660] = BinaryenNop(the_module);
- expressions[661] = BinaryenUnreachable(the_module);
+ expressions[660] = BinaryenAtomicLoad(the_module, 4, 0, 1, expressions[23]);
+ expressions[661] = BinaryenAtomicStore(the_module, 4, 0, expressions[23], expressions[660], 1);
+ expressions[662] = BinaryenAtomicWait(the_module, expressions[23], expressions[23], expressions[33], 1);
+ expressions[663] = BinaryenDrop(the_module, expressions[662]);
+ expressions[664] = BinaryenAtomicNotify(the_module, expressions[23], expressions[23]);
+ expressions[665] = BinaryenDrop(the_module, expressions[664]);
+ expressions[666] = BinaryenAtomicFence(the_module);
+ expressions[667] = BinaryenNop(the_module);
+ expressions[668] = BinaryenUnreachable(the_module);
BinaryenExpressionPrint(expressions[51]);
(f32.neg
(f32.const -33.61199951171875)
@@ -3358,27 +3385,27 @@ int main() {
expressions[627], expressions[629], expressions[632], expressions[635], expressions[637], expressions[639],
expressions[642], expressions[644], expressions[646], expressions[648], expressions[650], expressions[651],
expressions[652], expressions[653], expressions[655], expressions[656], expressions[658], expressions[659],
- expressions[660], expressions[661] };
- expressions[662] = BinaryenBlock(the_module, "the-value", children, 247, BinaryenTypeAuto());
+ expressions[661], expressions[663], expressions[665], expressions[666], expressions[667], expressions[668] };
+ expressions[669] = BinaryenBlock(the_module, "the-value", children, 251, BinaryenTypeAuto());
}
- expressions[663] = BinaryenDrop(the_module, expressions[662]);
+ expressions[670] = BinaryenDrop(the_module, expressions[669]);
{
- BinaryenExpressionRef children[] = { expressions[663] };
- expressions[664] = BinaryenBlock(the_module, "the-nothing", children, 1, BinaryenTypeAuto());
+ BinaryenExpressionRef children[] = { expressions[670] };
+ expressions[671] = BinaryenBlock(the_module, "the-nothing", children, 1, BinaryenTypeAuto());
}
- expressions[665] = BinaryenConst(the_module, BinaryenLiteralInt32(42));
+ expressions[672] = BinaryenConst(the_module, BinaryenLiteralInt32(42));
{
- BinaryenExpressionRef children[] = { expressions[664], expressions[665] };
- expressions[666] = BinaryenBlock(the_module, "the-body", children, 2, BinaryenTypeAuto());
+ BinaryenExpressionRef children[] = { expressions[671], expressions[672] };
+ expressions[673] = BinaryenBlock(the_module, "the-body", children, 2, BinaryenTypeAuto());
}
{
BinaryenType varTypes[] = { 1, 7 };
- functions[0] = BinaryenAddFunction(the_module, "kitchen()sinker", functionTypes[0], varTypes, 2, expressions[666]);
+ functions[0] = BinaryenAddFunction(the_module, "kitchen()sinker", functionTypes[0], varTypes, 2, expressions[673]);
}
- expressions[667] = BinaryenConst(the_module, BinaryenLiteralInt32(7));
- globals[0] = BinaryenAddGlobal(the_module, "a-global", 1, 0, expressions[667]);
- expressions[668] = BinaryenConst(the_module, BinaryenLiteralFloat32(7.5));
- globals[1] = BinaryenAddGlobal(the_module, "a-mutable-global", 3, 1, expressions[668]);
+ expressions[674] = BinaryenConst(the_module, BinaryenLiteralInt32(7));
+ globals[0] = BinaryenAddGlobal(the_module, "a-global", 1, 0, expressions[674]);
+ expressions[675] = BinaryenConst(the_module, BinaryenLiteralFloat32(7.5));
+ globals[1] = BinaryenAddGlobal(the_module, "a-mutable-global", 3, 1, expressions[675]);
{
BinaryenType paramTypes[] = { 1, 4 };
functionTypes[2] = BinaryenAddFunctionType(the_module, "fiF", 3, paramTypes, 2);
@@ -3390,24 +3417,24 @@ int main() {
const char* funcNames[] = { "kitchen()sinker" };
BinaryenSetFunctionTable(the_module, 1, 1, funcNames, 1);
}
- expressions[669] = BinaryenConst(the_module, BinaryenLiteralInt32(10));
+ expressions[676] = BinaryenConst(the_module, BinaryenLiteralInt32(10));
{
const char segment0[] = { 104, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100 };
const char segment1[] = { 73, 32, 97, 109, 32, 112, 97, 115, 115, 105, 118, 101 };
const char* segments[] = { segment0, segment1 };
int8_t segmentPassive[] = { 0, 1 };
- BinaryenExpressionRef segmentOffsets[] = { expressions[669], expressions[0] };
+ BinaryenExpressionRef segmentOffsets[] = { expressions[676], expressions[0] };
BinaryenIndex segmentSizes[] = { 12, 12 };
- BinaryenSetMemory(the_module, 1, 256, "mem", segments, segmentPassive, segmentOffsets, segmentSizes, 2, 0);
+ BinaryenSetMemory(the_module, 1, 256, "mem", segments, segmentPassive, segmentOffsets, segmentSizes, 2, 1);
}
{
BinaryenType paramTypes[] = { 0 };
functionTypes[3] = BinaryenAddFunctionType(the_module, "v", 0, paramTypes, 0);
}
- expressions[670] = BinaryenNop(the_module);
+ expressions[677] = BinaryenNop(the_module);
{
BinaryenType varTypes[] = { 0 };
- functions[1] = BinaryenAddFunction(the_module, "starter", functionTypes[3], varTypes, 0, expressions[670]);
+ functions[1] = BinaryenAddFunction(the_module, "starter", functionTypes[3], varTypes, 0, expressions[677]);
}
BinaryenSetStart(the_module, functions[1]);
{
@@ -3426,7 +3453,7 @@ int main() {
(type $v (func))
(type $4 (func))
(import "module" "base" (func $an-imported (param i32 f64) (result f32)))
- (memory $0 1 256)
+ (memory $0 (shared 1 256))
(data (i32.const 10) "hello, world")
(data passive "I am passive")
(table $0 1 1 funcref)
@@ -4813,6 +4840,26 @@ int main() {
)
)
)
+ (i32.atomic.store
+ (i32.const 0)
+ (i32.atomic.load
+ (i32.const 0)
+ )
+ )
+ (drop
+ (i32.atomic.wait
+ (i32.const 0)
+ (i32.const 0)
+ (i64.const 111)
+ )
+ )
+ (drop
+ (atomic.notify
+ (i32.const 0)
+ (i32.const 0)
+ )
+ )
+ (atomic.fence)
(nop)
(unreachable)
)
diff --git a/test/example/c-api-kitchen-sink.txt.txt b/test/example/c-api-kitchen-sink.txt.txt
index 181b16718..792656d96 100644
--- a/test/example/c-api-kitchen-sink.txt.txt
+++ b/test/example/c-api-kitchen-sink.txt.txt
@@ -8,7 +8,7 @@
(type $v (func))
(type $4 (func))
(import "module" "base" (func $an-imported (param i32 f64) (result f32)))
- (memory $0 1 256)
+ (memory $0 (shared 1 256))
(data (i32.const 10) "hello, world")
(data passive "I am passive")
(table $0 1 1 funcref)
@@ -1395,6 +1395,26 @@
)
)
)
+ (i32.atomic.store
+ (i32.const 0)
+ (i32.atomic.load
+ (i32.const 0)
+ )
+ )
+ (drop
+ (i32.atomic.wait
+ (i32.const 0)
+ (i32.const 0)
+ (i64.const 111)
+ )
+ )
+ (drop
+ (atomic.notify
+ (i32.const 0)
+ (i32.const 0)
+ )
+ )
+ (atomic.fence)
(nop)
(unreachable)
)
diff --git a/test/passes/translate-to-fuzz_all-features.txt b/test/passes/translate-to-fuzz_all-features.txt
index efbe0c232..a0481ba60 100644
--- a/test/passes/translate-to-fuzz_all-features.txt
+++ b/test/passes/translate-to-fuzz_all-features.txt
@@ -9,10 +9,9 @@
(import "fuzzing-support" "log-i64" (func $log-i64 (param i64)))
(import "fuzzing-support" "log-f32" (func $log-f32 (param f32)))
(import "fuzzing-support" "log-f64" (func $log-f64 (param f64)))
- (memory $0 (shared 1 1))
+ (memory $0 1 1)
(data (i32.const 0) "N\0fN\f5\f9\b1\ff\fa\eb\e5\fe\a7\ec\fb\fc\f4\a6\e4\ea\f0\ae\e3")
- (table $0 3 3 funcref)
- (elem (i32.const 0) $func_5 $func_5 $func_5)
+ (table $0 0 funcref)
(global $global$0 (mut i32) (i32.const 975663930))
(global $global$1 (mut i32) (i32.const 2066300474))
(global $global$2 (mut i64) (i64.const 20510))
@@ -276,341 +275,20 @@
)
(block $label$0
(br_if $label$0
- (i32.const 1376786182)
- )
- (local.set $4
- (v128.const i32x4 0x0e0a0e0d 0x0709060c 0x764b6f6f 0x00040000)
- )
- (local.set $4
- (if (result v128)
- (i32.eqz
- (if (result i32)
- (if (result i32)
- (i32.eqz
- (if (result i32)
- (i32.eqz
- (if
- (i32.const 1329942351)
- (local.tee $2
- (local.tee $2
- (loop $label$38
- (block
- (if
- (i32.eqz
- (global.get $hangLimit)
- )
- (return)
- )
- (global.set $hangLimit
- (i32.sub
- (global.get $hangLimit)
- (i32.const 1)
- )
- )
- )
- (if
- (i32.eqz
- (local.get $2)
- )
- (block $label$39
- (nop)
- (br $label$0)
- )
- (block $label$40
- (local.set $4
- (v128.const i32x4 0x05050505 0x46190000 0xc6800000 0x4a031a19)
- )
- (br $label$0)
- )
- )
- )
- )
- )
- (block $label$41
- (nop)
- (br $label$0)
- )
- )
- )
- (local.get $2)
- (local.get $2)
- )
- )
- (block $label$47
- (local.set $2
- (local.get $2)
- )
- (br $label$0)
- )
- (block $label$48 (result i32)
- (loop $label$49
- (block
- (if
- (i32.eqz
- (global.get $hangLimit)
- )
- (return)
- )
- (global.set $hangLimit
- (i32.sub
- (global.get $hangLimit)
- (i32.const 1)
- )
- )
- )
- (block
- (local.set $5
- (f32.const 9.625223197211503e-38)
- )
- (br_if $label$49
- (if (result i32)
- (block $label$57
- (local.set $5
- (local.tee $5
- (block $label$58 (result f32)
- (local.set $4
- (local.get $4)
- )
- (local.get $5)
- )
- )
- )
- (br $label$0)
- )
- (if (result i32)
- (i32.const 1376786182)
- (block $label$60
- (if
- (block $label$61 (result i32)
- (i32.const 925442358)
- )
- (block $label$62
- (br_if $label$62
- (i32.const 256)
- )
- )
- (block $label$63
- (if
- (local.get $2)
- (local.set $1
- (local.get $1)
- )
- (block $label$67
- (if
- (i32.eqz
- (i32.const 0)
- )
- (block $label$68
- (local.set $1
- (local.get $1)
- )
- (block $label$69
- (nop)
- (local.set $4
- (local.get $4)
- )
- )
- )
- (if
- (i32.eqz
- (br_if $label$48
- (i32.const 32768)
- (local.get $2)
- )
- )
- (local.set $4
- (v128.const i32x4 0xffffff81 0xffffffeb 0x80000000 0x74273131)
- )
- (local.set $2
- (local.get $2)
- )
- )
- )
- (local.set $0
- (i64.const -2097152)
- )
- )
- )
- (local.set $1
- (local.get $1)
- )
- )
- )
- (br $label$0)
- )
- (block $label$70 (result i32)
- (loop $label$71 (result i32)
- (block
- (if
- (i32.eqz
- (global.get $hangLimit)
- )
- (return)
- )
- (global.set $hangLimit
- (i32.sub
- (global.get $hangLimit)
- (i32.const 1)
- )
- )
- )
- (block (result i32)
- (loop $label$72
- (block
- (if
- (i32.eqz
- (global.get $hangLimit)
- )
- (return)
- )
- (global.set $hangLimit
- (i32.sub
- (global.get $hangLimit)
- (i32.const 1)
- )
- )
- )
- (local.set $4
- (local.tee $4
- (local.get $4)
- )
- )
- )
- (br_if $label$71
- (i32.eqz
- (loop $label$73
- (block
- (if
- (i32.eqz
- (global.get $hangLimit)
- )
- (return)
- )
- (global.set $hangLimit
- (i32.sub
- (global.get $hangLimit)
- (i32.const 1)
- )
- )
- )
- (block $label$74
- (local.set $4
- (v128.const i32x4 0xf8f8ff00 0x000000a5 0x0000000e 0xffff00ff)
- )
- (br $label$73)
- )
- )
- )
- )
- (i32.const -131072)
- )
- )
- )
- )
- (if (result i32)
- (local.get $2)
- (block $label$75
- (call $log-i32
- (local.tee $2
- (i32.const 5)
- )
- )
- (br $label$49)
- )
- (block $label$76 (result i32)
- (nop)
- (local.tee $2
- (i32.const 1276448839)
- )
- )
- )
- )
- )
- (local.set $2
- (local.get $2)
- )
- )
- )
- (loop $label$90
- (block
- (if
- (i32.eqz
- (global.get $hangLimit)
- )
- (return)
- )
- (global.set $hangLimit
- (i32.sub
- (global.get $hangLimit)
- (i32.const 1)
- )
- )
- )
- (block
- (local.set $1
- (local.get $1)
- )
- (br_if $label$90
- (i32.eqz
- (local.tee $2
- (i32.const -93)
- )
- )
- )
- (nop)
- )
- )
- (local.get $2)
- )
- )
- (block $label$91 (result i32)
- (local.set $5
- (block $label$92 (result f32)
- (local.set $1
- (loop $label$19 (result f64)
- (block
- (if
- (i32.eqz
- (global.get $hangLimit)
- )
- (return)
- )
- (global.set $hangLimit
- (i32.sub
- (global.get $hangLimit)
- (i32.const 1)
- )
- )
- )
- (block (result f64)
- (nop)
- (br_if $label$19
- (i32.eqz
- (i32.const -129)
- )
- )
- (local.tee $1
- (f64.const -nan:0xffffffffffff0)
- )
- )
- )
- )
- (local.get $5)
- )
- )
- (local.get $2)
- )
- (block $label$95 (result i32)
- (local.get $2)
+ (i32.eqz
+ (local.tee $2
+ (local.tee $2
+ (local.tee $2
+ (i32.const 512)
)
)
)
- (local.get $4)
- (block $label$96 (result v128)
- (v128.const i32x4 0x80800000 0xdf800000 0xcf000000 0x4f800000)
- )
)
)
+ (local.set $4
+ (v128.const i32x4 0x0e0a0e0d 0x0709060c 0x764b6f6f 0x00040000)
+ )
+ (nop)
)
)
(func $hangLimitInitializer (; 6 ;)
diff --git a/test/passes/translate-to-fuzz_no-fuzz-nans_all-features.txt b/test/passes/translate-to-fuzz_no-fuzz-nans_all-features.txt
index ba8dec2d4..91ed6ceca 100644
--- a/test/passes/translate-to-fuzz_no-fuzz-nans_all-features.txt
+++ b/test/passes/translate-to-fuzz_no-fuzz-nans_all-features.txt
@@ -9,7 +9,7 @@
(import "fuzzing-support" "log-i64" (func $log-i64 (param i64)))
(import "fuzzing-support" "log-f32" (func $log-f32 (param f32)))
(import "fuzzing-support" "log-f64" (func $log-f64 (param f64)))
- (memory $0 (shared 1 1))
+ (memory $0 1 1)
(data (i32.const 0) "N\0fN\f5\f9\b1\ff\fa\eb\e5\fe\a7\ec\fb\fc\f4\a6\e4\ea\f0\ae\e3")
(table $0 0 funcref)
(global $global$0 (mut i32) (i32.const 975663930))
@@ -20,6 +20,7 @@
(event $event$0 (attr 0) (param i32 f32 i32 f64 i32))
(export "hashMemory" (func $hashMemory))
(export "memory" (memory $0))
+ (export "func_5" (func $func_5))
(export "hangLimitInitializer" (func $hangLimitInitializer))
(func $hashMemory (; 4 ;) (type $FUNCSIG$i) (result i32)
(local $0 i32)
@@ -252,7 +253,7 @@
)
(local.get $0)
)
- (func $func_5 (; 5 ;) (param $0 i64)
+ (func $func_5 (; 5 ;) (type $FUNCSIG$vj) (param $0 i64)
(local $1 f64)
(local $2 i32)
(local $3 i64)
@@ -293,235 +294,306 @@
(if (result v128)
(i32.eqz
(if (result i32)
- (if (result i32)
- (i32.eqz
- (if (result i32)
- (i32.eqz
- (if
- (i32.eqz
- (if (result i32)
- (i32.eqz
- (if (result i32)
- (i32.eqz
- (if (result i32)
- (local.get $2)
- (loop $label$1 (result i32)
- (block
- (if
- (i32.eqz
- (global.get $hangLimit)
- )
- (return)
- )
- (global.set $hangLimit
- (i32.sub
- (global.get $hangLimit)
- (i32.const 1)
- )
+ (i32.eqz
+ (if (result i32)
+ (i32.eqz
+ (if (result i32)
+ (if (result i32)
+ (if (result i32)
+ (i32.eqz
+ (if
+ (i32.eqz
+ (if (result i32)
+ (local.get $2)
+ (loop $label$1 (result i32)
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
)
+ (return)
)
- (block (result i32)
- (block $label$2
- (local.set $3
- (i64.const 15662)
- )
- (local.set $2
- (local.get $2)
- )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
)
- (br_if $label$1
- (local.get $2)
+ )
+ )
+ (block (result i32)
+ (block $label$2
+ (local.set $3
+ (i64.const 15662)
)
- (if (result i32)
- (i32.eqz
- (local.get $2)
+ (local.set $2
+ (local.tee $2
+ (i32.const 1010006831)
)
- (local.get $2)
+ )
+ )
+ (br_if $label$1
+ (local.get $2)
+ )
+ (if (result i32)
+ (i32.eqz
(local.get $2)
)
+ (local.get $2)
+ (local.get $2)
)
)
- (block $label$3 (result i32)
- (local.tee $2
- (i32.const 286267661)
- )
+ )
+ (block $label$3 (result i32)
+ (local.tee $2
+ (i32.const 286267661)
)
)
)
- (block $label$4
- (loop $label$5
- (block
- (if
- (i32.eqz
- (global.get $hangLimit)
- )
- (return)
+ )
+ (block $label$4
+ (loop $label$5
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
)
- (global.set $hangLimit
- (i32.sub
- (global.get $hangLimit)
- (i32.const 1)
- )
+ (return)
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
)
)
- (block
- (block $label$6
- (if
- (i32.eqz
- (loop $label$7 (result i32)
- (block
- (if
- (i32.eqz
- (global.get $hangLimit)
- )
- (return)
+ )
+ (block
+ (block $label$6
+ (if
+ (i32.eqz
+ (loop $label$7 (result i32)
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
)
- (global.set $hangLimit
- (i32.sub
- (global.get $hangLimit)
- (i32.const 1)
- )
+ (return)
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
)
)
- (i32.const 6506)
)
- )
- (block $label$8
- (local.set $2
- (local.tee $2
- (local.get $2)
+ (block (result i32)
+ (local.set $1
+ (f64.const -131072)
+ )
+ (br_if $label$7
+ (i32.const 387334656)
)
+ (local.get $2)
)
- (local.set $5
- (local.get $5)
+ )
+ )
+ (block $label$8
+ (local.set $2
+ (local.tee $2
+ (local.get $2)
)
)
- (block $label$9
- (if
- (local.tee $2
- (if (result i32)
- (local.get $2)
- (local.get $2)
- (loop $label$10 (result i32)
- (block
- (if
- (i32.eqz
- (global.get $hangLimit)
- )
- (return)
+ (local.set $5
+ (local.get $5)
+ )
+ )
+ (block $label$9
+ (if
+ (local.tee $2
+ (if (result i32)
+ (i32.const 1899592761)
+ (local.get $2)
+ (loop $label$10 (result i32)
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
)
- (global.set $hangLimit
- (i32.sub
- (global.get $hangLimit)
- (i32.const 1)
- )
+ (return)
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
)
)
- (block (result i32)
- (nop)
- (br_if $label$10
- (i32.eqz
- (i32.const 64)
- )
+ )
+ (block (result i32)
+ (nop)
+ (br_if $label$10
+ (i32.eqz
+ (i32.const 64)
)
- (local.tee $2
- (loop $label$11 (result i32)
- (block
- (if
- (i32.eqz
- (global.get $hangLimit)
- )
- (return)
+ )
+ (local.tee $2
+ (loop $label$11 (result i32)
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
)
- (global.set $hangLimit
- (i32.sub
- (global.get $hangLimit)
- (i32.const 1)
- )
+ (return)
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
)
)
- (i32.const 512)
)
+ (i32.const 512)
)
)
)
)
)
- (local.set $3
- (local.get $3)
- )
- (loop $label$12
- (block
- (if
- (i32.eqz
- (global.get $hangLimit)
- )
- (return)
- )
- (global.set $hangLimit
- (i32.sub
- (global.get $hangLimit)
- (i32.const 1)
- )
+ )
+ (local.set $3
+ (local.get $3)
+ )
+ (loop $label$12
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
)
+ (return)
)
- (local.set $1
- (local.get $1)
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
)
)
- )
- (local.set $2
- (i32.const 170)
+ (local.set $1
+ (local.get $1)
+ )
)
)
- )
- (call $log-i32
- (local.get $2)
+ (local.set $2
+ (i32.const 170)
+ )
)
)
- (br_if $label$5
- (i32.eqz
- (i32.const 2376257)
- )
+ (call $log-i32
+ (i32.const 0)
)
- (local.set $4
- (local.tee $4
- (v128.const i32x4 0xfff70000 0x007f700e 0x07420400 0x8000007f)
- )
+ )
+ (br_if $label$5
+ (i32.eqz
+ (i32.const 2376257)
+ )
+ )
+ (local.set $4
+ (local.tee $4
+ (v128.const i32x4 0xfff70000 0x007f700e 0x07420400 0x8000007f)
)
)
)
- (block $label$13
- (if
- (i32.eqz
- (block $label$14 (result i32)
- (local.set $4
- (v128.const i32x4 0x80000000 0x00000080 0xfffffffc 0x00007fff)
- )
- (i32.const -123)
+ )
+ (block $label$13
+ (if
+ (i32.eqz
+ (block $label$14 (result i32)
+ (local.set $4
+ (v128.const i32x4 0x80000000 0x00000080 0xfffffffc 0x00007fff)
)
+ (i32.const -123)
)
- (local.set $1
- (local.get $1)
+ )
+ (block $label$15
+ (local.set $4
+ (v128.const i32x4 0x00200000 0xc1e00000 0x00000000 0xc3e00000)
)
- (local.set $5
- (local.get $5)
+ (local.set $4
+ (v128.const i32x4 0x01ef00e4 0x7009efff 0x53000c13 0x0000153a)
+ )
+ )
+ (block $label$16
+ (if
+ (local.get $2)
+ (local.set $0
+ (local.tee $3
+ (local.get $3)
+ )
+ )
+ (if
+ (i32.eqz
+ (local.get $2)
+ )
+ (local.set $5
+ (f32.const 12732744)
+ )
+ (local.set $0
+ (local.get $3)
+ )
+ )
)
)
- (br $label$0)
)
+ (br $label$0)
)
- (block $label$17 (result i32)
- (i64.atomic.store offset=3
- (i32.const 640629291)
- (local.tee $0
- (i64.const -16)
- )
+ )
+ (block $label$17
+ (if
+ (i32.eqz
+ (local.get $2)
)
- (if (result i32)
- (block $label$18
- (local.set $1
- (loop $label$19 (result f64)
+ (block $label$18
+ (if
+ (local.tee $2
+ (i32.const 127)
+ )
+ (block $label$19
+ (local.set $4
+ (v128.const i32x4 0x0000001b 0x00000014 0x161b00bf 0x00402000)
+ )
+ (local.set $1
+ (f64.const 0)
+ )
+ )
+ (block $label$20
+ (local.set $3
+ (i64.const -67108864)
+ )
+ (local.set $5
+ (local.get $5)
+ )
+ )
+ )
+ (loop $label$21
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return)
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (block
+ (local.set $4
+ (local.get $4)
+ )
+ (br_if $label$21
+ (i32.const 85)
+ )
+ (loop $label$22
(block
(if
(i32.eqz
@@ -536,61 +608,113 @@
)
)
)
- (block (result f64)
- (nop)
- (br_if $label$19
+ (block
+ (local.set $1
+ (local.get $1)
+ )
+ (br_if $label$22
(i32.eqz
- (local.get $2)
+ (block $label$23
+ (nop)
+ (br $label$21)
+ )
)
)
- (local.tee $1
- (f64.const 0)
- )
+ (nop)
)
)
)
- (return)
)
- (local.tee $2
- (local.get $2)
+ )
+ (block $label$24
+ (loop $label$25
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return)
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (block
+ (local.set $0
+ (local.get $0)
+ )
+ (br_if $label$25
+ (i32.const -67108864)
+ )
+ (local.set $5
+ (local.get $5)
+ )
+ )
)
- (block $label$20
- (loop $label$21
- (block
- (if
- (i32.eqz
- (global.get $hangLimit)
- )
- (return)
+ (loop $label$26
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
)
- (global.set $hangLimit
- (i32.sub
- (global.get $hangLimit)
- (i32.const 1)
+ (return)
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (block
+ (local.set $3
+ (i64.const 128)
+ )
+ (br_if $label$26
+ (block $label$27 (result i32)
+ (local.set $4
+ (v128.const i32x4 0x01010101 0x00000000 0x00000059 0x00000000)
)
+ (local.get $2)
)
)
- (local.set $1
- (local.get $1)
+ (local.set $3
+ (loop $label$28 (result i64)
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return)
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (i64.const 246)
+ )
)
)
- (return)
)
)
)
+ (br $label$0)
)
)
- (block $label$22 (result i32)
- (local.set $5
- (f32.const 10160664)
- )
- (if (result i32)
+ )
+ (i32.const -31)
+ (block $label$29 (result i32)
+ (local.tee $3
+ (if
(i32.eqz
- (i32.const 0)
- )
- (block $label$23
- (local.set $1
- (loop $label$24 (result f64)
+ (br_if $label$29
+ (loop $label$30 (result i32)
(block
(if
(i32.eqz
@@ -605,52 +729,133 @@
)
)
)
- (block (result f64)
- (local.set $3
- (local.get $0)
+ (block (result i32)
+ (local.set $5
+ (f32.const 49)
)
- (br_if $label$24
- (i32.const -9)
+ (br_if $label$30
+ (local.get $2)
)
- (f64.const -18446744073709551615)
+ (local.get $2)
)
)
+ (local.tee $2
+ (i32.const 342496264)
+ )
)
- (br $label$0)
)
- (block $label$25 (result i32)
- (loop $label$26
- (block
- (if
- (i32.eqz
- (global.get $hangLimit)
- )
- (return)
+ (block $label$32
+ (call $log-i32
+ (call $hashMemory)
+ )
+ (block
+ (block $label$33
+ (local.set $3
+ (i64.const -65535)
)
- (global.set $hangLimit
- (i32.sub
- (global.get $hangLimit)
- (i32.const 1)
- )
+ (br $label$0)
+ )
+ (drop
+ (local.get $2)
+ )
+ )
+ )
+ (if
+ (i32.const -32768)
+ (block $label$34
+ (br $label$0)
+ )
+ (block $label$35
+ (block $label$36
+ (local.set $3
+ (local.get $3)
+ )
+ (local.set $4
+ (local.get $4)
)
)
- (block
- (local.set $2
- (local.get $2)
+ (br $label$0)
+ )
+ )
+ )
+ )
+ (local.get $2)
+ )
+ )
+ (block $label$37 (result i32)
+ (loop $label$38
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return)
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (block
+ (block $label$39
+ (local.set $5
+ (f32.const 1.1754943508222875e-38)
+ )
+ (local.set $2
+ (i32.const -65535)
+ )
+ )
+ (br_if $label$38
+ (loop $label$40 (result i32)
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
)
- (br_if $label$26
- (i32.eqz
- (if (result i32)
- (br_if $label$25
- (i32.const -8)
- (local.get $2)
+ (return)
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (block (result i32)
+ (block $label$41
+ (local.set $0
+ (local.tee $3
+ (local.tee $3
+ (local.get $0)
+ )
+ )
+ )
+ (call $log-i32
+ (call $hashMemory)
+ )
+ )
+ (br_if $label$40
+ (loop $label$42 (result i32)
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
)
- (local.get $2)
- (block $label$29 (result i32)
- (call $log-i32
- (call $hashMemory)
- )
- (loop $label$30 (result i32)
+ (return)
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (block (result i32)
+ (block $label$43
+ (local.set $4
+ (loop $label$44 (result v128)
(block
(if
(i32.eqz
@@ -665,67 +870,394 @@
)
)
)
- (local.get $2)
+ (v128.const i32x4 0x00000000 0x40d1c680 0xffffffff 0xffefffff)
+ )
+ )
+ (nop)
+ )
+ (br_if $label$42
+ (loop $label$45
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return)
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (block
+ (local.set $5
+ (local.get $5)
+ )
+ (br_if $label$45
+ (i32.const 101975070)
+ )
+ (block $label$46
+ (br $label$45)
+ )
)
)
)
+ (local.tee $2
+ (i32.const 32768)
+ )
)
)
- (local.set $5
+ )
+ (local.get $2)
+ )
+ )
+ )
+ (loop $label$47
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return)
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (block
+ (drop
+ (v128.const i32x4 0x0000007f 0x00000000 0x372e2e2e 0x35373022)
+ )
+ (br_if $label$47
+ (i32.eqz
+ (local.get $2)
+ )
+ )
+ (local.set $5
+ (local.tee $5
+ (if (result f32)
+ (local.get $2)
+ (f32.const -8)
(local.get $5)
)
)
)
- (local.get $2)
)
)
)
- (block $label$35
- (local.set $1
- (f64.const 1414944843)
- )
- (br $label$0)
- )
)
- )
- (local.tee $2
(local.tee $2
- (loop $label$38
- (block
- (if
- (i32.eqz
- (global.get $hangLimit)
+ (local.tee $2
+ (local.tee $2
+ (local.tee $2
+ (local.tee $2
+ (local.get $2)
)
- (return)
)
- (global.set $hangLimit
- (i32.sub
- (global.get $hangLimit)
- (i32.const 1)
+ )
+ )
+ )
+ )
+ (block $label$48
+ (local.set $5
+ (local.tee $5
+ (local.tee $5
+ (block $label$49 (result f32)
+ (local.set $4
+ (local.get $4)
)
+ (local.get $5)
)
)
- (if
+ )
+ )
+ (br $label$0)
+ )
+ )
+ (block $label$50 (result i32)
+ (if
+ (i32.eqz
+ (i32.const 2097152)
+ )
+ (if
+ (i32.eqz
+ (if (result i32)
(i32.eqz
- (local.get $2)
+ (loop $label$51 (result i32)
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return)
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (block (result i32)
+ (block $label$52
+ (local.set $5
+ (local.tee $5
+ (local.get $5)
+ )
+ )
+ (local.set $0
+ (i64.const 128)
+ )
+ )
+ (br_if $label$51
+ (i32.const 2)
+ )
+ (i32.const 1667136122)
+ )
+ )
)
- (block $label$39
- (nop)
+ (block $label$53
+ (drop
+ (if (result f32)
+ (i32.eqz
+ (if (result i32)
+ (i32.eqz
+ (local.tee $2
+ (br_if $label$50
+ (local.get $2)
+ (local.get $2)
+ )
+ )
+ )
+ (br_if $label$50
+ (local.get $2)
+ (i32.const 8192)
+ )
+ (local.get $2)
+ )
+ )
+ (block $label$54 (result f32)
+ (local.set $4
+ (v128.const i32x4 0x040f1919 0x00800000 0x4a000000 0x00000000)
+ )
+ (local.tee $5
+ (f32.const 1.1754943508222875e-38)
+ )
+ )
+ (if (result f32)
+ (loop $label$55 (result i32)
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return)
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (local.tee $2
+ (local.tee $2
+ (i32.const 470239259)
+ )
+ )
+ )
+ (local.get $5)
+ (f32.const 20288)
+ )
+ )
+ )
(br $label$0)
)
- (block $label$40
- (local.set $1
- (local.get $1)
+ (block $label$56 (result i32)
+ (br_if $label$0
+ (i32.eqz
+ (br_if $label$56
+ (i32.const 4096)
+ (i32.const 1048576)
+ )
+ )
)
(br $label$0)
)
)
)
+ (block $label$57
+ (block $label$58
+ (local.set $0
+ (local.tee $0
+ (local.get $3)
+ )
+ )
+ (loop $label$59
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return)
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (block
+ (block $label$60
+ (local.set $5
+ (f32.const 1.7096404532038735e-33)
+ )
+ (data.drop 0)
+ )
+ (br_if $label$59
+ (i32.eqz
+ (i32.const 235539981)
+ )
+ )
+ (local.set $5
+ (local.tee $5
+ (f32.const 1364283776)
+ )
+ )
+ )
+ )
+ )
+ (block $label$61
+ (local.set $4
+ (v128.const i32x4 0x21474459 0xff7fffff 0x4cc3ca60 0x4b800000)
+ )
+ (local.set $2
+ (i32.const 32767)
+ )
+ )
+ )
+ (block $label$62
+ (local.set $2
+ (if (result i32)
+ (loop $label$63 (result i32)
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return)
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (block (result i32)
+ (block $label$64
+ (if
+ (local.get $2)
+ (nop)
+ (nop)
+ )
+ (block $label$65
+ (local.set $0
+ (local.get $0)
+ )
+ (local.set $2
+ (local.get $2)
+ )
+ )
+ )
+ (br_if $label$63
+ (br_if $label$50
+ (local.get $2)
+ (i32.eqz
+ (local.get $2)
+ )
+ )
+ )
+ (local.get $2)
+ )
+ )
+ (br_if $label$50
+ (i32.const -86)
+ (i32.eqz
+ (if (result i32)
+ (i32.const -8192)
+ (i32.const 437327895)
+ (i32.const 32767)
+ )
+ )
+ )
+ (block $label$66
+ (local.set $4
+ (v128.const i32x4 0x00000070 0x31313113 0x0000780c 0xffff8000)
+ )
+ (loop $label$67
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return)
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (block $label$68
+ (local.set $4
+ (v128.const i32x4 0x657b077d 0x1113ff82 0x6c650000 0x0000fff8)
+ )
+ (br $label$62)
+ )
+ )
+ )
+ )
+ )
+ (local.set $5
+ (local.get $5)
+ )
+ )
+ )
+ (block $label$69
+ (local.set $1
+ (local.get $1)
+ )
+ (local.set $1
+ (local.get $1)
+ )
+ )
+ )
+ (local.tee $2
+ (local.tee $2
+ (local.tee $2
+ (local.tee $2
+ (local.tee $2
+ (local.tee $2
+ (i32.const 32)
+ )
+ )
+ )
+ )
)
)
- (block $label$41
- (memory.copy
- (loop $label$42 (result i32)
+ )
+ (block $label$70 (result i32)
+ (if
+ (i32.eqz
+ (loop $label$71 (result i32)
(block
(if
(i32.eqz
@@ -740,8 +1272,93 @@
)
)
)
- (if (result i32)
- (loop $label$43 (result i32)
+ (block (result i32)
+ (memory.fill
+ (i32.and
+ (if (result i32)
+ (f32.gt
+ (local.get $5)
+ (local.tee $5
+ (f32.const 504699424)
+ )
+ )
+ (block $label$72
+ (local.set $2
+ (i32.const -4)
+ )
+ (br $label$0)
+ )
+ (local.tee $2
+ (i32.const 825172795)
+ )
+ )
+ (i32.const 15)
+ )
+ (i32.and
+ (local.tee $2
+ (i32.const -32768)
+ )
+ (i32.const 15)
+ )
+ (block $label$73 (result i32)
+ (loop $label$74
+ (block
+ (if
+ (i32.eqz
+ (global.get $hangLimit)
+ )
+ (return)
+ )
+ (global.set $hangLimit
+ (i32.sub
+ (global.get $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (block
+ (block $label$75
+ (local.set $4
+ (local.get $4)
+ )
+ (br_if $label$71
+ (i32.const 359954033)
+ )
+ )
+ (br_if $label$74
+ (i32.eqz
+ (local.get $2)
+ )
+ )
+ (local.set $5
+ (local.get $5)
+ )
+ )
+ )
+ (i32.const -127)
+ )
+ )
+ (br_if $label$71
+ (i32.eqz
+ (i32.const 0)
+ )
+ )
+ (i32.const 0)
+ )
+ )
+ )
+ (block $label$76
+ (if
+ (i32.eqz
+ (block $label$77
+ (local.set $5
+ (local.get $5)
+ )
+ (br $label$0)
+ )
+ )
+ (br_if $label$76
+ (loop $label$78 (result i32)
(block
(if
(i32.eqz
@@ -756,119 +1373,128 @@
)
)
)
- (block $label$44 (result i32)
- (local.set $3
- (i64.const 2097574720517510216)
+ (block (result i32)
+ (local.tee $2
+ (block $label$79
+ (local.set $2
+ (local.tee $2
+ (i32.const 1196248392)
+ )
+ )
+ (br $label$76)
+ )
)
- (if (result i32)
+ (br_if $label$78
(i32.eqz
- (local.get $2)
- )
- (i32.const 1296450369)
- (local.tee $2
- (i32.const -14)
+ (i32.const 0)
)
)
+ (local.get $2)
+ )
+ )
+ )
+ (local.set $1
+ (local.tee $1
+ (f64.const -2147483648)
+ )
+ )
+ )
+ (local.set $4
+ (local.tee $4
+ (local.tee $4
+ (local.tee $4
+ (local.tee $4
+ (local.get $4)
+ )
)
)
- (block $label$45
- (local.set $2
- (i32.const 235407412)
+ )
+ )
+ )
+ (block $label$80
+ (block $label$81
+ (local.set $4
+ (local.tee $4
+ (local.tee $4
+ (v128.const i32x4 0x080f185d 0x46aca200 0x41800000 0x4b060a0c)
)
- (br $label$0)
)
- (block $label$46 (result i32)
- (local.set $2
- (local.tee $2
- (local.tee $2
- (local.tee $2
- (i32.const 1179009606)
+ )
+ (block $label$82
+ (if
+ (i32.eqz
+ (br_if $label$70
+ (br_if $label$70
+ (i32.const -65536)
+ (i32.eqz
+ (i32.const 757217343)
)
)
+ (i32.const -65535)
+ )
+ )
+ (local.set $3
+ (local.tee $0
+ (local.get $3)
)
)
- (i32.const 1073741824)
+ (block $label$83
+ (local.set $0
+ (if (result i64)
+ (local.get $2)
+ (block $label$84
+ (local.set $5
+ (f32.const 119)
+ )
+ (br $label$82)
+ )
+ (local.get $0)
+ )
+ )
+ (local.set $3
+ (block $label$85 (result i64)
+ (local.set $3
+ (i64.const -82)
+ )
+ (local.get $3)
+ )
+ )
+ )
+ )
+ (local.set $5
+ (local.get $5)
)
)
)
- (local.get $2)
- (i32.const 1073741824)
+ (local.set $5
+ (f32.const 10282366454988800)
+ )
)
- (return)
)
- )
- )
- (local.get $2)
- (local.get $2)
- )
- )
- (block $label$47
- (local.set $2
- (local.get $2)
- )
- (br $label$0)
- )
- (block $label$48 (result i32)
- (loop $label$49
- (block
- (if
- (i32.eqz
- (global.get $hangLimit)
- )
- (return)
- )
- (global.set $hangLimit
- (i32.sub
- (global.get $hangLimit)
- (i32.const 1)
- )
- )
- )
- (local.set $5
- (local.get $5)
- )
- )
- (loop $label$90
- (block
- (if
- (i32.eqz
- (global.get $hangLimit)
- )
- (return)
- )
- (global.set $hangLimit
- (i32.sub
- (global.get $hangLimit)
- (i32.const 1)
- )
- )
- )
- (block
- (local.set $1
- (local.get $1)
- )
- (local.set $2
(local.get $2)
)
- (nop)
)
)
(local.get $2)
- )
- )
- (block $label$91 (result i32)
- (local.set $5
- (block $label$92 (result f32)
- (f32.const 6)
+ (block $label$88 (result i32)
+ (i32.const -16)
)
)
+ )
+ (block $label$89 (result i32)
+ (local.get $2)
+ )
+ (block $label$90 (result i32)
(local.get $2)
)
- (local.get $2)
)
)
- (v128.const i32x4 0xffffffc0 0x00001f16 0x00008000 0x505c1a13)
- (v128.const i32x4 0xc7007b11 0x721d0901 0x01810043 0x441f1201)
+ (block $label$91 (result v128)
+ (v128.const i32x4 0x00000000 0x41600000 0x00000000 0x42400000)
+ )
+ (block $label$92 (result v128)
+ (v128.const i32x4 0x00000001 0x00001d6e 0x4f0affed 0x00020054)
+ )
)
)
)
diff --git a/test/spec/atomics.wast b/test/spec/atomics.wast
new file mode 100644
index 000000000..4e6dd3563
--- /dev/null
+++ b/test/spec/atomics.wast
@@ -0,0 +1,8 @@
+(module
+ (memory $0 (shared 23 256))
+ (func (export "atomic-fence")
+ (atomic.fence)
+ )
+)
+
+(assert_return (invoke "atomic-fence"))