1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
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 "ecmascript/ic/ic_compare_op.h"
17
18 #include "ecmascript/accessor_data.h"
19 #include "ecmascript/base/error_helper.h"
20 #include "ecmascript/base/number_helper.h"
21 #include "ecmascript/base/string_helper.h"
22 #include "ecmascript/ecma_runtime_call_info.h"
23 #include "ecmascript/ecma_string-inl.h"
24 #include "ecmascript/mem/c_containers.h"
25 #include "ecmascript/mem/tagged_object-inl.h"
26 #include "ecmascript/runtime_call_id.h"
27
28 namespace panda::ecmascript {
EqualWithIC(JSThread * thread,JSTaggedValue left,JSTaggedValue right,CompareOpType operationType)29 JSTaggedValue CompareOp::EqualWithIC(JSThread* thread, JSTaggedValue left,
30 JSTaggedValue right, CompareOpType operationType)
31 {
32 INTERPRETER_TRACE(thread, EqualWithIC);
33 double leftDouble = 0;
34 double rightDouble = 0;
35 JSTaggedValue ret = JSTaggedValue::False();
36 switch (operationType) {
37 case CompareOpType::NUMBER_NUMBER: {
38 leftDouble = left.GetNumber();
39 rightDouble = right.GetNumber();
40 ret = JSTaggedValue(JSTaggedValue::StrictNumberEquals(leftDouble, rightDouble));
41 break;
42 }
43 case CompareOpType::STRING_NUMBER: {
44 JSTaggedValue temp = left;
45 left = right;
46 right = temp;
47 [[fallthrough]];
48 }
49 case CompareOpType::NUMBER_STRING: {
50 JSHandle<JSTaggedValue> leftHandle(thread, left);
51 JSHandle<JSTaggedValue> rightHandle(thread, right);
52 rightDouble = JSTaggedValue::ToNumber(thread, rightHandle).GetNumber();
53 RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::False());
54 leftDouble = leftHandle.GetTaggedValue().GetNumber();
55 ret = JSTaggedValue(JSTaggedValue::StrictNumberEquals(leftDouble, rightDouble));
56 break;
57 }
58 case CompareOpType::BOOLEAN_NUMBER: {
59 JSTaggedValue temp = left;
60 left = right;
61 right = temp;
62 [[fallthrough]];
63 }
64 case CompareOpType::NUMBER_BOOLEAN: {
65 leftDouble = left.GetNumber();
66 if (right.GetRawData() == JSTaggedValue::VALUE_TRUE) {
67 rightDouble = 1;
68 }
69 ret = JSTaggedValue(JSTaggedValue::StrictNumberEquals(leftDouble, rightDouble));
70 break;
71 }
72 case CompareOpType::OBJ_NUMBER: {
73 JSTaggedValue temp = left;
74 left = right;
75 right = temp;
76 [[fallthrough]];
77 }
78 case CompareOpType::NUMBER_OBJ: {
79 JSHandle<JSTaggedValue> leftHandle(thread, left);
80 JSHandle<JSTaggedValue> rightHandle(thread, right);
81 JSHandle<JSTaggedValue> rightPrimitive(thread, JSTaggedValue::ToPrimitive(thread, rightHandle));
82 RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::False());
83 if (rightPrimitive->IsNumber()) {
84 ret = EqualWithIC(thread, leftHandle.GetTaggedValue(),
85 rightPrimitive.GetTaggedValue(), CompareOpType::NUMBER_NUMBER);
86 } else if (rightPrimitive->IsString()) {
87 ret = EqualWithIC(thread, leftHandle.GetTaggedValue(),
88 rightPrimitive.GetTaggedValue(), CompareOpType::NUMBER_STRING);
89 } else if (rightPrimitive->IsBoolean()) {
90 ret = EqualWithIC(thread, leftHandle.GetTaggedValue(),
91 rightPrimitive.GetTaggedValue(), CompareOpType::NUMBER_BOOLEAN);
92 }
93 break;
94 }
95 case CompareOpType::STRING_STRING: {
96 bool result = EcmaStringAccessor::StringsAreEqual(static_cast<EcmaString *>(left.GetTaggedObject()),
97 static_cast<EcmaString *>(right.GetTaggedObject()));
98 ret = result ? JSTaggedValue::True() : JSTaggedValue::False();
99 break;
100 }
101 case CompareOpType::BOOLEAN_STRING: {
102 JSTaggedValue temp = left;
103 left = right;
104 right = temp;
105 [[fallthrough]];
106 }
107 case CompareOpType::STRING_BOOLEAN: {
108 JSHandle<JSTaggedValue> leftHandle(thread, left);
109 JSHandle<JSTaggedValue> rightHandle(thread, right);
110 leftDouble = JSTaggedValue::ToNumber(thread, leftHandle).GetNumber();
111 RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::False());
112 if (rightHandle.GetTaggedValue().GetRawData() == JSTaggedValue::VALUE_TRUE) {
113 rightDouble = 1;
114 }
115 ret = JSTaggedValue(JSTaggedValue::StrictNumberEquals(leftDouble, rightDouble));
116 break;
117 }
118 case CompareOpType::OBJ_STRING: {
119 JSTaggedValue temp = left;
120 left = right;
121 right = temp;
122 [[fallthrough]];
123 }
124 case CompareOpType::STRING_OBJ: {
125 JSHandle<JSTaggedValue> leftHandle(thread, left);
126 JSHandle<JSTaggedValue> rightHandle(thread, right);
127 JSHandle<JSTaggedValue> rightPrimitive(thread, JSTaggedValue::ToPrimitive(thread, rightHandle));
128 RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::False());
129 if (rightPrimitive->IsNumber()) {
130 ret = EqualWithIC(thread, leftHandle.GetTaggedValue(),
131 rightPrimitive.GetTaggedValue(), CompareOpType::NUMBER_STRING);
132 } else if (rightPrimitive->IsString()) {
133 ret = EqualWithIC(thread, leftHandle.GetTaggedValue(),
134 rightPrimitive.GetTaggedValue(), CompareOpType::STRING_STRING);
135 } else if (rightPrimitive->IsBoolean()) {
136 ret = EqualWithIC(thread, leftHandle.GetTaggedValue(),
137 rightPrimitive.GetTaggedValue(), CompareOpType::STRING_BOOLEAN);
138 }
139 break;
140 }
141 case CompareOpType::BOOLEAN_BOOLEAN: {
142 if (left.GetRawData() == JSTaggedValue::VALUE_TRUE) {
143 leftDouble = 1;
144 }
145 if (right.GetRawData() == JSTaggedValue::VALUE_TRUE) {
146 rightDouble = 1;
147 }
148 ret = JSTaggedValue(JSTaggedValue::StrictNumberEquals(leftDouble, rightDouble));
149 break;
150 }
151 case CompareOpType::OBJ_BOOLEAN: {
152 JSHandle<JSTaggedValue> leftHandle(thread, left);
153 JSHandle<JSTaggedValue> rightHandle(thread, right);
154 JSHandle<JSTaggedValue> leftPrimitive(thread, JSTaggedValue::ToPrimitive(thread, leftHandle));
155 RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::False());
156 if (leftPrimitive->IsNumber()) {
157 ret = EqualWithIC(thread, leftPrimitive.GetTaggedValue(),
158 rightHandle.GetTaggedValue(), CompareOpType::NUMBER_BOOLEAN);
159 } else if (leftPrimitive->IsString()) {
160 ret = EqualWithIC(thread, leftPrimitive.GetTaggedValue(),
161 rightHandle.GetTaggedValue(), CompareOpType::STRING_BOOLEAN);
162 } else if (leftPrimitive->IsBoolean()) {
163 ret = EqualWithIC(thread, leftPrimitive.GetTaggedValue(),
164 rightHandle.GetTaggedValue(), CompareOpType::BOOLEAN_BOOLEAN);
165 }
166 break;
167 }
168 case CompareOpType::BOOLEAN_OBJ: {
169 JSHandle<JSTaggedValue> leftHandle(thread, left);
170 JSHandle<JSTaggedValue> rightHandle(thread, right);
171 JSHandle<JSTaggedValue> rightPrimitive(thread, JSTaggedValue::ToPrimitive(thread, rightHandle));
172 RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::False());
173 if (rightPrimitive->IsNumber()) {
174 ret = EqualWithIC(thread, rightPrimitive.GetTaggedValue(),
175 leftHandle.GetTaggedValue(), CompareOpType::NUMBER_BOOLEAN);
176 } else if (rightPrimitive->IsString()) {
177 ret = EqualWithIC(thread, rightPrimitive.GetTaggedValue(),
178 leftHandle.GetTaggedValue(), CompareOpType::STRING_BOOLEAN);
179 } else if (rightPrimitive->IsBoolean()) {
180 ret = EqualWithIC(thread, rightPrimitive.GetTaggedValue(),
181 leftHandle.GetTaggedValue(), CompareOpType::BOOLEAN_BOOLEAN);
182 }
183 break;
184 }
185 case CompareOpType::OBJ_OBJ: {
186 // if same type, must call Type::StrictEqual()
187 JSType xType = left.GetTaggedObject()->GetClass()->GetObjectType();
188 JSType yType = right.GetTaggedObject()->GetClass()->GetObjectType();
189 bool resultObj = false;
190 if (xType == yType) {
191 resultObj = JSTaggedValue::StrictEqual(thread, JSHandle<JSTaggedValue>(thread, left),
192 JSHandle<JSTaggedValue>(thread, right));
193 }
194 ret = resultObj ? JSTaggedValue::True() : JSTaggedValue::False();
195 break;
196 }
197 case CompareOpType::SYMBOL_SYMBOL: {
198 ret = left == right ? JSTaggedValue::True() : JSTaggedValue::False();
199 break;
200 }
201 case CompareOpType::NULL_NULL:
202 case CompareOpType::NULL_UNDEFINED:
203 case CompareOpType::UNDEFINED_UNDEFINED:
204 case CompareOpType::UNDEFINED_NULL: {
205 ret = JSTaggedValue::True();
206 break;
207 }
208 default:
209 ret = JSTaggedValue::False();
210 }
211 return ret;
212 }
213
NotEqualWithIC(JSThread * thread,JSTaggedValue left,JSTaggedValue right,CompareOpType operationType)214 JSTaggedValue CompareOp::NotEqualWithIC(JSThread *thread, JSTaggedValue left,
215 JSTaggedValue right, CompareOpType operationType)
216 {
217 INTERPRETER_TRACE(thread, NotEqualWithIC);
218 JSTaggedValue res = EqualWithIC(thread, left, right, operationType);
219 return res == JSTaggedValue::True() ? JSTaggedValue::False() : JSTaggedValue::True();
220 }
221
Compare(JSThread * thread,JSTaggedValue left,JSTaggedValue right,CompareOpType operationType)222 ComparisonResult CompareOp::Compare(JSThread *thread, JSTaggedValue left,
223 JSTaggedValue right, CompareOpType operationType)
224 {
225 INTERPRETER_TRACE(thread, Compare);
226 double leftDouble = 0;
227 double rightDouble = 0;
228 ComparisonResult ret = ComparisonResult::UNDEFINED;
229 switch (operationType) {
230 case CompareOpType::NUMBER_NUMBER: {
231 leftDouble = left.IsInt() ? static_cast<double>(left.GetInt()) : left.GetDouble();
232 rightDouble = right.IsInt() ? static_cast<double>(right.GetInt()) : right.GetDouble();
233 ret = JSTaggedValue::StrictNumberCompare(leftDouble, rightDouble);
234 break;
235 }
236 case CompareOpType::NUMBER_STRING: {
237 JSHandle<JSTaggedValue> leftHandle(thread, left);
238 JSHandle<JSTaggedValue> rightHandle(thread, right);
239
240 rightDouble = JSTaggedValue::ToNumber(thread, rightHandle).GetNumber();
241 RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, ComparisonResult::UNDEFINED);
242 leftDouble = leftHandle.GetTaggedValue().GetNumber();
243 ret = JSTaggedValue::StrictNumberCompare(leftDouble, rightDouble);
244 break;
245 }
246 case CompareOpType::NUMBER_BOOLEAN: {
247 leftDouble = left.GetNumber();
248 if (right.GetRawData() == JSTaggedValue::VALUE_TRUE) {
249 rightDouble = 1;
250 }
251 ret = JSTaggedValue::StrictNumberCompare(leftDouble, rightDouble);
252 break;
253 }
254 case CompareOpType::NUMBER_OBJ: {
255 JSHandle<JSTaggedValue> leftHandle(thread, left);
256 JSHandle<JSTaggedValue> rightHandle(thread, right);
257 JSHandle<JSTaggedValue> rightPrimitive(thread, JSTaggedValue::ToPrimitive(thread, rightHandle));
258 RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, ComparisonResult::UNDEFINED);
259 if (rightPrimitive->IsNumber()) {
260 ret = Compare(thread, leftHandle.GetTaggedValue(),
261 rightPrimitive.GetTaggedValue(), CompareOpType::NUMBER_NUMBER);
262 } else if (rightPrimitive->IsString()) {
263 ret = Compare(thread, leftHandle.GetTaggedValue(),
264 rightPrimitive.GetTaggedValue(), CompareOpType::NUMBER_STRING);
265 } else if (rightPrimitive->IsBoolean()) {
266 ret = Compare(thread, leftHandle.GetTaggedValue(),
267 rightPrimitive.GetTaggedValue(), CompareOpType::NUMBER_BOOLEAN);
268 }
269 break;
270 }
271 case CompareOpType::STRING_STRING: {
272 auto xString = static_cast<EcmaString *>(left.GetTaggedObject());
273 auto yString = static_cast<EcmaString *>(right.GetTaggedObject());
274 int result = EcmaStringAccessor::Compare(xString, yString);
275 if (result < 0) {
276 ret = ComparisonResult::LESS;
277 } else if (result == 0) {
278 ret = ComparisonResult::EQUAL;
279 } else {
280 ret = ComparisonResult::GREAT;
281 }
282 break;
283 }
284 case CompareOpType::STRING_NUMBER: {
285 JSHandle<JSTaggedValue> leftHandle(thread, left);
286 JSHandle<JSTaggedValue> rightHandle(thread, right);
287 leftDouble = JSTaggedValue::ToNumber(thread, leftHandle).GetNumber();
288 RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, ComparisonResult::UNDEFINED);
289 rightDouble = rightHandle.GetTaggedValue().GetNumber();
290 ret = JSTaggedValue::StrictNumberCompare(leftDouble, rightDouble);
291 break;
292 }
293 case CompareOpType::STRING_BOOLEAN: {
294 JSHandle<JSTaggedValue> leftHandle(thread, left);
295 JSHandle<JSTaggedValue> rightHandle(thread, right);
296 leftDouble = JSTaggedValue::ToNumber(thread, leftHandle).GetNumber();
297 RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, ComparisonResult::UNDEFINED);
298 if (rightHandle.GetTaggedValue().GetRawData() == JSTaggedValue::VALUE_TRUE) {
299 rightDouble = 1;
300 }
301 ret = JSTaggedValue::StrictNumberCompare(leftDouble, rightDouble);
302 break;
303 }
304 case CompareOpType::STRING_OBJ: {
305 JSHandle<JSTaggedValue> leftHandle(thread, left);
306 JSHandle<JSTaggedValue> rightHandle(thread, right);
307 JSHandle<JSTaggedValue> rightPrimitive(thread, JSTaggedValue::ToPrimitive(thread, rightHandle));
308 RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, ComparisonResult::UNDEFINED);
309 if (rightPrimitive->IsNumber()) {
310 ret = Compare(thread, leftHandle.GetTaggedValue(),
311 rightPrimitive.GetTaggedValue(), CompareOpType::NUMBER_STRING);
312 } else if (rightPrimitive->IsString()) {
313 ret = Compare(thread, leftHandle.GetTaggedValue(),
314 rightPrimitive.GetTaggedValue(), CompareOpType::STRING_STRING);
315 } else if (rightPrimitive->IsBoolean()) {
316 ret = Compare(thread, leftHandle.GetTaggedValue(),
317 rightPrimitive.GetTaggedValue(), CompareOpType::STRING_BOOLEAN);
318 }
319 break;
320 }
321 case CompareOpType::BOOLEAN_BOOLEAN: {
322 if (left.GetRawData() == JSTaggedValue::VALUE_TRUE) {
323 leftDouble = 1;
324 }
325 if (right.GetRawData() == JSTaggedValue::VALUE_TRUE) {
326 rightDouble = 1;
327 }
328 ret = JSTaggedValue::StrictNumberCompare(leftDouble, rightDouble);
329 break;
330 }
331
332 case CompareOpType::BOOLEAN_NUMBER: {
333 if (left.GetRawData() == JSTaggedValue::VALUE_TRUE) {
334 leftDouble = 1;
335 }
336 rightDouble = right.GetNumber();
337 ret = JSTaggedValue::StrictNumberCompare(leftDouble, rightDouble);
338 break;
339 }
340
341 case CompareOpType::BOOLEAN_STRING: {
342 JSHandle<JSTaggedValue> leftHandle(thread, left);
343 JSHandle<JSTaggedValue> rightHandle(thread, right);
344 rightDouble = JSTaggedValue::ToNumber(thread, rightHandle).GetNumber();
345 RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, ComparisonResult::UNDEFINED);
346 if (leftHandle.GetTaggedValue().GetRawData() == JSTaggedValue::VALUE_TRUE) {
347 leftDouble = 1;
348 }
349 ret = JSTaggedValue::StrictNumberCompare(leftDouble, rightDouble);
350 break;
351 }
352
353 case CompareOpType::BOOLEAN_OBJ: {
354 JSHandle<JSTaggedValue> leftHandle(thread, left);
355 JSHandle<JSTaggedValue> rightHandle(thread, right);
356 JSHandle<JSTaggedValue> rightPrimitive(thread, JSTaggedValue::ToPrimitive(thread, rightHandle));
357 RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, ComparisonResult::UNDEFINED);
358 if (rightPrimitive->IsNumber()) {
359 ret = Compare(thread, rightPrimitive.GetTaggedValue(),
360 leftHandle.GetTaggedValue(), CompareOpType::NUMBER_BOOLEAN);
361 } else if (rightPrimitive->IsString()) {
362 ret = Compare(thread, rightPrimitive.GetTaggedValue(),
363 leftHandle.GetTaggedValue(), CompareOpType::STRING_BOOLEAN);
364 } else if (rightPrimitive->IsBoolean()) {
365 ret = Compare(thread, rightPrimitive.GetTaggedValue(),
366 leftHandle.GetTaggedValue(), CompareOpType::BOOLEAN_BOOLEAN);
367 }
368 break;
369 }
370 case CompareOpType::OBJ_OBJ: {
371 JSHandle<JSTaggedValue> leftHandle(thread, left);
372 JSHandle<JSTaggedValue> rightHandle(thread, right);
373 ret = JSTaggedValue::Compare(thread, leftHandle, rightHandle);
374 break;
375 }
376 case CompareOpType::OBJ_NUMBER: {
377 JSHandle<JSTaggedValue> leftHandle(thread, left);
378 JSHandle<JSTaggedValue> rightHandle(thread, right);
379 JSHandle<JSTaggedValue> leftPrimitive(thread, JSTaggedValue::ToPrimitive(thread, leftHandle));
380 RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, ComparisonResult::UNDEFINED);
381 if (leftPrimitive->IsNumber()) {
382 ret = Compare(thread, leftPrimitive.GetTaggedValue(),
383 rightHandle.GetTaggedValue(), CompareOpType::NUMBER_NUMBER);
384 } else if (leftPrimitive->IsString()) {
385 ret = Compare(thread, leftPrimitive.GetTaggedValue(),
386 rightHandle.GetTaggedValue(), CompareOpType::STRING_NUMBER);
387 } else if (leftPrimitive->IsBoolean()) {
388 ret = Compare(thread, leftPrimitive.GetTaggedValue(),
389 rightHandle.GetTaggedValue(), CompareOpType::BOOLEAN_NUMBER);
390 }
391 break;
392 }
393 case CompareOpType::OBJ_STRING: {
394 JSHandle<JSTaggedValue> leftHandle(thread, left);
395 JSHandle<JSTaggedValue> rightHandle(thread, right);
396 JSHandle<JSTaggedValue> leftPrimitive(thread, JSTaggedValue::ToPrimitive(thread, leftHandle));
397 RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, ComparisonResult::UNDEFINED);
398 if (leftPrimitive->IsNumber()) {
399 ret = Compare(thread, leftPrimitive.GetTaggedValue(),
400 rightHandle.GetTaggedValue(), CompareOpType::NUMBER_STRING);
401 } else if (leftPrimitive->IsString()) {
402 ret = Compare(thread, leftPrimitive.GetTaggedValue(),
403 rightHandle.GetTaggedValue(), CompareOpType::STRING_STRING);
404 } else if (leftPrimitive->IsBoolean()) {
405 ret = Compare(thread, leftPrimitive.GetTaggedValue(),
406 rightHandle.GetTaggedValue(), CompareOpType::BOOLEAN_STRING);
407 }
408 break;
409 }
410 case CompareOpType::OBJ_BOOLEAN: {
411 JSHandle<JSTaggedValue> leftHandle(thread, left);
412 JSHandle<JSTaggedValue> rightHandle(thread, right);
413 JSHandle<JSTaggedValue> leftPrimitive(thread, JSTaggedValue::ToPrimitive(thread, leftHandle));
414 RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, ComparisonResult::UNDEFINED);
415 if (leftPrimitive->IsNumber()) {
416 ret = Compare(thread, leftPrimitive.GetTaggedValue(),
417 rightHandle.GetTaggedValue(), CompareOpType::NUMBER_BOOLEAN);
418 } else if (leftPrimitive->IsString()) {
419 ret = Compare(thread, leftPrimitive.GetTaggedValue(),
420 rightHandle.GetTaggedValue(), CompareOpType::STRING_BOOLEAN);
421 } else if (leftPrimitive->IsBoolean()) {
422 ret = Compare(thread, leftPrimitive.GetTaggedValue(),
423 rightHandle.GetTaggedValue(), CompareOpType::BOOLEAN_BOOLEAN);
424 }
425 break;
426 }
427 default:
428 ret = ComparisonResult::UNDEFINED;
429 }
430 return ret;
431 }
432
LessWithIC(JSThread * thread,JSTaggedValue left,JSTaggedValue right,CompareOpType operationType)433 JSTaggedValue CompareOp::LessWithIC(JSThread *thread, JSTaggedValue left,
434 JSTaggedValue right, CompareOpType operationType)
435 {
436 INTERPRETER_TRACE(thread, LessWithIC);
437 bool ret = CompareOp::Compare(thread, left, right, operationType) == ComparisonResult::LESS;
438 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
439 return (ret ? JSTaggedValue::True() : JSTaggedValue::False());
440 }
441
LessEqWithIC(JSThread * thread,JSTaggedValue left,JSTaggedValue right,CompareOpType operationType)442 JSTaggedValue CompareOp::LessEqWithIC(JSThread *thread, JSTaggedValue left,
443 JSTaggedValue right, CompareOpType operationType)
444 {
445 INTERPRETER_TRACE(thread, LessEqWithIC);
446 bool ret = CompareOp::Compare(thread, left, right, operationType) <= ComparisonResult::EQUAL;
447 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
448 return (ret ? JSTaggedValue::True() : JSTaggedValue::False());
449 }
450
GreaterWithIC(JSThread * thread,JSTaggedValue left,JSTaggedValue right,CompareOpType operationType)451 JSTaggedValue CompareOp::GreaterWithIC(JSThread *thread, JSTaggedValue left,
452 JSTaggedValue right, CompareOpType operationType)
453 {
454 INTERPRETER_TRACE(thread, GreaterWithIC);
455 bool ret = CompareOp::Compare(thread, left, right, operationType) == ComparisonResult::GREAT;
456 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
457 return (ret ? JSTaggedValue::True() : JSTaggedValue::False());
458 }
459
GreaterEqWithIC(JSThread * thread,JSTaggedValue left,JSTaggedValue right,CompareOpType operationType)460 JSTaggedValue CompareOp::GreaterEqWithIC(JSThread *thread, JSTaggedValue left,
461 JSTaggedValue right, CompareOpType operationType)
462 {
463 INTERPRETER_TRACE(thread, GreaterEqWithIC);
464 ComparisonResult comparison = CompareOp::Compare(thread, left, right, operationType);
465 bool ret = (comparison == ComparisonResult::GREAT) || (comparison == ComparisonResult::EQUAL);
466 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
467 return (ret ? JSTaggedValue::True() : JSTaggedValue::False());
468 }
469 } // namespace panda::ecmascript
470