mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 19:40:18 +00:00
Merge pull request #178 from Chukobyte/c_import_handler
Added import handler to c api.
This commit is contained in:
commit
f1ff2639af
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,6 +3,7 @@ __pycache__/
|
|||||||
.ipynb_checkpoints
|
.ipynb_checkpoints
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.coverage
|
.coverage
|
||||||
|
.idea
|
||||||
|
|
||||||
src/main
|
src/main
|
||||||
gmon.out
|
gmon.out
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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*);
|
||||||
|
@ -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;
|
||||||
|
18
src/io.cpp
18
src/io.cpp
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
21
src/vm.cpp
21
src/vm.cpp
@ -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);
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user