diff -r 31f42dd24f25 js/src/jsproxy.cpp --- a/js/src/jsproxy.cpp Tue Jul 31 14:47:18 2012 +0200 +++ b/js/src/jsproxy.cpp Thu Aug 02 23:47:39 2012 +0200 @@ -44,67 +44,50 @@ GetConstruct(JSObject *proxy) static inline HeapSlot & GetFunctionProxyConstruct(JSObject *proxy) { JS_ASSERT(IsFunctionProxy(proxy)); JS_ASSERT(proxy->slotSpan() > JSSLOT_PROXY_CONSTRUCT); return proxy->getSlotRef(JSSLOT_PROXY_CONSTRUCT); } -#ifdef DEBUG -static bool -OperationInProgress(JSContext *cx, JSObject *proxy) -{ - PendingProxyOperation *op = cx->runtime->pendingProxyOperation; - while (op) { - if (op->object == proxy) - return true; - op = op->next; - } - return false; -} -#endif - BaseProxyHandler::BaseProxyHandler(void *family) : mFamily(family) { } BaseProxyHandler::~BaseProxyHandler() { } bool BaseProxyHandler::has(JSContext *cx, JSObject *proxy, jsid id, bool *bp) { - JS_ASSERT(OperationInProgress(cx, proxy)); AutoPropertyDescriptorRooter desc(cx); if (!getPropertyDescriptor(cx, proxy, id, false, &desc)) return false; *bp = !!desc.obj; return true; } bool BaseProxyHandler::hasOwn(JSContext *cx, JSObject *proxy, jsid id, bool *bp) { - JS_ASSERT(OperationInProgress(cx, proxy)); AutoPropertyDescriptorRooter desc(cx); if (!getOwnPropertyDescriptor(cx, proxy, id, false, &desc)) return false; *bp = !!desc.obj; return true; } bool BaseProxyHandler::get(JSContext *cx, JSObject *proxy, JSObject *receiver_, jsid id_, Value *vp) { RootedObject receiver(cx, receiver_); RootedId id(cx, id_); - JS_ASSERT(OperationInProgress(cx, proxy)); AutoPropertyDescriptorRooter desc(cx); if (!getPropertyDescriptor(cx, proxy, id, false, &desc)) return false; if (!desc.obj) { vp->setUndefined(); return true; } if (!desc.getter || @@ -152,17 +135,16 @@ BaseProxyHandler::getElementIfPresent(JS bool BaseProxyHandler::set(JSContext *cx, JSObject *proxy_, JSObject *receiver_, jsid id_, bool strict, Value *vp) { RootedObject proxy(cx, proxy_), receiver(cx, receiver_); RootedId id(cx, id_); - JS_ASSERT(OperationInProgress(cx, proxy)); AutoPropertyDescriptorRooter desc(cx); if (!getOwnPropertyDescriptor(cx, proxy, id, true, &desc)) return false; /* The control-flow here differs from ::get() because of the fall-through case below. */ if (desc.obj) { // Check for read-only properties. if (desc.attrs & JSPROP_READONLY) return strict ? Throw(cx, id, JSMSG_CANT_REDEFINE_PROP) : true; @@ -226,17 +208,16 @@ BaseProxyHandler::set(JSContext *cx, JSO desc.getter = NULL; desc.setter = NULL; // Pick up the class getter/setter. return defineProperty(cx, receiver, id, &desc); } bool BaseProxyHandler::keys(JSContext *cx, JSObject *proxy, AutoIdVector &props) { - JS_ASSERT(OperationInProgress(cx, proxy)); JS_ASSERT(props.length() == 0); if (!getOwnPropertyNames(cx, proxy, props)) return false; /* Select only the enumerable properties through in-place iteration. */ AutoPropertyDescriptorRooter desc(cx); size_t i = 0; @@ -255,17 +236,16 @@ BaseProxyHandler::keys(JSContext *cx, JS return true; } bool BaseProxyHandler::iterate(JSContext *cx, JSObject *proxy_, unsigned flags, Value *vp) { RootedObject proxy(cx, proxy_); - JS_ASSERT(OperationInProgress(cx, proxy)); AutoIdVector props(cx); if ((flags & JSITER_OWNONLY) ? !keys(cx, proxy, props) : !enumerate(cx, proxy, props)) { return false; } RootedValue value(cx); @@ -336,41 +316,37 @@ BaseProxyHandler::iteratorNext(JSContext { vp->setMagic(JS_NO_ITER_VALUE); return true; } bool BaseProxyHandler::nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args) { - JS_ASSERT(OperationInProgress(cx, &args.thisv().toObject())); ReportIncompatible(cx, args); return false; } bool BaseProxyHandler::hasInstance(JSContext *cx, JSObject *proxy, const Value *vp, bool *bp) { - JS_ASSERT(OperationInProgress(cx, proxy)); js_ReportValueError(cx, JSMSG_BAD_INSTANCEOF_RHS, JSDVG_SEARCH_STACK, ObjectValue(*proxy), NULL); return false; } JSType BaseProxyHandler::typeOf(JSContext *cx, JSObject *proxy) { - JS_ASSERT(OperationInProgress(cx, proxy)); return IsFunctionProxy(proxy) ? JSTYPE_FUNCTION : JSTYPE_OBJECT; } bool BaseProxyHandler::objectClassIs(JSObject *proxy, ESClassValue classValue, JSContext *cx) { - JS_ASSERT(OperationInProgress(cx, proxy)); return false; } void BaseProxyHandler::finalize(JSFreeOp *fop, JSObject *proxy) { } @@ -453,29 +429,27 @@ IndirectProxyHandler::enumerate(JSContex { return GetPropertyNames(cx, GetProxyTargetObject(proxy), 0, &props); } bool IndirectProxyHandler::call(JSContext *cx, JSObject *proxy, unsigned argc, Value *vp) { - JS_ASSERT(OperationInProgress(cx, proxy)); AutoValueRooter rval(cx); JSBool ok = Invoke(cx, vp[1], GetCall(proxy), argc, JS_ARGV(cx, vp), rval.addr()); if (ok) JS_SET_RVAL(cx, vp, rval.value()); return ok; } bool IndirectProxyHandler::construct(JSContext *cx, JSObject *proxy, unsigned argc, Value *argv, Value *rval) { - JS_ASSERT(OperationInProgress(cx, proxy)); Value fval = GetConstruct(proxy); if (fval.isUndefined()) return InvokeConstructor(cx, GetCall(proxy), argc, argv, rval); return Invoke(cx, UndefinedValue(), fval, argc, argv, rval); } bool IndirectProxyHandler::nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, @@ -765,39 +739,46 @@ ArrayToIdVector(JSContext *cx, const Val /* Derived class for all scripted proxy handlers. */ class ScriptedProxyHandler : public IndirectProxyHandler { public: ScriptedProxyHandler(); virtual ~ScriptedProxyHandler(); /* ES5 Harmony fundamental proxy traps. */ - virtual bool getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set, + virtual bool getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, + bool set, PropertyDescriptor *desc); - virtual bool getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set, + virtual bool getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy, + jsid id, bool set, PropertyDescriptor *desc); virtual bool defineProperty(JSContext *cx, JSObject *proxy, jsid id, PropertyDescriptor *desc); - virtual bool getOwnPropertyNames(JSContext *cx, JSObject *proxy, AutoIdVector &props); + virtual bool getOwnPropertyNames(JSContext *cx, JSObject *proxy, + AutoIdVector &props); virtual bool delete_(JSContext *cx, JSObject *proxy, jsid id, bool *bp); virtual bool enumerate(JSContext *cx, JSObject *proxy, AutoIdVector &props); /* ES5 Harmony derived proxy traps. */ virtual bool has(JSContext *cx, JSObject *proxy, jsid id, bool *bp); virtual bool hasOwn(JSContext *cx, JSObject *proxy, jsid id, bool *bp); - virtual bool get(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, Value *vp); - virtual bool set(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, bool strict, - Value *vp); + virtual bool get(JSContext *cx, JSObject *proxy, JSObject *receiver, + jsid id, Value *vp); + virtual bool set(JSContext *cx, JSObject *proxy, JSObject *receiver, + jsid id, bool strict, Value *vp); virtual bool keys(JSContext *cx, JSObject *proxy, AutoIdVector &props); - virtual bool iterate(JSContext *cx, JSObject *proxy, unsigned flags, Value *vp); + virtual bool iterate(JSContext *cx, JSObject *proxy, unsigned flags, + Value *vp); /* Spidermonkey extensions. */ - virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args) MOZ_OVERRIDE; + virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, + NativeImpl impl, CallArgs args); virtual JSType typeOf(JSContext *cx, JSObject *proxy); - virtual bool defaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp); + virtual bool defaultValue(JSContext *cx, JSObject *obj, JSType hint, + Value *vp); static ScriptedProxyHandler singleton; }; static int sScriptedProxyHandlerFamily = 0; ScriptedProxyHandler::ScriptedProxyHandler() : IndirectProxyHandler(&sScriptedProxyHandlerFamily) { @@ -819,17 +800,16 @@ ReturnedValueMustNotBePrimitive(JSContex return false; } return true; } static JSObject * GetProxyHandlerObject(JSContext *cx, JSObject *proxy) { - JS_ASSERT(OperationInProgress(cx, proxy)); return GetProxyPrivate(proxy).toObjectOrNull(); } bool ScriptedProxyHandler::getPropertyDescriptor(JSContext *cx, JSObject *proxy_, jsid id_, bool set, PropertyDescriptor *desc) { RootedId id(cx, id_); @@ -1027,258 +1007,214 @@ ScriptedProxyHandler::defaultValue(JSCon * This function is only here to prevent bug 757063. It will be removed when * the direct proxy refactor is complete. */ return BaseProxyHandler::defaultValue(cx, proxy, hint, vp); } ScriptedProxyHandler ScriptedProxyHandler::singleton; -class AutoPendingProxyOperation { - JSRuntime *rt; - PendingProxyOperation op; - public: - AutoPendingProxyOperation(JSContext *cx, JSObject *proxy) - : rt(cx->runtime), op(cx, proxy) - { - op.next = rt->pendingProxyOperation; - rt->pendingProxyOperation = &op; - } - - ~AutoPendingProxyOperation() { - JS_ASSERT(rt->pendingProxyOperation == &op); - rt->pendingProxyOperation = op.next; - } -}; - bool Proxy::getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set, PropertyDescriptor *desc) { JS_CHECK_RECURSION(cx, return false); - AutoPendingProxyOperation pending(cx, proxy); return GetProxyHandler(proxy)->getPropertyDescriptor(cx, proxy, id, set, desc); } bool Proxy::getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set, Value *vp) { JS_CHECK_RECURSION(cx, return false); - AutoPendingProxyOperation pending(cx, proxy); AutoPropertyDescriptorRooter desc(cx); return Proxy::getPropertyDescriptor(cx, proxy, id, set, &desc) && NewPropertyDescriptorObject(cx, &desc, vp); } bool Proxy::getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set, PropertyDescriptor *desc) { JS_CHECK_RECURSION(cx, return false); - AutoPendingProxyOperation pending(cx, proxy); return GetProxyHandler(proxy)->getOwnPropertyDescriptor(cx, proxy, id, set, desc); } bool Proxy::getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set, Value *vp) { JS_CHECK_RECURSION(cx, return false); - AutoPendingProxyOperation pending(cx, proxy); AutoPropertyDescriptorRooter desc(cx); return Proxy::getOwnPropertyDescriptor(cx, proxy, id, set, &desc) && NewPropertyDescriptorObject(cx, &desc, vp); } bool Proxy::defineProperty(JSContext *cx, JSObject *proxy, jsid id, PropertyDescriptor *desc) { JS_CHECK_RECURSION(cx, return false); - AutoPendingProxyOperation pending(cx, proxy); return GetProxyHandler(proxy)->defineProperty(cx, proxy, id, desc); } bool Proxy::defineProperty(JSContext *cx, JSObject *proxy_, jsid id_, const Value &v) { JS_CHECK_RECURSION(cx, return false); RootedObject proxy(cx, proxy_); RootedId id(cx, id_); - AutoPendingProxyOperation pending(cx, proxy); AutoPropertyDescriptorRooter desc(cx); return ParsePropertyDescriptorObject(cx, proxy, v, &desc) && Proxy::defineProperty(cx, proxy, id, &desc); } bool Proxy::getOwnPropertyNames(JSContext *cx, JSObject *proxy, AutoIdVector &props) { JS_CHECK_RECURSION(cx, return false); - AutoPendingProxyOperation pending(cx, proxy); return GetProxyHandler(proxy)->getOwnPropertyNames(cx, proxy, props); } bool Proxy::delete_(JSContext *cx, JSObject *proxy, jsid id, bool *bp) { JS_CHECK_RECURSION(cx, return false); - AutoPendingProxyOperation pending(cx, proxy); return GetProxyHandler(proxy)->delete_(cx, proxy, id, bp); } bool Proxy::enumerate(JSContext *cx, JSObject *proxy, AutoIdVector &props) { JS_CHECK_RECURSION(cx, return false); - AutoPendingProxyOperation pending(cx, proxy); return GetProxyHandler(proxy)->enumerate(cx, proxy, props); } bool Proxy::has(JSContext *cx, JSObject *proxy, jsid id, bool *bp) { JS_CHECK_RECURSION(cx, return false); - AutoPendingProxyOperation pending(cx, proxy); return GetProxyHandler(proxy)->has(cx, proxy, id, bp); } bool Proxy::hasOwn(JSContext *cx, JSObject *proxy, jsid id, bool *bp) { JS_CHECK_RECURSION(cx, return false); - AutoPendingProxyOperation pending(cx, proxy); return GetProxyHandler(proxy)->hasOwn(cx, proxy, id, bp); } bool Proxy::get(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, Value *vp) { JS_CHECK_RECURSION(cx, return false); - AutoPendingProxyOperation pending(cx, proxy); return GetProxyHandler(proxy)->get(cx, proxy, receiver, id, vp); } bool Proxy::getElementIfPresent(JSContext *cx, JSObject *proxy, JSObject *receiver, uint32_t index, Value *vp, bool *present) { JS_CHECK_RECURSION(cx, return false); - AutoPendingProxyOperation pending(cx, proxy); return GetProxyHandler(proxy)->getElementIfPresent(cx, proxy, receiver, index, vp, present); } bool Proxy::set(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, bool strict, Value *vp) { JS_CHECK_RECURSION(cx, return false); - AutoPendingProxyOperation pending(cx, proxy); return GetProxyHandler(proxy)->set(cx, proxy, receiver, id, strict, vp); } bool Proxy::keys(JSContext *cx, JSObject *proxy, AutoIdVector &props) { JS_CHECK_RECURSION(cx, return false); - AutoPendingProxyOperation pending(cx, proxy); return GetProxyHandler(proxy)->keys(cx, proxy, props); } bool Proxy::iterate(JSContext *cx, JSObject *proxy, unsigned flags, Value *vp) { JS_CHECK_RECURSION(cx, return false); - AutoPendingProxyOperation pending(cx, proxy); return GetProxyHandler(proxy)->iterate(cx, proxy, flags, vp); } bool Proxy::call(JSContext *cx, JSObject *proxy, unsigned argc, Value *vp) { JS_CHECK_RECURSION(cx, return false); - AutoPendingProxyOperation pending(cx, proxy); return GetProxyHandler(proxy)->call(cx, proxy, argc, vp); } bool Proxy::construct(JSContext *cx, JSObject *proxy, unsigned argc, Value *argv, Value *rval) { JS_CHECK_RECURSION(cx, return false); - AutoPendingProxyOperation pending(cx, proxy); return GetProxyHandler(proxy)->construct(cx, proxy, argc, argv, rval); } bool Proxy::nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args) { JS_CHECK_RECURSION(cx, return false); Rooted proxy(cx, &args.thisv().toObject()); - AutoPendingProxyOperation pending(cx, proxy); return GetProxyHandler(proxy)->nativeCall(cx, test, impl, args); } bool Proxy::hasInstance(JSContext *cx, JSObject *proxy, const js::Value *vp, bool *bp) { JS_CHECK_RECURSION(cx, return false); - AutoPendingProxyOperation pending(cx, proxy); return GetProxyHandler(proxy)->hasInstance(cx, proxy, vp, bp); } JSType Proxy::typeOf(JSContext *cx, JSObject *proxy) { // FIXME: API doesn't allow us to report error (bug 618906). JS_CHECK_RECURSION(cx, return JSTYPE_OBJECT); - AutoPendingProxyOperation pending(cx, proxy); return GetProxyHandler(proxy)->typeOf(cx, proxy); } bool Proxy::objectClassIs(JSObject *proxy, ESClassValue classValue, JSContext *cx) { - AutoPendingProxyOperation pending(cx, proxy); return GetProxyHandler(proxy)->objectClassIs(proxy, classValue, cx); } JSString * Proxy::obj_toString(JSContext *cx, JSObject *proxy) { JS_CHECK_RECURSION(cx, return NULL); - AutoPendingProxyOperation pending(cx, proxy); return GetProxyHandler(proxy)->obj_toString(cx, proxy); } JSString * Proxy::fun_toString(JSContext *cx, JSObject *proxy, unsigned indent) { JS_CHECK_RECURSION(cx, return NULL); - AutoPendingProxyOperation pending(cx, proxy); return GetProxyHandler(proxy)->fun_toString(cx, proxy, indent); } bool Proxy::regexp_toShared(JSContext *cx, JSObject *proxy, RegExpGuard *g) { JS_CHECK_RECURSION(cx, return false); - AutoPendingProxyOperation pending(cx, proxy); return GetProxyHandler(proxy)->regexp_toShared(cx, proxy, g); } bool Proxy::defaultValue(JSContext *cx, JSObject *proxy, JSType hint, Value *vp) { JS_CHECK_RECURSION(cx, return false); - AutoPendingProxyOperation pending(cx, proxy); return GetProxyHandler(proxy)->defaultValue(cx, proxy, hint, vp); } bool Proxy::iteratorNext(JSContext *cx, JSObject *proxy, Value *vp) { JS_CHECK_RECURSION(cx, return false); - AutoPendingProxyOperation pending(cx, proxy); return GetProxyHandler(proxy)->iteratorNext(cx, proxy, vp); } static JSObject * proxy_innerObject(JSContext *cx, HandleObject obj) { return GetProxyPrivate(obj).toObjectOrNull(); } @@ -1593,17 +1529,16 @@ proxy_Finalize(FreeOp *fop, JSObject *ob JS_ASSERT(obj->isProxy()); if (!obj->getSlot(JSSLOT_PROXY_HANDLER).isUndefined()) GetProxyHandler(obj)->finalize(fop, obj); } static JSBool proxy_HasInstance(JSContext *cx, HandleObject proxy, const Value *v, JSBool *bp) { - AutoPendingProxyOperation pending(cx, proxy); bool b; if (!Proxy::hasInstance(cx, proxy, v, &b)) return false; *bp = !!b; return true; } static JSType @@ -1910,32 +1845,16 @@ proxy_createFunction(JSContext *cx, unsi } static JSFunctionSpec static_methods[] = { JS_FN("create", proxy_create, 2, 0), JS_FN("createFunction", proxy_createFunction, 3, 0), JS_FS_END }; -Class js::CallableObjectClass = { - "Function", - JSCLASS_HAS_RESERVED_SLOTS(2), - JS_PropertyStub, /* addProperty */ - JS_PropertyStub, /* delProperty */ - JS_PropertyStub, /* getProperty */ - JS_StrictPropertyStub, /* setProperty */ - JS_EnumerateStub, - JS_ResolveStub, - JS_ConvertStub, - NULL, /* finalize */ - NULL, /* checkAccess */ - NULL, /* call */ - NULL /* construct */ -}; - Class js::ProxyClass = { "Proxy", JSCLASS_HAS_CACHED_PROTO(JSProto_Proxy), JS_PropertyStub, /* addProperty */ JS_PropertyStub, /* delProperty */ JS_PropertyStub, /* getProperty */ JS_StrictPropertyStub, /* setProperty */ JS_EnumerateStub,