Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
128c634c
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,发现更多精彩内容 >>
提交
128c634c
编写于
8月 20, 2018
作者:
R
Ralf Jung
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
also avoid recomputing the layout for unary and binary ops, where possible
上级
54c81ac9
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
47 addition
and
19 deletion
+47
-19
src/librustc_mir/interpret/operand.rs
src/librustc_mir/interpret/operand.rs
+4
-8
src/librustc_mir/interpret/step.rs
src/librustc_mir/interpret/step.rs
+38
-6
src/librustc_mir/interpret/terminator/mod.rs
src/librustc_mir/interpret/terminator/mod.rs
+5
-5
未找到文件。
src/librustc_mir/interpret/operand.rs
浏览文件 @
128c634c
...
...
@@ -497,19 +497,15 @@ pub(super) fn global_to_op(&mut self, gid: GlobalId<'tcx>) -> EvalResult<'tcx, O
/// We cannot do self.read_value(self.eval_operand) due to eval_operand taking &mut self,
/// so this helps avoid unnecessary let.
pub
fn
eval_operand_and_read_valty
(
#[inline]
pub
fn
eval_operand_and_read_value
(
&
mut
self
,
op
:
&
mir
::
Operand
<
'tcx
>
,
layout
:
Option
<
TyLayout
<
'tcx
>>
,
)
->
EvalResult
<
'tcx
,
ValTy
<
'tcx
>>
{
let
op
=
self
.eval_operand
(
op
,
None
)
?
;
let
op
=
self
.eval_operand
(
op
,
layout
)
?
;
self
.read_value
(
op
)
}
pub
fn
eval_operand_and_read_scalar
(
&
mut
self
,
op
:
&
mir
::
Operand
<
'tcx
>
,
)
->
EvalResult
<
'tcx
,
ScalarMaybeUndef
>
{
Ok
(
self
.eval_operand_and_read_valty
(
op
)
?
.to_scalar_or_undef
())
}
/// reads a tag and produces the corresponding variant index
pub
fn
read_discriminant_as_variant_index
(
...
...
src/librustc_mir/interpret/step.rs
浏览文件 @
128c634c
...
...
@@ -8,6 +8,33 @@
use
super
::{
EvalContext
,
Machine
};
/// Classify whether an operator is "left-homogeneous", i.e. the LHS has the
/// same type as the result.
#[inline]
fn
binop_left_homogeneous
(
op
:
mir
::
BinOp
)
->
bool
{
use
rustc
::
mir
::
BinOp
::
*
;
match
op
{
Add
|
Sub
|
Mul
|
Div
|
Rem
|
BitXor
|
BitAnd
|
BitOr
|
Offset
|
Shl
|
Shr
=>
true
,
Eq
|
Ne
|
Lt
|
Le
|
Gt
|
Ge
=>
false
,
}
}
/// Classify whether an operator is "right-homogeneous", i.e. the RHS has the
/// same type as the LHS.
#[inline]
fn
binop_right_homogeneous
(
op
:
mir
::
BinOp
)
->
bool
{
use
rustc
::
mir
::
BinOp
::
*
;
match
op
{
Add
|
Sub
|
Mul
|
Div
|
Rem
|
BitXor
|
BitAnd
|
BitOr
|
Eq
|
Ne
|
Lt
|
Le
|
Gt
|
Ge
=>
true
,
Offset
|
Shl
|
Shr
=>
false
,
}
}
impl
<
'a
,
'mir
,
'tcx
,
M
:
Machine
<
'mir
,
'tcx
>>
EvalContext
<
'a
,
'mir
,
'tcx
,
M
>
{
pub
fn
inc_step_counter_and_detect_loops
(
&
mut
self
)
->
EvalResult
<
'tcx
,
()
>
{
/// The number of steps between loop detector snapshots.
...
...
@@ -147,8 +174,10 @@ fn eval_rvalue_into_place(
}
BinaryOp
(
bin_op
,
ref
left
,
ref
right
)
=>
{
let
left
=
self
.eval_operand_and_read_valty
(
left
)
?
;
let
right
=
self
.eval_operand_and_read_valty
(
right
)
?
;
let
layout
=
if
binop_left_homogeneous
(
bin_op
)
{
Some
(
dest
.layout
)
}
else
{
None
};
let
left
=
self
.eval_operand_and_read_value
(
left
,
layout
)
?
;
let
layout
=
if
binop_right_homogeneous
(
bin_op
)
{
Some
(
left
.layout
)
}
else
{
None
};
let
right
=
self
.eval_operand_and_read_value
(
right
,
layout
)
?
;
self
.binop_ignore_overflow
(
bin_op
,
left
,
...
...
@@ -158,8 +187,10 @@ fn eval_rvalue_into_place(
}
CheckedBinaryOp
(
bin_op
,
ref
left
,
ref
right
)
=>
{
let
left
=
self
.eval_operand_and_read_valty
(
left
)
?
;
let
right
=
self
.eval_operand_and_read_valty
(
right
)
?
;
// Due to the extra boolean in the result, we can never reuse the `dest.layout`.
let
left
=
self
.eval_operand_and_read_value
(
left
,
None
)
?
;
let
layout
=
if
binop_right_homogeneous
(
bin_op
)
{
Some
(
left
.layout
)
}
else
{
None
};
let
right
=
self
.eval_operand_and_read_value
(
right
,
layout
)
?
;
self
.binop_with_overflow
(
bin_op
,
left
,
...
...
@@ -169,8 +200,9 @@ fn eval_rvalue_into_place(
}
UnaryOp
(
un_op
,
ref
operand
)
=>
{
let
val
=
self
.eval_operand_and_read_scalar
(
operand
)
?
;
let
val
=
self
.unary_op
(
un_op
,
val
.not_undef
()
?
,
dest
.layout
)
?
;
// The operand always has the same type as the result.
let
val
=
self
.eval_operand_and_read_value
(
operand
,
Some
(
dest
.layout
))
?
;
let
val
=
self
.unary_op
(
un_op
,
val
.to_scalar
()
?
,
dest
.layout
)
?
;
self
.write_scalar
(
val
,
dest
)
?
;
}
...
...
src/librustc_mir/interpret/terminator/mod.rs
浏览文件 @
128c634c
...
...
@@ -144,18 +144,18 @@ pub(super) fn eval_terminator(
target
,
..
}
=>
{
let
cond_val
=
self
.eval_operand_and_read_
scalar
(
cond
)
?
.not_undef
()
?
.to_bool
()
?
;
let
cond_val
=
self
.eval_operand_and_read_
value
(
cond
,
None
)
?
.to_scalar
()
?
.to_bool
()
?
;
if
expected
==
cond_val
{
self
.goto_block
(
target
);
}
else
{
use
rustc
::
mir
::
interpret
::
EvalErrorKind
::
*
;
return
match
*
msg
{
BoundsCheck
{
ref
len
,
ref
index
}
=>
{
let
len
=
self
.eval_operand_and_read_
scalar
(
len
)
.expect
(
"can't eval len"
)
let
len
=
self
.eval_operand_and_read_
value
(
len
,
None
)
.expect
(
"can't eval len"
)
.to_scalar
()
?
.to_bits
(
self
.memory
()
.pointer_size
())
?
as
u64
;
let
index
=
self
.eval_operand_and_read_
scalar
(
index
)
.expect
(
"can't eval index"
)
let
index
=
self
.eval_operand_and_read_
value
(
index
,
None
)
.expect
(
"can't eval index"
)
.to_scalar
()
?
.to_bits
(
self
.memory
()
.pointer_size
())
?
as
u64
;
err!
(
BoundsCheck
{
len
,
index
})
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录