Merge remote-tracking branch 'redux/master' into sh4-pool
[tamarin-stm.git] / core / ScopeChain.cpp
blob9f65b8713a08fba83b112f0e40c242cbb1afd9a8
1 /* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
2 /* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */
3 /* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
16 * The Original Code is [Open Source Virtual Machine.].
18 * The Initial Developer of the Original Code is
19 * Adobe System Incorporated.
20 * Portions created by the Initial Developer are Copyright (C) 2004-2006
21 * the Initial Developer. All Rights Reserved.
23 * Contributor(s):
24 * Adobe AS3 Team
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
41 #include "avmplus.h"
43 namespace avmplus
45 /* static */ const ScopeTypeChain* ScopeTypeChain::create(MMgc::GC* gc, Traits* traits, const ScopeTypeChain* outer, const Value* values, int32_t nValues, Traits* append, Traits* extra)
47 const int32_t capture = nValues + (append ? 1 : 0);
48 const int32_t extraEntries = extra ? 1 : 0;
49 const int32_t outerSize = (outer ? outer->size : 0);
50 const int32_t pad = capture + extraEntries;
51 const size_t padSize = sizeof(uintptr_t) * (((pad > 0) ? (pad - 1) : 0) + outerSize);
52 ScopeTypeChain* nscope = new(gc, MMgc::kExact, padSize) ScopeTypeChain(outerSize + capture, outerSize + capture + extraEntries, traits);
53 int32_t j = 0;
54 for (int32_t i = 0; i < outerSize; i++)
56 nscope->_scopes[j++] = outer->_scopes[i];
58 for (int32_t i = 0; i < nValues; i++)
60 const Value& v = values[i];
61 nscope->setScopeAt(j++, v.traits, v.isWith);
63 if (append)
65 nscope->setScopeAt(j++, append, false);
67 if (extra)
69 nscope->setScopeAt(j++, extra, false);
71 AvmAssert(j == nscope->fullsize);
72 return nscope;
75 /*static*/ const ScopeTypeChain* ScopeTypeChain::create(MMgc::GC* gc, Traits* traits, const ScopeTypeChain* outer, const FrameState* state, Traits* append, Traits* extra)
77 if (state && state->scopeDepth > 0)
78 return ScopeTypeChain::create(gc, traits, outer, &state->scopeValue(0), state->scopeDepth, append, extra);
79 else
80 return ScopeTypeChain::create(gc, traits, outer, 0, 0, append, extra);
84 #ifdef VMCFG_AOT
85 /*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)
87 MMgc::GC::AllocaAutoPtr valuesPtr;
88 Value *values = (Value *)VMPI_alloca_gc(gc, valuesPtr, sizeof(Value)*nStateTraits);
89 uint32_t firstWith = nStateTraits - nStateWithTraits;
90 for (uint32_t i = 0; i < nStateTraits; i++)
92 values[i].traits = stateTraits[i];
93 values[i].isWith = i >= firstWith;
95 return ScopeTypeChain::create(gc, traits, outer, values, nStateTraits, append, extra);
97 #endif
99 const ScopeTypeChain* ScopeTypeChain::cloneWithNewTraits(MMgc::GC* gc, Traits* p_traits) const
101 if (p_traits == this->traits())
102 return this;
104 const size_t padSize = sizeof(uintptr_t) * (this->fullsize ? this->fullsize-1 : 0);
105 ScopeTypeChain* nscope = new(gc, MMgc::kExact, padSize) ScopeTypeChain(this->size, this->fullsize, p_traits);
106 for (int32_t i=0; i < this->fullsize; i ++)
108 nscope->_scopes[i] = this->_scopes[i];
110 return nscope;
113 PrintWriter& ScopeTypeChain::print(PrintWriter& prw) const
115 prw << "STC:{traits=" << traits() << ":";
116 for (int32_t i = 0; i < fullsize; i++)
118 if (i > 0)
119 prw << ',';
120 prw << getScopeTraitsAt(i);
121 if (getScopeIsWithAt(i)) prw << "(iswith)";
124 return prw << "]";
127 bool ScopeTypeChain::equals(const ScopeTypeChain* that) const
129 if (this != that)
131 if (!this || !that)
132 return false;
134 if (this->size != that->size ||
135 this->fullsize != that->fullsize ||
136 this->_traits != that->_traits)
137 return false;
139 for (int32_t i = 0, n = this->fullsize; i < n; i++)
141 if (this->_scopes[i] != that->_scopes[i])
142 return false;
145 return true;
148 /*static*/ ScopeChain* ScopeChain::create(MMgc::GC* gc, VTable* vtable, AbcEnv* abcEnv, const ScopeTypeChain* scopeTraits, const ScopeChain* outer, Namespacep dxns)
150 AvmAssert(vtable->traits == scopeTraits->traits());
151 const int32_t scopeTraitsSize = scopeTraits->size;
152 const int32_t outerSize = outer ? outer->_scopeTraits->size : 0;
153 AvmAssert(scopeTraitsSize >= outerSize);
154 const size_t padSize = scopeTraitsSize > 0 ? sizeof(Atom) * (scopeTraitsSize-1) : 0;
155 ScopeChain* nscope = new(gc, MMgc::kExact, padSize) ScopeChain(vtable, abcEnv, scopeTraits, dxns);
156 for (int32_t i=0; i < outerSize; i ++)
158 nscope->setScope(gc, i, outer->_scopes[i]);
160 return nscope;
163 ScopeChain* ScopeChain::cloneWithNewVTable(MMgc::GC* gc, VTable* p_vtable, AbcEnv* p_abcEnv, const ScopeTypeChain* p_scopeTraits)
165 if (p_vtable == this->vtable() && p_abcEnv == this->abcEnv())
166 return this;
168 const ScopeTypeChain* nstc = p_scopeTraits ? p_scopeTraits : _scopeTraits->cloneWithNewTraits(gc, p_vtable->traits);
169 AvmAssert(nstc->traits() == p_vtable->traits);
170 const int32_t scopeTraitsSize = nstc->size;
171 const size_t padSize = scopeTraitsSize > 0 ? sizeof(Atom) * (scopeTraitsSize-1) : 0;
172 ScopeChain* nscope = new(gc, MMgc::kExact, padSize) ScopeChain(p_vtable, p_abcEnv, nstc, _defaultXmlNamespace);
173 for (int32_t i=0; i < nstc->size; i ++)
175 nscope->setScope(gc, i, this->_scopes[i]);
177 return nscope;
180 void ScopeChain::setScope(MMgc::GC* gc, int32_t i, Atom value)
182 AvmAssert(i >= 0 && i < _scopeTraits->size);
183 //scopes[i] = value;
184 WBATOM(gc, this, &_scopes[i], value);
187 PrintWriter& ScopeChain::print(PrintWriter& prw) const
189 prw << "SC:{dxns=(" << _defaultXmlNamespace << ")," << _scopeTraits << ",V:[";
190 for (int32_t i = 0; i < _scopeTraits->size; i++)
192 if (i > 0) prw << ",";
193 prw << asAtom(_scopes[i]);
195 return prw << "]}";