8 void CFunction::Set(funcid_t funcid, CPlugin *plugin)
13 m_errorstate = SP_ERROR_NONE;
16 int CFunction::CallFunction(const cell_t *params, unsigned int num_params, cell_t *result)
18 IPluginContext *ctx = m_pPlugin->m_ctx_current.base;
22 ctx->PushCell(params[num_params]);
25 return ctx->Execute(m_funcid, result);
28 IPlugin *CFunction::GetParentPlugin()
33 CFunction::CFunction(funcid_t funcid, CPlugin *plugin) :
34 m_funcid(funcid), m_pPlugin(plugin), m_curparam(0),
35 m_errorstate(SP_ERROR_NONE)
39 int CFunction::PushCell(cell_t cell)
41 if (m_curparam >= SP_MAX_EXEC_PARAMS)
43 return SetError(SP_ERROR_PARAMS_MAX);
46 m_info[m_curparam].marked = false;
47 m_params[m_curparam] = cell;
53 int CFunction::PushCellByRef(cell_t *cell, int flags)
55 if (m_curparam >= SP_MAX_EXEC_PARAMS)
57 return SetError(SP_ERROR_PARAMS_MAX);
60 return PushArray(cell, 1, NULL, flags);
63 int CFunction::PushFloat(float number)
65 cell_t val = *(cell_t *)&number;
70 int CFunction::PushFloatByRef(float *number, int flags)
72 return PushCellByRef((cell_t *)number, flags);
75 int CFunction::PushArray(cell_t *inarray, unsigned int cells, cell_t **phys_addr, int copyback)
77 if (m_curparam >= SP_MAX_EXEC_PARAMS)
79 return SetError(SP_ERROR_PARAMS_MAX);
82 IPluginContext *ctx = m_pPlugin->m_ctx_current.base;
83 ParamInfo *info = &m_info[m_curparam];
86 if ((err=ctx->HeapAlloc(cells, &info->local_addr, &info->phys_addr)) != SP_ERROR_NONE)
91 info->flags = inarray ? copyback : 0;
94 m_params[m_curparam] = info->local_addr;
99 memcpy(info->phys_addr, inarray, sizeof(cell_t) * cells);
100 info->orig_addr = inarray;
102 info->orig_addr = info->phys_addr;
107 *phys_addr = info->phys_addr;
113 int CFunction::PushString(const char *string)
115 return _PushString(string, 0);
118 int CFunction::PushStringEx(char *string, int flags)
120 return _PushString(string, flags);
123 int CFunction::_PushString(const char *string, int flags)
125 if (m_curparam >= SP_MAX_EXEC_PARAMS)
127 return SetError(SP_ERROR_PARAMS_MAX);
130 IPluginContext *base = m_pPlugin->m_ctx_current.base;
131 ParamInfo *info = &m_info[m_curparam];
132 size_t len = strlen(string);
133 size_t cells = (len + sizeof(cell_t) - 1) / sizeof(cell_t);
136 if ((err=base->HeapAlloc(cells, &info->local_addr, &info->phys_addr)) != SP_ERROR_NONE)
138 return SetError(err);
142 m_params[m_curparam] = info->local_addr;
143 m_curparam++; /* Prevent a leak */
145 if ((err=base->StringToLocalUTF8(info->local_addr, len, string, NULL)) != SP_ERROR_NONE)
147 return SetError(err);
151 info->orig_addr = (cell_t *)string;
154 return SP_ERROR_NONE;
157 void CFunction::Cancel()
164 IPluginContext *base = m_pPlugin->m_ctx_current.base;
168 if (m_info[m_curparam].marked)
170 base->HeapRelease(m_info[m_curparam].local_addr);
171 m_info[m_curparam].marked = false;
175 m_errorstate = SP_ERROR_NONE;
178 int CFunction::Execute(cell_t *result)
181 if (m_errorstate != SP_ERROR_NONE)
188 //This is for re-entrancy!
189 cell_t temp_params[SP_MAX_EXEC_PARAMS];
190 ParamInfo temp_info[SP_MAX_EXEC_PARAMS];
191 unsigned int numparams = m_curparam;
192 bool docopies = true;
196 //Save the info locally, then reset it for re-entrant calls.
197 memcpy(temp_params, m_params, numparams * sizeof(cell_t));
198 memcpy(temp_info, m_info, numparams * sizeof(ParamInfo));
202 if ((err = CallFunction(temp_params, numparams, result)) != SP_ERROR_NONE)
207 IPluginContext *base = m_pPlugin->m_ctx_current.base;
211 if (!temp_info[numparams].marked)
215 if (docopies && temp_info[numparams].flags)
217 if (temp_info[numparams].orig_addr)
219 if (temp_info[numparams].size == 1)
221 *temp_info[numparams].orig_addr = *temp_info[numparams].phys_addr;
223 memcpy(temp_info[numparams].orig_addr,
224 temp_info[numparams].phys_addr,
225 temp_info[numparams].size * sizeof(cell_t));
229 base->HeapPop(temp_info[numparams].local_addr);
230 temp_info[numparams].marked = false;
236 cell_t *CFunction::GetAddressOfPushedParam(unsigned int param)
238 if (m_errorstate != SP_ERROR_NONE
239 || param >= m_curparam
240 || !m_info[param].marked)
245 return m_info[param].phys_addr;