diff options
author | Mark Shannon <mark@hotpy.org> | 2023-06-14 15:15:08 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-14 15:15:08 (GMT) |
commit | 1d857da7f0e4858e561223f319ae5afe737d5657 (patch) | |
tree | ebfa22004b373a48769f42f002ed401248cdd3ea /Python/bytecodes.c | |
parent | 307bceaa65c4f1a8e110cd7a9cce6e93a1b021ba (diff) | |
download | cpython-1d857da7f0e4858e561223f319ae5afe737d5657.zip cpython-1d857da7f0e4858e561223f319ae5afe737d5657.tar.gz cpython-1d857da7f0e4858e561223f319ae5afe737d5657.tar.bz2 |
GH-77273: Better bytecodes for f-strings (GH-6132)
Diffstat (limited to 'Python/bytecodes.c')
-rw-r--r-- | Python/bytecodes.c | 54 |
1 files changed, 24 insertions, 30 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 78e276b..ddb43dd 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -52,6 +52,8 @@ #define family(name, ...) static int family_##name #define pseudo(name) static int pseudo_##name +typedef PyObject *(*convertion_func_ptr)(PyObject *); + // Dummy variables for stack effects. static PyObject *value, *value1, *value2, *left, *right, *res, *sum, *prod, *sub; static PyObject *container, *start, *stop, *v, *lhs, *rhs, *res2; @@ -3367,41 +3369,33 @@ dummy_func( ERROR_IF(slice == NULL, error); } - inst(FORMAT_VALUE, (value, fmt_spec if ((oparg & FVS_MASK) == FVS_HAVE_SPEC) -- result)) { - /* Handles f-string value formatting. */ - PyObject *(*conv_fn)(PyObject *); - int which_conversion = oparg & FVC_MASK; - - /* See if any conversion is specified. */ - switch (which_conversion) { - case FVC_NONE: conv_fn = NULL; break; - case FVC_STR: conv_fn = PyObject_Str; break; - case FVC_REPR: conv_fn = PyObject_Repr; break; - case FVC_ASCII: conv_fn = PyObject_ASCII; break; - default: - _PyErr_Format(tstate, PyExc_SystemError, - "unexpected conversion flag %d", - which_conversion); - goto error; - } + inst(CONVERT_VALUE, (value -- result)) { + convertion_func_ptr conv_fn; + assert(oparg >= FVC_STR && oparg <= FVC_ASCII); + conv_fn = CONVERSION_FUNCTIONS[oparg]; + result = conv_fn(value); + Py_DECREF(value); + ERROR_IF(result == NULL, error); + } - /* If there's a conversion function, call it and replace - value with that result. Otherwise, just use value, - without conversion. */ - if (conv_fn != NULL) { - result = conv_fn(value); + inst(FORMAT_SIMPLE, (value -- res)) { + /* If value is a unicode object, then we know the result + * of format(value) is value itself. */ + if (!PyUnicode_CheckExact(value)) { + res = PyObject_Format(value, NULL); Py_DECREF(value); - if (result == NULL) { - Py_XDECREF(fmt_spec); - ERROR_IF(true, error); - } - value = result; + ERROR_IF(res == NULL, error); } + else { + res = value; + } + } - result = PyObject_Format(value, fmt_spec); + inst(FORMAT_WITH_SPEC, (value, fmt_spec -- res)) { + res = PyObject_Format(value, fmt_spec); Py_DECREF(value); - Py_XDECREF(fmt_spec); - ERROR_IF(result == NULL, error); + Py_DECREF(fmt_spec); + ERROR_IF(res == NULL, error); } inst(COPY, (bottom, unused[oparg-1] -- bottom, unused[oparg-1], top)) { |