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; }