@@ -823,24 +823,60 @@ ecma_int32_to_number (int32_t value) /**< signed 32-bit integer value */
823
823
} /* ecma_int32_to_number */
824
824
825
825
/* *
826
- * ECMA-defined conversion of Number value to Uint32 value
826
+ * ECMA-defined conversion of Number value to UInt32 value
827
827
*
828
828
* See also:
829
829
* ECMA-262 v5, 9.6
830
830
*
831
- * @return number - result of conversion.
831
+ * @return 32-bit unsigned integer - result of conversion.
832
832
*/
833
833
uint32_t
834
- ecma_number_to_uint32 (ecma_number_t value ) /* *< unsigned 32-bit integer value */
834
+ ecma_number_to_uint32 (ecma_number_t num ) /* *< ecma-number */
835
835
{
836
- if (ecma_number_is_nan (value )
837
- || ecma_number_is_zero (value )
838
- || ecma_number_is_infinity (value ))
836
+ if (ecma_number_is_nan (num )
837
+ || ecma_number_is_zero (num )
838
+ || ecma_number_is_infinity (num ))
839
839
{
840
840
return 0 ;
841
841
}
842
842
843
- return (uint32_t ) value;
843
+ bool sign = ecma_number_is_negative (num);
844
+ ecma_number_t abs_num;
845
+
846
+ if (sign)
847
+ {
848
+ abs_num = ecma_number_negate (num);
849
+ }
850
+ else
851
+ {
852
+ abs_num = num;
853
+ }
854
+
855
+ // 2 ^ 32
856
+ const uint64_t uint64_2_pow_32 = (1ull << 32 );
857
+
858
+ const ecma_number_t num_2_pow_32 = (float ) uint64_2_pow_32;
859
+
860
+ ecma_number_t num_in_uint32_range = ecma_number_calc_remainder (abs_num,
861
+ num_2_pow_32);
862
+
863
+ uint64_t uint64_num = (uint64_t ) num_in_uint32_range;
864
+
865
+ uint64_t ret;
866
+
867
+ if (sign)
868
+ {
869
+ ret = uint64_2_pow_32 - uint64_num;
870
+ }
871
+ else
872
+ {
873
+ ret = uint64_num;
874
+ }
875
+
876
+ // Check that the value can be represented with uint32_t
877
+ JERRY_ASSERT (ret < (1ull << 32 ));
878
+
879
+ return (uint32_t ) ret;
844
880
} /* ecma_number_to_uint32 */
845
881
846
882
/* *
@@ -849,19 +885,36 @@ ecma_number_to_uint32 (ecma_number_t value) /**< unsigned 32-bit integer value *
849
885
* See also:
850
886
* ECMA-262 v5, 9.5
851
887
*
852
- * @return number - result of conversion.
888
+ * @return 32-bit signed integer - result of conversion.
853
889
*/
854
890
int32_t
855
- ecma_number_to_int32 (ecma_number_t value ) /* *< unsigned 32-bit integer value */
891
+ ecma_number_to_int32 (ecma_number_t num ) /* *< ecma-number */
856
892
{
857
- if (ecma_number_is_nan (value)
858
- || ecma_number_is_zero (value)
859
- || ecma_number_is_infinity (value))
893
+ int64_t int64_num = ecma_number_to_uint32 (num);
894
+
895
+ // 2 ^ 32
896
+ const int64_t int64_2_pow_32 = (1ll << 32 );
897
+
898
+ // 2 ^ 31
899
+ const int64_t int64_2_pow_31 = (1ll << 31 );
900
+
901
+ JERRY_ASSERT (int64_num >= 0 );
902
+
903
+ int64_t ret;
904
+
905
+ if (int64_num >= int64_2_pow_31)
860
906
{
861
- return 0 ;
907
+ ret = (int64_num - int64_2_pow_32) ;
862
908
}
909
+ else
910
+ {
911
+ ret = int64_num;
912
+ }
913
+
914
+ // Check that the value can be represented with int32_t
915
+ JERRY_ASSERT (ret >= -int64_2_pow_31 && ret < int64_2_pow_31);
863
916
864
- return (int32_t ) ( uint32_t ) value ;
917
+ return (int32_t ) ret ;
865
918
} /* ecma_number_to_int32 */
866
919
867
920
#if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64
0 commit comments