gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] gnash ChangeLog server/vm/Machine.h server/vm/A...


From: Chad Musick
Subject: [Gnash-commit] gnash ChangeLog server/vm/Machine.h server/vm/A...
Date: Fri, 05 Oct 2007 17:48:17 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Chad Musick <cmusick>   07/10/05 17:48:17

Modified files:
        .              : ChangeLog 
        server/vm      : Machine.h AbcHandlers.cpp 

Log message:
        More work on AS3.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.4540&r2=1.4541
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/Machine.h?cvsroot=gnash&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/AbcHandlers.cpp?cvsroot=gnash&r1=1.3&r2=1.4

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.4540
retrieving revision 1.4541
diff -u -b -r1.4540 -r1.4541
--- ChangeLog   5 Oct 2007 15:08:12 -0000       1.4540
+++ ChangeLog   5 Oct 2007 17:48:16 -0000       1.4541
@@ -1,4 +1,10 @@
 2007-10-06 Chad Musick <address@hidden>
+       * server/vm/Machine.h: More comments about functions, some
+         signature corrections.
+       * server/vm/AbcHandlers.cpp: Definition of some of the necessary
+         support functions.
+
+2007-10-06 Chad Musick <address@hidden>
 
        * server/vm/Machine.h: New File. First iteration (not documented,
          not compilable) of class definition for VM for ActionScript3

Index: server/vm/Machine.h
===================================================================
RCS file: /sources/gnash/gnash/server/vm/Machine.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- server/vm/Machine.h 5 Oct 2007 15:08:12 -0000       1.1
+++ server/vm/Machine.h 5 Oct 2007 17:48:16 -0000       1.2
@@ -131,6 +131,22 @@
        Stack<as_value> *mStack;
 };
 
+/// This machine is intended to work without relying on the C++ call stack,
+/// by resetting its Stream and Stack members (actually, by limiting the stack)
+/// to make function calls, rather than calling them directly in C++.
+/// As a result, many of the internal calls are void functions even though they
+/// will be returning some value.
+/// The exception to this is that C++ native functions defined in ActionScript
+/// objects will be called in the typical way.
+///
+/// The C++ exceptions mechanism is used for exception handling, since this
+/// allows both ActionScript code and C++ code to use the exception handling
+/// with a minimum of hassle, and it helps with correctness.
+///
+/// The intent is that the machine will run both AS2 and AS3 code. Despite the
+/// difference in presentation between the two, they should be compatible (or
+/// able to become so), so that extensions written for AS2 will work in AS3
+/// (and vice versa).
 class Machine
 {
 public:
@@ -142,21 +158,78 @@
        /// Not null.
        void setTarget(character* target);
 
-       void completeName(asBindingName&);
+       /// This will complete a name in AS3, where a part of the name
+       /// is stored in the stream and another part may be stored on
+       /// the stack.
+       ///
+       /// @param name
+       /// A partially filled asBoundName, this should be the id
+       /// from the stream.
+       ///
+       /// @param initial
+       /// The depth in the stack where the stack objects may be found.
+       ///
+       /// @return
+       /// The number of stack elements used by the name.
+       /// At present, always 0, 1, or 2. These are not dropped.
+       int completeName(asBoundName& name, int initial = 0);
+
+       /// Given a value v, find the class object of the superclass of v.
+       ///
+       /// @param obj
+       /// The object whose superclass is desired.
+       ///
+       /// @param find_primitive
+       /// If true, the ActionScript prototype will be find for primitive 
values.
+       ///
+       /// @return
+       /// Null if the superclass was not found, or the superclass.
+       asClass* findSuper(as_value& obj, bool find_primitive);
+
+       /// Get a member from an object.
+       ///
+       /// @param pDefinition
+       /// The definition of the class which is to be used. This should be the
+       /// one which has the property.
+       ///
+       /// @param name
+       /// The bound name of the member
+       ///
+       /// @param source
+       /// The source object -- the specific instance of the pDefinition class.
+       ///
+       /// @return
+       /// This returns the value, but on the stack.
+       /// (Since the return value is not known until after control has left
+       /// the caller of this, it's impossible to return a meaningful value.
+       void getMember(asClass* pDefinition, asBoundName& name, as_value& 
source);
+
+       /// Set a member in an object.
+       ///
+       /// @param pDefinition
+       /// The definition of the class which is to be used.
+       ///
+       /// @param name
+       /// The bound name of the member
+       ///
+       /// @param source
+       /// The source object -- where the instance should be set
+       ///
+       /// @param newvalue
+       /// The new value
+       ///
+       /// @return
+       /// Nothing.
+       void setMember(asClass*, asBoundName&, as_value& target, as_value& val);
 
-       asClass* findSuper(as_value&, bool);
-
-       as_value getMember(asClass*, asBindingName&, as_value&);
-       bool setMember(asClass*, asBindingName&, as_value& target, as_value& 
val);
-
-       std::string pool_string(uint32_t);
+       std::string& pool_string(uint32_t);
        int pool_int(uint32_t);
        unsigned int pool_uint(uint32_t);
        double pool_double(uint32_t);
        asNamespace* pool_namespace(uint32_t);
        asMethod* pool_method(uint32_t);
 
-       as_value(v) findProperty(asBindingName&);
+       as_value findProperty(asBoundName&);
 
        void pushScope(asScope*);
        asScope* popScope();
@@ -165,6 +238,8 @@
 
        void execute_as2();
 
+       void pushCall(int param_count, int return_count, asMethod *pMethod);
+
 private:
        Stack<as_value> mStack;
        Stack<FunctionEntry> mCallStack;

Index: server/vm/AbcHandlers.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/vm/AbcHandlers.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- server/vm/AbcHandlers.cpp   5 Oct 2007 15:08:12 -0000       1.3
+++ server/vm/AbcHandlers.cpp   5 Oct 2007 17:48:16 -0000       1.4
@@ -61,15 +61,15 @@
                // Get the name.
                asName a = mStream.read_V32();
                // Finish it, if necessary.
-               completeName(a);
+               mStack.drop(completeName(a));
                // Get the target object.
                as_value vobj& = mStack.top(0);
                asClass *pClass = findSuper(vobj, true);
                // If we don't have a class yet, throw.
                if (!pClass)
                        throw ASReferenceError();
-               // getMember will throw any necessary exceptions.
-               mStack.top(0) = getMember(pClass, a, vobj);
+               // getMember will throw any necessary exceptions and do the 
push.
+               getMember(pClass, a, vobj);
                break;
        }
 /// 0x05 ABC_ACTION_SETSUPER
@@ -87,7 +87,7 @@
                asName a = mStream.read_V32();
                as_value vobj = mStack.pop(); // The value
 
-               completeName(a);
+               mStack.drop(completeName(a));
 
                as_value target = mStack.pop();
                asClass *pClass = findSuper(target, true);
@@ -760,7 +760,7 @@
        case SWF::ABC_ACTION_CALLSUPERVOID:
        {
                asName a = mStream.read_V32();
-               completeName(a);
+               mStack.drop(completeName(a));
        
                mStack.top(argc) = mStack.top(argc).get_named_super(a)
                        .call_function(mStack.top(argc - 1));
@@ -956,7 +956,7 @@
        case SWF::ABC_ACTION_FINDPROPERTY:
        {
                asName a = mStream.read_V32();
-               completeName(a);
+               mStack.drop(completeName(a));
                as_value v = findProperty(a);
                if ((opcode == SWF::ABC_ACTION_FINDPROPSTRICT) && 
v.is_undefined())
                        throw ASReferenceException();
@@ -1016,7 +1016,7 @@
                        if (a.isRtns() || !(mStack.top(0).is_object()
                                && mStack.top(1).is_dictionary()))
                        {
-                               completeName(a);
+                               mStack.drop(completeName(a));
                                mStack.top(0).setProperty(a, v);
                                mStack.drop(1);
                        }
@@ -1094,7 +1094,7 @@
                        if (a.isRtns() || !(mStack.top(0).is_object()
                                && mStack.top(1).is_dictionary()))
                        {
-                               completeName(a);
+                               mStack.drop(completeName(a));
                                mStack.top(0) = mStack.top(0).getProperty(a);
                        }
                        else
@@ -1119,7 +1119,7 @@
        {
                asName a = mStream.read_V32();
                as_value& v = mStack.pop();
-               completeName(a);
+               mStack.drop(completeName(a));
                mStack.pop().to_object().setProperty(a, v, true); // true for 
init
                break;
        }
@@ -1133,7 +1133,7 @@
        case SWF::ABC_ACTION_DELETEPROPERTY:
        {
                asName a = mStream.read_V32();
-               completeName(a);
+               mStack.drop(completeName(a));
                mStack.top(0) = mStack.top(0).deleteProperty(a);
                break;
        }
@@ -1317,7 +1317,7 @@
        case SWF::ABC_ACTION_COERCE:
        {
                asName a = mStream.read_V32();
-               completeName(a);
+               mStack.drop(completeName(a));
                mStack.top(0) = mStack.top(0).coerce(a);
                break;
        }
@@ -1354,7 +1354,7 @@
        case SWF::ABC_ACTION_ASTYPE:
        {
                asName a = mStream.read_V32();
-               completeName(a);
+               mStack.drop(completeName(a));
                if (!mStack.top(0).conforms_to(a)
                        mStack.top(0).set_null();
                break;
@@ -1696,7 +1696,7 @@
        case SWF::ABC_ACTION_ISTYPE:
        {
                asName a = mStream.read_V32();
-               completeName(a);
+               mStack.drop(completeName(a));
                mStack.top(0).set_bool(mStack.top(0).conforms_to(a));
        }
 /// 0xB3 ABC_ACTION_ISTYPELATE
@@ -1859,9 +1859,77 @@
        } // end of main loop
 } // end of execute function
 
-/// Given a value v, find the class object of the superclass of v.
-/// If find_for_primitive is true, then, for example, The value
-/// 1 (a number) will return the Number class object.
+void
+ActionMachine::getMember(asClass* pDefinition, asBoundName& name,
+       as_value& instance)
+{
+       if (!instance.is_object())
+               throw ASTypeError();
+
+       asBinding *pBinding = pDefinition->findMember(name);
+       if (pBinding->isWriteOnly())
+               throw ASReferenceError();
+
+       if (!pBinding->isGetSet())
+       {
+               mStack.push(pBinding->getFromInstance(instance));
+               return;
+       }
+
+       // This is a getter, so we need to execute it. Even those
+       // written in C++ get called like this, with pushCall handling.
+       // 1 parameter (the source), 1 value expected back.
+       mStack.push(instance);
+       pushCall(1, 1, pBinding->getGetter());
+}
+
+void
+ActionMachine::setMember(asClass *pDefinition, asBoundName& name,
+       as_value& instance, as_value& newvalue)
+{
+       if (!instance.is_object())
+               throw ReferenceError();
+
+       asBinding *pBinding = pDefinition->findMember(name);
+       if (pBinding->isReadOnly())
+               throw ASReferenceError();
+
+       if (!pBinding->isGetSet())
+       {
+               pBinding->setInInstance(instance, newvalue);
+               return;
+       }
+
+       // Two parameters -- the target object, the value to set.
+       mStack.push(instance);
+       mStack.push(newvalue);
+       pushCall(2, 0, pBinding->getSetter());
+}
+
+int
+ActionMachine::completeName(asBoundName &name, int offset)
+{
+       int size = 0;
+
+       asUnboundName* uname = mNamePool.at(name.id);
+       if (uname->isRuntime())
+       {
+               as_value obj = mStack.top(offset);
+               if (obj.is_object() && obj.to_object()->isQName())
+                       name.fill(obj.to_object());
+               ++size;
+
+               if (uname->isRuntimeNamespace())
+                       ++size; // Ignore the Namespace.
+       }
+       else if (uname->isRuntimeNamespace())
+       {
+               uname->setNamespace(mStack.top(offset);
+               ++size;
+       }
+       return size;
+}
+
 asClass *
 ActionMachine::findSuper(as_value &v, bool find_for_primitive)
 {
@@ -1880,6 +1948,7 @@
        }
 
        // And so on...
+       // TODO: Other primitives
        return NULL;
 }
 




reply via email to

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