sourcepawn/jit/BaseRuntime.cpp
author GoD-Tony <aangione@gmail.com>
Sun Aug 04 10:03:40 2013 -0400 (2013-08-04)
changeset 3971 d2e8100b2814
parent 3651 23b839141e74
child 3977 fca2b54741ca
permissions -rw-r--r--
Added ISDKHooks interface with entity listeners (bug 5602, r=psychonic).
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
asherkin@3651
   222
	if ((plugin->flags & SP_FLAG_DEBUG) && (
asherkin@3651
   223
		!(plugin->debug.files) || 
asherkin@3651
   224
		!(plugin->debug.lines) || 
asherkin@3651
   225
		!(plugin->debug.symbols) || 
asherkin@3651
   226
		!(plugin->debug.stringbase) ))
dvander@2226
   227
	{
dvander@2226
   228
		return SP_ERROR_FILE_FORMAT;
dvander@2226
   229
	}
dvander@2226
   230
dvander@2226
   231
	if (m_pPlugin->num_publics > 0)
dvander@2226
   232
	{
dvander@2226
   233
		m_PubFuncs = new CFunction *[m_pPlugin->num_publics];
dvander@2226
   234
		memset(m_PubFuncs, 0, sizeof(CFunction *) * m_pPlugin->num_publics);
dvander@2226
   235
		m_PubJitFuncs = new JitFunction *[m_pPlugin->num_publics];
dvander@2226
   236
		memset(m_PubJitFuncs, 0, sizeof(JitFunction *) * m_pPlugin->num_publics);
dvander@2226
   237
	}
dvander@2226
   238
asherkin@3601
   239
	MD5 md5_pcode;
asherkin@3601
   240
	md5_pcode.update(plugin->pcode, plugin->pcode_size);
asherkin@3601
   241
	md5_pcode.finalize();
asherkin@3601
   242
	md5_pcode.raw_digest(m_CodeHash);
asherkin@3601
   243
	
asherkin@3601
   244
	MD5 md5_data;
asherkin@3601
   245
	md5_data.update(plugin->data, plugin->data_size);
asherkin@3601
   246
	md5_data.finalize();
asherkin@3601
   247
	md5_data.raw_digest(m_DataHash);
asherkin@3601
   248
dvander@2226
   249
	m_pPlugin->profiler = g_engine2.GetProfiler();
dvander@2226
   250
	m_pCtx = new BaseContext(this);
dvander@2226
   251
	m_pCo = g_Jit.StartCompilation(this);
dvander@2226
   252
dvander@2226
   253
	return SP_ERROR_NONE;
dvander@2193
   254
}
dvander@2193
   255
dvander@2193
   256
int BaseRuntime::FindNativeByName(const char *name, uint32_t *index)
dvander@2193
   257
{
dvander@2193
   258
	int high;
dvander@2193
   259
dvander@2226
   260
	high = m_pPlugin->num_natives - 1;
dvander@2193
   261
dvander@2226
   262
	for (uint32_t i=0; i<m_pPlugin->num_natives; i++)
dvander@2193
   263
	{
dvander@2193
   264
		if (strcmp(m_pPlugin->natives[i].name, name) == 0)
dvander@2193
   265
		{
dvander@2193
   266
			if (index)
dvander@2193
   267
			{
dvander@2193
   268
				*index = i;
dvander@2193
   269
			}
dvander@2193
   270
			return SP_ERROR_NONE;
dvander@2193
   271
		}
dvander@2193
   272
	}
dvander@2193
   273
dvander@2193
   274
	return SP_ERROR_NOT_FOUND;
dvander@2193
   275
}
dvander@2193
   276
dvander@2193
   277
int BaseRuntime::GetNativeByIndex(uint32_t index, sp_native_t **native)
dvander@2193
   278
{
dvander@2226
   279
	if (index >= m_pPlugin->num_natives)
dvander@2193
   280
	{
dvander@2193
   281
		return SP_ERROR_INDEX;
dvander@2193
   282
	}
dvander@2193
   283
dvander@2193
   284
	if (native)
dvander@2193
   285
	{
dvander@2193
   286
		*native = &(m_pPlugin->natives[index]);
dvander@2193
   287
	}
dvander@2193
   288
dvander@2193
   289
	return SP_ERROR_NONE;
dvander@2193
   290
}
dvander@2193
   291
dvander@2193
   292
dvander@2193
   293
uint32_t BaseRuntime::GetNativesNum()
dvander@2193
   294
{
dvander@2226
   295
	return m_pPlugin->num_natives;
dvander@2193
   296
}
dvander@2193
   297
dvander@2193
   298
int BaseRuntime::FindPublicByName(const char *name, uint32_t *index)
dvander@2193
   299
{
dvander@2193
   300
	int diff, high, low;
dvander@2193
   301
	uint32_t mid;
dvander@2193
   302
dvander@2226
   303
	high = m_pPlugin->num_publics - 1;
dvander@2193
   304
	low = 0;
dvander@2193
   305
dvander@2193
   306
	while (low <= high)
dvander@2193
   307
	{
dvander@2193
   308
		mid = (low + high) / 2;
dvander@2193
   309
		diff = strcmp(m_pPlugin->publics[mid].name, name);
dvander@2193
   310
		if (diff == 0)
dvander@2193
   311
		{
dvander@2193
   312
			if (index)
dvander@2193
   313
			{
dvander@2193
   314
				*index = mid;
dvander@2193
   315
			}
dvander@2193
   316
			return SP_ERROR_NONE;
dvander@2193
   317
		} else if (diff < 0) {
dvander@2193
   318
			low = mid + 1;
dvander@2193
   319
		} else {
dvander@2193
   320
			high = mid - 1;
dvander@2193
   321
		}
dvander@2193
   322
	}
dvander@2193
   323
dvander@2193
   324
	return SP_ERROR_NOT_FOUND;
dvander@2193
   325
}
dvander@2193
   326
dvander@2193
   327
int BaseRuntime::GetPublicByIndex(uint32_t index, sp_public_t **pblic)
dvander@2193
   328
{
dvander@2226
   329
	if (index >= m_pPlugin->num_publics)
dvander@2193
   330
	{
dvander@2193
   331
		return SP_ERROR_INDEX;
dvander@2193
   332
	}
dvander@2193
   333
dvander@2193
   334
	if (pblic)
dvander@2193
   335
	{
dvander@2193
   336
		*pblic = &(m_pPlugin->publics[index]);
dvander@2193
   337
	}
dvander@2193
   338
dvander@2193
   339
	return SP_ERROR_NONE;
dvander@2193
   340
}
dvander@2193
   341
dvander@2193
   342
uint32_t BaseRuntime::GetPublicsNum()
dvander@2193
   343
{
dvander@2226
   344
	return m_pPlugin->num_publics;
dvander@2193
   345
}
dvander@2193
   346
dvander@2193
   347
int BaseRuntime::GetPubvarByIndex(uint32_t index, sp_pubvar_t **pubvar)
dvander@2193
   348
{
dvander@2226
   349
	if (index >= m_pPlugin->num_pubvars)
dvander@2193
   350
	{
dvander@2193
   351
		return SP_ERROR_INDEX;
dvander@2193
   352
	}
dvander@2193
   353
dvander@2193
   354
	if (pubvar)
dvander@2193
   355
	{
dvander@2193
   356
		*pubvar = &(m_pPlugin->pubvars[index]);
dvander@2193
   357
	}
dvander@2193
   358
dvander@2193
   359
	return SP_ERROR_NONE;
dvander@2193
   360
}
dvander@2193
   361
dvander@2193
   362
int BaseRuntime::FindPubvarByName(const char *name, uint32_t *index)
dvander@2193
   363
{
dvander@2193
   364
	int diff, high, low;
dvander@2193
   365
	uint32_t mid;
dvander@2193
   366
dvander@2226
   367
	high = m_pPlugin->num_pubvars - 1;
dvander@2193
   368
	low = 0;
dvander@2193
   369
dvander@2193
   370
	while (low <= high)
dvander@2193
   371
	{
dvander@2193
   372
		mid = (low + high) / 2;
dvander@2193
   373
		diff = strcmp(m_pPlugin->pubvars[mid].name, name);
dvander@2193
   374
		if (diff == 0)
dvander@2193
   375
		{
dvander@2193
   376
			if (index)
dvander@2193
   377
			{
dvander@2193
   378
				*index = mid;
dvander@2193
   379
			}
dvander@2193
   380
			return SP_ERROR_NONE;
dvander@2226
   381
		}
dvander@2226
   382
		else if (diff < 0)
dvander@2226
   383
		{
dvander@2193
   384
			low = mid + 1;
dvander@2226
   385
		}
dvander@2226
   386
		else
dvander@2226
   387
		{
dvander@2193
   388
			high = mid - 1;
dvander@2193
   389
		}
dvander@2193
   390
	}
dvander@2193
   391
dvander@2193
   392
	return SP_ERROR_NOT_FOUND;
dvander@2193
   393
}
dvander@2193
   394
dvander@2193
   395
int BaseRuntime::GetPubvarAddrs(uint32_t index, cell_t *local_addr, cell_t **phys_addr)
dvander@2193
   396
{
dvander@2226
   397
	if (index >= m_pPlugin->num_pubvars)
dvander@2193
   398
	{
dvander@2193
   399
		return SP_ERROR_INDEX;
dvander@2193
   400
	}
dvander@2193
   401
dvander@2226
   402
	*local_addr = (uint8_t *)m_pPlugin->pubvars[index].offs - m_pPlugin->memory;
dvander@2193
   403
	*phys_addr = m_pPlugin->pubvars[index].offs;
dvander@2193
   404
dvander@2193
   405
	return SP_ERROR_NONE;
dvander@2193
   406
}
dvander@2193
   407
dvander@2193
   408
uint32_t BaseRuntime::GetPubVarsNum()
dvander@2193
   409
{
dvander@2226
   410
	return m_pPlugin->num_pubvars;
dvander@2193
   411
}
dvander@2193
   412
dvander@2193
   413
IPluginContext *BaseRuntime::GetDefaultContext()
dvander@2193
   414
{
dvander@2193
   415
	return m_pCtx;
dvander@2193
   416
}
dvander@2193
   417
dvander@2193
   418
IPluginDebugInfo *BaseRuntime::GetDebugInfo()
dvander@2193
   419
{
dvander@2193
   420
	return &m_Debug;
dvander@2193
   421
}
dvander@2193
   422
dvander@2193
   423
IPluginFunction *BaseRuntime::GetFunctionById(funcid_t func_id)
dvander@2193
   424
{
dvander@2193
   425
	CFunction *pFunc = NULL;
dvander@2193
   426
dvander@2193
   427
	if (func_id & 1)
dvander@2193
   428
	{
dvander@2193
   429
		func_id >>= 1;
dvander@2226
   430
		if (func_id >= m_pPlugin->num_publics)
dvander@2193
   431
		{
dvander@2193
   432
			return NULL;
dvander@2193
   433
		}
dvander@2193
   434
		pFunc = m_PubFuncs[func_id];
dvander@2193
   435
		if (!pFunc)
dvander@2193
   436
		{
dvander@2226
   437
			m_PubFuncs[func_id] = new CFunction(this, 
dvander@2193
   438
				(func_id << 1) | 1,
dvander@2193
   439
				func_id);
dvander@2193
   440
			pFunc = m_PubFuncs[func_id];
dvander@2193
   441
		}
dvander@2193
   442
	}
dvander@2193
   443
dvander@2193
   444
	return pFunc;
dvander@2193
   445
}
dvander@2193
   446
dvander@2193
   447
IPluginFunction *BaseRuntime::GetFunctionByName(const char *public_name)
dvander@2193
   448
{
dvander@2193
   449
	uint32_t index;
dvander@2193
   450
dvander@2193
   451
	if (FindPublicByName(public_name, &index) != SP_ERROR_NONE)
dvander@2193
   452
	{
dvander@2193
   453
		return NULL;
dvander@2193
   454
	}
dvander@2193
   455
dvander@2193
   456
	CFunction *pFunc = m_PubFuncs[index];
dvander@2193
   457
	if (!pFunc)
dvander@2193
   458
	{
dvander@2193
   459
		sp_public_t *pub = NULL;
dvander@2193
   460
		GetPublicByIndex(index, &pub);
dvander@2193
   461
		if (pub)
dvander@2193
   462
		{
dvander@2226
   463
			m_PubFuncs[index] = new CFunction(this, (index << 1) | 1, index);
dvander@2193
   464
		}
dvander@2193
   465
		pFunc = m_PubFuncs[index];
dvander@2193
   466
	}
dvander@2193
   467
dvander@2193
   468
	return pFunc;
dvander@2193
   469
}
dvander@2193
   470
dvander@2193
   471
bool BaseRuntime::IsDebugging()
dvander@2193
   472
{
dvander@2226
   473
	return true;
dvander@2193
   474
}
dvander@2193
   475
dvander@2193
   476
void BaseRuntime::SetPauseState(bool paused)
dvander@2193
   477
{
dvander@2193
   478
	if (paused)
dvander@2193
   479
	{
dvander@2193
   480
		m_pPlugin->run_flags |= SPFLAG_PLUGIN_PAUSED;
dvander@2193
   481
	}
dvander@2193
   482
	else
dvander@2193
   483
	{
dvander@2193
   484
		m_pPlugin->run_flags &= ~SPFLAG_PLUGIN_PAUSED;
dvander@2193
   485
	}
dvander@2193
   486
}
dvander@2193
   487
dvander@2193
   488
bool BaseRuntime::IsPaused()
dvander@2193
   489
{
dvander@2193
   490
	return ((m_pPlugin->run_flags & SPFLAG_PLUGIN_PAUSED) == SPFLAG_PLUGIN_PAUSED);
dvander@2193
   491
}
dvander@2193
   492
dvander@2193
   493
size_t BaseRuntime::GetMemUsage()
dvander@2193
   494
{
dvander@2193
   495
	size_t mem = 0;
dvander@2193
   496
dvander@2193
   497
	mem += sizeof(this);
dvander@2193
   498
	mem += sizeof(sp_plugin_t);
dvander@2193
   499
	mem += sizeof(BaseContext);
dvander@2193
   500
	mem += m_pPlugin->base_size;
dvander@2193
   501
dvander@2193
   502
	return mem;
dvander@2193
   503
}
dvander@2193
   504
asherkin@3601
   505
unsigned char *BaseRuntime::GetCodeHash()
asherkin@3601
   506
{
asherkin@3601
   507
	return m_CodeHash;
asherkin@3601
   508
}
asherkin@3601
   509
asherkin@3601
   510
unsigned char *BaseRuntime::GetDataHash()
asherkin@3601
   511
{
asherkin@3601
   512
	return m_DataHash;
asherkin@3601
   513
}
asherkin@3601
   514
dvander@2193
   515
BaseContext *BaseRuntime::GetBaseContext()
dvander@2193
   516
{
dvander@2193
   517
	return m_pCtx;
dvander@2193
   518
}
dvander@2193
   519
dvander@2226
   520
int BaseRuntime::ApplyCompilationOptions(ICompilation *co)
dvander@2226
   521
{
dvander@2226
   522
	if (co == NULL)
dvander@2226
   523
	{
dvander@2226
   524
		return SP_ERROR_NONE;
dvander@2226
   525
	}
dvander@2226
   526
dvander@2226
   527
	m_pCo = g_Jit.ApplyOptions(m_pCo, co);
dvander@2249
   528
	m_pPlugin->prof_flags = ((CompData *)m_pCo)->profile;
dvander@2226
   529
dvander@2226
   530
	return SP_ERROR_NONE;
dvander@2226
   531
}
dvander@2226
   532
dvander@2226
   533
JitFunction *BaseRuntime::GetJittedFunction(uint32_t idx)
dvander@2226
   534
{
dvander@2226
   535
	assert(idx <= m_NumFuncs);
dvander@2226
   536
dvander@2226
   537
	if (idx == 0 || idx > m_NumFuncs)
dvander@2226
   538
	{
dvander@2226
   539
		return NULL;
dvander@2226
   540
	}
dvander@2226
   541
dvander@2226
   542
	return m_FuncCache[idx - 1];
dvander@2226
   543
}
dvander@2226
   544
dvander@2226
   545
uint32_t BaseRuntime::AddJittedFunction(JitFunction *fn)
dvander@2226
   546
{
dvander@2226
   547
	if (m_NumFuncs + 1 > m_MaxFuncs)
dvander@2226
   548
	{
dvander@2226
   549
		if (m_MaxFuncs == 0)
dvander@2226
   550
		{
dvander@2226
   551
			m_MaxFuncs = 8;
dvander@2226
   552
		}
dvander@2226
   553
		else
dvander@2226
   554
		{
dvander@2226
   555
			m_MaxFuncs *= 2;
dvander@2226
   556
		}
dvander@2226
   557
dvander@2226
   558
		m_FuncCache = (JitFunction **)realloc(
dvander@2226
   559
			m_FuncCache,
dvander@2226
   560
			sizeof(JitFunction *) * m_MaxFuncs);
dvander@2226
   561
	}
dvander@2226
   562
dvander@2226
   563
	m_FuncCache[m_NumFuncs++] = fn;
dvander@2226
   564
dvander@2226
   565
	return m_NumFuncs;
dvander@2226
   566
}
dvander@2545
   567
dvander@2545
   568
int BaseRuntime::CreateBlank(uint32_t heastk)
dvander@2545
   569
{
dvander@2545
   570
	memset(m_pPlugin, 0, sizeof(sp_plugin_t));
dvander@2545
   571
dvander@2545
   572
	/* Align to cell_t bytes */
dvander@2545
   573
	heastk += sizeof(cell_t);
dvander@2545
   574
	heastk -= heastk % sizeof(cell_t);
dvander@2545
   575
dvander@2545
   576
	m_pPlugin->mem_size = heastk;
dvander@2545
   577
	m_pPlugin->memory = new uint8_t[heastk];
dvander@2545
   578
dvander@2545
   579
	m_pPlugin->profiler = g_engine2.GetProfiler();
dvander@2545
   580
	m_pCtx = new BaseContext(this);
dvander@2545
   581
	m_pCo = g_Jit.StartCompilation(this);
dvander@2545
   582
dvander@2545
   583
	return SP_ERROR_NONE;
dvander@2545
   584
}