ScriptObject* ScriptObject::getSlotObject(uint32_t slot) { Traits* traits = this->traits(); const TraitsBindingsp td = traits->getTraitsBindings(); void* p; const SlotStorageType sst = td->calcSlotAddrAndSST(slot, (void*)this, p); // based on profiling of Flex apps, it's *much* more common for the slot in this case // to have a type (vs "atom"), so check for that first... if (sst == SST_scriptobject) { return *((ScriptObject**)p); } else if (sst == SST_atom) { Atom const a = *((const Atom*)p); // don't call AvmCore::isObject(); it checks for null, which we don't care about here if (atomKind(a) == kObjectType) return (ScriptObject*)atomPtr(a); // else fall thru and return null } return NULL; }
Stringp Namespace::getURI() const { return (Stringp)atomPtr(m_uri); }
// note: coerceAndSetSlotAtom now includes a simplified and streamlined version // of Toplevel::coerce. If you modify that code, you might need to modify this code. void ScriptObject::coerceAndSetSlotAtom(uint32_t slot, Atom value) { Traits* traits = this->traits(); const TraitsBindingsp td = traits->getTraitsBindings(); void* p; const SlotStorageType sst = td->calcSlotAddrAndSST(slot, (void*)this, p); // repeated if-else is actually more performant than a switch statement in this case. // SST_atom is most common case, put it first if (sst == SST_atom) { // no call to coerce() needed, since anything will fit here... with one exception: // BUILTIN_object needs to convert undefined->null (though BUILTIN_any does not). // it's cheaper to do that here than call out to coerce(). AvmAssert(td->getSlotTraits(slot) == NULL || td->getSlotTraits(slot)->builtinType == BUILTIN_object); if (value == undefinedAtom && td->getSlotTraits(slot) != NULL) value = nullObjectAtom; WBATOM(traits->core->GetGC(), this, (Atom*)p, value); } else if (sst == SST_double) { *((double*)p) = AvmCore::number(value); } else if (sst == SST_int32) { *((int32_t*)p) = AvmCore::integer(value); } else if (sst == SST_uint32) { *((uint32_t*)p) = AvmCore::toUInt32(value); } else if (sst == SST_bool32) { *((int32_t*)p) = AvmCore::boolean(value); } else { // null/undefined -> NULL for all of these if (AvmCore::isNullOrUndefined(value)) { value = (Atom)0; // don't bother setting tag bits } else if (sst == SST_string) { value = (Atom)traits->core->string(value); // don't bother setting tag bits } else if (sst == SST_namespace) { // Namespace is final, so we don't have to do the hard work if (atomKind(value) != kNamespaceType) goto failure; } else // if (sst == SST_scriptobject) { AvmAssert(sst == SST_scriptobject); if (atomKind(value) != kObjectType || !AvmCore::atomToScriptObject(value)->traits()->subtypeof(td->getSlotTraits(slot))) goto failure; } WBRC(traits->core->GetGC(), this, p, atomPtr(value)); } return; failure: toplevel()->throwTypeError(kCheckTypeFailedError, traits->core->atomToErrorString(value), traits->core->toErrorString(td->getSlotTraits(slot))); return; }
Namespace* Stubs::do_atom2ns(MethodFrame*, Atom x) { assert(AvmCore::isNamespace(x) || AvmCore::isNull(x)); return (Namespace*)atomPtr(x); }
String* Stubs::do_atom2string(MethodFrame*, Atom x) { assert(AvmCore::isString(x) || AvmCore::isNull(x)); return (String*)atomPtr(x); }
ScriptObject* Stubs::do_atom2scriptobject(MethodFrame*, Atom x) { assert(AvmCore::isObject(x) || AvmCore::isNull(x)); return (ScriptObject*)atomPtr(x); }
Namespace* Stubs::do_castns(MethodFrame* f, Atom value) { coercens_atom(env(f), value); return (Namespace*)atomPtr(value); }