mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
rename Struct
This commit is contained in:
parent
3278699d03
commit
518fa3ac07
@ -156,24 +156,24 @@ void _bind(VM* vm, PyObject* obj, const char* sig, Ret(T::*func)(Params...)){
|
|||||||
#define PY_STRUCT_LIKE(wT) \
|
#define PY_STRUCT_LIKE(wT) \
|
||||||
static_assert(std::is_trivially_copyable<wT>::value); \
|
static_assert(std::is_trivially_copyable<wT>::value); \
|
||||||
type->attr().set("__struct__", vm->True); \
|
type->attr().set("__struct__", vm->True); \
|
||||||
vm->bind_func<1>(type, "from_struct", [](VM* vm, ArgsView args){ \
|
vm->bind_func<1>(type, "fromstruct", [](VM* vm, ArgsView args){ \
|
||||||
C99Struct& s = CAST(C99Struct&, args[0]); \
|
Struct& s = CAST(Struct&, args[0]); \
|
||||||
if(s.size != sizeof(wT)) vm->ValueError("size mismatch"); \
|
if(s.size != sizeof(wT)) vm->ValueError("size mismatch"); \
|
||||||
PyObject* obj = vm->new_user_object<wT>(); \
|
PyObject* obj = vm->new_user_object<wT>(); \
|
||||||
memcpy(&_CAST(wT&, obj), s.p, sizeof(wT)); \
|
memcpy(&_CAST(wT&, obj), s.p, sizeof(wT)); \
|
||||||
return obj; \
|
return obj; \
|
||||||
}, {}, BindType::STATICMETHOD); \
|
}, {}, BindType::STATICMETHOD); \
|
||||||
vm->bind_method<0>(type, "to_struct", [](VM* vm, ArgsView args){ \
|
vm->bind_method<0>(type, "tostruct", [](VM* vm, ArgsView args){ \
|
||||||
wT& self = _CAST(wT&, args[0]); \
|
wT& self = _CAST(wT&, args[0]); \
|
||||||
return vm->new_user_object<C99Struct>(&self, sizeof(wT)); \
|
return vm->new_user_object<Struct>(&self, sizeof(wT)); \
|
||||||
}); \
|
}); \
|
||||||
vm->bind_method<0>(type, "addr", [](VM* vm, ArgsView args){ \
|
vm->bind_method<0>(type, "addr", [](VM* vm, ArgsView args){ \
|
||||||
wT& self = _CAST(wT&, args[0]); \
|
wT& self = _CAST(wT&, args[0]); \
|
||||||
return vm->new_user_object<VoidP>(&self); \
|
return vm->new_user_object<VoidP>(&self); \
|
||||||
}); \
|
}); \
|
||||||
vm->bind_method<0>(type, "copy", [](VM* vm, ArgsView args){ \
|
vm->bind_method<0>(type, "copy", [](VM* vm, ArgsView args){ \
|
||||||
wT& self = _CAST(wT&, args[0]); \
|
wT& self = _CAST(wT&, args[0]); \
|
||||||
return vm->new_user_object<wT>(self); \
|
return vm->new_user_object<wT>(self); \
|
||||||
}); \
|
}); \
|
||||||
vm->bind_method<0>(type, "sizeof", [](VM* vm, ArgsView args){ \
|
vm->bind_method<0>(type, "sizeof", [](VM* vm, ArgsView args){ \
|
||||||
return VAR(sizeof(wT)); \
|
return VAR(sizeof(wT)); \
|
||||||
|
@ -60,14 +60,14 @@ POINTER_VAR(const bool*, "bool_p")
|
|||||||
#undef POINTER_VAR
|
#undef POINTER_VAR
|
||||||
|
|
||||||
|
|
||||||
struct C99Struct{
|
struct Struct{
|
||||||
static constexpr int INLINE_SIZE = 24;
|
static constexpr int INLINE_SIZE = 24;
|
||||||
|
|
||||||
char _inlined[INLINE_SIZE];
|
char _inlined[INLINE_SIZE];
|
||||||
char* p;
|
char* p;
|
||||||
int size;
|
int size;
|
||||||
|
|
||||||
C99Struct(int new_size, bool zero_init=true){
|
Struct(int new_size, bool zero_init=true){
|
||||||
this->size = new_size;
|
this->size = new_size;
|
||||||
if(size <= INLINE_SIZE){
|
if(size <= INLINE_SIZE){
|
||||||
p = _inlined;
|
p = _inlined;
|
||||||
@ -77,17 +77,17 @@ struct C99Struct{
|
|||||||
if(zero_init) memset(p, 0, size);
|
if(zero_init) memset(p, 0, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
C99Struct(void* p, int size): C99Struct(size, false){
|
Struct(void* p, int size): Struct(size, false){
|
||||||
if(p != nullptr) memcpy(this->p, p, size);
|
if(p != nullptr) memcpy(this->p, p, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
C99Struct(const C99Struct& other): C99Struct(other.p, other.size){}
|
Struct(const Struct& other): Struct(other.p, other.size){}
|
||||||
~C99Struct(){ if(p!=_inlined) free(p); }
|
~Struct(){ if(p!=_inlined) free(p); }
|
||||||
|
|
||||||
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(Py_<C99Struct>) <= 64);
|
static_assert(sizeof(Py_<Struct>) <= 64);
|
||||||
static_assert(sizeof(Py_<Tuple>) <= 64);
|
static_assert(sizeof(Py_<Tuple>) <= 64);
|
||||||
|
|
||||||
/***********************************************/
|
/***********************************************/
|
||||||
|
@ -105,9 +105,9 @@ def double_(val: float) -> struct: ...
|
|||||||
def bool_(val: bool) -> struct: ...
|
def bool_(val: bool) -> struct: ...
|
||||||
|
|
||||||
class _StructLike(Generic[T]):
|
class _StructLike(Generic[T]):
|
||||||
def to_struct(self) -> struct: ...
|
def tostruct(self) -> struct: ...
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_struct(cls, s: struct) -> T: ...
|
def fromstruct(cls, s: struct) -> T: ...
|
||||||
|
|
||||||
def addr(self) -> 'Pointer[T]': ...
|
def addr(self) -> 'Pointer[T]': ...
|
||||||
def copy(self) -> T: ...
|
def copy(self) -> T: ...
|
||||||
|
@ -63,7 +63,7 @@ class _Pickler:
|
|||||||
|
|
||||||
if getattr(o_t, '__struct__', False):
|
if getattr(o_t, '__struct__', False):
|
||||||
ret.append(_0)
|
ret.append(_0)
|
||||||
ret.append(o.to_struct().hex())
|
ret.append(o.tostruct().hex())
|
||||||
return [index]
|
return [index]
|
||||||
|
|
||||||
if hasattr(o, "__getnewargs__"):
|
if hasattr(o, "__getnewargs__"):
|
||||||
@ -143,7 +143,7 @@ class _Unpickler:
|
|||||||
# generic object
|
# generic object
|
||||||
cls = _find_class(o[0])
|
cls = _find_class(o[0])
|
||||||
if getattr(cls, '__struct__', False):
|
if getattr(cls, '__struct__', False):
|
||||||
inst = cls.from_struct(struct.fromhex(o[1]))
|
inst = cls.fromstruct(struct.fromhex(o[1]))
|
||||||
self.tag(index, inst)
|
self.tag(index, inst)
|
||||||
return inst
|
return inst
|
||||||
else:
|
else:
|
||||||
|
File diff suppressed because one or more lines are too long
34
src/cffi.cpp
34
src/cffi.cpp
@ -37,15 +37,15 @@ namespace pkpy{
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void C99Struct::_register(VM* vm, PyObject* mod, PyObject* type){
|
void Struct::_register(VM* vm, PyObject* mod, PyObject* type){
|
||||||
vm->bind_constructor<2>(type, [](VM* vm, ArgsView args){
|
vm->bind_constructor<2>(type, [](VM* vm, ArgsView args){
|
||||||
Type cls = PK_OBJ_GET(Type, args[0]);
|
Type cls = PK_OBJ_GET(Type, args[0]);
|
||||||
int size = CAST(int, args[1]);
|
int size = CAST(int, args[1]);
|
||||||
return vm->heap.gcnew<C99Struct>(cls, size);
|
return vm->heap.gcnew<Struct>(cls, size);
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bind_method<0>(type, "hex", [](VM* vm, ArgsView args){
|
vm->bind_method<0>(type, "hex", [](VM* vm, ArgsView args){
|
||||||
const C99Struct& self = _CAST(C99Struct&, args[0]);
|
const Struct& self = _CAST(Struct&, args[0]);
|
||||||
SStream ss;
|
SStream ss;
|
||||||
for(int i=0; i<self.size; i++) ss.write_hex((unsigned char)self.p[i]);
|
for(int i=0; i<self.size; i++) ss.write_hex((unsigned char)self.p[i]);
|
||||||
return VAR(ss.str());
|
return VAR(ss.str());
|
||||||
@ -55,7 +55,7 @@ namespace pkpy{
|
|||||||
vm->bind_func<1>(type, "fromhex", [](VM* vm, ArgsView args){
|
vm->bind_func<1>(type, "fromhex", [](VM* vm, ArgsView args){
|
||||||
const Str& s = CAST(Str&, args[0]);
|
const Str& s = CAST(Str&, args[0]);
|
||||||
if(s.size<2 || s.size%2!=0) vm->ValueError("invalid hex string");
|
if(s.size<2 || s.size%2!=0) vm->ValueError("invalid hex string");
|
||||||
C99Struct buffer(s.size/2, false);
|
Struct buffer(s.size/2, false);
|
||||||
for(int i=0; i<s.size; i+=2){
|
for(int i=0; i<s.size; i+=2){
|
||||||
char c = 0;
|
char c = 0;
|
||||||
if(s[i]>='0' && s[i]<='9') c += s[i]-'0';
|
if(s[i]>='0' && s[i]<='9') c += s[i]-'0';
|
||||||
@ -69,48 +69,48 @@ namespace pkpy{
|
|||||||
else vm->ValueError(_S("invalid hex char: '", s[i+1], "'"));
|
else vm->ValueError(_S("invalid hex char: '", s[i+1], "'"));
|
||||||
buffer.p[i/2] = c;
|
buffer.p[i/2] = c;
|
||||||
}
|
}
|
||||||
return vm->new_user_object<C99Struct>(std::move(buffer));
|
return vm->new_user_object<Struct>(std::move(buffer));
|
||||||
}, {}, BindType::STATICMETHOD);
|
}, {}, BindType::STATICMETHOD);
|
||||||
|
|
||||||
vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){
|
vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){
|
||||||
C99Struct& self = _CAST(C99Struct&, obj);
|
Struct& self = _CAST(Struct&, obj);
|
||||||
SStream ss;
|
SStream ss;
|
||||||
ss << "<struct object of " << self.size << " bytes>";
|
ss << "<struct object of " << self.size << " bytes>";
|
||||||
return VAR(ss.str());
|
return VAR(ss.str());
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bind_method<0>(type, "addr", [](VM* vm, ArgsView args){
|
vm->bind_method<0>(type, "addr", [](VM* vm, ArgsView args){
|
||||||
C99Struct& self = _CAST(C99Struct&, args[0]);
|
Struct& self = _CAST(Struct&, args[0]);
|
||||||
return vm->new_user_object<VoidP>(self.p);
|
return vm->new_user_object<VoidP>(self.p);
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bind_method<0>(type, "sizeof", [](VM* vm, ArgsView args){
|
vm->bind_method<0>(type, "sizeof", [](VM* vm, ArgsView args){
|
||||||
C99Struct& self = _CAST(C99Struct&, args[0]);
|
Struct& self = _CAST(Struct&, args[0]);
|
||||||
return VAR(self.size);
|
return VAR(self.size);
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bind_method<0>(type, "copy", [](VM* vm, ArgsView args){
|
vm->bind_method<0>(type, "copy", [](VM* vm, ArgsView args){
|
||||||
const C99Struct& self = _CAST(C99Struct&, args[0]);
|
const Struct& self = _CAST(Struct&, args[0]);
|
||||||
return vm->heap.gcnew<C99Struct>(vm->_tp(args[0]), self);
|
return vm->heap.gcnew<Struct>(vm->_tp(args[0]), self);
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){
|
vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){
|
||||||
C99Struct& self = _CAST(C99Struct&, lhs);
|
Struct& self = _CAST(Struct&, lhs);
|
||||||
if(!vm->is_user_type<C99Struct>(rhs)) return vm->NotImplemented;
|
if(!vm->is_user_type<Struct>(rhs)) return vm->NotImplemented;
|
||||||
C99Struct& other = _CAST(C99Struct&, rhs);
|
Struct& other = _CAST(Struct&, rhs);
|
||||||
bool ok = self.size == other.size && memcmp(self.p, other.p, self.size) == 0;
|
bool ok = self.size == other.size && memcmp(self.p, other.p, self.size) == 0;
|
||||||
return VAR(ok);
|
return VAR(ok);
|
||||||
});
|
});
|
||||||
|
|
||||||
#define BIND_SETGET(T, name) \
|
#define BIND_SETGET(T, name) \
|
||||||
vm->bind(type, "read_" name "(self, offset=0)", [](VM* vm, ArgsView args){ \
|
vm->bind(type, "read_" name "(self, offset=0)", [](VM* vm, ArgsView args){ \
|
||||||
C99Struct& self = _CAST(C99Struct&, args[0]); \
|
Struct& self = _CAST(Struct&, args[0]); \
|
||||||
i64 offset = CAST(i64, args[1]); \
|
i64 offset = CAST(i64, args[1]); \
|
||||||
void* ptr = self.p + offset; \
|
void* ptr = self.p + offset; \
|
||||||
return VAR(*(T*)ptr); \
|
return VAR(*(T*)ptr); \
|
||||||
}); \
|
}); \
|
||||||
vm->bind(type, "write_" name "(self, value, offset=0)", [](VM* vm, ArgsView args){ \
|
vm->bind(type, "write_" name "(self, value, offset=0)", [](VM* vm, ArgsView args){ \
|
||||||
C99Struct& self = _CAST(C99Struct&, args[0]); \
|
Struct& self = _CAST(Struct&, args[0]); \
|
||||||
i64 offset = CAST(i64, args[2]); \
|
i64 offset = CAST(i64, args[2]); \
|
||||||
void* ptr = self.p + offset; \
|
void* ptr = self.p + offset; \
|
||||||
*(T*)ptr = CAST(T, args[1]); \
|
*(T*)ptr = CAST(T, args[1]); \
|
||||||
@ -162,7 +162,7 @@ void add_module_c(VM* vm){
|
|||||||
});
|
});
|
||||||
|
|
||||||
vm->register_user_class<VoidP>(mod, "void_p", true);
|
vm->register_user_class<VoidP>(mod, "void_p", true);
|
||||||
vm->register_user_class<C99Struct>(mod, "struct", true);
|
vm->register_user_class<Struct>(mod, "struct", true);
|
||||||
|
|
||||||
mod->attr().set("NULL", vm->new_user_object<VoidP>(nullptr));
|
mod->attr().set("NULL", vm->new_user_object<VoidP>(nullptr));
|
||||||
|
|
||||||
@ -193,7 +193,7 @@ void add_module_c(VM* vm){
|
|||||||
#define BIND_PRIMITIVE(T, CNAME) \
|
#define BIND_PRIMITIVE(T, CNAME) \
|
||||||
vm->bind_func<1>(mod, CNAME "_", [](VM* vm, ArgsView args){ \
|
vm->bind_func<1>(mod, CNAME "_", [](VM* vm, ArgsView args){ \
|
||||||
T val = CAST(T, args[0]); \
|
T val = CAST(T, args[0]); \
|
||||||
return vm->new_user_object<C99Struct>(&val, sizeof(T)); \
|
return vm->new_user_object<Struct>(&val, sizeof(T)); \
|
||||||
}); \
|
}); \
|
||||||
type = vm->new_type_object(mod, CNAME "_p", vm->_tp_user<VoidP>()); \
|
type = vm->new_type_object(mod, CNAME "_p", vm->_tp_user<VoidP>()); \
|
||||||
mod->attr().set(CNAME "_p", type); \
|
mod->attr().set(CNAME "_p", type); \
|
||||||
|
@ -445,10 +445,10 @@ assert test_mat_copy.inverse_transform_vector(test_vec2_copy) == test_mat_copy.i
|
|||||||
|
|
||||||
import c
|
import c
|
||||||
a = vec2(1, 2)
|
a = vec2(1, 2)
|
||||||
b = a.to_struct()
|
b = a.tostruct()
|
||||||
assert a.sizeof() == 8
|
assert a.sizeof() == 8
|
||||||
assert b.sizeof() == 8
|
assert b.sizeof() == 8
|
||||||
assert vec2.from_struct(b) == a
|
assert vec2.fromstruct(b) == a
|
||||||
|
|
||||||
val = vec2.angle(vec2(-1, 0), vec2(0, -1))
|
val = vec2.angle(vec2(-1, 0), vec2(0, -1))
|
||||||
assert 1.57 < val < 1.58
|
assert 1.57 < val < 1.58
|
||||||
|
Loading…
x
Reference in New Issue
Block a user