1f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Copyright 2015 the V8 project authors. All rights reserved. 2f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// found in the LICENSE file. 4f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 5f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/asmjs/asm-js.h" 6f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 7f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/api-natives.h" 8f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/api.h" 9f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/asmjs/asm-typer.h" 10f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/asmjs/asm-wasm-builder.h" 11f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/assert-scope.h" 12f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/execution.h" 13f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/factory.h" 14f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/handles.h" 15f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/isolate.h" 16f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/objects.h" 17f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/parsing/parse-info.h" 18f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 19f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/wasm/module-decoder.h" 20f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/wasm/wasm-js.h" 21f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/wasm/wasm-module-builder.h" 22f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/wasm/wasm-module.h" 23c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "src/wasm/wasm-objects.h" 24f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/wasm/wasm-result.h" 25f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 26f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtypedef uint8_t byte; 27f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 28f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochusing v8::internal::wasm::ErrorThrower; 29f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 30f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace v8 { 31f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace internal { 32f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 33f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace { 34f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochHandle<i::Object> StdlibMathMember(i::Isolate* isolate, 35f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<JSReceiver> stdlib, 36f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Name> name) { 37f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (stdlib.is_null()) { 38f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Handle<i::Object>(); 39f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 40f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<i::Name> math_name( 41f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("Math"))); 42f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch MaybeHandle<i::Object> maybe_math = i::Object::GetProperty(stdlib, math_name); 43f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (maybe_math.is_null()) { 44f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Handle<i::Object>(); 45f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 46f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<i::Object> math = maybe_math.ToHandleChecked(); 47f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!math->IsJSReceiver()) { 48f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Handle<i::Object>(); 49f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 50f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch MaybeHandle<i::Object> maybe_value = i::Object::GetProperty(math, name); 51f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (maybe_value.is_null()) { 52f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Handle<i::Object>(); 53f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 54f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return maybe_value.ToHandleChecked(); 55f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 56f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 57f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool IsStdlibMemberValid(i::Isolate* isolate, Handle<JSReceiver> stdlib, 58f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<i::Object> member_id) { 59f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int32_t member_kind; 60f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!member_id->ToInt32(&member_kind)) { 61f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UNREACHABLE(); 62f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 63f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch switch (member_kind) { 64f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case wasm::AsmTyper::StandardMember::kNone: 65f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case wasm::AsmTyper::StandardMember::kModule: 66f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case wasm::AsmTyper::StandardMember::kStdlib: 67f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case wasm::AsmTyper::StandardMember::kHeap: 68f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case wasm::AsmTyper::StandardMember::kFFI: { 69f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Nothing to check for these. 70f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return true; 71f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 72f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case wasm::AsmTyper::StandardMember::kInfinity: { 73f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (stdlib.is_null()) { 74f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return false; 75f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 76f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<i::Name> name(isolate->factory()->InternalizeOneByteString( 77f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STATIC_CHAR_VECTOR("Infinity"))); 78f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch MaybeHandle<i::Object> maybe_value = i::Object::GetProperty(stdlib, name); 79f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (maybe_value.is_null()) { 80f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return false; 81f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 82f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<i::Object> value = maybe_value.ToHandleChecked(); 83f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return value->IsNumber() && std::isinf(value->Number()); 84f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 85f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case wasm::AsmTyper::StandardMember::kNaN: { 86f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (stdlib.is_null()) { 87f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return false; 88f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 89f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<i::Name> name(isolate->factory()->InternalizeOneByteString( 90f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STATIC_CHAR_VECTOR("NaN"))); 91f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch MaybeHandle<i::Object> maybe_value = i::Object::GetProperty(stdlib, name); 92f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (maybe_value.is_null()) { 93f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return false; 94f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 95f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<i::Object> value = maybe_value.ToHandleChecked(); 96f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return value->IsNaN(); 97f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 98f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define STDLIB_MATH_FUNC(CamelName, fname) \ 99f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case wasm::AsmTyper::StandardMember::k##CamelName: { \ 100f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<i::Name> name(isolate->factory()->InternalizeOneByteString( \ 101f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STATIC_CHAR_VECTOR(#fname))); \ 102f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<i::Object> value = StdlibMathMember(isolate, stdlib, name); \ 103f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (value.is_null() || !value->IsJSFunction()) { \ 104f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return false; \ 105f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } \ 106f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<i::JSFunction> func(i::JSFunction::cast(*value)); \ 107f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return func->shared()->code() == \ 108f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate->builtins()->builtin(Builtins::k##CamelName); \ 109f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 110f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STDLIB_MATH_FUNC(MathAcos, acos) 111f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STDLIB_MATH_FUNC(MathAsin, asin) 112f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STDLIB_MATH_FUNC(MathAtan, atan) 113f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STDLIB_MATH_FUNC(MathCos, cos) 114f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STDLIB_MATH_FUNC(MathSin, sin) 115f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STDLIB_MATH_FUNC(MathTan, tan) 116f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STDLIB_MATH_FUNC(MathExp, exp) 117f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STDLIB_MATH_FUNC(MathLog, log) 118f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STDLIB_MATH_FUNC(MathCeil, ceil) 119f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STDLIB_MATH_FUNC(MathFloor, floor) 120f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STDLIB_MATH_FUNC(MathSqrt, sqrt) 121f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STDLIB_MATH_FUNC(MathAbs, abs) 122f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STDLIB_MATH_FUNC(MathClz32, clz32) 123f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STDLIB_MATH_FUNC(MathMin, min) 124f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STDLIB_MATH_FUNC(MathMax, max) 125f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STDLIB_MATH_FUNC(MathAtan2, atan2) 126f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STDLIB_MATH_FUNC(MathPow, pow) 127f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STDLIB_MATH_FUNC(MathImul, imul) 128f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STDLIB_MATH_FUNC(MathFround, fround) 129f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#undef STDLIB_MATH_FUNC 130f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define STDLIB_MATH_CONST(cname, const_value) \ 131f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case wasm::AsmTyper::StandardMember::kMath##cname: { \ 132f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch i::Handle<i::Name> name(isolate->factory()->InternalizeOneByteString( \ 133f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STATIC_CHAR_VECTOR(#cname))); \ 134f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch i::Handle<i::Object> value = StdlibMathMember(isolate, stdlib, name); \ 135f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return !value.is_null() && value->IsNumber() && \ 136f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch value->Number() == const_value; \ 137f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 138f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STDLIB_MATH_CONST(E, 2.718281828459045) 139f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STDLIB_MATH_CONST(LN10, 2.302585092994046) 140f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STDLIB_MATH_CONST(LN2, 0.6931471805599453) 141f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STDLIB_MATH_CONST(LOG2E, 1.4426950408889634) 142f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STDLIB_MATH_CONST(LOG10E, 0.4342944819032518) 143f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STDLIB_MATH_CONST(PI, 3.141592653589793) 144f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STDLIB_MATH_CONST(SQRT1_2, 0.7071067811865476) 145f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STDLIB_MATH_CONST(SQRT2, 1.4142135623730951) 146f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#undef STDLIB_MATH_CONST 147f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch default: { UNREACHABLE(); } 148f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 149f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return false; 150f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 151f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 152f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} // namespace 153f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 154f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochMaybeHandle<FixedArray> AsmJs::ConvertAsmToWasm(ParseInfo* info) { 155f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ErrorThrower thrower(info->isolate(), "Asm.js -> WebAssembly conversion"); 156f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch wasm::AsmTyper typer(info->isolate(), info->zone(), *(info->script()), 157f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch info->literal()); 158f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!typer.Validate()) { 159f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(!info->isolate()->has_pending_exception()); 160f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch PrintF("Validation of asm.js module failed: %s", typer.error_message()); 161f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return MaybeHandle<FixedArray>(); 162f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 163f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch v8::internal::wasm::AsmWasmBuilder builder(info->isolate(), info->zone(), 164f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch info->literal(), &typer); 165f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch i::Handle<i::FixedArray> foreign_globals; 166c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch auto asm_wasm_result = builder.Run(&foreign_globals); 167c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch wasm::ZoneBuffer* module = asm_wasm_result.module_bytes; 168c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch wasm::ZoneBuffer* asm_offsets = asm_wasm_result.asm_offset_table; 169f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 170f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch i::MaybeHandle<i::JSObject> compiled = wasm::CreateModuleObjectFromBytes( 171f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch info->isolate(), module->begin(), module->end(), &thrower, 172c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch internal::wasm::kAsmJsOrigin, info->script(), asm_offsets->begin(), 173c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch asm_offsets->end()); 174f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(!compiled.is_null()); 175f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 176f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch wasm::AsmTyper::StdlibSet uses = typer.StdlibUses(); 177f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<FixedArray> uses_array = 178f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch info->isolate()->factory()->NewFixedArray(static_cast<int>(uses.size())); 179f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int count = 0; 180f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (auto i : uses) { 181f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch uses_array->set(count++, Smi::FromInt(i)); 182f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 183f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 184f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<FixedArray> result = info->isolate()->factory()->NewFixedArray(3); 185f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch result->set(0, *compiled.ToHandleChecked()); 186f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch result->set(1, *foreign_globals); 187f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch result->set(2, *uses_array); 188f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return result; 189f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 190f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 191f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool AsmJs::IsStdlibValid(i::Isolate* isolate, Handle<FixedArray> wasm_data, 192f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<JSReceiver> stdlib) { 193f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch i::Handle<i::FixedArray> uses(i::FixedArray::cast(wasm_data->get(2))); 194f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (int i = 0; i < uses->length(); ++i) { 195f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!IsStdlibMemberValid(isolate, stdlib, 196f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch uses->GetValueChecked<i::Object>(isolate, i))) { 197f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return false; 198f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 199f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 200f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return true; 201f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 202f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 203f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochMaybeHandle<Object> AsmJs::InstantiateAsmWasm(i::Isolate* isolate, 204f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<FixedArray> wasm_data, 205f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<JSArrayBuffer> memory, 206f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<JSReceiver> foreign) { 207f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch i::Handle<i::JSObject> module(i::JSObject::cast(wasm_data->get(0))); 208f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch i::Handle<i::FixedArray> foreign_globals( 209f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch i::FixedArray::cast(wasm_data->get(1))); 210f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 211f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ErrorThrower thrower(isolate, "Asm.js -> WebAssembly instantiation"); 212f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 213f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch i::MaybeHandle<i::JSObject> maybe_module_object = 214f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch i::wasm::WasmModule::Instantiate(isolate, &thrower, module, foreign, 215f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch memory); 216f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (maybe_module_object.is_null()) { 217f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return MaybeHandle<Object>(); 218f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 219f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 220f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch i::Handle<i::Name> init_name(isolate->factory()->InternalizeUtf8String( 221f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch wasm::AsmWasmBuilder::foreign_init_name)); 222f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 223f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch i::Handle<i::Object> module_object = maybe_module_object.ToHandleChecked(); 224f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch i::MaybeHandle<i::Object> maybe_init = 225f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch i::Object::GetProperty(module_object, init_name); 226f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(!maybe_init.is_null()); 227f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 228f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch i::Handle<i::Object> init = maybe_init.ToHandleChecked(); 229f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch i::Handle<i::Object> undefined(isolate->heap()->undefined_value(), isolate); 230f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch i::Handle<i::Object>* foreign_args_array = 231f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch new i::Handle<i::Object>[foreign_globals->length()]; 232f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (int j = 0; j < foreign_globals->length(); j++) { 233f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!foreign.is_null()) { 234f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch i::MaybeHandle<i::Name> name = i::Object::ToName( 235f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate, i::Handle<i::Object>(foreign_globals->get(j), isolate)); 236f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!name.is_null()) { 237f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch i::MaybeHandle<i::Object> val = 238f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch i::Object::GetProperty(foreign, name.ToHandleChecked()); 239f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!val.is_null()) { 240f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch foreign_args_array[j] = val.ToHandleChecked(); 241f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch continue; 242f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 243f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 244f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 245f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch foreign_args_array[j] = undefined; 246f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 247f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch i::MaybeHandle<i::Object> retval = i::Execution::Call( 248f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate, init, undefined, foreign_globals->length(), foreign_args_array); 249f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch delete[] foreign_args_array; 250f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(!retval.is_null()); 251f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 252f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch i::Handle<i::Name> single_function_name( 253f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch isolate->factory()->InternalizeUtf8String( 254f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch wasm::AsmWasmBuilder::single_function_name)); 255f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch i::MaybeHandle<i::Object> single_function = 256f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch i::Object::GetProperty(module_object, single_function_name); 257f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!single_function.is_null() && 258f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch !single_function.ToHandleChecked()->IsUndefined(isolate)) { 259f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return single_function; 260f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 261f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return module_object; 262f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 263f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 264f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} // namespace internal 265f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} // namespace v8 266