1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/sourcepawn/vm/sp_vm_engine.cpp Tue Sep 19 22:26:13 2006 +0000
1.3 @@ -0,0 +1,273 @@
1.4 +#include <malloc.h>
1.5 +#include <string.h>
1.6 +#include "sp_file_headers.h"
1.7 +#include "sp_vm_types.h"
1.8 +#include "sp_vm_engine.h"
1.9 +#include "zlib/zlib.h"
1.10 +#include "sp_vm_basecontext.h"
1.11 +
1.12 +using namespace SourcePawn;
1.13 +
1.14 +void *SourcePawnEngine::BaseAlloc(size_t size)
1.15 +{
1.16 + return malloc(size);
1.17 +}
1.18 +
1.19 +void SourcePawnEngine::BaseFree(void *memory)
1.20 +{
1.21 + free(memory);
1.22 +}
1.23 +
1.24 +IPluginContext *SourcePawnEngine::CreateBaseContext(sp_context_t *ctx)
1.25 +{
1.26 + return new BaseContext(ctx);
1.27 +}
1.28 +
1.29 +void SourcePawnEngine::FreeBaseContext(IPluginContext *ctx)
1.30 +{
1.31 + sp_context_t *_ctx = ctx->GetContext();
1.32 + IVirtualMachine *vm = ctx->GetVirtualMachine();
1.33 +
1.34 + vm->FreeContextVars(_ctx);
1.35 +
1.36 + delete ctx;
1.37 +}
1.38 +
1.39 +sp_plugin_t *_ReadPlugin(sp_file_hdr_t *hdr, uint8_t *base, sp_plugin_t *plugin, int *err)
1.40 +{
1.41 + char *nameptr;
1.42 + uint8_t sectnum = 0;
1.43 + sp_file_section_t *secptr = (sp_file_section_t *)(base + sizeof(sp_file_hdr_t));
1.44 +
1.45 + memset(plugin, 0, sizeof(sp_plugin_t));
1.46 +
1.47 + plugin->base = base;
1.48 +
1.49 + while (sectnum < hdr->sections)
1.50 + {
1.51 + nameptr = (char *)(base + hdr->stringtab + secptr->nameoffs);
1.52 +
1.53 + if (!(plugin->pcode) && !strcmp(nameptr, ".code"))
1.54 + {
1.55 + sp_file_code_t *cod = (sp_file_code_t *)(base + secptr->dataoffs);
1.56 + plugin->pcode = base + secptr->dataoffs + cod->code;
1.57 + plugin->pcode_size = cod->codesize;
1.58 + plugin->flags = cod->flags;
1.59 + }
1.60 + else if (!(plugin->data) && !strcmp(nameptr, ".data"))
1.61 + {
1.62 + sp_file_data_t *dat = (sp_file_data_t *)(base + secptr->dataoffs);
1.63 + plugin->data = base + secptr->dataoffs + dat->data;
1.64 + plugin->data_size = dat->datasize;
1.65 + plugin->memory = dat->memsize;
1.66 + }
1.67 + else if (!(plugin->info.publics) && !strcmp(nameptr, ".publics"))
1.68 + {
1.69 + plugin->info.publics_num = secptr->size / sizeof(sp_file_publics_t);
1.70 + plugin->info.publics = (sp_file_publics_t *)(base + secptr->dataoffs);
1.71 + }
1.72 + else if (!(plugin->info.pubvars) && !strcmp(nameptr, ".pubvars"))
1.73 + {
1.74 + plugin->info.pubvars_num = secptr->size / sizeof(sp_file_pubvars_t);
1.75 + plugin->info.pubvars = (sp_file_pubvars_t *)(base + secptr->dataoffs);
1.76 + }
1.77 + else if (!(plugin->info.natives) && !strcmp(nameptr, ".natives"))
1.78 + {
1.79 + plugin->info.natives_num = secptr->size / sizeof(sp_file_natives_t);
1.80 + plugin->info.natives = (sp_file_natives_t *)(base + secptr->dataoffs);
1.81 + }
1.82 + else if (!(plugin->info.stringbase) && !strcmp(nameptr, ".names"))
1.83 + {
1.84 + plugin->info.stringbase = (const char *)(base + secptr->dataoffs);
1.85 + }
1.86 + else if (!(plugin->debug.files) && !strcmp(nameptr, ".dbg.files"))
1.87 + {
1.88 + plugin->debug.files = (sp_fdbg_file_t *)(base + secptr->dataoffs);
1.89 + }
1.90 + else if (!(plugin->debug.lines) && !strcmp(nameptr, ".dbg.lines"))
1.91 + {
1.92 + plugin->debug.lines = (sp_fdbg_line_t *)(base + secptr->dataoffs);
1.93 + }
1.94 + else if (!(plugin->debug.symbols) && !strcmp(nameptr, ".dbg.symbols"))
1.95 + {
1.96 + plugin->debug.symbols = (sp_fdbg_symbol_t *)(base + secptr->dataoffs);
1.97 + }
1.98 + else if (!(plugin->debug.lines_num) && !strcmp(nameptr, ".dbg.info"))
1.99 + {
1.100 + sp_fdbg_info_t *inf = (sp_fdbg_info_t *)(base + secptr->dataoffs);
1.101 + plugin->debug.files_num = inf->num_files;
1.102 + plugin->debug.lines_num = inf->num_lines;
1.103 + plugin->debug.syms_num = inf->num_syms;
1.104 + }
1.105 + else if (!(plugin->debug.stringbase) && !strcmp(nameptr, ".dbg.strings"))
1.106 + {
1.107 + plugin->debug.stringbase = (const char *)(base + secptr->dataoffs);
1.108 + }
1.109 +
1.110 + secptr++;
1.111 + sectnum++;
1.112 + }
1.113 +
1.114 + if (!(plugin->pcode) || !(plugin->data) || !(plugin->info.stringbase))
1.115 + {
1.116 + goto return_error;
1.117 + }
1.118 +
1.119 + if ((plugin->flags & SP_FLAG_DEBUG) && (!(plugin->debug.files) || !(plugin->debug.lines) || !(plugin->debug.symbols)))
1.120 + {
1.121 + goto return_error;
1.122 + }
1.123 +
1.124 + if (err)
1.125 + {
1.126 + *err = SP_ERR_NONE;
1.127 + }
1.128 +
1.129 + return plugin;
1.130 +
1.131 +return_error:
1.132 + if (err)
1.133 + {
1.134 + *err = SP_ERR_FILE_FORMAT;
1.135 + }
1.136 +
1.137 + return NULL;
1.138 +}
1.139 +
1.140 +sp_plugin_t *SourcePawnEngine::LoadFromFilePointer(FILE *fp, int *err)
1.141 +{
1.142 + sp_file_hdr_t hdr;
1.143 + sp_plugin_t *plugin;
1.144 + uint8_t *base;
1.145 + int z_result;
1.146 + int error;
1.147 +
1.148 + if (!fp)
1.149 + {
1.150 + error = SP_ERR_NOT_FOUND;
1.151 + goto return_error;
1.152 + }
1.153 +
1.154 + /* Rewind for safety */
1.155 + rewind(fp);
1.156 + fread(&hdr, sizeof(sp_file_hdr_t), 1, fp);
1.157 +
1.158 + if (hdr.magic != SPFILE_MAGIC)
1.159 + {
1.160 + error = SP_ERR_FILE_FORMAT;
1.161 + goto return_error;
1.162 + }
1.163 +
1.164 + switch (hdr.compression)
1.165 + {
1.166 + case SPFILE_COMPRESSION_GZ:
1.167 + {
1.168 + uint32_t uncompsize = hdr.imagesize - hdr.dataoffs;
1.169 + uint32_t compsize = hdr.disksize - hdr.dataoffs;
1.170 + uint32_t sectsize = hdr.dataoffs - sizeof(sp_file_hdr_t);
1.171 + uLongf destlen = uncompsize;
1.172 +
1.173 + char *tempbuf = (char *)malloc(compsize);
1.174 + void *uncompdata = malloc(uncompsize);
1.175 + void *sectheader = malloc(sectsize);
1.176 +
1.177 + fread(sectheader, sectsize, 1, fp);
1.178 + fread(tempbuf, compsize, 1, fp);
1.179 +
1.180 + z_result = uncompress((Bytef *)uncompdata, &destlen, (Bytef *)tempbuf, compsize);
1.181 + free(tempbuf);
1.182 + if (z_result != Z_OK)
1.183 + {
1.184 + free(sectheader);
1.185 + free(uncompdata);
1.186 + error = SP_ERR_DECOMPRESSOR;
1.187 + goto return_error;
1.188 + }
1.189 +
1.190 + base = (uint8_t *)malloc(hdr.imagesize);
1.191 + memcpy(base, &hdr, sizeof(sp_file_hdr_t));
1.192 + memcpy(base + sizeof(sp_file_hdr_t), sectheader, sectsize);
1.193 + free(sectheader);
1.194 + memcpy(base + hdr.dataoffs, uncompdata, uncompsize);
1.195 + free(uncompdata);
1.196 + break;
1.197 + }
1.198 + case SPFILE_COMPRESSION_NONE:
1.199 + {
1.200 + base = (uint8_t *)malloc(hdr.imagesize);
1.201 + rewind(fp);
1.202 + fread(base, hdr.imagesize, 1, fp);
1.203 + break;
1.204 + }
1.205 + default:
1.206 + {
1.207 + error = SP_ERR_DECOMPRESSOR;
1.208 + goto return_error;
1.209 + }
1.210 + }
1.211 +
1.212 + plugin = (sp_plugin_t *)malloc(sizeof(sp_plugin_t));
1.213 + if (!_ReadPlugin(&hdr, base, plugin, err))
1.214 + {
1.215 + free(plugin);
1.216 + free(base);
1.217 + return NULL;
1.218 + }
1.219 +
1.220 + plugin->allocflags = 0;
1.221 +
1.222 + return plugin;
1.223 +
1.224 +return_error:
1.225 + if (err)
1.226 + {
1.227 + *err = error;
1.228 + }
1.229 + return NULL;
1.230 +}
1.231 +
1.232 +sp_plugin_t *SourcePawnEngine::LoadFromMemory(void *base, sp_plugin_t *plugin, int *err)
1.233 +{
1.234 + sp_file_hdr_t hdr;
1.235 + uint8_t noptr = 0;
1.236 +
1.237 + memcpy(&hdr, base, sizeof(sp_file_hdr_t));
1.238 +
1.239 + if (!plugin)
1.240 + {
1.241 + plugin = (sp_plugin_t *)malloc(sizeof(sp_plugin_t));
1.242 + noptr = 1;
1.243 + }
1.244 +
1.245 + if (!_ReadPlugin(&hdr, (uint8_t *)base, plugin, err))
1.246 + {
1.247 + if (noptr)
1.248 + {
1.249 + free(plugin);
1.250 + }
1.251 + return NULL;
1.252 + }
1.253 +
1.254 + if (!noptr)
1.255 + {
1.256 + plugin->allocflags |= SP_FA_SELF_EXTERNAL;
1.257 + }
1.258 + plugin->allocflags |= SP_FA_BASE_EXTERNAL;
1.259 +
1.260 + return plugin;
1.261 +}
1.262 +
1.263 +int SourcePawnEngine::FreeFromMemory(sp_plugin_t *plugin)
1.264 +{
1.265 + if (!(plugin->allocflags & SP_FA_BASE_EXTERNAL))
1.266 + {
1.267 + free(plugin->base);
1.268 + plugin->base = NULL;
1.269 + }
1.270 + if (!(plugin->allocflags & SP_FA_SELF_EXTERNAL))
1.271 + {
1.272 + free(plugin);
1.273 + }
1.274 +
1.275 + return SP_ERR_NONE;
1.276 +}