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