From a3719e08e532763d044848b6871ef3c960b7d3e3 Mon Sep 17 00:00:00 2001 From: Sergey Pepyakin Date: Tue, 11 Dec 2018 19:45:33 +0100 Subject: [PATCH] Pass arguments. --- src/backend.rs | 28 +++++++++++++++++++++++----- src/function_body.rs | 5 +---- src/tests.rs | 12 +++++++++--- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/backend.rs b/src/backend.rs index b3cf12a91b..dfcd301c32 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -81,6 +81,7 @@ impl Registers { } /// Describes location of a argument. +#[derive(Debug)] enum ArgLocation { /// Argument is passed via some register. Reg(GPR), @@ -336,6 +337,22 @@ pub fn copy_incoming_arg(ctx: &mut Context, arg_pos: u32) { ); } +pub fn pass_outgoing_args(ctx: &mut Context, arity: u32) { + for arg_pos in (0..arity).rev() { + ctx.sp_depth.free(1); + + let loc = abi_loc_for_arg(arg_pos); + match loc { + ArgLocation::Reg(gpr) => { + dynasm!(ctx.asm + ; pop Rq(gpr) + ); + } + _ => unimplemented!("don't know how to pass argument {} via {:?}", arg_pos, loc), + } + } +} + pub fn call_direct(ctx: &mut Context, index: u32) { let label = &ctx.func_starts[index as usize].1; dynasm!(ctx.asm @@ -358,11 +375,12 @@ pub fn prologue(ctx: &mut Context, stack_slots: u32) { } pub fn epilogue(ctx: &mut Context) { - assert_eq!( - ctx.sp_depth, - StackDepth(0), - "imbalanced pushes and pops detected" - ); + // TODO: This doesn't work with stack alignment. + // assert_eq!( + // ctx.sp_depth, + // StackDepth(0), + // "imbalanced pushes and pops detected" + // ); dynasm!(ctx.asm ; mov rsp, rbp ; pop rbp diff --git a/src/function_body.rs b/src/function_body.rs index 18733c644a..bffca70b98 100644 --- a/src/function_body.rs +++ b/src/function_body.rs @@ -219,15 +219,12 @@ pub fn translate( } Operator::Call { function_index } => { let callee_ty = translation_ctx.func_type(function_index); - assert!(callee_ty.params.len() == 0, "is not supported"); assert!(callee_ty.returns.len() == 0, "is not supported"); // TODO: ensure that this function is locally defined // We would like to support imported functions at some point - // TODO: pop arguments and move them in appropriate positions. - // only 6 for now. - + pass_outgoing_args(&mut ctx, callee_ty.params.len() as u32); call_direct(&mut ctx, function_index); } _ => { diff --git a/src/tests.rs b/src/tests.rs index 980d100bc4..d2e2effb78 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -111,16 +111,22 @@ fn function_call() { let code = r#" (module (func (param i32) (param i32) (result i32) - (call 1) + (call $assert_zero + (get_local 1) + ) (get_local 0) ) - (func + (func $assert_zero (param $v i32) + (local i32) + (if (get_local $v) + (unreachable) + ) ) ) "#; - assert_eq!(execute_wat(code, 2, 3), 2); + assert_eq!(execute_wat(code, 2, 0), 2); } // TODO: Add a test that checks argument passing via the stack.