1.1 --- a/core/systems/ExtensionSys.cpp Sat Nov 17 02:54:44 2007 +0000
1.2 +++ b/core/systems/ExtensionSys.cpp Sat Nov 17 04:31:01 2007 +0000
1.3 @@ -285,7 +285,22 @@
1.4 if ((*iter).pl == pPlugin)
1.5 {
1.6 iter = m_WeakNatives.erase(iter);
1.7 - } else {
1.8 + }
1.9 + else
1.10 + {
1.11 + iter++;
1.12 + }
1.13 + }
1.14 +
1.15 + iter = m_ReplacedNatives.begin();
1.16 + while (iter != m_ReplacedNatives.end())
1.17 + {
1.18 + if ((*iter).pl == pPlugin)
1.19 + {
1.20 + iter = m_ReplacedNatives.erase(iter);
1.21 + }
1.22 + else
1.23 + {
1.24 iter++;
1.25 }
1.26 }
1.27 @@ -703,6 +718,7 @@
1.28 uint32_t natives = pContext->GetNativesNum();
1.29 sp_native_t *native;
1.30 sm_extnative_t *x_native;
1.31 + sm_repnative_t *r_native;
1.32 for (uint32_t i=0; i<natives; i++)
1.33 {
1.34 /* Make sure the native is valid */
1.35 @@ -710,11 +726,26 @@
1.36 {
1.37 continue;
1.38 }
1.39 +
1.40 /* Make sure the native is not already bound */
1.41 if (native->status == SP_NATIVE_BOUND)
1.42 {
1.43 + /* If it is bound, see if there is a replacement. */
1.44 + if ((r_native = m_RepNatives.retrieve(native->name)) == NULL)
1.45 + {
1.46 + continue;
1.47 + }
1.48 +
1.49 + /* Rewrite the address. Whee! */
1.50 + native->pfn = r_native->info.func;
1.51 +
1.52 + /* Make sure this will unload safely */
1.53 + WeakNative wn((CPlugin *)pPlugin, i);
1.54 + r_native->owner->m_ReplacedNatives.push_back(wn);
1.55 +
1.56 continue;
1.57 }
1.58 +
1.59 /* See if we've got this native in our cache */
1.60 if ((x_native = m_ExtNatives.retrieve(native->name)) == NULL)
1.61 {
1.62 @@ -789,7 +820,7 @@
1.63 g_PluginSys.OnLibraryAction((*s_iter).c_str(), false, true);
1.64 }
1.65
1.66 - /* Unbound weak natives */
1.67 + /* Unbind weak natives */
1.68 List<WeakNative>::iterator wkn_iter;
1.69 for (wkn_iter=pExt->m_WeakNatives.begin(); wkn_iter!=pExt->m_WeakNatives.end(); wkn_iter++)
1.70 {
1.71 @@ -798,6 +829,21 @@
1.72 ctx->natives[wkn.idx].status = SP_NATIVE_UNBOUND;
1.73 }
1.74
1.75 + /* Unbind replacement natives, link them back to their originals */
1.76 + for (wkn_iter = pExt->m_ReplacedNatives.begin();
1.77 + wkn_iter != pExt->m_ReplacedNatives.end();
1.78 + wkn_iter++)
1.79 + {
1.80 + WeakNative & wkn = (*wkn_iter);
1.81 + sp_context_t *ctx = wkn.pl->GetContext();
1.82 + sm_repnative_t *r_native = m_RepNatives.retrieve(ctx->natives[wkn.idx].name);
1.83 + if (r_native == NULL || ctx->natives[wkn.idx].pfn != r_native->info.func)
1.84 + {
1.85 + continue;
1.86 + }
1.87 + ctx->natives[wkn.idx].pfn = r_native->original;
1.88 + }
1.89 +
1.90 /* Notify and/or unload all dependencies */
1.91 List<CExtension *>::iterator c_iter;
1.92 CExtension *pDep;
1.93 @@ -871,6 +917,22 @@
1.94 }
1.95 }
1.96
1.97 + /* Unbind our replacement natives */
1.98 + List<sm_repnative_t>::iterator rep_iter = m_RepNativeList.begin();
1.99 + while (rep_iter != m_RepNativeList.end())
1.100 + {
1.101 + sm_repnative_t & r_native = (*rep_iter);
1.102 + if (r_native.owner == pExt)
1.103 + {
1.104 + m_RepNatives.remove(r_native.info.name);
1.105 + rep_iter = m_RepNativeList.erase(rep_iter);
1.106 + }
1.107 + else
1.108 + {
1.109 + rep_iter++;
1.110 + }
1.111 + }
1.112 +
1.113 /* Tell it to unload */
1.114 pAPI = pExt->GetAPI();
1.115 pAPI->OnExtensionUnload();
1.116 @@ -919,6 +981,25 @@
1.117 }
1.118 }
1.119
1.120 +void CExtensionManager::OverrideNatives(IExtension *myself, const sp_nativeinfo_t *natives)
1.121 +{
1.122 + SPVM_NATIVE_FUNC orig;
1.123 +
1.124 + for (unsigned int i = 0; natives[i].func != NULL && natives[i].name != NULL; i++)
1.125 + {
1.126 + if ((orig = g_PluginSys.FindCoreNative(natives[i].name)) == NULL)
1.127 + {
1.128 + continue;
1.129 + }
1.130 + sm_repnative_t rep;
1.131 + rep.info = natives[i];
1.132 + rep.owner = (CExtension *)myself;
1.133 + rep.original = orig;
1.134 + m_RepNativeList.push_back(rep);
1.135 + m_RepNatives.insert(natives[i].name, rep);
1.136 + }
1.137 +}
1.138 +
1.139 void CExtensionManager::MarkAllLoaded()
1.140 {
1.141 List<CExtension *>::iterator iter;