@@ -153,6 +153,7 @@ typedef struct JSThreadState {
153
153
struct list_head port_list ; /* list of JSWorkerMessageHandler.link */
154
154
int eval_script_recurse ; /* only used in the main thread */
155
155
int64_t next_timer_id ; /* for setTimeout / setInterval */
156
+ JSValue exc ; /* current exception from one of our handlers */
156
157
/* not used in the main thread */
157
158
JSWorkerMessagePipe * recv_pipe , * send_pipe ;
158
159
} JSThreadState ;
@@ -2133,51 +2134,61 @@ static JSValue js_os_sleepAsync(JSContext *ctx, JSValueConst this_val,
2133
2134
return promise ;
2134
2135
}
2135
2136
2136
- static void call_handler (JSContext * ctx , JSValue func )
2137
+ static int call_handler (JSContext * ctx , JSValue func )
2137
2138
{
2139
+ int r ;
2138
2140
JSValue ret , func1 ;
2139
2141
/* 'func' might be destroyed when calling itself (if it frees the
2140
2142
handler), so must take extra care */
2141
2143
func1 = JS_DupValue (ctx , func );
2142
2144
ret = JS_Call (ctx , func1 , JS_UNDEFINED , 0 , NULL );
2143
2145
JS_FreeValue (ctx , func1 );
2144
- if (JS_IsException (ret ))
2145
- js_std_dump_error (ctx );
2146
+ r = 0 ;
2147
+ if (JS_IsException (ret )) {
2148
+ JSRuntime * rt = JS_GetRuntime (ctx );
2149
+ JSThreadState * ts = JS_GetRuntimeOpaque (rt );
2150
+ ts -> exc = JS_GetException (ctx );
2151
+ r = -1 ;
2152
+ }
2146
2153
JS_FreeValue (ctx , ret );
2154
+ return r ;
2147
2155
}
2148
2156
2149
- static int js_os_run_timers (JSRuntime * rt , JSContext * ctx , JSThreadState * ts )
2157
+ static int js_os_run_timers (JSRuntime * rt , JSContext * ctx , JSThreadState * ts , int * min_delay )
2150
2158
{
2151
2159
JSValue func ;
2152
2160
JSOSTimer * th ;
2153
- int min_delay ;
2154
2161
int64_t cur_time , delay ;
2155
2162
struct list_head * el ;
2163
+ int r ;
2156
2164
2157
- if (list_empty (& ts -> os_timers ))
2158
- return -1 ;
2165
+ if (list_empty (& ts -> os_timers )) {
2166
+ * min_delay = -1 ;
2167
+ return 0 ;
2168
+ }
2159
2169
2160
2170
cur_time = js__hrtime_ms ();
2161
- min_delay = 10000 ;
2171
+ * min_delay = INT32_MAX ;
2162
2172
2163
2173
list_for_each (el , & ts -> os_timers ) {
2164
2174
th = list_entry (el , JSOSTimer , link );
2165
2175
delay = th -> timeout - cur_time ;
2166
2176
if (delay > 0 ) {
2167
- min_delay = min_int (min_delay , delay );
2177
+ * min_delay = min_int (* min_delay , delay );
2168
2178
} else {
2179
+ * min_delay = 0 ;
2169
2180
func = JS_DupValueRT (rt , th -> func );
2170
2181
if (th -> repeats )
2171
2182
th -> timeout = cur_time + th -> delay ;
2172
2183
else
2173
2184
free_timer (rt , th );
2174
- call_handler (ctx , func );
2185
+ r = call_handler (ctx , func );
2175
2186
JS_FreeValueRT (rt , func );
2176
- return 0 ;
2187
+ return r ;
2177
2188
}
2178
2189
}
2179
2190
2180
- return min_delay ;
2191
+ return 0 ;
2181
2192
}
2182
2193
2183
2194
#if defined(_WIN32 )
@@ -2192,7 +2203,8 @@ static int js_os_poll(JSContext *ctx)
2192
2203
2193
2204
/* XXX: handle signals if useful */
2194
2205
2195
- min_delay = js_os_run_timers (rt , ctx , ts );
2206
+ if (js_os_run_timers (rt , ctx , ts , & min_delay ))
2207
+ return -1 ;
2196
2208
if (min_delay == 0 )
2197
2209
return 0 ; // expired timer
2198
2210
if (min_delay < 0 )
@@ -2221,9 +2233,8 @@ static int js_os_poll(JSContext *ctx)
2221
2233
list_for_each (el , & ts -> os_rw_handlers ) {
2222
2234
rh = list_entry (el , JSOSRWHandler , link );
2223
2235
if (rh -> fd == console_fd && !JS_IsNull (rh -> rw_func [0 ])) {
2224
- call_handler (ctx , rh -> rw_func [0 ]);
2236
+ return call_handler (ctx , rh -> rw_func [0 ]);
2225
2237
/* must stop because the list may have been modified */
2226
- break ;
2227
2238
}
2228
2239
}
2229
2240
}
@@ -2332,13 +2343,13 @@ static int js_os_poll(JSContext *ctx)
2332
2343
mask = (uint64_t )1 << sh -> sig_num ;
2333
2344
if (os_pending_signals & mask ) {
2334
2345
os_pending_signals &= ~mask ;
2335
- call_handler (ctx , sh -> func );
2336
- return 0 ;
2346
+ return call_handler (ctx , sh -> func );
2337
2347
}
2338
2348
}
2339
2349
}
2340
2350
2341
- min_delay = js_os_run_timers (rt , ctx , ts );
2351
+ if (js_os_run_timers (rt , ctx , ts , & min_delay ))
2352
+ return -1 ;
2342
2353
if (min_delay == 0 )
2343
2354
return 0 ; // expired timer
2344
2355
if (min_delay < 0 )
@@ -2379,15 +2390,13 @@ static int js_os_poll(JSContext *ctx)
2379
2390
rh = list_entry (el , JSOSRWHandler , link );
2380
2391
if (!JS_IsNull (rh -> rw_func [0 ]) &&
2381
2392
FD_ISSET (rh -> fd , & rfds )) {
2382
- call_handler (ctx , rh -> rw_func [0 ]);
2393
+ return call_handler (ctx , rh -> rw_func [0 ]);
2383
2394
/* must stop because the list may have been modified */
2384
- goto done ;
2385
2395
}
2386
2396
if (!JS_IsNull (rh -> rw_func [1 ]) &&
2387
2397
FD_ISSET (rh -> fd , & wfds )) {
2388
- call_handler (ctx , rh -> rw_func [1 ]);
2398
+ return call_handler (ctx , rh -> rw_func [1 ]);
2389
2399
/* must stop because the list may have been modified */
2390
- goto done ;
2391
2400
}
2392
2401
}
2393
2402
@@ -3879,6 +3888,7 @@ void js_std_init_handlers(JSRuntime *rt)
3879
3888
init_list_head (& ts -> port_list );
3880
3889
3881
3890
ts -> next_timer_id = 1 ;
3891
+ ts -> exc = JS_UNDEFINED ;
3882
3892
3883
3893
JS_SetRuntimeOpaque (rt , ts );
3884
3894
@@ -3938,7 +3948,7 @@ static void js_dump_obj(JSContext *ctx, FILE *f, JSValue val)
3938
3948
}
3939
3949
}
3940
3950
3941
- static void js_std_dump_error1 (JSContext * ctx , JSValue exception_val )
3951
+ void js_std_dump_error1 (JSContext * ctx , JSValue exception_val )
3942
3952
{
3943
3953
JSValue val ;
3944
3954
BOOL is_error ;
@@ -3974,8 +3984,10 @@ void js_std_promise_rejection_tracker(JSContext *ctx, JSValue promise,
3974
3984
}
3975
3985
3976
3986
/* main loop which calls the user JS callbacks */
3977
- void js_std_loop (JSContext * ctx )
3987
+ JSValue js_std_loop (JSContext * ctx )
3978
3988
{
3989
+ JSRuntime * rt = JS_GetRuntime (ctx );
3990
+ JSThreadState * ts = JS_GetRuntimeOpaque (rt );
3979
3991
JSContext * ctx1 ;
3980
3992
int err ;
3981
3993
@@ -3985,7 +3997,8 @@ void js_std_loop(JSContext *ctx)
3985
3997
err = JS_ExecutePendingJob (JS_GetRuntime (ctx ), & ctx1 );
3986
3998
if (err <= 0 ) {
3987
3999
if (err < 0 ) {
3988
- js_std_dump_error (ctx1 );
4000
+ ts -> exc = JS_GetException (ctx1 );
4001
+ goto done ;
3989
4002
}
3990
4003
break ;
3991
4004
}
@@ -3994,6 +4007,8 @@ void js_std_loop(JSContext *ctx)
3994
4007
if (!os_poll_func || os_poll_func (ctx ))
3995
4008
break ;
3996
4009
}
4010
+ done :
4011
+ return ts -> exc ;
3997
4012
}
3998
4013
3999
4014
/* Wait for a promise and execute pending jobs while waiting for
0 commit comments