// Copyright 2015 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "src/asmjs/asm-js.h" #include "src/asmjs/asm-names.h" #include "src/asmjs/asm-parser.h" #include "src/ast/ast.h" #include "src/base/optional.h" #include "src/base/platform/elapsed-timer.h" #include "src/codegen/compiler.h" #include "src/codegen/unoptimized-compilation-info.h" #include "src/common/assert-scope.h" #include "src/common/message-template.h" #include "src/execution/execution.h" #include "src/execution/isolate.h" #include "src/handles/handles.h" #include "src/heap/factory.h" #include "src/logging/counters.h" #include "src/objects/heap-number-inl.h" #include "src/objects/objects-inl.h" #include "src/parsing/parse-info.h" #include "src/parsing/scanner-character-streams.h" #include "src/parsing/scanner.h" #include "src/utils/vector.h" #include "src/wasm/wasm-engine.h" #include "src/wasm/wasm-js.h" #include "src/wasm/wasm-limits.h" #include "src/wasm/wasm-module-builder.h" #include "src/wasm/wasm-objects-inl.h" #include "src/wasm/wasm-result.h" namespace v8 { namespace internal { const char* const AsmJs::kSingleFunctionName = "__single_function__"; namespace { Handle StdlibMathMember(Isolate* isolate, Handle stdlib, Handle name) { Handle math_name( isolate->factory()->InternalizeString(StaticCharVector("Math"))); Handle math = JSReceiver::GetDataProperty(stdlib, math_name); if (!math->IsJSReceiver()) return isolate->factory()->undefined_value(); Handle math_receiver = Handle::cast(math); Handle value = JSReceiver::GetDataProperty(math_receiver, name); return value; } bool AreStdlibMembersValid(Isolate* isolate, Handle stdlib, wasm::AsmJsParser::StdlibSet members, bool* is_typed_array) { if (members.contains(wasm::AsmJsParser::StandardMember::kInfinity)) { members.Remove(wasm::AsmJsParser::StandardMember::kInfinity); Handle name = isolate->factory()->Infinity_string(); Handle value = JSReceiver::GetDataProperty(stdlib, name); if (!value->IsNumber() || !std::isinf(value->Number())) return false; } if (members.contains(wasm::AsmJsParser::StandardMember::kNaN)) { members.Remove(wasm::AsmJsParser::StandardMember::kNaN); Handle name = isolate->factory()->NaN_string(); Handle value = JSReceiver::GetDataProperty(stdlib, name); if (!value->IsNaN()) return false; } #define STDLIB_MATH_FUNC(fname, FName, ignore1, ignore2) \ if (members.contains(wasm::AsmJsParser::StandardMember::kMath##FName)) { \ members.Remove(wasm::AsmJsParser::StandardMember::kMath##FName); \ Handle name( \ isolate->factory()->InternalizeString(StaticCharVector(#fname))); \ Handle value = StdlibMathMember(isolate, stdlib, name); \ if (!value->IsJSFunction()) return false; \ SharedFunctionInfo shared = Handle::cast(value)->shared(); \ if (!shared.HasBuiltinId() || \ shared.builtin_id() != Builtins::kMath##FName) { \ return false; \ } \ DCHECK_EQ(shared.GetCode(), \ isolate->builtins()->builtin(Builtins::kMath##FName)); \ } STDLIB_MATH_FUNCTION_LIST(STDLIB_MATH_FUNC) #undef STDLIB_MATH_FUNC #define STDLIB_MATH_CONST(cname, const_value) \ if (members.contains(wasm::AsmJsParser::StandardMember::kMath##cname)) { \ members.Remove(wasm::AsmJsParser::StandardMember::kMath##cname); \ Handle name( \ isolate->factory()->InternalizeString(StaticCharVector(#cname))); \ Handle value = StdlibMathMember(isolate, stdlib, name); \ if (!value->IsNumber() || value->Number() != const_value) return false; \ } STDLIB_MATH_VALUE_LIST(STDLIB_MATH_CONST) #undef STDLIB_MATH_CONST #define STDLIB_ARRAY_TYPE(fname, FName) \ if (members.contains(wasm::AsmJsParser::StandardMember::k##FName)) { \ members.Remove(wasm::AsmJsParser::StandardMember::k##FName); \ *is_typed_array = true; \ Handle name( \ isolate->factory()->InternalizeString(StaticCharVector(#FName))); \ Handle value = JSReceiver::GetDataProperty(stdlib, name); \ if (!value->IsJSFunction()) return false; \ Handle func = Handle::cast(value); \ if (!func.is_identical_to(isolate->fname())) return false; \ } 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 // All members accounted for. DCHECK(members.empty()); return true; } void Report(Handle