blueloveTH před 2 roky
rodič
revize
bccabaa872
8 změnil soubory, kde provedl 59 přidání a 60 odebrání
  1. 39 20
      src/ceval.h
  2. 4 6
      src/expr.h
  3. 2 0
      src/frame.h
  4. 0 4
      src/gc.h
  5. 6 1
      src/iter.h
  6. 0 5
      src/obj.h
  7. 2 1
      src/opcodes.h
  8. 6 23
      src/vm.h

+ 39 - 20
src/ceval.h

@@ -145,7 +145,9 @@ __NEXT_STEP:;
         PUSH(self);
         PUSH(self);
     } DISPATCH();
     } DISPATCH();
     TARGET(LOAD_SUBSCR) {
     TARGET(LOAD_SUBSCR) {
-        TOP() = fast_call_method(SECOND(), __getitem__, 2);
+        PyObject* b = POPX();
+        PyObject* a = TOP();
+        TOP() = call_method(a, __getitem__, b);
     } DISPATCH();
     } DISPATCH();
     TARGET(STORE_FAST)
     TARGET(STORE_FAST)
         frame->_locals[byte.arg] = POPX();
         frame->_locals[byte.arg] = POPX();
@@ -171,12 +173,13 @@ __NEXT_STEP:;
         setattr(a, name, val);
         setattr(a, name, val);
         STACK_SHRINK(2);
         STACK_SHRINK(2);
     } DISPATCH();
     } DISPATCH();
-    TARGET(STORE_SUBSCR)
-        // val a b -> a b val
-        std::swap(SECOND(), THIRD());
-        std::swap(TOP(), SECOND());
-        fast_call_method(THIRD(), __setitem__, 3);
-        DISPATCH();
+    TARGET(STORE_SUBSCR) {
+        // val a b
+        PyObject* b = POPX();
+        PyObject* a = POPX();
+        PyObject* val = POPX();
+        call_method(a, __setitem__, b, val);
+    } DISPATCH();
     TARGET(DELETE_FAST) {
     TARGET(DELETE_FAST) {
         PyObject* val = frame->_locals[byte.arg];
         PyObject* val = frame->_locals[byte.arg];
         if(val == nullptr) vm->NameError(co->varnames[byte.arg]);
         if(val == nullptr) vm->NameError(co->varnames[byte.arg]);
@@ -207,9 +210,11 @@ __NEXT_STEP:;
         if(!a->attr().contains(name)) AttributeError(a, name);
         if(!a->attr().contains(name)) AttributeError(a, name);
         a->attr().erase(name);
         a->attr().erase(name);
     } DISPATCH();
     } DISPATCH();
-    TARGET(DELETE_SUBSCR)
-        fast_call_method(SECOND(), __delitem__, 2);
-        DISPATCH();
+    TARGET(DELETE_SUBSCR) {
+        PyObject* b = POPX();
+        PyObject* a = POPX();
+        call_method(a, __delitem__, b);
+    } DISPATCH();
     /*****************************************/
     /*****************************************/
     TARGET(BUILD_LIST) {
     TARGET(BUILD_LIST) {
         PyObject* obj = VAR(STACK_VIEW(byte.arg).to_list());
         PyObject* obj = VAR(STACK_VIEW(byte.arg).to_list());
@@ -251,9 +256,11 @@ __NEXT_STEP:;
         PUSH(VAR(ss.str()));
         PUSH(VAR(ss.str()));
     } DISPATCH();
     } DISPATCH();
     /*****************************************/
     /*****************************************/
-    TARGET(BINARY_OP)
-        TOP() = fast_call_method(SECOND(), BINARY_SPECIAL_METHODS[byte.arg], 2);
-        DISPATCH();
+    TARGET(BINARY_OP) {
+        PyObject* b = POPX();
+        PyObject* a = TOP();
+        TOP() = call_method(a, BINARY_SPECIAL_METHODS[byte.arg], b);
+    } DISPATCH();
 
 
 #define INT_BINARY_OP(op, func)                             \
 #define INT_BINARY_OP(op, func)                             \
         if(is_both_int(TOP(), SECOND())){                   \
         if(is_both_int(TOP(), SECOND())){                   \
@@ -262,7 +269,9 @@ __NEXT_STEP:;
             POP();                                          \
             POP();                                          \
             TOP() = VAR(a op b);                            \
             TOP() = VAR(a op b);                            \
         }else{                                              \
         }else{                                              \
-            TOP() = fast_call_method(SECOND(), func, 2);    \
+            PyObject* b = POPX();                           \
+            PyObject* a = TOP();                            \
+            TOP() = call_method(a, func, b);                \
         }
         }
 
 
     TARGET(BINARY_ADD)
     TARGET(BINARY_ADD)
@@ -323,8 +332,7 @@ __NEXT_STEP:;
     } DISPATCH();
     } DISPATCH();
     TARGET(CONTAINS_OP) {
     TARGET(CONTAINS_OP) {
         // a in b -> b __contains__ a
         // a in b -> b __contains__ a
-        std::swap(TOP(), SECOND());
-        PyObject* ret = fast_call_method(SECOND(), __contains__, 2);
+        PyObject* ret = call_method(TOP(), __contains__, SECOND());
         bool ret_c = CAST(bool, ret);
         bool ret_c = CAST(bool, ret);
         if(byte.arg == 1) ret_c = !ret_c;
         if(byte.arg == 1) ret_c = !ret_c;
         TOP() = VAR(ret_c);
         TOP() = VAR(ret_c);
@@ -357,6 +365,9 @@ __NEXT_STEP:;
         frame->jump_abs_break(index);
         frame->jump_abs_break(index);
     } DISPATCH();
     } DISPATCH();
     /*****************************************/
     /*****************************************/
+    TARGET(BEGIN_CALL)
+        PUSH(_py_begin_call);
+        DISPATCH();
     TARGET(CALL) {
     TARGET(CALL) {
         int ARGC = byte.arg & 0xFFFF;
         int ARGC = byte.arg & 0xFFFF;
         int KWARGC = (byte.arg >> 16) & 0xFFFF;
         int KWARGC = (byte.arg >> 16) & 0xFFFF;
@@ -406,9 +417,6 @@ __NEXT_STEP:;
     TARGET(UNARY_NOT)
     TARGET(UNARY_NOT)
         TOP() = VAR(!asBool(TOP()));
         TOP() = VAR(!asBool(TOP()));
         DISPATCH();
         DISPATCH();
-    TARGET(UNARY_STAR)
-        TOP() = VAR(StarWrapper(TOP()));
-        DISPATCH();
     /*****************************************/
     /*****************************************/
     TARGET(GET_ITER)
     TARGET(GET_ITER)
         TOP() = asIter(TOP());
         TOP() = asIter(TOP());
@@ -479,7 +487,18 @@ __NEXT_STEP:;
         }else{
         }else{
             if(iter->next() != nullptr) ValueError("too many values to unpack");
             if(iter->next() != nullptr) ValueError("too many values to unpack");
         }
         }
-    }; DISPATCH();
+    } DISPATCH();
+    TARGET(UNPACK_UNLIMITED) {
+        auto _lock = heap.gc_scope_lock();  // lock the gc via RAII!!
+        PyObject* obj = asIter(POPX());
+        BaseIter* iter = PyIter_AS_C(obj);
+        obj = iter->next();
+        while(obj != nullptr){
+            PUSH(obj);
+            // if(s_data.is_overflow()) StackOverflowError();
+            obj = iter->next();
+        }
+    } DISPATCH();
     /*****************************************/
     /*****************************************/
     TARGET(BEGIN_CLASS) {
     TARGET(BEGIN_CLASS) {
         StrName name(byte.arg);
         StrName name(byte.arg);

+ 4 - 6
src/expr.h

@@ -189,7 +189,7 @@ struct StarredExpr: Expr{
 
 
     void emit(CodeEmitContext* ctx) override {
     void emit(CodeEmitContext* ctx) override {
         child->emit(ctx);
         child->emit(ctx);
-        ctx->emit(OP_UNARY_STAR, BC_NOARG, line);
+        ctx->emit(OP_UNPACK_UNLIMITED, BC_NOARG, line);
     }
     }
 
 
     bool emit_store(CodeEmitContext* ctx) override {
     bool emit_store(CodeEmitContext* ctx) override {
@@ -627,6 +627,7 @@ struct CallExpr: Expr{
 
 
     void emit(CodeEmitContext* ctx) override {
     void emit(CodeEmitContext* ctx) override {
         VM* vm = ctx->vm;
         VM* vm = ctx->vm;
+        if(need_unpack()) ctx->emit(OP_BEGIN_CALL, BC_NOARG, line);
         // if callable is a AttrExpr, we should try to use `fast_call` instead of use `boundmethod` proxy
         // if callable is a AttrExpr, we should try to use `fast_call` instead of use `boundmethod` proxy
         if(callable->is_attrib()){
         if(callable->is_attrib()){
             auto p = static_cast<AttribExpr*>(callable.get());
             auto p = static_cast<AttribExpr*>(callable.get());
@@ -645,11 +646,8 @@ struct CallExpr: Expr{
         }
         }
         int KWARGC = (int)kwargs.size();
         int KWARGC = (int)kwargs.size();
         int ARGC = (int)args.size();
         int ARGC = (int)args.size();
-        if(KWARGC > 0){
-            ctx->emit(need_unpack() ? OP_CALL_KWARGS_UNPACK : OP_CALL_KWARGS, (KWARGC<<16)|ARGC, line);
-        }else{
-            ctx->emit(need_unpack() ? OP_CALL_UNPACK : OP_CALL, ARGC, line);
-        }
+        if(need_unpack()) ARGC = 0xFFFF;
+        ctx->emit(OP_CALL, (KWARGC<<16)|ARGC, line);
     }
     }
 };
 };
 
 

+ 2 - 0
src/frame.h

@@ -212,6 +212,8 @@ struct Frame {
 
 
     int stack_size() const { return _s->_sp - _sp_base; }
     int stack_size() const { return _s->_sp - _sp_base; }
 
 
+    ArgsView stack_view() const { return ArgsView(_sp_base, _s->_sp); }
+
     std::string stack_info(){
     std::string stack_info(){
         std::stringstream ss;
         std::stringstream ss;
         ss << this << ": [";
         ss << this << ": [";

+ 0 - 4
src/gc.h

@@ -141,10 +141,6 @@ template<> inline void gc_mark<BoundMethod>(BoundMethod& t){
     OBJ_MARK(t.method);
     OBJ_MARK(t.method);
 }
 }
 
 
-template<> inline void gc_mark<StarWrapper>(StarWrapper& t){
-    OBJ_MARK(t.obj);
-}
-
 template<> inline void gc_mark<Super>(Super& t){
 template<> inline void gc_mark<Super>(Super& t){
     OBJ_MARK(t.first);
     OBJ_MARK(t.first);
 }
 }

+ 6 - 1
src/iter.h

@@ -63,10 +63,15 @@ public:
 
 
 inline PyObject* Generator::next(){
 inline PyObject* Generator::next(){
     if(state == 2) return nullptr;
     if(state == 2) return nullptr;
-    vm->_push_new_frame(std::move(frame));
+    // restore the context
+    for(PyObject* obj: s_data) frame._s->push(obj);
+    s_data.clear();
+    vm->callstack.push(std::move(frame));
     PyObject* ret = vm->_run_top_frame();
     PyObject* ret = vm->_run_top_frame();
     if(ret == vm->_py_op_yield){
     if(ret == vm->_py_op_yield){
+        // backup the context
         frame = std::move(vm->callstack.top());
         frame = std::move(vm->callstack.top());
+        for(PyObject* obj: frame.stack_view()) s_data.push_back(obj);
         vm->callstack.pop();
         vm->callstack.pop();
         state = 1;
         state = 1;
         return frame._s->popx();
         return frame._s->popx();

+ 0 - 5
src/obj.h

@@ -50,11 +50,6 @@ struct Range {
     i64 step = 1;
     i64 step = 1;
 };
 };
 
 
-struct StarWrapper {
-    PyObject* obj;
-    StarWrapper(PyObject* obj): obj(obj) {}
-};
-
 using Super = std::pair<PyObject*, Type>;
 using Super = std::pair<PyObject*, Type>;
 
 
 // TODO: re-examine the design of Slice
 // TODO: re-examine the design of Slice

+ 2 - 1
src/opcodes.h

@@ -76,6 +76,7 @@ OPCODE(LOOP_CONTINUE)
 OPCODE(LOOP_BREAK)
 OPCODE(LOOP_BREAK)
 OPCODE(GOTO)
 OPCODE(GOTO)
 /**************************/
 /**************************/
+OPCODE(BEGIN_CALL)
 OPCODE(CALL)
 OPCODE(CALL)
 OPCODE(RETURN_VALUE)
 OPCODE(RETURN_VALUE)
 OPCODE(YIELD_VALUE)
 OPCODE(YIELD_VALUE)
@@ -86,7 +87,6 @@ OPCODE(SET_ADD)
 /**************************/
 /**************************/
 OPCODE(UNARY_NEGATIVE)
 OPCODE(UNARY_NEGATIVE)
 OPCODE(UNARY_NOT)
 OPCODE(UNARY_NOT)
-OPCODE(UNARY_STAR)
 /**************************/
 /**************************/
 OPCODE(GET_ITER)
 OPCODE(GET_ITER)
 OPCODE(FOR_ITER)
 OPCODE(FOR_ITER)
@@ -96,6 +96,7 @@ OPCODE(IMPORT_STAR)
 /**************************/
 /**************************/
 OPCODE(UNPACK_SEQUENCE)
 OPCODE(UNPACK_SEQUENCE)
 OPCODE(UNPACK_EX)
 OPCODE(UNPACK_EX)
+OPCODE(UNPACK_UNLIMITED)
 /**************************/
 /**************************/
 OPCODE(BEGIN_CLASS)
 OPCODE(BEGIN_CLASS)
 OPCODE(END_CLASS)
 OPCODE(END_CLASS)

+ 6 - 23
src/vm.h

@@ -48,11 +48,10 @@ Str _read_file_cwd(const Str& name, bool* ok);
 
 
 class Generator final: public BaseIter {
 class Generator final: public BaseIter {
     Frame frame;
     Frame frame;
-    int state; // 0,1,2
+    int state;      // 0,1,2
+    List s_data;    // backup
 public:
 public:
-    template<typename... Args>
-    Generator(VM* vm, Frame&& frame)
-        : BaseIter(vm), frame(std::move(frame)), state(0) {}
+    Generator(VM* vm, Frame&& frame): BaseIter(vm), frame(std::move(frame)), state(0) {}
 
 
     PyObject* next() override;
     PyObject* next() override;
     void _gc_mark() const override;
     void _gc_mark() const override;
@@ -103,7 +102,7 @@ public:
     Type tp_list, tp_tuple;
     Type tp_list, tp_tuple;
     Type tp_function, tp_native_function, tp_iterator, tp_bound_method;
     Type tp_function, tp_native_function, tp_iterator, tp_bound_method;
     Type tp_slice, tp_range, tp_module;
     Type tp_slice, tp_range, tp_module;
-    Type tp_super, tp_exception, tp_star_wrapper;
+    Type tp_super, tp_exception;
 
 
     VM(bool use_stdio) : heap(this){
     VM(bool use_stdio) : heap(this){
         this->vm = this;
         this->vm = this;
@@ -167,20 +166,6 @@ public:
         return false;
         return false;
     }
     }
 
 
-    PyObject* fast_call_method(PyObject* obj, StrName name, int ARGC){
-        PyObject* callable = find_name_in_mro(_t(obj), name);
-        if(callable == nullptr) AttributeError(obj, name);
-        // [a, b]
-        // [......., a, b]
-        // [unbound, a, b]
-        //  ^^^^^^^
-        s_data._sp++;
-        PyObject** t = s_data._sp;
-        for(; t>s_data._sp-ARGC; t--) *t = t[-1];
-        *t = obj;
-        return _vectorcall(ARGC-1);
-    }
-
     PyObject* exec(Str source, Str filename, CompileMode mode, PyObject* _module=nullptr){
     PyObject* exec(Str source, Str filename, CompileMode mode, PyObject* _module=nullptr){
         if(_module == nullptr) _module = _main;
         if(_module == nullptr) _module = _main;
         try {
         try {
@@ -333,6 +318,7 @@ public:
     }
     }
 
 
     void RecursionError() { _error("RecursionError", "maximum recursion depth exceeded"); }
     void RecursionError() { _error("RecursionError", "maximum recursion depth exceeded"); }
+    void StackOverflowError() { _error("StackOverflowError", ""); }
     void IOError(const Str& msg) { _error("IOError", msg); }
     void IOError(const Str& msg) { _error("IOError", msg); }
     void NotImplementedError(){ _error("NotImplementedError", ""); }
     void NotImplementedError(){ _error("NotImplementedError", ""); }
     void TypeError(const Str& msg){ _error("TypeError", msg); }
     void TypeError(const Str& msg){ _error("TypeError", msg); }
@@ -417,7 +403,6 @@ DEF_NATIVE_2(BoundMethod, tp_bound_method)
 DEF_NATIVE_2(Range, tp_range)
 DEF_NATIVE_2(Range, tp_range)
 DEF_NATIVE_2(Slice, tp_slice)
 DEF_NATIVE_2(Slice, tp_slice)
 DEF_NATIVE_2(Exception, tp_exception)
 DEF_NATIVE_2(Exception, tp_exception)
-DEF_NATIVE_2(StarWrapper, tp_star_wrapper)
 
 
 #define PY_CAST_INT(T)                                  \
 #define PY_CAST_INT(T)                                  \
 template<> inline T py_cast<T>(VM* vm, PyObject* obj){  \
 template<> inline T py_cast<T>(VM* vm, PyObject* obj){  \
@@ -586,8 +571,7 @@ inline i64 VM::hash(PyObject* obj){
 }
 }
 
 
 inline PyObject* VM::asRepr(PyObject* obj){
 inline PyObject* VM::asRepr(PyObject* obj){
-    // TODO: fastcall does not take care of super() proxy!
-    return fast_call_method(obj, __repr__, 0);
+    return call_method(obj, __repr__);
 }
 }
 
 
 inline PyObject* VM::new_module(StrName name) {
 inline PyObject* VM::new_module(StrName name) {
@@ -682,7 +666,6 @@ inline void VM::init_builtin_types(){
     tp_slice = _new_type_object("slice");
     tp_slice = _new_type_object("slice");
     tp_range = _new_type_object("range");
     tp_range = _new_type_object("range");
     tp_module = _new_type_object("module");
     tp_module = _new_type_object("module");
-    tp_star_wrapper = _new_type_object("_star_wrapper");
     tp_function = _new_type_object("function");
     tp_function = _new_type_object("function");
     tp_native_function = _new_type_object("native_function");
     tp_native_function = _new_type_object("native_function");
     tp_iterator = _new_type_object("iterator");
     tp_iterator = _new_type_object("iterator");