| Index: src/asmjs/asm-js.cc
|
| diff --git a/src/asmjs/asm-js.cc b/src/asmjs/asm-js.cc
|
| index 95d1e8a64f4df5f702534c6bba13d3321b774fe0..7da2cba506dc8523f67ccfa15374972358eed64d 100644
|
| --- a/src/asmjs/asm-js.cc
|
| +++ b/src/asmjs/asm-js.cc
|
| @@ -6,6 +6,7 @@
|
|
|
| #include "src/api-natives.h"
|
| #include "src/api.h"
|
| +#include "src/asmjs/asm-parser.h"
|
| #include "src/asmjs/asm-typer.h"
|
| #include "src/asmjs/asm-wasm-builder.h"
|
| #include "src/assert-scope.h"
|
| @@ -165,24 +166,74 @@ bool IsStdlibMemberValid(i::Isolate* isolate, Handle<JSReceiver> stdlib,
|
|
|
| MaybeHandle<FixedArray> AsmJs::CompileAsmViaWasm(CompilationInfo* info) {
|
| ErrorThrower thrower(info->isolate(), "Asm.js -> WebAssembly conversion");
|
| + wasm::ZoneBuffer* module;
|
| + wasm::ZoneBuffer* asm_offsets;
|
| + Handle<FixedArray> uses_array;
|
| + Handle<FixedArray> foreign_globals;
|
| base::ElapsedTimer asm_wasm_timer;
|
| asm_wasm_timer.Start();
|
| wasm::AsmWasmBuilder builder(info);
|
| - Handle<FixedArray> foreign_globals;
|
| - auto asm_wasm_result = builder.Run(&foreign_globals);
|
| - if (!asm_wasm_result.success) {
|
| - DCHECK(!info->isolate()->has_pending_exception());
|
| - if (!FLAG_suppress_asm_messages) {
|
| - MessageHandler::ReportMessage(info->isolate(),
|
| - builder.typer()->message_location(),
|
| - builder.typer()->error_message());
|
| + if (FLAG_fast_validate_asm) {
|
| + wasm::AsmJsParser parser(info->isolate(), info->zone(), info->script(),
|
| + info->literal()->start_position(),
|
| + info->literal()->end_position());
|
| + if (!parser.Run()) {
|
| + DCHECK(!info->isolate()->has_pending_exception());
|
| + if (!FLAG_suppress_asm_messages) {
|
| + MessageLocation location(info->script(), parser.failure_location(),
|
| + parser.failure_location());
|
| + Handle<String> message =
|
| + info->isolate()
|
| + ->factory()
|
| + ->NewStringFromUtf8(CStrVector(parser.failure_message()))
|
| + .ToHandleChecked();
|
| + Handle<JSMessageObject> error_message =
|
| + MessageHandler::MakeMessageObject(
|
| + info->isolate(), MessageTemplate::kAsmJsInvalid, &location,
|
| + message, Handle<JSArray>::null());
|
| + error_message->set_error_level(v8::Isolate::kMessageWarning);
|
| + MessageHandler::ReportMessage(info->isolate(), &location,
|
| + error_message);
|
| + }
|
| + return MaybeHandle<FixedArray>();
|
| + }
|
| + Zone* zone = info->zone();
|
| + module = new (zone) wasm::ZoneBuffer(zone);
|
| + parser.builder()->WriteTo(*module);
|
| + asm_offsets = new (zone) wasm::ZoneBuffer(zone);
|
| + parser.builder()->WriteAsmJsOffsetTable(*asm_offsets);
|
| + // TODO(bradnelson): Remove foreign_globals plumbing (as we don't need it
|
| + // for the new parser).
|
| + foreign_globals = info->isolate()->factory()->NewFixedArray(0);
|
| + uses_array = info->isolate()->factory()->NewFixedArray(
|
| + static_cast<int>(parser.stdlib_uses()->size()));
|
| + int count = 0;
|
| + for (auto i : *parser.stdlib_uses()) {
|
| + uses_array->set(count++, Smi::FromInt(i));
|
| + }
|
| + } else {
|
| + auto asm_wasm_result = builder.Run(&foreign_globals);
|
| + if (!asm_wasm_result.success) {
|
| + DCHECK(!info->isolate()->has_pending_exception());
|
| + if (!FLAG_suppress_asm_messages) {
|
| + MessageHandler::ReportMessage(info->isolate(),
|
| + builder.typer()->message_location(),
|
| + builder.typer()->error_message());
|
| + }
|
| + return MaybeHandle<FixedArray>();
|
| + }
|
| + module = asm_wasm_result.module_bytes;
|
| + asm_offsets = asm_wasm_result.asm_offset_table;
|
| + wasm::AsmTyper::StdlibSet uses = builder.typer()->StdlibUses();
|
| + uses_array = info->isolate()->factory()->NewFixedArray(
|
| + static_cast<int>(uses.size()));
|
| + int count = 0;
|
| + for (auto i : uses) {
|
| + uses_array->set(count++, Smi::FromInt(i));
|
| }
|
| - return MaybeHandle<FixedArray>();
|
| }
|
| - double asm_wasm_time = asm_wasm_timer.Elapsed().InMillisecondsF();
|
|
|
| - wasm::ZoneBuffer* module = asm_wasm_result.module_bytes;
|
| - wasm::ZoneBuffer* asm_offsets = asm_wasm_result.asm_offset_table;
|
| + double asm_wasm_time = asm_wasm_timer.Elapsed().InMillisecondsF();
|
| Vector<const byte> asm_offsets_vec(asm_offsets->begin(),
|
| static_cast<int>(asm_offsets->size()));
|
|
|
| @@ -197,14 +248,6 @@ MaybeHandle<FixedArray> AsmJs::CompileAsmViaWasm(CompilationInfo* info) {
|
| DCHECK_GE(module->end(), module->begin());
|
| uintptr_t wasm_size = module->end() - module->begin();
|
|
|
| - wasm::AsmTyper::StdlibSet uses = builder.typer()->StdlibUses();
|
| - Handle<FixedArray> uses_array =
|
| - info->isolate()->factory()->NewFixedArray(static_cast<int>(uses.size()));
|
| - int count = 0;
|
| - for (auto i : uses) {
|
| - uses_array->set(count++, Smi::FromInt(i));
|
| - }
|
| -
|
| Handle<FixedArray> result =
|
| info->isolate()->factory()->NewFixedArray(kWasmDataEntryCount);
|
| result->set(kWasmDataCompiledModule, *compiled.ToHandleChecked());
|
| @@ -283,33 +326,36 @@ MaybeHandle<Object> AsmJs::InstantiateAsmWasm(i::Isolate* isolate,
|
| }
|
| i::Handle<i::Object> module_object = maybe_module_object.ToHandleChecked();
|
|
|
| - i::Handle<i::Name> init_name(isolate->factory()->InternalizeUtf8String(
|
| - wasm::AsmWasmBuilder::foreign_init_name));
|
| - i::Handle<i::Object> init =
|
| - i::Object::GetProperty(module_object, init_name).ToHandleChecked();
|
| + if (!FLAG_fast_validate_asm) {
|
| + i::Handle<i::Name> init_name(isolate->factory()->InternalizeUtf8String(
|
| + wasm::AsmWasmBuilder::foreign_init_name));
|
| + i::Handle<i::Object> init =
|
| + i::Object::GetProperty(module_object, init_name).ToHandleChecked();
|
|
|
| - i::Handle<i::Object> undefined(isolate->heap()->undefined_value(), isolate);
|
| - i::Handle<i::Object>* foreign_args_array =
|
| - new i::Handle<i::Object>[foreign_globals->length()];
|
| - for (int j = 0; j < foreign_globals->length(); j++) {
|
| - if (!foreign.is_null()) {
|
| - i::MaybeHandle<i::Name> name = i::Object::ToName(
|
| - isolate, i::Handle<i::Object>(foreign_globals->get(j), isolate));
|
| - if (!name.is_null()) {
|
| - i::MaybeHandle<i::Object> val =
|
| - i::Object::GetProperty(foreign, name.ToHandleChecked());
|
| - if (!val.is_null()) {
|
| - foreign_args_array[j] = val.ToHandleChecked();
|
| - continue;
|
| + i::Handle<i::Object> undefined(isolate->heap()->undefined_value(), isolate);
|
| + i::Handle<i::Object>* foreign_args_array =
|
| + new i::Handle<i::Object>[foreign_globals->length()];
|
| + for (int j = 0; j < foreign_globals->length(); j++) {
|
| + if (!foreign.is_null()) {
|
| + i::MaybeHandle<i::Name> name = i::Object::ToName(
|
| + isolate, i::Handle<i::Object>(foreign_globals->get(j), isolate));
|
| + if (!name.is_null()) {
|
| + i::MaybeHandle<i::Object> val =
|
| + i::Object::GetProperty(foreign, name.ToHandleChecked());
|
| + if (!val.is_null()) {
|
| + foreign_args_array[j] = val.ToHandleChecked();
|
| + continue;
|
| + }
|
| }
|
| }
|
| + foreign_args_array[j] = undefined;
|
| }
|
| - foreign_args_array[j] = undefined;
|
| + i::MaybeHandle<i::Object> retval =
|
| + i::Execution::Call(isolate, init, undefined, foreign_globals->length(),
|
| + foreign_args_array);
|
| + delete[] foreign_args_array;
|
| + DCHECK(!retval.is_null());
|
| }
|
| - i::MaybeHandle<i::Object> retval = i::Execution::Call(
|
| - isolate, init, undefined, foreign_globals->length(), foreign_args_array);
|
| - delete[] foreign_args_array;
|
| - DCHECK(!retval.is_null());
|
|
|
| i::Handle<i::Name> single_function_name(
|
| isolate->factory()->InternalizeUtf8String(
|
|
|