diff options
author | Guido van Rossum <guido@python.org> | 2023-02-08 01:35:55 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-02-08 01:35:55 (GMT) |
commit | b2b85b5db9cfdb24f966b61757536a898abc3830 (patch) | |
tree | b5f09e352132a15f5e782e75ce6205b3da0552b1 | |
parent | aacbdb0c650492756738b044e6ddf8b72f89a1a2 (diff) | |
download | cpython-b2b85b5db9cfdb24f966b61757536a898abc3830.zip cpython-b2b85b5db9cfdb24f966b61757536a898abc3830.tar.gz cpython-b2b85b5db9cfdb24f966b61757536a898abc3830.tar.bz2 |
gh-98831: Modernize FORMAT_VALUE (#101628)
Generator update: support balanced parentheses and brackets in conditions and size expressions.
-rw-r--r-- | Python/bytecodes.c | 18 | ||||
-rw-r--r-- | Python/generated_cases.c.h | 20 | ||||
-rw-r--r-- | Python/opcode_metadata.h | 4 | ||||
-rw-r--r-- | Tools/cases_generator/parser.py | 9 | ||||
-rw-r--r-- | Tools/cases_generator/test_generator.py | 8 |
5 files changed, 24 insertions, 35 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c index c6c00a7..d0f0513 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -3054,18 +3054,10 @@ dummy_func( ERROR_IF(slice == NULL, error); } - // error: FORMAT_VALUE has irregular stack effect - inst(FORMAT_VALUE) { + inst(FORMAT_VALUE, (value, fmt_spec if ((oparg & FVS_MASK) == FVS_HAVE_SPEC) -- result)) { /* Handles f-string value formatting. */ - PyObject *result; - PyObject *fmt_spec; - PyObject *value; PyObject *(*conv_fn)(PyObject *); int which_conversion = oparg & FVC_MASK; - int have_fmt_spec = (oparg & FVS_MASK) == FVS_HAVE_SPEC; - - fmt_spec = have_fmt_spec ? POP() : NULL; - value = POP(); /* See if any conversion is specified. */ switch (which_conversion) { @@ -3088,7 +3080,7 @@ dummy_func( Py_DECREF(value); if (result == NULL) { Py_XDECREF(fmt_spec); - goto error; + ERROR_IF(true, error); } value = result; } @@ -3106,12 +3098,8 @@ dummy_func( result = PyObject_Format(value, fmt_spec); Py_DECREF(value); Py_XDECREF(fmt_spec); - if (result == NULL) { - goto error; - } + ERROR_IF(result == NULL, error); } - - PUSH(result); } inst(COPY, (bottom, unused[oparg-1] -- bottom, unused[oparg-1], top)) { diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index ded68d0..3ef8086 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -3703,16 +3703,12 @@ } TARGET(FORMAT_VALUE) { - /* Handles f-string value formatting. */ + PyObject *fmt_spec = ((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? PEEK((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0)) : NULL; + PyObject *value = PEEK(1 + (((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0)); PyObject *result; - PyObject *fmt_spec; - PyObject *value; + /* Handles f-string value formatting. */ PyObject *(*conv_fn)(PyObject *); int which_conversion = oparg & FVC_MASK; - int have_fmt_spec = (oparg & FVS_MASK) == FVS_HAVE_SPEC; - - fmt_spec = have_fmt_spec ? POP() : NULL; - value = POP(); /* See if any conversion is specified. */ switch (which_conversion) { @@ -3735,7 +3731,7 @@ Py_DECREF(value); if (result == NULL) { Py_XDECREF(fmt_spec); - goto error; + if (true) { STACK_SHRINK((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0)); goto pop_1_error; } } value = result; } @@ -3753,12 +3749,10 @@ result = PyObject_Format(value, fmt_spec); Py_DECREF(value); Py_XDECREF(fmt_spec); - if (result == NULL) { - goto error; - } + if (result == NULL) { STACK_SHRINK((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0)); goto pop_1_error; } } - - PUSH(result); + STACK_SHRINK((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0)); + POKE(1, result); DISPATCH(); } diff --git a/Python/opcode_metadata.h b/Python/opcode_metadata.h index c1e12a4..52bab1c 100644 --- a/Python/opcode_metadata.h +++ b/Python/opcode_metadata.h @@ -333,7 +333,7 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) { case BUILD_SLICE: return ((oparg == 3) ? 1 : 0) + 2; case FORMAT_VALUE: - return -1; + return (((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0) + 1; case COPY: return (oparg-1) + 1; case BINARY_OP: @@ -681,7 +681,7 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { case BUILD_SLICE: return 1; case FORMAT_VALUE: - return -1; + return 1; case COPY: return (oparg-1) + 2; case BINARY_OP: diff --git a/Tools/cases_generator/parser.py b/Tools/cases_generator/parser.py index ced66fa..c7c8d8a 100644 --- a/Tools/cases_generator/parser.py +++ b/Tools/cases_generator/parser.py @@ -263,7 +263,14 @@ class Parser(PLexer): @contextual def expression(self) -> Expression | None: tokens: list[lx.Token] = [] - while (tkn := self.peek()) and tkn.kind not in (lx.RBRACKET, lx.RPAREN): + level = 1 + while tkn := self.peek(): + if tkn.kind in (lx.LBRACKET, lx.LPAREN): + level += 1 + elif tkn.kind in (lx.RBRACKET, lx.RPAREN): + level -= 1 + if level == 0: + break tokens.append(tkn) self.next() if not tokens: diff --git a/Tools/cases_generator/test_generator.py b/Tools/cases_generator/test_generator.py index 0c3d04b..33bba7e 100644 --- a/Tools/cases_generator/test_generator.py +++ b/Tools/cases_generator/test_generator.py @@ -500,20 +500,20 @@ def test_register(): def test_cond_effect(): input = """ - inst(OP, (aa, input if (oparg & 1), cc -- xx, output if (oparg & 2), zz)) { + inst(OP, (aa, input if ((oparg & 1) == 1), cc -- xx, output if (oparg & 2), zz)) { output = spam(oparg, input); } """ output = """ TARGET(OP) { PyObject *cc = PEEK(1); - PyObject *input = (oparg & 1) ? PEEK(1 + ((oparg & 1) ? 1 : 0)) : NULL; - PyObject *aa = PEEK(2 + ((oparg & 1) ? 1 : 0)); + PyObject *input = ((oparg & 1) == 1) ? PEEK(1 + (((oparg & 1) == 1) ? 1 : 0)) : NULL; + PyObject *aa = PEEK(2 + (((oparg & 1) == 1) ? 1 : 0)); PyObject *xx; PyObject *output = NULL; PyObject *zz; output = spam(oparg, input); - STACK_SHRINK(((oparg & 1) ? 1 : 0)); + STACK_SHRINK((((oparg & 1) == 1) ? 1 : 0)); STACK_GROW(((oparg & 2) ? 1 : 0)); POKE(1, zz); if (oparg & 2) { POKE(1 + ((oparg & 2) ? 1 : 0), output); } |