@@ -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 ) ]
@@ -133,6 +134,7 @@ fn compile_function(
133134 stack_pos += function. n_returned_vars ;
134135
135136 compiler. func_name = function. name . clone ( ) ;
137+ compiler. stack_pos = stack_pos;
136138 compiler. stack_size = stack_pos;
137139 compiler. args_count = function. arguments . len ( ) ;
138140
@@ -159,8 +161,8 @@ fn compile_lines(
159161 match line {
160162 SimpleLine :: ForwardDeclaration { var } => {
161163 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 ;
164+ current_scope_layout. var_positions . insert ( var. clone ( ) , compiler. stack_pos ) ;
165+ compiler. stack_pos += 1 ;
164166 }
165167
166168 SimpleLine :: Assignment {
@@ -176,8 +178,8 @@ fn compile_lines(
176178 if let VarOrConstMallocAccess :: Var ( var) = var {
177179 declared_vars. insert ( var. clone ( ) ) ;
178180 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 ;
181+ current_scope_layout. var_positions . insert ( var. clone ( ) , compiler. stack_pos ) ;
182+ compiler. stack_pos += 1 ;
181183 }
182184
183185 instructions. push ( IntermediateInstruction :: computation (
@@ -196,11 +198,12 @@ fn compile_lines(
196198 IntermediateValue :: Constant ( 0 . into ( ) ) ,
197199 ) ) ;
198200
201+ // TODO: why is mark_vars_as_declared here?
199202 mark_vars_as_declared ( & [ arg0, arg1] , declared_vars) ;
200203 }
201204
202205 SimpleLine :: Match { value, arms } => {
203- let saved_stack_size = compiler. stack_size ;
206+ let saved_stack_pos = compiler. stack_pos ;
204207 compiler. stack_frame_layout . scopes . push ( ScopeLayout :: default ( ) ) ;
205208
206209 let match_index = compiler. match_blocks . len ( ) ;
@@ -209,11 +212,9 @@ fn compile_lines(
209212 let value_simplified = IntermediateValue :: from_simple_expr ( value, compiler) ;
210213
211214 let mut compiled_arms = vec ! [ ] ;
212- let original_stack_size = compiler. stack_size ;
213- let mut new_stack_size = original_stack_size;
214215 for ( i, arm) in arms. iter ( ) . enumerate ( ) {
215216 let mut arm_declared_vars = declared_vars. clone ( ) ;
216- compiler. stack_size = original_stack_size ;
217+ compiler. stack_pos = saved_stack_pos ;
217218 let arm_instructions = compile_lines (
218219 function_name,
219220 arm,
@@ -222,23 +223,21 @@ fn compile_lines(
222223 & mut arm_declared_vars,
223224 ) ?;
224225 compiled_arms. push ( arm_instructions) ;
225- new_stack_size = compiler. stack_size . max ( new_stack_size) ;
226226 * declared_vars = if i == 0 {
227227 arm_declared_vars
228228 } else {
229229 declared_vars. intersection ( & arm_declared_vars) . cloned ( ) . collect ( )
230230 } ;
231231 }
232- compiler. stack_size = new_stack_size;
233232 compiler. match_blocks . push ( MatchBlock {
234233 function_name : function_name. clone ( ) ,
235234 match_cases : compiled_arms,
236235 } ) ;
237236
238237 let value_scaled_offset = IntermediateValue :: MemoryAfterFp {
239- offset : compiler. stack_size . into ( ) ,
238+ offset : compiler. stack_pos . into ( ) ,
240239 } ;
241- compiler. stack_size += 1 ;
240+ compiler. stack_pos += 1 ;
242241 instructions. push ( IntermediateInstruction :: Computation {
243242 operation : Operation :: Mul ,
244243 arg_a : value_simplified,
@@ -247,9 +246,9 @@ fn compile_lines(
247246 } ) ;
248247
249248 let jump_dest_offset = IntermediateValue :: MemoryAfterFp {
250- offset : compiler. stack_size . into ( ) ,
249+ offset : compiler. stack_pos . into ( ) ,
251250 } ;
252- compiler. stack_size += 1 ;
251+ compiler. stack_pos += 1 ;
253252 instructions. push ( IntermediateInstruction :: Computation {
254253 operation : Operation :: Add ,
255254 arg_a : value_scaled_offset,
@@ -265,7 +264,9 @@ fn compile_lines(
265264 compiler. bytecode . insert ( end_label, remaining) ;
266265
267266 compiler. stack_frame_layout . scopes . pop ( ) ;
268- compiler. stack_size = saved_stack_size;
267+ compiler. stack_pos = saved_stack_pos;
268+ // It is not necessary to update compiler.stack_size here because the preceding call to
269+ // compile lines should have done so.
269270
270271 return Ok ( instructions) ;
271272 }
@@ -276,7 +277,6 @@ fn compile_lines(
276277 else_branch,
277278 line_number,
278279 } => {
279- let saved_stack_size = compiler. stack_size ;
280280 compiler. stack_frame_layout . scopes . push ( ScopeLayout :: default ( ) ) ;
281281
282282 validate_vars_declared ( & [ condition] , declared_vars) ?;
@@ -294,16 +294,16 @@ fn compile_lines(
294294 let condition_simplified = IntermediateValue :: from_simple_expr ( condition, compiler) ;
295295
296296 // 1/c (or 0 if c is zero)
297- let condition_inverse_offset = compiler. stack_size ;
298- compiler. stack_size += 1 ;
297+ let condition_inverse_offset = compiler. stack_pos ;
298+ compiler. stack_pos += 1 ;
299299 instructions. push ( IntermediateInstruction :: Inverse {
300300 arg : condition_simplified. clone ( ) ,
301301 res_offset : condition_inverse_offset,
302302 } ) ;
303303
304304 // c x 1/c
305- let product_offset = compiler. stack_size ;
306- compiler. stack_size += 1 ;
305+ let product_offset = compiler. stack_pos ;
306+ compiler. stack_pos += 1 ;
307307 instructions. push ( IntermediateInstruction :: Computation {
308308 operation : Operation :: Mul ,
309309 arg_a : condition_simplified. clone ( ) ,
@@ -314,10 +314,12 @@ fn compile_lines(
314314 offset : product_offset. into ( ) ,
315315 } ,
316316 } ) ;
317+ // It is not necessary to update compiler.stack_size here because the preceding call to
318+ // compile lines should have done so.
317319
318320 // 1 - (c x 1/c)
319- let one_minus_product_offset = compiler. stack_size ;
320- compiler. stack_size += 1 ;
321+ let one_minus_product_offset = compiler. stack_pos ;
322+ compiler. stack_pos += 1 ;
321323 instructions. push ( IntermediateInstruction :: Computation {
322324 operation : Operation :: Add ,
323325 arg_a : IntermediateValue :: MemoryAfterFp {
@@ -351,7 +353,7 @@ fn compile_lines(
351353 updated_fp : None ,
352354 } ) ;
353355
354- let original_stack = compiler. stack_size ;
356+ let saved_stack_pos = compiler. stack_pos ;
355357
356358 let mut then_declared_vars = declared_vars. clone ( ) ;
357359 let then_instructions = compile_lines (
@@ -361,9 +363,9 @@ fn compile_lines(
361363 Some ( end_label. clone ( ) ) ,
362364 & mut then_declared_vars,
363365 ) ?;
364- let then_stack = compiler. stack_size ;
365366
366- compiler. stack_size = original_stack;
367+ let then_stack_pos = compiler. stack_pos ;
368+ compiler. stack_pos = saved_stack_pos;
367369 let mut else_declared_vars = declared_vars. clone ( ) ;
368370 let else_instructions = compile_lines (
369371 function_name,
@@ -372,24 +374,23 @@ fn compile_lines(
372374 Some ( end_label. clone ( ) ) ,
373375 & mut else_declared_vars,
374376 ) ?;
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 ( ) ;
379377
380378 compiler. bytecode . insert ( if_label, then_instructions) ;
381379 compiler. bytecode . insert ( else_label, else_instructions) ;
382380
381+ compiler. stack_frame_layout . scopes . pop ( ) ;
382+ compiler. stack_pos = compiler. stack_pos . max ( then_stack_pos) ;
383+
383384 let remaining = compile_lines ( function_name, & lines[ i + 1 ..] , compiler, final_jump, declared_vars) ?;
384385 compiler. bytecode . insert ( end_label, remaining) ;
385-
386- compiler. stack_frame_layout . scopes . pop ( ) ;
387- compiler. stack_size = saved_stack_size;
386+ // It is not necessary to update compiler.stack_size here because the preceding call to
387+ // compile_lines should have done so.
388388
389389 return Ok ( instructions) ;
390390 }
391391
392392 SimpleLine :: RawAccess { res, index, shift } => {
393+ // TODO: why is validate_vars_declared here?
393394 validate_vars_declared ( & [ index] , declared_vars) ?;
394395 if let SimpleExpr :: Var ( var) = res {
395396 declared_vars. insert ( var. clone ( ) ) ;
@@ -415,8 +416,8 @@ fn compile_lines(
415416 compiler. call_counter += 1 ;
416417 let return_label = Label :: return_from_call ( call_id, * line_number) ;
417418
418- let new_fp_pos = compiler. stack_size ;
419- compiler. stack_size += 1 ;
419+ let new_fp_pos = compiler. stack_pos ;
420+ compiler. stack_pos += 1 ;
420421
421422 instructions. extend ( setup_function_call (
422423 callee_function_name,
@@ -426,12 +427,13 @@ fn compile_lines(
426427 compiler,
427428 ) ?) ;
428429
430+ // TODO: why is validate_vars_declared here?
429431 validate_vars_declared ( args, declared_vars) ?;
430432 declared_vars. extend ( return_data. iter ( ) . cloned ( ) ) ;
431433 for var in return_data. iter ( ) {
432434 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 ;
435+ current_scope_layout. var_positions . insert ( var. clone ( ) , compiler. stack_pos ) ;
436+ compiler. stack_pos += 1 ;
435437 }
436438
437439 let after_call = {
@@ -460,6 +462,8 @@ fn compile_lines(
460462 } ;
461463
462464 compiler. bytecode . insert ( return_label, after_call) ;
465+ // It is not necessary to update compiler.stack_size here because the preceding call to
466+ // compile_lines should have done so.
463467
464468 return Ok ( instructions) ;
465469 }
@@ -483,9 +487,9 @@ fn compile_lines(
483487 if compiler. func_name == "main" {
484488 // pc -> ending_pc, fp -> 0
485489 let zero_value_offset = IntermediateValue :: MemoryAfterFp {
486- offset : compiler. stack_size . into ( ) ,
490+ offset : compiler. stack_pos . into ( ) ,
487491 } ;
488- compiler. stack_size += 1 ;
492+ compiler. stack_pos += 1 ;
489493 instructions. push ( IntermediateInstruction :: Computation {
490494 operation : Operation :: Add ,
491495 arg_a : IntermediateValue :: Constant ( 0 . into ( ) ) ,
@@ -508,8 +512,8 @@ fn compile_lines(
508512 vectorized_len,
509513 } => {
510514 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 ;
515+ current_scope_layout. var_positions . insert ( var. clone ( ) , compiler. stack_pos ) ;
516+ compiler. stack_pos += 1 ;
513517 declared_vars. insert ( var. clone ( ) ) ;
514518 instructions. push ( IntermediateInstruction :: RequestMemory {
515519 offset : compiler. get_offset ( & var. clone ( ) . into ( ) ) ,
@@ -528,12 +532,13 @@ fn compile_lines(
528532 label,
529533 } => {
530534 instructions. push ( IntermediateInstruction :: DecomposeBits {
531- res_offset : compiler. stack_size ,
535+ res_offset : compiler. stack_pos ,
532536 to_decompose : to_decompose
533537 . iter ( )
534538 . map ( |expr| IntermediateValue :: from_simple_expr ( expr, compiler) )
535539 . collect ( ) ,
536540 } ) ;
541+ compiler. stack_pos += 1 ; // TODO: is this right?
537542
538543 handle_const_malloc (
539544 declared_vars,
@@ -550,12 +555,13 @@ fn compile_lines(
550555 label,
551556 } => {
552557 instructions. push ( IntermediateInstruction :: DecomposeCustom {
553- res_offset : compiler. stack_size ,
558+ res_offset : compiler. stack_pos ,
554559 to_decompose : to_decompose
555560 . iter ( )
556561 . map ( |expr| IntermediateValue :: from_simple_expr ( expr, compiler) )
557562 . collect ( ) ,
558563 } ) ;
564+ compiler. stack_pos += 1 ; // TODO: is this right?
559565
560566 handle_const_malloc (
561567 declared_vars,
@@ -568,8 +574,8 @@ fn compile_lines(
568574 }
569575 SimpleLine :: CounterHint { var } => {
570576 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 ;
577+ current_scope_layout. var_positions . insert ( var. clone ( ) , compiler. stack_pos ) ;
578+ compiler. stack_pos += 1 ;
573579 declared_vars. insert ( var. clone ( ) ) ;
574580 instructions. push ( IntermediateInstruction :: CounterHint {
575581 res_offset : compiler
@@ -594,6 +600,8 @@ fn compile_lines(
594600 }
595601 }
596602
603+ compiler. stack_size = compiler. stack_size . max ( compiler. stack_pos ) ;
604+
597605 if let Some ( jump_label) = final_jump {
598606 instructions. push ( IntermediateInstruction :: Jump {
599607 dest : IntermediateValue :: label ( jump_label) ,
@@ -622,8 +630,8 @@ fn handle_const_malloc(
622630 } ,
623631 } ) ;
624632 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;
633+ current_scope. const_mallocs . insert ( * label, compiler. stack_pos ) ;
634+ compiler. stack_pos += size;
627635}
628636
629637// Helper functions
0 commit comments