1
+ import std:: vec;
1
2
import std:: option:: none;
2
3
import syntax:: ast;
3
4
import lib:: llvm:: llvm:: { ValueRef , TypeRef } ;
@@ -13,9 +14,13 @@ import trans_common::*;
13
14
export trans_ivec, get_len_and_data, duplicate_heap_part, trans_add,
14
15
trans_append;
15
16
16
- fn trans_ivec ( bcx : @block_ctxt , args : & [ @ast:: expr ] , id : ast:: node_id ) ->
17
- result {
18
- let typ = node_id_type ( bcx_ccx ( bcx) , id) ;
17
+ fn alloc_with_heap ( bcx : @block_ctxt , typ : & ty:: t , vecsz : uint ) ->
18
+ { bcx : @block_ctxt ,
19
+ unit_ty : ty:: t ,
20
+ llunitsz : ValueRef ,
21
+ llptr : ValueRef ,
22
+ llfirsteltptr : ValueRef } {
23
+
19
24
let unit_ty;
20
25
alt ty:: struct ( bcx_tcx ( bcx) , typ) {
21
26
ty:: ty_vec ( mt) { unit_ty = mt. ty ; }
@@ -31,12 +36,11 @@ fn trans_ivec(bcx: @block_ctxt, args: &[@ast::expr], id: ast::node_id) ->
31
36
32
37
add_clean_temp ( bcx, llvecptr, typ) ;
33
38
34
- let lllen = bcx. build . Mul ( C_uint ( std :: vec :: len ( args ) ) , unit_sz) ;
39
+ let lllen = bcx. build . Mul ( C_uint ( vecsz ) , unit_sz) ;
35
40
// Allocate the vector pieces and store length and allocated length.
36
41
37
42
let llfirsteltptr;
38
- if std:: vec:: len ( args) > 0 u &&
39
- std:: vec:: len ( args) <= abi:: ivec_default_length {
43
+ if vecsz > 0 u && vecsz <= abi:: ivec_default_length {
40
44
// Interior case.
41
45
42
46
bcx. build . Store ( lllen,
@@ -61,7 +65,7 @@ fn trans_ivec(bcx: @block_ctxt, args: &[@ast::expr], id: ast::node_id) ->
61
65
let llstubptr = bcx. build . PointerCast ( llvecptr, T_ptr ( llstubty) ) ;
62
66
bcx. build . Store ( C_int ( 0 ) , bcx. build . InBoundsGEP ( llstubptr, stub_z) ) ;
63
67
let llheapty = T_ivec_heap_part ( llunitty) ;
64
- if std :: vec :: len ( args ) == 0 u {
68
+ if vecsz == 0 u {
65
69
// Null heap pointer indicates a zero-length vector.
66
70
67
71
bcx. build . Store ( llalen, bcx. build . InBoundsGEP ( llstubptr, stub_a) ) ;
@@ -86,8 +90,27 @@ fn trans_ivec(bcx: @block_ctxt, args: &[@ast::expr], id: ast::node_id) ->
86
90
C_int ( 0 ) ] ) ;
87
91
}
88
92
}
89
- // Store the individual elements.
93
+ ret {
94
+ bcx : bcx,
95
+ unit_ty : unit_ty,
96
+ llunitsz : unit_sz,
97
+ llptr : llvecptr,
98
+ llfirsteltptr : llfirsteltptr} ;
99
+ }
100
+
101
+ fn trans_ivec ( bcx : @block_ctxt , args : & [ @ast:: expr ] ,
102
+ id : ast:: node_id ) -> result {
103
+
104
+ let typ = node_id_type ( bcx_ccx ( bcx) , id) ;
105
+ let alloc_res = alloc_with_heap ( bcx, typ, vec:: len ( args) ) ;
106
+
107
+ let bcx = alloc_res. bcx ;
108
+ let unit_ty = alloc_res. unit_ty ;
109
+ let llunitsz = alloc_res. llunitsz ;
110
+ let llvecptr = alloc_res. llptr ;
111
+ let llfirsteltptr = alloc_res. llfirsteltptr ;
90
112
113
+ // Store the individual elements.
91
114
let i = 0 u;
92
115
for e: @ast:: expr in args {
93
116
let lv = trans_lval ( bcx, e) ;
@@ -96,7 +119,7 @@ fn trans_ivec(bcx: @block_ctxt, args: &[@ast::expr], id: ast::node_id) ->
96
119
if ty:: type_has_dynamic_size ( bcx_tcx ( bcx) , unit_ty) {
97
120
lleltptr =
98
121
bcx. build . InBoundsGEP ( llfirsteltptr,
99
- [ bcx. build . Mul ( C_uint ( i) , unit_sz ) ] ) ;
122
+ [ bcx. build . Mul ( C_uint ( i) , llunitsz ) ] ) ;
100
123
} else {
101
124
lleltptr = bcx. build . InBoundsGEP ( llfirsteltptr, [ C_uint ( i) ] ) ;
102
125
}
0 commit comments