mirror of
https://github.com/nodejs/node.git
synced 2025-05-15 16:01:52 +00:00

PR-URL: https://github.com/nodejs/node/pull/52293 Reviewed-By: Moshe Atlow <moshe@atlow.co.il> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com> Reviewed-By: Richard Lau <rlau@redhat.com>
144 lines
4.6 KiB
JavaScript
144 lines
4.6 KiB
JavaScript
// Copyright 2022 the V8 project authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
// Flags: --experimental-wasm-stringref --allow-natives-syntax
|
|
// We just want speculative inlining, but the "stress" variant doesn't like
|
|
// that flag for some reason, so use the GC flag which implies it.
|
|
d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
|
|
|
|
let kSig_w_v = makeSig([], [kWasmStringRef]);
|
|
let kSig_w_i = makeSig([kWasmI32], [kWasmStringRef]);
|
|
let kSig_v_w = makeSig([kWasmStringRef], []);
|
|
|
|
(function () {
|
|
let huge_builder = new WasmModuleBuilder();
|
|
huge_builder.addMemory(65001, undefined);
|
|
|
|
huge_builder.addFunction("huge", kSig_w_v).exportFunc().addBody([
|
|
kExprI32Const, 0, // address
|
|
...wasmI32Const(65000 * 65536), // bytes
|
|
...GCInstr(kExprStringNewUtf8), 0 // memory index
|
|
]);
|
|
|
|
let callee = huge_builder.addFunction("callee", kSig_w_i).addBody([
|
|
kExprI32Const, 0, // address
|
|
kExprLocalGet, 0, // bytes
|
|
...GCInstr(kExprStringNewUtf8), 0 // memory index
|
|
]);
|
|
|
|
let caller = huge_builder.addFunction("caller", kSig_i_i).exportFunc()
|
|
.addBody([
|
|
kExprTry, kWasmI32,
|
|
kExprLocalGet, 0,
|
|
kExprCallFunction, callee.index,
|
|
kExprDrop,
|
|
kExprI32Const, 1,
|
|
kExprCatchAll,
|
|
kExprI32Const, 0,
|
|
kExprEnd
|
|
]);
|
|
|
|
let instance;
|
|
try {
|
|
instance = huge_builder.instantiate();
|
|
// On 64-bit platforms, expect to see this message.
|
|
console.log("Instantiation successful, proceeding.");
|
|
} catch (e) {
|
|
// 32-bit builds don't have enough virtual memory, that's OK.
|
|
assertInstanceof(e, RangeError);
|
|
assertMatches(/Cannot allocate Wasm memory for new instance/, e.message,
|
|
'Error message');
|
|
return;
|
|
}
|
|
|
|
// Bug 1: The Utf8Decoder can't handle more than kMaxInt bytes as input.
|
|
assertThrows(() => instance.exports.huge(), RangeError);
|
|
|
|
// Bug 2: Exceptions created by the JS-focused strings infrastructure must
|
|
// be marked as uncatchable by Wasm.
|
|
let f1 = instance.exports.caller;
|
|
assertThrows(() => f1(2147483647), RangeError);
|
|
|
|
// Bug 3: Builtin calls that have neither a kNoThrow annotation nor exception-
|
|
// handling support make the Wasm inliner sad.
|
|
for (let i = 0; i < 20; i++) f1(10);
|
|
%WasmTierUpFunction(f1);
|
|
f1(10);
|
|
})();
|
|
|
|
(function () {
|
|
let builder = new WasmModuleBuilder();
|
|
|
|
let concat_body = [];
|
|
// This doubles the string 26 times, i.e. multiplies its length with a factor
|
|
// of ~65 million.
|
|
for (let i = 0; i < 26; i++) {
|
|
concat_body.push(...[
|
|
kExprLocalGet, 0, kExprLocalGet, 0,
|
|
...GCInstr(kExprStringConcat),
|
|
kExprLocalSet, 0
|
|
]);
|
|
}
|
|
|
|
builder.addFunction('concat', kSig_v_w).exportFunc().addBody(concat_body);
|
|
|
|
let instance = builder.instantiate();
|
|
|
|
// Bug 4: Throwing in StringAdd must clear the "thread in wasm" bit.
|
|
let f2 = instance.exports.concat;
|
|
assertThrows(() => f2("1234567890")); // 650M characters is too much.
|
|
|
|
// Bug 5: Operations that can trap must not be marked as kEliminatable,
|
|
// otherwise the trap may be eliminated.
|
|
for (let i = 0; i < 3; i++) f2("a"); // 65M characters is okay.
|
|
%WasmTierUpFunction(f2);
|
|
assertThrows(() => f2("1234567890")); // Optimized code still traps.
|
|
})();
|
|
|
|
(function TestThatOneCharacterStringsAreInternalized() {
|
|
let builder = new WasmModuleBuilder();
|
|
|
|
builder.addMemory(1, undefined);
|
|
const kMemIndex = 0;
|
|
builder.addActiveDataSegment(0, [kExprI32Const, 0], [65, 0]);
|
|
|
|
let a8 = builder.addArray(kWasmI8, true);
|
|
let a16 = builder.addArray(kWasmI16, true);
|
|
|
|
builder.addFunction('makeString8A', kSig_w_v).exportFunc().addBody([
|
|
...wasmI32Const(65),
|
|
kGCPrefix, kExprArrayNewFixed, a8, 1,
|
|
kExprI32Const, 0,
|
|
kExprI32Const, 1,
|
|
...GCInstr(kExprStringNewWtf8Array),
|
|
]);
|
|
|
|
builder.addFunction('makeString16A', kSig_w_v).exportFunc().addBody([
|
|
...wasmI32Const(65),
|
|
kGCPrefix, kExprArrayNewFixed, a16, 1,
|
|
kExprI32Const, 0,
|
|
kExprI32Const, 1,
|
|
...GCInstr(kExprStringNewWtf16Array),
|
|
]);
|
|
|
|
builder.addFunction('makeString8M', kSig_w_v).exportFunc().addBody([
|
|
kExprI32Const, 0,
|
|
kExprI32Const, 1,
|
|
...GCInstr(kExprStringNewWtf8), kMemIndex,
|
|
]);
|
|
|
|
builder.addFunction('makeString16M', kSig_w_v).exportFunc().addBody([
|
|
kExprI32Const, 0,
|
|
kExprI32Const, 1,
|
|
...GCInstr(kExprStringNewWtf16), kMemIndex,
|
|
]);
|
|
|
|
let wasm = builder.instantiate().exports;
|
|
|
|
assertTrue(%IsSameHeapObject("A", wasm.makeString8A()));
|
|
assertTrue(%IsSameHeapObject("A", wasm.makeString16A()));
|
|
assertTrue(%IsSameHeapObject("A", wasm.makeString8M()));
|
|
assertTrue(%IsSameHeapObject("A", wasm.makeString16M()));
|
|
})();
|