Implement variadic function calling
This commit is contained in:
parent
4bb8bfca94
commit
c68e76c33b
@ -338,6 +338,7 @@ pub mod libc {
|
||||
#[link(name = "c")]
|
||||
extern "C" {
|
||||
pub fn puts(s: *const u8);
|
||||
pub fn printf(format: *const char, ...) -> i32;
|
||||
pub fn malloc(size: usize) -> *mut u8;
|
||||
pub fn free(ptr: *mut u8);
|
||||
pub fn memcpy(dst: *mut u8, src: *const u8, size: usize);
|
||||
|
@ -121,6 +121,8 @@ fn main() {
|
||||
//return;
|
||||
|
||||
unsafe {
|
||||
printf("Hello %s\n\0" as *const str as *const char, "printf\0" as *const str as *const char);
|
||||
|
||||
let hello: &[u8] = b"Hello\0" as &[u8; 6];
|
||||
let ptr: *const u8 = hello as *const [u8] as *const u8;
|
||||
puts(ptr);
|
||||
|
24
src/abi.rs
24
src/abi.rs
@ -191,12 +191,13 @@ pub fn ty_fn_sig<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> ty::FnS
|
||||
pub fn get_function_name_and_sig<'a, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
inst: Instance<'tcx>,
|
||||
support_vararg: bool
|
||||
) -> (String, Signature) {
|
||||
assert!(!inst.substs.needs_infer() && !inst.substs.has_param_types());
|
||||
let fn_ty = inst.ty(tcx);
|
||||
let fn_sig = ty_fn_sig(tcx, fn_ty);
|
||||
if fn_sig.variadic {
|
||||
unimpl!("Variadic functions are not yet supported");
|
||||
if fn_sig.variadic && !support_vararg {
|
||||
unimpl!("Variadic function definitions are not yet supported");
|
||||
}
|
||||
let sig = clif_sig_from_fn_sig(tcx, fn_sig);
|
||||
(tcx.symbol_name(inst).as_str().to_string(), sig)
|
||||
@ -208,7 +209,7 @@ pub fn import_function<'a, 'tcx: 'a>(
|
||||
module: &mut Module<impl Backend>,
|
||||
inst: Instance<'tcx>,
|
||||
) -> FuncId {
|
||||
let (name, sig) = get_function_name_and_sig(tcx, inst);
|
||||
let (name, sig) = get_function_name_and_sig(tcx, inst, true);
|
||||
module
|
||||
.declare_function(&name, Linkage::Import, &sig)
|
||||
.unwrap()
|
||||
@ -659,6 +660,23 @@ pub fn codegen_call_inner<'a, 'tcx: 'a>(
|
||||
fx.bcx.ins().call(func_ref, &call_args)
|
||||
};
|
||||
|
||||
// FIXME find a cleaner way to support varargs
|
||||
if fn_sig.variadic {
|
||||
if fn_sig.abi != Abi::C {
|
||||
unimpl!("Variadic call for non-C abi {:?}", fn_sig.abi);
|
||||
}
|
||||
let sig_ref = fx.bcx.func.dfg.call_signature(call_inst).unwrap();
|
||||
let abi_params = call_args.into_iter().map(|arg| {
|
||||
let ty = fx.bcx.func.dfg.value_type(arg);
|
||||
if !ty.is_int() {
|
||||
// FIXME set %al to upperbound on float args once floats are supported
|
||||
unimpl!("Non int ty {:?} for variadic call", ty);
|
||||
}
|
||||
AbiParam::new(ty)
|
||||
}).collect::<Vec<AbiParam>>();
|
||||
fx.bcx.func.dfg.signatures[sig_ref].params = abi_params;
|
||||
}
|
||||
|
||||
match output_pass_mode {
|
||||
PassMode::NoPass => {}
|
||||
PassMode::ByVal(_) => {
|
||||
|
@ -65,7 +65,7 @@ fn trans_fn<'a, 'clif, 'tcx: 'a, B: Backend + 'static>(
|
||||
let mir = tcx.instance_mir(instance.def);
|
||||
|
||||
// Step 2. Declare function
|
||||
let (name, sig) = get_function_name_and_sig(tcx, instance);
|
||||
let (name, sig) = get_function_name_and_sig(tcx, instance, false);
|
||||
let func_id = cx.module
|
||||
.declare_function(&name, linkage, &sig)
|
||||
.unwrap();
|
||||
|
@ -53,8 +53,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx: 'a>(
|
||||
|
||||
let instance = Instance::mono(tcx, rust_main_def_id);
|
||||
|
||||
let (main_name, main_sig) = get_function_name_and_sig(tcx, instance);
|
||||
|
||||
let (main_name, main_sig) = get_function_name_and_sig(tcx, instance, false);
|
||||
let main_func_id = m
|
||||
.declare_function(&main_name, Linkage::Import, &main_sig)
|
||||
.unwrap();
|
||||
|
Loading…
x
Reference in New Issue
Block a user