@@ -14,19 +14,17 @@ mod decl {
1414 protocol:: PyBuffer ,
1515 PyObjectRef , PyResult , TryFromObject , VirtualMachine ,
1616 } ;
17- /// TODO
18- /// PyBytes: Currently getting recursion error with match_class!
1917 use num_bigint:: { BigInt , Sign } ;
2018 use num_traits:: Zero ;
2119
2220 #[ repr( u8 ) ]
2321 enum Type {
2422 // Null = b'0',
25- // None = b'N',
23+ None = b'N' ,
2624 False = b'F' ,
2725 True = b'T' ,
2826 // StopIter = b'S',
29- // Ellipsis = b'.',
27+ Ellipsis = b'.' ,
3028 Int = b'i' ,
3129 Float = b'g' ,
3230 // Complex = b'y',
@@ -56,11 +54,11 @@ mod decl {
5654 use Type :: * ;
5755 Ok ( match value {
5856 // b'0' => Null,
59- // b'N' => None,
57+ b'N' => None ,
6058 b'F' => False ,
6159 b'T' => True ,
6260 // b'S' => StopIter,
63- // b'.' => Ellipsis,
61+ b'.' => Ellipsis ,
6462 b'i' => Int ,
6563 b'g' => Float ,
6664 // b'y' => Complex,
@@ -109,80 +107,92 @@ mod decl {
109107
110108 /// Dumping helper function to turn a value into bytes.
111109 fn dump_obj ( buf : & mut Vec < u8 > , value : PyObjectRef , vm : & VirtualMachine ) -> PyResult < ( ) > {
112- match_class ! ( match value {
113- pyint @ PyInt => {
114- if pyint. class( ) . is( vm. ctx. types. bool_type) {
115- let typ = if pyint. as_bigint( ) . is_zero( ) {
116- Type :: False
110+ if vm. is_none ( & value) {
111+ buf. push ( Type :: None as u8 ) ;
112+ } else if value. is ( & vm. ctx . ellipsis ) {
113+ buf. push ( Type :: Ellipsis as u8 ) ;
114+ } else {
115+ match_class ! ( match value {
116+ pyint @ PyInt => {
117+ if pyint. class( ) . is( vm. ctx. types. bool_type) {
118+ let typ = if pyint. as_bigint( ) . is_zero( ) {
119+ Type :: False
120+ } else {
121+ Type :: True
122+ } ;
123+ buf. push( typ as u8 ) ;
117124 } else {
118- Type :: True
119- } ;
120- buf. push( typ as u8 ) ;
121- } else {
122- buf. push( Type :: Int as u8 ) ;
123- let ( sign, int_bytes) = pyint. as_bigint( ) . to_bytes_le( ) ;
124- let mut len = int_bytes. len( ) as i32 ;
125- if sign == Sign :: Minus {
126- len = -len;
125+ buf. push( Type :: Int as u8 ) ;
126+ let ( sign, int_bytes) = pyint. as_bigint( ) . to_bytes_le( ) ;
127+ let mut len = int_bytes. len( ) as i32 ;
128+ if sign == Sign :: Minus {
129+ len = -len;
130+ }
131+ buf. extend( len. to_le_bytes( ) ) ;
132+ buf. extend( int_bytes) ;
127133 }
128- buf. extend( len. to_le_bytes( ) ) ;
129- buf. extend( int_bytes) ;
130134 }
131- }
132- pyfloat @ PyFloat => {
133- buf. push( Type :: Float as u8 ) ;
134- buf. extend( pyfloat. to_f64( ) . to_le_bytes( ) ) ;
135- }
136- pystr @ PyStr => {
137- buf. push( Type :: Str as u8 ) ;
138- write_size( buf, pystr. as_str( ) . len( ) , vm) ?;
139- buf. extend( pystr. as_str( ) . as_bytes( ) ) ;
140- }
141- pylist @ PyList => {
142- buf. push( Type :: List as u8 ) ;
143- let pylist_items = pylist. borrow_vec( ) ;
144- dump_seq( buf, pylist_items. iter( ) , vm) ?;
145- }
146- pyset @ PySet => {
147- buf. push( Type :: Set as u8 ) ;
148- let elements = pyset. elements( ) ;
149- dump_seq( buf, elements. iter( ) , vm) ?;
150- }
151- pyfrozen @ PyFrozenSet => {
152- buf. push( Type :: FrozenSet as u8 ) ;
153- let elements = pyfrozen. elements( ) ;
154- dump_seq( buf, elements. iter( ) , vm) ?;
155- }
156- pytuple @ PyTuple => {
157- buf. push( Type :: Tuple as u8 ) ;
158- dump_seq( buf, pytuple. iter( ) , vm) ?;
159- }
160- pydict @ PyDict => {
161- buf. push( Type :: Dict as u8 ) ;
162- write_size( buf, pydict. len( ) , vm) ?;
163- for ( key, value) in pydict {
164- dump_obj( buf, key, vm) ?;
165- dump_obj( buf, value, vm) ?;
135+ pyfloat @ PyFloat => {
136+ buf. push( Type :: Float as u8 ) ;
137+ buf. extend( pyfloat. to_f64( ) . to_le_bytes( ) ) ;
166138 }
167- }
168- bytes @ PyByteArray => {
169- buf. push( Type :: Bytes as u8 ) ;
170- let data = bytes. borrow_buf( ) ;
171- write_size( buf, data. len( ) , vm) ?;
172- buf. extend( & * data) ;
173- }
174- co @ PyCode => {
175- buf. push( Type :: Code as u8 ) ;
176- let bytes = co. code. map_clone_bag( & bytecode:: BasicBag ) . to_bytes( ) ;
177- write_size( buf, bytes. len( ) , vm) ?;
178- buf. extend( bytes) ;
179- }
180- _ => {
181- return Err ( vm. new_not_implemented_error(
182- "TODO: not implemented yet or marshal unsupported type" . to_owned( ) ,
183- ) ) ;
184- }
185- } ) ;
139+ pystr @ PyStr => {
140+ buf. push( Type :: Str as u8 ) ;
141+ write_size( buf, pystr. as_str( ) . len( ) , vm) ?;
142+ buf. extend( pystr. as_str( ) . as_bytes( ) ) ;
143+ }
144+ pylist @ PyList => {
145+ buf. push( Type :: List as u8 ) ;
146+ let pylist_items = pylist. borrow_vec( ) ;
147+ dump_seq( buf, pylist_items. iter( ) , vm) ?;
148+ }
149+ pyset @ PySet => {
150+ buf. push( Type :: Set as u8 ) ;
151+ let elements = pyset. elements( ) ;
152+ dump_seq( buf, elements. iter( ) , vm) ?;
153+ }
154+ pyfrozen @ PyFrozenSet => {
155+ buf. push( Type :: FrozenSet as u8 ) ;
156+ let elements = pyfrozen. elements( ) ;
157+ dump_seq( buf, elements. iter( ) , vm) ?;
158+ }
159+ pytuple @ PyTuple => {
160+ buf. push( Type :: Tuple as u8 ) ;
161+ dump_seq( buf, pytuple. iter( ) , vm) ?;
162+ }
163+ pydict @ PyDict => {
164+ buf. push( Type :: Dict as u8 ) ;
165+ write_size( buf, pydict. len( ) , vm) ?;
166+ for ( key, value) in pydict {
167+ dump_obj( buf, key, vm) ?;
168+ dump_obj( buf, value, vm) ?;
169+ }
170+ }
171+ bytes @ PyBytes => {
172+ buf. push( Type :: Bytes as u8 ) ;
173+ let data = bytes. as_bytes( ) ;
174+ write_size( buf, data. len( ) , vm) ?;
175+ buf. extend( & * data) ;
176+ }
177+ bytes @ PyByteArray => {
178+ buf. push( Type :: Bytes as u8 ) ;
179+ let data = bytes. borrow_buf( ) ;
180+ write_size( buf, data. len( ) , vm) ?;
181+ buf. extend( & * data) ;
182+ }
183+ co @ PyCode => {
184+ buf. push( Type :: Code as u8 ) ;
185+ let bytes = co. code. map_clone_bag( & bytecode:: BasicBag ) . to_bytes( ) ;
186+ write_size( buf, bytes. len( ) , vm) ?;
187+ buf. extend( bytes) ;
188+ }
189+ _ => {
190+ return Err ( vm. new_not_implemented_error(
191+ "TODO: not implemented yet or marshal unsupported type" . to_owned( ) ,
192+ ) ) ;
193+ }
194+ } )
195+ }
186196 Ok ( ( ) )
187197 }
188198
@@ -248,8 +258,10 @@ mod decl {
248258 let typ = Type :: try_from ( * type_indicator)
249259 . map_err ( |_| vm. new_value_error ( "bad marshal data (unknown type code)" . to_owned ( ) ) ) ?;
250260 let ( obj, buf) = match typ {
251- Type :: True => ( ( true ) . to_pyobject ( vm) , buf) ,
252- Type :: False => ( ( false ) . to_pyobject ( vm) , buf) ,
261+ Type :: True => ( true . to_pyobject ( vm) , buf) ,
262+ Type :: False => ( false . to_pyobject ( vm) , buf) ,
263+ Type :: None => ( vm. ctx . none ( ) , buf) ,
264+ Type :: Ellipsis => ( vm. ctx . ellipsis ( ) , buf) ,
253265 Type :: Int => {
254266 if buf. len ( ) < 4 {
255267 return Err ( too_short_error ( vm) ) ;
0 commit comments