Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
uPython-mirror
Commits
8270e385
Commit
8270e385
authored
Apr 03, 2014
by
Damien George
Browse files
py: More robust int conversion and overflow checking.
parent
a58a7aef
Changes
6
Hide whitespace changes
Inline
Side-by-side
py/mpz.c
View file @
8270e385
...
...
@@ -1139,6 +1139,7 @@ mpz_t *mpz_mod(const mpz_t *lhs, const mpz_t *rhs) {
}
#endif
// TODO check that this correctly handles overflow in all cases
machine_int_t
mpz_as_int
(
const
mpz_t
*
i
)
{
machine_int_t
val
=
0
;
mpz_dig_t
*
d
=
i
->
dig
+
i
->
len
;
...
...
@@ -1147,11 +1148,13 @@ machine_int_t mpz_as_int(const mpz_t *i) {
machine_int_t
oldval
=
val
;
val
=
(
val
<<
DIG_SIZE
)
|
*
d
;
if
(
val
<
oldval
)
{
//
TODO need better handling of conversion overflow
//
overflow, return +/- "infinity"
if
(
i
->
neg
==
0
)
{
return
0x7fffffff
;
// +infinity
return
~
WORD_MSBIT_HIGH
;
}
else
{
return
0x80000000
;
// -infinity
return
WORD_MSBIT_HIGH
;
}
}
}
...
...
@@ -1163,6 +1166,28 @@ machine_int_t mpz_as_int(const mpz_t *i) {
return
val
;
}
// TODO check that this correctly handles overflow in all cases
bool
mpz_as_int_checked
(
const
mpz_t
*
i
,
machine_int_t
*
value
)
{
machine_int_t
val
=
0
;
mpz_dig_t
*
d
=
i
->
dig
+
i
->
len
;
while
(
--
d
>=
i
->
dig
)
{
machine_int_t
oldval
=
val
;
val
=
(
val
<<
DIG_SIZE
)
|
*
d
;
if
(
val
<
oldval
)
{
// overflow
return
false
;
}
}
if
(
i
->
neg
!=
0
)
{
val
=
-
val
;
}
*
value
=
val
;
return
true
;
}
#if MICROPY_ENABLE_FLOAT
mp_float_t
mpz_as_float
(
const
mpz_t
*
i
)
{
mp_float_t
val
=
0
;
...
...
py/mpz.h
View file @
8270e385
...
...
@@ -71,6 +71,7 @@ mpz_t *mpz_div(const mpz_t *lhs, const mpz_t *rhs);
mpz_t
*
mpz_mod
(
const
mpz_t
*
lhs
,
const
mpz_t
*
rhs
);
machine_int_t
mpz_as_int
(
const
mpz_t
*
z
);
bool
mpz_as_int_checked
(
const
mpz_t
*
z
,
machine_int_t
*
value
);
#if MICROPY_ENABLE_FLOAT
mp_float_t
mpz_as_float
(
const
mpz_t
*
z
);
#endif
...
...
py/obj.c
View file @
8270e385
...
...
@@ -203,6 +203,24 @@ machine_int_t mp_obj_get_int(mp_obj_t arg) {
}
}
// returns false if arg is not of integral type
// returns true and sets *value if it is of integral type
// can throw OverflowError if arg is of integral type, but doesn't fit in a machine_int_t
bool
mp_obj_get_int_maybe
(
mp_obj_t
arg
,
machine_int_t
*
value
)
{
if
(
arg
==
mp_const_false
)
{
*
value
=
0
;
}
else
if
(
arg
==
mp_const_true
)
{
*
value
=
1
;
}
else
if
(
MP_OBJ_IS_SMALL_INT
(
arg
))
{
*
value
=
MP_OBJ_SMALL_INT_VALUE
(
arg
);
}
else
if
(
MP_OBJ_IS_TYPE
(
arg
,
&
mp_type_int
))
{
*
value
=
mp_obj_int_get_checked
(
arg
);
}
else
{
return
false
;
}
return
true
;
}
#if MICROPY_ENABLE_FLOAT
mp_float_t
mp_obj_get_float
(
mp_obj_t
arg
)
{
if
(
arg
==
mp_const_false
)
{
...
...
py/obj.h
View file @
8270e385
...
...
@@ -359,6 +359,7 @@ bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2);
bool
mp_obj_less
(
mp_obj_t
o1
,
mp_obj_t
o2
);
machine_int_t
mp_obj_get_int
(
mp_obj_t
arg
);
bool
mp_obj_get_int_maybe
(
mp_obj_t
arg
,
machine_int_t
*
value
);
#if MICROPY_ENABLE_FLOAT
mp_float_t
mp_obj_get_float
(
mp_obj_t
self_in
);
void
mp_obj_get_complex
(
mp_obj_t
self_in
,
mp_float_t
*
real
,
mp_float_t
*
imag
);
...
...
py/objint_mpz.c
View file @
8270e385
...
...
@@ -243,8 +243,18 @@ machine_int_t mp_obj_int_get(mp_obj_t self_in) {
}
machine_int_t
mp_obj_int_get_checked
(
mp_obj_t
self_in
)
{
// TODO: Check overflow
return
mp_obj_int_get
(
self_in
);
if
(
MP_OBJ_IS_SMALL_INT
(
self_in
))
{
return
MP_OBJ_SMALL_INT_VALUE
(
self_in
);
}
else
{
mp_obj_int_t
*
self
=
self_in
;
machine_int_t
value
;
if
(
mpz_as_int_checked
(
&
self
->
mpz
,
&
value
))
{
return
value
;
}
else
{
// overflow
nlr_jump
(
mp_obj_new_exception_msg
(
&
mp_type_OverflowError
,
"overflow converting long int to machine word"
));
}
}
}
#if MICROPY_ENABLE_FLOAT
...
...
py/objlist.c
View file @
8270e385
...
...
@@ -122,12 +122,11 @@ STATIC mp_obj_t list_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
list_extend
(
lhs
,
rhs
);
return
o
;
}
case
MP_BINARY_OP_MULTIPLY
:
{
if
(
!
MP_OBJ_IS_SMALL_INT
(
rhs
))
{
case
MP_BINARY_OP_MULTIPLY
:
{
machine_int_t
n
;
if
(
!
mp_obj_get_int_maybe
(
rhs
,
&
n
))
{
return
NULL
;
}
int
n
=
MP_OBJ_SMALL_INT_VALUE
(
rhs
);
mp_obj_list_t
*
s
=
list_new
(
o
->
len
*
n
);
mp_seq_multiply
(
o
->
items
,
sizeof
(
*
o
->
items
),
o
->
len
,
n
,
s
->
items
);
return
s
;
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment