Prevent frontend function confusion (#383)

Function symbols can clash as we compile multiple YUL `object`
definition into the same `LLVM` module.
- Disambiguate via unique function symbols based its location (runtime
or deploy code).
- Use `LinkOnceODR` linkage for compiler builtin helpers.

---------

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
This commit is contained in:
xermicus
2025-09-29 23:05:57 +02:00
committed by GitHub
parent 6858cb9a61
commit b560d72139
12 changed files with 103 additions and 58 deletions
+1
View File
@@ -159,6 +159,7 @@ impl PolkaVMWriteLLVM for Block {
context.set_current_function(
current_function.as_str(),
Some((self.location.line, self.location.column)),
false,
)?;
if let Some(debug_info) = context.debug_info() {
@@ -135,7 +135,7 @@ impl FunctionCall {
values.push(value);
}
values.reverse();
let function = context.get_function(name.as_str()).ok_or_else(|| {
let function = context.get_function(name.as_str(), true).ok_or_else(|| {
anyhow::anyhow!("{} Undeclared function `{}`", location, name)
})?;
@@ -215,8 +215,9 @@ impl PolkaVMWriteLLVM for FunctionDefinition {
self.identifier.as_str(),
function_type,
self.result.len(),
Some(inkwell::module::Linkage::Private),
Some(inkwell::module::Linkage::External),
Some((self.location.line, self.location.column)),
true,
)?;
PolkaVMFunction::set_attributes(
context.llvm(),
@@ -235,6 +236,7 @@ impl PolkaVMWriteLLVM for FunctionDefinition {
context.set_current_function(
self.identifier.as_str(),
Some((self.location.line, self.location.column)),
true,
)?;
context.set_basic_block(context.current_function().borrow().entry_block());
+37 -29
View File
@@ -4,6 +4,7 @@ use std::collections::BTreeSet;
use std::collections::HashSet;
use inkwell::debug_info::AsDIScope;
use revive_llvm_context::PolkaVMCodeType;
use serde::Deserialize;
use serde::Serialize;
@@ -184,6 +185,12 @@ impl Object {
impl PolkaVMWriteLLVM for Object {
fn declare(&mut self, context: &mut PolkaVMContext) -> anyhow::Result<()> {
if self.identifier.ends_with("_deployed") {
context.set_code_type(PolkaVMCodeType::Runtime);
} else {
context.set_code_type(PolkaVMCodeType::Deploy);
}
revive_llvm_context::PolkaVMLoadImmutableDataFunction.declare(context)?;
revive_llvm_context::PolkaVMStoreImmutableDataFunction.declare(context)?;
@@ -230,40 +237,12 @@ impl PolkaVMWriteLLVM for Object {
.into_iter()
{
context
.get_function(name)
.get_function(name, false)
.expect("Always exists")
.borrow_mut()
.set_yul_data(revive_llvm_context::PolkaVMFunctionYulData::default());
}
entry.into_llvm(context)?;
revive_llvm_context::PolkaVMLoadImmutableDataFunction.into_llvm(context)?;
revive_llvm_context::PolkaVMStoreImmutableDataFunction.into_llvm(context)?;
revive_llvm_context::PolkaVMLoadHeapWordFunction.into_llvm(context)?;
revive_llvm_context::PolkaVMStoreHeapWordFunction.into_llvm(context)?;
revive_llvm_context::PolkaVMLoadStorageWordFunction.into_llvm(context)?;
revive_llvm_context::PolkaVMStoreStorageWordFunction.into_llvm(context)?;
revive_llvm_context::PolkaVMLoadTransientStorageWordFunction.into_llvm(context)?;
revive_llvm_context::PolkaVMStoreTransientStorageWordFunction.into_llvm(context)?;
revive_llvm_context::PolkaVMWordToPointerFunction.into_llvm(context)?;
revive_llvm_context::PolkaVMExitFunction.into_llvm(context)?;
revive_llvm_context::PolkaVMEventLogFunction::<0>.into_llvm(context)?;
revive_llvm_context::PolkaVMEventLogFunction::<1>.into_llvm(context)?;
revive_llvm_context::PolkaVMEventLogFunction::<2>.into_llvm(context)?;
revive_llvm_context::PolkaVMEventLogFunction::<3>.into_llvm(context)?;
revive_llvm_context::PolkaVMEventLogFunction::<4>.into_llvm(context)?;
revive_llvm_context::PolkaVMDivisionFunction.into_llvm(context)?;
revive_llvm_context::PolkaVMSignedDivisionFunction.into_llvm(context)?;
revive_llvm_context::PolkaVMRemainderFunction.into_llvm(context)?;
revive_llvm_context::PolkaVMSignedRemainderFunction.into_llvm(context)?;
revive_llvm_context::PolkaVMSbrkFunction.into_llvm(context)?;
Ok(())
}
@@ -280,8 +259,37 @@ impl PolkaVMWriteLLVM for Object {
context.set_debug_location(self.location.line, self.location.column, None)?;
if self.identifier.ends_with("_deployed") {
context.set_code_type(PolkaVMCodeType::Runtime);
revive_llvm_context::PolkaVMRuntimeCodeFunction::new(self.code).into_llvm(context)?;
} else {
context.set_code_type(PolkaVMCodeType::Deploy);
revive_llvm_context::PolkaVMEntryFunction::default().into_llvm(context)?;
revive_llvm_context::PolkaVMLoadImmutableDataFunction.into_llvm(context)?;
revive_llvm_context::PolkaVMStoreImmutableDataFunction.into_llvm(context)?;
revive_llvm_context::PolkaVMLoadHeapWordFunction.into_llvm(context)?;
revive_llvm_context::PolkaVMStoreHeapWordFunction.into_llvm(context)?;
revive_llvm_context::PolkaVMLoadStorageWordFunction.into_llvm(context)?;
revive_llvm_context::PolkaVMStoreStorageWordFunction.into_llvm(context)?;
revive_llvm_context::PolkaVMLoadTransientStorageWordFunction.into_llvm(context)?;
revive_llvm_context::PolkaVMStoreTransientStorageWordFunction.into_llvm(context)?;
revive_llvm_context::PolkaVMWordToPointerFunction.into_llvm(context)?;
revive_llvm_context::PolkaVMExitFunction.into_llvm(context)?;
revive_llvm_context::PolkaVMEventLogFunction::<0>.into_llvm(context)?;
revive_llvm_context::PolkaVMEventLogFunction::<1>.into_llvm(context)?;
revive_llvm_context::PolkaVMEventLogFunction::<2>.into_llvm(context)?;
revive_llvm_context::PolkaVMEventLogFunction::<3>.into_llvm(context)?;
revive_llvm_context::PolkaVMEventLogFunction::<4>.into_llvm(context)?;
revive_llvm_context::PolkaVMDivisionFunction.into_llvm(context)?;
revive_llvm_context::PolkaVMSignedDivisionFunction.into_llvm(context)?;
revive_llvm_context::PolkaVMRemainderFunction.into_llvm(context)?;
revive_llvm_context::PolkaVMSignedRemainderFunction.into_llvm(context)?;
revive_llvm_context::PolkaVMSbrkFunction.into_llvm(context)?;
revive_llvm_context::PolkaVMDeployCodeFunction::new(self.code).into_llvm(context)?;
}