Serenity Operating System
at master 83 lines 3.4 kB view raw
1/* 2 * Copyright (c) 2021, Ali Mohammad Pur <mpfard@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/ScopeGuard.h> 8#include <LibJS/Runtime/Array.h> 9#include <LibJS/Runtime/ArrayBuffer.h> 10#include <LibJS/Runtime/BigInt.h> 11#include <LibJS/Runtime/TypedArray.h> 12#include <LibWasm/AbstractMachine/Interpreter.h> 13#include <LibWeb/Bindings/Intrinsics.h> 14#include <LibWeb/WebAssembly/WebAssemblyInstanceObject.h> 15#include <LibWeb/WebAssembly/WebAssemblyMemoryPrototype.h> 16#include <LibWeb/WebAssembly/WebAssemblyObject.h> 17#include <LibWeb/WebAssembly/WebAssemblyTableObject.h> 18 19namespace Web::Bindings { 20 21WebAssemblyInstanceObject::WebAssemblyInstanceObject(JS::Realm& realm, size_t index) 22 : Object(ConstructWithPrototypeTag::Tag, Bindings::ensure_web_prototype<WebAssemblyInstancePrototype>(realm, "WebAssembly.Instance")) 23 , m_index(index) 24{ 25} 26 27JS::ThrowCompletionOr<void> WebAssemblyInstanceObject::initialize(JS::Realm& realm) 28{ 29 MUST_OR_THROW_OOM(Object::initialize(realm)); 30 31 auto& vm = this->vm(); 32 33 VERIFY(!m_exports_object); 34 m_exports_object = create(realm, nullptr); 35 auto& instance = this->instance(); 36 auto& cache = this->cache(); 37 for (auto& export_ : instance.exports()) { 38 TRY(export_.value().visit( 39 [&](Wasm::FunctionAddress const& address) -> JS::ThrowCompletionOr<void> { 40 Optional<JS::FunctionObject*> object = cache.function_instances.get(address); 41 if (!object.has_value()) { 42 object = create_native_function(vm, address, export_.name()); 43 cache.function_instances.set(address, *object); 44 } 45 m_exports_object->define_direct_property(export_.name(), *object, JS::default_attributes); 46 return {}; 47 }, 48 [&](Wasm::MemoryAddress const& address) -> JS::ThrowCompletionOr<void> { 49 Optional<WebAssemblyMemoryObject*> object = cache.memory_instances.get(address); 50 if (!object.has_value()) { 51 object = MUST_OR_THROW_OOM(heap().allocate<Web::Bindings::WebAssemblyMemoryObject>(realm, realm, address)); 52 cache.memory_instances.set(address, *object); 53 } 54 m_exports_object->define_direct_property(export_.name(), *object, JS::default_attributes); 55 return {}; 56 }, 57 [&](Wasm::TableAddress const& address) -> JS::ThrowCompletionOr<void> { 58 Optional<WebAssemblyTableObject*> object = cache.table_instances.get(address); 59 if (!object.has_value()) { 60 object = MUST_OR_THROW_OOM(heap().allocate<Web::Bindings::WebAssemblyTableObject>(realm, realm, address)); 61 cache.table_instances.set(address, *object); 62 } 63 m_exports_object->define_direct_property(export_.name(), *object, JS::default_attributes); 64 return {}; 65 }, 66 [&](auto const&) -> JS::ThrowCompletionOr<void> { 67 // FIXME: Implement other exports! 68 return {}; 69 })); 70 } 71 72 MUST(m_exports_object->set_integrity_level(IntegrityLevel::Frozen)); 73 74 return {}; 75} 76 77void WebAssemblyInstanceObject::visit_edges(Visitor& visitor) 78{ 79 Base::visit_edges(visitor); 80 visitor.visit(m_exports_object); 81} 82 83}