[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:
ahaas 2016-11-14 11:45:16 -08:00 committed by Commit bot
parent 2a350ed457
commit 1bde83046e
6 changed files with 22 additions and 32 deletions

View File

@ -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;
}

View File

@ -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 {

View File

@ -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());

View File

@ -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,

View File

@ -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;

View File

@ -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;