diff --git a/src/sbbs3/js_global.c b/src/sbbs3/js_global.c index ca455b0e0ce10c74c7e9d61ee2f11ef83929d1b2..c7287a9df5cfc1e1b5905371a69f7afcd38abc54 100644 --- a/src/sbbs3/js_global.c +++ b/src/sbbs3/js_global.c @@ -255,6 +255,7 @@ js_load(JSContext *cx, uintN argc, jsval *arglist) jsval val; JSObject* js_argv; JSObject* exec_obj; + JSObject* js_internal; JSContext* exec_cx=cx; JSBool success; JSBool background=JS_FALSE; @@ -291,6 +292,19 @@ js_load(JSContext *cx, uintN argc, jsval *arglist) bg->cb.terminated=NULL; /* could be bad pointer at any time */ bg->cb.counter=0; bg->cb.gc_attempts=0; + bg->cb.bg = TRUE; + + // Get the js.internal private data since it's the parents js_callback_t... + if(JS_GetProperty(cx, JS_GetGlobalObject(cx), "js", &val) && !JSVAL_NULL_OR_VOID(val)) { + js_internal = JSVAL_TO_OBJECT(val); + bg->cb.parent_cb = (js_callback_t*)JS_GetPrivate(cx,js_internal); + if (bg->cb.parent_cb == NULL) { + lprintf(LOG_ERR, "!ERROR parent CB is NULL"); + } + } + else { + lprintf(LOG_ERR, "!ERROR unabled to locate global js object"); + } if((bg->runtime = jsrt_GetNew(JAVASCRIPT_MAX_BYTES, 1000, __FILE__, __LINE__))==NULL) { free(bg); diff --git a/src/sbbs3/js_internal.c b/src/sbbs3/js_internal.c index e890d3c53fd792b9983b07858a7567b4ad83a015..6ca4bda482f8a128c94df73348bbe4b42bed45ba 100644 --- a/src/sbbs3/js_internal.c +++ b/src/sbbs3/js_internal.c @@ -64,6 +64,7 @@ static JSBool js_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp) jsval idval; jsint tiny; js_callback_t* cb; + js_callback_t* top_cb; if((cb=(js_callback_t*)JS_GetPrivate(cx,obj))==NULL) return(JS_FALSE); @@ -76,10 +77,16 @@ static JSBool js_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp) *vp=STRING_TO_JSVAL(JS_NewStringCopyZ(cx,(char *)JS_GetImplementationVersion())); break; case PROP_TERMINATED: - if(cb->terminated==NULL) + for(top_cb=cb; top_cb->bg && top_cb->parent_cb; top_cb=top_cb->parent_cb) { + if(top_cb->terminated && *top_cb->terminated) { + *vp=BOOLEAN_TO_JSVAL(TRUE); + return JS_TRUE; + } + } + if(top_cb->terminated==NULL) *vp=JSVAL_FALSE; else - *vp=BOOLEAN_TO_JSVAL(*cb->terminated); + *vp=BOOLEAN_TO_JSVAL(*top_cb->terminated); break; case PROP_AUTO_TERMINATE: *vp=BOOLEAN_TO_JSVAL(cb->auto_terminate); @@ -231,14 +238,19 @@ static char* prop_desc[] = { JSBool DLLCALL js_CommonOperationCallback(JSContext *cx, js_callback_t* cb) { + js_callback_t *top_cb; + cb->counter++; /* Terminated? */ - if(cb->auto_terminate && - (cb->terminated!=NULL && *cb->terminated)) { - JS_ReportWarning(cx,"Terminated"); - cb->counter=0; - return(JS_FALSE); + if(cb->auto_terminate) { + for(top_cb=cb; top_cb; top_cb=top_cb->parent_cb) { + if (top_cb->terminated!=NULL && *top_cb->terminated) { + JS_ReportWarning(cx,"Terminated"); + cb->counter=0; + return(JS_FALSE); + } + } } /* Infinite loop? */ diff --git a/src/sbbs3/sbbsdefs.h b/src/sbbs3/sbbsdefs.h index dd8ae213e6e697e796254cfebfad0b5de2ea9160..f19bba70b8007325676786a20380bd0002a0b1f0 100644 --- a/src/sbbs3/sbbsdefs.h +++ b/src/sbbs3/sbbsdefs.h @@ -78,7 +78,8 @@ #define JAVASCRIPT_LOAD_PATH "load" #define JAVASCRIPT_LOAD_PATH_LIST "load_path_list" -typedef struct { +struct js_callback; +typedef struct js_callback { uint32_t counter; uint32_t limit; uint32_t yield_interval; @@ -86,6 +87,8 @@ typedef struct { uint32_t gc_attempts; BOOL auto_terminate; volatile BOOL* terminated; + BOOL bg; + struct js_callback *parent_cb; } js_callback_t; #define JSVAL_NULL_OR_VOID(val) (JSVAL_IS_NULL(val) || JSVAL_IS_VOID(val))