diff --git a/src/sbbs3/js_global.c b/src/sbbs3/js_global.c index d0fd4297f4cfbbfd75e0e3a011f10ff1072968c5..fffad2fa624514f9ad97bb6c64af94d8ac65b6b9 100644 --- a/src/sbbs3/js_global.c +++ b/src/sbbs3/js_global.c @@ -52,14 +52,6 @@ #ifdef JAVASCRIPT -typedef struct { - scfg_t* cfg; - jsSyncMethodSpec* methods; - js_startup_t* startup; - unsigned bg_count; - sem_t bg_sem; -} private_t; - /* Global Object Properites */ enum { GLOB_PROP_ERRNO @@ -241,12 +233,12 @@ static jsval* js_CopyValue(JSContext* cx, jsrefcount *cx_rc, jsval val, JSContex JSBool BGContextCallback(JSContext *cx, uintN contextOp) { JSObject *gl=JS_GetGlobalObject(cx); - private_t* p; + global_private_t* p; if(!gl) return JS_TRUE; - if((p=(private_t*)JS_GetPrivate(cx,gl))==NULL) + if((p=(global_private_t*)JS_GetPrivate(cx,gl))==NULL) return(JS_TRUE); switch(contextOp) { @@ -275,7 +267,7 @@ js_load(JSContext *cx, uintN argc, jsval *arglist) uintN argn=0; char* filename; JSObject* script; - private_t* p; + global_private_t* p; jsval val; JSObject* js_argv; JSObject* exec_obj; @@ -289,7 +281,7 @@ js_load(JSContext *cx, uintN argc, jsval *arglist) JS_SET_RVAL(cx, arglist,JSVAL_VOID); - if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) + if((p=(global_private_t*)JS_GetPrivate(cx,obj))==NULL) return(JS_FALSE); exec_obj=JS_GetScopeChain(cx); @@ -353,6 +345,7 @@ js_load(JSContext *cx, uintN argc, jsval *arglist) } if((bg->logobj=JS_NewObjectWithGivenProto(bg->cx, NULL, NULL, bg->obj))==NULL) { + JS_RemoveObjectRoot(bg->cx, &bg->obj); JS_ENDREQUEST(bg->cx); JS_DestroyContext(bg->cx); jsrt_Release(bg->runtime); @@ -1412,7 +1405,7 @@ js_html_encode(JSContext *cx, uintN argc, jsval *arglist) struct tm tm; time_t now; BOOL nodisplay=FALSE; - private_t* p; + global_private_t* p; uchar attr_stack[64]; /* Saved attributes (stack) */ int attr_sp=0; /* Attribute stack pointer */ ulong clear_screen=0; @@ -1425,7 +1418,7 @@ js_html_encode(JSContext *cx, uintN argc, jsval *arglist) if(argc==0 || JSVAL_IS_VOID(argv[0])) return(JS_TRUE); - if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) /* Will this work? Ask DM */ + if((p=(global_private_t*)JS_GetPrivate(cx,obj))==NULL) /* Will this work? Ask DM */ return(JS_FALSE); JSVALUE_TO_STRING(cx, argv[0], inbuf, NULL); @@ -3924,9 +3917,9 @@ static jsConstIntSpec js_global_const_ints[] = { static void js_global_finalize(JSContext *cx, JSObject *obj) { - private_t* p; + global_private_t* p; - p=(private_t*)JS_GetPrivate(cx,obj); + p=(global_private_t*)JS_GetPrivate(cx,obj); if(p!=NULL) free(p); @@ -3938,10 +3931,10 @@ static void js_global_finalize(JSContext *cx, JSObject *obj) static JSBool js_global_resolve(JSContext *cx, JSObject *obj, jsid id) { char* name=NULL; - private_t* p; + global_private_t* p; JSBool ret=JS_TRUE; - if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) + if((p=(global_private_t*)JS_GetPrivate(cx,obj))==NULL) return(JS_FALSE); if(id != JSID_VOID && id != JSID_EMPTY && id != JS_DEFAULT_XML_NAMESPACE_ID) { @@ -3981,14 +3974,15 @@ static JSClass js_global_class = { BOOL DLLCALL js_CreateGlobalObject(JSContext* cx, scfg_t* cfg, jsSyncMethodSpec* methods, js_startup_t* startup, JSObject**glob) { - private_t* p; + global_private_t* p; - if((p = (private_t*)malloc(sizeof(private_t)))==NULL) + if((p = (global_private_t*)malloc(sizeof(global_private_t)))==NULL) return(FALSE); p->cfg = cfg; p->methods = methods; p->startup = startup; + p->exit_func=NULL; if((*glob = JS_NewCompartmentAndGlobalObject(cx, &js_global_class, NULL)) ==NULL) return(FALSE); diff --git a/src/sbbs3/js_internal.c b/src/sbbs3/js_internal.c index d852c8196cb00a0911904a8a25f4b43c04261333..14398f7a6d94e36a2c6d72421798b976fec7fedc 100644 --- a/src/sbbs3/js_internal.c +++ b/src/sbbs3/js_internal.c @@ -372,21 +372,33 @@ js_report_error(JSContext *cx, uintN argc, jsval *arglist) static JSBool js_on_exit(JSContext *cx, uintN argc, jsval *arglist) { - JSObject *obj=JS_THIS_OBJECT(cx, arglist); + JSObject *thisobj=JS_THIS_OBJECT(cx, arglist); + JSObject *parent=JS_GetParent(cx,thisobj); + JSObject *glob=JS_GetGlobalObject(cx); jsval *argv=JS_ARGV(cx, arglist); - js_callback_t* cb; + global_private_t* pd; + str_list_t list; char *p; JS_SET_RVAL(cx, arglist, JSVAL_VOID); - if((cb=(js_callback_t*)JS_GetPrivate(cx,obj))==NULL) - return(JS_FALSE); - - if(cb->exit_func==NULL) - cb->exit_func=strListInit(); + if(thisobj==parent) { + if((pd=(global_private_t*)JS_GetPrivate(cx,glob))==NULL) + return(JS_FALSE); + if(pd->exit_func==NULL) + pd->exit_func=strListInit(); + list=pd->exit_func; + } + else { + list=(str_list_t)JS_GetPrivate(cx,parent); + if(list==NULL) { + list=strListInit(); + JS_SetPrivate(cx,parent,list); + } + } JSVALUE_TO_STRING(cx, argv[0], p, NULL); - strListPush(&cb->exit_func,p); + strListPush(&list,p); return(JS_TRUE); } @@ -473,17 +485,27 @@ void DLLCALL js_EvalOnExit(JSContext *cx, JSObject *obj, js_callback_t* cb) jsval rval; JSObject* script; BOOL auto_terminate=cb->auto_terminate; + JSObject *glob=JS_GetGlobalObject(cx); + global_private_t *pt; + str_list_t list; + + if(glob==obj) { + pt=(global_private_t *)JS_GetPrivate(cx,JS_GetGlobalObject(cx)); + list=pt->exit_func; + } + else + list=JS_GetPrivate(cx,obj); cb->auto_terminate=FALSE; - while((p=strListPop(&cb->exit_func))!=NULL) { + while((p=strListPop(&list))!=NULL) { if((script=JS_CompileScript(cx, obj, p, strlen(p), NULL, 0))!=NULL) { JS_ExecuteScript(cx, obj, script, &rval); } free(p); } - strListFree(&cb->exit_func); + strListFree(&list); if(auto_terminate) cb->auto_terminate = TRUE; diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h index 5db05a5771d7b639f800ea6d70daa96727a87044..f3a36af41c3406983dc02f772ae9137f7e1f8ba8 100644 --- a/src/sbbs3/sbbs.h +++ b/src/sbbs3/sbbs.h @@ -1045,6 +1045,14 @@ extern "C" { ,js_server_props_t* props); /* js_global.c */ + typedef struct { + scfg_t* cfg; + jsSyncMethodSpec* methods; + js_startup_t* startup; + unsigned bg_count; + sem_t bg_sem; + str_list_t exit_func; + } global_private_t; DLLEXPORT BOOL DLLCALL js_argc(JSContext *cx, uintN argc, uintN min); DLLEXPORT BOOL DLLCALL js_CreateGlobalObject(JSContext* cx, scfg_t* cfg, jsSyncMethodSpec* methods, js_startup_t*, JSObject**); DLLEXPORT BOOL DLLCALL js_CreateCommonObjects(JSContext* cx diff --git a/src/sbbs3/sbbsdefs.h b/src/sbbs3/sbbsdefs.h index 8452ce479362e19762c365b858e14986ec3a39f8..8a00bbca4467ae5255bab82c35cdb726aefd8272 100644 --- a/src/sbbs3/sbbsdefs.h +++ b/src/sbbs3/sbbsdefs.h @@ -86,7 +86,6 @@ typedef struct { ulong gc_attempts; BOOL auto_terminate; volatile BOOL* terminated; - str_list_t exit_func; } js_callback_t; #define JSVAL_NULL_OR_VOID(val) (JSVAL_IS_NULL(val) || JSVAL_IS_VOID(val))