[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");
|
uint32_t size = consume_u32v("body size");
|
||||||
function->code_start_offset = pc_offset();
|
function->code_start_offset = pc_offset();
|
||||||
function->code_end_offset = pc_offset() + size;
|
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");
|
consume_bytes(size, "function body");
|
||||||
}
|
}
|
||||||
section_iter.advance();
|
section_iter.advance();
|
||||||
@ -646,6 +654,9 @@ class ModuleDecoder : public Decoder {
|
|||||||
}
|
}
|
||||||
const WasmModule* finished_module = module;
|
const WasmModule* finished_module = module;
|
||||||
ModuleResult result = toResult(finished_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);
|
if (FLAG_dump_wasm_module) DumpModule(module, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1925,7 +1925,7 @@ MaybeHandle<WasmModuleObject> wasm::CreateModuleObjectFromBytes(
|
|||||||
bool wasm::ValidateModuleBytes(Isolate* isolate, const byte* start,
|
bool wasm::ValidateModuleBytes(Isolate* isolate, const byte* start,
|
||||||
const byte* end, ErrorThrower* thrower,
|
const byte* end, ErrorThrower* thrower,
|
||||||
ModuleOrigin origin) {
|
ModuleOrigin origin) {
|
||||||
ModuleResult result = DecodeWasmModule(isolate, start, end, false, origin);
|
ModuleResult result = DecodeWasmModule(isolate, start, end, true, origin);
|
||||||
if (result.val) {
|
if (result.val) {
|
||||||
delete result.val;
|
delete result.val;
|
||||||
} else {
|
} else {
|
||||||
|
@ -24,15 +24,13 @@ uint32_t GetMinModuleMemSize(const WasmModule* module) {
|
|||||||
return WasmModule::kPageSize * module->min_mem_pages;
|
return WasmModule::kPageSize * module->min_mem_pages;
|
||||||
}
|
}
|
||||||
|
|
||||||
const WasmModule* DecodeWasmModuleForTesting(Isolate* isolate,
|
const WasmModule* DecodeWasmModuleForTesting(
|
||||||
ErrorThrower* thrower,
|
Isolate* isolate, ErrorThrower* thrower, const byte* module_start,
|
||||||
const byte* module_start,
|
const byte* module_end, ModuleOrigin origin, bool verify_functions) {
|
||||||
const byte* module_end,
|
|
||||||
ModuleOrigin origin) {
|
|
||||||
// Decode the module, but don't verify function bodies, since we'll
|
// Decode the module, but don't verify function bodies, since we'll
|
||||||
// be compiling them anyway.
|
// be compiling them anyway.
|
||||||
ModuleResult decoding_result =
|
ModuleResult decoding_result = DecodeWasmModule(
|
||||||
DecodeWasmModule(isolate, module_start, module_end, false, origin);
|
isolate, module_start, module_end, verify_functions, origin);
|
||||||
|
|
||||||
if (decoding_result.failed()) {
|
if (decoding_result.failed()) {
|
||||||
// Module verification failed. throw.
|
// Module verification failed. throw.
|
||||||
@ -129,22 +127,6 @@ int32_t InterpretWasmModule(Isolate* isolate, ErrorThrower* thrower,
|
|||||||
|
|
||||||
if (thrower->error()) return -1;
|
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.
|
// The code verifies, we create an instance to run it in the interpreter.
|
||||||
WasmInstance instance(module);
|
WasmInstance instance(module);
|
||||||
instance.context = isolate->native_context();
|
instance.context = isolate->native_context();
|
||||||
@ -154,7 +136,6 @@ int32_t InterpretWasmModule(Isolate* isolate, ErrorThrower* thrower,
|
|||||||
instance.mem_start =
|
instance.mem_start =
|
||||||
static_cast<byte*>(calloc(GetMinModuleMemSize(module), 1));
|
static_cast<byte*>(calloc(GetMinModuleMemSize(module), 1));
|
||||||
instance.globals_start = nullptr;
|
instance.globals_start = nullptr;
|
||||||
module_env.instance = &instance;
|
|
||||||
|
|
||||||
WasmInterpreter interpreter(&instance, isolate->allocator());
|
WasmInterpreter interpreter(&instance, isolate->allocator());
|
||||||
|
|
||||||
|
@ -19,11 +19,9 @@ namespace wasm {
|
|||||||
namespace testing {
|
namespace testing {
|
||||||
|
|
||||||
// Decodes the given encoded module.
|
// Decodes the given encoded module.
|
||||||
const WasmModule* DecodeWasmModuleForTesting(Isolate* isolate,
|
const WasmModule* DecodeWasmModuleForTesting(
|
||||||
ErrorThrower* thrower,
|
Isolate* isolate, ErrorThrower* thrower, const byte* module_start,
|
||||||
const byte* module_start,
|
const byte* module_end, ModuleOrigin origin, bool verify_functions = false);
|
||||||
const byte* module_end,
|
|
||||||
ModuleOrigin origin);
|
|
||||||
|
|
||||||
// Instantiates a module without any imports and exports.
|
// Instantiates a module without any imports and exports.
|
||||||
const Handle<JSObject> InstantiateModuleForTesting(Isolate* isolate,
|
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");
|
ErrorThrower interpreter_thrower(i_isolate, "Interpreter");
|
||||||
std::unique_ptr<const WasmModule> module(testing::DecodeWasmModuleForTesting(
|
std::unique_ptr<const WasmModule> module(testing::DecodeWasmModuleForTesting(
|
||||||
i_isolate, &interpreter_thrower, buffer.begin(), buffer.end(),
|
i_isolate, &interpreter_thrower, buffer.begin(), buffer.end(),
|
||||||
v8::internal::wasm::ModuleOrigin::kWasmOrigin));
|
v8::internal::wasm::ModuleOrigin::kWasmOrigin, true));
|
||||||
|
|
||||||
if (module == nullptr) {
|
if (module == nullptr) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -57,7 +57,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
|||||||
ErrorThrower interpreter_thrower(i_isolate, "Interpreter");
|
ErrorThrower interpreter_thrower(i_isolate, "Interpreter");
|
||||||
std::unique_ptr<const WasmModule> module(testing::DecodeWasmModuleForTesting(
|
std::unique_ptr<const WasmModule> module(testing::DecodeWasmModuleForTesting(
|
||||||
i_isolate, &interpreter_thrower, buffer.begin(), buffer.end(),
|
i_isolate, &interpreter_thrower, buffer.begin(), buffer.end(),
|
||||||
v8::internal::wasm::ModuleOrigin::kWasmOrigin));
|
v8::internal::wasm::ModuleOrigin::kWasmOrigin, true));
|
||||||
|
|
||||||
if (module == nullptr) {
|
if (module == nullptr) {
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user