Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
28243a5c
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,发现更多精彩内容 >>
提交
28243a5c
编写于
5月 15, 2014
作者:
L
Luqman Aden
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
librustc: Separate NullablePointer into RawNullablePointer and StructWrappedNullablePointer.
上级
d104daba
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
92 addition
and
75 deletion
+92
-75
src/librustc/middle/trans/adt.rs
src/librustc/middle/trans/adt.rs
+88
-74
src/librustc/middle/trans/debuginfo.rs
src/librustc/middle/trans/debuginfo.rs
+4
-1
未找到文件。
src/librustc/middle/trans/adt.rs
浏览文件 @
28243a5c
...
...
@@ -85,20 +85,30 @@ pub enum Repr {
* all start with a field for the discriminant.
*/
General
(
IntType
,
Vec
<
Struct
>
),
/**
* Two cases distinguished by a nullable pointer: the case with discriminant
* `nndiscr` must have single field which is known to be nonnull due to its type.
* The other case is known to be zero sized. Hence we represent the enum
* as simply a nullable pointer: if not null it indicates the `nndiscr` variant,
* otherwise it indicates the other case.
*/
RawNullablePointer
{
pub
nndiscr
:
Disr
,
pub
nnty
:
ty
::
t
,
pub
nullfields
:
Vec
<
ty
::
t
>
},
/**
* Two cases distinguished by a nullable pointer: the case with discriminant
* `nndiscr` is represented by the struct `nonnull`, where the `ptrfield`th
* field is known to be nonnull due to its type; if that field is null, then
* it represents the other case, which is inhabited by at most one value
* (and all other fields are undefined/unused).
* If the case with the nullable pointer has a single field then we don't
* wrap it in a struct and instead just deal with it directly as a pointer.
*
* For example, `std::option::Option` instantiated at a safe pointer type
* is represented such that `None` is a null pointer and `Some` is the
* identity function.
*/
NullablePointer
{
StructWrapped
NullablePointer
{
pub
nonnull
:
Struct
,
pub
nndiscr
:
Disr
,
pub
ptrfield
:
uint
,
...
...
@@ -202,17 +212,23 @@ fn represent_type_uncached(cx: &CrateContext, t: ty::t) -> Repr {
if
cases
.get
(
1
-
discr
)
.is_zerolen
(
cx
)
{
match
cases
.get
(
discr
)
.find_ptr
()
{
Some
(
ptrfield
)
=>
{
return
NullablePointer
{
nndiscr
:
discr
as
u64
,
nonnull
:
mk_struct
(
cx
,
cases
.get
(
discr
)
.tys
.as_slice
(),
false
),
ptrfield
:
ptrfield
,
nullfields
:
cases
.get
(
1
-
discr
)
.tys
.clone
()
}
let
st
=
mk_struct
(
cx
,
cases
.get
(
discr
)
.tys
.as_slice
(),
false
);
return
if
st
.fields
.len
()
==
1
{
RawNullablePointer
{
nndiscr
:
discr
as
Disr
,
nnty
:
*
st
.fields
.get
(
0
),
nullfields
:
cases
.get
(
1
-
discr
)
.tys
.clone
()
}
}
else
{
StructWrappedNullablePointer
{
nndiscr
:
discr
as
Disr
,
nonnull
:
st
,
ptrfield
:
ptrfield
,
nullfields
:
cases
.get
(
1
-
discr
)
.tys
.clone
()
}
};
}
None
=>
{
}
}
...
...
@@ -415,11 +431,8 @@ pub fn incomplete_type_of(cx: &CrateContext, r: &Repr, name: &str) -> Type {
}
pub
fn
finish_type_of
(
cx
:
&
CrateContext
,
r
:
&
Repr
,
llty
:
&
mut
Type
)
{
match
*
r
{
CEnum
(
..
)
|
General
(
..
)
=>
{
}
NullablePointer
{
nonnull
:
ref
st
,
..
}
if
st
.fields
.len
()
==
1
=>
{
}
Univariant
(
ref
st
,
_
)
|
NullablePointer
{
nonnull
:
ref
st
,
..
}
=>
CEnum
(
..
)
|
General
(
..
)
|
RawNullablePointer
{
..
}
=>
{
}
Univariant
(
ref
st
,
_
)
|
StructWrappedNullablePointer
{
nonnull
:
ref
st
,
..
}
=>
llty
.set_struct_body
(
struct_llfields
(
cx
,
st
,
false
)
.as_slice
(),
st
.packed
)
}
...
...
@@ -428,14 +441,8 @@ pub fn finish_type_of(cx: &CrateContext, r: &Repr, llty: &mut Type) {
fn
generic_type_of
(
cx
:
&
CrateContext
,
r
:
&
Repr
,
name
:
Option
<&
str
>
,
sizing
:
bool
)
->
Type
{
match
*
r
{
CEnum
(
ity
,
_
,
_
)
=>
ll_inttype
(
cx
,
ity
),
NullablePointer
{
nonnull
:
ref
st
,
..
}
if
st
.fields
.len
()
==
1
=>
{
if
sizing
{
type_of
::
sizing_type_of
(
cx
,
*
st
.fields
.get
(
0
))
}
else
{
type_of
::
type_of
(
cx
,
*
st
.fields
.get
(
0
))
}
}
Univariant
(
ref
st
,
_
)
|
NullablePointer
{
nonnull
:
ref
st
,
..
}
=>
{
RawNullablePointer
{
nnty
,
..
}
=>
type_of
::
sizing_type_of
(
cx
,
nnty
),
Univariant
(
ref
st
,
_
)
|
StructWrappedNullablePointer
{
nonnull
:
ref
st
,
..
}
=>
{
match
name
{
None
=>
{
Type
::
struct_
(
cx
,
struct_llfields
(
cx
,
st
,
sizing
)
.as_slice
(),
...
...
@@ -507,12 +514,10 @@ fn struct_llfields(cx: &CrateContext, st: &Struct, sizing: bool) -> Vec<Type> {
pub
fn
trans_switch
(
bcx
:
&
Block
,
r
:
&
Repr
,
scrutinee
:
ValueRef
)
->
(
_
match
::
branch_kind
,
Option
<
ValueRef
>
)
{
match
*
r
{
CEnum
(
..
)
|
General
(
..
)
=>
{
CEnum
(
..
)
|
General
(
..
)
|
RawNullablePointer
{
..
}
|
StructWrappedNullablePointer
{
..
}
=>
{
(
_
match
::
switch
,
Some
(
trans_get_discr
(
bcx
,
r
,
scrutinee
,
None
)))
}
NullablePointer
{
nonnull
:
ref
nonnull
,
nndiscr
,
ptrfield
,
..
}
=>
{
(
_
match
::
switch
,
Some
(
nullable_bitdiscr
(
bcx
,
nonnull
,
nndiscr
,
ptrfield
,
scrutinee
)))
}
Univariant
(
..
)
=>
{
(
_
match
::
single
,
None
)
}
...
...
@@ -540,8 +545,14 @@ pub fn trans_get_discr(bcx: &Block, r: &Repr, scrutinee: ValueRef, cast_to: Opti
val
=
C_u8
(
bcx
.ccx
(),
0
);
signed
=
false
;
}
NullablePointer
{
nonnull
:
ref
nonnull
,
nndiscr
,
ptrfield
,
..
}
=>
{
val
=
nullable_bitdiscr
(
bcx
,
nonnull
,
nndiscr
,
ptrfield
,
scrutinee
);
RawNullablePointer
{
nndiscr
,
nnty
,
..
}
=>
{
let
cmp
=
if
nndiscr
==
0
{
IntEQ
}
else
{
IntNE
};
let
llptrty
=
type_of
::
sizing_type_of
(
bcx
.ccx
(),
nnty
);
val
=
ICmp
(
bcx
,
cmp
,
Load
(
bcx
,
scrutinee
),
C_null
(
llptrty
));
signed
=
false
;
}
StructWrappedNullablePointer
{
nonnull
:
ref
nonnull
,
nndiscr
,
ptrfield
,
..
}
=>
{
val
=
struct_wrapped_nullable_bitdiscr
(
bcx
,
nonnull
,
nndiscr
,
ptrfield
,
scrutinee
);
signed
=
false
;
}
}
...
...
@@ -551,13 +562,9 @@ pub fn trans_get_discr(bcx: &Block, r: &Repr, scrutinee: ValueRef, cast_to: Opti
}
}
fn
nullable_bitdiscr
(
bcx
:
&
Block
,
nonnull
:
&
Struct
,
nndiscr
:
Disr
,
ptrfield
:
uint
,
scrutinee
:
ValueRef
)
->
ValueRef
{
let
llptr
=
if
nonnull
.fields
.len
()
==
1
{
Load
(
bcx
,
scrutinee
)
}
else
{
Load
(
bcx
,
GEPi
(
bcx
,
scrutinee
,
[
0
,
ptrfield
]))
};
fn
struct_wrapped_nullable_bitdiscr
(
bcx
:
&
Block
,
nonnull
:
&
Struct
,
nndiscr
:
Disr
,
ptrfield
:
uint
,
scrutinee
:
ValueRef
)
->
ValueRef
{
let
llptr
=
Load
(
bcx
,
GEPi
(
bcx
,
scrutinee
,
[
0
,
ptrfield
]));
let
cmp
=
if
nndiscr
==
0
{
IntEQ
}
else
{
IntNE
};
let
llptrty
=
type_of
::
type_of
(
bcx
.ccx
(),
*
nonnull
.fields
.get
(
ptrfield
));
ICmp
(
bcx
,
cmp
,
llptr
,
C_null
(
llptrty
))
...
...
@@ -606,7 +613,8 @@ pub fn trans_case<'a>(bcx: &'a Block<'a>, r: &Repr, discr: Disr)
Univariant
(
..
)
=>
{
bcx
.ccx
()
.sess
()
.bug
(
"no cases for univariants or structs"
)
}
NullablePointer
{
..
}
=>
{
RawNullablePointer
{
..
}
|
StructWrappedNullablePointer
{
..
}
=>
{
assert
!
(
discr
==
0
||
discr
==
1
);
_
match
::
single_result
(
Result
::
new
(
bcx
,
C_i1
(
bcx
.ccx
(),
discr
!=
0
)))
}
...
...
@@ -637,13 +645,15 @@ pub fn trans_start_init(bcx: &Block, r: &Repr, val: ValueRef, discr: Disr) {
Univariant
(
..
)
=>
{
assert_eq!
(
discr
,
0
);
}
NullablePointer
{
nonnull
:
ref
nonnull
,
nndiscr
,
ptrfield
,
..
}
=>
{
RawNullablePointer
{
nndiscr
,
nnty
,
..
}
=>
{
if
discr
!=
nndiscr
{
let
llptrptr
=
if
nonnull
.fields
.len
()
==
1
{
val
}
else
{
GEPi
(
bcx
,
val
,
[
0
,
ptrfield
])
};
let
llptrty
=
type_of
::
sizing_type_of
(
bcx
.ccx
(),
nnty
);
Store
(
bcx
,
C_null
(
llptrty
),
val
)
}
}
StructWrappedNullablePointer
{
nonnull
:
ref
nonnull
,
nndiscr
,
ptrfield
,
..
}
=>
{
if
discr
!=
nndiscr
{
let
llptrptr
=
GEPi
(
bcx
,
val
,
[
0
,
ptrfield
]);
let
llptrty
=
type_of
::
type_of
(
bcx
.ccx
(),
*
nonnull
.fields
.get
(
ptrfield
));
Store
(
bcx
,
C_null
(
llptrty
),
llptrptr
)
...
...
@@ -671,8 +681,11 @@ pub fn num_args(r: &Repr, discr: Disr) -> uint {
st
.fields
.len
()
-
(
if
dtor
{
1
}
else
{
0
})
}
General
(
_
,
ref
cases
)
=>
cases
.get
(
discr
as
uint
)
.fields
.len
()
-
1
,
NullablePointer
{
nonnull
:
ref
nonnull
,
nndiscr
,
nullfields
:
ref
nullfields
,
..
}
=>
{
RawNullablePointer
{
nndiscr
,
ref
nullfields
,
..
}
=>
{
if
discr
==
nndiscr
{
1
}
else
{
nullfields
.len
()
}
}
StructWrappedNullablePointer
{
nonnull
:
ref
nonnull
,
nndiscr
,
nullfields
:
ref
nullfields
,
..
}
=>
{
if
discr
==
nndiscr
{
nonnull
.fields
.len
()
}
else
{
nullfields
.len
()
}
}
}
...
...
@@ -695,24 +708,25 @@ pub fn trans_field_ptr(bcx: &Block, r: &Repr, val: ValueRef, discr: Disr,
General
(
_
,
ref
cases
)
=>
{
struct_field_ptr
(
bcx
,
cases
.get
(
discr
as
uint
),
val
,
ix
+
1
,
true
)
}
NullablePointer
{
nonnull
:
ref
nonnull
,
nullfields
:
ref
nullfields
,
nndiscr
,
..
}
=>
{
if
discr
==
nndiscr
{
if
nonnull
.fields
.len
()
==
1
{
assert_eq!
(
ix
,
0
);
val
}
else
{
struct_field_ptr
(
bcx
,
nonnull
,
val
,
ix
,
false
)
}
}
else
{
// The unit-like case might have a nonzero number of unit-like fields.
// (e.g., Result or Either with () as one side.)
let
ty
=
type_of
::
type_of
(
bcx
.ccx
(),
*
nullfields
.get
(
ix
));
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
,
ty
.ptr_to
())
}
RawNullablePointer
{
nndiscr
,
ref
nullfields
,
..
}
|
StructWrappedNullablePointer
{
nndiscr
,
ref
nullfields
,
..
}
if
discr
!=
nndiscr
=>
{
// The unit-like case might have a nonzero number of unit-like fields.
// (e.d., Result of Either with (), as one side.)
let
ty
=
type_of
::
type_of
(
bcx
.ccx
(),
*
nullfields
.get
(
ix
));
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 comparision.
PointerCast
(
bcx
,
val
,
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
,
ty
.ptr_to
())
}
StructWrappedNullablePointer
{
ref
nonnull
,
nndiscr
,
..
}
=>
{
assert_eq!
(
discr
,
nndiscr
);
struct_field_ptr
(
bcx
,
nonnull
,
val
,
ix
,
false
)
}
}
}
...
...
@@ -784,15 +798,15 @@ pub fn trans_const(ccx: &CrateContext, r: &Repr, discr: Disr,
let
contents
=
build_const_struct
(
ccx
,
st
,
vals
);
C_struct
(
ccx
,
contents
.as_slice
(),
st
.packed
)
}
NullablePointer
{
nonnull
:
ref
st
,
nndiscr
,
..
}
if
st
.fields
.len
()
==
1
=>
{
RawNullablePointer
{
nndiscr
,
nnty
,
..
}
=>
{
if
discr
==
nndiscr
{
assert_eq!
(
vals
.len
(),
1
);
vals
[
0
]
}
else
{
C_null
(
type_of
::
sizing_type_of
(
ccx
,
*
st
.fields
.get
(
0
)
))
C_null
(
type_of
::
sizing_type_of
(
ccx
,
nnty
))
}
}
NullablePointer
{
nonnull
:
ref
nonnull
,
nndiscr
,
..
}
=>
{
StructWrapped
NullablePointer
{
nonnull
:
ref
nonnull
,
nndiscr
,
..
}
=>
{
if
discr
==
nndiscr
{
C_struct
(
ccx
,
build_const_struct
(
ccx
,
nonnull
,
...
...
@@ -900,7 +914,7 @@ pub fn const_get_discrim(ccx: &CrateContext, r: &Repr, val: ValueRef)
}
}
Univariant
(
..
)
=>
0
,
NullablePointer
{
nonnull
:
ref
st
,
nndiscr
,
..
}
if
st
.fields
.len
()
==
1
=>
{
RawNullablePointer
{
nndiscr
,
..
}
=>
{
if
is_null
(
val
)
{
/* subtraction as uint is ok because nndiscr is either 0 or 1 */
(
1
-
nndiscr
)
as
Disr
...
...
@@ -908,7 +922,7 @@ pub fn const_get_discrim(ccx: &CrateContext, r: &Repr, val: ValueRef)
nndiscr
}
}
NullablePointer
{
nndiscr
,
ptrfield
,
..
}
=>
{
StructWrapped
NullablePointer
{
nndiscr
,
ptrfield
,
..
}
=>
{
if
is_null
(
const_struct_field
(
ccx
,
val
,
ptrfield
))
{
/* subtraction as uint is ok because nndiscr is either 0 or 1 */
(
1
-
nndiscr
)
as
Disr
...
...
@@ -932,11 +946,11 @@ pub fn const_get_field(ccx: &CrateContext, r: &Repr, val: ValueRef,
CEnum
(
..
)
=>
ccx
.sess
()
.bug
(
"element access in C-like enum const"
),
Univariant
(
..
)
=>
const_struct_field
(
ccx
,
val
,
ix
),
General
(
..
)
=>
const_struct_field
(
ccx
,
val
,
ix
+
1
),
NullablePointer
{
nonnull
:
ref
st
,
..
}
if
st
.fields
.len
()
==
1
=>
{
RawNullablePointer
{
..
}
=>
{
assert_eq!
(
ix
,
0
);
val
}
NullablePointer
{
..
}
=>
const_struct_field
(
ccx
,
val
,
ix
)
StructWrapped
NullablePointer
{
..
}
=>
const_struct_field
(
ccx
,
val
,
ix
)
}
}
...
...
src/librustc/middle/trans/debuginfo.rs
浏览文件 @
28243a5c
...
...
@@ -1657,7 +1657,10 @@ fn prepare_enum_metadata(cx: &CrateContext,
}),
}
}
adt
::
NullablePointer
{
nonnull
:
ref
struct_def
,
nndiscr
,
..
}
=>
{
adt
::
RawNullablePointer
{
nnty
,
..
}
=>
{
FinalMetadata
(
type_metadata
(
cx
,
nnty
,
span
))
}
adt
::
StructWrappedNullablePointer
{
nonnull
:
ref
struct_def
,
nndiscr
,
..
}
=>
{
let
(
metadata_stub
,
variant_llvm_type
,
member_description_factory
)
=
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录