ScummVM API documentation
sqvm.h
1 /* see copyright notice in squirrel.h */
2 #ifndef _SQVM_H_
3 #define _SQVM_H_
4 
5 #include "sqopcodes.h"
6 #include "sqobject.h"
7 #define MAX_NATIVE_CALLS 100
8 #define MIN_STACK_OVERHEAD 15
9 
10 #define SQ_SUSPEND_FLAG -666
11 #define SQ_TAILCALL_FLAG -777
12 #define DONT_FALL_BACK 666
13 //#define EXISTS_FALL_BACK -1
14 
15 #define GET_FLAG_RAW 0x00000001
16 #define GET_FLAG_DO_NOT_RAISE_ERROR 0x00000002
17 //base lib
18 void sq_base_register(HSQUIRRELVM v);
19 
21  SQExceptionTrap() : _stackbase(0), _stacksize(0), _ip(nullptr), _extarget(0) {}
22  SQExceptionTrap(SQInteger ss, SQInteger stackbase,SQInstruction *ip, SQInteger ex_target){ _stacksize = ss; _stackbase = stackbase; _ip = ip; _extarget = ex_target;}
23  SQInteger _stackbase;
24  SQInteger _stacksize;
25  SQInstruction *_ip;
26  SQInteger _extarget;
27 };
28 
29 #define _INLINE
30 
32 
33 struct SQVM : public CHAINABLE_OBJ
34 {
35  struct CallInfo{
36  //CallInfo() { _generator = NULL;}
37  SQInstruction *_ip;
38  SQObjectPtr *_literals;
39  SQObjectPtr _closure;
40  SQGenerator *_generator;
41  SQInt32 _etraps;
42  SQInt32 _prevstkbase;
43  SQInt32 _prevtop;
44  SQInt32 _target;
45  SQInt32 _ncalls;
46  SQBool _root;
47  };
48 
50 public:
51  void DebugHookProxy(SQInteger type, const SQChar * sourcename, SQInteger line, const SQChar * funcname);
52  static void _DebugHookProxy(HSQUIRRELVM v, SQInteger type, const SQChar * sourcename, SQInteger line, const SQChar * funcname);
53  enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM,ET_RESUME_THROW_VM };
54  SQVM(SQSharedState *ss);
55  ~SQVM();
56  bool Init(SQVM *friendvm, SQInteger stacksize);
57  bool Execute(SQObjectPtr &func, SQInteger nargs, SQInteger stackbase, SQObjectPtr &outres, SQBool raiseerror, ExecutionType et = ET_CALL);
58  //starts a native call return when the NATIVE closure returns
59  bool CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger newbase, SQObjectPtr &retval, SQInt32 target, bool &suspend,bool &tailcall);
60  bool TailCall(SQClosure *closure, SQInteger firstparam, SQInteger nparams);
61  //starts a SQUIRREL call in the same "Execution loop"
62  bool StartCall(SQClosure *closure, SQInteger target, SQInteger nargs, SQInteger stackbase, bool tailcall);
63  bool CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor);
64  //call a generic closure pure SQUIRREL or NATIVE
65  bool Call(SQObjectPtr &closure, SQInteger nparams, SQInteger stackbase, SQObjectPtr &outres,SQBool raiseerror);
66  SQRESULT Suspend();
67 
68  void CallDebugHook(SQInteger type,SQInteger forcedline=0);
69  void CallErrorHandler(SQObjectPtr &e);
70  bool Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, SQUnsignedInteger getflags, SQInteger selfidx);
71  SQInteger FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest);
72  bool InvokeDefaultDelegate(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest);
73  bool Set(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val, SQInteger selfidx);
74  SQInteger FallBackSet(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val);
75  bool NewSlot(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val,bool bstatic);
76  bool NewSlotA(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,const SQObjectPtr &attrs,bool bstatic,bool raw);
77  bool DeleteSlot(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &res);
78  bool Clone(const SQObjectPtr &self, SQObjectPtr &target);
79  bool ObjCmp(const SQObjectPtr &o1, const SQObjectPtr &o2,SQInteger &res);
80  bool StringCat(const SQObjectPtr &str, const SQObjectPtr &obj, SQObjectPtr &dest);
81  static bool IsEqual(const SQObjectPtr &o1,const SQObjectPtr &o2,bool &res);
82  bool ToString(const SQObjectPtr &o,SQObjectPtr &res);
83  SQString *PrintObjVal(const SQObjectPtr &o);
84 
85 
86  void Raise_Error(const SQChar *s, ...);
87  void Raise_Error(const SQObjectPtr &desc);
88  void Raise_IdxError(const SQObjectPtr &o);
89  void Raise_CompareError(const SQObject &o1, const SQObject &o2);
90  void Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type);
91 
92  void FindOuter(SQObjectPtr &target, SQObjectPtr *stackindex);
93  void RelocateOuters();
94  void CloseOuters(SQObjectPtr *stackindex);
95 
96  bool TypeOf(const SQObjectPtr &obj1, SQObjectPtr &dest);
97  bool CallMetaMethod(SQObjectPtr &closure, SQMetaMethod mm, SQInteger nparams, SQObjectPtr &outres);
98  bool ArithMetaMethod(SQInteger op, const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest);
99  bool Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval);
100  //new stuff
101  _INLINE bool ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
102  _INLINE bool BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
103  _INLINE bool NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o1);
104  _INLINE bool CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res);
105  bool CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func);
106  bool CLASS_OP(SQObjectPtr &target,SQInteger base,SQInteger attrs);
107  //return true if the loop is finished
108  bool FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr &o3,SQObjectPtr &o4,SQInteger arg_2,int exitpos,int &jump);
109  //_INLINE bool LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
110  _INLINE bool PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
111  _INLINE bool DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix,SQInteger arg0);
112 #ifdef _DEBUG_DUMP
113  void dumpstack(SQInteger stackbase=-1, bool dumpall = false);
114 #endif
115 
116 #ifndef NO_GARBAGE_COLLECTOR
117  void Mark(SQCollectable **chain);
118  SQObjectType GetType() {return OT_THREAD;}
119 #endif
120  void Finalize();
121  void FinalizeCore();
122  void GrowCallStack() {
123  SQInteger newsize = _alloccallsstacksize*2;
124  _callstackdata.resize(newsize);
125  _callsstack = &_callstackdata[0];
126  _alloccallsstacksize = newsize;
127  }
128  bool EnterFrame(SQInteger newbase, SQInteger newtop, bool tailcall);
129  void LeaveFrame();
130  void Release(){ sq_delete(this,SQVM); }
131  void CheckStackAccess(SQInteger n);
133  //stack functions for the api
134  void Remove(SQInteger n);
135 
136  static bool IsFalse(SQObjectPtr &o);
137 
138  void Pop();
139  void Pop(SQInteger n);
140  void Push(const SQObjectPtr &o);
141  void PushNull();
142  SQObjectPtr &Top();
143  SQObjectPtr &PopGet();
144  SQObjectPtr &GetUp(SQInteger n);
145  SQObjectPtr &GetAt(SQInteger n);
146 
147  SQObjectPtrVec _stack;
148 
149  SQInteger _top = 0;
150  SQInteger _stackbase = 0;
151  SQOuter *_openouters;
152  SQObjectPtr _roottable;
153  SQObjectPtr _lasterror;
154  SQObjectPtr _errorhandler;
155 
156  bool _debughook;
157  SQDEBUGHOOK _debughook_native;
158  SQObjectPtr _debughook_closure;
159 
160  SQObjectPtr temp_reg;
161 
162 
163  CallInfo* _callsstack = nullptr;
164  SQInteger _callsstacksize = 0;
165  SQInteger _alloccallsstacksize = 0;
166  sqvector<CallInfo> _callstackdata;
167 
168  ExceptionsTraps _etraps;
169  CallInfo *ci;
170  SQUserPointer _foreignptr;
171  //VMs sharing the same state
172  SQInteger _nnativecalls;
173  SQInteger _nmetamethodscall;
174  SQRELEASEHOOK _releasehook;
175  //suspend infos
176  SQBool _suspended;
177  SQBool _suspended_root;
178  SQInteger _suspended_target;
179  SQInteger _suspended_traps;
180 };
181 
182 struct AutoDec{
183  AutoDec(SQInteger *n) { _n = n; }
184  ~AutoDec() { (*_n)--; }
185  SQInteger *_n;
186 };
187 
188 inline SQObjectPtr &stack_get(HSQUIRRELVM v,SQInteger idx){return ((idx>=0)?(v->GetAt(idx+v->_stackbase-1)):(v->GetUp(idx)));}
189 
190 #define _ss(_vm_) (_vm_)->_sharedstate
191 
192 #ifndef NO_GARBAGE_COLLECTOR
193 #define _opt_ss(_vm_) (_vm_)->_sharedstate
194 #else
195 #define _opt_ss(_vm_) NULL
196 #endif
197 
198 #define PUSH_CALLINFO(v,nci){ \
199  SQInteger css = v->_callsstacksize; \
200  if(css == v->_alloccallsstacksize) { \
201  v->GrowCallStack(); \
202  } \
203  v->ci = &v->_callsstack[css]; \
204  *(v->ci) = nci; \
205  v->_callsstacksize++; \
206 }
207 
208 #define POP_CALLINFO(v){ \
209  SQInteger css = --v->_callsstacksize; \
210  v->ci->_closure.Null(); \
211  v->ci = css?&v->_callsstack[css-1]:NULL; \
212 }
213 #endif //_SQVM_H_
Definition: sqvm.h:35
Definition: sqclosure.h:10
Definition: sqvm.h:33
Definition: sqclass.h:28
Definition: sqclosure.h:74
Definition: sqvm.h:182
Definition: sqclosure.h:108
Definition: sqstate.h:59
Definition: sqopcodes.h:109
Definition: squirrel.h:153
Definition: sqvm.h:20
Definition: sqobject.h:205
Definition: sqstring.h:14
Definition: sqclosure.h:147
Definition: sqfuncproto.h:49
Definition: sqobject.h:313