blueloveTH 3 лет назад
Родитель
Сommit
f4248e25b1
3 измененных файлов с 35 добавлено и 16 удалено
  1. 22 4
      src/ceval.h
  2. 10 12
      src/compiler.h
  3. 3 0
      src/opcodes.h

+ 22 - 4
src/ceval.h

@@ -128,10 +128,28 @@ PyVar VM::run_frame(Frame* frame){
             } break;
         case OP_BITWISE_OP:
             {
-                frame->push(
-                    fast_call(BITWISE_SPECIAL_METHODS[byte.arg],
-                    frame->pop_n_values_reversed(this, 2))
-                );
+                pkpy::Args args(2);
+                args[1] = frame->pop_value(this);
+                args[0] = frame->top_value(this);
+                frame->top() = fast_call(BITWISE_SPECIAL_METHODS[byte.arg], std::move(args));
+            } break;
+        case OP_INPLACE_BINARY_OP:
+            {
+                pkpy::Args args(2);
+                args[1] = frame->pop_value(this);
+                args[0] = frame->top_value(this);
+                PyVar ret = fast_call(BINARY_SPECIAL_METHODS[byte.arg], std::move(args));
+                PyRef_AS_C(frame->top())->set(this, frame, std::move(ret));
+                frame->_pop();
+            } break;
+        case OP_INPLACE_BITWISE_OP:
+            {
+                pkpy::Args args(2);
+                args[1] = frame->pop_value(this);
+                args[0] = frame->top_value(this);
+                PyVar ret = fast_call(BITWISE_SPECIAL_METHODS[byte.arg], std::move(args));
+                PyRef_AS_C(frame->top())->set(this, frame, std::move(ret));
+                frame->_pop();
             } break;
         case OP_COMPARE_OP:
             {

+ 10 - 12
src/compiler.h

@@ -406,21 +406,19 @@ private:
             EXPR_TUPLE();
             emit(OP_STORE_REF);
         }else{                  // a += (expr) -> a = a + (expr)
-            emit(OP_DUP_TOP_VALUE);
             EXPR();
             switch (op) {
-                case TK("+="):      emit(OP_BINARY_OP, 0);  break;
-                case TK("-="):      emit(OP_BINARY_OP, 1);  break;
-                case TK("*="):      emit(OP_BINARY_OP, 2);  break;
-                case TK("/="):      emit(OP_BINARY_OP, 3);  break;
-                case TK("//="):     emit(OP_BINARY_OP, 4);  break;
-                case TK("%="):      emit(OP_BINARY_OP, 5);  break;
-                case TK("&="):      emit(OP_BITWISE_OP, 2);  break;
-                case TK("|="):      emit(OP_BITWISE_OP, 3);  break;
-                case TK("^="):      emit(OP_BITWISE_OP, 4);  break;
+                case TK("+="):      emit(OP_INPLACE_BINARY_OP, 0);  break;
+                case TK("-="):      emit(OP_INPLACE_BINARY_OP, 1);  break;
+                case TK("*="):      emit(OP_INPLACE_BINARY_OP, 2);  break;
+                case TK("/="):      emit(OP_INPLACE_BINARY_OP, 3);  break;
+                case TK("//="):     emit(OP_INPLACE_BINARY_OP, 4);  break;
+                case TK("%="):      emit(OP_INPLACE_BINARY_OP, 5);  break;
+                case TK("&="):      emit(OP_INPLACE_BITWISE_OP, 2);  break;
+                case TK("|="):      emit(OP_INPLACE_BITWISE_OP, 3);  break;
+                case TK("^="):      emit(OP_INPLACE_BITWISE_OP, 4);  break;
                 default: UNREACHABLE();
             }
-            emit(OP_STORE_REF);
         }
         co()->_rvalue = false;
     }
@@ -939,7 +937,7 @@ __LISTCOMP:
             consume_end_stmt();
             // If last op is not an assignment, pop the result.
             uint8_t last_op = co()->codes.back().op;
-            if( last_op!=OP_STORE_NAME && last_op!=OP_STORE_REF){
+            if( last_op!=OP_STORE_NAME && last_op!=OP_STORE_REF && last_op!=OP_INPLACE_BINARY_OP && last_op!=OP_INPLACE_BITWISE_OP){
                 if(mode()==REPL_MODE && parser->indents.top()==0) emit(OP_PRINT_EXPR, -1, true);
                 emit(OP_POP_TOP, -1, true);
             }

+ 3 - 0
src/opcodes.h

@@ -73,4 +73,7 @@ OPCODE(YIELD_VALUE)
 OPCODE(FAST_INDEX)      // a[x]
 OPCODE(FAST_INDEX_REF)       // a[x]
 
+OPCODE(INPLACE_BINARY_OP)
+OPCODE(INPLACE_BITWISE_OP)
+
 #endif