1 #include "vcallbuilder.h"
13 ValveCall::~ValveCall()
17 unsigned char *ptr = stk.front();
29 unsigned char *ValveCall::stk_get()
34 ptr = new unsigned char[stackSize];
42 void ValveCall::stk_put(unsigned char *ptr)
47 ValveCall *CreateValveCall(void *addr,
48 ValveCallType vcalltype,
49 const ValvePassInfo *retInfo,
50 const ValvePassInfo *params,
51 unsigned int numParams)
58 ValveCall *vc = new ValveCall;
63 /* Get return information - encode only */
65 size_t retBufSize = 0;
66 bool retbuf_needs_extra;
69 if ((size = ValveParamToBinParam(retInfo->vtype, retInfo->type, retInfo->flags, &retBuf, retbuf_needs_extra)) == 0)
74 retBufSize = retBuf.size;
75 if (retbuf_needs_extra)
81 /* Get thisinfo if needed */
82 ValvePassInfo thisbuf;
83 ValvePassInfo *thisinfo = NULL;
84 CallConvention cv = CallConv_Cdecl;
85 if (vcalltype != ValveCall_Static)
88 thisinfo->type = PassType_Basic;
89 if (vcalltype == ValveCall_Entity)
91 thisinfo->vtype = Valve_CBaseEntity;
92 thisinfo->decflags |= VDECODE_FLAG_ALLOWWORLD;
93 } else if (vcalltype == ValveCall_Player) {
94 thisinfo->vtype = Valve_CBasePlayer;
95 thisinfo->decflags = 0;
97 thisinfo->encflags = 0;
98 thisinfo->flags = PASSFLAG_BYVAL;
100 vc->stackSize += sizeof(void *);
101 cv = CallConv_ThisCall;
104 /* Get parameter info */
105 PassInfo paramBuf[32];
108 size_t extraSize = 0;
109 for (unsigned int i=0; i<numParams; i++)
112 if ((size = ValveParamToBinParam(params[i].vtype,
127 normSize += paramBuf[i].size;
128 extraSize += sizes[i];
131 /* Now we can try creating the call */
132 if ((vc->call = g_pBinTools->CreateCall(addr,
134 (retInfo ? &retBuf : NULL),
146 /* Allocate extra space for thisptr AND ret buffer, even if we don't use it */
147 vc->vparams = new ValvePassInfo[numParams + 2];
149 /* We've got the call and everything is encoded.
150 * It's time to save the valve specific information and helper variables.
154 /* Allocate and copy */
155 vc->retinfo = &(vc->vparams[numParams]);
156 *vc->retinfo = *retInfo;
157 vc->retinfo->offset = 0;
158 vc->retinfo->obj_offset = retbuf_needs_extra ? sizeof(void *) : 0;
159 /* Allocate stack space */
160 vc->retbuf = new unsigned char[retBufSize];
168 /* Allocate and copy */
169 vc->thisinfo = &(vc->vparams[numParams + 1]);
170 *vc->thisinfo = *thisinfo;
171 vc->thisinfo->offset = 0;
172 vc->thisinfo->obj_offset = 0;
177 /* Now, save info about each parameter. */
178 size_t last_extra_offset = 0;
179 for (unsigned int i=0; i<numParams; i++)
182 vc->vparams[i] = params[i];
183 vc->vparams[i].offset = vc->call->GetParamInfo(i)->offset;
184 vc->vparams[i].obj_offset = last_extra_offset;
185 last_extra_offset += sizes[i];
188 vc->stackSize = normSize + extraSize;
189 vc->stackEnd = normSize;
194 ValveCall *CreateValveVCall(unsigned int vtableIdx,
195 ValveCallType vcalltype,
196 const ValvePassInfo *retInfo,
197 const ValvePassInfo *params,
198 unsigned int numParams)
205 ValveCall *vc = new ValveCall;
210 /* Get return information - encode only */
212 size_t retBufSize = 0;
213 bool retbuf_needs_extra;
216 if ((size = ValveParamToBinParam(retInfo->vtype, retInfo->type, retInfo->flags, &retBuf, retbuf_needs_extra)) == 0)
221 retBufSize = retBuf.size;
222 if (retbuf_needs_extra)
228 /* Get parameter info */
229 PassInfo paramBuf[32];
232 size_t extraSize = 0;
233 for (unsigned int i=0; i<numParams; i++)
236 if ((size = ValveParamToBinParam(params[i].vtype,
251 normSize += paramBuf[i].size;
252 extraSize += sizes[i];
255 /* Now we can try creating the call */
256 if ((vc->call = g_pBinTools->CreateVCall(vtableIdx,
259 (retInfo ? &retBuf : NULL),
271 /* Allocate extra space for thisptr AND ret buffer, even if we don't use it */
272 vc->vparams = new ValvePassInfo[numParams + 2];
274 /* We've got the call and everything is encoded.
275 * It's time to save the valve specific information and helper variables.
279 /* Allocate and copy */
280 vc->retinfo = &(vc->vparams[numParams]);
281 *vc->retinfo = *retInfo;
282 vc->retinfo->offset = 0;
283 vc->retinfo->obj_offset = retbuf_needs_extra ? sizeof(void *) : 0;
284 /* Allocate stack space */
285 vc->retbuf = new unsigned char[retBufSize];
291 /* Save the this info for the dynamic decoder */
292 vc->thisinfo = &(vc->vparams[numParams + 1]);
293 vc->thisinfo->type = PassType_Basic;
294 if (vcalltype == ValveCall_Entity)
296 vc->thisinfo->vtype = Valve_CBaseEntity;
297 vc->thisinfo->decflags = VDECODE_FLAG_ALLOWWORLD;
298 } else if (vcalltype == ValveCall_Player) {
299 vc->thisinfo->vtype = Valve_CBasePlayer;
300 vc->thisinfo->decflags = 0;
302 vc->thisinfo->encflags = 0;
303 vc->thisinfo->flags = PASSFLAG_BYVAL;
304 vc->thisinfo->offset = 0;
305 vc->thisinfo->obj_offset = 0;
306 normSize += sizeof(void *);
308 /* Now, save info about each parameter. */
309 size_t last_extra_offset = 0;
310 for (unsigned int i=0; i<numParams; i++)
313 vc->vparams[i] = params[i];
314 vc->vparams[i].offset = vc->call->GetParamInfo(i)->offset;
315 vc->vparams[i].obj_offset = last_extra_offset;
316 last_extra_offset += sizes[i];
319 vc->stackSize = normSize + extraSize;
320 vc->stackEnd = normSize;