@@ -288,6 +288,10 @@ fn T_taskptr() -> TypeRef {
288
288
ret T_ptr ( T_task ( ) ) ;
289
289
}
290
290
291
+ fn T_typaram_ptr ( ) -> TypeRef {
292
+ ret T_ptr ( T_i8 ( ) ) ;
293
+ }
294
+
291
295
fn T_closure_ptr ( TypeRef lltarget_ty ,
292
296
TypeRef llbindings_ty ) -> TypeRef {
293
297
ret T_ptr ( T_box ( T_struct ( vec ( T_ptr ( T_tydesc ( ) ) ,
@@ -311,7 +315,7 @@ fn type_of(@crate_ctxt cx, @ty.t t) -> TypeRef {
311
315
ret llty;
312
316
}
313
317
314
- // NB: this function must match the ABI assumptions of trans_args .
318
+ // NB: this must match trans_args and create_llargs_for_fn_args .
315
319
fn type_of_fn_full ( @crate_ctxt cx ,
316
320
option. t[ TypeRef ] obj_self ,
317
321
vec[ ty. arg] inputs ,
@@ -326,6 +330,10 @@ fn type_of_fn_full(@crate_ctxt cx,
326
330
i += 1 u;
327
331
}
328
332
333
+ if ( ty. type_has_dynamic_size ( output) ) {
334
+ atys += T_typaram_ptr ( ) ;
335
+ }
336
+
329
337
alt ( obj_self) {
330
338
case ( some[ TypeRef ] ( ?t) ) {
331
339
check ( t as int != 0 ) ;
@@ -336,19 +344,20 @@ fn type_of_fn_full(@crate_ctxt cx,
336
344
}
337
345
}
338
346
339
- if ( ty. type_has_dynamic_size ( output) ) {
340
- atys += T_ptr ( type_of ( cx, output) ) ;
341
- }
342
-
343
347
for ( ty. arg arg in inputs) {
344
- let TypeRef t = type_of ( cx, arg. ty ) ;
345
- alt ( arg. mode ) {
346
- case ( ast. alias ) {
347
- t = T_ptr ( t) ;
348
+ if ( ty. type_has_dynamic_size ( arg. ty ) ) {
349
+ check ( arg. mode == ast. alias ) ;
350
+ atys += T_typaram_ptr ( ) ;
351
+ } else {
352
+ let TypeRef t = type_of ( cx, arg. ty ) ;
353
+ alt ( arg. mode ) {
354
+ case ( ast. alias ) {
355
+ t = T_ptr ( t) ;
356
+ }
357
+ case ( _) { /* fall through */ }
348
358
}
349
- case ( _ ) { /* fall through */ }
359
+ atys += t ;
350
360
}
351
- atys += t;
352
361
}
353
362
354
363
auto ret_ty;
@@ -441,7 +450,7 @@ fn type_of_inner(@crate_ctxt cx, @ty.t t) -> TypeRef {
441
450
fail;
442
451
}
443
452
case ( ty. ty_param ( _) ) {
444
- ret T_ptr ( T_i8 ( ) ) ;
453
+ ret T_typaram_ptr ( ) ;
445
454
}
446
455
}
447
456
fail;
@@ -797,7 +806,7 @@ fn make_drop_glue(@block_ctxt cx, ValueRef v, @ty.t t) -> result {
797
806
vec ( C_int ( 0 ) ,
798
807
C_int ( abi. box_rc_field_body ) ) ) ;
799
808
800
- auto body_val = load_non_structural ( cx, body, body_ty) ;
809
+ auto body_val = load_scalar_or_boxed ( cx, body, body_ty) ;
801
810
auto res = drop_ty ( cx, body_val, body_ty) ;
802
811
// FIXME: switch gc/non-gc on layer of the type.
803
812
ret trans_non_gc_free ( res. bcx , v) ;
@@ -1001,7 +1010,7 @@ fn iter_structural_ty(@block_ctxt cx,
1001
1010
for ( @ty. t arg in args) {
1002
1011
auto elt = r. bcx. build. GEP ( v, vec( C_int ( 0 ) , C_int ( i) ) ) ;
1003
1012
r = f( r. bcx,
1004
- load_non_structural ( r. bcx, elt, arg) ,
1013
+ load_scalar_or_boxed ( r. bcx, elt, arg) ,
1005
1014
arg) ;
1006
1015
i += 1 ;
1007
1016
}
@@ -1011,7 +1020,7 @@ fn iter_structural_ty(@block_ctxt cx,
1011
1020
for ( ty. field fld in fields) {
1012
1021
auto llfld = r. bcx. build. GEP ( v, vec( C_int ( 0 ) , C_int ( i) ) ) ;
1013
1022
r = f( r. bcx,
1014
- load_non_structural ( r. bcx, llfld, fld. ty) ,
1023
+ load_scalar_or_boxed ( r. bcx, llfld, fld. ty) ,
1015
1024
fld. ty) ;
1016
1025
i += 1 ;
1017
1026
}
@@ -1073,7 +1082,7 @@ fn iter_structural_ty(@block_ctxt cx,
1073
1082
auto llfldp = variant_cx. build. GEP ( llvarp,
1074
1083
vec( C_int ( 0 ) , C_int ( j as int) ) ) ;
1075
1084
auto llfld =
1076
- load_non_structural ( variant_cx,
1085
+ load_scalar_or_boxed ( variant_cx,
1077
1086
llfldp, a. ty) ;
1078
1087
1079
1088
auto res = f( variant_cx, llfld, a. ty) ;
@@ -1161,7 +1170,7 @@ fn iter_sequence(@block_ctxt cx,
1161
1170
1162
1171
auto elt = body_cx. build. GEP ( p0, vec( C_int ( 0 ) , ix) ) ;
1163
1172
auto body_res = f( body_cx,
1164
- load_non_structural ( body_cx, elt, elt_ty) ,
1173
+ load_scalar_or_boxed ( body_cx, elt, elt_ty) ,
1165
1174
elt_ty) ;
1166
1175
auto next_ix = body_res. bcx. build. Add ( ix, C_int ( 1 ) ) ;
1167
1176
auto next_scaled_ix = body_res. bcx. build. Add ( scaled_ix, unit_sz) ;
@@ -1206,7 +1215,7 @@ fn incr_all_refcnts(@block_ctxt cx,
1206
1215
fn drop_slot( @block_ctxt cx,
1207
1216
ValueRef slot,
1208
1217
@ty. t t) -> result {
1209
- auto llptr = load_non_structural ( cx, slot, t) ;
1218
+ auto llptr = load_scalar_or_boxed ( cx, slot, t) ;
1210
1219
auto re = drop_ty( cx, llptr, t) ;
1211
1220
1212
1221
auto llty = val_ty( slot) ;
@@ -1668,7 +1677,7 @@ impure fn trans_pat_match(@block_ctxt cx, @ast.pat pat, ValueRef llval,
1668
1677
auto llsubvalptr = matched_cx. build. GEP ( llunionptr,
1669
1678
vec( C_int ( 0 ) ,
1670
1679
C_int ( i) ) ) ;
1671
- auto llsubval = load_non_structural ( matched_cx,
1680
+ auto llsubval = load_scalar_or_boxed ( matched_cx,
1672
1681
llsubvalptr,
1673
1682
pat_ty( subpat) ) ;
1674
1683
auto subpat_res = trans_pat_match( matched_cx, subpat,
@@ -1709,7 +1718,7 @@ impure fn trans_pat_binding(@block_ctxt cx, @ast.pat pat, ValueRef llval)
1709
1718
for ( @ast. pat subpat in subpats) {
1710
1719
auto llsubvalptr = this_cx. build. GEP ( llunionptr,
1711
1720
vec( C_int ( 0 ) , C_int ( i) ) ) ;
1712
- auto llsubval = load_non_structural ( this_cx, llsubvalptr,
1721
+ auto llsubval = load_scalar_or_boxed ( this_cx, llsubvalptr,
1713
1722
pat_ty( subpat) ) ;
1714
1723
auto subpat_res = trans_pat_binding( this_cx, subpat,
1715
1724
llsubval) ;
@@ -1757,7 +1766,7 @@ impure fn trans_alt(@block_ctxt cx, @ast.expr expr, vec[ast.arm] arms)
1757
1766
ret res( last_cx, C_nil ( ) ) ;
1758
1767
}
1759
1768
1760
- type generic_info = rec( @ty. t monotype ,
1769
+ type generic_info = rec( @ty. t item_type ,
1761
1770
vec[ ValueRef ] tydescs) ;
1762
1771
1763
1772
type lval_result = rec( result res,
@@ -1815,7 +1824,7 @@ fn trans_path(@block_ctxt cx, &ast.path p, &option.t[ast.def] dopt,
1815
1824
append[ ValueRef ] ( tydescs,
1816
1825
get_tydesc( cx, t) ) ;
1817
1826
}
1818
- auto gen = rec( monotype = monoty ,
1827
+ auto gen = rec( item_type = ty . item_ty ( fn_item ) . _1 ,
1819
1828
tydescs = tydescs ) ;
1820
1829
lv = rec( generic = some[ generic_info] ( gen)
1821
1830
with lv) ;
@@ -1969,7 +1978,7 @@ impure fn trans_cast(@block_ctxt cx, @ast.expr e, &ast.ann ann) -> result {
1969
1978
}
1970
1979
1971
1980
1972
- // NB: this function must match the ABI assumptions of type_of_fn_full .
1981
+ // NB: this must match type_of_fn_full and create_llargs_for_fn_args .
1973
1982
impure fn trans_args( @block_ctxt cx,
1974
1983
ValueRef llclosure,
1975
1984
option. t[ ValueRef ] llobj,
@@ -1980,17 +1989,19 @@ impure fn trans_args(@block_ctxt cx,
1980
1989
let vec[ ValueRef ] vs = vec( cx. fcx. lltaskptr) ;
1981
1990
let @block_ctxt bcx = cx;
1982
1991
1983
- let vec[ ty. arg] args = vec( ) ; // FIXME: typestate bug
1984
- alt ( fn_ty. struct ) {
1985
- case ( ty. ty_fn( ?a, _) ) { args = a; }
1986
- case ( _) { fail; }
1987
- }
1992
+ let vec[ ty. arg] args = ty. ty_fn_args( fn_ty) ;
1988
1993
1989
1994
alt ( gen) {
1990
1995
case ( some[ generic_info] ( ?g) ) {
1991
1996
for ( ValueRef t in g. tydescs) {
1992
1997
vs += t;
1993
1998
}
1999
+ args = ty. ty_fn_args( g. item_type) ;
2000
+ if ( ty. type_has_dynamic_size( ty. ty_fn_ret( g. item_type) ) ) {
2001
+ // FIXME: allocate real outptr in caller,
2002
+ // pass in to here.
2003
+ vs += C_null ( T_typaram_ptr ( ) ) ;
2004
+ }
1994
2005
}
1995
2006
case ( _) { }
1996
2007
}
@@ -2019,29 +2030,33 @@ impure fn trans_args(@block_ctxt cx,
2019
2030
// we are now passing it as an arg, so need to load it.
2020
2031
re. val = re. bcx. build. Load ( re. val) ;
2021
2032
}
2022
- } else {
2023
- if ( mode == ast. alias) {
2024
- let lval_result lv;
2025
- if ( ty. is_lval( e) ) {
2026
- lv = trans_lval( bcx, e) ;
2027
- } else {
2028
- auto r = trans_expr( bcx, e) ;
2029
- lv = lval_val( r. bcx, r. val) ;
2030
- }
2033
+ } else if ( mode == ast. alias) {
2034
+ let lval_result lv;
2035
+ if ( ty. is_lval( e) ) {
2036
+ lv = trans_lval( bcx, e) ;
2037
+ } else {
2038
+ auto r = trans_expr( bcx, e) ;
2039
+ lv = lval_val( r. bcx, r. val) ;
2040
+ }
2031
2041
2032
- if ( !lv. is_mem) {
2033
- // Non-mem but we're trying to alias; synthesize an
2034
- // alloca, spill to it and pass its address.
2035
- auto llty = val_ty( lv. res. val) ;
2036
- auto llptr = lv. res. bcx. build. Alloca ( llty) ;
2037
- lv. res. bcx. build. Store ( lv. res. val, llptr) ;
2038
- re = res( lv. res. bcx, llptr) ;
2039
- } else {
2040
- re = lv. res;
2041
- }
2042
+ if ( !lv. is_mem) {
2043
+ // Non-mem but we're trying to alias; synthesize an
2044
+ // alloca, spill to it and pass its address.
2045
+ auto llty = val_ty( lv. res. val) ;
2046
+ auto llptr = lv. res. bcx. build. Alloca ( llty) ;
2047
+ lv. res. bcx. build. Store ( lv. res. val, llptr) ;
2048
+ re = res( lv. res. bcx, llptr) ;
2042
2049
} else {
2043
- re = trans_expr ( bcx , e ) ;
2050
+ re = lv . res ;
2044
2051
}
2052
+
2053
+ } else {
2054
+ re = trans_expr( bcx, e) ;
2055
+ }
2056
+
2057
+ if ( ty. type_has_dynamic_size( args. ( i) . ty) ) {
2058
+ re. val = re. bcx. build. PointerCast ( re. val,
2059
+ T_typaram_ptr ( ) ) ;
2045
2060
}
2046
2061
2047
2062
vs += re. val;
@@ -2444,7 +2459,7 @@ impure fn trans_expr(@block_ctxt cx, @ast.expr e) -> result {
2444
2459
auto t = node_ann_type( cx. fcx. ccx, ann) ;
2445
2460
auto lhs_res = trans_lval( cx, dst) ;
2446
2461
check ( lhs_res. is_mem) ;
2447
- auto lhs_val = load_non_structural ( lhs_res. res. bcx,
2462
+ auto lhs_val = load_scalar_or_boxed ( lhs_res. res. bcx,
2448
2463
lhs_res. res. val, t) ;
2449
2464
auto rhs_res = trans_expr( lhs_res. res. bcx, src) ;
2450
2465
auto v = trans_eager_binop( rhs_res. bcx, op, lhs_val, rhs_res. val) ;
@@ -2483,24 +2498,24 @@ impure fn trans_expr(@block_ctxt cx, @ast.expr e) -> result {
2483
2498
auto t = ty. expr_ty( e) ;
2484
2499
auto sub = trans_lval( cx, e) ;
2485
2500
ret res( sub. res. bcx,
2486
- load_non_structural ( sub. res. bcx, sub. res. val, t) ) ;
2501
+ load_scalar_or_boxed ( sub. res. bcx, sub. res. val, t) ) ;
2487
2502
}
2488
2503
}
2489
2504
cx. fcx. ccx. sess. unimpl( "expr variant in trans_expr" ) ;
2490
2505
fail;
2491
2506
}
2492
2507
2493
2508
// We pass structural values around the compiler "by pointer" and
2494
- // non-structural values "by value". This function selects whether
2495
- // to load a pointer or pass it.
2509
+ // non-structural values (scalars and boxes) "by value". This function selects
2510
+ // whether to load a pointer or pass it.
2496
2511
2497
- fn load_non_structural( @block_ctxt cx,
2498
- ValueRef v,
2499
- @ty. t t) -> ValueRef {
2500
- if ( ty. type_is_structural( t) ) {
2501
- ret v;
2502
- } else {
2512
+ fn load_scalar_or_boxed( @block_ctxt cx,
2513
+ ValueRef v,
2514
+ @ty. t t) -> ValueRef {
2515
+ if ( ty. type_is_scalar( t) || ty. type_is_boxed( t) ) {
2503
2516
ret cx. build. Load ( v) ;
2517
+ } else {
2518
+ ret v;
2504
2519
}
2505
2520
}
2506
2521
@@ -2591,7 +2606,8 @@ impure fn trans_ret(@block_ctxt cx, &option.t[@ast.expr] e) -> result {
2591
2606
2592
2607
alt ( cx. fcx. llretptr) {
2593
2608
case ( some[ ValueRef ] ( ?llptr) ) {
2594
- r. bcx. build. Store ( r. val, llptr) ;
2609
+ // FIXME: Generic return: Needs to use tydesc.
2610
+ // r.bcx.build.Store(r.val, llptr);
2595
2611
r. bcx. build. RetVoid ( ) ;
2596
2612
}
2597
2613
case ( none[ ValueRef ] ) {
@@ -2801,7 +2817,7 @@ fn new_fn_ctxt(@crate_ctxt cx,
2801
2817
ccx=cx) ;
2802
2818
}
2803
2819
2804
-
2820
+ // NB: this must match trans_args and type_of_fn_full.
2805
2821
fn create_llargs_for_fn_args ( & @fn_ctxt cx ,
2806
2822
option. t[ TypeRef ] ty_self ,
2807
2823
@ty. t ret_ty ,
@@ -2816,6 +2832,11 @@ fn create_llargs_for_fn_args(&@fn_ctxt cx,
2816
2832
arg_n += 1 u;
2817
2833
}
2818
2834
2835
+ if ( ty. type_has_dynamic_size( ret_ty) ) {
2836
+ cx. llretptr = some[ ValueRef ] ( llvm. LLVMGetParam ( cx. llfn, arg_n) ) ;
2837
+ arg_n += 1 u;
2838
+ }
2839
+
2819
2840
alt ( ty_self) {
2820
2841
case ( some[ TypeRef ] ( _) ) {
2821
2842
auto llself = llvm. LLVMGetParam ( cx. llfn, arg_n) ;
@@ -2829,11 +2850,6 @@ fn create_llargs_for_fn_args(&@fn_ctxt cx,
2829
2850
}
2830
2851
}
2831
2852
2832
- if ( ty. type_has_dynamic_size( ret_ty) ) {
2833
- cx. llretptr = some[ ValueRef ] ( llvm. LLVMGetParam ( cx. llfn, arg_n) ) ;
2834
- arg_n += 1 u;
2835
- }
2836
-
2837
2853
for ( ast. arg arg in args) {
2838
2854
auto llarg = llvm. LLVMGetParam ( cx. llfn, arg_n) ;
2839
2855
check ( llarg as int != 0 ) ;
@@ -3106,7 +3122,7 @@ impure fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
3106
3122
let int i = 0 ;
3107
3123
for ( ast. obj_field f in ob. fields) {
3108
3124
auto arg = r. bcx. fcx. llargs. get( f. id) ;
3109
- arg = load_non_structural ( r. bcx, arg, arg_tys. ( i) . ty) ;
3125
+ arg = load_scalar_or_boxed ( r. bcx, arg, arg_tys. ( i) . ty) ;
3110
3126
auto field = r. bcx. build. GEP ( body_fields,
3111
3127
vec( C_int ( 0 ) , C_int ( i) ) ) ;
3112
3128
r = copy_ty( r. bcx, true , field, arg, arg_tys. ( i) . ty) ;
0 commit comments