mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-04-22 04:27:58 +00:00
wip: args and returns
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user