11//! Implement python as a virtual machine with bytecodes. This module
22//! implements bytecode structure.
33
4- use crate :: marshal:: MarshalError ;
54use crate :: { marshal, Location } ;
65use bitflags:: bitflags;
76use itertools:: Itertools ;
@@ -46,6 +45,19 @@ pub trait ConstantBag: Sized + Copy {
4645 fn make_name ( & self , name : & str ) -> <Self :: Constant as Constant >:: Name ;
4746}
4847
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+
4961#[ derive( Clone , Copy ) ]
5062pub struct BasicBag ;
5163
@@ -1077,27 +1089,6 @@ impl<C: Constant> CodeObject<C> {
10771089 }
10781090}
10791091
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-
11011092impl < C : Constant > fmt:: Display for CodeObject < C > {
11021093 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
11031094 self . display_inner ( f, false , 1 ) ?;
@@ -1483,32 +1474,81 @@ impl<C: Constant> fmt::Debug for CodeObject<C> {
14831474 }
14841475}
14851476
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-
14931477pub mod frozen_lib {
14941478 use super :: * ;
1495- use marshal:: { Read , Write } ;
1479+ use marshal:: { Read , ReadBorrowed , Write } ;
14961480
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 ,
15031486 }
15041487
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 > {
15061546 remaining : u32 ,
1507- data : marshal :: Cursor < Vec < u8 > > ,
1547+ data : & ' a [ u8 ] ,
15081548 }
15091549
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 ] > ) ;
15121552
15131553 fn next ( & mut self ) -> Option < Self :: Item > {
15141554 if self . remaining > 0 {
@@ -1524,42 +1564,47 @@ pub mod frozen_lib {
15241564 ( self . remaining as usize , Some ( self . remaining as usize ) )
15251565 }
15261566 }
1527- impl ExactSizeIterator for FrozenModulesIter { }
1567+ impl ExactSizeIterator for FrozenModulesIter < ' _ > { }
15281568
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 > {
15301572 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 } ;
15331577 let package = rdr. read_u8 ( ) ? != 0 ;
15341578 Ok ( ( name, FrozenModule { code, package } ) )
15351579 }
15361580
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+ }
15471593 }
15481594
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 > ) > ,
15521598 ) {
15531599 marshal:: write_len ( buf, lib. len ( ) ) ;
15541600 for ( name, module) in lib {
15551601 write_entry ( buf, name, module) ;
15561602 }
15571603 }
15581604
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 ( ) ) ;
15631608 buf. write_u8 ( module. package as u8 ) ;
15641609 }
15651610}
0 commit comments