mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
...
This commit is contained in:
parent
6f19f8e3fa
commit
888982ef7a
@ -38,15 +38,14 @@ struct VoidP{
|
||||
PY_CLASS(VoidP, c, void_p)
|
||||
|
||||
void* ptr;
|
||||
int base_offset;
|
||||
VoidP(void* ptr): ptr(ptr), base_offset(1){}
|
||||
VoidP(): ptr(nullptr), base_offset(1){}
|
||||
VoidP(void* ptr): ptr(ptr){}
|
||||
VoidP(): ptr(nullptr){}
|
||||
|
||||
bool operator==(const VoidP& other) const {
|
||||
return ptr == other.ptr && base_offset == other.base_offset;
|
||||
return ptr == other.ptr;
|
||||
}
|
||||
bool operator!=(const VoidP& other) const {
|
||||
return ptr != other.ptr || base_offset != other.base_offset;
|
||||
return ptr != other.ptr;
|
||||
}
|
||||
bool operator<(const VoidP& other) const { return ptr < other.ptr; }
|
||||
bool operator<=(const VoidP& other) const { return ptr <= other.ptr; }
|
||||
@ -113,13 +112,11 @@ struct ReflField{
|
||||
struct ReflType{
|
||||
std::string_view name;
|
||||
size_t size;
|
||||
std::vector<ReflField> fields;
|
||||
};
|
||||
inline static std::map<std::string_view, ReflType> _refl_types;
|
||||
|
||||
inline void add_refl_type(std::string_view name, size_t size, std::vector<ReflField> fields){
|
||||
ReflType type{name, size, std::move(fields)};
|
||||
std::sort(type.fields.begin(), type.fields.end());
|
||||
inline void add_refl_type(std::string_view name, size_t size){
|
||||
ReflType type{name, size};
|
||||
_refl_types[name] = std::move(type);
|
||||
}
|
||||
|
||||
@ -129,7 +126,6 @@ struct C99ReflType final: ReflType{
|
||||
C99ReflType(const ReflType& type){
|
||||
this->name = type.name;
|
||||
this->size = type.size;
|
||||
this->fields = type.fields;
|
||||
}
|
||||
|
||||
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
||||
|
@ -9,7 +9,6 @@ def memcpy(dst: 'void_p', src: 'void_p', size: int) -> None: ...
|
||||
|
||||
class _refl:
|
||||
def __call__(self) -> 'struct': ...
|
||||
def __getitem__(self, key: str) -> int: ...
|
||||
def name(self) -> str: ...
|
||||
def size(self) -> int: ...
|
||||
|
||||
@ -18,7 +17,6 @@ class void_p:
|
||||
def __sub__(self, i: int) -> 'void_p': ...
|
||||
def __eq__(self, other: 'void_p') -> bool: ...
|
||||
def __ne__(self, other: 'void_p') -> bool: ...
|
||||
def offset(self, i: int) -> 'void_p': ...
|
||||
|
||||
def hex(self) -> str: ...
|
||||
@staticmethod
|
||||
@ -58,12 +56,6 @@ class void_p:
|
||||
def write_bytes(self, value: bytes) -> None: ...
|
||||
def write_struct(self, value: 'struct') -> None: ...
|
||||
|
||||
def get_base_offset(self) -> int: ...
|
||||
@overload
|
||||
def set_base_offset(self, offset: int) -> None: ...
|
||||
@overload
|
||||
def set_base_offset(self, offset: str) -> None: ...
|
||||
|
||||
class struct:
|
||||
@overload
|
||||
def __init__(self, size: int): ...
|
||||
|
65
src/cffi.cpp
65
src/cffi.cpp
@ -20,9 +20,7 @@ namespace pkpy{
|
||||
vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){
|
||||
VoidP& self = _CAST(VoidP&, obj);
|
||||
std::stringstream ss;
|
||||
ss << "<void* at " << self.hex();
|
||||
if(self.base_offset != 1) ss << ", base_offset=" << self.base_offset;
|
||||
ss << ">";
|
||||
ss << "<void* at " << self.hex() << ">";
|
||||
return VAR(ss.str());
|
||||
});
|
||||
|
||||
@ -45,28 +43,6 @@ namespace pkpy{
|
||||
return reinterpret_cast<i64>(self.ptr);
|
||||
});
|
||||
|
||||
vm->bind_method<1>(type, "set_base_offset", [](VM* vm, ArgsView args){
|
||||
VoidP& self = _CAST(VoidP&, args[0]);
|
||||
if(is_non_tagged_type(args[1], vm->tp_str)){
|
||||
const Str& type = _CAST(Str&, args[1]);
|
||||
self.base_offset = c99_sizeof(vm, type);
|
||||
}else{
|
||||
self.base_offset = CAST(int, args[1]);
|
||||
}
|
||||
return vm->None;
|
||||
});
|
||||
|
||||
vm->bind_method<0>(type, "get_base_offset", [](VM* vm, ArgsView args){
|
||||
VoidP& self = _CAST(VoidP&, args[0]);
|
||||
return VAR(self.base_offset);
|
||||
});
|
||||
|
||||
vm->bind_method<1>(type, "offset", [](VM* vm, ArgsView args){
|
||||
VoidP& self = _CAST(VoidP&, args[0]);
|
||||
i64 offset = CAST(i64, args[1]);
|
||||
return VAR_T(VoidP, (char*)self.ptr + offset * self.base_offset);
|
||||
});
|
||||
|
||||
vm->bind__add__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){
|
||||
VoidP& self = _CAST(VoidP&, lhs);
|
||||
i64 offset = CAST(i64, rhs);
|
||||
@ -257,17 +233,6 @@ namespace pkpy{
|
||||
C99ReflType& self = _CAST(C99ReflType&, args[0]);
|
||||
return VAR(self.size);
|
||||
});
|
||||
|
||||
vm->bind__getitem__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj, PyObject* key){
|
||||
C99ReflType& self = _CAST(C99ReflType&, obj);
|
||||
const Str& name = CAST(Str&, key);
|
||||
auto it = std::lower_bound(self.fields.begin(), self.fields.end(), name.sv());
|
||||
if(it == self.fields.end() || it->name != name.sv()){
|
||||
vm->KeyError(key);
|
||||
return vm->None;
|
||||
}
|
||||
return VAR(it->offset);
|
||||
});
|
||||
}
|
||||
|
||||
void add_module_c(VM* vm){
|
||||
@ -319,20 +284,20 @@ void add_module_c(VM* vm){
|
||||
C99ReflType::register_class(vm, mod);
|
||||
mod->attr().set("NULL", VAR_T(VoidP, nullptr));
|
||||
|
||||
add_refl_type("char", sizeof(char), {});
|
||||
add_refl_type("uchar", sizeof(unsigned char), {});
|
||||
add_refl_type("short", sizeof(short), {});
|
||||
add_refl_type("ushort", sizeof(unsigned short), {});
|
||||
add_refl_type("int", sizeof(int), {});
|
||||
add_refl_type("uint", sizeof(unsigned int), {});
|
||||
add_refl_type("long", sizeof(long), {});
|
||||
add_refl_type("ulong", sizeof(unsigned long), {});
|
||||
add_refl_type("longlong", sizeof(long long), {});
|
||||
add_refl_type("ulonglong", sizeof(unsigned long long), {});
|
||||
add_refl_type("float", sizeof(float), {});
|
||||
add_refl_type("double", sizeof(double), {});
|
||||
add_refl_type("bool", sizeof(bool), {});
|
||||
add_refl_type("void_p", sizeof(void*), {});
|
||||
add_refl_type("char", sizeof(char));
|
||||
add_refl_type("uchar", sizeof(unsigned char));
|
||||
add_refl_type("short", sizeof(short));
|
||||
add_refl_type("ushort", sizeof(unsigned short));
|
||||
add_refl_type("int", sizeof(int));
|
||||
add_refl_type("uint", sizeof(unsigned int));
|
||||
add_refl_type("long", sizeof(long));
|
||||
add_refl_type("ulong", sizeof(unsigned long));
|
||||
add_refl_type("longlong", sizeof(long long));
|
||||
add_refl_type("ulonglong", sizeof(unsigned long long));
|
||||
add_refl_type("float", sizeof(float));
|
||||
add_refl_type("double", sizeof(double));
|
||||
add_refl_type("bool", sizeof(bool));
|
||||
add_refl_type("void_p", sizeof(void*));
|
||||
|
||||
PyObject* void_p_t = mod->attr("void_p");
|
||||
for(const char* t: {"char", "uchar", "short", "ushort", "int", "uint", "long", "ulong", "longlong", "ulonglong", "float", "double", "bool"}){
|
||||
|
@ -3,17 +3,16 @@ import c
|
||||
c_int = c.refl("int")
|
||||
assert c_int.size() == c.sizeof("int")
|
||||
array = c.malloc(c.sizeof("int") * 10)
|
||||
array.set_base_offset("int")
|
||||
|
||||
assert array.get_base_offset() == c_int.size()
|
||||
|
||||
for i in range(10):
|
||||
array.offset(i).write_int(i)
|
||||
off = c.sizeof("int") * i
|
||||
(array+off).write_int(i)
|
||||
|
||||
x = c_int()
|
||||
x.addr().write_int(0)
|
||||
for i in range(10):
|
||||
i = array.offset(i).read_int()
|
||||
off = c.sizeof("int") * i
|
||||
i = (array+off).read_int()
|
||||
x.addr().write_int(
|
||||
x.addr().read_int() + i
|
||||
)
|
||||
@ -23,13 +22,14 @@ assert x.addr().read_int() == (0+9)*10//2
|
||||
c.memset(array, 0, c.sizeof("int") * 10)
|
||||
|
||||
for i in range(10):
|
||||
assert array.offset(i).read_char() == 0
|
||||
off = c.sizeof("int") * i
|
||||
assert (array+off).read_char() == 0
|
||||
|
||||
array2 = c.malloc(c.sizeof("int") * 10)
|
||||
array2.set_base_offset("int")
|
||||
c.memcpy(array2, array, c.sizeof("int") * 10)
|
||||
for i in range(10):
|
||||
assert array2.offset(i).read_char() == 0
|
||||
off = c.sizeof("int") * i
|
||||
assert (array+off).read_char() == 0
|
||||
|
||||
c.free(array)
|
||||
c.free(array2)
|
||||
|
@ -68,11 +68,6 @@ try:
|
||||
raise Exception('c.struct 的构造方法未能触发 TypeError("expected 1 or 2 arguments")')
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
try:
|
||||
x = c.refl("int")['a']
|
||||
except KeyError:
|
||||
pass
|
||||
# ------------------------------------------------
|
||||
my_struct1 = c.struct(16)
|
||||
assert my_struct1.size() == 16
|
||||
|
Loading…
x
Reference in New Issue
Block a user