00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef FLC_VM_H
00017 #define FLC_VM_H
00018
00019 #include <falcon/symtab.h>
00020 #include <falcon/symlist.h>
00021 #include <falcon/item.h>
00022 #include <falcon/stackframe.h>
00023 #include <falcon/module.h>
00024 #include <falcon/common.h>
00025 #include <falcon/error.h>
00026 #include <falcon/runtime.h>
00027 #include <falcon/vmmaps.h>
00028 #include <falcon/genericlist.h>
00029 #include <falcon/carray.h>
00030 #include <falcon/string.h>
00031 #include <falcon/coreobject.h>
00032 #include <falcon/coredict.h>
00033 #include <falcon/cclass.h>
00034 #include <falcon/genericmap.h>
00035 #include <falcon/genericlist.h>
00036 #include <falcon/fassert.h>
00037 #include <falcon/vm_sys.h>
00038 #include <falcon/coreslot.h>
00039 #include <falcon/baton.h>
00040 #include <falcon/livemodule.h>
00041 #include <falcon/vmcontext.h>
00042
00043 #define FALCON_VM_DFAULT_CHECK_LOOPS 5000
00044
00045 namespace Falcon {
00046
00047 class Runtime;
00048 class VMachine;
00049 class PropertyTable;
00050 class AttribHandler;
00051 class MemPool;
00052 class VMMessage;
00053 class GarbageLock;
00054
00055
00056 typedef void (*tOpcodeHandler)( register VMachine *);
00057
00058 void ContextList_deletor( void * );
00059
00060 class FALCON_DYN_CLASS ContextList: public List
00061 {
00062 friend void ContextList_deletor( void * );
00063
00064 public:
00065 ContextList()
00066 {}
00067 };
00068
00069
00070 void opcodeHandler_END ( register VMachine *vm );
00071 void opcodeHandler_NOP ( register VMachine *vm );
00072 void opcodeHandler_PSHN( register VMachine *vm );
00073 void opcodeHandler_RET ( register VMachine *vm );
00074 void opcodeHandler_RETA( register VMachine *vm );
00075 void opcodeHandler_PTRY( register VMachine *vm );
00076
00077
00078 void opcodeHandler_LNIL( register VMachine *vm );
00079 void opcodeHandler_RETV( register VMachine *vm );
00080 void opcodeHandler_FORK( register VMachine *vm );
00081 void opcodeHandler_BOOL( register VMachine *vm );
00082 void opcodeHandler_GENA( register VMachine *vm );
00083 void opcodeHandler_GEND( register VMachine *vm );
00084 void opcodeHandler_PUSH( register VMachine *vm );
00085 void opcodeHandler_PSHR( register VMachine *vm );
00086 void opcodeHandler_POP ( register VMachine *vm );
00087 void opcodeHandler_JMP ( register VMachine *vm );
00088 void opcodeHandler_INC ( register VMachine *vm );
00089 void opcodeHandler_DEC ( register VMachine *vm );
00090 void opcodeHandler_NEG ( register VMachine *vm );
00091 void opcodeHandler_NOT ( register VMachine *vm );
00092 void opcodeHandler_TRAL( register VMachine *vm );
00093 void opcodeHandler_IPOP( register VMachine *vm );
00094 void opcodeHandler_XPOP( register VMachine *vm );
00095 void opcodeHandler_GEOR( register VMachine *vm );
00096 void opcodeHandler_TRY ( register VMachine *vm );
00097 void opcodeHandler_JTRY( register VMachine *vm );
00098 void opcodeHandler_RIS ( register VMachine *vm );
00099 void opcodeHandler_BNOT( register VMachine *vm );
00100 void opcodeHandler_NOTS( register VMachine *vm );
00101 void opcodeHandler_PEEK( register VMachine *vm );
00102
00103
00104 void opcodeHandler_LD ( register VMachine *vm );
00105 void opcodeHandler_LDRF( register VMachine *vm );
00106 void opcodeHandler_ADD ( register VMachine *vm );
00107 void opcodeHandler_SUB ( register VMachine *vm );
00108 void opcodeHandler_MUL ( register VMachine *vm );
00109 void opcodeHandler_DIV ( register VMachine *vm );
00110 void opcodeHandler_MOD ( register VMachine *vm );
00111 void opcodeHandler_POW ( register VMachine *vm );
00112 void opcodeHandler_ADDS( register VMachine *vm );
00113 void opcodeHandler_SUBS( register VMachine *vm );
00114 void opcodeHandler_MULS( register VMachine *vm );
00115 void opcodeHandler_DIVS( register VMachine *vm );
00116 void opcodeHandler_MODS( register VMachine *vm );
00117 void opcodeHandler_BAND( register VMachine *vm );
00118 void opcodeHandler_BOR ( register VMachine *vm );
00119 void opcodeHandler_BXOR( register VMachine *vm );
00120 void opcodeHandler_ANDS( register VMachine *vm );
00121 void opcodeHandler_ORS ( register VMachine *vm );
00122 void opcodeHandler_XORS( register VMachine *vm );
00123 void opcodeHandler_GENR( register VMachine *vm );
00124 void opcodeHandler_EQ ( register VMachine *vm );
00125 void opcodeHandler_NEQ ( register VMachine *vm );
00126 void opcodeHandler_GT ( register VMachine *vm );
00127 void opcodeHandler_GE ( register VMachine *vm );
00128 void opcodeHandler_LT ( register VMachine *vm );
00129 void opcodeHandler_LE ( register VMachine *vm );
00130 void opcodeHandler_IFT ( register VMachine *vm );
00131 void opcodeHandler_IFF ( register VMachine *vm );
00132 void opcodeHandler_CALL( register VMachine *vm );
00133 void opcodeHandler_INST( register VMachine *vm );
00134 void opcodeHandler_ONCE( register VMachine *vm );
00135 void opcodeHandler_LDV ( register VMachine *vm );
00136 void opcodeHandler_LDP ( register VMachine *vm );
00137 void opcodeHandler_TRAN( register VMachine *vm );
00138 void opcodeHandler_LDAS( register VMachine *vm );
00139 void opcodeHandler_SWCH( register VMachine *vm );
00140 void opcodeHandler_IN ( register VMachine *vm );
00141 void opcodeHandler_NOIN( register VMachine *vm );
00142 void opcodeHandler_PROV( register VMachine *vm );
00143 void opcodeHandler_SSTA( register VMachine *vm );
00144 void opcodeHandler_SVAL( register VMachine *vm );
00145 void opcodeHandler_STPS( register VMachine *vm );
00146 void opcodeHandler_STVS( register VMachine *vm );
00147 void opcodeHandler_LSTA( register VMachine *vm );
00148 void opcodeHandler_LVAL( register VMachine *vm );
00149 void opcodeHandler_AND ( register VMachine *vm );
00150 void opcodeHandler_OR ( register VMachine *vm );
00151 void opcodeHandler_PASS( register VMachine *vm );
00152 void opcodeHandler_PSIN( register VMachine *vm );
00153
00154
00155 void opcodeHandler_STP ( register VMachine *vm );
00156 void opcodeHandler_STV ( register VMachine *vm );
00157 void opcodeHandler_LDVT( register VMachine *vm );
00158 void opcodeHandler_LDPT( register VMachine *vm );
00159 void opcodeHandler_STPR( register VMachine *vm );
00160 void opcodeHandler_STVR( register VMachine *vm );
00161 void opcodeHandler_TRAV( register VMachine *vm );
00162
00163 void opcodeHandler_SJMP( register VMachine *vm );
00164 void opcodeHandler_INCP( register VMachine *vm );
00165 void opcodeHandler_DECP( register VMachine *vm );
00166
00167 void opcodeHandler_SHL( register VMachine *vm );
00168 void opcodeHandler_SHR( register VMachine *vm );
00169 void opcodeHandler_SHLS( register VMachine *vm );
00170 void opcodeHandler_SHRS( register VMachine *vm );
00171 void opcodeHandler_CLOS( register VMachine *vm );
00172 void opcodeHandler_PSHL( register VMachine *vm );
00173
00174 void opcodeHandler_POWS( register VMachine *vm );
00175 void opcodeHandler_LSB( register VMachine *vm );
00176 void opcodeHandler_SELE( register VMachine *vm );
00177 void opcodeHandler_INDI( register VMachine *vm );
00178 void opcodeHandler_STEX( register VMachine *vm );
00179 void opcodeHandler_TRAC( register VMachine *vm );
00180 void opcodeHandler_WRT( register VMachine *vm );
00181 void opcodeHandler_STO( register VMachine *vm );
00182 void opcodeHandler_FORB( register VMachine *vm );
00183 void opcodeHandler_EVAL( register VMachine *vm );
00184 void opcodeHandler_OOB( register VMachine *vm );
00185 void opcodeHandler_TRDN( register VMachine *vm );
00186
00187
00188 class VMachine;
00189
00190 class FALCON_DYN_CLASS VMBaton: public Baton
00191 {
00192 VMachine *m_owner;
00193
00194 public:
00195 VMBaton( VMachine* owner ):
00196 Baton( true ),
00197 m_owner( owner )
00198 {}
00199 virtual ~VMBaton() {}
00200
00201 virtual void release();
00202 virtual void onBlockedAcquire();
00203 void releaseNotIdle();
00204 };
00205
00233 class FALCON_DYN_CLASS VMachine: public BaseAlloc
00234 {
00235 friend class MemPool;
00236
00237 public:
00238
00243 enum {
00244 i_pc_call_request = 0xFFFFFFFF-sizeof(int32)*4,
00245 i_pc_redo_request =0xFFFFFFFF-sizeof(int32)*4,
00246 i_pc_call_external_ctor = 0xFFFFFFFF-sizeof(int32)*3,
00247 i_pc_call_external_ctor_return = 0xFFFFFFFF-sizeof(int32)*2,
00248 i_pc_call_external = 0xFFFFFFFF-sizeof(int32),
00249 i_pc_call_external_return = 0xFFFFFFFF
00250 };
00251
00252 protected:
00254 class VarDefMod: public BaseAlloc
00255 {
00256 public:
00257 VarDef *vd;
00258 LiveModule *lmod;
00259 };
00260
00261
00262 mutable Mutex m_mtx;
00263
00265 mutable Mutex m_slot_mtx;
00266
00272 LiveModule *m_mainModule;
00273
00274
00276 Item m_imm[4];
00277
00278 Stream *m_stdIn;
00279 Stream *m_stdOut;
00280 Stream *m_stdErr;
00281 bool m_bhasStandardStreams;
00282
00284 uint32 m_opCount;
00285
00287 uint32 m_opLimit;
00288
00290 uint32 m_loopsGC;
00292 uint32 m_loopsContext;
00294 uint32 m_loopsCallback;
00295
00297 bool m_bSingleStep;
00298
00299 uint32 m_opNextGC;
00300 uint32 m_opNextContext;
00301 uint32 m_opNextCallback;
00302
00304 uint32 m_opNextCheck;
00305
00307 uint32 m_generation;
00308
00312 LiveModuleMap m_liveModules;
00313
00315 enum {
00316 i_noTryFrame = 0xFFFFFFFF
00317 };
00318
00320 VMContext *m_currentContext;
00321
00323 ContextList m_contexts;
00325 ContextList m_sleepingContexts;
00327 bool m_allowYield;
00328
00330 bool m_launchAtLink;
00331
00333 tOpcodeHandler *m_opHandlers;
00334
00338 SymModuleMap m_globalSyms;
00339
00343 SymModuleMap m_wellKnownSyms;
00344
00352 void putAtSleep( VMContext *ctx );
00353
00360 void reschedule( VMContext *ctx );
00361
00363 bool linkSubClass( LiveModule *mod , const Symbol *clssym, Map &props, ObjectFactory *factory );
00364
00365 friend class VMContext;
00366 friend class VMSemaphore;
00367
00376 Map m_services;
00377
00381 void *m_userData;
00382
00386 Sys::SystemData m_systemData;
00387
00388 CoreClass **m_metaClasses;
00389
00390 Map m_slots;
00391
00392 VMachine *m_nextVM;
00393 VMachine *m_prevVM;
00394
00395 VMachine *m_idleNext;
00396 VMachine *m_idlePrev;
00397
00404 bool m_bGcEnabled;
00405
00407 VMBaton m_baton;
00408
00409 Mutex m_mtx_mesasges;
00410 VMMessage* m_msg_head;
00411 VMMessage* m_msg_tail;
00412
00417 bool m_bPirorityGC;
00418
00420 Event m_eGCPerformed;
00421
00423 bool m_bWaitForCollect;
00424
00428 Mutex m_mtx_lockitem;
00429
00433 GarbageLock *m_lockRoot;
00434
00439 volatile int m_refcount;
00440
00442 void (*m_onFinalize)(VMachine *vm);
00443
00445 String m_appSearchPath;
00446
00447
00448
00449
00453 bool seekInteger( int64 num, byte *base, uint16 size, uint32 &landing ) const;
00454
00458 bool seekInRange( int64 num, byte *base, uint16 size, uint32 &landing ) const;
00459
00463 bool seekString( const String *str, byte *base, uint16 size, uint32 &landing ) const;
00464
00468 bool seekItem( const Item *item, byte *base, uint16 size, uint32 &landing );
00469
00473 bool seekItemClass( const Item *obj, byte *base, uint16 size, uint32 &landing ) const;
00474
00475 void internal_construct();
00476
00477 Item *parseSquareAccessor( const Item &accessed, String &accessor ) const;
00478
00480 int32 getNextNTD32()
00481 {
00482 register int32 ret = *reinterpret_cast<int32 *>(
00483 m_currentContext->code() + m_currentContext->pc_next() );
00484 m_currentContext->pc_next() += sizeof( int32 );
00485 return ret;
00486 }
00487
00489 int64 getNextNTD64()
00490 {
00491 register int64 ret = loadInt64(
00492 m_currentContext->code() + m_currentContext->pc_next() );
00493 m_currentContext->pc_next() += sizeof( int64 );
00494 return ret;
00495 }
00496
00498 Item *getOpcodeParam( register uint32 bc_pos );
00499
00500
00520 void handleRaisedItem( Item& value );
00521
00529 void handleRaisedError( Error* err );
00530
00532 void periodicChecks();
00533
00538 void createFrame( uint32 paramCount, ext_func_frame_t frameEndFunc = 0 )
00539 {
00540 m_currentContext->createFrame( paramCount, frameEndFunc );
00541 }
00542
00557 void setCurrent() const;
00558
00568 void processMessage( VMMessage* msg );
00569
00570 bool linkDefinedSymbol( const Symbol *sym, LiveModule *lmod );
00571 bool linkUndefinedSymbol( const Symbol *sym, LiveModule *lmod );
00572 bool completeModLink( LiveModule *lmod );
00573 LiveModule *prelink( Module *mod, bool bIsMain, bool bPrivate );
00574
00575 void raiseHardError( int code, const String &expl, int32 line );
00576
00578 Item* getNextTravVar();
00579
00583 virtual ~VMachine();
00584
00585 public:
00601 static VMachine *getCurrent();
00602
00612 VMachine( bool initItems );
00613
00614
00619 VMachine();
00620
00621
00645 void init();
00646
00665 LiveModule* link( Runtime *rt );
00666
00691 LiveModule *link( Module *module, bool isMainModule=true, bool bPrivate = false );
00692
00699 bool linkSymbol( const Symbol *sym, LiveModule *lmod );
00700
00701
00729 virtual bool linkSymbolDynamic( const String &name, SymModule &symdata );
00730
00746 bool linkClassSymbol( const Symbol *sym, LiveModule *livemod );
00747
00766 bool linkInstanceSymbol( const Symbol *sym, LiveModule *livemod );
00767
00791 void initializeInstance( const Symbol *sym, LiveModule *livemod );
00792
00809 bool linkCompleteSymbol( const Symbol *sym, LiveModule *livemod );
00810
00828 bool linkCompleteSymbol( Symbol *sym, const String &moduleName );
00829
00835 LiveModule *mainModule() const { return m_mainModule; }
00836
00859 bool unlink( const Runtime *rt );
00860
00881 bool unlink( const Module *module );
00882
00883
00892 CoreClass *linkClass( LiveModule *lmod, const Symbol *clsym );
00893
00894
00898 void launch() { launch( "__main__" ); }
00899
00928 void launch( const String &startSym, uint32 paramCount = 0 );
00929
00930
00952 void run();
00953
00954
00956 void fillErrorTraceback( Error &error );
00957
00966 bool getCaller( const Symbol *&sym, const Module *&module);
00967
00976 bool getCallerItem( Item &caller, uint32 level=0 );
00977
00980 void fillErrorContext( Error *err, bool filltb = true );
00981
00983 ItemArray &stack() { return m_currentContext->stack(); }
00984
00986 const ItemArray &stack() const { return m_currentContext->stack(); }
00987
00989 uint32& tryFrame() { return m_currentContext->tryFrame(); }
00990
00992 const uint32& tryFrame() const { return m_currentContext->tryFrame(); }
00993
00995 Item &stackItem( uint32 pos ) { return stack()[ pos ]; }
00996
00998 const Item &stackItem( uint32 pos ) const { return stack()[pos]; }
00999
01001 ItemArray ¤tGlobals() { return m_currentContext->globals(); }
01002
01004 const ItemArray ¤tGlobals() const { return m_currentContext->globals(); }
01005
01007 Item &moduleItem( uint32 pos ) { return currentGlobals()[ pos ]; }
01008
01010 const Item &moduleItem( uint32 pos ) const { return currentGlobals()[ pos ]; }
01011
01013 const Module *currentModule() const { return m_currentContext->lmodule()->module(); }
01014
01016 LiveModule *currentLiveModule() const { return m_currentContext->lmodule(); }
01017
01022 LiveModule *findModule( const String &name );
01023
01027 LiveModuleMap &liveModules() { return m_liveModules; }
01028
01032 const LiveModuleMap &liveModules() const { return m_liveModules; }
01033
01038 int32 paramCount() const {
01039 return ((StackFrame *)&stack()[ stackBase() - VM_FRAME_SPACE ] )->m_param_count;
01040 }
01041
01045 const Item *param( uint32 itemId ) const
01046 {
01047 register uint32 params = paramCount();
01048 if ( itemId >= params ) return 0;
01049 return stackItem( m_currentContext->stackBase() - params - VM_FRAME_SPACE + itemId ).dereference();
01050 }
01051
01077 Item *param( uint32 itemId )
01078 {
01079 register uint32 params = paramCount();
01080 if ( itemId >= params ) return 0;
01081 return stackItem( m_currentContext->stackBase() - params - VM_FRAME_SPACE + itemId ).dereference();
01082 }
01083
01084
01096 const Item *local( uint32 itemId ) const
01097 {
01098 return m_currentContext->local( itemId );
01099 }
01100
01107 Item *local( uint32 itemId )
01108 {
01109 return m_currentContext->local( itemId );
01110 }
01111
01116 bool isParamByRef( uint32 itemId ) const
01117 {
01118 register uint32 params = paramCount();
01119 if ( itemId >= params ) return false;
01120 return stackItem( m_currentContext->stackBase() - params - VM_FRAME_SPACE + itemId ).type() == FLC_ITEM_REFERENCE;
01121 }
01122
01123 const Item ®A() const { return m_currentContext->regA(); }
01124 Item ®A() { return m_currentContext->regA(); }
01125 const Item ®B() const { return m_currentContext->regB(); }
01126 Item ®B() { return m_currentContext->regB(); }
01127 const Item ®Bind() const { return m_currentContext->regBind(); }
01128 Item ®Bind() { return m_currentContext->regBind(); }
01129 const Item ®BindP() const { return m_currentContext->regBindP(); }
01130 Item ®BindP() { return m_currentContext->regBindP(); }
01131
01132 const Item &self() const { return m_currentContext->self(); }
01133 Item &self() { return m_currentContext->self(); }
01134
01138 const Item &latch() const { return m_currentContext->latch(); }
01142 Item &latch() { return m_currentContext->latch(); }
01143
01147 const Item &latcher() const { return m_currentContext->latcher(); }
01151 Item &latcher() { return m_currentContext->latcher(); }
01152
01153
01154 void retval( bool val ) {
01155 m_currentContext->regA().setBoolean( val );
01156 }
01157
01158 void retval( int32 val ) {
01159 m_currentContext->regA().setInteger( (int64) val );
01160 }
01161
01162 void retval( int64 val ) {
01163 m_currentContext->regA().setInteger( val );
01164 }
01165
01166 void retval( numeric val ) {
01167 m_currentContext->regA().setNumeric( val );
01168 }
01169
01170 void retval( const Item &val ) {
01171 m_currentContext->regA() = val;
01172 }
01173
01174
01176 void retval( String *cs )
01177 {
01178 m_currentContext->regA().setString(cs);
01179 }
01180
01181
01186 void retval( CoreString *cs )
01187 {
01188 m_currentContext->regA().setString(cs);
01189 }
01190
01191 void retval( CoreArray *ca ) {
01192 m_currentContext->regA().setArray(ca);
01193 }
01194
01195 void retval( MemBuf* mb ) {
01196 m_currentContext->regA().setMemBuf(mb);
01197 }
01198
01199 void retval( CoreDict *cd ) {
01200 m_currentContext->regA().setDict( cd );
01201 }
01202
01203 void retval( CoreObject *co ) {
01204 m_currentContext->regA().setObject(co);
01205 }
01206
01207 void retval( CoreClass *cc ) {
01208 m_currentContext->regA().setClass(cc);
01209 }
01210
01211 void retval( const String &cs ) {
01212 CoreString *cs1 = new CoreString( cs );
01213 cs1->bufferize();
01214 m_currentContext->regA().setString( cs1 );
01215 }
01216
01217 void retnil() { m_currentContext->regA().setNil();}
01218
01219 const Symbol *currentSymbol() const { return m_currentContext->symbol(); }
01220 uint32 programCounter() const { return m_currentContext->pc(); }
01221
01222 const SymModule *findGlobalSymbol( const String &str ) const;
01223
01229 void yield( numeric seconds );
01230
01231 void rotateContext();
01232 void terminateCurrentContext();
01233
01259 Item *findWKI( const String &name ) const;
01260
01278 Item *findGlobalItem( const String &name ) const;
01279
01294 bool findLocalVariable( const String &name, Item &data ) const;
01295
01308 Item *findLocalSymbolItem( const String &symName ) const;
01309
01345 void callItem( const Item &callable, int32 paramCount, bool asApp = false )
01346 {
01347 callFrame( callable, paramCount );
01348 if ( asApp ) currentFrame()->m_break = false;
01349 execFrame();
01350 }
01351
01365 void callFrame( const Item &callable, int32 paramCount )
01366 {
01367 callable.readyFrame( this, paramCount );
01368 }
01369
01371 void prepareFrame( CoreFunc* cf, uint32 paramCount );
01372
01380 void prepareFrame( CoreArray* ca, uint32 paramCount );
01381
01390 VMContext* coPrepare( int32 paramCount );
01391
01396 bool callCoroFrame( const Item &callable, int32 paramCount );
01397
01399 void execFrame()
01400 {
01401 currentFrame()->m_break = true;
01402 m_currentContext->pc() = m_currentContext->pc_next();
01403 run();
01404 }
01405
01406 StackFrame* currentFrame() const
01407 {
01408 return m_currentContext->currentFrame();
01409 }
01410
01411 VMContext* currentContext() const
01412 {
01413 return m_currentContext;
01414 }
01415
01447 void callFrameNow( ext_func_frame_t callbackFunc );
01448
01458 void recallFrame() { m_currentContext->pc_next() = m_currentContext->pc(); }
01459
01474 void callItemAtomic(const Item &callable, int32 paramCount );
01475
01491 void returnHandler( ext_func_frame_t callbackFunc ) {
01492 m_currentContext->returnHandler( callbackFunc );
01493 }
01494
01495 ext_func_frame_t returnHandler() const
01496 {
01497 return m_currentContext->returnHandler();
01498 }
01499
01500
01504 ext_func_frame_t returnHandler();
01505
01511 void pushParameter( const Item &item ) { m_currentContext->pushParameter(item); }
01512
01516 void addLocals( uint32 space )
01517 {
01518 m_currentContext->addLocals( space );
01519 }
01520
01521
01522 byte operandType( byte opNum ) const {
01523 return m_currentContext->code()[m_currentContext->pc() + 1 + opNum];
01524 }
01525
01527 bool allowYield() { return m_allowYield; }
01528
01530 void allowYield( bool mode ) { m_allowYield = mode; }
01531
01532
01533 const ContextList *getCtxList() const { return &m_contexts; }
01534 const ContextList *getSleepingList() const { return &m_sleepingContexts; }
01535
01539 void callReturn();
01540
01553 void itemToString( String &target, const Item *itm, const String &format );
01554
01555 void itemToString( String &target, const Item *itm )
01556 {
01557 itemToString( target, itm, "" );
01558 }
01559
01560
01566 PropertyTable *createClassTemplate( LiveModule *lmod, const Map &pt );
01567
01573 void publishService( Service *svr );
01574
01575
01582 Service *getService( const String &name );
01583
01584
01601 Stream *stdIn() const { return m_stdIn; }
01602
01618 Stream *stdOut() const { return m_stdOut; }
01619
01645 Stream *stdErr() const { return m_stdErr; }
01646
01652 void stdIn( Stream *nstream );
01653
01659 void stdOut( Stream *nstream );
01660
01668 void stdErr( Stream *nstream ) ;
01669
01670
01671 bool hasProcessStreams() const { return m_bhasStandardStreams; }
01672
01688 void hasProcessStreams( bool b ) { m_bhasStandardStreams = b; }
01689
01696 const String &moduleString( uint32 stringId ) const;
01697
01702 void reset();
01703
01704 void limitLoops( uint32 l ) { m_opLimit = l; }
01705 uint32 limitLoops() const { return m_opLimit; }
01706 bool limitLoopsHit() const { return m_opLimit >= m_opCount; }
01707
01708 void resetCounters();
01709
01711 void step() {
01712 m_currentContext->pc() = m_currentContext->pc_next();
01713 m_bSingleStep = true;
01714
01715 m_opNextCheck = m_opCount + 1;
01716 run();
01717 }
01718
01719 void singleStep( bool ss ) { m_bSingleStep = ss; }
01720 bool singleStep() const { return m_bSingleStep; }
01721
01727 virtual void periodicCallback();
01728
01729 void callbackLoops( uint32 cl ) { m_loopsCallback = cl; }
01730 uint32 callbackLoops() const { return m_loopsCallback; }
01731
01732 void gcCheckLoops( uint32 cl ) { m_loopsGC = cl; }
01733 uint32 gcCheckLoops() const { return m_loopsGC; }
01734
01735 void contextCheckLoops( uint32 cl ) { m_loopsContext = cl; }
01736 uint32 contextCheckLoops() const { return m_loopsContext; }
01737
01745 uint32 elapsedLoops() const { return m_opCount; }
01746
01747
01749 void pushTry( uint32 landingPC );
01750
01752 void popTry( bool moveTo );
01753
01763 void electContext();
01764
01769 typedef enum {
01770 return_ok,
01771 return_error_string,
01772 return_error_parse,
01773 return_error_internal,
01774 return_error_parse_fmt
01775 }
01776 returnCode;
01777
01781 returnCode expandString( const String &src, String &target );
01782
01790 void referenceItem( Item &target, Item &source );
01791
01792 const uint32& stackBase() const { return m_currentContext->stackBase(); }
01793 uint32& stackBase() { return m_currentContext->stackBase(); }
01794
01809 void userData( void *ud ) { m_userData = ud; }
01810
01815 void *userData() const { return m_userData; }
01816
01845 bool functionalEval( const Item &itm, uint32 pcount=0, bool retArray = true );
01846
01858 void interrupt() { m_systemData.interrupt(); }
01859
01872 bool interrupted( bool raise = false, bool reset = false, bool dontCheck = false );
01873
01877 const Sys::SystemData &systemData() const { return m_systemData; }
01878
01882 Sys::SystemData &systemData() { return m_systemData; }
01883
01891 bool exportSymbol( const Symbol *sym, LiveModule *mod );
01892
01896 bool exportAllSymbols( LiveModule *mod );
01897
01899 void launchAtLink( bool mode ) { m_launchAtLink = mode; }
01900
01905 bool launchAtLink() const { return m_launchAtLink; }
01906
01917 void setBindingContext( CoreDict *ctx ) { m_currentContext->regBind() = ctx; }
01918
01929 Item *getBinding( const String &bind ) const;
01930
01942 Item *getSafeBinding( const String &bind );
01943
01951 bool setBinding( const String &bind, const Item &value );
01952
01953
01954 typedef enum {
01955 lm_complete,
01956 lm_prelink,
01957 lm_postlink
01958 } t_linkMode;
01959
01960
01965 void requestConstruct() {
01966 if( m_currentContext->pc_next() == i_pc_call_external )
01967 m_currentContext->pc_next() = i_pc_call_external_ctor;
01968 }
01969
01970 void setMetaClass( int itemID, CoreClass *metaClass )
01971 {
01972 fassert( itemID >= 0 && itemID < FLC_ITEM_COUNT );
01973 m_metaClasses[ itemID ] = metaClass;
01974 }
01975
01976 CoreClass *getMetaClass( int itemID )
01977 {
01978 fassert( itemID >= 0 && itemID < FLC_ITEM_COUNT );
01979 return m_metaClasses[ itemID ];
01980 }
01981
01986 CoreSlot* getSlot( const String& slotName, bool create = true );
01987
01990 void removeSlot( const String& slotName );
01991
01993 void markSlots( uint32 mark );
01994
01999 bool consumeSignal();
02000
02008 void idle() { m_baton.release(); }
02009
02014 void unidle() { m_baton.acquire(); }
02015
02029 void gcEnable( bool mode );
02030
02031 bool isGcEnabled() const;
02032
02033
02044 void setupScript( int argc, char** argv );
02045
02046
02052 class Pauser
02053 {
02054 VMachine *m_vm;
02055 public:
02056 inline Pauser( VMachine *vm ):
02057 m_vm( vm ) { m_vm->idle(); }
02058
02059 inline ~Pauser() { m_vm->unidle(); }
02060 };
02061
02065 const VMBaton& baton() const { return m_baton; }
02066
02070 VMBaton& baton() { return m_baton; }
02071
02084 void postMessage( VMMessage *vm );
02085
02087 uint32 generation() const;
02088
02100 void performGC( bool bWaitForCollection = false );
02101
02103 void incref();
02104
02108 void decref();
02109
02121 void finalize();
02122
02124 void setFinalizeCallback( void (*finfunc)( VMachine* vm ) )
02125 {
02126 m_onFinalize = finfunc;
02127 }
02128
02130 const String& appSearchPath() const { return m_appSearchPath; }
02131
02133 void appSearchPath( const String &p ) { m_appSearchPath = p; }
02134
02155 virtual void onIdleTime( numeric seconds );
02156
02164 void bindItem( const String& name, const Item& value );
02165
02173 void unbindItem( const String& name, Item &tgt ) const;
02174
02176 void jump( uint32 pos )
02177 {
02178 m_currentContext->pc_next() = pos;
02179 }
02180
02187 void expandTRAV( uint32 count, Iterator& iter );
02188
02189
02190
02191
02192
02193
02197 friend void opcodeHandler_END ( register VMachine *vm );
02198 friend void opcodeHandler_NOP ( register VMachine *vm );
02199 friend void opcodeHandler_PSHN( register VMachine *vm );
02200 friend void opcodeHandler_RET ( register VMachine *vm );
02201 friend void opcodeHandler_RETA( register VMachine *vm );
02202 friend void opcodeHandler_PTRY( register VMachine *vm );
02203
02204
02205 friend void opcodeHandler_LNIL( register VMachine *vm );
02206 friend void opcodeHandler_RETV( register VMachine *vm );
02207 friend void opcodeHandler_FORK( register VMachine *vm );
02208 friend void opcodeHandler_BOOL( register VMachine *vm );
02209 friend void opcodeHandler_GENA( register VMachine *vm );
02210 friend void opcodeHandler_GEND( register VMachine *vm );
02211 friend void opcodeHandler_PUSH( register VMachine *vm );
02212 friend void opcodeHandler_PSHR( register VMachine *vm );
02213 friend void opcodeHandler_POP ( register VMachine *vm );
02214 friend void opcodeHandler_JMP ( register VMachine *vm );
02215 friend void opcodeHandler_INC ( register VMachine *vm );
02216 friend void opcodeHandler_DEC ( register VMachine *vm );
02217 friend void opcodeHandler_NEG ( register VMachine *vm );
02218 friend void opcodeHandler_NOT ( register VMachine *vm );
02219 friend void opcodeHandler_TRAL( register VMachine *vm );
02220 friend void opcodeHandler_IPOP( register VMachine *vm );
02221 friend void opcodeHandler_XPOP( register VMachine *vm );
02222 friend void opcodeHandler_GEOR( register VMachine *vm );
02223 friend void opcodeHandler_TRY ( register VMachine *vm );
02224 friend void opcodeHandler_JTRY( register VMachine *vm );
02225 friend void opcodeHandler_RIS ( register VMachine *vm );
02226 friend void opcodeHandler_BNOT( register VMachine *vm );
02227 friend void opcodeHandler_NOTS( register VMachine *vm );
02228 friend void opcodeHandler_PEEK( register VMachine *vm );
02229
02230
02231 friend void opcodeHandler_LD ( register VMachine *vm );
02232 friend void opcodeHandler_LDRF( register VMachine *vm );
02233 friend void opcodeHandler_ADD ( register VMachine *vm );
02234 friend void opcodeHandler_SUB ( register VMachine *vm );
02235 friend void opcodeHandler_MUL ( register VMachine *vm );
02236 friend void opcodeHandler_DIV ( register VMachine *vm );
02237 friend void opcodeHandler_MOD ( register VMachine *vm );
02238 friend void opcodeHandler_POW ( register VMachine *vm );
02239 friend void opcodeHandler_ADDS( register VMachine *vm );
02240 friend void opcodeHandler_SUBS( register VMachine *vm );
02241 friend void opcodeHandler_MULS( register VMachine *vm );
02242 friend void opcodeHandler_DIVS( register VMachine *vm );
02243 friend void opcodeHandler_MODS( register VMachine *vm );
02244 friend void opcodeHandler_BAND( register VMachine *vm );
02245 friend void opcodeHandler_BOR ( register VMachine *vm );
02246 friend void opcodeHandler_BXOR( register VMachine *vm );
02247 friend void opcodeHandler_ANDS( register VMachine *vm );
02248 friend void opcodeHandler_ORS ( register VMachine *vm );
02249 friend void opcodeHandler_XORS( register VMachine *vm );
02250 friend void opcodeHandler_GENR( register VMachine *vm );
02251 friend void opcodeHandler_EQ ( register VMachine *vm );
02252 friend void opcodeHandler_NEQ ( register VMachine *vm );
02253 friend void opcodeHandler_GT ( register VMachine *vm );
02254 friend void opcodeHandler_GE ( register VMachine *vm );
02255 friend void opcodeHandler_LT ( register VMachine *vm );
02256 friend void opcodeHandler_LE ( register VMachine *vm );
02257 friend void opcodeHandler_IFT ( register VMachine *vm );
02258 friend void opcodeHandler_IFF ( register VMachine *vm );
02259 friend void opcodeHandler_CALL( register VMachine *vm );
02260 friend void opcodeHandler_INST( register VMachine *vm );
02261 friend void opcodeHandler_ONCE( register VMachine *vm );
02262 friend void opcodeHandler_LDV ( register VMachine *vm );
02263 friend void opcodeHandler_LDP ( register VMachine *vm );
02264 friend void opcodeHandler_TRAN( register VMachine *vm );
02265 friend void opcodeHandler_LDAS( register VMachine *vm );
02266 friend void opcodeHandler_SWCH( register VMachine *vm );
02267 friend void opcodeHandler_IN ( register VMachine *vm );
02268 friend void opcodeHandler_NOIN( register VMachine *vm );
02269 friend void opcodeHandler_PROV( register VMachine *vm );
02270 friend void opcodeHandler_SSTA( register VMachine *vm );
02271 friend void opcodeHandler_SVAL( register VMachine *vm );
02272 friend void opcodeHandler_STPS( register VMachine *vm );
02273 friend void opcodeHandler_STVS( register VMachine *vm );
02274 friend void opcodeHandler_LSTA( register VMachine *vm );
02275 friend void opcodeHandler_LVAL( register VMachine *vm );
02276 friend void opcodeHandler_AND ( register VMachine *vm );
02277 friend void opcodeHandler_OR ( register VMachine *vm );
02278 friend void opcodeHandler_PASS( register VMachine *vm );
02279 friend void opcodeHandler_PSIN( register VMachine *vm );
02280
02281
02282 friend void opcodeHandler_STP ( register VMachine *vm );
02283 friend void opcodeHandler_STV ( register VMachine *vm );
02284 friend void opcodeHandler_LDVT( register VMachine *vm );
02285 friend void opcodeHandler_LDPT( register VMachine *vm );
02286 friend void opcodeHandler_STPR( register VMachine *vm );
02287 friend void opcodeHandler_STVR( register VMachine *vm );
02288 friend void opcodeHandler_TRAV( register VMachine *vm );
02289
02290 friend void opcodeHandler_INCP( register VMachine *vm );
02291 friend void opcodeHandler_DECP( register VMachine *vm );
02292
02293 friend void opcodeHandler_SHL( register VMachine *vm );
02294 friend void opcodeHandler_SHR( register VMachine *vm );
02295 friend void opcodeHandler_SHLS( register VMachine *vm );
02296 friend void opcodeHandler_SHRS( register VMachine *vm );
02297 friend void opcodeHandler_CLOS( register VMachine *vm );
02298 friend void opcodeHandler_PSHL( register VMachine *vm );
02299 friend void opcodeHandler_POWS( register VMachine *vm );
02300 friend void opcodeHandler_LSB( register VMachine *vm );
02301 friend void opcodeHandler_SELE( register VMachine *vm );
02302 friend void opcodeHandler_INDI( register VMachine *vm );
02303 friend void opcodeHandler_STEX( register VMachine *vm );
02304 friend void opcodeHandler_TRAC( register VMachine *vm );
02305 friend void opcodeHandler_WRT( register VMachine *vm );
02306 friend void opcodeHandler_STO( register VMachine *vm );
02307 friend void opcodeHandler_FORB( register VMachine *vm );
02308 friend void opcodeHandler_EVAL( register VMachine *vm );
02309 friend void opcodeHandler_OOB( register VMachine *vm );
02310 friend void opcodeHandler_TRDN( register VMachine *vm );
02311 };
02312
02313
02314 class FALCON_DYN_SYM VMachineWrapper
02315 {
02316 private:
02317 VMachine *m_vm;
02318 public:
02319 VMachineWrapper():
02320 m_vm( new VMachine )
02321 {
02322 }
02323
02324 VMachineWrapper( VMachine *host ):
02325 m_vm(host)
02326 {}
02327
02328 ~VMachineWrapper()
02329 {
02330 m_vm->finalize();
02331 }
02332
02333 VMachine *operator->() const
02334 {
02335 return m_vm;
02336 }
02337
02338 VMachine *vm() const
02339 {
02340 return m_vm;
02341 }
02342 };
02343
02344 }
02345
02346 #endif
02347
02348