Use SSE when available for floating-point operations (
bug 5841, r=her).
3 * =============================================================================
4 * SourceMod BinTools Extension
5 * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
6 * =============================================================================
8 * This program is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, version 3.0, as published by the
10 * Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
20 * As a special exception, AlliedModders LLC gives you permission to link the
21 * code of this program (as well as its derivative works) to "Half-Life 2," the
22 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
23 * by the Valve Corporation. You must obey the GNU General Public License in
24 * all respects for all other code used. Additionally, AlliedModders LLC grants
25 * this exception to all derivative works. AlliedModders LLC defines further
26 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
27 * or <http://www.sourcemod.net/license.php>.
32 #include "extension.h"
33 #include "CallWrapper.h"
34 #include "CallMaker.h"
36 CallWrapper::CallWrapper(const SourceHook::ProtoInfo *protoInfo)
38 m_AddrCodeBase = NULL;
41 unsigned int argnum = protoInfo->numOfParams;
44 m_Info.paramsPassInfo = new SourceHook::PassInfo[argnum + 1];
45 memcpy((void *)m_Info.paramsPassInfo, protoInfo->paramsPassInfo, sizeof(SourceHook::PassInfo) * (argnum+1));
49 m_Params = new PassEncode[argnum];
50 for (size_t i=0; i<argnum; i++)
52 GetSMPassInfo(&(m_Params[i].info), &(m_Info.paramsPassInfo[i+1]));
58 if (m_Info.retPassInfo.size != 0)
60 m_RetParam = new PassInfo;
61 GetSMPassInfo(m_RetParam, &(m_Info.retPassInfo));
66 /* Calculate virtual stack offsets for each parameter */
69 if (m_Info.convention == SourceHook::ProtoInfo::CallConv_ThisCall)
71 offs += sizeof(void *);
73 for (size_t i=0; i<argnum; i++)
75 m_Params[i].offset = offs;
76 offs += m_Params[i].info.size;
80 CallWrapper::~CallWrapper()
84 delete [] m_Info.paramsPassInfo;
87 void CallWrapper::Destroy()
89 if (m_AddrCodeBase != NULL)
91 g_SPEngine->FreePageMemory(m_AddrCodeBase);
92 m_AddrCodeBase = NULL;
98 CallConvention CallWrapper::GetCallConvention()
100 /* Need to convert to a SourceMod convention for bcompat */
101 return GetSMCallConvention((SourceHook::ProtoInfo::CallConvention)m_Info.convention);
104 const PassEncode *CallWrapper::GetParamInfo(unsigned int num)
106 if (num + 1 > GetParamCount())
111 return &m_Params[num];
114 const PassInfo *CallWrapper::GetReturnInfo()
119 unsigned int CallWrapper::GetParamCount()
121 return m_Info.numOfParams;
124 void CallWrapper::Execute(void *vParamStack, void *retBuffer)
126 typedef void (*CALL_EXECUTE)(void *, void *);
127 CALL_EXECUTE fn = (CALL_EXECUTE)GetCodeBaseAddr();
128 fn(vParamStack, retBuffer);
131 void CallWrapper::SetMemFuncInfo(const SourceHook::MemFuncInfo *funcInfo)
133 m_FuncInfo = *funcInfo;
136 SourceHook::MemFuncInfo *CallWrapper::GetMemFuncInfo()
141 void CallWrapper::SetCalleeAddr(void *addr)
146 void CallWrapper::SetCodeBaseAddr(void *addr)
148 m_AddrCodeBase = addr;
151 void *CallWrapper::GetCalleeAddr()
156 void *CallWrapper::GetCodeBaseAddr()
158 return m_AddrCodeBase;
161 const SourceHook::PassInfo *CallWrapper::GetSHReturnInfo()
163 return &(m_Info.retPassInfo);
166 SourceHook::ProtoInfo::CallConvention CallWrapper::GetSHCallConvention()
168 return (SourceHook::ProtoInfo::CallConvention)m_Info.convention;
171 const SourceHook::PassInfo * CallWrapper::GetSHParamInfo(unsigned int num)
173 if (num + 1 > GetParamCount())
178 return &(m_Info.paramsPassInfo[num+1]);
181 unsigned int CallWrapper::GetParamOffset(unsigned int num)
183 assert(num < GetParamCount() && num >= 0);
185 return m_Params[num].offset;