this repo has no description
1/* Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) */
2#pragma once
3
4#include "handles-decl.h"
5#include "objects.h"
6
7namespace py {
8
9// Define the set of bytecodes.
10//
11// Except for the *_CACHED instructions at the end of the list, these are all
12// taken directly from CPython. The cached bytecodes perform the same operation
13// as their CPython counterpart, but do it more quickly using an inline cache.
14//
15// `FOREACH_BYTECODE` calls V for each bytecode with 3 arguments:
16// 1. The opcode's name.
17// 2. The opcode's numeric value.
18// 3. The opcode handler's name.
19#define FOREACH_BYTECODE(V) \
20 V(UNUSED_BYTECODE_0, 0, doInvalidBytecode) \
21 V(POP_TOP, 1, doPopTop) \
22 V(ROT_TWO, 2, doRotTwo) \
23 V(ROT_THREE, 3, doRotThree) \
24 V(DUP_TOP, 4, doDupTop) \
25 V(DUP_TOP_TWO, 5, doDupTopTwo) \
26 V(ROT_FOUR, 6, doRotFour) \
27 V(UNARY_OP_ANAMORPHIC, 7, doUnaryOpAnamorphic) \
28 V(UNARY_NEGATIVE_SMALLINT, 8, doUnaryNegativeSmallInt) \
29 V(NOP, 9, doNop) \
30 V(UNARY_POSITIVE, 10, doUnaryPositive) \
31 V(UNARY_NEGATIVE, 11, doUnaryNegative) \
32 V(UNARY_NOT, 12, doUnaryNot) \
33 V(UNUSED_BYTECODE_13, 13, doInvalidBytecode) \
34 V(UNUSED_BYTECODE_14, 14, doInvalidBytecode) \
35 V(UNARY_INVERT, 15, doUnaryInvert) \
36 V(BINARY_MATRIX_MULTIPLY, 16, doBinaryMatrixMultiply) \
37 V(INPLACE_MATRIX_MULTIPLY, 17, doInplaceMatrixMultiply) \
38 V(UNUSED_BYTECODE_18, 18, doInvalidBytecode) \
39 V(BINARY_POWER, 19, doBinaryPower) \
40 V(BINARY_MULTIPLY, 20, doBinaryMultiply) \
41 V(UNUSED_BYTECODE_21, 21, doInvalidBytecode) \
42 V(BINARY_MODULO, 22, doBinaryModulo) \
43 V(BINARY_ADD, 23, doBinaryAdd) \
44 V(BINARY_SUBTRACT, 24, doBinarySubtract) \
45 V(BINARY_SUBSCR, 25, doBinarySubscr) \
46 V(BINARY_FLOOR_DIVIDE, 26, doBinaryFloorDivide) \
47 V(BINARY_TRUE_DIVIDE, 27, doBinaryTrueDivide) \
48 V(INPLACE_FLOOR_DIVIDE, 28, doInplaceFloorDivide) \
49 V(INPLACE_TRUE_DIVIDE, 29, doInplaceTrueDivide) \
50 V(UNUSED_BYTECODE_30, 30, doInvalidBytecode) \
51 V(UNUSED_BYTECODE_31, 31, doInvalidBytecode) \
52 V(UNUSED_BYTECODE_32, 32, doInvalidBytecode) \
53 V(UNUSED_BYTECODE_33, 33, doInvalidBytecode) \
54 V(UNUSED_BYTECODE_34, 34, doInvalidBytecode) \
55 V(UNUSED_BYTECODE_35, 35, doInvalidBytecode) \
56 V(UNUSED_BYTECODE_36, 36, doInvalidBytecode) \
57 V(UNUSED_BYTECODE_37, 37, doInvalidBytecode) \
58 V(UNUSED_BYTECODE_38, 38, doInvalidBytecode) \
59 V(UNUSED_BYTECODE_39, 39, doInvalidBytecode) \
60 V(UNUSED_BYTECODE_40, 40, doInvalidBytecode) \
61 V(UNUSED_BYTECODE_41, 41, doInvalidBytecode) \
62 V(UNUSED_BYTECODE_42, 42, doInvalidBytecode) \
63 V(UNUSED_BYTECODE_43, 43, doInvalidBytecode) \
64 V(UNUSED_BYTECODE_44, 44, doInvalidBytecode) \
65 V(UNUSED_BYTECODE_45, 45, doInvalidBytecode) \
66 V(UNUSED_BYTECODE_46, 46, doInvalidBytecode) \
67 V(UNUSED_BYTECODE_47, 47, doInvalidBytecode) \
68 V(LOAD_BOOL, 48, doLoadBool) \
69 V(UNUSED_BYTECODE_49, 49, doInvalidBytecode) \
70 V(GET_AITER, 50, doGetAiter) \
71 V(GET_ANEXT, 51, doGetAnext) \
72 V(BEFORE_ASYNC_WITH, 52, doBeforeAsyncWith) \
73 V(BEGIN_FINALLY, 53, doBeginFinally) \
74 V(END_ASYNC_FOR, 54, doEndAsyncFor) \
75 V(INPLACE_ADD, 55, doInplaceAdd) \
76 V(INPLACE_SUBTRACT, 56, doInplaceSubtract) \
77 V(INPLACE_MULTIPLY, 57, doInplaceMultiply) \
78 V(UNUSED_BYTECODE_58, 58, doInvalidBytecode) \
79 V(INPLACE_MODULO, 59, doInplaceModulo) \
80 V(STORE_SUBSCR, 60, doStoreSubscr) \
81 V(DELETE_SUBSCR, 61, doDeleteSubscr) \
82 V(BINARY_LSHIFT, 62, doBinaryLshift) \
83 V(BINARY_RSHIFT, 63, doBinaryRshift) \
84 V(BINARY_AND, 64, doBinaryAnd) \
85 V(BINARY_XOR, 65, doBinaryXor) \
86 V(BINARY_OR, 66, doBinaryOr) \
87 V(INPLACE_POWER, 67, doInplacePower) \
88 V(GET_ITER, 68, doGetIter) \
89 V(GET_YIELD_FROM_ITER, 69, doGetYieldFromIter) \
90 V(PRINT_EXPR, 70, doPrintExpr) \
91 V(LOAD_BUILD_CLASS, 71, doLoadBuildClass) \
92 V(YIELD_FROM, 72, doYieldFrom) \
93 V(GET_AWAITABLE, 73, doGetAwaitable) \
94 V(UNUSED_BYTECODE_74, 74, doInvalidBytecode) \
95 V(INPLACE_LSHIFT, 75, doInplaceLshift) \
96 V(INPLACE_RSHIFT, 76, doInplaceRshift) \
97 V(INPLACE_AND, 77, doInplaceAnd) \
98 V(INPLACE_XOR, 78, doInplaceXor) \
99 V(INPLACE_OR, 79, doInplaceOr) \
100 V(UNUSED_BYTECODE_80, 80, doInvalidBytecode) \
101 V(WITH_CLEANUP_START, 81, doWithCleanupStart) \
102 V(WITH_CLEANUP_FINISH, 82, doWithCleanupFinish) \
103 V(RETURN_VALUE, 83, doReturnValue) \
104 V(IMPORT_STAR, 84, doImportStar) \
105 V(SETUP_ANNOTATIONS, 85, doSetupAnnotations) \
106 V(YIELD_VALUE, 86, doYieldValue) \
107 V(POP_BLOCK, 87, doPopBlock) \
108 V(END_FINALLY, 88, doEndFinally) \
109 V(POP_EXCEPT, 89, doPopExcept) \
110 V(STORE_NAME, 90, doStoreName) \
111 V(DELETE_NAME, 91, doDeleteName) \
112 V(UNPACK_SEQUENCE, 92, doUnpackSequence) \
113 V(FOR_ITER, 93, doForIter) \
114 V(UNPACK_EX, 94, doUnpackEx) \
115 V(STORE_ATTR, 95, doStoreAttr) \
116 V(DELETE_ATTR, 96, doDeleteAttr) \
117 V(STORE_GLOBAL, 97, doStoreGlobal) \
118 V(DELETE_GLOBAL, 98, doDeleteGlobal) \
119 V(LOAD_FAST_REVERSE_UNCHECKED, 99, doLoadFastReverseUnchecked) \
120 V(LOAD_CONST, 100, doLoadConst) \
121 V(LOAD_NAME, 101, doLoadName) \
122 V(BUILD_TUPLE, 102, doBuildTuple) \
123 V(BUILD_LIST, 103, doBuildList) \
124 V(BUILD_SET, 104, doBuildSet) \
125 V(BUILD_MAP, 105, doBuildMap) \
126 V(LOAD_ATTR, 106, doLoadAttr) \
127 V(COMPARE_OP, 107, doCompareOp) \
128 V(IMPORT_NAME, 108, doImportName) \
129 V(IMPORT_FROM, 109, doImportFrom) \
130 V(JUMP_FORWARD, 110, doJumpForward) \
131 V(JUMP_IF_FALSE_OR_POP, 111, doJumpIfFalseOrPop) \
132 V(JUMP_IF_TRUE_OR_POP, 112, doJumpIfTrueOrPop) \
133 V(JUMP_ABSOLUTE, 113, doJumpAbsolute) \
134 V(POP_JUMP_IF_FALSE, 114, doPopJumpIfFalse) \
135 V(POP_JUMP_IF_TRUE, 115, doPopJumpIfTrue) \
136 V(LOAD_GLOBAL, 116, doLoadGlobal) \
137 V(UNUSED_BYTECODE_117, 117, doInvalidBytecode) \
138 V(UNUSED_BYTECODE_118, 118, doInvalidBytecode) \
139 V(UNUSED_BYTECODE_119, 119, doInvalidBytecode) \
140 V(LOAD_TYPE, 120, doLoadType) \
141 V(UNUSED_BYTECODE_121, 121, doInvalidBytecode) \
142 V(SETUP_FINALLY, 122, doSetupFinally) \
143 V(UNUSED_BYTECODE_123, 123, doInvalidBytecode) \
144 V(LOAD_FAST, 124, doLoadFast) \
145 V(STORE_FAST, 125, doStoreFast) \
146 V(DELETE_FAST, 126, doDeleteFast) \
147 V(DELETE_FAST_REVERSE_UNCHECKED, 127, doDeleteFastReverseUnchecked) \
148 V(UNUSED_BYTECODE_128, 128, doInvalidBytecode) \
149 V(UNUSED_BYTECODE_129, 129, doInvalidBytecode) \
150 V(RAISE_VARARGS, 130, doRaiseVarargs) \
151 V(CALL_FUNCTION, 131, doCallFunction) \
152 V(MAKE_FUNCTION, 132, doMakeFunction) \
153 V(BUILD_SLICE, 133, doBuildSlice) \
154 V(UNUSED_BYTECODE_134, 134, doInvalidBytecode) \
155 V(LOAD_CLOSURE, 135, doLoadClosure) \
156 V(LOAD_DEREF, 136, doLoadDeref) \
157 V(STORE_DEREF, 137, doStoreDeref) \
158 V(DELETE_DEREF, 138, doDeleteDeref) \
159 V(UNUSED_BYTECODE_139, 139, doInvalidBytecode) \
160 V(UNUSED_BYTECODE_140, 140, doInvalidBytecode) \
161 V(CALL_FUNCTION_KW, 141, doCallFunctionKw) \
162 V(CALL_FUNCTION_EX, 142, doCallFunctionEx) \
163 V(SETUP_WITH, 143, doSetupWith) \
164 V(EXTENDED_ARG, 144, doInvalidBytecode) \
165 V(LIST_APPEND, 145, doListAppend) \
166 V(SET_ADD, 146, doSetAdd) \
167 V(MAP_ADD, 147, doMapAdd) \
168 V(LOAD_CLASSDEREF, 148, doLoadClassDeref) \
169 V(BUILD_LIST_UNPACK, 149, doBuildListUnpack) \
170 V(BUILD_MAP_UNPACK, 150, doBuildMapUnpack) \
171 V(BUILD_MAP_UNPACK_WITH_CALL, 151, doBuildMapUnpackWithCall) \
172 V(BUILD_TUPLE_UNPACK, 152, doBuildTupleUnpack) \
173 V(BUILD_SET_UNPACK, 153, doBuildSetUnpack) \
174 V(SETUP_ASYNC_WITH, 154, doSetupAsyncWith) \
175 V(FORMAT_VALUE, 155, doFormatValue) \
176 V(BUILD_CONST_KEY_MAP, 156, doBuildConstKeyMap) \
177 V(BUILD_STRING, 157, doBuildString) \
178 V(BUILD_TUPLE_UNPACK_WITH_CALL, 158, doBuildTupleUnpack) \
179 V(UNUSED_BYTECODE_159, 159, doInvalidBytecode) \
180 V(LOAD_METHOD, 160, doLoadMethod) \
181 V(CALL_METHOD, 161, doCallMethod) \
182 V(CALL_FINALLY, 162, doCallFinally) \
183 V(POP_FINALLY, 163, doPopFinally) \
184 V(UNUSED_BYTECODE_164, 164, doInvalidBytecode) \
185 V(UNUSED_BYTECODE_165, 165, doInvalidBytecode) \
186 V(UNUSED_BYTECODE_166, 166, doInvalidBytecode) \
187 V(UNUSED_BYTECODE_167, 167, doInvalidBytecode) \
188 V(UNUSED_BYTECODE_168, 168, doInvalidBytecode) \
189 V(UNUSED_BYTECODE_169, 169, doInvalidBytecode) \
190 V(UNUSED_BYTECODE_170, 170, doInvalidBytecode) \
191 V(UNUSED_BYTECODE_171, 171, doInvalidBytecode) \
192 V(UNUSED_BYTECODE_172, 172, doInvalidBytecode) \
193 V(UNUSED_BYTECODE_173, 173, doInvalidBytecode) \
194 V(LOAD_METHOD_MODULE, 174, doLoadMethodModule) \
195 V(CALL_FUNCTION_TYPE_INIT, 175, doCallFunctionTypeInit) \
196 V(CALL_FUNCTION_TYPE_NEW, 176, doCallFunctionTypeNew) \
197 V(CALL_FUNCTION_ANAMORPHIC, 177, doCallFunctionAnamorphic) \
198 V(COMPARE_NE_STR, 178, doCompareNeStr) \
199 V(FOR_ITER_GENERATOR, 179, doForIterGenerator) \
200 V(STORE_SUBSCR_DICT, 180, doStoreSubscrDict) \
201 V(BINARY_MUL_SMALLINT, 181, doBinaryMulSmallInt) \
202 V(BINARY_SUBSCR_DICT, 182, doBinarySubscrDict) \
203 V(BINARY_SUBSCR_TUPLE, 183, doBinarySubscrTuple) \
204 V(INPLACE_SUB_SMALLINT, 184, doInplaceSubSmallInt) \
205 V(STORE_SUBSCR_LIST, 185, doStoreSubscrList) \
206 V(BINARY_SUBSCR_LIST, 186, doBinarySubscrList) \
207 V(LOAD_ATTR_INSTANCE_SLOT_DESCR, 187, doLoadAttrInstanceSlotDescr) \
208 V(COMPARE_IN_LIST, 188, doCompareInList) \
209 V(COMPARE_IN_DICT, 189, doCompareInDict) \
210 V(COMPARE_IN_TUPLE, 190, doCompareInTuple) \
211 V(COMPARE_IN_STR, 191, doCompareInStr) \
212 V(COMPARE_IN_POLYMORPHIC, 192, doCompareInPolymorphic) \
213 V(COMPARE_IN_MONOMORPHIC, 193, doCompareInMonomorphic) \
214 V(COMPARE_IN_ANAMORPHIC, 194, doCompareInAnamorphic) \
215 V(BINARY_FLOORDIV_SMALLINT, 195, doBinaryFloordivSmallInt) \
216 V(BINARY_AND_SMALLINT, 196, doBinaryAndSmallInt) \
217 V(FOR_ITER_STR, 197, doForIterStr) \
218 V(FOR_ITER_RANGE, 198, doForIterRange) \
219 V(FOR_ITER_TUPLE, 199, doForIterTuple) \
220 V(FOR_ITER_DICT, 200, doForIterDict) \
221 V(FOR_ITER_LIST, 201, doForIterList) \
222 V(INPLACE_ADD_SMALLINT, 202, doInplaceAddSmallInt) \
223 V(COMPARE_EQ_STR, 203, doCompareEqStr) \
224 V(COMPARE_LE_SMALLINT, 204, doCompareLeSmallInt) \
225 V(COMPARE_NE_SMALLINT, 205, doCompareNeSmallInt) \
226 V(COMPARE_GE_SMALLINT, 206, doCompareGeSmallInt) \
227 V(COMPARE_LT_SMALLINT, 207, doCompareLtSmallInt) \
228 V(COMPARE_GT_SMALLINT, 208, doCompareGtSmallInt) \
229 V(COMPARE_EQ_SMALLINT, 209, doCompareEqSmallInt) \
230 V(BINARY_OR_SMALLINT, 210, doBinaryOrSmallInt) \
231 V(BINARY_SUB_SMALLINT, 211, doBinarySubSmallInt) \
232 V(BINARY_ADD_SMALLINT, 212, doBinaryAddSmallInt) \
233 V(INPLACE_OP_POLYMORPHIC, 213, doInplaceOpPolymorphic) \
234 V(INPLACE_OP_MONOMORPHIC, 214, doInplaceOpMonomorphic) \
235 V(COMPARE_OP_POLYMORPHIC, 215, doCompareOpPolymorphic) \
236 V(COMPARE_OP_MONOMORPHIC, 216, doCompareOpMonomorphic) \
237 V(BINARY_OP_POLYMORPHIC, 217, doBinaryOpPolymorphic) \
238 V(BINARY_OP_MONOMORPHIC, 218, doBinaryOpMonomorphic) \
239 V(STORE_SUBSCR_POLYMORPHIC, 219, doStoreSubscrPolymorphic) \
240 V(STORE_SUBSCR_MONOMORPHIC, 220, doStoreSubscrMonomorphic) \
241 V(FOR_ITER_POLYMORPHIC, 221, doForIterPolymorphic) \
242 V(FOR_ITER_MONOMORPHIC, 222, doForIterMonomorphic) \
243 V(BINARY_SUBSCR_POLYMORPHIC, 223, doBinarySubscrPolymorphic) \
244 V(BINARY_SUBSCR_MONOMORPHIC, 224, doBinarySubscrMonomorphic) \
245 V(STORE_ATTR_INSTANCE_OVERFLOW_UPDATE, 225, \
246 doStoreAttrInstanceOverflowUpdate) \
247 V(STORE_ATTR_INSTANCE_OVERFLOW, 226, doStoreAttrInstanceOverflow) \
248 V(STORE_ATTR_INSTANCE, 227, doStoreAttrInstance) \
249 V(STORE_ATTR_POLYMORPHIC, 228, doStoreAttrPolymorphic) \
250 V(LOAD_ATTR_POLYMORPHIC, 229, doLoadAttrPolymorphic) \
251 V(LOAD_ATTR_INSTANCE_TYPE_BOUND_METHOD, 230, \
252 doLoadAttrInstanceTypeBoundMethod) \
253 V(LOAD_ATTR_INSTANCE, 231, doLoadAttrInstance) \
254 V(LOAD_METHOD_POLYMORPHIC, 232, doLoadMethodPolymorphic) \
255 V(LOAD_METHOD_INSTANCE_FUNCTION, 233, doLoadMethodInstanceFunction) \
256 V(STORE_SUBSCR_ANAMORPHIC, 234, doStoreSubscrAnamorphic) \
257 V(LOAD_ATTR_INSTANCE_TYPE, 235, doLoadAttrInstanceType) \
258 V(LOAD_ATTR_INSTANCE_TYPE_DESCR, 236, doLoadAttrInstanceTypeDescr) \
259 V(LOAD_ATTR_INSTANCE_PROPERTY, 237, doLoadAttrInstanceProperty) \
260 V(STORE_ATTR_INSTANCE_UPDATE, 238, doStoreAttrInstanceUpdate) \
261 V(LOAD_ATTR_TYPE, 239, doLoadAttrType) \
262 V(LOAD_ATTR_MODULE, 240, doLoadAttrModule) \
263 V(COMPARE_IS_NOT, 241, doCompareIsNot) \
264 V(COMPARE_IS, 242, doCompareIs) \
265 V(LOAD_IMMEDIATE, 243, doLoadImmediate) \
266 V(STORE_FAST_REVERSE, 244, doStoreFastReverse) \
267 V(LOAD_FAST_REVERSE, 245, doLoadFastReverse) \
268 V(LOAD_METHOD_ANAMORPHIC, 246, doLoadMethodAnamorphic) \
269 V(STORE_GLOBAL_CACHED, 247, doStoreGlobalCached) \
270 V(LOAD_GLOBAL_CACHED, 248, doLoadGlobalCached) \
271 V(FOR_ITER_ANAMORPHIC, 249, doForIterAnamorphic) \
272 V(COMPARE_OP_ANAMORPHIC, 250, doCompareOpAnamorphic) \
273 V(INPLACE_OP_ANAMORPHIC, 251, doInplaceOpAnamorphic) \
274 V(BINARY_OP_ANAMORPHIC, 252, doBinaryOpAnamorphic) \
275 V(BINARY_SUBSCR_ANAMORPHIC, 253, doBinarySubscrAnamorphic) \
276 V(STORE_ATTR_ANAMORPHIC, 254, doStoreAttrAnamorphic) \
277 V(LOAD_ATTR_ANAMORPHIC, 255, doLoadAttrAnamorphic)
278
279const word kNumBytecodes = 256;
280
281enum Bytecode {
282#define ENUM(name, value, handler) name = value,
283 FOREACH_BYTECODE(ENUM)
284#undef ENUM
285};
286
287enum CompareOp {
288 LT = 0,
289 LE = 1,
290 EQ = 2,
291 NE = 3,
292 GT = 4,
293 GE = 5,
294 IN,
295 NOT_IN,
296 IS,
297 IS_NOT,
298 EXC_MATCH,
299 BAD
300};
301
302enum class FormatValueConv {
303 kNone = 0,
304 kStr = 1,
305 kRepr = 2,
306 kAscii = 3,
307};
308
309const word kFormatValueConvMask = 0x3;
310const word kFormatValueHasSpecBit = 0x4;
311
312enum MakeFunctionFlag {
313 DEFAULT = 0x01,
314 DEFAULT_KW = 0x02,
315 ANNOTATION_DICT = 0x04,
316 CLOSURE = 0x08,
317};
318
319enum CallFunctionExFlag {
320 VAR_KEYWORDS = 0x01,
321};
322
323// Size of opcode + argument in bytecode (called `_Py_CODEUNIT` in cpython).
324const word kCompilerCodeUnitSize = 2;
325const word kCodeUnitSize = 4;
326// TODO(T84723098): Remove kCodeUnitScale and kCodeUnitScaleLog2 and all the
327// places that scale PCs
328const word kCodeUnitScale = kCodeUnitSize / kCompilerCodeUnitSize;
329const word kCodeUnitScaleLog2 = 1;
330
331extern const char* const kBytecodeNames[];
332
333struct BytecodeOp {
334 Bytecode bc;
335 int32_t arg;
336 uint16_t cache;
337};
338
339BytecodeOp nextBytecodeOp(const MutableBytes& bytecode, word* index);
340
341// Return the opcode in the bytes object at the given opcode index. For
342// example, in the following code:
343// LOAD_ATTR, arg,
344// LOAD_GLOBAL, arg,
345// bytecodeAt(..., 0) would return LOAD_ATTR and
346// bytecodeAt(..., 1) would return LOAD_GLOBAL.
347word bytecodeLength(const Bytes& bytecode);
348Bytecode bytecodeOpAt(const Bytes& bytecode, word index);
349byte bytecodeArgAt(const Bytes& bytecode, word index);
350
351// Return the opcode in the rewritten bytes object at the given opcode index.
352// For example, in the following code:
353// LOAD_ATTR, arg,
354// LOAD_GLOBAL_CACHED, arg,
355// rewrittenBytecodeAt(..., 0) would return LOAD_ATTR and
356// rewrittenBytecodeAt(..., 1) would return LOAD_GLOBAL_CACHED.
357word rewrittenBytecodeLength(const MutableBytes& bytecode);
358Bytecode rewrittenBytecodeOpAt(const MutableBytes& bytecode, word index);
359void rewrittenBytecodeOpAtPut(const MutableBytes& bytecode, word index,
360 Bytecode op);
361byte rewrittenBytecodeArgAt(const MutableBytes& bytecode, word index);
362void rewrittenBytecodeArgAtPut(const MutableBytes& bytecode, word index,
363 byte arg);
364uint16_t rewrittenBytecodeCacheAt(const MutableBytes& bytecode, word index);
365void rewrittenBytecodeCacheAtPut(const MutableBytes& bytecode, word index,
366 uint16_t cache);
367
368inline bool isByteCodeWithCache(const Bytecode bc) {
369 // TODO(T45720638): Add all caching opcodes here once they are supported for
370 // cache invalidation.
371 switch (bc) {
372 case BINARY_OP_MONOMORPHIC:
373 case BINARY_OP_POLYMORPHIC:
374 case BINARY_OP_ANAMORPHIC:
375 case BINARY_SUBSCR_ANAMORPHIC:
376 case BINARY_SUBSCR_MONOMORPHIC:
377 case BINARY_SUBSCR_POLYMORPHIC:
378 case COMPARE_OP_MONOMORPHIC:
379 case COMPARE_OP_POLYMORPHIC:
380 case COMPARE_OP_ANAMORPHIC:
381 case CALL_FUNCTION_TYPE_INIT:
382 case CALL_FUNCTION_TYPE_NEW:
383 case FOR_ITER_MONOMORPHIC:
384 case FOR_ITER_POLYMORPHIC:
385 case FOR_ITER_ANAMORPHIC:
386 case INPLACE_OP_MONOMORPHIC:
387 case INPLACE_OP_POLYMORPHIC:
388 case INPLACE_OP_ANAMORPHIC:
389 case LOAD_ATTR_INSTANCE:
390 case LOAD_ATTR_INSTANCE_PROPERTY:
391 case LOAD_ATTR_INSTANCE_SLOT_DESCR:
392 case LOAD_ATTR_INSTANCE_TYPE:
393 case LOAD_ATTR_INSTANCE_TYPE_BOUND_METHOD:
394 case LOAD_ATTR_INSTANCE_TYPE_DESCR:
395 case LOAD_ATTR_MODULE:
396 case LOAD_METHOD_MODULE:
397 case LOAD_ATTR_TYPE:
398 case LOAD_ATTR_ANAMORPHIC:
399 case LOAD_METHOD_ANAMORPHIC:
400 case LOAD_METHOD_INSTANCE_FUNCTION:
401 case LOAD_METHOD_POLYMORPHIC:
402 case STORE_ATTR_INSTANCE:
403 case STORE_ATTR_INSTANCE_OVERFLOW:
404 case STORE_ATTR_INSTANCE_OVERFLOW_UPDATE:
405 case STORE_ATTR_INSTANCE_UPDATE:
406 case STORE_ATTR_POLYMORPHIC:
407 case STORE_ATTR_ANAMORPHIC:
408 case STORE_SUBSCR_ANAMORPHIC:
409 return true;
410 default:
411 return false;
412 }
413}
414
415// Convert an immediate RawObject into a byte, and back to the original
416// object. If the object fits in a byte,
417// objectFromOparg(opargFromObject(obj) == obj will hold.
418int8_t opargFromObject(RawObject object);
419
420inline RawObject objectFromOparg(word arg) {
421 return RawObject(static_cast<uword>(static_cast<int8_t>(arg)));
422}
423
424// Expand kCompilerCodeUnitSize bytecode to kCodeUnitSize bytecode, leaving all
425// opcodes and arguments intact.
426RawObject expandBytecode(Thread* thread, const Bytes& bytecode);
427
428// Prepares bytecode for caching: Adds a rewritten variant of the bytecode to
429// `function`. It has the arguments of opcodes that use the cache replaced with
430// a cache index. The previous arguments are moved to a separate tuple and can
431// be retrieved with `icOriginalArg()`. Also adds a correctly sized `caches`
432// tuple to `function`.
433void rewriteBytecode(Thread* thread, const Function& function);
434
435} // namespace py