mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-24 05:20:17 +00:00
up
up
This commit is contained in:
parent
3721f48f8b
commit
29521c98d0
@ -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);
|
||||
|
||||
76
src/cffi.h
76
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
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
10
src/vm.h
10
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));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user