1/* Copyright JS Foundation and other contributors, http://js.foundation 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "ecma-comparison.h" 17#include "ecma-conversion.h" 18#include "ecma-exceptions.h" 19#include "ecma-function-object.h" 20#include "ecma-helpers.h" 21#include "ecma-objects.h" 22#include "ecma-try-catch-macro.h" 23#include "opcodes.h" 24 25/** \addtogroup vm Virtual machine 26 * @{ 27 * 28 * \addtogroup vm_opcodes Opcodes 29 * @{ 30 */ 31 32/** 33* Equality opcode handler. 34* 35* See also: ECMA-262 v5, 11.9.1, 11.9.2 36* 37* @return ecma value 38* Returned value must be freed with ecma_free_value 39*/ 40ecma_value_t 41opfunc_equality (ecma_value_t left_value, /**< left value */ 42 ecma_value_t right_value) /**< right value */ 43{ 44 JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (left_value) 45 && !ECMA_IS_VALUE_ERROR (right_value)); 46 47 ecma_value_t compare_result = ecma_op_abstract_equality_compare (left_value, right_value); 48 49 JERRY_ASSERT (ecma_is_value_boolean (compare_result) 50 || ECMA_IS_VALUE_ERROR (compare_result)); 51 52 return compare_result; 53} /* opfunc_equality */ 54 55/** 56 * Relation opcode handler. 57 * 58 * See also: ECMA-262 v5, 11.8.1, 11.8.2, 11.8.3, 11.8.4 59 * 60 * @return ecma value 61 * Returned value must be freed with ecma_free_value 62 */ 63ecma_value_t 64opfunc_relation (ecma_value_t left_value, /**< left value */ 65 ecma_value_t right_value, /**< right value */ 66 bool left_first, /**< 'LeftFirst' flag */ 67 bool is_invert) /**< is invert */ 68{ 69 JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (left_value) 70 && !ECMA_IS_VALUE_ERROR (right_value)); 71 72 ecma_value_t ret_value = ecma_op_abstract_relational_compare (left_value, right_value, left_first); 73 74 if (ECMA_IS_VALUE_ERROR (ret_value)) 75 { 76 return ret_value; 77 } 78 79 if (ecma_is_value_undefined (ret_value)) 80 { 81 ret_value = ECMA_VALUE_FALSE; 82 } 83 else 84 { 85 JERRY_ASSERT (ecma_is_value_boolean (ret_value)); 86 87 if (is_invert) 88 { 89 ret_value = ecma_invert_boolean_value (ret_value); 90 } 91 } 92 93 return ret_value; 94} /* opfunc_relation */ 95 96/** 97 * 'instanceof' opcode handler. 98 * 99 * See also: ECMA-262 v5, 11.8.6 100 * 101 * @return ecma value 102 * returned value must be freed with ecma_free_value. 103 */ 104ecma_value_t 105opfunc_instanceof (ecma_value_t left_value, /**< left value */ 106 ecma_value_t right_value) /**< right value */ 107{ 108 if (!ecma_is_value_object (right_value)) 109 { 110 return ecma_raise_type_error (ECMA_ERR_MSG ("Expected an object in 'instanceof' check.")); 111 } 112 113#if ENABLED (JERRY_ES2015) 114 ecma_value_t has_instance_method = ecma_op_get_method_by_symbol_id (right_value, LIT_GLOBAL_SYMBOL_HAS_INSTANCE); 115 if (ECMA_IS_VALUE_ERROR (has_instance_method)) 116 { 117 return has_instance_method; 118 } 119 120 if (JERRY_UNLIKELY (!ecma_is_value_undefined (has_instance_method))) 121 { 122 ecma_object_t *method_obj_p = ecma_get_object_from_value (has_instance_method); 123 ecma_value_t has_instance_result = ecma_op_function_call (method_obj_p, right_value, &left_value, 1); 124 125 ecma_free_value (has_instance_method); 126 127 if (ECMA_IS_VALUE_ERROR (has_instance_result)) 128 { 129 return has_instance_result; 130 } 131 132 bool has_instance = ecma_op_to_boolean (has_instance_result); 133 ecma_free_value (has_instance_result); 134 135 return ecma_make_boolean_value (has_instance); 136 } 137#endif /* ENABLED (JERRY_ES2015) */ 138 139 ecma_object_t *right_value_obj_p = ecma_get_object_from_value (right_value); 140 return ecma_op_object_has_instance (right_value_obj_p, left_value); 141} /* opfunc_instanceof */ 142 143/** 144 * 'in' opcode handler. 145 * 146 * See also: 147 * * ECMA-262 v5, 11.8.7 148 * * ECAM-262 v6, 12.9.3 149 * 150 * @return ecma value 151 * returned value must be freed with ecma_free_value. 152 */ 153ecma_value_t 154opfunc_in (ecma_value_t left_value, /**< left value */ 155 ecma_value_t right_value) /**< right value */ 156{ 157 if (!ecma_is_value_object (right_value)) 158 { 159 return ecma_raise_type_error (ECMA_ERR_MSG ("Expected an object in 'in' check.")); 160 } 161 162 ecma_string_t *property_name_p = ecma_op_to_prop_name (left_value); 163 164 if (JERRY_UNLIKELY (property_name_p == NULL)) 165 { 166 return ECMA_VALUE_ERROR; 167 } 168 169 ecma_object_t *right_value_obj_p = ecma_get_object_from_value (right_value); 170 ecma_value_t result = ecma_op_object_has_property (right_value_obj_p, property_name_p); 171 ecma_deref_ecma_string (property_name_p); 172 return result; 173} /* opfunc_in */ 174 175/** 176 * @} 177 * @} 178 */ 179