Implement String repeat (#2904)

Co-authored-by: Tamas Keri tkeri@inf.u-szeged.hu
JerryScript-DCO-1.0-Signed-off-by: Daniella Barsony bella@inf.u-szeged.hu
This commit is contained in:
Daniella Barsony
2019-06-19 12:19:21 +02:00
committed by Dániel Bátyai
parent 8ee8bc2767
commit 985de93d04
5 changed files with 163 additions and 0 deletions
@@ -2095,6 +2095,90 @@ ecma_builtin_string_prototype_object_trim (ecma_value_t this_arg) /**< this argu
return ret_value;
} /* ecma_builtin_string_prototype_object_trim */
#if ENABLED (JERRY_ES2015_BUILTIN)
/**
* The String.prototype object's 'repeat' routine
*
* See also:
* ECMA-262 v6, 21.1.3.13
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_string_prototype_object_repeat (ecma_value_t this_arg, /**< this argument */
ecma_value_t count) /**< times to repeat */
{
/* 1 */
ecma_value_t check_coercible_value = ecma_op_check_object_coercible (this_arg);
if (ECMA_IS_VALUE_ERROR (check_coercible_value))
{
return check_coercible_value;
}
/* 2, 3 */
ecma_value_t to_string_val = ecma_op_to_string (this_arg);
if (ECMA_IS_VALUE_ERROR (to_string_val))
{
return to_string_val;
}
ecma_string_t *original_string_p = ecma_get_string_from_value (to_string_val);
ecma_string_t *ret_string_p;
/* 4 */
ecma_number_t length_number;
ecma_value_t length_value = ecma_get_number (count, &length_number);
/* 5 */
if (ECMA_IS_VALUE_ERROR (length_value))
{
ecma_deref_ecma_string (original_string_p);
return length_value;
}
int32_t length = ecma_number_to_int32 (length_number);
bool isNan = ecma_number_is_nan (length_number);
/* 6, 7 */
if (length < 0 || (!isNan && ecma_number_is_infinity (length_number)))
{
ecma_deref_ecma_string (original_string_p);
return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid count value"));
}
if (length == 0 || isNan)
{
ecma_deref_ecma_string (original_string_p);
return ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY);
}
lit_utf8_size_t size = ecma_string_get_utf8_size (original_string_p);
lit_utf8_size_t total_size = size * (lit_utf8_size_t) length;
JMEM_DEFINE_LOCAL_ARRAY (str_buffer, total_size, lit_utf8_byte_t);
lit_utf8_byte_t *buffer_ptr = str_buffer;
for (int32_t n = 0; n < length; n++)
{
buffer_ptr += ecma_string_copy_to_cesu8_buffer (original_string_p, buffer_ptr,
(lit_utf8_size_t) (size));
}
ret_string_p = ecma_new_ecma_string_from_utf8 (str_buffer, (lit_utf8_size_t) (buffer_ptr - str_buffer));
JMEM_FINALIZE_LOCAL_ARRAY (str_buffer);
ecma_deref_ecma_string (original_string_p);
return ecma_make_string_value (ret_string_p);
} /* ecma_builtin_string_prototype_object_repeat */
#endif /* ENABLED (JERRY_ES2015_BUILTIN) */
#if ENABLED (JERRY_BUILTIN_ANNEXB)
/**
@@ -55,6 +55,10 @@ ROUTINE (LIT_MAGIC_STRING_REPLACE, ecma_builtin_string_prototype_object_replace,
ROUTINE (LIT_MAGIC_STRING_SEARCH, ecma_builtin_string_prototype_object_search, 1, 1)
#endif /* ENABLED (JERRY_BUILTIN_REGEXP) */
#if ENABLED (JERRY_ES2015_BUILTIN)
ROUTINE (LIT_MAGIC_STRING_REPEAT, ecma_builtin_string_prototype_object_repeat, 1, 1)
#endif /* ENABLED (JERRY_ES2015_BUILTIN) */
ROUTINE (LIT_MAGIC_STRING_SPLIT, ecma_builtin_string_prototype_object_split, 2, 2)
ROUTINE (LIT_MAGIC_STRING_SUBSTRING, ecma_builtin_string_prototype_object_substring, 2, 2)
ROUTINE (LIT_MAGIC_STRING_TO_LOWER_CASE_UL, ecma_builtin_string_prototype_object_to_lower_case, 0, 0)
+3
View File
@@ -300,6 +300,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_REDUCE, "reduce")
#if ENABLED (JERRY_ES2015_BUILTIN_PROMISE)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_REJECT, "reject")
#endif
#if ENABLED (JERRY_BUILTIN_STRING) && ENABLED (JERRY_ES2015_BUILTIN)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_REPEAT, "repeat")
#endif
#if ENABLED (JERRY_BUILTIN_REGEXP) && ENABLED (JERRY_BUILTIN_STRING) \
|| ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SEARCH, "search")
+1
View File
@@ -139,6 +139,7 @@ LIT_MAGIC_STRING_OBJECT = "object"
LIT_MAGIC_STRING_RANDOM = "random"
LIT_MAGIC_STRING_REDUCE = "reduce"
LIT_MAGIC_STRING_REJECT = "reject"
LIT_MAGIC_STRING_REPEAT = "repeat"
LIT_MAGIC_STRING_SEARCH = "search"
LIT_MAGIC_STRING_SOURCE = "source"
LIT_MAGIC_STRING_SPLICE = "splice"
@@ -0,0 +1,71 @@
/* 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.
*/
// ES v6.0 21.1.3.13.6
var z = "I am vengeance";
try {
z.repeat (-1);
assert (false);
} catch (e) {
assert (e instanceof RangeError);
}
// ES v6.0 21.1.3.13.7
var x = "I am the night";
try {
print(z.repeat (Infinity));
assert (false);
} catch (e) {
assert (e instanceof RangeError);
}
// ES v6.0 21.1.3.13.8
assert (z.repeat (0) === "");
assert (z.repeat (NaN) === "");
var y = "I am batman ";
assert (y.repeat (3) === "I am batman I am batman I am batman ");
assert (String.prototype.repeat.call ("My cat is awesome. ", 3) === "My cat is awesome. My cat is awesome. My cat is awesome. ");
try {
String.prototype.repeat.call (undefined);
assert (false);
} catch (e) {
assert (e instanceof TypeError);
}
try {
String.prototype.repeat.call (null);
assert (false);
} catch (e) {
assert (e instanceof TypeError);
}
try {
String.prototype.repeat.call (undefined, "Sylveon");
assert (false);
} catch (e) {
assert (e instanceof TypeError);
}
var a = Symbol ("Unicorn invasion.", 3);
try {
String.prototype.repeat.call (a);
assert (false);
} catch (e) {
assert (e instanceof TypeError);
}