From bded20949267ef4f27170eaa4b9aa824a0abc566 Mon Sep 17 00:00:00 2001 From: wpt967 Date: Thu, 12 Sep 2024 16:55:13 +0100 Subject: [PATCH] WIP --- .../src/polkavm/context/debug_info.rs | 3 - .../context/function/runtime/deploy_code.rs | 21 ++++- .../polkavm/context/function/runtime/entry.rs | 24 ++++- .../context/function/runtime/runtime_code.rs | 21 ++++- .../src/yul/parser/statement/assignment.rs | 38 ++++---- .../src/yul/parser/statement/block.rs | 54 ++++++++---- .../parser/statement/function_definition.rs | 88 +++++++++++-------- .../src/yul/parser/statement/object.rs | 24 ++--- 8 files changed, 180 insertions(+), 93 deletions(-) diff --git a/crates/llvm-context/src/polkavm/context/debug_info.rs b/crates/llvm-context/src/polkavm/context/debug_info.rs index ca56ce4c..18aba296 100644 --- a/crates/llvm-context/src/polkavm/context/debug_info.rs +++ b/crates/llvm-context/src/polkavm/context/debug_info.rs @@ -111,9 +111,6 @@ impl<'ctx> DebugInfo<'ctx> { is_optimized, ); - self.builder - .create_lexical_block(function.as_debug_info_scope(), file, line_num, column); - Ok(function) } diff --git a/crates/llvm-context/src/polkavm/context/function/runtime/deploy_code.rs b/crates/llvm-context/src/polkavm/context/function/runtime/deploy_code.rs index 8253764f..ba735840 100644 --- a/crates/llvm-context/src/polkavm/context/function/runtime/deploy_code.rs +++ b/crates/llvm-context/src/polkavm/context/function/runtime/deploy_code.rs @@ -63,6 +63,7 @@ where context.set_code_type(CodeType::Deploy); if let Some(dinfo) = context.debug_info() { + let di_builder = dinfo.builder(); let line_num: u32 = 0; let column: u32 = 0; let func_name: &str = runtime::FUNCTION_DEPLOY_CODE; @@ -85,13 +86,30 @@ where false, Some(inkwell::debug_info::DIFlagsConstants::PUBLIC), )?; - dinfo.push_scope(di_func_scope.as_debug_info_scope()); + let _ = dinfo.push_scope(di_func_scope.as_debug_info_scope()); let func_value = context .current_function() .borrow() .declaration() .function_value(); let _ = func_value.set_subprogram(di_func_scope); + + let lexical_scope = di_builder.create_lexical_block( + di_func_scope.as_debug_info_scope(), + dinfo.compilation_unit().get_file(), + line_num, + column, + ).as_debug_info_scope(); + let _ = dinfo.push_scope(lexical_scope); + + let di_loc = di_builder.create_debug_location( + context.llvm(), + line_num, + 0, + lexical_scope, + None, + ); + context.builder().set_current_debug_location(di_loc) } self.inner.into_llvm(context)?; @@ -111,6 +129,7 @@ where if let Some(dinfo) = context.debug_info() { let _ = dinfo.pop_scope(); + let _ = dinfo.pop_scope(); } Ok(()) diff --git a/crates/llvm-context/src/polkavm/context/function/runtime/entry.rs b/crates/llvm-context/src/polkavm/context/function/runtime/entry.rs index b18c753a..6ab05bb5 100644 --- a/crates/llvm-context/src/polkavm/context/function/runtime/entry.rs +++ b/crates/llvm-context/src/polkavm/context/function/runtime/entry.rs @@ -254,6 +254,7 @@ where context.set_basic_block(context.current_function().borrow().entry_block()); if let Some(dinfo) = context.debug_info() { + let di_builder = dinfo.builder(); let line_num: u32 = 0; let column: u32 = 0; let func_name: &str = runtime::FUNCTION_ENTRY; @@ -276,7 +277,27 @@ where false, Some(inkwell::debug_info::DIFlagsConstants::PUBLIC), )?; - dinfo.push_scope(di_func_scope.as_debug_info_scope()); + let _ = dinfo.push_scope(di_func_scope.as_debug_info_scope()); + let func_value = context + .current_function() + .borrow() + .declaration() + .function_value(); + let _ = func_value.set_subprogram(di_func_scope); + + let lexical_scope = di_builder + .create_lexical_block( + di_func_scope.as_debug_info_scope(), + dinfo.compilation_unit().get_file(), + line_num, + column, + ) + .as_debug_info_scope(); + let _ = dinfo.push_scope(lexical_scope); + + let di_loc = + di_builder.create_debug_location(context.llvm(), line_num, 0, lexical_scope, None); + context.builder().set_current_debug_location(di_loc) } Self::initialize_globals(context)?; @@ -289,6 +310,7 @@ where if let Some(dinfo) = context.debug_info() { let _ = dinfo.pop_scope(); + let _ = dinfo.pop_scope(); } Ok(()) diff --git a/crates/llvm-context/src/polkavm/context/function/runtime/runtime_code.rs b/crates/llvm-context/src/polkavm/context/function/runtime/runtime_code.rs index 8fc6a5fe..4111ce8c 100644 --- a/crates/llvm-context/src/polkavm/context/function/runtime/runtime_code.rs +++ b/crates/llvm-context/src/polkavm/context/function/runtime/runtime_code.rs @@ -62,6 +62,7 @@ where context.set_basic_block(context.current_function().borrow().entry_block()); context.set_code_type(CodeType::Runtime); if let Some(dinfo) = context.debug_info() { + let di_builder = dinfo.builder(); let line_num: u32 = 0; let column: u32 = 0; let func_name: &str = runtime::FUNCTION_RUNTIME_CODE; @@ -84,13 +85,30 @@ where false, Some(inkwell::debug_info::DIFlagsConstants::PUBLIC), )?; - dinfo.push_scope(di_func_scope.as_debug_info_scope()); + let _ = dinfo.push_scope(di_func_scope.as_debug_info_scope()); let func_value = context .current_function() .borrow() .declaration() .function_value(); let _ = func_value.set_subprogram(di_func_scope); + + let lexical_scope = di_builder.create_lexical_block( + di_func_scope.as_debug_info_scope(), + dinfo.compilation_unit().get_file(), + line_num, + column, + ).as_debug_info_scope(); + let _ = dinfo.push_scope(lexical_scope); + + let di_loc = di_builder.create_debug_location( + context.llvm(), + line_num, + 0, + lexical_scope, + None, + ); + context.builder().set_current_debug_location(di_loc) } self.inner.into_llvm(context)?; @@ -110,6 +128,7 @@ where if let Some(dinfo) = context.debug_info() { let _ = dinfo.pop_scope(); + let _ = dinfo.pop_scope(); } Ok(()) diff --git a/crates/solidity/src/yul/parser/statement/assignment.rs b/crates/solidity/src/yul/parser/statement/assignment.rs index de82a1ad..b02e7f0c 100644 --- a/crates/solidity/src/yul/parser/statement/assignment.rs +++ b/crates/solidity/src/yul/parser/statement/assignment.rs @@ -115,30 +115,28 @@ where mut self, context: &mut revive_llvm_context::PolkaVMContext, ) -> anyhow::Result<()> { + if let Some(dinfo) = context.debug_info() { + let di_parent_scope = dinfo + .top_scope() + .expect("expected a debug-info scope") + .clone(); + let line_num: u32 = std::cmp::min(self.location.line, u32::MAX as usize) as u32; + let di_loc = dinfo.builder().create_debug_location( + context.llvm(), + line_num, + 0, + di_parent_scope, + None, + ); + context.builder().set_current_debug_location(di_loc) + }; + let value = match self.initializer.into_llvm(context)? { Some(value) => value, None => return Ok(()), }; if self.bindings.len() == 1 { - if let Some(dinfo) = context.debug_info() { - let di_builder = dinfo.builder(); - let di_parent_scope = dinfo - .top_scope() - .expect("expected a debug-info scope") - .clone(); - let line_num: u32 = std::cmp::min(self.location.line, u32::MAX as usize) as u32; - - let di_loc = di_builder.create_debug_location( - context.llvm(), - line_num, - 0, - di_parent_scope, - None, - ); - context.builder().set_current_debug_location(di_loc) - }; - let identifier = self.bindings.remove(0); let pointer = context .current_function() @@ -162,14 +160,12 @@ where for (index, binding) in self.bindings.into_iter().enumerate() { if let Some(dinfo) = context.debug_info() { - let di_builder = dinfo.builder(); let di_parent_scope = dinfo .top_scope() .expect("expected a debug-info scope") .clone(); let line_num: u32 = std::cmp::min(self.location.line, u32::MAX as usize) as u32; - - let di_loc = di_builder.create_debug_location( + let di_loc = dinfo.builder().create_debug_location( context.llvm(), line_num, 0, diff --git a/crates/solidity/src/yul/parser/statement/block.rs b/crates/solidity/src/yul/parser/statement/block.rs index 86531614..42f97bff 100644 --- a/crates/solidity/src/yul/parser/statement/block.rs +++ b/crates/solidity/src/yul/parser/statement/block.rs @@ -138,6 +138,25 @@ where let current_function = context.current_function().borrow().name().to_owned(); let current_block = context.basic_block(); + let mut functions = Vec::with_capacity(self.statements.len()); + let mut local_statements = Vec::with_capacity(self.statements.len()); + + for statement in self.statements.into_iter() { + match statement { + Statement::FunctionDefinition(mut statement) => { + statement.declare(context)?; + functions.push(statement); + } + statement => local_statements.push(statement), + } + } + + for function in functions.into_iter() { + function.into_llvm(context)?; + } + + context.set_current_function(current_function.as_str())?; + if let Some(dinfo) = context.debug_info() { let di_builder = dinfo.builder(); let di_parent_scope = dinfo @@ -160,27 +179,24 @@ where context.builder().set_current_debug_location(di_loc); } - let mut functions = Vec::with_capacity(self.statements.len()); - let mut local_statements = Vec::with_capacity(self.statements.len()); - - for statement in self.statements.into_iter() { - match statement { - Statement::FunctionDefinition(mut statement) => { - statement.declare(context)?; - functions.push(statement); - } - statement => local_statements.push(statement), - } - } - - for function in functions.into_iter() { - function.into_llvm(context)?; - } - - context.set_current_function(current_function.as_str())?; context.set_basic_block(current_block); - for statement in local_statements.into_iter() { + if let Some(dinfo) = context.debug_info() { + let di_block_scope = dinfo + .top_scope() + .expect("expected a debug-info scope") + .clone(); + let line_num: u32 = + std::cmp::min(statement.location().line, u32::MAX as usize) as u32; + let di_loc = dinfo.builder().create_debug_location( + context.llvm(), + line_num, + 0, + di_block_scope, + None, + ); + context.builder().set_current_debug_location(di_loc); + } if context.basic_block().get_terminator().is_some() { break; } diff --git a/crates/solidity/src/yul/parser/statement/function_definition.rs b/crates/solidity/src/yul/parser/statement/function_definition.rs index 7ec0c82b..d032db11 100644 --- a/crates/solidity/src/yul/parser/statement/function_definition.rs +++ b/crates/solidity/src/yul/parser/statement/function_definition.rs @@ -267,45 +267,10 @@ where context: &mut revive_llvm_context::PolkaVMContext<'ctx, D>, ) -> anyhow::Result<()> { context.set_current_function(self.identifier.as_str())?; - let r#return = context.current_function().borrow().r#return(); - context.set_basic_block(context.current_function().borrow().entry_block()); - match r#return { - revive_llvm_context::PolkaVMFunctionReturn::None => {} - revive_llvm_context::PolkaVMFunctionReturn::Primitive { pointer } => { - let identifier = self.result.pop().expect("Always exists"); - - let r#type = identifier.r#type.unwrap_or_default(); - context.build_store(pointer, r#type.into_llvm(context).const_zero())?; - context - .current_function() - .borrow_mut() - .insert_stack_pointer(identifier.inner, pointer); - } - revive_llvm_context::PolkaVMFunctionReturn::Compound { pointer, .. } => { - for (index, identifier) in self.result.into_iter().enumerate() { - let r#type = identifier.r#type.unwrap_or_default().into_llvm(context); - let pointer = context.build_gep( - pointer, - &[ - context.word_const(0), - context - .integer_type(revive_common::BIT_LENGTH_X32) - .const_int(index as u64, false), - ], - context.word_type(), - format!("return_{index}_gep_pointer").as_str(), - ); - context.build_store(pointer, r#type.const_zero())?; - context - .current_function() - .borrow_mut() - .insert_stack_pointer(identifier.inner.clone(), pointer); - } - } - }; if let Some(dinfo) = context.debug_info() { + let di_builder = dinfo.builder(); let line_num: u32 = std::cmp::min(self.location.line, u32::MAX as usize) as u32; let column: u32 = std::cmp::min(self.location.column, u32::MAX as usize) as u32; let func_value = context @@ -338,8 +303,58 @@ where )?; dinfo.push_scope(di_func_scope.as_debug_info_scope()); let _ = func_value.set_subprogram(di_func_scope); + + let lexical_scope = di_builder + .create_lexical_block( + di_func_scope.as_debug_info_scope(), + dinfo.compilation_unit().get_file(), + line_num, + column, + ) + .as_debug_info_scope(); + let _ = dinfo.push_scope(lexical_scope); + + let di_loc = + di_builder.create_debug_location(context.llvm(), line_num, 0, lexical_scope, None); + context.builder().set_current_debug_location(di_loc) } + let r#return = context.current_function().borrow().r#return(); + match r#return { + revive_llvm_context::PolkaVMFunctionReturn::None => {} + revive_llvm_context::PolkaVMFunctionReturn::Primitive { pointer } => { + let identifier = self.result.pop().expect("Always exists"); + + let r#type = identifier.r#type.unwrap_or_default(); + context.build_store(pointer, r#type.into_llvm(context).const_zero())?; + context + .current_function() + .borrow_mut() + .insert_stack_pointer(identifier.inner, pointer); + } + revive_llvm_context::PolkaVMFunctionReturn::Compound { pointer, .. } => { + for (index, identifier) in self.result.into_iter().enumerate() { + let r#type = identifier.r#type.unwrap_or_default().into_llvm(context); + let pointer = context.build_gep( + pointer, + &[ + context.word_const(0), + context + .integer_type(revive_common::BIT_LENGTH_X32) + .const_int(index as u64, false), + ], + context.word_type(), + format!("return_{index}_gep_pointer").as_str(), + ); + context.build_store(pointer, r#type.const_zero())?; + context + .current_function() + .borrow_mut() + .insert_stack_pointer(identifier.inner.clone(), pointer); + } + } + }; + let argument_types: Vec<_> = self .arguments .iter() @@ -407,6 +422,7 @@ where if let Some(dinfo) = context.debug_info() { let _ = dinfo.pop_scope(); + let _ = dinfo.pop_scope(); } Ok(()) diff --git a/crates/solidity/src/yul/parser/statement/object.rs b/crates/solidity/src/yul/parser/statement/object.rs index 37dd73fe..42f0c734 100644 --- a/crates/solidity/src/yul/parser/statement/object.rs +++ b/crates/solidity/src/yul/parser/statement/object.rs @@ -226,14 +226,8 @@ where .expect("expected an existing debug-info scope") .clone(); let object_scope = di_builder.create_namespace(di_parent_scope, object_name, true); - let _ = context - .debug_info() - .unwrap() - .push_scope(object_scope.as_debug_info_scope()); - context - .debug_info() - .unwrap() - .push_namespace(object_name.to_string()) + let _ = dinfo.push_scope(object_scope.as_debug_info_scope()); + let _ = dinfo.push_namespace(object_name.to_string()); } if self.identifier.ends_with("_deployed") { @@ -249,10 +243,18 @@ where if let Some(dinfo) = context.debug_info() { let _ = dinfo.pop_namespace(); let _ = dinfo.pop_scope(); - dinfo.builder().finalize() + let _ = dinfo.builder().finalize(); + + context.module().verify().map_or_else( + |err| -> anyhow::Result<()> { + context.module().print_to_stderr(); + anyhow::bail!(err.to_string()) + }, + |_| -> anyhow::Result<()> { Ok(()) }, + ) + } else { + Ok(()) } - - Ok(()) } }