@@ -1955,24 +1955,93 @@ impure fn trans_bind(@block_ctxt cx, @ast.expr f,
1955
1955
if ( f_res. is_mem) {
1956
1956
cx. fcx. ccx. sess. unimpl( "re-binding existing function" ) ;
1957
1957
} else {
1958
- let vec[ @ty. t] bound = vec( ) ;
1958
+ let vec[ @ast. expr] bound = vec( ) ;
1959
+
1959
1960
for ( option. t[ @ast. expr] argopt in args) {
1960
1961
alt ( argopt) {
1961
1962
case ( none[ @ast. expr] ) {
1962
1963
}
1963
1964
case ( some[ @ast. expr] ( ?e) ) {
1964
- append[ @ty . t ] ( bound, ty . expr_ty ( e ) ) ;
1965
+ append[ @ast . expr ] ( bound, e ) ;
1965
1966
}
1966
1967
}
1967
1968
}
1968
- if ( _vec. len[ @ty . t ] ( bound) == 0 u) {
1969
+ if ( _vec. len[ @ast . expr ] ( bound) == 0 u) {
1969
1970
// Trivial 'binding': just return the static pair-ptr.
1970
1971
ret f_res. res;
1971
1972
} else {
1972
1973
auto bcx = f_res. res. bcx;
1973
1974
auto pair_t = node_type( cx. fcx. ccx, ann) ;
1974
1975
auto pair_v = bcx. build. Alloca( pair_t) ;
1975
- cx. fcx. ccx. sess. unimpl( "nontrivial binding" ) ;
1976
+
1977
+ auto pair_box = bcx. build. GEP ( pair_v,
1978
+ vec( C_int ( 0 ) ,
1979
+ C_int ( abi. fn_field_box) ) ) ;
1980
+
1981
+ // Translate the bound expressions.
1982
+ let vec[ @ty. t] bound_tys = vec( ) ;
1983
+ let vec[ ValueRef ] bound_vals = vec( ) ;
1984
+ for ( @ast. expr e in bound) {
1985
+ auto arg = trans_expr( bcx, e) ;
1986
+ bcx = arg. bcx;
1987
+ append[ ValueRef ] ( bound_vals, arg. val) ;
1988
+ append[ @ty. t] ( bound_tys, ty. expr_ty( e) ) ;
1989
+ }
1990
+
1991
+ // Synthesize a closure type.
1992
+ let @ty. t bindings_ty = ty. plain_ty( ty. ty_tup( bound_tys) ) ;
1993
+ let TypeRef llbindings_ty = type_of( bcx. fcx. ccx,
1994
+ bindings_ty) ;
1995
+ let TypeRef llclosure_ty =
1996
+ T_ptr ( T_box ( T_struct ( vec( T_ptr ( T_tydesc ( ) ) ,
1997
+ type_of( bcx. fcx. ccx,
1998
+ ty. expr_ty( f) ) ,
1999
+ llbindings_ty)
2000
+ // FIXME: add captured typarams.
2001
+ ) ) ) ;
2002
+
2003
+ // Malloc a box for the body.
2004
+ auto r = trans_malloc_inner( bcx, llclosure_ty) ;
2005
+ auto box = r. val;
2006
+ bcx = r. bcx;
2007
+ auto rc = bcx. build. GEP ( box,
2008
+ vec( C_int ( 0 ) ,
2009
+ C_int ( abi. box_rc_field_refcnt) ) ) ;
2010
+ auto closure =
2011
+ bcx. build. GEP ( box,
2012
+ vec( C_int ( 0 ) ,
2013
+ C_int ( abi. box_rc_field_body) ) ) ;
2014
+ bcx. build. Store ( C_int ( 1 ) , rc) ;
2015
+
2016
+
2017
+ // Store bindings tydesc.
2018
+ auto bound_tydesc =
2019
+ bcx. build. GEP ( closure,
2020
+ vec( C_int ( 0 ) ,
2021
+ C_int ( abi. closure_elt_tydesc) ) ) ;
2022
+
2023
+ auto bindings_tydesc = get_tydesc( bcx, bindings_ty) ;
2024
+ bcx. build. Store ( bindings_tydesc, bound_tydesc) ;
2025
+
2026
+ // Copy args into body fields.
2027
+ auto bindings =
2028
+ bcx. build. GEP ( closure,
2029
+ vec( C_int ( 0 ) ,
2030
+ C_int ( abi. closure_elt_bindings) ) ) ;
2031
+
2032
+ let int i = 0 ;
2033
+ for ( ValueRef v in bound_vals) {
2034
+ auto bound = bcx. build. GEP ( bindings,
2035
+ vec( C_int ( 0 ) , C_int ( i) ) ) ;
2036
+ bcx = copy_ty( r. bcx, true , bound, v, bound_tys. ( i) ) . bcx;
2037
+ i += 1 ;
2038
+ }
2039
+
2040
+ // Store box ptr in outer pair.
2041
+ let TypeRef llbox_ty = T_ptr ( T_box ( T_nil ( ) ) ) ;
2042
+ auto p = r. bcx. build. PointerCast ( box, llbox_ty) ;
2043
+ bcx. build. Store ( p, pair_box) ;
2044
+
1976
2045
ret res( bcx, pair_v) ;
1977
2046
}
1978
2047
}
0 commit comments