mirror of
https://github.com/RustPython/Parser.git
synced 2025-07-19 02:55:50 +00:00
Fix augassign double-loading the container of the target
This commit is contained in:
parent
d9653b4895
commit
e5eb2739b7
1 changed files with 61 additions and 8 deletions
|
@ -763,14 +763,7 @@ impl Compiler {
|
||||||
self.compile_store(target)?;
|
self.compile_store(target)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AugAssign { target, op, value } => {
|
AugAssign { target, op, value } => self.compile_augassign(target, op, value)?,
|
||||||
self.compile_expression(target)?;
|
|
||||||
self.compile_expression(value)?;
|
|
||||||
|
|
||||||
// Perform operation:
|
|
||||||
self.compile_op(op, true);
|
|
||||||
self.compile_store(target)?;
|
|
||||||
}
|
|
||||||
AnnAssign {
|
AnnAssign {
|
||||||
target,
|
target,
|
||||||
annotation,
|
annotation,
|
||||||
|
@ -1652,6 +1645,66 @@ impl Compiler {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn compile_augassign(
|
||||||
|
&mut self,
|
||||||
|
target: &ast::Expr,
|
||||||
|
op: &ast::Operator,
|
||||||
|
value: &ast::Expr,
|
||||||
|
) -> CompileResult<()> {
|
||||||
|
enum AugAssignKind<'a> {
|
||||||
|
Name { id: &'a str },
|
||||||
|
Subscript,
|
||||||
|
Attr { idx: bytecode::NameIdx },
|
||||||
|
}
|
||||||
|
|
||||||
|
let kind = match &target.node {
|
||||||
|
ast::ExprKind::Name { id, .. } => {
|
||||||
|
self.compile_name(id, NameUsage::Load)?;
|
||||||
|
AugAssignKind::Name { id }
|
||||||
|
}
|
||||||
|
ast::ExprKind::Subscript { value, slice, .. } => {
|
||||||
|
self.compile_expression(value)?;
|
||||||
|
self.compile_expression(slice)?;
|
||||||
|
self.emit(Instruction::Duplicate2);
|
||||||
|
self.emit(Instruction::Subscript);
|
||||||
|
AugAssignKind::Subscript
|
||||||
|
}
|
||||||
|
ast::ExprKind::Attribute { value, attr, .. } => {
|
||||||
|
self.check_forbidden_name(attr, NameUsage::Store)?;
|
||||||
|
self.compile_expression(value)?;
|
||||||
|
self.emit(Instruction::Duplicate);
|
||||||
|
let idx = self.name(attr);
|
||||||
|
self.emit(Instruction::LoadAttr { idx });
|
||||||
|
AugAssignKind::Attr { idx }
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return Err(self.error(CompileErrorType::Assign(target.node.name())));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
self.compile_expression(value)?;
|
||||||
|
self.compile_op(op, true);
|
||||||
|
|
||||||
|
match kind {
|
||||||
|
AugAssignKind::Name { id } => {
|
||||||
|
// stack: RESULT
|
||||||
|
self.compile_name(id, NameUsage::Store)?;
|
||||||
|
}
|
||||||
|
AugAssignKind::Subscript => {
|
||||||
|
// stack: CONTAINER SLICE RESULT
|
||||||
|
self.emit(Instruction::Rotate { amount: 3 });
|
||||||
|
self.emit(Instruction::StoreSubscript);
|
||||||
|
}
|
||||||
|
AugAssignKind::Attr { idx } => {
|
||||||
|
// stack: CONTAINER RESULT
|
||||||
|
self.emit(Instruction::Rotate { amount: 2 });
|
||||||
|
self.emit(Instruction::StoreAttr { idx });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn compile_op(&mut self, op: &ast::Operator, inplace: bool) {
|
fn compile_op(&mut self, op: &ast::Operator, inplace: bool) {
|
||||||
let op = match op {
|
let op = match op {
|
||||||
ast::Operator::Add => bytecode::BinaryOperator::Add,
|
ast::Operator::Add => bytecode::BinaryOperator::Add,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue