зеркало из 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_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_PUBLIC_API(JSContext *)
|
||||||
JS_NewContext(JSRuntime *rt, size_t stackChunkSize)
|
JS_NewContext(JSRuntime *rt, size_t stackChunkSize)
|
||||||
{
|
{
|
||||||
|
@ -939,19 +949,19 @@ JS_NewContext(JSRuntime *rt, size_t stackChunkSize)
|
||||||
JS_PUBLIC_API(void)
|
JS_PUBLIC_API(void)
|
||||||
JS_DestroyContext(JSContext *cx)
|
JS_DestroyContext(JSContext *cx)
|
||||||
{
|
{
|
||||||
js_DestroyContext(cx, JS_FORCE_GC);
|
js_DestroyContext(cx, JSDCM_FORCE_GC);
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_PUBLIC_API(void)
|
JS_PUBLIC_API(void)
|
||||||
JS_DestroyContextNoGC(JSContext *cx)
|
JS_DestroyContextNoGC(JSContext *cx)
|
||||||
{
|
{
|
||||||
js_DestroyContext(cx, JS_NO_GC);
|
js_DestroyContext(cx, JSDCM_NO_GC);
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_PUBLIC_API(void)
|
JS_PUBLIC_API(void)
|
||||||
JS_DestroyContextMaybeGC(JSContext *cx)
|
JS_DestroyContextMaybeGC(JSContext *cx)
|
||||||
{
|
{
|
||||||
js_DestroyContext(cx, JS_MAYBE_GC);
|
js_DestroyContext(cx, JSDCM_MAYBE_GC);
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_PUBLIC_API(void *)
|
JS_PUBLIC_API(void *)
|
||||||
|
|
|
@ -437,6 +437,9 @@ JS_Lock(JSRuntime *rt);
|
||||||
extern JS_PUBLIC_API(void)
|
extern JS_PUBLIC_API(void)
|
||||||
JS_Unlock(JSRuntime *rt);
|
JS_Unlock(JSRuntime *rt);
|
||||||
|
|
||||||
|
extern JS_PUBLIC_API(JSContextCallback)
|
||||||
|
JS_SetContextCallback(JSRuntime *rt, JSContextCallback cxCallback);
|
||||||
|
|
||||||
extern JS_PUBLIC_API(JSContext *)
|
extern JS_PUBLIC_API(JSContext *)
|
||||||
JS_NewContext(JSRuntime *rt, size_t stackChunkSize);
|
JS_NewContext(JSRuntime *rt, size_t stackChunkSize);
|
||||||
|
|
||||||
|
|
|
@ -168,6 +168,7 @@ js_NewContext(JSRuntime *rt, size_t stackChunkSize)
|
||||||
{
|
{
|
||||||
JSContext *cx;
|
JSContext *cx;
|
||||||
JSBool ok, first;
|
JSBool ok, first;
|
||||||
|
JSContextCallback cxCallback;
|
||||||
|
|
||||||
cx = (JSContext *) malloc(sizeof *cx);
|
cx = (JSContext *) malloc(sizeof *cx);
|
||||||
if (!cx)
|
if (!cx)
|
||||||
|
@ -214,7 +215,7 @@ js_NewContext(JSRuntime *rt, size_t stackChunkSize)
|
||||||
JS_InitArenaPool(&cx->tempPool, "temp", 1024, sizeof(jsdouble));
|
JS_InitArenaPool(&cx->tempPool, "temp", 1024, sizeof(jsdouble));
|
||||||
|
|
||||||
if (!js_InitRegExpStatics(cx, &cx->regExpStatics)) {
|
if (!js_InitRegExpStatics(cx, &cx->regExpStatics)) {
|
||||||
js_DestroyContext(cx, JS_NO_GC);
|
js_DestroyContext(cx, JSDCM_NEW_FAILED);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,7 +251,7 @@ js_NewContext(JSRuntime *rt, size_t stackChunkSize)
|
||||||
JS_EndRequest(cx);
|
JS_EndRequest(cx);
|
||||||
#endif
|
#endif
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
js_DestroyContext(cx, JS_NO_GC);
|
js_DestroyContext(cx, JSDCM_NEW_FAILED);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,13 +261,19 @@ js_NewContext(JSRuntime *rt, size_t stackChunkSize)
|
||||||
JS_UNLOCK_GC(rt);
|
JS_UNLOCK_GC(rt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cxCallback = rt->cxCallback;
|
||||||
|
if (cxCallback && !cxCallback(cx, JSCONTEXT_NEW)) {
|
||||||
|
js_DestroyContext(cx, JSDCM_NEW_FAILED);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
return cx;
|
return cx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
js_DestroyContext(JSContext *cx, JSGCMode gcmode)
|
js_DestroyContext(JSContext *cx, JSDestroyContextMode mode)
|
||||||
{
|
{
|
||||||
JSRuntime *rt;
|
JSRuntime *rt;
|
||||||
|
JSContextCallback cxCallback;
|
||||||
JSBool last;
|
JSBool last;
|
||||||
JSArgumentFormatMap *map;
|
JSArgumentFormatMap *map;
|
||||||
JSLocalRootStack *lrs;
|
JSLocalRootStack *lrs;
|
||||||
|
@ -274,6 +281,21 @@ js_DestroyContext(JSContext *cx, JSGCMode gcmode)
|
||||||
|
|
||||||
rt = cx->runtime;
|
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. */
|
/* Remove cx from context list first. */
|
||||||
JS_LOCK_GC(rt);
|
JS_LOCK_GC(rt);
|
||||||
JS_ASSERT(rt->state == JSRTS_UP || rt->state == JSRTS_LAUNCHING);
|
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_NOTIFY_ALL_CONDVAR(rt->stateChange);
|
||||||
JS_UNLOCK_GC(rt);
|
JS_UNLOCK_GC(rt);
|
||||||
} else {
|
} else {
|
||||||
if (gcmode == JS_FORCE_GC)
|
if (mode == JSDCM_FORCE_GC)
|
||||||
js_ForceGC(cx, 0);
|
js_ForceGC(cx, 0);
|
||||||
else if (gcmode == JS_MAYBE_GC)
|
else if (mode == JSDCM_MAYBE_GC)
|
||||||
JS_MaybeGC(cx);
|
JS_MaybeGC(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,12 @@ js_GetCurrentThread(JSRuntime *rt);
|
||||||
|
|
||||||
#endif /* JS_THREADSAFE */
|
#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 {
|
typedef enum JSRuntimeState {
|
||||||
JSRTS_DOWN,
|
JSRTS_DOWN,
|
||||||
|
@ -117,6 +122,9 @@ struct JSRuntime {
|
||||||
/* Runtime state, synchronized by the stateChange/gcLock condvar/lock. */
|
/* Runtime state, synchronized by the stateChange/gcLock condvar/lock. */
|
||||||
JSRuntimeState state;
|
JSRuntimeState state;
|
||||||
|
|
||||||
|
/* Context create/destroy callback. */
|
||||||
|
JSContextCallback cxCallback;
|
||||||
|
|
||||||
/* Garbage collector state, used by jsgc.c. */
|
/* Garbage collector state, used by jsgc.c. */
|
||||||
JSGCArenaList gcArenaList[GC_NUM_FREELISTS];
|
JSGCArenaList gcArenaList[GC_NUM_FREELISTS];
|
||||||
JSDHashTable gcRootsHash;
|
JSDHashTable gcRootsHash;
|
||||||
|
@ -735,7 +743,7 @@ extern JSContext *
|
||||||
js_NewContext(JSRuntime *rt, size_t stackChunkSize);
|
js_NewContext(JSRuntime *rt, size_t stackChunkSize);
|
||||||
|
|
||||||
extern void
|
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.
|
* Return true if cx points to a context in rt->contextList, else return false.
|
||||||
|
|
|
@ -541,6 +541,27 @@ typedef JSBool
|
||||||
|
|
||||||
/* Callbacks and their arguments. */
|
/* 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 {
|
typedef enum JSGCStatus {
|
||||||
JSGC_BEGIN,
|
JSGC_BEGIN,
|
||||||
JSGC_END,
|
JSGC_END,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче