sourcepawn/jit/engine2.cpp
author David Anderson <dvander@alliedmods.net>
Sun Oct 26 23:50:54 2008 -0500 (2008-10-26)
changeset 2377 6ee3bbd6fbdf
parent 2376 91efbb63ad5b
child 2378 d812052c5821
permissions -rw-r--r--
Fixed leaking relocation table memory in JIT.
dvander@2193
     1
#include <stdio.h>
dvander@2193
     2
#include <stdlib.h>
dvander@2193
     3
#include <string.h>
dvander@2193
     4
#include "engine2.h"
dvander@2193
     5
#include "x86/jit_x86.h"
dvander@2193
     6
#include "jit_version.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
pred@2219
    91
dvander@2226
    92
	pRuntime = new BaseRuntime();
dvander@2226
    93
	if ((error = pRuntime->CreateFromMemory(&hdr, base)) != SP_ERROR_NONE)
dvander@2193
    94
	{
dvander@2226
    95
		delete pRuntime;
dvander@2226
    96
		goto return_error;
dvander@2193
    97
	}
dvander@2193
    98
dvander@2226
    99
	size_t len;
dvander@2226
   100
	
dvander@2226
   101
	len = strlen(file);
dvander@2226
   102
	for (size_t i = len - 1; i >= 0 && i < len; i--)
dvander@2193
   103
	{
dvander@2226
   104
		if (file[i] == '/' 
dvander@2226
   105
		#if defined WIN32
dvander@2226
   106
			|| file[i] == '\\'
dvander@2226
   107
		#endif
dvander@2226
   108
		)
dvander@2226
   109
		{
dvander@2226
   110
			pRuntime->m_pPlugin->name = strdup(&file[i+1]);
dvander@2226
   111
			break;
dvander@2226
   112
		}
dvander@2193
   113
	}
dvander@2193
   114
dvander@2226
   115
	if (pRuntime->m_pPlugin->name == NULL)
dvander@2193
   116
	{
dvander@2226
   117
		pRuntime->m_pPlugin->name = strdup(file);
dvander@2193
   118
	}
dvander@2193
   119
dvander@2226
   120
	pRuntime->ApplyCompilationOptions(co);
dvander@2226
   121
dvander@2242
   122
    fclose(fp);
dvander@2242
   123
dvander@2193
   124
	return pRuntime;
dvander@2193
   125
dvander@2193
   126
return_error:
dvander@2193
   127
	*err = error;
dvander@2376
   128
	if (fp != NULL)
dvander@2376
   129
	{
dvander@2376
   130
    	fclose(fp);
dvander@2376
   131
	}
dvander@2193
   132
dvander@2193
   133
	return NULL;
dvander@2193
   134
}
dvander@2193
   135
dvander@2193
   136
SPVM_NATIVE_FUNC SourcePawnEngine2::CreateFakeNative(SPVM_FAKENATIVE_FUNC callback, void *pData)
dvander@2193
   137
{
dvander@2226
   138
	return g_Jit.CreateFakeNative(callback, pData);
dvander@2193
   139
}
dvander@2193
   140
dvander@2193
   141
void SourcePawnEngine2::DestroyFakeNative(SPVM_NATIVE_FUNC func)
dvander@2193
   142
{
dvander@2226
   143
	g_Jit.DestroyFakeNative(func);
dvander@2193
   144
}
dvander@2193
   145
dvander@2193
   146
const char *SourcePawnEngine2::GetEngineName()
dvander@2193
   147
{
dvander@2193
   148
	return "SourcePawn 1.1, jit-x86";
dvander@2193
   149
}
dvander@2193
   150
dvander@2193
   151
const char *SourcePawnEngine2::GetVersionString()
dvander@2193
   152
{
dvander@2193
   153
	return SVN_FULL_VERSION;
dvander@2193
   154
}
dvander@2193
   155
dvander@2193
   156
IProfiler *SourcePawnEngine2::GetProfiler()
dvander@2193
   157
{
dvander@2193
   158
	return m_Profiler;
dvander@2193
   159
}
dvander@2193
   160
dvander@2193
   161
void SourcePawnEngine2::SetProfiler(IProfiler *profiler)
dvander@2193
   162
{
dvander@2193
   163
	m_Profiler = profiler;
dvander@2193
   164
}
dvander@2193
   165
dvander@2193
   166
IDebugListener *SourcePawnEngine2::SetDebugListener(IDebugListener *listener)
dvander@2193
   167
{
dvander@2193
   168
	return g_engine1.SetDebugListener(listener);
dvander@2193
   169
}
dvander@2193
   170
dvander@2193
   171
unsigned int SourcePawnEngine2::GetAPIVersion()
dvander@2193
   172
{
dvander@2193
   173
	return SOURCEPAWN_ENGINE2_API_VERSION;
dvander@2193
   174
}
dvander@2193
   175
dvander@2193
   176
ICompilation *SourcePawnEngine2::StartCompilation()
dvander@2193
   177
{
dvander@2226
   178
	return g_Jit.StartCompilation();
dvander@2193
   179
}
dvander@2193
   180
dvander@2193
   181
const char *SourcePawnEngine2::GetErrorString(int err)
dvander@2193
   182
{
dvander@2193
   183
	return g_engine1.GetErrorString(err);
dvander@2193
   184
}
dvander@2226
   185
dvander@2226
   186
bool SourcePawnEngine2::Initialize()
dvander@2226
   187
{
dvander@2226
   188
	return g_Jit.InitializeJIT();
dvander@2226
   189
}
dvander@2226
   190
dvander@2226
   191
void SourcePawnEngine2::Shutdown()
dvander@2226
   192
{
dvander@2226
   193
	g_Jit.ShutdownJIT();
dvander@2226
   194
}