// 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 }
// this = argv[0] (ignored) // arg1 = argv[1] // argN = argv[argc] Atom ScriptObject::callProperty(const Multiname* multiname, int argc, Atom* argv) { Toplevel* toplevel = this->toplevel(); Atom method = getMultinameProperty(multiname); if (!AvmCore::isObject(method)) toplevel->throwTypeError(kCallOfNonFunctionError, core()->toErrorString(multiname)); argv[0] = atom(); // replace receiver return toplevel->op_call(method, argc, argv); }
// E4X 10.3, page 32 Atom XMLClass::ToXML(Atom arg) { Toplevel* toplevel = this->toplevel(); AvmCore* core = this->core(); if (AvmCore::isNullOrUndefined(arg)) { toplevel->throwTypeError( (arg == undefinedAtom) ? kConvertUndefinedToObjectError : kConvertNullToObjectError); return arg; } else if (AvmCore::isXML(arg)) { return arg; } else if (AvmCore::isXMLList(arg)) { XMLListObject *xl = AvmCore::atomToXMLList(arg); if (xl->_length() == 1) { return xl->_getAt(0)->atom(); } else { toplevel->throwTypeError(kXMLMarkupMustBeWellFormed); return 0;//notreached } } else { Namespace *defaultNamespace = toplevel->getDefaultNamespace(); // 2. Parse parentString as a W3C element information info e // 3. If the parse fails, throw a SyntaxError exception XMLObject *x = new (core->GetGC()) XMLObject(toplevel->xmlClass(), core->string(arg), defaultNamespace); // 4. x = toXML(e); // 5. if x.length == 0 // return new xml object if (!x->getNode()->_length()) { x->setNode( new (core->GetGC()) TextE4XNode(0, core->kEmptyString) ); } // 6. else if x.length == 1 // x[0].parent = null // return x[0] else if (x->getNode()->_length() == 1) { x->setNode( x->getNode()->_getAt (0)); // discard parent node x->getNode()->setParent (0); } // 7. else throw a syntaxError else { // check for multiple nodes where the first n-1 are PI/comment nodes and the // last one is an element node. Just ignore the PI/comment nodes and return // the element node. (bug 148526). // Will also now ignore any text nodes that just contain whitespace (leading // or trailing) the one valid element node. If multiple element nodes are found, // that is a failing case as well. (bug 192355) E4XNode *node = x->getNode(); E4XNode *validNode = NULL; for (uint32 i = 0; i < node->_length(); i++) { E4XNode *n = node->_getAt (i); if (n->getClass() == E4XNode::kElement) { if (validNode != NULL) toplevel->throwTypeError(kXMLMarkupMustBeWellFormed); validNode = n; } else if (n->getClass() == E4XNode::kText) { if (!n->getValue()->isWhitespace()) { toplevel->throwTypeError(kXMLMarkupMustBeWellFormed); } } } // No valid nodes found if (!validNode) toplevel->throwTypeError(kXMLMarkupMustBeWellFormed); x->setNode( validNode ); // discard parent node validNode->setParent (0); } return x->atom(); } }