From 13a71998409fd5c916dcd9c9e3038e58c03a6740 Mon Sep 17 00:00:00 2001 From: "K. Lange" Date: Sun, 21 Mar 2021 13:02:50 +0900 Subject: [PATCH] Fully replace non-pop conditional jumps with popping versions --- src/chunk.h | 5 ++--- src/compiler.c | 42 +++++++++++++++--------------------------- src/opcodes.h | 5 ++--- src/vm.c | 9 ++------- 4 files changed, 21 insertions(+), 40 deletions(-) diff --git a/src/chunk.h b/src/chunk.h index e27a828..8692141 100644 --- a/src/chunk.h +++ b/src/chunk.h @@ -103,14 +103,13 @@ typedef enum { OP_MAKE_SET, OP_REVERSE, - OP_JUMP_IF_FALSE = 128, - OP_JUMP_IF_TRUE, + OP_JUMP_IF_FALSE_OR_POP = 128, + OP_JUMP_IF_TRUE_OR_POP, OP_JUMP, OP_LOOP, OP_PUSH_TRY, OP_PUSH_WITH, OP_YIELD_FROM, - OP_JUMP_IF_FALSE_OR_POP, OP_CALL_LONG = 192, OP_CLASS_LONG, diff --git a/src/compiler.c b/src/compiler.c index 24b247e..e37a5c3 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -1090,17 +1090,16 @@ static void function(FunctionType type, size_t blockWidth) { /* Check if it's equal to the unset-kwarg-sentinel value */ emitConstant(KWARGS_VAL(0)); emitByte(OP_IS); - int jumpIndex = emitJump(OP_JUMP_IF_FALSE); + int jumpIndex = emitJump(OP_JUMP_IF_FALSE_OR_POP); /* And if it is, set it to the appropriate type */ beginScope(); if (hasCollectors == 1) EMIT_CONSTANT_OP(OP_MAKE_LIST,0); else EMIT_CONSTANT_OP(OP_MAKE_DICT,0); EMIT_CONSTANT_OP(OP_SET_LOCAL, myLocal); - emitByte(OP_POP); /* local value */ endScope(); /* Otherwise pop the comparison. */ patchJump(jumpIndex); - emitByte(OP_POP); /* comparison value */ + emitByte(OP_POP); /* comparison value or expression */ continue; } if (hasCollectors) { @@ -1128,14 +1127,13 @@ static void function(FunctionType type, size_t blockWidth) { EMIT_CONSTANT_OP(OP_GET_LOCAL, myLocal); emitConstant(KWARGS_VAL(0)); emitByte(OP_EQUAL); - int jumpIndex = emitJump(OP_JUMP_IF_FALSE); + int jumpIndex = emitJump(OP_JUMP_IF_FALSE_OR_POP); beginScope(); expression(); /* Read expression */ EMIT_CONSTANT_OP(OP_SET_LOCAL, myLocal); - emitByte(OP_POP); /* local value */ endScope(); patchJump(jumpIndex); - emitByte(OP_POP); + emitByte(OP_POP); /* comparison result or expression value */ current->codeobject->keywordArgs++; } else { if (current->codeobject->keywordArgs) { @@ -1519,8 +1517,7 @@ static void ifStatement() { /* if EXPR: */ consume(TOKEN_COLON, "Expect ':' after condition."); - int thenJump = emitJump(OP_JUMP_IF_FALSE); - emitByte(OP_POP); + int thenJump = emitJump(OP_JUMP_IF_FALSE_OR_POP); /* Start a new scope and enter a block */ beginScope(); @@ -1606,8 +1603,7 @@ static void whileStatement() { expression(); consume(TOKEN_COLON, "Expect ':' after condition."); - int exitJump = emitJump(OP_JUMP_IF_FALSE); - emitByte(OP_POP); + int exitJump = emitJump(OP_JUMP_IF_FALSE_OR_POP); int oldLocalCount = current->loopLocalCount; current->loopLocalCount = current->localCount; @@ -1676,8 +1672,7 @@ static void forStatement() { /* Get the loop iterator again */ EMIT_CONSTANT_OP(OP_GET_LOCAL, indLoopIter); emitByte(OP_EQUAL); - exitJump = emitJump(OP_JUMP_IF_TRUE); - emitByte(OP_POP); + exitJump = emitJump(OP_JUMP_IF_TRUE_OR_POP); if (varCount > 1) { EMIT_CONSTANT_OP(OP_GET_LOCAL, loopInd); @@ -1695,8 +1690,7 @@ static void forStatement() { beginScope(); expression(); /* condition */ endScope(); - exitJump = emitJump(OP_JUMP_IF_FALSE); - emitByte(OP_POP); + exitJump = emitJump(OP_JUMP_IF_FALSE_OR_POP); if (check(TOKEN_SEMICOLON)) { advance(); @@ -1790,8 +1784,7 @@ _anotherExcept: emitByte(OP_NONE); } emitByte(OP_FILTER_EXCEPT); - nextJump = emitJump(OP_JUMP_IF_FALSE); - emitByte(OP_POP); + nextJump = emitJump(OP_JUMP_IF_FALSE_OR_POP); /* Match 'as' to rename exception */ if (match(TOKEN_AS)) { @@ -1961,7 +1954,7 @@ static void delStatement() { static void assertStatement() { expression(); - int elseJump = emitJump(OP_JUMP_IF_TRUE); + int elseJump = emitJump(OP_JUMP_IF_TRUE_OR_POP); KrkToken assertionError = syntheticToken("AssertionError"); size_t ind = identifierConstant(&assertionError); @@ -2418,8 +2411,7 @@ static void generatorInner(KrkScanner scannerBefore, Parser parserBefore, void ( EMIT_CONSTANT_OP(OP_GET_LOCAL, indLoopIter); emitByte(OP_EQUAL); - int exitJump = emitJump(OP_JUMP_IF_TRUE); - emitByte(OP_POP); + int exitJump = emitJump(OP_JUMP_IF_TRUE_OR_POP); if (varCount > 1) { EMIT_CONSTANT_OP(OP_GET_LOCAL, loopInd); @@ -2432,8 +2424,7 @@ static void generatorInner(KrkScanner scannerBefore, Parser parserBefore, void ( if (match(TOKEN_IF)) { parsePrecedence(PREC_OR); - int acceptJump = emitJump(OP_JUMP_IF_TRUE); - emitByte(OP_POP); /* Pop condition */ + int acceptJump = emitJump(OP_JUMP_IF_TRUE_OR_POP); emitLoop(loopStart); patchJump(acceptJump); emitByte(OP_POP); /* Pop condition */ @@ -2783,8 +2774,7 @@ static void actualTernary(size_t count, KrkScanner oldScanner, Parser oldParser) parsePrecedence(PREC_OR); - int thenJump = emitJump(OP_JUMP_IF_TRUE); - emitByte(OP_POP); /* Pop the condition */ + int thenJump = emitJump(OP_JUMP_IF_TRUE_OR_POP); consume(TOKEN_ELSE, "Expected 'else' after ternary condition"); parsePrecedence(PREC_TERNARY); @@ -3099,8 +3089,7 @@ static void call(int canAssign) { } static void and_(int canAssign) { - int endJump = emitJump(OP_JUMP_IF_FALSE); - emitByte(OP_POP); + int endJump = emitJump(OP_JUMP_IF_FALSE_OR_POP); parsePrecedence(PREC_AND); patchJump(endJump); } @@ -3110,8 +3099,7 @@ static void ternary(int canAssign) { } static void or_(int canAssign) { - int endJump = emitJump(OP_JUMP_IF_TRUE); - emitByte(OP_POP); + int endJump = emitJump(OP_JUMP_IF_TRUE_OR_POP); parsePrecedence(PREC_OR); patchJump(endJump); } diff --git a/src/opcodes.h b/src/opcodes.h index c6917a7..bd12e3b 100644 --- a/src/opcodes.h +++ b/src/opcodes.h @@ -74,11 +74,10 @@ OPERAND(OP_MAKE_LIST, (void)0) OPERAND(OP_MAKE_DICT, (void)0) OPERAND(OP_MAKE_SET, (void)0) OPERAND(OP_REVERSE, (void)0) +JUMP(OP_JUMP_IF_FALSE_OR_POP,+) +JUMP(OP_JUMP_IF_TRUE_OR_POP,+) JUMP(OP_JUMP,+) -JUMP(OP_JUMP_IF_FALSE,+) -JUMP(OP_JUMP_IF_TRUE,+) JUMP(OP_LOOP,-) JUMP(OP_PUSH_TRY,+) JUMP(OP_PUSH_WITH,+) JUMP(OP_YIELD_FROM,+) -JUMP(OP_JUMP_IF_FALSE_OR_POP,+) diff --git a/src/vm.c b/src/vm.c index 3fbd321..48138c3 100644 --- a/src/vm.c +++ b/src/vm.c @@ -2299,21 +2299,16 @@ _finishReturn: (void)0; /* * Two-byte operands */ - - case OP_JUMP_IF_FALSE: { - uint16_t offset = OPERAND; - if (krk_isFalsey(krk_peek(0))) frame->ip += offset; - break; - } case OP_JUMP_IF_FALSE_OR_POP: { uint16_t offset = OPERAND; if (krk_isFalsey(krk_peek(0))) frame->ip += offset; else krk_pop(); break; } - case OP_JUMP_IF_TRUE: { + case OP_JUMP_IF_TRUE_OR_POP: { uint16_t offset = OPERAND; if (!krk_isFalsey(krk_peek(0))) frame->ip += offset; + else krk_pop(); break; } case OP_JUMP: {