@@ -3,7 +3,7 @@ pub mod instructions;
3
3
use super :: objects:: { Code , ObjectStore , ObjectRef , ObjectContent , PrimitiveObjects , Object } ;
4
4
use super :: sandbox:: EnvProxy ;
5
5
use super :: stack:: { Stack , VectorStack } ;
6
- use self :: instructions:: Instruction ;
6
+ use self :: instructions:: { CmpOperator , Instruction } ;
7
7
use std:: fmt;
8
8
use std:: collections:: HashMap ;
9
9
use std:: io:: Read ;
@@ -172,11 +172,13 @@ impl<EP: EnvProxy> Processor<EP> {
172
172
let mut stacks = Stacks { var_stack : VectorStack :: new ( ) , loop_stack : VectorStack :: new ( ) } ;
173
173
loop {
174
174
let instruction = try!( instructions. get ( program_counter) . ok_or ( ProcessorError :: InvalidProgramCounter ) ) ;
175
+ program_counter += 1 ;
175
176
match * instruction {
176
177
Instruction :: PopTop => {
177
178
pop_stack ! ( stacks. var_stack) ;
178
179
( )
179
180
} ,
181
+ Instruction :: Nop => ( ) ,
180
182
Instruction :: BinarySubscr => {
181
183
let index_ref = pop_stack ! ( stacks. var_stack) ;
182
184
let index = self . store . deref ( & index_ref) . content . clone ( ) ;
@@ -207,13 +209,6 @@ impl<EP: EnvProxy> Processor<EP> {
207
209
let name = try!( code. names . get ( i) . ok_or ( ProcessorError :: InvalidNameIndex ) ) . clone ( ) ;
208
210
stacks. var_stack . push ( try!( self . load_name ( namespace, name) ) )
209
211
}
210
- Instruction :: SetupLoop ( i) => {
211
- stacks. loop_stack . push ( Loop { begin : program_counter, end : program_counter+i } )
212
- }
213
- Instruction :: LoadFast ( i) => {
214
- let name = try!( code. varnames . get ( i) . ok_or ( ProcessorError :: InvalidVarnameIndex ) ) . clone ( ) ;
215
- stacks. var_stack . push ( try!( self . load_name ( namespace, name) ) )
216
- }
217
212
Instruction :: LoadAttr ( i) => {
218
213
let obj = {
219
214
let obj_ref = try!( stacks. var_stack . pop ( ) . ok_or ( ProcessorError :: StackTooSmall ) ) ;
@@ -222,6 +217,36 @@ impl<EP: EnvProxy> Processor<EP> {
222
217
let name = try!( code. names . get ( i) . ok_or ( ProcessorError :: InvalidNameIndex ) ) . clone ( ) ;
223
218
stacks. var_stack . push ( try!( self . load_attr ( & obj, name) ) )
224
219
} ,
220
+ Instruction :: SetupLoop ( i) => {
221
+ stacks. loop_stack . push ( Loop { begin : program_counter, end : program_counter+i } )
222
+ }
223
+ Instruction :: CompareOp ( CmpOperator :: Eq ) => {
224
+ // TODO: enhance this
225
+ let obj1 = self . store . deref ( & pop_stack ! ( stacks. var_stack) ) ;
226
+ let obj2 = self . store . deref ( & pop_stack ! ( stacks. var_stack) ) ;
227
+ if obj1. name == obj2. name && obj1. content == obj2. content {
228
+ stacks. var_stack . push ( self . primitive_objects . true_obj . clone ( ) )
229
+ }
230
+ else {
231
+ stacks. var_stack . push ( self . primitive_objects . false_obj . clone ( ) )
232
+ } ;
233
+ }
234
+ Instruction :: JumpForward ( delta) => {
235
+ program_counter += delta
236
+ }
237
+ Instruction :: LoadFast ( i) => {
238
+ let name = try!( code. varnames . get ( i) . ok_or ( ProcessorError :: InvalidVarnameIndex ) ) . clone ( ) ;
239
+ stacks. var_stack . push ( try!( self . load_name ( namespace, name) ) )
240
+ }
241
+ Instruction :: PopJumpIfFalse ( target) => {
242
+ let obj = self . store . deref ( & pop_stack ! ( stacks. var_stack) ) ;
243
+ match obj. content {
244
+ ObjectContent :: True => ( ) ,
245
+ ObjectContent :: False => program_counter = target,
246
+ _ => unimplemented ! ( ) ,
247
+ }
248
+ }
249
+
225
250
Instruction :: CallFunction ( nb_args, nb_kwargs) => {
226
251
// See “Call constructs” at:
227
252
// http://security.coverity.com/blog/2014/Nov/understanding-python-bytecode.html
@@ -245,7 +270,6 @@ impl<EP: EnvProxy> Processor<EP> {
245
270
} ,
246
271
_ => panic ! ( format!( "todo: instruction {:?}" , * instruction) ) ,
247
272
}
248
- program_counter += 1 ;
249
273
} ;
250
274
}
251
275
0 commit comments