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