зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
0160424edb
Коммит
d115537fbf
|
@ -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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче