Bug 342737: New API to register JS_NewContext/JS_DestroyContext* callback. In this way an embedding can do a common customization of JSContext instances in a single place. r=brendan

This commit is contained in:
igor.bukanov%gmail.com 2006-06-27 12:09:09 +00:00
Родитель 0160424edb
Коммит d115537fbf
5 изменённых файлов: 74 добавлений и 10 удалений

Просмотреть файл

@ -930,6 +930,16 @@ JS_Unlock(JSRuntime *rt)
JS_UNLOCK_RUNTIME(rt);
}
JS_PUBLIC_API(JSContextCallback)
JS_SetContextCallback(JSRuntime *rt, JSContextCallback cxCallback)
{
JSContextCallback old;
old = rt->cxCallback;
rt->cxCallback = cxCallback;
return old;
}
JS_PUBLIC_API(JSContext *)
JS_NewContext(JSRuntime *rt, size_t stackChunkSize)
{
@ -939,19 +949,19 @@ JS_NewContext(JSRuntime *rt, size_t stackChunkSize)
JS_PUBLIC_API(void)
JS_DestroyContext(JSContext *cx)
{
js_DestroyContext(cx, JS_FORCE_GC);
js_DestroyContext(cx, JSDCM_FORCE_GC);
}
JS_PUBLIC_API(void)
JS_DestroyContextNoGC(JSContext *cx)
{
js_DestroyContext(cx, JS_NO_GC);
js_DestroyContext(cx, JSDCM_NO_GC);
}
JS_PUBLIC_API(void)
JS_DestroyContextMaybeGC(JSContext *cx)
{
js_DestroyContext(cx, JS_MAYBE_GC);
js_DestroyContext(cx, JSDCM_MAYBE_GC);
}
JS_PUBLIC_API(void *)

Просмотреть файл

@ -437,6 +437,9 @@ JS_Lock(JSRuntime *rt);
extern JS_PUBLIC_API(void)
JS_Unlock(JSRuntime *rt);
extern JS_PUBLIC_API(JSContextCallback)
JS_SetContextCallback(JSRuntime *rt, JSContextCallback cxCallback);
extern JS_PUBLIC_API(JSContext *)
JS_NewContext(JSRuntime *rt, size_t stackChunkSize);

Просмотреть файл

@ -168,6 +168,7 @@ js_NewContext(JSRuntime *rt, size_t stackChunkSize)
{
JSContext *cx;
JSBool ok, first;
JSContextCallback cxCallback;
cx = (JSContext *) malloc(sizeof *cx);
if (!cx)
@ -214,7 +215,7 @@ js_NewContext(JSRuntime *rt, size_t stackChunkSize)
JS_InitArenaPool(&cx->tempPool, "temp", 1024, sizeof(jsdouble));
if (!js_InitRegExpStatics(cx, &cx->regExpStatics)) {
js_DestroyContext(cx, JS_NO_GC);
js_DestroyContext(cx, JSDCM_NEW_FAILED);
return NULL;
}
@ -250,7 +251,7 @@ js_NewContext(JSRuntime *rt, size_t stackChunkSize)
JS_EndRequest(cx);
#endif
if (!ok) {
js_DestroyContext(cx, JS_NO_GC);
js_DestroyContext(cx, JSDCM_NEW_FAILED);
return NULL;
}
@ -260,13 +261,19 @@ js_NewContext(JSRuntime *rt, size_t stackChunkSize)
JS_UNLOCK_GC(rt);
}
cxCallback = rt->cxCallback;
if (cxCallback && !cxCallback(cx, JSCONTEXT_NEW)) {
js_DestroyContext(cx, JSDCM_NEW_FAILED);
return NULL;
}
return cx;
}
void
js_DestroyContext(JSContext *cx, JSGCMode gcmode)
js_DestroyContext(JSContext *cx, JSDestroyContextMode mode)
{
JSRuntime *rt;
JSContextCallback cxCallback;
JSBool last;
JSArgumentFormatMap *map;
JSLocalRootStack *lrs;
@ -274,6 +281,21 @@ js_DestroyContext(JSContext *cx, JSGCMode gcmode)
rt = cx->runtime;
if (mode != JSDCM_NEW_FAILED) {
cxCallback = rt->cxCallback;
if (cxCallback) {
/*
* JSCONTEXT_DESTROY callback is not allowed to fail and must
* return true.
*/
#ifdef DEBUG
JSBool callbackStatus =
#endif
cxCallback(cx, JSCONTEXT_DESTROY);
JS_ASSERT(callbackStatus);
}
}
/* Remove cx from context list first. */
JS_LOCK_GC(rt);
JS_ASSERT(rt->state == JSRTS_UP || rt->state == JSRTS_LAUNCHING);
@ -357,9 +379,9 @@ js_DestroyContext(JSContext *cx, JSGCMode gcmode)
JS_NOTIFY_ALL_CONDVAR(rt->stateChange);
JS_UNLOCK_GC(rt);
} else {
if (gcmode == JS_FORCE_GC)
if (mode == JSDCM_FORCE_GC)
js_ForceGC(cx, 0);
else if (gcmode == JS_MAYBE_GC)
else if (mode == JSDCM_MAYBE_GC)
JS_MaybeGC(cx);
}

Просмотреть файл

@ -94,7 +94,12 @@ js_GetCurrentThread(JSRuntime *rt);
#endif /* JS_THREADSAFE */
typedef enum JSGCMode { JS_NO_GC, JS_MAYBE_GC, JS_FORCE_GC } JSGCMode;
typedef enum JSDestroyContextMode {
JSDCM_NO_GC,
JSDCM_MAYBE_GC,
JSDCM_FORCE_GC,
JSDCM_NEW_FAILED
} JSDestroyContextMode;
typedef enum JSRuntimeState {
JSRTS_DOWN,
@ -117,6 +122,9 @@ struct JSRuntime {
/* Runtime state, synchronized by the stateChange/gcLock condvar/lock. */
JSRuntimeState state;
/* Context create/destroy callback. */
JSContextCallback cxCallback;
/* Garbage collector state, used by jsgc.c. */
JSGCArenaList gcArenaList[GC_NUM_FREELISTS];
JSDHashTable gcRootsHash;
@ -735,7 +743,7 @@ extern JSContext *
js_NewContext(JSRuntime *rt, size_t stackChunkSize);
extern void
js_DestroyContext(JSContext *cx, JSGCMode gcmode);
js_DestroyContext(JSContext *cx, JSDestroyContextMode mode);
/*
* Return true if cx points to a context in rt->contextList, else return false.

Просмотреть файл

@ -541,6 +541,27 @@ typedef JSBool
/* Callbacks and their arguments. */
typedef enum JSContextOp {
JSCONTEXT_NEW,
JSCONTEXT_DESTROY
} JSContextOp;
/*
* The possible values for contextOp when the runtime calls the callback are:
* JSCONTEXT_NEW JS_NewContext succesfully created a new JSContext
* instance. The callback can initialize the instance as
* required. If the callback returns false, the instance
* will be destroyed and JS_NewContext returns null. In
* this case the callback is not called again.
* JSCONTEXT_DESTROY One of JS_DestroyContext* methods is called. The
* callback may perform its own cleanup and must always
* return true.
* Any other value For future compatibility the callback must do nothing
* and return true in this case.
*/
typedef JSBool
(* JS_DLL_CALLBACK JSContextCallback)(JSContext *cx, uintN contextOp);
typedef enum JSGCStatus {
JSGC_BEGIN,
JSGC_END,