forked from M-Labs/nac3
nac3core: get exception ID from symbol resolver
We need to store the exception class somewhere in order to create them back in the host. Fixes #200
This commit is contained in:
parent
84b4bd920b
commit
294943e303
|
@ -87,6 +87,7 @@ struct Nac3 {
|
||||||
working_directory: TempDir,
|
working_directory: TempDir,
|
||||||
top_levels: Vec<TopLevelComponent>,
|
top_levels: Vec<TopLevelComponent>,
|
||||||
string_store: Arc<RwLock<HashMap<String, i32>>>,
|
string_store: Arc<RwLock<HashMap<String, i32>>>,
|
||||||
|
exception_ids: Arc<RwLock<HashMap<usize, usize>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
create_exception!(nac3artiq, CompileError, exceptions::PyException);
|
create_exception!(nac3artiq, CompileError, exceptions::PyException);
|
||||||
|
@ -395,6 +396,7 @@ impl Nac3 {
|
||||||
pyid_to_def: Default::default(),
|
pyid_to_def: Default::default(),
|
||||||
working_directory,
|
working_directory,
|
||||||
string_store: Default::default(),
|
string_store: Default::default(),
|
||||||
|
exception_ids: Default::default(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,6 +444,8 @@ impl Nac3 {
|
||||||
let builtins = PyModule::import(py, "builtins")?;
|
let builtins = PyModule::import(py, "builtins")?;
|
||||||
let typings = PyModule::import(py, "typing")?;
|
let typings = PyModule::import(py, "typing")?;
|
||||||
let id_fn = builtins.getattr("id")?;
|
let id_fn = builtins.getattr("id")?;
|
||||||
|
let issubclass = builtins.getattr("issubclass")?;
|
||||||
|
let exn_class = builtins.getattr("Exception")?;
|
||||||
let store_obj = embedding_map.getattr("store_object").unwrap().to_object(py);
|
let store_obj = embedding_map.getattr("store_object").unwrap().to_object(py);
|
||||||
let store_str = embedding_map.getattr("store_str").unwrap().to_object(py);
|
let store_str = embedding_map.getattr("store_str").unwrap().to_object(py);
|
||||||
let store_fun = embedding_map.getattr("store_function").unwrap().to_object(py);
|
let store_fun = embedding_map.getattr("store_function").unwrap().to_object(py);
|
||||||
|
@ -451,7 +455,7 @@ impl Nac3 {
|
||||||
type_fn: builtins.getattr("type").unwrap().to_object(py),
|
type_fn: builtins.getattr("type").unwrap().to_object(py),
|
||||||
origin_ty_fn: typings.getattr("get_origin").unwrap().to_object(py),
|
origin_ty_fn: typings.getattr("get_origin").unwrap().to_object(py),
|
||||||
args_ty_fn: typings.getattr("get_args").unwrap().to_object(py),
|
args_ty_fn: typings.getattr("get_args").unwrap().to_object(py),
|
||||||
store_obj,
|
store_obj: store_obj.clone(),
|
||||||
store_str,
|
store_str,
|
||||||
};
|
};
|
||||||
let mut module_to_resolver_cache: HashMap<u64, _> = HashMap::new();
|
let mut module_to_resolver_cache: HashMap<u64, _> = HashMap::new();
|
||||||
|
@ -463,6 +467,18 @@ impl Nac3 {
|
||||||
let py_module: &PyAny = module.extract(py)?;
|
let py_module: &PyAny = module.extract(py)?;
|
||||||
let module_id: u64 = id_fn.call1((py_module,))?.extract()?;
|
let module_id: u64 = id_fn.call1((py_module,))?.extract()?;
|
||||||
let helper = helper.clone();
|
let helper = helper.clone();
|
||||||
|
let class_obj;
|
||||||
|
if let StmtKind::ClassDef { name, .. } = &stmt.node {
|
||||||
|
let class = py_module.getattr(name.to_string()).unwrap();
|
||||||
|
if issubclass.call1((class, exn_class)).unwrap().extract().unwrap() &&
|
||||||
|
class.getattr("artiq_builtin").is_err() {
|
||||||
|
class_obj = Some(class);
|
||||||
|
} else {
|
||||||
|
class_obj = None;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
class_obj = None;
|
||||||
|
}
|
||||||
let (name_to_pyid, resolver) =
|
let (name_to_pyid, resolver) =
|
||||||
module_to_resolver_cache.get(&module_id).cloned().unwrap_or_else(|| {
|
module_to_resolver_cache.get(&module_id).cloned().unwrap_or_else(|| {
|
||||||
let mut name_to_pyid: HashMap<StrRef, u64> = HashMap::new();
|
let mut name_to_pyid: HashMap<StrRef, u64> = HashMap::new();
|
||||||
|
@ -488,6 +504,7 @@ impl Nac3 {
|
||||||
field_to_val: Default::default(),
|
field_to_val: Default::default(),
|
||||||
helper,
|
helper,
|
||||||
string_store: self.string_store.clone(),
|
string_store: self.string_store.clone(),
|
||||||
|
exception_ids: self.exception_ids.clone(),
|
||||||
})))
|
})))
|
||||||
as Arc<dyn SymbolResolver + Send + Sync>;
|
as Arc<dyn SymbolResolver + Send + Sync>;
|
||||||
let name_to_pyid = Rc::new(name_to_pyid);
|
let name_to_pyid = Rc::new(name_to_pyid);
|
||||||
|
@ -504,6 +521,9 @@ impl Nac3 {
|
||||||
e
|
e
|
||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
|
if let Some(class_obj) = class_obj {
|
||||||
|
self.exception_ids.write().insert(def_id.0, store_obj.call1(py, (class_obj, ))?.extract(py)?);
|
||||||
|
}
|
||||||
|
|
||||||
match &stmt.node {
|
match &stmt.node {
|
||||||
StmtKind::FunctionDef { decorator_list, .. } => {
|
StmtKind::FunctionDef { decorator_list, .. } => {
|
||||||
|
@ -569,6 +589,7 @@ impl Nac3 {
|
||||||
module: module.to_object(py),
|
module: module.to_object(py),
|
||||||
helper,
|
helper,
|
||||||
string_store: self.string_store.clone(),
|
string_store: self.string_store.clone(),
|
||||||
|
exception_ids: self.exception_ids.clone(),
|
||||||
}))) as Arc<dyn SymbolResolver + Send + Sync>;
|
}))) as Arc<dyn SymbolResolver + Send + Sync>;
|
||||||
let (_, def_id, _) = composer
|
let (_, def_id, _) = composer
|
||||||
.register_top_level(synthesized.pop().unwrap(), Some(resolver.clone()), "".into())
|
.register_top_level(synthesized.pop().unwrap(), Some(resolver.clone()), "".into())
|
||||||
|
|
|
@ -41,6 +41,7 @@ pub struct InnerResolver {
|
||||||
pub primitive_ids: PrimitivePythonId,
|
pub primitive_ids: PrimitivePythonId,
|
||||||
pub helper: PythonHelper,
|
pub helper: PythonHelper,
|
||||||
pub string_store: Arc<RwLock<HashMap<String, i32>>>,
|
pub string_store: Arc<RwLock<HashMap<String, i32>>>,
|
||||||
|
pub exception_ids: Arc<RwLock<HashMap<usize, usize>>>,
|
||||||
// module specific
|
// module specific
|
||||||
pub name_to_pyid: HashMap<StrRef, u64>,
|
pub name_to_pyid: HashMap<StrRef, u64>,
|
||||||
pub module: PyObject,
|
pub module: PyObject,
|
||||||
|
@ -977,4 +978,9 @@ impl SymbolResolver for Resolver {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_exception_id(&self, tyid: usize) -> usize {
|
||||||
|
let exn_ids = self.0.exception_ids.read();
|
||||||
|
exn_ids.get(&tyid).cloned().unwrap_or(0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -468,7 +468,7 @@ pub fn exn_constructor<'ctx, 'a>(
|
||||||
let def = defs[zelf_id].read();
|
let def = defs[zelf_id].read();
|
||||||
let zelf_name =
|
let zelf_name =
|
||||||
if let TopLevelDef::Class { name, .. } = &*def { *name } else { unreachable!() };
|
if let TopLevelDef::Class { name, .. } = &*def { *name } else { unreachable!() };
|
||||||
let exception_name = format!("0:{}", zelf_name);
|
let exception_name = format!("{}:{}", ctx.resolver.get_exception_id(zelf_id), zelf_name);
|
||||||
unsafe {
|
unsafe {
|
||||||
let id_ptr = ctx.builder.build_in_bounds_gep(zelf, &[zero, zero], "exn.id");
|
let id_ptr = ctx.builder.build_in_bounds_gep(zelf, &[zero, zero], "exn.id");
|
||||||
let id = ctx.resolver.get_string_id(&exception_name);
|
let id = ctx.resolver.get_string_id(&exception_name);
|
||||||
|
@ -641,7 +641,13 @@ pub fn gen_try<'ctx, 'a, G: CodeGenerator>(
|
||||||
&mut ctx.unifier,
|
&mut ctx.unifier,
|
||||||
type_.custom.unwrap(),
|
type_.custom.unwrap(),
|
||||||
);
|
);
|
||||||
let exn_id = ctx.resolver.get_string_id(&format!("0:{}", exn_name));
|
let obj_id = if let TypeEnum::TObj { obj_id, .. } = &*ctx.unifier.get_ty(type_.custom.unwrap()) {
|
||||||
|
*obj_id
|
||||||
|
} else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
let exception_name = format!("{}:{}", ctx.resolver.get_exception_id(obj_id.0), exn_name);
|
||||||
|
let exn_id = ctx.resolver.get_string_id(&exception_name);
|
||||||
let exn_id_global =
|
let exn_id_global =
|
||||||
ctx.module.add_global(ctx.ctx.i32_type(), None, &format!("exn.{}", exn_id));
|
ctx.module.add_global(ctx.ctx.i32_type(), None, &format!("exn.{}", exn_id));
|
||||||
exn_id_global.set_initializer(&ctx.ctx.i32_type().const_int(exn_id as u64, false));
|
exn_id_global.set_initializer(&ctx.ctx.i32_type().const_int(exn_id as u64, false));
|
||||||
|
|
|
@ -136,6 +136,7 @@ pub trait SymbolResolver {
|
||||||
|
|
||||||
fn get_default_param_value(&self, expr: &nac3parser::ast::Expr) -> Option<SymbolValue>;
|
fn get_default_param_value(&self, expr: &nac3parser::ast::Expr) -> Option<SymbolValue>;
|
||||||
fn get_string_id(&self, s: &str) -> i32;
|
fn get_string_id(&self, s: &str) -> i32;
|
||||||
|
fn get_exception_id(&self, tyid: usize) -> usize;
|
||||||
// handle function call etc.
|
// handle function call etc.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1281,6 +1281,7 @@ impl TopLevelComposer {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ast::StmtKind::Assign { .. } => {}, // we don't class attributes
|
||||||
ast::StmtKind::Pass { .. } => {}
|
ast::StmtKind::Pass { .. } => {}
|
||||||
ast::StmtKind::Expr { value: _, .. } => {} // typically a docstring; ignoring all expressions matches CPython behavior
|
ast::StmtKind::Expr { value: _, .. } => {} // typically a docstring; ignoring all expressions matches CPython behavior
|
||||||
_ => {
|
_ => {
|
||||||
|
|
Loading…
Reference in New Issue