sourcepawn/jit/engine2.cpp
author David Anderson <dvander@alliedmods.net>
Fri Jul 11 06:51:21 2008 +0000 (2008-07-11)
branchrefac-jit
changeset 2192 7602d7fb60d9
parent 2188 24b170ea6ce7
permissions -rw-r--r--
fixed a compat regression, forgot msvc does funky things with overloaded virtual calls
dvander@2171
     1
#include <stdio.h>
dvander@2171
     2
#include <stdlib.h>
dvander@2171
     3
#include <string.h>
dvander@2171
     4
#include "engine2.h"
dvander@2171
     5
#include "x86/jit_x86.h"
dvander@2171
     6
#include "jit_version.h"
dvander@2171
     7
#include "zlib/zlib.h"
dvander@2171
     8
#include "BaseRuntime.h"
dvander@2171
     9
#include "sp_vm_engine.h"
dvander@2171
    10
dvander@2171
    11
using namespace SourcePawn;
dvander@2171
    12
dvander@2171
    13
SourcePawnEngine2::SourcePawnEngine2()
dvander@2171
    14
{
dvander@2171
    15
	m_Profiler = NULL;
dvander@2171
    16
}
dvander@2171
    17
dvander@2171
    18
sp_plugin_t *_ReadPlugin(sp_file_hdr_t *hdr, uint8_t *base, sp_plugin_t *plugin, int *err)
dvander@2171
    19
{
dvander@2171
    20
	char *nameptr;
dvander@2171
    21
	uint8_t sectnum = 0;
dvander@2171
    22
	sp_file_section_t *secptr = (sp_file_section_t *)(base + sizeof(sp_file_hdr_t));
dvander@2171
    23
dvander@2171
    24
	memset(plugin, 0, sizeof(sp_plugin_t));
dvander@2171
    25
dvander@2171
    26
	plugin->base = base;
dvander@2171
    27
dvander@2171
    28
	while (sectnum < hdr->sections)
dvander@2171
    29
	{
dvander@2171
    30
		nameptr = (char *)(base + hdr->stringtab + secptr->nameoffs);
dvander@2171
    31
dvander@2171
    32
		if (!(plugin->pcode) && !strcmp(nameptr, ".code"))
dvander@2171
    33
		{
dvander@2171
    34
			sp_file_code_t *cod = (sp_file_code_t *)(base + secptr->dataoffs);
dvander@2171
    35
			plugin->pcode = base + secptr->dataoffs + cod->code;
dvander@2171
    36
			plugin->pcode_size = cod->codesize;
dvander@2171
    37
			plugin->flags = cod->flags;
dvander@2171
    38
		}
dvander@2171
    39
		else if (!(plugin->data) && !strcmp(nameptr, ".data"))
dvander@2171
    40
		{
dvander@2171
    41
			sp_file_data_t *dat = (sp_file_data_t *)(base + secptr->dataoffs);
dvander@2171
    42
			plugin->data = base + secptr->dataoffs + dat->data;
dvander@2171
    43
			plugin->data_size = dat->datasize;
dvander@2171
    44
			plugin->mem_size = dat->memsize;
dvander@2171
    45
			plugin->memory = new uint8_t[plugin->mem_size];
dvander@2171
    46
			memcpy(plugin->memory, plugin->data, plugin->data_size);
dvander@2171
    47
		}
dvander@2171
    48
		else if (!(plugin->info.publics) && !strcmp(nameptr, ".publics"))
dvander@2171
    49
		{
dvander@2171
    50
			plugin->info.publics_num = secptr->size / sizeof(sp_file_publics_t);
dvander@2171
    51
			plugin->info.publics = (sp_file_publics_t *)(base + secptr->dataoffs);
dvander@2171
    52
		}
dvander@2171
    53
		else if (!(plugin->info.pubvars) && !strcmp(nameptr, ".pubvars"))
dvander@2171
    54
		{
dvander@2171
    55
			plugin->info.pubvars_num = secptr->size / sizeof(sp_file_pubvars_t);
dvander@2171
    56
			plugin->info.pubvars = (sp_file_pubvars_t *)(base + secptr->dataoffs);
dvander@2171
    57
		}
dvander@2171
    58
		else if (!(plugin->info.natives) && !strcmp(nameptr, ".natives"))
dvander@2171
    59
		{
dvander@2171
    60
			plugin->info.natives_num = secptr->size / sizeof(sp_file_natives_t);
dvander@2171
    61
			plugin->info.natives = (sp_file_natives_t *)(base + secptr->dataoffs);
dvander@2171
    62
		}
dvander@2171
    63
		else if (!(plugin->info.stringbase) && !strcmp(nameptr, ".names"))
dvander@2171
    64
		{
dvander@2171
    65
			plugin->info.stringbase = (const char *)(base + secptr->dataoffs);
dvander@2171
    66
		}
dvander@2171
    67
		else if (!(plugin->debug.files) && !strcmp(nameptr, ".dbg.files"))
dvander@2171
    68
		{
dvander@2171
    69
			plugin->debug.files = (sp_fdbg_file_t *)(base + secptr->dataoffs);
dvander@2171
    70
		}
dvander@2171
    71
		else if (!(plugin->debug.lines) && !strcmp(nameptr, ".dbg.lines"))
dvander@2171
    72
		{
dvander@2171
    73
			plugin->debug.lines = (sp_fdbg_line_t *)(base + secptr->dataoffs);
dvander@2171
    74
		}
dvander@2171
    75
		else if (!(plugin->debug.symbols) && !strcmp(nameptr, ".dbg.symbols"))
dvander@2171
    76
		{
dvander@2171
    77
			plugin->debug.symbols = (sp_fdbg_symbol_t *)(base + secptr->dataoffs);
dvander@2171
    78
		}
dvander@2171
    79
		else if (!(plugin->debug.lines_num) && !strcmp(nameptr, ".dbg.info"))
dvander@2171
    80
		{
dvander@2171
    81
			sp_fdbg_info_t *inf = (sp_fdbg_info_t *)(base + secptr->dataoffs);
dvander@2171
    82
			plugin->debug.files_num = inf->num_files;
dvander@2171
    83
			plugin->debug.lines_num = inf->num_lines;
dvander@2171
    84
			plugin->debug.syms_num = inf->num_syms;
dvander@2171
    85
		}
dvander@2171
    86
		else if (!(plugin->debug.stringbase) && !strcmp(nameptr, ".dbg.strings"))
dvander@2171
    87
		{
dvander@2171
    88
			plugin->debug.stringbase = (const char *)(base + secptr->dataoffs);
dvander@2171
    89
		}
dvander@2171
    90
dvander@2171
    91
		secptr++;
dvander@2171
    92
		sectnum++;
dvander@2171
    93
	}
dvander@2171
    94
dvander@2171
    95
	if (!(plugin->pcode) || !(plugin->data) || !(plugin->info.stringbase))
dvander@2171
    96
	{
dvander@2171
    97
		goto return_error;
dvander@2171
    98
	}
dvander@2171
    99
dvander@2171
   100
	if ((plugin->flags & SP_FLAG_DEBUG) && (!(plugin->debug.files) || !(plugin->debug.lines) || !(plugin->debug.symbols)))
dvander@2171
   101
	{
dvander@2171
   102
		goto return_error;
dvander@2171
   103
	}
dvander@2171
   104
dvander@2171
   105
	if (err)
dvander@2171
   106
	{
dvander@2171
   107
		*err = SP_ERROR_NONE;
dvander@2171
   108
	}
dvander@2171
   109
dvander@2171
   110
	return plugin;
dvander@2171
   111
dvander@2171
   112
return_error:
dvander@2171
   113
	if (err)
dvander@2171
   114
	{
dvander@2171
   115
		*err = SP_ERROR_FILE_FORMAT;
dvander@2171
   116
	}
dvander@2171
   117
dvander@2171
   118
	return NULL;
dvander@2171
   119
}
dvander@2171
   120
dvander@2171
   121
IPluginRuntime *SourcePawnEngine2::LoadPlugin(ICompilation *co, const char *file, int *err)
dvander@2171
   122
{
dvander@2171
   123
	sp_file_hdr_t hdr;
dvander@2171
   124
	sp_plugin_t *plugin;
dvander@2171
   125
	uint8_t *base;
dvander@2171
   126
	int z_result;
dvander@2171
   127
	int error;
dvander@2188
   128
	BaseRuntime *pRuntime;
dvander@2171
   129
dvander@2171
   130
	FILE *fp = fopen(file, "rb");
dvander@2171
   131
dvander@2171
   132
	if (!fp)
dvander@2171
   133
	{
dvander@2171
   134
		error = SP_ERROR_NOT_FOUND;
dvander@2171
   135
		goto return_error;
dvander@2171
   136
	}
dvander@2171
   137
dvander@2171
   138
	/* Rewind for safety */
dvander@2171
   139
	fread(&hdr, sizeof(sp_file_hdr_t), 1, fp);
dvander@2171
   140
dvander@2171
   141
	if (hdr.magic != SPFILE_MAGIC)
dvander@2171
   142
	{
dvander@2171
   143
		error = SP_ERROR_FILE_FORMAT;
dvander@2171
   144
		goto return_error;
dvander@2171
   145
	}
dvander@2171
   146
dvander@2171
   147
	switch (hdr.compression)
dvander@2171
   148
	{
dvander@2171
   149
	case SPFILE_COMPRESSION_GZ:
dvander@2171
   150
		{
dvander@2171
   151
			uint32_t uncompsize = hdr.imagesize - hdr.dataoffs;
dvander@2171
   152
			uint32_t compsize = hdr.disksize - hdr.dataoffs;
dvander@2171
   153
			uint32_t sectsize = hdr.dataoffs - sizeof(sp_file_hdr_t);
dvander@2171
   154
			uLongf destlen = uncompsize;
dvander@2171
   155
dvander@2171
   156
			char *tempbuf = (char *)malloc(compsize);
dvander@2171
   157
			void *uncompdata = malloc(uncompsize);
dvander@2171
   158
			void *sectheader = malloc(sectsize);
dvander@2171
   159
dvander@2171
   160
			fread(sectheader, sectsize, 1, fp);
dvander@2171
   161
			fread(tempbuf, compsize, 1, fp);
dvander@2171
   162
dvander@2171
   163
			z_result = uncompress((Bytef *)uncompdata, &destlen, (Bytef *)tempbuf, compsize);
dvander@2171
   164
			free(tempbuf);
dvander@2171
   165
			if (z_result != Z_OK)
dvander@2171
   166
			{
dvander@2171
   167
				free(sectheader);
dvander@2171
   168
				free(uncompdata);
dvander@2171
   169
				error = SP_ERROR_DECOMPRESSOR;
dvander@2171
   170
				goto return_error;
dvander@2171
   171
			}
dvander@2171
   172
dvander@2171
   173
			base = (uint8_t *)malloc(hdr.imagesize);
dvander@2171
   174
			memcpy(base, &hdr, sizeof(sp_file_hdr_t));
dvander@2171
   175
			memcpy(base + sizeof(sp_file_hdr_t), sectheader, sectsize);
dvander@2171
   176
			free(sectheader);
dvander@2171
   177
			memcpy(base + hdr.dataoffs, uncompdata, uncompsize);
dvander@2171
   178
			free(uncompdata);
dvander@2171
   179
			break;
dvander@2171
   180
		}
dvander@2171
   181
	case SPFILE_COMPRESSION_NONE:
dvander@2171
   182
		{
dvander@2171
   183
			base = (uint8_t *)malloc(hdr.imagesize);
dvander@2171
   184
			rewind(fp);
dvander@2171
   185
			fread(base, hdr.imagesize, 1, fp);
dvander@2171
   186
			break;
dvander@2171
   187
		}
dvander@2171
   188
	default:
dvander@2171
   189
		{
dvander@2171
   190
			error = SP_ERROR_DECOMPRESSOR;
dvander@2171
   191
			goto return_error;
dvander@2171
   192
		}
dvander@2171
   193
	}
dvander@2171
   194
dvander@2171
   195
	plugin = new sp_plugin_t;
dvander@2171
   196
dvander@2171
   197
	memset(plugin, 0, sizeof(sp_plugin_t));
dvander@2171
   198
dvander@2174
   199
	plugin->base_size = hdr.imagesize;
dvander@2171
   200
	if (!_ReadPlugin(&hdr, base, plugin, err))
dvander@2171
   201
	{
dvander@2171
   202
		delete plugin;
dvander@2171
   203
		free(base);
dvander@2171
   204
		return NULL;
dvander@2171
   205
	}
dvander@2171
   206
dvander@2188
   207
	pRuntime = new BaseRuntime(plugin);
dvander@2171
   208
dvander@2171
   209
	if (co == NULL)
dvander@2171
   210
	{
dvander@2171
   211
		co = g_Jit1.StartCompilation(pRuntime);
dvander@2171
   212
	}
dvander@2171
   213
dvander@2171
   214
dvander@2171
   215
	*err = pRuntime->ApplyCompilationOptions(co);
dvander@2171
   216
	if (*err != SP_ERROR_NONE)
dvander@2171
   217
	{
dvander@2171
   218
		delete pRuntime;
dvander@2171
   219
		return NULL;
dvander@2171
   220
	}
dvander@2171
   221
dvander@2171
   222
	return pRuntime;
dvander@2171
   223
dvander@2171
   224
return_error:
dvander@2171
   225
	*err = error;
dvander@2171
   226
dvander@2171
   227
	return NULL;
dvander@2171
   228
}
dvander@2171
   229
dvander@2171
   230
SPVM_NATIVE_FUNC SourcePawnEngine2::CreateFakeNative(SPVM_FAKENATIVE_FUNC callback, void *pData)
dvander@2171
   231
{
dvander@2171
   232
	return g_Jit1.CreateFakeNative(callback, pData);
dvander@2171
   233
}
dvander@2171
   234
dvander@2171
   235
void SourcePawnEngine2::DestroyFakeNative(SPVM_NATIVE_FUNC func)
dvander@2171
   236
{
dvander@2171
   237
	g_Jit1.DestroyFakeNative(func);
dvander@2171
   238
}
dvander@2171
   239
dvander@2171
   240
const char *SourcePawnEngine2::GetEngineName()
dvander@2171
   241
{
dvander@2171
   242
	return "SourcePawn 1.1, jit-x86";
dvander@2171
   243
}
dvander@2171
   244
dvander@2171
   245
const char *SourcePawnEngine2::GetVersionString()
dvander@2171
   246
{
dvander@2171
   247
	return SVN_FULL_VERSION;
dvander@2171
   248
}
dvander@2171
   249
dvander@2171
   250
IProfiler *SourcePawnEngine2::GetProfiler()
dvander@2171
   251
{
dvander@2171
   252
	return m_Profiler;
dvander@2171
   253
}
dvander@2171
   254
dvander@2171
   255
void SourcePawnEngine2::SetProfiler(IProfiler *profiler)
dvander@2171
   256
{
dvander@2171
   257
	m_Profiler = profiler;
dvander@2171
   258
}
dvander@2171
   259
dvander@2171
   260
IDebugListener *SourcePawnEngine2::SetDebugListener(IDebugListener *listener)
dvander@2171
   261
{
dvander@2171
   262
	return g_engine1.SetDebugListener(listener);
dvander@2171
   263
}
dvander@2171
   264
dvander@2171
   265
unsigned int SourcePawnEngine2::GetAPIVersion()
dvander@2171
   266
{
dvander@2171
   267
	return SOURCEPAWN_ENGINE2_API_VERSION;
dvander@2171
   268
}
dvander@2171
   269
dvander@2171
   270
ICompilation *SourcePawnEngine2::StartCompilation()
dvander@2171
   271
{
dvander@2171
   272
	return g_Jit1.StartCompilation();
dvander@2171
   273
}
dvander@2174
   274
dvander@2174
   275
const char *SourcePawnEngine2::GetErrorString(int err)
dvander@2174
   276
{
dvander@2174
   277
	return g_engine1.GetErrorString(err);
dvander@2174
   278
}