Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
4d38f8df
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,发现更多精彩内容 >>
提交
4d38f8df
编写于
7月 22, 2017
作者:
R
Ralf Jung
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
move pointer truncation to a common method in memory.rs
上级
40950b2c
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
113 addition
and
70 deletion
+113
-70
src/librustc_mir/interpret/cast.rs
src/librustc_mir/interpret/cast.rs
+2
-2
src/librustc_mir/interpret/eval_context.rs
src/librustc_mir/interpret/eval_context.rs
+3
-2
src/librustc_mir/interpret/memory.rs
src/librustc_mir/interpret/memory.rs
+95
-12
src/librustc_mir/interpret/terminator/mod.rs
src/librustc_mir/interpret/terminator/mod.rs
+2
-1
src/librustc_mir/interpret/traits.rs
src/librustc_mir/interpret/traits.rs
+4
-3
src/librustc_mir/interpret/value.rs
src/librustc_mir/interpret/value.rs
+7
-50
未找到文件。
src/librustc_mir/interpret/cast.rs
浏览文件 @
4d38f8df
...
...
@@ -4,7 +4,7 @@
use
error
::{
EvalResult
,
EvalError
};
use
eval_context
::
EvalContext
;
use
value
::
PrimVal
;
use
memory
::
MemoryPointer
;
use
memory
::
{
MemoryPointer
,
HasDataLayout
}
;
impl
<
'a
,
'tcx
>
EvalContext
<
'a
,
'tcx
>
{
pub
(
super
)
fn
cast_primval
(
...
...
@@ -78,7 +78,7 @@ fn cast_from_int(&self, v: u128, ty: ty::Ty<'tcx>, negative: bool) -> EvalResult
TyChar
=>
Err
(
EvalError
::
InvalidChar
(
v
)),
// No alignment check needed for raw pointers. But we have to truncate to target ptr size.
TyRawPtr
(
_
)
=>
Ok
(
PrimVal
::
Bytes
(
v
%
(
1u128
<<
self
.memory.layout.pointer_size
.bits
())
)),
TyRawPtr
(
_
)
=>
Ok
(
PrimVal
::
Bytes
(
self
.memory
.truncate_to_ptr
(
v
)
.0
as
u128
)),
_
=>
Err
(
EvalError
::
Unimplemented
(
format!
(
"int to {:?} cast"
,
ty
))),
}
...
...
src/librustc_mir/interpret/eval_context.rs
浏览文件 @
4d38f8df
...
...
@@ -1226,8 +1226,9 @@ pub(super) fn write_pair_to_ptr(
let
field_1_ty
=
self
.get_field_ty
(
ty
,
1
)
?
;
let
field_0_size
=
self
.type_size
(
field_0_ty
)
?
.expect
(
"pair element type must be sized"
);
let
field_1_size
=
self
.type_size
(
field_1_ty
)
?
.expect
(
"pair element type must be sized"
);
self
.memory
.write_primval
(
ptr
.offset
(
field_0
,
self
.memory.layout
)
?
.into
(),
a
,
field_0_size
)
?
;
self
.memory
.write_primval
(
ptr
.offset
(
field_1
,
self
.memory.layout
)
?
.into
(),
b
,
field_1_size
)
?
;
let
layout
=
self
.memory.layout
;
self
.memory
.write_primval
(
ptr
.offset
(
field_0
,
layout
)
?
.into
(),
a
,
field_0_size
)
?
;
self
.memory
.write_primval
(
ptr
.offset
(
field_1
,
layout
)
?
.into
(),
b
,
field_1_size
)
?
;
Ok
(())
}
...
...
src/librustc_mir/interpret/memory.rs
浏览文件 @
4d38f8df
...
...
@@ -7,7 +7,7 @@
use
syntax
::
ast
::
Mutability
;
use
error
::{
EvalError
,
EvalResult
};
use
value
::{
PrimVal
,
self
,
Pointer
};
use
value
::{
PrimVal
,
Pointer
};
use
eval_context
::
EvalContext
;
////////////////////////////////////////////////////////////////////////////////
...
...
@@ -73,26 +73,26 @@ pub fn new(alloc_id: AllocId, offset: u64) -> Self {
MemoryPointer
{
alloc_id
,
offset
}
}
pub
fn
wrapping_signed_offset
<
'tcx
>
(
self
,
i
:
i64
,
layout
:
&
TargetDataLayout
)
->
Self
{
MemoryPointer
::
new
(
self
.alloc_id
,
value
::
wrapping_signed_offset
(
self
.offset
,
i
,
layout
))
pub
(
crate
)
fn
wrapping_signed_offset
<
'a
,
L
:
HasDataLayout
<
'a
>>
(
self
,
i
:
i64
,
l
:
L
)
->
Self
{
MemoryPointer
::
new
(
self
.alloc_id
,
l
.wrapping_signed_offset
(
self
.offset
,
i
))
}
pub
fn
overflowing_signed_offset
<
'tcx
>
(
self
,
i
:
i128
,
layout
:
&
TargetDataLayout
)
->
(
Self
,
bool
)
{
let
(
res
,
over
)
=
value
::
overflowing_signed_offset
(
self
.offset
,
i
,
layout
);
pub
(
crate
)
fn
overflowing_signed_offset
<
'a
,
L
:
HasDataLayout
<
'a
>>
(
self
,
i
:
i128
,
l
:
L
)
->
(
Self
,
bool
)
{
let
(
res
,
over
)
=
l
.overflowing_signed_offset
(
self
.offset
,
i
);
(
MemoryPointer
::
new
(
self
.alloc_id
,
res
),
over
)
}
pub
fn
signed_offset
<
'tcx
>
(
self
,
i
:
i64
,
layout
:
&
TargetDataLayout
)
->
EvalResult
<
'tcx
,
Self
>
{
Ok
(
MemoryPointer
::
new
(
self
.alloc_id
,
value
::
signed_offset
(
self
.offset
,
i
,
layout
)
?
))
pub
(
crate
)
fn
signed_offset
<
'a
,
'tcx
,
L
:
HasDataLayout
<
'a
>>
(
self
,
i
:
i64
,
l
:
L
)
->
EvalResult
<
'tcx
,
Self
>
{
Ok
(
MemoryPointer
::
new
(
self
.alloc_id
,
l
.signed_offset
(
self
.offset
,
i
)
?
))
}
pub
fn
overflowing_offset
<
'tcx
>
(
self
,
i
:
u64
,
layout
:
&
TargetDataLayout
)
->
(
Self
,
bool
)
{
let
(
res
,
over
)
=
value
::
overflowing_offset
(
self
.offset
,
i
,
layout
);
pub
(
crate
)
fn
overflowing_offset
<
'a
,
L
:
HasDataLayout
<
'a
>>
(
self
,
i
:
u64
,
l
:
L
)
->
(
Self
,
bool
)
{
let
(
res
,
over
)
=
l
.overflowing_offset
(
self
.offset
,
i
);
(
MemoryPointer
::
new
(
self
.alloc_id
,
res
),
over
)
}
pub
fn
offset
<
'tcx
>
(
self
,
i
:
u64
,
layout
:
&
TargetDataLayout
)
->
EvalResult
<
'tcx
,
Self
>
{
Ok
(
MemoryPointer
::
new
(
self
.alloc_id
,
value
::
offset
(
self
.offset
,
i
,
layout
)
?
))
pub
(
crate
)
fn
offset
<
'a
,
'tcx
,
L
:
HasDataLayout
<
'a
>>
(
self
,
i
:
u64
,
l
:
L
)
->
EvalResult
<
'tcx
,
Self
>
{
Ok
(
MemoryPointer
::
new
(
self
.alloc_id
,
l
.offset
(
self
.offset
,
i
)
?
))
}
}
...
...
@@ -540,7 +540,7 @@ fn get_bytes_unchecked(&self, ptr: MemoryPointer, size: u64, align: u64) -> Eval
if
size
==
0
{
return
Ok
(
&
[]);
}
self
.check_bounds
(
ptr
.offset
(
size
,
self
.layout
)
?
,
true
)
?
;
// if ptr.offset is in bounds, then so is ptr (because offset checks for overflow)
self
.check_bounds
(
ptr
.offset
(
size
,
self
)
?
,
true
)
?
;
// if ptr.offset is in bounds, then so is ptr (because offset checks for overflow)
let
alloc
=
self
.get
(
ptr
.alloc_id
)
?
;
assert_eq!
(
ptr
.offset
as
usize
as
u64
,
ptr
.offset
);
assert_eq!
(
size
as
usize
as
u64
,
size
);
...
...
@@ -1131,6 +1131,7 @@ fn bit_index(bits: u64) -> (usize, usize) {
pub
(
crate
)
trait
HasMemory
<
'a
,
'tcx
>
{
fn
memory_mut
(
&
mut
self
)
->
&
mut
Memory
<
'a
,
'tcx
>
;
fn
memory
(
&
self
)
->
&
Memory
<
'a
,
'tcx
>
;
// These are not supposed to be overriden.
fn
read_maybe_aligned
<
F
,
T
>
(
&
mut
self
,
aligned
:
bool
,
f
:
F
)
->
EvalResult
<
'tcx
,
T
>
...
...
@@ -1159,6 +1160,11 @@ impl<'a, 'tcx> HasMemory<'a, 'tcx> for Memory<'a, 'tcx> {
fn
memory_mut
(
&
mut
self
)
->
&
mut
Memory
<
'a
,
'tcx
>
{
self
}
#[inline]
fn
memory
(
&
self
)
->
&
Memory
<
'a
,
'tcx
>
{
self
}
}
impl
<
'a
,
'tcx
>
HasMemory
<
'a
,
'tcx
>
for
EvalContext
<
'a
,
'tcx
>
{
...
...
@@ -1166,4 +1172,81 @@ impl<'a, 'tcx> HasMemory<'a, 'tcx> for EvalContext<'a, 'tcx> {
fn
memory_mut
(
&
mut
self
)
->
&
mut
Memory
<
'a
,
'tcx
>
{
&
mut
self
.memory
}
#[inline]
fn
memory
(
&
self
)
->
&
Memory
<
'a
,
'tcx
>
{
&
self
.memory
}
}
////////////////////////////////////////////////////////////////////////////////
// Pointer arithmetic
////////////////////////////////////////////////////////////////////////////////
pub
(
crate
)
trait
HasDataLayout
<
'a
>
:
Copy
{
fn
data_layout
(
self
)
->
&
'a
TargetDataLayout
;
// These are not supposed to be overriden.
//// Trunace the given value to the pointer size; also return whether there was an overflow
fn
truncate_to_ptr
(
self
,
val
:
u128
)
->
(
u64
,
bool
)
{
let
max_ptr_plus_1
=
1u128
<<
self
.data_layout
()
.pointer_size
.bits
();
((
val
%
max_ptr_plus_1
)
as
u64
,
val
>=
max_ptr_plus_1
)
}
// Overflow checking only works properly on the range from -u64 to +u64.
fn
overflowing_signed_offset
(
self
,
val
:
u64
,
i
:
i128
)
->
(
u64
,
bool
)
{
// FIXME: is it possible to over/underflow here?
if
i
<
0
{
// trickery to ensure that i64::min_value() works fine
// this formula only works for true negative values, it panics for zero!
let
n
=
u64
::
max_value
()
-
(
i
as
u64
)
+
1
;
val
.overflowing_sub
(
n
)
}
else
{
self
.overflowing_offset
(
val
,
i
as
u64
)
}
}
fn
overflowing_offset
(
self
,
val
:
u64
,
i
:
u64
)
->
(
u64
,
bool
)
{
let
(
res
,
over1
)
=
val
.overflowing_add
(
i
);
let
(
res
,
over2
)
=
self
.truncate_to_ptr
(
res
as
u128
);
(
res
,
over1
||
over2
)
}
fn
signed_offset
<
'tcx
>
(
self
,
val
:
u64
,
i
:
i64
)
->
EvalResult
<
'tcx
,
u64
>
{
let
(
res
,
over
)
=
self
.overflowing_signed_offset
(
val
,
i
as
i128
);
if
over
{
Err
(
EvalError
::
OverflowingMath
)
}
else
{
Ok
(
res
)
}
}
fn
offset
<
'tcx
>
(
self
,
val
:
u64
,
i
:
u64
)
->
EvalResult
<
'tcx
,
u64
>
{
let
(
res
,
over
)
=
self
.overflowing_offset
(
val
,
i
);
if
over
{
Err
(
EvalError
::
OverflowingMath
)
}
else
{
Ok
(
res
)
}
}
fn
wrapping_signed_offset
(
self
,
val
:
u64
,
i
:
i64
)
->
u64
{
self
.overflowing_signed_offset
(
val
,
i
as
i128
)
.0
}
}
impl
<
'a
>
HasDataLayout
<
'a
>
for
&
'a
TargetDataLayout
{
#[inline]
fn
data_layout
(
self
)
->
&
'a
TargetDataLayout
{
self
}
}
impl
<
'a
,
'b
,
'tcx
,
T
>
HasDataLayout
<
'a
>
for
&
'b
T
where
T
:
HasMemory
<
'a
,
'tcx
>
{
#[inline]
fn
data_layout
(
self
)
->
&
'a
TargetDataLayout
{
self
.memory
()
.layout
}
}
src/librustc_mir/interpret/terminator/mod.rs
浏览文件 @
4d38f8df
...
...
@@ -814,8 +814,9 @@ fn call_c_abi(
if
let
Some
((
name
,
value
))
=
new
{
// +1 for the null terminator
let
value_copy
=
self
.memory
.allocate
((
value
.len
()
+
1
)
as
u64
,
1
,
Kind
::
Env
)
?
;
let
layout
=
self
.memory.layout
;
self
.memory
.write_bytes
(
value_copy
.into
(),
&
value
)
?
;
self
.memory
.write_bytes
(
value_copy
.offset
(
value
.len
()
as
u64
,
self
.memory.
layout
)
?
.into
(),
&
[
0
])
?
;
self
.memory
.write_bytes
(
value_copy
.offset
(
value
.len
()
as
u64
,
layout
)
?
.into
(),
&
[
0
])
?
;
if
let
Some
(
var
)
=
self
.env_vars
.insert
(
name
.to_owned
(),
value_copy
)
{
self
.memory
.deallocate
(
var
,
None
,
Kind
::
Env
)
?
;
}
...
...
src/librustc_mir/interpret/traits.rs
浏览文件 @
4d38f8df
...
...
@@ -57,14 +57,15 @@ pub fn get_vtable(&mut self, ty: Ty<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>) ->
let
drop
=
self
.memory
.create_fn_alloc
(
drop
);
self
.memory
.write_ptr
(
vtable
,
drop
)
?
;
self
.memory
.write_usize
(
vtable
.offset
(
ptr_size
,
self
.memory.layout
)
?
,
size
)
?
;
self
.memory
.write_usize
(
vtable
.offset
(
ptr_size
*
2
,
self
.memory.layout
)
?
,
align
)
?
;
let
layout
=
self
.memory.layout
;
self
.memory
.write_usize
(
vtable
.offset
(
ptr_size
,
layout
)
?
,
size
)
?
;
self
.memory
.write_usize
(
vtable
.offset
(
ptr_size
*
2
,
layout
)
?
,
align
)
?
;
for
(
i
,
method
)
in
::
rustc
::
traits
::
get_vtable_methods
(
self
.tcx
,
trait_ref
)
.enumerate
()
{
if
let
Some
((
def_id
,
substs
))
=
method
{
let
instance
=
eval_context
::
resolve
(
self
.tcx
,
def_id
,
substs
);
let
fn_ptr
=
self
.memory
.create_fn_alloc
(
instance
);
self
.memory
.write_ptr
(
vtable
.offset
(
ptr_size
*
(
3
+
i
as
u64
),
self
.memory.
layout
)
?
,
fn_ptr
)
?
;
self
.memory
.write_ptr
(
vtable
.offset
(
ptr_size
*
(
3
+
i
as
u64
),
layout
)
?
,
fn_ptr
)
?
;
}
}
...
...
src/librustc_mir/interpret/value.rs
浏览文件 @
4d38f8df
#![allow(unknown_lints)]
#![allow(float_cmp)]
use
rustc
::
ty
::
layout
::
TargetDataLayout
;
use
error
::{
EvalError
,
EvalResult
};
use
memory
::{
Memory
,
MemoryPointer
,
HasMemory
};
use
memory
::{
Memory
,
MemoryPointer
,
HasMemory
,
HasDataLayout
};
pub
(
super
)
fn
bytes_to_f32
(
bytes
:
u128
)
->
f32
{
f32
::
from_bits
(
bytes
as
u32
)
...
...
@@ -61,33 +59,33 @@ pub fn into_inner_primval(self) -> PrimVal {
self
.primval
}
pub
(
crate
)
fn
signed_offset
(
self
,
i
:
i64
,
layout
:
&
TargetDataLayout
)
->
EvalResult
<
'tcx
,
Self
>
{
pub
(
crate
)
fn
signed_offset
<
'a
,
L
:
HasDataLayout
<
'a
>>
(
self
,
i
:
i64
,
layout
:
L
)
->
EvalResult
<
'tcx
,
Self
>
{
match
self
.primval
{
PrimVal
::
Bytes
(
b
)
=>
{
assert_eq!
(
b
as
u64
as
u128
,
b
);
Ok
(
Pointer
::
from
(
PrimVal
::
Bytes
(
signed_offset
(
b
as
u64
,
i
,
layout
)
?
as
u128
)))
Ok
(
Pointer
::
from
(
PrimVal
::
Bytes
(
layout
.signed_offset
(
b
as
u64
,
i
)
?
as
u128
)))
},
PrimVal
::
Ptr
(
ptr
)
=>
ptr
.signed_offset
(
i
,
layout
)
.map
(
Pointer
::
from
),
PrimVal
::
Undef
=>
Err
(
EvalError
::
ReadUndefBytes
),
}
}
pub
(
crate
)
fn
offset
(
self
,
i
:
u64
,
layout
:
&
TargetDataLayout
)
->
EvalResult
<
'tcx
,
Self
>
{
pub
(
crate
)
fn
offset
<
'a
,
L
:
HasDataLayout
<
'a
>>
(
self
,
i
:
u64
,
layout
:
L
)
->
EvalResult
<
'tcx
,
Self
>
{
match
self
.primval
{
PrimVal
::
Bytes
(
b
)
=>
{
assert_eq!
(
b
as
u64
as
u128
,
b
);
Ok
(
Pointer
::
from
(
PrimVal
::
Bytes
(
offset
(
b
as
u64
,
i
,
layout
)
?
as
u128
)))
Ok
(
Pointer
::
from
(
PrimVal
::
Bytes
(
layout
.offset
(
b
as
u64
,
i
)
?
as
u128
)))
},
PrimVal
::
Ptr
(
ptr
)
=>
ptr
.offset
(
i
,
layout
)
.map
(
Pointer
::
from
),
PrimVal
::
Undef
=>
Err
(
EvalError
::
ReadUndefBytes
),
}
}
pub
(
crate
)
fn
wrapping_signed_offset
(
self
,
i
:
i64
,
layout
:
&
TargetDataLayout
)
->
EvalResult
<
'tcx
,
Self
>
{
pub
(
crate
)
fn
wrapping_signed_offset
<
'a
,
L
:
HasDataLayout
<
'a
>>
(
self
,
i
:
i64
,
layout
:
L
)
->
EvalResult
<
'tcx
,
Self
>
{
match
self
.primval
{
PrimVal
::
Bytes
(
b
)
=>
{
assert_eq!
(
b
as
u64
as
u128
,
b
);
Ok
(
Pointer
::
from
(
PrimVal
::
Bytes
(
wrapping_signed_offset
(
b
as
u64
,
i
,
layout
)
as
u128
)))
Ok
(
Pointer
::
from
(
PrimVal
::
Bytes
(
layout
.wrapping_signed_offset
(
b
as
u64
,
i
)
as
u128
)))
},
PrimVal
::
Ptr
(
ptr
)
=>
Ok
(
Pointer
::
from
(
ptr
.wrapping_signed_offset
(
i
,
layout
))),
PrimVal
::
Undef
=>
Err
(
EvalError
::
ReadUndefBytes
),
...
...
@@ -323,47 +321,6 @@ pub fn to_bool(self) -> EvalResult<'tcx, bool> {
}
}
// Overflow checking only works properly on the range from -u64 to +u64.
pub
fn
overflowing_signed_offset
<
'tcx
>
(
val
:
u64
,
i
:
i128
,
layout
:
&
TargetDataLayout
)
->
(
u64
,
bool
)
{
// FIXME: is it possible to over/underflow here?
if
i
<
0
{
// trickery to ensure that i64::min_value() works fine
// this formula only works for true negative values, it panics for zero!
let
n
=
u64
::
max_value
()
-
(
i
as
u64
)
+
1
;
val
.overflowing_sub
(
n
)
}
else
{
overflowing_offset
(
val
,
i
as
u64
,
layout
)
}
}
pub
fn
overflowing_offset
<
'tcx
>
(
val
:
u64
,
i
:
u64
,
layout
:
&
TargetDataLayout
)
->
(
u64
,
bool
)
{
let
(
res
,
over
)
=
val
.overflowing_add
(
i
);
((
res
as
u128
%
(
1u128
<<
layout
.pointer_size
.bits
()))
as
u64
,
over
||
res
as
u128
>=
(
1u128
<<
layout
.pointer_size
.bits
()))
}
pub
fn
signed_offset
<
'tcx
>
(
val
:
u64
,
i
:
i64
,
layout
:
&
TargetDataLayout
)
->
EvalResult
<
'tcx
,
u64
>
{
let
(
res
,
over
)
=
overflowing_signed_offset
(
val
,
i
as
i128
,
layout
);
if
over
{
Err
(
EvalError
::
OverflowingMath
)
}
else
{
Ok
(
res
)
}
}
pub
fn
offset
<
'tcx
>
(
val
:
u64
,
i
:
u64
,
layout
:
&
TargetDataLayout
)
->
EvalResult
<
'tcx
,
u64
>
{
let
(
res
,
over
)
=
overflowing_offset
(
val
,
i
,
layout
);
if
over
{
Err
(
EvalError
::
OverflowingMath
)
}
else
{
Ok
(
res
)
}
}
pub
fn
wrapping_signed_offset
<
'tcx
>
(
val
:
u64
,
i
:
i64
,
layout
:
&
TargetDataLayout
)
->
u64
{
overflowing_signed_offset
(
val
,
i
as
i128
,
layout
)
.0
}
impl
PrimValKind
{
pub
fn
is_int
(
self
)
->
bool
{
use
self
::
PrimValKind
::
*
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录