/** 15.2.4.5 Object.prototype.hasOwnProperty (V) When the hasOwnProperty method is called with argument V, the following steps are taken: 1. Let O be this object. 2. Call ToString(V). 3. If O doesn't have a property with the name given by Result(2), return false. 4. Return true. NOTE Unlike [[HasProperty]] (section 8.6.2.4), this method does not consider objects in the prototype chain. */ bool ObjectClass::_hasOwnProperty(Atom thisAtom, Stringp name) { AvmCore* core = this->core(); name = name ? core->internString(name) : (Stringp)core->knull; Traitsp t = NULL; switch (atomKind(thisAtom)) { case kObjectType: { // ISSUE should this look in traits and dynamic vars, or just dynamic vars. ScriptObject* obj = AvmCore::atomToScriptObject(thisAtom); // TODO // The change below is important as otherwise we will throw error in a call to hasAtomProperty for ByteArrayObject. // This gets us back to the behaviour which we had in Marlin. // A bugzilla bug [ 562224 ] has been created to address this issue more cleanly in near future return obj->traits()->getTraitsBindings()->findBinding(name, core->findPublicNamespace()) != BIND_NONE || obj->hasStringProperty(name); } case kNamespaceType: case kStringType: case kBooleanType: case kDoubleType: case kIntptrType: t = toplevel()->toTraits(thisAtom); break; default: return false; } // NOTE use caller's public namespace return t->getTraitsBindings()->findBinding(name, core->findPublicNamespace()) != BIND_NONE; }
// Execute the ToString algorithm as described in ECMA-262 Section 9.8. // This is ToString(ToPrimitive(input argument, hint String)) // ToPrimitive(input argument, hint String) calls [[DefaultValue]] // described in ECMA-262 8.6.2.6. The [[DefaultValue]] algorithm // with hint String is inlined here. Stringp ScriptObject::toString() { AvmCore *core = this->core(); Toplevel* toplevel = this->toplevel(); Atom atomv_out[1]; // call this.toString() // NOTE use callers versioned public to get correct toString Multiname tempname(core->findPublicNamespace(), core->ktoString); atomv_out[0] = atom(); Atom result = toplevel->callproperty(atom(), &tempname, 0, atomv_out, vtable); // if result is primitive, return its ToString if (atomKind(result) != kObjectType) return core->string(result); // otherwise call this.valueOf() tempname.setName(core->kvalueOf); atomv_out[0] = atom(); result = toplevel->callproperty(atom(), &tempname, 0, atomv_out, vtable); // if result is primitive, return it if (atomKind(result) != kObjectType) return core->string(result); // could not convert to primitive. toplevel->throwTypeError(kConvertToPrimitiveError, core->toErrorString(traits())); return NULL; // unreachable }
Atom VectorBaseObject::getAtomProperty(Atom name) const { uint32 index; bool isNumber=false; AvmCore* core = this->core(); if (getVectorIndex(name, index, isNumber)) { return getUintProperty(index); } else { if(isNumber) { // Not a valid indexed name - has a decimal part // NOTE use default public for message gen Multiname mn(core->findPublicNamespace(), core->string(name)); toplevel()->throwReferenceError(kReadSealedError, &mn, traits()); } // Check the prototype chain - that will throw if there is no match return getAtomPropertyFromProtoChain(name, getDelegate(), traits()); } }
// E4X 10.4, pg 36 Atom XMLListClass::ToXMLList(Atom arg) { AvmCore* core = this->core(); if (AvmCore::isNullOrUndefined(arg)) { toplevel()->throwTypeError( (arg == undefinedAtom) ? kConvertUndefinedToObjectError : kConvertNullToObjectError); return arg; } if (AvmCore::isXMLList(arg)) { return arg; } else if (AvmCore::isXML(arg)) { XMLObject *x = AvmCore::atomToXMLObject(arg); Multiname m; bool bFound = x->getQName (&m); Atom parent = x->parent(); if (parent == undefinedAtom) parent = nullObjectAtom; XMLListObject *xl = XMLListObject::create(core->GetGC(), toplevel()->xmlListClass(), parent, bFound ? &m : 0); xl->_append (arg); return xl->atom(); } else { Toplevel* toplevel = this->toplevel(); Stringp s = core->string(arg); if (s->matchesLatin1("<>", 2, 0) && s->matchesLatin1("</>", 3, s->length()-3)) s = s->substr(2, s->length() - 5); Namespace *defaultNamespace = toplevel->getDefaultNamespace(); // We handle this step in the XMLObject constructor to avoid concatenation huge strings together // parentString = <parent xnlns=defaultNamespace> s </parent> // 3. Parse parentString as a W3C element information info e // 4. If the parse fails, throw a SyntaxError exception // 5. x = toXML(e); //StringBuffer parentString (core); //parentString << "<parent xmlns=\""; //parentString << defaultNamespace->getURI(); //parentString << "\">"; //parentString << s; //parentString << "</parent>"; XMLObject *x = XMLObject::create(core->GetGC(), toplevel->xmlClass(), s, defaultNamespace); XMLListObject *xl = XMLListObject::create(core->GetGC(), toplevel->xmlListClass()); for (uint32_t i = 0; i < x->getNode()->_length(); i++) { E4XNode *c = x->getNode()->_getAt (i); c->setParent (NULL); // !!@ trying to emulate rhino behavior here // Add the default namespace to our top element. Namespace *ns = toplevel->getDefaultNamespace(); c->_addInScopeNamespace (core, ns, core->findPublicNamespace()); xl->_appendNode (c); } return xl->atom(); } }