Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
e90ee167
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,发现更多精彩内容 >>
未验证
提交
e90ee167
编写于
6月 20, 2016
作者:
O
Oliver Schneider
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix comparing of function pointers
上级
d9776427
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
37 addition
and
9 deletion
+37
-9
src/interpreter/mod.rs
src/interpreter/mod.rs
+4
-0
src/memory.rs
src/memory.rs
+18
-8
src/primval.rs
src/primval.rs
+13
-1
tests/run-pass/function_pointers.rs
tests/run-pass/function_pointers.rs
+2
-0
未找到文件。
src/interpreter/mod.rs
浏览文件 @
e90ee167
...
...
@@ -1404,6 +1404,10 @@ pub fn read_primval(&mut self, ptr: Pointer, ty: Ty<'tcx>) -> EvalResult<'tcx, P
(
8
,
&
ty
::
TyUint
(
UintTy
::
Us
))
|
(
_
,
&
ty
::
TyUint
(
UintTy
::
U64
))
=>
PrimVal
::
U64
(
self
.memory
.read_uint
(
ptr
,
8
)
?
as
u64
),
(
_
,
&
ty
::
TyFnDef
(
def_id
,
substs
,
fn_ty
))
=>
{
PrimVal
::
FnPtr
(
self
.memory
.create_fn_ptr
(
def_id
,
substs
,
fn_ty
))
},
(
_
,
&
ty
::
TyFnPtr
(
_
))
=>
self
.memory
.read_ptr
(
ptr
)
.map
(
PrimVal
::
FnPtr
)
?
,
(
_
,
&
ty
::
TyRef
(
_
,
ty
::
TypeAndMut
{
ty
,
..
}))
|
(
_
,
&
ty
::
TyRawPtr
(
ty
::
TypeAndMut
{
ty
,
..
}))
=>
{
if
self
.type_is_sized
(
ty
)
{
...
...
src/memory.rs
浏览文件 @
e90ee167
...
...
@@ -42,7 +42,7 @@ pub fn offset(self, i: isize) -> Self {
}
}
#[derive(Debug,
Copy,
Clone)]
#[derive(Debug,
Copy,
Clone
,
Hash,
Eq,
PartialEq
)]
pub
struct
FunctionDefinition
<
'tcx
>
{
pub
def_id
:
DefId
,
pub
substs
:
&
'tcx
Substs
<
'tcx
>
,
...
...
@@ -59,6 +59,8 @@ pub struct Memory<'tcx> {
/// Function "allocations". They exist solely so pointers have something to point to, and
/// we can figure out what they point to.
functions
:
HashMap
<
AllocId
,
FunctionDefinition
<
'tcx
>>
,
/// Inverse map of `functions` so we don't allocate a new pointer every time we need one
function_definitions
:
HashMap
<
FunctionDefinition
<
'tcx
>
,
AllocId
>
,
next_id
:
AllocId
,
pub
pointer_size
:
usize
,
}
...
...
@@ -69,22 +71,29 @@ pub fn new(pointer_size: usize) -> Self {
Memory
{
alloc_map
:
HashMap
::
new
(),
functions
:
HashMap
::
new
(),
function_definitions
:
HashMap
::
new
(),
next_id
:
AllocId
(
0
),
pointer_size
:
pointer_size
,
}
}
// FIXME: never create two pointers to the same def_id + substs combination
// maybe re-use the statics cache of the EvalContext?
pub
fn
create_fn_ptr
(
&
mut
self
,
def_id
:
DefId
,
substs
:
&
'tcx
Substs
<
'tcx
>
,
fn_ty
:
&
'tcx
BareFnTy
<
'tcx
>
)
->
Pointer
{
let
id
=
self
.next_id
;
debug!
(
"creating fn ptr: {}"
,
id
);
self
.next_id
.0
+=
1
;
self
.functions
.insert
(
id
,
FunctionDefinition
{
let
def
=
FunctionDefinition
{
def_id
:
def_id
,
substs
:
substs
,
fn_ty
:
fn_ty
,
});
};
if
let
Some
(
&
alloc_id
)
=
self
.function_definitions
.get
(
&
def
)
{
return
Pointer
{
alloc_id
:
alloc_id
,
offset
:
0
,
};
}
let
id
=
self
.next_id
;
debug!
(
"creating fn ptr: {}"
,
id
);
self
.next_id
.0
+=
1
;
self
.functions
.insert
(
id
,
def
);
self
.function_definitions
.insert
(
def
,
id
);
Pointer
{
alloc_id
:
id
,
offset
:
0
,
...
...
@@ -361,6 +370,7 @@ pub fn write_primval(&mut self, ptr: Pointer, val: PrimVal) -> EvalResult<'tcx,
PrimVal
::
U32
(
n
)
=>
self
.write_uint
(
ptr
,
n
as
u64
,
4
),
PrimVal
::
U64
(
n
)
=>
self
.write_uint
(
ptr
,
n
as
u64
,
8
),
PrimVal
::
IntegerPtr
(
n
)
=>
self
.write_uint
(
ptr
,
n
as
u64
,
pointer_size
),
PrimVal
::
FnPtr
(
_
p
)
|
PrimVal
::
AbstractPtr
(
_
p
)
=>
unimplemented!
(),
}
}
...
...
src/primval.rs
浏览文件 @
e90ee167
...
...
@@ -10,6 +10,7 @@ pub enum PrimVal {
U8
(
u8
),
U16
(
u16
),
U32
(
u32
),
U64
(
u64
),
AbstractPtr
(
Pointer
),
FnPtr
(
Pointer
),
IntegerPtr
(
u64
),
}
...
...
@@ -130,9 +131,20 @@ fn unrelated_ptr_ops<'tcx>(bin_op: mir::BinOp) -> EvalResult<'tcx, PrimVal> {
(
IntegerPtr
(
l
),
IntegerPtr
(
r
))
=>
int_binops!
(
IntegerPtr
,
l
,
r
),
(
AbstractPtr
(
_
),
IntegerPtr
(
_
))
|
(
IntegerPtr
(
_
),
AbstractPtr
(
_
))
=>
(
AbstractPtr
(
_
),
IntegerPtr
(
_
))
|
(
IntegerPtr
(
_
),
AbstractPtr
(
_
))
|
(
FnPtr
(
_
),
AbstractPtr
(
_
))
|
(
AbstractPtr
(
_
),
FnPtr
(
_
))
|
(
FnPtr
(
_
),
IntegerPtr
(
_
))
|
(
IntegerPtr
(
_
),
FnPtr
(
_
))
=>
return
unrelated_ptr_ops
(
bin_op
),
(
FnPtr
(
l_ptr
),
FnPtr
(
r_ptr
))
=>
match
bin_op
{
Eq
=>
Bool
(
l_ptr
==
r_ptr
),
Ne
=>
Bool
(
l_ptr
!=
r_ptr
),
_
=>
return
Err
(
EvalError
::
Unimplemented
(
format!
(
"unimplemented fn ptr comparison: {:?}"
,
bin_op
))),
},
(
AbstractPtr
(
l_ptr
),
AbstractPtr
(
r_ptr
))
=>
{
if
l_ptr
.alloc_id
!=
r_ptr
.alloc_id
{
return
unrelated_ptr_ops
(
bin_op
);
...
...
tests/run-pass/function_pointers.rs
浏览文件 @
e90ee167
...
...
@@ -12,4 +12,6 @@ fn call_fn_ptr() -> i32 {
fn
main
()
{
assert_eq!
(
call_fn_ptr
(),
42
);
assert
!
(
return_fn_ptr
()
==
f
);
assert
!
(
return_fn_ptr
()
as
unsafe
fn
()
->
i32
==
f
as
fn
()
->
i32
as
unsafe
fn
()
->
i32
);
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录