wip: args and returns

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
This commit is contained in:
Cyrill Leutwiler
2025-07-03 10:08:26 +02:00
parent 63011b6d24
commit dfe56f9306
12 changed files with 201 additions and 29 deletions
@@ -298,11 +298,16 @@ impl<'ctx> Function<'ctx> {
*self.stack_slots.entry(name).or_insert_with(|| len)
}
/// References the stack variable `name`.
pub fn stack_variable_pointer<D: crate::PolkaVMDependency + Clone>(
&mut self,
name: String,
context: &mut super::Context<'ctx, D>,
) -> Pointer<'ctx> {
if let Some(pointer) = self.get_stack_pointer(&name) {
return pointer;
}
let pointer_name = format!("var_{}", &name);
let slot = self.stack_variable_slot(name);
Pointer::new(
@@ -1278,6 +1278,20 @@ where
where
T: BasicType<'ctx>,
{
let argument_types: Vec<inkwell::types::BasicMetadataTypeEnum> =
vec![self.llvm().ptr_type(Default::default()).into(); return_values_size]
.into_iter()
.chain(
argument_types
.as_slice()
.iter()
.map(T::as_basic_type_enum)
.map(inkwell::types::BasicMetadataTypeEnum::from),
)
.collect();
self.void_type().fn_type(&argument_types.as_slice(), false)
/*
let argument_types: Vec<inkwell::types::BasicMetadataTypeEnum> = argument_types
.as_slice()
.iter()
@@ -1294,6 +1308,7 @@ where
.structure_type(vec![self.word_type().as_basic_type_enum(); size].as_slice())
.fn_type(argument_types.as_slice(), false),
}
*/
}
/// Modifies the call site value, setting the default attributes.
+21 -3
View File
@@ -115,13 +115,29 @@ impl<D> revive_llvm_context::PolkaVMWriteLLVM<D> for Assignment
where
D: revive_llvm_context::PolkaVMDependency + Clone,
{
fn into_llvm(
fn into_llvm<'ctx>(
mut self,
context: &mut revive_llvm_context::PolkaVMContext<D>,
context: &mut revive_llvm_context::PolkaVMContext<'ctx, D>,
) -> anyhow::Result<()> {
context.set_debug_location(self.location.line, 0, None)?;
let value = match self.initializer.into_llvm(context)? {
let bindings: Vec<(String, revive_llvm_context::PolkaVMPointer<'ctx>)> = self
.bindings
.into_iter()
.map(|binding| {
(
binding.inner.clone(),
context
.current_function()
.borrow_mut()
.stack_variable_pointer(binding.inner, context),
)
})
.collect();
self.initializer.into_llvm(bindings.as_slice(), context)?;
/*
let value = match self.initializer.into_llvm(bindings.as_slice(), context)? {
Some(value) => value,
None => return Ok(()),
};
@@ -181,6 +197,8 @@ where
context.build_store(binding_pointer, value)?;
}
*/
Ok(())
}
}
+1 -1
View File
@@ -184,7 +184,7 @@ where
block.into_llvm(context)?;
}
Statement::Expression(expression) => {
expression.into_llvm(context)?;
expression.into_llvm(&[], context)?;
}
Statement::VariableDeclaration(statement) => statement.into_llvm(context)?,
Statement::Assignment(statement) => statement.into_llvm(context)?,
@@ -117,8 +117,9 @@ impl FunctionCall {
/// Converts the function call into an LLVM value.
pub fn into_llvm<'ctx, D>(
mut self,
bindings: &[(String, revive_llvm_context::PolkaVMPointer<'ctx>)],
context: &mut revive_llvm_context::PolkaVMContext<'ctx, D>,
) -> anyhow::Result<Option<inkwell::values::BasicValueEnum<'ctx>>>
) -> anyhow::Result<()>
where
D: revive_llvm_context::PolkaVMDependency + Clone,
{
@@ -126,15 +127,26 @@ impl FunctionCall {
match self.name {
Name::UserDefined(name) => {
let mut values = Vec::with_capacity(self.arguments.len());
for argument in self.arguments.into_iter().rev() {
let mut values = Vec::with_capacity(bindings.len() + self.arguments.len());
for (n, argument) in self.arguments.into_iter().rev().enumerate() {
let id = format!("arg_{n}");
let binding_pointer = context.build_alloca(context.word_type(), &id);
let value = argument
.into_llvm(context)?
.into_llvm(&[(id, binding_pointer)], context)?
.expect("Always exists")
.access(context)?;
.as_pointer(context)?
.value
.as_basic_value_enum();
values.push(value);
}
values.reverse();
let values = bindings
.into_iter()
.map(|(_, pointer)| pointer.value.as_basic_value_enum())
.chain(values.into_iter())
.collect::<Vec<_>>();
let function = context.get_function(name.as_str()).ok_or_else(|| {
anyhow::anyhow!("{} Undeclared function `{}`", location, name)
})?;
@@ -151,13 +163,13 @@ impl FunctionCall {
);
}
let return_value = context.build_call(
let _return_value = context.build_call(
function.borrow().declaration(),
values.as_slice(),
format!("{name}_call").as_str(),
);
Ok(return_value)
Ok(())
}
Name::Add => {
@@ -72,6 +72,7 @@ impl Literal {
/// Converts the literal into its LLVM.
pub fn into_llvm<'ctx, D>(
self,
binding: Option<(String, revive_llvm_context::PolkaVMPointer<'ctx>)>,
context: &revive_llvm_context::PolkaVMContext<'ctx, D>,
) -> anyhow::Result<revive_llvm_context::PolkaVMArgument<'ctx>>
where
@@ -97,7 +98,17 @@ impl Literal {
BooleanLiteral::True => num::BigUint::one(),
};
Ok(revive_llvm_context::PolkaVMArgument::value(value).with_constant(constant))
match binding {
Some((id, pointer)) => {
context.build_store(pointer, value)?;
Ok(revive_llvm_context::PolkaVMArgument::pointer(pointer, id)
.with_constant(constant))
}
None => {
Ok(revive_llvm_context::PolkaVMArgument::value(value)
.with_constant(constant))
}
}
}
LexicalLiteral::Integer(inner) => {
let r#type = self.yul_type.unwrap_or_default().into_llvm(context);
@@ -125,7 +136,17 @@ impl Literal {
}
.expect("Always valid");
Ok(revive_llvm_context::PolkaVMArgument::value(value).with_constant(constant))
match binding {
Some((id, pointer)) => {
context.build_store(pointer, value)?;
Ok(revive_llvm_context::PolkaVMArgument::pointer(pointer, id)
.with_constant(constant))
}
None => {
Ok(revive_llvm_context::PolkaVMArgument::value(value)
.with_constant(constant))
}
}
}
LexicalLiteral::String(inner) => {
let string = inner.inner;
@@ -216,7 +237,16 @@ impl Literal {
)
.expect("The value is valid")
.as_basic_value_enum();
Ok(revive_llvm_context::PolkaVMArgument::value(value).with_original(string))
match binding {
Some((id, pointer)) => {
context.build_store(pointer, value)?;
Ok(revive_llvm_context::PolkaVMArgument::pointer(pointer, id)
.with_original(string))
}
None => Ok(
revive_llvm_context::PolkaVMArgument::value(value).with_original(string)
),
}
}
}
}
@@ -100,7 +100,7 @@ impl Expression {
/// Converts the expression into an LLVM value.
pub fn into_llvm<'ctx, D>(
self,
//bindings: &[String],
bindings: &[(String, revive_llvm_context::PolkaVMPointer<'ctx>)],
context: &mut revive_llvm_context::PolkaVMContext<'ctx, D>,
) -> anyhow::Result<Option<revive_llvm_context::PolkaVMArgument<'ctx>>>
where
@@ -109,7 +109,13 @@ impl Expression {
match self {
Self::Literal(literal) => literal
.clone()
.into_llvm(context)
.into_llvm(
bindings
.first()
.to_owned()
.map(|(id, binding)| (id.to_string(), *binding)),
context,
)
.map_err(|error| {
anyhow::anyhow!(
"{} Invalid literal `{}`: {}",
@@ -139,9 +145,10 @@ impl Expression {
_ => argument,
}))
}
Self::FunctionCall(call) => Ok(call
.into_llvm(context)?
.map(revive_llvm_context::PolkaVMArgument::value)),
Self::FunctionCall(call) => {
call.into_llvm(bindings, context)?;
Ok(None)
}
}
}
}
+2 -1
View File
@@ -74,9 +74,10 @@ where
context.build_unconditional_branch(condition_block);
context.set_basic_block(condition_block);
let binding_pointer = context.build_alloca(context.word_type(), "if_condition");
let condition = self
.condition
.into_llvm(context)?
.into_llvm(&[("todo".to_string(), binding_pointer)], context)?
.expect("Always exists")
.access(context)?
.into_int_value();
@@ -231,8 +231,80 @@ where
context: &mut revive_llvm_context::PolkaVMContext<D>,
) -> anyhow::Result<()> {
context.set_current_function(self.identifier.as_str(), Some(self.location.line))?;
context.set_basic_block(context.current_function().borrow().entry_block());
let return_types: Vec<_> = self
.arguments
.iter()
.map(|argument| {
let yul_type = argument.r#type.to_owned().unwrap_or_default();
yul_type.into_llvm(context)
})
.collect();
for (index, argument) in self.result.iter().enumerate() {
let pointer = context
.current_function()
.borrow()
.get_nth_param(index)
.into_pointer_value();
let pointer = revive_llvm_context::PolkaVMPointer::new(
return_types[index],
Default::default(),
pointer,
);
context.build_store(pointer, pointer.r#type.const_zero())?;
context
.current_function()
.borrow_mut()
.insert_stack_pointer(argument.inner.clone(), pointer);
}
let argument_types: Vec<_> = self
.arguments
.iter()
.map(|argument| {
let yul_type = argument.r#type.to_owned().unwrap_or_default();
yul_type.into_llvm(context)
})
.collect();
for (index, argument) in self.arguments.iter().enumerate() {
let pointer = context
.current_function()
.borrow()
.get_nth_param(index + self.result.len())
.into_pointer_value();
let pointer = revive_llvm_context::PolkaVMPointer::new(
argument_types[index],
Default::default(),
pointer,
);
context
.current_function()
.borrow_mut()
.insert_stack_pointer(argument.inner.clone(), pointer);
}
self.body.into_llvm(context)?;
context.set_debug_location(self.location.line, 0, None)?;
match context
.basic_block()
.get_last_instruction()
.map(|instruction| instruction.get_opcode())
{
Some(inkwell::values::InstructionOpcode::Br) => {}
Some(inkwell::values::InstructionOpcode::Switch) => {}
_ => context
.build_unconditional_branch(context.current_function().borrow().return_block()),
}
context.set_basic_block(context.current_function().borrow().return_block());
context.build_return(None);
context.pop_debug_scope();
/*
let r#return = context.current_function().borrow().r#return();
match r#return {
revive_llvm_context::PolkaVMFunctionReturn::None => {}
@@ -319,6 +391,7 @@ where
}
context.pop_debug_scope();
*/
Ok(())
}
@@ -53,9 +53,10 @@ where
D: revive_llvm_context::PolkaVMDependency + Clone,
{
fn into_llvm(self, context: &mut revive_llvm_context::PolkaVMContext<D>) -> anyhow::Result<()> {
let binding_pointer = context.build_alloca(context.word_type(), "if_condition");
let condition = self
.condition
.into_llvm(context)?
.into_llvm(&[("todo".to_string(), binding_pointer)], context)?
.expect("Always exists")
.access(context)?
.into_int_value();
@@ -123,7 +123,7 @@ where
D: revive_llvm_context::PolkaVMDependency + Clone,
{
fn into_llvm(self, context: &mut revive_llvm_context::PolkaVMContext<D>) -> anyhow::Result<()> {
let scrutinee = self.expression.into_llvm(context)?;
let scrutinee = self.expression.into_llvm(&[], context)?;
if self.cases.is_empty() {
if let Some(block) = self.default {
@@ -137,7 +137,7 @@ where
let mut branches = Vec::with_capacity(self.cases.len());
for (index, case) in self.cases.into_iter().enumerate() {
let constant = case.literal.into_llvm(context)?.access(context)?;
let constant = case.literal.into_llvm(None, context)?.access(context)?;
let expression_block = context
.append_basic_block(format!("switch_case_branch_{}_block", index + 1).as_str());
@@ -99,16 +99,25 @@ where
mut self,
context: &mut revive_llvm_context::PolkaVMContext<'ctx, D>,
) -> anyhow::Result<()> {
let _pointers: Vec<revive_llvm_context::PolkaVMPointer<'ctx>> = self
let bindings: Vec<(String, revive_llvm_context::PolkaVMPointer<'ctx>)> = self
.bindings
.iter()
.into_iter()
.map(|binding| {
context
.current_function()
.borrow_mut()
.stack_variable_pointer(binding.inner.to_string(), context)
(
binding.inner.clone(),
context
.current_function()
.borrow_mut()
.stack_variable_pointer(binding.inner, context),
)
})
.collect();
if let Some(expression) = self.expression {
expression.into_llvm(&bindings, context)?;
}
/*
if self.bindings.len() == 1 {
let identifier = self.bindings.remove(0);
context.set_debug_location(self.location.line, 0, None)?;
@@ -223,6 +232,7 @@ where
})?;
context.build_store(pointer, value)?;
}
*/
Ok(())
}