This commit is contained in:
blueloveTH 2023-09-27 05:14:33 +08:00
parent 6f19f8e3fa
commit 888982ef7a
5 changed files with 29 additions and 81 deletions

View File

@ -38,15 +38,14 @@ struct VoidP{
PY_CLASS(VoidP, c, void_p) PY_CLASS(VoidP, c, void_p)
void* ptr; void* ptr;
int base_offset; VoidP(void* ptr): ptr(ptr){}
VoidP(void* ptr): ptr(ptr), base_offset(1){} VoidP(): ptr(nullptr){}
VoidP(): ptr(nullptr), base_offset(1){}
bool operator==(const VoidP& other) const { 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 { 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; }
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{ struct ReflType{
std::string_view name; std::string_view name;
size_t size; size_t size;
std::vector<ReflField> fields;
}; };
inline static std::map<std::string_view, ReflType> _refl_types; 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){ inline void add_refl_type(std::string_view name, size_t size){
ReflType type{name, size, std::move(fields)}; ReflType type{name, size};
std::sort(type.fields.begin(), type.fields.end());
_refl_types[name] = std::move(type); _refl_types[name] = std::move(type);
} }
@ -129,7 +126,6 @@ struct C99ReflType final: ReflType{
C99ReflType(const ReflType& type){ C99ReflType(const ReflType& type){
this->name = type.name; this->name = type.name;
this->size = type.size; this->size = type.size;
this->fields = type.fields;
} }
static void _register(VM* vm, PyObject* mod, PyObject* type); static void _register(VM* vm, PyObject* mod, PyObject* type);

View File

@ -9,7 +9,6 @@ def memcpy(dst: 'void_p', src: 'void_p', size: int) -> None: ...
class _refl: class _refl:
def __call__(self) -> 'struct': ... def __call__(self) -> 'struct': ...
def __getitem__(self, key: str) -> int: ...
def name(self) -> str: ... def name(self) -> str: ...
def size(self) -> int: ... def size(self) -> int: ...
@ -18,7 +17,6 @@ class void_p:
def __sub__(self, i: int) -> 'void_p': ... def __sub__(self, i: int) -> 'void_p': ...
def __eq__(self, other: 'void_p') -> bool: ... def __eq__(self, other: 'void_p') -> bool: ...
def __ne__(self, other: 'void_p') -> bool: ... def __ne__(self, other: 'void_p') -> bool: ...
def offset(self, i: int) -> 'void_p': ...
def hex(self) -> str: ... def hex(self) -> str: ...
@staticmethod @staticmethod
@ -58,12 +56,6 @@ class void_p:
def write_bytes(self, value: bytes) -> None: ... def write_bytes(self, value: bytes) -> None: ...
def write_struct(self, value: 'struct') -> 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: class struct:
@overload @overload
def __init__(self, size: int): ... def __init__(self, size: int): ...

View File

@ -20,9 +20,7 @@ namespace pkpy{
vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){ vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){
VoidP& self = _CAST(VoidP&, obj); VoidP& self = _CAST(VoidP&, obj);
std::stringstream ss; std::stringstream ss;
ss << "<void* at " << self.hex(); ss << "<void* at " << self.hex() << ">";
if(self.base_offset != 1) ss << ", base_offset=" << self.base_offset;
ss << ">";
return VAR(ss.str()); return VAR(ss.str());
}); });
@ -45,28 +43,6 @@ namespace pkpy{
return reinterpret_cast<i64>(self.ptr); 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){ vm->bind__add__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){
VoidP& self = _CAST(VoidP&, lhs); VoidP& self = _CAST(VoidP&, lhs);
i64 offset = CAST(i64, rhs); i64 offset = CAST(i64, rhs);
@ -257,17 +233,6 @@ namespace pkpy{
C99ReflType& self = _CAST(C99ReflType&, args[0]); C99ReflType& self = _CAST(C99ReflType&, args[0]);
return VAR(self.size); 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){ void add_module_c(VM* vm){
@ -319,20 +284,20 @@ void add_module_c(VM* vm){
C99ReflType::register_class(vm, mod); C99ReflType::register_class(vm, mod);
mod->attr().set("NULL", VAR_T(VoidP, nullptr)); mod->attr().set("NULL", VAR_T(VoidP, nullptr));
add_refl_type("char", sizeof(char), {}); add_refl_type("char", sizeof(char));
add_refl_type("uchar", sizeof(unsigned char), {}); add_refl_type("uchar", sizeof(unsigned char));
add_refl_type("short", sizeof(short), {}); add_refl_type("short", sizeof(short));
add_refl_type("ushort", sizeof(unsigned short), {}); add_refl_type("ushort", sizeof(unsigned short));
add_refl_type("int", sizeof(int), {}); add_refl_type("int", sizeof(int));
add_refl_type("uint", sizeof(unsigned int), {}); add_refl_type("uint", sizeof(unsigned int));
add_refl_type("long", sizeof(long), {}); add_refl_type("long", sizeof(long));
add_refl_type("ulong", sizeof(unsigned long), {}); add_refl_type("ulong", sizeof(unsigned long));
add_refl_type("longlong", sizeof(long long), {}); add_refl_type("longlong", sizeof(long long));
add_refl_type("ulonglong", sizeof(unsigned long long), {}); add_refl_type("ulonglong", sizeof(unsigned long long));
add_refl_type("float", sizeof(float), {}); add_refl_type("float", sizeof(float));
add_refl_type("double", sizeof(double), {}); add_refl_type("double", sizeof(double));
add_refl_type("bool", sizeof(bool), {}); add_refl_type("bool", sizeof(bool));
add_refl_type("void_p", sizeof(void*), {}); add_refl_type("void_p", sizeof(void*));
PyObject* void_p_t = mod->attr("void_p"); 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"}){ for(const char* t: {"char", "uchar", "short", "ushort", "int", "uint", "long", "ulong", "longlong", "ulonglong", "float", "double", "bool"}){

View File

@ -3,17 +3,16 @@ import c
c_int = c.refl("int") c_int = c.refl("int")
assert c_int.size() == c.sizeof("int") assert c_int.size() == c.sizeof("int")
array = c.malloc(c.sizeof("int") * 10) 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): 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 = c_int()
x.addr().write_int(0) x.addr().write_int(0)
for i in range(10): 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().write_int(
x.addr().read_int() + i 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) c.memset(array, 0, c.sizeof("int") * 10)
for i in range(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 = c.malloc(c.sizeof("int") * 10)
array2.set_base_offset("int")
c.memcpy(array2, array, c.sizeof("int") * 10) c.memcpy(array2, array, c.sizeof("int") * 10)
for i in range(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(array)
c.free(array2) c.free(array2)

View File

@ -68,11 +68,6 @@ try:
raise Exception('c.struct 的构造方法未能触发 TypeError("expected 1 or 2 arguments")') raise Exception('c.struct 的构造方法未能触发 TypeError("expected 1 or 2 arguments")')
except TypeError: except TypeError:
pass pass
try:
x = c.refl("int")['a']
except KeyError:
pass
# ------------------------------------------------ # ------------------------------------------------
my_struct1 = c.struct(16) my_struct1 = c.struct(16)
assert my_struct1.size() == 16 assert my_struct1.size() == 16