diff options
Diffstat (limited to 'deps/v8/src/asmjs/asm-js.cc')
-rw-r--r-- | deps/v8/src/asmjs/asm-js.cc | 523 |
1 files changed, 232 insertions, 291 deletions
diff --git a/deps/v8/src/asmjs/asm-js.cc b/deps/v8/src/asmjs/asm-js.cc index fb46026a98..516bce2543 100644 --- a/deps/v8/src/asmjs/asm-js.cc +++ b/deps/v8/src/asmjs/asm-js.cc @@ -6,10 +6,10 @@ #include "src/api-natives.h" #include "src/api.h" +#include "src/asmjs/asm-names.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" +#include "src/ast/ast.h" #include "src/base/platform/elapsed-timer.h" #include "src/compilation-info.h" #include "src/execution.h" @@ -18,7 +18,6 @@ #include "src/isolate.h" #include "src/objects-inl.h" #include "src/objects.h" -#include "src/parsing/parse-info.h" #include "src/wasm/module-decoder.h" #include "src/wasm/wasm-js.h" @@ -27,286 +26,266 @@ #include "src/wasm/wasm-objects.h" #include "src/wasm/wasm-result.h" -typedef uint8_t byte; - -using v8::internal::wasm::ErrorThrower; - namespace v8 { namespace internal { +const char* const AsmJs::kSingleFunctionName = "__single_function__"; + namespace { enum WasmDataEntries { kWasmDataCompiledModule, - kWasmDataForeignGlobals, kWasmDataUsesArray, - kWasmDataScript, - kWasmDataScriptPosition, kWasmDataEntryCount, }; -Handle<i::Object> StdlibMathMember(i::Isolate* isolate, - Handle<JSReceiver> stdlib, - Handle<Name> name) { - if (stdlib.is_null()) { - return Handle<i::Object>(); - } - Handle<i::Name> math_name( +Handle<Object> StdlibMathMember(Isolate* isolate, Handle<JSReceiver> stdlib, + Handle<Name> name) { + Handle<Name> math_name( isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("Math"))); - MaybeHandle<i::Object> maybe_math = i::Object::GetProperty(stdlib, math_name); - if (maybe_math.is_null()) { - return Handle<i::Object>(); - } - Handle<i::Object> math = maybe_math.ToHandleChecked(); - if (!math->IsJSReceiver()) { - return Handle<i::Object>(); - } - MaybeHandle<i::Object> maybe_value = i::Object::GetProperty(math, name); - if (maybe_value.is_null()) { - return Handle<i::Object>(); - } - return maybe_value.ToHandleChecked(); + Handle<Object> math = JSReceiver::GetDataProperty(stdlib, math_name); + if (!math->IsJSReceiver()) return isolate->factory()->undefined_value(); + Handle<JSReceiver> math_receiver = Handle<JSReceiver>::cast(math); + Handle<Object> value = JSReceiver::GetDataProperty(math_receiver, name); + return value; } -bool IsStdlibMemberValid(i::Isolate* isolate, Handle<JSReceiver> stdlib, - Handle<i::Object> member_id) { - int32_t member_kind; - if (!member_id->ToInt32(&member_kind)) { - UNREACHABLE(); - } - switch (member_kind) { - case wasm::AsmTyper::StandardMember::kNone: - case wasm::AsmTyper::StandardMember::kModule: - case wasm::AsmTyper::StandardMember::kStdlib: - case wasm::AsmTyper::StandardMember::kHeap: - case wasm::AsmTyper::StandardMember::kFFI: { - // Nothing to check for these. - return true; - } - case wasm::AsmTyper::StandardMember::kInfinity: { - if (stdlib.is_null()) { - return false; - } - Handle<i::Name> name(isolate->factory()->InternalizeOneByteString( - STATIC_CHAR_VECTOR("Infinity"))); - MaybeHandle<i::Object> maybe_value = i::Object::GetProperty(stdlib, name); - if (maybe_value.is_null()) { - return false; - } - Handle<i::Object> value = maybe_value.ToHandleChecked(); +bool IsStdlibMemberValid(Isolate* isolate, Handle<JSReceiver> stdlib, + wasm::AsmJsParser::StandardMember member, + bool* is_typed_array) { + switch (member) { + case wasm::AsmJsParser::StandardMember::kInfinity: { + Handle<Name> name = isolate->factory()->infinity_string(); + Handle<Object> value = JSReceiver::GetDataProperty(stdlib, name); return value->IsNumber() && std::isinf(value->Number()); } - case wasm::AsmTyper::StandardMember::kNaN: { - if (stdlib.is_null()) { - return false; - } - Handle<i::Name> name(isolate->factory()->InternalizeOneByteString( - STATIC_CHAR_VECTOR("NaN"))); - MaybeHandle<i::Object> maybe_value = i::Object::GetProperty(stdlib, name); - if (maybe_value.is_null()) { - return false; - } - Handle<i::Object> value = maybe_value.ToHandleChecked(); + case wasm::AsmJsParser::StandardMember::kNaN: { + Handle<Name> name = isolate->factory()->nan_string(); + Handle<Object> value = JSReceiver::GetDataProperty(stdlib, name); return value->IsNaN(); } -#define STDLIB_MATH_FUNC(CamelName, fname) \ - case wasm::AsmTyper::StandardMember::k##CamelName: { \ - Handle<i::Name> name(isolate->factory()->InternalizeOneByteString( \ - STATIC_CHAR_VECTOR(#fname))); \ - Handle<i::Object> value = StdlibMathMember(isolate, stdlib, name); \ - if (value.is_null() || !value->IsJSFunction()) { \ - return false; \ - } \ - Handle<i::JSFunction> func(i::JSFunction::cast(*value)); \ - return func->shared()->code() == \ - isolate->builtins()->builtin(Builtins::k##CamelName); \ +#define STDLIB_MATH_FUNC(fname, FName, ignore1, ignore2) \ + case wasm::AsmJsParser::StandardMember::kMath##FName: { \ + Handle<Name> name(isolate->factory()->InternalizeOneByteString( \ + STATIC_CHAR_VECTOR(#fname))); \ + Handle<Object> value = StdlibMathMember(isolate, stdlib, name); \ + if (!value->IsJSFunction()) return false; \ + Handle<JSFunction> func = Handle<JSFunction>::cast(value); \ + return func->shared()->code() == \ + isolate->builtins()->builtin(Builtins::kMath##FName); \ } - STDLIB_MATH_FUNC(MathAcos, acos) - STDLIB_MATH_FUNC(MathAsin, asin) - STDLIB_MATH_FUNC(MathAtan, atan) - STDLIB_MATH_FUNC(MathCos, cos) - STDLIB_MATH_FUNC(MathSin, sin) - STDLIB_MATH_FUNC(MathTan, tan) - STDLIB_MATH_FUNC(MathExp, exp) - STDLIB_MATH_FUNC(MathLog, log) - STDLIB_MATH_FUNC(MathCeil, ceil) - STDLIB_MATH_FUNC(MathFloor, floor) - STDLIB_MATH_FUNC(MathSqrt, sqrt) - STDLIB_MATH_FUNC(MathAbs, abs) - STDLIB_MATH_FUNC(MathClz32, clz32) - STDLIB_MATH_FUNC(MathMin, min) - STDLIB_MATH_FUNC(MathMax, max) - STDLIB_MATH_FUNC(MathAtan2, atan2) - STDLIB_MATH_FUNC(MathPow, pow) - STDLIB_MATH_FUNC(MathImul, imul) - STDLIB_MATH_FUNC(MathFround, fround) + STDLIB_MATH_FUNCTION_LIST(STDLIB_MATH_FUNC) #undef STDLIB_MATH_FUNC -#define STDLIB_MATH_CONST(cname, const_value) \ - case wasm::AsmTyper::StandardMember::kMath##cname: { \ - i::Handle<i::Name> name(isolate->factory()->InternalizeOneByteString( \ - STATIC_CHAR_VECTOR(#cname))); \ - i::Handle<i::Object> value = StdlibMathMember(isolate, stdlib, name); \ - return !value.is_null() && value->IsNumber() && \ - value->Number() == const_value; \ +#define STDLIB_MATH_CONST(cname, const_value) \ + case wasm::AsmJsParser::StandardMember::kMath##cname: { \ + Handle<Name> name(isolate->factory()->InternalizeOneByteString( \ + STATIC_CHAR_VECTOR(#cname))); \ + Handle<Object> value = StdlibMathMember(isolate, stdlib, name); \ + return value->IsNumber() && value->Number() == const_value; \ } - STDLIB_MATH_CONST(E, 2.718281828459045) - STDLIB_MATH_CONST(LN10, 2.302585092994046) - STDLIB_MATH_CONST(LN2, 0.6931471805599453) - STDLIB_MATH_CONST(LOG2E, 1.4426950408889634) - STDLIB_MATH_CONST(LOG10E, 0.4342944819032518) - STDLIB_MATH_CONST(PI, 3.141592653589793) - STDLIB_MATH_CONST(SQRT1_2, 0.7071067811865476) - STDLIB_MATH_CONST(SQRT2, 1.4142135623730951) + STDLIB_MATH_VALUE_LIST(STDLIB_MATH_CONST) #undef STDLIB_MATH_CONST - default: { UNREACHABLE(); } +#define STDLIB_ARRAY_TYPE(fname, FName) \ + case wasm::AsmJsParser::StandardMember::k##FName: { \ + *is_typed_array = true; \ + Handle<Name> name(isolate->factory()->InternalizeOneByteString( \ + STATIC_CHAR_VECTOR(#FName))); \ + Handle<Object> value = JSReceiver::GetDataProperty(stdlib, name); \ + if (!value->IsJSFunction()) return false; \ + Handle<JSFunction> func = Handle<JSFunction>::cast(value); \ + return func.is_identical_to(isolate->fname()); \ + } + STDLIB_ARRAY_TYPE(int8_array_fun, Int8Array) + STDLIB_ARRAY_TYPE(uint8_array_fun, Uint8Array) + STDLIB_ARRAY_TYPE(int16_array_fun, Int16Array) + STDLIB_ARRAY_TYPE(uint16_array_fun, Uint16Array) + STDLIB_ARRAY_TYPE(int32_array_fun, Int32Array) + STDLIB_ARRAY_TYPE(uint32_array_fun, Uint32Array) + STDLIB_ARRAY_TYPE(float32_array_fun, Float32Array) + STDLIB_ARRAY_TYPE(float64_array_fun, Float64Array) +#undef STDLIB_ARRAY_TYPE } + UNREACHABLE(); return false; } +void Report(Handle<Script> script, int position, Vector<const char> text, + MessageTemplate::Template message_template, + v8::Isolate::MessageErrorLevel level) { + Isolate* isolate = script->GetIsolate(); + MessageLocation location(script, position, position); + Handle<String> text_object = isolate->factory()->InternalizeUtf8String(text); + Handle<JSMessageObject> message = MessageHandler::MakeMessageObject( + isolate, message_template, &location, text_object, + Handle<FixedArray>::null()); + message->set_error_level(level); + MessageHandler::ReportMessage(isolate, &location, message); +} + +// Hook to report successful execution of {AsmJs::CompileAsmViaWasm} phase. +void ReportCompilationSuccess(Handle<Script> script, int position, + double translate_time, double compile_time, + size_t module_size) { + if (FLAG_suppress_asm_messages || !FLAG_trace_asm_time) return; + EmbeddedVector<char, 100> text; + int length = SNPrintF( + text, "success, asm->wasm: %0.3f ms, compile: %0.3f ms, %" PRIuS " bytes", + translate_time, compile_time, module_size); + CHECK_NE(-1, length); + text.Truncate(length); + Report(script, position, text, MessageTemplate::kAsmJsCompiled, + v8::Isolate::kMessageInfo); +} + +// Hook to report failed execution of {AsmJs::CompileAsmViaWasm} phase. +void ReportCompilationFailure(Handle<Script> script, int position, + const char* reason) { + if (FLAG_suppress_asm_messages) return; + Vector<const char> text = CStrVector(reason); + Report(script, position, text, MessageTemplate::kAsmJsInvalid, + v8::Isolate::kMessageWarning); +} + +// Hook to report successful execution of {AsmJs::InstantiateAsmWasm} phase. +void ReportInstantiationSuccess(Handle<Script> script, int position, + double instantiate_time) { + if (FLAG_suppress_asm_messages || !FLAG_trace_asm_time) return; + EmbeddedVector<char, 50> text; + int length = SNPrintF(text, "success, %0.3f ms", instantiate_time); + CHECK_NE(-1, length); + text.Truncate(length); + Report(script, position, text, MessageTemplate::kAsmJsInstantiated, + v8::Isolate::kMessageInfo); +} + +// Hook to report failed execution of {AsmJs::InstantiateAsmWasm} phase. +void ReportInstantiationFailure(Handle<Script> script, int position, + const char* reason) { + if (FLAG_suppress_asm_messages) return; + Vector<const char> text = CStrVector(reason); + Report(script, position, text, MessageTemplate::kAsmJsLinkingFailed, + v8::Isolate::kMessageWarning); +} + } // namespace MaybeHandle<FixedArray> AsmJs::CompileAsmViaWasm(CompilationInfo* info) { wasm::ZoneBuffer* module = nullptr; wasm::ZoneBuffer* asm_offsets = nullptr; Handle<FixedArray> uses_array; - Handle<FixedArray> foreign_globals; - base::ElapsedTimer asm_wasm_timer; - asm_wasm_timer.Start(); - wasm::AsmWasmBuilder builder(info); - if (FLAG_fast_validate_asm) { - wasm::AsmJsParser parser(info->isolate(), info->zone(), info->script(), + Handle<WasmModuleObject> compiled; + + // The compilation of asm.js modules is split into two distinct steps: + // [1] The asm.js module source is parsed, validated, and translated to a + // valid WebAssembly module. The result are two vectors representing the + // encoded module as well as encoded source position information. + // [2] The module is handed to WebAssembly which decodes it into an internal + // representation and eventually compiles it to machine code. + double translate_time; // Time (milliseconds) taken to execute step [1]. + double compile_time; // Time (milliseconds) taken to execute step [2]. + + // Step 1: Translate asm.js module to WebAssembly module. + { + HistogramTimerScope translate_time_scope( + info->isolate()->counters()->asm_wasm_translation_time()); + size_t compile_zone_start = info->zone()->allocation_size(); + base::ElapsedTimer translate_timer; + translate_timer.Start(); + + Zone* compile_zone = info->zone(); + Zone translate_zone(info->isolate()->allocator(), ZONE_NAME); + wasm::AsmJsParser parser(info->isolate(), &translate_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); - } + ReportCompilationFailure(info->script(), parser.failure_location(), + parser.failure_message()); return MaybeHandle<FixedArray>(); } - Zone* zone = info->zone(); - module = new (zone) wasm::ZoneBuffer(zone); + module = new (compile_zone) wasm::ZoneBuffer(compile_zone); parser.module_builder()->WriteTo(*module); - asm_offsets = new (zone) wasm::ZoneBuffer(zone); + asm_offsets = new (compile_zone) wasm::ZoneBuffer(compile_zone); parser.module_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)); + size_t compile_zone_size = + info->zone()->allocation_size() - compile_zone_start; + size_t translate_zone_size = translate_zone.allocation_size(); + info->isolate() + ->counters() + ->asm_wasm_translation_peak_memory_bytes() + ->AddSample(static_cast<int>(translate_zone_size)); + translate_time = translate_timer.Elapsed().InMillisecondsF(); + if (FLAG_trace_asm_parser) { + PrintF( + "[asm.js translation successful: time=%0.3fms, " + "translate_zone=%" PRIuS "KB, compile_zone+=%" PRIuS "KB]\n", + translate_time, translate_zone_size / KB, compile_zone_size / KB); } } - double asm_wasm_time = asm_wasm_timer.Elapsed().InMillisecondsF(); - Vector<const byte> asm_offsets_vec(asm_offsets->begin(), - static_cast<int>(asm_offsets->size())); - - base::ElapsedTimer compile_timer; - compile_timer.Start(); - ErrorThrower thrower(info->isolate(), "Asm.js -> WebAssembly conversion"); - MaybeHandle<JSObject> compiled = SyncCompileTranslatedAsmJs( - info->isolate(), &thrower, - wasm::ModuleWireBytes(module->begin(), module->end()), info->script(), - asm_offsets_vec); - DCHECK(!compiled.is_null()); - DCHECK(!thrower.error()); - double compile_time = compile_timer.Elapsed().InMillisecondsF(); - DCHECK_GE(module->end(), module->begin()); - uintptr_t wasm_size = module->end() - module->begin(); + // Step 2: Compile and decode the WebAssembly module. + { + base::ElapsedTimer compile_timer; + compile_timer.Start(); + wasm::ErrorThrower thrower(info->isolate(), "AsmJs::Compile"); + MaybeHandle<WasmModuleObject> maybe_compiled = SyncCompileTranslatedAsmJs( + info->isolate(), &thrower, + wasm::ModuleWireBytes(module->begin(), module->end()), info->script(), + Vector<const byte>(asm_offsets->begin(), asm_offsets->size())); + DCHECK(!maybe_compiled.is_null()); + DCHECK(!thrower.error()); + compile_time = compile_timer.Elapsed().InMillisecondsF(); + compiled = maybe_compiled.ToHandleChecked(); + } + // The result is a compiled module and serialized standard library uses. Handle<FixedArray> result = info->isolate()->factory()->NewFixedArray(kWasmDataEntryCount); - result->set(kWasmDataCompiledModule, *compiled.ToHandleChecked()); - result->set(kWasmDataForeignGlobals, *foreign_globals); + result->set(kWasmDataCompiledModule, *compiled); result->set(kWasmDataUsesArray, *uses_array); - result->set(kWasmDataScript, *info->script()); - result->set(kWasmDataScriptPosition, - Smi::FromInt(info->literal()->position())); - - MessageLocation location(info->script(), info->literal()->position(), - info->literal()->position()); - char text[100]; - int length; - if (FLAG_predictable) { - length = base::OS::SNPrintF(text, arraysize(text), "success"); - } else { - length = base::OS::SNPrintF( - text, arraysize(text), - "success, asm->wasm: %0.3f ms, compile: %0.3f ms, %" PRIuPTR " bytes", - asm_wasm_time, compile_time, wasm_size); - } - DCHECK_NE(-1, length); - USE(length); - Handle<String> stext(info->isolate()->factory()->InternalizeUtf8String(text)); - Handle<JSMessageObject> message = MessageHandler::MakeMessageObject( - info->isolate(), MessageTemplate::kAsmJsCompiled, &location, stext, - Handle<JSArray>::null()); - message->set_error_level(v8::Isolate::kMessageInfo); - if (!FLAG_suppress_asm_messages && FLAG_trace_asm_time) { - MessageHandler::ReportMessage(info->isolate(), &location, message); - } - + ReportCompilationSuccess(info->script(), info->literal()->position(), + translate_time, compile_time, module->size()); return result; } -bool AsmJs::IsStdlibValid(i::Isolate* isolate, Handle<FixedArray> wasm_data, - Handle<JSReceiver> stdlib) { - i::Handle<i::FixedArray> uses( - i::FixedArray::cast(wasm_data->get(kWasmDataUsesArray))); - for (int i = 0; i < uses->length(); ++i) { - if (!IsStdlibMemberValid(isolate, stdlib, - uses->GetValueChecked<i::Object>(isolate, i))) { - return false; - } - } - return true; -} - -MaybeHandle<Object> AsmJs::InstantiateAsmWasm(i::Isolate* isolate, +MaybeHandle<Object> AsmJs::InstantiateAsmWasm(Isolate* isolate, + Handle<SharedFunctionInfo> shared, Handle<FixedArray> wasm_data, - Handle<JSArrayBuffer> memory, - Handle<JSReceiver> foreign) { + Handle<JSReceiver> stdlib, + Handle<JSReceiver> foreign, + Handle<JSArrayBuffer> memory) { base::ElapsedTimer instantiate_timer; instantiate_timer.Start(); - i::Handle<i::WasmModuleObject> module( - i::WasmModuleObject::cast(wasm_data->get(kWasmDataCompiledModule))); - i::Handle<i::FixedArray> foreign_globals( - i::FixedArray::cast(wasm_data->get(kWasmDataForeignGlobals))); + Handle<FixedArray> stdlib_uses( + FixedArray::cast(wasm_data->get(kWasmDataUsesArray))); + Handle<WasmModuleObject> module( + WasmModuleObject::cast(wasm_data->get(kWasmDataCompiledModule))); + Handle<Script> script(Script::cast(shared->script())); + // TODO(mstarzinger): The position currently points to the module definition + // but should instead point to the instantiation site (more intuitive). + int position = shared->start_position(); + + // Check that all used stdlib members are valid. + bool stdlib_use_of_typed_array_present = false; + for (int i = 0; i < stdlib_uses->length(); ++i) { + if (stdlib.is_null()) { + ReportInstantiationFailure(script, position, "Requires standard library"); + return MaybeHandle<Object>(); + } + int member_id = Smi::cast(stdlib_uses->get(i))->value(); + wasm::AsmJsParser::StandardMember member = + static_cast<wasm::AsmJsParser::StandardMember>(member_id); + if (!IsStdlibMemberValid(isolate, stdlib, member, + &stdlib_use_of_typed_array_present)) { + ReportInstantiationFailure(script, position, "Unexpected stdlib member"); + return MaybeHandle<Object>(); + } + } // Create the ffi object for foreign functions {"": foreign}. Handle<JSObject> ffi_object; @@ -318,85 +297,47 @@ MaybeHandle<Object> AsmJs::InstantiateAsmWasm(i::Isolate* isolate, foreign, NONE); } - ErrorThrower thrower(isolate, "Asm.js -> WebAssembly instantiation"); - i::MaybeHandle<i::Object> maybe_module_object = - i::wasm::SyncInstantiate(isolate, &thrower, module, ffi_object, memory); + // Check that a valid heap buffer is provided if required. + if (stdlib_use_of_typed_array_present) { + if (memory.is_null()) { + ReportInstantiationFailure(script, position, "Requires heap buffer"); + return MaybeHandle<Object>(); + } + size_t size = NumberToSize(memory->byte_length()); + // TODO(mstarzinger): We currently only limit byte length of the buffer to + // be a multiple of 8, we should enforce the stricter spec limits here. + if (size % FixedTypedArrayBase::kMaxElementSize != 0) { + ReportInstantiationFailure(script, position, "Unexpected heap size"); + return MaybeHandle<Object>(); + } + } + + wasm::ErrorThrower thrower(isolate, "AsmJs::Instantiate"); + MaybeHandle<Object> maybe_module_object = + wasm::SyncInstantiate(isolate, &thrower, module, ffi_object, memory); if (maybe_module_object.is_null()) { - thrower.Reify(); // Ensure exceptions do not propagate. + thrower.Reset(); // Ensure exceptions do not propagate. + ReportInstantiationFailure(script, position, "Internal wasm failure"); return MaybeHandle<Object>(); } DCHECK(!thrower.error()); - i::Handle<i::Object> module_object = maybe_module_object.ToHandleChecked(); + Handle<Object> module_object = maybe_module_object.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(); + ReportInstantiationSuccess(script, position, + instantiate_timer.Elapsed().InMillisecondsF()); - 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; - } - 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( - wasm::AsmWasmBuilder::single_function_name)); - i::MaybeHandle<i::Object> single_function = - i::Object::GetProperty(module_object, single_function_name); + Handle<Name> single_function_name( + isolate->factory()->InternalizeUtf8String(AsmJs::kSingleFunctionName)); + MaybeHandle<Object> single_function = + Object::GetProperty(module_object, single_function_name); if (!single_function.is_null() && !single_function.ToHandleChecked()->IsUndefined(isolate)) { return single_function; } - i::Handle<i::Script> script(i::Script::cast(wasm_data->get(kWasmDataScript))); - int32_t position = 0; - if (!wasm_data->get(kWasmDataScriptPosition)->ToInt32(&position)) { - UNREACHABLE(); - } - MessageLocation location(script, position, position); - char text[50]; - int length; - if (FLAG_predictable) { - length = base::OS::SNPrintF(text, arraysize(text), "success"); - } else { - length = base::OS::SNPrintF(text, arraysize(text), "success, %0.3f ms", - instantiate_timer.Elapsed().InMillisecondsF()); - } - DCHECK_NE(-1, length); - USE(length); - Handle<String> stext(isolate->factory()->InternalizeUtf8String(text)); - Handle<JSMessageObject> message = MessageHandler::MakeMessageObject( - isolate, MessageTemplate::kAsmJsInstantiated, &location, stext, - Handle<JSArray>::null()); - message->set_error_level(v8::Isolate::kMessageInfo); - if (!FLAG_suppress_asm_messages && FLAG_trace_asm_time) { - MessageHandler::ReportMessage(isolate, &location, message); - } - Handle<String> exports_name = isolate->factory()->InternalizeUtf8String("exports"); - return i::Object::GetProperty(module_object, exports_name); + return Object::GetProperty(module_object, exports_name); } } // namespace internal |