@@ -381,6 +381,37 @@ static JSValue js_quickjsrb_call_global(JSContext *ctx, JSValueConst _this, int
381
381
}
382
382
}
383
383
384
+ static JSValue js_delay_and_eval_job (JSContext * ctx , int argc , JSValueConst * argv )
385
+ {
386
+ VALUE rb_delay_msec = to_rb_value (ctx , argv [1 ]);
387
+ VALUE rb_delay_sec = rb_funcall (rb_delay_msec , rb_intern ("/" ), 1 , rb_float_new (1000 ));
388
+ rb_thread_wait_for (rb_time_interval (rb_delay_sec ));
389
+ JS_Call (ctx , argv [0 ], JS_UNDEFINED , 0 , NULL );
390
+
391
+ return JS_UNDEFINED ;
392
+ }
393
+
394
+ static JSValue js_quickjsrb_set_timeout (JSContext * ctx , JSValueConst _this , int argc , JSValueConst * argv )
395
+ {
396
+ JSValueConst func ;
397
+ int64_t delay ;
398
+
399
+ func = argv [0 ];
400
+ if (!JS_IsFunction (ctx , func ))
401
+ return JS_ThrowTypeError (ctx , "not a function" );
402
+ if (JS_ToInt64 (ctx , & delay , argv [1 ])) // TODO: should be lower than global timeout
403
+ return JS_EXCEPTION ;
404
+
405
+ JSValueConst args [2 ];
406
+ args [0 ] = func ;
407
+ args [1 ] = argv [1 ]; // delay
408
+ // TODO: implement timer manager and poll with quickjs' queue
409
+ // Currently, queueing multiple js_delay_and_eval_job is not parallelized
410
+ JS_EnqueueJob (ctx , js_delay_and_eval_job , 2 , args );
411
+
412
+ return JS_UNDEFINED ;
413
+ }
414
+
384
415
static JSValue js_quickjsrb_log (JSContext * ctx , JSValueConst _this , int argc , JSValueConst * argv , const char * severity )
385
416
{
386
417
VMData * data = JS_GetContextOpaque (ctx );
@@ -492,6 +523,8 @@ static VALUE vm_m_initialize(int argc, VALUE *argv, VALUE r_self)
492
523
JS_SetModuleLoaderFunc (runtime , NULL , js_module_loader , NULL );
493
524
js_std_init_handlers (runtime );
494
525
526
+ JSValue j_global = JS_GetGlobalObject (data -> context );
527
+
495
528
if (RTEST (rb_funcall (r_features , rb_intern ("include?" ), 1 , QUICKJSRB_SYM (featureStdId ))))
496
529
{
497
530
js_init_module_std (data -> context , "std" );
@@ -524,6 +557,12 @@ static VALUE vm_m_initialize(int argc, VALUE *argv, VALUE r_self)
524
557
free (enableTimeout );
525
558
JS_FreeValue (data -> context , j_timeoutEval );
526
559
}
560
+ else if (RTEST (rb_funcall (r_features , rb_intern ("include?" ), 1 , QUICKJSRB_SYM (featureOsTimeoutBetaId ))))
561
+ {
562
+ JS_SetPropertyStr (
563
+ data -> context , j_global , "setTimeout" ,
564
+ JS_NewCFunction (data -> context , js_quickjsrb_set_timeout , "setTimeout" , 2 ));
565
+ }
527
566
528
567
if (RTEST (rb_funcall (r_features , rb_intern ("include?" ), 1 , QUICKJSRB_SYM (featurePolyfillIntlId ))))
529
568
{
@@ -553,7 +592,6 @@ static VALUE vm_m_initialize(int argc, VALUE *argv, VALUE r_self)
553
592
data -> context , j_console , "error" ,
554
593
JS_NewCFunction (data -> context , js_console_error , "error" , 1 ));
555
594
556
- JSValue j_global = JS_GetGlobalObject (data -> context );
557
595
JS_SetPropertyStr (data -> context , j_global , "console" , j_console );
558
596
JS_FreeValue (data -> context , j_global );
559
597
0 commit comments