Merge branch 'main' into lib.d

This commit is contained in:
Shunsuke Shibayama 2024-02-11 22:00:42 +09:00
commit 7823243dbe
3 changed files with 99 additions and 44 deletions

View file

@ -320,6 +320,10 @@ impl PyCodeGenerator {
self.units.last().unwrap()
}
fn is_toplevel(&self) -> bool {
self.cur_block() == self.toplevel_block()
}
fn captured_vars(&self) -> Vec<&str> {
let mut caps = vec![];
for unit in self.units.iter() {
@ -634,7 +638,7 @@ impl PyCodeGenerator {
})
}
fn local_search(&self, name: &str, _acc_kind: AccessKind) -> Option<Name> {
fn local_search(&self, name: &str, acc_kind: AccessKind) -> Option<Name> {
if self.py_version.minor < Some(11) {
if let Some(idx) = self
.cur_block_codeobj()
@ -645,34 +649,47 @@ impl PyCodeGenerator {
return Some(Name::deref(idx));
}
}
if let Some(idx) = self
.cur_block_codeobj()
.varnames
.iter()
.position(|v| &**v == name)
{
if self.captured_vars().contains(&name) {
Some(Name::deref(idx))
} else {
Some(Name::fast(idx))
match acc_kind {
AccessKind::Name => {
if let Some(idx) = self
.cur_block_codeobj()
.freevars
.iter()
.position(|f| &**f == name)
{
Some(Name::deref(idx))
} else if let Some(idx) = self
.cur_block_codeobj()
.varnames
.iter()
.position(|v| &**v == name)
{
if self.captured_vars().contains(&name) {
None
} else {
Some(Name::fast(idx))
}
} else if let Some(idx) = self
.cur_block_codeobj()
.names
.iter()
.position(|n| &**n == name)
{
if !self.is_toplevel() {
None
} else {
Some(Name::local(idx))
}
} else {
None
}
}
} else if let Some(idx) = self
.cur_block_codeobj()
.names
.iter()
.position(|n| &**n == name)
{
if self.py_version.minor >= Some(11) && self.captured_vars().contains(&name) {
None
} else {
Some(Name::local(idx))
}
} else {
self.cur_block_codeobj()
.freevars
_ => self
.cur_block_codeobj()
.names
.iter()
.position(|f| &**f == name)
.map(Name::deref)
.position(|n| &**n == name)
.map(Name::local),
}
}
@ -702,7 +719,7 @@ impl PyCodeGenerator {
}
fn register_name(&mut self, name: Str, kind: RegisterNameKind) -> Name {
let current_is_toplevel = self.cur_block() == self.toplevel_block();
let current_is_toplevel = self.is_toplevel();
match self.rec_search(&name) {
Some(st @ (StoreLoadKind::Local | StoreLoadKind::Global)) => {
if kind.is_fast() {
@ -843,6 +860,7 @@ impl PyCodeGenerator {
self.write_instr(instr);
self.write_arg(name.idx);
self.stack_inc();
self.mut_cur_block_codeobj().stacksize += 2;
if instr == LOAD_GLOBAL as u8 && self.py_version.minor >= Some(11) {
self.write_bytes(&[0; 2]);
self.write_bytes(&[0; 8]);
@ -3098,6 +3116,10 @@ impl PyCodeGenerator {
fn emit_dict(&mut self, dict: crate::hir::Dict) {
let init_stack_len = self.stack_len();
if !self.cfg.no_std {
self.emit_push_null();
self.emit_load_name_instr(Identifier::public("Dict"));
}
match dict {
crate::hir::Dict::Normal(dic) => {
let len = dic.kvs.len();
@ -3115,6 +3137,10 @@ impl PyCodeGenerator {
}
other => todo!("{other}"),
}
if !self.cfg.no_std {
self.emit_call_instr(1, Name);
self.stack_dec();
}
debug_assert_eq!(self.stack_len(), init_stack_len + 1);
}
@ -3304,8 +3330,9 @@ impl PyCodeGenerator {
fn emit_expr(&mut self, expr: Expr) {
log!(info "entered {} ({expr})", fn_name!());
self.push_lnotab(&expr);
let init_stack_len = self.stack_len();
let mut wrapped = true;
if !self.cfg.no_std {
if !self.cfg.no_std && expr.should_wrap() {
match expr.ref_t().derefine() {
Bool => {
self.emit_push_null();
@ -3353,6 +3380,8 @@ impl PyCodeGenerator {
}
},
}
} else {
wrapped = false;
}
match expr {
Expr::Literal(lit) => self.emit_load_const(lit.value),
@ -3380,6 +3409,7 @@ impl PyCodeGenerator {
self.emit_call_instr(1, Name);
self.stack_dec();
}
debug_assert_eq!(self.stack_len(), init_stack_len + 1);
}
/// forブロックなどで使う
@ -3716,11 +3746,11 @@ impl PyCodeGenerator {
0
};
let mut cells = vec![];
if self.py_version.minor >= Some(11) {
for captured in captured_names {
self.mut_cur_block()
.captured_vars
.push(captured.inspect().clone());
for captured in captured_names {
self.mut_cur_block()
.captured_vars
.push(captured.inspect().clone());
if self.py_version.minor >= Some(11) {
self.write_instr(Opcode311::MAKE_CELL);
cells.push((captured, self.lasti()));
self.write_arg(0);

View file

@ -2850,6 +2850,18 @@ impl Expr {
}
}
pub fn should_wrap(&self) -> bool {
match self {
Self::Literal(_)
| Self::Accessor(_)
| Self::Call(_)
| Self::BinOp(_)
| Self::UnaryOp(_) => true,
Self::TypeAsc(t) => t.expr.should_wrap(),
_ => false,
}
}
pub fn need_to_be_closed(&self) -> bool {
match self {
Self::BinOp(_) | Self::UnaryOp(_) | Self::Lambda(_) | Self::TypeAsc(_) => true,

View file

@ -629,10 +629,17 @@ impl CodeObj {
}
match op308 {
Opcode308::STORE_DEREF | Opcode308::LOAD_DEREF => {
write!(instrs, "{arg} ({})", self.freevars.get(arg).unwrap()).unwrap();
write!(
instrs,
"{arg} ({})",
self.freevars
.get(arg)
.unwrap_or_else(|| &self.cellvars[arg])
)
.unwrap();
}
Opcode308::LOAD_CLOSURE => {
write!(instrs, "{arg} ({})", self.cellvars.get(arg).unwrap()).unwrap();
write!(instrs, "{arg} ({})", self.cellvars[arg]).unwrap();
}
Opcode308::JUMP_ABSOLUTE => {
write!(instrs, "{arg} (to {})", arg).unwrap();
@ -670,10 +677,17 @@ impl CodeObj {
}
match op309 {
Opcode309::STORE_DEREF | Opcode309::LOAD_DEREF => {
write!(instrs, "{arg} ({})", self.freevars.get(arg).unwrap()).unwrap();
write!(
instrs,
"{arg} ({})",
self.freevars
.get(arg)
.unwrap_or_else(|| &self.cellvars[arg])
)
.unwrap();
}
Opcode309::LOAD_CLOSURE => {
write!(instrs, "{arg} ({})", self.cellvars.get(arg).unwrap()).unwrap();
write!(instrs, "{arg} ({})", self.cellvars[arg]).unwrap();
}
Opcode309::JUMP_ABSOLUTE => {
write!(instrs, "{arg} (to {})", arg).unwrap();
@ -716,13 +730,12 @@ impl CodeObj {
"{arg} ({})",
self.freevars
.get(arg)
.or_else(|| self.varnames.get(arg))
.unwrap()
.unwrap_or_else(|| &self.cellvars[arg])
)
.unwrap();
}
Opcode310::LOAD_CLOSURE => {
write!(instrs, "{arg} ({})", self.cellvars.get(arg).unwrap()).unwrap();
write!(instrs, "{arg} ({})", self.cellvars[arg]).unwrap();
}
Opcode310::JUMP_ABSOLUTE => {
write!(instrs, "{arg} (to {})", arg * 2).unwrap();
@ -762,10 +775,10 @@ impl CodeObj {
}
match op311 {
Opcode311::STORE_DEREF | Opcode311::LOAD_DEREF => {
write!(instrs, "{arg} ({})", self.varnames.get(arg).unwrap()).unwrap();
write!(instrs, "{arg} ({})", self.varnames[arg]).unwrap();
}
Opcode311::MAKE_CELL | Opcode311::LOAD_CLOSURE => {
write!(instrs, "{arg} ({})", self.varnames.get(arg).unwrap()).unwrap();
write!(instrs, "{arg} ({})", self.varnames[arg]).unwrap();
}
Opcode311::POP_JUMP_FORWARD_IF_FALSE | Opcode311::POP_JUMP_FORWARD_IF_TRUE => {
write!(instrs, "{arg} (to {})", idx + arg * 2 + 2).unwrap();
@ -787,7 +800,7 @@ impl CodeObj {
write!(instrs, "{arg}").unwrap();
}
Opcode311::KW_NAMES => {
write!(instrs, "{arg} ({})", self.consts.get(arg).unwrap()).unwrap();
write!(instrs, "{arg} ({})", self.consts[arg]).unwrap();
}
Opcode311::BINARY_OP => {
write!(