Record source column positions (#193)

And:
- display them in stack traces
- expose them as Function.prototype.columnNumber

OP_line_num is renamed to OP_source_loc and the pc2line data structure
is extended with the column number in zigzag encoding.

The bytecode version number BC_VERSION is incremented because pc2line
data is read and written by JS_ReadObject() and JS_WriteObject() when
it is present.

Fixes: https://github.com/quickjs-ng/quickjs/issues/149
This commit is contained in:
Ben Noordhuis 2023-12-11 22:36:13 +01:00 committed by GitHub
parent 40771c9103
commit bace4f635e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 412 additions and 188 deletions

View file

@ -81,6 +81,7 @@ DEF(empty_string, "")
DEF(length, "length")
DEF(fileName, "fileName")
DEF(lineNumber, "lineNumber")
DEF(columnNumber, "columnNumber")
DEF(message, "message")
DEF(cause, "cause")
DEF(errors, "errors")

View file

@ -44,6 +44,7 @@ FMT(loc)
FMT(arg)
FMT(var_ref)
FMT(u32)
FMT(u32x2)
FMT(i32)
FMT(const)
FMT(label)
@ -281,7 +282,7 @@ def(scope_put_private_field, 7, 2, 0, atom_u16) /* obj value ->, emitted in phas
def( set_class_name, 5, 1, 1, u32) /* emitted in phase 1, removed in phase 2 */
def( line_num, 5, 0, 0, u32) /* emitted in phase 1, removed in phase 3 */
def( source_loc, 9, 0, 0, u32x2) /* emitted in phase 1, removed in phase 3 */
DEF( push_minus1, 1, 0, 1, none_int)
DEF( push_0, 1, 0, 1, none_int)

571
quickjs.c

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,28 @@
import * as os from "os";
// Keep this at the top; it tests source positions.
function test_exception_source_pos()
{
var e;
try {
throw new Error(""); // line 9, column 19
} catch(_e) {
e = _e;
}
assert(e.stack.includes("test_builtin.js:9:19"));
}
// Keep this at the top; it tests source positions.
function test_function_source_pos() // line 18, column 1
{
function inner() {} // line 20, column 5
var f = eval("function f() {} f");
assert(`${test_function_source_pos.lineNumber}:${test_function_source_pos.columnNumber}`, "18:1");
assert(`${inner.lineNumber}:${inner.columnNumber}`, "20:5");
assert(`${f.lineNumber}:${f.columnNumber}`, "1:1");
}
function assert(actual, expected, message) {
if (arguments.length == 1)
@ -758,3 +781,5 @@ test_weak_map();
test_weak_set();
test_generator();
test_proxy_is_array();
test_exception_source_pos();
test_function_source_pos();