mirror of
https://github.com/python/cpython.git
synced 2025-08-03 16:39:00 +00:00
gh-98831: rewrite pattern matching opcodes in the instruction definition DSL (#101287)
This commit is contained in:
parent
f02fa64bf2
commit
1a9d8c750b
5 changed files with 64 additions and 73 deletions
|
@ -2092,61 +2092,37 @@ dummy_func(
|
|||
PUSH(len_o);
|
||||
}
|
||||
|
||||
// stack effect: (__0, __1 -- )
|
||||
inst(MATCH_CLASS) {
|
||||
inst(MATCH_CLASS, (subject, type, names -- attrs)) {
|
||||
// Pop TOS and TOS1. Set TOS to a tuple of attributes on success, or
|
||||
// None on failure.
|
||||
PyObject *names = POP();
|
||||
PyObject *type = POP();
|
||||
PyObject *subject = TOP();
|
||||
assert(PyTuple_CheckExact(names));
|
||||
PyObject *attrs = match_class(tstate, subject, type, oparg, names);
|
||||
Py_DECREF(names);
|
||||
Py_DECREF(type);
|
||||
attrs = match_class(tstate, subject, type, oparg, names);
|
||||
DECREF_INPUTS();
|
||||
if (attrs) {
|
||||
// Success!
|
||||
assert(PyTuple_CheckExact(attrs));
|
||||
SET_TOP(attrs);
|
||||
}
|
||||
else if (_PyErr_Occurred(tstate)) {
|
||||
// Error!
|
||||
goto error;
|
||||
assert(PyTuple_CheckExact(attrs)); // Success!
|
||||
}
|
||||
else {
|
||||
// Failure!
|
||||
SET_TOP(Py_NewRef(Py_None));
|
||||
ERROR_IF(_PyErr_Occurred(tstate), error); // Error!
|
||||
attrs = Py_NewRef(Py_None); // Failure!
|
||||
}
|
||||
Py_DECREF(subject);
|
||||
}
|
||||
|
||||
// stack effect: ( -- __0)
|
||||
inst(MATCH_MAPPING) {
|
||||
PyObject *subject = TOP();
|
||||
inst(MATCH_MAPPING, (subject -- subject, res)) {
|
||||
int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_MAPPING;
|
||||
PyObject *res = match ? Py_True : Py_False;
|
||||
PUSH(Py_NewRef(res));
|
||||
res = Py_NewRef(match ? Py_True : Py_False);
|
||||
PREDICT(POP_JUMP_IF_FALSE);
|
||||
}
|
||||
|
||||
// stack effect: ( -- __0)
|
||||
inst(MATCH_SEQUENCE) {
|
||||
PyObject *subject = TOP();
|
||||
inst(MATCH_SEQUENCE, (subject -- subject, res)) {
|
||||
int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_SEQUENCE;
|
||||
PyObject *res = match ? Py_True : Py_False;
|
||||
PUSH(Py_NewRef(res));
|
||||
res = Py_NewRef(match ? Py_True : Py_False);
|
||||
PREDICT(POP_JUMP_IF_FALSE);
|
||||
}
|
||||
|
||||
// stack effect: ( -- __0)
|
||||
inst(MATCH_KEYS) {
|
||||
inst(MATCH_KEYS, (subject, keys -- subject, keys, values_or_none)) {
|
||||
// On successful match, PUSH(values). Otherwise, PUSH(None).
|
||||
PyObject *keys = TOP();
|
||||
PyObject *subject = SECOND();
|
||||
PyObject *values_or_none = match_keys(tstate, subject, keys);
|
||||
if (values_or_none == NULL) {
|
||||
goto error;
|
||||
}
|
||||
PUSH(values_or_none);
|
||||
values_or_none = match_keys(tstate, subject, keys);
|
||||
ERROR_IF(values_or_none == NULL, error);
|
||||
}
|
||||
|
||||
// stack effect: ( -- )
|
||||
|
|
57
Python/generated_cases.c.h
generated
57
Python/generated_cases.c.h
generated
|
@ -2479,59 +2479,60 @@
|
|||
}
|
||||
|
||||
TARGET(MATCH_CLASS) {
|
||||
PyObject *names = PEEK(1);
|
||||
PyObject *type = PEEK(2);
|
||||
PyObject *subject = PEEK(3);
|
||||
PyObject *attrs;
|
||||
// Pop TOS and TOS1. Set TOS to a tuple of attributes on success, or
|
||||
// None on failure.
|
||||
PyObject *names = POP();
|
||||
PyObject *type = POP();
|
||||
PyObject *subject = TOP();
|
||||
assert(PyTuple_CheckExact(names));
|
||||
PyObject *attrs = match_class(tstate, subject, type, oparg, names);
|
||||
Py_DECREF(names);
|
||||
attrs = match_class(tstate, subject, type, oparg, names);
|
||||
Py_DECREF(subject);
|
||||
Py_DECREF(type);
|
||||
Py_DECREF(names);
|
||||
if (attrs) {
|
||||
// Success!
|
||||
assert(PyTuple_CheckExact(attrs));
|
||||
SET_TOP(attrs);
|
||||
}
|
||||
else if (_PyErr_Occurred(tstate)) {
|
||||
// Error!
|
||||
goto error;
|
||||
assert(PyTuple_CheckExact(attrs)); // Success!
|
||||
}
|
||||
else {
|
||||
// Failure!
|
||||
SET_TOP(Py_NewRef(Py_None));
|
||||
if (_PyErr_Occurred(tstate)) goto pop_3_error;
|
||||
attrs = Py_NewRef(Py_None); // Failure!
|
||||
}
|
||||
Py_DECREF(subject);
|
||||
STACK_SHRINK(2);
|
||||
POKE(1, attrs);
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(MATCH_MAPPING) {
|
||||
PyObject *subject = TOP();
|
||||
PyObject *subject = PEEK(1);
|
||||
PyObject *res;
|
||||
int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_MAPPING;
|
||||
PyObject *res = match ? Py_True : Py_False;
|
||||
PUSH(Py_NewRef(res));
|
||||
res = Py_NewRef(match ? Py_True : Py_False);
|
||||
STACK_GROW(1);
|
||||
POKE(1, res);
|
||||
PREDICT(POP_JUMP_IF_FALSE);
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(MATCH_SEQUENCE) {
|
||||
PyObject *subject = TOP();
|
||||
PyObject *subject = PEEK(1);
|
||||
PyObject *res;
|
||||
int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_SEQUENCE;
|
||||
PyObject *res = match ? Py_True : Py_False;
|
||||
PUSH(Py_NewRef(res));
|
||||
res = Py_NewRef(match ? Py_True : Py_False);
|
||||
STACK_GROW(1);
|
||||
POKE(1, res);
|
||||
PREDICT(POP_JUMP_IF_FALSE);
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(MATCH_KEYS) {
|
||||
PyObject *keys = PEEK(1);
|
||||
PyObject *subject = PEEK(2);
|
||||
PyObject *values_or_none;
|
||||
// On successful match, PUSH(values). Otherwise, PUSH(None).
|
||||
PyObject *keys = TOP();
|
||||
PyObject *subject = SECOND();
|
||||
PyObject *values_or_none = match_keys(tstate, subject, keys);
|
||||
if (values_or_none == NULL) {
|
||||
goto error;
|
||||
}
|
||||
PUSH(values_or_none);
|
||||
values_or_none = match_keys(tstate, subject, keys);
|
||||
if (values_or_none == NULL) goto error;
|
||||
STACK_GROW(1);
|
||||
POKE(1, values_or_none);
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
|
|
|
@ -133,10 +133,10 @@ static const struct {
|
|||
[JUMP_IF_TRUE_OR_POP] = { -1, -1, DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
|
||||
[JUMP_BACKWARD_NO_INTERRUPT] = { -1, -1, DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
|
||||
[GET_LEN] = { -1, -1, DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX },
|
||||
[MATCH_CLASS] = { -1, -1, DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
|
||||
[MATCH_MAPPING] = { -1, -1, DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX },
|
||||
[MATCH_SEQUENCE] = { -1, -1, DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX },
|
||||
[MATCH_KEYS] = { -1, -1, DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX },
|
||||
[MATCH_CLASS] = { 3, 1, DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
|
||||
[MATCH_MAPPING] = { 1, 2, DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX },
|
||||
[MATCH_SEQUENCE] = { 1, 2, DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX },
|
||||
[MATCH_KEYS] = { 2, 3, DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX },
|
||||
[GET_ITER] = { -1, -1, DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX },
|
||||
[GET_YIELD_FROM_ITER] = { -1, -1, DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX },
|
||||
[FOR_ITER] = { -1, -1, DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue