예제 #1
0
bool
js::GetProperty(JSContext *cx, Handle<ObjectImpl*> obj, Handle<ObjectImpl*> receiver,
                Handle<PropertyId> pid, unsigned resolveFlags, MutableHandle<Value> vp)
{
    NEW_OBJECT_REPRESENTATION_ONLY();

    MOZ_ASSERT(receiver);

    Rooted<ObjectImpl*> current(cx, obj);

    do {
        MOZ_ASSERT(obj);

        if (Downcast(current)->isProxy()) {
            MOZ_NOT_REACHED("NYI: proxy [[GetP]]");
            return false;
        }

        PropDesc desc;
        PropDesc::AutoRooter rootDesc(cx, &desc);
        if (!GetOwnProperty(cx, current, pid, resolveFlags, &desc))
            return false;

        /* No property?  Recur or bottom out. */
        if (desc.isUndefined()) {
            current = current->getProto();
            if (current)
                continue;

            vp.setUndefined();
            return true;
        }

        /* If it's a data property, return the value. */
        if (desc.isDataDescriptor()) {
            vp.set(desc.value());
            return true;
        }

        /* If it's an accessor property, call its [[Get]] with the receiver. */
        if (desc.isAccessorDescriptor()) {
            Rooted<Value> get(cx, desc.getterValue());
            if (get.isUndefined()) {
                vp.setUndefined();
                return true;
            }

            InvokeArgsGuard args;
            if (!cx->stack.pushInvokeArgs(cx, 0, &args))
                return false;

            args.setCallee(get);
            args.setThis(ObjectValue(*receiver));

            bool ok = Invoke(cx, args);
            vp.set(args.rval());
            return ok;
        }

        /* Otherwise it's a PropertyOp-based property.  XXX handle this! */
        MOZ_NOT_REACHED("NYI: handle PropertyOp'd properties here");
        return false;
    } while (false);

    MOZ_NOT_REACHED("buggy control flow");
    return false;
}