Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
c8079c65
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,发现更多精彩内容 >>
未验证
提交
c8079c65
编写于
6月 28, 2017
作者:
O
Oliver Schneider
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Address comments
上级
42d3edad
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
23 addition
and
19 deletion
+23
-19
src/eval_context.rs
src/eval_context.rs
+17
-9
src/operator.rs
src/operator.rs
+2
-6
src/terminator/mod.rs
src/terminator/mod.rs
+4
-4
未找到文件。
src/eval_context.rs
浏览文件 @
c8079c65
...
...
@@ -169,6 +169,20 @@ pub fn stack(&self) -> &[Frame<'tcx>] {
&
self
.stack
}
/// Returns true if the current frame or any parent frame is part of a ctfe.
///
/// Used to disable features in const eval, which do not have a rfc enabling
/// them or which can't be written in a way that they produce the same output
/// that evaluating the code at runtime would produce.
pub
fn
const_env
(
&
self
)
->
bool
{
for
frame
in
self
.stack
.iter
()
.rev
()
{
if
let
StackPopCleanup
::
MarkStatic
(
_
)
=
frame
.return_to_block
{
return
true
;
}
}
false
}
pub
(
crate
)
fn
str_to_value
(
&
mut
self
,
s
:
&
str
)
->
EvalResult
<
'tcx
,
Value
>
{
let
ptr
=
self
.memory
.allocate_cached
(
s
.as_bytes
())
?
;
Ok
(
Value
::
ByValPair
(
PrimVal
::
Ptr
(
ptr
),
PrimVal
::
from_u128
(
s
.len
()
as
u128
)))
...
...
@@ -655,7 +669,7 @@ pub(super) fn eval_rvalue_into_lvalue(
}
Len
(
ref
lvalue
)
=>
{
if
self
.
frame
()
.
const_env
()
{
if
self
.const_env
()
{
return
Err
(
EvalError
::
NeedsRfc
(
"computing the length of arrays"
.to_string
()));
}
let
src
=
self
.eval_lvalue
(
lvalue
)
?
;
...
...
@@ -704,7 +718,7 @@ pub(super) fn eval_rvalue_into_lvalue(
}
NullaryOp
(
mir
::
NullOp
::
Box
,
ty
)
=>
{
if
self
.
frame
()
.
const_env
()
{
if
self
.const_env
()
{
return
Err
(
EvalError
::
NeedsRfc
(
"
\"
heap
\"
allocations"
.to_string
()));
}
// FIXME: call the `exchange_malloc` lang item if available
...
...
@@ -718,7 +732,7 @@ pub(super) fn eval_rvalue_into_lvalue(
}
NullaryOp
(
mir
::
NullOp
::
SizeOf
,
ty
)
=>
{
if
self
.
frame
()
.
const_env
()
{
if
self
.const_env
()
{
return
Err
(
EvalError
::
NeedsRfc
(
"computing the size of types (size_of)"
.to_string
()));
}
let
size
=
self
.type_size
(
ty
)
?
.expect
(
"SizeOf nullary MIR operator called for unsized type"
);
...
...
@@ -1592,12 +1606,6 @@ pub fn modify_local<F>(
}
impl
<
'tcx
>
Frame
<
'tcx
>
{
pub
fn
const_env
(
&
self
)
->
bool
{
match
self
.return_to_block
{
StackPopCleanup
::
MarkStatic
(
_
)
=>
true
,
_
=>
false
,
}
}
pub
fn
get_local
(
&
self
,
local
:
mir
::
Local
)
->
EvalResult
<
'tcx
,
Value
>
{
// Subtract 1 because we don't store a value for the ReturnPointer, the local with index 0.
self
.locals
[
local
.index
()
-
1
]
.ok_or
(
EvalError
::
DeadLocal
)
...
...
src/operator.rs
浏览文件 @
c8079c65
...
...
@@ -151,12 +151,8 @@ pub fn binary_op(
let
usize
=
PrimValKind
::
from_uint_size
(
self
.memory
.pointer_size
());
let
isize
=
PrimValKind
::
from_int_size
(
self
.memory
.pointer_size
());
if
!
left_kind
.is_float
()
&&
!
right_kind
.is_float
()
{
if
(
!
left
.is_bytes
()
&&
!
right
.is_bytes
())
&&
self
.frame
()
.const_env
()
{
if
left
.is_ptr
()
&&
right
.is_ptr
()
{
return
Err
(
EvalError
::
NotConst
(
"Comparing pointers"
.to_string
()));
}
else
{
return
Err
(
EvalError
::
NeedsRfc
(
"Comparing Pointers integers with pointers"
.to_string
()));
}
if
(
!
left
.is_bytes
()
&&
!
right
.is_bytes
())
&&
self
.const_env
()
{
return
Err
(
EvalError
::
NeedsRfc
(
"Pointer arithmetic or comparison"
.to_string
()));
}
match
bin_op
{
Offset
if
left_kind
==
Ptr
&&
right_kind
==
usize
=>
{
...
...
src/terminator/mod.rs
浏览文件 @
c8079c65
...
...
@@ -37,7 +37,7 @@ pub(super) fn eval_terminator(
Goto
{
target
}
=>
self
.goto_block
(
target
),
SwitchInt
{
ref
discr
,
ref
values
,
ref
targets
,
..
}
=>
{
if
self
.
frame
()
.
const_env
()
{
if
self
.const_env
()
{
return
Err
(
EvalError
::
NeedsRfc
(
"branching (if, match, loop, ...)"
.to_string
()));
}
let
discr_val
=
self
.eval_operand
(
discr
)
?
;
...
...
@@ -95,7 +95,7 @@ pub(super) fn eval_terminator(
Drop
{
ref
location
,
target
,
..
}
=>
{
trace!
(
"TerminatorKind::drop: {:?}, {:?}"
,
location
,
self
.substs
());
if
self
.
frame
()
.
const_env
()
{
if
self
.const_env
()
{
return
Err
(
EvalError
::
NeedsRfc
(
"invoking `Drop::drop`"
.to_string
()));
}
let
lval
=
self
.eval_lvalue
(
location
)
?
;
...
...
@@ -430,7 +430,7 @@ fn eval_fn_call_inner(
let
mir
=
match
self
.load_mir
(
instance
.def
)
{
Ok
(
mir
)
=>
mir
,
Err
(
EvalError
::
NoMirFor
(
path
))
=>
{
if
self
.
frame
()
.
const_env
()
{
if
self
.const_env
()
{
return
Err
(
EvalError
::
NeedsRfc
(
format!
(
"calling extern function `{}`"
,
path
)));
}
self
.call_missing_fn
(
instance
,
destination
,
arg_operands
,
sig
,
path
)
?
;
...
...
@@ -439,7 +439,7 @@ fn eval_fn_call_inner(
Err
(
other
)
=>
return
Err
(
other
),
};
if
self
.
frame
()
.
const_env
()
&&
!
self
.tcx
.is_const_fn
(
instance
.def_id
())
{
if
self
.const_env
()
&&
!
self
.tcx
.is_const_fn
(
instance
.def_id
())
{
return
Err
(
EvalError
::
NotConst
(
format!
(
"calling non-const fn `{}`"
,
instance
)));
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录