From 07a65a8f216cdc6f95eceb8a36f37d8e9e192d31 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Tue, 6 Jan 2026 13:24:06 +0800 Subject: [PATCH] add `py_execo` --- include/pocketpy/pocketpy.h | 2 ++ src/public/CodeExecution.c | 14 +++++++++++ src/public/ModuleSystem.c | 12 +--------- src2/main.c | 47 +++++++++++++++++++++---------------- 4 files changed, 44 insertions(+), 31 deletions(-) diff --git a/include/pocketpy/pocketpy.h b/include/pocketpy/pocketpy.h index 22432871..f42a7799 100644 --- a/include/pocketpy/pocketpy.h +++ b/include/pocketpy/pocketpy.h @@ -185,6 +185,8 @@ PK_API bool py_compile(const char* source, /// Compile a `.py` file into a `.pyc` file. PK_API bool py_compilefile(const char* src_path, const char* dst_path) PY_RAISE; +/// Run a compiled code object. +PK_API bool py_execo(const void* data, int size, const char* filename, py_Ref module) PY_RAISE PY_RETURN; /// Run a source string. /// @param source source string. /// @param filename filename (for error messages). diff --git a/src/public/CodeExecution.c b/src/public/CodeExecution.c index f2a1a67f..ada8b22b 100644 --- a/src/public/CodeExecution.c +++ b/src/public/CodeExecution.c @@ -149,6 +149,20 @@ bool py_exec(const char* source, const char* filename, enum py_CompileMode mode, return ok; } +bool py_execo(const void* data, int size, const char* filename, py_Ref module) { + CodeObject co; + char* err = CodeObject__loads(data, size, filename, &co); + if(err == NULL) { + c11__rtassert(co.src->mode == EXEC_MODE); + c11__rtassert(co.src->is_dynamic == false); + bool ok = pk_exec(&co, module); + CodeObject__dtor(&co); + return ok; + } else { + return RuntimeError("bad code object %s: %s", filename, err); + } +} + bool py_eval(const char* source, py_Ref module) { return py_exec(source, "", EVAL_MODE, module); } diff --git a/src/public/ModuleSystem.c b/src/public/ModuleSystem.c index 4c362b59..e35c0bc9 100644 --- a/src/public/ModuleSystem.c +++ b/src/public/ModuleSystem.c @@ -188,20 +188,10 @@ __SUCCESS: bool ok; if(is_pyc) { - CodeObject co; - char* err = CodeObject__loads(data, data_size, filename->data, &co); - if(err == NULL) { - c11__rtassert(co.src->mode == EXEC_MODE); - c11__rtassert(co.src->is_dynamic == false); - ok = pk_exec(&co, mod); - } else { - RuntimeError("failed to load %s: %s", filename->data, err); - ok = false; - } + ok = py_execo(data, data_size, filename->data, mod); } else { ok = py_exec(data, filename->data, EXEC_MODE, mod); } - py_assign(py_retval(), mod); c11_string__delete(filename); diff --git a/src2/main.c b/src2/main.c index 683b3bf4..70230e7f 100644 --- a/src2/main.c +++ b/src2/main.c @@ -9,21 +9,6 @@ #include #endif -static char* read_file(const char* path) { - FILE* file = fopen(path, "rb"); - if(file == NULL) { - printf("Error: file not found\n"); - return NULL; - } - fseek(file, 0, SEEK_END); - long size = ftell(file); - fseek(file, 0, SEEK_SET); - char* buffer = PK_MALLOC(size + 1); - size = fread(buffer, 1, size, file); - buffer[size] = 0; - return buffer; -} - static char buf[2048]; int main(int argc, char** argv) { @@ -115,9 +100,28 @@ int main(int argc, char** argv) { if(profile) py_profiler_begin(); if(debug) py_debugger_waitforattach("127.0.0.1", 6110); - char* source = read_file(filename); - if(source) { - if(!py_exec(source, filename, EXEC_MODE, NULL)) py_printexc(); + int data_size; + char* data = py_callbacks()->importfile(filename, &data_size); + // check filename endswith .pyc + bool is_pyc = false; + int filename_len = (int)strlen(filename); + if(filename_len >= 4) { + if(filename[filename_len - 4] == '.' && + filename[filename_len - 3] == 'p' && + filename[filename_len - 2] == 'y' && + filename[filename_len - 1] == 'c') { + is_pyc = true; + } + } + + if(data) { + bool ok; + if(is_pyc) { + ok = py_execo(data, data_size, filename, NULL); + } else { + ok = py_exec(data, filename, EXEC_MODE, NULL); + } + if(!ok) py_printexc(); if(profile) { char* json_report = py_profiler_report(); @@ -128,8 +132,11 @@ int main(int argc, char** argv) { } PK_FREE(json_report); } - - PK_FREE(source); + PK_FREE(data); + } else { + printf("Error: cannot open file '%s'\n", filename); + py_finalize(); + return 1; } }