@@ -280,13 +280,87 @@ static const uint8_t ecma_uint4_clz[] = { 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0,
280280 */
281281#define EPSILON 0.0000001
282282
283+ /**
284+ * ECMA-defined conversion from string to number for different radixes (2, 8, 16).
285+ *
286+ * See also:
287+ * ECMA-262 v5 9.3.1
288+ * ECMA-262 v6 7.1.3.1
289+ *
290+ * @return NaN - if the conversion fails
291+ * converted number - otherwise
292+ */
293+ static ecma_number_t
294+ ecma_utf8_string_to_number_by_radix (const lit_utf8_byte_t * str_p , /**< utf-8 string */
295+ const lit_utf8_byte_t * end_p , /**< end of utf-8 string */
296+ uint32_t radix ) /**< radix */
297+ {
298+ JERRY_ASSERT (radix == 2 || radix == 8 || radix == 16 );
299+ ecma_number_t num = ECMA_NUMBER_ZERO ;
300+
301+ #if ENABLED (JERRY_ES2015 )
302+ if (radix <= 8 )
303+ {
304+ lit_code_point_t upper_limit = LIT_CHAR_0 + radix ;
305+
306+ for (const lit_utf8_byte_t * iter_p = str_p ; iter_p <= end_p ; iter_p ++ )
307+ {
308+ int32_t digit_value ;
309+
310+ if (* iter_p >= LIT_CHAR_0 && * iter_p < upper_limit )
311+ {
312+ digit_value = (* iter_p - LIT_CHAR_0 );
313+ }
314+ else
315+ {
316+ return ecma_number_make_nan ();
317+ }
318+
319+ num = num * radix + (ecma_number_t ) digit_value ;
320+ }
321+
322+ return num ;
323+ }
324+ #endif /* ENABLED (JERRY_ES2015) */
325+
326+ for (const lit_utf8_byte_t * iter_p = str_p ; iter_p <= end_p ; iter_p ++ )
327+ {
328+ int32_t digit_value ;
329+
330+ if (* iter_p >= LIT_CHAR_0
331+ && * iter_p <= LIT_CHAR_9 )
332+ {
333+ digit_value = (* iter_p - LIT_CHAR_0 );
334+ }
335+ else if (* iter_p >= LIT_CHAR_LOWERCASE_A
336+ && * iter_p <= LIT_CHAR_LOWERCASE_F )
337+ {
338+ digit_value = 10 + (* iter_p - LIT_CHAR_LOWERCASE_A );
339+ }
340+ else if (* iter_p >= LIT_CHAR_UPPERCASE_A
341+ && * iter_p <= LIT_CHAR_UPPERCASE_F )
342+ {
343+ digit_value = 10 + (* iter_p - LIT_CHAR_UPPERCASE_A );
344+ }
345+ else
346+ {
347+ return ecma_number_make_nan ();
348+ }
349+
350+ num = num * radix + (ecma_number_t ) digit_value ;
351+ }
352+
353+ return num ;
354+ } /* ecma_utf8_string_to_number_by_radix */
355+
283356/**
284357 * ECMA-defined conversion of string to Number.
285358 *
286359 * See also:
287360 * ECMA-262 v5, 9.3.1
288361 *
289- * @return ecma-number
362+ * @return NaN - if the conversion fails
363+ * converted number - otherwise
290364 */
291365ecma_number_t
292366ecma_utf8_string_to_number (const lit_utf8_byte_t * str_p , /**< utf-8 string */
@@ -307,46 +381,28 @@ ecma_utf8_string_to_number (const lit_utf8_byte_t *str_p, /**< utf-8 string */
307381 return ECMA_NUMBER_ZERO ;
308382 }
309383
310- if ((end_p >= str_p + 2 )
311- && str_p [0 ] == LIT_CHAR_0
312- && (str_p [1 ] == LIT_CHAR_LOWERCASE_X
313- || str_p [1 ] == LIT_CHAR_UPPERCASE_X ))
384+ if (end_p >= str_p + 2
385+ && str_p [0 ] == LIT_CHAR_0 )
314386 {
315- /* Hex literal handling */
316- str_p += 2 ;
317-
318- ecma_number_t num = ECMA_NUMBER_ZERO ;
319-
320- for (const lit_utf8_byte_t * iter_p = str_p ;
321- iter_p <= end_p ;
322- iter_p ++ )
387+ switch (LEXER_TO_ASCII_LOWERCASE (str_p [1 ]))
323388 {
324- int32_t digit_value ;
325-
326- if (* iter_p >= LIT_CHAR_0
327- && * iter_p <= LIT_CHAR_9 )
389+ case LIT_CHAR_LOWERCASE_X :
328390 {
329- digit_value = ( * iter_p - LIT_CHAR_0 );
391+ return ecma_utf8_string_to_number_by_radix ( str_p + 2 , end_p , 16 );
330392 }
331- else if (* iter_p >= LIT_CHAR_LOWERCASE_A
332- && * iter_p <= LIT_CHAR_LOWERCASE_F )
393+ case LIT_CHAR_LOWERCASE_O :
333394 {
334- digit_value = 10 + ( * iter_p - LIT_CHAR_LOWERCASE_A );
395+ return ecma_utf8_string_to_number_by_radix ( str_p + 2 , end_p , 8 );
335396 }
336- else if (* iter_p >= LIT_CHAR_UPPERCASE_A
337- && * iter_p <= LIT_CHAR_UPPERCASE_F )
397+ case LIT_CHAR_LOWERCASE_B :
338398 {
339- digit_value = 10 + ( * iter_p - LIT_CHAR_UPPERCASE_A );
399+ return ecma_utf8_string_to_number_by_radix ( str_p + 2 , end_p , 2 );
340400 }
341- else
401+ default :
342402 {
343- return ecma_number_make_nan () ;
403+ break ;
344404 }
345-
346- num = num * 16 + (ecma_number_t ) digit_value ;
347405 }
348-
349- return num ;
350406 }
351407
352408 bool sign = false; /* positive */
0 commit comments