diff --git a/jerry-core/ecma/base/ecma-helpers-number.c b/jerry-core/ecma/base/ecma-helpers-number.c
index 010bb8d00..9c9cc114a 100644
--- a/jerry-core/ecma/base/ecma-helpers-number.c
+++ b/jerry-core/ecma/base/ecma-helpers-number.c
@@ -729,13 +729,11 @@ ecma_number_parse_int (const lit_utf8_byte_t *string_buff, /**< routine's first
return ecma_make_nan_value ();
}
- const lit_utf8_byte_t *string_curr_p = string_buff;
+ /* 2. Remove leading whitespace. */
- /* 2. Remove leading whitespace. */
- ecma_string_trim_helper (&string_curr_p, &string_buff_size);
-
- const lit_utf8_byte_t *string_end_p = string_curr_p + string_buff_size;
- const lit_utf8_byte_t *start_p = string_curr_p;
+ const lit_utf8_byte_t *string_end_p = string_buff + string_buff_size;
+ const lit_utf8_byte_t *start_p = ecma_string_trim_front (string_buff, string_end_p);
+ const lit_utf8_byte_t *string_curr_p = start_p;
const lit_utf8_byte_t *end_p = string_end_p;
if (string_curr_p >= string_end_p)
@@ -906,13 +904,11 @@ ecma_number_parse_float (const lit_utf8_byte_t *string_buff, /**< routine's firs
return ecma_make_nan_value ();
}
- const lit_utf8_byte_t *str_curr_p = string_buff;
-
/* 2. Remove leading whitespace. */
- ecma_string_trim_helper (&str_curr_p, &string_buff_size);
- const lit_utf8_byte_t *str_end_p = str_curr_p + string_buff_size;
- const lit_utf8_byte_t *start_p = str_curr_p;
+ const lit_utf8_byte_t *str_end_p = string_buff + string_buff_size;
+ const lit_utf8_byte_t *start_p = ecma_string_trim_front (string_buff, str_end_p);
+ const lit_utf8_byte_t *str_curr_p = start_p;
const lit_utf8_byte_t *end_p = str_end_p;
bool sign = false;
diff --git a/jerry-core/ecma/base/ecma-helpers-string.c b/jerry-core/ecma/base/ecma-helpers-string.c
index 7f82c2d9c..9a69a42d1 100644
--- a/jerry-core/ecma/base/ecma-helpers-string.c
+++ b/jerry-core/ecma/base/ecma-helpers-string.c
@@ -2426,49 +2426,81 @@ ecma_string_substr (const ecma_string_t *string_p, /**< pointer to an ecma strin
* Helper function for trimming.
*
* Used by:
- * - ecma_string_trim
- * - ecma_utf8_string_to_number
+ * - ecma_string_trim_helper
* - ecma_builtin_global_object_parse_int
* - ecma_builtin_global_object_parse_float
+ *
+ * @return position of the first non whitespace character.
*/
-void
-ecma_string_trim_helper (const lit_utf8_byte_t **utf8_str_p, /**< [in, out] current string position */
- lit_utf8_size_t *utf8_str_size) /**< [in, out] size of the given string */
+const lit_utf8_byte_t *
+ecma_string_trim_front (const lit_utf8_byte_t *start_p, /**< current string's start position */
+ const lit_utf8_byte_t *end_p) /**< current string's end position */
{
ecma_char_t ch;
- lit_utf8_size_t read_size;
- const lit_utf8_byte_t *nonws_start_p = *utf8_str_p + *utf8_str_size;
- const lit_utf8_byte_t *current_p = *utf8_str_p;
- while (current_p < nonws_start_p)
+ while (start_p < end_p)
{
- read_size = lit_read_code_unit_from_utf8 (current_p, &ch);
-
- if (!lit_char_is_white_space (ch))
- {
- nonws_start_p = current_p;
- break;
- }
-
- current_p += read_size;
- }
-
- current_p = *utf8_str_p + *utf8_str_size;
-
- while (current_p > nonws_start_p)
- {
- read_size = lit_read_prev_code_unit_from_utf8 (current_p, &ch);
+ lit_utf8_size_t read_size = lit_read_code_unit_from_utf8 (start_p, &ch);
if (!lit_char_is_white_space (ch))
{
break;
}
- current_p -= read_size;
+ start_p += read_size;
}
- *utf8_str_p = nonws_start_p;
- *utf8_str_size = (lit_utf8_size_t) (current_p - nonws_start_p);
+ return start_p;
+} /* ecma_string_trim_front */
+
+/**
+ * Helper function for trimming.
+ *
+ * Used by:
+ * - ecma_string_trim_helper
+ *
+ * @return position of the last non whitespace character.
+ */
+const lit_utf8_byte_t *
+ecma_string_trim_back (const lit_utf8_byte_t *start_p, /**< current string's start position */
+ const lit_utf8_byte_t *end_p) /**< current string's end position */
+{
+ ecma_char_t ch;
+
+ while (end_p > start_p)
+ {
+ lit_utf8_size_t read_size = lit_read_prev_code_unit_from_utf8 (end_p, &ch);
+
+ if (!lit_char_is_white_space (ch))
+ {
+ break;
+ }
+
+ end_p -= read_size;
+ }
+
+ return end_p;
+} /* ecma_string_trim_back */
+
+/**
+ * Helper function for trimming.
+ *
+ * Used by:
+ * - ecma_string_trim
+ * - ecma_utf8_string_to_number
+ */
+inline void JERRY_ATTR_ALWAYS_INLINE
+ecma_string_trim_helper (const lit_utf8_byte_t **utf8_str_p, /**< [in, out] current string position */
+ lit_utf8_size_t *utf8_str_size) /**< [in, out] size of the given string */
+{
+ const lit_utf8_byte_t *end_p = *utf8_str_p + *utf8_str_size;
+ const lit_utf8_byte_t *start_p = *utf8_str_p;
+
+ const lit_utf8_byte_t *new_start_p = ecma_string_trim_front (start_p, end_p);
+ const lit_utf8_byte_t *new_end_p = ecma_string_trim_back (new_start_p, end_p);
+
+ *utf8_str_size = (lit_utf8_size_t) (new_end_p - new_start_p);
+ *utf8_str_p = new_start_p;
} /* ecma_string_trim_helper */
/**
diff --git a/jerry-core/ecma/base/ecma-helpers.h b/jerry-core/ecma/base/ecma-helpers.h
index 55e08807b..cdb350e42 100644
--- a/jerry-core/ecma/base/ecma-helpers.h
+++ b/jerry-core/ecma/base/ecma-helpers.h
@@ -397,6 +397,8 @@ lit_magic_string_id_t ecma_get_string_magic (const ecma_string_t *string_p);
lit_string_hash_t ecma_string_hash (const ecma_string_t *string_p);
ecma_string_t *ecma_string_substr (const ecma_string_t *string_p, lit_utf8_size_t start_pos, lit_utf8_size_t end_pos);
+const lit_utf8_byte_t *ecma_string_trim_front (const lit_utf8_byte_t *start_p, const lit_utf8_byte_t *end_p);
+const lit_utf8_byte_t *ecma_string_trim_back (const lit_utf8_byte_t *start_p, const lit_utf8_byte_t *end_p);
void ecma_string_trim_helper (const lit_utf8_byte_t **utf8_str_p,
lit_utf8_size_t *utf8_str_size);
ecma_string_t *ecma_string_trim (const ecma_string_t *string_p);
diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-intrinsic.c b/jerry-core/ecma/builtin-objects/ecma-builtin-intrinsic.c
index c87f2259b..a2474b57e 100644
--- a/jerry-core/ecma/builtin-objects/ecma-builtin-intrinsic.c
+++ b/jerry-core/ecma/builtin-objects/ecma-builtin-intrinsic.c
@@ -18,7 +18,9 @@
#include "ecma-container-object.h"
#include "ecma-array-object.h"
#include "ecma-typedarray-object.h"
+#include "ecma-string-object.h"
#include "ecma-gc.h"
+#include "ecma-helpers.h"
#include "lit-char-helpers.h"
#if ENABLED (JERRY_ESNEXT)
@@ -44,7 +46,9 @@ enum
ECMA_INTRINSIC_ARRAY_TO_STRING,
ECMA_INTRINSIC_DATE_TO_UTC_STRING,
ECMA_INTRINSIC_PARSE_FLOAT,
- ECMA_INTRINSIC_PARSE_INT
+ ECMA_INTRINSIC_PARSE_INT,
+ ECMA_INTRINSIC_STRING_TRIM_START,
+ ECMA_INTRINSIC_STRING_TRIM_END,
};
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-intrinsic.inc.h"
@@ -206,6 +210,48 @@ ecma_builtin_intrinsic_dispatch_routine (uint16_t builtin_routine_id, /**< built
return ecma_date_value_to_utc_string (*prim_value_p);
}
+ case ECMA_INTRINSIC_STRING_TRIM_START:
+ case ECMA_INTRINSIC_STRING_TRIM_END:
+ {
+ ecma_value_t coercible = ecma_op_check_object_coercible (this_arg);
+
+ if (ECMA_IS_VALUE_ERROR (coercible))
+ {
+ return coercible;
+ }
+
+ ecma_string_t *to_str_p = ecma_op_to_string (this_arg);
+ if (to_str_p == NULL)
+ {
+ return ECMA_VALUE_ERROR;
+ }
+
+ ECMA_STRING_TO_UTF8_STRING (to_str_p, start_p, input_start_size);
+
+ lit_utf8_size_t size;
+ const lit_utf8_byte_t *input_start_p = start_p;
+ const lit_utf8_byte_t *input_str_end_p = start_p + input_start_size;
+
+ ecma_string_t *ret_str_p;
+ if (builtin_routine_id == ECMA_INTRINSIC_STRING_TRIM_START)
+ {
+ const lit_utf8_byte_t *new_start_p = ecma_string_trim_front (input_start_p, input_str_end_p);
+ size = (lit_utf8_size_t) (input_str_end_p - new_start_p);
+ ret_str_p = ecma_new_ecma_string_from_utf8 (new_start_p, size);
+ }
+ else
+ {
+ const lit_utf8_byte_t *new_end_p = ecma_string_trim_back (input_start_p, input_str_end_p);
+ size = (lit_utf8_size_t) (new_end_p - input_start_p);
+ ret_str_p = ecma_new_ecma_string_from_utf8 (input_start_p, size);
+ }
+
+ ECMA_FINALIZE_UTF8_STRING (start_p, input_start_size);
+ ecma_value_t result = ecma_make_string_value (ret_str_p);
+ ecma_deref_ecma_string (to_str_p);
+ return result;
+
+ }
default:
{
JERRY_ASSERT (builtin_routine_id == ECMA_INTRINSIC_PARSE_INT
@@ -236,7 +282,6 @@ ecma_builtin_intrinsic_dispatch_routine (uint16_t builtin_routine_id, /**< built
ECMA_FINALIZE_UTF8_STRING (string_buff, string_buff_size);
ecma_deref_ecma_string (str_p);
-
return result;
}
}
diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-intrinsic.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-intrinsic.inc.h
index 89ae67c8b..d0063f7c9 100644
--- a/jerry-core/ecma/builtin-objects/ecma-builtin-intrinsic.inc.h
+++ b/jerry-core/ecma/builtin-objects/ecma-builtin-intrinsic.inc.h
@@ -74,6 +74,8 @@ ROUTINE (LIT_INTERNAL_MAGIC_STRING_ARRAY_PROTOTYPE_VALUES, ECMA_INTRINSIC_ARRAY_
ROUTINE (LIT_INTERNAL_MAGIC_STRING_TYPEDARRAY_PROTOTYPE_VALUES, ECMA_INTRINSIC_TYPEDARRAY_PROTOTYPE_VALUES, 0, 0)
ROUTINE (LIT_INTERNAL_MAGIC_STRING_SET_PROTOTYPE_VALUES, ECMA_INTRINSIC_SET_PROTOTYPE_VALUES, 0, 0)
ROUTINE (LIT_INTERNAL_MAGIC_STRING_MAP_PROTOTYPE_ENTRIES, ECMA_INTRINSIC_MAP_PROTOTYPE_ENTRIES, 0, 0)
+ROUTINE (LIT_MAGIC_STRING_TRIM_START, ECMA_INTRINSIC_STRING_TRIM_START, 0, 0)
+ROUTINE (LIT_MAGIC_STRING_TRIM_END, ECMA_INTRINSIC_STRING_TRIM_END, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_STRING_UL, ECMA_INTRINSIC_ARRAY_TO_STRING, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_UTC_STRING_UL, ECMA_INTRINSIC_DATE_TO_UTC_STRING, 0, 0)
ROUTINE (LIT_MAGIC_STRING_PARSE_FLOAT, ECMA_INTRINSIC_PARSE_FLOAT, 1, 1)
diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.inc.h
index f3e685b4d..17663d3f1 100644
--- a/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.inc.h
+++ b/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.inc.h
@@ -76,6 +76,15 @@ ROUTINE (LIT_MAGIC_STRING_CODE_POINT_AT, ECMA_STRING_PROTOTYPE_CODE_POINT_AT, 1,
ROUTINE (LIT_MAGIC_STRING_PAD_START, ECMA_STRING_PROTOTYPE_PAD_START, 2, 1)
ROUTINE (LIT_MAGIC_STRING_PAD_END, ECMA_STRING_PROTOTYPE_PAD_END, 2, 1)
ROUTINE (LIT_GLOBAL_SYMBOL_ITERATOR, ECMA_STRING_PROTOTYPE_ITERATOR, 0, 0)
+
+INTRINSIC_PROPERTY (LIT_MAGIC_STRING_TRIM_START, LIT_MAGIC_STRING_TRIM_START,
+ ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
+INTRINSIC_PROPERTY (LIT_MAGIC_STRING_TRIM_LEFT, LIT_MAGIC_STRING_TRIM_START,
+ ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
+INTRINSIC_PROPERTY (LIT_MAGIC_STRING_TRIM_END, LIT_MAGIC_STRING_TRIM_END,
+ ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
+INTRINSIC_PROPERTY (LIT_MAGIC_STRING_TRIM_RIGHT, LIT_MAGIC_STRING_TRIM_END,
+ ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#endif /* ENABLED (JERRY_ESNEXT) */
#endif /* ENABLED (JERRY_BUILTIN_STRING) */
diff --git a/jerry-core/lit/lit-magic-strings.inc.h b/jerry-core/lit/lit-magic-strings.inc.h
index 62410e425..36e59c7ff 100644
--- a/jerry-core/lit/lit-magic-strings.inc.h
+++ b/jerry-core/lit/lit-magic-strings.inc.h
@@ -531,6 +531,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SPECIES, "species")
#if ENABLED (JERRY_BUILTIN_NUMBER)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_TO_FIXED_UL, "toFixed")
#endif
+#if ENABLED (JERRY_ESNEXT)
+LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_TRIM_END, "trimEnd")
+#endif
#if ENABLED (JERRY_BUILTIN_REGEXP) && ENABLED (JERRY_ESNEXT)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_UNICODE, "unicode")
#endif
@@ -598,6 +601,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SET_UINT8_UL, "setUint8")
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SUBARRAY, "subarray")
#endif
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_TO_STRING_UL, "toString")
+#if ENABLED (JERRY_BUILTIN_STRING) && ENABLED (JERRY_ESNEXT)
+LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_TRIM_LEFT, "trimLeft")
+#endif
#if ENABLED (JERRY_BUILTIN_ANNEXB)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_UNESCAPE, "unescape")
#endif
@@ -668,6 +674,12 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_STRINGIFY, "stringify")
#if ENABLED (JERRY_BUILTIN_STRING)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SUBSTRING, "substring")
#endif
+#if ENABLED (JERRY_BUILTIN_STRING) && ENABLED (JERRY_ESNEXT)
+LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_TRIM_RIGHT, "trimRight")
+#endif
+#if ENABLED (JERRY_ESNEXT)
+LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_TRIM_START, "trimStart")
+#endif
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_UNDEFINED, "undefined")
#if ENABLED (JERRY_BUILTIN_TYPEDARRAY)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_INT16_ARRAY_UL, "Int16Array")
diff --git a/jerry-core/lit/lit-magic-strings.ini b/jerry-core/lit/lit-magic-strings.ini
index a54ea5596..50f22c9e2 100644
--- a/jerry-core/lit/lit-magic-strings.ini
+++ b/jerry-core/lit/lit-magic-strings.ini
@@ -206,6 +206,7 @@ LIT_MAGIC_STRING_SET_INT8_UL = "setInt8"
LIT_MAGIC_STRING_SET_YEAR_UL = "setYear"
LIT_MAGIC_STRING_SPECIES = "species"
LIT_MAGIC_STRING_TO_FIXED_UL = "toFixed"
+LIT_MAGIC_STRING_TRIM_END = "trimEnd"
LIT_MAGIC_STRING_UNICODE = "unicode"
LIT_MAGIC_STRING_UNSHIFT = "unshift"
LIT_MAGIC_STRING_VALUE_OF_UL = "valueOf"
@@ -236,6 +237,7 @@ LIT_MAGIC_STRING_SET_MONTH_UL = "setMonth"
LIT_MAGIC_STRING_SET_UINT8_UL = "setUint8"
LIT_MAGIC_STRING_SUBARRAY = "subarray"
LIT_MAGIC_STRING_TO_STRING_UL = "toString"
+LIT_MAGIC_STRING_TRIM_LEFT = "trimLeft"
LIT_MAGIC_STRING_UNESCAPE = "unescape"
LIT_MAGIC_STRING_WRITABLE = "writable"
LIT_MAGIC_STRING_OBJECT_TO_STRING_UL = "[object "
@@ -267,6 +269,8 @@ LIT_MAGIC_STRING_STRINGIFY = "stringify"
LIT_MAGIC_STRING_SET_UINT16_UL = "setUint16"
LIT_MAGIC_STRING_SET_UINT32_UL = "setUint32"
LIT_MAGIC_STRING_SUBSTRING = "substring"
+LIT_MAGIC_STRING_TRIM_RIGHT = "trimRight"
+LIT_MAGIC_STRING_TRIM_START = "trimStart"
LIT_MAGIC_STRING_UNDEFINED = "undefined"
LIT_MAGIC_STRING_INT16_ARRAY_UL = "Int16Array"
LIT_MAGIC_STRING_INT32_ARRAY_UL = "Int32Array"
diff --git a/tests/jerry/es.next/string-prototype-trim.js b/tests/jerry/es.next/string-prototype-trim.js
new file mode 100644
index 000000000..7aaf2fea4
--- /dev/null
+++ b/tests/jerry/es.next/string-prototype-trim.js
@@ -0,0 +1,29 @@
+// Copyright JS Foundation and other contributors, http://js.foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+var test = " asd ";
+assert(test.trimStart() === "asd ")
+assert(test.trimStart().length === 5)
+assert(test.trimLeft() === "asd ")
+assert(test.trimLeft().length === 5)
+assert(String.prototype.trimStart === String.prototype.trimLeft)
+
+assert(test.trimEnd() === " asd")
+assert(test.trimEnd().length === 5)
+assert(test.trimRight() === " asd")
+assert(test.trimRight().length === 5)
+assert(String.prototype.trimEnd === String.prototype.trimRight)
+
+assert(test.trim() === "asd")
+assert(test.trim().length === 3)
diff --git a/tests/test262-esnext-excludelist.xml b/tests/test262-esnext-excludelist.xml
index eb9e46b68..04d54a78e 100644
--- a/tests/test262-esnext-excludelist.xml
+++ b/tests/test262-esnext-excludelist.xml
@@ -92,12 +92,6 @@
-
-
-
-
-
-
@@ -1947,50 +1941,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-