Compile function body and create function object = compiler_function_body
(
&mut self,
name: &str,
parameters: &ast::Parameters,
body: &[ast::Stmt],
is_async: bool,
funcflags: bytecode::MakeFunctionFlags,
)
| 4047 | /// Compile function body and create function object |
| 4048 | // = compiler_function_body |
| 4049 | fn compile_function_body( |
| 4050 | &mut self, |
| 4051 | name: &str, |
| 4052 | parameters: &ast::Parameters, |
| 4053 | body: &[ast::Stmt], |
| 4054 | is_async: bool, |
| 4055 | funcflags: bytecode::MakeFunctionFlags, |
| 4056 | ) -> CompileResult<()> { |
| 4057 | // Save source range so MAKE_FUNCTION gets the `def` line, not the body's last line |
| 4058 | let saved_range = self.current_source_range; |
| 4059 | |
| 4060 | // Always enter function scope |
| 4061 | self.enter_function(name, parameters)?; |
| 4062 | self.current_code_info() |
| 4063 | .flags |
| 4064 | .set(bytecode::CodeFlags::COROUTINE, is_async); |
| 4065 | |
| 4066 | // Set up context |
| 4067 | let prev_ctx = self.ctx; |
| 4068 | self.ctx = CompileContext { |
| 4069 | loop_data: None, |
| 4070 | in_class: prev_ctx.in_class, |
| 4071 | func: if is_async { |
| 4072 | FunctionContext::AsyncFunction |
| 4073 | } else { |
| 4074 | FunctionContext::Function |
| 4075 | }, |
| 4076 | // A function starts a new async scope only if it's async |
| 4077 | in_async_scope: is_async, |
| 4078 | }; |
| 4079 | |
| 4080 | // Set qualname |
| 4081 | self.set_qualname(); |
| 4082 | |
| 4083 | // PEP 479: Wrap generator/coroutine body with StopIteration handler |
| 4084 | let is_gen = is_async || self.current_symbol_table().is_generator; |
| 4085 | let stop_iteration_block = if is_gen { |
| 4086 | let handler_block = self.new_block(); |
| 4087 | emit!( |
| 4088 | self, |
| 4089 | PseudoInstruction::SetupCleanup { |
| 4090 | delta: handler_block |
| 4091 | } |
| 4092 | ); |
| 4093 | self.set_no_location(); |
| 4094 | self.push_fblock(FBlockType::StopIteration, handler_block, handler_block)?; |
| 4095 | Some(handler_block) |
| 4096 | } else { |
| 4097 | None |
| 4098 | }; |
| 4099 | |
| 4100 | // Handle docstring - store in co_consts[0] if present |
| 4101 | let (doc_str, body) = split_doc(body, &self.opts); |
| 4102 | if let Some(doc) = &doc_str { |
| 4103 | // Docstring present: store in co_consts[0] and set HAS_DOCSTRING flag |
| 4104 | self.current_code_info() |
| 4105 | .metadata |
| 4106 | .consts |
no test coverage detected