/xbmc/visualizations/Vortex/angelscript/angelscript/source/as_callfunc_xenon.cpp

http://github.com/xbmc/xbmc · C++ · 826 lines · 593 code · 95 blank · 138 comment · 78 complexity · fcbd5b513042a93209ca68548ce6dcb6 MD5 · raw file

  1. /*
  2. AngelCode Scripting Library
  3. Copyright (c) 2003-2009 Andreas Jonsson
  4. This software is provided 'as-is', without any express or implied
  5. warranty. In no event will the authors be held liable for any
  6. damages arising from the use of this software.
  7. Permission is granted to anyone to use this software for any
  8. purpose, including commercial applications, and to alter it and
  9. redistribute it freely, subject to the following restrictions:
  10. 1. The origin of this software must not be misrepresented; you
  11. must not claim that you wrote the original software. If you use
  12. this software in a product, an acknowledgment in the product
  13. documentation would be appreciated but is not required.
  14. 2. Altered source versions must be plainly marked as such, and
  15. must not be misrepresented as being the original software.
  16. 3. This notice may not be removed or altered from any source
  17. distribution.
  18. The original version of this library can be located at:
  19. http://www.angelcode.com/angelscript/
  20. Andreas Jonsson
  21. andreas@angelcode.com
  22. */
  23. //
  24. // as_callfunc_xenon.cpp
  25. //
  26. // These functions handle the actual calling of system functions
  27. //
  28. // This version is Xenon specific
  29. // Modified from as_callfunc_ppc.cpp by Laszlo Perneky Februar 2007
  30. #include "as_config.h"
  31. #ifndef AS_MAX_PORTABILITY
  32. #ifdef AS_XENON
  33. #include "as_callfunc.h"
  34. #include "as_scriptengine.h"
  35. #include "as_texts.h"
  36. #include "as_tokendef.h"
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. BEGIN_AS_NAMESPACE
  40. #define AS_PPC_MAX_ARGS 32
  41. #define AS_MAX_REG_FLOATS 13
  42. #define AS_MAX_REG_INTS 8
  43. #define AS_PPC_THISCALL_REG 1
  44. #define AS_PPC_RETURNINMEM_REG 1
  45. #define AS_PPC_ENDOFARGS 1
  46. // The array used to send values to the correct places.
  47. // Contains a byte of argTypes to indicate the register type to load, or zero if end of arguments
  48. extern "C" {
  49. enum argTypes
  50. {
  51. ppcENDARG = 0,
  52. ppcINTARG,
  53. ppcFLOATARG,
  54. ppcDOUBLEARG
  55. };
  56. static asBYTE ppcArgsType[AS_PPC_MAX_ARGS + AS_PPC_RETURNINMEM_REG + AS_PPC_THISCALL_REG + AS_PPC_ENDOFARGS];
  57. static asDWORD ppcArgs[AS_PPC_MAX_ARGS + AS_PPC_RETURNINMEM_REG + AS_PPC_THISCALL_REG];
  58. }
  59. // Loads all data into the correct places and calls the function.
  60. // ppcArgsType is an array containing a byte type (enum argTypes) for each argument.
  61. // iStackArgSize is the size in bytes for how much data to put on the stack frame
  62. //--------------------------------------------------------------------
  63. asQWORD __declspec( naked ) ppcFunc(const asDWORD* pArgs, int iStackArgSize, asDWORD dwFunc)
  64. {
  65. __asm
  66. {
  67. //////////////////////////////////////////////////////////////////////////
  68. // Prepare args
  69. //////////////////////////////////////////////////////////////////////////
  70. _ppcFunc:
  71. // setup stack
  72. // Read link register
  73. mflr r12
  74. // Stack the link register
  75. stw r12, -8(r1)
  76. // Move stack pointer
  77. stwu r1, -70h(r1)
  78. mr r29, r3 //pArgs
  79. mr r30, r4 //iStackArgSize
  80. mr r27, r5 //dwFunc
  81. // Clear some registers
  82. sub r0, r0, r0
  83. // Counting of used/assigned GPR's
  84. mr r23, r0
  85. // Counting of used/assigned Float Registers
  86. mr r22, r0
  87. // Fetch argument types array address
  88. lau r25, ppcArgsType
  89. lal r25, r25, ppcArgsType
  90. // Fetch arguments array address
  91. lau r26, ppcArgs
  92. lal r26, r26, ppcArgs
  93. // Begin loading and stacking registers
  94. subi r25, r25, 1
  95. //////////////////////////////////////////////////////////////////////////
  96. // Fetch the next argument
  97. //////////////////////////////////////////////////////////////////////////
  98. ppcNextArg:
  99. // Increment rArgTypePtr
  100. addi r25, r25, 1
  101. // Get data type
  102. lbz r24, 0(r25)
  103. // r24 holds the data type
  104. cmplwi cr6, r24, 0
  105. beq cr6, ppcArgsEnd
  106. cmplwi cr6, r24, 1
  107. beq cr6, ppcArgIsInteger
  108. cmplwi cr6, r24, 2
  109. beq cr6, ppcArgIsFloat
  110. cmplwi cr6, r24, 3
  111. beq cr6, ppcArgIsDouble
  112. //////////////////////////////////////////////////////////////////////////
  113. // Load and stack integer arguments
  114. //////////////////////////////////////////////////////////////////////////
  115. ppcArgIsInteger:
  116. // Get the arg from the stack
  117. lwz r11, 0(r26)
  118. // r23 holds the integer arg count so far
  119. cmplwi cr6, r23, 0
  120. beq cr6, ppcLoadIntReg0
  121. cmplwi cr6, r23, 1
  122. beq cr6, ppcLoadIntReg1
  123. cmplwi cr6, r23, 2
  124. beq cr6, ppcLoadIntReg2
  125. cmplwi cr6, r23, 3
  126. beq cr6, ppcLoadIntReg3
  127. cmplwi cr6, r23, 4
  128. beq cr6, ppcLoadIntReg4
  129. cmplwi cr6, r23, 5
  130. beq cr6, ppcLoadIntReg5
  131. cmplwi cr6, r23, 6
  132. beq cr6, ppcLoadIntReg6
  133. cmplwi cr6, r23, 7
  134. beq cr6, ppcLoadIntReg7
  135. // no more than 8 parameters
  136. b ppcLoadIntRegUpd
  137. ppcLoadIntReg0:
  138. mr r3, r11
  139. b ppcLoadIntRegUpd
  140. ppcLoadIntReg1:
  141. mr r4, r11
  142. b ppcLoadIntRegUpd
  143. ppcLoadIntReg2:
  144. mr r5, r11
  145. b ppcLoadIntRegUpd
  146. ppcLoadIntReg3:
  147. mr r6, r11
  148. b ppcLoadIntRegUpd
  149. ppcLoadIntReg4:
  150. mr r7, r11
  151. b ppcLoadIntRegUpd
  152. ppcLoadIntReg5:
  153. mr r8, r11
  154. b ppcLoadIntRegUpd
  155. ppcLoadIntReg6:
  156. mr r9, r11
  157. b ppcLoadIntRegUpd
  158. ppcLoadIntReg7:
  159. mr r10, r11
  160. b ppcLoadIntRegUpd
  161. ppcLoadIntRegUpd:
  162. // Increment used int register count
  163. addi r23, r23, 1
  164. // Increment rArgsPtr
  165. addi r29, r29, 4
  166. // Increment rStackPtr
  167. addi r26, r26, 4
  168. b ppcNextArg
  169. //////////////////////////////////////////////////////////////////////////
  170. // Load and stack float arguments
  171. //////////////////////////////////////////////////////////////////////////
  172. ppcArgIsFloat:
  173. // Get the arg from the stack
  174. lfs fr15, 0(r26)
  175. // r22 holds the float arg count so far
  176. cmplwi cr6, r23, 0
  177. beq cr6, ppcLoadFloatReg0
  178. cmplwi cr6, r23, 1
  179. beq cr6, ppcLoadFloatReg1
  180. cmplwi cr6, r23, 2
  181. beq cr6, ppcLoadFloatReg2
  182. cmplwi cr6, r23, 3
  183. beq cr6, ppcLoadFloatReg3
  184. cmplwi cr6, r23, 4
  185. beq cr6, ppcLoadFloatReg4
  186. cmplwi cr6, r23, 5
  187. beq cr6, ppcLoadFloatReg5
  188. cmplwi cr6, r23, 6
  189. beq cr6, ppcLoadFloatReg6
  190. cmplwi cr6, r23, 7
  191. beq cr6, ppcLoadFloatReg7
  192. cmplwi cr6, r23, 8
  193. beq cr6, ppcLoadFloatReg8
  194. cmplwi cr6, r23, 9
  195. beq cr6, ppcLoadFloatReg9
  196. cmplwi cr6, r23, 10
  197. beq cr6, ppcLoadFloatReg10
  198. cmplwi cr6, r23, 11
  199. beq cr6, ppcLoadFloatReg11
  200. cmplwi cr6, r23, 12
  201. beq cr6, ppcLoadFloatReg12
  202. cmplwi cr6, r23, 13
  203. beq cr6, ppcLoadFloatReg13
  204. cmplwi cr6, r23, 14
  205. beq cr6, ppcLoadFloatReg14
  206. // no more than 14 parameters
  207. b ppcLoadFloatRegUpd
  208. ppcLoadFloatReg0:
  209. fmr fr0, fr15
  210. b ppcLoadFloatRegUpd
  211. ppcLoadFloatReg1:
  212. fmr fr1, fr15
  213. b ppcLoadFloatRegUpd
  214. ppcLoadFloatReg2:
  215. fmr fr2, fr15
  216. b ppcLoadFloatRegUpd
  217. ppcLoadFloatReg3:
  218. fmr fr3, fr15
  219. b ppcLoadFloatRegUpd
  220. ppcLoadFloatReg4:
  221. fmr fr4, fr15
  222. b ppcLoadFloatRegUpd
  223. ppcLoadFloatReg5:
  224. fmr fr5, fr15
  225. b ppcLoadFloatRegUpd
  226. ppcLoadFloatReg6:
  227. fmr fr6, fr15
  228. b ppcLoadFloatRegUpd
  229. ppcLoadFloatReg7:
  230. fmr fr7, fr15
  231. b ppcLoadFloatRegUpd
  232. ppcLoadFloatReg8:
  233. fmr fr8, fr15
  234. b ppcLoadFloatRegUpd
  235. ppcLoadFloatReg9:
  236. fmr fr9, fr15
  237. b ppcLoadFloatRegUpd
  238. ppcLoadFloatReg10:
  239. fmr fr10, fr15
  240. b ppcLoadFloatRegUpd
  241. ppcLoadFloatReg11:
  242. fmr fr11, fr15
  243. b ppcLoadFloatRegUpd
  244. ppcLoadFloatReg12:
  245. fmr fr12, fr15
  246. b ppcLoadFloatRegUpd
  247. ppcLoadFloatReg13:
  248. fmr fr13, fr15
  249. b ppcLoadFloatRegUpd
  250. ppcLoadFloatReg14:
  251. fmr fr14, fr15
  252. b ppcLoadFloatRegUpd
  253. ppcLoadFloatRegUpd:
  254. // Increment used float register count
  255. addi r22, r22, 1
  256. // Increment used int register count - a float reg eats up a GPR
  257. addi r23, r23, 1
  258. // Increment rArgsPtr
  259. addi r29, r29, 4
  260. // Increment rStackPtr
  261. addi r26, r26, 4
  262. b ppcNextArg
  263. //////////////////////////////////////////////////////////////////////////
  264. // Load and stack double float arguments
  265. //////////////////////////////////////////////////////////////////////////
  266. ppcArgIsDouble:
  267. // Get the arg from the stack
  268. lfs fr15, 0(r26)
  269. // r22 holds the float arg count so far
  270. cmplwi cr6, r23, 0
  271. beq cr6, ppcLoadDoubleReg0
  272. cmplwi cr6, r23, 1
  273. beq cr6, ppcLoadDoubleReg1
  274. cmplwi cr6, r23, 2
  275. beq cr6, ppcLoadDoubleReg2
  276. cmplwi cr6, r23, 3
  277. beq cr6, ppcLoadDoubleReg3
  278. cmplwi cr6, r23, 4
  279. beq cr6, ppcLoadDoubleReg4
  280. cmplwi cr6, r23, 5
  281. beq cr6, ppcLoadDoubleReg5
  282. cmplwi cr6, r23, 6
  283. beq cr6, ppcLoadDoubleReg6
  284. cmplwi cr6, r23, 7
  285. beq cr6, ppcLoadDoubleReg7
  286. cmplwi cr6, r23, 8
  287. beq cr6, ppcLoadDoubleReg8
  288. cmplwi cr6, r23, 9
  289. beq cr6, ppcLoadDoubleReg9
  290. cmplwi cr6, r23, 10
  291. beq cr6, ppcLoadDoubleReg10
  292. cmplwi cr6, r23, 11
  293. beq cr6, ppcLoadDoubleReg11
  294. cmplwi cr6, r23, 12
  295. beq cr6, ppcLoadDoubleReg12
  296. cmplwi cr6, r23, 13
  297. beq cr6, ppcLoadDoubleReg13
  298. cmplwi cr6, r23, 14
  299. beq cr6, ppcLoadDoubleReg14
  300. ppcLoadDoubleReg0:
  301. fmr fr0, fr15
  302. b ppcLoadDoubleRegUpd
  303. ppcLoadDoubleReg1:
  304. fmr fr1, fr15
  305. b ppcLoadDoubleRegUpd
  306. ppcLoadDoubleReg2:
  307. fmr fr2, fr15
  308. b ppcLoadDoubleRegUpd
  309. ppcLoadDoubleReg3:
  310. fmr fr3, fr15
  311. b ppcLoadDoubleRegUpd
  312. ppcLoadDoubleReg4:
  313. fmr fr4, fr15
  314. b ppcLoadDoubleRegUpd
  315. ppcLoadDoubleReg5:
  316. fmr fr5, fr15
  317. b ppcLoadDoubleRegUpd
  318. ppcLoadDoubleReg6:
  319. fmr fr6, fr15
  320. b ppcLoadDoubleRegUpd
  321. ppcLoadDoubleReg7:
  322. fmr fr7, fr15
  323. b ppcLoadDoubleRegUpd
  324. ppcLoadDoubleReg8:
  325. fmr fr8, fr15
  326. b ppcLoadDoubleRegUpd
  327. ppcLoadDoubleReg9:
  328. fmr fr9, fr15
  329. b ppcLoadDoubleRegUpd
  330. ppcLoadDoubleReg10:
  331. fmr fr10, fr15
  332. b ppcLoadDoubleRegUpd
  333. ppcLoadDoubleReg11:
  334. fmr fr11, fr15
  335. b ppcLoadDoubleRegUpd
  336. ppcLoadDoubleReg12:
  337. fmr fr12, fr15
  338. b ppcLoadDoubleRegUpd
  339. ppcLoadDoubleReg13:
  340. fmr fr13, fr15
  341. b ppcLoadDoubleRegUpd
  342. ppcLoadDoubleReg14:
  343. fmr fr14, fr15
  344. b ppcLoadDoubleRegUpd
  345. ppcLoadDoubleRegUpd:
  346. // Increment used float register count
  347. addi r22, r22, 1
  348. // Increment used int register count
  349. addi r23, r23, 1
  350. // Increment rArgsPtr
  351. addi r29, r29, 4
  352. // Increment rStackPtr
  353. addi r26, r26, 4
  354. b ppcNextArg
  355. //////////////////////////////////////////////////////////////////////////
  356. // Finished
  357. //////////////////////////////////////////////////////////////////////////
  358. ppcArgsEnd:
  359. // Call the function
  360. mtctr r27
  361. bctrl
  362. // Function returned
  363. // Restore callers stack
  364. addi r1, r1, 70h
  365. // Fetch return link to caller
  366. lwz r12, -8(r1)
  367. mtlr r12
  368. blr
  369. }
  370. }
  371. // Puts the arguments in the correct place in the stack array.
  372. //-------------------------------------------------------------------
  373. void stackArgs(const asDWORD *pArgs, int& iNumIntArgs, int& iNumFloatArgs, int& iNumDoubleArgs)
  374. {
  375. int iArgWordPos = iNumIntArgs + iNumFloatArgs + iNumDoubleArgs;
  376. for(int iArg = 0; iArg < AS_PPC_MAX_ARGS; iArg++)
  377. {
  378. if ( ppcArgsType[iArg] == ppcENDARG )
  379. break;
  380. if( ppcArgsType[iArg] == ppcFLOATARG )
  381. {
  382. // stow float
  383. ((float*)ppcArgs)[iArgWordPos] = ((float*)(pArgs))[iArg];
  384. iNumFloatArgs++;
  385. iArgWordPos++; //add one word
  386. }
  387. if ( ppcArgsType[iArg] == ppcDOUBLEARG )
  388. {
  389. // stow double
  390. ((double*)ppcArgs)[iArgWordPos] = ((double*)(pArgs))[iArg];
  391. iNumDoubleArgs++;
  392. iArgWordPos++; //add two words
  393. }
  394. if( ppcArgsType[iArg] == ppcINTARG )
  395. {
  396. // stow register
  397. ((int*)ppcArgs)[iArgWordPos] = ((int*)(pArgs))[iArg];
  398. iNumIntArgs++;
  399. iArgWordPos++;
  400. }
  401. }
  402. }
  403. // Prepare the arg list for a CDecl funtion and then call it
  404. //--------------------------------------------------------------------
  405. asQWORD CallCDeclFunction(const asDWORD* pArgs, int iArgSize, asDWORD dwFunc)
  406. {
  407. int iIntArgs = 0;
  408. int iFloatArgs = 0;
  409. int iDoubleArgs = 0;
  410. // Put the arguments in the correct places in the ppcArgs array
  411. if ( iArgSize > 0 )
  412. stackArgs( pArgs, iIntArgs, iFloatArgs, iDoubleArgs );
  413. return ppcFunc( ppcArgs, iArgSize, dwFunc);
  414. }
  415. // This function is identical to CallCDeclFunction, with the only difference that
  416. // the value in the first parameter is the object
  417. //--------------------------------------------------------------------
  418. asQWORD CallThisCallFunction(const void* pObj, const asDWORD* pArgs, int iArgSize, asDWORD dwFunc )
  419. {
  420. int iIntArgs = 0;
  421. int iFloatArgs = 0;
  422. int iDoubleArgs = 0;
  423. // Put the arguments in the correct places in the ppcArgs array /the this ptr is already in pArgs/
  424. if ( iArgSize > 0 )
  425. stackArgs( pArgs, iIntArgs, iFloatArgs, iDoubleArgs );
  426. return ppcFunc( ppcArgs, iArgSize, dwFunc);
  427. }
  428. // This function is identical to CallCDeclFunction, with the only difference that
  429. // the value in the last parameter is the object
  430. //--------------------------------------------------------------------
  431. asQWORD CallThisCallFunction_objLast(const void* pObj, const asDWORD* pArgs, int iArgSize, asDWORD dwFunc)
  432. {
  433. int iIntArgs = 0;
  434. int iFloatArgs = 0;
  435. int iDoubleArgs = 0;
  436. // Put the arguments in the correct places in the ppcArgs array /the this ptr is already in pArgs/
  437. if ( iArgSize > 0 )
  438. stackArgs( pArgs, iIntArgs, iFloatArgs, iDoubleArgs );
  439. int iNumArgs = iIntArgs + iFloatArgs + iDoubleArgs;
  440. if ( iNumArgs < AS_PPC_MAX_ARGS )
  441. {
  442. ppcArgs[iNumArgs] = (asDWORD)pObj;
  443. ppcArgsType[iNumArgs] = ppcINTARG;
  444. }
  445. return ppcFunc( ppcArgs, iArgSize + sizeof(pObj), dwFunc );
  446. }
  447. //--------------------------------------------------------------------
  448. asDWORD GetReturnedFloat()
  449. {
  450. asDWORD f;
  451. __asm
  452. {
  453. stfs fr0, f
  454. }
  455. return f;
  456. }
  457. asQWORD GetReturnedDouble()
  458. //--------------------------------------------------------------------
  459. {
  460. asQWORD f;
  461. __asm
  462. {
  463. stfd fr0, f
  464. }
  465. return f;
  466. }
  467. int CallSystemFunction(int iId, asCContext* pContext, void* pObjectPointer)
  468. //--------------------------------------------------------------------
  469. {
  470. memset( ppcArgsType, 0, sizeof(ppcArgsType));
  471. asCScriptEngine* pEngine = pContext->engine;
  472. asCScriptFunction* pDescr = pEngine->scriptFunctions[iId];
  473. asSSystemFunctionInterface* pSysFunc = pDescr->sysFuncIntf;
  474. int iCallConv = pSysFunc->callConv;
  475. if ( iCallConv == ICC_GENERIC_FUNC
  476. || iCallConv == ICC_GENERIC_METHOD )
  477. return pContext->CallGeneric( iId, pObjectPointer );
  478. asQWORD dwRetQW = 0;
  479. void* pFunc = (void*)pSysFunc->func;
  480. int iParamSize = pSysFunc->paramSize;
  481. asDWORD* pArgs = pContext->regs.stackPointer;
  482. void* pRetPointer = 0;
  483. void* pObj = 0;
  484. int iPopSize = iParamSize;
  485. asDWORD* pVftable;
  486. // We generate the parameter list to this, so it fits to teh callingconvention
  487. asDWORD fixedArgs[ AS_PPC_MAX_ARGS + AS_PPC_RETURNINMEM_REG + AS_PPC_THISCALL_REG ];
  488. memset(fixedArgs, 0, sizeof(fixedArgs));
  489. int iArgsPtr = 0;
  490. pContext->regs.objectType = pDescr->returnType.GetObjectType();
  491. // If the function returns an object in memory, we allocate the memory and put the ptr to the front (will go to r3)
  492. if ( pDescr->returnType.IsObject() && !pDescr->returnType.IsReference() && !pDescr->returnType.IsObjectHandle() )
  493. {
  494. pRetPointer = pEngine->CallAlloc(pDescr->returnType.GetObjectType());
  495. if( pSysFunc->hostReturnInMemory )
  496. iCallConv++;
  497. fixedArgs [ iArgsPtr ] = (asDWORD)pRetPointer;
  498. ppcArgsType[ iArgsPtr ] = ppcINTARG;
  499. iArgsPtr++;
  500. }
  501. // Find out if we have an object
  502. if ( iCallConv >= ICC_THISCALL )
  503. {
  504. if ( pObjectPointer )
  505. {
  506. pObj = pObjectPointer;
  507. }
  508. else
  509. {
  510. // The object pointer should be popped from the context stack
  511. iPopSize++;
  512. pObj = (void*)*(pArgs);
  513. pArgs++;
  514. // Check for null pointer
  515. if ( pObj == 0 )
  516. {
  517. pContext->SetInternalException(TXT_NULL_POINTER_ACCESS);
  518. if( pRetPointer )
  519. pEngine->CallFree(pRetPointer);
  520. return 0;
  521. }
  522. // Add the base offset for multiple inheritance
  523. pObj = (void*)(int(pObj) + pSysFunc->baseOffset);
  524. }
  525. }
  526. // If we have an object and it's not objectlast, then we put it az the first arg
  527. if ( pObj
  528. && iCallConv != ICC_CDECL_OBJLAST
  529. && iCallConv != ICC_CDECL_OBJLAST_RETURNINMEM )
  530. {
  531. fixedArgs [ iArgsPtr ] = (asDWORD)pObj;
  532. ppcArgsType[ iArgsPtr ] = ppcINTARG;
  533. iArgsPtr++;
  534. }
  535. asASSERT(pDescr->parameterTypes.GetLength() <= AS_PPC_MAX_ARGS);
  536. // Parameter calculation magic
  537. asDWORD paramBuffer[64];
  538. if ( pSysFunc->takesObjByVal )
  539. {
  540. iParamSize = 0;
  541. int iSpos = 0;
  542. int iDpos = 1;
  543. for ( asUINT uParam = 0; uParam < pDescr->parameterTypes.GetLength(); uParam++ )
  544. {
  545. // Parameter object by value
  546. if ( pDescr->parameterTypes[uParam].IsObject()
  547. && !pDescr->parameterTypes[uParam].IsObjectHandle()
  548. && !pDescr->parameterTypes[uParam].IsReference() )
  549. {
  550. #ifdef COMPLEX_OBJS_PASSED_BY_REF
  551. if( pDescr->parameterTypes[uParam].GetObjectType()->flags & COMPLEX_MASK )
  552. {
  553. paramBuffer[dpos++] = args[spos++];
  554. paramSize++;
  555. }
  556. else
  557. #endif
  558. {
  559. // Copy the object's memory to the buffer
  560. memcpy( &paramBuffer[iDpos], *(void**)(pArgs + iSpos), pDescr->parameterTypes[uParam].GetSizeInMemoryBytes() );
  561. // Delete the original memory
  562. pEngine->CallFree(*(char**)(pArgs + iSpos) );
  563. pArgs[uParam] = (asDWORD)&paramBuffer[iDpos];
  564. iSpos++;
  565. iDpos += pDescr->parameterTypes[uParam].GetSizeInMemoryDWords();
  566. iParamSize += pDescr->parameterTypes[uParam].GetSizeInMemoryDWords();
  567. }
  568. }
  569. else
  570. {
  571. // Copy the value directly
  572. paramBuffer[iDpos++] = pArgs[iSpos++];
  573. if( pDescr->parameterTypes[uParam].GetSizeOnStackDWords() > 1 )
  574. paramBuffer[iDpos++] = pArgs[iSpos++];
  575. iParamSize += pDescr->parameterTypes[uParam].GetSizeOnStackDWords();
  576. }
  577. }
  578. }
  579. // Copy the parameter types for the ppcFunc. Also copy the params for the fixed xenon args buffer /containing this and return ptr/
  580. for( int iParam = 0; iParam < (int)pDescr->parameterTypes.GetLength(); iParam++, iArgsPtr++ )
  581. {
  582. ppcArgsType[iArgsPtr] = ppcINTARG;
  583. if (pDescr->parameterTypes[iParam].IsFloatType())
  584. ppcArgsType[iArgsPtr] = ppcFLOATARG;
  585. else if (pDescr->parameterTypes[iParam].IsDoubleType())
  586. ppcArgsType[iArgsPtr] = ppcDOUBLEARG;
  587. fixedArgs[iArgsPtr] = pArgs[iParam];
  588. // If the arg is bool, then endian swap it /it would not neccessary if the AS_BIG_ENDIAN would swap the bool from 0x01000000 to 0x00000010/
  589. if ( pDescr->parameterTypes[iParam].GetTokenType() == ttBool )
  590. ((asBYTE*)(&fixedArgs[iArgsPtr]))[3] = ((asBYTE*)(&fixedArgs[iArgsPtr]))[0];
  591. }
  592. pContext->isCallingSystemFunction = true;
  593. switch ( iCallConv )
  594. {
  595. case ICC_CDECL:
  596. case ICC_CDECL_RETURNINMEM:
  597. case ICC_STDCALL:
  598. case ICC_STDCALL_RETURNINMEM:
  599. dwRetQW = CallCDeclFunction( fixedArgs, iArgsPtr, (asDWORD)pFunc );
  600. break;
  601. case ICC_THISCALL:
  602. case ICC_THISCALL_RETURNINMEM:
  603. dwRetQW = CallThisCallFunction( pObj, fixedArgs, iArgsPtr, (asDWORD)pFunc );
  604. break;
  605. case ICC_VIRTUAL_THISCALL:
  606. case ICC_VIRTUAL_THISCALL_RETURNINMEM:
  607. // Get virtual function table from the object pointer
  608. pVftable = *(asDWORD**)pObj;
  609. dwRetQW = CallThisCallFunction( pObj, fixedArgs, iArgsPtr, pVftable[asDWORD(pFunc)>>2] );
  610. break;
  611. case ICC_CDECL_OBJLAST:
  612. case ICC_CDECL_OBJLAST_RETURNINMEM:
  613. dwRetQW = CallThisCallFunction_objLast( pObj, fixedArgs, iArgsPtr, (asDWORD)pFunc );
  614. break;
  615. case ICC_CDECL_OBJFIRST:
  616. case ICC_CDECL_OBJFIRST_RETURNINMEM:
  617. dwRetQW = CallThisCallFunction( pObj, fixedArgs, iArgsPtr, (asDWORD)pFunc );
  618. break;
  619. default:
  620. pContext->SetInternalException( TXT_INVALID_CALLING_CONVENTION );
  621. }
  622. pContext->isCallingSystemFunction = false;
  623. #ifdef COMPLEX_OBJS_PASSED_BY_REF
  624. if( pSysFunc->takesObjByVal )
  625. {
  626. // Need to free the complex objects passed by value
  627. pArgs = pContext->regs.stackPointer;
  628. if ( iCallConv >= ICC_THISCALL
  629. && !pObjectPointer )
  630. pArgs++;
  631. int iSpos = 0;
  632. for( int iParam = 0; iParam < (int)descr->parameterTypes.GetLength(); iParam++ )
  633. {
  634. if ( pDescr->parameterTypes[iParam].IsObject()
  635. && !pDescr->parameterTypes[iParam].IsReference()
  636. && (pDescr->parameterTypes[iParam].GetObjectType()->flags & COMPLEX_MASK) )
  637. {
  638. void *pObj = (void*)pArgs[iSpos++];
  639. asSTypeBehaviour *pBeh = &pDescr->parameterTypes[iParam].GetObjectType()->beh;
  640. if( pBeh->destruct )
  641. pEngine->CallObjectMethod(pObj, pBeh->destruct);
  642. pEngine->CallFree(pObj);
  643. }
  644. else
  645. iSpos += pDescr->parameterTypes[iParam].GetSizeInMemoryDWords();
  646. }
  647. }
  648. #endif
  649. // Store the returned value in our stack
  650. if ( pDescr->returnType.IsObject()
  651. && !pDescr->returnType.IsReference() )
  652. {
  653. if ( pDescr->returnType.IsObjectHandle() )
  654. {
  655. pContext->regs.objectRegister = (void*)(asDWORD)dwRetQW;
  656. if ( pSysFunc->returnAutoHandle
  657. && pContext->regs.objectRegister )
  658. pEngine->CallObjectMethod( pContext->regs.objectRegister, pDescr->returnType.GetObjectType()->beh.addref );
  659. }
  660. else
  661. {
  662. if ( !pSysFunc->hostReturnInMemory )
  663. {
  664. // Copy the returned value to the pointer sent by the script engine
  665. if ( pSysFunc->hostReturnSize == 1 )
  666. *(asDWORD*)pRetPointer = (asDWORD)dwRetQW;
  667. else
  668. *(asQWORD*)pRetPointer = dwRetQW;
  669. }
  670. // Store the object in the register
  671. pContext->regs.objectRegister = pRetPointer;
  672. }
  673. }
  674. else
  675. {
  676. // If the retval is bool, then endian swap it /it would not neccessary if the AS_BIG_ENDIAN would swap the bool from 0x01000000 to 0x00000010/
  677. if ( pDescr->returnType.GetTokenType() == ttBool )
  678. {
  679. ((asBYTE*)(&dwRetQW))[4] = ((asBYTE*)(&dwRetQW))[7];
  680. ((asBYTE*)(&dwRetQW))[7] = 0;
  681. }
  682. // Store value in returnVal register
  683. if ( pSysFunc->hostReturnFloat )
  684. {
  685. if ( pSysFunc->hostReturnSize == 1 )
  686. *(asDWORD*)&pContext->regs.valueRegister = GetReturnedFloat();
  687. else
  688. pContext->regs.valueRegister = GetReturnedDouble();
  689. }
  690. else if ( pSysFunc->hostReturnSize == 1 )
  691. *(asDWORD*)&pContext->regs.valueRegister = (asDWORD)dwRetQW;
  692. else
  693. pContext->regs.valueRegister = dwRetQW;
  694. }
  695. if( pSysFunc->hasAutoHandles )
  696. {
  697. pArgs = pContext->regs.stackPointer;
  698. if ( iCallConv >= ICC_THISCALL
  699. && !pObjectPointer )
  700. pArgs++;
  701. int iSpos = 0;
  702. for ( asUINT uParam = 0; uParam < pDescr->parameterTypes.GetLength(); uParam++ )
  703. {
  704. if ( pSysFunc->paramAutoHandles[uParam]
  705. && pArgs[iSpos] )
  706. {
  707. // Call the release method on the type
  708. pEngine->CallObjectMethod( (void*)pArgs[iSpos], pDescr->parameterTypes[uParam].GetObjectType()->beh.release );
  709. pArgs[iSpos] = 0;
  710. }
  711. if ( pDescr->parameterTypes[uParam].IsObject()
  712. && !pDescr->parameterTypes[uParam].IsObjectHandle()
  713. && !pDescr->parameterTypes[uParam].IsReference() )
  714. iSpos++;
  715. else
  716. iSpos += pDescr->parameterTypes[uParam].GetSizeOnStackDWords();
  717. }
  718. }
  719. return iPopSize;
  720. }
  721. END_AS_NAMESPACE
  722. #endif // AS_XENON
  723. #endif // AS_MAX_PORTABILITY
  724. //------------------------------------------------------------------