blueloveTH 3 лет назад
Родитель
Сommit
29521c98d0
3 измененных файлов с 42 добавлено и 45 удалено
  1. 1 0
      src/ceval.h
  2. 35 41
      src/cffi.h
  3. 6 4
      src/vm.h

+ 1 - 0
src/ceval.h

@@ -299,6 +299,7 @@ PyVar VM::run_frame(Frame* frame){
                     _exec(code, new_mod);
                     frame->push(new_mod);
                     _lazy_modules.erase(it2);
+                    new_mod->attr()._try_perfect_rehash();
                 }
             }else{
                 frame->push(*ext_mod);

+ 35 - 41
src/cffi.h

@@ -2,23 +2,13 @@
 
 #include "vm.h"
 
-// struct Point2{
-//     int x;
-//     int y;
-// };
-
-// std::map<std::string_view, int> _Point2_members = {
-//     {"x", offsetof(Point2, x)},
-//     {"y", offsetof(Point2, y)},
-// };
-
 struct CType{
     PY_CLASS(c, type_)
 
     const char* name;       // must be a literal
     const int size;
     const int index;
-    constexpr CType(const char name[], int size, int index=-1) : name(name), size(size), index(index) {}
+    constexpr CType(const char name[], int size, int index) : name(name), size(size), index(index) {}
 
     static void _register(VM* vm, PyVar mod, PyVar type){
         vm->bind_static_method<-1>(type, "__new__", CPP_NOT_IMPLEMENTED());
@@ -200,7 +190,20 @@ struct StructMemberInfo {
 
 struct StructMetaInfo {
     Str name;
-    std::map<std::string_view, StructMemberInfo> members;
+    std::map<StrName, StructMemberInfo> members;
+};
+
+struct Point2{
+    int x;
+    int y;
+};
+
+static const StructMetaInfo _Point2_info = {
+    "Point2",
+    {
+        {StrName("x"), {offsetof(Point2, x), C_TYPE_T("int_")}},
+        {StrName("y"), {offsetof(Point2, y), C_TYPE_T("int_")}},
+    }
 };
 
 struct Struct {
@@ -210,47 +213,38 @@ struct Struct {
     int8_t* _data;      // store any `struct`
 
     Struct(const StructMetaInfo* info, int8_t* data) : info(info), _data(data) {}
+    Struct(){
+        info = &_Point2_info;
+        _data = new int8_t[sizeof(Point2)];
+    }
     ~Struct(){ delete[] _data; }
 
-    int8_t* address(std::string_view name){
+    Pointer address(VM* vm, StrName name){
         auto it = info->members.find(name);
-        if(it == info->members.end()) return nullptr;
-        return _data + it->second.offset;
+        if(it == info->members.end()) vm->AttributeError("struct " + info->name + " has no member " + name.str());
+        const StructMemberInfo& info = it->second;
+        return {_data+info.offset, info.type};
+    }
+
+    PyVarOrNull __getattr__(VM* vm, StrName name){
+        return address(vm, name).get(vm);
+    }
+
+    void __setattr__(VM* vm, StrName name, const PyVar& val){
+        address(vm, name).set(vm, val);
     }
 
     static void _register(VM* vm, PyVar mod, PyVar type){
-        vm->bind_static_method<-1>(type, "__new__", CPP_NOT_IMPLEMENTED());
+        vm->bind_static_method<-1>(type, "__new__", [](VM* vm, pkpy::Args& args) {
+            return vm->new_object<Struct>();
+        });
 
         vm->bind_method<0>(type, "__repr__", [](VM* vm, pkpy::Args& args) {
             Struct& self = vm->py_cast<Struct>(args[0]);
             StrStream ss;
-            ss << "<c._struct '" << self.info->name << "'>";
+            ss << self.info->name << "(" << ")";
             return vm->PyStr(ss.str());
         });
-
-#define MEMBER_LOOKUP() \
-    Struct& self = vm->py_cast<Struct>(args[0]);            \
-    std::string_view name = vm->PyStr_AS_C(args[1]);        \
-    auto it = self.info->members.find(name);                \
-    if(it == self.info->members.end()){                     \
-        vm->AttributeError(args[0], name.data());           \
-        return vm->None;                                    \
-    }                                                       \
-    const StructMemberInfo& info = it->second;              \
-    Pointer p = Pointer(self._data+info.offset, info.type); \
-
-        vm->bind_method<1>(type, "__getattr__", [](VM* vm, pkpy::Args& args) {
-            MEMBER_LOOKUP()
-            return p.get(vm);
-        });
-
-        vm->bind_method<2>(type, "__setattr__", [](VM* vm, pkpy::Args& args) {
-            MEMBER_LOOKUP()
-            p.set(vm, args[2]);
-            return vm->None;
-        });
-
-#undef MEMBER_LOOKUP
     }
 };
 

+ 6 - 4
src/vm.h

@@ -66,7 +66,9 @@ public:
     }
 
     inline Frame* top_frame() const {
+#ifdef PK_EXTRA_CHECK
         if(callstack.empty()) UNREACHABLE();
+#endif
         return callstack.top().get();
     }
 
@@ -671,10 +673,8 @@ public:
         }
 
         post_init();
-        for(auto [k, v]: _types.items()){
-            v->attr()._try_perfect_rehash();
-        }
-        builtins->attr()._try_perfect_rehash();
+        for(auto [k, v]: _types.items()) v->attr()._try_perfect_rehash();
+        for(auto [k, v]: _modules.items()) v->attr()._try_perfect_rehash();
     }
 
     void post_init();
@@ -735,6 +735,8 @@ public:
         _error("AttributeError", "type " +  OBJ_NAME(_t(obj)).escape(true) + " has no attribute " + name.str().escape(true));
     }
 
+    void AttributeError(Str msg){ _error("AttributeError", msg); }
+
     inline void check_type(const PyVar& obj, Type type){
         if(is_type(obj, type)) return;
         TypeError("expected " + OBJ_NAME(_t(type)).escape(true) + ", but got " + OBJ_NAME(_t(obj)).escape(true));