core/systems/PluginSys.cpp
changeset 2193 db7c6362f3f2
parent 2113 8e8b28162e23
child 2210 79822782197b
     1.1 --- a/core/systems/PluginSys.cpp	Thu Jul 10 01:26:02 2008 +0000
     1.2 +++ b/core/systems/PluginSys.cpp	Fri Jul 11 08:18:43 2008 +0000
     1.3 @@ -58,7 +58,7 @@
     1.4  	m_type = PluginType_Private;
     1.5  	m_status = Plugin_Uncompiled;
     1.6  	m_serial = ++MySerial;
     1.7 -	m_plugin = NULL;
     1.8 +	m_pRuntime = NULL;
     1.9  	m_errormsg[256] = '\0';
    1.10  	snprintf(m_filename, sizeof(m_filename), "%s", file);
    1.11  	m_handle = 0;
    1.12 @@ -82,27 +82,12 @@
    1.13  		g_ShareSys.DestroyIdentity(m_ident);
    1.14  	}
    1.15  
    1.16 -	if (m_ctx.base)
    1.17 -	{
    1.18 -		delete m_ctx.base;
    1.19 -		m_ctx.base = NULL;
    1.20 -	}
    1.21 -	if (m_ctx.ctx)
    1.22 +	if (m_pRuntime != NULL)
    1.23  	{
    1.24 -		m_ctx.vm->FreeContext(m_ctx.ctx);
    1.25 -		m_ctx.ctx = NULL;
    1.26 -	}
    1.27 -	if (m_ctx.co)
    1.28 -	{
    1.29 -		m_ctx.vm->AbortCompilation(m_ctx.co);
    1.30 -		m_ctx.co = NULL;
    1.31 +		delete m_pRuntime;
    1.32 +		m_pRuntime = NULL;
    1.33  	}
    1.34  
    1.35 -	if (m_plugin)
    1.36 -	{
    1.37 -		g_pSourcePawn->FreeFromMemory(m_plugin);
    1.38 -		m_plugin = NULL;
    1.39 -	}
    1.40  	if (m_pProps)
    1.41  	{
    1.42  		sm_trie_destroy(m_pProps);
    1.43 @@ -125,7 +110,8 @@
    1.44  	{
    1.45  		m_ident = g_ShareSys.CreateIdentity(g_PluginIdent, this);
    1.46  		m_handle = g_HandleSys.CreateHandle(g_PluginType, this, g_PluginSys.GetIdentity(), g_PluginSys.GetIdentity(), NULL);
    1.47 -		m_ctx.base->SetIdentity(m_ident);
    1.48 +		m_pRuntime->GetDefaultContext()->SetKey(1, m_ident);
    1.49 +		m_pRuntime->GetDefaultContext()->SetKey(2, (IPlugin *)this);
    1.50  	}
    1.51  }
    1.52  
    1.53 @@ -157,37 +143,6 @@
    1.54  		base_size += (*i).size();
    1.55  	}
    1.56  
    1.57 -	if (m_plugin != NULL)
    1.58 -	{
    1.59 -		base_size += sizeof(sp_plugin_t);
    1.60 -		base_size += m_plugin->data_size;
    1.61 -		base_size += m_plugin->pcode_size;
    1.62 -		base_size += (m_plugin->info.natives_num * sizeof(sp_file_natives_t));
    1.63 -		base_size += (m_plugin->info.publics_num * sizeof(sp_file_publics_t));
    1.64 -		base_size += (m_plugin->info.pubvars_num * sizeof(sp_file_pubvars_t));
    1.65 -		base_size += (m_plugin->debug.files_num * sizeof(sp_fdbg_file_t));
    1.66 -		base_size += (m_plugin->debug.lines_num * sizeof(sp_fdbg_line_t));
    1.67 -		base_size += (m_plugin->debug.syms_num * sizeof(sp_fdbg_symbol_t));
    1.68 -		/* We can't get strtab size, oh well. */
    1.69 -	}
    1.70 -
    1.71 -	if (m_ctx.base != NULL)
    1.72 -	{
    1.73 -		base_size += sizeof(BaseContext);
    1.74 -		base_size += m_ctx.base->GetPublicsNum() * sizeof(CFunction);
    1.75 -	}
    1.76 -	if (m_ctx.ctx != NULL)
    1.77 -	{
    1.78 -		base_size += m_ctx.ctx->mem_size;
    1.79 -		base_size += (m_plugin->debug.files_num * sizeof(sp_debug_file_t));
    1.80 -		base_size += (m_plugin->debug.lines_num * sizeof(sp_debug_line_t));
    1.81 -		base_size += (m_plugin->debug.syms_num * sizeof(sp_debug_symbol_t));
    1.82 -		base_size += (m_plugin->info.pubvars_num * sizeof(sp_pubvar_t));
    1.83 -		base_size += (m_plugin->info.publics_num * sizeof(sp_public_t));
    1.84 -		base_size += (m_plugin->info.natives_num * sizeof(sp_native_t));
    1.85 -		/* We also don't know the JIT code size, oh well. */
    1.86 -	}
    1.87 -
    1.88  	return base_size;
    1.89  }
    1.90  
    1.91 @@ -214,23 +169,6 @@
    1.92  		return pPlugin;
    1.93  	}
    1.94  
    1.95 -	int err;
    1.96 -	sp_plugin_t *pl = g_pSourcePawn->LoadFromFilePointer(fp, &err);
    1.97 -	if (pl == NULL)
    1.98 -	{
    1.99 -		fclose(fp);
   1.100 -		if (error)
   1.101 -		{
   1.102 -			snprintf(error, maxlength, "Error %d while parsing plugin", err);
   1.103 -		}
   1.104 -		pPlugin->m_status = Plugin_BadLoad;
   1.105 -		return pPlugin;
   1.106 -	}
   1.107 -
   1.108 -	fclose(fp);
   1.109 -
   1.110 -	pPlugin->m_plugin = pl;
   1.111 -
   1.112  	return pPlugin;
   1.113  }
   1.114  
   1.115 @@ -251,69 +189,9 @@
   1.116  	return sm_trie_insert(m_pProps, prop, ptr);
   1.117  }
   1.118  
   1.119 -ICompilation *CPlugin::StartMyCompile(IVirtualMachine *vm)
   1.120 -{
   1.121 -	if (!m_plugin)
   1.122 -	{
   1.123 -		return NULL;
   1.124 -	}
   1.125 -
   1.126 -	/* :NOTICE: We will eventually need to change these natives
   1.127 -	 * for swapping in new contexts
   1.128 -	 */
   1.129 -	if (m_ctx.co || m_ctx.ctx)
   1.130 -	{
   1.131 -		return NULL;
   1.132 -	}
   1.133 -
   1.134 -	m_status = Plugin_Uncompiled;
   1.135 -
   1.136 -	m_ctx.vm = vm;
   1.137 -	m_ctx.co = vm->StartCompilation(m_plugin);
   1.138 -
   1.139 -	return m_ctx.co;
   1.140 -}
   1.141 -
   1.142 -void CPlugin::CancelMyCompile()
   1.143 +IPluginRuntime *CPlugin::GetRuntime()
   1.144  {
   1.145 -	if (!m_ctx.co)
   1.146 -	{
   1.147 -		return;
   1.148 -	}
   1.149 -
   1.150 -	m_ctx.vm->AbortCompilation(m_ctx.co);
   1.151 -	m_ctx.co = NULL;
   1.152 -	m_ctx.vm = NULL;
   1.153 -}
   1.154 -
   1.155 -bool CPlugin::FinishMyCompile(char *error, size_t maxlength)
   1.156 -{
   1.157 -	if (!m_ctx.co)
   1.158 -	{
   1.159 -		return false;
   1.160 -	}
   1.161 -
   1.162 -	int err;
   1.163 -	m_ctx.ctx = m_ctx.vm->CompileToContext(m_ctx.co, &err);
   1.164 -	if (!m_ctx.ctx)
   1.165 -	{
   1.166 -		memset(&m_ctx, 0, sizeof(m_ctx));
   1.167 -		if (error)
   1.168 -		{
   1.169 -			snprintf(error, maxlength, "JIT failed to compile (error %d)", err);
   1.170 -		}
   1.171 -		return false;
   1.172 -	}
   1.173 -
   1.174 -	m_ctx.base = new BaseContext(m_ctx.ctx);
   1.175 -	m_ctx.ctx->user[SM_CONTEXTVAR_MYSELF] = (void *)this;
   1.176 -
   1.177 -	m_status = Plugin_Created;
   1.178 -	m_ctx.co = NULL;
   1.179 -
   1.180 -	UpdateInfo();
   1.181 -
   1.182 -	return true;
   1.183 +	return m_pRuntime;
   1.184  }
   1.185  
   1.186  void CPlugin::SetErrorState(PluginStatus status, const char *error_fmt, ...)
   1.187 @@ -332,9 +210,9 @@
   1.188  	vsnprintf(m_errormsg, sizeof(m_errormsg), error_fmt, ap);
   1.189  	va_end(ap);
   1.190  
   1.191 -	if (m_ctx.ctx)
   1.192 +	if (m_pRuntime != NULL)
   1.193  	{
   1.194 -		m_ctx.ctx->flags |= SPFLAG_PLUGIN_PAUSED;
   1.195 +		m_pRuntime->SetPauseState(true);
   1.196  	}
   1.197  }
   1.198  
   1.199 @@ -415,7 +293,7 @@
   1.200  	m_status = Plugin_Running;
   1.201  
   1.202  	cell_t result;
   1.203 -	IPluginFunction *pFunction = m_ctx.base->GetFunctionByName("OnPluginStart");
   1.204 +	IPluginFunction *pFunction = m_pRuntime->GetFunctionByName("OnPluginStart");
   1.205  	if (!pFunction)
   1.206  	{
   1.207  		return;
   1.208 @@ -436,7 +314,7 @@
   1.209  	}
   1.210  
   1.211  	cell_t result;
   1.212 -	IPluginFunction *pFunction = m_ctx.base->GetFunctionByName("OnPluginEnd");
   1.213 +	IPluginFunction *pFunction = m_pRuntime->GetFunctionByName("OnPluginEnd");
   1.214  	if (!pFunction)
   1.215  	{
   1.216  		return;
   1.217 @@ -460,7 +338,7 @@
   1.218  	m_bGotAllLoaded = true;
   1.219  
   1.220  	cell_t result;
   1.221 -	IPluginFunction *pFunction = m_ctx.base->GetFunctionByName("OnAllPluginsLoaded");
   1.222 +	IPluginFunction *pFunction = m_pRuntime->GetFunctionByName("OnAllPluginsLoaded");
   1.223  	if (pFunction != NULL)
   1.224  	{
   1.225  		pFunction->Execute(&result);
   1.226 @@ -468,7 +346,7 @@
   1.227  
   1.228  	if (g_OnMapStarted)
   1.229  	{
   1.230 -		if ((pFunction = m_ctx.base->GetFunctionByName("OnMapStart")) != NULL)
   1.231 +		if ((pFunction = m_pRuntime->GetFunctionByName("OnMapStart")) != NULL)
   1.232  		{
   1.233  			pFunction->Execute(NULL);
   1.234  		}
   1.235 @@ -491,7 +369,7 @@
   1.236  
   1.237  	int err;
   1.238  	cell_t result;
   1.239 -	IPluginFunction *pFunction = m_ctx.base->GetFunctionByName("AskPluginLoad");
   1.240 +	IPluginFunction *pFunction = m_pRuntime->GetFunctionByName("AskPluginLoad");
   1.241  
   1.242  	if (!pFunction)
   1.243  	{
   1.244 @@ -515,19 +393,24 @@
   1.245  	return true;
   1.246  }
   1.247  
   1.248 -const sp_plugin_t *CPlugin::GetPluginStructure()
   1.249 +void *CPlugin::GetPluginStructure()
   1.250  {
   1.251 -	return m_plugin;
   1.252 +	return NULL;
   1.253  }
   1.254  
   1.255  IPluginContext *CPlugin::GetBaseContext()
   1.256  {
   1.257 -	return m_ctx.base;
   1.258 +	if (m_pRuntime == NULL)
   1.259 +	{
   1.260 +		return NULL;
   1.261 +	}
   1.262 +
   1.263 +	return m_pRuntime->GetDefaultContext();
   1.264  }
   1.265  
   1.266  sp_context_t *CPlugin::GetContext()
   1.267  {
   1.268 -	return m_ctx.ctx;
   1.269 +	return NULL;
   1.270  }
   1.271  
   1.272  const char *CPlugin::GetFilename()
   1.273 @@ -557,12 +440,12 @@
   1.274  
   1.275  bool CPlugin::IsDebugging()
   1.276  {
   1.277 -	if (!m_ctx.ctx)
   1.278 +	if (m_pRuntime == NULL)
   1.279  	{
   1.280  		return false;
   1.281  	}
   1.282  
   1.283 -	return ((m_ctx.ctx->flags & SP_FLAG_DEBUG) == SP_FLAG_DEBUG);
   1.284 +	return m_pRuntime->IsDebugging();
   1.285  }
   1.286  
   1.287  void CPlugin::LibraryActions(bool dropping)
   1.288 @@ -590,7 +473,7 @@
   1.289  		LibraryActions(true);
   1.290  	}
   1.291  
   1.292 -	IPluginFunction *pFunction = m_ctx.base->GetFunctionByName("OnPluginPauseChange");
   1.293 +	IPluginFunction *pFunction = m_pRuntime->GetFunctionByName("OnPluginPauseChange");
   1.294  	if (pFunction)
   1.295  	{
   1.296  		cell_t result;
   1.297 @@ -601,10 +484,10 @@
   1.298  	if (paused)
   1.299  	{
   1.300  		m_status = Plugin_Paused;
   1.301 -		m_ctx.ctx->flags |= SPFLAG_PLUGIN_PAUSED;
   1.302 +		m_pRuntime->SetPauseState(true);
   1.303  	} else {
   1.304  		m_status = Plugin_Running;
   1.305 -		m_ctx.ctx->flags &= ~SPFLAG_PLUGIN_PAUSED;
   1.306 +		m_pRuntime->SetPauseState(false);
   1.307  	}
   1.308  
   1.309  	g_PluginSys._SetPauseState(this, paused);
   1.310 @@ -652,8 +535,9 @@
   1.311  		return false;
   1.312  	}
   1.313  
   1.314 -	ICompilation *co = g_pVM->StartCompilation(m_ctx.ctx->plugin);
   1.315 -	if (!g_pVM->SetCompilationOption(co, "debug", (debug) ? "1" : "0"))
   1.316 +	ICompilation *co = g_pSourcePawn2->StartCompilation();
   1.317 +
   1.318 +	if (!co->SetOption("debug", (debug) ? "1" : "0"))
   1.319  	{
   1.320  		if (error)
   1.321  		{
   1.322 @@ -662,32 +546,7 @@
   1.323  		return false;
   1.324  	}
   1.325  
   1.326 -	sp_context_t *new_ctx = g_pVM->CompileToContext(co, &err);
   1.327 -
   1.328 -	if (new_ctx)
   1.329 -	{
   1.330 -		memcpy(new_ctx->memory, m_ctx.ctx->memory, m_ctx.ctx->mem_size);
   1.331 -		new_ctx->hp = m_ctx.ctx->hp;
   1.332 -		new_ctx->sp = m_ctx.ctx->sp;
   1.333 -		new_ctx->frm = m_ctx.ctx->frm;
   1.334 -		new_ctx->dbreak = m_ctx.ctx->dbreak;
   1.335 -		new_ctx->context = m_ctx.ctx->context;
   1.336 -		memcpy(new_ctx->user, m_ctx.ctx->user, sizeof(m_ctx.ctx->user));
   1.337 -
   1.338 -		uint32_t nativeCount = m_plugin->info.natives_num;
   1.339 -		for (uint32_t i=0; i<nativeCount; i++)
   1.340 -		{
   1.341 -			new_ctx->natives[i].pfn = m_ctx.ctx->natives[i].pfn;
   1.342 -			new_ctx->natives[i].status = m_ctx.ctx->natives[i].status;
   1.343 -		}
   1.344 -
   1.345 -		g_pVM->FreeContext(m_ctx.ctx);
   1.346 -		m_ctx.ctx = new_ctx;
   1.347 -		m_ctx.base->SetContext(new_ctx);
   1.348 -
   1.349 -		UpdateInfo();
   1.350 -	}
   1.351 -	else
   1.352 +	if ((err = m_pRuntime->ApplyCompilationOptions(co)) != SP_ERROR_NONE)
   1.353  	{
   1.354  		if (error)
   1.355  		{
   1.356 @@ -696,6 +555,8 @@
   1.357  		return false;
   1.358  	}
   1.359  
   1.360 +	UpdateInfo();
   1.361 +
   1.362  	return true;
   1.363  }
   1.364  
   1.365 @@ -741,7 +602,7 @@
   1.366  
   1.367  void CPlugin::DependencyDropped(CPlugin *pOwner)
   1.368  {
   1.369 -	if (!m_ctx.ctx)
   1.370 +	if (!m_pRuntime)
   1.371  	{
   1.372  		return;
   1.373  	}
   1.374 @@ -771,12 +632,12 @@
   1.375  	{
   1.376  		pNative = (*iter);
   1.377  		/* Find this native! */
   1.378 -		if (m_ctx.base->FindNativeByName(pNative->name, &idx) != SP_ERROR_NONE)
   1.379 +		if (m_pRuntime->FindNativeByName(pNative->name, &idx) != SP_ERROR_NONE)
   1.380  		{
   1.381  			continue;
   1.382  		}
   1.383  		/* Unbind it */
   1.384 -		m_ctx.base->GetNativeByIndex(idx, &native);
   1.385 +		m_pRuntime->GetNativeByIndex(idx, &native);
   1.386  		native->pfn = NULL;
   1.387  		native->status = SP_NATIVE_UNBOUND;
   1.388  		unbound++;
   1.389 @@ -1047,6 +908,7 @@
   1.390  		return LoadRes_NeverLoad;
   1.391  	}
   1.392  
   1.393 +	int err;
   1.394  	bool no_load = false;
   1.395  	PluginSettings *pset;
   1.396  	unsigned int setcount = m_PluginInfo.GetSettingsNum();
   1.397 @@ -1102,7 +964,7 @@
   1.398  
   1.399  	if (pPlugin->m_status == Plugin_Uncompiled)
   1.400  	{
   1.401 -		co = pPlugin->StartMyCompile(g_pVM);
   1.402 +		co = g_pSourcePawn2->StartCompilation();
   1.403  	}
   1.404  
   1.405  	for (unsigned int i=0; i<setcount; i++)
   1.406 @@ -1122,13 +984,13 @@
   1.407  				{
   1.408  					continue;
   1.409  				}
   1.410 -				if (!g_pVM->SetCompilationOption(co, key, val))
   1.411 +				if ((err = co->SetOption(key, val)) == SP_ERROR_NONE)
   1.412  				{
   1.413  					if (error)
   1.414  					{
   1.415  						snprintf(error, maxlength, "Unable to set JIT option (key \"%s\") (value \"%s\")", key, val);
   1.416  					}
   1.417 -					pPlugin->CancelMyCompile();
   1.418 +					co->Abort();
   1.419  					co = NULL;
   1.420  					break;
   1.421  				}
   1.422 @@ -1137,10 +999,25 @@
   1.423  	}
   1.424  
   1.425  	/* Do the actual compiling */
   1.426 -	if (co)
   1.427 +	if (co != NULL)
   1.428  	{
   1.429 -		pPlugin->FinishMyCompile(error, maxlength);
   1.430 -		co = NULL;
   1.431 +		char fullpath[PLATFORM_MAX_PATH];
   1.432 +		g_SourceMod.BuildPath(Path_SM, fullpath, sizeof(fullpath), "plugins/%s", pPlugin->m_filename);
   1.433 +
   1.434 +		pPlugin->m_pRuntime = g_pSourcePawn2->LoadPlugin(co, fullpath, &err);
   1.435 +		if (pPlugin->m_pRuntime == NULL)
   1.436 +		{
   1.437 +			snprintf(error, 
   1.438 +				maxlength, 
   1.439 +				"Unable to load plugin (error %d: %s)", 
   1.440 +				err, 
   1.441 +				g_pSourcePawn2->GetErrorString(err));
   1.442 +		}
   1.443 +		else
   1.444 +		{
   1.445 +			pPlugin->UpdateInfo();
   1.446 +			pPlugin->m_status = Plugin_Created;
   1.447 +		}
   1.448  	}
   1.449  
   1.450  	/* Get the status */
   1.451 @@ -1321,7 +1198,7 @@
   1.452  				{
   1.453  					cell_t res;
   1.454  					pFunc->Execute(&res);
   1.455 -					if (pPlugin->GetContext()->n_err != SP_ERROR_NONE)
   1.456 +					if (pPlugin->GetBaseContext()->GetLastNativeError() != SP_ERROR_NONE)
   1.457  					{
   1.458  						if (error)
   1.459  						{
   1.460 @@ -1448,7 +1325,7 @@
   1.461  					{
   1.462  						cell_t res;
   1.463  						pFunc->Execute(&res);
   1.464 -						if (pPlugin->GetContext()->n_err != SP_ERROR_NONE)
   1.465 +						if (pPlugin->GetBaseContext()->GetLastNativeError() != SP_ERROR_NONE)
   1.466  						{
   1.467  							if (error)
   1.468  							{
   1.469 @@ -1615,9 +1492,9 @@
   1.470  	{
   1.471  		/* If we got here, all natives are okay again! */
   1.472  		pPlugin->m_status = Plugin_Running;
   1.473 -		if ((pPlugin->m_ctx.ctx->flags & SPFLAG_PLUGIN_PAUSED) == SPFLAG_PLUGIN_PAUSED)
   1.474 +		if (pPlugin->m_pRuntime->IsPaused())
   1.475  		{
   1.476 -			pPlugin->m_ctx.ctx->flags &= ~SPFLAG_PLUGIN_PAUSED;
   1.477 +			pPlugin->m_pRuntime->SetPauseState(false);
   1.478  			_SetPauseState(pPlugin, false);
   1.479  		}
   1.480  	}
   1.481 @@ -1687,8 +1564,22 @@
   1.482  
   1.483  IPlugin *CPluginManager::FindPluginByContext(const sp_context_t *ctx)
   1.484  {
   1.485 -	IPlugin *pl = (IPlugin *)ctx->user[SM_CONTEXTVAR_MYSELF];
   1.486 -	return pl;
   1.487 +	IPlugin *pPlugin;
   1.488 +	IPluginContext *pContext;
   1.489 +
   1.490 +	pContext = reinterpret_cast<IPluginContext *>(const_cast<sp_context_t *>(ctx));
   1.491 +
   1.492 +	if (pContext->GetKey(2, (void **)&pPlugin))
   1.493 +	{
   1.494 +		return pPlugin;
   1.495 +	}
   1.496 +
   1.497 +	return NULL;
   1.498 +}
   1.499 +
   1.500 +CPlugin *CPluginManager::GetPluginByCtx(const sp_context_t *ctx)
   1.501 +{
   1.502 +	return (CPlugin *)FindPluginByContext(ctx);
   1.503  }
   1.504  
   1.505  unsigned int CPluginManager::GetPluginCount()