Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
997ec63f
R
Rust
项目概览
int
/
Rust
12 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
997ec63f
编写于
8月 05, 2023
作者:
R
Ralf Jung
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
simplify handling of valtrees for unsized types
上级
b6e3bc23
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
43 addition
and
82 deletion
+43
-82
compiler/rustc_const_eval/src/const_eval/valtrees.rs
compiler/rustc_const_eval/src/const_eval/valtrees.rs
+28
-71
compiler/rustc_const_eval/src/interpret/place.rs
compiler/rustc_const_eval/src/interpret/place.rs
+14
-2
compiler/rustc_const_eval/src/interpret/terminator.rs
compiler/rustc_const_eval/src/interpret/terminator.rs
+1
-9
未找到文件。
compiler/rustc_const_eval/src/const_eval/valtrees.rs
浏览文件 @
997ec63f
...
...
@@ -7,9 +7,10 @@
intern_const_alloc_recursive
,
ConstValue
,
ImmTy
,
Immediate
,
InternKind
,
MemPlaceMeta
,
MemoryKind
,
Place
,
Projectable
,
Scalar
,
};
use
rustc_middle
::
ty
::
layout
::{
LayoutOf
,
TyAndLayout
};
use
rustc_middle
::
ty
::{
self
,
ScalarInt
,
Ty
,
TyCtxt
};
use
rustc_span
::
source_map
::
DUMMY_SP
;
use
rustc_target
::
abi
::
{
Align
,
VariantIdx
}
;
use
rustc_target
::
abi
::
VariantIdx
;
#[instrument(skip(ecx),
level
=
"debug"
)]
fn
branches
<
'tcx
>
(
...
...
@@ -154,52 +155,37 @@ pub(crate) fn const_to_valtree_inner<'tcx>(
}
}
#[instrument(skip(ecx),
level
=
"debug"
)]
fn
create_mplace_from_layout
<
'tcx
>
(
ecx
:
&
mut
CompileTimeEvalContext
<
'tcx
,
'tcx
>
,
ty
:
Ty
<
'tcx
>
,
)
->
MPlaceTy
<
'tcx
>
{
let
tcx
=
ecx
.tcx
;
let
param_env
=
ecx
.param_env
;
let
layout
=
tcx
.layout_of
(
param_env
.and
(
ty
))
.unwrap
();
debug!
(
?
layout
);
ecx
.allocate
(
layout
,
MemoryKind
::
Stack
)
.unwrap
()
}
// Walks custom DSTs and gets the type of the unsized field and the number of elements
// in the unsized field.
fn
get_info_on_unsized_field
<
'tcx
>
(
ty
:
Ty
<
'tcx
>
,
/// Valtrees don't store the `MemPlaceMeta` that all dynamically sized values have in the interpreter.
/// This function reconstructs it.
fn
reconstruct_place_meta
<
'tcx
>
(
layout
:
TyAndLayout
<
'tcx
>
,
valtree
:
ty
::
ValTree
<
'tcx
>
,
tcx
:
TyCtxt
<
'tcx
>
,
)
->
(
Ty
<
'tcx
>
,
usize
)
{
)
->
MemPlaceMeta
{
if
layout
.is_sized
()
{
return
MemPlaceMeta
::
None
;
}
let
mut
last_valtree
=
valtree
;
// Traverse the type, and update `last_valtree` as we go.
let
tail
=
tcx
.struct_tail_with_normalize
(
ty
,
layout
.
ty
,
|
ty
|
ty
,
||
{
let
branches
=
last_valtree
.unwrap_branch
();
last_valtree
=
branches
[
branches
.len
()
-
1
]
;
last_valtree
=
*
branches
.last
()
.unwrap
()
;
debug!
(
?
branches
,
?
last_valtree
);
},
);
let
unsized_inner_ty
=
match
tail
.kind
()
{
ty
::
Slice
(
t
)
=>
*
t
,
ty
::
Str
=>
tail
,
_
=>
bug!
(
"expected Slice or Str"
),
};
// Have to adjust type for ty::Str
let
unsized_inner_ty
=
match
unsized_inner_ty
.kind
()
{
ty
::
Str
=>
tcx
.types.u8
,
_
=>
unsized_inner_ty
,
// Sanity-check that we got a tail we support.
match
tail
.kind
()
{
ty
::
Slice
(
..
)
|
ty
::
Str
=>
{}
_
=>
bug!
(
"unsized tail of a valtree must be Slice or Str"
),
};
// Get the number of elements in the unsized field
// Get the number of elements in the unsized field
.
let
num_elems
=
last_valtree
.unwrap_branch
()
.len
();
(
unsized_inner_ty
,
num_elems
)
MemPlaceMeta
::
Meta
(
Scalar
::
from_target_usize
(
num_elems
as
u64
,
&
tcx
))
}
#[instrument(skip(ecx),
level
=
"debug"
,
ret)]
...
...
@@ -208,41 +194,9 @@ fn create_pointee_place<'tcx>(
ty
:
Ty
<
'tcx
>
,
valtree
:
ty
::
ValTree
<
'tcx
>
,
)
->
MPlaceTy
<
'tcx
>
{
let
tcx
=
ecx
.tcx.tcx
;
if
!
ty
.is_sized
(
*
ecx
.tcx
,
ty
::
ParamEnv
::
empty
())
{
// We need to create `Allocation`s for custom DSTs
let
(
unsized_inner_ty
,
num_elems
)
=
get_info_on_unsized_field
(
ty
,
valtree
,
tcx
);
let
unsized_inner_ty
=
match
unsized_inner_ty
.kind
()
{
ty
::
Str
=>
tcx
.types.u8
,
_
=>
unsized_inner_ty
,
};
let
unsized_inner_ty_size
=
tcx
.layout_of
(
ty
::
ParamEnv
::
empty
()
.and
(
unsized_inner_ty
))
.unwrap
()
.layout
.size
();
debug!
(
?
unsized_inner_ty
,
?
unsized_inner_ty_size
,
?
num_elems
);
// for custom DSTs only the last field/element is unsized, but we need to also allocate
// space for the other fields/elements
let
layout
=
tcx
.layout_of
(
ty
::
ParamEnv
::
empty
()
.and
(
ty
))
.unwrap
();
let
size_of_sized_part
=
layout
.layout
.size
();
// Get the size of the memory behind the DST
let
dst_size
=
unsized_inner_ty_size
.checked_mul
(
num_elems
as
u64
,
&
tcx
)
.unwrap
();
let
size
=
size_of_sized_part
.checked_add
(
dst_size
,
&
tcx
)
.unwrap
();
let
align
=
Align
::
from_bytes
(
size
.bytes
()
.next_power_of_two
())
.unwrap
();
let
ptr
=
ecx
.allocate_ptr
(
size
,
align
,
MemoryKind
::
Stack
)
.unwrap
();
debug!
(
?
ptr
);
MPlaceTy
::
from_aligned_ptr_with_meta
(
ptr
.into
(),
layout
,
MemPlaceMeta
::
Meta
(
Scalar
::
from_target_usize
(
num_elems
as
u64
,
&
tcx
)),
)
}
else
{
create_mplace_from_layout
(
ecx
,
ty
)
}
let
layout
=
ecx
.layout_of
(
ty
)
.unwrap
();
let
meta
=
reconstruct_place_meta
(
layout
,
valtree
,
ecx
.tcx.tcx
);
ecx
.allocate_dyn
(
layout
,
MemoryKind
::
Stack
,
meta
)
.unwrap
()
}
/// Converts a `ValTree` to a `ConstValue`, which is needed after mir
...
...
@@ -282,10 +236,13 @@ pub fn valtree_to_const_value<'tcx>(
ty
::
Ref
(
_
,
_
,
_
)
|
ty
::
Tuple
(
_
)
|
ty
::
Array
(
_
,
_
)
|
ty
::
Adt
(
..
)
=>
{
let
place
=
match
ty
.kind
()
{
ty
::
Ref
(
_
,
inner_ty
,
_
)
=>
{
// Need to create a place for the pointee
to fill for Refs
// Need to create a place for the pointee
(the reference itself will be an immediate)
create_pointee_place
(
&
mut
ecx
,
*
inner_ty
,
valtree
)
}
_
=>
create_mplace_from_layout
(
&
mut
ecx
,
ty
),
_
=>
{
// Need to create a place for this valtree.
create_pointee_place
(
&
mut
ecx
,
ty
,
valtree
)
}
};
debug!
(
?
place
);
...
...
compiler/rustc_const_eval/src/interpret/place.rs
浏览文件 @
997ec63f
...
...
@@ -934,14 +934,26 @@ pub fn force_allocation(
Ok
(
MPlaceTy
{
mplace
,
layout
:
place
.layout
,
align
:
place
.align
})
}
pub
fn
allocate_dyn
(
&
mut
self
,
layout
:
TyAndLayout
<
'tcx
>
,
kind
:
MemoryKind
<
M
::
MemoryKind
>
,
meta
:
MemPlaceMeta
<
M
::
Provenance
>
,
)
->
InterpResult
<
'tcx
,
MPlaceTy
<
'tcx
,
M
::
Provenance
>>
{
let
Some
((
size
,
align
))
=
self
.size_and_align_of
(
&
meta
,
&
layout
)
?
else
{
span_bug!
(
self
.cur_span
(),
"cannot allocate space for `extern` type, size is not known"
)
};
let
ptr
=
self
.allocate_ptr
(
size
,
align
,
kind
)
?
;
Ok
(
MPlaceTy
::
from_aligned_ptr_with_meta
(
ptr
.into
(),
layout
,
meta
))
}
pub
fn
allocate
(
&
mut
self
,
layout
:
TyAndLayout
<
'tcx
>
,
kind
:
MemoryKind
<
M
::
MemoryKind
>
,
)
->
InterpResult
<
'tcx
,
MPlaceTy
<
'tcx
,
M
::
Provenance
>>
{
assert
!
(
layout
.is_sized
());
let
ptr
=
self
.allocate_ptr
(
layout
.size
,
layout
.align.abi
,
kind
)
?
;
Ok
(
MPlaceTy
::
from_aligned_ptr
(
ptr
.into
(),
layout
))
self
.allocate_dyn
(
layout
,
kind
,
MemPlaceMeta
::
None
)
}
/// Returns a wide MPlace of type `&'static [mut] str` to a new 1-aligned allocation.
...
...
compiler/rustc_const_eval/src/interpret/terminator.rs
浏览文件 @
997ec63f
...
...
@@ -393,15 +393,7 @@ fn pass_argument<'x, 'y>(
));
assert_eq!
(
dest_offset
,
None
);
// Allocate enough memory to hold `src`.
let
Some
((
size
,
align
))
=
self
.size_and_align_of_mplace
(
&
src
)
?
else
{
span_bug!
(
self
.cur_span
(),
"unsized fn arg with `extern` type tail should not be allowed"
)
};
let
ptr
=
self
.allocate_ptr
(
size
,
align
,
MemoryKind
::
Stack
)
?
;
let
dest_place
=
MPlaceTy
::
from_aligned_ptr_with_meta
(
ptr
.into
(),
callee_arg
.layout
,
src
.meta
);
let
dest_place
=
self
.allocate_dyn
(
src
.layout
,
MemoryKind
::
Stack
,
src
.meta
)
?
;
// Update the local to be that new place.
*
M
::
access_local_mut
(
self
,
dest_frame
,
dest_local
)
?
=
Operand
::
Indirect
(
*
dest_place
);
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录