[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] /srv/bzr/gnash/trunk r11561: Widespread but relatively un
From: |
Benjamin Wolsey |
Subject: |
[Gnash-commit] /srv/bzr/gnash/trunk r11561: Widespread but relatively unimportant changes to get rid of annoyances and |
Date: |
Wed, 14 Oct 2009 18:40:32 +0200 |
User-agent: |
Bazaar (1.16.1) |
------------------------------------------------------------
revno: 11561 [merge]
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Wed 2009-10-14 18:40:32 +0200
message:
Widespread but relatively unimportant changes to get rid of annoyances and
misleading code (intrusive_ptr).
Various changes to the Array implementation so that it's less type-dependant
and closer to the target implementation.
modified:
libcore/Button.cpp
libcore/MovieClip.cpp
libcore/MovieClip.h
libcore/PropertyList.cpp
libcore/PropertyList.h
libcore/TextField.cpp
libcore/Video.cpp
libcore/as_function.cpp
libcore/as_object.cpp
libcore/as_object.h
libcore/as_value.cpp
libcore/as_value.h
libcore/asobj/Array_as.cpp
libcore/asobj/Array_as.h
libcore/asobj/AsBroadcaster.cpp
libcore/asobj/Color_as.cpp
libcore/asobj/Global_as.h
libcore/asobj/Globals.cpp
libcore/asobj/Globals.h
libcore/asobj/LoadableObject.cpp
libcore/asobj/MovieClipLoader.cpp
libcore/asobj/Object.cpp
libcore/asobj/QName_as.cpp
libcore/asobj/Selection_as.cpp
libcore/asobj/String_as.cpp
libcore/asobj/TextFormat_as.cpp
libcore/asobj/flash/display/BitmapData_as.cpp
libcore/asobj/flash/display/DisplayObjectContainer_as.cpp
libcore/asobj/flash/display/MovieClip_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/geom/Transform_as.cpp
libcore/asobj/flash/media/Camera_as.cpp
libcore/asobj/flash/media/Microphone_as.cpp
libcore/asobj/flash/media/Sound_as.cpp
libcore/asobj/flash/net/LocalConnection_as.cpp
libcore/asobj/flash/net/NetStream_as.cpp
libcore/asobj/flash/net/SharedObject_as.cpp
libcore/asobj/flash/text/TextSnapshot_as.cpp
libcore/asobj/flash/text/TextSnapshot_as.h
libcore/asobj/flash/ui/ContextMenu_as.cpp
libcore/asobj/flash/xml/XMLDocument_as.cpp
libcore/asobj/flash/xml/XMLNode_as.cpp
libcore/movie_root.cpp
libcore/swf_function.cpp
libcore/swf_function.h
libcore/vm/ASHandlers.cpp
libcore/vm/Machine.cpp
testsuite/actionscript.all/array.as
testsuite/swfdec/PASSING
=== modified file 'libcore/Button.cpp'
--- a/libcore/Button.cpp 2009-10-12 12:06:51 +0000
+++ b/libcore/Button.cpp 2009-10-14 08:47:08 +0000
@@ -1024,7 +1024,7 @@
as_value
button_blendMode(const fn_call& fn)
{
- as_object* obj = ensureType<Button>(fn.this_ptr).get();
+ as_object* obj = ensureType<Button>(fn.this_ptr);
UNUSED(obj);
return as_value();
}
@@ -1032,7 +1032,7 @@
as_value
button_cacheAsBitmap(const fn_call& fn)
{
- as_object* obj = ensureType<Button>(fn.this_ptr).get();
+ as_object* obj = ensureType<Button>(fn.this_ptr);
UNUSED(obj);
return as_value();
}
@@ -1040,7 +1040,7 @@
as_value
button_filters(const fn_call& fn)
{
- as_object* obj = ensureType<Button>(fn.this_ptr).get();
+ as_object* obj = ensureType<Button>(fn.this_ptr);
UNUSED(obj);
return as_value();
}
@@ -1048,7 +1048,7 @@
as_value
button_scale9Grid(const fn_call& fn)
{
- as_object* obj = ensureType<Button>(fn.this_ptr).get();
+ as_object* obj = ensureType<Button>(fn.this_ptr);
UNUSED(obj);
return as_value();
}
@@ -1056,7 +1056,7 @@
as_value
button_getTabIndex(const fn_call& fn)
{
- as_object* obj = ensureType<Button>(fn.this_ptr).get();
+ as_object* obj = ensureType<Button>(fn.this_ptr);
UNUSED(obj);
return as_value();
}
@@ -1064,7 +1064,7 @@
as_value
button_setTabIndex(const fn_call& fn)
{
- as_object* obj = ensureType<Button>(fn.this_ptr).get();
+ as_object* obj = ensureType<Button>(fn.this_ptr);
UNUSED(obj);
return as_value();
}
@@ -1072,7 +1072,7 @@
as_value
button_getDepth(const fn_call& fn)
{
- as_object* obj = ensureType<Button>(fn.this_ptr).get();
+ as_object* obj = ensureType<Button>(fn.this_ptr);
UNUSED(obj);
return as_value();
}
=== modified file 'libcore/MovieClip.cpp'
--- a/libcore/MovieClip.cpp 2009-10-13 07:59:26 +0000
+++ b/libcore/MovieClip.cpp 2009-10-14 08:47:08 +0000
@@ -597,47 +597,15 @@
}
DisplayObject*
-MovieClip::add_empty_movieclip(const std::string& name, int depth)
+MovieClip::addDisplayListObject(DisplayObject* obj, int depth)
{
- MovieClip* movieclip = new MovieClip(0, _swf, this);
- movieclip->set_name(name);
- movieclip->setDynamic();
-
// TODO: only call set_invalidated if this DisplayObject actually overrides
// an existing one !
set_invalidated();
-
- _displayList.placeDisplayObject(movieclip, depth);
-
- return movieclip;
-}
-
-boost::intrusive_ptr<DisplayObject>
-MovieClip::add_textfield(const std::string& name, int depth, int x, int y,
- float width, float height)
-{
-
- // Set textfield bounds
- SWFRect bounds(0, 0, pixelsToTwips(width), pixelsToTwips(height));
-
- // Create an instance
- boost::intrusive_ptr<DisplayObject> txt_char = new TextField(this, bounds);
-
- // Give name and mark as dynamic
- txt_char->set_name(name);
- txt_char->setDynamic();
-
- // Set _x and _y
- SWFMatrix txt_matrix;
- txt_matrix.set_translation(pixelsToTwips(x), pixelsToTwips(y));
- // update caches (although shouldn't be needed as we only set translation)
- txt_char->setMatrix(txt_matrix, true);
-
- // Here we add the DisplayObject to the displayList.
- _displayList.placeDisplayObject(txt_char.get(), depth);
-
- return txt_char;
-}
+ _displayList.placeDisplayObject(obj, depth);
+ return obj;
+}
+
boost::intrusive_ptr<MovieClip>
MovieClip::duplicateMovieClip(const std::string& newname, int depth,
@@ -847,7 +815,7 @@
return tmp.to_sprite(true);
}
- return tmp.to_object(*getGlobal(*this)).get();
+ return tmp.to_object(*getGlobal(*this));
}
bool
=== modified file 'libcore/MovieClip.h'
--- a/libcore/MovieClip.h 2009-10-13 07:59:26 +0000
+++ b/libcore/MovieClip.h 2009-10-14 06:55:13 +0000
@@ -318,10 +318,8 @@
///
DisplayObject* getDisplayObjectAtDepth(int depth);
- DisplayObject* add_empty_movieclip(const std::string& name, int depth);
-
- boost::intrusive_ptr<DisplayObject> add_textfield(const std::string& name,
- int depth, int x, int y, float width, float height);
+ /// Attach a DisplayObject at the specified depth.
+ DisplayObject* addDisplayListObject(DisplayObject* obj, int depth);
/// Place a DisplayObject or mask to the DisplayList.
//
=== modified file 'libcore/PropertyList.cpp'
--- a/libcore/PropertyList.cpp 2009-07-30 11:20:20 +0000
+++ b/libcore/PropertyList.cpp 2009-10-14 08:47:08 +0000
@@ -65,7 +65,7 @@
// something in namespace 0.
static inline
PropertyList::container::iterator
-iterator_find(PropertyList::container &p, string_table::key name,
+iterator_find(const PropertyList::container &p, string_table::key name,
string_table::key nsId)
{
if (nsId)
@@ -251,13 +251,10 @@
}
Property*
-PropertyList::getProperty(string_table::key key, string_table::key nsId)
+PropertyList::getProperty(string_table::key key, string_table::key nsId) const
{
container::iterator found = iterator_find(_props, key, nsId);
- if (found == _props.end())
- {
- return NULL;
- }
+ if (found == _props.end()) return 0;
return const_cast<Property*>(&(*found));
}
=== modified file 'libcore/PropertyList.h'
--- a/libcore/PropertyList.h 2009-07-29 14:33:56 +0000
+++ b/libcore/PropertyList.h 2009-10-14 08:47:08 +0000
@@ -298,7 +298,8 @@
/// ownership of returned Propery is kept by the PropertyList,
/// so plase *don't* delete it !
///
- Property* getProperty(string_table::key key, string_table::key nsId =
0);
+ Property* getProperty(string_table::key key, string_table::key nsId = 0)
+ const;
/// Get a property, if existing, by order
///
=== modified file 'libcore/TextField.cpp'
--- a/libcore/TextField.cpp 2009-10-12 12:15:41 +0000
+++ b/libcore/TextField.cpp 2009-10-14 14:50:52 +0000
@@ -88,6 +88,8 @@
void attachPrototypeProperties(as_object& proto);
void attachTextFieldStaticMembers(as_object& o);
+ as_value textfield_createTextField(const fn_call& fn);
+
as_value textfield_variable(const fn_call& fn);
as_value textfield_setTextFormat(const fn_call& fn);
as_value textfield_getTextFormat(const fn_call& fn);
@@ -254,17 +256,12 @@
{
as_object* proto = getTextFieldInterface(getVM(*this));
+ attachPrototypeProperties(*proto);
- // This is an instantiation, so attach properties to the
- // prototype.
- // TODO: is it correct to do it here, or can some TextFields
- // be constructed without attaching these?
- attachPrototypeProperties(*proto);
-
set_prototype(proto);
- Array_as* ar = new Array_as();
- ar->push(this);
+ as_object* ar = getGlobal(*this)->createArray();
+ ar->callMethod(NSV::PROP_PUSH, this);
set_member(NSV::PROP_uLISTENERS, ar);
registerTextVariable();
@@ -2362,6 +2359,9 @@
vm.registerNative(textfield_setNewTextFormat, 104, 105);
vm.registerNative(textfield_getDepth, 104, 106);
vm.registerNative(textfield_replaceText, 104, 107);
+
+ vm.registerNative(textfield_createTextField, 104, 200);
+ vm.registerNative(textfield_getFontList, 104, 201);
}
bool
@@ -2797,12 +2797,8 @@
void
attachPrototypeProperties(as_object& o)
{
- // Standard flags.
- const int flags = PropFlags::dontDelete
- |PropFlags::dontEnum;
-
// SWF6 or higher
- const int swf6Flags = flags | PropFlags::onlySWF6Up;
+ const int swf6Flags = as_object::DefaultFlags | PropFlags::onlySWF6Up;
boost::intrusive_ptr<builtin_function> getset;
@@ -2866,6 +2862,68 @@
}
+/// This is in fact a property of MovieClip, but it is more a TextField
+/// function, as its major number (104) in the native table shows.
+as_value
+textfield_createTextField(const fn_call& fn)
+{
+ boost::intrusive_ptr<MovieClip> ptr = ensureType<MovieClip>(fn.this_ptr);
+
+ // name, depth, x, y, width, height
+ if (fn.nargs < 6) {
+ IF_VERBOSE_ASCODING_ERRORS(
+ log_aserror(_("createTextField called with %d args, "
+ "expected 6 - returning undefined"), fn.nargs);
+ );
+ return as_value();
+ }
+
+ const std::string& name = fn.arg(0).to_string();
+ int depth = fn.arg(1).to_int();
+ int x = fn.arg(2).to_int();
+ int y = fn.arg(3).to_int();
+ int width = fn.arg(4).to_int();
+
+ if (width < 0) {
+ IF_VERBOSE_ASCODING_ERRORS(
+ log_aserror(_("createTextField: negative width (%d)"
+ " - reverting sign"), width);
+ );
+ width = -width;
+ }
+
+ int height = fn.arg(5).to_int();
+ if ( height < 0 )
+ {
+ IF_VERBOSE_ASCODING_ERRORS(
+ log_aserror(_("createTextField: negative height (%d)"
+ " - reverting sign"), height);
+ );
+ height = -height;
+ }
+ // Set textfield bounds
+ SWFRect bounds(0, 0, pixelsToTwips(width), pixelsToTwips(height));
+
+ // Create an instance
+ DisplayObject* tf = new TextField(ptr.get(), bounds);
+
+ // Give name and mark as dynamic
+ tf->set_name(name);
+ tf->setDynamic();
+
+ // Set _x and _y
+ SWFMatrix matrix;
+ matrix.set_translation(pixelsToTwips(x), pixelsToTwips(y));
+ // update caches (although shouldn't be needed as we only set translation)
+ tf->setMatrix(matrix, true);
+
+ DisplayObject* txt = ptr->addDisplayListObject(tf, depth);
+
+ // createTextField returns void, it seems
+ if (getSWFVersion(fn) > 7) return as_value(txt);
+ return as_value();
+}
+
as_value
textfield_background(const fn_call& fn)
{
@@ -3281,7 +3339,7 @@
}
TextFormat_as* tf;
- if (!isNativeType(fn.arg(0).to_object(*getGlobal(fn)).get(), tf)) {
+ if (!isNativeType(fn.arg(0).to_object(*getGlobal(fn)), tf)) {
IF_VERBOSE_ASCODING_ERRORS(
std::stringstream ss; fn.dump_args(ss);
@@ -3661,17 +3719,10 @@
void
attachTextFieldStaticMembers(as_object& o)
{
- // Standard flags.
- const int flags = PropFlags::dontDelete
- |PropFlags::dontEnum;
-
// SWF6 or higher
- const int swf6Flags = flags | PropFlags::onlySWF6Up;
-
- Global_as* gl = getGlobal(o);
- o.init_member("getFontList",
- gl->createFunction(textfield_getFontList), swf6Flags);
-
+ const int swf6Flags = as_object::DefaultFlags | PropFlags::onlySWF6Up;
+ VM& vm = getVM(o);
+ o.init_member("getFontList", vm.getNative(104, 201), swf6Flags);
}
/// This is called when a prototype should be added
=== modified file 'libcore/Video.cpp'
--- a/libcore/Video.cpp 2009-10-12 09:42:13 +0000
+++ b/libcore/Video.cpp 2009-10-14 08:47:08 +0000
@@ -394,7 +394,7 @@
return as_value();
}
- as_object* obj = fn.arg(0).to_object(*getGlobal(fn)).get();
+ as_object* obj = fn.arg(0).to_object(*getGlobal(fn));
NetStream_as* ns;
if (isNativeType(obj, ns)) {
=== modified file 'libcore/as_function.cpp'
--- a/libcore/as_function.cpp 2009-08-20 12:19:38 +0000
+++ b/libcore/as_function.cpp 2009-10-14 08:47:08 +0000
@@ -195,7 +195,7 @@
// 'this' pointer. Others return a new object. This is to handle those
// cases.
if (isBuiltin() && ret.is_object()) {
- newobj = ret.to_object(*getGlobal(env)).get();
+ newobj = ret.to_object(*getGlobal(env));
newobj->init_member(NSV::PROP_uuCONSTRUCTORuu, as_value(this),
flags);
@@ -294,7 +294,7 @@
else
{
// Get the object to use as 'this' reference
- as_object* obj = fn.arg(0).to_object(*getGlobal(fn)).get();
+ as_object* obj = fn.arg(0).to_object(*getGlobal(fn));
if (!obj) obj = new as_object;
@@ -377,7 +377,7 @@
else {
// Get the object to use as 'this' reference
as_value this_val = fn.arg(0);
- as_object* this_ptr = this_val.to_object(*getGlobal(fn)).get();
+ as_object* this_ptr = this_val.to_object(*getGlobal(fn));
if (!this_ptr) {
// If the first argument is not an object, we should
@@ -397,7 +397,7 @@
}
else {
new_fn_call.this_ptr = this_ptr;
- as_object* proto = this_ptr->get_prototype().get();
+ as_object* proto = this_ptr->get_prototype();
if (proto) {
new_fn_call.super = this_ptr->get_super();
}
=== modified file 'libcore/as_object.cpp'
--- a/libcore/as_object.cpp 2009-10-12 08:56:07 +0000
+++ b/libcore/as_object.cpp 2009-10-14 08:47:08 +0000
@@ -107,7 +107,7 @@
throw ActionLimitException("Lookup depth exceeded.");
}
- _object = _object->get_prototype().get();
+ _object = _object->get_prototype();
// TODO: there is recursion prevention anyway; is this extra
// check for circularity really necessary?
@@ -218,7 +218,7 @@
private:
as_object* prototype() {
- return _super ? _super->get_prototype().get() : 0;
+ return _super ? _super->get_prototype() : 0;
}
as_function* constructor() {
@@ -236,7 +236,7 @@
// Our class superclass prototype is __proto__.__proto__
// Our class prototype is __proto__.
- as_object* proto = get_prototype().get();
+ as_object* proto = get_prototype();
if (!proto) return new as_super(*getGlobal(*this), 0);
if (!fname || getSWFVersion(*this) <= 6) {
@@ -254,7 +254,7 @@
as_object* tmp = proto;
while (tmp && tmp->get_prototype() != owner) {
- tmp = tmp->get_prototype().get();
+ tmp = tmp->get_prototype();
}
// ok, now 'tmp' should be the object whose __proto__ member
// contains the actual named method.
@@ -486,7 +486,7 @@
as_object *obj = this;
while (depth--)
{
- obj = obj->get_prototype().get();
+ obj = obj->get_prototype();
if (!obj)
return NULL;
}
@@ -502,7 +502,7 @@
// Our class superclass prototype is __proto__.__proto__
// Our class prototype is __proto__.
- as_object* proto = get_prototype().get();
+ as_object* proto = get_prototype();
if ( fname && getSWFVersion(*this) > 6)
{
@@ -542,7 +542,7 @@
as_object *obj = this;
while (i--)
{
- obj = obj->get_prototype().get();
+ obj = obj->get_prototype();
if (!obj)
return 0;
}
@@ -550,7 +550,7 @@
const Property *p = obj->_members.getOrderAfter(index);
if (!p)
{
- obj = obj->get_prototype().get();
+ obj = obj->get_prototype();
if (!obj)
return 0;
p = obj->_members.getOrderAfter(0);
@@ -940,7 +940,7 @@
#endif
return false;
}
- as_object* ctorProto = protoVal.to_object(*getGlobal(*this)).get();
+ as_object* ctorProto = protoVal.to_object(*getGlobal(*this));
if ( ! ctorProto )
{
#ifdef GNASH_DEBUG_INSTANCE_OF
@@ -957,7 +957,7 @@
as_object* obj = this;
while (obj && visited.insert(obj).second )
{
- as_object* thisProto = obj->get_prototype().get();
+ as_object* thisProto = obj->get_prototype();
if ( ! thisProto )
{
break;
@@ -1186,14 +1186,14 @@
return getOwnProperty(key, nsname) != NULL;
}
-boost::intrusive_ptr<as_object>
-as_object::get_prototype()
+as_object*
+as_object::get_prototype() const
{
int swfVersion = getSWFVersion(*this);
Property* prop = _members.getProperty(NSV::PROP_uuPROTOuu);
- if ( ! prop ) return 0;
- if ( ! prop->visible(swfVersion) ) return 0;
+ if (!prop) return 0;
+ if (!prop->visible(swfVersion)) return 0;
as_value tmp = prop->getValue(*this);
@@ -1325,7 +1325,7 @@
return NULL;
}
- return tmp.to_object(*getGlobal(*this)).get();
+ return tmp.to_object(*getGlobal(*this));
}
void
=== modified file 'libcore/as_object.h'
--- a/libcore/as_object.h 2009-10-12 08:56:07 +0000
+++ b/libcore/as_object.h 2009-10-14 08:47:08 +0000
@@ -983,12 +983,7 @@
///
/// NOTE: can return NULL (and it is expected to do for Object.prototype)
///
- boost::intrusive_ptr<as_object> get_prototype();
-
- const boost::intrusive_ptr<as_object> get_prototype() const {
- // cast away constness
- return const_cast<as_object*>(this)->get_prototype();
- }
+ as_object* get_prototype() const;
/// Set this object's '__proto__' member
//
@@ -1185,14 +1180,14 @@
/// @param obj the pointer to be cast.
/// @return If the cast succeeds, the pointer cast to the requested type.
template <typename T>
-boost::intrusive_ptr<T>
-ensureType(boost::intrusive_ptr<as_object> obj)
+T*
+ensureType(as_object* obj)
{
- boost::intrusive_ptr<T> ret = boost::dynamic_pointer_cast<T>(obj);
+ T* ret = dynamic_cast<T*>(obj);
if (!ret) {
- std::string target = typeName(ret.get());
- std::string source = typeName(obj.get());
+ std::string target = typeName(ret);
+ std::string source = typeName(obj);
std::string msg = "builtin method or gettersetter for " +
target + " called from " + source + " instance.";
=== modified file 'libcore/as_value.cpp'
--- a/libcore/as_value.cpp 2009-10-07 09:30:57 +0000
+++ b/libcore/as_value.cpp 2009-10-14 14:26:23 +0000
@@ -315,12 +315,10 @@
:
m_type(AS_FUNCTION)
{
- if ( func )
- {
- _value = boost::intrusive_ptr<as_object>(func);
+ if (func) {
+ _value = func;
}
- else
- {
+ else {
m_type = NULLTYPE;
_value = boost::blank();
}
@@ -379,8 +377,7 @@
case AS_FUNCTION:
case OBJECT:
{
- as_object* obj = m_type == AS_FUNCTION ? getFun().get() :
- getObj().get();
+ as_object* obj = m_type == AS_FUNCTION ? getFun() : getObj();
String_as* s;
if (isNativeType(obj, s)) return s->value();
@@ -469,7 +466,7 @@
if (m_type == OBJECT && swfVersion > 5) {
Date_as* d;
- if (isNativeType(getObj().get(), d)) hint = STRING;
+ if (isNativeType(getObj(), d)) hint = STRING;
}
return to_primitive(hint);
@@ -485,7 +482,7 @@
if (m_type == OBJECT && swfVersion > 5) {
Date_as* d;
- if (isNativeType<Date_as>(getObj().get(), d)) hint = STRING;
+ if (isNativeType<Date_as>(getObj(), d)) hint = STRING;
}
*this = to_primitive(hint);
@@ -515,8 +512,8 @@
return as_value(NaN);
}
#endif
- if ( m_type == OBJECT ) obj = getObj().get();
- else obj = getFun().get();
+ if ( m_type == OBJECT ) obj = getObj();
+ else obj = getFun();
if ((!obj->get_member(NSV::PROP_VALUE_OF, &method)) ||
(!method.is_function()))
{
@@ -539,8 +536,8 @@
return as_value(getCharacterProxy().getTarget());
}
- if ( m_type == OBJECT ) obj = getObj().get();
- else obj = getFun().get();
+ if ( m_type == OBJECT ) obj = getObj();
+ else obj = getFun();
// @@ Moock says, "the value that results from
// calling toString() on the object".
@@ -902,21 +899,19 @@
}
// Return value as an object.
-boost::intrusive_ptr<as_object>
+as_object*
as_value::to_object(Global_as& global) const
{
- typedef boost::intrusive_ptr<as_object> ptr;
-
switch (m_type)
{
case OBJECT:
return getObj();
case AS_FUNCTION:
- return getFun().get();
+ return getFun();
case MOVIECLIP:
- return ptr(toDisplayObject());
+ return toDisplayObject();
case STRING:
return global.createString(getStr());
@@ -952,12 +947,6 @@
}
void
-as_value::set_sprite(MovieClip& sprite)
-{
- setDisplayObject(sprite);
-}
-
-void
as_value::setDisplayObject(DisplayObject& sprite)
{
m_type = MOVIECLIP;
@@ -971,7 +960,7 @@
{
if (m_type == AS_FUNCTION) {
// OK.
- return getFun().get();
+ return getFun();
}
return NULL;
@@ -999,10 +988,10 @@
set_null();
return;
}
- DisplayObject* sp = obj->toDisplayObject();
- if ( sp )
- {
- setDisplayObject(*sp);
+ if (obj->displayObject()) {
+ // The static cast is fine as long as the as_object is genuinely
+ // a DisplayObject.
+ setDisplayObject(static_cast<DisplayObject&>(*obj));
return;
}
as_function* func = obj->to_function();
@@ -1014,7 +1003,7 @@
if (m_type != OBJECT || getObj() != obj)
{
m_type = OBJECT;
- _value = boost::intrusive_ptr<as_object>(obj);
+ _value = obj;
}
}
@@ -1027,12 +1016,12 @@
void
as_value::set_as_function(as_function* func)
{
- if (m_type != AS_FUNCTION || getFun().get() != func)
+ if (m_type != AS_FUNCTION || getFun() != func)
{
m_type = AS_FUNCTION;
if (func)
{
- _value = boost::intrusive_ptr<as_object>(func);
+ _value = func;
}
else
{
@@ -1043,13 +1032,6 @@
}
bool
-as_value::conforms_to(string_table::key /*name*/)
-{
- // TODO: Implement
- return false;
-}
-
-bool
as_value::equals(const as_value& v) const
{
// Comments starting with numbers refer to the ECMA-262 document
@@ -1087,7 +1069,7 @@
/// Compare to same type
if ( obj_or_func && v_obj_or_func )
{
- return boost::get<AsObjPtr>(_value) == boost::get<AsObjPtr>(v._value);
+ return boost::get<as_object*>(_value) ==
boost::get<as_object*>(v._value);
}
if ( m_type == v.m_type ) return equalsSameType(v);
@@ -1373,13 +1355,13 @@
return ret.str();
case OBJECT:
{
- as_object* obj = getObj().get();
+ as_object* obj = getObj();
ret = boost::format("[object(%s):%p]") % typeName(*obj)
% static_cast<void*>(obj);
return ret.str();
}
case AS_FUNCTION:
{
- as_function* obj = getFun().get();
+ as_function* obj = getFun();
ret = boost::format("[function(%s):%p]") %
typeName(*obj) % static_cast<void*>(obj);
return ret.str();
}
@@ -1566,14 +1548,14 @@
{
case OBJECT:
{
- as_value::AsObjPtr op = getObj();
+ as_object* op = getObj();
if (op)
op->setReachable();
break;
}
case AS_FUNCTION:
{
- as_value::AsFunPtr fp = getFun();
+ as_function* fp = getFun();
if (fp)
fp->setReachable();
break;
@@ -1589,18 +1571,18 @@
#endif // GNASH_USE_GC
}
-as_value::AsFunPtr
+as_function*
as_value::getFun() const
{
assert(m_type == AS_FUNCTION);
- return boost::get<AsObjPtr>(_value)->to_function();
+ return boost::get<as_object*>(_value)->to_function();
}
-as_value::AsObjPtr
+as_object*
as_value::getObj() const
{
assert(m_type == OBJECT);
- return boost::get<AsObjPtr>(_value);
+ return boost::get<as_object*>(_value);
}
CharacterProxy
@@ -1616,15 +1598,6 @@
return getCharacterProxy().get(allowUnloaded);
}
-as_value::SpritePtr
-as_value::getSprite(bool allowUnloaded) const
-{
- assert(m_type == MOVIECLIP);
- DisplayObject* ch = getCharacter(allowUnloaded);
- if ( ! ch ) return 0;
- return ch->to_movie();
-}
-
void
as_value::set_string(const std::string& str)
{
@@ -1704,6 +1677,7 @@
VM& vm = VM::get();
string_table& st = vm.getStringTable();
+ Global_as* gl = vm.getGlobal();
switch (el.getType()) {
case amf::Element::NOTYPE:
@@ -1813,7 +1787,9 @@
#ifdef GNASH_DEBUG_AMF_DESERIALIZE
log_debug("as_value(Element&) : AMF type ECMA_ARRAY");
#endif
- Array_as* obj = new Array_as;
+
+ 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);
@@ -1834,9 +1810,9 @@
#ifdef GNASH_DEBUG_AMF_DESERIALIZE
log_debug("as_value(Element&) : AMF type STRICT_ARRAY");
#endif
- Array_as* obj = new Array_as;
+ as_object* obj = gl->createArray();
size_t len = el.propertySize();
- obj->resize(len);
+ 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);
@@ -1947,6 +1923,8 @@
}
}
+ Global_as* gl = vm.getGlobal();
+
switch (amf_type)
{
@@ -2032,89 +2010,89 @@
case amf::Element::STRICT_ARRAY_AMF0:
{
- boost::intrusive_ptr<Array_as> array(new
Array_as());
- objRefs.push_back(array.get());
+ as_object* array = gl->createArray();
+ objRefs.push_back(array);
- boost::uint32_t li = readNetworkLong(b); b += 4;
+ boost::uint32_t li = readNetworkLong(b); b += 4;
#ifdef GNASH_DEBUG_AMF_DESERIALIZE
- log_debug("amf0 starting read of STRICT_ARRAY
with %i elements", li);
+ log_debug("amf0 starting read of STRICT_ARRAY with %i elements",
li);
#endif
- as_value arrayElement;
- for(size_t i = 0; i < li; ++i)
- {
- if ( ! amf0_read_value(b, end,
arrayElement, -1,
- objRefs, vm) )
- {
- return false;
- }
- array->push(arrayElement);
- }
+ as_value arrayElement;
+ for (size_t i = 0; i < li; ++i)
+ {
+ if ( ! amf0_read_value(b, end, arrayElement, -1,
+ objRefs, vm) )
+ {
+ return false;
+ }
+ array->callMethod(NSV::PROP_PUSH, arrayElement);
+ }
- ret.set_as_object(array);
- return true;
+ ret.set_as_object(array);
+ return true;
}
case amf::Element::ECMA_ARRAY_AMF0:
{
- Array_as* obj = new Array_as(); // GC-managed...
- objRefs.push_back(obj);
-
- // set the value immediately, so if there's any problem parsing
- // (like premature end of buffer) we still get something.
- ret.set_as_object(obj);
-
- boost::uint32_t li = readNetworkLong(b); b += 4;
-
- 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
- obj->resize(li);
-
- // TODO: do boundary checking (if b >= end...)
-
-#ifdef GNASH_DEBUG_AMF_DESERIALIZE
- log_debug("amf0 starting read of ECMA_ARRAY
with %i elements", li);
-#endif
- as_value objectElement;
- string_table& st = vm.getStringTable();
- for (;;)
- {
- if ( b+2 >= end )
- {
- log_error("MALFORMED SOL: premature end of ECMA_ARRAY "
- "block");
- break;
- }
- boost::uint16_t strlen =
readNetworkShort(b); b+=2;
-
- // end of ECMA_ARRAY is signalled by an empty string
- // followed by an OBJECT_END_AMF0 (0x09) byte
- if ( ! strlen )
- {
- // expect an object terminator here
- if ( *b++ != amf::Element::OBJECT_END_AMF0 )
- {
- log_error("MALFORMED SOL: empty member name not "
- "followed by OBJECT_END_AMF0 byte");
- }
- break;
- }
-
- std::string name(reinterpret_cast<const
char*>(b), strlen);
-
-#ifdef GNASH_DEBUG_AMF_DESERIALIZE
- log_debug("amf0 ECMA_ARRAY prop name is
%s", name);
-#endif
- b += strlen;
- if ( ! amf0_read_value(b, end,
objectElement, -1, objRefs, vm) )
- {
- return false;
- }
- obj->set_member(st.find(name),
objectElement);
- }
-
- return true;
+ as_object* obj = gl->createArray();
+ objRefs.push_back(obj);
+
+ // set the value immediately, so if there's any problem parsing
+ // (like premature end of buffer) we still get something.
+ ret.set_as_object(obj);
+
+ boost::uint32_t li = readNetworkLong(b); b += 4;
+
+ 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
+ obj->set_member(NSV::PROP_LENGTH, li);
+
+ // TODO: do boundary checking (if b >= end...)
+
+#ifdef GNASH_DEBUG_AMF_DESERIALIZE
+ log_debug("amf0 starting read of ECMA_ARRAY with %i elements", li);
+#endif
+ as_value objectElement;
+ string_table& st = vm.getStringTable();
+ for (;;)
+ {
+ if ( b+2 >= end )
+ {
+ log_error("MALFORMED SOL: premature end of ECMA_ARRAY "
+ "block");
+ break;
+ }
+ boost::uint16_t strlen = readNetworkShort(b); b+=2;
+
+ // end of ECMA_ARRAY is signalled by an empty string
+ // followed by an OBJECT_END_AMF0 (0x09) byte
+ if ( ! strlen )
+ {
+ // expect an object terminator here
+ if ( *b++ != amf::Element::OBJECT_END_AMF0 )
+ {
+ log_error("MALFORMED SOL: empty member name not "
+ "followed by OBJECT_END_AMF0 byte");
+ }
+ break;
+ }
+
+ std::string name(reinterpret_cast<const char*>(b), strlen);
+
+#ifdef GNASH_DEBUG_AMF_DESERIALIZE
+ log_debug("amf0 ECMA_ARRAY prop name is %s", name);
+#endif
+ b += strlen;
+ if ( ! amf0_read_value(b, end, objectElement, -1, objRefs, vm)
)
+ {
+ return false;
+ }
+ obj->set_member(st.find(name), objectElement);
+ }
+
+ return true;
}
case amf::Element::OBJECT_AMF0:
@@ -2211,7 +2189,6 @@
log_debug("amf0 read date: %e", dub);
#endif
- Global_as* gl = vm.getGlobal();
as_function* ctor =
gl->getMember(NSV::CLASS_DATE).to_as_function();
if (ctor) {
fn_call::Args args;
@@ -2272,7 +2249,7 @@
case OBJECT:
{
- as_object* obj = to_object(*vm.getGlobal()).get();
+ as_object* obj = to_object(*vm.getGlobal());
assert(obj);
OffsetTable::iterator it = offsetTable.find(obj);
if (it == offsetTable.end()) {
=== modified file 'libcore/as_value.h'
--- a/libcore/as_value.h 2009-10-07 07:46:44 +0000
+++ b/libcore/as_value.h 2009-10-14 09:29:00 +0000
@@ -286,7 +286,7 @@
static bool parseNonDecimalInt(const std::string& s, double& d,
bool whole = true);
- /// Return the primitive type of this value, as a string.
+ /// Return the primitive type of this value as a string.
const char* typeOf() const;
/// Get the primitive type of this value
@@ -294,14 +294,10 @@
/// Only used in AVM2
primitive_types ptype() const;
- // Chad: Document
- bool conforms_to(string_table::key name);
-
/// \brief
/// Return true if this value is callable
/// (AS_FUNCTION).
- bool is_function() const
- {
+ bool is_function() const {
return m_type == AS_FUNCTION;
}
@@ -435,7 +431,7 @@
/// @param global The global object object for the conversion. This
/// contains the prototypes or constructors necessary for
/// conversion.
- boost::intrusive_ptr<as_object> to_object(Global_as& global) const;
+ as_object* to_object(Global_as& global) const;
/// Return value as a sprite or NULL if this is not possible.
//
@@ -510,8 +506,11 @@
void set_bool(bool val);
- void set_sprite(MovieClip& sp);
-
+ /// 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); }
@@ -545,19 +544,26 @@
bool is_bool() const { return (m_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 == AS_FUNCTION_EXCEPT
- || m_type == MOVIECLIP_EXCEPT || m_type == STRING_EXCEPT);
+ bool is_exception() const {
+ return (m_type == UNDEFINED_EXCEPT || m_type == NULLTYPE_EXCEPT
+ || m_type == BOOLEAN_EXCEPT || m_type == NUMBER_EXCEPT
+ || m_type == OBJECT_EXCEPT || m_type == AS_FUNCTION_EXCEPT
+ || m_type == MOVIECLIP_EXCEPT || m_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); }
- void unflag_exception()
- { if (is_exception()) m_type =
static_cast<AsType>(static_cast<int>(m_type) - 1); }
+ void flag_exception() {
+ if (!is_exception()) {
+ m_type = static_cast<AsType>(static_cast<int>(m_type) + 1);
+ }
+ }
+
+ void unflag_exception() {
+ if (is_exception()) {
+ m_type = static_cast<AsType>(static_cast<int>(m_type) - 1);
+ }
+ }
/// Return true if this value is strictly equal to the given one
//
@@ -606,10 +612,7 @@
AsType m_type;
- typedef MovieClip* SpritePtr;
typedef DisplayObject* CharacterPtr;
- typedef boost::intrusive_ptr<as_function> AsFunPtr;
- typedef boost::intrusive_ptr<as_object> AsObjPtr;
/// AsValueType handles the following AS types:
//
@@ -620,24 +623,17 @@
/// 5. MovieClip
/// 6. String
typedef boost::variant<boost::blank, double,
- bool, AsObjPtr, CharacterProxy, std::string> AsValueType;
+ bool, as_object*, CharacterProxy, std::string> AsValueType;
AsValueType _value;
-
/// Get the function pointer variant member (we assume m_type ==
FUNCTION)
- AsFunPtr getFun() const;
+ as_function* getFun() const;
/// Get the object pointer variant member (we assume m_type == OBJECT)
- AsObjPtr getObj() const;
-
- /// Get the sprite pointer variant member (we assume m_type ==
MOVIECLIP)
- //
- /// NOTE: this is possibly NULL !
- ///
- SpritePtr getSprite(bool skipRebinding=false) const;
-
- /// Get the DisplayObject pointer variant member (we assume m_type ==
MOVIECLIP)
+ as_object* getObj() const;
+
+ /// Get the DisplayObject variant member (we assume m_type == MOVIECLIP)
//
/// NOTE: this is possibly NULL !
///
@@ -648,22 +644,19 @@
CharacterProxy getCharacterProxy() const;
/// Get the number variant member (we assume m_type == NUMBER)
- double getNum() const
- {
+ double getNum() const {
assert(m_type == NUMBER);
return boost::get<double>(_value);
}
/// Get the boolean variant member (we assume m_type == BOOLEAN)
- bool getBool() const
- {
+ bool getBool() const {
assert(m_type == BOOLEAN);
return boost::get<bool>(_value);
}
/// Get the boolean variant member (we assume m_type == STRING)
- const std::string& getStr() const
- {
+ const std::string& getStr() const {
assert(m_type == STRING);
return boost::get<std::string>(_value);
}
=== modified file 'libcore/asobj/Array_as.cpp'
--- a/libcore/asobj/Array_as.cpp 2009-10-04 15:55:41 +0000
+++ b/libcore/asobj/Array_as.cpp 2009-10-14 15:45:27 +0000
@@ -47,6 +47,23 @@
typedef boost::function2<bool, const as_value&, const as_value&> as_cmp_fn;
+inline string_table::key
+arrayKey(string_table& st, size_t i)
+{
+ std::ostringstream os;
+ os << i;
+ return st.find(os.str());
+}
+
+namespace {
+
+string_table::key getKey(const fn_call& fn, size_t i) {
+ string_table& st = getStringTable(fn);
+ return arrayKey(st, i);
+}
+
+}
+
static as_object* getArrayInterface();
static void attachArrayProperties(as_object& proto);
static void attachArrayInterface(as_object& proto);
@@ -607,61 +624,6 @@
}
void
-Array_as::push(const as_value& val)
-{
- const ArrayContainer::size_type s = elements.size();
- elements.resize(s+1);
- elements[s] = val;
-}
-
-void
-Array_as::unshift(const as_value& val)
-{
- shiftElementsRight(1);
- elements[0] = val;
-}
-
-as_value
-Array_as::pop()
-{
- // If the array is empty, report an error and return undefined!
- const ArrayContainer::size_type s = elements.size();
-
- if ( ! s )
- {
- IF_VERBOSE_ASCODING_ERRORS(
- log_aserror(_("tried to pop element from back of empty array,
returning undef"));
- );
- return as_value(); // undefined
- }
-
- as_value ret = elements[s - 1];
- elements.resize(s - 1);
-
- return ret;
-}
-
-as_value
-Array_as::shift()
-{
- const ArrayContainer::size_type s = elements.size();
-
- // If the array is empty, report an error and return undefined!
- if ( ! s )
- {
- IF_VERBOSE_ASCODING_ERRORS(
- log_aserror(_("tried to shift element from front of empty array,
returning undef"));
- );
- return as_value(); // undefined
- }
-
- as_value ret = elements[0];
- shiftElementsLeft(1);
-
- return ret;
-}
-
-void
Array_as::reverse()
{
const ArrayContainer::size_type s = elements.size();
@@ -709,21 +671,6 @@
}
-void
-Array_as::concat(const Array_as& other)
-{
- for (ArrayContainer::size_type i = 0, e = other.size(); i < e; i++)
- {
- push(other.at(i));
- }
-}
-
-std::string
-Array_as::toString() const
-{
- return join(",");
-}
-
unsigned int
Array_as::size() const
{
@@ -763,20 +710,6 @@
}
-bool
-Array_as::removeFirst(const as_value& v)
-{
- for (iterator it = elements.begin(), e = elements.end(); it != e; ++it)
- {
- if ( v.equals(*it) )
- {
- splice(it.index(), 1);
- return true;
- }
- }
- return false;
-}
-
/* virtual public, overriding as_object::get_member */
bool
Array_as::get_member(string_table::key name, as_value *val,
@@ -844,20 +777,6 @@
elements.resize(newsize);
}
-void
-Array_as::set_indexed(unsigned int index,
- const as_value& val)
-{
- if (index >= elements.size())
- {
- // make sure the vector is large enough.
- elements.resize(index + 1);
- }
-
- elements[index] = val;
- return;
-}
-
/* virtual public, overriding as_object::set_member */
bool
Array_as::set_member(string_table::key name,
@@ -892,7 +811,7 @@
for (std::deque<indexed_as_value>::const_iterator it = elems.begin();
it != elems.end(); ++it)
{
- intIndexes->push(as_value(it->vec_index));
+ intIndexes->callMethod(NSV::PROP_PUSH, it->vec_index);
}
return intIndexes;
}
@@ -1176,67 +1095,119 @@
}
// Callback to push values to the back of an array
-static as_value
+as_value
array_push(const fn_call& fn)
{
- boost::intrusive_ptr<Array_as> array = ensureType<Array_as>(fn.this_ptr);
-
- IF_VERBOSE_ACTION (
- log_action(_("calling array push, pushing %d values onto back of
array"),fn.nargs);
- );
-
- for (unsigned int i=0;i<fn.nargs;i++)
- array->push(fn.arg(i));
-
- return as_value(array->size());
+ as_object* array = ensureType<as_object>(fn.this_ptr);
+
+ if (!fn.nargs) return as_value();
+
+ const size_t shift = fn.nargs;
+
+ as_value length;
+ if (!array->get_member(NSV::PROP_LENGTH, &length)) return as_value();
+
+ const int size = length.to_int();
+ if (size < 0) return as_value();
+
+ for (size_t i = 0; i < fn.nargs; ++i) {
+ array->set_member(getKey(fn, size + i), fn.arg(i));
+ }
+
+ // TODO: this is wrong, but Gnash relies on it.
+ array->set_member(NSV::PROP_LENGTH, size + shift);
+
+ return as_value(size + shift);
}
// Callback to push values to the front of an array
static as_value
array_unshift(const fn_call& fn)
{
- boost::intrusive_ptr<Array_as> array = ensureType<Array_as>(fn.this_ptr);
-
- IF_VERBOSE_ACTION (
- log_action(_("calling array unshift, pushing %d values onto front of
array"), fn.nargs);
- );
-
- for (int i=fn.nargs-1; i>=0; i--)
- array->unshift(fn.arg(i));
-
- return as_value(array->size());
+
+ as_object* array = ensureType<as_object>(fn.this_ptr);
+
+ if (!fn.nargs) return as_value();
+
+ const size_t shift = fn.nargs;
+
+ as_value length;
+ if (!array->get_member(NSV::PROP_LENGTH, &length)) return as_value();
+
+ const int size = length.to_int();
+ if (size < 0) return as_value();
+
+ string_table& st = getStringTable(fn);
+ as_value ret = array->getMember(st.find("0"));
+
+ for (size_t i = size + shift - 1; i >= shift ; --i) {
+ const string_table::key nextkey = getKey(fn, i - shift);
+ const string_table::key currentkey = getKey(fn, i);
+ array->delProperty(currentkey);
+ array->set_member(currentkey, array->getMember(nextkey));
+ }
+
+ for (size_t i = shift; i > 0; --i) {
+ const size_t index = i - 1;
+ array->set_member(getKey(fn, index), fn.arg(index));
+ }
+
+ // TODO: this is wrong, but Gnash relies on it.
+ array->set_member(NSV::PROP_LENGTH, size + shift);
+
+ return as_value(size + shift);
}
// Callback to pop a value from the back of an array
static as_value
array_pop(const fn_call& fn)
{
- boost::intrusive_ptr<Array_as> array = ensureType<Array_as>(fn.this_ptr);
-
- // Get our index, log, then return result
- as_value rv = array->pop();
-
- IF_VERBOSE_ACTION (
- log_action(_("calling array pop, result:%s, new array size:%d"),
- rv, array->size());
- );
- return rv;
+
+ as_object* array = ensureType<as_object>(fn.this_ptr);
+
+ as_value length;
+ if (!array->get_member(NSV::PROP_LENGTH, &length)) return as_value();
+
+ const int size = length.to_int();
+ if (size < 1) return as_value();
+
+ const string_table::key ind = getKey(fn, size - 1);
+ as_value ret = array->getMember(ind);
+ array->delProperty(ind);
+
+ // TODO: this is wrong, but Gnash relies on it.
+ array->set_member(NSV::PROP_LENGTH, size - 1);
+
+ return ret;
}
// Callback to pop a value from the front of an array
static as_value
array_shift(const fn_call& fn)
{
- boost::intrusive_ptr<Array_as> array = ensureType<Array_as>(fn.this_ptr);
-
- // Get our index, log, then return result
- as_value rv = array->shift();
-
- IF_VERBOSE_ACTION (
- log_action(_("calling array shift, result:%s, new array size:%d"),
- rv, array->size());
- );
- return rv;
+ as_object* array = ensureType<as_object>(fn.this_ptr);
+
+ as_value length;
+ if (!array->get_member(NSV::PROP_LENGTH, &length)) return as_value();
+
+ const int size = length.to_int();
+
+ // An array with no elements has nothing to return.
+ if (size < 1) return as_value();
+
+ as_value ret = array->getMember(getKey(fn, 0));
+
+ for (size_t i = 0; i < static_cast<size_t>(size - 1); ++i) {
+ const string_table::key nextkey = getKey(fn, i + 1);
+ const string_table::key currentkey = getKey(fn, i);
+ array->delProperty(currentkey);
+ array->set_member(currentkey, array->getMember(nextkey));
+ }
+
+ // TODO: this is wrong, but Gnash relies on it.
+ array->set_member(NSV::PROP_LENGTH, size - 1);
+
+ return ret;
}
// Callback to reverse the position of the elements in an array
@@ -1256,51 +1227,68 @@
return rv;
}
-// Callback to convert array to a string with optional custom separator
(default ',')
-static as_value
+as_value
+join(as_object* array, const std::string& separator)
+{
+ as_value length;
+ if (!array->get_member(NSV::PROP_LENGTH, &length)) return as_value("");
+
+ const double size = length.to_int();
+ if (size < 0) return as_value("");
+
+ std::string s;
+
+ string_table& st = getStringTable(*array);
+ const int version = getSWFVersion(*array);
+
+ for (size_t i = 0; i < size; ++i) {
+ std::ostringstream os;
+ os << i;
+ if (i) s += separator;
+ as_value el;
+ array->get_member(st.find(os.str()), &el);
+ s += el.to_string_versioned(version);
+ }
+ return as_value(s);
+}
+
+as_value
array_join(const fn_call& fn)
{
- boost::intrusive_ptr<Array_as> array = ensureType<Array_as>(fn.this_ptr);
-
- std::string separator = ",";
- int version = getSWFVersion(fn);
-
- if (fn.nargs > 0)
- {
- separator = fn.arg(0).to_string_versioned(version);
- }
-
- std::string ret = array->join(separator);
-
- return as_value(ret);
+ as_object* array = ensureType<as_object>(fn.this_ptr);
+
+ const int version = getSWFVersion(fn);
+ const std::string separator =
+ fn.nargs ? fn.arg(0).to_string_versioned(version) : ",";
+
+ return join(array, separator);
}
// Callback to convert array to a string
-// TODO CHECKME: rely on Object.toString ? (
-static as_value
-array_to_string(const fn_call& fn)
+as_value
+array_toString(const fn_call& fn)
{
- boost::intrusive_ptr<Array_as> array = ensureType<Array_as>(fn.this_ptr);
-
- std::string ret = array->toString();
-
- IF_VERBOSE_ACTION
- (
- log_action(_("array_to_string called, nargs = %d, "
- "this_ptr = %p"),
- fn.nargs, (void*)fn.this_ptr);
- log_action(_("to_string result is: %s"), ret);
- );
-
- return as_value(ret);
+ as_object* array = ensureType<as_object>(fn.this_ptr);
+ return join(array, ",");
}
+class PushToArray
+{
+public:
+ PushToArray(as_object& obj) : _obj(obj) {}
+ void operator()(const as_value& val) {
+ _obj.callMethod(NSV::PROP_PUSH, val);
+ }
+private:
+ as_object& _obj;
+};
+
/// concatenates the elements specified in the parameters with
/// the elements in my_array, and creates a new array. If the
/// value parameters specify an array, the elements of that
/// array are concatenated, rather than the array itself. The
/// array my_array is left unchanged.
-static as_value
+as_value
array_concat(const fn_call& fn)
{
boost::intrusive_ptr<Array_as> array = ensureType<Array_as>(fn.this_ptr);
@@ -1308,23 +1296,29 @@
// use copy ctor
Array_as* newarray = new Array_as();
- for (size_t i=0, e=array->size(); i<e; i++)
- newarray->push(array->at(i));
-
- for (unsigned int i=0; i<fn.nargs; i++)
- {
+ PushToArray push(*newarray);
+ if (!foreachArray(*array, push)) return as_value();
+
+ for (size_t i = 0; i < fn.nargs; ++i) {
+
// Array args get concatenated by elements
- boost::intrusive_ptr<Array_as> other =
- boost::dynamic_pointer_cast<Array_as>(
- fn.arg(i).to_object(*getGlobal(fn)));
- if ( other )
- {
- newarray->concat(*other);
- }
- else
- {
- newarray->push(fn.arg(i));
- }
+ // The type is checked using instanceOf.
+ const as_value& arg = fn.arg(i);
+
+ Global_as* gl = getGlobal(fn);
+ as_object* other = arg.to_object(*gl);
+
+ if (other) {
+
+ // If it's not an array, we want to carry on and add it as an
+ // object.
+ if (other->instanceOf(getClassConstructor(fn, "Array"))) {
+ // Do we care if it has no length property?
+ foreachArray(*other, push);
+ continue;
+ }
+ }
+ newarray->callMethod(NSV::PROP_PUSH, fn.arg(i));
}
return as_value(newarray);
@@ -1444,7 +1438,7 @@
as_value index_number;
for (unsigned int i = 0; i < fn.nargs; i++)
{
- ao->push(fn.arg(i));
+ ao->callMethod(NSV::PROP_PUSH, fn.arg(i));
}
}
@@ -1478,54 +1472,18 @@
{
VM& vm = getVM(proto);
- // Array.push
- vm.registerNative(array_push, 252, 1);
proto.init_member("push", vm.getNative(252, 1));
-
- // Array.pop
- vm.registerNative(array_pop, 252, 2);
proto.init_member("pop", vm.getNative(252, 2));
-
- // Array.concat
- vm.registerNative(array_concat, 252, 3);
proto.init_member("concat", vm.getNative(252, 3));
-
- // Array.shift
- vm.registerNative(array_shift, 252, 4);
proto.init_member("shift", vm.getNative(252, 4));
-
- // Array.unshift
- vm.registerNative(array_unshift, 252, 5);
proto.init_member("unshift", vm.getNative(252, 5));
-
- // Array.slice
- vm.registerNative(array_slice, 252, 6);
proto.init_member("slice", vm.getNative(252, 6));
-
- // Array.join
- vm.registerNative(array_join, 252, 7);
proto.init_member("join", vm.getNative(252, 7));
-
- // Array.splice
- vm.registerNative(array_splice, 252, 8);
proto.init_member("splice", vm.getNative(252, 8));
-
- // Array.toString
- vm.registerNative(array_to_string, 252, 9);
proto.init_member("toString", vm.getNative(252, 9));
-
- // Array.sort
- vm.registerNative(array_sort, 252, 10);
proto.init_member("sort", vm.getNative(252, 10));
-
- // Array.reverse
- vm.registerNative(array_reverse, 252, 11);
proto.init_member("reverse", vm.getNative(252, 11));
-
- // Array.sortOn
- vm.registerNative(array_sortOn, 252, 12);
proto.init_member("sortOn", vm.getNative(252, 12));
-
}
static as_object*
@@ -1547,6 +1505,18 @@
{
VM& vm = getVM(global);
vm.registerNative(array_new, 252, 0);
+ vm.registerNative(array_push, 252, 1);
+ vm.registerNative(array_pop, 252, 2);
+ vm.registerNative(array_concat, 252, 3);
+ vm.registerNative(array_shift, 252, 4);
+ vm.registerNative(array_unshift, 252, 5);
+ vm.registerNative(array_slice, 252, 6);
+ vm.registerNative(array_join, 252, 7);
+ vm.registerNative(array_splice, 252, 8);
+ vm.registerNative(array_toString, 252, 9);
+ vm.registerNative(array_sort, 252, 10);
+ vm.registerNative(array_reverse, 252, 11);
+ vm.registerNative(array_sortOn, 252, 12);
}
// this registers the "Array" member on a "Global"
@@ -1589,44 +1559,6 @@
}
void
-Array_as::shiftElementsLeft(unsigned int count)
-{
- ArrayContainer& v = elements;
-
- if ( count >= v.size() )
- {
- // NOTE: v.clear() would NOT set size to 0 !!
- v.resize(0);
- return;
- }
-
- for (unsigned int i=0; i<count; ++i) v.erase_element(i);
-
- for (iterator i=v.begin(), e=v.end(); i!=e; ++i)
- {
- int currentIndex = i.index();
- int newIndex = currentIndex-count;
- v[newIndex] = *i;
- }
- v.resize(v.size()-count);
-}
-
-void
-Array_as::shiftElementsRight(unsigned int count)
-{
- ArrayContainer& v = elements;
-
- v.resize(v.size()+count);
- for (ArrayContainer::reverse_iterator i=v.rbegin(), e=v.rend(); i!=e;
++i)
- {
- int currentIndex = i.index();
- int newIndex = currentIndex+count;
- v[newIndex] = *i;
- }
- while (count--) v.erase_element(count);
-}
-
-void
Array_as::splice(unsigned int start, unsigned int count, const
std::vector<as_value>* replace, Array_as* receive)
{
size_t sz = elements.size();
@@ -1661,7 +1593,7 @@
if ( receive )
{
for (size_t i=start; i<start+count; ++i )
- receive->push(elements[i]);
+ receive->callMethod(NSV::PROP_PUSH, elements[i]);
}
elements = newelements;
=== modified file 'libcore/asobj/Array_as.h'
--- a/libcore/asobj/Array_as.h 2009-08-19 08:48:14 +0000
+++ b/libcore/asobj/Array_as.h 2009-10-14 16:12:54 +0000
@@ -20,6 +20,7 @@
#include "as_object.h" // for inheritance
#include "smart_ptr.h" // GNASH_USE_GC
+#include "namedStrings.h"
#include <deque>
#include <vector>
@@ -54,8 +55,6 @@
void visit(as_value& v) { cont.push_back(v); }
};
-struct blank {};
-
/// The Array ActionScript object
class Array_as : public as_object
{
@@ -137,40 +136,20 @@
Array_as::const_iterator end();
- /// Push an element to the end of the array
- //
- /// @param val
- /// The element to add
- ///
- void push(const as_value& val);
-
- void unshift(const as_value& val);
-
- as_value shift();
-
- as_value pop();
-
as_value at(unsigned int index) const;
Array_as* get_indices(std::deque<indexed_as_value> origElems);
void reverse();
- void set_indexed(unsigned int index, const as_value &v);
-
/// @param separator
/// String to use as separator between elements
std::string join(const std::string& separator) const;
- /// Convert array to string.
- std::string toString() const;
-
unsigned int size() const;
void resize(unsigned int);
- void concat(const Array_as& other);
-
/// \brief
/// Return a newly created array containing elements
/// from 'start' up to but not including 'end'.
@@ -193,21 +172,6 @@
boost::intrusive_ptr<Array_as> slice(
unsigned int start, unsigned int one_past_end);
- /// Remove first element matching the given value
- //
- /// Return true if any element was removed, false otherwise
- ///
- /// NOTE: if an element is removed, holes in the array will be
- /// filled.
- ///
- /// @param v
- /// The value to compare elements against
- ///
- /// @param env
- /// The environment to use when comparing (needed by
as_value::equals)
- ///
- bool removeFirst(const as_value& v);
-
/// \brief
/// Replace count elements from start with given values, optionally
/// returning the erased ones.
@@ -404,21 +368,26 @@
// if the string does not refer to an index, or an appropriate int if
the string does refer to an index
int index_requested(string_table::key name);
- /// Shift all elements to the left by count positions
- //
- /// Pre-condition: size of the array must be >= count
- /// Post-condition: size of the array will reduce by 'count'
- ///
- void shiftElementsLeft(unsigned int count);
-
- /// Shift all elements to the right by count positions
- //
- /// Pre-condition: none
- /// Post-condition: size of the array will incremented by 'count'
- ///
- void shiftElementsRight(unsigned int count);
};
+string_table::key arrayKey(string_table& st, size_t i);
+
+template<typename T>
+bool foreachArray(as_object& array, T& pred)
+{
+ as_value length;
+ if (!array.get_member(NSV::PROP_LENGTH, &length)) return false;
+
+ const int size = length.to_int();
+ if (size < 0) return false;
+
+ string_table& st = getStringTable(array);
+
+ for (size_t i = 0; i < static_cast<size_t>(size); ++i) {
+ pred(array.getMember(arrayKey(st, i)));
+ }
+ return true;
+}
/// Initialize the global.Array object
// needed by SWFHandlers::ActionInitArray
@@ -426,10 +395,6 @@
void registerArrayNative(as_object& global);
-/// Constructor for ActionScript class Array.
-// needed by SWFHandlers::ActionInitArray
-as_value array_new(const fn_call& fn);
-
}
#endif
=== modified file 'libcore/asobj/AsBroadcaster.cpp'
--- a/libcore/asobj/AsBroadcaster.cpp 2009-08-20 09:36:50 +0000
+++ b/libcore/asobj/AsBroadcaster.cpp 2009-10-14 14:31:24 +0000
@@ -120,7 +120,7 @@
// Find _global.AsBroadcaster.
as_object* asb =
- gl->getMember(NSV::CLASS_AS_BROADCASTER).to_object(*gl).get();
+ gl->getMember(NSV::CLASS_AS_BROADCASTER).to_object(*gl);
// If it's not an object, these are left undefined, but they are
// always attached to the initialized object.
@@ -139,7 +139,7 @@
const as_value& asn = gl->callMethod(NSV::PROP_AS_NATIVE, 101, 12);
o.set_member(NSV::PROP_BROADCAST_MESSAGE, asn);
- o.set_member(NSV::PROP_uLISTENERS, new Array_as());
+ o.set_member(NSV::PROP_uLISTENERS, gl->createArray());
}
@@ -256,30 +256,16 @@
"an object: %s"), (void*)fn.this_ptr, fn.dump_args(),
listenersValue);
);
- return as_value(false); // TODO: check this
- }
-
- boost::intrusive_ptr<as_object> listenersObj =
- listenersValue.to_object(*getGlobal(fn));
- assert(listenersObj);
-
- boost::intrusive_ptr<Array_as> listeners =
boost::dynamic_pointer_cast<Array_as>(listenersObj);
- if ( ! listeners )
- {
- IF_VERBOSE_ASCODING_ERRORS(
- log_aserror(_("%p.addListener(%s): this object's _listener isn't "
- "an array: %s -- will call 'push' on it anyway"),
- (void*)fn.this_ptr,
- fn.dump_args(), listenersValue);
- );
-
- listenersObj->callMethod(NSV::PROP_PUSH, newListener);
-
- }
- else
- {
- listeners->push(newListener);
- }
+ // TODO: check this
+ return as_value(false);
+ }
+
+ as_object* listeners = listenersValue.to_object(*getGlobal(fn));
+
+ // We checked is_object() above.
+ assert(listeners);
+
+ listeners->callMethod(NSV::PROP_PUSH, newListener);
return as_value(true);
@@ -359,10 +345,24 @@
// Remove the first listener matching the new value
// See http://www.senocular.com/flash/tutorials/
// listenersasbroadcaster/?page=2
- // TODO: make this call as a normal (don't want to
- // rely on _listeners type at all)
- bool removed = listeners->removeFirst(listenerToRemove);
- return as_value(removed);
+
+ // This is an ActionScript-like implementation, which is why it looks
+ // like poor C++.
+ int length = listenersObj->getMember(NSV::PROP_LENGTH).to_int();
+ int i = 0;
+ string_table& st = getStringTable(fn);
+ while (i < length) {
+ std::ostringstream s;
+ s << i;
+ as_value el =
+ listenersObj->getMember(st.find(s.str()));
+ if (el.equals(listenerToRemove)) {
+ listeners->callMethod(NSV::PROP_SPLICE, s.str(), 1);
+ return as_value(true);
+ }
+ ++i;
+ }
+ return as_value(false);
}
}
@@ -401,8 +401,7 @@
}
boost::intrusive_ptr<Array_as> listeners =
- boost::dynamic_pointer_cast<Array_as>(
- listenersValue.to_object(*getGlobal(fn)));
+ dynamic_cast<Array_as*>(listenersValue.to_object(*getGlobal(fn)));
if ( ! listeners )
{
=== modified file 'libcore/asobj/Color_as.cpp'
--- a/libcore/asobj/Color_as.cpp 2009-08-27 06:40:41 +0000
+++ b/libcore/asobj/Color_as.cpp 2009-10-14 08:47:08 +0000
@@ -72,7 +72,7 @@
attachColorInterface, 0, uri);
as_object* proto =
- cl->getMember(NSV::PROP_PROTOTYPE).to_object(*getGlobal(where)).get();
+ cl->getMember(NSV::PROP_PROTOTYPE).to_object(*getGlobal(where));
if (!proto) return;
=== modified file 'libcore/asobj/Global_as.h'
--- a/libcore/asobj/Global_as.h 2009-09-29 09:56:55 +0000
+++ b/libcore/asobj/Global_as.h 2009-10-14 14:20:47 +0000
@@ -83,6 +83,13 @@
/// expected behaviour.
virtual as_object* createBoolean(bool b) = 0;
+ /// Create an Array object
+ //
+ /// This calls the Array constructor. If that has been changed, this
+ /// function may not produce an Array object. This is generally
+ /// expected behaviour.
+ virtual as_object* createArray() = 0;
+
/// Create an Object
//
/// This function returns an Object with Object.prototype as its
=== modified file 'libcore/asobj/Globals.cpp'
--- a/libcore/asobj/Globals.cpp 2009-10-12 11:37:04 +0000
+++ b/libcore/asobj/Globals.cpp 2009-10-14 14:20:47 +0000
@@ -240,6 +240,16 @@
}
+/// This serves the purpose of hiding the Array_as type from the
+/// implementation, which at least enforces good behaviour from users.
+//
+/// TODO: it could well already call the Array constructor.
+as_object*
+AVM1Global::createArray()
+{
+ return new Array_as();
+}
+
as_object*
AVM1Global::createBoolean(bool b)
{
@@ -292,6 +302,14 @@
return constructObject(*this, b, NSV::CLASS_BOOLEAN);
}
+/// This serves the purpose of hiding the Array_as type from the
+/// implementation, which at least enforces good behaviour from users.
+as_object*
+AVM2Global::createArray()
+{
+ return new Array_as();
+}
+
void
AVM1Global::markReachableResources() const
{
@@ -1025,7 +1043,7 @@
Global_as* gl = getGlobal(fn);
- as_object* targetObject = fn.arg(0).to_object(*gl).get();
+ as_object* targetObject = fn.arg(0).to_object(*gl);
if (!targetObject) {
return as_value();
}
@@ -1096,7 +1114,7 @@
Global_as* gl = getGlobal(fn);
- as_object* targetObject = fn.arg(0).to_object(*gl).get();
+ as_object* targetObject = fn.arg(0).to_object(*gl);
if (!targetObject) {
return as_value();
}
@@ -1171,7 +1189,7 @@
as_value
local_errorConstructor(const fn_call& fn)
{
- as_object* obj = ensureType<as_object>(fn.this_ptr).get();
+ as_object* obj = ensureType<as_object>(fn.this_ptr);
const as_value& arg = fn.nargs ? fn.arg(0) : as_value();
string_table& st = getStringTable(fn);
obj->set_member(st.find("message"), arg);
=== modified file 'libcore/asobj/Globals.h'
--- a/libcore/asobj/Globals.h 2009-09-07 17:34:36 +0000
+++ b/libcore/asobj/Globals.h 2009-10-14 14:20:47 +0000
@@ -74,6 +74,8 @@
virtual as_object* createObject();
+ virtual as_object* createArray();
+
virtual const ClassHierarchy& classHierarchy() const {
return _classes;
}
@@ -140,6 +142,8 @@
virtual as_object* createObject();
+ virtual as_object* createArray();
+
virtual const ClassHierarchy& classHierarchy() const {
return _classes;
}
=== modified file 'libcore/asobj/LoadableObject.cpp'
--- a/libcore/asobj/LoadableObject.cpp 2009-10-12 12:52:36 +0000
+++ b/libcore/asobj/LoadableObject.cpp 2009-10-14 16:10:50 +0000
@@ -46,6 +46,71 @@
as_value loadableobject_sendAndLoad(const fn_call& fn);
}
+/// Functors for use with foreachArray
+namespace {
+
+class WriteHeaders
+{
+public:
+
+ WriteHeaders(NetworkAdapter::RequestHeaders& headers)
+ :
+ _headers(headers),
+ _i(0)
+ {}
+
+ void operator()(const as_value& val)
+ {
+ // Store even elements and continue
+ if (!(_i++ % 2)) {
+ _key = val;
+ return;
+ }
+
+ // Both elements apparently must be strings, or we move onto the
+ // next pair.
+ if (!val.is_string() || !_key.is_string()) return;
+ _headers[_key.to_string()] = val.to_string();
+ }
+
+private:
+ as_value _key;
+ NetworkAdapter::RequestHeaders _headers;
+ size_t _i;
+};
+
+class GetHeaders
+{
+public:
+
+ GetHeaders(as_object& target)
+ :
+ _target(target),
+ _i(0)
+ {}
+
+ void operator()(const as_value& val)
+ {
+ // Store even elements and continue
+ if (!(_i++ % 2)) {
+ _key = val;
+ return;
+ }
+
+ // Both elements apparently must be strings, or we move onto the
+ // next pair.
+ if (!val.is_string() || !_key.is_string()) return;
+ _target.callMethod(NSV::PROP_PUSH, _key, val);
+ }
+
+private:
+ as_value _key;
+ as_object& _target;
+ size_t _i;
+};
+
+}
+
LoadableObject::LoadableObject(as_object* owner)
:
ActiveRelay(owner),
@@ -95,8 +160,7 @@
URL url(urlstr, ri.baseURL());
std::auto_ptr<IOChannel> str;
- if (post)
- {
+ if (post) {
as_value customHeaders;
NetworkAdapter::RequestHeaders headers;
@@ -106,33 +170,10 @@
/// Read in our custom headers if they exist and are an
/// array.
- Array_as* array = dynamic_cast<Array_as*>(
- customHeaders.to_object(*getGlobal(target)).get());
-
- if (array)
- {
- Array_as::const_iterator e = array->end();
- --e;
-
- for (Array_as::const_iterator i = array->begin(); i != e; ++i)
- {
- // Only even indices can be a header.
- if (i.index() % 2) continue;
- if (! (*i).is_string()) continue;
-
- // Only the immediately following odd number can be
- // a value.
- if (array->at(i.index() + 1).is_string())
- {
- const std::string& name = (*i).to_string();
- const std::string& val =
- array->at(i.index() + 1).to_string();
-
- // Values should overwrite existing ones.
- headers[name] = val;
- }
-
- }
+ as_object* array = customHeaders.to_object(*getGlobal(target));
+ if (array) {
+ WriteHeaders wh(headers);
+ foreachArray(*array, wh);
}
}
@@ -331,6 +372,7 @@
return bytesTotal;
}
+
/// Can take either a two strings as arguments or an array of strings,
/// alternately header and value.
as_value
@@ -340,9 +382,11 @@
as_value customHeaders;
as_object* array;
+ Global_as* gl = getGlobal(fn);
+
if (fn.this_ptr->get_member(NSV::PROP_uCUSTOM_HEADERS, &customHeaders))
{
- array = customHeaders.to_object(*getGlobal(fn)).get();
+ array = customHeaders.to_object(*gl);
if (!array)
{
IF_VERBOSE_ASCODING_ERRORS(
@@ -352,15 +396,11 @@
return as_value();
}
}
- else
- {
- array = new Array_as;
+ else {
+ array = gl->createArray();
// This property is always initialized on the first call to
- // addRequestHeaders.
- const int flags = PropFlags::dontEnum |
- PropFlags::dontDelete;
-
- fn.this_ptr->init_member(NSV::PROP_uCUSTOM_HEADERS, array, flags);
+ // addRequestHeaders. It has default properties.
+ fn.this_ptr->init_member(NSV::PROP_uCUSTOM_HEADERS, array);
}
if (fn.nargs == 0)
@@ -375,14 +415,11 @@
if (fn.nargs == 1)
{
- // This must be an array. Keys / values are pushed in valid
- // pairs to the _customHeaders array.
- boost::intrusive_ptr<as_object> obj =
- fn.arg(0).to_object(*getGlobal(fn));
- Array_as* headerArray = dynamic_cast<Array_as*>(obj.get());
+ // This must be an array (or something like it). Keys / values are
+ // pushed in valid pairs to the _customHeaders array.
+ boost::intrusive_ptr<as_object> headerArray = fn.arg(0).to_object(*gl);
- if (!headerArray)
- {
+ if (!headerArray) {
IF_VERBOSE_ASCODING_ERRORS(
log_aserror(_("XML.addRequestHeader: single argument "
"is not an array"));
@@ -390,23 +427,8 @@
return as_value();
}
- Array_as::const_iterator e = headerArray->end();
- --e;
-
- for (Array_as::const_iterator i = headerArray->begin(); i != e; ++i)
- {
- // Only even indices can be a key, and they must be a string.
- if (i.index() % 2) continue;
- if (!(*i).is_string()) continue;
-
- // Only the immediately following odd number can be
- // a value, and it must also be a string.
- const as_value& val = headerArray->at(i.index() + 1);
- if (val.is_string())
- {
- array->callMethod(NSV::PROP_PUSH, *i, val);
- }
- }
+ GetHeaders gh(*array);
+ foreachArray(*headerArray, gh);
return as_value();
}
=== modified file 'libcore/asobj/MovieClipLoader.cpp'
--- a/libcore/asobj/MovieClipLoader.cpp 2009-08-18 10:32:14 +0000
+++ b/libcore/asobj/MovieClipLoader.cpp 2009-10-14 14:41:39 +0000
@@ -144,8 +144,8 @@
as_object(getMovieClipLoaderInterface())
{
- Array_as* ar = new Array_as();
- ar->push(this);
+ as_object* ar = getGlobal(*this)->createArray();
+ ar->callMethod(NSV::PROP_PUSH, this);
set_member(NSV::PROP_uLISTENERS, ar);
}
=== modified file 'libcore/asobj/Object.cpp'
--- a/libcore/asobj/Object.cpp 2009-08-27 06:41:27 +0000
+++ b/libcore/asobj/Object.cpp 2009-10-14 08:47:08 +0000
@@ -169,7 +169,7 @@
Global_as* gl = getGlobal(fn);
if (fn.nargs == 1) {
- as_object* obj = fn.arg(0).to_object(*gl).get();
+ as_object* obj = fn.arg(0).to_object(*gl);
if (obj) return as_value(obj);
}
=== modified file 'libcore/asobj/QName_as.cpp'
--- a/libcore/asobj/QName_as.cpp 2009-10-07 06:18:09 +0000
+++ b/libcore/asobj/QName_as.cpp 2009-10-14 08:47:08 +0000
@@ -98,7 +98,7 @@
as_value
qname_ctor(const fn_call& fn)
{
- as_object* obj = ensureType<as_object>(fn.this_ptr).get();
+ as_object* obj = ensureType<as_object>(fn.this_ptr);
attachQNameInterface(*obj);
return as_value();
}
=== modified file 'libcore/asobj/Selection_as.cpp'
--- a/libcore/asobj/Selection_as.cpp 2009-08-20 10:16:35 +0000
+++ b/libcore/asobj/Selection_as.cpp 2009-10-14 08:47:08 +0000
@@ -221,7 +221,7 @@
else {
/// Try converting directly to DisplayObject.
ch = dynamic_cast<DisplayObject*>(
- focus.to_object(*getGlobal(fn)).get());
+ focus.to_object(*getGlobal(fn)));
}
// If the argument does not resolve to a DisplayObject, do nothing.
=== modified file 'libcore/asobj/String_as.cpp'
--- a/libcore/asobj/String_as.cpp 2009-10-02 08:18:58 +0000
+++ b/libcore/asobj/String_as.cpp 2009-10-14 14:31:24 +0000
@@ -28,7 +28,6 @@
#include "builtin_function.h" // need builtin_function
#include "NativeFunction.h"
#include "log.h"
-#include "Array_as.h"
#include "as_value.h"
#include "GnashException.h"
#include "movie_definition.h"
@@ -240,13 +239,14 @@
std::wstring wstr = utf8::decodeCanonicalString(str, version);
- boost::intrusive_ptr<Array_as> array(new Array_as());
+ Global_as* gl = getGlobal(fn);
+ as_object* array = gl->createArray();
if (fn.nargs == 0)
{
// Condition 1:
- array->push(str);
- return as_value(array.get());
+ array->callMethod(NSV::PROP_PUSH, str);
+ return as_value(array);
}
const std::wstring& delim = utf8::decodeCanonicalString(
@@ -257,8 +257,8 @@
(version >= 6 && fn.arg(0).is_undefined()))
{
// Condition 2:
- array->push(str);
- return as_value(array.get());
+ array->callMethod(NSV::PROP_PUSH, str);
+ return as_value(array);
}
size_t max = wstr.size() + 1;
@@ -272,7 +272,7 @@
if (limit < 1)
{
// Return empty array.
- return as_value(array.get());
+ return as_value(array);
}
max = clamp<size_t>(limit, 0, max);
}
@@ -281,8 +281,8 @@
{
// Condition 3 (plus a shortcut if the string itself
// is empty).
- array->push(str);
- return as_value(array.get());
+ array->callMethod(NSV::PROP_PUSH, str);
+ return as_value(array);
}
}
else
@@ -293,8 +293,8 @@
// If the string itself is empty, SWF6 returns a 0-sized
// array only if the delimiter is also empty. Otherwise
// it returns an array with 1 empty element.
- if (delimiterSize) array->push(str);
- return as_value(array.get());
+ if (delimiterSize) array->callMethod(NSV::PROP_PUSH, str);
+ return as_value(array);
}
// If we reach this point, the string is not empty and
@@ -304,7 +304,7 @@
int limit = fn.arg(1).to_int();
if (limit < 1) {
// Return empty array if
- return as_value(array.get());
+ return as_value(array);
}
max = clamp<size_t>(limit, 0, max);
}
@@ -314,9 +314,10 @@
if (delim.empty()) {
for (size_t i = 0, e = std::min<size_t>(wstr.size(), max);
i < e; ++i) {
- array->push(utf8::encodeCanonicalString(wstr.substr(i, 1),
version));
+ array->callMethod(NSV::PROP_PUSH,
+ utf8::encodeCanonicalString(wstr.substr(i, 1),
version));
}
- return as_value(array.get());
+ return as_value(array);
}
}
@@ -327,16 +328,16 @@
while (num < max) {
pos = wstr.find(delim, pos);
- array->push(utf8::encodeCanonicalString(
- wstr.substr(prevpos, pos - prevpos),
- version));
+ array->callMethod(NSV::PROP_PUSH, utf8::encodeCanonicalString(
+ wstr.substr(prevpos, pos - prevpos), version));
+
if (pos == std::wstring::npos) break;
num++;
prevpos = pos + delimiterSize;
pos++;
}
- return as_value(array.get());
+ return as_value(array);
}
/// String.lastIndexOf[string[, pos]]
=== modified file 'libcore/asobj/TextFormat_as.cpp'
--- a/libcore/asobj/TextFormat_as.cpp 2009-08-27 10:18:44 +0000
+++ b/libcore/asobj/TextFormat_as.cpp 2009-10-14 08:47:08 +0000
@@ -176,7 +176,7 @@
textformat_new(const fn_call& fn)
{
- as_object* obj = ensureType<as_object>(fn.this_ptr).get();
+ as_object* obj = ensureType<as_object>(fn.this_ptr);
std::auto_ptr<TextFormat_as> tf(new TextFormat_as);
@@ -223,7 +223,7 @@
}
obj->setRelay(tf.release());
- as_object* proto = obj->get_prototype().get();
+ as_object* proto = obj->get_prototype();
if (proto) attachTextFormatInterface(*proto);
const int flags = 0;
@@ -293,7 +293,7 @@
return ret;
}
- as_object* arg = fn.arg(0).to_object(*getGlobal(fn)).get();
+ as_object* arg = fn.arg(0).to_object(*getGlobal(fn));
Array_as* tStops = dynamic_cast<Array_as*>(arg);
if (!tStops) return as_value();
=== modified file 'libcore/asobj/flash/display/BitmapData_as.cpp'
--- a/libcore/asobj/flash/display/BitmapData_as.cpp 2009-09-29 11:09:52
+0000
+++ b/libcore/asobj/flash/display/BitmapData_as.cpp 2009-10-14 08:47:08
+0000
@@ -356,7 +356,7 @@
}
// This can be any object with the right properties.
- as_object* obj = arg.to_object(*getGlobal(fn)).get();
+ as_object* obj = arg.to_object(*getGlobal(fn));
assert(obj);
as_value x, y, w, h;
@@ -653,7 +653,7 @@
as_value
bitmapdata_ctor(const fn_call& fn)
{
- as_object* ptr = ensureType<as_object>(fn.this_ptr).get();
+ as_object* ptr = ensureType<as_object>(fn.this_ptr);
if (fn.nargs < 2) {
IF_VERBOSE_ASCODING_ERRORS(
log_aserror("BitmapData constructor requires at least two "
=== modified file 'libcore/asobj/flash/display/DisplayObjectContainer_as.cpp'
--- a/libcore/asobj/flash/display/DisplayObjectContainer_as.cpp 2009-07-29
05:59:24 +0000
+++ b/libcore/asobj/flash/display/DisplayObjectContainer_as.cpp 2009-10-14
08:47:08 +0000
@@ -145,7 +145,7 @@
);
}
- as_object* objArg = fn.arg(0).to_object(*getGlobal(fn)).get();
+ as_object* objArg = fn.arg(0).to_object(*getGlobal(fn));
if (!objArg) {
IF_VERBOSE_ASCODING_ERRORS(
std::stringstream ss; fn.dump_args(ss);
@@ -191,7 +191,7 @@
);
}
- as_object* objArg = fn.arg(0).to_object(*getGlobal(fn)).get();
+ as_object* objArg = fn.arg(0).to_object(*getGlobal(fn));
if (!objArg) {
IF_VERBOSE_ASCODING_ERRORS(
std::stringstream ss; fn.dump_args(ss);
=== modified file 'libcore/asobj/flash/display/MovieClip_as.cpp'
--- a/libcore/asobj/flash/display/MovieClip_as.cpp 2009-10-13 09:07:45
+0000
+++ b/libcore/asobj/flash/display/MovieClip_as.cpp 2009-10-14 08:47:08
+0000
@@ -60,7 +60,6 @@
as_value movieclip_beginBitmapFill(const fn_call& fn);
as_value movieclip_createEmptyMovieClip(const fn_call& fn);
as_value movieclip_removeMovieClip(const fn_call& fn);
- as_value movieclip_createTextField(const fn_call& fn);
as_value movieclip_curveTo(const fn_call& fn);
as_value movieclip_beginFill(const fn_call& fn);
as_value movieclip_prevFrame(const fn_call& fn);
@@ -221,8 +220,6 @@
vm.registerNative(movieclip_beginBitmapFill, 901, 11);
vm.registerNative(movieclip_scale9Grid, 901, 12);
- vm.registerNative(movieclip_createTextField, 104, 200);
-
}
/// Properties (and/or methods) attached to every *instance* of a MovieClip
@@ -352,6 +349,44 @@
}
+//createEmptyMovieClip(name:String, depth:Number) : MovieClip
+as_value
+movieclip_createEmptyMovieClip(const fn_call& fn)
+{
+ boost::intrusive_ptr<MovieClip> ptr = ensureType<MovieClip>(fn.this_ptr);
+
+ if (fn.nargs != 2) {
+ if (fn.nargs < 2) {
+ IF_VERBOSE_ASCODING_ERRORS(
+ log_aserror(_("createEmptyMovieClip needs "
+ "2 args, but %d given,"
+ " returning undefined"),
+ fn.nargs);
+ );
+ return as_value();
+ }
+ IF_VERBOSE_ASCODING_ERRORS(
+ log_aserror(_("createEmptyMovieClip takes "
+ "2 args, but %d given, discarding"
+ " the excess"),
+ fn.nargs);
+ )
+ }
+
+ // TODO: improve MovieClip ctor (and don't use it here anyway).
+ Movie* m = getRoot(fn).topLevelMovie();
+ MovieClip* mc = new MovieClip(0, m, ptr.get());
+
+ mc->set_name(fn.arg(0).to_string());
+ mc->setDynamic();
+
+ // 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.
+ DisplayObject* ch = ptr->addDisplayListObject(mc, fn.arg(1).to_int());
+ return as_value(ch);
+}
+
as_value
movieclip_play(const fn_call& fn)
@@ -585,7 +620,7 @@
}
NetStream_as* ns;
- if (!isNativeType(fn.arg(0).to_object(*getGlobal(fn)).get(), ns))
+ if (!isNativeType(fn.arg(0).to_object(*getGlobal(fn)), ns))
{
std::stringstream ss; fn.dump_args(ss);
// TODO: find out what to do here
@@ -614,39 +649,6 @@
}
-//createEmptyMovieClip(name:String, depth:Number) : MovieClip
-as_value
-movieclip_createEmptyMovieClip(const fn_call& fn)
-{
- boost::intrusive_ptr<MovieClip> movieclip =
- ensureType<MovieClip>(fn.this_ptr);
-
- if (fn.nargs != 2) {
- if (fn.nargs < 2) {
- IF_VERBOSE_ASCODING_ERRORS(
- log_aserror(_("createEmptyMovieClip needs "
- "2 args, but %d given,"
- " returning undefined"),
- fn.nargs);
- );
- return as_value();
- }
- IF_VERBOSE_ASCODING_ERRORS(
- log_aserror(_("createEmptyMovieClip takes "
- "2 args, but %d given, discarding"
- " the excess"),
- fn.nargs);
- )
- }
-
- // 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.
- DisplayObject* ch = movieclip->add_empty_movieclip(fn.arg(0).to_string(),
- fn.arg(1).to_int());
- return as_value(ch);
-}
-
as_value
movieclip_getDepth(const fn_call& fn)
{
@@ -1146,57 +1148,6 @@
}
-as_value
-movieclip_createTextField(const fn_call& fn)
-{
- boost::intrusive_ptr<MovieClip> movieclip =
- ensureType<MovieClip>(fn.this_ptr);
-
- if (fn.nargs < 6) // name, depth, x, y, width, height
- {
- IF_VERBOSE_ASCODING_ERRORS(
- log_aserror(_("createTextField called with %d args, "
- "expected 6 - returning undefined"), fn.nargs);
- );
- return as_value();
- }
-
- std::string txt_name = fn.arg(0).to_string();
-
- int txt_depth = fn.arg(1).to_int();
-
- int txt_x = fn.arg(2).to_int();
-
- int txt_y = fn.arg(3).to_int();
-
- int txt_width = fn.arg(4).to_int();
- if ( txt_width < 0 )
- {
- IF_VERBOSE_ASCODING_ERRORS(
- log_aserror(_("createTextField: negative width (%d)"
- " - reverting sign"), txt_width);
- );
- txt_width = -txt_width;
- }
-
- int txt_height = fn.arg(5).to_int();
- if ( txt_height < 0 )
- {
- IF_VERBOSE_ASCODING_ERRORS(
- log_aserror(_("createTextField: negative height (%d)"
- " - reverting sign"), txt_height);
- );
- txt_height = -txt_height;
- }
-
- boost::intrusive_ptr<DisplayObject> txt =
movieclip->add_textfield(txt_name,
- txt_depth, txt_x, txt_y, txt_width, txt_height);
-
- // createTextField returns void, it seems
- if (getSWFVersion(fn) > 7) return as_value(txt.get());
- else return as_value();
-}
-
//getNextHighestDepth() : Number
as_value
movieclip_getNextHighestDepth(const fn_call& fn)
@@ -2421,7 +2372,7 @@
return as_value();
}
- as_object* obj = fn.arg(0).to_object(*getGlobal(fn)).get();
+ as_object* obj = fn.arg(0).to_object(*getGlobal(fn));
BitmapData_as* bd;
if (!isNativeType(obj, bd)) {
@@ -2443,13 +2394,8 @@
as_value
movieclip_as2_ctor(const fn_call& fn)
{
-
assert(!isAS3(fn));
-
- boost::intrusive_ptr<as_object> clip =
- new as_object(getMovieClipAS2Interface());
-
- return as_value(clip.get());
+ return as_value();
}
=== modified file 'libcore/asobj/flash/geom/ColorTransform_as.cpp'
--- a/libcore/asobj/flash/geom/ColorTransform_as.cpp 2009-10-07 05:52:30
+0000
+++ b/libcore/asobj/flash/geom/ColorTransform_as.cpp 2009-10-14 08:47:08
+0000
@@ -255,7 +255,7 @@
colortransform_toString(const fn_call& fn)
{
- as_object* ptr = ensureType<as_object>(fn.this_ptr).get();
+ as_object* ptr = ensureType<as_object>(fn.this_ptr);
string_table& st = getStringTable(fn);
@@ -330,7 +330,7 @@
colortransform_ctor(const fn_call& fn)
{
- as_object* obj = ensureType<as_object>(fn.this_ptr).get();
+ as_object* obj = ensureType<as_object>(fn.this_ptr);
// Default arguments.
if (fn.nargs < 8)
=== modified file 'libcore/asobj/flash/geom/Matrix_as.cpp'
--- a/libcore/asobj/flash/geom/Matrix_as.cpp 2009-10-07 05:52:30 +0000
+++ b/libcore/asobj/flash/geom/Matrix_as.cpp 2009-10-14 08:47:08 +0000
@@ -201,7 +201,7 @@
}
// The object to concatenate doesn't have to be a matrix.
- as_object* obj = arg.to_object(*getGlobal(fn)).get();
+ as_object* obj = arg.to_object(*getGlobal(fn));
assert(obj);
MatrixType concatMatrix;
@@ -404,7 +404,7 @@
// It doesn't have to be a point. If it has x and y
// properties, they will be used.
- as_object* obj = arg.to_object(*getGlobal(fn)).get();
+ as_object* obj = arg.to_object(*getGlobal(fn));
assert(obj);
const PointType& point = transformPoint(obj, ptr.get());
@@ -706,7 +706,7 @@
return as_value();
}
- as_object* obj = arg.to_object(*getGlobal(fn)).get();
+ as_object* obj = arg.to_object(*getGlobal(fn));
assert(obj);
if (!obj->instanceOf(getClassConstructor(fn, "flash.geom.Point"))) {
/// Isn't a point.
=== modified file 'libcore/asobj/flash/geom/Point_as.cpp'
--- a/libcore/asobj/flash/geom/Point_as.cpp 2009-10-07 08:06:57 +0000
+++ b/libcore/asobj/flash/geom/Point_as.cpp 2009-10-14 08:47:08 +0000
@@ -128,7 +128,7 @@
}
);
const as_value& arg1 = fn.arg(0);
- as_object* o = arg1.to_object(*getGlobal(fn)).get();
+ as_object* o = arg1.to_object(*getGlobal(fn));
if ( ! o )
{
IF_VERBOSE_ASCODING_ERRORS(
@@ -199,7 +199,7 @@
);
return as_value(false);
}
- as_object* o = arg1.to_object(*getGlobal(fn)).get();
+ as_object* o = arg1.to_object(*getGlobal(fn));
assert(o);
if (!o->instanceOf(getClassConstructor(fn, "flash.geom.Point")))
{
@@ -305,7 +305,7 @@
as_value
point_subtract(const fn_call& fn)
{
- as_object* ptr = ensureType<as_object>(fn.this_ptr).get();
+ as_object* ptr = ensureType<as_object>(fn.this_ptr);
as_value x, y;
ptr->get_member(NSV::PROP_X, &x);
@@ -329,7 +329,7 @@
}
);
const as_value& arg1 = fn.arg(0);
- as_object* o = arg1.to_object(*getGlobal(fn)).get();
+ as_object* o = arg1.to_object(*getGlobal(fn));
if ( ! o )
{
IF_VERBOSE_ASCODING_ERRORS(
@@ -367,7 +367,7 @@
as_value
point_toString(const fn_call& fn)
{
- as_object* ptr = ensureType<as_object>(fn.this_ptr).get();
+ as_object* ptr = ensureType<as_object>(fn.this_ptr);
as_value x, y;
ptr->get_member(NSV::PROP_X, &x);
@@ -386,7 +386,7 @@
as_value
point_length(const fn_call& fn)
{
- as_object* ptr = ensureType<as_object>(fn.this_ptr).get();
+ as_object* ptr = ensureType<as_object>(fn.this_ptr);
if ( ! fn.nargs ) // getter
{
@@ -438,7 +438,7 @@
);
return as_value();
}
- as_object* o1 = arg1.to_object(*getGlobal(fn)).get();
+ as_object* o1 = arg1.to_object(*getGlobal(fn));
assert(o1);
if (!o1->instanceOf(getClassConstructor(fn, "flash.geom.Point")))
{
@@ -450,7 +450,7 @@
}
const as_value& arg2 = fn.arg(1);
- as_object* o2 = arg2.to_object(*getGlobal(fn)).get();
+ as_object* o2 = arg2.to_object(*getGlobal(fn));
assert(o2);
// it seems there's no need to check arg2 (see actionscript.all/Point.as)
@@ -510,7 +510,7 @@
);
const as_value& p0val = fn.arg(0);
- as_object* p0 = p0val.to_object(*getGlobal(fn)).get();
+ as_object* p0 = p0val.to_object(*getGlobal(fn));
if ( ! p0 )
{
IF_VERBOSE_ASCODING_ERRORS(
@@ -525,7 +525,7 @@
}
const as_value& p1val = fn.arg(1);
- as_object* p1 = p1val.to_object(*getGlobal(fn)).get();
+ as_object* p1 = p1val.to_object(*getGlobal(fn));
if ( ! p1 )
{
IF_VERBOSE_ASCODING_ERRORS(
@@ -605,7 +605,7 @@
point_ctor(const fn_call& fn)
{
- as_object* obj = ensureType<as_object>(fn.this_ptr).get();
+ as_object* obj = ensureType<as_object>(fn.this_ptr);
as_value x;
as_value y;
=== modified file 'libcore/asobj/flash/geom/Rectangle_as.cpp'
--- a/libcore/asobj/flash/geom/Rectangle_as.cpp 2009-10-07 07:46:44 +0000
+++ b/libcore/asobj/flash/geom/Rectangle_as.cpp 2009-10-14 08:47:08 +0000
@@ -609,7 +609,7 @@
Rectangle_ctor(const fn_call& fn)
{
- as_object* obj = ensureType<as_object>(fn.this_ptr).get();
+ as_object* obj = ensureType<as_object>(fn.this_ptr);
as_value x;
as_value y;
=== modified file 'libcore/asobj/flash/geom/Transform_as.cpp'
--- a/libcore/asobj/flash/geom/Transform_as.cpp 2009-10-07 05:52:30 +0000
+++ b/libcore/asobj/flash/geom/Transform_as.cpp 2009-10-14 08:47:08 +0000
@@ -345,7 +345,7 @@
boost::intrusive_ptr<MovieClip> mc =
ensureType<MovieClip>(fn.arg(0).to_object(*getGlobal(fn)));
- as_object* obj = ensureType<as_object>(fn.this_ptr).get();
+ as_object* obj = ensureType<as_object>(fn.this_ptr);
obj->setRelay(new Transform_as(*mc));
return as_value();
=== modified file 'libcore/asobj/flash/media/Camera_as.cpp'
--- a/libcore/asobj/flash/media/Camera_as.cpp 2009-08-28 11:03:35 +0000
+++ b/libcore/asobj/flash/media/Camera_as.cpp 2009-10-14 14:50:52 +0000
@@ -30,7 +30,6 @@
#include "builtin_function.h"
#include "NativeFunction.h"
#include "Object.h"
-#include "Array_as.h"
#include "MediaHandler.h"
#include "VideoInput.h"
@@ -534,13 +533,14 @@
const size_t size = names.size();
- boost::intrusive_ptr<Array_as> data = new Array_as;
+ Global_as* gl = getGlobal(fn);
+ as_object* data = gl->createArray();
for (size_t i = 0; i < size; ++i) {
- data->push(names[i]);
+ data->callMethod(NSV::PROP_PUSH, names[i]);
}
- return as_value(data.get());
+ return as_value(data);
}
=== modified file 'libcore/asobj/flash/media/Microphone_as.cpp'
--- a/libcore/asobj/flash/media/Microphone_as.cpp 2009-09-13 22:29:48
+0000
+++ b/libcore/asobj/flash/media/Microphone_as.cpp 2009-10-14 14:50:52
+0000
@@ -30,7 +30,6 @@
#include "builtin_function.h"
#include "NativeFunction.h"
#include "Object.h" // for getObjectInterface
-#include "Array_as.h"
#include <cmath>
#ifdef USE_GST
@@ -426,15 +425,16 @@
size_t size = vect.size();
- boost::intrusive_ptr<Array_as> data = new Array_as;
+ Global_as* gl = getGlobal(fn);
+ as_object* data = gl->createArray();
for (size_t i=0; i < size; ++i) {
- data->push(vect[i]);
+ data->callMethod(NSV::PROP_PUSH, vect[i]);
}
if ( fn.nargs == 0 ) // getter
{
- return as_value(data.get());
+ return as_value(data);
}
else // setter
{
=== modified file 'libcore/asobj/flash/media/Sound_as.cpp'
--- a/libcore/asobj/flash/media/Sound_as.cpp 2009-08-26 14:29:24 +0000
+++ b/libcore/asobj/flash/media/Sound_as.cpp 2009-10-14 08:47:08 +0000
@@ -810,7 +810,7 @@
const as_value& arg0 = fn.arg(0);
if ( ! arg0.is_null() && ! arg0.is_undefined() )
{
- as_object* obj = arg0.to_object(*getGlobal(fn)).get();
+ as_object* obj = arg0.to_object(*getGlobal(fn));
DisplayObject* ch = obj ? obj->toDisplayObject() : 0;
IF_VERBOSE_ASCODING_ERRORS(
if (!ch) {
=== modified file 'libcore/asobj/flash/net/LocalConnection_as.cpp'
--- a/libcore/asobj/flash/net/LocalConnection_as.cpp 2009-08-26 14:29:24
+0000
+++ b/libcore/asobj/flash/net/LocalConnection_as.cpp 2009-10-14 08:47:08
+0000
@@ -265,7 +265,7 @@
localconnection_new(const fn_call& fn)
{
// TODO: this doesn't happen on construction.
- as_object* obj = ensureType<as_object>(fn.this_ptr).get();
+ as_object* obj = ensureType<as_object>(fn.this_ptr);
obj->setRelay(new LocalConnection_as(obj));
return as_value();
}
=== modified file 'libcore/asobj/flash/net/NetStream_as.cpp'
--- a/libcore/asobj/flash/net/NetStream_as.cpp 2009-08-27 10:35:23 +0000
+++ b/libcore/asobj/flash/net/NetStream_as.cpp 2009-10-14 08:47:08 +0000
@@ -1580,7 +1580,7 @@
if (fn.nargs) {
NetConnection_as* nc;
- if (isNativeType(fn.arg(0).to_object(*getGlobal(fn)).get(), nc)) {
+ if (isNativeType(fn.arg(0).to_object(*getGlobal(fn)), nc)) {
ns->setNetCon(nc);
}
else {
=== modified file 'libcore/asobj/flash/net/SharedObject_as.cpp'
--- a/libcore/asobj/flash/net/SharedObject_as.cpp 2009-09-07 17:34:36
+0000
+++ b/libcore/asobj/flash/net/SharedObject_as.cpp 2009-10-14 08:47:08
+0000
@@ -880,7 +880,7 @@
}
NetConnection_as* nc;
- if (!isNativeType(fn.arg(0).to_object(*getGlobal(fn)).get(), nc)) {
+ if (!isNativeType(fn.arg(0).to_object(*getGlobal(fn)), nc)) {
return as_value();
}
=== modified file 'libcore/asobj/flash/text/TextSnapshot_as.cpp'
--- a/libcore/asobj/flash/text/TextSnapshot_as.cpp 2009-08-26 14:29:24
+0000
+++ b/libcore/asobj/flash/text/TextSnapshot_as.cpp 2009-10-14 14:50:52
+0000
@@ -37,7 +37,6 @@
#include "MovieClip.h"
#include "Font.h"
#include "swf/TextRecord.h"
-#include "Array_as.h"
#include "RGBA.h"
#include "GnashNumeric.h"
@@ -171,7 +170,7 @@
}
void
-TextSnapshot_as::getTextRunInfo(size_t start, size_t end, Array_as& ri) const
+TextSnapshot_as::getTextRunInfo(size_t start, size_t end, as_object& ri) const
{
std::string::size_type pos = 0;
@@ -233,7 +232,7 @@
el->init_member("matrix_tx", xpos);
el->init_member("matrix_ty", ypos);
- ri.push(el);
+ ri.callMethod(NSV::PROP_PUSH, el);
++pos;
x += k->advance;
@@ -455,7 +454,8 @@
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());
- Array_as* ri = new Array_as;
+ Global_as* gl = getGlobal(fn);
+ as_object* ri = gl->createArray();;
ts->getTextRunInfo(start, end, *ri);
=== modified file 'libcore/asobj/flash/text/TextSnapshot_as.h'
--- a/libcore/asobj/flash/text/TextSnapshot_as.h 2009-08-26 14:29:24
+0000
+++ b/libcore/asobj/flash/text/TextSnapshot_as.h 2009-10-14 14:50:52
+0000
@@ -30,7 +30,6 @@
namespace gnash {
class StaticText;
- class Array_as;
namespace SWF {
class TextRecord;
}
@@ -73,7 +72,7 @@
std::string getSelectedText(bool newlines) const;
- void getTextRunInfo(size_t start, size_t end, Array_as& ri) const;
+ void getTextRunInfo(size_t start, size_t end, as_object& ri) const;
protected:
=== modified file 'libcore/asobj/flash/ui/ContextMenu_as.cpp'
--- a/libcore/asobj/flash/ui/ContextMenu_as.cpp 2009-08-27 11:29:16 +0000
+++ b/libcore/asobj/flash/ui/ContextMenu_as.cpp 2009-10-14 14:50:52 +0000
@@ -31,7 +31,6 @@
#include "GnashException.h" // for ActionException
#include "Object.h" // for getObjectInterface
#include "namedStrings.h"
-#include "Array_as.h"
namespace gnash {
@@ -118,7 +117,7 @@
string_table& st = getStringTable(fn);
as_value onSelect, builtInItems;
- as_value customItems = new Array_as;;
+ as_value customItems = gl->createArray();
ptr->get_member(NSV::PROP_ON_SELECT, &onSelect);
ptr->get_member(st.find("builtInItems"), &builtInItems);
@@ -131,11 +130,11 @@
// The customItems object is a deep copy, but only of elements that are
// instances of ContextMenuItem (have its prototype as a __proto__ member).
- as_object* nc = new Array_as;
+ as_object* nc = gl->createArray();
as_object* customs;
if (customItems.is_object() &&
- (customs = customItems.to_object(*getGlobal(fn)).get())) {
+ (customs = customItems.to_object(*getGlobal(fn)))) {
// TODO: only copy properties that are ContextMenuItems.
nc->copyProperties(*customs);
customItems = nc;
@@ -163,7 +162,7 @@
obj->set_member(st.find("builtInItems"), builtInItems);
// There is an empty customItems array.
- Array_as* customItems = new Array_as();
+ as_object* customItems = gl->createArray();
obj->set_member(st.find("customItems"), customItems);
return as_value();
=== modified file 'libcore/asobj/flash/xml/XMLDocument_as.cpp'
--- a/libcore/asobj/flash/xml/XMLDocument_as.cpp 2009-09-07 17:34:36
+0000
+++ b/libcore/asobj/flash/xml/XMLDocument_as.cpp 2009-10-14 08:47:08
+0000
@@ -585,7 +585,7 @@
o.init_property("xmlDecl", &xml_xmlDecl, &xml_xmlDecl, flags);
o.init_property("docTypeDecl", &xml_docTypeDecl, &xml_docTypeDecl, flags);
- as_object* proto = o.get_prototype().get();
+ as_object* proto = o.get_prototype();
if (!proto) return;
proto->init_property("loaded", xml_loaded, xml_loaded);
proto->init_property("status", xml_status, xml_status);
@@ -651,7 +651,7 @@
// Copy constructor clones nodes.
if (fn.arg(0).is_object()) {
- as_object* obj = fn.arg(0).to_object(*getGlobal(fn)).get();
+ as_object* obj = fn.arg(0).to_object(*getGlobal(fn));
xml_obj = dynamic_cast<XMLDocument_as*>(obj);
if (xml_obj) {
=== modified file 'libcore/asobj/flash/xml/XMLNode_as.cpp'
--- a/libcore/asobj/flash/xml/XMLNode_as.cpp 2009-08-27 06:01:23 +0000
+++ b/libcore/asobj/flash/xml/XMLNode_as.cpp 2009-10-14 14:50:52 +0000
@@ -23,7 +23,6 @@
#include "xml/XMLNode_as.h"
#include "xml/XMLDocument_as.h"
-#include "Array_as.h"
#include "Object.h"
#include "VM.h"
#include "log.h"
@@ -538,7 +537,8 @@
}
boost::intrusive_ptr<XMLNode_as> xml_obj =
-
boost::dynamic_pointer_cast<XMLNode_as>(fn.arg(0).to_object(*getGlobal(fn)));
+ dynamic_cast<XMLNode_as*>(fn.arg(0).to_object(*getGlobal(fn)));
+
if ( ! xml_obj )
{
IF_VERBOSE_ASCODING_ERRORS(
@@ -582,7 +582,7 @@
}
boost::intrusive_ptr<XMLNode_as> newnode =
-
boost::dynamic_pointer_cast<XMLNode_as>(fn.arg(0).to_object(*getGlobal(fn)));
+ dynamic_cast<XMLNode_as*>(fn.arg(0).to_object(*getGlobal(fn)));
if (!newnode) {
IF_VERBOSE_ASCODING_ERRORS(
@@ -594,7 +594,7 @@
}
boost::intrusive_ptr<XMLNode_as> pos =
-
boost::dynamic_pointer_cast<XMLNode_as>(fn.arg(1).to_object(*getGlobal(fn)));
+ dynamic_cast<XMLNode_as*>(fn.arg(1).to_object(*getGlobal(fn)));
if (!pos) {
IF_VERBOSE_ASCODING_ERRORS(
@@ -921,7 +921,9 @@
xmlnode_childNodes(const fn_call& fn)
{
boost::intrusive_ptr<XMLNode_as> ptr = ensureType<XMLNode_as>(fn.this_ptr);
- boost::intrusive_ptr<Array_as> ary = new Array_as();
+
+ Global_as* gl = getGlobal(fn);
+ as_object* ary = gl->createArray();
typedef XMLNode_as::Children Children;
@@ -930,10 +932,10 @@
it != itEnd; ++it )
{
boost::intrusive_ptr<XMLNode_as> node = *it;
- ary->push(as_value(node.get()));
+ ary->callMethod(NSV::PROP_PUSH, node.get());
}
- return as_value(ary.get());
+ return as_value(ary);
}
=== modified file 'libcore/movie_root.cpp'
--- a/libcore/movie_root.cpp 2009-10-07 11:54:54 +0000
+++ b/libcore/movie_root.cpp 2009-10-14 08:47:08 +0000
@@ -525,7 +525,7 @@
as_value s;
if (!global->get_member(NSV::CLASS_SELECTION, &s)) return 0;
- as_object* sel = s.to_object(*global).get();
+ as_object* sel = s.to_object(*global);
return sel;
}
@@ -538,7 +538,7 @@
Global_as* global = _vm.getGlobal();
if (!global) return 0;
if (!global->get_member(NSV::PROP_iSTAGE, &v) ) return 0;
- return v.to_object(*global).get();
+ return v.to_object(*global);
}
void
=== modified file 'libcore/swf_function.cpp'
--- a/libcore/swf_function.cpp 2009-10-13 10:32:52 +0000
+++ b/libcore/swf_function.cpp 2009-10-14 14:41:58 +0000
@@ -34,6 +34,22 @@
namespace gnash {
+namespace {
+
+ /// Return an 'arguments' object.
+ //
+ /// The 'arguments' variable is an array with an additional
+ /// 'callee' member, set to the function being called.
+ ///
+ /// NOTE: the callee as_object will be stored in an as_value, thus
+ /// getting wrapped into an intrusive_ptr. Make sure you have
+ /// a reference on it!
+ ///
+ ///
+ as_object* getArguments(swf_function& callee, const fn_call& fn,
+ as_object* caller);
+}
+
swf_function::~swf_function()
{
#ifndef GNASH_USE_GC
@@ -59,31 +75,6 @@
init_member(NSV::PROP_CONSTRUCTOR,
as_function::getFunctionConstructor());
}
-/*private static*/
-Array_as*
-swf_function::getArguments(swf_function& callee, const fn_call& fn,
- as_object* caller)
-{
-#ifndef GNASH_USE_GC
- // We'll be storing the callee as_object into an as_value
- // so you must make sure you have a reference on it before
- // callign this function.
- assert(callee.get_ref_count() > 0);
-#endif // ndef GNASH_USE_GC
-
- // Super class prototype is : obj.__proto__.constructor.prototype
- Array_as* arguments = new Array_as();
- for (unsigned int i=0; i<fn.nargs; ++i)
- {
- arguments->push(fn.arg(i));
- }
- arguments->init_member(NSV::PROP_CALLEE, &callee);
-
- arguments->init_member(NSV::PROP_CALLER, as_value(caller));
-
- return arguments;
-
-}
/// Exception safe (scoped) as_environment's target changer
//
@@ -219,7 +210,8 @@
}
// Init arguments array, if it's going to be needed.
- boost::intrusive_ptr<Array_as> arg_array;
+ as_object* arg_array = 0;
+
if ((m_function2_flags & PRELOAD_ARGUMENTS) ||
!(m_function2_flags & SUPPRESS_ARGUMENTS)) {
arg_array = getArguments(*this, fn, caller);
@@ -227,13 +219,13 @@
if (m_function2_flags & PRELOAD_ARGUMENTS) {
// preload 'arguments' into a register.
- m_env.setRegister(current_reg,
as_value(arg_array.get()));
+ m_env.setRegister(current_reg, as_value(arg_array));
current_reg++;
}
if (!(m_function2_flags & SUPPRESS_ARGUMENTS)) {
// Put 'arguments' in a local var.
- m_env.add_local("arguments", as_value(arg_array.get()));
+ m_env.add_local("arguments", as_value(arg_array));
}
if ((m_function2_flags & PRELOAD_SUPER) && swfversion > 5) {
@@ -366,5 +358,33 @@
}
#endif // GNASH_USE_GC
+namespace {
+
+as_object*
+getArguments(swf_function& callee, const fn_call& fn,
+ as_object* caller)
+{
+#ifndef GNASH_USE_GC
+ // We'll be storing the callee as_object into an as_value
+ // so you must make sure you have a reference on it before
+ // callign this function.
+ assert(callee.get_ref_count() > 0);
+#endif // ndef GNASH_USE_GC
+
+ // Super class prototype is : obj.__proto__.constructor.prototype
+ as_object* arguments = getGlobal(fn)->createArray();
+ for (unsigned int i=0; i<fn.nargs; ++i) {
+ arguments->callMethod(NSV::PROP_PUSH, fn.arg(i));
+ }
+
+ arguments->init_member(NSV::PROP_CALLEE, &callee);
+
+ arguments->init_member(NSV::PROP_CALLER, as_value(caller));
+
+ return arguments;
+
+}
+
+}
} // end of gnash namespace
=== modified file 'libcore/swf_function.h'
--- a/libcore/swf_function.h 2009-07-15 07:37:56 +0000
+++ b/libcore/swf_function.h 2009-10-14 14:41:58 +0000
@@ -82,19 +82,6 @@
/// See
http://sswf.sourceforge.net/SWFalexref.html#action_declare_function2
boost::uint16_t m_function2_flags;
- /// Return an 'arguments' object.
- //
- /// The 'arguments' variable is an array with an additional
- /// 'callee' member, set to the function being called.
- ///
- /// NOTE: the callee as_object will be stored in an as_value, thus
- /// getting wrapped into an intrusive_ptr. Make sure you have
- /// a reference on it!
- ///
- ///
- static Array_as* getArguments(swf_function& callee, const fn_call& fn,
- as_object* caller);
-
public:
enum SWFDefineFunction2Flags
=== modified file 'libcore/vm/ASHandlers.cpp'
--- a/libcore/vm/ASHandlers.cpp 2009-10-13 07:32:05 +0000
+++ b/libcore/vm/ASHandlers.cpp 2009-10-14 15:44:50 +0000
@@ -28,7 +28,6 @@
#include "rc.h"
#include "ASHandlers.h"
#include "movie_definition.h"
-#include "Array_as.h"
#include "swf_function.h"
#include "as_function.h"
#include "fn_call.h"
@@ -2810,7 +2809,7 @@
assert(array_size >= 0); // TODO: trigger this !!
// Call the array constructor, to create an empty array.
- as_value result = array_new(fn_call(NULL, env));
+ as_value result = getGlobal(env)->createArray();
boost::intrusive_ptr<as_object> ao =
convertToObject(*getGlobal(thread.env), result);
assert(ao);
@@ -3961,7 +3960,7 @@
{
try {
- return val.to_object(gl).get();
+ return val.to_object(gl);
}
catch (const GnashException& gl) {
return 0;
=== modified file 'libcore/vm/Machine.cpp'
--- a/libcore/vm/Machine.cpp 2009-10-07 07:46:44 +0000
+++ b/libcore/vm/Machine.cpp 2009-10-14 14:41:51 +0000
@@ -21,7 +21,6 @@
#include "as_object.h"
#include "ClassHierarchy.h"
#include "namedStrings.h"
-#include "Array_as.h"
#include "AbcBlock.h"
#include "fn_call.h"
#include "abc_function.h"
@@ -177,7 +176,7 @@
if (b)
\
{
\
mStream->seekTo(opStart);
\
- pushGet(e->to_object(*_global).get(), *e, b);
\
+ pushGet(e->to_object(*_global), *e, b);
\
break;
\
}
\
}
\
@@ -208,7 +207,7 @@
if (d)
\
{
\
mStream->seekTo(opStart);
\
- pushGet(c->to_object(*_global).get(), *c, d);
\
+ pushGet(c->to_object(*_global), *c, d);
\
break;
\
}
\
}
\
@@ -255,22 +254,24 @@
else return a.equals(b);
}
+/// NB: the stubbed but unimplemented as_value::conforms_to no longer exists,
+/// but the code is left here for later reference.
#define ABSTRACT_TYPELATE(st, checkval, matchval)
\
{
\
bool *store = &st;
\
- as_value &a = checkval; /* Don't call checkval multiple times */
\
+ /*as_value &a = checkval; Don't call checkval multiple times */
\
as_value &b = matchval; /* Don't call matchval multiple times */
\
*store = true;
\
if (b.is_object())
\
{
\
as_value v;
\
b.to_object(*_global)->get_member(NSV::INTERNAL_TYPE, &v);
\
- if (!a.conforms_to(mST.find(v.to_string())))
\
+ if (true) /*(!a.conforms_to(mST.find(v.to_string()))) */
\
*store = false;
\
}
\
else if (b.is_string())
\
{
\
- if (!a.conforms_to(mST.find(b.to_string())))
\
+ if (true) /*(!a.conforms_to(mST.find(b.to_string()))) */
\
*store = false;
\
}
\
else
\
@@ -438,7 +439,7 @@
// Use get_super?
as_object *super = _stack.top(0).to_object(*_global)->
- get_prototype().get();
+ get_prototype();
// If we don't have a super, throw.
if (!super) throw ASReferenceError();
@@ -470,7 +471,7 @@
// Use get_super?
as_object* super = _stack.pop().to_object(*_global)->
- get_prototype().get();
+ get_prototype();
if (!super) throw ASReferenceError();
Property* b = super->findProperty(a.getABCName(),
a.getNamespace()->getURI());
@@ -869,7 +870,7 @@
case SWF::ABC_ACTION_PUSHSCOPE:
{
as_value scope_value = pop_stack();
- if (!scope_value.to_object(*_global).get()) {
+ if (!scope_value.to_object(*_global)) {
// Should throw an exception.
IF_VERBOSE_ASCODING_ERRORS(
log_aserror(_("Can't push a null value onto the "
@@ -893,7 +894,7 @@
log_unimpl("ABC_ACTION_PUSHWITH");
// A scope object is just a regular object.
// ENSURE_OBJECT(_stack.top(0));
- // as_object *a =
_stack.top(0).to_object(*_global).get();
+ // as_object *a =
_stack.top(0).to_object(*_global);
//
// if (!_scopeStack.empty())
//
a->set_prototype(_scopeStack.top(0).mScope);
@@ -933,7 +934,7 @@
{
ENSURE_NUMBER(_stack.top(0));
ENSURE_OBJECT(_stack.top(1));
- as_object *obj = _stack.top(1).to_object(*_global).get();
+ as_object *obj = _stack.top(1).to_object(*_global);
const boost::uint32_t index =
_stack.top(0).to_number<boost::uint32_t>();
@@ -965,7 +966,7 @@
{
ENSURE_NUMBER(_stack.top(0));
ENSURE_OBJECT(_stack.top(1));
- as_object *obj = _stack.top(1).to_object(*_global).get();
+ as_object *obj = _stack.top(1).to_object(*_global);
boost::uint32_t index =
_stack.top(0).to_number<boost::uint32_t>();
_stack.drop(1);
@@ -1005,7 +1006,7 @@
{
ENSURE_NUMBER(_stack.top(0));
ENSURE_OBJECT(_stack.top(1));
- as_object *obj = _stack.top(1).to_object(*_global).get();
+ as_object *obj = _stack.top(1).to_object(*_global);
const boost::uint32_t index =
_stack.top(0).to_number<boost::uint32_t>();
const Property *b = obj->getByIndex(index);
@@ -1172,7 +1173,7 @@
log_abc("HASNEXT2: Object is %s, index is %d",
objv, indexv);
- as_object *obj = objv.to_object(*_global).get();
+ as_object *obj = objv.to_object(*_global);
if (!obj) {
// TODO: Check what to do here.
log_error("ABC_ACTION_HASNEXT2: expecting object in "
@@ -1239,7 +1240,7 @@
ENSURE_OBJECT(_stack.top(argc + 1)); // The func
ENSURE_OBJECT(_stack.top(argc)); // The 'this'
as_function *f = _stack.top(argc + 1).to_as_function();
- as_object *obj =
_stack.top(argc).to_object(*_global).get();
+ as_object *obj = _stack.top(argc).to_object(*_global);
// We start with argc + 2 values related to this call
// on the stack. We want to end with 1 value. We pass
// argc values (the parameters), so we need to drop
@@ -1286,7 +1287,7 @@
boost::uint32_t dispatch_id = mStream->read_V32() - 1;
boost::uint32_t argc = mStream->read_V32();
ENSURE_OBJECT(_stack.top(argc));
- as_object *obj =
_stack.top(argc).to_object(*_global).get();
+ as_object *obj = _stack.top(argc).to_object(*_global);
const Property *f = obj->getByIndex(dispatch_id);
as_function* func;
#if 0
@@ -1322,7 +1323,7 @@
boost::uint32_t argc = mStream->read_V32();
as_function *func = m->getPrototype();
ENSURE_OBJECT(_stack.top(argc));
- as_object *obj =
_stack.top(argc).to_object(*_global).get();
+ as_object *obj = _stack.top(argc).to_object(*_global);
pushCall(func, obj, _stack.top(argc), argc, 0);
break;
}
@@ -1405,7 +1406,7 @@
as_value object_val = pop_stack();
- as_object *object = object_val.to_object(*_global).get();
+ as_object *object = object_val.to_object(*_global);
if (!object) {
log_abc(_("CALLPROP: Can't call a method of a value "
"that doesn't cast to an object (%s)."),
@@ -1438,7 +1439,7 @@
/* int shift = completeName(a, argc);
ENSURE_OBJECT(_stack.top(shift + argc));
- as_object *obj = _stack.top(argc +
shift).to_object(*_global).get();
+ as_object *obj = _stack.top(argc +
shift).to_object(*_global);
Property *b = obj->findProperty(a.getABCName(),
a.getNamespace()->getURI());
if (!b)
@@ -1513,11 +1514,11 @@
fn_call::Args args;
get_args(argc, args);
- as_object* obj =
_stack.top(argc).to_object(*_global).get();
+ as_object* obj = _stack.top(argc).to_object(*_global);
// Using get_super() here fails; is it broken, or is
// prototype what we want?
- as_object* super = obj ? obj->get_prototype().get() : 0;
+ as_object* super = obj ? obj->get_prototype() : 0;
log_abc("CONSTRUCTSUPER: object %s, super %s, args %s",
_stack.top(argc), super, argc);
@@ -1556,7 +1557,7 @@
"%s on object %s", mST.value(a.getGlobalName()),
_stack.top(0));
- as_object* object = pop_stack().to_object(*_global).get();
+ as_object* object = pop_stack().to_object(*_global);
if (!object) {
//TODO: Should this result in an exeception or an
@@ -1598,7 +1599,7 @@
as_value val = c.to_object(*_global)->getMember(
NSV::PROP_CONSTRUCTOR, 0);
- call_method(val, env, c.to_object(*_global).get(),
args);
+ call_method(val, env, c.to_object(*_global), args);
// Push the constructed property
push_stack(c);
@@ -1647,12 +1648,11 @@
case SWF::ABC_ACTION_NEWARRAY:
{
boost::uint32_t asize = mStream->read_V32();
- log_abc("Creating array of size %u",asize);
- Array_as *arr = new Array_as;
- arr->resize(asize);
boost::uint32_t i = asize;
+
+ as_object* arr = _global->createArray();
while (i--) {
- arr->set_indexed(i, pop_stack());
+ arr->callMethod(NSV::PROP_PUSH, pop_stack());
}
push_stack(as_value(arr));
break;
@@ -1697,7 +1697,7 @@
mST.value(c->getName()));
// This may be 0, and that's fine.
- as_object* base_class =
pop_stack().to_object(*_global).get();
+ as_object* base_class = pop_stack().to_object(*_global);
as_object* new_class = c->getPrototype();
new_class->set_prototype(base_class);
@@ -1868,7 +1868,7 @@
else name = a.getGlobalName();
as_value val = pop_stack();
- as_object *object = val.to_object(*_global).get();
+ as_object *object = val.to_object(*_global);
if (!object) {
log_error("ABC_ACTION_SETPROPERTY: expecting object "
@@ -1956,7 +1956,7 @@
else name = a.getGlobalName();
as_value object_val = pop_stack();
- as_object* object = object_val.to_object(*_global).get();
+ as_object* object = object_val.to_object(*_global);
log_abc(_("GETPROPERTY: Looking for property "
"%s of object %s"), mST.value(name), object_val);
@@ -2004,7 +2004,7 @@
// pop name and namespace values.
as_value object_val = pop_stack();
- as_object* object = object_val.to_object(*_global).get();
+ as_object* object = object_val.to_object(*_global);
if (!object) {
log_abc("INITPROPERTY: expecting object on stack, "
"got %s", object_val);
@@ -2027,7 +2027,7 @@
{
asName a = pool_name(mStream->read_V32(), mPoolObject);
_stack.drop(completeName(a));
- as_object* obj = _stack.top(0).to_object(*_global).get();
+ as_object* obj = _stack.top(0).to_object(*_global);
if (!obj) {
// TODO: what here?
@@ -2056,7 +2056,7 @@
{
as_value val;
boost::uint32_t sindex = mStream->read_V32();
- as_object* object = pop_stack().to_object(*_global).get();
+ as_object* object = pop_stack().to_object(*_global);
if (!object) {
log_abc("GETSLOT: Did not find expected object on "
"stack");
@@ -2088,7 +2088,7 @@
log_abc("SETSLOT object: %s, value: %s, index: %s",
object, value, sindex);
- as_object* obj = object.to_object(*_global).get();
+ as_object* obj = object.to_object(*_global);
if ( ! obj )
{
IF_VERBOSE_ASCODING_ERRORS(
@@ -2234,7 +2234,7 @@
/// Do: If obj is Undefined or Null, throw TypeError
case SWF::ABC_ACTION_CONVERT_O:
{
- _stack.top(0) = _stack.top(0).to_object(*_global).get();
+ _stack.top(0) = _stack.top(0).to_object(*_global);
if (_stack.top(0).is_undefined() ||
_stack.top(0).is_null())
throw ASTypeError();
break;
@@ -2352,7 +2352,7 @@
case SWF::ABC_ACTION_COERCE_O:
{
if (_stack.top(0).is_undefined())
- _stack.top(0) =
_stack.top(0).to_object(*_global).get();
+ _stack.top(0) = _stack.top(0).to_object(*_global);
else
_stack.top(0).set_undefined();
break;
@@ -2687,8 +2687,8 @@
{
asName a = pool_name(mStream->read_V32(), mPoolObject);
_stack.drop(completeName(a));
- // TODO: Namespace stuff?
-
_stack.top(0).set_bool(_stack.top(0).conforms_to(a.getABCName()));
+ // TODO: Implement it.
+
//_stack.top(0).set_bool(_stack.top(0).conforms_to(a.getABCName()));
}
/// 0xB3 ABC_ACTION_ISTYPELATE
@@ -2701,8 +2701,8 @@
{
as_value type = pop_stack();
as_value value = pop_stack();
- as_object* const valueObject =
value.to_object(*_global).get();
- as_object* const typeObject =
type.to_object(*_global).get();
+ as_object* const valueObject = value.to_object(*_global);
+ as_object* const typeObject = type.to_object(*_global);
if (!valueObject || !typeObject) {
// TODO: what here!?
=== modified file 'testsuite/actionscript.all/array.as'
--- a/testsuite/actionscript.all/array.as 2009-02-25 22:33:03 +0000
+++ b/testsuite/actionscript.all/array.as 2009-10-14 11:56:50 +0000
@@ -1459,6 +1459,65 @@
check(!a.hasOwnProperty(2));
#endif
+/// Test array functions on normal objects for a better idea of what goes
+/// on.
+
+fakeArray = function() {
+ o = {};
+ o[1] = "one";
+ o[2] = "two";
+ o[3] = "three";
+ o[4] = "four";
+ o[5] = "five";
+ o[6] = "six";
+ o[7] = "seven";
+
+ // This is deliberately less than the actual length!
+ o.length = 6;
+ return o;
+};
+
+traceProps = function(obj) {
+ s = "";
+ for (i in obj) { s += i + ","; };
+ return s;
+};
+
+o = fakeArray();
+o.shift = Array.prototype.shift;
+
+// Order of property creation.
+check_equals(traceProps(o), "shift,length,7,6,5,4,3,2,1,");
+
+o.shift();
+// Properties are readded from 0 to 5.
+check_equals(traceProps(o), "4,3,2,1,0,shift,length,7,6,5,");
+xcheck_equals(o.length, 6);
+
+o = fakeArray();
+o.unshift = Array.prototype.unshift;
+
+// Order of property creation.
+check_equals(traceProps(o), "unshift,length,7,6,5,4,3,2,1,");
+
+o.unshift("new");
+// Properties are readded in reverse order.
+check_equals(traceProps(o), "0,1,2,3,4,5,6,unshift,length,7,")
+xcheck_equals(o.length, 6);
+
+
+o = fakeArray();
+o.pop = Array.prototype.pop;
+
+// Order of property creation.
+check_equals(traceProps(o), "pop,length,7,6,5,4,3,2,1,");
+
+val = o.pop();
+check_equals(val, "five");
+// Length is not decremented, property 5 is deleted.
+check_equals(traceProps(o), "pop,length,7,6,4,3,2,1,");
+xcheck_equals(o.length, 6);
+
// TODO: test ASnative-returned functions:
//
@@ -1478,11 +1537,11 @@
#if OUTPUT_VERSION < 6
- check_totals(501);
+ check_totals(511);
#else
# if OUTPUT_VERSION < 7
- check_totals(562);
+ check_totals(572);
# else
- check_totals(572);
+ check_totals(582);
# endif
#endif
=== modified file 'testsuite/swfdec/PASSING'
--- a/testsuite/swfdec/PASSING 2009-10-13 10:23:35 +0000
+++ b/testsuite/swfdec/PASSING 2009-10-14 14:52:58 +0000
@@ -232,6 +232,7 @@
constructor-madness-8.swf:5357273baf6b66f6af0223cb1d13b144
constructor-prototype.swf:22505f0f8dd8440972a298110d697e3b
constructor-relay-5.swf:2d1a814c37f55485d66624cb97c58e03
+construct-properties-5.swf:2683d3e400600e0288470ca5b6fbe94c
context-menu-5.swf:867624e2cb2c3d47dc07270d756152db
context-menu-6.swf:9124c06f1cc4725684717eb3641837bd
context-menu-7.swf:fc22bea201998188714399c2de1ac1f5
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] /srv/bzr/gnash/trunk r11561: Widespread but relatively unimportant changes to get rid of annoyances and,
Benjamin Wolsey <=