mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
some fix
This commit is contained in:
parent
17805032da
commit
ca5881b6cc
@ -24,7 +24,7 @@ static cJSON* covert_dict_to_cjson(const Dict& dict, VM* vm){
|
|||||||
}
|
}
|
||||||
|
|
||||||
static cJSON* convert_python_object_to_cjson(PyVar obj, VM* vm){
|
static cJSON* convert_python_object_to_cjson(PyVar obj, VM* vm){
|
||||||
if(obj == vm->None) return cJSON_CreateNull();
|
if(is_none(obj)) return cJSON_CreateNull();
|
||||||
Type obj_t = vm->_tp(obj);
|
Type obj_t = vm->_tp(obj);
|
||||||
switch(obj_t){
|
switch(obj_t){
|
||||||
case VM::tp_int.index: cJSON_CreateNumber(_CAST(i64, obj));
|
case VM::tp_int.index: cJSON_CreateNumber(_CAST(i64, obj));
|
||||||
|
@ -217,7 +217,7 @@ struct PyLuaFunction: PyLuaObject{
|
|||||||
};
|
};
|
||||||
|
|
||||||
void lua_push_from_python(VM* vm, PyVar val){
|
void lua_push_from_python(VM* vm, PyVar val){
|
||||||
if(val == vm->None){
|
if(is_none(val)){
|
||||||
lua_pushnil(_L);
|
lua_pushnil(_L);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,7 @@ struct Struct {
|
|||||||
template <typename Tp>
|
template <typename Tp>
|
||||||
Tp to_void_p(VM* vm, PyVar var) {
|
Tp to_void_p(VM* vm, PyVar var) {
|
||||||
static_assert(std::is_pointer_v<Tp>);
|
static_assert(std::is_pointer_v<Tp>);
|
||||||
if(var == vm->None) return nullptr; // None can be casted to any pointer implicitly
|
if(is_none(var)) return nullptr; // None can be casted to any pointer implicitly
|
||||||
VoidP& p = CAST(VoidP&, var);
|
VoidP& p = CAST(VoidP&, var);
|
||||||
return reinterpret_cast<Tp>(p.ptr);
|
return reinterpret_cast<Tp>(p.ptr);
|
||||||
}
|
}
|
||||||
|
@ -218,13 +218,14 @@ public:
|
|||||||
constexpr static Type tp_super = Type(15), tp_exception = Type(16), tp_bytes = Type(17), tp_mappingproxy = Type(18);
|
constexpr static Type tp_super = Type(15), tp_exception = Type(16), tp_bytes = Type(17), tp_mappingproxy = Type(18);
|
||||||
constexpr static Type tp_dict = Type(19), tp_property = Type(20), tp_star_wrapper = Type(21);
|
constexpr static Type tp_dict = Type(19), tp_property = Type(20), tp_star_wrapper = Type(21);
|
||||||
constexpr static Type tp_staticmethod = Type(22), tp_classmethod = Type(23);
|
constexpr static Type tp_staticmethod = Type(22), tp_classmethod = Type(23);
|
||||||
constexpr static Type tp_none_type = Type(24), tp_not_implemented = Type(25), tp_ellipsis = Type(26);
|
constexpr static Type tp_none_type = Type(kTpNoneTypeIndex), tp_not_implemented_type = Type(kTpNotImplementedTypeIndex);
|
||||||
|
constexpr static Type tp_ellipsis = Type(26);
|
||||||
constexpr static Type tp_stack_memory = Type(kTpStackMemoryIndex);
|
constexpr static Type tp_stack_memory = Type(kTpStackMemoryIndex);
|
||||||
|
|
||||||
constexpr static PyVar True{const_sso_var(), tp_bool, 1};
|
constexpr static PyVar True{const_sso_var(), tp_bool, 1};
|
||||||
constexpr static PyVar False{const_sso_var(), tp_bool, 0};
|
constexpr static PyVar False{const_sso_var(), tp_bool, 0};
|
||||||
constexpr static PyVar None{const_sso_var(), tp_none_type, 0};
|
constexpr static PyVar None{const_sso_var(), tp_none_type, 0};
|
||||||
constexpr static PyVar NotImplemented{const_sso_var(), tp_not_implemented, 0};
|
constexpr static PyVar NotImplemented{const_sso_var(), tp_not_implemented_type, 0};
|
||||||
constexpr static PyVar Ellipsis{const_sso_var(), tp_ellipsis, 0};
|
constexpr static PyVar Ellipsis{const_sso_var(), tp_ellipsis, 0};
|
||||||
|
|
||||||
const bool enable_os;
|
const bool enable_os;
|
||||||
@ -421,9 +422,6 @@ public:
|
|||||||
const PyTypeInfo* _tp_info(Type type) { return &_all_types[type]; }
|
const PyTypeInfo* _tp_info(Type type) { return &_all_types[type]; }
|
||||||
PyObject* _t(PyVar obj){ return _all_types[_tp(obj)].obj; }
|
PyObject* _t(PyVar obj){ return _all_types[_tp(obj)].obj; }
|
||||||
PyObject* _t(Type type){ return _all_types[type].obj; }
|
PyObject* _t(Type type){ return _all_types[type].obj; }
|
||||||
|
|
||||||
// equivalent to `obj == NotImplemented` but faster
|
|
||||||
static bool is_not_implemented(PyVar obj){ return obj.type == tp_not_implemented; }
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if PK_REGION("User Type Registration")
|
#if PK_REGION("User Type Registration")
|
||||||
@ -684,7 +682,7 @@ __T _py_cast__internal(VM* vm, PyVar obj) {
|
|||||||
if constexpr(std::is_same_v<T, const char*> || std::is_same_v<T, CString>) {
|
if constexpr(std::is_same_v<T, const char*> || std::is_same_v<T, CString>) {
|
||||||
static_assert(!std::is_reference_v<__T>);
|
static_assert(!std::is_reference_v<__T>);
|
||||||
// str (shortcuts)
|
// str (shortcuts)
|
||||||
if(obj == vm->None) return nullptr;
|
if(is_none(obj)) return nullptr;
|
||||||
if constexpr(with_check) vm->check_type(obj, vm->tp_str);
|
if constexpr(with_check) vm->check_type(obj, vm->tp_str);
|
||||||
return PK_OBJ_GET(Str, obj).c_str();
|
return PK_OBJ_GET(Str, obj).c_str();
|
||||||
} else if constexpr(std::is_same_v<T, bool>) {
|
} else if constexpr(std::is_same_v<T, bool>) {
|
||||||
|
@ -75,8 +75,10 @@ struct Slice {
|
|||||||
void _gc_mark(VM*) const;
|
void _gc_mark(VM*) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
const inline int kTpIntIndex = 3;
|
const inline int16_t kTpIntIndex = 3;
|
||||||
const inline int kTpFloatIndex = 4;
|
const inline int16_t kTpFloatIndex = 4;
|
||||||
|
const inline int16_t kTpNoneTypeIndex = 24;
|
||||||
|
const inline int16_t kTpNotImplementedTypeIndex = 25;
|
||||||
|
|
||||||
inline bool is_tagged(PyVar p) noexcept { return !p.is_ptr; }
|
inline bool is_tagged(PyVar p) noexcept { return !p.is_ptr; }
|
||||||
|
|
||||||
@ -84,6 +86,10 @@ inline bool is_float(PyVar p) noexcept { return p.type.index == kTpFloatIndex; }
|
|||||||
|
|
||||||
inline bool is_int(PyVar p) noexcept { return p.type.index == kTpIntIndex; }
|
inline bool is_int(PyVar p) noexcept { return p.type.index == kTpIntIndex; }
|
||||||
|
|
||||||
|
inline bool is_none(PyVar p) noexcept { return p.type.index == kTpNoneTypeIndex; }
|
||||||
|
|
||||||
|
inline bool is_not_implemented(PyVar p) noexcept { return p.type.index == kTpNotImplementedTypeIndex; }
|
||||||
|
|
||||||
inline bool is_type(PyVar obj, Type type) {
|
inline bool is_type(PyVar obj, Type type) {
|
||||||
assert(obj != nullptr);
|
assert(obj != nullptr);
|
||||||
return obj.type == type;
|
return obj.type == type;
|
||||||
|
@ -1042,7 +1042,7 @@ PyVar VM::__run_top_frame() {
|
|||||||
case OP_BEGIN_CLASS: {
|
case OP_BEGIN_CLASS: {
|
||||||
StrName _name(byte.arg);
|
StrName _name(byte.arg);
|
||||||
PyVar _0 = POPX(); // super
|
PyVar _0 = POPX(); // super
|
||||||
if(_0 == None) _0 = _t(tp_object);
|
if(is_none(_0)) _0 = _t(tp_object);
|
||||||
check_type(_0, tp_type);
|
check_type(_0, tp_type);
|
||||||
__curr_class = new_type_object(frame->_module, _name, PK_OBJ_GET(Type, _0), true);
|
__curr_class = new_type_object(frame->_module, _name, PK_OBJ_GET(Type, _0), true);
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ struct JsonSerializer {
|
|||||||
|
|
||||||
void write_object(PyVar obj) {
|
void write_object(PyVar obj) {
|
||||||
Type obj_t = vm->_tp(obj);
|
Type obj_t = vm->_tp(obj);
|
||||||
if(obj == vm->None) {
|
if(is_none(obj)) {
|
||||||
ss << "null";
|
ss << "null";
|
||||||
} else if(obj_t == vm->tp_int) {
|
} else if(obj_t == vm->tp_int) {
|
||||||
ss << _CAST(i64, obj);
|
ss << _CAST(i64, obj);
|
||||||
@ -285,7 +285,7 @@ bool VM::py_callable(PyVar obj) {
|
|||||||
PyVar VM::__minmax_reduce(bool (VM::*op)(PyVar, PyVar), PyVar args, PyVar key) {
|
PyVar VM::__minmax_reduce(bool (VM::*op)(PyVar, PyVar), PyVar args, PyVar key) {
|
||||||
auto _lock = heap.gc_scope_lock();
|
auto _lock = heap.gc_scope_lock();
|
||||||
const Tuple& args_tuple = PK_OBJ_GET(Tuple, args); // from *args, it must be a tuple
|
const Tuple& args_tuple = PK_OBJ_GET(Tuple, args); // from *args, it must be a tuple
|
||||||
if(key == vm->None && args_tuple.size() == 2) {
|
if(is_none(key) && args_tuple.size() == 2) {
|
||||||
// fast path
|
// fast path
|
||||||
PyVar a = args_tuple[0];
|
PyVar a = args_tuple[0];
|
||||||
PyVar b = args_tuple[1];
|
PyVar b = args_tuple[1];
|
||||||
@ -304,7 +304,7 @@ PyVar VM::__minmax_reduce(bool (VM::*op)(PyVar, PyVar), PyVar args, PyVar key) {
|
|||||||
if(view.empty()) ValueError("arg is an empty sequence");
|
if(view.empty()) ValueError("arg is an empty sequence");
|
||||||
PyVar res = view[0];
|
PyVar res = view[0];
|
||||||
|
|
||||||
if(key == vm->None) {
|
if(is_none(key)) {
|
||||||
for(int i = 1; i < view.size(); i++) {
|
for(int i = 1; i < view.size(); i++) {
|
||||||
if((this->*op)(view[i], res)) res = view[i];
|
if((this->*op)(view[i], res)) res = view[i];
|
||||||
}
|
}
|
||||||
@ -419,7 +419,7 @@ PyVar VM::py_negate(PyVar obj) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool VM::__py_bool_non_trivial(PyVar obj) {
|
bool VM::__py_bool_non_trivial(PyVar obj) {
|
||||||
if(obj == None) return false;
|
if(is_none(obj)) return false;
|
||||||
if(is_int(obj)) return _CAST(i64, obj) != 0;
|
if(is_int(obj)) return _CAST(i64, obj) != 0;
|
||||||
if(is_float(obj)) return _CAST(f64, obj) != 0.0;
|
if(is_float(obj)) return _CAST(f64, obj) != 0.0;
|
||||||
PyVar self;
|
PyVar self;
|
||||||
@ -486,20 +486,20 @@ void VM::parse_int_slice(const Slice& s, int length, int& start, int& stop, int&
|
|||||||
if(value > max) return max;
|
if(value > max) return max;
|
||||||
return value;
|
return value;
|
||||||
};
|
};
|
||||||
if(s.step == None)
|
if(is_none(s.step))
|
||||||
step = 1;
|
step = 1;
|
||||||
else
|
else
|
||||||
step = CAST(int, s.step);
|
step = CAST(int, s.step);
|
||||||
if(step == 0) ValueError("slice step cannot be zero");
|
if(step == 0) ValueError("slice step cannot be zero");
|
||||||
if(step > 0) {
|
if(step > 0) {
|
||||||
if(s.start == None) {
|
if(is_none(s.start)) {
|
||||||
start = 0;
|
start = 0;
|
||||||
} else {
|
} else {
|
||||||
start = CAST(int, s.start);
|
start = CAST(int, s.start);
|
||||||
if(start < 0) start += length;
|
if(start < 0) start += length;
|
||||||
start = clip(start, 0, length);
|
start = clip(start, 0, length);
|
||||||
}
|
}
|
||||||
if(s.stop == None) {
|
if(is_none(s.stop)) {
|
||||||
stop = length;
|
stop = length;
|
||||||
} else {
|
} else {
|
||||||
stop = CAST(int, s.stop);
|
stop = CAST(int, s.stop);
|
||||||
@ -507,14 +507,14 @@ void VM::parse_int_slice(const Slice& s, int length, int& start, int& stop, int&
|
|||||||
stop = clip(stop, 0, length);
|
stop = clip(stop, 0, length);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(s.start == None) {
|
if(is_none(s.start)) {
|
||||||
start = length - 1;
|
start = length - 1;
|
||||||
} else {
|
} else {
|
||||||
start = CAST(int, s.start);
|
start = CAST(int, s.start);
|
||||||
if(start < 0) start += length;
|
if(start < 0) start += length;
|
||||||
start = clip(start, -1, length - 1);
|
start = clip(start, -1, length - 1);
|
||||||
}
|
}
|
||||||
if(s.stop == None) {
|
if(is_none(s.stop)) {
|
||||||
stop = -1;
|
stop = -1;
|
||||||
} else {
|
} else {
|
||||||
stop = CAST(int, s.stop);
|
stop = CAST(int, s.stop);
|
||||||
@ -557,7 +557,7 @@ PyVar VM::__py_exec_internal(const CodeObject_& code, PyVar globals, PyVar local
|
|||||||
if(!callstack.empty()) frame = &callstack.top();
|
if(!callstack.empty()) frame = &callstack.top();
|
||||||
|
|
||||||
// fast path
|
// fast path
|
||||||
if(frame && globals == vm->None && locals == vm->None) {
|
if(frame && is_none(globals) && is_none(locals)) {
|
||||||
return vm->_exec(code.get(), frame->_module, frame->_callable, frame->_locals);
|
return vm->_exec(code.get(), frame->_module, frame->_callable, frame->_locals);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -569,8 +569,8 @@ PyVar VM::__py_exec_internal(const CodeObject_& code, PyVar globals, PyVar local
|
|||||||
NameDict_ locals_closure = nullptr;
|
NameDict_ locals_closure = nullptr;
|
||||||
Dict* locals_dict = nullptr;
|
Dict* locals_dict = nullptr;
|
||||||
|
|
||||||
if(frame && globals == vm->None) {
|
if(is_none(globals)){
|
||||||
globals_obj = frame->_module;
|
globals_obj = frame ? frame->_module: _main;
|
||||||
} else {
|
} else {
|
||||||
if(is_type(globals, VM::tp_mappingproxy)) {
|
if(is_type(globals, VM::tp_mappingproxy)) {
|
||||||
globals_obj = PK_OBJ_GET(MappingProxy, globals).obj;
|
globals_obj = PK_OBJ_GET(MappingProxy, globals).obj;
|
||||||
@ -588,7 +588,7 @@ PyVar VM::__py_exec_internal(const CodeObject_& code, PyVar globals, PyVar local
|
|||||||
|
|
||||||
PyVar retval = nullptr;
|
PyVar retval = nullptr;
|
||||||
|
|
||||||
if(locals == vm->None) {
|
if(is_none(locals)) {
|
||||||
retval = vm->_exec(code, globals_obj); // only globals
|
retval = vm->_exec(code, globals_obj); // only globals
|
||||||
} else {
|
} else {
|
||||||
check_compatible_type(locals, VM::tp_dict);
|
check_compatible_type(locals, VM::tp_dict);
|
||||||
@ -909,7 +909,7 @@ void VM::__init_builtin_types() {
|
|||||||
validate(tp_classmethod, new_type_object<ClassMethod>(nullptr, "classmethod", tp_object, false));
|
validate(tp_classmethod, new_type_object<ClassMethod>(nullptr, "classmethod", tp_object, false));
|
||||||
|
|
||||||
validate(tp_none_type, new_type_object(nullptr, "NoneType", tp_object, false));
|
validate(tp_none_type, new_type_object(nullptr, "NoneType", tp_object, false));
|
||||||
validate(tp_not_implemented, new_type_object(nullptr, "NotImplementedType", tp_object, false));
|
validate(tp_not_implemented_type, new_type_object(nullptr, "NotImplementedType", tp_object, false));
|
||||||
validate(tp_ellipsis, new_type_object(nullptr, "ellipsis", tp_object, false));
|
validate(tp_ellipsis, new_type_object(nullptr, "ellipsis", tp_object, false));
|
||||||
validate(tp_stack_memory, new_type_object<StackMemory>(nullptr, "_stack_memory", tp_object, false));
|
validate(tp_stack_memory, new_type_object<StackMemory>(nullptr, "_stack_memory", tp_object, false));
|
||||||
|
|
||||||
|
@ -154,7 +154,7 @@ struct Array2d {
|
|||||||
case VM::tp_float.index: is_basic_type = true; break;
|
case VM::tp_float.index: is_basic_type = true; break;
|
||||||
case VM::tp_str.index: is_basic_type = true; break;
|
case VM::tp_str.index: is_basic_type = true; break;
|
||||||
case VM::tp_bool.index: is_basic_type = true; break;
|
case VM::tp_bool.index: is_basic_type = true; break;
|
||||||
default: is_basic_type = _2 == vm->None;
|
default: is_basic_type = is_none(_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(is_basic_type) {
|
if(is_basic_type) {
|
||||||
|
@ -396,7 +396,7 @@ void Mat3x3::_register(VM* vm, PyObject* mod, PyObject* type) {
|
|||||||
vm->bind(type, "matmul(self, other: mat3x3, out: mat3x3 = None)", [](VM* vm, ArgsView args) {
|
vm->bind(type, "matmul(self, other: mat3x3, out: mat3x3 = None)", [](VM* vm, ArgsView args) {
|
||||||
const Mat3x3& self = _CAST(Mat3x3&, args[0]);
|
const Mat3x3& self = _CAST(Mat3x3&, args[0]);
|
||||||
const Mat3x3& other = CAST(Mat3x3&, args[1]);
|
const Mat3x3& other = CAST(Mat3x3&, args[1]);
|
||||||
if(args[2] == vm->None) {
|
if(is_none(args[2])) {
|
||||||
return vm->new_user_object<Mat3x3>(self.matmul(other));
|
return vm->new_user_object<Mat3x3>(self.matmul(other));
|
||||||
} else {
|
} else {
|
||||||
Mat3x3& out = CAST(Mat3x3&, args[2]);
|
Mat3x3& out = CAST(Mat3x3&, args[2]);
|
||||||
|
@ -183,7 +183,7 @@ struct Random {
|
|||||||
int size = view.size();
|
int size = view.size();
|
||||||
if(size == 0) vm->IndexError("cannot choose from an empty sequence");
|
if(size == 0) vm->IndexError("cannot choose from an empty sequence");
|
||||||
array<f64> cum_weights(size);
|
array<f64> cum_weights(size);
|
||||||
if(args[2] == vm->None) {
|
if(is_none(args[2])) {
|
||||||
for(int i = 0; i < size; i++)
|
for(int i = 0; i < size; i++)
|
||||||
cum_weights[i] = i + 1;
|
cum_weights[i] = i + 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -162,7 +162,7 @@ void __init_builtins(VM* _vm) {
|
|||||||
if(is_int(args[0])) return args[0];
|
if(is_int(args[0])) return args[0];
|
||||||
f64 x = CAST(f64, args[0]);
|
f64 x = CAST(f64, args[0]);
|
||||||
f64 offset = x >= 0 ? 0.5 : -0.5;
|
f64 offset = x >= 0 ? 0.5 : -0.5;
|
||||||
if(args[1] == vm->None) return VAR((i64)(x + offset));
|
if(is_none(args[1])) return VAR((i64)(x + offset));
|
||||||
int ndigits = CAST(int, args[1]);
|
int ndigits = CAST(int, args[1]);
|
||||||
if(ndigits < 0) vm->ValueError("ndigits should be non-negative");
|
if(ndigits < 0) vm->ValueError("ndigits should be non-negative");
|
||||||
// ndigits > 0
|
// ndigits > 0
|
||||||
@ -751,7 +751,7 @@ void __init_builtins(VM* _vm) {
|
|||||||
|
|
||||||
_vm->bind(_vm->_t(VM::tp_str), "strip(self, chars=None)", [](VM* vm, ArgsView args) {
|
_vm->bind(_vm->_t(VM::tp_str), "strip(self, chars=None)", [](VM* vm, ArgsView args) {
|
||||||
const Str& self = _CAST(Str&, args[0]);
|
const Str& self = _CAST(Str&, args[0]);
|
||||||
if(args[1] == vm->None) {
|
if(is_none(args[1])) {
|
||||||
return VAR(self.strip());
|
return VAR(self.strip());
|
||||||
} else {
|
} else {
|
||||||
const Str& chars = CAST(Str&, args[1]);
|
const Str& chars = CAST(Str&, args[1]);
|
||||||
@ -761,7 +761,7 @@ void __init_builtins(VM* _vm) {
|
|||||||
|
|
||||||
_vm->bind(_vm->_t(VM::tp_str), "lstrip(self, chars=None)", [](VM* vm, ArgsView args) {
|
_vm->bind(_vm->_t(VM::tp_str), "lstrip(self, chars=None)", [](VM* vm, ArgsView args) {
|
||||||
const Str& self = _CAST(Str&, args[0]);
|
const Str& self = _CAST(Str&, args[0]);
|
||||||
if(args[1] == vm->None) {
|
if(is_none(args[1])) {
|
||||||
return VAR(self.lstrip());
|
return VAR(self.lstrip());
|
||||||
} else {
|
} else {
|
||||||
const Str& chars = CAST(Str&, args[1]);
|
const Str& chars = CAST(Str&, args[1]);
|
||||||
@ -771,7 +771,7 @@ void __init_builtins(VM* _vm) {
|
|||||||
|
|
||||||
_vm->bind(_vm->_t(VM::tp_str), "rstrip(self, chars=None)", [](VM* vm, ArgsView args) {
|
_vm->bind(_vm->_t(VM::tp_str), "rstrip(self, chars=None)", [](VM* vm, ArgsView args) {
|
||||||
const Str& self = _CAST(Str&, args[0]);
|
const Str& self = _CAST(Str&, args[0]);
|
||||||
if(args[1] == vm->None) {
|
if(is_none(args[1])) {
|
||||||
return VAR(self.rstrip());
|
return VAR(self.rstrip());
|
||||||
} else {
|
} else {
|
||||||
const Str& chars = CAST(Str&, args[1]);
|
const Str& chars = CAST(Str&, args[1]);
|
||||||
@ -826,7 +826,7 @@ void __init_builtins(VM* _vm) {
|
|||||||
_vm->bind(_vm->_t(VM::tp_list), "sort(self, key=None, reverse=False)", [](VM* vm, ArgsView args) {
|
_vm->bind(_vm->_t(VM::tp_list), "sort(self, key=None, reverse=False)", [](VM* vm, ArgsView args) {
|
||||||
List& self = _CAST(List&, args[0]);
|
List& self = _CAST(List&, args[0]);
|
||||||
PyVar key = args[1];
|
PyVar key = args[1];
|
||||||
if(key == vm->None) {
|
if(is_none(key)) {
|
||||||
std::stable_sort(self.begin(), self.end(), [vm](PyVar a, PyVar b) {
|
std::stable_sort(self.begin(), self.end(), [vm](PyVar a, PyVar b) {
|
||||||
return vm->py_lt(a, b);
|
return vm->py_lt(a, b);
|
||||||
});
|
});
|
||||||
|
@ -294,7 +294,7 @@ bool pkpy_is_none(pkpy_vm* vm_handle, int i) {
|
|||||||
PK_ASSERT_NO_ERROR()
|
PK_ASSERT_NO_ERROR()
|
||||||
PK_PROTECTED(
|
PK_PROTECTED(
|
||||||
PyVar item = stack_item(vm, i);
|
PyVar item = stack_item(vm, i);
|
||||||
return item == vm->None;
|
return is_none(item);
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user