From 9d724db40331504137b8148f17ca628eff62b744 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A1szl=C3=B3=20Lang=C3=B3?= Date: Tue, 22 Jan 2019 15:42:28 +0100 Subject: [PATCH] Added new 'jerry_value_strict_equal' API function. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added new API function to perform strict equality comparison between 'jerry_value_t's from C code. JerryScript-DCO-1.0-Signed-off-by: László Langó llango.u-szeged@partner.samsung.com --- docs/02.API-REFERENCE.md | 57 +++++++++++++ jerry-core/api/jerry.c | 24 ++++++ jerry-core/include/jerryscript-core.h | 5 ++ tests/unit-core/test-api-strict-equal.c | 104 ++++++++++++++++++++++++ 4 files changed, 190 insertions(+) create mode 100644 tests/unit-core/test-api-strict-equal.c diff --git a/docs/02.API-REFERENCE.md b/docs/02.API-REFERENCE.md index 77af7c6afb..837a52f686 100644 --- a/docs/02.API-REFERENCE.md +++ b/docs/02.API-REFERENCE.md @@ -1630,6 +1630,63 @@ jerry_value_is_undefined (const jerry_value_t value) - [jerry_release_value](#jerry_release_value) + +## jerry_strict_equal + +**Summary** + +Perform strict equality comparison on the given operands. + +**Prototype** + +```c +jerry_value_t jerry_strict_equal (const jerry_value_t lhs, const jerry_value_t rhs); +``` + +- `lhs` - left-hand side operand +- `rhs` - right-hand side operand +- return value + - error, if argument has an error flag + - true, if the two operands are strictly equal + - false, otherwise + +**Example** + +```c +{ + jerry_value_t value1; + jerry_value_t value2; + ... // create or acquire value + + jerry_value_t result = jerry_strict_equal (value1, value2) + + if (!jerry_value_is_error (result)) + { + if (jerry_get_boolean_value (result)) + { + // value1 and value2 are equal + } + else + { + // value1 and value2 are NOT equal + } + } + else + { + ... // handle error + } + + jerry_release_value (value1); + jerry_release_value (value2); + jerry_release_value (result); +} +``` + +**See also** + +- [jerry_value_t](#jerry_value_t) + + ## jerry_value_get_type **Summary** diff --git a/jerry-core/api/jerry.c b/jerry-core/api/jerry.c index 7b7c7228de..90481a25c7 100644 --- a/jerry-core/api/jerry.c +++ b/jerry-core/api/jerry.c @@ -21,6 +21,7 @@ #include "ecma-arraybuffer-object.h" #include "ecma-builtin-helpers.h" #include "ecma-builtins.h" +#include "ecma-comparison.h" #include "ecma-exceptions.h" #include "ecma-eval.h" #include "ecma-function-object.h" @@ -782,6 +783,29 @@ jerry_value_is_undefined (const jerry_value_t value) /**< api value */ return ecma_is_value_undefined (value); } /* jerry_value_is_undefined */ +/** + * Perform strict equality comparison on the given operands. + * + * See also ECMA-262 v5.1, 11.9.6 + * + * @return true - if the two operands are strictly equal + * false - otherwise + * error - if argument has an error flag + */ +jerry_value_t +jerry_strict_equal (const jerry_value_t lhs, /**< first operand */ + const jerry_value_t rhs) /**< second operand */ +{ + jerry_assert_api_available (); + + if (ecma_is_value_error_reference (lhs) || ecma_is_value_error_reference (rhs)) + { + return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p))); + } + + return ecma_make_boolean_value (ecma_op_strict_equality_compare (lhs, rhs)); +} /* jerry_strict_equal */ + /** * Perform the base type of the JavaScript value. * diff --git a/jerry-core/include/jerryscript-core.h b/jerry-core/include/jerryscript-core.h index 1386abaf70..f2522de2b3 100644 --- a/jerry-core/include/jerryscript-core.h +++ b/jerry-core/include/jerryscript-core.h @@ -356,6 +356,11 @@ bool jerry_value_is_promise (const jerry_value_t value); bool jerry_value_is_string (const jerry_value_t value); bool jerry_value_is_undefined (const jerry_value_t value); +/* + * Comparison functions + */ +jerry_value_t jerry_strict_equal (const jerry_value_t lhs, const jerry_value_t rhs); + /** * JerryScript API value type information. */ diff --git a/tests/unit-core/test-api-strict-equal.c b/tests/unit-core/test-api-strict-equal.c new file mode 100644 index 0000000000..a0ddb1f005 --- /dev/null +++ b/tests/unit-core/test-api-strict-equal.c @@ -0,0 +1,104 @@ +/* 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. + */ + +#include "jerryscript.h" + +#include "test-common.h" + +#define T(lhs, rhs, res) \ + { lhs, rhs, res } + +typedef struct +{ + jerry_value_t lhs; + jerry_value_t rhs; + bool expected; +} test_entry_t; + +int +main (void) +{ + TEST_INIT (); + + jerry_init (JERRY_INIT_EMPTY); + + jerry_value_t obj1 = jerry_eval ((const jerry_char_t *) "o={x:1};o", 9, JERRY_PARSE_NO_OPTS); + jerry_value_t obj2 = jerry_eval ((const jerry_char_t *) "o={x:1};o", 9, JERRY_PARSE_NO_OPTS); + jerry_value_t err1 = jerry_create_error (JERRY_ERROR_SYNTAX, (const jerry_char_t *) "error"); + + test_entry_t tests[] = + { + T (jerry_create_number (5.0), jerry_create_number (5.0), true), + T (jerry_create_number (3.1), jerry_create_number (10), false), + T (jerry_create_number (3.1), jerry_create_undefined (), false), + T (jerry_create_number (3.1), jerry_create_boolean (true), false), + T (jerry_create_string ((const jerry_char_t *) "example string"), + jerry_create_string ((const jerry_char_t *) "example string"), + true), + T (jerry_create_string ((const jerry_char_t *) "example string"), jerry_create_undefined (), false), + T (jerry_create_string ((const jerry_char_t *) "example string"), jerry_create_null (), false), + T (jerry_create_string ((const jerry_char_t *) "example string"), jerry_create_number (5.0), false), + T (jerry_create_undefined (), jerry_create_undefined (), true), + T (jerry_create_undefined (), jerry_create_null (), false), + T (jerry_create_null (), jerry_create_null (), true), + T (jerry_create_boolean (true), jerry_create_boolean (true), true), + T (jerry_create_boolean (true), jerry_create_boolean (false), false), + T (jerry_create_boolean (false), jerry_create_boolean (true), false), + T (jerry_create_boolean (false), jerry_create_boolean (false), true), + T (jerry_acquire_value (obj1), jerry_acquire_value (obj1), true), + T (jerry_acquire_value (obj1), jerry_acquire_value (obj2), false), + T (jerry_acquire_value (obj2), jerry_acquire_value (obj1), false), + T (jerry_acquire_value (obj1), jerry_create_null (), false), + T (jerry_acquire_value (obj1), jerry_create_undefined (), false), + T (jerry_acquire_value (obj1), jerry_create_boolean (true), false), + T (jerry_acquire_value (obj1), jerry_create_boolean (false), false), + T (jerry_acquire_value (obj1), jerry_create_number (5.0), false), + T (jerry_acquire_value (obj1), jerry_create_string ((const jerry_char_t *) "example string"), false) + }; + + for (uint32_t idx = 0; idx < sizeof (tests) / sizeof (test_entry_t); idx++) + { + jerry_value_t result = jerry_strict_equal (tests[idx].lhs, tests[idx].rhs); + TEST_ASSERT (!jerry_value_is_error (result)); + TEST_ASSERT (jerry_get_boolean_value (result) == tests[idx].expected); + jerry_release_value (tests[idx].lhs); + jerry_release_value (tests[idx].rhs); + jerry_release_value (result); + } + + test_entry_t error_tests[] = + { + T (jerry_acquire_value (err1), jerry_acquire_value (err1), true), + T (jerry_acquire_value (err1), jerry_create_undefined (), true), + T (jerry_create_undefined (), jerry_acquire_value (err1), true), + }; + + for (uint32_t idx = 0; idx < sizeof (error_tests) / sizeof (test_entry_t); idx++) + { + jerry_value_t result = jerry_strict_equal (error_tests[idx].lhs, error_tests[idx].rhs); + TEST_ASSERT (jerry_value_is_error (result) == error_tests[idx].expected); + jerry_release_value (error_tests[idx].lhs); + jerry_release_value (error_tests[idx].rhs); + jerry_release_value (result); + } + + jerry_release_value (obj1); + jerry_release_value (obj2); + jerry_release_value (err1); + + jerry_cleanup (); + + return 0; +} /* main */