diff -r 4edce76aefe3 -r 4c93f74cae51 core/NativeInvoker.cpp
--- a/core/NativeInvoker.cpp Fri Mar 29 12:28:02 2013 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,379 +0,0 @@
-/**
- * vim: set ts=4 :
- * =============================================================================
- * SourcePawn
- * Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
- * =============================================================================
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, version 3.0, as published by the
- * Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program. If not, see .
- *
- * As a special exception, AlliedModders LLC gives you permission to link the
- * code of this program (as well as its derivative works) to "Half-Life 2," the
- * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
- * by the Valve Corporation. You must obey the GNU General Public License in
- * all respects for all other code used. Additionally, AlliedModders LLC grants
- * this exception to all derivative works. AlliedModders LLC defines further
- * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
- * or .
- *
- * Version: $Id$
- */
-
-#include "NativeInvoker.h"
-#include "ShareSys.h"
-
-NativeInterface g_NInvoke;
-
-NativeInvoker::NativeInvoker()
-{
-}
-
-NativeInvoker::~NativeInvoker()
-{
-}
-
-const char *NativeInterface::GetInterfaceName()
-{
- return SMINTERFACE_NINVOKE_NAME;
-}
-
-unsigned int NativeInterface::GetInterfaceVersion()
-{
- return SMINTERFACE_NINVOKE_VERSION;
-}
-
-void NativeInterface::OnSourceModAllInitialized()
-{
- g_ShareSys.AddInterface(NULL, &g_NInvoke);
-}
-
-IPluginRuntime *NativeInterface::CreateRuntime(const char *name, size_t bytes)
-{
- return g_pSourcePawn2->CreateEmptyRuntime(name, bytes);
-}
-
-INativeInvoker *NativeInterface::CreateInvoker()
-{
- return new NativeInvoker();
-}
-
-bool NativeInvoker::Start(IPluginContext *pContext, const char *name)
-{
- NativeEntry *entry;
-
- entry = g_ShareSys.FindNative(name);
- if (entry == NULL)
- {
- return false;
- }
-
- native = NULL;
- if (entry->replacement.owner != NULL)
- {
- native = entry->replacement.func;
- }
- else if (entry->owner != NULL)
- {
- native = entry->func;
- }
-
- if (native == NULL)
- {
- return false;
- }
-
- this->pContext = pContext;
-
- m_curparam = 0;
- m_errorstate = SP_ERROR_NONE;
-
- return true;
-}
-
-cell_t NativeInvoker::PushCell(cell_t cell)
-{
- if (m_curparam >= SP_MAX_EXEC_PARAMS)
- {
- return SetError(SP_ERROR_PARAMS_MAX);
- }
-
- m_info[m_curparam].marked = false;
- m_params[m_curparam] = cell;
- m_curparam++;
-
- return SP_ERROR_NONE;
-}
-
-int NativeInvoker::PushCellByRef(cell_t *cell, int flags)
-{
- return PushArray(cell, 1, flags);
-}
-
-int NativeInvoker::PushFloat(float number)
-{
- cell_t val = *(cell_t *)&number;
-
- return PushCell(val);
-}
-
-int NativeInvoker::PushFloatByRef(float *number, int flags)
-{
- return PushCellByRef((cell_t *)number, flags);
-}
-
-int NativeInvoker::PushArray(cell_t *inarray, unsigned int cells, int copyback)
-{
- if (m_curparam >= SP_MAX_EXEC_PARAMS)
- {
- return SetError(SP_ERROR_PARAMS_MAX);
- }
-
- ParamInfo *info = &m_info[m_curparam];
-
- info->flags = inarray ? copyback : 0;
- info->marked = true;
- info->size = cells;
- info->str.is_sz = false;
- info->orig_addr = inarray;
-
- m_curparam++;
-
- return SP_ERROR_NONE;
-}
-
-int NativeInvoker::PushString(const char *string)
-{
- return _PushString(string, SM_PARAM_STRING_COPY, 0, strlen(string)+1);
-}
-
-int NativeInvoker::PushStringEx(char *buffer, size_t length, int sz_flags, int cp_flags)
-{
- return _PushString(buffer, sz_flags, cp_flags, length);
-}
-
-int NativeInvoker::_PushString(const char *string, int sz_flags, int cp_flags, size_t len)
-{
- if (m_curparam >= SP_MAX_EXEC_PARAMS)
- {
- return SetError(SP_ERROR_PARAMS_MAX);
- }
-
- ParamInfo *info = &m_info[m_curparam];
-
- info->marked = true;
- info->orig_addr = (cell_t *)string;
- info->flags = cp_flags;
- info->size = len;
- info->str.sz_flags = sz_flags;
- info->str.is_sz = true;
-
- m_curparam++;
-
- return SP_ERROR_NONE;
-}
-
-void NativeInvoker::Cancel()
-{
- if (pContext == NULL)
- {
- return;
- }
-
- m_errorstate = SP_ERROR_NONE;
- m_curparam = 0;
- pContext = NULL;
- native = NULL;
-}
-
-int NativeInvoker::SetError(int err)
-{
- m_errorstate = err;
- return err;
-}
-
-int NativeInvoker::Invoke(cell_t *result)
-{
- int err = SP_ERROR_NONE;
-
- if (pContext == NULL)
- {
- return SP_ERROR_INVALID_NATIVE;
- }
-
- if (m_errorstate != SP_ERROR_NONE)
- {
- err = m_errorstate;
- Cancel();
- return err;
- }
-
- cell_t tresult;
-
- if (result == NULL)
- {
- result = &tresult;
- }
-
- //This is for re-entrancy!
- IPluginContext *ctx = pContext;
- cell_t _temp_params[SP_MAX_EXEC_PARAMS + 1];
- cell_t *temp_params = &_temp_params[1];
- ParamInfo temp_info[SP_MAX_EXEC_PARAMS];
- unsigned int numparams = m_curparam;
- unsigned int i;
- bool docopies = true;
-
- if (numparams)
- {
- //Save the info locally, then reset it for re-entrant calls.
- memcpy(temp_info, m_info, numparams * sizeof(ParamInfo));
- }
- m_curparam = 0;
- pContext = NULL;
-
- /* Initialize 0th parameter */
- _temp_params[0] = numparams;
-
- /* Browse the parameters and build arrays */
- for (i = 0; i < numparams; i++)
- {
- /* Is this marked as an array? */
- if (temp_info[i].marked)
- {
- if (!temp_info[i].str.is_sz)
- {
- /* Allocate a normal/generic array */
- if ((err = ctx->HeapAlloc(temp_info[i].size,
- &temp_info[i].local_addr,
- &temp_info[i].phys_addr))
- != SP_ERROR_NONE)
- {
- break;
- }
- if (temp_info[i].orig_addr)
- {
- memcpy(temp_info[i].phys_addr, temp_info[i].orig_addr, sizeof(cell_t) * temp_info[i].size);
- }
- }
- else
- {
- /* Calculate cells required for the string */
- size_t cells = (temp_info[i].size + sizeof(cell_t) - 1) / sizeof(cell_t);
-
- /* Allocate the buffer */
- if ((err = ctx->HeapAlloc(cells,
- &temp_info[i].local_addr,
- &temp_info[i].phys_addr))
- != SP_ERROR_NONE)
- {
- break;
- }
- /* Copy original string if necessary */
- if ((temp_info[i].str.sz_flags & SM_PARAM_STRING_COPY) && (temp_info[i].orig_addr != NULL))
- {
- /* Cut off UTF-8 properly */
- if (temp_info[i].str.sz_flags & SM_PARAM_STRING_UTF8)
- {
- if ((err = ctx->StringToLocalUTF8(temp_info[i].local_addr,
- temp_info[i].size,
- (const char *)temp_info[i].orig_addr,
- NULL))
- != SP_ERROR_NONE)
- {
- break;
- }
- }
- /* Copy a binary blob */
- else if (temp_info[i].str.sz_flags & SM_PARAM_STRING_BINARY)
- {
- memmove(temp_info[i].phys_addr, temp_info[i].orig_addr, temp_info[i].size);
- }
- /* Copy ASCII characters */
- else
- {
- if ((err = ctx->StringToLocal(temp_info[i].local_addr,
- temp_info[i].size,
- (const char *)temp_info[i].orig_addr))
- != SP_ERROR_NONE)
- {
- break;
- }
- }
- }
- } /* End array/string calculation */
- /* Update the pushed parameter with the byref local address */
- temp_params[i] = temp_info[i].local_addr;
- }
- else
- {
- /* Just copy the value normally */
- temp_params[i] = m_params[i];
- }
- }
-
- /* Make the call if we can */
- if (err == SP_ERROR_NONE)
- {
- *result = native(ctx, _temp_params);
- if (ctx->GetLastNativeError() != SP_ERROR_NONE)
- {
- docopies = false;
- ctx->ClearLastNativeError();
- }
- }
- else
- {
- docopies = false;
- }
-
- /* i should be equal to the last valid parameter + 1 */
- while (i--)
- {
- if (!temp_info[i].marked)
- {
- continue;
- }
-
- if (docopies && (temp_info[i].flags & SM_PARAM_COPYBACK))
- {
- if (temp_info[i].orig_addr)
- {
- if (temp_info[i].str.is_sz)
- {
- memcpy(temp_info[i].orig_addr, temp_info[i].phys_addr, temp_info[i].size);
-
- }
- else
- {
- if (temp_info[i].size == 1)
- {
- *temp_info[i].orig_addr = *(temp_info[i].phys_addr);
- }
- else
- {
- memcpy(temp_info[i].orig_addr,
- temp_info[i].phys_addr,
- temp_info[i].size * sizeof(cell_t));
- }
- }
- }
- }
-
- if ((err = ctx->HeapPop(temp_info[i].local_addr)) != SP_ERROR_NONE)
- {
- return err;
- }
- }
-
- return err;
-}