@@ -17,6 +17,7 @@ struct Compiler {
1717 stack_frame_layout : StackFrameLayout ,
1818 args_count : usize ,
1919 stack_size : usize ,
20+ stack_pos : usize ,
2021}
2122
2223#[ derive( Default ) ]
@@ -104,6 +105,8 @@ pub fn compile_to_intermediate_bytecode(simple_program: SimpleProgram) -> Result
104105 let instructions = compile_function ( function, & mut compiler) ?;
105106 compiler. bytecode . insert ( Label :: function ( & function. name ) , instructions) ;
106107 memory_sizes. insert ( function. name . clone ( ) , compiler. stack_size ) ;
108+ compiler. stack_size = 0 ;
109+ compiler. stack_pos = 0 ;
107110 }
108111
109112 Ok ( IntermediateBytecode {
@@ -133,6 +136,7 @@ fn compile_function(
133136 stack_pos += function. n_returned_vars ;
134137
135138 compiler. func_name = function. name . clone ( ) ;
139+ compiler. stack_pos = stack_pos;
136140 compiler. stack_size = stack_pos;
137141 compiler. args_count = function. arguments . len ( ) ;
138142
@@ -159,8 +163,8 @@ fn compile_lines(
159163 match line {
160164 SimpleLine :: ForwardDeclaration { var } => {
161165 let mut current_scope_layout = compiler. stack_frame_layout . scopes . last_mut ( ) . unwrap ( ) ;
162- current_scope_layout. var_positions . insert ( var. clone ( ) , compiler. stack_size ) ;
163- compiler. stack_size += 1 ;
166+ current_scope_layout. var_positions . insert ( var. clone ( ) , compiler. stack_pos ) ;
167+ compiler. stack_pos += 1 ;
164168 }
165169
166170 SimpleLine :: Assignment {
@@ -176,8 +180,8 @@ fn compile_lines(
176180 if let VarOrConstMallocAccess :: Var ( var) = var {
177181 declared_vars. insert ( var. clone ( ) ) ;
178182 let mut current_scope_layout = compiler. stack_frame_layout . scopes . last_mut ( ) . unwrap ( ) ;
179- current_scope_layout. var_positions . insert ( var. clone ( ) , compiler. stack_size ) ;
180- compiler. stack_size += 1 ;
183+ current_scope_layout. var_positions . insert ( var. clone ( ) , compiler. stack_pos ) ;
184+ compiler. stack_pos += 1 ;
181185 }
182186
183187 instructions. push ( IntermediateInstruction :: computation (
@@ -196,11 +200,12 @@ fn compile_lines(
196200 IntermediateValue :: Constant ( 0 . into ( ) ) ,
197201 ) ) ;
198202
203+ // TODO: why is mark_vars_as_declared here?
199204 mark_vars_as_declared ( & [ arg0, arg1] , declared_vars) ;
200205 }
201206
202207 SimpleLine :: Match { value, arms } => {
203- let saved_stack_size = compiler. stack_size ;
208+ let saved_stack_pos = compiler. stack_pos ;
204209 compiler. stack_frame_layout . scopes . push ( ScopeLayout :: default ( ) ) ;
205210
206211 let match_index = compiler. match_blocks . len ( ) ;
@@ -209,11 +214,9 @@ fn compile_lines(
209214 let value_simplified = IntermediateValue :: from_simple_expr ( value, compiler) ;
210215
211216 let mut compiled_arms = vec ! [ ] ;
212- let original_stack_size = compiler. stack_size ;
213- let mut new_stack_size = original_stack_size;
214217 for ( i, arm) in arms. iter ( ) . enumerate ( ) {
215218 let mut arm_declared_vars = declared_vars. clone ( ) ;
216- compiler. stack_size = original_stack_size ;
219+ compiler. stack_pos = saved_stack_pos ;
217220 let arm_instructions = compile_lines (
218221 function_name,
219222 arm,
@@ -222,23 +225,21 @@ fn compile_lines(
222225 & mut arm_declared_vars,
223226 ) ?;
224227 compiled_arms. push ( arm_instructions) ;
225- new_stack_size = compiler. stack_size . max ( new_stack_size) ;
226228 * declared_vars = if i == 0 {
227229 arm_declared_vars
228230 } else {
229231 declared_vars. intersection ( & arm_declared_vars) . cloned ( ) . collect ( )
230232 } ;
231233 }
232- compiler. stack_size = new_stack_size;
233234 compiler. match_blocks . push ( MatchBlock {
234235 function_name : function_name. clone ( ) ,
235236 match_cases : compiled_arms,
236237 } ) ;
237238
238239 let value_scaled_offset = IntermediateValue :: MemoryAfterFp {
239- offset : compiler. stack_size . into ( ) ,
240+ offset : compiler. stack_pos . into ( ) ,
240241 } ;
241- compiler. stack_size += 1 ;
242+ compiler. stack_pos += 1 ;
242243 instructions. push ( IntermediateInstruction :: Computation {
243244 operation : Operation :: Mul ,
244245 arg_a : value_simplified,
@@ -247,9 +248,9 @@ fn compile_lines(
247248 } ) ;
248249
249250 let jump_dest_offset = IntermediateValue :: MemoryAfterFp {
250- offset : compiler. stack_size . into ( ) ,
251+ offset : compiler. stack_pos . into ( ) ,
251252 } ;
252- compiler. stack_size += 1 ;
253+ compiler. stack_pos += 1 ;
253254 instructions. push ( IntermediateInstruction :: Computation {
254255 operation : Operation :: Add ,
255256 arg_a : value_scaled_offset,
@@ -265,7 +266,9 @@ fn compile_lines(
265266 compiler. bytecode . insert ( end_label, remaining) ;
266267
267268 compiler. stack_frame_layout . scopes . pop ( ) ;
268- compiler. stack_size = saved_stack_size;
269+ compiler. stack_pos = saved_stack_pos;
270+ // It is not necessary to update compiler.stack_size here because the preceding call to
271+ // compile lines should have done so.
269272
270273 return Ok ( instructions) ;
271274 }
@@ -276,7 +279,6 @@ fn compile_lines(
276279 else_branch,
277280 line_number,
278281 } => {
279- let saved_stack_size = compiler. stack_size ;
280282 compiler. stack_frame_layout . scopes . push ( ScopeLayout :: default ( ) ) ;
281283
282284 validate_vars_declared ( & [ condition] , declared_vars) ?;
@@ -294,16 +296,16 @@ fn compile_lines(
294296 let condition_simplified = IntermediateValue :: from_simple_expr ( condition, compiler) ;
295297
296298 // 1/c (or 0 if c is zero)
297- let condition_inverse_offset = compiler. stack_size ;
298- compiler. stack_size += 1 ;
299+ let condition_inverse_offset = compiler. stack_pos ;
300+ compiler. stack_pos += 1 ;
299301 instructions. push ( IntermediateInstruction :: Inverse {
300302 arg : condition_simplified. clone ( ) ,
301303 res_offset : condition_inverse_offset,
302304 } ) ;
303305
304306 // c x 1/c
305- let product_offset = compiler. stack_size ;
306- compiler. stack_size += 1 ;
307+ let product_offset = compiler. stack_pos ;
308+ compiler. stack_pos += 1 ;
307309 instructions. push ( IntermediateInstruction :: Computation {
308310 operation : Operation :: Mul ,
309311 arg_a : condition_simplified. clone ( ) ,
@@ -314,10 +316,12 @@ fn compile_lines(
314316 offset : product_offset. into ( ) ,
315317 } ,
316318 } ) ;
319+ // It is not necessary to update compiler.stack_size here because the preceding call to
320+ // compile lines should have done so.
317321
318322 // 1 - (c x 1/c)
319- let one_minus_product_offset = compiler. stack_size ;
320- compiler. stack_size += 1 ;
323+ let one_minus_product_offset = compiler. stack_pos ;
324+ compiler. stack_pos += 1 ;
321325 instructions. push ( IntermediateInstruction :: Computation {
322326 operation : Operation :: Add ,
323327 arg_a : IntermediateValue :: MemoryAfterFp {
@@ -351,7 +355,7 @@ fn compile_lines(
351355 updated_fp : None ,
352356 } ) ;
353357
354- let original_stack = compiler. stack_size ;
358+ let saved_stack_pos = compiler. stack_pos ;
355359
356360 let mut then_declared_vars = declared_vars. clone ( ) ;
357361 let then_instructions = compile_lines (
@@ -361,9 +365,9 @@ fn compile_lines(
361365 Some ( end_label. clone ( ) ) ,
362366 & mut then_declared_vars,
363367 ) ?;
364- let then_stack = compiler. stack_size ;
365368
366- compiler. stack_size = original_stack;
369+ let then_stack_pos = compiler. stack_pos ;
370+ compiler. stack_pos = saved_stack_pos;
367371 let mut else_declared_vars = declared_vars. clone ( ) ;
368372 let else_instructions = compile_lines (
369373 function_name,
@@ -372,24 +376,23 @@ fn compile_lines(
372376 Some ( end_label. clone ( ) ) ,
373377 & mut else_declared_vars,
374378 ) ?;
375- let else_stack = compiler. stack_size ;
376-
377- compiler. stack_size = then_stack. max ( else_stack) ;
378- * declared_vars = then_declared_vars. intersection ( & else_declared_vars) . cloned ( ) . collect ( ) ;
379379
380380 compiler. bytecode . insert ( if_label, then_instructions) ;
381381 compiler. bytecode . insert ( else_label, else_instructions) ;
382382
383+ compiler. stack_frame_layout . scopes . pop ( ) ;
384+ compiler. stack_pos = compiler. stack_pos . max ( then_stack_pos) ;
385+
383386 let remaining = compile_lines ( function_name, & lines[ i + 1 ..] , compiler, final_jump, declared_vars) ?;
384387 compiler. bytecode . insert ( end_label, remaining) ;
385-
386- compiler. stack_frame_layout . scopes . pop ( ) ;
387- compiler. stack_size = saved_stack_size;
388+ // It is not necessary to update compiler.stack_size here because the preceding call to
389+ // compile_lines should have done so.
388390
389391 return Ok ( instructions) ;
390392 }
391393
392394 SimpleLine :: RawAccess { res, index, shift } => {
395+ // TODO: why is validate_vars_declared here?
393396 validate_vars_declared ( & [ index] , declared_vars) ?;
394397 if let SimpleExpr :: Var ( var) = res {
395398 declared_vars. insert ( var. clone ( ) ) ;
@@ -415,8 +418,8 @@ fn compile_lines(
415418 compiler. call_counter += 1 ;
416419 let return_label = Label :: return_from_call ( call_id, * line_number) ;
417420
418- let new_fp_pos = compiler. stack_size ;
419- compiler. stack_size += 1 ;
421+ let new_fp_pos = compiler. stack_pos ;
422+ compiler. stack_pos += 1 ;
420423
421424 instructions. extend ( setup_function_call (
422425 callee_function_name,
@@ -426,12 +429,13 @@ fn compile_lines(
426429 compiler,
427430 ) ?) ;
428431
432+ // TODO: why is validate_vars_declared here?
429433 validate_vars_declared ( args, declared_vars) ?;
430434 declared_vars. extend ( return_data. iter ( ) . cloned ( ) ) ;
431435 for var in return_data. iter ( ) {
432436 let mut current_scope_layout = compiler. stack_frame_layout . scopes . last_mut ( ) . unwrap ( ) ;
433- current_scope_layout. var_positions . insert ( var. clone ( ) , compiler. stack_size ) ;
434- compiler. stack_size += 1 ;
437+ current_scope_layout. var_positions . insert ( var. clone ( ) , compiler. stack_pos ) ;
438+ compiler. stack_pos += 1 ;
435439 }
436440
437441 let after_call = {
@@ -460,6 +464,8 @@ fn compile_lines(
460464 } ;
461465
462466 compiler. bytecode . insert ( return_label, after_call) ;
467+ // It is not necessary to update compiler.stack_size here because the preceding call to
468+ // compile_lines should have done so.
463469
464470 return Ok ( instructions) ;
465471 }
@@ -483,9 +489,9 @@ fn compile_lines(
483489 if compiler. func_name == "main" {
484490 // pc -> ending_pc, fp -> 0
485491 let zero_value_offset = IntermediateValue :: MemoryAfterFp {
486- offset : compiler. stack_size . into ( ) ,
492+ offset : compiler. stack_pos . into ( ) ,
487493 } ;
488- compiler. stack_size += 1 ;
494+ compiler. stack_pos += 1 ;
489495 instructions. push ( IntermediateInstruction :: Computation {
490496 operation : Operation :: Add ,
491497 arg_a : IntermediateValue :: Constant ( 0 . into ( ) ) ,
@@ -508,8 +514,8 @@ fn compile_lines(
508514 vectorized_len,
509515 } => {
510516 let mut current_scope_layout = compiler. stack_frame_layout . scopes . last_mut ( ) . unwrap ( ) ;
511- current_scope_layout. var_positions . insert ( var. clone ( ) , compiler. stack_size ) ;
512- compiler. stack_size += 1 ;
517+ current_scope_layout. var_positions . insert ( var. clone ( ) , compiler. stack_pos ) ;
518+ compiler. stack_pos += 1 ;
513519 declared_vars. insert ( var. clone ( ) ) ;
514520 instructions. push ( IntermediateInstruction :: RequestMemory {
515521 offset : compiler. get_offset ( & var. clone ( ) . into ( ) ) ,
@@ -528,12 +534,13 @@ fn compile_lines(
528534 label,
529535 } => {
530536 instructions. push ( IntermediateInstruction :: DecomposeBits {
531- res_offset : compiler. stack_size ,
537+ res_offset : compiler. stack_pos ,
532538 to_decompose : to_decompose
533539 . iter ( )
534540 . map ( |expr| IntermediateValue :: from_simple_expr ( expr, compiler) )
535541 . collect ( ) ,
536542 } ) ;
543+ compiler. stack_pos += 1 ; // TODO: is this right?
537544
538545 handle_const_malloc (
539546 declared_vars,
@@ -550,12 +557,13 @@ fn compile_lines(
550557 label,
551558 } => {
552559 instructions. push ( IntermediateInstruction :: DecomposeCustom {
553- res_offset : compiler. stack_size ,
560+ res_offset : compiler. stack_pos ,
554561 to_decompose : to_decompose
555562 . iter ( )
556563 . map ( |expr| IntermediateValue :: from_simple_expr ( expr, compiler) )
557564 . collect ( ) ,
558565 } ) ;
566+ compiler. stack_pos += 1 ; // TODO: is this right?
559567
560568 handle_const_malloc (
561569 declared_vars,
@@ -568,8 +576,8 @@ fn compile_lines(
568576 }
569577 SimpleLine :: CounterHint { var } => {
570578 let mut current_scope_layout = compiler. stack_frame_layout . scopes . last_mut ( ) . unwrap ( ) ;
571- current_scope_layout. var_positions . insert ( var. clone ( ) , compiler. stack_size ) ;
572- compiler. stack_size += 1 ;
579+ current_scope_layout. var_positions . insert ( var. clone ( ) , compiler. stack_pos ) ;
580+ compiler. stack_pos += 1 ;
573581 declared_vars. insert ( var. clone ( ) ) ;
574582 instructions. push ( IntermediateInstruction :: CounterHint {
575583 res_offset : compiler
@@ -594,6 +602,8 @@ fn compile_lines(
594602 }
595603 }
596604
605+ compiler. stack_size = compiler. stack_size . max ( compiler. stack_pos ) ;
606+
597607 if let Some ( jump_label) = final_jump {
598608 instructions. push ( IntermediateInstruction :: Jump {
599609 dest : IntermediateValue :: label ( jump_label) ,
@@ -622,8 +632,8 @@ fn handle_const_malloc(
622632 } ,
623633 } ) ;
624634 let current_scope = compiler. stack_frame_layout . scopes . last_mut ( ) . unwrap ( ) ;
625- current_scope. const_mallocs . insert ( * label, compiler. stack_size ) ;
626- compiler. stack_size += size;
635+ current_scope. const_mallocs . insert ( * label, compiler. stack_pos ) ;
636+ compiler. stack_pos += size;
627637}
628638
629639// Helper functions
0 commit comments