v8/test/unittests/wasm/wasm-text-unittest.cc
Clemens Hammacher bcdf2e2a54 [wasm] Remove non-const arguments from module builder
R=ahaas@chromium.org

Bug: v8:9429, v8:9396
Change-Id: I2a66142c04b2ec0e3ed57ea2392dda6d17d53b38
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1687895
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: Andreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62554}
2019-07-08 11:42:59 +00:00

122 lines
3.4 KiB
C++

// 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