Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
b4d6589e
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,发现更多精彩内容 >>
提交
b4d6589e
编写于
2月 23, 2011
作者:
P
Patrick Walton
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Implement type descriptor binding. Un-XFAIL test/run-pass/generic-bind.rs.
上级
38168404
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
100 addition
and
19 deletion
+100
-19
src/Makefile
src/Makefile
+1
-0
src/comp/middle/trans.rs
src/comp/middle/trans.rs
+96
-19
src/comp/middle/ty.rs
src/comp/middle/ty.rs
+3
-0
未找到文件。
src/Makefile
浏览文件 @
b4d6589e
...
...
@@ -480,6 +480,7 @@ TEST_XFAILS_RUSTC := $(filter-out \
foreach-simple.rs
\
fun-call-variants.rs
\
fun-indirect-call.rs
\
generic-bind.rs
\
generic-derived-type.rs
\
generic-fn.rs
\
generic-fn-infer.rs
\
...
...
src/comp/middle/trans.rs
浏览文件 @
b4d6589e
...
...
@@ -373,11 +373,12 @@ fn T_typaram_ptr(type_names tn) -> TypeRef {
fn
T_closure_ptr
(
type_names
tn
,
TypeRef
lltarget_ty
,
TypeRef
llbindings_ty
)
->
TypeRef
{
TypeRef
llbindings_ty
,
uint
n_ty_params
)
->
TypeRef
{
ret
T_ptr
(
T_box
(
T_struct
(
vec
(
T_ptr
(
T_tydesc
(
tn
)),
lltarget_ty
,
llbindings_ty
)
// FIXME: add captured typarams.
llbindings_ty
,
T_captured_tydescs
(
tn
,
n_ty_params
))
)));
}
...
...
@@ -388,7 +389,8 @@ fn T_opaque_closure_ptr(type_names tn) -> TypeRef {
}
auto
t
=
T_closure_ptr
(
tn
,
T_struct
(
vec
(
T_ptr
(
T_nil
()),
T_ptr
(
T_nil
()))),
T_nil
());
T_nil
(),
0u
);
tn
.associate
(
s
,
t
);
ret
t
;
}
...
...
@@ -2747,7 +2749,8 @@ fn trans_bind_thunk(@crate_ctxt cx,
@
ty
.t
outgoing_fty
,
vec
[
option
.t
[
@
ast
.expr
]]
args
,
TypeRef
llclosure_ty
,
vec
[
@
ty
.t
]
bound_tys
)
->
ValueRef
{
vec
[
@
ty
.t
]
bound_tys
,
uint
ty_param_count
)
->
ValueRef
{
// Construct a thunk-call with signature incoming_fty, and that copies
// args forward into a call to outgoing_fty.
...
...
@@ -2755,9 +2758,6 @@ fn trans_bind_thunk(@crate_ctxt cx,
let
TypeRef
llthunk_ty
=
get_pair_fn_ty
(
type_of
(
cx
,
incoming_fty
));
let
ValueRef
llthunk
=
decl_fastcall_fn
(
cx
.llmod
,
s
,
llthunk_ty
);
// FIXME: handle ty params properly.
let
vec
[
ast
.ty_param
]
ty_params
=
vec
();
auto
fcx
=
new_fn_ctxt
(
cx
,
s
,
llthunk
);
auto
bcx
=
new_top_block_ctxt
(
fcx
);
...
...
@@ -2779,11 +2779,33 @@ fn trans_bind_thunk(@crate_ctxt cx,
vec
(
C_int
(
0
),
C_int
(
abi
.fn_field_box
)));
lltargetclosure
=
bcx
.build
.Load
(
lltargetclosure
);
let
vec
[
ValueRef
]
llargs
=
vec
(
fcx
.llretptr
,
auto
outgoing_ret_ty
=
ty
.ty_fn_ret
(
outgoing_fty
);
auto
outgoing_arg_tys
=
ty
.ty_fn_args
(
outgoing_fty
);
auto
llretptr
=
fcx
.llretptr
;
if
(
ty
.type_has_dynamic_size
(
outgoing_ret_ty
))
{
llretptr
=
bcx
.build
.PointerCast
(
llretptr
,
T_typaram_ptr
(
cx
.tn
));
}
let
vec
[
ValueRef
]
llargs
=
vec
(
llretptr
,
fcx
.lltaskptr
,
lltargetclosure
);
let
uint
a
=
0u
;
// Copy in the type parameters.
let
uint
i
=
0u
;
while
(
i
<
ty_param_count
)
{
auto
lltyparam_ptr
=
bcx
.build
.GEP
(
llbody
,
vec
(
C_int
(
0
),
C_int
(
abi
.closure_elt_ty_params
),
C_int
(
i
as
int
)));
llargs
+=
vec
(
bcx
.build
.Load
(
lltyparam_ptr
));
i
+=
1u
;
}
let
uint
a
=
2u
+
i
;
// retptr, task ptr, env come first
let
int
b
=
0
;
let
uint
outgoing_arg_index
=
0u
;
for
(
option
.t
[
@
ast
.expr
]
arg
in
args
)
{
alt
(
arg
)
{
...
...
@@ -2800,10 +2822,19 @@ fn trans_bind_thunk(@crate_ctxt cx,
// Arg will be provided when the thunk is invoked.
case
(
none
[
@
ast
.expr
])
{
let
ValueRef
passed_arg
=
llvm
.LLVMGetParam
(
llthunk
,
a
);
if
(
ty
.type_has_dynamic_size
(
outgoing_arg_tys
.
(
outgoing_arg_index
)
.ty
))
{
// Cast to a generic typaram pointer in order to make a
// type-compatible call.
passed_arg
=
bcx
.build
.PointerCast
(
passed_arg
,
T_typaram_ptr
(
cx
.tn
));
}
llargs
+=
passed_arg
;
a
+=
1u
;
}
}
outgoing_arg_index
+=
0u
;
}
// FIXME: turn this call + ret into a tail call.
...
...
@@ -2811,6 +2842,7 @@ fn trans_bind_thunk(@crate_ctxt cx,
vec
(
C_int
(
0
),
C_int
(
abi
.fn_field_code
)));
lltargetfn
=
bcx
.build
.Load
(
lltargetfn
);
auto
r
=
bcx
.build
.FastCall
(
lltargetfn
,
llargs
);
bcx
.build
.RetVoid
();
...
...
@@ -2835,7 +2867,23 @@ fn trans_bind(@block_ctxt cx, @ast.expr f,
}
}
}
if
(
_
vec
.len
[
@
ast
.expr
](
bound
)
==
0u
)
{
// Figure out which tydescs we need to pass, if any.
// FIXME: typestate botch
let
@
ty
.t
outgoing_fty
=
ty
.plain_ty
(
ty
.ty_nil
);
let
vec
[
ValueRef
]
lltydescs
=
vec
();
alt
(
f_res
.generic
)
{
case
(
none
[
generic_info
])
{
outgoing_fty
=
ty
.expr_ty
(
f
);
}
case
(
some
[
generic_info
](
?
ginfo
))
{
outgoing_fty
=
ginfo
.item_type
;
lltydescs
=
ginfo
.tydescs
;
}
}
auto
ty_param_count
=
_
vec
.len
[
ValueRef
](
lltydescs
);
if
(
_
vec
.len
[
@
ast
.expr
](
bound
)
==
0u
&&
ty_param_count
==
0u
)
{
// Trivial 'binding': just return the static pair-ptr.
ret
f_res
.res
;
}
else
{
...
...
@@ -2846,20 +2894,27 @@ fn trans_bind(@block_ctxt cx, @ast.expr f,
// Translate the bound expressions.
let
vec
[
@
ty
.t
]
bound_tys
=
vec
();
let
vec
[
ValueRef
]
bound_vals
=
vec
();
auto
i
=
0u
;
for
(
@
ast
.expr
e
in
bound
)
{
auto
arg
=
trans_expr
(
bcx
,
e
);
bcx
=
arg
.bcx
;
append
[
ValueRef
](
bound_vals
,
arg
.val
);
append
[
@
ty
.t
](
bound_tys
,
ty
.expr_ty
(
e
));
i
+=
1u
;
}
// Get the type of the bound function.
let
TypeRef
lltarget_ty
=
type_of
(
bcx
.fcx.ccx
,
outgoing_fty
);
// Synthesize a closure type.
let
@
ty
.t
bindings_ty
=
plain_ty
(
ty
.ty_tup
(
bound_tys
));
let
TypeRef
lltarget_ty
=
type_of
(
bcx
.fcx.ccx
,
ty
.expr_ty
(
f
));
let
TypeRef
llbindings_ty
=
type_of
(
bcx
.fcx.ccx
,
bindings_ty
);
let
TypeRef
llclosure_ty
=
T_closure_ptr
(
cx
.fcx.ccx.tn
,
lltarget_ty
,
llbindings_ty
);
llbindings_ty
,
ty_param_count
);
// Malloc a box for the body.
auto
r
=
trans_malloc_inner
(
bcx
,
llclosure_ty
);
...
...
@@ -2888,19 +2943,40 @@ fn trans_bind(@block_ctxt cx, @ast.expr f,
bcx
.build
.GEP
(
closure
,
vec
(
C_int
(
0
),
C_int
(
abi
.closure_elt_target
)));
bcx
.build
.Store
(
bcx
.build
.Load
(
f_res
.res.val
),
bound_target
);
auto
src
=
bcx
.build
.Load
(
f_res
.res.val
);
bcx
.build
.Store
(
src
,
bound_target
);
// Copy expr values into boxed bindings.
let
int
i
=
0
;
i
=
0u
;
auto
bindings
=
bcx
.build
.GEP
(
closure
,
vec
(
C_int
(
0
),
C_int
(
abi
.closure_elt_bindings
)));
for
(
ValueRef
v
in
bound_vals
)
{
auto
bound
=
bcx
.build
.GEP
(
bindings
,
vec
(
C_int
(
0
),
C_int
(
i
)));
vec
(
C_int
(
0
),
C_int
(
i
as
int
)));
bcx
=
copy_ty
(
r
.bcx
,
INIT
,
bound
,
v
,
bound_tys
.
(
i
))
.bcx
;
i
+=
1
;
i
+=
1u
;
}
// If necessary, copy tydescs describing type parameters into the
// appropriate slot in the closure.
alt
(
f_res
.generic
)
{
case
(
none
[
generic_info
])
{
/* nothing to do */
}
case
(
some
[
generic_info
](
?
ginfo
))
{
auto
ty_params_slot
=
bcx
.build
.GEP
(
closure
,
vec
(
C_int
(
0
),
C_int
(
abi
.closure_elt_ty_params
)));
auto
i
=
0
;
for
(
ValueRef
td
in
ginfo
.tydescs
)
{
auto
ty_param_slot
=
bcx
.build
.GEP
(
ty_params_slot
,
vec
(
C_int
(
0
),
C_int
(
i
)));
bcx
.build
.Store
(
td
,
ty_param_slot
);
i
+=
1
;
}
}
}
// Make thunk and store thunk-ptr in outer pair's code slot.
...
...
@@ -2910,8 +2986,9 @@ fn trans_bind(@block_ctxt cx, @ast.expr f,
let
@
ty
.t
pair_ty
=
node_ann_type
(
cx
.fcx.ccx
,
ann
);
let
ValueRef
llthunk
=
trans_bind_thunk
(
cx
.fcx.ccx
,
pair_ty
,
ty
.expr_ty
(
f
),
args
,
llclosure_ty
,
bound_tys
);
trans_bind_thunk
(
cx
.fcx.ccx
,
pair_ty
,
outgoing_fty
,
args
,
llclosure_ty
,
bound_tys
,
ty_param_count
);
bcx
.build
.Store
(
llthunk
,
pair_code
);
...
...
src/comp/middle/ty.rs
浏览文件 @
b4d6589e
...
...
@@ -598,12 +598,14 @@ fn ty_fn_args(@t fty) -> vec[arg] {
case
(
ty
.ty_fn
(
_
,
?
a
,
_
))
{
ret
a
;
}
case
(
ty
.ty_native_fn
(
?
a
,
_
))
{
ret
a
;
}
}
fail
;
}
fn
ty_fn_proto
(
@
t
fty
)
->
ast
.proto
{
alt
(
fty
.struct
)
{
case
(
ty
.ty_fn
(
?
p
,
_
,
_
))
{
ret
p
;
}
}
fail
;
}
fn
ty_fn_ret
(
@
t
fty
)
->
@
t
{
...
...
@@ -611,6 +613,7 @@ fn ty_fn_ret(@t fty) -> @t {
case
(
ty
.ty_fn
(
_
,
_
,
?
r
))
{
ret
r
;
}
case
(
ty
.ty_native_fn
(
_
,
?
r
))
{
ret
r
;
}
}
fail
;
}
fn
is_fn_ty
(
@
t
fty
)
->
bool
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录