aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Python/bytecodes.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2022-11-22 16:04:57 -0800
committerGitHub <noreply@github.com>2022-11-22 16:04:57 -0800
commit8f18ac04d32515eab841172c956a8cb14bcee9c3 (patch)
treeb2c54230bb6a336b40e18c42c0e3cc5f1da41e24 /Python/bytecodes.c
parentf1a4a6a58736196f766d51f048d19a2b0a0a155a (diff)
downloadcpython-8f18ac04d32515eab841172c956a8cb14bcee9c3.tar.gz
cpython-8f18ac04d32515eab841172c956a8cb14bcee9c3.zip
GH-98831: Add `macro` and `op` and their implementation to DSL (#99495)
Newly supported interpreter definition syntax: - `op(NAME, (input_stack_effects -- output_stack_effects)) { ... }` - `macro(NAME) = OP1 + OP2;` Also some other random improvements: - Convert `WITH_EXCEPT_START` to use stack effects - Fix lexer to balk at unrecognized characters, e.g. `@` - Fix moved output names; support object pointers in cache - Introduce `error()` method to print errors - Introduce read_uint16(p) as equivalent to `*p` Co-authored-by: Brandt Bucher <brandtbucher@gmail.com>
Diffstat (limited to 'Python/bytecodes.c')
-rw-r--r--Python/bytecodes.c32
1 files changed, 13 insertions, 19 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index 78f7d4ac061..a1f910da8ed 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -70,6 +70,8 @@ do { \
#define DISPATCH_SAME_OPARG() ((void)0)
#define inst(name, ...) case name:
+#define op(name, ...) /* NAME is ignored */
+#define macro(name) static int MACRO_##name
#define super(name) static int SUPER_##name
#define family(name, ...) static int family_##name
@@ -80,6 +82,7 @@ do { \
static PyObject *value, *value1, *value2, *left, *right, *res, *sum, *prod, *sub;
static PyObject *container, *start, *stop, *v, *lhs, *rhs;
static PyObject *list, *tuple, *dict;
+static PyObject *exit_func, *lasti, *val;
static PyObject *
dummy_func(
@@ -156,10 +159,7 @@ dummy_func(
res = NULL;
}
- inst(END_FOR, (value1, value2 --)) {
- Py_DECREF(value1);
- Py_DECREF(value2);
- }
+ macro(END_FOR) = POP_TOP + POP_TOP;
inst(UNARY_POSITIVE, (value -- res)) {
res = PyNumber_Positive(value);
@@ -2725,33 +2725,27 @@ dummy_func(
PUSH(res);
}
- // stack effect: ( -- __0)
- inst(WITH_EXCEPT_START) {
+ inst(WITH_EXCEPT_START, (exit_func, lasti, unused, val -- exit_func, lasti, unused, val, res)) {
/* At the top of the stack are 4 values:
- - TOP = exc_info()
- - SECOND = previous exception
- - THIRD: lasti of exception in exc_info()
- - FOURTH: the context.__exit__ bound method
+ - val: TOP = exc_info()
+ - unused: SECOND = previous exception
+ - lasti: THIRD = lasti of exception in exc_info()
+ - exit_func: FOURTH = the context.__exit__ bound method
We call FOURTH(type(TOP), TOP, GetTraceback(TOP)).
Then we push the __exit__ return value.
*/
- PyObject *exit_func;
- PyObject *exc, *val, *tb, *res;
+ PyObject *exc, *tb;
- val = TOP();
assert(val && PyExceptionInstance_Check(val));
exc = PyExceptionInstance_Class(val);
tb = PyException_GetTraceback(val);
Py_XDECREF(tb);
- assert(PyLong_Check(PEEK(3)));
- exit_func = PEEK(4);
+ assert(PyLong_Check(lasti));
+ (void)lasti; // Shut up compiler warning if asserts are off
PyObject *stack[4] = {NULL, exc, val, tb};
res = PyObject_Vectorcall(exit_func, stack + 1,
3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
- if (res == NULL)
- goto error;
-
- PUSH(res);
+ ERROR_IF(res == NULL, error);
}
// stack effect: ( -- __0)