From cfb97b3393b5a6a43d81c5edbb8d7867ac1d7bf0 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Mon, 3 Jan 2011 22:39:43 -0800 Subject: Begin sketching translation of bind_expr. No captures yet, also crashy. --- src/comp/middle/trans.rs | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) (limited to 'src/comp') diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 4681b579..24d95d4e 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -193,6 +193,11 @@ fn T_fn(vec[TypeRef] inputs, TypeRef output) -> TypeRef { False); } +fn T_closure(TypeRef tfn) -> TypeRef { + ret T_struct(vec(tfn, + T_ptr(T_opaque()))); +} + fn T_ptr(TypeRef t) -> TypeRef { ret llvm.LLVMPointerType(t, 0u); } @@ -1932,12 +1937,42 @@ impure fn trans_args(@block_ctxt cx, option.t[ValueRef] llobj, ret tup(bcx, vs); } +impure fn trans_bind(@block_ctxt cx, @ast.expr f, + vec[option.t[@ast.expr]] args, + &ast.ann ann) -> result { + auto f_res = trans_lval(cx, f); + auto bcx = f_res.res.bcx; + auto pair_t = T_closure(node_type(cx.fcx.ccx, ann)); + auto pair_v = bcx.build.Alloca(pair_t); + if (f_res.is_mem) { + cx.fcx.ccx.sess.unimpl("re-binding existing function"); + } else { + auto code_cell = + bcx.build.GEP(pair_v, vec(C_int(0), + C_int(abi.fn_field_code))); + bcx.build.Store(f_res.res.val, code_cell); + } + ret res(bcx, pair_v); +} + impure fn trans_call(@block_ctxt cx, @ast.expr f, vec[@ast.expr] args, &ast.ann ann) -> result { auto f_res = trans_lval(cx, f); auto faddr = f_res.res.val; if (f_res.is_mem) { - faddr = f_res.res.bcx.build.Load(faddr); + alt (f_res.llobj) { + case (some[ValueRef](_)) { + // It's a vtbl entry. + faddr = f_res.res.bcx.build.Load(faddr); + } + case (none[ValueRef]) { + // It's a closure. + auto bcx = f_res.res.bcx; + faddr = bcx.build.GEP(faddr, vec(C_int(0), + C_int(abi.fn_field_code))); + faddr = bcx.build.Load(faddr); + } + } } auto fn_ty = ty.expr_ty(f); auto ret_ty = ty.ann_to_type(ann); @@ -2110,6 +2145,10 @@ impure fn trans_expr(@block_ctxt cx, @ast.expr e) -> result { ret copy_ty(rhs_res.bcx, false, lhs_res.res.val, v, t); } + case (ast.expr_bind(?f, ?args, ?ann)) { + ret trans_bind(cx, f, args, ann); + } + case (ast.expr_call(?f, ?args, ?ann)) { ret trans_call(cx, f, args, ann); } -- cgit v1.2.3