Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
da828747
R
Rust
项目概览
int
/
Rust
大约 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
da828747
编写于
1月 18, 2012
作者:
N
Niko Matsakis
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
correct use of GEP_tup_like in closure constr
also, streamline type_is_tup_like() to the cases which actually work
上级
2286d8c1
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
66 addition
and
28 deletion
+66
-28
src/comp/middle/trans.rs
src/comp/middle/trans.rs
+7
-0
src/comp/middle/trans_closure.rs
src/comp/middle/trans_closure.rs
+27
-22
src/comp/middle/ty.rs
src/comp/middle/ty.rs
+2
-6
src/test/run-pass/alignment-gep-tup-like-1.rs
src/test/run-pass/alignment-gep-tup-like-1.rs
+14
-0
src/test/run-pass/alignment-gep-tup-like-2.rs
src/test/run-pass/alignment-gep-tup-like-2.rs
+16
-0
未找到文件。
src/comp/middle/trans.rs
浏览文件 @
da828747
...
...
@@ -691,6 +691,9 @@ fn GEP_tup_like(bcx: @block_ctxt, t: ty::t, base: ValueRef, ixs: [int])
:
type_is_tup_like
(
bcx
,
t
)
->
result
{
// It might be a static-known type. Handle this.
if
!
ty
::
type_has_dynamic_size
(
bcx_tcx
(
bcx
),
t
)
{
#
debug
[
"GEP_tup_like t=%? ixs=%? -> static"
,
ty_to_str
(
bcx_tcx
(
bcx
),
t
),
ixs
];
ret
rslt
(
bcx
,
GEPi
(
bcx
,
base
,
ixs
));
}
// It is a dynamic-containing type that, if we convert directly to an LLVM
...
...
@@ -758,6 +761,10 @@ fn split_type(ccx: @crate_ctxt, t: ty::t, ixs: [int], n: uint) ->
for
typ
:
ty
::
t
in
s
.prefix
{
args
+=
[
typ
];
}
let
prefix_ty
=
ty
::
mk_tup
(
bcx_tcx
(
bcx
),
args
);
#
debug
[
"GEP_tup_like t=%? ixs=%? prefix_ty=%?"
,
ty_to_str
(
bcx_tcx
(
bcx
),
t
),
ixs
,
ty_to_str
(
bcx_tcx
(
bcx
),
prefix_ty
)];
let
sz
=
size_of_
(
bcx
,
prefix_ty
,
align_next
(
s
.target
));
ret
rslt
(
sz
.bcx
,
bump_ptr
(
sz
.bcx
,
s
.target
,
base
,
sz
.val
));
}
...
...
src/comp/middle/trans_closure.rs
浏览文件 @
da828747
...
...
@@ -261,7 +261,7 @@ fn allocate_cbox(bcx: @block_ctxt,
type
closure_result
=
{
llbox
:
ValueRef
,
// llvalue of ptr to closure
cbox
ptr_ty
:
ty
::
t
,
// type of ptr to closure
cbox
_ty
:
ty
::
t
,
// type of the closure data
bcx
:
@
block_ctxt
// final bcx
};
...
...
@@ -332,12 +332,12 @@ fn maybe_clone_tydesc(bcx: @block_ctxt,
// whatever.
let
cboxptr_ty
=
ty
::
mk_ptr
(
tcx
,
{
ty
:
cbox_ty
,
mut
:
ast
::
imm
});
let
llbox
=
cast_if_we_can
(
bcx
,
llbox
,
cboxptr_ty
);
check
type_is_tup_like
(
bcx
,
cbox
ptr
_ty
);
check
type_is_tup_like
(
bcx
,
cbox_ty
);
// If necessary, copy tydescs describing type parameters into the
// appropriate slot in the closure.
let
{
bcx
:
bcx
,
val
:
ty_params_slot
}
=
GEP_tup_like
_1
(
bcx
,
cboxptr
_ty
,
llbox
,
[
0
,
abi
::
cbox_elt_ty_params
]);
GEP_tup_like
(
bcx
,
cbox
_ty
,
llbox
,
[
0
,
abi
::
cbox_elt_ty_params
]);
let
off
=
0
;
for
tp
in
lltyparams
{
let
cloned_td
=
maybe_clone_tydesc
(
bcx
,
ck
,
tp
.desc
);
...
...
@@ -354,15 +354,16 @@ fn maybe_clone_tydesc(bcx: @block_ctxt,
// Copy expr values into boxed bindings.
// Silly check
let
{
bcx
:
bcx
,
val
:
bindings_slot
}
=
GEP_tup_like_1
(
bcx
,
cboxptr_ty
,
llbox
,
[
0
,
abi
::
cbox_elt_bindings
]);
vec
::
iteri
(
bound_values
)
{
|
i
,
bv
|
if
(
!
ccx
.sess.opts.no_asm_comments
)
{
add_comment
(
bcx
,
#
fmt
(
"Copy %s into closure"
,
ev_to_str
(
ccx
,
bv
)));
}
let
bound_data
=
GEPi
(
bcx
,
bindings_slot
,
[
0
,
i
as
int
]);
let
bound_data
=
GEP_tup_like_1
(
bcx
,
cbox_ty
,
llbox
,
[
0
,
abi
::
cbox_elt_bindings
,
i
as
int
]);
bcx
=
bound_data
.bcx
;
let
bound_data
=
bound_data
.val
;
alt
bv
{
env_expr
(
e
)
{
bcx
=
trans
::
trans_expr_save_in
(
bcx
,
e
,
bound_data
);
...
...
@@ -397,7 +398,7 @@ fn maybe_clone_tydesc(bcx: @block_ctxt,
}
for
cleanup
in
temp_cleanups
{
revoke_clean
(
bcx
,
cleanup
);
}
ret
{
llbox
:
llbox
,
cbox
ptr_ty
:
cboxptr
_ty
,
bcx
:
bcx
};
ret
{
llbox
:
llbox
,
cbox
_ty
:
cbox
_ty
,
bcx
:
bcx
};
}
// Given a context and a list of upvars, build a closure. This just
...
...
@@ -441,13 +442,15 @@ fn build_closure(bcx0: @block_ctxt,
// with the upvars and type descriptors.
fn
load_environment
(
enclosing_cx
:
@
block_ctxt
,
fcx
:
@
fn_ctxt
,
cbox
ptr
_ty
:
ty
::
t
,
cbox_ty
:
ty
::
t
,
cap_vars
:
[
capture
::
capture_var
],
ck
:
ty
::
closure_kind
)
{
let
bcx
=
new_raw_block_ctxt
(
fcx
,
fcx
.llloadenv
);
let
ccx
=
bcx_ccx
(
bcx
);
let
tcx
=
bcx_tcx
(
bcx
);
let
sp
=
bcx
.sp
;
let
cboxptr_ty
=
ty
::
mk_ptr
(
tcx
,
{
ty
:
cbox_ty
,
mut
:
ast
::
imm
});
check
(
type_has_static_size
(
ccx
,
cboxptr_ty
));
let
llty
=
type_of
(
ccx
,
sp
,
cboxptr_ty
);
let
llclosure
=
PointerCast
(
bcx
,
fcx
.llenv
,
llty
);
...
...
@@ -479,9 +482,9 @@ fn load_environment(enclosing_cx: @block_ctxt,
alt
cap_var
.mode
{
capture
::
cap_drop
.
{
/* ignore */
}
_
{
check
type_is_tup_like
(
bcx
,
cbox
ptr
_ty
);
check
type_is_tup_like
(
bcx
,
cbox_ty
);
let
upvarptr
=
GEP_tup_like
(
bcx
,
cbox
ptr
_ty
,
llclosure
,
path
+
[
i
as
int
]);
bcx
,
cbox_ty
,
llclosure
,
path
+
[
i
as
int
]);
bcx
=
upvarptr
.bcx
;
let
llupvarptr
=
upvarptr
.val
;
alt
ck
{
...
...
@@ -516,9 +519,9 @@ fn trans_expr_fn(bcx: @block_ctxt,
let
trans_closure_env
=
fn
@
(
ck
:
ty
::
closure_kind
)
->
ValueRef
{
let
cap_vars
=
capture
::
compute_capture_vars
(
ccx
.tcx
,
id
,
proto
,
cap_clause
);
let
{
llbox
,
cbox
ptr
_ty
,
bcx
}
=
build_closure
(
bcx
,
cap_vars
,
ck
);
let
{
llbox
,
cbox_ty
,
bcx
}
=
build_closure
(
bcx
,
cap_vars
,
ck
);
trans_closure
(
sub_cx
,
sp
,
decl
,
body
,
llfn
,
no_self
,
[],
id
,
{|
fcx
|
load_environment
(
bcx
,
fcx
,
cbox
ptr
_ty
,
cap_vars
,
ck
);
load_environment
(
bcx
,
fcx
,
cbox_ty
,
cap_vars
,
ck
);
});
llbox
};
...
...
@@ -616,7 +619,7 @@ fn trans_bind_1(cx: @block_ctxt, outgoing_fty: ty::t,
};
// Actually construct the closure
let
{
llbox
,
cbox
ptr
_ty
,
bcx
}
=
store_environment
(
let
{
llbox
,
cbox_ty
,
bcx
}
=
store_environment
(
bcx
,
vec
::
map
(
lltydescs
,
{|
d
|
{
desc
:
d
,
dicts
:
none
}}),
env_vals
+
vec
::
map
(
bound
,
{|
x
|
env_expr
(
x
)}),
ty
::
ck_box
);
...
...
@@ -624,7 +627,7 @@ fn trans_bind_1(cx: @block_ctxt, outgoing_fty: ty::t,
// Make thunk
let
llthunk
=
trans_bind_thunk
(
cx
.fcx.lcx
,
cx
.sp
,
pair_ty
,
outgoing_fty_real
,
args
,
cbox
ptr
_ty
,
*
param_bounds
,
target_res
);
cbox_ty
,
*
param_bounds
,
target_res
);
// Fill the function pair
fill_fn_pair
(
bcx
,
get_dest_addr
(
dest
),
llthunk
.val
,
llbox
);
...
...
@@ -782,7 +785,7 @@ fn trans_bind_thunk(cx: @local_ctxt,
incoming_fty
:
ty
::
t
,
outgoing_fty
:
ty
::
t
,
args
:
[
option
::
t
<@
ast
::
expr
>
],
cbox
ptr
_ty
:
ty
::
t
,
cbox_ty
:
ty
::
t
,
param_bounds
:
[
ty
::
param_bounds
],
target_fn
:
option
::
t
<
ValueRef
>
)
->
{
val
:
ValueRef
,
ty
:
TypeRef
}
{
...
...
@@ -794,6 +797,7 @@ fn trans_bind_thunk(cx: @local_ctxt,
*/
// but since we don't, we have to do the checks at the beginning.
let
ccx
=
cx
.ccx
;
let
tcx
=
ccx_tcx
(
ccx
);
check
type_has_static_size
(
ccx
,
incoming_fty
);
// Here we're not necessarily constructing a thunk in the sense of
...
...
@@ -838,7 +842,8 @@ fn trans_bind_thunk(cx: @local_ctxt,
// to the original function. So, let's create one of those:
// The llenv pointer needs to be the correct size. That size is
// 'cboxptr_ty', which was determined by trans_bind.
// 'cbox_ty', which was determined by trans_bind.
let
cboxptr_ty
=
ty
::
mk_ptr
(
tcx
,
{
ty
:
cbox_ty
,
mut
:
ast
::
imm
});
check
type_has_static_size
(
ccx
,
cboxptr_ty
);
let
llclosure_ptr_ty
=
type_of
(
ccx
,
sp
,
cboxptr_ty
);
let
llclosure
=
PointerCast
(
l_bcx
,
fcx
.llenv
,
llclosure_ptr_ty
);
...
...
@@ -854,9 +859,9 @@ fn trans_bind_thunk(cx: @local_ctxt,
}
none
.
{
// Silly check
check
type_is_tup_like
(
bcx
,
cbox
ptr
_ty
);
check
type_is_tup_like
(
bcx
,
cbox_ty
);
let
{
bcx
:
cx
,
val
:
pair
}
=
GEP_tup_like
(
bcx
,
cbox
ptr
_ty
,
llclosure
,
GEP_tup_like
(
bcx
,
cbox_ty
,
llclosure
,
[
0
,
abi
::
cbox_elt_bindings
,
0
]);
let
lltargetenv
=
Load
(
cx
,
GEPi
(
cx
,
pair
,
[
0
,
abi
::
fn_field_box
]));
...
...
@@ -891,9 +896,9 @@ fn trans_bind_thunk(cx: @local_ctxt,
let
llargs
:
[
ValueRef
]
=
[
llretptr
,
lltargetenv
];
// Copy in the type parameters.
check
type_is_tup_like
(
l_bcx
,
cbox
ptr
_ty
);
check
type_is_tup_like
(
l_bcx
,
cbox_ty
);
let
{
bcx
:
l_bcx
,
val
:
param_record
}
=
GEP_tup_like
(
l_bcx
,
cbox
ptr
_ty
,
llclosure
,
GEP_tup_like
(
l_bcx
,
cbox_ty
,
llclosure
,
[
0
,
abi
::
cbox_elt_ty_params
]);
let
off
=
0
;
for
param
in
param_bounds
{
...
...
@@ -932,9 +937,9 @@ fn trans_bind_thunk(cx: @local_ctxt,
// closure.
some
(
e
)
{
// Silly check
check
type_is_tup_like
(
bcx
,
cbox
ptr
_ty
);
check
type_is_tup_like
(
bcx
,
cbox_ty
);
let
bound_arg
=
GEP_tup_like
(
bcx
,
cbox
ptr
_ty
,
llclosure
,
GEP_tup_like
(
bcx
,
cbox_ty
,
llclosure
,
[
0
,
abi
::
cbox_elt_bindings
,
b
]);
bcx
=
bound_arg
.bcx
;
let
val
=
bound_arg
.val
;
...
...
src/comp/middle/ty.rs
浏览文件 @
da828747
...
...
@@ -859,8 +859,7 @@ fn sequence_element_type(cx: ctxt, ty: t) -> t {
pure
fn
type_is_tup_like
(
cx
:
ctxt
,
ty
:
t
)
->
bool
{
let
sty
=
struct
(
cx
,
ty
);
alt
sty
{
ty_ptr
(
_
)
|
ty_uniq
(
_
)
|
ty_box
(
_
)
|
ty_rec
(
_
)
|
ty_tup
(
_
)
|
ty_tag
(
_
,
_
)
{
true
}
ty_rec
(
_
)
|
ty_tup
(
_
)
{
true
}
_
{
false
}
}
}
...
...
@@ -871,12 +870,9 @@ fn get_element_type(cx: ctxt, ty: t, i: uint) -> t {
ty_tup
(
ts
)
{
ret
ts
[
i
];
}
_
{
cx
.sess
.bug
(
"get_element_type called on type "
+
ty_to_str
(
cx
,
ty
)
+
" - expected a
\
tuple or record"
);
" - expected a tuple or record"
);
}
}
// NB: This is not exhaustive -- struct(cx, ty) could be a box or a
// tag.
}
pure
fn
type_is_box
(
cx
:
ctxt
,
ty
:
t
)
->
bool
{
...
...
src/test/run-pass/alignment-gep-tup-like-1.rs
0 → 100644
浏览文件 @
da828747
type
pair
<
A
,
B
>
=
{
a
:
A
,
b
:
B
};
fn
f
<
A
:
copy
>
(
a
:
A
,
b
:
u16
)
->
fn
@
()
->
(
A
,
u16
)
{
fn
@
()
->
(
A
,
u16
)
{
(
a
,
b
)
}
}
fn
main
()
{
let
(
a
,
b
)
=
f
(
22_u64
,
44u16
)();
#
debug
[
"a=%? b=%?"
,
a
,
b
];
assert
a
==
22u64
;
assert
b
==
44u16
;
}
\ No newline at end of file
src/test/run-pass/alignment-gep-tup-like-2.rs
0 → 100644
浏览文件 @
da828747
type
pair
<
A
,
B
>
=
{
a
:
A
,
b
:
B
};
fn
f
<
A
:
send
,
B
:
send
>
(
a
:
A
,
b
:
B
)
->
fn
~
()
->
(
A
,
B
)
{
fn
~
()
->
(
A
,
B
)
{
(
a
,
b
)
}
}
fn
main
()
{
let
x
=
22_u8
;
let
y
=
44_u64
;
let
(
a
,
b
)
=
f
(
~
x
,
~
y
)();
#
debug
[
"a=%? b=%?"
,
*
a
,
*
b
];
assert
*
a
==
x
;
assert
*
b
==
y
;
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录