diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/binary-reader-interpreter.cc | 72 | ||||
-rw-r--r-- | src/interpreter-opcode.def | 38 | ||||
-rw-r--r-- | src/interpreter.cc | 374 | ||||
-rw-r--r-- | src/interpreter.h | 9 | ||||
-rw-r--r-- | src/opcode.cc | 8 | ||||
-rw-r--r-- | src/opcode.def | 10 |
6 files changed, 240 insertions, 271 deletions
diff --git a/src/binary-reader-interpreter.cc b/src/binary-reader-interpreter.cc index 6c9f5a52..19969c4e 100644 --- a/src/binary-reader-interpreter.cc +++ b/src/binary-reader-interpreter.cc @@ -217,8 +217,7 @@ class BinaryReaderInterpreter : public BinaryReaderNop { const void* data, IstreamOffset size); wabt::Result EmitData(const void* data, IstreamOffset size); - wabt::Result EmitOpcode(wabt::Opcode opcode); - wabt::Result EmitOpcode(interpreter::Opcode opcode); + wabt::Result EmitOpcode(Opcode opcode); wabt::Result EmitI8(uint8_t value); wabt::Result EmitI32(uint32_t value); wabt::Result EmitI64(uint64_t value); @@ -385,12 +384,15 @@ wabt::Result BinaryReaderInterpreter::EmitData(const void* data, return wabt::Result::Ok; } -wabt::Result BinaryReaderInterpreter::EmitOpcode(wabt::Opcode opcode) { - return EmitData(&opcode, sizeof(uint8_t)); -} +wabt::Result BinaryReaderInterpreter::EmitOpcode(Opcode opcode) { + if (opcode.HasPrefix()) { + CHECK_RESULT(EmitI8(opcode.GetPrefix())); + } -wabt::Result BinaryReaderInterpreter::EmitOpcode(interpreter::Opcode opcode) { - return EmitData(&opcode, sizeof(uint8_t)); + // Assume opcode codes are all 1 byte for now (excluding the prefix). + uint32_t code = opcode.GetCode(); + assert(code < 256); + return EmitI8(code); } wabt::Result BinaryReaderInterpreter::EmitI8(uint8_t value) { @@ -416,9 +418,9 @@ wabt::Result BinaryReaderInterpreter::EmitDropKeep(uint32_t drop, assert(keep <= 1); if (drop > 0) { if (drop == 1 && keep == 0) { - CHECK_RESULT(EmitOpcode(interpreter::Opcode::Drop)); + CHECK_RESULT(EmitOpcode(Opcode::Drop)); } else { - CHECK_RESULT(EmitOpcode(interpreter::Opcode::DropKeep)); + CHECK_RESULT(EmitOpcode(Opcode::InterpreterDropKeep)); CHECK_RESULT(EmitI32(drop)); CHECK_RESULT(EmitI8(keep)); } @@ -478,7 +480,7 @@ wabt::Result BinaryReaderInterpreter::EmitBr(Index depth, Index drop_count, Index keep_count) { CHECK_RESULT(EmitDropKeep(drop_count, keep_count)); - CHECK_RESULT(EmitOpcode(interpreter::Opcode::Br)); + CHECK_RESULT(EmitOpcode(Opcode::Br)); CHECK_RESULT(EmitBrOffset(depth, GetLabel(depth)->offset)); return wabt::Result::Ok; } @@ -1074,7 +1076,7 @@ wabt::Result BinaryReaderInterpreter::EndFunctionBody(Index index) { CHECK_RESULT(GetReturnDropKeepCount(&drop_count, &keep_count)); CHECK_RESULT(typechecker_.EndFunction()); CHECK_RESULT(EmitDropKeep(drop_count, keep_count)); - CHECK_RESULT(EmitOpcode(interpreter::Opcode::Return)); + CHECK_RESULT(EmitOpcode(Opcode::Return)); PopLabel(); current_func_ = nullptr; return wabt::Result::Ok; @@ -1095,7 +1097,7 @@ wabt::Result BinaryReaderInterpreter::OnLocalDecl(Index decl_index, if (decl_index == current_func_->local_decl_count - 1) { /* last local declaration, allocate space for all locals. */ - CHECK_RESULT(EmitOpcode(interpreter::Opcode::Alloca)); + CHECK_RESULT(EmitOpcode(Opcode::InterpreterAlloca)); CHECK_RESULT(EmitI32(current_func_->local_count)); } return wabt::Result::Ok; @@ -1151,7 +1153,7 @@ wabt::Result BinaryReaderInterpreter::OnIfExpr(Index num_types, Type* sig_types) { TypeVector sig(sig_types, sig_types + num_types); CHECK_RESULT(typechecker_.OnIf(&sig)); - CHECK_RESULT(EmitOpcode(interpreter::Opcode::BrUnless)); + CHECK_RESULT(EmitOpcode(Opcode::InterpreterBrUnless)); IstreamOffset fixup_offset = GetIstreamOffset(); CHECK_RESULT(EmitI32(kInvalidIstreamOffset)); PushLabel(kInvalidIstreamOffset, fixup_offset); @@ -1162,7 +1164,7 @@ wabt::Result BinaryReaderInterpreter::OnElseExpr() { CHECK_RESULT(typechecker_.OnElse()); Label* label = TopLabel(); IstreamOffset fixup_cond_offset = label->fixup_offset; - CHECK_RESULT(EmitOpcode(interpreter::Opcode::Br)); + CHECK_RESULT(EmitOpcode(Opcode::Br)); label->fixup_offset = GetIstreamOffset(); CHECK_RESULT(EmitI32(kInvalidIstreamOffset)); CHECK_RESULT(EmitI32At(fixup_cond_offset, GetIstreamOffset())); @@ -1195,7 +1197,7 @@ wabt::Result BinaryReaderInterpreter::OnBrIfExpr(Index depth) { CHECK_RESULT(typechecker_.OnBrIf(depth)); CHECK_RESULT(GetBrDropKeepCount(depth, &drop_count, &keep_count)); /* flip the br_if so if <cond> is true it can drop values from the stack */ - CHECK_RESULT(EmitOpcode(interpreter::Opcode::BrUnless)); + CHECK_RESULT(EmitOpcode(Opcode::InterpreterBrUnless)); IstreamOffset fixup_br_offset = GetIstreamOffset(); CHECK_RESULT(EmitI32(kInvalidIstreamOffset)); CHECK_RESULT(EmitBr(depth, drop_count, keep_count)); @@ -1208,13 +1210,13 @@ wabt::Result BinaryReaderInterpreter::OnBrTableExpr( Index* target_depths, Index default_target_depth) { CHECK_RESULT(typechecker_.BeginBrTable()); - CHECK_RESULT(EmitOpcode(interpreter::Opcode::BrTable)); + CHECK_RESULT(EmitOpcode(Opcode::BrTable)); CHECK_RESULT(EmitI32(num_targets)); IstreamOffset fixup_table_offset = GetIstreamOffset(); CHECK_RESULT(EmitI32(kInvalidIstreamOffset)); /* not necessary for the interpreter, but it makes it easier to disassemble. * This opcode specifies how many bytes of data follow. */ - CHECK_RESULT(EmitOpcode(interpreter::Opcode::Data)); + CHECK_RESULT(EmitOpcode(Opcode::InterpreterData)); CHECK_RESULT(EmitI32((num_targets + 1) * WABT_TABLE_ENTRY_SIZE)); CHECK_RESULT(EmitI32At(fixup_table_offset, GetIstreamOffset())); @@ -1234,10 +1236,10 @@ wabt::Result BinaryReaderInterpreter::OnCallExpr(Index func_index) { CHECK_RESULT(typechecker_.OnCall(&sig->param_types, &sig->result_types)); if (func->is_host) { - CHECK_RESULT(EmitOpcode(interpreter::Opcode::CallHost)); + CHECK_RESULT(EmitOpcode(Opcode::InterpreterCallHost)); CHECK_RESULT(EmitI32(TranslateFuncIndexToEnv(func_index))); } else { - CHECK_RESULT(EmitOpcode(interpreter::Opcode::Call)); + CHECK_RESULT(EmitOpcode(Opcode::Call)); CHECK_RESULT(EmitFuncOffset(cast<DefinedFunc>(func), func_index)); } @@ -1253,7 +1255,7 @@ wabt::Result BinaryReaderInterpreter::OnCallIndirectExpr(Index sig_index) { CHECK_RESULT( typechecker_.OnCallIndirect(&sig->param_types, &sig->result_types)); - CHECK_RESULT(EmitOpcode(interpreter::Opcode::CallIndirect)); + CHECK_RESULT(EmitOpcode(Opcode::CallIndirect)); CHECK_RESULT(EmitI32(module_->table_index)); CHECK_RESULT(EmitI32(TranslateSigIndexToEnv(sig_index))); return wabt::Result::Ok; @@ -1269,34 +1271,34 @@ wabt::Result BinaryReaderInterpreter::OnConvertExpr(wabt::Opcode opcode) { wabt::Result BinaryReaderInterpreter::OnDropExpr() { CHECK_RESULT(typechecker_.OnDrop()); - CHECK_RESULT(EmitOpcode(interpreter::Opcode::Drop)); + CHECK_RESULT(EmitOpcode(Opcode::Drop)); return wabt::Result::Ok; } wabt::Result BinaryReaderInterpreter::OnI32ConstExpr(uint32_t value) { CHECK_RESULT(typechecker_.OnConst(Type::I32)); - CHECK_RESULT(EmitOpcode(interpreter::Opcode::I32Const)); + CHECK_RESULT(EmitOpcode(Opcode::I32Const)); CHECK_RESULT(EmitI32(value)); return wabt::Result::Ok; } wabt::Result BinaryReaderInterpreter::OnI64ConstExpr(uint64_t value) { CHECK_RESULT(typechecker_.OnConst(Type::I64)); - CHECK_RESULT(EmitOpcode(interpreter::Opcode::I64Const)); + CHECK_RESULT(EmitOpcode(Opcode::I64Const)); CHECK_RESULT(EmitI64(value)); return wabt::Result::Ok; } wabt::Result BinaryReaderInterpreter::OnF32ConstExpr(uint32_t value_bits) { CHECK_RESULT(typechecker_.OnConst(Type::F32)); - CHECK_RESULT(EmitOpcode(interpreter::Opcode::F32Const)); + CHECK_RESULT(EmitOpcode(Opcode::F32Const)); CHECK_RESULT(EmitI32(value_bits)); return wabt::Result::Ok; } wabt::Result BinaryReaderInterpreter::OnF64ConstExpr(uint64_t value_bits) { CHECK_RESULT(typechecker_.OnConst(Type::F64)); - CHECK_RESULT(EmitOpcode(interpreter::Opcode::F64Const)); + CHECK_RESULT(EmitOpcode(Opcode::F64Const)); CHECK_RESULT(EmitI64(value_bits)); return wabt::Result::Ok; } @@ -1305,7 +1307,7 @@ wabt::Result BinaryReaderInterpreter::OnGetGlobalExpr(Index global_index) { CHECK_RESULT(CheckGlobal(global_index)); Type type = GetGlobalTypeByModuleIndex(global_index); CHECK_RESULT(typechecker_.OnGetGlobal(type)); - CHECK_RESULT(EmitOpcode(interpreter::Opcode::GetGlobal)); + CHECK_RESULT(EmitOpcode(Opcode::GetGlobal)); CHECK_RESULT(EmitI32(TranslateGlobalIndexToEnv(global_index))); return wabt::Result::Ok; } @@ -1319,7 +1321,7 @@ wabt::Result BinaryReaderInterpreter::OnSetGlobalExpr(Index global_index) { return wabt::Result::Error; } CHECK_RESULT(typechecker_.OnSetGlobal(global->typed_value.type)); - CHECK_RESULT(EmitOpcode(interpreter::Opcode::SetGlobal)); + CHECK_RESULT(EmitOpcode(Opcode::SetGlobal)); CHECK_RESULT(EmitI32(TranslateGlobalIndexToEnv(global_index))); return wabt::Result::Ok; } @@ -1337,7 +1339,7 @@ wabt::Result BinaryReaderInterpreter::OnGetLocalExpr(Index local_index) { // old stack size. Index translated_local_index = TranslateLocalIndex(local_index); CHECK_RESULT(typechecker_.OnGetLocal(type)); - CHECK_RESULT(EmitOpcode(interpreter::Opcode::GetLocal)); + CHECK_RESULT(EmitOpcode(Opcode::GetLocal)); CHECK_RESULT(EmitI32(translated_local_index)); return wabt::Result::Ok; } @@ -1346,7 +1348,7 @@ wabt::Result BinaryReaderInterpreter::OnSetLocalExpr(Index local_index) { CHECK_RESULT(CheckLocal(local_index)); Type type = GetLocalTypeByIndex(current_func_, local_index); CHECK_RESULT(typechecker_.OnSetLocal(type)); - CHECK_RESULT(EmitOpcode(interpreter::Opcode::SetLocal)); + CHECK_RESULT(EmitOpcode(Opcode::SetLocal)); CHECK_RESULT(EmitI32(TranslateLocalIndex(local_index))); return wabt::Result::Ok; } @@ -1355,7 +1357,7 @@ wabt::Result BinaryReaderInterpreter::OnTeeLocalExpr(Index local_index) { CHECK_RESULT(CheckLocal(local_index)); Type type = GetLocalTypeByIndex(current_func_, local_index); CHECK_RESULT(typechecker_.OnTeeLocal(type)); - CHECK_RESULT(EmitOpcode(interpreter::Opcode::TeeLocal)); + CHECK_RESULT(EmitOpcode(Opcode::TeeLocal)); CHECK_RESULT(EmitI32(TranslateLocalIndex(local_index))); return wabt::Result::Ok; } @@ -1363,7 +1365,7 @@ wabt::Result BinaryReaderInterpreter::OnTeeLocalExpr(Index local_index) { wabt::Result BinaryReaderInterpreter::OnGrowMemoryExpr() { CHECK_RESULT(CheckHasMemory(wabt::Opcode::GrowMemory)); CHECK_RESULT(typechecker_.OnGrowMemory()); - CHECK_RESULT(EmitOpcode(interpreter::Opcode::GrowMemory)); + CHECK_RESULT(EmitOpcode(Opcode::GrowMemory)); CHECK_RESULT(EmitI32(module_->memory_index)); return wabt::Result::Ok; } @@ -1395,7 +1397,7 @@ wabt::Result BinaryReaderInterpreter::OnStoreExpr(wabt::Opcode opcode, wabt::Result BinaryReaderInterpreter::OnCurrentMemoryExpr() { CHECK_RESULT(CheckHasMemory(wabt::Opcode::CurrentMemory)); CHECK_RESULT(typechecker_.OnCurrentMemory()); - CHECK_RESULT(EmitOpcode(interpreter::Opcode::CurrentMemory)); + CHECK_RESULT(EmitOpcode(Opcode::CurrentMemory)); CHECK_RESULT(EmitI32(module_->memory_index)); return wabt::Result::Ok; } @@ -1409,19 +1411,19 @@ wabt::Result BinaryReaderInterpreter::OnReturnExpr() { CHECK_RESULT(GetReturnDropKeepCount(&drop_count, &keep_count)); CHECK_RESULT(typechecker_.OnReturn()); CHECK_RESULT(EmitDropKeep(drop_count, keep_count)); - CHECK_RESULT(EmitOpcode(interpreter::Opcode::Return)); + CHECK_RESULT(EmitOpcode(Opcode::Return)); return wabt::Result::Ok; } wabt::Result BinaryReaderInterpreter::OnSelectExpr() { CHECK_RESULT(typechecker_.OnSelect()); - CHECK_RESULT(EmitOpcode(interpreter::Opcode::Select)); + CHECK_RESULT(EmitOpcode(Opcode::Select)); return wabt::Result::Ok; } wabt::Result BinaryReaderInterpreter::OnUnreachableExpr() { CHECK_RESULT(typechecker_.OnUnreachable()); - CHECK_RESULT(EmitOpcode(interpreter::Opcode::Unreachable)); + CHECK_RESULT(EmitOpcode(Opcode::Unreachable)); return wabt::Result::Ok; } diff --git a/src/interpreter-opcode.def b/src/interpreter-opcode.def deleted file mode 100644 index b2d2b0a0..00000000 --- a/src/interpreter-opcode.def +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2017 WebAssembly Community Group participants - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef WABT_OPCODE -#error "You must define WABT_OPCODE before including this file." -#endif - -/* - * tr: result type - * t1: type of the 1st parameter - * t2: type of the 2nd parameter - * m: memory size of the operation, if any - * code: opcode - * Name: used to generate the opcode enum - * text: a string of the opcode name in the text format - * - * tr t1 t2 m prefix code Name text - * ============================================================ */ - -#include "src/opcode.def" -WABT_OPCODE(___, ___, ___, 0, 0, 0xc0, Alloca, "alloca") -WABT_OPCODE(___, ___, ___, 0, 0, 0xc1, BrUnless, "br_unless") -WABT_OPCODE(___, ___, ___, 0, 0, 0xc2, CallHost, "call_host") -WABT_OPCODE(___, ___, ___, 0, 0, 0xc3, Data, "data") -WABT_OPCODE(___, ___, ___, 0, 0, 0xc4, DropKeep, "drop_keep") diff --git a/src/interpreter.cc b/src/interpreter.cc index 3ea17a71..d6f58578 100644 --- a/src/interpreter.cc +++ b/src/interpreter.cc @@ -30,15 +30,6 @@ namespace wabt { namespace interpreter { -static const char* s_opcode_name[] = { -#define WABT_OPCODE(rtype, type1, type2, mem_size, prefix, code, NAME, text) \ - text, -#include "src/interpreter-opcode.def" -#undef WABT_OPCODE - - "<invalid>", -}; - // Differs from the normal CHECK_RESULT because this one is meant to return the // interpreter Result type. #undef CHECK_RESULT @@ -59,13 +50,6 @@ static const char* s_opcode_name[] = { } \ } while (0) -static const char* GetOpcodeName(Opcode opcode) { - int value = static_cast<int>(opcode); - return value < static_cast<int>(WABT_ARRAY_SIZE(s_opcode_name)) - ? s_opcode_name[value] - : "<invalid>"; -} - Environment::Environment() : istream_(new OutputBuffer()) {} Index Environment::FindModuleIndex(string_view name) const { @@ -275,7 +259,7 @@ struct FloatTraits<float> { static const uint32_t kNegMax = 0xff7fffffU; static const uint32_t kNegInf = 0xff800000U; static const uint32_t kNegOne = 0xbf800000U; - static const uint32_t kNegZero =0x80000000U; + static const uint32_t kNegZero = 0x80000000U; static const uint32_t kQuietNan = 0x7fc00000U; static const uint32_t kQuietNegNan = 0xffc00000U; static const uint32_t kQuietNanBit = 0x00400000U; @@ -287,9 +271,7 @@ struct FloatTraits<float> { return (bits > kInf && bits < kNegZero) || (bits > kNegInf); } - static bool IsZero(uint32_t bits) { - return bits == 0 || bits == kNegZero; - } + static bool IsZero(uint32_t bits) { return bits == 0 || bits == kNegZero; } static bool IsCanonicalNan(uint32_t bits) { return bits == kQuietNan || bits == kQuietNegNan; @@ -375,9 +357,7 @@ struct FloatTraits<double> { return (bits > kInf && bits < kNegZero) || (bits > kNegInf); } - static bool IsZero(uint64_t bits) { - return bits == 0 || bits == kNegZero; - } + static bool IsZero(uint64_t bits) { return bits == 0 || bits == kNegZero; } static bool IsCanonicalNan(uint64_t bits) { return bits == kQuietNan || bits == kQuietNegNan; @@ -538,47 +518,75 @@ template<> uint64_t GetValue<double>(Value v) { return v.f64_bits; } #define PUSH_NEG_1_AND_BREAK_IF(cond) \ if (WABT_UNLIKELY(cond)) { \ - CHECK_TRAP(Push<int32_t>(-1)); \ + CHECK_TRAP(Push<int32_t>(-1)); \ break; \ } #define GOTO(offset) pc = &istream[offset] -static WABT_INLINE uint32_t read_u32_at(const uint8_t* pc) { - uint32_t result; - memcpy(&result, pc, sizeof(uint32_t)); +template <typename T> +inline T ReadUxAt(const uint8_t* pc) { + T result; + memcpy(&result, pc, sizeof(T)); return result; } -static WABT_INLINE uint32_t read_u32(const uint8_t** pc) { - uint32_t result = read_u32_at(*pc); - *pc += sizeof(uint32_t); +template <typename T> +inline T ReadUx(const uint8_t** pc) { + T result = ReadUxAt<T>(*pc); + *pc += sizeof(T); return result; } -static WABT_INLINE uint64_t read_u64_at(const uint8_t* pc) { - uint64_t result; - memcpy(&result, pc, sizeof(uint64_t)); - return result; +inline uint8_t ReadU8At(const uint8_t* pc) { + return ReadUxAt<uint8_t>(pc); } -static WABT_INLINE uint64_t read_u64(const uint8_t** pc) { - uint64_t result = read_u64_at(*pc); - *pc += sizeof(uint64_t); - return result; +inline uint8_t ReadU8(const uint8_t** pc) { + return ReadUx<uint8_t>(pc); +} + +inline uint32_t ReadU32At(const uint8_t* pc) { + return ReadUxAt<uint32_t>(pc); } -static WABT_INLINE void read_table_entry_at(const uint8_t* pc, - IstreamOffset* out_offset, - uint32_t* out_drop, - uint8_t* out_keep) { - *out_offset = read_u32_at(pc + WABT_TABLE_ENTRY_OFFSET_OFFSET); - *out_drop = read_u32_at(pc + WABT_TABLE_ENTRY_DROP_OFFSET); - *out_keep = *(pc + WABT_TABLE_ENTRY_KEEP_OFFSET); +inline uint32_t ReadU32(const uint8_t** pc) { + return ReadUx<uint32_t>(pc); +} + +inline uint64_t ReadU64At(const uint8_t* pc) { + return ReadUxAt<uint64_t>(pc); +} + +inline uint64_t ReadU64(const uint8_t** pc) { + return ReadUx<uint64_t>(pc); +} + +inline Opcode ReadOpcode(const uint8_t** pc) { + uint8_t value = ReadU8(pc); + if (Opcode::IsPrefixByte(value)) { + // For now, assume all instructions are encoded with just one extra byte + // so we don't have to decode LEB128 here. + uint32_t code = ReadU8(pc); + return Opcode::FromCode(value, code); + } else { + // TODO(binji): Optimize if needed; Opcode::FromCode does a log2(n) lookup + // from the encoding. + return Opcode::FromCode(value); + } +} + +inline void read_table_entry_at(const uint8_t* pc, + IstreamOffset* out_offset, + uint32_t* out_drop, + uint8_t* out_keep) { + *out_offset = ReadU32At(pc + WABT_TABLE_ENTRY_OFFSET_OFFSET); + *out_drop = ReadU32At(pc + WABT_TABLE_ENTRY_DROP_OFFSET); + *out_keep = ReadU8At(pc + WABT_TABLE_ENTRY_KEEP_OFFSET); } Memory* Thread::ReadMemory(const uint8_t** pc) { - Index memory_index = read_u32(pc); + Index memory_index = ReadU32(pc); return &env_->memories_[memory_index]; } @@ -645,7 +653,7 @@ Result Thread::Load(const uint8_t** pc) { "Extended type should be float iff MemType is float"); Memory* memory = ReadMemory(pc); - uint64_t offset = static_cast<uint64_t>(Pop<uint32_t>()) + read_u32(pc); + uint64_t offset = static_cast<uint64_t>(Pop<uint32_t>()) + ReadU32(pc); MemType value; TRAP_IF(offset + sizeof(value) > memory->data.size(), MemoryAccessOutOfBounds); @@ -659,7 +667,7 @@ Result Thread::Store(const uint8_t** pc) { typedef typename WrapMemType<ResultType, MemType>::type WrappedType; Memory* memory = ReadMemory(pc); WrappedType value = PopRep<ResultType>(); - uint64_t offset = static_cast<uint64_t>(Pop<uint32_t>()) + read_u32(pc); + uint64_t offset = static_cast<uint64_t>(Pop<uint32_t>()) + ReadU32(pc); TRAP_IF(offset + sizeof(value) > memory->data.size(), MemoryAccessOutOfBounds); void* dst = memory->data.data() + static_cast<IstreamOffset>(offset); @@ -1166,7 +1174,7 @@ Result Thread::Run(int num_instructions, IstreamOffset* call_stack_return_top) { const uint8_t* istream = GetIstream(); const uint8_t* pc = &istream[pc_]; for (int i = 0; i < num_instructions; ++i) { - Opcode opcode = static_cast<Opcode>(*pc++); + Opcode opcode = ReadOpcode(&pc); switch (opcode) { case Opcode::Select: { uint32_t cond = Pop<uint32_t>(); @@ -1177,19 +1185,19 @@ Result Thread::Run(int num_instructions, IstreamOffset* call_stack_return_top) { } case Opcode::Br: - GOTO(read_u32(&pc)); + GOTO(ReadU32(&pc)); break; case Opcode::BrIf: { - IstreamOffset new_pc = read_u32(&pc); + IstreamOffset new_pc = ReadU32(&pc); if (Pop<uint32_t>()) GOTO(new_pc); break; } case Opcode::BrTable: { - Index num_targets = read_u32(&pc); - IstreamOffset table_offset = read_u32(&pc); + Index num_targets = ReadU32(&pc); + IstreamOffset table_offset = ReadU32(&pc); uint32_t key = Pop<uint32_t>(); IstreamOffset key_offset = (key >= num_targets ? num_targets : key) * WABT_TABLE_ENTRY_SIZE; @@ -1216,62 +1224,62 @@ Result Thread::Run(int num_instructions, IstreamOffset* call_stack_return_top) { break; case Opcode::I32Const: - CHECK_TRAP(Push<uint32_t>(read_u32(&pc))); + CHECK_TRAP(Push<uint32_t>(ReadU32(&pc))); break; case Opcode::I64Const: - CHECK_TRAP(Push<uint64_t>(read_u64(&pc))); + CHECK_TRAP(Push<uint64_t>(ReadU64(&pc))); break; case Opcode::F32Const: - CHECK_TRAP(PushRep<float>(read_u32(&pc))); + CHECK_TRAP(PushRep<float>(ReadU32(&pc))); break; case Opcode::F64Const: - CHECK_TRAP(PushRep<double>(read_u64(&pc))); + CHECK_TRAP(PushRep<double>(ReadU64(&pc))); break; case Opcode::GetGlobal: { - Index index = read_u32(&pc); + Index index = ReadU32(&pc); assert(index < env_->globals_.size()); CHECK_TRAP(Push(env_->globals_[index].typed_value.value)); break; } case Opcode::SetGlobal: { - Index index = read_u32(&pc); + Index index = ReadU32(&pc); assert(index < env_->globals_.size()); env_->globals_[index].typed_value.value = Pop(); break; } case Opcode::GetLocal: { - Value value = Pick(read_u32(&pc)); + Value value = Pick(ReadU32(&pc)); CHECK_TRAP(Push(value)); break; } case Opcode::SetLocal: { Value value = Pop(); - Pick(read_u32(&pc)) = value; + Pick(ReadU32(&pc)) = value; break; } case Opcode::TeeLocal: - Pick(read_u32(&pc)) = Top(); + Pick(ReadU32(&pc)) = Top(); break; case Opcode::Call: { - IstreamOffset offset = read_u32(&pc); + IstreamOffset offset = ReadU32(&pc); CHECK_TRAP(PushCall(pc)); GOTO(offset); break; } case Opcode::CallIndirect: { - Index table_index = read_u32(&pc); + Index table_index = ReadU32(&pc); Table* table = &env_->tables_[table_index]; - Index sig_index = read_u32(&pc); + Index sig_index = ReadU32(&pc); Index entry_index = Pop<uint32_t>(); TRAP_IF(entry_index >= table->func_indexes.size(), UndefinedTableIndex); Index func_index = table->func_indexes[entry_index]; @@ -1288,8 +1296,8 @@ Result Thread::Run(int num_instructions, IstreamOffset* call_stack_return_top) { break; } - case Opcode::CallHost: { - Index func_index = read_u32(&pc); + case Opcode::InterpreterCallHost: { + Index func_index = ReadU32(&pc); CallHost(cast<HostFunc>(env_->funcs_[func_index].get())); break; } @@ -1982,17 +1990,17 @@ Result Thread::Run(int num_instructions, IstreamOffset* call_stack_return_top) { CHECK_TRAP(Unop(IntExtendS<uint64_t, int32_t>)); break; - case Opcode::Alloca: { + case Opcode::InterpreterAlloca: { Value* old_value_stack_top = value_stack_top_; - value_stack_top_ += read_u32(&pc); + value_stack_top_ += ReadU32(&pc); CHECK_STACK(); memset(old_value_stack_top, 0, (value_stack_top_ - old_value_stack_top) * sizeof(Value)); break; } - case Opcode::BrUnless: { - IstreamOffset new_pc = read_u32(&pc); + case Opcode::InterpreterBrUnless: { + IstreamOffset new_pc = ReadU32(&pc); if (!Pop<uint32_t>()) GOTO(new_pc); break; @@ -2002,14 +2010,14 @@ Result Thread::Run(int num_instructions, IstreamOffset* call_stack_return_top) { (void)Pop(); break; - case Opcode::DropKeep: { - uint32_t drop_count = read_u32(&pc); + case Opcode::InterpreterDropKeep: { + uint32_t drop_count = ReadU32(&pc); uint8_t keep_count = *pc++; DropKeep(drop_count, keep_count); break; } - case Opcode::Data: + case Opcode::InterpreterData: /* shouldn't ever execute this */ assert(0); break; @@ -2037,28 +2045,28 @@ void Thread::Trace(Stream* stream) { stream->Writef("#%" PRIzd ". %4" PRIzd ": V:%-3" PRIzd "| ", call_stack_depth, pc - istream, value_stack_depth); - Opcode opcode = static_cast<Opcode>(*pc++); + Opcode opcode = ReadOpcode(&pc); switch (opcode) { case Opcode::Select: - stream->Writef("%s %u, %" PRIu64 ", %" PRIu64 "\n", GetOpcodeName(opcode), + stream->Writef("%s %u, %" PRIu64 ", %" PRIu64 "\n", opcode.GetName(), Pick(3).i32, Pick(2).i64, Pick(1).i64); break; case Opcode::Br: - stream->Writef("%s @%u\n", GetOpcodeName(opcode), read_u32_at(pc)); + stream->Writef("%s @%u\n", opcode.GetName(), ReadU32At(pc)); break; case Opcode::BrIf: - stream->Writef("%s @%u, %u\n", GetOpcodeName(opcode), read_u32_at(pc), + stream->Writef("%s @%u, %u\n", opcode.GetName(), ReadU32At(pc), Top().i32); break; case Opcode::BrTable: { - Index num_targets = read_u32_at(pc); - IstreamOffset table_offset = read_u32_at(pc + 4); + Index num_targets = ReadU32At(pc); + IstreamOffset table_offset = ReadU32At(pc + 4); uint32_t key = Top().i32; - stream->Writef("%s %u, $#%" PRIindex ", table:$%u\n", - GetOpcodeName(opcode), key, num_targets, table_offset); + stream->Writef("%s %u, $#%" PRIindex ", table:$%u\n", opcode.GetName(), + key, num_targets, table_offset); break; } @@ -2066,58 +2074,56 @@ void Thread::Trace(Stream* stream) { case Opcode::Return: case Opcode::Unreachable: case Opcode::Drop: - stream->Writef("%s\n", GetOpcodeName(opcode)); + stream->Writef("%s\n", opcode.GetName()); break; case Opcode::CurrentMemory: { - Index memory_index = read_u32(&pc); - stream->Writef("%s $%" PRIindex "\n", GetOpcodeName(opcode), - memory_index); + Index memory_index = ReadU32(&pc); + stream->Writef("%s $%" PRIindex "\n", opcode.GetName(), memory_index); break; } case Opcode::I32Const: - stream->Writef("%s $%u\n", GetOpcodeName(opcode), read_u32_at(pc)); + stream->Writef("%s $%u\n", opcode.GetName(), ReadU32At(pc)); break; case Opcode::I64Const: - stream->Writef("%s $%" PRIu64 "\n", GetOpcodeName(opcode), - read_u64_at(pc)); + stream->Writef("%s $%" PRIu64 "\n", opcode.GetName(), ReadU64At(pc)); break; case Opcode::F32Const: - stream->Writef("%s $%g\n", GetOpcodeName(opcode), - Bitcast<float>(read_u32_at(pc))); + stream->Writef("%s $%g\n", opcode.GetName(), + Bitcast<float>(ReadU32At(pc))); break; case Opcode::F64Const: - stream->Writef("%s $%g\n", GetOpcodeName(opcode), - Bitcast<double>(read_u64_at(pc))); + stream->Writef("%s $%g\n", opcode.GetName(), + Bitcast<double>(ReadU64At(pc))); break; case Opcode::GetLocal: case Opcode::GetGlobal: - stream->Writef("%s $%u\n", GetOpcodeName(opcode), read_u32_at(pc)); + stream->Writef("%s $%u\n", opcode.GetName(), ReadU32At(pc)); break; case Opcode::SetLocal: case Opcode::SetGlobal: case Opcode::TeeLocal: - stream->Writef("%s $%u, %u\n", GetOpcodeName(opcode), read_u32_at(pc), + stream->Writef("%s $%u, %u\n", opcode.GetName(), ReadU32At(pc), Top().i32); break; case Opcode::Call: - stream->Writef("%s @%u\n", GetOpcodeName(opcode), read_u32_at(pc)); + stream->Writef("%s @%u\n", opcode.GetName(), ReadU32At(pc)); break; case Opcode::CallIndirect: - stream->Writef("%s $%u, %u\n", GetOpcodeName(opcode), read_u32_at(pc), + stream->Writef("%s $%u, %u\n", opcode.GetName(), ReadU32At(pc), Top().i32); break; - case Opcode::CallHost: - stream->Writef("%s $%u\n", GetOpcodeName(opcode), read_u32_at(pc)); + case Opcode::InterpreterCallHost: + stream->Writef("%s $%u\n", opcode.GetName(), ReadU32At(pc)); break; case Opcode::I32Load8S: @@ -2134,18 +2140,18 @@ void Thread::Trace(Stream* stream) { case Opcode::I64Load: case Opcode::F32Load: case Opcode::F64Load: { - Index memory_index = read_u32(&pc); - stream->Writef("%s $%" PRIindex ":%u+$%u\n", GetOpcodeName(opcode), - memory_index, Top().i32, read_u32_at(pc)); + Index memory_index = ReadU32(&pc); + stream->Writef("%s $%" PRIindex ":%u+$%u\n", opcode.GetName(), + memory_index, Top().i32, ReadU32At(pc)); break; } case Opcode::I32Store8: case Opcode::I32Store16: case Opcode::I32Store: { - Index memory_index = read_u32(&pc); - stream->Writef("%s $%" PRIindex ":%u+$%u, %u\n", GetOpcodeName(opcode), - memory_index, Pick(2).i32, read_u32_at(pc), Pick(1).i32); + Index memory_index = ReadU32(&pc); + stream->Writef("%s $%" PRIindex ":%u+$%u, %u\n", opcode.GetName(), + memory_index, Pick(2).i32, ReadU32At(pc), Pick(1).i32); break; } @@ -2153,33 +2159,33 @@ void Thread::Trace(Stream* stream) { case Opcode::I64Store16: case Opcode::I64Store32: case Opcode::I64Store: { - Index memory_index = read_u32(&pc); + Index memory_index = ReadU32(&pc); stream->Writef("%s $%" PRIindex ":%u+$%u, %" PRIu64 "\n", - GetOpcodeName(opcode), memory_index, Pick(2).i32, - read_u32_at(pc), Pick(1).i64); + opcode.GetName(), memory_index, Pick(2).i32, ReadU32At(pc), + Pick(1).i64); break; } case Opcode::F32Store: { - Index memory_index = read_u32(&pc); - stream->Writef("%s $%" PRIindex ":%u+$%u, %g\n", GetOpcodeName(opcode), - memory_index, Pick(2).i32, read_u32_at(pc), + Index memory_index = ReadU32(&pc); + stream->Writef("%s $%" PRIindex ":%u+$%u, %g\n", opcode.GetName(), + memory_index, Pick(2).i32, ReadU32At(pc), Bitcast<float>(Pick(1).f32_bits)); break; } case Opcode::F64Store: { - Index memory_index = read_u32(&pc); - stream->Writef("%s $%" PRIindex ":%u+$%u, %g\n", GetOpcodeName(opcode), - memory_index, Pick(2).i32, read_u32_at(pc), + Index memory_index = ReadU32(&pc); + stream->Writef("%s $%" PRIindex ":%u+$%u, %g\n", opcode.GetName(), + memory_index, Pick(2).i32, ReadU32At(pc), Bitcast<double>(Pick(1).f64_bits)); break; } case Opcode::GrowMemory: { - Index memory_index = read_u32(&pc); - stream->Writef("%s $%" PRIindex ":%u\n", GetOpcodeName(opcode), - memory_index, Top().i32); + Index memory_index = ReadU32(&pc); + stream->Writef("%s $%" PRIindex ":%u\n", opcode.GetName(), memory_index, + Top().i32); break; } @@ -2208,15 +2214,14 @@ void Thread::Trace(Stream* stream) { case Opcode::I32GeU: case Opcode::I32Rotr: case Opcode::I32Rotl: - stream->Writef("%s %u, %u\n", GetOpcodeName(opcode), Pick(2).i32, - Pick(1).i32); + stream->Writef("%s %u, %u\n", opcode.GetName(), Pick(2).i32, Pick(1).i32); break; case Opcode::I32Clz: case Opcode::I32Ctz: case Opcode::I32Popcnt: case Opcode::I32Eqz: - stream->Writef("%s %u\n", GetOpcodeName(opcode), Top().i32); + stream->Writef("%s %u\n", opcode.GetName(), Top().i32); break; case Opcode::I64Add: @@ -2244,7 +2249,7 @@ void Thread::Trace(Stream* stream) { case Opcode::I64GeU: case Opcode::I64Rotr: case Opcode::I64Rotl: - stream->Writef("%s %" PRIu64 ", %" PRIu64 "\n", GetOpcodeName(opcode), + stream->Writef("%s %" PRIu64 ", %" PRIu64 "\n", opcode.GetName(), Pick(2).i64, Pick(1).i64); break; @@ -2252,7 +2257,7 @@ void Thread::Trace(Stream* stream) { case Opcode::I64Ctz: case Opcode::I64Popcnt: case Opcode::I64Eqz: - stream->Writef("%s %" PRIu64 "\n", GetOpcodeName(opcode), Top().i64); + stream->Writef("%s %" PRIu64 "\n", opcode.GetName(), Top().i64); break; case Opcode::F32Add: @@ -2268,7 +2273,7 @@ void Thread::Trace(Stream* stream) { case Opcode::F32Le: case Opcode::F32Gt: case Opcode::F32Ge: - stream->Writef("%s %g, %g\n", GetOpcodeName(opcode), + stream->Writef("%s %g, %g\n", opcode.GetName(), Bitcast<float>(Pick(2).i32), Bitcast<float>(Pick(1).i32)); break; @@ -2279,8 +2284,7 @@ void Thread::Trace(Stream* stream) { case Opcode::F32Trunc: case Opcode::F32Nearest: case Opcode::F32Sqrt: - stream->Writef("%s %g\n", GetOpcodeName(opcode), - Bitcast<float>(Top().i32)); + stream->Writef("%s %g\n", opcode.GetName(), Bitcast<float>(Top().i32)); break; case Opcode::F64Add: @@ -2296,7 +2300,7 @@ void Thread::Trace(Stream* stream) { case Opcode::F64Le: case Opcode::F64Gt: case Opcode::F64Ge: - stream->Writef("%s %g, %g\n", GetOpcodeName(opcode), + stream->Writef("%s %g, %g\n", opcode.GetName(), Bitcast<double>(Pick(2).i64), Bitcast<double>(Pick(1).i64)); break; @@ -2308,8 +2312,7 @@ void Thread::Trace(Stream* stream) { case Opcode::F64Trunc: case Opcode::F64Nearest: case Opcode::F64Sqrt: - stream->Writef("%s %g\n", GetOpcodeName(opcode), - Bitcast<double>(Top().i64)); + stream->Writef("%s %g\n", opcode.GetName(), Bitcast<double>(Top().i64)); break; case Opcode::I32TruncSF32: @@ -2322,8 +2325,7 @@ void Thread::Trace(Stream* stream) { case Opcode::I32TruncUSatF32: case Opcode::I64TruncSSatF32: case Opcode::I64TruncUSatF32: - stream->Writef("%s %g\n", GetOpcodeName(opcode), - Bitcast<float>(Top().i32)); + stream->Writef("%s %g\n", opcode.GetName(), Bitcast<float>(Top().i32)); break; case Opcode::I32TruncSF64: @@ -2336,8 +2338,7 @@ void Thread::Trace(Stream* stream) { case Opcode::I32TruncUSatF64: case Opcode::I64TruncSSatF64: case Opcode::I64TruncUSatF64: - stream->Writef("%s %g\n", GetOpcodeName(opcode), - Bitcast<double>(Top().i64)); + stream->Writef("%s %g\n", opcode.GetName(), Bitcast<double>(Top().i64)); break; case Opcode::I32WrapI64: @@ -2346,7 +2347,7 @@ void Thread::Trace(Stream* stream) { case Opcode::F64ConvertSI64: case Opcode::F64ConvertUI64: case Opcode::F64ReinterpretI64: - stream->Writef("%s %" PRIu64 "\n", GetOpcodeName(opcode), Top().i64); + stream->Writef("%s %" PRIu64 "\n", opcode.GetName(), Top().i64); break; case Opcode::I64ExtendSI32: @@ -2356,24 +2357,24 @@ void Thread::Trace(Stream* stream) { case Opcode::F32ReinterpretI32: case Opcode::F64ConvertSI32: case Opcode::F64ConvertUI32: - stream->Writef("%s %u\n", GetOpcodeName(opcode), Top().i32); + stream->Writef("%s %u\n", opcode.GetName(), Top().i32); break; - case Opcode::Alloca: - stream->Writef("%s $%u\n", GetOpcodeName(opcode), read_u32_at(pc)); + case Opcode::InterpreterAlloca: + stream->Writef("%s $%u\n", opcode.GetName(), ReadU32At(pc)); break; - case Opcode::BrUnless: - stream->Writef("%s @%u, %u\n", GetOpcodeName(opcode), read_u32_at(pc), + case Opcode::InterpreterBrUnless: + stream->Writef("%s @%u, %u\n", opcode.GetName(), ReadU32At(pc), Top().i32); break; - case Opcode::DropKeep: - stream->Writef("%s $%u $%u\n", GetOpcodeName(opcode), read_u32_at(pc), + case Opcode::InterpreterDropKeep: + stream->Writef("%s $%u $%u\n", opcode.GetName(), ReadU32At(pc), *(pc + 4)); break; - case Opcode::Data: + case Opcode::InterpreterData: /* shouldn't ever execute this */ assert(0); break; @@ -2398,26 +2399,25 @@ void Environment::Disassemble(Stream* stream, while (static_cast<IstreamOffset>(pc - istream) < to) { stream->Writef("%4" PRIzd "| ", pc - istream); - Opcode opcode = static_cast<Opcode>(*pc++); + Opcode opcode = ReadOpcode(&pc); switch (opcode) { case Opcode::Select: - stream->Writef("%s %%[-3], %%[-2], %%[-1]\n", GetOpcodeName(opcode)); + stream->Writef("%s %%[-3], %%[-2], %%[-1]\n", opcode.GetName()); break; case Opcode::Br: - stream->Writef("%s @%u\n", GetOpcodeName(opcode), read_u32(&pc)); + stream->Writef("%s @%u\n", opcode.GetName(), ReadU32(&pc)); break; case Opcode::BrIf: - stream->Writef("%s @%u, %%[-1]\n", GetOpcodeName(opcode), - read_u32(&pc)); + stream->Writef("%s @%u, %%[-1]\n", opcode.GetName(), ReadU32(&pc)); break; case Opcode::BrTable: { - Index num_targets = read_u32(&pc); - IstreamOffset table_offset = read_u32(&pc); + Index num_targets = ReadU32(&pc); + IstreamOffset table_offset = ReadU32(&pc); stream->Writef("%s %%[-1], $#%" PRIindex ", table:$%u\n", - GetOpcodeName(opcode), num_targets, table_offset); + opcode.GetName(), num_targets, table_offset); break; } @@ -2425,60 +2425,57 @@ void Environment::Disassemble(Stream* stream, case Opcode::Return: case Opcode::Unreachable: case Opcode::Drop: - stream->Writef("%s\n", GetOpcodeName(opcode)); + stream->Writef("%s\n", opcode.GetName()); break; case Opcode::CurrentMemory: { - Index memory_index = read_u32(&pc); - stream->Writef("%s $%" PRIindex "\n", GetOpcodeName(opcode), - memory_index); + Index memory_index = ReadU32(&pc); + stream->Writef("%s $%" PRIindex "\n", opcode.GetName(), memory_index); break; } case Opcode::I32Const: - stream->Writef("%s $%u\n", GetOpcodeName(opcode), read_u32(&pc)); + stream->Writef("%s $%u\n", opcode.GetName(), ReadU32(&pc)); break; case Opcode::I64Const: - stream->Writef("%s $%" PRIu64 "\n", GetOpcodeName(opcode), - read_u64(&pc)); + stream->Writef("%s $%" PRIu64 "\n", opcode.GetName(), ReadU64(&pc)); break; case Opcode::F32Const: - stream->Writef("%s $%g\n", GetOpcodeName(opcode), - Bitcast<float>(read_u32(&pc))); + stream->Writef("%s $%g\n", opcode.GetName(), + Bitcast<float>(ReadU32(&pc))); break; case Opcode::F64Const: - stream->Writef("%s $%g\n", GetOpcodeName(opcode), - Bitcast<double>(read_u64(&pc))); + stream->Writef("%s $%g\n", opcode.GetName(), + Bitcast<double>(ReadU64(&pc))); break; case Opcode::GetLocal: case Opcode::GetGlobal: - stream->Writef("%s $%u\n", GetOpcodeName(opcode), read_u32(&pc)); + stream->Writef("%s $%u\n", opcode.GetName(), ReadU32(&pc)); break; case Opcode::SetLocal: case Opcode::SetGlobal: case Opcode::TeeLocal: - stream->Writef("%s $%u, %%[-1]\n", GetOpcodeName(opcode), - read_u32(&pc)); + stream->Writef("%s $%u, %%[-1]\n", opcode.GetName(), ReadU32(&pc)); break; case Opcode::Call: - stream->Writef("%s @%u\n", GetOpcodeName(opcode), read_u32(&pc)); + stream->Writef("%s @%u\n", opcode.GetName(), ReadU32(&pc)); break; case Opcode::CallIndirect: { - Index table_index = read_u32(&pc); - stream->Writef("%s $%" PRIindex ":%u, %%[-1]\n", GetOpcodeName(opcode), - table_index, read_u32(&pc)); + Index table_index = ReadU32(&pc); + stream->Writef("%s $%" PRIindex ":%u, %%[-1]\n", opcode.GetName(), + table_index, ReadU32(&pc)); break; } - case Opcode::CallHost: - stream->Writef("%s $%u\n", GetOpcodeName(opcode), read_u32(&pc)); + case Opcode::InterpreterCallHost: + stream->Writef("%s $%u\n", opcode.GetName(), ReadU32(&pc)); break; case Opcode::I32Load8S: @@ -2495,9 +2492,9 @@ void Environment::Disassemble(Stream* stream, case Opcode::I64Load: case Opcode::F32Load: case Opcode::F64Load: { - Index memory_index = read_u32(&pc); - stream->Writef("%s $%" PRIindex ":%%[-1]+$%u\n", GetOpcodeName(opcode), - memory_index, read_u32(&pc)); + Index memory_index = ReadU32(&pc); + stream->Writef("%s $%" PRIindex ":%%[-1]+$%u\n", opcode.GetName(), + memory_index, ReadU32(&pc)); break; } @@ -2510,9 +2507,9 @@ void Environment::Disassemble(Stream* stream, case Opcode::I64Store: case Opcode::F32Store: case Opcode::F64Store: { - Index memory_index = read_u32(&pc); + Index memory_index = ReadU32(&pc); stream->Writef("%s %%[-2]+$%" PRIindex ", $%u:%%[-1]\n", - GetOpcodeName(opcode), memory_index, read_u32(&pc)); + opcode.GetName(), memory_index, ReadU32(&pc)); break; } @@ -2592,7 +2589,7 @@ void Environment::Disassemble(Stream* stream, case Opcode::F64Le: case Opcode::F64Gt: case Opcode::F64Ge: - stream->Writef("%s %%[-2], %%[-1]\n", GetOpcodeName(opcode)); + stream->Writef("%s %%[-2], %%[-1]\n", opcode.GetName()); break; case Opcode::I32Clz: @@ -2650,35 +2647,34 @@ void Environment::Disassemble(Stream* stream, case Opcode::I32TruncUSatF64: case Opcode::I64TruncSSatF64: case Opcode::I64TruncUSatF64: - stream->Writef("%s %%[-1]\n", GetOpcodeName(opcode)); + stream->Writef("%s %%[-1]\n", opcode.GetName()); break; case Opcode::GrowMemory: { - Index memory_index = read_u32(&pc); - stream->Writef("%s $%" PRIindex ":%%[-1]\n", GetOpcodeName(opcode), + Index memory_index = ReadU32(&pc); + stream->Writef("%s $%" PRIindex ":%%[-1]\n", opcode.GetName(), memory_index); break; } - case Opcode::Alloca: - stream->Writef("%s $%u\n", GetOpcodeName(opcode), read_u32(&pc)); + case Opcode::InterpreterAlloca: + stream->Writef("%s $%u\n", opcode.GetName(), ReadU32(&pc)); break; - case Opcode::BrUnless: - stream->Writef("%s @%u, %%[-1]\n", GetOpcodeName(opcode), - read_u32(&pc)); + case Opcode::InterpreterBrUnless: + stream->Writef("%s @%u, %%[-1]\n", opcode.GetName(), ReadU32(&pc)); break; - case Opcode::DropKeep: { - uint32_t drop = read_u32(&pc); + case Opcode::InterpreterDropKeep: { + uint32_t drop = ReadU32(&pc); uint8_t keep = *pc++; - stream->Writef("%s $%u $%u\n", GetOpcodeName(opcode), drop, keep); + stream->Writef("%s $%u $%u\n", opcode.GetName(), drop, keep); break; } - case Opcode::Data: { - uint32_t num_bytes = read_u32(&pc); - stream->Writef("%s $%u\n", GetOpcodeName(opcode), num_bytes); + case Opcode::InterpreterData: { + uint32_t num_bytes = ReadU32(&pc); + stream->Writef("%s $%u\n", opcode.GetName(), num_bytes); /* for now, the only reason this is emitted is for br_table, so display * it as a list of table entries */ if (num_bytes % WABT_TABLE_ENTRY_SIZE == 0) { diff --git a/src/interpreter.h b/src/interpreter.h index 8466bb2d..178fad19 100644 --- a/src/interpreter.h +++ b/src/interpreter.h @@ -91,15 +91,6 @@ static const IstreamOffset kInvalidIstreamOffset = ~0; #define WABT_TABLE_ENTRY_DROP_OFFSET sizeof(uint32_t) #define WABT_TABLE_ENTRY_KEEP_OFFSET (sizeof(IstreamOffset) + sizeof(uint32_t)) -// NOTE: These enumeration values do not match the standard binary encoding. -enum class Opcode { -#define WABT_OPCODE(rtype, type1, type2, mem_size, prefix, code, Name, text) \ - Name, -#include "src/interpreter-opcode.def" -#undef WABT_OPCODE - Invalid, -}; - struct FuncSignature { FuncSignature() = default; FuncSignature(Index param_count, diff --git a/src/opcode.cc b/src/opcode.cc index 5b37c42d..d5b305bf 100644 --- a/src/opcode.cc +++ b/src/opcode.cc @@ -102,6 +102,14 @@ bool Opcode::IsEnabled(const Features& features) const { case Opcode::I64Extend32S: return features.threads_enabled(); + // Interpreter opcodes are never "enabled". + case Opcode::InterpreterAlloca: + case Opcode::InterpreterBrUnless: + case Opcode::InterpreterCallHost: + case Opcode::InterpreterData: + case Opcode::InterpreterDropKeep: + return false; + default: return true; } diff --git a/src/opcode.def b/src/opcode.def index b16df876..7ecf1d1d 100644 --- a/src/opcode.def +++ b/src/opcode.def @@ -18,6 +18,8 @@ #error "You must define WABT_OPCODE before including this file." #endif +/* *** NOTE *** This list must be kept sorted so it can be binary searched */ + /* * tr: result type * t1: type of the 1st parameter @@ -215,6 +217,13 @@ WABT_OPCODE(I64, I64, ___, 0, 0, 0xC2, I64Extend8S, "i64.extend8_s") WABT_OPCODE(I64, I64, ___, 0, 0, 0xC3, I64Extend16S, "i64.extend16_s") WABT_OPCODE(I64, I64, ___, 0, 0, 0xC4, I64Extend32S, "i64.extend32_s") +/* Interpreter-only opcodes */ +WABT_OPCODE(___, ___, ___, 0, 0, 0xe0, InterpreterAlloca, "alloca") +WABT_OPCODE(___, ___, ___, 0, 0, 0xe1, InterpreterBrUnless, "br_unless") +WABT_OPCODE(___, ___, ___, 0, 0, 0xe2, InterpreterCallHost, "call_host") +WABT_OPCODE(___, ___, ___, 0, 0, 0xe3, InterpreterData, "data") +WABT_OPCODE(___, ___, ___, 0, 0, 0xe4, InterpreterDropKeep, "drop_keep") + WABT_OPCODE(I32, F32, ___, 0, 0xfc, 0x00, I32TruncSSatF32, "i32.trunc_s:sat/f32") WABT_OPCODE(I32, F32, ___, 0, 0xfc, 0x01, I32TruncUSatF32, "i32.trunc_u:sat/f32") WABT_OPCODE(I32, F64, ___, 0, 0xfc, 0x02, I32TruncSSatF64, "i32.trunc_s:sat/f64") @@ -223,3 +232,4 @@ WABT_OPCODE(I64, F32, ___, 0, 0xfc, 0x04, I64TruncSSatF32, "i64.trunc_s:sat/f32 WABT_OPCODE(I64, F32, ___, 0, 0xfc, 0x05, I64TruncUSatF32, "i64.trunc_u:sat/f32") WABT_OPCODE(I64, F64, ___, 0, 0xfc, 0x06, I64TruncSSatF64, "i64.trunc_s:sat/f64") WABT_OPCODE(I64, F64, ___, 0, 0xfc, 0x07, I64TruncUSatF64, "i64.trunc_u:sat/f64") + |