gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] /srv/bzr/gnash/trunk r11661: Store Object.prototype in th


From: Benjamin Wolsey
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r11661: Store Object.prototype in the Global objects, removing the need for
Date: Mon, 30 Nov 2009 08:43:29 +0100
User-agent: Bazaar (1.16.1)

------------------------------------------------------------
revno: 11661 [merge]
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Mon 2009-11-30 08:43:29 +0100
message:
  Store Object.prototype in the Global objects, removing the need for
  static pointers. Initialize them differently (the pp does so too).
  
  Add tests to work out what to do for the Function class.
  
  Remove various things from the as_function class.
modified:
  libcore/MovieClip.cpp
  libcore/as_function.cpp
  libcore/as_function.h
  libcore/asobj/Globals.cpp
  libcore/asobj/Globals.h
  libcore/asobj/Object.cpp
  libcore/asobj/Object.h
  libcore/asobj/flash/media/Camera_as.cpp
  libcore/asobj/flash/media/Microphone_as.cpp
  libcore/parser/sprite_definition.cpp
  libcore/swf_function.cpp
  libcore/swf_function.h
  libcore/vm/ASHandlers.cpp
  libcore/vm/VM.cpp
  testsuite/actionscript.all/Function.as
=== modified file 'libcore/MovieClip.cpp'
--- a/libcore/MovieClip.cpp     2009-11-23 07:42:51 +0000
+++ b/libcore/MovieClip.cpp     2009-11-29 09:24:30 +0000
@@ -1908,7 +1908,7 @@
         if ( ctor && ! ctor->isBuiltin() )
         {
             // Set the new prototype *after* the constructor was called
-            boost::intrusive_ptr<as_object> proto = ctor->getPrototype();
+            as_value proto = ctor->getMember(NSV::PROP_PROTOTYPE);
             getObject(this)->set_prototype(proto);
 
             // Call event handlers *after* setting up the __proto__

=== modified file 'libcore/as_function.cpp'
--- a/libcore/as_function.cpp   2009-11-23 17:14:01 +0000
+++ b/libcore/as_function.cpp   2009-11-29 09:24:30 +0000
@@ -71,42 +71,6 @@
        init_member(NSV::PROP_uuPROTOuu, as_value(getFunctionPrototype()), 
flags);
 }
 
-
-void
-as_function::setPrototype(as_object* proto)
-{
-       init_member(NSV::PROP_PROTOTYPE, as_value(proto));
-}
-
-void
-as_function::extends(as_object& superclass)
-{
-       as_object* newproto = new as_object();
-       as_object* p =
-        superclass.getMember(NSV::PROP_PROTOTYPE).to_object(
-                *VM::get().getGlobal());
-       newproto->set_prototype(p);
-
-    if (getSWFVersion(superclass) > 5) {
-        const int flags = PropFlags::dontEnum;
-        newproto->init_member(NSV::PROP_uuCONSTRUCTORuu, &superclass, flags); 
-    }
-
-       init_member(NSV::PROP_PROTOTYPE, as_value(newproto));
-}
-
-boost::intrusive_ptr<as_object>
-as_function::getPrototype()
-{
-       // TODO: create if not available ?
-       // TODO WARNING: what if user overwrites the 'prototype' member ?!
-       //               this function should likely return the *new*
-       //               prototype, not the old !!
-       as_value proto;
-       get_member(NSV::PROP_PROTOTYPE, &proto);
-       return proto.to_object(*VM::get().getGlobal());
-}
-
 NativeFunction*
 as_function::getFunctionConstructor()
 {
@@ -232,13 +196,12 @@
        if (proto.get() == NULL) {
 
                // Initialize Function prototype
-               proto = new as_object();
+        proto = VM::get().getGlobal()->createObject();
         
                // 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& vm = VM::get();
 

=== modified file 'libcore/as_function.h'
--- a/libcore/as_function.h     2009-11-23 08:58:01 +0000
+++ b/libcore/as_function.h     2009-11-29 09:27:07 +0000
@@ -89,35 +89,12 @@
        as_object* constructInstance(const as_environment& env,
                        fn_call::Args& args);
 
-       /// Get this function's "prototype" member (exported interface).
-       ///
-       boost::intrusive_ptr<as_object> getPrototype();
-
-       /// Make this function a subclass of the given as_function
-       void extends(as_object& superclass);
-
        /// Return true if this is a built-in class.
        virtual bool isBuiltin() { return false; }
 
        /// Return the built-in Function constructor
        static NativeFunction* getFunctionConstructor();
 
-#ifdef GNASH_USE_GC
-       /// Mark reachable resources. Override from GcResource
-       //
-       /// Reachable resources from this object is its prototype
-       /// and the default as_object reachables (properties and parent).
-       ///
-       /// The default implementation only marks that. If you
-       /// override this function from a derived class remember
-       /// to call markAsFunctionReachableResources() as a final step.
-       ///
-       virtual void markReachableResources() const
-       {
-               markAsFunctionReachable();
-       }
-#endif // GNASH_USE_GC
-
 protected:
        
     /// Construct a function with no interface
@@ -126,25 +103,6 @@
        ///
        as_function(Global_as& gl);
 
-#ifdef GNASH_USE_GC
-       /// Mark prototype (properties) as being reachable and invoke
-       /// the as_object class marker.
-       //
-       /// Call this function from an override of markReachableResources
-       /// in a derived class
-       ///
-       void markAsFunctionReachable() const
-       {
-               //_properties->setReachable();
-
-               markAsObjectReachable();
-       }
-#endif // GNASH_USE_GC
-
-
-private:
-
-       void setPrototype(as_object* proto);
 };
 
 /// Initialize the global Function constructor

=== modified file 'libcore/asobj/Globals.cpp'
--- a/libcore/asobj/Globals.cpp 2009-11-26 11:22:34 +0000
+++ b/libcore/asobj/Globals.cpp 2009-11-30 07:43:29 +0000
@@ -167,7 +167,8 @@
 AVM2Global::AVM2Global(abc::Machine& /*machine*/, VM& vm)
     :
     _classes(this, 0),
-    _vm(vm)
+    _vm(vm),
+    _objectProto(new as_object(*this))
 {
 }
 
@@ -177,7 +178,9 @@
    
     const string_table::key NS_GLOBAL(0);
     
-    object_class_init(*this, ObjectURI(NSV::CLASS_OBJECT, NS_GLOBAL)); 
+    initObjectClass(_objectProto, *this,
+            ObjectURI(NSV::CLASS_OBJECT, NS_GLOBAL)); 
+
     function_class_init(*this, ObjectURI(NSV::CLASS_FUNCTION, NS_GLOBAL));
     string_class_init(*this, ObjectURI(NSV::CLASS_STRING, NS_GLOBAL)); 
     array_class_init(*this, ObjectURI(NSV::CLASS_ARRAY, NS_GLOBAL)); 
@@ -201,7 +204,7 @@
 AVM1Global::createObject()
 {
     as_object* obj = new as_object(*this);
-    obj->set_prototype(getObjectInterface());
+    obj->set_prototype(_objectProto);
     return obj;
 }
 
@@ -287,7 +290,7 @@
 AVM2Global::createObject()
 {
     as_object* obj = new as_object(*this);
-    obj->set_prototype(getObjectInterface());
+    obj->set_prototype(_objectProto);
     return obj;
 }
 
@@ -348,13 +351,15 @@
 AVM1Global::markReachableResources() const
 {
     _classes.markReachableResources();
+    _objectProto->setReachable();
     markAsObjectReachable();
 }
 
 AVM1Global::AVM1Global(VM& vm)
     :
     _classes(this, &_et),
-    _vm(vm)
+    _vm(vm),
+    _objectProto(new as_object(*this))
 {
 }
 
@@ -365,7 +370,9 @@
 
     const string_table::key NS_GLOBAL(0);
 
-    object_class_init(*this, ObjectURI(NSV::CLASS_OBJECT, NS_GLOBAL)); 
+    initObjectClass(_objectProto, *this,
+            ObjectURI(NSV::CLASS_OBJECT, NS_GLOBAL)); 
+
     function_class_init(*this, ObjectURI(NSV::CLASS_FUNCTION, NS_GLOBAL));
     string_class_init(*this, ObjectURI(NSV::CLASS_STRING, NS_GLOBAL)); 
     array_class_init(*this, ObjectURI(NSV::CLASS_ARRAY, NS_GLOBAL)); 

=== modified file 'libcore/asobj/Globals.h'
--- a/libcore/asobj/Globals.h   2009-11-15 16:26:27 +0000
+++ b/libcore/asobj/Globals.h   2009-11-29 08:57:58 +0000
@@ -111,6 +111,8 @@
 
     ClassHierarchy _classes;
     VM& _vm;
+    
+    as_object* _objectProto;
 
 };
 
@@ -162,6 +164,7 @@
 
     virtual void markReachableResources() const {
         _classes.markReachableResources();
+        _objectProto->setReachable();
         markAsObjectReachable();
     }
 
@@ -169,6 +172,7 @@
 
     ClassHierarchy _classes;
     VM& _vm;
+    as_object* _objectProto;
 
 };
 

=== modified file 'libcore/asobj/Object.cpp'
--- a/libcore/asobj/Object.cpp  2009-11-23 09:04:08 +0000
+++ b/libcore/asobj/Object.cpp  2009-11-29 08:57:58 +0000
@@ -77,12 +77,14 @@
 
 // extern (used by Global.cpp)
 void
-object_class_init(as_object& where, const ObjectURI& uri)
+initObjectClass(as_object* proto, as_object& where, const ObjectURI& uri)
 {
 
+    assert(proto);
+    attachObjectInterface(*proto);
+
     Global_as& gl = getGlobal(where);
-    as_object* proto = getObjectInterface();
-    boost::intrusive_ptr<as_object> cl = gl.createClass(object_ctor, proto);
+    as_object* cl = gl.createClass(object_ctor, proto);
 
     // The as_function ctor takes care of initializing these, but they
     // are different for the Object class.
@@ -97,37 +99,9 @@
                     
        // Register _global.Object (should only be visible in SWF5 up)
        int flags = PropFlags::dontEnum; 
-       where.init_member(getName(uri), cl.get(), flags, getNamespace(uri));
-
-}
-
-
-as_object*
-getObjectInterface()
-{
-    VM& vm = VM::get();
-    
-    if (isAS3(vm)) {
-        static boost::intrusive_ptr<as_object> o;
-        if ( o == NULL )
-        {
-            o = new as_object(); // end of the inheritance chain
-            attachObjectInterface(*o);
-        }
-        return o.get();
-    }
-
-    static boost::intrusive_ptr<as_object> o;
-    if ( o == NULL )
-    {
-        o = new as_object(); // end of the inheritance chain
-        attachObjectInterface(*o);
-    }
-    return o.get();
-
-}
-
-
+       where.init_member(getName(uri), cl, flags, getNamespace(uri));
+
+}
 
 
 namespace {

=== modified file 'libcore/asobj/Object.h'
--- a/libcore/asobj/Object.h    2009-11-18 11:34:54 +0000
+++ b/libcore/asobj/Object.h    2009-11-29 08:57:58 +0000
@@ -26,9 +26,7 @@
 class ObjectURI;
 
 /// Initialize the global Object class
-void object_class_init(as_object& global, const ObjectURI& uri);
-
-as_object* getObjectInterface();
+void initObjectClass(as_object* proto, as_object& global, const ObjectURI& 
uri);
 
 void registerObjectNative(as_object& global);
 

=== modified file 'libcore/asobj/flash/media/Camera_as.cpp'
--- a/libcore/asobj/flash/media/Camera_as.cpp   2009-11-18 13:01:28 +0000
+++ b/libcore/asobj/flash/media/Camera_as.cpp   2009-11-29 08:57:58 +0000
@@ -139,8 +139,7 @@
     static boost::intrusive_ptr<as_object> o;
     if ( ! o )
     {
-        o = new as_object();
-        o->set_prototype(getObjectInterface());
+        o = VM::get().getGlobal()->createObject();
         attachCameraInterface(*o);
     }
     return o.get();

=== modified file 'libcore/asobj/flash/media/Microphone_as.cpp'
--- a/libcore/asobj/flash/media/Microphone_as.cpp       2009-11-29 08:07:23 
+0000
+++ b/libcore/asobj/flash/media/Microphone_as.cpp       2009-11-29 08:57:58 
+0000
@@ -130,8 +130,7 @@
        static boost::intrusive_ptr<as_object> o;
        if ( ! o )
        {
-        o = new as_object();
-        o->set_prototype(getObjectInterface());
+        o = VM::get().getGlobal()->createObject();
                attachMicrophoneInterface(*o);
        }
        return o.get();

=== modified file 'libcore/parser/sprite_definition.cpp'
--- a/libcore/parser/sprite_definition.cpp      2009-11-04 20:39:35 +0000
+++ b/libcore/parser/sprite_definition.cpp      2009-11-29 09:24:30 +0000
@@ -148,8 +148,14 @@
 {
        registeredClass = the_class;
 #ifdef DEBUG_REGISTER_CLASS
-       log_debug(_("Registered class %p for sprite_def %p"), 
(void*)registeredClass.get(), (void*)this);
-       as_object* proto = registeredClass->getPrototype().get();
+    assert(registeredClass);
+
+       log_debug(_("Registered class %p for sprite_def %p"),
+            (void*)registeredClass.get(), (void*)this);
+       as_object* proto =
+        registeredClass->getMember(NSV::PROP_PROTOTYPE).to_object(
+                getGlobal(*registeredClass));
+
        log_debug(_(" Exported interface: "));
        proto->dump_members();
 #endif

=== modified file 'libcore/swf_function.cpp'
--- a/libcore/swf_function.cpp  2009-11-23 16:46:42 +0000
+++ b/libcore/swf_function.cpp  2009-11-29 09:27:07 +0000
@@ -351,7 +351,7 @@
        m_env.markReachableResources();
 
        // Invoke parent class marker
-       markAsFunctionReachable(); 
+       markAsObjectReachable(); 
 }
 #endif // GNASH_USE_GC
 

=== modified file 'libcore/swf_function.h'
--- a/libcore/swf_function.h    2009-11-23 07:42:51 +0000
+++ b/libcore/swf_function.h    2009-11-29 09:27:07 +0000
@@ -142,9 +142,9 @@
        virtual as_value call(const fn_call& fn);
 
 #ifdef GNASH_USE_GC
-       /// Mark reachable resources. Override from as_function.
+       /// Mark reachable resources. Override from as_object
        //
-       /// Reachable resources from this object is it's scope stack
+       /// Reachable resources from this object are its scope stack
        /// and the prototype.
        ///
        virtual void markReachableResources() const;

=== modified file 'libcore/vm/ASHandlers.cpp'
--- a/libcore/vm/ASHandlers.cpp 2009-11-23 18:05:35 +0000
+++ b/libcore/vm/ASHandlers.cpp 2009-11-29 09:07:59 +0000
@@ -3311,7 +3311,9 @@
 
     as_environment& env = thread.env;
 
-    as_object* super = env.top(0).to_object(getGlobal(thread.env));
+    Global_as& gl = getGlobal(thread.env);
+
+    as_object* super = env.top(0).to_object(gl);
     as_function* sub = env.top(1).to_function();
 
     if (!super ||!sub) {
@@ -3330,7 +3332,16 @@
     }
     env.drop(2);
 
-    sub->extends(*super);
+       as_object* newproto = new as_object(gl);
+       as_object* p = super->getMember(NSV::PROP_PROTOTYPE).to_object(gl);
+       newproto->set_prototype(p);
+
+    if (getSWFVersion(*super) > 5) {
+        const int flags = PropFlags::dontEnum;
+        newproto->init_member(NSV::PROP_uuCONSTRUCTORuu, super, flags); 
+    }
+
+       sub->init_member(NSV::PROP_PROTOTYPE, as_value(newproto));
 
 }
 

=== modified file 'libcore/vm/VM.cpp'
--- a/libcore/vm/VM.cpp 2009-11-15 16:26:27 +0000
+++ b/libcore/vm/VM.cpp 2009-11-29 11:33:46 +0000
@@ -270,9 +270,8 @@
 }
 
 void
-VM::registerNative(as_c_function_ptr fun, unsigned int x, unsigned int y)
+VM::registerNative(Global_as::ASFunction fun, unsigned int x, unsigned int y)
 {
-    //log_debug("Registering function %p as ASnative(%d, %d) ", (void*)fun, x, 
y);
     assert(fun);
     assert(!_asNativeTable[x][y]);
     _asNativeTable[x][y] = fun;
@@ -285,7 +284,7 @@
     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;
+    Global_as::ASFunction fun = col->second;
 
     NativeFunction* f = new NativeFunction(*_global, fun);
     f->init_member(NSV::PROP_CONSTRUCTOR,

=== modified file 'testsuite/actionscript.all/Function.as'
--- a/testsuite/actionscript.all/Function.as    2009-10-15 09:45:00 +0000
+++ b/testsuite/actionscript.all/Function.as    2009-11-29 15:58:48 +0000
@@ -981,12 +981,103 @@
 check_equals(a.count, 2);
 check_equals(b.count, 1); // See bug #22203
 
+
+/// Check property construction.
+
+#if OUTPUT_VERSION >= 6
+
+check(_global.Function.prototype.constructor === _global.Function);
+
+f = ASnative(1, 0);
+check(f.__proto__ === _global.Function.prototype);
+
+backup = _global.Function.prototype;
+_global.Function.prototype = 8;
+
+// Obviously this doesn't change already assigned properties
+check(f.__proto__ === backup);
+
+// Native function __proto__ is _global.Function.prototype
+f = ASnative(1, 0);
+xcheck(f.__proto__ === _global.Function.prototype);
+xcheck(f.__proto__ === 8);
+
+funbackup = _global.Function;
+
+_global.Function = function() { this.a = "string"; };
+o = { p:"hi" };
+_global.Function.prototype = o;
+_global.Function.prototype.constructor = 2;
+_global.Function.constructor = 6;
+
+// 1. Does not call new Function();
+// 2. Does not call Function.constructor;
+// 3. does not call Function.prototype.constructor;
+
+// The only things it does are:
+
+// 4. Sets constructor to be _global.Function (whatever that is and regardless
+//    of visibility.
+// 5. Sets __proto__ to be _global.Function.prototype (whatever that is) and
+//    regardless of visibility.
+
+f = ASnative(1, 0);
+xcheck(f.__proto__  === o);
+
+// Inherited property.
+xcheck(f.p === "hi");
+xcheck(f instanceOf _global.Function);
+xcheck(f.constructor === _global.Function);
+check(f.constructor !== _global.Function.prototype.constructor);
+
+
+// SWF-defined functions:
+// __proto__ is _global.Function.prototype
+uf = function() {};
+xcheck(uf.p === "hi");
+xcheck(uf.__proto__ === _global.Function.prototype);
+
+// uf.prototype is a new object.
+check(uf.prototype.constructor === uf);
+
+_global.Function = 8;
+
+// Neither property is added if _global.Function is not an object.
+f = ASnative(1, 0);
+check_equals(typeof(f), "function");
+f.hasOwnProperty = Object.prototype.hasOwnProperty;
+xcheck(!f.hasOwnProperty("__proto__"));
+xcheck(!f.hasOwnProperty("constructor"));
+
+
+_global.Function = {};
+
+// Neither property is added if _global.Function is not a function.
+f = ASnative(1, 0);
+check_equals(typeof(f), "function");
+f.hasOwnProperty = Object.prototype.hasOwnProperty;
+xcheck(!f.hasOwnProperty("__proto__"));
+xcheck(!f.hasOwnProperty("constructor"));
+
+called = 0;
+_global.Function = function() { ++called; };
+
+// But the function is not called.
+f = ASnative(1, 0);
+check_equals(typeof(f), "function");
+f.hasOwnProperty = Object.prototype.hasOwnProperty;
+check(f.hasOwnProperty("__proto__"));
+check(f.hasOwnProperty("constructor"));
+
+check_equals(called, 0);
+#endif
+
 #if OUTPUT_VERSION == 5
  check_totals(150); // SWF5
 #endif
 #if OUTPUT_VERSION == 6
- check_totals(216); // SWF6
+ check_totals(239); // SWF6
 #endif
 #if OUTPUT_VERSION >= 7
- check_totals(217); // SWF7,SWF8
+ check_totals(240); // SWF7,SWF8
 #endif


reply via email to

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