blueloveTH 2 年之前
父節點
當前提交
54f376c189
共有 5 個文件被更改,包括 59 次插入34 次删除
  1. 2 0
      src/c.pyi
  2. 50 32
      src/cffi.h
  3. 1 1
      src/dict.h
  4. 1 1
      src/namedict.h
  5. 5 0
      src/obj.h

+ 2 - 0
src/c.pyi

@@ -64,3 +64,5 @@ class struct:
     def addr(self) -> 'void_p': ...
     def copy(self) -> 'struct': ...
     def size(self) -> int: ...
+    def __eq__(self, other: 'struct') -> bool: ...
+    def __ne__(self, other: 'struct') -> bool: ...

+ 50 - 32
src/cffi.h

@@ -222,6 +222,20 @@ struct C99Struct{
             return VAR_T(C99Struct, self);
         });
 
+        vm->bind__eq__(OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){
+            C99Struct& self = _CAST(C99Struct&, lhs);
+            if(!is_non_tagged_type(rhs, C99Struct::_type(vm))) return false;
+            C99Struct& other = _CAST(C99Struct&, rhs);
+            return self.size == other.size && memcmp(self.p, other.p, self.size) == 0;
+        });
+
+        vm->bind__ne__(OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){
+            C99Struct& self = _CAST(C99Struct&, lhs);
+            if(!is_non_tagged_type(rhs, C99Struct::_type(vm))) return true;
+            C99Struct& other = _CAST(C99Struct&, rhs);
+            return self.size != other.size || memcmp(self.p, other.p, self.size) != 0;
+        });
+
         // patch VoidP
         type = vm->_t(VoidP::_type(vm));
 
@@ -241,43 +255,33 @@ struct C99Struct{
     }
 };
 
+struct ReflField{
+    std::string_view name;
+    int offset;
+    bool operator<(const ReflField& other) const{ return name < other.name; }
+    bool operator==(const ReflField& other) const{ return name == other.name; }
+    bool operator!=(const ReflField& other) const{ return name != other.name; }
+    bool operator<(std::string_view other) const{ return name < other; }
+    bool operator==(std::string_view other) const{ return name == other; }
+    bool operator!=(std::string_view other) const{ return name != other; }
+};
 
 struct ReflType{
     std::string_view name;
     size_t size;
-    std::map<std::string_view, int> fields;
+    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::initializer_list<std::pair<std::string_view, int>> fields){
-    ReflType type{name, size, {}};
-    for(auto& [name, offset] : fields){
-        type.fields[name] = offset;
-    }
+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());
     _refl_types[name] = std::move(type);
 }
 
 inline static int c99_sizeof(VM* vm, const Str& type){
-    static const std::map<std::string_view, i64> c99_sizes = {
-        {"char", sizeof(char)},
-        {"uchar", sizeof(unsigned char)},
-        {"short", sizeof(short)},
-        {"ushort", sizeof(unsigned short)},
-        {"int", sizeof(int)},
-        {"uint", sizeof(unsigned int)},
-        {"long", sizeof(long)},
-        {"ulong", sizeof(unsigned long)},
-        {"longlong", sizeof(long long)},
-        {"ulonglong", sizeof(unsigned long long)},
-        {"float", sizeof(float)},
-        {"double", sizeof(double)},
-        {"bool", sizeof(bool)},
-        {"void_p", sizeof(void*)}
-    };
-    auto it = c99_sizes.find(type.sv());
-    if(it != c99_sizes.end()) return it->second;
-    auto it2 = _refl_types.find(type.sv());
-    if(it2 != _refl_types.end()) return it2->second.size;
+    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;
 }
@@ -312,12 +316,12 @@ struct C99ReflType final: ReflType{
         vm->bind__getitem__(OBJ_GET(Type, type), [](VM* vm, PyObject* obj, PyObject* key){
             C99ReflType& self = _CAST(C99ReflType&, obj);
             const Str& name = CAST(Str&, key);
-            auto it = self.fields.find(name.sv());
+            auto it = std::lower_bound(self.fields.begin(), self.fields.end(), name.sv());
             if(it == self.fields.end()){
-                vm->_error("KeyError", name.escape());
+                vm->KeyError(key);
                 return vm->None;
             }
-            return VAR(it->second);
+            return VAR(it->offset);
         });
     }
 };
@@ -386,8 +390,7 @@ struct NativeProxyFuncC final: NativeProxyFuncCBase {
 };
 
 inline PyObject* _any_c_wrapper(VM* vm, ArgsView args){
-    static const StrName m_proxy("__proxy__");
-    NativeProxyFuncCBase* pf = CAST(NativeProxyFuncCBase*, args[-2]->attr(m_proxy));
+    NativeProxyFuncCBase* pf = static_cast<NativeProxyFuncCBase*>(lambda_get_userdata(args)._p);
     return (*pf)(vm, args);
 }
 
@@ -397,7 +400,7 @@ inline void bind_any_c_fp(VM* vm, PyObject* obj, Str name, T fp){
     static_assert(std::is_pointer_v<T>);
     auto proxy = new NativeProxyFuncC(fp);
     PyObject* func = VAR(NativeFunc(_any_c_wrapper, proxy->N, false));
-    func->attr().set("__proxy__", VAR_T(VoidP, proxy));
+    _CAST(NativeFunc&, func).userdata._p = proxy;
     obj->attr().set(name, func);
 }
 
@@ -449,6 +452,21 @@ inline void add_module_c(VM* vm){
     C99Struct::register_class(vm, mod);
     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*), {});
 }
 
 }   // namespace pkpy

+ 1 - 1
src/dict.h

@@ -10,7 +10,7 @@ namespace pkpy{
 struct Dict{
     using Item = std::pair<PyObject*, PyObject*>;
     static constexpr int __Capacity = 8;
-    static constexpr float __LoadFactor = 0.67;
+    static constexpr float __LoadFactor = 0.67f;
     static_assert(sizeof(Item) * __Capacity <= 128);
 
     VM* vm;

+ 1 - 1
src/namedict.h

@@ -47,7 +47,7 @@ struct NameDictImpl {
         memset(_items, 0, cap * sizeof(Item));
     }
 
-    NameDictImpl(float load_factor=0.67):
+    NameDictImpl(float load_factor=0.67f):
         _load_factor(load_factor), _capacity(__Capacity), _size(0), 
         _hash_seed(kHashSeeds[0]), _mask(__Capacity-1) {
         _alloc(__Capacity);

+ 5 - 0
src/obj.h

@@ -409,6 +409,11 @@ T lambda_get_fp(ArgsView args){
     return reinterpret_cast<T>(f);
 }
 
+inline UserData& lambda_get_userdata(ArgsView args){
+    if(args[-1] != PY_NULL) return OBJ_GET(NativeFunc, args[-1]).userdata;
+    else return OBJ_GET(NativeFunc, args[-2]).userdata;
+}
+
 
 
 }   // namespace pkpy