root/inc/cilVm.h

Revision 195, 62.0 kB (checked in by hak, 2 months ago)

Ver.0.91.0.137
- Added OSX/GCC support!
- Can compile in XCode 3.1/GCC 4.0.1 & Visual Studio 2005.
- Runs in OSX 10.5.4 & Windows XP/Vista
- Number::toString support a radix.
- BRFALSE bug fix
- Minor code clean up

Line 
1 /****************************************************************************
2  *
3  * CRI Middleware SDK
4  *
5  * Copyright (c) 2008 CRI Middleware, Inc. All rights reserved.
6  *
7  * Use, modification and distribution are subject to the CRI Script Software
8  * License, Version 1.0(see accompanying file "CriScript_License_1_0.txt" or
9  * copy at www.criscript.com/trac/wiki/CRI%20Script%20Software%20License%201.0 ).
10  *
11  *
12  * Library  : CRIScript
13  * Module   : cil VM definitions
14  * File     : cilVm.h
15  * Date     :
16  * Version  :
17  *
18  ****************************************************************************/
19 #pragma once
20
21 #include "criscript.h"
22 #include "versions.h"
23 #include "iCodeGen.h"
24 #include "cilCodeGen.h"
25 #include "variable.h"
26 #include "vmRuntimeError.h"
27
28 using namespace std;
29
30 namespace cri {
31
32 /***************************************************************************
33  *      VM costants
34  ***************************************************************************/
35 const int32_t LONGBR_ADJUST = 4;
36 const int32_t SHORTBR_ADJUST = 1;
37 const int32_t SIZE_LONGBR = 5;
38 const int32_t SIZE_SHORTBR = 2;
39
40 class CVmObject;
41
42 typedef CVmObject* VMOBJECTREF;
43
44 const int32_t VM_REFCOUNT_MANAGED = 0;//0x40000000;
45
46 /*EN Maximum callstack entries in a VM. assertion is triggerred when the callstack entries exceeds this number.
47 Note: Need tail recursion optimization
48 \ingroup MDL_LIB_VM
49 */
50 const int32_t MAX_CALLSTACK = 512;
51
52 /*EN Maximum evalstack entries in a VM. assertion is triggerred when the evalstack entries exceeds this number.
53 Note: Future optimization: Now eval stack push/pop involves ref count inc/dec. Needs non ref counter implementation.
54 \ingroup MDL_LIB_VM
55 */
56 const int32_t MAX_EVALSTACK = 4096;
57
58 /*EN Maximum local variable stack entries in a VM. assertion is triggerred when the local variable stack entries exceeds this number.
59 \ingroup MDL_LIB_VM
60 */
61 const int32_t MAX_LOCAL_VARIABLE = 256;
62
63 /*EN Maximum argument variable stack entries in a VM. assertion is triggerred when the argument variable stack entries exceeds this number.
64 \ingroup MDL_LIB_VM
65 */
66 const int32_t MAX_ARG_VARIABLE = 1024;
67
68
69 /***************************************************************************
70  *      VM HANDLER Type
71  ***************************************************************************/
72 /*EN User speficied VM handler types
73 \ingroup MDL_LIB_VM
74 */
75 enum VM_HANDLER_TYPE {
76         VM_HANDLER_EXCEPTIONNOTHANDLED, /*EN< Callback invoked when the exception is not handled*/
77         VM_HANDLER_MAX,
78 };
79
80 /*EN VM callback function signature
81 \ingroup MDL_LIB_VM
82 */
83 typedef void( *VM_HANDLER_CALLBACK )( int32_t iType, CVariable* pVar );
84
85
86 /***************************************************************************
87  *      VM status enum
88  ***************************************************************************/
89 /*EN Current VM statuses
90 \ingroup MDL_LIB_VM
91 */
92 enum VM_STATUS_TYPE {
93         VM_EXECUTE_INITIALIZING,        /*EN< VM instance is created but still not initialized yet*/
94         VM_EXECUTE_INITIALIZED,         /*EN< VM instance is initialized but still not executed yet*/
95         VM_EXECUTE_EXECUTING,           /*EN< VM instance is initialized but still not executed yet*/
96         VM_EXECUTE_DONE,                        /*EN< Byte code execution is finished successfully*/
97         VM_EXECUTE_SUSPENDED,           /*EN< VM suspended by resume() call. Not implemented yet*/
98         VM_EXECUTE_SWAPPEDOUT,          /*EN< VM time slice is ended and current context is swapped out. not implemented yet.*/
99         VM_EXECUTE_ERROR,                       /*EN< VM is in the error state*/
100 };
101
102 /***************************************************************************
103  *      VM reset Type
104  ***************************************************************************/
105 /*EN VM reset type
106 \ingroup MDL_LIB_VM
107 */
108 enum VM_RESET_TYPE {
109         VM_RESET_DEFAULT,       /*EN< Reset VM to the initialized status
110                                                                 All the fields values, objects statuses are reset.*/
111 };
112
113
114 /***************************************************************************
115  *      Callstack slot info
116  ***************************************************************************/
117 /*EN Callstack type
118 \ingroup MDL_LIB_VM
119 */
120 enum VM_CALLSTACK_TYPE {
121         VM_CALLSTACK_CALLSTACK, /*EN< Regular call stack */
122         VM_CALLSTACK_EH,                /*EN< Excepiton handling clause */
123 };
124
125 /*EN Execution status of the current clause
126 \ingroup MDL_LIB_VM
127 */
128 enum VM_EHCLAUSESTATUS_TYPE {
129         VM_EHCLAUSE_NORMAL                              =  0,           /*EN< Executing normally */
130         VM_EHCLAUSE_EXECUTING_CATCH             = -1,           /*EN< Executing catch clause */
131         VM_EHCLAUSE_EXECUTING_FINALLY   = -2,           /*EN< Executing finally clause */
132         VM_EHCLAUSE_RETURNING                   = -3,           /*EN< Returning from EH clause */
133         VM_EHCLAUSE_EXECUTED_CATCH              = -4,           /*EN< Executed catch clause */
134 };
135
136 /*EN Structure that represent a call stack information
137 \ingroup MDL_LIB_VM
138 */
139 struct VM_CALLSTACK {
140         VM_CALLSTACK_TYPE               type;                                   /*EN< Type of call stack*/
141         RID                                             ridMethod;                              /*EN< Method RID*/
142         uint8_t*                                pInstruction;                   /*EN< Return Instruction pointer*/
143         VM_EHCLAUSESTATUS_TYPE  status;                                 /*EN< Current execution status*/
144         union {
145                 /*EN Local variable start index*/
146                 int32_t                 iLocalVariableStartIndex;       
147                 /*EN Catch clause RID*/
148                 RID                                     ridCatch;
149         };
150         union {
151                 /*EN Argument list start index*/
152                 int32_t                 iArgumentListStartIndex;
153                 /*EN Finally clause RID*/
154                 RID                                     ridFinally;
155         };
156         /*EN Number of an argument used in the method*/
157         uint8_t                         iNumArgument;
158         /*EN Number of an argument given by callee*/
159         uint8_t                         iNumGivenArgument;
160         /*EN Flag that indicates if it's calling ctor.
161         When calling ctor, return value needed to be avoided*/
162         bool                            bConstructor;
163 };
164
165 /***************************************************************************
166  *      VM object definition
167  ***************************************************************************/
168 /*EN
169  A pointer to the CVmObject. Inherit a Code generation object metadata
170  \ingroup MDL_LIB_VM
171 */
172 class CVmObject : public CObjectTypeInfo {
173         int32_t         m_iRefCount;    /*EN< Reference Counter*/
174         CVariable       m_varPrototype; /*EN< A prototype object value*/
175         CVariable       m_varParent;    /*EN< A parent value, needed for a property access*/
176         CVariable       m_varValue;             /*EN< A value of the object*/
177
178         /*EN An accessor for the prototype varialbe*/
179         static CVariable* prototypeAccessor(CCilVm* const pVm,
180                                                                                 CVmObject* const pObject,
181                                                                                 const wstring* const pName,
182                                                                                 CVariable* const var,
183                                                                                 const bool bSet );
184
185 public:
186         CVmObject();                                                    /*EN< ctor*/
187         ~CVmObject();                                                   /*EN< dtor*/
188         CVmObject( const CVmObject& right );    /*EN< Copy ctor*/
189
190         /*EN Increments a reference count of the object.
191         \return current reference count value
192         */
193         int32_t addRef();
194
195         /*EN Decrements a reference count of the object.
196         \return current reference count value
197         */
198         int32_t release();
199
200         /*EN Enforce to set a reference count of the object.
201         \param iCount new reference count value to be set
202         */
203         void setRefCount( int32_t iCount ) { m_iRefCount = iCount; }
204
205         /*EN Retrieves a reference count of the object.
206         \return areference count value
207         */
208         int32_t getRefCount() { return m_iRefCount; }
209
210         /*EN Clears a reference count value to 0.
211         */
212         void clearRefCount( void );
213         /*EN Sets a prototype object.
214         \param pPrototype A pointer to the prototype VM Object
215         \param type operand type, usually OPERAND_OBJECTREF.
216         \param flag flags
217         */
218         void setPrototypeObject( CVmObject* const pPrototype,
219                                                                 const OPERAND_TYPE type = OPERAND_OBJECTREF,
220                                                                 const OPERAND_FLAG flag = OPERAND_FLAG( OPERAND_FLAG_DONTDELETE
221                                                                                                         | OPERAND_FLAG_DONTENUM ) )
222         {
223                 assert( type == OPERAND_OBJECTREF );
224                 m_varPrototype.setObjectRefWithFlags( pPrototype, flag, RID_NULL );
225         }
226
227         /*EN Retrieves a prototype object.
228         \return A prototype object reference.
229         A prototype object has a chain and finally goes to the Object prototype object.
230         */
231         CVmObject* getPrototypeObject( void ) { return m_varPrototype.refObject; }
232
233         /*EN Looks up the property with the given name
234         Use this version only when you are sure getter/setters are not involved in.
235         \param str A name of the property
236         \return A pointers to a value of the property. Returns NULL if a requested property does not exist.
237         */
238         CVariable* lookupProperty( const wstring& str );
239
240         /*EN Retrieves an iterator tothe property with the given name
241         Use this version only when you are sure getter/setters are not involved in.
242         \param str A name of the property
243         \return An iterator of the property. Returns invalid iterator when the property does not exist.
244         */
245         hash_map< wstring, CVariable >::iterator lookupPropertyIterator( const wstring& str );
246
247         /*EN Sets the property value with the given name
248         Use this version only when you are sure getter/setters are not involved in.
249         \param str A name of the property
250         \param value value of the property
251         */
252         void setProperty( const wstring& str, CVariable& value );
253
254         /*EN Looks up the property with the given name.
255         This version can invoke a getter.
256         \param pVm A pointer to the VM instance
257         \param str A name of the property
258         \return A pointers to a value of the property. Returns NULL if a requested property does not exist.
259         */
260         CVariable* lookupProperty( CCilVm* const pVm, const wstring& str, CVariable* const pThis = NULL );
261
262         /*EN Sets the property value with the given name
263         This version can invoke a setter.
264         Use this version only when you are sure getter/setters are not involved in.
265         \param pVm A pointer to the VM instance
266         \param str A name of the property
267         \param value value of the property
268         */
269         void setProperty( CCilVm* const pVm, const wstring& str, CVariable& value );
270
271         /*EN Sets the method property with the given name
272         \param pVm A pointer to the VM instance
273         \param name A name of the property
274         \param ridMethod RID value of the method
275         \param iLength A number of parameters that the method can accept. This value is set to method.length property.
276         */
277         void setProperty( CCilVm* const pVm,
278                                  const wstring& name,
279                                  const RID ridMethod,
280                                  const int32_t iLength );
281
282         /*EN Removes a specified property.
283         \param name A name of the property to be removed
284         */
285         void removeProperty( const wstring& name );
286
287         /*EN Sets a property accessor.
288         \param name A name of the property that the accessor will be set
289         \param pAccessro A pointer of the accessor callback
290         */
291         void setPropertyAccessor( const wstring& name, PACCESSORMETHOD pAccessor );
292
293         /*EN Retrieves a value of the object.
294         \return value of the object
295         */
296         CVariable& getValue( void )
297         {
298                 return m_varValue;
299         }
300
301         /*EN Set a value of the object.
302         \param var an object value
303         */
304         void setValue( CVariable& var )
305         {
306                 var.moveTo( m_varValue );
307                 return;
308         }
309
310         /*EN Retrieves a parent variable of the object.
311         \return value of the object
312         */
313         CVariable& getParentVariable( void ) { return m_varParent; }
314
315         /*EN Set a parent value of the object.
316         \param variable a parent value of the object value
317         */
318         void setParentVariable( const CVariable& variable ) { m_varParent = variable; }
319
320 };
321
322 //Some forward decl
323 class CCilDebugger;
324
325 /***************************************************************************
326  *      CIL VM implementation
327  ***************************************************************************/
328         /*EN
329          \brief The VM class for CRI Script byte code strem
330          \ingroup MDL_LIB_VM
331         */
332         class CCilVm
333         {
334         public:
335                 CCilVm();       /*EN< ctor*/
336                 ~CCilVm();      /*EN< dtor*/
337
338                 /*EN Initialize the VM.
339                 \return true when the initialization succeeded.
340                 */
341                 bool init();
342
343                 /*EN verify an attathed byte code stream.
344                 \return true when the verification succeeded.
345                 */
346                 bool verify();
347
348                 /*EN reset VM status to Initilized status
349                 \param iResetType VM reset type
350                 \return true when the reset succeeded.
351                 */
352                 bool reset( const VM_RESET_TYPE iResetType );
353
354                 /*EN Retrieve Version Number of the VM */
355                 const CRISCRIPT_VERSIONS& getVersions(void) { return criscript_version_struct; }
356
357                 //----------------------------------------------------------------------
358                 //VM Management
359                 //----------------------------------------------------------------------
360                 /*EN execute the byte code.
361                 \return current execution status.
362                 */
363                 VM_STATUS_TYPE execute();
364
365                 /*EN Retrieves an exit code of the script.
366                 \return exit code value. If the exit code can not be converted via ToNumber(), 0 is returned.
367                 An exit code is set from the script variable 'System.Environment.ExitCode' .
368                 */
369                 int32_t getExitCode();
370
371                 //----------------------------------------------------------------------
372                 //Register Handler
373                 //----------------------------------------------------------------------
374                 /*EN Register VM handlers.
375                 \return a handler which was set prior to the given handler. New handler should make sure to call prior set handler.
376                 \param handlertype handler type to set
377                 \param pCallBack a callback pointer
378                 */
379                 VM_HANDLER_CALLBACK registerHandler( VM_HANDLER_TYPE handlertype, VM_HANDLER_CALLBACK pCallBack );
380
381                 //----------------------------------------------------------------------
382                 //Initialize engines
383                 //----------------------------------------------------------------------
384                 /*EN Attaches an IL(intermediate language) stream to the VM.
385                 return: true when succeeded.
386                 */
387                 bool setILPool( const std::vector< uint8_t >& vecIL);
388                
389                 /*EN Attaches an IL(intermediate language) stream to the VM.
390                  return: true when succeeded.
391                  */
392                 bool setILPool( const uint8_t* pILPool, const size_t size_t);
393
394                 /*EN Attaches a metadata for corresponding IL(intermediate language) stream to the VM.
395                 \return true when succeeded.
396                 */
397                 bool setMetaData( CMetaData& MetaData );
398
399                 /*EN Retrieves currently set metadata.
400                 \return currently set metadata.
401                 */
402                 CMetaData& getMetaData() { return m_MetaData; }
403
404                 /*EN Binds a built in method to the VM.
405                 \param strQualifiedName Fully qualified name of the method that need to be bound.
406                 \param pMethod A pointer to the method that need to be bound.
407                 \param iLength A number of arguments that the method can accept. This number is set to method.length property.
408                 \return true when the binding succeeded, false otherwise.
409                 */
410                 bool bindBuiltinMethod( const wstring& strQualifiedName,
411                                                                 PMETHOD const pMethod,
412                                                                 const int32_t iLength );
413
414                 /*EN Binds a built in method to the VM with a wrapper code given.
415                 \param strQualifiedName Fully qualified name of the method that need to be bound.
416                 \param pMethod A pointer to the wrapper code that is generated semi-automatically.
417                 \param pMethodBody A pointer to the method that need to be bound.
418                 \return true when the binding succeeded, false otherwise.
419                 */
420                 bool bindBuiltinMethod( const wstring& strQualifiedName,
421                                                                 PMETHOD const pMethod, PMETHOD const pMethodBody );
422
423                 /*EN Binds a built in method to the VM.
424                 \param strQualifiedName Fully qualified name of the variable that need to be bound.
425                 \param pvar A pointer to the variable that need to be bound.
426                 \return true when the binding succeeded, false otherwise.
427                 */
428                 bool bindBuiltinVariable( const wstring& strQualifiedName,
429                                                                 CVariable* const pvar );
430
431                 //----------------------------------------------------------------------
432                 //Field accesssor
433                 //----------------------------------------------------------------------
434                 /*EN Retrieve a static field value with given RID.
435                 \param rid RID to retrieve a value.
436                 \return variable that with given RID
437                 */
438                 CVariable& getStaticField( const RID rid );
439
440                 /*EN Set a static field value with given RID.
441                 \param rid RID to set a value.
442                 \param value a reference to a value to set.
443                 \return true when the value is set successfully, false otherwise.
444                 */
445                 bool setStaticField( const RID rid, const CVariable& value );
446
447                 /*EN Set a static field value with given RID.
448                 \param rid RID of the static field to be initialized
449                 \param value a reference to a value to set.
450                 \param bForce true enforces an overwriting the value even READONLY flag is set.
451                 \return true when the value is set successfully, false otherwise.
452                 */
453                 bool setStaticField( const RID rid, const CVariable& value, bool bForce );
454                
455                 //----------------------------------------------------------------------
456                 //Debug functions
457                 //----------------------------------------------------------------------
458                 /*EN Attaches a debugger interface to the VM.
459                 \param pDebugger A pointer to the debugger interface
460                 \return true when the debugger successfully attached. false otherwise.
461                 */
462                 bool attachDebugger( CCilDebugger* const pDebugger ) { m_pDebugger = pDebugger; return true; }
463                
464                 /*EN Dettaches a debugger interface from the VM.
465                 \return true when the debugger successfully dettached. false otherwise.
466                 */
467                 bool detachDebugger() { m_pDebugger = NULL; return true; }
468                
469                 /*EN Sets a map of symbol information.
470                 \attention Symbol information and metadata APIs will be redesigned later.
471                 \param symbolinfo map of the symbol information.
472                 \return true when the symbol information map successfully set. false otherwise.
473                 */
474                 bool setSymbolInformation( hash_map<wstring, CG_SYMBOL_INFORMATION>& symbolinfo);
475
476                 /*EN Query a symbol information
477                 \param symbolName Fully qualified name of the symbol.
478                 \return Information related to hte symbol
479                 */
480                 CG_SYMBOL_INFORMATION& querySymbolInformation( const wstring& symbolName );
481
482                 /*EN dump current VM status including variables and IL stream to stdout. This API is for Debug purpose.
483                 */
484                 void debugDumpStats( void );
485
486                 //----------------------------------------------------------------------
487                 //Invoke method from outside of the current context
488                 //----------------------------------------------------------------------
489                 /*EN Invokes a methods directly from C++ code.
490                 \return A return value from the byte code method.
491                         Returned value need to be freed as a caller's responsibility.
492                 \param ridMethod RID of the calling method.
493                 \param iNumArg A number of arguments for the methods.
494                 \param pArguments A pointer to the argument array
495                 */
496                 CVariable* invokeMethod( const RID ridMethod, const int32_t iNumArg,
497                                                                                            CVariable* pArguments );
498
499                 //----------------------------------------------------------------------
500                 //Get object pool
501                 //----------------------------------------------------------------------
502                 /*EN Retrieves an object pool list
503                 \return A reference to the object pool. An object pool is a implemented with STL::list
504                 */
505                 list< CVmObject >& getObjectPool() { return m_ObjectPool; }
506
507                 /*EN Retrieves a prototype object for given RID
508                 \return A reference to the prototype object.
509                 */
510                 CVmObject& getPrototypeObject( const RID ridPrototype );
511
512                 //----------------------------------------------------------------------
513                 //Throw an exception from the API
514                 //----------------------------------------------------------------------
515                 /*EN Throws an exception from inside of built-in functions.
516                 \param errObject a pointer to the error object.
517                 */
518                 void throwException( CVariable* errObject );
519                 /*EN Throws an exception from inside of built-in functions.
520                 \param pstrMessage A pointer to an error description
521                 \param pstrName A pointer to an error name
522                 \param iNumber A pointer to an error number
523                 */
524                 void throwException( wstring* pstrMessage, wstring* pstrName = NULL , int32_t iNumber = -1 );
525
526                 //----------------------------------------------------------------------
527                 //Object handlings
528                 //----------------------------------------------------------------------
529                 /*EN Creates a prototype objecft with given RIDs
530                 \param ridObject RID of the prototype object
531                 \param ridObjectName String RID of the object name
532                 \param ridPrototype Object RID of a prototype object for the object
533                 \return RID of created prototype object
534                 */
535                 RID createPrototypeObject( const RID ridObject,
536                                                                 const RID ridObjectName,
537                                                                 const RID ridPrototype );
538
539                 /*EN Creates an object with given RID and store it to the object pool
540                 \param ridObject RID of the object to be created
541                 \return A pointer to the created object. An object resides in a object pool and has reference count for Garbage collector,
542                 */
543                 VMOBJECTREF createObject( const RID ridObject );
544
545                 /*EN Retrieve an object from the variable. If the variable is not an object, a prototype object reference is returned.
546                 \param var A reference to the variable
547                 \return A pointer to the object or prototype object that corresponds to the variable type
548                 */
549                 VMOBJECTREF getObjectPointer( CVariable& var );
550
551                 //----------------------------------------------------------------------
552                 //Static members
553                 //----------------------------------------------------------------------
554                 /*EN Retrieves Object prototype object RID
555                 \return RID of the Object prototype object
556                 */
557                 static RID getObjectRID() { return m_ridObject; }
558                 /*EN Retrieves Array prototype object RID
559                 \return RID of the Array prototype object
560                 */
561                 static RID getArrayObjectRID() { return m_ridArrayObject; }
562                 /*EN Retrieves String prototype object RID
563                 \return RID of the String prototype object
564                 */
565                 static RID getStringObjectRID() { return m_ridStringObject; }
566                 /*EN Retrieves Function prototype object RID
567                 \return RID of the Function prototype object
568                 */
569                 static RID getFunctionObjectRID() { return m_ridFunctionObject; }
570                 /*EN Retrieves System prototype object RID
571                 \return RID of the System prototype object
572                 */
573                 static RID getSystemObjectRID() { return m_ridSystemObject; }
574                 /*EN Retrieves Boolean prototype object RID
575                 \return RID of the Boolean prototype object
576                 */
577                 static RID getBooleanObjectRID() { return m_ridBooleanObject; }
578                 /*EN Retrieves Number prototype object RID
579                 \return RID of the Number prototype object
580                 */
581                 static RID getNumberObjectRID() { return m_ridNumberObject; }
582                 /*EN Retrieves Date prototype object RID
583                 \return RID of the Date prototype object
584                 */
585                 static RID getDateObjectRID() { return m_ridDateObject; }
586                 /*EN Retrieves Regex prototype object RID
587                 \return RID of the Regex prototype object
588                 */
589                 static RID getRegexObjectRID() { return m_ridRegexObject; }
590                 /*EN Retrieves Error prototype object RID
591                 \return RID of the Error prototype object
592                 */
593                 static RID getErrorObjectRID() { return m_ridErrorObject; }
594                 /*EN Retrieves Math prototype object RID
595                &n