diff options
author | Ben Smith <binjimin@gmail.com> | 2017-09-08 15:53:38 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-09-08 15:53:38 -0700 |
commit | c73acd290c29429f4f4c491e8a66cc62f7ef8f2e (patch) | |
tree | 2070fe92d9aa25635e7d9d3242c9b8e48e659420 /src/binary-reader-interpreter.cc | |
parent | 6a582bccddb48009414c5d909dea1544bcfcc512 (diff) | |
download | wabt-c73acd290c29429f4f4c491e8a66cc62f7ef8f2e.tar.gz wabt-c73acd290c29429f4f4c491e8a66cc62f7ef8f2e.tar.bz2 wabt-c73acd290c29429f4f4c491e8a66cc62f7ef8f2e.zip |
Move Interpreter::Opcodes into Opcode (#618)
Having the interpreter use its own opcodes was convenient because it
adds a few additional codes (e.g. alloca, br_unless, etc).
As soon as we add the atomic instructions, this count goes above 1-byte,
so we need some mechanism for storing those codes. We could just
increase the opcode size to uint16_t, but it's simpler to just use the
same encoding as the WebAssembly binary format.
The one drawback is that mapping from the encoding to Opcode is a
log2(n) operation currently. This doesn't affect the speed of running
tests at all because it is too insignificant, but it's worth mentioning.
Diffstat (limited to 'src/binary-reader-interpreter.cc')
-rw-r--r-- | src/binary-reader-interpreter.cc | 72 |
1 files changed, 37 insertions, 35 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; } |