mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 915613 - Introduce a mechanism to get a default context for a runtime, and use that in js-ctypes. r=jorendorff
This causes us to use the SafeJSContext on main thread, and the singleton JSContext on workers. I opted for the slightly-heavier-weight dynamic callback, rather than just setting it as a member on the runtime, because we like to delay the creation of the SafeJSContext a bit, so I didn't want to spin it up right when we spin up the runtime.
This commit is contained in:
parent
b1772a3a73
commit
986a60874a
@ -164,7 +164,6 @@ namespace CType {
|
||||
|
||||
static void Trace(JSTracer* trc, JSObject* obj);
|
||||
static void Finalize(JSFreeOp *fop, JSObject* obj);
|
||||
static void FinalizeProtoClass(JSFreeOp *fop, JSObject* obj);
|
||||
|
||||
static bool PrototypeGetter(JSContext* cx, HandleObject obj, HandleId idval,
|
||||
MutableHandleValue vp);
|
||||
@ -468,7 +467,7 @@ static const JSClass sCTypeProtoClass = {
|
||||
"CType",
|
||||
JSCLASS_HAS_RESERVED_SLOTS(CTYPEPROTO_SLOTS),
|
||||
JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, CType::FinalizeProtoClass,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL,
|
||||
NULL, ConstructAbstract, NULL, ConstructAbstract
|
||||
};
|
||||
|
||||
@ -3293,22 +3292,6 @@ CType::Finalize(JSFreeOp *fop, JSObject* obj)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CType::FinalizeProtoClass(JSFreeOp *fop, JSObject* obj)
|
||||
{
|
||||
// Finalize the CTypeProto class. The only important bit here is our
|
||||
// SLOT_CLOSURECX -- it contains the JSContext that was (lazily) instantiated
|
||||
// for use with FunctionType closures. And if we're here, in this finalizer,
|
||||
// we're guaranteed to not need it anymore. Note that this slot will only
|
||||
// be set for the object (of class CTypeProto) ctypes.FunctionType.prototype.
|
||||
jsval slot = JS_GetReservedSlot(obj, SLOT_CLOSURECX);
|
||||
if (JSVAL_IS_VOID(slot))
|
||||
return;
|
||||
|
||||
JSContext* closureCx = static_cast<JSContext*>(JSVAL_TO_PRIVATE(slot));
|
||||
JS_DestroyContextNoGC(closureCx);
|
||||
}
|
||||
|
||||
void
|
||||
CType::Trace(JSTracer* trc, JSObject* obj)
|
||||
{
|
||||
@ -6005,23 +5988,7 @@ CClosure::Create(JSContext* cx,
|
||||
JS_ASSERT(CType::IsCTypeProto(proto));
|
||||
|
||||
// Get a JSContext for use with the closure.
|
||||
jsval slot = JS_GetReservedSlot(proto, SLOT_CLOSURECX);
|
||||
if (!JSVAL_IS_VOID(slot)) {
|
||||
// Use the existing JSContext.
|
||||
cinfo->cx = static_cast<JSContext*>(JSVAL_TO_PRIVATE(slot));
|
||||
JS_ASSERT(cinfo->cx);
|
||||
} else {
|
||||
// Lazily instantiate a new JSContext, and stash it on
|
||||
// ctypes.FunctionType.prototype.
|
||||
JSRuntime* runtime = JS_GetRuntime(cx);
|
||||
cinfo->cx = JS_NewContext(runtime, 8192);
|
||||
if (!cinfo->cx) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JS_SetReservedSlot(proto, SLOT_CLOSURECX, PRIVATE_TO_JSVAL(cinfo->cx));
|
||||
}
|
||||
cinfo->cx = js::DefaultJSContext(JS_GetRuntime(cx));
|
||||
|
||||
// Prepare the error sentinel value. It's important to do this now, because
|
||||
// we might be unable to convert the value to the proper type. If so, we want
|
||||
|
@ -335,7 +335,6 @@ enum CTypeProtoSlot {
|
||||
SLOT_UINT64PROTO = 10, // ctypes.UInt64.prototype object
|
||||
SLOT_CTYPES = 11, // ctypes object
|
||||
SLOT_OURDATAPROTO = 12, // the data prototype corresponding to this object
|
||||
SLOT_CLOSURECX = 13, // JSContext for use with FunctionType closures
|
||||
CTYPEPROTO_SLOTS
|
||||
};
|
||||
|
||||
|
@ -1068,6 +1068,24 @@ js::detail::IdMatchesAtom(jsid id, JSAtom *atom)
|
||||
return id == INTERNED_STRING_TO_JSID(NULL, atom);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSContext *)
|
||||
js::DefaultJSContext(JSRuntime *rt)
|
||||
{
|
||||
if (rt->defaultJSContextCallback) {
|
||||
JSContext *cx = rt->defaultJSContextCallback(rt);
|
||||
JS_ASSERT(cx);
|
||||
return cx;
|
||||
}
|
||||
JS_ASSERT(rt->contextList.getFirst() == rt->contextList.getLast());
|
||||
return rt->contextList.getFirst();
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js::SetDefaultJSContextCallback(JSRuntime *rt, DefaultJSContextCallback cb)
|
||||
{
|
||||
rt->defaultJSContextCallback = cb;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js::SetCTypesActivityCallback(JSRuntime *rt, CTypesActivityCallback cb)
|
||||
{
|
||||
|
@ -1507,6 +1507,20 @@ IsReadOnlyDateMethod(JS::IsAcceptableThis test, JS::NativeImpl method);
|
||||
extern JS_FRIEND_API(bool)
|
||||
IsTypedArrayThisCheck(JS::IsAcceptableThis test);
|
||||
|
||||
/*
|
||||
* If the embedder has registered a default JSContext callback, returns the
|
||||
* result of the callback. Otherwise, asserts that |rt| has exactly one
|
||||
* JSContext associated with it, and returns that context.
|
||||
*/
|
||||
extern JS_FRIEND_API(JSContext *)
|
||||
DefaultJSContext(JSRuntime *rt);
|
||||
|
||||
typedef JSContext*
|
||||
(* DefaultJSContextCallback)(JSRuntime *rt);
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
SetDefaultJSContextCallback(JSRuntime *rt, DefaultJSContextCallback cb);
|
||||
|
||||
enum CTypesActivityType {
|
||||
CTYPES_CALL_BEGIN,
|
||||
CTYPES_CALL_END,
|
||||
|
@ -272,6 +272,7 @@ JSRuntime::JSRuntime(JSUseHelperThreads useHelperThreads)
|
||||
jitSupportsFloatingPoint(false),
|
||||
ionPcScriptCache(NULL),
|
||||
threadPool(this),
|
||||
defaultJSContextCallback(NULL),
|
||||
ctypesActivityCallback(NULL),
|
||||
parallelWarmup(0),
|
||||
ionReturnOverride_(MagicValue(JS_ARG_POISON)),
|
||||
|
@ -1478,6 +1478,8 @@ struct JSRuntime : public JS::shadow::Runtime,
|
||||
|
||||
js::ThreadPool threadPool;
|
||||
|
||||
js::DefaultJSContextCallback defaultJSContextCallback;
|
||||
|
||||
js::CTypesActivityCallback ctypesActivityCallback;
|
||||
|
||||
// Non-zero if this is a parallel warmup execution. See
|
||||
|
@ -1209,7 +1209,15 @@ xpc::SimulateActivityCallback(bool aActive)
|
||||
XPCJSRuntime::ActivityCallback(XPCJSRuntime::Get(), aActive);
|
||||
}
|
||||
|
||||
//static
|
||||
// static
|
||||
JSContext*
|
||||
XPCJSRuntime::DefaultJSContextCallback(JSRuntime *rt)
|
||||
{
|
||||
MOZ_ASSERT(rt == Get()->Runtime());
|
||||
return Get()->GetJSContextStack()->GetSafeJSContext();
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
XPCJSRuntime::ActivityCallback(void *arg, bool active)
|
||||
{
|
||||
@ -3019,6 +3027,7 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
|
||||
stack->sampleRuntime(runtime);
|
||||
#endif
|
||||
JS_SetAccumulateTelemetryCallback(runtime, AccumulateTelemetryCallback);
|
||||
js::SetDefaultJSContextCallback(runtime, DefaultJSContextCallback);
|
||||
js::SetActivityCallback(runtime, ActivityCallback, this);
|
||||
js::SetCTypesActivityCallback(runtime, CTypesActivityCallback);
|
||||
JS_SetOperationCallback(runtime, OperationCallback);
|
||||
|
@ -764,6 +764,7 @@ public:
|
||||
void AddContextCallback(xpcContextCallback cb);
|
||||
void RemoveContextCallback(xpcContextCallback cb);
|
||||
|
||||
static JSContext* DefaultJSContextCallback(JSRuntime *rt);
|
||||
static void ActivityCallback(void *arg, bool active);
|
||||
static void CTypesActivityCallback(JSContext *cx,
|
||||
js::CTypesActivityType type);
|
||||
|
Loading…
Reference in New Issue
Block a user