Skip to content

Commit dc13082

Browse files
committed
Add inheritence and primitive types.
1 parent b8239a9 commit dc13082

6 files changed

Lines changed: 223 additions & 70 deletions

File tree

src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,9 @@ pub fn run_file<R: io::Read, EP: sandbox::EnvProxy>(reader: &mut R, envproxy: EP
3333
try!(reader.read_exact(&mut buf).map_err(InterpreterError::Io));
3434
// TODO: do something with the content of the buffer
3535
let mut store = objects::ObjectStore::new();
36-
let module = try!(marshal::read_object(reader, &mut store).map_err(InterpreterError::Unmarshal));
37-
let mut processor = Processor { envproxy: envproxy, store: store, primitives: primitives::get_default_primitives() };
36+
let primitive_objects = objects::PrimitiveObjects::new(&mut store);
37+
let module = try!(marshal::read_object(reader, &mut store, &primitive_objects).map_err(InterpreterError::Unmarshal));
38+
let mut processor = Processor { envproxy: envproxy, store: store, primitive_functions: primitives::get_default_primitives(), primitive_objects: primitive_objects };
3839
let result = try!(processor.run_code_object(module).map_err(InterpreterError::Processor));
3940
Ok((processor, result))
4041
}

src/marshal/decode.rs

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::fmt;
22
use std::io;
33

4-
use super::super::objects::{Code, ObjectContent, ObjectRef, ObjectStore};
4+
use super::super::objects::{Code, ObjectContent, ObjectRef, ObjectStore, PrimitiveObjects};
55

66
#[derive(Debug)]
77
pub enum UnmarshalError {
@@ -73,11 +73,11 @@ fn read_unicode_string<R: io::Read>(reader: &mut R, size: usize) -> Result<Strin
7373
}
7474

7575
/// Read an arbitrary number of contiguous marshal objects
76-
fn read_objects<R: io::Read>(reader: &mut R, store: &mut ObjectStore, references: &mut Vec<ObjectRef>, size: usize) -> Result<Vec<ObjectRef>, UnmarshalError> {
76+
fn read_objects<R: io::Read>(reader: &mut R, store: &mut ObjectStore, primitive_objects: &PrimitiveObjects, references: &mut Vec<ObjectRef>, size: usize) -> Result<Vec<ObjectRef>, UnmarshalError> {
7777
let mut vector = Vec::<ObjectRef>::new();
7878
vector.reserve(size);
7979
for _ in 0..size {
80-
let object = try!(read_object(reader, store, references));
80+
let object = try!(read_object(reader, store, primitive_objects, references));
8181
vector.push(object);
8282
};
8383
Ok(vector)
@@ -108,19 +108,17 @@ macro_rules! deref_checktype {
108108
/// If the flag is true, add this object to the vector of objects before reading its content
109109
/// (required, as the order of objects matter for references).
110110
macro_rules! build_container {
111-
( $reader:expr, $store:ident, $references:ident, $container:expr, $size:expr, $flag:expr) => {{
111+
( $reader:expr, $store:ident, $references:ident, $primitive_objects:ident, $factory:ident, $size:expr, $flag:expr) => {{
112112
if $flag {
113-
let index = $references.len();
114-
let obj_ref = $store.allocate(ObjectContent::Hole);
113+
let obj_ref = ObjectRef::new();
115114
$references.push(obj_ref.clone());
116-
let objects = try!(read_objects($reader, $store, $references, $size));
117-
$store.replace_hole(&obj_ref, $container(objects));
118-
$references[index] = obj_ref.clone();
115+
let objects = try!(read_objects($reader, $store, $primitive_objects, $references, $size));
116+
$store.allocate_at(obj_ref.clone(), $primitive_objects.$factory(objects));
119117
Ok(obj_ref)
120118
}
121119
else {
122-
let objects = try!(read_objects($reader, $store, $references, $size));
123-
Ok($store.allocate($container(objects)))
120+
let objects = try!(read_objects($reader, $store, $primitive_objects, $references, $size));
121+
Ok($store.allocate($primitive_objects.$factory(objects)))
124122
}
125123
}}
126124
}
@@ -129,33 +127,33 @@ macro_rules! build_container {
129127
/// If it is a container, read its content too.
130128
/// If the first bit is 1 and the marshal protocol allows the type to be referenced,
131129
/// add it to the list of references too.
132-
pub fn read_object<R: io::Read>(reader: &mut R, store: &mut ObjectStore, references: &mut Vec<ObjectRef>) -> Result<ObjectRef, UnmarshalError> {
130+
pub fn read_object<R: io::Read>(reader: &mut R, store: &mut ObjectStore, primitive_objects: &PrimitiveObjects, references: &mut Vec<ObjectRef>) -> Result<ObjectRef, UnmarshalError> {
133131
let byte = read_byte!(reader);
134132
let flag = byte & 0b10000000 != 0;
135133
let opcode = byte & 0b01111111;
136134
match opcode as char {
137135
'0' => return Err(UnmarshalError::UnexpectedCode("NULL object in marshal data for object".to_string())),
138-
'N' => Ok(store.allocate(ObjectContent::None)),
139-
'F' => Ok(store.allocate(ObjectContent::False)),
140-
'T' => Ok(store.allocate(ObjectContent::True)),
136+
'N' => Ok(primitive_objects.none.clone()),
137+
'F' => Ok(primitive_objects.false_obj.clone()),
138+
'T' => Ok(primitive_objects.true_obj.clone()),
141139
'i' => {
142-
let obj_ref = store.allocate(ObjectContent::Int(try!(read_long(reader))));
140+
let obj_ref = store.allocate(primitive_objects.new_int(try!(read_long(reader))));
143141
if flag {
144142
references.push(obj_ref.clone());
145143
}
146144
Ok(obj_ref)
147145
},
148146
'z' | 'Z' => { // “short ascii”, “short ascii interned”
149147
let size = read_byte!(reader) as usize;
150-
let obj_ref = store.allocate(ObjectContent::String(try!(read_ascii_string(reader, size))));
148+
let obj_ref = store.allocate(primitive_objects.new_string(try!(read_ascii_string(reader, size))));
151149
if flag {
152150
references.push(obj_ref.clone());
153151
}
154152
Ok(obj_ref)
155153
},
156154
'u' => { // “unicode”
157155
let size = try!(read_long(reader)) as usize; // TODO: overflow check if usize is smaller than u32
158-
let obj_ref = store.allocate(ObjectContent::String(try!(read_unicode_string(reader, size))));
156+
let obj_ref = store.allocate(primitive_objects.new_string(try!(read_unicode_string(reader, size))));
159157
if flag {
160158
references.push(obj_ref.clone());
161159
}
@@ -169,31 +167,31 @@ pub fn read_object<R: io::Read>(reader: &mut R, store: &mut ObjectStore, referen
169167
Err(err) => return Err(UnmarshalError::Io(err)),
170168
Ok(()) => ()
171169
};
172-
let obj_ref = store.allocate(ObjectContent::Bytes(buf));
170+
let obj_ref = store.allocate(primitive_objects.new_bytes(buf));
173171
if flag {
174172
references.push(obj_ref.clone());
175173
}
176174
Ok(obj_ref)
177175
},
178176
')' => { // “small tuple”
179177
let size = read_byte!(reader) as usize;
180-
build_container!(reader, store, references, ObjectContent::Tuple, size, flag)
178+
build_container!(reader, store, references, primitive_objects, new_tuple, size, flag)
181179
},
182180
'(' => { // “tuple”
183181
let size = try!(read_long(reader)) as usize; // TODO: overflow check if usize is smaller than u32
184-
build_container!(reader, store, references, ObjectContent::Tuple, size, flag)
182+
build_container!(reader, store, references, primitive_objects, new_tuple, size, flag)
185183
},
186184
'[' => { // “list”
187185
let size = try!(read_long(reader)) as usize; // TODO: overflow check if usize is smaller than u32
188-
build_container!(reader, store, references, ObjectContent::List, size, flag)
186+
build_container!(reader, store, references, primitive_objects, new_list, size, flag)
189187
}
190188
'<' => { // “set”
191189
let size = try!(read_long(reader)) as usize; // TODO: overflow check if usize is smaller than u32
192-
build_container!(reader, store, references, ObjectContent::Set, size, flag)
190+
build_container!(reader, store, references, primitive_objects, new_set, size, flag)
193191
}
194192
'>' => { // “frozenset”
195193
let size = try!(read_long(reader)) as usize; // TODO: overflow check if usize is smaller than u32
196-
build_container!(reader, store, references, ObjectContent::FrozenSet, size, false)
194+
build_container!(reader, store, references, primitive_objects, new_frozenset, size, false)
197195
}
198196
'r' => {
199197
let index = try!(read_long(reader));
@@ -202,7 +200,7 @@ pub fn read_object<R: io::Read>(reader: &mut R, store: &mut ObjectStore, referen
202200
},
203201
'c' => { // “code”
204202
let allocate_at = if flag {
205-
let obj_ref = store.allocate(ObjectContent::Hole);
203+
let obj_ref = ObjectRef::new();
206204
references.push(obj_ref.clone());
207205
Some(obj_ref)
208206
}
@@ -214,16 +212,16 @@ pub fn read_object<R: io::Read>(reader: &mut R, store: &mut ObjectStore, referen
214212
let nlocals = try!(read_long(reader));
215213
let stacksize = try!(read_long(reader));
216214
let flags = try!(read_long(reader));
217-
let code = try!(read_object(reader, store, references));
218-
let consts = try!(read_object(reader, store, references));
219-
let names = try!(read_object(reader, store, references));
220-
let varnames = try!(read_object(reader, store, references));
221-
let freevars = try!(read_object(reader, store, references));
222-
let cellvars = try!(read_object(reader, store, references));
223-
let filename = try!(read_object(reader, store, references));
224-
let name = try!(read_object(reader, store, references));
215+
let code = try!(read_object(reader, store, primitive_objects, references));
216+
let consts = try!(read_object(reader, store, primitive_objects, references));
217+
let names = try!(read_object(reader, store, primitive_objects, references));
218+
let varnames = try!(read_object(reader, store, primitive_objects, references));
219+
let freevars = try!(read_object(reader, store, primitive_objects, references));
220+
let cellvars = try!(read_object(reader, store, primitive_objects, references));
221+
let filename = try!(read_object(reader, store, primitive_objects, references));
222+
let name = try!(read_object(reader, store, primitive_objects, references));
225223
let firstlineno = try!(read_long(reader));
226-
let lnotab = try!(read_object(reader, store, references)); // TODO: decode this
224+
let lnotab = try!(read_object(reader, store, primitive_objects, references)); // TODO: decode this
227225
let code = Code {
228226
argcount: argcount as usize,
229227
kwonlyargcount: kwonlyargcount,
@@ -242,11 +240,11 @@ pub fn read_object<R: io::Read>(reader: &mut R, store: &mut ObjectStore, referen
242240
lnotab: lnotab,
243241
};
244242

245-
let obj = ObjectContent::Code(Box::new(code));
243+
let obj = primitive_objects.new_code(code);
246244
let obj_ref = match allocate_at {
247245
None => store.allocate(obj),
248246
Some(obj_ref) => {
249-
store.replace_hole(&obj_ref, obj);
247+
store.allocate_at(obj_ref.clone(), obj);
250248
obj_ref
251249
},
252250
};
@@ -261,7 +259,8 @@ macro_rules! get_obj {
261259
( $store:ident, $bytecode:expr ) => {{
262260
let mut reader: &[u8] = $bytecode;
263261
let mut refs = Vec::new();
264-
let obj_ref = read_object(&mut reader, &mut $store, &mut refs).unwrap();
262+
let primitive_objects = PrimitiveObjects::new($store);
263+
let obj_ref = read_object(&mut reader, &mut $store, primitive_objects, &mut refs).unwrap();
265264
$store.deref(&obj_ref).content.clone()
266265
}};
267266
}

src/marshal/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
pub mod decode;
22

33
use std::io;
4-
use super::objects::{ObjectRef, ObjectStore};
4+
use super::objects::{ObjectRef, ObjectStore, PrimitiveObjects};
55

66

7-
pub fn read_object<R: io::Read>(reader: &mut R, store: &mut ObjectStore) -> Result<ObjectRef, decode::UnmarshalError> {
8-
decode::read_object(reader, store, &mut Vec::new())
7+
pub fn read_object<R: io::Read>(reader: &mut R, store: &mut ObjectStore, primitive_objects: &PrimitiveObjects) -> Result<ObjectRef, decode::UnmarshalError> {
8+
decode::read_object(reader, store, primitive_objects, &mut Vec::new())
99
}

0 commit comments

Comments
 (0)