LCOV - code coverage report
Current view: top level - src/wasm - wasm-js.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 695 758 91.7 %
Date: 2019-01-20 Functions: 72 81 88.9 %

          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/wasm/wasm-js.h"
       6             : 
       7             : #include <string>
       8             : 
       9             : #include "src/api-inl.h"
      10             : #include "src/api-natives.h"
      11             : #include "src/assert-scope.h"
      12             : #include "src/ast/ast.h"
      13             : #include "src/base/overflowing-math.h"
      14             : #include "src/execution.h"
      15             : #include "src/handles.h"
      16             : #include "src/heap/factory.h"
      17             : #include "src/isolate.h"
      18             : #include "src/objects-inl.h"
      19             : #include "src/objects/js-promise-inl.h"
      20             : #include "src/objects/templates.h"
      21             : #include "src/parsing/parse-info.h"
      22             : #include "src/trap-handler/trap-handler.h"
      23             : #include "src/wasm/streaming-decoder.h"
      24             : #include "src/wasm/wasm-engine.h"
      25             : #include "src/wasm/wasm-limits.h"
      26             : #include "src/wasm/wasm-memory.h"
      27             : #include "src/wasm/wasm-objects-inl.h"
      28             : #include "src/wasm/wasm-serialization.h"
      29             : 
      30             : using v8::internal::wasm::ErrorThrower;
      31             : 
      32             : namespace v8 {
      33             : 
      34          60 : class WasmStreaming::WasmStreamingImpl {
      35             :  public:
      36          30 :   WasmStreamingImpl(
      37             :       Isolate* isolate,
      38             :       std::shared_ptr<internal::wasm::CompilationResultResolver> resolver)
      39          30 :       : isolate_(isolate), resolver_(std::move(resolver)) {
      40          30 :     i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate_);
      41          30 :     auto enabled_features = i::wasm::WasmFeaturesFromIsolate(i_isolate);
      42          90 :     streaming_decoder_ = i_isolate->wasm_engine()->StartStreamingCompilation(
      43             :         i_isolate, enabled_features, handle(i_isolate->context(), i_isolate),
      44             :         resolver_);
      45          30 :   }
      46             : 
      47             :   void OnBytesReceived(const uint8_t* bytes, size_t size) {
      48          10 :     streaming_decoder_->OnBytesReceived(i::VectorOf(bytes, size));
      49             :   }
      50          10 :   void Finish() { streaming_decoder_->Finish(); }
      51             : 
      52          10 :   void Abort(MaybeLocal<Value> exception) {
      53          10 :     i::HandleScope scope(reinterpret_cast<i::Isolate*>(isolate_));
      54          10 :     streaming_decoder_->Abort();
      55             : 
      56             :     // If no exception value is provided, we do not reject the promise. This can
      57             :     // happen when streaming compilation gets aborted when no script execution
      58             :     // is allowed anymore, e.g. when a browser tab gets refreshed.
      59          20 :     if (exception.IsEmpty()) return;
      60             : 
      61           5 :     resolver_->OnCompilationFailed(
      62          10 :         Utils::OpenHandle(*exception.ToLocalChecked()));
      63             :   }
      64             : 
      65           0 :   bool SetCompiledModuleBytes(const uint8_t* bytes, size_t size) {
      66           0 :     if (!i::wasm::IsSupportedVersion({bytes, size})) return false;
      67           0 :     return streaming_decoder_->SetCompiledModuleBytes({bytes, size});
      68             :   }
      69             : 
      70           0 :   void SetClient(std::shared_ptr<Client> client) {
      71             :     // There are no other event notifications so just pass client to decoder.
      72             :     // Wrap the client with a callback here so we can also wrap the result.
      73             :     streaming_decoder_->SetModuleCompiledCallback(
      74           0 :         [client](const std::shared_ptr<i::wasm::NativeModule>& native_module) {
      75           0 :           client->OnModuleCompiled(Utils::Convert(native_module));
      76           0 :         });
      77           0 :   }
      78             : 
      79             :  private:
      80             :   Isolate* isolate_ = nullptr;
      81             :   std::shared_ptr<internal::wasm::StreamingDecoder> streaming_decoder_;
      82             :   std::shared_ptr<internal::wasm::CompilationResultResolver> resolver_;
      83             : };
      84             : 
      85           0 : WasmStreaming::WasmStreaming(std::unique_ptr<WasmStreamingImpl> impl)
      86           0 :     : impl_(std::move(impl)) {}
      87             : 
      88             : // The destructor is defined here because we have a unique_ptr with forward
      89             : // declaration.
      90             : WasmStreaming::~WasmStreaming() = default;
      91             : 
      92          10 : void WasmStreaming::OnBytesReceived(const uint8_t* bytes, size_t size) {
      93             :   impl_->OnBytesReceived(bytes, size);
      94          10 : }
      95             : 
      96          20 : void WasmStreaming::Finish() { impl_->Finish(); }
      97             : 
      98          10 : void WasmStreaming::Abort(MaybeLocal<Value> exception) {
      99          10 :   impl_->Abort(exception);
     100          10 : }
     101             : 
     102           0 : bool WasmStreaming::SetCompiledModuleBytes(const uint8_t* bytes, size_t size) {
     103           0 :   return impl_->SetCompiledModuleBytes(bytes, size);
     104             : }
     105             : 
     106           0 : void WasmStreaming::SetClient(std::shared_ptr<Client> client) {
     107           0 :   impl_->SetClient(client);
     108           0 : }
     109             : 
     110             : // static
     111          25 : std::shared_ptr<WasmStreaming> WasmStreaming::Unpack(Isolate* isolate,
     112             :                                                      Local<Value> value) {
     113             :   i::HandleScope scope(reinterpret_cast<i::Isolate*>(isolate));
     114             :   auto managed =
     115             :       i::Handle<i::Managed<WasmStreaming>>::cast(Utils::OpenHandle(*value));
     116          75 :   return managed->get();
     117             : }
     118             : 
     119             : namespace {
     120             : 
     121             : #define ASSIGN(type, var, expr)                      \
     122             :   Local<type> var;                                   \
     123             :   do {                                               \
     124             :     if (!expr.ToLocal(&var)) {                       \
     125             :       DCHECK(i_isolate->has_scheduled_exception());  \
     126             :       return;                                        \
     127             :     } else {                                         \
     128             :       DCHECK(!i_isolate->has_scheduled_exception()); \
     129             :     }                                                \
     130             :   } while (false)
     131             : 
     132             : // Like an ErrorThrower, but turns all pending exceptions into scheduled
     133             : // exceptions when going out of scope. Use this in API methods.
     134             : // Note that pending exceptions are not necessarily created by the ErrorThrower,
     135             : // but e.g. by the wasm start function. There might also be a scheduled
     136             : // exception, created by another API call (e.g. v8::Object::Get). But there
     137             : // should never be both pending and scheduled exceptions.
     138             : class ScheduledErrorThrower : public ErrorThrower {
     139             :  public:
     140             :   ScheduledErrorThrower(i::Isolate* isolate, const char* context)
     141             :       : ErrorThrower(isolate, context) {}
     142             : 
     143             :   ~ScheduledErrorThrower();
     144             : };
     145             : 
     146    48650933 : ScheduledErrorThrower::~ScheduledErrorThrower() {
     147             :   // There should never be both a pending and a scheduled exception.
     148             :   DCHECK(!isolate()->has_scheduled_exception() ||
     149             :          !isolate()->has_pending_exception());
     150             :   // Don't throw another error if there is already a scheduled error.
     151    72996679 :   if (isolate()->has_scheduled_exception()) {
     152        2034 :     Reset();
     153    24323435 :   } else if (isolate()->has_pending_exception()) {
     154          63 :     Reset();
     155          63 :     isolate()->OptionalRescheduleException(false);
     156    24323374 :   } else if (error()) {
     157       48690 :     isolate()->ScheduleThrow(*Reify());
     158             :   }
     159    24325466 : }
     160             : 
     161             : i::Handle<i::String> v8_str(i::Isolate* isolate, const char* str) {
     162     2431862 :   return isolate->factory()->NewStringFromAsciiChecked(str);
     163             : }
     164             : Local<String> v8_str(Isolate* isolate, const char* str) {
     165             :   return Utils::ToLocal(v8_str(reinterpret_cast<i::Isolate*>(isolate), str));
     166             : }
     167             : 
     168      145064 : i::MaybeHandle<i::WasmModuleObject> GetFirstArgumentAsModule(
     169             :     const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) {
     170             :   i::Handle<i::Object> arg0 = Utils::OpenHandle(*args[0]);
     171      290142 :   if (!arg0->IsWasmModuleObject()) {
     172         432 :     thrower->TypeError("Argument 0 must be a WebAssembly.Module");
     173         432 :     return {};
     174             :   }
     175             : 
     176             :   Local<Object> module_obj = Local<Object>::Cast(args[0]);
     177             :   return i::Handle<i::WasmModuleObject>::cast(
     178      144641 :       v8::Utils::OpenHandle(*module_obj));
     179             : }
     180             : 
     181      312569 : i::wasm::ModuleWireBytes GetFirstArgumentAsBytes(
     182      312567 :     const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower,
     183             :     bool* is_shared) {
     184             :   const uint8_t* start = nullptr;
     185             :   size_t length = 0;
     186             :   v8::Local<v8::Value> source = args[0];
     187      312569 :   if (source->IsArrayBuffer()) {
     188             :     // A raw array buffer was passed.
     189             :     Local<ArrayBuffer> buffer = Local<ArrayBuffer>::Cast(source);
     190      308795 :     ArrayBuffer::Contents contents = buffer->GetContents();
     191             : 
     192      308786 :     start = reinterpret_cast<const uint8_t*>(contents.Data());
     193      308786 :     length = contents.ByteLength();
     194      308786 :     *is_shared = buffer->IsSharedArrayBuffer();
     195        3789 :   } else if (source->IsTypedArray()) {
     196             :     // A TypedArray was passed.
     197             :     Local<TypedArray> array = Local<TypedArray>::Cast(source);
     198        3249 :     Local<ArrayBuffer> buffer = array->Buffer();
     199             : 
     200        3249 :     ArrayBuffer::Contents contents = buffer->GetContents();
     201             : 
     202             :     start =
     203        3249 :         reinterpret_cast<const uint8_t*>(contents.Data()) + array->ByteOffset();
     204        3249 :     length = array->ByteLength();
     205        3249 :     *is_shared = buffer->IsSharedArrayBuffer();
     206             :   } else {
     207         540 :     thrower->TypeError("Argument 0 must be a buffer source");
     208             :   }
     209             :   DCHECK_IMPLIES(length, start != nullptr);
     210      312567 :   if (length == 0) {
     211         864 :     thrower->CompileError("BufferSource argument is empty");
     212             :   }
     213      312567 :   if (length > i::wasm::kV8MaxWasmModuleSize) {
     214             :     thrower->RangeError("buffer source exceeds maximum size of %zu (is %zu)",
     215           0 :                         i::wasm::kV8MaxWasmModuleSize, length);
     216             :   }
     217      312567 :   if (thrower->error()) return i::wasm::ModuleWireBytes(nullptr, nullptr);
     218      623352 :   return i::wasm::ModuleWireBytes(start, start + length);
     219             : }
     220             : 
     221      147160 : i::MaybeHandle<i::JSReceiver> GetValueAsImports(Local<Value> arg,
     222             :                                                 ErrorThrower* thrower) {
     223      147160 :   if (arg->IsUndefined()) return {};
     224             : 
     225      139694 :   if (!arg->IsObject()) {
     226         270 :     thrower->TypeError("Argument 1 must be an object");
     227         270 :     return {};
     228             :   }
     229             :   Local<Object> obj = Local<Object>::Cast(arg);
     230      139428 :   return i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj));
     231             : }
     232             : 
     233             : namespace {
     234             : // This class resolves the result of WebAssembly.compile. It just places the
     235             : // compilation result in the supplied {promise}.
     236             : class AsyncCompilationResolver : public i::wasm::CompilationResultResolver {
     237             :  public:
     238        1608 :   AsyncCompilationResolver(i::Isolate* isolate, i::Handle<i::JSPromise> promise)
     239        1608 :       : promise_(isolate->global_handles()->Create(*promise)) {
     240             :     i::GlobalHandles::AnnotateStrongRetainer(promise_.location(),
     241         804 :                                              kGlobalPromiseHandle);
     242         804 :   }
     243             : 
     244         804 :   ~AsyncCompilationResolver() override {
     245         804 :     i::GlobalHandles::Destroy(promise_.location());
     246         804 :   }
     247             : 
     248         355 :   void OnCompilationSucceeded(i::Handle<i::WasmModuleObject> result) override {
     249         355 :     if (finished_) return;
     250         355 :     finished_ = true;
     251             :     i::MaybeHandle<i::Object> promise_result =
     252         355 :         i::JSPromise::Resolve(promise_, result);
     253         710 :     CHECK_EQ(promise_result.is_null(),
     254             :              promise_->GetIsolate()->has_pending_exception());
     255             :   }
     256             : 
     257         433 :   void OnCompilationFailed(i::Handle<i::Object> error_reason) override {
     258         866 :     if (finished_) return;
     259         433 :     finished_ = true;
     260             :     i::MaybeHandle<i::Object> promise_result =
     261         433 :         i::JSPromise::Reject(promise_, error_reason);
     262         866 :     CHECK_EQ(promise_result.is_null(),
     263             :              promise_->GetIsolate()->has_pending_exception());
     264             :   }
     265             : 
     266             :  private:
     267             :   static constexpr char kGlobalPromiseHandle[] =
     268             :       "AsyncCompilationResolver::promise_";
     269             :   bool finished_ = false;
     270             :   i::Handle<i::JSPromise> promise_;
     271             : };
     272             : 
     273             : constexpr char AsyncCompilationResolver::kGlobalPromiseHandle[];
     274             : 
     275             : // This class resolves the result of WebAssembly.instantiate(module, imports).
     276             : // It just places the instantiation result in the supplied {promise}.
     277             : class InstantiateModuleResultResolver
     278             :     : public i::wasm::InstantiationResultResolver {
     279             :  public:
     280       14400 :   InstantiateModuleResultResolver(i::Isolate* isolate,
     281             :                                   i::Handle<i::JSPromise> promise)
     282       14400 :       : promise_(isolate->global_handles()->Create(*promise)) {
     283             :     i::GlobalHandles::AnnotateStrongRetainer(promise_.location(),
     284        7200 :                                              kGlobalPromiseHandle);
     285        7200 :   }
     286             : 
     287        7200 :   ~InstantiateModuleResultResolver() override {
     288        7200 :     i::GlobalHandles::Destroy(promise_.location());
     289        7200 :   }
     290             : 
     291         108 :   void OnInstantiationSucceeded(
     292             :       i::Handle<i::WasmInstanceObject> instance) override {
     293             :     i::MaybeHandle<i::Object> promise_result =
     294         108 :         i::JSPromise::Resolve(promise_, instance);
     295         216 :     CHECK_EQ(promise_result.is_null(),
     296             :              promise_->GetIsolate()->has_pending_exception());
     297         108 :   }
     298             : 
     299        5121 :   void OnInstantiationFailed(i::Handle<i::Object> error_reason) override {
     300             :     i::MaybeHandle<i::Object> promise_result =
     301        5121 :         i::JSPromise::Reject(promise_, error_reason);
     302       10242 :     CHECK_EQ(promise_result.is_null(),
     303             :              promise_->GetIsolate()->has_pending_exception());
     304        5121 :   }
     305             : 
     306             :  private:
     307             :   static constexpr char kGlobalPromiseHandle[] =
     308             :       "InstantiateModuleResultResolver::promise_";
     309             :   i::Handle<i::JSPromise> promise_;
     310             : };
     311             : 
     312             : constexpr char InstantiateModuleResultResolver::kGlobalPromiseHandle[];
     313             : 
     314             : // This class resolves the result of WebAssembly.instantiate(bytes, imports).
     315             : // For that it creates a new {JSObject} which contains both the provided
     316             : // {WasmModuleObject} and the resulting {WebAssemblyInstanceObject} itself.
     317             : class InstantiateBytesResultResolver
     318             :     : public i::wasm::InstantiationResultResolver {
     319             :  public:
     320        1944 :   InstantiateBytesResultResolver(i::Isolate* isolate,
     321             :                                  i::Handle<i::JSPromise> promise,
     322             :                                  i::Handle<i::WasmModuleObject> module)
     323             :       : isolate_(isolate),
     324        3888 :         promise_(isolate_->global_handles()->Create(*promise)),
     325        7776 :         module_(isolate_->global_handles()->Create(*module)) {
     326             :     i::GlobalHandles::AnnotateStrongRetainer(promise_.location(),
     327        1944 :                                              kGlobalPromiseHandle);
     328             :     i::GlobalHandles::AnnotateStrongRetainer(module_.location(),
     329        1944 :                                              kGlobalModuleHandle);
     330        1944 :   }
     331             : 
     332        3888 :   ~InstantiateBytesResultResolver() override {
     333        1944 :     i::GlobalHandles::Destroy(promise_.location());
     334        1944 :     i::GlobalHandles::Destroy(module_.location());
     335        3888 :   }
     336             : 
     337        1305 :   void OnInstantiationSucceeded(
     338             :       i::Handle<i::WasmInstanceObject> instance) override {
     339             :     // The result is a JSObject with 2 fields which contain the
     340             :     // WasmInstanceObject and the WasmModuleObject.
     341             :     i::Handle<i::JSObject> result =
     342        1305 :         isolate_->factory()->NewJSObject(isolate_->object_function());
     343             : 
     344             :     i::Handle<i::String> instance_name =
     345             :         isolate_->factory()
     346        1305 :             ->NewStringFromOneByte(i::StaticCharVector("instance"))
     347        2610 :             .ToHandleChecked();
     348             : 
     349             :     i::Handle<i::String> module_name =
     350             :         isolate_->factory()
     351        1305 :             ->NewStringFromOneByte(i::StaticCharVector("module"))
     352        2610 :             .ToHandleChecked();
     353             : 
     354             :     i::JSObject::AddProperty(isolate_, result, instance_name, instance,
     355        1305 :                              i::NONE);
     356        1305 :     i::JSObject::AddProperty(isolate_, result, module_name, module_, i::NONE);
     357             : 
     358             :     i::MaybeHandle<i::Object> promise_result =
     359        1305 :         i::JSPromise::Resolve(promise_, result);
     360        2610 :     CHECK_EQ(promise_result.is_null(), isolate_->has_pending_exception());
     361        1305 :   }
     362             : 
     363         639 :   void OnInstantiationFailed(i::Handle<i::Object> error_reason) override {
     364             :     i::MaybeHandle<i::Object> promise_result =
     365         639 :         i::JSPromise::Reject(promise_, error_reason);
     366        1278 :     CHECK_EQ(promise_result.is_null(), isolate_->has_pending_exception());
     367         639 :   }
     368             : 
     369             :  private:
     370             :   static constexpr char kGlobalPromiseHandle[] =
     371             :       "InstantiateBytesResultResolver::promise_";
     372             :   static constexpr char kGlobalModuleHandle[] =
     373             :       "InstantiateBytesResultResolver::module_";
     374             :   i::Isolate* isolate_;
     375             :   i::Handle<i::JSPromise> promise_;
     376             :   i::Handle<i::WasmModuleObject> module_;
     377             : };
     378             : 
     379             : constexpr char InstantiateBytesResultResolver::kGlobalPromiseHandle[];
     380             : constexpr char InstantiateBytesResultResolver::kGlobalModuleHandle[];
     381             : 
     382             : // This class is the {CompilationResultResolver} for
     383             : // WebAssembly.instantiate(bytes, imports). When compilation finishes,
     384             : // {AsyncInstantiate} is started on the compilation result.
     385             : class AsyncInstantiateCompileResultResolver
     386             :     : public i::wasm::CompilationResultResolver {
     387             :  public:
     388        1971 :   AsyncInstantiateCompileResultResolver(
     389             :       i::Isolate* isolate, i::Handle<i::JSPromise> promise,
     390             :       i::MaybeHandle<i::JSReceiver> maybe_imports)
     391             :       : isolate_(isolate),
     392        2709 :         promise_(isolate_->global_handles()->Create(*promise)),
     393             :         maybe_imports_(maybe_imports.is_null()
     394             :                            ? maybe_imports
     395             :                            : isolate_->global_handles()->Create(
     396        4680 :                                  *maybe_imports.ToHandleChecked())) {
     397             :     i::GlobalHandles::AnnotateStrongRetainer(promise_.location(),
     398        1971 :                                              kGlobalPromiseHandle);
     399        1971 :     if (!maybe_imports_.is_null()) {
     400             :       i::GlobalHandles::AnnotateStrongRetainer(
     401         738 :           maybe_imports_.ToHandleChecked().location(), kGlobalImportsHandle);
     402             :     }
     403        1971 :   }
     404             : 
     405        3942 :   ~AsyncInstantiateCompileResultResolver() override {
     406        1971 :     i::GlobalHandles::Destroy(promise_.location());
     407        1971 :     if (!maybe_imports_.is_null()) {
     408         738 :       i::GlobalHandles::Destroy(maybe_imports_.ToHandleChecked().location());
     409             :     }
     410        3942 :   }
     411             : 
     412        1944 :   void OnCompilationSucceeded(i::Handle<i::WasmModuleObject> result) override {
     413        3888 :     if (finished_) return;
     414        1944 :     finished_ = true;
     415             :     isolate_->wasm_engine()->AsyncInstantiate(
     416             :         isolate_,
     417             :         base::make_unique<InstantiateBytesResultResolver>(isolate_, promise_,
     418             :                                                           result),
     419        9720 :         result, maybe_imports_);
     420             :   }
     421             : 
     422          27 :   void OnCompilationFailed(i::Handle<i::Object> error_reason) override {
     423          54 :     if (finished_) return;
     424          27 :     finished_ = true;
     425             :     i::MaybeHandle<i::Object> promise_result =
     426          27 :         i::JSPromise::Reject(promise_, error_reason);
     427          54 :     CHECK_EQ(promise_result.is_null(), isolate_->has_pending_exception());
     428             :   }
     429             : 
     430             :  private:
     431             :   static constexpr char kGlobalPromiseHandle[] =
     432             :       "AsyncInstantiateCompileResultResolver::promise_";
     433             :   static constexpr char kGlobalImportsHandle[] =
     434             :       "AsyncInstantiateCompileResultResolver::module_";
     435             :   bool finished_ = false;
     436             :   i::Isolate* isolate_;
     437             :   i::Handle<i::JSPromise> promise_;
     438             :   i::MaybeHandle<i::JSReceiver> maybe_imports_;
     439             : };
     440             : 
     441             : constexpr char AsyncInstantiateCompileResultResolver::kGlobalPromiseHandle[];
     442             : constexpr char AsyncInstantiateCompileResultResolver::kGlobalImportsHandle[];
     443             : 
     444         963 : std::string ToString(const char* name) { return std::string(name); }
     445             : 
     446         351 : std::string ToString(const i::Handle<i::String> name) {
     447        1755 :   return std::string("Property '") + name->ToCString().get() + "'";
     448             : }
     449             : 
     450             : // Web IDL: '[EnforceRange] unsigned long'
     451             : // Previously called ToNonWrappingUint32 in the draft WebAssembly JS spec.
     452             : // https://heycam.github.io/webidl/#EnforceRange
     453             : template <typename T>
     454       26188 : bool EnforceUint32(T argument_name, Local<v8::Value> v, Local<Context> context,
     455             :                    ErrorThrower* thrower, uint32_t* res) {
     456             :   double double_number;
     457             : 
     458       52376 :   if (!v->NumberValue(context).To(&double_number)) {
     459         144 :     thrower->TypeError("%s must be convertible to a number",
     460             :                        ToString(argument_name).c_str());
     461          63 :     return false;
     462             :   }
     463       26125 :   if (!std::isfinite(double_number)) {
     464        1278 :     thrower->TypeError("%s must be convertible to a valid number",
     465             :                        ToString(argument_name).c_str());
     466         585 :     return false;
     467             :   }
     468       25540 :   if (double_number < 0) {
     469         882 :     thrower->TypeError("%s must be non-negative",
     470             :                        ToString(argument_name).c_str());
     471         396 :     return false;
     472             :   }
     473       25144 :   if (double_number > std::numeric_limits<uint32_t>::max()) {
     474         675 :     thrower->TypeError("%s must be in the unsigned long range",
     475             :                        ToString(argument_name).c_str());
     476         270 :     return false;
     477             :   }
     478             : 
     479       24874 :   *res = static_cast<uint32_t>(double_number);
     480       24874 :   return true;
     481             : }
     482             : }  // namespace
     483             : 
     484             : // WebAssembly.compile(bytes) -> Promise
     485        1548 : void WebAssemblyCompile(const v8::FunctionCallbackInfo<v8::Value>& args) {
     486             :   v8::Isolate* isolate = args.GetIsolate();
     487             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
     488             : 
     489         774 :   HandleScope scope(isolate);
     490         513 :   ScheduledErrorThrower thrower(i_isolate, "WebAssembly.compile()");
     491             : 
     492        1548 :   if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) {
     493          27 :     thrower.CompileError("Wasm code generation disallowed by embedder");
     494             :   }
     495             : 
     496         774 :   Local<Context> context = isolate->GetCurrentContext();
     497        1809 :   ASSIGN(Promise::Resolver, promise_resolver, Promise::Resolver::New(context));
     498         774 :   Local<Promise> promise = promise_resolver->GetPromise();
     499             :   v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
     500             :   return_value.Set(promise);
     501             : 
     502             :   std::shared_ptr<i::wasm::CompilationResultResolver> resolver(
     503        1548 :       new AsyncCompilationResolver(i_isolate, Utils::OpenHandle(*promise)));
     504             : 
     505         774 :   bool is_shared = false;
     506         774 :   auto bytes = GetFirstArgumentAsBytes(args, &thrower, &is_shared);
     507         774 :   if (thrower.error()) {
     508         261 :     resolver->OnCompilationFailed(thrower.Reify());
     509             :     return;
     510             :   }
     511             :   // Asynchronous compilation handles copying wire bytes if necessary.
     512         513 :   auto enabled_features = i::wasm::WasmFeaturesFromIsolate(i_isolate);
     513             :   i_isolate->wasm_engine()->AsyncCompile(i_isolate, enabled_features,
     514        2052 :                                          std::move(resolver), bytes, is_shared);
     515             : }
     516             : 
     517             : // WebAssembly.compileStreaming(Promise<Response>) -> Promise
     518          30 : void WebAssemblyCompileStreaming(
     519          60 :     const v8::FunctionCallbackInfo<v8::Value>& args) {
     520             :   v8::Isolate* isolate = args.GetIsolate();
     521          30 :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
     522          30 :   HandleScope scope(isolate);
     523          90 :   ScheduledErrorThrower thrower(i_isolate, "WebAssembly.compile()");
     524          30 :   Local<Context> context = isolate->GetCurrentContext();
     525             : 
     526             :   // Create and assign the return value of this function.
     527          60 :   ASSIGN(Promise::Resolver, result_resolver, Promise::Resolver::New(context));
     528          30 :   Local<Promise> promise = result_resolver->GetPromise();
     529             :   v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
     530             :   return_value.Set(promise);
     531             : 
     532             :   // Prepare the CompilationResultResolver for the compilation.
     533             :   auto resolver = std::make_shared<AsyncCompilationResolver>(
     534          60 :       i_isolate, Utils::OpenHandle(*promise));
     535             : 
     536          60 :   if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) {
     537           0 :     thrower.CompileError("Wasm code generation disallowed by embedder");
     538           0 :     resolver->OnCompilationFailed(thrower.Reify());
     539           0 :     return;
     540             :   }
     541             : 
     542             :   // Allocate the streaming decoder in a Managed so we can pass it to the
     543             :   // embedder.
     544             :   i::Handle<i::Managed<WasmStreaming>> data =
     545             :       i::Managed<WasmStreaming>::Allocate(
     546             :           i_isolate, 0,
     547             :           base::make_unique<WasmStreaming::WasmStreamingImpl>(isolate,
     548          60 :                                                               resolver));
     549             : 
     550             :   DCHECK_NOT_NULL(i_isolate->wasm_streaming_callback());
     551          90 :   ASSIGN(
     552             :       v8::Function, compile_callback,
     553             :       v8::Function::New(context, i_isolate->wasm_streaming_callback(),
     554             :                         Utils::ToLocal(i::Handle<i::Object>::cast(data)), 1));
     555             : 
     556             :   // The parameter may be of type {Response} or of type {Promise<Response>}.
     557             :   // Treat either case of parameter as Promise.resolve(parameter)
     558             :   // as per https://www.w3.org/2001/tag/doc/promises-guide#resolve-arguments
     559             : 
     560             :   // Ending with:
     561             :   //    return Promise.resolve(parameter).then(compile_callback);
     562          60 :   ASSIGN(Promise::Resolver, input_resolver, Promise::Resolver::New(context));
     563          30 :   if (!input_resolver->Resolve(context, args[0]).IsJust()) return;
     564             : 
     565             :   // We do not have any use of the result here. The {compile_callback} will
     566             :   // start streaming compilation, which will eventually resolve the promise we
     567             :   // set as result value.
     568          90 :   USE(input_resolver->GetPromise()->Then(context, compile_callback));
     569             : }
     570             : 
     571             : // WebAssembly.validate(bytes) -> bool
     572      284940 : void WebAssemblyValidate(const v8::FunctionCallbackInfo<v8::Value>& args) {
     573             :   v8::Isolate* isolate = args.GetIsolate();
     574             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
     575      142470 :   HandleScope scope(isolate);
     576      142254 :   ScheduledErrorThrower thrower(i_isolate, "WebAssembly.validate()");
     577             : 
     578      142470 :   bool is_shared = false;
     579      142470 :   auto bytes = GetFirstArgumentAsBytes(args, &thrower, &is_shared);
     580             : 
     581             :   v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
     582             : 
     583      142470 :   if (thrower.error()) {
     584         216 :     if (thrower.wasm_error()) thrower.Reset();  // Clear error.
     585             :     return_value.Set(v8::False(isolate));
     586      142686 :     return;
     587             :   }
     588             : 
     589      142254 :   auto enabled_features = i::wasm::WasmFeaturesFromIsolate(i_isolate);
     590             :   bool validated = false;
     591      142254 :   if (is_shared) {
     592             :     // Make a copy of the wire bytes to avoid concurrent modification.
     593           0 :     std::unique_ptr<uint8_t[]> copy(new uint8_t[bytes.length()]);
     594             :     memcpy(copy.get(), bytes.start(), bytes.length());
     595             :     i::wasm::ModuleWireBytes bytes_copy(copy.get(),
     596           0 :                                         copy.get() + bytes.length());
     597             :     validated = i_isolate->wasm_engine()->SyncValidate(
     598           0 :         i_isolate, enabled_features, bytes_copy);
     599             :   } else {
     600             :     // The wire bytes are not shared, OK to use them directly.
     601             :     validated = i_isolate->wasm_engine()->SyncValidate(i_isolate,
     602      142254 :                                                        enabled_features, bytes);
     603             :   }
     604             : 
     605      142254 :   return_value.Set(Boolean::New(isolate, validated));
     606             : }
     607             : 
     608             : // new WebAssembly.Module(bytes) -> WebAssembly.Module
     609      317401 : void WebAssemblyModule(const v8::FunctionCallbackInfo<v8::Value>& args) {
     610             :   v8::Isolate* isolate = args.GetIsolate();
     611      167300 :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
     612      184508 :   if (i_isolate->wasm_module_callback()(args)) return;
     613             : 
     614      167297 :   HandleScope scope(isolate);
     615      150101 :   ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Module()");
     616             : 
     617      167305 :   if (!args.IsConstructCall()) {
     618          27 :     thrower.TypeError("WebAssembly.Module must be invoked with 'new'");
     619          27 :     return;
     620             :   }
     621      334555 :   if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) {
     622          27 :     thrower.CompileError("Wasm code generation disallowed by embedder");
     623          27 :     return;
     624             :   }
     625             : 
     626      167238 :   bool is_shared = false;
     627      167238 :   auto bytes = GetFirstArgumentAsBytes(args, &thrower, &is_shared);
     628             : 
     629      167239 :   if (thrower.error()) {
     630             :     return;
     631             :   }
     632      166950 :   auto enabled_features = i::wasm::WasmFeaturesFromIsolate(i_isolate);
     633             :   i::MaybeHandle<i::Object> module_obj;
     634      166952 :   if (is_shared) {
     635             :     // Make a copy of the wire bytes to avoid concurrent modification.
     636           0 :     std::unique_ptr<uint8_t[]> copy(new uint8_t[bytes.length()]);
     637             :     memcpy(copy.get(), bytes.start(), bytes.length());
     638             :     i::wasm::ModuleWireBytes bytes_copy(copy.get(),
     639           0 :                                         copy.get() + bytes.length());
     640             :     module_obj = i_isolate->wasm_engine()->SyncCompile(
     641           0 :         i_isolate, enabled_features, &thrower, bytes_copy);
     642             :   } else {
     643             :     // The wire bytes are not shared, OK to use them directly.
     644             :     module_obj = i_isolate->wasm_engine()->SyncCompile(
     645      166952 :         i_isolate, enabled_features, &thrower, bytes);
     646             :   }
     647             : 
     648      166950 :   if (module_obj.is_null()) return;
     649             : 
     650             :   v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
     651      150104 :   return_value.Set(Utils::ToLocal(module_obj.ToHandleChecked()));
     652             : }
     653             : 
     654             : // WebAssembly.Module.imports(module) -> Array<Import>
     655         720 : void WebAssemblyModuleImports(const v8::FunctionCallbackInfo<v8::Value>& args) {
     656         279 :   HandleScope scope(args.GetIsolate());
     657             :   v8::Isolate* isolate = args.GetIsolate();
     658             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
     659         162 :   ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Module.imports()");
     660             : 
     661         279 :   auto maybe_module = GetFirstArgumentAsModule(args, &thrower);
     662         396 :   if (thrower.error()) return;
     663         162 :   auto imports = i::wasm::GetImports(i_isolate, maybe_module.ToHandleChecked());
     664         162 :   args.GetReturnValue().Set(Utils::ToLocal(imports));
     665             : }
     666             : 
     667             : // WebAssembly.Module.exports(module) -> Array<Export>
     668         693 : void WebAssemblyModuleExports(const v8::FunctionCallbackInfo<v8::Value>& args) {
     669         270 :   HandleScope scope(args.GetIsolate());
     670             :   v8::Isolate* isolate = args.GetIsolate();
     671             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
     672         153 :   ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Module.exports()");
     673             : 
     674         270 :   auto maybe_module = GetFirstArgumentAsModule(args, &thrower);
     675         387 :   if (thrower.error()) return;
     676         153 :   auto exports = i::wasm::GetExports(i_isolate, maybe_module.ToHandleChecked());
     677         153 :   args.GetReturnValue().Set(Utils::ToLocal(exports));
     678             : }
     679             : 
     680             : // WebAssembly.Module.customSections(module, name) -> Array<Section>
     681          99 : void WebAssemblyModuleCustomSections(
     682         252 :     const v8::FunctionCallbackInfo<v8::Value>& args) {
     683          99 :   HandleScope scope(args.GetIsolate());
     684             :   v8::Isolate* isolate = args.GetIsolate();
     685             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
     686             :   ScheduledErrorThrower thrower(i_isolate,
     687          54 :                                 "WebAssembly.Module.customSections()");
     688             : 
     689          99 :   auto maybe_module = GetFirstArgumentAsModule(args, &thrower);
     690         144 :   if (thrower.error()) return;
     691             : 
     692             :   i::MaybeHandle<i::Object> maybe_name =
     693          63 :       i::Object::ToString(i_isolate, Utils::OpenHandle(*args[1]));
     694             :   i::Handle<i::Object> name;
     695          63 :   if (!maybe_name.ToHandle(&name)) return;
     696             :   auto custom_sections =
     697             :       i::wasm::GetCustomSections(i_isolate, maybe_module.ToHandleChecked(),
     698         108 :                                  i::Handle<i::String>::cast(name), &thrower);
     699          54 :   if (thrower.error()) return;
     700          54 :   args.GetReturnValue().Set(Utils::ToLocal(custom_sections));
     701             : }
     702             : 
     703      144263 : MaybeLocal<Value> WebAssemblyInstantiateImpl(Isolate* isolate,
     704             :                                              Local<Value> module,
     705             :                                              Local<Value> ffi) {
     706             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
     707             : 
     708             :   i::MaybeHandle<i::Object> instance_object;
     709             :   {
     710             :     ScheduledErrorThrower thrower(i_isolate, "WebAssembly Instantiation");
     711             : 
     712             :     // TODO(ahaas): These checks on the module should not be necessary here They
     713             :     // are just a workaround for https://crbug.com/837417.
     714             :     i::Handle<i::Object> module_obj = Utils::OpenHandle(*module);
     715      288529 :     if (!module_obj->IsWasmModuleObject()) {
     716           0 :       thrower.TypeError("Argument 0 must be a WebAssembly.Module object");
     717           0 :       return {};
     718             :     }
     719             : 
     720             :     i::MaybeHandle<i::JSReceiver> maybe_imports =
     721      144265 :         GetValueAsImports(ffi, &thrower);
     722      144267 :     if (thrower.error()) return {};
     723             : 
     724             :     instance_object = i_isolate->wasm_engine()->SyncInstantiate(
     725             :         i_isolate, &thrower, i::Handle<i::WasmModuleObject>::cast(module_obj),
     726      288354 :         maybe_imports, i::MaybeHandle<i::JSArrayBuffer>());
     727             :   }
     728             : 
     729             :   DCHECK_EQ(instance_object.is_null(), i_isolate->has_scheduled_exception());
     730      144178 :   if (instance_object.is_null()) return {};
     731      142324 :   return Utils::ToLocal(instance_object.ToHandleChecked());
     732             : }
     733             : 
     734             : // new WebAssembly.Instance(module, imports) -> WebAssembly.Instance
     735      431238 : void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) {
     736             :   Isolate* isolate = args.GetIsolate();
     737      144453 :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
     738             :   i_isolate->CountUsage(
     739      144453 :       v8::Isolate::UseCounterFeature::kWebAssemblyInstantiation);
     740             : 
     741      144461 :   HandleScope scope(args.GetIsolate());
     742      144651 :   if (i_isolate->wasm_instance_callback()(args)) return;
     743             : 
     744      144268 :   ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Instance()");
     745      144446 :   if (!args.IsConstructCall()) {
     746          27 :     thrower.TypeError("WebAssembly.Instance must be invoked with 'new'");
     747          27 :     return;
     748             :   }
     749             : 
     750      144419 :   GetFirstArgumentAsModule(args, &thrower);
     751      144425 :   if (thrower.error()) return;
     752             : 
     753             :   // If args.Length < 2, this will be undefined - see FunctionCallbackInfo.
     754             :   // We'll check for that in WebAssemblyInstantiateImpl.
     755      144263 :   Local<Value> data = args[1];
     756             : 
     757             :   Local<Value> instance;
     758      288531 :   if (WebAssemblyInstantiateImpl(isolate, args[0], data).ToLocal(&instance)) {
     759             :     args.GetReturnValue().Set(instance);
     760      144268 :   }
     761             : }
     762             : 
     763           0 : void WebAssemblyInstantiateStreaming(
     764           0 :     const v8::FunctionCallbackInfo<v8::Value>& args) {
     765           0 :   v8::Isolate* isolate = args.GetIsolate();
     766           0 :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
     767             :   i_isolate->CountUsage(
     768           0 :       v8::Isolate::UseCounterFeature::kWebAssemblyInstantiation);
     769             : 
     770           0 :   HandleScope scope(isolate);
     771           0 :   Local<Context> context = isolate->GetCurrentContext();
     772             :   ScheduledErrorThrower thrower(i_isolate,
     773           0 :                                 "WebAssembly.instantiateStreaming()");
     774             : 
     775             :   // Create and assign the return value of this function.
     776           0 :   ASSIGN(Promise::Resolver, result_resolver, Promise::Resolver::New(context));
     777           0 :   Local<Promise> promise = result_resolver->GetPromise();
     778             :   v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
     779             :   return_value.Set(promise);
     780             : 
     781             :   // Create an InstantiateResultResolver in case there is an issue with the
     782             :   // passed parameters.
     783             :   std::unique_ptr<i::wasm::InstantiationResultResolver> resolver(
     784             :       new InstantiateModuleResultResolver(i_isolate,
     785           0 :                                           Utils::OpenHandle(*promise)));
     786             : 
     787           0 :   if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) {
     788           0 :     thrower.CompileError("Wasm code generation disallowed by embedder");
     789           0 :     resolver->OnInstantiationFailed(thrower.Reify());
     790           0 :     return;
     791             :   }
     792             : 
     793             :   // If args.Length < 2, this will be undefined - see FunctionCallbackInfo.
     794           0 :   Local<Value> ffi = args[1];
     795             :   i::MaybeHandle<i::JSReceiver> maybe_imports =
     796           0 :       GetValueAsImports(ffi, &thrower);
     797             : 
     798           0 :   if (thrower.error()) {
     799           0 :     resolver->OnInstantiationFailed(thrower.Reify());
     800           0 :     return;
     801             :   }
     802             : 
     803             :   // We start compilation now, we have no use for the
     804             :   // {InstantiationResultResolver}.
     805             :   resolver.reset();
     806             : 
     807             :   std::shared_ptr<i::wasm::CompilationResultResolver> compilation_resolver(
     808             :       new AsyncInstantiateCompileResultResolver(
     809           0 :           i_isolate, Utils::OpenHandle(*promise), maybe_imports));
     810             : 
     811             :   // Allocate the streaming decoder in a Managed so we can pass it to the
     812             :   // embedder.
     813             :   i::Handle<i::Managed<WasmStreaming>> data =
     814             :       i::Managed<WasmStreaming>::Allocate(
     815             :           i_isolate, 0,
     816             :           base::make_unique<WasmStreaming::WasmStreamingImpl>(
     817           0 :               isolate, compilation_resolver));
     818             : 
     819             :   DCHECK_NOT_NULL(i_isolate->wasm_streaming_callback());
     820           0 :   ASSIGN(
     821             :       v8::Function, compile_callback,
     822             :       v8::Function::New(context, i_isolate->wasm_streaming_callback(),
     823             :                         Utils::ToLocal(i::Handle<i::Object>::cast(data)), 1));
     824             : 
     825             :   // The parameter may be of type {Response} or of type {Promise<Response>}.
     826             :   // Treat either case of parameter as Promise.resolve(parameter)
     827             :   // as per https://www.w3.org/2001/tag/doc/promises-guide#resolve-arguments
     828             : 
     829             :   // Ending with:
     830             :   //    return Promise.resolve(parameter).then(compile_callback);
     831           0 :   ASSIGN(Promise::Resolver, input_resolver, Promise::Resolver::New(context));
     832           0 :   if (!input_resolver->Resolve(context, args[0]).IsJust()) return;
     833             : 
     834             :   // We do not have any use of the result here. The {compile_callback} will
     835             :   // start streaming compilation, which will eventually resolve the promise we
     836             :   // set as result value.
     837           0 :   USE(input_resolver->GetPromise()->Then(context, compile_callback));
     838             : }
     839             : 
     840             : // WebAssembly.instantiate(module, imports) -> WebAssembly.Instance
     841             : // WebAssembly.instantiate(bytes, imports) ->
     842             : //     {module: WebAssembly.Module, instance: WebAssembly.Instance}
     843       14400 : void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) {
     844             :   v8::Isolate* isolate = args.GetIsolate();
     845             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
     846             :   i_isolate->CountUsage(
     847        7200 :       v8::Isolate::UseCounterFeature::kWebAssemblyInstantiation);
     848             : 
     849             :   ScheduledErrorThrower thrower(i_isolate, "WebAssembly Instantiation");
     850             : 
     851        9144 :   HandleScope scope(isolate);
     852             : 
     853        7200 :   Local<Context> context = isolate->GetCurrentContext();
     854             : 
     855       19656 :   ASSIGN(Promise::Resolver, promise_resolver, Promise::Resolver::New(context));
     856        7200 :   Local<Promise> promise = promise_resolver->GetPromise();
     857             :   args.GetReturnValue().Set(promise);
     858             : 
     859             :   std::unique_ptr<i::wasm::InstantiationResultResolver> resolver(
     860             :       new InstantiateModuleResultResolver(i_isolate,
     861        7200 :                                           Utils::OpenHandle(*promise)));
     862             : 
     863             :   Local<Value> first_arg_value = args[0];
     864             :   i::Handle<i::Object> first_arg = Utils::OpenHandle(*first_arg_value);
     865       14400 :   if (!first_arg->IsJSObject()) {
     866             :     thrower.TypeError(
     867        4302 :         "Argument 0 must be a buffer source or a WebAssembly.Module object");
     868        4302 :     resolver->OnInstantiationFailed(thrower.Reify());
     869        4302 :     return;
     870             :   }
     871             : 
     872             :   // If args.Length < 2, this will be undefined - see FunctionCallbackInfo.
     873        2898 :   Local<Value> ffi = args[1];
     874             :   i::MaybeHandle<i::JSReceiver> maybe_imports =
     875        2898 :       GetValueAsImports(ffi, &thrower);
     876             : 
     877        2898 :   if (thrower.error()) {
     878         180 :     resolver->OnInstantiationFailed(thrower.Reify());
     879         180 :     return;
     880             :   }
     881             : 
     882        5436 :   if (first_arg->IsWasmModuleObject()) {
     883             :     i::Handle<i::WasmModuleObject> module_obj =
     884         630 :         i::Handle<i::WasmModuleObject>::cast(first_arg);
     885             : 
     886             :     i_isolate->wasm_engine()->AsyncInstantiate(i_isolate, std::move(resolver),
     887        1260 :                                                module_obj, maybe_imports);
     888             :     return;
     889             :   }
     890             : 
     891        2088 :   bool is_shared = false;
     892        2088 :   auto bytes = GetFirstArgumentAsBytes(args, &thrower, &is_shared);
     893        2088 :   if (thrower.error()) {
     894         117 :     resolver->OnInstantiationFailed(thrower.Reify());
     895         117 :     return;
     896             :   }
     897             : 
     898             :   // We start compilation now, we have no use for the
     899             :   // {InstantiationResultResolver}.
     900             :   resolver.reset();
     901             : 
     902             :   std::shared_ptr<i::wasm::CompilationResultResolver> compilation_resolver(
     903             :       new AsyncInstantiateCompileResultResolver(
     904        3942 :           i_isolate, Utils::OpenHandle(*promise), maybe_imports));
     905             : 
     906             :   // The first parameter is a buffer source, we have to check if we are allowed
     907             :   // to compile it.
     908        3942 :   if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) {
     909          27 :     thrower.CompileError("Wasm code generation disallowed by embedder");
     910          27 :     compilation_resolver->OnCompilationFailed(thrower.Reify());
     911             :     return;
     912             :   }
     913             : 
     914             :   // Asynchronous compilation handles copying wire bytes if necessary.
     915        1944 :   auto enabled_features = i::wasm::WasmFeaturesFromIsolate(i_isolate);
     916             :   i_isolate->wasm_engine()->AsyncCompile(i_isolate, enabled_features,
     917             :                                          std::move(compilation_resolver), bytes,
     918        7776 :                                          is_shared);
     919             : }
     920             : 
     921        9331 : bool GetIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower,
     922             :                         Local<Context> context, v8::Local<v8::Value> value,
     923             :                         i::Handle<i::String> property_name, int64_t* result,
     924             :                         int64_t lower_bound, uint64_t upper_bound) {
     925             :   uint32_t number;
     926        9331 :   if (!EnforceUint32(property_name, value, context, thrower, &number)) {
     927             :     return false;
     928             :   }
     929        8980 :   if (number < lower_bound) {
     930             :     thrower->RangeError("Property '%s': value %" PRIu32
     931             :                         " is below the lower bound %" PRIx64,
     932         162 :                         property_name->ToCString().get(), number, lower_bound);
     933             :     return false;
     934             :   }
     935        8926 :   if (number > upper_bound) {
     936             :     thrower->RangeError("Property '%s': value %" PRIu32
     937             :                         " is above the upper bound %" PRIu64,
     938         108 :                         property_name->ToCString().get(), number, upper_bound);
     939             :     return false;
     940             :   }
     941             : 
     942        8890 :   *result = static_cast<int64_t>(number);
     943             :   return true;
     944             : }
     945             : 
     946        6946 : bool GetRequiredIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower,
     947             :                                 Local<Context> context,
     948             :                                 Local<v8::Object> object,
     949             :                                 Local<String> property, int64_t* result,
     950             :                                 int64_t lower_bound, uint64_t upper_bound) {
     951             :   v8::Local<v8::Value> value;
     952       13892 :   if (!object->Get(context, property).ToLocal(&value)) {
     953             :     return false;
     954             :   }
     955             : 
     956             :   i::Handle<i::String> property_name = v8::Utils::OpenHandle(*property);
     957             : 
     958             :   // Web IDL: dictionary presence
     959             :   // https://heycam.github.io/webidl/#dfn-present
     960        6946 :   if (value->IsUndefined()) {
     961             :     thrower->TypeError("Property '%s' is required",
     962         108 :                        property_name->ToCString().get());
     963             :     return false;
     964             :   }
     965             : 
     966             :   return GetIntegerProperty(isolate, thrower, context, value, property_name,
     967        6910 :                             result, lower_bound, upper_bound);
     968             : }
     969             : 
     970        6685 : bool GetOptionalIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower,
     971             :                                 Local<Context> context,
     972             :                                 Local<v8::Object> object,
     973             :                                 Local<String> property, int64_t* result,
     974             :                                 int64_t lower_bound, uint64_t upper_bound) {
     975             :   v8::Local<v8::Value> value;
     976       13370 :   if (!object->Get(context, property).ToLocal(&value)) {
     977             :     return false;
     978             :   }
     979             : 
     980             :   // Web IDL: dictionary presence
     981             :   // https://heycam.github.io/webidl/#dfn-present
     982        6685 :   if (value->IsUndefined()) {
     983             :     return true;
     984             :   }
     985             : 
     986        2421 :   i::Handle<i::String> property_name = v8::Utils::OpenHandle(*property);
     987             : 
     988             :   return GetIntegerProperty(isolate, thrower, context, value, property_name,
     989        2421 :                             result, lower_bound, upper_bound);
     990             : }
     991             : 
     992             : // new WebAssembly.Table(args) -> WebAssembly.Table
     993        4077 : void WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) {
     994             :   v8::Isolate* isolate = args.GetIsolate();
     995             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
     996        2277 :   HandleScope scope(isolate);
     997        1800 :   ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Module()");
     998        2277 :   if (!args.IsConstructCall()) {
     999          27 :     thrower.TypeError("WebAssembly.Table must be invoked with 'new'");
    1000          27 :     return;
    1001             :   }
    1002        2250 :   if (!args[0]->IsObject()) {
    1003         135 :     thrower.TypeError("Argument 0 must be a table descriptor");
    1004         135 :     return;
    1005             :   }
    1006        2115 :   Local<Context> context = isolate->GetCurrentContext();
    1007             :   Local<v8::Object> descriptor = Local<Object>::Cast(args[0]);
    1008             :   // The descriptor's 'element'.
    1009             :   {
    1010             :     v8::MaybeLocal<v8::Value> maybe =
    1011        2115 :         descriptor->Get(context, v8_str(isolate, "element"));
    1012             :     v8::Local<v8::Value> value;
    1013        2115 :     if (!maybe.ToLocal(&value)) return;
    1014             :     v8::Local<v8::String> string;
    1015        4230 :     if (!value->ToString(context).ToLocal(&string)) return;
    1016        2115 :     if (!string->StringEquals(v8_str(isolate, "anyfunc"))) {
    1017          99 :       thrower.TypeError("Descriptor property 'element' must be 'anyfunc'");
    1018          99 :       return;
    1019             :     }
    1020             :   }
    1021             :   // The descriptor's 'initial'.
    1022        2016 :   int64_t initial = 0;
    1023        2016 :   if (!GetRequiredIntegerProperty(isolate, &thrower, context, descriptor,
    1024             :                                   v8_str(isolate, "initial"), &initial, 0,
    1025        4032 :                                   i::FLAG_wasm_max_table_size)) {
    1026             :     return;
    1027             :   }
    1028             :   // The descriptor's 'maximum'.
    1029        1908 :   int64_t maximum = -1;
    1030        1908 :   if (!GetOptionalIntegerProperty(isolate, &thrower, context, descriptor,
    1031             :                                   v8_str(isolate, "maximum"), &maximum, initial,
    1032        3816 :                                   i::wasm::kSpecMaxWasmTableSize)) {
    1033             :     return;
    1034             :   }
    1035             : 
    1036             :   i::Handle<i::FixedArray> fixed_array;
    1037             :   i::Handle<i::JSObject> table_obj =
    1038             :       i::WasmTableObject::New(i_isolate, static_cast<uint32_t>(initial),
    1039        1800 :                               static_cast<uint32_t>(maximum), &fixed_array);
    1040             :   v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
    1041        1800 :   return_value.Set(Utils::ToLocal(table_obj));
    1042             : }
    1043             : 
    1044        9752 : void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) {
    1045             :   v8::Isolate* isolate = args.GetIsolate();
    1046             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
    1047        5092 :   HandleScope scope(isolate);
    1048        4660 :   ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Memory()");
    1049        5092 :   if (!args.IsConstructCall()) {
    1050          27 :     thrower.TypeError("WebAssembly.Memory must be invoked with 'new'");
    1051          27 :     return;
    1052             :   }
    1053        5065 :   if (!args[0]->IsObject()) {
    1054         135 :     thrower.TypeError("Argument 0 must be a memory descriptor");
    1055         135 :     return;
    1056             :   }
    1057        4930 :   Local<Context> context = isolate->GetCurrentContext();
    1058             :   Local<v8::Object> descriptor = Local<Object>::Cast(args[0]);
    1059             :   // The descriptor's 'initial'.
    1060        4930 :   int64_t initial = 0;
    1061        4930 :   if (!GetRequiredIntegerProperty(isolate, &thrower, context, descriptor,
    1062             :                                   v8_str(isolate, "initial"), &initial, 0,
    1063        9860 :                                   i::wasm::max_mem_pages())) {
    1064             :     return;
    1065             :   }
    1066             :   // The descriptor's 'maximum'.
    1067        4777 :   int64_t maximum = -1;
    1068        4777 :   if (!GetOptionalIntegerProperty(isolate, &thrower, context, descriptor,
    1069             :                                   v8_str(isolate, "maximum"), &maximum, initial,
    1070        9554 :                                   i::wasm::kSpecMaxWasmMemoryPages)) {
    1071             :     return;
    1072             :   }
    1073             : 
    1074             :   bool is_shared_memory = false;
    1075        4669 :   auto enabled_features = i::wasm::WasmFeaturesFromIsolate(i_isolate);
    1076        4669 :   if (enabled_features.threads) {
    1077             :     // Shared property of descriptor
    1078             :     Local<String> shared_key = v8_str(isolate, "shared");
    1079         261 :     Maybe<bool> has_shared = descriptor->Has(context, shared_key);
    1080         522 :     if (!has_shared.IsNothing() && has_shared.FromJust()) {
    1081         252 :       v8::MaybeLocal<v8::Value> maybe = descriptor->Get(context, shared_key);
    1082             :       v8::Local<v8::Value> value;
    1083         252 :       if (maybe.ToLocal(&value)) {
    1084         252 :         is_shared_memory = value->BooleanValue(isolate);
    1085             :       }
    1086             :     }
    1087             :     // Throw TypeError if shared is true, and the descriptor has no "maximum"
    1088         261 :     if (is_shared_memory && maximum == -1) {
    1089             :       thrower.TypeError(
    1090           9 :           "If shared is true, maximum property should be defined.");
    1091             :     }
    1092             :   }
    1093             : 
    1094             :   i::SharedFlag shared_flag =
    1095        4669 :       is_shared_memory ? i::SharedFlag::kShared : i::SharedFlag::kNotShared;
    1096             :   i::Handle<i::JSArrayBuffer> buffer;
    1097        4669 :   size_t size = static_cast<size_t>(i::wasm::kWasmPageSize) *
    1098        4669 :                 static_cast<size_t>(initial);
    1099        4669 :   if (!i::wasm::NewArrayBuffer(i_isolate, size, shared_flag)
    1100        9338 :            .ToHandle(&buffer)) {
    1101           9 :     thrower.RangeError("could not allocate memory");
    1102           9 :     return;
    1103             :   }
    1104        4660 :   if (buffer->is_shared()) {
    1105             :     Maybe<bool> result =
    1106         225 :         buffer->SetIntegrityLevel(buffer, i::FROZEN, i::kDontThrow);
    1107         225 :     if (!result.FromJust()) {
    1108             :       thrower.TypeError(
    1109           0 :           "Status of setting SetIntegrityLevel of buffer is false.");
    1110             :     }
    1111             :   }
    1112             :   i::Handle<i::JSObject> memory_obj = i::WasmMemoryObject::New(
    1113        9320 :       i_isolate, buffer, static_cast<uint32_t>(maximum));
    1114        4660 :   args.GetReturnValue().Set(Utils::ToLocal(memory_obj));
    1115             : }
    1116             : 
    1117       16074 : void WebAssemblyGlobal(const v8::FunctionCallbackInfo<v8::Value>& args) {
    1118             :   v8::Isolate* isolate = args.GetIsolate();
    1119             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
    1120        8172 :   HandleScope scope(isolate);
    1121        7902 :   ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Global()");
    1122        8172 :   if (!args.IsConstructCall()) {
    1123           9 :     thrower.TypeError("WebAssembly.Global must be invoked with 'new'");
    1124           9 :     return;
    1125             :   }
    1126        8163 :   if (!args[0]->IsObject()) {
    1127         117 :     thrower.TypeError("Argument 0 must be a global descriptor");
    1128         117 :     return;
    1129             :   }
    1130        8046 :   Local<Context> context = isolate->GetCurrentContext();
    1131             :   Local<v8::Object> descriptor = Local<Object>::Cast(args[0]);
    1132             : 
    1133             :   // The descriptor's 'mutable'.
    1134             :   bool is_mutable = false;
    1135             :   {
    1136             :     Local<String> mutable_key = v8_str(isolate, "mutable");
    1137        8046 :     v8::MaybeLocal<v8::Value> maybe = descriptor->Get(context, mutable_key);
    1138             :     v8::Local<v8::Value> value;
    1139        8046 :     if (maybe.ToLocal(&value)) {
    1140        8046 :       is_mutable = value->BooleanValue(isolate);
    1141             :     }
    1142             :   }
    1143             : 
    1144             :   // The descriptor's type, called 'value'. It is called 'value' because this
    1145             :   // descriptor is planned to be re-used as the global's type for reflection,
    1146             :   // so calling it 'type' is redundant.
    1147             :   i::wasm::ValueType type;
    1148             :   {
    1149             :     v8::MaybeLocal<v8::Value> maybe =
    1150        8046 :         descriptor->Get(context, v8_str(isolate, "value"));
    1151             :     v8::Local<v8::Value> value;
    1152        8046 :     if (!maybe.ToLocal(&value)) return;
    1153             :     v8::Local<v8::String> string;
    1154       16092 :     if (!value->ToString(context).ToLocal(&string)) return;
    1155             : 
    1156        8046 :     if (string->StringEquals(v8_str(isolate, "i32"))) {
    1157             :       type = i::wasm::kWasmI32;
    1158        5157 :     } else if (string->StringEquals(v8_str(isolate, "f32"))) {
    1159             :       type = i::wasm::kWasmF32;
    1160        1863 :     } else if (string->StringEquals(v8_str(isolate, "i64"))) {
    1161             :       type = i::wasm::kWasmI64;
    1162        1764 :     } else if (string->StringEquals(v8_str(isolate, "f64"))) {
    1163             :       type = i::wasm::kWasmF64;
    1164         243 :     } else if (string->StringEquals(v8_str(isolate, "anyref"))) {
    1165             :       type = i::wasm::kWasmAnyRef;
    1166             :     } else {
    1167             :       thrower.TypeError(
    1168             :           "Descriptor property 'value' must be 'i32', 'i64', 'f32', or "
    1169         117 :           "'f64'");
    1170         117 :       return;
    1171             :     }
    1172             :   }
    1173             : 
    1174             :   const uint32_t offset = 0;
    1175             :   i::MaybeHandle<i::WasmGlobalObject> maybe_global_obj =
    1176             :       i::WasmGlobalObject::New(i_isolate, i::MaybeHandle<i::JSArrayBuffer>(),
    1177             :                                i::MaybeHandle<i::FixedArray>(), type, offset,
    1178        7929 :                                is_mutable);
    1179             : 
    1180             :   i::Handle<i::WasmGlobalObject> global_obj;
    1181        7929 :   if (!maybe_global_obj.ToHandle(&global_obj)) {
    1182           0 :     thrower.RangeError("could not allocate memory");
    1183           0 :     return;
    1184             :   }
    1185             : 
    1186             :   // Convert value to a WebAssembly value, the default value is 0.
    1187             :   Local<v8::Value> value = Local<Value>::Cast(args[1]);
    1188        7929 :   switch (type) {
    1189             :     case i::wasm::kWasmI32: {
    1190             :       int32_t i32_value = 0;
    1191        2889 :       if (!value->IsUndefined()) {
    1192             :         v8::Local<v8::Int32> int32_value;
    1193        5436 :         if (!value->ToInt32(context).ToLocal(&int32_value)) return;
    1194        5436 :         if (!int32_value->Int32Value(context).To(&i32_value)) return;
    1195             :       }
    1196        5778 :       global_obj->SetI32(i32_value);
    1197             :       break;
    1198             :     }
    1199             :     case i::wasm::kWasmI64: {
    1200             :       int64_t i64_value = 0;
    1201          99 :       if (!value->IsUndefined()) {
    1202          54 :         auto enabled_features = i::wasm::WasmFeaturesFromIsolate(i_isolate);
    1203          54 :         if (!enabled_features.bigint) {
    1204          18 :           thrower.TypeError("Can't set the value of i64 WebAssembly.Global");
    1205          18 :           return;
    1206             :         }
    1207             : 
    1208             :         v8::Local<v8::BigInt> bigint_value;
    1209          72 :         if (!value->ToBigInt(context).ToLocal(&bigint_value)) return;
    1210          27 :         i64_value = bigint_value->Int64Value();
    1211             :       }
    1212         144 :       global_obj->SetI64(i64_value);
    1213          72 :       break;
    1214             :     }
    1215             :     case i::wasm::kWasmF32: {
    1216             :       float f32_value = 0;
    1217        3294 :       if (!value->IsUndefined()) {
    1218             :         double f64_value = 0;
    1219             :         v8::Local<v8::Number> number_value;
    1220        6300 :         if (!value->ToNumber(context).ToLocal(&number_value)) return;
    1221        6300 :         if (!number_value->NumberValue(context).To(&f64_value)) return;
    1222        3150 :         f32_value = static_cast<float>(f64_value);
    1223             :       }
    1224        6588 :       global_obj->SetF32(f32_value);
    1225        3294 :       break;
    1226             :     }
    1227             :     case i::wasm::kWasmF64: {
    1228             :       double f64_value = 0;
    1229        1521 :       if (!value->IsUndefined()) {
    1230             :         v8::Local<v8::Number> number_value;
    1231        2754 :         if (!value->ToNumber(context).ToLocal(&number_value)) return;
    1232        2754 :         if (!number_value->NumberValue(context).To(&f64_value)) return;
    1233             :       }
    1234        3042 :       global_obj->SetF64(f64_value);
    1235             :       break;
    1236             :     }
    1237             :     case i::wasm::kWasmAnyRef: {
    1238         126 :       if (args.Length() < 2) {
    1239             :         // When no inital value is provided, we have to use the WebAssembly
    1240             :         // default value 'null', and not the JS default value 'undefined'.
    1241             :         global_obj->SetAnyRef(
    1242          18 :             handle(i::ReadOnlyRoots(i_isolate).null_value(), i_isolate));
    1243          18 :         break;
    1244             :       }
    1245         108 :       global_obj->SetAnyRef(Utils::OpenHandle(*value));
    1246         108 :       break;
    1247             :     }
    1248             :     default:
    1249           0 :       UNREACHABLE();
    1250             :   }
    1251             : 
    1252             :   i::Handle<i::JSObject> global_js_object(global_obj);
    1253        7902 :   args.GetReturnValue().Set(Utils::ToLocal(global_js_object));
    1254             : }
    1255             : 
    1256             : // WebAssembly.Exception
    1257           9 : void WebAssemblyException(const v8::FunctionCallbackInfo<v8::Value>& args) {
    1258             :   v8::Isolate* isolate = args.GetIsolate();
    1259             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
    1260           9 :   HandleScope scope(isolate);
    1261           9 :   ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Excepion()");
    1262          18 :   thrower.TypeError("WebAssembly.Exception cannot be called");
    1263           9 : }
    1264             : 
    1265             : constexpr const char* kName_WasmGlobalObject = "WebAssembly.Global";
    1266             : constexpr const char* kName_WasmMemoryObject = "WebAssembly.Memory";
    1267             : constexpr const char* kName_WasmInstanceObject = "WebAssembly.Instance";
    1268             : constexpr const char* kName_WasmTableObject = "WebAssembly.Table";
    1269             : 
    1270             : #define EXTRACT_THIS(var, WasmType)                                  \
    1271             :   i::Handle<i::WasmType> var;                                        \
    1272             :   {                                                                  \
    1273             :     i::Handle<i::Object> this_arg = Utils::OpenHandle(*args.This()); \
    1274             :     if (!this_arg->Is##WasmType()) {                                 \
    1275             :       thrower.TypeError("Receiver is not a %s", kName_##WasmType);   \
    1276             :       return;                                                        \
    1277             :     }                                                                \
    1278             :     var = i::Handle<i::WasmType>::cast(this_arg);                    \
    1279             :   }
    1280             : 
    1281    23654933 : void WebAssemblyInstanceGetExports(
    1282    70964700 :   const v8::FunctionCallbackInfo<v8::Value>& args) {
    1283             :   v8::Isolate* isolate = args.GetIsolate();
    1284             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
    1285    23654933 :   HandleScope scope(isolate);
    1286    23654834 :   ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Instance.exports()");
    1287    70964798 :   EXTRACT_THIS(receiver, WasmInstanceObject);
    1288    47309668 :   i::Handle<i::JSObject> exports_object(receiver->exports_object(), i_isolate);
    1289    23654834 :   args.GetReturnValue().Set(Utils::ToLocal(exports_object));
    1290             : }
    1291             : 
    1292        9009 : void WebAssemblyTableGetLength(
    1293       26901 :     const v8::FunctionCallbackInfo<v8::Value>& args) {
    1294             :   v8::Isolate* isolate = args.GetIsolate();
    1295             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
    1296        9009 :   HandleScope scope(isolate);
    1297        8883 :   ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Table.length()");
    1298       27027 :   EXTRACT_THIS(receiver, WasmTableObject);
    1299             :   args.GetReturnValue().Set(
    1300       26649 :       v8::Number::New(isolate, receiver->current_length()));
    1301             : }
    1302             : 
    1303             : // WebAssembly.Table.grow(num) -> num
    1304        2160 : void WebAssemblyTableGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
    1305             :   v8::Isolate* isolate = args.GetIsolate();
    1306             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
    1307         837 :   HandleScope scope(isolate);
    1308         486 :   ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Table.grow()");
    1309         837 :   Local<Context> context = isolate->GetCurrentContext();
    1310        1674 :   EXTRACT_THIS(receiver, WasmTableObject);
    1311             : 
    1312             :   uint32_t grow_by;
    1313         729 :   if (!EnforceUint32("Argument 0", args[0], context, &thrower, &grow_by)) {
    1314             :     return;
    1315             :   }
    1316             : 
    1317        1116 :   i::Handle<i::FixedArray> old_array(receiver->functions(), i_isolate);
    1318         558 :   uint32_t old_size = static_cast<uint32_t>(old_array->length());
    1319             : 
    1320         558 :   uint64_t max_size64 = receiver->maximum_length()->Number();
    1321         558 :   if (max_size64 > i::FLAG_wasm_max_table_size) {
    1322             :     max_size64 = i::FLAG_wasm_max_table_size;
    1323             :   }
    1324             : 
    1325             :   DCHECK_LE(max_size64, std::numeric_limits<uint32_t>::max());
    1326             : 
    1327             :   uint64_t new_size64 =
    1328         558 :       static_cast<uint64_t>(old_size) + static_cast<uint64_t>(grow_by);
    1329         558 :   if (new_size64 > max_size64) {
    1330          72 :     thrower.RangeError("maximum table size exceeded");
    1331          72 :     return;
    1332             :   }
    1333         486 :   uint32_t new_size = static_cast<uint32_t>(new_size64);
    1334             : 
    1335         486 :   if (new_size != old_size) {
    1336         900 :     receiver->Grow(i_isolate, new_size - old_size);
    1337             : 
    1338             :     i::Handle<i::FixedArray> new_array =
    1339         450 :         i_isolate->factory()->NewFixedArray(new_size);
    1340     5398713 :     for (uint32_t i = 0; i < old_size; ++i) {
    1341    10796526 :       new_array->set(i, old_array->get(i));
    1342             :     }
    1343         450 :     i::Object null = i::ReadOnlyRoots(i_isolate).null_value();
    1344    95957352 :     for (uint32_t i = old_size; i < new_size; ++i) new_array->set(i, null);
    1345         450 :     receiver->set_functions(*new_array);
    1346             :   }
    1347             : 
    1348             :   // TODO(gdeepti): use weak links for instances
    1349             :   v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
    1350         486 :   return_value.Set(old_size);
    1351             : }
    1352             : 
    1353             : // WebAssembly.Table.get(num) -> JSFunction
    1354       35109 : void WebAssemblyTableGet(const v8::FunctionCallbackInfo<v8::Value>& args) {
    1355             :   v8::Isolate* isolate = args.GetIsolate();
    1356             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
    1357       11916 :   HandleScope scope(isolate);
    1358       10791 :   ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Table.get()");
    1359       11916 :   Local<Context> context = isolate->GetCurrentContext();
    1360       23832 :   EXTRACT_THIS(receiver, WasmTableObject);
    1361       23616 :   i::Handle<i::FixedArray> array(receiver->functions(), i_isolate);
    1362             : 
    1363             :   uint32_t index;
    1364       11808 :   if (!EnforceUint32("Argument 0", args[0], context, &thrower, &index)) {
    1365             :     return;
    1366             :   }
    1367             : 
    1368             :   v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
    1369       11277 :   if (index >= static_cast<uint32_t>(array->length())) {
    1370         486 :     thrower.RangeError("Index out of bounds");
    1371         486 :     return;
    1372             :   }
    1373             : 
    1374       10791 :   i::Handle<i::Object> value(array->get(static_cast<int>(index)), i_isolate);
    1375       10791 :   return_value.Set(Utils::ToLocal(value));
    1376             : }
    1377             : 
    1378             : // WebAssembly.Table.set(num, JSFunction)
    1379        8874 : void WebAssemblyTableSet(const v8::FunctionCallbackInfo<v8::Value>& args) {
    1380             :   v8::Isolate* isolate = args.GetIsolate();
    1381             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
    1382        4437 :   HandleScope scope(isolate);
    1383        3420 :   ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Table.set()");
    1384        4437 :   Local<Context> context = isolate->GetCurrentContext();
    1385        8874 :   EXTRACT_THIS(receiver, WasmTableObject);
    1386             : 
    1387             :   // Parameter 0.
    1388             :   uint32_t index;
    1389        4320 :   if (!EnforceUint32("Argument 0", args[0], context, &thrower, &index)) {
    1390             :     return;
    1391             :   }
    1392             : 
    1393             :   // Parameter 1.
    1394             :   i::Handle<i::Object> value = Utils::OpenHandle(*args[1]);
    1395       10791 :   if (!value->IsNull(i_isolate) &&
    1396        2673 :       !i::WasmExportedFunction::IsWasmExportedFunction(*value)) {
    1397         279 :     thrower.TypeError("Argument 1 must be null or a WebAssembly function");
    1398         279 :     return;
    1399             :   }
    1400             : 
    1401       11340 :   if (index >= static_cast<uint64_t>(receiver->functions()->length())) {
    1402         360 :     thrower.RangeError("index out of bounds");
    1403         360 :     return;
    1404             :   }
    1405             : 
    1406             :   i::WasmTableObject::Set(i_isolate, receiver, index,
    1407        6840 :                           value->IsNull(i_isolate)
    1408             :                               ? i::Handle<i::JSFunction>::null()
    1409        6840 :                               : i::Handle<i::JSFunction>::cast(value));
    1410             : }
    1411             : 
    1412             : // WebAssembly.Memory.grow(num) -> num
    1413        1368 : void WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
    1414             :   v8::Isolate* isolate = args.GetIsolate();
    1415             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
    1416         504 :   HandleScope scope(isolate);
    1417         360 :   ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Memory.grow()");
    1418         504 :   Local<Context> context = isolate->GetCurrentContext();
    1419        1008 :   EXTRACT_THIS(receiver, WasmMemoryObject);
    1420             : 
    1421             :   int64_t delta_size = 0;
    1422         972 :   if (!args[0]->IntegerValue(context).To(&delta_size)) return;
    1423             : 
    1424         477 :   int64_t max_size64 = receiver->maximum_pages();
    1425         477 :   if (max_size64 < 0 || max_size64 > int64_t{i::wasm::max_mem_pages()}) {
    1426         171 :     max_size64 = i::wasm::max_mem_pages();
    1427             :   }
    1428         954 :   i::Handle<i::JSArrayBuffer> old_buffer(receiver->array_buffer(), i_isolate);
    1429         477 :   if (!old_buffer->is_growable()) {
    1430           9 :     thrower.RangeError("This memory cannot be grown");
    1431           9 :     return;
    1432             :   }
    1433         468 :   int64_t old_size = old_buffer->byte_length() / i::wasm::kWasmPageSize;
    1434             :   int64_t new_size64 = base::AddWithWraparound(old_size, delta_size);
    1435         468 :   if (delta_size < 0 || max_size64 < new_size64 || new_size64 < old_size) {
    1436             :     thrower.RangeError(new_size64 < old_size ? "trying to shrink memory"
    1437         108 :                                              : "maximum memory size exceeded");
    1438         108 :     return;
    1439             :   }
    1440             :   int32_t ret = i::WasmMemoryObject::Grow(i_isolate, receiver,
    1441         360 :                                           static_cast<uint32_t>(delta_size));
    1442         360 :   if (ret == -1) {
    1443           0 :     thrower.RangeError("Unable to grow instance memory.");
    1444           0 :     return;
    1445             :   }
    1446             :   v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
    1447         360 :   return_value.Set(ret);
    1448             : }
    1449             : 
    1450             : // WebAssembly.Memory.buffer -> ArrayBuffer
    1451        7782 : void WebAssemblyMemoryGetBuffer(
    1452       23220 :     const v8::FunctionCallbackInfo<v8::Value>& args) {
    1453             :   v8::Isolate* isolate = args.GetIsolate();
    1454             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
    1455        7782 :   HandleScope scope(isolate);
    1456        7656 :   ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Memory.buffer");
    1457       23346 :   EXTRACT_THIS(receiver, WasmMemoryObject);
    1458             : 
    1459       15312 :   i::Handle<i::Object> buffer_obj(receiver->array_buffer(), i_isolate);
    1460             :   DCHECK(buffer_obj->IsJSArrayBuffer());
    1461             :   i::Handle<i::JSArrayBuffer> buffer(i::JSArrayBuffer::cast(*buffer_obj),
    1462             :                                      i_isolate);
    1463        7656 :   if (buffer->is_shared()) {
    1464             :     // TODO(gdeepti): More needed here for when cached buffer, and current
    1465             :     // buffer are out of sync, handle that here when bounds checks, and Grow
    1466             :     // are handled correctly.
    1467             :     Maybe<bool> result =
    1468        5226 :         buffer->SetIntegrityLevel(buffer, i::FROZEN, i::kDontThrow);
    1469        5226 :     if (!result.FromJust()) {
    1470             :       thrower.TypeError(
    1471           0 :           "Status of setting SetIntegrityLevel of buffer is false.");
    1472             :     }
    1473             :   }
    1474             :   v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
    1475        7656 :   return_value.Set(Utils::ToLocal(buffer));
    1476             : }
    1477             : 
    1478       10197 : void WebAssemblyGlobalGetValueCommon(
    1479       30411 :     const v8::FunctionCallbackInfo<v8::Value>& args, const char* name) {
    1480             :   v8::Isolate* isolate = args.GetIsolate();
    1481             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
    1482       10197 :   HandleScope scope(isolate);
    1483       10017 :   ScheduledErrorThrower thrower(i_isolate, name);
    1484       30591 :   EXTRACT_THIS(receiver, WasmGlobalObject);
    1485             : 
    1486             :   v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
    1487             : 
    1488       10017 :   switch (receiver->type()) {
    1489             :     case i::wasm::kWasmI32:
    1490        7866 :       return_value.Set(receiver->GetI32());
    1491        3933 :       break;
    1492             :     case i::wasm::kWasmI64: {
    1493         126 :       auto enabled_features = i::wasm::WasmFeaturesFromIsolate(i_isolate);
    1494         126 :       if (enabled_features.bigint) {
    1495         162 :         Local<BigInt> value = BigInt::New(isolate, receiver->GetI64());
    1496             : 
    1497             :         return_value.Set(value);
    1498             :       } else {
    1499          45 :         thrower.TypeError("Can't get the value of i64 WebAssembly.Global");
    1500             :       }
    1501             :       break;
    1502             :     }
    1503             :     case i::wasm::kWasmF32:
    1504       11097 :       return_value.Set(receiver->GetF32());
    1505        3699 :       break;
    1506             :     case i::wasm::kWasmF64:
    1507        3942 :       return_value.Set(receiver->GetF64());
    1508        1971 :       break;
    1509             :     case i::wasm::kWasmAnyRef:
    1510         576 :       return_value.Set(Utils::ToLocal(receiver->GetAnyRef()));
    1511         288 :       break;
    1512             :     default:
    1513           0 :       UNREACHABLE();
    1514       10017 :   }
    1515             : }
    1516             : 
    1517             : // WebAssembly.Global.valueOf() -> num
    1518        3582 : void WebAssemblyGlobalValueOf(const v8::FunctionCallbackInfo<v8::Value>& args) {
    1519        3582 :   return WebAssemblyGlobalGetValueCommon(args, "WebAssembly.Global.valueOf()");
    1520             : }
    1521             : 
    1522             : // get WebAssembly.Global.value -> num
    1523        6615 : void WebAssemblyGlobalGetValue(
    1524             :     const v8::FunctionCallbackInfo<v8::Value>& args) {
    1525        6615 :   return WebAssemblyGlobalGetValueCommon(args, "get WebAssembly.Global.value");
    1526             : }
    1527             : 
    1528             : // set WebAssembly.Global.value(num)
    1529        3150 : void WebAssemblyGlobalSetValue(
    1530        6300 :     const v8::FunctionCallbackInfo<v8::Value>& args) {
    1531             :   v8::Isolate* isolate = args.GetIsolate();
    1532             :   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
    1533        3150 :   HandleScope scope(isolate);
    1534        3150 :   Local<Context> context = isolate->GetCurrentContext();
    1535        2799 :   ScheduledErrorThrower thrower(i_isolate, "set WebAssembly.Global.value");
    1536        6300 :   EXTRACT_THIS(receiver, WasmGlobalObject);
    1537             : 
    1538        3069 :   if (!receiver->is_mutable()) {
    1539         243 :     thrower.TypeError("Can't set the value of an immutable global.");
    1540         243 :     return;
    1541             :   }
    1542        2826 :   if (args[0]->IsUndefined()) {
    1543          18 :     thrower.TypeError("Argument 0: must be a value");
    1544          18 :     return;
    1545             :   }
    1546             : 
    1547        2808 :   switch (receiver->type()) {
    1548             :     case i::wasm::kWasmI32: {
    1549             :       int32_t i32_value = 0;
    1550        2250 :       if (!args[0]->Int32Value(context).To(&i32_value)) return;
    1551        2250 :       receiver->SetI32(i32_value);
    1552             :       break;
    1553             :     }
    1554             :     case i::wasm::kWasmI64: {
    1555          36 :       auto enabled_features = i::wasm::WasmFeaturesFromIsolate(i_isolate);
    1556          36 :       if (enabled_features.bigint) {
    1557             :         v8::Local<v8::BigInt> bigint_value;
    1558          54 :         if (!args[0]->ToBigInt(context).ToLocal(&bigint_value)) return;
    1559          54 :         receiver->SetI64(bigint_value->Int64Value());
    1560             :       } else {
    1561           9 :         thrower.TypeError("Can't set the value of i64 WebAssembly.Global");
    1562             :       }
    1563          27 :       break;
    1564             :     }
    1565             :     case i::wasm::kWasmF32: {
    1566             :       double f64_value = 0;
    1567        2178 :       if (!args[0]->NumberValue(context).To(&f64_value)) return;
    1568        3267 :       receiver->SetF32(static_cast<float>(f64_value));
    1569             :       break;
    1570             :     }
    1571             :     case i::wasm::kWasmF64: {
    1572             :       double f64_value = 0;
    1573         990 :       if (!args[0]->NumberValue(context).To(&f64_value)) return;
    1574         990 :       receiver->SetF64(f64_value);
    1575             :       break;
    1576             :     }
    1577             :     case i::wasm::kWasmAnyRef: {
    1578          63 :       receiver->SetAnyRef(Utils::OpenHandle(*args[0]));
    1579          63 :       break;
    1580             :     }
    1581             :     default:
    1582           0 :       UNREACHABLE();
    1583        2799 :   }
    1584             : }
    1585             : 
    1586             : }  // namespace
    1587             : 
    1588             : // TODO(titzer): we use the API to create the function template because the
    1589             : // internal guts are too ugly to replicate here.
    1590     1922799 : static i::Handle<i::FunctionTemplateInfo> NewFunctionTemplate(
    1591             :     i::Isolate* i_isolate, FunctionCallback func) {
    1592             :   Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate);
    1593     1922799 :   Local<FunctionTemplate> templ = FunctionTemplate::New(isolate, func);
    1594     1922804 :   templ->ReadOnlyPrototype();
    1595     1922804 :   return v8::Utils::OpenHandle(*templ);
    1596             : }
    1597             : 
    1598             : static i::Handle<i::ObjectTemplateInfo> NewObjectTemplate(
    1599             :     i::Isolate* i_isolate) {
    1600             :   Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate);
    1601      457864 :   Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
    1602             :   return v8::Utils::OpenHandle(*templ);
    1603             : }
    1604             : 
    1605             : namespace internal {
    1606             : 
    1607     1922799 : Handle<JSFunction> CreateFunc(Isolate* isolate, Handle<String> name,
    1608             :                               FunctionCallback func) {
    1609     1922799 :   Handle<FunctionTemplateInfo> temp = NewFunctionTemplate(isolate, func);
    1610             :   Handle<JSFunction> function =
    1611     3845602 :       ApiNatives::InstantiateFunction(temp, name).ToHandleChecked();
    1612             :   DCHECK(function->shared()->HasSharedName());
    1613     1922798 :   return function;
    1614             : }
    1615             : 
    1616     1465028 : Handle<JSFunction> InstallFunc(Isolate* isolate, Handle<JSObject> object,
    1617             :                                const char* str, FunctionCallback func,
    1618             :                                int length = 0,
    1619             :                                PropertyAttributes attributes = NONE) {
    1620             :   Handle<String> name = v8_str(isolate, str);
    1621     1465028 :   Handle<JSFunction> function = CreateFunc(isolate, name, func);
    1622     2930054 :   function->shared()->set_length(length);
    1623     1465027 :   JSObject::AddProperty(isolate, object, name, function, attributes);
    1624     1465028 :   return function;
    1625             : }
    1626             : 
    1627           0 : Handle<JSFunction> InstallConstructorFunc(Isolate* isolate,
    1628             :                                          Handle<JSObject> object,
    1629             :                                          const char* str,
    1630             :                                          FunctionCallback func) {
    1631      457863 :   return InstallFunc(isolate, object, str, func, 1, DONT_ENUM);
    1632             : }
    1633             : 
    1634      366218 : Handle<String> GetterName(Isolate* isolate, Handle<String> name) {
    1635      366218 :   return Name::ToFunctionName(isolate, name, isolate->factory()->get_string())
    1636     1098654 :       .ToHandleChecked();
    1637             : }
    1638             : 
    1639      274664 : void InstallGetter(Isolate* isolate, Handle<JSObject> object, const char* str,
    1640             :                    FunctionCallback func) {
    1641             :   Handle<String> name = v8_str(isolate, str);
    1642             :   Handle<JSFunction> function =
    1643      274665 :       CreateFunc(isolate, GetterName(isolate, name), func);
    1644             : 
    1645             :   Utils::ToLocal(object)->SetAccessorProperty(Utils::ToLocal(name),
    1646             :                                               Utils::ToLocal(function),
    1647      274665 :                                               Local<Function>(), v8::None);
    1648      274665 : }
    1649             : 
    1650       91555 : Handle<String> SetterName(Isolate* isolate, Handle<String> name) {
    1651       91555 :   return Name::ToFunctionName(isolate, name, isolate->factory()->set_string())
    1652      274665 :       .ToHandleChecked();
    1653             : }
    1654             : 
    1655       91553 : void InstallGetterSetter(Isolate* isolate, Handle<JSObject> object,
    1656             :                          const char* str, FunctionCallback getter,
    1657             :                          FunctionCallback setter) {
    1658             :   Handle<String> name = v8_str(isolate, str);
    1659             :   Handle<JSFunction> getter_func =
    1660       91554 :       CreateFunc(isolate, GetterName(isolate, name), getter);
    1661             :   Handle<JSFunction> setter_func =
    1662       91555 :       CreateFunc(isolate, SetterName(isolate, name), setter);
    1663      183110 :   setter_func->shared()->set_length(1);
    1664             : 
    1665             :   v8::PropertyAttribute attributes = v8::None;
    1666             : 
    1667             :   Utils::ToLocal(object)->SetAccessorProperty(
    1668             :       Utils::ToLocal(name), Utils::ToLocal(getter_func),
    1669       91555 :       Utils::ToLocal(setter_func), attributes);
    1670       91555 : }
    1671             : 
    1672             : // Assigns a dummy instance template to the given constructor function. Used to
    1673             : // make sure the implicit receivers for the constructors in this file have an
    1674             : // instance type different from the internal one, they allocate the resulting
    1675             : // object explicitly and ignore implicit receiver.
    1676      457864 : void SetDummyInstanceTemplate(Isolate* isolate, Handle<JSFunction> fun) {
    1677             :   Handle<ObjectTemplateInfo> instance_template = NewObjectTemplate(isolate);
    1678             :   FunctionTemplateInfo::SetInstanceTemplate(
    1679      915729 :       isolate, handle(fun->shared()->get_api_func_data(), isolate),
    1680     1373594 :       instance_template);
    1681      457864 : }
    1682             : 
    1683             : // static
    1684     1550281 : void WasmJs::Install(Isolate* isolate, bool exposed_on_global_object) {
    1685     1458726 :   Handle<JSGlobalObject> global = isolate->global_object();
    1686     2917452 :   Handle<Context> context(global->native_context(), isolate);
    1687             :   // Install the JS API once only.
    1688     2917452 :   Object prev = context->get(Context::WASM_MODULE_CONSTRUCTOR_INDEX);
    1689     1458726 :   if (!prev->IsUndefined(isolate)) {
    1690             :     DCHECK(prev->IsJSFunction());
    1691     1367171 :     return;
    1692             :   }
    1693             : 
    1694             :   Factory* factory = isolate->factory();
    1695             : 
    1696             :   // Setup WebAssembly
    1697             :   Handle<String> name = v8_str(isolate, "WebAssembly");
    1698             :   NewFunctionArgs args = NewFunctionArgs::ForFunctionWithoutCode(
    1699       91555 :       name, isolate->strict_function_map(), LanguageMode::kStrict);
    1700       91555 :   Handle<JSFunction> cons = factory->NewFunction(args);
    1701      183110 :   JSFunction::SetPrototype(cons, isolate->initial_object_prototype());
    1702       91555 :   Handle<JSObject> webassembly = factory->NewJSObject(cons, TENURED);
    1703             : 
    1704             :   PropertyAttributes ro_attributes =
    1705             :       static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
    1706             :   JSObject::AddProperty(isolate, webassembly, factory->to_string_tag_symbol(),
    1707       91554 :                         name, ro_attributes);
    1708       91555 :   InstallFunc(isolate, webassembly, "compile", WebAssemblyCompile, 1);
    1709       91555 :   InstallFunc(isolate, webassembly, "validate", WebAssemblyValidate, 1);
    1710       91554 :   InstallFunc(isolate, webassembly, "instantiate", WebAssemblyInstantiate, 1);
    1711             : 
    1712       91555 :   if (isolate->wasm_streaming_callback() != nullptr) {
    1713             :     InstallFunc(isolate, webassembly, "compileStreaming",
    1714          30 :                 WebAssemblyCompileStreaming, 1);
    1715             :     InstallFunc(isolate, webassembly, "instantiateStreaming",
    1716          30 :                 WebAssemblyInstantiateStreaming, 1);
    1717             :   }
    1718             : 
    1719             :   // Expose the API on the global object if configured to do so.
    1720       91555 :   if (exposed_on_global_object) {
    1721       91528 :     JSObject::AddProperty(isolate, global, name, webassembly, DONT_ENUM);
    1722             :   }
    1723             : 
    1724             :   // Setup Module
    1725             :   Handle<JSFunction> module_constructor =
    1726             :       InstallConstructorFunc(isolate, webassembly, "Module", WebAssemblyModule);
    1727       91555 :   context->set_wasm_module_constructor(*module_constructor);
    1728       91555 :   SetDummyInstanceTemplate(isolate, module_constructor);
    1729       91555 :   JSFunction::EnsureHasInitialMap(module_constructor);
    1730             :   Handle<JSObject> module_proto(
    1731      183109 :       JSObject::cast(module_constructor->instance_prototype()), isolate);
    1732             :   i::Handle<i::Map> module_map =
    1733       91554 :       isolate->factory()->NewMap(i::WASM_MODULE_TYPE, WasmModuleObject::kSize);
    1734       91555 :   JSFunction::SetInitialMap(module_constructor, module_map, module_proto);
    1735             :   InstallFunc(isolate, module_constructor, "imports", WebAssemblyModuleImports,
    1736       91555 :               1);
    1737             :   InstallFunc(isolate, module_constructor, "exports", WebAssemblyModuleExports,
    1738       91555 :               1);
    1739             :   InstallFunc(isolate, module_constructor, "customSections",
    1740       91555 :               WebAssemblyModuleCustomSections, 2);
    1741             :   JSObject::AddProperty(isolate, module_proto, factory->to_string_tag_symbol(),
    1742       91555 :                         v8_str(isolate, "WebAssembly.Module"), ro_attributes);
    1743             : 
    1744             :   // Setup Instance
    1745             :   Handle<JSFunction> instance_constructor = InstallConstructorFunc(
    1746             :       isolate, webassembly, "Instance", WebAssemblyInstance);
    1747       91555 :   context->set_wasm_instance_constructor(*instance_constructor);
    1748       91555 :   SetDummyInstanceTemplate(isolate, instance_constructor);
    1749       91555 :   JSFunction::EnsureHasInitialMap(instance_constructor);
    1750             :   Handle<JSObject> instance_proto(
    1751      183110 :       JSObject::cast(instance_constructor->instance_prototype()), isolate);
    1752             :   i::Handle<i::Map> instance_map = isolate->factory()->NewMap(
    1753       91555 :       i::WASM_INSTANCE_TYPE, WasmInstanceObject::kSize);
    1754       91555 :   JSFunction::SetInitialMap(instance_constructor, instance_map, instance_proto);
    1755             :   InstallGetter(isolate, instance_proto, "exports",
    1756       91555 :                 WebAssemblyInstanceGetExports);
    1757             :   JSObject::AddProperty(isolate, instance_proto,
    1758             :                         factory->to_string_tag_symbol(),
    1759       91555 :                         v8_str(isolate, "WebAssembly.Instance"), ro_attributes);
    1760             : 
    1761             :   // Setup Table
    1762             :   Handle<JSFunction> table_constructor =
    1763             :       InstallConstructorFunc(isolate, webassembly, "Table", WebAssemblyTable);
    1764       91555 :   context->set_wasm_table_constructor(*table_constructor);
    1765       91555 :   SetDummyInstanceTemplate(isolate, table_constructor);
    1766       91555 :   JSFunction::EnsureHasInitialMap(table_constructor);
    1767             :   Handle<JSObject> table_proto(
    1768      183110 :       JSObject::cast(table_constructor->instance_prototype()), isolate);
    1769             :   i::Handle<i::Map> table_map =
    1770       91555 :       isolate->factory()->NewMap(i::WASM_TABLE_TYPE, WasmTableObject::kSize);
    1771       91555 :   JSFunction::SetInitialMap(table_constructor, table_map, table_proto);
    1772       91555 :   InstallGetter(isolate, table_proto, "length", WebAssemblyTableGetLength);
    1773       91555 :   InstallFunc(isolate, table_proto, "grow", WebAssemblyTableGrow, 1);
    1774       91555 :   InstallFunc(isolate, table_proto, "get", WebAssemblyTableGet, 1);
    1775       91555 :   InstallFunc(isolate, table_proto, "set", WebAssemblyTableSet, 2);
    1776             :   JSObject::AddProperty(isolate, table_proto, factory->to_string_tag_symbol(),
    1777       91555 :                         v8_str(isolate, "WebAssembly.Table"), ro_attributes);
    1778             : 
    1779             :   // Setup Memory
    1780             :   Handle<JSFunction> memory_constructor =
    1781             :       InstallConstructorFunc(isolate, webassembly, "Memory", WebAssemblyMemory);
    1782       91555 :   context->set_wasm_memory_constructor(*memory_constructor);
    1783       91555 :   SetDummyInstanceTemplate(isolate, memory_constructor);
    1784       91555 :   JSFunction::EnsureHasInitialMap(memory_constructor);
    1785             :   Handle<JSObject> memory_proto(
    1786      183110 :       JSObject::cast(memory_constructor->instance_prototype()), isolate);
    1787             :   i::Handle<i::Map> memory_map =
    1788       91555 :       isolate->factory()->NewMap(i::WASM_MEMORY_TYPE, WasmMemoryObject::kSize);
    1789       91555 :   JSFunction::SetInitialMap(memory_constructor, memory_map, memory_proto);
    1790       91555 :   InstallFunc(isolate, memory_proto, "grow", WebAssemblyMemoryGrow, 1);
    1791       91554 :   InstallGetter(isolate, memory_proto, "buffer", WebAssemblyMemoryGetBuffer);
    1792             :   JSObject::AddProperty(isolate, memory_proto, factory->to_string_tag_symbol(),
    1793       91555 :                         v8_str(isolate, "WebAssembly.Memory"), ro_attributes);
    1794             : 
    1795             :   // The context is not set up completely yet. That's why we cannot use
    1796             :   // {WasmFeaturesFromIsolate} and have to use {WasmFeaturesFromFlags} instead.
    1797       91555 :   auto enabled_features = i::wasm::WasmFeaturesFromFlags();
    1798             : 
    1799             :   // Setup Global
    1800             :   Handle<JSFunction> global_constructor =
    1801             :       InstallConstructorFunc(isolate, webassembly, "Global", WebAssemblyGlobal);
    1802       91555 :   context->set_wasm_global_constructor(*global_constructor);
    1803       91555 :   SetDummyInstanceTemplate(isolate, global_constructor);
    1804       91554 :   JSFunction::EnsureHasInitialMap(global_constructor);
    1805             :   Handle<JSObject> global_proto(
    1806      183109 :       JSObject::cast(global_constructor->instance_prototype()), isolate);
    1807             :   i::Handle<i::Map> global_map =
    1808       91554 :       isolate->factory()->NewMap(i::WASM_GLOBAL_TYPE, WasmGlobalObject::kSize);
    1809       91555 :   JSFunction::SetInitialMap(global_constructor, global_map, global_proto);
    1810       91555 :   InstallFunc(isolate, global_proto, "valueOf", WebAssemblyGlobalValueOf, 0);
    1811             :   InstallGetterSetter(isolate, global_proto, "value", WebAssemblyGlobalGetValue,
    1812       91554 :                       WebAssemblyGlobalSetValue);
    1813             :   JSObject::AddProperty(isolate, global_proto, factory->to_string_tag_symbol(),
    1814       91555 :                         v8_str(isolate, "WebAssembly.Global"), ro_attributes);
    1815             : 
    1816             :   // Setup Exception
    1817       91555 :   if (enabled_features.eh) {
    1818             :     Handle<JSFunction> exception_constructor = InstallConstructorFunc(
    1819             :         isolate, webassembly, "Exception", WebAssemblyException);
    1820          90 :     context->set_wasm_exception_constructor(*exception_constructor);
    1821          90 :     SetDummyInstanceTemplate(isolate, exception_constructor);
    1822          90 :     JSFunction::EnsureHasInitialMap(exception_constructor);
    1823             :     Handle<JSObject> exception_proto(
    1824         180 :         JSObject::cast(exception_constructor->instance_prototype()), isolate);
    1825             :     i::Handle<i::Map> exception_map = isolate->factory()->NewMap(
    1826          90 :         i::WASM_EXCEPTION_TYPE, WasmExceptionObject::kSize);
    1827             :     JSFunction::SetInitialMap(exception_constructor, exception_map,
    1828          90 :                               exception_proto);
    1829             :   }
    1830             : 
    1831             :   // Setup errors
    1832             :   Handle<JSFunction> compile_error(
    1833      274665 :       isolate->native_context()->wasm_compile_error_function(), isolate);
    1834             :   JSObject::AddProperty(isolate, webassembly,
    1835             :                         isolate->factory()->CompileError_string(),
    1836       91555 :                         compile_error, DONT_ENUM);
    1837             :   Handle<JSFunction> link_error(
    1838      274665 :       isolate->native_context()->wasm_link_error_function(), isolate);
    1839             :   JSObject::AddProperty(isolate, webassembly,
    1840             :                         isolate->factory()->LinkError_string(), link_error,
    1841       91555 :                         DONT_ENUM);
    1842             :   Handle<JSFunction> runtime_error(
    1843      274665 :       isolate->native_context()->wasm_runtime_error_function(), isolate);
    1844             :   JSObject::AddProperty(isolate, webassembly,
    1845             :                         isolate->factory()->RuntimeError_string(),
    1846       91555 :                         runtime_error, DONT_ENUM);
    1847             : }
    1848             : 
    1849             : #undef ASSIGN
    1850             : #undef EXTRACT_THIS
    1851             : 
    1852             : }  // namespace internal
    1853      183867 : }  // namespace v8

Generated by: LCOV version 1.10