[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] /srv/bzr/gnash/trunk r11679: Changes to as_value to make
From: |
Benjamin Wolsey |
Subject: |
[Gnash-commit] /srv/bzr/gnash/trunk r11679: Changes to as_value to make it less dependent on AS2. |
Date: |
Tue, 08 Dec 2009 14:14:24 +0100 |
User-agent: |
Bazaar (1.16.1) |
------------------------------------------------------------
revno: 11679 [merge]
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Tue 2009-12-08 14:14:24 +0100
message:
Changes to as_value to make it less dependent on AS2.
Cleanups and documentation for AS3.
modified:
libcore/TextField.cpp
libcore/abc/AbcBlock.cpp
libcore/abc/AbcBlock.h
libcore/abc/Class.cpp
libcore/abc/Class.h
libcore/as_object.cpp
libcore/as_value.cpp
libcore/as_value.h
libcore/asobj/Array_as.cpp
libcore/asobj/AsBroadcaster.cpp
libcore/asobj/Color_as.cpp
libcore/asobj/Date_as.cpp
libcore/asobj/Globals.cpp
libcore/asobj/LoadableObject.cpp
libcore/asobj/Number_as.cpp
libcore/asobj/Selection_as.cpp
libcore/asobj/String_as.cpp
libcore/asobj/flash/display/BitmapData_as.cpp
libcore/asobj/flash/display/MovieClip_as.cpp
libcore/asobj/flash/display/Stage_as.cpp
libcore/asobj/flash/filters/BevelFilter_as.cpp
libcore/asobj/flash/filters/BlurFilter_as.cpp
libcore/asobj/flash/filters/DropShadowFilter_as.cpp
libcore/asobj/flash/filters/GlowFilter_as.cpp
libcore/asobj/flash/filters/GradientBevelFilter_as.cpp
libcore/asobj/flash/filters/GradientGlowFilter_as.cpp
libcore/asobj/flash/geom/ColorTransform_as.cpp
libcore/asobj/flash/geom/Matrix_as.cpp
libcore/asobj/flash/geom/Point_as.cpp
libcore/asobj/flash/geom/Rectangle_as.cpp
libcore/asobj/flash/media/Microphone_as.cpp
libcore/asobj/flash/net/NetConnection_as.cpp
libcore/asobj/flash/net/SharedObject_as.cpp
libcore/asobj/flash/text/TextFormat_as.cpp
libcore/asobj/flash/text/TextSnapshot_as.cpp
libcore/asobj/flash/ui/Keyboard_as.cpp
libcore/asobj/flash/xml/XMLDocument_as.cpp
libcore/asobj/flash/xml/XMLNode_as.cpp
libcore/asobj/int_as.cpp
libcore/vm/ASHandlers.cpp
libcore/vm/Machine.cpp
libcore/vm/Machine.h
libcore/vm/VM.cpp
testsuite/libcore.all/AsValueTest.cpp
=== modified file 'libcore/TextField.cpp'
--- a/libcore/TextField.cpp 2009-12-04 09:20:14 +0000
+++ b/libcore/TextField.cpp 2009-12-08 08:47:03 +0000
@@ -2882,11 +2882,11 @@
}
const std::string& name = fn.arg(0).to_string();
- const int depth = fn.arg(1).to_int();
- const int x = fn.arg(2).to_int();
- const int y = fn.arg(3).to_int();
+ const int depth = toInt(fn.arg(1));
+ const int x = toInt(fn.arg(2));
+ const int y = toInt(fn.arg(3));
- int width = fn.arg(4).to_int();
+ int width = toInt(fn.arg(4));
if (width < 0) {
IF_VERBOSE_ASCODING_ERRORS(
log_aserror(_("createTextField: negative width (%d)"
@@ -2895,7 +2895,7 @@
width = -width;
}
- int height = fn.arg(5).to_int();
+ int height = toInt(fn.arg(5));
if ( height < 0 )
{
IF_VERBOSE_ASCODING_ERRORS(
@@ -2971,7 +2971,7 @@
}
else {
rgba newColor;
- newColor.parseRGB(static_cast<boost::uint32_t>(fn.arg(0).to_int()));
+ newColor.parseRGB(static_cast<boost::uint32_t>(toInt(fn.arg(0))));
ptr->setBackgroundColor(newColor);
}
@@ -3512,7 +3512,7 @@
return as_value(maxChars);
}
// Setter
- text->maxChars(fn.arg(0).to_int());
+ text->maxChars(toInt(fn.arg(0)));
return as_value();
}
@@ -3659,7 +3659,7 @@
return as_value();
}
- int userEnd = fn.arg(1).to_int();
+ int userEnd = toInt(fn.arg(1));
if ( userEnd < 0 )
{
IF_VERBOSE_ASCODING_ERRORS(
@@ -3670,13 +3670,13 @@
return as_value();
}
- wstring::size_type start = fn.arg(0).to_int();
+ wstring::size_type start = toInt(fn.arg(0));
wstring::size_type end = userEnd;
int version = getSWFVersion(fn);
// TODO: check if it's possible for SWF6 to use this function
- // and if it is whether to_string should be to_string_versioned
+ // and if it is whether to_string should be to_string
// (affects the way undefined values are considered)
const wstring& replacement =
utf8::decodeCanonicalString(fn.arg(2).to_string(), version);
=== modified file 'libcore/abc/AbcBlock.cpp'
--- a/libcore/abc/AbcBlock.cpp 2009-12-02 16:47:14 +0000
+++ b/libcore/abc/AbcBlock.cpp 2009-12-08 11:59:39 +0000
@@ -36,86 +36,86 @@
namespace abc {
bool
-Trait::finalize(AbcBlock *pBlock, abc::Class *pScript, bool do_static)
+Trait::finalize(AbcBlock *block, abc::Class* script, bool do_static)
{
log_abc("Finalize class %s (%s), trait kind: %s",
- pBlock->_stringTable->value(pScript->getName()), pScript, _kind);
+ block->_stringTable->value(script->getName()), script, _kind);
switch (_kind)
{
- case KIND_SLOT:
- case KIND_CONST:
- {
- // Validate the type.
- abc::Class *pType;
- if (_typeIndex) {
- log_abc("Trait type: %s",
- pBlock->_stringPool[
- pBlock->_multinamePool[_typeIndex].getABCName()]);
- pType =
pBlock->locateClass(pBlock->_multinamePool[_typeIndex]);
- }
- else {
- pType = pBlock->mTheObject;
- }
-
- if (!pType) {
- log_error(_("ABC: Finalizing trait yielded bad type for
slot."));
- return false;
- }
-
- // The name has been validated in read.
- // TODO: Find a better way to initialize trait values.
- if (!_hasValue) {
- as_object* null = 0;
- _value = null;
- }
-
- log_abc("Adding property=%s with value=%s slot=%u",
- pBlock->_stringPool[_name], _value, _slotID);
-
- pScript->addValue(_globalName, _namespace, _slotID, pType,
- _value, _kind == KIND_CONST, do_static);
- break;
- }
- case KIND_METHOD:
- {
- pScript->addMethod(_globalName, _namespace, _method, false);
- break;
- }
- case KIND_GETTER:
- {
- pScript->addGetter(_name, _namespace, _method, do_static);
- break;
- }
- case KIND_SETTER:
- {
- pScript->addSetter(_name, _namespace, _method, do_static);
- break;
- }
- case KIND_CLASS:
- {
- log_abc("Adding class %s, value %s, slot=%u",
- pBlock->_stringPool[_name], _value, _slotID);
-
- pScript->addMemberScript(_globalName, _namespace, _slotID,
- pBlock->_classes[_classInfoIndex], do_static);
- break;
- }
- case KIND_FUNCTION:
- {
- pScript->addSlotFunction(_name, _namespace, _slotID, _method,
do_static);
- break;
- }
- default:
- // Not here -- validated already in read.
- return false;
- break;
+ case KIND_SLOT:
+ case KIND_CONST:
+ {
+ // Validate the type.
+ abc::Class *type;
+ if (_typeIndex) {
+ log_abc("Trait type: %s",
+ block->_stringPool[
+ block->_multinamePool[_typeIndex].getABCName()]);
+ type = block->locateClass(block->_multinamePool[_typeIndex]);
+ }
+ else {
+ type = block->mTheObject;
+ }
+
+ if (!type) {
+ log_error(_("ABC: Finalizing trait yielded bad type for
slot."));
+ return false;
+ }
+
+ // The name has been validated in read.
+ // TODO: Find a better way to initialize trait values.
+ if (!_hasValue) {
+ as_object* null = 0;
+ _value = null;
+ }
+
+ log_abc("Adding property=%s with value=%s slot=%u",
+ block->_stringPool[_name], _value, _slotID);
+
+ script->addValue(_globalName, _namespace, _slotID, type,
+ _value, _kind == KIND_CONST, do_static);
+ break;
+ }
+ case KIND_METHOD:
+ {
+ script->addMethod(_globalName, _namespace, _method, false);
+ break;
+ }
+ case KIND_GETTER:
+ {
+ script->addGetter(_name, _namespace, _method, do_static);
+ break;
+ }
+ case KIND_SETTER:
+ {
+ script->addSetter(_name, _namespace, _method, do_static);
+ break;
+ }
+ case KIND_CLASS:
+ {
+ log_abc("Adding class %s, value %s, slot=%u",
+ block->_stringPool[_name], _value, _slotID);
+
+ script->addMemberScript(_globalName, _namespace, _slotID,
+ block->_classes[_classInfoIndex], do_static);
+ break;
+ }
+ case KIND_FUNCTION:
+ {
+ script->addSlotFunction(_name, _namespace, _slotID, _method,
do_static);
+ break;
+ }
+ default:
+ // Not here -- validated already in read.
+ return false;
+ break;
} // end of switch
return true;
}
bool
-Trait::finalize_mbody(AbcBlock *pBlock, Method *pMethod)
+Trait::finalize_mbody(AbcBlock *block, Method *pMethod)
{
log_abc("Finalizing method trait: kind %s", _kind);
switch (_kind)
@@ -124,15 +124,15 @@
case KIND_CONST:
{
// Validate the type.
- abc::Class *pType;
+ abc::Class *type;
if (_typeIndex) {
- pType =
pBlock->locateClass(pBlock->_multinamePool[_typeIndex]);
+ type =
block->locateClass(block->_multinamePool[_typeIndex]);
}
else {
- pType = pBlock->mTheObject;
+ type = block->mTheObject;
}
- if (!pType) {
+ if (!type) {
log_error(_("ABC: Finalizing trait yielded bad type for
slot."));
return false;
}
@@ -143,8 +143,8 @@
_value = as_value((as_object*)0); // NULL value, right ?
}
log_abc("Adding property=%s with value=%s slot=%u",
- pBlock->_stringPool[_name], _value.toDebugString(), _slotID);
- pMethod->addValue(_globalName, _namespace, _slotID, pType,
+ block->_stringPool[_name], _value.toDebugString(), _slotID);
+ pMethod->addValue(_globalName, _namespace, _slotID, type,
_value, _kind == KIND_CONST);
break;
}
@@ -166,7 +166,7 @@
case KIND_CLASS:
{
pMethod->addMemberScript(_name, _namespace, _slotID,
- pBlock->_classes[_classInfoIndex]);
+ block->_classes[_classInfoIndex]);
break;
}
case KIND_FUNCTION:
@@ -183,29 +183,29 @@
/// Read an AS3 'trait'
bool
-Trait::read(SWFStream* in, AbcBlock *pBlock)
+Trait::read(SWFStream* in, AbcBlock *block)
{
boost::uint32_t name = in->read_V32();
- if (name >= pBlock->_multinamePool.size())
+ if (name >= block->_multinamePool.size())
{
log_error(_("ABC: Bad name for trait."));
return false;
}
- if (!pBlock->_multinamePool[name].isQName())
+ if (!block->_multinamePool[name].isQName())
{
log_error(_("ABC: Trait name must be fully qualified."));
return false;
}
- MultiName multiname = pBlock->_multinamePool[name];
- _name = pBlock->_multinamePool[name].getABCName();
- _globalName = pBlock->_multinamePool[name].getGlobalName();
- _namespace = pBlock->_multinamePool[name].getNamespace();
+ MultiName multiname = block->_multinamePool[name];
+ _name = block->_multinamePool[name].getABCName();
+ _globalName = block->_multinamePool[name].getGlobalName();
+ _namespace = block->_multinamePool[name].getNamespace();
boost::uint8_t kind = in->read_u8();
_kind = static_cast<Kind>(kind & 0x0F);
log_abc("Trait name: %s, Trait kind: %s",
- pBlock->_stringPool[multiname.getABCName()], _kind);
+ block->_stringPool[multiname.getABCName()], _kind);
switch (_kind)
{
@@ -216,14 +216,14 @@
_typeIndex = in->read_V32();
boost::uint32_t vindex = in->read_V32();
log_abc("Slot ID=%u Type=%s Pool index=%u", _slotID,
- pBlock->_stringPool[
- pBlock->_multinamePool[_typeIndex].getABCName()], vindex);
+ block->_stringPool[
+ block->_multinamePool[_typeIndex].getABCName()], vindex);
if (vindex) {
const AbcBlock::PoolConstant c =
static_cast<AbcBlock::PoolConstant>(in->read_u8());
- if (!pBlock->pool_value(vindex, c, _value))
+ if (!block->pool_value(vindex, c, _value))
return false; // Message done by pool_value
_hasValue = true;
}
@@ -239,11 +239,11 @@
boost::uint32_t offset = in->read_V32();
log_abc("Method index=%u", offset);
- if (offset >= pBlock->_methods.size()) {
+ if (offset >= block->_methods.size()) {
log_error(_("Bad method id in trait."));
return false;
}
- _method = pBlock->_methods[offset];
+ _method = block->_methods[offset];
break;
}
case KIND_CLASS:
@@ -252,10 +252,10 @@
_classInfoIndex = in->read_V32();
log_abc("Slot id: %u Class index: %u Class Name: %s", _slotID,
_classInfoIndex,
- pBlock->_stringTable->value(
- pBlock->_classes[_classInfoIndex]->getName()));
+ block->_stringTable->value(
+ block->_classes[_classInfoIndex]->getName()));
- if (_classInfoIndex >= pBlock->_classes.size()) {
+ if (_classInfoIndex >= block->_classes.size()) {
log_error(_("Bad Class id in trait."));
return false;
}
@@ -265,11 +265,11 @@
{
_slotID = in->read_V32();
boost::uint32_t offset = in->read_V32();
- if (offset >= pBlock->_methods.size()) {
+ if (offset >= block->_methods.size()) {
log_error(_("Bad method id in trait."));
return false;
}
- _method = pBlock->_methods[offset];
+ _method = block->_methods[offset];
break;
}
default:
@@ -725,7 +725,7 @@
log_error(_("Action Block: Bad index in optional
argument."));
return false;
}
- v.set_int(_integerPool[index]);
+ v.set_double(_integerPool[index]);
break;
}
case POOL_UINTEGER:
@@ -735,7 +735,7 @@
log_error(_("Action Block: Bad index in optional
argument."));
return false;
}
- v.set_int(_uIntegerPool[index]);
+ v.set_double(_uIntegerPool[index]);
break;
}
case POOL_DOUBLE:
@@ -936,7 +936,6 @@
log_abc("There are %u instances.", count);
_classes.resize(count);
for (size_t i = 0; i < count; ++i) {
- abc::Class* pScript;
//Read multiname index.
boost::uint32_t index = _stream->read_V32();
// 0 is allowed as a name, typically for the last entry.
@@ -958,16 +957,16 @@
return false;
}
- pScript = locateClass(multiname);
+ abc::Class* cl = locateClass(multiname);
- if (!pScript) {
+ if (!cl) {
const string_table::key className = multiname.getGlobalName();
- pScript = mCH->newClass();
- pScript->setName(className);
+ cl = mCH->newClass();
+ cl->setName(className);
- if (!multiname.getNamespace()->addScript(className,
pScript)) {
+ if (!multiname.getNamespace()->addScript(className,
cl)) {
log_error(_("Duplicate class registration."));
return false;
@@ -980,8 +979,8 @@
multiname.getNamespace()->dump(*_stringTable);
}
- pScript->setDeclared();
- _classes[i] = pScript;
+ cl->setDeclared();
+ _classes[i] = cl;
boost::uint32_t super_index = _stream->read_V32();
if (super_index && super_index >= _multinamePool.size()) {
@@ -990,7 +989,7 @@
}
if (!super_index) {
- pScript->setSuper(mTheObject);
+ cl->setSuper(mTheObject);
}
else {
abc::Class *pSuper =
locateClass(_multinamePool[super_index]);
@@ -1013,25 +1012,25 @@
return false;
}
- if (pSuper == pScript)
+ if (pSuper == cl)
{
log_error(_("ABC: Class cannot be its own
supertype."));
return false;
}
- pScript->setSuper(pSuper);
+ cl->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, pScript, index,
+ "flags=%X", i, cl, index,
_stringPool[_multinamePool[index].getABCName()],
super_index, flags | 0x0);
- 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_SEALED) cl->setSealed();
+ if (flags & INSTANCE_FINAL) cl->setFinal();
+ if (flags & INSTANCE_INTERFACE) cl->setInterface();
+ if ((flags & 7) == INSTANCE_DYNAMIC) cl->setDynamic();
if (flags & INSTANCE_PROTECTED_NS) {
boost::uint32_t ns_index = _stream->read_V32();
@@ -1040,10 +1039,10 @@
return false;
}
// Set the protected namespace's parent, if it exists.
- if (pScript->getSuper()->hasProtectedNs())
+ if (cl->getSuper()->hasProtectedNs())
_namespacePool[ns_index]->setParent(
- pScript->getSuper()->getProtectedNs());
- pScript->setProtectedNs(_namespacePool[ns_index]);
+ cl->getSuper()->getProtectedNs());
+ cl->setProtectedNs(_namespacePool[ns_index]);
}
// This is the list of interfaces which the instances has
agreed to
@@ -1065,7 +1064,7 @@
log_error(_("ABC: Can't implement a
non-interface type."));
return false;
}
- pScript->pushInterface(pInterface);
+ cl->pushInterface(pInterface);
}
// The next thing should be the constructor.
@@ -1078,12 +1077,7 @@
return false;
}
// Don't validate for previous owner.
- 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(pScript);
+ cl->setConstructor(_methods[offset]);
// Next come the 'traits' of the instance. (The members.)
boost::uint32_t tcount = _stream->read_V32();
@@ -1091,7 +1085,7 @@
for (unsigned int j = 0; j < tcount; ++j)
{
Trait &aTrait = newTrait();
- aTrait.set_target(pScript, false);
+ aTrait.set_target(cl, false);
if (!aTrait.read(_stream, this))
return false;
}
@@ -1109,9 +1103,9 @@
log_abc("There are %u classes.", count);
for (size_t i = 0; i < count; ++i) {
- abc::Class* pScript = _classes[i];
+ abc::Class* cl = _classes[i];
boost::uint32_t offset = _stream->read_V32();
- log_abc("Class %u(%s) static constructor index=%u", i, pScript,
offset);
+ log_abc("Class %u(%s) static constructor index=%u", i, cl,
offset);
if (offset >= _methods.size()) {
log_error(_("ABC: Out of bound static constructor for
class."));
@@ -1119,18 +1113,13 @@
}
// Don't validate for previous owner.
- pScript->setStaticConstructor(_methods[offset]);
+ cl->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(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(pScript, true);
+ aTrait.set_target(cl, true);
if (!(aTrait.read(_stream, this)))
return false;
}
@@ -1144,42 +1133,41 @@
AbcBlock::read_scripts()
{
log_abc("Begin reading scripts.");
- boost::uint32_t count = _stream->read_V32();
- log_abc("There are %u scripts.", count);
- _scripts.resize(count);
- for (unsigned int i = 0; i < count; ++i)
- {
- abc::Class* pScript = mCH->newClass();
- _scripts[i] = pScript;
+
+ const boost::uint32_t scriptcount = _stream->read_V32();
+ log_abc("There are %u scripts.", scriptcount);
+
+ _scripts.resize(scriptcount);
+ for (size_t i = 0; i < scriptcount; ++i) {
+
+ abc::Class* script = mCH->newClass();
+ _scripts[i] = script;
boost::uint32_t offset = _stream->read_V32();
log_abc("Reading script %u(%s) initializer method index=%u", i,
- pScript, offset);
- if (offset >= _methods.size())
- {
+ script, offset);
+ if (offset >= _methods.size()) {
log_error(_("ABC: Out of bounds method for script."));
return false;
}
- pScript->setConstructor(_methods[offset]);
- pScript->setSuper(mTheObject);
+ script->setConstructor(_methods[offset]);
- boost::uint32_t tcount = _stream->read_V32();
- for (unsigned int j = 0; j < tcount; ++j)
- {
+ const boost::uint32_t tcount = _stream->read_V32();
+ for (size_t j = 0; j < tcount; ++j) {
- Trait &aTrait = newTrait();
- aTrait.set_target(pScript, false);
- if (!(aTrait.read(_stream, this))) {
+ Trait& trait = newTrait();
+ trait.set_target(script, false);
+ if (!(trait.read(_stream, this))) {
return false;
}
log_abc("Trait: %u name: %s(%u) kind: %s value: %s ",
j,
- _stringPool[aTrait._name], aTrait._name, aTrait._kind,
- aTrait._value.to_string());
+ _stringPool[trait._name], trait._name, trait._kind,
+ trait._value.to_string());
- pScript->_traits.push_back(aTrait);
+ script->_traits.push_back(trait);
}
- } // end of scripts loop
+ }
return true;
}
@@ -1232,14 +1220,14 @@
// Exception count and exceptions
const boost::uint32_t ecount = _stream->read_V32();
for (unsigned int j = 0; j < ecount; ++j) {
- asException *pExcept = mCH->newException();
+ asException *ex = mCH->newException();
// Where the try block begins and ends.
- pExcept->setStart(_stream->read_V32());
- pExcept->setEnd(_stream->read_V32());
+ ex->setStart(_stream->read_V32());
+ ex->setEnd(_stream->read_V32());
// Where to go when the exception is activated.
- pExcept->setCatch(_stream->read_V32());
+ ex->setCatch(_stream->read_V32());
// What types should be caught.
boost::uint32_t catch_type = _stream->read_V32();
@@ -1248,11 +1236,11 @@
return false;
}
if (!catch_type) {
- pExcept->catchAny();
+ ex->catchAny();
}
else {
- abc::Class *pType =
locateClass(_multinamePool[catch_type]);
- if (!pType) {
+ abc::Class *type =
locateClass(_multinamePool[catch_type]);
+ if (!type) {
log_error(_("ABC: Unknown type of
object to catch. (%s)"),
_stringTable->value(
@@ -1260,10 +1248,10 @@
// return false;
// Fake it, for now:
- pExcept->catchAny();
+ ex->catchAny();
}
else {
- pExcept->setCatchType(pType);
+ ex->setCatchType(type);
}
}
@@ -1276,8 +1264,8 @@
"exception."));
return false;
}
-
pExcept->setName(_multinamePool[cvn].getABCName());
-
pExcept->setNamespace(_multinamePool[cvn].getNamespace());
+ ex->setName(_multinamePool[cvn].getABCName());
+
ex->setNamespace(_multinamePool[cvn].getNamespace());
}
}
=== modified file 'libcore/abc/AbcBlock.h'
--- a/libcore/abc/AbcBlock.h 2009-12-02 15:57:58 +0000
+++ b/libcore/abc/AbcBlock.h 2009-12-08 11:59:39 +0000
@@ -51,7 +51,6 @@
{
public:
-
enum Kind
{
KIND_SLOT = 0,
@@ -63,25 +62,6 @@
KIND_FUNCTION = 5
};
- bool _hasValue;
- Kind _kind;
- boost::uint32_t _slotID;
- boost::uint32_t _typeIndex;
- boost::uint32_t _classInfoIndex;
- as_value _value;
-
- URI _name;
-
- string_table::key _globalName;
-
- Namespace* _namespace;
- Method* _method;
- bool _valueSet;
-
- abc::Class* _classTarget;
- Method* _methodTarget;
- bool _static;
-
Trait()
:
_hasValue(false),
@@ -100,29 +80,52 @@
_static(false)
{}
- bool read(SWFStream* in, AbcBlock *pBlock);
-
- bool finalize(AbcBlock* pBlock, abc::Class* pScript, bool do_static);
-
- bool finalize_mbody(AbcBlock* pBlock, Method* pMethod);
-
- void set_target(abc::Class* pScript, bool do_static) {
- _classTarget = pScript;
+ bool read(SWFStream* in, AbcBlock *block);
+
+ bool finalize(AbcBlock* block, abc::Class* cl, bool do_static);
+
+ bool finalize_mbody(AbcBlock* block, Method* m);
+
+ void set_target(abc::Class* cl, bool do_static) {
+ _classTarget = cl;
_static = do_static;
}
- void set_target(Method *pMethod) {
+ void set_target(Method *m) {
_classTarget = 0;
- _methodTarget = pMethod;
+ _methodTarget = m;
}
- bool finalize(AbcBlock* pBlock)
+ bool finalize(AbcBlock* block)
{
if (_classTarget) {
- return finalize(pBlock, _classTarget, _static);
+ return finalize(block, _classTarget, _static);
}
- return finalize_mbody(pBlock, _methodTarget);
+ return finalize_mbody(block, _methodTarget);
}
+
+private:
+
+ friend class AbcBlock;
+
+ bool _hasValue;
+ Kind _kind;
+ boost::uint32_t _slotID;
+ boost::uint32_t _typeIndex;
+ boost::uint32_t _classInfoIndex;
+ as_value _value;
+
+ URI _name;
+ string_table::key _globalName;
+
+ Namespace* _namespace;
+ Method* _method;
+ bool _valueSet;
+
+ abc::Class* _classTarget;
+ Method* _methodTarget;
+ bool _static;
+
};
/// Output stream operator for abc::Trait::Kind
@@ -237,7 +240,7 @@
abc::Class* locateClass(const std::string& className);
- abc::Trait &newTrait()
+ abc::Trait& newTrait()
{
abc::Trait *p = new abc::Trait;
_traits.push_back(p);
=== modified file 'libcore/abc/Class.cpp'
--- a/libcore/abc/Class.cpp 2009-12-04 10:56:27 +0000
+++ b/libcore/abc/Class.cpp 2009-12-08 11:59:39 +0000
@@ -29,15 +29,12 @@
#include "Global_as.h"
#include "as_class.h"
-#ifdef ENABLE_AVM2
#include "Method.h"
#include "abc_function.h"
-#endif
namespace gnash {
namespace abc {
-#ifdef ENABLE_AVM2
bool
Class::addValue(string_table::key name, Namespace *ns,
boost::uint32_t slotId, Class *type, as_value& val, bool isconst,
@@ -108,7 +105,7 @@
return true;
}
- bool
+bool
Class::addMethod(string_table::key name, Namespace* /*ns*/,
Method* method, bool /*isstatic*/)
{
@@ -129,13 +126,10 @@
Property *getset = _prototype->getOwnProperty(uri);
- if (getset)
- getset->setGetter(method->getPrototype());
- else
- {
+ if (getset) getset->setGetter(method->getPrototype());
+ else {
int flags = PropFlags::dontDelete | PropFlags::dontEnum;
- if (isstatic)
- flags |= PropFlags::staticProp;
+ if (isstatic) flags |= PropFlags::staticProp;
_prototype->init_property(uri, *method->getPrototype(),
*method->getPrototype(), flags);
}
@@ -151,8 +145,7 @@
Property *getset = _prototype->getOwnProperty(uri);
- if (getset)
- getset->setSetter(method->getPrototype());
+ if (getset) getset->setSetter(method->getPrototype());
else
{
int flags = PropFlags::dontDelete | PropFlags::dontEnum;
@@ -164,33 +157,6 @@
}
#if 0 // TODO
-void
-Class::buildFromPrototype(as_object *o, string_table::key name,
- ClassHierarchy *pCH)
-{
- setName(name);
- PropertyList *pList = &o->_members;
- PropertyList::iterator i = pList->begin();
-
- for ( ; i != pList->end(); ++i)
- {
- Property *pProp = i->second;
- fprintf(stderr, "Evaluating property %s.\n", STV(i->first));
- if (pProp->isDestructive())
- {
- fprintf(stderr, "%s is destructive.\n", STV(i->first));
- }
- if (pProp->isGetterSetter())
- {
- fprintf(stderr, "%s is a getset.\n", STV(i->first));
- }
- if (pProp->isReadOnly())
- {
- fprintf(stderr, "%s is read only.\n", STV(i->first));
- }
- }
-}
-
bool
Class::addValue(string_table::key name, Namespace *ns, boost::uint32_t slotId,
Class *type, as_value& val, bool isconst, bool isstatic,
@@ -245,7 +211,6 @@
}
#endif
-#endif
} // namespace abc
} // namespace gnash
=== modified file 'libcore/abc/Class.h'
--- a/libcore/abc/Class.h 2009-12-02 15:57:58 +0000
+++ b/libcore/abc/Class.h 2009-12-08 11:59:39 +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_ABC_SCRIPT_H
-#define GNASH_ABC_SCRIPT_H
+#ifndef GNASH_ABC_CLASS_H
+#define GNASH_ABC_CLASS_H
#ifdef HAVE_CONFIG_H
#include "gnashconfig.h"
@@ -30,11 +30,8 @@
#include "as_value.h"
#include "as_object.h"
#include "Property.h"
-
-#ifdef ENABLE_AVM2
-# include "CodeStream.h"
-# include "AbcBlock.h"
-#endif
+#include "CodeStream.h"
+#include "AbcBlock.h"
namespace gnash {
namespace abc {
@@ -45,7 +42,6 @@
class BoundAccessor;
class Method;
class Class;
- typedef Property Binding;
class Namespace;
}
class ClassHierarchy;
@@ -72,9 +68,16 @@
/// is constructed. As not all Classes are constructed, the iinit method
/// may never be executed.
//
+/// Classes are parsed from the "instances" and "classes" section of an
+/// ABCBlock. Each of these contains the same number of entries. The iinit
+/// methods are found in the instances section, the cinit methods in the
+/// classes section.
+//
+/// Note: the following does not describe very well how the data are organized
+/// in the ABC file.
/// A Script may contain more than one class. When a Script runs, the cinit
/// methods of all its classes are executed in the order they appear in the
-/// Script.
+/// Script.
class Class
{
public:
@@ -115,8 +118,6 @@
void dump();
-#ifdef ENABLE_AVM2
-
bool addValue(string_table::key name, Namespace *ns,
boost::uint32_t slotID, Class *type, as_value& val,
bool isconst, bool isstatic);
@@ -180,7 +181,7 @@
bool hasProtectedNs() const { return _protectedNs; }
/// Get the protected namespace.
- Namespace *getProtectedNs() { return _protectedNs; }
+ Namespace* getProtectedNs() { return _protectedNs; }
/// Set the protected namespace.
void setProtectedNs(Namespace *n) { _protectedNs = n; }
@@ -192,9 +193,13 @@
}
void initPrototype();
+
+ /// Retrieve the Class from which this Class derives.
+ Class* getSuper() const { return _super; }
- /// TODO: see if these are useful.
- Class* getSuper() const { return _super; }
+ /// Set the Super Class.
+ //
+ /// This is the base class for this Class.
void setSuper(Class *p) { _super = p; }
/// We implement this interface.
@@ -225,7 +230,7 @@
return _staticConstructor;
}
- Binding* getBinding(string_table::key name)
+ Property* getBinding(string_table::key name)
{
BindingContainer::iterator i;
if (_bindings.empty()) return NULL;
@@ -235,36 +240,31 @@
return &i->second;
}
- Binding* getGetBinding(as_value& v, abc::MultiName& n);
- Binding* getSetBinding(as_value& v, abc::MultiName& n);
+ Property* getGetBinding(as_value& v, abc::MultiName& n);
+ Property* getSetBinding(as_value& v, abc::MultiName& n);
std::vector<abc::Trait> _traits;
-#endif
-
private:
- typedef std::map<string_table::key, Binding> BindingContainer;
+ typedef std::map<string_table::key, Property> BindingContainer;
as_object *_prototype;
- bool addBinding(string_table::key name, const Binding& b) {
+ bool addBinding(string_table::key name, const Property& b) {
_bindings.insert(std::make_pair(name, b));
return true;
}
- bool addStaticBinding(string_table::key name, const Binding& b) {
+ bool addStaticBinding(string_table::key name, const Property& b) {
_staticBindings.insert(std::make_pair(name, b));
return true;
}
- Binding *getStaticBinding(string_table::key name)
+ Property *getStaticBinding(string_table::key name)
{
- BindingContainer::iterator i;
- if (_staticBindings.empty())
- return NULL;
- i = _staticBindings.find(name);
- if (i == _staticBindings.end())
- return NULL;
+ if (_staticBindings.empty()) return 0;
+ BindingContainer::iterator i = _staticBindings.find(name);
+ if (i == _staticBindings.end()) return 0;
return &i->second;
}
=== modified file 'libcore/as_object.cpp'
--- a/libcore/as_object.cpp 2009-12-04 09:20:14 +0000
+++ b/libcore/as_object.cpp 2009-12-08 08:47:03 +0000
@@ -263,7 +263,7 @@
bool accept(const ObjectURI& uri, const as_value& val) {
_to.push_front(std::make_pair(_st.value(getName(uri)),
- val.to_string_versioned(_version)));
+ val.to_string(_version)));
return true;
}
=== modified file 'libcore/as_value.cpp'
--- a/libcore/as_value.cpp 2009-12-02 14:27:13 +0000
+++ b/libcore/as_value.cpp 2009-12-08 09:47:55 +0000
@@ -21,11 +21,11 @@
#include "as_value.h"
#include "as_object.h"
#include "as_function.h" // for as_function
-#include "MovieClip.h" // for MOVIECLIP values
-#include "DisplayObject.h" // for MOVIECLIP values
-#include "as_environment.h" // for MOVIECLIP values
-#include "VM.h" // for MOVIECLIP values
-#include "movie_root.h" // for MOVIECLIP values
+#include "MovieClip.h" // for DISPLAYOBJECT values
+#include "DisplayObject.h" // for DISPLAYOBJECT values
+#include "as_environment.h" // for DISPLAYOBJECT values
+#include "VM.h" // for DISPLAYOBJECT values
+#include "movie_root.h" // for DISPLAYOBJECT values
#include "utility.h" // for typeName()
#include "GnashNumeric.h"
#include "namedStrings.h"
@@ -68,29 +68,11 @@
namespace {
-struct invalidHexDigit {};
-boost::uint8_t parseHex(char c)
+/// Returns a member only if it is an object.
+inline bool
+findMethod(as_object& obj, string_table::key m, as_value& ret)
{
- switch (c)
- {
- case '0': return 0;
- case '1': return 1;
- case '2': return 2;
- case '3': return 3;
- case '4': return 4;
- case '5': return 5;
- case '6': return 6;
- case '7': return 7;
- case '8': return 8;
- case '9': return 9;
- case 'a': case 'A': return 10;
- case 'b': case 'B': return 11;
- case 'c': case 'C': return 12;
- case 'd': case 'D': return 13;
- case 'e': case 'E': return 14;
- case 'f': case 'F': return 15;
- default: throw invalidHexDigit();
- }
+ return obj.get_member(m, &ret) && ret.is_object();
}
inline boost::uint16_t
@@ -114,8 +96,7 @@
boost::int32_t
truncateToInt(double d)
{
- if (d < 0)
- {
+ if (d < 0) {
return - static_cast<boost::uint32_t>(std::fmod(-d, 4294967296.0));
}
@@ -324,82 +305,45 @@
// Conversion to const std::string&.
std::string
-as_value::to_string() const
+as_value::to_string(int version) const
{
- switch (m_type)
+ switch (_type)
{
-
case STRING:
return getStr();
-
- case MOVIECLIP:
+ case DISPLAYOBJECT:
{
const CharacterProxy& sp = getCharacterProxy();
- if ( ! sp.get() )
- {
- return "";
- }
- else
- {
- return sp.getTarget();
- }
+ if (!sp.get()) return "";
+ return sp.getTarget();
}
-
case NUMBER:
- {
- double d = getNum();
- return doubleToString(d);
- }
-
+ return doubleToString(getNum());
case UNDEFINED:
-
- // Behavior depends on file version. In
- // version 7+, it's "undefined", in versions
- // 6-, it's "".
- //
- // We'll go with the v7 behavior by default,
- // and conditionalize via _versioned()
- // functions.
- //
+ if (version <= 6) return "";
return "undefined";
-
case NULLTYPE:
return "null";
-
case BOOLEAN:
- {
- bool b = getBool();
- return b ? "true" : "false";
- }
-
+ return getBool() ? "true" : "false";
case OBJECT:
{
as_object* obj = getObj();
String_as* s;
if (isNativeType(obj, s)) return s->value();
- try
- {
+ try {
as_value ret = to_primitive(STRING);
// This additional is_string test is NOT
compliant with ECMA-262
// specification, but seems required for
compatibility with the
// reference player.
-#if GNASH_DEBUG_CONVERSION_TO_PRIMITIVE
- log_debug(" %s.to_primitive(STRING) returned
%s", *this, ret);
-#endif
- if ( ret.is_string() ) return ret.to_string();
+ if (ret.is_string()) return ret.getStr();
}
- catch (ActionTypeError& e)
- {
-#if GNASH_DEBUG_CONVERSION_TO_PRIMITIVE
- log_debug(_("to_primitive(%s, STRING) threw an
ActionTypeError %s"),
- *this, e.what());
-#endif
+ catch (ActionTypeError& e) {
}
- if (m_type == OBJECT) {
- return is_function() ? "[type Function]" :
- "[type Object]";
+ if (_type == OBJECT) {
+ return is_function() ? "[type Function]" : "[type Object]";
}
}
@@ -410,87 +354,44 @@
}
-// Conversion to const std::string&.
-std::string
-as_value::to_string_versioned(int version) const
-{
- if (m_type == UNDEFINED)
- {
- // Version-dependent behavior.
- if (version <= 6)
- {
- return "";
- }
- return "undefined";
- }
-
- return to_string();
-}
-
/// This is only used in AVM2.
primitive_types
as_value::ptype() const
{
- switch (m_type)
+ switch (_type)
{
- case STRING: return PTYPE_STRING;
- case NUMBER: return PTYPE_NUMBER;
+ case STRING:
+ return PTYPE_STRING;
+ case NUMBER:
case UNDEFINED:
case NULLTYPE:
- case MOVIECLIP:
- return PTYPE_NUMBER;
+ case DISPLAYOBJECT:
case OBJECT:
- {
return PTYPE_NUMBER;
- }
case BOOLEAN:
return PTYPE_BOOLEAN;
default:
- break; // Should be only exceptions here.
- }
+ break;
+ }
return PTYPE_NUMBER;
}
-// Conversion to primitive value.
-as_value
-as_value::to_primitive() const
-{
- VM& vm = VM::get();
- int swfVersion = vm.getSWFVersion();
-
- AsType hint = NUMBER;
-
- if (m_type == OBJECT && swfVersion > 5) {
- Date_as* d;
- if (isNativeType(getObj(), d)) hint = STRING;
- }
-
- return to_primitive(hint);
-}
-
-as_value&
-as_value::convert_to_primitive()
-{
- VM& vm = VM::get();
- int swfVersion = vm.getSWFVersion();
-
- AsType hint = NUMBER;
-
- if (m_type == OBJECT && swfVersion > 5) {
- Date_as* d;
- if (isNativeType<Date_as>(getObj(), d)) hint = STRING;
- }
-
- *this = to_primitive(hint);
- return *this;
+as_value::AsType
+as_value::defaultPrimitive(int version) const
+{
+ if (_type == OBJECT && version > 5) {
+ Date_as* d;
+ if (isNativeType(getObj(), d)) return STRING;
+ }
+ return NUMBER;
}
// Conversion to primitive value.
as_value
as_value::to_primitive(AsType hint) const
{
- if (m_type != OBJECT) return *this;
+ if (_type != OBJECT) return *this;
#if GNASH_DEBUG_CONVERSION_TO_PRIMITIVE
log_debug("to_primitive(%s)", hint==NUMBER ? "NUMBER" : "STRING");
@@ -502,18 +403,10 @@
as_object* obj(0);
if (hint == NUMBER) {
-
- if (m_type == MOVIECLIP) return as_value(NaN);
-
- assert(m_type == OBJECT);
+ assert(_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
+ if (!findMethod(*obj, NSV::PROP_VALUE_OF, method)) {
// Returning undefined here instead of throwing
// a TypeError passes tests in actionscript.all/Object.as
// and many swfdec tests, with no new failures (though
@@ -523,34 +416,15 @@
}
else {
assert(hint == STRING);
-
- if (m_type == MOVIECLIP) return getCharacterProxy().getTarget();
- assert(m_type == OBJECT);
+ assert(_type == OBJECT);
obj = getObj();
// @@ Moock says, "the value that results from
// calling toString() on the object".
- //
- // When the toString() method doesn't exist, or
- // doesn't return a valid number, the default
- // 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 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 GNASH_DEBUG_CONVERSION_TO_PRIMITIVE
- log_debug(" valueOf not found");
-#endif
+ if (!findMethod(*obj, NSV::PROP_TO_STRING, method) &&
+ !findMethod(*obj, NSV::PROP_VALUE_OF, method)) {
throw ActionTypeError();
- }
- }
+ }
}
assert(obj);
@@ -558,57 +432,15 @@
as_environment env(getVM(*obj));
fn_call::Args args;
as_value ret = invoke(method, env, obj, args);
+
#if GNASH_DEBUG_CONVERSION_TO_PRIMITIVE
log_debug("to_primitive: method call returned %s", ret);
#endif
- if (ret.m_type == OBJECT)
- {
+
+ if (ret._type == OBJECT) {
throw ActionTypeError();
}
-
-
return ret;
-
-}
-
-bool
-as_value::parseNonDecimalInt(const std::string& s, double& d, bool whole)
-{
- const std::string::size_type slen = s.length();
-
- // "0#" would still be octal, but has the same value as a decimal.
- if (slen < 3) return false;
-
- bool negative = false;
-
- if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
- {
- // The only legitimate place for a '-' is after 0x. If it's a
- // '+' we don't care, as it won't disturb the conversion.
- std::string::size_type start = 2;
- if (s[2] == '-') {
- negative = true;
- ++start;
- }
- d = parsePositiveInt(s.substr(start), BASE_HEX, whole);
- if (negative) d = -d;
- return true;
- }
- else if ((s[0] == '0' || ((s[0] == '-' || s[0] == '+') && s[1] == '0')) &&
- s.find_first_not_of("01234567", 1) == std::string::npos)
- {
- std::string::size_type start = 0;
- if (s[0] == '-') {
- negative = true;
- ++start;
- }
- d = parsePositiveInt(s.substr(start), BASE_OCT, whole);
- if (negative) d = -d;
- return true;
- }
-
- return false;
-
}
double
@@ -617,7 +449,7 @@
const int swfversion = VM::get().getSWFVersion();
- switch (m_type)
+ switch (_type)
{
case STRING:
{
@@ -677,12 +509,10 @@
{
// Evan: from my tests
// Martin: FlashPlayer6 gives 0; FP9 gives NaN.
- return ( swfversion >= 7 ? NaN : 0 );
+ return (swfversion >= 7 ? NaN : 0);
}
case BOOLEAN:
- // Evan: from my tests
- // Martin: confirmed
return getBool() ? 1 : 0;
case NUMBER:
@@ -695,8 +525,7 @@
// method".
//
// Arrays and Movieclips should return NaN.
- try
- {
+ try {
as_value ret = to_primitive(NUMBER);
return ret.to_number();
}
@@ -714,7 +543,7 @@
}
}
- case MOVIECLIP:
+ case DISPLAYOBJECT:
{
// This is tested, no valueOf is going
// to be invoked for movieclips.
@@ -735,7 +564,7 @@
boost::shared_ptr<amf::Element> el ( new amf::Element );
as_object* ptr = to_object(*vm.getGlobal());
- switch (m_type) {
+ switch (_type) {
case UNDEFINED:
el->makeUndefined();
break;
@@ -759,9 +588,8 @@
ptr->visitProperties<Exists>(props);
break;
}
- case MOVIECLIP:
+ case DISPLAYOBJECT:
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 ?
break;
default:
break;
@@ -770,92 +598,22 @@
return el;
}
-// This returns an as_value as an integer. It is
-// probably used for most implicit conversions to
-// int, for instance in the String class.
-boost::int32_t
-as_value::to_int() const
-{
- double d = to_number();
-
- if (!isFinite(d)) return 0;
-
- return truncateToInt(d);
-}
-
-// Conversion to boolean for SWF7 and up
-bool
-as_value::to_bool_v7() const
-{
- switch (m_type)
- {
- case STRING:
- return getStr() != "";
- case NUMBER:
- {
- double d = getNum();
- return d && ! isNaN(d);
- }
- case BOOLEAN:
- return getBool();
- case OBJECT:
- return true;
-
- case MOVIECLIP:
- return true;
- default:
- assert(m_type == UNDEFINED || m_type == NULLTYPE ||
- is_exception());
- return false;
- }
-}
-
-// Conversion to boolean up to SWF5
-bool
-as_value::to_bool_v5() const
-{
- switch (m_type)
- {
- case STRING:
- {
- double num = to_number();
- bool ret = num && ! isNaN(num);
- return ret;
- }
- case NUMBER:
- {
- double d = getNum();
- return d && ! isNaN(d);
- }
- case BOOLEAN:
- return getBool();
- case OBJECT:
- return true;
-
- case MOVIECLIP:
- return true;
- default:
- assert(m_type == UNDEFINED || m_type == NULLTYPE ||
- is_exception());
- return false;
- }
-}
-
-// Conversion to boolean for SWF6
-bool
-as_value::to_bool_v6() const
-{
- switch (m_type)
- {
- case STRING:
- {
- double num = to_number();
- bool ret = num && ! isNaN(num);
- return ret;
- }
- case NUMBER:
- {
- double d = getNum();
+// Conversion to boolean
+bool
+as_value::to_bool() const
+{
+ const int version = VM::get().getSWFVersion();
+ switch (_type)
+ {
+ case STRING:
+ {
+ if (version >= 7) return !getStr().empty();
+ const double num = to_number();
+ return num && !isNaN(num);
+ }
+ case NUMBER:
+ {
+ const double d = getNum();
// see testsuite/swfdec/if-6.swf
return d && ! isNaN(d);
}
@@ -863,36 +621,24 @@
return getBool();
case OBJECT:
return true;
-
- case MOVIECLIP:
+ case DISPLAYOBJECT:
return true;
default:
- assert(m_type == UNDEFINED || m_type == NULLTYPE ||
- is_exception());
+ assert(_type == UNDEFINED || _type == NULLTYPE ||
is_exception());
return false;
}
}
-// Conversion to boolean.
-bool
-as_value::to_bool() const
-{
- int ver = VM::get().getSWFVersion();
- if ( ver >= 7 ) return to_bool_v7();
- else if ( ver == 6 ) return to_bool_v6();
- else return to_bool_v5();
-}
-
// Return value as an object.
as_object*
as_value::to_object(Global_as& global) const
{
- switch (m_type)
+ switch (_type)
{
case OBJECT:
return getObj();
- case MOVIECLIP:
+ case DISPLAYOBJECT:
return getObject(toDisplayObject());
case STRING:
@@ -911,9 +657,9 @@
}
MovieClip*
-as_value::to_sprite(bool allowUnloaded) const
+as_value::toMovieClip(bool allowUnloaded) const
{
- if ( m_type != MOVIECLIP ) return 0;
+ if ( _type != DISPLAYOBJECT ) return 0;
DisplayObject *ch = getCharacter(allowUnloaded);
if ( ! ch ) return 0;
@@ -923,24 +669,16 @@
DisplayObject*
as_value::toDisplayObject(bool allowUnloaded) const
{
- if ( m_type != MOVIECLIP ) return NULL;
-
+ if (_type != DISPLAYOBJECT) return NULL;
return getCharacter(allowUnloaded);
}
-void
-as_value::setDisplayObject(DisplayObject& sprite)
-{
- m_type = MOVIECLIP;
- _value = CharacterProxy(&sprite);
-}
-
// Return value as an ActionScript function. Returns NULL if value is
// not an ActionScript function.
as_function*
as_value::to_function() const
{
- if (m_type == OBJECT) {
+ if (_type == OBJECT) {
return getObj()->to_function();
}
@@ -950,14 +688,14 @@
void
as_value::set_undefined()
{
- m_type = UNDEFINED;
+ _type = UNDEFINED;
_value = boost::blank();
}
void
as_value::set_null()
{
- m_type = NULLTYPE;
+ _type = NULLTYPE;
_value = boost::blank();
}
@@ -972,12 +710,13 @@
if (obj->displayObject()) {
// The static cast is fine as long as the as_object is genuinely
// a DisplayObject.
- setDisplayObject(*obj->displayObject());
+ _type = DISPLAYOBJECT;
+ _value = CharacterProxy(obj->displayObject());
return;
}
- if (m_type != OBJECT || getObj() != obj) {
- m_type = OBJECT;
+ if (_type != OBJECT || getObj() != obj) {
+ _type = OBJECT;
_value = obj;
}
}
@@ -987,138 +726,110 @@
{
// Comments starting with numbers refer to the ECMA-262 document
-#ifdef GNASH_DEBUG_EQUALITY
- static int count=0;
- log_debug("equals(%s, %s) called [%d]", *this, v, count++);
-#endif
-
int SWFVersion = VM::get().getSWFVersion();
- bool this_nulltype = (m_type == UNDEFINED || m_type == NULLTYPE);
- bool v_nulltype = (v.m_type == UNDEFINED || v.m_type == NULLTYPE);
+ bool this_nulltype = (_type == UNDEFINED || _type == NULLTYPE);
+ bool v_nulltype = (v._type == UNDEFINED || v._type == NULLTYPE);
// It seems like functions are considered the same as a NULL type
// in SWF5 (and I hope below, didn't check)
- //
- if ( SWFVersion < 6 )
- {
+ if (SWFVersion < 6) {
if (is_function()) this_nulltype = true;
if (v.is_function()) v_nulltype = true;
}
- if (this_nulltype || v_nulltype)
- {
+ if (this_nulltype || v_nulltype) {
#ifdef GNASH_DEBUG_EQUALITY
log_debug(" one of the two things is undefined or null");
#endif
return this_nulltype == v_nulltype;
}
- bool obj_or_func = (m_type == OBJECT);
- bool v_obj_or_func = (v.m_type == OBJECT);
+ bool obj_or_func = (_type == OBJECT);
+ bool v_obj_or_func = (v._type == OBJECT);
/// Compare to same type
- if ( obj_or_func && v_obj_or_func )
- {
- return boost::get<as_object*>(_value) ==
boost::get<as_object*>(v._value);
+ if (obj_or_func && v_obj_or_func) {
+ return boost::get<as_object*>(_value) ==
+ boost::get<as_object*>(v._value);
}
- if ( m_type == v.m_type ) return equalsSameType(v);
+ if (_type == v._type) return equalsSameType(v);
// 16. If Type(x) is Number and Type(y) is String,
// return the result of the comparison x == ToNumber(y).
- if (m_type == NUMBER && v.m_type == STRING)
- {
- double n = v.to_number();
+ if (_type == NUMBER && v._type == STRING) {
+ const double n = v.to_number();
if (!isFinite(n)) return false;
return equalsSameType(n);
}
// 17. If Type(x) is String and Type(y) is Number,
// return the result of the comparison ToNumber(x) == y.
- if (v.m_type == NUMBER && m_type == STRING)
- {
- double n = to_number();
+ if (v._type == NUMBER && _type == STRING) {
+ const double n = to_number();
if (!isFinite(n)) return false;
return v.equalsSameType(n);
}
// 18. If Type(x) is Boolean, return the result of the comparison
ToNumber(x) == y.
- if (m_type == BOOLEAN)
- {
+ if (_type == BOOLEAN) {
return as_value(to_number()).equals(v);
}
// 19. If Type(y) is Boolean, return the result of the comparison x ==
ToNumber(y).
- if (v.m_type == BOOLEAN)
- {
+ if (v._type == BOOLEAN) {
return as_value(v.to_number()).equals(*this);
}
// 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))
+ if ((_type == STRING || _type == NUMBER) && (v._type == OBJECT))
{
// convert this value to a primitive and recurse
- try
- {
- as_value v2 = v.to_primitive();
- if ( v.strictly_equals(v2) ) return false;
-
-#ifdef GNASH_DEBUG_EQUALITY
- log_debug(" 20: convertion to primitive : %s -> %s", v, v2);
-#endif
-
- return equals(v2);
- }
- catch (ActionTypeError& e)
- {
-#ifdef GNASH_DEBUG_EQUALITY
- log_debug(" %s.to_primitive() threw an ActionTypeError %s", v,
e.what());
-#endif
- return false; // no valid conversion
- }
-
+ try {
+ as_value v2 = v.to_primitive(v.defaultPrimitive(SWFVersion));
+ if (v.strictly_equals(v2)) return false;
+#ifdef GNASH_DEBUG_EQUALITY
+ log_debug(" 20: convertion to primitive : %s -> %s", v, v2);
+#endif
+ return equals(v2);
+ }
+ catch (ActionTypeError& e) {
+#ifdef GNASH_DEBUG_EQUALITY
+ log_debug(" %s.to_primitive() threw an ActionTypeError %s", v,
+ e.what());
+#endif
+ return false;
+ }
}
// 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))
- {
+ if ((v._type == STRING || v._type == NUMBER) && (_type == OBJECT)) {
// convert this value to a primitive and recurse
- try
- {
+ try {
// Date objects default to primitive type STRING from SWF6 up,
// but we always prefer valueOf to toString in this case.
as_value v2 = to_primitive(NUMBER);
- if ( strictly_equals(v2) ) return false;
-
+ if (strictly_equals(v2)) return false;
#ifdef GNASH_DEBUG_EQUALITY
log_debug(" 21: convertion to primitive : %s -> %s", *this, v2);
#endif
-
return v2.equals(v);
}
- catch (ActionTypeError& e)
- {
-
+ catch (ActionTypeError& e) {
#ifdef GNASH_DEBUG_EQUALITY
log_debug(" %s.to_primitive() threw an ActionTypeError %s",
*this, e.what());
#endif
-
- return false; // no valid conversion
+ return false;
}
-
}
-
#ifdef GNASH_DEBUG_EQUALITY
- // Both operands are objects (OBJECT,AS_FUNCTION,MOVIECLIP)
- if ( ! is_object() || ! v.is_object() )
- {
+ // Both operands are objects (OBJECT,DISPLAYOBJECT)
+ if (!is_object() || !v.is_object()) {
log_debug("Equals(%s,%s)", *this, v);
}
#endif
@@ -1128,48 +839,44 @@
as_value p = *this;
as_value vp = v;
- int converted = 0;
- try
- {
- p = to_primitive();
- if ( ! strictly_equals(p) ) ++converted;
+ bool converted(false);
+
+ try {
+ p = to_primitive(p.defaultPrimitive(SWFVersion));
+ if (!strictly_equals(p)) converted = true;
#ifdef GNASH_DEBUG_EQUALITY
- log_debug(" convertion to primitive (this): %s -> %s", *this,
p);
+ log_debug(" conversion to primitive (this): %s -> %s", *this,
p);
#endif
}
- catch (ActionTypeError& e)
- {
+ catch (ActionTypeError& e) {
#ifdef GNASH_DEBUG_CONVERSION_TO_PRIMITIVE
log_debug(" %s.to_primitive() threw an ActionTypeError %s",
*this, e.what());
#endif
}
- try
- {
- vp = v.to_primitive();
- if ( ! v.strictly_equals(vp) ) ++converted;
+ try {
+ vp = v.to_primitive(v.defaultPrimitive(SWFVersion));
+ if (!v.strictly_equals(vp)) converted = true;
#ifdef GNASH_DEBUG_EQUALITY
- log_debug(" convertion to primitive (that): %s -> %s", v, vp);
+ log_debug(" conversion to primitive (that): %s -> %s", v, vp);
#endif
}
- catch (ActionTypeError& e)
- {
+ catch (ActionTypeError& e) {
#ifdef GNASH_DEBUG_CONVERSION_TO_PRIMITIVE
log_debug(" %s.to_primitive() threw an ActionTypeError %s",
v, e.what());
#endif
}
- if ( converted )
+ if (converted)
{
#ifdef GNASH_DEBUG_EQUALITY
- log_debug(" some conversion took place, recurring");
+ log_debug(" some conversion took place, recursing");
#endif
return p.equals(vp);
}
- else
- {
+ else {
#ifdef GNASH_DEBUG_EQUALITY
log_debug(" no conversion took place, returning false");
#endif
@@ -1179,36 +886,27 @@
}
-// Sets *this to this string plus the given string.
-void
-as_value::string_concat(const std::string& str)
-{
- std::string currVal = to_string();
- m_type = STRING;
- _value = currVal + str;
-}
-
const char*
as_value::typeOf() const
{
- switch(m_type)
+ switch (_type)
{
- case as_value::UNDEFINED:
+ case UNDEFINED:
return "undefined";
- case as_value::STRING:
+ case STRING:
return "string";
- case as_value::NUMBER:
+ case NUMBER:
return "number";
- case as_value::BOOLEAN:
+ case BOOLEAN:
return "boolean";
- case as_value::OBJECT:
+ case OBJECT:
return is_function() ? "function" : "object";
- case as_value::MOVIECLIP:
+ case DISPLAYOBJECT:
{
DisplayObject* ch = getCharacter();
if ( ! ch ) return "movieclip"; // dangling
@@ -1216,29 +914,22 @@
return "object"; // bound to some other DisplayObject
}
- case as_value::NULLTYPE:
+ case NULLTYPE:
return "null";
default:
- if (is_exception())
- {
- return "exception";
- }
- abort();
- return NULL;
+ if (is_exception()) return "exception";
+ std::abort();
+ return 0;
}
}
-/*private*/
bool
as_value::equalsSameType(const as_value& v) const
{
-#ifdef GNASH_DEBUG_EQUALITY
- static int count=0;
- log_debug("equalsSameType(%s, %s) called [%d]", *this, v, count++);
-#endif
- assert(m_type == v.m_type);
- switch (m_type)
+ assert(_type == v._type);
+
+ switch (_type)
{
case UNDEFINED:
case NULLTYPE:
@@ -1249,39 +940,28 @@
case STRING:
return _value == v._value;
- case MOVIECLIP:
+ case DISPLAYOBJECT:
return toDisplayObject() == v.toDisplayObject();
case NUMBER:
{
- double a = getNum();
- double b = v.getNum();
-
- // Nan != NaN
- //if ( isNaN(a) || isNaN(b) ) return false;
-
- if ( isNaN(a) && isNaN(b) ) return true;
-
- // -0.0 == 0.0
- if ( (a == -0 && b == 0) || (a == 0 && b == -0) )
return true;
-
+ const double a = getNum();
+ const double b = v.getNum();
+ if (isNaN(a) && isNaN(b)) return true;
return a == b;
}
default:
- if (is_exception())
- {
- return false; // Exceptions equal nothing.
- }
+ if (is_exception()) return false;
}
- abort();
+ std::abort();
return false;
}
bool
as_value::strictly_equals(const as_value& v) const
{
- if ( m_type != v.m_type ) return false;
+ if ( _type != v._type ) return false;
return equalsSameType(v);
}
@@ -1290,7 +970,7 @@
{
boost::format ret;
- switch (m_type)
+ switch (_type)
{
case UNDEFINED:
return "[undefined]";
@@ -1302,7 +982,8 @@
case OBJECT:
{
as_object* obj = getObj();
- ret = boost::format("[object(%s):%p]") % typeName(*obj)
% static_cast<void*>(obj);
+ ret = boost::format("[object(%s):%p]") % typeName(*obj)
%
+ static_cast<void*>(obj);
return ret.str();
}
case STRING:
@@ -1313,26 +994,22 @@
stream << getNum();
return "[number:" + stream.str() + "]";
}
- case MOVIECLIP:
+ case DISPLAYOBJECT:
{
const CharacterProxy& sp = getCharacterProxy();
- if ( sp.isDangling() )
- {
+ if (sp.isDangling()) {
DisplayObject* rebound = sp.get();
- if ( rebound )
- {
+ if (rebound) {
ret = boost::format("[rebound %s(%s):%p]")
%
typeName(*rebound) %
sp.getTarget() %
static_cast<void*>(rebound);
}
- else
- {
+ else {
ret = boost::format("[dangling
DisplayObject:%s]") %
sp.getTarget();
}
}
- else
- {
+ else {
DisplayObject* ch = sp.get();
ret = boost::format("[%s(%s):%p]") %
typeName(*ch) %
sp.getTarget() %
static_cast<void*>(ch);
@@ -1340,141 +1017,30 @@
return ret.str();
}
default:
- if (is_exception())
- {
- return "[exception]";
- }
- abort();
+ if (is_exception()) return "[exception]";
+ std::abort();
}
}
void
as_value::operator=(const as_value& v)
{
- m_type = v.m_type;
+ _type = v._type;
_value = v._value;
}
-/// Examples:
-//
-/// e.g. for 9*.1234567890123456789:
-/// 9999.12345678901
-/// 99999.123456789
-/// 999999.123456789
-/// 9999999.12345679
-/// [...]
-/// 999999999999.123
-/// 9999999999999.12
-/// 99999999999999.1
-/// 999999999999999
-/// 1e+16
-/// 1e+17
-//
-/// For 1*.111111111111111111111111111111111111:
-/// 1111111111111.11
-/// 11111111111111.1
-/// 111111111111111
-/// 1.11111111111111e+15
-/// 1.11111111111111e+16
-//
-/// For 1.234567890123456789 * 10^-i:
-/// 1.23456789012346
-/// 0.123456789012346
-/// 0.0123456789012346
-/// 0.00123456789012346
-/// 0.000123456789012346
-/// 0.0000123456789012346
-/// 0.00000123456789012346
-/// 1.23456789012346e-6
-/// 1.23456789012346e-7
-std::string
-as_value::doubleToString(double val, int radix)
-{
- // Handle non-numeric values.
- if (isNaN(val)) return "NaN";
-
- if (isInf(val)) return val < 0 ? "-Infinity" : "Infinity";
-
- if (val == 0.0 || val == -0.0) return "0";
-
- std::ostringstream ostr;
-
- if (radix == 10)
- {
- // ActionScript always expects dot as decimal point.
- ostr.imbue(std::locale::classic());
-
- // force to decimal notation for this range (because the
- // reference player does)
- if (std::abs(val) < 0.0001 && std::abs(val) >= 0.00001)
- {
- // All nineteen digits (4 zeros + up to 15 significant
digits)
- ostr << std::fixed << std::setprecision(19) << val;
-
- std::string str = ostr.str();
-
- // Because 'fixed' also adds trailing zeros, remove
them.
- std::string::size_type pos = str.find_last_not_of('0');
- if (pos != std::string::npos) {
- str.erase(pos + 1);
- }
- return str;
- }
-
- ostr << std::setprecision(15) << val;
-
- std::string str = ostr.str();
-
- // Remove a leading zero from 2-digit exponent if any
- std::string::size_type pos = str.find("e", 0);
-
- if (pos != std::string::npos && str.at(pos + 2) == '0') {
- str.erase(pos + 2, 1);
- }
-
- return str;
- }
-
- // Radix isn't 10
- bool negative = (val < 0);
- if (negative) val = -val;
-
- double left = std::floor(val);
- if (left < 1) return "0";
-
- std::string str;
- const std::string digits = "0123456789abcdefghijklmnopqrstuvwxyz";
-
- // Construct the string backwards for speed, then reverse.
- while (left)
- {
- double n = left;
- left = std::floor(left / radix);
- n -= (left * radix);
- str.push_back(digits[static_cast<int>(n)]);
- }
- if (negative) str.push_back('-');
-
- std::reverse(str.begin(), str.end());
-
- return str;
-
-}
-
void
as_value::setReachable() const
{
-#ifdef GNASH_USE_GC
- switch (m_type)
+ switch (_type)
{
case OBJECT:
{
as_object* op = getObj();
- if (op)
- op->setReachable();
+ if (op) op->setReachable();
break;
}
- case MOVIECLIP:
+ case DISPLAYOBJECT:
{
CharacterProxy sp = getCharacterProxy();
sp.setReachable();
@@ -1482,24 +1048,23 @@
}
default: break;
}
-#endif // GNASH_USE_GC
}
as_object*
as_value::getObj() const
{
- assert(m_type == OBJECT);
+ assert(_type == OBJECT);
return boost::get<as_object*>(_value);
}
CharacterProxy
as_value::getCharacterProxy() const
{
- assert(m_type == MOVIECLIP);
+ assert(_type == DISPLAYOBJECT);
return boost::get<CharacterProxy>(_value);
}
-as_value::CharacterPtr
+DisplayObject*
as_value::getCharacter(bool allowUnloaded) const
{
return getCharacterProxy().get(allowUnloaded);
@@ -1508,62 +1073,62 @@
void
as_value::set_string(const std::string& str)
{
- m_type = STRING;
+ _type = STRING;
_value = str;
}
void
as_value::set_double(double val)
{
- m_type = NUMBER;
+ _type = NUMBER;
_value = val;
}
void
as_value::set_bool(bool val)
{
- m_type = BOOLEAN;
+ _type = BOOLEAN;
_value = val;
}
as_value::as_value()
:
- m_type(UNDEFINED),
+ _type(UNDEFINED),
_value(boost::blank())
{
}
as_value::as_value(const as_value& v)
:
- m_type(v.m_type),
+ _type(v._type),
_value(v._value)
{
}
as_value::as_value(const char* str)
:
- m_type(STRING),
+ _type(STRING),
_value(std::string(str))
{
}
as_value::as_value(const std::string& str)
:
- m_type(STRING),
+ _type(STRING),
_value(str)
{
}
as_value::as_value(double num)
:
- m_type(NUMBER),
+ _type(NUMBER),
_value(num)
{
}
as_value::as_value(as_object* obj)
:
- m_type(UNDEFINED)
+ _type(UNDEFINED)
{
set_as_object(obj);
}
@@ -1571,212 +1136,7 @@
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)
-{
-
- VM& vm = VM::get();
- string_table& st = vm.getStringTable();
- Global_as& gl = *vm.getGlobal();
-
- switch (el.getType()) {
- case amf::Element::NOTYPE:
- {
-#ifdef GNASH_DEBUG_AMF_DESERIALIZE
- log_debug("as_value(Element&) : AMF type NO TYPE!");
-#endif
- break;
- }
- case amf::Element::NULL_AMF0:
- {
-#ifdef GNASH_DEBUG_AMF_DESERIALIZE
- log_debug("as_value(Element&) : AMF type NULL");
-#endif
- set_null();
- break;
- }
- case amf::Element::UNDEFINED_AMF0:
- {
-#ifdef GNASH_DEBUG_AMF_DESERIALIZE
- log_debug("as_value(Element&) : AMF type UNDEFINED");
-#endif
- set_undefined();
- break;
- }
- case amf::Element::MOVIECLIP_AMF0:
- {
-#ifdef GNASH_DEBUG_AMF_DESERIALIZE
- log_debug("as_value(Element&) : AMF type MOVIECLIP");
-#endif
- log_unimpl("MOVIECLIP AMF0 type");
- set_undefined();
- //m_type = MOVIECLIP;
- //_value = el.getData();
-
- break;
- }
- case amf::Element::NUMBER_AMF0:
- {
-#ifdef GNASH_DEBUG_AMF_DESERIALIZE
- log_debug("as_value(Element&) : AMF type NUMBER");
-#endif
- double num = el.to_number();
- set_double(num);
- break;
- }
- case amf::Element::BOOLEAN_AMF0:
- {
-#ifdef GNASH_DEBUG_AMF_DESERIALIZE
- log_debug("as_value(Element&) : AMF type BOOLEAN");
-#endif
- bool flag = el.to_bool();
- set_bool(flag);
- break;
- }
-
- case amf::Element::STRING_AMF0:
- case amf::Element::LONG_STRING_AMF0:
- {
-#ifdef GNASH_DEBUG_AMF_DESERIALIZE
- log_debug("as_value(Element&) : AMF type STRING");
-#endif
- std::string str;
- // If there is data, convert it to a string for the as_value
- if (el.getDataSize() != 0) {
- str = el.to_string();
- // Element's store the property name as the name, not as data.
- } else if (el.getNameSize() != 0) {
- str = el.getName();
- }
-
- set_string(str);
- break;
- }
-
- case amf::Element::OBJECT_AMF0:
- {
-
-#ifdef GNASH_DEBUG_AMF_DESERIALIZE
- log_debug("as_value(Element&) : AMF type OBJECT");
-#endif
- as_object* obj = gl.createObject();
- if (el.propertySize()) {
- for (size_t i=0; i < el.propertySize(); i++) {
- const boost::shared_ptr<amf::Element> prop =
el.getProperty(i);
- if (prop == 0) {
- break;
- } else {
- if (prop->getNameSize() == 0) {
- log_debug("%s:(%d) Property has no name!",
__PRETTY_FUNCTION__, __LINE__);
- } else {
- obj->set_member(st.find(prop->getName()),
as_value(*prop));
- }
- }
- }
- }
- set_as_object(obj);
- break;
- }
-
- case amf::Element::ECMA_ARRAY_AMF0:
- {
- // TODO: fixme: ECMA_ARRAY has an additional fiedl, dunno
- // if accessible trought Element class
- // (the theoretic number of elements in it)
-
-#ifdef GNASH_DEBUG_AMF_DESERIALIZE
- log_debug("as_value(Element&) : AMF type ECMA_ARRAY");
-#endif
-
- as_object* obj = gl.createArray();
-
- if (el.propertySize()) {
- for (size_t i=0; i < el.propertySize(); i++) {
- const boost::shared_ptr<amf::Element> prop =
el.getProperty(i);
- if (prop == 0) {
- break;
- } else {
- obj->set_member(st.find(prop->getName()),
as_value(*prop));
- }
- }
- }
- set_as_object(obj);
- break;
- }
-
-
- case amf::Element::STRICT_ARRAY_AMF0:
- {
-#ifdef GNASH_DEBUG_AMF_DESERIALIZE
- log_debug("as_value(Element&) : AMF type STRICT_ARRAY");
-#endif
- as_object* obj = gl.createArray();
- size_t len = el.propertySize();
- obj->set_member(NSV::PROP_LENGTH, len);
-
- for (size_t i=0; i < el.propertySize(); i++) {
- const boost::shared_ptr<amf::Element> prop = el.getProperty(i);
- if (prop == 0) {
- break;
- } else {
- if (prop->getNameSize() == 0) {
- log_debug("%s:(%d) Property has no name!",
__PRETTY_FUNCTION__, __LINE__);
- } else {
- obj->set_member(st.find(prop->getName()),
as_value(*prop));
- }
- }
- }
-
- set_as_object(obj);
- break;
- }
-
- case amf::Element::REFERENCE_AMF0:
- {
- log_unimpl("REFERENCE Element to as_value");
- break;
- }
-
- case amf::Element::DATE_AMF0:
- {
-#ifdef GNASH_DEBUG_AMF_DESERIALIZE
- log_debug("as_value(Element&) : AMF type DATE");
-#endif
- double num = el.to_number();
- set_double(num);
- break;
- }
- //if (swfVersion > 5) m_type = STRING;
-
- case amf::Element::UNSUPPORTED_AMF0:
- {
-#ifdef GNASH_DEBUG_AMF_DESERIALIZE
- log_debug("as_value(Element&) : AMF type UNSUPPORTED");
-#endif
- break;
- }
- case amf::Element::RECORD_SET_AMF0:
- log_unimpl("Record Set data type is not supported yet");
- break;
- case amf::Element::XML_OBJECT_AMF0:
- log_unimpl("XML data type is not supported yet");
- break;
- case amf::Element::TYPED_OBJECT_AMF0:
- log_unimpl("Typed Object data type is not supported yet");
- break;
- case amf::Element::AMF3_DATA:
- log_unimpl("AMF3 data type is not supported yet");
- break;
- default:
- log_unimpl("Element to as_value - unsupported Element type %d",
- el.getType());
- break;
- }
+ return _type == OBJECT && getObj()->to_function();
}
// Pass pointer to buffer and pointer to end of buffer. Buffer is raw AMF
@@ -1937,8 +1297,10 @@
log_debug("array size: %d", li);
- // the count specifies array size, so to have that even if none of
the members are indexed
- // if short, will be incremented everytime an indexed member is
found
+ // the count specifies array size, so to have that even if none
+ // of the members are indexed
+ // if short, will be incremented everytime an indexed member is
+ // found
obj->set_member(NSV::PROP_LENGTH, li);
// TODO: do boundary checking (if b >= end...)
@@ -1960,11 +1322,9 @@
// end of ECMA_ARRAY is signalled by an empty string
// followed by an OBJECT_END_AMF0 (0x09) byte
- if ( ! strlen )
- {
+ if (!strlen) {
// expect an object terminator here
- if ( *b++ != amf::Element::OBJECT_END_AMF0 )
- {
+ if (*b++ != amf::Element::OBJECT_END_AMF0) {
log_error("MALFORMED SOL: empty member name not "
"followed by OBJECT_END_AMF0 byte");
}
@@ -1977,8 +1337,7 @@
log_debug("amf0 ECMA_ARRAY prop name is %s", name);
#endif
b += strlen;
- if ( ! amf0_read_value(b, end, objectElement, -1, objRefs, vm)
)
- {
+ if (!amf0_read_value(b, end, objectElement, -1, objRefs, vm)) {
return false;
}
obj->set_member(st.find(name), objectElement);
@@ -2013,8 +1372,7 @@
}
keyString = tmp.to_string();
- if ( keyString.empty() )
- {
+ if (keyString.empty()) {
if (b < end) {
b += 1; // AMF0 has a redundant "object end" byte
} else {
@@ -2024,8 +1382,7 @@
return true;
}
- if ( ! amf0_read_value(b, end, tmp, -1, objRefs, vm) )
- {
+ if (!amf0_read_value(b, end, tmp, -1, objRefs, vm)) {
return false;
}
obj->set_member(st.find(keyString), tmp);
@@ -2129,10 +1486,10 @@
assert (!is_exception());
- switch (m_type)
+ switch (_type)
{
default:
- log_unimpl(_("serialization of as_value of type %d"), m_type);
+ log_unimpl(_("serialization of as_value of type %d"), _type);
return false;
case OBJECT:
@@ -2273,10 +1630,10 @@
return true;
}
- case MOVIECLIP:
+ case DISPLAYOBJECT:
{
#ifdef GNASH_DEBUG_AMF_SERIALIZE
- log_debug(_("writeAMF0: serializing MOVIECLIP (as undefined)"));
+ log_debug(_("writeAMF0: serializing DISPLAYOBJECT (as
undefined)"));
#endif
// See misc-ming.all/SharedObjectTest.as
buf.appendByte(amf::Element::UNDEFINED_AMF0);
@@ -2317,6 +1674,161 @@
}
}
+
+boost::int32_t
+toInt(const as_value& val)
+{
+ const double d = val.to_number();
+
+ if (!isFinite(d)) return 0;
+
+ return truncateToInt(d);
+}
+
+bool
+parseNonDecimalInt(const std::string& s, double& d, bool whole)
+{
+ const std::string::size_type slen = s.length();
+
+ // "0#" would still be octal, but has the same value as a decimal.
+ if (slen < 3) return false;
+
+ bool negative = false;
+
+ if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) {
+ // The only legitimate place for a '-' is after 0x. If it's a
+ // '+' we don't care, as it won't disturb the conversion.
+ std::string::size_type start = 2;
+ if (s[2] == '-') {
+ negative = true;
+ ++start;
+ }
+ d = parsePositiveInt(s.substr(start), BASE_HEX, whole);
+ if (negative) d = -d;
+ return true;
+ }
+ else if ((s[0] == '0' || ((s[0] == '-' || s[0] == '+') && s[1] == '0')) &&
+ s.find_first_not_of("01234567", 1) == std::string::npos) {
+
+ std::string::size_type start = 0;
+ if (s[0] == '-') {
+ negative = true;
+ ++start;
+ }
+ d = parsePositiveInt(s.substr(start), BASE_OCT, whole);
+ if (negative) d = -d;
+ return true;
+ }
+
+ return false;
+
+}
+
+std::string
+doubleToString(double val, int radix)
+{
+ // Examples:
+ //
+ // e.g. for 9*.1234567890123456789:
+ // 9999.12345678901
+ // 99999.123456789
+ // 999999.123456789
+ // 9999999.12345679
+ // [...]
+ // 999999999999.123
+ // 9999999999999.12
+ // 99999999999999.1
+ // 999999999999999
+ // 1e+16
+ // 1e+17
+ //
+ // For 1*.111111111111111111111111111111111111:
+ // 1111111111111.11
+ // 11111111111111.1
+ // 111111111111111
+ // 1.11111111111111e+15
+ // 1.11111111111111e+16
+ //
+ // For 1.234567890123456789 * 10^-i:
+ // 1.23456789012346
+ // 0.123456789012346
+ // 0.0123456789012346
+ // 0.00123456789012346
+ // 0.000123456789012346
+ // 0.0000123456789012346
+ // 0.00000123456789012346
+ // 1.23456789012346e-6
+ // 1.23456789012346e-7
+
+ // Handle non-numeric values.
+ if (isNaN(val)) return "NaN";
+
+ if (isInf(val)) return val < 0 ? "-Infinity" : "Infinity";
+
+ if (val == 0.0 || val == -0.0) return "0";
+
+ std::ostringstream ostr;
+
+ if (radix == 10) {
+
+ // ActionScript always expects dot as decimal point.
+ ostr.imbue(std::locale::classic());
+
+ // force to decimal notation for this range (because the
+ // reference player does)
+ if (std::abs(val) < 0.0001 && std::abs(val) >= 0.00001) {
+
+ // All nineteen digits (4 zeros + up to 15 significant
digits)
+ ostr << std::fixed << std::setprecision(19) << val;
+
+ std::string str = ostr.str();
+
+ // Because 'fixed' also adds trailing zeros, remove
them.
+ std::string::size_type pos = str.find_last_not_of('0');
+ if (pos != std::string::npos) {
+ str.erase(pos + 1);
+ }
+ return str;
+ }
+
+ ostr << std::setprecision(15) << val;
+
+ std::string str = ostr.str();
+
+ // Remove a leading zero from 2-digit exponent if any
+ std::string::size_type pos = str.find("e", 0);
+
+ if (pos != std::string::npos && str.at(pos + 2) == '0') {
+ str.erase(pos + 2, 1);
+ }
+
+ return str;
+ }
+
+ // Radix isn't 10
+ bool negative = (val < 0);
+ if (negative) val = -val;
+
+ double left = std::floor(val);
+ if (left < 1) return "0";
+
+ std::string str;
+ const std::string digits = "0123456789abcdefghijklmnopqrstuvwxyz";
+
+ // Construct the string backwards for speed, then reverse.
+ while (left) {
+ double n = left;
+ left = std::floor(left / radix);
+ n -= (left * radix);
+ str.push_back(digits[static_cast<int>(n)]);
+ }
+ if (negative) str.push_back('-');
+
+ std::reverse(str.begin(), str.end());
+
+ return str;
+}
+
/// Force type to number.
as_value&
convertToNumber(as_value& v, VM& /*vm*/)
@@ -2329,7 +1841,7 @@
as_value&
convertToString(as_value& v, VM& vm)
{
- v.set_string(v.to_string_versioned(vm.getSWFVersion()));
+ v.set_string(v.to_string(vm.getSWFVersion()));
return v;
}
@@ -2340,6 +1852,222 @@
v.set_bool(v.to_bool());
return v;
}
+
+as_value&
+convertToPrimitive(as_value& v, VM& vm)
+{
+ const as_value::AsType t(v.defaultPrimitive(vm.getSWFVersion()));
+ v = v.to_primitive(t);
+ return v;
+}
+
+#if 0
+
+/// Instantiate this value from an AMF element
+as_value::as_value(const amf::Element& el)
+ :
+ _type(UNDEFINED)
+{
+
+ VM& vm = VM::get();
+ string_table& st = vm.getStringTable();
+ Global_as& gl = *vm.getGlobal();
+
+ switch (el.getType()) {
+ case amf::Element::NOTYPE:
+ {
+#ifdef GNASH_DEBUG_AMF_DESERIALIZE
+ log_debug("as_value(Element&) : AMF type NO TYPE!");
+#endif
+ break;
+ }
+ case amf::Element::NULL_AMF0:
+ {
+#ifdef GNASH_DEBUG_AMF_DESERIALIZE
+ log_debug("as_value(Element&) : AMF type NULL");
+#endif
+ set_null();
+ break;
+ }
+ case amf::Element::UNDEFINED_AMF0:
+ {
+#ifdef GNASH_DEBUG_AMF_DESERIALIZE
+ log_debug("as_value(Element&) : AMF type UNDEFINED");
+#endif
+ set_undefined();
+ break;
+ }
+ case amf::Element::MOVIECLIP_AMF0:
+ {
+#ifdef GNASH_DEBUG_AMF_DESERIALIZE
+ log_debug("as_value(Element&) : AMF type DISPLAYOBJECT");
+#endif
+ log_unimpl("DISPLAYOBJECT AMF0 type");
+ set_undefined();
+ //_type = DISPLAYOBJECT;
+ //_value = el.getData();
+
+ break;
+ }
+ case amf::Element::NUMBER_AMF0:
+ {
+#ifdef GNASH_DEBUG_AMF_DESERIALIZE
+ log_debug("as_value(Element&) : AMF type NUMBER");
+#endif
+ double num = el.to_number();
+ set_double(num);
+ break;
+ }
+ case amf::Element::BOOLEAN_AMF0:
+ {
+#ifdef GNASH_DEBUG_AMF_DESERIALIZE
+ log_debug("as_value(Element&) : AMF type BOOLEAN");
+#endif
+ bool flag = el.to_bool();
+ set_bool(flag);
+ break;
+ }
+
+ case amf::Element::STRING_AMF0:
+ case amf::Element::LONG_STRING_AMF0:
+ {
+#ifdef GNASH_DEBUG_AMF_DESERIALIZE
+ log_debug("as_value(Element&) : AMF type STRING");
+#endif
+ std::string str;
+ // If there is data, convert it to a string for the as_value
+ if (el.getDataSize() != 0) {
+ str = el.to_string();
+ // Element's store the property name as the name, not as data.
+ } else if (el.getNameSize() != 0) {
+ str = el.getName();
+ }
+
+ set_string(str);
+ break;
+ }
+
+ case amf::Element::OBJECT_AMF0:
+ {
+
+#ifdef GNASH_DEBUG_AMF_DESERIALIZE
+ log_debug("as_value(Element&) : AMF type OBJECT");
+#endif
+ as_object* obj = gl.createObject();
+ if (el.propertySize()) {
+ for (size_t i=0; i < el.propertySize(); i++) {
+ const boost::shared_ptr<amf::Element> prop =
el.getProperty(i);
+ if (prop == 0) {
+ break;
+ } else {
+ if (prop->getNameSize() == 0) {
+ log_debug("%s:(%d) Property has no name!",
__PRETTY_FUNCTION__, __LINE__);
+ } else {
+ obj->set_member(st.find(prop->getName()),
as_value(*prop));
+ }
+ }
+ }
+ }
+ set_as_object(obj);
+ break;
+ }
+
+ case amf::Element::ECMA_ARRAY_AMF0:
+ {
+ // TODO: fixme: ECMA_ARRAY has an additional fiedl, dunno
+ // if accessible trought Element class
+ // (the theoretic number of elements in it)
+
+#ifdef GNASH_DEBUG_AMF_DESERIALIZE
+ log_debug("as_value(Element&) : AMF type ECMA_ARRAY");
+#endif
+
+ as_object* obj = gl.createArray();
+
+ if (el.propertySize()) {
+ for (size_t i=0; i < el.propertySize(); i++) {
+ const boost::shared_ptr<amf::Element> prop =
el.getProperty(i);
+ if (prop == 0) {
+ break;
+ } else {
+ obj->set_member(st.find(prop->getName()),
as_value(*prop));
+ }
+ }
+ }
+ set_as_object(obj);
+ break;
+ }
+
+
+ case amf::Element::STRICT_ARRAY_AMF0:
+ {
+#ifdef GNASH_DEBUG_AMF_DESERIALIZE
+ log_debug("as_value(Element&) : AMF type STRICT_ARRAY");
+#endif
+ as_object* obj = gl.createArray();
+ size_t len = el.propertySize();
+ obj->set_member(NSV::PROP_LENGTH, len);
+
+ for (size_t i=0; i < el.propertySize(); i++) {
+ const boost::shared_ptr<amf::Element> prop = el.getProperty(i);
+ if (prop == 0) {
+ break;
+ } else {
+ if (prop->getNameSize() == 0) {
+ log_debug("%s:(%d) Property has no name!",
__PRETTY_FUNCTION__, __LINE__);
+ } else {
+ obj->set_member(st.find(prop->getName()),
as_value(*prop));
+ }
+ }
+ }
+
+ set_as_object(obj);
+ break;
+ }
+
+ case amf::Element::REFERENCE_AMF0:
+ {
+ log_unimpl("REFERENCE Element to as_value");
+ break;
+ }
+
+ case amf::Element::DATE_AMF0:
+ {
+#ifdef GNASH_DEBUG_AMF_DESERIALIZE
+ log_debug("as_value(Element&) : AMF type DATE");
+#endif
+ double num = el.to_number();
+ set_double(num);
+ break;
+ }
+ //if (swfVersion > 5) _type = STRING;
+
+ case amf::Element::UNSUPPORTED_AMF0:
+ {
+#ifdef GNASH_DEBUG_AMF_DESERIALIZE
+ log_debug("as_value(Element&) : AMF type UNSUPPORTED");
+#endif
+ break;
+ }
+ case amf::Element::RECORD_SET_AMF0:
+ log_unimpl("Record Set data type is not supported yet");
+ break;
+ case amf::Element::XML_OBJECT_AMF0:
+ log_unimpl("XML data type is not supported yet");
+ break;
+ case amf::Element::TYPED_OBJECT_AMF0:
+ log_unimpl("Typed Object data type is not supported yet");
+ break;
+ case amf::Element::AMF3_DATA:
+ log_unimpl("AMF3 data type is not supported yet");
+ break;
+ default:
+ log_unimpl("Element to as_value - unsupported Element type %d",
+ el.getType());
+ break;
+ }
+}
+#endif
} // namespace gnash
=== modified file 'libcore/as_value.h'
--- a/libcore/as_value.h 2009-12-01 11:02:43 +0000
+++ b/libcore/as_value.h 2009-12-08 08:47:03 +0000
@@ -66,7 +66,8 @@
// type safety (i.e., they will only compile for floating point arguments).
template <typename T>
inline bool
-isNaN(const T& num, typename boost::enable_if<boost::is_floating_point<T>
>::type* dummy = 0)
+isNaN(const T& num, typename boost::enable_if<boost::is_floating_point<T> >::
+ type* dummy = 0)
{
UNUSED(dummy);
return num != num;
@@ -90,179 +91,83 @@
/// ActionScript value type.
//
-/// Any ActionScript value is stored into an instance of this
-/// class. The instance keeps primitive types by value and
-/// composite types by reference (smart pointer).
-///
+/// The as_value class can store basic ActionScript types.
+//
+/// These are the primitive types (Number, Boolean, String, null, and
+/// undefined), as well as complex types (Object and DisplayObject).
+//
+/// Most type handling is hidden within the class. There are two different
+/// types of access to the as_value: converting and non-converting.
+//
+/// Non-converting access
+/// Non-converting access is available for the complex types, for instance
+/// to_function() and toMovieClip(). In these cases, an object pointer is
+/// return only if the as_value is currently of the requested type. There
+/// are no ActionScript side-effects in such cases.
+//
+/// Converting access
+/// The primitive types and Objects have converting access. This means that
+/// as_values of a different type are converted to the requested type. These
+/// functions may have ActionScript side-effects, for instance the calling of
+/// toString or valueOf, or construction of an object.
+//
+/// It is possible to check the current type of an as_value using is_string(),
+/// is_number() etc. These functions have no ActionScript side effects.
class as_value
{
public:
+ // The exception type should always be one greater than the normal type.
enum AsType
{
- // Always make the exception type one greater than the normal
type.
-
- /// Undefined value
UNDEFINED,
UNDEFINED_EXCEPT,
-
- /// NULL value
NULLTYPE,
NULLTYPE_EXCEPT,
-
- /// Boolean value
BOOLEAN,
BOOLEAN_EXCEPT,
-
- /// String value
STRING,
STRING_EXCEPT,
-
- /// Number value
NUMBER,
NUMBER_EXCEPT,
-
- /// Object reference
OBJECT,
OBJECT_EXCEPT,
-
- /// MovieClip reference
- MOVIECLIP,
- MOVIECLIP_EXCEPT
+ DISPLAYOBJECT,
+ DISPLAYOBJECT_EXCEPT
};
- /// Construct an UNDEFINED value
+ /// Construct an undefined value
DSOEXPORT as_value();
- /// Copy constructor.
- as_value(const as_value& value);
-
- /// Construct a STRING value
+ /// Construct a primitive String value
as_value(const char* str);
as_value(const std::string& str);
- /// Construct a BOOLEAN value
+ /// Construct a primitive Boolean value
template <typename T>
as_value(T val, typename boost::enable_if<boost::is_same<bool, T>
>::type*
dummy = 0)
:
- m_type(BOOLEAN),
+ _type(BOOLEAN),
_value(val)
{
UNUSED(dummy);
}
- /// Construct a NUMBER value
+ /// Construct a primitive Number value
as_value(double val);
-
+
+ /// Construct a null, Object, or DisplayObject value
+ as_value(as_object* obj);
+
+ /// Copy constructor.
+ as_value(const as_value& value);
+
+#if 0
/// Construct a value from an AMF element
as_value(const amf::Element& el);
-
- /// Construct a NULL, OBJECT, MOVIECLIP value
- //
- /// See as_object::to_movie and as_object::to_function
- ///
- /// Internally adds a reference to the ref-counted as_object,
- /// if not-null
- ///
- as_value(as_object* obj);
-
- /// 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.
- ///
- /// 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
- ///
- /// TODO restore first parameter on parse errors
- ///
- /// @param b
- /// Pointer to buffer where to start reading.
- /// Will be moved as data is read.
- ///
- /// @param end
- /// Pointer to end of buffer. Reading from this would
- /// be invalid.
- ///
- /// @param inType
- /// Type of the AMF object to read. If -1, type will be
- /// read from a type byte.
- ///
- /// @param objRefs
- /// A vector of already-parsed objects to properly interpret
references.
- /// Pass an empty vector on first call as it will be used
internally.
- /// On return, the vector will be filled with pointers to every
- /// complex object parsed from the stream.
- ///
- /// @param vm
- /// Virtual machine to use for initialization of the values
- /// (string_table)
- ///
- DSOEXPORT bool readAMF0(const boost::uint8_t*& b,
- const boost::uint8_t* const end, int inType,
- std::vector<as_object*>& objRefs, VM& vm);
-
- /// Serialize value in AMF0 format.
- //
- /// @param buf
- /// The buffer to append serialized version of this value to.
- ///
- /// @param offsetTable
- /// A map of already-parsed objects, pass an empty map on first call as
- /// it will be used internally.
- ///
- /// @param vm
- /// Virtual machine to use for serialization of property names
- /// (string_table)
- ///
- /// @param allowStrictArray
- /// If true strict arrays will be encoded a STRICT_ARRAY types.
- ///
- bool writeAMF0(SimpleBuffer& buf, std::map<as_object*, size_t>&
offsetTable,
- VM& vm, bool allowStrictArray) const;
-
- /// Convert numeric value to string value, following ECMA-262
specification
- //
- // Printing formats:
- //
- // If _val > 1, Print up to 15 significant digits, then switch
- // to scientific notation, rounding at the last place and
- // omitting trailing zeroes.
- // For values < 1, print up to 4 leading zeroes after the
- // decimal point, then switch to scientific notation with up
- // to 15 significant digits, rounding with no trailing zeroes
- // If the value is negative, just add a '-' to the start; this
- // does not affect the precision of the printed value.
- //
- // This almost corresponds to iomanip's std::setprecision(15)
- // format, except that iomanip switches to scientific notation
- // at e-05 not e-06, and always prints at least two digits for the
exponent.
- static std::string doubleToString(double val, int radix=10);
-
- /// Try to parse a string into a 32-bit signed int using base 8 or 16. //
- /// This function will throw a boost::bad_lexical_cast (or a derived
- /// exception) if the passed string cannot be converted.
- //
- /// @param s The string to parse
- /// @param d The 32-bit int represented as a double. This is only a
- /// valid number if the return value is true.
- /// @param whole If true, expect the whole string to be valid, i.e.
- /// throw if there are any invalid DisplayObjects. If false,
- /// returns any valid number up to the first invalid
- /// DisplayObject.
- /// @return True if the string was non-decimal and successfully
- /// parsed.
- static bool parseNonDecimalInt(const std::string& s, double& d,
- bool whole = true);
+#endif
/// Return the primitive type of this value as a string.
const char* typeOf() const;
@@ -272,130 +177,55 @@
/// Only used in AVM2
primitive_types ptype() const;
- /// \brief
- /// Return true if this value is callable
+ /// Return true if this value is a function
bool is_function() const;
- /// Return true if this value is strictly a string
- //
- /// Note that you usually DON'T need to call this
- /// function, as if you really want a string you
- /// can always call the to_string() or to_std_string()
- /// method to perform a conversion.
- ///
- bool is_string() const
- {
- return m_type == STRING;
+ /// Return true if this value is a string
+ bool is_string() const {
+ return _type == STRING;
}
/// Return true if this value is strictly a number
- //
- /// Note that you usually DON'T need to call this
- /// function, as if you really want a number you
- /// can always call the to_number()
- /// method to perform a conversion.
- ///
- bool is_number() const
- {
- return m_type == NUMBER;
+ bool is_number() const {
+ return _type == NUMBER;
}
- /// \brief
/// Return true if this value is an object
- /// (OBJECT, or MOVIECLIP).
- bool is_object() const
- {
- return m_type == OBJECT || m_type == MOVIECLIP;
+ //
+ /// Both DisplayObjects and Objects count as Objects
+ bool is_object() const {
+ return _type == OBJECT || _type == DISPLAYOBJECT;
}
- /// \brief
- /// Return true if this value is a MOVIECLIP
- ///
- bool is_sprite() const
- {
- return m_type == MOVIECLIP;
+ /// Return true if this value is a DISPLAYOBJECT
+ bool is_sprite() const {
+ return _type == DISPLAYOBJECT;
}
/// Get a std::string representation for this value.
- std::string to_string() const;
-
- // Used for operator<< to give useful information about an
- // as_value object.
- DSOEXPORT std::string toDebugString() const;
-
- /// Get a string representation for this value.
- //
- /// This differs from to_string() in that returned
- /// representation will depend on version of the SWF
- /// source.
- /// @@ shouldn't this be the default ?
- ///
- /// @param version
- /// SWF version for which the operation is desired.
- ///
- std::string to_string_versioned(int version) const;
+ //
+ /// @param version The SWF version to use to transform the string.
+ /// This only affects undefined values, which trace
+ /// "undefined" for version 7 and above, nothing
+ /// for lower versions.
+ //
+ /// TODO: drop the default argument.
+ std::string to_string(int version = 7) const;
/// Get a number representation for this value
- double to_number() const;
-
- /// Get an AMF element representation for this value
- boost::shared_ptr<amf::Element> to_element() const;
-
- /// Conversion to 32bit integer
- //
- /// Use this conversion whenever an int is needed.
- /// This is NOT the same as calling to_number<boost::int32_t>().
- ///
- boost::int32_t to_int() const;
-
- /// Shorthand: casts the result of to_number() to the requested number
- /// type.
- //
- /// Parameter identical to that of to_number().
- ///
- /// TODO: deprecate this function, it gets confusing as when an integer
- /// is needed the caller should invoke to_int() rather then
to_number().
- /// Implementing specializations for *all* integer types might be
tedious
- ///
- template <typename T>
- T to_number () const
- {
- return static_cast<T>(to_number());
- }
+ //
+ /// This function performs conversion if necessary.
+ double to_number() const;
/// Conversion to boolean.
//
- /// Will call version-dependent functions
- /// based on current version.
- ///
- /// See to_bool_v5(), to_bool_v6(), to_bool_v7()
- ///
- bool to_bool() const;
-
- /// Conversion to boolean for SWF7 and up
- //
- /// See to_bool()
- ///
- bool to_bool_v7() const;
-
- /// Conversion to boolean for SWF6
- //
- /// See to_bool()
- ///
- bool to_bool_v6() const;
-
- /// Conversion to boolean up to SWF5
- //
- /// See to_bool()
- ///
- bool to_bool_v5() const;
+ /// This function performs conversion if necessary.
+ bool to_bool() const;
/// Return value as an object, converting primitive values as needed.
//
- /// Make sure you don't break the intrusive_ptr chain
- /// as the returned object might be a newly allocated one in case
- /// of a conversion from a primitive string, number or boolean value.
- ///
+ /// This function performs conversion where necessary.
+ //
/// string values are converted to String objects
/// numeric values are converted to Number objects
/// boolean values are converted to Boolean objects
@@ -408,47 +238,51 @@
/// conversion.
as_object* to_object(Global_as& global) const;
- /// Return value as a sprite or NULL if this is not possible.
+ /// Returns value as a MovieClip if it is a MovieClip.
//
+ /// This function performs no conversion, so returns 0 if the as_value is
+ /// not a MovieClip.
+ //
/// This is just a wrapper around toDisplayObject() performing
/// an additional final cast.
- ///
- MovieClip* to_sprite(bool skipRebinding=false) const;
+ MovieClip* toMovieClip(bool skipRebinding = false) const;
/// Return value as a DisplayObject or NULL if this is not possible.
//
- /// If the value is a MOVIECLIP value, the stored DisplayObject target
+ /// Note that this function performs no conversion, so returns 0 if the
+ /// as_value is not a DisplayObject.
+ //
+ /// If the value is a DisplayObject value, the stored DisplayObject
target
/// is evaluated using the root movie's environment.
/// If the target points to something that doesn't cast to a
DisplayObject,
- /// NULL is returned.
- ///
- /// Note that if the value is NOT a MOVIECLIP type, NULL is always
- /// returned.
- ///
- /// @param skipRebinding
- /// If true a reference to a destroyed DisplayObject is still
returned
- /// as such, rather then attempted to be resolved as a
soft-reference.
- /// Main use for this is during paths resolution, to avoid
- /// infinite loops. See bug #21647.
- ///
- DisplayObject* toDisplayObject(bool skipRebinding=false) const;
+ /// 0 is returned.
+ ///
+ /// @param skipRebinding If true a reference to a destroyed
+ /// DisplayObject is still returned, rather than
+ /// attempting to resolve it as a soft-reference.
+ /// Main use for this is during paths
resolution,
+ /// to avoid infinite loops. See bug #21647.
+ DisplayObject* toDisplayObject(bool skipRebinding = false) const;
- /// \brief
- /// Return value as an ActionScript function ptr
- /// or NULL if it is not an ActionScript function.
+ /// Return the value as a function only if it is a function.
+ //
+ /// Note that this performs no conversion, so returns 0 if the as_value
+ /// is not a function.
as_function* to_function() const;
- /// Return value as a primitive type
- //
- /// Primitive types are: undefined, null, boolean, string, number.
- /// See ECMA-2.6.2 (sections 4.3.2 and 8.6.2.6).
- ///
- /// @throw ActionTypeError if an object can't be converted to a
primitive
- ///
- as_value to_primitive() const;
+ /// Get an AMF element representation for this value
+ boost::shared_ptr<amf::Element> to_element() const;
+
+ // Used for operator<< to give useful information about an
+ // as_value object.
+ DSOEXPORT std::string toDebugString() const;
+
+ AsType defaultPrimitive(int version) const;
/// Return value as a primitive type, with a preference
//
+ /// This function performs no conversion.
+ //
/// Primitive types are: undefined, null, boolean, string, number.
/// See ECMA-2.6.2 (sections 4.3.2 and 8.6.2.6).
///
@@ -459,48 +293,19 @@
///
as_value to_primitive(AsType hint) const;
- /// Convert this value to a primitive type, with a preference
- //
- /// Primitive types are: undefined, null, boolean, string, number.
- /// See ECMA-2.6.2 (sections 4.3.2 and 8.6.2.6).
- ///
- /// @param hint
- /// NUMBER or STRING, the preferred representation we're asking for.
- ///
- /// @throw ActionTypeError if an object can't be converted to a
primitive
- ///
- as_value& convert_to_primitive();
-
- // These set_*()'s are more type-safe; should be used
- // in preference to generic overloaded set(). You are
- // more likely to get a warning/error if misused.
-
+ /// Set to a primitive string.
void set_string(const std::string& str);
+ /// Set to a primitive number.
void set_double(double val);
+ /// Set to a primitive boolean.
void set_bool(bool val);
- /// Set this as_value to a DisplayObject
- //
- /// as_value itself does not distinguish between MovieClips and other
- /// types of DisplayObject; TextFields initially appear as type
- /// "movieclip".
- void setDisplayObject(DisplayObject& sp);
-
- void set_int(int val) { set_double(val); }
-
- void set_nan() { set_double(NaN); }
-
- /// Make this value a NULL, OBJECT, MOVIECLIP value
- //
- /// See as_object::to_movie and as_object::to_function
- ///
- /// Internally adds a reference to the ref-counted as_object,
- /// if not-null
- ///
+ /// Make this value a NULL, OBJECT, DISPLAYOBJECT value
void set_as_object(as_object* obj);
+ /// Set to undefined.
void set_undefined();
/// Set this value to the NULL value
@@ -508,30 +313,36 @@
void operator=(const as_value& v);
- bool is_undefined() const { return (m_type == UNDEFINED); }
-
- bool is_null() const { return (m_type == NULLTYPE); }
-
- bool is_bool() const { return (m_type == BOOLEAN); }
+ bool is_undefined() const {
+ return (_type == UNDEFINED);
+ }
+
+ bool is_null() const {
+ return (_type == NULLTYPE);
+ }
+
+ bool is_bool() const {
+ return (_type == BOOLEAN);
+ }
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 == MOVIECLIP_EXCEPT || m_type == STRING_EXCEPT);
+ return (_type == UNDEFINED_EXCEPT || _type == NULLTYPE_EXCEPT
+ || _type == BOOLEAN_EXCEPT || _type == NUMBER_EXCEPT
+ || _type == OBJECT_EXCEPT || _type == DISPLAYOBJECT_EXCEPT
+ || _type == STRING_EXCEPT);
}
// Flag or unflag an as_value as an exception -- this gets flagged
// when an as_value is 'thrown'.
void flag_exception() {
if (!is_exception()) {
- m_type = static_cast<AsType>(static_cast<int>(m_type) + 1);
+ _type = static_cast<AsType>(static_cast<int>(_type) + 1);
}
}
void unflag_exception() {
if (is_exception()) {
- m_type = static_cast<AsType>(static_cast<int>(m_type) - 1);
+ _type = static_cast<AsType>(static_cast<int>(_type) - 1);
}
}
@@ -539,7 +350,6 @@
//
/// Strict equality is defined as the two values being of the
/// same type and the same value.
- ///
bool strictly_equals(const as_value& v) const;
/// Return true if this value is abstractly equal to the given one
@@ -552,38 +362,78 @@
/// - A == B is equivalent to B == A, except for order of
/// evaluation of A and B.
///
- /// @param v
- /// The as_value to compare to
- ///
+ /// @param v The as_value to compare to
bool equals(const as_value& v) const;
- /// Sets this value to this string plus the given string.
- void string_concat(const std::string& str);
-
/// Set any object value as reachable (for the GC)
//
/// Object values are values stored by pointer (objects and functions)
- ///
void setReachable() const;
+ /// 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.
+ ///
+ /// 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
+ ///
+ /// TODO restore first parameter on parse errors
+ ///
+ /// @param b
+ /// Pointer to buffer where to start reading.
+ /// Will be moved as data is read.
+ ///
+ /// @param end
+ /// Pointer to end of buffer. Reading from this would
+ /// be invalid.
+ ///
+ /// @param inType
+ /// Type of the AMF object to read. If -1, type will be
+ /// read from a type byte.
+ ///
+ /// @param objRefs
+ /// A vector of already-parsed objects to properly interpret
references.
+ /// Pass an empty vector on first call as it will be used
internally.
+ /// On return, the vector will be filled with pointers to every
+ /// complex object parsed from the stream.
+ ///
+ /// @param vm
+ /// Virtual machine to use for initialization of the values
+ /// (string_table)
+ ///
+ DSOEXPORT bool readAMF0(const boost::uint8_t*& b,
+ const boost::uint8_t* const end, int inType,
+ std::vector<as_object*>& objRefs, VM& vm);
+
+ /// Serialize value in AMF0 format.
+ //
+ /// @param buf
+ /// The buffer to append serialized version of this value to.
+ ///
+ /// @param offsetTable
+ /// A map of already-parsed objects, pass an empty map on first call as
+ /// it will be used internally.
+ ///
+ /// @param vm
+ /// Virtual machine to use for serialization of property names
+ /// (string_table)
+ ///
+ /// @param allowStrictArray
+ /// If true strict arrays will be encoded a STRICT_ARRAY types.
+ ///
+ bool writeAMF0(SimpleBuffer& buf, std::map<as_object*, size_t>&
offsetTable,
+ VM& vm, bool allowStrictArray) const;
+
private:
- /// Use the relevant equality function, not operator==
- bool operator==(const as_value& v) const;
-
- /// Use the relevant inequality function, not operator!=
- bool operator!=(const as_value& v) const;
-
- /// Compare values of the same type
- //
- /// NOTE: will abort if values are not of the same type!
- ///
- bool equalsSameType(const as_value& v) const;
-
- AsType m_type;
-
- typedef DisplayObject* CharacterPtr;
-
/// AsValueType handles the following AS types:
//
/// 1. undefined / null
@@ -600,36 +450,67 @@
std::string>
AsValueType;
+ /// Use the relevant equality function, not operator==
+ bool operator==(const as_value& v) const;
+
+ /// Use the relevant inequality function, not operator!=
+ bool operator!=(const as_value& v) const;
+
+ /// Compare values of the same type
+ //
+ /// NOTE: will abort if values are not of the same type!
+ ///
+ bool equalsSameType(const as_value& v) const;
+
+ /// Conversion to boolean for SWF7 and up
+ bool to_bool_v7() const;
+
+ /// Conversion to boolean for SWF6
+ bool to_bool_v6() const;
+
+ /// Conversion to boolean up to SWF5
+ bool to_bool_v5() const;
+
+ AsType _type;
+
AsValueType _value;
- /// Get the object pointer variant member (we assume m_type == OBJECT)
+ /// Get the object pointer variant member.
+ //
+ /// Callers must check that this is an Object (including DisplayObjects).
as_object* getObj() const;
- /// Get the DisplayObject variant member (we assume m_type == MOVIECLIP)
- //
- /// NOTE: this is possibly NULL !
- ///
- CharacterPtr getCharacter(bool skipRebinding=false) const;
+ /// Get the DisplayObject variant member.
+ //
+ /// The caller must check that this is a DisplayObject.
+ DisplayObject* getCharacter(bool skipRebinding = false) const;
- /// Get the sprite proxy variant member (we assume m_type == MOVIECLIP)
- //
+ /// Get the DisplayObject proxy variant member.
+ //
+ /// The caller must check that this value is a DisplayObject
CharacterProxy getCharacterProxy() const;
- /// Get the number variant member (we assume m_type == NUMBER)
+ /// Get the number variant member.
+ //
+ /// The caller must check that this value is a Number.
double getNum() const {
- assert(m_type == NUMBER);
+ assert(_type == NUMBER);
return boost::get<double>(_value);
}
- /// Get the boolean variant member (we assume m_type == BOOLEAN)
+ /// Get the boolean variant member.
+ //
+ /// The caller must check that this value is a Boolean.
bool getBool() const {
- assert(m_type == BOOLEAN);
+ assert(_type == BOOLEAN);
return boost::get<bool>(_value);
}
- /// Get the boolean variant member (we assume m_type == STRING)
+ /// Get the boolean variant member.
+ //
+ /// The caller must check that this value is a String.
const std::string& getStr() const {
- assert(m_type == STRING);
+ assert(_type == STRING);
return boost::get<std::string>(_value);
}
@@ -645,10 +526,61 @@
/// Force type to bool.
as_value& convertToBoolean(as_value& v, VM& vm);
+/// Convert to primitive type
+as_value& convertToPrimitive(as_value& v, VM& vm);
+
inline std::ostream& operator<< (std::ostream& os, const as_value& v) {
return os << v.toDebugString();
}
+/// Convert numeric value to string value, following ECMA-262 specification
+//
+// Printing formats:
+//
+// If _val > 1, Print up to 15 significant digits, then switch
+// to scientific notation, rounding at the last place and
+// omitting trailing zeroes.
+// For values < 1, print up to 4 leading zeroes after the
+// decimal point, then switch to scientific notation with up
+// to 15 significant digits, rounding with no trailing zeroes
+// If the value is negative, just add a '-' to the start; this
+// does not affect the precision of the printed value.
+//
+// This almost corresponds to iomanip's std::setprecision(15)
+// format, except that iomanip switches to scientific notation
+// at e-05 not e-06, and always prints at least two digits for the exponent.
+std::string doubleToString(double val, int radix = 10);
+
+/// Try to parse a string into a 32-bit signed int using base 8 or 16. //
+/// This function will throw a boost::bad_lexical_cast (or a derived
+/// exception) if the passed string cannot be converted.
+//
+/// @param s The string to parse
+/// @param d The 32-bit int represented as a double. This is only a
+/// valid number if the return value is true.
+/// @param whole If true, expect the whole string to be valid, i.e.
+/// throw if there are any invalid DisplayObjects. If false,
+/// returns any valid number up to the first invalid
+/// DisplayObject.
+/// @return True if the string was non-decimal and successfully
+/// parsed.
+bool parseNonDecimalInt(const std::string& s, double& d, bool whole = true);
+
+/// AS2-compatible conversion to 32bit integer
+//
+/// This truncates large numbers to fit in the 32-bit space. It is not a
+/// proper function of as_value because it is simply a further operation on
+/// the stored number type.
+//
+/// This function calls to_number(), so performs a conversion if necessary.
+boost::int32_t toInt(const as_value& val);
+
+/// Set a value to NaN
+inline void
+setNaN(as_value& v) {
+ v.set_double(NaN);
+}
+
} // namespace gnash
#endif // GNASH_AS_VALUE_H
=== modified file 'libcore/asobj/Array_as.cpp'
--- a/libcore/asobj/Array_as.cpp 2009-12-04 09:20:14 +0000
+++ b/libcore/asobj/Array_as.cpp 2009-12-08 08:47:03 +0000
@@ -317,16 +317,16 @@
inline int str_cmp(const as_value& a, const as_value& b)
{
- std::string s = a.to_string_versioned(_version);
- return s.compare(b.to_string_versioned(_version));
+ std::string s = a.to_string(_version);
+ return s.compare(b.to_string(_version));
}
inline int str_nocase_cmp(const as_value& a, const as_value& b)
{
using namespace boost::algorithm;
- std::string c = to_upper_copy(a.to_string_versioned(_version));
- std::string d = to_upper_copy(b.to_string_versioned(_version));
+ std::string c = to_upper_copy(a.to_string(_version));
+ std::string d = to_upper_copy(b.to_string(_version));
return c.compare(d);
}
@@ -612,7 +612,7 @@
args += b, a;
ret = invoke(cmp_method, _env, _object, args);
- return (*_zeroCmp)(ret.to_int());
+ return (*_zeroCmp)(toInt(ret));
}
};
@@ -762,7 +762,7 @@
_version(version)
{}
void operator()(const as_value& val) {
- _v.push_back(_st.find(val.to_string_versioned(_version)));
+ _v.push_back(_st.find(val.to_string(_version)));
}
private:
std::vector<string_table::key>& _v;
@@ -825,7 +825,7 @@
{
const string_table::key name = getName(uri);
if (name == NSV::PROP_LENGTH) {
- resizeArray(array, val.to_int());
+ resizeArray(array, toInt(val));
return;
}
@@ -845,7 +845,7 @@
as_value length;
if (!array.get_member(NSV::PROP_LENGTH, &length)) return 0;
- const int size = length.to_int();
+ const int size = toInt(length);
if (size < 0) return 0;
return size;
}
@@ -949,7 +949,7 @@
// Get start offset
//----------------
- int start = fn.arg(0).to_int();
+ int start = toInt(fn.arg(0));
if (start < 0) start = size + start;
start = clamp<int>(start, 0, size);
@@ -957,7 +957,7 @@
size_t remove = size - start;
if (fn.nargs > 1) {
- int remval = fn.arg(1).to_int();
+ int remval = toInt(fn.arg(1));
if (remval < 0) {
IF_VERBOSE_ASCODING_ERRORS(
log_aserror(_("Array.splice(%d,%d): negative length "
@@ -1094,7 +1094,7 @@
if (fn.arg(0).is_string())
{
string_table::key propField =
- st.find(fn.arg(0).to_string_versioned(version));
+ st.find(fn.arg(0).to_string(version));
if (fn.nargs > 1 && fn.arg(1).is_number()) {
flags = static_cast<boost::uint8_t>(fn.arg(1).to_number());
@@ -1177,7 +1177,7 @@
// case: sortOn(["prop1", "prop2"], Array.FLAG)
else {
boost::uint8_t flags =
- static_cast<boost::uint8_t>(fn.arg(1).to_int());
+ static_cast<boost::uint8_t>(toInt(fn.arg(1)));
flags = flag_preprocess(flags, &do_unique, &do_index);
as_cmp_fn c = get_basic_cmp(flags, version);
@@ -1333,7 +1333,7 @@
const int version = getSWFVersion(fn);
const std::string separator =
- fn.nargs ? fn.arg(0).to_string_versioned(version) : ",";
+ fn.nargs ? fn.arg(0).to_string(version) : ",";
return join(array, separator);
}
@@ -1402,10 +1402,10 @@
);
}
- int startindex = fn.nargs ? fn.arg(0).to_int() : 0;
+ int startindex = fn.nargs ? toInt(fn.arg(0)) : 0;
// if we sent at least two arguments, setup endindex
- int endindex = fn.nargs > 1 ? fn.arg(1).to_int() :
+ int endindex = fn.nargs > 1 ? toInt(fn.arg(1)) :
std::numeric_limits<int>::max();
Global_as& gl = getGlobal(fn);
@@ -1435,7 +1435,7 @@
}
if (fn.nargs == 1 && fn.arg(0).is_number()) {
- int newSize = fn.arg(0).to_int();
+ int newSize = toInt(fn.arg(0));
if (newSize < 0) newSize = 0;
else {
ao->set_member(NSV::PROP_LENGTH, newSize);
@@ -1470,7 +1470,7 @@
if (i) s += separator;
as_value el;
array->get_member(st.find(os.str()), &el);
- s += el.to_string_versioned(version);
+ s += el.to_string(version);
}
return as_value(s);
}
=== modified file 'libcore/asobj/AsBroadcaster.cpp'
--- a/libcore/asobj/AsBroadcaster.cpp 2009-11-18 11:51:35 +0000
+++ b/libcore/asobj/AsBroadcaster.cpp 2009-12-07 12:16:50 +0000
@@ -325,14 +325,14 @@
// This is an ActionScript-like implementation, which is why it looks
// like poor C++.
- int length = listeners->getMember(NSV::PROP_LENGTH).to_int();
+ const int length = toInt(listeners->getMember(NSV::PROP_LENGTH));
int i = 0;
string_table& st = getStringTable(fn);
+
while (i < length) {
std::ostringstream s;
s << i;
- as_value el =
- listeners->getMember(st.find(s.str()));
+ as_value el = listeners->getMember(st.find(s.str()));
if (el.equals(listenerToRemove)) {
callMethod(listeners, NSV::PROP_SPLICE, s.str(), 1);
return as_value(true);
@@ -347,7 +347,7 @@
as_value
asbroadcaster_broadcastMessage(const fn_call& fn)
{
- boost::intrusive_ptr<as_object> obj = fn.this_ptr;
+ as_object* obj = ensure<ValidThis>(fn);
as_value listenersValue;
@@ -355,12 +355,10 @@
// inheritance chain in case its own property _listeners
// has been deleted while another one is found in any base
// class.
- if ( ! obj->get_member(NSV::PROP_uLISTENERS, &listenersValue) )
- {
+ if (!obj->get_member(NSV::PROP_uLISTENERS, &listenersValue)) {
IF_VERBOSE_ASCODING_ERRORS(
log_aserror(_("%p.addListener(%s): this object has no "
- "_listeners member"), (void*)fn.this_ptr,
- fn.dump_args());
+ "_listeners member"), obj, fn.dump_args());
);
return as_value(); // TODO: check this
}
=== modified file 'libcore/asobj/Color_as.cpp'
--- a/libcore/asobj/Color_as.cpp 2009-11-30 10:31:53 +0000
+++ b/libcore/asobj/Color_as.cpp 2009-12-07 12:16:50 +0000
@@ -162,7 +162,7 @@
MovieClip* sp = getTarget(obj, fn);
if (!sp) return as_value();
- boost::int32_t color = fn.arg(0).to_int();
+ boost::int32_t color = toInt(fn.arg(0));
const int r = (color & 0xff0000) >> 16;
const int g = (color & 0x00ff00) >> 8;
@@ -275,7 +275,7 @@
getTarget(as_object* obj, const fn_call& fn)
{
const as_value& target = obj->getMember(NSV::PROP_TARGET);
- MovieClip* sp = target.to_sprite();
+ MovieClip* sp = target.toMovieClip();
if (sp) return sp;
DisplayObject* o = fn.env().find_target(target.to_string());
if (o) return o->to_movie();
=== modified file 'libcore/asobj/Date_as.cpp'
--- a/libcore/asobj/Date_as.cpp 2009-12-04 09:20:14 +0000
+++ b/libcore/asobj/Date_as.cpp 2009-12-07 12:16:50 +0000
@@ -448,9 +448,9 @@
gt.minute = 0;
gt.hour = 0;
gt.monthday = 1;
- gt.month = fn.arg(1).to_int();
+ gt.month = toInt(fn.arg(1));
- int year = fn.arg(0).to_int();
+ int year = toInt(fn.arg(0));
// GnashTime.year is the value since 1900 (like struct tm)
// negative value is a year before 1900. A year between 0
@@ -469,15 +469,15 @@
)
case 7:
// fractions of milliseconds are ignored
- gt.millisecond = fn.arg(6).to_int();
+ gt.millisecond = toInt(fn.arg(6));
case 6:
- gt.second = fn.arg(5).to_int();
+ gt.second = toInt(fn.arg(5));
case 5:
- gt.minute = fn.arg(4).to_int();
+ gt.minute = toInt(fn.arg(4));
case 4:
- gt.hour = fn.arg(3).to_int();
+ gt.hour = toInt(fn.arg(3));
case 3:
- gt.monthday = fn.arg(2).to_int();
+ gt.monthday = toInt(fn.arg(2));
case 2:
break;
// Done already
@@ -847,7 +847,7 @@
GnashTime gt;
dateToGnashTime(*date, gt, utc);
- gt.year = fn.arg(0).to_int() - 1900;
+ gt.year = toInt(fn.arg(0)) - 1900;
switch (fn.nargs)
{
default:
@@ -857,9 +857,9 @@
);
case 3:
- gt.monthday = fn.arg(2).to_int();
+ gt.monthday = toInt(fn.arg(2));
case 2:
- gt.month = fn.arg(1).to_int();
+ gt.month = toInt(fn.arg(1));
}
gnashTimeToDate(gt, *date, utc);
}
@@ -907,8 +907,8 @@
truncateDouble(gt.year, year);
- if (fn.nargs >= 2) gt.month = fn.arg(1).to_int();
- if (fn.nargs >= 3) gt.monthday = fn.arg(2).to_int();
+ if (fn.nargs >= 2) gt.month = toInt(fn.arg(1));
+ if (fn.nargs >= 3) gt.monthday = toInt(fn.arg(2));
if (fn.nargs > 3) {
IF_VERBOSE_ASCODING_ERRORS(
log_aserror(_("Date.setYear was called with more than three "
@@ -1006,7 +1006,7 @@
GnashTime gt;
dateToGnashTime(*date, gt, utc);
- gt.monthday = fn.arg(0).to_int();
+ gt.monthday = toInt(fn.arg(0));
gnashTimeToDate(gt, *date, utc);
}
if (fn.nargs > 1) {
@@ -1051,10 +1051,10 @@
GnashTime gt;
dateToGnashTime(*date, gt, utc);
- gt.hour = fn.arg(0).to_int();
- if (fn.nargs >= 2) gt.minute = fn.arg(1).to_int();
- if (fn.nargs >= 3) gt.second = fn.arg(2).to_int();
- if (fn.nargs >= 4) gt.millisecond = fn.arg(3).to_int();
+ gt.hour = toInt(fn.arg(0));
+ if (fn.nargs >= 2) gt.minute = toInt(fn.arg(1));
+ if (fn.nargs >= 3) gt.second = toInt(fn.arg(2));
+ if (fn.nargs >= 4) gt.millisecond = toInt(fn.arg(3));
if (fn.nargs > 4) {
IF_VERBOSE_ASCODING_ERRORS(
log_aserror(_("Date.set%sHours was called with more than "
@@ -1096,9 +1096,9 @@
GnashTime gt;
dateToGnashTime(*date, gt, utc);
- gt.minute = fn.arg(0).to_int();
- if (fn.nargs >= 2) gt.second = fn.arg(1).to_int();
- if (fn.nargs >= 3) gt.millisecond = fn.arg(2).to_int();
+ gt.minute = toInt(fn.arg(0));
+ if (fn.nargs >= 2) gt.second = toInt(fn.arg(1));
+ if (fn.nargs >= 3) gt.millisecond = toInt(fn.arg(2));
if (fn.nargs > 3) {
IF_VERBOSE_ASCODING_ERRORS(
log_aserror(_("Date.set%sMinutes was called with more than "
@@ -1140,8 +1140,8 @@
GnashTime gt;
dateToGnashTime(*date, gt, utc);
- gt.second = fn.arg(0).to_int();
- if (fn.nargs >= 2) gt.millisecond = fn.arg(1).to_int();
+ gt.second = toInt(fn.arg(0));
+ if (fn.nargs >= 2) gt.millisecond = toInt(fn.arg(1));
if (fn.nargs > 2) {
IF_VERBOSE_ASCODING_ERRORS(
log_aserror(_("Date.set%sMinutes was called with more than "
@@ -1269,17 +1269,17 @@
)
case 7:
// millisecs is double, but fractions of millisecs are ignored.
- gt.millisecond = fn.arg(6).to_int();
+ gt.millisecond = toInt(fn.arg(6));
case 6:
- gt.second = fn.arg(5).to_int();
+ gt.second = toInt(fn.arg(5));
case 5:
- gt.minute = fn.arg(4).to_int();
+ gt.minute = toInt(fn.arg(4));
case 4:
- gt.hour = fn.arg(3).to_int();
+ gt.hour = toInt(fn.arg(3));
case 3:
- gt.monthday = fn.arg(2).to_int();
+ gt.monthday = toInt(fn.arg(2));
case 2: // these last two are always performed
- gt.month = fn.arg(1).to_int();
+ gt.month = toInt(fn.arg(1));
{
boost::int32_t year = 0;
truncateDouble(year, fn.arg(0).to_number());
=== modified file 'libcore/asobj/Globals.cpp'
--- a/libcore/asobj/Globals.cpp 2009-12-02 15:31:53 +0000
+++ b/libcore/asobj/Globals.cpp 2009-12-07 12:16:50 +0000
@@ -864,7 +864,7 @@
size_t base;
if (fn.nargs > 1)
{
- base = fn.arg(1).to_int();
+ base = toInt(fn.arg(1));
// Bases from 2 to 36 are valid, otherwise return NaN
if (base < 2 || base > 36) return as_value(NaN);
@@ -874,7 +874,7 @@
/// No radix specified, so try parsing as octal or hexadecimal
try {
double d;
- if (as_value::parseNonDecimalInt(expr, d, false)) return d;
+ if (parseNonDecimalInt(expr, d, false)) return d;
}
catch (boost::bad_lexical_cast&) {
return as_value(NaN);
@@ -995,7 +995,7 @@
// ASSetPropFlags was exposed in Flash 5, however the fourth argument
// 'set_false' was not required as it always defaulted to the value '~0'.
- const int setFalse = (fn.nargs < 4 ? 0 : fn.arg(3).to_int()) &
+ const int setFalse = (fn.nargs < 4 ? 0 : toInt(fn.arg(3))) &
flagsMask;
obj->setPropFlags(props, setFalse, setTrue);
@@ -1018,8 +1018,8 @@
return as_value();
}
- const int sx = fn.arg(0).to_int();
- const int sy = fn.arg(1).to_int();
+ const int sx = toInt(fn.arg(0));
+ const int sy = toInt(fn.arg(1));
if (sx < 0 || sy < 0) {
IF_VERBOSE_ASCODING_ERRORS(
@@ -1061,8 +1061,8 @@
return as_value();
}
- const int sx = fn.arg(0).to_int();
- const int sy = fn.arg(1).to_int();
+ const int sx = toInt(fn.arg(0));
+ const int sy = toInt(fn.arg(1));
if (sx < 0 || sy < 0) {
IF_VERBOSE_ASCODING_ERRORS(
@@ -1114,12 +1114,12 @@
return as_value();
}
- const int major = fn.arg(1).to_int();
+ const int major = toInt(fn.arg(1));
if (major < 0) return as_value();
const std::string& props = fn.arg(2).to_string();
const int minor =
- fn.nargs > 3 ? std::max<boost::int32_t>(fn.arg(3).to_int(), 0) : 0;
+ fn.nargs > 3 ? std::max<boost::int32_t>(toInt(fn.arg(3)), 0) : 0;
std::string::const_iterator pos = props.begin();
@@ -1185,12 +1185,12 @@
return as_value();
}
- const int major = fn.arg(1).to_int();
+ const int major = toInt(fn.arg(1));
if (major < 0) return as_value();
const std::string& props = fn.arg(2).to_string();
const int minor =
- fn.nargs > 3 ? std::max<boost::int32_t>(fn.arg(3).to_int(), 0) : 0;
+ fn.nargs > 3 ? std::max<boost::int32_t>(toInt(fn.arg(3)), 0) : 0;
std::string::const_iterator pos = props.begin();
=== modified file 'libcore/asobj/LoadableObject.cpp'
--- a/libcore/asobj/LoadableObject.cpp 2009-11-19 07:43:46 +0000
+++ b/libcore/asobj/LoadableObject.cpp 2009-12-08 08:47:03 +0000
@@ -257,7 +257,7 @@
ValuesMap vals;
const int version = getSWFVersion(fn);
- const std::string qs = fn.arg(0).to_string_versioned(version);
+ const std::string qs = fn.arg(0).to_string(version);
if (qs.empty()) return as_value();
=== modified file 'libcore/asobj/Number_as.cpp'
--- a/libcore/asobj/Number_as.cpp 2009-12-04 09:20:14 +0000
+++ b/libcore/asobj/Number_as.cpp 2009-12-07 12:16:50 +0000
@@ -70,7 +70,7 @@
if ( fn.nargs )
{
- int userRadix = fn.arg(0).to_int();
+ int userRadix = toInt(fn.arg(0));
if ( userRadix >= 2 && userRadix <= 36 ) radix=userRadix;
else
{
@@ -82,7 +82,7 @@
}
}
- return as_value::doubleToString(val, radix);
+ return doubleToString(val, radix);
}
as_value
=== modified file 'libcore/asobj/Selection_as.cpp'
--- a/libcore/asobj/Selection_as.cpp 2009-11-18 11:51:35 +0000
+++ b/libcore/asobj/Selection_as.cpp 2009-12-07 12:16:50 +0000
@@ -244,8 +244,8 @@
return as_value();
}
- int start = fn.arg(0).to_int();
- int end = fn.arg(1).to_int();
+ int start = toInt(fn.arg(0));
+ int end = toInt(fn.arg(1));
tf->setSelection(start, end);
=== modified file 'libcore/asobj/String_as.cpp'
--- a/libcore/asobj/String_as.cpp 2009-12-04 09:20:14 +0000
+++ b/libcore/asobj/String_as.cpp 2009-12-08 08:47:03 +0000
@@ -162,7 +162,7 @@
const int version = getStringVersioned(fn, val, str);
for (size_t i = 0; i < fn.nargs; i++) {
- str += fn.arg(i).to_string_versioned(version);
+ str += fn.arg(i).to_string(version);
}
return as_value(str);
@@ -182,13 +182,13 @@
if (!checkArgs(fn, 1, 2, "String.slice()")) return as_value();
- size_t start = validIndex(wstr, fn.arg(0).to_int());
+ size_t start = validIndex(wstr, toInt(fn.arg(0)));
size_t end = wstr.length();
if (fn.nargs >= 2)
{
- end = validIndex(wstr, fn.arg(1).to_int());
+ end = validIndex(wstr, toInt(fn.arg(1)));
}
@@ -264,7 +264,7 @@
// SWF5
if (fn.nargs > 1 && !fn.arg(1).is_undefined())
{
- int limit = fn.arg(1).to_int();
+ int limit = toInt(fn.arg(1));
if (limit < 1)
{
// Return empty array.
@@ -297,7 +297,7 @@
// the delimiter is defined.
if (fn.nargs > 1 && !fn.arg(1).is_undefined())
{
- int limit = fn.arg(1).to_int();
+ int limit = toInt(fn.arg(1));
if (limit < 1) {
// Return empty array if
return as_value(array);
@@ -350,12 +350,12 @@
if (!checkArgs(fn, 1, 2, "String.lastIndexOf()")) return as_value(-1);
- const std::string& toFind = fn.arg(0).to_string_versioned(version);
+ const std::string& toFind = fn.arg(0).to_string(version);
int start = str.size();
if (fn.nargs >= 2) {
- start = fn.arg(1).to_int();
+ start = toInt(fn.arg(1));
}
if (start < 0) {
@@ -388,13 +388,13 @@
if (!checkArgs(fn, 1, 2, "String.substr()")) return as_value(str);
- int start = validIndex(wstr, fn.arg(0).to_int());
+ int start = validIndex(wstr, toInt(fn.arg(0)));
int num = wstr.length();
if (fn.nargs >= 2 && !fn.arg(1).is_undefined())
{
- num = fn.arg(1).to_int();
+ num = toInt(fn.arg(1));
if ( num < 0 )
{
if ( -num <= start ) num = 0;
@@ -428,7 +428,7 @@
const as_value& s = fn.arg(0);
- int start = s.to_int();
+ int start = toInt(s);
int end = wstr.size();
if (s.is_undefined() || start < 0) {
@@ -440,7 +440,7 @@
}
if (fn.nargs >= 2 && !fn.arg(1).is_undefined()) {
- int num = fn.arg(1).to_int();
+ int num = toInt(fn.arg(1));
if (num < 0) {
num = 0;
@@ -482,7 +482,7 @@
const as_value& tfarg = fn.arg(0); // to find arg
const std::wstring& toFind =
- utf8::decodeCanonicalString(tfarg.to_string_versioned(version),
+ utf8::decodeCanonicalString(tfarg.to_string(version),
version);
size_t start = 0;
@@ -490,7 +490,7 @@
if (fn.nargs >= 2)
{
const as_value& saval = fn.arg(1); // start arg val
- int start_arg = saval.to_int();
+ int start_arg = toInt(saval);
if ( start_arg > 0 ) start = (size_t) start_arg;
else
{
@@ -528,7 +528,7 @@
for (unsigned int i = 0; i < fn.nargs; i++)
{
// Maximum 65535, as with all DisplayObject codes.
- boost::uint16_t c =
static_cast<boost::uint16_t>(fn.arg(i).to_int());
+ boost::uint16_t c = static_cast<boost::uint16_t>(toInt(fn.arg(i)));
// If more than 255, push 'overflow' byte.
if (c > 255)
@@ -548,7 +548,7 @@
for (unsigned int i = 0; i < fn.nargs; i++)
{
- boost::uint16_t c = static_cast<boost::uint16_t>(fn.arg(i).to_int());
+ boost::uint16_t c = static_cast<boost::uint16_t>(toInt(fn.arg(i)));
if (c == 0) break;
wstr.push_back(c);
}
@@ -572,7 +572,7 @@
log_aserror(_("string.charCodeAt needs one argument"));
)
as_value rv;
- rv.set_nan();
+ setNaN(rv);
return rv; // Same as for out-of-range arg
}
@@ -586,7 +586,7 @@
if (index >= wstr.length()) {
as_value rv;
- rv.set_nan();
+ setNaN(rv);
return rv;
}
@@ -604,7 +604,7 @@
if (!checkArgs(fn, 1, 1, "String.charAt()")) return as_value("");
// to_int() makes this safe from overflows.
- const size_t index = static_cast<size_t>(fn.arg(0).to_int());
+ const size_t index = static_cast<size_t>(toInt(fn.arg(0)));
size_t currentIndex = 0;
@@ -730,7 +730,7 @@
string_valueOf(const fn_call& fn)
{
const int version = getSWFVersion(fn);
- return as_value(fn.this_ptr).to_string_versioned(version);
+ return as_value(fn.this_ptr).to_string(version);
}
as_value
@@ -749,7 +749,7 @@
std::string str;
if (fn.nargs) {
- str = fn.arg(0).to_string_versioned(version);
+ str = fn.arg(0).to_string(version);
}
if (!fn.isInstantiation())
@@ -784,7 +784,7 @@
const int version = fn.callerDef ? fn.callerDef->get_version() :
getSWFVersion(fn);
- str = val.to_string_versioned(version);
+ str = val.to_string(version);
return version;
=== modified file 'libcore/asobj/flash/display/BitmapData_as.cpp'
--- a/libcore/asobj/flash/display/BitmapData_as.cpp 2009-12-02 12:30:12
+0000
+++ b/libcore/asobj/flash/display/BitmapData_as.cpp 2009-12-07 12:16:50
+0000
@@ -304,7 +304,7 @@
return as_value();
}
- MovieClip* mc = fn.arg(0).to_sprite();
+ MovieClip* mc = fn.arg(0).toMovieClip();
if (!mc) {
// log error
@@ -364,9 +364,9 @@
obj->get_member(NSV::PROP_WIDTH, &w);
obj->get_member(NSV::PROP_HEIGHT, &h);
- boost::uint32_t color = fn.arg(1).to_int();
+ const boost::uint32_t color = toInt(fn.arg(1));
- ptr->fillRect(x.to_int(), y.to_int(), w.to_int(), h.to_int(), color);
+ ptr->fillRect(toInt(x), toInt(y), toInt(w), toInt(h), color);
return as_value();
}
@@ -411,9 +411,8 @@
}
// TODO: what happens when the pixel is outside the image?
-
- int x = fn.arg(0).to_int();
- int y = fn.arg(1).to_int();
+ const int x = toInt(fn.arg(0));
+ const int y = toInt(fn.arg(1));
return ptr->getPixel(x, y, false);
}
@@ -429,9 +428,8 @@
}
// TODO: what happens when the pixel is outside the image?
-
- int x = fn.arg(0).to_int();
- int y = fn.arg(1).to_int();
+ const int x = toInt(fn.arg(0));
+ const int y = toInt(fn.arg(1));
return ptr->getPixel(x, y, true);
}
@@ -517,7 +515,7 @@
}
// Ignore any transparency here.
- boost::uint32_t color = fn.arg(2).to_int() & 0xffffff;
+ const boost::uint32_t color = toInt(fn.arg(2)) & 0xffffff;
ptr->setPixel(x, y, color);
@@ -541,7 +539,7 @@
}
// TODO: multiply.
- boost::uint32_t color = fn.arg(2).to_int();
+ const boost::uint32_t color = toInt(fn.arg(2));
ptr->setPixel32(x, y, color);
@@ -669,13 +667,13 @@
default:
// log AS coding error
case 4:
- fillColor = fn.arg(3).to_int();
+ fillColor = toInt(fn.arg(3));
case 3:
transparent = fn.arg(2).to_bool();
case 2:
// Is to_int correct?
- height = fn.arg(1).to_int();
- width = fn.arg(0).to_int();
+ height = toInt(fn.arg(1));
+ width = toInt(fn.arg(0));
break;
}
=== modified file 'libcore/asobj/flash/display/MovieClip_as.cpp'
--- a/libcore/asobj/flash/display/MovieClip_as.cpp 2009-12-04 09:20:14
+0000
+++ b/libcore/asobj/flash/display/MovieClip_as.cpp 2009-12-07 12:16:50
+0000
@@ -341,7 +341,7 @@
// Unlike other MovieClip methods, the depth argument of an empty movie
clip
// can be any number. All numbers are converted to an int32_t, and are
valid
// depths even when outside the usual bounds.
- ptr->addDisplayListObject(mc, fn.arg(1).to_int());
+ ptr->addDisplayListObject(mc, toInt(fn.arg(1)));
return as_value(o);
}
@@ -641,7 +641,7 @@
int target_depth = 0;
// movieclip.swapDepth(movieclip)
- if (MovieClip* target_movieclip = fn.arg(0).to_sprite()) {
+ if (MovieClip* target_movieclip = fn.arg(0).toMovieClip()) {
if (movieclip == target_movieclip) {
IF_VERBOSE_ASCODING_ERRORS(
@@ -936,7 +936,7 @@
// TODO: if GET/POST should send variables of *this* movie,
// no matter if the target will be replaced by another movie !!
const MovieClip::VariablesMethod method =
- static_cast<MovieClip::VariablesMethod>(val.to_int());
+ static_cast<MovieClip::VariablesMethod>(toInt(val));
std::string data;
@@ -993,7 +993,7 @@
}
const MovieClip::VariablesMethod method =
- static_cast<MovieClip::VariablesMethod>(val.to_int());
+ static_cast<MovieClip::VariablesMethod>(toInt(val));
movieclip->loadVariables(urlstr, method);
log_debug("MovieClip.loadVariables(%s) - TESTING ", urlstr);
@@ -1101,7 +1101,7 @@
return as_value();
}
- const int depth = fn.arg(0).to_int();
+ const int depth = toInt(fn.arg(0));
DisplayObject* ch = mc->getDisplayObjectAtDepth(depth);
@@ -1161,7 +1161,7 @@
MovieClip::VariablesMethod method =
- static_cast<MovieClip::VariablesMethod>(val.to_int());
+ static_cast<MovieClip::VariablesMethod>(toInt(val));
std::string vars;
@@ -1646,7 +1646,7 @@
"first eight will be discarded"), ss.str());
);
case 8:
- miterLimitFactor = clamp<int>(fn.arg(7).to_int(), 1, 255);
+ miterLimitFactor = clamp<int>(toInt(fn.arg(7)), 1, 255);
case 7:
{
std::string joinStyleStr = fn.arg(6).to_string();
@@ -1725,7 +1725,7 @@
// See pollock.swf for eventual regressions.
// It sets color to a random number from
// 0 to 160000000 (about 10 times more then the max).
- boost::uint32_t rgbval = fn.arg(1).to_int();
+ boost::uint32_t rgbval = toInt(fn.arg(1));
r = boost::uint8_t((rgbval & 0xFF0000) >> 16);
g = boost::uint8_t((rgbval & 0x00FF00) >> 8);
b = boost::uint8_t((rgbval & 0x0000FF) );
@@ -1879,7 +1879,7 @@
if ( fn.nargs > 1 )
{
- a = 255 * clamp<int>(fn.arg(1).to_int(), 0, 100) / 100;
+ a = 255 * clamp<int>(toInt(fn.arg(1)), 0, 100) / 100;
IF_VERBOSE_ASCODING_ERRORS(
if ( fn.nargs > 2 )
{
@@ -2087,10 +2087,10 @@
// Create the gradients vector
// ----------------------------
- size_t ngradients = colors->getMember(NSV::PROP_LENGTH).to_int();
+ size_t ngradients = toInt(colors->getMember(NSV::PROP_LENGTH));
// Check length compatibility of all args
- if ( ngradients != (size_t)alphas->getMember(NSV::PROP_LENGTH).to_int() ||
- ngradients != (size_t)ratios->getMember(NSV::PROP_LENGTH).to_int() )
+ if (ngradients != (size_t)toInt(alphas->getMember(NSV::PROP_LENGTH)) ||
+ ngradients != (size_t)toInt(ratios->getMember(NSV::PROP_LENGTH)))
{
IF_VERBOSE_ASCODING_ERRORS(
std::stringstream ss; fn.dump_args(ss);
@@ -2121,15 +2121,15 @@
string_table::key key = st.find(boost::lexical_cast<std::string>(i));
as_value colVal = colors->getMember(key);
- boost::uint32_t col = colVal.is_number() ? colVal.to_int() : 0;
+ boost::uint32_t col = colVal.is_number() ? toInt(colVal) : 0;
as_value alpVal = alphas->getMember(key);
boost::uint8_t alp = alpVal.is_number() ?
- clamp<int>(alpVal.to_int(), 0, 255) : 0;
+ clamp<int>(toInt(alpVal), 0, 255) : 0;
as_value ratVal = ratios->getMember(key);
boost::uint8_t rat = ratVal.is_number() ?
- clamp<int>(ratVal.to_int(), 0, 255) : 0;
+ clamp<int>(toInt(ratVal), 0, 255) : 0;
rgba color;
color.parseRGB(col);
@@ -2291,7 +2291,7 @@
return as_value();
}
- int depth = fn.arg(1).to_int();
+ int depth = toInt(fn.arg(1));
DisplayObject* bm = new Bitmap(getRoot(fn), 0, bd, ptr);
ptr->attachCharacter(*bm, depth, 0);
=== modified file 'libcore/asobj/flash/display/Stage_as.cpp'
--- a/libcore/asobj/flash/display/Stage_as.cpp 2009-11-18 11:51:35 +0000
+++ b/libcore/asobj/flash/display/Stage_as.cpp 2009-12-08 09:36:43 +0000
@@ -121,28 +121,24 @@
movie_root& m = getRoot(fn);
- if ( fn.nargs == 0 ) // getter
- {
+ if (!fn.nargs) {
return as_value(getScaleModeString(m.getStageScaleMode()));
}
- else // setter
- {
- // Defaults to showAll if the string is invalid.
- movie_root::ScaleMode mode = movie_root::showAll;
-
- const std::string& str = fn.arg(0).to_string();
-
- StringNoCaseEqual noCaseCompare;
-
- if ( noCaseCompare(str, "noScale") ) mode = movie_root::noScale;
- else if ( noCaseCompare(str, "exactFit") ) mode =
movie_root::exactFit;
- else if ( noCaseCompare(str, "noBorder") ) mode =
movie_root::noBorder;
-
- if ( m.getStageScaleMode() == mode ) return as_value(); // nothing to
do
-
- m.setStageScaleMode(mode);
- return as_value();
- }
+
+ // Defaults to showAll if the string is invalid.
+ movie_root::ScaleMode mode = movie_root::showAll;
+
+ const int version = getSWFVersion(fn);
+ const std::string& str = fn.arg(0).to_string(version);
+
+ StringNoCaseEqual noCaseCompare;
+
+ if (noCaseCompare(str, "noScale")) mode = movie_root::noScale;
+ else if (noCaseCompare(str, "exactFit")) mode = movie_root::exactFit;
+ else if (noCaseCompare(str, "noBorder")) mode = movie_root::noBorder;
+
+ m.setStageScaleMode(mode);
+ return as_value();
}
as_value
@@ -187,20 +183,18 @@
{
movie_root& m = getRoot(fn);
- if ( fn.nargs == 0 ) // getter
- {
+ if (!fn.nargs) {
return as_value (m.getStageAlignMode());
}
- else // setter
- {
- const std::string& str = fn.arg(0).to_string();
-
- const short am = stringToStageAlign(str);
-
- m.setStageAlignment(am);
-
- return as_value();
- }
+
+ const int version = getSWFVersion(fn);
+ const std::string& str = fn.arg(0).to_string(version);
+
+ const short am = stringToStageAlign(str);
+
+ m.setStageAlignment(am);
+
+ return as_value();
}
as_value
@@ -234,7 +228,9 @@
StringNoCaseEqual noCaseCompare;
- const std::string& str = fn.arg(0).to_string();
+ const int version = getSWFVersion(fn);
+ const std::string& str = fn.arg(0).to_string(version);
+
if (noCaseCompare(str, "normal")) {
m.setStageDisplayState(movie_root::DISPLAYSTATE_NORMAL);
}
=== modified file 'libcore/asobj/flash/filters/BevelFilter_as.cpp'
--- a/libcore/asobj/flash/filters/BevelFilter_as.cpp 2009-10-22 14:56:18
+0000
+++ b/libcore/asobj/flash/filters/BevelFilter_as.cpp 2009-12-07 08:35:23
+0000
@@ -124,7 +124,7 @@
if (fn.nargs == 0) {
return as_value(ptr->m_highlightColor );
}
- boost::uint32_t sp_highlightColor = fn.arg(0).to_number<boost::uint32_t>
();
+ boost::uint32_t sp_highlightColor = fn.arg(0).to_number ();
ptr->m_highlightColor = sp_highlightColor;
return as_value();
}
@@ -136,7 +136,7 @@
if (fn.nargs == 0) {
return as_value(ptr->m_highlightAlpha );
}
- boost::uint8_t sp_highlightAlpha = fn.arg(0).to_number<boost::uint8_t> ();
+ boost::uint8_t sp_highlightAlpha = fn.arg(0).to_number ();
ptr->m_highlightAlpha = sp_highlightAlpha;
return as_value();
}
@@ -148,7 +148,7 @@
if (fn.nargs == 0) {
return as_value(ptr->m_shadowColor );
}
- boost::uint32_t sp_shadowColor = fn.arg(0).to_number<boost::uint32_t> ();
+ boost::uint32_t sp_shadowColor = fn.arg(0).to_number ();
ptr->m_shadowColor = sp_shadowColor;
return as_value();
}
@@ -160,7 +160,7 @@
if (fn.nargs == 0) {
return as_value(ptr->m_shadowAlpha );
}
- boost::uint8_t sp_shadowAlpha = fn.arg(0).to_number<boost::uint8_t> ();
+ boost::uint8_t sp_shadowAlpha = fn.arg(0).to_number ();
ptr->m_shadowAlpha = sp_shadowAlpha;
return as_value();
}
@@ -172,7 +172,7 @@
if (fn.nargs == 0) {
return as_value(ptr->m_blurX );
}
- float sp_blurX = fn.arg(0).to_number<float> ();
+ float sp_blurX = fn.arg(0).to_number ();
ptr->m_blurX = sp_blurX;
return as_value();
}
@@ -184,7 +184,7 @@
if (fn.nargs == 0) {
return as_value(ptr->m_blurY );
}
- float sp_blurY = fn.arg(0).to_number<float> ();
+ float sp_blurY = fn.arg(0).to_number ();
ptr->m_blurY = sp_blurY;
return as_value();
}
@@ -196,7 +196,7 @@
if (fn.nargs == 0) {
return as_value(ptr->m_strength );
}
- float sp_strength = fn.arg(0).to_number<float> ();
+ float sp_strength = fn.arg(0).to_number ();
ptr->m_strength = sp_strength;
return as_value();
}
@@ -208,7 +208,7 @@
if (fn.nargs == 0) {
return as_value(ptr->m_quality );
}
- boost::uint8_t sp_quality = fn.arg(0).to_number<boost::uint8_t> ();
+ boost::uint8_t sp_quality = fn.arg(0).to_number ();
ptr->m_quality = sp_quality;
return as_value();
}
=== modified file 'libcore/asobj/flash/filters/BlurFilter_as.cpp'
--- a/libcore/asobj/flash/filters/BlurFilter_as.cpp 2009-10-22 14:56:18
+0000
+++ b/libcore/asobj/flash/filters/BlurFilter_as.cpp 2009-12-07 08:35:23
+0000
@@ -67,7 +67,7 @@
if (fn.nargs == 0) {
return as_value(ptr->m_blurX );
}
- float sp_blurX = fn.arg(0).to_number<float> ();
+ float sp_blurX = fn.arg(0).to_number ();
ptr->m_blurX = sp_blurX;
return as_value();
}
@@ -79,7 +79,7 @@
if (fn.nargs == 0) {
return as_value(ptr->m_blurY );
}
- float sp_blurY = fn.arg(0).to_number<float> ();
+ float sp_blurY = fn.arg(0).to_number ();
ptr->m_blurY = sp_blurY;
return as_value();
}
@@ -91,7 +91,7 @@
if (fn.nargs == 0) {
return as_value(ptr->m_quality );
}
- boost::uint8_t sp_quality = fn.arg(0).to_number<boost::uint8_t> ();
+ boost::uint8_t sp_quality = fn.arg(0).to_number ();
ptr->m_quality = sp_quality;
return as_value();
}
=== modified file 'libcore/asobj/flash/filters/DropShadowFilter_as.cpp'
--- a/libcore/asobj/flash/filters/DropShadowFilter_as.cpp 2009-10-22
14:56:18 +0000
+++ b/libcore/asobj/flash/filters/DropShadowFilter_as.cpp 2009-12-07
08:35:23 +0000
@@ -145,7 +145,7 @@
if (fn.nargs == 0) {
return as_value(ptr->m_blurX );
}
- float sp_blurX = fn.arg(0).to_number<float> ();
+ float sp_blurX = fn.arg(0).to_number ();
ptr->m_blurX = sp_blurX;
return as_value();
}
@@ -157,7 +157,7 @@
if (fn.nargs == 0) {
return as_value(ptr->m_blurY );
}
- float sp_blurY = fn.arg(0).to_number<float> ();
+ float sp_blurY = fn.arg(0).to_number ();
ptr->m_blurY = sp_blurY;
return as_value();
}
@@ -169,7 +169,7 @@
if (fn.nargs == 0) {
return as_value(ptr->m_strength );
}
- float sp_strength = fn.arg(0).to_number<float> ();
+ float sp_strength = fn.arg(0).to_number ();
ptr->m_strength = sp_strength;
return as_value();
}
@@ -181,7 +181,7 @@
if (fn.nargs == 0) {
return as_value(ptr->m_quality );
}
- boost::uint8_t sp_quality = fn.arg(0).to_number<boost::uint8_t> ();
+ boost::uint8_t sp_quality = fn.arg(0).to_number ();
ptr->m_quality = sp_quality;
return as_value();
}
=== modified file 'libcore/asobj/flash/filters/GlowFilter_as.cpp'
--- a/libcore/asobj/flash/filters/GlowFilter_as.cpp 2009-10-22 14:56:18
+0000
+++ b/libcore/asobj/flash/filters/GlowFilter_as.cpp 2009-12-07 08:35:23
+0000
@@ -87,7 +87,7 @@
if (fn.nargs == 0) {
return as_value(ptr->m_inner );
}
- boost::uint32_t sp_inner = fn.arg(0).to_number<boost::uint32_t> ();
+ boost::uint32_t sp_inner = fn.arg(0).to_number ();
ptr->m_inner = sp_inner;
return as_value();
}
@@ -99,7 +99,7 @@
if (fn.nargs == 0) {
return as_value(ptr->m_color );
}
- float sp_color = fn.arg(0).to_number<float> ();
+ float sp_color = fn.arg(0).to_number ();
ptr->m_color = sp_color;
return as_value();
}
@@ -111,7 +111,7 @@
if (fn.nargs == 0) {
return as_value(ptr->m_alpha );
}
- float sp_alpha = fn.arg(0).to_number<float> ();
+ float sp_alpha = fn.arg(0).to_number ();
ptr->m_alpha = sp_alpha;
return as_value();
}
@@ -123,7 +123,7 @@
if (fn.nargs == 0) {
return as_value(ptr->m_blurX );
}
- float sp_blurX = fn.arg(0).to_number<float> ();
+ float sp_blurX = fn.arg(0).to_number ();
ptr->m_blurX = sp_blurX;
return as_value();
}
@@ -135,7 +135,7 @@
if (fn.nargs == 0) {
return as_value(ptr->m_blurY );
}
- float sp_blurY = fn.arg(0).to_number<float> ();
+ float sp_blurY = fn.arg(0).to_number ();
ptr->m_blurY = sp_blurY;
return as_value();
}
@@ -147,7 +147,7 @@
if (fn.nargs == 0) {
return as_value(ptr->m_strength );
}
- float sp_strength = fn.arg(0).to_number<float> ();
+ float sp_strength = fn.arg(0).to_number ();
ptr->m_strength = sp_strength;
return as_value();
}
@@ -159,7 +159,7 @@
if (fn.nargs == 0) {
return as_value(ptr->m_quality );
}
- boost::uint8_t sp_quality = fn.arg(0).to_number<boost::uint8_t> ();
+ boost::uint8_t sp_quality = fn.arg(0).to_number ();
ptr->m_quality = sp_quality;
return as_value();
}
=== modified file 'libcore/asobj/flash/filters/GradientBevelFilter_as.cpp'
--- a/libcore/asobj/flash/filters/GradientBevelFilter_as.cpp 2009-10-22
14:56:18 +0000
+++ b/libcore/asobj/flash/filters/GradientBevelFilter_as.cpp 2009-12-07
08:35:23 +0000
@@ -145,7 +145,7 @@
if (fn.nargs == 0) {
return as_value(ptr->m_blurX );
}
- float sp_blurX = fn.arg(0).to_number<float> ();
+ float sp_blurX = fn.arg(0).to_number ();
ptr->m_blurX = sp_blurX;
return as_value();
}
@@ -157,7 +157,7 @@
if (fn.nargs == 0) {
return as_value(ptr->m_blurY );
}
- float sp_blurY = fn.arg(0).to_number<float> ();
+ float sp_blurY = fn.arg(0).to_number ();
ptr->m_blurY = sp_blurY;
return as_value();
}
@@ -169,7 +169,7 @@
if (fn.nargs == 0) {
return as_value(ptr->m_strength );
}
- float sp_strength = fn.arg(0).to_number<float> ();
+ float sp_strength = fn.arg(0).to_number ();
ptr->m_strength = sp_strength;
return as_value();
}
@@ -181,7 +181,7 @@
if (fn.nargs == 0) {
return as_value(ptr->m_quality );
}
- boost::uint8_t sp_quality = fn.arg(0).to_number<boost::uint8_t> ();
+ boost::uint8_t sp_quality = fn.arg(0).to_number ();
ptr->m_quality = sp_quality;
return as_value();
}
=== modified file 'libcore/asobj/flash/filters/GradientGlowFilter_as.cpp'
--- a/libcore/asobj/flash/filters/GradientGlowFilter_as.cpp 2009-10-22
14:56:18 +0000
+++ b/libcore/asobj/flash/filters/GradientGlowFilter_as.cpp 2009-12-07
08:35:23 +0000
@@ -147,7 +147,7 @@
if (fn.nargs == 0) {
return as_value(ptr->m_blurX );
}
- float sp_blurX = fn.arg(0).to_number<float> ();
+ float sp_blurX = fn.arg(0).to_number ();
ptr->m_blurX = sp_blurX;
return as_value();
}
@@ -159,7 +159,7 @@
if (fn.nargs == 0) {
return as_value(ptr->m_blurY );
}
- float sp_blurY = fn.arg(0).to_number<float> ();
+ float sp_blurY = fn.arg(0).to_number ();
ptr->m_blurY = sp_blurY;
return as_value();
}
@@ -171,7 +171,7 @@
if (fn.nargs == 0) {
return as_value(ptr->m_strength );
}
- float sp_strength = fn.arg(0).to_number<float> ();
+ float sp_strength = fn.arg(0).to_number ();
ptr->m_strength = sp_strength;
return as_value();
}
@@ -183,7 +183,7 @@
if (fn.nargs == 0) {
return as_value(ptr->m_quality );
}
- boost::uint8_t sp_quality = fn.arg(0).to_number<boost::uint8_t> ();
+ boost::uint8_t sp_quality = fn.arg(0).to_number ();
ptr->m_quality = sp_quality;
return as_value();
}
=== modified file 'libcore/asobj/flash/geom/ColorTransform_as.cpp'
--- a/libcore/asobj/flash/geom/ColorTransform_as.cpp 2009-12-02 12:30:12
+0000
+++ b/libcore/asobj/flash/geom/ColorTransform_as.cpp 2009-12-08 08:47:03
+0000
@@ -270,14 +270,14 @@
const int version = getSWFVersion(fn);
- ss << "(redMultiplier=" << rm.to_string_versioned(version) << ", "
- << "greenMultiplier=" << gm.to_string_versioned(version) << ", "
- << "blueMultiplier=" << bm.to_string_versioned(version) << ", "
- << "alphaMultiplier=" << am.to_string_versioned(version) << ", "
- << "redOffset=" << ro.to_string_versioned(version) << ", "
- << "greenOffset=" << go.to_string_versioned(version) << ", "
- << "blueOffset=" << bo.to_string_versioned(version) << ", "
- << "alphaOffset=" << ao.to_string_versioned(version) << ")";
+ ss << "(redMultiplier=" << rm.to_string(version) << ", "
+ << "greenMultiplier=" << gm.to_string(version) << ", "
+ << "blueMultiplier=" << bm.to_string(version) << ", "
+ << "alphaMultiplier=" << am.to_string(version) << ", "
+ << "redOffset=" << ro.to_string(version) << ", "
+ << "greenOffset=" << go.to_string(version) << ", "
+ << "blueOffset=" << bo.to_string(version) << ", "
+ << "alphaOffset=" << ao.to_string(version) << ")";
return as_value(ss.str());
@@ -309,7 +309,7 @@
// Setter
- boost::uint32_t rgb = fn.arg(0).to_int();
+ boost::uint32_t rgb = toInt(fn.arg(0));
relay->setRedOffset((rgb & 0xFF0000) >> 16);
relay->setGreenOffset((rgb & 0x00FF00) >> 8);
relay->setBlueOffset(rgb & 0x0000FF);
=== modified file 'libcore/asobj/flash/geom/Matrix_as.cpp'
--- a/libcore/asobj/flash/geom/Matrix_as.cpp 2009-12-02 12:30:12 +0000
+++ b/libcore/asobj/flash/geom/Matrix_as.cpp 2009-12-08 08:47:03 +0000
@@ -666,12 +666,12 @@
const int version = getSWFVersion(fn);
- ss << "(a=" << a.to_string_versioned(version) << ", "
- "b="<< b.to_string_versioned(version) << ", "
- "c="<< c.to_string_versioned(version) << ", "
- "d="<< d.to_string_versioned(version) << ", "
- "tx="<< tx.to_string_versioned(version) << ", "
- "ty="<< ty.to_string_versioned(version) << ")";
+ ss << "(a=" << a.to_string(version) << ", "
+ "b="<< b.to_string(version) << ", "
+ "c="<< c.to_string(version) << ", "
+ "d="<< d.to_string(version) << ", "
+ "tx="<< tx.to_string(version) << ", "
+ "ty="<< ty.to_string(version) << ")";
return as_value(ss.str());
}
=== modified file 'libcore/asobj/flash/geom/Point_as.cpp'
--- a/libcore/asobj/flash/geom/Point_as.cpp 2009-12-02 12:30:12 +0000
+++ b/libcore/asobj/flash/geom/Point_as.cpp 2009-12-08 08:47:03 +0000
@@ -375,8 +375,8 @@
int version = getSWFVersion(fn);
std::stringstream ss;
- ss << "(x=" << x.to_string_versioned(version)
- << ", y=" << y.to_string_versioned(version)
+ ss << "(x=" << x.to_string(version)
+ << ", y=" << y.to_string(version)
<< ")";
return as_value(ss.str());
=== modified file 'libcore/asobj/flash/geom/Rectangle_as.cpp'
--- a/libcore/asobj/flash/geom/Rectangle_as.cpp 2009-12-02 12:30:12 +0000
+++ b/libcore/asobj/flash/geom/Rectangle_as.cpp 2009-12-08 08:47:03 +0000
@@ -354,10 +354,12 @@
ptr->get_member(NSV::PROP_HEIGHT, &h);
std::stringstream ss;
- ss << "(x=" << x.to_string()
- << ", y=" << y.to_string()
- << ", w=" << w.to_string()
- << ", h=" << h.to_string()
+ const int version = getSWFVersion(fn);
+
+ ss << "(x=" << x.to_string(version)
+ << ", y=" << y.to_string(version)
+ << ", w=" << w.to_string(version)
+ << ", h=" << h.to_string(version)
<< ")";
return as_value(ss.str());
=== modified file 'libcore/asobj/flash/media/Microphone_as.cpp'
--- a/libcore/asobj/flash/media/Microphone_as.cpp 2009-12-04 09:20:14
+0000
+++ b/libcore/asobj/flash/media/Microphone_as.cpp 2009-12-07 12:16:50
+0000
@@ -295,8 +295,7 @@
return as_value();
}
- const boost::int32_t gain =
- clamp<boost::int32_t>(fn.arg(0).to_int(), 0, 100);
+ const boost::int32_t gain = clamp<boost::int32_t>(toInt(fn.arg(0)), 0,
100);
ptr->setGain(gain);
return as_value();
}
@@ -311,7 +310,7 @@
log_error("Microphone.setRate: wrong number of parameters passed");
return as_value();
}
- ptr->setRate(fn.arg(0).to_int());
+ ptr->setRate(toInt(fn.arg(0)));
return as_value();
}
@@ -453,7 +452,7 @@
if (numargs > 1) {
// If it's less than 0, it's set to 0.
- const int timeout = std::max<boost::int32_t>(fn.arg(1).to_int(), 0);
+ const int timeout = std::max<boost::int32_t>(toInt(fn.arg(1)), 0);
ptr->setSilenceTimeout(timeout);
}
return as_value();
=== modified file 'libcore/asobj/flash/net/NetConnection_as.cpp'
--- a/libcore/asobj/flash/net/NetConnection_as.cpp 2009-11-18 11:51:35
+0000
+++ b/libcore/asobj/flash/net/NetConnection_as.cpp 2009-12-08 08:47:03
+0000
@@ -1148,7 +1148,7 @@
const as_value& uri = fn.arg(0);
const VM& vm = getVM(fn);
- const std::string& uriStr = uri.to_string_versioned(vm.getSWFVersion());
+ const std::string& uriStr = uri.to_string(vm.getSWFVersion());
// This is always set without validification.
ptr->setURI(uriStr);
=== modified file 'libcore/asobj/flash/net/SharedObject_as.cpp'
--- a/libcore/asobj/flash/net/SharedObject_as.cpp 2009-12-04 09:20:14
+0000
+++ b/libcore/asobj/flash/net/SharedObject_as.cpp 2009-12-08 08:47:03
+0000
@@ -865,7 +865,7 @@
#if 0
const as_value& uri = fn.arg(1);
const VM& vm = getVM(fn);
- const std::string& uriStr =
uri.to_string_versioned(vm.getSWFVersion());
+ const std::string& uriStr = uri.to_string(vm.getSWFVersion());
#endif
}
@@ -952,7 +952,7 @@
int space = 0;
if (fn.nargs) {
- space = fn.arg(0).to_int();
+ space = toInt(fn.arg(0));
}
/// If there is no data member, returns undefined.
@@ -970,7 +970,7 @@
as_value objNameVal;
if (fn.nargs > 0) objNameVal = fn.arg(0);
- const std::string objName = objNameVal.to_string_versioned(swfVersion);
+ const std::string objName = objNameVal.to_string(swfVersion);
if (objName.empty()) {
IF_VERBOSE_ASCODING_ERRORS(
std::ostringstream ss;
@@ -986,7 +986,7 @@
std::string root;
if (fn.nargs > 1)
{
- root = fn.arg(1).to_string_versioned(swfVersion);
+ root = fn.arg(1).to_string(swfVersion);
}
log_debug("SO name:%s, root:%s", objName, root);
@@ -1012,7 +1012,7 @@
objNameVal = fn.arg(0);
}
- std::string objName = objNameVal.to_string_versioned(swfVersion);
+ std::string objName = objNameVal.to_string(swfVersion);
if (objName.empty()) {
IF_VERBOSE_ASCODING_ERRORS(
std::ostringstream ss;
@@ -1036,8 +1036,8 @@
// cases and just checking the argument type here.
std::string persistence;
if (fn.nargs > 1) {
- root = fn.arg(1).to_string_versioned(swfVersion);
- persistence = fn.arg(2).to_string_versioned(swfVersion);
+ root = fn.arg(1).to_string(swfVersion);
+ persistence = fn.arg(2).to_string(swfVersion);
}
log_debug("SO name:%s, root:%s, persistence: %s", objName, root,
persistence);
=== modified file 'libcore/asobj/flash/text/TextFormat_as.cpp'
--- a/libcore/asobj/flash/text/TextFormat_as.cpp 2009-12-04 09:20:14
+0000
+++ b/libcore/asobj/flash/text/TextFormat_as.cpp 2009-12-07 12:16:50
+0000
@@ -185,13 +185,13 @@
default:
log_error(_("Too many args (%d) passed to TextFormat"), args);
case 13:
- tf->leadingSet(pixelsToTwips(fn.arg(12).to_int()));
+ tf->leadingSet(pixelsToTwips(toInt(fn.arg(12))));
case 12:
- tf->indentSet(pixelsToTwips(fn.arg(11).to_int()));
+ tf->indentSet(pixelsToTwips(toInt(fn.arg(11))));
case 11:
- tf->rightMarginSet(pixelsToTwips(fn.arg(10).to_int()));
+ tf->rightMarginSet(pixelsToTwips(toInt(fn.arg(10))));
case 10:
- tf->leftMarginSet(pixelsToTwips(fn.arg(9).to_int()));
+ tf->leftMarginSet(pixelsToTwips(toInt(fn.arg(9))));
case 9:
tf->alignSet(fn.arg(8).to_string());
case 8:
@@ -207,11 +207,11 @@
case 3:
{
rgba col;
- col.parseRGB(fn.arg(2).to_int());
+ col.parseRGB(toInt(fn.arg(2)));
tf->colorSet(col);
}
case 2:
- tf->sizeSet(pixelsToTwips(fn.arg(1).to_int()));
+ tf->sizeSet(pixelsToTwips(toInt(fn.arg(1))));
case 1:
tf->fontSet(fn.arg(0).to_string());
break;
@@ -330,7 +330,7 @@
}
else // setter
{
- relay->blockIndentSet(pixelsToTwips(fn.arg(0).to_int()));
+ relay->blockIndentSet(pixelsToTwips(toInt(fn.arg(0))));
}
return ret;
@@ -350,7 +350,7 @@
}
else // setter
{
- relay->leadingSet(pixelsToTwips(fn.arg(0).to_int()));
+ relay->leadingSet(pixelsToTwips(toInt(fn.arg(0))));
}
return ret;
@@ -370,7 +370,7 @@
}
else // setter
{
- relay->indentSet(pixelsToTwips(fn.arg(0).to_int()));
+ relay->indentSet(pixelsToTwips(toInt(fn.arg(0))));
}
return ret;
@@ -390,7 +390,7 @@
}
else // setter
{
- relay->rightMarginSet(pixelsToTwips(fn.arg(0).to_int()));
+ relay->rightMarginSet(pixelsToTwips(toInt(fn.arg(0))));
}
return ret;
@@ -412,7 +412,7 @@
}
else // setter
{
- relay->leftMarginSet(pixelsToTwips(fn.arg(0).to_int()));
+ relay->leftMarginSet(pixelsToTwips(toInt(fn.arg(0))));
}
return ret;
@@ -555,7 +555,7 @@
else // setter
{
rgba newcolor;
- newcolor.parseRGB(fn.arg(0).to_int());
+ newcolor.parseRGB(toInt(fn.arg(0)));
relay->colorSet(newcolor);
}
@@ -576,7 +576,7 @@
}
else // setter
{
- relay->sizeSet(pixelsToTwips(fn.arg(0).to_int()));
+ relay->sizeSet(pixelsToTwips(toInt(fn.arg(0))));
}
return ret;
=== modified file 'libcore/asobj/flash/text/TextSnapshot_as.cpp'
--- a/libcore/asobj/flash/text/TextSnapshot_as.cpp 2009-11-19 07:58:46
+0000
+++ b/libcore/asobj/flash/text/TextSnapshot_as.cpp 2009-12-07 12:16:50
+0000
@@ -501,8 +501,8 @@
return as_value();
}
- size_t start = std::max<boost::int32_t>(0, fn.arg(0).to_int());
- size_t end = std::max<boost::int32_t>(start + 1, fn.arg(1).to_int());
+ size_t start = std::max<boost::int32_t>(0, toInt(fn.arg(0)));
+ size_t end = std::max<boost::int32_t>(start + 1, toInt(fn.arg(1)));
Global_as& gl = getGlobal(fn);
as_object* ri = gl.createArray();;
@@ -526,7 +526,7 @@
return as_value();
}
- boost::int32_t start = fn.arg(0).to_int();
+ boost::int32_t start = toInt(fn.arg(0));
const std::string& text = fn.arg(1).to_string();
/// Yes, the pp is case-insensitive by default. We don't write
@@ -565,8 +565,8 @@
return as_value();
}
- size_t start = std::max<boost::int32_t>(0, fn.arg(0).to_int());
- size_t end = std::max<boost::int32_t>(start + 1, fn.arg(1).to_int());
+ size_t start = std::max<boost::int32_t>(0, toInt(fn.arg(0)));
+ size_t end = std::max<boost::int32_t>(start + 1, toInt(fn.arg(1)));
return as_value(ts->getSelected(start, end));
}
@@ -604,8 +604,8 @@
return as_value();
}
- boost::int32_t start = fn.arg(0).to_int();
- boost::int32_t end = fn.arg(1).to_int();
+ boost::int32_t start = toInt(fn.arg(0));
+ boost::int32_t end = toInt(fn.arg(1));
const bool newline = (fn.nargs > 2) ? fn.arg(2).to_bool() : false;
@@ -649,8 +649,8 @@
return as_value();
}
- size_t start = std::max<boost::int32_t>(0, fn.arg(0).to_int());
- size_t end = std::max<boost::int32_t>(start, fn.arg(1).to_int());
+ size_t start = std::max<boost::int32_t>(0, toInt(fn.arg(0)));
+ size_t end = std::max<boost::int32_t>(start, toInt(fn.arg(1)));
bool selected = (fn.nargs > 2) ? fn.arg(2).to_bool() : true;
@@ -664,7 +664,7 @@
{
as_object* ptr = ensure<ValidThis>(fn);
- MovieClip* mc = (fn.nargs == 1) ? fn.arg(0).to_sprite() : 0;
+ MovieClip* mc = (fn.nargs == 1) ? fn.arg(0).toMovieClip() : 0;
ptr->setRelay(new TextSnapshot_as(mc));
return as_value();
=== modified file 'libcore/asobj/flash/ui/Keyboard_as.cpp'
--- a/libcore/asobj/flash/ui/Keyboard_as.cpp 2009-11-18 11:51:35 +0000
+++ b/libcore/asobj/flash/ui/Keyboard_as.cpp 2009-12-07 12:16:50 +0000
@@ -77,7 +77,7 @@
return as_value();
}
- const int keycode = fn.arg(0).to_int();
+ const int keycode = toInt(fn.arg(0));
if (keycode < 0 || keycode >= key::KEYCOUNT) {
// AS coding error !
IF_VERBOSE_ASCODING_ERRORS(
=== modified file 'libcore/asobj/flash/xml/XMLDocument_as.cpp'
--- a/libcore/asobj/flash/xml/XMLDocument_as.cpp 2009-12-04 09:20:14
+0000
+++ b/libcore/asobj/flash/xml/XMLDocument_as.cpp 2009-12-08 09:36:43
+0000
@@ -64,13 +64,13 @@
as_value xml_loaded(const fn_call& fn);
as_value xml_status(const fn_call& fn);
- bool textAfterWhitespace(const std::string& xml,
- std::string::const_iterator& it);
- bool textMatch(const std::string& xml, std::string::const_iterator& it,
+ typedef std::string::const_iterator xml_iterator;
+
+ bool textAfterWhitespace(xml_iterator& it, xml_iterator end);
+ bool textMatch(xml_iterator& it, xml_iterator end,
const std::string& match, bool advance = true);
- bool parseNodeWithTerminator(const std::string& xml,
- std::string::const_iterator& it, const std::string& terminator,
- std::string& content);
+ bool parseNodeWithTerminator( xml_iterator& it, xml_iterator end,
+ const std::string& terminator, std::string& content);
typedef std::map<std::string, std::string> Entities;
@@ -181,26 +181,20 @@
typedef std::map<std::string, std::string, StringNoCaseLessThan>
Attributes;
- void parseTag(XMLNode_as*& node, const std::string& xml,
- std::string::const_iterator& it);
-
- void parseAttribute(XMLNode_as* node, const std::string& xml,
- std::string::const_iterator& it, Attributes& attributes);
-
- void parseDocTypeDecl(const std::string& xml,
- std::string::const_iterator& it);
-
- void parseText(XMLNode_as* node, const std::string& xml,
- std::string::const_iterator& it);
-
- void parseXMLDecl(const std::string& xml,
- std::string::const_iterator& it);
-
- void parseComment(XMLNode_as* node, const std::string& xml,
- std::string::const_iterator& it);
-
- void parseCData(XMLNode_as* node, const std::string& xml,
- std::string::const_iterator& it);
+ void parseTag(XMLNode_as*& node, xml_iterator& it, xml_iterator end);
+
+ void parseAttribute(XMLNode_as* node, xml_iterator& it,
+ xml_iterator end, Attributes& attributes);
+
+ void parseDocTypeDecl( xml_iterator& it, xml_iterator end);
+
+ void parseText(XMLNode_as* node, xml_iterator& it, xml_iterator end);
+
+ void parseXMLDecl(xml_iterator& it, xml_iterator end);
+
+ void parseComment(XMLNode_as* node, xml_iterator& it, xml_iterator end);
+
+ void parseCData(XMLNode_as* node, xml_iterator& it, xml_iterator end);
/// Clear all properties.
//
@@ -268,20 +262,20 @@
}
void
-XMLDocument_as::parseAttribute(XMLNode_as* node, const std::string& xml,
- std::string::const_iterator& it, Attributes& attributes)
+XMLDocument_as::parseAttribute(XMLNode_as* node, xml_iterator& it,
+ const xml_iterator end, Attributes& attributes)
{
const std::string terminators("\r\t\n >=");
- std::string::const_iterator end = std::find_first_of(it, xml.end(),
+ xml_iterator ourend = std::find_first_of(it, end,
terminators.begin(), terminators.end());
- if (end == xml.end()) {
+ if (ourend == end) {
_status = XML_UNTERMINATED_ELEMENT;
return;
}
- std::string name(it, end);
+ std::string name(it, ourend);
if (name.empty()) {
_status = XML_UNTERMINATED_ELEMENT;
@@ -289,11 +283,11 @@
}
// Point iterator to the DisplayObject after the name.
- it = end;
+ it = ourend;
// Skip any whitespace before the '='. If we reach the end of the string
// or don't find an '=', it's a parser error.
- if (!textAfterWhitespace(xml, it) || *it != '=') {
+ if (!textAfterWhitespace(it, end) || *it != '=') {
_status = XML_UNTERMINATED_ELEMENT;
return;
}
@@ -303,7 +297,7 @@
// Skip any whitespace. If we reach the end of the string, or don't find
// a " or ', it's a parser error.
- if (!textAfterWhitespace(xml, it) || (*it != '"' && *it != '\'')) {
+ if (!textAfterWhitespace(it, end) || (*it != '"' && *it != '\'')) {
_status = XML_UNTERMINATED_ELEMENT;
return;
}
@@ -312,29 +306,26 @@
// as long as it's not escaped. We begin one after the present position,
// which should be the opening DisplayObject. We want to remember what the
// iterator is pointing to for a while, so don't advance it.
- end = it;
+ ourend = it;
do {
- ++end;
- end = std::find(end, xml.end(), *it);
- } while (end != xml.end() && *(end - 1) == '\\');
+ ++ourend;
+ ourend = std::find(ourend, end, *it);
+ } while (ourend != end && *(ourend - 1) == '\\');
- if (end == xml.end()) {
+ if (ourend == end) {
_status = XML_UNTERMINATED_ATTRIBUTE;
return;
}
++it;
- std::string value(it, end);
+ std::string value(it, ourend);
// Replace entities in the value.
unescapeXML(value);
- //log_debug("adding attribute to node %s: %s, %s", node->nodeName(),
- // name, value);
-
- // We've already checked that end != xml.end(), so we can advance at
+ // We've already checked that ourend != end, so we can advance at
// least once.
- it = end;
+ it = ourend;
// Advance past the last attribute DisplayObject
++it;
@@ -355,12 +346,11 @@
/// Parse and set the docTypeDecl. This is stored without any validation and
/// with the same case as in the parsed XML.
void
-XMLDocument_as::parseDocTypeDecl(const std::string& xml,
- std::string::const_iterator& it)
+XMLDocument_as::parseDocTypeDecl(xml_iterator& it, const xml_iterator end)
{
- std::string::const_iterator end;
- std::string::const_iterator current = it;
+ xml_iterator ourend;
+ xml_iterator current = it;
std::string::size_type count = 1;
@@ -368,32 +358,32 @@
while (count) {
// Find the next closing bracket after the current position.
- end = std::find(current, xml.end(), '>');
- if (end == xml.end()) {
+ ourend = std::find(current, end, '>');
+ if (ourend == end) {
_status = XML_UNTERMINATED_DOCTYPE_DECL;
return;
}
--count;
// Count any opening brackets in between.
- count += std::count(current, end, '<');
- current = end;
+ count += std::count(current, ourend, '<');
+ current = ourend;
++current;
}
- const std::string content(it, end);
+ const std::string content(it, ourend);
std::ostringstream os;
os << '<' << content << '>';
_docTypeDecl = os.str();
- it = end + 1;
+ it = ourend + 1;
}
void
-XMLDocument_as::parseXMLDecl(const std::string& xml,
std::string::const_iterator& it)
+XMLDocument_as::parseXMLDecl(xml_iterator& it, const xml_iterator end)
{
std::string content;
- if (!parseNodeWithTerminator(xml, it, "?>", content))
+ if (!parseNodeWithTerminator(it, end, "?>", content))
{
_status = XML_UNTERMINATED_XML_DECL;
return;
@@ -409,10 +399,9 @@
// The iterator should be pointing to the first char after the '<'
void
-XMLDocument_as::parseTag(XMLNode_as*& node, const std::string& xml,
- std::string::const_iterator& it)
+XMLDocument_as::parseTag(XMLNode_as*& node, xml_iterator& it,
+ const xml_iterator end)
{
- //log_debug("Processing node: %s", node->nodeName());
bool closing = (*it == '/');
if (closing) ++it;
@@ -420,11 +409,11 @@
// These are for terminating the tag name, not (necessarily) the tag.
const std::string terminators("\r\n\t >");
- std::string::const_iterator endName = std::find_first_of(it, xml.end(),
- terminators.begin(), terminators.end());
+ xml_iterator endName = std::find_first_of(it, end, terminators.begin(),
+ terminators.end());
// Check that one of the terminators was found; otherwise it's malformed.
- if (endName == xml.end()) {
+ if (endName == end) {
_status = XML_UNTERMINATED_ELEMENT;
return;
}
@@ -451,11 +440,10 @@
childNode->nodeNameSet(tagName);
childNode->nodeTypeSet(Element);
- //log_debug("created childNode with name %s", childNode->nodeName());
// Skip to the end of any whitespace after the tag name
it = endName;
- if (!textAfterWhitespace(xml, it)) {
+ if (!textAfterWhitespace(it, end)) {
_status = XML_UNTERMINATED_ELEMENT;
return;
}
@@ -464,16 +452,16 @@
// '>'
// Attributes are added in reverse order and without any duplicates.
Attributes attributes;
- while (it != xml.end() && *it != '>' && _status == XML_OK)
+ while (it != end && *it != '>' && _status == XML_OK)
{
- if (xml.end() - it > 1 && std::equal(it, it + 2, "/>")) break;
+ if (end - it > 1 && std::equal(it, it + 2, "/>")) break;
// This advances the iterator
- parseAttribute(childNode, xml, it, attributes);
+ parseAttribute(childNode, it, end, attributes);
// Skip any whitespace. If we reach the end of the string,
// it's malformed.
- if (!textAfterWhitespace(xml, it)) {
+ if (!textAfterWhitespace(it, end)) {
_status = XML_UNTERMINATED_ELEMENT;
return;
}
@@ -498,10 +486,9 @@
// If we reach here, this is a closing tag.
- it = std::find(endName, xml.end(), '>');
+ it = std::find(endName, end, '>');
- if (it == xml.end())
- {
+ if (it == end) {
_status = XML_UNTERMINATED_ELEMENT;
return;
}
@@ -532,13 +519,13 @@
}
void
-XMLDocument_as::parseText(XMLNode_as* node, const std::string& xml,
- std::string::const_iterator& it)
+XMLDocument_as::parseText(XMLNode_as* node, xml_iterator& it,
+ const xml_iterator end)
{
- std::string::const_iterator end = std::find(it, xml.end(), '<');
- std::string content(it, end);
+ xml_iterator ourend = std::find(it, end, '<');
+ std::string content(it, ourend);
- it = end;
+ it = ourend;
if (ignoreWhite() &&
content.find_first_not_of("\t\r\n ") == std::string::npos) return;
@@ -553,34 +540,29 @@
childNode->nodeValueSet(content);
node->appendChild(childNode);
- //log_debug("appended text node: %s", content);
}
-
-
void
-XMLDocument_as::parseComment(XMLNode_as* /*node*/, const std::string& xml,
- std::string::const_iterator& it)
+XMLDocument_as::parseComment(XMLNode_as* /*node*/, xml_iterator& it,
+ const xml_iterator end)
{
- //log_debug("discarding comment node");
std::string content;
- if (!parseNodeWithTerminator(xml, it, "-->", content)) {
+ if (!parseNodeWithTerminator(it, end, "-->", content)) {
_status = XML_UNTERMINATED_COMMENT;
return;
}
// Comments are discarded at least up to SWF8
-
}
void
-XMLDocument_as::parseCData(XMLNode_as* node, const std::string& xml,
- std::string::const_iterator& it)
+XMLDocument_as::parseCData(XMLNode_as* node, xml_iterator& it,
+ const xml_iterator end)
{
std::string content;
- if (!parseNodeWithTerminator(xml, it, "]]>", content)) {
+ if (!parseNodeWithTerminator(it, end, "]]>", content)) {
_status = XML_UNTERMINATED_CDATA;
return;
}
@@ -606,37 +588,38 @@
// Clear current data
clear();
- std::string::const_iterator it = xml.begin();
+ xml_iterator it = xml.begin();
+ const xml_iterator end = xml.end();
XMLNode_as* node = this;
- while (it != xml.end() && _status == XML_OK)
+ while (it != end && _status == XML_OK)
{
if (*it == '<')
{
++it;
- if (textMatch(xml, it, "!DOCTYPE", false))
+ if (textMatch(it, end, "!DOCTYPE", false))
{
// We should not advance past the DOCTYPE label, as
// the case is preserved.
- parseDocTypeDecl(xml, it);
+ parseDocTypeDecl(it, end);
}
- else if (textMatch(xml, it, "?xml", false))
+ else if (textMatch(it, end, "?xml", false))
{
// We should not advance past the xml label, as
// the case is preserved.
- parseXMLDecl(xml, it);
- }
- else if (textMatch(xml, it, "!--"))
- {
- parseComment(node, xml, it);
- }
- else if (textMatch(xml, it, "![CDATA["))
- {
- parseCData(node, xml, it);
- }
- else parseTag(node, xml, it);
+ parseXMLDecl(it, end);
+ }
+ else if (textMatch(it, end, "!--"))
+ {
+ parseComment(node, it, end);
+ }
+ else if (textMatch(it, end, "![CDATA["))
+ {
+ parseCData(node, it, end);
+ }
+ else parseTag(node, it, end);
}
- else parseText(node, xml, it);
+ else parseText(node, it, end);
}
// If everything parsed correctly, check that we've got back to the
@@ -758,7 +741,7 @@
as_object* obj = ensure<ValidThis>(fn);
- if (fn.nargs > 0) {
+ if (fn.nargs && !fn.arg(0).is_undefined()) {
// Copy constructor clones nodes.
if (fn.arg(0).is_object()) {
@@ -771,18 +754,12 @@
}
}
- const std::string& xml_in = fn.arg(0).to_string();
- if (xml_in.empty()) {
- IF_VERBOSE_ASCODING_ERRORS(
- log_aserror(_("First arg given to XML constructor (%s) "
- "evaluates to the empty string"), fn.arg(0));
- );
- }
- else {
- obj->setRelay(new XMLDocument_as(*obj, xml_in));
- attachXMLProperties(*obj);
- return as_value();
- }
+ const int version = getSWFVersion(fn);
+ const std::string& xml_in = fn.arg(0).to_string(version);
+ // It doesn't matter if the string is empty.
+ obj->setRelay(new XMLDocument_as(*obj, xml_in));
+ attachXMLProperties(*obj);
+ return as_value();
}
obj->setRelay(new XMLDocument_as(*obj));
@@ -1000,12 +977,11 @@
/// DisplayObjects left or if there is no match. If there is a match, and
advance
/// is not false, the iterator points to the DisplayObject after the match.
bool
-textMatch(const std::string& xml, std::string::const_iterator& it,
+textMatch(xml_iterator& it, const xml_iterator end,
const std::string& match, bool advance)
{
const std::string::size_type len = match.length();
- const std::string::const_iterator end = xml.end();
if (static_cast<size_t>(end - it) < len) return false;
@@ -1021,11 +997,11 @@
/// @return true if there is text after the whitespace, false if we
/// reach the end of the string.
bool
-textAfterWhitespace(const std::string& xml, std::string::const_iterator& it)
+textAfterWhitespace(xml_iterator& it, const xml_iterator end)
{
const std::string whitespace("\r\t\n ");
- while (it != xml.end() && whitespace.find(*it) != std::string::npos) ++it;
- return (it != xml.end());
+ while (it != end && whitespace.find(*it) != std::string::npos) ++it;
+ return (it != end);
}
/// Parse a complete node up to a specified terminator.
@@ -1039,19 +1015,18 @@
/// the tag.
/// @param xml The complete XML string.
bool
-parseNodeWithTerminator(const std::string& xml,
- std::string::const_iterator& it, const std::string& terminator,
- std::string& content)
+parseNodeWithTerminator( xml_iterator& it, const xml_iterator end,
+ const std::string& terminator, std::string& content)
{
- std::string::const_iterator end = std::search(it, xml.end(),
- terminator.begin(), terminator.end());
+ xml_iterator ourend = std::search(it, end, terminator.begin(),
+ terminator.end());
- if (end == xml.end()) {
+ if (ourend == end) {
return false;
}
- content = std::string(it, end);
- it = end + terminator.length();
+ content = std::string(it, ourend);
+ it = ourend + terminator.length();
return true;
}
=== modified file 'libcore/asobj/flash/xml/XMLNode_as.cpp'
--- a/libcore/asobj/flash/xml/XMLNode_as.cpp 2009-12-04 09:20:14 +0000
+++ b/libcore/asobj/flash/xml/XMLNode_as.cpp 2009-12-07 12:16:50 +0000
@@ -562,7 +562,7 @@
}
std::auto_ptr<XMLNode_as> xml(new XMLNode_as(getGlobal(fn)));
- xml->nodeTypeSet(XMLNode_as::NodeType(fn.arg(0).to_int()));
+ xml->nodeTypeSet(XMLNode_as::NodeType(toInt(fn.arg(0))));
if (fn.nargs > 1) {
const std::string& str = fn.arg(1).to_string();
=== modified file 'libcore/asobj/int_as.cpp'
--- a/libcore/asobj/int_as.cpp 2009-12-04 09:20:14 +0000
+++ b/libcore/asobj/int_as.cpp 2009-12-07 12:16:50 +0000
@@ -52,7 +52,7 @@
LOG_ONCE( log_unimpl("Arguments passed to int() ctor unhandled") );
}
- obj->setRelay(new int_as(fn.nargs ? fn.arg(0).to_int() : 0));
+ obj->setRelay(new int_as(fn.nargs ? toInt(fn.arg(0)) : 0));
return as_value();
}
=== modified file 'libcore/vm/ASHandlers.cpp'
--- a/libcore/vm/ASHandlers.cpp 2009-12-04 09:20:14 +0000
+++ b/libcore/vm/ASHandlers.cpp 2009-12-08 08:47:03 +0000
@@ -80,7 +80,7 @@
as_object* construct_object(as_function* ctor_as_func, as_environment& env,
unsigned int nargs);
- as_object* convertToObject(Global_as& gl, const as_value& val);
+ as_object* toObject(Global_as& gl, const as_value& val);
/// Common code for ActionGetUrl and ActionGetUrl2
//
@@ -716,7 +716,7 @@
env.top(1).set_string("#ERROR#");
}
else if (operand1 == 0 || isNaN(operand1) || isNaN(operand2)) {
- env.top(1).set_nan();
+ setNaN(env.top(1));
}
else {
// Division by -0.0 is not possible in AS, so
@@ -810,8 +810,8 @@
as_environment& env = thread.env;
const int version = env.get_version();
- const std::string& str0 = env.top(0).to_string_versioned(version);
- const std::string& str1 = env.top(1).to_string_versioned(version);
+ const std::string& str0 = env.top(0).to_string(version);
+ const std::string& str1 = env.top(1).to_string(version);
env.top(1).set_bool(str0 == str1);
env.drop(1);
@@ -834,7 +834,7 @@
}
else
{
- env.top(0).set_int(env.top(0).to_string_versioned(version).size());
+ env.top(0).set_double(env.top(0).to_string(version).size());
}
}
@@ -851,12 +851,12 @@
const as_value& strval = env.top(2);
// Undefined values should resolve to 0.
- int size = env.top(0).to_int();
- int start = env.top(1).to_int();
+ int size = toInt(env.top(0));
+ int start = toInt(env.top(1));
const int version = env.get_version();
const std::wstring wstr = utf8::decodeCanonicalString(
- strval.to_string_versioned(version), version);
+ strval.to_string(version), version);
if (size < 0)
@@ -936,8 +936,7 @@
SWFHandlers::ActionInt(ActionExec& thread)
{
as_environment& env = thread.env;
-
- env.top(0).set_int((env.top(0).to_int()));
+ env.top(0).set_double(toInt(env.top(0)));
}
void
@@ -1022,7 +1021,7 @@
//
// For _versioned, see swfdec's settarget2-tostring.as (swf 7 and 8)
//
- std::string target_name =
env.top(0).to_string_versioned(env.get_version());
+ std::string target_name = env.top(0).to_string(env.get_version());
CommonSetTarget(thread, target_name);
@@ -1032,12 +1031,11 @@
void
SWFHandlers::ActionStringConcat(ActionExec& thread)
{
-
as_environment& env = thread.env;
-
- const int version = env.get_version();
- convertToString(env.top(1), getVM(env));
- env.top(1).string_concat(env.top(0).to_string_versioned(version));
+ const int version = getSWFVersion(env);
+ env.top(1).set_string(env.top(1).to_string(version) +
+ env.top(0).to_string(version));
+
env.drop(1);
}
@@ -1302,7 +1300,7 @@
as_environment& env = thread.env;
const int ver = env.get_version();
- env.top(1).set_bool(env.top(1).to_string_versioned(ver) <
env.top(0).to_string_versioned(ver));
+ env.top(1).set_bool(env.top(1).to_string(ver) < env.top(0).to_string(ver));
env.drop(1);
}
@@ -1326,10 +1324,10 @@
as_environment& env = thread.env;
// Get the "instance"
- as_object* instance = convertToObject(getGlobal(thread.env), env.top(0));
+ as_object* instance = toObject(getGlobal(thread.env), env.top(0));
// Get the "super" function
- as_object* super = convertToObject(getGlobal(thread.env), env.top(1));
+ as_object* super = toObject(getGlobal(thread.env), env.top(1));
// Invalid args!
if (!super || ! instance)
@@ -1377,7 +1375,7 @@
as_environment& env = thread.env;
as_value objval = env.pop();
- as_object *obj = convertToObject(getGlobal(thread.env), objval);
+ as_object *obj = toObject(getGlobal(thread.env), objval);
int count = static_cast<int>(env.pop().to_number());
if (!obj) {
@@ -1395,7 +1393,7 @@
);
return;
}
- obj = convertToObject(getGlobal(thread.env), protoval);
+ obj = toObject(getGlobal(thread.env), protoval);
if (!obj) {
IF_VERBOSE_ASCODING_ERRORS(
log_aserror(_("IMPLEMENTSOP target object's prototype is not "
@@ -1414,7 +1412,7 @@
while (count--) {
as_value ctorval = env.pop();
- as_object* ctor = convertToObject(getGlobal(thread.env), ctorval);
+ as_object* ctor = toObject(getGlobal(thread.env), ctorval);
if (!ctor) {
IF_VERBOSE_ASCODING_ERRORS(
log_aserror(_("class found on stack on IMPLEMENTSOP is "
@@ -1429,7 +1427,7 @@
);
continue;
}
- as_object *inter = convertToObject(getGlobal(thread.env), protoval);
+ as_object *inter = toObject(getGlobal(thread.env), protoval);
if (!inter) {
IF_VERBOSE_ASCODING_ERRORS(
log_aserror(_("Prototype of interface object for "
@@ -1452,7 +1450,6 @@
void
SWFHandlers::ActionFscommand2(ActionExec& thread)
{
-
#if GNASH_PARANOIA_LEVEL > 1
assert(thread.atActionTag(SWF::ACTION_FSCOMMAND2)); // 0x0E
@@ -1462,7 +1459,7 @@
unsigned int off=0;
- const unsigned int nargs = env.top(off++).to_int();
+ const unsigned int nargs = toInt(env.top(off++));
std::string cmd = env.top(off++).to_string();
@@ -1495,7 +1492,7 @@
as_environment& env = thread.env;
- int max = env.top(0).to_int();
+ int max = toInt(env.top(0));
if (max < 1) max = 1;
@@ -1507,7 +1504,7 @@
boost::variate_generator<VM::RNG&,
boost::uniform_int<> > uni(rnd, uni_dist);
- env.top(0).set_int(uni());
+ env.top(0).set_double(uni());
}
as_encoding_guess_t
@@ -1616,7 +1613,7 @@
if (str.empty())
{
- env.top(0).set_int(0);
+ env.top(0).set_double(0);
}
else
{
@@ -1624,7 +1621,7 @@
std::vector<int> unused;
unused.resize(str.length()+1);
(void) guessEncoding(str, length, unused);
- env.top(0).set_int(length);
+ env.top(0).set_double(length);
}
}
@@ -1643,7 +1640,7 @@
if (str.empty())
{
- env.top(0).set_int(0);
+ env.top(0).set_double(0);
return;
}
@@ -1651,7 +1648,7 @@
// decodeCanonicalString should correctly work out what the first
// character is according to version.
- env.top(0).set_int(wstr.at(0));
+ env.top(0).set_double(wstr.at(0));
}
void
@@ -1661,7 +1658,7 @@
as_environment& env = thread.env;
// Only handles values up to 65535
- boost::uint16_t c = static_cast<boost::uint16_t>(env.top(0).to_int());
+ boost::uint16_t c = static_cast<boost::uint16_t>(toInt(env.top(0)));
// If the argument to chr() is '0', we return
// nothing, not NULL
@@ -1715,8 +1712,8 @@
const as_value& arg1 = env.top(1);
// Undefined values should resolve to 0.
- int size = env.top(0).to_int();
- int start = env.top(1).to_int();
+ int size = toInt(env.top(0));
+ int start = toInt(env.top(1));
as_value& string_val = env.top(2);
@@ -1727,7 +1724,7 @@
env.drop(2);
const int version = env.get_version();
- std::string str = string_val.to_string_versioned(version);
+ std::string str = string_val.to_string(version);
int length = 0;
std::vector<int> offsets;
@@ -1812,7 +1809,7 @@
boost::uint32_t out = utf8::decodeNextUnicodeCharacter(it, e);
/// Always valid, or can it be undefined?
- env.top(0).set_int(out);
+ env.top(0).set_double(out);
}
void
@@ -1832,7 +1829,7 @@
}
// Cut to uint16, as characters above 65535 'wrap around'
- const boost::uint16_t i = static_cast<boost::uint16_t>
(env.top(0).to_int());
+ const boost::uint16_t i = static_cast<boost::uint16_t> (toInt(env.top(0)));
std::string out = utf8::encodeUnicodeCharacter(i);
@@ -2337,11 +2334,11 @@
}
else {
as_value target = thread.getVariable(path);
- obj = convertToObject(getGlobal(thread.env), target);
+ obj = toObject(getGlobal(thread.env), target);
propertyname = var;
}
}
- else obj = convertToObject(getGlobal(thread.env), env.top(1));
+ else obj = toObject(getGlobal(thread.env), env.top(1));
if (!obj)
{
@@ -2383,7 +2380,7 @@
// Otherwise see if it's an object and delete it.
as_value target = thread.getVariable(path);
- boost::intrusive_ptr<as_object> obj =
convertToObject(getGlobal(thread.env), target);
+ boost::intrusive_ptr<as_object> obj = toObject(getGlobal(thread.env),
target);
if (!obj)
{
@@ -2430,7 +2427,7 @@
// function is called. If it is undefined, nothing happens, even if
// there is a function called 'undefined'.
//
- // Using to_string_versioned() would produce the wrong behaviour.
+ // Using to_string() would produce the wrong behaviour.
//
// In all cases, even undefined, the specified number of arguments
// is dropped from the stack.
@@ -2602,7 +2599,7 @@
as_environment& env = thread.env;
- const int array_size = env.pop().to_int();
+ const int array_size = toInt(env.pop());
assert(array_size >= 0); // TODO: trigger this !!
Global_as& gl = getGlobal(env);
@@ -2634,7 +2631,7 @@
// [003] Integer: 1
// SWFACTION_INITOBJECT
- const int nmembers = env.pop().to_int();
+ const int nmembers = toInt(env.pop());
// TODO: see if this could call the ASnative function(101, 9).
Global_as& gl = getGlobal(env);
@@ -2709,7 +2706,7 @@
env.top(0).set_undefined();
- const boost::intrusive_ptr<as_object> obj =
convertToObject(getGlobal(thread.env), variable);
+ const boost::intrusive_ptr<as_object> obj =
toObject(getGlobal(thread.env), variable);
if ( !obj || !variable.is_object() )
{
IF_VERBOSE_ASCODING_ERRORS(
@@ -2750,13 +2747,13 @@
assert(thread.atActionTag(SWF::ACTION_NEWEQUALS));
#endif
- const VM& vm = getVM(env);
+ VM& vm = getVM(env);
int swfVersion = vm.getSWFVersion();
if (swfVersion <= 5)
{
as_value op1 = env.top(0);
- try { op1 = op1.to_primitive(); }
+ try { convertToPrimitive(op1, vm); }
catch (ActionTypeError& e)
{
log_debug(_("to_primitive(%s) threw an ActionTypeError %s"),
@@ -2764,7 +2761,7 @@
}
as_value op2 = env.top(1);
- try { op2 = op2.to_primitive(); }
+ try { convertToPrimitive(op2, vm); }
catch (ActionTypeError& e)
{
log_debug(_("to_primitive(%s) threw an ActionTypeError %s"),
@@ -2819,7 +2816,7 @@
as_value target = env.top(1);
boost::intrusive_ptr<as_object> obj =
- convertToObject(getGlobal(thread.env), target);
+ toObject(getGlobal(thread.env), target);
if (!obj)
{
IF_VERBOSE_ASCODING_ERRORS(
@@ -2864,7 +2861,7 @@
as_environment& env = thread.env;
- boost::intrusive_ptr<as_object> obj =
convertToObject(getGlobal(thread.env), env.top(2));
+ boost::intrusive_ptr<as_object> obj = toObject(getGlobal(thread.env),
env.top(2));
const std::string& member_name = env.top(1).to_string();
const as_value& member_value = env.top(0);
@@ -2967,7 +2964,7 @@
log_action(_(" method nargs: %d"), nargs);
);
- as_object* obj = convertToObject(getGlobal(thread.env), obj_value);
+ as_object* obj = toObject(getGlobal(thread.env), obj_value);
if (!obj) {
// If this value is not an object, it can neither have any members
// nor be called as a function, so neither opcode usage is possible.
@@ -3072,7 +3069,7 @@
nargs = available_args;
}
- boost::intrusive_ptr<as_object> obj =
convertToObject(getGlobal(thread.env), obj_val);
+ boost::intrusive_ptr<as_object> obj = toObject(getGlobal(thread.env),
obj_val);
if (!obj) {
// SWF integrity check
// FIXME, should this be log_swferror? Or log_aserror?
@@ -3137,11 +3134,11 @@
as_environment& env = thread.env;
// Get the "super" function
- as_object* super = convertToObject(getGlobal(thread.env), env.top(0));
+ as_object* super = toObject(getGlobal(thread.env), env.top(0));
// Get the "instance" (but avoid implicit conversion of primitive values!)
as_object* instance = env.top(1).is_object() ?
- convertToObject(getGlobal(thread.env), env.top(1)) : NULL;
+ toObject(getGlobal(thread.env), env.top(1)) : NULL;
// Invalid args!
if (!super || ! instance) {
@@ -3174,7 +3171,7 @@
// as we copied that as_value.
env.top(0).set_undefined();
- const boost::intrusive_ptr<as_object> obj =
convertToObject(getGlobal(thread.env), obj_val);
+ const boost::intrusive_ptr<as_object> obj =
toObject(getGlobal(thread.env), obj_val);
if ( !obj || !obj_val.is_object() )
{
IF_VERBOSE_ASCODING_ERRORS(
@@ -3193,8 +3190,8 @@
{
as_environment& env = thread.env;
- int operand1 = env.top(1).to_int();
- int operand2 = env.top(0).to_int();
+ int operand1 = toInt(env.top(1));
+ int operand2 = toInt(env.top(0));
env.top(1) = operand1 & operand2;
env.drop(1);
@@ -3206,8 +3203,8 @@
as_environment& env = thread.env;
- int operand1 = env.top(1).to_int();
- int operand2 = env.top(0).to_int();
+ int operand1 = toInt(env.top(1));
+ int operand2 = toInt(env.top(0));
env.top(1) = operand1|operand2;
env.drop(1);
@@ -3219,8 +3216,8 @@
as_environment& env = thread.env;
- int operand1 = env.top(1).to_int();
- int operand2 = env.top(0).to_int();
+ int operand1 = toInt(env.top(1));
+ int operand2 = toInt(env.top(0));
env.top(1) = operand1^operand2;
env.drop(1);
@@ -3235,10 +3232,10 @@
/// A left shift of more than or equal to the size in
/// bits of the left operand, or a negative shift, results
/// in undefined behaviour in C++.
- boost::int32_t amount = env.top(0).to_int() % 32;
+ boost::int32_t amount = toInt(env.top(0)) % 32;
if (amount < 0) amount += 32;
- boost::int32_t value = env.top(1).to_int();
+ boost::int32_t value = toInt(env.top(1));
value = value << amount;
@@ -3252,8 +3249,8 @@
as_environment& env = thread.env;
- boost::uint32_t amount = env.top(0).to_int();
- boost::int32_t value = env.top(1).to_int();
+ boost::uint32_t amount = toInt(env.top(0));
+ boost::int32_t value = toInt(env.top(1));
value = value >> amount;
@@ -3267,8 +3264,8 @@
as_environment& env = thread.env;
- boost::uint32_t amount = env.top(0).to_int();
- boost::int32_t value = env.top(1).to_int();
+ boost::uint32_t amount = toInt(env.top(0));
+ boost::int32_t value = toInt(env.top(1));
value = boost::uint32_t(value) >> amount;
@@ -3303,7 +3300,7 @@
as_environment& env = thread.env;
- // No need to use to_string_versioned() here, this is a swf7 opcode
+ // No need to use to_string() here, this is a swf7 opcode
env.top(1).set_bool(env.top(1).to_string() > env.top(0).to_string());
env.drop(1);
}
@@ -3453,11 +3450,11 @@
env.push(function_value);
}
#ifdef USE_DEBUGGER
- // WARNING: convertToObject(getGlobal(thread.env), function_value) can
return a newly allocated
+ // WARNING: toObject(getGlobal(thread.env), function_value) can return a
newly allocated
// thing into the intrusive_ptr, so the debugger
// will be left with a deleted object !!
// Rob: we don't want to use void pointers here..
- as_object* o = convertToObject(getGlobal(thread.env), function_value);
+ as_object* o = toObject(getGlobal(thread.env), function_value);
debugger.addSymbol(o.get(), name);
#endif
}
@@ -3646,11 +3643,11 @@
thread.setVariable(name, function_value);
#ifdef USE_DEBUGGER
- // WARNING: convertToObject(getGlobal(thread.env), new_obj) can return
a newly allocated
+ // WARNING: toObject(getGlobal(thread.env), new_obj) can return a
newly allocated
// thing into the intrusive_ptr, so the debugger
// will be left with a deleted object !!
// Rob: we don't want to use void pointers here..
- boost::intrusive_ptr<as_object> o =
convertToObject(getGlobal(thread.env), function_value);
+ boost::intrusive_ptr<as_object> o = toObject(getGlobal(thread.env),
function_value);
#ifndef GNASH_USE_GC
o->add_ref(); // this will leak, but at least debugger won't end up
// with a dandling reference...
@@ -3737,7 +3734,7 @@
namespace {
as_object*
-convertToObject(Global_as& gl, const as_value& val)
+toObject(Global_as& gl, const as_value& val)
{
try {
=== modified file 'libcore/vm/Machine.cpp'
--- a/libcore/vm/Machine.cpp 2009-12-04 12:34:34 +0000
+++ b/libcore/vm/Machine.cpp 2009-12-07 12:16:50 +0000
@@ -859,7 +859,7 @@
if (!_stack.top(0).is_number()) throw ASException();
boost::uint32_t index =
- _stack.top(0).to_number<boost::uint32_t>();
+ _stack.top(0).to_number();
_stack.drop(1);
mStream->seekBy(3); // Skip the intial offset.
@@ -948,7 +948,7 @@
ENSURE_OBJECT(_stack.top(1));
as_object *obj = _stack.top(1).to_object(*_global);
const boost::uint32_t index =
- _stack.top(0).to_number<boost::uint32_t>();
+ _stack.top(0).to_number();
if (!obj) {
// TODO: check what to do here.
@@ -980,7 +980,7 @@
ENSURE_OBJECT(_stack.top(1));
as_object *obj = _stack.top(1).to_object(*_global);
boost::uint32_t index =
- _stack.top(0).to_number<boost::uint32_t>();
+ _stack.top(0).to_number();
_stack.drop(1);
assert(obj);
_stack.top(0) = obj->nextIndex(index);
@@ -1020,7 +1020,7 @@
ENSURE_OBJECT(_stack.top(1));
as_object *obj = _stack.top(1).to_object(*_global);
const boost::uint32_t index =
- _stack.top(0).to_number<boost::uint32_t>();
+ _stack.top(0).to_number();
const Property *b = obj->getByIndex(index);
_stack.drop(1);
if (!b) _stack.top(0).set_undefined();
@@ -1074,7 +1074,7 @@
/// NaN -- the NaN object
case SWF::ABC_ACTION_PUSHNAN:
_stack.grow(1);
- _stack.top(0).set_nan();
+ setNaN(_stack.top(0));
break;
/// 0x29 ABC_ACTION_POP
@@ -1202,7 +1202,7 @@
break;
}
- boost::uint32_t index =
indexv.to_number<boost::uint32_t>();
+ boost::uint32_t index = toInt(indexv);
as_object *owner = 0;
int next = obj->nextIndex(index, &owner);
@@ -2207,7 +2207,7 @@
/// int_value -- value as an integer object
case SWF::ABC_ACTION_CONVERT_I:
case SWF::ABC_ACTION_COERCE_I:
- _stack.top(0) = _stack.top(0).to_int();
+ _stack.top(0) = toInt(_stack.top(0));
break;
/// 0x74 ABC_ACTION_CONVERT_U
@@ -2218,7 +2218,8 @@
/// int_value -- value as an unsigned integer object
case SWF::ABC_ACTION_CONVERT_U:
case SWF::ABC_ACTION_COERCE_U:
- _stack.top(0) = _stack.top(0).to_number<unsigned int>();
+ _stack.top(0) = static_cast<boost::uint32_t>(
+ _stack.top(0).to_number());
break;
/// 0x75 ABC_ACTION_CONVERT_D
@@ -2451,7 +2452,7 @@
/// Stack Out:
/// nint -- ~((Int) obj)
case SWF::ABC_ACTION_BITNOT:
- _stack.top(0) = ~_stack.top(0).to_int();
+ _stack.top(0) = ~toInt(_stack.top(0));
break;
/// 0xA0 ABC_ACTION_ADD
@@ -2523,7 +2524,7 @@
/// a << b
case SWF::ABC_ACTION_LSHIFT:
{
- _stack.top(1) = _stack.top(1).to_int() <<
_stack.top(0).to_int();
+ _stack.top(1) = toInt(_stack.top(1)) <<
toInt(_stack.top(0));
_stack.drop(1);
break;
}
@@ -2536,7 +2537,7 @@
/// a >> b
case SWF::ABC_ACTION_RSHIFT:
{
- _stack.top(1) = _stack.top(1).to_int() >>
_stack.top(0).to_int();
+ _stack.top(1) = toInt(_stack.top(1)) >>
toInt(_stack.top(0));
_stack.drop(1);
break;
}
@@ -2549,8 +2550,9 @@
/// ((unsigned) a) >> b
case SWF::ABC_ACTION_URSHIFT:
{
- _stack.top(1) = _stack.top(1).to_number<unsigned int>()
- >> _stack.top(0).to_int();
+ _stack.top(1) =
+ static_cast<boost::uint32_t>(_stack.top(1).to_number())
+ >> toInt(_stack.top(0));
_stack.drop(1);
break;
}
@@ -2561,7 +2563,7 @@
/// Stack Out:
/// a & b
case SWF::ABC_ACTION_BITAND:
- _stack.top(1) = _stack.top(1).to_int() &
_stack.top(0).to_int();
+ _stack.top(1) = toInt(_stack.top(1)) &
toInt(_stack.top(0));
_stack.drop(1);
break;
@@ -2572,7 +2574,7 @@
/// Stack Out:
/// a | b
case SWF::ABC_ACTION_BITOR:
- _stack.top(1) = _stack.top(1).to_int() |
_stack.top(0).to_int();
+ _stack.top(1) = toInt(_stack.top(1)) |
toInt(_stack.top(0));
_stack.drop(1);
break;
@@ -2584,7 +2586,7 @@
/// a ^ b
case SWF::ABC_ACTION_BITXOR:
{
- _stack.top(1) = _stack.top(1).to_int() ^
_stack.top(0).to_int();
+ _stack.top(1) = toInt(_stack.top(1)) ^
toInt(_stack.top(0));
_stack.drop(1);
break;
}
@@ -2755,7 +2757,7 @@
/// See: 0x91 (ABC_ACTION_INCREMENT), but forces types to int,
not double
case SWF::ABC_ACTION_INCREMENT_I:
{
- _stack.top(0) = _stack.top(0).to_int() + 1;
+ _stack.top(0) = toInt(_stack.top(0)) + 1;
break;
}
@@ -2763,7 +2765,7 @@
/// See: 0x93 (ABC_ACTION_DECREMENT), but forces types to int,
not double
case SWF::ABC_ACTION_DECREMENT_I:
{
- _stack.top(0) = _stack.top(0).to_int() - 1;
+ _stack.top(0) = toInt(_stack.top(0)) - 1;
break;
}
@@ -2773,7 +2775,7 @@
case SWF::ABC_ACTION_INCLOCAL_I:
{
const boost::uint32_t foff = mStream->read_V32();
- setRegister(foff, getRegister(foff).to_int() + 1);
+ setRegister(foff, toInt(getRegister(foff)) + 1);
break;
}
@@ -2783,7 +2785,7 @@
case SWF::ABC_ACTION_DECLOCAL_I:
{
const boost::uint32_t foff = mStream->read_V32();
- setRegister(foff, getRegister(foff).to_int() - 1);
+ setRegister(foff, toInt(getRegister(foff)) - 1);
break;
}
@@ -2792,7 +2794,7 @@
/// not double
case SWF::ABC_ACTION_NEGATE_I:
{
- _stack.top(0) = - _stack.top(0).to_int();
+ _stack.top(0) = - toInt(_stack.top(0));
break;
}
@@ -2800,8 +2802,8 @@
/// See: 0xA0 (ABC_ACTION_ADD), but forces type to int
case SWF::ABC_ACTION_ADD_I:
{
- _stack.top(1) = _stack.top(1).to_int() +
- _stack.top(0).to_int();
+ _stack.top(1) = toInt(_stack.top(1)) +
+ toInt(_stack.top(0));
_stack.drop(1);
break;
}
@@ -2810,8 +2812,8 @@
/// See: 0xA1 (ABC_ACTION_SUBTRACT), but forces type to int
case SWF::ABC_ACTION_SUBTRACT_I:
{
- _stack.top(1) = _stack.top(1).to_int() -
- _stack.top(0).to_int();
+ _stack.top(1) = toInt(_stack.top(1)) -
+ toInt(_stack.top(0));
_stack.drop(1);
break;
}
@@ -2820,7 +2822,7 @@
/// See: 0xA2 (ABC_ACTION_MULTIPLY), but forces type to int
case SWF::ABC_ACTION_MULTIPLY_I:
{
- _stack.top(1) = _stack.top(0).to_int() *
_stack.top(1).to_int();
+ _stack.top(1) = toInt(_stack.top(0)) *
toInt(_stack.top(1));
_stack.drop(1);
break;
}
=== modified file 'libcore/vm/Machine.h'
--- a/libcore/vm/Machine.h 2009-12-04 09:44:49 +0000
+++ b/libcore/vm/Machine.h 2009-12-08 11:59:39 +0000
@@ -34,7 +34,6 @@
class MultiName;
class Class;
class abc_function;
- typedef Property Binding;
class Method;
class Namespace;
}
@@ -162,7 +161,7 @@
/// Nothing.
void setMember(Class*, MultiName&, as_value& target, as_value& val);
- Binding* findProperty(MultiName&) { return NULL; }
+ Property* findProperty(MultiName&) { return NULL; }
void execute();
=== modified file 'libcore/vm/VM.cpp'
--- a/libcore/vm/VM.cpp 2009-11-29 11:33:46 +0000
+++ b/libcore/vm/VM.cpp 2009-12-08 08:47:03 +0000
@@ -307,14 +307,14 @@
// The order of the operations is important: op2 is converted to
// primitive before op1.
- try { r = r.to_primitive(); }
+ try { convertToPrimitive(r, vm); }
catch (ActionTypeError& e)
{
log_debug(_("%s.to_primitive() threw an error during "
"ActionNewAdd"), r);
}
- try { op1 = op1.to_primitive(); }
+ try { convertToPrimitive(op1, vm); }
catch (ActionTypeError& e)
{
log_debug(_("%s.to_primitive() threw an error during "
@@ -330,7 +330,7 @@
// use string semantic
const int version = vm.getSWFVersion();
convertToString(op1, vm);
- op1.string_concat(r.to_string_versioned(version));
+ op1.set_string(op1.to_string(version) + r.to_string(version));
return;
}
=== modified file 'testsuite/libcore.all/AsValueTest.cpp'
--- a/testsuite/libcore.all/AsValueTest.cpp 2009-12-01 09:30:50 +0000
+++ b/testsuite/libcore.all/AsValueTest.cpp 2009-12-07 13:06:22 +0000
@@ -189,6 +189,7 @@
void
test_el()
{
+#if 0
// bool notest = false;
Element el1;
@@ -240,11 +241,13 @@
//}
// There is no equivalent AMF element type to the as_value AS_FUNCTION type
+#endif
}
void
test_obj(const as_object* o)
{
+#if 0
// Create an object element with some properties
bool notest = false;
Element top;
@@ -317,6 +320,7 @@
} else {
runtest.fail("as_value::to_element()");
}
+#endif
}
void
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] /srv/bzr/gnash/trunk r11679: Changes to as_value to make it less dependent on AS2.,
Benjamin Wolsey <=