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
Showing only changes of commit c7de22287e - Show all commits

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
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): 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