Source code drop for the Actionscript virtual machine in the Adobe Flash Player for December 2013
178 lines
6.8 KiB
C++
178 lines
6.8 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
|
|
{
|
|
/*static*/ const ScopeTypeChain* ScopeTypeChain::createExplicit(MMgc::GC* gc, Traits* owner, Traits** types)
|
|
{
|
|
uint32_t fullsize = 0;
|
|
for (Traits** t = types; *t != NULL; ++t)
|
|
++fullsize;
|
|
uint32_t size = (fullsize > 0) ? (fullsize - 1) : 0;
|
|
const size_t padSize = sizeof(uintptr_t) * size;
|
|
ScopeTypeChain* stc = new(gc, MMgc::kExact, padSize) ScopeTypeChain(size, fullsize, owner);
|
|
for (uint32_t i = 0; i < fullsize; ++i)
|
|
stc->setScopeAt(i, types[i]);
|
|
return stc;
|
|
}
|
|
|
|
/* static */ const ScopeTypeChain* ScopeTypeChain::create(MMgc::GC* gc, Traits* traits, const ScopeTypeChain* outer, const FrameValue* values, int32_t nValues, Traits* append, Traits* extra)
|
|
{
|
|
const int32_t capture = nValues + (append ? 1 : 0);
|
|
const int32_t extraEntries = extra ? 1 : 0;
|
|
const int32_t outerSize = (outer ? outer->size : 0);
|
|
const int32_t pad = capture + extraEntries;
|
|
const size_t padSize = sizeof(uintptr_t) * (((pad > 0) ? (pad - 1) : 0) + outerSize);
|
|
ScopeTypeChain* nscope = new(gc, MMgc::kExact, padSize) ScopeTypeChain(outerSize + capture, outerSize + capture + extraEntries, traits);
|
|
int32_t j = 0;
|
|
for (int32_t i = 0; i < outerSize; i++)
|
|
{
|
|
nscope->_scopes[j++] = outer->_scopes[i];
|
|
}
|
|
for (int32_t i = 0; i < nValues; i++)
|
|
{
|
|
const FrameValue& v = values[i];
|
|
nscope->setScopeAt(j++, v.traits, v.isWith);
|
|
}
|
|
if (append)
|
|
{
|
|
nscope->setScopeAt(j++, append, false);
|
|
}
|
|
if (extra)
|
|
{
|
|
nscope->setScopeAt(j++, extra, false);
|
|
}
|
|
AvmAssert(j == nscope->fullsize);
|
|
return nscope;
|
|
}
|
|
|
|
/*static*/ const ScopeTypeChain* ScopeTypeChain::create(MMgc::GC* gc, Traits* traits, const ScopeTypeChain* outer, const FrameState* state, Traits* append, Traits* extra)
|
|
{
|
|
if (state && state->scopeDepth > 0)
|
|
return ScopeTypeChain::create(gc, traits, outer, &state->scopeValue(0), state->scopeDepth, append, extra);
|
|
else
|
|
return ScopeTypeChain::create(gc, traits, outer, 0, 0, append, extra);
|
|
|
|
}
|
|
|
|
#ifdef VMCFG_AOT
|
|
/*static*/ const ScopeTypeChain* ScopeTypeChain::create(MMgc::GC* gc, Traits* traits, const ScopeTypeChain* outer, Traits* const* stateTraits, uint32_t nStateTraits, uint32_t nStateWithTraits, Traits* append, Traits* extra)
|
|
{
|
|
MMgc::GC::AllocaAutoPtr valuesPtr;
|
|
FrameValue *values = (FrameValue *)avmStackAllocGC(gc, valuesPtr, sizeof(FrameValue)*nStateTraits);
|
|
uint32_t firstWith = nStateTraits - nStateWithTraits;
|
|
for (uint32_t i = 0; i < nStateTraits; i++)
|
|
{
|
|
values[i].traits = stateTraits[i];
|
|
values[i].isWith = i >= firstWith;
|
|
}
|
|
return ScopeTypeChain::create(gc, traits, outer, values, nStateTraits, append, extra);
|
|
}
|
|
#endif
|
|
|
|
const ScopeTypeChain* ScopeTypeChain::cloneWithNewTraits(MMgc::GC* gc, Traits* p_traits) const
|
|
{
|
|
if (p_traits == this->traits())
|
|
return this;
|
|
|
|
const size_t padSize = sizeof(uintptr_t) * (this->fullsize ? this->fullsize-1 : 0);
|
|
ScopeTypeChain* nscope = new(gc, MMgc::kExact, padSize) ScopeTypeChain(this->size, this->fullsize, p_traits);
|
|
for (int32_t i=0; i < this->fullsize; i ++)
|
|
{
|
|
nscope->_scopes[i] = this->_scopes[i];
|
|
}
|
|
return nscope;
|
|
}
|
|
|
|
PrintWriter& ScopeTypeChain::print(PrintWriter& prw) const
|
|
{
|
|
prw << "STC:{traits=" << traits() << ":";
|
|
for (int32_t i = 0; i < fullsize; i++)
|
|
{
|
|
if (i > 0)
|
|
prw << ',';
|
|
prw << getScopeTraitsAt(i);
|
|
if (getScopeIsWithAt(i)) prw << "(iswith)";
|
|
|
|
}
|
|
return prw << "]";
|
|
}
|
|
|
|
bool ScopeTypeChain::equals(const ScopeTypeChain* that) const
|
|
{
|
|
if (this != that)
|
|
{
|
|
if (!this || !that)
|
|
return false;
|
|
|
|
if (this->size != that->size ||
|
|
this->fullsize != that->fullsize ||
|
|
this->_traits != that->_traits)
|
|
return false;
|
|
|
|
for (int32_t i = 0, n = this->fullsize; i < n; i++)
|
|
{
|
|
if (this->_scopes[i] != that->_scopes[i])
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/*static*/ ScopeChain* ScopeChain::create(MMgc::GC* gc, VTable* vtable, AbcEnv* abcEnv, const ScopeTypeChain* scopeTraits, const ScopeChain* outer, Namespacep dxns)
|
|
{
|
|
AvmAssert(vtable->traits == scopeTraits->traits());
|
|
const int32_t scopeTraitsSize = scopeTraits->size;
|
|
const int32_t outerSize = outer ? outer->_scopeTraits->size : 0;
|
|
AvmAssert(scopeTraitsSize >= outerSize);
|
|
const size_t padSize = scopeTraitsSize > 0 ? sizeof(Atom) * (scopeTraitsSize-1) : 0;
|
|
ScopeChain* nscope = new(gc, MMgc::kExact, padSize) ScopeChain(vtable, abcEnv, scopeTraits, dxns);
|
|
for (int32_t i=0; i < outerSize; i ++)
|
|
{
|
|
nscope->setScope(gc, i, outer->_scopes[i]);
|
|
}
|
|
return nscope;
|
|
}
|
|
|
|
ScopeChain* ScopeChain::cloneWithNewVTable(MMgc::GC* gc, VTable* p_vtable, AbcEnv* p_abcEnv, const ScopeTypeChain* p_scopeTraits)
|
|
{
|
|
if (p_vtable == this->vtable() && p_abcEnv == this->abcEnv())
|
|
return this;
|
|
|
|
const ScopeTypeChain* nstc = p_scopeTraits ? p_scopeTraits : _scopeTraits->cloneWithNewTraits(gc, p_vtable->traits);
|
|
AvmAssert(nstc->traits() == p_vtable->traits);
|
|
const int32_t scopeTraitsSize = nstc->size;
|
|
const size_t padSize = scopeTraitsSize > 0 ? sizeof(Atom) * (scopeTraitsSize-1) : 0;
|
|
ScopeChain* nscope = new(gc, MMgc::kExact, padSize) ScopeChain(p_vtable, p_abcEnv, nstc, _defaultXmlNamespace);
|
|
for (int32_t i=0; i < nstc->size; i ++)
|
|
{
|
|
nscope->setScope(gc, i, this->_scopes[i]);
|
|
}
|
|
return nscope;
|
|
}
|
|
|
|
void ScopeChain::setScope(MMgc::GC* gc, int32_t i, Atom value)
|
|
{
|
|
AvmAssert(i >= 0 && i < _scopeTraits->size);
|
|
//scopes[i] = value;
|
|
WBATOM(gc, this, &_scopes[i], value);
|
|
}
|
|
|
|
PrintWriter& ScopeChain::print(PrintWriter& prw) const
|
|
{
|
|
prw << "SC:{dxns=(" << _defaultXmlNamespace << ")," << _scopeTraits << ",V:[";
|
|
for (int32_t i = 0; i < _scopeTraits->size; i++)
|
|
{
|
|
if (i > 0) prw << ",";
|
|
prw << asAtom(_scopes[i]);
|
|
}
|
|
return prw << "]}";
|
|
}
|
|
}
|