PageRenderTime 65ms CodeModel.GetById 20ms app.highlight 39ms RepoModel.GetById 1ms app.codeStats 1ms

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