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