diff -r 7602d7fb60d9 -r 026da5437111 sourcepawn/jit/sp_vm_function.cpp
--- a/sourcepawn/jit/sp_vm_function.cpp Fri Jul 11 06:51:21 2008 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,355 +0,0 @@
-/**
- * vim: set ts=4 :
- * =============================================================================
- * SourcePawn
- * Copyright (C) 2004-2008 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
-#include
-#include "sp_vm_function.h"
-#include "BaseRuntime.h"
-
-/********************
-* FUNCTION CALLING *
-********************/
-
-void CFunction::Set(uint32_t code_addr, BaseRuntime *runtime, funcid_t fnid, uint32_t pub_id)
-{
- m_codeaddr = code_addr;
- m_pRuntime = runtime;
- m_curparam = 0;
- m_errorstate = SP_ERROR_NONE;
- m_Invalid = false;
- m_FnId = fnid;
-}
-
-bool CFunction::IsRunnable()
-{
- return !m_pRuntime->IsPaused();
-}
-
-int CFunction::CallFunction(const cell_t *params, unsigned int num_params, cell_t *result)
-{
- return CallFunction2(m_pRuntime->GetDefaultContext(), params, num_params, result);
-}
-
-int CFunction::CallFunction2(IPluginContext *pContext, const cell_t *params, unsigned int num_params, cell_t *result)
-{
- return pContext->Execute2(this, params, num_params, result);
-}
-
-IPluginContext *CFunction::GetParentContext()
-{
- return m_pRuntime->GetDefaultContext();
-}
-
-CFunction::CFunction(uint32_t code_addr, BaseRuntime *runtime, funcid_t id, uint32_t pub_id) :
- m_codeaddr(code_addr), m_curparam(0), m_errorstate(SP_ERROR_NONE), m_FnId(id)
-{
- m_Invalid = false;
- m_pRuntime = runtime;
-}
-
-int CFunction::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 CFunction::PushCellByRef(cell_t *cell, int flags)
-{
- return PushArray(cell, 1, flags);
-}
-
-int CFunction::PushFloat(float number)
-{
- cell_t val = *(cell_t *)&number;
-
- return PushCell(val);
-}
-
-int CFunction::PushFloatByRef(float *number, int flags)
-{
- return PushCellByRef((cell_t *)number, flags);
-}
-
-int CFunction::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 CFunction::PushString(const char *string)
-{
- return _PushString(string, SM_PARAM_STRING_COPY, 0, strlen(string)+1);
-}
-
-int CFunction::PushStringEx(char *buffer, size_t length, int sz_flags, int cp_flags)
-{
- return _PushString(buffer, sz_flags, cp_flags, length);
-}
-
-int CFunction::_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 CFunction::Cancel()
-{
- if (!m_curparam)
- {
- return;
- }
-
- m_errorstate = SP_ERROR_NONE;
- m_curparam = 0;
-}
-
-int CFunction::Execute(cell_t *result)
-{
- return Execute2(m_pRuntime->GetDefaultContext(), result);
-}
-
-int CFunction::Execute2(IPluginContext *ctx, cell_t *result)
-{
- int err = SP_ERROR_NONE;
-
- if (!IsRunnable())
- {
- m_errorstate = SP_ERROR_NOT_RUNNABLE;
- }
-
- if (m_errorstate != SP_ERROR_NONE)
- {
- err = m_errorstate;
- Cancel();
- return err;
- }
-
- //This is for re-entrancy!
- cell_t temp_params[SP_MAX_EXEC_PARAMS];
- 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;
-
- /* Browse the parameters and build arrays */
- for (i=0; iHeapAlloc(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)
- {
- if ((err = CallFunction2(ctx, temp_params, numparams, result)) != SP_ERROR_NONE)
- {
- docopies = false;
- }
- }
- 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;
-}
-
-funcid_t CFunction::GetFunctionID()
-{
- return m_FnId;
-}
-
-int CFunction::SetError(int err)
-{
- m_errorstate = err;
-
- return err;
-}
-
-bool CFunction::IsInvalidated()
-{
- return m_Invalid;
-}
-
-