Ecma-number decoding helpers

This commit is contained in:
Ruben Ayrapetyan 2014-08-20 19:20:03 +04:00
parent 284e7fc91b
commit 5095bd31c9
3 changed files with 316 additions and 1 deletions

View File

@ -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)\"" \

View File

@ -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 */
/**
* @}
* @}
*/

View File

@ -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[],