@@ -1364,6 +1364,103 @@ ecma_builtin_global_object_escape (ecma_value_t this_arg __attr_unused___, /**<
13641364 return ret_value;
13651365} /* ecma_builtin_global_object_escape */
13661366
1367+ /* *
1368+ * The Global object's 'unescape' routine
1369+ *
1370+ * See also:
1371+ * ECMA-262 v5, B.2.2
1372+ *
1373+ * @return completion value
1374+ * Returned value must be freed with ecma_free_completion_value.
1375+ */
1376+ static ecma_completion_value_t
1377+ ecma_builtin_global_object_unescape (ecma_value_t this_arg __attr_unused___, /* *< this argument */
1378+ ecma_value_t arg) /* *< routine's first argument */
1379+ {
1380+ ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
1381+
1382+ /* 1. */
1383+ ECMA_TRY_CATCH (string, ecma_op_to_string (arg), ret_value);
1384+ ecma_string_t *input_string_p = ecma_get_string_from_value (string);
1385+ /* 2. */
1386+ lit_utf8_size_t input_size = ecma_string_get_size (input_string_p);
1387+
1388+ /* 3. */
1389+ MEM_DEFINE_LOCAL_ARRAY (input_start_p, input_size, lit_utf8_byte_t );
1390+ ssize_t sz = ecma_string_to_utf8_string (input_string_p, input_start_p, (ssize_t ) (input_size));
1391+ JERRY_ASSERT (sz >= 0 );
1392+
1393+ lit_utf8_byte_t *input_curr_p = input_start_p;
1394+ lit_utf8_byte_t *input_end_p = input_start_p + input_size;
1395+ /* 4. */
1396+ /* The length of input string is always greater than output string
1397+ * so we re-use the input string buffer.
1398+ * The %xx is three byte long, and the maximum encoded value is 0xff,
1399+ * which maximum encoded length is two byte. Similar to this, the maximum
1400+ * encoded length of %uxxxx is four byte. */
1401+ lit_utf8_byte_t *output_char_p = input_start_p;
1402+
1403+ /* The state of parsing that tells us where we are in an escape pattern.
1404+ * 0 we are outside of pattern,
1405+ * 1 found '%', start of pattern,
1406+ * 2 found first hex digit of '%xy' pattern
1407+ * 3 found valid '%xy' pattern
1408+ * 4 found 'u', start of '%uwxyz' pattern
1409+ * 5-7 found hex digits of '%uwxyz' pattern
1410+ * 8 found valid '%uwxyz' pattern
1411+ */
1412+ uint8_t status = 0 ;
1413+ ecma_char_t hex_digits = 0 ;
1414+ /* 5. */
1415+ while (input_curr_p < input_end_p)
1416+ {
1417+ /* 6. */
1418+ ecma_char_t chr = lit_utf8_read_next (&input_curr_p);
1419+
1420+ /* 7-8. */
1421+ if (status == 0 && chr == LIT_CHAR_PERCENT)
1422+ {
1423+ /* Found '%' char, start of escape sequence. */
1424+ status = 1 ;
1425+ }
1426+ /* 9-10. */
1427+ else if (status == 1 && chr == LIT_CHAR_LOWERCASE_U)
1428+ {
1429+ /* Found 'u' char after '%'. */
1430+ status = 4 ;
1431+ }
1432+ else if (status > 0 && lit_char_is_hex_digit (chr))
1433+ {
1434+ /* Found hexadecimal digit in escape sequence. */
1435+ hex_digits = (ecma_char_t ) (hex_digits * 16 + (ecma_char_t ) lit_char_hex_to_int (chr));
1436+ status++;
1437+ }
1438+
1439+ /* 11-17. Found valid '%uwxyz' or '%xy' escape. */
1440+ if (status == 8 || status == 3 )
1441+ {
1442+ output_char_p -= (status == 3 ) ? 2 : 5 ;
1443+ status = 0 ;
1444+ chr = hex_digits;
1445+ hex_digits = 0 ;
1446+ }
1447+
1448+ /* Copying character. */
1449+ lit_utf8_size_t lit_size = lit_code_unit_to_utf8 (chr, output_char_p);
1450+ output_char_p += lit_size;
1451+ JERRY_ASSERT (output_char_p <= input_curr_p);
1452+ }
1453+
1454+ lit_utf8_size_t output_length = (lit_utf8_size_t ) (output_char_p - input_start_p);
1455+ ecma_string_t *output_string_p = ecma_new_ecma_string_from_utf8 (input_start_p, output_length);
1456+ ret_value = ecma_make_normal_completion_value (ecma_make_string_value (output_string_p));
1457+
1458+ MEM_FINALIZE_LOCAL_ARRAY (input_start_p);
1459+
1460+ ECMA_FINALIZE (string);
1461+ return ret_value;
1462+ } /* ecma_builtin_global_object_unescape */
1463+
13671464#endif /* CONFIG_ECMA_COMPACT_PROFILE_DISABLE_ANNEXB_BUILTIN */
13681465
13691466/* *
0 commit comments