extensions/bintools/CallWrapper.cpp
author Scott Ehlert <ds@alliedmods.net>
Wed May 09 05:20:03 2007 +0000 (2007-05-09)
changeset 757 b799caa9a190
parent 739 d22243bb5864
child 942 5a930535b6d0
permissions -rw-r--r--
Whew, massive-ish reorgranization for extensions and such. I will inevitably be shot for this.
(Yes, bail, it all compiles on both platforms)
     1 /**
     2  * vim: set ts=4 :
     3  * ===============================================================
     4  * SourceMod BinTools Extension
     5  * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
     6  * ===============================================================
     7  *
     8  * This program is free software; you can redistribute it and/or
     9  * modify it under the terms of the GNU General Public License
    10  * as published by the Free Software Foundation; either version 2
    11  * of the License, or (at your option) any later version.
    12  * This program is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    15  * GNU General Public License for more details.
    16  * 
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program; if not, write to the Free Software
    19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    20  *
    21  * Version: $Id$
    22  */
    23 
    24 #include "extension.h"
    25 #include "CallWrapper.h"
    26 
    27 CallWrapper::CallWrapper(CallConvention cv, const PassInfo *paramInfo, const PassInfo *retInfo, unsigned int numParams)
    28 {
    29 	m_Cv = cv;
    30 
    31 	if (numParams)
    32 	{
    33 		m_Params = new PassEncode[numParams];
    34 		for (size_t i=0; i<numParams; i++)
    35 		{
    36 			m_Params[i].info = paramInfo[i];
    37 		}
    38 	}
    39 
    40 	if (retInfo)
    41 	{
    42 		m_RetParam = new PassInfo;
    43 		*m_RetParam = *retInfo;
    44 	} else {
    45 		m_RetParam = NULL;
    46 	}
    47 
    48 	m_NumParams = numParams;
    49 
    50 	/* Calculate virtual stack offsets for each parameter */
    51 	size_t offs = 0;
    52 
    53 	if (cv == CallConv_ThisCall)
    54 	{
    55 		offs += sizeof(void *);
    56 	}
    57 	for (size_t i=0; i<numParams; i++)
    58 	{
    59 		m_Params[i].offset = offs;
    60 		offs += m_Params[i].info.size;
    61 	}
    62 }
    63 
    64 CallWrapper::~CallWrapper()
    65 {
    66 	delete [] m_Params;
    67 	delete m_RetParam;
    68 	g_SPEngine->ExecFree(m_Addrs[ADDR_CODEBASE]);
    69 }
    70 
    71 CallConvention CallWrapper::GetCallConvention()
    72 {
    73 	return m_Cv;
    74 }
    75 
    76 const PassEncode *CallWrapper::GetParamInfo(unsigned int num)
    77 {
    78 	return (num+1 > m_NumParams) ? NULL : &m_Params[num];
    79 }
    80 
    81 const PassInfo *CallWrapper::GetReturnInfo()
    82 {
    83 	return m_RetParam;
    84 }
    85 
    86 unsigned int CallWrapper::GetParamCount()
    87 {
    88 	return m_NumParams;
    89 }
    90 
    91 void CallWrapper::Execute(void *vParamStack, void *retBuffer)
    92 {
    93 	typedef void (*CALL_EXECUTE)(void *, void *);
    94 	CALL_EXECUTE fn = (CALL_EXECUTE)m_Addrs[ADDR_CODEBASE];
    95 	fn(vParamStack, retBuffer);
    96 }