mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 19:40:18 +00:00
a lot of fix
This commit is contained in:
parent
f5a4c37968
commit
529c23043c
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
@ -1,11 +1,13 @@
|
|||||||
name: build
|
name: build
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
branches: [ main ]
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- 'docs/**'
|
- 'docs/**'
|
||||||
- 'web/**'
|
- 'web/**'
|
||||||
- '**.md'
|
- '**.md'
|
||||||
pull_request:
|
pull_request:
|
||||||
|
branches: [ main ]
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- 'docs/**'
|
- 'docs/**'
|
||||||
- 'web/**'
|
- 'web/**'
|
||||||
|
@ -28,7 +28,7 @@ struct any{
|
|||||||
|
|
||||||
any() : data(nullptr), _vt(nullptr) {}
|
any() : data(nullptr), _vt(nullptr) {}
|
||||||
|
|
||||||
operator bool() const { return _vt != nullptr; }
|
explicit operator bool() const { return _vt != nullptr; }
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
any(T&& value){
|
any(T&& value){
|
||||||
@ -85,7 +85,7 @@ struct function<Ret(Params...)>{
|
|||||||
|
|
||||||
function(): _impl(), _wrapper(nullptr) {}
|
function(): _impl(), _wrapper(nullptr) {}
|
||||||
|
|
||||||
operator bool() const { return _wrapper != nullptr; }
|
explicit operator bool() const { return _wrapper != nullptr; }
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
function(F&& f) : _impl(std::forward<F>(f)){
|
function(F&& f) : _impl(std::forward<F>(f)){
|
||||||
@ -110,7 +110,7 @@ struct lightfunction<Ret(Params...)>{
|
|||||||
|
|
||||||
lightfunction() : _impl(nullptr), _wrapper(nullptr) {}
|
lightfunction() : _impl(nullptr), _wrapper(nullptr) {}
|
||||||
|
|
||||||
operator bool() const { return _wrapper != nullptr; }
|
explicit operator bool() const { return _wrapper != nullptr; }
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
lightfunction(const F& f){
|
lightfunction(const F& f){
|
||||||
|
@ -102,7 +102,7 @@ struct Type {
|
|||||||
explicit constexpr Type(int index): index(index) {}
|
explicit constexpr Type(int index): index(index) {}
|
||||||
bool operator==(Type other) const { return this->index == other.index; }
|
bool operator==(Type other) const { return this->index == other.index; }
|
||||||
bool operator!=(Type other) const { return this->index != other.index; }
|
bool operator!=(Type other) const { return this->index != other.index; }
|
||||||
operator int() const { return this->index; }
|
explicit operator bool() const { return index != -1; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PK_LAMBDA(x) ([](VM* vm, ArgsView args) { return x; })
|
#define PK_LAMBDA(x) ([](VM* vm, ArgsView args) { return x; })
|
||||||
@ -177,19 +177,27 @@ struct PyVar final{
|
|||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
char _bytes[12];
|
char _bytes[12];
|
||||||
|
|
||||||
PyVar(): type(), is_sso(false), flags(0) { }
|
// uninitialized
|
||||||
PyVar(std::nullptr_t): type(), is_sso(false), flags(0) { }
|
PyVar(): type() { }
|
||||||
PyVar(Type type, bool is_sso): type(type), is_sso(is_sso), flags(0) { }
|
// zero initialized
|
||||||
PyVar(Type type, PyObject* p): type(type), is_sso(false), flags(0) { as<PyObject*>() = p; }
|
PyVar(std::nullptr_t): type(), is_sso(false), flags(0), _bytes{0} { }
|
||||||
|
// PyObject* initialized (is_sso = false)
|
||||||
|
PyVar(Type type, PyObject* p): type(type), is_sso(false), flags(0) {
|
||||||
|
as<PyObject*>() = p;
|
||||||
|
}
|
||||||
|
// SSO initialized (is_sso = true)
|
||||||
|
template<typename T>
|
||||||
|
PyVar(Type type, T value): type(type), is_sso(true), flags(0) {
|
||||||
|
as<T>() = value;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T& as() const {
|
T& as() const {
|
||||||
static_assert(!std::is_reference_v<T>);
|
static_assert(!std::is_reference_v<T>);
|
||||||
PK_DEBUG_ASSERT(is_sso)
|
|
||||||
return *(T*)_bytes;
|
return *(T*)_bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator bool() const { return type; }
|
explicit operator bool() const { return (bool)type; }
|
||||||
|
|
||||||
bool operator==(const PyVar& other) const {
|
bool operator==(const PyVar& other) const {
|
||||||
return memcmp(this, &other, sizeof(PyVar)) == 0;
|
return memcmp(this, &other, sizeof(PyVar)) == 0;
|
||||||
@ -199,14 +207,33 @@ struct PyVar final{
|
|||||||
return memcmp(this, &other, sizeof(PyVar)) != 0;
|
return memcmp(this, &other, sizeof(PyVar)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(std::nullptr_t) const { return !type; }
|
bool operator==(std::nullptr_t) const { return !(bool)type; }
|
||||||
bool operator!=(std::nullptr_t) const { return type; }
|
bool operator!=(std::nullptr_t) const { return (bool)type; }
|
||||||
|
|
||||||
|
PyObject* get() const {
|
||||||
|
PK_DEBUG_ASSERT(!is_sso)
|
||||||
|
return as<PyObject*>();
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject* operator->() const {
|
||||||
|
PK_DEBUG_ASSERT(!is_sso)
|
||||||
|
return as<PyObject*>();
|
||||||
|
}
|
||||||
|
|
||||||
PyObject* get() const { return as<PyObject*>(); }
|
|
||||||
i64 hash() const { return as<i64>(); }
|
i64 hash() const { return as<i64>(); }
|
||||||
PyObject* operator->() const { return as<PyObject*>(); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(PyVar) == 16 && is_pod_v<PyVar>);
|
static_assert(sizeof(PyVar) == 16 && is_pod_v<PyVar>);
|
||||||
|
|
||||||
} // namespace pkpy
|
} // namespace pkpy
|
||||||
|
|
||||||
|
|
||||||
|
// specialize std::less for PyVar
|
||||||
|
namespace std {
|
||||||
|
template<>
|
||||||
|
struct less<pkpy::PyVar> {
|
||||||
|
bool operator()(const pkpy::PyVar& lhs, const pkpy::PyVar& rhs) const {
|
||||||
|
return memcmp(&lhs, &rhs, sizeof(pkpy::PyVar)) < 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -128,7 +128,7 @@ struct StrName {
|
|||||||
|
|
||||||
struct SStream{
|
struct SStream{
|
||||||
PK_ALWAYS_PASS_BY_POINTER(SStream)
|
PK_ALWAYS_PASS_BY_POINTER(SStream)
|
||||||
// pod_vector<T> is allocated by pool64 so the buffer can be moved into Str without a copy
|
// pod_vector<T> is allocated by pool128 so the buffer can be moved into Str without a copy
|
||||||
pod_vector<char> buffer;
|
pod_vector<char> buffer;
|
||||||
int _precision = -1;
|
int _precision = -1;
|
||||||
|
|
||||||
|
@ -366,10 +366,10 @@ public:
|
|||||||
void check_compatible_type(PyVar obj, Type type){ if(!isinstance(obj, type)) TypeError(type, _tp(obj)); }
|
void check_compatible_type(PyVar obj, Type type){ if(!isinstance(obj, type)) TypeError(type, _tp(obj)); }
|
||||||
|
|
||||||
Type _tp(PyVar obj){ return obj.type; }
|
Type _tp(PyVar obj){ return obj.type; }
|
||||||
const PyTypeInfo* _tp_info(PyVar obj) { return &_all_types[_tp(obj)]; }
|
const PyTypeInfo* _tp_info(PyVar obj) { return &_all_types[_tp(obj).index]; }
|
||||||
const PyTypeInfo* _tp_info(Type type) { return &_all_types[type]; }
|
const PyTypeInfo* _tp_info(Type type) { return &_all_types[type.index]; }
|
||||||
PyVar _t(PyVar obj){ return _all_types[_tp(obj)].obj; }
|
PyVar _t(PyVar obj){ return _all_types[_tp(obj).index].obj; }
|
||||||
PyVar _t(Type type){ return _all_types[type].obj; }
|
PyVar _t(Type type){ return _all_types[type.index].obj; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if PK_REGION("User Type Registration")
|
#if PK_REGION("User Type Registration")
|
||||||
@ -480,14 +480,10 @@ PyVar py_var(VM* vm, __T&& value){
|
|||||||
return value ? vm->True : vm->False;
|
return value ? vm->True : vm->False;
|
||||||
}else if constexpr(is_integral_v<T>){
|
}else if constexpr(is_integral_v<T>){
|
||||||
// int
|
// int
|
||||||
PyVar retval(VM::tp_int, true);
|
return PyVar(VM::tp_int, static_cast<i64>(value));
|
||||||
retval.as<i64>() = static_cast<i64>(value);
|
|
||||||
return retval;
|
|
||||||
}else if constexpr(is_floating_point_v<T>){
|
}else if constexpr(is_floating_point_v<T>){
|
||||||
// float
|
// float
|
||||||
PyVar retval(VM::tp_float, true);
|
return PyVar(VM::tp_float, static_cast<f64>(value));
|
||||||
retval.as<f64>() = static_cast<f64>(value);
|
|
||||||
return retval;
|
|
||||||
}else if constexpr(std::is_pointer_v<T>){
|
}else if constexpr(std::is_pointer_v<T>){
|
||||||
return from_void_p(vm, (void*)value);
|
return from_void_p(vm, (void*)value);
|
||||||
}else{
|
}else{
|
||||||
|
@ -898,9 +898,9 @@ __NEXT_STEP:;
|
|||||||
StrName _name(byte.arg);
|
StrName _name(byte.arg);
|
||||||
frame->_module->attr().set(_name, __curr_class);
|
frame->_module->attr().set(_name, __curr_class);
|
||||||
// call on_end_subclass
|
// call on_end_subclass
|
||||||
PyTypeInfo* ti = &_all_types[PK_OBJ_GET(Type, __curr_class)];
|
PyTypeInfo* ti = &_all_types[PK_OBJ_GET(Type, __curr_class).index];
|
||||||
if(ti->base != tp_object){
|
if(ti->base != tp_object){
|
||||||
PyTypeInfo* base_ti = &_all_types[ti->base];
|
PyTypeInfo* base_ti = &_all_types[ti->base.index];
|
||||||
if(base_ti->on_end_subclass) base_ti->on_end_subclass(this, ti);
|
if(base_ti->on_end_subclass) base_ti->on_end_subclass(this, ti);
|
||||||
}
|
}
|
||||||
__curr_class = nullptr;
|
__curr_class = nullptr;
|
||||||
@ -924,7 +924,7 @@ __NEXT_STEP:;
|
|||||||
PK_ASSERT(__curr_class != nullptr);
|
PK_ASSERT(__curr_class != nullptr);
|
||||||
StrName _name(byte.arg);
|
StrName _name(byte.arg);
|
||||||
Type type = PK_OBJ_GET(Type, __curr_class);
|
Type type = PK_OBJ_GET(Type, __curr_class);
|
||||||
_all_types[type].annotated_fields.push_back(_name);
|
_all_types[type.index].annotated_fields.push_back(_name);
|
||||||
} DISPATCH()
|
} DISPATCH()
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
case OP_WITH_ENTER:
|
case OP_WITH_ENTER:
|
||||||
|
@ -13,7 +13,7 @@ static void patch__init__(VM* vm, Type cls){
|
|||||||
});
|
});
|
||||||
|
|
||||||
Type cls = vm->_tp(self);
|
Type cls = vm->_tp(self);
|
||||||
const PyTypeInfo* cls_info = &vm->_all_types[cls];
|
const PyTypeInfo* cls_info = &vm->_all_types[cls.index];
|
||||||
NameDict& cls_d = cls_info->obj->attr();
|
NameDict& cls_d = cls_info->obj->attr();
|
||||||
const auto& fields = cls_info->annotated_fields;
|
const auto& fields = cls_info->annotated_fields;
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ static void patch__init__(VM* vm, Type cls){
|
|||||||
|
|
||||||
static void patch__repr__(VM* vm, Type cls){
|
static void patch__repr__(VM* vm, Type cls){
|
||||||
vm->bind__repr__(cls, [](VM* vm, PyVar _0) -> Str{
|
vm->bind__repr__(cls, [](VM* vm, PyVar _0) -> Str{
|
||||||
const PyTypeInfo* cls_info = &vm->_all_types[vm->_tp(_0)];
|
const PyTypeInfo* cls_info = &vm->_all_types[vm->_tp(_0).index];
|
||||||
const auto& fields = cls_info->annotated_fields;
|
const auto& fields = cls_info->annotated_fields;
|
||||||
const NameDict& obj_d = _0->attr();
|
const NameDict& obj_d = _0->attr();
|
||||||
SStream ss;
|
SStream ss;
|
||||||
@ -65,7 +65,7 @@ static void patch__repr__(VM* vm, Type cls){
|
|||||||
static void patch__eq__(VM* vm, Type cls){
|
static void patch__eq__(VM* vm, Type cls){
|
||||||
vm->bind__eq__(cls, [](VM* vm, PyVar _0, PyVar _1){
|
vm->bind__eq__(cls, [](VM* vm, PyVar _0, PyVar _1){
|
||||||
if(vm->_tp(_0) != vm->_tp(_1)) return vm->NotImplemented;
|
if(vm->_tp(_0) != vm->_tp(_1)) return vm->NotImplemented;
|
||||||
const PyTypeInfo* cls_info = &vm->_all_types[vm->_tp(_0)];
|
const PyTypeInfo* cls_info = &vm->_all_types[vm->_tp(_0).index];
|
||||||
const auto& fields = cls_info->annotated_fields;
|
const auto& fields = cls_info->annotated_fields;
|
||||||
for(StrName field: fields){
|
for(StrName field: fields){
|
||||||
PyVar lhs = _0->attr(field);
|
PyVar lhs = _0->attr(field);
|
||||||
@ -88,7 +88,7 @@ void add_module_dataclasses(VM* vm){
|
|||||||
if(!cls_d.contains(__repr__)) patch__repr__(vm, cls);
|
if(!cls_d.contains(__repr__)) patch__repr__(vm, cls);
|
||||||
if(!cls_d.contains(__eq__)) patch__eq__(vm, cls);
|
if(!cls_d.contains(__eq__)) patch__eq__(vm, cls);
|
||||||
|
|
||||||
const auto& fields = vm->_all_types[cls].annotated_fields;
|
const auto& fields = vm->_all_types[cls.index].annotated_fields;
|
||||||
bool has_default = false;
|
bool has_default = false;
|
||||||
for(StrName field: fields){
|
for(StrName field: fields){
|
||||||
if(cls_d.contains(field)){
|
if(cls_d.contains(field)){
|
||||||
|
@ -104,7 +104,7 @@ void __init_builtins(VM* _vm) {
|
|||||||
StrName _1 = _type_name(vm, type);
|
StrName _1 = _type_name(vm, type);
|
||||||
vm->TypeError("super(): " + _0.escape() + " is not an instance of " + _1.escape());
|
vm->TypeError("super(): " + _0.escape() + " is not an instance of " + _1.escape());
|
||||||
}
|
}
|
||||||
return vm->heap.gcnew<Super>(vm->tp_super, self_arg, vm->_all_types[type].base);
|
return vm->heap.gcnew<Super>(vm->tp_super, self_arg, vm->_all_types[type.index].base);
|
||||||
});
|
});
|
||||||
|
|
||||||
_vm->bind_func(_vm->builtins, "staticmethod", 1, [](VM* vm, ArgsView args) {
|
_vm->bind_func(_vm->builtins, "staticmethod", 1, [](VM* vm, ArgsView args) {
|
||||||
@ -1502,7 +1502,7 @@ void VM::__post_init_builtin_types(){
|
|||||||
|
|
||||||
bind_func(tp_module, __new__, -1, PK_ACTION(vm->NotImplementedError()));
|
bind_func(tp_module, __new__, -1, PK_ACTION(vm->NotImplementedError()));
|
||||||
|
|
||||||
_all_types[tp_module].m__getattr__ = [](VM* vm, PyVar obj, StrName name) -> PyVar{
|
_all_types[tp_module.index].m__getattr__ = [](VM* vm, PyVar obj, StrName name) -> PyVar{
|
||||||
const Str& path = CAST(Str&, obj->attr(__path__));
|
const Str& path = CAST(Str&, obj->attr(__path__));
|
||||||
return vm->py_import(_S(path, ".", name.sv()), false);
|
return vm->py_import(_S(path, ".", name.sv()), false);
|
||||||
};
|
};
|
||||||
@ -1522,22 +1522,22 @@ void VM::__post_init_builtin_types(){
|
|||||||
|
|
||||||
bind__repr__(tp_type, [](VM* vm, PyVar self) -> Str{
|
bind__repr__(tp_type, [](VM* vm, PyVar self) -> Str{
|
||||||
SStream ss;
|
SStream ss;
|
||||||
const PyTypeInfo& info = vm->_all_types[PK_OBJ_GET(Type, self)];
|
const PyTypeInfo& info = vm->_all_types[PK_OBJ_GET(Type, self).index];
|
||||||
ss << "<class '" << info.name << "'>";
|
ss << "<class '" << info.name << "'>";
|
||||||
return ss.str();
|
return ss.str();
|
||||||
});
|
});
|
||||||
|
|
||||||
bind_property(_t(tp_object), "__class__", PK_LAMBDA(vm->_t(args[0])));
|
bind_property(_t(tp_object), "__class__", PK_LAMBDA(vm->_t(args[0])));
|
||||||
bind_property(_t(tp_type), "__base__", [](VM* vm, ArgsView args){
|
bind_property(_t(tp_type), "__base__", [](VM* vm, ArgsView args){
|
||||||
const PyTypeInfo& info = vm->_all_types[PK_OBJ_GET(Type, args[0])];
|
const PyTypeInfo& info = vm->_all_types[PK_OBJ_GET(Type, args[0]).index];
|
||||||
return info.base.index == -1 ? vm->None : vm->_all_types[info.base].obj;
|
return info.base.index == -1 ? vm->None : vm->_all_types[info.base.index].obj;
|
||||||
});
|
});
|
||||||
bind_property(_t(tp_type), "__name__", [](VM* vm, ArgsView args){
|
bind_property(_t(tp_type), "__name__", [](VM* vm, ArgsView args){
|
||||||
const PyTypeInfo& info = vm->_all_types[PK_OBJ_GET(Type, args[0])];
|
const PyTypeInfo& info = vm->_all_types[PK_OBJ_GET(Type, args[0]).index];
|
||||||
return VAR(info.name.sv());
|
return VAR(info.name.sv());
|
||||||
});
|
});
|
||||||
bind_property(_t(tp_type), "__module__", [](VM* vm, ArgsView args){
|
bind_property(_t(tp_type), "__module__", [](VM* vm, ArgsView args){
|
||||||
const PyTypeInfo& info = vm->_all_types[PK_OBJ_GET(Type, args[0])];
|
const PyTypeInfo& info = vm->_all_types[PK_OBJ_GET(Type, args[0]).index];
|
||||||
if(info.mod == nullptr) return vm->None;
|
if(info.mod == nullptr) return vm->None;
|
||||||
return info.mod;
|
return info.mod;
|
||||||
});
|
});
|
||||||
|
@ -17,7 +17,7 @@ int utf8len(unsigned char c, bool suppress){
|
|||||||
if(this->size < (int)sizeof(this->_inlined)){ \
|
if(this->size < (int)sizeof(this->_inlined)){ \
|
||||||
this->data = this->_inlined; \
|
this->data = this->_inlined; \
|
||||||
}else{ \
|
}else{ \
|
||||||
this->data = (char*)pool64_alloc(this->size+1); \
|
this->data = (char*)pool128_alloc(this->size+1); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PK_STR_COPY_INIT(__s) \
|
#define PK_STR_COPY_INIT(__s) \
|
||||||
@ -97,7 +97,7 @@ int utf8len(unsigned char c, bool suppress){
|
|||||||
}
|
}
|
||||||
|
|
||||||
Str& Str::operator=(const Str& other){
|
Str& Str::operator=(const Str& other){
|
||||||
if(!is_inlined()) pool64_dealloc(data);
|
if(!is_inlined()) pool128_dealloc(data);
|
||||||
size = other.size;
|
size = other.size;
|
||||||
is_ascii = other.is_ascii;
|
is_ascii = other.is_ascii;
|
||||||
PK_STR_ALLOCATE()
|
PK_STR_ALLOCATE()
|
||||||
@ -168,7 +168,7 @@ int utf8len(unsigned char c, bool suppress){
|
|||||||
}
|
}
|
||||||
|
|
||||||
Str::~Str(){
|
Str::~Str(){
|
||||||
if(!is_inlined()) pool64_dealloc(data);
|
if(!is_inlined()) pool128_dealloc(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
Str Str::substr(int start, int len) const {
|
Str Str::substr(int start, int len) const {
|
||||||
|
52
src/vm.cpp
52
src/vm.cpp
@ -148,7 +148,7 @@ namespace pkpy{
|
|||||||
do{
|
do{
|
||||||
val = _t(cls)->attr().try_get(name);
|
val = _t(cls)->attr().try_get(name);
|
||||||
if(val != nullptr) return val;
|
if(val != nullptr) return val;
|
||||||
cls = _all_types[cls].base;
|
cls = _all_types[cls.index].base;
|
||||||
if(cls.index == -1) break;
|
if(cls.index == -1) break;
|
||||||
}while(true);
|
}while(true);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -161,7 +161,7 @@ namespace pkpy{
|
|||||||
bool VM::issubclass(Type cls, Type base){
|
bool VM::issubclass(Type cls, Type base){
|
||||||
do{
|
do{
|
||||||
if(cls == base) return true;
|
if(cls == base) return true;
|
||||||
Type next = _all_types[cls].base;
|
Type next = _all_types[cls.index].base;
|
||||||
if(next.index == -1) break;
|
if(next.index == -1) break;
|
||||||
cls = next;
|
cls = next;
|
||||||
}while(true);
|
}while(true);
|
||||||
@ -207,7 +207,7 @@ namespace pkpy{
|
|||||||
|
|
||||||
PyVar VM::new_type_object(PyVar mod, StrName name, Type base, bool subclass_enabled){
|
PyVar VM::new_type_object(PyVar mod, StrName name, Type base, bool subclass_enabled){
|
||||||
PyVar obj = heap._new<Type>(tp_type, Type(_all_types.size()));
|
PyVar obj = heap._new<Type>(tp_type, Type(_all_types.size()));
|
||||||
const PyTypeInfo& base_info = _all_types[base];
|
const PyTypeInfo& base_info = _all_types[base.index];
|
||||||
if(!base_info.subclass_enabled){
|
if(!base_info.subclass_enabled){
|
||||||
Str error = _S("type ", base_info.name.escape(), " is not `subclass_enabled`");
|
Str error = _S("type ", base_info.name.escape(), " is not `subclass_enabled`");
|
||||||
throw std::runtime_error(error.c_str());
|
throw std::runtime_error(error.c_str());
|
||||||
@ -280,10 +280,10 @@ namespace pkpy{
|
|||||||
bool VM::py_callable(PyVar obj){
|
bool VM::py_callable(PyVar obj){
|
||||||
Type cls = vm->_tp(obj);
|
Type cls = vm->_tp(obj);
|
||||||
switch(cls.index){
|
switch(cls.index){
|
||||||
case VM::tp_function.index: return vm->True;
|
case VM::tp_function.index: return true;
|
||||||
case VM::tp_native_func.index: return vm->True;
|
case VM::tp_native_func.index: return true;
|
||||||
case VM::tp_bound_method.index: return vm->True;
|
case VM::tp_bound_method.index: return true;
|
||||||
case VM::tp_type.index: return vm->True;
|
case VM::tp_type.index: return true;
|
||||||
}
|
}
|
||||||
return vm->find_name_in_mro(cls, __call__) != nullptr;
|
return vm->find_name_in_mro(cls, __call__) != nullptr;
|
||||||
}
|
}
|
||||||
@ -501,7 +501,7 @@ i64 VM::py_hash(PyVar obj){
|
|||||||
return CAST(i64, ret);
|
return CAST(i64, ret);
|
||||||
}
|
}
|
||||||
// if it is trivial `object`, return PK_BITS
|
// if it is trivial `object`, return PK_BITS
|
||||||
if(ti == &_all_types[tp_object]) return obj.hash();
|
if(ti == &_all_types[tp_object.index]) return obj.hash();
|
||||||
// otherwise, we check if it has a custom __eq__ other than object.__eq__
|
// otherwise, we check if it has a custom __eq__ other than object.__eq__
|
||||||
bool has_custom_eq = false;
|
bool has_custom_eq = false;
|
||||||
if(ti->m__eq__) has_custom_eq = true;
|
if(ti->m__eq__) has_custom_eq = true;
|
||||||
@ -868,7 +868,7 @@ void VM::__init_builtin_types(){
|
|||||||
this->Ellipsis = heap._new<Dummy>(_new_type("ellipsis"));
|
this->Ellipsis = heap._new<Dummy>(_new_type("ellipsis"));
|
||||||
this->True = heap._new<Dummy>(tp_bool);
|
this->True = heap._new<Dummy>(tp_bool);
|
||||||
this->False = heap._new<Dummy>(tp_bool);
|
this->False = heap._new<Dummy>(tp_bool);
|
||||||
this->StopIteration = _all_types[_new_type("StopIteration", tp_exception)].obj;
|
this->StopIteration = _all_types[_new_type("StopIteration", tp_exception).index].obj;
|
||||||
|
|
||||||
this->builtins = new_module("builtins");
|
this->builtins = new_module("builtins");
|
||||||
|
|
||||||
@ -1182,7 +1182,7 @@ PyVar VM::getattr(PyVar obj, StrName name, bool throw_err){
|
|||||||
if(cls_var != nullptr){
|
if(cls_var != nullptr){
|
||||||
// bound method is non-data descriptor
|
// bound method is non-data descriptor
|
||||||
if(!is_tagged(cls_var)){
|
if(!is_tagged(cls_var)){
|
||||||
switch(cls_var.type){
|
switch(cls_var.type.index){
|
||||||
case tp_function.index:
|
case tp_function.index:
|
||||||
return VAR(BoundMethod(obj, cls_var));
|
return VAR(BoundMethod(obj, cls_var));
|
||||||
case tp_native_func.index:
|
case tp_native_func.index:
|
||||||
@ -1196,7 +1196,7 @@ PyVar VM::getattr(PyVar obj, StrName name, bool throw_err){
|
|||||||
return cls_var;
|
return cls_var;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PyTypeInfo* ti = &_all_types[objtype];
|
const PyTypeInfo* ti = &_all_types[objtype.index];
|
||||||
if(ti->m__getattr__){
|
if(ti->m__getattr__){
|
||||||
PyVar ret = ti->m__getattr__(this, obj, name);
|
PyVar ret = ti->m__getattr__(this, obj, name);
|
||||||
if(ret) return ret;
|
if(ret) return ret;
|
||||||
@ -1249,7 +1249,7 @@ PyVar VM::get_unbound_method(PyVar obj, StrName name, PyVar* self, bool throw_er
|
|||||||
|
|
||||||
if(cls_var != nullptr){
|
if(cls_var != nullptr){
|
||||||
if(!is_tagged(cls_var)){
|
if(!is_tagged(cls_var)){
|
||||||
switch(cls_var.type){
|
switch(cls_var.type.index){
|
||||||
case tp_function.index:
|
case tp_function.index:
|
||||||
*self = obj;
|
*self = obj;
|
||||||
break;
|
break;
|
||||||
@ -1267,7 +1267,7 @@ PyVar VM::get_unbound_method(PyVar obj, StrName name, PyVar* self, bool throw_er
|
|||||||
return cls_var;
|
return cls_var;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PyTypeInfo* ti = &_all_types[objtype];
|
const PyTypeInfo* ti = &_all_types[objtype.index];
|
||||||
if(fallback && ti->m__getattr__){
|
if(fallback && ti->m__getattr__){
|
||||||
PyVar ret = ti->m__getattr__(this, obj, name);
|
PyVar ret = ti->m__getattr__(this, obj, name);
|
||||||
if(ret) return ret;
|
if(ret) return ret;
|
||||||
@ -1301,7 +1301,7 @@ void VM::setattr(PyVar obj, StrName name, PyVar value){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const PyTypeInfo* ti = &_all_types[objtype];
|
const PyTypeInfo* ti = &_all_types[objtype.index];
|
||||||
if(ti->m__setattr__){
|
if(ti->m__setattr__){
|
||||||
ti->m__setattr__(this, obj, name, value);
|
ti->m__setattr__(this, obj, name, value);
|
||||||
return;
|
return;
|
||||||
@ -1429,7 +1429,7 @@ void ManagedHeap::mark() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
StrName _type_name(VM *vm, Type type){
|
StrName _type_name(VM *vm, Type type){
|
||||||
return vm->_all_types[type].name;
|
return vm->_all_types[type.index].name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _gc_mark_namedict(NameDict* t){
|
void _gc_mark_namedict(NameDict* t){
|
||||||
@ -1439,14 +1439,14 @@ void _gc_mark_namedict(NameDict* t){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void VM::bind__getitem__(Type type, PyVar (*f)(VM*, PyVar, PyVar)){
|
void VM::bind__getitem__(Type type, PyVar (*f)(VM*, PyVar, PyVar)){
|
||||||
_all_types[type].m__getitem__ = f;
|
_all_types[type.index].m__getitem__ = f;
|
||||||
bind_func(type, __getitem__, 2, [](VM* vm, ArgsView args){
|
bind_func(type, __getitem__, 2, [](VM* vm, ArgsView args){
|
||||||
return lambda_get_userdata<PyVar(*)(VM*, PyVar, PyVar)>(args.begin())(vm, args[0], args[1]);
|
return lambda_get_userdata<PyVar(*)(VM*, PyVar, PyVar)>(args.begin())(vm, args[0], args[1]);
|
||||||
}, f);
|
}, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VM::bind__setitem__(Type type, void (*f)(VM*, PyVar, PyVar, PyVar)){
|
void VM::bind__setitem__(Type type, void (*f)(VM*, PyVar, PyVar, PyVar)){
|
||||||
_all_types[type].m__setitem__ = f;
|
_all_types[type.index].m__setitem__ = f;
|
||||||
bind_func(type, __setitem__, 3, [](VM* vm, ArgsView args){
|
bind_func(type, __setitem__, 3, [](VM* vm, ArgsView args){
|
||||||
lambda_get_userdata<void(*)(VM* vm, PyVar, PyVar, PyVar)>(args.begin())(vm, args[0], args[1], args[2]);
|
lambda_get_userdata<void(*)(VM* vm, PyVar, PyVar, PyVar)>(args.begin())(vm, args[0], args[1], args[2]);
|
||||||
return vm->None;
|
return vm->None;
|
||||||
@ -1454,7 +1454,7 @@ void VM::bind__setitem__(Type type, void (*f)(VM*, PyVar, PyVar, PyVar)){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void VM::bind__delitem__(Type type, void (*f)(VM*, PyVar, PyVar)){
|
void VM::bind__delitem__(Type type, void (*f)(VM*, PyVar, PyVar)){
|
||||||
_all_types[type].m__delitem__ = f;
|
_all_types[type.index].m__delitem__ = f;
|
||||||
bind_func(type, __delitem__, 2, [](VM* vm, ArgsView args){
|
bind_func(type, __delitem__, 2, [](VM* vm, ArgsView args){
|
||||||
lambda_get_userdata<void(*)(VM*, PyVar, PyVar)>(args.begin())(vm, args[0], args[1]);
|
lambda_get_userdata<void(*)(VM*, PyVar, PyVar)>(args.begin())(vm, args[0], args[1]);
|
||||||
return vm->None;
|
return vm->None;
|
||||||
@ -1470,7 +1470,7 @@ PyVar VM::__pack_next_retval(unsigned n){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void VM::bind__next__(Type type, unsigned (*f)(VM*, PyVar)){
|
void VM::bind__next__(Type type, unsigned (*f)(VM*, PyVar)){
|
||||||
_all_types[type].m__next__ = f;
|
_all_types[type.index].m__next__ = f;
|
||||||
bind_func(type, __next__, 1, [](VM* vm, ArgsView args){
|
bind_func(type, __next__, 1, [](VM* vm, ArgsView args){
|
||||||
int n = lambda_get_userdata<unsigned(*)(VM*, PyVar)>(args.begin())(vm, args[0]);
|
int n = lambda_get_userdata<unsigned(*)(VM*, PyVar)>(args.begin())(vm, args[0]);
|
||||||
return vm->__pack_next_retval(n);
|
return vm->__pack_next_retval(n);
|
||||||
@ -1486,9 +1486,9 @@ void VM::bind__next__(Type type, PyVar (*f)(VM*, PyVar)){
|
|||||||
|
|
||||||
#define BIND_UNARY_SPECIAL(name) \
|
#define BIND_UNARY_SPECIAL(name) \
|
||||||
void VM::bind##name(Type type, PyVar (*f)(VM*, PyVar)){ \
|
void VM::bind##name(Type type, PyVar (*f)(VM*, PyVar)){ \
|
||||||
_all_types[type].m##name = f; \
|
_all_types[type.index].m##name = f; \
|
||||||
bind_func(type, name, 1, [](VM* vm, ArgsView args){ \
|
bind_func(type, name, 1, [](VM* vm, ArgsView args){ \
|
||||||
return lambda_get_userdata<PyVar(*)(VM*, PyVar)>(args.begin())(vm, args[0]); \
|
return lambda_get_userdata<PyVar(*)(VM*, PyVar)>(args.begin())(vm, args[0]);\
|
||||||
}, f); \
|
}, f); \
|
||||||
}
|
}
|
||||||
BIND_UNARY_SPECIAL(__iter__)
|
BIND_UNARY_SPECIAL(__iter__)
|
||||||
@ -1497,7 +1497,7 @@ void VM::bind__next__(Type type, PyVar (*f)(VM*, PyVar)){
|
|||||||
#undef BIND_UNARY_SPECIAL
|
#undef BIND_UNARY_SPECIAL
|
||||||
|
|
||||||
void VM::bind__str__(Type type, Str (*f)(VM*, PyVar)){
|
void VM::bind__str__(Type type, Str (*f)(VM*, PyVar)){
|
||||||
_all_types[type].m__str__ = f;
|
_all_types[type.index].m__str__ = f;
|
||||||
bind_func(type, __str__, 1, [](VM* vm, ArgsView args){
|
bind_func(type, __str__, 1, [](VM* vm, ArgsView args){
|
||||||
Str s = lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0]);
|
Str s = lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0]);
|
||||||
return VAR(s);
|
return VAR(s);
|
||||||
@ -1505,7 +1505,7 @@ void VM::bind__str__(Type type, Str (*f)(VM*, PyVar)){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void VM::bind__repr__(Type type, Str (*f)(VM*, PyVar)){
|
void VM::bind__repr__(Type type, Str (*f)(VM*, PyVar)){
|
||||||
_all_types[type].m__repr__ = f;
|
_all_types[type.index].m__repr__ = f;
|
||||||
bind_func(type, __repr__, 1, [](VM* vm, ArgsView args){
|
bind_func(type, __repr__, 1, [](VM* vm, ArgsView args){
|
||||||
Str s = lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0]);
|
Str s = lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0]);
|
||||||
return VAR(s);
|
return VAR(s);
|
||||||
@ -1513,7 +1513,7 @@ void VM::bind__repr__(Type type, Str (*f)(VM*, PyVar)){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void VM::bind__hash__(Type type, i64 (*f)(VM*, PyVar)){
|
void VM::bind__hash__(Type type, i64 (*f)(VM*, PyVar)){
|
||||||
_all_types[type].m__hash__ = f;
|
_all_types[type.index].m__hash__ = f;
|
||||||
bind_func(type, __hash__, 1, [](VM* vm, ArgsView args){
|
bind_func(type, __hash__, 1, [](VM* vm, ArgsView args){
|
||||||
i64 ret = lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0]);
|
i64 ret = lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0]);
|
||||||
return VAR(ret);
|
return VAR(ret);
|
||||||
@ -1521,7 +1521,7 @@ void VM::bind__hash__(Type type, i64 (*f)(VM*, PyVar)){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void VM::bind__len__(Type type, i64 (*f)(VM*, PyVar)){
|
void VM::bind__len__(Type type, i64 (*f)(VM*, PyVar)){
|
||||||
_all_types[type].m__len__ = f;
|
_all_types[type.index].m__len__ = f;
|
||||||
bind_func(type, __len__, 1, [](VM* vm, ArgsView args){
|
bind_func(type, __len__, 1, [](VM* vm, ArgsView args){
|
||||||
i64 ret = lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0]);
|
i64 ret = lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0]);
|
||||||
return VAR(ret);
|
return VAR(ret);
|
||||||
@ -1531,7 +1531,7 @@ void VM::bind__len__(Type type, i64 (*f)(VM*, PyVar)){
|
|||||||
|
|
||||||
#define BIND_BINARY_SPECIAL(name) \
|
#define BIND_BINARY_SPECIAL(name) \
|
||||||
void VM::bind##name(Type type, BinaryFuncC f){ \
|
void VM::bind##name(Type type, BinaryFuncC f){ \
|
||||||
_all_types[type].m##name = f; \
|
_all_types[type.index].m##name = f; \
|
||||||
bind_func(type, name, 2, [](VM* vm, ArgsView args){ \
|
bind_func(type, name, 2, [](VM* vm, ArgsView args){ \
|
||||||
return lambda_get_userdata<BinaryFuncC>(args.begin())(vm, args[0], args[1]);\
|
return lambda_get_userdata<BinaryFuncC>(args.begin())(vm, args[0], args[1]);\
|
||||||
}, f); \
|
}, f); \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user