@@ -249,8 +249,8 @@ struct JSRuntime {
249
249
JSValue current_exception;
250
250
/* true if inside an out of memory error, to avoid recursing */
251
251
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 ;
254
254
/* true if inside JS_FreeRuntime */
255
255
bool in_free;
256
256
@@ -396,7 +396,7 @@ struct JSContext {
396
396
JSValue error_ctor;
397
397
JSValue error_back_trace;
398
398
JSValue error_prepare_stack;
399
- int error_stack_trace_limit;
399
+ JSValue error_stack_trace_limit;
400
400
JSValue iterator_ctor;
401
401
JSValue iterator_proto;
402
402
JSValue async_iterator_proto;
@@ -2311,7 +2311,7 @@ JSContext *JS_NewContextRaw(JSRuntime *rt)
2311
2311
ctx->error_ctor = JS_NULL;
2312
2312
ctx->error_back_trace = JS_UNDEFINED;
2313
2313
ctx->error_prepare_stack = JS_UNDEFINED;
2314
- ctx->error_stack_trace_limit = 10 ;
2314
+ ctx->error_stack_trace_limit = js_int32(10) ;
2315
2315
init_list_head(&ctx->loaded_modules);
2316
2316
2317
2317
JS_AddIntrinsicBasicObjects(ctx);
@@ -2431,6 +2431,7 @@ static void JS_MarkContext(JSRuntime *rt, JSContext *ctx,
2431
2431
JS_MarkValue(rt, ctx->error_ctor, mark_func);
2432
2432
JS_MarkValue(rt, ctx->error_back_trace, mark_func);
2433
2433
JS_MarkValue(rt, ctx->error_prepare_stack, mark_func);
2434
+ JS_MarkValue(rt, ctx->error_stack_trace_limit, mark_func);
2434
2435
for(i = 0; i < rt->class_count; i++) {
2435
2436
JS_MarkValue(rt, ctx->class_proto[i], mark_func);
2436
2437
}
@@ -2499,6 +2500,7 @@ void JS_FreeContext(JSContext *ctx)
2499
2500
JS_FreeValue(ctx, ctx->error_ctor);
2500
2501
JS_FreeValue(ctx, ctx->error_back_trace);
2501
2502
JS_FreeValue(ctx, ctx->error_prepare_stack);
2503
+ JS_FreeValue(ctx, ctx->error_stack_trace_limit);
2502
2504
for(i = 0; i < rt->class_count; i++) {
2503
2505
JS_FreeValue(ctx, ctx->class_proto[i]);
2504
2506
}
@@ -6751,26 +6753,43 @@ static void build_backtrace(JSContext *ctx, JSValue error_val, JSValue filter_fu
6751
6753
JSRuntime *rt;
6752
6754
JSCallSiteData csd[64];
6753
6755
uint32_t i;
6756
+ double d;
6754
6757
int stack_trace_limit;
6755
6758
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);
6756
6778
saved_exception = JS_UNINITIALIZED;
6757
- stack_trace_limit = ctx->error_stack_trace_limit;
6779
+
6758
6780
stack_trace_limit = min_int(stack_trace_limit, countof(csd));
6759
6781
stack_trace_limit = max_int(stack_trace_limit, 0);
6760
- rt = ctx->rt;
6761
6782
has_prepare = false;
6762
6783
has_filter_func = backtrace_flags & JS_BACKTRACE_FLAG_FILTER_FUNC;
6763
6784
i = 0;
6764
6785
6765
- if (!rt->in_prepare_stack_trace && ! JS_IsNull(ctx->error_ctor)) {
6786
+ if (!JS_IsNull(ctx->error_ctor)) {
6766
6787
prepare = js_dup(ctx->error_prepare_stack);
6767
6788
has_prepare = JS_IsFunction(ctx, prepare);
6768
- rt->in_prepare_stack_trace = true;
6769
6789
}
6770
6790
6771
6791
if (has_prepare) {
6772
- saved_exception = rt->current_exception;
6773
- rt->current_exception = JS_UNINITIALIZED;
6792
+ saved_exception = JS_GetException(ctx);
6774
6793
if (stack_trace_limit == 0)
6775
6794
goto done;
6776
6795
if (filename)
@@ -6894,8 +6913,7 @@ static void build_backtrace(JSContext *ctx, JSValue error_val, JSValue filter_fu
6894
6913
else
6895
6914
stack = stack2;
6896
6915
JS_FreeValue(ctx, prepare);
6897
- JS_FreeValue(ctx, rt->current_exception);
6898
- rt->current_exception = saved_exception;
6916
+ JS_Throw(ctx, saved_exception);
6899
6917
} else {
6900
6918
if (dbuf_error(&dbuf))
6901
6919
stack = JS_NULL;
@@ -6904,7 +6922,6 @@ static void build_backtrace(JSContext *ctx, JSValue error_val, JSValue filter_fu
6904
6922
dbuf_free(&dbuf);
6905
6923
}
6906
6924
6907
- rt->in_prepare_stack_trace = false;
6908
6925
if (JS_IsUndefined(ctx->error_back_trace))
6909
6926
ctx->error_back_trace = js_dup(stack);
6910
6927
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
6913
6930
} else {
6914
6931
JS_FreeValue(ctx, stack);
6915
6932
}
6933
+
6934
+ rt->in_build_stack_trace = false;
6916
6935
}
6917
6936
6918
6937
JSValue JS_NewError(JSContext *ctx)
@@ -38154,23 +38173,14 @@ static JSValue js_error_get_stackTraceLimit(JSContext *ctx, JSValue this_val)
38154
38173
if (JS_IsException(val))
38155
38174
return val;
38156
38175
JS_FreeValue(ctx, val);
38157
- return js_int32 (ctx->error_stack_trace_limit);
38176
+ return js_dup (ctx->error_stack_trace_limit);
38158
38177
}
38159
38178
38160
38179
static JSValue js_error_set_stackTraceLimit(JSContext *ctx, JSValue this_val, JSValue value)
38161
38180
{
38162
38181
if (JS_IsUndefined(this_val) || JS_IsNull(this_val))
38163
38182
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);
38174
38184
return JS_UNDEFINED;
38175
38185
}
38176
38186
0 commit comments