Пример #1
0
ScriptEnv* DomainMgr::mapScriptToScriptEnv(DomainEnv* domainEnv, MethodInfo* mi)
{
    ScriptEnv* se = NULL;
    if (mi != NULL)
    {
        se = domainEnv->m_scriptEnvMap->get(mi);
        if (se == NULL)
        {
            // This is an item from a parent domain that's not in the MI->SE map yet.
            // walk up the parent chain and find it. This can happen if
            // we find a (cached) entry from a parent Domain; since addNamedScriptEnvs()
            // only added mappings for the MI/SE's in this Domain/DomainEnv pair,
            // we won't have the proper mapping. However, we know it must be in
            // a parent (which is why we start at 1, not 0: no point in looking
            // in our own map again), so lazily find it.
            for (uint32_t i = 1, n = domainEnv->m_baseCount; i < n; ++i)
            {
                DomainEnv* de = domainEnv->m_bases[i];
                if (mi->pool()->domain == de->domain())
                {
                    se = de->m_scriptEnvMap->get(mi);
                    AvmAssert(se != NULL);
                    domainEnv->m_scriptEnvMap->add(mi, se);
                    break;
                }
            }
        }
        // If the MethodInfo was entered, but the script then failed verification,
        // we might not have a matching ScriptEnv... so don't crash in Debug builds.
        // (Caller already expects NULL and checks for it.)
        AvmAssert(se == NULL || se->method == mi);
    }
    return se;
}
Пример #2
0
DomainEnv::DomainEnv(AvmCore* core, Domain* domain, DomainEnv* base, uint32_t baseCount)
    : m_scriptEnvMap(ScriptEnvMap::create(core->GetGC()))
    , m_domain(domain)
    , m_globalMemoryScratch(mmfx_new0(Scratch))
    , m_globalMemoryBase(m_globalMemoryScratch->scratch)
    , m_globalMemorySize(GLOBAL_MEMORY_MIN_SIZE)
    , m_baseCount(baseCount)
{
    WB(core->GetGC(), this, &this->m_bases[0], this);
    for (uint32_t i = 1; i < baseCount; ++i)
    {
        WB(core->GetGC(), this, &this->m_bases[i], base->m_bases[i-1]);
    }

#ifdef _DEBUG
    GCList<Domain> dl(core->GetGC(), 0);
    for (Domain* di = m_domain; di != NULL; di = di->base())
        dl.add(di);

    GCList<DomainEnv> el(core->GetGC(), 0);
    for (DomainEnv* di = this; di != NULL; di = di->base())
        el.add(di);

    AvmAssert(dl.length() == el.length());
    for (uint32_t i = 0, n = el.length(); i < n; ++i)
    {
        Domain* d = dl[i];
        DomainEnv* e = el[i];
        AvmAssert(e->domain() == d);
    }
#endif
}
Пример #3
0
void DomainMgr::addNamedScriptEnvs(AbcEnv* abcEnv, const GCList<ScriptEnv>& envs)
{
    // If the MethodInfo for this ScriptEnv isn't in the Domain's or Pool's
    // map, then we must have filtered it out as unreachable: don't
    // bother adding the ScriptEnv, as we'll never need to look it up.
    // (Note that we don't need to bother checking the parent Domains
    // for this, since we want to check loaded, not cached.) We can't rely
    // on looking up by name, since scripts all tend to be named "global",
    // so instead we make a temporary map of all the entries in the relevant
    // Pool and Domain.

    PoolObject* pool = abcEnv->pool();
    DomainEnv* domainEnv = abcEnv->domainEnv();
    Domain* domain = domainEnv->domain();

    // we have no generic "set" type, so let's use a hashtable for the same purpose
    // (a bit more mem, but short-lived and better average lookup time than using List<>)
    HeapHashtable* ht = HeapHashtable::create(core->GetGC());
    for (StMNHTMethodInfoIterator iter(pool->m_loadedScripts); iter.next(); )
    {
        if (!iter.key()) continue;
        Atom const a = AvmCore::genericObjectToAtom(iter.value());
        ht->add(a, a);
    }
    for (StMNHTMethodInfoIterator iter(domain->m_loadedScripts); iter.next(); )
    {
        if (!iter.key()) continue;
        Atom const a = AvmCore::genericObjectToAtom(iter.value());
        ht->add(a, a);
    }

    for (uint32_t i = 0, n = envs.length(); i < n; ++i)
    {
        ScriptEnv* se = envs[i];
        AvmAssert(se->abcEnv() == abcEnv);
        MethodInfo* mi = se->method;
        AvmAssert(domainEnv->m_scriptEnvMap->get(mi) == NULL);
        if (ht->get(AvmCore::genericObjectToAtom(mi)) == undefinedAtom)
            continue;
        domainEnv->m_scriptEnvMap->add(mi, se);
    }

    delete ht;
}