Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
4fe41ad8
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,发现更多精彩内容 >>
提交
4fe41ad8
编写于
12月 17, 2016
作者:
S
Scott Olson
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Refactor PrimVal::bits() out of existence.
上级
9e244251
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
91 addition
and
71 deletion
+91
-71
src/cast.rs
src/cast.rs
+2
-2
src/eval_context.rs
src/eval_context.rs
+3
-3
src/memory.rs
src/memory.rs
+1
-2
src/operator.rs
src/operator.rs
+52
-28
src/terminator/intrinsic.rs
src/terminator/intrinsic.rs
+31
-24
src/terminator/mod.rs
src/terminator/mod.rs
+1
-1
src/value.rs
src/value.rs
+1
-11
未找到文件。
src/cast.rs
浏览文件 @
4fe41ad8
...
...
@@ -20,9 +20,9 @@ pub(super) fn cast_primval(
F32
=>
self
.cast_float
(
val
.to_f32
()
?
as
f64
,
dest_ty
),
F64
=>
self
.cast_float
(
val
.to_f64
()
?
,
dest_ty
),
I8
|
I16
|
I32
|
I64
=>
self
.cast_signed_int
(
val
.
bits
()
as
i64
,
dest_ty
),
I8
|
I16
|
I32
|
I64
=>
self
.cast_signed_int
(
val
.
to_i64
()
?
,
dest_ty
),
Bool
|
Char
|
U8
|
U16
|
U32
|
U64
=>
self
.cast_int
(
val
.
bits
()
,
dest_ty
,
false
),
Bool
|
Char
|
U8
|
U16
|
U32
|
U64
=>
self
.cast_int
(
val
.
to_u64
()
?
,
dest_ty
,
false
),
FnPtr
|
Ptr
=>
self
.cast_ptr
(
val
.to_ptr
()
?
,
dest_ty
),
}
...
...
src/eval_context.rs
浏览文件 @
4fe41ad8
...
...
@@ -1093,10 +1093,10 @@ pub(super) fn ty_to_primval_kind(&self, ty: Ty<'tcx>) -> EvalResult<'tcx, PrimVa
fn
ensure_valid_value
(
&
self
,
val
:
PrimVal
,
ty
:
Ty
<
'tcx
>
)
->
EvalResult
<
'tcx
,
()
>
{
match
ty
.sty
{
ty
::
TyBool
if
val
.
bits
()
>
1
=>
Err
(
EvalError
::
InvalidBool
),
ty
::
TyBool
if
val
.
to_bytes
()
?
>
1
=>
Err
(
EvalError
::
InvalidBool
),
ty
::
TyChar
if
::
std
::
char
::
from_u32
(
val
.
bits
()
as
u32
)
.is_none
()
=>
Err
(
EvalError
::
InvalidChar
(
val
.
bits
()
as
u32
as
u64
)),
ty
::
TyChar
if
::
std
::
char
::
from_u32
(
val
.
to_bytes
()
?
as
u32
)
.is_none
()
=>
Err
(
EvalError
::
InvalidChar
(
val
.
to_bytes
()
?
as
u32
as
u64
)),
_
=>
Ok
(()),
}
...
...
src/memory.rs
浏览文件 @
4fe41ad8
...
...
@@ -77,8 +77,7 @@ pub fn points_to_zst(&self) -> bool {
pub
fn
to_int
<
'tcx
>
(
&
self
)
->
EvalResult
<
'tcx
,
u64
>
{
match
self
.alloc_id
{
NEVER_ALLOC_ID
|
ZST_ALLOC_ID
=>
Ok
(
self
.offset
),
NEVER_ALLOC_ID
=>
Ok
(
self
.offset
),
_
=>
Err
(
EvalError
::
ReadPointerAsBytes
),
}
}
...
...
src/operator.rs
浏览文件 @
4fe41ad8
...
...
@@ -139,16 +139,38 @@ pub fn binary_op<'tcx>(
use
rustc
::
mir
::
BinOp
::
*
;
use
value
::
PrimValKind
::
*
;
// If the pointers are into the same allocation, fall through to the more general match
// later, which will do comparisons on the `bits` fields, which are the pointer offsets
// in this case.
let
left_ptr
=
left
.to_ptr
()
?
;
let
right_ptr
=
right
.to_ptr
()
?
;
if
left_ptr
.alloc_id
!=
right_ptr
.alloc_id
{
return
Ok
((
unrelated_ptr_ops
(
bin_op
,
left_ptr
,
right_ptr
)
?
,
false
));
// FIXME(solson): Temporary hack. It will go away when we get rid of Pointer's ability to store
// plain bytes, and leave that to PrimVal::Bytes.
fn
normalize
(
val
:
PrimVal
)
->
PrimVal
{
if
let
PrimVal
::
Ptr
(
ptr
)
=
val
{
if
let
Ok
(
bytes
)
=
ptr
.to_int
()
{
return
PrimVal
::
Bytes
(
bytes
);
}
}
val
}
let
(
left
,
right
)
=
(
normalize
(
left
),
normalize
(
right
));
let
(
l
,
r
)
=
match
(
left
,
right
)
{
(
PrimVal
::
Bytes
(
left_bytes
),
PrimVal
::
Bytes
(
right_bytes
))
=>
(
left_bytes
,
right_bytes
),
(
PrimVal
::
Ptr
(
left_ptr
),
PrimVal
::
Ptr
(
right_ptr
))
=>
{
if
left_ptr
.alloc_id
==
right_ptr
.alloc_id
{
// If the pointers are into the same allocation, fall through to the more general
// match later, which will do comparisons on the pointer offsets.
(
left_ptr
.offset
,
right_ptr
.offset
)
}
else
{
return
Ok
((
unrelated_ptr_ops
(
bin_op
,
left_ptr
,
right_ptr
)
?
,
false
));
}
}
(
PrimVal
::
Ptr
(
ptr
),
PrimVal
::
Bytes
(
bytes
))
|
(
PrimVal
::
Bytes
(
bytes
),
PrimVal
::
Ptr
(
ptr
))
=>
{
return
Ok
((
unrelated_ptr_ops
(
bin_op
,
ptr
,
Pointer
::
from_int
(
bytes
))
?
,
false
));
}
let
(
l
,
r
)
=
(
left
.bits
(),
right
.bits
());
(
PrimVal
::
Undef
,
_
)
|
(
_
,
PrimVal
::
Undef
)
=>
return
Err
(
EvalError
::
ReadUndefBytes
),
};
// These ops can have an RHS with a different numeric type.
if
bin_op
==
Shl
||
bin_op
==
Shr
{
...
...
@@ -165,11 +187,11 @@ pub fn binary_op<'tcx>(
// Cast to `u32` because `overflowing_sh{l,r}` only take `u32`, then apply the bitmask
// to ensure it's within the valid shift value range.
let
r
=
(
right
.bits
()
as
u32
)
&
(
type_bits
-
1
);
let
masked_shift_width
=
(
r
as
u32
)
&
(
type_bits
-
1
);
return
match
bin_op
{
Shl
=>
int_shift!
(
left_kind
,
overflowing_shl
,
l
,
r
),
Shr
=>
int_shift!
(
left_kind
,
overflowing_shr
,
l
,
r
),
Shl
=>
int_shift!
(
left_kind
,
overflowing_shl
,
l
,
masked_shift_width
),
Shr
=>
int_shift!
(
left_kind
,
overflowing_shr
,
l
,
masked_shift_width
),
_
=>
bug!
(
"it has already been checked that this is a shift op"
),
};
}
...
...
@@ -253,26 +275,28 @@ pub fn unary_op<'tcx>(
use
rustc
::
mir
::
UnOp
::
*
;
use
value
::
PrimValKind
::
*
;
let
bits
=
match
(
un_op
,
val_kind
)
{
(
Not
,
Bool
)
=>
!
bits_to_bool
(
val
.bits
())
as
u64
,
let
bytes
=
val
.to_bytes
()
?
;
let
result_bytes
=
match
(
un_op
,
val_kind
)
{
(
Not
,
Bool
)
=>
!
bits_to_bool
(
bytes
)
as
u64
,
(
Not
,
U8
)
=>
!
(
val
.bits
()
as
u8
)
as
u64
,
(
Not
,
U16
)
=>
!
(
val
.bits
()
as
u16
)
as
u64
,
(
Not
,
U32
)
=>
!
(
val
.bits
()
as
u32
)
as
u64
,
(
Not
,
U64
)
=>
!
val
.bits
()
,
(
Not
,
U8
)
=>
!
(
bytes
as
u8
)
as
u64
,
(
Not
,
U16
)
=>
!
(
bytes
as
u16
)
as
u64
,
(
Not
,
U32
)
=>
!
(
bytes
as
u32
)
as
u64
,
(
Not
,
U64
)
=>
!
bytes
,
(
Not
,
I8
)
=>
!
(
val
.bits
()
as
i8
)
as
u64
,
(
Not
,
I16
)
=>
!
(
val
.bits
()
as
i16
)
as
u64
,
(
Not
,
I32
)
=>
!
(
val
.bits
()
as
i32
)
as
u64
,
(
Not
,
I64
)
=>
!
(
val
.bits
()
as
i64
)
as
u64
,
(
Not
,
I8
)
=>
!
(
bytes
as
i8
)
as
u64
,
(
Not
,
I16
)
=>
!
(
bytes
as
i16
)
as
u64
,
(
Not
,
I32
)
=>
!
(
bytes
as
i32
)
as
u64
,
(
Not
,
I64
)
=>
!
(
bytes
as
i64
)
as
u64
,
(
Neg
,
I8
)
=>
-
(
val
.bits
()
as
i8
)
as
u64
,
(
Neg
,
I16
)
=>
-
(
val
.bits
()
as
i16
)
as
u64
,
(
Neg
,
I32
)
=>
-
(
val
.bits
()
as
i32
)
as
u64
,
(
Neg
,
I64
)
=>
-
(
val
.bits
()
as
i64
)
as
u64
,
(
Neg
,
I8
)
=>
-
(
bytes
as
i8
)
as
u64
,
(
Neg
,
I16
)
=>
-
(
bytes
as
i16
)
as
u64
,
(
Neg
,
I32
)
=>
-
(
bytes
as
i32
)
as
u64
,
(
Neg
,
I64
)
=>
-
(
bytes
as
i64
)
as
u64
,
(
Neg
,
F32
)
=>
f32_to_bits
(
-
bits_to_f32
(
val
.bits
()
)),
(
Neg
,
F64
)
=>
f64_to_bits
(
-
bits_to_f64
(
val
.bits
()
)),
(
Neg
,
F32
)
=>
f32_to_bits
(
-
bits_to_f32
(
bytes
)),
(
Neg
,
F64
)
=>
f64_to_bits
(
-
bits_to_f64
(
bytes
)),
_
=>
{
let
msg
=
format!
(
"unimplemented unary op: {:?}, {:?}"
,
un_op
,
val
);
...
...
@@ -280,5 +304,5 @@ pub fn unary_op<'tcx>(
}
};
Ok
(
PrimVal
::
Bytes
(
bit
s
))
Ok
(
PrimVal
::
Bytes
(
result_byte
s
))
}
src/terminator/intrinsic.rs
浏览文件 @
4fe41ad8
...
...
@@ -163,7 +163,7 @@ pub(super) fn call_intrinsic(
let
ty
=
substs
.type_at
(
0
);
let
num
=
self
.value_to_primval
(
arg_vals
[
0
],
ty
)
?
;
let
kind
=
self
.ty_to_primval_kind
(
ty
)
?
;
let
num
=
numeric_intrinsic
(
intrinsic_name
,
num
,
kind
);
let
num
=
numeric_intrinsic
(
intrinsic_name
,
num
,
kind
)
?
;
self
.write_primval
(
dest
,
num
,
ty
)
?
;
}
...
...
@@ -501,33 +501,40 @@ fn field_ty(
}
}
macro_rules!
integer_intrinsic
{
(
$name:expr
,
$val:expr
,
$kind:expr
,
$method:ident
)
=>
({
let
val
=
$val
;
use
value
::
PrimValKind
::
*
;
let
bits
=
match
$kind
{
I8
=>
(
val
.bits
()
as
i8
)
.
$method
()
as
u64
,
U8
=>
(
val
.bits
()
as
u8
)
.
$method
()
as
u64
,
I16
=>
(
val
.bits
()
as
i16
)
.
$method
()
as
u64
,
U16
=>
(
val
.bits
()
as
u16
)
.
$method
()
as
u64
,
I32
=>
(
val
.bits
()
as
i32
)
.
$method
()
as
u64
,
U32
=>
(
val
.bits
()
as
u32
)
.
$method
()
as
u64
,
I64
=>
(
val
.bits
()
as
i64
)
.
$method
()
as
u64
,
U64
=>
(
val
.bits
()
as
u64
)
.
$method
()
as
u64
,
_
=>
bug!
(
"invalid `{}` argument: {:?}"
,
$name
,
val
),
};
PrimVal
::
Bytes
(
bits
)
});
}
fn
numeric_intrinsic
<
'tcx
>
(
name
:
&
str
,
val
:
PrimVal
,
kind
:
PrimValKind
)
->
EvalResult
<
'tcx
,
PrimVal
>
{
macro_rules!
integer_intrinsic
{
(
$name:expr
,
$val:expr
,
$kind:expr
,
$method:ident
)
=>
({
let
val
=
$val
;
let
bytes
=
val
.to_bytes
()
?
;
use
value
::
PrimValKind
::
*
;
let
result_bytes
=
match
$kind
{
I8
=>
(
bytes
as
i8
)
.
$method
()
as
u64
,
U8
=>
(
bytes
as
u8
)
.
$method
()
as
u64
,
I16
=>
(
bytes
as
i16
)
.
$method
()
as
u64
,
U16
=>
(
bytes
as
u16
)
.
$method
()
as
u64
,
I32
=>
(
bytes
as
i32
)
.
$method
()
as
u64
,
U32
=>
(
bytes
as
u32
)
.
$method
()
as
u64
,
I64
=>
(
bytes
as
i64
)
.
$method
()
as
u64
,
U64
=>
bytes
.
$method
()
as
u64
,
_
=>
bug!
(
"invalid `{}` argument: {:?}"
,
$name
,
val
),
};
PrimVal
::
Bytes
(
result_bytes
)
});
}
fn
numeric_intrinsic
(
name
:
&
str
,
val
:
PrimVal
,
kind
:
PrimValKind
)
->
PrimVal
{
match
name
{
let
result_val
=
match
name
{
"bswap"
=>
integer_intrinsic!
(
"bswap"
,
val
,
kind
,
swap_bytes
),
"ctlz"
=>
integer_intrinsic!
(
"ctlz"
,
val
,
kind
,
leading_zeros
),
"ctpop"
=>
integer_intrinsic!
(
"ctpop"
,
val
,
kind
,
count_ones
),
"cttz"
=>
integer_intrinsic!
(
"cttz"
,
val
,
kind
,
trailing_zeros
),
_
=>
bug!
(
"not a numeric intrinsic: {}"
,
name
),
}
};
Ok
(
result_val
)
}
src/terminator/mod.rs
浏览文件 @
4fe41ad8
...
...
@@ -53,7 +53,7 @@ pub(super) fn eval_terminator(
for
(
index
,
const_val
)
in
values
.iter
()
.enumerate
()
{
let
val
=
self
.const_to_value
(
const_val
)
?
;
let
prim
=
self
.value_to_primval
(
val
,
discr_ty
)
?
;
if
discr_prim
.
bits
()
==
prim
.bits
()
{
if
discr_prim
.
to_bytes
()
?
==
prim
.to_bytes
()
?
{
target_block
=
targets
[
index
];
break
;
}
...
...
src/value.rs
浏览文件 @
4fe41ad8
...
...
@@ -117,16 +117,6 @@ pub(super) fn expect_slice(&self, mem: &Memory<'a, 'tcx>) -> EvalResult<'tcx, (P
}
impl
<
'tcx
>
PrimVal
{
// FIXME(solson): Remove this. It's a temporary function to aid refactoring, but it shouldn't
// stick around with this name.
pub
fn
bits
(
self
)
->
u64
{
match
self
{
PrimVal
::
Bytes
(
b
)
=>
b
,
PrimVal
::
Ptr
(
p
)
=>
p
.offset
,
PrimVal
::
Undef
=>
panic!
(
".bits()() on PrimVal::Undef"
),
}
}
pub
fn
from_u64
(
n
:
u64
)
->
Self
{
PrimVal
::
Bytes
(
n
)
}
...
...
@@ -151,7 +141,7 @@ pub fn from_char(c: char) -> Self {
PrimVal
::
Bytes
(
c
as
u64
)
}
fn
to_bytes
(
self
)
->
EvalResult
<
'tcx
,
u64
>
{
pub
fn
to_bytes
(
self
)
->
EvalResult
<
'tcx
,
u64
>
{
match
self
{
PrimVal
::
Bytes
(
b
)
=>
Ok
(
b
),
PrimVal
::
Ptr
(
p
)
=>
p
.to_int
(),
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录