Skip to content

Commit

Permalink
Fix calling build_backtrace too often (#906)
Browse files Browse the repository at this point in the history
Bug introduced in commit 4c32c53 from late last month.

When unwinding the stack, call build_backtrace only when the exception
object doesn't already have a .stack property, like how it was before
commit 4c32c53.

Fixes: #904
  • Loading branch information
bnoordhuis authored Feb 10, 2025
1 parent f507557 commit 55db71e
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 2 deletions.
26 changes: 24 additions & 2 deletions quickjs.c
Original file line number Diff line number Diff line change
Expand Up @@ -14817,6 +14817,18 @@ static void dump_single_byte_code(JSContext *ctx, const uint8_t *pc,
static void print_func_name(JSFunctionBytecode *b);
#endif

static bool needs_backtrace(JSValue exc)
{
JSObject *p;

if (JS_VALUE_GET_TAG(exc) != JS_TAG_OBJECT)
return false;
p = JS_VALUE_GET_OBJ(exc);
if (p->class_id != JS_CLASS_ERROR)
return false;
return !find_own_property1(p, JS_ATOM_stack);
}

/* argv[] is modified if (flags & JS_CALL_FLAG_COPY_ARGV) = 0. */
static JSValue JS_CallInternal(JSContext *caller_ctx, JSValue func_obj,
JSValue this_obj, JSValue new_target,
Expand Down Expand Up @@ -17290,8 +17302,12 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValue func_obj,
}
}
exception:
sf->cur_pc = pc;
build_backtrace(ctx, rt->current_exception, JS_UNDEFINED, NULL, 0, 0, 0);
if (needs_backtrace(rt->current_exception)
|| JS_IsUndefined(ctx->error_back_trace)) {
sf->cur_pc = pc;
build_backtrace(ctx, rt->current_exception, JS_UNDEFINED,
NULL, 0, 0, 0);
}
if (!JS_IsUncatchableError(ctx, rt->current_exception)) {
while (sp > stack_buf) {
JSValue val = *--sp;
Expand Down Expand Up @@ -33325,9 +33341,15 @@ static JSValue JS_EvalInternal(JSContext *ctx, JSValue this_obj,
const char *input, size_t input_len,
const char *filename, int line, int flags, int scope_idx)
{
JSRuntime *rt = ctx->rt;

if (unlikely(!ctx->eval_internal)) {
return JS_ThrowTypeError(ctx, "eval is not supported");
}
if (!rt->current_stack_frame) {
JS_FreeValueRT(rt, ctx->error_back_trace);
ctx->error_back_trace = JS_UNDEFINED;
}
return ctx->eval_internal(ctx, this_obj, input, input_len, filename, line,
flags, scope_idx);
}
Expand Down
6 changes: 6 additions & 0 deletions tests/bug904.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import {assert, assertThrows} from "./assert.js"
let calls = 0
Error.prepareStackTrace = function() { calls++ }
function f() { f() }
assertThrows(RangeError, f)
assert(calls, 0)

0 comments on commit 55db71e

Please sign in to comment.