-
Notifications
You must be signed in to change notification settings - Fork 1k
Closed as not planned
Description
Hi,
I tried to define setInterval in quickjs-libc.c
file. The idea was that if the timer completed and the interval value was present then it would start again.
I used this resource https://www.freelists.org/post/quickjs-devel/PATCH-setInterval-not-implemented but I get this error:
TypeError: OSTimer object expected
at clearTimeout (native)
at <eval> (tests/hello.js:5)
diff --git a/quickjs-libc.c b/quickjs-libc.c
index e180dd0..600dda5 100644
--- a/quickjs-libc.c
+++ b/quickjs-libc.c
@@ -91,6 +91,7 @@ typedef struct {
struct list_head link;
BOOL has_object;
int64_t timeout;
+ int64_t interval;
JSValue func;
} JSOSTimer;
@@ -2040,6 +2041,7 @@ static JSValue js_os_setTimeout(JSContext *ctx, JSValueConst this_val,
}
th->has_object = TRUE;
th->timeout = get_time_ms() + delay;
+ th->interval = 0;
th->func = JS_DupValue(ctx, func);
list_add_tail(&th->link, &ts->os_timers);
JS_SetOpaque(obj, th);
@@ -2056,6 +2058,44 @@ static JSValue js_os_clearTimeout(JSContext *ctx, JSValueConst this_val,
return JS_UNDEFINED;
}
+ // !!! Same as setTimeout except for one line.
+static JSValue js_os_setInterval(JSContext *ctx, JSValueConst this_val,
+ int argc, JSValueConst *argv)
+{
+ JSRuntime *rt = JS_GetRuntime(ctx);
+ JSThreadState *ts = JS_GetRuntimeOpaque(rt);
+ int64_t delay;
+ JSValueConst func;
+ JSOSTimer *th;
+ JSValue obj;
+
+ func = argv[0];
+ if (!JS_IsFunction(ctx, func))
+ return JS_ThrowTypeError(ctx, "not a function");
+ if (JS_ToInt64(ctx, &delay, argv[1]))
+ return JS_EXCEPTION;
+ obj = JS_NewObjectClass(ctx, js_os_timer_class_id);
+ if (JS_IsException(obj))
+ return obj;
+ th = js_mallocz(ctx, sizeof(*th));
+ if (!th) {
+ JS_FreeValue(ctx, obj);
+ return JS_EXCEPTION;
+ }
+ th->has_object = TRUE;
+ th->timeout = get_time_ms() + delay;
+ th->interval = delay; // <--- The line that is different.
+ th->func = JS_DupValue(ctx, func);
+ list_add_tail(&th->link, &ts->os_timers);
+ JS_SetOpaque(obj, th);
+ return obj;
+}
+
static JSClassDef js_os_timer_class = {
"OSTimer",
.finalizer = js_os_timer_finalizer,
@@ -2102,20 +2142,25 @@ static int js_os_poll(JSContext *ctx)
JSValue func;
/* the timer expired */
func = th->func;
- th->func = JS_UNDEFINED;
- unlink_timer(rt, th);
- if (!th->has_object)
- free_timer(rt, th);
- call_handler(ctx, func);
- JS_FreeValue(ctx, func);
- return 0;
- } else if (delay < min_delay) {
- min_delay = delay;
- }
- }
- } else {
- min_delay = -1;
- }
+ if (th->interval > 0) {
+ th->timeout = cur_time + th->interval;
+ call_handler(ctx, func);
+ } else {
+ th->func = JS_UNDEFINED;
+ unlink_timer(rt, th);
+ if (!th->has_object)
+ free_timer(rt, th);
+ call_handler(ctx, func);
+ JS_FreeValue(ctx, func);
+ return 0;
+ }
+ } else if (delay < min_delay) {
+ min_delay = delay;
+ }
+ }
+ } else {
+ min_delay = -1;
+ }
console_fd = -1;
list_for_each(el, &ts->os_rw_handlers) {
@@ -3622,7 +3667,11 @@ static const JSCFunctionListEntry js_os_funcs[] = {
OS_FLAG(SIGTTOU),
#endif
JS_CFUNC_DEF("setTimeout", 2, js_os_setTimeout ),
+ JS_CFUNC_DEF("setInterval", 2, js_os_setInterval ),
JS_CFUNC_DEF("clearTimeout", 1, js_os_clearTimeout ),
+ JS_CFUNC_DEF("clearInterval", 1, js_os_clearTimeout ),
JS_PROP_STRING_DEF("platform", OS_PLATFORM, 0 ),
JS_CFUNC_DEF("getcwd", 0, js_os_getcwd ),
JS_CFUNC_DEF("chdir", 0, js_os_chdir ),
Metadata
Metadata
Assignees
Labels
No labels