From 2c23544b29b583ed9af3951f94f689e0c0b76d04 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Mon, 7 Jul 2008 06:25:15 +0000 Subject: [PATCH] amazingly, core now builds. it probably crashes horribly but i'll test tomorrow. --HG-- branch : refac-jit extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/branches/refac-jit%402377 --- core/sm_globals.h | 1 + core/sm_srvcmds.cpp | 4 +- core/smn_console.cpp | 12 +- core/smn_core.cpp | 15 ++- core/smn_fakenatives.cpp | 9 +- core/smn_filesystem.cpp | 10 +- core/smn_halflife.cpp | 6 +- core/smn_hudtext.cpp | 4 +- core/smn_player.cpp | 20 +-- core/smn_string.cpp | 2 +- core/sourcemod.cpp | 111 +++------------ core/systems/HandleSys.cpp | 2 +- core/systems/PluginSys.cpp | 270 +++++++++++-------------------------- core/systems/PluginSys.h | 38 +----- core/systems/ShareSys.cpp | 2 +- 15 files changed, 151 insertions(+), 355 deletions(-) diff --git a/core/sm_globals.h b/core/sm_globals.h index 7f7f5253..d7352e64 100644 --- a/core/sm_globals.h +++ b/core/sm_globals.h @@ -173,6 +173,7 @@ private: }; extern ISourcePawnEngine *g_pSourcePawn; +extern ISourcePawnEngine2 *g_pSourcePawn2; extern IVirtualMachine *g_pVM; extern IdentityToken_t *g_pCoreIdent; diff --git a/core/sm_srvcmds.cpp b/core/sm_srvcmds.cpp index 7df5e42e..440f188e 100644 --- a/core/sm_srvcmds.cpp +++ b/core/sm_srvcmds.cpp @@ -281,8 +281,8 @@ void RootConsoleMenu::OnRootConsoleCommand(const char *cmdname, const CCommand & { ConsolePrint(" SourceMod Version Information:"); ConsolePrint(" SourceMod Version: %s", SVN_FULL_VERSION); - ConsolePrint(" JIT Version: %s, %s", g_pVM->GetVMName(), g_pVM->GetVersionString()); - ConsolePrint(" JIT Settings: %s", g_pVM->GetCPUOptimizations()); + ConsolePrint(" SourcePawn Engine: %s (build %s)", g_pSourcePawn2->GetEngineName(), g_pSourcePawn2->GetVersionString()); + ConsolePrint(" SourcePawn API: v1 = %d, v2 = %d", g_pSourcePawn->GetEngineAPIVersion(), g_pSourcePawn2->GetAPIVersion()); ConsolePrint(" Compiled on: %s %s", __DATE__, __TIME__); ConsolePrint(" http://www.sourcemod.net/"); } diff --git a/core/smn_console.cpp b/core/smn_console.cpp index c635a339..7dded75e 100644 --- a/core/smn_console.cpp +++ b/core/smn_console.cpp @@ -833,7 +833,7 @@ static cell_t sm_ServerCommand(IPluginContext *pContext, const cell_t *params) char buffer[1024]; size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer)-2, pContext, params, 1); - if (pContext->GetContext()->n_err != SP_ERROR_NONE) + if (pContext->GetLastNativeError() != SP_ERROR_NONE) { return 0; } @@ -854,7 +854,7 @@ static cell_t sm_InsertServerCommand(IPluginContext *pContext, const cell_t *par char buffer[1024]; size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer)-2, pContext, params, 1); - if (pContext->GetContext()->n_err != SP_ERROR_NONE) + if (pContext->GetLastNativeError() != SP_ERROR_NONE) { return 0; } @@ -894,7 +894,7 @@ static cell_t sm_ClientCommand(IPluginContext *pContext, const cell_t *params) char buffer[256]; g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2); - if (pContext->GetContext()->n_err != SP_ERROR_NONE) + if (pContext->GetLastNativeError() != SP_ERROR_NONE) { return 0; } @@ -921,7 +921,7 @@ static cell_t FakeClientCommand(IPluginContext *pContext, const cell_t *params) char buffer[256]; g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2); - if (pContext->GetContext()->n_err != SP_ERROR_NONE) + if (pContext->GetLastNativeError() != SP_ERROR_NONE) { return 0; } @@ -948,7 +948,7 @@ static cell_t FakeClientCommandEx(IPluginContext *pContext, const cell_t *params char buffer[256]; g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2); - if (pContext->GetContext()->n_err != SP_ERROR_NONE) + if (pContext->GetLastNativeError() != SP_ERROR_NONE) { return 0; } @@ -966,7 +966,7 @@ static cell_t ReplyToCommand(IPluginContext *pContext, const cell_t *params) char buffer[1024]; size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer)-2, pContext, params, 2); - if (pContext->GetContext()->n_err != SP_ERROR_NONE) + if (pContext->GetLastNativeError() != SP_ERROR_NONE) { return 0; } diff --git a/core/smn_core.cpp b/core/smn_core.cpp index 78d18ebd..70d0be98 100644 --- a/core/smn_core.cpp +++ b/core/smn_core.cpp @@ -130,7 +130,7 @@ static cell_t ThrowError(IPluginContext *pContext, const cell_t *params) g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1); - if (pContext->GetContext()->n_err == SP_ERROR_NONE) + if (pContext->GetLastNativeError() == SP_ERROR_NONE) { pContext->ThrowNativeErrorEx(SP_ERROR_ABORTED, "%s", buffer); } @@ -387,7 +387,7 @@ static cell_t SetFailState(IPluginContext *pContext, const cell_t *params) char buffer[2048]; g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1); - if (pContext->GetContext()->n_err != SP_ERROR_NONE) + if (pContext->GetLastNativeError() != SP_ERROR_NONE) { pPlugin->SetErrorState(Plugin_Error, "%s", str); return pContext->ThrowNativeErrorEx(SP_ERROR_ABORTED, "Formatting error (%s)", str); @@ -455,6 +455,7 @@ static cell_t MarkNativeAsOptional(IPluginContext *pContext, const cell_t *param { char *name; uint32_t idx; + sp_native_t *native; sp_context_t *ctx = pContext->GetContext(); pContext->LocalToString(params[1], &name); @@ -464,7 +465,9 @@ static cell_t MarkNativeAsOptional(IPluginContext *pContext, const cell_t *param return 0; } - ctx->natives[idx].flags |= SP_NTVFLAG_OPTIONAL; + pContext->GetNativeByIndex(idx, &native); + + native->flags |= SP_NTVFLAG_OPTIONAL; return 1; } @@ -505,7 +508,7 @@ static cell_t sm_LogAction(IPluginContext *pContext, const cell_t *params) g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE); g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 3); - if (pContext->GetContext()->n_err != SP_ERROR_NONE) + if (pContext->GetLastNativeError() != SP_ERROR_NONE) { return 0; } @@ -535,7 +538,7 @@ static cell_t LogToFile(IPluginContext *pContext, const cell_t *params) g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE); g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2); - if (pContext->GetContext()->n_err != SP_ERROR_NONE) + if (pContext->GetLastNativeError() != SP_ERROR_NONE) { fclose(fp); return 0; @@ -568,7 +571,7 @@ static cell_t LogToFileEx(IPluginContext *pContext, const cell_t *params) g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE); g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2); - if (pContext->GetContext()->n_err != SP_ERROR_NONE) + if (pContext->GetLastNativeError() != SP_ERROR_NONE) { fclose(fp); return 0; diff --git a/core/smn_fakenatives.cpp b/core/smn_fakenatives.cpp index 5e1fd71b..f5c3c24c 100644 --- a/core/smn_fakenatives.cpp +++ b/core/smn_fakenatives.cpp @@ -54,8 +54,7 @@ cell_t FakeNativeRouter(IPluginContext *pContext, const cell_t *params, void *pD } /* Check if the native is paused */ - sp_context_t *pNativeCtx = native->ctx->GetContext(); - if ((pNativeCtx->flags & SPFLAG_PLUGIN_PAUSED) == SPFLAG_PLUGIN_PAUSED) + if (native->ctx->GetRuntime()->IsPaused()) { return pContext->ThrowNativeError("Plugin owning this native is currently paused."); } @@ -90,7 +89,7 @@ cell_t FakeNativeRouter(IPluginContext *pContext, const cell_t *params, void *pD int error; if ((error=native->call->Execute(&result)) != SP_ERROR_NONE) { - if (pContext->GetContext()->n_err == SP_ERROR_NONE) + if (pContext->GetLastNativeError() == SP_ERROR_NONE) { pContext->ThrowNativeErrorEx(error, "Error encountered while processing a dynamic native"); } @@ -146,7 +145,7 @@ static cell_t ThrowNativeError(IPluginContext *pContext, const cell_t *params) g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2); - if (pContext->GetContext()->n_err != SP_ERROR_NONE) + if (pContext->GetLastNativeError() != SP_ERROR_NONE) { s_curcaller->ThrowNativeError("Error encountered while processing a dynamic native"); } else { @@ -434,7 +433,7 @@ static cell_t FormatNativeString(IPluginContext *pContext, const cell_t *params) pContext->LocalToPhysAddr(params[5], &addr); *addr = (cell_t)written; - return s_curcaller->GetContext()->n_err; + return s_curcaller->GetLastNativeError(); } //tee hee diff --git a/core/smn_filesystem.cpp b/core/smn_filesystem.cpp index 9870d6a6..74f3aa8c 100644 --- a/core/smn_filesystem.cpp +++ b/core/smn_filesystem.cpp @@ -573,7 +573,7 @@ static cell_t sm_LogToGame(IPluginContext *pContext, const cell_t *params) char buffer[1024]; size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1); - if (pContext->GetContext()->n_err != SP_ERROR_NONE) + if (pContext->GetLastNativeError() != SP_ERROR_NONE) { return 0; } @@ -599,7 +599,7 @@ static cell_t sm_LogMessage(IPluginContext *pContext, const cell_t *params) char buffer[1024]; g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1); - if (pContext->GetContext()->n_err != SP_ERROR_NONE) + if (pContext->GetLastNativeError() != SP_ERROR_NONE) { return 0; } @@ -617,7 +617,7 @@ static cell_t sm_LogError(IPluginContext *pContext, const cell_t *params) char buffer[1024]; g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1); - if (pContext->GetContext()->n_err != SP_ERROR_NONE) + if (pContext->GetLastNativeError() != SP_ERROR_NONE) { return 0; } @@ -670,7 +670,7 @@ static cell_t sm_LogToOpenFile(IPluginContext *pContext, const cell_t *params) g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE); g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2); - if (pContext->GetContext()->n_err != SP_ERROR_NONE) + if (pContext->GetLastNativeError() != SP_ERROR_NONE) { return 0; } @@ -701,7 +701,7 @@ static cell_t sm_LogToOpenFileEx(IPluginContext *pContext, const cell_t *params) g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE); g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2); - if (pContext->GetContext()->n_err != SP_ERROR_NONE) + if (pContext->GetLastNativeError() != SP_ERROR_NONE) { return 0; } diff --git a/core/smn_halflife.cpp b/core/smn_halflife.cpp index d34d6732..40590d94 100644 --- a/core/smn_halflife.cpp +++ b/core/smn_halflife.cpp @@ -289,7 +289,7 @@ static cell_t PrintToChat(IPluginContext *pContext, const cell_t *params) g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2); /* Check for an error before printing to the client */ - if (pContext->GetContext()->n_err != SP_ERROR_NONE) + if (pContext->GetLastNativeError() != SP_ERROR_NONE) { return 0; } @@ -323,7 +323,7 @@ static cell_t PrintCenterText(IPluginContext *pContext, const cell_t *params) g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2); /* Check for an error before printing to the client */ - if (pContext->GetContext()->n_err != SP_ERROR_NONE) + if (pContext->GetLastNativeError() != SP_ERROR_NONE) { return 0; } @@ -357,7 +357,7 @@ static cell_t PrintHintText(IPluginContext *pContext, const cell_t *params) g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2); /* Check for an error before printing to the client */ - if (pContext->GetContext()->n_err != SP_ERROR_NONE) + if (pContext->GetLastNativeError() != SP_ERROR_NONE) { return 0; } diff --git a/core/smn_hudtext.cpp b/core/smn_hudtext.cpp index 01426830..a5d98769 100644 --- a/core/smn_hudtext.cpp +++ b/core/smn_hudtext.cpp @@ -371,7 +371,7 @@ static cell_t ShowSyncHudText(IPluginContext *pContext, const cell_t *params) } g_SourceMod.FormatString(message_buffer, sizeof(message_buffer), pContext, params, 3); - if (pContext->GetContext()->n_err != SP_ERROR_NONE) + if (pContext->GetLastNativeError() != SP_ERROR_NONE) { return 0; } @@ -443,7 +443,7 @@ static cell_t ShowHudText(IPluginContext *pContext, const cell_t *params) } g_SourceMod.FormatString(message_buffer, sizeof(message_buffer), pContext, params, 3); - if (pContext->GetContext()->n_err != SP_ERROR_NONE) + if (pContext->GetLastNativeError() != SP_ERROR_NONE) { return 0; } diff --git a/core/smn_player.cpp b/core/smn_player.cpp index ed185f09..33b5b826 100644 --- a/core/smn_player.cpp +++ b/core/smn_player.cpp @@ -1000,7 +1000,7 @@ static cell_t _ShowActivity(IPluginContext *pContext, g_SourceMod.SetGlobalTarget(client); g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param); - if (pContext->GetContext()->n_err != SP_ERROR_NONE) + if (pContext->GetLastNativeError() != SP_ERROR_NONE) { return 0; } @@ -1015,7 +1015,7 @@ static cell_t _ShowActivity(IPluginContext *pContext, g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE); g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param); - if (pContext->GetContext()->n_err != SP_ERROR_NONE) + if (pContext->GetLastNativeError() != SP_ERROR_NONE) { return 0; } @@ -1054,7 +1054,7 @@ static cell_t _ShowActivity(IPluginContext *pContext, } g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param); - if (pContext->GetContext()->n_err != SP_ERROR_NONE) + if (pContext->GetLastNativeError() != SP_ERROR_NONE) { return 0; } @@ -1078,7 +1078,7 @@ static cell_t _ShowActivity(IPluginContext *pContext, } g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param); - if (pContext->GetContext()->n_err != SP_ERROR_NONE) + if (pContext->GetLastNativeError() != SP_ERROR_NONE) { return 0; } @@ -1123,7 +1123,7 @@ static cell_t _ShowActivity2(IPluginContext *pContext, g_SourceMod.SetGlobalTarget(client); g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param); - if (pContext->GetContext()->n_err != SP_ERROR_NONE) + if (pContext->GetLastNativeError() != SP_ERROR_NONE) { return 0; } @@ -1152,7 +1152,7 @@ static cell_t _ShowActivity2(IPluginContext *pContext, g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE); g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param); - if (pContext->GetContext()->n_err != SP_ERROR_NONE) + if (pContext->GetLastNativeError() != SP_ERROR_NONE) { return 0; } @@ -1191,7 +1191,7 @@ static cell_t _ShowActivity2(IPluginContext *pContext, } g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param); - if (pContext->GetContext()->n_err != SP_ERROR_NONE) + if (pContext->GetLastNativeError() != SP_ERROR_NONE) { return 0; } @@ -1215,7 +1215,7 @@ static cell_t _ShowActivity2(IPluginContext *pContext, } g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param); - if (pContext->GetContext()->n_err != SP_ERROR_NONE) + if (pContext->GetLastNativeError() != SP_ERROR_NONE) { return 0; } @@ -1286,7 +1286,7 @@ static cell_t KickClient(IPluginContext *pContext, const cell_t *params) char buffer[256]; g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2); - if (pContext->GetContext()->n_err != SP_ERROR_NONE) + if (pContext->GetLastNativeError() != SP_ERROR_NONE) { return 0; } @@ -1332,7 +1332,7 @@ static cell_t KickClientEx(IPluginContext *pContext, const cell_t *params) char buffer[256]; g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2); - if (pContext->GetContext()->n_err != SP_ERROR_NONE) + if (pContext->GetLastNativeError() != SP_ERROR_NONE) { return 0; } diff --git a/core/smn_string.cpp b/core/smn_string.cpp index e9d7b647..3cf92ee4 100644 --- a/core/smn_string.cpp +++ b/core/smn_string.cpp @@ -234,7 +234,7 @@ static cell_t sm_vformat(IPluginContext *pContext, const cell_t *params) /* Get the parent parameter array */ sp_context_t *ctx = pContext->GetContext(); - cell_t *local_params = (cell_t *)(ctx->memory + ctx->frm + (2 * sizeof(cell_t))); + cell_t *local_params = pContext->GetLocalParams(); cell_t max = local_params[0]; if (vargPos > (int)max + 1) diff --git a/core/sourcemod.cpp b/core/sourcemod.cpp index 8cf5fbbd..81163a95 100644 --- a/core/sourcemod.cpp +++ b/core/sourcemod.cpp @@ -33,7 +33,6 @@ #include "sourcemod.h" #include "sourcemm_api.h" #include "systems/LibrarySys.h" -#include "vm/sp_vm_engine.h" #include #include "PluginSys.h" #include "ShareSys.h" @@ -47,27 +46,26 @@ #include "ForwardSys.h" #include "TimerSys.h" #include "GameConfigs.h" +#include "DebugReporter.h" +#include "Profiler.h" SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, false, bool, const char *, const char *, const char *, const char *, bool, bool); SH_DECL_HOOK0_void(IServerGameDLL, LevelShutdown, SH_NOATTRIB, false); SH_DECL_HOOK1_void(IServerGameDLL, GameFrame, SH_NOATTRIB, false, bool); SH_DECL_HOOK1_void(IVEngineServer, ServerCommand, SH_NOATTRIB, false, const char *); -SourcePawnEngine g_SourcePawn; SourceModBase g_SourceMod; ILibrary *g_pJIT = NULL; SourceHook::String g_BaseDir; -ISourcePawnEngine *g_pSourcePawn = &g_SourcePawn; -IVirtualMachine *g_pVM; +ISourcePawnEngine *g_pSourcePawn = NULL; +ISourcePawnEngine2 *g_pSourcePawn2 = NULL; IdentityToken_t *g_pCoreIdent = NULL; IForward *g_pOnMapEnd = NULL; bool g_Loaded = false; -typedef int (*GIVEENGINEPOINTER)(ISourcePawnEngine *); -typedef int (*GIVEENGINEPOINTER2)(ISourcePawnEngine *, unsigned int api_version); -typedef unsigned int (*GETEXPORTCOUNT)(); -typedef IVirtualMachine *(*GETEXPORT)(unsigned int); +typedef ISourcePawnEngine *(*GET_SP_V1)(); +typedef ISourcePawnEngine2 *(*GET_SP_V2)(); typedef void (*NOTIFYSHUTDOWN)(); void ShutdownJIT() @@ -165,105 +163,34 @@ bool SourceModBase::InitializeSourceMod(char *error, size_t maxlength, bool late return false; } - int err; - - GIVEENGINEPOINTER2 jit_init2 = (GIVEENGINEPOINTER2)g_pJIT->GetSymbolAddress("GiveEnginePointer2"); - if (!jit_init2) - { - GIVEENGINEPOINTER jit_init = (GIVEENGINEPOINTER)g_pJIT->GetSymbolAddress("GiveEnginePointer"); - if (!jit_init) - { - ShutdownJIT(); - if (error && maxlength) - { - snprintf(error, maxlength, "Failed to find GiveEnginePointer in JIT!"); - } - return false; - } + GET_SP_V1 getv1 = (GET_SP_V1)g_pJIT->GetSymbolAddress("GetSourcePawn1"); + GET_SP_V2 getv2 = (GET_SP_V2)g_pJIT->GetSymbolAddress("GetSourcePawn2"); - if ((err=jit_init(g_pSourcePawn)) != 0) - { - ShutdownJIT(); - if (error && maxlength) - { - snprintf(error, maxlength, "GiveEnginePointer returned %d in the JIT", err); - } - return false; - } - } - else + if (getv1 == NULL) { - /* On version bumps, we should check for older versions as well, if the new version fails. - * We can then check the exports to see if any VM versions will be sufficient. - */ - if ((err=jit_init2(g_pSourcePawn, SOURCEPAWN_ENGINE_API_VERSION)) != SP_ERROR_NONE) - { - ShutdownJIT(); - if (error && maxlength) - { - snprintf(error, maxlength, "JIT incompatible with SourceMod version"); - } - return false; - } - } - - GETEXPORTCOUNT jit_getnum = (GETEXPORTCOUNT)g_pJIT->GetSymbolAddress("GetExportCount"); - GETEXPORT jit_get = (GETEXPORT)g_pJIT->GetSymbolAddress("GetExport"); - if (!jit_get) - { - ShutdownJIT(); if (error && maxlength) { - snprintf(error, maxlength, "JIT is missing a necessary export!"); + snprintf(error, maxlength, "JIT is too old; upgrade SourceMod"); } + ShutdownJIT(); return false; } - - unsigned int num = jit_getnum(); - if (!num) + else if (getv2 == NULL) { - ShutdownJIT(); if (error && maxlength) { - snprintf(error, maxlength, "JIT did not export any virtual machines!"); + snprintf(error, maxlength, "JIT is too old; upgrade SourceMod"); } - return false; - } - - unsigned int api_version; - for (unsigned int i=0; iAlso refuse anything < 3 because we need fake natives. - * Also refuse anything < 7 because we need the new sp_native definition. - */ - api_version = g_pVM->GetAPIVersion(); - if (api_version < 7 || api_version > SOURCEPAWN_VM_API_VERSION) - { - if (error && maxlength) - { - snprintf(error, maxlength, "JIT is not a compatible version"); - } - g_pVM = NULL; - continue; - } - break; - } - - if (!g_pVM) - { ShutdownJIT(); return false; } + g_pSourcePawn = getv1(); + g_pSourcePawn2 = getv2(); + + g_pSourcePawn2->SetDebugListener(&g_DbgReporter); + g_pSourcePawn2->SetProfiler(&g_Profiler); + /* Hook this now so we can detect startup without calling StartSourceMod() */ SH_ADD_HOOK_MEMFUNC(IServerGameDLL, LevelInit, gamedll, this, &SourceModBase::LevelInit, false); diff --git a/core/systems/HandleSys.cpp b/core/systems/HandleSys.cpp index 897a5ff9..71b41fa9 100644 --- a/core/systems/HandleSys.cpp +++ b/core/systems/HandleSys.cpp @@ -990,7 +990,7 @@ bool HandleSystem::TryAndFreeSomeHandles() g_Logger.LogFatal("[SM] Reloading plugin to free %d handles.", highest_handle_count); g_Logger.LogFatal("[SM] Contact the author(s) of this plugin to correct this error.", highest_handle_count); - highest_owner->GetContext()->n_err = SP_ERROR_MEMACCESS; + highest_owner->GetBaseContext()->ThrowNativeErrorEx(SP_ERROR_MEMACCESS, "Memory leak"); return g_PluginSys.UnloadPlugin(highest_owner); } diff --git a/core/systems/PluginSys.cpp b/core/systems/PluginSys.cpp index bf6c7e0e..dcf842ad 100644 --- a/core/systems/PluginSys.cpp +++ b/core/systems/PluginSys.cpp @@ -58,7 +58,7 @@ CPlugin::CPlugin(const char *file) m_type = PluginType_Private; m_status = Plugin_Uncompiled; m_serial = ++MySerial; - m_plugin = NULL; + m_pRuntime = NULL; m_errormsg[256] = '\0'; snprintf(m_filename, sizeof(m_filename), "%s", file); m_handle = 0; @@ -82,27 +82,12 @@ CPlugin::~CPlugin() g_ShareSys.DestroyIdentity(m_ident); } - if (m_ctx.base) + if (m_pRuntime != NULL) { - delete m_ctx.base; - m_ctx.base = NULL; - } - if (m_ctx.ctx) - { - m_ctx.vm->FreeContext(m_ctx.ctx); - m_ctx.ctx = NULL; - } - if (m_ctx.co) - { - m_ctx.vm->AbortCompilation(m_ctx.co); - m_ctx.co = NULL; + delete m_pRuntime; + m_pRuntime = NULL; } - if (m_plugin) - { - g_pSourcePawn->FreeFromMemory(m_plugin); - m_plugin = NULL; - } if (m_pProps) { sm_trie_destroy(m_pProps); @@ -125,7 +110,7 @@ void CPlugin::InitIdentity() { m_ident = g_ShareSys.CreateIdentity(g_PluginIdent, this); m_handle = g_HandleSys.CreateHandle(g_PluginType, this, g_PluginSys.GetIdentity(), g_PluginSys.GetIdentity(), NULL); - m_ctx.base->SetIdentity(m_ident); + m_pRuntime->GetDefaultContext()->SetKey(1, m_ident); } } @@ -157,37 +142,6 @@ unsigned int CPlugin::CalcMemUsage() base_size += (*i).size(); } - if (m_plugin != NULL) - { - base_size += sizeof(sp_plugin_t); - base_size += m_plugin->data_size; - base_size += m_plugin->pcode_size; - base_size += (m_plugin->info.natives_num * sizeof(sp_file_natives_t)); - base_size += (m_plugin->info.publics_num * sizeof(sp_file_publics_t)); - base_size += (m_plugin->info.pubvars_num * sizeof(sp_file_pubvars_t)); - base_size += (m_plugin->debug.files_num * sizeof(sp_fdbg_file_t)); - base_size += (m_plugin->debug.lines_num * sizeof(sp_fdbg_line_t)); - base_size += (m_plugin->debug.syms_num * sizeof(sp_fdbg_symbol_t)); - /* We can't get strtab size, oh well. */ - } - - if (m_ctx.base != NULL) - { - base_size += sizeof(BaseContext); - base_size += m_ctx.base->GetPublicsNum() * sizeof(CFunction); - } - if (m_ctx.ctx != NULL) - { - base_size += m_ctx.ctx->mem_size; - base_size += (m_plugin->debug.files_num * sizeof(sp_debug_file_t)); - base_size += (m_plugin->debug.lines_num * sizeof(sp_debug_line_t)); - base_size += (m_plugin->debug.syms_num * sizeof(sp_debug_symbol_t)); - base_size += (m_plugin->info.pubvars_num * sizeof(sp_pubvar_t)); - base_size += (m_plugin->info.publics_num * sizeof(sp_public_t)); - base_size += (m_plugin->info.natives_num * sizeof(sp_native_t)); - /* We also don't know the JIT code size, oh well. */ - } - return base_size; } @@ -214,23 +168,6 @@ CPlugin *CPlugin::CreatePlugin(const char *file, char *error, size_t maxlength) return pPlugin; } - int err; - sp_plugin_t *pl = g_pSourcePawn->LoadFromFilePointer(fp, &err); - if (pl == NULL) - { - fclose(fp); - if (error) - { - snprintf(error, maxlength, "Error %d while parsing plugin", err); - } - pPlugin->m_status = Plugin_BadLoad; - return pPlugin; - } - - fclose(fp); - - pPlugin->m_plugin = pl; - return pPlugin; } @@ -251,69 +188,9 @@ bool CPlugin::SetProperty(const char *prop, void *ptr) return sm_trie_insert(m_pProps, prop, ptr); } -ICompilation *CPlugin::StartMyCompile(IVirtualMachine *vm) +IPluginRuntime *CPlugin::GetRuntime() { - if (!m_plugin) - { - return NULL; - } - - /* :NOTICE: We will eventually need to change these natives - * for swapping in new contexts - */ - if (m_ctx.co || m_ctx.ctx) - { - return NULL; - } - - m_status = Plugin_Uncompiled; - - m_ctx.vm = vm; - m_ctx.co = vm->StartCompilation(m_plugin); - - return m_ctx.co; -} - -void CPlugin::CancelMyCompile() -{ - if (!m_ctx.co) - { - return; - } - - m_ctx.vm->AbortCompilation(m_ctx.co); - m_ctx.co = NULL; - m_ctx.vm = NULL; -} - -bool CPlugin::FinishMyCompile(char *error, size_t maxlength) -{ - if (!m_ctx.co) - { - return false; - } - - int err; - m_ctx.ctx = m_ctx.vm->CompileToContext(m_ctx.co, &err); - if (!m_ctx.ctx) - { - memset(&m_ctx, 0, sizeof(m_ctx)); - if (error) - { - snprintf(error, maxlength, "JIT failed to compile (error %d)", err); - } - return false; - } - - m_ctx.base = new BaseContext(m_ctx.ctx); - m_ctx.ctx->user[SM_CONTEXTVAR_MYSELF] = (void *)this; - - m_status = Plugin_Created; - m_ctx.co = NULL; - - UpdateInfo(); - - return true; + return m_pRuntime; } void CPlugin::SetErrorState(PluginStatus status, const char *error_fmt, ...) @@ -332,9 +209,9 @@ void CPlugin::SetErrorState(PluginStatus status, const char *error_fmt, ...) vsnprintf(m_errormsg, sizeof(m_errormsg), error_fmt, ap); va_end(ap); - if (m_ctx.ctx) + if (m_pRuntime != NULL) { - m_ctx.ctx->flags |= SPFLAG_PLUGIN_PAUSED; + m_pRuntime->SetPauseState(true); } } @@ -415,7 +292,7 @@ void CPlugin::Call_OnPluginStart() m_status = Plugin_Running; cell_t result; - IPluginFunction *pFunction = m_ctx.base->GetFunctionByName("OnPluginStart"); + IPluginFunction *pFunction = m_pRuntime->GetFunctionByName("OnPluginStart"); if (!pFunction) { return; @@ -436,7 +313,7 @@ void CPlugin::Call_OnPluginEnd() } cell_t result; - IPluginFunction *pFunction = m_ctx.base->GetFunctionByName("OnPluginEnd"); + IPluginFunction *pFunction = m_pRuntime->GetFunctionByName("OnPluginEnd"); if (!pFunction) { return; @@ -460,7 +337,7 @@ void CPlugin::Call_OnAllPluginsLoaded() m_bGotAllLoaded = true; cell_t result; - IPluginFunction *pFunction = m_ctx.base->GetFunctionByName("OnAllPluginsLoaded"); + IPluginFunction *pFunction = m_pRuntime->GetFunctionByName("OnAllPluginsLoaded"); if (pFunction != NULL) { pFunction->Execute(&result); @@ -468,7 +345,7 @@ void CPlugin::Call_OnAllPluginsLoaded() if (g_OnMapStarted) { - if ((pFunction = m_ctx.base->GetFunctionByName("OnMapStart")) != NULL) + if ((pFunction = m_pRuntime->GetFunctionByName("OnMapStart")) != NULL) { pFunction->Execute(NULL); } @@ -491,7 +368,7 @@ bool CPlugin::Call_AskPluginLoad(char *error, size_t maxlength) int err; cell_t result; - IPluginFunction *pFunction = m_ctx.base->GetFunctionByName("AskPluginLoad"); + IPluginFunction *pFunction = m_pRuntime->GetFunctionByName("AskPluginLoad"); if (!pFunction) { @@ -515,19 +392,24 @@ bool CPlugin::Call_AskPluginLoad(char *error, size_t maxlength) return true; } -const sp_plugin_t *CPlugin::GetPluginStructure() +void *CPlugin::GetPluginStructure() { - return m_plugin; + return NULL; } IPluginContext *CPlugin::GetBaseContext() { - return m_ctx.base; + if (m_pRuntime == NULL) + { + return NULL; + } + + return m_pRuntime->GetDefaultContext(); } sp_context_t *CPlugin::GetContext() { - return m_ctx.ctx; + return NULL; } const char *CPlugin::GetFilename() @@ -557,12 +439,12 @@ PluginStatus CPlugin::GetStatus() bool CPlugin::IsDebugging() { - if (!m_ctx.ctx) + if (m_pRuntime == NULL) { return false; } - return ((m_ctx.ctx->flags & SP_FLAG_DEBUG) == SP_FLAG_DEBUG); + return m_pRuntime->IsDebugging(); } void CPlugin::LibraryActions(bool dropping) @@ -590,7 +472,7 @@ bool CPlugin::SetPauseState(bool paused) LibraryActions(true); } - IPluginFunction *pFunction = m_ctx.base->GetFunctionByName("OnPluginPauseChange"); + IPluginFunction *pFunction = m_pRuntime->GetFunctionByName("OnPluginPauseChange"); if (pFunction) { cell_t result; @@ -601,10 +483,10 @@ bool CPlugin::SetPauseState(bool paused) if (paused) { m_status = Plugin_Paused; - m_ctx.ctx->flags |= SPFLAG_PLUGIN_PAUSED; + m_pRuntime->SetPauseState(true); } else { m_status = Plugin_Running; - m_ctx.ctx->flags &= ~SPFLAG_PLUGIN_PAUSED; + m_pRuntime->SetPauseState(false); } g_PluginSys._SetPauseState(this, paused); @@ -652,8 +534,9 @@ bool CPlugin::ToggleDebugMode(bool debug, char *error, size_t maxlength) return false; } - ICompilation *co = g_pVM->StartCompilation(m_ctx.ctx->plugin); - if (!g_pVM->SetCompilationOption(co, "debug", (debug) ? "1" : "0")) + ICompilation *co = g_pSourcePawn2->StartCompilation(); + + if (!co->SetOption("debug", (debug) ? "1" : "0")) { if (error) { @@ -662,32 +545,7 @@ bool CPlugin::ToggleDebugMode(bool debug, char *error, size_t maxlength) return false; } - sp_context_t *new_ctx = g_pVM->CompileToContext(co, &err); - - if (new_ctx) - { - memcpy(new_ctx->memory, m_ctx.ctx->memory, m_ctx.ctx->mem_size); - new_ctx->hp = m_ctx.ctx->hp; - new_ctx->sp = m_ctx.ctx->sp; - new_ctx->frm = m_ctx.ctx->frm; - new_ctx->dbreak = m_ctx.ctx->dbreak; - new_ctx->context = m_ctx.ctx->context; - memcpy(new_ctx->user, m_ctx.ctx->user, sizeof(m_ctx.ctx->user)); - - uint32_t nativeCount = m_plugin->info.natives_num; - for (uint32_t i=0; inatives[i].pfn = m_ctx.ctx->natives[i].pfn; - new_ctx->natives[i].status = m_ctx.ctx->natives[i].status; - } - - g_pVM->FreeContext(m_ctx.ctx); - m_ctx.ctx = new_ctx; - m_ctx.base->SetContext(new_ctx); - - UpdateInfo(); - } - else + if ((err = m_pRuntime->ApplyCompilationOptions(co)) != SP_ERROR_NONE) { if (error) { @@ -696,6 +554,8 @@ bool CPlugin::ToggleDebugMode(bool debug, char *error, size_t maxlength) return false; } + UpdateInfo(); + return true; } @@ -741,7 +601,7 @@ IPhraseCollection *CPlugin::GetPhrases() void CPlugin::DependencyDropped(CPlugin *pOwner) { - if (!m_ctx.ctx) + if (!m_pRuntime) { return; } @@ -771,12 +631,12 @@ void CPlugin::DependencyDropped(CPlugin *pOwner) { pNative = (*iter); /* Find this native! */ - if (m_ctx.base->FindNativeByName(pNative->name, &idx) != SP_ERROR_NONE) + if (m_pRuntime->FindNativeByName(pNative->name, &idx) != SP_ERROR_NONE) { continue; } /* Unbind it */ - m_ctx.base->GetNativeByIndex(idx, &native); + m_pRuntime->GetNativeByIndex(idx, &native); native->pfn = NULL; native->status = SP_NATIVE_UNBOUND; unbound++; @@ -1047,6 +907,7 @@ LoadRes CPluginManager::_LoadPlugin(CPlugin **_plugin, const char *path, bool de return LoadRes_NeverLoad; } + int err; bool no_load = false; PluginSettings *pset; unsigned int setcount = m_PluginInfo.GetSettingsNum(); @@ -1102,7 +963,7 @@ LoadRes CPluginManager::_LoadPlugin(CPlugin **_plugin, const char *path, bool de if (pPlugin->m_status == Plugin_Uncompiled) { - co = pPlugin->StartMyCompile(g_pVM); + co = g_pSourcePawn2->StartCompilation(); } for (unsigned int i=0; iSetCompilationOption(co, key, val)) + if ((err = co->SetOption(key, val)) == SP_ERROR_NONE) { if (error) { snprintf(error, maxlength, "Unable to set JIT option (key \"%s\") (value \"%s\")", key, val); } - pPlugin->CancelMyCompile(); + co->Abort(); co = NULL; break; } @@ -1137,10 +998,25 @@ LoadRes CPluginManager::_LoadPlugin(CPlugin **_plugin, const char *path, bool de } /* Do the actual compiling */ - if (co) + if (co != NULL) { - pPlugin->FinishMyCompile(error, maxlength); - co = NULL; + char fullpath[PLATFORM_MAX_PATH]; + g_SourceMod.BuildPath(Path_SM, fullpath, sizeof(fullpath), "plugins/%s", pPlugin->m_filename); + + pPlugin->m_pRuntime = g_pSourcePawn2->LoadPlugin(co, fullpath, &err); + if (pPlugin->m_pRuntime == NULL) + { + snprintf(error, + maxlength, + "Unable to load plugin (error %d: %s)", + err, + g_pSourcePawn2->GetErrorString(err)); + } + else + { + pPlugin->UpdateInfo(); + pPlugin->m_status = Plugin_Created; + } } /* Get the status */ @@ -1321,7 +1197,7 @@ bool CPluginManager::FindOrRequirePluginDeps(CPlugin *pPlugin, char *error, size { cell_t res; pFunc->Execute(&res); - if (pPlugin->GetContext()->n_err != SP_ERROR_NONE) + if (pPlugin->GetBaseContext()->GetLastNativeError() != SP_ERROR_NONE) { if (error) { @@ -1448,7 +1324,7 @@ bool CPluginManager::LoadOrRequireExtensions(CPlugin *pPlugin, unsigned int pass { cell_t res; pFunc->Execute(&res); - if (pPlugin->GetContext()->n_err != SP_ERROR_NONE) + if (pPlugin->GetBaseContext()->GetLastNativeError() != SP_ERROR_NONE) { if (error) { @@ -1615,9 +1491,9 @@ void CPluginManager::TryRefreshDependencies(CPlugin *pPlugin) { /* If we got here, all natives are okay again! */ pPlugin->m_status = Plugin_Running; - if ((pPlugin->m_ctx.ctx->flags & SPFLAG_PLUGIN_PAUSED) == SPFLAG_PLUGIN_PAUSED) + if (pPlugin->m_pRuntime->IsPaused()) { - pPlugin->m_ctx.ctx->flags &= ~SPFLAG_PLUGIN_PAUSED; + pPlugin->m_pRuntime->SetPauseState(false); _SetPauseState(pPlugin, false); } } @@ -1687,8 +1563,24 @@ bool CPluginManager::UnloadPlugin(IPlugin *plugin) IPlugin *CPluginManager::FindPluginByContext(const sp_context_t *ctx) { - IPlugin *pl = (IPlugin *)ctx->user[SM_CONTEXTVAR_MYSELF]; - return pl; + List::iterator iter; + + /* :TODO: :TODO: respeed this up somehow */ + for (iter = m_plugins.begin(); iter != m_plugins.end(); iter++) + { + CPlugin *pl = (*iter); + if (pl->m_pRuntime != NULL && pl->m_pRuntime->GetDefaultContext()->GetContext() == ctx) + { + return pl; + } + } + + return NULL; +} + +CPlugin *CPluginManager::GetPluginByCtx(const sp_context_t *ctx) +{ + return (CPlugin *)FindPluginByContext(ctx); } unsigned int CPluginManager::GetPluginCount() diff --git a/core/systems/PluginSys.h b/core/systems/PluginSys.h index 7e79871a..1bb41141 100644 --- a/core/systems/PluginSys.h +++ b/core/systems/PluginSys.h @@ -43,7 +43,6 @@ #include #include #include "sm_globals.h" -#include "vm/sp_vm_basecontext.h" #include "PluginInfoDatabase.h" #include "sm_trie.h" #include "sourcemod.h" @@ -109,19 +108,6 @@ using namespace SourceHook; * 7. Once all plugins are deemed to be loaded, OnPluginStart() is called */ -#define SM_CONTEXTVAR_MYSELF 0 - -struct ContextPair -{ - ContextPair() : base(NULL), ctx(NULL), co(NULL) - { - }; - BaseContext *base; - sp_context_t *ctx; - ICompilation *co; - IVirtualMachine *vm; -}; - enum LoadRes { LoadRes_Successful, @@ -152,18 +138,19 @@ public: PluginType GetType(); SourcePawn::IPluginContext *GetBaseContext(); sp_context_t *GetContext(); - const sm_plugininfo_t *GetPublicInfo(); + void *GetPluginStructure(); const char *GetFilename(); bool IsDebugging(); PluginStatus GetStatus(); + const sm_plugininfo_t *GetPublicInfo(); bool SetPauseState(bool paused); unsigned int GetSerial(); - const sp_plugin_t *GetPluginStructure(); IdentityToken_t *GetIdentity(); unsigned int CalcMemUsage(); bool SetProperty(const char *prop, void *ptr); bool GetProperty(const char *prop, void **ptr, bool remove=false); void DropEverything(); + SourcePawn::IPluginRuntime *GetRuntime(); public: /** * Creates a plugin object with default values. @@ -174,16 +161,6 @@ public: */ static CPlugin *CreatePlugin(const char *file, char *error, size_t maxlength); public: - /** - * Starts the initial compilation of a plugin. - * Returns false if another compilation exists or there is a current context set. - */ - ICompilation *StartMyCompile(IVirtualMachine *vm); - /** - * Finalizes a compilation. If error buffer is NULL, the error is saved locally. - */ - bool FinishMyCompile(char *error, size_t maxlength); - void CancelMyCompile(); /** * Sets an error state on the plugin @@ -267,13 +244,11 @@ protected: void SetTimeStamp(time_t t); void DependencyDropped(CPlugin *pOwner); private: - ContextPair m_ctx; PluginType m_type; char m_filename[PLATFORM_MAX_PATH]; PluginStatus m_status; unsigned int m_serial; sm_plugininfo_t m_info; - sp_plugin_t *m_plugin; char m_errormsg[256]; time_t m_LastAccess; IdentityToken_t *m_ident; @@ -289,6 +264,8 @@ private: bool m_bGotAllLoaded; int m_FileVersion; char m_DateTime[256]; + IPluginRuntime *m_pRuntime; + IPluginContext *m_pContext; }; class CPluginManager : @@ -382,10 +359,7 @@ public: /** * Internal version of FindPluginByContext() */ - inline CPlugin *GetPluginByCtx(const sp_context_t *ctx) - { - return reinterpret_cast(ctx->user[SM_CONTEXTVAR_MYSELF]); - } + CPlugin *GetPluginByCtx(const sp_context_t *ctx); /** * Gets status text for a status code diff --git a/core/systems/ShareSys.cpp b/core/systems/ShareSys.cpp index 391a9c7c..3d04f7fa 100644 --- a/core/systems/ShareSys.cpp +++ b/core/systems/ShareSys.cpp @@ -488,7 +488,7 @@ NativeEntry *ShareSystem::AddFakeNative(IPluginFunction *pFunc, const char *name pFake = new FakeNative; - if ((gate = g_pVM->CreateFakeNative(func, pFake)) == NULL) + if ((gate = g_pSourcePawn2->CreateFakeNative(func, pFake)) == NULL) { delete pFake; return NULL;