Gnash
0.8.10
|
00001 // Machine.h A VM to run AS3 code, and AS2 code in the future. 00002 // 00003 // Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 00004 // Free Software Foundation, Inc. 00005 // 00006 // This program is free software; you can redistribute it and/or modify 00007 // it under the terms of the GNU General Public License as published by 00008 // the Free Software Foundation; either version 3 of the License, or 00009 // (at your option) any later version. 00010 // 00011 // This program is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 // 00016 // You should have received a copy of the GNU General Public License 00017 // along with this program; if not, write to the Free Software 00018 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00019 00020 #ifndef GNASH_MACHINE_H 00021 #define GNASH_MACHINE_H 00022 00023 #include <string> 00024 #include <vector> 00025 #include "SafeStack.h" 00026 #include "as_value.h" 00027 #include "log.h" 00028 00029 namespace gnash { 00030 namespace abc { 00031 class AbcBlock; 00032 class MultiName; 00033 class Class; 00034 class abc_function; 00035 class Method; 00036 class Namespace; 00037 } 00038 class Global_as; 00039 class DisplayObject; 00040 class as_object; 00041 class Property; 00042 class CodeStream; 00043 class VM; 00044 template <typename T> class FunctionArgs; 00045 class string_table; 00046 } 00047 00048 00049 namespace gnash { 00050 00051 namespace abc { 00052 00054 // 00073 class Machine 00074 { 00075 public: 00076 00078 Machine(VM& vm); 00079 00081 // 00088 // 00090 void init(); 00091 00092 00093 // Flash specific members. 00095 DisplayObject *getTarget(); 00096 00099 void setTarget(DisplayObject* target); 00100 00115 int completeName(MultiName& name, int initial = 0); 00116 00127 Class* findSuper(as_value& obj, bool find_primitive); 00128 00145 void getMember(Class* pDefinition, MultiName& name, as_value& source); 00146 00163 void setMember(Class*, MultiName&, as_value& target, as_value& val); 00164 00165 Property* findProperty(MultiName&) { return NULL; } 00166 00167 void execute(); 00168 00188 void pushGet(as_object *this_obj, as_value& return_slot, Property *prop); 00189 00204 void pushSet(as_object *this_obj, as_value& value, Property *prop); 00205 00231 void pushCall(as_function *func, as_object *pThis, as_value& return_slot, 00232 unsigned char stack_in, short stack_out); 00233 00234 void immediateFunction(const as_function *to_call, as_object* pThis, 00235 as_value& storage, unsigned char stack_in, short stack_out); 00236 00237 void immediateProcedure(const as_function *to_call, as_object *pthis, 00238 unsigned char stack_in, short stack_out) { 00239 immediateFunction(to_call, pthis, mIgnoreReturn, stack_in, stack_out); 00240 } 00241 00242 void initMachine(AbcBlock* pool_block); 00243 00244 as_value executeFunction(Method* function, const fn_call& fn); 00245 00246 void instantiateClass(std::string className, as_object* global); 00248 // 00253 Global_as* global(); 00254 00255 void markReachableResources() const; 00256 00257 private: 00259 class State 00260 { 00261 public: 00262 unsigned int _stackDepth; 00263 unsigned int _stackTotalSize; 00264 unsigned int _scopeStackDepth; 00265 unsigned int mScopeTotalSize; 00266 bool mReturn; 00267 CodeStream *mStream; 00268 Namespace *mDefaultXMLNamespace; 00269 as_object *mCurrentScope; 00270 as_value *mGlobalReturn; 00271 as_object *mThis; 00272 std::vector<as_value> _registers; 00273 abc_function* mFunction; 00274 void to_debug_string(){ 00275 log_abc("StackDepth=%u StackTotalSize=%u ScopeStackDepth=%u ScopeTotalSize=%u",_stackDepth,_stackTotalSize,_scopeStackDepth,mScopeTotalSize); 00276 00277 } 00278 }; 00279 00280 class Scope 00281 { 00282 public: 00283 unsigned int mHeightAfterPop; 00284 as_object *mScope; 00285 00286 Scope() : mHeightAfterPop(0), mScope(NULL) {} 00287 Scope(unsigned int i, as_object *o) : mHeightAfterPop(i), 00288 mScope(o) 00289 {} 00290 }; 00291 00292 void saveState(); 00293 void restoreState(); 00294 00295 as_value find_prop_strict(MultiName multiname); 00296 00297 void print_stack(); 00298 00299 void print_scope_stack(); 00300 00301 void get_args(size_t argc, FunctionArgs<as_value>& args); 00302 00303 void load_function(CodeStream* stream, boost::uint32_t maxRegisters); 00304 00305 void executeCodeblock(CodeStream* stream); 00306 00307 void clearRegisters(boost::uint32_t maxRegsiters); 00308 00309 const as_value& getRegister(int index){ 00310 log_abc("Getting value at a register %d ", index); 00311 return _registers[index]; 00312 } 00313 00314 void setRegister(size_t index, const as_value& val) { 00315 log_abc("Putting %s in register %s", val, index); 00316 if (_registers.size() <= index) { 00317 log_abc("Register doesn't exist! Adding new registers!"); 00318 _registers.resize(index + 1); 00319 } 00320 _registers[index] = val; 00321 } 00322 00323 void push_stack(as_value object){ 00324 log_abc("Pushing value %s onto stack.", object); 00325 _stack.push(object); 00326 } 00327 00328 as_value pop_stack(){ 00329 as_value value = _stack.pop(); 00330 log_abc("Popping value %s off the stack.", value); 00331 return value; 00332 } 00333 00334 void push_scope_stack(as_value object); 00335 00336 as_object* pop_scope_stack() { 00337 log_abc("Popping value %s off the scope stack. There will be " 00338 "%u items left.", as_value(_scopeStack.top(0)), 00339 _scopeStack.size()-1); 00340 return _scopeStack.pop(); 00341 } 00342 00343 as_object* get_scope_stack(boost::uint8_t depth) const { 00344 log_abc("Getting value from scope stack %u from the bottom.", 00345 depth | 0x0); 00346 return _scopeStack.value(depth); 00347 } 00348 00349 SafeStack<as_value> _stack; 00350 SafeStack<State> mStateStack; 00351 std::vector<as_value> _registers; 00352 00354 // 00361 SafeStack<as_object*> _scopeStack; 00362 00363 CodeStream *mStream; 00364 00365 string_table& mST; 00366 00367 Namespace* mDefaultXMLNamespace; 00368 as_object* mCurrentScope; 00369 as_object* mGlobalScope; 00370 as_object* mDefaultThis; 00371 as_object* mThis; 00372 00374 Global_as* _global; 00375 00376 as_value mGlobalReturn; 00377 as_value mIgnoreReturn; // Throw away returns go here. 00378 00379 bool mExitWithReturn; 00380 AbcBlock* mPoolObject; // Where all of the pools are stored. 00381 00382 abc_function* mCurrentFunction; 00383 00384 VM& _vm; 00385 }; 00386 } // namespace abc 00387 } // namespace gnash 00388 #endif