diff options
author | Ben Smith <binjimin@gmail.com> | 2017-09-20 09:49:58 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-09-20 09:49:58 -0700 |
commit | 447e6f752b157d0a9951525a045d862e62d9b88c (patch) | |
tree | 2484ab5841f35fa50127f6dd83460f943a202fb6 /src/binary-reader-interpreter.cc | |
parent | c71918746e06d2afffc46b3da5e3f2c024cc4b92 (diff) | |
download | wabt-447e6f752b157d0a9951525a045d862e62d9b88c.tar.gz wabt-447e6f752b157d0a9951525a045d862e62d9b88c.tar.bz2 wabt-447e6f752b157d0a9951525a045d862e62d9b88c.zip |
Add Atomic instructions (#633)
This adds support for all atomic instructions, enabled via the
`--enable-threads` flag.
It supports all tools: parsing text, decoding binary, validation, and
interpreting. It does not currently ensure that the memory is marked as
shared; that flag is not supported in wabt yet.
Diffstat (limited to 'src/binary-reader-interpreter.cc')
-rw-r--r-- | src/binary-reader-interpreter.cc | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/src/binary-reader-interpreter.cc b/src/binary-reader-interpreter.cc index 19969c4e..258ffc5f 100644 --- a/src/binary-reader-interpreter.cc +++ b/src/binary-reader-interpreter.cc @@ -136,6 +136,18 @@ class BinaryReaderInterpreter : public BinaryReaderNop { wabt::Result OnLocalDeclCount(Index count) override; wabt::Result OnLocalDecl(Index decl_index, Index count, Type type) override; + wabt::Result OnAtomicLoadExpr(Opcode opcode, + uint32_t alignment_log2, + Address offset) override; + wabt::Result OnAtomicStoreExpr(Opcode opcode, + uint32_t alignment_log2, + Address offset) override; + wabt::Result OnAtomicRmwExpr(Opcode opcode, + uint32_t alignment_log2, + Address offset) override; + wabt::Result OnAtomicRmwCmpxchgExpr(Opcode opcode, + uint32_t alignment_log2, + Address offset) override; wabt::Result OnBinaryExpr(wabt::Opcode opcode) override; wabt::Result OnBlockExpr(Index num_types, Type* sig_types) override; wabt::Result OnBrExpr(Index depth) override; @@ -243,6 +255,8 @@ class BinaryReaderInterpreter : public BinaryReaderNop { const Limits* actual_limits); wabt::Result CheckHasMemory(wabt::Opcode opcode); wabt::Result CheckAlign(uint32_t alignment_log2, Address natural_alignment); + wabt::Result CheckAtomicAlign(uint32_t alignment_log2, + Address natural_alignment); wabt::Result AppendExport(Module* module, ExternalKind kind, @@ -1121,12 +1135,72 @@ wabt::Result BinaryReaderInterpreter::CheckAlign(uint32_t alignment_log2, return wabt::Result::Ok; } +wabt::Result BinaryReaderInterpreter::CheckAtomicAlign( + uint32_t alignment_log2, + Address natural_alignment) { + if (alignment_log2 >= 32 || (1U << alignment_log2) != natural_alignment) { + PrintError("alignment must be equal to natural alignment (%u)", + natural_alignment); + return wabt::Result::Error; + } + return wabt::Result::Ok; +} + wabt::Result BinaryReaderInterpreter::OnUnaryExpr(wabt::Opcode opcode) { CHECK_RESULT(typechecker_.OnUnary(opcode)); CHECK_RESULT(EmitOpcode(opcode)); return wabt::Result::Ok; } +wabt::Result BinaryReaderInterpreter::OnAtomicLoadExpr(Opcode opcode, + uint32_t alignment_log2, + Address offset) { + CHECK_RESULT(CheckHasMemory(opcode)); + CHECK_RESULT(CheckAtomicAlign(alignment_log2, opcode.GetMemorySize())); + CHECK_RESULT(typechecker_.OnAtomicLoad(opcode)); + CHECK_RESULT(EmitOpcode(opcode)); + CHECK_RESULT(EmitI32(module_->memory_index)); + CHECK_RESULT(EmitI32(offset)); + return wabt::Result::Ok; +} + +wabt::Result BinaryReaderInterpreter::OnAtomicStoreExpr(Opcode opcode, + uint32_t alignment_log2, + Address offset) { + CHECK_RESULT(CheckHasMemory(opcode)); + CHECK_RESULT(CheckAtomicAlign(alignment_log2, opcode.GetMemorySize())); + CHECK_RESULT(typechecker_.OnAtomicStore(opcode)); + CHECK_RESULT(EmitOpcode(opcode)); + CHECK_RESULT(EmitI32(module_->memory_index)); + CHECK_RESULT(EmitI32(offset)); + return wabt::Result::Ok; +} + +wabt::Result BinaryReaderInterpreter::OnAtomicRmwExpr(Opcode opcode, + uint32_t alignment_log2, + Address offset) { + CHECK_RESULT(CheckHasMemory(opcode)); + CHECK_RESULT(CheckAtomicAlign(alignment_log2, opcode.GetMemorySize())); + CHECK_RESULT(typechecker_.OnAtomicRmw(opcode)); + CHECK_RESULT(EmitOpcode(opcode)); + CHECK_RESULT(EmitI32(module_->memory_index)); + CHECK_RESULT(EmitI32(offset)); + return wabt::Result::Ok; +} + +wabt::Result BinaryReaderInterpreter::OnAtomicRmwCmpxchgExpr( + Opcode opcode, + uint32_t alignment_log2, + Address offset) { + CHECK_RESULT(CheckHasMemory(opcode)); + CHECK_RESULT(CheckAtomicAlign(alignment_log2, opcode.GetMemorySize())); + CHECK_RESULT(typechecker_.OnAtomicRmwCmpxchg(opcode)); + CHECK_RESULT(EmitOpcode(opcode)); + CHECK_RESULT(EmitI32(module_->memory_index)); + CHECK_RESULT(EmitI32(offset)); + return wabt::Result::Ok; +} + wabt::Result BinaryReaderInterpreter::OnBinaryExpr(wabt::Opcode opcode) { CHECK_RESULT(typechecker_.OnBinary(opcode)); CHECK_RESULT(EmitOpcode(opcode)); |