sourcepawn/jit/engine2.cpp
author David Anderson <danderson@mozilla.com>
Thu Aug 08 09:41:24 2013 -0700 (2013-08-08)
changeset 3977 fca2b54741ca
parent 3630 b72450a8be42
child 4013 6201c1180e0e
permissions -rw-r--r--
Refactor the JIT to use a newer, simpler macro assembler. (bug 5827, r=ann)
dvander@2783
     1
#include <sourcemod_version.h>
dvander@2193
     2
#include <stdio.h>
dvander@2193
     3
#include <stdlib.h>
dvander@2193
     4
#include <string.h>
dvander@2193
     5
#include "engine2.h"
dvander@2193
     6
#include "x86/jit_x86.h"
dvander@2193
     7
#include "zlib/zlib.h"
dvander@2193
     8
#include "BaseRuntime.h"
dvander@2193
     9
#include "sp_vm_engine.h"
dvander@2193
    10
dvander@2193
    11
using namespace SourcePawn;
dvander@2193
    12
dvander@2193
    13
SourcePawnEngine2::SourcePawnEngine2()
dvander@2193
    14
{
dvander@2193
    15
	m_Profiler = NULL;
dvander@2193
    16
}
dvander@2193
    17
dvander@2193
    18
IPluginRuntime *SourcePawnEngine2::LoadPlugin(ICompilation *co, const char *file, int *err)
dvander@2193
    19
{
dvander@2193
    20
	sp_file_hdr_t hdr;
dvander@2193
    21
	uint8_t *base;
dvander@2193
    22
	int z_result;
dvander@2193
    23
	int error;
dvander@2193
    24
	BaseRuntime *pRuntime;
dvander@2193
    25
dvander@2193
    26
	FILE *fp = fopen(file, "rb");
dvander@2193
    27
dvander@2193
    28
	if (!fp)
dvander@2193
    29
	{
dvander@2193
    30
		error = SP_ERROR_NOT_FOUND;
dvander@2193
    31
		goto return_error;
dvander@2193
    32
	}
dvander@2193
    33
dvander@2193
    34
	/* Rewind for safety */
dvander@2193
    35
	fread(&hdr, sizeof(sp_file_hdr_t), 1, fp);
dvander@2193
    36
dvander@2193
    37
	if (hdr.magic != SPFILE_MAGIC)
dvander@2193
    38
	{
dvander@2193
    39
		error = SP_ERROR_FILE_FORMAT;
dvander@2193
    40
		goto return_error;
dvander@2193
    41
	}
dvander@2193
    42
dvander@2193
    43
	switch (hdr.compression)
dvander@2193
    44
	{
dvander@2193
    45
	case SPFILE_COMPRESSION_GZ:
dvander@2193
    46
		{
dvander@2193
    47
			uint32_t uncompsize = hdr.imagesize - hdr.dataoffs;
dvander@2193
    48
			uint32_t compsize = hdr.disksize - hdr.dataoffs;
dvander@2193
    49
			uint32_t sectsize = hdr.dataoffs - sizeof(sp_file_hdr_t);
dvander@2193
    50
			uLongf destlen = uncompsize;
dvander@2193
    51
dvander@2193
    52
			char *tempbuf = (char *)malloc(compsize);
dvander@2193
    53
			void *uncompdata = malloc(uncompsize);
dvander@2193
    54
			void *sectheader = malloc(sectsize);
dvander@2193
    55
dvander@2193
    56
			fread(sectheader, sectsize, 1, fp);
dvander@2193
    57
			fread(tempbuf, compsize, 1, fp);
dvander@2193
    58
dvander@2193
    59
			z_result = uncompress((Bytef *)uncompdata, &destlen, (Bytef *)tempbuf, compsize);
dvander@2193
    60
			free(tempbuf);
dvander@2193
    61
			if (z_result != Z_OK)
dvander@2193
    62
			{
dvander@2193
    63
				free(sectheader);
dvander@2193
    64
				free(uncompdata);
dvander@2193
    65
				error = SP_ERROR_DECOMPRESSOR;
dvander@2193
    66
				goto return_error;
dvander@2193
    67
			}
dvander@2193
    68
dvander@2193
    69
			base = (uint8_t *)malloc(hdr.imagesize);
dvander@2193
    70
			memcpy(base, &hdr, sizeof(sp_file_hdr_t));
dvander@2193
    71
			memcpy(base + sizeof(sp_file_hdr_t), sectheader, sectsize);
dvander@2193
    72
			free(sectheader);
dvander@2193
    73
			memcpy(base + hdr.dataoffs, uncompdata, uncompsize);
dvander@2193
    74
			free(uncompdata);
dvander@2193
    75
			break;
dvander@2193
    76
		}
dvander@2193
    77
	case SPFILE_COMPRESSION_NONE:
dvander@2193
    78
		{
dvander@2193
    79
			base = (uint8_t *)malloc(hdr.imagesize);
dvander@2193
    80
			rewind(fp);
dvander@2193
    81
			fread(base, hdr.imagesize, 1, fp);
dvander@2193
    82
			break;
dvander@2193
    83
		}
dvander@2193
    84
	default:
dvander@2193
    85
		{
dvander@2193
    86
			error = SP_ERROR_DECOMPRESSOR;
dvander@2193
    87
			goto return_error;
dvander@2193
    88
		}
dvander@2193
    89
	}
dvander@2193
    90
dvander@2226
    91
	pRuntime = new BaseRuntime();
dvander@2226
    92
	if ((error = pRuntime->CreateFromMemory(&hdr, base)) != SP_ERROR_NONE)
dvander@2193
    93
	{
dvander@2226
    94
		delete pRuntime;
dvander@2226
    95
		goto return_error;
dvander@2193
    96
	}
dvander@2193
    97
dvander@2226
    98
	size_t len;
dvander@2226
    99
	
dvander@2226
   100
	len = strlen(file);
ds@3261
   101
	for (size_t i = len - 1; i < len; i--)
dvander@2193
   102
	{
dvander@2226
   103
		if (file[i] == '/' 
dvander@2226
   104
		#if defined WIN32
dvander@2226
   105
			|| file[i] == '\\'
dvander@2226
   106
		#endif
dvander@2226
   107
		)
dvander@2226
   108
		{
danderson@3977
   109
			pRuntime->SetName(&file[i+1]);
dvander@2226
   110
			break;
dvander@2226
   111
		}
dvander@2193
   112
	}
dvander@2193
   113
danderson@3977
   114
	if (!pRuntime->plugin()->name)
dvander@2193
   115
	{
danderson@3977
   116
		pRuntime->SetName(file);
dvander@2193
   117
	}
dvander@2193
   118
dvander@2226
   119
	pRuntime->ApplyCompilationOptions(co);
dvander@2226
   120
danderson@3977
   121
	fclose(fp);
dvander@2242
   122
dvander@2193
   123
	return pRuntime;
dvander@2193
   124
dvander@2193
   125
return_error:
dvander@2193
   126
	*err = error;
dvander@2376
   127
	if (fp != NULL)
dvander@2376
   128
	{
dvander@2376
   129
    	fclose(fp);
dvander@2376
   130
	}
dvander@2193
   131
dvander@2193
   132
	return NULL;
dvander@2193
   133
}
dvander@2193
   134
dvander@2193
   135
SPVM_NATIVE_FUNC SourcePawnEngine2::CreateFakeNative(SPVM_FAKENATIVE_FUNC callback, void *pData)
dvander@2193
   136
{
dvander@2226
   137
	return g_Jit.CreateFakeNative(callback, pData);
dvander@2193
   138
}
dvander@2193
   139
dvander@2193
   140
void SourcePawnEngine2::DestroyFakeNative(SPVM_NATIVE_FUNC func)
dvander@2193
   141
{
dvander@2226
   142
	g_Jit.DestroyFakeNative(func);
dvander@2193
   143
}
dvander@2193
   144
dvander@2193
   145
const char *SourcePawnEngine2::GetEngineName()
dvander@2193
   146
{
dvander@2193
   147
	return "SourcePawn 1.1, jit-x86";
dvander@2193
   148
}
dvander@2193
   149
dvander@2193
   150
const char *SourcePawnEngine2::GetVersionString()
dvander@2193
   151
{
asherkin@3630
   152
	return SM_VERSION_STRING;
dvander@2193
   153
}
dvander@2193
   154
dvander@2193
   155
IProfiler *SourcePawnEngine2::GetProfiler()
dvander@2193
   156
{
dvander@2193
   157
	return m_Profiler;
dvander@2193
   158
}
dvander@2193
   159
dvander@2193
   160
void SourcePawnEngine2::SetProfiler(IProfiler *profiler)
dvander@2193
   161
{
dvander@2193
   162
	m_Profiler = profiler;
dvander@2193
   163
}
dvander@2193
   164
dvander@2193
   165
IDebugListener *SourcePawnEngine2::SetDebugListener(IDebugListener *listener)
dvander@2193
   166
{
dvander@2193
   167
	return g_engine1.SetDebugListener(listener);
dvander@2193
   168
}
dvander@2193
   169
dvander@2193
   170
unsigned int SourcePawnEngine2::GetAPIVersion()
dvander@2193
   171
{
dvander@2193
   172
	return SOURCEPAWN_ENGINE2_API_VERSION;
dvander@2193
   173
}
dvander@2193
   174
dvander@2193
   175
ICompilation *SourcePawnEngine2::StartCompilation()
dvander@2193
   176
{
dvander@2226
   177
	return g_Jit.StartCompilation();
dvander@2193
   178
}
dvander@2193
   179
dvander@2193
   180
const char *SourcePawnEngine2::GetErrorString(int err)
dvander@2193
   181
{
dvander@2193
   182
	return g_engine1.GetErrorString(err);
dvander@2193
   183
}
dvander@2226
   184
dvander@2226
   185
bool SourcePawnEngine2::Initialize()
dvander@2226
   186
{
dvander@2226
   187
	return g_Jit.InitializeJIT();
dvander@2226
   188
}
dvander@2226
   189
dvander@2226
   190
void SourcePawnEngine2::Shutdown()
dvander@2226
   191
{
dvander@2226
   192
	g_Jit.ShutdownJIT();
dvander@2226
   193
}
dvander@2545
   194
dvander@2545
   195
IPluginRuntime *SourcePawnEngine2::CreateEmptyRuntime(const char *name, uint32_t memory)
dvander@2545
   196
{
dvander@2545
   197
	int err;
dvander@2545
   198
	BaseRuntime *rt;
dvander@2545
   199
dvander@2545
   200
	rt = new BaseRuntime();
dvander@2545
   201
	if ((err = rt->CreateBlank(memory)) != SP_ERROR_NONE)
dvander@2545
   202
	{
dvander@2545
   203
		delete rt;
dvander@2545
   204
		return NULL;
dvander@2545
   205
	}
dvander@2545
   206
danderson@3977
   207
	rt->SetName(name != NULL ? name : "<anonymous>");
dvander@2545
   208
dvander@2545
   209
	rt->ApplyCompilationOptions(NULL);
dvander@2545
   210
	
dvander@2545
   211
	return rt;
dvander@2545
   212
}