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

Method compile

crates/jit/src/instructions.rs:207–300  ·  view source on GitHub ↗
(
        &mut self,
        func_ref: FuncRef,
        bytecode: &CodeObject<C>,
    )

Source from the content-addressed store, hash-verified

205 }
206
207 pub fn compile<C: bytecode::Constant>(
208 &mut self,
209 func_ref: FuncRef,
210 bytecode: &CodeObject<C>,
211 ) -> Result<(), JitCompileError> {
212 // JIT should consume a stable instruction stream: de-specialized opcodes
213 // with zeroed CACHE entries, not runtime-mutated quickened code.
214 let clean_instructions: bytecode::CodeUnits = bytecode
215 .instructions
216 .original_bytes()
217 .as_slice()
218 .try_into()
219 .map_err(|_| JitCompileError::BadBytecode)?;
220
221 let mut label_targets = BTreeSet::new();
222 let mut target_arg_state = OpArgState::default();
223 for (offset, &raw_instr) in clean_instructions.iter().enumerate() {
224 let (instruction, arg) = target_arg_state.get(raw_instr);
225 if let Some(target) = Self::instruction_target(offset as u32, instruction, arg)? {
226 label_targets.insert(target);
227 }
228 }
229 let mut arg_state = OpArgState::default();
230
231 // Track whether we have "returned" in the current block
232 let mut in_unreachable_code = false;
233
234 for (offset, &raw_instr) in clean_instructions.iter().enumerate() {
235 let label = Label::from_u32(offset as u32);
236 let (instruction, arg) = arg_state.get(raw_instr);
237
238 // If this is a label that some earlier jump can target,
239 // treat it as the start of a new reachable block:
240 if label_targets.contains(&label) {
241 // Create or get the block for this label:
242 let target_block = self.get_or_create_block(label);
243
244 // If the current block isn't terminated, add a fallthrough jump
245 if let Some(cur) = self.builder.current_block()
246 && cur != target_block
247 {
248 // Check if the block needs a terminator by examining the last instruction
249 let needs_terminator = match self.builder.func.layout.last_inst(cur) {
250 None => true, // Empty block needs terminator
251 Some(inst) => {
252 // Check if the last instruction is a terminator
253 !self.builder.func.dfg.insts[inst].opcode().is_terminator()
254 }
255 };
256 if needs_terminator {
257 self.builder.ins().jump(target_block, &[]);
258 }
259 }
260 // Switch to the target block
261 if self.builder.current_block() != Some(target_block) {
262 self.builder.switch_to_block(target_block);
263 }
264

Callers 1

build_functionMethod · 0.45

Calls 15

newFunction · 0.85
original_bytesMethod · 0.80
get_or_create_blockMethod · 0.80
current_blockMethod · 0.80
jumpMethod · 0.80
insMethod · 0.80
switch_to_blockMethod · 0.80
add_instructionMethod · 0.80
SomeClass · 0.50
as_sliceMethod · 0.45
iterMethod · 0.45
getMethod · 0.45

Tested by

no test coverage detected