Merge remote-tracking branch 'redux/master' into sh4-pool
[tamarin-stm.git] / core / DomainEnv.cpp
blobdfbcd2ebd79fedb3e4cedae1792c6a9d00ee6c2d
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) 1993-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 DomainEnv::DomainEnv(AvmCore* core, Domain* domain, DomainEnv* base, uint32_t baseCount)
46 : m_scriptEnvMap(ScriptEnvMap::create(core->GetGC()))
47 , m_domain(domain)
48 , m_globalMemoryScratch(mmfx_new0(Scratch))
49 , m_globalMemoryBase(m_globalMemoryScratch->scratch)
50 , m_globalMemorySize(GLOBAL_MEMORY_MIN_SIZE)
51 , m_baseCount(baseCount)
53 WB(core->GetGC(), this, &this->m_bases[0], this);
54 for (uint32_t i = 1; i < baseCount; ++i)
56 WB(core->GetGC(), this, &this->m_bases[i], base->m_bases[i-1]);
59 #ifdef _DEBUG
60 GCList<Domain> dl(core->GetGC(), 0);
61 for (Domain* di = m_domain; di != NULL; di = di->base())
62 dl.add(di);
64 GCList<DomainEnv> el(core->GetGC(), 0);
65 for (DomainEnv* di = this; di != NULL; di = di->base())
66 el.add(di);
68 AvmAssert(dl.length() == el.length());
69 for (uint32_t i = 0, n = el.length(); i < n; ++i)
71 Domain* d = dl[i];
72 DomainEnv* e = el[i];
73 AvmAssert(e->domain() == d);
75 #endif
78 DomainEnv* DomainEnv::newDomainEnv(AvmCore* core, Domain* domain, DomainEnv* base)
80 uint32_t baseCount = (base ? base->m_baseCount : 0) + 1;
81 // Note that we deliberately overallocate by one here (the proper
82 // amount is baseCount-1) so that we always have one, zeroed-out
83 // entry at the end. This allows us to always use "m_bases[1]"
84 // to get our immediate base, even if our base is NULL, thus
85 // avoiding a check in the implementation of base().
86 uint32_t extra = baseCount * sizeof(DomainEnv*);
87 return new (core->GetGC(), MMgc::kExact, extra) DomainEnv(core, domain, base, baseCount);
90 DomainEnv::~DomainEnv()
92 mmfx_delete(m_globalMemoryScratch);
95 Toplevel* DomainEnv::toplevel() const
97 if(m_toplevel) return m_toplevel;
98 if(base()) return base()->toplevel();
99 AvmAssert(0);
100 return NULL;
103 bool DomainEnv::set_globalMemory(ByteArrayObject* providerObject)
105 if (!providerObject)
107 // null obj -- use scratch
108 if (m_globalMemoryProviderObject) // unsubscribe from current if any
109 globalMemoryUnsubscribe(m_globalMemoryProviderObject);
110 // remember NULL obj
111 m_globalMemoryProviderObject = NULL;
112 // point at scratch mem
113 notifyGlobalMemoryChanged(m_globalMemoryScratch->scratch, GLOBAL_MEMORY_MIN_SIZE);
115 else if (!globalMemorySubscribe(providerObject))
117 // failed... do nothing
118 return false;
120 else
122 // success on globalMemorySubscribe would have led to notifyGlobalMemoryChanged
123 // success... unsubscribe from original
124 if (m_globalMemoryProviderObject)
125 globalMemoryUnsubscribe(m_globalMemoryProviderObject);
126 // remember the new one
127 m_globalMemoryProviderObject = providerObject;
129 return true;
132 // memory changed so go through and update all reference to both the base
133 // and the size of the global memory
134 void DomainEnv::notifyGlobalMemoryChanged(uint8_t* newBase, uint32_t newSize)
136 AvmAssert(newBase != NULL); // real base address
137 AvmAssert(newSize >= GLOBAL_MEMORY_MIN_SIZE); // big enough
139 m_globalMemoryBase = newBase;
140 m_globalMemorySize = newSize;
143 bool DomainEnv::globalMemorySubscribe(ByteArrayObject* providerObject)
145 return providerObject->GetByteArray().addSubscriber(this);
148 bool DomainEnv::globalMemoryUnsubscribe(ByteArrayObject* providerObject)
150 return providerObject->GetByteArray().removeSubscriber(this);