@@ -19,6 +19,7 @@ struct Compiler {
1919 stack_size : usize ,
2020}
2121
22+ #[ derive( Default ) ]
2223struct StackFrameLayout {
2324 // Innermost lexical scope last
2425 scopes : Vec < ScopeLayout > ,
@@ -36,7 +37,7 @@ impl Compiler {
3637 VarOrConstMallocAccess :: Var ( var) => {
3738 for scope in self . stack_frame_layout . scopes . iter ( ) . rev ( ) {
3839 if let Some ( offset) = scope. var_positions . get ( var) {
39- return offset. into ( ) ;
40+ return ( * offset) . into ( ) ;
4041 }
4142 }
4243 panic ! ( "Variable {var} not in scope" ) ;
@@ -45,9 +46,9 @@ impl Compiler {
4546 for scope in self . stack_frame_layout . scopes . iter ( ) . rev ( ) {
4647 if let Some ( base) = scope. const_mallocs . get ( malloc_label) {
4748 return ConstExpression :: Binary {
48- left : Box :: new ( base. into ( ) ) ,
49+ left : Box :: new ( ( * base) . into ( ) ) ,
4950 operation : HighLevelOperation :: Add ,
50- right : Box :: new ( offset. clone ( ) ) ,
51+ right : Box :: new ( ( * offset) . clone ( ) ) ,
5152 } ;
5253 }
5354 }
@@ -82,7 +83,10 @@ impl IntermediateValue {
8283 } ,
8384 SimpleExpr :: Constant ( c) => Self :: Constant ( c. clone ( ) ) ,
8485 SimpleExpr :: ConstMallocAccess { malloc_label, offset } => Self :: MemoryAfterFp {
85- offset : compiler. get_offset ( SimpleExpr :: ConstMallocAccess { malloc_label, offset } ) ,
86+ offset : compiler. get_offset ( & VarOrConstMallocAccess :: ConstMallocAccess {
87+ malloc_label : * malloc_label,
88+ offset : offset. clone ( )
89+ } ) ,
8690 } ,
8791 }
8892 }
@@ -115,15 +119,14 @@ fn compile_function(
115119) -> Result < Vec < IntermediateInstruction > , String > {
116120 // memory layout: pc, fp, args, return_vars, internal_vars
117121 let mut stack_pos = 2 ; // Reserve space for pc and fp
118- let mut var_positions = BTreeMap :: new ( ) ;
119- let mut function_scope = Scope :: default ( ) ;
122+ let mut function_scope_layout = ScopeLayout :: default ( ) ;
120123 compiler. stack_frame_layout = StackFrameLayout {
121- scopes : vec ! [ function_scope ] ,
124+ scopes : vec ! [ function_scope_layout ] ,
122125 } ;
123- let function_scope = & mut compiler. stack_frame_layout . scopes [ 0 ] ;
126+ let function_scope_layout = & mut compiler. stack_frame_layout . scopes [ 0 ] ;
124127
125128 for ( i, var) in function. arguments . iter ( ) . enumerate ( ) {
126- function_scope . var_positions . insert ( var. clone ( ) , stack_pos + i) ;
129+ function_scope_layout . var_positions . insert ( var. clone ( ) , stack_pos + i) ;
127130 }
128131 stack_pos += function. arguments . len ( ) ;
129132
@@ -150,14 +153,14 @@ fn compile_lines(
150153 final_jump : Option < Label > ,
151154 declared_vars : & mut BTreeSet < Var > ,
152155) -> Result < Vec < IntermediateInstruction > , String > {
153- // TODO: amend stack frame layout with internal variables.
154-
155156 let mut instructions = Vec :: new ( ) ;
156157
157158 for ( i, line) in lines. iter ( ) . enumerate ( ) {
158159 match line {
159- SimpleLine :: ForwardDeclaration => {
160- todo ! ( ) ; // amend stack frame layout
160+ SimpleLine :: ForwardDeclaration { var } => {
161+ 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 ;
161164 }
162165
163166 SimpleLine :: Assignment {
@@ -166,18 +169,23 @@ fn compile_lines(
166169 arg0,
167170 arg1,
168171 } => {
169- todo ! ( ) ; // amend stack frame layout
170- instructions. push ( IntermediateInstruction :: computation (
171- * operation,
172- IntermediateValue :: from_simple_expr ( arg0, compiler) ,
173- IntermediateValue :: from_simple_expr ( arg1, compiler) ,
174- IntermediateValue :: from_var_or_const_malloc_access ( var, compiler) ,
175- ) ) ;
176-
177172 mark_vars_as_declared ( & [ arg0, arg1] , declared_vars) ;
173+ let arg0 = IntermediateValue :: from_simple_expr ( arg0, compiler) ;
174+ let arg1 = IntermediateValue :: from_simple_expr ( arg1, compiler) ;
175+
178176 if let VarOrConstMallocAccess :: Var ( var) = var {
179177 declared_vars. insert ( var. clone ( ) ) ;
178+ 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 ;
180181 }
182+
183+ instructions. push ( IntermediateInstruction :: computation (
184+ * operation,
185+ arg0,
186+ arg1,
187+ IntermediateValue :: from_var_or_const_malloc_access ( var, compiler) ,
188+ ) ) ;
181189 }
182190
183191 SimpleLine :: TestZero { operation, arg0, arg1 } => {
@@ -192,7 +200,9 @@ fn compile_lines(
192200 }
193201
194202 SimpleLine :: Match { value, arms } => {
195- todo ! ( ) ; // amend stack frame layout
203+ let saved_stack_size = compiler. stack_size ;
204+ compiler. stack_frame_layout . scopes . push ( ScopeLayout :: default ( ) ) ;
205+
196206 let match_index = compiler. match_blocks . len ( ) ;
197207 let end_label = Label :: match_end ( match_index) ;
198208
@@ -254,6 +264,9 @@ fn compile_lines(
254264 let remaining = compile_lines ( function_name, & lines[ i + 1 ..] , compiler, final_jump, declared_vars) ?;
255265 compiler. bytecode . insert ( end_label, remaining) ;
256266
267+ compiler. stack_frame_layout . scopes . pop ( ) ;
268+ compiler. stack_size = saved_stack_size;
269+
257270 return Ok ( instructions) ;
258271 }
259272
@@ -263,7 +276,9 @@ fn compile_lines(
263276 else_branch,
264277 line_number,
265278 } => {
266- todo ! ( ) ; // amend stack frame layout
279+ let saved_stack_size = compiler. stack_size ;
280+ compiler. stack_frame_layout . scopes . push ( ScopeLayout :: default ( ) ) ;
281+
267282 validate_vars_declared ( & [ condition] , declared_vars) ?;
268283
269284 let if_id = compiler. if_counter ;
@@ -368,6 +383,9 @@ fn compile_lines(
368383 let remaining = compile_lines ( function_name, & lines[ i + 1 ..] , compiler, final_jump, declared_vars) ?;
369384 compiler. bytecode . insert ( end_label, remaining) ;
370385
386+ compiler. stack_frame_layout . scopes . pop ( ) ;
387+ compiler. stack_size = saved_stack_size;
388+
371389 return Ok ( instructions) ;
372390 }
373391
@@ -393,7 +411,6 @@ fn compile_lines(
393411 return_data,
394412 line_number,
395413 } => {
396- todo ! ( ) ; // amend stack frame layout
397414 let call_id = compiler. call_counter ;
398415 compiler. call_counter += 1 ;
399416 let return_label = Label :: return_from_call ( call_id, * line_number) ;
@@ -411,6 +428,11 @@ fn compile_lines(
411428
412429 validate_vars_declared ( args, declared_vars) ?;
413430 declared_vars. extend ( return_data. iter ( ) . cloned ( ) ) ;
431+ for var in return_data. iter ( ) {
432+ 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+ }
414436
415437 let after_call = {
416438 let mut instructions = Vec :: new ( ) ;
@@ -443,7 +465,6 @@ fn compile_lines(
443465 }
444466
445467 SimpleLine :: Precompile { table, args, .. } => {
446- todo ! ( ) ; // amend stack frame layout?
447468 if * table == Table :: poseidon24 ( ) {
448469 assert_eq ! ( args. len( ) , 3 ) ;
449470 } else {
@@ -486,7 +507,9 @@ fn compile_lines(
486507 vectorized,
487508 vectorized_len,
488509 } => {
489- todo ! ( ) ; // amend stack frame layout
510+ 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 ;
490513 declared_vars. insert ( var. clone ( ) ) ;
491514 instructions. push ( IntermediateInstruction :: RequestMemory {
492515 offset : compiler. get_offset ( & var. clone ( ) . into ( ) ) ,
@@ -496,7 +519,6 @@ fn compile_lines(
496519 } ) ;
497520 }
498521 SimpleLine :: ConstMalloc { var, size, label } => {
499- todo ! ( ) ; // amend stack frame layout
500522 let size = size. naive_eval ( ) . unwrap ( ) . to_usize ( ) ; // TODO not very good;
501523 handle_const_malloc ( declared_vars, & mut instructions, compiler, var, size, label) ;
502524 }
@@ -505,7 +527,6 @@ fn compile_lines(
505527 to_decompose,
506528 label,
507529 } => {
508- todo ! ( ) ; // amend stack frame layout
509530 instructions. push ( IntermediateInstruction :: DecomposeBits {
510531 res_offset : compiler. stack_size ,
511532 to_decompose : to_decompose
@@ -528,7 +549,6 @@ fn compile_lines(
528549 to_decompose,
529550 label,
530551 } => {
531- todo ! ( ) ; // amend stack frame layout
532552 instructions. push ( IntermediateInstruction :: DecomposeCustom {
533553 res_offset : compiler. stack_size ,
534554 to_decompose : to_decompose
@@ -547,7 +567,9 @@ fn compile_lines(
547567 ) ;
548568 }
549569 SimpleLine :: CounterHint { var } => {
550- todo ! ( ) ; // amend stack frame layout
570+ 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 ;
551573 declared_vars. insert ( var. clone ( ) ) ;
552574 instructions. push ( IntermediateInstruction :: CounterHint {
553575 res_offset : compiler
@@ -590,7 +612,6 @@ fn handle_const_malloc(
590612 size : usize ,
591613 label : & ConstMallocLabel ,
592614) {
593- todo ! ( ) ; // amend stack frame layout
594615 declared_vars. insert ( var. clone ( ) ) ;
595616 instructions. push ( IntermediateInstruction :: Computation {
596617 operation : Operation :: Add ,
@@ -600,7 +621,8 @@ fn handle_const_malloc(
600621 offset : compiler. get_offset ( & var. clone ( ) . into ( ) ) ,
601622 } ,
602623 } ) ;
603- compiler. const_mallocs . insert ( * label, compiler. stack_size ) ;
624+ let current_scope = compiler. stack_frame_layout . scopes . last_mut ( ) . unwrap ( ) ;
625+ current_scope. const_mallocs . insert ( * label, compiler. stack_size ) ;
604626 compiler. stack_size += size;
605627}
606628
@@ -688,11 +710,13 @@ fn compile_function_ret(
688710 } ) ;
689711}
690712
691- // TODO: delete this?
692713fn find_internal_vars ( lines : & [ SimpleLine ] ) -> BTreeSet < Var > {
693714 let mut internal_vars = BTreeSet :: new ( ) ;
694715 for line in lines {
695716 match line {
717+ SimpleLine :: ForwardDeclaration { var } => {
718+ internal_vars. insert ( var. clone ( ) ) ;
719+ }
696720 SimpleLine :: Match { arms, .. } => {
697721 for arm in arms {
698722 internal_vars. extend ( find_internal_vars ( arm) ) ;
0 commit comments