|
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 |
{ |
|
dvander@2226
|
109 |
pRuntime->m_pPlugin->name = strdup(&file[i+1]); |
|
dvander@2226
|
110 |
break; |
|
dvander@2226
|
111 |
} |
|
dvander@2193
|
112 |
} |
|
dvander@2193
|
113 |
|
|
dvander@2226
|
114 |
if (pRuntime->m_pPlugin->name == NULL) |
|
dvander@2193
|
115 |
{ |
|
dvander@2226
|
116 |
pRuntime->m_pPlugin->name = strdup(file); |
|
dvander@2193
|
117 |
} |
|
dvander@2193
|
118 |
|
|
dvander@2226
|
119 |
pRuntime->ApplyCompilationOptions(co); |
|
dvander@2226
|
120 |
|
|
dvander@2242
|
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 |
{ |
|
dvander@2783
|
152 |
return SM_FULL_VERSION; |
|
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 |
|
|
dvander@2545
|
207 |
rt->m_pPlugin->name = strdup(name != NULL ? name : "<anonymous>"); |
|
dvander@2545
|
208 |
|
|
dvander@2545
|
209 |
rt->ApplyCompilationOptions(NULL); |
|
dvander@2545
|
210 |
|
|
dvander@2545
|
211 |
return rt; |
|
dvander@2545
|
212 |
} |