@@ -1325,6 +1325,131 @@ ecma_builtin_global_object_escape (ecma_value_t this_arg __attr_unused___, /**<
13251325 return ret_value;
13261326} /* ecma_builtin_global_object_escape */
13271327
1328+ /* *
1329+ * The Global object's 'unescape' routine
1330+ *
1331+ * See also:
1332+ * ECMA-262 v5, B.2.2
1333+ *
1334+ * @return completion value
1335+ * Returned value must be freed with ecma_free_completion_value.
1336+ */
1337+ static ecma_completion_value_t
1338+ ecma_builtin_global_object_unescape (ecma_value_t this_arg __attr_unused___, /* *< this argument */
1339+ ecma_value_t arg) /* *< routine's first argument */
1340+ {
1341+ ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
1342+
1343+ /* 1. */
1344+ ECMA_TRY_CATCH (string, ecma_op_to_string (arg), ret_value);
1345+ ecma_string_t *input_string_p = ecma_get_string_from_value (string);
1346+ /* 2. */
1347+ lit_utf8_size_t input_size = ecma_string_get_size (input_string_p);
1348+
1349+ /* 3. */
1350+ MEM_DEFINE_LOCAL_ARRAY (input_start_p, input_size, lit_utf8_byte_t );
1351+ ssize_t sz = ecma_string_to_utf8_string (input_string_p, input_start_p, (ssize_t ) (input_size));
1352+ JERRY_ASSERT (sz >= 0 );
1353+
1354+ lit_utf8_iterator_t iterator = lit_utf8_iterator_create (input_start_p, input_size);
1355+ /* 4. */
1356+ lit_utf8_size_t output_length = 0 ;
1357+ /* The length of input string is always greater than output string
1358+ * so we re-use the input string buffer. */
1359+ lit_utf8_byte_t *output_char_p = input_start_p;
1360+
1361+ /* The state of parsing that tells us where we are in an escape pattern.
1362+ * 0 we are outside of pattern,
1363+ * 1 found '%', start of pattern,
1364+ * 2 found first hex digit of '%xy' pattern
1365+ * 3 found valid '%xy' pattern
1366+ * 4 found 'u', start of '%uwxyz' pattern
1367+ * 5-7 found hex digits of '%uwxyz' pattern
1368+ * 8 found valid '%uwxyz' pattern
1369+ */
1370+ uint8_t status = 0 ;
1371+ lit_code_point_t code_point = 0 ;
1372+ lit_code_point_t hex_digits = 0 ;
1373+ /* 5. */
1374+ while (!lit_utf8_iterator_is_eos (&iterator))
1375+ {
1376+ /* 6. */
1377+ ecma_char_t ch = lit_utf8_iterator_read_next (&iterator);
1378+
1379+ /* 7-8. */
1380+ if (status == 0 && ch == LIT_CHAR_PERCENT)
1381+ {
1382+ /* Found '%' char, start of escape sequence. */
1383+ status = 1 ;
1384+ }
1385+ /* 9-10. */
1386+ else if (status == 1 && ch == LIT_CHAR_LOWERCASE_U)
1387+ {
1388+ /* Found 'u' char after '%'. */
1389+ status = 4 ;
1390+ }
1391+ else if (status > 0 && lit_char_is_hex_digit (ch))
1392+ {
1393+ /* Found hexadecimal digit in escape sequence. */
1394+ hex_digits = hex_digits * 16 + lit_char_hex_to_int (ch);
1395+ status++;
1396+ }
1397+
1398+ /* 11-13. */
1399+ if (status == 8 )
1400+ {
1401+ /* Found valid '%uwxyz' escape, decode. */
1402+ output_char_p -= 5 ;
1403+ output_length -= 5 ;
1404+ status = 0 ;
1405+ code_point = hex_digits;
1406+ hex_digits = 0 ;
1407+ }
1408+ /* 14-17. */
1409+ else if (status == 3 )
1410+ {
1411+ /* Found valid '%xy' escape, decode. */
1412+ output_char_p -= 2 ;
1413+ output_length -= 2 ;
1414+ status = 0 ;
1415+ code_point = hex_digits;
1416+ hex_digits = 0 ;
1417+ }
1418+ /* 18. */
1419+ else
1420+ {
1421+ /* Copying unescaped character. */
1422+ code_point = ch;
1423+
1424+ /* Handle surrogate pairs. */
1425+ if (lit_is_code_unit_high_surrogate (ch) && !lit_utf8_iterator_is_eos (&iterator))
1426+ {
1427+ ecma_char_t next_ch = lit_utf8_iterator_peek_next (&iterator);
1428+
1429+ if (lit_is_code_unit_low_surrogate (next_ch))
1430+ {
1431+ code_point = lit_convert_surrogate_pair_to_code_point (ch, next_ch);
1432+ lit_utf8_iterator_incr (&iterator);
1433+ }
1434+ }
1435+ }
1436+
1437+ lit_utf8_size_t lit_size = lit_code_point_to_utf8 (code_point, output_char_p);
1438+ output_char_p += lit_size;
1439+ output_length += lit_size;
1440+
1441+ JERRY_ASSERT (output_length <= iterator.buf_pos .offset );
1442+ }
1443+
1444+ ecma_string_t *output_string_p = ecma_new_ecma_string_from_utf8 (input_start_p, output_length);
1445+ ret_value = ecma_make_normal_completion_value (ecma_make_string_value (output_string_p));
1446+
1447+ MEM_FINALIZE_LOCAL_ARRAY (input_start_p);
1448+
1449+ ECMA_FINALIZE (string);
1450+ return ret_value;
1451+ } /* ecma_builtin_global_object_unescape */
1452+
13281453#endif /* CONFIG_ECMA_COMPACT_PROFILE_DISABLE_ANNEXB_BUILTIN */
13291454
13301455/* *
0 commit comments