Bug 714218 - Specialize some get* implementations to do property-type-specific handling, with their getGeneric forwarding to the appropriate specific implementation. r=bhackett

--HG--
extra : rebase_source : 1fcbac06cb7215b00a5756cef659318e6368fc49
This commit is contained in:
Jeff Walden 2011-09-15 11:44:10 -07:00
parent e3c4951e46
commit fd5ff3e57f
6 changed files with 103 additions and 66 deletions

View File

@ -776,60 +776,45 @@ js_GetDenseArrayElementValue(JSContext *cx, JSObject *obj, jsid id, Value *vp)
}
static JSBool
array_getGeneric(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, Value *vp)
array_getProperty(JSContext *cx, JSObject *obj, JSObject *receiver, PropertyName *name, Value *vp)
{
uint32_t i;
if (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom)) {
if (name == cx->runtime->atomState.lengthAtom) {
vp->setNumber(obj->getArrayLength());
return JS_TRUE;
return true;
}
if (JSID_IS_ATOM(id, cx->runtime->atomState.protoAtom)) {
if (name == cx->runtime->atomState.protoAtom) {
vp->setObjectOrNull(obj->getProto());
return JS_TRUE;
return true;
}
if (!obj->isDenseArray())
return js_GetProperty(cx, obj, id, vp);
return js_GetProperty(cx, obj, receiver, ATOM_TO_JSID(name), vp);
if (!js_IdIsIndex(id, &i) || i >= obj->getDenseArrayInitializedLength() ||
obj->getDenseArrayElement(i).isMagic(JS_ARRAY_HOLE)) {
JSObject *proto = obj->getProto();
if (!proto) {
vp->setUndefined();
return JS_TRUE;
}
return proto->getGeneric(cx, receiver, id, vp);
JSObject *proto = obj->getProto();
if (!proto) {
vp->setUndefined();
return true;
}
*vp = obj->getDenseArrayElement(i);
/* Type information for dense array elements must be correct. */
JS_ASSERT_IF(!obj->hasSingletonType(),
js::types::TypeHasProperty(cx, obj->type(), JSID_VOID, *vp));
return JS_TRUE;
}
static JSBool
array_getProperty(JSContext *cx, JSObject *obj, JSObject *receiver, PropertyName *name, Value *vp)
{
return array_getGeneric(cx, obj, receiver, ATOM_TO_JSID(name), vp);
return proto->getProperty(cx, receiver, name, vp);
}
static JSBool
array_getElement(JSContext *cx, JSObject *obj, JSObject *receiver, uint32_t index, Value *vp)
{
if (!obj->isDenseArray())
return js_GetElement(cx, obj, index, vp);
return js_GetElement(cx, obj, receiver, index, vp);
if (index < obj->getDenseArrayInitializedLength() &&
!obj->getDenseArrayElement(index).isMagic(JS_ARRAY_HOLE))
{
if (index < obj->getDenseArrayInitializedLength()) {
*vp = obj->getDenseArrayElement(index);
return true;
if (!vp->isMagic(JS_ARRAY_HOLE)) {
/* Type information for dense array elements must be correct. */
JS_ASSERT_IF(!obj->hasSingletonType(),
js::types::TypeHasProperty(cx, obj->type(), JSID_VOID, *vp));
return true;
}
}
JSObject *proto = obj->getProto();
@ -844,7 +829,35 @@ array_getElement(JSContext *cx, JSObject *obj, JSObject *receiver, uint32_t inde
static JSBool
array_getSpecial(JSContext *cx, JSObject *obj, JSObject *receiver, SpecialId sid, Value *vp)
{
return array_getGeneric(cx, obj, receiver, SPECIALID_TO_JSID(sid), vp);
if (obj->isDenseArray() && !obj->getProto()) {
vp->setUndefined();
return true;
}
return js_GetProperty(cx, obj, receiver, SPECIALID_TO_JSID(sid), vp);
}
static JSBool
array_getGeneric(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, Value *vp)
{
Value idval = IdToValue(id);
uint32_t index;
if (IsDefinitelyIndex(idval, &index))
return array_getElement(cx, obj, receiver, index, vp);
SpecialId sid;
if (ValueIsSpecial(obj, &idval, &sid, cx))
return array_getSpecial(cx, obj, receiver, sid, vp);
JSAtom *atom;
if (!js_ValueToAtom(cx, idval, &atom))
return false;
if (atom->isIndex(&index))
return array_getElement(cx, obj, receiver, index, vp);
return array_getProperty(cx, obj, receiver, atom->asPropertyName(), vp);
}
static JSBool

View File

@ -3216,7 +3216,7 @@ BEGIN_CASE(JSOP_GETELEM)
SpecialId special;
if (ValueIsSpecial(obj, &rref, &special, cx)) {
if (!obj->getSpecial(cx, special, &rval))
if (!obj->getSpecial(cx, obj, special, &rval))
goto error;
} else {
JSAtom *name;

View File

@ -1324,9 +1324,9 @@ JSObject::getElementIfPresent(JSContext *cx, JSObject *receiver, uint32_t index,
}
inline JSBool
JSObject::getSpecial(JSContext *cx, js::SpecialId sid, js::Value *vp)
JSObject::getSpecial(JSContext *cx, JSObject *receiver, js::SpecialId sid, js::Value *vp)
{
return getGeneric(cx, SPECIALID_TO_JSID(sid), vp);
return getGeneric(cx, receiver, SPECIALID_TO_JSID(sid), vp);
}
inline JSBool

View File

@ -397,7 +397,16 @@ JSBool
ArrayBuffer::obj_getProperty(JSContext *cx, JSObject *obj, JSObject *receiver, PropertyName *name,
Value *vp)
{
return obj_getGeneric(cx, obj, receiver, ATOM_TO_JSID(name), vp);
obj = getArrayBuffer(obj);
if (name == cx->runtime->atomState.byteLengthAtom) {
vp->setInt32(obj->arrayBufferByteLength());
return true;
}
JSObject *delegate = DelegateObject(cx, obj);
if (!delegate)
return false;
return js_GetProperty(cx, delegate, receiver, ATOM_TO_JSID(name), vp);
}
JSBool
@ -1012,36 +1021,23 @@ class TypedArrayTemplate
}
static JSBool
obj_getGeneric(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, Value *vp)
obj_getProperty(JSContext *cx, JSObject *obj, JSObject *receiver, PropertyName *name,
Value *vp)
{
JSObject *tarray = getTypedArray(obj);
if (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom)) {
if (name == cx->runtime->atomState.lengthAtom) {
vp->setNumber(getLength(tarray));
return true;
}
jsuint index;
if (isArrayIndex(cx, tarray, id, &index)) {
// this inline function is specialized for each type
copyIndexToValue(cx, tarray, index, vp);
return true;
}
JSObject *proto = obj->getProto();
if (!proto) {
vp->setUndefined();
return true;
}
return proto->getGeneric(cx, receiver, id, vp);
}
static JSBool
obj_getProperty(JSContext *cx, JSObject *obj, JSObject *receiver, PropertyName *name,
Value *vp)
{
return obj_getGeneric(cx, obj, receiver, ATOM_TO_JSID(name), vp);
return proto->getProperty(cx, receiver, name, vp);
}
static JSBool
@ -1050,7 +1046,6 @@ class TypedArrayTemplate
JSObject *tarray = getTypedArray(obj);
if (index < getLength(tarray)) {
// this inline function is specialized for each type
copyIndexToValue(cx, tarray, index, vp);
return true;
}
@ -1064,6 +1059,41 @@ class TypedArrayTemplate
return proto->getElement(cx, receiver, index, vp);
}
static JSBool
obj_getSpecial(JSContext *cx, JSObject *obj, JSObject *receiver, SpecialId sid, Value *vp)
{
JSObject *proto = obj->getProto();
if (!proto) {
vp->setUndefined();
return true;
}
return proto->getSpecial(cx, receiver, sid, vp);
}
static JSBool
obj_getGeneric(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, Value *vp)
{
Value idval = IdToValue(id);
uint32_t index;
if (IsDefinitelyIndex(idval, &index))
return obj_getElement(cx, obj, receiver, index, vp);
SpecialId sid;
if (ValueIsSpecial(obj, &idval, &sid, cx))
return obj_getSpecial(cx, obj, receiver, sid, vp);
JSAtom *atom;
if (!js_ValueToAtom(cx, idval, &atom))
return false;
if (atom->isIndex(&index))
return obj_getElement(cx, obj, receiver, index, vp);
return obj_getProperty(cx, obj, receiver, atom->asPropertyName(), vp);
}
static JSBool
obj_getElementIfPresent(JSContext *cx, JSObject *obj, JSObject *receiver, uint32_t index, Value *vp, bool *present)
{
@ -1086,12 +1116,6 @@ class TypedArrayTemplate
return proto->getElementIfPresent(cx, receiver, index, vp, present);
}
static JSBool
obj_getSpecial(JSContext *cx, JSObject *obj, JSObject *receiver, SpecialId sid, Value *vp)
{
return obj_getGeneric(cx, obj, receiver, SPECIALID_TO_JSID(sid), vp);
}
static bool
setElementTail(JSContext *cx, JSObject *tarray, uint32_t index, Value *vp, JSBool strict)
{

View File

@ -7586,7 +7586,7 @@ js_GetDefaultXMLNamespace(JSContext *cx, jsval *vp)
for (tmp = scopeChain; tmp; tmp = tmp->enclosingScope()) {
if (tmp->isBlock() || tmp->isWith())
continue;
if (!tmp->getSpecial(cx, SpecialId::defaultXMLNamespace(), &v))
if (!tmp->getSpecial(cx, tmp, SpecialId::defaultXMLNamespace(), &v))
return JS_FALSE;
if (!JSVAL_IS_PRIMITIVE(v)) {
*vp = v;

View File

@ -404,7 +404,7 @@ stubs::GetElem(VMFrame &f)
} else {
SpecialId special;
if (ValueIsSpecial(obj, &rref, &special, cx)) {
if (!obj->getSpecial(cx, special, &rval))
if (!obj->getSpecial(cx, obj, special, &rval))
THROW();
} else {
JSAtom *name;