|
@@ -100,33 +100,33 @@ namespace pkpy{
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void C99Struct::_register(VM* vm, PyObject* mod, PyObject* type){
|
|
void C99Struct::_register(VM* vm, PyObject* mod, PyObject* type){
|
|
|
- vm->bind_constructor<-1>(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]);
|
|
|
- if(args.size() == 1+1){
|
|
|
|
|
- if(is_int(args[1])){
|
|
|
|
|
- int size = _CAST(int, args[1]);
|
|
|
|
|
- return vm->heap.gcnew<C99Struct>(cls, size);
|
|
|
|
|
- }
|
|
|
|
|
- if(is_non_tagged_type(args[1], vm->tp_str)){
|
|
|
|
|
- const Str& s = _CAST(Str&, args[1]);
|
|
|
|
|
- return vm->heap.gcnew<C99Struct>(cls, (void*)s.data, s.size);
|
|
|
|
|
- }
|
|
|
|
|
- if(is_non_tagged_type(args[1], vm->tp_bytes)){
|
|
|
|
|
- const Bytes& b = _CAST(Bytes&, args[1]);
|
|
|
|
|
- return vm->heap.gcnew<C99Struct>(cls, (void*)b.data(), b.size());
|
|
|
|
|
- }
|
|
|
|
|
- vm->TypeError("expected int, str or bytes");
|
|
|
|
|
- return vm->None;
|
|
|
|
|
|
|
+ if(is_int(args[1])){
|
|
|
|
|
+ int size = _CAST(int, args[1]);
|
|
|
|
|
+ return vm->heap.gcnew<C99Struct>(cls, size);
|
|
|
}
|
|
}
|
|
|
- if(args.size() == 1+2){
|
|
|
|
|
- void* p = CAST(void*, args[1]);
|
|
|
|
|
- int size = CAST(int, args[2]);
|
|
|
|
|
- return vm->heap.gcnew<C99Struct>(cls, p, size);
|
|
|
|
|
|
|
+ if(is_non_tagged_type(args[1], vm->tp_bytes)){
|
|
|
|
|
+ const Bytes& b = _CAST(Bytes&, args[1]);
|
|
|
|
|
+ return vm->heap.gcnew<C99Struct>(cls, (void*)b.data(), b.size());
|
|
|
}
|
|
}
|
|
|
- vm->TypeError("expected 1 or 2 arguments");
|
|
|
|
|
|
|
+ vm->TypeError("expected int or bytes");
|
|
|
return vm->None;
|
|
return vm->None;
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
|
|
+ vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){
|
|
|
|
|
+ C99Struct& self = _CAST(C99Struct&, obj);
|
|
|
|
|
+ std::stringstream ss;
|
|
|
|
|
+ ss << "<struct object of " << self.size << " bytes>";
|
|
|
|
|
+ return VAR(ss.str());
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ vm->bind__hash__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){
|
|
|
|
|
+ C99Struct& self = _CAST(C99Struct&, obj);
|
|
|
|
|
+ std::string_view view((char*)self.p, self.size);
|
|
|
|
|
+ return (i64)std::hash<std::string_view>()(view);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
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]);
|
|
C99Struct& self = _CAST(C99Struct&, args[0]);
|
|
|
return VAR_T(VoidP, self.p);
|
|
return VAR_T(VoidP, self.p);
|
|
@@ -142,18 +142,6 @@ namespace pkpy{
|
|
|
return VAR_T(C99Struct, self);
|
|
return VAR_T(C99Struct, self);
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
- vm->bind_method<0>(type, "to_string", [](VM* vm, ArgsView args){
|
|
|
|
|
- C99Struct& self = _CAST(C99Struct&, args[0]);
|
|
|
|
|
- return VAR(Str(self.p, self.size));
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- vm->bind_method<0>(type, "to_bytes", [](VM* vm, ArgsView args){
|
|
|
|
|
- C99Struct& self = _CAST(C99Struct&, args[0]);
|
|
|
|
|
- std::vector<char> buffer(self.size);
|
|
|
|
|
- memcpy(buffer.data(), self.p, self.size);
|
|
|
|
|
- return VAR(Bytes(std::move(buffer)));
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
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);
|
|
C99Struct& self = _CAST(C99Struct&, lhs);
|
|
|
if(!is_non_tagged_type(rhs, C99Struct::_type(vm))) return vm->NotImplemented;
|
|
if(!is_non_tagged_type(rhs, C99Struct::_type(vm))) return vm->NotImplemented;
|
|
@@ -198,8 +186,7 @@ namespace pkpy{
|
|
|
|
|
|
|
|
vm->bind_method<1>(type, "read_struct", [](VM* vm, ArgsView args){
|
|
vm->bind_method<1>(type, "read_struct", [](VM* vm, ArgsView args){
|
|
|
VoidP& self = _CAST(VoidP&, args[0]);
|
|
VoidP& self = _CAST(VoidP&, args[0]);
|
|
|
- const Str& type = CAST(Str&, args[1]);
|
|
|
|
|
- int size = c99_sizeof(vm, type);
|
|
|
|
|
|
|
+ int size = CAST(int, args[1]);
|
|
|
return VAR_T(C99Struct, self.ptr, size);
|
|
return VAR_T(C99Struct, self.ptr, size);
|
|
|
});
|
|
});
|
|
|
|
|
|
|
@@ -211,30 +198,6 @@ namespace pkpy{
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- void C99ReflType::_register(VM* vm, PyObject* mod, PyObject* type){
|
|
|
|
|
- vm->bind_notimplemented_constructor<C99ReflType>(type);
|
|
|
|
|
-
|
|
|
|
|
- vm->bind_method<0>(type, "__call__", [](VM* vm, ArgsView args){
|
|
|
|
|
- C99ReflType& self = _CAST(C99ReflType&, args[0]);
|
|
|
|
|
- return VAR_T(C99Struct, nullptr, self.size);
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- vm->bind_method<0>(type, "__repr__", [](VM* vm, ArgsView args){
|
|
|
|
|
- C99ReflType& self = _CAST(C99ReflType&, args[0]);
|
|
|
|
|
- return VAR("<ctype '" + Str(self.name) + "'>");
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- vm->bind_method<0>(type, "name", [](VM* vm, ArgsView args){
|
|
|
|
|
- C99ReflType& self = _CAST(C99ReflType&, args[0]);
|
|
|
|
|
- return VAR(self.name);
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- vm->bind_method<0>(type, "size", [](VM* vm, ArgsView args){
|
|
|
|
|
- C99ReflType& self = _CAST(C99ReflType&, args[0]);
|
|
|
|
|
- return VAR(self.size);
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
void add_module_c(VM* vm){
|
|
void add_module_c(VM* vm){
|
|
|
PyObject* mod = vm->new_module("c");
|
|
PyObject* mod = vm->new_module("c");
|
|
|
|
|
|
|
@@ -267,50 +230,44 @@ void add_module_c(VM* vm){
|
|
|
|
|
|
|
|
vm->bind_func<1>(mod, "sizeof", [](VM* vm, ArgsView args){
|
|
vm->bind_func<1>(mod, "sizeof", [](VM* vm, ArgsView args){
|
|
|
const Str& type = CAST(Str&, args[0]);
|
|
const Str& type = CAST(Str&, args[0]);
|
|
|
- i64 size = c99_sizeof(vm, type);
|
|
|
|
|
- return VAR(size);
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- vm->bind_func<1>(mod, "refl", [](VM* vm, ArgsView args){
|
|
|
|
|
- const Str& key = CAST(Str&, args[0]);
|
|
|
|
|
- auto it = _refl_types.find(key.sv());
|
|
|
|
|
- if(it == _refl_types.end()) vm->ValueError("reflection type not found");
|
|
|
|
|
- const ReflType& rt = it->second;
|
|
|
|
|
- return VAR_T(C99ReflType, rt);
|
|
|
|
|
|
|
+ auto it = _refl_types.find(type.sv());
|
|
|
|
|
+ if(it != _refl_types.end()) return VAR(it->second.size);
|
|
|
|
|
+ vm->ValueError("not a valid c99 type");
|
|
|
|
|
+ return vm->None;
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
VoidP::register_class(vm, mod);
|
|
VoidP::register_class(vm, mod);
|
|
|
C99Struct::register_class(vm, mod);
|
|
C99Struct::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("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("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"}){
|
|
|
|
|
- mod->attr().set(Str(t) + "_", VAR_T(C99ReflType, _refl_types[t]));
|
|
|
|
|
- mod->attr().set(Str(t) + "_p", void_p_t);
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
|
|
|
|
|
-int c99_sizeof(VM* vm, const Str& type){
|
|
|
|
|
- auto it = _refl_types.find(type.sv());
|
|
|
|
|
- if(it != _refl_types.end()) return it->second.size;
|
|
|
|
|
- vm->ValueError("not a valid c99 type");
|
|
|
|
|
- return 0;
|
|
|
|
|
|
|
+#define BIND_PRIMITIVE(T, name) \
|
|
|
|
|
+ vm->bind_func<1>(mod, name "_", [](VM* vm, ArgsView args){ \
|
|
|
|
|
+ T val = CAST(T, args[0]); \
|
|
|
|
|
+ return VAR_T(C99Struct, &val, sizeof(T)); \
|
|
|
|
|
+ }); \
|
|
|
|
|
+ add_refl_type(name, sizeof(T)); \
|
|
|
|
|
+ mod->attr().set(name "_p", void_p_t); \
|
|
|
|
|
+
|
|
|
|
|
+ BIND_PRIMITIVE(char, "char")
|
|
|
|
|
+ BIND_PRIMITIVE(unsigned char, "uchar")
|
|
|
|
|
+ BIND_PRIMITIVE(short, "short")
|
|
|
|
|
+ BIND_PRIMITIVE(unsigned short, "ushort")
|
|
|
|
|
+ BIND_PRIMITIVE(int, "int")
|
|
|
|
|
+ BIND_PRIMITIVE(unsigned int, "uint")
|
|
|
|
|
+ BIND_PRIMITIVE(long, "long")
|
|
|
|
|
+ BIND_PRIMITIVE(unsigned long, "ulong")
|
|
|
|
|
+ BIND_PRIMITIVE(long long, "longlong")
|
|
|
|
|
+ BIND_PRIMITIVE(unsigned long long, "ulonglong")
|
|
|
|
|
+ BIND_PRIMITIVE(float, "float")
|
|
|
|
|
+ BIND_PRIMITIVE(double, "double")
|
|
|
|
|
+ BIND_PRIMITIVE(bool, "bool")
|
|
|
|
|
+
|
|
|
|
|
+ // add array type
|
|
|
|
|
+ CodeObject_ code = vm->compile(kPythonLibs["c"], "c.py", EXEC_MODE);
|
|
|
|
|
+ vm->_exec(code, mod);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
} // namespace pkpy
|
|
} // namespace pkpy
|