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:
Brandt Bucher 2021-10-27 02:45:35 -07:00 committed by GitHub
parent 19a6c41e56
commit 82a662e521
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 130 additions and 116 deletions

View File

@ -755,15 +755,6 @@ iterations of the loop.
.. versionadded:: 3.11 .. versionadded:: 3.11
.. opcode:: COPY_DICT_WITHOUT_KEYS
TOS is a tuple of mapping keys, and TOS1 is the match subject. Replace TOS
with a :class:`dict` formed from the items of TOS1, but without any of the
keys in TOS.
.. versionadded:: 3.10
.. opcode:: GET_LEN .. opcode:: GET_LEN
Push ``len(TOS)`` onto the stack. Push ``len(TOS)`` onto the stack.
@ -795,11 +786,14 @@ iterations of the loop.
TOS is a tuple of mapping keys, and TOS1 is the match subject. If TOS1 TOS is a tuple of mapping keys, and TOS1 is the match subject. If TOS1
contains all of the keys in TOS, push a :class:`tuple` containing the contains all of the keys in TOS, push a :class:`tuple` containing the
corresponding values, followed by ``True``. Otherwise, push ``None``, corresponding values. Otherwise, push ``None``.
followed by ``False``.
.. versionadded:: 3.10 .. versionadded:: 3.10
.. versionchanged:: 3.11
Previously, this instruction also pushed a boolean value indicating
success (``True``) or failure (``False``).
All of the following opcodes use their arguments. All of the following opcodes use their arguments.
@ -1277,12 +1271,16 @@ All of the following opcodes use their arguments.
against, and TOS2 is the match subject. *count* is the number of positional against, and TOS2 is the match subject. *count* is the number of positional
sub-patterns. sub-patterns.
Pop TOS. If TOS2 is an instance of TOS1 and has the positional and keyword Pop TOS, TOS1, and TOS2. If TOS2 is an instance of TOS1 and has the
attributes required by *count* and TOS, set TOS to ``True`` and TOS1 to a positional and keyword attributes required by *count* and TOS, push a tuple
tuple of extracted attributes. Otherwise, set TOS to ``False``. of extracted attributes. Otherwise, push ``None``.
.. versionadded:: 3.10 .. versionadded:: 3.10
.. versionchanged:: 3.11
Previously, this instruction also pushed a boolean value indicating
success (``True``) or failure (``False``).
.. opcode:: GEN_START (kind) .. opcode:: GEN_START (kind)
Pops TOS. If TOS was not ``None``, raises an exception. The ``kind`` Pops TOS. If TOS was not ``None``, raises an exception. The ``kind``
@ -1301,6 +1299,14 @@ All of the following opcodes use their arguments.
.. versionadded:: 3.10 .. versionadded:: 3.10
.. opcode:: COPY (i)
Push the *i*-th item to the top of the stack. The item is not removed from its
original location.
.. versionadded:: 3.11
.. opcode:: HAVE_ARGUMENT .. opcode:: HAVE_ARGUMENT
This is not really an opcode. It identifies the dividing line between This is not really an opcode. It identifies the dividing line between

View File

@ -308,6 +308,16 @@ CPython bytecode changes
fashion as :opcode:`CALL_METHOD`, but also supports keyword arguments. Works fashion as :opcode:`CALL_METHOD`, but also supports keyword arguments. Works
in tandem with :opcode:`LOAD_METHOD`. in tandem with :opcode:`LOAD_METHOD`.
* Removed ``COPY_DICT_WITHOUT_KEYS``.
* :opcode:`MATCH_CLASS` and :opcode:`MATCH_KEYS` no longer push an additional
boolean value indicating whether the match succeeded or failed. Instead, they
indicate failure with :const:`None` (where a tuple of extracted values would
otherwise be).
* Added :opcode:`COPY`, which pushes the *i*-th item to the top of the stack.
The item is not removed from its original location.
Deprecated Deprecated
========== ==========

38
Include/opcode.h generated
View File

@ -34,7 +34,6 @@ extern "C" {
#define MATCH_MAPPING 31 #define MATCH_MAPPING 31
#define MATCH_SEQUENCE 32 #define MATCH_SEQUENCE 32
#define MATCH_KEYS 33 #define MATCH_KEYS 33
#define COPY_DICT_WITHOUT_KEYS 34
#define PUSH_EXC_INFO 35 #define PUSH_EXC_INFO 35
#define POP_EXCEPT_AND_RERAISE 37 #define POP_EXCEPT_AND_RERAISE 37
#define WITH_EXCEPT_START 49 #define WITH_EXCEPT_START 49
@ -104,6 +103,7 @@ extern "C" {
#define IS_OP 117 #define IS_OP 117
#define CONTAINS_OP 118 #define CONTAINS_OP 118
#define RERAISE 119 #define RERAISE 119
#define COPY 120
#define JUMP_IF_NOT_EXC_MATCH 121 #define JUMP_IF_NOT_EXC_MATCH 121
#define LOAD_FAST 124 #define LOAD_FAST 124
#define STORE_FAST 125 #define STORE_FAST 125
@ -142,24 +142,24 @@ extern "C" {
#define BINARY_ADD_UNICODE 14 #define BINARY_ADD_UNICODE 14
#define BINARY_ADD_UNICODE_INPLACE_FAST 18 #define BINARY_ADD_UNICODE_INPLACE_FAST 18
#define BINARY_MULTIPLY_ADAPTIVE 21 #define BINARY_MULTIPLY_ADAPTIVE 21
#define BINARY_MULTIPLY_INT 36 #define BINARY_MULTIPLY_INT 34
#define BINARY_MULTIPLY_FLOAT 38 #define BINARY_MULTIPLY_FLOAT 36
#define BINARY_SUBSCR_ADAPTIVE 39 #define BINARY_SUBSCR_ADAPTIVE 38
#define BINARY_SUBSCR_LIST_INT 40 #define BINARY_SUBSCR_LIST_INT 39
#define BINARY_SUBSCR_TUPLE_INT 41 #define BINARY_SUBSCR_TUPLE_INT 40
#define BINARY_SUBSCR_DICT 42 #define BINARY_SUBSCR_DICT 41
#define CALL_FUNCTION_ADAPTIVE 43 #define CALL_FUNCTION_ADAPTIVE 42
#define CALL_FUNCTION_BUILTIN_O 44 #define CALL_FUNCTION_BUILTIN_O 43
#define CALL_FUNCTION_BUILTIN_FAST 45 #define CALL_FUNCTION_BUILTIN_FAST 44
#define CALL_FUNCTION_LEN 46 #define CALL_FUNCTION_LEN 45
#define CALL_FUNCTION_ISINSTANCE 47 #define CALL_FUNCTION_ISINSTANCE 46
#define CALL_FUNCTION_PY_SIMPLE 48 #define CALL_FUNCTION_PY_SIMPLE 47
#define JUMP_ABSOLUTE_QUICK 58 #define JUMP_ABSOLUTE_QUICK 48
#define LOAD_ATTR_ADAPTIVE 80 #define LOAD_ATTR_ADAPTIVE 58
#define LOAD_ATTR_INSTANCE_VALUE 81 #define LOAD_ATTR_INSTANCE_VALUE 80
#define LOAD_ATTR_WITH_HINT 87 #define LOAD_ATTR_WITH_HINT 81
#define LOAD_ATTR_SLOT 88 #define LOAD_ATTR_SLOT 87
#define LOAD_ATTR_MODULE 120 #define LOAD_ATTR_MODULE 88
#define LOAD_GLOBAL_ADAPTIVE 122 #define LOAD_GLOBAL_ADAPTIVE 122
#define LOAD_GLOBAL_MODULE 123 #define LOAD_GLOBAL_MODULE 123
#define LOAD_GLOBAL_BUILTIN 127 #define LOAD_GLOBAL_BUILTIN 127

View File

@ -364,6 +364,8 @@ _code_type = type(_write_atomic.__code__)
# Python 3.11a1 3459 (PEP 657: add end line numbers and column offsets for instructions) # Python 3.11a1 3459 (PEP 657: add end line numbers and column offsets for instructions)
# Python 3.11a1 3460 (Add co_qualname field to PyCodeObject bpo-44530) # Python 3.11a1 3460 (Add co_qualname field to PyCodeObject bpo-44530)
# Python 3.11a1 3461 (JUMP_ABSOLUTE must jump backwards) # Python 3.11a1 3461 (JUMP_ABSOLUTE must jump backwards)
# Python 3.11a2 3462 (bpo-44511: remove COPY_DICT_WITHOUT_KEYS, change
# MATCH_CLASS and MATCH_KEYS, and add COPY)
# #
# MAGIC must change whenever the bytecode emitted by the compiler may no # MAGIC must change whenever the bytecode emitted by the compiler may no
@ -373,7 +375,7 @@ _code_type = type(_write_atomic.__code__)
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array # Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
# in PC/launcher.c must also be updated. # in PC/launcher.c must also be updated.
MAGIC_NUMBER = (3461).to_bytes(2, 'little') + b'\r\n' MAGIC_NUMBER = (3462).to_bytes(2, 'little') + b'\r\n'
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
_PYCACHE = '__pycache__' _PYCACHE = '__pycache__'

View File

@ -85,7 +85,7 @@ def_op('GET_LEN', 30)
def_op('MATCH_MAPPING', 31) def_op('MATCH_MAPPING', 31)
def_op('MATCH_SEQUENCE', 32) def_op('MATCH_SEQUENCE', 32)
def_op('MATCH_KEYS', 33) def_op('MATCH_KEYS', 33)
def_op('COPY_DICT_WITHOUT_KEYS', 34)
def_op('PUSH_EXC_INFO', 35) def_op('PUSH_EXC_INFO', 35)
def_op('POP_EXCEPT_AND_RERAISE', 37) def_op('POP_EXCEPT_AND_RERAISE', 37)
@ -165,7 +165,7 @@ name_op('LOAD_GLOBAL', 116) # Index in name list
def_op('IS_OP', 117) def_op('IS_OP', 117)
def_op('CONTAINS_OP', 118) def_op('CONTAINS_OP', 118)
def_op('RERAISE', 119) def_op('RERAISE', 119)
def_op('COPY', 120)
jabs_op('JUMP_IF_NOT_EXC_MATCH', 121) jabs_op('JUMP_IF_NOT_EXC_MATCH', 121)
def_op('LOAD_FAST', 124) # Local variable number def_op('LOAD_FAST', 124) # Local variable number

View File

@ -0,0 +1 @@
Improve the generated bytecode for class and mapping patterns.

BIN
Programs/_freeze_importlib Executable file

Binary file not shown.

View File

@ -4143,25 +4143,30 @@ check_eval_breaker:
} }
TARGET(MATCH_CLASS) { TARGET(MATCH_CLASS) {
// Pop TOS. On success, set TOS to True and TOS1 to a tuple of // Pop TOS and TOS1. Set TOS to a tuple of attributes on success, or
// attributes. On failure, set TOS to False. // None on failure.
PyObject *names = POP(); PyObject *names = POP();
PyObject *type = TOP(); PyObject *type = POP();
PyObject *subject = SECOND(); PyObject *subject = TOP();
assert(PyTuple_CheckExact(names)); assert(PyTuple_CheckExact(names));
PyObject *attrs = match_class(tstate, subject, type, oparg, names); PyObject *attrs = match_class(tstate, subject, type, oparg, names);
Py_DECREF(names); Py_DECREF(names);
Py_DECREF(type);
if (attrs) { if (attrs) {
// Success! // Success!
assert(PyTuple_CheckExact(attrs)); assert(PyTuple_CheckExact(attrs));
Py_DECREF(subject); SET_TOP(attrs);
SET_SECOND(attrs);
} }
else if (_PyErr_Occurred(tstate)) { else if (_PyErr_Occurred(tstate)) {
// Error!
goto error; goto error;
} }
Py_DECREF(type); else {
SET_TOP(PyBool_FromLong(!!attrs)); // Failure!
Py_INCREF(Py_None);
SET_TOP(Py_None);
}
Py_DECREF(subject);
DISPATCH(); DISPATCH();
} }
@ -4171,6 +4176,7 @@ check_eval_breaker:
PyObject *res = match ? Py_True : Py_False; PyObject *res = match ? Py_True : Py_False;
Py_INCREF(res); Py_INCREF(res);
PUSH(res); PUSH(res);
PREDICT(POP_JUMP_IF_FALSE);
DISPATCH(); DISPATCH();
} }
@ -4180,12 +4186,12 @@ check_eval_breaker:
PyObject *res = match ? Py_True : Py_False; PyObject *res = match ? Py_True : Py_False;
Py_INCREF(res); Py_INCREF(res);
PUSH(res); PUSH(res);
PREDICT(POP_JUMP_IF_FALSE);
DISPATCH(); DISPATCH();
} }
TARGET(MATCH_KEYS) { TARGET(MATCH_KEYS) {
// On successful match for all keys, PUSH(values) and PUSH(True). // On successful match, PUSH(values). Otherwise, PUSH(None).
// Otherwise, PUSH(None) and PUSH(False).
PyObject *keys = TOP(); PyObject *keys = TOP();
PyObject *subject = SECOND(); PyObject *subject = SECOND();
PyObject *values_or_none = match_keys(tstate, subject, keys); PyObject *values_or_none = match_keys(tstate, subject, keys);
@ -4193,40 +4199,6 @@ check_eval_breaker:
goto error; goto error;
} }
PUSH(values_or_none); 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(); DISPATCH();
} }
@ -5027,6 +4999,14 @@ check_eval_breaker:
DISPATCH(); DISPATCH();
} }
TARGET(COPY) {
assert(oparg != 0);
PyObject *peek = PEEK(oparg);
Py_INCREF(peek);
PUSH(peek);
DISPATCH();
}
TARGET(EXTENDED_ARG) { TARGET(EXTENDED_ARG) {
int oldoparg = oparg; int oldoparg = oparg;
NEXTOPARG(); NEXTOPARG();

View File

@ -1248,18 +1248,17 @@ stack_effect(int opcode, int oparg, int jump)
case DICT_MERGE: case DICT_MERGE:
case DICT_UPDATE: case DICT_UPDATE:
return -1; return -1;
case COPY_DICT_WITHOUT_KEYS:
return 0;
case MATCH_CLASS: case MATCH_CLASS:
return -1; return -2;
case GET_LEN: case GET_LEN:
case MATCH_MAPPING: case MATCH_MAPPING:
case MATCH_SEQUENCE: case MATCH_SEQUENCE:
return 1;
case MATCH_KEYS: case MATCH_KEYS:
return 2; return 1;
case ROT_N: case ROT_N:
return 0; return 0;
case COPY:
return 1;
default: default:
return PY_INVALID_STACK_EFFECT; return PY_INVALID_STACK_EFFECT;
} }
@ -6118,10 +6117,16 @@ compiler_pattern_class(struct compiler *c, pattern_ty p, pattern_context *pc)
} }
ADDOP_LOAD_CONST_NEW(c, attr_names); ADDOP_LOAD_CONST_NEW(c, attr_names);
ADDOP_I(c, MATCH_CLASS, nargs); ADDOP_I(c, MATCH_CLASS, nargs);
// TOS is now a tuple of (nargs + nattrs) attributes. Preserve it: ADDOP(c, DUP_TOP);
ADDOP_LOAD_CONST(c, Py_None);
ADDOP_I(c, IS_OP, 1);
// TOS is now a tuple of (nargs + nattrs) attributes (or None):
pc->on_top++; pc->on_top++;
RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE));
ADDOP_I(c, UNPACK_SEQUENCE, nargs + nattrs);
pc->on_top += nargs + nattrs - 1;
for (i = 0; i < nargs + nattrs; i++) { for (i = 0; i < nargs + nattrs; i++) {
pc->on_top--;
pattern_ty pattern; pattern_ty pattern;
if (i < nargs) { if (i < nargs) {
// Positional: // Positional:
@ -6132,17 +6137,12 @@ compiler_pattern_class(struct compiler *c, pattern_ty p, pattern_context *pc)
pattern = asdl_seq_GET(kwd_patterns, i - nargs); pattern = asdl_seq_GET(kwd_patterns, i - nargs);
} }
if (WILDCARD_CHECK(pattern)) { if (WILDCARD_CHECK(pattern)) {
ADDOP(c, POP_TOP);
continue; continue;
} }
// Get the i-th attribute, and match it against the i-th pattern:
ADDOP(c, DUP_TOP);
ADDOP_LOAD_CONST_NEW(c, PyLong_FromSsize_t(i));
ADDOP(c, BINARY_SUBSCR);
RETURN_IF_FALSE(compiler_pattern_subpattern(c, pattern, pc)); RETURN_IF_FALSE(compiler_pattern_subpattern(c, pattern, pc));
} }
// Success! Pop the tuple of attributes: // Success! Pop the tuple of attributes:
pc->on_top--;
ADDOP(c, POP_TOP);
return 1; return 1;
} }
@ -6183,7 +6183,7 @@ compiler_pattern_mapping(struct compiler *c, pattern_ty p, pattern_context *pc)
return compiler_error(c, "too many sub-patterns in mapping pattern"); return compiler_error(c, "too many sub-patterns in mapping pattern");
} }
// Collect all of the keys into a tuple for MATCH_KEYS and // Collect all of the keys into a tuple for MATCH_KEYS and
// COPY_DICT_WITHOUT_KEYS. They can either be dotted names or literals: // **rest. They can either be dotted names or literals:
// Maintaining a set of Constant_kind kind keys allows us to raise a // Maintaining a set of Constant_kind kind keys allows us to raise a
// SyntaxError in the case of duplicates. // SyntaxError in the case of duplicates.
@ -6235,35 +6235,45 @@ compiler_pattern_mapping(struct compiler *c, pattern_ty p, pattern_context *pc)
ADDOP(c, MATCH_KEYS); ADDOP(c, MATCH_KEYS);
// There's now a tuple of keys and a tuple of values on top of the subject: // There's now a tuple of keys and a tuple of values on top of the subject:
pc->on_top += 2; pc->on_top += 2;
ADDOP(c, DUP_TOP);
ADDOP_LOAD_CONST(c, Py_None);
ADDOP_I(c, IS_OP, 1);
RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE));
// So far so good. Use that tuple of values on the stack to match // So far so good. Use that tuple of values on the stack to match
// sub-patterns against: // sub-patterns against:
ADDOP_I(c, UNPACK_SEQUENCE, size);
pc->on_top += size - 1;
for (Py_ssize_t i = 0; i < size; i++) { for (Py_ssize_t i = 0; i < size; i++) {
pc->on_top--;
pattern_ty pattern = asdl_seq_GET(patterns, i); pattern_ty pattern = asdl_seq_GET(patterns, i);
if (WILDCARD_CHECK(pattern)) {
continue;
}
ADDOP(c, DUP_TOP);
ADDOP_LOAD_CONST_NEW(c, PyLong_FromSsize_t(i));
ADDOP(c, BINARY_SUBSCR);
RETURN_IF_FALSE(compiler_pattern_subpattern(c, pattern, pc)); RETURN_IF_FALSE(compiler_pattern_subpattern(c, pattern, pc));
} }
// If we get this far, it's a match! We're done with the tuple of values, // If we get this far, it's a match! Whatever happens next should consume
// and whatever happens next should consume the tuple of keys underneath it: // the tuple of keys and the subject:
pc->on_top -= 2; pc->on_top -= 2;
ADDOP(c, POP_TOP);
if (star_target) { if (star_target) {
// If we have a starred name, bind a dict of remaining items to it: // If we have a starred name, bind a dict of remaining items to it (this may
ADDOP(c, COPY_DICT_WITHOUT_KEYS); // seem a bit inefficient, but keys is rarely big enough to actually impact
// runtime):
// rest = dict(TOS1)
// for key in TOS:
// del rest[key]
ADDOP_I(c, BUILD_MAP, 0); // [subject, keys, empty]
ADDOP(c, ROT_THREE); // [empty, subject, keys]
ADDOP(c, ROT_TWO); // [empty, keys, subject]
ADDOP_I(c, DICT_UPDATE, 2); // [copy, keys]
ADDOP_I(c, UNPACK_SEQUENCE, size); // [copy, keys...]
while (size) {
ADDOP_I(c, COPY, 1 + size--); // [copy, keys..., copy]
ADDOP(c, ROT_TWO); // [copy, keys..., copy, key]
ADDOP(c, DELETE_SUBSCR); // [copy, keys...]
}
RETURN_IF_FALSE(pattern_helper_store_name(c, star_target, pc)); RETURN_IF_FALSE(pattern_helper_store_name(c, star_target, pc));
} }
else { else {
// Otherwise, we don't care about this tuple of keys anymore: ADDOP(c, POP_TOP); // Tuple of keys.
ADDOP(c, POP_TOP); ADDOP(c, POP_TOP); // Subject.
} }
// Pop the subject:
pc->on_top--;
ADDOP(c, POP_TOP);
return 1; return 1;
error: error:
@ -8362,6 +8372,11 @@ optimize_basic_block(struct compiler *c, basicblock *bb, PyObject *consts)
fold_rotations(inst - oparg + 1, oparg); fold_rotations(inst - oparg + 1, oparg);
} }
break; break;
case COPY:
if (oparg == 1) {
inst->i_opcode = DUP_TOP;
}
break;
default: default:
/* All HAS_CONST opcodes should be handled with LOAD_CONST */ /* All HAS_CONST opcodes should be handled with LOAD_CONST */
assert (!HAS_CONST(inst->i_opcode)); assert (!HAS_CONST(inst->i_opcode));

View File

@ -33,11 +33,10 @@ static void *opcode_targets[256] = {
&&TARGET_MATCH_MAPPING, &&TARGET_MATCH_MAPPING,
&&TARGET_MATCH_SEQUENCE, &&TARGET_MATCH_SEQUENCE,
&&TARGET_MATCH_KEYS, &&TARGET_MATCH_KEYS,
&&TARGET_COPY_DICT_WITHOUT_KEYS,
&&TARGET_PUSH_EXC_INFO,
&&TARGET_BINARY_MULTIPLY_INT, &&TARGET_BINARY_MULTIPLY_INT,
&&TARGET_POP_EXCEPT_AND_RERAISE, &&TARGET_PUSH_EXC_INFO,
&&TARGET_BINARY_MULTIPLY_FLOAT, &&TARGET_BINARY_MULTIPLY_FLOAT,
&&TARGET_POP_EXCEPT_AND_RERAISE,
&&TARGET_BINARY_SUBSCR_ADAPTIVE, &&TARGET_BINARY_SUBSCR_ADAPTIVE,
&&TARGET_BINARY_SUBSCR_LIST_INT, &&TARGET_BINARY_SUBSCR_LIST_INT,
&&TARGET_BINARY_SUBSCR_TUPLE_INT, &&TARGET_BINARY_SUBSCR_TUPLE_INT,
@ -48,6 +47,7 @@ static void *opcode_targets[256] = {
&&TARGET_CALL_FUNCTION_LEN, &&TARGET_CALL_FUNCTION_LEN,
&&TARGET_CALL_FUNCTION_ISINSTANCE, &&TARGET_CALL_FUNCTION_ISINSTANCE,
&&TARGET_CALL_FUNCTION_PY_SIMPLE, &&TARGET_CALL_FUNCTION_PY_SIMPLE,
&&TARGET_JUMP_ABSOLUTE_QUICK,
&&TARGET_WITH_EXCEPT_START, &&TARGET_WITH_EXCEPT_START,
&&TARGET_GET_AITER, &&TARGET_GET_AITER,
&&TARGET_GET_ANEXT, &&TARGET_GET_ANEXT,
@ -57,7 +57,7 @@ static void *opcode_targets[256] = {
&&TARGET_INPLACE_ADD, &&TARGET_INPLACE_ADD,
&&TARGET_INPLACE_SUBTRACT, &&TARGET_INPLACE_SUBTRACT,
&&TARGET_INPLACE_MULTIPLY, &&TARGET_INPLACE_MULTIPLY,
&&TARGET_JUMP_ABSOLUTE_QUICK, &&TARGET_LOAD_ATTR_ADAPTIVE,
&&TARGET_INPLACE_MODULO, &&TARGET_INPLACE_MODULO,
&&TARGET_STORE_SUBSCR, &&TARGET_STORE_SUBSCR,
&&TARGET_DELETE_SUBSCR, &&TARGET_DELETE_SUBSCR,
@ -79,15 +79,15 @@ static void *opcode_targets[256] = {
&&TARGET_INPLACE_AND, &&TARGET_INPLACE_AND,
&&TARGET_INPLACE_XOR, &&TARGET_INPLACE_XOR,
&&TARGET_INPLACE_OR, &&TARGET_INPLACE_OR,
&&TARGET_LOAD_ATTR_ADAPTIVE,
&&TARGET_LOAD_ATTR_INSTANCE_VALUE, &&TARGET_LOAD_ATTR_INSTANCE_VALUE,
&&TARGET_LOAD_ATTR_WITH_HINT,
&&TARGET_LIST_TO_TUPLE, &&TARGET_LIST_TO_TUPLE,
&&TARGET_RETURN_VALUE, &&TARGET_RETURN_VALUE,
&&TARGET_IMPORT_STAR, &&TARGET_IMPORT_STAR,
&&TARGET_SETUP_ANNOTATIONS, &&TARGET_SETUP_ANNOTATIONS,
&&TARGET_YIELD_VALUE, &&TARGET_YIELD_VALUE,
&&TARGET_LOAD_ATTR_WITH_HINT,
&&TARGET_LOAD_ATTR_SLOT, &&TARGET_LOAD_ATTR_SLOT,
&&TARGET_LOAD_ATTR_MODULE,
&&TARGET_POP_EXCEPT, &&TARGET_POP_EXCEPT,
&&TARGET_STORE_NAME, &&TARGET_STORE_NAME,
&&TARGET_DELETE_NAME, &&TARGET_DELETE_NAME,
@ -119,7 +119,7 @@ static void *opcode_targets[256] = {
&&TARGET_IS_OP, &&TARGET_IS_OP,
&&TARGET_CONTAINS_OP, &&TARGET_CONTAINS_OP,
&&TARGET_RERAISE, &&TARGET_RERAISE,
&&TARGET_LOAD_ATTR_MODULE, &&TARGET_COPY,
&&TARGET_JUMP_IF_NOT_EXC_MATCH, &&TARGET_JUMP_IF_NOT_EXC_MATCH,
&&TARGET_LOAD_GLOBAL_ADAPTIVE, &&TARGET_LOAD_GLOBAL_ADAPTIVE,
&&TARGET_LOAD_GLOBAL_MODULE, &&TARGET_LOAD_GLOBAL_MODULE,