Skip to content

Commit 631f3d3

Browse files
committed
Allow stacktraces in Lua 5.1 and LuaJIT
* Fix the constructor passed when getting the stacktrace * Fix testEachVersion builder
1 parent e2e7578 commit 631f3d3

3 files changed

Lines changed: 33 additions & 4 deletions

File tree

src/lualib/Error.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { __TS__New } from "./New";
2+
13
interface ErrorType {
24
name: string;
35
new (...args: any[]): Error;
@@ -22,6 +24,10 @@ function getErrorStack(constructor: () => any): string | undefined {
2224

2325
if (_VERSION.includes("Lua 5.0")) {
2426
return debug.traceback(`[Level ${level}]`);
27+
} else if (_VERSION === "Lua 5.1") {
28+
// Lua 5.1 and LuaJIT have a bug where it's not possible to specify the level without a message.
29+
// @ts-ignore Fails when compiled with Lua 5.0 types
30+
return string.sub(debug.traceback("", level), 2);
2531
} else {
2632
// @ts-ignore Fails when compiled with Lua 5.0 types
2733
return debug.traceback(undefined, level);
@@ -33,7 +39,7 @@ function wrapErrorToString<T extends Error>(getDescription: (this: T) => string)
3339
const description = getDescription.call(this as T);
3440
const caller = debug.getinfo(3, "f");
3541
// @ts-ignore Fails when compiled with Lua 5.0 types
36-
const isClassicLua = _VERSION.includes("Lua 5.0") || _VERSION === "Lua 5.1";
42+
const isClassicLua = _VERSION.includes("Lua 5.0");
3743
if (isClassicLua || (caller && caller.func !== error)) {
3844
return description;
3945
} else {
@@ -55,7 +61,7 @@ export const Error: ErrorConstructor = initErrorClass(
5561
public stack?: string;
5662

5763
constructor(public message = "") {
58-
this.stack = getErrorStack((this.constructor as any).new);
64+
this.stack = getErrorStack(__TS__New as any);
5965
const metatable = getmetatable(this);
6066
if (metatable && !metatable.__errorToStringPatched) {
6167
metatable.__errorToStringPatched = true;

test/unit/error.spec.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as util from "../util";
2+
import * as tstl from "../../src";
23

34
test("throwString", () => {
45
util.testFunction`
@@ -343,3 +344,25 @@ test("still works without debug module", () => {
343344
stack: undefined,
344345
});
345346
});
347+
348+
util.testEachVersion(
349+
"error stacktrace omits constructor and __TS_New",
350+
() => util.testFunction`
351+
const e = new Error();
352+
return e.stack;
353+
`,
354+
{
355+
...util.expectEachVersionExceptJit(builder => {
356+
builder.expectToHaveNoDiagnostics();
357+
const luaResult = builder.getLuaExecutionResult();
358+
expect(luaResult.split('\n').length).toBe(4);
359+
}),
360+
361+
// 5.0 debug.traceback doesn't support levels
362+
[tstl.LuaTarget.Lua50]: builder => {
363+
builder.expectToHaveNoDiagnostics();
364+
const luaResult = builder.getLuaExecutionResult();
365+
expect(luaResult).toContain("Level 4");
366+
},
367+
}
368+
);

test/util.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ function getLuaBindingsForVersion(target: tstl.LuaTarget): { lauxlib: LauxLib; l
4343
return { lauxlib, lua, lualib };
4444
}
4545
if (target === tstl.LuaTarget.LuaJIT) {
46-
throw Error("Can't use executeLua() or expectToMatchJsResult() wit LuaJIT as target!");
46+
throw Error("Can't use executeLua() or expectToMatchJsResult() with LuaJIT as target!");
4747
}
4848

4949
const { lauxlib, lua, lualib } = require("lua-wasm-bindings/dist/lua.54");
@@ -63,7 +63,7 @@ export function testEachVersion<T extends TestBuilder>(
6363
): void {
6464
for (const version of Object.values(tstl.LuaTarget) as tstl.LuaTarget[]) {
6565
const specialBuilder = special?.[version];
66-
if (specialBuilder === false) return;
66+
if (specialBuilder === false) continue;
6767

6868
const testName = name === undefined ? version : `${name} [${version}]`;
6969
defineTest(testName, () => {

0 commit comments

Comments
 (0)