diff options
| author | Lindsey Kuper <[email protected]> | 2011-03-31 11:26:25 -0700 |
|---|---|---|
| committer | Graydon Hoare <[email protected]> | 2011-03-31 14:16:02 -0700 |
| commit | ef0c903f6a25cd9d8c900fbde336d4a4a5b43c56 (patch) | |
| tree | 7401bc79f12a909f271caaed8d29b8913493f4c6 /src | |
| parent | More machinery for adding an expr_call_self AST node. (diff) | |
| download | rust-ef0c903f6a25cd9d8c900fbde336d4a4a5b43c56.tar.xz rust-ef0c903f6a25cd9d8c900fbde336d4a4a5b43c56.zip | |
More stuff to go with the new expr_call_self AST node
Diffstat (limited to 'src')
| -rw-r--r-- | src/comp/middle/trans.rs | 68 | ||||
| -rw-r--r-- | src/comp/pretty/pprust.rs | 7 |
2 files changed, 75 insertions, 0 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index ceb15f71..38aff67b 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -4444,6 +4444,70 @@ fn trans_call(@block_ctxt cx, @ast.expr f, ret res(bcx, retval); } +fn trans_call_self(@block_ctxt cx, @ast.expr f, + option.t[ValueRef] lliterbody, + vec[@ast.expr] args, + &ast.ann ann) -> result { + log "translating a self-call"; + + auto f_res = trans_lval(cx, f); + auto faddr = f_res.res.val; + auto llenv = C_null(T_opaque_closure_ptr(cx.fcx.ccx.tn)); + + 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; + auto pair = faddr; + faddr = bcx.build.GEP(pair, vec(C_int(0), + C_int(abi.fn_field_code))); + faddr = bcx.build.Load(faddr); + + auto llclosure = bcx.build.GEP(pair, + vec(C_int(0), + C_int(abi.fn_field_box))); + llenv = bcx.build.Load(llclosure); + } + } + auto fn_ty = ty.expr_ty(f); + auto ret_ty = ty.ann_to_type(ann); + auto args_res = trans_args(f_res.res.bcx, + llenv, f_res.llobj, + f_res.generic, + lliterbody, + args, fn_ty); + + auto bcx = args_res._0; + auto llargs = args_res._1; + auto llretslot = args_res._2; + + /* + log "calling: " + val_str(cx.fcx.ccx.tn, faddr); + + for (ValueRef arg in llargs) { + log "arg: " + val_str(cx.fcx.ccx.tn, arg); + } + */ + + bcx.build.FastCall(faddr, llargs); + auto retval = C_nil(); + + if (!ty.type_is_nil(ret_ty)) { + retval = load_scalar_or_boxed(bcx, llretslot, ret_ty); + // Retval doesn't correspond to anything really tangible in the frame, + // but it's a ref all the same, so we put a note here to drop it when + // we're done in this scope. + find_scope_cx(cx).cleanups += + vec(clean(bind drop_ty(_, retval, ret_ty))); + } + + ret res(bcx, retval); +} + fn trans_tup(@block_ctxt cx, vec[ast.elt] elts, &ast.ann ann) -> result { auto bcx = cx; @@ -4680,6 +4744,10 @@ fn trans_expr(@block_ctxt cx, @ast.expr e) -> result { ret trans_call(cx, f, none[ValueRef], args, ann); } + case (ast.expr_call_self(?f, ?args, ?ann)) { + ret trans_call_self(cx, f, none[ValueRef], args, ann); + } + case (ast.expr_cast(?e, _, ?ann)) { ret trans_cast(cx, e, ann); } diff --git a/src/comp/pretty/pprust.rs b/src/comp/pretty/pprust.rs index 0007cfd5..2d17696b 100644 --- a/src/comp/pretty/pprust.rs +++ b/src/comp/pretty/pprust.rs @@ -431,6 +431,13 @@ impure fn print_expr(ps s, &@ast.expr expr) { commasep_exprs(s, args); pclose(s); } + case (ast.expr_call_self(?func,?args,_)) { + wrd(s.s, "self."); + print_expr(s, func); + popen(s); + commasep_exprs(s, args); + pclose(s); + } case (ast.expr_bind(?func,?args,_)) { impure fn print_opt(ps s, &option.t[@ast.expr] expr) { alt (expr) { |