Commit 45618a9a authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[wasm] Make prototype flags experimental

Most prototype implementations are not fully supported in the
interpreter. This is the case at least for exception handling, simd, and
atomics. Any function can be redirected to the interpreter though,
either by passing --wasm-interpret-all, or by dynamically redirecting to
the interpreter for debugging.
Making the flags experimental keeps the fuzzer from playing around with
these flags.

Drive-by: Refactor tests which explicitly set the prototype flag to use
a new scope for that.

R=ahaas@chromium.org
BUG=chromium:727584

Change-Id: I67da79f579f1ac93c67189afef40c6524bdd4430
Reviewed-on: https://chromium-review.googlesource.com/519402
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45639}
parent b21bc232
......@@ -576,13 +576,13 @@ DEFINE_STRING(dump_wasm_module_path, NULL, "directory to dump wasm modules to")
DEFINE_INT(typed_array_max_size_in_heap, 64,
"threshold for in-heap typed array")
DEFINE_BOOL(wasm_simd_prototype, false,
DEFINE_BOOL(experimental_wasm_simd, false,
"enable prototype simd opcodes for wasm")
DEFINE_BOOL(wasm_eh_prototype, false,
DEFINE_BOOL(experimental_wasm_eh, false,
"enable prototype exception handling opcodes for wasm")
DEFINE_BOOL(wasm_mv_prototype, false,
DEFINE_BOOL(experimental_wasm_mv, false,
"enable prototype multi-value support for wasm")
DEFINE_BOOL(wasm_atomics_prototype, false,
DEFINE_BOOL(experimental_wasm_atomics, false,
"enable prototype atomic opcodes for wasm")
DEFINE_BOOL(wasm_opt, true, "enable wasm optimization")
......
......@@ -1222,7 +1222,8 @@ Object* Isolate::UnwindAndFindHandler() {
trap_handler::ClearThreadInWasm();
}
if (!FLAG_wasm_eh_prototype || !is_catchable_by_wasm(exception)) break;
if (!FLAG_experimental_wasm_eh || !is_catchable_by_wasm(exception))
break;
int stack_slots = 0; // Will contain stack slot count of frame.
WasmCompiledFrame* wasm_frame = static_cast<WasmCompiledFrame*>(frame);
int offset = wasm_frame->LookupExceptionHandlerInTable(&stack_slots);
......
......@@ -100,7 +100,7 @@ struct BlockTypeOperand {
types = pc + 1;
} else {
// Handle multi-value blocks.
if (!CHECKED_COND(FLAG_wasm_mv_prototype)) {
if (!CHECKED_COND(FLAG_experimental_wasm_mv)) {
decoder->error(pc + 1, "invalid block arity > 1");
return;
}
......
......@@ -35,13 +35,13 @@ namespace wasm {
#define TRACE(...)
#endif
#define CHECK_PROTOTYPE_OPCODE(flag) \
if (module_ != nullptr && module_->is_asm_js()) { \
error("Opcode not supported for asmjs modules"); \
} \
if (!FLAG_##flag) { \
error("Invalid opcode (enable with --" #flag ")"); \
break; \
#define CHECK_PROTOTYPE_OPCODE(flag) \
if (module_ != nullptr && module_->is_asm_js()) { \
error("Opcode not supported for asmjs modules"); \
} \
if (!FLAG_experimental_wasm_##flag) { \
error("Invalid opcode (enable with --experimental-wasm-" #flag ")"); \
break; \
}
// An SsaEnv environment carries the current local variable renaming
......@@ -599,7 +599,8 @@ class WasmDecoder : public Decoder {
case kExprUnreachable:
return {0, 0};
default:
V8_Fatal(__FILE__, __LINE__, "unimplemented opcode: %x", opcode);
V8_Fatal(__FILE__, __LINE__, "unimplemented opcode: %x (%s)", opcode,
WasmOpcodes::OpcodeName(opcode));
return {0, 0};
}
#undef DECLARE_OPCODE_CASE
......@@ -843,7 +844,7 @@ class WasmFullDecoder : public WasmDecoder {
break;
}
case kExprThrow: {
CHECK_PROTOTYPE_OPCODE(wasm_eh_prototype);
CHECK_PROTOTYPE_OPCODE(eh);
Value value = Pop(0, kWasmI32);
BUILD(Throw, value.node);
// TODO(titzer): Throw should end control, but currently we build a
......@@ -853,7 +854,7 @@ class WasmFullDecoder : public WasmDecoder {
break;
}
case kExprTry: {
CHECK_PROTOTYPE_OPCODE(wasm_eh_prototype);
CHECK_PROTOTYPE_OPCODE(eh);
BlockTypeOperand<true> operand(this, pc_);
SsaEnv* outer_env = ssa_env_;
SsaEnv* try_env = Steal(outer_env);
......@@ -865,7 +866,7 @@ class WasmFullDecoder : public WasmDecoder {
break;
}
case kExprCatch: {
CHECK_PROTOTYPE_OPCODE(wasm_eh_prototype);
CHECK_PROTOTYPE_OPCODE(eh);
LocalIndexOperand<true> operand(this, pc_);
len = 1 + operand.length;
......@@ -1262,7 +1263,7 @@ class WasmFullDecoder : public WasmDecoder {
len = DecodeLoadMem(kWasmF64, MachineType::Float64());
break;
case kExprS128LoadMem:
CHECK_PROTOTYPE_OPCODE(wasm_simd_prototype);
CHECK_PROTOTYPE_OPCODE(simd);
len = DecodeLoadMem(kWasmS128, MachineType::Simd128());
break;
case kExprI32StoreMem8:
......@@ -1293,7 +1294,7 @@ class WasmFullDecoder : public WasmDecoder {
len = DecodeStoreMem(kWasmF64, MachineType::Float64());
break;
case kExprS128StoreMem:
CHECK_PROTOTYPE_OPCODE(wasm_simd_prototype);
CHECK_PROTOTYPE_OPCODE(simd);
len = DecodeStoreMem(kWasmS128, MachineType::Simd128());
break;
case kExprGrowMemory: {
......@@ -1341,7 +1342,7 @@ class WasmFullDecoder : public WasmDecoder {
break;
}
case kSimdPrefix: {
CHECK_PROTOTYPE_OPCODE(wasm_simd_prototype);
CHECK_PROTOTYPE_OPCODE(simd);
len++;
byte simd_index = read_u8<true>(pc_ + 1, "simd index");
opcode = static_cast<WasmOpcode>(opcode << 8 | simd_index);
......@@ -1355,10 +1356,7 @@ class WasmFullDecoder : public WasmDecoder {
error("Atomics are allowed only in AsmJs modules");
break;
}
if (!FLAG_wasm_atomics_prototype) {
error("Invalid opcode (enable with --wasm_atomics_prototype)");
break;
}
CHECK_PROTOTYPE_OPCODE(atomics);
len = 2;
byte atomic_opcode = read_u8<true>(pc_ + 1, "atomic index");
opcode = static_cast<WasmOpcode>(opcode << 8 | atomic_opcode);
......
......@@ -1163,7 +1163,7 @@ class ModuleDecoder : public Decoder {
case kLocalF64:
return kWasmF64;
default:
if (origin_ != kAsmJsOrigin && FLAG_wasm_simd_prototype) {
if (origin_ != kAsmJsOrigin && FLAG_experimental_wasm_simd) {
switch (t) {
case kLocalS128:
return kWasmS128;
......@@ -1196,7 +1196,7 @@ class ModuleDecoder : public Decoder {
}
// parse return types
const size_t max_return_count = FLAG_wasm_mv_prototype
const size_t max_return_count = FLAG_experimental_wasm_mv
? kV8MaxWasmFunctionMultiReturns
: kV8MaxWasmFunctionReturns;
uint32_t return_count = consume_count("return count", max_return_count);
......
......@@ -11,8 +11,9 @@ v8_executable("cctest") {
"$target_gen_dir/resources.cc",
### gcmole(all) ###
"../common/wasm/test-signatures.h",
"../common/wasm/wasm-macro-gen.h",
"../../test/common/wasm/flag-utils.h",
"../../test/common/wasm/test-signatures.h",
"../../test/common/wasm/wasm-macro-gen.h",
"ast-types-fuzz.h",
"cctest.cc",
"cctest.h",
......
......@@ -336,6 +336,7 @@
'../..',
],
'sources': [
'../common/wasm/flag-utils.h',
'../common/wasm/test-signatures.h',
'../common/wasm/wasm-macro-gen.h',
'../common/wasm/wasm-module-runner.cc',
......
This diff is collapsed.
......@@ -109,14 +109,14 @@ static void RunInt32AddTest(WasmExecutionMode execution_mode, const byte* code,
}
WASM_EXEC_TEST(Int32Add_P2) {
FLAG_wasm_mv_prototype = true;
EXPERIMENTAL_FLAG_SCOPE(mv);
static const byte code[] = {
WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))};
RunInt32AddTest(execution_mode, code, sizeof(code));
}
WASM_EXEC_TEST(Int32Add_block1) {
FLAG_wasm_mv_prototype = true;
EXPERIMENTAL_FLAG_SCOPE(mv);
static const byte code[] = {
WASM_BLOCK_TT(kWasmI32, kWasmI32, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
kExprI32Add};
......@@ -124,7 +124,7 @@ WASM_EXEC_TEST(Int32Add_block1) {
}
WASM_EXEC_TEST(Int32Add_block2) {
FLAG_wasm_mv_prototype = true;
EXPERIMENTAL_FLAG_SCOPE(mv);
static const byte code[] = {
WASM_BLOCK_TT(kWasmI32, kWasmI32, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
kExprBr, DEPTH_0),
......@@ -133,7 +133,7 @@ WASM_EXEC_TEST(Int32Add_block2) {
}
WASM_EXEC_TEST(Int32Add_multi_if) {
FLAG_wasm_mv_prototype = true;
EXPERIMENTAL_FLAG_SCOPE(mv);
static const byte code[] = {
WASM_IF_ELSE_TT(kWasmI32, kWasmI32, WASM_GET_LOCAL(0),
WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
......@@ -2398,7 +2398,7 @@ WASM_EXEC_TEST(AddCall) {
}
WASM_EXEC_TEST(MultiReturnSub) {
FLAG_wasm_mv_prototype = true;
EXPERIMENTAL_FLAG_SCOPE(mv);
WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
ValueType storage[] = {kWasmI32, kWasmI32, kWasmI32, kWasmI32};
......@@ -2420,7 +2420,7 @@ WASM_EXEC_TEST(MultiReturnSub) {
template <typename T>
void RunMultiReturnSelect(WasmExecutionMode execution_mode, const T* inputs) {
FLAG_wasm_mv_prototype = true;
EXPERIMENTAL_FLAG_SCOPE(mv);
ValueType type = WasmOpcodes::ValueTypeFor(MachineTypeForC<T>());
ValueType storage[] = {type, type, type, type, type, type};
const size_t kNumReturns = 2;
......
......@@ -13,8 +13,6 @@
#include <memory>
#include "src/base/utils/random-number-generator.h"
#include "src/zone/accounting-allocator.h"
#include "src/compiler/compiler-source-position-table.h"
#include "src/compiler/graph-visualizer.h"
#include "src/compiler/int64-lowering.h"
......@@ -32,12 +30,13 @@
#include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-objects.h"
#include "src/wasm/wasm-opcodes.h"
#include "src/zone/accounting-allocator.h"
#include "src/zone/zone.h"
#include "test/cctest/cctest.h"
#include "test/cctest/compiler/call-tester.h"
#include "test/cctest/compiler/graph-builder-tester.h"
#include "test/common/wasm/flag-utils.h"
static const uint32_t kMaxFunctions = 10;
......@@ -839,11 +838,6 @@ bool WasmRunnerBase::trap_happened;
} \
void RunWasm_##name(WasmExecutionMode execution_mode)
#define WASM_EXEC_COMPILED_TEST(name) \
void RunWasm_##name(WasmExecutionMode execution_mode); \
TEST(RunWasmCompiled_##name) { RunWasm_##name(kExecuteCompiled); } \
void RunWasm_##name(WasmExecutionMode execution_mode)
} // namespace
#endif
// Copyright 2017 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.
#ifndef V8_TEST_COMMON_FLAG_UTILS_H
#define V8_TEST_COMMON_FLAG_UTILS_H
class EnableFlagScope {
public:
EnableFlagScope(bool* flag, bool new_value = true)
: flag_(flag), previous_value_(flag) {
*flag = new_value;
}
~EnableFlagScope() { *flag_ = previous_value_; }
private:
bool* flag_;
bool previous_value_;
};
#define EXPERIMENTAL_FLAG_SCOPE(flag) \
EnableFlagScope __flag_scope_##__LINE__(&FLAG_experimental_wasm_##flag)
#endif // V8_TEST_COMMON_FLAG_UTILS_H
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --expose-wasm --wasm-eh-prototype
// Flags: --expose-wasm --experimental-wasm-eh
load("test/mjsunit/wasm/wasm-constants.js");
load("test/mjsunit/wasm/wasm-module-builder.js");
......
......@@ -15,12 +15,13 @@
#include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-opcodes.h"
#include "test/common/wasm/flag-utils.h"
#include "test/common/wasm/test-signatures.h"
#include "test/common/wasm/wasm-macro-gen.h"
namespace v8 {
namespace internal {
namespace wasm {
using namespace v8::internal;
using namespace v8::internal::wasm;
using namespace v8::internal::wasm::testing;
#define B1(a) WASM_BLOCK(a)
#define B2(a, b) WASM_BLOCK(a, b)
......@@ -82,21 +83,12 @@ static const WasmOpcode kInt32BinopOpcodes[] = {
Verify(false, sigs.sig(), code, code + sizeof(code)); \
} while (false)
static bool old_eh_flag;
class FunctionBodyDecoderTest : public TestWithZone {
public:
typedef std::pair<uint32_t, ValueType> LocalsDecl;
FunctionBodyDecoderTest() : module(nullptr), local_decls(zone()) {}
static void SetUpTestCase() { old_eh_flag = FLAG_wasm_eh_prototype; }
static void TearDownTestCase() {
// Reset the wasm_eh_prototype flag
FLAG_wasm_eh_prototype = old_eh_flag;
}
TestSignatures sigs;
ModuleEnv* module;
LocalDeclEncoder local_decls;
......@@ -1446,7 +1438,7 @@ TEST_F(FunctionBodyDecoderTest, CallsWithMismatchedSigs3) {
}
TEST_F(FunctionBodyDecoderTest, MultiReturn) {
FLAG_wasm_mv_prototype = true;
EXPERIMENTAL_FLAG_SCOPE(mv);
ValueType storage[] = {kWasmI32, kWasmI32};
FunctionSig sig_ii_v(2, 0, storage);
FunctionSig sig_v_ii(0, 2, storage);
......@@ -1462,7 +1454,7 @@ TEST_F(FunctionBodyDecoderTest, MultiReturn) {
}
TEST_F(FunctionBodyDecoderTest, MultiReturnType) {
FLAG_wasm_mv_prototype = true;
EXPERIMENTAL_FLAG_SCOPE(mv);
for (size_t a = 0; a < arraysize(kValueTypes); a++) {
for (size_t b = 0; b < arraysize(kValueTypes); b++) {
for (size_t c = 0; c < arraysize(kValueTypes); c++) {
......@@ -2247,7 +2239,7 @@ TEST_F(FunctionBodyDecoderTest, Select_TypeCheck) {
}
TEST_F(FunctionBodyDecoderTest, Throw) {
FLAG_wasm_eh_prototype = true;
EXPERIMENTAL_FLAG_SCOPE(eh);
EXPECT_VERIFIES(v_i, WASM_GET_LOCAL(0), kExprThrow);
EXPECT_FAILURE(i_d, WASM_GET_LOCAL(0), kExprThrow, WASM_I32V(0));
......@@ -2257,7 +2249,7 @@ TEST_F(FunctionBodyDecoderTest, Throw) {
TEST_F(FunctionBodyDecoderTest, ThrowUnreachable) {
// TODO(titzer): unreachable code after throw should validate.
// FLAG_wasm_eh_prototype = true;
// EXPERIMENTAL_FLAG_SCOPE(eh);
// EXPECT_VERIFIES(v_i, WASM_GET_LOCAL(0), kExprThrow, kExprSetLocal, 0);
}
......@@ -2266,7 +2258,7 @@ TEST_F(FunctionBodyDecoderTest, ThrowUnreachable) {
#define WASM_CATCH(local) kExprCatch, static_cast<byte>(local)
TEST_F(FunctionBodyDecoderTest, TryCatch) {
FLAG_wasm_eh_prototype = true;
EXPERIMENTAL_FLAG_SCOPE(eh);
EXPECT_VERIFIES(v_i, WASM_TRY_OP, WASM_CATCH(0), kExprEnd);
// Missing catch.
......@@ -2280,21 +2272,21 @@ TEST_F(FunctionBodyDecoderTest, TryCatch) {
}
TEST_F(FunctionBodyDecoderTest, MultiValBlock1) {
FLAG_wasm_mv_prototype = true;
EXPERIMENTAL_FLAG_SCOPE(mv);
EXPECT_VERIFIES(i_ii, WASM_BLOCK_TT(kWasmI32, kWasmI32, WASM_GET_LOCAL(0),
WASM_GET_LOCAL(1)),
kExprI32Add);
}
TEST_F(FunctionBodyDecoderTest, MultiValBlock2) {
FLAG_wasm_mv_prototype = true;
EXPERIMENTAL_FLAG_SCOPE(mv);
EXPECT_VERIFIES(i_ii, WASM_BLOCK_TT(kWasmI32, kWasmI32, WASM_GET_LOCAL(0),
WASM_GET_LOCAL(1)),
WASM_I32_ADD(WASM_NOP, WASM_NOP));
}
TEST_F(FunctionBodyDecoderTest, MultiValBlockBr1) {
FLAG_wasm_mv_prototype = true;
EXPERIMENTAL_FLAG_SCOPE(mv);
EXPECT_FAILURE(
i_ii, WASM_BLOCK_TT(kWasmI32, kWasmI32, WASM_GET_LOCAL(0), WASM_BR(0)),
kExprI32Add);
......@@ -2304,7 +2296,7 @@ TEST_F(FunctionBodyDecoderTest, MultiValBlockBr1) {
}
TEST_F(FunctionBodyDecoderTest, MultiValIf1) {
FLAG_wasm_mv_prototype = true;
EXPERIMENTAL_FLAG_SCOPE(mv);
EXPECT_FAILURE(
i_ii, WASM_IF_ELSE_TT(kWasmI32, kWasmI32, WASM_GET_LOCAL(0),
WASM_SEQ(WASM_GET_LOCAL(0)),
......@@ -2826,7 +2818,3 @@ TEST_F(BytecodeIteratorTest, WithLocalDecls) {
iter.next();
EXPECT_FALSE(iter.has_next());
}
} // namespace wasm
} // namespace internal
} // namespace v8
......@@ -9,6 +9,7 @@
#include "src/wasm/module-decoder.h"
#include "src/wasm/wasm-limits.h"
#include "src/wasm/wasm-opcodes.h"
#include "test/common/wasm/flag-utils.h"
#include "test/common/wasm/wasm-macro-gen.h"
namespace v8 {
......@@ -833,18 +834,16 @@ TEST_F(WasmSignatureDecodeTest, TooManyParams) {
}
TEST_F(WasmSignatureDecodeTest, TooManyReturns) {
bool prev = FLAG_wasm_mv_prototype;
for (int i = 0; i < 2; i++) {
FLAG_wasm_mv_prototype = i != 0;
const int max_return_count =
static_cast<int>(FLAG_wasm_mv_prototype ? kV8MaxWasmFunctionMultiReturns
: kV8MaxWasmFunctionReturns);
EnableFlagScope flag_scope(&FLAG_experimental_wasm_mv, i != 0);
const int max_return_count = static_cast<int>(
FLAG_experimental_wasm_mv ? kV8MaxWasmFunctionMultiReturns
: kV8MaxWasmFunctionReturns);
byte data[] = {kWasmFunctionTypeForm, 0, WASM_I32V_3(max_return_count + 1),
kLocalI32};
FunctionSig* sig =
DecodeWasmSignatureForTesting(zone(), data, data + sizeof(data));
EXPECT_EQ(nullptr, sig);
FLAG_wasm_mv_prototype = prev;
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment