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)
     1 #include <sourcemod_version.h>
     2 #include <stdio.h>
     3 #include <stdlib.h>
     4 #include <string.h>
     5 #include "engine2.h"
     6 #include "x86/jit_x86.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 	pRuntime = new BaseRuntime();
    92 	if ((error = pRuntime->CreateFromMemory(&hdr, base)) != SP_ERROR_NONE)
    93 	{
    94 		delete pRuntime;
    95 		goto return_error;
    96 	}
    97 
    98 	size_t len;
    99 	
   100 	len = strlen(file);
   101 	for (size_t i = len - 1; i < len; i--)
   102 	{
   103 		if (file[i] == '/' 
   104 		#if defined WIN32
   105 			|| file[i] == '\\'
   106 		#endif
   107 		)
   108 		{
   109 			pRuntime->SetName(&file[i+1]);
   110 			break;
   111 		}
   112 	}
   113 
   114 	if (!pRuntime->plugin()->name)
   115 	{
   116 		pRuntime->SetName(file);
   117 	}
   118 
   119 	pRuntime->ApplyCompilationOptions(co);
   120 
   121 	fclose(fp);
   122 
   123 	return pRuntime;
   124 
   125 return_error:
   126 	*err = error;
   127 	if (fp != NULL)
   128 	{
   129     	fclose(fp);
   130 	}
   131 
   132 	return NULL;
   133 }
   134 
   135 SPVM_NATIVE_FUNC SourcePawnEngine2::CreateFakeNative(SPVM_FAKENATIVE_FUNC callback, void *pData)
   136 {
   137 	return g_Jit.CreateFakeNative(callback, pData);
   138 }
   139 
   140 void SourcePawnEngine2::DestroyFakeNative(SPVM_NATIVE_FUNC func)
   141 {
   142 	g_Jit.DestroyFakeNative(func);
   143 }
   144 
   145 const char *SourcePawnEngine2::GetEngineName()
   146 {
   147 	return "SourcePawn 1.1, jit-x86";
   148 }
   149 
   150 const char *SourcePawnEngine2::GetVersionString()
   151 {
   152 	return SM_VERSION_STRING;
   153 }
   154 
   155 IProfiler *SourcePawnEngine2::GetProfiler()
   156 {
   157 	return m_Profiler;
   158 }
   159 
   160 void SourcePawnEngine2::SetProfiler(IProfiler *profiler)
   161 {
   162 	m_Profiler = profiler;
   163 }
   164 
   165 IDebugListener *SourcePawnEngine2::SetDebugListener(IDebugListener *listener)
   166 {
   167 	return g_engine1.SetDebugListener(listener);
   168 }
   169 
   170 unsigned int SourcePawnEngine2::GetAPIVersion()
   171 {
   172 	return SOURCEPAWN_ENGINE2_API_VERSION;
   173 }
   174 
   175 ICompilation *SourcePawnEngine2::StartCompilation()
   176 {
   177 	return g_Jit.StartCompilation();
   178 }
   179 
   180 const char *SourcePawnEngine2::GetErrorString(int err)
   181 {
   182 	return g_engine1.GetErrorString(err);
   183 }
   184 
   185 bool SourcePawnEngine2::Initialize()
   186 {
   187 	return g_Jit.InitializeJIT();
   188 }
   189 
   190 void SourcePawnEngine2::Shutdown()
   191 {
   192 	g_Jit.ShutdownJIT();
   193 }
   194 
   195 IPluginRuntime *SourcePawnEngine2::CreateEmptyRuntime(const char *name, uint32_t memory)
   196 {
   197 	int err;
   198 	BaseRuntime *rt;
   199 
   200 	rt = new BaseRuntime();
   201 	if ((err = rt->CreateBlank(memory)) != SP_ERROR_NONE)
   202 	{
   203 		delete rt;
   204 		return NULL;
   205 	}
   206 
   207 	rt->SetName(name != NULL ? name : "<anonymous>");
   208 
   209 	rt->ApplyCompilationOptions(NULL);
   210 	
   211 	return rt;
   212 }