Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
555fc41d
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,发现更多精彩内容 >>
提交
555fc41d
编写于
7月 13, 2017
作者:
O
Oliver Schneider
提交者:
GitHub
7月 13, 2017
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #243 from solson/magic_numbers
Get rid of magic numbers
上级
14c8fe7a
f8757aa0
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
88 addition
and
18 deletion
+88
-18
src/const_eval.rs
src/const_eval.rs
+17
-11
src/error.rs
src/error.rs
+5
-0
src/terminator/mod.rs
src/terminator/mod.rs
+66
-7
未找到文件。
src/const_eval.rs
浏览文件 @
555fc41d
use
rustc
::
hir
::
def_id
::
DefId
;
use
rustc
::
traits
::
Reveal
;
use
rustc
::
ty
::
subst
::
Substs
;
use
rustc
::
ty
::{
self
,
TyCtxt
};
use
rustc
::
ty
::{
self
,
TyCtxt
,
Ty
,
Instance
};
use
error
::{
EvalError
,
EvalResult
};
use
lvalue
::{
Global
,
GlobalId
,
Lvalue
};
use
value
::
PrimVal
;
use
rustc_const_math
::
ConstInt
;
use
eval_context
::{
EvalContext
,
StackPopCleanup
};
pub
fn
eval_body_as_
integer
<
'a
,
'tcx
>
(
pub
fn
eval_body_as_
primval
<
'a
,
'tcx
>
(
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
(
def_id
,
substs
):
(
DefId
,
&
'tcx
Substs
<
'tcx
>
)
,
)
->
EvalResult
<
'tcx
,
ConstInt
>
{
instance
:
Instance
<
'tcx
>
,
)
->
EvalResult
<
'tcx
,
(
PrimVal
,
Ty
<
'tcx
>
)
>
{
let
limits
=
::
ResourceLimits
::
default
();
let
mut
ecx
=
EvalContext
::
new
(
tcx
,
limits
);
let
instance
=
ecx
.resolve_associated_const
(
def_id
,
substs
);
let
cid
=
GlobalId
{
instance
,
promoted
:
None
};
if
ecx
.tcx
.has_attr
(
def_id
,
"linkage"
)
{
if
ecx
.tcx
.has_attr
(
instance
.def_id
()
,
"linkage"
)
{
return
Err
(
EvalError
::
NotConst
(
"extern global"
.to_string
()));
}
...
...
@@ -28,7 +26,7 @@ pub fn eval_body_as_integer<'a, 'tcx>(
ty
::
ParamEnv
::
empty
(
Reveal
::
All
),
mir
.span
);
let
cleanup
=
StackPopCleanup
::
MarkStatic
(
mutable
);
let
name
=
ty
::
tls
::
with
(|
tcx
|
tcx
.item_path_str
(
def_id
));
let
name
=
ty
::
tls
::
with
(|
tcx
|
tcx
.item_path_str
(
instance
.def_id
()
));
trace!
(
"pushing stack frame for global: {}"
,
name
);
ecx
.push_stack_frame
(
instance
,
...
...
@@ -41,11 +39,19 @@ pub fn eval_body_as_integer<'a, 'tcx>(
while
ecx
.step
()
?
{}
}
let
value
=
ecx
.globals
.get
(
&
cid
)
.expect
(
"global not cached"
)
.value
;
let
prim
=
ecx
.value_to_primval
(
value
,
mir
.return_ty
)
?
.to_bytes
()
?
;
Ok
((
ecx
.value_to_primval
(
value
,
mir
.return_ty
)
?
,
mir
.return_ty
))
}
pub
fn
eval_body_as_integer
<
'a
,
'tcx
>
(
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
instance
:
Instance
<
'tcx
>
,
)
->
EvalResult
<
'tcx
,
ConstInt
>
{
let
(
prim
,
ty
)
=
eval_body_as_primval
(
tcx
,
instance
)
?
;
let
prim
=
prim
.to_bytes
()
?
;
use
syntax
::
ast
::{
IntTy
,
UintTy
};
use
rustc
::
ty
::
TypeVariants
::
*
;
use
rustc_const_math
::{
ConstIsize
,
ConstUsize
};
Ok
(
match
mir
.return_
ty.sty
{
Ok
(
match
ty
.sty
{
TyInt
(
IntTy
::
I8
)
=>
ConstInt
::
I8
(
prim
as
i128
as
i8
),
TyInt
(
IntTy
::
I16
)
=>
ConstInt
::
I16
(
prim
as
i128
as
i16
),
TyInt
(
IntTy
::
I32
)
=>
ConstInt
::
I32
(
prim
as
i128
as
i32
),
...
...
src/error.rs
浏览文件 @
555fc41d
...
...
@@ -69,6 +69,7 @@ pub enum EvalError<'tcx> {
NeedsRfc
(
String
),
NotConst
(
String
),
ReadFromReturnPointer
,
PathNotFound
(
Vec
<
String
>
),
}
pub
type
EvalResult
<
'tcx
,
T
=
()
>
=
Result
<
T
,
EvalError
<
'tcx
>>
;
...
...
@@ -175,6 +176,8 @@ fn description(&self) -> &str {
"this feature is not compatible with constant evaluation"
,
ReadFromReturnPointer
=>
"tried to read from the return pointer"
,
EvalError
::
PathNotFound
(
_
)
=>
"a path could not be resolved, maybe the crate is not loaded"
,
}
}
...
...
@@ -215,6 +218,8 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!
(
f
,
"
\"
{}
\"
needs an rfc before being allowed inside constants"
,
msg
),
NotConst
(
ref
msg
)
=>
write!
(
f
,
"Cannot evaluate within constants:
\"
{}
\"
"
,
msg
),
EvalError
::
PathNotFound
(
ref
path
)
=>
write!
(
f
,
"Cannot find path {:?}"
,
path
),
_
=>
write!
(
f
,
"{}"
,
self
.description
()),
}
}
...
...
src/terminator/mod.rs
浏览文件 @
555fc41d
use
rustc
::
hir
::
def_id
::
DefId
;
use
rustc
::
hir
::
def_id
::
{
DefId
,
CRATE_DEF_INDEX
}
;
use
rustc
::
mir
;
use
rustc
::
ty
::{
self
,
TypeVariants
,
Ty
};
use
rustc
::
ty
::
layout
::
Layout
;
...
...
@@ -13,6 +13,8 @@
use
value
::{
PrimVal
,
Value
};
use
rustc_data_structures
::
indexed_vec
::
Idx
;
use
std
::
mem
;
mod
drop
;
mod
intrinsic
;
...
...
@@ -853,12 +855,32 @@ fn call_c_abi(
"sysconf"
=>
{
let
name
=
self
.value_to_primval
(
args
[
0
],
usize
)
?
.to_u64
()
?
;
trace!
(
"sysconf() called with name {}"
,
name
);
let
result
=
match
name
{
30
=>
PrimVal
::
Bytes
(
4096
),
// _SC_PAGESIZE
70
=>
PrimVal
::
from_i128
(
-
1
),
// _SC_GETPW_R_SIZE_MAX
_
=>
return
Err
(
EvalError
::
Unimplemented
(
format!
(
"Unimplemented sysconf name: {}"
,
name
)))
};
self
.write_primval
(
dest
,
result
,
dest_ty
)
?
;
// cache the sysconf integers via miri's global cache
let
paths
=
&
[
(
&
[
"libc"
,
"_SC_PAGESIZE"
],
PrimVal
::
Bytes
(
4096
)),
(
&
[
"libc"
,
"_SC_GETPW_R_SIZE_MAX"
],
PrimVal
::
from_i128
(
-
1
)),
];
let
mut
result
=
None
;
for
&
(
path
,
path_value
)
in
paths
{
if
let
Ok
(
instance
)
=
self
.resolve_path
(
path
)
{
use
lvalue
::
GlobalId
;
let
cid
=
GlobalId
{
instance
,
promoted
:
None
};
// compute global if not cached
let
val
=
match
self
.globals
.get
(
&
cid
)
.map
(|
glob
|
glob
.value
)
{
Some
(
value
)
=>
self
.value_to_primval
(
value
,
usize
)
?
.to_u64
()
?
,
None
=>
::
const_eval
::
eval_body_as_primval
(
self
.tcx
,
instance
)
?
.0
.to_u64
()
?
,
};
if
val
==
name
{
result
=
Some
(
path_value
);
break
;
}
}
}
if
let
Some
(
result
)
=
result
{
self
.write_primval
(
dest
,
result
,
dest_ty
)
?
;
}
else
{
return
Err
(
EvalError
::
Unimplemented
(
format!
(
"Unimplemented sysconf name: {}"
,
name
)));
}
}
// Hook pthread calls that go to the thread-local storage memory subsystem
...
...
@@ -933,4 +955,41 @@ fn call_c_abi(
self
.goto_block
(
dest_block
);
Ok
(())
}
/// Get an instance for a path.
fn
resolve_path
(
&
self
,
path
:
&
[
&
str
])
->
EvalResult
<
'tcx
,
ty
::
Instance
<
'tcx
>>
{
let
cstore
=
&
self
.tcx.sess.cstore
;
let
crates
=
cstore
.crates
();
crates
.iter
()
.find
(|
&&
krate
|
cstore
.crate_name
(
krate
)
==
path
[
0
])
.and_then
(|
krate
|
{
let
krate
=
DefId
{
krate
:
*
krate
,
index
:
CRATE_DEF_INDEX
,
};
let
mut
items
=
cstore
.item_children
(
krate
,
self
.tcx.sess
);
let
mut
path_it
=
path
.iter
()
.skip
(
1
)
.peekable
();
while
let
Some
(
segment
)
=
path_it
.next
()
{
for
item
in
&
mem
::
replace
(
&
mut
items
,
vec!
[])
{
if
item
.ident.name
==
*
segment
{
if
path_it
.peek
()
.is_none
()
{
return
Some
(
ty
::
Instance
::
mono
(
self
.tcx
,
item
.def
.def_id
()));
}
items
=
cstore
.item_children
(
item
.def
.def_id
(),
self
.tcx.sess
);
break
;
}
}
}
None
})
.ok_or_else
(||
{
let
path
=
path
.iter
()
.map
(|
&
s
|
s
.to_owned
())
.collect
();
EvalError
::
PathNotFound
(
path
)
})
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录