[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] /srv/bzr/gnash/trunk r11672: Separate AVM2 and AVM1 class
From: |
Benjamin Wolsey |
Subject: |
[Gnash-commit] /srv/bzr/gnash/trunk r11672: Separate AVM2 and AVM1 classes better. |
Date: |
Tue, 01 Dec 2009 12:48:27 +0100 |
User-agent: |
Bazaar (1.16.1) |
------------------------------------------------------------
revno: 11672 [merge]
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Tue 2009-12-01 12:48:27 +0100
message:
Separate AVM2 and AVM1 classes better.
Add better documentation.
Simplify as_value's object handling. This is needed to avoid code
proliferation
when the as_class type is used.
added:
libcore/abc/as_class.cpp
libcore/abc/as_class.h
renamed:
libcore/Namespace.cpp => libcore/abc/Namespace.cpp
libcore/Namespace.h => libcore/abc/Namespace.h
libcore/abc/Class.cpp => libcore/abc/Script.cpp
libcore/abc/Class.h => libcore/abc/Script.h
modified:
libcore/ClassHierarchy.cpp
libcore/ClassHierarchy.h
libcore/Makefile.am
libcore/abc/AbcBlock.cpp
libcore/abc/AbcBlock.h
libcore/abc/Method.cpp
libcore/abc/Method.h
libcore/abc/MultiName.h
libcore/abc/abc_function.cpp
libcore/abc/abc_function.h
libcore/abc/asException.h
libcore/as_function.cpp
libcore/as_function.h
libcore/as_object.cpp
libcore/as_object.h
libcore/as_value.cpp
libcore/as_value.h
libcore/asobj/Globals.cpp
libcore/asobj/Globals.h
libcore/asobj/Object.cpp
libcore/debugger.cpp
libcore/vm/ActionExec.cpp
libcore/vm/Machine.cpp
libcore/vm/Machine.h
testsuite/libcore.all/AsValueTest.cpp
libcore/abc/Namespace.cpp
libcore/abc/Namespace.h
libcore/abc/Script.cpp
libcore/abc/Script.h
=== modified file 'libcore/ClassHierarchy.cpp'
--- a/libcore/ClassHierarchy.cpp 2009-11-23 07:42:51 +0000
+++ b/libcore/ClassHierarchy.cpp 2009-12-01 11:02:43 +0000
@@ -23,7 +23,7 @@
#include "ClassHierarchy.h"
#include "as_function.h"
#include "builtin_function.h"
-#include "Class.h"
+#include "Script.h"
#include "Global_as.h"
#include "extension.h"
@@ -204,13 +204,15 @@
{
if (!mExtension) return false;
- mGlobalNamespace->stubPrototype(*this, c.name);
- mGlobalNamespace->getClass(c.name)->setDeclared();
- mGlobalNamespace->getClass(c.name)->setSystem();
-
- boost::intrusive_ptr<as_function> getter =
- new declare_extension_function(c, mGlobal, mExtension);
-
+#ifdef ENABLE_AVM2
+ if (isAS3(*mGlobal)) {
+ mGlobalNamespace->stubPrototype(*this, c.name);
+ mGlobalNamespace->getScript(c.name)->setDeclared();
+ mGlobalNamespace->getScript(c.name)->setSystem();
+ }
+#endif
+
+ as_function* getter(new declare_extension_function(c, mGlobal,
mExtension));
int flags=PropFlags::dontEnum;
addVisibilityFlag(flags, c.version);
@@ -220,18 +222,20 @@
bool
ClassHierarchy::declareClass(const NativeClass& c)
{
- // AS2 classes should be registered with namespace 0, so they all
- // appear in a single global namespace.
- Namespace *nso = findNamespace(c.namespace_name);
-
- if (!nso) nso = addNamespace(c.namespace_name);
-
- nso->stubPrototype(*this, c.name);
- nso->getClass(c.name)->setDeclared();
- nso->getClass(c.name)->setSystem();
-
- boost::intrusive_ptr<as_function> getter =
- new declare_native_function(c, mGlobal);
+
+#ifdef ENABLE_AVM2
+ if (isAS3(*mGlobal)) {
+ abc::Namespace *nso = findNamespace(c.namespace_name);
+
+ if (!nso) nso = addNamespace(c.namespace_name);
+
+ nso->stubPrototype(*this, c.name);
+ nso->getScript(c.name)->setDeclared();
+ nso->getScript(c.name)->setSystem();
+ }
+#endif
+
+ as_function* getter = new declare_native_function(c, mGlobal);
int flags = PropFlags::dontEnum;
addVisibilityFlag(flags, c.version);
=== modified file 'libcore/ClassHierarchy.h'
--- a/libcore/ClassHierarchy.h 2009-11-16 14:42:56 +0000
+++ b/libcore/ClassHierarchy.h 2009-12-01 11:02:43 +0000
@@ -24,11 +24,11 @@
#endif
#include "as_object.h"
-#include "SafeStack.h"
-#include "Class.h"
-#include "Namespace.h"
#ifdef ENABLE_AVM2
+# include "SafeStack.h"
+# include "Script.h"
+# include "Namespace.h"
# include "BoundValues.h"
# include "asException.h"
# include "Method.h"
@@ -116,12 +116,12 @@
ClassHierarchy(as_object* global, Extension* e)
:
mGlobal(global),
- mExtension(e) ,
+ mExtension(e)
+#ifdef ENABLE_AVM2
+ ,
mAnonNamespaces(),
mGlobalNamespace(addNamespace(0)),
- mClassMemory()
-#ifdef ENABLE_AVM2
- ,
+ mScriptMemory(),
mExceptionMemory(),
mMethodMemory(),
mBoundValueMemory(),
@@ -133,7 +133,6 @@
/// Delete our private namespaces.
~ClassHierarchy();
-
typedef std::vector<NativeClass> NativeClasses;
/// Declare an ActionScript class, with information on how to load it.
@@ -155,21 +154,20 @@
/// Declare a list of native classes.
void declareAll(const NativeClasses& classes);
+#ifdef ENABLE_AVM2
+
/// The global namespace
///
/// Get the global namespace. This is not the Global object -- it only
/// contains the classes, not any globally available functions or
anything
/// else.
- Namespace* getGlobalNs() { return mGlobalNamespace; }
-
- // Chad: Document
- as_object* newOfType(string_table::key /*whattype*/) { return NULL; }
+ abc::Namespace* getGlobalNs() { return mGlobalNamespace; }
/// Find a namespace with the given uri.
///
/// @return
/// The namespace with the given uri or NULL if it doesn't exist.
- Namespace* findNamespace(string_table::key uri)
+ abc::Namespace* findNamespace(string_table::key uri)
{
namespacesContainer::iterator i;
if (mNamespaces.empty())
@@ -186,10 +184,10 @@
/// can't ever be found. (They must be kept and passed to the
appropriate
/// objects.)
///
- Namespace* anonNamespace(string_table::key uri)
+ abc::Namespace* anonNamespace(string_table::key uri)
{
mAnonNamespaces.grow(1);
- Namespace *n = &mAnonNamespaces.top(0);
+ abc::Namespace *n = &mAnonNamespaces.top(0);
n->setURI(uri);
return n;
}
@@ -198,9 +196,9 @@
/// Add a namespace to the set. Don't use to add unnamed namespaces.
/// Will overwrite existing namespaces 'kind' and 'prefix' values.
/// Returns the added space.
- Namespace* addNamespace(string_table::key uri)
+ abc::Namespace* addNamespace(string_table::key uri)
{
- Namespace *n = findNamespace(uri);
+ abc::Namespace *n = findNamespace(uri);
if (n) return n;
// The set should create it automatically here. TODO: Make sure
mNamespaces[uri].setURI(uri);
@@ -208,13 +206,11 @@
}
/// Create a new abc::Class object for use.
- abc::Class* newClass() {
- mClassMemory.grow(1);
- return &mClassMemory.top(0);
+ abc::Script* newScript() {
+ mScriptMemory.grow(1);
+ return &mScriptMemory.top(0);
}
-#ifdef ENABLE_AVM2
-
asException* newException() {
mExceptionMemory.grow(1);
return &mExceptionMemory.top(0);
@@ -245,13 +241,12 @@
as_object* mGlobal;
Extension* mExtension;
- typedef std::map<string_table::key, Namespace> namespacesContainer;
+#ifdef ENABLE_AVM2
+ typedef std::map<string_table::key, abc::Namespace> namespacesContainer;
namespacesContainer mNamespaces;
- SafeStack<Namespace> mAnonNamespaces;
- Namespace* mGlobalNamespace;
- SafeStack<abc::Class> mClassMemory;
-
-#ifdef ENABLE_AVM2
+ SafeStack<abc::Namespace> mAnonNamespaces;
+ abc::Namespace* mGlobalNamespace;
+ SafeStack<abc::Script> mScriptMemory;
SafeStack<asException> mExceptionMemory;
SafeStack<abc::Method> mMethodMemory;
SafeStack<abc::BoundValue> mBoundValueMemory;
=== modified file 'libcore/Makefile.am'
--- a/libcore/Makefile.am 2009-11-16 14:42:56 +0000
+++ b/libcore/Makefile.am 2009-12-01 11:02:43 +0000
@@ -130,15 +130,16 @@
styles.cpp \
Timers.cpp \
RGBA.cpp \
- abc/Class.cpp \
MovieFactory.cpp \
MovieLoader.cpp \
- Namespace.cpp \
$(FREETYPE_SOURCES) \
$(NULL)
if ENABLE_AVM2
libgnashcore_la_SOURCES += \
+ abc/Script.cpp \
+ abc/Namespace.cpp \
+ abc/as_class.cpp \
abc/abc_function.cpp \
abc/Method.cpp \
abc/AbcBlock.cpp \
@@ -214,7 +215,10 @@
if ENABLE_AVM2
noinst_HEADERS += \
+ abc/Script.h \
+ abc/Namespace.h \
swf/DoABCTag.h \
+ abc/as_class.h \
abc/abc_function.h \
abc/Method.h \
abc/asException.h \
@@ -269,8 +273,6 @@
RGBA.h \
Geometry.h \
Video.h \
- abc/Class.h \
- Namespace.h \
$(NULL)
# These makefile fragments build the ActionScript library for
=== modified file 'libcore/abc/AbcBlock.cpp'
--- a/libcore/abc/AbcBlock.cpp 2009-11-17 08:09:35 +0000
+++ b/libcore/abc/AbcBlock.cpp 2009-12-01 11:02:43 +0000
@@ -24,7 +24,7 @@
#include "VM.h"
#include "log.h"
#include "ClassHierarchy.h"
-#include "Class.h"
+#include "Script.h"
#include "namedStrings.h"
#include "CodeStream.h"
#include "action_buffer.h"
@@ -36,10 +36,10 @@
namespace abc {
bool
-Trait::finalize(AbcBlock *pBlock, abc::Class *pClass, bool do_static)
+Trait::finalize(AbcBlock *pBlock, abc::Script *pScript, bool do_static)
{
log_abc("Finalize class %s (%s), trait kind: %s",
- pBlock->_stringTable->value(pClass->getName()), pClass, _kind);
+ pBlock->_stringTable->value(pScript->getName()), pScript, _kind);
switch (_kind)
{
@@ -47,12 +47,12 @@
case KIND_CONST:
{
// Validate the type.
- abc::Class *pType;
+ abc::Script *pType;
if (_typeIndex) {
log_abc("Trait type: %s",
pBlock->_stringPool[
pBlock->_multinamePool[_typeIndex].getABCName()]);
- pType =
pBlock->locateClass(pBlock->_multinamePool[_typeIndex]);
+ pType =
pBlock->locateScript(pBlock->_multinamePool[_typeIndex]);
}
else {
pType = pBlock->mTheObject;
@@ -73,23 +73,23 @@
log_abc("Adding property=%s with value=%s slot=%u",
pBlock->_stringPool[_name], _value, _slotID);
- pClass->addValue(_globalName, _namespace, _slotID, pType,
+ pScript->addValue(_globalName, _namespace, _slotID, pType,
_value, _kind == KIND_CONST, do_static);
break;
}
case KIND_METHOD:
{
- pClass->addMethod(_globalName, _namespace, _method, false);
+ pScript->addMethod(_globalName, _namespace, _method, false);
break;
}
case KIND_GETTER:
{
- pClass->addGetter(_name, _namespace, _method, do_static);
+ pScript->addGetter(_name, _namespace, _method, do_static);
break;
}
case KIND_SETTER:
{
- pClass->addSetter(_name, _namespace, _method, do_static);
+ pScript->addSetter(_name, _namespace, _method, do_static);
break;
}
case KIND_CLASS:
@@ -97,13 +97,13 @@
log_abc("Adding class %s, value %s, slot=%u",
pBlock->_stringPool[_name], _value, _slotID);
- pClass->addMemberClass(_globalName, _namespace, _slotID,
+ pScript->addMemberScript(_globalName, _namespace, _slotID,
pBlock->_classes[_classInfoIndex], do_static);
break;
}
case KIND_FUNCTION:
{
- pClass->addSlotFunction(_name, _namespace, _slotID, _method,
do_static);
+ pScript->addSlotFunction(_name, _namespace, _slotID, _method,
do_static);
break;
}
default:
@@ -124,9 +124,9 @@
case KIND_CONST:
{
// Validate the type.
- abc::Class *pType;
+ abc::Script *pType;
if (_typeIndex) {
- pType =
pBlock->locateClass(pBlock->_multinamePool[_typeIndex]);
+ pType =
pBlock->locateScript(pBlock->_multinamePool[_typeIndex]);
}
else {
pType = pBlock->mTheObject;
@@ -165,7 +165,7 @@
}
case KIND_CLASS:
{
- pMethod->addMemberClass(_name, _namespace, _slotID,
+ pMethod->addMemberScript(_name, _namespace, _slotID,
pBlock->_classes[_classInfoIndex]);
break;
}
@@ -250,13 +250,13 @@
{
_slotID = in->read_V32();
_classInfoIndex = in->read_V32();
- log_abc("Slot id: %u Class index: %u Class Name: %s", _slotID,
+ log_abc("Slot id: %u Script index: %u Script Name: %s", _slotID,
_classInfoIndex,
pBlock->_stringTable->value(
pBlock->_classes[_classInfoIndex]->getName()));
if (_classInfoIndex >= pBlock->_classes.size()) {
- log_error(_("Bad Class id in trait."));
+ log_error(_("Bad Script id in trait."));
return false;
}
break;
@@ -321,7 +321,7 @@
mCH = &VM::get().getMachine()->global()->classHierarchy();
// TODO: Make this the real 'Object' prototype.
mCH->getGlobalNs()->stubPrototype(*mCH, NSV::CLASS_OBJECT);
- mTheObject = mCH->getGlobalNs()->getClass(NSV::CLASS_OBJECT);
+ mTheObject = mCH->getGlobalNs()->getScript(NSV::CLASS_OBJECT);
}
void
@@ -329,11 +329,11 @@
{
std::for_each(_classes.begin(), _classes.end(),
- std::mem_fun(&abc::Class::initPrototype));
+ std::mem_fun(&abc::Script::initPrototype));
// The last (entry) script has Global as its prototype.
// This can be deduced because the global classes are initialized with a
- // slot on script 0 (entry script). OpNewClass then attempts to set the
+ // slot on script 0 (entry script). OpNewScript then attempts to set the
// corresponding slot once the class has been constructed. At this point,
// global should verifiably be on the stack, so the slots are expected
// to be set on the global object.
@@ -341,7 +341,7 @@
// scripts have Global as a target object (prototype), so for now we
// will do that.
std::for_each(_scripts.begin(), _scripts.end(),
- boost::bind(&abc::Class::setPrototype, _1, mach->global()));
+ boost::bind(&abc::Script::setPrototype, _1, mach->global()));
std::for_each(_methods.begin(), _methods.end(),
boost::bind(&Method::initPrototype, _1, mach));
@@ -405,8 +405,8 @@
log_abc("Namespace: %s AbcURI=%u URI=%u.", name, ABCName, global_key);
}
-abc::Class*
-AbcBlock::locateClass(const std::string& className)
+abc::Script*
+AbcBlock::locateScript(const std::string& className)
{
const std::string::size_type pos = className.rfind(".");
@@ -432,18 +432,18 @@
}
}
- return locateClass(a);
+ return locateScript(a);
}
-abc::Class*
-AbcBlock::locateClass(MultiName& m)
+abc::Script*
+AbcBlock::locateScript(MultiName& m)
{
- abc::Class* found = 0;
+ abc::Script* found = 0;
if (m.getNamespace())
{
- found = m.getNamespace()->getClass(m.getGlobalName());
+ found = m.getNamespace()->getScript(m.getGlobalName());
if (found) return found;
}
if (m.namespaceSet() && !m.namespaceSet()->empty())
@@ -451,7 +451,7 @@
std::vector<Namespace*>::const_iterator i;
for (i = m.namespaceSet()->begin(); i !=
m.namespaceSet()->end(); ++i) {
- found = (*i)->getClass(m.getGlobalName());
+ found = (*i)->getScript(m.getGlobalName());
if (found) return found;
}
}
@@ -823,12 +823,12 @@
// TODO: this can be 'void', which clearly isn't a class, so this
// seems bogus. As setReturnType is a no-op, we should log it
// and ignore it.
- abc::Class* rtClass = locateClass(_multinamePool[return_type]);
- if (!rtClass) {
+ abc::Script* rtScript = locateScript(_multinamePool[return_type]);
+ if (!rtScript) {
log_abc(_("ABC: Unknown return type."));
}
- pMethod->setReturnType(rtClass);
+ pMethod->setReturnType(rtScript);
}
for (size_t j = 0; j < param_count; ++j) {
log_abc(" Reading parameter %u", j);
@@ -848,7 +848,7 @@
// A value of 0 is legitimate, meaning 'any (*)'.
if (ptype) {
- abc::Class* param_type = locateClass(_multinamePool[ptype]);
+ abc::Script* param_type = locateScript(_multinamePool[ptype]);
if (!param_type) {
log_abc((_("ABC: Unknown parameter type.")));
@@ -936,7 +936,7 @@
log_abc("There are %u instances.", count);
_classes.resize(count);
for (size_t i = 0; i < count; ++i) {
- abc::Class* pClass;
+ abc::Script* pScript;
//Read multiname index.
boost::uint32_t index = _stream->read_V32();
// 0 is allowed as a name, typically for the last entry.
@@ -958,16 +958,16 @@
return false;
}
- pClass = locateClass(multiname);
+ pScript = locateScript(multiname);
- if (!pClass) {
+ if (!pScript) {
const string_table::key className = multiname.getGlobalName();
- pClass = mCH->newClass();
- pClass->setName(className);
+ pScript = mCH->newScript();
+ pScript->setName(className);
- if (!multiname.getNamespace()->addClass(className,
pClass)) {
+ if (!multiname.getNamespace()->addScript(className,
pScript)) {
log_error(_("Duplicate class registration."));
return false;
@@ -980,8 +980,8 @@
multiname.getNamespace()->dump(*_stringTable);
}
- pClass->setDeclared();
- _classes[i] = pClass;
+ pScript->setDeclared();
+ _classes[i] = pScript;
boost::uint32_t super_index = _stream->read_V32();
if (super_index && super_index >= _multinamePool.size()) {
@@ -990,10 +990,10 @@
}
if (!super_index) {
- pClass->setSuper(mTheObject);
+ pScript->setSuper(mTheObject);
}
else {
- abc::Class *pSuper =
locateClass(_multinamePool[super_index]);
+ abc::Script *pSuper =
locateScript(_multinamePool[super_index]);
if (!pSuper)
{
log_error(_("ABC: Super type not found (%s)"),
@@ -1013,25 +1013,25 @@
return false;
}
- if (pSuper == pClass)
+ if (pSuper == pScript)
{
- log_error(_("ABC: Class cannot be its own
supertype."));
+ log_error(_("ABC: Script cannot be its own
supertype."));
return false;
}
- pClass->setSuper(pSuper);
+ pScript->setSuper(pSuper);
pSuper->setInherited();
}
boost::uint8_t flags = _stream->read_u8();
log_abc("Instance %u(%s) multiname index=%u name=%s super
index=%u "
- "flags=%X", i, pClass, index,
+ "flags=%X", i, pScript, index,
_stringPool[_multinamePool[index].getABCName()],
super_index, flags | 0x0);
- if (flags & INSTANCE_SEALED) pClass->setSealed();
- if (flags & INSTANCE_FINAL) pClass->setFinal();
- if (flags & INSTANCE_INTERFACE) pClass->setInterface();
- if ((flags & 7) == INSTANCE_DYNAMIC) pClass->setDynamic();
+ if (flags & INSTANCE_SEALED) pScript->setSealed();
+ if (flags & INSTANCE_FINAL) pScript->setFinal();
+ if (flags & INSTANCE_INTERFACE) pScript->setInterface();
+ if ((flags & 7) == INSTANCE_DYNAMIC) pScript->setDynamic();
if (flags & INSTANCE_PROTECTED_NS) {
boost::uint32_t ns_index = _stream->read_V32();
@@ -1040,10 +1040,10 @@
return false;
}
// Set the protected namespace's parent, if it exists.
- if (pClass->getSuper()->hasProtectedNs())
+ if (pScript->getSuper()->hasProtectedNs())
_namespacePool[ns_index]->setParent(
- pClass->getSuper()->getProtectedNs());
- pClass->setProtectedNs(_namespacePool[ns_index]);
+ pScript->getSuper()->getProtectedNs());
+ pScript->setProtectedNs(_namespacePool[ns_index]);
}
// This is the list of interfaces which the instances has
agreed to
@@ -1058,14 +1058,14 @@
log_error(_("ABC: Bad name for interface."));
return false;
}
- abc::Class *pInterface =
locateClass(_multinamePool[i_index]);
+ abc::Script *pInterface =
locateScript(_multinamePool[i_index]);
// These may be undefined still, so don't check
interface just yet.
if (0) //!pInterface || !pInterface->isInterface())
{
log_error(_("ABC: Can't implement a
non-interface type."));
return false;
}
- pClass->pushInterface(pInterface);
+ pScript->pushInterface(pInterface);
}
// The next thing should be the constructor.
@@ -1078,12 +1078,12 @@
return false;
}
// Don't validate for previous owner.
- pClass->setConstructor(_methods[offset]);
+ pScript->setConstructor(_methods[offset]);
/* Calling the Method::setOwner always results in a
segmentation fault,
since it tries to modify Method.mPrototype, which is never
initialized. The parser seems to work ok without this call.*/
-// _methods[offset]->setOwner(pClass);
+// _methods[offset]->setOwner(pScript);
// Next come the 'traits' of the instance. (The members.)
boost::uint32_t tcount = _stream->read_V32();
@@ -1091,7 +1091,7 @@
for (unsigned int j = 0; j < tcount; ++j)
{
Trait &aTrait = newTrait();
- aTrait.set_target(pClass, false);
+ aTrait.set_target(pScript, false);
if (!aTrait.read(_stream, this))
return false;
}
@@ -1109,9 +1109,9 @@
log_abc("There are %u classes.", count);
for (size_t i = 0; i < count; ++i) {
- abc::Class* pClass = _classes[i];
+ abc::Script* pScript = _classes[i];
boost::uint32_t offset = _stream->read_V32();
- log_abc("Class %u(%s) static constructor index=%u", i, pClass,
offset);
+ log_abc("Script %u(%s) static constructor index=%u", i,
pScript, offset);
if (offset >= _methods.size()) {
log_error(_("ABC: Out of bound static constructor for
class."));
@@ -1119,18 +1119,18 @@
}
// Don't validate for previous owner.
- pClass->setStaticConstructor(_methods[offset]);
+ pScript->setStaticConstructor(_methods[offset]);
/* Calling the Method::setOwner always results in a
segmentation fault,
since it tries to modify Method.mPrototype, which is never
initialized. The parser seems to work ok without this call.*/
-// _methods[offset]->setOwner(pClass);
+// _methods[offset]->setOwner(pScript);
boost::uint32_t tcount = _stream->read_V32();
log_abc("This class has %u traits.", tcount);
for (size_t j = 0; j < tcount; ++j) {
Trait &aTrait = newTrait();
- aTrait.set_target(pClass, true);
+ aTrait.set_target(pScript, true);
if (!(aTrait.read(_stream, this)))
return false;
}
@@ -1149,7 +1149,7 @@
_scripts.resize(count);
for (unsigned int i = 0; i < count; ++i)
{
- abc::Class* pScript = mCH->newClass();
+ abc::Script* pScript = mCH->newScript();
_scripts[i] = pScript;
boost::uint32_t offset = _stream->read_V32();
@@ -1257,7 +1257,7 @@
pExcept->catchAny();
}
else {
- abc::Class *pType =
locateClass(_multinamePool[catch_type]);
+ abc::Script *pType =
locateScript(_multinamePool[catch_type]);
if (!pType) {
log_error(_("ABC: Unknown type of
object to catch. (%s)"),
=== modified file 'libcore/abc/AbcBlock.h'
--- a/libcore/abc/AbcBlock.h 2009-11-17 08:09:35 +0000
+++ b/libcore/abc/AbcBlock.h 2009-12-01 11:02:43 +0000
@@ -35,11 +35,11 @@
namespace abc {
class AbcBlock;
class Machine;
- class Class;
+ class Script;
class Method;
}
class SWFStream; // for read signature
- class ClassHierarchy;
+ class ClasstHierarchy;
}
namespace gnash {
@@ -78,7 +78,7 @@
Method* _method;
bool _valueSet;
- abc::Class* _classTarget;
+ abc::Script* _classTarget;
Method* _methodTarget;
bool _static;
@@ -102,12 +102,12 @@
bool read(SWFStream* in, AbcBlock *pBlock);
- bool finalize(AbcBlock* pBlock, abc::Class* pClass, bool do_static);
+ bool finalize(AbcBlock* pBlock, abc::Script* pScript, bool do_static);
bool finalize_mbody(AbcBlock* pBlock, Method* pMethod);
- void set_target(abc::Class* pClass, bool do_static) {
- _classTarget = pClass;
+ void set_target(abc::Script* pScript, bool do_static) {
+ _classTarget = pScript;
_static = do_static;
}
@@ -159,7 +159,7 @@
/// flash.text namespace. Using the global name means that we 'import' the
/// built-in namespace into our own resources.
//
-/// Instances / Classes
+/// Instances / Scriptes
//
/// Likewise, classes are always given a global name, not an ABC name. This is
/// because they become globally available, including (we assume) to other ABC
@@ -169,14 +169,14 @@
/// the built-in classes already in a namespace: ABC names and global names
/// can have the same index even when the names are different.
//
-/// Class lookup
+/// Script lookup
//
-/// This is particularly important for locateClass (called by instantiateClass
-/// from SymbolClass tag execution). The SymbolClass tag identifies a class
+/// This is particularly important for locateScript (called by
instantiateScript
+/// from SymbolScript tag execution). The SymbolScript tag identifies a class
/// using a global name, which may be qualified with a namespace. If it is
/// not qualified, we look in the global namespace 0.
//
-/// When we call locateClass, we use global names, not ABC names, because
+/// When we call locateScript, we use global names, not ABC names, because
/// classes are identified by global names (see above). However, we
/// still look only in the ABC block's namespaces. The block's first namespace
/// is always the global namespace; other package namespaces are imported
@@ -233,9 +233,9 @@
AbcBlock();
- abc::Class* locateClass(MultiName &m);
+ abc::Script* locateScript(MultiName &m);
- abc::Class* locateClass(const std::string& className);
+ abc::Script* locateScript(const std::string& className);
abc::Trait &newTrait()
{
@@ -248,7 +248,7 @@
void update_global_name(unsigned int multiname_index);
- const std::vector<abc::Class*>& scripts() const {
+ const std::vector<abc::Script*>& scripts() const {
return _scripts;
}
@@ -282,7 +282,7 @@
return _multinamePool[i];
}
- abc::Class* classPoolAt(size_t i) const {
+ abc::Script* classPoolAt(size_t i) const {
checkBounds(i, _classes);
return _classes[i];
}
@@ -333,14 +333,14 @@
std::vector<NamespaceSet> _namespaceSetPool;
std::vector<Method*> _methods;
std::vector<MultiName> _multinamePool;
- std::vector<Class*> _classes;
- std::vector<Class*> _scripts;
+ std::vector<Script*> _classes;
+ std::vector<Script*> _scripts;
std::vector<Trait*> _traits;
string_table* _stringTable;
SWFStream* _stream; // Not stored beyond one read.
- abc::Class *mTheObject;
+ abc::Script *mTheObject;
ClassHierarchy *mCH;
boost::uint32_t mVersion;
=== modified file 'libcore/abc/Method.cpp'
--- a/libcore/abc/Method.cpp 2009-11-16 14:42:56 +0000
+++ b/libcore/abc/Method.cpp 2009-12-01 11:02:43 +0000
@@ -20,7 +20,7 @@
#endif
#include "Method.h"
-#include "Class.h"
+#include "Script.h"
#include "CodeStream.h"
#include "abc_function.h"
#include "Global_as.h"
@@ -65,7 +65,7 @@
}
void
-Method::setOwner(Class *pOwner)
+Method::setOwner(Script *pOwner)
{
log_debug("Method::setOwner");
if (!_prototype) {
@@ -75,14 +75,14 @@
}
void
-Method::setReturnType(Class* /*type*/)
+Method::setReturnType(Script* /*type*/)
{
/* No-op */
}
bool
Method::addValue(string_table::key name, Namespace *ns,
- boost::uint32_t slotId, Class *type, as_value& val, bool isconst)
+ boost::uint32_t slotId, Script *type, as_value& val, bool isconst)
{
Global_as* g = VM::get().getGlobal();
if (val.is_object()) {
@@ -142,15 +142,15 @@
}
bool
-Method::addMemberClass(string_table::key name, Namespace *ns,
- boost::uint32_t slotId, Class *type)
+Method::addMemberScript(string_table::key name, Namespace *ns,
+ boost::uint32_t slotId, Script *type)
{
return addSlot(name, ns, slotId, type);
}
bool
Method::addSlot(string_table::key name, Namespace* ns, boost::uint32_t slotId,
- Class */*type*/)
+ Script */*type*/)
{
string_table::key nsname = ns ? ns->getURI() : string_table::key(0);
int flags = PropFlags::dontDelete;
@@ -163,7 +163,7 @@
Method::addSlotFunction(string_table::key name, Namespace *ns,
boost::uint32_t slotId, Method *method)
{
- Class a;
+ Script a;
a.setName(NSV::CLASS_FUNCTION);
as_value b(method->getPrototype());
return addValue(name, ns, slotId, &a, b, false);
=== modified file 'libcore/abc/Method.h'
--- a/libcore/abc/Method.h 2009-11-16 14:42:56 +0000
+++ b/libcore/abc/Method.h 2009-12-01 11:02:43 +0000
@@ -34,7 +34,8 @@
namespace abc {
class Machine;
class abc_function;
- class Class;
+ class Namespace;
+ class Script;
}
class CodeStream;
class as_object;
@@ -52,7 +53,7 @@
{
public:
- typedef std::list<Class*> ArgumentList;
+ typedef std::list<Script*> ArgumentList;
Method();
@@ -124,10 +125,10 @@
void setBody(CodeStream *b) { _body = b; }
bool addValue(string_table::key name, Namespace *ns,
- boost::uint32_t slotID, Class *type, as_value& val, bool isconst);
+ boost::uint32_t slotID, Script *type, as_value& val, bool isconst);
bool addSlot(string_table::key name, Namespace *ns,
- boost::uint32_t slotID, Class *type);
+ boost::uint32_t slotID, Script *type);
bool addMethod(string_table::key name, Namespace *ns, Method *method);
@@ -135,30 +136,30 @@
bool addSetter(string_table::key name, Namespace *ns, Method *method);
- bool addMemberClass(string_table::key name, Namespace *ns,
- boost::uint32_t slotID, Class *type);
+ bool addMemberScript(string_table::key name, Namespace *ns,
+ boost::uint32_t slotID, Script *type);
bool addSlotFunction(string_table::key name, Namespace *ns,
boost::uint32_t slotID, Method *method);
/// \brief
/// Set the owner of this method.
- void setOwner(Class* s);
+ void setOwner(Script* s);
/// \brief
/// Get the unique identifier for the return type. 0 is 'anything'.
/// (This is the value of any dynamic property.)
/// Id reference: Type
- Class* getReturnType() const;
+ Script* getReturnType() const;
/// Set the return type
//
/// TODO: This is currently a no-op, so find out what it's for and
/// implement it.
/// NB: the return type of a method can be * (any) or void, neither of
- /// which are abc::Classes, so this may not be an appropriate way to
+ /// which are abc::Scriptes, so this may not be an appropriate way to
/// handle return type.
- void setReturnType(Class* t);
+ void setReturnType(Script* t);
Method *getSuper();
@@ -220,7 +221,7 @@
/// Push an argument of type t into the method definition
//
/// A value of 0 stands for 'any'.
- void pushArgument(Class* t) { _arguments.push_back(t); }
+ void pushArgument(Script* t) { _arguments.push_back(t); }
/// Push an optional argument's default value.
void pushOptional(const as_value& v) { _optionalArguments.push_back(v);
}
=== modified file 'libcore/abc/MultiName.h'
--- a/libcore/abc/MultiName.h 2009-11-16 14:01:20 +0000
+++ b/libcore/abc/MultiName.h 2009-12-01 11:02:43 +0000
@@ -20,11 +20,14 @@
#include <vector>
namespace gnash {
-
-class as_object;
-class Namespace;
-class Property;
-
+ class as_object;
+ class Property;
+ namespace abc {
+ class Namespace;
+ }
+}
+
+namespace gnash {
namespace abc {
/// This type should always be used for the index of AbcBlocks' names.
=== renamed file 'libcore/Namespace.cpp' => 'libcore/abc/Namespace.cpp'
--- a/libcore/Namespace.cpp 2009-11-16 14:42:56 +0000
+++ b/libcore/abc/Namespace.cpp 2009-12-01 11:02:43 +0000
@@ -28,22 +28,22 @@
#include <sstream>
namespace gnash {
+namespace abc {
void
Namespace::stubPrototype(ClassHierarchy& ch, string_table::key name)
{
- abc::Class *pClass = ch.newClass();
+ abc::Script *pClass = ch.newScript();
pClass->setName(name);
- addClass(name, pClass);
+ addScript(name, pClass);
}
void
Namespace::dump(string_table& st)
{
-#if ENABLE_AVM2
std::ostringstream s;
- for (container::const_iterator i = _classes.begin(), e = _classes.end();
+ for (container::const_iterator i = _scripts.begin(), e = _scripts.end();
i != e; ++i)
{
const string_table::key t = i->second->getName();
@@ -52,7 +52,7 @@
log_debug("Classes in namespace %s (URI: %s): %s",
st.value(_uri), _uri, s.str());
-#endif
}
-}
+} // namespace abc
+} // namespace gnash
=== renamed file 'libcore/Namespace.h' => 'libcore/abc/Namespace.h'
--- a/libcore/Namespace.h 2009-11-16 14:42:56 +0000
+++ b/libcore/abc/Namespace.h 2009-12-01 11:11:21 +0000
@@ -24,13 +24,14 @@
// Forward declarations
namespace gnash {
namespace abc {
- class Class;
+ class Script;
}
class ClassHierarchy;
class string_table;
}
namespace gnash {
+namespace abc {
/// Represent an ActionScript Namespace
//
@@ -40,6 +41,9 @@
/// Because there is no guarantee that a Namespace is private to an AbcBlock,
/// they must never store any AbcBlock-internal information, particularly
/// not the AbcURI.
+//
+/// A Namespace is currently a collection of Scripts, which should be
+/// turned into a Class on first use.
class Namespace
{
public:
@@ -50,7 +54,7 @@
_parent(0),
_uri(0),
_prefix(0),
- _classes(),
+ _scripts(),
mRecursePrevent(false),
_private(false),
_protected(false),
@@ -73,12 +77,12 @@
/// What is the XML prefix?
string_table::key getPrefix() const { return _prefix; }
- /// Add a class to the namespace. The namespace stores this, but
- /// does not take ownership. (So don't delete it.)
- bool addClass(string_table::key name, abc::Class *a)
+ /// Add a Script to the namespace. The namespace stores this, but
+ /// does not take ownership.
+ bool addScript(string_table::key name, Script* a)
{
- if (getClassInternal(name)) return false;
- _classes[static_cast<std::size_t>(name)] = a;
+ if (getScriptInternal(name)) return false;
+ _scripts[static_cast<std::size_t>(name)] = a;
return true;
}
@@ -86,16 +90,16 @@
/// Get the named class. Returns NULL if information is not known
/// about the class. (Stubbed classes still return NULL here.)
- abc::Class* getClass(string_table::key name)
+ Script* getScript(string_table::key name)
{
if (mRecursePrevent) return NULL;
- abc::Class* found = getClassInternal(name);
+ Script* found = getScriptInternal(name);
if (found || !getParent()) return found;
mRecursePrevent = true;
- found = getParent()->getClass(name);
+ found = getParent()->getScript(name);
mRecursePrevent = false;
return found;
}
@@ -120,27 +124,28 @@
string_table::key _uri;
string_table::key _prefix;
- typedef std::map<string_table::key, abc::Class*> container;
- container _classes;
+ typedef std::map<string_table::key, Script*> container;
+ container _scripts;
mutable bool mRecursePrevent;
bool _private;
bool _protected;
bool _package;
- abc::Class* getClassInternal(string_table::key name) const
+ Script* getScriptInternal(string_table::key name) const
{
container::const_iterator i;
- if (_classes.empty()) return NULL;
-
- i = _classes.find(name);
-
- if (i == _classes.end()) return NULL;
+ if (_scripts.empty()) return NULL;
+
+ i = _scripts.find(name);
+
+ if (i == _scripts.end()) return NULL;
return i->second;
}
};
+} // namespace abc
} // namespace gnash
#endif
=== renamed file 'libcore/abc/Class.cpp' => 'libcore/abc/Script.cpp'
--- a/libcore/abc/Class.cpp 2009-11-16 14:42:56 +0000
+++ b/libcore/abc/Script.cpp 2009-12-01 11:02:43 +0000
@@ -19,7 +19,7 @@
#include "gnashconfig.h"
#endif
-#include "Class.h"
+#include "Script.h"
#include "as_object.h"
#include "ClassHierarchy.h"
#include "VM.h"
@@ -27,6 +27,7 @@
#include "as_value.h"
#include "Namespace.h"
#include "Global_as.h"
+#include "as_class.h"
#ifdef ENABLE_AVM2
#include "Method.h"
@@ -38,8 +39,8 @@
#ifdef ENABLE_AVM2
bool
-Class::addValue(string_table::key name, Namespace *ns,
- boost::uint32_t slotId, Class *type, as_value& val, bool isconst,
+Script::addValue(string_table::key name, Namespace *ns,
+ boost::uint32_t slotId, Script *type, as_value& val, bool isconst,
bool isstatic)
{
Global_as* g = VM::get().getGlobal();
@@ -65,26 +66,34 @@
}
return true;
}
+
+void
+Script::initPrototype()
+{
+ Global_as& gl = *VM::get().getGlobal();
+ _prototype = new as_class(gl);
+}
+
bool
-Class::addMemberClass(string_table::key name, Namespace *ns,
- boost::uint32_t slotId, Class *type, bool isstatic)
+Script::addMemberScript(string_table::key name, Namespace *ns,
+ boost::uint32_t slotId, Script *type, bool isstatic)
{
return addSlot(name, ns, slotId, type, isstatic);
}
bool
-Class::addSlotFunction(string_table::key name, Namespace *ns,
+Script::addSlotFunction(string_table::key name, Namespace *ns,
boost::uint32_t slotId, Method *method, bool isstatic)
{
- Class a;
+ Script a;
a.setName(NSV::CLASS_FUNCTION);
as_value b(method->getPrototype());
return addValue(name, ns, slotId, &a, b, false, isstatic);
}
bool
-Class::addSlot(string_table::key name, Namespace* ns,
- boost::uint32_t slotId, Class* /*type*/, bool /*isstatic*/)
+Script::addSlot(string_table::key name, Namespace* ns,
+ boost::uint32_t slotId, Script* /*type*/, bool /*isstatic*/)
{
string_table::key nsname = ns ? ns->getURI() : 0;
@@ -99,23 +108,18 @@
}
bool
-Class::addMethod(string_table::key name, Namespace* /*ns*/,
+Script::addMethod(string_table::key name, Namespace* /*ns*/,
Method* method, bool /*isstatic*/)
{
as_value val = new abc::abc_function(method,
getVM(*_prototype).getMachine());
_prototype->init_member(name, val);
-// int flags = PropFlags::readOnly | PropFlags::dontDelete
-// | PropFlags::dontEnum;
-// if (isstatic)
-// flags |= PropFlags::staticProp;
-
return true;
}
bool
-Class::addGetter(string_table::key name, Namespace *ns, Method *method,
+Script::addGetter(string_table::key name, Namespace *ns, Method *method,
bool isstatic)
{
string_table::key nsname = ns ? ns->getURI() : string_table::key(0);
@@ -136,7 +140,7 @@
}
bool
-Class::addSetter(string_table::key name, Namespace *ns, Method *method,
+Script::addSetter(string_table::key name, Namespace *ns, Method *method,
bool isstatic)
{
string_table::key nsname = ns ? ns->getURI() : string_table::key(0);
@@ -158,7 +162,7 @@
#if 0 // TODO
void
-Class::buildFromPrototype(as_object *o, string_table::key name,
+Script::buildFromPrototype(as_object *o, string_table::key name,
ClassHierarchy *pCH)
{
setName(name);
@@ -185,8 +189,8 @@
}
bool
-Class::addValue(string_table::key name, Namespace *ns, boost::uint32_t slotId,
- Class *type, as_value& val, bool isconst, bool isstatic,
+Script::addValue(string_table::key name, Namespace *ns, boost::uint32_t slotId,
+ Script *type, as_value& val, bool isconst, bool isstatic,
ClassHierarchy *CH)
{
asBoundValue *bv = CH->newBoundValue();
@@ -198,8 +202,8 @@
}
bool
-Class::addSlot(string_table::key name, Namespace *ns, boost::uint32_t slotId,
- Class *type, bool isstatic, ClassHierarchy *CH)
+Script::addSlot(string_table::key name, Namespace *ns, boost::uint32_t slotId,
+ Script *type, bool isstatic, ClassHierarchy *CH)
{
asBoundValue *bv = CH->newBoundValue();
bv->setType(type);
@@ -209,7 +213,7 @@
}
bool
-Class::addMethod(string_table::key name, Namespace *ns, Method *method,
+Script::addMethod(string_table::key name, Namespace *ns, Method *method,
bool isstatic)
{
if (!isstatic)
@@ -219,8 +223,8 @@
}
bool
-Class::addMemberClass(string_table::key name, Namespace *ns,
- boost::uint32_t slotId, Class *type, bool isstatic)
+Script::addMemberScript(string_table::key name, Namespace *ns,
+ boost::uint32_t slotId, Script *type, bool isstatic)
{
if (!isstatic)
return addBinding(name, asBinding(ns, type, slotId, isstatic));
@@ -229,7 +233,7 @@
// TODO: Figure out how this differs from addMethod
bool
-Class::addSlotFunction(string_table::key name, Namespace *ns,
+Script::addSlotFunction(string_table::key name, Namespace *ns,
boost::uint32_t slotId, Method *method, bool isstatic)
{
if (!isstatic)
=== renamed file 'libcore/abc/Class.h' => 'libcore/abc/Script.h'
--- a/libcore/abc/Class.h 2009-11-16 14:42:56 +0000
+++ b/libcore/abc/Script.h 2009-12-01 11:11:21 +0000
@@ -15,8 +15,8 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-#ifndef GNASH_AS_CLASS_H
-#define GNASH_AS_CLASS_H
+#ifndef GNASH_ABC_SCRIPT_H
+#define GNASH_ABC_SCRIPT_H
#ifdef HAVE_CONFIG_H
#include "gnashconfig.h"
@@ -44,10 +44,10 @@
class BoundValue;
class BoundAccessor;
class Method;
- class Class;
+ class Script;
typedef Property Binding;
+ class Namespace;
}
- class Namespace;
class ClassHierarchy;
class Property;
}
@@ -55,17 +55,32 @@
namespace gnash {
namespace abc {
-/// A class to represent, abstractly, ActionScript prototypes.
-///
-/// This class is intended to be able to capture the structure of an
-/// ActionScript prototype as a type, rather than as an object. This is
-/// contrary to the spirit of ActionScript as a dynamic language, but it is
-/// incredibly helpful to an interpreter for that language.
-class Class
+/// A class to represent, AS3 scripts.
+//
+/// Used to store ABC scripts. These are not themselves AS-referenceable
+/// objects, but can be associated with AS3 Class objects in a way that
+/// is yet to be determined.
+//
+/// TODO: update this documentation when we've worked it out.
+//
+/// A Script is a static description of a Class. Scripts have the following
+/// important properties:
+//
+/// 1. A static initialization method ("cinit"). This is executed no more
+/// than once. The point at which the cinit method is called depends on
+/// the structure of the SWF. It is always executed before the iinit
+/// method is called.
+/// 2. A constructor method ("iinit"). This is run every time the Class
+/// is constructed. As not all Classes are constructed, the iinit method
+/// may never be executed.
+//
+/// Note that Gnash (and AS3), a Class is regarded as an instance of a
+/// Script, and an Object is an instance of a Class.
+class Script
{
public:
- Class()
+ Script()
:
_prototype(0),
_final(false),
@@ -104,11 +119,11 @@
#ifdef ENABLE_AVM2
bool addValue(string_table::key name, Namespace *ns,
- boost::uint32_t slotID, Class *type, as_value& val,
+ boost::uint32_t slotID, Script *type, as_value& val,
bool isconst, bool isstatic);
bool addSlot(string_table::key name, Namespace *ns,
- boost::uint32_t slotID, Class *type, bool isstatic);
+ boost::uint32_t slotID, Script *type, bool isstatic);
bool addMethod(string_table::key name, Namespace *ns, Method *method,
bool isstatic);
@@ -119,8 +134,8 @@
bool addSetter(string_table::key name, Namespace *ns, Method *method,
bool isstatic);
- bool addMemberClass(string_table::key name, Namespace *ns,
- boost::uint32_t slotID, Class *type, bool isstatic);
+ bool addMemberScript(string_table::key name, Namespace *ns,
+ boost::uint32_t slotID, Script *type, bool isstatic);
// TODO: Figure out how this differs from addMethod
bool addSlotFunction(string_table::key name, Namespace *ns,
@@ -177,33 +192,41 @@
_prototype = prototype;
}
- void initPrototype() {
- _prototype = new as_object();
- }
+ void initPrototype();
- /// What is the type of our parent class?
- Class* getSuper() const { return _super; }
+ /// TODO: see if these are useful.
+ Script* getSuper() const { return _super; }
+ void setSuper(Script *p) { _super = p; }
/// We implement this interface.
- void pushInterface(Class* p) { _interfaces.push_back(p); }
+ void pushInterface(Script* p) { _interfaces.push_back(p); }
- /// This is our constructor.
+ /// Set the iinit method.
+ //
+ /// This is used to construct instances of the Class.
void setConstructor(Method *m) { _constructor = m; }
- Method *getConstructor() { return _constructor; }
-
+
+ /// Get the iinit method or 'constructor'.
+ //
+ /// A Script is also valid if it does not have an iinit method, so this
+ /// function can return 0.
+ Method* getConstructor() const {
+ return _constructor;
+ }
+
+ /// Set the cinit method
+ //
+ /// This is used to initialize the Class.
void setStaticConstructor(Method *m) { _staticConstructor = m; }
-
+
+ /// Get the cinit method or 'static constructor'.
+ //
+ /// A Script may have no cinit method, so this function can return 0.
Method* getStaticConstructor() const {
return _staticConstructor;
}
- void setSuper(Class *p) { _super = p; }
-
- /// Try to build an Class object from just a prototype.
- void buildFro_prototype(as_object *o, string_table::key name,
- ClassHierarchy *);
-
- Binding *getBinding(string_table::key name)
+ Binding* getBinding(string_table::key name)
{
BindingContainer::iterator i;
if (_bindings.empty()) return NULL;
@@ -246,9 +269,9 @@
bool _dynamic;
bool _interface;
string_table::key _name;
- std::list<Class*> _interfaces;
+ std::list<Script*> _interfaces;
Namespace* _protectedNs;
- Class* _super;
+ Script* _super;
Method* _constructor;
Method* _staticConstructor;
=== modified file 'libcore/abc/abc_function.cpp'
--- a/libcore/abc/abc_function.cpp 2009-11-23 07:42:51 +0000
+++ b/libcore/abc/abc_function.cpp 2009-12-01 11:02:43 +0000
@@ -17,7 +17,6 @@
#include "log.h"
#include "abc_function.h"
-#include "Class.h"
#include "fn_call.h"
#include "Machine.h"
=== modified file 'libcore/abc/abc_function.h'
--- a/libcore/abc/abc_function.h 2009-11-23 07:42:51 +0000
+++ b/libcore/abc/abc_function.h 2009-12-01 11:02:43 +0000
@@ -25,7 +25,6 @@
#include "as_function.h"
#include "as_value.h"
#include "CodeStream.h"
-#include "Class.h"
#include "SafeStack.h"
#include "as_object.h"
#include "as_environment.h"
=== modified file 'libcore/abc/asException.h'
--- a/libcore/abc/asException.h 2009-11-16 14:42:56 +0000
+++ b/libcore/abc/asException.h 2009-12-01 11:02:43 +0000
@@ -19,6 +19,13 @@
#define GNASH_AS_EXCEPTION_H
namespace gnash {
+ namespace abc {
+ class Namespace;
+ class Script;
+ }
+}
+
+namespace gnash {
class asException
{
@@ -27,8 +34,8 @@
void setEnd(boost::uint32_t i) { mEnd = i; }
void setCatch(boost::uint32_t i) { mCatch = i; }
void catchAny() { mCatchAny = true; }
- void setCatchType(abc::Class* p) { mCatchType = p; }
- void setNamespace(Namespace* n) { _namespace = n; }
+ void setCatchType(abc::Script* p) { mCatchType = p; }
+ void setNamespace(abc::Namespace* n) { _namespace = n; }
void setName(string_table::key name) { _name = name; }
private:
@@ -36,8 +43,8 @@
boost::uint32_t mEnd;
boost::uint32_t mCatch;
bool mCatchAny;
- abc::Class *mCatchType;
- Namespace *_namespace;
+ abc::Script *mCatchType;
+ abc::Namespace *_namespace;
string_table::key _name;
};
=== added file 'libcore/abc/as_class.cpp'
--- a/libcore/abc/as_class.cpp 1970-01-01 00:00:00 +0000
+++ b/libcore/abc/as_class.cpp 2009-12-01 08:45:59 +0000
@@ -0,0 +1,34 @@
+//
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "as_class.h"
+#include <string>
+
+namespace gnash {
+namespace abc {
+
+const std::string&
+as_class::stringValue() const
+{
+ assert(isAS3(*this));
+
+ static const std::string str("[class Class]");
+ return str;
+}
+
+}
+}
=== added file 'libcore/abc/as_class.h'
--- a/libcore/abc/as_class.h 1970-01-01 00:00:00 +0000
+++ b/libcore/abc/as_class.h 2009-12-01 08:45:59 +0000
@@ -0,0 +1,43 @@
+//
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef GNASH_ABC_AS_CLASS_H
+#define GNASH_ABC_AS_CLASS_H
+
+#include "as_object.h"
+
+namespace gnash {
+namespace abc {
+
+/// The implementation of a 'Class' type in ActionScript 3.
+//
+/// A Class is a first-class type, i.e. it can be referenced itself in
+/// ActionScript.
+class as_class : public as_object
+{
+public:
+ as_class(Global_as& gl) : as_object(gl) {}
+ virtual ~as_class() {}
+
+ virtual const std::string& stringValue() const;
+
+};
+
+} // namespace abc
+} // namespace gnash
+
+#endif
=== modified file 'libcore/as_function.cpp'
--- a/libcore/as_function.cpp 2009-11-30 12:06:32 +0000
+++ b/libcore/as_function.cpp 2009-12-01 08:42:45 +0000
@@ -72,6 +72,15 @@
init_member(NSV::PROP_uuPROTOuu, as_value(getFunctionPrototype()),
flags);
}
+const std::string&
+as_function::stringValue() const
+{
+ // TODO: find out what AS3 functions return.
+ static const std::string str("[type Function]");
+ return str;
+}
+
+
NativeFunction*
as_function::getFunctionConstructor()
{
=== modified file 'libcore/as_function.h'
--- a/libcore/as_function.h 2009-11-30 12:32:56 +0000
+++ b/libcore/as_function.h 2009-12-01 08:42:45 +0000
@@ -72,6 +72,8 @@
/// be called.
virtual as_value call(const fn_call& fn) = 0;
+ virtual const std::string& stringValue() const;
+
/// Run this function as a constructor on an object
//
/// This function assigns various constructor properties and runs the
=== modified file 'libcore/as_object.cpp'
--- a/libcore/as_object.cpp 2009-11-23 18:05:35 +0000
+++ b/libcore/as_object.cpp 2009-12-01 11:02:43 +0000
@@ -43,7 +43,6 @@
#include <boost/algorithm/string/case_conv.hpp>
#include <utility> // for std::pair
#include "namedStrings.h"
-#include "Class.h"
namespace gnash {
@@ -284,10 +283,25 @@
}
as_value
-as_object::call(const fn_call& /*fn*/) {
+as_object::call(const fn_call& /*fn*/)
+{
throw ActionTypeError();
}
+const std::string&
+as_object::stringValue() const
+{
+ // TODO: AS3 returns a string describing the type of object, e.g.
+ // "[object MyObject]"
+ if (isAS3(*this)) {
+ static const std::string str("[object Object]");
+ return str;
+ }
+
+ static const std::string str("[object Object]");
+ return str;
+}
+
std::pair<bool,bool>
as_object::delProperty(string_table::key name, string_table::key nsname)
{
@@ -773,7 +787,7 @@
as_object::init_property(const std::string& key, as_function& getter,
as_function& setter, int flags, string_table::key nsname)
{
- string_table::key k = getStringTable(*this).find(PROPNAME(key));
+ string_table::key k = getStringTable(*this).find(key);
init_property(k, getter, setter, flags, nsname);
}
@@ -792,7 +806,7 @@
as_object::init_property(const std::string& key, as_c_function_ptr getter,
as_c_function_ptr setter, int flags, string_table::key nsname)
{
- string_table::key k = getStringTable(*this).find(PROPNAME(key));
+ string_table::key k = getStringTable(*this).find(key);
init_property(k, getter, setter, flags, nsname);
}
@@ -827,7 +841,7 @@
as_object::init_readonly_property(const std::string& key, as_function& getter,
int initflags, string_table::key nsname)
{
- string_table::key k = getStringTable(*this).find(PROPNAME(key));
+ string_table::key k = getStringTable(*this).find(key);
init_property(k, getter, getter, initflags | PropFlags::readOnly
| PropFlags::isProtected, nsname);
@@ -847,7 +861,7 @@
as_object::init_readonly_property(const std::string& key,
as_c_function_ptr getter, int initflags, string_table::key nsname)
{
- string_table::key k = getStringTable(*this).find(PROPNAME(key));
+ string_table::key k = getStringTable(*this).find(key);
init_property(k, getter, getter, initflags | PropFlags::readOnly
| PropFlags::isProtected, nsname);
@@ -1310,10 +1324,16 @@
return o.vm().getSWFVersion();
}
-Global_as& getGlobal(const as_object& o)
+Global_as&
+getGlobal(const as_object& o)
{
return *o.vm().getGlobal();
}
+bool
+isAS3(const as_object& o)
+{
+ return isAS3(getVM(o));
+}
} // end of gnash namespace
=== modified file 'libcore/as_object.h'
--- a/libcore/as_object.h 2009-11-23 18:05:35 +0000
+++ b/libcore/as_object.h 2009-12-01 08:42:45 +0000
@@ -182,6 +182,8 @@
explicit as_object(Global_as& global);
/// Construct an ActionScript object with no prototype associated.
+ //
+ /// This constructor is deprecated!
as_object();
/// Function dispatch
@@ -191,6 +193,12 @@
/// implementation throws an ActionTypeError.
virtual as_value call(const fn_call& fn);
+ /// Return the string representation for this object
+ //
+ /// This is dependent on the VM version and the type of object, function,
+ /// or class.
+ virtual const std::string& stringValue() const;
+
/// The most common flags for built-in properties.
//
/// Most API properties, including classes and objects, have these flags.
@@ -1196,24 +1204,27 @@
return relay;
}
-/// Get the VM from an as_object
+/// Get the VM from an as_object.
VM& getVM(const as_object& o);
-/// Get the movie_root from an as_object
+/// Get the movie_root from an as_object.
movie_root& getRoot(const as_object& o);
-/// Get the string_table from an as_object
+/// Get the string_table from an as_object.
string_table& getStringTable(const as_object& o);
-/// Get the RunResources from an as_object
+/// Get the RunResources from an as_object.
const RunResources& getRunResources(const as_object& o);
-/// Get the executing VM version from an as_object
+/// Get the executing VM version from an as_object.
int getSWFVersion(const as_object& o);
-/// Get the Global object from an as_object
+/// Get the Global object from an as_object.
Global_as& getGlobal(const as_object& o);
+/// Return whether the object is an AS3 object.
+bool isAS3(const as_object& o);
+
} // namespace gnash
=== modified file 'libcore/as_value.cpp'
--- a/libcore/as_value.cpp 2009-11-30 11:12:37 +0000
+++ b/libcore/as_value.cpp 2009-12-01 09:35:54 +0000
@@ -271,7 +271,7 @@
if ( _error ) return true;
// Tested with SharedObject and AMFPHP
- if ( val.is_function() )
+ if (val.is_function())
{
log_debug("AMF0: skip serialization of FUNCTION property");
return true;
@@ -318,23 +318,6 @@
};
-//
-// as_value -- ActionScript value type
-//
-
-as_value::as_value(as_function* func)
- :
- m_type(AS_FUNCTION)
-{
- if (func) {
- _value = func;
- }
- else {
- m_type = NULLTYPE;
- _value = boost::blank();
- }
-}
-
// Conversion to const std::string&.
std::string
as_value::to_string() const
@@ -385,10 +368,9 @@
return b ? "true" : "false";
}
- case AS_FUNCTION:
case OBJECT:
{
- as_object* obj = m_type == AS_FUNCTION ? getFun() : getObj();
+ as_object* obj = getObj();
String_as* s;
if (isNativeType(obj, s)) return s->value();
@@ -411,9 +393,10 @@
#endif
}
- if ( m_type == OBJECT ) return "[type Object]";
- assert(m_type == AS_FUNCTION);
- return "[type Function]";
+ if (m_type == OBJECT) {
+ return is_function() ? "[type Function]" :
+ "[type Object]";
+ }
}
@@ -449,7 +432,6 @@
{
case STRING: return PTYPE_STRING;
case NUMBER: return PTYPE_NUMBER;
- case AS_FUNCTION:
case UNDEFINED:
case NULLTYPE:
case MOVIECLIP:
@@ -504,7 +486,7 @@
as_value
as_value::to_primitive(AsType hint) const
{
- if ( m_type != OBJECT && m_type != AS_FUNCTION ) return *this;
+ if (m_type != OBJECT) return *this;
#if GNASH_DEBUG_CONVERSION_TO_PRIMITIVE
log_debug("to_primitive(%s)", hint==NUMBER ? "NUMBER" : "STRING");
@@ -513,21 +495,18 @@
// TODO: implement as_object::DefaultValue (ECMA-262 - 8.6.2.6)
as_value method;
- as_object* obj = NULL;
-
- if (hint == NUMBER)
- {
-#if 1
- if ( m_type == MOVIECLIP )
- {
- return as_value(NaN);
- }
-#endif
- if ( m_type == OBJECT ) obj = getObj();
- else obj = getFun();
-
- if ((!obj->get_member(NSV::PROP_VALUE_OF, &method)) ||
(!method.is_function()))
- {
+ as_object* obj(0);
+
+ if (hint == NUMBER) {
+
+ if (m_type == MOVIECLIP) return as_value(NaN);
+
+ assert(m_type == OBJECT);
+ obj = getObj();
+
+ if ((!obj->get_member(NSV::PROP_VALUE_OF, &method)) ||
+ (!method.is_function())) {
+
#if GNASH_DEBUG_CONVERSION_TO_PRIMITIVE
log_debug(" valueOf not found");
#endif
@@ -538,17 +517,12 @@
return as_value();
}
}
- else
- {
- assert(hint==STRING);
-
- if ( m_type == MOVIECLIP )
- {
- return as_value(getCharacterProxy().getTarget());
- }
-
- if ( m_type == OBJECT ) obj = getObj();
- else obj = getFun();
+ else {
+ assert(hint == STRING);
+
+ if (m_type == MOVIECLIP) return getCharacterProxy().getTarget();
+ assert(m_type == OBJECT);
+ obj = getObj();
// @@ Moock says, "the value that results from
// calling toString() on the object".
@@ -558,14 +532,14 @@
// text representation for that object is used
// instead.
//
- if ( (!obj->get_member(NSV::PROP_TO_STRING, &method)) ||
- (!method.is_function()) ) // ECMA says ! is_object()
+ if ((!obj->get_member(NSV::PROP_TO_STRING, &method)) ||
+ (!method.is_function())) // ECMA says ! is_object()
{
#if GNASH_DEBUG_CONVERSION_TO_PRIMITIVE
log_debug(" toString not found");
#endif
- if ( (!obj->get_member(NSV::PROP_VALUE_OF, &method)) ||
- (!method.is_function()) ) // ECMA says ! is_object()
+ if ((!obj->get_member(NSV::PROP_VALUE_OF, &method)) ||
+ (!method.is_function())) // ECMA says ! is_object()
{
#if GNASH_DEBUG_CONVERSION_TO_PRIMITIVE
log_debug(" valueOf not found");
@@ -583,7 +557,7 @@
#if GNASH_DEBUG_CONVERSION_TO_PRIMITIVE
log_debug("to_primitive: method call returned %s", ret);
#endif
- if ( ret.m_type == OBJECT || ret.m_type == AS_FUNCTION ) // not a
primitive
+ if (ret.m_type == OBJECT)
{
throw ActionTypeError();
}
@@ -711,7 +685,6 @@
return getNum();
case OBJECT:
- case AS_FUNCTION:
{
// @@ Moock says the result here should be
// "the return value of the object's valueOf()
@@ -729,7 +702,9 @@
log_debug(_("to_primitive(%s, NUMBER) threw an "
"ActionTypeError %s"), *this, e.what());
#endif
- if (m_type == AS_FUNCTION && swfversion < 6) return 0;
+ if (is_function() && swfversion < 6) {
+ return 0;
+ }
return NaN;
}
@@ -754,7 +729,7 @@
VM& vm = VM::get();
//int swfVersion = vm.getSWFVersion();
boost::shared_ptr<amf::Element> el ( new amf::Element );
- boost::intrusive_ptr<as_object> ptr = to_object(*vm.getGlobal());
+ as_object* ptr = to_object(*vm.getGlobal());
switch (m_type) {
case UNDEFINED:
@@ -774,15 +749,12 @@
break;
case OBJECT:
{
- el->makeObject();
- PropsSerializer props(*el, vm);
- ptr->visitProperties<Exists>(props);
+ if (is_function()) break;
+ el->makeObject();
+ PropsSerializer props(*el, vm);
+ ptr->visitProperties<Exists>(props);
break;
}
- case AS_FUNCTION:
- log_unimpl("Converting an AS function to an element is not
supported");
- // TODO: what kind of Element will be left with ? Should we throw an
exception ?
- break;
case MOVIECLIP:
log_unimpl("Converting a Movie Clip to an element is not supported");
// TODO: what kind of Element will be left with ? Should we throw an
exception ?
@@ -823,7 +795,6 @@
case BOOLEAN:
return getBool();
case OBJECT:
- case AS_FUNCTION:
return true;
case MOVIECLIP:
@@ -855,7 +826,6 @@
case BOOLEAN:
return getBool();
case OBJECT:
- case AS_FUNCTION:
return true;
case MOVIECLIP:
@@ -888,7 +858,6 @@
case BOOLEAN:
return getBool();
case OBJECT:
- case AS_FUNCTION:
return true;
case MOVIECLIP:
@@ -919,9 +888,6 @@
case OBJECT:
return getObj();
- case AS_FUNCTION:
- return getFun();
-
case MOVIECLIP:
return getObject(toDisplayObject());
@@ -970,12 +936,11 @@
as_function*
as_value::to_function() const
{
- if (m_type == AS_FUNCTION) {
- // OK.
- return getFun();
+ if (m_type == OBJECT) {
+ return getObj()->to_function();
}
- return NULL;
+ return 0;
}
void
@@ -1006,43 +971,13 @@
setDisplayObject(*obj->displayObject());
return;
}
- as_function* func = obj->to_function();
- if ( func )
- {
- set_as_function(func);
- return;
- }
- if (m_type != OBJECT || getObj() != obj)
- {
+
+ if (m_type != OBJECT || getObj() != obj) {
m_type = OBJECT;
_value = obj;
}
}
-void
-as_value::set_as_object(boost::intrusive_ptr<as_object> obj)
-{
- set_as_object(obj.get());
-}
-
-void
-as_value::set_as_function(as_function* func)
-{
- if (m_type != AS_FUNCTION || getFun() != func)
- {
- m_type = AS_FUNCTION;
- if (func)
- {
- _value = func;
- }
- else
- {
- m_type = NULLTYPE;
- _value = boost::blank(); // to properly destroy anything else
might be stuffed into it
- }
- }
-}
-
bool
as_value::equals(const as_value& v) const
{
@@ -1063,8 +998,8 @@
//
if ( SWFVersion < 6 )
{
- if ( m_type == AS_FUNCTION ) this_nulltype = true;
- if ( v.m_type == AS_FUNCTION ) v_nulltype = true;
+ if (is_function()) this_nulltype = true;
+ if (v.is_function()) v_nulltype = true;
}
if (this_nulltype || v_nulltype)
@@ -1075,8 +1010,8 @@
return this_nulltype == v_nulltype;
}
- bool obj_or_func = (m_type == OBJECT || m_type == AS_FUNCTION);
- bool v_obj_or_func = (v.m_type == OBJECT || v.m_type == AS_FUNCTION);
+ bool obj_or_func = (m_type == OBJECT);
+ bool v_obj_or_func = (v.m_type == OBJECT);
/// Compare to same type
if ( obj_or_func && v_obj_or_func )
@@ -1119,7 +1054,7 @@
// 20. If Type(x) is either String or Number and Type(y) is Object,
// return the result of the comparison x == ToPrimitive(y).
if ( (m_type == STRING || m_type == NUMBER ) &&
- (v.m_type == OBJECT || v.m_type == AS_FUNCTION ))
+ (v.m_type == OBJECT))
{
// convert this value to a primitive and recurse
try
@@ -1146,7 +1081,7 @@
// 21. If Type(x) is Object and Type(y) is either String or Number,
// return the result of the comparison ToPrimitive(x) == y.
if ((v.m_type == STRING || v.m_type == NUMBER) &&
- (m_type == OBJECT || m_type == AS_FUNCTION))
+ (m_type == OBJECT))
{
// convert this value to a primitive and recurse
try
@@ -1267,7 +1202,7 @@
return "boolean";
case as_value::OBJECT:
- return "object";
+ return is_function() ? "function" : "object";
case as_value::MOVIECLIP:
{
@@ -1280,9 +1215,6 @@
case as_value::NULLTYPE:
return "null";
- case as_value::AS_FUNCTION:
- return "function";
-
default:
if (is_exception())
{
@@ -1309,7 +1241,6 @@
return true;
case OBJECT:
- case AS_FUNCTION:
case BOOLEAN:
case STRING:
return _value == v._value;
@@ -1370,12 +1301,6 @@
ret = boost::format("[object(%s):%p]") % typeName(*obj)
% static_cast<void*>(obj);
return ret.str();
}
- case AS_FUNCTION:
- {
- as_function* obj = getFun();
- ret = boost::format("[function(%s):%p]") %
typeName(*obj) % static_cast<void*>(obj);
- return ret.str();
- }
case STRING:
return "[string:" + getStr() + "]";
case NUMBER:
@@ -1422,28 +1347,9 @@
void
as_value::operator=(const as_value& v)
{
-#if 0
- type the_type = v.m_type;
- if (v.is_exception())
- the_type = (type) ((int) the_type - 1);
-#endif
-
m_type = v.m_type;
_value = v._value;
-
-#if 0
- if (v.is_exception())
- flag_exception();
-#endif
-}
-
-as_value::as_value(boost::intrusive_ptr<as_object> obj)
- :
- m_type(UNDEFINED)
-{
- set_as_object(obj);
-}
-
+}
/// Examples:
//
@@ -1564,13 +1470,6 @@
op->setReachable();
break;
}
- case AS_FUNCTION:
- {
- as_function* fp = getFun();
- if (fp)
- fp->setReachable();
- break;
- }
case MOVIECLIP:
{
CharacterProxy sp = getCharacterProxy();
@@ -1582,13 +1481,6 @@
#endif // GNASH_USE_GC
}
-as_function*
-as_value::getFun() const
-{
- assert(m_type == AS_FUNCTION);
- return boost::get<as_object*>(_value)->to_function();
-}
-
as_object*
as_value::getObj() const
{
@@ -1672,14 +1564,17 @@
set_as_object(obj);
}
+bool
+as_value::is_function() const
+{
+ return m_type == OBJECT && getObj()->to_function();
+}
/// Instantiate this value from an AMF element
as_value::as_value(const amf::Element& el)
:
m_type(UNDEFINED)
{
-// GNASH_REPORT_FUNCTION;
-// el.dump();
VM& vm = VM::get();
string_table& st = vm.getStringTable();
@@ -2236,12 +2131,9 @@
log_unimpl(_("serialization of as_value of type %d"), m_type);
return false;
- case AS_FUNCTION:
- log_unimpl(_("serialization of as_value of type FUNCTION"),
m_type);
- return false;
-
case OBJECT:
{
+ if (is_function()) return false;
as_object* obj = to_object(*vm.getGlobal());
assert(obj);
OffsetTable::iterator it = offsetTable.find(obj);
=== modified file 'libcore/as_value.h'
--- a/libcore/as_value.h 2009-11-16 11:16:48 +0000
+++ b/libcore/as_value.h 2009-12-01 11:02:43 +0000
@@ -50,7 +50,6 @@
class as_function;
class MovieClip;
class DisplayObject;
- class Namespace;
class SimpleBuffer;
}
namespace amf {
@@ -81,13 +80,6 @@
}
-/// Use this methods to obtain a properly-formatted property name
-/// The methods will convert the name to lowercase if the current VM target
-/// is SWF6 or lower
-///
-//#define PROPNAME(x) ( VM::get().getSWFVersion() < 7 ?
boost::to_lower_copy(std::string(x)) : (x) )
-#define PROPNAME(x) ( x )
-
/// These are the primitive types, see the ECMAScript reference.
enum primitive_types
{
@@ -135,10 +127,6 @@
OBJECT,
OBJECT_EXCEPT,
- /// ActionScript function reference
- AS_FUNCTION,
- AS_FUNCTION_EXCEPT,
-
/// MovieClip reference
MOVIECLIP,
MOVIECLIP_EXCEPT
@@ -171,7 +159,7 @@
/// Construct a value from an AMF element
as_value(const amf::Element& el);
- /// Construct a NULL, OBJECT, MOVIECLIP or AS_FUNCTION value
+ /// Construct a NULL, OBJECT, MOVIECLIP value
//
/// See as_object::to_movie and as_object::to_function
///
@@ -180,23 +168,17 @@
///
as_value(as_object* obj);
- /// Construct an NULL, MOVIECLIP, AS_FUNCTION or OBJECT value
- as_value(boost::intrusive_ptr<as_object> obj);
-
- /// Construct a NULL or AS_FUNCTION value
- as_value(as_function* func);
-
/// Read AMF0 data from the given buffer
//
/// Pass pointer to buffer and pointer to end of buffer. Buffer is raw
AMF
/// encoded data. Must start with a type byte unless third parameter is
set.
///
/// On success, sets the given as_value and returns true.
- /// On error (premature end of buffer, etc.) returns false and leaves
the given
- /// as_value untouched.
+ /// On error (premature end of buffer, etc.) returns false and
+ /// leaves the given as_value untouched.
///
- /// IF you pass a fourth parameter, it WILL NOT READ A TYPE BYTE, but
use what
- /// you passed instead.
+ /// IF you pass a fourth parameter, it WILL NOT READ A TYPE BYTE, but
+ /// use what you passed instead.
///
/// The l-value you pass as the first parameter (buffer start) is
updated to
/// point just past the last byte parsed
@@ -292,10 +274,7 @@
/// \brief
/// Return true if this value is callable
- /// (AS_FUNCTION).
- bool is_function() const {
- return m_type == AS_FUNCTION;
- }
+ bool is_function() const;
/// Return true if this value is strictly a string
//
@@ -323,10 +302,10 @@
/// \brief
/// Return true if this value is an object
- /// (OBJECT, AS_FUNCTION or MOVIECLIP).
+ /// (OBJECT, or MOVIECLIP).
bool is_object() const
{
- return m_type == OBJECT || m_type == AS_FUNCTION || m_type ==
MOVIECLIP;
+ return m_type == OBJECT || m_type == MOVIECLIP;
}
/// \brief
@@ -513,7 +492,7 @@
void set_nan() { set_double(NaN); }
- /// Make this value a NULL, OBJECT, MOVIECLIP or AS_FUNCTION value
+ /// Make this value a NULL, OBJECT, MOVIECLIP value
//
/// See as_object::to_movie and as_object::to_function
///
@@ -522,11 +501,6 @@
///
void set_as_object(as_object* obj);
- void set_as_object(boost::intrusive_ptr<as_object> obj);
-
- /// Make this a NULL or AS_FUNCTION value
- void set_as_function(as_function* func);
-
void set_undefined();
/// Set this value to the NULL value
@@ -543,7 +517,7 @@
bool is_exception() const {
return (m_type == UNDEFINED_EXCEPT || m_type == NULLTYPE_EXCEPT
|| m_type == BOOLEAN_EXCEPT || m_type == NUMBER_EXCEPT
- || m_type == OBJECT_EXCEPT || m_type == AS_FUNCTION_EXCEPT
+ || m_type == OBJECT_EXCEPT
|| m_type == MOVIECLIP_EXCEPT || m_type == STRING_EXCEPT);
}
@@ -618,14 +592,16 @@
/// 4. Object
/// 5. MovieClip
/// 6. String
- typedef boost::variant<boost::blank, double,
- bool, as_object*, CharacterProxy, std::string> AsValueType;
+ typedef boost::variant<boost::blank,
+ double,
+ bool,
+ as_object*,
+ CharacterProxy,
+ std::string>
+ AsValueType;
AsValueType _value;
- /// Get the function pointer variant member (we assume m_type ==
FUNCTION)
- as_function* getFun() const;
-
/// Get the object pointer variant member (we assume m_type == OBJECT)
as_object* getObj() const;
=== modified file 'libcore/asobj/Globals.cpp'
--- a/libcore/asobj/Globals.cpp 2009-11-30 16:49:34 +0000
+++ b/libcore/asobj/Globals.cpp 2009-12-01 11:02:43 +0000
@@ -163,42 +163,6 @@
template<typename T> as_object* constructObject(Global_as& gl, const T&
arg,
string_table::key className);
}
-
-AVM2Global::AVM2Global(abc::Machine& /*machine*/, VM& vm)
- :
- _classes(this, 0),
- _vm(vm),
- _objectProto(new as_object(*this))
-{
-}
-
-void
-AVM2Global::registerClasses()
-{
-
- const string_table::key NS_GLOBAL(0);
-
- initObjectClass(_objectProto, *this,
- ObjectURI(NSV::CLASS_OBJECT, NS_GLOBAL));
-
- function_class_init(*this, ObjectURI(NSV::CLASS_FUNCTION, NS_GLOBAL));
- string_class_init(*this, ObjectURI(NSV::CLASS_STRING, NS_GLOBAL));
- array_class_init(*this, ObjectURI(NSV::CLASS_ARRAY, NS_GLOBAL));
-
- init_member("trace", createFunction(global_trace));
- init_member("escape", createFunction(global_escape));
-
- _classes.declareAll(avm2Classes(_vm.getStringTable()));
- _classes.getGlobalNs()->stubPrototype(_classes, NSV::CLASS_FUNCTION);
- _classes.getGlobalNs()->getClass(NSV::CLASS_FUNCTION)->setDeclared();
- _classes.getGlobalNs()->stubPrototype(_classes, NSV::CLASS_OBJECT);
- _classes.getGlobalNs()->getClass(NSV::CLASS_OBJECT)->setDeclared();
- _classes.getGlobalNs()->stubPrototype(_classes, NSV::CLASS_ARRAY);
- _classes.getGlobalNs()->getClass(NSV::CLASS_ARRAY)->setDeclared();
- _classes.getGlobalNs()->stubPrototype(_classes, NSV::CLASS_STRING);
- _classes.getGlobalNs()->getClass(NSV::CLASS_STRING)->setDeclared();
-
-}
as_object*
AVM1Global::createObject()
@@ -285,67 +249,6 @@
{
return constructObject(*this, b, NSV::CLASS_BOOLEAN);
}
-
-as_object*
-AVM2Global::createObject()
-{
- as_object* obj = new as_object(*this);
- obj->set_prototype(_objectProto);
- return obj;
-}
-
-builtin_function*
-AVM2Global::createFunction(Global_as::ASFunction function)
-{
- builtin_function* f = new builtin_function(*this, function);
- f->init_member(NSV::PROP_CONSTRUCTOR,
- as_function::getFunctionConstructor());
- return f;
-}
-
-as_object*
-AVM2Global::createClass(Global_as::ASFunction ctor, as_object* prototype)
-{
- // TODO: this should attach the function to the prototype as its
- as_object* cl = new builtin_function(*this, ctor);
-
- if (prototype) {
- prototype->init_member(NSV::PROP_CONSTRUCTOR, cl);
- cl->init_member(NSV::PROP_PROTOTYPE, prototype);
- }
- return cl;
-}
-
-as_object*
-AVM2Global::createString(const std::string& s)
-{
- // What AVM2 does for createString is untested, so we do the same
- // as AVM1 for now.
- return constructObject(*this, s, NSV::CLASS_STRING);
-}
-
-as_object*
-AVM2Global::createNumber(double d)
-{
- return constructObject(*this, d, NSV::CLASS_NUMBER);
-}
-
-as_object*
-AVM2Global::createBoolean(bool b)
-{
- return constructObject(*this, b, NSV::CLASS_BOOLEAN);
-}
-
-/// This serves the purpose of hiding the Array_as type from the
-/// implementation, which at least enforces good behaviour from users.
-as_object*
-AVM2Global::createArray()
-{
- as_object* array = new as_object(*this);
- array->setArray();
- array->init_member(NSV::PROP_CONSTRUCTOR, getMember(NSV::CLASS_ARRAY));
- return array;
-}
void
AVM1Global::markReachableResources() const
@@ -430,20 +333,8 @@
case 7:
case 6:
- _classes.getGlobalNs()->stubPrototype(_classes,
- NSV::CLASS_FUNCTION);
-
- _classes.getGlobalNs()->getClass(
- NSV::CLASS_FUNCTION)->setDeclared();
-
case 5:
- _classes.getGlobalNs()->stubPrototype(_classes, NSV::CLASS_OBJECT);
- _classes.getGlobalNs()->getClass(NSV::CLASS_OBJECT)->setDeclared();
- _classes.getGlobalNs()->stubPrototype(_classes, NSV::CLASS_ARRAY);
- _classes.getGlobalNs()->getClass(NSV::CLASS_ARRAY)->setDeclared();
- _classes.getGlobalNs()->stubPrototype(_classes, NSV::CLASS_STRING);
-
_classes.getGlobalNs()->getClass(NSV::CLASS_STRING)->setDeclared();
// This is surely not correct, but they are not available
// in SWF4
init_member("escape", _vm.getNative(100, 0));
@@ -490,6 +381,107 @@
}
+#ifdef ENABLE_AVM2
+
+AVM2Global::AVM2Global(abc::Machine& /*machine*/, VM& vm)
+ :
+ _classes(this, 0),
+ _vm(vm),
+ _objectProto(new as_object(*this))
+{
+}
+
+void
+AVM2Global::registerClasses()
+{
+
+ const string_table::key NS_GLOBAL(0);
+
+ initObjectClass(_objectProto, *this,
+ ObjectURI(NSV::CLASS_OBJECT, NS_GLOBAL));
+
+ function_class_init(*this, ObjectURI(NSV::CLASS_FUNCTION, NS_GLOBAL));
+ string_class_init(*this, ObjectURI(NSV::CLASS_STRING, NS_GLOBAL));
+ array_class_init(*this, ObjectURI(NSV::CLASS_ARRAY, NS_GLOBAL));
+
+ init_member("trace", createFunction(global_trace));
+ init_member("escape", createFunction(global_escape));
+
+ _classes.declareAll(avm2Classes(_vm.getStringTable()));
+ _classes.getGlobalNs()->stubPrototype(_classes, NSV::CLASS_FUNCTION);
+ _classes.getGlobalNs()->getScript(NSV::CLASS_FUNCTION)->setDeclared();
+ _classes.getGlobalNs()->stubPrototype(_classes, NSV::CLASS_OBJECT);
+ _classes.getGlobalNs()->getScript(NSV::CLASS_OBJECT)->setDeclared();
+ _classes.getGlobalNs()->stubPrototype(_classes, NSV::CLASS_ARRAY);
+ _classes.getGlobalNs()->getScript(NSV::CLASS_ARRAY)->setDeclared();
+ _classes.getGlobalNs()->stubPrototype(_classes, NSV::CLASS_STRING);
+ _classes.getGlobalNs()->getScript(NSV::CLASS_STRING)->setDeclared();
+
+}
+
+as_object*
+AVM2Global::createObject()
+{
+ as_object* obj = new as_object(*this);
+ obj->set_prototype(_objectProto);
+ return obj;
+}
+
+builtin_function*
+AVM2Global::createFunction(Global_as::ASFunction function)
+{
+ builtin_function* f = new builtin_function(*this, function);
+ f->init_member(NSV::PROP_CONSTRUCTOR,
+ as_function::getFunctionConstructor());
+ return f;
+}
+
+as_object*
+AVM2Global::createClass(Global_as::ASFunction ctor, as_object* prototype)
+{
+ // TODO: this should attach the function to the prototype as its
+ as_object* cl = new builtin_function(*this, ctor);
+
+ if (prototype) {
+ prototype->init_member(NSV::PROP_CONSTRUCTOR, cl);
+ cl->init_member(NSV::PROP_PROTOTYPE, prototype);
+ }
+ return cl;
+}
+
+as_object*
+AVM2Global::createString(const std::string& s)
+{
+ // What AVM2 does for createString is untested, so we do the same
+ // as AVM1 for now.
+ return constructObject(*this, s, NSV::CLASS_STRING);
+}
+
+as_object*
+AVM2Global::createNumber(double d)
+{
+ return constructObject(*this, d, NSV::CLASS_NUMBER);
+}
+
+as_object*
+AVM2Global::createBoolean(bool b)
+{
+ return constructObject(*this, b, NSV::CLASS_BOOLEAN);
+}
+
+/// This serves the purpose of hiding the Array_as type from the
+/// implementation, which at least enforces good behaviour from users.
+as_object*
+AVM2Global::createArray()
+{
+ as_object* array = new as_object(*this);
+ array->setArray();
+ array->init_member(NSV::PROP_CONSTRUCTOR, getMember(NSV::CLASS_ARRAY));
+ return array;
+}
+
+#endif
+
namespace {
const ClassHierarchy::NativeClasses&
@@ -568,6 +560,8 @@
}
+#ifdef ENABLE_AVM2
+
const ClassHierarchy::NativeClasses&
avm2Classes(string_table& st)
{
@@ -709,10 +703,11 @@
(N(eventdispatcher_class_init, NSV::CLASS_EVENTDISPATCHER,
NSV::CLASS_OBJECT, NSV::NS_FLASH_EVENTS, 5));
-
return s;
}
+#endif
+
as_value
global_trace(const fn_call& fn)
{
@@ -1027,15 +1022,13 @@
global_asnative(const fn_call& fn)
{
- as_value ret;
-
if (fn.nargs < 2)
{
IF_VERBOSE_ASCODING_ERRORS(
log_aserror(_("ASNative(%s): needs at least two arguments"),
fn.dump_args());
)
- return ret;
+ return as_value();
}
const int sx = fn.arg(0).to_int();
@@ -1054,12 +1047,11 @@
VM& vm = getVM(fn);
as_function* fun = vm.getNative(x, y);
- if ( ! fun ) {
+ if (!fun) {
log_debug(_("No ASnative(%d, %d) registered with the VM"), x, y);
- return ret;
+ return as_value();
}
- ret.set_as_function(fun);
- return ret;
+ return as_value(fun);
}
=== modified file 'libcore/asobj/Globals.h'
--- a/libcore/asobj/Globals.h 2009-11-29 08:57:58 +0000
+++ b/libcore/asobj/Globals.h 2009-12-01 11:02:43 +0000
@@ -116,6 +116,8 @@
};
+#ifdef ENABLE_AVM2
+
class AVM2Global : public Global_as
{
public:
@@ -176,6 +178,8 @@
};
+#endif
+
} // namespace gnash
#endif
=== modified file 'libcore/asobj/Object.cpp'
--- a/libcore/asobj/Object.cpp 2009-11-30 13:44:18 +0000
+++ b/libcore/asobj/Object.cpp 2009-12-01 08:44:22 +0000
@@ -165,11 +165,7 @@
object_toString(const fn_call& fn)
{
as_object* obj = ensure<ValidThis>(fn);
-
- if (obj && obj->to_function()) {
- return as_value("[type Function]");
- }
- return as_value("[object Object]");
+ return as_value(obj->stringValue());
}
as_value
=== modified file 'libcore/debugger.cpp'
--- a/libcore/debugger.cpp 2009-10-23 06:25:25 +0000
+++ b/libcore/debugger.cpp 2009-12-01 08:51:26 +0000
@@ -700,7 +700,7 @@
// GNASH_REPORT_FUNCTION;
if (_symbols.size()) {
VM& vm = VM::get(); // cache this ?
- std::string namei = PROPNAME(name);
+ std::string namei = name;
std::map<void *, std::string>::const_iterator it;
for (it=_symbols.begin(); it != _symbols.end(); it++) {
if (it->second == namei) {
@@ -718,7 +718,7 @@
{
// GNASH_REPORT_FUNCTION;
VM& vm = VM::get(); // cache this ?
- std::string namei = PROPNAME(name);
+ std::string namei = name;
if (namei.size() > 1)
{
// log_debug ("Adding symbol %s at address: %p", namei, ptr);
=== modified file 'libcore/vm/ActionExec.cpp'
--- a/libcore/vm/ActionExec.cpp 2009-11-30 21:37:20 +0000
+++ b/libcore/vm/ActionExec.cpp 2009-12-01 08:51:26 +0000
@@ -676,14 +676,14 @@
ActionExec::delObjectMember(as_object& obj, const std::string& name)
{
string_table& st = getStringTable(env);
- std::pair<bool,bool> ret = obj.delProperty(st.find(PROPNAME(name)));
+ std::pair<bool,bool> ret = obj.delProperty(st.find(name));
return ret.second;
}
void
ActionExec::setVariable(const std::string& name, const as_value& val)
{
- return env.set_variable(PROPNAME(name), val, getScopeStack());
+ return env.set_variable(name, val, getScopeStack());
}
as_value
@@ -695,7 +695,7 @@
as_value
ActionExec::getVariable(const std::string& name, as_object** target)
{
- return env.get_variable(PROPNAME(name), getScopeStack(), target);
+ return env.get_variable(name, getScopeStack(), target);
}
void
@@ -703,11 +703,11 @@
{
if ( isFunction() ) {
// TODO: set local in the function object?
- env.set_local(PROPNAME(name), val);
+ env.set_local(name, val);
} else {
// TODO: set target member ?
// what about 'with' stack ?
- env.set_variable(PROPNAME(name), val, getScopeStack());
+ env.set_variable(name, val, getScopeStack());
}
}
=== modified file 'libcore/vm/Machine.cpp'
--- a/libcore/vm/Machine.cpp 2009-11-30 11:12:37 +0000
+++ b/libcore/vm/Machine.cpp 2009-12-01 11:02:43 +0000
@@ -136,8 +136,8 @@
}
}
-inline Class*
-pool_class(boost::uint32_t index, AbcBlock* pool)
+inline Script*
+pool_script(boost::uint32_t index, AbcBlock* pool)
{
if (!pool) throw ASException();
try {
@@ -360,8 +360,8 @@
void
Machine::push_scope_stack(as_value object)
{
- boost::intrusive_ptr<as_object> scopeObj = object.to_object(*_global);
- assert(scopeObj.get());
+ as_object* scopeObj = object.to_object(*_global);
+ assert(scopeObj);
log_abc("Pushing value %s onto scope stack.", object);
_scopeStack.push(scopeObj);
print_scope_stack();
@@ -1580,14 +1580,13 @@
as_value c = object->getMember(a.getGlobalName(), ns);
- // TODO: don't do this. Classes should not be functions;
+ // TODO: don't do this. Scriptes should not be functions;
// we should always use the constructor member, most
// likely.
- boost::intrusive_ptr<as_function> ctor = c.to_function();
+ as_function* ctor = c.to_function();
if (ctor) {
- boost::intrusive_ptr<as_object> newobj =
- constructInstance(*ctor, env, args);
+ as_object* newobj = constructInstance(*ctor, env,
args);
push_stack(as_value(newobj));
}
@@ -1698,8 +1697,8 @@
case SWF::ABC_ACTION_NEWCLASS:
{
boost::uint32_t cid = mStream->read_V32();
- log_abc("Class index: %s", cid);
- Class *c = pool_class(cid, mPoolObject);
+ log_abc("Script index: %s", cid);
+ Script* c = pool_script(cid, mPoolObject);
log_abc("Creating new class id=%u name=%s", c->getName(),
mST.value(c->getName()));
@@ -1915,9 +1914,7 @@
/// global -- The global scope object
case SWF::ABC_ACTION_GETGLOBALSCOPE:
{
- // TODO: Use get_scope_stack here.
- push_stack(as_value(_scopeStack.value(0).get()));
- //print_stack();
+ push_stack(_scopeStack.value(0));
break;
}
@@ -2901,7 +2898,7 @@
}
void
-Machine::getMember(Class* pDefinition, MultiName& name,
+Machine::getMember(Script* pDefinition, MultiName& name,
as_value& instance)
{
if (!instance.is_object())
@@ -2925,7 +2922,7 @@
}
void
-Machine::setMember(Class *pDefinition, MultiName& name, as_value& instance,
+Machine::setMember(Script *pDefinition, MultiName& name, as_value& instance,
as_value& newvalue)
{
if (!instance.is_object())
@@ -2982,20 +2979,20 @@
return size;
}
-Class *
+Script *
Machine::findSuper(as_value &v, bool find_for_primitive)
{
if (v.is_undefined() || v.is_null()) return NULL;
if (v.is_object()) {
- Class *pProto = NULL; // TODO:
v.to_object(*_global)->getClass();
+ Script *pProto = NULL; // TODO:
v.to_object(*_global)->getScript();
return pProto ? pProto->getSuper() : NULL;
}
if (!find_for_primitive) return 0;
if (v.is_number()) {
- return NULL; // TODO: _classes->getClass(NSV::CLASS_NUMBER);
+ return NULL; // TODO: _classes->getScript(NSV::CLASS_NUMBER);
}
// And so on...
@@ -3129,7 +3126,7 @@
{
mPoolObject = pool_block;
log_debug("Getting entry script.");
- Class* start_script = pool_block->scripts().back();
+ Script* start_script = pool_block->scripts().back();
log_debug("Getting constructor.");
Method* constructor = start_script->getConstructor();
clearRegisters(constructor->getMaxRegisters());
@@ -3205,7 +3202,7 @@
log_debug("instantiateClass: class name %s", className);
- Class* cl = mPoolObject->locateClass(className);
+ Script* cl = mPoolObject->locateScript(className);
if (!cl)
{
/// This seems like a big error.
@@ -3216,7 +3213,7 @@
Method* ctor = cl->getConstructor();
if (!ctor) {
- log_error("Class found has no constructor, can't instantiate "
+ log_error("Script found has no constructor, can't instantiate "
"class");
return;
}
@@ -3266,7 +3263,7 @@
for (size_t i = 0; i < _scopeStack.totalSize(); ++i)
{
- as_object* scope_object = _scopeStack.at(i).get();
+ as_object* scope_object = _scopeStack.at(i);
if (!scope_object) {
log_abc("Scope object is NULL.");
continue;
@@ -3308,7 +3305,7 @@
size_t totalSize = _scopeStack.totalSize();
for (unsigned int i = 0; i < totalSize; ++i) {
- ss << as_value(_scopeStack.at(i).get()).toDebugString();
+ ss << as_value(_scopeStack.at(i)).toDebugString();
}
log_abc("%s", ss.str());
}
=== modified file 'libcore/vm/Machine.h'
--- a/libcore/vm/Machine.h 2009-11-16 14:42:56 +0000
+++ b/libcore/vm/Machine.h 2009-12-01 11:02:43 +0000
@@ -23,7 +23,7 @@
#include <sstream>
#include "SafeStack.h"
#include "as_value.h"
-#include "Class.h"
+#include "Script.h"
#include "SWF.h"
#include "as_environment.h"
#include "VM.h"
@@ -120,7 +120,7 @@
///
/// @return
/// Null if the superclass was not found, or the superclass.
- Class* findSuper(as_value& obj, bool find_primitive);
+ Script* findSuper(as_value& obj, bool find_primitive);
/// Get a member from an object.
///
@@ -138,7 +138,7 @@
/// This returns the value, but on the stack.
/// (Since the return value is not known until after control has left
/// the caller of this, it's impossible to return a meaningful value.
- void getMember(Class* pDefinition, MultiName& name,
+ void getMember(Script* pDefinition, MultiName& name,
as_value& source);
/// Set a member in an object.
@@ -157,7 +157,7 @@
///
/// @return
/// Nothing.
- void setMember(Class*, MultiName&, as_value& target, as_value& val);
+ void setMember(Script*, MultiName&, as_value& target, as_value& val);
Binding* findProperty(MultiName&) { return NULL; }
@@ -330,15 +330,14 @@
void push_scope_stack(as_value object);
- boost::intrusive_ptr<as_object> pop_scope_stack() {
+ as_object* pop_scope_stack() {
log_abc("Popping value %s off the scope stack. There will be "
"%u items left.", as_value(_scopeStack.top(0)),
_scopeStack.size()-1);
return _scopeStack.pop();
}
- boost::intrusive_ptr<as_object> get_scope_stack(boost::uint8_t depth)
- const {
+ as_object* get_scope_stack(boost::uint8_t depth) const {
log_abc("Getting value from scope stack %u from the bottom.",
depth | 0x0);
return _scopeStack.value(depth);
@@ -356,7 +355,7 @@
/// before.
/// Most importantly, the complete stack is used for lookups, including
/// the section that is not changeable.
- SafeStack<boost::intrusive_ptr<as_object> > _scopeStack;
+ SafeStack<as_object*> _scopeStack;
CodeStream *mStream;
=== modified file 'testsuite/libcore.all/AsValueTest.cpp'
--- a/testsuite/libcore.all/AsValueTest.cpp 2009-11-04 15:06:07 +0000
+++ b/testsuite/libcore.all/AsValueTest.cpp 2009-12-01 09:30:50 +0000
@@ -287,8 +287,8 @@
if (ao1.get() == 0) {
runtest.unresolved("as_value(Element &prop1)");
} else {
- ao1.get()->get_member(st.find(PROPNAME("foo")), &fooas);
- ao1.get()->get_member(st.find(PROPNAME("bar")), &baras);
+ ao1.get()->get_member(st.find("foo"), &fooas);
+ ao1.get()->get_member(st.find("bar"), &baras);
if ((fooas.is_string()) && (fooas.to_string() ==
foo->to_string())) {
runtest.pass("as_value(Element prop1)");
} else {
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] /srv/bzr/gnash/trunk r11672: Separate AVM2 and AVM1 classes better.,
Benjamin Wolsey <=