1425bb815Sopenharmony_ci/* Copyright JS Foundation and other contributors, http://js.foundation 2425bb815Sopenharmony_ci * 3425bb815Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4425bb815Sopenharmony_ci * you may not use this file except in compliance with the License. 5425bb815Sopenharmony_ci * You may obtain a copy of the License at 6425bb815Sopenharmony_ci * 7425bb815Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8425bb815Sopenharmony_ci * 9425bb815Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10425bb815Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS 11425bb815Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12425bb815Sopenharmony_ci * See the License for the specific language governing permissions and 13425bb815Sopenharmony_ci * limitations under the License. 14425bb815Sopenharmony_ci */ 15425bb815Sopenharmony_ci 16425bb815Sopenharmony_ci#include "ecma-comparison.h" 17425bb815Sopenharmony_ci#include "ecma-conversion.h" 18425bb815Sopenharmony_ci#include "ecma-exceptions.h" 19425bb815Sopenharmony_ci#include "ecma-function-object.h" 20425bb815Sopenharmony_ci#include "ecma-helpers.h" 21425bb815Sopenharmony_ci#include "ecma-objects.h" 22425bb815Sopenharmony_ci#include "ecma-try-catch-macro.h" 23425bb815Sopenharmony_ci#include "opcodes.h" 24425bb815Sopenharmony_ci 25425bb815Sopenharmony_ci/** \addtogroup vm Virtual machine 26425bb815Sopenharmony_ci * @{ 27425bb815Sopenharmony_ci * 28425bb815Sopenharmony_ci * \addtogroup vm_opcodes Opcodes 29425bb815Sopenharmony_ci * @{ 30425bb815Sopenharmony_ci */ 31425bb815Sopenharmony_ci 32425bb815Sopenharmony_ci/** 33425bb815Sopenharmony_ci* Equality opcode handler. 34425bb815Sopenharmony_ci* 35425bb815Sopenharmony_ci* See also: ECMA-262 v5, 11.9.1, 11.9.2 36425bb815Sopenharmony_ci* 37425bb815Sopenharmony_ci* @return ecma value 38425bb815Sopenharmony_ci* Returned value must be freed with ecma_free_value 39425bb815Sopenharmony_ci*/ 40425bb815Sopenharmony_ciecma_value_t 41425bb815Sopenharmony_ciopfunc_equality (ecma_value_t left_value, /**< left value */ 42425bb815Sopenharmony_ci ecma_value_t right_value) /**< right value */ 43425bb815Sopenharmony_ci{ 44425bb815Sopenharmony_ci JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (left_value) 45425bb815Sopenharmony_ci && !ECMA_IS_VALUE_ERROR (right_value)); 46425bb815Sopenharmony_ci 47425bb815Sopenharmony_ci ecma_value_t compare_result = ecma_op_abstract_equality_compare (left_value, right_value); 48425bb815Sopenharmony_ci 49425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_value_boolean (compare_result) 50425bb815Sopenharmony_ci || ECMA_IS_VALUE_ERROR (compare_result)); 51425bb815Sopenharmony_ci 52425bb815Sopenharmony_ci return compare_result; 53425bb815Sopenharmony_ci} /* opfunc_equality */ 54425bb815Sopenharmony_ci 55425bb815Sopenharmony_ci/** 56425bb815Sopenharmony_ci * Relation opcode handler. 57425bb815Sopenharmony_ci * 58425bb815Sopenharmony_ci * See also: ECMA-262 v5, 11.8.1, 11.8.2, 11.8.3, 11.8.4 59425bb815Sopenharmony_ci * 60425bb815Sopenharmony_ci * @return ecma value 61425bb815Sopenharmony_ci * Returned value must be freed with ecma_free_value 62425bb815Sopenharmony_ci */ 63425bb815Sopenharmony_ciecma_value_t 64425bb815Sopenharmony_ciopfunc_relation (ecma_value_t left_value, /**< left value */ 65425bb815Sopenharmony_ci ecma_value_t right_value, /**< right value */ 66425bb815Sopenharmony_ci bool left_first, /**< 'LeftFirst' flag */ 67425bb815Sopenharmony_ci bool is_invert) /**< is invert */ 68425bb815Sopenharmony_ci{ 69425bb815Sopenharmony_ci JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (left_value) 70425bb815Sopenharmony_ci && !ECMA_IS_VALUE_ERROR (right_value)); 71425bb815Sopenharmony_ci 72425bb815Sopenharmony_ci ecma_value_t ret_value = ecma_op_abstract_relational_compare (left_value, right_value, left_first); 73425bb815Sopenharmony_ci 74425bb815Sopenharmony_ci if (ECMA_IS_VALUE_ERROR (ret_value)) 75425bb815Sopenharmony_ci { 76425bb815Sopenharmony_ci return ret_value; 77425bb815Sopenharmony_ci } 78425bb815Sopenharmony_ci 79425bb815Sopenharmony_ci if (ecma_is_value_undefined (ret_value)) 80425bb815Sopenharmony_ci { 81425bb815Sopenharmony_ci ret_value = ECMA_VALUE_FALSE; 82425bb815Sopenharmony_ci } 83425bb815Sopenharmony_ci else 84425bb815Sopenharmony_ci { 85425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_value_boolean (ret_value)); 86425bb815Sopenharmony_ci 87425bb815Sopenharmony_ci if (is_invert) 88425bb815Sopenharmony_ci { 89425bb815Sopenharmony_ci ret_value = ecma_invert_boolean_value (ret_value); 90425bb815Sopenharmony_ci } 91425bb815Sopenharmony_ci } 92425bb815Sopenharmony_ci 93425bb815Sopenharmony_ci return ret_value; 94425bb815Sopenharmony_ci} /* opfunc_relation */ 95425bb815Sopenharmony_ci 96425bb815Sopenharmony_ci/** 97425bb815Sopenharmony_ci * 'instanceof' opcode handler. 98425bb815Sopenharmony_ci * 99425bb815Sopenharmony_ci * See also: ECMA-262 v5, 11.8.6 100425bb815Sopenharmony_ci * 101425bb815Sopenharmony_ci * @return ecma value 102425bb815Sopenharmony_ci * returned value must be freed with ecma_free_value. 103425bb815Sopenharmony_ci */ 104425bb815Sopenharmony_ciecma_value_t 105425bb815Sopenharmony_ciopfunc_instanceof (ecma_value_t left_value, /**< left value */ 106425bb815Sopenharmony_ci ecma_value_t right_value) /**< right value */ 107425bb815Sopenharmony_ci{ 108425bb815Sopenharmony_ci if (!ecma_is_value_object (right_value)) 109425bb815Sopenharmony_ci { 110425bb815Sopenharmony_ci return ecma_raise_type_error (ECMA_ERR_MSG ("Expected an object in 'instanceof' check.")); 111425bb815Sopenharmony_ci } 112425bb815Sopenharmony_ci 113425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 114425bb815Sopenharmony_ci ecma_value_t has_instance_method = ecma_op_get_method_by_symbol_id (right_value, LIT_GLOBAL_SYMBOL_HAS_INSTANCE); 115425bb815Sopenharmony_ci if (ECMA_IS_VALUE_ERROR (has_instance_method)) 116425bb815Sopenharmony_ci { 117425bb815Sopenharmony_ci return has_instance_method; 118425bb815Sopenharmony_ci } 119425bb815Sopenharmony_ci 120425bb815Sopenharmony_ci if (JERRY_UNLIKELY (!ecma_is_value_undefined (has_instance_method))) 121425bb815Sopenharmony_ci { 122425bb815Sopenharmony_ci ecma_object_t *method_obj_p = ecma_get_object_from_value (has_instance_method); 123425bb815Sopenharmony_ci ecma_value_t has_instance_result = ecma_op_function_call (method_obj_p, right_value, &left_value, 1); 124425bb815Sopenharmony_ci 125425bb815Sopenharmony_ci ecma_free_value (has_instance_method); 126425bb815Sopenharmony_ci 127425bb815Sopenharmony_ci if (ECMA_IS_VALUE_ERROR (has_instance_result)) 128425bb815Sopenharmony_ci { 129425bb815Sopenharmony_ci return has_instance_result; 130425bb815Sopenharmony_ci } 131425bb815Sopenharmony_ci 132425bb815Sopenharmony_ci bool has_instance = ecma_op_to_boolean (has_instance_result); 133425bb815Sopenharmony_ci ecma_free_value (has_instance_result); 134425bb815Sopenharmony_ci 135425bb815Sopenharmony_ci return ecma_make_boolean_value (has_instance); 136425bb815Sopenharmony_ci } 137425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 138425bb815Sopenharmony_ci 139425bb815Sopenharmony_ci ecma_object_t *right_value_obj_p = ecma_get_object_from_value (right_value); 140425bb815Sopenharmony_ci return ecma_op_object_has_instance (right_value_obj_p, left_value); 141425bb815Sopenharmony_ci} /* opfunc_instanceof */ 142425bb815Sopenharmony_ci 143425bb815Sopenharmony_ci/** 144425bb815Sopenharmony_ci * 'in' opcode handler. 145425bb815Sopenharmony_ci * 146425bb815Sopenharmony_ci * See also: 147425bb815Sopenharmony_ci * * ECMA-262 v5, 11.8.7 148425bb815Sopenharmony_ci * * ECAM-262 v6, 12.9.3 149425bb815Sopenharmony_ci * 150425bb815Sopenharmony_ci * @return ecma value 151425bb815Sopenharmony_ci * returned value must be freed with ecma_free_value. 152425bb815Sopenharmony_ci */ 153425bb815Sopenharmony_ciecma_value_t 154425bb815Sopenharmony_ciopfunc_in (ecma_value_t left_value, /**< left value */ 155425bb815Sopenharmony_ci ecma_value_t right_value) /**< right value */ 156425bb815Sopenharmony_ci{ 157425bb815Sopenharmony_ci if (!ecma_is_value_object (right_value)) 158425bb815Sopenharmony_ci { 159425bb815Sopenharmony_ci return ecma_raise_type_error (ECMA_ERR_MSG ("Expected an object in 'in' check.")); 160425bb815Sopenharmony_ci } 161425bb815Sopenharmony_ci 162425bb815Sopenharmony_ci ecma_string_t *property_name_p = ecma_op_to_prop_name (left_value); 163425bb815Sopenharmony_ci 164425bb815Sopenharmony_ci if (JERRY_UNLIKELY (property_name_p == NULL)) 165425bb815Sopenharmony_ci { 166425bb815Sopenharmony_ci return ECMA_VALUE_ERROR; 167425bb815Sopenharmony_ci } 168425bb815Sopenharmony_ci 169425bb815Sopenharmony_ci ecma_object_t *right_value_obj_p = ecma_get_object_from_value (right_value); 170425bb815Sopenharmony_ci ecma_value_t result = ecma_op_object_has_property (right_value_obj_p, property_name_p); 171425bb815Sopenharmony_ci ecma_deref_ecma_string (property_name_p); 172425bb815Sopenharmony_ci return result; 173425bb815Sopenharmony_ci} /* opfunc_in */ 174425bb815Sopenharmony_ci 175425bb815Sopenharmony_ci/** 176425bb815Sopenharmony_ci * @} 177425bb815Sopenharmony_ci * @} 178425bb815Sopenharmony_ci */ 179