Atom ScriptObject::getAtomPropertyFromProtoChain(Atom name, ScriptObject* o, Traits *origObjTraits) const { // todo will delegate always be non-null here? if (o != NULL) { Atom searchname = name; Stringp s = core()->atomToString(name); AvmAssert(s->isInterned()); Atom ival = s->getIntAtom(); if (ival) { searchname = ival; } do { // ensure prototype is dynamic if (!o->vtable->traits->getHashtableOffset()) continue; Atom const value = o->getTable()->getNonEmpty(searchname); if (!InlineHashtable::isEmpty(value)) return value; } while ((o = o->delegate) != NULL); } // NOTE use default public since name is not used Multiname multiname(core()->getAnyPublicNamespace(), AvmCore::atomToString(name)); toplevel()->throwReferenceError(kReadSealedError, &multiname, origObjTraits); // unreached return undefinedAtom; }
/** * traverse the delegate chain looking for a value. * [ed] it's okay to look only at the HT's in the delegate chain because * delegate values may only be instances of Object. They cannot be objects * with slots. We don't need to look at traits at each step. * todo - enforce this rule * @param name * @return */ Atom ScriptObject::getAtomProperty(Atom name) const { if (!traits()->needsHashtable()) { return getAtomPropertyFromProtoChain(name, delegate, traits()); } else { Stringp s = core()->atomToString(name); AvmAssert(s->isInterned()); Atom ival = s->getIntAtom(); if (ival) { name = ival; } // dynamic lookup on this object const ScriptObject *o = this; do { // ensure prototype is dynamic if (!o->vtable->traits->getHashtableOffset()) continue; Atom const value = o->getTable()->getNonEmpty(name); if (!InlineHashtable::isEmpty(value)) return value; } while ((o = o->delegate) != NULL); return undefinedAtom; } }
void ScriptObject::setAtomPropertyIsEnumerable(Atom name, bool enumerable) { if (traits()->needsHashtable()) { Stringp s = core()->atomToString(name); AvmAssert(s->isInterned()); Atom ival = s->getIntAtom(); if (ival) { name = ival; } getTable()->setAtomPropertyIsEnumerable(name, enumerable); } else { throwWriteSealedError(name); } }
bool ScriptObject::deleteAtomProperty(Atom name) { if (traits()->needsHashtable()) { Stringp s = core()->atomToString(name); AvmAssert(s->isInterned()); Atom ival = s->getIntAtom(); if (ival) { name = ival; } getTable()->remove(name); return true; } else { return false; } }
bool ScriptObject::getAtomPropertyIsEnumerable(Atom name) const { if (traits()->needsHashtable()) { Stringp s = core()->atomToString(name); AvmAssert(s->isInterned()); Atom ival = s->getIntAtom(); if (ival) { name = ival; } return getTable()->getAtomPropertyIsEnumerable(name); } else { // ISSUE should this walk the proto chain? return false; } }
void ScriptObject::setAtomProperty(Atom name, Atom value) { if (traits()->needsHashtable()) { Stringp s = core()->atomToString(name); AvmAssert(s->isInterned()); Atom ival = s->getIntAtom(); if (ival) { name = ival; } MMGC_MEM_TYPE(this); getTable()->add (name, value); MMGC_MEM_TYPE(NULL); } else { throwWriteSealedError(name); } }