Skip to content

Help for setInterval #186

@cemalgnlts

Description

@cemalgnlts

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

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions