42DirectHandle<Object> StdlibMathMember(Isolate* isolate,
43 DirectHandle<JSReceiver> stdlib,
44 DirectHandle<Name> name) {
45 DirectHandle<Name> math_name(
47 DirectHandle<Object> math =
49 if (!IsJSReceiver(*math))
return isolate->factory()->undefined_value();
54bool AreStdlibMembersValid(Isolate* isolate, DirectHandle<JSReceiver> stdlib,
56 bool* is_typed_array) {
59 DirectHandle<Name> name = isolate->factory()->Infinity_string();
60 DirectHandle<Object> value =
67 DirectHandle<Name> name = isolate->factory()->NaN_string();
68 DirectHandle<Object> value =
70 if (!
IsNaN(*value))
return false;
72#define STDLIB_MATH_FUNC(fname, FName, ignore1, ignore2) \
73 if (members.contains(wasm::AsmJsParser::StandardMember::kMath##FName)) { \
74 members.Remove(wasm::AsmJsParser::StandardMember::kMath##FName); \
75 DirectHandle<Name> name(isolate->factory()->InternalizeString( \
76 base::StaticCharVector(#fname))); \
77 DirectHandle<Object> value = StdlibMathMember(isolate, stdlib, name); \
78 if (!IsJSFunction(*value)) return false; \
79 Tagged<SharedFunctionInfo> shared = Cast<JSFunction>(value)->shared(); \
80 if (!shared->HasBuiltinId() || \
81 shared->builtin_id() != Builtin::kMath##FName) { \
84 DCHECK_EQ(shared->GetCode(isolate), \
85 isolate->builtins()->code(Builtin::kMath##FName)); \
88#undef STDLIB_MATH_FUNC
89#define STDLIB_MATH_CONST(cname, const_value) \
90 if (members.contains(wasm::AsmJsParser::StandardMember::kMath##cname)) { \
91 members.Remove(wasm::AsmJsParser::StandardMember::kMath##cname); \
92 DirectHandle<Name> name(isolate->factory()->InternalizeString( \
93 base::StaticCharVector(#cname))); \
94 DirectHandle<Object> value = StdlibMathMember(isolate, stdlib, name); \
95 if (!IsNumber(*value) || Object::NumberValue(*value) != const_value) \
99#undef STDLIB_MATH_CONST
100#define STDLIB_ARRAY_TYPE(fname, FName) \
101 if (members.contains(wasm::AsmJsParser::StandardMember::k##FName)) { \
102 members.Remove(wasm::AsmJsParser::StandardMember::k##FName); \
103 *is_typed_array = true; \
104 DirectHandle<Name> name(isolate->factory()->InternalizeString( \
105 base::StaticCharVector(#FName))); \
106 DirectHandle<Object> value = \
107 JSReceiver::GetDataProperty(isolate, stdlib, name); \
108 if (!IsJSFunction(*value)) return false; \
109 DirectHandle<JSFunction> func = Cast<JSFunction>(value); \
110 if (!func.is_identical_to(isolate->fname())) return false; \
120#undef STDLIB_ARRAY_TYPE
129 Isolate* isolate = script->GetIsolate();
131 DirectHandle<String> text_object =
132 isolate->factory()->InternalizeUtf8String(text);
134 isolate, message_template, &location, text_object);
135 message->set_error_level(level);
141 double compile_time,
size_t module_size) {
143 base::EmbeddedVector<char, 100> text;
144 int length =
SNPrintF(text,
"success, compile time %0.3f ms, %zu bytes",
145 compile_time, module_size);
147 text.Truncate(length);
148 Report(script,
position, text, MessageTemplate::kAsmJsCompiled,
153void ReportCompilationFailure(ParseInfo* parse_info,
int position,
154 const char* reason) {
155 if (
v8_flags.suppress_asm_messages)
return;
156 parse_info->pending_error_handler()->ReportWarningAt(
162 double instantiate_time) {
164 base::EmbeddedVector<char, 50> text;
165 int length =
SNPrintF(text,
"success, %0.3f ms", instantiate_time);
167 text.Truncate(length);
168 Report(script,
position, text, MessageTemplate::kAsmJsInstantiated,
174 const char* reason) {
175 if (
v8_flags.suppress_asm_messages)
return;
177 Report(script,
position, text, MessageTemplate::kAsmJsLinkingFailed,
239 std::optional<AllowHandleDereference> allow_deref;
241 allow_deref.emplace();
246 if (!
v8_flags.suppress_asm_messages) {
255 if (!
v8_flags.suppress_asm_messages) {
256 ReportCompilationFailure(
258 "Module size exceeds engine's supported maximum");
275 compile_timer.
Start();
288 shared_info->language_mode())
296 ReportCompilationSuccess(script, shared_info->StartPosition(),
compile_time_,
308 return std::make_unique<AsmJsCompilationJob>(parse_info,
literal, allocator);
312inline bool IsValidAsmjsMemorySize(
size_t size) {
314 if (size < (1u << 12u))
return false;
318 if (size < (1u << 24u)) {
319 uint32_t size32 =
static_cast<uint32_t
>(
size);
323 if ((size % (1u << 24u)) != 0)
return false;
329 if (size > 0x8000'0000u)
return false;
340 instantiate_timer.
Start();
347 wasm_engine->FinalizeTranslatedAsmJs(isolate, wasm_data, script);
351 int position = shared->StartPosition();
355 ReportInstantiationFailure(script,
position,
356 "Cannot be instantiated as resumable function");
361 bool stdlib_use_of_typed_array_present =
false;
364 if (!stdlib_uses.
empty()) {
366 ReportInstantiationFailure(script,
position,
"Requires standard library");
369 if (!AreStdlibMembersValid(isolate, stdlib, stdlib_uses,
370 &stdlib_use_of_typed_array_present)) {
371 ReportInstantiationFailure(script,
position,
"Unexpected stdlib member");
377 if (stdlib_use_of_typed_array_present) {
378 if (memory.is_null()) {
379 ReportInstantiationFailure(script,
position,
"Requires heap buffer");
383 if (memory->is_shared()) {
384 ReportInstantiationFailure(script,
position,
385 "Invalid heap type: SharedArrayBuffer");
390 if (memory->is_resizable_by_js()) {
391 ReportInstantiationFailure(script,
position,
392 "Invalid heap type: resizable ArrayBuffer");
397 if (memory->GetBackingStore() &&
398 memory->GetBackingStore()->is_wasm_memory()) {
399 ReportInstantiationFailure(script,
position,
400 "Invalid heap type: WebAssembly.Memory");
403 size_t size = memory->byte_length();
405 if (!IsValidAsmjsMemorySize(size)) {
406 ReportInstantiationFailure(script,
position,
"Invalid heap size");
411 memory->set_is_detachable(
false);
418 wasm_engine->SyncInstantiate(isolate, &thrower, module, foreign, memory);
419 if (maybe_instance.
is_null()) {
423 if (isolate->is_execution_terminating())
return {};
424 if (isolate->has_exception()) isolate->clear_exception();
425 if (thrower.
error()) {
427 SNPrintF(error_reason,
"Internal wasm failure: %s", thrower.
error_msg());
428 ReportInstantiationFailure(script,
position, error_reason.
begin());
430 ReportInstantiationFailure(script,
position,
"Internal wasm failure");
438 ReportInstantiationSuccess(script,
position,
445 if (!single_function.
is_null() &&
447 return single_function;
454 DCHECK(IsJSObject(instance->exports_object()));
#define STDLIB_MATH_CONST(cname, const_value)
#define STDLIB_MATH_FUNC(fname, FName, ignore1, ignore2)
#define STDLIB_ARRAY_TYPE(fname, FName)
#define STDLIB_MATH_VALUE_LIST(V)
#define STDLIB_MATH_FUNCTION_LIST(V)
TimeDelta Elapsed() const
static constexpr EnumSet FromIntegral(uint64_t bits)
constexpr bool empty() const
constexpr T ToIntegral() const
double InMillisecondsF() const
constexpr T * begin() const
void RecordHistograms(Isolate *isolate)
AccountingAllocator * allocator_
wasm::ZoneBuffer * asm_offsets_
AsmJsCompilationJob(const AsmJsCompilationJob &)=delete
UnoptimizedCompilationInfo compilation_info_
AsmJsCompilationJob & operator=(const AsmJsCompilationJob &)=delete
wasm::AsmJsParser::StdlibSet stdlib_uses_
wasm::ZoneBuffer * module_
AsmJsCompilationJob(ParseInfo *parse_info, FunctionLiteral *literal, AccountingAllocator *allocator)
Status ExecuteJobImpl() final
Status FinalizeJobImpl(DirectHandle< SharedFunctionInfo > shared_info, Isolate *isolate) final
static const char *const kSingleFunctionName
static MaybeDirectHandle< Object > InstantiateAsmWasm(Isolate *isolate, DirectHandle< SharedFunctionInfo >, DirectHandle< AsmWasmData > wasm_data, DirectHandle< JSReceiver > stdlib, DirectHandle< JSReceiver > foreign, DirectHandle< JSArrayBuffer > memory)
static std::unique_ptr< UnoptimizedCompilationJob > NewCompilationJob(ParseInfo *parse_info, FunctionLiteral *literal, AccountingAllocator *allocator)
V8_INLINE bool is_null() const
int start_position() const
static Handle< Object > GetDataProperty(Isolate *isolate, DirectHandle< JSReceiver > object, DirectHandle< Name > name)
V8_INLINE DirectHandle< T > ToHandleChecked() const
V8_INLINE bool is_null() const
static V8_EXPORT_PRIVATE void ReportMessage(Isolate *isolate, const MessageLocation *loc, DirectHandle< JSMessageObject > message)
static V8_EXPORT_PRIVATE Handle< JSMessageObject > MakeMessageObject(Isolate *isolate, MessageTemplate type, const MessageLocation *location, DirectHandle< Object > argument, DirectHandle< StackTraceInfo > stack_trace=DirectHandle< StackTraceInfo >::null())
static double NumberValue(Tagged< Number > obj)
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT MaybeHandle< Object > GetProperty(LookupIterator *it, bool is_global_reference=false)
Utf16CharacterStream * character_stream() const
void SetAsmWasmData(Handle< AsmWasmData > asm_wasm_data)
FunctionLiteral * literal() const
ParseInfo * parse_info() const
uintptr_t stack_limit() const
UnoptimizedCompilationInfo * compilation_info() const
virtual bool can_access_heap() const =0
int failure_location() const
const StdlibSet * stdlib_uses() const
base::EnumSet< StandardMember, uint64_t > StdlibSet
const char * failure_message() const
WasmModuleBuilder * module_builder()
MaybeHandle< AsmWasmData > SyncCompileTranslatedAsmJs(Isolate *isolate, ErrorThrower *thrower, base::OwnedVector< const uint8_t > bytes, DirectHandle< Script > script, base::Vector< const uint8_t > asm_js_offset_table_bytes, DirectHandle< HeapNumber > uses_bitset, LanguageMode language_mode)
void WriteTo(ZoneBuffer *buffer) const
void WriteAsmJsOffsetTable(ZoneBuffer *buffer) const
ZoneVector< RpoNumber > & result
FunctionLiteral * literal
constexpr bool IsPowerOfTwo(T value)
int SNPrintF(Vector< char > str, const char *format,...)
constexpr Vector< const char > StaticCharVector(const char(&array)[N])
constexpr Vector< T > VectorOf(T *start, size_t size)
Vector< const char > CStrVector(const char *data)
OwnedVector< T > OwnedCopyOf(const T *data, size_t size)
uint64_t max_mem32_bytes()
WasmEngine * GetWasmEngine()
bool IsNaN(Tagged< Object > obj)
bool IsNumber(Tagged< Object > obj)
bool IsResumableFunction(FunctionKind kind)
V8_INLINE DirectHandle< T > direct_handle(Tagged< T > object, Isolate *isolate)
V8_EXPORT_PRIVATE FlagValues v8_flags
kInterpreterTrampolineOffset script
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
#define CHECK_NE(lhs, rhs)
#define DCHECK(condition)