[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] /srv/bzr/gnash/trunk r11582: Drop more static data, corr
From: |
Benjamin Wolsey |
Subject: |
[Gnash-commit] /srv/bzr/gnash/trunk r11582: Drop more static data, correct native array construction. |
Date: |
Wed, 21 Oct 2009 16:05:36 +0200 |
User-agent: |
Bazaar (1.16.1) |
------------------------------------------------------------
revno: 11582 [merge]
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Wed 2009-10-21 16:05:36 +0200
message:
Drop more static data, correct native array construction.
modified:
libcore/as_function.cpp
libcore/as_object.cpp
libcore/as_object.h
libcore/as_value.cpp
libcore/asobj/Array_as.cpp
libcore/asobj/Array_as.h
libcore/asobj/Globals.cpp
libcore/asobj/flash/text/TextSnapshot_as.cpp
libcore/asobj/flash/text/TextSnapshot_as.h
libcore/vm/ASHandlers.cpp
libcore/vm/ActionExec.cpp
libcore/vm/with_stack_entry.h
testsuite/actionscript.all/array.as
testsuite/swfdec/PASSING
=== modified file 'libcore/as_function.cpp'
--- a/libcore/as_function.cpp 2009-10-15 14:40:38 +0000
+++ b/libcore/as_function.cpp 2009-10-21 12:02:12 +0000
@@ -138,7 +138,7 @@
// Create an empty object, with a ref to the constructor's prototype.
// TODO: The prototype should not be converted to an object!
as_object* newobj = new as_object();
- if (has_proto) newobj->set_prototype(proto.to_object(*getGlobal(env)));
+ if (has_proto) newobj->set_prototype(proto);
// Add a __constructor__ member to the new object, but only for SWF6 up
// (to be checked). NOTE that we assume the builtin constructors
=== modified file 'libcore/as_object.cpp'
--- a/libcore/as_object.cpp 2009-10-16 14:17:00 +0000
+++ b/libcore/as_object.cpp 2009-10-21 12:48:16 +0000
@@ -273,6 +273,7 @@
as_object::as_object(Global_as& gl)
:
_displayObject(false),
+ _array(false),
_relay(0),
_vm(getVM(gl)),
_members(_vm)
@@ -282,6 +283,7 @@
as_object::as_object()
:
_displayObject(false),
+ _array(false),
_relay(0),
_vm(VM::get()),
_members(_vm)
@@ -291,6 +293,7 @@
as_object::as_object(as_object* proto)
:
_displayObject(false),
+ _array(false),
_relay(0),
_vm(VM::get()),
_members(_vm)
@@ -301,6 +304,7 @@
as_object::as_object(boost::intrusive_ptr<as_object> proto)
:
_displayObject(false),
+ _array(false),
_relay(0),
_vm(VM::get()),
_members(_vm)
@@ -686,6 +690,10 @@
// We still need to set the member.
}
+ // Handle the length property for arrays. NB: checkArrayLength() will
+ // call this function again if the key is a valid index.
+ if (array()) checkArrayLength(*this, key, val, nsname);
+
const ObjectURI uri(key, nsname);
PrototypeRecursor<Exists> pr(this, uri);
=== modified file 'libcore/as_object.h'
--- a/libcore/as_object.h 2009-10-16 14:17:00 +0000
+++ b/libcore/as_object.h 2009-10-21 13:16:04 +0000
@@ -961,7 +961,12 @@
/// constructors and special creation functions like
/// MovieClip.createTextField(). As Relay objects are not available to
/// ActionScript, this should never appear in built-in functions.
+ //
+ /// This function also removes Array typing from an object when a Relay
+ /// is assigned. There are tests verifying this behaviour in
+ /// actionscript.all and the swfdec testsuite.
void setRelay(Relay* p) {
+ if (p) _array = false;
_relay.reset(p);
}
@@ -979,6 +984,14 @@
return _relay.get();
}
+ bool array() const {
+ return _array;
+ }
+
+ void setArray() {
+ _array = true;
+ }
+
/// Return true if this is a DisplayObject.
bool displayObject() const {
return _displayObject;
@@ -1076,6 +1089,15 @@
/// object is a DisplayObject
bool _displayObject;
+ /// An array is a special type of object.
+ //
+ /// Like DisplayObjects, Arrays handle property setting differently. We
+ /// use an extra flag to avoid checking Relay type on every property
+ /// set, but tests show that the Array constructor removes the Relay. It
+ /// would be possible to implement using a Relay, but as an Array stores
+ /// no extra native data, it's not clear what the point is.
+ bool _array;
+
/// The polymorphic Relay object for native types.
//
/// This is owned by the as_object and destroyed when the as_object's
=== modified file 'libcore/as_value.cpp'
--- a/libcore/as_value.cpp 2009-10-16 14:17:00 +0000
+++ b/libcore/as_value.cpp 2009-10-21 11:35:19 +0000
@@ -2278,14 +2278,13 @@
return true;
}
- Array_as* ary = dynamic_cast<Array_as*>(obj);
- if (ary) {
+ if (obj->array()) {
string_table& st = vm.getStringTable();
- const size_t len = arrayLength(*ary);
+ const size_t len = arrayLength(*obj);
if (allowStrict) {
IsStrictArray s(st);
// Check if any non-hidden properties are non-numeric.
- ary->visitProperties<IsEnumerable>(s);
+ obj->visitProperties<IsEnumerable>(s);
if (s.strict()) {
#ifdef GNASH_DEBUG_AMF_SERIALIZE
@@ -2298,7 +2297,7 @@
as_value elem;
for (size_t i = 0; i < len; ++i) {
- elem = ary->getMember(arrayKey(st, i));
+ elem = obj->getMember(arrayKey(st, i));
if (!elem.writeAMF0(buf, offsetTable, vm,
allowStrict)) {
log_error("Problems serializing strict
array "
=== modified file 'libcore/asobj/Array_as.cpp'
--- a/libcore/asobj/Array_as.cpp 2009-10-16 14:17:00 +0000
+++ b/libcore/asobj/Array_as.cpp 2009-10-21 13:15:42 +0000
@@ -814,51 +814,23 @@
return false;
}
-Array_as::Array_as()
- :
- as_object(getArrayInterface())
-{
- init_member(NSV::PROP_LENGTH, 0.0);
-}
-
-
-Array_as::~Array_as()
-{
-}
-
-unsigned int
-Array_as::size() const
-{
- return arrayLength(const_cast<Array_as&>(*this));
-}
-
-as_value
-Array_as::at(unsigned int index) const
-{
- if (index > size() - 1) return as_value();
- return
const_cast<Array_as*>(this)->getMember(arrayKey(getStringTable(*this), index));
-}
-
-/* virtual public, overriding as_object::set_member */
-bool
-Array_as::set_member(string_table::key name, const as_value& val,
- string_table::key nsname, bool ifFound)
-{
-
+void
+checkArrayLength(as_object& array, string_table::key name, const as_value& val,
+ string_table::key /*nsname*/)
+{
if (name == NSV::PROP_LENGTH) {
- resizeArray(*this, val.to_int());
+ resizeArray(array, val.to_int());
+ return;
}
- else {
- int index = isIndex(getStringTable(*this).value(name));
- // if we were sent a valid array index and not a normal member
- if (index >= 0) {
- if (static_cast<size_t>(index) >= arrayLength(*this)) {
- setArrayLength(*this, index + 1);
- }
+
+ const int index = isIndex(getStringTable(array).value(name));
+
+ // if we were sent a valid array index
+ if (index >= 0) {
+ if (static_cast<size_t>(index) >= arrayLength(array)) {
+ setArrayLength(array, index + 1);
}
}
-
- return as_object::set_member(name,val, nsname, ifFound);
}
size_t
@@ -894,21 +866,20 @@
void
array_class_init(as_object& where, const ObjectURI& uri)
{
- static as_object* cl = 0;
-
- if (cl == NULL) {
-
- // This is going to be the global Array "class"/"function"
- VM& vm = getVM(where);
-
- as_object* proto = getArrayInterface();
- cl = vm.getNative(252, 0);
- cl->init_member(NSV::PROP_PROTOTYPE, proto);
- proto->init_member(NSV::PROP_CONSTRUCTOR, cl);
-
- // Attach static members
- attachArrayStatics(*cl);
- }
+
+ // This is going to be the global Array "class"/"function"
+ VM& vm = getVM(where);
+ Global_as* gl = getGlobal(where);
+
+ as_object* proto = gl->createObject();
+
+ as_object* cl = vm.getNative(252, 0);
+
+ cl->init_member(NSV::PROP_PROTOTYPE, proto);
+ proto->init_member(NSV::PROP_CONSTRUCTOR, cl);
+
+ attachArrayInterface(*proto);
+ attachArrayStatics(*cl);
const int flags = PropFlags::dontEnum;
where.init_member(getName(uri), cl, flags, getNamespace(uri));
@@ -953,20 +924,6 @@
proto.init_member("sortOn", vm.getNative(252, 12));
}
-as_object*
-getArrayInterface()
-{
- static boost::intrusive_ptr<as_object> proto = NULL;
- if ( proto == NULL )
- {
- proto = new as_object(getObjectInterface());
- getVM(*proto).addStatic(proto.get());
-
- attachArrayInterface(*proto);
- }
- return proto.get();
-}
-
as_value
array_splice(const fn_call& fn)
{
@@ -1262,8 +1219,6 @@
array->set_member(getKey(fn, size + i), fn.arg(i));
}
- log_debug("size: %s, shift :%s", size, shift);
-
return as_value(size + shift);
}
@@ -1461,15 +1416,17 @@
as_value
array_new(const fn_call& fn)
{
- IF_VERBOSE_ACTION (
- log_action(_("array_new called, nargs = %d"), fn.nargs);
- );
-
- // TODO: use the this_ptr
- as_object* ao = new Array_as;
+
+ as_object* ao = fn.isInstantiation() ? ensureType<as_object>(fn.this_ptr) :
+ getGlobal(fn)->createArray();
+
+ ao->setRelay(0);
+ ao->setArray();
+
+ ao->init_member(NSV::PROP_LENGTH, 0.0);
if (fn.nargs == 0) {
- return ao;
+ return as_value(ao);
}
if (fn.nargs == 1 && fn.arg(0).is_number()) {
@@ -1478,13 +1435,14 @@
else {
ao->set_member(NSV::PROP_LENGTH, newSize);
}
- return ao;
+ return as_value(ao);
}
// Use the arguments as initializers.
for (size_t i = 0; i < fn.nargs; i++) {
ao->callMethod(NSV::PROP_PUSH, fn.arg(i));
}
+
return as_value(ao);
}
@@ -1576,15 +1534,13 @@
}
void
-setArrayLength(as_object& o, const int size)
+setArrayLength(as_object& array, const int size)
{
- Array_as* array = dynamic_cast<Array_as*>(&o);
- if (!array) return;
-
- resizeArray(*array, size);
-
- // Do not call Array_as::set_member because that calls this!
- array->as_object::set_member(NSV::PROP_LENGTH, size);
+ if (!array.array()) return;
+
+ resizeArray(array, size);
+
+ array.set_member(NSV::PROP_LENGTH, size);
}
int
=== modified file 'libcore/asobj/Array_as.h'
--- a/libcore/asobj/Array_as.h 2009-10-16 14:17:00 +0000
+++ b/libcore/asobj/Array_as.h 2009-10-21 11:35:19 +0000
@@ -18,19 +18,11 @@
#ifndef GNASH_ARRAY_H
#define GNASH_ARRAY_H
-#include "as_object.h" // for inheritance
-#include "smart_ptr.h" // GNASH_USE_GC
-#include "namedStrings.h"
+#include "as_object.h"
#include "Global_as.h"
-#include <deque>
-#include <vector>
-#include <memory> // for auto_ptr
-#include <string>
-
// Forward declarations
namespace gnash {
- class fn_call;
class as_value;
}
@@ -55,7 +47,6 @@
/// @return The string table key to look up.
string_table::key arrayKey(string_table& st, size_t i);
-
/// A visitor to check whether an array is strict or not.
//
/// Strict arrays have no non-hidden non-numeric properties. Only real arrays
@@ -74,25 +65,14 @@
string_table& _st;
};
-/// The Array ActionScript object
-class Array_as : public as_object
-{
-
-public:
-
- Array_as();
-
- ~Array_as();
-
- as_value at(unsigned int index) const;
-
- unsigned int size() const;
-
- /// Overridden to provide array[#]=x semantic
- virtual bool set_member(string_table::key name,
- const as_value& val, string_table::key nsname=0, bool
ifFound=false);
-
-};
+
+/// Genuine arrays handle the length property in a special way.
+//
+/// The only distinction between Arrays and Objects is that the length
+/// property is changed when an element is added, and that changing the length
+/// can result in deleted properties.
+void checkArrayLength(as_object& array, string_table::key name,
+ const as_value& val, string_table::key nsname = 0);
template<typename T>
void foreachArray(as_object& array, T& pred)
=== modified file 'libcore/asobj/Globals.cpp'
--- a/libcore/asobj/Globals.cpp 2009-10-15 14:40:38 +0000
+++ b/libcore/asobj/Globals.cpp 2009-10-21 13:16:25 +0000
@@ -28,12 +28,12 @@
#include "as_value.h"
#include "as_function.h" // for function_class_init
#include "NativeFunction.h"
-#include "Array_as.h"
#include "AsBroadcaster.h"
#include "Boolean_as.h"
#include "Color_as.h"
#include "CustomActions.h"
#include "Date_as.h"
+#include "Array_as.h"
#include "Error_as.h"
#include "String_as.h"
#include "Selection_as.h"
@@ -249,15 +249,28 @@
}
-/// This serves the purpose of hiding the Array_as type from the
-/// implementation, which at least enforces good behaviour from users.
+/// Construct an Array.
//
-/// TODO: it could well already call the Array constructor.
+/// This uses the _global Array class to initialize the "constructor" and
+/// "__proto__" properties. If Array.prototype is undefined, those properties
+/// are not added.
as_object*
AVM1Global::createArray()
{
- as_object* array = new Array_as;
- array->init_member(NSV::PROP_CONSTRUCTOR, getMember(NSV::CLASS_ARRAY));
+ as_object* array = new as_object(*this);
+
+ as_value ctor = getMember(NSV::CLASS_ARRAY);
+ as_object* obj = ctor.to_object(*this);
+ if (obj) {
+ as_value proto;
+ if (obj->get_member(NSV::PROP_PROTOTYPE, &proto)) {
+ array->init_member(NSV::PROP_CONSTRUCTOR, ctor);
+ array->set_prototype(obj->getMember(NSV::PROP_PROTOTYPE));
+ }
+ }
+
+ array->init_member(NSV::PROP_LENGTH, 0.0);
+ array->setArray();
return array;
}
@@ -322,7 +335,8 @@
as_object*
AVM2Global::createArray()
{
- as_object* array = new Array_as;
+ as_object* array = new as_object(*this);
+ array->setArray();
array->init_member(NSV::PROP_CONSTRUCTOR, getMember(NSV::CLASS_ARRAY));
return array;
}
@@ -510,7 +524,7 @@
(N(Keyboard_as::init, NSV::CLASS_KEY, NSV::CLASS_OBJECT, NS_GLOBAL, 5))
(N(AsBroadcaster::init, NSV::CLASS_AS_BROADCASTER, NSV::CLASS_OBJECT,
NS_GLOBAL, 5))
- (N(TextSnapshot_as::init, NSV::CLASS_TEXT_SNAPSHOT, NSV::CLASS_OBJECT,
+ (N(textsnapshot_class_init, NSV::CLASS_TEXT_SNAPSHOT,
NSV::CLASS_OBJECT,
NS_GLOBAL, 5))
(N(video_class_init, NSV::CLASS_VIDEO, NSV::CLASS_OBJECT, NS_GLOBAL,
6))
(N(camera_class_init, NSV::CLASS_CAMERA, NSV::CLASS_OBJECT,
@@ -596,7 +610,7 @@
NSV::CLASS_INTERACTIVEOBJECT, NSV::NS_FLASH_TEXT, 3))
(N(textformat_class_init, NSV::CLASS_TEXT_FORMAT, NSV::CLASS_OBJECT,
NSV::NS_FLASH_TEXT, 5))
- (N(TextSnapshot_as::init, NSV::CLASS_TEXT_SNAPSHOT, NSV::CLASS_OBJECT,
+ (N(textsnapshot_class_init, NSV::CLASS_TEXT_SNAPSHOT,
NSV::CLASS_OBJECT,
NSV::NS_FLASH_TEXT, 5))
(N(textfieldautosize_class_init, NSV::CLASS_TEXTFIELDAUTOSIZE,
NSV::CLASS_OBJECT, NSV::NS_FLASH_TEXT, 5))
=== modified file 'libcore/asobj/flash/text/TextSnapshot_as.cpp'
--- a/libcore/asobj/flash/text/TextSnapshot_as.cpp 2009-10-14 14:50:52
+0000
+++ b/libcore/asobj/flash/text/TextSnapshot_as.cpp 2009-10-21 13:16:25
+0000
@@ -46,8 +46,81 @@
namespace gnash {
+class TextSnapshot_as : public Relay
+{
+
+public:
+
+ typedef std::vector<const SWF::TextRecord*> Records;
+
+ /// Should remain in the order of insertion
+ /// We should only ever iterate from begin to end, so there's no
+ /// performance issue.
+ typedef std::vector<std::pair<StaticText*, Records> > TextFields;
+
+ /// Construct a TextSnapshot_as from a MovieClip.
+ //
+ /// @param mc The MovieClip to search for static text. If 0, the
+ /// TextSnapshot is invalid, which should be reflected in
+ /// AS return values.
+ TextSnapshot_as(const MovieClip* mc);
+
+ std::string getText(boost::int32_t start, boost::int32_t end,
+ bool nl) const;
+
+ boost::int32_t findText(boost::int32_t start, const std::string& text,
+ bool ignoreCase) const;
+
+ bool valid() const { return _valid; }
+
+ size_t getCount() const { return _count; }
+
+ void setSelected(size_t start, size_t end, bool selected);
+
+ bool getSelected(size_t start, size_t end) const;
+
+ std::string getSelectedText(bool newlines) const;
+
+ void getTextRunInfo(size_t start, size_t end, as_object& ri) const;
+
+protected:
+
+ virtual void setReachable() const;
+
+private:
+
+ /// Generate a string from the TextRecords in this TextSnapshot.
+ //
+ /// @param to The string to write to
+ /// @param newline If true, newlines are written after every
+ /// StaticText in this TextSnapshot
+ /// @param selectedOnly Only write DisplayObject that are selected to.
+ /// @param start The start index
+ /// @param len The number of StaticText DisplayObjects to
traverse.
+ /// This includes non-selected DisplayObjects.
+ void makeString(std::string& to, bool newline = false,
+ bool selectedOnly = false,
+ std::string::size_type start = 0,
+ std::string::size_type len = std::string::npos) const;
+
+ TextFields _textFields;
+
+ /// Whether the object is valid, i.e. it was constructed with a MovieClip.
+ //
+ /// This should be deducible from another member, but since there seems
+ /// to be no point in storing the MovieClip this bool will do instead.
+ const bool _valid;
+
+ /// The number of DisplayObjects
+ //
+ /// There is no need to store this, but it is quicker than counting
+ /// afresh every time.
+ const size_t _count;
+
+};
// Forward declarations
namespace {
+
void attachTextSnapshotStaticInterface(as_object& o);
as_value textsnapshot_findText(const fn_call& fn);
@@ -62,7 +135,6 @@
as_value textsnapshot_ctor(const fn_call& fn);
void attachTextSnapshotInterface(as_object& o);
- as_object* getTextSnapshotInterface();
size_t getTextFields(const MovieClip* mc,
TextSnapshot_as::TextFields& fields);
@@ -71,19 +143,19 @@
}
+
// extern (used by Global.cpp)
void
-TextSnapshot_as::init(as_object& where, const ObjectURI& uri)
+textsnapshot_class_init(as_object& where, const ObjectURI& uri)
{
- static boost::intrusive_ptr<as_object> cl;
- if (!cl) {
- Global_as* gl = getGlobal(where);
- as_object* proto = getTextSnapshotInterface();
- cl = gl->createClass(&textsnapshot_ctor, proto);
- attachTextSnapshotStaticInterface(*cl);
- }
- where.init_member(getName(uri), cl.get(), as_object::DefaultFlags,
+ Global_as* gl = getGlobal(where);
+ as_object* proto = gl->createObject();
+ as_object* cl = gl->createClass(&textsnapshot_ctor, proto);
+ attachTextSnapshotStaticInterface(*cl);
+ attachTextSnapshotInterface(*proto);
+
+ where.init_member(getName(uri), cl, as_object::DefaultFlags,
getNamespace(uri));
}
@@ -91,7 +163,6 @@
/// that it is constructed before it is used.
TextSnapshot_as::TextSnapshot_as(const MovieClip* mc)
:
- as_object(getTextSnapshotInterface()),
_textFields(),
_valid(mc),
_count(getTextFields(mc, _textFields))
@@ -163,10 +234,9 @@
}
void
-TextSnapshot_as::markReachableResources() const
+TextSnapshot_as::setReachable() const
{
std::for_each(_textFields.begin(), _textFields.end(), setTextReachable);
- markAsObjectReachable();
}
void
@@ -427,23 +497,11 @@
o.init_member("getTextRunInfo", vm.getNative(1067, 9), flags);
}
-as_object*
-getTextSnapshotInterface()
-{
- static boost::intrusive_ptr<as_object> o;
- if ( ! o )
- {
- o = new as_object(getObjectInterface());
- attachTextSnapshotInterface(*o);
- }
- return o.get();
-}
as_value
textsnapshot_getTextRunInfo(const fn_call& fn)
{
- boost::intrusive_ptr<TextSnapshot_as> ts =
- ensureType<TextSnapshot_as>(fn.this_ptr);
+ TextSnapshot_as* ts = ensureNativeType<TextSnapshot_as>(fn.this_ptr);
if (!ts->valid()) return as_value();
@@ -465,8 +523,7 @@
as_value
textsnapshot_findText(const fn_call& fn)
{
- boost::intrusive_ptr<TextSnapshot_as> ts =
- ensureType<TextSnapshot_as>(fn.this_ptr);
+ TextSnapshot_as* ts = ensureNativeType<TextSnapshot_as>(fn.this_ptr);
if (!ts->valid()) return as_value();
@@ -490,8 +547,7 @@
as_value
textsnapshot_getCount(const fn_call& fn)
{
- boost::intrusive_ptr<TextSnapshot_as> ts =
- ensureType<TextSnapshot_as>(fn.this_ptr);
+ TextSnapshot_as* ts = ensureNativeType<TextSnapshot_as>(fn.this_ptr);
if (!ts->valid()) return as_value();
@@ -509,8 +565,7 @@
as_value
textsnapshot_getSelected(const fn_call& fn)
{
- boost::intrusive_ptr<TextSnapshot_as> ts =
- ensureType<TextSnapshot_as>(fn.this_ptr);
+ TextSnapshot_as* ts = ensureNativeType<TextSnapshot_as>(fn.this_ptr);
if (!ts->valid()) return as_value();
@@ -528,8 +583,7 @@
as_value
textsnapshot_getSelectedText(const fn_call& fn)
{
- boost::intrusive_ptr<TextSnapshot_as> ts =
- ensureType<TextSnapshot_as>(fn.this_ptr);
+ TextSnapshot_as* ts = ensureNativeType<TextSnapshot_as>(fn.this_ptr);
if (!ts->valid()) return as_value();
@@ -546,8 +600,7 @@
as_value
textsnapshot_getText(const fn_call& fn)
{
- boost::intrusive_ptr<TextSnapshot_as> ts =
- ensureType<TextSnapshot_as>(fn.this_ptr);
+ TextSnapshot_as* ts = ensureNativeType<TextSnapshot_as>(fn.this_ptr);
if (!ts->valid()) return as_value();
@@ -573,8 +626,7 @@
as_value
textsnapshot_hitTestTextNearPos(const fn_call& fn)
{
- boost::intrusive_ptr<TextSnapshot_as> ts =
- ensureType<TextSnapshot_as>(fn.this_ptr);
+ TextSnapshot_as* ts = ensureNativeType<TextSnapshot_as>(fn.this_ptr);
if (!ts->valid()) return as_value();
@@ -586,8 +638,9 @@
as_value
textsnapshot_setSelectColor(const fn_call& fn)
{
- boost::intrusive_ptr<TextSnapshot_as> ts =
- ensureType<TextSnapshot_as>(fn.this_ptr);
+
+ TextSnapshot_as* ts = ensureNativeType<TextSnapshot_as>(fn.this_ptr);
+ UNUSED(ts);
log_unimpl (__FUNCTION__);
return as_value();
@@ -598,8 +651,7 @@
as_value
textsnapshot_setSelected(const fn_call& fn)
{
- boost::intrusive_ptr<TextSnapshot_as> ts =
- ensureType<TextSnapshot_as>(fn.this_ptr);
+ TextSnapshot_as* ts = ensureNativeType<TextSnapshot_as>(fn.this_ptr);
if (fn.nargs < 2 || fn.nargs > 3) {
return as_value();
@@ -618,8 +670,12 @@
as_value
textsnapshot_ctor(const fn_call& fn)
{
+ as_object* ptr = ensureType<as_object>(fn.this_ptr);
+
MovieClip* mc = (fn.nargs == 1) ? fn.arg(0).to_sprite() : 0;
- return as_value(new TextSnapshot_as(mc));
+
+ ptr->setRelay(new TextSnapshot_as(mc));
+ return as_value();
}
size_t
=== modified file 'libcore/asobj/flash/text/TextSnapshot_as.h'
--- a/libcore/asobj/flash/text/TextSnapshot_as.h 2009-10-14 14:50:52
+0000
+++ b/libcore/asobj/flash/text/TextSnapshot_as.h 2009-10-21 13:16:25
+0000
@@ -29,89 +29,10 @@
namespace gnash {
- class StaticText;
- namespace SWF {
- class TextRecord;
- }
-
-// Forward declarations
-class TextSnapshot_as: public as_object
-{
-
-public:
-
- typedef std::vector<const SWF::TextRecord*> Records;
-
- /// Should remain in the order of insertion
- /// We should only ever iterate from begin to end, so there's no
- /// performance issue.
- typedef std::vector<std::pair<StaticText*, Records> > TextFields;
-
- /// Construct a TextSnapshot_as from a MovieClip.
- //
- /// @param mc The MovieClip to search for static text. If 0, the
- /// TextSnapshot is invalid, which should be reflected in
- /// AS return values.
- TextSnapshot_as(const MovieClip* mc);
-
- static void init(as_object& where, const ObjectURI& uri);
-
- std::string getText(boost::int32_t start, boost::int32_t end,
- bool nl) const;
-
- boost::int32_t findText(boost::int32_t start, const std::string& text,
- bool ignoreCase) const;
-
- bool valid() const { return _valid; }
-
- size_t getCount() const { return _count; }
-
- void setSelected(size_t start, size_t end, bool selected);
-
- bool getSelected(size_t start, size_t end) const;
-
- std::string getSelectedText(bool newlines) const;
-
- void getTextRunInfo(size_t start, size_t end, as_object& ri) const;
-
-protected:
-
- void markReachableResources() const;
-
-private:
-
- /// Generate a string from the TextRecords in this TextSnapshot.
- //
- /// @param to The string to write to
- /// @param newline If true, newlines are written after every
- /// StaticText in this TextSnapshot
- /// @param selectedOnly Only write DisplayObject that are selected to.
- /// @param start The start index
- /// @param len The number of StaticText DisplayObjects to
traverse.
- /// This includes non-selected DisplayObjects.
- void makeString(std::string& to, bool newline = false,
- bool selectedOnly = false,
- std::string::size_type start = 0,
- std::string::size_type len = std::string::npos) const;
-
- TextFields _textFields;
-
- /// Whether the object is valid, i.e. it was constructed with a MovieClip.
- //
- /// This should be deducible from another member, but since there seems
- /// to be no point in storing the MovieClip this bool will do instead.
- const bool _valid;
-
- /// The number of DisplayObjects
- //
- /// There is no need to store this, but it is quicker than counting
- /// afresh every time.
- const size_t _count;
-
-};
-
void registerTextSnapshotNative(as_object& global);
+void textsnapshot_class_init(as_object& where, const ObjectURI& uri);
+
} // gnash namespace
// GNASH_ASOBJ3_TEXTSNAPSHOT_H
=== modified file 'libcore/vm/ASHandlers.cpp'
--- a/libcore/vm/ASHandlers.cpp 2009-10-16 07:09:56 +0000
+++ b/libcore/vm/ASHandlers.cpp 2009-10-21 12:23:49 +0000
@@ -2629,18 +2629,16 @@
as_value function = thread.getVariable(funcname, &this_ptr);
- if ( ! function.is_object() )
- {
+ if (!function.is_object()) {
IF_VERBOSE_ASCODING_ERRORS (
log_aserror(_("ActionCallFunction: %s is not an object"), funcname);
)
}
- else if ( ! function.is_function() )
- {
+ else if (!function.is_function()) {
log_error(_("ActionCallFunction: function name %s evaluated to "
"non-function value %s"), funcname, function);
// Calling super ?
- boost::intrusive_ptr<as_object> obj =
convertToObject(*getGlobal(thread.env), function);
+ as_object* obj = convertToObject(*getGlobal(thread.env), function);
this_ptr = thread.getThisPointer();
if (!obj->get_member(NSV::PROP_CONSTRUCTOR, &function) )
{
@@ -2809,10 +2807,7 @@
Global_as* gl = getGlobal(env);
- as_value result = gl->createArray();
-
- as_object* ao = convertToObject(*getGlobal(thread.env), result);
- assert(ao);
+ as_object* ao = gl->createArray();
// Fill the elements with the initial values from the stack.
for (int i = 0; i < array_size; i++) {
@@ -2821,7 +2816,7 @@
env.pop());
}
- env.push(result);
+ env.push(ao);
}
@@ -3735,7 +3730,6 @@
void
SWFHandlers::ActionWith(ActionExec& thread)
{
-
as_environment& env = thread.env;
const action_buffer& code = thread.code;
@@ -3745,9 +3739,8 @@
assert(thread.atActionTag(SWF::ACTION_WITH));
#endif
- as_value with_obj_val = convertToObject(*getGlobal(thread.env), env.pop());
- boost::intrusive_ptr<as_object> with_obj =
- convertToObject(*getGlobal(thread.env), with_obj_val);
+ const as_value& val = env.pop();
+ as_object* with_obj = val.to_object(*getGlobal(thread.env));
++pc; // skip tag code
@@ -3774,21 +3767,20 @@
// now we should be on the first action of the 'with' body
assert(thread.getNextPC() == pc);
- if ( ! with_obj )
- {
+ if (!with_obj) {
IF_VERBOSE_ASCODING_ERRORS(
log_aserror(_("with(%s) : first argument doesn't cast to an object!"),
- with_obj_val);
+ val);
);
// skip the full block
thread.adjustNextPC(block_length);
return;
}
- // where does the 'with' block ends ?
- unsigned block_end = thread.getNextPC() + block_length;
+ // where does the 'with' block end?
+ const size_t block_end = thread.getNextPC() + block_length;
- if ( ! thread.pushWithEntry(with_stack_entry(with_obj, block_end)) )
+ if (!thread.pushWithEntry(with_stack_entry(with_obj, block_end)))
{
// skip the full block
thread.adjustNextPC(block_length);
=== modified file 'libcore/vm/ActionExec.cpp'
--- a/libcore/vm/ActionExec.cpp 2009-10-09 06:16:57 +0000
+++ b/libcore/vm/ActionExec.cpp 2009-10-21 08:51:44 +0000
@@ -757,12 +757,10 @@
as_object*
ActionExec::getTarget()
{
- if ( ! _withStack.empty() )
- {
+ if (!_withStack.empty()) {
return _withStack.back().object();
}
- else
- {
+ else {
return env.get_target();
}
}
=== modified file 'libcore/vm/with_stack_entry.h'
--- a/libcore/vm/with_stack_entry.h 2009-02-25 22:33:03 +0000
+++ b/libcore/vm/with_stack_entry.h 2009-10-21 08:51:44 +0000
@@ -39,13 +39,6 @@
{
}
- with_stack_entry(boost::intrusive_ptr<as_object> obj, size_t end)
- :
- _object(obj),
- _block_end_pc(end)
- {
- }
-
size_t end_pc()
{
return _block_end_pc;
@@ -53,22 +46,20 @@
const as_object* object() const
{
- return _object.get();
+ return _object;
}
as_object* object()
{
- return _object.get();
+ return _object;
}
private:
- boost::intrusive_ptr<as_object> _object;
+ as_object* _object;
size_t _block_end_pc;
-
-
};
} // end namespace gnash
=== modified file 'testsuite/actionscript.all/array.as'
--- a/testsuite/actionscript.all/array.as 2009-10-16 14:18:01 +0000
+++ b/testsuite/actionscript.all/array.as 2009-10-21 12:43:52 +0000
@@ -1605,9 +1605,84 @@
check_equals(o.length, 6);
o.sort();
-xcheck_equals(traceProps(o), "5,4,2,1,0,sort,length,7,6,3,");
+#if OUTPUT_VERSION > 6
+ xcheck_equals(traceProps(o), "5,4,2,1,0,sort,length,7,6,3,");
+#else
+ xcheck_equals(traceProps(o), "5,4,3,2,1,sort,length,7,6,");
+#endif
o.sort();
-xcheck_equals(traceProps(o), "5,4,2,1,0,sort,length,7,6,3,");
+#if OUTPUT_VERSION > 6
+ xcheck_equals(traceProps(o), "5,4,2,1,0,sort,length,7,6,3,");
+#else
+ xcheck_equals(traceProps(o), "5,4,3,2,1,sort,length,7,6,");
+#endif
+
+#if OUTPUT_VERSION > 5
+
+/// This checks that Array and relay objects are not compatible (unlike
+/// DisplayObjects).
+CA = function () {
+ backup = this;
+ this.__proto__.__constructor__ = Date;
+ super ();
+ check_equals(this.length, undefined);
+ this.__proto__.__constructor__ = Array;
+ super ();
+ check_equals(backup, this);
+ check_equals(this.length, 0);
+ this[2] = 3;
+ check_equals(this.length, 3);
+ this.__proto__.__constructor__ = Date;
+ super ();
+ check_equals(this.length, 3);
+ this[6] = 3;
+ check_equals(this.length, 3);
+};
+
+o = new CA();
+
+
+/// Test what happens with []
+backup = _global.Array;
+delete _global.Array;
+
+_global.Array = 8;
+ar = [];
+check_equals(typeof(ar.constructor), "undefined");
+
+h = function() {};
+h.prototype = 8;
+
+_global.Array = h;
+
+ar = [];
+check_equals(typeof(ar.constructor), "function");
+check_equals(typeof(ar.__proto__), "number");
+check_equals(ar.__proto__, 8);
+
+/// If we use the constructor, it's set to anything you like.
+ar = new Array();
+check_equals(typeof(ar.__proto__), "number");
+
+/// Properties are only set if there is a _global.Array.prototype
+
+_global.Array = {};
+
+ar = [];
+check_equals(typeof(ar.constructor), "undefined");
+check_equals(typeof(ar.__proto__), "undefined");
+check_equals(ar.__proto__, undefined);
+
+_global.Array.prototype = "string";
+
+ar = [];
+check_equals(typeof(ar.constructor), "object");
+check_equals(typeof(ar.__proto__), "string");
+check_equals(ar.__proto__, "string");
+
+#endif
+
+
// TODO: test ASnative-returned functions:
//
@@ -1630,8 +1705,8 @@
check_totals(538);
#else
# if OUTPUT_VERSION < 7
- check_totals(599);
+ check_totals(616);
# else
- check_totals(609);
+ check_totals(626);
# endif
#endif
=== modified file 'testsuite/swfdec/PASSING'
--- a/testsuite/swfdec/PASSING 2009-10-15 12:29:22 +0000
+++ b/testsuite/swfdec/PASSING 2009-10-21 13:17:14 +0000
@@ -55,6 +55,10 @@
array-new-7.swf:77c4510eed0fd37d8654f761800edcce
array-new-8.swf:8b26fcd892b0cd7a1cd2832d3844d00d
array-new-override-5.swf:5016b51c60e30ee262b3cb022ba4c58f
+array-no-object-5.swf:5ed032608114aab258046f7b03a600a1
+array-no-object-6.swf:024a80f84a2f9ec3c465e38d1e5c4e69
+array-no-object-7.swf:57e4d1f02420a4cbb67ce4376ff2c431
+array-no-object-8.swf:d79cc40101cf7aa9c549c56625520d00
array-properties-5.swf:e4b9235bdad5543e29893d8166c16a9a
array-properties-6.swf:822c1697e2f36bdfc87574a100583c78
array-properties-7.swf:bd3778e753752345ae8c2d72b3ccaf3a
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] /srv/bzr/gnash/trunk r11582: Drop more static data, correct native array construction.,
Benjamin Wolsey <=