[wasm] Reimplement function verification in the module decoder.
This CL adds the function verification option to the module decoder. Therefore we can remove the verification in wasm-module-runner.cc R=titzer@chromium.org Review-Url: https://codereview.chromium.org/2496203002 Cr-Commit-Position: refs/heads/master@{#40977}
This commit is contained in:
parent
2a350ed457
commit
1bde83046e
@ -586,6 +586,14 @@ class ModuleDecoder : public Decoder {
|
||||
uint32_t size = consume_u32v("body size");
|
||||
function->code_start_offset = pc_offset();
|
||||
function->code_end_offset = pc_offset() + size;
|
||||
if (verify_functions) {
|
||||
ModuleEnv module_env;
|
||||
module_env.module = module;
|
||||
module_env.origin = module->origin;
|
||||
|
||||
VerifyFunctionBody(i + module->num_imported_functions, &module_env,
|
||||
function);
|
||||
}
|
||||
consume_bytes(size, "function body");
|
||||
}
|
||||
section_iter.advance();
|
||||
@ -646,6 +654,9 @@ class ModuleDecoder : public Decoder {
|
||||
}
|
||||
const WasmModule* finished_module = module;
|
||||
ModuleResult result = toResult(finished_module);
|
||||
if (verify_functions && result.ok()) {
|
||||
result.MoveFrom(result_); // Copy error code and location.
|
||||
}
|
||||
if (FLAG_dump_wasm_module) DumpModule(module, result);
|
||||
return result;
|
||||
}
|
||||
|
@ -1925,7 +1925,7 @@ MaybeHandle<WasmModuleObject> wasm::CreateModuleObjectFromBytes(
|
||||
bool wasm::ValidateModuleBytes(Isolate* isolate, const byte* start,
|
||||
const byte* end, ErrorThrower* thrower,
|
||||
ModuleOrigin origin) {
|
||||
ModuleResult result = DecodeWasmModule(isolate, start, end, false, origin);
|
||||
ModuleResult result = DecodeWasmModule(isolate, start, end, true, origin);
|
||||
if (result.val) {
|
||||
delete result.val;
|
||||
} else {
|
||||
|
@ -24,15 +24,13 @@ uint32_t GetMinModuleMemSize(const WasmModule* module) {
|
||||
return WasmModule::kPageSize * module->min_mem_pages;
|
||||
}
|
||||
|
||||
const WasmModule* DecodeWasmModuleForTesting(Isolate* isolate,
|
||||
ErrorThrower* thrower,
|
||||
const byte* module_start,
|
||||
const byte* module_end,
|
||||
ModuleOrigin origin) {
|
||||
const WasmModule* DecodeWasmModuleForTesting(
|
||||
Isolate* isolate, ErrorThrower* thrower, const byte* module_start,
|
||||
const byte* module_end, ModuleOrigin origin, bool verify_functions) {
|
||||
// Decode the module, but don't verify function bodies, since we'll
|
||||
// be compiling them anyway.
|
||||
ModuleResult decoding_result =
|
||||
DecodeWasmModule(isolate, module_start, module_end, false, origin);
|
||||
ModuleResult decoding_result = DecodeWasmModule(
|
||||
isolate, module_start, module_end, verify_functions, origin);
|
||||
|
||||
if (decoding_result.failed()) {
|
||||
// Module verification failed. throw.
|
||||
@ -129,22 +127,6 @@ int32_t InterpretWasmModule(Isolate* isolate, ErrorThrower* thrower,
|
||||
|
||||
if (thrower->error()) return -1;
|
||||
|
||||
ModuleEnv module_env;
|
||||
module_env.module = module;
|
||||
module_env.origin = module->origin;
|
||||
|
||||
for (size_t i = 0; i < module->functions.size(); i++) {
|
||||
FunctionBody body = {
|
||||
&module_env, module->functions[i].sig, module->module_start,
|
||||
module->module_start + module->functions[i].code_start_offset,
|
||||
module->module_start + module->functions[i].code_end_offset};
|
||||
DecodeResult result = VerifyWasmCode(isolate->allocator(), body);
|
||||
if (result.failed()) {
|
||||
thrower->CompileError("Function did not verify");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// The code verifies, we create an instance to run it in the interpreter.
|
||||
WasmInstance instance(module);
|
||||
instance.context = isolate->native_context();
|
||||
@ -154,7 +136,6 @@ int32_t InterpretWasmModule(Isolate* isolate, ErrorThrower* thrower,
|
||||
instance.mem_start =
|
||||
static_cast<byte*>(calloc(GetMinModuleMemSize(module), 1));
|
||||
instance.globals_start = nullptr;
|
||||
module_env.instance = &instance;
|
||||
|
||||
WasmInterpreter interpreter(&instance, isolate->allocator());
|
||||
|
||||
|
@ -19,11 +19,9 @@ namespace wasm {
|
||||
namespace testing {
|
||||
|
||||
// Decodes the given encoded module.
|
||||
const WasmModule* DecodeWasmModuleForTesting(Isolate* isolate,
|
||||
ErrorThrower* thrower,
|
||||
const byte* module_start,
|
||||
const byte* module_end,
|
||||
ModuleOrigin origin);
|
||||
const WasmModule* DecodeWasmModuleForTesting(
|
||||
Isolate* isolate, ErrorThrower* thrower, const byte* module_start,
|
||||
const byte* module_end, ModuleOrigin origin, bool verify_functions = false);
|
||||
|
||||
// Instantiates a module without any imports and exports.
|
||||
const Handle<JSObject> InstantiateModuleForTesting(Isolate* isolate,
|
||||
|
@ -136,7 +136,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
ErrorThrower interpreter_thrower(i_isolate, "Interpreter");
|
||||
std::unique_ptr<const WasmModule> module(testing::DecodeWasmModuleForTesting(
|
||||
i_isolate, &interpreter_thrower, buffer.begin(), buffer.end(),
|
||||
v8::internal::wasm::ModuleOrigin::kWasmOrigin));
|
||||
v8::internal::wasm::ModuleOrigin::kWasmOrigin, true));
|
||||
|
||||
if (module == nullptr) {
|
||||
return 0;
|
||||
|
@ -57,7 +57,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
ErrorThrower interpreter_thrower(i_isolate, "Interpreter");
|
||||
std::unique_ptr<const WasmModule> module(testing::DecodeWasmModuleForTesting(
|
||||
i_isolate, &interpreter_thrower, buffer.begin(), buffer.end(),
|
||||
v8::internal::wasm::ModuleOrigin::kWasmOrigin));
|
||||
v8::internal::wasm::ModuleOrigin::kWasmOrigin, true));
|
||||
|
||||
if (module == nullptr) {
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user