зеркало из https://github.com/mozilla/gecko-dev.git
Backout 684958bd600b (bug 769911) for failures in test_bug435425.html on a CLOSED TREE
This commit is contained in:
Родитель
8172b9ba46
Коммит
6f3dfcd32a
|
@ -922,26 +922,4 @@ EnableRuntimeProfilingStack(JSRuntime *rt, bool enabled)
|
|||
rt->spsProfiler.enable(enabled);
|
||||
}
|
||||
|
||||
static void *gListBaseHandlerFamily = NULL;
|
||||
static uint32_t gListBaseExpandoSlot = 0;
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
SetListBaseInformation(void *listBaseHandlerFamily, uint32_t listBaseExpandoSlot)
|
||||
{
|
||||
gListBaseHandlerFamily = listBaseHandlerFamily;
|
||||
gListBaseExpandoSlot = listBaseExpandoSlot;
|
||||
}
|
||||
|
||||
void *
|
||||
GetListBaseHandlerFamily()
|
||||
{
|
||||
return gListBaseHandlerFamily;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
GetListBaseExpandoSlot()
|
||||
{
|
||||
return gListBaseExpandoSlot;
|
||||
}
|
||||
|
||||
} // namespace js
|
||||
|
|
|
@ -456,6 +456,13 @@ GetObjectSlot(RawObject obj, size_t slot)
|
|||
return reinterpret_cast<const shadow::Object *>(obj)->slotRef(slot);
|
||||
}
|
||||
|
||||
inline Shape *
|
||||
GetObjectShape(RawObject obj)
|
||||
{
|
||||
shadow::Shape *shape = reinterpret_cast<const shadow::Object*>(obj)->shape;
|
||||
return reinterpret_cast<Shape *>(shape);
|
||||
}
|
||||
|
||||
inline const jschar *
|
||||
GetAtomChars(JSAtom *atom)
|
||||
{
|
||||
|
@ -886,13 +893,6 @@ NukeCrossCompartmentWrappers(JSContext* cx,
|
|||
const CompartmentFilter& targetFilter,
|
||||
NukeReferencesToWindow nukeReferencesToWindow);
|
||||
|
||||
/* Specify information about ListBase proxies in the DOM, for use by ICs. */
|
||||
JS_FRIEND_API(void)
|
||||
SetListBaseInformation(void *listBaseHandlerFamily, uint32_t listBaseExpandoSlot);
|
||||
|
||||
void *GetListBaseHandlerFamily();
|
||||
uint32_t GetListBaseExpandoSlot();
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5023,7 +5023,7 @@ mjit::Compiler::jsop_getprop(PropertyName *name, JSValueType knownType,
|
|||
*/
|
||||
pic.canCallHook = pic.forcedTypeBarrier =
|
||||
!forPrototype &&
|
||||
(JSOp(*PC) == JSOP_GETPROP || JSOp(*PC) == JSOP_LENGTH) &&
|
||||
JSOp(*PC) == JSOP_GETPROP &&
|
||||
analysis->getCode(PC).accessGetter;
|
||||
|
||||
/* Guard that the type is an object. */
|
||||
|
|
|
@ -428,10 +428,6 @@ class NunboxAssembler : public JSC::MacroAssembler
|
|||
return branch32(cond, tagOf(address), ImmTag(JSVAL_TAG_STRING));
|
||||
}
|
||||
|
||||
Jump testPrivate(Condition cond, Address address, void *ptr) {
|
||||
return branchPtr(cond, address, ImmPtr(ptr));
|
||||
}
|
||||
|
||||
void compareValue(Address one, Address two, RegisterID T0, RegisterID T1,
|
||||
Vector<Jump> *mismatches) {
|
||||
loadValueAsComponents(one, T0, T1);
|
||||
|
|
|
@ -595,23 +595,6 @@ IsCacheableProtoChain(JSObject *obj, JSObject *holder)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
IsCacheableListBase(JSObject *obj)
|
||||
{
|
||||
if (!obj->isProxy())
|
||||
return false;
|
||||
|
||||
BaseProxyHandler *handler = GetProxyHandler(obj);
|
||||
|
||||
if (handler->family() != GetListBaseHandlerFamily())
|
||||
return false;
|
||||
|
||||
if (obj->numFixedSlots() <= GetListBaseExpandoSlot())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename IC>
|
||||
struct GetPropHelper {
|
||||
// These fields are set in the constructor and describe a property lookup.
|
||||
|
@ -658,9 +641,6 @@ struct GetPropHelper {
|
|||
JSObject *aobj = obj;
|
||||
if (obj->isDenseArray())
|
||||
aobj = obj->getProto();
|
||||
else if (IsCacheableListBase(obj))
|
||||
aobj = obj->getProto();
|
||||
|
||||
if (!aobj->isNative())
|
||||
return ic.disable(f, "non-native");
|
||||
|
||||
|
@ -1246,53 +1226,6 @@ class GetPropCompiler : public PICStubCompiler
|
|||
if (!shapeMismatches.append(shapeGuardJump))
|
||||
return error();
|
||||
|
||||
// Guard on the proxy guts for ListBase accesses, if applicable.
|
||||
if (IsCacheableListBase(obj)) {
|
||||
// The shape check above ensures this is a proxy with the correct
|
||||
// number of fixed slots, but we need further checks to ensure that
|
||||
//
|
||||
// (a) the object is a ListBase.
|
||||
// (b) the object does not have any expando properties, or has an
|
||||
// expando which does not have the desired property.
|
||||
//
|
||||
// If both of these hold, all accesses on non-indexed PropertyName
|
||||
// properties will go through the object's native prototype chain.
|
||||
|
||||
Address handler(pic.objReg, JSObject::getFixedSlotOffset(JSSLOT_PROXY_HANDLER));
|
||||
Jump handlerGuard = masm.testPrivate(Assembler::NotEqual, handler, GetProxyHandler(obj));
|
||||
if (!shapeMismatches.append(handlerGuard))
|
||||
return error();
|
||||
|
||||
Address expandoAddress(pic.objReg, JSObject::getFixedSlotOffset(GetListBaseExpandoSlot()));
|
||||
|
||||
Value expandoValue = obj->getFixedSlot(GetListBaseExpandoSlot());
|
||||
JSObject *expando = expandoValue.isObject() ? &expandoValue.toObject() : NULL;
|
||||
|
||||
// Expando objects just hold any extra properties the object has
|
||||
// been given by a script, and have no prototype or anything else
|
||||
// that will complicate property lookups on them.
|
||||
JS_ASSERT_IF(expando, expando->isNative() && expando->getProto() == NULL);
|
||||
|
||||
if (expando && expando->nativeLookupNoAllocation(name) == NULL) {
|
||||
Jump expandoGuard = masm.testObject(Assembler::NotEqual, expandoAddress);
|
||||
if (!shapeMismatches.append(expandoGuard))
|
||||
return error();
|
||||
|
||||
masm.loadPayload(expandoAddress, pic.shapeReg);
|
||||
pic.shapeRegHasBaseShape = false;
|
||||
|
||||
Jump shapeGuard = masm.branchPtr(Assembler::NotEqual,
|
||||
Address(pic.shapeReg, JSObject::offsetOfShape()),
|
||||
ImmPtr(expando->lastProperty()));
|
||||
if (!shapeMismatches.append(expandoGuard))
|
||||
return error();
|
||||
} else {
|
||||
Jump expandoGuard = masm.testUndefined(Assembler::NotEqual, expandoAddress);
|
||||
if (!shapeMismatches.append(expandoGuard))
|
||||
return error();
|
||||
}
|
||||
}
|
||||
|
||||
RegisterID holderReg = pic.objReg;
|
||||
if (obj != holder) {
|
||||
if (!GeneratePrototypeGuards(cx, shapeMismatches, masm, obj, holder,
|
||||
|
@ -2231,10 +2164,6 @@ GetElementIC::attachGetProp(VMFrame &f, HandleObject obj, HandleValue v, HandleP
|
|||
JS_ASSERT(v.isString());
|
||||
JSContext *cx = f.cx;
|
||||
|
||||
// don't handle special logic required for property access on proxies.
|
||||
if (!obj->isNative())
|
||||
return Lookup_Uncacheable;
|
||||
|
||||
GetPropHelper<GetElementIC> getprop(cx, obj, name, *this, f);
|
||||
LookupStatus status = getprop.lookupAndTest();
|
||||
if (status != Lookup_Cacheable)
|
||||
|
|
|
@ -345,11 +345,6 @@ class PunboxAssembler : public JSC::MacroAssembler
|
|||
return testString(cond, Registers::ValueReg);
|
||||
}
|
||||
|
||||
Jump testPrivate(Condition cond, Address address, void *ptr) {
|
||||
uint64_t valueBits = PrivateValue(ptr).asRawBits();
|
||||
return branchPtr(cond, address, ImmPtr((void *) valueBits));
|
||||
}
|
||||
|
||||
void compareValue(Address one, Address two, RegisterID T0, RegisterID T1,
|
||||
Vector<Jump> *mismatches) {
|
||||
loadValue(one, T0);
|
||||
|
|
|
@ -29,7 +29,8 @@ namespace dom {
|
|||
namespace binding {
|
||||
|
||||
enum {
|
||||
JSPROXYSLOT_EXPANDO = 0
|
||||
JSPROXYSLOT_PROTOSHAPE = 0,
|
||||
JSPROXYSLOT_EXPANDO = 1
|
||||
};
|
||||
|
||||
static jsid s_prototype_id = JSID_VOID;
|
||||
|
@ -67,12 +68,6 @@ DefineStaticJSVals(JSContext *cx)
|
|||
|
||||
int HandlerFamily;
|
||||
|
||||
struct SetListBaseInformation
|
||||
{
|
||||
SetListBaseInformation() {
|
||||
js::SetListBaseInformation((void*) &HandlerFamily, js::JSSLOT_PROXY_EXTRA + JSPROXYSLOT_EXPANDO);
|
||||
}
|
||||
} gSetListBaseInformation;
|
||||
|
||||
JSBool
|
||||
Throw(JSContext *cx, nsresult rv)
|
||||
|
@ -143,6 +138,26 @@ Unwrap(JSContext *cx, jsval v, NoType **ppArg, nsISupports **ppArgRef, jsval *vp
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Because we use proxies for wrapping DOM list objects we don't get the benefits of the property
|
||||
// cache. To improve performance when using a property that lives on the prototype chain we
|
||||
// implemented a cheap caching mechanism. Every DOM list proxy object stores a pointer to a shape
|
||||
// in an extra slot. The first time we access a property on the object that lives on the prototype
|
||||
// we check if all the DOM properties on the prototype chain are the real DOM properties and in
|
||||
// that case we store a pointer to the shape of the object's prototype in the extra slot. From
|
||||
// then on, every time we access a DOM property that lives on the prototype we check that the
|
||||
// shape of the prototype is still identical to the cached shape and we do a fast lookup of the
|
||||
// property. If the shape has changed, we recheck all the DOM properties on the prototype chain
|
||||
// and we update the shape pointer if they are still the real DOM properties. This mechanism
|
||||
// covers addition/removal of properties, changes in getters/setters, changes in the prototype
|
||||
// chain, ... It does not cover changes in the values of the properties. For those we store an
|
||||
// enum value in a reserved slot in every DOM prototype object. The value starts off as USE_CACHE.
|
||||
// If a property of a DOM prototype object is set to a different value, we set the value to
|
||||
// CHECK_CACHE. The next time we try to access the value of a property on that DOM prototype
|
||||
// object we check if all the DOM properties on that DOM prototype object still match the real DOM
|
||||
// properties. If they do we set the value to USE_CACHE again, if they're not we set the value to
|
||||
// DONT_USE_CACHE. If the value is USE_CACHE we do the fast lookup.
|
||||
|
||||
template<class LC>
|
||||
typename ListBase<LC>::Properties ListBase<LC>::sProtoProperties[] = {
|
||||
{ s_VOID_id, NULL, NULL }
|
||||
|
@ -188,6 +203,22 @@ ListBase<LC>::getListObject(JSObject *obj)
|
|||
return getNative(obj);
|
||||
}
|
||||
|
||||
template<class LC>
|
||||
js::Shape *
|
||||
ListBase<LC>::getProtoShape(JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(objIsList(obj));
|
||||
return (js::Shape *) js::GetProxyExtra(obj, JSPROXYSLOT_PROTOSHAPE).toPrivate();
|
||||
}
|
||||
|
||||
template<class LC>
|
||||
void
|
||||
ListBase<LC>::setProtoShape(JSObject *obj, js::Shape *shape)
|
||||
{
|
||||
JS_ASSERT(objIsList(obj));
|
||||
js::SetProxyExtra(obj, JSPROXYSLOT_PROTOSHAPE, PrivateValue(shape));
|
||||
}
|
||||
|
||||
static JSBool
|
||||
UnwrapSecurityWrapper(JSContext *cx, JSObject *obj, JSObject *callee, JSObject **unwrapped)
|
||||
{
|
||||
|
@ -315,18 +346,43 @@ interface_hasInstance(JSContext *cx, JSHandleObject obj, const JS::Value *vp, JS
|
|||
return true;
|
||||
}
|
||||
|
||||
enum {
|
||||
USE_CACHE = 0,
|
||||
CHECK_CACHE = 1,
|
||||
DONT_USE_CACHE = 2
|
||||
};
|
||||
|
||||
static JSBool
|
||||
InvalidateProtoShape_add(JSContext *cx, JSHandleObject obj, JSHandleId id, JSMutableHandleValue vp);
|
||||
static JSBool
|
||||
InvalidateProtoShape_set(JSContext *cx, JSHandleObject obj, JSHandleId id, JSBool strict, JSMutableHandleValue vp);
|
||||
|
||||
js::Class sInterfacePrototypeClass = {
|
||||
"Object",
|
||||
JSCLASS_HAS_RESERVED_SLOTS(0),
|
||||
JS_PropertyStub, /* addProperty */
|
||||
JS_PropertyStub, /* delProperty */
|
||||
JS_PropertyStub, /* getProperty */
|
||||
JS_StrictPropertyStub, /* setProperty */
|
||||
JSCLASS_HAS_RESERVED_SLOTS(1),
|
||||
InvalidateProtoShape_add, /* addProperty */
|
||||
JS_PropertyStub, /* delProperty */
|
||||
JS_PropertyStub, /* getProperty */
|
||||
InvalidateProtoShape_set, /* setProperty */
|
||||
JS_EnumerateStub,
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub
|
||||
};
|
||||
|
||||
static JSBool
|
||||
InvalidateProtoShape_add(JSContext *cx, JSHandleObject obj, JSHandleId id, JSMutableHandleValue vp)
|
||||
{
|
||||
if (JSID_IS_STRING(id) && JS_InstanceOf(cx, obj, Jsvalify(&sInterfacePrototypeClass), NULL))
|
||||
js::SetReservedSlot(obj, 0, PrivateUint32Value(CHECK_CACHE));
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
InvalidateProtoShape_set(JSContext *cx, JSHandleObject obj, JSHandleId id, JSBool strict, JSMutableHandleValue vp)
|
||||
{
|
||||
return InvalidateProtoShape_add(cx, obj, id, vp);
|
||||
}
|
||||
|
||||
template<class LC>
|
||||
JSObject *
|
||||
ListBase<LC>::getPrototype(JSContext *cx, JSObject *receiver, bool *enabled)
|
||||
|
@ -402,6 +458,10 @@ ListBase<LC>::getPrototype(JSContext *cx, XPCWrappedNativeScope *scope,
|
|||
NULL, 0))
|
||||
return NULL;
|
||||
|
||||
// This needs to happen after we've set all our own properties on interfacePrototype, to
|
||||
// overwrite the value set by InvalidateProtoShape_add when we set our own properties.
|
||||
js::SetReservedSlot(interfacePrototype, 0, PrivateUint32Value(USE_CACHE));
|
||||
|
||||
if (!cache.Put(sInterfaceClass.name, interfacePrototype, fallible_t()))
|
||||
return NULL;
|
||||
|
||||
|
@ -438,6 +498,7 @@ ListBase<LC>::create(JSContext *cx, JSObject *scope, ListType *aList,
|
|||
return NULL;
|
||||
|
||||
NS_ADDREF(aList);
|
||||
setProtoShape(obj, NULL);
|
||||
|
||||
aWrapperCache->SetWrapper(obj);
|
||||
|
||||
|
@ -770,6 +831,59 @@ ListBase<LC>::has(JSContext *cx, JSObject *proxy, jsid id, bool *bp)
|
|||
return ok;
|
||||
}
|
||||
|
||||
template<class LC>
|
||||
bool
|
||||
ListBase<LC>::protoIsClean(JSContext *cx, JSObject *proto, bool *isClean)
|
||||
{
|
||||
JSPropertyDescriptor desc;
|
||||
for (size_t n = 0; n < sProtoPropertiesCount; ++n) {
|
||||
jsid id = sProtoProperties[n].id;
|
||||
if (!JS_GetPropertyDescriptorById(cx, proto, id, JSRESOLVE_QUALIFIED, &desc))
|
||||
return false;
|
||||
JSStrictPropertyOp setter =
|
||||
sProtoProperties[n].setter ? sProtoProperties[n].setter : InvalidateProtoShape_set;
|
||||
if (desc.obj != proto || desc.getter != sProtoProperties[n].getter ||
|
||||
desc.setter != setter) {
|
||||
*isClean = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t n = 0; n < sProtoMethodsCount; ++n) {
|
||||
jsid id = sProtoMethods[n].id;
|
||||
if (!JS_GetPropertyDescriptorById(cx, proto, id, JSRESOLVE_QUALIFIED, &desc))
|
||||
return false;
|
||||
if (desc.obj != proto || desc.getter || JSVAL_IS_PRIMITIVE(desc.value) ||
|
||||
n >= js::GetObjectSlotSpan(proto) || js::GetObjectSlot(proto, n + 1) != desc.value ||
|
||||
!JS_IsNativeFunction(JSVAL_TO_OBJECT(desc.value), sProtoMethods[n].native)) {
|
||||
*isClean = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
*isClean = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class LC>
|
||||
bool
|
||||
ListBase<LC>::shouldCacheProtoShape(JSContext *cx, JSObject *proto, bool *shouldCache)
|
||||
{
|
||||
bool ok = protoIsClean(cx, proto, shouldCache);
|
||||
if (!ok || !*shouldCache)
|
||||
return ok;
|
||||
|
||||
js::SetReservedSlot(proto, 0, PrivateUint32Value(USE_CACHE));
|
||||
|
||||
JSObject *protoProto = js::GetObjectProto(proto);
|
||||
if (!protoProto) {
|
||||
*shouldCache = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
return Base::shouldCacheProtoShape(cx, protoProto, shouldCache);
|
||||
}
|
||||
|
||||
template<class LC>
|
||||
bool
|
||||
ListBase<LC>::resolveNativeName(JSContext *cx, JSObject *proxy, jsid id, JSPropertyDescriptor *desc)
|
||||
|
@ -807,6 +921,64 @@ ListBase<LC>::resolveNativeName(JSContext *cx, JSObject *proxy, jsid id, JSPrope
|
|||
return Base::resolveNativeName(cx, proxy, id, desc);
|
||||
}
|
||||
|
||||
template<class LC>
|
||||
bool
|
||||
ListBase<LC>::nativeGet(JSContext *cx, JSObject *proxy_, JSObject *proto, jsid id_, bool *found, Value *vp)
|
||||
{
|
||||
JS::RootedObject proxy(cx, proxy_);
|
||||
JS::RootedId id(cx, id_);
|
||||
|
||||
uint32_t cache = js::GetReservedSlot(proto, 0).toPrivateUint32();
|
||||
if (cache == CHECK_CACHE) {
|
||||
bool isClean;
|
||||
if (!protoIsClean(cx, proto, &isClean))
|
||||
return false;
|
||||
if (!isClean) {
|
||||
js::SetReservedSlot(proto, 0, PrivateUint32Value(DONT_USE_CACHE));
|
||||
return true;
|
||||
}
|
||||
js::SetReservedSlot(proto, 0, PrivateUint32Value(USE_CACHE));
|
||||
}
|
||||
else if (cache == DONT_USE_CACHE) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
#ifdef DEBUG
|
||||
bool isClean;
|
||||
JS_ASSERT(protoIsClean(cx, proto, &isClean) && isClean);
|
||||
#endif
|
||||
}
|
||||
|
||||
for (size_t n = 0; n < sProtoPropertiesCount; ++n) {
|
||||
if (sProtoProperties[n].id == id) {
|
||||
*found = true;
|
||||
if (!vp)
|
||||
return true;
|
||||
|
||||
return sProtoProperties[n].getter(cx, proxy, id, JSMutableHandleValue::fromMarkedLocation(vp));
|
||||
}
|
||||
}
|
||||
for (size_t n = 0; n < sProtoMethodsCount; ++n) {
|
||||
if (sProtoMethods[n].id == id) {
|
||||
*found = true;
|
||||
if (!vp)
|
||||
return true;
|
||||
|
||||
*vp = js::GetObjectSlot(proto, n + 1);
|
||||
JS_ASSERT(JS_IsNativeFunction(&vp->toObject(), sProtoMethods[n].native));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
JSObject *protoProto = js::GetObjectProto(proto);
|
||||
if (!protoProto) {
|
||||
*found = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
return Base::nativeGet(cx, proxy, protoProto, id, found, vp);
|
||||
}
|
||||
|
||||
template<class LC>
|
||||
bool
|
||||
ListBase<LC>::getPropertyOnPrototype(JSContext *cx, JSObject *proxy, jsid id, bool *found,
|
||||
|
@ -816,6 +988,33 @@ ListBase<LC>::getPropertyOnPrototype(JSContext *cx, JSObject *proxy, jsid id, bo
|
|||
if (!proto)
|
||||
return true;
|
||||
|
||||
bool hit;
|
||||
if (getProtoShape(proxy) != js::GetObjectShape(proto)) {
|
||||
if (!shouldCacheProtoShape(cx, proto, &hit))
|
||||
return false;
|
||||
if (hit)
|
||||
setProtoShape(proxy, js::GetObjectShape(proto));
|
||||
} else {
|
||||
hit = true;
|
||||
}
|
||||
|
||||
if (hit) {
|
||||
if (id == s_length_id) {
|
||||
if (vp) {
|
||||
PRUint32 length;
|
||||
getListObject(proxy)->GetLength(&length);
|
||||
JS_ASSERT(int32_t(length) >= 0);
|
||||
vp->setInt32(length);
|
||||
}
|
||||
*found = true;
|
||||
return true;
|
||||
}
|
||||
if (!nativeGet(cx, proxy, proto, id, found, vp))
|
||||
return false;
|
||||
if (*found)
|
||||
return true;
|
||||
}
|
||||
|
||||
JSBool hasProp;
|
||||
if (!JS_HasPropertyById(cx, proto, id, &hasProp))
|
||||
return false;
|
||||
|
@ -839,7 +1038,7 @@ ListBase<LC>::hasPropertyOnPrototype(JSContext *cx, JSObject *proxy, jsid id)
|
|||
}
|
||||
JS_ASSERT(objIsList(proxy));
|
||||
|
||||
bool found = false;
|
||||
bool found;
|
||||
// We ignore an error from getPropertyOnPrototype.
|
||||
return !getPropertyOnPrototype(cx, proxy, id, &found, NULL) || found;
|
||||
}
|
||||
|
@ -878,7 +1077,7 @@ ListBase<LC>::get(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, V
|
|||
}
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
bool found;
|
||||
if (!getPropertyOnPrototype(cx, proxy, id, &found, vp))
|
||||
return false;
|
||||
|
||||
|
|
|
@ -78,10 +78,21 @@ class NoBase {
|
|||
public:
|
||||
static JSObject *getPrototype(JSContext *cx, XPCWrappedNativeScope *scope,
|
||||
JSObject *receiver);
|
||||
static bool shouldCacheProtoShape(JSContext *cx, JSObject *proto, bool *shouldCache)
|
||||
{
|
||||
*shouldCache = true;
|
||||
return true;
|
||||
}
|
||||
static bool resolveNativeName(JSContext *cx, JSObject *proxy, jsid id, JSPropertyDescriptor *desc)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
static bool nativeGet(JSContext *cx, JSObject *proxy, JSObject *proto, jsid id, bool *found,
|
||||
JS::Value *vp)
|
||||
{
|
||||
*found = false;
|
||||
return true;
|
||||
}
|
||||
static nsISupports* nativeToSupports(nsISupports* aNative)
|
||||
{
|
||||
return aNative;
|
||||
|
@ -133,6 +144,9 @@ private:
|
|||
|
||||
static JSObject *ensureExpandoObject(JSContext *cx, JSObject *obj);
|
||||
|
||||
static js::Shape *getProtoShape(JSObject *obj);
|
||||
static void setProtoShape(JSObject *obj, js::Shape *shape);
|
||||
|
||||
static JSBool length_getter(JSContext *cx, JSHandleObject obj, JSHandleId id, JSMutableHandleValue vp);
|
||||
|
||||
static inline bool getItemAt(ListType *list, uint32_t i, IndexGetterType &item);
|
||||
|
@ -199,8 +213,12 @@ public:
|
|||
|
||||
static JSObject *getPrototype(JSContext *cx, XPCWrappedNativeScope *scope,
|
||||
JSObject *receiver);
|
||||
static inline bool protoIsClean(JSContext *cx, JSObject *proto, bool *isClean);
|
||||
static bool shouldCacheProtoShape(JSContext *cx, JSObject *proto, bool *shouldCache);
|
||||
static bool resolveNativeName(JSContext *cx, JSObject *proxy, jsid id,
|
||||
JSPropertyDescriptor *desc);
|
||||
static bool nativeGet(JSContext *cx, JSObject *proxy, JSObject *proto, jsid id, bool *found,
|
||||
JS::Value *vp);
|
||||
static ListType *getNative(JSObject *proxy);
|
||||
static nsISupports* nativeToSupports(ListType* aNative)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче