Browse Source

add `OP_LOAD_SUBSCR_SMALL_INT`

blueloveTH 1 year ago
parent
commit
4665fb3405
4 changed files with 26 additions and 8 deletions
  1. 1 0
      include/pocketpy/opcodes.h
  2. 10 0
      src/ceval.cpp
  3. 14 7
      src/expr.cpp
  4. 1 1
      src/vm.cpp

+ 1 - 0
include/pocketpy/opcodes.h

@@ -29,6 +29,7 @@ OPCODE(LOAD_CLASS_GLOBAL)
 OPCODE(LOAD_METHOD)
 OPCODE(LOAD_METHOD)
 OPCODE(LOAD_SUBSCR)
 OPCODE(LOAD_SUBSCR)
 OPCODE(LOAD_SUBSCR_FAST)
 OPCODE(LOAD_SUBSCR_FAST)
+OPCODE(LOAD_SUBSCR_SMALL_INT)
 
 
 OPCODE(STORE_FAST)
 OPCODE(STORE_FAST)
 OPCODE(STORE_NAME)
 OPCODE(STORE_NAME)

+ 10 - 0
src/ceval.cpp

@@ -215,6 +215,16 @@ __NEXT_STEP:;
             TOP() = call_method(_0, __getitem__, _1);
             TOP() = call_method(_0, __getitem__, _1);
         }
         }
     } DISPATCH();
     } DISPATCH();
+    TARGET(LOAD_SUBSCR_SMALL_INT){
+        PyObject* _1 = (PyObject*)(uintptr_t)byte.arg;
+        PyObject* _0 = TOP();     // a
+        auto _ti = _inst_type_info(_0);
+        if(_ti->m__getitem__){
+            TOP() = _ti->m__getitem__(this, _0, _1);
+        }else{
+            TOP() = call_method(_0, __getitem__, _1);
+        }
+    } DISPATCH();
     TARGET(STORE_FAST)
     TARGET(STORE_FAST)
         frame->_locals[byte.arg] = POPX();
         frame->_locals[byte.arg] = POPX();
         DISPATCH();
         DISPATCH();

+ 14 - 7
src/expr.cpp

@@ -9,6 +9,10 @@ namespace pkpy{
         return true;
         return true;
     }
     }
 
 
+    inline bool is_small_int(i64 value){
+        return value >= 0 && value < 1024;
+    }
+
     int CodeEmitContext::get_loop() const {
     int CodeEmitContext::get_loop() const {
         int index = curr_block_i;
         int index = curr_block_i;
         while(index >= 0){
         while(index >= 0){
@@ -86,7 +90,7 @@ namespace pkpy{
     }
     }
 
 
     int CodeEmitContext::emit_int(i64 value, int line){
     int CodeEmitContext::emit_int(i64 value, int line){
-        if(value >= 0 && value < 1024){
+        if(is_small_int(value)){
             value = (value << 2) | 0b10;
             value = (value << 2) | 0b10;
             return emit_(OP_LOAD_SMALL_INT, (uint16_t)value, line);
             return emit_(OP_LOAD_SMALL_INT, (uint16_t)value, line);
         }else{
         }else{
@@ -536,10 +540,13 @@ namespace pkpy{
     void SubscrExpr::emit_(CodeEmitContext* ctx){
     void SubscrExpr::emit_(CodeEmitContext* ctx){
         a->emit_(ctx);
         a->emit_(ctx);
         b->emit_(ctx);
         b->emit_(ctx);
-        if(b->is_name() && ctx->co->codes.back().op == OP_LOAD_FAST){
-            auto arg = ctx->co->codes.back().arg;
+        Bytecode last_bc = ctx->co->codes.back();
+        if(b->is_name() && last_bc.op == OP_LOAD_FAST){
+            ctx->revert_last_emit_();
+            ctx->emit_(OP_LOAD_SUBSCR_FAST, last_bc.arg, line);
+        }else if(b->is_literal() && last_bc.op == OP_LOAD_SMALL_INT){
             ctx->revert_last_emit_();
             ctx->revert_last_emit_();
-            ctx->emit_(OP_LOAD_SUBSCR_FAST, arg, line);
+            ctx->emit_(OP_LOAD_SUBSCR_SMALL_INT, last_bc.arg, line);
         }else{
         }else{
             ctx->emit_(OP_LOAD_SUBSCR, BC_NOARG, line);
             ctx->emit_(OP_LOAD_SUBSCR, BC_NOARG, line);
         }
         }
@@ -548,10 +555,10 @@ namespace pkpy{
     bool SubscrExpr::emit_store(CodeEmitContext* ctx){
     bool SubscrExpr::emit_store(CodeEmitContext* ctx){
         a->emit_(ctx);
         a->emit_(ctx);
         b->emit_(ctx);
         b->emit_(ctx);
-        if(b->is_name() && ctx->co->codes.back().op == OP_LOAD_FAST){
-            auto arg = ctx->co->codes.back().arg;
+        Bytecode last_bc = ctx->co->codes.back();
+        if(b->is_name() && last_bc.op == OP_LOAD_FAST){
             ctx->revert_last_emit_();
             ctx->revert_last_emit_();
-            ctx->emit_(OP_STORE_SUBSCR_FAST, arg, line);
+            ctx->emit_(OP_STORE_SUBSCR_FAST, last_bc.arg, line);
         }else{
         }else{
             ctx->emit_(OP_STORE_SUBSCR, BC_NOARG, line);
             ctx->emit_(OP_STORE_SUBSCR, BC_NOARG, line);
         }
         }

+ 1 - 1
src/vm.cpp

@@ -584,7 +584,7 @@ static std::string _opcode_argstr(VM* vm, Bytecode byte, const CodeObject* co){
         case OP_LOAD_FUNCTION:
         case OP_LOAD_FUNCTION:
             argStr += _S(" (", co->func_decls[byte.arg]->code->name, ")").sv();
             argStr += _S(" (", co->func_decls[byte.arg]->code->name, ")").sv();
             break;
             break;
-        case OP_LOAD_SMALL_INT:
+        case OP_LOAD_SMALL_INT: case OP_LOAD_SUBSCR_SMALL_INT:
             argStr += _S(" (", (int)(byte.arg >> 2), ")").sv();
             argStr += _S(" (", (int)(byte.arg >> 2), ")").sv();
     }
     }
     return argStr;
     return argStr;