@@ -249,8 +249,8 @@ struct JSRuntime {
249249 JSValue current_exception;
250250 /* true if inside an out of memory error, to avoid recursing */
251251 bool in_out_of_memory;
252- /* and likewise if inside Error.prepareStackTrace() */
253- bool in_prepare_stack_trace ;
252+ /* true if inside build_backtrace, to avoid recursing */
253+ bool in_build_stack_trace ;
254254 /* true if inside JS_FreeRuntime */
255255 bool in_free;
256256
@@ -396,7 +396,7 @@ struct JSContext {
396396 JSValue error_ctor;
397397 JSValue error_back_trace;
398398 JSValue error_prepare_stack;
399- int error_stack_trace_limit;
399+ JSValue error_stack_trace_limit;
400400 JSValue iterator_ctor;
401401 JSValue iterator_proto;
402402 JSValue async_iterator_proto;
@@ -2311,7 +2311,7 @@ JSContext *JS_NewContextRaw(JSRuntime *rt)
23112311 ctx->error_ctor = JS_NULL;
23122312 ctx->error_back_trace = JS_UNDEFINED;
23132313 ctx->error_prepare_stack = JS_UNDEFINED;
2314- ctx->error_stack_trace_limit = 10 ;
2314+ ctx->error_stack_trace_limit = js_int32(10) ;
23152315 init_list_head(&ctx->loaded_modules);
23162316
23172317 JS_AddIntrinsicBasicObjects(ctx);
@@ -2431,6 +2431,7 @@ static void JS_MarkContext(JSRuntime *rt, JSContext *ctx,
24312431 JS_MarkValue(rt, ctx->error_ctor, mark_func);
24322432 JS_MarkValue(rt, ctx->error_back_trace, mark_func);
24332433 JS_MarkValue(rt, ctx->error_prepare_stack, mark_func);
2434+ JS_MarkValue(rt, ctx->error_stack_trace_limit, mark_func);
24342435 for(i = 0; i < rt->class_count; i++) {
24352436 JS_MarkValue(rt, ctx->class_proto[i], mark_func);
24362437 }
@@ -2499,6 +2500,7 @@ void JS_FreeContext(JSContext *ctx)
24992500 JS_FreeValue(ctx, ctx->error_ctor);
25002501 JS_FreeValue(ctx, ctx->error_back_trace);
25012502 JS_FreeValue(ctx, ctx->error_prepare_stack);
2503+ JS_FreeValue(ctx, ctx->error_stack_trace_limit);
25022504 for(i = 0; i < rt->class_count; i++) {
25032505 JS_FreeValue(ctx, ctx->class_proto[i]);
25042506 }
@@ -6751,26 +6753,43 @@ static void build_backtrace(JSContext *ctx, JSValue error_val, JSValue filter_fu
67516753 JSRuntime *rt;
67526754 JSCallSiteData csd[64];
67536755 uint32_t i;
6756+ double d;
67546757 int stack_trace_limit;
67556758
6759+ rt = ctx->rt;
6760+ if (rt->in_build_stack_trace)
6761+ return;
6762+ rt->in_build_stack_trace = true;
6763+
6764+ // Save exception because conversion to double may fail.
6765+ saved_exception = JS_GetException(ctx);
6766+
6767+ // Extract stack trace limit.
6768+ JS_ToFloat64(ctx, &d, ctx->error_stack_trace_limit);
6769+ if (isnan(d) || d < 0.0)
6770+ stack_trace_limit = 0;
6771+ else if (d > INT32_MAX)
6772+ stack_trace_limit = INT32_MAX;
6773+ else
6774+ stack_trace_limit = fabs(d);
6775+
6776+ // Restore current exception.
6777+ JS_Throw(ctx, saved_exception);
67566778 saved_exception = JS_UNINITIALIZED;
6757- stack_trace_limit = ctx->error_stack_trace_limit;
6779+
67586780 stack_trace_limit = min_int(stack_trace_limit, countof(csd));
67596781 stack_trace_limit = max_int(stack_trace_limit, 0);
6760- rt = ctx->rt;
67616782 has_prepare = false;
67626783 has_filter_func = backtrace_flags & JS_BACKTRACE_FLAG_FILTER_FUNC;
67636784 i = 0;
67646785
6765- if (!rt->in_prepare_stack_trace && ! JS_IsNull(ctx->error_ctor)) {
6786+ if (!JS_IsNull(ctx->error_ctor)) {
67666787 prepare = js_dup(ctx->error_prepare_stack);
67676788 has_prepare = JS_IsFunction(ctx, prepare);
6768- rt->in_prepare_stack_trace = true;
67696789 }
67706790
67716791 if (has_prepare) {
6772- saved_exception = rt->current_exception;
6773- rt->current_exception = JS_UNINITIALIZED;
6792+ saved_exception = JS_GetException(ctx);
67746793 if (stack_trace_limit == 0)
67756794 goto done;
67766795 if (filename)
@@ -6894,8 +6913,7 @@ static void build_backtrace(JSContext *ctx, JSValue error_val, JSValue filter_fu
68946913 else
68956914 stack = stack2;
68966915 JS_FreeValue(ctx, prepare);
6897- JS_FreeValue(ctx, rt->current_exception);
6898- rt->current_exception = saved_exception;
6916+ JS_Throw(ctx, saved_exception);
68996917 } else {
69006918 if (dbuf_error(&dbuf))
69016919 stack = JS_NULL;
@@ -6904,7 +6922,6 @@ static void build_backtrace(JSContext *ctx, JSValue error_val, JSValue filter_fu
69046922 dbuf_free(&dbuf);
69056923 }
69066924
6907- rt->in_prepare_stack_trace = false;
69086925 if (JS_IsUndefined(ctx->error_back_trace))
69096926 ctx->error_back_trace = js_dup(stack);
69106927 if (has_filter_func || can_add_backtrace(error_val)) {
@@ -6913,6 +6930,8 @@ static void build_backtrace(JSContext *ctx, JSValue error_val, JSValue filter_fu
69136930 } else {
69146931 JS_FreeValue(ctx, stack);
69156932 }
6933+
6934+ rt->in_build_stack_trace = false;
69166935}
69176936
69186937JSValue JS_NewError(JSContext *ctx)
@@ -38154,23 +38173,14 @@ static JSValue js_error_get_stackTraceLimit(JSContext *ctx, JSValue this_val)
3815438173 if (JS_IsException(val))
3815538174 return val;
3815638175 JS_FreeValue(ctx, val);
38157- return js_int32 (ctx->error_stack_trace_limit);
38176+ return js_dup (ctx->error_stack_trace_limit);
3815838177}
3815938178
3816038179static JSValue js_error_set_stackTraceLimit(JSContext *ctx, JSValue this_val, JSValue value)
3816138180{
3816238181 if (JS_IsUndefined(this_val) || JS_IsNull(this_val))
3816338182 return JS_ThrowTypeErrorNotAnObject(ctx);
38164- double limit = 0;
38165- if (JS_ToFloat64(ctx, &limit, value) < 0)
38166- return JS_EXCEPTION;
38167- if (isfinite(limit)) {
38168- ctx->error_stack_trace_limit = limit;
38169- } else if (isnan(limit) || limit == -INFINITY) {
38170- ctx->error_stack_trace_limit = 0;
38171- } else {
38172- ctx->error_stack_trace_limit = INT32_MAX;
38173- }
38183+ ctx->error_stack_trace_limit = js_dup(value);
3817438184 return JS_UNDEFINED;
3817538185}
3817638186
0 commit comments