Optimize ecma_string_get_array_index

JerryScript-DCO-1.0-Signed-off-by: Dániel Bátyai dbatyai@inf.u-szeged.hu
This commit is contained in:
Dániel Bátyai
2016-07-14 12:16:12 +00:00
parent f0fd939d87
commit 3354da3021
2 changed files with 69 additions and 21 deletions
-8
View File
@@ -777,14 +777,6 @@ typedef double ecma_number_t;
*/ */
#define ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32 10 #define ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32 10
/**
* Maximum value of valid array index
*
* See also:
* ECMA-262 v5, 15.4
*/
#define ECMA_MAX_VALUE_OF_VALID_ARRAY_INDEX ((uint32_t) (-1))
/** /**
* Description of a collection's header. * Description of a collection's header.
*/ */
+69 -13
View File
@@ -554,27 +554,83 @@ bool
ecma_string_get_array_index (const ecma_string_t *str_p, /**< ecma-string */ ecma_string_get_array_index (const ecma_string_t *str_p, /**< ecma-string */
uint32_t *out_index_p) /**< [out] index */ uint32_t *out_index_p) /**< [out] index */
{ {
bool is_array_index = true; const ecma_string_container_t type = ECMA_STRING_GET_CONTAINER (str_p);
if (ECMA_STRING_GET_CONTAINER (str_p) == ECMA_STRING_CONTAINER_UINT32_IN_DESC)
if (type == ECMA_STRING_CONTAINER_UINT32_IN_DESC)
{ {
*out_index_p = str_p->u.uint32_number; const uint32_t index = str_p->u.uint32_number;
*out_index_p = index;
return index != UINT32_MAX;
}
else if (type == ECMA_STRING_CONTAINER_MAGIC_STRING)
{
return false;
} }
else else
{ {
ecma_number_t num = ecma_string_to_number (str_p); lit_utf8_size_t size;
*out_index_p = ecma_number_to_uint32 (num); const lit_utf8_byte_t *raw_str_p;
ecma_string_t *to_uint32_to_string_p = ecma_new_ecma_string_from_uint32 (*out_index_p); if (unlikely (type == ECMA_STRING_CONTAINER_MAGIC_STRING_EX))
{
size = lit_get_magic_string_ex_size (str_p->u.magic_string_ex_id);
raw_str_p = lit_get_magic_string_ex_utf8 (str_p->u.magic_string_ex_id);
}
else
{
JERRY_ASSERT (type == ECMA_STRING_CONTAINER_HEAP_UTF8_STRING);
is_array_index = ecma_compare_ecma_strings (str_p, size = str_p->u.utf8_string.size;
to_uint32_to_string_p); raw_str_p = (const lit_utf8_byte_t *) (str_p + 1);
}
ecma_deref_ecma_string (to_uint32_to_string_p); if (*raw_str_p == LIT_CHAR_0)
{
*out_index_p = 0;
return size == 1;
}
if (size > 10)
{
return false;
}
uint32_t index = 0;
const lit_utf8_size_t end = (size == 10) ? 9 : size;
for (lit_utf8_size_t i = 0; i < end; i++)
{
if (raw_str_p[i] > LIT_CHAR_9 || raw_str_p[i] < LIT_CHAR_0)
{
return false;
}
index = (index * 10) + (uint32_t) (raw_str_p[i] - LIT_CHAR_0);
}
if (size == 10)
{
if (index > UINT32_MAX / 10
|| raw_str_p[9] > LIT_CHAR_9
|| raw_str_p[9] < LIT_CHAR_0)
{
return false;
}
index *= 10;
const uint32_t digit = (uint32_t) (raw_str_p[9] - LIT_CHAR_0);
if (index >= UINT32_MAX - digit)
{
return false;
}
index += digit;
}
*out_index_p = index;
return true;
} }
is_array_index = is_array_index && (*out_index_p != ECMA_MAX_VALUE_OF_VALID_ARRAY_INDEX);
return is_array_index;
} /* ecma_string_get_array_index */ } /* ecma_string_get_array_index */
/** /**