Serenity Operating System
1/*
2 * Copyright (c) 2021, Ali Mohammad Pur <mpfard@serenityos.org>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <LibWeb/Bindings/Intrinsics.h>
8#include <LibWeb/WebAssembly/WebAssemblyMemoryConstructor.h>
9#include <LibWeb/WebAssembly/WebAssemblyMemoryPrototype.h>
10#include <LibWeb/WebAssembly/WebAssemblyObject.h>
11
12namespace Web::Bindings {
13
14WebAssemblyMemoryConstructor::WebAssemblyMemoryConstructor(JS::Realm& realm)
15 : NativeFunction(*realm.intrinsics().function_prototype())
16{
17}
18
19WebAssemblyMemoryConstructor::~WebAssemblyMemoryConstructor() = default;
20
21JS::ThrowCompletionOr<JS::Value> WebAssemblyMemoryConstructor::call()
22{
23 return vm().throw_completion<JS::TypeError>(JS::ErrorType::ConstructorWithoutNew, "WebAssembly.Memory");
24}
25
26JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Object>> WebAssemblyMemoryConstructor::construct(FunctionObject&)
27{
28 auto& vm = this->vm();
29 auto& realm = *vm.current_realm();
30
31 auto descriptor = TRY(vm.argument(0).to_object(vm));
32 auto initial_value = TRY(descriptor->get("initial"));
33 auto maximum_value = TRY(descriptor->get("maximum"));
34
35 if (!initial_value.is_number())
36 return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "Number");
37
38 u32 initial = TRY(initial_value.to_u32(vm));
39
40 Optional<u32> maximum;
41
42 if (!maximum_value.is_undefined())
43 maximum = TRY(maximum_value.to_u32(vm));
44
45 auto address = WebAssemblyObject::s_abstract_machine.store().allocate(Wasm::MemoryType { Wasm::Limits { initial, maximum } });
46 if (!address.has_value())
47 return vm.throw_completion<JS::TypeError>("Wasm Memory allocation failed"sv);
48
49 return MUST_OR_THROW_OOM(vm.heap().allocate<WebAssemblyMemoryObject>(realm, realm, *address));
50}
51
52JS::ThrowCompletionOr<void> WebAssemblyMemoryConstructor::initialize(JS::Realm& realm)
53{
54 auto& vm = this->vm();
55
56 MUST_OR_THROW_OOM(NativeFunction::initialize(realm));
57 define_direct_property(vm.names.prototype, &Bindings::ensure_web_prototype<WebAssemblyMemoryPrototype>(realm, "WebAssembly.Memory"), 0);
58 define_direct_property(vm.names.length, JS::Value(1), JS::Attribute::Configurable);
59
60 return {};
61}
62
63}