Back to home page

Enduro/X

 
 

    


0001 /*  see copyright notice in pscript.h */
0002 #ifndef _PSVM_H_
0003 #define _PSVM_H_
0004 
0005 #include "psopcodes.h"
0006 #include "psobject.h"
0007 #define MAX_NATIVE_CALLS 100
0008 #define MIN_STACK_OVERHEAD 15
0009 
0010 #define PS_SUSPEND_FLAG -666
0011 #define DONT_FALL_BACK 666
0012 //#define EXISTS_FALL_BACK -1

0013 
0014 #define GET_FLAG_RAW                0x00000001
0015 #define GET_FLAG_DO_NOT_RAISE_ERROR 0x00000002
0016 //base lib

0017 void ps_base_register(HPSCRIPTVM v);
0018 
0019 struct PSExceptionTrap{
0020     PSExceptionTrap() {}
0021     PSExceptionTrap(PSInteger ss, PSInteger stackbase,PSInstruction *ip, PSInteger ex_target){ _stacksize = ss; _stackbase = stackbase; _ip = ip; _extarget = ex_target;}
0022     PSExceptionTrap(const PSExceptionTrap &et) { (*this) = et;  }
0023     PSInteger _stackbase;
0024     PSInteger _stacksize;
0025     PSInstruction *_ip;
0026     PSInteger _extarget;
0027 };
0028 
0029 #define _INLINE
0030 
0031 #define STK(a) _stack._vals[_stackbase+(a)]
0032 #define TARGET _stack._vals[_stackbase+arg0]
0033 
0034 typedef psvector<PSExceptionTrap> ExceptionsTraps;
0035 
0036 struct PSVM : public CHAINABLE_OBJ
0037 {
0038     struct CallInfo{
0039         //CallInfo() { _generator = NULL;}

0040         PSInstruction *_ip;
0041         PSObjectPtr *_literals;
0042         PSObjectPtr _closure;
0043         PSGenerator *_generator;
0044         PSInt32 _etraps;
0045         PSInt32 _prevstkbase;
0046         PSInt32 _prevtop;
0047         PSInt32 _target;
0048         PSInt32 _ncalls;
0049         PSBool _root;
0050     };
0051 
0052 typedef psvector<CallInfo> CallInfoVec;
0053 public:
0054     void DebugHookProxy(PSInteger type, const PSChar * sourcename, PSInteger line, const PSChar * funcname);
0055     static void _DebugHookProxy(HPSCRIPTVM v, PSInteger type, const PSChar * sourcename, PSInteger line, const PSChar * funcname);
0056     enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM,ET_RESUME_THROW_VM };
0057     PSVM(PSSharedState *ss);
0058     ~PSVM();
0059     bool Init(PSVM *friendvm, PSInteger stacksize);
0060     bool Execute(PSObjectPtr &func, PSInteger nargs, PSInteger stackbase, PSObjectPtr &outres, PSBool raiseerror, ExecutionType et = ET_CALL);
0061     //starts a native call return when the NATIVE closure returns

0062     bool CallNative(PSNativeClosure *nclosure, PSInteger nargs, PSInteger newbase, PSObjectPtr &retval,bool &suspend);
0063     //starts a PSCRIPT call in the same "Execution loop"

0064     bool StartCall(PSClosure *closure, PSInteger target, PSInteger nargs, PSInteger stackbase, bool tailcall);
0065     bool CreateClassInstance(PSClass *theclass, PSObjectPtr &inst, PSObjectPtr &constructor);
0066     //call a generic closure pure PSCRIPT or NATIVE

0067     bool Call(PSObjectPtr &closure, PSInteger nparams, PSInteger stackbase, PSObjectPtr &outres,PSBool raiseerror);
0068     PSRESULT Suspend();
0069 
0070     void CallDebugHook(PSInteger type,PSInteger forcedline=0);
0071     void CallErrorHandler(PSObjectPtr &e);
0072     bool Get(const PSObjectPtr &self, const PSObjectPtr &key, PSObjectPtr &dest, PSUnsignedInteger getflags, PSInteger selfidx);
0073     PSInteger FallBackGet(const PSObjectPtr &self,const PSObjectPtr &key,PSObjectPtr &dest);
0074     bool InvokeDefaultDelegate(const PSObjectPtr &self,const PSObjectPtr &key,PSObjectPtr &dest);
0075     bool Set(const PSObjectPtr &self, const PSObjectPtr &key, const PSObjectPtr &val, PSInteger selfidx);
0076     PSInteger FallBackSet(const PSObjectPtr &self,const PSObjectPtr &key,const PSObjectPtr &val);
0077     bool NewSlot(const PSObjectPtr &self, const PSObjectPtr &key, const PSObjectPtr &val,bool bstatic);
0078     bool NewSlotA(const PSObjectPtr &self,const PSObjectPtr &key,const PSObjectPtr &val,const PSObjectPtr &attrs,bool bstatic,bool raw);
0079     bool DeleteSlot(const PSObjectPtr &self, const PSObjectPtr &key, PSObjectPtr &res);
0080     bool Clone(const PSObjectPtr &self, PSObjectPtr &target);
0081     bool ObjCmp(const PSObjectPtr &o1, const PSObjectPtr &o2,PSInteger &res);
0082     bool StringCat(const PSObjectPtr &str, const PSObjectPtr &obj, PSObjectPtr &dest);
0083     static bool IsEqual(const PSObjectPtr &o1,const PSObjectPtr &o2,bool &res);
0084     bool ToString(const PSObjectPtr &o,PSObjectPtr &res);
0085     PSString *PrintObjVal(const PSObjectPtr &o);
0086 
0087 
0088     void Raise_Error(const PSChar *s, ...);
0089     void Raise_Error(const PSObjectPtr &desc);
0090     void Raise_IdxError(const PSObjectPtr &o);
0091     void Raise_CompareError(const PSObject &o1, const PSObject &o2);
0092     void Raise_ParamTypeError(PSInteger nparam,PSInteger typemask,PSInteger type);
0093 
0094     void FindOuter(PSObjectPtr &target, PSObjectPtr *stackindex);
0095     void RelocateOuters();
0096     void CloseOuters(PSObjectPtr *stackindex);
0097 
0098     bool TypeOf(const PSObjectPtr &obj1, PSObjectPtr &dest);
0099     bool CallMetaMethod(PSObjectPtr &closure, PSMetaMethod mm, PSInteger nparams, PSObjectPtr &outres);
0100     bool ArithMetaMethod(PSInteger op, const PSObjectPtr &o1, const PSObjectPtr &o2, PSObjectPtr &dest);
0101     bool Return(PSInteger _arg0, PSInteger _arg1, PSObjectPtr &retval);
0102     //new stuff

0103     _INLINE bool ARITH_OP(PSUnsignedInteger op,PSObjectPtr &trg,const PSObjectPtr &o1,const PSObjectPtr &o2);
0104     _INLINE bool BW_OP(PSUnsignedInteger op,PSObjectPtr &trg,const PSObjectPtr &o1,const PSObjectPtr &o2);
0105     _INLINE bool NEG_OP(PSObjectPtr &trg,const PSObjectPtr &o1);
0106     _INLINE bool CMP_OP(CmpOP op, const PSObjectPtr &o1,const PSObjectPtr &o2,PSObjectPtr &res);
0107     bool CLOSURE_OP(PSObjectPtr &target, PSFunctionProto *func);
0108     bool CLASS_OP(PSObjectPtr &target,PSInteger base,PSInteger attrs);
0109     //return true if the loop is finished

0110     bool FOREACH_OP(PSObjectPtr &o1,PSObjectPtr &o2,PSObjectPtr &o3,PSObjectPtr &o4,PSInteger arg_2,int exitpos,int &jump);
0111     //_INLINE bool LOCAL_INC(PSInteger op,PSObjectPtr &target, PSObjectPtr &a, PSObjectPtr &incr);

0112     _INLINE bool PLOCAL_INC(PSInteger op,PSObjectPtr &target, PSObjectPtr &a, PSObjectPtr &incr);
0113     _INLINE bool DerefInc(PSInteger op,PSObjectPtr &target, PSObjectPtr &self, PSObjectPtr &key, PSObjectPtr &incr, bool postfix,PSInteger arg0);
0114 #ifdef _DEBUG_DUMP
0115     void dumpstack(PSInteger stackbase=-1, bool dumpall = false);
0116 #endif
0117 
0118 #ifndef NO_GARBAGE_COLLECTOR
0119     void Mark(PSCollectable **chain);
0120     PSObjectType GetType() {return OT_THREAD;}
0121 #endif
0122     void Finalize();
0123     void GrowCallStack() {
0124         PSInteger newsize = _alloccallsstacksize*2;
0125         _callstackdata.resize(newsize);
0126         _callsstack = &_callstackdata[0];
0127         _alloccallsstacksize = newsize;
0128     }
0129     bool EnterFrame(PSInteger newbase, PSInteger newtop, bool tailcall);
0130     void LeaveFrame();
0131     void Release(){ ps_delete(this,PSVM); }
0132 ////////////////////////////////////////////////////////////////////////////

0133     //stack functions for the api

0134     void Remove(PSInteger n);
0135 
0136     static bool IsFalse(PSObjectPtr &o);
0137 
0138     void Pop();
0139     void Pop(PSInteger n);
0140     void Push(const PSObjectPtr &o);
0141     void PushNull();
0142     PSObjectPtr &Top();
0143     PSObjectPtr &PopGet();
0144     PSObjectPtr &GetUp(PSInteger n);
0145     PSObjectPtr &GetAt(PSInteger n);
0146 
0147     PSObjectPtrVec _stack;
0148 
0149     PSInteger _top;
0150     PSInteger _stackbase;
0151     PSOuter *_openouters;
0152     PSObjectPtr _roottable;
0153     PSObjectPtr _lasterror;
0154     PSObjectPtr _errorhandler;
0155 
0156     bool _debughook;
0157     PSDEBUGHOOK _debughook_native;
0158     PSObjectPtr _debughook_closure;
0159 
0160     PSObjectPtr temp_reg;
0161 
0162 
0163     CallInfo* _callsstack;
0164     PSInteger _callsstacksize;
0165     PSInteger _alloccallsstacksize;
0166     psvector<CallInfo>  _callstackdata;
0167 
0168     ExceptionsTraps _etraps;
0169     CallInfo *ci;
0170     PSUserPointer _foreignptr;
0171     //VMs sharing the same state

0172     PSSharedState *_sharedstate;
0173     PSInteger _nnativecalls;
0174     PSInteger _nmetamethodscall;
0175     PSRELEASEHOOK _releasehook;
0176     //suspend infos

0177     PSBool _suspended;
0178     PSBool _suspended_root;
0179     PSInteger _suspended_target;
0180     PSInteger _suspended_traps;
0181 };
0182 
0183 struct AutoDec{
0184     AutoDec(PSInteger *n) { _n = n; }
0185     ~AutoDec() { (*_n)--; }
0186     PSInteger *_n;
0187 };
0188 
0189 inline PSObjectPtr &stack_get(HPSCRIPTVM v,PSInteger idx){return ((idx>=0)?(v->GetAt(idx+v->_stackbase-1)):(v->GetUp(idx)));}
0190 
0191 #define _ss(_vm_) (_vm_)->_sharedstate
0192 
0193 #ifndef NO_GARBAGE_COLLECTOR
0194 #define _opt_ss(_vm_) (_vm_)->_sharedstate
0195 #else
0196 #define _opt_ss(_vm_) NULL
0197 #endif
0198 
0199 #define PUSH_CALLINFO(v,nci){ \
0200     PSInteger css = v->_callsstacksize; \
0201     if(css == v->_alloccallsstacksize) { \
0202         v->GrowCallStack(); \
0203     } \
0204     v->ci = &v->_callsstack[css]; \
0205     *(v->ci) = nci; \
0206     v->_callsstacksize++; \
0207 }
0208 
0209 #define POP_CALLINFO(v){ \
0210     PSInteger css = --v->_callsstacksize; \
0211     v->ci->_closure.Null(); \
0212     v->ci = css?&v->_callsstack[css-1]:NULL;    \
0213 }
0214 #endif //_PSVM_H_