@@ -18,6 +18,9 @@ type CompileResult<T> = Result<T, CompileError>;
1818
1919struct CodeInfo {
2020 code : CodeObject ,
21+ instructions : Vec < Instruction > ,
22+ locations : Vec < bytecode:: Location > ,
23+ constants : Vec < bytecode:: ConstantData > ,
2124 name_cache : IndexSet < String > ,
2225 varname_cache : IndexSet < String > ,
2326 cellvar_cache : IndexSet < String > ,
@@ -28,17 +31,23 @@ impl CodeInfo {
2831 fn finalize_code ( self ) -> CodeObject {
2932 let CodeInfo {
3033 mut code,
34+ instructions,
35+ locations,
36+ constants,
3137 name_cache,
3238 varname_cache,
3339 cellvar_cache,
3440 freevar_cache,
3541 label_map,
3642 } = self ;
3743
38- code. names . extend ( name_cache) ;
39- code. varnames . extend ( varname_cache) ;
40- code. cellvars . extend ( cellvar_cache) ;
41- code. freevars . extend ( freevar_cache) ;
44+ code. instructions = instructions. into ( ) ;
45+ code. locations = locations. into ( ) ;
46+ code. constants = constants. into ( ) ;
47+ code. names = name_cache. into_iter ( ) . collect ( ) ;
48+ code. varnames = varname_cache. into_iter ( ) . collect ( ) ;
49+ code. cellvars = cellvar_cache. into_iter ( ) . collect ( ) ;
50+ code. freevars = freevar_cache. into_iter ( ) . collect ( ) ;
4251
4352 if !code. cellvars . is_empty ( ) {
4453 let total_args = code. arg_count
@@ -65,7 +74,7 @@ impl CodeInfo {
6574 }
6675 }
6776
68- for instruction in & mut code. instructions {
77+ for instruction in & mut * code. instructions {
6978 use Instruction :: * ;
7079 // this is a little bit hacky, as until now the data stored inside Labels in
7180 // Instructions is just bookkeeping, but I think it's the best way to do this
@@ -221,14 +230,17 @@ impl Compiler {
221230 fn new ( opts : CompileOpts , source_path : String , code_name : String ) -> Self {
222231 let module_code = CodeInfo {
223232 code : CodeObject :: new (
224- Default :: default ( ) ,
233+ bytecode :: CodeFlags :: NEW_LOCALS ,
225234 0 ,
226235 0 ,
227236 0 ,
228237 source_path. clone ( ) ,
229238 0 ,
230239 code_name,
231240 ) ,
241+ instructions : Vec :: new ( ) ,
242+ locations : Vec :: new ( ) ,
243+ constants : Vec :: new ( ) ,
232244 name_cache : IndexSet :: new ( ) ,
233245 varname_cache : IndexSet :: new ( ) ,
234246 cellvar_cache : IndexSet :: new ( ) ,
@@ -287,6 +299,9 @@ impl Compiler {
287299
288300 let info = CodeInfo {
289301 code,
302+ instructions : Vec :: new ( ) ,
303+ locations : Vec :: new ( ) ,
304+ constants : Vec :: new ( ) ,
290305 name_cache : IndexSet :: new ( ) ,
291306 varname_cache : IndexSet :: new ( ) ,
292307 cellvar_cache,
@@ -315,7 +330,7 @@ impl Compiler {
315330 name : & str ,
316331 cache : impl FnOnce ( & mut CodeInfo ) -> & mut IndexSet < String > ,
317332 ) -> bytecode:: NameIdx {
318- let cache = cache ( self . code_stack . last_mut ( ) . expect ( "nothing on stack" ) ) ;
333+ let cache = cache ( self . current_codeinfo ( ) ) ;
319334 cache
320335 . get_index_of ( name)
321336 . unwrap_or_else ( || cache. insert_full ( name. to_owned ( ) ) . 0 )
@@ -1160,7 +1175,7 @@ impl Compiler {
11601175
11611176 fn build_closure ( & mut self , code : & CodeObject ) {
11621177 if !code. freevars . is_empty ( ) {
1163- for var in & code. freevars {
1178+ for var in & * code. freevars {
11641179 let table = self . symbol_table_stack . last ( ) . unwrap ( ) ;
11651180 let symbol = table. lookup ( var) . unwrap ( ) ;
11661181 let parent_code = self . code_stack . last ( ) . unwrap ( ) ;
@@ -2423,29 +2438,29 @@ impl Compiler {
24232438 fn emit ( & mut self , instruction : Instruction ) {
24242439 let location = compile_location ( & self . current_source_location ) ;
24252440 // TODO: insert source filename
2426- let code = self . current_code ( ) ;
2427- code . instructions . push ( instruction) ;
2428- code . locations . push ( location) ;
2441+ let info = self . current_codeinfo ( ) ;
2442+ info . instructions . push ( instruction) ;
2443+ info . locations . push ( location) ;
24292444 }
24302445
24312446 fn emit_constant ( & mut self , constant : bytecode:: ConstantData ) {
2432- let code = self . current_code ( ) ;
2433- let idx = code . constants . len ( ) ;
2434- code . constants . push ( constant) ;
2447+ let info = self . current_codeinfo ( ) ;
2448+ let idx = info . constants . len ( ) ;
2449+ info . constants . push ( constant) ;
24352450 self . emit ( Instruction :: LoadConst { idx } )
24362451 }
24372452
24382453 fn current_code ( & mut self ) -> & mut CodeObject {
2439- & mut self
2440- . code_stack
2441- . last_mut ( )
2442- . expect ( "No OutputStream on stack" )
2443- . code
2454+ & mut self . current_codeinfo ( ) . code
2455+ }
2456+
2457+ fn current_codeinfo ( & mut self ) -> & mut CodeInfo {
2458+ self . code_stack . last_mut ( ) . expect ( "no code on stack" )
24442459 }
24452460
24462461 // Generate a new label
24472462 fn new_label ( & mut self ) -> Label {
2448- let label_map = & mut self . code_stack . last_mut ( ) . unwrap ( ) . label_map ;
2463+ let label_map = & mut self . current_codeinfo ( ) . label_map ;
24492464 let label = Label ( label_map. len ( ) ) ;
24502465 label_map. push ( None ) ;
24512466 label
@@ -2454,9 +2469,11 @@ impl Compiler {
24542469 // Assign current position the given label
24552470 fn set_label ( & mut self , label : Label ) {
24562471 let CodeInfo {
2457- code, label_map, ..
2458- } = self . code_stack . last_mut ( ) . unwrap ( ) ;
2459- let actual_label = Label ( code. instructions . len ( ) ) ;
2472+ instructions,
2473+ label_map,
2474+ ..
2475+ } = self . current_codeinfo ( ) ;
2476+ let actual_label = Label ( instructions. len ( ) ) ;
24602477 let prev_val = std:: mem:: replace ( & mut label_map[ label. 0 ] , Some ( actual_label) ) ;
24612478 debug_assert ! (
24622479 prev_val. map_or( true , |x| x == actual_label) ,
0 commit comments