1
1
//! Implement python as a virtual machine with bytecodes. This module
2
2
//! implements bytecode structure.
3
3
4
- use crate :: marshal:: MarshalError ;
5
4
use crate :: { marshal, Location } ;
6
5
use bitflags:: bitflags;
7
6
use itertools:: Itertools ;
@@ -46,6 +45,19 @@ pub trait ConstantBag: Sized + Copy {
46
45
fn make_name ( & self , name : & str ) -> <Self :: Constant as Constant >:: Name ;
47
46
}
48
47
48
+ pub trait AsBag {
49
+ type Bag : ConstantBag ;
50
+ #[ allow( clippy:: wrong_self_convention) ]
51
+ fn as_bag ( self ) -> Self :: Bag ;
52
+ }
53
+
54
+ impl < Bag : ConstantBag > AsBag for Bag {
55
+ type Bag = Self ;
56
+ fn as_bag ( self ) -> Self {
57
+ self
58
+ }
59
+ }
60
+
49
61
#[ derive( Clone , Copy ) ]
50
62
pub struct BasicBag ;
51
63
@@ -1077,27 +1089,6 @@ impl<C: Constant> CodeObject<C> {
1077
1089
}
1078
1090
}
1079
1091
1080
- impl CodeObject < ConstantData > {
1081
- /// Load a code object from bytes
1082
- pub fn from_bytes ( data : & [ u8 ] ) -> Result < Self , MarshalError > {
1083
- use lz4_flex:: block:: DecompressError ;
1084
- let raw_bincode = lz4_flex:: decompress_size_prepended ( data) . map_err ( |e| match e {
1085
- DecompressError :: OutputTooSmall { .. } | DecompressError :: ExpectedAnotherByte => {
1086
- MarshalError :: Eof
1087
- }
1088
- _ => MarshalError :: InvalidBytecode ,
1089
- } ) ?;
1090
- marshal:: deserialize_code ( & mut & raw_bincode[ ..] , BasicBag )
1091
- }
1092
-
1093
- /// Serialize this bytecode to bytes.
1094
- pub fn to_bytes ( & self ) -> Vec < u8 > {
1095
- let mut data = Vec :: new ( ) ;
1096
- marshal:: serialize_code ( & mut data, self ) ;
1097
- lz4_flex:: compress_prepend_size ( & data)
1098
- }
1099
- }
1100
-
1101
1092
impl < C : Constant > fmt:: Display for CodeObject < C > {
1102
1093
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1103
1094
self . display_inner ( f, false , 1 ) ?;
@@ -1483,32 +1474,81 @@ impl<C: Constant> fmt::Debug for CodeObject<C> {
1483
1474
}
1484
1475
}
1485
1476
1486
- /// A frozen module. Holds a code object and whether it is part of a package
1487
- #[ derive( Debug ) ]
1488
- pub struct FrozenModule {
1489
- pub code : CodeObject < ConstantData > ,
1490
- pub package : bool ,
1491
- }
1492
-
1493
1477
pub mod frozen_lib {
1494
1478
use super :: * ;
1495
- use marshal:: { Read , Write } ;
1479
+ use marshal:: { Read , ReadBorrowed , Write } ;
1496
1480
1497
- /// Decode a library to a iterable of frozen modules
1498
- pub fn decode_lib ( bytes : & [ u8 ] ) -> FrozenModulesIter {
1499
- let data = lz4_flex:: decompress_size_prepended ( bytes) . unwrap ( ) ;
1500
- let mut data = marshal:: Cursor { data, position : 0 } ;
1501
- let remaining = data. read_u32 ( ) . unwrap ( ) ;
1502
- FrozenModulesIter { remaining, data }
1481
+ /// A frozen module. Holds a frozen code object and whether it is part of a package
1482
+ #[ derive( Copy , Clone ) ]
1483
+ pub struct FrozenModule < B = & ' static [ u8 ] > {
1484
+ pub code : FrozenCodeObject < B > ,
1485
+ pub package : bool ,
1503
1486
}
1504
1487
1505
- pub struct FrozenModulesIter {
1488
+ #[ derive( Copy , Clone ) ]
1489
+ pub struct FrozenCodeObject < B > {
1490
+ pub bytes : B ,
1491
+ }
1492
+
1493
+ impl < B : AsRef < [ u8 ] > > FrozenCodeObject < B > {
1494
+ /// Decode a frozen codeobject
1495
+ #[ inline]
1496
+ pub fn decode < Bag : AsBag > (
1497
+ & self ,
1498
+ bag : Bag ,
1499
+ ) -> CodeObject < <Bag :: Bag as ConstantBag >:: Constant > {
1500
+ Self :: _decode ( self . bytes . as_ref ( ) , bag. as_bag ( ) )
1501
+ }
1502
+ fn _decode < Bag : ConstantBag > ( data : & [ u8 ] , bag : Bag ) -> CodeObject < Bag :: Constant > {
1503
+ let decompressed = lz4_flex:: decompress_size_prepended ( data)
1504
+ . expect ( "deserialize frozen CodeObject failed" ) ;
1505
+ marshal:: deserialize_code ( & mut & decompressed[ ..] , bag)
1506
+ . expect ( "deserializing frozen CodeObject failed" )
1507
+ }
1508
+ }
1509
+
1510
+ impl FrozenCodeObject < Vec < u8 > > {
1511
+ pub fn encode < C : Constant > ( code : & CodeObject < C > ) -> Self {
1512
+ let mut data = Vec :: new ( ) ;
1513
+ marshal:: serialize_code ( & mut data, code) ;
1514
+ let bytes = lz4_flex:: compress_prepend_size ( & data) ;
1515
+ FrozenCodeObject { bytes }
1516
+ }
1517
+ }
1518
+
1519
+ #[ repr( transparent) ]
1520
+ pub struct FrozenLib < B : ?Sized = [ u8 ] > {
1521
+ pub bytes : B ,
1522
+ }
1523
+
1524
+ impl < B : AsRef < [ u8 ] > + ?Sized > FrozenLib < B > {
1525
+ pub const fn from_ref ( b : & B ) -> & FrozenLib < B > {
1526
+ unsafe { & * ( b as * const B as * const FrozenLib < B > ) }
1527
+ }
1528
+
1529
+ /// Decode a library to a iterable of frozen modules
1530
+ pub fn decode ( & self ) -> FrozenModulesIter < ' _ > {
1531
+ let mut data = self . bytes . as_ref ( ) ;
1532
+ let remaining = data. read_u32 ( ) . unwrap ( ) ;
1533
+ FrozenModulesIter { remaining, data }
1534
+ }
1535
+ }
1536
+
1537
+ impl < ' a , B : AsRef < [ u8 ] > + ?Sized > IntoIterator for & ' a FrozenLib < B > {
1538
+ type Item = ( & ' a str , FrozenModule < & ' a [ u8 ] > ) ;
1539
+ type IntoIter = FrozenModulesIter < ' a > ;
1540
+ fn into_iter ( self ) -> Self :: IntoIter {
1541
+ self . decode ( )
1542
+ }
1543
+ }
1544
+
1545
+ pub struct FrozenModulesIter < ' a > {
1506
1546
remaining : u32 ,
1507
- data : marshal :: Cursor < Vec < u8 > > ,
1547
+ data : & ' a [ u8 ] ,
1508
1548
}
1509
1549
1510
- impl Iterator for FrozenModulesIter {
1511
- type Item = ( String , FrozenModule ) ;
1550
+ impl < ' a > Iterator for FrozenModulesIter < ' a > {
1551
+ type Item = ( & ' a str , FrozenModule < & ' a [ u8 ] > ) ;
1512
1552
1513
1553
fn next ( & mut self ) -> Option < Self :: Item > {
1514
1554
if self . remaining > 0 {
@@ -1524,42 +1564,47 @@ pub mod frozen_lib {
1524
1564
( self . remaining as usize , Some ( self . remaining as usize ) )
1525
1565
}
1526
1566
}
1527
- impl ExactSizeIterator for FrozenModulesIter { }
1567
+ impl ExactSizeIterator for FrozenModulesIter < ' _ > { }
1528
1568
1529
- fn read_entry ( rdr : & mut impl Read ) -> Result < ( String , FrozenModule ) , marshal:: MarshalError > {
1569
+ fn read_entry < ' a > (
1570
+ rdr : & mut & ' a [ u8 ] ,
1571
+ ) -> Result < ( & ' a str , FrozenModule < & ' a [ u8 ] > ) , marshal:: MarshalError > {
1530
1572
let len = rdr. read_u32 ( ) ?;
1531
- let name = rdr. read_str ( len) ?. to_owned ( ) ;
1532
- let code = marshal:: deserialize_code ( rdr, BasicBag ) ?;
1573
+ let name = rdr. read_str_borrow ( len) ?;
1574
+ let len = rdr. read_u32 ( ) ?;
1575
+ let code_slice = rdr. read_slice_borrow ( len) ?;
1576
+ let code = FrozenCodeObject { bytes : code_slice } ;
1533
1577
let package = rdr. read_u8 ( ) ? != 0 ;
1534
1578
Ok ( ( name, FrozenModule { code, package } ) )
1535
1579
}
1536
1580
1537
- /// Encode the given iterator of frozen modules into a compressed vector of bytes
1538
- pub fn encode_lib < ' a , I > ( lib : I ) -> Vec < u8 >
1539
- where
1540
- I : IntoIterator < Item = ( & ' a str , & ' a FrozenModule ) > ,
1541
- I :: IntoIter : ExactSizeIterator + Clone ,
1542
- {
1543
- let iter = lib. into_iter ( ) ;
1544
- let mut data = Vec :: new ( ) ;
1545
- write_lib ( & mut data, iter) ;
1546
- lz4_flex:: compress_prepend_size ( & data)
1581
+ impl FrozenLib < Vec < u8 > > {
1582
+ /// Encode the given iterator of frozen modules into a compressed vector of bytes
1583
+ pub fn encode < ' a , I , B : AsRef < [ u8 ] > > ( lib : I ) -> FrozenLib < Vec < u8 > >
1584
+ where
1585
+ I : IntoIterator < Item = ( & ' a str , FrozenModule < B > ) > ,
1586
+ I :: IntoIter : ExactSizeIterator + Clone ,
1587
+ {
1588
+ let iter = lib. into_iter ( ) ;
1589
+ let mut bytes = Vec :: new ( ) ;
1590
+ write_lib ( & mut bytes, iter) ;
1591
+ Self { bytes }
1592
+ }
1547
1593
}
1548
1594
1549
- fn write_lib < ' a > (
1550
- buf : & mut impl Write ,
1551
- lib : impl ExactSizeIterator < Item = ( & ' a str , & ' a FrozenModule ) > ,
1595
+ fn write_lib < ' a , B : AsRef < [ u8 ] > > (
1596
+ buf : & mut Vec < u8 > ,
1597
+ lib : impl ExactSizeIterator < Item = ( & ' a str , FrozenModule < B > ) > ,
1552
1598
) {
1553
1599
marshal:: write_len ( buf, lib. len ( ) ) ;
1554
1600
for ( name, module) in lib {
1555
1601
write_entry ( buf, name, module) ;
1556
1602
}
1557
1603
}
1558
1604
1559
- fn write_entry ( buf : & mut impl Write , name : & str , module : & FrozenModule ) {
1560
- marshal:: write_len ( buf, name. len ( ) ) ;
1561
- buf. write_slice ( name. as_bytes ( ) ) ;
1562
- marshal:: serialize_code ( buf, & module. code ) ;
1605
+ fn write_entry ( buf : & mut Vec < u8 > , name : & str , module : FrozenModule < impl AsRef < [ u8 ] > > ) {
1606
+ marshal:: write_vec ( buf, name. as_bytes ( ) ) ;
1607
+ marshal:: write_vec ( buf, module. code . bytes . as_ref ( ) ) ;
1563
1608
buf. write_u8 ( module. package as u8 ) ;
1564
1609
}
1565
1610
}
0 commit comments