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() {
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);
let arg_slot = ctx.builder.build_bitcast(arg_slot, ptr_type, "rpc.arg");
let arg_ptr = unsafe {

View File

@ -6,7 +6,7 @@ use crate::{
get_llvm_type,
get_llvm_abi_type,
irrt::*,
stmt::gen_raise,
stmt::{gen_raise, gen_var},
CodeGenContext, CodeGenTask,
},
symbol_resolver::{SymbolValue, ValueEnum},
@ -357,13 +357,14 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
}
pub fn build_call_or_invoke(
&self,
&mut self,
fun: FunctionValue<'ctx>,
params: &[BasicValueEnum<'ctx>],
call_name: &str,
) -> Option<BasicValueEnum<'ctx>> {
let mut loc_params: Vec<BasicValueEnum<'ctx>> = Vec::new();
let mut return_slot = None;
if fun.count_params() > 0 {
let sret_id = Attribute::get_named_enum_kind_id("sret");
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() {
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());
self.builder.build_store(slot, *param);
} 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 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 zero = int32.const_zero();
unsafe {

View File

@ -74,6 +74,12 @@ void output_str(struct cslice *slice) {
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) {
printf("__nac3_personality(state: %u, exception_object: %u, context: %u\n", state, exception_object, context);
exit(101);

View File

@ -51,6 +51,9 @@ def patch(module):
def output_float(x):
print("%f" % x)
def dbg_stack_address(_):
return 0
Outdated
Review

This expression with id doesn't make sense. Just exclude this test from the interpreter runs, or just return 0.

This expression with id doesn't make sense. Just exclude this test from the interpreter runs, or just return 0.
def extern(fun):
name = fun.__name__
if name == "output_asciiart":
@ -67,6 +70,8 @@ def patch(module):
"output_str",
}:
return print
elif name == "dbg_stack_address":
return dbg_stack_address
else:
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