root/inc/cilVm.h

Revision 195, 62.0 kB (checked in by hak, 10 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                 \return RID of the Math prototype object
596                 */
597                 static RID getMathObjectRID() { return m_ridMathObject; }
598
599                 //----------------------------------------------------------------------
600                 //Eval stack manipulations
601                 //Those need to be exposed for built in/user supplied functions
602                 //----------------------------------------------------------------------
603                 void pushEvalStack( const CVariable& operand );
604                 void pushEvalStack( const int32_t i );
605                 void pushEvalStack( const int64_t i );
606                 void pushEvalStack( const float f );
607                 void pushEvalStack( const double d );
608                 void pushEvalStack( const bool b );
609                 void pushEvalStackUndefined();
610                 void pushEvalStackNaN();
611                 void pushEvalStackInfinity();
612                 void pushEvalStackNull();
613                 void pushEvalStackObjectRef( const VMOBJECTREF refObject );
614                 void pushEvalStackVariable( const CVariable& var );
615                 void pushEvalStackString( const wchar_t* );
616                 void pushEvalStackString( const wstring* str );
617                 void pushEvalStackStringPointer( wstring* str );        //Pointer is stored directory and should not be deleted
618
619                 //----------------------------------------------------------------------
620                 //Eval stack helpers
621                 //----------------------------------------------------------------------
622                 void popPushEvalStack( const int32_t i ) { popEvalStack(); popEvalStack(); pushEvalStack( i ); };
623                 void popPushEvalStack( const int64_t i ) { popEvalStack(); popEvalStack(); pushEvalStack( i ); };
624                 void popPushEvalStack( const float f ) { popEvalStack(); popEvalStack(); pushEvalStack( f ); };
625                 void popPushEvalStack( const double d ) { popEvalStack(); popEvalStack(); pushEvalStack( d ); };
626                 void popPushEvalStack( const bool b ) { popEvalStack(); popEvalStack(); pushEvalStack( b ); };
627                 void popPushEvalStackUndefined() { popEvalStack(); popEvalStack(); pushEvalStackUndefined(); };
628                 void popPushEvalStackNaN() { popEvalStack(); popEvalStack(); pushEvalStackNaN(); };
629                 void popPushEvalStackNull() { popEvalStack(); popEvalStack(); pushEvalStackNull(); };
630                 void popPushEvalStackInfinity() { popEvalStack(); popEvalStack(); pushEvalStackInfinity(); };
631                 void popThrowTypeError() {      popEvalStack();
632                                                                         popEvalStack();
633                                                                         pushEvalStackNaN();
634                                                                         ThrowExceptionFromVm( &wstring( ERRORSTRING_TYPEERROR_STORESTATICFIELD ),
635                                                                                 &wstring( NAME_BUILTIN_ERROR_OBJECT ),
636                                                                                 ERROR_TYPEERROR_STORESTATICFIELD );
637                                                                 };
638
639                 void popEvalStack( void );
640                 void popEvalStackFast( void );
641                 bool isEvalStackEmpty();
642                 void dupEvalStack( void );
643                 size_t getEvalStackSize();
644                 CVariable& getEvalStackFirstEntry();
645                 CVariable& getEvalStackSecondEntry();
646                 CVariable& getEvalStackNewEntry();
647
648                 void clearEvalStack();                  /*EN< Clear eval stack*/
649                 void clearLocalVariableList();  /*EN< Clear local variable list*/
650                 void clearArgList();                    /*EN< Clear argument list*/
651                 void clearCallStack();                  /*EN< Clear call stack*/
652                 void clearStaticFields();               /*EN< Clear static field*/
653
654                 //----------------------------------------------------------------------
655                 //Operator routines
656                 //Those need to be exposed for built-in/user supplied functions
657                 //----------------------------------------------------------------------
658                 /*EN Retrieve an argument list
659                 \return reference of the array list
660                 */
661                 CVariable* getArgumentList() { return m_ArgList; };
662
663                 /*EN Retrieve a local variable list
664                 \return reference of the local list
665                 */
666                 CVariable* getLocalList() { return m_LocalVariableList; };
667
668                 /*EN Takes a variable from the eval stack and stores it to the static field with given RID
669                 \param rid RID of the static field that the value to be stored in.
670                 */
671                 void storeStaticField( const RID rid );
672
673                 /*EN Takes a variable from static field with given RID and put the variable to the eval stack
674                 \param rid RID of the static field that the value is to be loaded from.
675                 */
676                 void loadStaticField( const RID rid );
677
678                 /*EN Takes a variable from the eval stack and stores it to the local variable with given index
679                 \param iIndex An index of a local variable. Negative index means a local variable in the enclosing scope.
680                 */
681                 void storeLocalVariable( const int32_t iIndex );
682
683                 /*EN Takes a variable of the local variable with given index and push it to the eval stack.
684                 \param iIndex An index of a local variable. Negative index means a local variable in the enclosing scope.
685                 */
686                 void loadLocalVariable( const int32_t iIndex );
687
688                 /*EN Takes a variable from the eval stack and stores it to the argument list with given index
689                 \param iIndex An index of an argument list. 0 means this pointer, Negative index means a local variable in the enclosing scope.
690                 */
691                 void storeArgument( const int32_t iIndex );
692
693                 /*EN Takes a variable from the argument list with given index and push it to the eval stack.
694                 \param iIndex An index of an argument list. 0 means this pointer, Negative index means a local variable in the enclosing scope.
695                 */
696                 void loadArgument( const int32_t iIndex );
697
698                 /*EN Retrieves a table of the static field vector
699                 \return A vector of the static field variables
700                 */
701                 CVariable* getStaticFieldTable() { return m_pStaticFieldTable; }
702
703                 /*EN Takes a variable from the eval stack and stores it to the destination variable with a respect of a type constraint.
704                 \param varDest A reference of a variable that the value from an eval stack is stored in.
705                 */
706                 void storeAsRestrictedType( CVariable& varDest );
707
708                 /*EN Calls given RID, invoked from Function.apply*/
709                 void CallOperator( const CVariable* thisPointer,
710                                                         const RID rid,
711                                                         const bool bConstructor = false );
712                 /*EN Stores a variable to argument list by hand. Invoked from Function.apply*/
713                 void storeArgumentList( const CVariable& var );
714
715                 /*EN Generates 'arguments' property based on current callstack and arguments list information on the fly.
716                 */
717                 CVariable* generateArgumentsProperty();
718                
719                 /*EN Generates 'restArguments' argument if the method signature requires it.
720                 This helper should be called immediate before function call.
721                 */
722                 void generateRestArguments( int32_t iNumArgsToStore );
723
724                 /*EN Generates 'caller' property based on current callstack and arguments list information on the fly.
725                 */
726                 CVariable* generateCallerProperty();
727
728                 /*EN Disposes arguments given to the API explicitly*/
729                 void disposeArgumentList();
730
731                 /*EN Resets number of arguments in the list*/
732                 void resetArgumentList();
733
734                 /*EN Returns exception handler nesting level
735                 \return Current exception handler nesting level.
736                         Return non zero if current code is inside an exception handler clause.
737                 */
738                 int32_t getExectipnHandlerNestingLevel() { return m_ExceptionHandlerNestingLevel; }
739
740
741                 //----------------------------------------------------------------------
742                 //Print() management
743                 //----------------------------------------------------------------------
744                 /*EN Flush print() buffer if some strings are in the buffer, otherwise, do nothing..
745                 */
746                 void flushPrintBuffer() { wprintf( m_strPrintBuffer.data() ); m_strPrintBuffer.clear(); }
747
748                 /*EN Retrieves print() buffer if some strings are in the buffer, otherwise, do nothing..
749                 \return A reference for the wstring that is used for print() intermedeiate buffer
750                 */
751                 wstring& getPrintBuffer() { return m_strPrintBuffer; }
752
753                 /*EN Retrieves print() buffer if some strings are in the buffer, otherwise, do nothing..
754                 \param str wstring that will be printed.
755                 */
756                 void appendPrintBuffer( wstring& str ) { m_strPrintBuffer.append( str ); }
757
758         private:
759                 //----------------------------------------------------------------------
760                 //Initialize engines
761                 //----------------------------------------------------------------------
762                 bool setStaticFieldTypeTable( vector< OPERAND_TYPE_FLAG >& vecSFType );
763                 void initializePrototypeObjects();
764
765                 /*EN Set a static field value with a function object with given method RID.
766                 This method is a helper function to initialize a static field
767                 \param rid RID to set a value.
768                 \param ridMethod RID of the method
769                 \return true when the value is set successfully, false otherwise.
770                 */
771                 bool setStaticFieldFunctionObject( const RID rid, const RID ridMethod );
772
773                 //----------------------------------------------------------------------
774                 //Garbage collector helper
775                 //----------------------------------------------------------------------
776                 void clearRefCount();
777                 void cleanObjectPool();
778
779                 //----------------------------------------------------------------------
780                 //Throw an exception from the VM
781                 //----------------------------------------------------------------------
782                 void ThrowExceptionFromVm( wstring* pstrMessage, wstring* pstrName = NULL , int32_t iNumber = -1 );
783
784                 //----------------------------------------------------------------------
785                 //Byte code stream accesser
786                 //----------------------------------------------------------------------
787                 uint8_t getNextBytecode( void );        /*EN< Retrieve next byte code from an attached byte code stream*/
788                 RID getNextToken( void );                       /*EN< Retrieve next Token from an attached byte code stream*/
789                 int32_t getNextInt32( void );           /*EN< Retrieve next int32_t value from an attached byte code stream*/
790                 int64_t getNextInt64( void );           /*EN< Retrieve next int64_t value from an attached byte code stream*/
791                 int8_t getNextInt8( void );                     /*EN< Retrieve next int8_t value from an attached byte code stream*/
792                 uint8_t getNextUint8( void );           /*EN< Retrieve next uint8_t value from an attached byte code stream*/
793                 float getNextFloat( void );                     /*EN< Retrieve next float value from an attached byte code stream*/
794                 double getNextDouble( void );           /*EN< Retrieve next double value from an attached byte code stream*/
795
796                 //----------------------------------------------------------------------
797                 //Private Field accessor
798                 //----------------------------------------------------------------------
799                 CVariable& getLocalVariable( const int32_t iIndex );
800                 bool setLocalVariable( const int32_t iIndex, const CVariable& value );
801                 CVariable& getArgument( const int32_t iIndex );
802                 bool setArgument( const int32_t iIndex, const CVariable& value );
803
804                 //----------------------------------------------------------------------
805                 //call stack accesses
806                 //----------------------------------------------------------------------
807                 /*EN Retrieves a top of the callstack regardless of a stack type.
808                 A callstack could be one of the callstack, exception handlers
809                 \return A pointer to the callstack top entry
810                 */
811                 VM_CALLSTACK* getCurrentCallStack() { return &m_CallStack.back(); }
812
813                 /*EN Search and retrieves a callstack entries with given argument criteria matches
814                 \param type A type of callstack to be returned
815                 \param iLevel A callstack level to be returned.
816                 \return A pointer to the callstack entry that matches an arguments criateria
817                 */
818                 VM_CALLSTACK* getCurrentCallStack( const VM_CALLSTACK_TYPE type, int iLevel = 1 )
819                 {
820                         vector< VM_CALLSTACK >::reverse_iterator it = m_CallStack.rbegin();
821                         while( it != m_CallStack.rend() )
822                         {
823                                 if( it->type == type && !(--iLevel) )
824                                 {
825                                         return &*it;
826                                 }
827                                 ++it;
828                         }
829                         return NULL;
830                 }
831
832                 //----------------------------------------------------------------------
833                 //Operator routines
834                 //----------------------------------------------------------------------
835                 void addOperator();
836                 void subtractOperator();
837                 void multiplyOperator();
838                 void divisionOperator();
839                 void negOperator();
840                 void reminderOperator();
841                 void incStaticFieldOperator( const RID rid );
842                 void incOperator();
843                 void decOperator();
844
845                 void bitwiseAndOperator();
846                 void bitwiseOrOperator();
847                 void bitwiseXorOperator();
848                 void bitwiseNotOperator();
849
850                 void ShlOperator();
851                 void ShrOperator();
852                 void ShrUnOperator();
853
854                 void BrTrueOperator();
855                 void BrTrueShortOperator();
856                 void BrFalseOperator();
857                 void BrFalseShortOperator();
858
859                 void BeqOperator();
860                 void BeqShortOperator();
861                 void BneOperator();
862                 void BneShortOperator();
863                 void BngeOperator();
864                 void BngeShortOperator();
865                 void BngtOperator();
866                 void BngtShortOperator();
867                 void BnleOperator();
868                 void BnleShortOperator();
869                 void BnltOperator();
870                 void BnltShortOperator();
871
872                 void CeqOperator();
873                 void CneOperator();
874                 void CgtOperator();
875                 void CgeOperator();
876                 void CleOperator();
877                 void CltOperator();
878
879                 void CallOperator();                                                                    //call given rid
880                 void CallOperator( const CVariable& var );                                      //call given variable
881                 bool RetOperator();
882                 void CreateNewObject();
883                 void CreateNewStringValue();
884                 void LoadObjectRef();
885                 void EnterOperator();
886                 void LeaveOperator();
887                 void ThrowOperator();
888                 void FinallyOperator();
889
890                 void convertToBoolean();
891
892                 //----------------------------------------------------------------------
893                 //Local variables
894                 //----------------------------------------------------------------------
895                 void reserveLocalVariables( const RID ridLocalsToReserve );
896                 void disposeLocalVariables( const uint32_t iLocalsToDispose );
897                 uint32_t getCurrentLocalVariableIndex( void ) { return (uint32_t)m_iLocalVariableListIndex; }
898
899                 //----------------------------------------------------------------------
900                 //Argument list
901                 //----------------------------------------------------------------------
902                 void storeArgumentListWithThisPointer( const uint32_t iArgToStore );
903                 void storeArgumentListWithoutThisPointer( const uint32_t iArgToStore );
904                 void disposeArgumentList( const uint32_t iArgToDispose );
905                 uint32_t getCurrentArgumentListIndex( void ) { return (uint32_t)m_iArgListIndex; }
906                 void pushArgumentListUndefined( void );
907                 void popArgumentList( void );
908                
909                 //----------------------------------------------------------------------
910                 //ILPool vector
911                 //each function object has 1 ILFRAGMENTINFO
912                 //----------------------------------------------------------------------
913                 ILFRAGMENTINFO m_CurrentILPool;
914
915                 //----------------------------------------------------------------------
916                 // VM status
917                 //----------------------------------------------------------------------
918                 uint8_t* m_pCurrentInstruction;
919                 int32_t m_iTickCount;
920                 VM_STATUS_TYPE m_status;
921                
922                 //----------------------------------------------------------------------
923                 //Debug Variables
924                 //----------------------------------------------------------------------
925                 CStopWatch m_stopwatch;
926                 CCilDebugger* m_pDebugger;
927                 map<wstring, CG_SYMBOL_INFORMATION> m_SymbolInfoPool;           //Symbol information
928                 
929                 //----------------------------------------------------------------------
930                 //Evaluation stack
931                 //----------------------------------------------------------------------
932                 CVariable       m_OperandEvalStack[ MAX_EVALSTACK ];
933                 CVariable*      m_pCurrentEvalStack;
934                 CVariable*      m_pMaxEvalStack;
935
936                 CVariable       m_LocalVariableList[ MAX_LOCAL_VARIABLE ];
937                 uint32_t        m_iLocalVariableListIndex;
938                 uint32_t        m_iMaxLocalVariableListIndex;
939
940                 CVariable       m_ArgList[ MAX_ARG_VARIABLE ];
941                 uint32_t        m_iArgListIndex;
942                 uint32_t        m_iMaxArgListIndex;
943
944                 void updateEvalStackIndex() {
945                         m_pCurrentEvalStack++;
946 #ifdef VM_TRACK_MAXSTACKUSAGE
947                         if( m_pCurrentEvalStack > m_pMaxEvalStack )
948                                 m_pMaxEvalStack = m_pCurrentEvalStack;
949 #endif
950                 }
951                 void updateLocalVariableListIndex() {
952                         m_iLocalVariableListIndex++;
953 #ifdef VM_TRACK_MAXSTACKUSAGE
954                         if( m_iLocalVariableListIndex > m_iMaxLocalVariableListIndex )
955                                 m_iMaxLocalVariableListIndex++;
956 #endif
957                 }
958                 void updateArgListIndex() {
959                         m_iArgListIndex++;
960 #ifdef VM_TRACK_MAXSTACKUSAGE
961                         if( m_iArgListIndex > m_iMaxArgListIndex )
962                                 m_iMaxArgListIndex++;
963 #endif
964                 }
965
966                 //----------------------------------------------------------------------
967                 //Variable Tables
968                 //----------------------------------------------------------------------
969                 CVariable*              m_pStaticFieldTable;    //This talbe is accesible through ld/stsfld instructions, accessed via RID
970                 uint32_t                m_iStaticFieldTalbeSize;
971                 list< CVmObject >       m_ObjectPool;
972                 vector< CVmObject >     m_BuiltinPrototypeObjectTable;
973                 CMetaData                       m_MetaData;
974
975                 //----------------------------------------------------------------------
976                 //Caller/calee stack
977                 //----------------------------------------------------------------------
978                 vector< VM_CALLSTACK > m_CallStack;
979                 uint32_t m_iCurrentThisPointerIndex;
980                 int32_t m_iCallStackRoot;
981                 int32_t m_iNumGivenArguments;   //Keep tracking # of arguments for Exception throw
982
983                 //----------------------------------------------------------------------
984                 //GC
985                 //----------------------------------------------------------------------
986
987                 //----------------------------------------------------------------------
988                 //MetaData
989                 //----------------------------------------------------------------------
990                 static RID m_ridObject;                                 //Object RID
991                 static RID m_ridFunctionObject;                 //Function Object RID
992                 static RID m_ridSystemObject;                   //System Object RID
993                 static RID m_ridStringObject;                   //String object RID
994                 static RID m_ridArrayObject;                    //Array object RID
995                 static RID m_ridErrorObject;                    //Error object RID
996                 static RID m_ridRegexObject;                    //Regex object RID
997                 static RID m_ridBooleanObject;                  //Boolean object RID
998                 static RID m_ridNumberObject;                   //Numer object RID
999                 static RID m_ridDateObject;                             //Date object RID
1000                 static RID m_ridMathObject;                             //Math object RID
1001
1002                 //----------------------------------------------------------------------
1003                 //print buffer, flushed when exiting the VM
1004                 //----------------------------------------------------------------------
1005                 wstring m_strPrintBuffer;                               /*<EN Buffer for print().*/
1006
1007                 //----------------------------------------------------------------------
1008                 //Exception handling
1009                 //----------------------------------------------------------------------
1010                 int32_t m_ExceptionHandlerNestingLevel; /*Excepiton Handler Nest Level*/
1011
1012                 //----------------------------------------------------------------------
1013                 //VM Handler
1014                 //----------------------------------------------------------------------
1015                 VM_HANDLER_CALLBACK m_Handler[ VM_HANDLER_MAX ];
1016                
1017         };
1018
1019         /***************************************************************************
1020          *      VM helper APIs
1021          ***************************************************************************/
1022 #define VMRET_INT int32_t
1023 #define VMRET_FLOAT float
1024 #define VMRET_DOUBLE double
1025         
1026 #define VMARG_INT int32_t
1027 #define VMARG_FLOAT float
1028 #define VMARG_DOUBLE double
1029         
1030         /*EN Wrapper template classes for user specified functions.
1031          This wrapper is for a function that does not require 'this' value.
1032          no parameter, with return variable version.
1033          \param pVm A pointer to the VM
1034          \param iNumArguments A number of given parameters.
1035          \param pArguments A pointer to the arguments array.
1036          \param pMethodBody An API body.
1037          \ingroup MDL_LIB_VM
1038          */
1039         template< class RET >
1040         void MakeWrapperStdP0( CCilVm* const pVm,
1041                                                   const int32_t iNumArguments,
1042                                                   CVariable* pArguments,
1043                                                   PMETHOD pMethodBody )
1044         {
1045                 RET ret = ((RET (*)( void ) )pMethodBody)();
1046                 pVm->pushEvalStack( ret );
1047                
1048                 return;
1049         }
1050        
1051         /*EN Wrapper template classes for user specified functions.
1052          This wrapper is for a function that does not require 'this' value.
1053          1 parameter, with return variable version.
1054          \param pVm A pointer to the VM
1055          \param iNumArguments A number of given parameters.
1056          \param pArguments A pointer to the arguments array.
1057          \param pMethodBody An API body.
1058          \ingroup MDL_LIB_VM
1059          */
1060         template< class RET, class P1 >
1061         void MakeWrapperStdP1( CCilVm* const pVm,
1062                                                   const int32_t iNumArguments,
1063                                                   CVariable* pArguments,
1064                                                   PMETHOD pMethodBody )
1065         {
1066                 //Skip This pointer
1067                 pArguments ++;
1068                
1069                 P1 param1;
1070                 switch( iNumArguments )
1071                 {
1072                         default:
1073                                 param1 = (P1)*pArguments;
1074                         case 1:
1075                                 break;
1076                 }
1077                
1078                 RET ret = ((RET (*)( P1 ) )pMethodBody)( param1 );
1079                 pVm->pushEvalStack( ret );
1080                
1081                 return;
1082         }
1083        
1084         /*EN Wrapper template classes for user specified functions.
1085          This wrapper is for a function that does not require 'this' value.
1086          2 parameters, with return variable version.
1087          \param pVm A pointer to the VM
1088          \param iNumArguments A number of given parameters.
1089          \param pArguments A pointer to the arguments array.
1090          \param pMethodBody An API body.
1091          \ingroup MDL_LIB_VM
1092          */
1093         template< class RET, class P1, class P2 >
1094         void MakeWrapperStdP2( CCilVm* const pVm,
1095                                                   const int32_t iNumArguments,
1096                                                   CVariable* pArguments,
1097                                                   PMETHOD pMethodBody )
1098         {
1099                 //Skip This pointer
1100                 pArguments ++;
1101                
1102                 P1 param1 = (P1)0;
1103                 P2 param2 = (P2)0;
1104                 switch( iNumArguments )
1105                 {
1106                         default:
1107                                 param2 = (P2)*(pArguments+1);
1108                         case 2:
1109                                 param1 = (P1)*pArguments;
1110                         case 1:
1111                                 break;
1112                 }
1113                
1114                 RET ret = ((RET (*)( P1, P2 ) )pMethodBody)( param1, param2 );
1115                 pVm->pushEvalStack( ret );
1116                
1117                 return;
1118         }
1119        
1120         /*EN Wrapper template classes for user specified functions.
1121          This wrapper is for a function that does not require 'this' value.
1122          3 parameters, with return variable version.
1123          \param pVm A pointer to the VM
1124          \param iNumArguments A number of given parameters.
1125          \param pArguments A pointer to the arguments array.
1126          \param pMethodBody An API body.
1127          \ingroup MDL_LIB_VM
1128          */
1129         template< class RET, class P1, class P2, class P3 >
1130         void MakeWrapperStdP3( CCilVm* const pVm,
1131                                                   const int32_t iNumArguments,
1132                                                   CVariable* pArguments,
1133                                                   PMETHOD pMethodBody )
1134         {
1135                 //Skip This pointer
1136                 pArguments ++;
1137                
1138                 P1 param1 = (P1)0;
1139                 P2 param2 = (P2)0;
1140                 P3 param3 = (P3)0;
1141                 switch( iNumArguments )
1142                 {
1143                         default:
1144                                 param3 = (P3)*(pArguments+2);
1145                         case 3:
1146                                 param2 = (P2)*(pArguments+1);
1147                         case 2:
1148                                 param1 = (P1)*pArguments;
1149                         case 1:
1150                                 break;
1151                 }
1152                
1153                 RET ret = ((RET (*)( P1, P2, P3 ) )pMethodBody)( param1, param2, param3 );
1154                 pVm->pushEvalStack( ret );
1155                
1156                 return;
1157         }
1158        
1159         /*EN Wrapper template classes for user specified functions.
1160          This wrapper is for a function that does not require 'this' value.
1161          4 parameters, with return variable version.
1162          \param pVm A pointer to the VM
1163          \param iNumArguments A number of given parameters.
1164          \param pArguments A pointer to the arguments array.
1165          \param pMethodBody An API body.
1166          \ingroup MDL_LIB_VM
1167          */
1168         template< class RET, class P1, class P2, class P3, class P4 >
1169         void MakeWrapperStdP4( CCilVm* const pVm,
1170                                                   const int32_t iNumArguments,
1171                                                   CVariable* pArguments,
1172                                                   PMETHOD pMethodBody )
1173         {
1174                 //Skip This pointer
1175                 pArguments ++;
1176                
1177                 P1 param1 = (P1)0;
1178                 P2 param2 = (P2)0;
1179                 P3 param3 = (P3)0;
1180                 P4 param4 = (P4)0;
1181                 switch( iNumArguments )
1182                 {
1183                         default:
1184                                 param4 = (P4)*(pArguments+3);
1185                         case 4:
1186                                 param3 = (P3)*(pArguments+2);
1187                         case 3:
1188                                 param2 = (P2)*(pArguments+1);
1189                         case 2:
1190                                 param1 = (P1)*pArguments;
1191                         case 1:
1192                                 break;
1193                 }
1194                
1195                 RET ret = ((RET (*)( P1, P2, P3, P4 ) )pMethodBody)( param1, param2, param3, param4 );
1196                 pVm->pushEvalStack( ret );
1197                
1198                 return;
1199         }
1200        
1201         /*EN Wrapper template classes for user specified functions.
1202          This wrapper is for a function that does not require 'this' value.
1203          5 parameters, with return variable version.
1204          \param pVm A pointer to the VM
1205          \param iNumArguments A number of given parameters.
1206          \param pArguments A pointer to the arguments array.
1207          \param pMethodBody An API body.
1208          \ingroup MDL_LIB_VM
1209          */
1210         template< class RET, class P1, class P2, class P3, class P4, class P5 >
1211         void MakeWrapperStdP5( CCilVm* const pVm,
1212                                                   const int32_t iNumArguments,
1213                                                   CVariable* pArguments,
1214                                                   PMETHOD pMethodBody )
1215         {
1216                 //Skip This pointer
1217                 pArguments ++;
1218                
1219                 P1 param1 = (P1)0;
1220                 P2 param2 = (P2)0;
1221                 P3 param3 = (P3)0;
1222                 P4 param4 = (P4)0;
1223                 P5 param5 = (P5)0;
1224                 switch( iNumArguments )
1225                 {
1226                         default:
1227                                 param5 = (P5)*(pArguments+4);
1228                         case 5:
1229                                 param4 = (P4)*(pArguments+3);
1230                         case 4:
1231                                 param3 = (P3)*(pArguments+2);
1232                         case 3:
1233                                 param2 = (P2)*(pArguments+1);
1234                         case 2:
1235                                 param1 = (P1)*pArguments;
1236                         case 1:
1237                                 break;
1238                 }
1239                
1240                 RET ret = ((RET (*)( P1, P2, P3, P4, P5 ) )pMethodBody)( param1, param2, param3, param4, param5 );
1241                 pVm->pushEvalStack( ret );
1242                
1243                 return;
1244         }
1245        
1246         //----------------------
1247         //Void return version
1248         //----------------------
1249         /*EN Wrapper template classes for user specified functions.
1250          This wrapper is for a function that does not require 'this' value.
1251          no parameter, without return variable version.
1252          \param pVm A pointer to the VM
1253          \param iNumArguments A number of given parameters.
1254          \param pArguments A pointer to the arguments array.
1255          \param pMethodBody An API body.
1256          \ingroup MDL_LIB_VM
1257          */
1258         void MakeWrapperStdVoidP0( CCilVm* const pVm,
1259                                                           const int32_t iNumArguments,
1260                                                           CVariable* pArguments,
1261                                                           PMETHOD pMethodBody );
1262         /*
1263          {
1264          ((void (*)( void ) )pMethodBody)();
1265          pVm->pushEvalStackUndefined();
1266         
1267          return;
1268          }*/
1269        
1270         /*EN Wrapper template classes for user specified functions.
1271          This wrapper is for a function that does not require 'this' value.
1272          1 parameter, without return variable version.
1273          \param pVm A pointer to the VM
1274          \param iNumArguments A number of given parameters.
1275          \param pArguments A pointer to the arguments array.
1276          \param pMethodBody An API body.
1277          \ingroup MDL_LIB_VM
1278          */
1279         template< class P1 >
1280         void MakeWrapperStdVoidP1( CCilVm* const pVm,
1281                                                           const int32_t iNumArguments,
1282                                                           CVariable* pArguments,
1283                                                           PMETHOD pMethodBody )
1284         {
1285                 //Skip This pointer
1286                 pArguments ++;
1287                
1288                 P1 param1;
1289                 switch( iNumArguments )
1290                 {
1291                         default:
1292                                 param1 = (P1)*pArguments;
1293                         case 1:
1294                                 break;
1295                 }
1296                
1297                 ((void (*)( P1 ) )pMethodBody)( param1 );
1298                 pVm->pushEvalStackUndefined();
1299                
1300                 return;
1301         }
1302        
1303         /*EN Wrapper template classes for user specified functions.
1304          This wrapper is for a function that does not require 'this' value.
1305          2 parameters, without return variable version.
1306          \param pVm A pointer to the VM
1307          \param iNumArguments A number of given parameters.
1308          \param pArguments A pointer to the arguments array.
1309          \param pMethodBody An API body.
1310          \ingroup MDL_LIB_VM
1311          */
1312         template< class P1, class P2 >
1313         void MakeWrapperStdVoidP2( CCilVm* const pVm,
1314                                                           const int32_t iNumArguments,
1315                                                           CVariable* pArguments,
1316                                                           PMETHOD pMethodBody )
1317         {
1318                 //Skip This pointer
1319                 pArguments ++;
1320                
1321                 P1 param1 = (P1)0;
1322                 P2 param2 = (P2)0;
1323                 switch( iNumArguments )
1324                 {
1325                         default:
1326                                 param2 = (P2)*(pArguments+1);
1327                         case 2:
1328                                 param1 = (P1)*pArguments;
1329                         case 1:
1330                                 break;
1331                 }
1332                
1333                
1334                 ((void (*)( P1, P2 ) )pMethodBody)( param1, param2 );
1335                 pVm->pushEvalStackUndefined();
1336                
1337                 return;
1338         }
1339        
1340         /*EN Wrapper template classes for user specified functions.
1341          This wrapper is for a function that does not require 'this' value.
1342          3 parameters, without return variable version.
1343          \param pVm A pointer to the VM
1344          \param iNumArguments A number of given parameters.
1345          \param pArguments A pointer to the arguments array.
1346          \param pMethodBody An API body.
1347          \ingroup MDL_LIB_VM
1348          */
1349         template< class P1, class P2, class P3 >
1350         void MakeWrapperStdVoidP3( CCilVm* const pVm,
1351                                                           const int32_t iNumArguments,
1352                                                           CVariable* pArguments,
1353                                                           PMETHOD pMethodBody )
1354         {
1355                 //Skip This pointer
1356                 pArguments ++;
1357                
1358                 P1 param1 = (P1)0;
1359                 P2 param2 = (P2)0;
1360                 P3 param3 = (P3)0;
1361                 switch( iNumArguments )
1362                 {
1363                         default:
1364                                 param3 = (P3)*(pArguments+2);
1365                         case 3:
1366                                 param2 = (P2)*(pArguments+1);
1367                         case 2:
1368                                 param1 = (P1)*pArguments;
1369                         case 1:
1370                                 break;
1371                 }
1372                
1373                 ((void (*)( P1, P2, P3 ) )pMethodBody)( param1, param2, param3 );
1374                 pVm->pushEvalStackUndefined();
1375                
1376                 return;
1377         }
1378        
1379         /*EN Wrapper template classes for user specified functions.
1380          This wrapper is for a function that does not require 'this' value.
1381          4 parameters, without return variable version.
1382          \param pVm A pointer to the VM
1383          \param iNumArguments A number of given parameters.
1384          \param pArguments A pointer to the arguments array.
1385          \param pMethodBody An API body.
1386          \ingroup MDL_LIB_VM
1387          */
1388         template< class P1, class P2, class P3, class P4 >
1389         void MakeWrapperStdVoidP4( CCilVm* const pVm,
1390                                                           const int32_t iNumArguments,
1391                                                           CVariable* pArguments,
1392                                                           PMETHOD pMethodBody )
1393         {
1394                 //Skip This pointer
1395                 pArguments ++;
1396                
1397                 P1 param1 = (P1)0;
1398                 P2 param2 = (P2)0;
1399                 P3 param3 = (P3)0;
1400                 P4 param4 = (P4)0;
1401                 switch( iNumArguments )
1402                 {
1403                         default:
1404                                 param4 = (P4)*(pArguments+3);
1405                         case 4:
1406                                 param3 = (P3)*(pArguments+2);
1407                         case 3:
1408                                 param2 = (P2)*(pArguments+1);
1409                         case 2:
1410                                 param1 = (P1)*pArguments;
1411                         case 1:
1412                                 break;
1413                 }
1414                
1415                 ((void (*)( P1, P2, P3, P4 ) )pMethodBody)( param1, param2, param3, param4 );
1416                 pVm->pushEvalStackUndefined();
1417                
1418                 return;
1419         }
1420        
1421         /*EN Wrapper template classes for user specified functions.
1422          This wrapper is for a function that does not require 'this' value.
1423          5 parameters, without return variable version.
1424          \param pVm A pointer to the VM
1425          \param iNumArguments A number of given parameters.
1426          \param pArguments A pointer to the arguments array.
1427          \param pMethodBody An API body.
1428          \ingroup MDL_LIB_VM
1429          */
1430         template< class P1, class P2, class P3, class P4, class P5 >
1431         void MakeWrapperStdVoidP5( CCilVm* const pVm,
1432                                                           const int32_t iNumArguments,
1433                                                           CVariable* pArguments,
1434                                                           PMETHOD pMethodBody )
1435         {
1436                 //Skip This pointer
1437                 pArguments ++;
1438                
1439                 P1 param1 = (P1)0;
1440                 P2 param2 = (P2)0;
1441                 P3 param3 = (P3)0;
1442                 P4 param4 = (P4)0;
1443                 P5 param5 = (P5)0;
1444                 switch( iNumArguments )
1445                 {
1446                         default:
1447                                 param5 = (P5)*(pArguments+4);
1448                         case 5:
1449                                 param4 = (P4)*(pArguments+3);
1450                         case 4:
1451                                 param3 = (P3)*(pArguments+2);
1452                         case 3:
1453                                 param2 = (P2)*(pArguments+1);
1454                         case 2:
1455                                 param1 = (P1)*pArguments;
1456                         case 1:
1457                                 break;
1458                 }
1459                
1460                 ((void (*)( P1, P2, P3, P4, P5 ) )pMethodBody)( param1, param2, param3, param4, param5 );
1461                 pVm->pushEvalStackUndefined();
1462                
1463                 return;
1464         }
1465         //-------------------------------------------
1466         //Member version
1467         //-------------------------------------------
1468         /*EN Wrapper template classes for user specified functions.
1469          This wrapper is for a function thatrequires 'this' value as a first parameter.
1470          No parameter, with a return variable version.
1471          \param pVm A pointer to the VM
1472          \param iNumArguments A number of given parameters.
1473          \param pArguments A pointer to the arguments array.
1474          \param pMethodBody An API body.
1475          \ingroup MDL_LIB_VM
1476          */
1477         template< class RET >
1478         void MakeWrapperMtdP0( CCilVm* const pVm,
1479                                                   const int32_t iNumArguments,
1480                                                   CVariable* pArguments,
1481                                                   PMETHOD pMethodBody )
1482         {
1483                 //Keep This pointer
1484                 CVariable* pVar = &*pArguments ++;
1485                
1486                 RET ret = ((RET (*)( CVariable* ) )pMethodBody)( pVar );
1487                 pVm->pushEvalStack( ret );
1488                
1489                 return;
1490         }
1491        
1492         /*EN Wrapper template classes for user specified functions.
1493          This wrapper is for a function thatrequires 'this' value as a first parameter.
1494          1 parameter, with a return variable version.
1495          \param pVm A pointer to the VM
1496          \param iNumArguments A number of given parameters.
1497          \param pArguments A pointer to the arguments array.
1498          \param pMethodBody An API body.
1499          \ingroup MDL_LIB_VM
1500          */
1501         template< class RET, class P1 >
1502         void MakeWrapperMtdP1( CCilVm* const pVm,
1503                                                   const int32_t iNumArguments,
1504                                                   CVariable* pArguments,
1505                                                   PMETHOD pMethodBody )
1506         {
1507                 //Keep This pointer
1508                 CVariable* pVar = &*pArguments ++;
1509                
1510                 P1 param1;
1511                 switch( iNumArguments )
1512                 {
1513                         default:
1514                                 param1 = (P1)*pArguments;
1515                         case 1:
1516                                 break;
1517                 }
1518                
1519                 RET ret = ((RET (*)( CVariable*, P1 ) )pMethodBody)( pVar, param1 );
1520                 pVm->pushEvalStack( ret );
1521                
1522                 return;
1523         }
1524        
1525         /*EN Wrapper template classes for user specified functions.
1526          This wrapper is for a function thatrequires 'this' value as a first parameter.
1527          2 parameters, with a return variable version.
1528          \param pVm A pointer to the VM
1529          \param iNumArguments A number of given parameters.
1530          \param pArguments A pointer to the arguments array.
1531          \param pMethodBody An API body.
1532          \ingroup MDL_LIB_VM
1533          */
1534         template< class RET, class P1, class P2 >
1535         void MakeWrapperMtdP2( CCilVm* const pVm,
1536                                                   const int32_t iNumArguments,
1537                                                   CVariable* pArguments,
1538                                                   PMETHOD pMethodBody )
1539         {
1540                 //Keep This pointer
1541                 CVariable* pVar = &*pArguments ++;
1542                
1543                 P1 param1 = (P1)0;
1544                 P2 param2 = (P2)0;
1545                 switch( iNumArguments )
1546                 {
1547                         default:
1548                                 param2 = (P2)*(pArguments+1);
1549                         case 2:
1550                                 param1 = (P1)*pArguments;
1551                         case 1:
1552                                 break;
1553                 }
1554                
1555                 RET ret = ((RET (*)( CVariable*, P1, P2 ) )pMethodBody)( pVar, param1, param2 );
1556                 pVm->pushEvalStack( ret );
1557                
1558                 return;
1559         }
1560        
1561         /*EN Wrapper template classes for user specified functions.
1562          This wrapper is for a function thatrequires 'this' value as a first parameter.
1563          3 parameters, with a return variable version.
1564          \param pVm A pointer to the VM
1565          \param iNumArguments A number of given parameters.
1566          \param pArguments A pointer to the arguments array.
1567          \param pMethodBody An API body.
1568          \ingroup MDL_LIB_VM
1569          */
1570         template< class RET, class P1, class P2, class P3 >
1571         void MakeWrapperMtdP3( CCilVm* const pVm,
1572                                                   const int32_t iNumArguments,
1573                                                   CVariable* pArguments,
1574                                                   PMETHOD pMethodBody )
1575         {
1576                 //Keep This pointer
1577                 CVariable* pVar = &*pArguments ++;
1578                
1579                 P1 param1 = (P1)0;
1580                 P2 param2 = (P2)0;
1581                 P3 param3 = (P3)0;
1582                 switch( iNumArguments )
1583                 {
1584                         default:
1585                                 param3 = (P3)*(pArguments+2);
1586                         case 3:
1587                                 param2 = (P2)*(pArguments+1);
1588                         case 2:
1589                                 param1 = (P1)*pArguments;
1590                         case 1:
1591                                 break;
1592                 }
1593                
1594                 RET ret = ((RET (*)( CVariable*, P1, P2, P3 ) )pMethodBody)( pVar, param1, param2, param3 );
1595                 pVm->pushEvalStack( ret );
1596                
1597                 return;
1598         }
1599        
1600         /*EN Wrapper template classes for user specified functions.
1601          This wrapper is for a function thatrequires 'this' value as a first parameter.
1602          4 parameters, with a return variable version.
1603          \param pVm A pointer to the VM
1604          \param iNumArguments A number of given parameters.
1605          \param pArguments A pointer to the arguments array.
1606          \param pMethodBody An API body.
1607          \ingroup MDL_LIB_VM
1608          */
1609         template< class RET, class P1, class P2, class P3, class P4 >
1610         void MakeWrapperMtdP4( CCilVm* const pVm,
1611                                                   const int32_t iNumArguments,
1612                                                   CVariable* pArguments,
1613                                                   PMETHOD pMethodBody )
1614         {
1615                 //Keep This pointer
1616                 CVariable* pVar = &*pArguments ++;
1617                
1618                 P1 param1 = (P1)0;
1619                 P2 param2 = (P2)0;
1620                 P3 param3 = (P3)0;
1621                 P4 param4 = (P4)0;
1622                 switch( iNumArguments )
1623                 {
1624                         default:
1625                                 param4 = (P4)*(pArguments+3);
1626                         case 4:
1627                                 param3 = (P3)*(pArguments+2);
1628                         case 3:
1629                                 param2 = (P2)*(pArguments+1);
1630                         case 2:
1631                                 param1 = (P1)*pArguments;
1632                         case 1:
1633                                 break;
1634                 }
1635                
1636                 RET ret = ((RET (*)( CVariable*, P1, P2, P3, P4 ) )pMethodBody)( pVar, param1, param2, param3, param4 );
1637                 pVm->pushEvalStack( ret );
1638                
1639                 return;
1640         }
1641        
1642         /*EN Wrapper template classes for user specified functions.
1643          This wrapper is for a function thatrequires 'this' value as a first parameter.
1644          5 parameters, with a return variable version.
1645          \param pVm A pointer to the VM
1646          \param iNumArguments A number of given parameters.
1647          \param pArguments A pointer to the arguments array.
1648          \param pMethodBody An API body.
1649          \ingroup MDL_LIB_VM
1650          */
1651         template< class RET, class P1, class P2, class P3, class P4, class P5 >
1652         void MakeWrapperMtdP5( CCilVm* const pVm,
1653                                                   const int32_t iNumArguments,
1654                                                   CVariable* pArguments,
1655                                                   PMETHOD pMethodBody )
1656         {
1657                 //Keep This pointer
1658                 CVariable* pVar = &*pArguments ++;
1659                
1660                 P1 param1 = (P1)0;
1661                 P2 param2 = (P2)0;
1662                 P3 param3 = (P3)0;
1663                 P4 param4 = (P4)0;
1664                 P5 param5 = (P5)0;
1665                 switch( iNumArguments )
1666                 {
1667                         default:
1668                                 param5 = (P5)*(pArguments+4);
1669                         case 5:
1670                                 param4 = (P4)*(pArguments+3);
1671                         case 4:
1672                                 param3 = (P3)*(pArguments+2);
1673                         case 3:
1674                                 param2 = (P2)*(pArguments+1);
1675                         case 2:
1676                                 param1 = (P1)*pArguments;
1677                         case 1:
1678                                 break;
1679                 }
1680                
1681                 RET ret = ((RET (*)( CVariable*, P1, P2, P3, P4, P5 ) )pMethodBody)( pVar, param1, param2, param3, param4, param5 );
1682                 pVm->pushEvalStack( ret );
1683                
1684                 return;
1685         }
1686        
1687         //----------------------
1688         //Void return version
1689         //----------------------
1690         /*EN Wrapper template classes for user specified functions.
1691          This wrapper is for a function thatrequires 'this' value as a first parameter.
1692          no parameter, without a return variable version.
1693          \param pVm A pointer to the VM
1694          \param iNumArguments A number of given parameters.
1695          \param pArguments A pointer to the arguments array.
1696          \param pMethodBody An API body.
1697          \ingroup MDL_LIB_VM
1698          */
1699         void MakeWrapperMtdVoidP0( CCilVm* const pVm,
1700                                                           const int32_t iNumArguments,
1701                                                           CVariable* pArguments,
1702                                                           PMETHOD pMethodBody );
1703         /*
1704          {
1705          //Keep This pointer
1706          CVariable* pVar = &*pArguments ++;
1707         
1708          ((void (*)( CVariable* ) )pMethodBody)( pVar );
1709          pVm->pushEvalStackUndefined();
1710         
1711          return;
1712          }
1713          */
1714        
1715         /*EN Wrapper template classes for user specified functions.
1716          This wrapper is for a function thatrequires 'this' value as a first parameter.
1717          1 parameter, without a return variable version.
1718          \param pVm A pointer to the VM
1719          \param iNumArguments A number of given parameters.
1720          \param pArguments A pointer to the arguments array.
1721          \param pMethodBody An API body.
1722          \ingroup MDL_LIB_VM
1723          */
1724         template< class P1 >
1725         void MakeWrapperMtdVoidP1( CCilVm* const pVm,
1726                                                           const int32_t iNumArguments,
1727                                                           CVariable* pArguments,
1728                                                           PMETHOD pMethodBody )
1729         {
1730                 //Keep This pointer
1731                 CVariable* pVar = &*pArguments ++;
1732                
1733                 P1 param1;
1734                 switch( iNumArguments )
1735                 {
1736                         default:
1737                                 param1 = (P1)*pArguments;
1738                         case 1:
1739                                 break;
1740                 }
1741                
1742                 ((void (*)( CVariable*, P1 ) )pMethodBody)( pVar, param1 );
1743                 pVm->pushEvalStackUndefined();
1744                
1745                 return;
1746         }
1747        
1748         /*EN Wrapper template classes for user specified functions.
1749          This wrapper is for a function thatrequires 'this' value as a first parameter.
1750          2 parameters, without a return variable version.
1751          \param pVm A pointer to the VM
1752          \param iNumArguments A number of given parameters.
1753          \param pArguments A pointer to the arguments array.
1754          \param pMethodBody An API body.
1755          \ingroup MDL_LIB_VM
1756          */
1757         template< class P1, class P2 >
1758         void MakeWrapperMtdVoidP2( CCilVm* const pVm,
1759                                                           const int32_t iNumArguments,
1760                                                           CVariable* pArguments,
1761                                                           PMETHOD pMethodBody )
1762         {
1763                 //Keep This pointer
1764                 CVariable* pVar = &*pArguments ++;
1765                
1766                 P1 param1 = (P1)0;
1767                 P2 param2 = (P2)0;
1768                 switch( iNumArguments )
1769                 {
1770                         default:
1771                                 param2 = (P2)*(pArguments+1);
1772                         case 2:
1773                                 param1 = (P1)*pArguments;
1774                         case 1:
1775                                 break;
1776                 }
1777                
1778                
1779                 ((void (*)( CVariable*, P1, P2 ) )pMethodBody)( pVar, param1, param2 );
1780                 pVm->pushEvalStackUndefined();
1781                
1782                 return;
1783         }
1784        
1785         /*EN Wrapper template classes for user specified functions.
1786          This wrapper is for a function thatrequires 'this' value as a first parameter.
1787          3 parameters, without a return variable version.
1788          \param pVm A pointer to the VM
1789          \param iNumArguments A number of given parameters.
1790          \param pArguments A pointer to the arguments array.
1791          \param pMethodBody An API body.
1792          \ingroup MDL_LIB_VM
1793          */
1794         template< class P1, class P2, class P3 >
1795         void MakeWrapperMtdVoidP3( CCilVm* const pVm,
1796                                                           const int32_t iNumArguments,
1797                                                           CVariable* pArguments,
1798                                                           PMETHOD pMethodBody )
1799         {
1800                 //Keep This pointer
1801                 CVariable* pVar = &*pArguments ++;
1802                
1803                 P1 param1 = (P1)0;
1804                 P2 param2 = (P2)0;
1805                 P3 param3 = (P3)0;
1806                 switch( iNumArguments )
1807                 {
1808                         default:
1809                                 param3 = (P3)*(pArguments+2);
1810                         case 3:
1811                                 param2 = (P2)*(pArguments+1);
1812                         case 2:
1813                                 param1 = (P1)*pArguments;
1814                         case 1:
1815                                 break;
1816                 }
1817                
1818                 ((void (*)( CVariable*, P1, P2, P3 ) )pMethodBody)( pVar, param1, param2, param3 );
1819                 pVm->pushEvalStackUndefined();
1820                
1821                 return;
1822         }
1823        
1824         /*EN Wrapper template classes for user specified functions.
1825          This wrapper is for a function thatrequires 'this' value as a first parameter.
1826          4 parameters, without a return variable version.
1827          \param pVm A pointer to the VM
1828          \param iNumArguments A number of given parameters.
1829          \param pArguments A pointer to the arguments array.
1830          \param pMethodBody An API body.
1831          \ingroup MDL_LIB_VM
1832          */
1833         template< class P1, class P2, class P3, class P4 >
1834         void MakeWrapperMtdVoidP4( CCilVm* const pVm,
1835                                                           const int32_t iNumArguments,
1836                                                           CVariable* pArguments,
1837                                                           PMETHOD pMethodBody )
1838         {
1839                 //Keep This pointer
1840                 CVariable* pVar = &*pArguments ++;
1841                
1842                 P1 param1 = (P1)0;
1843                 P2 param2 = (P2)0;
1844                 P3 param3 = (P3)0;
1845                 P4 param4 = (P4)0;
1846                 switch( iNumArguments )
1847                 {
1848                         default:
1849                                 param4 = (P4)*(pArguments+3);
1850                         case 4:
1851                                 param3 = (P3)*(pArguments+2);
1852                         case 3:
1853                                 param2 = (P2)*(pArguments+1);
1854                         case 2:
1855                                 param1 = (P1)*pArguments;
1856                         case 1:
1857                                 break;
1858                 }
1859                
1860                 ((void (*)( CVariable*, P1, P2, P3, P4 ) )pMethodBody)( pVar, param1, param2, param3, param4 );
1861                 pVm->pushEvalStackUndefined();
1862                
1863                 return;
1864         }
1865        
1866         /*EN Wrapper template classes for user specified functions.
1867          This wrapper is for a function thatrequires 'this' value as a first parameter.
1868          5 parameters, without a return variable version.
1869          \param pVm A pointer to the VM
1870          \param iNumArguments A number of given parameters.
1871          \param pArguments A pointer to the arguments array.
1872          \param pMethodBody An API body.
1873          \ingroup MDL_LIB_VM
1874          */
1875         template< class P1, class P2, class P3, class P4, class P5 >
1876         void MakeWrapperMtdVoidP5( CCilVm* const pVm,
1877                                                           const int32_t iNumArguments,
1878                                                           CVariable* pArguments,
1879                                                           PMETHOD pMethodBody )
1880         {
1881                 //Keep This pointer
1882                 CVariable* pVar = &*pArguments ++;
1883                
1884                 P1 param1 = (P1)0;
1885                 P2 param2 = (P2)0;
1886                 P3 param3 = (P3)0;
1887                 P4 param4 = (P4)0;
1888                 P5 param5 = (P5)0;
1889                 switch( iNumArguments )
1890                 {
1891                         default:
1892                                 param5 = (P5)*(pArguments+4);
1893                         case 5:
1894                                 param4 = (P4)*(pArguments+3);
1895                         case 4:
1896                                 param3 = (P3)*(pArguments+2);
1897                         case 3:
1898                                 param2 = (P2)*(pArguments+1);
1899                         case 2:
1900                                 param1 = (P1)*pArguments;
1901                         case 1:
1902                                 break;
1903                 }
1904                
1905                 ((void (*)( CVariable*, P1, P2, P3, P4, P5 ) )pMethodBody)( pVar, param1, param2, param3, param4, param5 );
1906                 pVm->pushEvalStackUndefined();
1907                
1908                 return;
1909         }
1910        
1911 }//namespace cri
1912
Note: See TracBrowser for help on using the browser.