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
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.
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 ***** */
45 DomainEnv::DomainEnv(AvmCore
* core
, Domain
* domain
, DomainEnv
* base
, uint32_t baseCount
)
46 : m_scriptEnvMap(ScriptEnvMap::create(core
->GetGC()))
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]);
60 GCList
<Domain
> dl(core
->GetGC(), 0);
61 for (Domain
* di
= m_domain
; di
!= NULL
; di
= di
->base())
64 GCList
<DomainEnv
> el(core
->GetGC(), 0);
65 for (DomainEnv
* di
= this; di
!= NULL
; di
= di
->base())
68 AvmAssert(dl
.length() == el
.length());
69 for (uint32_t i
= 0, n
= el
.length(); i
< n
; ++i
)
73 AvmAssert(e
->domain() == d
);
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();
103 bool DomainEnv::set_globalMemory(ByteArrayObject
* providerObject
)
107 // null obj -- use scratch
108 if (m_globalMemoryProviderObject
) // unsubscribe from current if any
109 globalMemoryUnsubscribe(m_globalMemoryProviderObject
);
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
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
;
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);