blueloveTH 3 years ago
parent
commit
b0e2c6e489
5 changed files with 42 additions and 50 deletions
  1. 6 6
      src/ceval.h
  2. 4 4
      src/cffi.h
  3. 2 2
      src/compiler.h
  4. 25 25
      src/pocketpy.h
  5. 5 13
      src/vm.h

+ 6 - 6
src/ceval.h

@@ -150,13 +150,13 @@ PyVar VM::run_frame(Frame* frame){
             PyVar rhs = frame->pop_value(this);
             bool ret_c = rhs == frame->top_value(this);
             if(byte.arg == 1) ret_c = !ret_c;
-            frame->top() = PyBool(ret_c);
+            frame->top() = py_object(this, ret_c);
         } continue;
         case OP_CONTAINS_OP: {
             PyVar rhs = frame->pop_value(this);
-            bool ret_c = PyBool_AS_C(call(rhs, __contains__, one_arg(frame->pop_value(this))));
+            bool ret_c = py_cast_v<bool>(this, call(rhs, __contains__, one_arg(frame->pop_value(this))));
             if(byte.arg == 1) ret_c = !ret_c;
-            frame->push(PyBool(ret_c));
+            frame->push(py_object(this, ret_c));
         } continue;
         case OP_UNARY_NEGATIVE:
             frame->top() = num_negated(frame->top_value(this));
@@ -164,10 +164,10 @@ PyVar VM::run_frame(Frame* frame){
         case OP_UNARY_NOT: {
             PyVar obj = frame->pop_value(this);
             const PyVar& obj_bool = asBool(obj);
-            frame->push(PyBool(!_PyBool_AS_C(obj_bool)));
+            frame->push(py_object(this, !_py_cast_v<bool>(this, obj_bool)));
         } continue;
         case OP_POP_JUMP_IF_FALSE:
-            if(!_PyBool_AS_C(asBool(frame->pop_value(this)))) frame->jump_abs(byte.arg);
+            if(!_py_cast_v<bool>(this, asBool(frame->pop_value(this)))) frame->jump_abs(byte.arg);
             continue;
         case OP_LOAD_NONE: frame->push(None); continue;
         case OP_LOAD_TRUE: frame->push(True); continue;
@@ -182,7 +182,7 @@ PyVar VM::run_frame(Frame* frame){
         case OP_EXCEPTION_MATCH: {
             const auto& e = py_cast<Exception>(this, frame->top());
             StrName name = frame->co->names[byte.arg].first;
-            frame->push(PyBool(e.match_type(name)));
+            frame->push(py_object(this, e.match_type(name)));
         } continue;
         case OP_RAISE: {
             PyVar obj = frame->pop_value(this);

+ 4 - 4
src/cffi.h

@@ -89,13 +89,13 @@ struct Pointer{
         vm->bind_method<1>(type, "__eq__", [](VM* vm, Args& args) {
             Pointer& self = vm->_cast<Pointer>(args[0]);
             Pointer& other = vm->_cast<Pointer>(args[1]);
-            return vm->PyBool(self.ptr == other.ptr);
+            return py_object(vm, self.ptr == other.ptr);
         });
 
         vm->bind_method<1>(type, "__ne__", [](VM* vm, Args& args) {
             Pointer& self = vm->_cast<Pointer>(args[0]);
             Pointer& other = vm->_cast<Pointer>(args[1]);
-            return vm->PyBool(self.ptr != other.ptr);
+            return py_object(vm, self.ptr != other.ptr);
         });
 
         // https://docs.python.org/zh-cn/3/library/ctypes.html
@@ -145,7 +145,7 @@ struct Pointer{
             case C_TYPE("int_"): return py_object(vm, ref<int>());
             case C_TYPE("float_"): return py_object(vm, ref<float>());
             case C_TYPE("double_"): return py_object(vm, ref<double>());
-            case C_TYPE("bool_"): return vm->PyBool(ref<bool>());
+            case C_TYPE("bool_"): return py_object(vm, ref<bool>());
             case C_TYPE("void_"): vm->ValueError("cannot get void*"); break;
             case C_TYPE("int8_"): return py_object(vm, ref<int8_t>());
             case C_TYPE("int16_"): return py_object(vm, ref<int16_t>());
@@ -168,7 +168,7 @@ struct Pointer{
             case C_TYPE("int_"): ref<int>() = py_cast_v<i64>(vm, val); break;
             case C_TYPE("float_"): ref<float>() = py_cast_v<f64>(vm, val); break;
             case C_TYPE("double_"): ref<double>() = py_cast_v<f64>(vm, val); break;
-            case C_TYPE("bool_"): ref<bool>() = vm->PyBool_AS_C(val); break;
+            case C_TYPE("bool_"): ref<bool>() = py_cast_v<bool>(vm, val); break;
             case C_TYPE("void_"): vm->ValueError("cannot set void*"); break;
             case C_TYPE("int8_"): ref<int8_t>() = py_cast_v<i64>(vm, val); break;
             case C_TYPE("int16_"): ref<int16_t>() = py_cast_v<i64>(vm, val); break;

+ 2 - 2
src/compiler.h

@@ -1101,8 +1101,8 @@ __LISTCOMP:
         }
         if(match(TK("@num"))) return parser->prev.value;
         if(match(TK("@str"))) return parser->prev.value;
-        if(match(TK("True"))) return vm->PyBool(true);
-        if(match(TK("False"))) return vm->PyBool(false);
+        if(match(TK("True"))) return py_object(vm, true);
+        if(match(TK("False"))) return py_object(vm, false);
         if(match(TK("None"))) return vm->None;
         if(match(TK("..."))) return vm->Ellipsis;
         return nullptr;

+ 25 - 25
src/pocketpy.h

@@ -31,12 +31,12 @@ CodeObject_ VM::compile(Str source, Str filename, CompileMode mode) {
 #define BIND_NUM_LOGICAL_OPT(name, op, is_eq)                                                           \
     _vm->_bind_methods<1>({"int","float"}, #name, [](VM* vm, Args& args){                         \
         if(!is_both_int_or_float(args[0], args[1])){                                                    \
-            if constexpr(is_eq) return vm->PyBool(args[0] op args[1]);                                  \
+            if constexpr(is_eq) return py_object(vm, args[0] op args[1]);                                  \
             vm->TypeError("unsupported operand type(s) for " #op );                                     \
         }                                                                                               \
         if(is_both_int(args[0], args[1]))                                                               \
-            return vm->PyBool(_py_cast_v<i64>(vm, args[0]) op _py_cast_v<i64>(vm, args[1]));                    \
-        return vm->PyBool(vm->num_to_float(args[0]) op vm->num_to_float(args[1]));                      \
+            return py_object(vm, _py_cast_v<i64>(vm, args[0]) op _py_cast_v<i64>(vm, args[1]));                    \
+        return py_object(vm, vm->num_to_float(args[0]) op vm->num_to_float(args[1]));                      \
     });
     
 
@@ -117,7 +117,7 @@ void init_builtins(VM* _vm) {
     });
 
     _vm->bind_builtin_func<2>("hasattr", [](VM* vm, Args& args) {
-        return vm->PyBool(vm->getattr(args[0], py_cast<Str>(vm, args[1]), false) != nullptr);
+        return py_object(vm, vm->getattr(args[0], py_cast<Str>(vm, args[1]), false) != nullptr);
     });
 
     _vm->bind_builtin_func<3>("setattr", [](VM* vm, Args& args) {
@@ -159,8 +159,8 @@ void init_builtins(VM* _vm) {
         return py_object(vm, s);
     });
 
-    _vm->bind_method<1>("object", "__eq__", CPP_LAMBDA(vm->PyBool(args[0] == args[1])));
-    _vm->bind_method<1>("object", "__ne__", CPP_LAMBDA(vm->PyBool(args[0] != args[1])));
+    _vm->bind_method<1>("object", "__eq__", CPP_LAMBDA(py_object(vm, args[0] == args[1])));
+    _vm->bind_method<1>("object", "__ne__", CPP_LAMBDA(py_object(vm, args[0] != args[1])));
 
     _vm->bind_static_method<1>("type", "__new__", CPP_LAMBDA(vm->_t(args[0])));
 
@@ -211,7 +211,7 @@ void init_builtins(VM* _vm) {
     _vm->bind_static_method<1>("int", "__new__", [](VM* vm, Args& args) {
         if (is_type(args[0], vm->tp_int)) return args[0];
         if (is_type(args[0], vm->tp_float)) return py_object(vm, (i64)py_cast_v<f64>(vm, args[0]));
-        if (is_type(args[0], vm->tp_bool)) return py_object(vm, vm->_PyBool_AS_C(args[0]) ? 1 : 0);
+        if (is_type(args[0], vm->tp_bool)) return py_object(vm, _py_cast_v<bool>(vm, args[0]) ? 1 : 0);
         if (is_type(args[0], vm->tp_str)) {
             const Str& s = py_cast<Str>(vm, args[0]);
             try{
@@ -257,7 +257,7 @@ void init_builtins(VM* _vm) {
     _vm->bind_static_method<1>("float", "__new__", [](VM* vm, Args& args) {
         if (is_type(args[0], vm->tp_int)) return py_object(vm, (f64)py_cast_v<i64>(vm, args[0]));
         if (is_type(args[0], vm->tp_float)) return args[0];
-        if (is_type(args[0], vm->tp_bool)) return py_object(vm, vm->_PyBool_AS_C(args[0]) ? 1.0 : 0.0);
+        if (is_type(args[0], vm->tp_bool)) return py_object(vm, _py_cast_v<bool>(vm, args[0]) ? 1.0 : 0.0);
         if (is_type(args[0], vm->tp_str)) {
             const Str& s = py_cast<Str>(vm, args[0]);
             if(s == "inf") return py_object(vm, INFINITY);
@@ -306,7 +306,7 @@ void init_builtins(VM* _vm) {
     _vm->bind_method<1>("str", "__contains__", [](VM* vm, Args& args) {
         const Str& self = py_cast<Str>(vm, args[0]);
         const Str& other = py_cast<Str>(vm, args[1]);
-        return vm->PyBool(self.find(other) != Str::npos);
+        return py_object(vm, self.find(other) != Str::npos);
     });
 
     _vm->bind_method<0>("str", "__str__", CPP_LAMBDA(args[0]));
@@ -324,14 +324,14 @@ void init_builtins(VM* _vm) {
 
     _vm->bind_method<1>("str", "__eq__", [](VM* vm, Args& args) {
         if(is_type(args[0], vm->tp_str) && is_type(args[1], vm->tp_str))
-            return vm->PyBool(py_cast<Str>(vm, args[0]) == py_cast<Str>(vm, args[1]));
-        return vm->PyBool(args[0] == args[1]);
+            return py_object(vm, py_cast<Str>(vm, args[0]) == py_cast<Str>(vm, args[1]));
+        return py_object(vm, args[0] == args[1]);
     });
 
     _vm->bind_method<1>("str", "__ne__", [](VM* vm, Args& args) {
         if(is_type(args[0], vm->tp_str) && is_type(args[1], vm->tp_str))
-            return vm->PyBool(py_cast<Str>(vm, args[0]) != py_cast<Str>(vm, args[1]));
-        return vm->PyBool(args[0] != args[1]);
+            return py_object(vm, py_cast<Str>(vm, args[0]) != py_cast<Str>(vm, args[1]));
+        return py_object(vm, args[0] != args[1]);
     });
 
     _vm->bind_method<1>("str", "__getitem__", [](VM* vm, Args& args) {
@@ -351,13 +351,13 @@ void init_builtins(VM* _vm) {
     _vm->bind_method<1>("str", "__gt__", [](VM* vm, Args& args) {
         const Str& self (py_cast<Str>(vm, args[0]));
         const Str& obj (py_cast<Str>(vm, args[1]));
-        return vm->PyBool(self > obj);
+        return py_object(vm, self > obj);
     });
 
     _vm->bind_method<1>("str", "__lt__", [](VM* vm, Args& args) {
         const Str& self (py_cast<Str>(vm, args[0]));
         const Str& obj (py_cast<Str>(vm, args[1]));
-        return vm->PyBool(self < obj);
+        return py_object(vm, self < obj);
     });
 
     _vm->bind_method<2>("str", "replace", [](VM* vm, Args& args) {
@@ -377,13 +377,13 @@ void init_builtins(VM* _vm) {
     _vm->bind_method<1>("str", "startswith", [](VM* vm, Args& args) {
         const Str& _self = py_cast<Str>(vm, args[0]);
         const Str& _prefix = py_cast<Str>(vm, args[1]);
-        return vm->PyBool(_self.find(_prefix) == 0);
+        return py_object(vm, _self.find(_prefix) == 0);
     });
 
     _vm->bind_method<1>("str", "endswith", [](VM* vm, Args& args) {
         const Str& _self = py_cast<Str>(vm, args[0]);
         const Str& _suffix = py_cast<Str>(vm, args[1]);
-        return vm->PyBool(_self.rfind(_suffix) == _self.length() - _suffix.length());
+        return py_object(vm, _self.rfind(_suffix) == _self.length() - _suffix.length());
     });
 
     _vm->bind_method<1>("str", "join", [](VM* vm, Args& args) {
@@ -521,19 +521,19 @@ void init_builtins(VM* _vm) {
     _vm->bind_static_method<1>("bool", "__new__", CPP_LAMBDA(vm->asBool(args[0])));
 
     _vm->bind_method<0>("bool", "__repr__", [](VM* vm, Args& args) {
-        bool val = vm->PyBool_AS_C(args[0]);
+        bool val = py_cast_v<bool>(vm, args[0]);
         return py_object(vm, val ? "True" : "False");
     });
 
     _vm->bind_method<0>("bool", "__json__", [](VM* vm, Args& args) {
-        bool val = vm->PyBool_AS_C(args[0]);
+        bool val = py_cast_v<bool>(vm, args[0]);
         return py_object(vm, val ? "true" : "false");
     });
 
     _vm->bind_method<1>("bool", "__xor__", [](VM* vm, Args& args) {
-        bool self = vm->PyBool_AS_C(args[0]);
-        bool other = vm->PyBool_AS_C(args[1]);
-        return vm->PyBool(self ^ other);
+        bool self = py_cast_v<bool>(vm, args[0]);
+        bool other = py_cast_v<bool>(vm, args[1]);
+        return py_object(vm, self ^ other);
     });
 
     _vm->bind_method<0>("ellipsis", "__repr__", CPP_LAMBDA(py_object(vm, "Ellipsis")));
@@ -596,8 +596,8 @@ void add_module_math(VM* vm){
     vm->bind_func<1>(mod, "sin", CPP_LAMBDA(py_object(vm, std::sin(vm->num_to_float(args[0])))));
     vm->bind_func<1>(mod, "cos", CPP_LAMBDA(py_object(vm, std::cos(vm->num_to_float(args[0])))));
     vm->bind_func<1>(mod, "tan", CPP_LAMBDA(py_object(vm, std::tan(vm->num_to_float(args[0])))));
-    vm->bind_func<1>(mod, "isnan", CPP_LAMBDA(vm->PyBool(std::isnan(vm->num_to_float(args[0])))));
-    vm->bind_func<1>(mod, "isinf", CPP_LAMBDA(vm->PyBool(std::isinf(vm->num_to_float(args[0])))));
+    vm->bind_func<1>(mod, "isnan", CPP_LAMBDA(py_object(vm, std::isnan(vm->num_to_float(args[0])))));
+    vm->bind_func<1>(mod, "isinf", CPP_LAMBDA(py_object(vm, std::isinf(vm->num_to_float(args[0])))));
     vm->bind_func<1>(mod, "fabs", CPP_LAMBDA(py_object(vm, std::fabs(vm->num_to_float(args[0])))));
     vm->bind_func<1>(mod, "floor", CPP_LAMBDA(py_object(vm, (i64)std::floor(vm->num_to_float(args[0])))));
     vm->bind_func<1>(mod, "ceil", CPP_LAMBDA(py_object(vm, (i64)std::ceil(vm->num_to_float(args[0])))));
@@ -977,7 +977,7 @@ extern "C" {
             switch(ret_code){
                 case 'i': return py_object(vm, f_int(packet));
                 case 'f': return py_object(vm, f_float(packet));
-                case 'b': return vm->PyBool(f_bool(packet));
+                case 'b': return py_object(vm, f_bool(packet));
                 case 's': {
                     char* p = f_str(packet);
                     if(p == nullptr) return vm->None;

+ 5 - 13
src/vm.h

@@ -247,14 +247,6 @@ public:
         return static_cast<BaseIter*>(obj->value());
     }
     
-    // there is only one True/False, so no need to copy them!
-    inline bool PyBool_AS_C(const PyVar& obj){
-        check_type(obj, tp_bool);
-        return obj == True;
-    }
-    inline bool _PyBool_AS_C(const PyVar& obj){ return obj == True; }
-    inline const PyVar& PyBool(bool value){return value ? True : False;}
-
     /***** Error Reporter *****/
     void _error(StrName name, const Str& msg){
         _error(Exception(name, msg));
@@ -433,7 +425,7 @@ template<> f64 _py_cast_v<f64>(VM* vm, const PyVar& obj){
     return __8B(bits)._float;
 }
 
-PyVar py_object(VM* vm, bool val){
+const PyVar& py_object(VM* vm, bool val){
     return val ? vm->True : vm->False;
 }
 template<> bool py_cast_v<bool>(VM* vm, const PyVar& obj){
@@ -471,12 +463,12 @@ f64 VM::num_to_float(const PyVar& obj){
 const PyVar& VM::asBool(const PyVar& obj){
     if(is_type(obj, tp_bool)) return obj;
     if(obj == None) return False;
-    if(is_type(obj, tp_int)) return PyBool(py_cast_v<i64>(this, obj) != 0);
-    if(is_type(obj, tp_float)) return PyBool(py_cast_v<f64>(this, obj) != 0.0);
+    if(is_type(obj, tp_int)) return py_object(this, py_cast_v<i64>(this, obj) != 0);
+    if(is_type(obj, tp_float)) return py_object(this, py_cast_v<f64>(this, obj) != 0.0);
     PyVarOrNull len_fn = getattr(obj, __len__, false);
     if(len_fn != nullptr){
         PyVar ret = call(len_fn);
-        return PyBool(py_cast_v<i64>(this, ret) > 0);
+        return py_object(this, py_cast_v<i64>(this, ret) > 0);
     }
     return True;
 }
@@ -494,7 +486,7 @@ i64 VM::hash(const PyVar& obj){
         return x;
     }
     if (is_type(obj, tp_type)) return obj.bits;
-    if (is_type(obj, tp_bool)) return _PyBool_AS_C(obj) ? 1 : 0;
+    if (is_type(obj, tp_bool)) return _py_cast_v<bool>(this, obj) ? 1 : 0;
     if (is_float(obj)){
         f64 val = py_cast_v<f64>(this, obj);
         return (i64)std::hash<f64>()(val);