From 7964cc1af6e5a1a3772e7b7d4856c2d44283cf7a Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Mon, 9 Sep 2024 13:20:11 +0800 Subject: [PATCH 1/5] support dll load --- .gitignore | 4 +--- build_dll.sh | 6 ++++++ src/interpreter/dll.c | 36 ++++++++++++++++++++++++++++++++++++ src/public/modules.c | 7 ++++--- src2/hello.c | 15 +++++++++++++++ 5 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 build_dll.sh create mode 100644 src/interpreter/dll.c create mode 100644 src2/hello.c diff --git a/.gitignore b/.gitignore index 5e644ff6..efd5fa98 100644 --- a/.gitignore +++ b/.gitignore @@ -26,9 +26,7 @@ APPS build main -pocketpy.dSYM -libpocketpy.dylib.dSYM/ -main.dSYM/ +*.dSYM docs/references.md diff --git a/build_dll.sh b/build_dll.sh new file mode 100644 index 00000000..0c3110b5 --- /dev/null +++ b/build_dll.sh @@ -0,0 +1,6 @@ +set -e + +FLAGS="-std=c11 -Iinclude -O0 -Wfatal-errors -g -DDEBUG -DPK_ENABLE_OS=1" + +clang $FLAGS -shared -fPIC src2/hello.c -o libhello.dylib -undefined dynamic_lookup + diff --git a/src/interpreter/dll.c b/src/interpreter/dll.c new file mode 100644 index 00000000..2a4c7e86 --- /dev/null +++ b/src/interpreter/dll.c @@ -0,0 +1,36 @@ +#include "pocketpy/pocketpy.h" + +#if PK_IS_DESKTOP_PLATFORM + +#ifdef _WIN32 +#include +#else +#include +#endif + +typedef bool (*py_module_initialize_t)() PY_RAISE PY_RETURN; + +int load_module_from_dll_desktop_only(const char* path) PY_RAISE PY_RETURN { + const char* f_init_name = "py_module_initialize"; +#ifdef _WIN32 + HMODULE dll = LoadLibraryA(path); + if(dll == NULL) return 0; + py_module_initialize_t f_init = (py_module_initialize_t)GetProcAddress(dll, init_func); +#else + void* dll = dlopen(path, RTLD_LAZY); + if(dll == NULL) return 0; + py_module_initialize_t f_init = (py_module_initialize_t)dlsym(dll, f_init_name); +#endif + if(f_init == NULL) return 0; + bool success = f_init(); + if(!success) return -1; + return 1; +} + +#else + +int load_module_from_dll_desktop_only(const char* path) PY_RAISE PY_RETURN { + return 0; +} + +#endif \ No newline at end of file diff --git a/src/public/modules.c b/src/public/modules.c index df1a928a..6be8c503 100644 --- a/src/public/modules.c +++ b/src/public/modules.c @@ -63,9 +63,9 @@ py_Ref py_newmodule(const char* path) { return py_getmodule(path); } -int py_import(const char* path_cstr) { - // printf("importing %s\n", path_cstr); +int load_module_from_dll_desktop_only(const char* path) PY_RAISE PY_RETURN; +int py_import(const char* path_cstr) { VM* vm = pk_current_vm; c11_sv path = {path_cstr, strlen(path_cstr)}; if(path.size == 0) return ValueError("empty module name"); @@ -142,7 +142,8 @@ int py_import(const char* path_cstr) { c11_string__delete(filename); c11_string__delete(slashed_path); - return 0; + // not found + return load_module_from_dll_desktop_only(path_cstr); __SUCCESS: do { diff --git a/src2/hello.c b/src2/hello.c new file mode 100644 index 00000000..92520fdb --- /dev/null +++ b/src2/hello.c @@ -0,0 +1,15 @@ +#include "pocketpy.h" + +static bool hello_add(int argc, py_Ref argv){ + PY_CHECK_ARGC(2); + return py_binaryadd(py_arg(0), py_arg(1)); +} + +bool py_module_initialize(){ + py_GlobalRef mod = py_newmodule("hello"); + + py_bindfunc(mod, "add", hello_add); + + py_assign(py_retval(), mod); + return true; +} \ No newline at end of file From 4ccc4cb138eac0041d5f9ed5d02087bc2531b7c5 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Mon, 9 Sep 2024 13:26:43 +0800 Subject: [PATCH 2/5] ... --- src/public/internal.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/public/internal.c b/src/public/internal.c index 0480388e..49e1f305 100644 --- a/src/public/internal.c +++ b/src/public/internal.c @@ -20,6 +20,10 @@ static VM pk_default_vm; static VM* pk_all_vm[16]; void py_initialize() { + if(!pk_current_vm){ + c11__abort("py_initialize() can only be called once!"); + } + MemoryPools__initialize(); py_Name__initialize(); From 2742414fa71a1131e7205b8a4a92d47a6202f560 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Mon, 9 Sep 2024 13:31:57 +0800 Subject: [PATCH 3/5] ... --- build_dll.sh | 4 ++-- src/public/internal.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build_dll.sh b/build_dll.sh index 0c3110b5..772a07fe 100644 --- a/build_dll.sh +++ b/build_dll.sh @@ -2,5 +2,5 @@ set -e FLAGS="-std=c11 -Iinclude -O0 -Wfatal-errors -g -DDEBUG -DPK_ENABLE_OS=1" -clang $FLAGS -shared -fPIC src2/hello.c -o libhello.dylib -undefined dynamic_lookup - +# link libpocketpy.dylib +clang $FLAGS -shared -fPIC src2/hello.c -o libhello.dylib -L. -lpocketpy diff --git a/src/public/internal.c b/src/public/internal.c index 49e1f305..94efb519 100644 --- a/src/public/internal.c +++ b/src/public/internal.c @@ -20,7 +20,7 @@ static VM pk_default_vm; static VM* pk_all_vm[16]; void py_initialize() { - if(!pk_current_vm){ + if(pk_current_vm){ c11__abort("py_initialize() can only be called once!"); } From 34cc526104bdf15496df87f5e226f5881779bd52 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Mon, 9 Sep 2024 13:47:14 +0800 Subject: [PATCH 4/5] ... --- CMakeLists.txt | 2 +- src/interpreter/dll.c | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c17d50f..eb63418c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,7 +69,7 @@ else() target_link_libraries(main ${PROJECT_NAME}) endif() -# link math library if(UNIX) target_link_libraries(${PROJECT_NAME} m) + target_link_libraries(${PROJECT_NAME} dl) endif() diff --git a/src/interpreter/dll.c b/src/interpreter/dll.c index 2a4c7e86..c60b8ec2 100644 --- a/src/interpreter/dll.c +++ b/src/interpreter/dll.c @@ -3,7 +3,8 @@ #if PK_IS_DESKTOP_PLATFORM #ifdef _WIN32 -#include +void* LoadLibraryA(const char*); +void* GetProcAddress(void*, const char*); #else #include #endif @@ -13,9 +14,9 @@ typedef bool (*py_module_initialize_t)() PY_RAISE PY_RETURN; int load_module_from_dll_desktop_only(const char* path) PY_RAISE PY_RETURN { const char* f_init_name = "py_module_initialize"; #ifdef _WIN32 - HMODULE dll = LoadLibraryA(path); + void* dll = LoadLibraryA(path); if(dll == NULL) return 0; - py_module_initialize_t f_init = (py_module_initialize_t)GetProcAddress(dll, init_func); + py_module_initialize_t f_init = (py_module_initialize_t)GetProcAddress(dll, f_init_name); #else void* dll = dlopen(path, RTLD_LAZY); if(dll == NULL) return 0; From ce8d9600a4192d5393838903d22d14aef0374805 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Mon, 9 Sep 2024 13:49:39 +0800 Subject: [PATCH 5/5] ... --- build.sh | 2 +- build_g.sh | 2 +- run_profile.sh | 2 +- run_tests.sh | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build.sh b/build.sh index 9123bf92..b9c50eb4 100644 --- a/build.sh +++ b/build.sh @@ -19,7 +19,7 @@ SRC=$(find src/ -name "*.c") echo "> Compiling and linking source files... " -clang -std=c11 -O2 -Wfatal-errors -Iinclude -DNDEBUG -o main src2/main.c $SRC -lm +clang -std=c11 -O2 -Wfatal-errors -Iinclude -DNDEBUG -o main src2/main.c $SRC -lm -ldl if [ $? -eq 0 ]; then echo "Build completed. Type \"./main\" to enter REPL." diff --git a/build_g.sh b/build_g.sh index 9909b282..b9570dd3 100644 --- a/build_g.sh +++ b/build_g.sh @@ -4,7 +4,7 @@ python prebuild.py SRC=$(find src/ -name "*.c") -FLAGS="-std=c11 -lm -Iinclude -O0 -Wfatal-errors -g -DDEBUG -DPK_ENABLE_OS=1" +FLAGS="-std=c11 -lm -ldl -Iinclude -O0 -Wfatal-errors -g -DDEBUG -DPK_ENABLE_OS=1" SANITIZE_FLAGS="-fsanitize=address,leak,undefined" diff --git a/run_profile.sh b/run_profile.sh index cc1528ea..28cc8c37 100644 --- a/run_profile.sh +++ b/run_profile.sh @@ -4,7 +4,7 @@ python prebuild.py SRC=$(find src/ -name "*.c") -gcc -pg -Og -std=c11 -Wfatal-errors -o main $SRC src2/main.c -Iinclude -lm -DNDEBUG -flto +gcc -pg -Og -std=c11 -Wfatal-errors -o main $SRC src2/main.c -Iinclude -lm -ldl -DNDEBUG -flto ./main benchmarks/fib.py gprof main gmon.out > gprof.txt rm gmon.out diff --git a/run_tests.sh b/run_tests.sh index 14915a2f..d827701b 100644 --- a/run_tests.sh +++ b/run_tests.sh @@ -4,7 +4,7 @@ python prebuild.py SRC=$(find src/ -name "*.c") -clang -std=c11 --coverage -O1 -Wfatal-errors -o main src2/main.c $SRC -Iinclude -DPK_ENABLE_OS=1 -DPK_ENABLE_PROFILER=1 -lm -DNDEBUG +clang -std=c11 --coverage -O1 -Wfatal-errors -o main src2/main.c $SRC -Iinclude -DPK_ENABLE_OS=1 -DPK_ENABLE_PROFILER=1 -lm -ldl -DNDEBUG python scripts/run_tests.py