up
This commit is contained in:
blueloveTH 2023-02-27 01:45:18 +08:00
parent 3721f48f8b
commit 29521c98d0
3 changed files with 42 additions and 45 deletions

View File

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

View File

@ -2,23 +2,13 @@
#include "vm.h" #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{ struct CType{
PY_CLASS(c, type_) PY_CLASS(c, type_)
const char* name; // must be a literal const char* name; // must be a literal
const int size; const int size;
const int index; 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){ 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__", CPP_NOT_IMPLEMENTED());
@ -200,7 +190,20 @@ struct StructMemberInfo {
struct StructMetaInfo { struct StructMetaInfo {
Str name; 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 { struct Struct {
@ -210,47 +213,38 @@ struct Struct {
int8_t* _data; // store any `struct` int8_t* _data; // store any `struct`
Struct(const StructMetaInfo* info, int8_t* data) : info(info), _data(data) {} Struct(const StructMetaInfo* info, int8_t* data) : info(info), _data(data) {}
Struct(){
info = &_Point2_info;
_data = new int8_t[sizeof(Point2)];
}
~Struct(){ delete[] _data; } ~Struct(){ delete[] _data; }
int8_t* address(std::string_view name){ Pointer address(VM* vm, StrName name){
auto it = info->members.find(name); auto it = info->members.find(name);
if(it == info->members.end()) return nullptr; if(it == info->members.end()) vm->AttributeError("struct " + info->name + " has no member " + name.str());
return _data + it->second.offset; 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){ 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) { vm->bind_method<0>(type, "__repr__", [](VM* vm, pkpy::Args& args) {
Struct& self = vm->py_cast<Struct>(args[0]); Struct& self = vm->py_cast<Struct>(args[0]);
StrStream ss; StrStream ss;
ss << "<c._struct '" << self.info->name << "'>"; ss << self.info->name << "(" << ")";
return vm->PyStr(ss.str()); 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
} }
}; };

View File

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