1014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Copyright 2015 the V8 project authors. All rights reserved. 2014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// found in the LICENSE file. 4014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/api-natives.h" 613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include "src/api.h" 7f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/asmjs/asm-js.h" 8f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/asmjs/asm-typer.h" 9f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/asmjs/asm-wasm-builder.h" 10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/assert-scope.h" 11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/ast/ast.h" 1213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include "src/execution.h" 13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/factory.h" 14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/handles.h" 15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/isolate.h" 1662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/objects-inl.h" 17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/objects.h" 18f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/parsing/parse-info.h" 19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/wasm/module-decoder.h" 21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/wasm/wasm-js.h" 2262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/wasm/wasm-limits.h" 23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/wasm/wasm-module.h" 24c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "src/wasm/wasm-objects.h" 25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/wasm/wasm-result.h" 26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtypedef uint8_t byte; 28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochusing v8::internal::wasm::ErrorThrower; 30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace v8 { 32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace { 3462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 3562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#define RANGE_ERROR_MSG \ 3662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch "Wasm compilation exceeds internal limits in this context for the provided " \ 3762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch "arguments" 3862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 3962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// TODO(wasm): move brand check to the respective types, and don't throw 4062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// in it, rather, use a provided ErrorThrower, or let caller handle it. 4162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochstatic bool HasBrand(i::Handle<i::Object> value, i::Handle<i::Symbol> sym) { 4262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!value->IsJSObject()) return false; 4362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Handle<i::JSObject> object = i::Handle<i::JSObject>::cast(value); 4462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Maybe<bool> has_brand = i::JSObject::HasOwnProperty(object, sym); 4562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return has_brand.FromMaybe(false); 4662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 4762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 4862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochstatic bool BrandCheck(i::Handle<i::Object> value, i::Handle<i::Symbol> sym, 4962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ErrorThrower* thrower, const char* msg) { 5062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return HasBrand(value, sym) ? true : (thrower->TypeError("%s", msg), false); 5162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 5262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 53f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochi::Handle<i::String> v8_str(i::Isolate* isolate, const char* str) { 54f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return isolate->factory()->NewStringFromAsciiChecked(str); 55f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 56f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochLocal<String> v8_str(Isolate* isolate, const char* str) { 57f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return Utils::ToLocal(v8_str(reinterpret_cast<i::Isolate*>(isolate), str)); 58f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 59f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 6062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochi::MaybeHandle<i::WasmModuleObject> GetFirstArgumentAsModule( 6162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) { 6262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8::Isolate* isolate = args.GetIsolate(); 6362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (args.Length() < 1) { 6462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch thrower->TypeError("Argument 0 must be a WebAssembly.Module"); 6562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return {}; 6662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 6862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Local<Context> context = isolate->GetCurrentContext(); 6962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Handle<i::Context> i_context = Utils::OpenHandle(*context); 7062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!BrandCheck(Utils::OpenHandle(*args[0]), 7162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::handle(i_context->wasm_module_sym()), thrower, 7262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch "Argument 0 must be a WebAssembly.Module")) { 7362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return {}; 7462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 7562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 7662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Local<Object> module_obj = Local<Object>::Cast(args[0]); 7762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return i::Handle<i::WasmModuleObject>::cast( 7862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8::Utils::OpenHandle(*module_obj)); 7962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 8062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 8162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochbool IsCompilationAllowed(i::Isolate* isolate, ErrorThrower* thrower, 8262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8::Local<v8::Value> source, bool is_async) { 8362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Allow caller to do one final check on thrower state, rather than 8462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // one at each step. No information is lost - failure reason is captured 8562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // in the thrower state. 8662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (thrower->error()) return false; 8762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 8862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch AllowWasmCompileCallback callback = isolate->allow_wasm_compile_callback(); 8962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (callback != nullptr && 9062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch !callback(reinterpret_cast<v8::Isolate*>(isolate), source, is_async)) { 9162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch thrower->RangeError(RANGE_ERROR_MSG); 9262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return false; 9362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 9462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return true; 9562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 9662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 9762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochbool IsInstantiationAllowed(i::Isolate* isolate, ErrorThrower* thrower, 9862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8::Local<v8::Value> module_or_bytes, 9962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::MaybeHandle<i::JSReceiver> ffi, bool is_async) { 10062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Allow caller to do one final check on thrower state, rather than 10162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // one at each step. No information is lost - failure reason is captured 10262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // in the thrower state. 10362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (thrower->error()) return false; 10462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8::MaybeLocal<v8::Value> v8_ffi; 10562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!ffi.is_null()) { 10662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8_ffi = v8::Local<v8::Value>::Cast(Utils::ToLocal(ffi.ToHandleChecked())); 10762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 10862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch AllowWasmInstantiateCallback callback = 10962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isolate->allow_wasm_instantiate_callback(); 11062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (callback != nullptr && 11162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch !callback(reinterpret_cast<v8::Isolate*>(isolate), module_or_bytes, 11262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8_ffi, is_async)) { 11362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch thrower->RangeError(RANGE_ERROR_MSG); 11462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return false; 11562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 11662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return true; 11762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 11862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 11962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochi::wasm::ModuleWireBytes GetFirstArgumentAsBytes( 12062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) { 12162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (args.Length() < 1) { 12262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch thrower->TypeError("Argument 0 must be a buffer source"); 12362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return i::wasm::ModuleWireBytes(nullptr, nullptr); 12462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 12662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const byte* start = nullptr; 12762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch size_t length = 0; 12862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8::Local<v8::Value> source = args[0]; 12913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (source->IsArrayBuffer()) { 1303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // A raw array buffer was passed. 13113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Local<ArrayBuffer> buffer = Local<ArrayBuffer>::Cast(source); 1323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ArrayBuffer::Contents contents = buffer->GetContents(); 1333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch start = reinterpret_cast<const byte*>(contents.Data()); 13562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch length = contents.ByteLength(); 13613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } else if (source->IsTypedArray()) { 1373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // A TypedArray was passed. 13813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Local<TypedArray> array = Local<TypedArray>::Cast(source); 1393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Local<ArrayBuffer> buffer = array->Buffer(); 1403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ArrayBuffer::Contents contents = buffer->GetContents(); 1423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch start = 1443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch reinterpret_cast<const byte*>(contents.Data()) + array->ByteOffset(); 14562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch length = array->ByteLength(); 1463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 14762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch thrower->TypeError("Argument 0 must be a buffer source"); 148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 14962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_IMPLIES(length, start != nullptr); 15062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (length == 0) { 15162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch thrower->CompileError("BufferSource argument is empty"); 15262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 15362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (length > i::wasm::kV8MaxWasmModuleSize) { 15462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch thrower->RangeError("buffer source exceeds maximum size of %zu (is %zu)", 15562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::wasm::kV8MaxWasmModuleSize, length); 15662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 15762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (thrower->error()) return i::wasm::ModuleWireBytes(nullptr, nullptr); 15862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // TODO(titzer): use the handle as well? 15962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return i::wasm::ModuleWireBytes(start, start + length); 160f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 161f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 16262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochi::MaybeHandle<i::JSReceiver> GetSecondArgumentAsImports( 16362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) { 16462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (args.Length() < 2) return {}; 16562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (args[1]->IsUndefined()) return {}; 16613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 16762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!args[1]->IsObject()) { 16862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch thrower->TypeError("Argument 1 must be an object"); 16962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return {}; 170f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 17162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Local<Object> obj = Local<Object>::Cast(args[1]); 17262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj)); 17313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 17413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 17562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// WebAssembly.compile(bytes) -> Promise 17613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid WebAssemblyCompile(const v8::FunctionCallbackInfo<v8::Value>& args) { 17713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch v8::Isolate* isolate = args.GetIsolate(); 17862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 17913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch HandleScope scope(isolate); 18062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ErrorThrower thrower(i_isolate, "WebAssembly.compile()"); 18113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 18213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Local<Context> context = isolate->GetCurrentContext(); 18313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch v8::Local<v8::Promise::Resolver> resolver; 18413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (!v8::Promise::Resolver::New(context).ToLocal(&resolver)) return; 18513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 18613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return_value.Set(resolver->GetPromise()); 18762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 18862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch auto bytes = GetFirstArgumentAsBytes(args, &thrower); 18962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!IsCompilationAllowed(i_isolate, &thrower, args[0], true)) { 19062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch resolver->Reject(context, Utils::ToLocal(thrower.Reify())); 19162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return; 19262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 19362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(!thrower.error()); 19462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Handle<i::JSPromise> promise = Utils::OpenHandle(*resolver->GetPromise()); 19562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::wasm::AsyncCompile(i_isolate, promise, bytes); 19613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 19713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 19862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// WebAssembly.validate(bytes) -> bool 199f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid WebAssemblyValidate(const v8::FunctionCallbackInfo<v8::Value>& args) { 200f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8::Isolate* isolate = args.GetIsolate(); 20162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 202f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch HandleScope scope(isolate); 20362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ErrorThrower thrower(i_isolate, "WebAssembly.validate()"); 204f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 20562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch auto bytes = GetFirstArgumentAsBytes(args, &thrower); 206f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 207f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 20862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!thrower.error() && 20962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::wasm::SyncValidate(reinterpret_cast<i::Isolate*>(isolate), &thrower, 21062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bytes)) { 211f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return_value.Set(v8::True(isolate)); 212f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } else { 21362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (thrower.wasm_error()) thrower.Reify(); // Clear error. 214f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return_value.Set(v8::False(isolate)); 215f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 216f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 217f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 21862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// new WebAssembly.Module(bytes) -> WebAssembly.Module 21913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid WebAssemblyModule(const v8::FunctionCallbackInfo<v8::Value>& args) { 22013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch v8::Isolate* isolate = args.GetIsolate(); 22162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 22213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch HandleScope scope(isolate); 22362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ErrorThrower thrower(i_isolate, "WebAssembly.Module()"); 22413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 22562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch auto bytes = GetFirstArgumentAsBytes(args, &thrower); 22662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!IsCompilationAllowed(i_isolate, &thrower, args[0], false)) return; 22762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 22862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(!thrower.error()); 22962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::MaybeHandle<i::Object> module_obj = 23062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::wasm::SyncCompile(i_isolate, &thrower, bytes); 23113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (module_obj.is_null()) return; 23213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 23313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 23413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return_value.Set(Utils::ToLocal(module_obj.ToHandleChecked())); 23513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 23613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 23762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// WebAssembly.Module.imports(module) -> Array<Import> 23862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid WebAssemblyModuleImports(const v8::FunctionCallbackInfo<v8::Value>& args) { 23962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HandleScope scope(args.GetIsolate()); 24062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8::Isolate* isolate = args.GetIsolate(); 24162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 24262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ErrorThrower thrower(i_isolate, "WebAssembly.Module.imports()"); 24362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 24462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch auto maybe_module = GetFirstArgumentAsModule(args, &thrower); 24562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (thrower.error()) return; 24662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch auto imports = i::wasm::GetImports(i_isolate, maybe_module.ToHandleChecked()); 24762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch args.GetReturnValue().Set(Utils::ToLocal(imports)); 24862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 24962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 25062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// WebAssembly.Module.exports(module) -> Array<Export> 25162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid WebAssemblyModuleExports(const v8::FunctionCallbackInfo<v8::Value>& args) { 25213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch HandleScope scope(args.GetIsolate()); 25313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch v8::Isolate* isolate = args.GetIsolate(); 254f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 25562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ErrorThrower thrower(i_isolate, "WebAssembly.Module.exports()"); 25662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 25762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch auto maybe_module = GetFirstArgumentAsModule(args, &thrower); 25862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (thrower.error()) return; 25962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch auto exports = i::wasm::GetExports(i_isolate, maybe_module.ToHandleChecked()); 26062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch args.GetReturnValue().Set(Utils::ToLocal(exports)); 26162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 262f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 26362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// WebAssembly.Module.customSections(module, name) -> Array<Section> 26462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid WebAssemblyModuleCustomSections( 26562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const v8::FunctionCallbackInfo<v8::Value>& args) { 26662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HandleScope scope(args.GetIsolate()); 26762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8::Isolate* isolate = args.GetIsolate(); 26862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 26962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ErrorThrower thrower(i_isolate, "WebAssembly.Module.customSections()"); 27062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 27162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch auto maybe_module = GetFirstArgumentAsModule(args, &thrower); 27262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (thrower.error()) return; 27362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 27462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (args.Length() < 2) { 27562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch thrower.TypeError("Argument 1 must be a string"); 27662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return; 27762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 27862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 27962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Handle<i::Object> name = Utils::OpenHandle(*args[1]); 28062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!name->IsString()) { 28162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch thrower.TypeError("Argument 1 must be a string"); 28262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return; 28362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 28462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 28562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch auto custom_sections = 28662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::wasm::GetCustomSections(i_isolate, maybe_module.ToHandleChecked(), 28762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Handle<i::String>::cast(name), &thrower); 28862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (thrower.error()) return; 28962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch args.GetReturnValue().Set(Utils::ToLocal(custom_sections)); 29062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 29162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 29262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// new WebAssembly.Instance(module, imports) -> WebAssembly.Instance 29362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) { 29462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HandleScope scope(args.GetIsolate()); 29562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8::Isolate* isolate = args.GetIsolate(); 29662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 297f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ErrorThrower thrower(i_isolate, "WebAssembly.Instance()"); 29813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 29962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch auto maybe_module = GetFirstArgumentAsModule(args, &thrower); 30062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (thrower.error()) return; 30162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 30262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch auto maybe_imports = GetSecondArgumentAsImports(args, &thrower); 30362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!IsInstantiationAllowed(i_isolate, &thrower, args[0], maybe_imports, 30462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch false)) { 30513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return; 30613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 30762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(!thrower.error()); 30862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 30962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::MaybeHandle<i::Object> instance_object = i::wasm::SyncInstantiate( 31062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i_isolate, &thrower, maybe_module.ToHandleChecked(), maybe_imports, 31162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::MaybeHandle<i::JSArrayBuffer>()); 31262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (instance_object.is_null()) return; 31362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch args.GetReturnValue().Set(Utils::ToLocal(instance_object.ToHandleChecked())); 31462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 31562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 31662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// WebAssembly.instantiate(module, imports) -> WebAssembly.Instance 31762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// WebAssembly.instantiate(bytes, imports) -> 31862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// {module: WebAssembly.Module, instance: WebAssembly.Instance} 31962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) { 32062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8::Isolate* isolate = args.GetIsolate(); 32162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 32262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ErrorThrower thrower(i_isolate, "WebAssembly.instantiate()"); 32362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 32462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HandleScope scope(isolate); 325f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 32613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Local<Context> context = isolate->GetCurrentContext(); 32713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch i::Handle<i::Context> i_context = Utils::OpenHandle(*context); 32862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 32962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8::Local<v8::Promise::Resolver> resolver; 33062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!v8::Promise::Resolver::New(context).ToLocal(&resolver)) return; 33162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 33262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return_value.Set(resolver->GetPromise()); 33362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 33462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (args.Length() < 1) { 33562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch thrower.TypeError( 33662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch "Argument 0 must be provided and must be either a buffer source or a " 33762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch "WebAssembly.Module object"); 33862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch resolver->Reject(context, Utils::ToLocal(thrower.Reify())); 339f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return; 340f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 34113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 34262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Handle<i::Object> first_arg = Utils::OpenHandle(*args[0]); 34362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!first_arg->IsJSObject()) { 34462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch thrower.TypeError( 34562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch "Argument 0 must be a buffer source or a WebAssembly.Module object"); 34662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch resolver->Reject(context, Utils::ToLocal(thrower.Reify())); 34762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return; 348f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 349f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 35062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch auto maybe_imports = GetSecondArgumentAsImports(args, &thrower); 35162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (thrower.error()) { 35262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch resolver->Reject(context, Utils::ToLocal(thrower.Reify())); 35362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return; 354f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 35562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!IsInstantiationAllowed(i_isolate, &thrower, args[0], maybe_imports, 35662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch true)) { 35762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch resolver->Reject(context, Utils::ToLocal(thrower.Reify())); 358f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return; 359f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 36062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Handle<i::JSPromise> promise = Utils::OpenHandle(*resolver->GetPromise()); 36162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (HasBrand(first_arg, i::Handle<i::Symbol>(i_context->wasm_module_sym()))) { 36262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // WebAssembly.instantiate(module, imports) -> WebAssembly.Instance 36362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch auto module_object = GetFirstArgumentAsModule(args, &thrower); 36462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::wasm::AsyncInstantiate(i_isolate, promise, 36562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch module_object.ToHandleChecked(), maybe_imports); 36662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 36762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // WebAssembly.instantiate(bytes, imports) -> {module, instance} 36862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch auto bytes = GetFirstArgumentAsBytes(args, &thrower); 36962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (thrower.error()) { 37062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch resolver->Reject(context, Utils::ToLocal(thrower.Reify())); 37162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return; 37262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 37362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::wasm::AsyncCompileAndInstantiate(i_isolate, promise, bytes, 37462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch maybe_imports); 37562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 377f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 378f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool GetIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower, 379f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Local<Context> context, Local<v8::Object> object, 38062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Local<String> property, int* result, 38162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int64_t lower_bound, uint64_t upper_bound) { 382f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8::MaybeLocal<v8::Value> maybe = object->Get(context, property); 383f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8::Local<v8::Value> value; 384f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (maybe.ToLocal(&value)) { 385f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch int64_t number; 386f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!value->IntegerValue(context).To(&number)) return false; 38762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (number < lower_bound) { 388f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch thrower->RangeError("Property value %" PRId64 38962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch " is below the lower bound %" PRIx64, 390f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch number, lower_bound); 391f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return false; 392f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 393f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (number > static_cast<int64_t>(upper_bound)) { 394f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch thrower->RangeError("Property value %" PRId64 39562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch " is above the upper bound %" PRIu64, 396f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch number, upper_bound); 397f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return false; 398f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 399f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch *result = static_cast<int>(number); 400f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return true; 401f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 402f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return false; 403f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 404f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 40562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// new WebAssembly.Table(args) -> WebAssembly.Table 406f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) { 407f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8::Isolate* isolate = args.GetIsolate(); 40862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 409f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch HandleScope scope(isolate); 41062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ErrorThrower thrower(i_isolate, "WebAssembly.Module()"); 411f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (args.Length() < 1 || !args[0]->IsObject()) { 412f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch thrower.TypeError("Argument 0 must be a table descriptor"); 413f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return; 414f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 415f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Local<Context> context = isolate->GetCurrentContext(); 416f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Local<v8::Object> descriptor = args[0]->ToObject(context).ToLocalChecked(); 417f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // The descriptor's 'element'. 418f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch { 419f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8::MaybeLocal<v8::Value> maybe = 420f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch descriptor->Get(context, v8_str(isolate, "element")); 421f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8::Local<v8::Value> value; 422f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!maybe.ToLocal(&value)) return; 423f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8::Local<v8::String> string; 424f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!value->ToString(context).ToLocal(&string)) return; 425f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch bool equal; 426f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!string->Equals(context, v8_str(isolate, "anyfunc")).To(&equal)) return; 427f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!equal) { 428f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch thrower.TypeError("Descriptor property 'element' must be 'anyfunc'"); 429f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return; 430f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 431f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 432f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // The descriptor's 'initial'. 43362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int initial = 0; 434f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!GetIntegerProperty(isolate, &thrower, context, descriptor, 435f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8_str(isolate, "initial"), &initial, 0, 43662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::FLAG_wasm_max_table_size)) { 437f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return; 438f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 439f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // The descriptor's 'maximum'. 44062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int maximum = -1; 441f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Local<String> maximum_key = v8_str(isolate, "maximum"); 442f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Maybe<bool> has_maximum = descriptor->Has(context, maximum_key); 443f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 44462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!has_maximum.IsNothing() && has_maximum.FromJust()) { 445f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!GetIntegerProperty(isolate, &thrower, context, descriptor, maximum_key, 44662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch &maximum, initial, 44762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::wasm::kSpecMaxWasmTableSize)) { 448f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return; 449f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 450f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 451f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 452c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i::Handle<i::FixedArray> fixed_array; 453f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch i::Handle<i::JSObject> table_obj = 454c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i::WasmTableObject::New(i_isolate, initial, maximum, &fixed_array); 455f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 456f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return_value.Set(Utils::ToLocal(table_obj)); 457f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 458f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 459f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) { 460f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8::Isolate* isolate = args.GetIsolate(); 46162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 462f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch HandleScope scope(isolate); 46362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ErrorThrower thrower(i_isolate, "WebAssembly.Memory()"); 464f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (args.Length() < 1 || !args[0]->IsObject()) { 465c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch thrower.TypeError("Argument 0 must be a memory descriptor"); 466f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return; 467f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 468f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Local<Context> context = isolate->GetCurrentContext(); 469f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Local<v8::Object> descriptor = args[0]->ToObject(context).ToLocalChecked(); 470f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // The descriptor's 'initial'. 47162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int initial = 0; 472f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!GetIntegerProperty(isolate, &thrower, context, descriptor, 47362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8_str(isolate, "initial"), &initial, 0, 47462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::FLAG_wasm_max_mem_pages)) { 475f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return; 476f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 477f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // The descriptor's 'maximum'. 47862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int maximum = -1; 479f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Local<String> maximum_key = v8_str(isolate, "maximum"); 480f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Maybe<bool> has_maximum = descriptor->Has(context, maximum_key); 481f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 48262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!has_maximum.IsNothing() && has_maximum.FromJust()) { 483f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!GetIntegerProperty(isolate, &thrower, context, descriptor, maximum_key, 48462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch &maximum, initial, 48562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::wasm::kSpecMaxWasmMemoryPages)) { 486f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return; 487f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 488f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 489f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch size_t size = static_cast<size_t>(i::wasm::WasmModule::kPageSize) * 490f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch static_cast<size_t>(initial); 49162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Handle<i::JSArrayBuffer> buffer = 49262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::wasm::NewArrayBuffer(i_isolate, size, i::FLAG_wasm_guard_pages); 49362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (buffer.is_null()) { 49462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch thrower.RangeError("could not allocate memory"); 49562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return; 49662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 49762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Handle<i::JSObject> memory_obj = 49862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::WasmMemoryObject::New(i_isolate, buffer, maximum); 499c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch args.GetReturnValue().Set(Utils::ToLocal(memory_obj)); 500f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 501c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 502f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid WebAssemblyTableGetLength( 503f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch const v8::FunctionCallbackInfo<v8::Value>& args) { 504c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch v8::Isolate* isolate = args.GetIsolate(); 50562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 50662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HandleScope scope(isolate); 50762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ErrorThrower thrower(i_isolate, "WebAssembly.Table.length()"); 508c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Local<Context> context = isolate->GetCurrentContext(); 509c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i::Handle<i::Context> i_context = Utils::OpenHandle(*context); 51062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!BrandCheck(Utils::OpenHandle(*args.This()), 51162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Handle<i::Symbol>(i_context->wasm_table_sym()), &thrower, 512c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch "Receiver is not a WebAssembly.Table")) { 513c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return; 514c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 515c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch auto receiver = 516c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i::Handle<i::WasmTableObject>::cast(Utils::OpenHandle(*args.This())); 517c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch args.GetReturnValue().Set( 518c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch v8::Number::New(isolate, receiver->current_length())); 519f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 520c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 52162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// WebAssembly.Table.grow(num) -> num 522f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid WebAssemblyTableGrow(const v8::FunctionCallbackInfo<v8::Value>& args) { 523c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch v8::Isolate* isolate = args.GetIsolate(); 52462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 52562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HandleScope scope(isolate); 52662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ErrorThrower thrower(i_isolate, "WebAssembly.Table.grow()"); 527c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Local<Context> context = isolate->GetCurrentContext(); 528c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i::Handle<i::Context> i_context = Utils::OpenHandle(*context); 52962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!BrandCheck(Utils::OpenHandle(*args.This()), 53062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Handle<i::Symbol>(i_context->wasm_table_sym()), &thrower, 531c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch "Receiver is not a WebAssembly.Table")) { 532c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return; 533c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 534c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 535c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch auto receiver = 536c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i::Handle<i::WasmTableObject>::cast(Utils::OpenHandle(*args.This())); 53762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Handle<i::FixedArray> old_array(receiver->functions(), i_isolate); 538c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int old_size = old_array->length(); 539c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int64_t new_size64 = 0; 540c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (args.Length() > 0 && !args[0]->IntegerValue(context).To(&new_size64)) { 541c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return; 542c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 543c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch new_size64 += old_size; 544c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 54562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int64_t max_size64 = receiver->maximum_length(); 54662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (max_size64 < 0 || 54762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch max_size64 > static_cast<int64_t>(i::FLAG_wasm_max_table_size)) { 54862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch max_size64 = i::FLAG_wasm_max_table_size; 54962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 55062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 55162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (new_size64 < old_size || new_size64 > max_size64) { 55262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch thrower.RangeError(new_size64 < old_size ? "trying to shrink table" 55362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch : "maximum table size exceeded"); 554c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return; 555c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 55662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 557c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int new_size = static_cast<int>(new_size64); 55862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::WasmTableObject::Grow(i_isolate, receiver, 55962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch static_cast<uint32_t>(new_size - old_size)); 560c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 561c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (new_size != old_size) { 562c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i::Handle<i::FixedArray> new_array = 563c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i_isolate->factory()->NewFixedArray(new_size); 564c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch for (int i = 0; i < old_size; ++i) new_array->set(i, old_array->get(i)); 565c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i::Object* null = i_isolate->heap()->null_value(); 566c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch for (int i = old_size; i < new_size; ++i) new_array->set(i, null); 567c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch receiver->set_functions(*new_array); 568c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 569c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 57062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // TODO(gdeepti): use weak links for instances 57162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 57262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return_value.Set(old_size); 573f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 574c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 57562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// WebAssembly.Table.get(num) -> JSFunction 576f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid WebAssemblyTableGet(const v8::FunctionCallbackInfo<v8::Value>& args) { 577c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch v8::Isolate* isolate = args.GetIsolate(); 57862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 57962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HandleScope scope(isolate); 58062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ErrorThrower thrower(i_isolate, "WebAssembly.Table.get()"); 581c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Local<Context> context = isolate->GetCurrentContext(); 582c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i::Handle<i::Context> i_context = Utils::OpenHandle(*context); 58362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!BrandCheck(Utils::OpenHandle(*args.This()), 58462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Handle<i::Symbol>(i_context->wasm_table_sym()), &thrower, 585c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch "Receiver is not a WebAssembly.Table")) { 586c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return; 587c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 588c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 589c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch auto receiver = 590c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i::Handle<i::WasmTableObject>::cast(Utils::OpenHandle(*args.This())); 59162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Handle<i::FixedArray> array(receiver->functions(), i_isolate); 592c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int i = 0; 593c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (args.Length() > 0 && !args[0]->Int32Value(context).To(&i)) return; 594c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 595c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (i < 0 || i >= array->length()) { 59662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch thrower.RangeError("index out of bounds"); 597c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return; 598c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 599c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 600c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i::Handle<i::Object> value(array->get(i), i_isolate); 601c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return_value.Set(Utils::ToLocal(value)); 602f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 603c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 60462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// WebAssembly.Table.set(num, JSFunction) 605f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid WebAssemblyTableSet(const v8::FunctionCallbackInfo<v8::Value>& args) { 606c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch v8::Isolate* isolate = args.GetIsolate(); 607c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 60862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HandleScope scope(isolate); 60962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ErrorThrower thrower(i_isolate, "WebAssembly.Table.set()"); 610c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Local<Context> context = isolate->GetCurrentContext(); 611c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i::Handle<i::Context> i_context = Utils::OpenHandle(*context); 61262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!BrandCheck(Utils::OpenHandle(*args.This()), 61362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Handle<i::Symbol>(i_context->wasm_table_sym()), &thrower, 614c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch "Receiver is not a WebAssembly.Table")) { 615c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return; 616c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 617c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (args.Length() < 2) { 61862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch thrower.TypeError("Argument 1 must be null or a function"); 619c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return; 620c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 621c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i::Handle<i::Object> value = Utils::OpenHandle(*args[1]); 622c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!value->IsNull(i_isolate) && 623c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch (!value->IsJSFunction() || 624c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i::Handle<i::JSFunction>::cast(value)->code()->kind() != 625c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i::Code::JS_TO_WASM_FUNCTION)) { 62662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch thrower.TypeError("Argument 1 must be null or a WebAssembly function"); 627c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return; 628c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 629c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 630c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch auto receiver = 631c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i::Handle<i::WasmTableObject>::cast(Utils::OpenHandle(*args.This())); 63262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Handle<i::FixedArray> array(receiver->functions(), i_isolate); 633c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int i; 634c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!args[0]->Int32Value(context).To(&i)) return; 635c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (i < 0 || i >= array->length()) { 63662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch thrower.RangeError("index out of bounds"); 637c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return; 638c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 639c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 64062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Handle<i::FixedArray> dispatch_tables(receiver->dispatch_tables(), 641c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i_isolate); 642c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (value->IsNull(i_isolate)) { 643c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i::wasm::UpdateDispatchTables(i_isolate, dispatch_tables, i, 644c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i::Handle<i::JSFunction>::null()); 645c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else { 646c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i::wasm::UpdateDispatchTables(i_isolate, dispatch_tables, i, 647c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i::Handle<i::JSFunction>::cast(value)); 648c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 649c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 650c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i::Handle<i::FixedArray>::cast(array)->set(i, *value); 651f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 652c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 65362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// WebAssembly.Memory.grow(num) -> num 654f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) { 655c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch v8::Isolate* isolate = args.GetIsolate(); 65662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 65762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HandleScope scope(isolate); 65862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ErrorThrower thrower(i_isolate, "WebAssembly.Memory.grow()"); 659c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Local<Context> context = isolate->GetCurrentContext(); 660c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i::Handle<i::Context> i_context = Utils::OpenHandle(*context); 66162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!BrandCheck(Utils::OpenHandle(*args.This()), 66262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Handle<i::Symbol>(i_context->wasm_memory_sym()), &thrower, 663c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch "Receiver is not a WebAssembly.Memory")) { 664c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return; 665c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 66662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int64_t delta_size = 0; 66762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (args.Length() < 1 || !args[0]->IntegerValue(context).To(&delta_size)) { 66862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch thrower.TypeError("Argument 0 required, must be numeric value of pages"); 669c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return; 670c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 67162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Handle<i::WasmMemoryObject> receiver = 67262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Handle<i::WasmMemoryObject>::cast(Utils::OpenHandle(*args.This())); 67362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int64_t max_size64 = receiver->maximum_pages(); 67462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (max_size64 < 0 || 67562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch max_size64 > static_cast<int64_t>(i::FLAG_wasm_max_mem_pages)) { 67662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch max_size64 = i::FLAG_wasm_max_mem_pages; 67762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 67862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Handle<i::JSArrayBuffer> old_buffer(receiver->buffer()); 67962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch uint32_t old_size = 68062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch old_buffer->byte_length()->Number() / i::wasm::kSpecMaxWasmMemoryPages; 68162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int64_t new_size64 = old_size + delta_size; 68262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (delta_size < 0 || max_size64 < new_size64 || new_size64 < old_size) { 68362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch thrower.RangeError(new_size64 < old_size ? "trying to shrink memory" 68462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch : "maximum memory size exceeded"); 685c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return; 686c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 68762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int32_t ret = i::wasm::GrowWebAssemblyMemory( 68862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i_isolate, receiver, static_cast<uint32_t>(delta_size)); 68962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (ret == -1) { 69062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch thrower.RangeError("Unable to grow instance memory."); 691c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return; 692c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 693c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 694c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return_value.Set(ret); 695f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 696c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 69762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// WebAssembly.Memory.buffer -> ArrayBuffer 698f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid WebAssemblyMemoryGetBuffer( 699f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch const v8::FunctionCallbackInfo<v8::Value>& args) { 700f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8::Isolate* isolate = args.GetIsolate(); 70162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 70262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HandleScope scope(isolate); 70362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ErrorThrower thrower(i_isolate, "WebAssembly.Memory.buffer"); 704f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Local<Context> context = isolate->GetCurrentContext(); 705f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch i::Handle<i::Context> i_context = Utils::OpenHandle(*context); 70662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!BrandCheck(Utils::OpenHandle(*args.This()), 70762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Handle<i::Symbol>(i_context->wasm_memory_sym()), &thrower, 708f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch "Receiver is not a WebAssembly.Memory")) { 709f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return; 710f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 71162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Handle<i::WasmMemoryObject> receiver = 71262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Handle<i::WasmMemoryObject>::cast(Utils::OpenHandle(*args.This())); 71362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Handle<i::Object> buffer(receiver->buffer(), i_isolate); 714f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(buffer->IsJSArrayBuffer()); 715f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 716f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return_value.Set(Utils::ToLocal(buffer)); 717f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace 719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// TODO(titzer): we use the API to create the function template because the 721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// internal guts are too ugly to replicate here. 722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic i::Handle<i::FunctionTemplateInfo> NewTemplate(i::Isolate* i_isolate, 723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FunctionCallback func) { 724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate); 72562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Local<FunctionTemplate> templ = FunctionTemplate::New(isolate, func); 72662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch templ->ReadOnlyPrototype(); 72762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return v8::Utils::OpenHandle(*templ); 728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace internal { 731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 732f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochHandle<JSFunction> InstallFunc(Isolate* isolate, Handle<JSObject> object, 73362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const char* str, FunctionCallback func, 73462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int length = 0) { 735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<String> name = v8_str(isolate, str); 736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FunctionTemplateInfo> temp = NewTemplate(isolate, func); 737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSFunction> function = 738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ApiNatives::InstantiateFunction(temp).ToHandleChecked(); 73962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch JSFunction::SetName(function, name, isolate->factory()->empty_string()); 74062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch function->shared()->set_length(length); 74162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch PropertyAttributes attributes = static_cast<PropertyAttributes>(DONT_ENUM); 742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSObject::AddProperty(object, name, function, attributes); 74313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return function; 744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 746f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochHandle<JSFunction> InstallGetter(Isolate* isolate, Handle<JSObject> object, 747f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch const char* str, FunctionCallback func) { 748f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<String> name = v8_str(isolate, str); 749f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<FunctionTemplateInfo> temp = NewTemplate(isolate, func); 750f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<JSFunction> function = 751f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ApiNatives::InstantiateFunction(temp).ToHandleChecked(); 752f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8::PropertyAttribute attributes = 75362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch static_cast<v8::PropertyAttribute>(v8::DontEnum); 754f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Utils::ToLocal(object)->SetAccessorProperty(Utils::ToLocal(name), 755f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Utils::ToLocal(function), 756f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Local<Function>(), attributes); 757f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return function; 758f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 759f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 76062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid WasmJs::Install(Isolate* isolate) { 76162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<JSGlobalObject> global = isolate->global_object(); 76262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Context> context(global->native_context(), isolate); 76362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // TODO(titzer): once FLAG_expose_wasm is gone, this should become a DCHECK. 76462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (context->get(Context::WASM_FUNCTION_MAP_INDEX)->IsMap()) return; 76562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 76662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Install Maps. 76762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 76862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // TODO(titzer): Also make one for strict mode functions? 76962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Map> prev_map = Handle<Map>(context->sloppy_function_map(), isolate); 77062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 77162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch InstanceType instance_type = prev_map->instance_type(); 77262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int internal_fields = JSObject::GetInternalFieldCount(*prev_map); 77362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CHECK_EQ(0, internal_fields); 77462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int pre_allocated = 77562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch prev_map->GetInObjectProperties() - prev_map->unused_property_fields(); 77662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int instance_size = 0; 77762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int in_object_properties = 0; 77862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int wasm_internal_fields = internal_fields + 1 // module instance object 77962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch + 1 // function arity 78062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch + 1; // function signature 78162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch JSFunction::CalculateInstanceSizeHelper(instance_type, wasm_internal_fields, 78262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 0, &instance_size, 78362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch &in_object_properties); 78462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 78562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int unused_property_fields = in_object_properties - pre_allocated; 78662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Map> map = Map::CopyInitialMap( 78762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch prev_map, instance_size, in_object_properties, unused_property_fields); 78862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 78962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch context->set_wasm_function_map(*map); 79062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 79162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Install symbols. 792f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 793f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Factory* factory = isolate->factory(); 794f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Create private symbols. 795f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<Symbol> module_sym = factory->NewPrivateSymbol(); 796f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch context->set_wasm_module_sym(*module_sym); 797f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 798f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<Symbol> instance_sym = factory->NewPrivateSymbol(); 799f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch context->set_wasm_instance_sym(*instance_sym); 800f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 801f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<Symbol> table_sym = factory->NewPrivateSymbol(); 802f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch context->set_wasm_table_sym(*table_sym); 803f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 804f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<Symbol> memory_sym = factory->NewPrivateSymbol(); 805f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch context->set_wasm_memory_sym(*memory_sym); 806f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 80762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Install the JS API. 80862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 80962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Setup WebAssembly 810f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<String> name = v8_str(isolate, "WebAssembly"); 811f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<JSFunction> cons = factory->NewFunction(name); 812f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch JSFunction::SetInstancePrototype( 813f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch cons, Handle<Object>(context->initial_object_prototype(), isolate)); 814f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch cons->shared()->set_instance_class_name(*name); 815c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<JSObject> webassembly = factory->NewJSObject(cons, TENURED); 816f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch PropertyAttributes attributes = static_cast<PropertyAttributes>(DONT_ENUM); 817c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch JSObject::AddProperty(global, name, webassembly, attributes); 81862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch PropertyAttributes ro_attributes = 81962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY); 82062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch JSObject::AddProperty(webassembly, factory->to_string_tag_symbol(), 82162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8_str(isolate, "WebAssembly"), ro_attributes); 82262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch InstallFunc(isolate, webassembly, "compile", WebAssemblyCompile, 1); 82362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch InstallFunc(isolate, webassembly, "validate", WebAssemblyValidate, 1); 82462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch InstallFunc(isolate, webassembly, "instantiate", WebAssemblyInstantiate, 1); 825f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 826f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Setup Module 827f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<JSFunction> module_constructor = 82862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch InstallFunc(isolate, webassembly, "Module", WebAssemblyModule, 1); 829f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch context->set_wasm_module_constructor(*module_constructor); 830f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<JSObject> module_proto = 831f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch factory->NewJSObject(module_constructor, TENURED); 83262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Handle<i::Map> module_map = isolate->factory()->NewMap( 83362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::JS_API_OBJECT_TYPE, i::JSObject::kHeaderSize + 834c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch WasmModuleObject::kFieldCount * i::kPointerSize); 83562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch JSFunction::SetInitialMap(module_constructor, module_map, module_proto); 83662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch InstallFunc(isolate, module_constructor, "imports", WebAssemblyModuleImports, 83762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 1); 83862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch InstallFunc(isolate, module_constructor, "exports", WebAssemblyModuleExports, 83962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 1); 84062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch InstallFunc(isolate, module_constructor, "customSections", 84162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch WebAssemblyModuleCustomSections, 2); 842f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch JSObject::AddProperty(module_proto, isolate->factory()->constructor_string(), 843f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch module_constructor, DONT_ENUM); 84462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch JSObject::AddProperty(module_proto, factory->to_string_tag_symbol(), 84562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8_str(isolate, "WebAssembly.Module"), ro_attributes); 846f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 847f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Setup Instance 848f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<JSFunction> instance_constructor = 84962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch InstallFunc(isolate, webassembly, "Instance", WebAssemblyInstance, 1); 850f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch context->set_wasm_instance_constructor(*instance_constructor); 85162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<JSObject> instance_proto = 85262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch factory->NewJSObject(instance_constructor, TENURED); 85362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Handle<i::Map> instance_map = isolate->factory()->NewMap( 85462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::JS_API_OBJECT_TYPE, i::JSObject::kHeaderSize + 85562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch WasmInstanceObject::kFieldCount * i::kPointerSize); 85662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch JSFunction::SetInitialMap(instance_constructor, instance_map, instance_proto); 85762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch JSObject::AddProperty(instance_proto, 85862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isolate->factory()->constructor_string(), 85962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch instance_constructor, DONT_ENUM); 86062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch JSObject::AddProperty(instance_proto, factory->to_string_tag_symbol(), 86162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8_str(isolate, "WebAssembly.Instance"), ro_attributes); 862f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 863f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Setup Table 864f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<JSFunction> table_constructor = 86562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch InstallFunc(isolate, webassembly, "Table", WebAssemblyTable, 1); 866f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch context->set_wasm_table_constructor(*table_constructor); 867f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<JSObject> table_proto = 868f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch factory->NewJSObject(table_constructor, TENURED); 86962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Handle<i::Map> table_map = isolate->factory()->NewMap( 87062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::JS_API_OBJECT_TYPE, i::JSObject::kHeaderSize + 871c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch WasmTableObject::kFieldCount * i::kPointerSize); 87262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch JSFunction::SetInitialMap(table_constructor, table_map, table_proto); 873f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch JSObject::AddProperty(table_proto, isolate->factory()->constructor_string(), 874f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch table_constructor, DONT_ENUM); 875f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch InstallGetter(isolate, table_proto, "length", WebAssemblyTableGetLength); 87662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch InstallFunc(isolate, table_proto, "grow", WebAssemblyTableGrow, 1); 87762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch InstallFunc(isolate, table_proto, "get", WebAssemblyTableGet, 1); 87862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch InstallFunc(isolate, table_proto, "set", WebAssemblyTableSet, 2); 87962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch JSObject::AddProperty(table_proto, factory->to_string_tag_symbol(), 88062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8_str(isolate, "WebAssembly.Table"), ro_attributes); 881f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 882f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Setup Memory 883f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<JSFunction> memory_constructor = 88462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch InstallFunc(isolate, webassembly, "Memory", WebAssemblyMemory, 1); 885f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch context->set_wasm_memory_constructor(*memory_constructor); 886f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<JSObject> memory_proto = 887f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch factory->NewJSObject(memory_constructor, TENURED); 88862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::Handle<i::Map> memory_map = isolate->factory()->NewMap( 88962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i::JS_API_OBJECT_TYPE, i::JSObject::kHeaderSize + 890c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch WasmMemoryObject::kFieldCount * i::kPointerSize); 89162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch JSFunction::SetInitialMap(memory_constructor, memory_map, memory_proto); 892f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch JSObject::AddProperty(memory_proto, isolate->factory()->constructor_string(), 893f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch memory_constructor, DONT_ENUM); 89462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch InstallFunc(isolate, memory_proto, "grow", WebAssemblyMemoryGrow, 1); 895f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch InstallGetter(isolate, memory_proto, "buffer", WebAssemblyMemoryGetBuffer); 89662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch JSObject::AddProperty(memory_proto, factory->to_string_tag_symbol(), 89762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8_str(isolate, "WebAssembly.Memory"), ro_attributes); 898c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 899c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Setup errors 90062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch attributes = static_cast<PropertyAttributes>(DONT_ENUM); 901c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<JSFunction> compile_error( 902c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch isolate->native_context()->wasm_compile_error_function()); 903c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch JSObject::AddProperty(webassembly, isolate->factory()->CompileError_string(), 904c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch compile_error, attributes); 90562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<JSFunction> link_error( 90662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isolate->native_context()->wasm_link_error_function()); 90762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch JSObject::AddProperty(webassembly, isolate->factory()->LinkError_string(), 90862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch link_error, attributes); 909c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<JSFunction> runtime_error( 910c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch isolate->native_context()->wasm_runtime_error_function()); 911c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch JSObject::AddProperty(webassembly, isolate->factory()->RuntimeError_string(), 912c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch runtime_error, attributes); 913f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 914f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 915c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochbool WasmJs::IsWasmMemoryObject(Isolate* isolate, Handle<Object> value) { 916c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i::Handle<i::Symbol> symbol(isolate->context()->wasm_memory_sym(), isolate); 917c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return HasBrand(value, symbol); 918c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch} 919c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 920c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochbool WasmJs::IsWasmTableObject(Isolate* isolate, Handle<Object> value) { 921c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i::Handle<i::Symbol> symbol(isolate->context()->wasm_table_sym(), isolate); 922c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return HasBrand(value, symbol); 923c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch} 924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 926