Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
4b831569
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,发现更多精彩内容 >>
未验证
提交
4b831569
编写于
7月 05, 2016
作者:
O
Oliver Schneider
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
implement floats by running the ops on the host architecture
上级
a7cc77a0
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
67 addition
and
3 deletion
+67
-3
src/interpreter/mod.rs
src/interpreter/mod.rs
+21
-3
src/memory.rs
src/memory.rs
+3
-0
src/primval.rs
src/primval.rs
+35
-0
tests/run-pass/floats.rs
tests/run-pass/floats.rs
+8
-0
未找到文件。
src/interpreter/mod.rs
浏览文件 @
4b831569
...
...
@@ -169,7 +169,8 @@ pub fn stack(&self) -> &[Frame<'a, 'tcx>] {
// TODO(solson): Try making const_to_primval instead.
fn
const_to_ptr
(
&
mut
self
,
const_val
:
&
const_val
::
ConstVal
)
->
EvalResult
<
'tcx
,
Pointer
>
{
use
rustc
::
middle
::
const_val
::
ConstVal
::
*
;
use
rustc_const_math
::{
ConstInt
,
ConstIsize
,
ConstUsize
};
use
rustc_const_math
::{
ConstInt
,
ConstIsize
,
ConstUsize
,
ConstFloat
};
use
std
::
mem
::
transmute
;
macro_rules!
i2p
{
(
$i:ident
,
$n:expr
)
=>
{{
let
ptr
=
self
.memory
.allocate
(
$n
);
...
...
@@ -178,7 +179,15 @@ fn const_to_ptr(&mut self, const_val: &const_val::ConstVal) -> EvalResult<'tcx,
}}
}
match
*
const_val
{
Float
(
_
f
)
=>
unimplemented!
(),
Float
(
ConstFloat
::
F32
(
f
))
=>
{
let
i
=
unsafe
{
transmute
::
<
_
,
u32
>
(
f
)
};
i2p!
(
i
,
4
)
},
Float
(
ConstFloat
::
F64
(
f
))
=>
{
let
i
=
unsafe
{
transmute
::
<
_
,
u64
>
(
f
)
};
i2p!
(
i
,
8
)
},
Float
(
ConstFloat
::
FInfer
{
..
})
=>
unreachable!
(),
Integral
(
ConstInt
::
Infer
(
_
))
=>
unreachable!
(),
Integral
(
ConstInt
::
InferSigned
(
_
))
=>
unreachable!
(),
Integral
(
ConstInt
::
I8
(
i
))
=>
i2p!
(
i
,
1
),
...
...
@@ -824,7 +833,8 @@ fn move_(&mut self, src: Pointer, dest: Pointer, ty: Ty<'tcx>) -> EvalResult<'tc
}
pub
fn
read_primval
(
&
mut
self
,
ptr
:
Pointer
,
ty
:
Ty
<
'tcx
>
)
->
EvalResult
<
'tcx
,
PrimVal
>
{
use
syntax
::
ast
::{
IntTy
,
UintTy
};
use
syntax
::
ast
::{
IntTy
,
UintTy
,
FloatTy
};
use
std
::
mem
::
transmute
;
let
val
=
match
(
self
.memory
.pointer_size
(),
&
ty
.sty
)
{
(
_
,
&
ty
::
TyBool
)
=>
PrimVal
::
Bool
(
self
.memory
.read_bool
(
ptr
)
?
),
(
_
,
&
ty
::
TyChar
)
=>
{
...
...
@@ -848,6 +858,14 @@ pub fn read_primval(&mut self, ptr: Pointer, ty: Ty<'tcx>) -> EvalResult<'tcx, P
(
_
,
&
ty
::
TyUint
(
UintTy
::
U32
))
=>
PrimVal
::
U32
(
self
.memory
.read_uint
(
ptr
,
4
)
?
as
u32
),
(
8
,
&
ty
::
TyUint
(
UintTy
::
Us
))
|
(
_
,
&
ty
::
TyUint
(
UintTy
::
U64
))
=>
PrimVal
::
U64
(
self
.memory
.read_uint
(
ptr
,
8
)
?
as
u64
),
(
_
,
&
ty
::
TyFloat
(
FloatTy
::
F32
))
=>
{
let
i
=
self
.memory
.read_uint
(
ptr
,
4
)
?
as
u32
;
PrimVal
::
F32
(
unsafe
{
transmute
(
i
)
})
},
(
_
,
&
ty
::
TyFloat
(
FloatTy
::
F64
))
=>
{
let
i
=
self
.memory
.read_uint
(
ptr
,
8
)
?
;
PrimVal
::
F64
(
unsafe
{
transmute
(
i
)
})
},
(
_
,
&
ty
::
TyFnDef
(
def_id
,
substs
,
fn_ty
))
=>
{
PrimVal
::
FnPtr
(
self
.memory
.create_fn_ptr
(
def_id
,
substs
,
fn_ty
))
...
...
src/memory.rs
浏览文件 @
4b831569
...
...
@@ -394,6 +394,7 @@ pub fn write_ptr(&mut self, dest: Pointer, ptr: Pointer) -> EvalResult<'tcx, ()>
}
pub
fn
write_primval
(
&
mut
self
,
ptr
:
Pointer
,
val
:
PrimVal
)
->
EvalResult
<
'tcx
,
()
>
{
use
std
::
mem
::
transmute
;
let
pointer_size
=
self
.pointer_size
();
match
val
{
PrimVal
::
Bool
(
b
)
=>
self
.write_bool
(
ptr
,
b
),
...
...
@@ -407,6 +408,8 @@ pub fn write_primval(&mut self, ptr: Pointer, val: PrimVal) -> EvalResult<'tcx,
PrimVal
::
U64
(
n
)
=>
self
.write_uint
(
ptr
,
n
as
u64
,
8
),
PrimVal
::
Char
(
c
)
=>
self
.write_uint
(
ptr
,
c
as
u64
,
4
),
PrimVal
::
IntegerPtr
(
n
)
=>
self
.write_uint
(
ptr
,
n
as
u64
,
pointer_size
),
PrimVal
::
F32
(
f
)
=>
self
.write_uint
(
ptr
,
unsafe
{
transmute
::
<
_
,
u32
>
(
f
)
}
as
u64
,
4
),
PrimVal
::
F64
(
f
)
=>
self
.write_uint
(
ptr
,
unsafe
{
transmute
::
<
_
,
u64
>
(
f
)
},
8
),
PrimVal
::
FnPtr
(
_
p
)
|
PrimVal
::
AbstractPtr
(
_
p
)
=>
unimplemented!
(),
}
...
...
src/primval.rs
浏览文件 @
4b831569
...
...
@@ -13,6 +13,8 @@ pub enum PrimVal {
FnPtr
(
Pointer
),
IntegerPtr
(
u64
),
Char
(
char
),
F32
(
f32
),
F64
(
f64
),
}
/// returns the result of the operation and whether the operation overflowed
...
...
@@ -57,6 +59,34 @@ pub fn binary_op<'tcx>(bin_op: mir::BinOp, left: PrimVal, right: PrimVal) -> Eva
})
}
macro_rules!
float_binops
{
(
$v:ident
,
$l:ident
,
$r:ident
)
=>
({
match
bin_op
{
Add
=>
$v
(
$l
+
$r
),
Sub
=>
$v
(
$l
-
$r
),
Mul
=>
$v
(
$l
*
$r
),
Div
=>
$v
(
$l
/
$r
),
Rem
=>
$v
(
$l
%
$r
),
// invalid float ops
BitXor
=>
unreachable!
(),
BitAnd
=>
unreachable!
(),
BitOr
=>
unreachable!
(),
Shl
=>
unreachable!
(),
Shr
=>
unreachable!
(),
// directly comparing floats is questionable
// miri could forbid it, or at least miri as rust const eval should forbid it
Eq
=>
Bool
(
$l
==
$r
),
Ne
=>
Bool
(
$l
!=
$r
),
Lt
=>
Bool
(
$l
<
$r
),
Le
=>
Bool
(
$l
<=
$r
),
Gt
=>
Bool
(
$l
>
$r
),
Ge
=>
Bool
(
$l
>=
$r
),
}
})
}
fn
unrelated_ptr_ops
<
'tcx
>
(
bin_op
:
mir
::
BinOp
)
->
EvalResult
<
'tcx
,
PrimVal
>
{
use
rustc
::
mir
::
repr
::
BinOp
::
*
;
match
bin_op
{
...
...
@@ -128,6 +158,8 @@ fn unrelated_ptr_ops<'tcx>(bin_op: mir::BinOp) -> EvalResult<'tcx, PrimVal> {
(
U16
(
l
),
U16
(
r
))
=>
int_binops!
(
U16
,
l
,
r
),
(
U32
(
l
),
U32
(
r
))
=>
int_binops!
(
U32
,
l
,
r
),
(
U64
(
l
),
U64
(
r
))
=>
int_binops!
(
U64
,
l
,
r
),
(
F32
(
l
),
F32
(
r
))
=>
float_binops!
(
F32
,
l
,
r
),
(
F64
(
l
),
F64
(
r
))
=>
float_binops!
(
F64
,
l
,
r
),
(
Char
(
l
),
Char
(
r
))
=>
match
bin_op
{
Eq
=>
Bool
(
l
==
r
),
Ne
=>
Bool
(
l
!=
r
),
...
...
@@ -211,6 +243,9 @@ pub fn unary_op<'tcx>(un_op: mir::UnOp, val: PrimVal) -> EvalResult<'tcx, PrimVa
(
Not
,
U16
(
n
))
=>
Ok
(
U16
(
!
n
)),
(
Not
,
U32
(
n
))
=>
Ok
(
U32
(
!
n
)),
(
Not
,
U64
(
n
))
=>
Ok
(
U64
(
!
n
)),
(
Neg
,
F64
(
n
))
=>
Ok
(
F64
(
-
n
)),
(
Neg
,
F32
(
n
))
=>
Ok
(
F32
(
-
n
)),
_
=>
Err
(
EvalError
::
Unimplemented
(
format!
(
"unimplemented unary op: {:?}, {:?}"
,
un_op
,
val
))),
}
}
tests/run-pass/floats.rs
0 → 100644
浏览文件 @
4b831569
fn
main
()
{
assert_eq!
(
6.0_f32
*
6.0_f32
,
36.0_f32
);
assert_eq!
(
6.0_f64
*
6.0_f64
,
36.0_f64
);
assert_eq!
(
-
{
5.0_f32
},
-
5.0_f32
);
assert
!
((
5.0_f32
/
0.0
)
.is_infinite
());
assert
!
((
-
5.0_f32
)
.sqrt
()
.is_nan
());
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录