1use 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
27pub const MAGIC_NUMBER: &[u8; 4] = b"\0MUR";
29
30#[derive(Debug)]
32pub enum DecodeError {
33 DivisionByZero,
35 EmptyList,
37 IncorrectMagicNumber([u8; 4]),
39 IncorrectVersion(u32),
41 InvalidChar(u32),
43 InvalidCodeFlags(u32),
45 InvalidName(u32),
47 InvalidParamCount,
49 InvalidType(u8),
51 InvalidUtf8,
53 UnbalancedComma,
55 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#[derive(Debug)]
93pub enum EncodeError {
94 InvalidUtf8,
96 Overflow,
98 UnencodableType(&'static str),
100 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
123pub 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
130pub 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
251pub 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
259pub 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
361struct ValueDecoder<'a, 'data> {
363 data: Cursor<&'data [u8]>,
364 ctx: &'a Context,
365}
366
367impl<'a, 'data> ValueDecoder<'a, 'data> {
368 fn new(ctx: &'a Context, data: &'data [u8]) -> ValueDecoder<'a, 'data> {
372 ValueDecoder{
373 data: Cursor::new(data),
374 ctx,
375 }
376 }
377
378 fn is_empty(&self) -> bool {
380 let buf = self.data.get_ref();
381 self.data.position() as usize == buf.len()
382 }
383
384 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 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 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
645struct ValueEncoder {
647 data: Vec<u8>,
648}
649
650impl ValueEncoder {
651 fn new() -> ValueEncoder {
653 ValueEncoder{
654 data: Vec::with_capacity(32),
655 }
656 }
657
658 fn into_bytes(self) -> Vec<u8> {
660 self.data
661 }
662
663 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 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
933fn 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 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}