From fcaa5361c890ca1ebbaf632023f6e36ceab59bc2 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Tue, 24 Feb 2015 22:58:31 -0800 Subject: [PATCH] Don't expose mutable sp_native_t. --- core/logic/NativeOwner.cpp | 10 ++++----- core/logic/PluginSys.cpp | 30 ++++++++++---------------- core/logic/ShareSys.cpp | 34 +++++++++++++++--------------- core/logic/ShareSys.h | 2 +- core/logic/smn_core.cpp | 6 +----- public/sourcepawn/sp_vm_api.h | 35 ++++++++++++++++++++++++------- sourcepawn/jit/debug-trace.cpp | 4 ++-- sourcepawn/jit/dll_exports.cpp | 7 +------ sourcepawn/jit/plugin-runtime.cpp | 22 ++++++++++++++----- sourcepawn/jit/plugin-runtime.h | 3 ++- sourcepawn/jit/x86/jit_x86.cpp | 2 +- 11 files changed, 85 insertions(+), 70 deletions(-) diff --git a/core/logic/NativeOwner.cpp b/core/logic/NativeOwner.cpp index bb62f837..e6adcb2e 100644 --- a/core/logic/NativeOwner.cpp +++ b/core/logic/NativeOwner.cpp @@ -84,11 +84,11 @@ void CNativeOwner::UnbindWeakRef(const WeakNative &ref) IPluginContext *pContext; pContext = ref.pl->GetBaseContext(); - if ((pContext->GetNativeByIndex(ref.idx, &native)) == SP_ERROR_NONE) - { - native->status = SP_NATIVE_UNBOUND; - native->pfn = NULL; - } + pContext->GetRuntime()->UpdateNativeBinding( + ref.idx, + nullptr, + 0, + nullptr); } void CNativeOwner::DropEverything() diff --git a/core/logic/PluginSys.cpp b/core/logic/PluginSys.cpp index db4611cf..420c2a11 100644 --- a/core/logic/PluginSys.cpp +++ b/core/logic/PluginSys.cpp @@ -646,11 +646,7 @@ void CPlugin::DependencyDropped(CPlugin *pOwner) if (m_pRuntime->FindNativeByName(entry->name(), &idx) != SP_ERROR_NONE) continue; - sp_native_t *native; - m_pRuntime->GetNativeByIndex(idx, &native); - - native->pfn = NULL; - native->status = SP_NATIVE_UNBOUND; + m_pRuntime->UpdateNativeBinding(idx, nullptr, 0, nullptr); unbound++; } @@ -1357,16 +1353,14 @@ bool CPluginManager::RunSecondPass(CPlugin *pPlugin, char *error, size_t maxleng /* Find any unbound natives. Right now, these are not allowed. */ IPluginContext *pContext = pPlugin->GetBaseContext(); uint32_t num = pContext->GetNativesNum(); - sp_native_t *native; for (unsigned int i=0; iGetNativeByIndex(i, &native) != SP_ERROR_NONE) - { + const sp_native_t *native = pContext->GetRuntime()->GetNative(i); + if (!native) break; - } - if (native->status == SP_NATIVE_UNBOUND - && native->name[0] != '@' - && !(native->flags & SP_NTVFLAG_OPTIONAL)) + if (native->status == SP_NATIVE_UNBOUND && + native->name[0] != '@' && + !(native->flags & SP_NTVFLAG_OPTIONAL)) { if (error) { @@ -1478,16 +1472,14 @@ void CPluginManager::TryRefreshDependencies(CPlugin *pPlugin) */ IPluginContext *pContext = pPlugin->GetBaseContext(); uint32_t num = pContext->GetNativesNum(); - sp_native_t *native; for (unsigned int i=0; iGetNativeByIndex(i, &native) != SP_ERROR_NONE) - { + const sp_native_t *native = pContext->GetRuntime()->GetNative(i); + if (!native) break; - } - if (native->status == SP_NATIVE_UNBOUND - && native->name[0] != '@' - && !(native->flags & SP_NTVFLAG_OPTIONAL)) + if (native->status == SP_NATIVE_UNBOUND && + native->name[0] != '@' && + !(native->flags & SP_NTVFLAG_OPTIONAL)) { pPlugin->SetErrorState(Plugin_Error, "Native not found: %s", native->name); return; diff --git a/core/logic/ShareSys.cpp b/core/logic/ShareSys.cpp index ddde22a5..16067b43 100644 --- a/core/logic/ShareSys.cpp +++ b/core/logic/ShareSys.cpp @@ -271,7 +271,6 @@ PassRef ShareSystem::FindNative(const char *name) void ShareSystem::BindNativesToPlugin(CPlugin *pPlugin, bool bCoreOnly) { - sp_native_t *native; uint32_t i, native_count; IPluginContext *pContext; @@ -284,7 +283,8 @@ void ShareSystem::BindNativesToPlugin(CPlugin *pPlugin, bool bCoreOnly) native_count = pContext->GetNativesNum(); for (i = 0; i < native_count; i++) { - if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE) + const sp_native_t *native = pContext->GetRuntime()->GetNative(i); + if (!native) continue; // If we're already bound, no need to do anything else. @@ -314,8 +314,8 @@ void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin, const Ref &entry) if (pContext->FindNativeByName(entry->name(), &i) != SP_ERROR_NONE) return; - sp_native_t *native; - if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE) + const sp_native_t *native = pContext->GetRuntime()->GetNative(i); + if (!native) return; if (native->status == SP_NATIVE_BOUND) @@ -324,18 +324,15 @@ void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin, const Ref &entry) BindNativeToPlugin(pPlugin, native, i, entry); } -void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin, sp_native_t *native, uint32_t index, +void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin, const sp_native_t *native, uint32_t index, const Ref &pEntry) { - /* Mark as bound... we do the rest next. */ - native->status = SP_NATIVE_BOUND; - native->pfn = pEntry->func(); - + uint32_t flags = 0; if (pEntry->fake) { /* This native is not necessarily optional, but we don't guarantee * that its address is long-lived. */ - native->flags |= SP_NTVFLAG_EPHEMERAL; + flags |= SP_NTVFLAG_EPHEMERAL; } /* We don't bother with dependency crap if the owner is Core. */ @@ -345,10 +342,9 @@ void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin, sp_native_t *native, uint if ((native->flags & SP_NTVFLAG_OPTIONAL) == SP_NTVFLAG_OPTIONAL) { /* Only add if there is a valid owner. */ - if (pEntry->owner) - pEntry->owner->AddWeakRef(WeakNative(pPlugin, index)); - else - native->status = SP_NATIVE_UNBOUND; + if (!pEntry->owner) + return; + pEntry->owner->AddWeakRef(WeakNative(pPlugin, index)); } /* Otherwise, we're a strong dependent and not a weak one */ else @@ -367,6 +363,12 @@ void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin, sp_native_t *native, uint } } } + + pPlugin->GetRuntime()->UpdateNativeBinding( + index, + pEntry->func(), + flags, + nullptr); } PassRef ShareSystem::AddNativeToCache(CNativeOwner *pOwner, const sp_nativeinfo_t *ntv) @@ -468,9 +470,7 @@ FeatureStatus ShareSystem::TestNative(IPluginRuntime *pRuntime, const char *name if (pRuntime->FindNativeByName(name, &index) == SP_ERROR_NONE) { - sp_native_t *native; - if (pRuntime->GetNativeByIndex(index, &native) == SP_ERROR_NONE) - { + if (const sp_native_t *native = pRuntime->GetNative(index)) { if (native->status == SP_NATIVE_BOUND) return FeatureStatus_Available; else diff --git a/core/logic/ShareSys.h b/core/logic/ShareSys.h index b9cc1aec..456e2c59 100644 --- a/core/logic/ShareSys.h +++ b/core/logic/ShareSys.h @@ -126,7 +126,7 @@ public: private: ke::PassRef AddNativeToCache(CNativeOwner *pOwner, const sp_nativeinfo_t *ntv); void ClearNativeFromCache(CNativeOwner *pOwner, const char *name); - void BindNativeToPlugin(CPlugin *pPlugin, sp_native_t *ntv, uint32_t index, const ke::Ref &pEntry); + void BindNativeToPlugin(CPlugin *pPlugin, const sp_native_t *ntv, uint32_t index, const ke::Ref &pEntry); private: typedef NameHashSet, Native> NativeCache; diff --git a/core/logic/smn_core.cpp b/core/logic/smn_core.cpp index c595ebab..f6d2ef76 100644 --- a/core/logic/smn_core.cpp +++ b/core/logic/smn_core.cpp @@ -457,7 +457,6 @@ static cell_t MarkNativeAsOptional(IPluginContext *pContext, const cell_t *param { char *name; uint32_t idx; - sp_native_t *native; pContext->LocalToString(params[1], &name); if (pContext->FindNativeByName(name, &idx) != SP_ERROR_NONE) @@ -466,10 +465,7 @@ static cell_t MarkNativeAsOptional(IPluginContext *pContext, const cell_t *param return 0; } - pContext->GetNativeByIndex(idx, &native); - - native->flags |= SP_NTVFLAG_OPTIONAL; - + pContext->GetRuntime()->UpdateNativeBinding(idx, nullptr, SP_NTVFLAG_OPTIONAL, nullptr); return 1; } diff --git a/public/sourcepawn/sp_vm_api.h b/public/sourcepawn/sp_vm_api.h index 653b2c4f..2c57a6b6 100644 --- a/public/sourcepawn/sp_vm_api.h +++ b/public/sourcepawn/sp_vm_api.h @@ -22,8 +22,8 @@ #include "sp_vm_types.h" /** SourcePawn Engine API Versions */ -#define SOURCEPAWN_ENGINE2_API_VERSION 7 -#define SOURCEPAWN_API_VERSION 0x0207 +#define SOURCEPAWN_ENGINE2_API_VERSION 8 +#define SOURCEPAWN_API_VERSION 0x0208 namespace SourceMod { struct IdentityToken_t; @@ -305,10 +305,11 @@ namespace SourcePawn virtual int FindNativeByName(const char *name, uint32_t *index) =0; /** - * @brief Gets native info by index. + * @brief Deprecated, does nothing. * - * @param index Index number of native. - * @param native Optionally filled with pointer to native structure. + * @param index Unused. + * @param native Unused. + * @return Returns SP_ERROR_PARAM. */ virtual int GetNativeByIndex(uint32_t index, sp_native_t **native) =0; @@ -446,6 +447,23 @@ namespace SourcePawn * @return 16-byte buffer with MD5 hash of the plugin's Data. */ virtual unsigned char *GetDataHash() =0; + + /** + * @brief Update the native binding at the given index. + * + * @param pfn Native function pointer. + * @param flags Native flags. + * @param user User data pointer. + */ + virtual int UpdateNativeBinding(uint32_t index, SPVM_NATIVE_FUNC pfn, uint32_t flags, void *data) = 0; + + /** + * @brief Returns the native at the given index. + * + * @param index Native index. + * @return Native pointer, or NULL on failure. + */ + virtual const sp_native_t *GetNative(uint32_t index) = 0; }; /** @@ -537,10 +555,11 @@ namespace SourcePawn virtual int FindNativeByName(const char *name, uint32_t *index) =0; /** - * @brief Deprecated, use IPluginRuntime instead. + * @brief Deprecated, does nothing. * - * @param index Index number of native. - * @param native Optionally filled with pointer to native structure. + * @param index Unused. + * @param native Unused. + * @return Returns SP_ERROR_PARAM. */ virtual int GetNativeByIndex(uint32_t index, sp_native_t **native) =0; diff --git a/sourcepawn/jit/debug-trace.cpp b/sourcepawn/jit/debug-trace.cpp index 32e3fc81..29aa1d4a 100644 --- a/sourcepawn/jit/debug-trace.cpp +++ b/sourcepawn/jit/debug-trace.cpp @@ -111,8 +111,8 @@ CContextTrace::GetLastNative(uint32_t *index) if (lastNative < 0) return NULL; - sp_native_t *native; - if (m_pRuntime->GetNativeByIndex(lastNative, &native) != SP_ERROR_NONE) + const sp_native_t *native = m_pRuntime->GetNative(lastNative); + if (!native) return NULL; if (index) diff --git a/sourcepawn/jit/dll_exports.cpp b/sourcepawn/jit/dll_exports.cpp index e7fa3c42..2fe8b94b 100644 --- a/sourcepawn/jit/dll_exports.cpp +++ b/sourcepawn/jit/dll_exports.cpp @@ -173,12 +173,7 @@ static void BindNative(IPluginRuntime *rt, const char *name, SPVM_NATIVE_FUNC fn if ((err = rt->FindNativeByName(name, &index)) != SP_ERROR_NONE) return; - sp_native_t *native; - if (rt->GetNativeByIndex(index, &native) != SP_ERROR_NONE) - return; - - native->pfn = fn; - native->status = SP_NATIVE_BOUND; + rt->UpdateNativeBinding(index, fn, 0, nullptr); } static cell_t PrintFloat(IPluginContext *cx, const cell_t *params) diff --git a/sourcepawn/jit/plugin-runtime.cpp b/sourcepawn/jit/plugin-runtime.cpp index 9f88feeb..cbaed60b 100644 --- a/sourcepawn/jit/plugin-runtime.cpp +++ b/sourcepawn/jit/plugin-runtime.cpp @@ -351,20 +351,32 @@ PluginRuntime::FindNativeByName(const char *name, uint32_t *index) int PluginRuntime::GetNativeByIndex(uint32_t index, sp_native_t **native) +{ + return SP_ERROR_PARAM; +} + +int +PluginRuntime::UpdateNativeBinding(uint32_t index, SPVM_NATIVE_FUNC pfn, uint32_t flags, void *data) { if (index >= m_plugin.num_natives) return SP_ERROR_INDEX; - if (native) - *native = &(m_plugin.natives[index]); + sp_native_t *native = &m_plugin.natives[index]; + native->pfn = pfn; + native->status = pfn + ? SP_NATIVE_BOUND + : SP_NATIVE_UNBOUND; + native->flags = flags; + native->user = data; return SP_ERROR_NONE; } -sp_native_t * -PluginRuntime::GetNativeByIndex(uint32_t index) +const sp_native_t * +PluginRuntime::GetNative(uint32_t index) { - assert(index < m_plugin.num_natives); + if (index >= m_plugin.num_natives) + return nullptr; return &m_plugin.natives[index]; } diff --git a/sourcepawn/jit/plugin-runtime.h b/sourcepawn/jit/plugin-runtime.h index 1ced62dc..27166ae8 100644 --- a/sourcepawn/jit/plugin-runtime.h +++ b/sourcepawn/jit/plugin-runtime.h @@ -60,7 +60,6 @@ class PluginRuntime virtual IPluginDebugInfo *GetDebugInfo(); virtual int FindNativeByName(const char *name, uint32_t *index); virtual int GetNativeByIndex(uint32_t index, sp_native_t **native); - virtual sp_native_t *GetNativeByIndex(uint32_t index); virtual uint32_t GetNativesNum(); virtual int FindPublicByName(const char *name, uint32_t *index); virtual int GetPublicByIndex(uint32_t index, sp_public_t **publicptr); @@ -83,6 +82,8 @@ class PluginRuntime void SetName(const char *name); unsigned GetNativeReplacement(size_t index); ScriptedInvoker *GetPublicFunction(size_t index); + int UpdateNativeBinding(uint32_t index, SPVM_NATIVE_FUNC pfn, uint32_t flags, void *data) KE_OVERRIDE; + const sp_native_t *GetNative(uint32_t index) KE_OVERRIDE; PluginContext *GetBaseContext(); const sp_plugin_t *plugin() const { diff --git a/sourcepawn/jit/x86/jit_x86.cpp b/sourcepawn/jit/x86/jit_x86.cpp index b66643f3..c064c8a7 100644 --- a/sourcepawn/jit/x86/jit_x86.cpp +++ b/sourcepawn/jit/x86/jit_x86.cpp @@ -1497,7 +1497,7 @@ Compiler::emitNativeCall(OPCODE op) __ subl(stk, dat); __ movl(Operand(eax, PluginContext::offsetOfSp()), stk); - sp_native_t *native = rt_->GetNativeByIndex(native_index); + const sp_native_t *native = rt_->GetNative(native_index); if ((native->status != SP_NATIVE_BOUND) || (native->flags & (SP_NTVFLAG_OPTIONAL | SP_NTVFLAG_EPHEMERAL))) {