|
113 | 113 | ) |
114 | 114 | from mypyc.primitives.float_ops import isinstance_float |
115 | 115 | from mypyc.primitives.generic_ops import generic_setattr, setup_object |
116 | | -from mypyc.primitives.int_ops import isinstance_int |
| 116 | +from mypyc.primitives.int_ops import ( |
| 117 | + int_to_big_endian_op, |
| 118 | + int_to_bytes_op, |
| 119 | + int_to_little_endian_op, |
| 120 | + isinstance_int, |
| 121 | +) |
117 | 122 | from mypyc.primitives.librt_strings_ops import ( |
118 | 123 | bytes_writer_adjust_index_op, |
119 | 124 | bytes_writer_get_item_unsafe_op, |
@@ -1242,6 +1247,77 @@ def translate_object_setattr(builder: IRBuilder, expr: CallExpr, callee: RefExpr |
1242 | 1247 | return builder.call_c(generic_setattr, [self_reg, name_reg, value], expr.line) |
1243 | 1248 |
|
1244 | 1249 |
|
| 1250 | +@specialize_function("to_bytes", int_rprimitive) |
| 1251 | +def specialize_int_to_bytes(builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> Value | None: |
| 1252 | + # int.to_bytes(length, byteorder, signed=False) |
| 1253 | + if any(kind not in (ARG_POS, ARG_NAMED) for kind in expr.arg_kinds): |
| 1254 | + return None |
| 1255 | + if not isinstance(callee, MemberExpr): |
| 1256 | + return None |
| 1257 | + length_expr: Expression | None = None |
| 1258 | + byteorder_expr: Expression | None = None |
| 1259 | + signed_expr: Expression | None = None |
| 1260 | + positional_index = 0 |
| 1261 | + for name, arg in zip(expr.arg_names, expr.args): |
| 1262 | + if name is None: |
| 1263 | + if positional_index == 0: |
| 1264 | + length_expr = arg |
| 1265 | + elif positional_index == 1: |
| 1266 | + byteorder_expr = arg |
| 1267 | + elif positional_index == 2: |
| 1268 | + signed_expr = arg |
| 1269 | + else: |
| 1270 | + return None |
| 1271 | + positional_index += 1 |
| 1272 | + elif name == "length": |
| 1273 | + if length_expr is not None: |
| 1274 | + return None |
| 1275 | + length_expr = arg |
| 1276 | + elif name == "byteorder": |
| 1277 | + if byteorder_expr is not None: |
| 1278 | + return None |
| 1279 | + byteorder_expr = arg |
| 1280 | + elif name == "signed": |
| 1281 | + if signed_expr is not None: |
| 1282 | + return None |
| 1283 | + signed_expr = arg |
| 1284 | + else: |
| 1285 | + return None |
| 1286 | + if length_expr is None or byteorder_expr is None: |
| 1287 | + return None |
| 1288 | + |
| 1289 | + signed_is_bool = True |
| 1290 | + if signed_expr is not None: |
| 1291 | + signed_is_bool = is_bool_rprimitive(builder.node_type(signed_expr)) |
| 1292 | + if not ( |
| 1293 | + is_int_rprimitive(builder.node_type(length_expr)) |
| 1294 | + and is_str_rprimitive(builder.node_type(byteorder_expr)) |
| 1295 | + and signed_is_bool |
| 1296 | + ): |
| 1297 | + return None |
| 1298 | + |
| 1299 | + self_arg = builder.accept(callee.expr) |
| 1300 | + length_arg = builder.accept(length_expr) |
| 1301 | + if signed_expr is None: |
| 1302 | + signed_arg = builder.false() |
| 1303 | + else: |
| 1304 | + signed_arg = builder.accept(signed_expr) |
| 1305 | + if isinstance(byteorder_expr, StrExpr): |
| 1306 | + if byteorder_expr.value == "little": |
| 1307 | + return builder.call_c( |
| 1308 | + int_to_little_endian_op, [self_arg, length_arg, signed_arg], expr.line |
| 1309 | + ) |
| 1310 | + elif byteorder_expr.value == "big": |
| 1311 | + return builder.call_c( |
| 1312 | + int_to_big_endian_op, [self_arg, length_arg, signed_arg], expr.line |
| 1313 | + ) |
| 1314 | + # Fallback to generic primitive op |
| 1315 | + byteorder_arg = builder.accept(byteorder_expr) |
| 1316 | + return builder.call_c( |
| 1317 | + int_to_bytes_op, [self_arg, length_arg, byteorder_arg, signed_arg], expr.line |
| 1318 | + ) |
| 1319 | + |
| 1320 | + |
1245 | 1321 | def translate_getitem_with_bounds_check( |
1246 | 1322 | builder: IRBuilder, |
1247 | 1323 | base_expr: Expression, |
|
0 commit comments