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