1.1 --- a/core/smn_functions.cpp Fri Mar 28 06:21:34 2008 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,609 +0,0 @@
1.4 -/**
1.5 - * vim: set ts=4 :
1.6 - * =============================================================================
1.7 - * SourceMod
1.8 - * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
1.9 - * =============================================================================
1.10 - *
1.11 - * This program is free software; you can redistribute it and/or modify it under
1.12 - * the terms of the GNU General Public License, version 3.0, as published by the
1.13 - * Free Software Foundation.
1.14 - *
1.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
1.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1.18 - * details.
1.19 - *
1.20 - * You should have received a copy of the GNU General Public License along with
1.21 - * this program. If not, see <http://www.gnu.org/licenses/>.
1.22 - *
1.23 - * As a special exception, AlliedModders LLC gives you permission to link the
1.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
1.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
1.26 - * by the Valve Corporation. You must obey the GNU General Public License in
1.27 - * all respects for all other code used. Additionally, AlliedModders LLC grants
1.28 - * this exception to all derivative works. AlliedModders LLC defines further
1.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
1.30 - * or <http://www.sourcemod.net/license.php>.
1.31 - *
1.32 - * Version: $Id$
1.33 - */
1.34 -
1.35 -#include "sm_globals.h"
1.36 -#include "PluginSys.h"
1.37 -#include "ForwardSys.h"
1.38 -#include "HandleSys.h"
1.39 -
1.40 -HandleType_t g_GlobalFwdType = 0;
1.41 -HandleType_t g_PrivateFwdType = 0;
1.42 -
1.43 -static bool s_CallStarted = false;
1.44 -static ICallable *s_pCallable = NULL;
1.45 -static IPluginFunction *s_pFunction = NULL;
1.46 -static IForward *s_pForward = NULL;
1.47 -
1.48 -class ForwardNativeHelpers :
1.49 - public SMGlobalClass,
1.50 - public IHandleTypeDispatch
1.51 -{
1.52 -public:
1.53 - void OnSourceModAllInitialized()
1.54 - {
1.55 - HandleAccess sec;
1.56 -
1.57 - /* Set GlobalFwd handle access security */
1.58 - g_HandleSys.InitAccessDefaults(NULL, &sec);
1.59 - sec.access[HandleAccess_Read] = 0;
1.60 - sec.access[HandleAccess_Clone] = HANDLE_RESTRICT_IDENTITY | HANDLE_RESTRICT_OWNER;
1.61 -
1.62 - /* Create 'GlobalFwd' handle type */
1.63 - g_GlobalFwdType = g_HandleSys.CreateType("GlobalFwd", this, 0, NULL, &sec, g_pCoreIdent, NULL);
1.64 -
1.65 - /* Private forwards are cloneable */
1.66 - sec.access[HandleAccess_Clone] = 0;
1.67 -
1.68 - /* Create 'PrivateFwd' handle type */
1.69 - g_PrivateFwdType = g_HandleSys.CreateType("PrivateFwd", this, g_GlobalFwdType, NULL, &sec, g_pCoreIdent, NULL);
1.70 - }
1.71 -
1.72 - void OnSourceModShutdown()
1.73 - {
1.74 - g_HandleSys.RemoveType(g_PrivateFwdType, g_pCoreIdent);
1.75 - g_HandleSys.RemoveType(g_GlobalFwdType, g_pCoreIdent);
1.76 - }
1.77 -
1.78 - void OnHandleDestroy(HandleType_t type, void *object)
1.79 - {
1.80 - IForward *pForward = static_cast<IForward *>(object);
1.81 -
1.82 - g_Forwards.ReleaseForward(pForward);
1.83 - }
1.84 -} g_ForwardNativeHelpers;
1.85 -
1.86 -
1.87 -/* Turn a public index into a function ID */
1.88 -inline funcid_t PublicIndexToFuncId(uint32_t idx)
1.89 -{
1.90 - return (idx << 1) | (1 << 0);
1.91 -}
1.92 -
1.93 -/* Reset global function/forward call variables */
1.94 -inline void ResetCall()
1.95 -{
1.96 - s_CallStarted = false;
1.97 - s_pFunction = NULL;
1.98 - s_pForward = NULL;
1.99 - s_pCallable = NULL;
1.100 -}
1.101 -
1.102 -static cell_t sm_GetFunctionByName(IPluginContext *pContext, const cell_t *params)
1.103 -{
1.104 - Handle_t hndl = static_cast<Handle_t>(params[1]);
1.105 - HandleError err;
1.106 - char *name;
1.107 - uint32_t idx;
1.108 - IPlugin *pPlugin;
1.109 -
1.110 - if (hndl == 0)
1.111 - {
1.112 - pPlugin = g_PluginSys.FindPluginByContext(pContext->GetContext());
1.113 - } else {
1.114 - pPlugin = g_PluginSys.PluginFromHandle(hndl, &err);
1.115 -
1.116 - if (!pPlugin)
1.117 - {
1.118 - return pContext->ThrowNativeError("Plugin handle %x is invalid (error %d)", hndl, err);
1.119 - }
1.120 - }
1.121 -
1.122 - pContext->LocalToString(params[2], &name);
1.123 -
1.124 - /* Get public function index */
1.125 - if (pPlugin->GetBaseContext()->FindPublicByName(name, &idx) == SP_ERROR_NOT_FOUND)
1.126 - {
1.127 - /* Return INVALID_FUNCTION if not found */
1.128 - return -1;
1.129 - }
1.130 -
1.131 - /* Return function ID */
1.132 - return PublicIndexToFuncId(idx);
1.133 -}
1.134 -
1.135 -static cell_t sm_CreateGlobalForward(IPluginContext *pContext, const cell_t *params)
1.136 -{
1.137 - cell_t count = params[0];
1.138 - char *name;
1.139 - ParamType forwardParams[SP_MAX_EXEC_PARAMS];
1.140 -
1.141 - if (count - 2 > SP_MAX_EXEC_PARAMS)
1.142 - {
1.143 - return pContext->ThrowNativeErrorEx(SP_ERROR_PARAMS_MAX, NULL);
1.144 - }
1.145 -
1.146 - pContext->LocalToString(params[1], &name);
1.147 -
1.148 - cell_t *addr;
1.149 - for (int i = 3; i <= count; i++)
1.150 - {
1.151 - pContext->LocalToPhysAddr(params[i], &addr);
1.152 - forwardParams[i - 3] = static_cast<ParamType>(*addr);
1.153 - }
1.154 -
1.155 - IForward *pForward = g_Forwards.CreateForward(name, static_cast<ExecType>(params[2]), count - 2, forwardParams);
1.156 -
1.157 - return g_HandleSys.CreateHandle(g_GlobalFwdType, pForward, pContext->GetIdentity(), g_pCoreIdent, NULL);
1.158 -}
1.159 -
1.160 -static cell_t sm_CreateForward(IPluginContext *pContext, const cell_t *params)
1.161 -{
1.162 - cell_t count = params[0];
1.163 - ParamType forwardParams[SP_MAX_EXEC_PARAMS];
1.164 -
1.165 - if (count - 1 > SP_MAX_EXEC_PARAMS)
1.166 - {
1.167 - return pContext->ThrowNativeErrorEx(SP_ERROR_PARAMS_MAX, NULL);
1.168 - }
1.169 -
1.170 - cell_t *addr;
1.171 - for (int i = 2; i <= count; i++)
1.172 - {
1.173 - pContext->LocalToPhysAddr(params[i], &addr);
1.174 - forwardParams[i - 2] = static_cast<ParamType>(*addr);
1.175 - }
1.176 -
1.177 - IChangeableForward *pForward = g_Forwards.CreateForwardEx(NULL, static_cast<ExecType>(params[1]), count - 1, forwardParams);
1.178 -
1.179 - return g_HandleSys.CreateHandle(g_PrivateFwdType, pForward, pContext->GetIdentity(), g_pCoreIdent, NULL);
1.180 -}
1.181 -
1.182 -static cell_t sm_GetForwardFunctionCount(IPluginContext *pContext, const cell_t *params)
1.183 -{
1.184 - Handle_t hndl = static_cast<Handle_t>(params[1]);
1.185 - HandleError err;
1.186 - IForward *pForward;
1.187 -
1.188 - if ((err=g_HandleSys.ReadHandle(hndl, g_GlobalFwdType, NULL, (void **)&pForward))
1.189 - != HandleError_None)
1.190 - {
1.191 - return pContext->ThrowNativeError("Invalid forward handle %x (error %d)", hndl, err);
1.192 - }
1.193 -
1.194 - return pForward->GetFunctionCount();
1.195 -}
1.196 -
1.197 -static cell_t sm_AddToForward(IPluginContext *pContext, const cell_t *params)
1.198 -{
1.199 - Handle_t fwdHandle = static_cast<Handle_t>(params[1]);
1.200 - Handle_t plHandle = static_cast<Handle_t>(params[2]);
1.201 - HandleError err;
1.202 - IChangeableForward *pForward;
1.203 - IPlugin *pPlugin;
1.204 -
1.205 - if ((err=g_HandleSys.ReadHandle(fwdHandle, g_PrivateFwdType, NULL, (void **)&pForward))
1.206 - != HandleError_None)
1.207 - {
1.208 - return pContext->ThrowNativeError("Invalid private forward handle %x (error %d)", fwdHandle, err);
1.209 - }
1.210 -
1.211 - if (plHandle == 0)
1.212 - {
1.213 - pPlugin = g_PluginSys.FindPluginByContext(pContext->GetContext());
1.214 - } else {
1.215 - pPlugin = g_PluginSys.PluginFromHandle(plHandle, &err);
1.216 -
1.217 - if (!pPlugin)
1.218 - {
1.219 - return pContext->ThrowNativeError("Plugin handle %x is invalid (error %d)", plHandle, err);
1.220 - }
1.221 - }
1.222 -
1.223 - IPluginFunction *pFunction = pPlugin->GetBaseContext()->GetFunctionById(params[3]);
1.224 -
1.225 - if (!pFunction)
1.226 - {
1.227 - return pContext->ThrowNativeError("Invalid function id (%X)", params[3]);
1.228 - }
1.229 -
1.230 - return pForward->AddFunction(pFunction);
1.231 -}
1.232 -
1.233 -static cell_t sm_RemoveFromForward(IPluginContext *pContext, const cell_t *params)
1.234 -{
1.235 - Handle_t fwdHandle = static_cast<Handle_t>(params[1]);
1.236 - Handle_t plHandle = static_cast<Handle_t>(params[2]);
1.237 - HandleError err;
1.238 - IChangeableForward *pForward;
1.239 - IPlugin *pPlugin;
1.240 -
1.241 - if ((err=g_HandleSys.ReadHandle(fwdHandle, g_PrivateFwdType, NULL, (void **)&pForward))
1.242 - != HandleError_None)
1.243 - {
1.244 - return pContext->ThrowNativeError("Invalid private forward handle %x (error %d)", fwdHandle, err);
1.245 - }
1.246 -
1.247 - if (plHandle == 0)
1.248 - {
1.249 - pPlugin = g_PluginSys.FindPluginByContext(pContext->GetContext());
1.250 - } else {
1.251 - pPlugin = g_PluginSys.PluginFromHandle(plHandle, &err);
1.252 -
1.253 - if (!pPlugin)
1.254 - {
1.255 - return pContext->ThrowNativeError("Plugin handle %x is invalid (error %d)", plHandle, err);
1.256 - }
1.257 - }
1.258 -
1.259 - IPluginFunction *pFunction = pPlugin->GetBaseContext()->GetFunctionById(params[3]);
1.260 -
1.261 - if (!pFunction)
1.262 - {
1.263 - return pContext->ThrowNativeError("Invalid function id (%X)", params[3]);
1.264 - }
1.265 -
1.266 - return pForward->RemoveFunction(pFunction);
1.267 -}
1.268 -
1.269 -static cell_t sm_RemoveAllFromForward(IPluginContext *pContext, const cell_t *params)
1.270 -{
1.271 - Handle_t fwdHandle = static_cast<Handle_t>(params[1]);
1.272 - Handle_t plHandle = static_cast<Handle_t>(params[2]);
1.273 - HandleError err;
1.274 - IChangeableForward *pForward;
1.275 - IPlugin *pPlugin;
1.276 -
1.277 - if ((err=g_HandleSys.ReadHandle(fwdHandle, g_PrivateFwdType, NULL, (void **)&pForward))
1.278 - != HandleError_None)
1.279 - {
1.280 - return pContext->ThrowNativeError("Invalid private forward handle %x (error %d)", fwdHandle, err);
1.281 - }
1.282 -
1.283 - if (plHandle == 0)
1.284 - {
1.285 - pPlugin = g_PluginSys.FindPluginByContext(pContext->GetContext());
1.286 - } else {
1.287 - pPlugin = g_PluginSys.PluginFromHandle(plHandle, &err);
1.288 -
1.289 - if (!pPlugin)
1.290 - {
1.291 - return pContext->ThrowNativeError("Plugin handle %x is invalid (error %d)", plHandle, err);
1.292 - }
1.293 - }
1.294 -
1.295 - return pForward->RemoveFunctionsOfPlugin(pPlugin);
1.296 -}
1.297 -
1.298 -static cell_t sm_CallStartFunction(IPluginContext *pContext, const cell_t *params)
1.299 -{
1.300 - Handle_t hndl;
1.301 - HandleError err;
1.302 - IPlugin *pPlugin;
1.303 -
1.304 - if (s_CallStarted)
1.305 - {
1.306 - return pContext->ThrowNativeError("Cannot start a call while one is already in progress");
1.307 - }
1.308 -
1.309 - hndl = static_cast<Handle_t>(params[1]);
1.310 -
1.311 - if (hndl == 0)
1.312 - {
1.313 - pPlugin = g_PluginSys.FindPluginByContext(pContext->GetContext());
1.314 - } else {
1.315 - pPlugin = g_PluginSys.PluginFromHandle(hndl, &err);
1.316 -
1.317 - if (!pPlugin)
1.318 - {
1.319 - return pContext->ThrowNativeError("Plugin handle %x is invalid (error %d)", hndl, err);
1.320 - }
1.321 - }
1.322 -
1.323 - s_pFunction = pPlugin->GetBaseContext()->GetFunctionById(params[2]);
1.324 -
1.325 - if (!s_pFunction)
1.326 - {
1.327 - return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
1.328 - }
1.329 -
1.330 - s_pCallable = static_cast<ICallable *>(s_pFunction);
1.331 -
1.332 - s_CallStarted = true;
1.333 -
1.334 - return 1;
1.335 -}
1.336 -
1.337 -static cell_t sm_CallStartForward(IPluginContext *pContext, const cell_t *params)
1.338 -{
1.339 - Handle_t hndl;
1.340 - HandleError err;
1.341 - IForward *pForward;
1.342 -
1.343 - if (s_CallStarted)
1.344 - {
1.345 - return pContext->ThrowNativeError("Cannot start a call while one is already in progress");
1.346 - }
1.347 -
1.348 - hndl = static_cast<Handle_t>(params[1]);
1.349 -
1.350 - if ((err=g_HandleSys.ReadHandle(hndl, g_GlobalFwdType, NULL, (void **)&pForward))
1.351 - != HandleError_None)
1.352 - {
1.353 - return pContext->ThrowNativeError("Invalid forward handle %x (error %d)", hndl, err);
1.354 - }
1.355 -
1.356 - s_pForward = pForward;
1.357 -
1.358 - s_pCallable = static_cast<ICallable *>(pForward);
1.359 -
1.360 - s_CallStarted = true;
1.361 -
1.362 - return 1;
1.363 -}
1.364 -
1.365 -static cell_t sm_CallPushCell(IPluginContext *pContext, const cell_t *params)
1.366 -{
1.367 - int err;
1.368 -
1.369 - if (!s_CallStarted)
1.370 - {
1.371 - return pContext->ThrowNativeError("Cannot push parameters when there is no call in progress");
1.372 - }
1.373 -
1.374 - err = s_pCallable->PushCell(params[1]);
1.375 -
1.376 - if (err)
1.377 - {
1.378 - s_pCallable->Cancel();
1.379 - ResetCall();
1.380 - return pContext->ThrowNativeErrorEx(err, NULL);
1.381 - }
1.382 -
1.383 - return 1;
1.384 -}
1.385 -
1.386 -static cell_t sm_CallPushCellRef(IPluginContext *pContext, const cell_t *params)
1.387 -{
1.388 - int err;
1.389 - cell_t *addr;
1.390 -
1.391 - if (!s_CallStarted)
1.392 - {
1.393 - return pContext->ThrowNativeError("Cannot push parameters when there is no call in progress");
1.394 - }
1.395 -
1.396 - pContext->LocalToPhysAddr(params[1], &addr);
1.397 -
1.398 - err = s_pCallable->PushCellByRef(addr);
1.399 -
1.400 - if (err)
1.401 - {
1.402 - s_pCallable->Cancel();
1.403 - ResetCall();
1.404 - return pContext->ThrowNativeErrorEx(err, NULL);
1.405 - }
1.406 -
1.407 - return 1;
1.408 -}
1.409 -
1.410 -static cell_t sm_CallPushFloat(IPluginContext *pContext, const cell_t *params)
1.411 -{
1.412 - int err;
1.413 -
1.414 - if (!s_CallStarted)
1.415 - {
1.416 - return pContext->ThrowNativeError("Cannot push parameters when there is no call in progress");
1.417 - }
1.418 -
1.419 - err = s_pCallable->PushFloat(sp_ctof(params[1]));
1.420 -
1.421 - if (err)
1.422 - {
1.423 - s_pCallable->Cancel();
1.424 - ResetCall();
1.425 - return pContext->ThrowNativeErrorEx(err, NULL);
1.426 - }
1.427 -
1.428 - return 1;
1.429 -}
1.430 -
1.431 -static cell_t sm_CallPushFloatRef(IPluginContext *pContext, const cell_t *params)
1.432 -{
1.433 - int err;
1.434 - cell_t *addr;
1.435 -
1.436 - if (!s_CallStarted)
1.437 - {
1.438 - return pContext->ThrowNativeError("Cannot push parameters when there is no call in progress");
1.439 - }
1.440 -
1.441 - pContext->LocalToPhysAddr(params[1], &addr);
1.442 -
1.443 - err = s_pCallable->PushFloatByRef(reinterpret_cast<float *>(addr));
1.444 -
1.445 - if (err)
1.446 - {
1.447 - s_pCallable->Cancel();
1.448 - ResetCall();
1.449 - return pContext->ThrowNativeErrorEx(err, NULL);
1.450 - }
1.451 -
1.452 - return 1;
1.453 -}
1.454 -
1.455 -static cell_t sm_CallPushArray(IPluginContext *pContext, const cell_t *params)
1.456 -{
1.457 - int err;
1.458 - cell_t *addr;
1.459 -
1.460 - if (!s_CallStarted)
1.461 - {
1.462 - return pContext->ThrowNativeError("Cannot push parameters when there is no call in progress");
1.463 - }
1.464 -
1.465 - pContext->LocalToPhysAddr(params[1], &addr);
1.466 -
1.467 - err = s_pCallable->PushArray(addr, params[2]);
1.468 -
1.469 - if (err)
1.470 - {
1.471 - s_pCallable->Cancel();
1.472 - ResetCall();
1.473 - return pContext->ThrowNativeErrorEx(err, NULL);
1.474 - }
1.475 -
1.476 - return 1;
1.477 -}
1.478 -
1.479 -static cell_t sm_CallPushArrayEx(IPluginContext *pContext, const cell_t *params)
1.480 -{
1.481 - int err;
1.482 - cell_t *addr;
1.483 -
1.484 - if (!s_CallStarted)
1.485 - {
1.486 - return pContext->ThrowNativeError("Cannot push parameters when there is no call in progress");
1.487 - }
1.488 -
1.489 - pContext->LocalToPhysAddr(params[1], &addr);
1.490 -
1.491 - err = s_pCallable->PushArray(addr, params[2], params[3]);
1.492 -
1.493 - if (err)
1.494 - {
1.495 - s_pCallable->Cancel();
1.496 - ResetCall();
1.497 - return pContext->ThrowNativeErrorEx(err, NULL);
1.498 - }
1.499 -
1.500 - return 1;
1.501 -}
1.502 -
1.503 -static cell_t sm_CallPushString(IPluginContext *pContext, const cell_t *params)
1.504 -{
1.505 - int err;
1.506 - char *value;
1.507 -
1.508 - if (!s_CallStarted)
1.509 - {
1.510 - return pContext->ThrowNativeError("Cannot push parameters when there is no call in progress");
1.511 - }
1.512 -
1.513 - pContext->LocalToString(params[1], &value);
1.514 -
1.515 - err = s_pCallable->PushString(value);
1.516 -
1.517 - if (err)
1.518 - {
1.519 - s_pCallable->Cancel();
1.520 - ResetCall();
1.521 - return pContext->ThrowNativeErrorEx(err, NULL);
1.522 - }
1.523 -
1.524 - return 1;
1.525 -}
1.526 -
1.527 -static cell_t sm_CallPushStringEx(IPluginContext *pContext, const cell_t *params)
1.528 -{
1.529 - int err;
1.530 - char *value;
1.531 -
1.532 - if (!s_CallStarted)
1.533 - {
1.534 - return pContext->ThrowNativeError("Cannot push parameters when there is no call in progress");
1.535 - }
1.536 -
1.537 - pContext->LocalToString(params[1], &value);
1.538 -
1.539 - err = s_pCallable->PushStringEx(value, params[2], params[3], params[4]);
1.540 -
1.541 - if (err)
1.542 - {
1.543 - s_pCallable->Cancel();
1.544 - ResetCall();
1.545 - return pContext->ThrowNativeErrorEx(err, NULL);
1.546 - }
1.547 -
1.548 - return 1;
1.549 -}
1.550 -
1.551 -static cell_t sm_CallFinish(IPluginContext *pContext, const cell_t *params)
1.552 -{
1.553 - int err = SP_ERROR_NOT_RUNNABLE;
1.554 - cell_t *result;
1.555 -
1.556 - if (!s_CallStarted)
1.557 - {
1.558 - return pContext->ThrowNativeError("Cannot finish call when there is no call in progress");
1.559 - }
1.560 -
1.561 - pContext->LocalToPhysAddr(params[1], &result);
1.562 -
1.563 - if (s_pFunction)
1.564 - {
1.565 - IPluginFunction *pFunction = s_pFunction;
1.566 - ResetCall();
1.567 - err = pFunction->Execute(result);
1.568 - } else if (s_pForward) {
1.569 - IForward *pForward = s_pForward;
1.570 - ResetCall();
1.571 - err = pForward->Execute(result, NULL);
1.572 - }
1.573 -
1.574 - return err;
1.575 -}
1.576 -
1.577 -static cell_t sm_CallCancel(IPluginContext *pContext, const cell_t *params)
1.578 -{
1.579 - if (!s_CallStarted)
1.580 - {
1.581 - return pContext->ThrowNativeError("Cannot cancel call when there is no call in progress");
1.582 - }
1.583 -
1.584 - s_pCallable->Cancel();
1.585 - ResetCall();
1.586 -
1.587 - return 1;
1.588 -}
1.589 -
1.590 -REGISTER_NATIVES(functionNatives)
1.591 -{
1.592 - {"GetFunctionByName", sm_GetFunctionByName},
1.593 - {"CreateGlobalForward", sm_CreateGlobalForward},
1.594 - {"CreateForward", sm_CreateForward},
1.595 - {"GetForwardFunctionCount", sm_GetForwardFunctionCount},
1.596 - {"AddToForward", sm_AddToForward},
1.597 - {"RemoveFromForward", sm_RemoveFromForward},
1.598 - {"RemoveAllFromForward", sm_RemoveAllFromForward},
1.599 - {"Call_StartFunction", sm_CallStartFunction},
1.600 - {"Call_StartForward", sm_CallStartForward},
1.601 - {"Call_PushCell", sm_CallPushCell},
1.602 - {"Call_PushCellRef", sm_CallPushCellRef},
1.603 - {"Call_PushFloat", sm_CallPushFloat},
1.604 - {"Call_PushFloatRef", sm_CallPushFloatRef},
1.605 - {"Call_PushArray", sm_CallPushArray},
1.606 - {"Call_PushArrayEx", sm_CallPushArrayEx},
1.607 - {"Call_PushString", sm_CallPushString},
1.608 - {"Call_PushStringEx", sm_CallPushStringEx},
1.609 - {"Call_Finish", sm_CallFinish},
1.610 - {"Call_Cancel", sm_CallCancel},
1.611 - {NULL, NULL},
1.612 -};