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.
     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <string.h>
     4 #include "engine2.h"
     5 #include "x86/jit_x86.h"
     6 #include "jit_version.h"
     7 #include "zlib/zlib.h"
     8 #include "BaseRuntime.h"
     9 #include "sp_vm_engine.h"
    10 
    11 using namespace SourcePawn;
    12 
    13 SourcePawnEngine2::SourcePawnEngine2()
    14 {
    15 	m_Profiler = NULL;
    16 }
    17 
    18 IPluginRuntime *SourcePawnEngine2::LoadPlugin(ICompilation *co, const char *file, int *err)
    19 {
    20 	sp_file_hdr_t hdr;
    21 	uint8_t *base;
    22 	int z_result;
    23 	int error;
    24 	BaseRuntime *pRuntime;
    25 
    26 	FILE *fp = fopen(file, "rb");
    27 
    28 	if (!fp)
    29 	{
    30 		error = SP_ERROR_NOT_FOUND;
    31 		goto return_error;
    32 	}
    33 
    34 	/* Rewind for safety */
    35 	fread(&hdr, sizeof(sp_file_hdr_t), 1, fp);
    36 
    37 	if (hdr.magic != SPFILE_MAGIC)
    38 	{
    39 		error = SP_ERROR_FILE_FORMAT;
    40 		goto return_error;
    41 	}
    42 
    43 	switch (hdr.compression)
    44 	{
    45 	case SPFILE_COMPRESSION_GZ:
    46 		{
    47 			uint32_t uncompsize = hdr.imagesize - hdr.dataoffs;
    48 			uint32_t compsize = hdr.disksize - hdr.dataoffs;
    49 			uint32_t sectsize = hdr.dataoffs - sizeof(sp_file_hdr_t);
    50 			uLongf destlen = uncompsize;
    51 
    52 			char *tempbuf = (char *)malloc(compsize);
    53 			void *uncompdata = malloc(uncompsize);
    54 			void *sectheader = malloc(sectsize);
    55 
    56 			fread(sectheader, sectsize, 1, fp);
    57 			fread(tempbuf, compsize, 1, fp);
    58 
    59 			z_result = uncompress((Bytef *)uncompdata, &destlen, (Bytef *)tempbuf, compsize);
    60 			free(tempbuf);
    61 			if (z_result != Z_OK)
    62 			{
    63 				free(sectheader);
    64 				free(uncompdata);
    65 				error = SP_ERROR_DECOMPRESSOR;
    66 				goto return_error;
    67 			}
    68 
    69 			base = (uint8_t *)malloc(hdr.imagesize);
    70 			memcpy(base, &hdr, sizeof(sp_file_hdr_t));
    71 			memcpy(base + sizeof(sp_file_hdr_t), sectheader, sectsize);
    72 			free(sectheader);
    73 			memcpy(base + hdr.dataoffs, uncompdata, uncompsize);
    74 			free(uncompdata);
    75 			break;
    76 		}
    77 	case SPFILE_COMPRESSION_NONE:
    78 		{
    79 			base = (uint8_t *)malloc(hdr.imagesize);
    80 			rewind(fp);
    81 			fread(base, hdr.imagesize, 1, fp);
    82 			break;
    83 		}
    84 	default:
    85 		{
    86 			error = SP_ERROR_DECOMPRESSOR;
    87 			goto return_error;
    88 		}
    89 	}
    90 
    91 
    92 	pRuntime = new BaseRuntime();
    93 	if ((error = pRuntime->CreateFromMemory(&hdr, base)) != SP_ERROR_NONE)
    94 	{
    95 		delete pRuntime;
    96 		goto return_error;
    97 	}
    98 
    99 	size_t len;
   100 	
   101 	len = strlen(file);
   102 	for (size_t i = len - 1; i >= 0 && i < len; i--)
   103 	{
   104 		if (file[i] == '/' 
   105 		#if defined WIN32
   106 			|| file[i] == '\\'
   107 		#endif
   108 		)
   109 		{
   110 			pRuntime->m_pPlugin->name = strdup(&file[i+1]);
   111 			break;
   112 		}
   113 	}
   114 
   115 	if (pRuntime->m_pPlugin->name == NULL)
   116 	{
   117 		pRuntime->m_pPlugin->name = strdup(file);
   118 	}
   119 
   120 	pRuntime->ApplyCompilationOptions(co);
   121 
   122     fclose(fp);
   123 
   124 	return pRuntime;
   125 
   126 return_error:
   127 	*err = error;
   128 	if (fp != NULL)
   129 	{
   130     	fclose(fp);
   131 	}
   132 
   133 	return NULL;
   134 }
   135 
   136 SPVM_NATIVE_FUNC SourcePawnEngine2::CreateFakeNative(SPVM_FAKENATIVE_FUNC callback, void *pData)
   137 {
   138 	return g_Jit.CreateFakeNative(callback, pData);
   139 }
   140 
   141 void SourcePawnEngine2::DestroyFakeNative(SPVM_NATIVE_FUNC func)
   142 {
   143 	g_Jit.DestroyFakeNative(func);
   144 }
   145 
   146 const char *SourcePawnEngine2::GetEngineName()
   147 {
   148 	return "SourcePawn 1.1, jit-x86";
   149 }
   150 
   151 const char *SourcePawnEngine2::GetVersionString()
   152 {
   153 	return SVN_FULL_VERSION;
   154 }
   155 
   156 IProfiler *SourcePawnEngine2::GetProfiler()
   157 {
   158 	return m_Profiler;
   159 }
   160 
   161 void SourcePawnEngine2::SetProfiler(IProfiler *profiler)
   162 {
   163 	m_Profiler = profiler;
   164 }
   165 
   166 IDebugListener *SourcePawnEngine2::SetDebugListener(IDebugListener *listener)
   167 {
   168 	return g_engine1.SetDebugListener(listener);
   169 }
   170 
   171 unsigned int SourcePawnEngine2::GetAPIVersion()
   172 {
   173 	return SOURCEPAWN_ENGINE2_API_VERSION;
   174 }
   175 
   176 ICompilation *SourcePawnEngine2::StartCompilation()
   177 {
   178 	return g_Jit.StartCompilation();
   179 }
   180 
   181 const char *SourcePawnEngine2::GetErrorString(int err)
   182 {
   183 	return g_engine1.GetErrorString(err);
   184 }
   185 
   186 bool SourcePawnEngine2::Initialize()
   187 {
   188 	return g_Jit.InitializeJIT();
   189 }
   190 
   191 void SourcePawnEngine2::Shutdown()
   192 {
   193 	g_Jit.ShutdownJIT();
   194 }