mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
some fix
This commit is contained in:
parent
75d83787f4
commit
978e04cdfd
28
src/cffi.h
28
src/cffi.h
@ -2,30 +2,36 @@
|
|||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "vm.h"
|
#include "vm.h"
|
||||||
|
#include <type_traits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace pkpy {
|
namespace pkpy {
|
||||||
|
|
||||||
template<typename Ret, typename... Params>
|
template<typename Ret, typename... Params>
|
||||||
struct ProxyFunction {
|
struct NativeProxyFunc {
|
||||||
using T = Ret(*)(Params...);
|
using T = Ret(*)(Params...);
|
||||||
static constexpr int N = sizeof...(Params);
|
static constexpr int N = sizeof...(Params);
|
||||||
T func;
|
T func;
|
||||||
ProxyFunction(T func) : func(func) {}
|
NativeProxyFunc(T func) : func(func) {}
|
||||||
|
|
||||||
PyVar operator()(VM* vm, Args& args) {
|
PyVar operator()(VM* vm, Args& args) {
|
||||||
if (args.size() != N) vm->TypeError("invalid number of arguments");
|
if (args.size() != N) vm->TypeError("invalid number of arguments");
|
||||||
return call(vm, args, std::make_index_sequence<N>());
|
return call<Ret>(vm, args, std::make_index_sequence<N>());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t... Is>
|
template<typename __Ret, size_t... Is>
|
||||||
PyVar call(VM* vm, Args& args, std::index_sequence<Is...>) {
|
std::enable_if_t<std::is_void_v<__Ret>, PyVar> call(VM* vm, Args& args, std::index_sequence<Is...>) {
|
||||||
Ret ret = func(py_cast<Params>(vm, args[Is])...);
|
func(py_cast<Params>(vm, args[Is])...);
|
||||||
|
return vm->None;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename __Ret, size_t... Is>
|
||||||
|
std::enable_if_t<!std::is_void_v<__Ret>, PyVar> call(VM* vm, Args& args, std::index_sequence<Is...>) {
|
||||||
|
__Ret ret = func(py_cast<Params>(vm, args[Is])...);
|
||||||
return VAR(std::move(ret));
|
return VAR(std::move(ret));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct TypeInfo;
|
struct TypeInfo;
|
||||||
|
|
||||||
struct MemberInfo{
|
struct MemberInfo{
|
||||||
@ -304,4 +310,12 @@ void add_module_c(VM* vm){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyVar py_var(VM* vm, void* p){
|
||||||
|
return VAR_T(Pointer, (char*)p, &_type_infos["void"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyVar py_var(VM* vm, char* p){
|
||||||
|
return VAR_T(Pointer, (char*)p, &_type_infos["char"]);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace pkpy
|
} // namespace pkpy
|
@ -75,9 +75,9 @@ struct Type {
|
|||||||
#define UNREACHABLE() throw std::runtime_error( __FILE__ + std::string(":") + std::to_string(__LINE__) + " UNREACHABLE()!");
|
#define UNREACHABLE() throw std::runtime_error( __FILE__ + std::string(":") + std::to_string(__LINE__) + " UNREACHABLE()!");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const float kLocalsLoadFactor = 0.67;
|
const float kLocalsLoadFactor = 0.67f;
|
||||||
const float kInstAttrLoadFactor = 0.67;
|
const float kInstAttrLoadFactor = 0.67f;
|
||||||
const float kTypeAttrLoadFactor = 0.5;
|
const float kTypeAttrLoadFactor = 0.5f;
|
||||||
|
|
||||||
// do extra check for debug
|
// do extra check for debug
|
||||||
// #define PK_EXTRA_CHECK
|
// #define PK_EXTRA_CHECK
|
||||||
|
@ -159,6 +159,7 @@ void init_builtins(VM* _vm) {
|
|||||||
_vm->bind_method<1>("object", "__ne__", CPP_LAMBDA(VAR(args[0] != args[1])));
|
_vm->bind_method<1>("object", "__ne__", CPP_LAMBDA(VAR(args[0] != args[1])));
|
||||||
|
|
||||||
_vm->bind_static_method<1>("type", "__new__", CPP_LAMBDA(vm->_t(args[0])));
|
_vm->bind_static_method<1>("type", "__new__", CPP_LAMBDA(vm->_t(args[0])));
|
||||||
|
_vm->bind_method<0>("type", "__repr__", CPP_LAMBDA(VAR("<class '" + OBJ_GET(Str, args[0]->attr(__name__)) + "'>")));
|
||||||
|
|
||||||
_vm->bind_static_method<-1>("range", "__new__", [](VM* vm, Args& args) {
|
_vm->bind_static_method<-1>("range", "__new__", [](VM* vm, Args& args) {
|
||||||
Range r;
|
Range r;
|
||||||
|
63
src/vm.h
63
src/vm.h
@ -73,7 +73,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
PyVar asStr(const PyVar& obj){
|
PyVar asStr(const PyVar& obj){
|
||||||
PyVarOrNull f = getattr(obj, __str__, false);
|
PyVarOrNull f = getattr(obj, __str__, false, true);
|
||||||
if(f != nullptr) return call(f);
|
if(f != nullptr) return call(f);
|
||||||
return asRepr(obj);
|
return asRepr(obj);
|
||||||
}
|
}
|
||||||
@ -87,7 +87,7 @@ public:
|
|||||||
|
|
||||||
PyVar asIter(const PyVar& obj){
|
PyVar asIter(const PyVar& obj){
|
||||||
if(is_type(obj, tp_native_iterator)) return obj;
|
if(is_type(obj, tp_native_iterator)) return obj;
|
||||||
PyVarOrNull iter_f = getattr(obj, __iter__, false);
|
PyVarOrNull iter_f = getattr(obj, __iter__, false, true);
|
||||||
if(iter_f != nullptr) return call(iter_f);
|
if(iter_f != nullptr) return call(iter_f);
|
||||||
TypeError(OBJ_NAME(_t(obj)).escape(true) + " object is not iterable");
|
TypeError(OBJ_NAME(_t(obj)).escape(true) + " object is not iterable");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -122,11 +122,11 @@ public:
|
|||||||
template<typename ArgT>
|
template<typename ArgT>
|
||||||
inline std::enable_if_t<std::is_same_v<std::decay_t<ArgT>, Args>, PyVar>
|
inline std::enable_if_t<std::is_same_v<std::decay_t<ArgT>, Args>, PyVar>
|
||||||
call(const PyVar& obj, const StrName name, ArgT&& args){
|
call(const PyVar& obj, const StrName name, ArgT&& args){
|
||||||
return call(getattr(obj, name), std::forward<ArgT>(args), no_arg(), false);
|
return call(getattr(obj, name, true, true), std::forward<ArgT>(args), no_arg(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline PyVar call(const PyVar& obj, StrName name){
|
inline PyVar call(const PyVar& obj, StrName name){
|
||||||
return call(getattr(obj, name), no_arg(), no_arg(), false);
|
return call(getattr(obj, name, true, true), no_arg(), no_arg(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -305,7 +305,7 @@ public:
|
|||||||
void init_builtin_types();
|
void init_builtin_types();
|
||||||
PyVar call(const PyVar& _callable, Args args, const Args& kwargs, bool opCall);
|
PyVar call(const PyVar& _callable, Args args, const Args& kwargs, bool opCall);
|
||||||
void unpack_args(Args& args);
|
void unpack_args(Args& args);
|
||||||
PyVarOrNull getattr(const PyVar& obj, StrName name, bool throw_err=true);
|
PyVarOrNull getattr(const PyVar& obj, StrName name, bool throw_err=true, bool class_only=false);
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void setattr(PyVar& obj, StrName name, T&& value);
|
void setattr(PyVar& obj, StrName name, T&& value);
|
||||||
template<int ARGC>
|
template<int ARGC>
|
||||||
@ -388,17 +388,6 @@ template<> i64 py_cast<i64>(VM* vm, const PyVar& obj){
|
|||||||
template<> i64 _py_cast<i64>(VM* vm, const PyVar& obj){
|
template<> i64 _py_cast<i64>(VM* vm, const PyVar& obj){
|
||||||
return obj.bits >> 2;
|
return obj.bits >> 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef PKPY_USE_32_BITS
|
|
||||||
template<> int py_cast<int>(VM* vm, const PyVar& obj){
|
|
||||||
vm->check_type(obj, vm->tp_int);
|
|
||||||
return obj.bits >> 2;
|
|
||||||
}
|
|
||||||
template<> int _py_cast<int>(VM* vm, const PyVar& obj){
|
|
||||||
return obj.bits >> 2;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<> f64 py_cast<f64>(VM* vm, const PyVar& obj){
|
template<> f64 py_cast<f64>(VM* vm, const PyVar& obj){
|
||||||
vm->check_type(obj, vm->tp_float);
|
vm->check_type(obj, vm->tp_float);
|
||||||
i64 bits = obj.bits;
|
i64 bits = obj.bits;
|
||||||
@ -411,6 +400,27 @@ template<> f64 _py_cast<f64>(VM* vm, const PyVar& obj){
|
|||||||
return __8B(bits)._float;
|
return __8B(bits)._float;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef PKPY_USE_32_BITS
|
||||||
|
template<> int py_cast<int>(VM* vm, const PyVar& obj){
|
||||||
|
vm->check_type(obj, vm->tp_int);
|
||||||
|
return obj.bits >> 2;
|
||||||
|
}
|
||||||
|
template<> int _py_cast<int>(VM* vm, const PyVar& obj){
|
||||||
|
return obj.bits >> 2;
|
||||||
|
}
|
||||||
|
template<> float py_cast<float>(VM* vm, const PyVar& obj){
|
||||||
|
vm->check_type(obj, vm->tp_float);
|
||||||
|
i64 bits = obj.bits;
|
||||||
|
bits = (bits >> 2) << 2;
|
||||||
|
return __8B(bits)._float;
|
||||||
|
}
|
||||||
|
template<> float _py_cast<float>(VM* vm, const PyVar& obj){
|
||||||
|
i64 bits = obj.bits;
|
||||||
|
bits = (bits >> 2) << 2;
|
||||||
|
return __8B(bits)._float;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
std::enable_if_t<std::is_floating_point_v<T>, PyVar> py_var(VM* vm, T _val){
|
std::enable_if_t<std::is_floating_point_v<T>, PyVar> py_var(VM* vm, T _val){
|
||||||
f64 val = static_cast<f64>(_val);
|
f64 val = static_cast<f64>(_val);
|
||||||
@ -466,7 +476,7 @@ const PyVar& VM::asBool(const PyVar& obj){
|
|||||||
if(obj == None) return False;
|
if(obj == None) return False;
|
||||||
if(is_type(obj, tp_int)) return VAR(CAST(i64, obj) != 0);
|
if(is_type(obj, tp_int)) return VAR(CAST(i64, obj) != 0);
|
||||||
if(is_type(obj, tp_float)) return VAR(CAST(f64, obj) != 0.0);
|
if(is_type(obj, tp_float)) return VAR(CAST(f64, obj) != 0.0);
|
||||||
PyVarOrNull len_fn = getattr(obj, __len__, false);
|
PyVarOrNull len_fn = getattr(obj, __len__, false, true);
|
||||||
if(len_fn != nullptr){
|
if(len_fn != nullptr){
|
||||||
PyVar ret = call(len_fn);
|
PyVar ret = call(len_fn);
|
||||||
return VAR(CAST(i64, ret) > 0);
|
return VAR(CAST(i64, ret) > 0);
|
||||||
@ -497,7 +507,6 @@ i64 VM::hash(const PyVar& obj){
|
|||||||
}
|
}
|
||||||
|
|
||||||
PyVar VM::asRepr(const PyVar& obj){
|
PyVar VM::asRepr(const PyVar& obj){
|
||||||
if(is_type(obj, tp_type)) return VAR("<class '" + OBJ_GET(Str, obj->attr(__name__)) + "'>");
|
|
||||||
return call(obj, __repr__);
|
return call(obj, __repr__);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -654,7 +663,7 @@ PyVar VM::call(const PyVar& _callable, Args args, const Args& kwargs, bool opCal
|
|||||||
obj = call(*new_f, std::move(args), kwargs, false);
|
obj = call(*new_f, std::move(args), kwargs, false);
|
||||||
}else{
|
}else{
|
||||||
obj = new_object(_callable, DummyInstance());
|
obj = new_object(_callable, DummyInstance());
|
||||||
PyVarOrNull init_f = getattr(obj, __init__, false);
|
PyVarOrNull init_f = getattr(obj, __init__, false, true);
|
||||||
if (init_f != nullptr) call(init_f, std::move(args), kwargs, false);
|
if (init_f != nullptr) call(init_f, std::move(args), kwargs, false);
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
@ -739,7 +748,7 @@ void VM::unpack_args(Args& args){
|
|||||||
args = Args::from_list(std::move(unpacked));
|
args = Args::from_list(std::move(unpacked));
|
||||||
}
|
}
|
||||||
|
|
||||||
PyVarOrNull VM::getattr(const PyVar& obj, StrName name, bool throw_err) {
|
PyVarOrNull VM::getattr(const PyVar& obj, StrName name, bool throw_err, bool class_only) {
|
||||||
PyVar* val;
|
PyVar* val;
|
||||||
PyObject* cls;
|
PyObject* cls;
|
||||||
|
|
||||||
@ -754,10 +763,12 @@ PyVarOrNull VM::getattr(const PyVar& obj, StrName name, bool throw_err) {
|
|||||||
cls = _t(*root).get();
|
cls = _t(*root).get();
|
||||||
for(int i=0; i<depth; i++) cls = cls->attr(__base__).get();
|
for(int i=0; i<depth; i++) cls = cls->attr(__base__).get();
|
||||||
|
|
||||||
val = (*root)->attr().try_get(name);
|
if(!class_only){
|
||||||
if(val != nullptr) return *val;
|
val = (*root)->attr().try_get(name);
|
||||||
|
if(val != nullptr) return *val;
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
if(!obj.is_tagged() && obj->is_attr_valid()){
|
if(!class_only && !obj.is_tagged() && obj->is_attr_valid()){
|
||||||
val = obj->attr().try_get(name);
|
val = obj->attr().try_get(name);
|
||||||
if(val != nullptr) return *val;
|
if(val != nullptr) return *val;
|
||||||
}
|
}
|
||||||
@ -767,10 +778,8 @@ PyVarOrNull VM::getattr(const PyVar& obj, StrName name, bool throw_err) {
|
|||||||
while(cls != None.get()) {
|
while(cls != None.get()) {
|
||||||
val = cls->attr().try_get(name);
|
val = cls->attr().try_get(name);
|
||||||
if(val != nullptr){
|
if(val != nullptr){
|
||||||
PyVarOrNull descriptor = getattr(*val, __get__, false);
|
PyVarOrNull descriptor = getattr(*val, __get__, false, true);
|
||||||
if(descriptor != nullptr){
|
if(descriptor != nullptr) return call(descriptor, one_arg(obj));
|
||||||
return call(descriptor, one_arg(obj));
|
|
||||||
}
|
|
||||||
if(is_type(*val, tp_function) || is_type(*val, tp_native_function)){
|
if(is_type(*val, tp_function) || is_type(*val, tp_native_function)){
|
||||||
return VAR(BoundMethod(obj, *val));
|
return VAR(BoundMethod(obj, *val));
|
||||||
}else{
|
}else{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user