VTable* VTable::newParameterizedVTable(Traits* param_traits, Stringp fullname) { Toplevel* toplevel = this->toplevel(); AvmCore* core = toplevel->core(); Namespacep traitsNs = this->traits->ns(); GCRef<builtinClassManifest> builtinClasses = toplevel->builtinClasses(); GCRef<ObjectVectorClass> vectorobj_cls = builtinClasses->get_Vector_objectClass(); GCRef<ScopeChain> vectorobj_cscope = vectorobj_cls->vtable->init->scope(); GCRef<ScopeChain> vectorobj_iscope = vectorobj_cls->ivtable()->init->scope(); VTable* objVecVTable = vectorobj_cls->vtable; AbcEnv* objVecAbcEnv = vectorobj_cscope->abcEnv(); Toplevel* objVecToplevel = objVecVTable->toplevel(); VTable* objVecIVTable = objVecVTable->ivtable; // these cases should all be filtered out by the caller; // we only want to handle Vector<SomeObject> here AvmAssert(param_traits != NULL && param_traits != toplevel->intClass()->vtable->traits->itraits && param_traits != toplevel->uintClass()->vtable->traits->itraits && param_traits != toplevel->numberClass()->vtable->traits->itraits); PoolObject* traitsPool = this->traits->pool; Stringp classname = core->internString(fullname->appendLatin1("$")); Traits* ctraits = core->domainMgr()->findTraitsInPoolByNameAndNS(traitsPool, classname, traitsNs); Traits* itraits; if (!ctraits) { // important: base the new ctraits on objVecVTable->traits, *not* this->traits; // we want the result to be based off ObjectVectorClass, not VectorClass // (otherwise sizeofInstance would be too small and we'd be crashy) ctraits = objVecVTable->traits->newParameterizedCTraits(classname, traitsNs); ctraits->verifyBindings(toplevel); itraits = traitsPool->resolveParameterizedType(toplevel, this->ivtable->traits, param_traits); ctraits->itraits = itraits; } else { itraits = ctraits->itraits; } AvmAssert(itraits != NULL); VTable* class_ivtable = builtinClasses->get_ClassClass()->ivtable(); VTable* cvtab = core->newVTable(ctraits, class_ivtable, objVecToplevel); ScopeChain* cvtab_cscope = vectorobj_cscope->cloneWithNewVTable(core->GetGC(), cvtab, objVecAbcEnv); VTable* ivtab = core->newVTable(itraits, objVecIVTable, objVecToplevel); ScopeChain* ivtab_iscope = vectorobj_iscope->cloneWithNewVTable(core->GetGC(), ivtab, objVecAbcEnv); cvtab->ivtable = ivtab; ivtab->init = objVecIVTable->init; cvtab->resolveSignatures(cvtab_cscope); ivtab->resolveSignatures(ivtab_iscope); return cvtab; }
bool ProxyObject::flash_proxy_isAttribute(Atom name) { if (!AvmCore::isQName(name)) return false; GCRef<QNameObject> q = AvmCore::atomToQName(name); return q->isAttr(); }
Atom ProxyObject::getDescendants(const Multiname* name) const { GCRef<Toplevel> toplevel = this->toplevel(); GCRef<builtinClassManifest> builtinClasses = toplevel->builtinClasses(); GCRef<QNameObject> q = QNameObject::create(core()->GetGC(), builtinClasses->get_QNameClass(), *name); Atom argv[] = { atom(), q->atom() }; int const argc = 1; Binding b = builtinClasses->get_ProxyClass()->m_getDescendants; GCRef<MethodEnv> method = vtable->methods[AvmCore::bindingToMethodId(b)]; return method->coerceEnter(argc, argv); }
bool ProxyObject::deleteMultinameProperty(const Multiname* name) { GCRef<Toplevel> toplevel = this->toplevel(); GCRef<builtinClassManifest> builtinClasses = toplevel->builtinClasses(); GCRef<QNameObject> q = QNameObject::create(core()->GetGC(), builtinClasses->get_QNameClass(), *name); Atom argv[] = { atom(), q->atom() }; int const argc = 1; Binding b = builtinClasses->get_ProxyClass()->m_deleteProperty; GCRef<MethodEnv> method = vtable->methods[AvmCore::bindingToMethodId(b)]; return method->coerceEnter(argc, argv) != falseAtom; }
void ProxyObject::setMultinameProperty(const Multiname* name, Atom value) { GCRef<Toplevel> toplevel = this->toplevel(); GCRef<builtinClassManifest> builtinClasses = toplevel->builtinClasses(); GCRef<QNameObject> q = QNameObject::create(core()->GetGC(), builtinClasses->get_QNameClass(), *name); Atom argv[] = { atom(), q->atom(), value }; int const argc = 2; Binding b = builtinClasses->get_ProxyClass()->m_setProperty; GCRef<MethodEnv> method = vtable->methods[AvmCore::bindingToMethodId(b)]; method->coerceEnter(argc, argv); }
Atom ProxyObject::callProperty(const Multiname* name, int argc, Atom* argv) { GCRef<Toplevel> toplevel = this->toplevel(); GCRef<builtinClassManifest> builtinClasses = toplevel->builtinClasses(); int proxy_argc = argc+1; MMgc::GC::AllocaAutoPtr proxy_argv_autoptr; Atom* proxy_argv = (Atom*) avmStackAllocArray(core(), proxy_argv_autoptr, proxy_argc+1, sizeof(Atom)); GCRef<QNameObject> q = QNameObject::create(core()->GetGC(), builtinClasses->get_QNameClass(), *name); proxy_argv[0] = atom(); proxy_argv[1] = q->atom(); for (int i = 1; i <= argc; i++) { proxy_argv[i+1] = argv[i]; } Binding b = builtinClasses->get_ProxyClass()->m_callProperty; GCRef<MethodEnv> method = vtable->methods[AvmCore::bindingToMethodId(b)]; return method->coerceEnter(proxy_argc, proxy_argv); }
bool ProxyObject::hasUintProperty(uint32_t i) const { GCRef<Toplevel> toplevel = this->toplevel(); GCRef<builtinClassManifest> builtinClasses = toplevel->builtinClasses(); Binding b = builtinClasses->get_ProxyClass()->m_hasProperty; Atom argv[] = { atom(), core()->internUint32(i)->atom() }; int const argc = 1; GCRef<MethodEnv> method = vtable->methods[AvmCore::bindingToMethodId(b)]; return method->coerceEnter(argc, argv) != falseAtom; }
bool ProxyObject::deleteAtomProperty(Atom name) { GCRef<Toplevel> toplevel = this->toplevel(); GCRef<builtinClassManifest> builtinClasses = toplevel->builtinClasses(); Binding b = builtinClasses->get_ProxyClass()->m_deleteProperty; Atom argv[] = { atom(), name }; int const argc = 1; GCRef<MethodEnv> method = vtable->methods[AvmCore::bindingToMethodId(b)]; return method->coerceEnter(argc, argv) != falseAtom; }
void ProxyObject::setAtomProperty(Atom name, Atom value) { GCRef<Toplevel> toplevel = this->toplevel(); GCRef<builtinClassManifest> builtinClasses = toplevel->builtinClasses(); Binding b = builtinClasses->get_ProxyClass()->m_setProperty; Atom argv[3] = { atom(), name, value }; int const argc = 2; GCRef<MethodEnv> method = vtable->methods[AvmCore::bindingToMethodId(b)]; method->coerceEnter(argc, argv); }
Atom ProxyObject::nextValue(int index) { GCRef<Toplevel> toplevel = this->toplevel(); GCRef<builtinClassManifest> builtinClasses = toplevel->builtinClasses(); Atom argv[] = { atom(), core()->intToAtom (index) }; int const argc = 1; Binding b = builtinClasses->get_ProxyClass()->m_nextValue; GCRef<MethodEnv> method = vtable->methods[AvmCore::bindingToMethodId(b)]; return method->coerceEnter(argc, argv); }
void AvmplusHostContext::throwInternalError(const char* msgz) { // FIXME - proper error ID? GCRef<ErrorObject> e = toplevel->errorClass()->constructObject(core->newStringUTF8(msgz)->atom(), core->intToAtom(0)); core->throwAtom(e->atom()); }