1
// Machine.h A VM to run AS3 code, and AS2 code in the future.
3
// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
5
// This program is free software; you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation; either version 3 of the License, or
8
// (at your option) any later version.
10
// This program is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
// GNU General Public License for more details.
15
// You should have received a copy of the GNU General Public License
16
// along with this program; if not, write to the Free Software
17
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
#ifndef GNASH_MACHINE_H
20
#define GNASH_MACHINE_H
24
#include "SafeStack.h"
37
/// This machine is intended to work without relying on the C++ call stack,
38
/// by resetting its Stream and Stack members (actually, by limiting the stack)
39
/// to make function calls, rather than calling them directly in C++.
40
/// As a result, many of the internal calls are void functions even though they
41
/// will be returning some value.
42
/// The exception to this is that C++ native functions defined in ActionScript
43
/// objects will be called in the typical way.
45
/// The C++ exceptions mechanism is used for exception handling, since this
46
/// allows both ActionScript code and C++ code to use the exception handling
47
/// with a minimum of hassle, and it helps with correctness.
49
/// The intent is that the machine will run both AS2 and AS3 code. Despite the
50
/// difference in presentation between the two, they should be compatible (or
51
/// able to become so), so that extensions written for AS2 will work in AS3
56
// Flash specific members.
57
/// The character which initiated these actions.
58
character *getTarget();
60
/// Set the character which initiated the actions.
62
void setTarget(character* target);
64
/// This will complete a name in AS3, where a part of the name
65
/// is stored in the stream and another part may be stored on
69
/// A partially filled asBoundName, this should be the id
73
/// The depth in the stack where the stack objects may be found.
76
/// The number of stack elements used by the name.
77
/// At present, always 0, 1, or 2. These are not dropped.
78
int completeName(asName& name, int initial = 0);
80
/// Given a value v, find the class object of the superclass of v.
83
/// The object whose superclass is desired.
85
/// @param find_primitive
86
/// If true, the ActionScript prototype will be found for primitive values.
89
/// Null if the superclass was not found, or the superclass.
90
asClass* findSuper(as_value& obj, bool find_primitive);
92
/// Get a member from an object.
94
/// @param pDefinition
95
/// The definition of the class which is to be used. This should be the
96
/// one which has the property.
99
/// The bound name of the member
102
/// The source object -- the specific instance of the pDefinition class.
105
/// This returns the value, but on the stack.
106
/// (Since the return value is not known until after control has left
107
/// the caller of this, it's impossible to return a meaningful value.
108
void getMember(asClass* pDefinition, asName& name, as_value& source);
110
/// Set a member in an object.
112
/// @param pDefinition
113
/// The definition of the class which is to be used.
116
/// The bound name of the member
119
/// The source object -- where the instance should be set
126
void setMember(asClass*, asName&, as_value& target, as_value& val);
128
asBinding* findProperty(asName&) { return NULL; }
132
/// push a get call to be executed next.
134
/// Any Property can be pushed, and it will put an appropriate value
135
/// into return_slot. This ensures that getter properties
136
/// can be accessed in the same way as other properties, and hides
137
/// the difference between ActionScript methods and native C++ methods.
140
/// The 'this' to use for a getter/setter if it exists.
142
/// @param return_slot
143
/// A space for the return value. An assignment will always be made here,
144
/// but mVoidSlot can be used for values that will be discarded.
147
/// The property. If this is a value, it simply returns that value in
148
/// the return_slot immediately. Otherwise, it may immediately call
149
/// the gettter or it may push that onto the call stack and transfer
150
/// control. Callers can be agnostic as to which happens.
151
void pushGet(as_object *this_obj, as_value& return_slot, Property *prop);
153
/// push a set call to be executed next.
155
/// Any Property can be pushed, and it will set the property, if possible.
156
/// setter properties and simple properties alike will be handled by this.
159
/// The 'this' to use for a getter/setter if it exists.
162
/// The value which should be set
165
/// The property desired to be set.
167
void pushSet(as_object *this_obj, as_value& value, Property *prop);
169
/// push a call to be executed next
171
/// Push a call to be executed as soon as execution of the current opcode
172
/// finishes. At the end, transfer will return to the previous context.
175
/// The function to call
178
/// The object to act as the 'this' pointer.
180
/// @param return_slot
181
/// The slot to use for returns. Use mIgnoreReturn if you don't care
182
/// what happens here.
185
/// How many of the values on the stack are for the new context
188
/// How much of the stack should be left behind when the function exits.
189
/// For example: 0 will leave a stack which is stack_in shorter than it
190
/// was on call. 1 will leave a stack which is 1 taller than it was on
193
/// RESTRICTION: stack_in - stack_out must not be negative
194
void pushCall(as_function *func, as_object *pThis, as_value& return_slot,
195
unsigned char stack_in, short stack_out);
197
void immediateFunction(const as_function *to_call, as_object* pThis,
198
as_value& storage, unsigned char stack_in, short stack_out);
200
void immediateProcedure(const as_function *to_call, as_object *pthis,
201
unsigned char stack_in, short stack_out)
202
{ immediateFunction(to_call, pthis, mIgnoreReturn, stack_in, stack_out); }
204
Machine(string_table &ST, ClassHierarchy *CH);
207
/// The state of the machine.
211
unsigned int mStackDepth;
212
unsigned int mStackTotalSize;
213
unsigned int mScopeStackDepth;
214
unsigned int mScopeTotalSize;
216
asNamespace *mDefaultXMLNamespace;
217
as_object *mCurrentScope;
218
as_value *mGlobalReturn;
225
unsigned int mHeightAfterPop;
228
Scope() : mHeightAfterPop(0), mScope(NULL) {/**/}
229
Scope(unsigned int i, as_object *o) : mHeightAfterPop(i),
237
SafeStack<as_value> mStack;
238
SafeStack<State> mStateStack;
239
SafeStack<Scope> mScopeStack;
240
SafeStack<as_value> mFrame;
246
asNamespace* mDefaultXMLNamespace;
247
as_object* mCurrentScope;
248
as_object* mGlobalScope;
249
as_object* mDefaultThis;
252
as_value *mGlobalReturn;
253
as_value mIgnoreReturn; // Throw away returns go here.
255
bool mIsAS3; // Is the stream an AS3 stream.
256
abc_block* mPoolObject; // Where all of the pools are stored.
260
#endif /* GNASH_MACHINE_H */