Fix DynFunctionCall and Function instructions

This commit is contained in:
Sofia 2026-02-23 19:03:18 +02:00
parent 17545baa50
commit c96a433ce5
3 changed files with 20 additions and 8 deletions

View File

@ -708,9 +708,12 @@ impl Builder {
} }
Instr::Function(_) => Ok(()), Instr::Function(_) => Ok(()),
Instr::DynFunctionCall(instr, _) => { Instr::DynFunctionCall(instr, _) => {
let fn_ty = instr.get_type(&self)?; let ptr = instr.get_type(&self)?;
let Type::Function(..) = fn_ty else { let Type::Ptr(fn_ty) = ptr else {
return Err(ErrorKind::NotPointer(instr, fn_ty)); return Err(ErrorKind::NotPointer(instr, ptr));
};
let Type::Function(..) = *fn_ty else {
return Err(ErrorKind::NotFunction(instr, *fn_ty));
}; };
Ok(()) Ok(())
} }
@ -880,11 +883,15 @@ impl InstructionValue {
IsNull(_) => Ok(Type::Bool), IsNull(_) => Ok(Type::Bool),
Function(fun) => { Function(fun) => {
let data = builder.function_data(fun); let data = builder.function_data(fun);
Ok(Type::Function(data.params, Box::new(data.ret))) Ok(Type::Ptr(Box::new(Type::Function(
data.params,
Box::new(data.ret),
))))
} }
DynFunctionCall(instr, _) => { DynFunctionCall(instr, _) => {
let fn_ty = instr.get_type(builder)?; let ptr_ty = instr.get_type(builder)?;
let Type::Function(_, ret_ty) = fn_ty else { let Type::Ptr(fn_ty) = ptr_ty else { panic!() };
let Type::Function(_, ret_ty) = *fn_ty else {
panic!() panic!()
}; };
Ok(*ret_ty) Ok(*ret_ty)

View File

@ -1118,8 +1118,11 @@ impl InstructionHolder {
Function(function_value) => module.functions.get(function_value).unwrap().value_ref, Function(function_value) => module.functions.get(function_value).unwrap().value_ref,
DynFunctionCall(function_value, instruction_values) => { DynFunctionCall(function_value, instruction_values) => {
let fun = module.values.get(&*function_value).unwrap(); let fun = module.values.get(&*function_value).unwrap();
let Type::Ptr(fn_ty) = &fun.ty else { panic!() };
let ret_ty = let ret_ty =
LLVMGetReturnType(fun.ty.as_llvm(module.context_ref, &module.types)); LLVMGetReturnType(fn_ty.as_llvm(module.context_ref, &module.types));
let mut param_list: Vec<LLVMValueRef> = instruction_values let mut param_list: Vec<LLVMValueRef> = instruction_values
.iter() .iter()
@ -1132,7 +1135,7 @@ impl InstructionHolder {
} }
let value = LLVMBuildCall2( let value = LLVMBuildCall2(
module.builder_ref, module.builder_ref,
fun.ty.as_llvm(module.context_ref, &module.types), fn_ty.as_llvm(module.context_ref, &module.types),
fun.value_ref, fun.value_ref,
param_list.as_mut_ptr(), param_list.as_mut_ptr(),
param_list.len() as u32, param_list.len() as u32,

View File

@ -50,6 +50,8 @@ pub enum ErrorKind {
NotPointer(InstructionValue, Type), NotPointer(InstructionValue, Type),
#[error("Value {0:?} is not a struct, is {1:?}")] #[error("Value {0:?} is not a struct, is {1:?}")]
NotStruct(InstructionValue, Type), NotStruct(InstructionValue, Type),
#[error("Value {0:?} is not a function, is {1:?}")]
NotFunction(InstructionValue, Type),
#[error("Struct {0:?} has no such field as {1:?}")] #[error("Struct {0:?} has no such field as {1:?}")]
NoSuchField(Type, u32), NoSuchField(Type, u32),
#[error("Function {0:?} has no such parameter as {1:?}")] #[error("Function {0:?} has no such parameter as {1:?}")]