[Top][All Lists]
[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;
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] gnash ChangeLog server/vm/Machine.h server/vm/A...,
Chad Musick <=