mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
up
This commit is contained in:
parent
0a2453a20a
commit
d9a45ec60d
53
src/cffi.h
53
src/cffi.h
@ -269,28 +269,56 @@ struct Pointer{
|
||||
};
|
||||
|
||||
|
||||
struct Struct {
|
||||
PY_CLASS(Struct, c, struct_)
|
||||
struct Value {
|
||||
PY_CLASS(Value, c, value_)
|
||||
|
||||
char* data;
|
||||
Pointer head;
|
||||
|
||||
const TypeInfo* ctype() const { return head.ctype; }
|
||||
|
||||
Struct(const Pointer& head) {
|
||||
data = new char[head.ctype->size];
|
||||
memcpy(data, head.ptr, head.ctype->size);
|
||||
this->head = Pointer(head.ctype, head.level, data);
|
||||
Value(const TypeInfo* type) {
|
||||
data = new char[type->size];
|
||||
memset(data, 0, type->size);
|
||||
this->head = Pointer(type, data);
|
||||
}
|
||||
|
||||
static void _register(VM* vm, PyVar mod, PyVar type){
|
||||
vm->bind_static_method<-1>(type, "__new__", CPP_NOT_IMPLEMENTED());
|
||||
|
||||
vm->bind_method<0>(type, "__repr__", [](VM* vm, Args& args) {
|
||||
Struct& self = CAST(Struct&, args[0]);
|
||||
StrStream ss;
|
||||
ss << self.ctype()->name << "(" << ")";
|
||||
return VAR(ss.str());
|
||||
vm->bind_method<0>(type, "ptr", [](VM* vm, Args& args) {
|
||||
Value& self = CAST(Value&, args[0]);
|
||||
return VAR_T(Pointer, self.head);
|
||||
});
|
||||
|
||||
vm->bind_method<1>(type, "__getattr__", [](VM* vm, Args& args) {
|
||||
Value& self = CAST(Value&, args[0]);
|
||||
const Str& name = CAST(Str&, args[1]);
|
||||
return self.head._to(vm, name).get(vm);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct CType{
|
||||
PY_CLASS(CType, c, ctype)
|
||||
|
||||
const TypeInfo* type;
|
||||
|
||||
CType() : type(&_type_infos["void"]) {}
|
||||
CType(const TypeInfo* type) : type(type) {}
|
||||
|
||||
static void _register(VM* vm, PyVar mod, PyVar type){
|
||||
vm->bind_static_method<1>(type, "__new__", [](VM* vm, Args& args) {
|
||||
const Str& name = CAST(Str&, args[0]);
|
||||
auto it = _type_infos.find(name);
|
||||
if (it == _type_infos.end()) vm->TypeError("unknown type: " + name.escape(true));
|
||||
return VAR_T(CType, &it->second);
|
||||
});
|
||||
|
||||
vm->bind_method<0>(type, "__call__", [](VM* vm, Args& args) {
|
||||
CType& self = CAST(CType&, args[0]);
|
||||
return VAR_T(Value, self.type);
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -298,7 +326,8 @@ struct Struct {
|
||||
void add_module_c(VM* vm){
|
||||
PyVar mod = vm->new_module("c");
|
||||
PyVar ptr_t = Pointer::register_class(vm, mod);
|
||||
Struct::register_class(vm, mod);
|
||||
Value::register_class(vm, mod);
|
||||
CType::register_class(vm, mod);
|
||||
|
||||
vm->setattr(mod, "nullptr", VAR_T(Pointer));
|
||||
|
||||
|
@ -204,6 +204,7 @@ const StrName __len__ = StrName::get("__len__");
|
||||
const StrName __get__ = StrName::get("__get__");
|
||||
const StrName __getattr__ = StrName::get("__getattr__");
|
||||
const StrName __setattr__ = StrName::get("__setattr__");
|
||||
const StrName __call__ = StrName::get("__call__");
|
||||
|
||||
const StrName m_eval = StrName::get("eval");
|
||||
const StrName m_self = StrName::get("self");
|
||||
|
14
src/vm.h
14
src/vm.h
@ -736,6 +736,11 @@ PyVar VM::call(const PyVar& _callable, Args args, const Args& kwargs, bool opCal
|
||||
if(opCall) return _py_op_call;
|
||||
return _exec();
|
||||
}
|
||||
|
||||
PyVarOrNull call_f = getattr(_callable, __call__, false, true);
|
||||
if(call_f != nullptr){
|
||||
return call(call_f, std::move(args), kwargs, false);
|
||||
}
|
||||
TypeError(OBJ_NAME(_t(*callable)).escape(true) + " object is not callable");
|
||||
return None;
|
||||
}
|
||||
@ -795,9 +800,12 @@ PyVarOrNull VM::getattr(const PyVar& obj, StrName name, bool throw_err, bool cla
|
||||
}
|
||||
}else{
|
||||
// this operation is expensive!!!
|
||||
PyVar* interceptor = cls->attr().try_get(__getattr__);
|
||||
if(interceptor != nullptr){
|
||||
return call(*interceptor, two_args(obj, VAR(name.str())));
|
||||
const Str& s = name.str();
|
||||
if(s.empty() || s[0] != '_'){
|
||||
PyVar* interceptor = cls->attr().try_get(__getattr__);
|
||||
if(interceptor != nullptr){
|
||||
return call(*interceptor, two_args(obj, VAR(s)));
|
||||
}
|
||||
}
|
||||
}
|
||||
cls = cls->attr(__base__).get();
|
||||
|
Loading…
x
Reference in New Issue
Block a user