Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
9be3e918
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,发现更多精彩内容 >>
提交
9be3e918
编写于
6月 23, 2017
作者:
O
Oliver Schneider
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Remove the zst allocation
上级
f10dd417
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
70 addition
and
48 deletion
+70
-48
src/error.rs
src/error.rs
+6
-0
src/eval_context.rs
src/eval_context.rs
+12
-8
src/lvalue.rs
src/lvalue.rs
+0
-4
src/memory.rs
src/memory.rs
+7
-29
src/terminator/drop.rs
src/terminator/drop.rs
+1
-1
src/terminator/mod.rs
src/terminator/mod.rs
+27
-3
tests/compile-fail/zst.rs
tests/compile-fail/zst.rs
+1
-1
tests/compile-fail/zst2.rs
tests/compile-fail/zst2.rs
+8
-0
tests/compile-fail/zst3.rs
tests/compile-fail/zst3.rs
+8
-0
tests/run-pass/zst.rs
tests/run-pass/zst.rs
+0
-2
未找到文件。
src/error.rs
浏览文件 @
9be3e918
...
...
@@ -59,6 +59,8 @@ pub enum EvalError<'tcx> {
ReallocatedStaticMemory
,
DeallocatedStaticMemory
,
Layout
(
layout
::
LayoutError
<
'tcx
>
),
HeapAllocZeroBytes
,
HeapAllocNonPowerOfTwoAlignment
(
u64
),
Unreachable
,
Panic
,
}
...
...
@@ -146,6 +148,10 @@ fn description(&self) -> &str {
"rustc layout computation failed"
,
EvalError
::
UnterminatedCString
(
_
)
=>
"attempted to get length of a null terminated string, but no null found before end of allocation"
,
EvalError
::
HeapAllocZeroBytes
=>
"tried to re-, de- or allocate zero bytes on the heap"
,
EvalError
::
HeapAllocNonPowerOfTwoAlignment
(
_
)
=>
"tried to re-, de-, or allocate heap memory with alignment that is not a power of two"
,
EvalError
::
Unreachable
=>
"entered unreachable code"
,
EvalError
::
Panic
=>
...
...
src/eval_context.rs
浏览文件 @
9be3e918
...
...
@@ -370,7 +370,7 @@ pub(super) fn pop_stack_frame(&mut self) -> EvalResult<'tcx> {
instance
,
mir
.span
,
mir
,
Lvalue
::
zst
(),
Lvalue
::
undef
(),
StackPopCleanup
::
Tls
(
Some
(
key
)),
)
?
;
let
arg_local
=
self
.frame
()
.mir
.args_iter
()
.next
()
.ok_or
(
EvalError
::
AbiViolation
(
"TLS dtor does not take enough arguments."
.to_owned
()))
?
;
...
...
@@ -673,8 +673,14 @@ pub(super) fn eval_rvalue_into_lvalue(
}
NullaryOp
(
mir
::
NullOp
::
Box
,
ty
)
=>
{
let
ptr
=
self
.alloc_ptr
(
ty
)
?
;
self
.write_primval
(
dest
,
PrimVal
::
Ptr
(
ptr
),
dest_ty
)
?
;
// FIXME: call the `exchange_malloc` lang item if available
if
self
.type_size
(
ty
)
?
.expect
(
"box only works with sized types"
)
==
0
{
let
align
=
self
.type_align
(
ty
)
?
;
self
.write_primval
(
dest
,
PrimVal
::
Bytes
(
align
.into
()),
dest_ty
)
?
;
}
else
{
let
ptr
=
self
.alloc_ptr
(
ty
)
?
;
self
.write_primval
(
dest
,
PrimVal
::
Ptr
(
ptr
),
dest_ty
)
?
;
}
}
NullaryOp
(
mir
::
NullOp
::
SizeOf
,
ty
)
=>
{
...
...
@@ -904,11 +910,9 @@ pub(super) fn pointer_offset(&self, ptr: PrimVal, pointee_ty: Ty<'tcx>, offset:
let
pointee_size
=
self
.type_size
(
pointee_ty
)
?
.expect
(
"cannot offset a pointer to an unsized type"
)
as
i64
;
return
if
let
Some
(
offset
)
=
offset
.checked_mul
(
pointee_size
)
{
let
ptr
=
ptr
.signed_offset
(
offset
,
self
.memory.layout
)
?
;
// Do not do bounds-checking for integers
or ZST
; they can never alias a normal pointer anyway.
// Do not do bounds-checking for integers; they can never alias a normal pointer anyway.
if
let
PrimVal
::
Ptr
(
ptr
)
=
ptr
{
if
!
(
ptr
.points_to_zst
()
&&
(
offset
==
0
||
pointee_size
==
0
))
{
self
.memory
.check_bounds
(
ptr
,
false
)
?
;
}
self
.memory
.check_bounds
(
ptr
,
false
)
?
;
}
else
if
ptr
.is_null
()
?
{
// We moved *to* a NULL pointer. That seems wrong, LLVM considers the NULL pointer its own small allocation. Reject this, for now.
return
Err
(
EvalError
::
NullPointerOutOfBounds
);
...
...
@@ -1697,7 +1701,7 @@ fn run_main<'a, 'tcx: 'a>(
main_instance
,
main_mir
.span
,
main_mir
,
Lvalue
::
zst
(),
Lvalue
::
undef
(),
StackPopCleanup
::
Tls
(
None
),
)
?
;
}
...
...
src/lvalue.rs
浏览文件 @
9be3e918
...
...
@@ -73,10 +73,6 @@ fn from_primval_ptr(ptr: PrimVal) -> Self {
Lvalue
::
Ptr
{
ptr
,
extra
:
LvalueExtra
::
None
}
}
pub
fn
zst
()
->
Self
{
Self
::
from_ptr
(
Pointer
::
zst_ptr
())
}
pub
fn
from_ptr
(
ptr
:
Pointer
)
->
Self
{
Self
::
from_primval_ptr
(
PrimVal
::
Ptr
(
ptr
))
}
...
...
src/memory.rs
浏览文件 @
9be3e918
...
...
@@ -81,14 +81,6 @@ pub fn overflowing_offset<'tcx>(self, i: u64, layout: &TargetDataLayout) -> (Sel
pub
fn
offset
<
'tcx
>
(
self
,
i
:
u64
,
layout
:
&
TargetDataLayout
)
->
EvalResult
<
'tcx
,
Self
>
{
Ok
(
Pointer
::
new
(
self
.alloc_id
,
value
::
offset
(
self
.offset
,
i
,
layout
)
?
))
}
pub
fn
points_to_zst
(
&
self
)
->
bool
{
self
.alloc_id
==
ZST_ALLOC_ID
}
pub
fn
zst_ptr
()
->
Self
{
Pointer
::
new
(
ZST_ALLOC_ID
,
0
)
}
}
pub
type
TlsKey
=
usize
;
...
...
@@ -157,15 +149,13 @@ pub struct Memory<'a, 'tcx> {
next_thread_local
:
TlsKey
,
}
const
ZST_ALLOC_ID
:
AllocId
=
AllocId
(
0
);
impl
<
'a
,
'tcx
>
Memory
<
'a
,
'tcx
>
{
pub
fn
new
(
layout
:
&
'a
TargetDataLayout
,
max_memory
:
u64
)
->
Self
{
Memory
{
alloc_map
:
HashMap
::
new
(),
functions
:
HashMap
::
new
(),
function_alloc_cache
:
HashMap
::
new
(),
next_id
:
AllocId
(
2
),
next_id
:
AllocId
(
0
),
layout
,
memory_size
:
max_memory
,
memory_usage
:
0
,
...
...
@@ -206,10 +196,8 @@ pub fn allocate_cached(&mut self, bytes: &[u8]) -> EvalResult<'tcx, Pointer> {
}
pub
fn
allocate
(
&
mut
self
,
size
:
u64
,
align
:
u64
)
->
EvalResult
<
'tcx
,
Pointer
>
{
if
size
==
0
{
return
Ok
(
Pointer
::
zst_ptr
());
}
assert_ne!
(
align
,
0
);
assert
!
(
align
.is_power_of_two
());
if
self
.memory_size
-
self
.memory_usage
<
size
{
return
Err
(
EvalError
::
OutOfMemory
{
...
...
@@ -236,13 +224,11 @@ pub fn allocate(&mut self, size: u64, align: u64) -> EvalResult<'tcx, Pointer> {
// TODO(solson): Track which allocations were returned from __rust_allocate and report an error
// when reallocating/deallocating any others.
pub
fn
reallocate
(
&
mut
self
,
ptr
:
Pointer
,
new_size
:
u64
,
align
:
u64
)
->
EvalResult
<
'tcx
,
Pointer
>
{
assert
!
(
align
.is_power_of_two
());
// TODO(solson): Report error about non-__rust_allocate'd pointer.
if
ptr
.offset
!=
0
{
return
Err
(
EvalError
::
Unimplemented
(
format!
(
"bad pointer offset: {}"
,
ptr
.offset
)));
}
if
ptr
.points_to_zst
()
{
return
self
.allocate
(
new_size
,
align
);
}
if
self
.get
(
ptr
.alloc_id
)
.ok
()
.map_or
(
false
,
|
alloc
|
alloc
.static_kind
!=
StaticKind
::
NotStatic
)
{
return
Err
(
EvalError
::
ReallocatedStaticMemory
);
}
...
...
@@ -253,6 +239,7 @@ pub fn reallocate(&mut self, ptr: Pointer, new_size: u64, align: u64) -> EvalRes
let
amount
=
new_size
-
size
;
self
.memory_usage
+=
amount
;
let
alloc
=
self
.get_mut
(
ptr
.alloc_id
)
?
;
// FIXME: check alignment here
assert_eq!
(
amount
as
usize
as
u64
,
amount
);
alloc
.bytes
.extend
(
iter
::
repeat
(
0
)
.take
(
amount
as
usize
));
alloc
.undef_mask
.grow
(
amount
,
false
);
...
...
@@ -260,6 +247,7 @@ pub fn reallocate(&mut self, ptr: Pointer, new_size: u64, align: u64) -> EvalRes
self
.memory_usage
-=
size
-
new_size
;
self
.clear_relocations
(
ptr
.offset
(
new_size
,
self
.layout
)
?
,
size
-
new_size
)
?
;
let
alloc
=
self
.get_mut
(
ptr
.alloc_id
)
?
;
// FIXME: check alignment here
// `as usize` is fine here, since it is smaller than `size`, which came from a usize
alloc
.bytes
.truncate
(
new_size
as
usize
);
alloc
.bytes
.shrink_to_fit
();
...
...
@@ -271,9 +259,6 @@ pub fn reallocate(&mut self, ptr: Pointer, new_size: u64, align: u64) -> EvalRes
// TODO(solson): See comment on `reallocate`.
pub
fn
deallocate
(
&
mut
self
,
ptr
:
Pointer
)
->
EvalResult
<
'tcx
>
{
if
ptr
.points_to_zst
()
{
return
Ok
(());
}
if
ptr
.offset
!=
0
{
// TODO(solson): Report error about non-__rust_allocate'd pointer.
return
Err
(
EvalError
::
Unimplemented
(
format!
(
"bad pointer offset: {}"
,
ptr
.offset
)));
...
...
@@ -459,7 +444,6 @@ pub fn get(&self, id: AllocId) -> EvalResult<'tcx, &Allocation> {
Some
(
alloc
)
=>
Ok
(
alloc
),
None
=>
match
self
.functions
.get
(
&
id
)
{
Some
(
_
)
=>
Err
(
EvalError
::
DerefFunctionPointer
),
None
if
id
==
ZST_ALLOC_ID
=>
Err
(
EvalError
::
InvalidMemoryAccess
),
None
=>
Err
(
EvalError
::
DanglingPointerDeref
),
}
}
...
...
@@ -474,7 +458,6 @@ pub fn get_mut(&mut self, id: AllocId) -> EvalResult<'tcx, &mut Allocation> {
},
None
=>
match
self
.functions
.get
(
&
id
)
{
Some
(
_
)
=>
Err
(
EvalError
::
DerefFunctionPointer
),
None
if
id
==
ZST_ALLOC_ID
=>
Err
(
EvalError
::
InvalidMemoryAccess
),
None
=>
Err
(
EvalError
::
DanglingPointerDeref
),
}
}
...
...
@@ -508,7 +491,6 @@ pub fn dump_allocs(&self, mut allocs: Vec<AllocId>) {
let
mut
allocs_seen
=
HashSet
::
new
();
while
let
Some
(
id
)
=
allocs_to_print
.pop_front
()
{
if
id
==
ZST_ALLOC_ID
{
continue
;
}
let
mut
msg
=
format!
(
"Alloc {:<5} "
,
format!
(
"{}:"
,
id
));
let
prefix_len
=
msg
.len
();
let
mut
relocations
=
vec!
[];
...
...
@@ -556,10 +538,7 @@ pub fn dump_allocs(&self, mut allocs: Vec<AllocId>) {
for
(
i
,
target_id
)
in
relocations
{
// this `as usize` is fine, since we can't print more chars than `usize::MAX`
write!
(
msg
,
"{:1$}"
,
""
,
((
i
-
pos
)
*
3
)
as
usize
)
.unwrap
();
let
target
=
match
target_id
{
ZST_ALLOC_ID
=>
String
::
from
(
"zst"
),
_
=>
format!
(
"({})"
,
target_id
),
};
let
target
=
format!
(
"({})"
,
target_id
);
// this `as usize` is fine, since we can't print more chars than `usize::MAX`
write!
(
msg
,
"└{0:─^1$}┘ "
,
target
,
relocation_width
as
usize
)
.unwrap
();
pos
=
i
+
self
.pointer_size
();
...
...
@@ -637,7 +616,7 @@ impl<'a, 'tcx> Memory<'a, 'tcx> {
/// mark an allocation as being the entry point to a static (see `static_alloc` field)
pub
fn
mark_static
(
&
mut
self
,
alloc_id
:
AllocId
)
{
trace!
(
"mark_static: {:?}"
,
alloc_id
);
if
alloc_id
!=
ZST_ALLOC_ID
&&
!
self
.static_alloc
.insert
(
alloc_id
)
{
if
!
self
.static_alloc
.insert
(
alloc_id
)
{
bug!
(
"tried to mark an allocation ({:?}) as static twice"
,
alloc_id
);
}
}
...
...
@@ -667,7 +646,6 @@ pub fn mark_static_initalized(&mut self, alloc_id: AllocId, mutable: bool) -> Ev
// mark recursively
mem
::
replace
(
relocations
,
Default
::
default
())
},
None
if
alloc_id
==
ZST_ALLOC_ID
=>
return
Ok
(()),
None
if
!
self
.functions
.contains_key
(
&
alloc_id
)
=>
return
Err
(
EvalError
::
DanglingPointerDeref
),
_
=>
return
Ok
(()),
};
...
...
src/terminator/drop.rs
浏览文件 @
9be3e918
...
...
@@ -49,7 +49,7 @@ pub(crate) fn drop(&mut self, arg: Value, mut instance: ty::Instance<'tcx>, ty:
instance
,
span
,
mir
,
Lvalue
::
zst
(),
Lvalue
::
undef
(),
StackPopCleanup
::
None
,
)
?
;
...
...
src/terminator/mod.rs
浏览文件 @
9be3e918
...
...
@@ -596,6 +596,12 @@ fn call_c_abi(
"__rust_allocate"
=>
{
let
size
=
self
.value_to_primval
(
args
[
0
],
usize
)
?
.to_u64
()
?
;
let
align
=
self
.value_to_primval
(
args
[
1
],
usize
)
?
.to_u64
()
?
;
if
size
==
0
{
return
Err
(
EvalError
::
HeapAllocZeroBytes
);
}
if
!
align
.is_power_of_two
()
{
return
Err
(
EvalError
::
HeapAllocNonPowerOfTwoAlignment
(
align
));
}
let
ptr
=
self
.memory
.allocate
(
size
,
align
)
?
;
self
.write_primval
(
dest
,
PrimVal
::
Ptr
(
ptr
),
dest_ty
)
?
;
}
...
...
@@ -603,6 +609,12 @@ fn call_c_abi(
"__rust_allocate_zeroed"
=>
{
let
size
=
self
.value_to_primval
(
args
[
0
],
usize
)
?
.to_u64
()
?
;
let
align
=
self
.value_to_primval
(
args
[
1
],
usize
)
?
.to_u64
()
?
;
if
size
==
0
{
return
Err
(
EvalError
::
HeapAllocZeroBytes
);
}
if
!
align
.is_power_of_two
()
{
return
Err
(
EvalError
::
HeapAllocNonPowerOfTwoAlignment
(
align
));
}
let
ptr
=
self
.memory
.allocate
(
size
,
align
)
?
;
self
.memory
.write_repeat
(
ptr
,
0
,
size
)
?
;
self
.write_primval
(
dest
,
PrimVal
::
Ptr
(
ptr
),
dest_ty
)
?
;
...
...
@@ -611,8 +623,14 @@ fn call_c_abi(
"__rust_deallocate"
=>
{
let
ptr
=
args
[
0
]
.read_ptr
(
&
self
.memory
)
?
.to_ptr
()
?
;
// FIXME: insert sanity check for size and align?
let
_
old_size
=
self
.value_to_primval
(
args
[
1
],
usize
)
?
.to_u64
()
?
;
let
_
align
=
self
.value_to_primval
(
args
[
2
],
usize
)
?
.to_u64
()
?
;
let
old_size
=
self
.value_to_primval
(
args
[
1
],
usize
)
?
.to_u64
()
?
;
let
align
=
self
.value_to_primval
(
args
[
2
],
usize
)
?
.to_u64
()
?
;
if
old_size
==
0
{
return
Err
(
EvalError
::
HeapAllocZeroBytes
);
}
if
!
align
.is_power_of_two
()
{
return
Err
(
EvalError
::
HeapAllocNonPowerOfTwoAlignment
(
align
));
}
self
.memory
.deallocate
(
ptr
)
?
;
},
...
...
@@ -620,6 +638,12 @@ fn call_c_abi(
let
ptr
=
args
[
0
]
.read_ptr
(
&
self
.memory
)
?
.to_ptr
()
?
;
let
size
=
self
.value_to_primval
(
args
[
2
],
usize
)
?
.to_u64
()
?
;
let
align
=
self
.value_to_primval
(
args
[
3
],
usize
)
?
.to_u64
()
?
;
if
size
==
0
{
return
Err
(
EvalError
::
HeapAllocZeroBytes
);
}
if
!
align
.is_power_of_two
()
{
return
Err
(
EvalError
::
HeapAllocNonPowerOfTwoAlignment
(
align
));
}
let
new_ptr
=
self
.memory
.reallocate
(
ptr
,
size
,
align
)
?
;
self
.write_primval
(
dest
,
PrimVal
::
Ptr
(
new_ptr
),
dest_ty
)
?
;
}
...
...
@@ -640,7 +664,7 @@ fn call_c_abi(
f_instance
,
mir
.span
,
mir
,
Lvalue
::
zst
(),
Lvalue
::
undef
(),
StackPopCleanup
::
Goto
(
dest_block
),
)
?
;
...
...
tests/compile-fail/zst.rs
浏览文件 @
9be3e918
fn
main
()
{
let
x
=
&
()
as
*
const
()
as
*
const
i32
;
let
_
=
unsafe
{
*
x
};
//~ ERROR: tried to access memory
through an invalid pointer
let
_
=
unsafe
{
*
x
};
//~ ERROR: tried to access memory
with alignment 1, but alignment 4 is required
}
tests/compile-fail/zst2.rs
0 → 100644
浏览文件 @
9be3e918
// error-pattern: the evaluated program panicked
#[derive(Debug)]
struct
A
;
fn
main
()
{
assert_eq!
(
&
A
as
*
const
A
as
*
const
(),
&
()
as
*
const
_
);
}
tests/compile-fail/zst3.rs
0 → 100644
浏览文件 @
9be3e918
// error-pattern: the evaluated program panicked
#[derive(Debug)]
struct
A
;
fn
main
()
{
assert_eq!
(
&
A
as
*
const
A
,
&
A
as
*
const
A
);
}
tests/run-pass/zst.rs
浏览文件 @
9be3e918
...
...
@@ -13,8 +13,6 @@ fn use_zst() -> A {
fn
main
()
{
assert_eq!
(
zst_ret
(),
A
);
assert_eq!
(
use_zst
(),
A
);
assert_eq!
(
&
A
as
*
const
A
as
*
const
(),
&
()
as
*
const
_
);
assert_eq!
(
&
A
as
*
const
A
,
&
A
as
*
const
A
);
let
x
=
42
as
*
mut
();
unsafe
{
*
x
=
();
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录