From 0fb9998a96acf1fba22f686463236be155d307b2 Mon Sep 17 00:00:00 2001 From: ychenfo Date: Mon, 4 Apr 2022 23:21:00 +0800 Subject: [PATCH] nac3core: add location information to codegen context --- nac3core/src/codegen/expr.rs | 53 ++++++++++++++++--------------- nac3core/src/codegen/mod.rs | 6 ++-- nac3core/src/codegen/stmt.rs | 9 +++--- nac3core/src/toplevel/builtins.rs | 17 ++++++++-- 4 files changed, 51 insertions(+), 34 deletions(-) diff --git a/nac3core/src/codegen/expr.rs b/nac3core/src/codegen/expr.rs index 63c17b47..fe46c212 100644 --- a/nac3core/src/codegen/expr.rs +++ b/nac3core/src/codegen/expr.rs @@ -395,9 +395,9 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> { self.gen_const(generator, &nac3parser::ast::Constant::Str(s.into()), self.primitives.str) } - pub fn raise_exn( + pub fn raise_exn( &mut self, - generator: &mut G, + generator: &mut dyn CodeGenerator, name: &str, msg: BasicValueEnum<'ctx>, params: [Option>; 3], @@ -434,9 +434,9 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> { gen_raise(generator, self, Some(&zelf.into()), loc); } - pub fn make_assert( + pub fn make_assert( &mut self, - generator: &mut G, + generator: &mut dyn CodeGenerator, cond: IntValue<'ctx>, err_name: &str, err_msg: &str, @@ -447,9 +447,9 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> { self.make_assert_impl(generator, cond, err_name, err_msg, params, loc) } - pub fn make_assert_impl( + pub fn make_assert_impl( &mut self, - generator: &mut G, + generator: &mut dyn CodeGenerator, cond: IntValue<'ctx>, err_name: &str, err_msg: BasicValueEnum<'ctx>, @@ -969,6 +969,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( ctx: &mut CodeGenContext<'ctx, 'a>, expr: &Expr>, ) -> Result>, String> { + ctx.current_loc = expr.location; let int32 = ctx.ctx.i32_type(); let zero = int32.const_int(0, false); Ok(Some(match &expr.node { @@ -1368,26 +1369,26 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( unreachable!() } }; - // directly generate code for option.unwrap - // since it needs location information from ast - if attr == &"unwrap".into() - && id == ctx.primitives.option.get_obj_id(&ctx.unifier) - { - if let BasicValueEnum::PointerValue(ptr) = val.to_basic_value_enum(ctx, generator)? { - let not_null = ctx.builder.build_is_not_null(ptr, "unwrap_not_null"); - ctx.make_assert( - generator, - not_null, - "0:UnwrapNoneError", - "", - [None, None, None], - expr.location, - ); - return Ok(Some(ctx.builder.build_load(ptr, "unwrap_some").into())) - } else { - unreachable!("option must be ptr") - } - } + // // directly generate code for option.unwrap + // // since it needs location information from ast + // if attr == &"unwrap".into() + // && id == ctx.primitives.option.get_obj_id(&ctx.unifier) + // { + // if let BasicValueEnum::PointerValue(ptr) = val.to_basic_value_enum(ctx, generator)? { + // let not_null = ctx.builder.build_is_not_null(ptr, "unwrap_not_null"); + // ctx.make_assert( + // generator, + // not_null, + // "0:UnwrapNoneError", + // "", + // [None, None, None], + // expr.location, + // ); + // return Ok(Some(ctx.builder.build_load(ptr, "unwrap_some").into())) + // } else { + // unreachable!("option must be ptr") + // } + // } return Ok(generator .gen_call( ctx, diff --git a/nac3core/src/codegen/mod.rs b/nac3core/src/codegen/mod.rs index 7e0b0f92..191b023e 100644 --- a/nac3core/src/codegen/mod.rs +++ b/nac3core/src/codegen/mod.rs @@ -20,7 +20,7 @@ use inkwell::{ values::{BasicValueEnum, FunctionValue, PhiValue, PointerValue} }; use itertools::Itertools; -use nac3parser::ast::{Stmt, StrRef}; +use nac3parser::ast::{Stmt, StrRef, Location}; use parking_lot::{Condvar, Mutex}; use std::collections::{HashMap, HashSet}; use std::sync::{ @@ -77,6 +77,7 @@ pub struct CodeGenContext<'ctx, 'a> { pub outer_catch_clauses: Option<(Vec>>, BasicBlock<'ctx>, PhiValue<'ctx>)>, pub need_sret: bool, + pub current_loc: Location, } impl<'ctx, 'a> CodeGenContext<'ctx, 'a> { @@ -570,7 +571,8 @@ pub fn gen_func_impl<'ctx, G: CodeGenerator, F: FnOnce(&mut G, &mut CodeGenConte module, unifier, static_value_store, - need_sret: has_sret + need_sret: has_sret, + current_loc: Default::default(), }; let result = codegen_function(generator, &mut code_gen_context); diff --git a/nac3core/src/codegen/stmt.rs b/nac3core/src/codegen/stmt.rs index 18ffc823..6fddfb2f 100644 --- a/nac3core/src/codegen/stmt.rs +++ b/nac3core/src/codegen/stmt.rs @@ -422,8 +422,8 @@ pub fn final_proxy<'ctx, 'a>( final_paths.push(block); } -pub fn get_builtins<'ctx, 'a, G: CodeGenerator>( - generator: &mut G, +pub fn get_builtins<'ctx, 'a>( + generator: &mut dyn CodeGenerator, ctx: &mut CodeGenContext<'ctx, 'a>, symbol: &str, ) -> FunctionValue<'ctx> { @@ -519,8 +519,8 @@ pub fn exn_constructor<'ctx, 'a>( Ok(Some(zelf.into())) } -pub fn gen_raise<'ctx, 'a, G: CodeGenerator>( - generator: &mut G, +pub fn gen_raise<'ctx, 'a>( + generator: &mut dyn CodeGenerator, ctx: &mut CodeGenContext<'ctx, 'a>, exception: Option<&BasicValueEnum<'ctx>>, loc: Location, @@ -931,6 +931,7 @@ pub fn gen_stmt<'ctx, 'a, G: CodeGenerator>( ctx: &mut CodeGenContext<'ctx, 'a>, stmt: &Stmt>, ) -> Result<(), String> { + ctx.current_loc = stmt.location; match &stmt.node { StmtKind::Pass { .. } => {} StmtKind::Expr { value, .. } => { diff --git a/nac3core/src/toplevel/builtins.rs b/nac3core/src/toplevel/builtins.rs index 9491d5e7..4705a0ba 100644 --- a/nac3core/src/toplevel/builtins.rs +++ b/nac3core/src/toplevel/builtins.rs @@ -263,8 +263,21 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { instance_to_stmt: Default::default(), resolver: None, codegen_callback: Some(Arc::new(GenCall::new(Box::new( - |_, _, _, _, _| { - unreachable!("handled in gen_expr") + |ctx, obj, _, _, generator| { + if let BasicValueEnum::PointerValue(ptr) = obj.unwrap().1.to_basic_value_enum(ctx, generator)? { + let not_null = ctx.builder.build_is_not_null(ptr, "unwrap_not_null"); + ctx.make_assert( + generator, + not_null, + "0:UnwrapNoneError", + "", + [None, None, None], + ctx.current_loc, + ); + Ok(Some(ctx.builder.build_load(ptr, "unwrap_some"))) + } else { + unreachable!("option must be ptr") + } }, )))), loc: None,