From 8d7e300a4a1c03d243038a2ec78cac2ce794e2aa Mon Sep 17 00:00:00 2001 From: ychenfo Date: Sun, 27 Mar 2022 10:13:17 +0800 Subject: [PATCH 1/3] nac3core: do not use const struct for tuple --- nac3core/src/codegen/expr.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/nac3core/src/codegen/expr.rs b/nac3core/src/codegen/expr.rs index 9657dad..7898530 100644 --- a/nac3core/src/codegen/expr.rs +++ b/nac3core/src/codegen/expr.rs @@ -1020,7 +1020,20 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( .map_or_else(Err, |v| v.unwrap().to_basic_value_enum(ctx, generator)) }) .collect::, _>>()?; - ctx.ctx.const_struct(&element_val, false).into() + let element_ty = element_val.iter().map(BasicValueEnum::get_type).collect_vec(); + let tuple_ty = ctx.ctx.struct_type(&element_ty, false); + let tuple_ptr = ctx.builder.build_alloca(tuple_ty, "tuple"); + for (i, v) in element_val.into_iter().enumerate() { + unsafe { + let ptr = ctx.builder.build_in_bounds_gep( + tuple_ptr, + &[zero, int32.const_int(i as u64, false)], + "ptr", + ); + ctx.builder.build_store(ptr, v); + } + } + ctx.builder.build_load(tuple_ptr, "tup_val").into() } ExprKind::Attribute { value, attr, .. } => { // note that we would handle class methods directly in calls -- 2.44.1 From 0d2b844a2e7d51036e00184c02b61449f7604cb4 Mon Sep 17 00:00:00 2001 From: ychenfo Date: Sun, 27 Mar 2022 10:29:08 +0800 Subject: [PATCH 2/3] nac3artiq: avoid getting tuple as pointer value --- nac3artiq/src/symbol_resolver.rs | 35 -------------------------------- 1 file changed, 35 deletions(-) diff --git a/nac3artiq/src/symbol_resolver.rs b/nac3artiq/src/symbol_resolver.rs index 999f4f9..a629377 100644 --- a/nac3artiq/src/symbol_resolver.rs +++ b/nac3artiq/src/symbol_resolver.rs @@ -808,42 +808,7 @@ impl InnerResolver { Ok(Some(global.as_pointer_value().into())) } else if ty_id == self.primitive_ids.tuple { - let id_str = id.to_string(); - - if let Some(global) = ctx.module.get_global(&id_str) { - return Ok(Some(global.as_pointer_value().into())); - } - let elements: &PyTuple = obj.cast_as()?; - let types: Result, _>, _> = elements - .iter() - .enumerate() - .map(|(i, elem)| { - self.get_obj_type( - py, - elem, - &mut ctx.unifier, - &ctx.top_level.definitions.read(), - &ctx.primitives, - ) - .map_err(|e| super::CompileError::new_err(format!("Error getting element {}: {}", i, e))) - .map(|ty| ty.map(|ty| ctx.get_llvm_type(generator, ty))) - }) - .collect(); - let types = types?.unwrap(); - let ty = ctx.ctx.struct_type(&types, false); - - { - if self.global_value_ids.read().contains_key(&id) { - let global = ctx.module.get_global(&id_str).unwrap_or_else(|| { - ctx.module.add_global(ty, Some(AddressSpace::Generic), &id_str) - }); - return Ok(Some(global.as_pointer_value().into())); - } else { - self.global_value_ids.write().insert(id, obj.into()); - } - } - let val: Result>, _> = elements.iter().enumerate().map(|(i, elem)| self.get_obj_value(py, elem, ctx, generator).map_err(|e| super::CompileError::new_err(format!("Error getting element {}: {}", i, e)))).collect(); -- 2.44.1 From bed33a7421b2c8f6b595f8feaa602de041bcc14f Mon Sep 17 00:00:00 2001 From: ychenfo Date: Sun, 27 Mar 2022 10:14:22 +0800 Subject: [PATCH 3/3] nac3standalone: add tests for tuple --- nac3standalone/demo/demo.rs | 5 +++++ nac3standalone/demo/src/tuple.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 nac3standalone/demo/src/tuple.py diff --git a/nac3standalone/demo/demo.rs b/nac3standalone/demo/demo.rs index 7f42c89..c7e4452 100644 --- a/nac3standalone/demo/demo.rs +++ b/nac3standalone/demo/demo.rs @@ -74,6 +74,11 @@ pub extern "C" fn __nac3_personality(_state: u32, _exception_object: u32, _conte unimplemented!(); } +#[no_mangle] +pub extern "C" fn __nac3_raise(_state: u32, _exception_object: u32, _context: u32) -> u32 { + unimplemented!(); +} + extern "C" { fn run() -> i32; } diff --git a/nac3standalone/demo/src/tuple.py b/nac3standalone/demo/src/tuple.py new file mode 100644 index 0000000..f71d3f9 --- /dev/null +++ b/nac3standalone/demo/src/tuple.py @@ -0,0 +1,29 @@ +@extern +def output_int32_list(x: list[int32]): + ... + +@extern +def output_int32(x: int32): + ... + +class A: + a: int32 + b: bool + def __init__(self, a: int32, b: bool): + self.a = a + self.b = b + +def run() -> int32: + data = [0, 1, 2, 3] + + t = [(d, d + d) for d in data] + for i in t: + tt = (Some(i[1]), i[0]) + tl = ([i[0], i[1] + i[0]], i[1]) + output_int32(tt[0].unwrap()) + output_int32(tt[1]) + output_int32(tl[0][0]) + output_int32(tl[0][1]) + output_int32(tl[1]) + + return 0 \ No newline at end of file -- 2.44.1