mirror of
https://github.com/erg-lang/erg.git
synced 2025-10-02 13:41:10 +00:00
fix: closure codegen bug
This commit is contained in:
parent
0bfd4044b5
commit
4012b323d5
4 changed files with 22 additions and 4 deletions
|
@ -1484,15 +1484,24 @@ impl PyCodeGenerator {
|
||||||
fn register_cellvars(&mut self, flag: &mut usize) {
|
fn register_cellvars(&mut self, flag: &mut usize) {
|
||||||
if !self.cur_block_codeobj().cellvars.is_empty() {
|
if !self.cur_block_codeobj().cellvars.is_empty() {
|
||||||
let cellvars_len = self.cur_block_codeobj().cellvars.len();
|
let cellvars_len = self.cur_block_codeobj().cellvars.len();
|
||||||
for i in 0..cellvars_len {
|
let cellvars = self.cur_block_codeobj().cellvars.clone();
|
||||||
|
for (i, name) in cellvars.iter().enumerate() {
|
||||||
|
// Since 3.11, LOAD_CLOSURE is simply an alias for LOAD_FAST.
|
||||||
if self.py_version.minor >= Some(11) {
|
if self.py_version.minor >= Some(11) {
|
||||||
|
let idx = self
|
||||||
|
.cur_block_codeobj()
|
||||||
|
.varnames
|
||||||
|
.iter()
|
||||||
|
.position(|n| n == name)
|
||||||
|
.unwrap();
|
||||||
self.write_instr(Opcode311::MAKE_CELL);
|
self.write_instr(Opcode311::MAKE_CELL);
|
||||||
self.write_arg(i);
|
self.write_arg(idx);
|
||||||
self.write_instr(Opcode311::LOAD_CLOSURE);
|
self.write_instr(Opcode311::LOAD_CLOSURE);
|
||||||
|
self.write_arg(idx);
|
||||||
} else {
|
} else {
|
||||||
self.write_instr(Opcode310::LOAD_CLOSURE);
|
self.write_instr(Opcode310::LOAD_CLOSURE);
|
||||||
|
self.write_arg(i);
|
||||||
}
|
}
|
||||||
self.write_arg(i);
|
|
||||||
}
|
}
|
||||||
self.write_instr(BUILD_TUPLE);
|
self.write_instr(BUILD_TUPLE);
|
||||||
self.write_arg(cellvars_len);
|
self.write_arg(cellvars_len);
|
||||||
|
|
|
@ -745,7 +745,7 @@ impl CodeObj {
|
||||||
write!(instrs, "{arg} ({})", self.varnames.get(arg).unwrap()).unwrap();
|
write!(instrs, "{arg} ({})", self.varnames.get(arg).unwrap()).unwrap();
|
||||||
}
|
}
|
||||||
Opcode311::MAKE_CELL | Opcode311::LOAD_CLOSURE => {
|
Opcode311::MAKE_CELL | Opcode311::LOAD_CLOSURE => {
|
||||||
write!(instrs, "{arg} ({})", self.cellvars.get(arg).unwrap()).unwrap();
|
write!(instrs, "{arg} ({})", self.varnames.get(arg).unwrap()).unwrap();
|
||||||
}
|
}
|
||||||
Opcode311::POP_JUMP_FORWARD_IF_FALSE | Opcode311::POP_JUMP_FORWARD_IF_TRUE => {
|
Opcode311::POP_JUMP_FORWARD_IF_FALSE | Opcode311::POP_JUMP_FORWARD_IF_TRUE => {
|
||||||
write!(instrs, "{arg} (to {})", idx + arg * 2 + 2).unwrap();
|
write!(instrs, "{arg} (to {})", idx + arg * 2 + 2).unwrap();
|
||||||
|
|
4
tests/should_ok/closure.er
Normal file
4
tests/should_ok/closure.er
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
func vers: Array(Int), version: Int =
|
||||||
|
all map(v -> v == version, vers)
|
||||||
|
|
||||||
|
assert func([1, 1], 1)
|
|
@ -51,6 +51,11 @@ fn exec_class_attr() -> Result<(), ()> {
|
||||||
expect_success("tests/should_ok/class_attr.er", 2)
|
expect_success("tests/should_ok/class_attr.er", 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn exec_closure() -> Result<(), ()> {
|
||||||
|
expect_success("tests/should_ok/closure.er", 0)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn exec_collection() -> Result<(), ()> {
|
fn exec_collection() -> Result<(), ()> {
|
||||||
expect_success("tests/should_ok/collection.er", 0)
|
expect_success("tests/should_ok/collection.er", 0)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue