Skip to content

Commit c369776

Browse files
committed
Better exception handling. More exceptions, less panics.
1 parent 3c3d329 commit c369776

File tree

5 files changed

+455
-373
lines changed

5 files changed

+455
-373
lines changed

src/lib.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ mod marshal;
22
mod objects;
33
mod processor;
44
mod sandbox;
5+
mod state;
56
mod varstack;
67
mod primitives;
78

89
use std::fmt;
910
use std::io;
1011
use std::collections::HashMap;
11-
pub use processor::{PyResult, Processor};
12+
pub use state::{State, PyResult};
13+
pub use processor::call_main_code;
1214

1315
pub use sandbox::{EnvProxy, RealEnvProxy, MockEnvProxy};
1416

@@ -29,7 +31,7 @@ impl fmt::Display for InterpreterError {
2931
}
3032
}
3133

32-
pub fn run_file<R: io::Read, EP: sandbox::EnvProxy>(reader: &mut R, envproxy: EP) -> Result<(Processor<EP>, PyResult), InterpreterError> {
34+
pub fn run_file<R: io::Read, EP: sandbox::EnvProxy>(reader: &mut R, envproxy: EP) -> Result<(State<EP>, PyResult), InterpreterError> {
3335
let mut buf = [0; 12];
3436
try!(reader.read_exact(&mut buf).map_err(InterpreterError::Io));
3537
if !marshal::check_magic(&buf[0..4]) {
@@ -38,8 +40,8 @@ pub fn run_file<R: io::Read, EP: sandbox::EnvProxy>(reader: &mut R, envproxy: EP
3840
let mut store = objects::ObjectStore::new();
3941
let primitive_objects = objects::PrimitiveObjects::new(&mut store);
4042
let module = try!(marshal::read_object(reader, &mut store, &primitive_objects).map_err(InterpreterError::Unmarshal));
41-
let mut processor = Processor { envproxy: envproxy, store: store, primitive_functions: primitives::get_default_primitives(), primitive_objects: primitive_objects, modules: HashMap::new(), };
42-
let result = processor.call_main_code(module);
43-
Ok((processor, result))
43+
let mut state = State { envproxy: envproxy, store: store, primitive_functions: primitives::get_default_primitives(), primitive_objects: primitive_objects, modules: HashMap::new(), };
44+
let result = call_main_code(&mut state, module);
45+
Ok((state, result))
4446
}
4547

src/objects/mod.rs

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -217,10 +217,18 @@ pub struct PrimitiveObjects {
217217
pub function_type: ObjectRef,
218218
pub code_type: ObjectRef,
219219

220+
pub module: ObjectRef,
221+
220222
pub baseexception: ObjectRef,
221-
pub runtimeerror: ObjectRef,
223+
pub processorerror: ObjectRef,
224+
pub exception: ObjectRef,
222225

223-
pub module: ObjectRef,
226+
pub nameerror: ObjectRef,
227+
pub attributeerror: ObjectRef,
228+
pub typeerror: ObjectRef,
229+
230+
pub lookuperror: ObjectRef,
231+
pub keyerror: ObjectRef,
224232

225233
pub names_map: HashMap<String, ObjectRef>,
226234
}
@@ -252,10 +260,19 @@ impl PrimitiveObjects {
252260
let function_type = store.allocate(Object::new_class("function".to_string(), None, type_ref.clone(), vec![obj_ref.clone()]));
253261
let code_type = store.allocate(Object::new_class("code".to_string(), None, type_ref.clone(), vec![obj_ref.clone()]));
254262

263+
let module = store.allocate(Object::new_class("module".to_string(), None, type_ref.clone(), vec![obj_ref.clone()]));
264+
255265
let baseexception = store.allocate(Object::new_class("BaseException".to_string(), None, type_ref.clone(), vec![obj_ref.clone()]));
256-
let runtimeerror = store.allocate(Object::new_class("RuntimeError".to_string(), None, type_ref.clone(), vec![baseexception.clone()]));
266+
let processorerror = store.allocate(Object::new_class("ProcessorError".to_string(), None, type_ref.clone(), vec![baseexception.clone()]));
267+
let exception = store.allocate(Object::new_class("Exception".to_string(), None, type_ref.clone(), vec![baseexception.clone()]));
268+
269+
let nameerror = store.allocate(Object::new_class("NameError".to_string(), None, type_ref.clone(), vec![exception.clone()]));
270+
let attributeerror = store.allocate(Object::new_class("AttributeError".to_string(), None, type_ref.clone(), vec![exception.clone()]));
271+
let typeerror = store.allocate(Object::new_class("TypeError".to_string(), None, type_ref.clone(), vec![exception.clone()]));
272+
273+
let lookuperror = store.allocate(Object::new_class("LookupError".to_string(), None, type_ref.clone(), vec![exception.clone()]));
274+
let keyerror = store.allocate(Object::new_class("KeyError".to_string(), None, type_ref.clone(), vec![lookuperror.clone()]));
257275

258-
let module = store.allocate(Object::new_class("module".to_string(), None, type_ref.clone(), vec![obj_ref.clone()]));
259276

260277
let mut map = HashMap::new();
261278
map.insert("object".to_string(), obj_ref.clone());
@@ -274,10 +291,20 @@ impl PrimitiveObjects {
274291
map.insert("str".to_string(), str_type.clone());
275292
map.insert("function".to_string(), function_type.clone());
276293
map.insert("code".to_string(), code_type.clone());
277-
map.insert("BaseException".to_string(), baseexception.clone());
278-
map.insert("RuntimeError".to_string(), runtimeerror.clone());
279294
map.insert("module".to_string(), module.clone());
280295

296+
// Base classes
297+
map.insert("BaseException".to_string(), baseexception.clone());
298+
map.insert("ProcessorError".to_string(), processorerror.clone());
299+
map.insert("Exception".to_string(), exception.clone());
300+
301+
map.insert("NameError".to_string(), nameerror.clone());
302+
map.insert("AttributeError".to_string(), attributeerror.clone());
303+
map.insert("TypeError".to_string(), typeerror.clone());
304+
305+
map.insert("LookupError".to_string(), lookuperror.clone());
306+
map.insert("KeyError".to_string(), keyerror.clone());
307+
281308
PrimitiveObjects {
282309
object: obj_ref, type_: type_ref,
283310
none_type: none_type, none: none,
@@ -286,7 +313,9 @@ impl PrimitiveObjects {
286313
set_type: set_type, frozenset_type: frozenset_type,
287314
bytes_type: bytes_type, str_type: str_type,
288315
function_type: function_type, code_type: code_type,
289-
baseexception: baseexception, runtimeerror: runtimeerror,
316+
baseexception: baseexception, processorerror: processorerror, exception: exception,
317+
nameerror: nameerror, attributeerror: attributeerror, typeerror: typeerror,
318+
lookuperror: lookuperror, keyerror: keyerror,
290319
module: module,
291320
names_map: map,
292321
}

src/primitives/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::collections::{HashMap, HashSet};
22
use std::io::Write;
33
use std::collections::linked_list::LinkedList;
44
use super::sandbox::EnvProxy;
5-
use super::processor::{Processor, ProcessorError, PyResult, PyFunction};
5+
use super::state::{State, PyResult, PyFunction};
66
use super::objects::{ObjectRef, ObjectContent, Object};
77

88
macro_rules! parse_first_arguments {
@@ -31,7 +31,7 @@ macro_rules! parse_arguments {
3131
}};
3232
}
3333

34-
fn write_stdout<EP: EnvProxy>(processor: &mut Processor<EP>, args: Vec<ObjectRef>) -> PyResult {
34+
fn write_stdout<EP: EnvProxy>(processor: &mut State<EP>, args: Vec<ObjectRef>) -> PyResult {
3535
parse_arguments!("__primitives__.write_stdout", processor.store, args,
3636
"value" "a string, boolean, or integer": {
3737
ObjectContent::String(ref s) => {
@@ -51,7 +51,7 @@ fn write_stdout<EP: EnvProxy>(processor: &mut Processor<EP>, args: Vec<ObjectRef
5151
PyResult::Return(processor.primitive_objects.none.clone())
5252
}
5353

54-
fn build_class<EP: EnvProxy>(processor: &mut Processor<EP>, args: Vec<ObjectRef>) -> PyResult {
54+
fn build_class<EP: EnvProxy>(processor: &mut State<EP>, args: Vec<ObjectRef>) -> PyResult {
5555
let name;
5656
let code;
5757
let mut args_iter = args.into_iter();
@@ -75,7 +75,7 @@ fn build_class<EP: EnvProxy>(processor: &mut Processor<EP>, args: Vec<ObjectRef>
7575
PyResult::Return(processor.store.allocate(Object::new_class(name, Some(code), processor.primitive_objects.type_.clone(), bases)))
7676
}
7777

78-
fn issubclass<EP: EnvProxy>(processor: &mut Processor<EP>, args: Vec<ObjectRef>) -> PyResult {
78+
fn issubclass<EP: EnvProxy>(processor: &mut State<EP>, args: Vec<ObjectRef>) -> PyResult {
7979
if args.len() != 2 {
8080
panic!(format!("__primitives__.issubclass takes 2 arguments, not {}", args.len()))
8181
}
@@ -104,7 +104,7 @@ fn issubclass<EP: EnvProxy>(processor: &mut Processor<EP>, args: Vec<ObjectRef>)
104104
PyResult::Return(processor.primitive_objects.false_obj.clone())
105105
}
106106

107-
fn isinstance<EP: EnvProxy>(processor: &mut Processor<EP>, mut args: Vec<ObjectRef>) -> PyResult {
107+
fn isinstance<EP: EnvProxy>(processor: &mut State<EP>, mut args: Vec<ObjectRef>) -> PyResult {
108108
if args.len() != 2 {
109109
panic!(format!("__primitives__.isinstance takes 2 arguments, not {}", args.len()))
110110
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy