From f60cd8a21e5e4354c1ee5059eab3823425c789d9 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Wed, 3 May 2023 16:09:37 +0800 Subject: [PATCH] fix a bug --- src/compiler.h | 10 +++++----- tests/99_bugs.py | 9 ++++++++- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/compiler.h b/src/compiler.h index f1928a6b..8a98486b 100644 --- a/src/compiler.h +++ b/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"); diff --git a/tests/99_bugs.py b/tests/99_bugs.py index 9332374c..4c1eda34 100644 --- a/tests/99_bugs.py +++ b/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 \ No newline at end of file +assert not 3>4 + +def f(x): + if x>1: + return 1 + +assert f(2) == 1 +assert f(0) == None \ No newline at end of file