Bug 1124935 - Remove LookupProperty from JS_GetPropertyDescriptor. r=efaust,bz

This commit is contained in:
Tom Schuster 2015-02-06 15:43:20 +01:00
parent d2c796ffbe
commit 811d8614fd
11 changed files with 70 additions and 58 deletions

View File

@ -96,7 +96,6 @@ shouldThrow(function() {
var getOwn = 0;
var defineProp = 0;
var _has = 0;
var handler2 = {
getOwnPropertyDescriptor: function(target, name) {
if (name == "constructor") {
@ -109,12 +108,6 @@ var handler2 = {
defineProp++;
}
return Object.defineProperty(target, name, propertyDescriptor);
},
has: function(target, name) {
if (name == "constructor") {
_has++;
}
return name in target;
}
};
var proxy2 = new Proxy({}, handler2);
@ -125,8 +118,6 @@ document.registerElement('x-proxymagic2', {
is(getOwn, 1, "number of getOwnPropertyDescriptor calls from registerElement: " + getOwn);
is(defineProp, 1, "number of defineProperty calls from registerElement: " + defineProp);
is(_has, 1, "number of 'has' calls from registerElement: " + _has);
</script>
</head>
@ -139,4 +130,4 @@ is(_has, 1, "number of 'has' calls from registerElement: " + _has);
<pre id="test">
</pre>
</body>
</html>
</html>

View File

@ -88,9 +88,9 @@ GetDataProperty(JSContext *cx, HandleValue objVal, HandlePropertyName field, Mut
if (IsScriptedProxy(obj))
return LinkFail(cx, "accessing property of a Proxy");
Rooted<JSPropertyDescriptor> desc(cx);
Rooted<PropertyDescriptor> desc(cx);
RootedId id(cx, NameToId(field));
if (!JS_GetPropertyDescriptorById(cx, obj, id, &desc))
if (!GetPropertyDescriptor(cx, obj, id, &desc))
return false;
if (!desc.object())

View File

@ -43,6 +43,7 @@ UNIFIED_SOURCES += [
'testGCNursery.cpp',
'testGCOutOfMemory.cpp',
'testGCStoreBufferRemoval.cpp',
'testGetPropertyDescriptor.cpp',
'testHashTable.cpp',
'testHashTableInit.cpp',
'testIndexToString.cpp',

View File

@ -0,0 +1,32 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "jsapi-tests/tests.h"
BEGIN_TEST(test_GetPropertyDescriptor)
{
JS::RootedValue v(cx);
EVAL("({ somename : 123 })", &v);
CHECK(v.isObject());
JS::RootedObject obj(cx, &v.toObject());
JS::Rooted<JSPropertyDescriptor> desc(cx);
CHECK(JS_GetPropertyDescriptor(cx, obj, "somename", &desc));
CHECK_EQUAL(desc.object(), obj);
CHECK_SAME(desc.value(), JS::Int32Value(123));
CHECK(JS_GetPropertyDescriptor(cx, obj, "not-here", &desc));
CHECK_EQUAL(desc.object(), nullptr);
CHECK(JS_GetPropertyDescriptor(cx, obj, "toString", &desc));
JS::RootedObject objectProto(cx, JS_GetObjectPrototype(cx, obj));
CHECK(objectProto);
CHECK_EQUAL(desc.object(), objectProto);
CHECK(desc.value().isObject());
CHECK(JS::IsCallable(&desc.value().toObject()));
return true;
}
END_TEST(test_GetPropertyDescriptor)

View File

@ -2624,46 +2624,6 @@ JS::ParsePropertyDescriptorObject(JSContext *cx,
return true;
}
static bool
GetPropertyDescriptorById(JSContext *cx, HandleObject obj, HandleId id,
MutableHandle<PropertyDescriptor> desc)
{
RootedObject obj2(cx);
RootedShape shape(cx);
if (!LookupProperty(cx, obj, id, &obj2, &shape))
return false;
desc.clear();
if (!shape)
return true;
desc.object().set(obj2);
if (obj2->isNative()) {
if (IsImplicitDenseOrTypedArrayElement(shape)) {
desc.setEnumerable();
desc.value().set(obj2->as<NativeObject>().getDenseOrTypedArrayElement(JSID_TO_INT(id)));
} else {
desc.setAttributes(shape->attributes());
desc.setGetter(shape->getter());
desc.setSetter(shape->setter());
MOZ_ASSERT(desc.value().isUndefined());
if (shape->hasSlot())
desc.value().set(obj2->as<NativeObject>().getSlot(shape->slot()));
}
return true;
}
// When we hit a proxy during lookup, the property might be
// on the prototype of the proxy, thus use getPropertyDescriptor.
if (obj2->is<ProxyObject>())
return Proxy::getPropertyDescriptor(cx, obj2, id, desc);
// Assume other non-natives (i.e. TypedObjects) behave in a sane way.
return GetOwnPropertyDescriptor(cx, obj2, id, desc);
}
JS_PUBLIC_API(bool)
JS_GetOwnPropertyDescriptorById(JSContext *cx, HandleObject obj, HandleId id,
MutableHandle<JSPropertyDescriptor> desc)
@ -2689,7 +2649,7 @@ JS_PUBLIC_API(bool)
JS_GetPropertyDescriptorById(JSContext *cx, HandleObject obj, HandleId id,
MutableHandle<JSPropertyDescriptor> desc)
{
return GetPropertyDescriptorById(cx, obj, id, desc);
return GetPropertyDescriptor(cx, obj, id, desc);
}
JS_PUBLIC_API(bool)

View File

@ -1173,7 +1173,7 @@ SuppressDeletedPropertyHelper(JSContext *cx, HandleObject obj, StringPredicate p
return false;
Rooted<PropertyDescriptor> desc(cx);
if (!JS_GetPropertyDescriptorById(cx, proto, id, &desc))
if (!GetPropertyDescriptor(cx, proto, id, &desc))
return false;
if (desc.object()) {
@ -1183,7 +1183,7 @@ SuppressDeletedPropertyHelper(JSContext *cx, HandleObject obj, StringPredicate p
}
/*
* If JS_GetPropertyDescriptorById above removed a property from
* If GetPropertyDescriptorById above removed a property from
* ni, start over.
*/
if (props_end != ni->props_end || props_cursor != ni->props_cursor)

View File

@ -3338,6 +3338,30 @@ js::SetImmutablePrototype(ExclusiveContext *cx, HandleObject obj, bool *succeede
return true;
}
bool
js::GetPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id,
MutableHandle<PropertyDescriptor> desc)
{
RootedObject pobj(cx);
for (pobj = obj; pobj;) {
if (pobj->is<ProxyObject>())
return Proxy::getPropertyDescriptor(cx, pobj, id, desc);
if (!GetOwnPropertyDescriptor(cx, pobj, id, desc))
return false;
if (desc.object())
return true;
if (!GetPrototype(cx, pobj, &pobj))
return false;
}
MOZ_ASSERT(!desc.object());
return true;
}
bool
js::ToPrimitive(JSContext *cx, HandleObject obj, JSType hint, MutableHandleValue vp)
{

View File

@ -925,6 +925,10 @@ DeleteElement(JSContext *cx, js::HandleObject obj, uint32_t index, bool *succeed
extern bool
SetImmutablePrototype(js::ExclusiveContext *cx, JS::HandleObject obj, bool *succeeded);
extern bool
GetPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id,
MutableHandle<PropertyDescriptor> desc);
/*
* Deprecated. A version of HasProperty that also returns the object on which
* the property was found (but that information is unreliable for proxies), and

View File

@ -20,7 +20,7 @@ DirectProxyHandler::getPropertyDescriptor(JSContext *cx, HandleObject proxy, Han
assertEnteredPolicy(cx, proxy, id, GET | SET | GET_PROPERTY_DESCRIPTOR);
MOZ_ASSERT(!hasPrototype()); // Should never be called if there's a prototype.
RootedObject target(cx, proxy->as<ProxyObject>().target());
return JS_GetPropertyDescriptorById(cx, target, id, desc);
return GetPropertyDescriptor(cx, target, id, desc);
}
bool

View File

@ -111,7 +111,7 @@ Proxy::getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
return false;
if (desc.object())
return true;
INVOKE_ON_PROTOTYPE(cx, handler, proxy, JS_GetPropertyDescriptorById(cx, proto, id, desc));
INVOKE_ON_PROTOTYPE(cx, handler, proxy, GetPropertyDescriptor(cx, proto, id, desc));
}
bool

View File

@ -429,7 +429,7 @@ ScriptedDirectProxyHandler::getPropertyDescriptor(JSContext *cx, HandleObject pr
MOZ_ASSERT(!desc.object());
return true;
}
return JS_GetPropertyDescriptorById(cx, proto, id, desc);
return GetPropertyDescriptor(cx, proto, id, desc);
}
// ES6 (5 April 2014) 9.5.5 Proxy.[[GetOwnProperty]](P)