Merge remote-tracking branch 'redux/master' into sh4-pool
[tamarin-stm.git] / shell / DomainClass.cpp
blob50288f08467fc07d21485047f2be1113269c2632
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 "avmshell.h"
43 #ifndef AVMSHELL_BUILD
44 #error "This file is only for use with avmshell"
45 #endif
47 namespace avmplus
49 using namespace avmshell;
51 DomainObject::DomainObject(VTable *vtable, ScriptObject *delegate)
52 : ScriptObject(vtable, delegate)
53 , domainEnv(delegate->core()->codeContext()->domainEnv())
54 , domainToplevel(delegate->toplevel())
58 void DomainObject::init(DomainObject* parentDomain)
60 ShellCore* core = (ShellCore*) this->core();
62 DomainEnv* baseDomainEnv = parentDomain ?
63 parentDomain->domainEnv :
64 (DomainEnv*)NULL;
65 Domain* baseDomain = baseDomainEnv ?
66 baseDomainEnv->domain() :
67 NULL;
69 domainToplevel = parentDomain ?
70 (Toplevel*)parentDomain->domainToplevel :
71 core->createShellToplevel();
73 Domain* domain = Domain::newDomain(core, baseDomain);
74 domainEnv = DomainEnv::newDomainEnv(core, domain, parentDomain ? parentDomain->domainEnv : (DomainEnv*)NULL);
77 Atom DomainObject::loadBytes(ByteArrayObject* b, uint32_t swfVersion)
79 AvmCore* core = this->core();
80 if (!b)
81 toplevel()->throwTypeError(kNullArgumentError, core->toErrorString("bytes"));
83 // parse new bytecode
84 size_t len = b->get_length();
85 ScriptBuffer code = core->newScriptBuffer(len);
86 VMPI_memcpy(code.getBuffer(), &b->GetByteArray()[0], len);
88 Toplevel* toplevel = domainToplevel;
89 ApiVersion apiVersion = core->getApiVersionFromCallStack();
91 // parse constants and attributes.
92 PoolObject* pool = core->parseActionBlock(code,
93 /*start*/0,
94 toplevel,
95 domainEnv->domain(),
96 /*ninit*/NULL,
97 apiVersion);
100 // by default, use the same bugCompatibility as the builtins use
101 const BugCompatibility* bugCompatibility = toplevel->abcEnv()->codeContext()->bugCompatibility();
102 if (swfVersion != 0)
104 // ...unless specified otherwise.
105 for (int j = 0; j < BugCompatibility::VersionCount; ++j)
107 if (BugCompatibility::kNames[j] == swfVersion)
109 bugCompatibility = core->createBugCompatibility((BugCompatibility::Version)j);
110 goto done;
113 // if we get here, didn't find a valid name
114 toplevel->throwTypeError(kInvalidArgumentError, core->toErrorString("swfVersion"));
116 done:
118 ShellCodeContext* codeContext = new (core->GetGC()) ShellCodeContext(domainEnv, bugCompatibility);
119 return core->handleActionPool(pool, toplevel, codeContext);
122 ScriptObject* DomainObject::finddef(const Multiname& multiname,
123 DomainEnv* domainEnv)
125 Toplevel* toplevel = this->toplevel();
127 ScriptEnv* script = core()->domainMgr()->findScriptEnvInDomainEnvByMultiname(domainEnv, multiname);
128 if (script == (ScriptEnv*)BIND_AMBIGUOUS)
129 toplevel->throwReferenceError(kAmbiguousBindingError, multiname);
131 if (script == (ScriptEnv*)BIND_NONE)
132 toplevel->throwReferenceError(kUndefinedVarError, multiname);
134 if (script->global == NULL)
136 script->initGlobal();
137 script->coerceEnter(script->global->atom());
140 return script->global;
143 ClassClosure* DomainObject::getClass(Stringp name)
145 AvmCore *core = this->core();
147 if (name == NULL) {
148 toplevel()->throwArgumentError(kNullArgumentError, core->toErrorString("name"));
152 // Search for a dot from the end.
153 int dot = name->lastIndexOf(core->cachedChars[(int)'.']);
155 // If there is a '.', this is a fully-qualified
156 // class name in a package. Must turn it into
157 // a namespace-qualified multiname.
158 Namespace* ns;
159 Stringp className;
160 if (dot >= 0) {
161 Stringp uri = core->internString(name->substring(0, dot));
162 ns = core->internNamespace(core->newNamespace(uri, Namespace::NS_Public, core->getApiVersionFromCallStack()));
163 className = core->internString(name->substring(dot+1, name->length()));
164 } else {
165 ns = core->findPublicNamespace();
166 className = core->internString(name);
169 Multiname multiname(ns, className);
171 ScriptObject *container = finddef(multiname, domainEnv);
172 if (!container) {
173 toplevel()->throwTypeError(kClassNotFoundError, core->toErrorString(&multiname));
175 Atom atom = toplevel()->getproperty(container->atom(),
176 &multiname,
177 container->vtable);
179 if (!AvmCore::istype(atom, core->traits.class_itraits)) {
180 toplevel()->throwTypeError(kClassNotFoundError, core->toErrorString(&multiname));
182 return (ClassClosure*)AvmCore::atomToScriptObject(atom);
185 DomainClass::DomainClass(VTable *cvtable)
186 : ClassClosure(cvtable)
188 createVanillaPrototype();
191 DomainObject* DomainClass::get_currentDomain()
193 return (DomainObject*) newInstance();
196 int DomainClass::get_MIN_DOMAIN_MEMORY_LENGTH()
198 return DomainEnv::GLOBAL_MEMORY_MIN_SIZE;
201 ByteArrayObject* DomainObject::get_domainMemory() const
203 return (ByteArrayObject*)domainEnv->get_globalMemory();
206 void DomainObject::set_domainMemory(ByteArrayObject* mem)
208 if(!domainEnv->set_globalMemory(mem))
209 toplevel()->throwError(kEndOfFileError);