Source code drop for the Actionscript virtual machine in the Adobe Flash Player for December 2013
97 lines
3.7 KiB
C++
97 lines
3.7 KiB
C++
/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
|
|
/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
#include "avmplus.h"
|
|
|
|
namespace avmplus
|
|
{
|
|
Domain::Domain(AvmCore* core, Domain* base, uint32_t baseCount)
|
|
: m_loadedTraits(MultinameTraitsHashtable::create(core->GetGC()))
|
|
, m_cachedTraits(MultinameTraitsHashtable::create(core->GetGC()))
|
|
, m_loadedScripts(MultinameMethodInfoHashtable::create(core->GetGC()))
|
|
, m_cachedScripts(MultinameMethodInfoHashtable::create(core->GetGC()))
|
|
, m_parameterizedTypes(WeakKeyHashtable::create(core->GetGC()))
|
|
, m_baseCount(baseCount)
|
|
{
|
|
WB(core->GetGC(), 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]);
|
|
}
|
|
}
|
|
|
|
Domain* Domain::newDomain(AvmCore* core, Domain* base)
|
|
{
|
|
uint32_t baseCount = (base ? base->m_baseCount : 0) + 1;
|
|
// Note that we deliberately overallocate by one here (the proper
|
|
// amount is baseCount-1) so that we always have one, zeroed-out
|
|
// entry at the end. This allows us to always use "m_bases[1]"
|
|
// to get our immediate base, even if our base is NULL, thus
|
|
// avoiding a check in the implementation of base().
|
|
uint32_t extra = baseCount * sizeof(Domain*);
|
|
return new (core->GetGC(), MMgc::kExact, extra) Domain(core, base, baseCount);
|
|
}
|
|
|
|
ClassClosure* Domain::getParameterizedType(ClassClosure* type)
|
|
{
|
|
ClassClosure* result = NULL;
|
|
AvmAssert(type != NULL);
|
|
if (type)
|
|
{
|
|
Atom value = m_parameterizedTypes->get(type->atom());
|
|
if (AvmCore::isGenericObject(value))
|
|
{
|
|
MMgc::GCWeakRef* wr = (MMgc::GCWeakRef*)AvmCore::atomToGenericObject(value);
|
|
if (wr)
|
|
{
|
|
result = (ClassClosure*)wr->get();
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
bool Domain::isParameterizedTypePresent(ClassClosure* type)
|
|
{
|
|
bool result = false;
|
|
if (type)
|
|
{
|
|
Atom value = m_parameterizedTypes->get(type->atom());
|
|
if (AvmCore::isGenericObject(value))
|
|
{
|
|
MMgc::GCWeakRef* wr = (MMgc::GCWeakRef*)AvmCore::atomToGenericObject(value);
|
|
if (wr)
|
|
{
|
|
result = !(wr->isNull());
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void Domain::addParameterizedType(ClassClosure* type, ClassClosure* parameterizedType)
|
|
{
|
|
AvmAssert(type && parameterizedType);
|
|
if (type && parameterizedType)
|
|
{
|
|
AvmAssert(!isParameterizedTypePresent(type));
|
|
// Note that what we really need here is fixing the problems with our weak tables.
|
|
// If there exists a cycle in the weak table ('value' indirectly pointing to the weak 'key'),
|
|
// the weak key will not get collected even if there are no references to
|
|
// it from elsewhere and hence the table entry will not be deleted, which
|
|
// will in turn lead to value not getting collected.
|
|
//
|
|
// As a short term fix, we'll just use WeakKeyHashtable with explicit GCWeakRef usage
|
|
// for the value.
|
|
MMgc::GCWeakRef* wr = parameterizedType ? parameterizedType->GetWeakRef() : NULL;
|
|
m_parameterizedTypes->add(type->atom(), AvmCore::genericObjectToAtom(wr));
|
|
}
|
|
}
|
|
}
|
|
|
|
|