Skip to content

Commit e064aa4

Browse files
committed
Add support for large arguments en BuildTuple.
1 parent 5e16b88 commit e064aa4

File tree

2 files changed

+22
-4
lines changed

2 files changed

+22
-4
lines changed

src/processor/instructions.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ pub enum CmpOperator {
1616
}
1717

1818
impl CmpOperator {
19-
pub fn from_bytecode(n: u16) -> Self {
19+
pub fn from_bytecode(n: u32) -> Self {
2020
match n {
2121
0 => CmpOperator::Lt,
2222
1 => CmpOperator::Leq,
@@ -52,6 +52,7 @@ pub enum Instruction {
5252
ForIter(usize),
5353
LoadConst(usize),
5454
LoadName(usize),
55+
BuildTuple(usize),
5556
LoadAttr(usize),
5657
SetupLoop(usize),
5758
SetupExcept(usize),
@@ -70,12 +71,13 @@ pub enum Instruction {
7071
#[derive(Debug)]
7172
pub struct InstructionDecoder<I> where I: Iterator {
7273
bytestream: I,
74+
arg_prefix: Option<u32>,
7375
pending_nops: u8, // Number of NOPs to be inserted after this instruction to match CPython's addresses (instructions have different sizes)
7476
}
7577

7678
impl<I> InstructionDecoder<I> where I: Iterator {
7779
pub fn new(bytes: I) -> InstructionDecoder<I> {
78-
InstructionDecoder { bytestream: bytes, pending_nops: 0, }
80+
InstructionDecoder { bytestream: bytes, pending_nops: 0, arg_prefix: None, }
7981
}
8082
}
8183

@@ -89,11 +91,19 @@ impl<'a, I> InstructionDecoder<I> where I: Iterator<Item=&'a u8> {
8991
_ => panic!("End of stream in the middle of an instruction."),
9092
}
9193
}
92-
fn read_argument(&mut self) -> u16 {
94+
fn read_argument(&mut self) -> u32 {
9395
match (self.bytestream.next(), self.bytestream.next()) {
9496
(Some(b1), Some(b2)) => {
9597
self.pending_nops += 2;
96-
((*b2 as u16) << 8) + (*b1 as u16)},
98+
let arg = ((*b2 as u32) << 8) + (*b1 as u32);
99+
if let Some(prefix) = self.arg_prefix {
100+
self.arg_prefix = None;
101+
(prefix << 16) + arg
102+
}
103+
else {
104+
arg
105+
}
106+
},
97107
_ => panic!("End of stream in the middle of an instruction."),
98108
}
99109
}
@@ -122,6 +132,7 @@ impl<'a, I> Iterator for InstructionDecoder<I> where I: Iterator<Item=&'a u8> {
122132
93 => Instruction::ForIter(self.read_argument() as usize),
123133
100 => Instruction::LoadConst(self.read_argument() as usize),
124134
101 => Instruction::LoadName(self.read_argument() as usize),
135+
102 => Instruction::BuildTuple(self.read_argument() as usize),
125136
106 => Instruction::LoadAttr(self.read_argument() as usize),
126137
107 => Instruction::CompareOp(CmpOperator::from_bytecode(self.read_argument())),
127138
110 => Instruction::JumpForward(self.read_argument() as usize + 2), // +2, because JumpForward takes 3 bytes, and the relative address is computed from the next instruction.
@@ -142,6 +153,7 @@ impl<'a, I> Iterator for InstructionDecoder<I> where I: Iterator<Item=&'a u8> {
142153
let nb_annot = 0;
143154
Instruction::MakeFunction(nb_pos as usize, nb_kw as usize, nb_annot as usize)
144155
},
156+
144 => { self.arg_prefix = Some(self.read_argument()); Instruction::Nop },
145157
_ => panic!(format!("Opcode not supported: {}", opcode)),
146158
}
147159
})

src/processor/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,12 @@ fn run_code<EP: EnvProxy>(state: &mut State<EP>, call_stack: &mut Vec<Frame>) ->
390390
}
391391
}
392392
}
393+
Instruction::BuildTuple(size) => {
394+
let frame = call_stack.last_mut().unwrap();
395+
let mut content = py_unwrap!(state, frame.var_stack.pop_many(size), ProcessorError::StackTooSmall);
396+
let tuple = state.primitive_objects.new_tuple(content);
397+
frame.var_stack.push(state.store.allocate(tuple));
398+
}
393399
Instruction::LoadAttr(i) => {
394400
let (name, obj) = {
395401
let frame = call_stack.last_mut().unwrap();

0 commit comments

Comments
 (0)