MCPcopy Index your code
hub / github.com/RustPython/RustPython / compile_call

Method compile_call

crates/codegen/src/compile.rs:8448–8523  ·  view source on GitHub ↗
(&mut self, func: &ast::Expr, args: &ast::Arguments)

Source from the content-addressed store, hash-verified

8446 }
8447
8448 fn compile_call(&mut self, func: &ast::Expr, args: &ast::Arguments) -> CompileResult<()> {
8449 // Save the call expression's source range so CALL instructions use the
8450 // call start line, not the last argument's line.
8451 let call_range = self.current_source_range;
8452 let uses_ex_call = self.call_uses_ex_call(args);
8453
8454 // Method call: obj → LOAD_ATTR_METHOD → [method, self_or_null] → args → CALL
8455 // Regular call: func → PUSH_NULL → args → CALL
8456 if let ast::Expr::Attribute(ast::ExprAttribute { value, attr, .. }) = &func {
8457 // Check for super() method call optimization
8458 if !uses_ex_call
8459 && let Some(super_type) = self.can_optimize_super_call(value, attr.as_str())
8460 {
8461 // super().method() or super(cls, self).method() optimization
8462 // Stack: [global_super, class, self] → LOAD_SUPER_METHOD → [method, self]
8463 // Set source range to the super() call for LOAD_GLOBAL/LOAD_DEREF/etc.
8464 let super_range = value.range();
8465 self.set_source_range(super_range);
8466 self.load_args_for_super(&super_type)?;
8467 self.set_source_range(super_range);
8468 let idx = self.name(attr.as_str());
8469 match super_type {
8470 SuperCallType::TwoArg { .. } => {
8471 self.emit_load_super_method(idx);
8472 }
8473 SuperCallType::ZeroArg => {
8474 self.emit_load_zero_super_method(idx);
8475 }
8476 }
8477 // NOP for line tracking at .method( line
8478 self.set_source_range(attr.range());
8479 emit!(self, Instruction::Nop);
8480 // CALL at .method( line (not the full expression line)
8481 self.codegen_call_helper(0, args, attr.range())?;
8482 } else {
8483 self.compile_expression(value)?;
8484 let idx = self.name(attr.as_str());
8485 // Imported names and CALL_FUNCTION_EX-style calls use plain
8486 // LOAD_ATTR + PUSH_NULL; other names use method-call mode.
8487 // Check current scope and enclosing scopes for IMPORTED flag.
8488 let is_import = matches!(value.as_ref(), ast::Expr::Name(ast::ExprName { id, .. })
8489 if self.is_name_imported(id.as_str()));
8490 if is_import || uses_ex_call {
8491 self.emit_load_attr(idx);
8492 emit!(self, Instruction::PushNull);
8493 } else {
8494 self.emit_load_attr_method(idx);
8495 }
8496 self.codegen_call_helper(0, args, call_range)?;
8497 }
8498 } else if let Some(kind) = (!uses_ex_call)
8499 .then(|| self.detect_builtin_generator_call(func, args))
8500 .flatten()
8501 {
8502 // Optimized builtin(genexpr) path: compile the genexpr only once
8503 // so its code object appears exactly once in co_consts.
8504 let end = self.new_block();
8505 self.compile_expression(func)?;

Callers 1

compile_expressionMethod · 0.80

Calls 15

call_uses_ex_callMethod · 0.80
set_source_rangeMethod · 0.80
load_args_for_superMethod · 0.80
codegen_call_helperMethod · 0.80
compile_expressionMethod · 0.80
emit_load_attrMethod · 0.80
emit_load_attr_methodMethod · 0.80
new_blockMethod · 0.80

Tested by

no test coverage detected