blueloveTH před 1 rokem
rodič
revize
c954431442
4 změnil soubory, kde provedl 78 přidání a 138 odebrání
  1. 1 3
      include/pocketpy/pocketpy.h
  2. 41 99
      src/interpreter/ceval.c
  3. 35 35
      src/interpreter/py_number.c
  4. 1 1
      src/public/vm.c

+ 1 - 3
include/pocketpy/pocketpy.h

@@ -18,10 +18,8 @@ typedef struct py_Error {
 /// Native function signature.
 /// @param argc number of arguments.
 /// @param argv array of arguments. Use `py_arg(i)` macro to get the i-th argument.
-/// @param out output reference to the result. Please note that `out` could overlap with `argv`.
-/// Always set `out` after using `argv`.
 /// @return true if the function is successful.
-typedef bool (*py_CFunction)(int argc, py_TValue* argv, py_TValue* out);
+typedef bool (*py_CFunction)(int argc, py_TValue* argv);
 
 typedef enum BindType {
     BindType_FUNCTION,

+ 41 - 99
src/interpreter/ceval.c

@@ -11,6 +11,8 @@ int NameError(py_Name name) { return -1; }
 #define AttributeError(obj, name) false
 #define BinaryOptError(op) false
 
+static bool stack_binaryop(pk_VM* self, py_Name op, py_Name rop);
+
 #define DISPATCH()                                                                                 \
     do {                                                                                           \
         frame->ip++;                                                                               \
@@ -259,9 +261,10 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
                 py_Ref magic = py_tpfindmagic(SECOND()->type, __getitem__);
                 if(magic) {
                     if(magic->type == tp_nativefunc) {
-                        bool ok = magic->_cfunc(2, SECOND(), SECOND());
+                        bool ok = magic->_cfunc(2, SECOND());
                         if(!ok) goto __ERROR;
                         POP();
+                        *TOP() = self->last_retval;
                     } else {
                         INSERT_THIRD();     // [?, a, b]
                         *THIRD() = *magic;  // [__getitem__, a, b]
@@ -311,9 +314,10 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
                 py_Ref magic = py_tpfindmagic(SECOND()->type, __setitem__);
                 if(magic) {
                     if(magic->type == tp_nativefunc) {
-                        bool ok = magic->_cfunc(3, THIRD(), FOURTH());
+                        bool ok = magic->_cfunc(3, THIRD());
                         if(!ok) goto __ERROR;
-                        STACK_SHRINK(4);
+                        STACK_SHRINK(3);
+                        *TOP() = self->last_retval;
                     } else {
                         INSERT_THIRD();      // [?, a, b]
                         *FOURTH() = *magic;  // [__selitem__, a, b, val]
@@ -380,9 +384,10 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
                 py_Ref magic = py_tpfindmagic(SECOND()->type, __delitem__);
                 if(magic) {
                     if(magic->type == tp_nativefunc) {
-                        bool ok = magic->_cfunc(2, SECOND(), SECOND());
+                        bool ok = magic->_cfunc(2, SECOND());
                         if(!ok) goto __ERROR;
-                        STACK_SHRINK(2);
+                        POP();
+                        *TOP() = self->last_retval;
                     } else {
                         INSERT_THIRD();     // [?, a, b]
                         *THIRD() = *magic;  // [__delitem__, a, b]
@@ -492,67 +497,11 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
             /*****************************/
             case OP_BINARY_OP: {
                 py_Name op = byte.arg & 0xFF;
-                // [a, b]
-                py_Ref _0 = py_tpfindmagic(SECOND()->type, op);
-                py_Ref _1;
-                py_TValue tmp;
-                if(_0) {
-                    if(_0->type == tp_nativefunc) {
-                        bool ok = _0->_cfunc(2, SECOND(), &tmp);
-                        if(!ok) goto __ERROR;
-                        if(tmp.type != tp_not_implemented_type) {
-                            POP();
-                            *TOP() = tmp;
-                            DISPATCH();
-                        }
-                    } else {
-                        // standard call
-                        bool ok = py_call(_0, 2, SECOND());
-                        if(!ok) goto __ERROR;
-                        if(self->last_retval.type != tp_not_implemented_type) {
-                            POP();
-                            *TOP() = self->last_retval;
-                            DISPATCH();
-                        }
-                    }
-                }
-                // try reverse operation
-                op = byte.arg >> 8;
-                if(op) {
-                    // [a, b] -> [b, a]
-                    tmp = *TOP();
-                    *TOP() = *SECOND();
-                    *SECOND() = tmp;
-                    _1 = py_tpfindmagic(SECOND()->type, op);
-                    if(_1) {
-                        if(_1->type == tp_nativefunc) {
-                            bool ok = _1->_cfunc(2, SECOND(), &tmp);
-                            if(!ok) goto __ERROR;
-                            if(tmp.type != tp_not_implemented_type) {
-                                POP();
-                                *TOP() = tmp;
-                                DISPATCH();
-                            }
-                        } else {
-                            // standard call
-                            bool ok = py_call(_1, 2, SECOND());
-                            if(!ok) goto __ERROR;
-                            if(self->last_retval.type != tp_not_implemented_type) {
-                                POP();
-                                *TOP() = self->last_retval;
-                                DISPATCH();
-                            }
-                        }
-                    }
-                }
-                // eq/ne op never fails
-                if(op == __eq__ || op == __ne__) {
-                    POP();
-                    *TOP() = (op == __eq__) ? self->False : self->True;
-                    DISPATCH();
-                }
-                BinaryOptError(byte.arg);
-                goto __ERROR;
+                py_Name rop = byte.arg >> 8;
+                if(!stack_binaryop(self, op, rop)) goto __ERROR;
+                POP();
+                *TOP() = self->last_retval;
+                DISPATCH();
             }
             case OP_IS_OP: {
                 bool res = py_isidentical(SECOND(), TOP());
@@ -566,7 +515,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
                 py_Ref magic = py_tpfindmagic(SECOND()->type, __contains__);
                 if(magic) {
                     if(magic->type == tp_nativefunc) {
-                        bool ok = magic->_cfunc(2, SECOND(), SECOND());
+                        bool ok = magic->_cfunc(2, SECOND());
                         if(!ok) goto __ERROR;
                         POP();
                         *TOP() = self->last_retval;
@@ -667,29 +616,22 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
     return RES_RETURN;
 }
 
-bool py_binaryop(const py_Ref lhs, const py_Ref rhs, py_Name op, py_Name rop) {
-    pk_VM* self = pk_current_vm;
-    PUSH(lhs);
-    PUSH(rhs);
+/// Assumes [a, b] are on the stack, performs a binary op.
+/// The result is stored in `self->last_retval`.
+/// The stack remains unchanged.
+static bool stack_binaryop(pk_VM* self, py_Name op, py_Name rop) {
     // [a, b]
-    py_Ref _0 = py_tpfindmagic(SECOND()->type, op);
-    py_Ref _1;
-    if(_0) {
-        if(_0->type == tp_nativefunc) {
-            bool ok = _0->_cfunc(2, SECOND(), &self->last_retval);
+    py_Ref magic = py_tpfindmagic(SECOND()->type, op);
+    if(magic) {
+        if(magic->type == tp_nativefunc) {
+            bool ok = magic->_cfunc(2, SECOND());
             if(!ok) return false;
-            if(self->last_retval.type != tp_not_implemented_type) {
-                STACK_SHRINK(2);
-                return true;
-            }
+            if(self->last_retval.type != tp_not_implemented_type) return true;
         } else {
             // standard call
-            bool ok = py_call(_0, 2, SECOND());
+            bool ok = py_call(magic, 2, SECOND());
             if(!ok) return false;
-            if(self->last_retval.type != tp_not_implemented_type) {
-                STACK_SHRINK(2);
-                return true;
-            }
+            if(self->last_retval.type != tp_not_implemented_type) return true;
         }
     }
     // try reverse operation
@@ -698,31 +640,31 @@ bool py_binaryop(const py_Ref lhs, const py_Ref rhs, py_Name op, py_Name rop) {
         py_TValue tmp = *TOP();
         *TOP() = *SECOND();
         *SECOND() = tmp;
-        _1 = py_tpfindmagic(SECOND()->type, rop);
-        if(_1) {
-            if(_1->type == tp_nativefunc) {
-                bool ok = _1->_cfunc(2, SECOND(), &self->last_retval);
+        magic = py_tpfindmagic(SECOND()->type, rop);
+        if(magic) {
+            if(magic->type == tp_nativefunc) {
+                bool ok = magic->_cfunc(2, SECOND());
                 if(!ok) return false;
-                if(tmp.type != tp_not_implemented_type) {
-                    STACK_SHRINK(2);
-                    return true;
-                }
+                if(self->last_retval.type != tp_not_implemented_type) return true;
             } else {
                 // standard call
-                bool ok = py_call(_1, 2, SECOND());
+                bool ok = py_call(magic, 2, SECOND());
                 if(!ok) return false;
-                if(self->last_retval.type != tp_not_implemented_type) {
-                    STACK_SHRINK(2);
-                    return true;
-                }
+                if(self->last_retval.type != tp_not_implemented_type) return true;
             }
         }
     }
     // eq/ne op never fails
     if(op == __eq__ || op == __ne__) {
-        STACK_SHRINK(2);
         self->last_retval = (op == __eq__) ? self->False : self->True;
         return true;
     }
     return BinaryOptError(byte.arg);
 }
+
+bool py_binaryop(const py_Ref lhs, const py_Ref rhs, py_Name op, py_Name rop) {
+    pk_VM* self = pk_current_vm;
+    PUSH(lhs);
+    PUSH(rhs);
+    return stack_binaryop(self, op, rop);
+}

+ 35 - 35
src/interpreter/py_number.c

@@ -40,29 +40,29 @@
 // }
 
 #define DEF_NUM_BINARY_OP(name, op, rint, rfloat)                                                  \
-    static bool _py_int##name(int argc, py_Ref argv, py_Ref out) {                                 \
+    static bool _py_int##name(int argc, py_Ref argv) {                                             \
         py_checkargc(2);                                                                           \
         if(py_isint(&argv[1])) {                                                                   \
             int64_t lhs = py_toint(&argv[0]);                                                      \
             int64_t rhs = py_toint(&argv[1]);                                                      \
-            rint(out, lhs op rhs);                                                                 \
+            rint(py_lastretval(), lhs op rhs);                                                     \
         } else if(py_isfloat(&argv[1])) {                                                          \
             int64_t lhs = py_toint(&argv[0]);                                                      \
             double rhs = py_tofloat(&argv[1]);                                                     \
-            rfloat(out, lhs op rhs);                                                               \
+            rfloat(py_lastretval(), lhs op rhs);                                                   \
         } else {                                                                                   \
-            py_newnotimplemented(out);                                                             \
+            py_newnotimplemented(py_lastretval());                                                 \
         }                                                                                          \
         return true;                                                                               \
     }                                                                                              \
-    static bool _py_float##name(int argc, py_Ref argv, py_Ref out) {                               \
+    static bool _py_float##name(int argc, py_Ref argv) {                                           \
         py_checkargc(2);                                                                           \
         double lhs = py_tofloat(&argv[0]);                                                         \
         double rhs;                                                                                \
         if(py_castfloat(&argv[1], &rhs)) {                                                         \
-            rfloat(out, lhs op rhs);                                                               \
+            rfloat(py_lastretval(), lhs op rhs);                                                   \
         } else {                                                                                   \
-            py_newnotimplemented(out);                                                             \
+            py_newnotimplemented(py_lastretval());                                                 \
         }                                                                                          \
         return true;                                                                               \
     }
@@ -80,47 +80,47 @@ DEF_NUM_BINARY_OP(__ge__, >=, py_newbool, py_newbool)
 
 #undef DEF_NUM_BINARY_OP
 
-static bool _py_int__neg__(int argc, py_Ref argv, py_Ref out) {
+static bool _py_int__neg__(int argc, py_Ref argv) {
     py_checkargc(1);
     int64_t val = py_toint(&argv[0]);
-    py_newint(out, -val);
+    py_newint(py_lastretval(), -val);
     return true;
 }
 
-static bool _py_float__neg__(int argc, py_Ref argv, py_Ref out) {
+static bool _py_float__neg__(int argc, py_Ref argv) {
     py_checkargc(1);
     double val = py_tofloat(&argv[0]);
-    py_newfloat(out, -val);
+    py_newfloat(py_lastretval(), -val);
     return true;
 }
 
-static bool _py_int__truediv__(int argc, py_Ref argv, py_Ref out) {
+static bool _py_int__truediv__(int argc, py_Ref argv) {
     py_checkargc(2);
     int64_t lhs = py_toint(&argv[0]);
     double rhs;
     if(py_castfloat(&argv[1], &rhs)) {
-        py_newfloat(out, lhs / rhs);
+        py_newfloat(py_lastretval(), lhs / rhs);
     } else {
-        py_newnotimplemented(out);
+        py_newnotimplemented(py_lastretval());
     }
     return true;
 }
 
-static bool _py_float__truediv__(int argc, py_Ref argv, py_Ref out) {
+static bool _py_float__truediv__(int argc, py_Ref argv) {
     py_checkargc(2);
     double lhs = py_tofloat(&argv[0]);
     double rhs;
     if(py_castfloat(&argv[1], &rhs)) {
-        py_newfloat(out, lhs / rhs);
+        py_newfloat(py_lastretval(), lhs / rhs);
     } else {
-        py_newnotimplemented(out);
+        py_newnotimplemented(py_lastretval());
     }
     return true;
 }
 
 #define ZeroDivisionError(msg) false
 
-static bool _py_number__pow__(int argc, py_Ref argv, py_Ref out) {
+static bool _py_number__pow__(int argc, py_Ref argv) {
     py_checkargc(2);
     if(py_isint(&argv[0]) && py_isint(&argv[1])) {
         int64_t lhs = py_toint(&argv[0]);
@@ -129,7 +129,7 @@ static bool _py_number__pow__(int argc, py_Ref argv, py_Ref out) {
             if(lhs == 0) {
                 return ZeroDivisionError("0.0 cannot be raised to a negative power");
             } else {
-                py_newfloat(out, pow(lhs, rhs));
+                py_newfloat(py_lastretval(), pow(lhs, rhs));
             }
         } else {
             int64_t ret = 1;
@@ -138,54 +138,54 @@ static bool _py_number__pow__(int argc, py_Ref argv, py_Ref out) {
                 lhs *= lhs;
                 rhs >>= 1;
             }
-            py_newint(out, ret);
+            py_newint(py_lastretval(), ret);
         }
     } else {
         double lhs, rhs;
         py_castfloat(&argv[0], &lhs);
         if(py_castfloat(&argv[1], &rhs)) {
-            py_newfloat(out, pow(lhs, rhs));
+            py_newfloat(py_lastretval(), pow(lhs, rhs));
         } else {
-            py_newnotimplemented(out);
+            py_newnotimplemented(py_lastretval());
         }
     }
     return true;
 }
 
-static bool _py_int__floordiv__(int argc, py_Ref argv, py_Ref out) {
+static bool _py_int__floordiv__(int argc, py_Ref argv) {
     py_checkargc(2);
     int64_t lhs = py_toint(&argv[0]);
     if(py_isint(&argv[1])) {
         int64_t rhs = py_toint(&argv[1]);
         if(rhs == 0) return -1;
-        py_newint(out, lhs / rhs);
+        py_newint(py_lastretval(), lhs / rhs);
     } else {
-        py_newnotimplemented(out);
+        py_newnotimplemented(py_lastretval());
     }
     return true;
 }
 
-static bool _py_int__mod__(int argc, py_Ref argv, py_Ref out) {
+static bool _py_int__mod__(int argc, py_Ref argv) {
     py_checkargc(2);
     int64_t lhs = py_toint(&argv[0]);
     if(py_isint(&argv[1])) {
         int64_t rhs = py_toint(&argv[1]);
         if(rhs == 0) return ZeroDivisionError("integer division or modulo by zero");
-        py_newint(out, lhs % rhs);
+        py_newint(py_lastretval(), lhs % rhs);
     } else {
-        py_newnotimplemented(out);
+        py_newnotimplemented(py_lastretval());
     }
     return true;
 }
 
-static bool _py_int__invert__(int argc, py_Ref argv, py_Ref out) {
+static bool _py_int__invert__(int argc, py_Ref argv) {
     py_checkargc(1);
     int64_t val = py_toint(&argv[0]);
-    py_newint(out, ~val);
+    py_newint(py_lastretval(), ~val);
     return true;
 }
 
-static bool _py_int__bit_length(int argc, py_Ref argv, py_Ref out) {
+static bool _py_int__bit_length(int argc, py_Ref argv) {
     py_checkargc(1);
     int64_t x = py_toint(py_arg(0));
     if(x < 0) x = -x;
@@ -194,19 +194,19 @@ static bool _py_int__bit_length(int argc, py_Ref argv, py_Ref out) {
         x >>= 1;
         bits++;
     }
-    py_newint(out, bits);
+    py_newint(py_lastretval(), bits);
     return true;
 }
 
 #define DEF_INT_BITWISE_OP(name, op)                                                               \
-    static bool _py_int##name(int argc, py_Ref argv, py_Ref out) {                                 \
+    static bool _py_int##name(int argc, py_Ref argv) {                                             \
         py_checkargc(2);                                                                           \
         int64_t lhs = py_toint(&argv[0]);                                                          \
         if(py_isint(&argv[1])) {                                                                   \
             int64_t rhs = py_toint(&argv[1]);                                                      \
-            py_newint(out, lhs op rhs);                                                            \
+            py_newint(py_lastretval(), lhs op rhs);                                                \
         } else {                                                                                   \
-            py_newnotimplemented(out);                                                             \
+            py_newnotimplemented(py_lastretval());                                                 \
         }                                                                                          \
         return true;                                                                               \
     }

+ 1 - 1
src/public/vm.c

@@ -91,6 +91,6 @@ bool py_callmagic(py_Name name, int argc, py_Ref argv) {
     assert(argc >= 1);
     py_Ref tmp = py_tpfindmagic(argv->type, name);
     if(!tmp) return TypeError(name);
-    if(tmp->type == tp_nativefunc) { return tmp->_cfunc(argc, argv, &pk_current_vm->last_retval); }
+    if(tmp->type == tp_nativefunc) { return tmp->_cfunc(argc, argv); }
     return py_call(tmp, argc, argv);
 }