gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] gnash ChangeLog server/StreamProvider.cpp serve...


From: Chad Musick
Subject: [Gnash-commit] gnash ChangeLog server/StreamProvider.cpp serve...
Date: Mon, 29 Oct 2007 21:07:35 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Chad Musick <cmusick>   07/10/29 21:07:34

Modified files:
        .              : ChangeLog 
        server         : StreamProvider.cpp as_object.h as_object.cpp 
                         namedStrings.h namedStrings.cpp 
        server/asobj   : ClassHierarchy.cpp 
        server/vm      : ASHandlers.cpp Machine.h Machine.cpp 
                         SafeStack.h CodeStream.h 
        testsuite/actionscript.all: Date.as 

Log message:
        Various updates to AS3 support, fix a compile error in StreamProvider, 
and a
        faulty assumption in testsuite/actionscript.all/Date.as

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.4736&r2=1.4737
http://cvs.savannah.gnu.org/viewcvs/gnash/server/StreamProvider.cpp?cvsroot=gnash&r1=1.21&r2=1.22
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_object.h?cvsroot=gnash&r1=1.80&r2=1.81
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_object.cpp?cvsroot=gnash&r1=1.77&r2=1.78
http://cvs.savannah.gnu.org/viewcvs/gnash/server/namedStrings.h?cvsroot=gnash&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/gnash/server/namedStrings.cpp?cvsroot=gnash&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/ClassHierarchy.cpp?cvsroot=gnash&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/ASHandlers.cpp?cvsroot=gnash&r1=1.145&r2=1.146
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/Machine.h?cvsroot=gnash&r1=1.5&r2=1.6
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/Machine.cpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/SafeStack.h?cvsroot=gnash&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/CodeStream.h?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/actionscript.all/Date.as?cvsroot=gnash&r1=1.32&r2=1.33

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.4736
retrieving revision 1.4737
diff -u -b -r1.4736 -r1.4737
--- ChangeLog   29 Oct 2007 20:09:38 -0000      1.4736
+++ ChangeLog   29 Oct 2007 21:07:32 -0000      1.4737
@@ -1,3 +1,20 @@
+2007-10-30 Chad Musick <address@hidden>
+
+       * server/StreamProvider.cpp: Even if LIBCURL is not being used,
+         URLAccessManager.h must be included.
+       * server/as_object.h,.cpp: Make instanceOf a recursive function
+         so that non-proper properties, like interfaces, will be correctly
+         searched. Add get_super() and get_constructor() functions, not yet
+         implemented.
+       * server/namedStrings.h,.cpp: Add another anonymous string.
+       * server/asobj/ClassHierarchy.cpp: Add prototypes to loaded objects if
+         they don't do so themselves.
+       * server/vm/ASHandlers.cpp: ImplementsOp -- not quite working, yet.
+       * server/vm/Machine.h,.cpp: More work toward AS3 ability.
+       * testsuite/actionscript.all/Date.as: Fix bogus test -- the time
+         returned depends on local timezone, so you can't check to the second.
+       * server/vm/SafeStack.h, server/vm/CodeStream.h -- Comment updates.
+
 2007-10-27 Sandro Santilli <address@hidden>
 
        * testsuite/MovieTester.cpp (checkPixel): multiply tolerance by

Index: server/StreamProvider.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/StreamProvider.cpp,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -b -r1.21 -r1.22
--- server/StreamProvider.cpp   20 Oct 2007 07:06:16 -0000      1.21
+++ server/StreamProvider.cpp   29 Oct 2007 21:07:33 -0000      1.22
@@ -27,8 +27,8 @@
 #ifdef USE_CURL
 //# include <curl/curl.h>
 # include "curl_adapter.h"
-#include "URLAccessManager.h"
 #endif
+#include "URLAccessManager.h"
 #include "log.h"
 #include "rc.h" // for rcfile
 

Index: server/as_object.h
===================================================================
RCS file: /sources/gnash/gnash/server/as_object.h,v
retrieving revision 1.80
retrieving revision 1.81
diff -u -b -r1.80 -r1.81
--- server/as_object.h  29 Oct 2007 10:53:12 -0000      1.80
+++ server/as_object.h  29 Oct 2007 21:07:33 -0000      1.81
@@ -472,6 +472,20 @@
        bool isXML() const { return false; /* TODO */ }
        bool isDictionary() const { return false; /* TODO */ }
 
+       /// Get the super object of this object.
+       ///
+       /// The super should be __proto__ if this is a prototype object
+       /// itself, or __proto__.__proto__ if this is not a prototype
+       /// object. This is only conceptual however, and may be more
+       /// convoluted to obtain the actual super.
+       as_object* get_super(); 
+
+       /// Get the constructor for this object.
+       ///
+       /// This is the AS constructor for this object. When invoked, it
+       /// should initialize the object passed as 'this'
+       as_function* get_constructor();
+
        /// Get a member as_value by name in an AS-compatible way
        //
        /// NOTE that this method is non-const becase a property

Index: server/as_object.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/as_object.cpp,v
retrieving revision 1.77
retrieving revision 1.78
diff -u -b -r1.77 -r1.78
--- server/as_object.cpp        29 Oct 2007 10:53:12 -0000      1.77
+++ server/as_object.cpp        29 Oct 2007 21:07:33 -0000      1.78
@@ -135,6 +135,20 @@
        return const_cast<Property *>(obj->_members.getPropertyByOrder(index));
 }
 
+as_object*
+as_object::get_super()
+{
+       // TODO: Implement
+       return NULL;
+}
+
+as_function*
+as_object::get_constructor()
+{
+       // TODO: Implement
+       return NULL;
+}
+
 int
 as_object::nextIndex(int index, as_object **owner)
 {
@@ -483,6 +497,8 @@
 void
 as_object::add_interface(as_object* obj)
 {
+       assert(obj);
+
        if (std::find(mInterfaces.begin(), mInterfaces.end(), obj) == 
mInterfaces.end())
                mInterfaces.push_back(obj);
        else
@@ -492,26 +508,22 @@
 bool
 as_object::instanceOf(as_function* ctor)
 {
-       boost::intrusive_ptr<as_object> obj = this;
-
-       std::set< as_object* > visited;
+       if (this == ctor->getPrototype())
+               return true;
 
-       if (this == ctor)
-       { assert(0); }
-       while (obj && visited.insert(obj.get()).second )
+       if (!mInterfaces.empty())
+       {
+               // TODO: Make this work.
+               if (std::find(mInterfaces.begin(), mInterfaces.end(), 
ctor->getPrototype()) != mInterfaces.end())
        {
-               if (!mInterfaces.empty() &&
-                       std::find(mInterfaces.begin(), mInterfaces.end(), obj) 
!= mInterfaces.end())
                        return true;
-               if ( obj->get_prototype() == ctor->getPrototype() ) return true;
-               obj = obj->get_prototype(); 
+               }
        }
 
-       // See actionscript.all/Inheritance.as for a way to trigger this
-       IF_VERBOSE_ASCODING_ERRORS(
-       if ( obj ) log_aserror(_("Circular inheritance chain detected during 
instanceOf call"));
-       );
-
+       as_object *proto = this->get_prototype().get();
+       if (proto)
+               return proto->instanceOf(ctor);
+       else
        return false;
 }
 

Index: server/namedStrings.h
===================================================================
RCS file: /sources/gnash/gnash/server/namedStrings.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- server/namedStrings.h       18 Oct 2007 11:47:55 -0000      1.6
+++ server/namedStrings.h       29 Oct 2007 21:07:33 -0000      1.7
@@ -160,7 +160,8 @@
                NS_FLASH_UI,
                NS_ADOBE_UTILS,
                INTERNAL_TYPE, // The type name
-               INTERNAL_STACK_PARENT // Any public property is unsafe
+               INTERNAL_STACK_PARENT, // Any public property is unsafe
+               INTERNAL_INTERFACES
        } named_strings;
 
 /// Load the prenamed strings.

Index: server/namedStrings.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/namedStrings.cpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- server/namedStrings.cpp     18 Oct 2007 11:47:54 -0000      1.4
+++ server/namedStrings.cpp     29 Oct 2007 21:07:34 -0000      1.5
@@ -138,7 +138,8 @@
        { "flash.ui", NSV::NS_FLASH_UI },
        { "adobe.utils", NSV::NS_ADOBE_UTILS },
        { "", NSV::INTERNAL_TYPE },
-       { "", NSV::INTERNAL_STACK_PARENT }
+       { "", NSV::INTERNAL_STACK_PARENT },
+       { "", NSV::INTERNAL_INTERFACES }
 };
 
 void load_strings(string_table *table, int version)

Index: server/asobj/ClassHierarchy.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/ClassHierarchy.cpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- server/asobj/ClassHierarchy.cpp     18 Oct 2007 11:47:55 -0000      1.4
+++ server/asobj/ClassHierarchy.cpp     29 Oct 2007 21:07:34 -0000      1.5
@@ -101,7 +101,7 @@
                                super.set_undefined();
                                return super;
                        }
-                       if (!super.is_object())
+                       if (!super.is_as_function())
                        {
                                // Error here -- not an object.
                                // TODO: Log the error.
@@ -115,8 +115,8 @@
                        // Successfully loaded it, now find it, set its proto, 
and return.
                        as_value us;
                        mTarget->get_member(mDeclaration.name, &us);
-                       if (0 && mDeclaration.super_name)
-                               
us.to_object()->set_prototype(boost::intrusive_ptr<as_object>(super.to_object()));
+                       if (mDeclaration.super_name && 
!us.to_object()->get_prototype())
+                               
us.to_object()->set_prototype(super.to_as_function()->getPrototype());
                        fprintf(stderr, "Loaded ourselves.\n");
                        return us;
                }
@@ -158,7 +158,7 @@
                                super.set_undefined();
                                return super;
                        }
-                       if (!super.is_object())
+                       if (!super.is_as_function())
                        {
                                // Error here -- not an object.
                                // TODO: Log the error.
@@ -170,8 +170,8 @@
                // Successfully loaded it, now find it, set its proto, and 
return.
                as_value us;
                mTarget->get_member(mDeclaration.name, &us);
-               if (0 && mDeclaration.super_name)
-                       
us.to_object()->set_prototype(boost::intrusive_ptr<as_object>(super.to_object()));
+               if (mDeclaration.super_name && !us.to_object()->get_prototype())
+                       
us.to_object()->set_prototype(super.to_as_function()->getPrototype());
                return us;
        }
 };

Index: server/vm/ASHandlers.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/vm/ASHandlers.cpp,v
retrieving revision 1.145
retrieving revision 1.146
diff -u -b -r1.145 -r1.146
--- server/vm/ASHandlers.cpp    25 Oct 2007 09:37:35 -0000      1.145
+++ server/vm/ASHandlers.cpp    29 Oct 2007 21:07:34 -0000      1.146
@@ -17,7 +17,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
-/* $Id: ASHandlers.cpp,v 1.145 2007/10/25 09:37:35 strk Exp $ */
+/* $Id: ASHandlers.cpp,v 1.146 2007/10/29 21:07:34 cmusick Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -1358,27 +1358,51 @@
        }
 
        env.drop(1);
-       if ( instance->instanceOf(super) )
+       if (instance->instanceOf(super))
        {
+               fprintf(stderr, "Cast succeeded.\n");
                env.top(0) = as_value(instance);
        }
        else
        {
-               env.top(0) = as_value();
+               fprintf(stderr, "Cast failed.\n");
+               env.top(0).set_null(); // null, not undefined.
        }
 
        log_msg(_("ActionCastOp TESTING"));
 }
 
 void
-SWFHandlers::ActionImplementsOp(ActionExec& /*thread*/)
+SWFHandlers::ActionImplementsOp(ActionExec& thread)
 {
 //     GNASH_REPORT_FUNCTION;
+//     TODO: This doesn't work quite right, yet.
+       as_environment& env = thread.env;
 
-    // assert(thread.code[thread.pc] == SWF::ACTION_IMPLEMENTSOP);
+       thread.ensureStack(2);
 
-    //as_environment& env = thread.env;
-    log_unimpl (__PRETTY_FUNCTION__);
+       as_object *obj = env.pop().to_object().get();
+       int count = static_cast<int>(env.pop().to_number(&env));
+       as_value a(1);
+
+       if (!obj)
+       {
+               log_msg(_("In ImplementsOp, not an object.\n"));
+               return;
+       }
+       obj = obj->get_prototype().get();
+       if (!obj)
+       {
+               log_msg(_("In ImplementsOp, object had no prototype.\n"));
+               return;
+       }
+
+       thread.ensureStack(count);
+       while (count--)
+       {
+               as_object *inter = 
env.pop().to_as_function()->getPrototype().get();
+               obj->add_interface(inter);
+       }
 }
 
 void
@@ -3492,6 +3516,7 @@
        }
        env.drop(2);
 
+       fprintf(stderr, "Extending.\n");
        sub->extends(*super);
 
        //log_msg(_("%s: testing"), __PRETTY_FUNCTION__);

Index: server/vm/Machine.h
===================================================================
RCS file: /sources/gnash/gnash/server/vm/Machine.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- server/vm/Machine.h 18 Oct 2007 11:47:56 -0000      1.5
+++ server/vm/Machine.h 29 Oct 2007 21:07:34 -0000      1.6
@@ -1,3 +1,5 @@
+// Machine.h A VM to run AS3 code, and AS2 code in the future.
+//
 //   Copyright (C) 2007 Free Software Foundation, Inc.
 // 
 // This program is free software; you can redistribute it and/or modify
@@ -127,36 +129,77 @@
 
        void execute();
 
-       /// push a function call to be executed next.
+       /// push a get call to be executed next.
        ///
-       /// Any asBinding can be pushed, and it will appropriate value
-       /// into return_slot.  This ensures that getter/setter properties
+       /// Any Property can be pushed, and it will put an appropriate value
+       /// into return_slot.  This ensures that getter properties
        /// can be accessed in the same way as other properties, and hides
        /// the difference between ActionScript methods and native C++ methods.
        ///
-       /// @param stack_in
-       /// The initial stack size when the function is entered. This can be 
used
-       /// to pass 'this' and other parameters to the call.
-       ///
-       /// @param stack_out
-       /// The maximum number of values to leave on the stack when the function
-       /// returns.
+       /// @param this_obj
+       /// The 'this' to use for a getter/setter if it exists.
        ///
        /// @param return_slot
        /// A space for the return value. An assignment will always be made 
here,
        /// but mVoidSlot can be used for values that will be discarded.
        ///
-       /// @param pBind
-       /// The binding.  If this is only a partial binding, then
-       /// the 'this' value will be used to complete it, when possible.
-       /// Sending a null binding will result in a no-op, not an error.
-       void pushCall(unsigned int stack_in, as_value *return_slot,
-               Property *pBind);
-
-       void immediateFunction(as_function *to_call, as_value& storage,
-               as_object *pThis);
-       void immediateProcedure(as_function *to_call, as_object *pthis,
-               const as_value *stackAdditions, unsigned int 
stackAdditionsCount);
+       /// @param prop
+       /// The property. If this is a value, it simply returns that value in
+       /// the return_slot immediately. Otherwise, it may immediately call
+       /// the gettter or it may push that onto the call stack and transfer
+       /// control. Callers can be agnostic as to which happens.
+       void pushGet(as_object *this_obj, as_value& return_slot, Property 
*prop);
+
+       /// push a set call to be executed next.
+       ///
+       /// Any Property can be pushed, and it will set the property, if 
possible.
+       /// setter properties and simple properties alike will be handled by 
this.
+       ///
+       /// @param this_obj
+       /// The 'this' to use for a getter/setter if it exists.
+       ///
+       /// @param value
+       /// The value which should be set
+       ///
+       /// @param prop
+       /// The property desired to be set.
+       ///
+       void pushSet(as_object *this_obj, as_value& value, Property *prop);
+
+       /// push a call to be executed next
+       ///
+       /// Push a call to be executed as soon as execution of the current 
opcode
+       /// finishes. At the end, transfer will return to the previous context.
+       ///
+       /// @param func
+       /// The function to call
+       ///
+       /// @param pThis
+       /// The object to act as the 'this' pointer.
+       ///
+       /// @param return_slot
+       /// The slot to use for returns. Use mIgnoreReturn if you don't care
+       /// what happens here.
+       ///
+       /// @param stack_in
+       /// How many of the values on the stack are for the new context
+       ///
+       /// @param stack_out
+       /// How much of the stack should be left behind when the function exits.
+       /// For example: 0 will leave a stack which is stack_in shorter than it
+       /// was on call. 1 will leave a stack which is 1 taller than it was on
+       /// call.
+       ///
+       /// RESTRICTION: stack_in - stack_out must not be negative
+       void pushCall(as_function *func, as_object *pThis, as_value& 
return_slot,
+               unsigned char stack_in, short stack_out);
+
+       void immediateFunction(const as_function *to_call, as_object* pThis,
+               as_value& storage, unsigned char stack_in, short stack_out);
+
+       void immediateProcedure(const as_function *to_call, as_object *pthis,
+               unsigned char stack_in, short stack_out)
+       { immediateFunction(to_call, pthis, mIgnoreReturn, stack_in, 
stack_out); }
 
        Machine(string_table &ST, ClassHierarchy *CH);
 

Index: server/vm/Machine.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/vm/Machine.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- server/vm/Machine.cpp       18 Oct 2007 11:47:56 -0000      1.2
+++ server/vm/Machine.cpp       29 Oct 2007 21:07:34 -0000      1.3
@@ -1,3 +1,4 @@
+// Machine.cpp A machine to run AS3 code, with AS2 code in the future
 //
 //   Copyright (C) 2007 Free Software Foundation, Inc.
 //
@@ -22,6 +23,7 @@
 #include "namedStrings.h"
 #include "array.h"
 #include "abc_block.h"
+#include "fn_call.h"
 
 namespace gnash {
 
@@ -120,8 +122,7 @@
                if (b)                                                          
                                                                \
                {                                                               
                                                                        \
                        mStream->seekTo(opStart);                               
                                                \
-                       mStack.push(*e);                                        
                                                        \
-                       pushCall(1, e, b);                                      
                                                        \
+                       pushGet(e->to_object().get(), *e, b);                   
                                \
                        break;                                                  
                                                                \
                }                                                               
                                                                        \
        }                                                                       
                                                                        \
@@ -148,8 +149,7 @@
                if (d)                                                          
                                                                \
                {                                                               
                                                                        \
                        mStream->seekTo(opStart);                               
                                                \
-                       mStack.push(*c);                                        
                                                        \
-                       pushCall(1, c, d);                                      
                                                        \
+                       pushGet(c->to_object().get(), *c, d);                   
                                \
                        break;                                                  
                                                                \
                }                                                               
                                                                        \
        }                                                                       
                                                                        \
@@ -323,7 +323,7 @@
                Property *b = super->findProperty(a.getName(), 
                        a.getNamespace()->getURI());
                // The object is on the top already.
-               pushCall(1, &mStack.top(0), b);
+               pushGet(super, mStack.top(0), b);
                break;
        }
 /// 0x05 ABC_ACTION_SETSUPER
@@ -349,8 +349,8 @@
                        throw ASReferenceError();
                Property* b = super->findProperty(a.getName(), 
                        a.getNamespace()->getURI());
-               // The object is on the top already.
-               pushCall(1, &mStack.top(0), b);
+               mStack.push(vobj);
+               pushSet(super, vobj, b);
                break;
        }
 /// 0x06 ABC_ACTION_DXNS
@@ -780,8 +780,11 @@
                mStack.drop(1);
                if (!b)
                        mStack.top(0).set_undefined();
-               else // The top of the stack is obj, as it should be.
-                       pushCall(1, &mStack.top(0), const_cast<Property*>(b));
+               else
+               {
+                       mStack.drop(1);
+                       pushGet(obj, mStack.top(0), const_cast<Property*>(b));
+               }
                break;
        }
 /// 0x24 ABC_ACTION_PUSHBYTE
@@ -984,13 +987,19 @@
        case SWF::ABC_ACTION_CALL:
        {
                uint32_t argc = mStream->read_V32();
-               ENSURE_OBJECT(mStack.top(argc + 1));
+               ENSURE_OBJECT(mStack.top(argc + 1)); // The func
+               ENSURE_OBJECT(mStack.top(argc)); // The 'this'
                as_function *f = mStack.top(argc + 1).to_as_function();
-               // argc + 1 will be dropped, and mStack.top(argc + 1)
-               // will be the top of the stack, so that is where the
-               // return value should go. (Currently it is the func)
-               Property b(0, 0, f, NULL);
-               pushCall(argc + 1, &mStack.top(argc + 1), &b);
+               as_object *obj = mStack.top(argc).to_object().get();
+               // We start with argc + 2 values related to this call
+               // on the stack. We want to end with 1 value. We pass
+               // argc values (the parameters), so we need to drop
+               // one more than we pass and store the return just
+               // below that one. Thus:
+               // return is mStack.top(argc + 1)
+               // bottom of arguments is argc deep
+               // drop 1 more value than is passed, on return
+               pushCall(f, obj, mStack.top(argc + 1), argc, -1);
                break;
        }
 /// 0x42 ABC_ACTION_CONSTRUCT
@@ -1005,7 +1014,7 @@
                uint32_t argc = mStream->read_V32();
                as_function *f = mStack.top(argc).to_as_function();
                Property b(0, 0, f, NULL);
-               pushCall(argc, &mStack.top(argc), &b);
+               pushCall(f, NULL, mStack.top(argc), argc, 0);
                break;
        }
 /// 0x43 ABC_ACTION_CALLMETHOD
@@ -1021,14 +1030,21 @@
                uint32_t argc = mStream->read_V32();
                ENSURE_OBJECT(mStack.top(argc));
                as_object *obj = mStack.top(argc).to_object().get();
-               Property *b = NULL; // TODO: obj->findProperty(dispatch_id);
-               if (!b)
+               Property *f = obj->getByIndex(dispatch_id);
+               as_function* func;
+               if (f->isGetterSetter())
                {
-                       mStack.drop(argc);
-                       mStack.top(0).set_undefined();
-                       break;
+                       // Likely an error, but try to handle it.
+                       func = f->getGetter();
+               }
+               else if (f->getValue(*obj).is_function())
+                       func = f->getValue(*obj).to_as_function();
+               else
+               {
+                       // Definitely an error, and not the kind we can handle.
+                       throw ASException();
                }
-               pushCall(argc + 1, &mStack.top(argc), b);
+               pushCall(func, obj, mStack.top(argc), argc, 0);
                break;
        }
 /// 0x44 ABC_ACTION_CALLSTATIC
@@ -1042,8 +1058,10 @@
        {
                asMethod *m = pool_method(mStream->read_V32(), mPoolObject);
                uint32_t argc = mStream->read_V32();
-               Property b; //TODO: asBinding b(m);
-               pushCall(argc + 1, &mStack.top(argc), &b);
+               as_function *func = m->getPrototype();
+               ENSURE_OBJECT(mStack.top(argc));
+               as_object *obj = mStack.top(argc).to_object().get();
+               pushCall(func, obj, mStack.top(argc), argc, 0);
                break;
        }
 /// 0x45 ABC_ACTION_CALLSUPER
@@ -1065,16 +1083,20 @@
                int dropsize = completeName(a);
                ENSURE_OBJECT(mStack.top(argc + dropsize));
                mStack.drop(dropsize);
-               ENSURE_OBJECT(mStack.top(argc));
-               as_object *super = 
mStack.top(argc).to_object()->get_prototype().get();
+               as_object *super = mStack.top(argc).to_object()->get_super();
                if (!super)
                        throw ASReferenceError();
                Property *b = super->findProperty(a.getName(), 
                        a.getNamespace()->getURI());
+               if (!b)
+                       throw ASReferenceError();
+               as_function *f = b->isGetterSetter() ? b->getGetter() :
+                       b->getValue(super).to_as_function();
+
                if (opcode == SWF::ABC_ACTION_CALLSUPER)
-                       pushCall(argc + 1, &mStack.top(argc), b);
-               else
-                       pushCall(argc + 1, &mIgnoreReturn, b);
+                       pushCall(f, super, mStack.top(argc), argc, 0);
+               else // Void call
+                       pushCall(f, super, mIgnoreReturn, argc, -1); // drop 
obj too.
                break;
        }
 /// 0x46 ABC_ACTION_CALLPROPERTY
@@ -1099,21 +1121,33 @@
                uint32_t argc = mStream->read_V32();
                int shift = completeName(a, argc);
                ENSURE_OBJECT(mStack.top(shift + argc));
-               // Ugly setup. Any name stuff is between the args and the 
object.
-               if (shift)
+               as_object *obj = mStack.top(argc + shift).to_object().get();
+               Property *b = obj->findProperty(a.getName(), 
+                       a.getNamespace()->getURI());
+               if (!b)
+                       throw ASReferenceError();
+
+               as_function *func;
+               if (b->isGetterSetter())
                {
-                       uint32_t i = argc;
-                       while (i--)
-                               mStack.top(i + shift) = mStack.top(i);
-                       mStack.drop(shift);
+                       if (lex_only)
+                       {
+                               mStack.top(argc + shift).set_undefined();
+                               mStack.drop(argc + shift);
+                               break;
+                       }
+                       else
+                       {
+                               func = b->getGetter();
+                       }
                }
-               Property *b = mStack.top(argc).to_object()->
-                       findProperty(a.getName(), a.getNamespace()->getURI());
-               //TODO: b->setLexOnly(lex_only);
+               else
+                       func = b->getValue(obj).to_as_function();
+
                if (opcode == SWF::ABC_ACTION_CALLPROPVOID)
-                       pushCall(argc + 1, &mIgnoreReturn, b);
+                       pushCall(func, obj, mIgnoreReturn, argc, -shift - 1);
                else
-               pushCall(argc + 1, &mStack.top(argc), b);
+                       pushCall(func, obj, mStack.top(argc + shift), argc, 
-shift);
                break;
        }
 /// 0x47 ABC_ACTION_RETURNVOID
@@ -1135,6 +1169,7 @@
        case SWF::ABC_ACTION_RETURNVALUE:
        {
                // Slot the return.
+               if (mGlobalReturn != &mStack.top(0));
                *mGlobalReturn = mStack.top(0);
                // And restore the previous state.
                restoreState();
@@ -1143,17 +1178,27 @@
 /// 0x49 ABC_ACTION_CONSTRUCTSUPER
 /// Stream: V32 'arg_count'
 /// Stack In:
+///  argN ... arg1 -- the arg_count arguments
 ///  obj -- the object whose super's constructor should be invoked
-///  arg1 ... argN -- the arg_count arguments
 /// Stack Out:
 ///  .
        case SWF::ABC_ACTION_CONSTRUCTSUPER:
        {
+               // TODO
                uint32_t argc = mStream->read_V32();
                ENSURE_OBJECT(mStack.top(argc));
-               asMethod *m = findSuper(mStack.top(argc), 
true)->getConstructor();
-               Property b; //TODO: asBinding b(m);
-               pushCall(argc + 1, &mIgnoreReturn, &b);
+               as_object *obj = mStack.top(argc).to_object().get();
+               as_object *super = mStack.top(argc).to_object()->get_super();
+               if (!super)
+               {
+                       throw ASException();
+                       break;
+               }
+               as_function *func = super->get_constructor();
+               // 'obj' is the 'this' for the call, we ignore the return, 
there are
+               // argc arguments, and we drop all of the arguments plus 'obj' 
from
+               // the stack.
+               pushCall(func, obj, mIgnoreReturn, argc, -1);
                break;
        }
 /// 0x4A ABC_ACTION_CONSTRUCTPROP
@@ -1167,6 +1212,7 @@
 ///   'name_offset'(arg1, ..., argN)
        case SWF::ABC_ACTION_CONSTRUCTPROP:
        {
+               // TODO
                asName a = pool_name(mStream->read_V32(), mPoolObject);
                uint32_t argc = mStream->read_V32();
                int shift = completeName(a, argc);
@@ -1197,7 +1243,7 @@
 /// NB: This builds an object from its properties, it's not a constructor.
        case SWF::ABC_ACTION_NEWOBJECT:
        {
-               as_object *obj = mCH->newOfType(NSV::CLASS_OBJECT);
+               as_object *obj = new as_object;
                uint32_t argc = mStream->read_V32();
                int i = argc;
                while (i--)
@@ -1222,14 +1268,13 @@
        case SWF::ABC_ACTION_NEWARRAY:
        {
                uint32_t asize = mStream->read_V32();
-               as_object *obj = mCH->newOfType(NSV::CLASS_ARRAY);
-               as_array_object *array = dynamic_cast<as_array_object*> (obj);
-               array->resize(asize);
+               as_array_object *arr = new as_array_object;
+               arr->resize(asize);
                uint32_t i = asize;
                while (i--)
-                       array->set_indexed(i, mStack.value(i));
+                       arr->set_indexed(i, mStack.value(i));
                mStack.drop(asize - 1);
-               mStack.top(0) = array;
+               mStack.top(0) = arr;
                break;
        }
 /// 0x57 ABC_ACTION_NEWACTIVATION
@@ -1252,9 +1297,12 @@
        {
                uint32_t cid = mStream->read_V32();
                asClass *c = pool_class(cid, mPoolObject);
-               asMethod *m = c->getConstructor();
-               Property b; //TODO: asBinding b(m);
-               pushCall(1, &mStack.top(0), &b);
+               ENSURE_OBJECT(mStack.top(0));
+               as_object *obj = mStack.top(0).to_object().get();
+               as_function *func = c->getConstructor()->getPrototype();
+               // func is the constructor, obj is 'this' and also the return
+               // value, no arguments, no change in stack.
+               pushCall(func, obj, mStack.top(0), 0, 0);
                break;
        }
 /// 0x59 ABC_ACTION_GETDESCENDANTS
@@ -1301,16 +1349,19 @@
        {
                asName a = pool_name(mStream->read_V32(), mPoolObject);
                mStack.drop(completeName(a));
-               Property *b = NULL; //TODO: asBinding *b = findProperty(a);
-               if (0)//!b)
+               as_object *owner;
+               Property *b = mCurrentScope->findProperty(a.getName(), 
+                       a.getNamespace()->getURI(), &owner);
+               if (!b)
+               {
                        if (opcode == SWF::ABC_ACTION_FINDPROPSTRICT)
                                throw ASReferenceError();
                        else
                                mStack.push(as_value());
+               }
                else
                {
-                       mStack.push(as_value());
-                       pushCall(0, &mStack.top(0), b);
+                       mStack.push(owner);
                }
                break;
        }
@@ -1333,13 +1384,14 @@
        case SWF::ABC_ACTION_GETLEX:
        {
                asName a = pool_name(mStream->read_V32(), mPoolObject);
-               // The name is expected to be complete.
-               Property *b = NULL; //TODO: asBinding *b = findProperty(a);
-               if (0)//!b)
-                       throw ASReferenceError();
-               //TODO: b->setLexOnly(b);
+               as_object *owner;
+               Property *b = mCurrentScope->findProperty(a.getName(),
+                       a.getNamespace()->getURI(), &owner);
+               if (!b)
+                       throw ASException();
+
                mStack.grow(1);
-               pushCall(0, &mStack.top(0), b);
+               pushGet(owner, mStack.top(0), b);
                break;
        }
 /// 0x61 ABC_ACTION_SETPROPERTY
@@ -2242,13 +2294,7 @@
 {
        if (!instance.is_object())
                throw ASTypeError();
-
-       return; // TODO:
 #if 0
-       asBinding *pBinding = pDefinition->getBinding(name.getName());
-       if (pBinding->isWriteOnly())
-               throw ASReferenceError();
-
        if (!pBinding->isGetSet())
        {
                //TODO: mStack.push(pBinding->getFromInstance(instance));
@@ -2340,89 +2386,76 @@
 }
 
 void
-Machine::immediateFunction(as_function *to_call, as_value& storage,
-       as_object *pThis)
+Machine::immediateFunction(const as_function *to_call, as_object *pThis,
+       as_value& storage, unsigned char stack_in, short stack_out)
 {
-       // TODO: Implement
+       // TODO: Set up the fn, or remove the need.
+       fn_call fn(NULL, NULL, 0, 0);
+       mStack.drop(stack_in - stack_out);
+       saveState();
+       mThis = pThis;
+       mStack.grow(stack_in - stack_out);
+       mStack.setDownstop(stack_in);
+       storage = const_cast<as_function*>(to_call)->call(fn);
+       restoreState();
 }
 
 void
-Machine::immediateProcedure(as_function *to_call, as_object *pthis,
-       const as_value *stackAdditions, unsigned int stackAdditionsCount)
+Machine::pushGet(as_object *this_obj, as_value &return_slot, Property *prop)
 {
-       // TODO: Implement
+       if (!prop)
+               return;
+
+       if (prop->isGetterSetter())
+       {
+               //TODO pushCall(prop->getGetter(), this_obj, return_slot, 0);
+               return;
+       }
+
+       return_slot = prop->getValue(*this_obj);
 }
 
 void
-Machine::pushCall(unsigned int stack_in, as_value *return_slot,
-       Property *pBind)
+Machine::pushSet(as_object *this_obj, as_value &value, Property *prop)
 {
-       if (!pBind)
+       if (!prop)
                return;
-       //TODO
-#if 0
-       switch (pBind->mType)
+
+       if (prop->isGetterSetter())
        {
-       default:
-       case asBinding::T_ACCESS:
-       case asBinding::T_CLASS:
-               throw ASException();
-               return;
-       case asBinding::T_VALUE:
-               *return_slot = pBind->getValue()->getCurrentValue();
+               mStack.push(value);
+               //TODO pushCall(prop->getSetter(), this_obj, mIgnoreReturn, 1);
                return;
-       case asBinding::T_METHOD:
-               break;
        }
 
-       asMethod *m = pBind->getMethod();
+       prop->setValue(*this_obj, value);
+}
 
-       if (!(m->isNative() || m->hasBody()))
-               throw ASException();
+void
+Machine::pushCall(as_function *func, as_object *pthis, as_value& return_slot,
+       unsigned char stack_in, short stack_out)
+{
+       if (1 || func->isBuiltin())
+       {
+               immediateFunction(func, pthis, return_slot, stack_in, 
stack_out);
+               return;
+       }
+       // TODO: Make this work for stackless.
 
        // Here is where the SafeStack shines:
        // We set the stack the way it should be on return.
-       // If the return slot is the deepest parameter, leave room for it.
-       if (stack_in && (return_slot == &mStack.top(stack_in - 1)))
-               mStack.drop(stack_in - 1);
-       else // The return slot is somewhere else.
-               mStack.drop(stack_in);
+       mStack.drop(stack_in - stack_out);
        // We save that state.
        saveState();
-       // Set the 'this' object for the new call.
-       if (stack_in == 0)
-               mThis = mDefaultThis;
-       else
-               mThis = mStack.value(0).to_object().get(); // Checked in caller.
-       // We make the stack appear empty.
-       mStack.fixDownstop();
-       // We grow to reclaim the parameters. Since this is a SafeStack, they
-       // were not lost.
-       mStack.grow(stack_in);
-
-       // Native functions have to be called now.
-       if (m->isNative())
-       {
-               //TODO: return_slot = m->CallNative(mStack, mGlobalScope);
-               restoreState();
-               return;
-       }
-
-       // The scope stack should be fixed for non-native calls.
-       mScopeStack.fixDownstop();
-       //TODO: mScopeStack.push(m->getActivation());
-       if (!mScopeStack.empty())
-               mCurrentScope = mScopeStack.top(0).mScope;
-       else
-               mCurrentScope = NULL;
-
-       // We set the stream and return as given in the method and call.
-       //TODO: mStream = m->getBody();
-       mGlobalReturn = return_slot;
+       // Set the 'this' for the new call
+       mThis = pthis;
+       // Retrieve the stack. (It wasn't lost)
+       mStack.grow(stack_in - stack_out);
+       // And then we set the downstop
+       mStack.setDownstop(stack_in);
 
        // When control goes to the main loop of the interpreter, it will
        // automatically start executing the method.
-#endif
 }
 
 void

Index: server/vm/SafeStack.h
===================================================================
RCS file: /sources/gnash/gnash/server/vm/SafeStack.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- server/vm/SafeStack.h       18 Oct 2007 11:47:56 -0000      1.4
+++ server/vm/SafeStack.h       29 Oct 2007 21:07:34 -0000      1.5
@@ -1,3 +1,7 @@
+// SafeStack.h A stack which doesn't drop or free references until explicitly
+// asked to do so, so that values outside of the stack are guaranteed good
+// in an appropriate scope.
+//
 //   Copyright (C) 2007 Free Software Foundation, Inc.
 // 
 // This program is free software; you can redistribute it and/or modify

Index: server/vm/CodeStream.h
===================================================================
RCS file: /sources/gnash/gnash/server/vm/CodeStream.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- server/vm/CodeStream.h      8 Oct 2007 06:55:11 -0000       1.2
+++ server/vm/CodeStream.h      29 Oct 2007 21:07:34 -0000      1.3
@@ -1,3 +1,5 @@
+// CodeStream.h A class which allows bounds-checked reading from a char array
+//
 //   Copyright (C) 2007 Free Software Foundation, Inc.
 // 
 // This program is free software; you can redistribute it and/or modify

Index: testsuite/actionscript.all/Date.as
===================================================================
RCS file: /sources/gnash/gnash/testsuite/actionscript.all/Date.as,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -b -r1.32 -r1.33
--- testsuite/actionscript.all/Date.as  26 Oct 2007 08:26:54 -0000      1.32
+++ testsuite/actionscript.all/Date.as  29 Oct 2007 21:07:34 -0000      1.33
@@ -21,7 +21,7 @@
 // compile this test case with Ming makeswf, and then
 // execute it like this gnash -1 -r 0 -v out.swf
 
-rcsid="$Id: Date.as,v 1.32 2007/10/26 08:26:54 strk Exp $";
+rcsid="$Id: Date.as,v 1.33 2007/10/29 21:07:34 cmusick Exp $";
 
 #include "check.as"
 
@@ -532,8 +532,9 @@
  check_equals(foo.indexOf("Feb"), 8);
 #else
  check_equals(typeof(bar), 'number');
- // correct: "foo 950569200000"
- check_equals(foo.substring(0, 10), 'foo 950569');
+ // correct: "foo 950569200000", but only for the timezone
+ // of the original author
+ check_equals(foo.substring(0, 7), 'foo 950');
 #endif
 
 totals();




reply via email to

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