summaryrefslogtreecommitdiff
path: root/deps/v8/test/fuzzer
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/fuzzer')
-rw-r--r--deps/v8/test/fuzzer/multi-return.cc5
-rw-r--r--deps/v8/test/fuzzer/regexp-builtins.cc14
-rw-r--r--deps/v8/test/fuzzer/wasm-async.cc4
-rw-r--r--deps/v8/test/fuzzer/wasm-compile.cc21
-rw-r--r--deps/v8/test/fuzzer/wasm-fuzzer-common.cc49
-rw-r--r--deps/v8/test/fuzzer/wasm.cc8
6 files changed, 65 insertions, 36 deletions
diff --git a/deps/v8/test/fuzzer/multi-return.cc b/deps/v8/test/fuzzer/multi-return.cc
index 4f109228a5..0be812c8dd 100644
--- a/deps/v8/test/fuzzer/multi-return.cc
+++ b/deps/v8/test/fuzzer/multi-return.cc
@@ -19,6 +19,7 @@
#include "src/optimized-compilation-info.h"
#include "src/simulator.h"
#include "src/wasm/wasm-engine.h"
+#include "src/wasm/wasm-features.h"
#include "src/wasm/wasm-limits.h"
#include "src/wasm/wasm-objects-inl.h"
#include "src/wasm/wasm-objects.h"
@@ -160,7 +161,8 @@ std::unique_ptr<wasm::NativeModule> AllocateNativeModule(i::Isolate* isolate,
// WasmCallDescriptor assumes that code is on the native heap and not
// within a code object.
return isolate->wasm_engine()->code_manager()->NewNativeModule(
- isolate, code_size, false, std::move(module), env);
+ isolate, i::wasm::kAllWasmFeatures, code_size, false, std::move(module),
+ env);
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
@@ -306,6 +308,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
&wrapper_info, i_isolate, wrapper_desc, caller.graph(),
AssemblerOptions::Default(i_isolate), caller.Export())
.ToHandleChecked();
+
auto fn = GeneratedCode<int32_t>::FromCode(*wrapper_code);
int result = fn.Call();
diff --git a/deps/v8/test/fuzzer/regexp-builtins.cc b/deps/v8/test/fuzzer/regexp-builtins.cc
index 495604b071..c4ff115d72 100644
--- a/deps/v8/test/fuzzer/regexp-builtins.cc
+++ b/deps/v8/test/fuzzer/regexp-builtins.cc
@@ -319,12 +319,12 @@ std::string GenerateSourceString(FuzzerArgs* args, const std::string& test) {
return ss.str();
}
-void PrintExceptionMessage(v8::TryCatch* try_catch) {
+void PrintExceptionMessage(v8::Isolate* isolate, v8::TryCatch* try_catch) {
CHECK(try_catch->HasCaught());
static const int kBufferLength = 256;
char buffer[kBufferLength + 1];
try_catch->Message()->Get()->WriteOneByte(
- reinterpret_cast<uint8_t*>(&buffer[0]), 0, kBufferLength);
+ isolate, reinterpret_cast<uint8_t*>(&buffer[0]), 0, kBufferLength);
fprintf(stderr, "%s\n", buffer);
}
@@ -337,9 +337,10 @@ bool ResultsAreIdentical(FuzzerArgs* args) {
"assertEquals(fast.re.lastIndex, slow.re.lastIndex);\n";
v8::Local<v8::Value> result;
- v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(args->isolate));
+ v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(args->isolate);
+ v8::TryCatch try_catch(isolate);
if (!CompileRun(args->context, source.c_str()).ToLocal(&result)) {
- PrintExceptionMessage(&try_catch);
+ PrintExceptionMessage(isolate, &try_catch);
args->isolate->clear_pending_exception();
return false;
}
@@ -349,14 +350,15 @@ bool ResultsAreIdentical(FuzzerArgs* args) {
void CompileRunAndVerify(FuzzerArgs* args, const std::string& source) {
v8::Local<v8::Value> result;
- v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(args->isolate));
+ v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(args->isolate);
+ v8::TryCatch try_catch(isolate);
if (!CompileRun(args->context, source.c_str()).ToLocal(&result)) {
args->isolate->clear_pending_exception();
// No need to verify result if an exception was thrown here, since that
// implies a syntax error somewhere in the pattern or string. We simply
// ignore those.
if (kVerbose) {
- PrintExceptionMessage(&try_catch);
+ PrintExceptionMessage(isolate, &try_catch);
fprintf(stderr, "Failed to run script:\n```\n%s\n```\n", source.c_str());
}
return;
diff --git a/deps/v8/test/fuzzer/wasm-async.cc b/deps/v8/test/fuzzer/wasm-async.cc
index 5ceb8d8bf8..8e140b71f2 100644
--- a/deps/v8/test/fuzzer/wasm-async.cc
+++ b/deps/v8/test/fuzzer/wasm-async.cc
@@ -68,8 +68,10 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
testing::SetupIsolateForWasmModule(i_isolate);
bool done = false;
+ auto enabled_features = i::wasm::WasmFeaturesFromIsolate(i_isolate);
i_isolate->wasm_engine()->AsyncCompile(
- i_isolate, base::make_unique<AsyncFuzzerResolver>(i_isolate, &done),
+ i_isolate, enabled_features,
+ std::make_shared<AsyncFuzzerResolver>(i_isolate, &done),
ModuleWireBytes(data, data + size), false);
// Wait for the promise to resolve.
diff --git a/deps/v8/test/fuzzer/wasm-compile.cc b/deps/v8/test/fuzzer/wasm-compile.cc
index 93c03a92db..a9f4382cd1 100644
--- a/deps/v8/test/fuzzer/wasm-compile.cc
+++ b/deps/v8/test/fuzzer/wasm-compile.cc
@@ -43,8 +43,10 @@ class DataRange {
// lead to OOM because the end might not be reached.
// Define move constructor and move assignment, disallow copy constructor and
// copy assignment (below).
- DataRange(DataRange&& other) : DataRange(other.data_) { other.data_ = {}; }
- DataRange& operator=(DataRange&& other) {
+ DataRange(DataRange&& other) V8_NOEXCEPT : DataRange(other.data_) {
+ other.data_ = {};
+ }
+ DataRange& operator=(DataRange&& other) V8_NOEXCEPT {
data_ = other.data_;
other.data_ = {};
return *this;
@@ -380,9 +382,9 @@ class WasmGenerator {
void set_global(DataRange& data) { global_op<kWasmStmt>(data); }
- template <ValueType T1, ValueType T2>
+ template <ValueType... Types>
void sequence(DataRange& data) {
- Generate<T1, T2>(data);
+ Generate<Types...>(data);
}
void current_memory(DataRange& data) {
@@ -472,6 +474,9 @@ void WasmGenerator::Generate<kWasmStmt>(DataRange& data) {
constexpr generate_fn alternates[] = {
&WasmGenerator::sequence<kWasmStmt, kWasmStmt>,
+ &WasmGenerator::sequence<kWasmStmt, kWasmStmt, kWasmStmt, kWasmStmt>,
+ &WasmGenerator::sequence<kWasmStmt, kWasmStmt, kWasmStmt, kWasmStmt,
+ kWasmStmt, kWasmStmt, kWasmStmt, kWasmStmt>,
&WasmGenerator::block<kWasmStmt>,
&WasmGenerator::loop<kWasmStmt>,
&WasmGenerator::if_<kWasmStmt, kIf>,
@@ -508,7 +513,9 @@ void WasmGenerator::Generate<kWasmI32>(DataRange& data) {
}
constexpr generate_fn alternates[] = {
+ &WasmGenerator::sequence<kWasmI32, kWasmStmt>,
&WasmGenerator::sequence<kWasmStmt, kWasmI32>,
+ &WasmGenerator::sequence<kWasmStmt, kWasmI32, kWasmStmt>,
&WasmGenerator::op<kExprI32Eqz, kWasmI32>,
&WasmGenerator::op<kExprI32Eq, kWasmI32, kWasmI32>,
@@ -597,7 +604,9 @@ void WasmGenerator::Generate<kWasmI64>(DataRange& data) {
}
constexpr generate_fn alternates[] = {
+ &WasmGenerator::sequence<kWasmI64, kWasmStmt>,
&WasmGenerator::sequence<kWasmStmt, kWasmI64>,
+ &WasmGenerator::sequence<kWasmStmt, kWasmI64, kWasmStmt>,
&WasmGenerator::op<kExprI64Add, kWasmI64, kWasmI64>,
&WasmGenerator::op<kExprI64Sub, kWasmI64, kWasmI64>,
@@ -652,7 +661,9 @@ void WasmGenerator::Generate<kWasmF32>(DataRange& data) {
}
constexpr generate_fn alternates[] = {
+ &WasmGenerator::sequence<kWasmF32, kWasmStmt>,
&WasmGenerator::sequence<kWasmStmt, kWasmF32>,
+ &WasmGenerator::sequence<kWasmStmt, kWasmF32, kWasmStmt>,
&WasmGenerator::op<kExprF32Add, kWasmF32, kWasmF32>,
&WasmGenerator::op<kExprF32Sub, kWasmF32, kWasmF32>,
@@ -683,7 +694,9 @@ void WasmGenerator::Generate<kWasmF64>(DataRange& data) {
}
constexpr generate_fn alternates[] = {
+ &WasmGenerator::sequence<kWasmF64, kWasmStmt>,
&WasmGenerator::sequence<kWasmStmt, kWasmF64>,
+ &WasmGenerator::sequence<kWasmStmt, kWasmF64, kWasmStmt>,
&WasmGenerator::op<kExprF64Add, kWasmF64, kWasmF64>,
&WasmGenerator::op<kExprF64Sub, kWasmF64, kWasmF64>,
diff --git a/deps/v8/test/fuzzer/wasm-fuzzer-common.cc b/deps/v8/test/fuzzer/wasm-fuzzer-common.cc
index f84e700fc9..c253da9cb5 100644
--- a/deps/v8/test/fuzzer/wasm-fuzzer-common.cc
+++ b/deps/v8/test/fuzzer/wasm-fuzzer-common.cc
@@ -10,7 +10,7 @@
#include "src/wasm/wasm-engine.h"
#include "src/wasm/wasm-module-builder.h"
#include "src/wasm/wasm-module.h"
-#include "src/wasm/wasm-objects.h"
+#include "src/wasm/wasm-objects-inl.h"
#include "src/zone/accounting-allocator.h"
#include "src/zone/zone.h"
#include "test/common/wasm/flag-utils.h"
@@ -153,9 +153,10 @@ std::ostream& operator<<(std::ostream& os, const PrintName& name) {
void GenerateTestCase(Isolate* isolate, ModuleWireBytes wire_bytes,
bool compiles) {
constexpr bool kVerifyFunctions = false;
- ModuleResult module_res =
- SyncDecodeWasmModule(isolate, wire_bytes.start(), wire_bytes.end(),
- kVerifyFunctions, ModuleOrigin::kWasmOrigin);
+ auto enabled_features = i::wasm::WasmFeaturesFromIsolate(isolate);
+ ModuleResult module_res = DecodeWasmModule(
+ enabled_features, wire_bytes.start(), wire_bytes.end(), kVerifyFunctions,
+ ModuleOrigin::kWasmOrigin, isolate->counters(), isolate->allocator());
CHECK(module_res.ok());
WasmModule* module = module_res.val.get();
CHECK_NOT_NULL(module);
@@ -181,7 +182,7 @@ void GenerateTestCase(Isolate* isolate, ModuleWireBytes wire_bytes,
os << ", undefined";
}
os << ", " << (module->mem_export ? "true" : "false");
- if (FLAG_experimental_wasm_threads && module->has_shared_memory) {
+ if (module->has_shared_memory) {
os << ", shared";
}
os << ");\n";
@@ -208,7 +209,8 @@ void GenerateTestCase(Isolate* isolate, ModuleWireBytes wire_bytes,
// Add locals.
BodyLocalDecls decls(&tmp_zone);
- DecodeLocalDecls(&decls, func_code.start(), func_code.end());
+ DecodeLocalDecls(enabled_features, &decls, func_code.start(),
+ func_code.end());
if (!decls.type_list.empty()) {
os << " ";
for (size_t pos = 0, count = 1, locals = decls.type_list.size();
@@ -284,6 +286,7 @@ int WasmExecutionFuzzer::FuzzWasmModule(Vector<const uint8_t> data,
ModuleWireBytes wire_bytes(buffer.begin(), buffer.end());
// Compile with Turbofan here. Liftoff will be tested later.
+ auto enabled_features = i::wasm::WasmFeaturesFromIsolate(i_isolate);
MaybeHandle<WasmModuleObject> compiled_module;
{
// Explicitly enable Liftoff, disable tiering and set the tier_mask. This
@@ -292,7 +295,7 @@ int WasmExecutionFuzzer::FuzzWasmModule(Vector<const uint8_t> data,
FlagScope<bool> no_tier_up(&FLAG_wasm_tier_up, false);
FlagScope<int> tier_mask_scope(&FLAG_wasm_tier_mask_for_testing, tier_mask);
compiled_module = i_isolate->wasm_engine()->SyncCompile(
- i_isolate, &interpreter_thrower, wire_bytes);
+ i_isolate, enabled_features, &interpreter_thrower, wire_bytes);
}
bool compiles = !compiled_module.is_null();
@@ -300,8 +303,8 @@ int WasmExecutionFuzzer::FuzzWasmModule(Vector<const uint8_t> data,
GenerateTestCase(i_isolate, wire_bytes, compiles);
}
- bool validates =
- i_isolate->wasm_engine()->SyncValidate(i_isolate, wire_bytes);
+ bool validates = i_isolate->wasm_engine()->SyncValidate(
+ i_isolate, enabled_features, wire_bytes);
CHECK_EQ(compiles, validates);
CHECK_IMPLIES(require_valid, validates);
@@ -332,6 +335,16 @@ int WasmExecutionFuzzer::FuzzWasmModule(Vector<const uint8_t> data,
return 0;
}
+ // The WebAssembly spec allows the sign bit of NaN to be non-deterministic.
+ // This sign bit can make the difference between an infinite loop and
+ // terminating code. With possible non-determinism we cannot guarantee that
+ // the generated code will not go into an infinite loop and cause a timeout in
+ // Clusterfuzz. Therefore we do not execute the generated code if the result
+ // may be non-deterministic.
+ if (possible_nondeterminism) {
+ return 0;
+ }
+
bool expect_exception =
result_interpreter == static_cast<int32_t>(0xDEADBEEF);
@@ -349,20 +362,14 @@ int WasmExecutionFuzzer::FuzzWasmModule(Vector<const uint8_t> data,
"main", num_args, compiler_args.get());
}
- // The WebAssembly spec allows the sign bit of NaN to be non-deterministic.
- // This sign bit may cause result_interpreter to be different than
- // result_compiled. Therefore we do not check the equality of the results
- // if the execution may have produced a NaN at some point.
- if (!possible_nondeterminism) {
- if (expect_exception != i_isolate->has_pending_exception()) {
- const char* exception_text[] = {"no exception", "exception"};
- FATAL("interpreter: %s; compiled: %s", exception_text[expect_exception],
- exception_text[i_isolate->has_pending_exception()]);
- }
-
- if (!expect_exception) CHECK_EQ(result_interpreter, result_compiled);
+ if (expect_exception != i_isolate->has_pending_exception()) {
+ const char* exception_text[] = {"no exception", "exception"};
+ FATAL("interpreter: %s; compiled: %s", exception_text[expect_exception],
+ exception_text[i_isolate->has_pending_exception()]);
}
+ if (!expect_exception) CHECK_EQ(result_interpreter, result_compiled);
+
// Cleanup any pending exception.
i_isolate->clear_pending_exception();
return 0;
diff --git a/deps/v8/test/fuzzer/wasm.cc b/deps/v8/test/fuzzer/wasm.cc
index 75a6dd9865..fb9135b0f1 100644
--- a/deps/v8/test/fuzzer/wasm.cc
+++ b/deps/v8/test/fuzzer/wasm.cc
@@ -42,9 +42,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
i::HandleScope scope(i_isolate);
i::wasm::ErrorThrower thrower(i_isolate, "wasm fuzzer");
i::Handle<i::WasmModuleObject> module_object;
- bool compiles = i_isolate->wasm_engine()
- ->SyncCompile(i_isolate, &thrower, wire_bytes)
- .ToHandle(&module_object);
+ auto enabled_features = i::wasm::WasmFeaturesFromIsolate(i_isolate);
+ bool compiles =
+ i_isolate->wasm_engine()
+ ->SyncCompile(i_isolate, enabled_features, &thrower, wire_bytes)
+ .ToHandle(&module_object);
if (i::FLAG_wasm_fuzzer_gen_test) {
i::wasm::fuzzer::GenerateTestCase(i_isolate, wire_bytes, compiles);