ketos/
encode.rs

1//! Implements encoding and decoding of compiled bytecode file format.
2
3use std::char::from_u32;
4use std::fmt;
5use std::fs::File;
6use std::io::{Cursor, Read, Write};
7use std::path::{Path, PathBuf};
8use std::rc::Rc;
9use std::str::from_utf8;
10
11use byteorder::{BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt};
12
13use crate::bytecode::{BYTECODE_VERSION, Code};
14use crate::bytes::Bytes;
15use crate::error::Error;
16use crate::exec::Context;
17use crate::function::Lambda;
18use crate::integer::{Integer, Ratio, Sign};
19use crate::io::{IoError, IoMode};
20use crate::module::ModuleCode;
21use crate::name::{Name, NameDisplay, NameMap, NameSet, NameStore,
22    NameInputConversion, NameOutputConversion};
23use crate::scope::ImportSet;
24use crate::structs::{StructDef, StructValueDef};
25use crate::value::Value;
26
27/// First four bytes written to a compiled bytecode file.
28pub const MAGIC_NUMBER: &[u8; 4] = b"\0MUR";
29
30/// Error in decoding bytecode file format
31#[derive(Debug)]
32pub enum DecodeError {
33    /// Ratio with zero divisor encountered
34    DivisionByZero,
35    /// Empty list encountered
36    EmptyList,
37    /// Incorrect magic number in file header
38    IncorrectMagicNumber([u8; 4]),
39    /// Incorrect version number in file header
40    IncorrectVersion(u32),
41    /// Invalid unicode character value
42    InvalidChar(u32),
43    /// Invalid flags in code object
44    InvalidCodeFlags(u32),
45    /// Invalid name value
46    InvalidName(u32),
47    /// Invalid parameter count in code object
48    InvalidParamCount,
49    /// Invalid type value
50    InvalidType(u8),
51    /// Invalid UTF-8 in string value
52    InvalidUtf8,
53    /// Unbalanced `Quasiquote` and `Comma` values
54    UnbalancedComma,
55    /// Unexpected end-of-file
56    UnexpectedEof,
57}
58
59impl fmt::Display for DecodeError {
60    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
61        use self::DecodeError::*;
62
63        match *self {
64            DivisionByZero => f.write_str("zero denominator"),
65            EmptyList => f.write_str("empty list"),
66            IncorrectMagicNumber(n) => write!(f,
67                "incorrect magic number: expected {:?}; found {:?}",
68                MAGIC_NUMBER, n),
69            IncorrectVersion(n) => write!(f,
70                "incorrect version number: expected {:08x}; found {:08x}",
71                BYTECODE_VERSION, n),
72            InvalidChar(n) => write!(f, "\\u{{{:x}}} is not a valid char", n),
73            InvalidCodeFlags(flags) =>
74                write!(f, "invalid code object flags: {:#x}", flags),
75            InvalidName(n) => write!(f, "invalid name: {}", n),
76            InvalidParamCount => f.write_str("invalid parameter count"),
77            InvalidType(ty) => write!(f, "invalid type {:#x}", ty),
78            InvalidUtf8 => f.write_str("invalid UTF-8 in string"),
79            UnbalancedComma => f.write_str("unbalanced quasiquote and comma values"),
80            UnexpectedEof => f.write_str("unexpected end-of-file"),
81        }
82    }
83}
84
85impl NameDisplay for DecodeError {
86    fn fmt(&self, _names: &NameStore, f: &mut fmt::Formatter) -> fmt::Result {
87        fmt::Display::fmt(self, f)
88    }
89}
90
91/// Error in encoding bytecode file format
92#[derive(Debug)]
93pub enum EncodeError {
94    /// A `Path` value contains invalid UTF-8
95    InvalidUtf8,
96    /// Integer overflow in encoding value
97    Overflow,
98    /// Attempt to encode a type that cannot be encoded
99    UnencodableType(&'static str),
100    /// Attempt to encode a value that cannot be encoded
101    UnencodableValue(&'static str),
102}
103
104impl fmt::Display for EncodeError {
105    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
106        use self::EncodeError::*;
107
108        match *self {
109            InvalidUtf8 => f.write_str("invalid utf-8"),
110            Overflow => f.write_str("integer overflow"),
111            UnencodableType(ty) => write!(f, "cannot encode value of type `{}`", ty),
112            UnencodableValue(v) => write!(f, "cannot encode value {}", v),
113        }
114    }
115}
116
117impl NameDisplay for EncodeError {
118    fn fmt(&self, _names: &NameStore, f: &mut fmt::Formatter) -> fmt::Result {
119        fmt::Display::fmt(self, f)
120    }
121}
122
123/// Read compiled bytecode from a file
124pub fn read_bytecode_file(path: &Path, ctx: &Context) -> Result<ModuleCode, Error> {
125    let mut f = File::open(path)
126        .map_err(|e| IoError::new(IoMode::Open, path, e))?;
127    read_bytecode(&mut f, path, ctx)
128}
129
130/// Read compiled bytecode
131pub fn read_bytecode<R: Read>(r: &mut R, path: &Path, ctx: &Context)
132        -> Result<ModuleCode, Error> {
133    let mut buf = [0; 4];
134
135    r.read_exact(&mut buf)
136        .map_err(|e| IoError::new(IoMode::Read, path, e))?;
137    check_magic_number(buf)?;
138
139    r.read_exact(&mut buf)
140        .map_err(|e| IoError::new(IoMode::Read, path, e))?;
141    check_version(buf)?;
142
143    let mut buf = Vec::new();
144    r.read_to_end(&mut buf)
145        .map_err(|e| IoError::new(IoMode::Read, path, e))?;
146
147    let mut dec = ValueDecoder::new(ctx, &buf);
148
149    let n_names = dec.read_uint()?;
150    let mut names = NameInputConversion::new();
151
152    {
153        let mut name_store = ctx.scope().names().borrow_mut();
154
155        for _ in 0..n_names {
156            let s = dec.read_string()?;
157            names.insert(name_store.add(s));
158        }
159    }
160
161    let n_exports = dec.read_uint()?;
162    let mut exports = NameSet::new();
163
164    for _ in 0..n_exports {
165        let name = dec.read_name(&names)?;
166        exports.insert(name);
167    }
168
169    let n_imports = dec.read_uint()?;
170    let mut imports = Vec::new();
171
172    for _ in 0..n_imports {
173        let mod_name = dec.read_name(&names)?;
174        let mut imp = ImportSet::new(mod_name);
175
176        let n_names = dec.read_uint()?;
177
178        for _ in 0..n_names {
179            let src = dec.read_name(&names)?;
180            let dest = dec.read_name(&names)?;
181
182            imp.names.push((src, dest));
183        }
184
185        imports.push(imp);
186    }
187
188    let n_consts = dec.read_uint()?;
189    let mut consts = Vec::with_capacity(n_consts as usize);
190
191    for _ in 0..n_consts {
192        let name = dec.read_name(&names)?;
193        let value = dec.read_value(&names)?;
194        consts.push((name, value));
195    }
196
197    let n_macros = dec.read_uint()?;
198    let mut macros = Vec::with_capacity(n_macros as usize);
199
200    for _ in 0..n_macros {
201        let name = dec.read_name(&names)?;
202        let code = Rc::new(dec.read_code(&names)?);
203        macros.push((name, code));
204    }
205
206    let n_values = dec.read_uint()?;
207    let mut values = Vec::with_capacity(n_values as usize);
208
209    for _ in 0..n_values {
210        let name = dec.read_name(&names)?;
211        let value = dec.read_value(&names)?;
212
213        values.push((name, value));
214    }
215
216    let doc = dec.read_string()?;
217    let doc = if doc.is_empty() {
218        None
219    } else {
220        Some(doc.to_owned())
221    };
222
223    let n_docs = dec.read_uint()?;
224    let mut docs = Vec::with_capacity(n_docs as usize);
225
226    for _ in 0..n_docs {
227        let name = dec.read_name(&names)?;
228        let doc = dec.read_string()?;
229
230        docs.push((name, doc.to_owned()));
231    }
232
233    let mut exprs = Vec::new();
234
235    while !dec.is_empty() {
236        exprs.push(Rc::new(dec.read_code(&names)?));
237    }
238
239    Ok(ModuleCode{
240        code: exprs,
241        constants: consts,
242        macros,
243        values,
244        exports: exports.into_slice(),
245        imports,
246        module_doc: doc,
247        docs,
248    })
249}
250
251/// Write compiled bytecode to a file
252pub fn write_bytecode_file(path: &Path, module: &ModuleCode,
253        name_store: &NameStore) -> Result<(), Error> {
254    let mut f = File::create(path)
255        .map_err(|e| IoError::new(IoMode::Create, path, e))?;
256    write_bytecode(&mut f, path, module, name_store)
257}
258
259/// Write compiled bytecode
260pub fn write_bytecode<W: Write>(w: &mut W, path: &Path, module: &ModuleCode,
261        name_store: &NameStore) -> Result<(), Error> {
262    let mut names = NameOutputConversion::new(name_store);
263    let mut body_enc = ValueEncoder::new();
264
265    body_enc.write_len(module.imports.len())?;
266
267    for imp in &module.imports {
268        body_enc.write_name(imp.module_name, &mut names)?;
269
270        body_enc.write_len(imp.names.len())?;
271
272        for &(src, dest) in &imp.names {
273            body_enc.write_name(src, &mut names)?;
274            body_enc.write_name(dest, &mut names)?;
275        }
276    }
277
278    body_enc.write_len(module.constants.len())?;
279
280    for &(name, ref value) in &module.constants {
281        body_enc.write_name(name, &mut names)?;
282        body_enc.write_value(value, &mut names)?;
283    }
284
285    body_enc.write_len(module.macros.len())?;
286
287    for &(name, ref mac) in &module.macros {
288        body_enc.write_name(name, &mut names)?;
289        body_enc.write_code(mac, &mut names)?;
290    }
291
292    body_enc.write_len(module.values.len())?;
293
294    for &(name, ref value) in &module.values {
295        body_enc.write_name(name, &mut names)?;
296        body_enc.write_value(value, &mut names)?;
297    }
298
299    if let Some(ref doc) = module.module_doc {
300        body_enc.write_string(doc)?;
301    } else {
302        body_enc.write_string("")?;
303    }
304
305    body_enc.write_len(module.docs.len())?;
306
307    for &(name, ref doc) in &module.docs {
308        body_enc.write_name(name, &mut names)?;
309        body_enc.write_string(doc)?;
310    }
311
312    for code in &module.code {
313        body_enc.write_code(code, &mut names)?;
314    }
315
316    let mut head_enc = ValueEncoder::new();
317
318    head_enc.write_len(names.len())?;
319
320    for name in names.names() {
321        head_enc.write_string(name)?;
322    }
323
324    head_enc.write_len(module.exports.len())?;
325
326    for name in &module.exports {
327        head_enc.write_name(name, &mut names)?;
328    }
329
330    w.write_all(MAGIC_NUMBER)
331        .map_err(|e| IoError::new(IoMode::Write, path, e))?;
332
333    w.write_u32::<BigEndian>(BYTECODE_VERSION)
334        .map_err(|e| IoError::new(IoMode::Write, path, e))?;
335
336    w.write_all(&head_enc.into_bytes())
337        .and_then(|_| w.write_all(&body_enc.into_bytes()))
338        .map_err(|e| IoError::new(IoMode::Write, path, e))?;
339
340    Ok(())
341}
342
343fn check_magic_number(num: [u8; 4]) -> Result<(), DecodeError> {
344    if &num == MAGIC_NUMBER {
345        Ok(())
346    } else {
347        Err(DecodeError::IncorrectMagicNumber(num))
348    }
349}
350
351fn check_version(num: [u8; 4]) -> Result<(), DecodeError> {
352    let version = BigEndian::read_u32(&num);
353
354    if version == BYTECODE_VERSION {
355        Ok(())
356    } else {
357        Err(DecodeError::IncorrectVersion(version))
358    }
359}
360
361/// Reads values from a byte stream
362struct ValueDecoder<'a, 'data> {
363    data: Cursor<&'data [u8]>,
364    ctx: &'a Context,
365}
366
367impl<'a, 'data> ValueDecoder<'a, 'data> {
368    /// Creates a new `ValueDecoder` reading from the given byte stream.
369    /// `ctx` is the execution context whose module-level scope
370    /// will be passed to newly created `Lambda` objects.
371    fn new(ctx: &'a Context, data: &'data [u8]) -> ValueDecoder<'a, 'data> {
372        ValueDecoder{
373            data: Cursor::new(data),
374            ctx,
375        }
376    }
377
378    /// Returns `true` if there is no data left to decode.
379    fn is_empty(&self) -> bool {
380        let buf = self.data.get_ref();
381        self.data.position() as usize == buf.len()
382    }
383
384    /// Reads a `Value` from the byte stream.
385    fn read_value(&mut self, names: &NameInputConversion) -> Result<Value, DecodeError> {
386        use self::types::*;
387
388        let ty = self.read_u8()?;
389
390        match ty {
391            UNIT => Ok(Value::Unit),
392            BOOL_TRUE => Ok(Value::Bool(true)),
393            BOOL_FALSE => Ok(Value::Bool(false)),
394            FLOAT => Ok(Value::Float(self.read_f64()?)),
395            INTEGER | INTEGER_NEG => {
396                let sign = if ty == INTEGER {
397                    Sign::Plus
398                } else {
399                    Sign::Minus
400                };
401
402                self.read_integer(sign).map(Value::Integer)
403            }
404            INTEGER_ZERO => Ok(Value::Integer(Integer::zero())),
405            RATIO | RATIO_NEG => {
406                let sign = if ty == RATIO {
407                    Sign::Plus
408                } else {
409                    Sign::Minus
410                };
411
412                let numer = self.read_integer(sign)?;
413                // Denominator is always positive
414                let denom = self.read_integer(Sign::Plus)?;
415
416                if denom.is_zero() {
417                    Err(DecodeError::DivisionByZero)
418                } else {
419                    Ok(Ratio::new(numer, denom).into())
420                }
421            }
422            RATIO_ZERO => Ok(Value::Ratio(Ratio::zero())),
423            NAME => Ok(Value::Name(self.read_name(names)?)),
424            KEYWORD => Ok(Value::Keyword(self.read_name(names)?)),
425            CHAR => {
426                let c = self.read_u32()?;
427                from_u32(c)
428                    .map(Value::Char)
429                    .ok_or_else(|| DecodeError::InvalidChar(c))
430            }
431            STRING => self.read_string().map(|s| s.into()),
432            BYTES => self.read_byte_string().map(|s| s.into()),
433            PATH => self.read_string().map(|s| PathBuf::from(s).into()),
434            // XXX: Decoding struct values is not implemented
435            STRUCT => Err(DecodeError::InvalidType(STRUCT)),
436            STRUCT_DEF => {
437                let name = self.read_name(names)?;
438                let n = self.read_uint()?;
439                let mut fields = NameMap::new();
440
441                for _ in 0..n {
442                    let field = self.read_name(names)?;
443                    let ty = self.read_name(names)?;
444
445                    fields.insert(field, ty);
446                }
447
448                let def = StructValueDef::new(fields.into_slice());
449
450                Ok(Value::StructDef(Rc::new(StructDef::new(name, Box::new(def)))))
451            }
452            QUASI_QUOTE => {
453                let n = u32::from(self.read_u8()?);
454                self.read_value(names).map(|v| v.quasiquote(n))
455            }
456            QUASI_QUOTE_ONE => self.read_value(names).map(|v| v.quasiquote(1)),
457            COMMA => {
458                let n = u32::from(self.read_u8()?);
459                self.read_value(names).map(|v| v.comma(n))
460            }
461            COMMA_ONE => self.read_value(names).map(|v| v.comma(1)),
462            COMMA_AT => {
463                let n = u32::from(self.read_u8()?);
464                self.read_value(names).map(|v| v.comma_at(n))
465            }
466            COMMA_AT_ONE => self.read_value(names).map(|v| v.comma_at(1)),
467            QUOTE => {
468                let n = u32::from(self.read_u8()?);
469                self.read_value(names).map(|v| v.quote(n))
470            }
471            QUOTE_ONE => self.read_value(names).map(|v| v.quote(1)),
472            LIST => {
473                let n = self.read_len()?;
474
475                if n == 0 {
476                    return Err(DecodeError::EmptyList);
477                }
478
479                let mut v = Vec::with_capacity(n);
480
481                for _ in 0..n {
482                    v.push(self.read_value(names)?);
483                }
484
485                Ok(v.into())
486            }
487            LAMBDA => {
488                let code = self.read_code(names)?;
489                Ok(Value::Lambda(Lambda::new(Rc::new(code), self.ctx.scope())))
490            }
491            _ => Err(DecodeError::InvalidType(ty))
492        }
493    }
494
495    fn read_bytes(&mut self, n: usize) -> Result<&'data [u8], DecodeError> {
496        read_cursor(&mut self.data, n).ok_or(DecodeError::UnexpectedEof)
497    }
498
499    fn read_code(&mut self, names: &NameInputConversion) -> Result<Code, DecodeError> {
500        use crate::bytecode::code_flags::*;
501
502        let flags = u32::from(self.read_u8()?);
503
504        if flags & ALL_FLAGS != flags {
505            return Err(DecodeError::InvalidCodeFlags(flags));
506        }
507
508        let name = if flags & HAS_NAME == 0 {
509            None
510        } else {
511            Some(self.read_name(names)?)
512        };
513
514        let doc = if flags & HAS_DOC_STRING == 0 {
515            None
516        } else {
517            Some(self.read_string()?.to_owned())
518        };
519
520        let n_consts = self.read_len()?;
521        let mut consts = Vec::with_capacity(n_consts);
522
523        for _ in 0..n_consts {
524            let v = self.read_value(names)?;
525            validate_value(&v)?;
526            consts.push(v);
527        }
528
529        let code_bytes = self.read_len()?;
530        let code = self.read_bytes(code_bytes)?.to_vec();
531
532        let n_params = self.read_uint()?;
533        let req_params = self.read_uint()?;
534
535        if n_params < req_params {
536            return Err(DecodeError::InvalidParamCount);
537        }
538
539        let mut kw_params = Vec::new();
540
541        match flags & PARAM_FLAGS_MASK {
542            0 | HAS_REST_PARAMS => (),
543            HAS_KW_PARAMS => {
544                let n = self.read_len()?;
545
546                if n == 0 {
547                    return Err(DecodeError::InvalidCodeFlags(flags));
548                }
549
550                kw_params.reserve_exact(n);
551
552                for _ in 0..n {
553                    kw_params.push(self.read_name(names)?);
554                }
555            }
556            _ => return Err(DecodeError::InvalidCodeFlags(flags))
557        }
558
559        Ok(Code{
560            name,
561            consts: consts.into_boxed_slice(),
562            code: code.into_boxed_slice(),
563            kw_params: kw_params.into_boxed_slice(),
564            n_params,
565            req_params,
566            flags,
567            doc,
568        })
569    }
570
571    fn read_name(&mut self, names: &NameInputConversion) -> Result<Name, DecodeError> {
572        let n = self.read_uint()?;
573        names.get(n).ok_or_else(|| DecodeError::InvalidName(n))
574    }
575
576    fn read_string(&mut self) -> Result<&'data str, DecodeError> {
577        let n = self.read_uint()?;
578        let b = self.read_bytes(n as usize)?;
579
580        from_utf8(b).map_err(|_| DecodeError::InvalidUtf8)
581    }
582
583    fn read_byte_string(&mut self) -> Result<Bytes, DecodeError> {
584        let n = self.read_uint()?;
585        let b = self.read_bytes(n as usize)?;
586
587        Ok(Bytes::from(b))
588    }
589
590    fn read_integer(&mut self, sign: Sign) -> Result<Integer, DecodeError> {
591        let n = self.read_uint()?;
592        let b = self.read_bytes(n as usize)?;
593        Ok(Integer::from_bytes_be(sign, b))
594    }
595
596    fn read_u8(&mut self) -> Result<u8, DecodeError> {
597        Ok(self.data.read_u8()
598            .map_err(|_| DecodeError::UnexpectedEof)?)
599    }
600
601    fn read_u32(&mut self) -> Result<u32, DecodeError> {
602        Ok(self.data.read_u32::<BigEndian>()
603            .map_err(|_| DecodeError::UnexpectedEof)?)
604    }
605
606    fn read_len(&mut self) -> Result<usize, DecodeError> {
607        self.read_uint().map(|n| n as usize)
608    }
609
610    fn read_uint(&mut self) -> Result<u32, DecodeError> {
611        let hi = u32::from(self.read_u8()?);
612
613        if hi & 0x80 == 0 {
614            Ok(hi)
615        } else {
616            let hi = (hi & 0x7f) << 8;
617            let lo = u32::from(self.read_u8()?);
618            Ok(hi | lo)
619        }
620    }
621
622    fn read_f64(&mut self) -> Result<f64, DecodeError> {
623        Ok(self.data.read_f64::<BigEndian>()
624            .map_err(|_| DecodeError::UnexpectedEof)?)
625    }
626}
627
628fn validate_value(v: &Value) -> Result<(), DecodeError> {
629    validate_value_inner(v, 0)
630}
631
632fn validate_value_inner(v: &Value, quasi: u32) -> Result<(), DecodeError> {
633    match *v {
634        Value::Quasiquote(ref v, n) => validate_value_inner(v, quasi + n),
635        Value::Comma(ref v, n) | Value::CommaAt(ref v, n) => if n >= quasi {
636            Err(DecodeError::UnbalancedComma)
637        } else {
638            validate_value_inner(v, quasi - n)
639        },
640        Value::Quote(ref v, _) => validate_value_inner(v, quasi),
641        _ => Ok(())
642    }
643}
644
645/// Encodes values to a byte stream
646struct ValueEncoder {
647    data: Vec<u8>,
648}
649
650impl ValueEncoder {
651    /// Creates a new `ValueEncoder`.
652    fn new() -> ValueEncoder {
653        ValueEncoder{
654            data: Vec::with_capacity(32),
655        }
656    }
657
658    /// Consumes the encoder and returns the encoded byte stream.
659    fn into_bytes(self) -> Vec<u8> {
660        self.data
661    }
662
663    /// Writes a `Value` to the byte stream.
664    fn write_value(&mut self, value: &Value, names: &mut NameOutputConversion) -> Result<(), EncodeError> {
665        use self::types::*;
666
667        match *value {
668            Value::Unit => self.write_u8(UNIT),
669            Value::Bool(b) => if b {
670                self.write_u8(BOOL_TRUE);
671            } else {
672                self.write_u8(BOOL_FALSE);
673            },
674            Value::Float(f) => {
675                self.write_u8(FLOAT);
676                self.write_f64(f);
677            }
678            Value::Integer(ref i) => {
679                if i.is_zero() {
680                    self.write_u8(INTEGER_ZERO);
681                } else {
682                    if i.is_negative() {
683                        self.write_u8(INTEGER_NEG);
684                    } else {
685                        self.write_u8(INTEGER);
686                    }
687
688                    self.write_integer(i)?;
689                }
690            }
691            Value::Ratio(ref r) => {
692                if r.is_zero() {
693                    self.write_u8(RATIO_ZERO);
694                } else {
695                    if r.is_positive() {
696                        self.write_u8(RATIO);
697                    } else {
698                        self.write_u8(RATIO_NEG);
699                    }
700
701                    self.write_integer(r.numer())?;
702                    self.write_integer(r.denom())?;
703                }
704            }
705            Value::Name(name) => {
706                self.write_u8(NAME);
707                self.write_name(name, names)?;
708            }
709            Value::Keyword(name) => {
710                self.write_u8(KEYWORD);
711                self.write_name(name, names)?;
712            }
713            Value::Char(c) => {
714                self.write_u8(CHAR);
715                self.write_u32(c as u32);
716            }
717            Value::String(ref s) => {
718                self.write_u8(STRING);
719                self.write_string(s)?;
720            }
721            Value::Bytes(ref s) => {
722                self.write_u8(BYTES);
723                self.write_byte_string(s)?;
724            }
725            Value::Path(ref p) => {
726                self.write_u8(PATH);
727                self.write_path(p)?;
728            }
729            // TODO: Encode/decode struct values.
730            // Modules could begin with a listing of all defined StructDefs,
731            // which could be referenced by index thereafter.
732            // However, Struct encoding/decoding must also account for the
733            // possibility that a Struct value exists in a module based on a
734            // definition which is found in another module.
735            Value::Struct(_) => return Err(EncodeError::UnencodableType("struct")),
736            Value::StructDef(ref def) => {
737                if let Some(vdef) = def.def().downcast_ref::<StructValueDef>() {
738                    self.write_u8(STRUCT_DEF);
739
740                    let fields = vdef.fields();
741
742                    self.write_name(def.name(), names)?;
743                    self.write_len(fields.len())?;
744
745                    for &(name, ty) in fields {
746                        self.write_name(name, names)?;
747                        self.write_name(ty, names)?;
748                    }
749                } else {
750                    return Err(EncodeError::UnencodableType("struct-def"));
751                }
752            }
753            Value::Quasiquote(ref v, 1) => {
754                self.write_u8(QUASI_QUOTE_ONE);
755                self.write_value(v, names)?;
756            }
757            Value::Quasiquote(ref v, n) if n <= 0xff => {
758                self.write_u8(QUASI_QUOTE);
759                self.write_u8(n as u8);
760                self.write_value(v, names)?;
761            }
762            Value::Comma(ref v, 1) => {
763                self.write_u8(COMMA_ONE);
764                self.write_value(v, names)?;
765            }
766            Value::Comma(ref v, n) if n <= 0xff => {
767                self.write_u8(COMMA);
768                self.write_u8(n as u8);
769                self.write_value(v, names)?;
770            }
771            Value::CommaAt(ref v, 1) => {
772                self.write_u8(COMMA_AT_ONE);
773                self.write_value(v, names)?;
774            }
775            Value::CommaAt(ref v, n) if n <= 0xff => {
776                self.write_u8(COMMA_AT);
777                self.write_u8(n as u8);
778                self.write_value(v, names)?;
779            }
780            Value::Quote(ref v, 1) => {
781                self.write_u8(QUOTE_ONE);
782                self.write_value(v, names)?;
783            }
784            Value::Quote(ref v, n) if n <= 0xff => {
785                self.write_u8(QUOTE);
786                self.write_u8(n as u8);
787                self.write_value(v, names)?;
788            }
789            Value::Comma(_, _)
790            | Value::CommaAt(_, _)
791            | Value::Quasiquote(_, _)
792            | Value::Quote(_, _) => {
793                return Err(EncodeError::Overflow);
794            }
795            Value::List(ref li) => {
796                self.write_u8(LIST);
797                self.write_len(li.len())?;
798
799                for v in li {
800                    self.write_value(v, names)?;
801                }
802            }
803            Value::Lambda(ref l) => {
804                if l.values.is_some() {
805                    return Err(EncodeError::UnencodableValue(
806                        "lambda with enclosed values"));
807                }
808                self.write_u8(LAMBDA);
809                self.write_code(&l.code, names)?;
810            }
811            Value::Foreign(_) =>
812                return Err(EncodeError::UnencodableType("foreign value")),
813            ref v => return Err(EncodeError::UnencodableType(v.type_name()))
814        }
815
816        Ok(())
817    }
818
819    fn write_bytes(&mut self, b: &[u8]) {
820        self.data.extend(b);
821    }
822
823    fn write_code(&mut self, code: &Code, names: &mut NameOutputConversion) -> Result<(), EncodeError> {
824        use crate::bytecode::code_flags::*;
825
826        self.write_u8(code.flags as u8);
827
828        assert_eq!(code.flags & HAS_NAME != 0, code.name.is_some());
829        assert_eq!(code.flags & HAS_DOC_STRING != 0, code.doc.is_some());
830
831        if let Some(name) = code.name {
832            self.write_name(name, names)?;
833        }
834
835        if let Some(ref doc) = code.doc {
836            self.write_string(doc)?;
837        }
838
839        self.write_len(code.consts.len())?;
840
841        for c in code.consts.iter() {
842            self.write_value(c, names)?;
843        }
844
845        self.write_len(code.code.len())?;
846        self.write_bytes(&code.code);
847
848        self.write_uint(code.n_params)?;
849        self.write_uint(code.req_params)?;
850
851        assert_eq!(code.flags & PARAM_FLAGS_MASK == HAS_KW_PARAMS,
852            !code.kw_params.is_empty());
853
854        if !code.kw_params.is_empty() {
855            self.write_len(code.kw_params.len())?;
856
857            for &name in code.kw_params.iter() {
858                self.write_name(name, names)?;
859            }
860        }
861
862        Ok(())
863    }
864
865    fn write_integer(&mut self, i: &Integer) -> Result<(), EncodeError> {
866        let (_, b) = i.to_bytes_be();
867
868        self.write_len(b.len())?;
869        self.write_bytes(&b);
870        Ok(())
871    }
872
873    fn write_name(&mut self, name: Name, names: &mut NameOutputConversion) -> Result<(), EncodeError> {
874        let n = names.add(name);
875        self.write_uint(n)
876    }
877
878    fn write_string(&mut self, s: &str) -> Result<(), EncodeError> {
879        self.write_len(s.len())?;
880        self.write_bytes(s.as_bytes());
881        Ok(())
882    }
883
884    fn write_byte_string(&mut self, b: &[u8]) -> Result<(), EncodeError> {
885        self.write_len(b.len())?;
886        self.write_bytes(b);
887        Ok(())
888    }
889
890    fn write_path(&mut self, p: &Path) -> Result<(), EncodeError> {
891        match p.to_str() {
892            Some(s) => self.write_string(s),
893            None => Err(EncodeError::InvalidUtf8)
894        }
895    }
896
897    fn write_u8(&mut self, b: u8) {
898        self.data.push(b);
899    }
900
901    fn write_u32(&mut self, n: u32) {
902        let _ = self.data.write_u32::<BigEndian>(n);
903    }
904
905    fn write_len(&mut self, n: usize) -> Result<(), EncodeError> {
906        if n > 0x7fff {
907            Err(EncodeError::Overflow)
908        } else {
909            self.write_uint(n as u32)
910        }
911    }
912
913    fn write_uint(&mut self, n: u32) -> Result<(), EncodeError> {
914        if n <= 0x7f {
915            self.write_u8(n as u8);
916            Ok(())
917        } else if n <= 0x7fff {
918            let hi = (n >> 8) as u8;
919            let lo = n as u8;
920            self.write_u8(hi | 0x80);
921            self.write_u8(lo);
922            Ok(())
923        } else {
924            Err(EncodeError::Overflow)
925        }
926    }
927
928    fn write_f64(&mut self, f: f64) {
929        let _ = self.data.write_f64::<BigEndian>(f);
930    }
931}
932
933/// Reads bytes from a cursor without copying data.
934fn read_cursor<'a>(cur: &mut Cursor<&'a [u8]>, n: usize) -> Option<&'a [u8]> {
935    let pos = cur.position() as usize;
936    let bytes = *cur.get_ref();
937
938    if bytes.len() < pos + n {
939        None
940    } else {
941        cur.set_position((pos + n) as u64);
942        Some(&bytes[pos..pos + n])
943    }
944}
945
946macro_rules! types {
947    ( $( $name:ident = $value:expr , )+ ) => {
948        /// Byte constants indicating the type of the following value.
949        ///
950        /// Any addition, deletion, or modification to these constants constitutes
951        /// a breaking change to the bytecode format.
952        mod types {
953            $( pub const $name: u8 = $value; )+
954        }
955    }
956}
957
958types!{
959    UNIT = 0,
960    BOOL_TRUE = 1,
961    BOOL_FALSE = 2,
962    FLOAT = 3,
963    INTEGER = 4,
964    INTEGER_NEG = 5,
965    INTEGER_ZERO = 6,
966    RATIO = 7,
967    RATIO_NEG = 8,
968    RATIO_ZERO = 9,
969    NAME = 10,
970    KEYWORD = 11,
971    CHAR = 12,
972    STRING = 13,
973    BYTES = 14,
974    PATH = 15,
975    STRUCT = 16,
976    STRUCT_DEF = 17,
977    QUASI_QUOTE = 18,
978    QUASI_QUOTE_ONE = 19,
979    COMMA = 20,
980    COMMA_ONE = 21,
981    COMMA_AT = 22,
982    COMMA_AT_ONE = 23,
983    QUOTE = 24,
984    QUOTE_ONE = 25,
985    LIST = 26,
986    LAMBDA = 27,
987}