diff --git a/src/document/document.h b/src/document/document.h index 43b350fb..b0d83a9e 100644 --- a/src/document/document.h +++ b/src/document/document.h @@ -150,6 +150,7 @@ struct timeout_data { struct ecmascript_interpreter *interpreter; unsigned char *code; timer_id_T timer; + void *object; }; #endif diff --git a/src/ecmascript/ecmascript.c b/src/ecmascript/ecmascript.c index 99315fa9..84c91147 100644 --- a/src/ecmascript/ecmascript.c +++ b/src/ecmascript/ecmascript.c @@ -333,12 +333,13 @@ ecmascript_timeout_handler(void *i) assertm(interpreter->vs->doc_view != NULL, "setTimeout: vs with no document (e_f %d)", interpreter->vs->ecmascript_fragile); - del_from_list(td); { struct string code = INIT_STRING(td->code, strlen(td->code)); + ecmascript_clear_timeout2(td); ecmascript_eval(interpreter, &code, NULL); } + del_from_list(td); mem_free(td->code); mem_free(td); } diff --git a/src/ecmascript/ecmascript.h b/src/ecmascript/ecmascript.h index 69e6e2ed..00515fa0 100644 --- a/src/ecmascript/ecmascript.h +++ b/src/ecmascript/ecmascript.h @@ -87,7 +87,8 @@ void ecmascript_timeout_dialog(struct terminal *term, int max_exec_time); void ecmascript_set_action(unsigned char **action, unsigned char *string); struct timeout_data *ecmascript_set_timeout(struct ecmascript_interpreter *interpreter, unsigned char *code, int timeout); -void ecmascript_clear_timeout(struct timeout_data *td); +void ecmascript_clear_timeout(struct timeout_data *td); /* the same for both SpiderMonkey and SEE */ +void ecmascript_clear_timeout2(struct timeout_data *td); /* engine dependent */ extern struct module ecmascript_module; diff --git a/src/ecmascript/see/window.c b/src/ecmascript/see/window.c index 3a30e63a..42df8ebe 100644 --- a/src/ecmascript/see/window.c +++ b/src/ecmascript/see/window.c @@ -350,6 +350,17 @@ end: done_uri(uri); } +void +ecmascript_clear_timeout2(struct timeout_data *td) +{ + struct timeout_class *timer = td->object; + + if (timer) { + timer->td = NULL; + td->object = NULL; + } +} + static void js_clearTimeout(struct SEE_interpreter *interp, struct SEE_object *self, struct SEE_object *thisobj, int argc, struct SEE_value **argv, @@ -360,7 +371,7 @@ js_clearTimeout(struct SEE_interpreter *interp, struct SEE_object *self, if (argc != 1) return; timer = (struct timeout_class *)argv[0]->u.object; see_check_class(interp, (struct SEE_object *)timer, &js_timeout_object_class); - ecmascript_clear_timeout(timer->td); + if (timer && timer->td) ecmascript_clear_timeout(timer->td); } @@ -384,9 +395,12 @@ js_setTimeout(struct SEE_interpreter *interp, struct SEE_object *self, timeout = SEE_ToInt32(interp, argv[1]); td = ecmascript_set_timeout(ei, code, timeout); timer = SEE_NEW(interp, struct timeout_class); - timer->object.objectclass = &js_timeout_object_class; - timer->object.Prototype = NULL; - timer->td = td; + if (timer) { + timer->object.objectclass = &js_timeout_object_class; + timer->object.Prototype = NULL; + timer->td = td; + td->object = timer; + } SEE_SET_OBJECT(res, (struct SEE_object *)timer); } diff --git a/src/ecmascript/spidermonkey/window.c b/src/ecmascript/spidermonkey/window.c index fda29101..94227445 100644 --- a/src/ecmascript/spidermonkey/window.c +++ b/src/ecmascript/spidermonkey/window.c @@ -448,18 +448,31 @@ end: static JSBool window_clearTimeout(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { - JSObject *timeout; + JSObject *timer; struct timeout_data *td; if (argc != 1) return JS_TRUE; - timeout = JSVAL_TO_OBJECT(argv[0]); - if (!JS_InstanceOf(ctx, timeout, (JSClass *) &timeout_class, NULL)) return JS_FALSE; - td = JS_GetPrivate(ctx, timeout); - ecmascript_clear_timeout(td); + timer = JSVAL_TO_OBJECT(argv[0]); + if (!JS_InstanceOf(ctx, timer, (JSClass *) &timeout_class, NULL)) return JS_FALSE; + td = JS_GetPrivate(ctx, timer); + if (td) ecmascript_clear_timeout(td); return JS_TRUE; } +void +ecmascript_clear_timeout2(struct timeout_data *td) +{ + struct ecmascript_interpreter *interpreter = td->interpreter; + JSContext *ctx = interpreter->backend_data; + JSObject *timer = td->object; + + if (timer) { + JS_SetPrivate(ctx, timer, NULL); + td->object = NULL; + } +} + /* @window_funcs{"setTimeout"} */ static JSBool window_setTimeout(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) @@ -487,7 +500,10 @@ window_setTimeout(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval } td = ecmascript_set_timeout(interpreter, code, timeout); timer = JS_NewObject(ctx, (JSClass *)&timeout_class, NULL, NULL); - JS_SetPrivate(ctx, timer, td); + if (timer) { + JS_SetPrivate(ctx, timer, td); + td->object = timer; + } object_to_jsval(ctx, rval, timer); return JS_TRUE; }