aboutsummaryrefslogtreecommitdiff
path: root/src/comp
diff options
context:
space:
mode:
authorGraydon Hoare <[email protected]>2011-01-03 22:39:43 -0800
committerGraydon Hoare <[email protected]>2011-01-03 22:39:43 -0800
commitcfb97b3393b5a6a43d81c5edbb8d7867ac1d7bf0 (patch)
tree91a87865e65419fd2341dfe7f6010d901e4500e4 /src/comp
parentSplit driver between parsing source files and crate files, by extension. Add ... (diff)
downloadrust-cfb97b3393b5a6a43d81c5edbb8d7867ac1d7bf0.tar.xz
rust-cfb97b3393b5a6a43d81c5edbb8d7867ac1d7bf0.zip
Begin sketching translation of bind_expr. No captures yet, also crashy.
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/middle/trans.rs41
1 files changed, 40 insertions, 1 deletions
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);
}