зеркало из https://github.com/mozilla/pjs.git
Clean up API for creating natives with reserved slots, fix uses in CTypes and jsworkers shell, bug 697537.
This commit is contained in:
Родитель
5a1e8e571a
Коммит
f749fa5ea8
|
@ -641,7 +641,7 @@ InitTypeConstructor(JSContext* cx,
|
|||
JSObject*& typeProto,
|
||||
JSObject*& dataProto)
|
||||
{
|
||||
JSFunction* fun = JS_DefineFunction(cx, parent, spec.name, spec.call,
|
||||
JSFunction* fun = js::DefineFunctionWithReserved(cx, parent, spec.name, spec.call,
|
||||
spec.nargs, spec.flags);
|
||||
if (!fun)
|
||||
return false;
|
||||
|
@ -672,8 +672,7 @@ InitTypeConstructor(JSContext* cx,
|
|||
|
||||
// Stash ctypes.{Pointer,Array,Struct}Type.prototype on a reserved slot of
|
||||
// the type constructor, for faster lookup.
|
||||
if (!JS_SetReservedSlot(cx, obj, SLOT_FN_CTORPROTO, OBJECT_TO_JSVAL(typeProto)))
|
||||
return false;
|
||||
js::SetFunctionNativeReserved(obj, SLOT_FN_CTORPROTO, OBJECT_TO_JSVAL(typeProto));
|
||||
|
||||
// Create an object to serve as the common ancestor for all CData objects
|
||||
// created from the given type constructor. This has ctypes.CData.prototype
|
||||
|
@ -721,14 +720,18 @@ InitInt64Class(JSContext* cx,
|
|||
if (!JS_FreezeObject(cx, ctor))
|
||||
return NULL;
|
||||
|
||||
// Stash ctypes.{Int64,UInt64}.prototype on a reserved slot of the 'join'
|
||||
// function.
|
||||
jsval join;
|
||||
ASSERT_OK(JS_GetProperty(cx, ctor, "join", &join));
|
||||
if (!JS_SetReservedSlot(cx, JSVAL_TO_OBJECT(join), SLOT_FN_INT64PROTO,
|
||||
OBJECT_TO_JSVAL(prototype)))
|
||||
// Redefine the 'join' function as an extended native and stash
|
||||
// ctypes.{Int64,UInt64}.prototype in a reserved slot of the new function.
|
||||
JS_ASSERT(clasp == &sInt64ProtoClass || clasp == &sUInt64ProtoClass);
|
||||
JSNative native = (clasp == &sInt64ProtoClass) ? Int64::Join : UInt64::Join;
|
||||
JSFunction* fun = js::DefineFunctionWithReserved(cx, ctor, "join", native,
|
||||
2, CTYPESFN_FLAGS);
|
||||
if (!fun)
|
||||
return NULL;
|
||||
|
||||
js::SetFunctionNativeReserved(fun, SLOT_FN_INT64PROTO,
|
||||
OBJECT_TO_JSVAL(prototype));
|
||||
|
||||
if (!JS_FreezeObject(cx, prototype))
|
||||
return NULL;
|
||||
|
||||
|
@ -3030,8 +3033,7 @@ CType::GetProtoFromCtor(JSContext* cx, JSObject* obj, CTypeProtoSlot slot)
|
|||
{
|
||||
// Get ctypes.{Pointer,Array,Struct}Type.prototype from a reserved slot
|
||||
// on the type constructor.
|
||||
jsval protoslot;
|
||||
ASSERT_OK(JS_GetReservedSlot(cx, obj, SLOT_FN_CTORPROTO, &protoslot));
|
||||
jsval protoslot = js::GetFunctionNativeReserved(obj, SLOT_FN_CTORPROTO);
|
||||
JSObject* proto = JSVAL_TO_OBJECT(protoslot);
|
||||
JS_ASSERT(proto);
|
||||
JS_ASSERT(JS_GET_CLASS(cx, proto) == &sCTypeProtoClass);
|
||||
|
@ -6242,8 +6244,7 @@ Int64::Join(JSContext* cx, uintN argc, jsval* vp)
|
|||
// Get Int64.prototype from the function's reserved slot.
|
||||
JSObject* callee = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
|
||||
|
||||
jsval slot;
|
||||
ASSERT_OK(JS_GetReservedSlot(cx, callee, SLOT_FN_INT64PROTO, &slot));
|
||||
jsval slot = js::GetFunctionNativeReserved(callee, SLOT_FN_INT64PROTO);
|
||||
JSObject* proto = JSVAL_TO_OBJECT(slot);
|
||||
JS_ASSERT(JS_GET_CLASS(cx, proto) == &sInt64ProtoClass);
|
||||
|
||||
|
@ -6410,8 +6411,7 @@ UInt64::Join(JSContext* cx, uintN argc, jsval* vp)
|
|||
// Get UInt64.prototype from the function's reserved slot.
|
||||
JSObject* callee = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
|
||||
|
||||
jsval slot;
|
||||
ASSERT_OK(JS_GetReservedSlot(cx, callee, SLOT_FN_INT64PROTO, &slot));
|
||||
jsval slot = js::GetFunctionNativeReserved(callee, SLOT_FN_INT64PROTO);
|
||||
JSObject* proto = JSVAL_TO_OBJECT(slot);
|
||||
JS_ASSERT(JS_GET_CLASS(cx, proto) == &sUInt64ProtoClass);
|
||||
|
||||
|
|
|
@ -4290,12 +4290,7 @@ JS_NewFunctionById(JSContext *cx, JSNative native, uintN nargs, uintN flags, JSO
|
|||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, parent);
|
||||
|
||||
/* Allow natives created through this interface to use {Get,Set}FunctionNativeReserved. */
|
||||
AllocKind kind = native
|
||||
? (AllocKind) JSFunction::ExtendedFinalizeKind
|
||||
: (AllocKind) JSFunction::FinalizeKind;
|
||||
|
||||
return js_NewFunction(cx, NULL, native, nargs, flags, parent, JSID_TO_ATOM(id), kind);
|
||||
return js_NewFunction(cx, NULL, native, nargs, flags, parent, JSID_TO_ATOM(id));
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
|
|
|
@ -207,6 +207,46 @@ js::IsOriginalScriptFunction(JSFunction *fun)
|
|||
return fun->script()->function() == fun;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSFunction *)
|
||||
js::DefineFunctionWithReserved(JSContext *cx, JSObject *obj, const char *name, JSNative call,
|
||||
uintN nargs, uintN attrs)
|
||||
{
|
||||
JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj);
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name));
|
||||
if (!atom)
|
||||
return NULL;
|
||||
return js_DefineFunction(cx, obj, ATOM_TO_JSID(atom), call, nargs, attrs,
|
||||
JSFunction::ExtendedFinalizeKind);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSFunction *)
|
||||
js::NewFunctionByIdWithReserved(JSContext *cx, JSNative native, uintN nargs, uintN flags, JSObject *parent,
|
||||
jsid id)
|
||||
{
|
||||
JS_ASSERT(JSID_IS_STRING(id));
|
||||
JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, parent);
|
||||
|
||||
return js_NewFunction(cx, NULL, native, nargs, flags, parent, JSID_TO_ATOM(id),
|
||||
JSFunction::ExtendedFinalizeKind);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSObject *)
|
||||
js::InitClassWithReserved(JSContext *cx, JSObject *obj, JSObject *parent_proto,
|
||||
JSClass *clasp, JSNative constructor, uintN nargs,
|
||||
JSPropertySpec *ps, JSFunctionSpec *fs,
|
||||
JSPropertySpec *static_ps, JSFunctionSpec *static_fs)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj, parent_proto);
|
||||
return js_InitClass(cx, obj, parent_proto, Valueify(clasp), constructor,
|
||||
nargs, ps, fs, static_ps, static_fs, NULL,
|
||||
JSFunction::ExtendedFinalizeKind);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(const Value &)
|
||||
js::GetFunctionNativeReserved(JSObject *fun, size_t which)
|
||||
{
|
||||
|
|
|
@ -276,6 +276,20 @@ GetObjectGlobal(JSObject *obj);
|
|||
JS_FRIEND_API(bool)
|
||||
IsOriginalScriptFunction(JSFunction *fun);
|
||||
|
||||
JS_FRIEND_API(JSFunction *)
|
||||
DefineFunctionWithReserved(JSContext *cx, JSObject *obj, const char *name, JSNative call,
|
||||
uintN nargs, uintN attrs);
|
||||
|
||||
JS_FRIEND_API(JSFunction *)
|
||||
NewFunctionByIdWithReserved(JSContext *cx, JSNative native, uintN nargs, uintN flags,
|
||||
JSObject *parent, jsid id);
|
||||
|
||||
JS_FRIEND_API(JSObject *)
|
||||
InitClassWithReserved(JSContext *cx, JSObject *obj, JSObject *parent_proto,
|
||||
JSClass *clasp, JSNative constructor, uintN nargs,
|
||||
JSPropertySpec *ps, JSFunctionSpec *fs,
|
||||
JSPropertySpec *static_ps, JSFunctionSpec *static_fs);
|
||||
|
||||
JS_FRIEND_API(const Value &)
|
||||
GetFunctionNativeReserved(JSObject *fun, size_t which);
|
||||
|
||||
|
|
|
@ -4243,7 +4243,7 @@ DefineConstructorAndPrototype(JSContext *cx, JSObject *obj, JSProtoKey key, JSAt
|
|||
Native constructor, uintN nargs,
|
||||
JSPropertySpec *ps, JSFunctionSpec *fs,
|
||||
JSPropertySpec *static_ps, JSFunctionSpec *static_fs,
|
||||
JSObject **ctorp)
|
||||
JSObject **ctorp, AllocKind ctorKind)
|
||||
{
|
||||
/*
|
||||
* Create a prototype object for this class.
|
||||
|
@ -4316,7 +4316,8 @@ DefineConstructorAndPrototype(JSContext *cx, JSObject *obj, JSProtoKey key, JSAt
|
|||
* perhaps as part of bug 638316.)
|
||||
*/
|
||||
JSFunction *fun =
|
||||
js_NewFunction(cx, NULL, constructor, nargs, JSFUN_CONSTRUCTOR, obj, atom);
|
||||
js_NewFunction(cx, NULL, constructor, nargs, JSFUN_CONSTRUCTOR, obj, atom,
|
||||
ctorKind);
|
||||
if (!fun)
|
||||
goto bad;
|
||||
fun->setConstructorClass(clasp);
|
||||
|
@ -4431,7 +4432,7 @@ js_InitClass(JSContext *cx, JSObject *obj, JSObject *protoProto,
|
|||
Class *clasp, Native constructor, uintN nargs,
|
||||
JSPropertySpec *ps, JSFunctionSpec *fs,
|
||||
JSPropertySpec *static_ps, JSFunctionSpec *static_fs,
|
||||
JSObject **ctorp)
|
||||
JSObject **ctorp, AllocKind ctorKind)
|
||||
{
|
||||
JSAtom *atom = js_Atomize(cx, clasp->name, strlen(clasp->name));
|
||||
if (!atom)
|
||||
|
@ -4457,7 +4458,7 @@ js_InitClass(JSContext *cx, JSObject *obj, JSObject *protoProto,
|
|||
}
|
||||
|
||||
return DefineConstructorAndPrototype(cx, obj, key, atom, protoProto, clasp, constructor, nargs,
|
||||
ps, fs, static_ps, static_fs, ctorp);
|
||||
ps, fs, static_ps, static_fs, ctorp, ctorKind);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1517,14 +1517,6 @@ extern JSFunctionSpec object_static_methods[];
|
|||
|
||||
namespace js {
|
||||
|
||||
JSObject *
|
||||
DefineConstructorAndPrototype(JSContext *cx, JSObject *obj, JSProtoKey key, JSAtom *atom,
|
||||
JSObject *protoProto, Class *clasp,
|
||||
Native constructor, uintN nargs,
|
||||
JSPropertySpec *ps, JSFunctionSpec *fs,
|
||||
JSPropertySpec *static_ps, JSFunctionSpec *static_fs,
|
||||
JSObject **ctorp = NULL);
|
||||
|
||||
bool
|
||||
IsStandardClassResolved(JSObject *obj, js::Class *clasp);
|
||||
|
||||
|
@ -1533,13 +1525,6 @@ MarkStandardClassInitializedNoProto(JSObject *obj, js::Class *clasp);
|
|||
|
||||
}
|
||||
|
||||
extern JSObject *
|
||||
js_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
|
||||
js::Class *clasp, JSNative constructor, uintN nargs,
|
||||
JSPropertySpec *ps, JSFunctionSpec *fs,
|
||||
JSPropertySpec *static_ps, JSFunctionSpec *static_fs,
|
||||
JSObject **ctorp = NULL);
|
||||
|
||||
/*
|
||||
* Select Object.prototype method names shared between jsapi.cpp and jsobj.cpp.
|
||||
*/
|
||||
|
|
|
@ -1939,8 +1939,25 @@ ValueIsSpecial(JSObject *obj, Value *propval, SpecialId *sidp, JSContext *cx)
|
|||
return false;
|
||||
}
|
||||
|
||||
JSObject *
|
||||
DefineConstructorAndPrototype(JSContext *cx, JSObject *obj, JSProtoKey key, JSAtom *atom,
|
||||
JSObject *protoProto, Class *clasp,
|
||||
Native constructor, uintN nargs,
|
||||
JSPropertySpec *ps, JSFunctionSpec *fs,
|
||||
JSPropertySpec *static_ps, JSFunctionSpec *static_fs,
|
||||
JSObject **ctorp = NULL,
|
||||
gc::AllocKind ctorKind = JSFunction::FinalizeKind);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
extern JSObject *
|
||||
js_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
|
||||
js::Class *clasp, JSNative constructor, uintN nargs,
|
||||
JSPropertySpec *ps, JSFunctionSpec *fs,
|
||||
JSPropertySpec *static_ps, JSFunctionSpec *static_fs,
|
||||
JSObject **ctorp = NULL,
|
||||
js::gc::AllocKind ctorKind = JSFunction::FinalizeKind);
|
||||
|
||||
inline JSObject *
|
||||
js_GetProtoIfDenseArray(JSObject *obj)
|
||||
{
|
||||
|
|
|
@ -647,20 +647,25 @@ class Worker : public WorkerParent
|
|||
// alive, this postMessage function cannot be called after the Worker
|
||||
// is collected. Therefore it's safe to stash a pointer (a weak
|
||||
// reference) to the C++ Worker object in the reserved slot.
|
||||
post = JS_GetFunctionObject(JS_DefineFunction(context, global, "postMessage",
|
||||
(JSNative) jsPostMessageToParent, 1, 0));
|
||||
if (!post || !JS_SetReservedSlot(context, post, 0, PRIVATE_TO_JSVAL(this)))
|
||||
post = JS_GetFunctionObject(
|
||||
js::DefineFunctionWithReserved(context, global, "postMessage",
|
||||
(JSNative) jsPostMessageToParent, 1, 0));
|
||||
if (!post)
|
||||
goto bad;
|
||||
|
||||
proto = JS_InitClass(context, global, NULL, &jsWorkerClass, jsConstruct, 1,
|
||||
NULL, jsMethods, NULL, NULL);
|
||||
js::SetFunctionNativeReserved(post, 0, PRIVATE_TO_JSVAL(this));
|
||||
|
||||
proto = js::InitClassWithReserved(context, global, NULL, &jsWorkerClass, jsConstruct, 1,
|
||||
NULL, jsMethods, NULL, NULL);
|
||||
if (!proto)
|
||||
goto bad;
|
||||
|
||||
ctor = JS_GetConstructor(context, proto);
|
||||
if (!ctor || !JS_SetReservedSlot(context, ctor, 0, PRIVATE_TO_JSVAL(this)))
|
||||
if (!ctor)
|
||||
goto bad;
|
||||
|
||||
js::SetFunctionNativeReserved(post, 0, PRIVATE_TO_JSVAL(this));
|
||||
|
||||
JS_EndRequest(context);
|
||||
JS_ClearContextThread(context);
|
||||
return true;
|
||||
|
@ -806,23 +811,17 @@ class Worker : public WorkerParent
|
|||
}
|
||||
|
||||
static bool getWorkerParentFromConstructor(JSContext *cx, JSObject *ctor, WorkerParent **p) {
|
||||
jsval v;
|
||||
if (!JS_GetReservedSlot(cx, ctor, 0, &v))
|
||||
return false;
|
||||
jsval v = js::GetFunctionNativeReserved(ctor, 0);
|
||||
if (JSVAL_IS_VOID(v)) {
|
||||
// This means ctor is the root Worker constructor (created in
|
||||
// Worker::initWorkers as opposed to Worker::createContext, which sets up
|
||||
// Worker sandboxes) and nothing is initialized yet.
|
||||
if (!JS_GetReservedSlot(cx, ctor, 1, &v))
|
||||
return false;
|
||||
v = js::GetFunctionNativeReserved(ctor, 1);
|
||||
ThreadPool *threadPool = (ThreadPool *) JSVAL_TO_PRIVATE(v);
|
||||
if (!threadPool->start(cx))
|
||||
return false;
|
||||
WorkerParent *parent = threadPool->getMainQueue();
|
||||
if (!JS_SetReservedSlot(cx, ctor, 0, PRIVATE_TO_JSVAL(parent))) {
|
||||
threadPool->shutdown(cx);
|
||||
return false;
|
||||
}
|
||||
js::SetFunctionNativeReserved(ctor, 0, PRIVATE_TO_JSVAL(parent));
|
||||
*p = parent;
|
||||
return true;
|
||||
}
|
||||
|
@ -861,17 +860,16 @@ class Worker : public WorkerParent
|
|||
*objp = threadPool->asObject();
|
||||
|
||||
// Create the Worker constructor.
|
||||
JSObject *proto = JS_InitClass(cx, global, NULL, &jsWorkerClass,
|
||||
jsConstruct, 1,
|
||||
NULL, jsMethods, NULL, NULL);
|
||||
JSObject *proto = js::InitClassWithReserved(cx, global, NULL, &jsWorkerClass,
|
||||
jsConstruct, 1,
|
||||
NULL, jsMethods, NULL, NULL);
|
||||
if (!proto)
|
||||
return NULL;
|
||||
|
||||
// Stash a pointer to the ThreadPool in constructor reserved slot 1.
|
||||
// It will be used later when lazily creating the MainQueue.
|
||||
JSObject *ctor = JS_GetConstructor(cx, proto);
|
||||
if (!JS_SetReservedSlot(cx, ctor, 1, PRIVATE_TO_JSVAL(threadPool)))
|
||||
return NULL;
|
||||
js::SetFunctionNativeReserved(ctor, 1, PRIVATE_TO_JSVAL(threadPool));
|
||||
|
||||
return threadPool;
|
||||
}
|
||||
|
@ -1155,9 +1153,7 @@ Worker::processOneEvent()
|
|||
JSBool
|
||||
Worker::jsPostMessageToParent(JSContext *cx, uintN argc, jsval *vp)
|
||||
{
|
||||
jsval workerval;
|
||||
if (!JS_GetReservedSlot(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)), 0, &workerval))
|
||||
return false;
|
||||
jsval workerval = js::GetFunctionNativeReserved(JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)), 0);
|
||||
Worker *w = (Worker *) JSVAL_TO_PRIVATE(workerval);
|
||||
|
||||
{
|
||||
|
|
|
@ -3879,8 +3879,8 @@ FunctionWrapper(JSContext *cx, uintN argc, jsval *vp)
|
|||
JSBool
|
||||
WrapCallable(JSContext *cx, JSObject *obj, jsid id, JSObject *propobj, jsval *vp)
|
||||
{
|
||||
JSFunction *fun = JS_NewFunctionById(cx, FunctionWrapper, 0, 0,
|
||||
JS_GetGlobalForObject(cx, obj), id);
|
||||
JSFunction *fun = js::NewFunctionByIdWithReserved(cx, FunctionWrapper, 0, 0,
|
||||
JS_GetGlobalForObject(cx, obj), id);
|
||||
if (!fun)
|
||||
return JS_FALSE;
|
||||
|
||||
|
|
|
@ -186,7 +186,7 @@ GeneratePropertyOp(JSContext *cx, JSObject *obj, jsid id, uintN argc, Op pop)
|
|||
// The JS engine provides two reserved slots on function objects for
|
||||
// XPConnect to use. Use them to stick the necessary info here.
|
||||
JSFunction *fun =
|
||||
JS_NewFunctionById(cx, PropertyOpForwarder<Op>, argc, 0, obj, id);
|
||||
js::NewFunctionByIdWithReserved(cx, PropertyOpForwarder<Op>, argc, 0, obj, id);
|
||||
if (!fun)
|
||||
return JS_FALSE;
|
||||
|
||||
|
|
|
@ -160,7 +160,7 @@ XPCNativeMember::Resolve(XPCCallContext& ccx, XPCNativeInterface* iface,
|
|||
callback = XPC_WN_GetterSetter;
|
||||
}
|
||||
|
||||
JSFunction *fun = JS_NewFunctionById(ccx, callback, argc, 0, parent, GetName());
|
||||
JSFunction *fun = js::NewFunctionByIdWithReserved(ccx, callback, argc, 0, parent, GetName());
|
||||
if (!fun)
|
||||
return JS_FALSE;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче