Skip to content

Commit 3f4e33b

Browse files
committed
---
yaml --- r: 1398 b: refs/heads/master c: 79d3cea h: refs/heads/master v: v3
1 parent ac30d48 commit 3f4e33b

File tree

2 files changed

+117
-8
lines changed

2 files changed

+117
-8
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: e867d8ea993945803d96396bcba9c07d61d7c95d
2+
refs/heads/master: 79d3ceaac0b4a6ca83f0ff7b8b533649fc5165a1

trunk/src/comp/middle/trans.rs

Lines changed: 116 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ state type fn_ctxt = rec(ValueRef llfn,
8888
ValueRef llenv,
8989
ValueRef llretptr,
9090
mutable option.t[ValueRef] llself,
91+
mutable option.t[ValueRef] lliterbody,
9192
hashmap[ast.def_id, ValueRef] llargs,
9293
hashmap[ast.def_id, ValueRef] llobjfields,
9394
hashmap[ast.def_id, ValueRef] lllocals,
@@ -399,6 +400,8 @@ fn type_of_explicit_args(@crate_ctxt cx,
399400
// - trans_args
400401

401402
fn type_of_fn_full(@crate_ctxt cx,
403+
// FIXME: change bool flag to tag
404+
bool is_iter,
402405
option.t[TypeRef] obj_self,
403406
vec[ty.arg] inputs,
404407
@ty.t output) -> TypeRef {
@@ -436,14 +439,26 @@ fn type_of_fn_full(@crate_ctxt cx,
436439
}
437440
}
438441

442+
if (is_iter) {
443+
// If it's an iter, the 'output' type of the iter is actually the
444+
// *input* type of the function we're given as our iter-block
445+
// argument.
446+
atys += T_fn_pair(type_of_fn_full(cx, false, none[TypeRef],
447+
vec(rec(mode=ast.val, ty=output)),
448+
plain_ty(ty.ty_nil)));
449+
}
450+
439451
// ... then explicit args.
440452
atys += type_of_explicit_args(cx, inputs);
441453

442454
ret T_fn(atys, llvm.LLVMVoidType());
443455
}
444456

445-
fn type_of_fn(@crate_ctxt cx, vec[ty.arg] inputs, @ty.t output) -> TypeRef {
446-
ret type_of_fn_full(cx, none[TypeRef], inputs, output);
457+
fn type_of_fn(@crate_ctxt cx,
458+
// FIXME: change bool flag to tag
459+
bool is_iter,
460+
vec[ty.arg] inputs, @ty.t output) -> TypeRef {
461+
ret type_of_fn_full(cx, is_iter, none[TypeRef], inputs, output);
447462
}
448463

449464
fn type_of_native_fn(@crate_ctxt cx, vec[ty.arg] inputs,
@@ -499,7 +514,8 @@ fn type_of_inner(@crate_ctxt cx, @ty.t t) -> TypeRef {
499514
ret T_struct(tys);
500515
}
501516
case (ty.ty_fn(?args, ?out)) {
502-
ret T_fn_pair(type_of_fn(cx, args, out));
517+
// FIXME: put iter in ty_fn.
518+
ret T_fn_pair(type_of_fn(cx, false, args, out));
503519
}
504520
case (ty.ty_native_fn(?args, ?out)) {
505521
ret T_fn_pair(type_of_native_fn(cx, args, out));
@@ -512,6 +528,8 @@ fn type_of_inner(@crate_ctxt cx, @ty.t t) -> TypeRef {
512528
for (ty.method m in meths) {
513529
let TypeRef mty =
514530
type_of_fn_full(cx,
531+
// FIXME: support method iters
532+
false,
515533
some[TypeRef](self_ty),
516534
m.inputs, m.output);
517535
mtys += T_ptr(mty);
@@ -2141,7 +2159,83 @@ fn trans_for_each(@block_ctxt cx,
21412159
@ast.decl decl,
21422160
@ast.expr seq,
21432161
&ast.block body) -> result {
2144-
cx.fcx.ccx.sess.unimpl("for each loop");
2162+
2163+
/*
2164+
* The translation is a little .. complex here. Code like:
2165+
*
2166+
* let ty1 p = ...;
2167+
*
2168+
* let ty1 q = ...;
2169+
*
2170+
* foreach (ty v in foo(a,b)) { body(p,q,v) }
2171+
*
2172+
*
2173+
* Turns into a something like so (C/Rust mishmash):
2174+
*
2175+
* type env = { *ty1 p, *ty2 q, ... };
2176+
*
2177+
* let env e = { &p, &q, ... };
2178+
*
2179+
* fn foreach123_body(env* e, ty v) { body(*(e->p),*(e->q),v) }
2180+
*
2181+
* foo([foreach123_body, env*], a, b);
2182+
*
2183+
*/
2184+
2185+
// Step 1: walk body and figure out which references it makes
2186+
// escape. This could be determined upstream, and probably ought
2187+
// to be so, eventualy. For first cut, skip this. Null env.
2188+
2189+
auto env_ty = T_struct(vec(T_ptr(T_i8())));
2190+
2191+
2192+
// Step 2: Declare foreach body function.
2193+
2194+
// FIXME: possibly support alias-mode here?
2195+
auto decl_ty = plain_ty(ty.ty_nil);
2196+
alt (decl.node) {
2197+
case (ast.decl_local(?local)) {
2198+
decl_ty = node_ann_type(cx.fcx.ccx, local.ann);
2199+
}
2200+
}
2201+
2202+
let str s =
2203+
cx.fcx.ccx.names.next("_rust_foreach")
2204+
+ sep() + cx.fcx.ccx.path;
2205+
2206+
// The 'env' arg entering the body function is a fake env member (as in
2207+
// the env-part of the normal rust calling convention) that actually
2208+
// points to a stack allocated env in this frame. We bundle that env
2209+
// pointer along with the foreach-body-fn pointer into a 'normal' fn pair
2210+
// and pass it in as a first class fn-arg to the iterator.
2211+
2212+
auto foreach_llty = type_of_fn_full(cx.fcx.ccx, false, none[TypeRef],
2213+
vec(rec(mode=ast.val, ty=decl_ty)),
2214+
plain_ty(ty.ty_nil));
2215+
2216+
let ValueRef llforeach = decl_fastcall_fn(cx.fcx.ccx.llmod,
2217+
s, foreach_llty);
2218+
2219+
// FIXME: handle ty params properly.
2220+
let vec[ast.ty_param] ty_params = vec();
2221+
2222+
auto fcx = new_fn_ctxt(cx.fcx.ccx, s, llforeach);
2223+
auto bcx = new_top_block_ctxt(fcx);
2224+
2225+
// FIXME: populate lllocals from llenv here.
2226+
auto res = trans_block(bcx, body);
2227+
res.bcx.build.RetVoid();
2228+
2229+
2230+
// Step 3: Call iter passing [llforeach, llenv], plus other args.
2231+
2232+
alt (seq.node) {
2233+
case (ast.expr_call(?f, ?args, ?ann)) {
2234+
// FIXME_ finish here by transferring to trans_call,
2235+
// suitably refactored.
2236+
cx.fcx.ccx.sess.unimpl("for each loop in trans");
2237+
}
2238+
}
21452239
fail;
21462240
}
21472241

@@ -3538,6 +3632,7 @@ fn new_fn_ctxt(@crate_ctxt cx,
35383632
llenv=llenv,
35393633
llretptr=llretptr,
35403634
mutable llself=none[ValueRef],
3635+
mutable lliterbody=none[ValueRef],
35413636
llargs=llargs,
35423637
llobjfields=llobjfields,
35433638
lllocals=lllocals,
@@ -3553,6 +3648,8 @@ fn new_fn_ctxt(@crate_ctxt cx,
35533648
// - trans_args
35543649

35553650
fn create_llargs_for_fn_args(&@fn_ctxt cx,
3651+
// FIXME: change bool flag to tag
3652+
bool is_iter,
35563653
option.t[TypeRef] ty_self,
35573654
@ty.t ret_ty,
35583655
&vec[ast.arg] args,
@@ -3577,6 +3674,12 @@ fn create_llargs_for_fn_args(&@fn_ctxt cx,
35773674
}
35783675
}
35793676

3677+
if (is_iter) {
3678+
auto llarg = llvm.LLVMGetParam(cx.llfn, arg_n);
3679+
check (llarg as int != 0);
3680+
cx.lliterbody = some[ValueRef](llarg);
3681+
arg_n += 1u;
3682+
}
35803683

35813684
for (ast.arg arg in args) {
35823685
auto llarg = llvm.LLVMGetParam(cx.llfn, arg_n);
@@ -3713,7 +3816,8 @@ fn trans_fn(@crate_ctxt cx, &ast._fn f, ast.def_id fid,
37133816
cx.item_names.insert(cx.path, llfndecl);
37143817

37153818
auto fcx = new_fn_ctxt(cx, cx.path, llfndecl);
3716-
create_llargs_for_fn_args(fcx, ty_self, ret_ty_of_fn(ann),
3819+
create_llargs_for_fn_args(fcx, f.is_iter,
3820+
ty_self, ret_ty_of_fn(ann),
37173821
f.decl.inputs, ty_params);
37183822
auto bcx = new_top_block_ctxt(fcx);
37193823

@@ -3754,6 +3858,8 @@ fn trans_vtbl(@crate_ctxt cx, TypeRef self_ty,
37543858
alt (node_ann_type(cx, m.node.ann).struct) {
37553859
case (ty.ty_fn(?inputs, ?output)) {
37563860
llfnty = type_of_fn_full(cx,
3861+
// FIXME: support method iters.
3862+
false,
37573863
some[TypeRef](self_ty),
37583864
inputs, output);
37593865
}
@@ -3797,7 +3903,8 @@ fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
37973903
}
37983904

37993905
auto fcx = new_fn_ctxt(cx, cx.path, llctor_decl);
3800-
create_llargs_for_fn_args(fcx, none[TypeRef], ret_ty_of_fn(ann),
3906+
create_llargs_for_fn_args(fcx, false,
3907+
none[TypeRef], ret_ty_of_fn(ann),
38013908
fn_args, ty_params);
38023909

38033910
auto bcx = new_top_block_ctxt(fcx);
@@ -3925,7 +4032,8 @@ fn trans_tag_variant(@crate_ctxt cx, ast.def_id tag_id,
39254032
let ValueRef llfndecl = cx.item_ids.get(variant.id);
39264033

39274034
auto fcx = new_fn_ctxt(cx, cx.path, llfndecl);
3928-
create_llargs_for_fn_args(fcx, none[TypeRef], ret_ty_of_fn(variant.ann),
4035+
create_llargs_for_fn_args(fcx, false,
4036+
none[TypeRef], ret_ty_of_fn(variant.ann),
39294037
fn_args, ty_params);
39304038

39314039
auto bcx = new_top_block_ctxt(fcx);
@@ -4331,6 +4439,7 @@ fn trans_exit_task_glue(@crate_ctxt cx) {
43314439
llenv=C_null(T_opaque_closure_ptr()),
43324440
llretptr=C_null(T_ptr(T_nil())),
43334441
mutable llself=none[ValueRef],
4442+
mutable lliterbody=none[ValueRef],
43344443
llargs=new_def_hash[ValueRef](),
43354444
llobjfields=new_def_hash[ValueRef](),
43364445
lllocals=new_def_hash[ValueRef](),

0 commit comments

Comments
 (0)