sourcepawn/jit/BaseRuntime.cpp
author David Anderson <dvander@alliedmods.net>
Sun Oct 26 23:50:54 2008 -0500 (2008-10-26)
changeset 2377 6ee3bbd6fbdf
parent 2249 a1ce7e3f08b7
child 2378 d812052c5821
permissions -rw-r--r--
Fixed leaking relocation table memory in JIT.
dvander@2193
     1
#include <stdio.h>
dvander@2193
     2
#include <stdlib.h>
dvander@2193
     3
#include <string.h>
dvander@2226
     4
#include <assert.h>
dvander@2193
     5
#include "BaseRuntime.h"
dvander@2193
     6
#include "sp_vm_engine.h"
dvander@2193
     7
#include "x86/jit_x86.h"
dvander@2193
     8
#include "sp_vm_basecontext.h"
dvander@2193
     9
#include "engine2.h"
dvander@2193
    10
dvander@2193
    11
using namespace SourcePawn;
dvander@2193
    12
dvander@2226
    13
BaseRuntime::BaseRuntime() : m_Debug(&m_plugin), m_pPlugin(&m_plugin), m_pCtx(NULL), 
dvander@2226
    14
m_PubFuncs(NULL), m_PubJitFuncs(NULL), m_pCo(NULL), m_CompSerial(0)
dvander@2193
    15
{
dvander@2226
    16
	memset(&m_plugin, 0, sizeof(m_plugin));
dvander@2193
    17
dvander@2226
    18
	m_FuncCache = NULL;
dvander@2226
    19
	m_MaxFuncs = 0;
dvander@2226
    20
	m_NumFuncs = 0;
dvander@2193
    21
}
dvander@2193
    22
dvander@2193
    23
BaseRuntime::~BaseRuntime()
dvander@2193
    24
{
dvander@2226
    25
	for (uint32_t i = 0; i < m_pPlugin->num_publics; i++)
dvander@2193
    26
	{
dvander@2193
    27
		delete m_PubFuncs[i];
dvander@2193
    28
		m_PubFuncs[i] = NULL;
dvander@2193
    29
	}
dvander@2193
    30
	delete [] m_PubFuncs;
dvander@2226
    31
	delete [] m_PubJitFuncs;
dvander@2193
    32
dvander@2226
    33
	for (unsigned int i = 0; i < m_NumFuncs; i++)
dvander@2226
    34
	{
dvander@2226
    35
		delete m_FuncCache[i];
dvander@2226
    36
	}
dvander@2226
    37
	free(m_FuncCache);
dvander@2226
    38
dvander@2226
    39
	delete m_pCtx;
dvander@2377
    40
	if (m_pCo != NULL)
dvander@2377
    41
	{
dvander@2377
    42
		m_pCo->Abort();
dvander@2377
    43
	}
dvander@2193
    44
dvander@2193
    45
	free(m_pPlugin->base);
dvander@2193
    46
	delete [] m_pPlugin->memory;
dvander@2226
    47
	delete [] m_pPlugin->publics;
dvander@2226
    48
	delete [] m_pPlugin->pubvars;
dvander@2195
    49
	delete [] m_pPlugin->natives;
dvander@2226
    50
	free(m_pPlugin->name);
dvander@2226
    51
}
dvander@2226
    52
dvander@2226
    53
static cell_t InvalidNative(IPluginContext *pCtx, const cell_t *params)
dvander@2226
    54
{
dvander@2226
    55
	return pCtx->ThrowNativeErrorEx(SP_ERROR_INVALID_NATIVE, "Invalid native");
dvander@2193
    56
}
dvander@2193
    57
dvander@2226
    58
int BaseRuntime::CreateFromMemory(sp_file_hdr_t *hdr, uint8_t *base)
dvander@2193
    59
{
dvander@2226
    60
	int set_err;
dvander@2226
    61
	char *nameptr;
dvander@2226
    62
	uint8_t sectnum = 0;
dvander@2226
    63
	sp_plugin_t *plugin = m_pPlugin;
dvander@2226
    64
	sp_file_section_t *secptr = (sp_file_section_t *)(base + sizeof(sp_file_hdr_t));
dvander@2226
    65
dvander@2226
    66
	memset(plugin, 0, sizeof(sp_plugin_t));
dvander@2226
    67
dvander@2226
    68
	plugin->base = base;
dvander@2226
    69
	plugin->base_size = hdr->imagesize;
dvander@2226
    70
	set_err = SP_ERROR_NONE;
dvander@2226
    71
dvander@2226
    72
	/* We have to read the name section first */
dvander@2226
    73
	for (sectnum = 0; sectnum < hdr->sections; sectnum++)
dvander@2226
    74
	{
dvander@2226
    75
		nameptr = (char *)(base + hdr->stringtab + secptr[sectnum].nameoffs);
dvander@2226
    76
		if (strcmp(nameptr, ".names") == 0)
dvander@2226
    77
		{
dvander@2226
    78
			plugin->stringbase = (const char *)(base + secptr[sectnum].dataoffs);
dvander@2226
    79
			break;
dvander@2226
    80
		}
dvander@2226
    81
	}
dvander@2226
    82
dvander@2226
    83
	sectnum = 0;
dvander@2226
    84
dvander@2226
    85
	/* Now read the rest of the sections */
dvander@2226
    86
	while (sectnum < hdr->sections)
dvander@2226
    87
	{
dvander@2226
    88
		nameptr = (char *)(base + hdr->stringtab + secptr->nameoffs);
dvander@2226
    89
dvander@2226
    90
		if (!(plugin->pcode) && !strcmp(nameptr, ".code"))
dvander@2226
    91
		{
dvander@2226
    92
			sp_file_code_t *cod = (sp_file_code_t *)(base + secptr->dataoffs);
dvander@2226
    93
dvander@2226
    94
			if (cod->codeversion < SP_CODEVERS_JIT1)
dvander@2226
    95
			{
dvander@2226
    96
				return SP_ERROR_CODE_TOO_OLD;
dvander@2226
    97
			}
dvander@2226
    98
			else if (cod->codeversion > SP_CODEVERS_JIT2)
dvander@2226
    99
			{
dvander@2226
   100
				return SP_ERROR_CODE_TOO_NEW;
dvander@2226
   101
			}
dvander@2226
   102
dvander@2226
   103
			plugin->pcode = base + secptr->dataoffs + cod->code;
dvander@2226
   104
			plugin->pcode_size = cod->codesize;
dvander@2226
   105
			plugin->flags = cod->flags;
dvander@2226
   106
			plugin->pcode_version = cod->codeversion;
dvander@2226
   107
		}
dvander@2226
   108
		else if (!(plugin->data) && !strcmp(nameptr, ".data"))
dvander@2226
   109
		{
dvander@2226
   110
			sp_file_data_t *dat = (sp_file_data_t *)(base + secptr->dataoffs);
dvander@2226
   111
			plugin->data = base + secptr->dataoffs + dat->data;
dvander@2226
   112
			plugin->data_size = dat->datasize;
dvander@2226
   113
			plugin->mem_size = dat->memsize;
dvander@2226
   114
			plugin->memory = new uint8_t[plugin->mem_size];
dvander@2226
   115
			memcpy(plugin->memory, plugin->data, plugin->data_size);
dvander@2226
   116
		}
dvander@2226
   117
		else if ((plugin->publics == NULL) && !strcmp(nameptr, ".publics"))
dvander@2226
   118
		{
dvander@2226
   119
			sp_file_publics_t *publics;
dvander@2226
   120
dvander@2226
   121
			publics = (sp_file_publics_t *)(base + secptr->dataoffs);
dvander@2226
   122
			plugin->num_publics = secptr->size / sizeof(sp_file_publics_t);
dvander@2226
   123
dvander@2226
   124
			if (plugin->num_publics > 0)
dvander@2226
   125
			{
dvander@2226
   126
				plugin->publics = new sp_public_t[plugin->num_publics];
dvander@2226
   127
dvander@2226
   128
				for (uint32_t i = 0; i < plugin->num_publics; i++)
dvander@2226
   129
				{
dvander@2226
   130
					plugin->publics[i].code_offs = publics[i].address;
dvander@2226
   131
					plugin->publics[i].funcid = (i << 1) | 1;
dvander@2226
   132
					plugin->publics[i].name = plugin->stringbase + publics[i].name;
dvander@2226
   133
				}
dvander@2226
   134
			}
dvander@2226
   135
		}
dvander@2226
   136
		else if ((plugin->pubvars == NULL) && !strcmp(nameptr, ".pubvars"))
dvander@2226
   137
		{
dvander@2226
   138
			sp_file_pubvars_t *pubvars;
dvander@2226
   139
dvander@2226
   140
			pubvars = (sp_file_pubvars_t *)(base + secptr->dataoffs);
dvander@2226
   141
			plugin->num_pubvars = secptr->size / sizeof(sp_file_pubvars_t);
dvander@2226
   142
dvander@2226
   143
			if (plugin->num_pubvars > 0)
dvander@2226
   144
			{
dvander@2226
   145
				plugin->pubvars = new sp_pubvar_t[plugin->num_pubvars];
dvander@2226
   146
dvander@2226
   147
				for (uint32_t i = 0; i < plugin->num_pubvars; i++)
dvander@2226
   148
				{
dvander@2226
   149
					plugin->pubvars[i].name = plugin->stringbase + pubvars[i].name;
dvander@2226
   150
					plugin->pubvars[i].offs = (cell_t *)(plugin->memory + pubvars[i].address);
dvander@2226
   151
				}
dvander@2226
   152
			}
dvander@2226
   153
		}
dvander@2226
   154
		else if ((plugin->natives == NULL) && !strcmp(nameptr, ".natives"))
dvander@2226
   155
		{
dvander@2226
   156
			sp_file_natives_t *natives;
dvander@2226
   157
dvander@2226
   158
			natives = (sp_file_natives_t *)(base + secptr->dataoffs);
dvander@2226
   159
			plugin->num_natives = secptr->size / sizeof(sp_file_natives_t);
dvander@2226
   160
dvander@2226
   161
			if (plugin->num_natives > 0)
dvander@2226
   162
			{
dvander@2226
   163
				plugin->natives = new sp_native_t[plugin->num_natives];
dvander@2226
   164
dvander@2226
   165
				for (uint32_t i = 0; i < plugin->num_natives; i++)
dvander@2226
   166
				{
dvander@2226
   167
					plugin->natives[i].flags = 0;
dvander@2226
   168
					plugin->natives[i].pfn = InvalidNative;
dvander@2226
   169
					plugin->natives[i].status = SP_NATIVE_UNBOUND;
dvander@2226
   170
					plugin->natives[i].user = NULL;
dvander@2226
   171
					plugin->natives[i].name = plugin->stringbase + natives[i].name;
dvander@2226
   172
				}
dvander@2226
   173
			}
dvander@2226
   174
		}
dvander@2226
   175
		else if (!(plugin->debug.files) && !strcmp(nameptr, ".dbg.files"))
dvander@2226
   176
		{
dvander@2226
   177
			plugin->debug.files = (sp_fdbg_file_t *)(base + secptr->dataoffs);
dvander@2226
   178
		}
dvander@2226
   179
		else if (!(plugin->debug.lines) && !strcmp(nameptr, ".dbg.lines"))
dvander@2226
   180
		{
dvander@2226
   181
			plugin->debug.lines = (sp_fdbg_line_t *)(base + secptr->dataoffs);
dvander@2226
   182
		}
dvander@2226
   183
		else if (!(plugin->debug.symbols) && !strcmp(nameptr, ".dbg.symbols"))
dvander@2226
   184
		{
dvander@2226
   185
			plugin->debug.symbols = (sp_fdbg_symbol_t *)(base + secptr->dataoffs);
dvander@2226
   186
		}
dvander@2226
   187
		else if (!(plugin->debug.lines_num) && !strcmp(nameptr, ".dbg.info"))
dvander@2226
   188
		{
dvander@2226
   189
			sp_fdbg_info_t *inf = (sp_fdbg_info_t *)(base + secptr->dataoffs);
dvander@2226
   190
			plugin->debug.files_num = inf->num_files;
dvander@2226
   191
			plugin->debug.lines_num = inf->num_lines;
dvander@2226
   192
			plugin->debug.syms_num = inf->num_syms;
dvander@2226
   193
		}
dvander@2226
   194
		else if (!(plugin->debug.stringbase) && !strcmp(nameptr, ".dbg.strings"))
dvander@2226
   195
		{
dvander@2226
   196
			plugin->debug.stringbase = (const char *)(base + secptr->dataoffs);
dvander@2226
   197
		}
dvander@2226
   198
dvander@2226
   199
		secptr++;
dvander@2226
   200
		sectnum++;
dvander@2226
   201
	}
dvander@2226
   202
dvander@2226
   203
	if (plugin->pcode == NULL || plugin->data == NULL)
dvander@2226
   204
	{
dvander@2226
   205
		return SP_ERROR_FILE_FORMAT;
dvander@2226
   206
	}
dvander@2226
   207
dvander@2226
   208
	if ((plugin->flags & SP_FLAG_DEBUG) && (!(plugin->debug.files) || !(plugin->debug.lines) || !(plugin->debug.symbols)))
dvander@2226
   209
	{
dvander@2226
   210
		return SP_ERROR_FILE_FORMAT;
dvander@2226
   211
	}
dvander@2226
   212
dvander@2226
   213
	if (m_pPlugin->num_publics > 0)
dvander@2226
   214
	{
dvander@2226
   215
		m_PubFuncs = new CFunction *[m_pPlugin->num_publics];
dvander@2226
   216
		memset(m_PubFuncs, 0, sizeof(CFunction *) * m_pPlugin->num_publics);
dvander@2226
   217
		m_PubJitFuncs = new JitFunction *[m_pPlugin->num_publics];
dvander@2226
   218
		memset(m_PubJitFuncs, 0, sizeof(JitFunction *) * m_pPlugin->num_publics);
dvander@2226
   219
	}
dvander@2226
   220
dvander@2226
   221
	m_pPlugin->profiler = g_engine2.GetProfiler();
dvander@2226
   222
	m_pCtx = new BaseContext(this);
dvander@2226
   223
	m_pCo = g_Jit.StartCompilation(this);
dvander@2226
   224
dvander@2226
   225
	return SP_ERROR_NONE;
dvander@2193
   226
}
dvander@2193
   227
dvander@2193
   228
int BaseRuntime::FindNativeByName(const char *name, uint32_t *index)
dvander@2193
   229
{
dvander@2193
   230
	int high;
dvander@2193
   231
dvander@2226
   232
	high = m_pPlugin->num_natives - 1;
dvander@2193
   233
dvander@2226
   234
	for (uint32_t i=0; i<m_pPlugin->num_natives; i++)
dvander@2193
   235
	{
dvander@2193
   236
		if (strcmp(m_pPlugin->natives[i].name, name) == 0)
dvander@2193
   237
		{
dvander@2193
   238
			if (index)
dvander@2193
   239
			{
dvander@2193
   240
				*index = i;
dvander@2193
   241
			}
dvander@2193
   242
			return SP_ERROR_NONE;
dvander@2193
   243
		}
dvander@2193
   244
	}
dvander@2193
   245
dvander@2193
   246
	return SP_ERROR_NOT_FOUND;
dvander@2193
   247
}
dvander@2193
   248
dvander@2193
   249
int BaseRuntime::GetNativeByIndex(uint32_t index, sp_native_t **native)
dvander@2193
   250
{
dvander@2226
   251
	if (index >= m_pPlugin->num_natives)
dvander@2193
   252
	{
dvander@2193
   253
		return SP_ERROR_INDEX;
dvander@2193
   254
	}
dvander@2193
   255
dvander@2193
   256
	if (native)
dvander@2193
   257
	{
dvander@2193
   258
		*native = &(m_pPlugin->natives[index]);
dvander@2193
   259
	}
dvander@2193
   260
dvander@2193
   261
	return SP_ERROR_NONE;
dvander@2193
   262
}
dvander@2193
   263
dvander@2193
   264
dvander@2193
   265
uint32_t BaseRuntime::GetNativesNum()
dvander@2193
   266
{
dvander@2226
   267
	return m_pPlugin->num_natives;
dvander@2193
   268
}
dvander@2193
   269
dvander@2193
   270
int BaseRuntime::FindPublicByName(const char *name, uint32_t *index)
dvander@2193
   271
{
dvander@2193
   272
	int diff, high, low;
dvander@2193
   273
	uint32_t mid;
dvander@2193
   274
dvander@2226
   275
	high = m_pPlugin->num_publics - 1;
dvander@2193
   276
	low = 0;
dvander@2193
   277
dvander@2193
   278
	while (low <= high)
dvander@2193
   279
	{
dvander@2193
   280
		mid = (low + high) / 2;
dvander@2193
   281
		diff = strcmp(m_pPlugin->publics[mid].name, name);
dvander@2193
   282
		if (diff == 0)
dvander@2193
   283
		{
dvander@2193
   284
			if (index)
dvander@2193
   285
			{
dvander@2193
   286
				*index = mid;
dvander@2193
   287
			}
dvander@2193
   288
			return SP_ERROR_NONE;
dvander@2193
   289
		} else if (diff < 0) {
dvander@2193
   290
			low = mid + 1;
dvander@2193
   291
		} else {
dvander@2193
   292
			high = mid - 1;
dvander@2193
   293
		}
dvander@2193
   294
	}
dvander@2193
   295
dvander@2193
   296
	return SP_ERROR_NOT_FOUND;
dvander@2193
   297
}
dvander@2193
   298
dvander@2193
   299
int BaseRuntime::GetPublicByIndex(uint32_t index, sp_public_t **pblic)
dvander@2193
   300
{
dvander@2226
   301
	if (index >= m_pPlugin->num_publics)
dvander@2193
   302
	{
dvander@2193
   303
		return SP_ERROR_INDEX;
dvander@2193
   304
	}
dvander@2193
   305
dvander@2193
   306
	if (pblic)
dvander@2193
   307
	{
dvander@2193
   308
		*pblic = &(m_pPlugin->publics[index]);
dvander@2193
   309
	}
dvander@2193
   310
dvander@2193
   311
	return SP_ERROR_NONE;
dvander@2193
   312
}
dvander@2193
   313
dvander@2193
   314
uint32_t BaseRuntime::GetPublicsNum()
dvander@2193
   315
{
dvander@2226
   316
	return m_pPlugin->num_publics;
dvander@2193
   317
}
dvander@2193
   318
dvander@2193
   319
int BaseRuntime::GetPubvarByIndex(uint32_t index, sp_pubvar_t **pubvar)
dvander@2193
   320
{
dvander@2226
   321
	if (index >= m_pPlugin->num_pubvars)
dvander@2193
   322
	{
dvander@2193
   323
		return SP_ERROR_INDEX;
dvander@2193
   324
	}
dvander@2193
   325
dvander@2193
   326
	if (pubvar)
dvander@2193
   327
	{
dvander@2193
   328
		*pubvar = &(m_pPlugin->pubvars[index]);
dvander@2193
   329
	}
dvander@2193
   330
dvander@2193
   331
	return SP_ERROR_NONE;
dvander@2193
   332
}
dvander@2193
   333
dvander@2193
   334
int BaseRuntime::FindPubvarByName(const char *name, uint32_t *index)
dvander@2193
   335
{
dvander@2193
   336
	int diff, high, low;
dvander@2193
   337
	uint32_t mid;
dvander@2193
   338
dvander@2226
   339
	high = m_pPlugin->num_pubvars - 1;
dvander@2193
   340
	low = 0;
dvander@2193
   341
dvander@2193
   342
	while (low <= high)
dvander@2193
   343
	{
dvander@2193
   344
		mid = (low + high) / 2;
dvander@2193
   345
		diff = strcmp(m_pPlugin->pubvars[mid].name, name);
dvander@2193
   346
		if (diff == 0)
dvander@2193
   347
		{
dvander@2193
   348
			if (index)
dvander@2193
   349
			{
dvander@2193
   350
				*index = mid;
dvander@2193
   351
			}
dvander@2193
   352
			return SP_ERROR_NONE;
dvander@2226
   353
		}
dvander@2226
   354
		else if (diff < 0)
dvander@2226
   355
		{
dvander@2193
   356
			low = mid + 1;
dvander@2226
   357
		}
dvander@2226
   358
		else
dvander@2226
   359
		{
dvander@2193
   360
			high = mid - 1;
dvander@2193
   361
		}
dvander@2193
   362
	}
dvander@2193
   363
dvander@2193
   364
	return SP_ERROR_NOT_FOUND;
dvander@2193
   365
}
dvander@2193
   366
dvander@2193
   367
int BaseRuntime::GetPubvarAddrs(uint32_t index, cell_t *local_addr, cell_t **phys_addr)
dvander@2193
   368
{
dvander@2226
   369
	if (index >= m_pPlugin->num_pubvars)
dvander@2193
   370
	{
dvander@2193
   371
		return SP_ERROR_INDEX;
dvander@2193
   372
	}
dvander@2193
   373
dvander@2226
   374
	*local_addr = (uint8_t *)m_pPlugin->pubvars[index].offs - m_pPlugin->memory;
dvander@2193
   375
	*phys_addr = m_pPlugin->pubvars[index].offs;
dvander@2193
   376
dvander@2193
   377
	return SP_ERROR_NONE;
dvander@2193
   378
}
dvander@2193
   379
dvander@2193
   380
uint32_t BaseRuntime::GetPubVarsNum()
dvander@2193
   381
{
dvander@2226
   382
	return m_pPlugin->num_pubvars;
dvander@2193
   383
}
dvander@2193
   384
dvander@2193
   385
IPluginContext *BaseRuntime::GetDefaultContext()
dvander@2193
   386
{
dvander@2193
   387
	return m_pCtx;
dvander@2193
   388
}
dvander@2193
   389
dvander@2193
   390
IPluginDebugInfo *BaseRuntime::GetDebugInfo()
dvander@2193
   391
{
dvander@2193
   392
	return &m_Debug;
dvander@2193
   393
}
dvander@2193
   394
dvander@2193
   395
IPluginFunction *BaseRuntime::GetFunctionById(funcid_t func_id)
dvander@2193
   396
{
dvander@2193
   397
	CFunction *pFunc = NULL;
dvander@2193
   398
dvander@2193
   399
	if (func_id & 1)
dvander@2193
   400
	{
dvander@2193
   401
		func_id >>= 1;
dvander@2226
   402
		if (func_id >= m_pPlugin->num_publics)
dvander@2193
   403
		{
dvander@2193
   404
			return NULL;
dvander@2193
   405
		}
dvander@2193
   406
		pFunc = m_PubFuncs[func_id];
dvander@2193
   407
		if (!pFunc)
dvander@2193
   408
		{
dvander@2226
   409
			m_PubFuncs[func_id] = new CFunction(this, 
dvander@2193
   410
				(func_id << 1) | 1,
dvander@2193
   411
				func_id);
dvander@2193
   412
			pFunc = m_PubFuncs[func_id];
dvander@2193
   413
		}
dvander@2193
   414
	}
dvander@2193
   415
dvander@2193
   416
	return pFunc;
dvander@2193
   417
}
dvander@2193
   418
dvander@2193
   419
IPluginFunction *BaseRuntime::GetFunctionByName(const char *public_name)
dvander@2193
   420
{
dvander@2193
   421
	uint32_t index;
dvander@2193
   422
dvander@2193
   423
	if (FindPublicByName(public_name, &index) != SP_ERROR_NONE)
dvander@2193
   424
	{
dvander@2193
   425
		return NULL;
dvander@2193
   426
	}
dvander@2193
   427
dvander@2193
   428
	CFunction *pFunc = m_PubFuncs[index];
dvander@2193
   429
	if (!pFunc)
dvander@2193
   430
	{
dvander@2193
   431
		sp_public_t *pub = NULL;
dvander@2193
   432
		GetPublicByIndex(index, &pub);
dvander@2193
   433
		if (pub)
dvander@2193
   434
		{
dvander@2226
   435
			m_PubFuncs[index] = new CFunction(this, (index << 1) | 1, index);
dvander@2193
   436
		}
dvander@2193
   437
		pFunc = m_PubFuncs[index];
dvander@2193
   438
	}
dvander@2193
   439
dvander@2193
   440
	return pFunc;
dvander@2193
   441
}
dvander@2193
   442
dvander@2193
   443
bool BaseRuntime::IsDebugging()
dvander@2193
   444
{
dvander@2226
   445
	return true;
dvander@2193
   446
}
dvander@2193
   447
dvander@2193
   448
void BaseRuntime::SetPauseState(bool paused)
dvander@2193
   449
{
dvander@2193
   450
	if (paused)
dvander@2193
   451
	{
dvander@2193
   452
		m_pPlugin->run_flags |= SPFLAG_PLUGIN_PAUSED;
dvander@2193
   453
	}
dvander@2193
   454
	else
dvander@2193
   455
	{
dvander@2193
   456
		m_pPlugin->run_flags &= ~SPFLAG_PLUGIN_PAUSED;
dvander@2193
   457
	}
dvander@2193
   458
}
dvander@2193
   459
dvander@2193
   460
bool BaseRuntime::IsPaused()
dvander@2193
   461
{
dvander@2193
   462
	return ((m_pPlugin->run_flags & SPFLAG_PLUGIN_PAUSED) == SPFLAG_PLUGIN_PAUSED);
dvander@2193
   463
}
dvander@2193
   464
dvander@2193
   465
size_t BaseRuntime::GetMemUsage()
dvander@2193
   466
{
dvander@2193
   467
	size_t mem = 0;
dvander@2193
   468
dvander@2193
   469
	mem += sizeof(this);
dvander@2193
   470
	mem += sizeof(sp_plugin_t);
dvander@2193
   471
	mem += sizeof(BaseContext);
dvander@2193
   472
	mem += m_pPlugin->base_size;
dvander@2193
   473
dvander@2193
   474
	return mem;
dvander@2193
   475
}
dvander@2193
   476
dvander@2193
   477
BaseContext *BaseRuntime::GetBaseContext()
dvander@2193
   478
{
dvander@2193
   479
	return m_pCtx;
dvander@2193
   480
}
dvander@2193
   481
dvander@2226
   482
int BaseRuntime::ApplyCompilationOptions(ICompilation *co)
dvander@2226
   483
{
dvander@2226
   484
	if (co == NULL)
dvander@2226
   485
	{
dvander@2226
   486
		return SP_ERROR_NONE;
dvander@2226
   487
	}
dvander@2226
   488
dvander@2226
   489
	m_pCo = g_Jit.ApplyOptions(m_pCo, co);
dvander@2249
   490
	m_pPlugin->prof_flags = ((CompData *)m_pCo)->profile;
dvander@2226
   491
dvander@2226
   492
	return SP_ERROR_NONE;
dvander@2226
   493
}
dvander@2226
   494
dvander@2226
   495
JitFunction *BaseRuntime::GetJittedFunction(uint32_t idx)
dvander@2226
   496
{
dvander@2226
   497
	assert(idx <= m_NumFuncs);
dvander@2226
   498
dvander@2226
   499
	if (idx == 0 || idx > m_NumFuncs)
dvander@2226
   500
	{
dvander@2226
   501
		return NULL;
dvander@2226
   502
	}
dvander@2226
   503
dvander@2226
   504
	return m_FuncCache[idx - 1];
dvander@2226
   505
}
dvander@2226
   506
dvander@2226
   507
uint32_t BaseRuntime::AddJittedFunction(JitFunction *fn)
dvander@2226
   508
{
dvander@2226
   509
	if (m_NumFuncs + 1 > m_MaxFuncs)
dvander@2226
   510
	{
dvander@2226
   511
		if (m_MaxFuncs == 0)
dvander@2226
   512
		{
dvander@2226
   513
			m_MaxFuncs = 8;
dvander@2226
   514
		}
dvander@2226
   515
		else
dvander@2226
   516
		{
dvander@2226
   517
			m_MaxFuncs *= 2;
dvander@2226
   518
		}
dvander@2226
   519
dvander@2226
   520
		m_FuncCache = (JitFunction **)realloc(
dvander@2226
   521
			m_FuncCache,
dvander@2226
   522
			sizeof(JitFunction *) * m_MaxFuncs);
dvander@2226
   523
	}
dvander@2226
   524
dvander@2226
   525
	m_FuncCache[m_NumFuncs++] = fn;
dvander@2226
   526
dvander@2226
   527
	return m_NumFuncs;
dvander@2226
   528
}