Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
b78ca5f7
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,发现更多精彩内容 >>
未验证
提交
b78ca5f7
编写于
5月 30, 2016
作者:
O
Oliver Schneider
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
replace `panic!`s with `Result`
上级
55ce704a
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
52 addition
and
48 deletion
+52
-48
src/error.rs
src/error.rs
+6
-0
src/interpreter.rs
src/interpreter.rs
+25
-26
src/memory.rs
src/memory.rs
+3
-3
src/primval.rs
src/primval.rs
+18
-19
未找到文件。
src/error.rs
浏览文件 @
b78ca5f7
use
std
::
error
::
Error
;
use
std
::
fmt
;
use
rustc
::
mir
::
repr
as
mir
;
#[derive(Clone,
Debug)]
pub
enum
EvalError
{
...
...
@@ -11,6 +12,8 @@ pub enum EvalError {
ReadBytesAsPointer
,
InvalidPointerMath
,
ReadUndefBytes
,
InvalidBoolOp
(
mir
::
BinOp
),
Unimplemented
(
String
),
}
pub
type
EvalResult
<
T
>
=
Result
<
T
,
EvalError
>
;
...
...
@@ -34,6 +37,9 @@ fn description(&self) -> &str {
"attempted to do math or a comparison on pointers into different allocations"
,
EvalError
::
ReadUndefBytes
=>
"attempted to read undefined bytes"
,
EvalError
::
InvalidBoolOp
(
_
)
=>
"invalid boolean operation"
,
EvalError
::
Unimplemented
(
ref
msg
)
=>
msg
,
}
}
...
...
src/interpreter.rs
浏览文件 @
b78ca5f7
...
...
@@ -392,11 +392,11 @@ fn eval_terminator(&mut self, terminator: &mir::Terminator<'tcx>)
TerminatorTarget
::
Call
}
abi
=>
panic!
(
"can't handle function with {:?} ABI"
,
abi
),
abi
=>
return
Err
(
EvalError
::
Unimplemented
(
format!
(
"can't handle function with {:?} ABI"
,
abi
))
),
}
}
_
=>
panic!
(
"can't handle callee of type {:?}"
,
func_ty
),
_
=>
return
Err
(
EvalError
::
Unimplemented
(
format!
(
"can't handle callee of type {:?}"
,
func_ty
))
),
}
}
...
...
@@ -470,7 +470,7 @@ fn read_discriminant_value(&self, adt_ptr: Pointer, adt_ty: Ty<'tcx>) -> EvalRes
}
StructWrappedNullablePointer
{
nndiscr
,
ref
discrfield
,
..
}
=>
{
let
offset
=
self
.nonnull_offset
(
adt_ty
,
nndiscr
,
discrfield
);
let
offset
=
self
.nonnull_offset
(
adt_ty
,
nndiscr
,
discrfield
)
?
;
let
nonnull
=
adt_ptr
.offset
(
offset
.bytes
()
as
isize
);
self
.read_nonnull_discriminant_value
(
nonnull
,
nndiscr
)
?
}
...
...
@@ -620,7 +620,7 @@ fn call_intrinsic(
self
.memory
.write_uint
(
dest
,
n
*
elem_size
,
dest_size
)
?
;
}
_
=>
panic!
(
"unimplemented: size_of_val::<{:?}>"
,
ty
),
_
=>
return
Err
(
EvalError
::
Unimplemented
(
format!
(
"unimplemented: size_of_val::<{:?}>"
,
ty
))
),
}
}
}
...
...
@@ -631,7 +631,7 @@ fn call_intrinsic(
}
"uninit"
=>
self
.memory
.mark_definedness
(
dest
,
dest_size
,
false
)
?
,
name
=>
panic!
(
"can't handle intrinsic: {}"
,
name
),
name
=>
return
Err
(
EvalError
::
Unimplemented
(
format!
(
"unimplemented intrinsic: {}"
,
name
))
),
}
// Since we pushed no stack frame, the main loop will act
...
...
@@ -693,7 +693,7 @@ fn call_c_abi(
self
.memory
.write_int
(
dest
,
result
,
dest_size
)
?
;
}
_
=>
panic!
(
"can't call C ABI function: {}"
,
link_name
),
_
=>
return
Err
(
EvalError
::
Unimplemented
(
format!
(
"can't call C ABI function: {}"
,
link_name
))
),
}
// Since we pushed no stack frame, the main loop will act
...
...
@@ -748,7 +748,7 @@ fn eval_assignment(&mut self, lvalue: &mir::Lvalue<'tcx>, rvalue: &mir::Rvalue<'
let
ptr
=
self
.eval_operand
(
operand
)
?
;
let
ty
=
self
.operand_ty
(
operand
);
let
val
=
self
.read_primval
(
ptr
,
ty
)
?
;
self
.memory
.write_primval
(
dest
,
primval
::
unary_op
(
un_op
,
val
))
?
;
self
.memory
.write_primval
(
dest
,
primval
::
unary_op
(
un_op
,
val
)
?
)
?
;
}
Aggregate
(
ref
kind
,
ref
operands
)
=>
{
...
...
@@ -809,7 +809,7 @@ fn eval_assignment(&mut self, lvalue: &mir::Lvalue<'tcx>, rvalue: &mir::Rvalue<'
try!
(
self
.assign_fields
(
dest
,
offsets
,
operands
));
}
else
{
assert_eq!
(
operands
.len
(),
0
);
let
offset
=
self
.nonnull_offset
(
dest_ty
,
nndiscr
,
discrfield
);
let
offset
=
self
.nonnull_offset
(
dest_ty
,
nndiscr
,
discrfield
)
?
;
let
dest
=
dest
.offset
(
offset
.bytes
()
as
isize
);
try!
(
self
.memory
.write_isize
(
dest
,
0
));
}
...
...
@@ -834,8 +834,7 @@ fn eval_assignment(&mut self, lvalue: &mir::Lvalue<'tcx>, rvalue: &mir::Rvalue<'
}
}
_
=>
panic!
(
"can't handle destination layout {:?} when assigning {:?}"
,
dest_layout
,
kind
),
_
=>
return
Err
(
EvalError
::
Unimplemented
(
format!
(
"can't handle destination layout {:?} when assigning {:?}"
,
dest_layout
,
kind
))),
}
}
...
...
@@ -904,7 +903,7 @@ fn eval_assignment(&mut self, lvalue: &mir::Lvalue<'tcx>, rvalue: &mir::Rvalue<'
self
.memory
.write_usize
(
len_ptr
,
length
as
u64
)
?
;
}
_
=>
panic!
(
"can't handle cast: {:?}"
,
rvalue
),
_
=>
return
Err
(
EvalError
::
Unimplemented
(
format!
(
"can't handle cast: {:?}"
,
rvalue
))
),
}
}
...
...
@@ -914,7 +913,7 @@ fn eval_assignment(&mut self, lvalue: &mir::Lvalue<'tcx>, rvalue: &mir::Rvalue<'
self
.memory
.copy
(
src
,
dest
,
size
)
?
;
}
_
=>
panic!
(
"can't handle cast: {:?}"
,
rvalue
),
_
=>
return
Err
(
EvalError
::
Unimplemented
(
format!
(
"can't handle cast: {:?}"
,
rvalue
))
),
}
}
...
...
@@ -925,7 +924,7 @@ fn eval_assignment(&mut self, lvalue: &mir::Lvalue<'tcx>, rvalue: &mir::Rvalue<'
Ok
(())
}
fn
nonnull_offset
(
&
self
,
ty
:
Ty
<
'tcx
>
,
nndiscr
:
u64
,
discrfield
:
&
[
u32
])
->
Size
{
fn
nonnull_offset
(
&
self
,
ty
:
Ty
<
'tcx
>
,
nndiscr
:
u64
,
discrfield
:
&
[
u32
])
->
EvalResult
<
Size
>
{
// Skip the constant 0 at the start meant for LLVM GEP.
let
mut
path
=
discrfield
.iter
()
.skip
(
1
)
.map
(|
&
i
|
i
as
usize
);
...
...
@@ -946,49 +945,49 @@ fn nonnull_offset(&self, ty: Ty<'tcx>, nndiscr: u64, discrfield: &[u32]) -> Size
self
.field_path_offset
(
inner_ty
,
path
)
}
fn
field_path_offset
<
I
:
Iterator
<
Item
=
usize
>>
(
&
self
,
mut
ty
:
Ty
<
'tcx
>
,
path
:
I
)
->
Size
{
fn
field_path_offset
<
I
:
Iterator
<
Item
=
usize
>>
(
&
self
,
mut
ty
:
Ty
<
'tcx
>
,
path
:
I
)
->
EvalResult
<
Size
>
{
let
mut
offset
=
Size
::
from_bytes
(
0
);
// Skip the initial 0 intended for LLVM GEP.
for
field_index
in
path
{
let
field_offset
=
self
.get_field_offset
(
ty
,
field_index
);
ty
=
self
.get_field_ty
(
ty
,
field_index
);
let
field_offset
=
self
.get_field_offset
(
ty
,
field_index
)
?
;
ty
=
self
.get_field_ty
(
ty
,
field_index
)
?
;
offset
=
offset
.checked_add
(
field_offset
,
&
self
.tcx.data_layout
)
.unwrap
();
}
offset
Ok
(
offset
)
}
fn
get_field_ty
(
&
self
,
ty
:
Ty
<
'tcx
>
,
field_index
:
usize
)
->
Ty
<
'tcx
>
{
fn
get_field_ty
(
&
self
,
ty
:
Ty
<
'tcx
>
,
field_index
:
usize
)
->
EvalResult
<
Ty
<
'tcx
>
>
{
match
ty
.sty
{
ty
::
TyStruct
(
adt_def
,
substs
)
=>
{
adt_def
.struct_variant
()
.fields
[
field_index
]
.ty
(
self
.tcx
,
substs
)
Ok
(
adt_def
.struct_variant
()
.fields
[
field_index
]
.ty
(
self
.tcx
,
substs
)
)
}
ty
::
TyRef
(
_
,
ty
::
TypeAndMut
{
ty
,
..
})
|
ty
::
TyRawPtr
(
ty
::
TypeAndMut
{
ty
,
..
})
|
ty
::
TyBox
(
ty
)
=>
{
assert_eq!
(
field_index
,
0
);
ty
Ok
(
ty
)
}
_
=>
panic!
(
"can't handle type: {:?}"
,
ty
),
_
=>
Err
(
EvalError
::
Unimplemented
(
format!
(
"can't handle type: {:?}"
,
ty
))
),
}
}
fn
get_field_offset
(
&
self
,
ty
:
Ty
<
'tcx
>
,
field_index
:
usize
)
->
Size
{
fn
get_field_offset
(
&
self
,
ty
:
Ty
<
'tcx
>
,
field_index
:
usize
)
->
EvalResult
<
Size
>
{
let
layout
=
self
.type_layout
(
ty
);
use
rustc
::
ty
::
layout
::
Layout
::
*
;
match
*
layout
{
Univariant
{
..
}
=>
{
assert_eq!
(
field_index
,
0
);
Size
::
from_bytes
(
0
)
Ok
(
Size
::
from_bytes
(
0
)
)
}
FatPointer
{
..
}
=>
{
let
bytes
=
layout
::
FAT_PTR_ADDR
*
self
.memory.pointer_size
;
Size
::
from_bytes
(
bytes
as
u64
)
Ok
(
Size
::
from_bytes
(
bytes
as
u64
)
)
}
_
=>
panic!
(
"can't handle type: {:?}, with layout: {:?}"
,
ty
,
layout
),
_
=>
Err
(
EvalError
::
Unimplemented
(
format!
(
"can't handle type: {:?}, with layout: {:?}"
,
ty
,
layout
))
),
}
}
...
...
@@ -1223,7 +1222,7 @@ pub fn read_primval(&mut self, ptr: Pointer, ty: Ty<'tcx>) -> EvalResult<PrimVal
Err
(
e
)
=>
return
Err
(
e
),
}
}
else
{
panic!
(
"unimplemented: primitive read of fat pointer type: {:?}"
,
ty
);
return
Err
(
EvalError
::
Unimplemented
(
format!
(
"unimplemented: primitive read of fat pointer type: {:?}"
,
ty
))
);
}
}
...
...
src/memory.rs
浏览文件 @
b78ca5f7
...
...
@@ -80,7 +80,7 @@ pub fn allocate(&mut self, size: usize) -> Pointer {
pub
fn
reallocate
(
&
mut
self
,
ptr
:
Pointer
,
new_size
:
usize
)
->
EvalResult
<
()
>
{
if
ptr
.offset
!=
0
{
// TODO(solson): Report error about non-__rust_allocate'd pointer.
panic!
()
return
Err
(
EvalError
::
Unimplemented
(
format!
(
"bad pointer offset: {}"
,
ptr
.offset
)));
}
let
alloc
=
self
.get_mut
(
ptr
.alloc_id
)
?
;
...
...
@@ -90,7 +90,7 @@ pub fn reallocate(&mut self, ptr: Pointer, new_size: usize) -> EvalResult<()> {
alloc
.bytes
.extend
(
iter
::
repeat
(
0
)
.take
(
amount
));
alloc
.undef_mask
.grow
(
amount
,
false
);
}
else
if
size
>
new_size
{
unimplemented!
()
return
Err
(
EvalError
::
Unimplemented
(
format!
(
"unimplemented allocation relocation"
)));
// alloc.bytes.truncate(new_size);
// alloc.undef_mask.len = new_size;
// TODO: potentially remove relocations
...
...
@@ -103,7 +103,7 @@ pub fn reallocate(&mut self, ptr: Pointer, new_size: usize) -> EvalResult<()> {
pub
fn
deallocate
(
&
mut
self
,
ptr
:
Pointer
)
->
EvalResult
<
()
>
{
if
ptr
.offset
!=
0
{
// TODO(solson): Report error about non-__rust_allocate'd pointer.
panic!
()
return
Err
(
EvalError
::
Unimplemented
(
format!
(
"bad pointer offset: {}"
,
ptr
.offset
)));
}
if
self
.alloc_map
.remove
(
&
ptr
.alloc_id
)
.is_none
()
{
...
...
src/primval.rs
浏览文件 @
b78ca5f7
...
...
@@ -74,8 +74,7 @@ fn unrelated_ptr_ops(bin_op: mir::BinOp) -> EvalResult<PrimVal> {
BitOr
=>
l
|
r
,
BitXor
=>
l
^
r
,
BitAnd
=>
l
&
r
,
Add
|
Sub
|
Mul
|
Div
|
Rem
|
Shl
|
Shr
=>
panic!
(
"invalid binary operation on booleans: {:?}"
,
bin_op
),
Add
|
Sub
|
Mul
|
Div
|
Rem
|
Shl
|
Shr
=>
return
Err
(
EvalError
::
InvalidBoolOp
(
bin_op
)),
})
}
...
...
@@ -99,33 +98,33 @@ fn unrelated_ptr_ops(bin_op: mir::BinOp) -> EvalResult<PrimVal> {
Le
=>
Bool
(
l
<=
r
),
Gt
=>
Bool
(
l
>
r
),
Ge
=>
Bool
(
l
>=
r
),
_
=>
unimplemented!
(
),
_
=>
return
Err
(
EvalError
::
Unimplemented
(
format!
(
"unimplemented ptr op: {:?}"
,
bin_op
))
),
}
}
_
=>
unimplemented!
(
),
(
l
,
r
)
=>
return
Err
(
EvalError
::
Unimplemented
(
format!
(
"unimplemented binary op: {:?}, {:?}, {:?}"
,
l
,
r
,
bin_op
))
),
};
Ok
(
val
)
}
pub
fn
unary_op
(
un_op
:
mir
::
UnOp
,
val
:
PrimVal
)
->
PrimVal
{
pub
fn
unary_op
(
un_op
:
mir
::
UnOp
,
val
:
PrimVal
)
->
EvalResult
<
PrimVal
>
{
use
rustc
::
mir
::
repr
::
UnOp
::
*
;
use
self
::
PrimVal
::
*
;
match
(
un_op
,
val
)
{
(
Not
,
Bool
(
b
))
=>
Bool
(
!
b
),
(
Not
,
I8
(
n
))
=>
I8
(
!
n
),
(
Neg
,
I8
(
n
))
=>
I8
(
-
n
),
(
Not
,
I16
(
n
))
=>
I16
(
!
n
),
(
Neg
,
I16
(
n
))
=>
I16
(
-
n
),
(
Not
,
I32
(
n
))
=>
I32
(
!
n
),
(
Neg
,
I32
(
n
))
=>
I32
(
-
n
),
(
Not
,
I64
(
n
))
=>
I64
(
!
n
),
(
Neg
,
I64
(
n
))
=>
I64
(
-
n
),
(
Not
,
U8
(
n
))
=>
U8
(
!
n
),
(
Not
,
U16
(
n
))
=>
U16
(
!
n
),
(
Not
,
U32
(
n
))
=>
U32
(
!
n
),
(
Not
,
U64
(
n
))
=>
U64
(
!
n
),
_
=>
unimplemented!
(
),
(
Not
,
Bool
(
b
))
=>
Ok
(
Bool
(
!
b
)
),
(
Not
,
I8
(
n
))
=>
Ok
(
I8
(
!
n
)
),
(
Neg
,
I8
(
n
))
=>
Ok
(
I8
(
-
n
)
),
(
Not
,
I16
(
n
))
=>
Ok
(
I16
(
!
n
)
),
(
Neg
,
I16
(
n
))
=>
Ok
(
I16
(
-
n
)
),
(
Not
,
I32
(
n
))
=>
Ok
(
I32
(
!
n
)
),
(
Neg
,
I32
(
n
))
=>
Ok
(
I32
(
-
n
)
),
(
Not
,
I64
(
n
))
=>
Ok
(
I64
(
!
n
)
),
(
Neg
,
I64
(
n
))
=>
Ok
(
I64
(
-
n
)
),
(
Not
,
U8
(
n
))
=>
Ok
(
U8
(
!
n
)
),
(
Not
,
U16
(
n
))
=>
Ok
(
U16
(
!
n
)
),
(
Not
,
U32
(
n
))
=>
Ok
(
U32
(
!
n
)
),
(
Not
,
U64
(
n
))
=>
Ok
(
U64
(
!
n
)
),
_
=>
Err
(
EvalError
::
Unimplemented
(
format!
(
"unimplemented unary op: {:?}, {:?}"
,
un_op
,
val
))
),
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录