Fix restoration of stack address after invoking function with struct-typed arguments #333

Merged
sb10q merged 1 commits from issue-233 into master 2024-08-17 17:37:20 +08:00
5 changed files with 32 additions and 5 deletions

View File

@ -385,7 +385,7 @@ fn rpc_codegen_callback_fn<'ctx, 'a>(
} }
for (i, arg) in real_params.iter().enumerate() { for (i, arg) in real_params.iter().enumerate() {
let arg_slot = ctx.builder.build_alloca(arg.get_type(), &format!("rpc.arg{}", i)); let arg_slot = generator.gen_var_alloc(ctx, arg.get_type(), Some(&format!("rpc.arg{i}"))).unwrap();
ctx.builder.build_store(arg_slot, *arg); ctx.builder.build_store(arg_slot, *arg);
let arg_slot = ctx.builder.build_bitcast(arg_slot, ptr_type, "rpc.arg"); let arg_slot = ctx.builder.build_bitcast(arg_slot, ptr_type, "rpc.arg");
let arg_ptr = unsafe { let arg_ptr = unsafe {

View File

@ -6,7 +6,7 @@ use crate::{
get_llvm_type, get_llvm_type,
get_llvm_abi_type, get_llvm_abi_type,
irrt::*, irrt::*,
stmt::gen_raise, stmt::{gen_raise, gen_var},
CodeGenContext, CodeGenTask, CodeGenContext, CodeGenTask,
}, },
symbol_resolver::{SymbolValue, ValueEnum}, symbol_resolver::{SymbolValue, ValueEnum},
@ -357,13 +357,14 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
} }
pub fn build_call_or_invoke( pub fn build_call_or_invoke(
&self, &mut self,
fun: FunctionValue<'ctx>, fun: FunctionValue<'ctx>,
params: &[BasicValueEnum<'ctx>], params: &[BasicValueEnum<'ctx>],
call_name: &str, call_name: &str,
) -> Option<BasicValueEnum<'ctx>> { ) -> Option<BasicValueEnum<'ctx>> {
let mut loc_params: Vec<BasicValueEnum<'ctx>> = Vec::new(); let mut loc_params: Vec<BasicValueEnum<'ctx>> = Vec::new();
let mut return_slot = None; let mut return_slot = None;
if fun.count_params() > 0 { if fun.count_params() > 0 {
let sret_id = Attribute::get_named_enum_kind_id("sret"); let sret_id = Attribute::get_named_enum_kind_id("sret");
let byref_id = Attribute::get_named_enum_kind_id("byref"); let byref_id = Attribute::get_named_enum_kind_id("byref");
@ -384,7 +385,7 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
if loc_params.is_empty() { if loc_params.is_empty() {
loc_params.extend(params[0..i+offset].iter().copied()); loc_params.extend(params[0..i+offset].iter().copied());
} }
let slot = self.builder.build_alloca(param.get_type(), call_name); let slot = gen_var(self, param.get_type(), Some(call_name)).unwrap();
loc_params.push(slot.into()); loc_params.push(slot.into());
self.builder.build_store(slot, *param); self.builder.build_store(slot, *param);
} else if !loc_params.is_empty() { } else if !loc_params.is_empty() {
@ -451,7 +452,7 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
) { ) {
let ty = self.get_llvm_type(generator, self.primitives.exception).into_pointer_type(); let ty = self.get_llvm_type(generator, self.primitives.exception).into_pointer_type();
let zelf_ty: BasicTypeEnum = ty.get_element_type().into_struct_type().into(); let zelf_ty: BasicTypeEnum = ty.get_element_type().into_struct_type().into();
let zelf = self.builder.build_alloca(zelf_ty, "alloca"); let zelf = generator.gen_var_alloc(self, zelf_ty, Some("exn")).unwrap();
let int32 = self.ctx.i32_type(); let int32 = self.ctx.i32_type();
let zero = int32.const_zero(); let zero = int32.const_zero();
unsafe { unsafe {

View File

@ -74,6 +74,12 @@ void output_str(struct cslice *slice) {
putchar('\n'); putchar('\n');
} }
uint64_t dbg_stack_address(__attribute__((unused)) struct cslice *slice) {
int i;
void *ptr = (void *) &i;
return (uintptr_t) ptr;
}
uint32_t __nac3_personality(uint32_t state, uint32_t exception_object, uint32_t context) { uint32_t __nac3_personality(uint32_t state, uint32_t exception_object, uint32_t context) {
printf("__nac3_personality(state: %u, exception_object: %u, context: %u\n", state, exception_object, context); printf("__nac3_personality(state: %u, exception_object: %u, context: %u\n", state, exception_object, context);
exit(101); exit(101);

View File

@ -51,6 +51,9 @@ def patch(module):
def output_float(x): def output_float(x):
print("%f" % x) print("%f" % x)
def dbg_stack_address(_):
return 0
def extern(fun): def extern(fun):
name = fun.__name__ name = fun.__name__
if name == "output_asciiart": if name == "output_asciiart":
@ -67,6 +70,8 @@ def patch(module):
"output_str", "output_str",
}: }:
return print return print
elif name == "dbg_stack_address":
return dbg_stack_address
else: else:
raise NotImplementedError raise NotImplementedError

View File

@ -0,0 +1,15 @@
@extern
def output_bool(x: bool):
...
@extern
def dbg_stack_address(x: str) -> uint64:
...
def run() -> int32:
a = dbg_stack_address("a")
b = dbg_stack_address("b")
output_bool(a == b)
return 0