Line data Source code
1 : // Copyright 2017 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include <limits.h>
6 : #include <stddef.h>
7 : #include <stdint.h>
8 :
9 : #include "include/v8.h"
10 : #include "src/api.h"
11 : #include "src/factory.h"
12 : #include "src/isolate-inl.h"
13 : #include "src/isolate.h"
14 : #include "src/objects-inl.h"
15 : #include "src/objects.h"
16 : #include "src/wasm/module-compiler.h"
17 : #include "src/wasm/wasm-api.h"
18 : #include "src/wasm/wasm-module.h"
19 : #include "test/common/wasm/flag-utils.h"
20 : #include "test/common/wasm/wasm-module-runner.h"
21 : #include "test/fuzzer/fuzzer-support.h"
22 : #include "test/fuzzer/wasm-fuzzer-common.h"
23 :
24 : namespace v8 {
25 : namespace internal {
26 : class WasmModuleObject;
27 :
28 : namespace wasm {
29 : namespace fuzzer {
30 :
31 : #define ASSIGN(type, var, expr) \
32 : v8::Local<type> var; \
33 : do { \
34 : if (!expr.ToLocal(&var)) { \
35 : DCHECK(i_isolate->has_scheduled_exception()); \
36 : return 0; \
37 : } else { \
38 : DCHECK(!i_isolate->has_scheduled_exception()); \
39 : } \
40 : } while (false)
41 :
42 : namespace {
43 : // We need this helper function because we cannot use
44 : // Handle<WasmModuleObject>::cast here. To use this function we would have to
45 : // mark it with V8_EXPORT_PRIVATE, which is quite ugly in this case.
46 2 : Handle<WasmModuleObject> ToWasmModuleObjectUnchecked(Handle<Object> that) {
47 2 : return handle(reinterpret_cast<WasmModuleObject*>(*that));
48 : }
49 : }
50 :
51 2 : void InstantiateCallback(const FunctionCallbackInfo<Value>& args) {
52 : DCHECK_GE(args.Length(), 1);
53 : v8::Isolate* isolate = args.GetIsolate();
54 : MicrotasksScope does_not_run_microtasks(
55 2 : isolate, v8::MicrotasksScope::kDoNotRunMicrotasks);
56 :
57 4 : v8::HandleScope scope(isolate);
58 :
59 : Local<v8::Value> module = args[0];
60 :
61 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
62 :
63 : Handle<WasmModuleObject> module_obj =
64 2 : ToWasmModuleObjectUnchecked(Utils::OpenHandle(v8::Object::Cast(*module)));
65 4 : InterpretAndExecuteModule(i_isolate, module_obj);
66 2 : }
67 :
68 3 : extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
69 : FlagScope<bool> turn_on_async_compile(
70 : &v8::internal::FLAG_wasm_async_compilation, true);
71 : FlagScope<uint32_t> max_mem_flag_scope(&v8::internal::FLAG_wasm_max_mem_pages,
72 : 32);
73 : FlagScope<uint32_t> max_table_size_scope(
74 : &v8::internal::FLAG_wasm_max_table_size, 100);
75 3 : v8_fuzzer::FuzzerSupport* support = v8_fuzzer::FuzzerSupport::Get();
76 3 : v8::Isolate* isolate = support->GetIsolate();
77 : i::Isolate* i_isolate = reinterpret_cast<v8::internal::Isolate*>(isolate);
78 :
79 : // Clear any pending exceptions from a prior run.
80 3 : if (i_isolate->has_pending_exception()) {
81 : i_isolate->clear_pending_exception();
82 : }
83 :
84 : v8::Isolate::Scope isolate_scope(isolate);
85 6 : v8::HandleScope handle_scope(isolate);
86 : i::HandleScope internal_scope(i_isolate);
87 3 : v8::Context::Scope context_scope(support->GetContext());
88 6 : TryCatch try_catch(isolate);
89 3 : testing::SetupIsolateForWasmModule(i_isolate);
90 :
91 : // Get the promise for async compilation.
92 6 : ASSIGN(Promise::Resolver, resolver,
93 : Promise::Resolver::New(support->GetContext()));
94 3 : Local<Promise> promise = resolver->GetPromise();
95 :
96 : AsyncCompile(i_isolate, Utils::OpenHandle(*promise),
97 6 : ModuleWireBytes(data, data + size));
98 :
99 6 : ASSIGN(Function, instantiate_impl,
100 : Function::New(support->GetContext(), &InstantiateCallback,
101 : Undefined(isolate)));
102 :
103 6 : ASSIGN(Promise, result,
104 : promise->Then(support->GetContext(), instantiate_impl));
105 :
106 : // Wait for the promise to resolve.
107 14 : while (result->State() == Promise::kPending) {
108 11 : support->PumpMessageLoop(platform::MessageLoopBehavior::kWaitForWork);
109 11 : isolate->RunMicrotasks();
110 : }
111 : return 0;
112 : }
113 :
114 : #undef ASSIGN
115 :
116 : } // namespace fuzzer
117 : } // namespace wasm
118 : } // namespace internal
119 : } // namespace v8
|