зеркало из https://github.com/mozilla/gecko-dev.git
186 строки
6.0 KiB
C++
186 строки
6.0 KiB
C++
/* ***** BEGIN LICENSE BLOCK *****
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
*
|
|
* The contents of this file are subject to the Mozilla Public License Version 1.1 (the
|
|
* "License"); you may not use this file except in compliance with the License. You may obtain
|
|
* a copy of the License at http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
|
|
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
|
* language governing rights and limitations under the License.
|
|
*
|
|
* The Original Code is [Open Source Virtual Machine.]
|
|
*
|
|
* The Initial Developer of the Original Code is Adobe System Incorporated. Portions created
|
|
* by the Initial Developer are Copyright (C)[ 2004-2006 ] Adobe Systems Incorporated. All Rights
|
|
* Reserved.
|
|
*
|
|
* Contributor(s): Adobe AS3 Team
|
|
*
|
|
* Alternatively, the contents of this file may be used under the terms of either the GNU
|
|
* General Public License Version 2 or later (the "GPL"), or the GNU Lesser General Public
|
|
* License Version 2.1 or later (the "LGPL"), in which case the provisions of the GPL or the
|
|
* LGPL are applicable instead of those above. If you wish to allow use of your version of this
|
|
* file only under the terms of either the GPL or the LGPL, and not to allow others to use your
|
|
* version of this file under the terms of the MPL, indicate your decision by deleting provisions
|
|
* above and replace them with the notice and other provisions required by the GPL or the
|
|
* LGPL. If you do not delete the provisions above, a recipient may use your version of this file
|
|
* under the terms of any one of the MPL, the GPL or the LGPL.
|
|
*
|
|
***** END LICENSE BLOCK ***** */
|
|
|
|
|
|
#include "avmshell.h"
|
|
|
|
namespace avmshell
|
|
{
|
|
BEGIN_NATIVE_MAP(DomainClass)
|
|
NATIVE_METHOD(avmplus_Domain_Domain, DomainObject::constructFromDomain)
|
|
NATIVE_METHOD(avmplus_Domain_loadBytes, DomainObject::loadBytes)
|
|
NATIVE_METHOD(avmplus_Domain_currentDomain_get, DomainClass::get_currentDomain)
|
|
NATIVE_METHOD(avmplus_Domain_getClass, DomainObject::getClass)
|
|
END_NATIVE_MAP()
|
|
|
|
DomainObject::DomainObject(VTable *vtable, ScriptObject *delegate)
|
|
: ScriptObject(vtable, delegate)
|
|
{
|
|
}
|
|
|
|
DomainObject::~DomainObject()
|
|
{
|
|
}
|
|
|
|
void DomainObject::constructFromDomain(DomainObject *parentDomain)
|
|
{
|
|
Shell *core = (Shell*) this->core();
|
|
|
|
Domain* baseDomain;
|
|
if (parentDomain) {
|
|
baseDomain = parentDomain->domainEnv->getDomain();
|
|
} else {
|
|
baseDomain = core->builtinDomain;
|
|
}
|
|
|
|
Domain* domain = new (core->GetGC()) Domain(core, baseDomain);
|
|
|
|
if (parentDomain) {
|
|
domainToplevel = parentDomain->domainToplevel;
|
|
} else {
|
|
domainToplevel = core->initShellBuiltins();
|
|
}
|
|
|
|
domainEnv = new (core->GetGC()) DomainEnv(core, domain, parentDomain->domainEnv);
|
|
}
|
|
|
|
Atom DomainObject::loadBytes(ByteArrayObject *b)
|
|
{
|
|
AvmCore* core = this->core();
|
|
if (!b)
|
|
toplevel()->throwTypeError(kNullArgumentError, core->toErrorString("bytes"));
|
|
|
|
ShellCodeContext* codeContext = new (core->GetGC()) ShellCodeContext();
|
|
codeContext->domainEnv = domainEnv;
|
|
|
|
// parse new bytecode
|
|
size_t len = b->get_length();
|
|
ScriptBuffer code = core->newScriptBuffer(len);
|
|
memcpy(code.getBuffer(), &b->GetByteArray()[0], len);
|
|
Toplevel *toplevel = domainToplevel;
|
|
return core->handleActionBlock(code, 0,
|
|
domainEnv,
|
|
toplevel,
|
|
NULL, NULL, NULL, codeContext);
|
|
}
|
|
|
|
ScriptObject* DomainObject::finddef(Multiname* multiname,
|
|
DomainEnv* domainEnv)
|
|
{
|
|
Toplevel* toplevel = this->toplevel();
|
|
|
|
ScriptEnv* script = (ScriptEnv*) domainEnv->getScriptInit(multiname);
|
|
if (script == (ScriptEnv*)BIND_AMBIGUOUS)
|
|
toplevel->throwReferenceError(kAmbiguousBindingError, multiname);
|
|
|
|
if (script == (ScriptEnv*)BIND_NONE)
|
|
toplevel->throwReferenceError(kUndefinedVarError, multiname);
|
|
|
|
if (script->global == NULL)
|
|
{
|
|
script->initGlobal();
|
|
Atom argv[1] = { script->global->atom() };
|
|
script->coerceEnter(0, argv);
|
|
}
|
|
|
|
return script->global;
|
|
}
|
|
|
|
ClassClosure* DomainObject::getClass(Stringp name)
|
|
{
|
|
AvmCore *core = this->core();
|
|
|
|
if (name == NULL) {
|
|
toplevel()->throwArgumentError(kNullArgumentError, core->toErrorString("name"));
|
|
}
|
|
|
|
// Search for a dot from the end.
|
|
int dot;
|
|
for (dot=name->length()-1; dot >= 0; dot--)
|
|
if ((*name)[dot] == (wchar)'.')
|
|
break;
|
|
|
|
// If there is a '.', this is a fully-qualified
|
|
// class name in a package. Must turn it into
|
|
// a namespace-qualified multiname.
|
|
Namespace* ns;
|
|
Stringp className;
|
|
if (dot != -1) {
|
|
Stringp uri = core->internString(new (core->GetGC()) String(name, 0, dot));
|
|
ns = core->internNamespace(core->newNamespace(uri));
|
|
className = core->internString(new (core->GetGC()) String(name, dot+1, name->length()-(dot+1)));
|
|
} else {
|
|
ns = core->publicNamespace;
|
|
className = core->internString(name);
|
|
}
|
|
|
|
Multiname multiname(ns, className);
|
|
|
|
ShellCodeContext* codeContext = (ShellCodeContext*)core->codeContext();
|
|
|
|
ScriptObject *container = finddef(&multiname, codeContext->domainEnv);
|
|
if (!container) {
|
|
toplevel()->throwTypeError(kClassNotFoundError, core->toErrorString(&multiname));
|
|
}
|
|
Atom atom = toplevel()->getproperty(container->atom(),
|
|
&multiname,
|
|
container->vtable);
|
|
|
|
if (!core->istype(atom, core->traits.class_itraits)) {
|
|
toplevel()->throwTypeError(kClassNotFoundError, core->toErrorString(&multiname));
|
|
}
|
|
return (ClassClosure*)AvmCore::atomToScriptObject(atom);
|
|
}
|
|
|
|
DomainClass::DomainClass(VTable *cvtable)
|
|
: ClassClosure(cvtable)
|
|
{
|
|
createVanillaPrototype();
|
|
}
|
|
|
|
ScriptObject* DomainClass::createInstance(VTable *ivtable,
|
|
ScriptObject *prototype)
|
|
{
|
|
return new (core()->GetGC(), ivtable->getExtraSize()) DomainObject(ivtable, prototype);
|
|
}
|
|
|
|
DomainObject* DomainClass::get_currentDomain()
|
|
{
|
|
ShellCodeContext* codeContext = (ShellCodeContext*)core()->codeContext();
|
|
|
|
DomainObject* domainObject = (DomainObject*) createInstance(ivtable(), prototype);
|
|
domainObject->domainEnv = codeContext->domainEnv;
|
|
domainObject->domainToplevel = toplevel();
|
|
|
|
return domainObject;
|
|
}
|
|
}
|