Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
d9277b16
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,发现更多精彩内容 >>
提交
d9277b16
编写于
3月 09, 2016
作者:
E
Eduard Burtescu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
trans: Make everything used from within at_start Builder-friendly.
上级
82fad1df
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
169 addition
and
142 deletion
+169
-142
src/librustc_trans/trans/abi.rs
src/librustc_trans/trans/abi.rs
+4
-7
src/librustc_trans/trans/adt.rs
src/librustc_trans/trans/adt.rs
+35
-18
src/librustc_trans/trans/base.rs
src/librustc_trans/trans/base.rs
+33
-20
src/librustc_trans/trans/closure.rs
src/librustc_trans/trans/closure.rs
+2
-2
src/librustc_trans/trans/common.rs
src/librustc_trans/trans/common.rs
+4
-0
src/librustc_trans/trans/glue.rs
src/librustc_trans/trans/glue.rs
+20
-22
src/librustc_trans/trans/intrinsic.rs
src/librustc_trans/trans/intrinsic.rs
+4
-2
src/librustc_trans/trans/mir/block.rs
src/librustc_trans/trans/mir/block.rs
+3
-7
src/librustc_trans/trans/mir/lvalue.rs
src/librustc_trans/trans/mir/lvalue.rs
+22
-11
src/librustc_trans/trans/mir/mod.rs
src/librustc_trans/trans/mir/mod.rs
+33
-36
src/librustc_trans/trans/mir/operand.rs
src/librustc_trans/trans/mir/operand.rs
+3
-6
src/librustc_trans/trans/mir/rvalue.rs
src/librustc_trans/trans/mir/rvalue.rs
+6
-11
未找到文件。
src/librustc_trans/trans/abi.rs
浏览文件 @
d9277b16
...
...
@@ -10,9 +10,8 @@
use
llvm
::{
self
,
ValueRef
};
use
trans
::
base
;
use
trans
::
build
::
B
;
use
trans
::
builder
::
Builder
;
use
trans
::
common
::{
type_is_fat_ptr
,
Block
};
use
trans
::
common
::{
type_is_fat_ptr
,
Block
AndBuilder
};
use
trans
::
context
::
CrateContext
;
use
trans
::
cabi_x86
;
use
trans
::
cabi_x86_64
;
...
...
@@ -169,18 +168,16 @@ pub fn store(&self, b: &Builder, mut val: ValueRef, dst: ValueRef) {
}
}
pub
fn
store_fn_arg
(
&
self
,
bcx
:
Block
,
idx
:
&
mut
usize
,
dst
:
ValueRef
)
{
pub
fn
store_fn_arg
(
&
self
,
bcx
:
&
BlockAndBuilder
,
idx
:
&
mut
usize
,
dst
:
ValueRef
)
{
if
self
.pad
.is_some
()
{
*
idx
+=
1
;
}
if
self
.is_ignore
()
{
return
;
}
let
val
=
llvm
::
get_param
(
bcx
.fcx.llfn
,
*
idx
as
c_uint
);
let
val
=
llvm
::
get_param
(
bcx
.fcx
()
.llfn
,
*
idx
as
c_uint
);
*
idx
+=
1
;
if
!
bcx
.unreachable
.get
()
{
self
.store
(
&
B
(
bcx
),
val
,
dst
);
}
self
.store
(
bcx
,
val
,
dst
);
}
}
...
...
src/librustc_trans/trans/adt.rs
浏览文件 @
d9277b16
...
...
@@ -1065,6 +1065,15 @@ pub fn num_args(r: &Repr, discr: Disr) -> usize {
/// Access a field, at a point when the value's case is known.
pub
fn
trans_field_ptr
<
'blk
,
'tcx
>
(
bcx
:
Block
<
'blk
,
'tcx
>
,
r
:
&
Repr
<
'tcx
>
,
val
:
MaybeSizedValue
,
discr
:
Disr
,
ix
:
usize
)
->
ValueRef
{
trans_field_ptr_builder
(
&
bcx
.build
(),
r
,
val
,
discr
,
ix
)
}
/// Access a field, at a point when the value's case is known.
pub
fn
trans_field_ptr_builder
<
'blk
,
'tcx
>
(
bcx
:
&
BlockAndBuilder
<
'blk
,
'tcx
>
,
r
:
&
Repr
<
'tcx
>
,
val
:
MaybeSizedValue
,
discr
:
Disr
,
ix
:
usize
)
->
ValueRef
{
// Note: if this ever needs to generate conditionals (e.g., if we
// decide to do some kind of cdr-coding-like non-unique repr
// someday), it will need to return a possibly-new bcx as well.
...
...
@@ -1087,13 +1096,15 @@ pub fn trans_field_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>,
assert_eq!
(
machine
::
llsize_of_alloc
(
bcx
.ccx
(),
ty
),
0
);
// The contents of memory at this pointer can't matter, but use
// the value that's "reasonable" in case of pointer comparison.
PointerCast
(
bcx
,
val
.value
,
ty
.ptr_to
())
if
bcx
.is_unreachable
()
{
return
C_undef
(
ty
.ptr_to
());
}
bcx
.pointercast
(
val
.value
,
ty
.ptr_to
())
}
RawNullablePointer
{
nndiscr
,
nnty
,
..
}
=>
{
assert_eq!
(
ix
,
0
);
assert_eq!
(
discr
,
nndiscr
);
let
ty
=
type_of
::
type_of
(
bcx
.ccx
(),
nnty
);
PointerCast
(
bcx
,
val
.value
,
ty
.ptr_to
())
if
bcx
.is_unreachable
()
{
return
C_undef
(
ty
.ptr_to
());
}
bcx
.pointercast
(
val
.value
,
ty
.ptr_to
())
}
StructWrappedNullablePointer
{
ref
nonnull
,
nndiscr
,
..
}
=>
{
assert_eq!
(
discr
,
nndiscr
);
...
...
@@ -1102,33 +1113,39 @@ pub fn trans_field_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>,
}
}
pub
fn
struct_field_ptr
<
'blk
,
'tcx
>
(
bcx
:
Block
<
'blk
,
'tcx
>
,
st
:
&
Struct
<
'tcx
>
,
val
:
MaybeSizedValue
,
ix
:
usize
,
needs_cast
:
bool
)
->
ValueRef
{
fn
struct_field_ptr
<
'blk
,
'tcx
>
(
bcx
:
&
BlockAndBuilder
<
'blk
,
'tcx
>
,
st
:
&
Struct
<
'tcx
>
,
val
:
MaybeSizedValue
,
ix
:
usize
,
needs_cast
:
bool
)
->
ValueRef
{
let
ccx
=
bcx
.ccx
();
let
fty
=
st
.fields
[
ix
];
let
ll_fty
=
type_of
::
in_memory_type_of
(
bcx
.ccx
(),
fty
);
if
bcx
.is_unreachable
()
{
return
C_undef
(
ll_fty
.ptr_to
());
}
let
ptr_val
=
if
needs_cast
{
let
fields
=
st
.fields
.iter
()
.map
(|
&
ty
|
{
type_of
::
in_memory_type_of
(
ccx
,
ty
)
})
.collect
::
<
Vec
<
_
>>
();
let
real_ty
=
Type
::
struct_
(
ccx
,
&
fields
[
..
],
st
.packed
);
PointerCast
(
bcx
,
val
.value
,
real_ty
.ptr_to
())
bcx
.pointercast
(
val
.value
,
real_ty
.ptr_to
())
}
else
{
val
.value
};
let
fty
=
st
.fields
[
ix
];
// Simple case - we can just GEP the field
// * First field - Always aligned properly
// * Packed struct - There is no alignment padding
// * Field is sized - pointer is properly aligned already
if
ix
==
0
||
st
.packed
||
type_is_sized
(
bcx
.tcx
(),
fty
)
{
return
StructGEP
(
bcx
,
ptr_val
,
ix
);
return
bcx
.struct_gep
(
ptr_val
,
ix
);
}
// If the type of the last field is [T] or str, then we don't need to do
// any adjusments
match
fty
.sty
{
ty
::
TySlice
(
..
)
|
ty
::
TyStr
=>
{
return
StructGEP
(
bcx
,
ptr_val
,
ix
);
return
bcx
.struct_gep
(
ptr_val
,
ix
);
}
_
=>
()
}
...
...
@@ -1137,7 +1154,7 @@ pub fn struct_field_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, st: &Struct<'tcx>, v
if
!
val
.has_meta
()
{
debug!
(
"Unsized field `{}`, of `{:?}` has no metadata for adjustment"
,
ix
,
Value
(
ptr_val
));
return
StructGEP
(
bcx
,
ptr_val
,
ix
);
return
bcx
.struct_gep
(
ptr_val
,
ix
);
}
let
dbloc
=
DebugLoc
::
None
;
...
...
@@ -1178,22 +1195,21 @@ pub fn struct_field_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, st: &Struct<'tcx>, v
// (unaligned offset + (align - 1)) & -align
// Calculate offset
let
align_sub_1
=
Sub
(
bcx
,
align
,
C_uint
(
bcx
.ccx
(),
1u64
),
dbloc
);
let
offset
=
And
(
bcx
,
Add
(
bcx
,
unaligned_offset
,
align_sub_1
,
dbloc
),
Neg
(
bcx
,
align
,
dbloc
),
dbloc
);
dbloc
.apply
(
bcx
.fcx
());
let
align_sub_1
=
bcx
.sub
(
align
,
C_uint
(
bcx
.ccx
(),
1u64
));
let
offset
=
bcx
.and
(
bcx
.add
(
unaligned_offset
,
align_sub_1
),
bcx
.neg
(
align
));
debug!
(
"struct_field_ptr: DST field offset: {:?}"
,
Value
(
offset
));
// Cast and adjust pointer
let
byte_ptr
=
PointerCast
(
bcx
,
ptr_val
,
Type
::
i8p
(
bcx
.ccx
()));
let
byte_ptr
=
GEP
(
bcx
,
byte_ptr
,
&
[
offset
]);
let
byte_ptr
=
bcx
.pointercast
(
ptr_val
,
Type
::
i8p
(
bcx
.ccx
()));
let
byte_ptr
=
bcx
.gep
(
byte_ptr
,
&
[
offset
]);
// Finally, cast back to the type expected
let
ll_fty
=
type_of
::
in_memory_type_of
(
bcx
.ccx
(),
fty
);
debug!
(
"struct_field_ptr: Field type is {:?}"
,
ll_fty
);
PointerCast
(
bcx
,
byte_ptr
,
ll_fty
.ptr_to
())
bcx
.pointercast
(
byte_ptr
,
ll_fty
.ptr_to
())
}
pub
fn
fold_variants
<
'blk
,
'tcx
,
F
>
(
bcx
:
Block
<
'blk
,
'tcx
>
,
...
...
@@ -1284,7 +1300,8 @@ pub fn trans_drop_flag_ptr<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
}
));
bcx
=
fold_variants
(
bcx
,
r
,
val
,
|
variant_cx
,
st
,
value
|
{
let
ptr
=
struct_field_ptr
(
variant_cx
,
st
,
MaybeSizedValue
::
sized
(
value
),
let
ptr
=
struct_field_ptr
(
&
variant_cx
.build
(),
st
,
MaybeSizedValue
::
sized
(
value
),
(
st
.fields
.len
()
-
1
),
false
);
datum
::
Datum
::
new
(
ptr
,
ptr_ty
,
datum
::
Lvalue
::
new
(
"adt::trans_drop_flag_ptr"
))
.store_to
(
variant_cx
,
scratch
.val
)
...
...
src/librustc_trans/trans/base.rs
浏览文件 @
d9277b16
...
...
@@ -911,33 +911,43 @@ pub fn load_if_immediate<'blk, 'tcx>(cx: Block<'blk, 'tcx>, v: ValueRef, t: Ty<'
/// differs from the type used for SSA values. Also handles various special cases where the type
/// gives us better information about what we are loading.
pub
fn
load_ty
<
'blk
,
'tcx
>
(
cx
:
Block
<
'blk
,
'tcx
>
,
ptr
:
ValueRef
,
t
:
Ty
<
'tcx
>
)
->
ValueRef
{
if
cx
.unreachable
.get
()
||
type_is_zero_size
(
cx
.ccx
(),
t
)
{
if
cx
.unreachable
.get
()
{
return
C_undef
(
type_of
::
type_of
(
cx
.ccx
(),
t
));
}
load_ty_builder
(
&
B
(
cx
),
ptr
,
t
)
}
pub
fn
load_ty_builder
<
'a
,
'tcx
>
(
b
:
&
Builder
<
'a
,
'tcx
>
,
ptr
:
ValueRef
,
t
:
Ty
<
'tcx
>
)
->
ValueRef
{
let
ccx
=
b
.ccx
;
if
type_is_zero_size
(
ccx
,
t
)
{
return
C_undef
(
type_of
::
type_of
(
ccx
,
t
));
}
unsafe
{
let
global
=
llvm
::
LLVMIsAGlobalVariable
(
ptr
);
if
!
global
.is_null
()
&&
llvm
::
LLVMIsGlobalConstant
(
global
)
==
llvm
::
True
{
let
val
=
llvm
::
LLVMGetInitializer
(
global
);
if
!
val
.is_null
()
{
return
to_immediate
(
cx
,
val
,
t
);
if
t
.is_bool
()
{
return
llvm
::
LLVMConstTrunc
(
val
,
Type
::
i1
(
ccx
)
.to_ref
());
}
return
val
;
}
}
}
let
val
=
if
t
.is_bool
()
{
LoadRangeAssert
(
cx
,
ptr
,
0
,
2
,
llvm
::
False
)
if
t
.is_bool
()
{
b
.trunc
(
b
.load_range_assert
(
ptr
,
0
,
2
,
llvm
::
False
),
Type
::
i1
(
ccx
)
)
}
else
if
t
.is_char
()
{
// a char is a Unicode codepoint, and so takes values from 0
// to 0x10FFFF inclusive only.
LoadRangeAssert
(
cx
,
ptr
,
0
,
0x10FFFF
+
1
,
llvm
::
False
)
}
else
if
(
t
.is_region_ptr
()
||
t
.is_unique
())
&&
!
common
::
type_is_fat_ptr
(
cx
.tcx
(),
t
)
{
LoadNonNull
(
cx
,
ptr
)
b
.load_range_assert
(
ptr
,
0
,
0x10FFFF
+
1
,
llvm
::
False
)
}
else
if
(
t
.is_region_ptr
()
||
t
.is_unique
())
&&
!
common
::
type_is_fat_ptr
(
ccx
.tcx
(),
t
)
{
b
.load_nonnull
(
ptr
)
}
else
{
Load
(
cx
,
ptr
)
};
to_immediate
(
cx
,
val
,
t
)
b
.load
(
ptr
)
}
}
/// Helper for storing values in memory. Does the necessary conversion if the in-memory type
...
...
@@ -1644,13 +1654,14 @@ fn bind_args(&'blk self,
uninit_reason
,
arg_scope_id
,
|
bcx
,
dst
|
{
debug!
(
"FunctionContext::bind_args: {:?}: {:?}"
,
hir_arg
,
arg_ty
);
let
b
=
&
bcx
.build
();
if
common
::
type_is_fat_ptr
(
bcx
.tcx
(),
arg_ty
)
{
let
meta
=
&
self
.fn_ty.args
[
idx
];
idx
+=
1
;
arg
.store_fn_arg
(
b
cx
,
&
mut
llarg_idx
,
expr
::
get_dataptr
(
bcx
,
dst
));
meta
.store_fn_arg
(
b
cx
,
&
mut
llarg_idx
,
expr
::
get_meta
(
bcx
,
dst
));
arg
.store_fn_arg
(
b
,
&
mut
llarg_idx
,
expr
::
get_dataptr
(
bcx
,
dst
));
meta
.store_fn_arg
(
b
,
&
mut
llarg_idx
,
expr
::
get_meta
(
bcx
,
dst
));
}
else
{
arg
.store_fn_arg
(
b
cx
,
&
mut
llarg_idx
,
dst
);
arg
.store_fn_arg
(
b
,
&
mut
llarg_idx
,
dst
);
}
bcx
}))
...
...
@@ -1672,13 +1683,14 @@ fn bind_args(&'blk self,
for
(
j
,
&
tupled_arg_ty
)
in
tupled_arg_tys
.iter
()
.enumerate
()
{
let
dst
=
StructGEP
(
bcx
,
llval
,
j
);
let
arg
=
&
self
.fn_ty.args
[
idx
];
let
b
=
&
bcx
.build
();
if
common
::
type_is_fat_ptr
(
bcx
.tcx
(),
tupled_arg_ty
)
{
let
meta
=
&
self
.fn_ty.args
[
idx
];
idx
+=
1
;
arg
.store_fn_arg
(
b
cx
,
&
mut
llarg_idx
,
expr
::
get_dataptr
(
bcx
,
dst
));
meta
.store_fn_arg
(
b
cx
,
&
mut
llarg_idx
,
expr
::
get_meta
(
bcx
,
dst
));
arg
.store_fn_arg
(
b
,
&
mut
llarg_idx
,
expr
::
get_dataptr
(
bcx
,
dst
));
meta
.store_fn_arg
(
b
,
&
mut
llarg_idx
,
expr
::
get_meta
(
bcx
,
dst
));
}
else
{
arg
.store_fn_arg
(
b
cx
,
&
mut
llarg_idx
,
dst
);
arg
.store_fn_arg
(
b
,
&
mut
llarg_idx
,
dst
);
}
}
bcx
...
...
@@ -2024,13 +2036,14 @@ pub fn trans_ctor_shim<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
let
lldestptr
=
adt
::
trans_field_ptr
(
bcx
,
&
repr
,
dest_val
,
Disr
::
from
(
disr
),
i
);
let
arg
=
&
fcx
.fn_ty.args
[
arg_idx
];
arg_idx
+=
1
;
let
b
=
&
bcx
.build
();
if
common
::
type_is_fat_ptr
(
bcx
.tcx
(),
arg_ty
)
{
let
meta
=
&
fcx
.fn_ty.args
[
arg_idx
];
arg_idx
+=
1
;
arg
.store_fn_arg
(
b
cx
,
&
mut
llarg_idx
,
expr
::
get_dataptr
(
bcx
,
lldestptr
));
meta
.store_fn_arg
(
b
cx
,
&
mut
llarg_idx
,
expr
::
get_meta
(
bcx
,
lldestptr
));
arg
.store_fn_arg
(
b
,
&
mut
llarg_idx
,
expr
::
get_dataptr
(
bcx
,
lldestptr
));
meta
.store_fn_arg
(
b
,
&
mut
llarg_idx
,
expr
::
get_meta
(
bcx
,
lldestptr
));
}
else
{
arg
.store_fn_arg
(
b
cx
,
&
mut
llarg_idx
,
lldestptr
);
arg
.store_fn_arg
(
b
,
&
mut
llarg_idx
,
lldestptr
);
}
}
adt
::
trans_set_discr
(
bcx
,
&
repr
,
dest
,
disr
);
...
...
src/librustc_trans/trans/closure.rs
浏览文件 @
d9277b16
...
...
@@ -53,7 +53,7 @@ fn load_closure_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let
llenv
=
if
kind
==
ty
::
ClosureKind
::
FnOnce
&&
!
env_arg
.is_indirect
()
{
let
closure_ty
=
node_id_type
(
bcx
,
id
);
let
llenv
=
rvalue_scratch_datum
(
bcx
,
closure_ty
,
"closure_env"
)
.val
;
env_arg
.store_fn_arg
(
bcx
,
&
mut
env_idx
,
llenv
);
env_arg
.store_fn_arg
(
&
bcx
.build
()
,
&
mut
env_idx
,
llenv
);
llenv
}
else
{
get_param
(
bcx
.fcx.llfn
,
env_idx
as
c_uint
)
...
...
@@ -410,7 +410,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
InitAlloca
::
Dropped
,
self_scope_id
,
|
bcx
,
llval
|
{
let
mut
llarg_idx
=
self_idx
;
env_arg
.store_fn_arg
(
bcx
,
&
mut
llarg_idx
,
llval
);
env_arg
.store_fn_arg
(
&
bcx
.build
()
,
&
mut
llarg_idx
,
llval
);
bcx
.fcx
.schedule_lifetime_end
(
self_scope_id
,
llval
);
bcx
}))
.val
...
...
src/librustc_trans/trans/common.rs
浏览文件 @
d9277b16
...
...
@@ -688,6 +688,10 @@ pub fn at_start<F, R>(&self, f: F) -> R
// Methods delegated to bcx
pub
fn
is_unreachable
(
&
self
)
->
bool
{
self
.bcx.unreachable
.get
()
}
pub
fn
ccx
(
&
self
)
->
&
'blk
CrateContext
<
'blk
,
'tcx
>
{
self
.bcx
.ccx
()
}
...
...
src/librustc_trans/trans/glue.rs
浏览文件 @
d9277b16
...
...
@@ -371,7 +371,8 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
bcx
.fcx
.pop_and_trans_custom_cleanup_scope
(
bcx
,
contents_scope
)
}
pub
fn
size_and_align_of_dst
<
'blk
,
'tcx
>
(
bcx
:
Block
<
'blk
,
'tcx
>
,
t
:
Ty
<
'tcx
>
,
info
:
ValueRef
)
pub
fn
size_and_align_of_dst
<
'blk
,
'tcx
>
(
bcx
:
&
BlockAndBuilder
<
'blk
,
'tcx
>
,
t
:
Ty
<
'tcx
>
,
info
:
ValueRef
)
->
(
ValueRef
,
ValueRef
)
{
debug!
(
"calculate size of DST: {}; with lost info: {:?}"
,
t
,
Value
(
info
));
...
...
@@ -385,6 +386,10 @@ pub fn size_and_align_of_dst<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: Ty<'tcx>, in
let
align
=
C_uint
(
bcx
.ccx
(),
align
);
return
(
size
,
align
);
}
if
bcx
.is_unreachable
()
{
let
llty
=
Type
::
int
(
bcx
.ccx
());
return
(
C_undef
(
llty
),
C_undef
(
llty
));
}
match
t
.sty
{
ty
::
TyStruct
(
def
,
substs
)
=>
{
let
ccx
=
bcx
.ccx
();
...
...
@@ -407,8 +412,6 @@ pub fn size_and_align_of_dst<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: Ty<'tcx>, in
let
field_ty
=
monomorphize
::
field_ty
(
bcx
.tcx
(),
substs
,
last_field
);
let
(
unsized_size
,
unsized_align
)
=
size_and_align_of_dst
(
bcx
,
field_ty
,
info
);
let
dbloc
=
DebugLoc
::
None
;
// FIXME (#26403, #27023): We should be adding padding
// to `sized_size` (to accommodate the `unsized_align`
// required of the unsized field that follows) before
...
...
@@ -417,14 +420,14 @@ pub fn size_and_align_of_dst<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: Ty<'tcx>, in
// here. But this is where the add would go.)
// Return the sum of sizes and max of aligns.
let
mut
size
=
Add
(
bcx
,
sized_size
,
unsized_size
,
dbloc
);
let
mut
size
=
bcx
.add
(
sized_size
,
unsized_size
);
// Issue #27023: If there is a drop flag, *now* we add 1
// to the size. (We can do this without adding any
// padding because drop flags do not have any alignment
// constraints.)
if
sizing_type
.needs_drop_flag
()
{
size
=
Add
(
bcx
,
size
,
C_uint
(
bcx
.ccx
(),
1_u64
),
dbloc
);
size
=
bcx
.add
(
size
,
C_uint
(
bcx
.ccx
(),
1_u64
)
);
}
// Choose max of two known alignments (combined value must
...
...
@@ -435,14 +438,9 @@ pub fn size_and_align_of_dst<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: Ty<'tcx>, in
// pick the correct alignment statically.
C_uint
(
ccx
,
std
::
cmp
::
max
(
sized_align
,
unsized_align
))
}
_
=>
Select
(
bcx
,
ICmp
(
bcx
,
llvm
::
IntUGT
,
sized_align
,
unsized_align
,
dbloc
),
sized_align
,
unsized_align
)
_
=>
bcx
.select
(
bcx
.icmp
(
llvm
::
IntUGT
,
sized_align
,
unsized_align
),
sized_align
,
unsized_align
)
};
// Issue #27023: must add any necessary padding to `size`
...
...
@@ -456,19 +454,18 @@ pub fn size_and_align_of_dst<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: Ty<'tcx>, in
//
// `(size + (align-1)) & -align`
let
addend
=
Sub
(
bcx
,
align
,
C_uint
(
bcx
.ccx
(),
1_u64
),
dbloc
);
let
size
=
And
(
bcx
,
Add
(
bcx
,
size
,
addend
,
dbloc
),
Neg
(
bcx
,
align
,
dbloc
),
dbloc
);
let
addend
=
bcx
.sub
(
align
,
C_uint
(
bcx
.ccx
(),
1_u64
));
let
size
=
bcx
.and
(
bcx
.add
(
size
,
addend
),
bcx
.neg
(
align
));
(
size
,
align
)
}
ty
::
TyTrait
(
..
)
=>
{
// info points to the vtable and the second entry in the vtable is the
// dynamic size of the object.
let
info
=
PointerCast
(
bcx
,
info
,
Type
::
int
(
bcx
.ccx
())
.ptr_to
());
let
size_ptr
=
GEPi
(
bcx
,
info
,
&
[
1
]);
let
align_ptr
=
GEPi
(
bcx
,
info
,
&
[
2
]);
(
Load
(
bcx
,
size_ptr
),
Load
(
bcx
,
align_ptr
))
let
info
=
bcx
.pointercast
(
info
,
Type
::
int
(
bcx
.ccx
())
.ptr_to
());
let
size_ptr
=
bcx
.gepi
(
info
,
&
[
1
]);
let
align_ptr
=
bcx
.gepi
(
info
,
&
[
2
]);
(
bcx
.load
(
size_ptr
),
bcx
.load
(
align_ptr
))
}
ty
::
TySlice
(
_
)
|
ty
::
TyStr
=>
{
let
unit_ty
=
t
.sequence_element_type
(
bcx
.tcx
());
...
...
@@ -477,7 +474,7 @@ pub fn size_and_align_of_dst<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: Ty<'tcx>, in
let
llunit_ty
=
sizing_type_of
(
bcx
.ccx
(),
unit_ty
);
let
unit_align
=
llalign_of_min
(
bcx
.ccx
(),
llunit_ty
);
let
unit_size
=
llsize_of_alloc
(
bcx
.ccx
(),
llunit_ty
);
(
Mul
(
bcx
,
info
,
C_uint
(
bcx
.ccx
(),
unit_size
),
DebugLoc
::
None
),
(
bcx
.mul
(
info
,
C_uint
(
bcx
.ccx
(),
unit_size
)
),
C_uint
(
bcx
.ccx
(),
unit_align
))
}
_
=>
bcx
.sess
()
.bug
(
&
format!
(
"Unexpected unsized type, found {}"
,
t
))
...
...
@@ -522,7 +519,8 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, g: DropGlueK
let
bcx
=
drop_ty
(
bcx
,
v0
,
content_ty
,
DebugLoc
::
None
);
let
info
=
expr
::
get_meta
(
bcx
,
v0
);
let
info
=
Load
(
bcx
,
info
);
let
(
llsize
,
llalign
)
=
size_and_align_of_dst
(
bcx
,
content_ty
,
info
);
let
(
llsize
,
llalign
)
=
size_and_align_of_dst
(
&
bcx
.build
(),
content_ty
,
info
);
// `Box<ZeroSizeType>` does not allocate.
let
needs_free
=
ICmp
(
bcx
,
...
...
src/librustc_trans/trans/intrinsic.rs
浏览文件 @
d9277b16
...
...
@@ -430,7 +430,8 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
(
_
,
"size_of_val"
)
=>
{
let
tp_ty
=
*
substs
.types
.get
(
FnSpace
,
0
);
if
!
type_is_sized
(
tcx
,
tp_ty
)
{
let
(
llsize
,
_
)
=
glue
::
size_and_align_of_dst
(
bcx
,
tp_ty
,
llargs
[
1
]);
let
(
llsize
,
_
)
=
glue
::
size_and_align_of_dst
(
&
bcx
.build
(),
tp_ty
,
llargs
[
1
]);
llsize
}
else
{
let
lltp_ty
=
type_of
::
type_of
(
ccx
,
tp_ty
);
...
...
@@ -444,7 +445,8 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
(
_
,
"min_align_of_val"
)
=>
{
let
tp_ty
=
*
substs
.types
.get
(
FnSpace
,
0
);
if
!
type_is_sized
(
tcx
,
tp_ty
)
{
let
(
_
,
llalign
)
=
glue
::
size_and_align_of_dst
(
bcx
,
tp_ty
,
llargs
[
1
]);
let
(
_
,
llalign
)
=
glue
::
size_and_align_of_dst
(
&
bcx
.build
(),
tp_ty
,
llargs
[
1
]);
llalign
}
else
{
C_uint
(
ccx
,
type_of
::
align_of
(
ccx
,
tp_ty
))
...
...
src/librustc_trans/trans/mir/block.rs
浏览文件 @
d9277b16
...
...
@@ -26,7 +26,7 @@
use
trans
::
type_
::
Type
;
use
super
::{
MirContext
,
drop
};
use
super
::
lvalue
::
LvalueRef
;
use
super
::
lvalue
::
{
LvalueRef
,
load_fat_ptr
}
;
use
super
::
operand
::
OperandRef
;
use
super
::
operand
::
OperandValue
::{
self
,
FatPtr
,
Immediate
,
Ref
};
...
...
@@ -478,13 +478,9 @@ fn trans_arguments_untupled(&mut self,
let
base_repr
=
adt
::
represent_type
(
bcx
.ccx
(),
lv_ty
);
let
base
=
adt
::
MaybeSizedValue
::
sized
(
lv
.llval
);
for
(
n
,
&
ty
)
in
result_types
.iter
()
.enumerate
()
{
let
ptr
=
bcx
.with_block
(|
bcx
|
{
adt
::
trans_field_ptr
(
bcx
,
&
base_repr
,
base
,
Disr
(
0
),
n
)
});
let
ptr
=
adt
::
trans_field_ptr_builder
(
bcx
,
&
base_repr
,
base
,
Disr
(
0
),
n
);
let
val
=
if
common
::
type_is_fat_ptr
(
bcx
.tcx
(),
ty
)
{
let
(
lldata
,
llextra
)
=
bcx
.with_block
(|
bcx
|
{
base
::
load_fat_ptr
(
bcx
,
ptr
,
ty
)
});
let
(
lldata
,
llextra
)
=
load_fat_ptr
(
bcx
,
ptr
);
FatPtr
(
lldata
,
llextra
)
}
else
{
// Don't bother loading the value, trans_argument will.
...
...
src/librustc_trans/trans/mir/lvalue.rs
浏览文件 @
d9277b16
...
...
@@ -12,8 +12,10 @@
use
rustc
::
middle
::
ty
::{
self
,
Ty
,
TypeFoldable
};
use
rustc
::
mir
::
repr
as
mir
;
use
rustc
::
mir
::
tcx
::
LvalueTy
;
use
trans
::
abi
;
use
trans
::
adt
;
use
trans
::
base
;
use
trans
::
builder
::
Builder
;
use
trans
::
common
::{
self
,
BlockAndBuilder
};
use
trans
::
consts
;
use
trans
::
machine
;
...
...
@@ -54,6 +56,18 @@ pub fn alloca<'bcx>(bcx: &BlockAndBuilder<'bcx, 'tcx>,
}
}
pub
fn
get_meta
(
b
:
&
Builder
,
fat_ptr
:
ValueRef
)
->
ValueRef
{
b
.struct_gep
(
fat_ptr
,
abi
::
FAT_PTR_EXTRA
)
}
pub
fn
get_dataptr
(
b
:
&
Builder
,
fat_ptr
:
ValueRef
)
->
ValueRef
{
b
.struct_gep
(
fat_ptr
,
abi
::
FAT_PTR_ADDR
)
}
pub
fn
load_fat_ptr
(
b
:
&
Builder
,
fat_ptr
:
ValueRef
)
->
(
ValueRef
,
ValueRef
)
{
(
b
.load
(
get_dataptr
(
b
,
fat_ptr
)),
b
.load
(
get_meta
(
b
,
fat_ptr
)))
}
impl
<
'bcx
,
'tcx
>
MirContext
<
'bcx
,
'tcx
>
{
pub
fn
lvalue_len
(
&
mut
self
,
bcx
:
&
BlockAndBuilder
<
'bcx
,
'tcx
>
,
...
...
@@ -130,14 +144,12 @@ pub fn trans_lvalue(&mut self,
let
(
llprojected
,
llextra
)
=
match
projection
.elem
{
mir
::
ProjectionElem
::
Deref
=>
{
let
base_ty
=
tr_base
.ty
.to_ty
(
tcx
);
bcx
.with_block
(|
bcx
|
{
if
common
::
type_is_sized
(
tcx
,
projected_ty
.to_ty
(
tcx
))
{
(
base
::
load_ty
(
bcx
,
tr_base
.llval
,
base_ty
),
ptr
::
null_mut
())
}
else
{
base
::
load_fat_ptr
(
bcx
,
tr_base
.llval
,
base_ty
)
}
})
if
common
::
type_is_sized
(
tcx
,
projected_ty
.to_ty
(
tcx
))
{
(
base
::
load_ty_builder
(
bcx
,
tr_base
.llval
,
base_ty
),
ptr
::
null_mut
())
}
else
{
load_fat_ptr
(
bcx
,
tr_base
.llval
)
}
}
mir
::
ProjectionElem
::
Field
(
ref
field
,
_
)
=>
{
let
base_ty
=
tr_base
.ty
.to_ty
(
tcx
);
...
...
@@ -153,9 +165,8 @@ pub fn trans_lvalue(&mut self,
}
else
{
adt
::
MaybeSizedValue
::
unsized_
(
tr_base
.llval
,
tr_base
.llextra
)
};
let
llprojected
=
bcx
.with_block
(|
bcx
|
{
adt
::
trans_field_ptr
(
bcx
,
&
base_repr
,
base
,
Disr
(
discr
),
field
.index
())
});
let
llprojected
=
adt
::
trans_field_ptr_builder
(
bcx
,
&
base_repr
,
base
,
Disr
(
discr
),
field
.index
());
let
llextra
=
if
is_sized
{
ptr
::
null_mut
()
}
else
{
...
...
src/librustc_trans/trans/mir/mod.rs
浏览文件 @
d9277b16
...
...
@@ -14,14 +14,12 @@
use
rustc
::
mir
::
repr
as
mir
;
use
rustc
::
mir
::
tcx
::
LvalueTy
;
use
trans
::
base
;
use
trans
::
build
;
use
trans
::
common
::{
self
,
Block
,
BlockAndBuilder
,
FunctionContext
};
use
trans
::
expr
;
use
std
::
ops
::
Deref
;
use
std
::
rc
::
Rc
;
use
self
::
lvalue
::
LvalueRef
;
use
self
::
lvalue
::
{
LvalueRef
,
get_dataptr
,
get_meta
}
;
use
self
::
operand
::
OperandRef
;
#[derive(Clone)]
...
...
@@ -185,26 +183,25 @@ fn arg_value_refs<'bcx, 'tcx>(bcx: &BlockAndBuilder<'bcx, 'tcx>,
_
=>
unreachable!
(
"spread argument isn't a tuple?!"
)
};
let
llval
=
bcx
.with_block
(|
bcx
|
{
let
lltemp
=
base
::
alloc_ty
(
bcx
,
arg_ty
,
&
format!
(
"arg{}"
,
arg_index
));
for
(
i
,
&
tupled_arg_ty
)
in
tupled_arg_tys
.iter
()
.enumerate
()
{
let
dst
=
build
::
StructGEP
(
bcx
,
lltemp
,
i
);
let
arg
=
&
fcx
.fn_ty.args
[
idx
];
let
lltemp
=
bcx
.with_block
(|
bcx
|
{
base
::
alloc_ty
(
bcx
,
arg_ty
,
&
format!
(
"arg{}"
,
arg_index
))
});
for
(
i
,
&
tupled_arg_ty
)
in
tupled_arg_tys
.iter
()
.enumerate
()
{
let
dst
=
bcx
.struct_gep
(
lltemp
,
i
);
let
arg
=
&
fcx
.fn_ty.args
[
idx
];
idx
+=
1
;
if
common
::
type_is_fat_ptr
(
tcx
,
tupled_arg_ty
)
{
if
common
::
type_is_fat_ptr
(
tcx
,
tupled_arg_ty
)
{
// We pass fat pointers as two words, but inside the tuple
// they are the two sub-fields of a single aggregate field.
let
meta
=
&
fcx
.fn_ty.args
[
idx
];
idx
+=
1
;
arg
.store_fn_arg
(
bcx
,
&
mut
llarg_idx
,
expr
::
get_dataptr
(
bcx
,
dst
));
meta
.store_fn_arg
(
bcx
,
&
mut
llarg_idx
,
expr
::
get_meta
(
bcx
,
dst
));
}
else
{
arg
.store_fn_arg
(
bcx
,
&
mut
llarg_idx
,
dst
);
}
let
meta
=
&
fcx
.fn_ty.args
[
idx
];
idx
+=
1
;
arg
.store_fn_arg
(
bcx
,
&
mut
llarg_idx
,
get_dataptr
(
bcx
,
dst
));
meta
.store_fn_arg
(
bcx
,
&
mut
llarg_idx
,
get_meta
(
bcx
,
dst
));
}
else
{
arg
.store_fn_arg
(
bcx
,
&
mut
llarg_idx
,
dst
);
}
lltemp
});
return
LvalueRef
::
new_sized
(
llval
,
LvalueTy
::
from_ty
(
arg_ty
));
}
return
LvalueRef
::
new_sized
(
lltemp
,
LvalueTy
::
from_ty
(
arg_ty
));
}
let
arg
=
&
fcx
.fn_ty.args
[
idx
];
...
...
@@ -218,23 +215,23 @@ fn arg_value_refs<'bcx, 'tcx>(bcx: &BlockAndBuilder<'bcx, 'tcx>,
llarg_idx
+=
1
;
llarg
}
else
{
bcx
.with_block
(|
bcx
|
{
let
lltemp
=
base
::
alloc_ty
(
bcx
,
arg_ty
,
&
format!
(
"arg{}"
,
arg_index
));
if
common
::
type_is_fat_ptr
(
tcx
,
arg_ty
)
{
// we pass fat pointers as two words, but we want to
// represent them internally as a pointer to two words,
// so make an alloca to store them in.
let
meta
=
&
fcx
.fn_ty.args
[
idx
];
idx
+=
1
;
arg
.store_fn_arg
(
bcx
,
&
mut
llarg_idx
,
expr
::
get_dataptr
(
bcx
,
lltemp
))
;
meta
.store_fn_arg
(
bcx
,
&
mut
llarg_idx
,
expr
::
get_meta
(
bcx
,
lltemp
));
}
else
{
// otherwise, arg is passed by value, so make a
// temporary and store it there
arg
.store_fn_arg
(
bcx
,
&
mut
llarg_idx
,
lltemp
);
}
lltemp
})
let
lltemp
=
bcx
.with_block
(|
bcx
|
{
base
::
alloc_ty
(
bcx
,
arg_ty
,
&
format!
(
"arg{}"
,
arg_index
))
});
if
common
::
type_is_fat_ptr
(
tcx
,
arg_ty
)
{
// we pass fat pointers as two words, but we want to
// represent them internally as a pointer to two words,
// so make an alloca to store them in.
let
meta
=
&
fcx
.fn_ty.args
[
idx
]
;
idx
+=
1
;
arg
.store_fn_arg
(
bcx
,
&
mut
llarg_idx
,
get_dataptr
(
bcx
,
lltemp
));
meta
.store_fn_arg
(
bcx
,
&
mut
llarg_idx
,
get_meta
(
bcx
,
lltemp
));
}
else
{
// otherwise, arg is passed by value, so make a
// temporary and store it there
arg
.store_fn_arg
(
bcx
,
&
mut
llarg_idx
,
lltemp
);
}
lltemp
};
LvalueRef
::
new_sized
(
llval
,
LvalueTy
::
from_ty
(
arg_ty
))
})
.collect
()
...
...
src/librustc_trans/trans/mir/operand.rs
浏览文件 @
d9277b16
...
...
@@ -19,6 +19,7 @@
use
std
::
fmt
;
use
super
::
lvalue
::
load_fat_ptr
;
use
super
::{
MirContext
,
TempRef
,
drop
};
/// The representation of a Rust value. The enum variant is in fact
...
...
@@ -94,14 +95,10 @@ pub fn trans_load(&mut self,
let
val
=
match
datum
::
appropriate_rvalue_mode
(
bcx
.ccx
(),
ty
)
{
datum
::
ByValue
=>
{
bcx
.with_block
(|
bcx
|
{
OperandValue
::
Immediate
(
base
::
load_ty
(
bcx
,
llval
,
ty
))
})
OperandValue
::
Immediate
(
base
::
load_ty_builder
(
bcx
,
llval
,
ty
))
}
datum
::
ByRef
if
common
::
type_is_fat_ptr
(
bcx
.tcx
(),
ty
)
=>
{
let
(
lldata
,
llextra
)
=
bcx
.with_block
(|
bcx
|
{
base
::
load_fat_ptr
(
bcx
,
llval
,
ty
)
});
let
(
lldata
,
llextra
)
=
load_fat_ptr
(
bcx
,
llval
);
OperandValue
::
FatPtr
(
lldata
,
llextra
)
}
datum
::
ByRef
=>
OperandValue
::
Ref
(
llval
)
...
...
src/librustc_trans/trans/mir/rvalue.rs
浏览文件 @
d9277b16
...
...
@@ -21,7 +21,6 @@
use
trans
::
common
::{
self
,
BlockAndBuilder
,
Result
};
use
trans
::
debuginfo
::
DebugLoc
;
use
trans
::
declare
;
use
trans
::
expr
;
use
trans
::
adt
;
use
trans
::
machine
;
use
trans
::
type_
::
Type
;
...
...
@@ -32,7 +31,7 @@
use
super
::
MirContext
;
use
super
::
operand
::{
OperandRef
,
OperandValue
};
use
super
::
lvalue
::
LvalueRef
;
use
super
::
lvalue
::
{
LvalueRef
,
get_dataptr
,
get_meta
}
;
impl
<
'bcx
,
'tcx
>
MirContext
<
'bcx
,
'tcx
>
{
pub
fn
trans_rvalue
(
&
mut
self
,
...
...
@@ -100,8 +99,8 @@ pub fn trans_rvalue(&mut self,
let
tr_elem
=
self
.trans_operand
(
&
bcx
,
elem
);
let
count
=
ConstVal
::
Integral
(
ConstInt
::
Usize
(
count
.value
));
let
size
=
self
.trans_constval
(
&
bcx
,
&
count
,
bcx
.tcx
()
.types.usize
)
.immediate
();
let
base
=
get_dataptr
(
&
bcx
,
dest
.llval
);
let
bcx
=
bcx
.map_block
(|
block
|
{
let
base
=
expr
::
get_dataptr
(
block
,
dest
.llval
);
tvec
::
iter_vec_raw
(
block
,
base
,
tr_elem
.ty
,
size
,
|
block
,
llslot
,
_
|
{
self
.store_operand_direct
(
block
,
llslot
,
tr_elem
);
block
...
...
@@ -124,9 +123,8 @@ pub fn trans_rvalue(&mut self,
// Do not generate stores and GEPis for zero-sized fields.
if
!
common
::
type_is_zero_size
(
bcx
.ccx
(),
op
.ty
)
{
let
val
=
adt
::
MaybeSizedValue
::
sized
(
dest
.llval
);
let
lldest_i
=
bcx
.with_block
(|
bcx
|
{
adt
::
trans_field_ptr
(
bcx
,
&
repr
,
val
,
disr
,
i
)
});
let
lldest_i
=
adt
::
trans_field_ptr_builder
(
&
bcx
,
&
repr
,
val
,
disr
,
i
);
self
.store_operand
(
&
bcx
,
lldest_i
,
op
);
}
self
.set_operand_dropped
(
&
bcx
,
operand
);
...
...
@@ -186,11 +184,8 @@ pub fn trans_rvalue(&mut self,
let
llbase1
=
bcx
.gepi
(
llbase
,
&
[
from_start
]);
let
adj
=
common
::
C_uint
(
ccx
,
from_start
+
from_end
);
let
lllen1
=
bcx
.sub
(
lllen
,
adj
);
let
(
lladdrdest
,
llmetadest
)
=
bcx
.with_block
(|
bcx
|
{
(
expr
::
get_dataptr
(
bcx
,
dest
.llval
),
expr
::
get_meta
(
bcx
,
dest
.llval
))
});
bcx
.store
(
llbase1
,
lladdrdest
);
bcx
.store
(
lllen1
,
llmetadest
);
bcx
.store
(
llbase1
,
get_dataptr
(
&
bcx
,
dest
.llval
));
bcx
.store
(
lllen1
,
get_meta
(
&
bcx
,
dest
.llval
));
bcx
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录