| OLD | NEW |
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <stddef.h> | 5 #include <stddef.h> |
| 6 #include <stdint.h> | 6 #include <stdint.h> |
| 7 | 7 |
| 8 #include "include/v8.h" | 8 #include "include/v8.h" |
| 9 #include "src/isolate.h" | 9 #include "src/isolate.h" |
| 10 #include "src/objects.h" | 10 #include "src/objects.h" |
| 11 #include "src/utils.h" |
| 11 #include "src/wasm/wasm-interpreter.h" | 12 #include "src/wasm/wasm-interpreter.h" |
| 12 #include "src/wasm/wasm-module-builder.h" | 13 #include "src/wasm/wasm-module-builder.h" |
| 13 #include "src/wasm/wasm-module.h" | 14 #include "src/wasm/wasm-module.h" |
| 14 #include "test/common/wasm/test-signatures.h" | 15 #include "test/common/wasm/test-signatures.h" |
| 15 #include "test/common/wasm/wasm-module-runner.h" | 16 #include "test/common/wasm/wasm-module-runner.h" |
| 16 #include "test/fuzzer/fuzzer-support.h" | 17 #include "test/fuzzer/fuzzer-support.h" |
| 17 | 18 |
| 18 #define WASM_CODE_FUZZER_HASH_SEED 83 | 19 #define WASM_CODE_FUZZER_HASH_SEED 83 |
| 19 #define MAX_NUM_FUNCTIONS 3 | 20 #define MAX_NUM_FUNCTIONS 3 |
| 20 #define MAX_NUM_PARAMS 3 | 21 #define MAX_NUM_PARAMS 3 |
| 21 | 22 |
| 22 #define FUZZER_TYPE_FLOAT32 0 | |
| 23 #define FUZZER_TYPE_FLOAT64 1 | |
| 24 #define FUZZER_TYPE_INT32 2 | |
| 25 #define FUZZER_TYPE_INT64 3 | |
| 26 | |
| 27 using namespace v8::internal::wasm; | 23 using namespace v8::internal::wasm; |
| 28 | 24 |
| 29 template <typename V> | 25 template <typename V> |
| 30 static inline V read_value(const uint8_t** data, size_t* size, bool* ok) { | 26 static inline V read_value(const uint8_t** data, size_t* size, bool* ok) { |
| 31 // The status flag {ok} checks that the decoding up until now was okay, and | 27 // The status flag {ok} checks that the decoding up until now was okay, and |
| 32 // that a value of type V can be read without problems. | 28 // that a value of type V can be read without problems. |
| 33 *ok &= (*size > sizeof(V)); | 29 *ok &= (*size > sizeof(V)); |
| 34 if (!(*ok)) return 0; | 30 if (!(*ok)) return 0; |
| 35 V result = *reinterpret_cast<const V*>(*data); | 31 V result = v8::internal::ReadLittleEndianValue<V>(*data); |
| 36 *data += sizeof(V); | 32 *data += sizeof(V); |
| 37 *size -= sizeof(V); | 33 *size -= sizeof(V); |
| 38 return result; | 34 return result; |
| 39 } | 35 } |
| 40 | 36 |
| 41 static void add_argument( | 37 static void add_argument( |
| 42 v8::internal::Isolate* isolate, uint8_t type, WasmVal* interpreter_args, | 38 v8::internal::Isolate* isolate, LocalType type, WasmVal* interpreter_args, |
| 43 v8::internal::Handle<v8::internal::Object>* compiled_args, int* argc, | 39 v8::internal::Handle<v8::internal::Object>* compiled_args, int* argc, |
| 44 const uint8_t** data, size_t* size, bool* ok) { | 40 const uint8_t** data, size_t* size, bool* ok) { |
| 45 if (!(*ok)) return; | 41 if (!(*ok)) return; |
| 46 switch (type) { | 42 switch (type) { |
| 47 case FUZZER_TYPE_FLOAT32: { | 43 case kAstF32: { |
| 48 float value = read_value<float>(data, size, ok); | 44 float value = read_value<float>(data, size, ok); |
| 49 interpreter_args[*argc] = WasmVal(value); | 45 interpreter_args[*argc] = WasmVal(value); |
| 50 compiled_args[*argc] = | 46 compiled_args[*argc] = |
| 51 isolate->factory()->NewNumber(static_cast<double>(value)); | 47 isolate->factory()->NewNumber(static_cast<double>(value)); |
| 52 break; | 48 break; |
| 53 } | 49 } |
| 54 case FUZZER_TYPE_FLOAT64: { | 50 case kAstF64: { |
| 55 double value = read_value<double>(data, size, ok); | 51 double value = read_value<double>(data, size, ok); |
| 56 interpreter_args[*argc] = WasmVal(value); | 52 interpreter_args[*argc] = WasmVal(value); |
| 57 compiled_args[*argc] = isolate->factory()->NewNumber(value); | 53 compiled_args[*argc] = isolate->factory()->NewNumber(value); |
| 58 break; | 54 break; |
| 59 } | 55 } |
| 60 case FUZZER_TYPE_INT32: { | 56 case kAstI32: { |
| 61 int32_t value = read_value<int32_t>(data, size, ok); | 57 int32_t value = read_value<int32_t>(data, size, ok); |
| 62 interpreter_args[*argc] = WasmVal(value); | 58 interpreter_args[*argc] = WasmVal(value); |
| 63 compiled_args[*argc] = | 59 compiled_args[*argc] = |
| 64 isolate->factory()->NewNumber(static_cast<double>(value)); | 60 isolate->factory()->NewNumber(static_cast<double>(value)); |
| 65 break; | 61 break; |
| 66 } | 62 } |
| 67 default: | 63 default: |
| 68 UNREACHABLE(); | 64 UNREACHABLE(); |
| 69 } | 65 } |
| 70 (*argc)++; | 66 (*argc)++; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 99 int argc = 0; | 95 int argc = 0; |
| 100 | 96 |
| 101 WasmModuleBuilder builder(&zone); | 97 WasmModuleBuilder builder(&zone); |
| 102 for (int fun = 0; fun < num_functions; fun++) { | 98 for (int fun = 0; fun < num_functions; fun++) { |
| 103 size_t num_params = static_cast<size_t>( | 99 size_t num_params = static_cast<size_t>( |
| 104 (read_value<uint8_t>(&data, &size, &ok) % MAX_NUM_PARAMS) + 1); | 100 (read_value<uint8_t>(&data, &size, &ok) % MAX_NUM_PARAMS) + 1); |
| 105 FunctionSig::Builder sig_builder(&zone, 1, num_params); | 101 FunctionSig::Builder sig_builder(&zone, 1, num_params); |
| 106 sig_builder.AddReturn(kAstI32); | 102 sig_builder.AddReturn(kAstI32); |
| 107 for (size_t param = 0; param < num_params; param++) { | 103 for (size_t param = 0; param < num_params; param++) { |
| 108 // The main function cannot handle int64 parameters. | 104 // The main function cannot handle int64 parameters. |
| 109 uint8_t param_type = (read_value<uint8_t>(&data, &size, &ok) % | 105 LocalType param_type = types[(read_value<uint8_t>(&data, &size, &ok) % |
| 110 (arraysize(types) - (fun == 0 ? 1 : 0))); | 106 (arraysize(types) - (fun == 0 ? 1 : 0)))]; |
| 111 sig_builder.AddParam(types[param_type]); | 107 sig_builder.AddParam(param_type); |
| 112 if (fun == 0) { | 108 if (fun == 0) { |
| 113 add_argument(i_isolate, param_type, interpreter_args, compiled_args, | 109 add_argument(i_isolate, param_type, interpreter_args, compiled_args, |
| 114 &argc, &data, &size, &ok); | 110 &argc, &data, &size, &ok); |
| 115 } | 111 } |
| 116 } | 112 } |
| 117 v8::internal::wasm::WasmFunctionBuilder* f = | 113 v8::internal::wasm::WasmFunctionBuilder* f = |
| 118 builder.AddFunction(sig_builder.Build()); | 114 builder.AddFunction(sig_builder.Build()); |
| 119 uint32_t code_size = static_cast<uint32_t>(size / num_functions); | 115 uint32_t code_size = static_cast<uint32_t>(size / num_functions); |
| 120 f->EmitCode(data, code_size); | 116 f->EmitCode(data, code_size); |
| 121 data += code_size; | 117 data += code_size; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 // result_compiled. Therefore we do not check the equality of the results | 174 // result_compiled. Therefore we do not check the equality of the results |
| 179 // if the execution may have produced a NaN at some point. | 175 // if the execution may have produced a NaN at some point. |
| 180 if (!possible_nondeterminism && (result_interpreted != result_compiled)) { | 176 if (!possible_nondeterminism && (result_interpreted != result_compiled)) { |
| 181 V8_Fatal(__FILE__, __LINE__, "WasmCodeFuzzerHash=%x", | 177 V8_Fatal(__FILE__, __LINE__, "WasmCodeFuzzerHash=%x", |
| 182 v8::internal::StringHasher::HashSequentialString( | 178 v8::internal::StringHasher::HashSequentialString( |
| 183 data, static_cast<int>(size), WASM_CODE_FUZZER_HASH_SEED)); | 179 data, static_cast<int>(size), WASM_CODE_FUZZER_HASH_SEED)); |
| 184 } | 180 } |
| 185 } | 181 } |
| 186 return 0; | 182 return 0; |
| 187 } | 183 } |
| OLD | NEW |