diff --git a/Makefile.mk b/Makefile.mk index 5c0fff82e..c59ea9983 100644 --- a/Makefile.mk +++ b/Makefile.mk @@ -245,7 +245,8 @@ BUILD_DATE=$(shell date +'%d/%m/%Y') CFLAGS_JERRY = $(CFLAGS_WARNINGS) $(CFLAGS_WERROR) $(CFLAGS_WFATAL_ERRORS) DEFINES_JERRY = -DMEM_HEAP_CHUNK_SIZE=$$((64)) -DMEM_HEAP_AREA_SIZE=$$((2 * 1024 + 512)) -DMEM_STATS \ -DCONFIG_ECMA_REFERENCE_COUNTER_WIDTH=$$((10)) \ - -DCONFIG_MEM_STACK_LIMIT=$$((4 * 1024)) -DCONFIG_MEM_DATA_LIMIT_MINUS_HEAP_SIZE=$$((1024)) + -DCONFIG_MEM_STACK_LIMIT=$$((4 * 1024)) -DCONFIG_MEM_DATA_LIMIT_MINUS_HEAP_SIZE=$$((1024)) \ + -DCONFIG_ECMA_NUMBER_FLOAT32 DEFINES_JERRY += -DJERRY_BUILD_DATE="\"$(BUILD_DATE)\"" \ -DJERRY_COMMIT_HASH="\"$(GIT_HASH)\"" \ diff --git a/src/libecmaobjects/ecma-helpers-number.c b/src/libecmaobjects/ecma-helpers-number.c new file mode 100644 index 000000000..2eb9400b7 --- /dev/null +++ b/src/libecmaobjects/ecma-helpers-number.c @@ -0,0 +1,307 @@ +/* Copyright 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** \addtogroup ecma ---TODO--- + * @{ + * + * \addtogroup ecmahelpers Helpers for operations with ECMA data types + * @{ + */ + +#include "ecma-globals.h" +#include "ecma-helpers.h" + +#ifdef CONFIG_ECMA_NUMBER_FLOAT32 +JERRY_STATIC_ASSERT (sizeof (ecma_number_t) == sizeof (uint32_t)); + +/** + * Width of sign field + * + * See also: + * IEEE-754 2008, 3.6, Table 3.5 + */ +#define ECMA_NUMBER_SIGN_WIDTH (1) + +/** + * Width of biased exponent field + * + * See also: + * IEEE-754 2008, 3.6, Table 3.5 + */ +#define ECMA_NUMBER_BIASED_EXP_WIDTH (8) + +/** + * Width of fraction field + * + * See also: + * IEEE-754 2008, 3.6, Table 3.5 + */ +#define ECMA_NUMBER_FRACTION_WIDTH (23) + +/** + * Field of ecma-number + * + * See also: + * IEEE-754 2008, 3.4 + */ +typedef struct +{ + /** sign bit */ + unsigned int sign : ECMA_NUMBER_SIGN_WIDTH; + + /** biased exponent field */ + unsigned int biased_exp : ECMA_NUMBER_BIASED_EXP_WIDTH; + + /** fraction field */ + unsigned int fraction : ECMA_NUMBER_FRACTION_WIDTH; +} ecma_number_fields_t; + +/** + * Value used to calculate exponent from biased exponent + * + * See also: + * IEEE-754 2008, 3.6, Table 3.5 + */ +const int32_t ecma_number_exponent_bias = 127; +#elif defined (CONFIG_ECMA_NUMBER_FLOAT64) +JERRY_STATIC_ASSERT (sizeof (ecma_number_t) == sizeof (uint64_t)); + +/** + * Width of sign field + * + * See also: + * IEEE-754 2008, 3.6, Table 3.5 + */ +#define ECMA_NUMBER_SIGN_WIDTH (1) + +/** + * Width of biased exponent field + * + * See also: + * IEEE-754 2008, 3.6, Table 3.5 + */ +#define ECMA_NUMBER_BIASED_EXP_WIDTH (11) + +/** + * Width of fraction field + * + * See also: + * IEEE-754 2008, 3.6, Table 3.5 + */ +#define ECMA_NUMBER_FRACTION_WIDTH (52) + +/** + * Field of ecma-number + * + * See also: + * IEEE-754 2008, 3.4 + */ +typedef struct +{ + /** sign bit */ + unsigned long int sign : ECMA_NUMBER_SIGN_WIDTH; + + /** biased exponent field */ + unsigned long int biased_exp : ECMA_NUMBER_BIASED_EXP_WIDTH; + + /** fraction field */ + unsigned long int fraction : ECMA_NUMBER_FRACTION_WIDTH; +} ecma_number_fields_t; + +/** + * Value used to calculate exponent from biased exponent + * + * See also: + * IEEE-754 2008, 3.6, Table 3.5 + */ +const int32_t ecma_number_exponent_bias = 1023; +#else /* !CONFIG_ECMA_NUMBER_FLOAT32 && !CONFIG_ECMA_NUMBER_FLOAT64 */ +# error "!CONFIG_ECMA_NUMBER_FLOAT32 && !CONFIG_ECMA_NUMBER_FLOAT64" +#endif /* !CONFIG_ECMA_NUMBER_FLOAT32 && !CONFIG_ECMA_NUMBER_FLOAT64 */ + +/** + * Get fraction of number + * + * @return normalized fraction field of number + */ +static uint64_t +ecma_number_get_fraction_field (ecma_number_t num) /**< ecma-number */ +{ + union + { + ecma_number_fields_t fields; + ecma_number_t value; + } u; + + u.value = num; + + return u.fields.fraction; +} /* ecma_number_get_fraction_field */ + +/** + * Get exponent of number + * + * @return exponent corresponding to normalized fraction of number + */ +static uint32_t +ecma_number_get_biased_exponent_field (ecma_number_t num) /**< ecma-number */ +{ + union + { + ecma_number_fields_t fields; + ecma_number_t value; + } u; + + u.value = num; + + return u.fields.biased_exp; +} /* ecma_number_get_biased_exponent_field */ + +/** + * Get sign bit of number + * + * @return 0 or 1 - value of sign bit + */ +static uint32_t +ecma_number_get_sign_field (ecma_number_t num) /**< ecma-number */ +{ + union + { + ecma_number_fields_t fields; + ecma_number_t value; + } u; + + u.value = num; + + return u.fields.sign; +} /* ecma_number_get_sign_field */ + +/** + * Check if ecma-number is NaN + * + * @return true - if biased exponent is filled with 1 bits and + fraction is filled with anything but not all zero bits, + * false - otherwise + */ +bool +ecma_number_is_nan (ecma_number_t num) /**< ecma-number */ +{ + uint32_t biased_exp = ecma_number_get_biased_exponent_field (num); + uint64_t fraction = ecma_number_get_fraction_field (num); + + /* IEEE-754 2008, 3.4, a */ + + return ((biased_exp == (1u << ECMA_NUMBER_BIASED_EXP_WIDTH) - 1) + && (fraction != 0)); +} /* ecma_number_is_nan */ + +/** + * Check if ecma-number is negative + * + * @return true - if sign bit of ecma-number is set + * false - otherwise + */ +bool +ecma_number_is_negative (ecma_number_t num) /**< ecma-number */ +{ + JERRY_ASSERT (!ecma_number_is_nan (num)); + + /* IEEE-754 2008, 3.4 */ + + return (ecma_number_get_sign_field (num) != 0); +} /* ecma_number_is_negative */ + +/** + * Check if ecma-number is zero + * + * @return true - if fraction is zero and biased exponent is zero, + * false - otherwise + */ +bool +ecma_number_is_zero (ecma_number_t num) /**< ecma-number */ +{ + JERRY_ASSERT (!ecma_number_is_nan (num)); + + /* IEEE-754 2008, 3.4, e */ + + return (ecma_number_get_fraction_field (num) == 0 + && ecma_number_get_biased_exponent_field (num) == 0); +} /* ecma_number_is_zero */ + +/** + * Check if number is infinity + * + * @return true - if biased exponent is filled with 1 bits and + * fraction is filled with zero bits, + * false - otherwise. + */ +bool +ecma_number_is_infinity (ecma_number_t num) /**< ecma-number */ +{ + JERRY_ASSERT (!ecma_number_is_nan (num)); + + uint32_t biased_exp = ecma_number_get_biased_exponent_field (num); + uint64_t fraction = ecma_number_get_fraction_field (num); + + /* IEEE-754 2008, 3.4, b */ + + return ((biased_exp == (1u << ECMA_NUMBER_BIASED_EXP_WIDTH) - 1) + && (fraction == 0)); +} /* ecma_number_is_infinity */ + +/** + * Get fraction and exponent of the number + * + * @return normalized fraction field of the number + */ +uint64_t +ecma_number_get_fraction_and_exponent (ecma_number_t num, /**< ecma-number */ + int32_t *out_exponent_p) /**< out: exponent of the number */ +{ + JERRY_ASSERT (!ecma_number_is_nan (num)); + JERRY_ASSERT (!ecma_number_is_zero (num)); + JERRY_ASSERT (!ecma_number_is_infinity (num)); + + uint32_t biased_exp = ecma_number_get_biased_exponent_field (num); + uint64_t fraction = ecma_number_get_fraction_field (num); + int32_t exponent = (int32_t) biased_exp - ecma_number_exponent_bias; + + if (unlikely (biased_exp == 0)) + { + /* IEEE-754 2008, 3.4, d */ + + while (!(fraction & (1u << (ECMA_NUMBER_FRACTION_WIDTH - 1)))) + { + JERRY_ASSERT (fraction != 0); + + fraction <<= 1; + exponent--; + } + } + else + { + /* IEEE-754 2008, 3.4, c */ + + JERRY_ASSERT (biased_exp > 0 && biased_exp < (1u << ECMA_NUMBER_BIASED_EXP_WIDTH) - 1); + } + + *out_exponent_p = exponent; + return fraction; +} /* ecma_number_get_fraction_and_exponent */ + +/** + * @} + * @} + */ diff --git a/src/libecmaobjects/ecma-helpers.h b/src/libecmaobjects/ecma-helpers.h index 6406f076e..507eb2504 100644 --- a/src/libecmaobjects/ecma-helpers.h +++ b/src/libecmaobjects/ecma-helpers.h @@ -100,6 +100,13 @@ extern int32_t ecma_compare_zt_string_to_zt_string (const ecma_char_t *string1_p extern bool ecma_compare_ecma_string_to_ecma_string (const ecma_string_t *string1_p, const ecma_string_t *string2_p); +/* ecma-helpers-number.c */ +extern bool ecma_number_is_nan (ecma_number_t num); +extern bool ecma_number_is_negative (ecma_number_t num); +extern bool ecma_number_is_zero (ecma_number_t num); +extern bool ecma_number_is_infinity (ecma_number_t num); +extern uint64_t ecma_number_get_fraction_and_exponent (ecma_number_t num, int32_t *out_exponent_p); + /* ecma-helpers-values-collection.c */ extern ecma_collection_header_t *ecma_new_values_collection (ecma_value_t values_buffer[],