Merge pull request #178 from Chukobyte/c_import_handler

Added import handler to c api.
This commit is contained in:
BLUELOVETH 2023-11-28 23:52:45 +08:00 committed by GitHub
commit f1ff2639af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 36 additions and 37 deletions

1
.gitignore vendored
View File

@ -3,6 +3,7 @@ __pycache__/
.ipynb_checkpoints .ipynb_checkpoints
.DS_Store .DS_Store
.coverage .coverage
.idea
src/main src/main
gmon.out gmon.out

View File

@ -60,24 +60,6 @@ When you do `import` a module, the VM will try to find it in the following order
### Customized import handler ### Customized import handler
You can use `vm->_import_handler` to provide a custom import handler for the 3rd step. You can use `vm->_import_handler` to provide a custom import handler for the 3rd step.
if both `enable_os` and `PK_ENABLE_OS` are `true`, the default `import_handler` is as follows:
```cpp
inline Bytes _default_import_handler(const Str& name){
std::filesystem::path path(name.sv());
bool exists = std::filesystem::exists(path);
if(!exists) return Bytes();
std::string cname = name.str();
FILE* fp = fopen(cname.c_str(), "rb");
if(!fp) return Bytes();
fseek(fp, 0, SEEK_END);
std::vector<char> buffer(ftell(fp));
fseek(fp, 0, SEEK_SET);
fread(buffer.data(), 1, buffer.size(), fp);
fclose(fp);
return Bytes(std::move(buffer));
};
```
### Import module via cpp ### Import module via cpp

View File

@ -3,7 +3,7 @@
#include "cffi.h" #include "cffi.h"
namespace pkpy{ namespace pkpy{
Bytes _default_import_handler(const Str& name); unsigned char* _default_import_handler(const char*, int, int*);
void add_module_os(VM* vm); void add_module_os(VM* vm);
void add_module_io(VM* vm); void add_module_io(VM* vm);
} }

View File

@ -13,6 +13,7 @@ extern "C" {
typedef struct pkpy_vm_handle pkpy_vm; typedef struct pkpy_vm_handle pkpy_vm;
typedef int (*pkpy_CFunction)(pkpy_vm*); typedef int (*pkpy_CFunction)(pkpy_vm*);
typedef void (*pkpy_COutputHandler)(pkpy_vm*, const char*, int); typedef void (*pkpy_COutputHandler)(pkpy_vm*, const char*, int);
typedef unsigned char* (*pkpy_CImportHandler)(const char*, int, int*);
typedef int pkpy_CName; typedef int pkpy_CName;
typedef int pkpy_CType; typedef int pkpy_CType;
@ -95,6 +96,7 @@ PK_EXPORT pkpy_CName pkpy_name(const char* s);
PK_EXPORT pkpy_CString pkpy_name_to_string(pkpy_CName name); PK_EXPORT pkpy_CString pkpy_name_to_string(pkpy_CName name);
PK_EXPORT void pkpy_compile_to_string(pkpy_vm*, const char* source, const char* filename, int mode, bool* ok, char** out); PK_EXPORT void pkpy_compile_to_string(pkpy_vm*, const char* source, const char* filename, int mode, bool* ok, char** out);
PK_EXPORT void pkpy_set_output_handler(pkpy_vm*, pkpy_COutputHandler handler); PK_EXPORT void pkpy_set_output_handler(pkpy_vm*, pkpy_COutputHandler handler);
PK_EXPORT void pkpy_set_import_handler(pkpy_vm*, pkpy_CImportHandler handler);
/* REPL */ /* REPL */
PK_EXPORT void* pkpy_new_repl(pkpy_vm*); PK_EXPORT void* pkpy_new_repl(pkpy_vm*);

View File

@ -142,7 +142,7 @@ public:
PrintFunc _stdout; PrintFunc _stdout;
PrintFunc _stderr; PrintFunc _stderr;
Bytes (*_import_handler)(const Str& name); unsigned char* (*_import_handler)(const char*, int, int*);
// for quick access // for quick access
Type tp_object, tp_type, tp_int, tp_float, tp_bool, tp_str; Type tp_object, tp_type, tp_int, tp_float, tp_bool, tp_str;

View File

@ -23,14 +23,13 @@ static size_t io_fread(void* buffer, size_t size, size_t count, FILE* fp){
} }
Bytes _default_import_handler(const Str& name){ unsigned char* _default_import_handler(const char* name_p, int name_size, int* out_size){
#if PK_ENABLE_OS #if PK_ENABLE_OS
std::filesystem::path path(name.sv()); std::string name(name_p, name_size);
bool exists = std::filesystem::exists(path); bool exists = std::filesystem::exists(std::filesystem::path(name));
if(!exists) return Bytes(); if(!exists) return nullptr;
std::string cname = name.str(); FILE* fp = io_fopen(name.c_str(), "rb");
FILE* fp = io_fopen(cname.c_str(), "rb"); if(!fp) return nullptr;
if(!fp) return Bytes();
fseek(fp, 0, SEEK_END); fseek(fp, 0, SEEK_END);
int buffer_size = ftell(fp); int buffer_size = ftell(fp);
unsigned char* buffer = new unsigned char[buffer_size]; unsigned char* buffer = new unsigned char[buffer_size];
@ -38,9 +37,10 @@ Bytes _default_import_handler(const Str& name){
size_t sz = io_fread(buffer, 1, buffer_size, fp); size_t sz = io_fread(buffer, 1, buffer_size, fp);
PK_UNUSED(sz); PK_UNUSED(sz);
fclose(fp); fclose(fp);
return Bytes(buffer, buffer_size); *out_size = buffer_size;
return buffer;
#else #else
return Bytes(); return nullptr;
#endif #endif
}; };

View File

@ -584,6 +584,11 @@ void pkpy_set_output_handler(pkpy_vm* vm_handle, pkpy_COutputHandler handler){
vm->_stdout = reinterpret_cast<PrintFunc>(handler); vm->_stdout = reinterpret_cast<PrintFunc>(handler);
} }
void pkpy_set_import_handler(pkpy_vm* vm_handle, pkpy_CImportHandler handler){
VM* vm = (VM*) vm_handle;
vm->_import_handler = handler;
}
void* pkpy_new_repl(pkpy_vm* vm_handle){ void* pkpy_new_repl(pkpy_vm* vm_handle){
return new REPL((VM*)vm_handle); return new REPL((VM*)vm_handle);
} }

View File

@ -82,9 +82,11 @@ namespace pkpy{
callstack.reserve(8); callstack.reserve(8);
_main = nullptr; _main = nullptr;
_last_exception = nullptr; _last_exception = nullptr;
_import_handler = [](const Str& name) { _import_handler = [](const char* name_p, int name_size, int* out_size) -> unsigned char*{
PK_UNUSED(name); PK_UNUSED(name_p);
return Bytes(); PK_UNUSED(name_size);
PK_UNUSED(out_size);
return nullptr;
}; };
init_builtin_types(); init_builtin_types();
} }
@ -335,17 +337,20 @@ namespace pkpy{
bool is_init = false; bool is_init = false;
auto it = _lazy_modules.find(name); auto it = _lazy_modules.find(name);
if(it == _lazy_modules.end()){ if(it == _lazy_modules.end()){
Bytes b = _import_handler(filename); int out_size;
if(!b){ unsigned char* out = _import_handler(filename.data, filename.size, &out_size);
if(out == nullptr){
filename = path.replace('.', kPlatformSep).str() + kPlatformSep + "__init__.py"; filename = path.replace('.', kPlatformSep).str() + kPlatformSep + "__init__.py";
is_init = true; is_init = true;
b = _import_handler(filename); out = _import_handler(filename.data, filename.size, &out_size);
} }
if(!b){ if(out == nullptr){
if(throw_err) ImportError(fmt("module ", path.escape(), " not found")); if(throw_err) ImportError(fmt("module ", path.escape(), " not found"));
else return nullptr; else return nullptr;
} }
source = Str(b.str()); PK_ASSERT(out_size >= 0)
source = Str(std::string_view((char*)out, out_size));
free(out);
}else{ }else{
source = it->second; source = it->second;
_lazy_modules.erase(it); _lazy_modules.erase(it);

View File

@ -246,6 +246,10 @@ void pkpy_set_output_handler(pkpy_vm* vm, pkpy_COutputHandler handler) {
} }
void pkpy_set_import_handler(pkpy_vm* vm, pkpy_CImportHandler handler) {
}
void* pkpy_new_repl(pkpy_vm* vm) { void* pkpy_new_repl(pkpy_vm* vm) {
void* returnValue; void* returnValue;
return returnValue; return returnValue;