diff options
Diffstat (limited to 'deps/v8/test/unittests/wasm/wasm-text-unittest.cc')
-rw-r--r-- | deps/v8/test/unittests/wasm/wasm-text-unittest.cc | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/deps/v8/test/unittests/wasm/wasm-text-unittest.cc b/deps/v8/test/unittests/wasm/wasm-text-unittest.cc new file mode 100644 index 0000000000..e960b730a5 --- /dev/null +++ b/deps/v8/test/unittests/wasm/wasm-text-unittest.cc @@ -0,0 +1,121 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <sstream> + +#include "test/unittests/test-utils.h" + +#include "src/wasm/module-decoder.h" +#include "src/wasm/wasm-module-builder.h" +#include "src/wasm/wasm-module.h" +#include "src/wasm/wasm-opcodes.h" +#include "src/wasm/wasm-text.h" +#include "test/common/wasm/test-signatures.h" + +namespace v8 { +namespace internal { +namespace wasm { + +class WasmTextTest : public TestWithIsolateAndZone { + public: + TestSignatures sigs; + WasmFeatures enabled_features_; + + void TestInstruction(const byte* func_start, size_t func_size) { + WasmModuleBuilder mb(zone()); + auto* fb = mb.AddFunction(sigs.v_v()); + fb->EmitCode(func_start, static_cast<uint32_t>(func_size)); + fb->Emit(kExprEnd); + + ZoneBuffer buffer(zone()); + mb.WriteTo(&buffer); + + ModuleWireBytes wire_bytes( + Vector<const byte>(buffer.begin(), buffer.size())); + + ModuleResult result = DecodeWasmModule( + enabled_features_, buffer.begin(), buffer.end(), false, kWasmOrigin, + isolate()->counters(), isolate()->wasm_engine()->allocator()); + EXPECT_TRUE(result.ok()); + + std::stringstream ss; + PrintWasmText(result.value().get(), wire_bytes, 0, ss, nullptr); + } +}; + +TEST_F(WasmTextTest, EveryOpcodeCanBeDecoded) { + static const struct { + WasmOpcode opcode; + const char* debug_name; + } kValues[] = { +#define DECLARE_ELEMENT(name, opcode, sig) {kExpr##name, "kExpr" #name}, + FOREACH_OPCODE(DECLARE_ELEMENT)}; +#undef DECLARE_ELEMENT + + for (const auto& value : kValues) { + // Pad with 0 for any immediate values. If they're not needed, they'll be + // interpreted as unreachable. + byte data[20] = {0}; + + printf("%s\n", value.debug_name); + switch (value.opcode) { + // Instructions that have a special case because they affect the control + // depth. + case kExprBlock: + case kExprLoop: + case kExprIf: + case kExprTry: + data[0] = value.opcode; + data[1] = kLocalVoid; + data[2] = kExprEnd; + break; + case kExprElse: + data[0] = kExprIf; + data[1] = value.opcode; + data[2] = kExprEnd; + break; + case kExprCatch: + data[0] = kExprTry; + data[1] = value.opcode; + data[2] = kExprEnd; + break; + case kExprEnd: + break; + + // Instructions with special requirements for immediates. + case kExprSelectWithType: + data[0] = kExprSelectWithType; + data[1] = 1; + data[2] = kLocalI32; + break; + + default: { + if (value.opcode >= 0x100) { + data[0] = value.opcode >> 8; // Prefix byte. + byte opcode = value.opcode & 0xff; // Actual opcode. + if (opcode >= 0x80) { + // Opcode with prefix, and needs to be LEB encoded (3 bytes). + // For now, this can only be in the range [0x80, 0xff], which means + // that the third byte is always 1. + data[1] = (opcode & 0x7f) | 0x80; + data[2] = 1; + } else { + // Opcode with prefix (2 bytes). + data[1] = opcode; + } + } else { + // Single-byte opcode. + data[0] = value.opcode; + } + break; + } + } + + TestInstruction(data, arraysize(data)); + } +} + +} // namespace wasm +} // namespace internal +} // namespace v8 |