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