blueloveTH před 2 roky
rodič
revize
f60cd8a21e
2 změnil soubory, kde provedl 13 přidání a 6 odebrání
  1. 5 5
      src/compiler.h
  2. 8 1
      tests/99_bugs.py

+ 5 - 5
src/compiler.h

@@ -62,11 +62,11 @@ class Compiler {
         if(!ctx()->s_expr.empty()){
             throw std::runtime_error("!ctx()->s_expr.empty()\n" + ctx()->_log_s_expr());
         }
-        // if the last op does not return, add a default return None
-        if(ctx()->co->codes.empty() || ctx()->co->codes.back().op != OP_RETURN_VALUE){
-            ctx()->emit(OP_LOAD_NONE, BC_NOARG, BC_KEEPLINE);
-            ctx()->emit(OP_RETURN_VALUE, BC_NOARG, BC_KEEPLINE);
-        }
+        // add a `return None` in the end as a guard
+        // previously, we only do this if the last opcode is not a return
+        // however, this is buggy...since there may be a jump to the end (out of bound) even if the last opcode is a return
+        ctx()->emit(OP_LOAD_NONE, BC_NOARG, BC_KEEPLINE);
+        ctx()->emit(OP_RETURN_VALUE, BC_NOARG, BC_KEEPLINE);
         ctx()->co->optimize(vm);
         if(ctx()->co->varnames.size() > PK_MAX_CO_VARNAMES){
             SyntaxError("maximum number of local variables exceeded");

+ 8 - 1
tests/99_bugs.py

@@ -4,4 +4,11 @@ mp = map(lambda x:  x**2, [1, 2, 3, 4, 5]  )
 assert list(mp) == [1, 4, 9, 16, 25]
 
 
-assert not 3>4
+assert not 3>4
+
+def f(x):
+    if x>1:
+        return 1
+
+assert f(2) == 1
+assert f(0) == None