c0ee8f905b
The `Script::source_url` field holds the value of the magic `//# sourceURL` comment if found, and the `Script::name` field is supposed to hold the actual name of the resource (as provided by the embedder ideally), in case of Chromium that's supposed to be the URL (in case of Node.js it's often the local path). Using `source_url` worked by chance so far, but for loading DWARF symbol files correctly we need the initiator (which we pick from the embedderName of the Script as reported to DevTools). More importantly, the partial handling of `//# sourceURL` in V8 is a layering violation and causes trouble in DevTools, i.e. when users put relative paths here. So as part of refactoring and correctifying the handling of `//# sourceURL`, we need to make sure that the embedder provided name (the URL in case of Chromium) is always stored in the `Script::name` field. Bug: chromium:1183990, chromium:974543, chromium:1174507 Change-Id: I32e11def2b9b52be11bd2e0e64a2ab6bdcf5e52d Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2773584 Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Reviewed-by: Clemens Backes <clemensb@chromium.org> Cr-Commit-Position: refs/heads/master@{#73536}
185 lines
6.6 KiB
JavaScript
185 lines
6.6 KiB
JavaScript
// Copyright 2016 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: --expose-wasm --no-force-slow-path
|
|
|
|
load("test/mjsunit/wasm/wasm-module-builder.js");
|
|
|
|
// The stack trace contains file path, only keep "stack.js".
|
|
function stripPath(s) {
|
|
return s.replace(/[^ (]*stack\.js/g, "stack.js");
|
|
}
|
|
|
|
function verifyStack(frames, expected) {
|
|
assertEquals(expected.length, frames.length, "number of frames mismatch");
|
|
expected.forEach(function(exp, i) {
|
|
assertEquals(exp[1], frames[i].getFunctionName(),
|
|
"["+i+"].getFunctionName()");
|
|
assertEquals(exp[2], frames[i].getLineNumber(), "["+i+"].getLineNumber()");
|
|
if (exp[0])
|
|
assertEquals(exp[3], frames[i].getPosition(),
|
|
"["+i+"].getPosition()");
|
|
assertContains(exp[4], frames[i].getFileName(), "["+i+"].getFileName()");
|
|
var toString;
|
|
if (exp[0]) {
|
|
toString = "<anonymous>:wasm-function[" + exp[6] + "]:" + exp[5];
|
|
if (exp[1] !== null) toString = exp[1] + " (" + toString + ")";
|
|
} else {
|
|
toString = exp[4] + ":" + exp[2] + ":";
|
|
}
|
|
assertContains(toString, frames[i].toString(), "["+i+"].toString()");
|
|
});
|
|
}
|
|
|
|
|
|
var stack;
|
|
function STACK() {
|
|
var e = new Error();
|
|
stack = e.stack;
|
|
}
|
|
|
|
var builder = new WasmModuleBuilder();
|
|
|
|
builder.addMemory(0, 1, false);
|
|
|
|
builder.addImport("mod", "func", kSig_v_v);
|
|
|
|
builder.addFunction("main", kSig_v_v)
|
|
.addBody([kExprCallFunction, 0])
|
|
.exportAs("main");
|
|
|
|
builder.addFunction("exec_unreachable", kSig_v_v)
|
|
.addBody([kExprUnreachable])
|
|
.exportAs("exec_unreachable");
|
|
|
|
// Make this function unnamed, just to test also this case.
|
|
var mem_oob_func = builder.addFunction(undefined, kSig_i_v)
|
|
// Access the memory at offset -1, to provoke a trap.
|
|
.addBody([kExprI32Const, 0x7f, kExprI32LoadMem8S, 0, 0])
|
|
.exportAs("mem_out_of_bounds");
|
|
|
|
// Call the mem_out_of_bounds function, in order to have two wasm stack frames.
|
|
builder.addFunction("call_mem_out_of_bounds", kSig_i_v)
|
|
.addBody([kExprCallFunction, mem_oob_func.index])
|
|
.exportAs("call_mem_out_of_bounds");
|
|
|
|
var module = builder.instantiate({mod: {func: STACK}});
|
|
|
|
(function testSimpleStack() {
|
|
var expected_string = 'Error\n' +
|
|
// The line numbers below will change as this test gains / loses lines..
|
|
' at STACK (stack.js:38:11)\n' + // --
|
|
' at main (<anonymous>:wasm-function[1]:0x86)\n' + // --
|
|
' at testSimpleStack (stack.js:77:18)\n' + // --
|
|
' at stack.js:79:3'; // --
|
|
|
|
module.exports.main();
|
|
assertEquals(expected_string, stripPath(stack));
|
|
})();
|
|
|
|
// For the remaining tests, collect the Callsite objects instead of just a
|
|
// string:
|
|
Error.prepareStackTrace = function(error, frames) {
|
|
return frames;
|
|
};
|
|
|
|
(function testStackFrames() {
|
|
module.exports.main();
|
|
|
|
verifyStack(stack, [
|
|
// isWasm function line pos file offset funcIndex
|
|
[ false, "STACK", 38, 0, "stack.js"],
|
|
[ true, "main", 1, 0x86, "wasm://wasm/7168ab72", '0x86', 1],
|
|
[ false, "testStackFrames", 88, 0, "stack.js"],
|
|
[ false, null, 97, 0, "stack.js"]
|
|
]);
|
|
})();
|
|
|
|
(function testWasmUnreachable() {
|
|
try {
|
|
module.exports.exec_unreachable();
|
|
fail("expected wasm exception");
|
|
} catch (e) {
|
|
assertContains("unreachable", e.message);
|
|
verifyStack(e.stack, [
|
|
// isWasm function line pos file offset funcIndex
|
|
[ true, "exec_unreachable", 1, 0x8b, "wasm://wasm/7168ab72", '0x8b', 2],
|
|
[ false, "testWasmUnreachable", 101, 0, "stack.js"],
|
|
[ false, null, 112, 0, "stack.js"]
|
|
]);
|
|
}
|
|
})();
|
|
|
|
(function testWasmMemOutOfBounds() {
|
|
try {
|
|
module.exports.call_mem_out_of_bounds();
|
|
fail("expected wasm exception");
|
|
} catch (e) {
|
|
assertContains("out of bounds", e.message);
|
|
verifyStack(e.stack, [
|
|
// isWasm function line pos file offset funcIndex
|
|
[ true, "mem_out_of_bounds", 1, 0x91, "wasm://wasm/7168ab72", '0x91', 3],
|
|
[ true, "call_mem_out_of_bounds", 1, 0x97, "wasm://wasm/7168ab72", '0x97', 4],
|
|
[ false, "testWasmMemOutOfBounds", 116, 0, "stack.js"],
|
|
[ false, null, 128, 0, "stack.js"]
|
|
]);
|
|
}
|
|
})();
|
|
|
|
(function testStackOverflow() {
|
|
print("testStackOverflow");
|
|
var builder = new WasmModuleBuilder();
|
|
|
|
var sig_index = builder.addType(kSig_v_v);
|
|
builder.addFunction("recursion", sig_index)
|
|
.addBody([
|
|
kExprI32Const, 0,
|
|
kExprCallIndirect, sig_index, kTableZero
|
|
])
|
|
.exportFunc();
|
|
builder.appendToTable([0]);
|
|
|
|
try {
|
|
builder.instantiate().exports.recursion();
|
|
fail("expected wasm exception");
|
|
} catch (e) {
|
|
assertEquals("Maximum call stack size exceeded", e.message, "trap reason");
|
|
assertTrue(e.stack.length >= 4, "expected at least 4 stack entries");
|
|
verifyStack(e.stack.splice(0, 4), [
|
|
// isWasm function line pos file offset funcIndex
|
|
[ true, "recursion", 1, 0x34, "wasm://wasm/80a35e5a", '0x34', 0],
|
|
[ true, "recursion", 1, 0x37, "wasm://wasm/80a35e5a", '0x37', 0],
|
|
[ true, "recursion", 1, 0x37, "wasm://wasm/80a35e5a", '0x37', 0],
|
|
[ true, "recursion", 1, 0x37, "wasm://wasm/80a35e5a", '0x37', 0]
|
|
]);
|
|
}
|
|
})();
|
|
|
|
(function testBigOffset() {
|
|
print('testBigOffset');
|
|
var builder = new WasmModuleBuilder();
|
|
|
|
let body = [kExprI32Const, 0, kExprI32Add];
|
|
while (body.length <= 65536) body = body.concat(body);
|
|
body.unshift(kExprI32Const, 0);
|
|
body.push(kExprUnreachable);
|
|
let unreachable_pos = body.length - 1;
|
|
|
|
builder.addFunction('main', kSig_v_v).addBody(body).exportFunc();
|
|
|
|
try {
|
|
builder.instantiate().exports.main();
|
|
fail('expected wasm exception');
|
|
} catch (e) {
|
|
assertEquals('unreachable', e.message, 'trap reason');
|
|
let hexOffset = '0x' + (unreachable_pos + 0x25).toString(16);
|
|
verifyStack(e.stack, [
|
|
// isWasm function line pos file offset funcIndex
|
|
[ true, 'main', 1, unreachable_pos + 0x25, 'wasm://wasm/000600e6', hexOffset, 0],
|
|
[ false, 'testBigOffset', 172, 0, 'stack.js'],
|
|
[ false, null, 184, 0, 'stack.js']
|
|
]);
|
|
}
|
|
})();
|