Implement String.prototype.codePointAt method (#3291)
The algorithm is based on ECMA-262 v6, 21.1.3.3 JerryScript-DCO-1.0-Signed-off-by: Adam Szilagyi aszilagy@inf.u-szeged.hu
This commit is contained in:
committed by
Robert Fancsik
parent
da69589f05
commit
452c78182d
@@ -30,6 +30,7 @@
|
|||||||
#include "jrt.h"
|
#include "jrt.h"
|
||||||
#include "jrt-libc-includes.h"
|
#include "jrt-libc-includes.h"
|
||||||
#include "lit-char-helpers.h"
|
#include "lit-char-helpers.h"
|
||||||
|
#include "lit-strings.h"
|
||||||
|
|
||||||
#if ENABLED (JERRY_BUILTIN_REGEXP)
|
#if ENABLED (JERRY_BUILTIN_REGEXP)
|
||||||
#include "ecma-regexp-object.h"
|
#include "ecma-regexp-object.h"
|
||||||
@@ -77,6 +78,7 @@ enum
|
|||||||
ECMA_STRING_PROTOTYPE_SUBSTR,
|
ECMA_STRING_PROTOTYPE_SUBSTR,
|
||||||
|
|
||||||
ECMA_STRING_PROTOTYPE_REPEAT,
|
ECMA_STRING_PROTOTYPE_REPEAT,
|
||||||
|
ECMA_STRING_PROTOTYPE_CODE_POINT_AT,
|
||||||
/* Note: These 5 routines MUST be in this order */
|
/* Note: These 5 routines MUST be in this order */
|
||||||
ECMA_STRING_PROTOTYPE_INDEX_OF,
|
ECMA_STRING_PROTOTYPE_INDEX_OF,
|
||||||
ECMA_STRING_PROTOTYPE_LAST_INDEX_OF,
|
ECMA_STRING_PROTOTYPE_LAST_INDEX_OF,
|
||||||
@@ -1401,6 +1403,54 @@ ecma_builtin_string_prototype_object_repeat (ecma_string_t *original_string_p, /
|
|||||||
return ecma_make_string_value (ret_string_p);
|
return ecma_make_string_value (ret_string_p);
|
||||||
} /* ecma_builtin_string_prototype_object_repeat */
|
} /* ecma_builtin_string_prototype_object_repeat */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The String.prototype object's 'codePointAt' routine
|
||||||
|
*
|
||||||
|
* See also:
|
||||||
|
* ECMA-262 v6, 21.1.3.3
|
||||||
|
*
|
||||||
|
* @return lit_code_point_t
|
||||||
|
*/
|
||||||
|
static ecma_value_t
|
||||||
|
ecma_builtin_string_prototype_object_code_point_at (ecma_string_t *this_string_p, /**< this argument */
|
||||||
|
ecma_value_t pos) /**< given position */
|
||||||
|
{
|
||||||
|
ecma_number_t pos_num;
|
||||||
|
ecma_value_t error = ecma_op_to_integer (pos, &pos_num);
|
||||||
|
|
||||||
|
if (ECMA_IS_VALUE_ERROR (error))
|
||||||
|
{
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
ecma_length_t size = ecma_string_get_length (this_string_p);
|
||||||
|
|
||||||
|
if (pos_num < 0 || pos_num >= size)
|
||||||
|
{
|
||||||
|
return ECMA_VALUE_UNDEFINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t index = (uint32_t) pos_num;
|
||||||
|
|
||||||
|
ecma_char_t first = ecma_string_get_char_at_pos (this_string_p, index);
|
||||||
|
|
||||||
|
if (first < LIT_UTF16_HIGH_SURROGATE_MIN
|
||||||
|
|| first > LIT_UTF16_HIGH_SURROGATE_MAX
|
||||||
|
|| index + 1 == size)
|
||||||
|
{
|
||||||
|
return ecma_make_uint32_value (first);
|
||||||
|
}
|
||||||
|
|
||||||
|
ecma_char_t second = ecma_string_get_char_at_pos (this_string_p, index + 1);
|
||||||
|
|
||||||
|
if (second < LIT_UTF16_LOW_SURROGATE_MARKER
|
||||||
|
|| second > LIT_UTF16_LOW_SURROGATE_MAX)
|
||||||
|
{
|
||||||
|
return ecma_make_uint32_value (first);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ecma_make_uint32_value (lit_convert_surrogate_pair_to_code_point (first, second));
|
||||||
|
} /* ecma_builtin_string_prototype_object_code_point_at */
|
||||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN) */
|
#endif /* ENABLED (JERRY_ES2015_BUILTIN) */
|
||||||
|
|
||||||
#if ENABLED (JERRY_BUILTIN_ANNEXB)
|
#if ENABLED (JERRY_BUILTIN_ANNEXB)
|
||||||
@@ -1615,6 +1665,11 @@ ecma_builtin_string_prototype_dispatch_routine (uint16_t builtin_routine_id, /**
|
|||||||
ret_value = ecma_builtin_string_prototype_object_repeat (string_p, arg1);
|
ret_value = ecma_builtin_string_prototype_object_repeat (string_p, arg1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ECMA_STRING_PROTOTYPE_CODE_POINT_AT:
|
||||||
|
{
|
||||||
|
ret_value = ecma_builtin_string_prototype_object_code_point_at (string_p, arg1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN) */
|
#endif /* ENABLED (JERRY_ES2015_BUILTIN) */
|
||||||
#if ENABLED (JERRY_ES2015_BUILTIN_ITERATOR)
|
#if ENABLED (JERRY_ES2015_BUILTIN_ITERATOR)
|
||||||
case ECMA_STRING_PROTOTYPE_ITERATOR:
|
case ECMA_STRING_PROTOTYPE_ITERATOR:
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ ROUTINE (LIT_MAGIC_STRING_REPEAT, ECMA_STRING_PROTOTYPE_REPEAT, 1, 1)
|
|||||||
ROUTINE (LIT_MAGIC_STRING_STARTS_WITH, ECMA_STRING_PROTOTYPE_STARTS_WITH, 2, 1)
|
ROUTINE (LIT_MAGIC_STRING_STARTS_WITH, ECMA_STRING_PROTOTYPE_STARTS_WITH, 2, 1)
|
||||||
ROUTINE (LIT_MAGIC_STRING_INCLUDES, ECMA_STRING_PROTOTYPE_INCLUDES, 2, 1)
|
ROUTINE (LIT_MAGIC_STRING_INCLUDES, ECMA_STRING_PROTOTYPE_INCLUDES, 2, 1)
|
||||||
ROUTINE (LIT_MAGIC_STRING_ENDS_WITH, ECMA_STRING_PROTOTYPE_ENDS_WITH, 2, 1)
|
ROUTINE (LIT_MAGIC_STRING_ENDS_WITH, ECMA_STRING_PROTOTYPE_ENDS_WITH, 2, 1)
|
||||||
|
ROUTINE (LIT_MAGIC_STRING_CODE_POINT_AT, ECMA_STRING_PROTOTYPE_CODE_POINT_AT, 1, 1)
|
||||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN) */
|
#endif /* ENABLED (JERRY_ES2015_BUILTIN) */
|
||||||
|
|
||||||
#if ENABLED (JERRY_ES2015_BUILTIN_ITERATOR)
|
#if ENABLED (JERRY_ES2015_BUILTIN_ITERATOR)
|
||||||
|
|||||||
@@ -612,6 +612,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SYNTAX_ERROR_UL, "SyntaxError")
|
|||||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_UINT16_ARRAY_UL, "Uint16Array")
|
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_UINT16_ARRAY_UL, "Uint16Array")
|
||||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_UINT32_ARRAY_UL, "Uint32Array")
|
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_UINT32_ARRAY_UL, "Uint32Array")
|
||||||
#endif
|
#endif
|
||||||
|
#if ENABLED (JERRY_BUILTIN_STRING) && ENABLED (JERRY_ES2015_BUILTIN)
|
||||||
|
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_CODE_POINT_AT, "codePointAt")
|
||||||
|
#endif
|
||||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_CONSTRUCTOR, "constructor")
|
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_CONSTRUCTOR, "constructor")
|
||||||
#if ENABLED (JERRY_BUILTIN_DATE)
|
#if ENABLED (JERRY_BUILTIN_DATE)
|
||||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_GET_FULL_YEAR_UL, "getFullYear")
|
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_GET_FULL_YEAR_UL, "getFullYear")
|
||||||
|
|||||||
@@ -261,6 +261,7 @@ LIT_MAGIC_STRING_SYNTAX_ERROR_UL = "SyntaxError"
|
|||||||
LIT_MAGIC_STRING_UINT16_ARRAY_UL = "Uint16Array"
|
LIT_MAGIC_STRING_UINT16_ARRAY_UL = "Uint16Array"
|
||||||
LIT_MAGIC_STRING_UINT32_ARRAY_UL = "Uint32Array"
|
LIT_MAGIC_STRING_UINT32_ARRAY_UL = "Uint32Array"
|
||||||
LIT_MAGIC_STRING_CONSTRUCTOR = "constructor"
|
LIT_MAGIC_STRING_CONSTRUCTOR = "constructor"
|
||||||
|
LIT_MAGIC_STRING_CODE_POINT_AT = "codePointAt"
|
||||||
LIT_MAGIC_STRING_GET_FULL_YEAR_UL = "getFullYear"
|
LIT_MAGIC_STRING_GET_FULL_YEAR_UL = "getFullYear"
|
||||||
LIT_MAGIC_STRING_GET_UTC_HOURS_UL = "getUTCHours"
|
LIT_MAGIC_STRING_GET_UTC_HOURS_UL = "getUTCHours"
|
||||||
LIT_MAGIC_STRING_GET_UTC_MONTH_UL = "getUTCMonth"
|
LIT_MAGIC_STRING_GET_UTC_MONTH_UL = "getUTCMonth"
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
// 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 str = "A🌃B\uD800";
|
||||||
|
var obj = {};
|
||||||
|
|
||||||
|
// Test with normal inputs
|
||||||
|
assert(str.codePointAt(0) === 65);
|
||||||
|
assert(str.codePointAt(1) === 127747);
|
||||||
|
assert(str.codePointAt(2) === 57091);
|
||||||
|
assert(str.codePointAt(3) === 66);
|
||||||
|
assert(str.codePointAt(4) === 55296);
|
||||||
|
|
||||||
|
// Test with string
|
||||||
|
assert(str.codePointAt("a") === 65);
|
||||||
|
assert(str.codePointAt("B") === 65);
|
||||||
|
|
||||||
|
// Test with object
|
||||||
|
assert(str.codePointAt(obj) === 65);
|
||||||
|
|
||||||
|
// Test with NaN
|
||||||
|
assert(str.codePointAt(NaN) === 65);
|
||||||
|
|
||||||
|
// Test when the input >= length
|
||||||
|
assert(str.codePointAt(5) === undefined);
|
||||||
|
assert(str.codePointAt(10) === undefined);
|
||||||
|
|
||||||
|
// Test witn negative
|
||||||
|
assert(str.codePointAt(-1) === undefined);
|
||||||
|
assert(str.codePointAt(-5) === undefined);
|
||||||
|
assert(str.codePointAt(-0) === 65);
|
||||||
|
|
||||||
|
// Test with undefined and +/- Infinity
|
||||||
|
assert(str.codePointAt(undefined) === 65);
|
||||||
|
assert(str.codePointAt(Infinity) === undefined);
|
||||||
|
assert(str.codePointAt(-Infinity) === undefined);
|
||||||
|
|
||||||
|
// Test with boolean
|
||||||
|
assert(str.codePointAt(true) === 127747);
|
||||||
|
assert(str.codePointAt(false) === 65);
|
||||||
|
|
||||||
|
// Test when input > UINT32_MAX
|
||||||
|
assert(str.codePointAt(4294967299) === undefined);
|
||||||
Reference in New Issue
Block a user