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 {
|
struct Value {
|
||||||
PY_CLASS(Struct, c, struct_)
|
PY_CLASS(Value, c, value_)
|
||||||
|
|
||||||
char* data;
|
char* data;
|
||||||
Pointer head;
|
Pointer head;
|
||||||
|
|
||||||
const TypeInfo* ctype() const { return head.ctype; }
|
const TypeInfo* ctype() const { return head.ctype; }
|
||||||
|
|
||||||
Struct(const Pointer& head) {
|
Value(const TypeInfo* type) {
|
||||||
data = new char[head.ctype->size];
|
data = new char[type->size];
|
||||||
memcpy(data, head.ptr, head.ctype->size);
|
memset(data, 0, type->size);
|
||||||
this->head = Pointer(head.ctype, head.level, data);
|
this->head = Pointer(type, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
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());
|
||||||
|
|
||||||
vm->bind_method<0>(type, "__repr__", [](VM* vm, Args& args) {
|
vm->bind_method<0>(type, "ptr", [](VM* vm, Args& args) {
|
||||||
Struct& self = CAST(Struct&, args[0]);
|
Value& self = CAST(Value&, args[0]);
|
||||||
StrStream ss;
|
return VAR_T(Pointer, self.head);
|
||||||
ss << self.ctype()->name << "(" << ")";
|
});
|
||||||
return VAR(ss.str());
|
|
||||||
|
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){
|
void add_module_c(VM* vm){
|
||||||
PyVar mod = vm->new_module("c");
|
PyVar mod = vm->new_module("c");
|
||||||
PyVar ptr_t = Pointer::register_class(vm, mod);
|
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));
|
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 __get__ = StrName::get("__get__");
|
||||||
const StrName __getattr__ = StrName::get("__getattr__");
|
const StrName __getattr__ = StrName::get("__getattr__");
|
||||||
const StrName __setattr__ = StrName::get("__setattr__");
|
const StrName __setattr__ = StrName::get("__setattr__");
|
||||||
|
const StrName __call__ = StrName::get("__call__");
|
||||||
|
|
||||||
const StrName m_eval = StrName::get("eval");
|
const StrName m_eval = StrName::get("eval");
|
||||||
const StrName m_self = StrName::get("self");
|
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;
|
if(opCall) return _py_op_call;
|
||||||
return _exec();
|
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");
|
TypeError(OBJ_NAME(_t(*callable)).escape(true) + " object is not callable");
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@ -795,9 +800,12 @@ PyVarOrNull VM::getattr(const PyVar& obj, StrName name, bool throw_err, bool cla
|
|||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
// this operation is expensive!!!
|
// this operation is expensive!!!
|
||||||
PyVar* interceptor = cls->attr().try_get(__getattr__);
|
const Str& s = name.str();
|
||||||
if(interceptor != nullptr){
|
if(s.empty() || s[0] != '_'){
|
||||||
return call(*interceptor, two_args(obj, VAR(name.str())));
|
PyVar* interceptor = cls->attr().try_get(__getattr__);
|
||||||
|
if(interceptor != nullptr){
|
||||||
|
return call(*interceptor, two_args(obj, VAR(s)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cls = cls->attr(__base__).get();
|
cls = cls->attr(__base__).get();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user