MCPcopy
hub / github.com/python/mypy / emit_method_call

Method emit_method_call

mypyc/codegen/emitfunc.py:599–643  ·  view source on GitHub ↗
(self, dest: str, op_obj: Value, name: str, op_args: list[Value])

Source from the content-addressed store, hash-verified

597 self.emit_method_call(dest, op.obj, op.method, op.args)
598
599 def emit_method_call(self, dest: str, op_obj: Value, name: str, op_args: list[Value]) -> None:
600 obj = self.reg(op_obj)
601 rtype = op_obj.type
602 assert isinstance(rtype, RInstance), rtype
603 class_ir = rtype.class_ir
604 # Use method_decl (not get_method) because under separate compilation the
605 # FuncIR body may live in a different group — only its declaration is
606 # visible here, and a decl is all we need to emit a direct C call
607 # (the symbol resolves through that group's exports table).
608 method_decl = rtype.class_ir.method_decl(name)
609
610 # Can we call the method directly, bypassing vtable? Non-extension classes
611 # don't have a vtable (compute_vtable is skipped for them), so the only
612 # way to dispatch is a direct C call.
613 is_direct = not class_ir.is_ext_class or class_ir.is_method_final(name)
614
615 # The first argument gets omitted for static methods and
616 # turned into the class for class methods
617 obj_args = (
618 []
619 if method_decl.kind == FUNC_STATICMETHOD
620 else [f"(PyObject *)Py_TYPE({obj})"] if method_decl.kind == FUNC_CLASSMETHOD else [obj]
621 )
622 args = ", ".join(obj_args + [self.reg(arg) for arg in op_args])
623 mtype = native_function_type_from_decl(method_decl, self.emitter)
624 version = "_TRAIT" if rtype.class_ir.is_trait else ""
625 if is_direct:
626 # Directly call method, without going through the vtable.
627 self.emit_line(f"{dest}{self.emitter.native_function_call(method_decl)}({args});")
628 else:
629 # Call using vtable.
630 method_idx = rtype.method_index(name)
631 self.emit_line(
632 "{}CPY_GET_METHOD{}({}, {}, {}, {}, {})({}); /* {} */".format(
633 dest,
634 version,
635 obj,
636 self.emitter.type_struct_name(rtype.class_ir),
637 method_idx,
638 rtype.struct_name(self.names),
639 mtype,
640 args,
641 name,
642 )
643 )
644
645 def visit_inc_ref(self, op: IncRef) -> None:
646 if (

Callers 2

visit_get_attrMethod · 0.95
visit_method_callMethod · 0.95

Calls 12

regMethod · 0.95
emit_lineMethod · 0.95
isinstanceFunction · 0.85
method_declMethod · 0.80
is_method_finalMethod · 0.80
native_function_callMethod · 0.80
method_indexMethod · 0.80
type_struct_nameMethod · 0.80
joinMethod · 0.45
formatMethod · 0.45
struct_nameMethod · 0.45

Tested by

no test coverage detected