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