dotgnu-pnet-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Dotgnu-pnet-commits] CVS: pnet/engine cvm.h,1.46,1.47 cvm_call.c,1.67,


From: Rhys Weatherley <address@hidden>
Subject: [Dotgnu-pnet-commits] CVS: pnet/engine cvm.h,1.46,1.47 cvm_call.c,1.67,1.68 cvm_dasm.c,1.53,1.54 cvm_lengths.c,1.14,1.15 cvmc.c,1.39,1.40 cvmc_call.c,1.26,1.27 null_coder.c,1.20,1.21 verify.c,1.42,1.43 verify_call.c,1.40,1.41
Date: Thu, 19 Jun 2003 08:19:42 -0400

Update of /cvsroot/dotgnu-pnet/pnet/engine
In directory subversions:/tmp/cvs-serv18859/engine

Modified Files:
        cvm.h cvm_call.c cvm_dasm.c cvm_lengths.c cvmc.c cvmc_call.c 
        null_coder.c verify.c verify_call.c 
Log Message:


Re-implement tail calls in the verifier, coder, and interpreter.


Index: cvm.h
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/cvm.h,v
retrieving revision 1.46
retrieving revision 1.47
diff -C2 -r1.46 -r1.47
*** cvm.h       16 Jun 2003 00:05:15 -0000      1.46
--- cvm.h       19 Jun 2003 12:19:40 -0000      1.47
***************
*** 402,522 ****
   */
  #define       COP_PREFIX_TAIL_CALL            0x16
! #define       COP_PREFIX_LDFTN                        0x17
! #define       COP_PREFIX_LDVIRTFTN            0x18
! #define       COP_PREFIX_LDINTERFFTN          0x19
! #define       COP_PREFIX_PACK_VARARGS         0x1A
  
  /*
   * Prefixed exception handling opcodes.
   */
! #define       COP_PREFIX_ENTER_TRY            0x1B
! #define       COP_PREFIX_THROW                        0x1C
! #define       COP_PREFIX_THROW_CALLER         0x1D
! #define       COP_PREFIX_SET_STACK_TRACE      0x1E
  
  /*
   * Prefixed typedref handling opcodes.
   */
! #define       COP_PREFIX_MKREFANY                     0x1F
! #define       COP_PREFIX_REFANYVAL            0x20
! #define       COP_PREFIX_REFANYTYPE           0x21
  
  /*
   * Prefixed conversion opcodes.
   */
! #define       COP_PREFIX_I2B_OVF                      0x22
! #define       COP_PREFIX_I2UB_OVF                     0x23
! #define       COP_PREFIX_IU2B_OVF                     0x24
! #define       COP_PREFIX_IU2UB_OVF            0x25
! #define       COP_PREFIX_I2S_OVF                      0x26
! #define       COP_PREFIX_I2US_OVF                     0x27
! #define       COP_PREFIX_IU2S_OVF                     0x28
! #define       COP_PREFIX_IU2US_OVF            0x29
! #define       COP_PREFIX_I2IU_OVF                     0x2A
! #define       COP_PREFIX_IU2I_OVF                     0x2B
! #define       COP_PREFIX_I2UL_OVF                     0x2C
! #define       COP_PREFIX_L2I_OVF                      0x2D
! #define       COP_PREFIX_L2UI_OVF                     0x2E
! #define       COP_PREFIX_LU2I_OVF                     0x2F
! #define       COP_PREFIX_LU2IU_OVF            0x30
! #define       COP_PREFIX_L2UL_OVF                     0x31
! #define       COP_PREFIX_LU2L_OVF                     0x32
! #define       COP_PREFIX_F2I_OVF                      0x33
! #define       COP_PREFIX_F2IU_OVF                     0x34
! #define       COP_PREFIX_F2L_OVF                      0x35
! #define       COP_PREFIX_F2LU_OVF                     0x36
! #define       COP_PREFIX_I2B_ALIGNED          0x37
! #define       COP_PREFIX_I2S_ALIGNED          0x38
! #define       COP_PREFIX_F2F_ALIGNED          0x39
! #define       COP_PREFIX_F2D_ALIGNED          0x3A
  
  /*
   * Prefixed arithmetic opcodes.
   */
! #define       COP_PREFIX_CKFINITE                     0x3B
  
  /*
   * Marshalling conversion opcodes.
   */
! #define       COP_PREFIX_STR2ANSI                     0x3C
! #define       COP_PREFIX_STR2UTF8                     0x3D
! #define       COP_PREFIX_ANSI2STR                     0x3E
! #define       COP_PREFIX_UTF82STR                     0x3F
! #define       COP_PREFIX_STR2UTF16            0x40
! #define       COP_PREFIX_UTF162STR            0x41
! #define       COP_PREFIX_DELEGATE2FNPTR       0x42
! #define       COP_PREFIX_ARRAY2PTR            0x43
! #define       COP_PREFIX_REFARRAY2ANSI        0x44
! #define       COP_PREFIX_REFARRAY2UTF8        0x45
! #define       COP_PREFIX_TOCUSTOM                     0x46
! #define       COP_PREFIX_FROMCUSTOM           0x47
! #define       COP_PREFIX_ARRAY2ANSI           0x48
! #define       COP_PREFIX_ARRAY2UTF8           0x49
  
  /*
   * Inline method replacements.
   */
! #define       COP_PREFIX_STRING_CONCAT_2      0x4A
! #define       COP_PREFIX_STRING_CONCAT_3      0x4B
! #define       COP_PREFIX_STRING_CONCAT_4      0x4C
! #define       COP_PREFIX_STRING_EQ            0x4D
! #define       COP_PREFIX_STRING_NE            0x4E
! #define       COP_PREFIX_STRING_GET_CHAR      0x4F
! #define       COP_PREFIX_TYPE_FROM_HANDLE     0x50
! #define       COP_PREFIX_MONITOR_ENTER        0x51
! #define       COP_PREFIX_MONITOR_EXIT         0x52
! #define       COP_PREFIX_APPEND_CHAR          0x53
! #define       COP_PREFIX_IS_WHITE_SPACE       0x54
  
  /*
   * Binary value fixups.
   */
! #define       COP_PREFIX_FIX_I4_I                     0x55
! #define       COP_PREFIX_FIX_I4_U                     0x56
  
  /*
   * Trigger method unrolling.
   */
! #define       COP_PREFIX_UNROLL_METHOD        0x57
  
  /*
   * Allocate local stack space.
   */
! #define       COP_PREFIX_LOCAL_ALLOC          0x58
  
  /*
   * Method profiling.
   */
! #define COP_PREFIX_PROFILE_COUNT      0x59
  
  /*
   * Thread static handling.
   */
! #define       COP_PREFIX_THREAD_STATIC        0x5A
  
  /*
   * Argument packing for native calls.
   */
! #define       COP_PREFIX_WADDR_NATIVE_N       0x5B
  
  /*
--- 402,525 ----
   */
  #define       COP_PREFIX_TAIL_CALL            0x16
! #define       COP_PREFIX_TAIL_CALLI           0x17
! #define       COP_PREFIX_TAIL_CALLVIRT        0x18
! #define       COP_PREFIX_TAIL_CALLINTF        0x19
! #define       COP_PREFIX_LDFTN                        0x1A
! #define       COP_PREFIX_LDVIRTFTN            0x1B
! #define       COP_PREFIX_LDINTERFFTN          0x1C
! #define       COP_PREFIX_PACK_VARARGS         0x1D
  
  /*
   * Prefixed exception handling opcodes.
   */
! #define       COP_PREFIX_ENTER_TRY            0x1E
! #define       COP_PREFIX_THROW                        0x1F
! #define       COP_PREFIX_THROW_CALLER         0x20
! #define       COP_PREFIX_SET_STACK_TRACE      0x21
  
  /*
   * Prefixed typedref handling opcodes.
   */
! #define       COP_PREFIX_MKREFANY                     0x22
! #define       COP_PREFIX_REFANYVAL            0x23
! #define       COP_PREFIX_REFANYTYPE           0x24
  
  /*
   * Prefixed conversion opcodes.
   */
! #define       COP_PREFIX_I2B_OVF                      0x25
! #define       COP_PREFIX_I2UB_OVF                     0x26
! #define       COP_PREFIX_IU2B_OVF                     0x27
! #define       COP_PREFIX_IU2UB_OVF            0x28
! #define       COP_PREFIX_I2S_OVF                      0x28
! #define       COP_PREFIX_I2US_OVF                     0x2A
! #define       COP_PREFIX_IU2S_OVF                     0x2B
! #define       COP_PREFIX_IU2US_OVF            0x2C
! #define       COP_PREFIX_I2IU_OVF                     0x2D
! #define       COP_PREFIX_IU2I_OVF                     0x2E
! #define       COP_PREFIX_I2UL_OVF                     0x2F
! #define       COP_PREFIX_L2I_OVF                      0x30
! #define       COP_PREFIX_L2UI_OVF                     0x31
! #define       COP_PREFIX_LU2I_OVF                     0x32
! #define       COP_PREFIX_LU2IU_OVF            0x33
! #define       COP_PREFIX_L2UL_OVF                     0x34
! #define       COP_PREFIX_LU2L_OVF                     0x35
! #define       COP_PREFIX_F2I_OVF                      0x36
! #define       COP_PREFIX_F2IU_OVF                     0x37
! #define       COP_PREFIX_F2L_OVF                      0x38
! #define       COP_PREFIX_F2LU_OVF                     0x39
! #define       COP_PREFIX_I2B_ALIGNED          0x3A
! #define       COP_PREFIX_I2S_ALIGNED          0x3B
! #define       COP_PREFIX_F2F_ALIGNED          0x3C
! #define       COP_PREFIX_F2D_ALIGNED          0x3D
  
  /*
   * Prefixed arithmetic opcodes.
   */
! #define       COP_PREFIX_CKFINITE                     0x3E
  
  /*
   * Marshalling conversion opcodes.
   */
! #define       COP_PREFIX_STR2ANSI                     0x3F
! #define       COP_PREFIX_STR2UTF8                     0x40
! #define       COP_PREFIX_ANSI2STR                     0x41
! #define       COP_PREFIX_UTF82STR                     0x42
! #define       COP_PREFIX_STR2UTF16            0x43
! #define       COP_PREFIX_UTF162STR            0x44
! #define       COP_PREFIX_DELEGATE2FNPTR       0x45
! #define       COP_PREFIX_ARRAY2PTR            0x46
! #define       COP_PREFIX_REFARRAY2ANSI        0x47
! #define       COP_PREFIX_REFARRAY2UTF8        0x48
! #define       COP_PREFIX_TOCUSTOM                     0x49
! #define       COP_PREFIX_FROMCUSTOM           0x4A
! #define       COP_PREFIX_ARRAY2ANSI           0x4B
! #define       COP_PREFIX_ARRAY2UTF8           0x4C
  
  /*
   * Inline method replacements.
   */
! #define       COP_PREFIX_STRING_CONCAT_2      0x4D
! #define       COP_PREFIX_STRING_CONCAT_3      0x4E
! #define       COP_PREFIX_STRING_CONCAT_4      0x4F
! #define       COP_PREFIX_STRING_EQ            0x50
! #define       COP_PREFIX_STRING_NE            0x51
! #define       COP_PREFIX_STRING_GET_CHAR      0x52
! #define       COP_PREFIX_TYPE_FROM_HANDLE     0x53
! #define       COP_PREFIX_MONITOR_ENTER        0x54
! #define       COP_PREFIX_MONITOR_EXIT         0x55
! #define       COP_PREFIX_APPEND_CHAR          0x56
! #define       COP_PREFIX_IS_WHITE_SPACE       0x57
  
  /*
   * Binary value fixups.
   */
! #define       COP_PREFIX_FIX_I4_I                     0x58
! #define       COP_PREFIX_FIX_I4_U                     0x59
  
  /*
   * Trigger method unrolling.
   */
! #define       COP_PREFIX_UNROLL_METHOD        0x5A
  
  /*
   * Allocate local stack space.
   */
! #define       COP_PREFIX_LOCAL_ALLOC          0x5B
  
  /*
   * Method profiling.
   */
! #define COP_PREFIX_PROFILE_COUNT      0x5C
  
  /*
   * Thread static handling.
   */
! #define       COP_PREFIX_THREAD_STATIC        0x5D
  
  /*
   * Argument packing for native calls.
   */
! #define       COP_PREFIX_WADDR_NATIVE_N       0x5E
  
  /*

Index: cvm_call.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/cvm_call.c,v
retrieving revision 1.67
retrieving revision 1.68
diff -C2 -r1.67 -r1.68
*** cvm_call.c  16 Jun 2003 00:05:15 -0000      1.67
--- cvm_call.c  19 Jun 2003 12:19:40 -0000      1.68
***************
*** 1435,1438 ****
--- 1435,1439 ----
        methodToCall = CVM_ARG_TAIL_METHOD;
  
+ performTailCall:
        /* Convert the method if necessary */
        if(methodToCall->userData)
***************
*** 1465,1468 ****
--- 1466,1566 ----
  }
  VMBREAK(COP_PREFIX_TAIL_CALL);
+ 
+ /**
+  * <opcode name="tail_calli" group="Call management instructions">
+  *   <operation>Call a method using indirect tail call semantics</operation>
+  *
+  *   <format>prefix<fsep/>tail_calli</format>
+  *   <dformat>{tail_calli}</dformat>
+  *
+  *   <form name="tail_calli" code="COP_PREFIX_TAIL_CALLI"/>
+  *
+  *   <description>This instruction is identical to <i>calli</i>, except
+  *   that it performs a tail-optimized call.</description>
+  * </opcode>
+  */
+ VMCASE(COP_PREFIX_TAIL_CALLI):
+ {
+       /* Retrieve the target method */
+       methodToCall = (ILMethod *)(stacktop[-1].ptrValue);
+       --stacktop;
+       if(methodToCall)
+       {
+               goto performTailCall;
+       }
+       else
+       {
+               NULL_POINTER_EXCEPTION();
+       }
+ }
+ VMBREAK(COP_PREFIX_TAIL_CALLI);
+ 
+ /**
+  * <opcode name="tail_callvirt" group="Call management instructions">
+  *   <operation>Call a virtual method using tail call semantics</operation>
+  *
+  *   <format>prefix<fsep/>tail_callvirt<fsep/>N[1]<fsep/>M[1]</format>
+  *   <dformat>{tail_callvirt}<fsep/>N<fsep/>M</dformat>
+  *
+  *   <form name="tail_callvirt" code="COP_PREFIX_TAIL_CALLVIRT"/>
+  *
+  *   <description>The <i>tail_callvirt</i> instruction is identical
+  *   to <i>call_virtual</i>, except that it uses tail call semantics.
+  *   </description>
+  * </opcode>
+  */
+ VMCASE(COP_PREFIX_TAIL_CALLVIRT):
+ {
+       /* Call a virtual method */
+       tempptr = stacktop[-((ILInt32)CVMP_ARG_WORD)].ptrValue;
+       if(tempptr)
+       {
+               /* Locate the method to be called */
+               methodToCall = 
(GetObjectClassPrivate(tempptr))->vtable[CVMP_ARG_WORD2];
+               goto performTailCall;
+       }
+       else
+       {
+               NULL_POINTER_EXCEPTION();
+       }
+ }
+ VMBREAK(COP_PREFIX_TAIL_CALLVIRT);
+ 
+ /**
+  * <opcode name="tail_callintf" group="Call management instructions">
+  *   <operation>Call an interface method using tail call semantics</operation>
+  *
+  *   
<format>prefix<fsep/>tail_callintf<fsep/>N[1]<fsep/>M[1]<fsep/>cptr</format>
+  *   <dformat>{tail_callintf}<fsep/>N<fsep/>M<fsep/>cptr</dformat>
+  *
+  *   <form name="tail_callintf" code="COP_PREFIX_TAIL_CALLINTF"/>
+  *
+  *   <description>The <i>tail_callintf</i> instruction is identical
+  *   to <i>call_interface</i>, except that it uses tail call semantics.
+  *   </description>
+  * </opcode>
+  */
+ VMCASE(COP_PREFIX_TAIL_CALLINTF):
+ {
+       /* Call an interface method */
+       tempptr = stacktop[-((ILInt32)CVMP_ARG_WORD)].ptrValue;
+       if(tempptr)
+       {
+               /* Locate the method to be called */
+               methodToCall = _ILLookupInterfaceMethod
+                       (GetObjectClassPrivate(tempptr), 
CVMP_ARG_WORD2_PTR(ILClass *),
+                        CVMP_ARG_WORD2);
+               if(!methodToCall)
+               {
+                       MISSING_METHOD_EXCEPTION();
+               }
+               goto performTailCall;
+       }
+       else
+       {
+               NULL_POINTER_EXCEPTION();
+       }
+ }
+ VMBREAK(COP_PREFIX_TAIL_CALLINTF);
  
  /**

Index: cvm_dasm.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/cvm_dasm.c,v
retrieving revision 1.53
retrieving revision 1.54
diff -C2 -r1.53 -r1.54
*** cvm_dasm.c  16 Jun 2003 00:05:15 -0000      1.53
--- cvm_dasm.c  19 Jun 2003 12:19:40 -0000      1.54
***************
*** 60,63 ****
--- 60,64 ----
  #define       CVM_OPER_CUSTOM                         27
  #define       CVM_OPER_TWO_UINT32                     28
+ #define       CVM_OPER_TAIL_INTERFACE         29
  
  /*
***************
*** 460,463 ****
--- 461,467 ----
         */
        {"tail_call",           CVM_OPER_TAIL_CALL},
+       {"tail_calli",          CVM_OPER_NONE},
+       {"tail_callvirt",       CVM_OPER_TWO_UINT32},
+       {"tail_callintf",       CVM_OPER_TAIL_INTERFACE},
        {"ldftn",                       CVM_OPER_METHOD},
        {"ldvirtftn",           CVM_OPER_UINT32},
***************
*** 581,587 ****
         * Reserved opcodes.
         */
-       {"preserved_5C",        CVM_OPER_NONE},
-       {"preserved_5D",        CVM_OPER_NONE},
-       {"preserved_5E",        CVM_OPER_NONE},
        {"preserved_5F",        CVM_OPER_NONE},
  };
--- 585,588 ----
***************
*** 988,991 ****
--- 989,1004 ----
                                                        (unsigned 
long)(IL_READ_UINT32(pc + 6)));
                                        pc += 10;
+                               }
+                               break;
+ 
+                               case CVM_OPER_TAIL_INTERFACE:
+                               {
+                                       classInfo = (ILClass 
*)CVMReadPointer(pc + 10);
+                                       fprintf(stream, "%lu, %lu, ",
+                                                       (unsigned 
long)(IL_READ_UINT32(pc + 2)),
+                                                       (unsigned 
long)(IL_READ_UINT32(pc + 6)));
+                                       ILDumpClassName(stream, 
ILProgramItem_Image(currMethod),
+                                                                       
classInfo, 0);
+                                       size = 10 + sizeof(void *);
                                }
                                break;

Index: cvm_lengths.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/cvm_lengths.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -C2 -r1.14 -r1.15
*** cvm_lengths.c       1 May 2003 10:29:08 -0000       1.14
--- cvm_lengths.c       19 Jun 2003 12:19:40 -0000      1.15
***************
*** 415,418 ****
--- 415,421 ----
         */
        /* tail_call */                 CVMP_LEN_PTR,
+       /* tail_calli */                CVMP_LEN_NONE,
+       /* tail_callvirt */             CVMP_LEN_WORD2,
+       /* tail_callintf */             CVMP_LEN_WORD2_PTR,
        /* ldftn */                             CVMP_LEN_PTR,
        /* ldvirtftn */                 CVMP_LEN_WORD,
***************
*** 529,538 ****
        
        /*
         * Reserved opcodes.
         */
-       /* preserved_5b */              CVMP_LEN_NONE,
-       /* preserved_5c */              CVMP_LEN_NONE,
-       /* preserved_5d */              CVMP_LEN_NONE,
-       /* preserved_5e */              CVMP_LEN_NONE,
        /* preserved_5f */              CVMP_LEN_NONE,
  
--- 532,542 ----
        
        /*
+        * Argument packing for native calls.
+        */
+       /* waddr_native_n */    CVMP_LEN_WORD2,
+ 
+       /*
         * Reserved opcodes.
         */
        /* preserved_5f */              CVMP_LEN_NONE,
  

Index: cvmc.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/cvmc.c,v
retrieving revision 1.39
retrieving revision 1.40
diff -C2 -r1.39 -r1.40
*** cvmc.c      26 May 2003 05:47:03 -0000      1.39
--- cvmc.c      19 Jun 2003 12:19:40 -0000      1.40
***************
*** 78,82 ****
        unsigned char  *switchStart;
        ILMethod           *currentMethod;
-       int                             tailCallFlag;
        int                             debugEnabled;
        int                             flags;
--- 78,81 ----
***************
*** 161,165 ****
        coder->switchStart = 0;
        coder->currentMethod = 0;
-       coder->tailCallFlag = 0;
        coder->debugEnabled = 0;
        coder->flags = 0;
--- 160,163 ----
***************
*** 426,430 ****
        CVMCoder_LoadVirtualAddr,
        CVMCoder_LoadInterfaceAddr,
-       CVMCoder_TailCall,
        CVMCoder_SetupExceptions,
        CVMCoder_Throw,
--- 424,427 ----

Index: cvmc_call.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/cvmc_call.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -C2 -r1.26 -r1.27
*** cvmc_call.c 8 May 2003 01:34:15 -0000       1.26
--- cvmc_call.c 19 Jun 2003 12:19:40 -0000      1.27
***************
*** 144,148 ****
  {
        CallStaticConstructor(coder, ILMethod_Owner(methodInfo), 0);
!       if(((ILCVMCoder *)coder)->tailCallFlag)
        {
                CVMP_OUT_PTR(COP_PREFIX_TAIL_CALL, methodInfo);
--- 144,148 ----
  {
        CallStaticConstructor(coder, ILMethod_Owner(methodInfo), 0);
!       if(info->tailCall)
        {
                CVMP_OUT_PTR(COP_PREFIX_TAIL_CALL, methodInfo);
***************
*** 153,157 ****
        }
        AdjustForCall(coder, info, returnItem);
-       ((ILCVMCoder *)coder)->tailCallFlag = 0;
  }
  
--- 153,156 ----
***************
*** 159,166 ****
                                                                  
ILEngineStackItem *returnItem)
  {
!       CVM_OUT_NONE(COP_CALLI);
        CVM_ADJUST(-1); /* The function pointer was popped */
        AdjustForCall(coder, info, returnItem);
-       ((ILCVMCoder *)coder)->tailCallFlag = 0;
  }
  
--- 158,171 ----
                                                                  
ILEngineStackItem *returnItem)
  {
!       if(info->tailCall)
!       {
!               CVMP_OUT_NONE(COP_PREFIX_TAIL_CALLI);
!       }
!       else
!       {
!               CVM_OUT_NONE(COP_CALLI);
!       }
        CVM_ADJUST(-1); /* The function pointer was popped */
        AdjustForCall(coder, info, returnItem);
  }
  
***************
*** 172,176 ****
        AdjustForCall(coder, info, 0);
        CVM_ADJUST(1);
-       ((ILCVMCoder *)coder)->tailCallFlag = 0;
  }
  
--- 177,180 ----
***************
*** 184,190 ****
                ++argSize;
        }
!       CVM_OUT_DWIDE(COP_CALL_VIRTUAL, argSize, methodInfo->index);
        AdjustForCall(coder, info, returnItem);
-       ((ILCVMCoder *)coder)->tailCallFlag = 0;
  }
  
--- 188,200 ----
                ++argSize;
        }
!       if(info->tailCall)
!       {
!               CVMP_OUT_WORD2(COP_PREFIX_TAIL_CALLVIRT, argSize, 
methodInfo->index);
!       }
!       else
!       {
!               CVM_OUT_DWIDE(COP_CALL_VIRTUAL, argSize, methodInfo->index);
!       }
        AdjustForCall(coder, info, returnItem);
  }
  
***************
*** 199,205 ****
                ++argSize;
        }
!       CVM_OUT_DWIDE_PTR(COP_CALL_INTERFACE, argSize, methodInfo->index, ptr);
        AdjustForCall(coder, info, returnItem);
-       ((ILCVMCoder *)coder)->tailCallFlag = 0;
  }
  
--- 209,222 ----
                ++argSize;
        }
!       if(info->tailCall)
!       {
!               CVMP_OUT_WORD2_PTR(COP_PREFIX_TAIL_CALLINTF, argSize,
!                                                  methodInfo->index, ptr);
!       }
!       else
!       {
!               CVM_OUT_DWIDE_PTR(COP_CALL_INTERFACE, argSize, 
methodInfo->index, ptr);
!       }
        AdjustForCall(coder, info, returnItem);
  }
  
***************
*** 207,213 ****
                                                                   ILMethod 
*methodInfo)
  {
-       /* Inline methods cannot be tail calls */
-       ((ILCVMCoder *)coder)->tailCallFlag = 0;
- 
        /* Determine what to do for the inlineable method type */
        switch(inlineType)
--- 224,227 ----
***************
*** 464,472 ****
        CVMP_OUT_WORD_PTR(COP_PREFIX_LDINTERFFTN, methodInfo->index,
                                          methodInfo->member.owner);
- }
- 
- static void CVMCoder_TailCall(ILCoder *coder, ILMethod *methodInfo)
- {
-       ((ILCVMCoder *)coder)->tailCallFlag = 1;
  }
  
--- 478,481 ----

Index: null_coder.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/null_coder.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -C2 -r1.20 -r1.21
*** null_coder.c        26 May 2003 05:47:03 -0000      1.20
--- null_coder.c        19 Jun 2003 12:19:40 -0000      1.21
***************
*** 317,323 ****
  {
  }
- static void Coder_TailCall(ILCoder *coder, ILMethod *methodInfo)
- {
- }
  static void Coder_SetupExceptions(ILCoder *coder, ILException *exceptions,
                                                                  int 
hasRethrow)
--- 317,320 ----
***************
*** 457,461 ****
        Coder_LoadVirtualAddr,
        Coder_LoadInterfaceAddr,
-       Coder_TailCall,
        Coder_SetupExceptions,
        Coder_Throw,
--- 454,457 ----

Index: verify.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/verify.c,v
retrieving revision 1.42
retrieving revision 1.43
diff -C2 -r1.42 -r1.43
*** verify.c    19 Jun 2003 07:52:14 -0000      1.42
--- verify.c    19 Jun 2003 12:19:40 -0000      1.43
***************
*** 638,641 ****
--- 638,642 ----
        ILException *exception;
        int hasRethrow;
+       int tailCall = 0;
  #ifdef IL_CONFIG_DEBUG_LINES
        int haveDebug = ILDebugPresent(ILProgramItem_Image(method));

Index: verify_call.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/verify_call.c,v
retrieving revision 1.40
retrieving revision 1.41
diff -C2 -r1.40 -r1.41
*** verify_call.c       14 Jun 2003 11:41:13 -0000      1.40
--- verify_call.c       19 Jun 2003 12:19:40 -0000      1.41
***************
*** 174,178 ****
                                                      ILMethod *method, int 
unsafeAllowed,
                                                          int suppressThis, int 
indirectCall,
!                                                         ILCoderMethodInfo 
*callInfo)
  {
        ILClass *owner = (method ? ILMethod_Owner(method) : 0);
--- 174,178 ----
                                                      ILMethod *method, int 
unsafeAllowed,
                                                          int suppressThis, int 
indirectCall,
!                                                         ILCoderMethodInfo 
*callInfo, int tailCall)
  {
        ILClass *owner = (method ? ILMethod_Owner(method) : 0);
***************
*** 570,573 ****
--- 570,578 ----
                                        return -1;
                                }
+                               if(tailCall && !unsafeAllowed)
+                               {
+                                       /* Cannot use managed pointers in tail 
calls */
+                                       return -1;
+                               }
                        }
                        break;
***************
*** 619,622 ****
--- 624,628 ----
        callInfo->numVarArgs = totalParams - numParams;
        callInfo->hasParamArray = 0;
+       callInfo->tailCall = tailCall;
  
  #ifdef IL_CONFIG_VARARGS
***************
*** 1042,1046 ****
                        numParams = MatchSignature(coder, stack, stackSize,
                                                                           
methodSignature, methodInfo,
!                                                                          
unsafeAllowed, 0, 0, &callInfo);
                        if(numParams >= 0)
                        {
--- 1048,1054 ----
                        numParams = MatchSignature(coder, stack, stackSize,
                                                                           
methodSignature, methodInfo,
!                                                                          
unsafeAllowed, 0, 0,
!                                                                          
&callInfo, tailCall);
!                       tailCall = 0;
                        if(numParams >= 0)
                        {
***************
*** 1136,1140 ****
                                                                   
methodSignature, 0,
                                                                   
unsafeAllowed, 0, 1,
!                                                                  &callInfo);
                if(numParams >= 0)
                {
--- 1144,1149 ----
                                                                   
methodSignature, 0,
                                                                   
unsafeAllowed, 0, 1,
!                                                                  &callInfo, 
tailCall);
!               tailCall = 0;
                if(numParams >= 0)
                {
***************
*** 1218,1222 ****
                                                                           
methodSignature, methodInfo,
                                                                           
unsafeAllowed, 0, 0,
!                                                                          
&callInfo);
                        if(numParams >= 0)
                        {
--- 1227,1232 ----
                                                                           
methodSignature, methodInfo,
                                                                           
unsafeAllowed, 0, 0,
!                                                                          
&callInfo, tailCall);
!                       tailCall = 0;
                        if(numParams >= 0)
                        {
***************
*** 1327,1331 ****
                                                                           
methodSignature, methodInfo,
                                                                           
unsafeAllowed, 1, 0,
!                                                                          
&callInfo);
                        if(numParams < 0)
                        {
--- 1337,1342 ----
                                                                           
methodSignature, methodInfo,
                                                                           
unsafeAllowed, 1, 0,
!                                                                          
&callInfo, tailCall);
!                       tailCall = 0;
                        if(numParams < 0)
                        {
***************
*** 1367,1371 ****
                                                                           
methodSignature, methodInfo,
                                                                           
unsafeAllowed, 0, 0,
!                                                                          
&callInfo);
                        if(numParams < 0)
                        {
--- 1378,1383 ----
                                                                           
methodSignature, methodInfo,
                                                                           
unsafeAllowed, 0, 0,
!                                                                          
&callInfo, tailCall);
!                       tailCall = 0;
                        if(numParams < 0)
                        {
***************
*** 1488,1572 ****
  case IL_OP_PREFIX + IL_PREFIX_OP_TAIL:
  {
!       /* Missing: (?)
!        *
!        * Correct CIL must not branch to the call instruction, but it is
!        * permitted to branch to ret.
!        *
!        * The tail.call (or calli or callvirt) instruction cannot be used
!        * to transfer control out of a try, filter, catch, or finally block.
!        */
! 
!       /* Confirm that the .tail precedes a call */
!       if ((pc[2] == IL_OP_CALL || pc[2] == IL_OP_CALLI || 
!                pc[2] == IL_OP_CALLVIRT) && pc[7] == IL_OP_RET)
!       {
!               /*  Initialization */
!               methodInfo = 0;
!               methodSignature = 0;
!               numParams = 0;
! 
!               /*  Get called method information as appropriate. */
!               switch(pc[2]) 
!               {
!               case IL_OP_CALL:
!                       /* Test that only the target method's arguments are on 
the stack */
!                       methodInfo = GetMethodToken(method, &pc[2], 
&methodSignature);
!                       numParams = MatchSignature(coder, stack, stackSize,
!                                                                  
methodSignature, methodInfo,
!                                                                  
unsafeAllowed, 0, 0,
!                                                                  &callInfo);
! 
!               case IL_OP_CALLI:
!               case IL_OP_CALLVIRT:
!                       /*  TODO - Implement CALLI and CALLVIRT tails */
!                       break;
!               }
  
!               /*  A method exists and it's not synchronized? */
!               if (methodInfo && !ILMethod_IsSynchronized(methodInfo)) 
!               {
!                       /*  Test that the stack contents are sane */
!                       if (stackSize == numParams) 
!                       {
!                               if (unsafeAllowed) 
!                               {
!                                       /*  Don't bother checking for pointers 
*/
!                                       ILCoderTailCall(coder, method);
!                               } 
!                               else 
!                               {
!                                       /*  Test for managed pointers on the 
stack - a no-no */
!                                       int i, mPtrFlag;
!                                       mPtrFlag = 0;
!                                       for (i=0; i<numParams; i++)
!                                       {
!                                               if (stack[i].engineType == 
ILEngineType_M ||
!                                                               
stack[i].engineType == ILEngineType_T)
!                                               {
!                                                       mPtrFlag = 1;
!                                                       break;
!                                               }
!                                       }
  
!                                       if (mPtrFlag) 
!                                       {
!                                               VERIFY_TYPE_ERROR();
!                                       } 
!                                       else 
!                                       {
!                                               ILCoderTailCall(coder, method);
!                                       }
!                               }
!                       }
!                       else
!                       {
!                               VERIFY_STACK_ERROR();
!                       }
!               }
!       } 
!       else 
        {
                VERIFY_INSN_ERROR();
        }
  }
  break;
--- 1500,1524 ----
  case IL_OP_PREFIX + IL_PREFIX_OP_TAIL:
  {
!       /* Need at least 8 bytes to make up the full tail call sequence */
!       if(len < 8)
!       {
!               VERIFY_TRUNCATED();
!       }
  
!       /* Check that the instruction after the tail call is not a branch 
target */
!       if(IsJumpTarget(jumpMask, offset + 2))
!       {
!               VERIFY_BRANCH_ERROR();
!       }
  
!       /* Check that the instruction sequence is as expected */
!       if((pc[2] != IL_OP_CALL && pc[2] == IL_OP_CALLI &&
!           pc[2] != IL_OP_CALLVIRT) || pc[7] != IL_OP_RET)
        {
                VERIFY_INSN_ERROR();
        }
+ 
+       /* Set the tail call flag and then advance to the next instruction */
+       tailCall = 1;
  }
  break;





reply via email to

[Prev in Thread] Current Thread [Next in Thread]