Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

521 lines
26 KiB

  1. //========== Copyright (c) 2008, Valve Corporation, All rights reserved. ========
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #ifndef VSCRIPT_TEMPLATES_H
  7. #define VSCRIPT_TEMPLATES_H
  8. #include "tier0/basetypes.h"
  9. #if defined( _WIN32 )
  10. #pragma once
  11. #endif
  12. #define FUNC_APPEND_PARAMS_0
  13. #define FUNC_APPEND_PARAMS_1 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 1 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) );
  14. #define FUNC_APPEND_PARAMS_2 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 2 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) );
  15. #define FUNC_APPEND_PARAMS_3 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 3 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) );
  16. #define FUNC_APPEND_PARAMS_4 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 4 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) );
  17. #define FUNC_APPEND_PARAMS_5 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 5 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) );
  18. #define FUNC_APPEND_PARAMS_6 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 6 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) );
  19. #define FUNC_APPEND_PARAMS_7 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 7 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) );
  20. #define FUNC_APPEND_PARAMS_8 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 8 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_8 ) );
  21. #define FUNC_APPEND_PARAMS_9 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 9 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_8 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_9 ) );
  22. #define FUNC_APPEND_PARAMS_10 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 10 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_8 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_9 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_10 ) );
  23. #define FUNC_APPEND_PARAMS_11 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 11 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_8 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_9 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_10 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_11 ) );
  24. #define FUNC_APPEND_PARAMS_12 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 12 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_8 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_9 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_10 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_11 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_12 ) );
  25. #define FUNC_APPEND_PARAMS_13 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 13 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_8 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_9 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_10 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_11 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_12 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_13 ) );
  26. #define FUNC_APPEND_PARAMS_14 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 14 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_8 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_9 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_10 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_11 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_12 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_13 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_14 ) );
  27. #define DEFINE_NONMEMBER_FUNC_TYPE_DEDUCER(N) \
  28. template <typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N> \
  29. inline void ScriptDeduceFunctionSignature(ScriptFuncDescriptor_t *pDesc, FUNCTION_RETTYPE (*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) ) \
  30. { \
  31. pDesc->m_ReturnType = ScriptDeduceType(FUNCTION_RETTYPE); \
  32. FUNC_APPEND_PARAMS_##N \
  33. }
  34. FUNC_GENERATE_ALL( DEFINE_NONMEMBER_FUNC_TYPE_DEDUCER );
  35. #define DEFINE_MEMBER_FUNC_TYPE_DEDUCER(N) \
  36. template <typename OBJECT_TYPE_PTR, typename FUNCTION_CLASS, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N> \
  37. inline void ScriptDeduceFunctionSignature(ScriptFuncDescriptor_t *pDesc, OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) ) \
  38. { \
  39. pDesc->m_ReturnType = ScriptDeduceType(FUNCTION_RETTYPE); \
  40. FUNC_APPEND_PARAMS_##N \
  41. }
  42. FUNC_GENERATE_ALL( DEFINE_MEMBER_FUNC_TYPE_DEDUCER );
  43. //-------------------------------------
  44. #define DEFINE_CONST_MEMBER_FUNC_TYPE_DEDUCER(N) \
  45. template <typename OBJECT_TYPE_PTR, typename FUNCTION_CLASS, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N> \
  46. inline void ScriptDeduceFunctionSignature(ScriptFuncDescriptor_t *pDesc, OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) const ) \
  47. { \
  48. pDesc->m_ReturnType = ScriptDeduceType(FUNCTION_RETTYPE); \
  49. FUNC_APPEND_PARAMS_##N \
  50. }
  51. FUNC_GENERATE_ALL( DEFINE_CONST_MEMBER_FUNC_TYPE_DEDUCER );
  52. #define ScriptInitMemberFuncDescriptor_( pDesc, class, func, scriptName ) if ( 0 ) {} else { (pDesc)->m_pszScriptName = scriptName; (pDesc)->m_pszFunction = #func; ScriptDeduceFunctionSignature( pDesc, (class *)(0), &class::func ); }
  53. #define ScriptInitFuncDescriptorNamed( pDesc, func, scriptName ) if ( 0 ) {} else { (pDesc)->m_pszScriptName = scriptName; (pDesc)->m_pszFunction = #func; ScriptDeduceFunctionSignature( pDesc, &func ); }
  54. #define ScriptInitFuncDescriptor( pDesc, func ) ScriptInitFuncDescriptorNamed( pDesc, func, #func )
  55. #define ScriptInitMemberFuncDescriptorNamed( pDesc, class, func, scriptName ) ScriptInitMemberFuncDescriptor_( pDesc, class, func, scriptName )
  56. #define ScriptInitMemberFuncDescriptor( pDesc, class, func ) ScriptInitMemberFuncDescriptorNamed( pDesc, class, func, #func )
  57. //-----------------------------------------------------------------------------
  58. //
  59. //-----------------------------------------------------------------------------
  60. template <typename FUNCPTR_TYPE>
  61. inline ScriptFunctionBindingStorageType_t ScriptConvertFreeFuncPtrToVoid( FUNCPTR_TYPE pFunc )
  62. {
  63. #if defined(_PS3) || defined(POSIX)
  64. COMPILE_TIME_ASSERT( sizeof( FUNCPTR_TYPE ) == sizeof( void* ) * 2 || sizeof( FUNCPTR_TYPE ) == sizeof( void* ) );
  65. if ( sizeof( FUNCPTR_TYPE ) == 4 )
  66. {
  67. union FuncPtrConvertMI
  68. {
  69. FUNCPTR_TYPE pFunc;
  70. ScriptFunctionBindingStorageType_t stype;
  71. };
  72. FuncPtrConvertMI convert;
  73. convert.pFunc = pFunc;
  74. return convert.stype;
  75. }
  76. else
  77. {
  78. union FuncPtrConvertMI
  79. {
  80. FUNCPTR_TYPE pFunc;
  81. struct
  82. {
  83. ScriptFunctionBindingStorageType_t stype;
  84. intptr_t iToc;
  85. } fn8;
  86. };
  87. FuncPtrConvertMI convert;
  88. convert.fn8.iToc = 0;
  89. convert.pFunc = pFunc;
  90. if ( !convert.fn8.iToc )
  91. return convert.fn8.stype;
  92. Assert( 0 );
  93. DebuggerBreak();
  94. return 0;
  95. }
  96. #else
  97. return ( ScriptFunctionBindingStorageType_t ) pFunc;
  98. #endif
  99. }
  100. template <typename FUNCPTR_TYPE>
  101. inline FUNCPTR_TYPE ScriptConvertFreeFuncPtrFromVoid( ScriptFunctionBindingStorageType_t p )
  102. {
  103. #if defined(_PS3) || defined(POSIX)
  104. COMPILE_TIME_ASSERT( sizeof( FUNCPTR_TYPE ) == sizeof(void*)*2 || sizeof( FUNCPTR_TYPE ) == sizeof(void*) );
  105. if ( sizeof( FUNCPTR_TYPE ) == 4 )
  106. {
  107. union FuncPtrConvertMI
  108. {
  109. FUNCPTR_TYPE pFunc;
  110. ScriptFunctionBindingStorageType_t stype;
  111. };
  112. FuncPtrConvertMI convert;
  113. convert.pFunc = 0;
  114. convert.stype = p;
  115. return convert.pFunc;
  116. }
  117. else
  118. {
  119. union FuncPtrConvertMI
  120. {
  121. FUNCPTR_TYPE pFunc;
  122. struct
  123. {
  124. ScriptFunctionBindingStorageType_t stype;
  125. intptr_t iToc;
  126. } fn8;
  127. };
  128. FuncPtrConvertMI convert;
  129. convert.pFunc = 0;
  130. convert.fn8.stype = p;
  131. convert.fn8.iToc = 0;
  132. return convert.pFunc;
  133. }
  134. #else
  135. return (FUNCPTR_TYPE) p;
  136. #endif
  137. }
  138. template <typename FUNCPTR_TYPE>
  139. inline ScriptFunctionBindingStorageType_t ScriptConvertFuncPtrToVoid( FUNCPTR_TYPE pFunc )
  140. {
  141. typedef FUNCPTR_TYPE FuncPtr_t;
  142. size_t funcPtrSize = sizeof( FuncPtr_t ); funcPtrSize;
  143. #if defined(_PS3) || defined(POSIX)
  144. return ScriptConvertFreeFuncPtrToVoid<FUNCPTR_TYPE>( pFunc );
  145. #else
  146. if ( ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) ) )
  147. {
  148. // simple inheritance
  149. union FuncPtrConvert
  150. {
  151. void *p;
  152. FUNCPTR_TYPE pFunc;
  153. };
  154. FuncPtrConvert convert;
  155. convert.pFunc = pFunc;
  156. return convert.p;
  157. }
  158. #if MSVC
  159. else if ( ( IsPlatformWindowsPC32() && ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) + sizeof( int ) ) ) ||
  160. ( IsPlatformWindowsPC64() && ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) + sizeof( int ) * 2 ) ) )
  161. {
  162. // multiple and virtual inheritance
  163. struct MicrosoftUnknownMFP
  164. {
  165. void *p;
  166. int m_delta;
  167. };
  168. union FuncPtrConvertMI
  169. {
  170. MicrosoftUnknownMFP mfp;
  171. FUNCPTR_TYPE pFunc;
  172. };
  173. FuncPtrConvertMI convert;
  174. convert.pFunc = pFunc;
  175. if ( convert.mfp.m_delta == 0 )
  176. {
  177. return convert.mfp.p;
  178. }
  179. AssertMsg( 0, "Function pointer must be from primary vtable" );
  180. }
  181. else if ( ( IsPlatformWindowsPC32() && ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) + ( sizeof( int ) * 3 ) ) ) ||
  182. ( IsPlatformWindowsPC64() && ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) + ( sizeof( int ) * 4 ) ) ) )
  183. {
  184. // unknown_inheritance case
  185. struct MicrosoftUnknownMFP
  186. {
  187. void *p;
  188. int m_delta;
  189. int m_vtordisp;
  190. int m_vtable_index;
  191. };
  192. union FuncPtrConvertMI
  193. {
  194. MicrosoftUnknownMFP mfp;
  195. FUNCPTR_TYPE pFunc;
  196. };
  197. FuncPtrConvertMI convert;
  198. convert.pFunc = pFunc;
  199. if ( convert.mfp.m_delta == 0 )
  200. {
  201. return convert.mfp.p;
  202. }
  203. AssertMsg( 0, "Function pointer must be from primary vtable" );
  204. }
  205. #elif defined( GNUC )
  206. else if ( ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) + sizeof( int ) ) )
  207. {
  208. AssertMsg( 0, "Note: This path has not been verified yet. See comments below in #else case." );
  209. struct GnuMFP
  210. {
  211. union
  212. {
  213. void *funcadr; // If vtable_index_2 is even, then this is the function pointer.
  214. int vtable_index_2; // If vtable_index_2 is odd, then this = vindex*2+1.
  215. };
  216. int delta;
  217. };
  218. GnuMFP *p = (GnuMFP*)&pFunc;
  219. if ( p->vtable_index_2 & 1 )
  220. {
  221. char **delta = (char**)p->delta;
  222. char *pCur = *delta + (p->vtable_index_2+1)/2;
  223. return (void*)( pCur + 4 );
  224. }
  225. else
  226. {
  227. return p->funcadr;
  228. }
  229. }
  230. #else
  231. #error "Need to implement code to crack non-offset member function pointer case"
  232. // For gcc, see: http://www.codeproject.com/KB/cpp/FastDelegate.aspx
  233. //
  234. // Current versions of the GNU compiler use a strange and tricky
  235. // optimization. It observes that, for virtual inheritance, you have to look
  236. // up the vtable in order to get the voffset required to calculate the this
  237. // pointer. While you're doing that, you might as well store the function
  238. // pointer in the vtable. By doing this, they combine the m_func_address and
  239. // m_vtable_index fields into one, and they distinguish between them by
  240. // ensuring that function pointers always point to even addresses but vtable
  241. // indices are always odd:
  242. //
  243. // // GNU g++ uses a tricky space optimisation, also adopted by IBM's VisualAge and XLC.
  244. // struct GnuMFP {
  245. // union {
  246. // CODEPTR funcadr; // always even
  247. // int vtable_index_2; // = vindex*2+1, always odd
  248. // };
  249. // int delta;
  250. // };
  251. // adjustedthis = this + delta
  252. // if (funcadr & 1) CALL (* ( *delta + (vindex+1)/2) + 4)
  253. // else CALL funcadr
  254. //
  255. // The G++ method is well documented, so it has been adopted by many other
  256. // vendors, including IBM's VisualAge and XLC compilers, recent versions of
  257. // Open64, Pathscale EKO, and Metrowerks' 64-bit compilers. A simpler scheme
  258. // used by earlier versions of GCC is also very common. SGI's now
  259. // discontinued MIPSPro and Pro64 compilers, and Apple's ancient MrCpp
  260. // compiler used this method. (Note that the Pro64 compiler has become the
  261. // open source Open64 compiler).
  262. #endif
  263. else
  264. AssertMsg( 0, "Member function pointer not supported. Why on earth are you using virtual inheritance!?" );
  265. return NULL;
  266. #endif
  267. }
  268. template <typename FUNCPTR_TYPE>
  269. inline FUNCPTR_TYPE ScriptConvertFuncPtrFromVoid( ScriptFunctionBindingStorageType_t p )
  270. {
  271. #if defined(_PS3) || defined(POSIX)
  272. return ScriptConvertFreeFuncPtrFromVoid<FUNCPTR_TYPE>( p );
  273. #else
  274. if ( ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) ) )
  275. {
  276. union FuncPtrConvert
  277. {
  278. void *p;
  279. FUNCPTR_TYPE pFunc;
  280. };
  281. FuncPtrConvert convert;
  282. convert.p = p;
  283. return convert.pFunc;
  284. }
  285. #if MSVC
  286. if ( ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) + sizeof( int ) ) )
  287. {
  288. struct MicrosoftUnknownMFP
  289. {
  290. void *p;
  291. int m_delta;
  292. };
  293. union FuncPtrConvertMI
  294. {
  295. MicrosoftUnknownMFP mfp;
  296. FUNCPTR_TYPE pFunc;
  297. };
  298. FuncPtrConvertMI convert;
  299. convert.mfp.p = p;
  300. convert.mfp.m_delta = 0;
  301. return convert.pFunc;
  302. }
  303. if ( ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) + ( sizeof( int ) * 3 ) ) )
  304. {
  305. struct MicrosoftUnknownMFP
  306. {
  307. void *p;
  308. int m_delta;
  309. int m_vtordisp;
  310. int m_vtable_index;
  311. };
  312. union FuncPtrConvertMI
  313. {
  314. MicrosoftUnknownMFP mfp;
  315. FUNCPTR_TYPE pFunc;
  316. };
  317. FuncPtrConvertMI convert;
  318. convert.mfp.p = p;
  319. convert.mfp.m_delta = 0;
  320. return convert.pFunc;
  321. }
  322. #elif defined( POSIX )
  323. AssertMsg( 0, "Note: This path has not been implemented yet." );
  324. #else
  325. #error "Need to implement code to crack non-offset member function pointer case"
  326. #endif
  327. Assert( 0 );
  328. return NULL;
  329. #endif
  330. }
  331. //-----------------------------------------------------------------------------
  332. //
  333. //-----------------------------------------------------------------------------
  334. #define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_0
  335. #define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_1 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_1
  336. #define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_2 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_2
  337. #define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_3 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_3
  338. #define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_4 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_4
  339. #define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_5 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_5
  340. #define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_6 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_6
  341. #define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_7 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_7
  342. #define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_8 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_8
  343. #define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_9 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_9
  344. #define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_10 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_10
  345. #define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_11 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_11
  346. #define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_12 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_12
  347. #define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_13 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_13
  348. #define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_14 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_14
  349. #define SCRIPT_BINDING_ARGS_0
  350. #define SCRIPT_BINDING_ARGS_1 pArguments[0]
  351. #define SCRIPT_BINDING_ARGS_2 pArguments[0], pArguments[1]
  352. #define SCRIPT_BINDING_ARGS_3 pArguments[0], pArguments[1], pArguments[2]
  353. #define SCRIPT_BINDING_ARGS_4 pArguments[0], pArguments[1], pArguments[2], pArguments[3]
  354. #define SCRIPT_BINDING_ARGS_5 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4]
  355. #define SCRIPT_BINDING_ARGS_6 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5]
  356. #define SCRIPT_BINDING_ARGS_7 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6]
  357. #define SCRIPT_BINDING_ARGS_8 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7]
  358. #define SCRIPT_BINDING_ARGS_9 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7], pArguments[8]
  359. #define SCRIPT_BINDING_ARGS_10 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7], pArguments[8], pArguments[9]
  360. #define SCRIPT_BINDING_ARGS_11 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7], pArguments[8], pArguments[9], pArguments[10]
  361. #define SCRIPT_BINDING_ARGS_12 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7], pArguments[8], pArguments[9], pArguments[10], pArguments[11]
  362. #define SCRIPT_BINDING_ARGS_13 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7], pArguments[8], pArguments[9], pArguments[10], pArguments[11], pArguments[12]
  363. #define SCRIPT_BINDING_ARGS_14 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7], pArguments[8], pArguments[9], pArguments[10], pArguments[11], pArguments[12], pArguments[13]
  364. #define DEFINE_SCRIPT_BINDINGS(N) \
  365. template <typename FUNC_TYPE, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N> \
  366. class CNonMemberScriptBinding##N \
  367. { \
  368. public: \
  369. static bool Call( ScriptFunctionBindingStorageType_t pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn ) \
  370. { \
  371. Assert( nArguments == N ); \
  372. Assert( pReturn ); \
  373. Assert( !pContext ); \
  374. \
  375. if ( nArguments != N || !pReturn || pContext ) \
  376. { \
  377. return false; \
  378. } \
  379. *pReturn = (ScriptConvertFreeFuncPtrFromVoid<FUNC_TYPE>(pFunction))( SCRIPT_BINDING_ARGS_##N ); \
  380. if ( pReturn->m_type == FIELD_VECTOR ) \
  381. pReturn->m_pVector = new Vector(*pReturn->m_pVector); \
  382. return true; \
  383. } \
  384. }; \
  385. \
  386. template <typename FUNC_TYPE FUNC_TEMPLATE_FUNC_PARAMS_##N> \
  387. class CNonMemberScriptBinding##N<FUNC_TYPE, void FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_##N> \
  388. { \
  389. public: \
  390. static bool Call( ScriptFunctionBindingStorageType_t pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn ) \
  391. { \
  392. Assert( nArguments == N ); \
  393. Assert( !pReturn ); \
  394. Assert( !pContext ); \
  395. \
  396. if ( nArguments != N || pReturn || pContext ) \
  397. { \
  398. return false; \
  399. } \
  400. (ScriptConvertFreeFuncPtrFromVoid<FUNC_TYPE>(pFunction))( SCRIPT_BINDING_ARGS_##N ); \
  401. return true; \
  402. } \
  403. }; \
  404. \
  405. template <class OBJECT_TYPE_PTR, typename FUNC_TYPE, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N> \
  406. class CMemberScriptBinding##N \
  407. { \
  408. public: \
  409. static bool Call( ScriptFunctionBindingStorageType_t pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn ) \
  410. { \
  411. Assert( nArguments == N ); \
  412. Assert( pReturn ); \
  413. Assert( pContext ); \
  414. \
  415. if ( nArguments != N || !pReturn || !pContext ) \
  416. { \
  417. return false; \
  418. } \
  419. *pReturn = (((OBJECT_TYPE_PTR)(pContext))->*ScriptConvertFuncPtrFromVoid<FUNC_TYPE>(pFunction))( SCRIPT_BINDING_ARGS_##N ); \
  420. if ( pReturn->m_type == FIELD_VECTOR ) \
  421. pReturn->m_pVector = new Vector(*pReturn->m_pVector); \
  422. return true; \
  423. } \
  424. }; \
  425. \
  426. template <class OBJECT_TYPE_PTR, typename FUNC_TYPE FUNC_TEMPLATE_FUNC_PARAMS_##N> \
  427. class CMemberScriptBinding##N<OBJECT_TYPE_PTR, FUNC_TYPE, void FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_##N> \
  428. { \
  429. public: \
  430. static bool Call( ScriptFunctionBindingStorageType_t pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn ) \
  431. { \
  432. Assert( nArguments == N ); \
  433. Assert( !pReturn ); \
  434. Assert( pContext ); \
  435. \
  436. if ( nArguments != N || pReturn || !pContext ) \
  437. { \
  438. return false; \
  439. } \
  440. (((OBJECT_TYPE_PTR)(pContext))->*ScriptConvertFuncPtrFromVoid<FUNC_TYPE>(pFunction))( SCRIPT_BINDING_ARGS_##N ); \
  441. return true; \
  442. } \
  443. }; \
  444. \
  445. template <typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N> \
  446. inline ScriptBindingFunc_t ScriptCreateBinding(FUNCTION_RETTYPE (*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) ) \
  447. { \
  448. typedef FUNCTION_RETTYPE (*Func_t)(FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N); \
  449. return &CNonMemberScriptBinding##N<Func_t, FUNCTION_RETTYPE FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_##N>::Call; \
  450. } \
  451. \
  452. template <typename OBJECT_TYPE_PTR, typename FUNCTION_CLASS, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N> \
  453. inline ScriptBindingFunc_t ScriptCreateBinding(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE (FUNCTION_CLASS::*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) ) \
  454. { \
  455. typedef FUNCTION_RETTYPE (FUNCTION_CLASS::*Func_t)(FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N); \
  456. return &CMemberScriptBinding##N<OBJECT_TYPE_PTR, Func_t, FUNCTION_RETTYPE FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_##N>::Call; \
  457. } \
  458. \
  459. template <typename OBJECT_TYPE_PTR, typename FUNCTION_CLASS, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N> \
  460. inline ScriptBindingFunc_t ScriptCreateBinding(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE (FUNCTION_CLASS::*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) const ) \
  461. { \
  462. typedef FUNCTION_RETTYPE (FUNCTION_CLASS::*Func_t)(FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N); \
  463. return &CMemberScriptBinding##N<OBJECT_TYPE_PTR, Func_t, FUNCTION_RETTYPE FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_##N>::Call; \
  464. }
  465. FUNC_GENERATE_ALL( DEFINE_SCRIPT_BINDINGS );
  466. //-----------------------------------------------------------------------------
  467. //
  468. //-----------------------------------------------------------------------------
  469. #endif // VSCRIPT_TEMPLATES_H