dvander@2783: #include dvander@2193: #include dvander@2193: #include dvander@2193: #include dvander@2193: #include "engine2.h" dvander@2193: #include "x86/jit_x86.h" dvander@2193: #include "zlib/zlib.h" dvander@2193: #include "BaseRuntime.h" dvander@2193: #include "sp_vm_engine.h" dvander@2193: dvander@2193: using namespace SourcePawn; dvander@2193: dvander@2193: SourcePawnEngine2::SourcePawnEngine2() dvander@2193: { dvander@2193: m_Profiler = NULL; dvander@2193: } dvander@2193: dvander@2193: IPluginRuntime *SourcePawnEngine2::LoadPlugin(ICompilation *co, const char *file, int *err) dvander@2193: { dvander@2193: sp_file_hdr_t hdr; dvander@2193: uint8_t *base; dvander@2193: int z_result; dvander@2193: int error; dvander@2193: BaseRuntime *pRuntime; dvander@2193: dvander@2193: FILE *fp = fopen(file, "rb"); dvander@2193: dvander@2193: if (!fp) dvander@2193: { dvander@2193: error = SP_ERROR_NOT_FOUND; dvander@2193: goto return_error; dvander@2193: } dvander@2193: dvander@2193: /* Rewind for safety */ dvander@2193: fread(&hdr, sizeof(sp_file_hdr_t), 1, fp); dvander@2193: dvander@2193: if (hdr.magic != SPFILE_MAGIC) dvander@2193: { dvander@2193: error = SP_ERROR_FILE_FORMAT; dvander@2193: goto return_error; dvander@2193: } dvander@2193: dvander@2193: switch (hdr.compression) dvander@2193: { dvander@2193: case SPFILE_COMPRESSION_GZ: dvander@2193: { dvander@2193: uint32_t uncompsize = hdr.imagesize - hdr.dataoffs; dvander@2193: uint32_t compsize = hdr.disksize - hdr.dataoffs; dvander@2193: uint32_t sectsize = hdr.dataoffs - sizeof(sp_file_hdr_t); dvander@2193: uLongf destlen = uncompsize; dvander@2193: dvander@2193: char *tempbuf = (char *)malloc(compsize); dvander@2193: void *uncompdata = malloc(uncompsize); dvander@2193: void *sectheader = malloc(sectsize); dvander@2193: dvander@2193: fread(sectheader, sectsize, 1, fp); dvander@2193: fread(tempbuf, compsize, 1, fp); dvander@2193: dvander@2193: z_result = uncompress((Bytef *)uncompdata, &destlen, (Bytef *)tempbuf, compsize); dvander@2193: free(tempbuf); dvander@2193: if (z_result != Z_OK) dvander@2193: { dvander@2193: free(sectheader); dvander@2193: free(uncompdata); dvander@2193: error = SP_ERROR_DECOMPRESSOR; dvander@2193: goto return_error; dvander@2193: } dvander@2193: dvander@2193: base = (uint8_t *)malloc(hdr.imagesize); dvander@2193: memcpy(base, &hdr, sizeof(sp_file_hdr_t)); dvander@2193: memcpy(base + sizeof(sp_file_hdr_t), sectheader, sectsize); dvander@2193: free(sectheader); dvander@2193: memcpy(base + hdr.dataoffs, uncompdata, uncompsize); dvander@2193: free(uncompdata); dvander@2193: break; dvander@2193: } dvander@2193: case SPFILE_COMPRESSION_NONE: dvander@2193: { dvander@2193: base = (uint8_t *)malloc(hdr.imagesize); dvander@2193: rewind(fp); dvander@2193: fread(base, hdr.imagesize, 1, fp); dvander@2193: break; dvander@2193: } dvander@2193: default: dvander@2193: { dvander@2193: error = SP_ERROR_DECOMPRESSOR; dvander@2193: goto return_error; dvander@2193: } dvander@2193: } dvander@2193: dvander@2226: pRuntime = new BaseRuntime(); dvander@2226: if ((error = pRuntime->CreateFromMemory(&hdr, base)) != SP_ERROR_NONE) dvander@2193: { dvander@2226: delete pRuntime; dvander@2226: goto return_error; dvander@2193: } dvander@2193: dvander@2226: size_t len; dvander@2226: dvander@2226: len = strlen(file); ds@3261: for (size_t i = len - 1; i < len; i--) dvander@2193: { dvander@2226: if (file[i] == '/' dvander@2226: #if defined WIN32 dvander@2226: || file[i] == '\\' dvander@2226: #endif dvander@2226: ) dvander@2226: { danderson@3977: pRuntime->SetName(&file[i+1]); dvander@2226: break; dvander@2226: } dvander@2193: } dvander@2193: danderson@3977: if (!pRuntime->plugin()->name) dvander@2193: { danderson@3977: pRuntime->SetName(file); dvander@2193: } dvander@2193: dvander@2226: pRuntime->ApplyCompilationOptions(co); dvander@2226: danderson@3977: fclose(fp); dvander@2242: dvander@2193: return pRuntime; dvander@2193: dvander@2193: return_error: dvander@2193: *err = error; dvander@2376: if (fp != NULL) dvander@2376: { dvander@2376: fclose(fp); dvander@2376: } dvander@2193: dvander@2193: return NULL; dvander@2193: } dvander@2193: dvander@2193: SPVM_NATIVE_FUNC SourcePawnEngine2::CreateFakeNative(SPVM_FAKENATIVE_FUNC callback, void *pData) dvander@2193: { dvander@2226: return g_Jit.CreateFakeNative(callback, pData); dvander@2193: } dvander@2193: dvander@2193: void SourcePawnEngine2::DestroyFakeNative(SPVM_NATIVE_FUNC func) dvander@2193: { dvander@2226: g_Jit.DestroyFakeNative(func); dvander@2193: } dvander@2193: dvander@2193: const char *SourcePawnEngine2::GetEngineName() dvander@2193: { dvander@2193: return "SourcePawn 1.1, jit-x86"; dvander@2193: } dvander@2193: dvander@2193: const char *SourcePawnEngine2::GetVersionString() dvander@2193: { asherkin@3630: return SM_VERSION_STRING; dvander@2193: } dvander@2193: dvander@2193: IProfiler *SourcePawnEngine2::GetProfiler() dvander@2193: { dvander@2193: return m_Profiler; dvander@2193: } dvander@2193: dvander@2193: void SourcePawnEngine2::SetProfiler(IProfiler *profiler) dvander@2193: { dvander@2193: m_Profiler = profiler; dvander@2193: } dvander@2193: dvander@2193: IDebugListener *SourcePawnEngine2::SetDebugListener(IDebugListener *listener) dvander@2193: { dvander@2193: return g_engine1.SetDebugListener(listener); dvander@2193: } dvander@2193: dvander@2193: unsigned int SourcePawnEngine2::GetAPIVersion() dvander@2193: { dvander@2193: return SOURCEPAWN_ENGINE2_API_VERSION; dvander@2193: } dvander@2193: dvander@2193: ICompilation *SourcePawnEngine2::StartCompilation() dvander@2193: { dvander@2226: return g_Jit.StartCompilation(); dvander@2193: } dvander@2193: dvander@2193: const char *SourcePawnEngine2::GetErrorString(int err) dvander@2193: { dvander@2193: return g_engine1.GetErrorString(err); dvander@2193: } dvander@2226: dvander@2226: bool SourcePawnEngine2::Initialize() dvander@2226: { dvander@2226: return g_Jit.InitializeJIT(); dvander@2226: } dvander@2226: dvander@2226: void SourcePawnEngine2::Shutdown() dvander@2226: { dvander@2226: g_Jit.ShutdownJIT(); dvander@2226: } dvander@2545: dvander@2545: IPluginRuntime *SourcePawnEngine2::CreateEmptyRuntime(const char *name, uint32_t memory) dvander@2545: { dvander@2545: int err; dvander@2545: BaseRuntime *rt; dvander@2545: dvander@2545: rt = new BaseRuntime(); dvander@2545: if ((err = rt->CreateBlank(memory)) != SP_ERROR_NONE) dvander@2545: { dvander@2545: delete rt; dvander@2545: return NULL; dvander@2545: } dvander@2545: danderson@3977: rt->SetName(name != NULL ? name : ""); dvander@2545: dvander@2545: rt->ApplyCompilationOptions(NULL); dvander@2545: dvander@2545: return rt; dvander@2545: }