mirror of
https://github.com/python/cpython
synced 2026-09-29 12:10:30 +03:00
bpo-44511: Improve the bytecode for class and mapping patterns (GH-26922)
* Refactor mapping patterns and speed up class patterns. * Simplify MATCH_KEYS and MATCH_CLASS. * Add COPY opcode.
This commit is contained in:
parent
19a6c41e56
commit
82a662e521
10 changed files with 130 additions and 116 deletions
|
|
@ -4143,25 +4143,30 @@ check_eval_breaker:
|
|||
}
|
||||
|
||||
TARGET(MATCH_CLASS) {
|
||||
// Pop TOS. On success, set TOS to True and TOS1 to a tuple of
|
||||
// attributes. On failure, set TOS to False.
|
||||
// Pop TOS and TOS1. Set TOS to a tuple of attributes on success, or
|
||||
// None on failure.
|
||||
PyObject *names = POP();
|
||||
PyObject *type = TOP();
|
||||
PyObject *subject = SECOND();
|
||||
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);
|
||||
if (attrs) {
|
||||
// Success!
|
||||
assert(PyTuple_CheckExact(attrs));
|
||||
Py_DECREF(subject);
|
||||
SET_SECOND(attrs);
|
||||
SET_TOP(attrs);
|
||||
}
|
||||
else if (_PyErr_Occurred(tstate)) {
|
||||
// Error!
|
||||
goto error;
|
||||
}
|
||||
Py_DECREF(type);
|
||||
SET_TOP(PyBool_FromLong(!!attrs));
|
||||
else {
|
||||
// Failure!
|
||||
Py_INCREF(Py_None);
|
||||
SET_TOP(Py_None);
|
||||
}
|
||||
Py_DECREF(subject);
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
|
|
@ -4171,6 +4176,7 @@ check_eval_breaker:
|
|||
PyObject *res = match ? Py_True : Py_False;
|
||||
Py_INCREF(res);
|
||||
PUSH(res);
|
||||
PREDICT(POP_JUMP_IF_FALSE);
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
|
|
@ -4180,12 +4186,12 @@ check_eval_breaker:
|
|||
PyObject *res = match ? Py_True : Py_False;
|
||||
Py_INCREF(res);
|
||||
PUSH(res);
|
||||
PREDICT(POP_JUMP_IF_FALSE);
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(MATCH_KEYS) {
|
||||
// On successful match for all keys, PUSH(values) and PUSH(True).
|
||||
// Otherwise, PUSH(None) and PUSH(False).
|
||||
// On successful match, PUSH(values). Otherwise, PUSH(None).
|
||||
PyObject *keys = TOP();
|
||||
PyObject *subject = SECOND();
|
||||
PyObject *values_or_none = match_keys(tstate, subject, keys);
|
||||
|
|
@ -4193,40 +4199,6 @@ check_eval_breaker:
|
|||
goto error;
|
||||
}
|
||||
PUSH(values_or_none);
|
||||
if (Py_IsNone(values_or_none)) {
|
||||
Py_INCREF(Py_False);
|
||||
PUSH(Py_False);
|
||||
DISPATCH();
|
||||
}
|
||||
assert(PyTuple_CheckExact(values_or_none));
|
||||
Py_INCREF(Py_True);
|
||||
PUSH(Py_True);
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(COPY_DICT_WITHOUT_KEYS) {
|
||||
// rest = dict(TOS1)
|
||||
// for key in TOS:
|
||||
// del rest[key]
|
||||
// SET_TOP(rest)
|
||||
PyObject *keys = TOP();
|
||||
PyObject *subject = SECOND();
|
||||
PyObject *rest = PyDict_New();
|
||||
if (rest == NULL || PyDict_Update(rest, subject)) {
|
||||
Py_XDECREF(rest);
|
||||
goto error;
|
||||
}
|
||||
// This may seem a bit inefficient, but keys is rarely big enough to
|
||||
// actually impact runtime.
|
||||
assert(PyTuple_CheckExact(keys));
|
||||
for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(keys); i++) {
|
||||
if (PyDict_DelItem(rest, PyTuple_GET_ITEM(keys, i))) {
|
||||
Py_DECREF(rest);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
Py_DECREF(keys);
|
||||
SET_TOP(rest);
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
|
|
@ -5027,6 +4999,14 @@ check_eval_breaker:
|
|||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(COPY) {
|
||||
assert(oparg != 0);
|
||||
PyObject *peek = PEEK(oparg);
|
||||
Py_INCREF(peek);
|
||||
PUSH(peek);
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(EXTENDED_ARG) {
|
||||
int oldoparg = oparg;
|
||||
NEXTOPARG();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue