MCPcopy Index your code
hub / github.com/python/mypy / emit_box

Method emit_box

mypyc/codegen/emit.py:1200–1271  ·  view source on GitHub ↗

Emit code for boxing a value of given type. Generate a simple assignment if no boxing is needed. The source reference count is stolen for the result (no need to decref afterwards).

(
        self, src: str, dest: str, typ: RType, declare_dest: bool = False, can_borrow: bool = False
    )

Source from the content-addressed store, hash-verified

1198 return None
1199
1200 def emit_box(
1201 self, src: str, dest: str, typ: RType, declare_dest: bool = False, can_borrow: bool = False
1202 ) -> None:
1203 """Emit code for boxing a value of given type.
1204
1205 Generate a simple assignment if no boxing is needed.
1206
1207 The source reference count is stolen for the result (no need to decref afterwards).
1208 """
1209 # TODO: Always generate a new reference (if a reference type)
1210 if declare_dest:
1211 declaration = "PyObject *"
1212 else:
1213 declaration = ""
1214 if is_int_rprimitive(typ) or is_short_int_rprimitive(typ):
1215 # Steal the existing reference if it exists.
1216 self.emit_line(f"{declaration}{dest} = CPyTagged_StealAsObject({src});")
1217 elif is_bool_or_bit_rprimitive(typ):
1218 # N.B: bool is special cased to produce a borrowed value
1219 # after boxing, so we don't need to increment the refcount
1220 # when this comes directly from a Box op.
1221 self.emit_lines(f"{declaration}{dest} = {src} ? Py_True : Py_False;")
1222 if not can_borrow:
1223 self.emit_inc_ref(dest, object_rprimitive)
1224 elif is_none_rprimitive(typ):
1225 # N.B: None is special cased to produce a borrowed value
1226 # after boxing, so we don't need to increment the refcount
1227 # when this comes directly from a Box op.
1228 self.emit_lines(f"{declaration}{dest} = Py_None;")
1229 if not can_borrow:
1230 self.emit_inc_ref(dest, object_rprimitive)
1231 elif is_int32_rprimitive(typ) or is_int16_rprimitive(typ) or is_uint8_rprimitive(typ):
1232 self.emit_line(f"{declaration}{dest} = PyLong_FromLong({src});")
1233 elif is_int64_rprimitive(typ):
1234 self.emit_line(f"{declaration}{dest} = PyLong_FromLongLong({src});")
1235 elif is_float_rprimitive(typ):
1236 self.emit_line(f"{declaration}{dest} = PyFloat_FromDouble({src});")
1237 elif isinstance(typ, RTuple):
1238 self.declare_tuple_struct(typ)
1239 if not typ.types:
1240 self.emit_line(f"{declaration}{dest} = CPyTuple_LoadEmptyTupleConstant();")
1241 else:
1242 self.emit_line(f"{declaration}{dest} = PyTuple_New({len(typ.types)});")
1243 self.emit_line(f"if (unlikely({dest} == NULL))")
1244 self.emit_line(" CPyError_OutOfMemory();")
1245
1246 # TODO: Fail if dest is None
1247 for i in range(len(typ.types)):
1248 if not typ.is_unboxed:
1249 self.emit_line(f"PyTuple_SET_ITEM({dest}, {i}, {src}.f{i}")
1250 else:
1251 inner_name = self.temp_name()
1252 self.emit_box(f"{src}.f{i}", inner_name, typ.types[i], declare_dest=True)
1253 self.emit_line(f"PyTuple_SET_ITEM({dest}, {i}, {inner_name});")
1254 elif isinstance(typ, RVec):
1255 specialized_api_name = vec_api_by_item_type.get(typ.item_type)
1256 if specialized_api_name is not None:
1257 api = specialized_api_name

Callers 4

emit_callMethod · 0.80
generate_getterFunction · 0.80
generate_readonly_getterFunction · 0.80
visit_boxMethod · 0.80

Calls 15

emit_lineMethod · 0.95
emit_linesMethod · 0.95
emit_inc_refMethod · 0.95
declare_tuple_structMethod · 0.95
temp_nameMethod · 0.95
vec_item_type_cMethod · 0.95
is_int_rprimitiveFunction · 0.90
is_short_int_rprimitiveFunction · 0.90
is_none_rprimitiveFunction · 0.90
is_int32_rprimitiveFunction · 0.90
is_int16_rprimitiveFunction · 0.90

Tested by

no test coverage detected