Fix restoration of stack address after invoking function with struct-typed arguments #333
|
@ -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 {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue