LCOV - code coverage report
Current view: top level - src/wasm - wasm-js.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 415 421 98.6 %
Date: 2017-04-26 Functions: 31 31 100.0 %

          Line data    Source code
       1             : // Copyright 2015 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/api-natives.h"
       6             : #include "src/api.h"
       7             : #include "src/asmjs/asm-js.h"
       8             : #include "src/asmjs/asm-typer.h"
       9             : #include "src/asmjs/asm-wasm-builder.h"
      10             : #include "src/assert-scope.h"
      11             : #include "src/ast/ast.h"
      12             : #include "src/execution.h"
      13             : #include "src/factory.h"
      14             : #include "src/handles.h"
      15             : #include "src/isolate.h"
      16             : #include "src/objects-inl.h"
      17             : #include "src/objects.h"
      18             : #include "src/parsing/parse-info.h"
      19             : 
      20             : #include "src/wasm/module-decoder.h"
      21             : #include "src/wasm/wasm-js.h"
      22             : #include "src/wasm/wasm-limits.h"
      23             : #include "src/wasm/wasm-module.h"
      24             : #include "src/wasm/wasm-objects.h"
      25             : #include "src/wasm/wasm-result.h"
      26             : 
      27             : typedef uint8_t byte;
      28             : 
      29             : using v8::internal::wasm::ErrorThrower;
      30             : 
      31             : namespace v8 {
      32             : 
      33             : namespace {
      34             : 
      35             : #define ASSIGN(type, var, expr)                      \
      36             :   Local<type> var;                                   \
      37             :   do {                                               \
      38             :     if (!expr.ToLocal(&var)) {                       \
      39             :       DCHECK(i_isolate->has_scheduled_exception());  \
      40             :       return;                                        \
      41             :     } else {                                         \
      42             :       DCHECK(!i_isolate->has_scheduled_exception()); \
      43             :     }                                                \
      44             :   } while (false)
      45             : 
      46             : // TODO(wasm): move brand check to the respective types, and don't throw
      47             : // in it, rather, use a provided ErrorThrower, or let caller handle it.
      48       68041 : static bool HasBrand(i::Handle<i::Object> value, i::Handle<i::Symbol> sym) {
      49       68041 :   if (!value->IsJSObject()) return false;
      50             :   i::Handle<i::JSObject> object = i::Handle<i::JSObject>::cast(value);
      51       67816 :   Maybe<bool> has_brand = i::JSObject::HasOwnProperty(object, sym);
      52             :   return has_brand.FromMaybe(false);
      53             : }
      54             : 
      55       65401 : static bool BrandCheck(i::Handle<i::Object> value, i::Handle<i::Symbol> sym,
      56             :                        ErrorThrower* thrower, const char* msg) {
      57       65401 :   return HasBrand(value, sym) ? true : (thrower->TypeError("%s", msg), false);
      58             : }
      59             : 
      60             : i::Handle<i::String> v8_str(i::Isolate* isolate, const char* str) {
      61     2324645 :   return isolate->factory()->NewStringFromAsciiChecked(str);
      62             : }
      63             : Local<String> v8_str(Isolate* isolate, const char* str) {
      64             :   return Utils::ToLocal(v8_str(reinterpret_cast<i::Isolate*>(isolate), str));
      65             : }
      66             : 
      67       40777 : i::MaybeHandle<i::WasmModuleObject> GetFirstArgumentAsModule(
      68       81554 :     const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) {
      69             :   v8::Isolate* isolate = args.GetIsolate();
      70       40777 :   if (args.Length() < 1) {
      71         120 :     thrower->TypeError("Argument 0 must be a WebAssembly.Module");
      72             :     return {};
      73             :   }
      74             : 
      75       40657 :   Local<Context> context = isolate->GetCurrentContext();
      76             :   i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
      77       40657 :   if (!BrandCheck(Utils::OpenHandle(*args[0]),
      78             :                   i::handle(i_context->wasm_module_sym()), thrower,
      79       40657 :                   "Argument 0 must be a WebAssembly.Module")) {
      80             :     return {};
      81             :   }
      82             : 
      83             :   Local<Object> module_obj = Local<Object>::Cast(args[0]);
      84             :   return i::Handle<i::WasmModuleObject>::cast(
      85             :       v8::Utils::OpenHandle(*module_obj));
      86             : }
      87             : 
      88       13661 : i::wasm::ModuleWireBytes GetFirstArgumentAsBytes(
      89       13661 :     const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) {
      90       13661 :   if (args.Length() < 1) {
      91         135 :     thrower->TypeError("Argument 0 must be a buffer source");
      92         135 :     return i::wasm::ModuleWireBytes(nullptr, nullptr);
      93             :   }
      94             : 
      95             :   const byte* start = nullptr;
      96             :   size_t length = 0;
      97             :   v8::Local<v8::Value> source = args[0];
      98       13526 :   if (source->IsArrayBuffer()) {
      99             :     // A raw array buffer was passed.
     100             :     Local<ArrayBuffer> buffer = Local<ArrayBuffer>::Cast(source);
     101       12116 :     ArrayBuffer::Contents contents = buffer->GetContents();
     102             : 
     103       12116 :     start = reinterpret_cast<const byte*>(contents.Data());
     104       12116 :     length = contents.ByteLength();
     105        1410 :   } else if (source->IsTypedArray()) {
     106             :     // A TypedArray was passed.
     107             :     Local<TypedArray> array = Local<TypedArray>::Cast(source);
     108        1050 :     Local<ArrayBuffer> buffer = array->Buffer();
     109             : 
     110        1050 :     ArrayBuffer::Contents contents = buffer->GetContents();
     111             : 
     112             :     start =
     113        1050 :         reinterpret_cast<const byte*>(contents.Data()) + array->ByteOffset();
     114        1050 :     length = array->ByteLength();
     115             :   } else {
     116         360 :     thrower->TypeError("Argument 0 must be a buffer source");
     117             :   }
     118             :   DCHECK_IMPLIES(length, start != nullptr);
     119       13526 :   if (length == 0) {
     120         765 :     thrower->CompileError("BufferSource argument is empty");
     121             :   }
     122       13526 :   if (length > i::wasm::kV8MaxWasmModuleSize) {
     123             :     thrower->RangeError("buffer source exceeds maximum size of %zu (is %zu)",
     124          15 :                         i::wasm::kV8MaxWasmModuleSize, length);
     125             :   }
     126       13526 :   if (thrower->error()) return i::wasm::ModuleWireBytes(nullptr, nullptr);
     127             :   // TODO(titzer): use the handle as well?
     128       25492 :   return i::wasm::ModuleWireBytes(start, start + length);
     129             : }
     130             : 
     131       40777 : i::MaybeHandle<i::JSReceiver> GetValueAsImports(Local<Value> arg,
     132             :                                                 ErrorThrower* thrower) {
     133       40777 :   if (arg->IsUndefined()) return {};
     134             : 
     135       37037 :   if (!arg->IsObject()) {
     136         225 :     thrower->TypeError("Argument 1 must be an object");
     137             :     return {};
     138             :   }
     139             :   Local<Object> obj = Local<Object>::Cast(arg);
     140             :   return i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj));
     141             : }
     142             : 
     143             : // WebAssembly.compile(bytes) -> Promise
     144        2460 : void WebAssemblyCompile(const v8::FunctionCallbackInfo<v8::Value>& args) {
     145             :   v8::Isolate* isolate = args.GetIsolate();
     146        1245 :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
     147        1245 :   MicrotasksScope runs_microtasks(isolate, MicrotasksScope::kRunMicrotasks);
     148        1725 :   if (i_isolate->wasm_compile_callback()(args)) return;
     149             : 
     150        1980 :   HandleScope scope(isolate);
     151         765 :   ErrorThrower thrower(i_isolate, "WebAssembly.compile()");
     152             : 
     153        1215 :   Local<Context> context = isolate->GetCurrentContext();
     154        2880 :   ASSIGN(Promise::Resolver, resolver, Promise::Resolver::New(context));
     155             :   v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
     156        1215 :   return_value.Set(resolver->GetPromise());
     157             : 
     158        1215 :   auto bytes = GetFirstArgumentAsBytes(args, &thrower);
     159        1215 :   if (thrower.error()) {
     160         450 :     auto maybe = resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
     161         450 :     CHECK_IMPLIES(!maybe.FromMaybe(false),
     162             :                   i_isolate->has_scheduled_exception());
     163             :     return;
     164             :   }
     165        1530 :   i::Handle<i::JSPromise> promise = Utils::OpenHandle(*resolver->GetPromise());
     166        1530 :   i::wasm::AsyncCompile(i_isolate, promise, bytes);
     167             : }
     168             : 
     169             : // WebAssembly.validate(bytes) -> bool
     170        2400 : void WebAssemblyValidate(const v8::FunctionCallbackInfo<v8::Value>& args) {
     171             :   v8::Isolate* isolate = args.GetIsolate();
     172             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
     173        1200 :   HandleScope scope(isolate);
     174        1200 :   ErrorThrower thrower(i_isolate, "WebAssembly.validate()");
     175             : 
     176        1200 :   auto bytes = GetFirstArgumentAsBytes(args, &thrower);
     177             : 
     178             :   v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
     179        2310 :   if (!thrower.error() &&
     180             :       i::wasm::SyncValidate(reinterpret_cast<i::Isolate*>(isolate), &thrower,
     181        1110 :                             bytes)) {
     182             :     return_value.Set(v8::True(isolate));
     183             :   } else {
     184         615 :     if (thrower.wasm_error()) thrower.Reify();  // Clear error.
     185             :     return_value.Set(v8::False(isolate));
     186        1200 :   }
     187        1200 : }
     188             : 
     189             : // new WebAssembly.Module(bytes) -> WebAssembly.Module
     190       21592 : void WebAssemblyModule(const v8::FunctionCallbackInfo<v8::Value>& args) {
     191             :   v8::Isolate* isolate = args.GetIsolate();
     192       11276 :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
     193       12236 :   if (i_isolate->wasm_module_callback()(args)) return;
     194             : 
     195       11246 :   HandleScope scope(isolate);
     196       10316 :   ErrorThrower thrower(i_isolate, "WebAssembly.Module()");
     197             : 
     198       11246 :   auto bytes = GetFirstArgumentAsBytes(args, &thrower);
     199             : 
     200       11246 :   if (thrower.error()) {
     201         930 :     return;
     202             :   }
     203             :   i::MaybeHandle<i::Object> module_obj =
     204       21742 :       i::wasm::SyncCompile(i_isolate, &thrower, bytes);
     205       10871 :   if (module_obj.is_null()) return;
     206             : 
     207             :   v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
     208       10316 :   return_value.Set(Utils::ToLocal(module_obj.ToHandleChecked()));
     209             : }
     210             : 
     211             : // WebAssembly.Module.imports(module) -> Array<Import>
     212         360 : void WebAssemblyModuleImports(const v8::FunctionCallbackInfo<v8::Value>& args) {
     213         150 :   HandleScope scope(args.GetIsolate());
     214             :   v8::Isolate* isolate = args.GetIsolate();
     215             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
     216          60 :   ErrorThrower thrower(i_isolate, "WebAssembly.Module.imports()");
     217             : 
     218         150 :   auto maybe_module = GetFirstArgumentAsModule(args, &thrower);
     219         300 :   if (thrower.error()) return;
     220          60 :   auto imports = i::wasm::GetImports(i_isolate, maybe_module.ToHandleChecked());
     221          60 :   args.GetReturnValue().Set(Utils::ToLocal(imports));
     222             : }
     223             : 
     224             : // WebAssembly.Module.exports(module) -> Array<Export>
     225         360 : void WebAssemblyModuleExports(const v8::FunctionCallbackInfo<v8::Value>& args) {
     226         150 :   HandleScope scope(args.GetIsolate());
     227             :   v8::Isolate* isolate = args.GetIsolate();
     228             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
     229          60 :   ErrorThrower thrower(i_isolate, "WebAssembly.Module.exports()");
     230             : 
     231         150 :   auto maybe_module = GetFirstArgumentAsModule(args, &thrower);
     232         300 :   if (thrower.error()) return;
     233          60 :   auto exports = i::wasm::GetExports(i_isolate, maybe_module.ToHandleChecked());
     234          60 :   args.GetReturnValue().Set(Utils::ToLocal(exports));
     235             : }
     236             : 
     237             : // WebAssembly.Module.customSections(module, name) -> Array<Section>
     238         210 : void WebAssemblyModuleCustomSections(
     239         585 :     const v8::FunctionCallbackInfo<v8::Value>& args) {
     240         210 :   HandleScope scope(args.GetIsolate());
     241             :   v8::Isolate* isolate = args.GetIsolate();
     242             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
     243          60 :   ErrorThrower thrower(i_isolate, "WebAssembly.Module.customSections()");
     244             : 
     245         210 :   auto maybe_module = GetFirstArgumentAsModule(args, &thrower);
     246         210 :   if (thrower.error()) return;
     247             : 
     248         105 :   if (args.Length() < 2) {
     249          30 :     thrower.TypeError("Argument 1 must be a string");
     250          30 :     return;
     251             :   }
     252             : 
     253             :   i::Handle<i::Object> name = Utils::OpenHandle(*args[1]);
     254          75 :   if (!name->IsString()) {
     255          15 :     thrower.TypeError("Argument 1 must be a string");
     256          15 :     return;
     257             :   }
     258             : 
     259             :   auto custom_sections =
     260             :       i::wasm::GetCustomSections(i_isolate, maybe_module.ToHandleChecked(),
     261          60 :                                  i::Handle<i::String>::cast(name), &thrower);
     262          60 :   if (thrower.error()) return;
     263          60 :   args.GetReturnValue().Set(Utils::ToLocal(custom_sections));
     264             : }
     265             : 
     266       40777 : MaybeLocal<Value> WebAssemblyInstantiateImpl(Isolate* isolate,
     267             :                                              Local<Value> module,
     268             :                                              Local<Value> ffi) {
     269             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
     270             : 
     271             :   ErrorThrower thrower(i_isolate, "WebAssembly Instantiation");
     272             :   i::MaybeHandle<i::JSReceiver> maybe_imports =
     273       40777 :       GetValueAsImports(ffi, &thrower);
     274       40777 :   if (thrower.error()) return {};
     275             : 
     276             :   i::Handle<i::WasmModuleObject> module_obj =
     277             :       i::Handle<i::WasmModuleObject>::cast(
     278       40552 :           Utils::OpenHandle(Object::Cast(*module)));
     279             :   i::MaybeHandle<i::Object> instance_object =
     280             :       i::wasm::SyncInstantiate(i_isolate, &thrower, module_obj, maybe_imports,
     281       81104 :                                i::MaybeHandle<i::JSArrayBuffer>());
     282             : 
     283       40552 :   if (instance_object.is_null()) {
     284             :     // TODO(wasm): this *should* mean there's an error to throw, but
     285             :     // we exit sometimes the instantiation pipeline without throwing.
     286             :     // v8:6232.
     287         825 :     return {};
     288             :   }
     289       39727 :   return Utils::ToLocal(instance_object.ToHandleChecked());
     290             : }
     291             : 
     292             : // Entered as internal implementation detail of sync and async instantiate.
     293             : // args[0] *must* be a WebAssembly.Module.
     294         165 : void WebAssemblyInstantiateImplCallback(
     295         570 :     const v8::FunctionCallbackInfo<v8::Value>& args) {
     296             :   DCHECK_GE(args.Length(), 1);
     297             :   v8::Isolate* isolate = args.GetIsolate();
     298             :   MicrotasksScope does_not_run_microtasks(isolate,
     299         165 :                                           MicrotasksScope::kDoNotRunMicrotasks);
     300             : 
     301         330 :   HandleScope scope(args.GetIsolate());
     302         165 :   Local<Value> module = args[0];
     303         165 :   Local<Value> ffi = args.Data();
     304             :   Local<Value> instance;
     305         330 :   if (WebAssemblyInstantiateImpl(isolate, module, ffi).ToLocal(&instance)) {
     306             :     args.GetReturnValue().Set(instance);
     307         165 :   }
     308         165 : }
     309             : 
     310         510 : void WebAssemblyInstantiateToPairCallback(
     311        1725 :     const v8::FunctionCallbackInfo<v8::Value>& args) {
     312             :   DCHECK_GE(args.Length(), 1);
     313             :   Isolate* isolate = args.GetIsolate();
     314             :   MicrotasksScope does_not_run_microtasks(isolate,
     315         510 :                                           MicrotasksScope::kDoNotRunMicrotasks);
     316             : 
     317         705 :   HandleScope scope(args.GetIsolate());
     318             : 
     319         510 :   Local<Context> context = isolate->GetCurrentContext();
     320         510 :   Local<Value> module = args[0];
     321             : 
     322             :   const uint8_t* instance_str = reinterpret_cast<const uint8_t*>("instance");
     323             :   const uint8_t* module_str = reinterpret_cast<const uint8_t*>("module");
     324             :   Local<Value> instance;
     325         510 :   if (!WebAssemblyInstantiateImpl(isolate, module, args.Data())
     326        1020 :            .ToLocal(&instance)) {
     327         315 :     return;
     328             :   }
     329             : 
     330         195 :   Local<Object> ret = Object::New(isolate);
     331             :   Local<String> instance_name =
     332             :       String::NewFromOneByte(isolate, instance_str,
     333             :                              NewStringType::kInternalized)
     334         195 :           .ToLocalChecked();
     335             :   Local<String> module_name =
     336             :       String::NewFromOneByte(isolate, module_str, NewStringType::kInternalized)
     337         195 :           .ToLocalChecked();
     338             : 
     339         195 :   CHECK(ret->CreateDataProperty(context, instance_name, instance).IsJust());
     340         195 :   CHECK(ret->CreateDataProperty(context, module_name, module).IsJust());
     341         195 :   args.GetReturnValue().Set(ret);
     342             : }
     343             : 
     344             : // new WebAssembly.Instance(module, imports) -> WebAssembly.Instance
     345      120051 : void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) {
     346             :   Isolate* isolate = args.GetIsolate();
     347             :   MicrotasksScope does_not_run_microtasks(isolate,
     348       40297 :                                           MicrotasksScope::kDoNotRunMicrotasks);
     349             : 
     350       80399 :   HandleScope scope(args.GetIsolate());
     351       40297 :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
     352       40492 :   if (i_isolate->wasm_instance_callback()(args)) return;
     353             : 
     354       40102 :   ErrorThrower thrower(i_isolate, "WebAssembly.Instance()");
     355             : 
     356       40267 :   auto maybe_module = GetFirstArgumentAsModule(args, &thrower);
     357       40267 :   if (thrower.error()) return;
     358             : 
     359             :   // If args.Length < 2, this will be undefined - see FunctionCallbackInfo.
     360             :   // We'll check for that in WebAssemblyInstantiateImpl.
     361       40102 :   Local<Value> data = args[1];
     362             : 
     363             :   Local<Value> instance;
     364       80204 :   if (WebAssemblyInstantiateImpl(isolate, args[0], data).ToLocal(&instance)) {
     365             :     args.GetReturnValue().Set(instance);
     366       40102 :   }
     367             : }
     368             : 
     369             : // WebAssembly.instantiate(module, imports) -> WebAssembly.Instance
     370             : // WebAssembly.instantiate(bytes, imports) ->
     371             : //     {module: WebAssembly.Module, instance: WebAssembly.Instance}
     372       35070 : void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) {
     373             :   v8::Isolate* isolate = args.GetIsolate();
     374       11205 :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
     375       11205 :   MicrotasksScope runs_microtasks(isolate, MicrotasksScope::kRunMicrotasks);
     376       21570 :   if (i_isolate->wasm_instantiate_callback()(args)) return;
     377             : 
     378         840 :   ErrorThrower thrower(i_isolate, "WebAssembly.instantiate()");
     379             : 
     380       12030 :   HandleScope scope(isolate);
     381             : 
     382       11190 :   Local<Context> context = isolate->GetCurrentContext();
     383             :   i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
     384             : 
     385       32730 :   ASSIGN(Promise::Resolver, resolver, Promise::Resolver::New(context));
     386       11175 :   Local<Promise> module_promise = resolver->GetPromise();
     387             :   args.GetReturnValue().Set(module_promise);
     388             : 
     389       11175 :   if (args.Length() < 1) {
     390             :     thrower.TypeError(
     391             :         "Argument 0 must be provided and must be either a buffer source or a "
     392       10275 :         "WebAssembly.Module object");
     393       10275 :     auto maybe = resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
     394       10275 :     CHECK_IMPLIES(!maybe.FromMaybe(false),
     395             :                   i_isolate->has_scheduled_exception());
     396             :     return;
     397             :   }
     398             : 
     399         900 :   Local<Value> first_arg_value = args[0];
     400             :   i::Handle<i::Object> first_arg = Utils::OpenHandle(*first_arg_value);
     401         900 :   if (!first_arg->IsJSObject()) {
     402             :     thrower.TypeError(
     403          60 :         "Argument 0 must be a buffer source or a WebAssembly.Module object");
     404          60 :     auto maybe = resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
     405          60 :     CHECK_IMPLIES(!maybe.FromMaybe(false),
     406             :                   i_isolate->has_scheduled_exception());
     407             :     return;
     408             :   }
     409             : 
     410             :   FunctionCallback instantiator = nullptr;
     411         840 :   if (HasBrand(first_arg, i::Handle<i::Symbol>(i_context->wasm_module_sym()))) {
     412         165 :     module_promise = resolver->GetPromise();
     413         165 :     if (!resolver->Resolve(context, first_arg_value).IsJust()) return;
     414             :     instantiator = WebAssemblyInstantiateImplCallback;
     415             :   } else {
     416        1350 :     ASSIGN(Function, async_compile, Function::New(context, WebAssemblyCompile));
     417        1350 :     ASSIGN(Value, async_compile_retval,
     418             :            async_compile->Call(context, args.Holder(), 1, &first_arg_value));
     419             :     module_promise = Local<Promise>::Cast(async_compile_retval);
     420             :     instantiator = WebAssemblyInstantiateToPairCallback;
     421             :   }
     422             :   DCHECK(!module_promise.IsEmpty());
     423             :   DCHECK_NOT_NULL(instantiator);
     424             :   // If args.Length < 2, this will be undefined - see FunctionCallbackInfo.
     425             :   // We'll check for that in WebAssemblyInstantiateImpl.
     426         840 :   Local<Value> data = args[1];
     427        1680 :   ASSIGN(Function, instantiate_impl,
     428             :          Function::New(context, instantiator, data));
     429        1680 :   ASSIGN(Promise, result, module_promise->Then(context, instantiate_impl));
     430         840 :   args.GetReturnValue().Set(result);
     431             : }
     432             : 
     433        2940 : bool GetIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower,
     434             :                         Local<Context> context, Local<v8::Object> object,
     435             :                         Local<String> property, int* result,
     436             :                         int64_t lower_bound, uint64_t upper_bound) {
     437        2940 :   v8::MaybeLocal<v8::Value> maybe = object->Get(context, property);
     438             :   v8::Local<v8::Value> value;
     439        2940 :   if (maybe.ToLocal(&value)) {
     440             :     int64_t number;
     441        5880 :     if (!value->IntegerValue(context).To(&number)) return false;
     442        2880 :     if (number < lower_bound) {
     443             :       thrower->RangeError("Property value %" PRId64
     444             :                           " is below the lower bound %" PRIx64,
     445         240 :                           number, lower_bound);
     446             :       return false;
     447             :     }
     448        2640 :     if (number > static_cast<int64_t>(upper_bound)) {
     449             :       thrower->RangeError("Property value %" PRId64
     450             :                           " is above the upper bound %" PRIu64,
     451         195 :                           number, upper_bound);
     452             :       return false;
     453             :     }
     454        2445 :     *result = static_cast<int>(number);
     455             :     return true;
     456             :   }
     457             :   return false;
     458             : }
     459             : 
     460             : // new WebAssembly.Table(args) -> WebAssembly.Table
     461        3390 : void WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) {
     462             :   v8::Isolate* isolate = args.GetIsolate();
     463             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
     464        1290 :   HandleScope scope(isolate);
     465         810 :   ErrorThrower thrower(i_isolate, "WebAssembly.Module()");
     466        2535 :   if (args.Length() < 1 || !args[0]->IsObject()) {
     467         105 :     thrower.TypeError("Argument 0 must be a table descriptor");
     468         105 :     return;
     469             :   }
     470        1185 :   Local<Context> context = isolate->GetCurrentContext();
     471        1185 :   Local<v8::Object> descriptor = args[0]->ToObject(context).ToLocalChecked();
     472             :   // The descriptor's 'element'.
     473             :   {
     474             :     v8::MaybeLocal<v8::Value> maybe =
     475        1185 :         descriptor->Get(context, v8_str(isolate, "element"));
     476             :     v8::Local<v8::Value> value;
     477        1335 :     if (!maybe.ToLocal(&value)) return;
     478             :     v8::Local<v8::String> string;
     479        2370 :     if (!value->ToString(context).ToLocal(&string)) return;
     480             :     bool equal;
     481        2370 :     if (!string->Equals(context, v8_str(isolate, "anyfunc")).To(&equal)) return;
     482        1185 :     if (!equal) {
     483         150 :       thrower.TypeError("Descriptor property 'element' must be 'anyfunc'");
     484         150 :       return;
     485             :     }
     486             :   }
     487             :   // The descriptor's 'initial'.
     488        1035 :   int initial = 0;
     489        1035 :   if (!GetIntegerProperty(isolate, &thrower, context, descriptor,
     490             :                           v8_str(isolate, "initial"), &initial, 0,
     491        2070 :                           i::FLAG_wasm_max_table_size)) {
     492             :     return;
     493             :   }
     494             :   // The descriptor's 'maximum'.
     495         915 :   int maximum = -1;
     496             :   Local<String> maximum_key = v8_str(isolate, "maximum");
     497         915 :   Maybe<bool> has_maximum = descriptor->Has(context, maximum_key);
     498             : 
     499        1830 :   if (!has_maximum.IsNothing() && has_maximum.FromJust()) {
     500         510 :     if (!GetIntegerProperty(isolate, &thrower, context, descriptor, maximum_key,
     501             :                             &maximum, initial,
     502         510 :                             i::wasm::kSpecMaxWasmTableSize)) {
     503             :       return;
     504             :     }
     505             :   }
     506             : 
     507             :   i::Handle<i::FixedArray> fixed_array;
     508             :   i::Handle<i::JSObject> table_obj =
     509         810 :       i::WasmTableObject::New(i_isolate, initial, maximum, &fixed_array);
     510             :   v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
     511         810 :   return_value.Set(Utils::ToLocal(table_obj));
     512             : }
     513             : 
     514        3000 : void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) {
     515             :   v8::Isolate* isolate = args.GetIsolate();
     516             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
     517        1125 :   HandleScope scope(isolate);
     518         750 :   ErrorThrower thrower(i_isolate, "WebAssembly.Memory()");
     519        2205 :   if (args.Length() < 1 || !args[0]->IsObject()) {
     520         105 :     thrower.TypeError("Argument 0 must be a memory descriptor");
     521         105 :     return;
     522             :   }
     523        1020 :   Local<Context> context = isolate->GetCurrentContext();
     524        1020 :   Local<v8::Object> descriptor = args[0]->ToObject(context).ToLocalChecked();
     525             :   // The descriptor's 'initial'.
     526        1020 :   int initial = 0;
     527        1020 :   if (!GetIntegerProperty(isolate, &thrower, context, descriptor,
     528             :                           v8_str(isolate, "initial"), &initial, 0,
     529        2040 :                           i::FLAG_wasm_max_mem_pages)) {
     530             :     return;
     531             :   }
     532             :   // The descriptor's 'maximum'.
     533         885 :   int maximum = -1;
     534             :   Local<String> maximum_key = v8_str(isolate, "maximum");
     535         885 :   Maybe<bool> has_maximum = descriptor->Has(context, maximum_key);
     536             : 
     537        1770 :   if (!has_maximum.IsNothing() && has_maximum.FromJust()) {
     538         375 :     if (!GetIntegerProperty(isolate, &thrower, context, descriptor, maximum_key,
     539             :                             &maximum, initial,
     540         375 :                             i::wasm::kSpecMaxWasmMemoryPages)) {
     541             :       return;
     542             :     }
     543             :   }
     544         750 :   size_t size = static_cast<size_t>(i::wasm::WasmModule::kPageSize) *
     545         750 :                 static_cast<size_t>(initial);
     546             :   i::Handle<i::JSArrayBuffer> buffer =
     547         750 :       i::wasm::NewArrayBuffer(i_isolate, size, i::FLAG_wasm_guard_pages);
     548         750 :   if (buffer.is_null()) {
     549           0 :     thrower.RangeError("could not allocate memory");
     550           0 :     return;
     551             :   }
     552             :   i::Handle<i::JSObject> memory_obj =
     553         750 :       i::WasmMemoryObject::New(i_isolate, buffer, maximum);
     554         750 :   args.GetReturnValue().Set(Utils::ToLocal(memory_obj));
     555             : }
     556             : 
     557        4812 : void WebAssemblyTableGetLength(
     558       19014 :     const v8::FunctionCallbackInfo<v8::Value>& args) {
     559             :   v8::Isolate* isolate = args.GetIsolate();
     560             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
     561        4812 :   HandleScope scope(isolate);
     562        4695 :   ErrorThrower thrower(i_isolate, "WebAssembly.Table.length()");
     563        4812 :   Local<Context> context = isolate->GetCurrentContext();
     564             :   i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
     565        4812 :   if (!BrandCheck(Utils::OpenHandle(*args.This()),
     566             :                   i::Handle<i::Symbol>(i_context->wasm_table_sym()), &thrower,
     567        4812 :                   "Receiver is not a WebAssembly.Table")) {
     568         117 :     return;
     569             :   }
     570             :   auto receiver =
     571             :       i::Handle<i::WasmTableObject>::cast(Utils::OpenHandle(*args.This()));
     572             :   args.GetReturnValue().Set(
     573        9390 :       v8::Number::New(isolate, receiver->current_length()));
     574             : }
     575             : 
     576             : // WebAssembly.Table.grow(num) -> num
     577        2205 : void WebAssemblyTableGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
     578             :   v8::Isolate* isolate = args.GetIsolate();
     579             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
     580         525 :   HandleScope scope(isolate);
     581         255 :   ErrorThrower thrower(i_isolate, "WebAssembly.Table.grow()");
     582         525 :   Local<Context> context = isolate->GetCurrentContext();
     583             :   i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
     584         525 :   if (!BrandCheck(Utils::OpenHandle(*args.This()),
     585             :                   i::Handle<i::Symbol>(i_context->wasm_table_sym()), &thrower,
     586         525 :                   "Receiver is not a WebAssembly.Table")) {
     587         270 :     return;
     588             :   }
     589             : 
     590             :   auto receiver =
     591             :       i::Handle<i::WasmTableObject>::cast(Utils::OpenHandle(*args.This()));
     592         450 :   i::Handle<i::FixedArray> old_array(receiver->functions(), i_isolate);
     593             :   int old_size = old_array->length();
     594             :   int64_t new_size64 = 0;
     595        1350 :   if (args.Length() > 0 && !args[0]->IntegerValue(context).To(&new_size64)) {
     596             :     return;
     597             :   }
     598         450 :   new_size64 += old_size;
     599             : 
     600         450 :   int64_t max_size64 = receiver->maximum_length();
     601         795 :   if (max_size64 < 0 ||
     602         345 :       max_size64 > static_cast<int64_t>(i::FLAG_wasm_max_table_size)) {
     603         105 :     max_size64 = i::FLAG_wasm_max_table_size;
     604             :   }
     605             : 
     606         450 :   if (new_size64 < old_size || new_size64 > max_size64) {
     607             :     thrower.RangeError(new_size64 < old_size ? "trying to shrink table"
     608         195 :                                              : "maximum table size exceeded");
     609         195 :     return;
     610             :   }
     611             : 
     612         255 :   int new_size = static_cast<int>(new_size64);
     613             :   i::WasmTableObject::Grow(i_isolate, receiver,
     614         255 :                            static_cast<uint32_t>(new_size - old_size));
     615             : 
     616         255 :   if (new_size != old_size) {
     617             :     i::Handle<i::FixedArray> new_array =
     618         180 :         i_isolate->factory()->NewFixedArray(new_size);
     619        2160 :     for (int i = 0; i < old_size; ++i) new_array->set(i, old_array->get(i));
     620         180 :     i::Object* null = i_isolate->heap()->null_value();
     621   150001035 :     for (int i = old_size; i < new_size; ++i) new_array->set(i, null);
     622         180 :     receiver->set_functions(*new_array);
     623             :   }
     624             : 
     625             :   // TODO(gdeepti): use weak links for instances
     626             :   v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
     627         255 :   return_value.Set(old_size);
     628             : }
     629             : 
     630             : // WebAssembly.Table.get(num) -> JSFunction
     631       58395 : void WebAssemblyTableGet(const v8::FunctionCallbackInfo<v8::Value>& args) {
     632             :   v8::Isolate* isolate = args.GetIsolate();
     633             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
     634       11730 :   HandleScope scope(isolate);
     635       11400 :   ErrorThrower thrower(i_isolate, "WebAssembly.Table.get()");
     636       11730 :   Local<Context> context = isolate->GetCurrentContext();
     637             :   i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
     638       11730 :   if (!BrandCheck(Utils::OpenHandle(*args.This()),
     639             :                   i::Handle<i::Symbol>(i_context->wasm_table_sym()), &thrower,
     640       11730 :                   "Receiver is not a WebAssembly.Table")) {
     641         330 :     return;
     642             :   }
     643             : 
     644             :   auto receiver =
     645             :       i::Handle<i::WasmTableObject>::cast(Utils::OpenHandle(*args.This()));
     646       11655 :   i::Handle<i::FixedArray> array(receiver->functions(), i_isolate);
     647             :   int i = 0;
     648       34965 :   if (args.Length() > 0 && !args[0]->Int32Value(context).To(&i)) return;
     649             :   v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
     650       23205 :   if (i < 0 || i >= array->length()) {
     651         225 :     thrower.RangeError("index out of bounds");
     652         225 :     return;
     653             :   }
     654             : 
     655             :   i::Handle<i::Object> value(array->get(i), i_isolate);
     656       11400 :   return_value.Set(Utils::ToLocal(value));
     657             : }
     658             : 
     659             : // WebAssembly.Table.set(num, JSFunction)
     660       16320 : void WebAssemblyTableSet(const v8::FunctionCallbackInfo<v8::Value>& args) {
     661             :   v8::Isolate* isolate = args.GetIsolate();
     662             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
     663        4200 :   HandleScope scope(isolate);
     664        3480 :   ErrorThrower thrower(i_isolate, "WebAssembly.Table.set()");
     665        4200 :   Local<Context> context = isolate->GetCurrentContext();
     666             :   i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
     667        4200 :   if (!BrandCheck(Utils::OpenHandle(*args.This()),
     668             :                   i::Handle<i::Symbol>(i_context->wasm_table_sym()), &thrower,
     669        4200 :                   "Receiver is not a WebAssembly.Table")) {
     670         720 :     return;
     671             :   }
     672        4110 :   if (args.Length() < 2) {
     673          60 :     thrower.TypeError("Argument 1 must be null or a function");
     674          60 :     return;
     675             :   }
     676             :   i::Handle<i::Object> value = Utils::OpenHandle(*args[1]);
     677        9690 :   if (!value->IsNull(i_isolate) &&
     678        1410 :       (!value->IsJSFunction() ||
     679             :        i::Handle<i::JSFunction>::cast(value)->code()->kind() !=
     680             :            i::Code::JS_TO_WASM_FUNCTION)) {
     681         240 :     thrower.TypeError("Argument 1 must be null or a WebAssembly function");
     682         240 :     return;
     683             :   }
     684             : 
     685             :   auto receiver =
     686             :       i::Handle<i::WasmTableObject>::cast(Utils::OpenHandle(*args.This()));
     687        3810 :   i::Handle<i::FixedArray> array(receiver->functions(), i_isolate);
     688             :   int i;
     689        7620 :   if (!args[0]->Int32Value(context).To(&i)) return;
     690        7470 :   if (i < 0 || i >= array->length()) {
     691         285 :     thrower.RangeError("index out of bounds");
     692         285 :     return;
     693             :   }
     694             : 
     695             :   i::Handle<i::FixedArray> dispatch_tables(receiver->dispatch_tables(),
     696        3480 :                                            i_isolate);
     697        3480 :   if (value->IsNull(i_isolate)) {
     698             :     i::wasm::UpdateDispatchTables(i_isolate, dispatch_tables, i,
     699        2250 :                                   i::Handle<i::JSFunction>::null());
     700             :   } else {
     701             :     i::wasm::UpdateDispatchTables(i_isolate, dispatch_tables, i,
     702        1230 :                                   i::Handle<i::JSFunction>::cast(value));
     703             :   }
     704             : 
     705        6960 :   i::Handle<i::FixedArray>::cast(array)->set(i, *value);
     706             : }
     707             : 
     708             : // WebAssembly.Memory.grow(num) -> num
     709        2940 : void WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
     710             :   v8::Isolate* isolate = args.GetIsolate();
     711             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
     712         660 :   HandleScope scope(isolate);
     713         420 :   ErrorThrower thrower(i_isolate, "WebAssembly.Memory.grow()");
     714         660 :   Local<Context> context = isolate->GetCurrentContext();
     715             :   i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
     716         660 :   if (!BrandCheck(Utils::OpenHandle(*args.This()),
     717             :                   i::Handle<i::Symbol>(i_context->wasm_memory_sym()), &thrower,
     718         660 :                   "Receiver is not a WebAssembly.Memory")) {
     719         240 :     return;
     720             :   }
     721             :   int64_t delta_size = 0;
     722        1800 :   if (args.Length() < 1 || !args[0]->IntegerValue(context).To(&delta_size)) {
     723           0 :     thrower.TypeError("Argument 0 required, must be numeric value of pages");
     724           0 :     return;
     725             :   }
     726             :   i::Handle<i::WasmMemoryObject> receiver =
     727             :       i::Handle<i::WasmMemoryObject>::cast(Utils::OpenHandle(*args.This()));
     728         600 :   int64_t max_size64 = receiver->maximum_pages();
     729        1050 :   if (max_size64 < 0 ||
     730         450 :       max_size64 > static_cast<int64_t>(i::FLAG_wasm_max_mem_pages)) {
     731         150 :     max_size64 = i::FLAG_wasm_max_mem_pages;
     732             :   }
     733         600 :   i::Handle<i::JSArrayBuffer> old_buffer(receiver->buffer());
     734             :   uint32_t old_size =
     735         600 :       old_buffer->byte_length()->Number() / i::wasm::kSpecMaxWasmMemoryPages;
     736         600 :   int64_t new_size64 = old_size + delta_size;
     737         600 :   if (delta_size < 0 || max_size64 < new_size64 || new_size64 < old_size) {
     738             :     thrower.RangeError(new_size64 < old_size ? "trying to shrink memory"
     739         180 :                                              : "maximum memory size exceeded");
     740         180 :     return;
     741             :   }
     742             :   int32_t ret = i::WasmMemoryObject::Grow(i_isolate, receiver,
     743         420 :                                           static_cast<uint32_t>(delta_size));
     744         420 :   if (ret == -1) {
     745           0 :     thrower.RangeError("Unable to grow instance memory.");
     746           0 :     return;
     747             :   }
     748         420 :   i::wasm::DetachWebAssemblyMemoryBuffer(i_isolate, old_buffer);
     749             :   v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
     750         420 :   return_value.Set(ret);
     751             : }
     752             : 
     753             : // WebAssembly.Memory.buffer -> ArrayBuffer
     754        2817 : void WebAssemblyMemoryGetBuffer(
     755       11034 :     const v8::FunctionCallbackInfo<v8::Value>& args) {
     756             :   v8::Isolate* isolate = args.GetIsolate();
     757             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
     758        2817 :   HandleScope scope(isolate);
     759        2700 :   ErrorThrower thrower(i_isolate, "WebAssembly.Memory.buffer");
     760        2817 :   Local<Context> context = isolate->GetCurrentContext();
     761             :   i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
     762        2817 :   if (!BrandCheck(Utils::OpenHandle(*args.This()),
     763             :                   i::Handle<i::Symbol>(i_context->wasm_memory_sym()), &thrower,
     764        2817 :                   "Receiver is not a WebAssembly.Memory")) {
     765         117 :     return;
     766             :   }
     767             :   i::Handle<i::WasmMemoryObject> receiver =
     768             :       i::Handle<i::WasmMemoryObject>::cast(Utils::OpenHandle(*args.This()));
     769        2700 :   i::Handle<i::Object> buffer(receiver->buffer(), i_isolate);
     770             :   DCHECK(buffer->IsJSArrayBuffer());
     771             :   v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
     772        2700 :   return_value.Set(Utils::ToLocal(buffer));
     773             : }
     774             : }  // namespace
     775             : 
     776             : // TODO(titzer): we use the API to create the function template because the
     777             : // internal guts are too ugly to replicate here.
     778     1686126 : static i::Handle<i::FunctionTemplateInfo> NewTemplate(i::Isolate* i_isolate,
     779             :                                                       FunctionCallback func) {
     780             :   Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate);
     781     1686126 :   Local<FunctionTemplate> templ = FunctionTemplate::New(isolate, func);
     782     1686128 :   templ->ReadOnlyPrototype();
     783     1686127 :   return v8::Utils::OpenHandle(*templ);
     784             : }
     785             : 
     786             : namespace internal {
     787             : 
     788     1475357 : Handle<JSFunction> InstallFunc(Isolate* isolate, Handle<JSObject> object,
     789             :                                const char* str, FunctionCallback func,
     790             :                                int length = 0) {
     791             :   Handle<String> name = v8_str(isolate, str);
     792     1475360 :   Handle<FunctionTemplateInfo> temp = NewTemplate(isolate, func);
     793             :   Handle<JSFunction> function =
     794     2950719 :       ApiNatives::InstantiateFunction(temp).ToHandleChecked();
     795     1475358 :   JSFunction::SetName(function, name, isolate->factory()->empty_string());
     796             :   function->shared()->set_length(length);
     797             :   PropertyAttributes attributes = static_cast<PropertyAttributes>(DONT_ENUM);
     798     1475359 :   JSObject::AddProperty(object, name, function, attributes);
     799     1475361 :   return function;
     800             : }
     801             : 
     802      210766 : Handle<JSFunction> InstallGetter(Isolate* isolate, Handle<JSObject> object,
     803             :                                  const char* str, FunctionCallback func) {
     804             :   Handle<String> name = v8_str(isolate, str);
     805      210766 :   Handle<FunctionTemplateInfo> temp = NewTemplate(isolate, func);
     806             :   Handle<JSFunction> function =
     807      421532 :       ApiNatives::InstantiateFunction(temp).ToHandleChecked();
     808             :   v8::PropertyAttribute attributes =
     809             :       static_cast<v8::PropertyAttribute>(v8::DontEnum);
     810             :   Utils::ToLocal(object)->SetAccessorProperty(Utils::ToLocal(name),
     811             :                                               Utils::ToLocal(function),
     812      210766 :                                               Local<Function>(), attributes);
     813      210766 :   return function;
     814             : }
     815             : 
     816      146805 : void WasmJs::Install(Isolate* isolate) {
     817      146805 :   Handle<JSGlobalObject> global = isolate->global_object();
     818             :   Handle<Context> context(global->native_context(), isolate);
     819             :   // TODO(titzer): once FLAG_expose_wasm is gone, this should become a DCHECK.
     820      188229 :   if (context->get(Context::WASM_FUNCTION_MAP_INDEX)->IsMap()) return;
     821             : 
     822             :   // Install Maps.
     823             : 
     824             :   // TODO(titzer): Also make one for strict mode functions?
     825             :   Handle<Map> prev_map = Handle<Map>(context->sloppy_function_map(), isolate);
     826             : 
     827             :   InstanceType instance_type = prev_map->instance_type();
     828      105383 :   int embedder_fields = JSObject::GetEmbedderFieldCount(*prev_map);
     829      105383 :   CHECK_EQ(0, embedder_fields);
     830             :   int pre_allocated =
     831      105383 :       prev_map->GetInObjectProperties() - prev_map->unused_property_fields();
     832      105383 :   int instance_size = 0;
     833      105383 :   int in_object_properties = 0;
     834             :   int wasm_embedder_fields = embedder_fields + 1  // module instance object
     835             :                              + 1                  // function arity
     836      105383 :                              + 1;                 // function signature
     837             :   JSFunction::CalculateInstanceSizeHelper(instance_type, wasm_embedder_fields,
     838             :                                           0, &instance_size,
     839      105383 :                                           &in_object_properties);
     840             : 
     841      105383 :   int unused_property_fields = in_object_properties - pre_allocated;
     842             :   Handle<Map> map = Map::CopyInitialMap(
     843      105383 :       prev_map, instance_size, in_object_properties, unused_property_fields);
     844             : 
     845             :   context->set_wasm_function_map(*map);
     846             : 
     847             :   // Install symbols.
     848             : 
     849             :   Factory* factory = isolate->factory();
     850             :   // Create private symbols.
     851      105383 :   Handle<Symbol> module_sym = factory->NewPrivateSymbol();
     852             :   context->set_wasm_module_sym(*module_sym);
     853             : 
     854      105382 :   Handle<Symbol> instance_sym = factory->NewPrivateSymbol();
     855             :   context->set_wasm_instance_sym(*instance_sym);
     856             : 
     857      105383 :   Handle<Symbol> table_sym = factory->NewPrivateSymbol();
     858             :   context->set_wasm_table_sym(*table_sym);
     859             : 
     860      105383 :   Handle<Symbol> memory_sym = factory->NewPrivateSymbol();
     861             :   context->set_wasm_memory_sym(*memory_sym);
     862             : 
     863             :   // Install the JS API.
     864             : 
     865             :   // Setup WebAssembly
     866             :   Handle<String> name = v8_str(isolate, "WebAssembly");
     867      105383 :   Handle<JSFunction> cons = factory->NewFunction(name);
     868      210766 :   JSFunction::SetPrototype(cons, isolate->initial_object_prototype());
     869      105382 :   cons->shared()->set_instance_class_name(*name);
     870      105382 :   Handle<JSObject> webassembly = factory->NewJSObject(cons, TENURED);
     871             :   PropertyAttributes attributes = static_cast<PropertyAttributes>(DONT_ENUM);
     872      105383 :   JSObject::AddProperty(global, name, webassembly, attributes);
     873             :   PropertyAttributes ro_attributes =
     874             :       static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
     875             :   JSObject::AddProperty(webassembly, factory->to_string_tag_symbol(),
     876      105383 :                         v8_str(isolate, "WebAssembly"), ro_attributes);
     877      105382 :   InstallFunc(isolate, webassembly, "compile", WebAssemblyCompile, 1);
     878      105382 :   InstallFunc(isolate, webassembly, "validate", WebAssemblyValidate, 1);
     879      105383 :   InstallFunc(isolate, webassembly, "instantiate", WebAssemblyInstantiate, 1);
     880             : 
     881             :   // Setup Module
     882             :   Handle<JSFunction> module_constructor =
     883      105383 :       InstallFunc(isolate, webassembly, "Module", WebAssemblyModule, 1);
     884             :   context->set_wasm_module_constructor(*module_constructor);
     885             :   Handle<JSObject> module_proto =
     886      105382 :       factory->NewJSObject(module_constructor, TENURED);
     887             :   i::Handle<i::Map> module_map = isolate->factory()->NewMap(
     888             :       i::JS_API_OBJECT_TYPE, i::JSObject::kHeaderSize +
     889      105383 :                              WasmModuleObject::kFieldCount * i::kPointerSize);
     890      105383 :   JSFunction::SetInitialMap(module_constructor, module_map, module_proto);
     891             :   InstallFunc(isolate, module_constructor, "imports", WebAssemblyModuleImports,
     892      105383 :               1);
     893             :   InstallFunc(isolate, module_constructor, "exports", WebAssemblyModuleExports,
     894      105383 :               1);
     895             :   InstallFunc(isolate, module_constructor, "customSections",
     896      105383 :               WebAssemblyModuleCustomSections, 2);
     897             :   JSObject::AddProperty(module_proto, isolate->factory()->constructor_string(),
     898      105383 :                         module_constructor, DONT_ENUM);
     899             :   JSObject::AddProperty(module_proto, factory->to_string_tag_symbol(),
     900      105383 :                         v8_str(isolate, "WebAssembly.Module"), ro_attributes);
     901             : 
     902             :   // Setup Instance
     903             :   Handle<JSFunction> instance_constructor =
     904      105383 :       InstallFunc(isolate, webassembly, "Instance", WebAssemblyInstance, 1);
     905             :   context->set_wasm_instance_constructor(*instance_constructor);
     906             :   Handle<JSObject> instance_proto =
     907      105383 :       factory->NewJSObject(instance_constructor, TENURED);
     908             :   i::Handle<i::Map> instance_map = isolate->factory()->NewMap(
     909             :       i::JS_API_OBJECT_TYPE, i::JSObject::kHeaderSize +
     910      105383 :                              WasmInstanceObject::kFieldCount * i::kPointerSize);
     911      105383 :   JSFunction::SetInitialMap(instance_constructor, instance_map, instance_proto);
     912             :   JSObject::AddProperty(instance_proto,
     913             :                         isolate->factory()->constructor_string(),
     914      105383 :                         instance_constructor, DONT_ENUM);
     915             :   JSObject::AddProperty(instance_proto, factory->to_string_tag_symbol(),
     916      105383 :                         v8_str(isolate, "WebAssembly.Instance"), ro_attributes);
     917             : 
     918             :   // Setup Table
     919             :   Handle<JSFunction> table_constructor =
     920      105383 :       InstallFunc(isolate, webassembly, "Table", WebAssemblyTable, 1);
     921             :   context->set_wasm_table_constructor(*table_constructor);
     922             :   Handle<JSObject> table_proto =
     923      105383 :       factory->NewJSObject(table_constructor, TENURED);
     924             :   i::Handle<i::Map> table_map = isolate->factory()->NewMap(
     925             :       i::JS_API_OBJECT_TYPE, i::JSObject::kHeaderSize +
     926      105383 :                              WasmTableObject::kFieldCount * i::kPointerSize);
     927      105383 :   JSFunction::SetInitialMap(table_constructor, table_map, table_proto);
     928             :   JSObject::AddProperty(table_proto, isolate->factory()->constructor_string(),
     929      105383 :                         table_constructor, DONT_ENUM);
     930      105383 :   InstallGetter(isolate, table_proto, "length", WebAssemblyTableGetLength);
     931      105383 :   InstallFunc(isolate, table_proto, "grow", WebAssemblyTableGrow, 1);
     932      105383 :   InstallFunc(isolate, table_proto, "get", WebAssemblyTableGet, 1);
     933      105383 :   InstallFunc(isolate, table_proto, "set", WebAssemblyTableSet, 2);
     934             :   JSObject::AddProperty(table_proto, factory->to_string_tag_symbol(),
     935      105383 :                         v8_str(isolate, "WebAssembly.Table"), ro_attributes);
     936             : 
     937             :   // Setup Memory
     938             :   Handle<JSFunction> memory_constructor =
     939      105382 :       InstallFunc(isolate, webassembly, "Memory", WebAssemblyMemory, 1);
     940             :   context->set_wasm_memory_constructor(*memory_constructor);
     941             :   Handle<JSObject> memory_proto =
     942      105382 :       factory->NewJSObject(memory_constructor, TENURED);
     943             :   i::Handle<i::Map> memory_map = isolate->factory()->NewMap(
     944             :       i::JS_API_OBJECT_TYPE, i::JSObject::kHeaderSize +
     945      105383 :                              WasmMemoryObject::kFieldCount * i::kPointerSize);
     946      105382 :   JSFunction::SetInitialMap(memory_constructor, memory_map, memory_proto);
     947             :   JSObject::AddProperty(memory_proto, isolate->factory()->constructor_string(),
     948      105383 :                         memory_constructor, DONT_ENUM);
     949      105383 :   InstallFunc(isolate, memory_proto, "grow", WebAssemblyMemoryGrow, 1);
     950      105383 :   InstallGetter(isolate, memory_proto, "buffer", WebAssemblyMemoryGetBuffer);
     951             :   JSObject::AddProperty(memory_proto, factory->to_string_tag_symbol(),
     952      105383 :                         v8_str(isolate, "WebAssembly.Memory"), ro_attributes);
     953             : 
     954             :   // Setup errors
     955             :   attributes = static_cast<PropertyAttributes>(DONT_ENUM);
     956             :   Handle<JSFunction> compile_error(
     957      210765 :       isolate->native_context()->wasm_compile_error_function());
     958             :   JSObject::AddProperty(webassembly, isolate->factory()->CompileError_string(),
     959      105383 :                         compile_error, attributes);
     960             :   Handle<JSFunction> link_error(
     961      210765 :       isolate->native_context()->wasm_link_error_function());
     962             :   JSObject::AddProperty(webassembly, isolate->factory()->LinkError_string(),
     963      105383 :                         link_error, attributes);
     964             :   Handle<JSFunction> runtime_error(
     965      210766 :       isolate->native_context()->wasm_runtime_error_function());
     966             :   JSObject::AddProperty(webassembly, isolate->factory()->RuntimeError_string(),
     967      105383 :                         runtime_error, attributes);
     968             : }
     969             : 
     970        1035 : bool WasmJs::IsWasmMemoryObject(Isolate* isolate, Handle<Object> value) {
     971             :   i::Handle<i::Symbol> symbol(isolate->context()->wasm_memory_sym(), isolate);
     972        1035 :   return HasBrand(value, symbol);
     973             : }
     974             : 
     975         765 : bool WasmJs::IsWasmTableObject(Isolate* isolate, Handle<Object> value) {
     976             :   i::Handle<i::Symbol> symbol(isolate->context()->wasm_table_sym(), isolate);
     977         765 :   return HasBrand(value, symbol);
     978             : }
     979             : }  // namespace internal
     980             : }  // namespace v8

Generated by: LCOV version 1.10