Skip to content

Commit

Permalink
Add support for atomic.fence from the threads proposal
Browse files Browse the repository at this point in the history
See WebAssembly/threads#141 for the binary
encoding.  This patch does add a field to AtomicFenceExpr for the
consistency model, though without a type for the time being.
  • Loading branch information
wingo committed Nov 18, 2019
1 parent 8b554c8 commit 72d1fae
Show file tree
Hide file tree
Showing 27 changed files with 613 additions and 510 deletions.
29 changes: 17 additions & 12 deletions src/binary-reader-ir.cc
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,13 @@ class BinaryReaderIR : public BinaryReaderNop {
Result OnAtomicRmwCmpxchgExpr(Opcode opcode,
uint32_t alignment_log2,
Address offset) override;
wabt::Result OnAtomicWaitExpr(Opcode opcode,
uint32_t alignment_log2,
Address offset) override;
wabt::Result OnAtomicNotifyExpr(Opcode opcode,
uint32_t alignment_log2,
Address offset) override;
Result OnAtomicWaitExpr(Opcode opcode,
uint32_t alignment_log2,
Address offset) override;
Result OnAtomicFenceExpr(uint32_t consistency_model) override;
Result OnAtomicNotifyExpr(Opcode opcode,
uint32_t alignment_log2,
Address offset) override;
Result OnBinaryExpr(Opcode opcode) override;
Result OnBlockExpr(Type sig_type) override;
Result OnBrExpr(Index depth) override;
Expand Down Expand Up @@ -632,16 +633,20 @@ Result BinaryReaderIR::OnAtomicRmwCmpxchgExpr(Opcode opcode,
MakeUnique<AtomicRmwCmpxchgExpr>(opcode, 1 << alignment_log2, offset));
}

wabt::Result BinaryReaderIR::OnAtomicWaitExpr(Opcode opcode,
uint32_t alignment_log2,
Address offset) {
Result BinaryReaderIR::OnAtomicWaitExpr(Opcode opcode,
uint32_t alignment_log2,
Address offset) {
return AppendExpr(
MakeUnique<AtomicWaitExpr>(opcode, 1 << alignment_log2, offset));
}

wabt::Result BinaryReaderIR::OnAtomicNotifyExpr(Opcode opcode,
uint32_t alignment_log2,
Address offset) {
Result BinaryReaderIR::OnAtomicFenceExpr(uint32_t consistency_model) {
return AppendExpr(MakeUnique<AtomicFenceExpr>(consistency_model));
}

Result BinaryReaderIR::OnAtomicNotifyExpr(Opcode opcode,
uint32_t alignment_log2,
Address offset) {
return AppendExpr(
MakeUnique<AtomicNotifyExpr>(opcode, 1 << alignment_log2, offset));
}
Expand Down
1 change: 1 addition & 0 deletions src/binary-reader-logging.cc
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,7 @@ DEFINE_LOAD_STORE_OPCODE(OnAtomicRmwExpr);
DEFINE_LOAD_STORE_OPCODE(OnAtomicRmwCmpxchgExpr);
DEFINE_LOAD_STORE_OPCODE(OnAtomicStoreExpr);
DEFINE_LOAD_STORE_OPCODE(OnAtomicWaitExpr);
DEFINE_INDEX_DESC(OnAtomicFenceExpr, "consistency_model");
DEFINE_LOAD_STORE_OPCODE(OnAtomicNotifyExpr);
DEFINE_INDEX_INDEX(OnBrOnExnExpr, "depth", "event_index");
DEFINE_OPCODE(OnBinaryExpr)
Expand Down
1 change: 1 addition & 0 deletions src/binary-reader-logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ class BinaryReaderLogging : public BinaryReaderDelegate {
Result OnAtomicWaitExpr(Opcode opcode,
uint32_t alignment_log2,
Address offset) override;
Result OnAtomicFenceExpr(uint32_t consistency_model) override;
Result OnAtomicNotifyExpr(Opcode opcode,
uint32_t alignment_log2,
Address offset) override;
Expand Down
3 changes: 3 additions & 0 deletions src/binary-reader-nop.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,9 @@ class BinaryReaderNop : public BinaryReaderDelegate {
Result OnAtomicWaitExpr(Opcode, uint32_t, Address) override {
return Result::Ok;
}
Result OnAtomicFenceExpr(uint32_t) override {
return Result::Ok;
}
Result OnAtomicNotifyExpr(Opcode, uint32_t, Address) override {
return Result::Ok;
}
Expand Down
10 changes: 10 additions & 0 deletions src/binary-reader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1285,6 +1285,16 @@ Result BinaryReader::ReadFunctionBody(Offset end_offset) {
break;
}

case Opcode::AtomicFence: {
uint8_t consistency_model;
CHECK_RESULT(ReadU8(&consistency_model, "consistency model"));
ERROR_UNLESS(consistency_model == 0,
"atomic.fence consistency model must be 0");
CALLBACK(OnAtomicFenceExpr, consistency_model);
CALLBACK(OnOpcodeUint32, consistency_model);
break;
}

case Opcode::I32AtomicLoad8U:
case Opcode::I32AtomicLoad16U:
case Opcode::I64AtomicLoad8U:
Expand Down
1 change: 1 addition & 0 deletions src/binary-reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ class BinaryReaderDelegate {
virtual Result OnAtomicWaitExpr(Opcode opcode,
uint32_t alignment_log2,
Address offset) = 0;
virtual Result OnAtomicFenceExpr(uint32_t consistency_model) = 0;
virtual Result OnAtomicNotifyExpr(Opcode opcode,
uint32_t alignment_log2,
Address offset) = 0;
Expand Down
7 changes: 7 additions & 0 deletions src/binary-writer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,13 @@ void BinaryWriter::WriteExpr(const Func* func, const Expr* expr) {
case ExprType::AtomicWait:
WriteLoadStoreExpr<AtomicWaitExpr>(func, expr, "memory offset");
break;
case ExprType::AtomicFence: {
auto* fence_expr = cast<AtomicFenceExpr>(expr);
WriteOpcode(stream_, Opcode::AtomicFence);
WriteU32Leb128(stream_, fence_expr->consistency_model,
"consistency model");
break;
}
case ExprType::AtomicNotify:
WriteLoadStoreExpr<AtomicNotifyExpr>(func, expr, "memory offset");
break;
Expand Down
1 change: 1 addition & 0 deletions src/c-writer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1671,6 +1671,7 @@ void CWriter::Write(const ExprList& exprs) {
case ExprType::AtomicRmwCmpxchg:
case ExprType::AtomicStore:
case ExprType::AtomicWait:
case ExprType::AtomicFence:
case ExprType::AtomicNotify:
case ExprType::BrOnExn:
case ExprType::Rethrow:
Expand Down
4 changes: 4 additions & 0 deletions src/expr-visitor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,10 @@ Result ExprVisitor::HandleDefaultState(Expr* expr) {
CHECK_RESULT(delegate_->OnAtomicWaitExpr(cast<AtomicWaitExpr>(expr)));
break;

case ExprType::AtomicFence:
CHECK_RESULT(delegate_->OnAtomicFenceExpr(cast<AtomicFenceExpr>(expr)));
break;

case ExprType::AtomicNotify:
CHECK_RESULT(delegate_->OnAtomicNotifyExpr(cast<AtomicNotifyExpr>(expr)));
break;
Expand Down
2 changes: 2 additions & 0 deletions src/expr-visitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ class ExprVisitor::Delegate {
virtual Result OnThrowExpr(ThrowExpr*) = 0;
virtual Result OnRethrowExpr(RethrowExpr*) = 0;
virtual Result OnAtomicWaitExpr(AtomicWaitExpr*) = 0;
virtual Result OnAtomicFenceExpr(AtomicFenceExpr*) = 0;
virtual Result OnAtomicNotifyExpr(AtomicNotifyExpr*) = 0;
virtual Result OnAtomicLoadExpr(AtomicLoadExpr*) = 0;
virtual Result OnAtomicStoreExpr(AtomicStoreExpr*) = 0;
Expand Down Expand Up @@ -187,6 +188,7 @@ class ExprVisitor::DelegateNop : public ExprVisitor::Delegate {
Result OnThrowExpr(ThrowExpr*) override { return Result::Ok; }
Result OnRethrowExpr(RethrowExpr*) override { return Result::Ok; }
Result OnAtomicWaitExpr(AtomicWaitExpr*) override { return Result::Ok; }
Result OnAtomicFenceExpr(AtomicFenceExpr*) override { return Result::Ok; }
Result OnAtomicNotifyExpr(AtomicNotifyExpr*) override { return Result::Ok; }
Result OnAtomicLoadExpr(AtomicLoadExpr*) override { return Result::Ok; }
Result OnAtomicStoreExpr(AtomicStoreExpr*) override { return Result::Ok; }
Expand Down
8 changes: 8 additions & 0 deletions src/interp/binary-reader-interp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ class BinaryReaderInterp : public BinaryReaderNop {
wabt::Result OnAtomicWaitExpr(Opcode opcode,
uint32_t alignment_log2,
Address offset) override;
wabt::Result OnAtomicFenceExpr(uint32_t consistency_model) override;
wabt::Result OnAtomicNotifyExpr(Opcode opcode,
uint32_t alignment_log2,
Address offset) override;
Expand Down Expand Up @@ -1808,6 +1809,13 @@ wabt::Result BinaryReaderInterp::OnAtomicWaitExpr(Opcode opcode,
return wabt::Result::Ok;
}

wabt::Result BinaryReaderInterp::OnAtomicFenceExpr(uint32_t consistency_model) {
CHECK_RESULT(typechecker_.OnAtomicFence(consistency_model));
CHECK_RESULT(EmitOpcode(Opcode::AtomicFence));
CHECK_RESULT(EmitI32(consistency_model));
return wabt::Result::Ok;
}

wabt::Result BinaryReaderInterp::OnAtomicNotifyExpr(Opcode opcode,
uint32_t alignment_log2,
Address offset) {
Expand Down
1 change: 1 addition & 0 deletions src/interp/interp-disassemble.cc
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ void Environment::Disassemble(Stream* stream,
case Opcode::Return:
case Opcode::Unreachable:
case Opcode::Drop:
case Opcode::AtomicFence:
stream->Writef("%s\n", opcode.GetName());
break;

Expand Down
6 changes: 6 additions & 0 deletions src/interp/interp-trace.cc
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,12 @@ void Thread::Trace(Stream* stream) {
break;
}

case Opcode::AtomicFence: {
const uint32_t consistency_model = ReadU32(&pc);
stream->Writef("%s $%u\n", opcode.GetName(), consistency_model);
break;
}

case Opcode::F32Store: {
const Index memory_index = ReadU32(&pc);
stream->Writef("%s $%" PRIindex ":%u+$%u, %g\n", opcode.GetName(),
Expand Down
1 change: 1 addition & 0 deletions src/interp/interp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2748,6 +2748,7 @@ Result Thread::Run(int num_instructions) {

case Opcode::I32AtomicWait:
case Opcode::I64AtomicWait:
case Opcode::AtomicFence:
case Opcode::AtomicNotify:
// TODO(binji): Implement.
TRAP(Unreachable);
Expand Down
1 change: 1 addition & 0 deletions src/ir-util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ ModuleContext::Arities ModuleContext::GetExprArity(const Expr& expr) const {

case ExprType::DataDrop:
case ExprType::ElemDrop:
case ExprType::AtomicFence:
return { 0, 0 };

case ExprType::MemoryInit:
Expand Down
1 change: 1 addition & 0 deletions src/ir.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
namespace {

const char* ExprTypeName[] = {
"AtomicFence",
"AtomicLoad",
"AtomicRmw",
"AtomicRmwCmpxchg",
Expand Down
11 changes: 11 additions & 0 deletions src/ir.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ enum class ExprType {
AtomicRmwCmpxchg,
AtomicStore,
AtomicNotify,
AtomicFence,
AtomicWait,
Binary,
Block,
Expand Down Expand Up @@ -467,6 +468,16 @@ typedef LoadStoreExpr<ExprType::AtomicWait> AtomicWaitExpr;
typedef LoadStoreExpr<ExprType::AtomicNotify> AtomicNotifyExpr;
typedef LoadStoreExpr<ExprType::LoadSplat> LoadSplatExpr;

class AtomicFenceExpr : public ExprMixin<ExprType::AtomicFence> {
public:
explicit AtomicFenceExpr(uint32_t consistency_model,
const Location& loc = Location())
: ExprMixin<ExprType::AtomicFence>(loc),
consistency_model(consistency_model) {}

uint32_t consistency_model;
};

struct Event {
explicit Event(string_view name) : name(name.to_string()) {}

Expand Down
1 change: 1 addition & 0 deletions src/lexer-keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ assert_return, TokenType::AssertReturn
assert_return_func, TokenType::AssertReturnFunc
assert_trap, TokenType::AssertTrap
assert_unlinkable, TokenType::AssertUnlinkable
atomic.fence, TokenType::AtomicFence, Opcode::AtomicFence
atomic.notify, TokenType::AtomicNotify, Opcode::AtomicNotify
binary, TokenType::Bin
block, TokenType::Block, Opcode::Block
Expand Down
1 change: 1 addition & 0 deletions src/opcode.cc
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ bool Opcode::IsEnabled(const Features& features) const {
case Opcode::AtomicNotify:
case Opcode::I32AtomicWait:
case Opcode::I64AtomicWait:
case Opcode::AtomicFence:
case Opcode::I32AtomicLoad:
case Opcode::I64AtomicLoad:
case Opcode::I32AtomicLoad8U:
Expand Down
1 change: 1 addition & 0 deletions src/opcode.def
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,7 @@ WABT_OPCODE(V128, I32, ___, ___, 8, 0xfd, 0xc5, I64X2LoadSplat, "i64x2.load_s
WABT_OPCODE(I32, I32, I32, ___, 4, 0xfe, 0x00, AtomicNotify, "atomic.notify", "")
WABT_OPCODE(I32, I32, I32, I64, 4, 0xfe, 0x01, I32AtomicWait, "i32.atomic.wait", "")
WABT_OPCODE(I32, I32, I64, I64, 8, 0xfe, 0x02, I64AtomicWait, "i64.atomic.wait", "")
WABT_OPCODE(___, ___, ___, ___, 0, 0xfe, 0x03, AtomicFence, "atomic.fence", "")
WABT_OPCODE(I32, I32, ___, ___, 4, 0xfe, 0x10, I32AtomicLoad, "i32.atomic.load", "")
WABT_OPCODE(I64, I32, ___, ___, 8, 0xfe, 0x11, I64AtomicLoad, "i64.atomic.load", "")
WABT_OPCODE(I32, I32, ___, ___, 1, 0xfe, 0x12, I32AtomicLoad8U, "i32.atomic.load8_u", "")
Expand Down
Loading

0 comments on commit 72d1fae

Please sign in to comment.