@@ -19,8 +19,6 @@ pub struct JitMemory {
1919 page : Page ,
2020 /// Information of momory pages.
2121 pages : [ MemPage ; 3 ] ,
22- /// Relocation information.
23- labels : Labels ,
2422}
2523
2624#[ derive( Debug , Clone , Copy , PartialEq ) ]
@@ -170,7 +168,7 @@ enum Rex {
170168 Byte ,
171169}
172170
173- #[ derive( Debug , Clone , Copy ) ]
171+ #[ derive( Debug , Clone ) ]
174172enum DataType {
175173 U64 ( u64 ) ,
176174 U32 ( u32 ) ,
@@ -258,7 +256,6 @@ impl JitMemory {
258256 JitMemory {
259257 page : Page ( 0 ) ,
260258 pages : [ initial_page, second_page, data_page] ,
261- labels : Labels :: new ( ) ,
262259 }
263260 }
264261
@@ -311,133 +308,130 @@ impl JitMemory {
311308
312309 /// Create a new label and returns `DestLabel`.
313310 pub fn label ( & mut self ) -> DestLabel {
314- self . labels . new_label ( )
311+ DestLabel :: new ( )
315312 }
316313
317314 pub fn const_f64 ( & mut self , val : f64 ) -> DestLabel {
318315 let label = self . label ( ) ;
319316 let val = u64:: from_ne_bytes ( val. to_ne_bytes ( ) ) ;
320- self . constants . push ( ( DataType :: U64 ( val) , label) ) ;
317+ self . constants . push ( ( DataType :: U64 ( val) , label. clone ( ) ) ) ;
321318 label
322319 }
323320
324321 pub fn const_i64 ( & mut self , val : i64 ) -> DestLabel {
325322 let label = self . label ( ) ;
326323 let val = val as u64 ;
327- self . constants . push ( ( DataType :: U64 ( val) , label) ) ;
324+ self . constants . push ( ( DataType :: U64 ( val) , label. clone ( ) ) ) ;
328325 label
329326 }
330327
331328 pub fn data_i64 ( & mut self , val : i64 ) -> DestLabel {
332329 let label = self . label ( ) ;
333330 let val = val as u64 ;
334- self . data . push ( ( DataType :: U64 ( val) , label) ) ;
331+ self . data . push ( ( DataType :: U64 ( val) , label. clone ( ) ) ) ;
335332 label
336333 }
337334
338335 pub fn const_i32 ( & mut self , val : i32 ) -> DestLabel {
339336 let label = self . label ( ) ;
340337 let val = val as u32 ;
341- self . constants . push ( ( DataType :: U32 ( val) , label) ) ;
338+ self . constants . push ( ( DataType :: U32 ( val) , label. clone ( ) ) ) ;
342339 label
343340 }
344341
345342 pub fn data_i32 ( & mut self , val : i32 ) -> DestLabel {
346343 let label = self . label ( ) ;
347344 let val = val as u32 ;
348- self . data . push ( ( DataType :: U32 ( val) , label) ) ;
345+ self . data . push ( ( DataType :: U32 ( val) , label. clone ( ) ) ) ;
349346 label
350347 }
351348
352349 pub fn constant ( & mut self , size : usize ) -> DestLabel {
353350 let label = self . label ( ) ;
354- self . constants . push ( ( DataType :: Bytes ( size) , label) ) ;
351+ self . constants . push ( ( DataType :: Bytes ( size) , label. clone ( ) ) ) ;
355352 label
356353 }
357354
358355 pub fn data ( & mut self , size : usize ) -> DestLabel {
359356 let label = self . label ( ) ;
360- self . data . push ( ( DataType :: Bytes ( size) , label) ) ;
357+ self . data . push ( ( DataType :: Bytes ( size) , label. clone ( ) ) ) ;
361358 label
362359 }
363360
364361 pub fn abs_address ( & mut self , addr_label : DestLabel ) -> DestLabel {
365362 let label = self . label ( ) ;
366363 self . constants
367- . push ( ( DataType :: AbsAddress ( addr_label) , label) ) ;
364+ . push ( ( DataType :: AbsAddress ( addr_label) , label. clone ( ) ) ) ;
368365 label
369366 }
370367
371368 pub fn const_align8 ( & mut self ) -> DestLabel {
372369 let label = self . label ( ) ;
373- self . constants . push ( ( DataType :: Align8 , label) ) ;
370+ self . constants . push ( ( DataType :: Align8 , label. clone ( ) ) ) ;
374371 label
375372 }
376373
377374 /// Bind the current location to `label`.
378- pub fn bind_label ( & mut self , label : DestLabel ) {
375+ pub fn bind_label ( & mut self , label : & DestLabel ) {
379376 let src_page = self . page ;
380- self . bind_label_with_page ( src_page, label) ;
377+ self . bind_label_with_page ( src_page, label. clone ( ) ) ;
381378 }
382379
383380 pub fn bind_label_with_page ( & mut self , src_page : Page , label : DestLabel ) {
384381 let src_pos = self [ src_page] . counter ;
385- match & mut self . labels [ label] {
382+ match label. 0 . take ( ) {
386383 LabelInfo :: Resolved ( _) => { } //panic!("The DestLabel has already been resolved."),
387384 LabelInfo :: NotResolved ( targets) => {
388- for target in std :: mem :: take ( targets) {
385+ for target in targets {
389386 self . write_reloc ( src_page, src_pos, target) ;
390387 }
391388 }
392389 }
393- self . labels [ label] = LabelInfo :: Resolved ( ( src_page, src_pos) ) ;
390+ * label. 0 . borrow_mut ( ) = LabelInfo :: Resolved ( ( src_page, src_pos) ) ;
394391 }
395392
396393 /// Bind the current location to `label`.
397- fn get_label_pos ( & self , label : DestLabel ) -> ( Page , Pos ) {
398- self . labels [ label] . loc ( )
394+ fn get_label_pos ( & self , label : & DestLabel ) -> ( Page , Pos ) {
395+ label. loc ( )
399396 }
400397
401398 pub fn get_current_address ( & self ) -> CodePtr {
402399 let ptr = unsafe { self . contents ( ) . add ( self . counter . 0 ) } ;
403400 CodePtr :: from ( ptr)
404401 }
405402
406- pub fn get_label_address ( & self , label : DestLabel ) -> CodePtr {
403+ pub fn get_label_address ( & self , label : & DestLabel ) -> CodePtr {
407404 let ( page, pos) = self . get_label_pos ( label) ;
408405 let ptr = unsafe { self [ page] . contents ( ) . add ( pos. 0 ) } ;
409406 CodePtr :: from ( ptr)
410407 }
411408
409+ fn handle_target ( & mut self , dest : DestLabel , target : TargetType ) {
410+ match & mut * dest. 0 . borrow_mut ( ) {
411+ LabelInfo :: Resolved ( ( src_page, src_pos) ) => {
412+ self . write_reloc ( * src_page, * src_pos, target) ;
413+ }
414+ LabelInfo :: NotResolved ( targets) => {
415+ targets. push ( target) ;
416+ }
417+ }
418+ }
419+
412420 /// Save relocaton slot for `DestLabel`.
413421 pub fn emit_reloc ( & mut self , dest : DestLabel , offset : u8 ) {
414422 let page = self . page ;
415423 let pos = self . counter ;
416424 let target = TargetType :: Rel { page, offset, pos } ;
417425 self . emitl ( 0 ) ;
418- match self . labels [ dest] {
419- LabelInfo :: Resolved ( ( src_page, src_pos) ) => {
420- self . write_reloc ( src_page, src_pos, target) ;
421- }
422- LabelInfo :: NotResolved ( ref mut targets) => {
423- targets. push ( target) ;
424- }
425- }
426+ self . handle_target ( dest, target) ;
426427 }
427428
428429 /// Save relocaton slot for `DestLabel`.
429430 fn emit_absolute_reloc ( & mut self , page : Page , dest : DestLabel ) {
430431 let pos = self [ page] . counter ;
431432 let target = TargetType :: Abs { page, pos } ;
432433 self [ page] . emitq ( 0 ) ;
433- match self . labels [ dest] {
434- LabelInfo :: Resolved ( ( src_page, src_pos) ) => {
435- self . write_reloc ( src_page, src_pos, target) ;
436- }
437- LabelInfo :: NotResolved ( ref mut targets) => {
438- targets. push ( target) ;
439- }
440- }
434+ self . handle_target ( dest, target) ;
441435 }
442436
443437 fn write_reloc ( & mut self , src_page : Page , src_pos : Pos , target : TargetType ) {
@@ -547,20 +541,20 @@ impl JitMemory {
547541 }
548542 }
549543
550- pub fn get_label_addr < T , U > ( & mut self , label : DestLabel ) -> extern "C" fn ( T ) -> U {
551- let ( page, counter) = self . labels [ label] . loc ( ) ;
544+ pub fn get_label_addr < T , U > ( & mut self , label : & DestLabel ) -> extern "C" fn ( T ) -> U {
545+ let ( page, counter) = label. loc ( ) ;
552546 let adr = self [ page] . contents ( ) ;
553547 unsafe { mem:: transmute ( adr. add ( counter. 0 ) ) }
554548 }
555549
556- pub fn get_label_addr2 < S , T , U > ( & mut self , label : DestLabel ) -> extern "C" fn ( S , T ) -> U {
557- let ( page, counter) = self . labels [ label] . loc ( ) ;
550+ pub fn get_label_addr2 < S , T , U > ( & mut self , label : & DestLabel ) -> extern "C" fn ( S , T ) -> U {
551+ let ( page, counter) = label. loc ( ) ;
558552 let adr = self [ page] . contents ( ) ;
559553 unsafe { mem:: transmute ( adr. add ( counter. 0 ) ) }
560554 }
561555
562- pub fn get_label_u64 ( & mut self , label : DestLabel ) -> u64 {
563- let ( page, counter) = self . labels [ label] . loc ( ) ;
556+ pub fn get_label_u64 ( & mut self , label : & DestLabel ) -> u64 {
557+ let ( page, counter) = label. loc ( ) ;
564558 let adr = self [ page] . contents ( ) ;
565559 unsafe { adr. add ( counter. 0 ) as u64 }
566560 }
@@ -573,7 +567,7 @@ impl JitMemory {
573567 ///
574568 /// Apply patch for the displacement of the jmp instruction in *patch_point*.
575569 ///
576- pub fn apply_jmp_patch_address ( & mut self , patch_point : CodePtr , jmp_dest : DestLabel ) {
570+ pub fn apply_jmp_patch_address ( & mut self , patch_point : CodePtr , jmp_dest : & DestLabel ) {
577571 let jmp_dest = self . get_label_address ( jmp_dest) ;
578572 let offset = jmp_dest - patch_point - 5 ;
579573 unsafe { * ( patch_point. as_ptr ( ) . add ( 1 ) as * mut [ u8 ; 4 ] ) = ( offset as i32 ) . to_ne_bytes ( ) } ;
@@ -705,24 +699,24 @@ impl JitMemory {
705699 // For rip, only indirect addressing with disp32 ([rip + disp32]) is allowed.
706700 // [rip] and [rip + disp8] are to be converted to [rip + disp32].
707701 let rm = Rm :: rip_ind_from ( rm) ;
708- rex_fn ( self , reg, rm. base , Reg ( 0 ) , rm. mode ) ;
702+ rex_fn ( self , reg, rm. base , Reg ( 0 ) , rm. mode . clone ( ) ) ;
709703 self . emit ( op) ;
710704 self . modrm ( modrm_mode, Mode :: Ind ( Scale :: None , Disp :: None ) , rm. base ) ;
711705 self . emit_disp_imm ( rm. mode . disp ( ) , imm) ;
712706 } else if rm. mode != Mode :: Reg && ( rm. base . 0 & 0b111 ) == 4 {
713707 // If mode != Reg and r/m == 4/12 (rsp/r12), use SIB.
714- match rm. mode {
708+ match & rm. mode {
715709 Mode :: Ind ( scale, disp) => {
716710 let ( scale, index) = match scale {
717711 Scale :: None => ( 0 , Reg ( 4 ) ) , // magic number
718- Scale :: S1 ( scale, index) => ( scale, index) ,
712+ Scale :: S1 ( scale, index) => ( * scale, * index) ,
719713 } ;
720714 let base = rm. base ;
721- rex_fn ( self , reg, base, index, rm. mode ) ;
715+ rex_fn ( self , reg, base, index, rm. mode . clone ( ) ) ;
722716 self . emit ( op) ;
723- self . modrm ( modrm_mode, rm. mode , base) ;
717+ self . modrm ( modrm_mode, rm. mode . clone ( ) , base) ;
724718 self . sib ( scale, index, base) ;
725- self . emit_disp_imm ( disp, imm) ;
719+ self . emit_disp_imm ( disp. clone ( ) , imm) ;
726720 }
727721 _ => unreachable ! ( ) ,
728722 }
@@ -732,7 +726,7 @@ impl JitMemory {
732726 rex_fn ( self , reg, rm. base , scale. index ( ) , rm. mode ) ;
733727 let mode = Mode :: Ind ( scale, Disp :: D8 ( 0 ) ) ;
734728 self . emit ( op) ;
735- self . modrm ( modrm_mode, mode, rm. base ) ;
729+ self . modrm ( modrm_mode, mode. clone ( ) , rm. base ) ;
736730 match scale {
737731 Scale :: None => { }
738732 Scale :: S1 ( scale, index) => self . sib ( scale, index, rm. base ) ,
@@ -750,11 +744,11 @@ impl JitMemory {
750744 Scale :: S1 ( _, index) => index,
751745 } ,
752746 } ,
753- rm. mode ,
747+ rm. mode . clone ( ) ,
754748 ) ;
755749 // index != Reg::RIP
756750 self . emit ( op) ;
757- self . modrm ( modrm_mode, rm. mode , rm. base ) ;
751+ self . modrm ( modrm_mode, rm. mode . clone ( ) , rm. base ) ;
758752 match rm. mode {
759753 Mode :: Reg => { }
760754 Mode :: Ind ( scale, _) => match scale {
0 commit comments