@@ -134,6 +134,30 @@ impl<'a> VM<'a> {
134134 self . push ( v) ; Ok ( ( ) )
135135 }
136136
137+ /* Allocate a List from items and push. Centralises the
138+ Rc::new(RefCell::new(items)) construction inlined ~15 times. */
139+ pub ( crate ) fn alloc_list ( & mut self , items : Vec < Val > ) -> Result < Val , VmErr > {
140+ self . heap . alloc ( HeapObj :: List ( Rc :: new ( RefCell :: new ( items) ) ) )
141+ }
142+
143+ /* Allocate a List, push it, return Ok. */
144+ pub ( crate ) fn alloc_and_push_list ( & mut self , items : Vec < Val > ) -> Result < ( ) , VmErr > {
145+ let v = self . alloc_list ( items) ?;
146+ self . push ( v) ; Ok ( ( ) )
147+ }
148+
149+ /* Allocate a Dict from a DictMap and push. */
150+ pub ( crate ) fn alloc_and_push_dict ( & mut self , dm : DictMap ) -> Result < ( ) , VmErr > {
151+ let v = self . heap . alloc ( HeapObj :: Dict ( Rc :: new ( RefCell :: new ( dm) ) ) ) ?;
152+ self . push ( v) ; Ok ( ( ) )
153+ }
154+
155+ /* Allocate a Tuple and push. */
156+ pub ( crate ) fn alloc_and_push_tuple ( & mut self , items : Vec < Val > ) -> Result < ( ) , VmErr > {
157+ let v = self . heap . alloc ( HeapObj :: Tuple ( items) ) ?;
158+ self . push ( v) ; Ok ( ( ) )
159+ }
160+
137161 pub fn call_int ( & mut self ) -> Result < ( ) , VmErr > {
138162 let o = self . pop ( ) ?;
139163 if o. is_heap ( )
@@ -262,8 +286,7 @@ impl<'a> VM<'a> {
262286 let o = self . pop ( ) ?;
263287 let mut items = self . extract_iter ( o, false ) ?;
264288 self . sort_by_lt ( & mut items) ?;
265- let val = self . heap . alloc ( HeapObj :: List ( Rc :: new ( RefCell :: new ( items) ) ) ) ?;
266- self . push ( val) ; Ok ( ( ) )
289+ self . alloc_and_push_list ( items)
267290 }
268291
269292 /* In-place sort using lt_vals for ordering. Captures the first error
@@ -294,13 +317,10 @@ impl<'a> VM<'a> {
294317 && let HeapObj :: Str ( s) = self . heap . get ( o) {
295318 let s = s. clone ( ) ;
296319 let items = self . str_to_char_vals ( & s) ?;
297- let val = self . heap . alloc ( HeapObj :: List ( Rc :: new ( RefCell :: new ( items) ) ) ) ?;
298- self . push ( val) ;
299- return Ok ( ( ) ) ;
320+ return self . alloc_and_push_list ( items) ;
300321 }
301322 let items = self . extract_iter ( o, true ) ?;
302- let val = self . heap . alloc ( HeapObj :: List ( Rc :: new ( RefCell :: new ( items) ) ) ) ?;
303- self . push ( val) ; Ok ( ( ) )
323+ self . alloc_and_push_list ( items)
304324 }
305325
306326 pub fn call_tuple ( & mut self ) -> Result < ( ) , VmErr > {
@@ -310,8 +330,7 @@ impl<'a> VM<'a> {
310330 HeapObj :: List ( v) => v. borrow ( ) . clone ( ) ,
311331 _ => return Err ( cold_type ( "tuple() argument must be iterable" ) ) ,
312332 } } else { return Err ( cold_type ( "tuple() argument must be iterable" ) ) ; } ;
313- let val = self . heap . alloc ( HeapObj :: Tuple ( items) ) ?;
314- self . push ( val) ; Ok ( ( ) )
333+ self . alloc_and_push_tuple ( items)
315334 }
316335
317336 pub fn call_enumerate ( & mut self ) -> Result < ( ) , VmErr > {
@@ -322,8 +341,7 @@ impl<'a> VM<'a> {
322341 let t = self . heap . alloc ( HeapObj :: Tuple ( vec ! [ Val :: int( i as i64 ) , x] ) ) ?;
323342 pairs. push ( t) ;
324343 }
325- let val = self . heap . alloc ( HeapObj :: List ( Rc :: new ( RefCell :: new ( pairs) ) ) ) ?;
326- self . push ( val) ; Ok ( ( ) )
344+ self . alloc_and_push_list ( pairs)
327345 }
328346
329347 /* Pairs elements from N iterables into tuples, truncating to the shortest. */
@@ -340,8 +358,7 @@ impl<'a> VM<'a> {
340358 let t = self . heap . alloc ( HeapObj :: Tuple ( tuple) ) ?;
341359 pairs. push ( t) ;
342360 }
343- let val = self . heap . alloc ( HeapObj :: List ( Rc :: new ( RefCell :: new ( pairs) ) ) ) ?;
344- self . push ( val) ; Ok ( ( ) )
361+ self . alloc_and_push_list ( pairs)
345362 }
346363
347364 /* Type-name based isinstance check. Accepts Type or NativeFn (for the
@@ -486,26 +503,22 @@ impl<'a> VM<'a> {
486503 }
487504 let mid = items. len ( ) - after;
488505 for & v in items[ mid..] . iter ( ) . rev ( ) { self . push ( v) ; }
489- let star = self . heap . alloc ( HeapObj :: List ( Rc :: new ( RefCell :: new (
490- items[ before..mid] . to_vec ( )
491- ) ) ) ) ?;
506+ let star = self . alloc_list ( items[ before..mid] . to_vec ( ) ) ?;
492507 self . push ( star) ;
493508 for & v in items[ ..before] . iter ( ) . rev ( ) { self . push ( v) ; }
494509 Ok ( ( ) )
495510 }
496511
497512 pub fn call_dict ( & mut self , op : u16 ) -> Result < ( ) , VmErr > {
498- if op == 0 {
499- let val = self . heap . alloc ( HeapObj :: Dict ( Rc :: new ( RefCell :: new ( DictMap :: new ( ) ) ) ) ) ?;
500- self . push ( val) ;
513+ let dm = if op == 0 {
514+ DictMap :: new ( )
501515 } else {
502516 let args = self . pop_n ( ( op as usize ) * 2 ) ?;
503517 let mut dm = DictMap :: with_capacity ( op as usize ) ;
504518 for pair in args. chunks ( 2 ) { dm. insert ( pair[ 0 ] , pair[ 1 ] ) ; }
505- let val = self . heap . alloc ( HeapObj :: Dict ( Rc :: new ( RefCell :: new ( dm) ) ) ) ?;
506- self . push ( val) ;
507- }
508- Ok ( ( ) )
519+ dm
520+ } ;
521+ self . alloc_and_push_dict ( dm)
509522 }
510523
511524 pub fn call_set ( & mut self , op : u16 ) -> Result < ( ) , VmErr > {
@@ -716,8 +729,7 @@ impl<'a> VM<'a> {
716729 let ( q, r) = ba. divmod ( & bb) . ok_or ( VmErr :: ZeroDiv ) ?;
717730 let qv = self . bigint_to_val ( q) ?;
718731 let rv = self . bigint_to_val ( r) ?;
719- let val = self . heap . alloc ( HeapObj :: Tuple ( vec ! [ qv, rv] ) ) ?;
720- self . push ( val) ; Ok ( ( ) )
732+ self . alloc_and_push_tuple ( vec ! [ qv, rv] )
721733 }
722734
723735 pub fn call_pow ( & mut self , op : u16 ) -> Result < ( ) , VmErr > {
@@ -846,8 +858,7 @@ impl<'a> VM<'a> {
846858 self . extract_iter ( o, true ) ?
847859 } ;
848860 items. reverse ( ) ;
849- let v = self . heap . alloc ( HeapObj :: List ( Rc :: new ( RefCell :: new ( items) ) ) ) ?;
850- self . push ( v) ; Ok ( ( ) )
861+ self . alloc_and_push_list ( items)
851862 }
852863
853864 // format(value [, spec]).
0 commit comments