1.1 --- a/core/vm/sp_vm_function.cpp Sat Mar 10 13:36:38 2007 +0000
1.2 +++ b/core/vm/sp_vm_function.cpp Sat Mar 10 21:02:40 2007 +0000
1.3 @@ -86,7 +86,7 @@
1.4 return SetError(SP_ERROR_PARAMS_MAX);
1.5 }
1.6
1.7 - return PushArray(cell, 1, NULL, flags);
1.8 + return PushArray(cell, 1, flags);
1.9 }
1.10
1.11 int CFunction::PushFloat(float number)
1.12 @@ -101,7 +101,7 @@
1.13 return PushCellByRef((cell_t *)number, flags);
1.14 }
1.15
1.16 -int CFunction::PushArray(cell_t *inarray, unsigned int cells, cell_t **phys_addr, int copyback)
1.17 +int CFunction::PushArray(cell_t *inarray, unsigned int cells, int copyback)
1.18 {
1.19 if (m_curparam >= SP_MAX_EXEC_PARAMS)
1.20 {
1.21 @@ -109,31 +109,14 @@
1.22 }
1.23
1.24 ParamInfo *info = &m_info[m_curparam];
1.25 - int err;
1.26 -
1.27 - if ((err=m_pContext->HeapAlloc(cells, &info->local_addr, &info->phys_addr)) != SP_ERROR_NONE)
1.28 - {
1.29 - return SetError(err);
1.30 - }
1.31
1.32 info->flags = inarray ? copyback : 0;
1.33 info->marked = true;
1.34 - info->size = cells * sizeof(cell_t);
1.35 - m_params[m_curparam] = info->local_addr;
1.36 - m_curparam++;
1.37 + info->size = cells;
1.38 + info->str.is_sz = false;
1.39 + info->orig_addr = inarray;
1.40
1.41 - if (inarray)
1.42 - {
1.43 - memcpy(info->phys_addr, inarray, sizeof(cell_t) * cells);
1.44 - info->orig_addr = inarray;
1.45 - } else {
1.46 - info->orig_addr = info->phys_addr;
1.47 - }
1.48 -
1.49 - if (phys_addr)
1.50 - {
1.51 - *phys_addr = info->phys_addr;
1.52 - }
1.53 + m_curparam++;
1.54
1.55 return SP_ERROR_NONE;
1.56 }
1.57 @@ -157,39 +140,15 @@
1.58
1.59 ParamInfo *info = &m_info[m_curparam];
1.60 size_t cells = (len + sizeof(cell_t) - 1) / sizeof(cell_t);
1.61 - int err;
1.62 -
1.63 - if ((err=m_pContext->HeapAlloc(cells, &info->local_addr, &info->phys_addr)) != SP_ERROR_NONE)
1.64 - {
1.65 - return SetError(err);
1.66 - }
1.67
1.68 info->marked = true;
1.69 - m_params[m_curparam] = info->local_addr;
1.70 - m_curparam++; /* Prevent a leak */
1.71 -
1.72 - if (!(sz_flags & SM_PARAM_STRING_COPY))
1.73 - {
1.74 - goto skip_localtostr;
1.75 - }
1.76 + info->orig_addr = (cell_t *)string;
1.77 + info->flags = cp_flags;
1.78 + info->size = len;
1.79 + info->str.sz_flags = sz_flags;
1.80 + info->str.is_sz = true;
1.81
1.82 - if (sz_flags & SM_PARAM_STRING_UTF8)
1.83 - {
1.84 - if ((err=m_pContext->StringToLocalUTF8(info->local_addr, len, string, NULL)) != SP_ERROR_NONE)
1.85 - {
1.86 - return SetError(err);
1.87 - }
1.88 - } else {
1.89 - if ((err=m_pContext->StringToLocal(info->local_addr, len, string)) != SP_ERROR_NONE)
1.90 - {
1.91 - return SetError(err);
1.92 - }
1.93 - }
1.94 -
1.95 -skip_localtostr:
1.96 - info->flags = cp_flags;
1.97 - info->orig_addr = (cell_t *)string;
1.98 - info->size = len;
1.99 + m_curparam++;
1.100
1.101 return SP_ERROR_NONE;
1.102 }
1.103 @@ -201,21 +160,13 @@
1.104 return;
1.105 }
1.106
1.107 - while (m_curparam--)
1.108 - {
1.109 - if (m_info[m_curparam].marked)
1.110 - {
1.111 - m_pContext->HeapRelease(m_info[m_curparam].local_addr);
1.112 - m_info[m_curparam].marked = false;
1.113 - }
1.114 - }
1.115 -
1.116 m_errorstate = SP_ERROR_NONE;
1.117 + m_curparam = 0;
1.118 }
1.119
1.120 int CFunction::Execute(cell_t *result)
1.121 {
1.122 - int err;
1.123 + int err = SP_ERROR_NONE;
1.124 if (!IsRunnable())
1.125 {
1.126 m_errorstate = SP_ERROR_NOT_RUNNABLE;
1.127 @@ -231,56 +182,122 @@
1.128 cell_t temp_params[SP_MAX_EXEC_PARAMS];
1.129 ParamInfo temp_info[SP_MAX_EXEC_PARAMS];
1.130 unsigned int numparams = m_curparam;
1.131 + unsigned int i;
1.132 bool docopies = true;
1.133
1.134 if (numparams)
1.135 {
1.136 //Save the info locally, then reset it for re-entrant calls.
1.137 - memcpy(temp_params, m_params, numparams * sizeof(cell_t));
1.138 memcpy(temp_info, m_info, numparams * sizeof(ParamInfo));
1.139 }
1.140 m_curparam = 0;
1.141
1.142 - if ((err = CallFunction(temp_params, numparams, result)) != SP_ERROR_NONE)
1.143 + /* Browse the parameters and build arrays */
1.144 + for (i=0; i<numparams; i++)
1.145 {
1.146 + /* Is this marked as an array? */
1.147 + if (temp_info[i].marked)
1.148 + {
1.149 + if (!temp_info[i].str.is_sz)
1.150 + {
1.151 + /* Allocate a normal/generic array */
1.152 + if ((err=m_pContext->HeapAlloc(temp_info[i].size,
1.153 + &(temp_info[i].local_addr),
1.154 + &(temp_info[i].phys_addr)))
1.155 + != SP_ERROR_NONE)
1.156 + {
1.157 + break;
1.158 + }
1.159 + if (temp_info[i].orig_addr)
1.160 + {
1.161 + memcpy(temp_info[i].phys_addr, temp_info[i].orig_addr, sizeof(cell_t) * temp_info[i].size);
1.162 + }
1.163 + } else {
1.164 + /* Calculate cells required for the string */
1.165 + size_t cells = (temp_info[i].size + sizeof(cell_t) - 1) / sizeof(cell_t);
1.166 +
1.167 + /* Allocate the buffer */
1.168 + if ((err=m_pContext->HeapAlloc(cells,
1.169 + &(temp_info[i].local_addr),
1.170 + &(temp_info[i].phys_addr)))
1.171 + != SP_ERROR_NONE)
1.172 + {
1.173 + break;
1.174 + }
1.175 + /* Copy original string if necessary */
1.176 + if ((temp_info[i].str.sz_flags & SM_PARAM_STRING_COPY) && (temp_info[i].orig_addr != NULL))
1.177 + {
1.178 + if (temp_info[i].str.sz_flags & SM_PARAM_STRING_UTF8)
1.179 + {
1.180 + if ((err=m_pContext->StringToLocalUTF8(temp_info[i].local_addr,
1.181 + temp_info[i].size,
1.182 + (const char *)temp_info[i].orig_addr,
1.183 + NULL))
1.184 + != SP_ERROR_NONE)
1.185 + {
1.186 + break;
1.187 + }
1.188 + } else {
1.189 + if ((err=m_pContext->StringToLocal(temp_info[i].local_addr,
1.190 + temp_info[i].size,
1.191 + (const char *)temp_info[i].orig_addr))
1.192 + != SP_ERROR_NONE)
1.193 + {
1.194 + break;
1.195 + }
1.196 + }
1.197 + }
1.198 + } /* End array/string calculation */
1.199 + /* Update the pushed parameter with the byref local address */
1.200 + temp_params[i] = temp_info[i].local_addr;
1.201 + } else {
1.202 + /* Just copy the value normally */
1.203 + temp_params[i] = m_params[i];
1.204 + }
1.205 + }
1.206 +
1.207 + /* Make the call if we can */
1.208 + if (err == SP_ERROR_NONE)
1.209 + {
1.210 + if ((err = CallFunction(temp_params, numparams, result)) != SP_ERROR_NONE)
1.211 + {
1.212 + docopies = false;
1.213 + }
1.214 + } else {
1.215 docopies = false;
1.216 }
1.217
1.218 - while (numparams--)
1.219 + /* i should be equal to the last valid parameter + 1 */
1.220 + while (i--)
1.221 {
1.222 - if (!temp_info[numparams].marked)
1.223 + if (!temp_info[i].marked)
1.224 {
1.225 continue;
1.226 }
1.227 - if (docopies && temp_info[numparams].flags)
1.228 + if (docopies && (temp_info[i].flags & SM_PARAM_COPYBACK))
1.229 {
1.230 - if (temp_info[numparams].orig_addr)
1.231 + if (temp_info[i].orig_addr)
1.232 {
1.233 - if (temp_info[numparams].size == sizeof(cell_t))
1.234 + if (temp_info[i].str.is_sz)
1.235 {
1.236 - *temp_info[numparams].orig_addr = *temp_info[numparams].phys_addr;
1.237 + memcpy(temp_info[i].orig_addr, temp_info[i].phys_addr, temp_info[i].size);
1.238 } else {
1.239 - memcpy(temp_info[numparams].orig_addr,
1.240 - temp_info[numparams].phys_addr,
1.241 - temp_info[numparams].size);
1.242 + if (temp_info[i].size == 1)
1.243 + {
1.244 + *temp_info[i].orig_addr = *(temp_info[i].phys_addr);
1.245 + } else {
1.246 + memcpy(temp_info[i].orig_addr,
1.247 + temp_info[i].phys_addr,
1.248 + temp_info[i].size * sizeof(cell_t));
1.249 + }
1.250 }
1.251 }
1.252 }
1.253 - m_pContext->HeapPop(temp_info[numparams].local_addr);
1.254 - temp_info[numparams].marked = false;
1.255 + if ((err=m_pContext->HeapPop(temp_info[i].local_addr)) != SP_ERROR_NONE)
1.256 + {
1.257 + return err;
1.258 + }
1.259 }
1.260
1.261 return err;
1.262 }
1.263 -
1.264 -cell_t *CFunction::GetAddressOfPushedParam(unsigned int param)
1.265 -{
1.266 - if (m_errorstate != SP_ERROR_NONE
1.267 - || param >= m_curparam
1.268 - || !m_info[param].marked)
1.269 - {
1.270 - return NULL;
1.271 - }
1.272 -
1.273 - return m_info[param].phys_addr;
1.274 -}