LCOV - code coverage report
Current view: top level - src/wasm - wasm-js.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 697 767 90.9 %
Date: 2019-02-19 Functions: 72 87 82.8 %

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

Generated by: LCOV version 1.10