1use std::fmt;
5use std::process;
6
7use erg_common::cache::CacheSet;
8use erg_common::config::ErgConfig;
9use erg_common::env::erg_core_path;
10use erg_common::error::{ErrorDisplay, Location};
11use erg_common::fresh::SharedFreshNameGenerator;
12use erg_common::io::Input;
13use erg_common::opcode::{CommonOpcode, CompareOp};
14use erg_common::opcode308::Opcode308;
15use erg_common::opcode309::Opcode309;
16use erg_common::opcode310::Opcode310;
17use erg_common::opcode311::{BinOpCode, Opcode311};
18use erg_common::option_enum_unwrap;
19use erg_common::python_util::{env_python_version, PythonVersion};
20use erg_common::traits::{Locational, Stream};
21use erg_common::Str;
22use erg_common::{
23 debug_power_assert, fmt_option, fn_name, fn_name_full, impl_stream, log, set,
24 switch_unreachable,
25};
26use erg_parser::ast::VisModifierSpec;
27use erg_parser::ast::{DefId, DefKind};
28use CommonOpcode::*;
29
30use erg_parser::ast::{ParamPattern, TypeBoundSpecs, VarName};
31use erg_parser::token::DOT;
32use erg_parser::token::EQUAL;
33use erg_parser::token::{Token, TokenKind};
34
35use crate::compile::{AccessKind, Name, StoreLoadKind};
36use crate::context::ControlKind;
37use crate::error::CompileError;
38use crate::hir::DefaultParamSignature;
39use crate::hir::GlobSignature;
40use crate::hir::ListWithLength;
41use crate::hir::{
42 Accessor, Args, BinOp, Block, Call, ClassDef, Def, DefBody, Dict, Expr, GuardClause,
43 Identifier, Lambda, List, Literal, NonDefaultParamSignature, Params, PatchDef, PosArg, ReDef,
44 Record, Set, Signature, SubrSignature, Tuple, UnaryOp, VarSignature, HIR,
45};
46use crate::ty::codeobj::{CodeObj, CodeObjFlags, MakeFunctionFlags};
47use crate::ty::value::{GenTypeObj, ValueObj};
48use crate::ty::SubrType;
49use crate::ty::{HasType, Type, TypeCode, TypePair, VisibilityModifier};
50use crate::varinfo::VarInfo;
51use AccessKind::*;
52use Type::*;
53
54#[derive(Debug)]
55pub enum RegisterNameKind {
56 Import,
57 Fast,
58 NonFast,
59}
60
61use RegisterNameKind::*;
62
63impl RegisterNameKind {
64 pub const fn is_fast(&self) -> bool {
65 matches!(self, Fast)
66 }
67
68 pub fn from_ident(ident: &Identifier) -> Self {
69 if ident.vi.is_fast_value() {
70 Fast
71 } else {
72 NonFast
73 }
74 }
75}
76
77fn debind(ident: &Identifier) -> Option<Str> {
80 match ident.vi.py_name.as_ref().map(|s| &s[..]) {
81 Some(name) if name.starts_with("Function::") => {
82 Some(Str::from(name.replace("Function::", "")))
83 }
84 Some(patch_method) if patch_method.contains("::") || patch_method.contains('.') => {
85 Some(Str::rc(patch_method))
86 }
87 _ => None,
88 }
89}
90
91fn escape_name(
92 name: &str,
93 vis: &VisibilityModifier,
94 def_line: u32,
95 def_col: u32,
96 is_attr: bool,
97) -> Str {
98 let name = name.replace('!', "__erg_proc__");
99 let name = name.replace('$', "__erg_shared__");
100 if vis.is_private() && !name.starts_with('%') {
103 if is_attr {
104 return Str::from(format!("::{name}"));
105 }
106 let line_mangling = match (def_line, def_col) {
107 (0, 0) => "".to_string(),
108 (0, _) => format!("_C{def_col}"),
109 (_, 0) => format!("_L{def_line}"),
110 (_, _) => format!("_L{def_line}_C{def_col}"),
111 };
112 Str::from(format!("::{name}{line_mangling}"))
113 } else {
114 Str::from(name)
115 }
116}
117
118fn escape_ident(ident: Identifier) -> Str {
119 let vis = ident.vis();
120 if &ident.inspect()[..] == "Self" {
121 let ty = ident
123 .vi
124 .t
125 .singleton_value()
126 .and_then(|tp| <&Type>::try_from(tp).ok())
127 .or_else(|| ident.vi.t.return_t())
128 .unwrap();
129 escape_name(
130 &ty.local_name(),
131 &ident.vi.vis.modifier,
132 ident.vi.def_loc.loc.ln_begin().unwrap_or(0),
133 ident.vi.def_loc.loc.col_begin().unwrap_or(0),
134 ident.vi.kind.is_instance_attr(),
135 )
136 } else if let Some(py_name) = ident.vi.py_name {
137 py_name
138 } else if ident.vi.is_parameter() || ident.inspect() == "self" {
139 ident.inspect().clone()
140 } else {
141 escape_name(
142 ident.inspect(),
143 vis,
144 ident.vi.def_loc.loc.ln_begin().unwrap_or(0),
145 ident.vi.def_loc.loc.col_begin().unwrap_or(0),
146 ident.vi.kind.is_instance_attr(),
147 )
148 }
149}
150
151#[derive(Debug, Clone)]
152pub struct PyCodeGenUnit {
153 pub(crate) id: usize,
154 pub(crate) py_version: PythonVersion,
155 pub(crate) codeobj: CodeObj,
156 pub(crate) captured_vars: Vec<Str>,
157 pub(crate) stack_len: u32, pub(crate) prev_lineno: u32,
159 pub(crate) lasti: usize,
160 pub(crate) prev_lasti: usize,
161 pub(crate) _refs: Vec<ValueObj>, }
163
164impl PartialEq for PyCodeGenUnit {
165 #[inline]
166 fn eq(&self, other: &Self) -> bool {
167 self.id == other.id
168 }
169}
170
171impl fmt::Display for PyCodeGenUnit {
172 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
173 write!(
174 f,
175 "CompilerUnit{{\nid: {}\ncode:\n{}\n}}",
176 self.id,
177 self.codeobj.code_info(Some(self.py_version))
178 )
179 }
180}
181
182impl PyCodeGenUnit {
183 #[allow(clippy::too_many_arguments)]
184 pub fn new<S: Into<Str>, T: Into<Str>>(
185 id: usize,
186 py_version: PythonVersion,
187 params: Vec<Str>,
188 kwonlyargcount: u32,
189 filename: S,
190 name: T,
191 firstlineno: u32,
192 flags: u32,
193 ) -> Self {
194 Self {
195 id,
196 py_version,
197 codeobj: CodeObj::empty(params, kwonlyargcount, filename, name, firstlineno, flags),
198 captured_vars: vec![],
199 stack_len: 0,
200 prev_lineno: firstlineno,
201 lasti: 0,
202 prev_lasti: 0,
203 _refs: vec![],
204 }
205 }
206}
207
208#[derive(Debug, Clone)]
209pub struct PyCodeGenStack(Vec<PyCodeGenUnit>);
210
211impl_stream!(PyCodeGenStack, PyCodeGenUnit);
212
213#[derive(Debug, Default)]
214pub struct PyCodeGenerator {
215 pub(crate) cfg: ErgConfig,
216 pub(crate) py_version: PythonVersion,
217 str_cache: CacheSet<str>,
218 prelude_loaded: bool,
219 mutate_op_loaded: bool,
220 contains_op_loaded: bool,
221 record_type_loaded: bool,
222 module_type_loaded: bool,
223 control_loaded: bool,
224 convertors_loaded: bool,
225 traits_loaded: bool,
226 operators_loaded: bool,
227 union_loaded: bool,
228 fake_generic_loaded: bool,
229 abc_loaded: bool,
230 builtins_loaded: bool,
231 unit_size: usize,
232 units: PyCodeGenStack,
233 fresh_gen: SharedFreshNameGenerator,
234}
235
236impl PyCodeGenerator {
237 pub fn new(cfg: ErgConfig) -> Self {
238 Self {
239 py_version: cfg.target_version.unwrap_or_else(|| {
240 let Some(version) = env_python_version() else {
241 panic!("Failed to get python version");
242 };
243 version
244 }),
245 cfg,
246 str_cache: CacheSet::new(),
247 prelude_loaded: false,
248 mutate_op_loaded: false,
249 contains_op_loaded: false,
250 record_type_loaded: false,
251 module_type_loaded: false,
252 control_loaded: false,
253 convertors_loaded: false,
254 traits_loaded: false,
255 operators_loaded: false,
256 union_loaded: false,
257 fake_generic_loaded: false,
258 abc_loaded: false,
259 builtins_loaded: false,
260 unit_size: 0,
261 units: PyCodeGenStack::empty(),
262 fresh_gen: SharedFreshNameGenerator::new("codegen"),
263 }
264 }
265
266 pub fn inherit(&self) -> Self {
267 Self {
268 cfg: self.cfg.clone(),
269 py_version: self.py_version,
270 str_cache: self.str_cache.clone(),
271 prelude_loaded: false,
272 mutate_op_loaded: false,
273 contains_op_loaded: false,
274 record_type_loaded: false,
275 module_type_loaded: false,
276 control_loaded: false,
277 convertors_loaded: false,
278 traits_loaded: false,
279 operators_loaded: false,
280 union_loaded: false,
281 fake_generic_loaded: false,
282 abc_loaded: false,
283 builtins_loaded: false,
284 unit_size: 0,
285 units: PyCodeGenStack::empty(),
286 fresh_gen: self.fresh_gen.clone(),
287 }
288 }
289
290 pub fn clear(&mut self) {
291 self.units.clear();
292 }
293
294 pub fn set_input(&mut self, input: Input) {
295 self.cfg.input = input;
296 }
297
298 pub fn initialize(&mut self) {
299 self.prelude_loaded = false;
300 self.mutate_op_loaded = false;
301 self.contains_op_loaded = false;
302 self.record_type_loaded = false;
303 self.module_type_loaded = false;
304 self.control_loaded = false;
305 self.convertors_loaded = false;
306 self.traits_loaded = false;
307 self.operators_loaded = false;
308 self.union_loaded = false;
309 self.fake_generic_loaded = false;
310 self.abc_loaded = false;
311 self.builtins_loaded = false;
312 }
313
314 #[inline]
315 fn input(&self) -> &Input {
316 &self.cfg.input
317 }
318
319 fn get_cached(&self, s: &str) -> Str {
320 self.str_cache.get(s)
321 }
322
323 #[inline]
324 fn toplevel_block(&self) -> &PyCodeGenUnit {
325 self.units.first().unwrap()
326 }
327
328 #[inline]
329 fn cur_block(&self) -> &PyCodeGenUnit {
330 self.units.last().unwrap()
331 }
332
333 fn is_toplevel(&self) -> bool {
334 self.cur_block() == self.toplevel_block()
335 }
336
337 fn captured_vars(&self) -> Vec<&str> {
338 let mut caps = vec![];
339 for unit in self.units.iter() {
340 caps.extend(unit.captured_vars.iter().map(|s| &**s));
341 }
342 caps
343 }
344
345 #[inline]
346 fn mut_cur_block(&mut self) -> &mut PyCodeGenUnit {
347 self.units.last_mut().unwrap()
348 }
349
350 #[inline]
351 fn cur_block_codeobj(&self) -> &CodeObj {
352 &self.cur_block().codeobj
353 }
354
355 #[inline]
356 fn mut_cur_block_codeobj(&mut self) -> &mut CodeObj {
357 &mut self.mut_cur_block().codeobj
358 }
359
360 #[inline]
361 fn toplevel_block_codeobj(&self) -> &CodeObj {
362 &self.toplevel_block().codeobj
363 }
364
365 #[inline]
366 fn stack_len(&self) -> u32 {
367 self.cur_block().stack_len
368 }
369
370 #[inline]
371 fn lasti(&self) -> usize {
372 self.cur_block().lasti
373 }
374
375 #[inline]
376 #[allow(dead_code)]
377 fn debug_print(&mut self, value: impl Into<ValueObj>) {
378 self.emit_load_const(value);
379 self.emit_print_expr();
380 }
381
382 #[inline]
383 #[allow(dead_code)]
384 fn emit_print_expr(&mut self) {
385 self.write_instr(Opcode311::PRINT_EXPR);
386 self.write_arg(0);
387 self.stack_dec();
388 }
389
390 fn _emit_compare_op(&mut self, op: CompareOp) {
391 self.write_instr(Opcode311::COMPARE_OP);
392 self.write_arg(op as usize);
393 self.stack_dec();
394 if self.py_version.minor >= Some(11) {
395 self.write_bytes(&[0; 4]);
396 }
397 }
398
399 #[allow(unused)]
401 fn terminate(&mut self) {
402 self.emit_push_null();
403 self.emit_load_name_instr(Identifier::static_public("exit"));
404 self.emit_load_const(1);
405 if self.py_version.minor >= Some(11) {
406 self.emit_precall_and_call(1);
407 } else {
408 self.write_instr(Opcode310::CALL_FUNCTION);
409 self.write_arg(1);
410 }
411 self.stack_dec();
412 }
413
414 #[allow(unused)]
416 fn rot2(&mut self) {
417 if self.py_version.minor >= Some(11) {
418 self.write_instr(Opcode311::SWAP);
419 self.write_arg(2);
420 } else {
421 self.write_instr(Opcode310::ROT_TWO);
422 self.write_arg(0);
423 }
424 }
425
426 #[allow(unused)]
427 fn dup_top(&mut self) {
428 if self.py_version.minor >= Some(11) {
429 self.write_instr(Opcode311::COPY);
430 self.write_arg(1);
431 } else {
432 self.write_instr(Opcode310::DUP_TOP);
433 self.write_arg(0);
434 }
435 self.stack_inc();
436 }
437
438 fn copy(&mut self, i: usize) {
440 debug_power_assert!(i, >, 0);
441 if self.py_version.minor >= Some(11) {
442 self.write_instr(Opcode311::COPY);
443 self.write_arg(i);
444 } else if i == 1 {
445 self.write_instr(Opcode310::DUP_TOP);
446 self.write_arg(0);
447 } else {
448 todo!()
449 }
450 self.stack_inc();
451 }
452
453 #[allow(dead_code)]
455 fn peek_stack(&mut self, i: usize) {
456 self.copy(i + 1);
457 self.emit_print_expr();
458 }
459
460 fn fill_jump(&mut self, idx: usize, jump_to: usize) {
461 let arg = if self.py_version.minor >= Some(10) {
462 jump_to / 2
463 } else {
464 jump_to
465 };
466 let bytes = u16::try_from(arg).unwrap().to_be_bytes();
467 *self.mut_cur_block_codeobj().code.get_mut(idx).unwrap() = bytes[0];
468 *self.mut_cur_block_codeobj().code.get_mut(idx + 2).unwrap() = bytes[1];
469 }
470
471 fn calc_edit_jump(&mut self, idx: usize, jump_to: usize) -> usize {
473 let arg = if self.py_version.minor >= Some(10) {
474 jump_to / 2
475 } else {
476 jump_to
477 };
478 if idx == 0
479 || !CommonOpcode::is_jump_op(*self.cur_block_codeobj().code.get(idx - 1).unwrap())
480 {
481 self.crash(&format!("calc_edit_jump: not jump op: {idx} {jump_to}"));
482 }
483 self.edit_code(idx, arg)
484 }
485
486 #[inline]
488 fn edit_code(&mut self, idx: usize, arg: usize) -> usize {
489 log!(err "editing: {idx} {arg}");
490 match u8::try_from(arg) {
491 Ok(u8code) => {
492 *self.mut_cur_block_codeobj().code.get_mut(idx).unwrap() = u8code;
493 0
494 }
495 Err(_e) => {
496 let bytes = u32::try_from(arg).unwrap().to_be_bytes();
499 let before_instr = idx.saturating_sub(1);
500 *self.mut_cur_block_codeobj().code.get_mut(idx).unwrap() = bytes[3];
501 self.extend_arg(before_instr, &bytes)
502 }
503 }
504 }
505
506 #[inline]
515 fn extend_arg(&mut self, before_instr: usize, bytes: &[u8]) -> usize {
516 let mut shift_bytes = 0;
517 for byte in bytes.iter().rev().skip(1) {
518 self.mut_cur_block_codeobj()
519 .code
520 .insert(before_instr, *byte);
521 self.mut_cur_block_codeobj()
522 .code
523 .insert(before_instr, CommonOpcode::EXTENDED_ARG as u8);
524 self.mut_cur_block().lasti += 2;
525 shift_bytes += 2;
526 }
527 shift_bytes
528 }
529
530 fn write_instr<C: Into<u8>>(&mut self, code: C) {
531 self.mut_cur_block_codeobj().code.push(code.into());
532 self.mut_cur_block().lasti += 1;
533 }
535
536 fn write_arg(&mut self, code: usize) -> usize {
538 match u8::try_from(code) {
539 Ok(u8code) => {
540 self.mut_cur_block_codeobj().code.push(u8code);
541 self.mut_cur_block().lasti += 1;
542 1
543 }
544 Err(_) => match u16::try_from(code) {
545 Ok(_) => {
546 let delta =
547 if CommonOpcode::is_jump_op(*self.cur_block_codeobj().code.last().unwrap())
548 {
549 2
550 } else {
551 0
552 };
553 let arg = code + delta;
554 let bytes = u16::try_from(arg).unwrap().to_be_bytes(); let before_instr = self.lasti().saturating_sub(1);
556 self.mut_cur_block_codeobj().code.push(bytes[1]);
557 self.mut_cur_block().lasti += 1;
558 self.extend_arg(before_instr, &bytes) + 1
559 }
560 Err(_) => {
561 let delta = 0;
562 if CommonOpcode::is_jump_op(*self.cur_block_codeobj().code.last().unwrap()) {
563 6
564 } else {
565 0
566 };
567 let arg = code + delta;
568 let bytes = u32::try_from(arg).unwrap().to_be_bytes(); let before_instr = self.lasti().saturating_sub(1);
570 self.mut_cur_block_codeobj().code.push(bytes[3]);
571 self.mut_cur_block().lasti += 1;
572 self.extend_arg(before_instr, &bytes) + 1
573 }
574 },
575 }
576 }
577
578 fn write_bytes(&mut self, bytes: &[u8]) {
579 self.mut_cur_block_codeobj().code.extend_from_slice(bytes);
580 self.mut_cur_block().lasti += bytes.len();
581 }
582
583 fn stack_inc(&mut self) {
584 self.mut_cur_block().stack_len += 1;
585 if self.stack_len() > self.cur_block_codeobj().stacksize {
586 self.mut_cur_block_codeobj().stacksize = self.stack_len();
587 }
588 }
589
590 fn stack_dec(&mut self) {
591 if self.stack_len() == 0 {
592 let lasti = self.lasti();
593 let last = self.cur_block_codeobj().code.last().unwrap();
594 self.crash(&format!(
595 "the stack size becomes -1\nlasti: {lasti}\nlast code: {last}"
596 ));
597 } else {
598 self.mut_cur_block().stack_len -= 1;
599 }
600 }
601
602 fn stack_inc_n(&mut self, n: usize) {
605 self.mut_cur_block().stack_len += n as u32;
606 if self.stack_len() > self.cur_block_codeobj().stacksize {
607 self.mut_cur_block_codeobj().stacksize = self.stack_len();
608 }
609 }
610
611 fn stack_dec_n(&mut self, n: usize) {
612 if n as u32 > self.stack_len() {
613 let lasti = self.lasti();
614 let last = self.cur_block_codeobj().code.last().unwrap();
615 self.crash(&format!(
616 "the stack size becomes -1\nlasti: {lasti}\nlast code: {last}"
617 ));
618 } else {
619 self.mut_cur_block().stack_len -= n as u32;
620 }
621 }
622
623 fn emit_load_const<C: Into<ValueObj>>(&mut self, cons: C) {
624 let value: ValueObj = cons.into();
625 let idx = self
626 .mut_cur_block_codeobj()
627 .consts
628 .iter()
629 .position(|c| c == &value)
630 .unwrap_or_else(|| {
631 self.mut_cur_block_codeobj().consts.push(value);
632 self.mut_cur_block_codeobj().consts.len() - 1
633 });
634 self.write_instr(LOAD_CONST);
635 self.write_arg(idx);
636 self.stack_inc();
637 }
638
639 fn register_const<C: Into<ValueObj>>(&mut self, cons: C) -> usize {
640 let value = cons.into();
641 self.mut_cur_block_codeobj()
642 .consts
643 .iter()
644 .position(|c| c == &value)
645 .unwrap_or_else(|| {
646 self.mut_cur_block_codeobj().consts.push(value);
647 self.mut_cur_block_codeobj().consts.len() - 1
648 })
649 }
650
651 fn local_search(&self, name: &str, acc_kind: AccessKind) -> Option<Name> {
652 if self.py_version.minor < Some(11) {
653 if let Some(idx) = self
654 .cur_block_codeobj()
655 .cellvars
656 .iter()
657 .position(|v| &**v == name)
658 {
659 return Some(Name::deref(idx));
660 }
661 }
662 match acc_kind {
663 AccessKind::Name => {
664 if let Some(idx) = self
665 .cur_block_codeobj()
666 .freevars
667 .iter()
668 .position(|f| &**f == name)
669 {
670 Some(Name::deref(idx))
671 } else if let Some(idx) = self
672 .cur_block_codeobj()
673 .varnames
674 .iter()
675 .position(|v| &**v == name)
676 {
677 if self.captured_vars().contains(&name) {
678 None
679 } else {
680 Some(Name::fast(idx))
681 }
682 } else if let Some(idx) = self
683 .cur_block_codeobj()
684 .names
685 .iter()
686 .position(|n| &**n == name)
687 {
688 if !self.is_toplevel() {
689 None
690 } else {
691 Some(Name::local(idx))
692 }
693 } else {
694 None
695 }
696 }
697 _ => self
698 .cur_block_codeobj()
699 .names
700 .iter()
701 .position(|n| &**n == name)
702 .map(Name::local),
703 }
704 }
705
706 fn rec_search(&mut self, name: &str) -> Option<StoreLoadKind> {
708 for (nth_from_toplevel, block) in self.units.iter_mut().enumerate().rev().skip(1) {
710 let block_is_toplevel = nth_from_toplevel == 0;
711 if block.codeobj.cellvars.iter().any(|c| &**c == name) {
712 return Some(StoreLoadKind::Deref);
713 } else if let Some(idx) = block.codeobj.varnames.iter().position(|v| &**v == name) {
714 if block_is_toplevel {
715 return Some(StoreLoadKind::Global);
716 } else {
717 let cellvar_name = block.codeobj.varnames.get(idx).unwrap().clone();
719 block.codeobj.cellvars.push(cellvar_name);
720 return Some(StoreLoadKind::Deref);
721 }
722 }
723 if block_is_toplevel && block.codeobj.names.iter().any(|n| &**n == name) {
724 return Some(StoreLoadKind::Global);
725 }
726 }
727 Some(StoreLoadKind::Global)
729 }
730
731 fn register_name(&mut self, name: Str, kind: RegisterNameKind) -> Name {
732 let current_is_toplevel = self.is_toplevel();
733 match self.rec_search(&name) {
734 Some(st @ (StoreLoadKind::Local | StoreLoadKind::Global)) => {
735 if kind.is_fast() {
736 self.mut_cur_block_codeobj().varnames.push(name);
737 Name::fast(self.cur_block_codeobj().varnames.len() - 1)
738 } else {
739 let st = if current_is_toplevel {
740 StoreLoadKind::Local
741 } else {
742 st
743 };
744 self.mut_cur_block_codeobj().names.push(name);
745 Name::new(st, self.cur_block_codeobj().names.len() - 1)
746 }
747 }
748 Some(StoreLoadKind::Deref) => {
749 self.mut_cur_block_codeobj().freevars.push(name.clone());
750 if self.py_version.minor >= Some(11) {
751 self.mut_cur_block_codeobj().varnames.push(name);
753 Name::deref(self.cur_block_codeobj().varnames.len() - 1)
754 } else {
755 Name::deref(self.cur_block_codeobj().freevars.len() - 1)
757 }
758 }
759 None => {
760 if current_is_toplevel {
762 self.mut_cur_block_codeobj().names.push(name);
763 Name::local(self.cur_block_codeobj().names.len() - 1)
764 } else {
765 self.mut_cur_block_codeobj().varnames.push(name);
766 Name::fast(self.cur_block_codeobj().varnames.len() - 1)
767 }
768 }
769 Some(_) => {
770 switch_unreachable!()
771 }
772 }
773 }
774
775 fn register_attr(&mut self, name: Str) -> Name {
776 self.mut_cur_block_codeobj().names.push(name);
777 Name::local(self.cur_block_codeobj().names.len() - 1)
778 }
779
780 fn register_method(&mut self, name: Str) -> Name {
781 self.mut_cur_block_codeobj().names.push(name);
782 Name::local(self.cur_block_codeobj().names.len() - 1)
783 }
784
785 fn select_load_instr(&self, kind: StoreLoadKind, acc_kind: AccessKind) -> u8 {
786 match kind {
787 StoreLoadKind::Fast | StoreLoadKind::FastConst => LOAD_FAST as u8,
788 StoreLoadKind::Global | StoreLoadKind::GlobalConst => LOAD_NAME as u8, StoreLoadKind::Deref | StoreLoadKind::DerefConst => {
790 if self.py_version.minor >= Some(11) {
791 Opcode311::LOAD_DEREF as u8
792 } else {
793 Opcode310::LOAD_DEREF as u8
794 }
795 }
796 StoreLoadKind::Local | StoreLoadKind::LocalConst => match acc_kind {
797 Name => LOAD_NAME as u8,
798 UnboundAttr => LOAD_ATTR as u8,
799 BoundAttr => LOAD_METHOD as u8,
800 },
801 }
802 }
803
804 fn select_store_instr(&self, kind: StoreLoadKind, acc_kind: AccessKind) -> u8 {
805 match kind {
806 StoreLoadKind::Fast => STORE_FAST as u8,
807 StoreLoadKind::FastConst => STORE_FAST as u8, StoreLoadKind::Global | StoreLoadKind::GlobalConst => STORE_NAME as u8,
811 StoreLoadKind::Deref | StoreLoadKind::DerefConst => {
812 if self.py_version.minor >= Some(11) {
813 Opcode311::STORE_DEREF as u8
814 } else {
815 Opcode310::STORE_DEREF as u8
816 }
817 }
818 StoreLoadKind::Local | StoreLoadKind::LocalConst => {
819 match acc_kind {
820 Name => STORE_NAME as u8,
821 UnboundAttr => STORE_ATTR as u8,
822 BoundAttr => STORE_ATTR as u8,
824 }
825 }
826 }
827 }
828
829 fn emit_load_name_instr(&mut self, ident: Identifier) {
830 log!(info "entered {}({ident})", fn_name!());
831 if &ident.inspect()[..] == "#ModuleType" && !self.module_type_loaded {
832 self.load_module_type();
833 self.module_type_loaded = true;
834 }
835 let kind = RegisterNameKind::from_ident(&ident);
836 let escaped = escape_ident(ident);
837 match &escaped[..] {
838 "if__" | "for__" | "while__" | "with__" | "discard__" | "assert__" => {
839 self.load_control();
840 }
841 "int__" | "nat__" | "str__" | "float__" => {
842 self.load_convertors();
843 }
844 "add" | "sub" | "mul" | "truediv" | "floordiv" | "mod" | "pow" | "eq" | "ne" | "lt"
845 | "le" | "gt" | "ge" | "and_" | "or_" | "xor" | "lshift" | "rshift" | "pos" | "neg"
846 | "invert" | "is_" | "is_not" | "call" => {
847 self.load_operators();
848 }
849 "Eq" | "Ord" | "Hash" | "Add" | "Sub" | "Mul" | "Div" | "Pos" | "Neg" => {
850 self.load_traits();
851 }
852 "CodeType" => {
853 self.emit_global_import_items(
854 Identifier::static_public("types"),
855 vec![(Identifier::static_public("CodeType"), None)],
856 );
857 }
858 "NoneType" => {
860 self.emit_push_null();
861 self.emit_load_name_instr(Identifier::static_public("type"));
862 let none = Expr::Literal(Literal::new(ValueObj::None, Token::DUMMY));
863 let args = Args::single(PosArg::new(none));
864 self.emit_args_311(args, AccessKind::Name);
865 return;
866 }
867 "list_iterator" => {
868 let list = Expr::Literal(Literal::new(ValueObj::List(vec![].into()), Token::DUMMY));
869 let iter = Identifier::static_public("iter");
870 let iter_call = iter.call(Args::single(PosArg::new(list)));
871 let typ = Identifier::static_public("type");
872 let typ_call = typ.call(Args::single(PosArg::new(iter_call.into())));
873 self.emit_call(typ_call);
874 return;
875 }
876 "set_iterator" => {
877 let set = Expr::Set(Set::empty());
878 let iter = Identifier::static_public("iter");
879 let iter_call = iter.call(Args::single(PosArg::new(set)));
880 let typ = Identifier::static_public("type");
881 let typ_call = typ.call(Args::single(PosArg::new(iter_call.into())));
882 self.emit_call(typ_call);
883 return;
884 }
885 "dict_items" => {
886 let dict = Expr::Dict(Dict::empty());
887 let items = Identifier::static_public("iter");
888 let items_call = items.call(Args::single(PosArg::new(dict)));
889 let typ = Identifier::static_public("type");
890 let typ_call = typ.call(Args::single(PosArg::new(items_call.into())));
891 self.emit_call(typ_call);
892 return;
893 }
894 "dict_keys" => {
895 let dict = Expr::Dict(Dict::empty());
896 let keys = Identifier::static_public("keys");
897 let keys_call = dict.method_call(keys, Args::empty());
898 let typ = Identifier::static_public("type");
899 let typ_call = typ.call(Args::single(PosArg::new(keys_call.into())));
900 self.emit_call(typ_call);
901 return;
902 }
903 "dict_values" => {
904 let dict = Expr::Dict(Dict::empty());
905 let values = Identifier::static_public("values");
906 let values_call = dict.method_call(values, Args::empty());
907 let typ = Identifier::static_public("type");
908 let typ_call = typ.call(Args::single(PosArg::new(values_call.into())));
909 self.emit_call(typ_call);
910 return;
911 }
912 _ => {}
913 }
914 let name = self
915 .local_search(&escaped, Name)
916 .unwrap_or_else(|| self.register_name(escaped, kind));
917 let instr = self.select_load_instr(name.kind, Name);
918 self.write_instr(instr);
919 self.write_arg(name.idx);
920 self.stack_inc();
921 self.mut_cur_block_codeobj().stacksize += 2;
922 if instr == LOAD_GLOBAL as u8 && self.py_version.minor >= Some(11) {
923 self.write_bytes(&[0; 2]);
924 self.write_bytes(&[0; 8]);
925 }
926 }
927
928 fn emit_load_global_instr(&mut self, ident: Identifier) {
929 log!(info "entered {} ({ident})", fn_name!());
930 let escaped = escape_ident(ident);
931 let name = self
932 .local_search(&escaped, Name)
933 .unwrap_or_else(|| self.register_name(escaped, NonFast));
934 let instr = LOAD_GLOBAL;
935 self.write_instr(instr);
936 self.write_arg(name.idx);
937 self.stack_inc();
938 }
939
940 fn emit_import_name_instr(&mut self, ident: Identifier, items_len: usize) {
941 log!(info "entered {}({ident})", fn_name!());
942 let escaped = escape_ident(ident);
943 let name = self
944 .local_search(&escaped, Name)
945 .unwrap_or_else(|| self.register_name(escaped, Import));
946 self.write_instr(IMPORT_NAME);
947 self.write_arg(name.idx);
948 self.stack_inc_n(items_len);
949 self.stack_dec(); }
951
952 fn emit_import_from_instr(&mut self, ident: Identifier) {
953 log!(info "entered {}", fn_name!());
954 let escaped = escape_ident(ident);
955 let name = self
956 .local_search(&escaped, Name)
957 .unwrap_or_else(|| self.register_name(escaped, Import));
958 self.write_instr(IMPORT_FROM);
959 self.write_arg(name.idx);
960 }
962
963 fn emit_import_all_instr(&mut self, ident: Identifier) {
964 log!(info "entered {}", fn_name!());
965 self.emit_load_const(0i32); self.emit_load_const([Str::ever("*")]);
967 let escaped = escape_ident(ident);
968 let name = self
969 .local_search(&escaped, Name)
970 .unwrap_or_else(|| self.register_name(escaped, Import));
971 self.write_instr(IMPORT_NAME);
972 self.write_arg(name.idx);
973 self.stack_inc();
974 self.write_instr(IMPORT_STAR);
975 self.write_arg(0);
976 self.stack_dec_n(3);
977 }
978
979 fn emit_global_import_items(
981 &mut self,
982 module: Identifier,
983 items: Vec<(Identifier, Option<Identifier>)>,
984 ) {
985 self.emit_load_const(0);
986 let item_name_tuple = items
987 .iter()
988 .map(|ident| ValueObj::Str(ident.0.inspect().clone()))
989 .collect::<Vec<_>>();
990 let items_len = item_name_tuple.len();
991 self.emit_load_const(item_name_tuple);
992 self.emit_import_name_instr(module, items_len);
993 for (item, renamed) in items.into_iter() {
994 if let Some(renamed) = renamed {
995 self.emit_import_from_instr(item);
996 self.emit_store_global_instr(renamed);
997 } else {
998 self.emit_import_from_instr(item.clone());
999 self.emit_store_global_instr(item);
1000 }
1001 }
1002 self.emit_pop_top(); }
1004
1005 fn emit_load_attr_instr(&mut self, ident: Identifier) {
1006 log!(info "entered {} ({ident})", fn_name!());
1007 let escaped = escape_ident(ident);
1008 let name = self
1009 .local_search(&escaped, UnboundAttr)
1010 .unwrap_or_else(|| self.register_attr(escaped));
1011 let instr = self.select_load_instr(name.kind, UnboundAttr);
1012 self.write_instr(instr);
1013 self.write_arg(name.idx);
1014 if self.py_version.minor >= Some(11) {
1015 self.write_bytes(&[0; 8]);
1016 }
1017 }
1018
1019 fn emit_load_method_instr(&mut self, ident: Identifier, acc_kind: AccessKind) {
1020 log!(info "entered {} ({ident})", fn_name!());
1021 let escaped = escape_ident(ident);
1022 let name = self
1023 .local_search(&escaped, acc_kind)
1024 .unwrap_or_else(|| self.register_method(escaped));
1025 let instr = self.select_load_instr(name.kind, acc_kind);
1026 self.write_instr(instr);
1027 self.write_arg(name.idx);
1028 if self.py_version.minor >= Some(11) {
1029 self.stack_inc(); self.write_bytes(&[0; 20]);
1031 }
1032 }
1033
1034 fn emit_store_instr(&mut self, ident: Identifier, acc_kind: AccessKind) {
1035 log!(info "entered {} ({ident})", fn_name!());
1036 let kind = RegisterNameKind::from_ident(&ident);
1037 let escaped = escape_ident(ident);
1038 let name = self.local_search(&escaped, acc_kind).unwrap_or_else(|| {
1039 if acc_kind.is_local() {
1040 self.register_name(escaped, kind)
1041 } else {
1042 self.register_attr(escaped)
1043 }
1044 });
1045 let instr = self.select_store_instr(name.kind, acc_kind);
1046 self.write_instr(instr);
1047 self.write_arg(name.idx);
1048 self.stack_dec();
1049 if instr == STORE_ATTR as u8 {
1050 if self.py_version.minor >= Some(11) {
1051 self.write_bytes(&[0; 8]);
1052 }
1053 self.stack_dec();
1054 } else if instr == STORE_FAST as u8 {
1055 self.mut_cur_block_codeobj().nlocals += 1;
1056 }
1057 }
1058
1059 fn emit_store_global_instr(&mut self, ident: Identifier) {
1062 log!(info "entered {} ({ident})", fn_name!());
1063 let escaped = escape_ident(ident);
1064 let name = self
1065 .local_search(&escaped, Name)
1066 .unwrap_or_else(|| self.register_name(escaped, NonFast));
1067 let instr = STORE_GLOBAL;
1068 self.write_instr(instr);
1069 self.write_arg(name.idx);
1070 self.stack_dec();
1071 }
1072
1073 fn store_acc(&mut self, acc: Accessor) {
1076 log!(info "entered {} ({acc})", fn_name!());
1077 match acc {
1078 Accessor::Ident(ident) => {
1079 self.emit_store_instr(ident, Name);
1080 }
1081 Accessor::Attr(attr) => {
1082 self.emit_expr(*attr.obj);
1083 self.emit_store_instr(attr.ident, UnboundAttr);
1084 }
1085 }
1086 }
1087
1088 fn emit_pop_top(&mut self) {
1089 self.write_instr(POP_TOP);
1090 self.write_arg(0);
1091 self.stack_dec();
1092 }
1093
1094 fn cancel_if_pop_top(&mut self) {
1095 if self.cur_block_codeobj().code.len() < 2 {
1096 return;
1097 }
1098 let lasop_t_idx = self.cur_block_codeobj().code.len() - 2;
1099 if self.cur_block_codeobj().code.get(lasop_t_idx) == Some(&(POP_TOP as u8)) {
1100 self.mut_cur_block_codeobj().code.pop();
1101 self.mut_cur_block_codeobj().code.pop();
1102 self.mut_cur_block().lasti -= 2;
1103 self.stack_inc();
1104 }
1105 }
1106
1107 #[track_caller]
1110 fn crash(&mut self, description: &str) -> ! {
1111 if cfg!(debug_assertions) || cfg!(feature = "debug") {
1112 println!("internal error: {description}");
1113 panic!("current block: {}", self.cur_block());
1114 } else {
1115 let err = CompileError::compiler_bug(
1116 0,
1117 self.input().clone(),
1118 Location::Unknown,
1119 fn_name!(),
1120 line!(),
1121 );
1122 err.write_to_stderr();
1123 process::exit(1);
1124 }
1125 }
1126
1127 fn gen_param_names(&self, params: &Params) -> Vec<Str> {
1128 params
1129 .non_defaults
1130 .iter()
1131 .map(|p| (p.inspect().map(|s| &s[..]).unwrap_or("_"), &p.vi))
1132 .chain(
1133 params
1134 .defaults
1135 .iter()
1136 .map(|p| (p.inspect().map(|s| &s[..]).unwrap_or("_"), &p.sig.vi)),
1137 )
1138 .chain(if let Some(var_args) = ¶ms.var_params {
1139 vec![(
1140 var_args.inspect().map(|s| &s[..]).unwrap_or("_"),
1141 &var_args.vi,
1142 )]
1143 } else {
1144 vec![]
1145 })
1146 .chain(if let Some(kw_var_args) = ¶ms.kw_var_params {
1147 vec![(
1148 kw_var_args.inspect().map(|s| &s[..]).unwrap_or("_"),
1149 &kw_var_args.vi,
1150 )]
1151 } else {
1152 vec![]
1153 })
1154 .enumerate()
1155 .map(|(i, (s, vi))| {
1156 if s == "_" {
1157 format!("_{i}")
1158 } else {
1159 escape_name(
1160 s,
1161 &VisibilityModifier::Public,
1162 vi.def_loc.loc.ln_begin().unwrap_or(0),
1163 vi.def_loc.loc.col_begin().unwrap_or(0),
1164 false,
1165 )
1166 .to_string()
1167 }
1168 })
1169 .map(|s| self.get_cached(&s))
1170 .collect()
1171 }
1172
1173 fn emit_acc(&mut self, acc: Accessor) {
1174 log!(info "entered {} ({acc})", fn_name!());
1175 let init_stack_len = self.stack_len();
1176 match acc {
1177 Accessor::Ident(ident) => {
1178 self.emit_load_name_instr(ident);
1179 }
1180 Accessor::Attr(mut a) => {
1181 let is_record = a.obj.ref_t().is_record();
1184 if is_record {
1185 a.ident.raw.vis = VisModifierSpec::Public(Location::Unknown);
1186 }
1187 if let Some(varname) = debind(&a.ident) {
1188 a.ident.raw.vis = VisModifierSpec::Private;
1189 a.ident.raw.name = VarName::from_str(varname);
1190 self.emit_load_name_instr(a.ident);
1191 } else {
1192 self.emit_expr(*a.obj);
1193 self.emit_load_attr_instr(a.ident);
1194 }
1195 }
1196 }
1197 debug_assert_eq!(self.stack_len(), init_stack_len + 1);
1198 }
1199
1200 fn emit_def(&mut self, def: Def) {
1201 log!(info "entered {} ({})", fn_name!(), def.sig);
1202 if def.def_kind().is_trait() {
1203 return self.emit_trait_def(def);
1204 }
1205 match def.sig {
1206 Signature::Subr(sig) => self.emit_subr_def(None, sig, def.body),
1207 Signature::Var(sig) => self.emit_var_def(sig, def.body),
1208 Signature::Glob(sig) => self.emit_glob_def(sig, def.body),
1209 }
1210 }
1211
1212 fn emit_push_null(&mut self) {
1213 if self.py_version.minor >= Some(11) {
1214 self.write_instr(Opcode311::PUSH_NULL);
1215 self.write_arg(0);
1216 self.stack_inc();
1217 }
1218 }
1219
1220 fn emit_precall_and_call(&mut self, argc: usize) {
1221 self.write_instr(Opcode311::PRECALL);
1222 self.write_arg(argc);
1223 self.write_arg(0);
1224 self.write_arg(0);
1225 self.write_instr(Opcode311::CALL);
1226 self.write_arg(argc);
1227 self.write_bytes(&[0; 8]);
1228 self.stack_dec();
1229 }
1230
1231 fn emit_call_instr(&mut self, argc: usize, kind: AccessKind) {
1232 if self.py_version.minor >= Some(11) {
1233 self.emit_precall_and_call(argc);
1234 } else {
1235 match kind {
1236 AccessKind::BoundAttr => self.write_instr(Opcode310::CALL_METHOD),
1237 _ => self.write_instr(Opcode310::CALL_FUNCTION),
1238 }
1239 self.write_arg(argc);
1240 }
1241 }
1242
1243 fn emit_call_kw_instr(&mut self, argc: usize, kws: Vec<ValueObj>) {
1244 if self.py_version.minor >= Some(11) {
1245 let idx = self.register_const(kws);
1246 self.write_instr(Opcode311::KW_NAMES);
1247 self.write_arg(idx);
1248 self.emit_precall_and_call(argc);
1249 } else {
1250 self.emit_load_const(kws);
1251 self.write_instr(Opcode310::CALL_FUNCTION_KW);
1252 self.write_arg(argc);
1253 }
1254 }
1255
1256 fn emit_trait_def(&mut self, def: Def) {
1257 if !self.abc_loaded {
1258 self.load_abc();
1259 self.abc_loaded = true;
1260 }
1261 self.emit_push_null();
1262 self.write_instr(LOAD_BUILD_CLASS);
1263 self.write_arg(0);
1264 self.stack_inc();
1265 let kind = def.def_kind();
1266 let code = self.emit_trait_block(kind, &def.sig, def.body.block);
1267 self.emit_load_const(code);
1268 if self.py_version.minor < Some(11) {
1269 self.emit_load_const(def.sig.ident().inspect().clone());
1270 } else {
1271 self.stack_inc();
1272 }
1273 self.write_instr(MAKE_FUNCTION);
1274 self.write_arg(0);
1275 self.emit_load_const(def.sig.ident().inspect().clone());
1276 self.emit_load_name_instr(Identifier::private("#ABCMeta"));
1277 let subclasses_len = 1;
1278 self.emit_call_kw_instr(2 + subclasses_len, vec![ValueObj::from("metaclass")]);
1279 let sum = if self.py_version.minor >= Some(11) {
1280 1 + 2 + subclasses_len
1281 } else {
1282 1 + 2 + 1 + subclasses_len
1283 };
1284 self.stack_dec_n(sum - 1);
1285 self.emit_store_instr(def.sig.into_ident(), Name);
1286 self.stack_dec();
1287 }
1288
1289 fn emit_trait_block(&mut self, kind: DefKind, sig: &Signature, mut block: Block) -> CodeObj {
1298 debug_assert!(kind.is_trait());
1299 let name = sig.ident().inspect().clone();
1300 let Expr::Call(mut trait_call) = block.remove(0) else {
1301 unreachable!()
1302 };
1303 let req = if let Some(Expr::Record(req)) = trait_call.args.remove_left_or_key("Requirement")
1304 {
1305 req.attrs.into_iter()
1306 } else {
1307 vec![].into_iter()
1308 };
1309 self.unit_size += 1;
1310 let firstlineno = block
1311 .get(0)
1312 .and_then(|def| def.ln_begin())
1313 .unwrap_or_else(|| sig.ln_begin().unwrap());
1314 self.units.push(PyCodeGenUnit::new(
1315 self.unit_size,
1316 self.py_version,
1317 vec![],
1318 0,
1319 Str::rc(self.cfg.input.enclosed_name()),
1320 &name,
1321 firstlineno,
1322 0,
1323 ));
1324 let mod_name = self.toplevel_block_codeobj().name.clone();
1325 self.emit_load_const(mod_name);
1326 self.emit_store_instr(Identifier::static_public("__module__"), Name);
1327 self.emit_load_const(name);
1328 self.emit_store_instr(Identifier::static_public("__qualname__"), Name);
1329 for def in req {
1330 self.emit_empty_func(
1331 Some(sig.ident().inspect()),
1332 def.sig.into_ident(),
1333 Some(Identifier::private("#abstractmethod")),
1334 );
1335 }
1336 self.emit_load_const(ValueObj::None);
1337 self.write_instr(RETURN_VALUE);
1338 self.write_arg(0);
1339 if self.stack_len() > 1 {
1340 let block_id = self.cur_block().id;
1341 let stack_len = self.stack_len();
1342 CompileError::stack_bug(
1343 self.input().clone(),
1344 Location::Unknown,
1345 stack_len,
1346 block_id,
1347 fn_name_full!(),
1348 )
1349 .write_to_stderr();
1350 self.crash("error in emit_trait_block: invalid stack size");
1351 }
1352 if !self.cur_block_codeobj().varnames.is_empty() {
1354 self.mut_cur_block_codeobj().flags += CodeObjFlags::NewLocals as u32;
1355 }
1356 let unit = self.units.pop().unwrap();
1358 if !self.units.is_empty() {
1359 let ld = unit.prev_lineno - self.cur_block().prev_lineno;
1360 if ld != 0 {
1361 if let Some(l) = self.mut_cur_block_codeobj().lnotab.last_mut() {
1362 *l += u8::try_from(ld).unwrap();
1363 }
1364 self.mut_cur_block().prev_lineno += ld;
1365 }
1366 }
1367 unit.codeobj
1368 }
1369
1370 fn emit_empty_func(
1371 &mut self,
1372 class_name: Option<&str>,
1373 ident: Identifier,
1374 deco: Option<Identifier>,
1375 ) {
1376 log!(info "entered {} ({ident})", fn_name!());
1377 self.emit_push_null();
1378 let deco_is_some = deco.is_some();
1379 if let Some(deco) = deco {
1380 self.emit_load_name_instr(deco);
1381 }
1382 let code = {
1383 self.unit_size += 1;
1384 self.units.push(PyCodeGenUnit::new(
1385 self.unit_size,
1386 self.py_version,
1387 vec![],
1388 0,
1389 Str::rc(self.cfg.input.enclosed_name()),
1390 ident.inspect(),
1391 ident.ln_begin().unwrap_or(0),
1392 0,
1393 ));
1394 self.emit_load_const(ValueObj::None);
1395 self.write_instr(RETURN_VALUE);
1396 self.write_arg(0);
1397 let unit = self.units.pop().unwrap();
1398 if !self.units.is_empty() {
1399 let ld = unit
1400 .prev_lineno
1401 .saturating_sub(self.cur_block().prev_lineno);
1402 if ld != 0 {
1403 if let Some(l) = self.mut_cur_block_codeobj().lnotab.last_mut() {
1404 *l += u8::try_from(ld).unwrap();
1405 }
1406 self.mut_cur_block().prev_lineno += ld;
1407 }
1408 }
1409 unit.codeobj
1410 };
1411 self.emit_load_const(code);
1412 if self.py_version.minor < Some(11) {
1413 if let Some(class) = class_name {
1414 self.emit_load_const(Str::from(format!("{class}.{}", ident.inspect())));
1415 } else {
1416 self.emit_load_const(ident.inspect().clone());
1417 }
1418 } else {
1419 self.stack_inc();
1420 }
1421 self.write_instr(MAKE_FUNCTION);
1422 self.write_arg(0);
1423 if deco_is_some {
1424 self.emit_call_instr(1, Name);
1425 self.stack_dec();
1426 }
1427 self.stack_dec();
1429 self.emit_store_instr(ident, Name);
1430 }
1431
1432 fn emit_class_def(&mut self, class_def: ClassDef) {
1433 log!(info "entered {} ({})", fn_name!(), class_def.sig);
1434 self.emit_push_null();
1435 let ident = class_def.sig.ident().clone();
1436 let require_or_sup = class_def.require_or_sup.clone().map(|x| *x);
1437 let obj = *class_def.obj.clone();
1438 self.write_instr(LOAD_BUILD_CLASS);
1439 self.write_arg(0);
1440 self.stack_inc();
1441 let code = self.emit_class_block(class_def);
1442 self.emit_load_const(code);
1443 if self.py_version.minor < Some(11) {
1444 self.emit_load_const(ident.inspect().clone());
1445 } else {
1446 self.stack_inc();
1447 }
1448 self.write_instr(MAKE_FUNCTION);
1449 self.write_arg(0);
1450 self.emit_load_const(ident.inspect().clone());
1451 let subclasses_len = self.emit_require_type(obj, require_or_sup);
1453 self.emit_call_instr(2 + subclasses_len, Name);
1454 self.stack_dec_n((1 + 2 + subclasses_len) - 1);
1455 self.emit_store_instr(ident, Name);
1456 self.stack_dec();
1457 }
1458
1459 fn emit_patch_def(&mut self, patch_def: PatchDef) {
1460 log!(info "entered {} ({})", fn_name!(), patch_def.sig);
1461 for def in patch_def.methods {
1462 let Expr::Def(mut def) = def else { todo!() };
1467 let namespace = self.cur_block_codeobj().name.trim_start_matches("::");
1468 let name = format!(
1469 "{}{}{}",
1470 namespace,
1471 patch_def.sig.ident().to_string_notype(),
1472 def.sig.ident().to_string_notype()
1473 );
1474 def.sig.ident_mut().raw.name = VarName::from_str(Str::from(name));
1475 def.sig.ident_mut().raw.vis = VisModifierSpec::Private;
1476 self.emit_def(def);
1477 }
1478 }
1479
1480 fn emit_require_type(&mut self, obj: GenTypeObj, require_or_sup: Option<Expr>) -> usize {
1486 log!(info "entered {} ({obj}, {})", fn_name!(), fmt_option!(require_or_sup));
1487 match obj {
1488 GenTypeObj::Class(_) => 0,
1489 GenTypeObj::Subclass(typ) => {
1490 let require_or_sup = require_or_sup.unwrap();
1491 let typ = if require_or_sup.is_acc() {
1492 require_or_sup
1493 } else {
1494 Expr::try_from_type(typ.sup.typ().derefine()).unwrap_or(require_or_sup)
1495 };
1496 self.emit_expr(typ);
1497 1 }
1499 _ => todo!(),
1500 }
1501 }
1502
1503 fn emit_redef(&mut self, redef: ReDef) {
1504 log!(info "entered {} ({redef})", fn_name!());
1505 self.emit_simple_block(redef.block);
1506 self.store_acc(redef.attr);
1507 }
1508
1509 fn emit_var_def(&mut self, sig: VarSignature, mut body: DefBody) {
1510 log!(info "entered {} ({sig} = {})", fn_name!(), body.block);
1511 if body.block.len() == 1 {
1512 self.emit_expr(body.block.remove(0));
1513 } else {
1514 self.emit_simple_block(body.block);
1515 }
1516 if sig.global {
1517 self.emit_store_global_instr(sig.ident);
1518 } else {
1519 self.emit_store_instr(sig.ident, Name);
1520 }
1521 }
1522
1523 fn emit_glob_def(&mut self, _sig: GlobSignature, _body: DefBody) {}
1524
1525 fn emit_params(
1528 &mut self,
1529 var_params: Option<&NonDefaultParamSignature>,
1530 defaults: Vec<DefaultParamSignature>,
1531 function_flag: &mut usize,
1532 ) {
1533 if var_params.is_some() && !defaults.is_empty() {
1534 let defaults_len = defaults.len();
1535 let names = defaults
1536 .iter()
1537 .map(|default| {
1538 escape_name(
1539 default.sig.inspect().map_or("_", |s| &s[..]),
1540 &VisibilityModifier::Public,
1541 0,
1542 0,
1543 false,
1544 )
1545 })
1546 .collect::<Vec<_>>();
1547 defaults
1548 .into_iter()
1549 .for_each(|default| self.emit_expr(default.default_val));
1550 self.emit_load_const(names);
1551 self.stack_dec();
1552 self.write_instr(BUILD_CONST_KEY_MAP);
1553 self.write_arg(defaults_len);
1554 self.stack_dec_n(defaults_len - 1);
1555 *function_flag += MakeFunctionFlags::KwDefaults as usize;
1556 } else if !defaults.is_empty() {
1557 let defaults_len = defaults.len();
1558 defaults
1559 .into_iter()
1560 .for_each(|default| self.emit_expr(default.default_val));
1561 self.write_instr(BUILD_TUPLE);
1562 self.write_arg(defaults_len);
1563 self.stack_dec_n(defaults_len - 1);
1564 *function_flag += MakeFunctionFlags::Defaults as usize;
1565 }
1566 }
1567
1568 fn emit_subr_def(&mut self, class_name: Option<&str>, sig: SubrSignature, body: DefBody) {
1569 log!(info "entered {} ({sig} = {})", fn_name!(), body.block);
1570 let name = sig.ident.inspect().clone();
1571 let mut make_function_flag = 0;
1572 let params = self.gen_param_names(&sig.params);
1573 let kwonlyargcount = if sig.params.var_params.is_some() {
1574 sig.params.defaults.len()
1575 } else {
1576 0
1577 };
1578 self.emit_params(
1579 sig.params.var_params.as_deref(),
1580 sig.params.defaults,
1581 &mut make_function_flag,
1582 );
1583 let mut flags = 0;
1584 if sig.params.var_params.is_some() {
1585 flags += CodeObjFlags::VarArgs as u32;
1586 }
1587 if sig.params.kw_var_params.is_some() {
1588 flags += CodeObjFlags::VarKeywords as u32;
1589 }
1590 let code = self.emit_block(
1591 body.block,
1592 sig.params.guards,
1593 Some(name.clone()),
1594 params,
1595 kwonlyargcount as u32,
1596 sig.captured_names.clone(),
1597 flags,
1598 );
1599 self.enclose_vars(&mut make_function_flag);
1601 let n_decos = sig.decorators.len();
1602 for deco in sig.decorators {
1603 self.emit_expr(deco);
1604 }
1605 self.rewrite_captured_fast(&code);
1606 self.emit_load_const(code);
1607 if self.py_version.minor < Some(11) {
1608 if let Some(class) = class_name {
1609 self.emit_load_const(Str::from(format!("{class}.{name}")));
1610 } else {
1611 self.emit_load_const(name);
1612 }
1613 } else {
1614 self.stack_inc();
1615 }
1616 self.write_instr(MAKE_FUNCTION);
1617 self.write_arg(make_function_flag);
1618 for _ in 0..n_decos {
1619 let argc = if self.py_version.minor >= Some(11) {
1620 0
1621 } else {
1622 self.stack_dec();
1623 1
1624 };
1625 self.emit_call_instr(argc, Name);
1626 }
1627 self.stack_dec();
1629 if make_function_flag
1630 & (MakeFunctionFlags::Defaults as usize | MakeFunctionFlags::KwDefaults as usize)
1631 != 0
1632 {
1633 self.stack_dec();
1634 }
1635 self.emit_store_instr(sig.ident, Name);
1636 }
1637
1638 fn emit_lambda(&mut self, lambda: Lambda) {
1639 log!(info "entered {} ({lambda})", fn_name!());
1640 let init_stack_len = self.stack_len();
1641 let mut make_function_flag = 0;
1642 let params = self.gen_param_names(&lambda.params);
1643 let kwonlyargcount = if lambda.params.var_params.is_some() {
1644 lambda.params.defaults.len()
1645 } else {
1646 0
1647 };
1648 self.emit_params(
1649 lambda.params.var_params.as_deref(),
1650 lambda.params.defaults,
1651 &mut make_function_flag,
1652 );
1653 let flags = if lambda.params.var_params.is_some() {
1654 CodeObjFlags::VarArgs as u32
1655 } else {
1656 0
1657 };
1658 let code = self.emit_block(
1659 lambda.body,
1660 lambda.params.guards,
1661 Some(format!("<lambda_{}>", lambda.id).into()),
1662 params,
1663 kwonlyargcount as u32,
1664 lambda.captured_names.clone(),
1665 flags,
1666 );
1667 self.enclose_vars(&mut make_function_flag);
1668 self.rewrite_captured_fast(&code);
1669 self.emit_load_const(code);
1670 if self.py_version.minor < Some(11) {
1671 self.emit_load_const(format!("<lambda_{}>", lambda.id));
1672 } else {
1673 self.stack_inc();
1674 }
1675 self.write_instr(MAKE_FUNCTION);
1676 self.write_arg(make_function_flag);
1677 self.stack_dec();
1679 if make_function_flag & MakeFunctionFlags::Defaults as usize != 0 {
1680 self.stack_dec();
1681 }
1682 debug_assert_eq!(self.stack_len(), init_stack_len + 1);
1683 }
1684
1685 fn enclose_vars(&mut self, flag: &mut usize) {
1686 if !self.cur_block_codeobj().cellvars.is_empty() {
1687 let cellvars_len = self.cur_block_codeobj().cellvars.len();
1688 let cellvars = self.cur_block_codeobj().cellvars.clone();
1689 for (i, name) in cellvars.iter().enumerate() {
1690 if self.py_version.minor >= Some(11) {
1692 let idx = self
1693 .cur_block_codeobj()
1694 .varnames
1695 .iter()
1696 .position(|n| n == name)
1697 .unwrap();
1698 self.write_instr(Opcode311::LOAD_CLOSURE);
1699 self.write_arg(idx);
1700 } else {
1701 self.write_instr(Opcode310::LOAD_CLOSURE);
1702 self.write_arg(i);
1703 }
1704 }
1705 self.write_instr(BUILD_TUPLE);
1706 self.write_arg(cellvars_len);
1707 *flag += MakeFunctionFlags::Closure as usize;
1708 }
1709 }
1710
1711 fn rewrite_captured_fast(&mut self, code: &CodeObj) {
1733 if self.py_version.minor >= Some(11) {
1734 return;
1735 }
1736 let cellvars = self.cur_block_codeobj().cellvars.clone();
1737 for cellvar in cellvars {
1738 if code.freevars.iter().any(|n| n == &cellvar) {
1739 let old_idx = self
1740 .cur_block_codeobj()
1741 .varnames
1742 .iter()
1743 .position(|n| n == &cellvar)
1744 .unwrap();
1745 let new_idx = self
1746 .cur_block_codeobj()
1747 .cellvars
1748 .iter()
1749 .position(|n| n == &cellvar)
1750 .unwrap();
1751 self.mut_cur_block().captured_vars.push(cellvar);
1752 let mut op_idx = 0;
1753 while let Some([op, arg]) = self
1754 .mut_cur_block_codeobj()
1755 .code
1756 .get_mut(op_idx..=op_idx + 1)
1757 {
1758 match Opcode310::try_from(*op) {
1759 Ok(Opcode310::LOAD_FAST) if *arg == old_idx as u8 => {
1760 *op = Opcode310::LOAD_DEREF as u8;
1761 *arg = new_idx as u8;
1762 }
1763 Ok(Opcode310::STORE_FAST) if *arg == old_idx as u8 => {
1764 *op = Opcode310::STORE_DEREF as u8;
1765 *arg = new_idx as u8;
1766 }
1767 _ => {}
1768 }
1769 op_idx += 2;
1770 }
1771 }
1772 }
1773 }
1774
1775 fn emit_unaryop(&mut self, unary: UnaryOp) {
1776 log!(info "entered {} ({unary})", fn_name!());
1777 let init_stack_len = self.stack_len();
1778 let val_t = unary
1779 .info
1780 .t
1781 .non_default_params()
1782 .and_then(|tys| tys.first().map(|pt| pt.typ()))
1783 .unwrap_or(Type::FAILURE);
1784 let tycode = TypeCode::from(val_t);
1785 let instr = match &unary.op.kind {
1786 TokenKind::PrePlus => UNARY_POSITIVE,
1788 TokenKind::PreMinus => UNARY_NEGATIVE,
1789 TokenKind::PreBitNot => UNARY_INVERT,
1790 TokenKind::Mutate => {
1791 if !self.mutate_op_loaded {
1792 self.load_mutate_op();
1793 }
1794 if self.py_version.minor >= Some(11) {
1795 self.emit_push_null();
1796 }
1797 self.emit_load_name_instr(Identifier::private("#mutate_operator"));
1798 NOP }
1800 _ => {
1801 CompileError::feature_error(
1802 self.cfg.input.clone(),
1803 line!() as usize,
1804 unary.op.loc(),
1805 &unary.op.inspect().clone(),
1806 String::from(unary.op.content),
1807 )
1808 .write_to_stderr();
1809 NOT_IMPLEMENTED
1810 }
1811 };
1812 self.emit_expr(*unary.expr);
1813 if instr != NOP {
1814 self.write_instr(instr);
1815 self.write_arg(tycode as usize);
1816 } else {
1817 if self.py_version.minor >= Some(11) {
1818 self.emit_precall_and_call(1);
1819 } else {
1820 self.write_instr(Opcode310::CALL_FUNCTION);
1821 self.write_arg(1);
1822 }
1823 self.stack_dec();
1824 }
1825 debug_assert_eq!(self.stack_len(), init_stack_len + 1);
1826 }
1827
1828 fn emit_binop(&mut self, bin: BinOp) {
1829 log!(info "entered {} ({bin})", fn_name!());
1830 let init_stack_len = self.stack_len();
1831 match &bin.op.kind {
1834 TokenKind::RightOpen => {
1836 self.emit_push_null();
1837 self.emit_load_name_instr(Identifier::static_public("RightOpenRange"));
1838 }
1839 TokenKind::LeftOpen => {
1840 self.emit_push_null();
1841 self.emit_load_name_instr(Identifier::static_public("LeftOpenRange"));
1842 }
1843 TokenKind::Closed => {
1844 self.emit_push_null();
1845 self.emit_load_name_instr(Identifier::static_public("ClosedRange"));
1846 }
1847 TokenKind::Open => {
1848 self.emit_push_null();
1849 self.emit_load_name_instr(Identifier::static_public("OpenRange"));
1850 }
1851 TokenKind::OrOp if bin.lhs.ref_t().is_type() => {
1854 self.load_union();
1855 let args = Args::pos_only(vec![PosArg::new(*bin.lhs), PosArg::new(*bin.rhs)], None);
1856 self.emit_push_null();
1857 self.emit_load_name_instr(Identifier::private("#UnionType"));
1858 self.emit_args_311(args, Name);
1859 return;
1860 }
1861 TokenKind::OrOp => {
1863 self.emit_expr(*bin.lhs);
1864 let idx = self.lasti();
1865 self.write_instr(EXTENDED_ARG);
1866 self.write_arg(0);
1867 self.write_instr(Opcode311::JUMP_IF_TRUE_OR_POP);
1868 self.write_arg(0);
1869 self.emit_expr(*bin.rhs);
1870 let arg = match self.py_version.minor {
1871 Some(11) => self.lasti() - idx - 4,
1872 _ => self.lasti(),
1873 };
1874 self.fill_jump(idx + 1, arg);
1875 self.stack_dec();
1876 return;
1877 }
1878 TokenKind::AndOp => {
1879 self.emit_expr(*bin.lhs);
1880 let idx = self.lasti();
1881 self.write_instr(EXTENDED_ARG);
1882 self.write_arg(0);
1883 self.write_instr(Opcode311::JUMP_IF_FALSE_OR_POP);
1884 self.write_arg(0);
1885 self.emit_expr(*bin.rhs);
1886 let arg = match self.py_version.minor {
1887 Some(11) => self.lasti() - idx - 4,
1888 _ => self.lasti(),
1889 };
1890 self.fill_jump(idx + 1, arg);
1891 self.stack_dec();
1892 return;
1893 }
1894 TokenKind::ContainsOp => {
1895 if self.cfg.no_std {
1897 self.emit_load_const(true);
1898 return;
1899 }
1900 if !self.contains_op_loaded {
1901 self.load_contains_op();
1902 }
1903 self.emit_push_null();
1904 self.emit_load_name_instr(Identifier::private("#contains_operator"));
1905 }
1906 _ => {}
1907 }
1908 let lhs_t = bin
1909 .info
1910 .t
1911 .non_default_params()
1912 .and_then(|tys| tys.first().map(|pt| pt.typ()))
1913 .unwrap_or(Type::FAILURE);
1914 let rhs_t = bin
1915 .info
1916 .t
1917 .non_default_params()
1918 .and_then(|tys| tys.get(1).map(|pt| pt.typ()))
1919 .unwrap_or(Type::FAILURE);
1920 let type_pair = TypePair::new(lhs_t, rhs_t);
1921 self.emit_expr(*bin.lhs);
1922 self.emit_expr(*bin.rhs);
1923 self.emit_binop_instr(bin.op, type_pair);
1924 debug_assert_eq!(self.stack_len(), init_stack_len + 1);
1925 }
1926
1927 fn emit_binop_instr(&mut self, binop: Token, type_pair: TypePair) {
1928 if self.py_version.minor >= Some(11) {
1929 self.emit_binop_instr_311(binop, type_pair);
1930 } else if self.py_version.minor >= Some(9) {
1931 self.emit_binop_instr_309(binop, type_pair);
1932 } else {
1933 self.emit_binop_instr_307(binop, type_pair);
1934 }
1935 }
1936
1937 fn emit_binop_instr_307(&mut self, binop: Token, type_pair: TypePair) {
1938 let instr = match &binop.kind {
1939 TokenKind::Plus => Opcode308::BINARY_ADD,
1940 TokenKind::Minus => Opcode308::BINARY_SUBTRACT,
1941 TokenKind::Star => Opcode308::BINARY_MULTIPLY,
1942 TokenKind::Slash => Opcode308::BINARY_TRUE_DIVIDE,
1943 TokenKind::FloorDiv => Opcode308::BINARY_FLOOR_DIVIDE,
1944 TokenKind::Pow => Opcode308::BINARY_POWER,
1945 TokenKind::Mod => Opcode308::BINARY_MODULO,
1946 TokenKind::AndOp | TokenKind::BitAnd => Opcode308::BINARY_AND,
1947 TokenKind::OrOp | TokenKind::BitOr => Opcode308::BINARY_OR,
1948 TokenKind::BitXor => Opcode308::BINARY_XOR,
1949 TokenKind::Less
1950 | TokenKind::LessEq
1951 | TokenKind::DblEq
1952 | TokenKind::NotEq
1953 | TokenKind::Gre
1954 | TokenKind::GreEq
1955 | TokenKind::InOp
1956 | TokenKind::NotInOp
1957 | TokenKind::IsOp
1958 | TokenKind::IsNotOp => Opcode308::COMPARE_OP,
1959 TokenKind::LeftOpen
1960 | TokenKind::RightOpen
1961 | TokenKind::Closed
1962 | TokenKind::Open
1963 | TokenKind::ContainsOp => Opcode308::CALL_FUNCTION, _ => {
1965 CompileError::feature_error(
1966 self.cfg.input.clone(),
1967 line!() as usize,
1968 binop.loc(),
1969 &binop.inspect().clone(),
1970 String::from(binop.content),
1971 )
1972 .write_to_stderr();
1973 Opcode308::NOT_IMPLEMENTED
1974 }
1975 };
1976 let arg = match &binop.kind {
1977 TokenKind::Less => 0,
1978 TokenKind::LessEq => 1,
1979 TokenKind::DblEq => 2,
1980 TokenKind::NotEq => 3,
1981 TokenKind::Gre => 4,
1982 TokenKind::GreEq => 5,
1983 TokenKind::InOp => 6,
1984 TokenKind::NotInOp => 7,
1985 TokenKind::IsOp => 8,
1986 TokenKind::IsNotOp => 9,
1987 TokenKind::LeftOpen
1988 | TokenKind::RightOpen
1989 | TokenKind::Closed
1990 | TokenKind::Open
1991 | TokenKind::ContainsOp => 2,
1992 _ => type_pair as usize,
1993 };
1994 self.write_instr(instr);
1995 self.write_arg(arg);
1996 self.stack_dec();
1997 match &binop.kind {
1998 TokenKind::LeftOpen
1999 | TokenKind::RightOpen
2000 | TokenKind::Open
2001 | TokenKind::Closed
2002 | TokenKind::ContainsOp => {
2003 self.stack_dec();
2004 }
2005 _ => {}
2006 }
2007 }
2008
2009 fn emit_binop_instr_309(&mut self, binop: Token, type_pair: TypePair) {
2010 let instr = match &binop.kind {
2011 TokenKind::Plus => Opcode309::BINARY_ADD,
2012 TokenKind::Minus => Opcode309::BINARY_SUBTRACT,
2013 TokenKind::Star => Opcode309::BINARY_MULTIPLY,
2014 TokenKind::Slash => Opcode309::BINARY_TRUE_DIVIDE,
2015 TokenKind::FloorDiv => Opcode309::BINARY_FLOOR_DIVIDE,
2016 TokenKind::Pow => Opcode309::BINARY_POWER,
2017 TokenKind::Mod => Opcode309::BINARY_MODULO,
2018 TokenKind::AndOp | TokenKind::BitAnd => Opcode309::BINARY_AND,
2019 TokenKind::OrOp | TokenKind::BitOr => Opcode309::BINARY_OR,
2020 TokenKind::BitXor => Opcode309::BINARY_XOR,
2021 TokenKind::IsOp | TokenKind::IsNotOp => Opcode309::IS_OP,
2022 TokenKind::Less
2023 | TokenKind::LessEq
2024 | TokenKind::DblEq
2025 | TokenKind::NotEq
2026 | TokenKind::Gre
2027 | TokenKind::GreEq => Opcode309::COMPARE_OP,
2028 TokenKind::LeftOpen
2029 | TokenKind::RightOpen
2030 | TokenKind::Closed
2031 | TokenKind::Open
2032 | TokenKind::ContainsOp => Opcode309::CALL_FUNCTION, _ => {
2034 CompileError::feature_error(
2035 self.cfg.input.clone(),
2036 line!() as usize,
2037 binop.loc(),
2038 &binop.inspect().clone(),
2039 String::from(binop.content),
2040 )
2041 .write_to_stderr();
2042 Opcode309::NOT_IMPLEMENTED
2043 }
2044 };
2045 let arg = match &binop.kind {
2046 TokenKind::Less => 0,
2047 TokenKind::LessEq => 1,
2048 TokenKind::DblEq => 2,
2049 TokenKind::NotEq => 3,
2050 TokenKind::Gre => 4,
2051 TokenKind::GreEq => 5,
2052 TokenKind::IsOp => 0,
2053 TokenKind::IsNotOp => 1,
2054 TokenKind::LeftOpen
2055 | TokenKind::RightOpen
2056 | TokenKind::Closed
2057 | TokenKind::Open
2058 | TokenKind::ContainsOp => 2,
2059 _ => type_pair as usize,
2060 };
2061 self.write_instr(instr);
2062 self.write_arg(arg);
2063 self.stack_dec();
2064 match &binop.kind {
2065 TokenKind::LeftOpen
2066 | TokenKind::RightOpen
2067 | TokenKind::Open
2068 | TokenKind::Closed
2069 | TokenKind::ContainsOp => {
2070 self.stack_dec();
2071 }
2072 _ => {}
2073 }
2074 }
2075
2076 fn emit_binop_instr_311(&mut self, binop: Token, type_pair: TypePair) {
2077 let instr = match &binop.kind {
2078 TokenKind::Plus
2079 | TokenKind::Minus
2080 | TokenKind::Star
2081 | TokenKind::Slash
2082 | TokenKind::FloorDiv
2083 | TokenKind::Pow
2084 | TokenKind::Mod
2085 | TokenKind::AndOp
2086 | TokenKind::OrOp
2087 | TokenKind::BitAnd
2088 | TokenKind::BitOr
2089 | TokenKind::BitXor => Opcode311::BINARY_OP,
2090 TokenKind::IsOp | TokenKind::IsNotOp => Opcode311::IS_OP,
2091 TokenKind::Less
2092 | TokenKind::LessEq
2093 | TokenKind::DblEq
2094 | TokenKind::NotEq
2095 | TokenKind::Gre
2096 | TokenKind::GreEq => Opcode311::COMPARE_OP,
2097 TokenKind::LeftOpen
2098 | TokenKind::RightOpen
2099 | TokenKind::Closed
2100 | TokenKind::Open
2101 | TokenKind::ContainsOp => {
2102 self.write_instr(Opcode311::PRECALL);
2103 self.write_arg(2);
2104 self.write_arg(0);
2105 self.write_arg(0);
2106 Opcode311::CALL
2107 }
2108 _ => {
2109 CompileError::feature_error(
2110 self.cfg.input.clone(),
2111 line!() as usize,
2112 binop.loc(),
2113 &binop.inspect().clone(),
2114 String::from(binop.content),
2115 )
2116 .write_to_stderr();
2117 Opcode311::NOT_IMPLEMENTED
2118 }
2119 };
2120 let arg = match &binop.kind {
2121 TokenKind::Plus => BinOpCode::Add as usize,
2122 TokenKind::Minus => BinOpCode::Subtract as usize,
2123 TokenKind::Star => BinOpCode::Multiply as usize,
2124 TokenKind::Slash => BinOpCode::TrueDivide as usize,
2125 TokenKind::FloorDiv => BinOpCode::FloorDiv as usize,
2126 TokenKind::Pow => BinOpCode::Power as usize,
2127 TokenKind::Mod => BinOpCode::Remainder as usize,
2128 TokenKind::AndOp | TokenKind::BitAnd => BinOpCode::And as usize,
2129 TokenKind::OrOp | TokenKind::BitOr => BinOpCode::Or as usize,
2130 TokenKind::BitXor => BinOpCode::Xor as usize,
2131 TokenKind::Less => 0,
2132 TokenKind::LessEq => 1,
2133 TokenKind::DblEq => 2,
2134 TokenKind::NotEq => 3,
2135 TokenKind::Gre => 4,
2136 TokenKind::GreEq => 5,
2137 TokenKind::IsOp => 0,
2138 TokenKind::IsNotOp => 1,
2139 TokenKind::LeftOpen
2140 | TokenKind::RightOpen
2141 | TokenKind::Closed
2142 | TokenKind::Open
2143 | TokenKind::ContainsOp => 2,
2144 _ => type_pair as usize,
2145 };
2146 self.write_instr(instr);
2147 self.write_arg(arg);
2148 match instr {
2149 Opcode311::CALL => {
2150 self.write_bytes(&[0; 8]);
2151 }
2152 Opcode311::BINARY_OP => {
2153 self.write_bytes(&[0; 2]);
2154 }
2155 Opcode311::COMPARE_OP => {
2156 self.write_bytes(&[0; 4]);
2157 }
2158 _ => {}
2159 }
2160 self.stack_dec();
2161 match &binop.kind {
2162 TokenKind::LeftOpen
2163 | TokenKind::RightOpen
2164 | TokenKind::Open
2165 | TokenKind::Closed
2166 | TokenKind::ContainsOp => {
2167 self.stack_dec();
2168 if self.py_version.minor >= Some(11) {
2169 self.stack_dec();
2170 }
2171 }
2172 _ => {}
2173 }
2174 }
2175
2176 fn emit_del_instr(&mut self, mut args: Args) {
2177 let Some(Expr::Accessor(Accessor::Ident(ident))) = args.remove_left_or_key("obj") else {
2178 log!(err "del instruction requires an identifier");
2179 return;
2180 };
2181 log!(info "entered {} ({ident})", fn_name!());
2182 let escaped = escape_ident(ident);
2183 let name = self
2184 .local_search(&escaped, Name)
2185 .unwrap_or_else(|| self.register_name(escaped, Fast));
2186 self.write_instr(DELETE_NAME);
2187 self.write_arg(name.idx);
2188 self.emit_load_const(ValueObj::None);
2189 }
2190
2191 fn emit_not_instr(&mut self, mut args: Args) {
2192 log!(info "entered {}", fn_name!());
2193 let expr = args.remove_left_or_key("b").unwrap();
2194 self.emit_expr(expr);
2195 self.write_instr(UNARY_NOT);
2196 self.write_arg(0);
2197 }
2198
2199 fn emit_discard_instr(&mut self, mut args: Args) {
2200 log!(info "entered {}", fn_name!());
2201 while let Some(arg) = args.try_remove(0) {
2202 self.emit_expr(arg);
2203 self.emit_pop_top();
2204 }
2205 self.emit_load_const(ValueObj::None);
2206 }
2207
2208 fn deopt_instr(&mut self, kind: ControlKind, args: Args) {
2209 if !self.control_loaded {
2210 self.load_control();
2211 }
2212 let local = match kind {
2213 ControlKind::If => Identifier::static_public("if__"),
2214 ControlKind::For => Identifier::static_public("for__"),
2215 ControlKind::While => Identifier::static_public("while__"),
2216 ControlKind::With => Identifier::static_public("with__"),
2217 ControlKind::Discard => Identifier::static_public("discard__"),
2218 ControlKind::Assert => Identifier::static_public("assert__"),
2219 kind => todo!("{kind:?}"),
2220 };
2221 self.emit_call_local(local, args);
2222 }
2223
2224 fn emit_if_instr(&mut self, mut args: Args) {
2225 log!(info "entered {}", fn_name!());
2226 let init_stack_len = self.stack_len();
2227 let cond = args.remove(0);
2228 self.emit_expr(cond);
2229 let idx_pop_jump_if_false = self.lasti();
2230 self.write_instr(EXTENDED_ARG);
2231 self.write_arg(0);
2232 self.write_instr(Opcode310::POP_JUMP_IF_FALSE);
2234 self.write_arg(0);
2236 match args.remove(0) {
2237 Expr::Lambda(lambda) => {
2239 self.emit_simple_block(lambda.body);
2241 }
2242 other => {
2243 self.emit_expr(other);
2244 }
2245 }
2246 if args.get(0).is_some() {
2247 let idx_jump_forward = self.lasti();
2248 self.write_instr(EXTENDED_ARG);
2249 self.write_arg(0);
2250 self.write_instr(Opcode308::JUMP_FORWARD); self.write_arg(0);
2252 let idx_else_begin = match self.py_version.minor {
2254 Some(11) => self.lasti() - idx_pop_jump_if_false - 4,
2255 Some(7..=10) => self.lasti(),
2256 _ => self.lasti(),
2257 };
2258 self.fill_jump(idx_pop_jump_if_false + 1, idx_else_begin);
2259 match args.remove(0) {
2260 Expr::Lambda(lambda) => {
2261 self.emit_simple_block(lambda.body);
2263 }
2264 other => {
2265 self.emit_expr(other);
2266 }
2267 }
2268 let idx_end = self.lasti();
2269 self.fill_jump(idx_jump_forward + 1, idx_end - idx_jump_forward - 2 - 1);
2270 while self.stack_len() != init_stack_len + 1 {
2272 self.stack_dec();
2273 }
2274 } else {
2275 self.write_instr(Opcode311::JUMP_FORWARD);
2276 let jump_to = match self.py_version.minor {
2277 Some(11 | 10) => 1,
2278 _ => 2,
2279 };
2280 self.write_arg(jump_to);
2281 let idx_end = if self.py_version.minor >= Some(11) {
2283 self.lasti() - idx_pop_jump_if_false - 3
2284 } else {
2285 self.lasti()
2286 };
2287 self.fill_jump(idx_pop_jump_if_false + 1, idx_end);
2288 self.emit_load_const(ValueObj::None);
2289 while self.stack_len() != init_stack_len + 1 {
2290 self.stack_dec();
2291 }
2292 }
2293 debug_assert_eq!(self.stack_len(), init_stack_len + 1);
2294 }
2295
2296 fn emit_for_instr(&mut self, mut args: Args) {
2297 log!(info "entered {} ({})", fn_name!(), args);
2298 if !matches!(args.get(1).unwrap(), Expr::Lambda(_)) {
2299 return self.deopt_instr(ControlKind::For, args);
2300 }
2301 let _init_stack_len = self.stack_len();
2302 let iterable = args.remove(0);
2303 self.emit_expr(iterable);
2304 self.write_instr(GET_ITER);
2305 self.write_arg(0);
2306 let idx_for_iter = self.lasti();
2307 self.write_instr(EXTENDED_ARG);
2308 self.write_arg(0);
2309 self.write_instr(FOR_ITER);
2310 self.stack_inc();
2311 self.write_arg(0);
2315 let Expr::Lambda(lambda) = args.remove(0) else {
2316 unreachable!()
2317 };
2318 let init_stack_len = self.stack_len();
2320 self.emit_control_block(lambda.body, lambda.params);
2322 if self.stack_len() > init_stack_len - 1 {
2323 self.emit_pop_top();
2324 }
2325 debug_assert_eq!(self.stack_len(), init_stack_len - 1); let idx = self.lasti();
2327 self.write_instr(EXTENDED_ARG);
2328 self.write_arg(0);
2329 match self.py_version.minor {
2330 Some(11) => {
2331 self.write_instr(Opcode311::JUMP_BACKWARD);
2332 self.write_arg(0);
2333 self.fill_jump(idx + 1, self.lasti() - idx_for_iter);
2334 }
2335 Some(7..=10) => {
2336 self.write_instr(Opcode309::JUMP_ABSOLUTE);
2337 self.write_arg(0);
2338 self.fill_jump(idx + 1, idx_for_iter);
2339 }
2340 _ => todo!("not supported Python version"),
2341 }
2342 let idx_end = self.lasti();
2343 self.fill_jump(idx_for_iter + 1, idx_end - idx_for_iter - 2 - 2);
2344 self.stack_dec();
2345 self.emit_load_const(ValueObj::None);
2346 debug_assert_eq!(self.stack_len(), _init_stack_len + 1);
2347 }
2348
2349 fn emit_while_instr(&mut self, mut args: Args) {
2350 log!(info "entered {} ({})", fn_name!(), args);
2351 if !matches!(args.get(1).unwrap(), Expr::Lambda(_)) {
2352 return self.deopt_instr(ControlKind::While, args);
2353 }
2354 let _init_stack_len = self.stack_len();
2355 let cond_block = args.remove(0);
2357 let cond = match cond_block {
2358 Expr::Lambda(mut lambda) => lambda.body.remove(0),
2359 Expr::Accessor(acc) => Expr::Accessor(acc).call_expr(Args::empty()),
2360 _ => todo!(),
2361 };
2362 self.emit_expr(cond.clone());
2364 let idx_while = self.lasti();
2365 self.write_instr(EXTENDED_ARG);
2366 self.write_arg(0);
2367 self.write_instr(Opcode310::POP_JUMP_IF_FALSE);
2368 self.write_arg(0);
2369 self.stack_dec();
2370 let Expr::Lambda(lambda) = args.remove(0) else {
2371 unreachable!()
2372 };
2373 let init_stack_len = self.stack_len();
2374 self.emit_control_block(lambda.body, lambda.params);
2375 if self.stack_len() > init_stack_len {
2376 self.emit_pop_top();
2377 }
2378 self.emit_expr(cond);
2379 let idx = self.lasti();
2380 self.write_instr(EXTENDED_ARG);
2381 self.write_arg(0);
2382 let arg = if self.py_version.minor >= Some(11) {
2383 let arg = self.lasti() - (idx_while + 2);
2384 self.write_instr(Opcode311::POP_JUMP_BACKWARD_IF_TRUE);
2385 self.write_arg(0);
2386 arg
2387 } else {
2388 self.write_instr(Opcode310::POP_JUMP_IF_TRUE);
2389 self.write_arg(0);
2390 idx_while + 4
2391 };
2392 self.fill_jump(idx + 1, arg);
2393 self.stack_dec();
2394 let idx_end = match self.py_version.minor {
2395 Some(11) => self.lasti() - idx_while - 3,
2396 _ => self.lasti(),
2397 };
2398 self.fill_jump(idx_while + 1, idx_end);
2399 self.emit_load_const(ValueObj::None);
2400 debug_assert_eq!(self.stack_len(), _init_stack_len + 1);
2401 }
2402
2403 fn emit_match_instr(&mut self, mut args: Args, _use_erg_specific: bool) {
2404 log!(info "entered {}", fn_name!());
2405 let init_stack_len = self.stack_len();
2406 let expr = args.remove(0);
2407 self.emit_expr(expr);
2408 let len = args.len();
2409 let mut jump_forward_points = vec![];
2410 while let Some(expr) = args.try_remove(0) {
2411 if len > 1 && !args.is_empty() {
2412 self.dup_top();
2413 }
2414 let Expr::Lambda(lambda) = expr else {
2416 unreachable!()
2417 };
2418 debug_power_assert!(lambda.params.len(), ==, 1);
2419 if !lambda.params.defaults.is_empty() {
2420 todo!("default values in match expression are not supported yet")
2421 }
2422 let pop_jump_points = self.emit_match_pattern(lambda.params, args.is_empty());
2423 self.emit_simple_block(lambda.body);
2424 self.stack_dec();
2427 for pop_jump_point in pop_jump_points {
2428 let idx = match self.py_version.minor {
2429 Some(11) => self.lasti() - pop_jump_point,
2430 Some(10) => self.lasti() + 4,
2431 _ => self.lasti() + 4,
2432 };
2433 self.fill_jump(pop_jump_point + 1, idx); }
2435 jump_forward_points.push(self.lasti());
2436 self.write_instr(EXTENDED_ARG);
2437 self.write_arg(0);
2438 self.write_instr(Opcode308::JUMP_FORWARD); self.write_arg(0);
2440 }
2441 let lasti = self.lasti();
2442 for jump_point in jump_forward_points.into_iter() {
2443 let jump_to = match self.py_version.minor {
2444 Some(11 | 10) => lasti - jump_point - 2 - 2,
2445 _ => lasti - jump_point - 2 - 2,
2446 };
2447 self.fill_jump(jump_point + 1, jump_to);
2448 }
2449 self.stack_inc();
2450 debug_assert_eq!(self.stack_len(), init_stack_len + 1);
2451 }
2452
2453 fn emit_match_pattern(&mut self, mut params: Params, is_last_arm: bool) -> Vec<usize> {
2455 let param = params.non_defaults.remove(0);
2456 log!(info "entered {}({param})", fn_name!());
2457 match ¶m.raw.pat {
2458 ParamPattern::VarName(name) => {
2459 let ident = erg_parser::ast::Identifier::private_from_varname(name.clone());
2460 let ident = Identifier::new(ident, None, param.vi);
2461 self.emit_store_instr(ident, AccessKind::Name);
2462 }
2463 ParamPattern::Discard(_) => {
2464 self.emit_pop_top();
2465 }
2466 _other => unreachable!(),
2467 }
2468 let mut pop_jump_points = vec![];
2469 let last = params.guards.len().saturating_sub(1);
2470 for (i, mut guard) in params.guards.into_iter().enumerate() {
2471 if let GuardClause::Condition(Expr::BinOp(BinOp {
2472 op:
2473 Token {
2474 kind: TokenKind::ContainsOp,
2475 ..
2476 },
2477 lhs,
2478 rhs,
2479 ..
2480 })) = &mut guard
2481 {
2482 if lhs.var_info().is_some_and(|vi| vi == &VarInfo::ILLEGAL) {
2485 continue;
2486 }
2487 if rhs.var_info().is_some_and(|vi| vi == &VarInfo::ILLEGAL) {
2488 continue;
2489 }
2490 *rhs.ref_mut_t().unwrap() = Type::Obj;
2492 }
2493 match guard {
2494 GuardClause::Bind(def) => {
2495 self.emit_def(def);
2496 }
2497 GuardClause::Condition(cond) => {
2498 self.emit_expr(cond);
2499 if is_last_arm {
2500 self.emit_pop_top();
2501 } else {
2502 pop_jump_points.push(self.lasti());
2503 self.write_instr(EXTENDED_ARG);
2507 self.write_arg(0);
2508 self.write_instr(Opcode310::POP_JUMP_IF_FALSE); self.write_arg(0);
2512 if i == last {
2514 self.emit_pop_top();
2515 } else {
2516 self.stack_dec();
2517 }
2518 }
2519 }
2520 }
2521 }
2522 pop_jump_points
2523 }
2524
2525 fn emit_with_instr_311(&mut self, mut args: Args) {
2526 log!(info "entered {}", fn_name!());
2527 if !matches!(args.get(1).unwrap(), Expr::Lambda(_)) {
2528 return self.deopt_instr(ControlKind::With, args);
2529 }
2530 let expr = args.remove(0);
2531 let Expr::Lambda(lambda) = args.remove(0) else {
2532 unreachable!()
2533 };
2534 let params = self.gen_param_names(&lambda.params);
2535 self.emit_expr(expr);
2536 self.write_instr(Opcode311::BEFORE_WITH);
2537 self.write_arg(0);
2538 self.stack_inc_n(2);
2540 let lambda_line = lambda.body.last().unwrap().ln_begin().unwrap_or(0);
2541 self.emit_with_block(lambda.body, params);
2542 let stash = Identifier::private_with_line(self.fresh_gen.fresh_varname(), lambda_line);
2543 self.emit_store_instr(stash.clone(), Name);
2544 self.emit_load_const(ValueObj::None);
2545 self.emit_load_const(ValueObj::None);
2546 self.emit_load_const(ValueObj::None);
2547 self.emit_precall_and_call(2);
2548 self.emit_pop_top();
2549 let idx_jump_forward = self.lasti();
2550 self.write_instr(Opcode311::JUMP_FORWARD);
2551 self.write_arg(0);
2552 self.write_instr(Opcode311::PUSH_EXC_INFO);
2553 self.write_arg(0);
2554 self.write_instr(Opcode309::WITH_EXCEPT_START);
2555 self.write_arg(0);
2556 self.write_instr(Opcode311::POP_JUMP_FORWARD_IF_TRUE);
2557 self.write_arg(4);
2558 self.write_instr(Opcode311::RERAISE);
2559 self.write_arg(0);
2560 self.write_instr(Opcode311::COPY);
2561 self.write_arg(3);
2562 self.write_instr(Opcode311::POP_EXCEPT);
2563 self.write_arg(0);
2564 self.write_instr(Opcode311::RERAISE);
2565 self.write_arg(1);
2566 self.emit_pop_top();
2567 self.write_instr(Opcode311::POP_EXCEPT);
2568 self.write_arg(0);
2569 self.emit_pop_top();
2570 self.emit_pop_top();
2571 self.calc_edit_jump(idx_jump_forward + 1, self.lasti() - idx_jump_forward - 2);
2572 self.emit_load_name_instr(stash);
2573 }
2574
2575 fn emit_with_instr_310(&mut self, mut args: Args) {
2576 log!(info "entered {}", fn_name!());
2577 if !matches!(args.get(1).unwrap(), Expr::Lambda(_)) {
2578 return self.deopt_instr(ControlKind::With, args);
2579 }
2580 let expr = args.remove(0);
2581 let Expr::Lambda(lambda) = args.remove(0) else {
2582 unreachable!()
2583 };
2584 let params = self.gen_param_names(&lambda.params);
2585 self.emit_expr(expr);
2586 let idx_setup_with = self.lasti();
2587 self.write_instr(Opcode310::SETUP_WITH);
2588 self.write_arg(0);
2589 self.stack_inc_n(2);
2591 let lambda_line = lambda.body.last().unwrap().ln_begin().unwrap_or(0);
2592 self.emit_with_block(lambda.body, params);
2593 let stash = Identifier::private_with_line(self.fresh_gen.fresh_varname(), lambda_line);
2594 self.emit_store_instr(stash.clone(), Name);
2595 self.write_instr(POP_BLOCK);
2596 self.write_arg(0);
2597 self.emit_load_const(ValueObj::None);
2598 self.write_instr(Opcode310::DUP_TOP);
2599 self.write_arg(0);
2600 self.stack_inc();
2601 self.write_instr(Opcode310::DUP_TOP);
2602 self.write_arg(0);
2603 self.stack_inc();
2604 self.write_instr(Opcode310::CALL_FUNCTION);
2605 self.write_arg(3);
2606 self.stack_dec_n((1 + 3) - 1);
2607 self.emit_pop_top();
2608 let idx_jump_forward = self.lasti();
2609 self.write_instr(Opcode310::JUMP_FORWARD);
2610 self.write_arg(0);
2611 self.edit_code(idx_setup_with + 1, (self.lasti() - idx_setup_with - 2) / 2);
2612 self.write_instr(Opcode310::WITH_EXCEPT_START);
2613 self.write_arg(0);
2614 let idx_pop_jump_if_true = self.lasti();
2615 self.write_instr(Opcode310::POP_JUMP_IF_TRUE);
2616 self.write_arg(0);
2617 self.write_instr(Opcode310::RERAISE);
2618 self.write_arg(1);
2619 self.edit_code(idx_pop_jump_if_true + 1, self.lasti() / 2);
2620 self.emit_pop_top();
2623 self.write_instr(Opcode310::POP_EXCEPT);
2624 self.write_arg(0);
2625 let idx_end = self.lasti();
2626 self.edit_code(idx_jump_forward + 1, (idx_end - idx_jump_forward - 2) / 2);
2627 self.emit_load_name_instr(stash);
2628 }
2629
2630 fn emit_with_instr_309(&mut self, mut args: Args) {
2631 log!(info "entered {}", fn_name!());
2632 if !matches!(args.get(1).unwrap(), Expr::Lambda(_)) {
2633 return self.deopt_instr(ControlKind::With, args);
2634 }
2635 let expr = args.remove(0);
2636 let Expr::Lambda(lambda) = args.remove(0) else {
2637 unreachable!()
2638 };
2639 let params = self.gen_param_names(&lambda.params);
2640 self.emit_expr(expr);
2641 let idx_setup_with = self.lasti();
2642 self.write_instr(Opcode310::SETUP_WITH);
2643 self.write_arg(0);
2644 self.stack_inc_n(2);
2646 let lambda_line = lambda.body.last().unwrap().ln_begin().unwrap_or(0);
2647 self.emit_with_block(lambda.body, params);
2648 let stash = Identifier::private_with_line(self.fresh_gen.fresh_varname(), lambda_line);
2649 self.emit_store_instr(stash.clone(), Name);
2650 self.write_instr(POP_BLOCK);
2651 self.write_arg(0);
2652 self.emit_load_const(ValueObj::None);
2653 self.write_instr(Opcode310::DUP_TOP);
2654 self.write_arg(0);
2655 self.stack_inc();
2656 self.write_instr(Opcode310::DUP_TOP);
2657 self.write_arg(0);
2658 self.stack_inc();
2659 self.write_instr(Opcode310::CALL_FUNCTION);
2660 self.write_arg(3);
2661 self.stack_dec_n((1 + 3) - 1);
2662 self.emit_pop_top();
2663 let idx_jump_forward = self.lasti();
2664 self.write_instr(Opcode311::JUMP_FORWARD);
2665 self.write_arg(0);
2666 self.edit_code(idx_setup_with + 1, self.lasti() - idx_setup_with - 2);
2667 self.write_instr(Opcode310::WITH_EXCEPT_START);
2668 self.write_arg(0);
2669 let idx_pop_jump_if_true = self.lasti();
2670 self.write_instr(Opcode310::POP_JUMP_IF_TRUE);
2671 self.write_arg(0);
2672 self.write_instr(Opcode309::RERAISE);
2673 self.write_arg(1);
2674 self.edit_code(idx_pop_jump_if_true + 1, self.lasti());
2675 self.emit_pop_top();
2678 self.write_instr(Opcode310::POP_EXCEPT);
2679 self.write_arg(0);
2680 let idx_end = self.lasti();
2681 self.edit_code(idx_jump_forward + 1, idx_end - idx_jump_forward - 2);
2682 self.emit_load_name_instr(stash);
2683 }
2684
2685 fn emit_with_instr_308(&mut self, mut args: Args) {
2686 log!(info "entered {}", fn_name!());
2687 if !matches!(args.get(1).unwrap(), Expr::Lambda(_)) {
2688 return self.deopt_instr(ControlKind::With, args);
2689 }
2690 let expr = args.remove(0);
2691 let Expr::Lambda(lambda) = args.remove(0) else {
2692 unreachable!()
2693 };
2694 let params = self.gen_param_names(&lambda.params);
2695 self.emit_expr(expr);
2696 let idx_setup_with = self.lasti();
2697 self.write_instr(Opcode309::SETUP_WITH);
2698 self.write_arg(0);
2699 let lambda_line = lambda.body.last().unwrap().ln_begin().unwrap_or(0);
2702 self.emit_with_block(lambda.body, params);
2703 let stash = Identifier::private_with_line(self.fresh_gen.fresh_varname(), lambda_line);
2704 self.emit_store_instr(stash.clone(), Name);
2705 self.write_instr(POP_BLOCK);
2706 self.write_arg(0);
2707 self.write_instr(Opcode308::BEGIN_FINALLY);
2708 self.write_arg(0);
2709 self.write_instr(Opcode308::WITH_CLEANUP_START);
2710 self.write_arg(0);
2711 self.edit_code(idx_setup_with + 1, (self.lasti() - idx_setup_with - 2) / 2);
2712 self.write_instr(Opcode308::WITH_CLEANUP_FINISH);
2713 self.write_arg(0);
2714 self.write_instr(Opcode308::END_FINALLY);
2715 self.write_arg(0);
2716 self.emit_load_name_instr(stash);
2717 }
2718
2719 fn emit_with_instr_307(&mut self, mut args: Args) {
2720 log!(info "entered {}", fn_name!());
2721 if !matches!(args.get(1).unwrap(), Expr::Lambda(_)) {
2722 return self.deopt_instr(ControlKind::With, args);
2723 }
2724 let expr = args.remove(0);
2725 let Expr::Lambda(lambda) = args.remove(0) else {
2726 unreachable!()
2727 };
2728 let params = self.gen_param_names(&lambda.params);
2729 self.emit_expr(expr);
2730 let idx_setup_with = self.lasti();
2731 self.write_instr(Opcode309::SETUP_WITH);
2732 self.write_arg(0);
2733 let lambda_line = lambda.body.last().unwrap().ln_begin().unwrap_or(0);
2736 self.emit_with_block(lambda.body, params);
2737 let stash = Identifier::private_with_line(self.fresh_gen.fresh_varname(), lambda_line);
2738 self.emit_store_instr(stash.clone(), Name);
2739 self.write_instr(POP_BLOCK);
2740 self.write_arg(0);
2741 self.emit_load_const(ValueObj::None);
2742 self.stack_dec();
2743 self.write_instr(Opcode308::WITH_CLEANUP_START);
2744 self.write_arg(0);
2745 self.edit_code(idx_setup_with + 1, (self.lasti() - idx_setup_with - 2) / 2);
2746 self.write_instr(Opcode308::WITH_CLEANUP_FINISH);
2747 self.write_arg(0);
2748 self.write_instr(Opcode308::END_FINALLY);
2749 self.write_arg(0);
2750 self.emit_load_name_instr(stash);
2751 }
2752
2753 fn emit_call(&mut self, call: Call) {
2754 log!(info "entered {} ({call})", fn_name!());
2755 let init_stack_len = self.stack_len();
2756 if let Some(attr_name) = call.attr_name {
2758 self.emit_call_method(*call.obj, attr_name, call.args);
2759 } else {
2760 match *call.obj {
2761 Expr::Accessor(Accessor::Ident(ident)) if ident.vis().is_private() => {
2762 self.emit_call_local(ident, call.args)
2763 }
2764 other if other.ref_t().is_poly_meta_type() => {
2765 self.emit_expr(other);
2766 self.emit_index_args(call.args);
2767 }
2768 other => {
2769 self.emit_push_null();
2770 self.emit_expr(other);
2771 self.emit_args_311(call.args, Name);
2772 }
2773 }
2774 }
2775 debug_assert_eq!(self.stack_len(), init_stack_len + 1);
2776 }
2777
2778 fn emit_call_local(&mut self, local: Identifier, args: Args) {
2779 log!(info "entered {}", fn_name!());
2780 match &local.inspect()[..] {
2781 "assert" => self.emit_assert_instr(args),
2782 "Del" => self.emit_del_instr(args),
2783 "not" => self.emit_not_instr(args),
2784 "discard" => self.emit_discard_instr(args),
2785 "for" | "for!" => self.emit_for_instr(args),
2786 "while!" => self.emit_while_instr(args),
2787 "if" | "if!" => self.emit_if_instr(args),
2788 "match" | "match!" => self.emit_match_instr(args, true),
2789 "with!" => match self.py_version.minor {
2790 Some(11) => self.emit_with_instr_311(args),
2791 Some(10) => self.emit_with_instr_310(args),
2792 Some(9) => self.emit_with_instr_309(args),
2793 Some(8) => self.emit_with_instr_308(args),
2794 Some(7) => self.emit_with_instr_307(args),
2795 _ => todo!("not supported Python version"),
2796 },
2797 "sum" if self.py_version.minor <= Some(7) && args.get_kw("start").is_some() => {
2798 self.load_builtins();
2799 self.emit_load_name_instr(Identifier::private("#sum"));
2800 self.emit_args_311(args, Name);
2801 }
2802 "ListIterator" => {
2803 let list = Expr::Literal(Literal::new(ValueObj::List(vec![].into()), Token::DUMMY));
2804 let iter = Identifier::static_public("iter");
2805 let iter_call = iter.call(Args::single(PosArg::new(list)));
2806 let typ = Identifier::static_public("type");
2807 let typ_call = typ.call(Args::single(PosArg::new(iter_call.into())));
2808 self.emit_call(typ_call);
2809 }
2810 "SetIterator" => {
2811 let set = Expr::Set(Set::empty());
2812 let iter = Identifier::static_public("iter");
2813 let iter_call = iter.call(Args::single(PosArg::new(set)));
2814 let typ = Identifier::static_public("type");
2815 let typ_call = typ.call(Args::single(PosArg::new(iter_call.into())));
2816 self.emit_call(typ_call);
2817 }
2818 "DictItems" => {
2819 let dict = Expr::Dict(Dict::empty());
2820 let iter = Identifier::static_public("iter");
2821 let items_call = iter.call(Args::single(PosArg::new(dict)));
2822 let typ = Identifier::static_public("type");
2823 let typ_call = typ.call(Args::single(PosArg::new(items_call.into())));
2824 self.emit_call(typ_call);
2825 }
2826 "DictKeys" => {
2827 let dict = Expr::Dict(Dict::empty());
2828 let keys = Identifier::static_public("keys");
2829 let keys_call = dict.method_call(keys, Args::empty());
2830 let typ = Identifier::static_public("type");
2831 let typ_call = typ.call(Args::single(PosArg::new(keys_call.into())));
2832 self.emit_call(typ_call);
2833 }
2834 "DictValues" => {
2835 let dict = Expr::Dict(Dict::empty());
2836 let values = Identifier::static_public("values");
2837 let values_call = dict.method_call(values, Args::empty());
2838 let typ = Identifier::static_public("type");
2839 let typ_call = typ.call(Args::single(PosArg::new(values_call.into())));
2840 self.emit_call(typ_call);
2841 }
2842 other if local.ref_t().is_poly_meta_type() && other != "classof" => {
2843 if self.py_version.minor <= Some(9) {
2844 self.load_fake_generic();
2845 self.emit_load_name_instr(Identifier::private("#FakeGenericAlias"));
2846 let mut args = args;
2847 args.insert_pos(0, PosArg::new(Expr::Accessor(Accessor::Ident(local))));
2848 self.emit_args_311(args, Name);
2849 } else {
2850 self.emit_load_name_instr(local);
2851 self.emit_index_args(args);
2852 }
2853 }
2854 _ => {
2856 self.emit_push_null();
2857 self.emit_load_name_instr(local);
2858 self.emit_args_311(args, Name);
2859 }
2860 }
2861 }
2862
2863 fn emit_call_method(&mut self, obj: Expr, method_name: Identifier, args: Args) {
2864 log!(info "entered {}", fn_name!());
2865 match &method_name.inspect()[..] {
2866 "return" if obj.ref_t().is_callable() => {
2867 return self.emit_return_instr(args);
2868 }
2869 "yield" => {
2871 return self.emit_yield_instr(args);
2872 }
2873 _ => {}
2874 }
2875 if let Some(func_name) = debind(&method_name) {
2876 return self.emit_call_fake_method(obj, func_name, method_name, args);
2877 }
2878 let is_type = method_name.ref_t().is_poly_meta_type();
2879 let kind = if self.py_version.minor >= Some(11)
2880 || (method_name.vi.t.is_method() && args.kw_args.is_empty())
2881 {
2882 BoundAttr
2883 } else {
2884 UnboundAttr
2885 };
2886 self.emit_expr(obj);
2887 self.emit_load_method_instr(method_name, kind);
2888 if is_type {
2889 self.emit_index_args(args);
2890 } else {
2891 self.emit_args_311(args, kind);
2892 }
2893 }
2894
2895 fn emit_var_args_311(&mut self, pos_len: usize, var_args: &PosArg) {
2896 if pos_len > 0 {
2897 self.write_instr(BUILD_LIST);
2898 self.write_arg(pos_len);
2899 }
2900 self.emit_expr(var_args.expr.clone());
2901 if pos_len > 0 {
2902 self.write_instr(Opcode310::LIST_EXTEND);
2903 self.write_arg(1);
2904 self.write_instr(Opcode310::LIST_TO_TUPLE);
2905 self.write_arg(0);
2906 }
2907 self.stack_dec();
2908 }
2909
2910 fn emit_var_args_308(&mut self, pos_len: usize, var_args: &PosArg) {
2911 if pos_len > 0 {
2912 self.write_instr(BUILD_TUPLE);
2913 self.write_arg(pos_len);
2914 }
2915 self.emit_expr(var_args.expr.clone());
2916 if pos_len > 0 {
2917 self.write_instr(Opcode309::BUILD_TUPLE_UNPACK_WITH_CALL);
2918 self.write_arg(2);
2919 }
2920 self.stack_dec();
2921 }
2922
2923 fn emit_kw_var_args_311(&mut self, pos_len: usize, kw_var: &PosArg) {
2924 self.write_instr(BUILD_TUPLE);
2925 self.write_arg(pos_len);
2926 self.stack_dec_n(pos_len.saturating_sub(1));
2927 self.write_instr(BUILD_MAP);
2928 self.write_arg(0);
2929 self.emit_expr(kw_var.expr.clone());
2930 self.write_instr(Opcode311::DICT_MERGE);
2931 self.write_arg(1);
2932 }
2933
2934 fn emit_kw_var_args_308(&mut self, pos_len: usize, kw_var: &PosArg) {
2935 self.write_instr(BUILD_TUPLE);
2936 self.write_arg(pos_len);
2937 self.emit_expr(kw_var.expr.clone());
2938 self.stack_dec_n(pos_len.saturating_sub(1));
2939 }
2940
2941 fn emit_args_311(&mut self, mut args: Args, kind: AccessKind) {
2942 let argc = args.len();
2943 let pos_len = args.pos_args.len();
2944 let mut kws = Vec::with_capacity(args.kw_len());
2945 while let Some(arg) = args.try_remove_pos(0) {
2946 self.emit_expr(arg.expr);
2947 }
2948 if let Some(var_args) = &args.var_args {
2949 if self.py_version.minor >= Some(9) {
2950 self.emit_var_args_311(pos_len, var_args);
2951 } else {
2952 self.emit_var_args_308(pos_len, var_args);
2953 }
2954 }
2955 while let Some(arg) = args.try_remove_kw(0) {
2956 kws.push(ValueObj::Str(arg.keyword.content));
2957 self.emit_expr(arg.expr);
2958 }
2959 if let Some(kw_var) = &args.kw_var {
2961 if self.py_version.minor >= Some(9) {
2962 self.emit_kw_var_args_311(pos_len, kw_var);
2963 } else {
2964 self.emit_kw_var_args_308(pos_len, kw_var);
2965 }
2966 }
2967 let kwsc = if !kws.is_empty() {
2968 self.emit_call_kw_instr(argc, kws);
2969 #[allow(clippy::bool_to_int_with_if)]
2970 if self.py_version.minor >= Some(11) {
2971 0
2972 } else {
2973 1
2974 }
2975 } else if args.var_args.is_some() || args.kw_var.is_some() {
2976 self.write_instr(CALL_FUNCTION_EX);
2977 if kws.is_empty() && args.kw_var.is_none() {
2978 self.write_arg(0);
2979 } else {
2980 self.write_arg(1);
2981 }
2982 if self.py_version.minor >= Some(11) {
2983 self.stack_dec();
2984 }
2985 if args.kw_var.is_some() {
2986 1
2987 } else {
2988 0
2989 }
2990 } else {
2991 self.emit_call_instr(argc, kind);
2992 0
2993 };
2994 self.stack_dec_n((1 + argc + kwsc) - 1);
2996 }
2997
2998 fn emit_index_args(&mut self, mut args: Args) {
2999 let argc = args.pos_args.len();
3000 while let Some(arg) = args.try_remove_pos(0) {
3001 self.emit_expr(arg.expr);
3002 }
3003 if argc > 1 {
3004 self.write_instr(BUILD_TUPLE);
3005 self.write_arg(argc);
3006 }
3007 self.write_instr(Opcode311::BINARY_SUBSCR);
3008 self.write_arg(0);
3009 if self.py_version.minor >= Some(11) {
3010 self.write_bytes(&[0; 8]);
3011 }
3012 self.stack_dec_n((1 + argc) - 1);
3014 }
3015
3016 fn emit_return_instr(&mut self, mut args: Args) {
3018 log!(info "entered {}", fn_name!());
3019 if args.is_empty() {
3020 self.emit_load_const(ValueObj::None);
3021 } else {
3022 self.emit_expr(args.remove(0));
3023 }
3024 self.write_instr(RETURN_VALUE);
3025 self.write_arg(0);
3026 }
3027
3028 fn emit_yield_instr(&mut self, mut args: Args) {
3029 log!(info "entered {}", fn_name!());
3030 if args.is_empty() {
3031 self.emit_load_const(ValueObj::None);
3032 } else {
3033 self.emit_expr(args.remove(0));
3034 }
3035 self.write_instr(YIELD_VALUE);
3036 self.write_arg(0);
3037 }
3038
3039 fn emit_call_fake_method(
3041 &mut self,
3042 obj: Expr,
3043 func_name: Str,
3044 mut method_name: Identifier,
3045 mut args: Args,
3046 ) {
3047 log!(info "entered {}", fn_name!());
3048 method_name.raw.vis = VisModifierSpec::Private;
3049 method_name.vi.py_name = Some(func_name);
3050 self.emit_push_null();
3051 self.emit_load_name_instr(method_name);
3052 args.insert_pos(0, PosArg::new(obj));
3053 self.emit_args_311(args, Name);
3054 }
3055
3056 fn emit_assert_instr(&mut self, mut args: Args) {
3058 log!(info "entered {}", fn_name!());
3059 let init_stack_len = self.stack_len();
3060 self.emit_expr(args.remove(0));
3061 let pop_jump_point = self.lasti();
3062 self.write_instr(EXTENDED_ARG);
3063 self.write_arg(0);
3064 self.write_instr(Opcode310::POP_JUMP_IF_TRUE);
3065 self.write_arg(0);
3066 self.stack_dec();
3067 if self.py_version.minor >= Some(10) {
3068 self.write_instr(Opcode310::LOAD_ASSERTION_ERROR);
3069 self.write_arg(0);
3070 self.stack_inc();
3071 } else {
3072 self.emit_load_global_instr(Identifier::static_public("AssertionError"));
3073 }
3074 if let Some(expr) = args.try_remove(0) {
3075 self.emit_expr(expr);
3076 if self.py_version.minor >= Some(11) {
3077 self.emit_precall_and_call(0);
3078 } else {
3079 self.write_instr(Opcode310::CALL_FUNCTION);
3080 self.write_arg(1);
3081 self.stack_dec();
3082 }
3083 }
3084 self.write_instr(RAISE_VARARGS);
3085 self.write_arg(1);
3086 self.stack_dec();
3087 let idx = match self.py_version.minor {
3088 Some(11) => self.lasti() - pop_jump_point - 4,
3089 Some(10) => self.lasti(),
3090 Some(_) => self.lasti(),
3091 _ => todo!(),
3092 };
3093 self.fill_jump(pop_jump_point + 1, idx);
3094 self.emit_load_const(ValueObj::None);
3095 debug_assert_eq!(self.stack_len(), init_stack_len + 1);
3096 }
3097
3098 fn emit_list(&mut self, list: List) {
3100 let init_stack_len = self.stack_len();
3101 if !self.cfg.no_std {
3102 self.emit_push_null();
3103 if list.is_unsized() {
3104 self.emit_load_name_instr(Identifier::static_public("UnsizedList"));
3105 } else {
3106 self.emit_load_name_instr(Identifier::static_public("List"));
3107 }
3108 }
3109 match list {
3110 List::Normal(mut lis) => {
3111 let len = lis.elems.len();
3112 while let Some(arg) = lis.elems.try_remove_pos(0) {
3113 self.emit_expr(arg.expr);
3114 }
3115 self.write_instr(BUILD_LIST);
3116 self.write_arg(len);
3117 if len == 0 {
3118 self.stack_inc();
3119 } else {
3120 self.stack_dec_n(len - 1);
3121 }
3122 }
3123 List::WithLength(ListWithLength {
3124 elem,
3125 len: Some(len),
3126 ..
3127 }) => {
3128 self.emit_expr(*elem);
3129 self.write_instr(BUILD_LIST);
3130 self.write_arg(1);
3131 self.emit_call_instr(1, Name);
3132 self.stack_dec();
3133 self.emit_expr(*len);
3134 self.emit_binop_instr(Token::dummy(TokenKind::Star, "*"), TypePair::ListNat);
3135 return;
3136 }
3137 List::WithLength(ListWithLength {
3138 elem, len: None, ..
3139 }) => {
3140 self.emit_expr(*elem);
3141 }
3142 other => todo!("{other}"),
3143 }
3144 if !self.cfg.no_std {
3145 self.emit_call_instr(1, Name);
3146 self.stack_dec();
3147 }
3148 debug_assert_eq!(self.stack_len(), init_stack_len + 1);
3149 }
3150
3151 fn emit_tuple(&mut self, tuple: Tuple) {
3154 let init_stack_len = self.stack_len();
3155 match tuple {
3156 Tuple::Normal(mut tup) => {
3157 let len = tup.elems.len();
3158 while let Some(arg) = tup.elems.try_remove_pos(0) {
3159 self.emit_expr(arg.expr);
3160 }
3161 self.write_instr(BUILD_TUPLE);
3162 self.write_arg(len);
3163 if len == 0 {
3164 self.stack_inc();
3165 } else {
3166 self.stack_dec_n(len - 1);
3167 }
3168 }
3169 }
3170 debug_assert_eq!(self.stack_len(), init_stack_len + 1);
3171 }
3172
3173 fn emit_set(&mut self, set: crate::hir::Set) {
3174 let init_stack_len = self.stack_len();
3175 match set {
3176 crate::hir::Set::Normal(mut set) => {
3177 let len = set.elems.len();
3178 while let Some(arg) = set.elems.try_remove_pos(0) {
3179 self.emit_expr(arg.expr);
3180 }
3181 self.write_instr(BUILD_SET);
3182 self.write_arg(len);
3183 if len == 0 {
3184 self.stack_inc();
3185 } else {
3186 self.stack_dec_n(len - 1);
3187 }
3188 }
3189 crate::hir::Set::WithLength(st) => {
3190 self.emit_expr(*st.elem);
3191 self.write_instr(BUILD_SET);
3192 self.write_arg(1);
3193 }
3194 }
3195 debug_assert_eq!(self.stack_len(), init_stack_len + 1);
3196 }
3197
3198 fn emit_dict(&mut self, dict: crate::hir::Dict) {
3199 let init_stack_len = self.stack_len();
3200 if !self.cfg.no_std {
3201 self.emit_push_null();
3202 self.emit_load_name_instr(Identifier::static_public("Dict"));
3203 }
3204 match dict {
3205 crate::hir::Dict::Normal(dic) => {
3206 let len = dic.kvs.len();
3207 for kv in dic.kvs.into_iter() {
3208 self.emit_expr(kv.key);
3209 self.emit_expr(kv.value);
3210 }
3211 self.write_instr(BUILD_MAP);
3212 self.write_arg(len);
3213 if len == 0 {
3214 self.stack_inc();
3215 } else {
3216 self.stack_dec_n(2 * len - 1);
3217 }
3218 }
3219 other => todo!("{other}"),
3220 }
3221 if !self.cfg.no_std {
3222 self.emit_call_instr(1, Name);
3223 self.stack_dec();
3224 }
3225 debug_assert_eq!(self.stack_len(), init_stack_len + 1);
3226 }
3227
3228 #[allow(clippy::identity_op)]
3229 fn emit_record(&mut self, rec: Record) {
3230 log!(info "entered {} ({rec})", fn_name!());
3231 let init_stack_len = self.stack_len();
3232 let attrs_len = rec.attrs.len();
3233 self.emit_push_null();
3234 let ident = Identifier::private("#NamedTuple");
3236 self.emit_load_name_instr(ident);
3237 self.emit_load_const("Record");
3239 for field in rec.attrs.iter() {
3240 self.emit_load_const(ValueObj::Str(field.sig.ident().inspect().clone()));
3241 }
3242 self.write_instr(BUILD_LIST);
3243 self.write_arg(attrs_len);
3244 if attrs_len == 0 {
3245 self.stack_inc();
3246 } else {
3247 self.stack_dec_n(attrs_len - 1);
3248 }
3249 self.emit_call_instr(2, Name);
3250 self.stack_dec_n((1 + 2 + 0) - 1);
3252 let ident = Identifier::private("#rec");
3253 self.emit_store_instr(ident, Name);
3254 let ident = Identifier::private("#rec");
3256 self.emit_push_null();
3257 self.emit_load_name_instr(ident);
3258 for field in rec.attrs.into_iter() {
3259 self.emit_simple_block(field.body.block);
3260 }
3261 self.emit_call_instr(attrs_len, Name);
3262 self.stack_dec_n((1 + attrs_len + 0) - 1);
3264 debug_assert_eq!(self.stack_len(), init_stack_len + 1);
3265 }
3266
3267 fn emit_code(&mut self, code: Block) {
3269 let mut gen = self.inherit();
3270 let code = gen.emit_block(code, vec![], None, vec![], 0, vec![], 0);
3271 self.emit_load_const(code);
3272 }
3273
3274 pub(crate) fn get_root(acc: &Accessor) -> Identifier {
3275 match acc {
3276 Accessor::Ident(ident) => ident.clone(),
3277 Accessor::Attr(attr) => {
3278 if let Expr::Accessor(acc) = attr.obj.as_ref() {
3279 Self::get_root(acc)
3280 } else {
3281 todo!("{:?}", attr.obj)
3282 }
3283 }
3284 }
3285 }
3286
3287 fn emit_import(&mut self, acc: Accessor) {
3288 self.emit_load_const(0i32);
3289 self.emit_load_const(ValueObj::None);
3290 let full_name = Str::from(
3291 acc.qual_name()
3292 .map_or(acc.show(), |s| s.replace(".__init__", "")),
3293 );
3294 let name = self
3295 .local_search(&full_name, Name)
3296 .unwrap_or_else(|| self.register_name(full_name, Import));
3297 self.write_instr(IMPORT_NAME);
3298 self.write_arg(name.idx);
3299 let root = Self::get_root(&acc);
3300 self.emit_store_instr(root, Name);
3301 self.stack_dec();
3302 }
3303
3304 fn emit_compound(&mut self, chunks: Block) {
3305 let is_module_loading_chunks = chunks
3306 .get(2)
3307 .map(|chunk| {
3308 option_enum_unwrap!(chunk, Expr::Call)
3309 .map(|call| call.obj.show_acc().as_ref().map(|s| &s[..]) == Some("exec"))
3310 .unwrap_or(false)
3311 })
3312 .unwrap_or(false);
3313 if !self.module_type_loaded && is_module_loading_chunks {
3314 self.load_module_type();
3315 self.module_type_loaded = true;
3316 }
3317 let init_stack_len = self.stack_len();
3318 for chunk in chunks.into_iter() {
3319 self.emit_chunk(chunk);
3320 if self.stack_len() == init_stack_len + 1 {
3321 self.emit_pop_top();
3322 }
3323 }
3324 self.cancel_if_pop_top();
3325 }
3326
3327 fn push_lnotab(&mut self, expr: &Expr) {
3329 let ln_begin = expr.ln_begin().unwrap_or(0);
3330 if ln_begin > self.cur_block().prev_lineno {
3331 let mut sd = self.lasti() - self.cur_block().prev_lasti;
3332 let mut ld = ln_begin - self.cur_block().prev_lineno;
3333 if ld != 0 {
3334 if sd != 0 {
3335 while sd > 254 {
3336 self.mut_cur_block_codeobj().lnotab.push(255);
3337 self.mut_cur_block_codeobj().lnotab.push(0);
3338 sd -= 254;
3339 }
3340 while ld > 127 {
3341 self.mut_cur_block_codeobj().lnotab.push(0);
3342 self.mut_cur_block_codeobj().lnotab.push(127);
3343 ld -= 127;
3344 }
3345 self.mut_cur_block_codeobj().lnotab.push(sd as u8);
3346 self.mut_cur_block_codeobj().lnotab.push(ld as u8);
3347 } else {
3348 if let Some(&last_ld) = self.cur_block_codeobj().lnotab.last() {
3350 if last_ld as u32 + ld > 127 {
3351 *self.mut_cur_block_codeobj().lnotab.last_mut().unwrap() = 127;
3352 self.mut_cur_block_codeobj().lnotab.push(0);
3353 ld -= 127;
3354 }
3355 while last_ld as u32 + ld > 127 {
3356 self.mut_cur_block_codeobj().lnotab.push(127);
3357 self.mut_cur_block_codeobj().lnotab.push(0);
3358 ld -= 127;
3359 }
3360 self.mut_cur_block_codeobj().lnotab.push(ld as u8);
3361 } else {
3362 self.mut_cur_block_codeobj().lnotab.push(0);
3364 self.mut_cur_block_codeobj()
3365 .lnotab
3366 .push(u8::try_from(ld).unwrap());
3367 }
3368 }
3369 self.mut_cur_block().prev_lineno += ld;
3370 self.mut_cur_block().prev_lasti = self.lasti();
3371 } else {
3372 CompileError::compiler_bug(
3373 0,
3374 self.cfg.input.clone(),
3375 expr.loc(),
3376 fn_name_full!(),
3377 line!(),
3378 )
3379 .write_to_stderr();
3380 self.crash("codegen failed: invalid bytecode format");
3381 }
3382 }
3383 }
3384
3385 fn emit_chunk(&mut self, chunk: Expr) {
3386 log!(info "entered {} ({chunk})", fn_name!());
3387 self.push_lnotab(&chunk);
3388 match chunk {
3389 Expr::Literal(lit) => self.emit_load_const(lit.value),
3390 Expr::Accessor(acc) => self.emit_acc(acc),
3391 Expr::Def(def) => self.emit_def(def),
3392 Expr::ClassDef(class) => self.emit_class_def(class),
3393 Expr::PatchDef(patch) => self.emit_patch_def(patch),
3394 Expr::ReDef(attr) => self.emit_redef(attr),
3395 Expr::Lambda(lambda) => self.emit_lambda(lambda),
3396 Expr::UnaryOp(unary) => self.emit_unaryop(unary),
3397 Expr::BinOp(bin) => self.emit_binop(bin),
3398 Expr::Call(call) => self.emit_call(call),
3399 Expr::List(lis) => self.emit_list(lis),
3400 Expr::Tuple(tup) => self.emit_tuple(tup),
3401 Expr::Set(set) => self.emit_set(set),
3402 Expr::Dict(dict) => self.emit_dict(dict),
3403 Expr::Record(rec) => self.emit_record(rec),
3404 Expr::Code(code) => self.emit_code(code),
3405 Expr::Compound(chunks) => self.emit_compound(chunks),
3406 Expr::Import(acc) => self.emit_import(acc),
3407 Expr::Dummy(_) | Expr::TypeAsc(_) => {}
3408 }
3409 }
3410
3411 fn emit_expr(&mut self, expr: Expr) {
3412 log!(info "entered {} ({expr})", fn_name!());
3413 self.push_lnotab(&expr);
3414 let init_stack_len = self.stack_len();
3415 let mut wrapped = true;
3416 if !self.cfg.no_std && expr.should_wrap() {
3417 match expr.ref_t().derefine() {
3418 v @ (Bool | Nat | Int | Float | Str) => {
3419 self.emit_push_null();
3420 self.emit_load_name_instr(Identifier::public(&v.qual_name()));
3421 }
3422 other => match &other.qual_name()[..] {
3423 t @ ("Bytes" | "List" | "Dict" | "Set") => {
3424 self.emit_push_null();
3425 self.emit_load_name_instr(Identifier::public(t));
3426 }
3427 _ => {
3428 wrapped = false;
3429 }
3430 },
3431 }
3432 } else {
3433 wrapped = false;
3434 }
3435 match expr {
3436 Expr::Literal(lit) => self.emit_load_const(lit.value),
3437 Expr::Accessor(acc) => self.emit_acc(acc),
3438 Expr::Def(def) => self.emit_def(def),
3439 Expr::ClassDef(class) => self.emit_class_def(class),
3440 Expr::PatchDef(patch) => self.emit_patch_def(patch),
3441 Expr::ReDef(attr) => self.emit_redef(attr),
3442 Expr::Lambda(lambda) => self.emit_lambda(lambda),
3443 Expr::UnaryOp(unary) => self.emit_unaryop(unary),
3444 Expr::BinOp(bin) => self.emit_binop(bin),
3445 Expr::Call(call) => self.emit_call(call),
3446 Expr::List(lis) => self.emit_list(lis),
3447 Expr::Tuple(tup) => self.emit_tuple(tup),
3448 Expr::Set(set) => self.emit_set(set),
3449 Expr::Dict(dict) => self.emit_dict(dict),
3450 Expr::Record(rec) => self.emit_record(rec),
3451 Expr::Code(code) => self.emit_code(code),
3452 Expr::Compound(chunks) => self.emit_compound(chunks),
3453 Expr::TypeAsc(tasc) => self.emit_expr(*tasc.expr),
3454 Expr::Import(acc) => self.emit_import(acc),
3455 Expr::Dummy(_) => {}
3456 }
3457 if !self.cfg.no_std && wrapped {
3458 self.emit_call_instr(1, Name);
3459 self.stack_dec();
3460 }
3461 debug_assert_eq!(self.stack_len(), init_stack_len + 1);
3462 }
3463
3464 fn emit_control_block(&mut self, block: Block, params: Params) {
3466 log!(info "entered {}", fn_name!());
3467 let param_names = self.gen_param_names(¶ms);
3468 let line = block.ln_begin().unwrap_or(0);
3469 for param in param_names {
3470 self.emit_store_instr(Identifier::public_with_line(DOT, param, line), Name);
3471 }
3472 for guard in params.guards {
3473 if let GuardClause::Bind(bind) = guard {
3474 self.emit_def(bind);
3475 }
3476 }
3477 if block.is_empty() {
3478 return;
3479 }
3480 let init_stack_len = self.stack_len();
3481 for chunk in block.into_iter() {
3482 self.emit_chunk(chunk);
3483 if self.stack_len() > init_stack_len {
3484 self.emit_pop_top();
3485 }
3486 }
3487 self.cancel_if_pop_top();
3488 }
3489
3490 fn emit_simple_block(&mut self, block: Block) {
3491 log!(info "entered {}", fn_name!());
3492 if block.is_empty() {
3493 return;
3494 }
3495 let init_stack_len = self.stack_len();
3496 for chunk in block.into_iter() {
3497 self.emit_chunk(chunk);
3498 if self.stack_len() > init_stack_len {
3499 self.emit_pop_top();
3500 }
3501 }
3502 self.cancel_if_pop_top();
3503 }
3504
3505 fn emit_with_block(&mut self, block: Block, params: Vec<Str>) {
3506 log!(info "entered {}", fn_name!());
3507 let line = block.ln_begin().unwrap_or(0);
3508 for param in params {
3509 self.emit_store_instr(Identifier::public_with_line(DOT, param, line), Name);
3510 }
3511 let init_stack_len = self.stack_len();
3512 for chunk in block.into_iter() {
3513 self.emit_chunk(chunk);
3514 if self.stack_len() > init_stack_len {
3516 self.emit_pop_top();
3517 }
3518 }
3519 self.cancel_if_pop_top();
3520 }
3521
3522 fn emit_class_block(&mut self, class: ClassDef) -> CodeObj {
3523 log!(info "entered {}", fn_name!());
3524 let name = class.sig.ident().inspect().clone();
3525 self.unit_size += 1;
3526 let firstlineno = match class.methods_list.first().and_then(|def| def.ln_begin()) {
3527 Some(l) => l,
3528 None => class.sig.ln_begin().unwrap_or(0),
3529 };
3530 self.units.push(PyCodeGenUnit::new(
3531 self.unit_size,
3532 self.py_version,
3533 vec![],
3534 0,
3535 Str::rc(self.cfg.input.enclosed_name()),
3536 &name,
3537 firstlineno,
3538 0,
3539 ));
3540 let init_stack_len = self.stack_len();
3541 let mod_name = self.toplevel_block_codeobj().name.clone();
3542 self.emit_load_const(mod_name);
3543 self.emit_store_instr(Identifier::static_public("__module__"), Name);
3544 self.emit_load_const(name);
3545 self.emit_store_instr(Identifier::static_public("__qualname__"), Name);
3546 let mut methods = ClassDef::take_all_methods(class.methods_list);
3547 let __init__ = methods
3548 .get_def("__init__")
3549 .or_else(|| methods.get_def("__init__!"))
3550 .cloned();
3551 self.emit_init_method(&class.sig, __init__, class.constructor.clone());
3552 if class.need_to_gen_new {
3553 self.emit_new_func(&class.sig, class.constructor);
3554 }
3555 let __del__ = methods
3556 .remove_def("__del__")
3557 .or_else(|| methods.remove_def("__del__!"));
3558 if let Some(mut __del__) = __del__ {
3559 __del__.sig.ident_mut().vi.py_name = Some(Str::from("__del__"));
3560 self.emit_def(__del__);
3561 }
3562 if !methods.is_empty() {
3563 self.emit_simple_block(methods);
3564 }
3565 if self.stack_len() == init_stack_len {
3566 self.emit_load_const(ValueObj::None);
3567 }
3568 self.write_instr(RETURN_VALUE);
3569 self.write_arg(0);
3570 if self.stack_len() > 1 {
3571 let block_id = self.cur_block().id;
3572 let stack_len = self.stack_len();
3573 CompileError::stack_bug(
3574 self.input().clone(),
3575 Location::Unknown,
3576 stack_len,
3577 block_id,
3578 fn_name_full!(),
3579 )
3580 .write_to_stderr();
3581 self.crash("error in emit_class_block: invalid stack size");
3582 }
3583 if !self.cur_block_codeobj().varnames.is_empty() {
3585 self.mut_cur_block_codeobj().flags += CodeObjFlags::NewLocals as u32;
3586 }
3587 let unit = self.units.pop().unwrap();
3589 if !self.units.is_empty() {
3590 let ld = unit.prev_lineno - self.cur_block().prev_lineno;
3591 if ld != 0 {
3592 if let Some(l) = self.mut_cur_block_codeobj().lnotab.last_mut() {
3593 *l += u8::try_from(ld).unwrap();
3594 }
3595 self.mut_cur_block().prev_lineno += ld;
3596 }
3597 }
3598 unit.codeobj
3599 }
3600
3601 fn emit_init_method(&mut self, sig: &Signature, __init__: Option<Def>, constructor: Type) {
3602 log!(info "entered {}", fn_name!());
3603 let new_first_param = constructor.non_default_params().unwrap().first();
3604 let line = sig.ln_begin().unwrap_or(0);
3605 let class_name = sig.ident().inspect();
3606 let mut ident = Identifier::public_with_line(DOT, Str::ever("__init__"), line);
3607 ident.vi.t = constructor.clone();
3608 let self_param = VarName::from_str_and_line(Str::ever("self"), line);
3609 let vi = VarInfo::nd_parameter(
3610 constructor.return_t().unwrap().clone(),
3611 ident.vi.def_loc.clone(),
3612 "?".into(),
3613 );
3614 let raw =
3615 erg_parser::ast::NonDefaultParamSignature::new(ParamPattern::VarName(self_param), None);
3616 let self_param = NonDefaultParamSignature::new(raw, vi, None);
3617 let (param_name, params) = if let Some(new_first_param) = new_first_param {
3618 let param_name = new_first_param
3619 .name()
3620 .cloned()
3621 .unwrap_or_else(|| self.fresh_gen.fresh_varname());
3622 let param = VarName::from_str_and_line(param_name.clone(), line);
3623 let raw =
3624 erg_parser::ast::NonDefaultParamSignature::new(ParamPattern::VarName(param), None);
3625 let vi = VarInfo::nd_parameter(
3626 new_first_param.typ().clone(),
3627 ident.vi.def_loc.clone(),
3628 "?".into(),
3629 );
3630 let param = NonDefaultParamSignature::new(raw, vi, None);
3631 let params = Params::new(vec![self_param, param], None, vec![], None, vec![], None);
3632 (param_name, params)
3633 } else {
3634 ("_".into(), Params::single(self_param))
3635 };
3636 let bounds = TypeBoundSpecs::empty();
3637 let subr_sig = SubrSignature::new(
3638 set! {},
3639 ident,
3640 bounds,
3641 params,
3642 sig.t_spec_with_op().cloned(),
3643 vec![],
3644 );
3645 let mut attrs = vec![];
3646 match new_first_param.map(|pt| pt.typ()) {
3647 Some(Type::Record(rec)) => {
3654 for field in rec.keys() {
3655 let obj =
3656 Expr::Accessor(Accessor::private_with_line(Str::from(¶m_name), line));
3657 let ident = erg_parser::ast::Identifier::public(field.symbol.clone());
3658 let expr = obj.attr_expr(Identifier::bare(ident));
3659 let obj = Expr::Accessor(Accessor::private_with_line(Str::ever("self"), line));
3660 let dot = if field.vis.is_private() {
3661 VisModifierSpec::Private
3662 } else {
3663 VisModifierSpec::Public(Location::Unknown)
3664 };
3665 let attr = erg_parser::ast::Identifier::new(
3666 dot,
3667 VarName::from_str(field.symbol.clone()),
3668 );
3669 let attr = obj.attr(Identifier::bare(attr));
3670 let redef = ReDef::new(attr, Block::new(vec![expr]));
3671 attrs.push(Expr::ReDef(redef));
3672 }
3673 }
3674 Some(_) => {
3676 let expr =
3677 Expr::Accessor(Accessor::private_with_line(Str::from(¶m_name), line));
3678 let obj = Expr::Accessor(Accessor::private_with_line(Str::ever("self"), line));
3679 let attr = obj.attr(Identifier::private_with_line(Str::ever("base"), line));
3680 let redef = ReDef::new(attr, Block::new(vec![expr]));
3681 attrs.push(Expr::ReDef(redef));
3682 }
3683 None => {}
3684 }
3685 if let Some(__init__) = __init__ {
3686 attrs.extend(__init__.body.block.clone());
3687 }
3688 let none = Token::new_fake(TokenKind::NoneLit, "None", line, 0, 0);
3689 attrs.push(Expr::Literal(Literal::new(ValueObj::None, none)));
3690 let block = Block::new(attrs);
3691 let body = DefBody::new(EQUAL, block, DefId(0));
3692 self.emit_subr_def(Some(class_name), subr_sig, body);
3693 }
3694
3695 fn emit_new_func(&mut self, sig: &Signature, constructor: Type) {
3701 log!(info "entered {}", fn_name!());
3702 let class_ident = sig.ident();
3703 let line = sig.ln_begin().unwrap_or(0);
3704 let mut ident = Identifier::public_with_line(DOT, Str::ever("new"), line);
3705 let class = Expr::Accessor(Accessor::Ident(class_ident.clone()));
3706 ident.vi.t = constructor;
3707 if let Ok(subr) = <&SubrType>::try_from(&ident.vi.t) {
3708 let mut params = Params::empty();
3709 let mut args = Args::empty();
3710 for nd_param in subr.non_default_params.iter() {
3711 let param_name = nd_param
3712 .name()
3713 .cloned()
3714 .unwrap_or_else(|| self.fresh_gen.fresh_varname());
3715 let param = VarName::from_str_and_line(param_name.clone(), line);
3716 let vi = VarInfo::nd_parameter(
3717 nd_param.typ().clone(),
3718 ident.vi.def_loc.clone(),
3719 "?".into(),
3720 );
3721 let raw = erg_parser::ast::NonDefaultParamSignature::new(
3722 ParamPattern::VarName(param),
3723 None,
3724 );
3725 let param = NonDefaultParamSignature::new(raw, vi, None);
3726 params.push_non_default(param);
3727 let arg = PosArg::new(Expr::Accessor(Accessor::public_with_line(param_name, line)));
3728 args.push_pos(arg);
3729 }
3730 let bounds = TypeBoundSpecs::empty();
3732 let sig = SubrSignature::new(
3733 set! {},
3734 ident,
3735 bounds,
3736 params,
3737 sig.t_spec_with_op().cloned(),
3738 vec![],
3739 );
3740 let call = class.call_expr(args);
3741 let block = Block::new(vec![call]);
3742 let body = DefBody::new(EQUAL, block, DefId(0));
3743 self.emit_subr_def(Some(class_ident.inspect()), sig, body);
3744 } else {
3745 let params = Params::empty();
3746 let bounds = TypeBoundSpecs::empty();
3747 let sig = SubrSignature::new(
3748 set! {},
3749 ident,
3750 bounds,
3751 params,
3752 sig.t_spec_with_op().cloned(),
3753 vec![],
3754 );
3755 let call = class.call_expr(Args::empty());
3756 let block = Block::new(vec![call]);
3757 let body = DefBody::new(EQUAL, block, DefId(0));
3758 self.emit_subr_def(Some(class_ident.inspect()), sig, body);
3759 }
3760 }
3761
3762 #[allow(clippy::too_many_arguments)]
3763 fn emit_block(
3764 &mut self,
3765 block: Block,
3766 guards: Vec<GuardClause>,
3767 opt_name: Option<Str>,
3768 params: Vec<Str>,
3769 kwonlyargcount: u32,
3770 captured_names: Vec<Identifier>,
3771 flags: u32,
3772 ) -> CodeObj {
3773 log!(info "entered {}", fn_name!());
3774 self.unit_size += 1;
3775 let name = if let Some(name) = opt_name {
3776 name
3777 } else {
3778 self.fresh_gen.fresh_varname()
3779 };
3780 let firstlineno = block
3781 .first()
3782 .and_then(|first| first.ln_begin())
3783 .unwrap_or(0);
3784 self.units.push(PyCodeGenUnit::new(
3785 self.unit_size,
3786 self.py_version,
3787 params,
3788 kwonlyargcount,
3789 Str::rc(self.cfg.input.enclosed_name()),
3790 name,
3791 firstlineno,
3792 flags,
3793 ));
3794 let idx_copy_free_vars = if self.py_version.minor >= Some(11) {
3795 let idx_copy_free_vars = self.lasti();
3796 self.write_instr(Opcode311::COPY_FREE_VARS);
3797 self.write_arg(0);
3798 self.write_instr(Opcode311::RESUME);
3799 self.write_arg(0);
3800 idx_copy_free_vars
3801 } else {
3802 0
3803 };
3804 let mut cells = vec![];
3805 for captured in captured_names {
3806 self.mut_cur_block()
3807 .captured_vars
3808 .push(captured.inspect().clone());
3809 if self.py_version.minor >= Some(11) {
3810 self.write_instr(Opcode311::MAKE_CELL);
3811 cells.push((captured, self.lasti()));
3812 self.write_arg(0);
3813 }
3814 }
3815 let init_stack_len = self.stack_len();
3816 for guard in guards {
3817 if let GuardClause::Bind(bind) = guard {
3818 self.emit_def(bind);
3819 }
3820 }
3821 for chunk in block.into_iter() {
3822 self.emit_chunk(chunk);
3823 if self.stack_len() > init_stack_len {
3827 self.emit_pop_top();
3828 }
3829 }
3830 self.cancel_if_pop_top(); if self.stack_len() == init_stack_len {
3832 self.emit_load_const(ValueObj::None);
3833 } else if self.stack_len() > init_stack_len + 1 {
3834 let block_id = self.cur_block().id;
3835 let stack_len = self.stack_len();
3836 CompileError::stack_bug(
3837 self.input().clone(),
3838 Location::Unknown,
3839 stack_len,
3840 block_id,
3841 fn_name_full!(),
3842 )
3843 .write_to_stderr();
3844 self.crash("error in emit_block: invalid stack size");
3845 }
3846 self.write_instr(RETURN_VALUE);
3847 self.write_arg(0);
3848 if !self.cur_block_codeobj().varnames.is_empty() {
3850 self.mut_cur_block_codeobj().flags += CodeObjFlags::NewLocals as u32;
3851 }
3852 let freevars_len = self.cur_block_codeobj().freevars.len();
3853 if freevars_len > 0 {
3854 self.mut_cur_block_codeobj().flags += CodeObjFlags::Nested as u32;
3855 if self.py_version.minor >= Some(11) {
3856 self.edit_code(idx_copy_free_vars + 1, freevars_len);
3857 }
3858 } else if self.py_version.minor >= Some(11) {
3859 let code = self.cur_block_codeobj().code.get(idx_copy_free_vars);
3861 debug_assert_eq!(code, Some(&(Opcode311::COPY_FREE_VARS as u8)));
3862 self.edit_code(idx_copy_free_vars, CommonOpcode::NOP as usize);
3863 }
3864 for (cell, placeholder) in cells {
3865 let name = escape_ident(cell);
3866 let Some(idx) = self
3867 .cur_block_codeobj()
3868 .varnames
3869 .iter()
3870 .position(|v| v == &name)
3871 else {
3872 continue;
3873 };
3874 self.edit_code(placeholder, idx);
3875 }
3876 let unit = self.units.pop().unwrap();
3878 if !self.units.is_empty() {
3880 let ld = unit
3881 .prev_lineno
3882 .saturating_sub(self.cur_block().prev_lineno);
3883 if ld != 0 {
3884 if let Some(l) = self.mut_cur_block_codeobj().lnotab.last_mut() {
3885 *l += u8::try_from(ld).unwrap();
3886 }
3887 self.mut_cur_block().prev_lineno += ld;
3888 }
3889 }
3890 unit.codeobj
3891 }
3892
3893 fn load_prelude(&mut self) {
3894 let no_std = self.cfg.no_std;
3897 self.cfg.no_std = true;
3898 self.load_record_type();
3899 self.load_prelude_py();
3900 self.prelude_loaded = true;
3901 self.record_type_loaded = true;
3902 self.cfg.no_std = no_std;
3903 }
3904
3905 fn load_contains_op(&mut self) {
3906 let mod_name = Identifier::static_public("_erg_std_prelude");
3907 self.emit_global_import_items(
3908 mod_name,
3909 vec![(
3910 Identifier::static_public("contains_operator"),
3911 Some(Identifier::private("#contains_operator")),
3912 )],
3913 );
3914 self.contains_op_loaded = true;
3915 }
3916
3917 fn load_mutate_op(&mut self) {
3918 let mod_name = Identifier::static_public("_erg_std_prelude");
3919 self.emit_global_import_items(
3920 mod_name,
3921 vec![(
3922 Identifier::static_public("mutate_operator"),
3923 Some(Identifier::private("#mutate_operator")),
3924 )],
3925 );
3926 self.mutate_op_loaded = true;
3927 }
3928
3929 fn load_control(&mut self) {
3930 let mod_name = Identifier::static_public("_erg_control");
3931 self.emit_import_all_instr(mod_name);
3932 self.control_loaded = true;
3933 }
3934
3935 fn load_convertors(&mut self) {
3936 let mod_name = Identifier::static_public("_erg_convertors");
3937 self.emit_import_all_instr(mod_name);
3938 self.convertors_loaded = true;
3939 }
3940
3941 fn load_traits(&mut self) {
3942 let mod_name = Identifier::static_public("_erg_traits");
3943 self.emit_import_all_instr(mod_name);
3944 self.traits_loaded = true;
3945 }
3946
3947 fn load_operators(&mut self) {
3948 let mod_name = Identifier::static_public("operator");
3949 self.emit_import_all_instr(mod_name);
3950 self.operators_loaded = true;
3951 }
3952
3953 fn load_prelude_py(&mut self) {
3954 self.emit_global_import_items(
3955 Identifier::static_public("sys"),
3956 vec![(
3957 Identifier::static_public("path"),
3958 Some(Identifier::private("#path")),
3959 )],
3960 );
3961 self.emit_load_name_instr(Identifier::private("#path"));
3962 self.emit_load_method_instr(Identifier::static_public("append"), BoundAttr);
3963 self.emit_load_const(erg_core_path().to_str().unwrap());
3964 self.emit_call_instr(1, BoundAttr);
3965 self.stack_dec();
3966 self.emit_pop_top();
3967 let erg_std_mod = Identifier::static_public("_erg_std_prelude");
3968 self.emit_global_import_items(
3970 erg_std_mod.clone(),
3971 vec![(
3972 Identifier::static_public("contains_operator"),
3973 Some(Identifier::private("#contains_operator")),
3974 )],
3975 );
3976 self.emit_import_all_instr(erg_std_mod);
3977 }
3978
3979 fn load_record_type(&mut self) {
3980 self.emit_global_import_items(
3981 Identifier::static_public("collections"),
3982 vec![(
3983 Identifier::static_public("namedtuple"),
3984 Some(Identifier::private("#NamedTuple")),
3985 )],
3986 );
3987 }
3988
3989 fn load_abc(&mut self) {
3990 self.emit_global_import_items(
3991 Identifier::static_public("abc"),
3992 vec![
3993 (
3994 Identifier::static_public("ABCMeta"),
3995 Some(Identifier::private("#ABCMeta")),
3996 ),
3997 (
3998 Identifier::static_public("abstractmethod"),
3999 Some(Identifier::private("#abstractmethod")),
4000 ),
4001 ],
4002 );
4003 }
4004
4005 fn load_union(&mut self) {
4006 self.emit_global_import_items(
4007 Identifier::static_public("_erg_type"),
4008 vec![(
4009 Identifier::static_public("UnionType"),
4010 Some(Identifier::private("#UnionType")),
4011 )],
4012 );
4013 }
4014
4015 fn load_fake_generic(&mut self) {
4016 self.emit_global_import_items(
4017 Identifier::static_public("_erg_type"),
4018 vec![(
4019 Identifier::static_public("FakeGenericAlias"),
4020 Some(Identifier::private("#FakeGenericAlias")),
4021 )],
4022 );
4023 }
4024
4025 fn load_module_type(&mut self) {
4026 self.emit_global_import_items(
4027 Identifier::static_public("types"),
4028 vec![(
4029 Identifier::static_public("ModuleType"),
4030 Some(Identifier::private("#ModuleType")),
4031 )],
4032 );
4033 }
4034
4035 fn load_builtins(&mut self) {
4036 self.emit_global_import_items(
4037 Identifier::static_public("_erg_builtins"),
4038 vec![(
4039 Identifier::static_public("sum"),
4040 Some(Identifier::private("#sum")),
4041 )],
4042 );
4043 }
4044
4045 pub fn emit(&mut self, hir: HIR) -> CodeObj {
4046 log!(info "the code-generating process has started.{RESET}");
4047 self.unit_size += 1;
4048 self.units.push(PyCodeGenUnit::new(
4049 self.unit_size,
4050 self.py_version,
4051 vec![],
4052 0,
4053 Str::rc(self.cfg.input.enclosed_name()),
4054 "<module>",
4055 1,
4056 0,
4057 ));
4058 if self.py_version.minor >= Some(11) {
4059 self.write_instr(Opcode311::RESUME);
4060 self.write_arg(0);
4061 }
4062 if !self.cfg.no_std && !self.prelude_loaded {
4063 self.load_prelude();
4064 }
4065 for chunk in hir.module.into_iter() {
4066 self.emit_chunk(chunk);
4067 if self.stack_len() == 1 {
4069 self.emit_pop_top();
4070 }
4071 }
4072 self.cancel_if_pop_top(); if self.input().is_repl() {
4074 if self.stack_len() == 1 {
4075 self.emit_print_expr();
4076 }
4077 self.stack_dec_n(self.stack_len() as usize);
4078 }
4079 if self.stack_len() == 0 {
4080 self.emit_load_const(ValueObj::None);
4081 } else if self.stack_len() > 1 {
4082 let block_id = self.cur_block().id;
4083 let stack_len = self.stack_len();
4084 CompileError::stack_bug(
4085 self.input().clone(),
4086 Location::Unknown,
4087 stack_len,
4088 block_id,
4089 fn_name_full!(),
4090 )
4091 .write_to_stderr();
4092 self.crash("error in emit: invalid stack size");
4093 }
4094 self.write_instr(RETURN_VALUE);
4095 self.write_arg(0);
4096 if !self.cur_block_codeobj().varnames.is_empty() {
4098 self.mut_cur_block_codeobj().flags += CodeObjFlags::NewLocals as u32;
4099 }
4100 let unit = self.units.pop().unwrap();
4102 if !self.units.is_empty() {
4103 let ld = unit.prev_lineno - self.cur_block().prev_lineno;
4104 if ld != 0 {
4105 if let Some(l) = self.mut_cur_block_codeobj().lnotab.last_mut() {
4106 *l += u8::try_from(ld).unwrap();
4107 }
4108 self.mut_cur_block().prev_lineno += ld;
4109 }
4110 }
4111 log!(info "the code-generating process has completed.{RESET}");
4112 unit.codeobj
4113 }
4114}