Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Libraries/LibWeb/WebAssembly/Memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ WebIDL::ExceptionOr<GC::Ref<Memory>> Memory::construct_impl(JS::Realm& realm, Me
auto& vm = realm.vm();

// https://webassembly.github.io/threads/js-api/index.html#dom-memory-memory
// 3. If maximum is not empty and maximum < initial, throw a RangeError exception.
if (descriptor.maximum.has_value() && descriptor.maximum.value() < descriptor.initial) {
return vm.throw_completion<JS::RangeError>("Initial is larger than maximum."sv);
}

// 4. Let share be shared if descriptor["shared"] is true and unshared otherwise.
// 5. If share is shared and maximum is empty, throw a TypeError exception.
auto shared = descriptor.shared.value_or(false);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
Harness status: OK

Found 24 tests

24 Pass
Pass name
Pass length
Pass No arguments
Pass Calling
Pass Invalid descriptor argument
Pass Undefined initial value in descriptor
Pass Out-of-range initial value in descriptor: NaN
Pass Out-of-range maximum value in descriptor: NaN
Pass Out-of-range initial value in descriptor: Infinity
Pass Out-of-range maximum value in descriptor: Infinity
Pass Out-of-range initial value in descriptor: -Infinity
Pass Out-of-range maximum value in descriptor: -Infinity
Pass Out-of-range initial value in descriptor: -1
Pass Out-of-range maximum value in descriptor: -1
Pass Out-of-range initial value in descriptor: 4294967296
Pass Out-of-range maximum value in descriptor: 4294967296
Pass Out-of-range initial value in descriptor: 68719476736
Pass Out-of-range maximum value in descriptor: 68719476736
Pass Initial value exceeds maximum
Pass Proxy descriptor
Pass Order of evaluation for descriptor
Pass Zero initial
Pass Non-zero initial
Pass Stray argument
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!doctype html>
<meta charset=utf-8>

<script>
self.GLOBAL = {
isWindow: function() { return true; },
isWorker: function() { return false; },
isShadowRealm: function() { return false; },
};
</script>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script src="../../../wasm/jsapi/assertions.js"></script>
<script src="../../../wasm/jsapi/memory/assertions.js"></script>
<div id=log></div>
<script src="../../../wasm/jsapi/memory/constructor.any.js"></script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
// META: global=window,dedicatedworker,jsshell,shadowrealm
// META: script=/wasm/jsapi/assertions.js
// META: script=/wasm/jsapi/memory/assertions.js

test(() => {
assert_function_name(WebAssembly.Memory, "Memory", "WebAssembly.Memory");
}, "name");

test(() => {
assert_function_length(WebAssembly.Memory, 1, "WebAssembly.Memory");
}, "length");

test(() => {
assert_throws_js(TypeError, () => new WebAssembly.Memory());
}, "No arguments");

test(() => {
const argument = { "initial": 0 };
assert_throws_js(TypeError, () => WebAssembly.Memory(argument));
}, "Calling");

test(() => {
const invalidArguments = [
undefined,
null,
false,
true,
"",
"test",
Symbol(),
1,
NaN,
{},
];
for (const invalidArgument of invalidArguments) {
assert_throws_js(TypeError,
() => new WebAssembly.Memory(invalidArgument),
`new Memory(${format_value(invalidArgument)})`);
}
}, "Invalid descriptor argument");

test(() => {
assert_throws_js(TypeError, () => new WebAssembly.Memory({ "initial": undefined }));
}, "Undefined initial value in descriptor");

const outOfRangeValues = [
NaN,
Infinity,
-Infinity,
-1,
0x100000000,
0x1000000000,
];

for (const value of outOfRangeValues) {
test(() => {
assert_throws_js(TypeError, () => new WebAssembly.Memory({ "initial": value }));
}, `Out-of-range initial value in descriptor: ${format_value(value)}`);

test(() => {
assert_throws_js(TypeError, () => new WebAssembly.Memory({ "initial": 0, "maximum": value }));
}, `Out-of-range maximum value in descriptor: ${format_value(value)}`);
}

test(() => {
assert_throws_js(RangeError, () => new WebAssembly.Memory({ "initial": 10, "maximum": 9 }));
}, "Initial value exceeds maximum");

test(() => {
const proxy = new Proxy({}, {
has(o, x) {
assert_unreached(`Should not call [[HasProperty]] with ${x}`);
},
get(o, x) {
// Due to the requirement not to supply both minimum and initial, we need to ignore one of them.
switch (x) {
case "shared":
return false;
case "initial":
case "maximum":
return 0;
default:
return undefined;
}
},
});
new WebAssembly.Memory(proxy);
}, "Proxy descriptor");

test(() => {
const order = [];

new WebAssembly.Memory({
get maximum() {
order.push("maximum");
return {
valueOf() {
order.push("maximum valueOf");
return 1;
},
};
},

get initial() {
order.push("initial");
return {
valueOf() {
order.push("initial valueOf");
return 1;
},
};
},
});

assert_array_equals(order, [
"initial",
"initial valueOf",
"maximum",
"maximum valueOf",
]);
}, "Order of evaluation for descriptor");

test(() => {
const argument = { "initial": 0 };
const memory = new WebAssembly.Memory(argument);
assert_Memory(memory, { "size": 0 });
}, "Zero initial");

test(() => {
const argument = { "initial": 4 };
const memory = new WebAssembly.Memory(argument);
assert_Memory(memory, { "size": 4 });
}, "Non-zero initial");

test(() => {
const argument = { "initial": 0 };
const memory = new WebAssembly.Memory(argument, {});
assert_Memory(memory, { "size": 0 });
}, "Stray argument");
Loading