• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
40 ecma_value_t
opfunc_equality(ecma_value_t left_value,ecma_value_t right_value)41 opfunc_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  */
63 ecma_value_t
opfunc_relation(ecma_value_t left_value,ecma_value_t right_value,bool left_first,bool is_invert)64 opfunc_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  */
104 ecma_value_t
opfunc_instanceof(ecma_value_t left_value,ecma_value_t right_value)105 opfunc_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  */
153 ecma_value_t
opfunc_in(ecma_value_t left_value,ecma_value_t right_value)154 opfunc_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