From 29521c98d0723b2fb572573192691828134cd53d Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Mon, 27 Feb 2023 01:45:18 +0800 Subject: [PATCH] up up --- src/ceval.h | 1 + src/cffi.h | 76 ++++++++++++++++++++++++----------------------------- src/vm.h | 10 ++++--- 3 files changed, 42 insertions(+), 45 deletions(-) diff --git a/src/ceval.h b/src/ceval.h index b89b740e..50e0d6cb 100644 --- a/src/ceval.h +++ b/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); diff --git a/src/cffi.h b/src/cffi.h index 94f5a0ba..ba2be953 100644 --- a/src/cffi.h +++ b/src/cffi.h @@ -2,23 +2,13 @@ #include "vm.h" -// struct Point2{ -// int x; -// int y; -// }; - -// std::map _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 members; + std::map 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(); + }); vm->bind_method<0>(type, "__repr__", [](VM* vm, pkpy::Args& args) { Struct& self = vm->py_cast(args[0]); StrStream ss; - ss << "name << "'>"; + ss << self.info->name << "(" << ")"; return vm->PyStr(ss.str()); }); - -#define MEMBER_LOOKUP() \ - Struct& self = vm->py_cast(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 } }; diff --git a/src/vm.h b/src/vm.h index db5894fb..700be342 100644 --- a/src/vm.h +++ b/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));