gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] /srv/bzr/gnash/trunk r11430: Implement difference between


From: Benjamin Wolsey
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r11430: Implement difference between native and built-in functions.
Date: Tue, 18 Aug 2009 13:58:13 +0200
User-agent: Bazaar (1.16.1)

------------------------------------------------------------
revno: 11430 [merge]
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Tue 2009-08-18 13:58:13 +0200
message:
  Implement difference between native and built-in functions.
  
  Drop static data usage for built-in functions (except those that Gnash
  implements more like a native function).
  
  Various cleanups and fixes.
added:
  libcore/NativeFunction.h
modified:
  libcore/Button.cpp
  libcore/Makefile.am
  libcore/Video.cpp
  libcore/as_function.cpp
  libcore/as_function.h
  libcore/as_object.cpp
  libcore/as_object.h
  libcore/asobj/Array_as.cpp
  libcore/asobj/AsBroadcaster.cpp
  libcore/asobj/Color_as.cpp
  libcore/asobj/CustomActions.cpp
  libcore/asobj/Date_as.cpp
  libcore/asobj/Error_as.cpp
  libcore/asobj/Global_as.h
  libcore/asobj/Globals.cpp
  libcore/asobj/LoadVars_as.cpp
  libcore/asobj/LoadableObject.cpp
  libcore/asobj/Math_as.cpp
  libcore/asobj/MovieClipLoader.cpp
  libcore/asobj/NetConnection_as.cpp
  libcore/asobj/Object.cpp
  libcore/asobj/Selection_as.cpp
  libcore/asobj/String_as.cpp
  libcore/asobj/flash/accessibility/AccessibilityProperties_as.cpp
  libcore/asobj/flash/desktop/ClipboardFormats_as.cpp
  libcore/asobj/flash/desktop/ClipboardTransferMode_as.cpp
  libcore/asobj/flash/desktop/Clipboard_as.cpp
  libcore/asobj/flash/display/BitmapDataChannel_as.cpp
  libcore/asobj/flash/display/BitmapData_as.cpp
  libcore/asobj/flash/display/CapsStyle_as.cpp
  libcore/asobj/flash/display/GradientType_as.cpp
  libcore/asobj/flash/display/InterpolationMethod_as.cpp
  libcore/asobj/flash/display/JointStyle_as.cpp
  libcore/asobj/flash/display/MovieClip_as.cpp
  libcore/asobj/flash/display/PixelSnapping_as.cpp
  libcore/asobj/flash/display/SWFVersion_as.cpp
  libcore/asobj/flash/display/SpreadMethod_as.cpp
  libcore/asobj/flash/display/StageAlign_as.cpp
  libcore/asobj/flash/display/StageDisplayState_as.cpp
  libcore/asobj/flash/display/StageQuality_as.cpp
  libcore/asobj/flash/display/StageScaleMode_as.cpp
  libcore/asobj/flash/display/Stage_as.cpp
  libcore/asobj/flash/display/Stage_as.h
  libcore/asobj/flash/external/ExternalInterface_as.cpp
  libcore/asobj/flash/filters/BitmapFilterQuality_as.cpp
  libcore/asobj/flash/filters/DisplacementMapFilterMode_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/SharedObject_as.cpp
  libcore/asobj/flash/printing/PrintJobOrientation_as.cpp
  libcore/asobj/flash/system/System_as.cpp
  libcore/asobj/flash/ui/ContextMenuItem_as.cpp
  libcore/asobj/flash/ui/ContextMenu_as.cpp
  libcore/asobj/flash/ui/Keyboard_as.cpp
  libcore/asobj/flash/ui/Mouse_as.cpp
  libcore/asobj/flash/xml/XMLDocument_as.cpp
  libcore/asobj/flash/xml/XMLNode_as.cpp
  libcore/builtin_function.h
  libcore/movie_root.cpp
  libcore/movie_root.h
  libcore/swf_function.cpp
  libcore/vm/VM.cpp
  libcore/vm/VM.h
  libcore/vm/fn_call.h
  testsuite/actionscript.all/ASnative.as
  testsuite/actionscript.all/Instance.as
  testsuite/actionscript.all/MovieClip.as
=== modified file 'libcore/Button.cpp'
--- a/libcore/Button.cpp        2009-07-29 05:40:20 +0000
+++ b/libcore/Button.cpp        2009-08-18 10:05:43 +0000
@@ -1114,26 +1114,19 @@
 static as_value
 button_ctor(const fn_call& /* fn */)
 {
-  boost::intrusive_ptr<as_object> clip = new as_object(getButtonInterface());
-  return as_value(clip.get());
+    return as_value();
 }
 
 void
 Button::init(as_object& global, const ObjectURI& uri)
 {
-  // This is going to be the global Button "class"/"function"
-  static boost::intrusive_ptr<as_object> cl=NULL;
-
-  if ( cl == NULL )
-  {
-        Global_as* gl = getGlobal(global);
-        as_object* proto = getButtonInterface();
-        cl = gl->createClass(&button_ctor, proto);
-    VM::get().addStatic(cl.get());
-  }
-
-  // Register _global.MovieClip
-  global.init_member(getName(uri), cl.get(), as_object::DefaultFlags,
+    // This is going to be the global Button "class"/"function"
+    Global_as* gl = getGlobal(global);
+    as_object* proto = getButtonInterface();
+    as_object* cl = gl->createClass(&button_ctor, proto);
+
+    // Register _global.MovieClip
+    global.init_member(getName(uri), cl, as_object::DefaultFlags,
             getNamespace(uri));
 }
 

=== modified file 'libcore/Makefile.am'
--- a/libcore/Makefile.am       2009-07-27 20:35:35 +0000
+++ b/libcore/Makefile.am       2009-08-18 11:58:13 +0000
@@ -223,6 +223,7 @@
        CharacterProxy.h \
        StringPredicates.h \
        builtin_function.h \
+       NativeFunction.h \
        as_function.h \
        namedStrings.h \
        as_environment.h \

=== added file 'libcore/NativeFunction.h'
--- a/libcore/NativeFunction.h  1970-01-01 00:00:00 +0000
+++ b/libcore/NativeFunction.h  2009-08-18 08:00:20 +0000
@@ -0,0 +1,75 @@
+// 
+//   Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+#ifndef GNASH_NATIVE_FUNCTION_H
+#define GNASH_NATIVE_FUNCTION_H
+
+#include "as_function.h" // for inheritance
+#include "fn_call.h" // for call operator
+#include "namedStrings.h"
+
+#include <cassert>
+
+namespace gnash {
+
+/// This class implements functions native to the player.
+//
+/// They are not implemented in ActionScript in the reference player, but
+/// rather have access to internal functions.
+//
+/// Native functions include methods for handling SharedObjects, NetConnections
+/// and MovieClips, but also constructors for types such as String, Number,
+/// Array, Boolean, and MovieClip.
+class NativeFunction : public as_function
+{
+    typedef as_value (*ASFunction)(const fn_call& fn);
+
+public:
+
+       /// Construct a builtin function/class with a default interface
+       //
+       /// The default interface will have a constructor member set as 'this'
+       ///
+       /// @param func
+       ///     The C function to call when this as_function is invoked.
+       ///     For classes, the function pointer is the constructor.
+       ///
+    NativeFunction(Global_as& gl, ASFunction func)
+               :
+               as_function(gl),
+               _func(func)
+       {
+       }
+
+       /// Invoke this function
+       virtual as_value operator()(const fn_call& fn)
+       {
+               assert(_func);
+               return _func(fn);
+       }
+
+       bool isBuiltin()  { return true; }
+
+private:
+
+       ASFunction _func;
+};
+
+} // end of gnash namespace
+
+#endif
+

=== modified file 'libcore/Video.cpp'
--- a/libcore/Video.cpp 2009-07-16 09:02:35 +0000
+++ b/libcore/Video.cpp 2009-08-18 09:24:49 +0000
@@ -300,17 +300,11 @@
 video_class_init(as_object& global, const ObjectURI& uri)
 {
        // This is going to be the global Video "class"/"function"
-       static boost::intrusive_ptr<as_object> cl;
-
-       if ( cl == NULL )
-       {
-        Global_as* gl = getGlobal(global);
-        cl = gl->createClass(&video_ctor, getVideoInterface(global));
-               getVM(global).addStatic(cl.get());
-       }
+    Global_as* gl = getGlobal(global);
+    as_object* cl = gl->createClass(&video_ctor, getVideoInterface(global));
 
        // Register _global.Video
-       global.init_member(getName(uri), cl.get(), as_object::DefaultFlags,
+       global.init_member(getName(uri), cl, as_object::DefaultFlags,
             getNamespace(uri));
 }
 
@@ -347,7 +341,6 @@
                getVM(where).addStatic(proto.get());
 
                attachVideoInterface(*proto);
-               //proto->init_member("constructor", 
gl->createFunction(video_ctor));
        }
        return proto.get();
 }

=== modified file 'libcore/as_function.cpp'
--- a/libcore/as_function.cpp   2009-08-11 09:16:26 +0000
+++ b/libcore/as_function.cpp   2009-08-18 08:36:49 +0000
@@ -29,6 +29,7 @@
 #include "VM.h"
 #include "Object.h" // for getObjectInterface
 #include "namedStrings.h"
+#include "NativeFunction.h"
 
 #include <iostream>
 
@@ -119,16 +120,20 @@
        return proto.to_object(*VM::get().getGlobal());
 }
 
-boost::intrusive_ptr<builtin_function>
+NativeFunction*
 as_function::getFunctionConstructor()
 {
-       static boost::intrusive_ptr<builtin_function> func = NULL;
+       static NativeFunction* func = 0;
        if ( ! func )
        {
         Global_as* gl = VM::get().getGlobal();
-               func = new builtin_function(*gl, function_ctor, 
getFunctionPrototype(),
-                true);
-               VM::get().addStatic(func.get());
+               func = new NativeFunction(*gl, function_ctor);
+        as_object* proto = getFunctionPrototype();
+
+        func->init_member(NSV::PROP_PROTOTYPE, proto);
+        func->init_member(NSV::PROP_CONSTRUCTOR, func);
+               proto->init_member(NSV::PROP_CONSTRUCTOR, func); 
+               VM::get().addStatic(func);
        }
        return func;
 }
@@ -144,128 +149,89 @@
 
        int swfversion = getSWFVersion(env);
 
-       boost::intrusive_ptr<as_object> newobj;
-
-       as_value us;
-       
-    get_member(NSV::PROP_PROTOTYPE, &us);
-       
-    bool has_proto = !us.is_undefined();
-
-    // a built-in class takes care of assigning a prototype
-    // TODO: change this
-    if (isBuiltin()) {
-               IF_VERBOSE_ACTION (
-            log_action(_("it's a built-in class"));
-               )
-
-               fn_call fn(0, env, args);
-               as_value ret;
-
-               try {
-                       ret = call(fn);
-               }
-        catch (GnashException& ex) {
-            // Catching a std::exception here can mask all sorts of bad 
-            // behaviour, as (for instance) a poorly constructed string may
-            // smash the stack, throw an exception, but not abort.
-            // This is very effective at confusing debugging tools.
-            // We only throw GnashExceptions. A std::bad_alloc may also be
-            // reasonable, but anything else shouldn't be caught here.
-                       log_debug("Native function called as constructor threw 
exception: "
-                    "%s", ex.what());
-
-            // If a constructor throws an exception, throw it back to the
-            // caller. This is the only way to signal that a constructor
-            // did not return anything.
-            throw;
-               }
-
-               if (ret.is_object()) newobj = ret.to_object(*getGlobal(env));
-               else {
-                       log_debug("Native function called as constructor 
returned %s", ret);
-                       newobj = new as_object();
-               }
-
-        // There should always be an object by this stage. Failed constructors
-        // are handled in the catch.
-               assert(newobj); 
-
-               // Add a __constructor__ member to the new object, but only for 
SWF6 up
-               // (to be checked). NOTE that we assume the builtin constructors
-               // won't set __constructor__ to some other value...
-               int flags = PropFlags::dontEnum | 
-                    PropFlags::onlySWF6Up; 
-
-               newobj->init_member(NSV::PROP_uuCONSTRUCTORuu, as_value(this), 
flags);
+       as_value proto;
+    bool has_proto = get_member(NSV::PROP_PROTOTYPE, &proto);
+    if (!has_proto) log_debug("No prototype");
+    else log_debug("Has prototype");
+               
+    // Create an empty object, with a ref to the constructor's prototype.
+    // TODO: The prototype should not be converted to an object!
+    as_object* newobj = new as_object();
+    if (has_proto) newobj->set_prototype(proto.to_object(*getGlobal(env)));
+    
+    // Add a __constructor__ member to the new object, but only for SWF6 up
+    // (to be checked). NOTE that we assume the builtin constructors
+    // won't set __constructor__ to some other value...
+    int flags = PropFlags::dontEnum | 
+                PropFlags::onlySWF6Up; 
+
+    newobj->init_member(NSV::PROP_uuCONSTRUCTORuu, as_value(this), flags);
+
+    if (swfversion < 7) {
+        newobj->init_member(NSV::PROP_CONSTRUCTOR, as_value(this),
+               PropFlags::dontEnum);
+    }
+
+    fn_call fn(newobj, env, args, newobj->get_super(), true);
+    as_value ret;
+
+    try {
+        ret = call(fn);
+    }
+    catch (GnashException& ex) {
+        // Catching a std::exception here can mask all sorts of bad 
+        // behaviour, as (for instance) a poorly constructed string may
+        // smash the stack, throw an exception, but not abort.
+        // This is very effective at confusing debugging tools.
+        // We only throw GnashExceptions. A std::bad_alloc may also be
+        // reasonable, but anything else shouldn't be caught here.
+        log_debug("Native function called as constructor threw exception: "
+                "%s", ex.what());
+
+        // If a constructor throws an exception, throw it back to the
+        // caller. This is the only way to signal that a constructor
+        // did not return anything.
+        throw;
+    }
+
+    // Some built-in constructors do things properly and operate on the
+    // '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->init_member(NSV::PROP_uuCONSTRUCTORuu, as_value(this),
+                flags);
 
         // Also for SWF5+ only?
-               if (swfversion < 7) {
-                       newobj->init_member(NSV::PROP_CONSTRUCTOR, 
as_value(this), flags);
-               }
-
+        if (swfversion < 7) {
+            newobj->init_member(NSV::PROP_CONSTRUCTOR, as_value(this),
+                    PropFlags::dontEnum);
+        }
     }
-       else {
-               // Set up the prototype.
-               as_value proto;
-
-               // We can safely call as_object::get_member here as member name 
is 
-               // a literal string in lowercase. (we should likely avoid 
calling
-               // get_member as a whole actually, and use a getProto() or 
similar
-               // method directly instead) TODO
-               /*bool func_has_prototype=*/ get_member(NSV::PROP_PROTOTYPE, 
&proto);
-
-               // User could have dropped the prototype.
-               // see construct-properties-#.swf from swfdec testsuite
-
-               IF_VERBOSE_ACTION(
-            log_action(_("constructor prototype is %s"), proto);
-               );
-
-               // Create an empty object, with a ref to the constructor's 
prototype.
-               newobj = new as_object(proto.to_object(*getGlobal(env)));
-
-               // Add a __constructor__ member to the new object, but only for 
SWF6 up
-               // (to be checked)
-        // Can delete, hidden in swf5 
-               int flags = PropFlags::dontEnum | 
-                    PropFlags::onlySWF6Up; 
-
-               newobj->init_member(NSV::PROP_uuCONSTRUCTORuu, this, flags);
-
-               if (swfversion < 7) {
-                       newobj->init_member(NSV::PROP_CONSTRUCTOR, this, flags);
-               }
-
-               // Super is computed from the object we're constructing,
-               // It will work as long as we did set it's __proto__ and 
__constructor__
-               // properties already.
-               as_object* super = newobj->get_super();
-
-               // Call the actual constructor function; new_obj is its 'this'.
-
-               // We don't need the function result.
-               fn_call fn(newobj.get(), env, args, super);
-               call(fn);
-       }
-
-       if (!has_proto) set_member(NSV::PROP_PROTOTYPE, as_value(newobj));
-    
+
        return newobj;
 }
 
 
 void
+registerFunctionNative(as_object& global)
+{
+    VM& vm = getVM(global);
+    vm.registerNative(function_call, 101, 10);
+    vm.registerNative(function_apply, 101, 11);
+}
+
+void
 function_class_init(as_object& global, const ObjectURI& uri)
 {
-       boost::intrusive_ptr<builtin_function> func = 
-        as_function::getFunctionConstructor();
+    NativeFunction* func = as_function::getFunctionConstructor();
 
        // Register _global.Function, only visible for SWF6 up
        int swf6flags = PropFlags::dontEnum | 
                     PropFlags::dontDelete | 
                     PropFlags::onlySWF6Up;
-       global.init_member(getName(uri), func.get(), swf6flags, 
getNamespace(uri));
+       global.init_member(getName(uri), func, swf6flags, getNamespace(uri));
 }
 
 namespace {
@@ -281,24 +247,20 @@
                // Initialize Function prototype
                proto = new as_object();
         
-        // TODO: get a Global_as passed in.
-        Global_as* gl = getGlobal(*proto);
-
                // We initialize the __proto__ member separately, as 
getObjectInterface
                // will end up calling getFunctionPrototype again and we want 
that
                // call to return the still-not-completely-constructed 
prototype rather
                // then create a new one. 
                proto->set_prototype(getObjectInterface());
 
-               VM::get().addStatic(proto.get());
-
-               const int flags = PropFlags::dontDelete | 
-                          PropFlags::dontEnum | 
-                          PropFlags::onlySWF6Up; 
-
-               proto->init_member("apply", gl->createFunction(function_apply),
-                flags);
-               proto->init_member("call", gl->createFunction(function_call), 
flags);
+        VM& vm = VM::get();
+
+               vm.addStatic(proto.get());
+
+               const int flags = as_object::DefaultFlags | 
PropFlags::onlySWF6Up; 
+
+               proto->init_member("call", vm.getNative(101, 10), flags);
+               proto->init_member("apply", vm.getNative(101, 11), flags);
        }
 
        return proto.get();
@@ -306,11 +268,9 @@
 }
 
 as_value
-function_ctor(const fn_call& /* fn */)
+function_ctor(const fn_call& /*fn*/)
 {
-       boost::intrusive_ptr<as_object> func = 
-        new as_object(getFunctionPrototype());
-       return as_value(func.get());
+       return as_value();
 }
 
 

=== modified file 'libcore/as_function.h'
--- a/libcore/as_function.h     2009-07-16 08:30:06 +0000
+++ b/libcore/as_function.h     2009-08-18 08:00:20 +0000
@@ -24,7 +24,7 @@
 // Forward declarations
 namespace gnash {
        class fn_call;
-       class builtin_function;
+       class NativeFunction;
        class Global_as;
 }
 
@@ -107,7 +107,7 @@
        }
 
        /// Return the built-in Function constructor
-       static boost::intrusive_ptr<builtin_function> getFunctionConstructor();
+       static NativeFunction* getFunctionConstructor();
 
 #ifdef GNASH_USE_GC
        /// Mark reachable resources. Override from GcResource
@@ -167,6 +167,7 @@
 
 /// Initialize the global Function constructor
 void function_class_init(as_object& global, const ObjectURI& uri);
+void registerFunctionNative(as_object& global);
 
 } // gnash namespace
 

=== modified file 'libcore/as_object.cpp'
--- a/libcore/as_object.cpp     2009-07-30 15:20:46 +0000
+++ b/libcore/as_object.cpp     2009-08-18 05:26:43 +0000
@@ -587,13 +587,12 @@
 }
 
 void
-as_object::set_prototype(boost::intrusive_ptr<as_object> proto, int flags)
+as_object::set_prototype(const as_value& proto, int flags)
 {
        // TODO: check what happens if __proto__ is set as a user-defined 
     // getter/setter
        // TODO: check triggers !!
-       _members.setValue(NSV::PROP_uuPROTOuu, as_value(proto.get()), *this, 0,
-            flags);
+       _members.setValue(NSV::PROP_uuPROTOuu, proto, *this, 0, flags);
 }
 
 void

=== modified file 'libcore/as_object.h'
--- a/libcore/as_object.h       2009-07-30 15:20:46 +0000
+++ b/libcore/as_object.h       2009-08-18 05:27:02 +0000
@@ -1061,8 +1061,7 @@
     /// public: set_member("__proto__", anyting)
     /// will do just the same
     ///
-    void set_prototype(boost::intrusive_ptr<as_object> proto,
-            int flags = DefaultFlags);
+    void set_prototype(const as_value& proto, int flags = DefaultFlags);
 
     /// @{ Common ActionScript methods for DisplayObjects
     /// TODO: make protected

=== modified file 'libcore/asobj/Array_as.cpp'
--- a/libcore/asobj/Array_as.cpp        2009-07-29 05:59:24 +0000
+++ b/libcore/asobj/Array_as.cpp        2009-08-18 06:49:40 +0000
@@ -26,6 +26,7 @@
 #include "Array_as.h"
 #include "log.h"
 #include "builtin_function.h" // for Array class
+#include "NativeFunction.h" 
 #include "as_function.h" // for sort user-defined comparator
 #include "fn_call.h"
 #include "Global_as.h"

=== modified file 'libcore/asobj/AsBroadcaster.cpp'
--- a/libcore/asobj/AsBroadcaster.cpp   2009-08-12 14:27:26 +0000
+++ b/libcore/asobj/AsBroadcaster.cpp   2009-08-18 06:49:40 +0000
@@ -26,6 +26,7 @@
 #include "AsBroadcaster.h"
 #include "fn_call.h"
 #include "builtin_function.h"
+#include "NativeFunction.h" 
 #include "VM.h" // for getPlayerVersion() 
 #include "Object.h" // for getObjectInterface
 #include "Global_as.h"
@@ -40,8 +41,6 @@
     as_value asbroadcaster_broadcastMessage(const fn_call& fn);
     as_value asbroadcaster_initialize(const fn_call& fn);
     as_value asbroadcaster_ctor(const fn_call& fn);
-
-    as_object* getAsBroadcasterInterface();
 }
 
 
@@ -117,19 +116,23 @@
 void 
 AsBroadcaster::initialize(as_object& o)
 {
-    as_object* asb = getAsBroadcaster();
-
-    as_value tmp;
-
-    if (asb->get_member(NSV::PROP_ADD_LISTENER, &tmp)) {
-        o.set_member(NSV::PROP_ADD_LISTENER, tmp);
-    }
-
-    if (asb->get_member(NSV::PROP_REMOVE_LISTENER, &tmp)) {
-        o.set_member(NSV::PROP_REMOVE_LISTENER, tmp);
-    }
-    
     Global_as* gl = getGlobal(o);
+
+    // Find _global.AsBroadcaster.
+    as_object* asb =
+        gl->getMember(NSV::CLASS_AS_BROADCASTER).to_object(*gl).get();
+
+    // If it's not an object, these are left undefined, but they are
+    // always attached to the initialized object.
+    as_value al, rl;
+
+    if (asb) {
+        al = asb->getMember(NSV::PROP_ADD_LISTENER);
+        rl = asb->getMember(NSV::PROP_REMOVE_LISTENER);
+    }
+    
+    o.set_member(NSV::PROP_ADD_LISTENER, al);
+    o.set_member(NSV::PROP_REMOVE_LISTENER, rl);
     
     // The function returned by ASnative(101, 12) is attached, even though
     // this may not exist (e.g. if _global.ASnative is altered)
@@ -140,39 +143,26 @@
 
 }
 
-as_object*
-AsBroadcaster::getAsBroadcaster()
+void
+attachAsBroadcasterStaticInterface(as_object& o)
 {
-    VM& vm = VM::get();
-
-    static boost::intrusive_ptr<as_object> obj = NULL;
-    if ( ! obj )
-    {
-        as_object* proto = getAsBroadcasterInterface();
-        Global_as* gl = vm.getGlobal();
-        obj = gl->createClass(asbroadcaster_ctor, proto); 
-        vm.addStatic(obj.get()); // correct ?
-
-        const int flags = PropFlags::dontEnum |
-                          PropFlags::dontDelete |
-                          PropFlags::onlySWF6Up;
-
-        // NOTE: we may add NSV::PROP_INITIALIZE, unavailable at
-        // time of writing. Anyway, since AsBroadcaster is the only
-        // class we know using an 'initialize' method we might as
-        // well save the string_table size in case we'll not load
-        // the class.
-        obj->init_member("initialize",
-                gl->createFunction(asbroadcaster_initialize), flags);
-        obj->init_member(NSV::PROP_ADD_LISTENER,
-                gl->createFunction(asbroadcaster_addListener), flags);
-        obj->init_member(NSV::PROP_REMOVE_LISTENER,
-                gl->createFunction(asbroadcaster_removeListener), flags);
-        obj->init_member(NSV::PROP_BROADCAST_MESSAGE, vm.getNative(101, 12),
-                flags);
-    }
-
-    return obj.get();
+    const int flags = PropFlags::dontEnum |
+                      PropFlags::dontDelete |
+                      PropFlags::onlySWF6Up;
+
+    Global_as* gl = getGlobal(o);
+
+    o.init_member("initialize",
+            gl->createFunction(asbroadcaster_initialize), flags);
+    o.init_member(NSV::PROP_ADD_LISTENER,
+            gl->createFunction(asbroadcaster_addListener), flags);
+    o.init_member(NSV::PROP_REMOVE_LISTENER,
+            gl->createFunction(asbroadcaster_removeListener), flags);
+
+    VM& vm = getVM(o);
+    o.init_member(NSV::PROP_BROADCAST_MESSAGE, vm.getNative(101, 12),
+            flags);
+
 }
 
 
@@ -187,9 +177,16 @@
 void
 AsBroadcaster::init(as_object& global, const ObjectURI& uri)
 {
-    // _global.AsBroadcaster is NOT a class, but a simple object
-    global.init_member(getName(uri), AsBroadcaster::getAsBroadcaster(),
-            as_object::DefaultFlags, getNamespace(uri));
+    Global_as* gl = getGlobal(global);
+
+    as_object* proto = gl->createObject(getObjectInterface());
+    as_object* cl = gl->createClass(asbroadcaster_ctor, proto); 
+
+    attachAsBroadcasterStaticInterface(*cl);
+
+    // AsBroadcaster is a class, even though it doesn't look much like one.
+    global.init_member(getName(uri), cl, as_object::DefaultFlags,
+            getNamespace(uri));
 }
 
 
@@ -444,23 +441,11 @@
 
 }
 
-as_object*
-getAsBroadcasterInterface()
-{
-    static boost::intrusive_ptr<as_object> o=NULL;
-    if ( o == NULL )
-    {
-        o = new as_object(getObjectInterface());
-        VM::get().addStatic(o.get());
-    }
-    return o.get();
-}
-
+// The constructor does nothing at all.
 as_value
 asbroadcaster_ctor(const fn_call& /*fn*/)
 {
-    as_object* obj = new as_object(getAsBroadcasterInterface());
-    return as_value(obj);
+    return as_value();
 }
 
 } // anonymous namespace

=== modified file 'libcore/asobj/Color_as.cpp'
--- a/libcore/asobj/Color_as.cpp        2009-08-13 12:28:02 +0000
+++ b/libcore/asobj/Color_as.cpp        2009-08-18 06:49:40 +0000
@@ -28,6 +28,7 @@
 #include "Global_as.h"
 #include "smart_ptr.h" // for boost intrusive_ptr
 #include "builtin_function.h" // need builtin_function
+#include "NativeFunction.h" 
 #include "Object.h" // for getObjectInterface
 #include "cxform.h" // for composition
 #include "VM.h"
@@ -46,7 +47,7 @@
     as_value color_settransform(const fn_call& fn);
     as_value color_ctor(const fn_call& fn);
 
-    as_object* getColorInterface();
+    void attachColorInterface(as_object& o);
     inline void parseColorTransProp(as_object& obj, string_table::key key,
             boost::int16_t& target, bool scale);
     inline MovieClip* getTarget(as_object* obj, const fn_call& fn);
@@ -68,9 +69,11 @@
 color_class_init(as_object& global, const ObjectURI& uri)
 {
     Global_as* gl = getGlobal(global);
-    as_object* proto = getColorInterface();
+    as_object* proto = gl->createObject(getObjectInterface());
     as_object* cl = gl->createClass(&color_ctor, proto);
 
+    attachColorInterface(*proto);
+
     // This has to be done after createClass is called, as that modifies
     // proto.
     const int protect = as_object::DefaultFlags | PropFlags::readOnly;
@@ -102,21 +105,6 @@
 
 }
 
-as_object*
-getColorInterface()
-{
-       static boost::intrusive_ptr<as_object> o;
-       if ( ! o )
-       {
-        as_object* proto = getObjectInterface();
-               o = new as_object(proto);
-
-               attachColorInterface(*o);
-       }
-       return o.get();
-}
-
-
 as_value
 color_getrgb(const fn_call& fn)
 {
@@ -255,8 +243,7 @@
 color_ctor(const fn_call& fn)
 {
        
-    as_object* proto = getColorInterface();
-    boost::intrusive_ptr<as_object> obj = new as_object(proto);
+    as_object* obj = fn.this_ptr.get();
     
     as_value target;
     if (fn.nargs) target = fn.arg(0);
@@ -265,7 +252,7 @@
 
     obj->init_member(NSV::PROP_TARGET, target, flags); 
 
-       return as_value(obj.get()); // will keep alive
+       return as_value(); 
 }
 
 inline void

=== modified file 'libcore/asobj/CustomActions.cpp'
--- a/libcore/asobj/CustomActions.cpp   2009-07-29 05:40:20 +0000
+++ b/libcore/asobj/CustomActions.cpp   2009-08-18 10:55:56 +0000
@@ -32,13 +32,28 @@
 
 namespace gnash {
 
-as_value customactions_get(const fn_call& fn);
-as_value customactions_install(const fn_call& fn);
-as_value customactions_list(const fn_call& fn);
-as_value customactions_uninstall(const fn_call& fn);
-as_value customactions_ctor(const fn_call& fn);
-
-static void
+namespace {
+
+    as_value customactions_get(const fn_call& fn);
+    as_value customactions_install(const fn_call& fn);
+    as_value customactions_list(const fn_call& fn);
+    as_value customactions_uninstall(const fn_call& fn);
+    as_value customactions_ctor(const fn_call& fn);
+    void attachCustomActionsInterface(as_object& o);
+
+}
+
+// extern (used by Global.cpp)
+void 
+customactions_class_init(as_object& where, const ObjectURI& uri)
+{
+    registerBuiltinObject(where, attachCustomActionsInterface, uri);
+}
+
+
+namespace {
+
+void
 attachCustomActionsInterface(as_object& o)
 {
     Global_as* gl = getGlobal(o);
@@ -48,83 +63,35 @@
        o.init_member("uninstall", gl->createFunction(customactions_uninstall));
 }
 
-static as_object*
-getCustomActionsInterface()
-{
-       static boost::intrusive_ptr<as_object> o;
-       if ( ! o )
-       {
-               o = new as_object(getObjectInterface());
-               attachCustomActionsInterface(*o);
-       }
-       return o.get();
-}
-
-class customactions_as_object: public as_object
-{
-
-public:
-
-       customactions_as_object()
-               :
-               as_object(getCustomActionsInterface())
-       {}
-
-       // override from as_object ?
-       //std::string get_text_value() const { return "CustomActions"; }
-
-       // override from as_object ?
-       //double get_numeric_value() const { return 0; }
-};
-
-as_value customactions_get(const fn_call& /*fn*/) {
-    log_unimpl (__FUNCTION__);
-    return as_value();
-}
-as_value customactions_install(const fn_call& /*fn*/) {
-    log_unimpl (__FUNCTION__);
-    return as_value();
-}
-as_value customactions_list(const fn_call& /*fn*/) {
-    log_unimpl (__FUNCTION__);
-    return as_value();
-}
-as_value customactions_uninstall(const fn_call& /*fn*/) {
-    log_unimpl (__FUNCTION__);
-    return as_value();
-}
-
-as_value
-customactions_ctor(const fn_call& /* fn */)
-{
-       boost::intrusive_ptr<as_object> obj = new customactions_as_object;
-       
-       return as_value(obj.get()); // will keep alive
-}
-
-// extern (used by Global.cpp)
-void customactions_class_init(as_object& global, const ObjectURI& uri)
-{
-       // This is going to be the global CustomActions "class"/"function"
-       static boost::intrusive_ptr<as_object> cl;
-
-       if ( cl == NULL )
-       {
-        Global_as* gl = getGlobal(global);
-        as_object* proto = getCustomActionsInterface();
-        cl = gl->createClass(&customactions_ctor, proto);
-               // replicate all interface to class, to be able to access
-               // all methods as static functions
-               attachCustomActionsInterface(*cl);
-                    
-       }
-
-       // Register _global.CustomActions
-       global.init_member(getName(uri), cl.get(), as_object::DefaultFlags,
-            getNamespace(uri));
-
-}
-
+as_value
+customactions_get(const fn_call& /*fn*/)
+{
+    log_unimpl (__FUNCTION__);
+    return as_value();
+}
+
+as_value
+customactions_install(const fn_call& /*fn*/)
+{
+    log_unimpl (__FUNCTION__);
+    return as_value();
+}
+
+as_value
+customactions_list(const fn_call& /*fn*/)
+{
+    log_unimpl (__FUNCTION__);
+    return as_value();
+}
+
+as_value
+customactions_uninstall(const fn_call& /*fn*/)
+{
+    log_unimpl (__FUNCTION__);
+    return as_value();
+}
+
+}
 
 } // end of gnash namespace
 

=== modified file 'libcore/asobj/Date_as.cpp'
--- a/libcore/asobj/Date_as.cpp 2009-08-13 09:20:28 +0000
+++ b/libcore/asobj/Date_as.cpp 2009-08-18 06:49:40 +0000
@@ -74,6 +74,7 @@
 #include "Global_as.h"
 #include "GnashException.h"
 #include "builtin_function.h"
+#include "NativeFunction.h" 
 #include "Object.h" // for getObjectInterface
 #include "ClockTime.h"
 #include "VM.h"

=== modified file 'libcore/asobj/Error_as.cpp'
--- a/libcore/asobj/Error_as.cpp        2009-08-07 14:01:37 +0000
+++ b/libcore/asobj/Error_as.cpp        2009-08-17 11:10:20 +0000
@@ -40,7 +40,6 @@
     as_value error_toString(const fn_call& fn);
     as_value error_ctor(const fn_call& fn);
 
-    as_object* getErrorInterface();
     void attachErrorInterface(as_object& o);
 }
 
@@ -52,8 +51,11 @@
     
     Global_as* gl = getGlobal(where);
 
-    boost::intrusive_ptr<as_object> cl =
-        gl->createClass(&error_ctor, getErrorInterface());
+       as_object* proto = gl->createObject(getObjectInterface());
+    boost::intrusive_ptr<as_object> cl = gl->createClass(&error_ctor, proto);
+
+    // Attach properties to the class prototype.
+    attachErrorInterface(*proto);
 
        // Register _global.Error
        where.init_member(getName(uri), cl.get(), as_object::DefaultFlags,
@@ -63,24 +65,6 @@
 
 namespace {
 
-as_object*
-getErrorInterface()
-{
-       static boost::intrusive_ptr<as_object> o;
-
-       if ( ! o )
-       {
-               o = new as_object(getObjectInterface());
-               VM::get().addStatic(o.get());
-
-               attachErrorInterface(*o);
-
-       }
-
-       return o.get();
-}
-
-
 void
 attachErrorInterface(as_object& o)
 {
@@ -111,16 +95,15 @@
 
     if (!fn.isInstantiation()) return as_value();
 
-    as_object* proto = getErrorInterface();
-       boost::intrusive_ptr<as_object> err = new as_object(proto);
-       
+    as_object* err = fn.this_ptr.get();
+
     string_table& st = getStringTable(fn);
-    if (fn.nargs > 0)
-       {
+
+    if (fn.nargs) {
                err->set_member(st.find("message"), fn.arg(0));
        }
 
-       return as_value(err.get()); // will keep alive
+       return as_value();
 }
 
 }

=== modified file 'libcore/asobj/Global_as.h'
--- a/libcore/asobj/Global_as.h 2009-07-28 11:11:43 +0000
+++ b/libcore/asobj/Global_as.h 2009-08-18 10:55:56 +0000
@@ -20,6 +20,7 @@
 #define GNASH_GLOBAL_H
 
 #include "as_object.h" // for inheritance
+#include "Object.h"
 
 // Forward declarations
 namespace gnash {
@@ -77,6 +78,27 @@
     virtual VM& getVM() const = 0;
 };
 
+typedef void(*Properties)(as_object&);
+
+/// Register a built-in object
+//
+/// @return the built-in object with properties attached.
+inline as_object*
+registerBuiltinObject(as_object& where, Properties p, const ObjectURI& uri)
+{
+
+    // This is going to be the global Mouse "class"/"function"
+    Global_as* gl = getGlobal(where);
+    as_object* proto = getObjectInterface();
+    as_object* obj = gl->createObject(proto);
+    p(*obj);
+    
+    where.init_member(getName(uri), obj, as_object::DefaultFlags,
+            getNamespace(uri));
+
+    return obj;
+}
+
 } // namespace gnash
 
 #endif 

=== modified file 'libcore/asobj/Globals.cpp'
--- a/libcore/asobj/Globals.cpp 2009-08-14 13:01:46 +0000
+++ b/libcore/asobj/Globals.cpp 2009-08-18 08:00:20 +0000
@@ -26,6 +26,7 @@
 #include "PropFlags.h"
 #include "as_value.h"
 #include "as_function.h" // for function_class_init
+#include "NativeFunction.h" 
 #include "Array_as.h"
 #include "AsBroadcaster.h"
 #include "Boolean_as.h"
@@ -161,23 +162,20 @@
 void
 AVM2Global::registerClasses()
 {
+   
+    const string_table::key NS_GLOBAL(0);
+    
+    object_class_init(*this, ObjectURI(NSV::CLASS_OBJECT, NS_GLOBAL)); 
+    function_class_init(*this, ObjectURI(NSV::CLASS_FUNCTION, NS_GLOBAL));
+    string_class_init(*this, ObjectURI(NSV::CLASS_STRING, NS_GLOBAL)); 
+    array_class_init(*this, ObjectURI(NSV::CLASS_ARRAY, NS_GLOBAL)); 
     
     init_member("trace", createFunction(global_trace));
     init_member("escape", createFunction(global_escape));
-   
-    const string_table::key NS_GLOBAL(0);
 
-    object_class_init(*this, ObjectURI(NSV::CLASS_OBJECT, NS_GLOBAL)); 
-    string_class_init(*this, ObjectURI(NSV::CLASS_STRING, NS_GLOBAL)); 
-    array_class_init(*this, ObjectURI(NSV::CLASS_ARRAY, NS_GLOBAL)); 
-    function_class_init(*this, ObjectURI(NSV::CLASS_FUNCTION, NS_GLOBAL));
-    
     _classes.declareAll(avm2Classes(_vm.getStringTable()));
-
     _classes.getGlobalNs()->stubPrototype(_classes, NSV::CLASS_FUNCTION);
-    
     _classes.getGlobalNs()->getClass(NSV::CLASS_FUNCTION)->setDeclared();
-
     _classes.getGlobalNs()->stubPrototype(_classes, NSV::CLASS_OBJECT);
     _classes.getGlobalNs()->getClass(NSV::CLASS_OBJECT)->setDeclared();
     _classes.getGlobalNs()->stubPrototype(_classes, NSV::CLASS_ARRAY);
@@ -202,14 +200,19 @@
 builtin_function*
 AVM1Global::createFunction(Global_as::ASFunction function)
 {
-    return new builtin_function(*this, function);
+    builtin_function* f = new builtin_function(*this, function);
+    f->init_member(NSV::PROP_CONSTRUCTOR,
+            as_function::getFunctionConstructor());
+    return f;
 }
 
 as_object*
 AVM1Global::createClass(Global_as::ASFunction ctor, as_object* prototype)
 {
-    return new builtin_function(*this, ctor, prototype);
-
+    as_object* cl = new builtin_function(*this, ctor, prototype);
+    cl->init_member(NSV::PROP_CONSTRUCTOR,
+            as_function::getFunctionConstructor());
+    return cl;
 }
 
 as_object*
@@ -252,7 +255,10 @@
 builtin_function*
 AVM2Global::createFunction(Global_as::ASFunction function)
 {
-    return new builtin_function(*this, function);
+    builtin_function* f = new builtin_function(*this, function);
+    f->init_member(NSV::PROP_CONSTRUCTOR,
+            as_function::getFunctionConstructor());
+    return f;
 }
 
 as_object*
@@ -260,7 +266,10 @@
 {
     // TODO: this should attach the function to the prototype as its
     // constructor member.
-    return new builtin_function(*this, ctor, prototype);
+    as_object* cl = new builtin_function(*this, ctor, prototype);
+    cl->init_member(NSV::PROP_CONSTRUCTOR,
+            as_function::getFunctionConstructor());
+    return cl;
 }
 
 as_object*
@@ -302,6 +311,13 @@
 {
     registerNatives(*this);
 
+    const string_table::key NS_GLOBAL(0);
+
+    object_class_init(*this, ObjectURI(NSV::CLASS_OBJECT, NS_GLOBAL)); 
+    function_class_init(*this, ObjectURI(NSV::CLASS_FUNCTION, NS_GLOBAL));
+    string_class_init(*this, ObjectURI(NSV::CLASS_STRING, NS_GLOBAL)); 
+    array_class_init(*this, ObjectURI(NSV::CLASS_ARRAY, NS_GLOBAL)); 
+
     // No idea why, but it seems there's a NULL _global.o 
     // defined at player startup...
     // Probably due to the AS-based initialization 
@@ -329,13 +345,6 @@
 
     _classes.declareAll(avm1Classes());
 
-    const string_table::key NS_GLOBAL(0);
-
-    object_class_init(*this, ObjectURI(NSV::CLASS_OBJECT, NS_GLOBAL)); 
-    string_class_init(*this, ObjectURI(NSV::CLASS_STRING, NS_GLOBAL)); 
-    array_class_init(*this, ObjectURI(NSV::CLASS_ARRAY, NS_GLOBAL)); 
-    function_class_init(*this, ObjectURI(NSV::CLASS_FUNCTION, NS_GLOBAL));
-
     // SWF8 visibility:
     const string_table::key NS_FLASH = getStringTable(*this).find("flash");
     flash_package_init(*this, ObjectURI(NS_FLASH, NS_GLOBAL)); 
@@ -1282,6 +1291,7 @@
     vm.registerNative(global_clearInterval, 250, 1);
 
     registerObjectNative(global);
+    registerFunctionNative(global);
     registerStringNative(global);
     registerArrayNative(global);
     registerMovieClipNative(global);

=== modified file 'libcore/asobj/LoadVars_as.cpp'
--- a/libcore/asobj/LoadVars_as.cpp     2009-07-29 05:40:20 +0000
+++ b/libcore/asobj/LoadVars_as.cpp     2009-08-18 10:32:14 +0000
@@ -25,6 +25,7 @@
 #include "Global_as.h"
 #include "smart_ptr.h" // GNASH_USE_GC
 #include "builtin_function.h" // need builtin_function
+#include "NativeFunction.h" // need builtin_function
 #include "as_function.h" // for calling event handlers
 #include "as_value.h" // for setting up a fn_call
 #include "VM.h"
@@ -142,22 +143,16 @@
 loadvars_class_init(as_object& global, const ObjectURI& uri)
 {
        // This is going to be the global LoadVars "class"/"function"
-       static boost::intrusive_ptr<as_object> cl;
-
-       if ( cl == NULL )
-       {
-        Global_as* gl = getGlobal(global);
-        as_object* proto = getLoadVarsInterface();
-        cl = gl->createClass(&loadvars_ctor, proto);
-       }
+    Global_as* gl = getGlobal(global);
+    as_object* proto = getLoadVarsInterface();
+    as_object* cl = gl->createClass(&loadvars_ctor, proto);
 
        // Register _global.LoadVars, only visible for SWF6 up
        int swf6flags = PropFlags::dontEnum | 
                     PropFlags::dontDelete | 
                     PropFlags::onlySWF6Up;
 
-       global.init_member(getName(uri), cl.get(), swf6flags,
-                       getNamespace(uri));
+       global.init_member(getName(uri), cl, swf6flags, getNamespace(uri));
 
 }
 

=== modified file 'libcore/asobj/LoadableObject.cpp'
--- a/libcore/asobj/LoadableObject.cpp  2009-08-11 11:13:35 +0000
+++ b/libcore/asobj/LoadableObject.cpp  2009-08-18 06:49:40 +0000
@@ -27,6 +27,7 @@
 #include "movie_root.h"
 #include "VM.h"
 #include "builtin_function.h"
+#include "NativeFunction.h"
 #include "utf8.h"
 #include "fn_call.h"
 #include "GnashAlgorithm.h"

=== modified file 'libcore/asobj/Math_as.cpp'
--- a/libcore/asobj/Math_as.cpp 2009-07-16 09:37:37 +0000
+++ b/libcore/asobj/Math_as.cpp 2009-08-18 11:13:25 +0000
@@ -20,13 +20,6 @@
 //
 // This file implements methods of the ActionScript Math class.
 //
-// They are all static methods; there is no Math class object as such.
-//
-// TODO:
-//     min(), max() and pow(1) return NaN here; they should return
-//     Infinity, -Infinity and 1 respectively
-//
-
 
 #include "VM.h" // get random generator
 #include "fn_call.h"
@@ -34,6 +27,7 @@
 #include "Math_as.h"
 #include "log.h"
 #include "builtin_function.h" 
+#include "NativeFunction.h" 
 #include "Object.h" // for getObjectInterface
 #include "GnashNumeric.h"
 
@@ -91,15 +85,9 @@
 
 
 void
-math_class_init(as_object& global, const ObjectURI& uri)
+math_class_init(as_object& where, const ObjectURI& uri)
 {
-    // Create built-in math object. It is not a class.
-       static boost::intrusive_ptr<as_object> obj =
-            new as_object(getObjectInterface());
-
-       attachMathInterface(*obj);
-       global.init_member(getName(uri), obj.get(), as_object::DefaultFlags,
-            getNamespace(uri));
+    registerBuiltinObject(where, attachMathInterface, uri);
 }
 
 namespace {

=== modified file 'libcore/asobj/MovieClipLoader.cpp'
--- a/libcore/asobj/MovieClipLoader.cpp 2009-07-16 09:02:35 +0000
+++ b/libcore/asobj/MovieClipLoader.cpp 2009-08-18 10:32:14 +0000
@@ -230,15 +230,10 @@
 moviecliploader_class_init(as_object& global, const ObjectURI& uri)
 {
        // This is going to be the global Number "class"/"function"
-       static boost::intrusive_ptr<as_object> cl = NULL;
-
-       if (cl == NULL)
-       {
-        Global_as* gl = getGlobal(global);
-               cl = gl->createClass(&moviecliploader_new,
+    Global_as* gl = getGlobal(global);
+    as_object* cl = gl->createClass(&moviecliploader_new,
                 getMovieClipLoaderInterface());
-       }
-       global.init_member(getName(uri), cl.get(), as_object::DefaultFlags,
+       global.init_member(getName(uri), cl, as_object::DefaultFlags,
             getNamespace(uri)); 
 }
 

=== modified file 'libcore/asobj/NetConnection_as.cpp'
--- a/libcore/asobj/NetConnection_as.cpp        2009-08-10 11:39:25 +0000
+++ b/libcore/asobj/NetConnection_as.cpp        2009-08-18 10:32:14 +0000
@@ -691,22 +691,12 @@
 NetConnection_as::init(as_object& global, const ObjectURI& uri)
 {
     // This is going to be the global NetConnection "class"/"function"
-    static boost::intrusive_ptr<as_object> cl;
-
-    if ( cl == NULL )
-    {
-        Global_as* gl = getGlobal(global);
-        as_object* proto = getNetConnectionInterface();
-        cl = gl->createClass(&netconnection_new, proto);
-
-        // replicate all interface to class, to be able to access
-        // all methods as static functions
-        attachNetConnectionInterface(*cl);
-             
-    }
+    Global_as* gl = getGlobal(global);
+    as_object* proto = getNetConnectionInterface();
+    as_object* cl = gl->createClass(&netconnection_new, proto);
 
     // Register _global.String
-    global.init_member(getName(uri), cl.get(), as_object::DefaultFlags,
+    global.init_member(getName(uri), cl, as_object::DefaultFlags,
             getNamespace(uri));
 }
 

=== modified file 'libcore/asobj/Object.cpp'
--- a/libcore/asobj/Object.cpp  2009-08-11 08:35:18 +0000
+++ b/libcore/asobj/Object.cpp  2009-08-18 09:24:49 +0000
@@ -23,10 +23,11 @@
 #include "smart_ptr.h"
 #include "fn_call.h"
 #include "as_object.h" // for inheritance
-#include "builtin_function.h" // need builtin_function
-#include "movie_definition.h" // for get_exported_resource
-#include "sprite_definition.h" // for get_movie_definition()
-#include "VM.h" // for SWF version (attachObjectInterface)
+#include "builtin_function.h" 
+#include "NativeFunction.h" 
+#include "movie_definition.h" 
+#include "sprite_definition.h"
+#include "VM.h" 
 #include "namedStrings.h" // for NSV::PROP_TO_STRING
 #include "Global_as.h"
 
@@ -61,7 +62,8 @@
        return new as_object(getObjectInterface());
 }
 
-void registerObjectNative(as_object& global)
+void
+registerObjectNative(as_object& global)
 {
     VM& vm = getVM(global);
 

=== modified file 'libcore/asobj/Selection_as.cpp'
--- a/libcore/asobj/Selection_as.cpp    2009-08-07 14:01:23 +0000
+++ b/libcore/asobj/Selection_as.cpp    2009-08-18 10:55:56 +0000
@@ -28,6 +28,7 @@
 #include "Global_as.h"
 #include "smart_ptr.h" // for boost intrusive_ptr
 #include "builtin_function.h" // need builtin_function
+#include "NativeFunction.h" 
 #include "Object.h" // for getObjectInterface
 #include "AsBroadcaster.h"
 #include "TextField.h"
@@ -46,22 +47,16 @@
     as_value selection_setFocus(const fn_call& fn);
     as_value selection_setSelection(const fn_call& fn);
 
-    as_object* getSelectionInterface();
     void attachSelectionInterface(as_object& o);
 }
 
 
 // extern (used by Global.cpp)
 void
-selection_class_init(as_object& global, const ObjectURI& uri)
+selection_class_init(as_object& where, const ObjectURI& uri)
 {
        // Selection is NOT a class, but a simple object, see Selection.as
-
-       as_object* obj = new as_object(getObjectInterface());
-       attachSelectionInterface(*obj);
-       global.init_member(getName(uri), obj, as_object::DefaultFlags,
-            getNamespace(uri));
-
+    registerBuiltinObject(where, attachSelectionInterface, uri);
 }
 
 void
@@ -100,18 +95,6 @@
  
 }
 
-as_object*
-getSelectionInterface()
-{
-       static boost::intrusive_ptr<as_object> o;
-       if ( ! o )
-       {
-               o = new as_object(getObjectInterface());
-               attachSelectionInterface(*o);
-       }
-       return o.get();
-}
-
 as_value
 selection_getBeginIndex(const fn_call& fn)
 {

=== modified file 'libcore/asobj/String_as.cpp'
--- a/libcore/asobj/String_as.cpp       2009-08-11 13:30:37 +0000
+++ b/libcore/asobj/String_as.cpp       2009-08-18 08:00:20 +0000
@@ -26,6 +26,7 @@
 #include "Global_as.h"
 #include "as_object.h"
 #include "builtin_function.h" // need builtin_function
+#include "NativeFunction.h" 
 #include "log.h"
 #include "Array_as.h"
 #include "as_value.h"
@@ -113,6 +114,7 @@
 registerStringNative(as_object& global)
 {
     VM& vm = getVM(global);
+    vm.registerNative(string_ctor, 251, 0);
        vm.registerNative(as_object::tostring_method, 251, 1);
        vm.registerNative(string_toString, 251, 2);
        vm.registerNative(string_oldToUpper, 102, 0);
@@ -137,13 +139,16 @@
 {
     // This is going to be the global String "class"/"function"
     
-    Global_as* gl = getGlobal(where);
+    VM& vm = getVM(where);
+
     as_object* proto = getStringInterface();
-    as_object* cl = gl->createClass(&string_ctor, proto);
-
-    cl->init_member("fromCharCode", getVM(*gl).getNative(251, 14)); 
-
-    int flags = PropFlags::dontEnum; 
+    as_object* cl = vm.getNative(251, 0);
+    cl->init_member(NSV::PROP_PROTOTYPE, proto);
+    proto->init_member(NSV::PROP_CONSTRUCTOR, cl);
+
+    cl->init_member("fromCharCode", vm.getNative(251, 14)); 
+
+    const int flags = PropFlags::dontEnum; 
     where.init_member(getName(uri), cl, flags, getNamespace(uri));
 }
 
@@ -822,7 +827,7 @@
 {
        std::string str;
        
-       if (fn.nargs )
+       if (fn.nargs)
        {
                str = fn.arg(0).to_string();
        }

=== modified file 
'libcore/asobj/flash/accessibility/AccessibilityProperties_as.cpp'
--- a/libcore/asobj/flash/accessibility/AccessibilityProperties_as.cpp  
2009-07-29 05:40:20 +0000
+++ b/libcore/asobj/flash/accessibility/AccessibilityProperties_as.cpp  
2009-08-17 11:46:48 +0000
@@ -40,31 +40,20 @@
 
 }
 
-class AccessibilityProperties_as : public as_object
-{
-
-public:
-
-    AccessibilityProperties_as()
-        :
-        as_object(getAccessibilityPropertiesInterface())
-    {}
-};
-
 // extern (used by Global.cpp)
-void accessibilityproperties_class_init(as_object& where, const ObjectURI& uri)
+void
+accessibilityproperties_class_init(as_object& where, const ObjectURI& uri)
 {
-    static boost::intrusive_ptr<as_object> cl;
-
-    if (!cl) {
-        Global_as* gl = getGlobal(where);
-        as_object* proto = getAccessibilityPropertiesInterface();
-        cl = gl->createClass(&accessibilityproperties_ctor, proto);
-        attachAccessibilityPropertiesStaticInterface(*cl);
-    }
+    Global_as* gl = getGlobal(where);
+    as_object* proto = gl->createObject();
+
+    as_object* cl = gl->createClass(&accessibilityproperties_ctor, proto);
+
+    attachAccessibilityPropertiesInterface(*proto);
+    attachAccessibilityPropertiesStaticInterface(*cl);
 
     // Register _global.AccessibilityProperties
-    where.init_member(getName(uri), cl.get(), as_object::DefaultFlags,
+    where.init_member(getName(uri), cl, as_object::DefaultFlags,
             getNamespace(uri));
 }
 
@@ -81,23 +70,10 @@
 
 }
 
-as_object*
-getAccessibilityPropertiesInterface()
-{
-    static boost::intrusive_ptr<as_object> o;
-    if ( ! o ) {
-        o = new as_object();
-        attachAccessibilityPropertiesInterface(*o);
-    }
-    return o.get();
-}
-
 as_value
 accessibilityproperties_ctor(const fn_call& /*fn*/)
 {
-    boost::intrusive_ptr<as_object> obj = new AccessibilityProperties_as;
-
-    return as_value(obj.get()); // will keep alive
+    return as_value();
 }
 
 } // anonymous namespace 

=== modified file 'libcore/asobj/flash/desktop/ClipboardFormats_as.cpp'
--- a/libcore/asobj/flash/desktop/ClipboardFormats_as.cpp       2009-07-31 
07:38:05 +0000
+++ b/libcore/asobj/flash/desktop/ClipboardFormats_as.cpp       2009-08-18 
11:07:45 +0000
@@ -40,13 +40,7 @@
 void
 clipboardformats_class_init(as_object& where, const ObjectURI& uri)
 {
-
-    Global_as* gl = getGlobal(where);
-    as_object* proto = getObjectInterface();
-    as_object* obj = gl->createObject(proto);
-    attachClipboardFormatsStaticInterface(*obj);
-    where.init_member(getName(uri), obj, as_object::DefaultFlags,
-            getNamespace(uri));
+    registerBuiltinObject(where, attachClipboardFormatsStaticInterface, uri);
 }
 
 namespace {

=== modified file 'libcore/asobj/flash/desktop/ClipboardTransferMode_as.cpp'
--- a/libcore/asobj/flash/desktop/ClipboardTransferMode_as.cpp  2009-07-31 
07:38:05 +0000
+++ b/libcore/asobj/flash/desktop/ClipboardTransferMode_as.cpp  2009-08-18 
11:07:45 +0000
@@ -42,12 +42,8 @@
 void
 clipboardtransfermode_class_init(as_object& where, const ObjectURI& uri)
 {
-    Global_as* gl = getGlobal(where);
-    as_object* proto = getObjectInterface();
-    as_object* obj = gl->createObject(proto);
-    attachClipboardTransferModeStaticInterface(*obj);
-    where.init_member(getName(uri), obj, as_object::DefaultFlags,
-            getNamespace(uri));
+    registerBuiltinObject(where, attachClipboardTransferModeStaticInterface, 
+            uri);
 }
 
 namespace {

=== modified file 'libcore/asobj/flash/desktop/Clipboard_as.cpp'
--- a/libcore/asobj/flash/desktop/Clipboard_as.cpp      2009-07-29 05:40:20 
+0000
+++ b/libcore/asobj/flash/desktop/Clipboard_as.cpp      2009-08-17 11:47:01 
+0000
@@ -28,6 +28,7 @@
 #include "smart_ptr.h" // for boost intrusive_ptr
 #include "builtin_function.h" // need builtin_function
 #include "GnashException.h" // for ActionException
+#include "Object.h"
 
 namespace gnash {
 
@@ -40,31 +41,19 @@
 
 }
 
-class Clipboard_as : public as_object
-{
-
-public:
-
-    Clipboard_as()
-        :
-        as_object(getClipboardInterface())
-    {}
-};
-
 // extern (used by Global.cpp)
 void clipboard_class_init(as_object& where, const ObjectURI& uri)
 {
-    static boost::intrusive_ptr<as_object> cl;
-
-    if (!cl) {
-        Global_as* gl = getGlobal(where);
-        as_object* proto = getClipboardInterface();
-        cl = gl->createClass(&clipboard_ctor, proto);
-        attachClipboardStaticInterface(*cl);
-    }
+    Global_as* gl = getGlobal(where);
+    as_object* proto = getObjectInterface();
+
+    as_object* cl = gl->createClass(&clipboard_ctor, proto);
+
+    attachClipboardInterface(*proto);
+    attachClipboardStaticInterface(*cl);
 
     // Register _global.Clipboard
-    where.init_member(getName(uri), cl.get(), as_object::DefaultFlags,
+    where.init_member(getName(uri), cl, as_object::DefaultFlags,
             getNamespace(uri));
 }
 
@@ -81,23 +70,10 @@
 
 }
 
-as_object*
-getClipboardInterface()
-{
-    static boost::intrusive_ptr<as_object> o;
-    if ( ! o ) {
-        o = new as_object();
-        attachClipboardInterface(*o);
-    }
-    return o.get();
-}
-
 as_value
 clipboard_ctor(const fn_call& /*fn*/)
 {
-    boost::intrusive_ptr<as_object> obj = new Clipboard_as;
-
-    return as_value(obj.get()); // will keep alive
+    return as_value(); 
 }
 
 } // anonymous namespace 

=== modified file 'libcore/asobj/flash/display/BitmapDataChannel_as.cpp'
--- a/libcore/asobj/flash/display/BitmapDataChannel_as.cpp      2009-07-31 
07:38:05 +0000
+++ b/libcore/asobj/flash/display/BitmapDataChannel_as.cpp      2009-08-18 
11:07:45 +0000
@@ -43,12 +43,7 @@
 void
 bitmapdatachannel_class_init(as_object& where, const ObjectURI& uri)
 {
-    Global_as* gl = getGlobal(where);
-    as_object* proto = getObjectInterface();
-    as_object* o = gl->createObject(proto);
-    attachBitmapDataChannelStaticInterface(*o);
-    where.init_member(getName(uri), o, as_object::DefaultFlags,
-            getNamespace(uri));
+    registerBuiltinObject(where, attachBitmapDataChannelStaticInterface, uri);
 }
 
 namespace {

=== modified file 'libcore/asobj/flash/display/BitmapData_as.cpp'
--- a/libcore/asobj/flash/display/BitmapData_as.cpp     2009-08-13 07:55:40 
+0000
+++ b/libcore/asobj/flash/display/BitmapData_as.cpp     2009-08-18 09:41:50 
+0000
@@ -224,24 +224,9 @@
     updateAttachedBitmaps();
 }
 
-as_object*
-getFlashDisplayBitmapDataConstructor(as_object& where)
-{
-    static as_object* cl = NULL;
-    if ( ! cl )
-    {
-        Global_as* gl = getGlobal(where);
-        as_object* proto = getBitmapDataInterface();
-        cl = gl->createClass(&BitmapData_ctor, proto);
-        VM::get().addStatic(cl);
-        attachBitmapDataStaticProperties(*cl);
-    }
-    return cl;
-}
-
-
 // extern 
-void bitmapdata_class_init(as_object& where, const ObjectURI& uri)
+void
+bitmapdata_class_init(as_object& where, const ObjectURI& uri)
 {
     // TODO: this may not be correct, but it should be enumerable.
     const int flags = 0;
@@ -677,7 +662,11 @@
 get_flash_display_bitmap_data_constructor(const fn_call& fn)
 {
     log_debug("Loading flash.display.BitmapData class");
-    return getFlashDisplayBitmapDataConstructor(*getVM(fn).getGlobal());
+    Global_as* gl = getGlobal(fn);
+    as_object* proto = getBitmapDataInterface();
+    as_object* cl = gl->createClass(&BitmapData_ctor, proto);
+    attachBitmapDataStaticProperties(*cl);
+    return cl;
 }
 
 as_value

=== modified file 'libcore/asobj/flash/display/CapsStyle_as.cpp'
--- a/libcore/asobj/flash/display/CapsStyle_as.cpp      2009-07-31 07:38:05 
+0000
+++ b/libcore/asobj/flash/display/CapsStyle_as.cpp      2009-08-18 11:07:45 
+0000
@@ -43,12 +43,7 @@
 void
 capsstyle_class_init(as_object& where, const ObjectURI& uri)
 {
-    Global_as* gl = getGlobal(where);
-    as_object* proto = getObjectInterface();
-    as_object* o = gl->createObject(proto);
-    attachCapsStyleStaticInterface(*o);
-    where.init_member(getName(uri), o, as_object::DefaultFlags,
-            getNamespace(uri));
+    registerBuiltinObject(where, attachCapsStyleStaticInterface, uri);
 }
 
 namespace {

=== modified file 'libcore/asobj/flash/display/GradientType_as.cpp'
--- a/libcore/asobj/flash/display/GradientType_as.cpp   2009-07-31 07:38:05 
+0000
+++ b/libcore/asobj/flash/display/GradientType_as.cpp   2009-08-18 11:02:07 
+0000
@@ -43,12 +43,7 @@
 void
 gradienttype_class_init(as_object& where, const ObjectURI& uri)
 {
-    Global_as* gl = getGlobal(where);
-    as_object* proto = getObjectInterface();
-    as_object* o = gl->createObject(proto);
-    attachGradientTypeStaticInterface(*o);
-    where.init_member(getName(uri), o, as_object::DefaultFlags,
-            getNamespace(uri));
+    registerBuiltinObject(where, attachGradientTypeStaticInterface, uri);
 }
 
 namespace {

=== modified file 'libcore/asobj/flash/display/InterpolationMethod_as.cpp'
--- a/libcore/asobj/flash/display/InterpolationMethod_as.cpp    2009-07-31 
07:38:05 +0000
+++ b/libcore/asobj/flash/display/InterpolationMethod_as.cpp    2009-08-18 
11:02:07 +0000
@@ -43,12 +43,7 @@
 void
 interpolationmethod_class_init(as_object& where, const ObjectURI& uri)
 {
-    Global_as* gl = getGlobal(where);
-    as_object* proto = getObjectInterface();
-    as_object* o = gl->createObject(proto);
-    attachInterpolationMethodStaticInterface(*o);
-    where.init_member(getName(uri), o, as_object::DefaultFlags,
-            getNamespace(uri));
+    registerBuiltinObject(where, attachInterpolationMethodStaticInterface, 
uri);
 }
 
 namespace {

=== modified file 'libcore/asobj/flash/display/JointStyle_as.cpp'
--- a/libcore/asobj/flash/display/JointStyle_as.cpp     2009-07-31 07:38:05 
+0000
+++ b/libcore/asobj/flash/display/JointStyle_as.cpp     2009-08-18 11:02:07 
+0000
@@ -43,12 +43,7 @@
 void
 jointstyle_class_init(as_object& where, const ObjectURI& uri)
 {
-    Global_as* gl = getGlobal(where);
-    as_object* proto = getObjectInterface();
-    as_object* o = gl->createObject(proto);
-    attachJointStyleStaticInterface(*o);
-    where.init_member(getName(uri), o, as_object::DefaultFlags,
-            getNamespace(uri));
+    registerBuiltinObject(where, attachJointStyleStaticInterface, uri);
 }
 
 namespace {

=== modified file 'libcore/asobj/flash/display/MovieClip_as.cpp'
--- a/libcore/asobj/flash/display/MovieClip_as.cpp      2009-07-29 05:40:20 
+0000
+++ b/libcore/asobj/flash/display/MovieClip_as.cpp      2009-08-18 06:49:40 
+0000
@@ -36,6 +36,7 @@
 #include "Global_as.h"
 #include "smart_ptr.h" // for boost intrusive_ptr
 #include "builtin_function.h" // need builtin_function
+#include "NativeFunction.h" 
 
 #include <boost/lexical_cast.hpp>
 

=== modified file 'libcore/asobj/flash/display/PixelSnapping_as.cpp'
--- a/libcore/asobj/flash/display/PixelSnapping_as.cpp  2009-07-31 07:38:05 
+0000
+++ b/libcore/asobj/flash/display/PixelSnapping_as.cpp  2009-08-18 11:07:45 
+0000
@@ -43,12 +43,7 @@
 void
 pixelsnapping_class_init(as_object& where, const ObjectURI& uri)
 {
-    Global_as* gl = getGlobal(where);
-    as_object* proto = getObjectInterface();
-    as_object* o = gl->createObject(proto);
-    attachPixelSnappingStaticInterface(*o);
-    where.init_member(getName(uri), o, as_object::DefaultFlags,
-            getNamespace(uri));
+    registerBuiltinObject(where, attachPixelSnappingStaticInterface, uri);
 }
 
 namespace {

=== modified file 'libcore/asobj/flash/display/SWFVersion_as.cpp'
--- a/libcore/asobj/flash/display/SWFVersion_as.cpp     2009-07-31 07:38:05 
+0000
+++ b/libcore/asobj/flash/display/SWFVersion_as.cpp     2009-08-18 11:02:07 
+0000
@@ -43,12 +43,7 @@
 void
 swfversion_class_init(as_object& where, const ObjectURI& uri)
 {
-    Global_as* gl = getGlobal(where);
-    as_object* proto = getObjectInterface();
-    as_object* o = gl->createObject(proto);
-    attachSWFVersionStaticInterface(*o);
-    where.init_member(getName(uri), o, as_object::DefaultFlags,
-            getNamespace(uri));
+    registerBuiltinObject(where, attachSWFVersionStaticInterface, uri);
 }
 
 namespace {

=== modified file 'libcore/asobj/flash/display/SpreadMethod_as.cpp'
--- a/libcore/asobj/flash/display/SpreadMethod_as.cpp   2009-07-31 07:38:05 
+0000
+++ b/libcore/asobj/flash/display/SpreadMethod_as.cpp   2009-08-18 11:07:45 
+0000
@@ -43,12 +43,7 @@
 void
 spreadmethod_class_init(as_object& where, const ObjectURI& uri)
 {
-    Global_as* gl = getGlobal(where);
-    as_object* proto = getObjectInterface();
-    as_object* o = gl->createObject(proto);
-    attachSpreadMethodStaticInterface(*o);
-    where.init_member(getName(uri), o, as_object::DefaultFlags,
-            getNamespace(uri));
+    registerBuiltinObject(where, attachSpreadMethodStaticInterface, uri);
 }
 
 namespace {

=== modified file 'libcore/asobj/flash/display/StageAlign_as.cpp'
--- a/libcore/asobj/flash/display/StageAlign_as.cpp     2009-07-31 07:38:05 
+0000
+++ b/libcore/asobj/flash/display/StageAlign_as.cpp     2009-08-18 11:02:07 
+0000
@@ -43,14 +43,7 @@
 void
 stagealign_class_init(as_object& where, const ObjectURI& uri)
 {
-    Global_as* gl = getGlobal(where);
-    as_object* proto = getObjectInterface();
-    boost::intrusive_ptr<as_object> obj = gl->createObject(proto);
-
-    attachStageAlignStaticInterface(*obj);
-
-    where.init_member(getName(uri), obj.get(), as_object::DefaultFlags,
-            getNamespace(uri));
+    registerBuiltinObject(where, attachStageAlignStaticInterface, uri);
 }
 
 namespace {

=== modified file 'libcore/asobj/flash/display/StageDisplayState_as.cpp'
--- a/libcore/asobj/flash/display/StageDisplayState_as.cpp      2009-07-29 
05:31:28 +0000
+++ b/libcore/asobj/flash/display/StageDisplayState_as.cpp      2009-08-18 
10:55:56 +0000
@@ -41,14 +41,7 @@
 void
 stagedisplaystate_class_init(as_object& where, const ObjectURI& uri)
 {
-    Global_as* gl = getGlobal(where);
-    as_object* proto = getObjectInterface();
-    static boost::intrusive_ptr<as_object> obj =
-        gl->createObject(proto);
-
-    attachStageDisplayStateStaticInterface(*obj);
-    where.init_member(getName(uri), obj.get(), as_object::DefaultFlags,
-            getNamespace(uri));
+    registerBuiltinObject(where, attachStageDisplayStateStaticInterface, uri);
 }
 
 namespace {

=== modified file 'libcore/asobj/flash/display/StageQuality_as.cpp'
--- a/libcore/asobj/flash/display/StageQuality_as.cpp   2009-07-29 05:31:28 
+0000
+++ b/libcore/asobj/flash/display/StageQuality_as.cpp   2009-08-18 11:02:07 
+0000
@@ -40,14 +40,7 @@
 void
 stagequality_class_init(as_object& where, const ObjectURI& uri)
 {
-    Global_as* gl = getGlobal(where);
-    as_object* proto = getObjectInterface();
-    static boost::intrusive_ptr<as_object> obj =
-        gl->createObject(proto);
-
-    attachStageQualityStaticInterface(*obj);
-    where.init_member(getName(uri), obj.get(), as_object::DefaultFlags,
-            getNamespace(uri));
+    registerBuiltinObject(where, attachStageQualityStaticInterface, uri);
 }
 
 namespace {

=== modified file 'libcore/asobj/flash/display/StageScaleMode_as.cpp'
--- a/libcore/asobj/flash/display/StageScaleMode_as.cpp 2009-07-16 09:37:37 
+0000
+++ b/libcore/asobj/flash/display/StageScaleMode_as.cpp 2009-08-18 11:02:07 
+0000
@@ -41,11 +41,7 @@
 void
 stagescalemode_class_init(as_object& where, const ObjectURI& uri)
 {
-    boost::intrusive_ptr<as_object> obj = new as_object(getObjectInterface());
-    attachStageScaleModeStaticInterface(*obj);
-
-    where.init_member(getName(uri), obj.get(), as_object::DefaultFlags,
-            getNamespace(uri));
+    registerBuiltinObject(where, attachStageScaleModeStaticInterface, uri);
 }
 
 

=== modified file 'libcore/asobj/flash/display/Stage_as.cpp'
--- a/libcore/asobj/flash/display/Stage_as.cpp  2009-07-28 11:58:27 +0000
+++ b/libcore/asobj/flash/display/Stage_as.cpp  2009-08-18 10:55:56 +0000
@@ -29,6 +29,7 @@
 #include "Global_as.h"
 #include "smart_ptr.h" // for boost intrusive_ptr
 #include "builtin_function.h" // need builtin_function
+#include "NativeFunction.h" // for ActionException
 #include "VM.h"
 #include "Object.h" // for getObjectInterface()
 #include "AsBroadcaster.h" // for initializing self as a broadcaster
@@ -67,10 +68,6 @@
 static void
 attachStageInterface(as_object& o)
 {
-    const int version = getSWFVersion(o);
-
-    if ( version < 5 ) return;
-
     o.init_property("scaleMode", &stage_scalemode, &stage_scalemode);
     o.init_property("align", &stage_align, &stage_align);
     o.init_property("width", &stage_width, &stage_width);
@@ -81,38 +78,6 @@
 }
 
 
-Stage_as::Stage_as()
-       :
-       as_object(getObjectInterface())
-{
-       attachStageInterface(*this);
-
-       const int swfversion = getSWFVersion(*this);
-       if ( swfversion > 5 )
-       {
-               AsBroadcaster::initialize(*this);
-       }
-}
-
-
-void
-Stage_as::notifyFullScreen(bool fs)
-{
-    // Should we notify resize here, or does movie_root do it anyway
-    // when the gui changes size?
-       log_debug("notifying Stage listeners about fullscreen state");
-       callMethod(NSV::PROP_BROADCAST_MESSAGE, "onFullScreen", fs);
-}
-
-
-void
-Stage_as::notifyResize()
-{
-       log_debug("notifying Stage listeners about a resize");
-       callMethod(NSV::PROP_BROADCAST_MESSAGE, "onResize");
-}
-
-
 const char*
 getDisplayStateString(movie_root::DisplayState ds)
 {
@@ -257,19 +222,17 @@
 
     movie_root& m = getRoot(fn);
 
-       if ( fn.nargs == 0 ) // getter
-       {
+       if (!fn.nargs) {
                return as_value(m.getShowMenuState());
        }
-       else // setter
-       {
-               LOG_ONCE(log_unimpl("Stage.showMenu implemented by setting 
gnashrc option and for gtk only"));
-
-               bool state = fn.arg(0).to_bool();
-               
-               m.setShowMenuState( state );
-               return as_value();
-       }
+
+    LOG_ONCE(log_unimpl("Stage.showMenu implemented by setting gnashrc "
+                "option and for gtk only"));
+
+    bool state = fn.arg(0).to_bool();
+    
+    m.setShowMenuState(state);
+    return as_value();
 }
 
 as_value
@@ -298,11 +261,11 @@
 }
 
 // extern (used by Global.cpp)
-void stage_class_init(as_object& where, const ObjectURI& uri)
+void
+stage_class_init(as_object& where, const ObjectURI& uri)
 {
-       static boost::intrusive_ptr<as_object> obj = new Stage_as();
-       where.init_member(getName(uri), obj.get(), as_object::DefaultFlags,
-            getNamespace(uri));
+    as_object* obj = registerBuiltinObject(where, attachStageInterface, uri);
+    AsBroadcaster::initialize(*obj);
 }
 
 } // end of gnash namespace

=== modified file 'libcore/asobj/flash/display/Stage_as.h'
--- a/libcore/asobj/flash/display/Stage_as.h    2009-07-28 11:58:27 +0000
+++ b/libcore/asobj/flash/display/Stage_as.h    2009-08-17 11:47:12 +0000
@@ -43,20 +43,6 @@
 /// appear to need this (not ASnative). The ASnative functions
 /// are available from SWF5
 
-class Stage_as: public as_object
-{
-
-public:
-    
-       Stage_as();
-       
-       /// Notify all listeners about a resize event
-       void notifyResize();
-       
-       void notifyFullScreen(bool fs);
-
-};
-
 /// Register native functions with the VM.
 void registerStageNative(as_object& o);
 

=== modified file 'libcore/asobj/flash/external/ExternalInterface_as.cpp'
--- a/libcore/asobj/flash/external/ExternalInterface_as.cpp     2009-07-29 
05:59:24 +0000
+++ b/libcore/asobj/flash/external/ExternalInterface_as.cpp     2009-08-18 
10:05:43 +0000
@@ -36,38 +36,53 @@
 
 namespace gnash {
 
-static as_value ExternalInterface_addCallback(const fn_call& fn);
-static as_value ExternalInterface_call(const fn_call& fn);
-static as_value ExternalInterface_uArgumentsToXML(const fn_call& fn);
-static as_value ExternalInterface_uArgumentsToAS(const fn_call& fn);
-static as_value ExternalInterface_uAddCallback(const fn_call& fn);
-static as_value ExternalInterface_uArrayToAS(const fn_call& fn);
-static as_value ExternalInterface_uArrayToJS(const fn_call& fn);
-static as_value ExternalInterface_uArrayToXML(const fn_call& fn);
-static as_value ExternalInterface_uCallIn(const fn_call& fn);
-static as_value ExternalInterface_uCallOut(const fn_call& fn);
-static as_value ExternalInterface_uEscapeXML(const fn_call& fn);
-static as_value ExternalInterface_uEvalJS(const fn_call& fn);
-static as_value ExternalInterface_uInitJS(const fn_call& fn);
-static as_value ExternalInterface_uJsQuoteString(const fn_call& fn);
-static as_value ExternalInterface_uObjectID(const fn_call& fn);
-static as_value ExternalInterface_uObjectToAS(const fn_call& fn);
-static as_value ExternalInterface_uObjectToJS(const fn_call& fn);
-static as_value ExternalInterface_uObjectToXML(const fn_call& fn);
-static as_value ExternalInterface_uToAS(const fn_call& fn);
-static as_value ExternalInterface_uToJS(const fn_call& fn);
-static as_value ExternalInterface_uToXML(const fn_call& fn);
-static as_value ExternalInterface_uUnescapeXML(const fn_call& fn);
-static as_value ExternalInterface_available(const fn_call& fn);
-
-as_value ExternalInterface_uctor(const fn_call& fn);
-
-static void
+namespace {
+    as_value externalinterface_addCallback(const fn_call& fn);
+    as_value externalinterface_call(const fn_call& fn);
+    as_value externalinterface_uArgumentsToXML(const fn_call& fn);
+    as_value externalinterface_uArgumentsToAS(const fn_call& fn);
+    as_value externalinterface_uAddCallback(const fn_call& fn);
+    as_value externalinterface_uArrayToAS(const fn_call& fn);
+    as_value externalinterface_uArrayToJS(const fn_call& fn);
+    as_value externalinterface_uArrayToXML(const fn_call& fn);
+    as_value externalinterface_uCallIn(const fn_call& fn);
+    as_value externalinterface_uCallOut(const fn_call& fn);
+    as_value externalinterface_uEscapeXML(const fn_call& fn);
+    as_value externalinterface_uEvalJS(const fn_call& fn);
+    as_value externalinterface_uInitJS(const fn_call& fn);
+    as_value externalinterface_uJsQuoteString(const fn_call& fn);
+    as_value externalinterface_uObjectID(const fn_call& fn);
+    as_value externalinterface_uObjectToAS(const fn_call& fn);
+    as_value externalinterface_uObjectToJS(const fn_call& fn);
+    as_value externalinterface_uObjectToXML(const fn_call& fn);
+    as_value externalinterface_uToAS(const fn_call& fn);
+    as_value externalinterface_uToJS(const fn_call& fn);
+    as_value externalinterface_uToXML(const fn_call& fn);
+    as_value externalinterface_uUnescapeXML(const fn_call& fn);
+    as_value externalinterface_available(const fn_call& fn);
+    as_value externalinterface_uctor(const fn_call& fn);
+    as_value externalInterfaceConstructor(const fn_call& fn);
+
+}
+
+// extern 
+void
+externalinterface_class_init(as_object& where, const ObjectURI& uri)
+{
+    // TODO: this may not be correct, but it should be enumerable.
+    const int flags = 0;
+    where.init_destructive_property(getName(uri), externalInterfaceConstructor,
+            flags, getNamespace(uri));
+}
+
+namespace {
+
+void
 attachExternalInterfaceInterface(as_object& /*o*/)
 {
 }
 
-static void
+void
 attachExternalInterfaceStaticProperties(as_object& o)
 {
     const int flags = PropFlags::dontEnum |
@@ -76,304 +91,246 @@
 
     Global_as* gl = getGlobal(o);
     o.init_member("addCallback", gl->createFunction(
-                ExternalInterface_addCallback), flags);
-    o.init_member("call", gl->createFunction(ExternalInterface_call), flags);
+                externalinterface_addCallback), flags);
+    o.init_member("call", gl->createFunction(externalinterface_call), flags);
     o.init_member("_argumentsToXML",
-            gl->createFunction(ExternalInterface_uArgumentsToXML), flags);
+            gl->createFunction(externalinterface_uArgumentsToXML), flags);
     o.init_member("_argumentsToAS",
-            gl->createFunction(ExternalInterface_uArgumentsToAS), flags);
+            gl->createFunction(externalinterface_uArgumentsToAS), flags);
     o.init_member("_addCallback",
-            gl->createFunction(ExternalInterface_uAddCallback), flags);
+            gl->createFunction(externalinterface_uAddCallback), flags);
     o.init_member("_arrayToAS",
-            gl->createFunction(ExternalInterface_uArrayToAS), flags);
+            gl->createFunction(externalinterface_uArrayToAS), flags);
     o.init_member("_arrayToJS",
-            gl->createFunction(ExternalInterface_uArrayToJS), flags);
+            gl->createFunction(externalinterface_uArrayToJS), flags);
     o.init_member("_arrayToXML",
-            gl->createFunction(ExternalInterface_uArrayToXML), flags);
+            gl->createFunction(externalinterface_uArrayToXML), flags);
     o.init_member("_callIn",
-            gl->createFunction(ExternalInterface_uCallIn), flags);
+            gl->createFunction(externalinterface_uCallIn), flags);
     o.init_member("_callOut",
-            gl->createFunction(ExternalInterface_uCallOut), flags);
+            gl->createFunction(externalinterface_uCallOut), flags);
     o.init_member("_escapeXML",
-            gl->createFunction(ExternalInterface_uEscapeXML), flags);
+            gl->createFunction(externalinterface_uEscapeXML), flags);
     o.init_member("_evalJS",
-            gl->createFunction(ExternalInterface_uEvalJS), flags);
+            gl->createFunction(externalinterface_uEvalJS), flags);
     o.init_member("_initJS",
-            gl->createFunction(ExternalInterface_uInitJS), flags);
+            gl->createFunction(externalinterface_uInitJS), flags);
     o.init_member("_jsQuoteString",
-            gl->createFunction(ExternalInterface_uJsQuoteString), flags);
+            gl->createFunction(externalinterface_uJsQuoteString), flags);
     o.init_member("_objectID",
-            gl->createFunction(ExternalInterface_uObjectID), flags);
+            gl->createFunction(externalinterface_uObjectID), flags);
     o.init_member("_objectToAS",
-            gl->createFunction(ExternalInterface_uObjectToAS), flags);
+            gl->createFunction(externalinterface_uObjectToAS), flags);
     o.init_member("_objectToJS",
-            gl->createFunction(ExternalInterface_uObjectToJS), flags);
+            gl->createFunction(externalinterface_uObjectToJS), flags);
     o.init_member("_objectToXML",
-            gl->createFunction(ExternalInterface_uObjectToXML), flags);
+            gl->createFunction(externalinterface_uObjectToXML), flags);
     o.init_member("_toAS",
-            gl->createFunction(ExternalInterface_uToAS), flags);
+            gl->createFunction(externalinterface_uToAS), flags);
     o.init_member("_toJS",
-            gl->createFunction(ExternalInterface_uToJS), flags);
+            gl->createFunction(externalinterface_uToJS), flags);
     o.init_member("_toXML",
-            gl->createFunction(ExternalInterface_uToXML), flags);
+            gl->createFunction(externalinterface_uToXML), flags);
     o.init_member("_unescapeXML",
-            gl->createFunction(ExternalInterface_uUnescapeXML), flags);
+            gl->createFunction(externalinterface_uUnescapeXML), flags);
 
     int protectedFlags = PropFlags::dontEnum |
                          PropFlags::dontDelete |
                          PropFlags::isProtected;
 
     o.init_member("available",
-            gl->createFunction(ExternalInterface_available), protectedFlags);
-}
-
-static as_object*
-getExternalInterfaceInterface()
-{
-       static boost::intrusive_ptr<as_object> o;
-
-       if ( ! o )
-       {
-               // TODO: check if this class should inherit from Object
-               //       or from a different class
-               o = new as_object(getObjectInterface());
-               VM::get().addStatic(o.get());
-
-               attachExternalInterfaceInterface(*o);
-
-       }
-
-       return o.get();
-}
-
-class ExternalInterface_as: public as_object
-{
-
-public:
-
-       ExternalInterface_as()
-               :
-               as_object(getExternalInterfaceInterface())
-       {}
-
-       // override from as_object ?
-       //std::string get_text_value() const { return "ExternalInterface"; }
-
-       // override from as_object ?
-       //double get_numeric_value() const { return 0; }
-};
-
-
-
-static as_value
-ExternalInterface_addCallback(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-static as_value
-ExternalInterface_call(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-as_value
-ExternalInterface_uArgumentsToXML(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-as_value
-ExternalInterface_uArgumentsToAS(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-as_value
-ExternalInterface_uAddCallback(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-as_value
-ExternalInterface_uArrayToAS(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-as_value
-ExternalInterface_uArrayToJS(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-as_value
-ExternalInterface_uArrayToXML(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-as_value
-ExternalInterface_uCallIn(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-as_value
-ExternalInterface_uCallOut(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-as_value
-ExternalInterface_uEscapeXML(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-as_value
-ExternalInterface_uEvalJS(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-as_value
-ExternalInterface_uInitJS(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-as_value
-ExternalInterface_uJsQuoteString(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-as_value
-ExternalInterface_uObjectID(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-as_value
-ExternalInterface_uObjectToAS(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-as_value
-ExternalInterface_uObjectToJS(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-as_value
-ExternalInterface_uObjectToXML(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-as_value
-ExternalInterface_uToAS(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-as_value
-ExternalInterface_uToJS(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-as_value
-ExternalInterface_uToXML(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-as_value
-ExternalInterface_uUnescapeXML(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-as_value
-ExternalInterface_available(const fn_call& /*fn*/)
-{
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
-       return as_value();
-}
-
-
-as_value
-ExternalInterface_ctor(const fn_call& fn)
-{
-       boost::intrusive_ptr<as_object> obj = new ExternalInterface_as;
-
-       if ( fn.nargs )
-       {
+            gl->createFunction(externalinterface_available), protectedFlags);
+}
+
+
+as_value
+externalinterface_addCallback(const fn_call& /*fn*/)
+{
+       LOG_ONCE( log_unimpl (__FUNCTION__) );
+       return as_value();
+}
+
+as_value
+externalinterface_call(const fn_call& /*fn*/)
+{
+       LOG_ONCE( log_unimpl (__FUNCTION__) );
+       return as_value();
+}
+
+as_value
+externalinterface_uArgumentsToXML(const fn_call& /*fn*/)
+{
+       LOG_ONCE( log_unimpl (__FUNCTION__) );
+       return as_value();
+}
+
+as_value
+externalinterface_uArgumentsToAS(const fn_call& /*fn*/)
+{
+       LOG_ONCE( log_unimpl (__FUNCTION__) );
+       return as_value();
+}
+
+as_value
+externalinterface_uAddCallback(const fn_call& /*fn*/)
+{
+       LOG_ONCE( log_unimpl (__FUNCTION__) );
+       return as_value();
+}
+
+as_value
+externalinterface_uArrayToAS(const fn_call& /*fn*/)
+{
+       LOG_ONCE( log_unimpl (__FUNCTION__) );
+       return as_value();
+}
+
+as_value
+externalinterface_uArrayToJS(const fn_call& /*fn*/)
+{
+       LOG_ONCE( log_unimpl (__FUNCTION__) );
+       return as_value();
+}
+
+as_value
+externalinterface_uArrayToXML(const fn_call& /*fn*/)
+{
+       LOG_ONCE( log_unimpl (__FUNCTION__) );
+       return as_value();
+}
+
+as_value
+externalinterface_uCallIn(const fn_call& /*fn*/)
+{
+       LOG_ONCE( log_unimpl (__FUNCTION__) );
+       return as_value();
+}
+
+as_value
+externalinterface_uCallOut(const fn_call& /*fn*/)
+{
+       LOG_ONCE( log_unimpl (__FUNCTION__) );
+       return as_value();
+}
+
+as_value
+externalinterface_uEscapeXML(const fn_call& /*fn*/)
+{
+       LOG_ONCE( log_unimpl (__FUNCTION__) );
+       return as_value();
+}
+
+as_value
+externalinterface_uEvalJS(const fn_call& /*fn*/)
+{
+       LOG_ONCE( log_unimpl (__FUNCTION__) );
+       return as_value();
+}
+
+as_value
+externalinterface_uInitJS(const fn_call& /*fn*/)
+{
+       LOG_ONCE( log_unimpl (__FUNCTION__) );
+       return as_value();
+}
+
+as_value
+externalinterface_uJsQuoteString(const fn_call& /*fn*/)
+{
+       LOG_ONCE( log_unimpl (__FUNCTION__) );
+       return as_value();
+}
+
+as_value
+externalinterface_uObjectID(const fn_call& /*fn*/)
+{
+       LOG_ONCE( log_unimpl (__FUNCTION__) );
+       return as_value();
+}
+
+as_value
+externalinterface_uObjectToAS(const fn_call& /*fn*/)
+{
+       LOG_ONCE( log_unimpl (__FUNCTION__) );
+       return as_value();
+}
+
+as_value
+externalinterface_uObjectToJS(const fn_call& /*fn*/)
+{
+       LOG_ONCE( log_unimpl (__FUNCTION__) );
+       return as_value();
+}
+
+as_value
+externalinterface_uObjectToXML(const fn_call& /*fn*/)
+{
+       LOG_ONCE( log_unimpl (__FUNCTION__) );
+       return as_value();
+}
+
+as_value
+externalinterface_uToAS(const fn_call& /*fn*/)
+{
+       LOG_ONCE( log_unimpl (__FUNCTION__) );
+       return as_value();
+}
+
+as_value
+externalinterface_uToJS(const fn_call& /*fn*/)
+{
+       LOG_ONCE( log_unimpl (__FUNCTION__) );
+       return as_value();
+}
+
+as_value
+externalinterface_uToXML(const fn_call& /*fn*/)
+{
+       LOG_ONCE( log_unimpl (__FUNCTION__) );
+       return as_value();
+}
+
+as_value
+externalinterface_uUnescapeXML(const fn_call& /*fn*/)
+{
+       LOG_ONCE( log_unimpl (__FUNCTION__) );
+       return as_value();
+}
+
+as_value
+externalinterface_available(const fn_call& /*fn*/)
+{
+       LOG_ONCE( log_unimpl (__FUNCTION__) );
+       return as_value();
+}
+
+
+as_value
+externalinterface_ctor(const fn_call& fn)
+{
+       if (fn.nargs) {
                std::stringstream ss;
                fn.dump_args(ss);
-               LOG_ONCE( log_unimpl("ExternalInterface(%s): %s", ss.str(), 
_("arguments discarded")) );
+               LOG_ONCE(log_unimpl("ExternalInterface(%s): %s", ss.str(),
+                    _("arguments discarded")) );
        }
 
-       return as_value(obj.get()); // will keep alive
+       return as_value(); 
 }
 
-as_object*
-getFlashExternalExternalInterfaceConstructor(Global_as& global)
+as_value
+externalInterfaceConstructor(const fn_call& fn)
 {
-    static as_object* cl=NULL;
-    if ( ! cl )
-    {
-        as_object* proto = getExternalInterfaceInterface();
-        cl = global.createClass(&ExternalInterface_ctor, proto);
-        VM::get().addStatic(cl);
-           attachExternalInterfaceStaticProperties(*cl);
-    }
+    log_debug("Loading flash.external.ExternalInterface class");
+    Global_as* gl = getGlobal(fn);
+    as_object* proto = gl->createObject(getObjectInterface());
+    as_object* cl = gl->createClass(&externalinterface_ctor, proto);
+
+    attachExternalInterfaceInterface(*proto);
+    attachExternalInterfaceStaticProperties(*cl);
     return cl;
 }
 
-
-static as_value
-get_flash_external_external_interface_constructor(const fn_call& fn)
-{
-    log_debug("Loading flash.external.ExternalInterface class");
-    return 
getFlashExternalExternalInterfaceConstructor(*getVM(fn).getGlobal());
-}
-
-
-// extern 
-void externalinterface_class_init(as_object& where, const ObjectURI& uri)
-{
-    // TODO: this may not be correct, but it should be enumerable.
-    const int flags = 0;
-    where.init_destructive_property(getName(uri),
-            get_flash_external_external_interface_constructor, flags,
-            getNamespace(uri));
-}
-
+}
 
 } // end of gnash namespace

=== modified file 'libcore/asobj/flash/filters/BitmapFilterQuality_as.cpp'
--- a/libcore/asobj/flash/filters/BitmapFilterQuality_as.cpp    2009-07-28 
11:58:27 +0000
+++ b/libcore/asobj/flash/filters/BitmapFilterQuality_as.cpp    2009-08-18 
11:07:45 +0000
@@ -41,12 +41,7 @@
 // extern (used by Global.cpp)
 void bitmapfilterquality_class_init(as_object& where, const ObjectURI& uri)
 {
-    boost::intrusive_ptr<as_object> cl = new as_object(getObjectInterface());
-    attachBitmapFilterQualityStaticInterface(*cl);
-
-    // Register _global.BitmapFilterQuality
-    where.init_member(getName(uri), cl.get(), as_object::DefaultFlags,
-            getNamespace(uri));
+    registerBuiltinObject(where, attachBitmapFilterQualityStaticInterface, 
uri);
 }
 
 namespace {

=== modified file 'libcore/asobj/flash/filters/DisplacementMapFilterMode_as.cpp'
--- a/libcore/asobj/flash/filters/DisplacementMapFilterMode_as.cpp      
2009-07-28 11:58:27 +0000
+++ b/libcore/asobj/flash/filters/DisplacementMapFilterMode_as.cpp      
2009-08-18 11:07:45 +0000
@@ -39,14 +39,11 @@
 }
 
 // extern (used by Global.cpp)
-void displacementmapfiltermode_class_init(as_object& where, const ObjectURI& 
uri)
+void displacementmapfiltermode_class_init(as_object& where,
+        const ObjectURI& uri)
 {
-    boost::intrusive_ptr<as_object> cl = new as_object(getObjectInterface());
-    attachDisplacementMapFilterModeStaticInterface(*cl);
-
-    // Register _global.DisplacementMapFilterMode
-    where.init_member(getName(uri), cl.get(), as_object::DefaultFlags,
-            getNamespace(uri));
+    registerBuiltinObject(where, 
attachDisplacementMapFilterModeStaticInterface,
+            uri);
 }
 
 namespace {

=== modified file 'libcore/asobj/flash/media/Camera_as.cpp'
--- a/libcore/asobj/flash/media/Camera_as.cpp   2009-08-12 15:25:48 +0000
+++ b/libcore/asobj/flash/media/Camera_as.cpp   2009-08-18 08:36:49 +0000
@@ -661,11 +661,9 @@
 }
 
 as_value
-camera_new(const fn_call& fn)
+camera_new(const fn_call& /*fn*/)
 {
-    as_object* proto = getCameraInterface();
-    Global_as* gl = getGlobal(fn);
-    return gl->createObject(proto);
+    return as_value();
 }
 
 as_value

=== modified file 'libcore/asobj/flash/media/Microphone_as.cpp'
--- a/libcore/asobj/flash/media/Microphone_as.cpp       2009-08-13 06:28:16 
+0000
+++ b/libcore/asobj/flash/media/Microphone_as.cpp       2009-08-18 11:17:30 
+0000
@@ -177,11 +177,9 @@
 // There is a constructor for Microphone that returns an object with
 // the correct properties, but it is not usable.
 as_value
-microphone_ctor(const fn_call& fn)
+microphone_ctor(const fn_call& /*fn*/)
 {
-    Global_as* gl = getGlobal(fn);
-    as_object* proto = getMicrophoneInterface();
-    return gl->createObject(proto);
+    return as_value();
 }
 
 // AS2 static accessor.
@@ -206,12 +204,8 @@
 as_value
 microphone_getMicrophone(const fn_call& fn)
 {
-    boost::intrusive_ptr<microphone_as_object> ptr;
-    try {
-        ptr = ensureType<microphone_as_object> (fn.this_ptr);
-    } catch (ActionTypeError& e) {
-        ptr = new microphone_as_object;
-    }
+    boost::intrusive_ptr<microphone_as_object> ptr
+        = ensureType<microphone_as_object> (fn.this_ptr);
     int numargs = fn.nargs;
     if (numargs > 0) {
         log_debug("%s: the mic is automatically chosen from gnashrc", 
__FUNCTION__);
@@ -223,14 +217,8 @@
 as_value 
 microphone_setgain(const fn_call& fn)
 {
-    boost::intrusive_ptr<microphone_as_object> ptr;
-    try {
-        ptr = ensureType<microphone_as_object> (fn.this_ptr);
-    } catch (ActionTypeError& e) {
-        log_error("%s: you must first initialize the microphone before setting 
vals",
-            __FUNCTION__);
-        return as_value();
-    }
+    boost::intrusive_ptr<microphone_as_object> ptr =
+        ensureType<microphone_as_object> (fn.this_ptr);
     
     int numargs = fn.nargs;
     if (numargs != 1) {
@@ -279,14 +267,8 @@
 as_value
 microphone_setrate(const fn_call& fn)
 {
-    boost::intrusive_ptr<microphone_as_object> ptr;
-    try {
-        ptr = ensureType<microphone_as_object> (fn.this_ptr);
-    } catch (ActionTypeError& e) {
-        log_error("%s: you must first initialize the microphone before setting 
vals",
-            __FUNCTION__);
-        return as_value();
-    }
+    boost::intrusive_ptr<microphone_as_object> ptr =
+        ensureType<microphone_as_object> (fn.this_ptr);
     
     int numargs = fn.nargs;
     const int32_t argument = fn.arg(0).to_int();
@@ -325,15 +307,10 @@
 }
 
 as_value
-microphone_activityLevel(const fn_call& fn) {
-    boost::intrusive_ptr<microphone_as_object> ptr;
-    try {
-        ptr = ensureType<microphone_as_object> (fn.this_ptr);
-    } catch (ActionTypeError& e) {
-        log_error("%s: microphone object not yet initialized, call new",
-            __FUNCTION__);
-        return as_value();
-    }
+microphone_activityLevel(const fn_call& fn)
+{
+    boost::intrusive_ptr<microphone_as_object> ptr =
+        ensureType<microphone_as_object> (fn.this_ptr);
         
     if ( fn.nargs == 0 ) // getter
     {
@@ -351,15 +328,10 @@
 }
 
 as_value
-microphone_gain(const fn_call& fn) {
-    boost::intrusive_ptr<microphone_as_object> ptr;
-    try {
-        ptr = ensureType<microphone_as_object> (fn.this_ptr);
-    } catch (ActionTypeError& e) {
-        log_error("%s: microphone object not yet initialized, call new",
-            __FUNCTION__);
-        return as_value();
-    }
+microphone_gain(const fn_call& fn)
+{
+    boost::intrusive_ptr<microphone_as_object> ptr =
+        ensureType<microphone_as_object> (fn.this_ptr);
         
     if ( fn.nargs == 0 ) // getter
     {
@@ -387,16 +359,11 @@
 }
 
 as_value
-microphone_index(const fn_call& fn) {
-    boost::intrusive_ptr<microphone_as_object> ptr;
-    try {
-        ptr = ensureType<microphone_as_object> (fn.this_ptr);
-    } catch (ActionTypeError& e) {
-        log_error("%s: microphone object not yet initialized, call new",
-            __FUNCTION__);
-        return as_value();
-    };
-        
+microphone_index(const fn_call& fn)
+{
+    boost::intrusive_ptr<microphone_as_object> ptr =
+        ensureType<microphone_as_object> (fn.this_ptr);
+    
     if ( fn.nargs == 0 ) // getter
     {
         return as_value(ptr->get_index());
@@ -414,14 +381,9 @@
 as_value
 microphone_muted(const fn_call& fn)
 {
-    boost::intrusive_ptr<microphone_as_object> ptr;
-    try {
-        ptr = ensureType<microphone_as_object> (fn.this_ptr);
-    } catch (ActionTypeError& e) {
-        log_error("%s: microphone object not yet initialized, call new",
-            __FUNCTION__);
-        return as_value();
-    }
+    boost::intrusive_ptr<microphone_as_object> ptr =
+        ensureType<microphone_as_object> (fn.this_ptr);
+    
     if ( fn.nargs == 0 ) // getter
     {
         log_unimpl("Microphone::muted is always false (always allows access)");
@@ -440,14 +402,8 @@
 as_value
 microphone_name(const fn_call& fn)
 {
-    boost::intrusive_ptr<microphone_as_object> ptr;
-    try {
-        ptr = ensureType<microphone_as_object> (fn.this_ptr);
-    } catch (ActionTypeError& e) {
-        log_error("%s: microphone object not yet initialized, call new",
-            __FUNCTION__);
-        return as_value();
-    }
+    boost::intrusive_ptr<microphone_as_object> ptr =
+        ensureType<microphone_as_object> (fn.this_ptr);
         
     if ( fn.nargs == 0 ) // getter
     {
@@ -504,14 +460,8 @@
 as_value
 microphone_rate(const fn_call& fn)
 {
-    boost::intrusive_ptr<microphone_as_object> ptr;
-    try {
-        ptr = ensureType<microphone_as_object> (fn.this_ptr);
-    } catch (ActionTypeError& e) {
-        log_error("%s: microphone object not yet initialized, call new",
-            __FUNCTION__);
-        return as_value();
-    }
+    boost::intrusive_ptr<microphone_as_object> ptr =
+        ensureType<microphone_as_object> (fn.this_ptr);
     
     if ( fn.nargs == 0 ) // getter
     {
@@ -533,16 +483,11 @@
 }
 
 as_value
-microphone_silenceLevel(const fn_call& fn) {
-    boost::intrusive_ptr<microphone_as_object> ptr;
-    try {
-        ptr = ensureType<microphone_as_object> (fn.this_ptr);
-    } catch (ActionTypeError& e) {
-        log_error("%s: microphone object not yet initialized, call new",
-            __FUNCTION__);
-        return as_value();
-    }
-        
+microphone_silenceLevel(const fn_call& fn)
+{
+    boost::intrusive_ptr<microphone_as_object> ptr =
+        ensureType<microphone_as_object> (fn.this_ptr);
+
     if ( fn.nargs == 0 ) // getter
     {
         log_unimpl("Microphone::silenceLevel can be set, but is 
unimplemented");
@@ -561,14 +506,8 @@
 as_value
 microphone_silenceTimeout(const fn_call& fn)
 {
-    boost::intrusive_ptr<microphone_as_object> ptr;
-    try {
-        ptr = ensureType<microphone_as_object> (fn.this_ptr);
-    } catch (ActionTypeError& e) {
-        log_error("%s: microphone object not yet initialized, call new",
-            __FUNCTION__);
-        return as_value();
-    }
+    boost::intrusive_ptr<microphone_as_object> ptr =
+        ensureType<microphone_as_object> (fn.this_ptr);
         
     if ( fn.nargs == 0 ) // getter
     {
@@ -588,14 +527,9 @@
 as_value
 microphone_useEchoSuppression(const fn_call& fn)
 {
-    boost::intrusive_ptr<microphone_as_object> ptr;
-    try {
-        ptr = ensureType<microphone_as_object> (fn.this_ptr);
-    } catch (ActionTypeError& e) {
-        log_error("%s: microphone object not yet initialized, call new",
-            __FUNCTION__);
-        return as_value();
-    }
+    boost::intrusive_ptr<microphone_as_object> ptr =
+        ensureType<microphone_as_object> (fn.this_ptr);
+    
     if ( fn.nargs == 0 ) // getter
     {
         log_unimpl("Microphone::useEchoSuppression can be set, but is "
@@ -614,16 +548,13 @@
 
 
 as_value
-microphone_setsilencelevel(const fn_call& fn) {
-    log_unimpl ("Microphone::setSilenceLevel can be set, but it's not 
implemented");
-    boost::intrusive_ptr<microphone_as_object> ptr;
-    try {
-        ptr = ensureType<microphone_as_object> (fn.this_ptr);
-    } catch (ActionTypeError& e) {
-        log_error("%s: can't set values until you have a new microphone 
object",
-            __FUNCTION__);
-        return as_value();
-    }
+microphone_setsilencelevel(const fn_call& fn)
+{
+    log_unimpl ("Microphone::setSilenceLevel can be set, but it's not "
+            "implemented");
+
+    boost::intrusive_ptr<microphone_as_object> ptr =
+        ensureType<microphone_as_object> (fn.this_ptr);
     
     int numargs = fn.nargs;
     if (numargs > 2) {
@@ -670,16 +601,11 @@
 as_value 
 microphone_setuseechosuppression(const fn_call& fn)
 {
-    log_unimpl ("Microphone::setUseEchoSuppression can be set, but it's not 
implemented");
-    boost::intrusive_ptr<microphone_as_object> ptr;
-    try {
-        ptr = ensureType<microphone_as_object> (fn.this_ptr);
-    } catch (ActionTypeError& e) {
-        log_error("%s: can't set values until you create a new microphone 
object",
-            __FUNCTION__);
-        return as_value();
-    }
-        
+    log_unimpl ("Microphone::setUseEchoSuppression can be set, but it's not "
+            "implemented");
+    boost::intrusive_ptr<microphone_as_object> ptr =
+        ensureType<microphone_as_object> (fn.this_ptr);
+    
     int numargs = fn.nargs;
     if (numargs > 1) {
         log_error("%s: Too many arguments", __FUNCTION__);

=== modified file 'libcore/asobj/flash/media/Sound_as.cpp'
--- a/libcore/asobj/flash/media/Sound_as.cpp    2009-07-28 11:58:27 +0000
+++ b/libcore/asobj/flash/media/Sound_as.cpp    2009-08-18 10:32:14 +0000
@@ -118,19 +118,13 @@
 Sound_as::init(as_object& where, const ObjectURI& uri)
 {
 
-    // This is going to be the global Sound "class"/"function"
-    static boost::intrusive_ptr<as_object> cl;
-
-    if ( cl == NULL )
-    {
-        as_object* iface = getSoundInterface();
-        Global_as* gl = getGlobal(where);
-        cl = gl->createClass(&sound_new, iface);
-        iface->set_member_flags(NSV::PROP_CONSTRUCTOR, PropFlags::readOnly);
-    }
+    as_object* iface = getSoundInterface();
+    Global_as* gl = getGlobal(where);
+    as_object* cl = gl->createClass(&sound_new, iface);
+    iface->set_member_flags(NSV::PROP_CONSTRUCTOR, PropFlags::readOnly);
 
     // Register _global.String
-    where.init_member(getName(uri), cl.get(), as_object::DefaultFlags,
+    where.init_member(getName(uri), cl, as_object::DefaultFlags,
             getNamespace(uri));
 
 }

=== modified file 'libcore/asobj/flash/net/LocalConnection_as.cpp'
--- a/libcore/asobj/flash/net/LocalConnection_as.cpp    2009-07-24 21:15:27 
+0000
+++ b/libcore/asobj/flash/net/LocalConnection_as.cpp    2009-08-18 09:38:13 
+0000
@@ -104,8 +104,8 @@
     _domain(getDomain())
 {
     log_debug("The domain for this host is: %s", _domain);
-       setconnected(false);
-       
+    setconnected(false);
+    
 }
 
 LocalConnection_as::~LocalConnection_as()
@@ -207,21 +207,12 @@
 void
 LocalConnection_as::init(as_object& glob, const ObjectURI& uri)
 {
-       // This is going to be the global Number "class"/"function"
-       static as_object* cl = NULL;
-
-       if ( cl == NULL )
-       {
-        Global_as* gl = getGlobal(glob);
-               cl = gl->createClass(&localconnection_new,
-                getLocalConnectionInterface());
-
-        // FIXME: why do we need to register ourself here ?
-               VM::get().addStatic(cl);
-       }
-
-
-       int swf6flags = PropFlags::dontEnum | 
+    // This is going to be the global Number "class"/"function"
+    Global_as* gl = getGlobal(glob);
+    as_object* proto = getLocalConnectionInterface();
+    as_object* cl = gl->createClass(&localconnection_new, proto);
+
+    int swf6flags = PropFlags::dontEnum | 
                     PropFlags::dontDelete | 
                     PropFlags::onlySWF6Up;
 
@@ -279,16 +270,16 @@
         return as_value(false);
     }
     
-       std::string connection_name;
-       //connection_name=fn.arg(0).to_string();
-       //log_debug("The arg(0) is: %s", connection_name);
-       
+    std::string connection_name;
+    //connection_name=fn.arg(0).to_string();
+    //log_debug("The arg(0) is: %s", connection_name);
+    
     if (fn.arg(0).to_string()=="") {
         return as_value(false);
     }
-               connection_name = ptr->domain();        
-       connection_name +=":";
-       connection_name += fn.arg(0).to_string();
+           connection_name = ptr->domain();    
+        connection_name +=":";
+        connection_name += fn.arg(0).to_string();
    
     ptr->connect(connection_name);
 
@@ -318,7 +309,7 @@
     // At least 2 args (connection name, function) required.
 
    log_debug(_("The number of args is %d \n"), fn.nargs) ;
-        
+     
     if (fn.nargs < 2) {
         IF_VERBOSE_ASCODING_ERRORS(
             std::ostringstream os;
@@ -327,7 +318,7 @@
                     "arguments"), os.str());
         );
         return as_value(false);
-               
+        
     }
 
     // Both the first two arguments must be a string
@@ -356,18 +347,18 @@
 //Si added
     int numarg=fn.nargs;
     for (int i=0; i!=numarg; i++)
-               log_debug(_(" *** The value of the arg[ %d ] : %s 
***"),i,fn.arg(i).to_string() ); 
-       
-       const std::string & connectionName= fn.arg(0).to_string();
-       const std::string & methodName=     fn.arg(1).to_string();
-               
-       std::vector< amf::Element * >  argument_to_send;
-       
-       for (int i=2; i!=numarg; i++){
-               amf::Element* temp_ptr = fn.arg(i).to_element().get();
-               argument_to_send.push_back(temp_ptr);
-       }
-       
+        log_debug(_(" *** The value of the arg[ %d ] : %s 
***"),i,fn.arg(i).to_string() ); 
+    
+    const std::string & connectionName= fn.arg(0).to_string();
+    const std::string & methodName=     fn.arg(1).to_string();
+        
+    std::vector< amf::Element * >  argument_to_send;
+    
+    for (int i=2; i!=numarg; i++){
+        amf::Element* temp_ptr = fn.arg(i).to_element().get();
+        argument_to_send.push_back(temp_ptr);
+    }
+    
     ptr->amf::LcShm::send(connectionName,methodName,argument_to_send);
 //end of Si added
 
@@ -410,7 +401,7 @@
     if ( o == NULL )
     {
         o = new as_object(getObjectInterface());
-           VM::get().addStatic(o.get());
+        VM::get().addStatic(o.get());
 
         attachLocalConnectionInterface(*o);
     }

=== modified file 'libcore/asobj/flash/net/SharedObject_as.cpp'
--- a/libcore/asobj/flash/net/SharedObject_as.cpp       2009-08-10 06:54:44 
+0000
+++ b/libcore/asobj/flash/net/SharedObject_as.cpp       2009-08-18 06:49:40 
+0000
@@ -37,6 +37,7 @@
 #include "fn_call.h"
 #include "Global_as.h"
 #include "builtin_function.h" // need builtin_function
+#include "NativeFunction.h" 
 #include "Object.h" // for getObjectInterface
 #include "VM.h"
 #include "Property.h"

=== modified file 'libcore/asobj/flash/printing/PrintJobOrientation_as.cpp'
--- a/libcore/asobj/flash/printing/PrintJobOrientation_as.cpp   2009-07-31 
07:38:05 +0000
+++ b/libcore/asobj/flash/printing/PrintJobOrientation_as.cpp   2009-08-18 
11:13:25 +0000
@@ -43,12 +43,7 @@
 void
 printjoborientation_class_init(as_object& where, const ObjectURI& uri)
 {
-    Global_as* gl = getGlobal(where);
-    as_object* proto = getObjectInterface();
-    as_object* o = gl->createObject(proto);
-    attachPrintJobOrientationStaticInterface(*o);
-    where.init_member(getName(uri), o, as_object::DefaultFlags,
-            getNamespace(uri));
+    registerBuiltinObject(where, attachPrintJobOrientationStaticInterface, 
uri);
 }
 
 namespace {

=== modified file 'libcore/asobj/flash/system/System_as.cpp'
--- a/libcore/asobj/flash/system/System_as.cpp  2009-07-28 11:58:27 +0000
+++ b/libcore/asobj/flash/system/System_as.cpp  2009-08-18 06:49:40 +0000
@@ -24,6 +24,7 @@
 #include "smart_ptr.h" // for boost intrusive_ptr
 #include "Global_as.h"
 #include "builtin_function.h"
+#include "NativeFunction.h" 
 #include "VM.h" // for getPlayerVersion() 
 #include "Object.h" // for getObjectInterface
 

=== modified file 'libcore/asobj/flash/ui/ContextMenuItem_as.cpp'
--- a/libcore/asobj/flash/ui/ContextMenuItem_as.cpp     2009-07-29 05:59:24 
+0000
+++ b/libcore/asobj/flash/ui/ContextMenuItem_as.cpp     2009-08-18 10:32:14 
+0000
@@ -36,7 +36,6 @@
     as_value contextmenuitem_ctor(const fn_call& fn);
     as_value contextmenuitem_copy(const fn_call& fn);
     void attachContextMenuItemInterface(as_object& o);
-    as_object* getContextMenuItemInterface();
 
 }
 
@@ -44,16 +43,12 @@
 void
 contextmenuitem_class_init(as_object& where, const ObjectURI& uri)
 {
-    static boost::intrusive_ptr<as_object> cl;
-
-    if (!cl) {
-        Global_as* gl = getGlobal(where);
-        as_object* proto = getContextMenuItemInterface();
-        cl = gl->createClass(&contextmenuitem_ctor, proto);
-    }
-
+    Global_as* gl = getGlobal(where);
+    as_object* proto = gl->createObject(getObjectInterface());
+    as_object* cl = gl->createClass(&contextmenuitem_ctor, proto);
+    attachContextMenuItemInterface(*proto);
     // Register _global.ContextMenuItem
-    where.init_member(getName(uri), cl.get(), as_object::DefaultFlags,
+    where.init_member(getName(uri), cl, as_object::DefaultFlags,
             getNamespace(uri));
 }
 
@@ -70,47 +65,34 @@
     o.init_member("copy", gl->createFunction(contextmenuitem_copy), flags);
 }
 
-as_object*
-getContextMenuItemInterface()
-{
-    static boost::intrusive_ptr<as_object> o;
-    if ( ! o ) {
-        o = new as_object(getObjectInterface());
-        attachContextMenuItemInterface(*o);
-        VM::get().addStatic(o.get());
-    }
-    return o.get();
-}
-
 as_value
 contextmenuitem_copy(const fn_call& fn)
 {
     boost::intrusive_ptr<as_object> ptr = ensureType<as_object>(fn.this_ptr);
 
-    as_value caption, separatorBefore, visible, enabled, onSelect;
+    Global_as* gl = getGlobal(fn);
     string_table& st = getStringTable(fn);
 
-    ptr->get_member(st.find("caption"), &caption);
-    ptr->get_member(st.find("separatorBefore"), &separatorBefore);
-    ptr->get_member(st.find("visible"), &visible);
-    ptr->get_member(NSV::PROP_ON_SELECT, &onSelect);
-    ptr->get_member(NSV::PROP_ENABLED, &enabled);
-
-    as_object* c = new as_object(getContextMenuItemInterface());
-    c->set_member(st.find("caption"), caption);
-    c->set_member(st.find("separatorBefore"), separatorBefore);
-    c->set_member(st.find("visible"), visible);
-    c->set_member(NSV::PROP_ON_SELECT, onSelect);
-    c->set_member(NSV::PROP_ENABLED, enabled);
-    
-    return as_value(c);
+    as_function* ctor =
+        gl->getMember(st.find("ContextMenuItem")).to_as_function();
+
+    if (!ctor) return as_value();
+
+    std::auto_ptr<std::vector<as_value> > args(new std::vector<as_value>());
+    args->push_back(ptr->getMember(st.find("caption")));
+    args->push_back(ptr->getMember(NSV::PROP_ON_SELECT));
+    args->push_back(ptr->getMember(st.find("separatorBefore")));
+    args->push_back(ptr->getMember(NSV::PROP_ENABLED));
+    args->push_back(ptr->getMember(st.find("visible")));
+
+    return ctor->constructInstance(fn.env(), args);
 }
 
 
 as_value
 contextmenuitem_ctor(const fn_call& fn)
 {
-    as_object* obj = new as_object(getContextMenuItemInterface());
+    as_object* obj = fn.this_ptr.get();
 
     string_table& st = getStringTable(fn);
 
@@ -121,7 +103,7 @@
     obj->set_member(NSV::PROP_ENABLED, fn.nargs > 3 ? fn.arg(3) : true);
     obj->set_member(st.find("visible"), fn.nargs > 4 ? fn.arg(4) : true);
 
-    return obj; 
+    return as_value(); 
 }
 
 } // anonymous namespace 

=== modified file 'libcore/asobj/flash/ui/ContextMenu_as.cpp'
--- a/libcore/asobj/flash/ui/ContextMenu_as.cpp 2009-07-29 05:40:20 +0000
+++ b/libcore/asobj/flash/ui/ContextMenu_as.cpp 2009-08-18 10:32:14 +0000
@@ -52,16 +52,12 @@
 void
 contextmenu_class_init(as_object& where, const ObjectURI& uri)
 {
-       static boost::intrusive_ptr<as_object> cl;
-
-       if (cl == NULL) {
-        Global_as* gl = getGlobal(where);
-        as_object* proto = getContextMenuInterface();
-        cl = gl->createClass(contextmenu_ctor, proto);
-       }
+    Global_as* gl = getGlobal(where);
+    as_object* proto = getContextMenuInterface();
+    as_object* cl = gl->createClass(contextmenu_ctor, proto);
 
        // Register _global.ContextMenu
-       where.init_member(getName(uri), cl.get(), as_object::DefaultFlags,
+       where.init_member(getName(uri), cl, as_object::DefaultFlags,
             getNamespace(uri));
 }
 

=== modified file 'libcore/asobj/flash/ui/Keyboard_as.cpp'
--- a/libcore/asobj/flash/ui/Keyboard_as.cpp    2009-07-29 13:50:30 +0000
+++ b/libcore/asobj/flash/ui/Keyboard_as.cpp    2009-08-18 06:49:40 +0000
@@ -30,6 +30,7 @@
 #include "action.h" // for call_method
 #include "VM.h" // for registerNative
 #include "builtin_function.h" // need builtin_function
+#include "NativeFunction.h" 
 #include "Object.h"
 #include "AsBroadcaster.h" //for initializing self as a broadcaster
 #include "namedStrings.h"

=== modified file 'libcore/asobj/flash/ui/Mouse_as.cpp'
--- a/libcore/asobj/flash/ui/Mouse_as.cpp       2009-08-11 10:29:44 +0000
+++ b/libcore/asobj/flash/ui/Mouse_as.cpp       2009-08-18 10:55:56 +0000
@@ -24,6 +24,7 @@
 #include "Global_as.h"
 #include "smart_ptr.h" // for boost intrusive_ptr
 #include "builtin_function.h" // need builtin_function
+#include "NativeFunction.h" 
 #include "VM.h" // for registerNative
 #include "Object.h" // for getObjectInterface
 #include "AsBroadcaster.h" // for initializing self as a broadcaster
@@ -56,16 +57,7 @@
 void
 mouse_class_init(as_object& where, const ObjectURI& uri)
 {
-    // This is going to be the global Mouse "class"/"function"
-    Global_as* gl = getGlobal(where);
-    as_object* proto = getObjectInterface();
-    boost::intrusive_ptr<as_object> obj = gl->createObject(proto);
-    attachMouseInterface(*obj);
-
-    // Register _global.Mouse
-    where.init_member(getName(uri), obj.get(), as_object::DefaultFlags,
-            getNamespace(uri));
-
+    registerBuiltinObject(where, attachMouseInterface, uri);
 }
 
 

=== modified file 'libcore/asobj/flash/xml/XMLDocument_as.cpp'
--- a/libcore/asobj/flash/xml/XMLDocument_as.cpp        2009-07-29 05:40:20 
+0000
+++ b/libcore/asobj/flash/xml/XMLDocument_as.cpp        2009-08-18 10:32:14 
+0000
@@ -30,6 +30,7 @@
 #include "xml/XMLNode_as.h"
 #include "xml/XMLDocument_as.h"
 #include "builtin_function.h"
+#include "NativeFunction.h"
 #include "VM.h"
 #include "namedStrings.h"
 #include "StringPredicates.h"
@@ -623,16 +624,11 @@
 XMLDocument_as::init(as_object& where, const ObjectURI& uri)
 {
 
-    static boost::intrusive_ptr<as_object> cl;
-
-    if ( cl == NULL )
-    {
-        Global_as* gl = getGlobal(where);
-        as_object* proto = getXMLInterface();
-        cl = gl->createClass(&xml_new, proto);
-    }
+    Global_as* gl = getGlobal(where);
+    as_object* proto = getXMLInterface();
+    as_object* cl = gl->createClass(&xml_new, proto);
     
-    where.init_member(getName(uri), cl.get(), as_object::DefaultFlags,
+    where.init_member(getName(uri), cl, as_object::DefaultFlags,
             getNamespace(uri));
 
 }

=== modified file 'libcore/asobj/flash/xml/XMLNode_as.cpp'
--- a/libcore/asobj/flash/xml/XMLNode_as.cpp    2009-07-29 05:40:20 +0000
+++ b/libcore/asobj/flash/xml/XMLNode_as.cpp    2009-08-18 10:32:14 +0000
@@ -31,7 +31,7 @@
 #include "Global_as.h"
 #include "smart_ptr.h" // for boost intrusive_ptr
 #include "builtin_function.h" // need builtin_function
-#include "GnashException.h" // for ActionException
+#include "NativeFunction.h"
 #include "string_table.h"
 #include "PropertyList.h"
 #include "Global_as.h"
@@ -446,17 +446,11 @@
 void
 XMLNode_as::init(as_object& where, const ObjectURI& uri)
 {
-    // This is the global XMLNode_as "class"
-    static boost::intrusive_ptr<as_object> cl;
-
-    if ( cl == NULL )
-    {
-        Global_as* gl = getGlobal(where);
-        as_object* proto = getXMLNodeInterface();
-        cl = gl->createClass(&xmlnode_new, proto);
-    }
-
-    where.init_member(getName(uri), cl.get(), as_object::DefaultFlags,
+    Global_as* gl = getGlobal(where);
+    as_object* proto = getXMLNodeInterface();
+    as_object* cl = gl->createClass(&xmlnode_new, proto);
+
+    where.init_member(getName(uri), cl, as_object::DefaultFlags,
             getNamespace(uri));
 
 }

=== modified file 'libcore/builtin_function.h'
--- a/libcore/builtin_function.h        2009-07-15 11:21:47 +0000
+++ b/libcore/builtin_function.h        2009-08-18 08:00:20 +0000
@@ -18,9 +18,9 @@
 #ifndef GNASH_BUILTIN_FUNCTION_H
 #define GNASH_BUILTIN_FUNCTION_H
 
-#include "as_function.h" // for inheritance
-#include "fn_call.h" // for call operator
-// #include "as_environment.h" // for FrameGuard
+#include "as_function.h" 
+#include "fn_call.h" 
+#include "as_environment.h" 
 #include "namedStrings.h"
 
 #include <cassert>
@@ -29,7 +29,14 @@
 
 
 
-/// Any built-in function/class should be of this type
+/// This is a special type of function implementing AS-code in C++
+//
+/// Many functions (including classes) are implemented in ActionScript in
+/// the reference player. Gnash implements them in C++, but they must
+/// be treated like swf-defined functions.
+//
+/// They are distinct from NativeFunctions, which are part of the player and
+/// do not go through the ActionScript interpreter.
 class builtin_function : public as_function
 {
     typedef as_value (*ASFunction)(const fn_call& fn);
@@ -49,8 +56,6 @@
                as_function(gl),
                _func(func)
        {
-               init_member(NSV::PROP_CONSTRUCTOR,
-                as_function::getFunctionConstructor().get());
        }
 
        /// Construct a builtin function with the given interface (possibly 
none)
@@ -67,17 +72,11 @@
        ///         to get a default interface instead.
     /// @param useThisAsCtor
     ///     Used only by getFunctionConstructor().
-       builtin_function(Global_as& gl, ASFunction func, as_object* iface,
-            bool useThisAsCtor = false)
+       builtin_function(Global_as& gl, ASFunction func, as_object* iface)
                :
                as_function(gl, iface),
                _func(func)
        {
-               if (useThisAsCtor) init_member(NSV::PROP_CONSTRUCTOR, this);
-               else {
-                       init_member(NSV::PROP_CONSTRUCTOR,
-                    as_function::getFunctionConstructor().get());
-               }
        }
 
        /// Invoke this function or this Class constructor
@@ -95,8 +94,8 @@
                // specifying for a builtin_function whether or not
                // it should be considered 'native'.
                // If not 'native', we'd push a CallFrame on stack...
-               //
-               //as_environment::FrameGuard guard(fn.env(), this);
+        as_environment env = fn.env();
+               as_environment::FrameGuard guard(env, this);
 
                assert(_func);
                return _func(fn);

=== modified file 'libcore/movie_root.cpp'
--- a/libcore/movie_root.cpp    2009-07-21 16:24:10 +0000
+++ b/libcore/movie_root.cpp    2009-08-17 11:47:12 +0000
@@ -523,15 +523,15 @@
     return sel;
 }
 
-boost::intrusive_ptr<Stage_as>
+as_object*
 movie_root::getStageObject()
 {
        as_value v;
        assert ( VM::isInitialized() ); // return NULL;
        Global_as* global = _vm.getGlobal();
-       if ( ! global ) return NULL;
-       if (!global->get_member(NSV::PROP_iSTAGE, &v) ) return NULL;
-       return boost::dynamic_pointer_cast<Stage_as>(v.to_object(*global));
+       if (!global) return 0;
+       if (!global->get_member(NSV::PROP_iSTAGE, &v) ) return 0;
+       return v.to_object(*global).get();
 }
                
 void
@@ -544,11 +544,14 @@
        m_viewport_width = w;
        m_viewport_height = h;
 
-       if ( _scaleMode == noScale ) // rescale not allowed, notify Stage (if 
any)
-       {
+       if (_scaleMode == noScale) {
                //log_debug("Rescaling disabled");
-               boost::intrusive_ptr<Stage_as> stage = getStageObject();
-               if ( stage ) stage->notifyResize();
+               as_object* stage = getStageObject();
+               if (stage) {
+            log_debug("notifying Stage listeners about a resize");
+            stage->callMethod(NSV::PROP_BROADCAST_MESSAGE, "onResize");
+        }
+
        }
 
        assert(testInvariant());
@@ -1535,10 +1538,12 @@
     _scaleMode = sm;
     callInterface("Stage.align");    
 
-    if ( notifyResize )
-    {
-        boost::intrusive_ptr<Stage_as> stage = getStageObject();
-        if ( stage ) stage->notifyResize();
+    if (notifyResize) {
+        as_object* stage = getStageObject();
+        if (stage) {
+            log_debug("notifying Stage listeners about a resize");
+            stage->callMethod(NSV::PROP_BROADCAST_MESSAGE, "onResize");
+        }
     }
 }
 
@@ -1547,9 +1552,11 @@
 {
     _displayState = ds;
 
-    boost::intrusive_ptr<Stage_as> stage = getStageObject();
+    as_object* stage = getStageObject();
     if (stage) {
-        stage->notifyFullScreen((_displayState == DISPLAYSTATE_FULLSCREEN));
+        log_debug("notifying Stage listeners about fullscreen state");
+        const bool fs = _displayState == DISPLAYSTATE_FULLSCREEN;
+        stage->callMethod(NSV::PROP_BROADCAST_MESSAGE, "onFullScreen", fs);
     }
 
        if (!_interfaceHandler) return; // No registered callback

=== modified file 'libcore/movie_root.h'
--- a/libcore/movie_root.h      2009-08-06 20:17:03 +0000
+++ b/libcore/movie_root.h      2009-08-17 11:47:12 +0000
@@ -103,7 +103,6 @@
 // Forward declarations
 namespace gnash {
     class ExecutableCode; // for ActionQueue
-    class Stage_as;
     class URL;
     class Timer;
     class MovieClip;
@@ -131,7 +130,7 @@
 /// Loading a new top-level movie does not create a new movie_root.
 //
 /// The 'Stage' part of movie_root is accessible through the ActionScript
-/// Stage object, implemented in Stage_as.
+/// Stage object, implemented in Stage_as.cpp.
 //
 /// The movie_root class is responsible for accepting and passing on
 /// user events (mouse or key events), for maintaining the heart-beat
@@ -1006,7 +1005,7 @@
     //
     /// Can return NULL if it's been deleted or not
     /// yet initialized.
-    boost::intrusive_ptr<Stage_as> getStageObject();
+    as_object* getStageObject();
 
     /// Return the singleton Selection object
     //

=== modified file 'libcore/swf_function.cpp'
--- a/libcore/swf_function.cpp  2009-07-15 11:21:47 +0000
+++ b/libcore/swf_function.cpp  2009-08-18 08:00:20 +0000
@@ -23,7 +23,7 @@
 #include "action_buffer.h"
 #include "ActionExec.h" // for operator()
 #include "VM.h" // for storing _global in a local register
-#include "builtin_function.h" // for Function constructor
+#include "NativeFunction.h" // for Function constructor
 #include "Object.h" // for getObjectInterface
 #include "Global_as.h" // for getObjectInterface
 #include "namedStrings.h"
@@ -56,8 +56,7 @@
 {
        assert( m_start_pc < m_action_buffer.size() );
 
-       init_member("constructor", 
-            as_value(as_function::getFunctionConstructor().get()));
+       init_member(NSV::PROP_CONSTRUCTOR, 
as_function::getFunctionConstructor());
 }
 
 /*private static*/

=== modified file 'libcore/vm/VM.cpp'
--- a/libcore/vm/VM.cpp 2009-08-07 08:43:01 +0000
+++ b/libcore/vm/VM.cpp 2009-08-18 08:00:20 +0000
@@ -24,13 +24,14 @@
 #include "VM.h"
 #include "flash/net/SharedObject_as.h" // for SharedObjectLibrary
 #include "smart_ptr.h" // GNASH_USE_GC
+#include "NativeFunction.h"
 #include "builtin_function.h"
 #include "movie_definition.h"
 #include "Movie.h"
 #include "movie_root.h"
 #include "Globals.h"
 #include "Global_as.h"
-#include "rc.h" //for overriding default version string with rcfile
+#include "rc.h" 
 #include "namedStrings.h"
 #include "VirtualClock.h" // for getTime()
 
@@ -274,15 +275,22 @@
     //log_debug("Registering function %p as ASnative(%d, %d) ", (void*)fun, x, 
y);
     assert(fun);
     assert(!_asNativeTable[x][y]);
-    _asNativeTable[x][y]=fun;
+    _asNativeTable[x][y] = fun;
 }
 
-builtin_function*
-VM::getNative(unsigned int x, unsigned int y)
+NativeFunction*
+VM::getNative(unsigned int x, unsigned int y) const
 {
-       as_c_function_ptr fun = _asNativeTable[x][y];
-       if (fun) return _global->createFunction(fun);
-       return 0;
+    AsNativeTable::const_iterator row = _asNativeTable.find(x);
+    if (row == _asNativeTable.end()) return 0;
+    FuncMap::const_iterator col = row->second.find(y);
+    if (col == row->second.end()) return 0;
+    as_c_function_ptr fun = col->second;
+
+    NativeFunction* f = new NativeFunction(*_global, fun);
+    f->init_member(NSV::PROP_CONSTRUCTOR,
+            as_function::getFunctionConstructor());
+    return f;
 }
 
 } // end of namespace gnash

=== modified file 'libcore/vm/VM.h'
--- a/libcore/vm/VM.h   2009-07-14 07:23:01 +0000
+++ b/libcore/vm/VM.h   2009-08-18 06:49:40 +0000
@@ -41,7 +41,7 @@
        class VM;
        class fn_call;
        class movie_root;
-       class builtin_function;
+       class NativeFunction;
     class SharedObjectLibrary;
        class as_value;
        class as_object;
@@ -256,8 +256,8 @@
 
        void registerNative(as_c_function_ptr fun, unsigned int x, unsigned int 
y);
 
-       /// Return a newly created builtin_function or null
-       builtin_function* getNative(unsigned int x, unsigned int y);
+       /// Return a native function or null
+       NativeFunction* getNative(unsigned int x, unsigned int y) const;
 
 #ifdef GNASH_USE_GC
        void addStatic(GcResource* res)

=== modified file 'libcore/vm/fn_call.h'
--- a/libcore/vm/fn_call.h      2009-07-14 15:33:46 +0000
+++ b/libcore/vm/fn_call.h      2009-08-17 08:42:00 +0000
@@ -68,6 +68,7 @@
         super(fn.super),
                nargs(fn.nargs),
         callerDef(fn.callerDef),
+        _new(false),
         _env(fn._env),
         _args(fn._args.get() ? new std::vector<as_value>(*fn._args) : 0)
        {
@@ -79,6 +80,7 @@
         super(sup),
         nargs(fn.nargs),
         callerDef(fn.callerDef),
+        _new(false),
                _env(fn._env),
         _args(fn._args.get() ? new std::vector<as_value>(*fn._args) : 0)
        {
@@ -91,6 +93,7 @@
                super(sup),
                nargs(nargs_in),
         callerDef(0),
+        _new(false),
                _env(env_in)
        {
                assert(first_in + 1 == env_in.stack_size());
@@ -98,12 +101,14 @@
        }
 
        fn_call(as_object* this_in, const as_environment& env_in,
-                       std::auto_ptr<std::vector<as_value> > args, as_object* 
sup = 0)
+                       std::auto_ptr<std::vector<as_value> > args, as_object* 
sup = 0,
+            bool isNew = false)
                :
                this_ptr(this_in),
                super(sup),
                nargs(args->size()),
         callerDef(0),
+        _new(isNew),
                _env(env_in),
                _args(args)
        {
@@ -115,6 +120,7 @@
                super(0),
                nargs(0),
         callerDef(0),
+        _new(false),
                _env(env_in)
        {
        }
@@ -134,7 +140,7 @@
                // For the future, we might use an explicit flag instead
                // as I belive there are some cases in which 'this' is
                // undefined even in a normal function call.
-               return (this_ptr == 0);
+               return _new;
        }
 
        /// Access a particular argument.
@@ -192,6 +198,8 @@
 
 private:
 
+    bool _new;
+
        /// The ActionScript environment in which the function call is taking
        /// place. This contains, among other things, the function arguments.
        const as_environment& _env;

=== modified file 'testsuite/actionscript.all/ASnative.as'
--- a/testsuite/actionscript.all/ASnative.as    2009-01-22 20:10:39 +0000
+++ b/testsuite/actionscript.all/ASnative.as    2009-08-18 10:05:43 +0000
@@ -275,8 +275,82 @@
 xcheck_equals(ret, true);
 xcheck_equals (typeof(f.data), "object");
 
-#if OUTPUT_VERSION > 5
-check_totals(83);
-#else
-check_totals(80);
+// Check that ASnative returns a new function, not the same one.
+a = ASnative(2106, 204);
+b = ASnative(2106, 204);
+#if OUTPUT_VERSION < 6
+check(a == b);
+#else
+check(a != b);
+#endif
+
+/// Test ASconstructor
+//
+/// The important things seem to be:
+/// 1. a new prototype is created every time; it's not the same object.
+/// 2. native functions may only work with an appropriate prototype.
+
+// This is _global.Number
+f = ASconstructor(106, 2);
+xcheck_equals(typeof(f), "function");
+xcheck_equals(typeof(f.prototype), "object");
+
+// Attach number natives and it works.
+ASSetNative(f.prototype, 106, "valueOf,toString");
+
+obj = new f(6);
+check_equals(obj.__proto__, f.prototype);
+#if OUTPUT_VERSION > 5
+check(obj.__proto__ != Number.prototype);
+#else
+check_equals(obj.__proto__, undefined);
+#endif
+
+xcheck_equals(typeof(obj), "object");
+xcheck_equals(obj.toString(), "6");
+
+// Attach boolean natives and it fails.
+ASSetNative(f.prototype, 107, "valueOf,toString");
+xcheck_equals(typeof(obj), "object");
+check_equals(obj.toString(), undefined);
+
+// Attach number natives to prototype again and it works.
+ASSetNative(f.prototype, 106, "valueOf,toString");
+xcheck_equals(obj.toString(), "6");
+
+g = ASnative(106, 2);
+xcheck_equals(typeof(g), "function");
+check_equals(typeof(g.prototype), "undefined");
+
+// This is the ASnative function Number.toString. It does not attach
+// Number.prototype, so the Number.toString function fails.
+f = ASconstructor(106, 1);
+ASSetNative(f.prototype, 106, "valueOf,toString");
+xcheck_equals(typeof(f), "function");
+xcheck_equals(typeof(f.prototype), "object");
+obj = new f(6);
+xcheck_equals(typeof(obj), "object");
+check_equals(obj.toString(), undefined);
+
+obj = new f();
+check_equals(obj.toString(), undefined);
+
+ba = ASnative;
+ASnative = 78;
+
+// ASconstructor doesn't rely on ASnative.
+f = ASconstructor(106, 2);
+xcheck_equals(typeof(f), "function");
+xcheck_equals(typeof(f.prototype), "object");
+
+g = ASnative(106, 2);
+check_equals(typeof(g), "undefined");
+check_equals(typeof(g.prototype), "undefined");
+
+ASnative = ba;
+
+#if OUTPUT_VERSION > 5
+check_totals(104);
+#else
+check_totals(101);
 #endif

=== modified file 'testsuite/actionscript.all/Instance.as'
--- a/testsuite/actionscript.all/Instance.as    2009-08-13 09:04:55 +0000
+++ b/testsuite/actionscript.all/Instance.as    2009-08-17 11:52:24 +0000
@@ -44,15 +44,9 @@
 check_equals(typeof(o.__proto__), "undefined");
 ASSetPropFlags(o, null, 6, 1);
 #if OUTPUT_VERSION < 7
-    #if OUTPUT_VERSION == 6
-    // SWF6 passes
     check_equals(typeof(o.constructor), "function");
-    #else
-    // SWF5 doesn't
-    xcheck_equals(typeof(o.constructor), "function");
-    #endif
 #else
-check_equals(typeof(o.constructor), "undefined");
+    check_equals(typeof(o.constructor), "undefined");
 #endif
 #if OUTPUT_VERSION > 5
 check_equals(typeof(o.__constructor__), "function");
@@ -69,15 +63,9 @@
 check_equals(typeof(o), "object");
 check_equals(typeof(o.__proto__), "undefined");
 #if OUTPUT_VERSION < 7
-    #if OUTPUT_VERSION == 6
-    // SWF6 passes
     check_equals(typeof(o.constructor), "function");
-    #else
-    // SWF5 doesn't
-    xcheck_equals(typeof(o.constructor), "function");
-    #endif
 #else
-check_equals(typeof(o.constructor), "undefined");
+    check_equals(typeof(o.constructor), "undefined");
 #endif
 check_equals(o.toString(), undefined);
 check_equals(o.valueOf(), undefined);
@@ -89,15 +77,9 @@
 check_equals(typeof(o), "object");
 check_equals(typeof(o.__proto__), "undefined");
 #if OUTPUT_VERSION < 7
-    #if OUTPUT_VERSION == 6
-    // SWF6 passes
     check_equals(typeof(o.constructor), "function");
-    #else
-    // SWF5 doesn't
-    xcheck_equals(typeof(o.constructor), "function");
-    #endif
 #else
-check_equals(typeof(o.constructor), "undefined");
+    check_equals(typeof(o.constructor), "undefined");
 #endif
 check_equals(o.toString(), undefined);
 check_equals(o.valueOf(), undefined);
@@ -121,4 +103,33 @@
 check_equals(typeof(o), "undefined");
 check_equals(o, undefined);
 
-check_totals(34);
+// Check object.prototype
+// It seems this can't be changed under any circumstances.
+delete Object.prototype;
+check_equals(typeof(Object.prototype), "object");
+Object.prototype = 6;
+check_equals(typeof(Object.prototype), "object");
+check_equals(Object.prototype.toString(), "[object Object]");
+ASSetPropFlags(Object, null, 0);
+delete Object.prototype;
+check_equals(typeof(Object.prototype), "object");
+
+// String.prototype can be changed.
+String.prototype = 8;
+check_equals(typeof(String.prototype), "number");
+check_equals(String.prototype, 8);
+s = new String("hello");
+xcheck_equals(s, undefined);
+xcheck_equals(s.__proto__, 8);
+check_equals(typeof(s), "object");
+check(!s instanceOf String);
+
+s = new Object("hello");
+xcheck_equals(s, undefined);
+
+Cl = function() {};
+Cl.prototype = 8;
+c = new Cl();
+check_equals(c.__proto__, 8);
+
+check_totals(46);

=== modified file 'testsuite/actionscript.all/MovieClip.as'
--- a/testsuite/actionscript.all/MovieClip.as   2009-07-18 14:22:10 +0000
+++ b/testsuite/actionscript.all/MovieClip.as   2009-08-18 08:36:30 +0000
@@ -1926,7 +1926,7 @@
 #if OUTPUT_VERSION < 6
  check_equals(retCaller, _root.meth); // in gnash works because functions 
resolve equal to undefined
 #else
- xcheck_equals(retCaller, _root.meth); // check that arguments.caller is also 
set for builtin functions
+ check_equals(retCaller, _root.meth); // check that arguments.caller is also 
set for builtin functions
 #endif
 check_equals(typeof(ret), 'number');
 check_equals(ret, 2);


reply via email to

[Prev in Thread] Current Thread [Next in Thread]