14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License.
54514f5e3Sopenharmony_ci * You may obtain a copy of the License at
64514f5e3Sopenharmony_ci *
74514f5e3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84514f5e3Sopenharmony_ci *
94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and
134514f5e3Sopenharmony_ci * limitations under the License.
144514f5e3Sopenharmony_ci */
154514f5e3Sopenharmony_ci
164514f5e3Sopenharmony_ci#include "ecmascript/ic/ic_compare_op.h"
174514f5e3Sopenharmony_ci
184514f5e3Sopenharmony_ci#include "ecmascript/runtime_call_id.h"
194514f5e3Sopenharmony_ci
204514f5e3Sopenharmony_cinamespace panda::ecmascript {
214514f5e3Sopenharmony_ciJSTaggedValue CompareOp::EqualWithIC(JSThread* thread, JSTaggedValue left,
224514f5e3Sopenharmony_ci    JSTaggedValue right, CompareOpType operationType)
234514f5e3Sopenharmony_ci{
244514f5e3Sopenharmony_ci    INTERPRETER_TRACE(thread, EqualWithIC);
254514f5e3Sopenharmony_ci    double leftDouble = 0;
264514f5e3Sopenharmony_ci    double rightDouble = 0;
274514f5e3Sopenharmony_ci    JSTaggedValue ret = JSTaggedValue::False();
284514f5e3Sopenharmony_ci    switch (operationType) {
294514f5e3Sopenharmony_ci        case CompareOpType::NUMBER_NUMBER: {
304514f5e3Sopenharmony_ci            leftDouble = left.GetNumber();
314514f5e3Sopenharmony_ci            rightDouble = right.GetNumber();
324514f5e3Sopenharmony_ci            ret = JSTaggedValue(JSTaggedValue::StrictNumberEquals(leftDouble, rightDouble));
334514f5e3Sopenharmony_ci            break;
344514f5e3Sopenharmony_ci        }
354514f5e3Sopenharmony_ci        case CompareOpType::STRING_NUMBER: {
364514f5e3Sopenharmony_ci            JSTaggedValue temp = left;
374514f5e3Sopenharmony_ci            left = right;
384514f5e3Sopenharmony_ci            right = temp;
394514f5e3Sopenharmony_ci            [[fallthrough]];
404514f5e3Sopenharmony_ci        }
414514f5e3Sopenharmony_ci        case CompareOpType::NUMBER_STRING: {
424514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> leftHandle(thread, left);
434514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> rightHandle(thread, right);
444514f5e3Sopenharmony_ci            rightDouble = JSTaggedValue::ToNumber(thread, rightHandle).GetNumber();
454514f5e3Sopenharmony_ci            RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::False());
464514f5e3Sopenharmony_ci            leftDouble = leftHandle.GetTaggedValue().GetNumber();
474514f5e3Sopenharmony_ci            ret = JSTaggedValue(JSTaggedValue::StrictNumberEquals(leftDouble, rightDouble));
484514f5e3Sopenharmony_ci            break;
494514f5e3Sopenharmony_ci        }
504514f5e3Sopenharmony_ci        case CompareOpType::BOOLEAN_NUMBER: {
514514f5e3Sopenharmony_ci            JSTaggedValue temp = left;
524514f5e3Sopenharmony_ci            left = right;
534514f5e3Sopenharmony_ci            right = temp;
544514f5e3Sopenharmony_ci            [[fallthrough]];
554514f5e3Sopenharmony_ci        }
564514f5e3Sopenharmony_ci        case CompareOpType::NUMBER_BOOLEAN: {
574514f5e3Sopenharmony_ci            leftDouble = left.GetNumber();
584514f5e3Sopenharmony_ci            if (right.GetRawData() == JSTaggedValue::VALUE_TRUE) {
594514f5e3Sopenharmony_ci                rightDouble = 1;
604514f5e3Sopenharmony_ci            }
614514f5e3Sopenharmony_ci            ret = JSTaggedValue(JSTaggedValue::StrictNumberEquals(leftDouble, rightDouble));
624514f5e3Sopenharmony_ci            break;
634514f5e3Sopenharmony_ci        }
644514f5e3Sopenharmony_ci        case CompareOpType::OBJ_NUMBER: {
654514f5e3Sopenharmony_ci            JSTaggedValue temp = left;
664514f5e3Sopenharmony_ci            left = right;
674514f5e3Sopenharmony_ci            right = temp;
684514f5e3Sopenharmony_ci            [[fallthrough]];
694514f5e3Sopenharmony_ci        }
704514f5e3Sopenharmony_ci        case CompareOpType::NUMBER_OBJ: {
714514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> leftHandle(thread, left);
724514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> rightHandle(thread, right);
734514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> rightPrimitive(thread, JSTaggedValue::ToPrimitive(thread, rightHandle));
744514f5e3Sopenharmony_ci            RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::False());
754514f5e3Sopenharmony_ci            if (rightPrimitive->IsNumber()) {
764514f5e3Sopenharmony_ci                ret = EqualWithIC(thread, leftHandle.GetTaggedValue(),
774514f5e3Sopenharmony_ci                                  rightPrimitive.GetTaggedValue(), CompareOpType::NUMBER_NUMBER);
784514f5e3Sopenharmony_ci            } else if (rightPrimitive->IsString()) {
794514f5e3Sopenharmony_ci                ret = EqualWithIC(thread, leftHandle.GetTaggedValue(),
804514f5e3Sopenharmony_ci                                  rightPrimitive.GetTaggedValue(), CompareOpType::NUMBER_STRING);
814514f5e3Sopenharmony_ci            } else if (rightPrimitive->IsBoolean()) {
824514f5e3Sopenharmony_ci                ret = EqualWithIC(thread, leftHandle.GetTaggedValue(),
834514f5e3Sopenharmony_ci                                  rightPrimitive.GetTaggedValue(), CompareOpType::NUMBER_BOOLEAN);
844514f5e3Sopenharmony_ci            }
854514f5e3Sopenharmony_ci            break;
864514f5e3Sopenharmony_ci        }
874514f5e3Sopenharmony_ci        case CompareOpType::STRING_STRING: {
884514f5e3Sopenharmony_ci            bool result = EcmaStringAccessor::StringsAreEqual(static_cast<EcmaString *>(left.GetTaggedObject()),
894514f5e3Sopenharmony_ci                static_cast<EcmaString *>(right.GetTaggedObject()));
904514f5e3Sopenharmony_ci            ret = result ? JSTaggedValue::True() : JSTaggedValue::False();
914514f5e3Sopenharmony_ci            break;
924514f5e3Sopenharmony_ci        }
934514f5e3Sopenharmony_ci        case CompareOpType::BOOLEAN_STRING: {
944514f5e3Sopenharmony_ci            JSTaggedValue temp = left;
954514f5e3Sopenharmony_ci            left = right;
964514f5e3Sopenharmony_ci            right = temp;
974514f5e3Sopenharmony_ci            [[fallthrough]];
984514f5e3Sopenharmony_ci        }
994514f5e3Sopenharmony_ci        case CompareOpType::STRING_BOOLEAN: {
1004514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> leftHandle(thread, left);
1014514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> rightHandle(thread, right);
1024514f5e3Sopenharmony_ci            leftDouble = JSTaggedValue::ToNumber(thread, leftHandle).GetNumber();
1034514f5e3Sopenharmony_ci            RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::False());
1044514f5e3Sopenharmony_ci            if (rightHandle.GetTaggedValue().GetRawData() == JSTaggedValue::VALUE_TRUE) {
1054514f5e3Sopenharmony_ci                rightDouble = 1;
1064514f5e3Sopenharmony_ci            }
1074514f5e3Sopenharmony_ci            ret = JSTaggedValue(JSTaggedValue::StrictNumberEquals(leftDouble, rightDouble));
1084514f5e3Sopenharmony_ci            break;
1094514f5e3Sopenharmony_ci        }
1104514f5e3Sopenharmony_ci        case CompareOpType::OBJ_STRING: {
1114514f5e3Sopenharmony_ci            JSTaggedValue temp = left;
1124514f5e3Sopenharmony_ci            left = right;
1134514f5e3Sopenharmony_ci            right = temp;
1144514f5e3Sopenharmony_ci            [[fallthrough]];
1154514f5e3Sopenharmony_ci        }
1164514f5e3Sopenharmony_ci        case CompareOpType::STRING_OBJ: {
1174514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> leftHandle(thread, left);
1184514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> rightHandle(thread, right);
1194514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> rightPrimitive(thread, JSTaggedValue::ToPrimitive(thread, rightHandle));
1204514f5e3Sopenharmony_ci            RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::False());
1214514f5e3Sopenharmony_ci            if (rightPrimitive->IsNumber()) {
1224514f5e3Sopenharmony_ci                ret = EqualWithIC(thread, leftHandle.GetTaggedValue(),
1234514f5e3Sopenharmony_ci                                  rightPrimitive.GetTaggedValue(), CompareOpType::NUMBER_STRING);
1244514f5e3Sopenharmony_ci            } else if (rightPrimitive->IsString()) {
1254514f5e3Sopenharmony_ci                ret = EqualWithIC(thread, leftHandle.GetTaggedValue(),
1264514f5e3Sopenharmony_ci                                  rightPrimitive.GetTaggedValue(), CompareOpType::STRING_STRING);
1274514f5e3Sopenharmony_ci            } else if (rightPrimitive->IsBoolean()) {
1284514f5e3Sopenharmony_ci                ret = EqualWithIC(thread, leftHandle.GetTaggedValue(),
1294514f5e3Sopenharmony_ci                                  rightPrimitive.GetTaggedValue(), CompareOpType::STRING_BOOLEAN);
1304514f5e3Sopenharmony_ci            }
1314514f5e3Sopenharmony_ci            break;
1324514f5e3Sopenharmony_ci        }
1334514f5e3Sopenharmony_ci        case CompareOpType::BOOLEAN_BOOLEAN: {
1344514f5e3Sopenharmony_ci            if (left.GetRawData() == JSTaggedValue::VALUE_TRUE) {
1354514f5e3Sopenharmony_ci                leftDouble = 1;
1364514f5e3Sopenharmony_ci            }
1374514f5e3Sopenharmony_ci            if (right.GetRawData() == JSTaggedValue::VALUE_TRUE) {
1384514f5e3Sopenharmony_ci                rightDouble = 1;
1394514f5e3Sopenharmony_ci            }
1404514f5e3Sopenharmony_ci            ret = JSTaggedValue(JSTaggedValue::StrictNumberEquals(leftDouble, rightDouble));
1414514f5e3Sopenharmony_ci            break;
1424514f5e3Sopenharmony_ci        }
1434514f5e3Sopenharmony_ci        case CompareOpType::OBJ_BOOLEAN: {
1444514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> leftHandle(thread, left);
1454514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> rightHandle(thread, right);
1464514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> leftPrimitive(thread, JSTaggedValue::ToPrimitive(thread, leftHandle));
1474514f5e3Sopenharmony_ci            RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::False());
1484514f5e3Sopenharmony_ci            if (leftPrimitive->IsNumber()) {
1494514f5e3Sopenharmony_ci                ret = EqualWithIC(thread, leftPrimitive.GetTaggedValue(),
1504514f5e3Sopenharmony_ci                                  rightHandle.GetTaggedValue(), CompareOpType::NUMBER_BOOLEAN);
1514514f5e3Sopenharmony_ci            } else if (leftPrimitive->IsString()) {
1524514f5e3Sopenharmony_ci                ret = EqualWithIC(thread, leftPrimitive.GetTaggedValue(),
1534514f5e3Sopenharmony_ci                                  rightHandle.GetTaggedValue(), CompareOpType::STRING_BOOLEAN);
1544514f5e3Sopenharmony_ci            } else if (leftPrimitive->IsBoolean()) {
1554514f5e3Sopenharmony_ci                ret = EqualWithIC(thread, leftPrimitive.GetTaggedValue(),
1564514f5e3Sopenharmony_ci                                  rightHandle.GetTaggedValue(), CompareOpType::BOOLEAN_BOOLEAN);
1574514f5e3Sopenharmony_ci            }
1584514f5e3Sopenharmony_ci            break;
1594514f5e3Sopenharmony_ci        }
1604514f5e3Sopenharmony_ci        case CompareOpType::BOOLEAN_OBJ: {
1614514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> leftHandle(thread, left);
1624514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> rightHandle(thread, right);
1634514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> rightPrimitive(thread, JSTaggedValue::ToPrimitive(thread, rightHandle));
1644514f5e3Sopenharmony_ci            RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::False());
1654514f5e3Sopenharmony_ci            if (rightPrimitive->IsNumber()) {
1664514f5e3Sopenharmony_ci                ret = EqualWithIC(thread, rightPrimitive.GetTaggedValue(),
1674514f5e3Sopenharmony_ci                                  leftHandle.GetTaggedValue(), CompareOpType::NUMBER_BOOLEAN);
1684514f5e3Sopenharmony_ci            } else if (rightPrimitive->IsString()) {
1694514f5e3Sopenharmony_ci                ret = EqualWithIC(thread, rightPrimitive.GetTaggedValue(),
1704514f5e3Sopenharmony_ci                                  leftHandle.GetTaggedValue(), CompareOpType::STRING_BOOLEAN);
1714514f5e3Sopenharmony_ci            } else if (rightPrimitive->IsBoolean()) {
1724514f5e3Sopenharmony_ci                ret = EqualWithIC(thread, rightPrimitive.GetTaggedValue(),
1734514f5e3Sopenharmony_ci                                  leftHandle.GetTaggedValue(), CompareOpType::BOOLEAN_BOOLEAN);
1744514f5e3Sopenharmony_ci            }
1754514f5e3Sopenharmony_ci            break;
1764514f5e3Sopenharmony_ci        }
1774514f5e3Sopenharmony_ci        case CompareOpType::OBJ_OBJ: {
1784514f5e3Sopenharmony_ci            // if same type, must call Type::StrictEqual()
1794514f5e3Sopenharmony_ci            JSType xType = left.GetTaggedObject()->GetClass()->GetObjectType();
1804514f5e3Sopenharmony_ci            JSType yType = right.GetTaggedObject()->GetClass()->GetObjectType();
1814514f5e3Sopenharmony_ci            bool resultObj = false;
1824514f5e3Sopenharmony_ci            if (xType == yType) {
1834514f5e3Sopenharmony_ci                resultObj = JSTaggedValue::StrictEqual(thread, JSHandle<JSTaggedValue>(thread, left),
1844514f5e3Sopenharmony_ci                    JSHandle<JSTaggedValue>(thread, right));
1854514f5e3Sopenharmony_ci            }
1864514f5e3Sopenharmony_ci            ret = resultObj ? JSTaggedValue::True() : JSTaggedValue::False();
1874514f5e3Sopenharmony_ci            break;
1884514f5e3Sopenharmony_ci        }
1894514f5e3Sopenharmony_ci        case CompareOpType::SYMBOL_SYMBOL: {
1904514f5e3Sopenharmony_ci            ret = left == right ? JSTaggedValue::True() : JSTaggedValue::False();
1914514f5e3Sopenharmony_ci            break;
1924514f5e3Sopenharmony_ci        }
1934514f5e3Sopenharmony_ci        case CompareOpType::NULL_NULL:
1944514f5e3Sopenharmony_ci        case CompareOpType::NULL_UNDEFINED:
1954514f5e3Sopenharmony_ci        case CompareOpType::UNDEFINED_UNDEFINED:
1964514f5e3Sopenharmony_ci        case CompareOpType::UNDEFINED_NULL: {
1974514f5e3Sopenharmony_ci            ret = JSTaggedValue::True();
1984514f5e3Sopenharmony_ci            break;
1994514f5e3Sopenharmony_ci        }
2004514f5e3Sopenharmony_ci        default:
2014514f5e3Sopenharmony_ci            ret = JSTaggedValue::False();
2024514f5e3Sopenharmony_ci    }
2034514f5e3Sopenharmony_ci    return ret;
2044514f5e3Sopenharmony_ci}
2054514f5e3Sopenharmony_ci
2064514f5e3Sopenharmony_ciJSTaggedValue CompareOp::NotEqualWithIC(JSThread *thread, JSTaggedValue left,
2074514f5e3Sopenharmony_ci    JSTaggedValue right, CompareOpType operationType)
2084514f5e3Sopenharmony_ci{
2094514f5e3Sopenharmony_ci    INTERPRETER_TRACE(thread, NotEqualWithIC);
2104514f5e3Sopenharmony_ci    JSTaggedValue res = EqualWithIC(thread, left, right, operationType);
2114514f5e3Sopenharmony_ci    return res.IsTrue() ? JSTaggedValue::False() : JSTaggedValue::True();
2124514f5e3Sopenharmony_ci}
2134514f5e3Sopenharmony_ci
2144514f5e3Sopenharmony_ciComparisonResult CompareOp::Compare(JSThread *thread, JSTaggedValue left,
2154514f5e3Sopenharmony_ci    JSTaggedValue right, CompareOpType operationType)
2164514f5e3Sopenharmony_ci{
2174514f5e3Sopenharmony_ci    INTERPRETER_TRACE(thread, Compare);
2184514f5e3Sopenharmony_ci    double leftDouble = 0;
2194514f5e3Sopenharmony_ci    double rightDouble = 0;
2204514f5e3Sopenharmony_ci    ComparisonResult ret = ComparisonResult::UNDEFINED;
2214514f5e3Sopenharmony_ci    switch (operationType) {
2224514f5e3Sopenharmony_ci        case CompareOpType::NUMBER_NUMBER: {
2234514f5e3Sopenharmony_ci            leftDouble = left.IsInt() ? static_cast<double>(left.GetInt()) : left.GetDouble();
2244514f5e3Sopenharmony_ci            rightDouble = right.IsInt() ? static_cast<double>(right.GetInt()) : right.GetDouble();
2254514f5e3Sopenharmony_ci            ret = JSTaggedValue::StrictNumberCompare(leftDouble, rightDouble);
2264514f5e3Sopenharmony_ci            break;
2274514f5e3Sopenharmony_ci        }
2284514f5e3Sopenharmony_ci        case CompareOpType::NUMBER_STRING: {
2294514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> leftHandle(thread, left);
2304514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> rightHandle(thread, right);
2314514f5e3Sopenharmony_ci
2324514f5e3Sopenharmony_ci            rightDouble = JSTaggedValue::ToNumber(thread, rightHandle).GetNumber();
2334514f5e3Sopenharmony_ci            RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, ComparisonResult::UNDEFINED);
2344514f5e3Sopenharmony_ci            leftDouble = leftHandle.GetTaggedValue().GetNumber();
2354514f5e3Sopenharmony_ci            ret = JSTaggedValue::StrictNumberCompare(leftDouble, rightDouble);
2364514f5e3Sopenharmony_ci            break;
2374514f5e3Sopenharmony_ci        }
2384514f5e3Sopenharmony_ci        case CompareOpType::NUMBER_BOOLEAN: {
2394514f5e3Sopenharmony_ci            leftDouble = left.GetNumber();
2404514f5e3Sopenharmony_ci            if (right.GetRawData() == JSTaggedValue::VALUE_TRUE) {
2414514f5e3Sopenharmony_ci                rightDouble = 1;
2424514f5e3Sopenharmony_ci            }
2434514f5e3Sopenharmony_ci            ret = JSTaggedValue::StrictNumberCompare(leftDouble, rightDouble);
2444514f5e3Sopenharmony_ci            break;
2454514f5e3Sopenharmony_ci        }
2464514f5e3Sopenharmony_ci        case CompareOpType::NUMBER_OBJ: {
2474514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> leftHandle(thread, left);
2484514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> rightHandle(thread, right);
2494514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> rightPrimitive(thread, JSTaggedValue::ToPrimitive(thread, rightHandle));
2504514f5e3Sopenharmony_ci            RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, ComparisonResult::UNDEFINED);
2514514f5e3Sopenharmony_ci            if (rightPrimitive->IsNumber()) {
2524514f5e3Sopenharmony_ci                ret = Compare(thread, leftHandle.GetTaggedValue(),
2534514f5e3Sopenharmony_ci                              rightPrimitive.GetTaggedValue(), CompareOpType::NUMBER_NUMBER);
2544514f5e3Sopenharmony_ci            } else if (rightPrimitive->IsString()) {
2554514f5e3Sopenharmony_ci                ret = Compare(thread, leftHandle.GetTaggedValue(),
2564514f5e3Sopenharmony_ci                              rightPrimitive.GetTaggedValue(), CompareOpType::NUMBER_STRING);
2574514f5e3Sopenharmony_ci            } else if (rightPrimitive->IsBoolean()) {
2584514f5e3Sopenharmony_ci                ret = Compare(thread, leftHandle.GetTaggedValue(),
2594514f5e3Sopenharmony_ci                              rightPrimitive.GetTaggedValue(), CompareOpType::NUMBER_BOOLEAN);
2604514f5e3Sopenharmony_ci            }
2614514f5e3Sopenharmony_ci            break;
2624514f5e3Sopenharmony_ci        }
2634514f5e3Sopenharmony_ci        case CompareOpType::STRING_STRING: {
2644514f5e3Sopenharmony_ci            JSHandle<EcmaString> xHandle(thread, left);
2654514f5e3Sopenharmony_ci            JSHandle<EcmaString> yHandle(thread, right);
2664514f5e3Sopenharmony_ci            int result = EcmaStringAccessor::Compare(thread->GetEcmaVM(), xHandle, yHandle);
2674514f5e3Sopenharmony_ci            if (result < 0) {
2684514f5e3Sopenharmony_ci                ret = ComparisonResult::LESS;
2694514f5e3Sopenharmony_ci            } else if (result == 0) {
2704514f5e3Sopenharmony_ci                ret = ComparisonResult::EQUAL;
2714514f5e3Sopenharmony_ci            } else {
2724514f5e3Sopenharmony_ci                ret = ComparisonResult::GREAT;
2734514f5e3Sopenharmony_ci            }
2744514f5e3Sopenharmony_ci            break;
2754514f5e3Sopenharmony_ci        }
2764514f5e3Sopenharmony_ci        case CompareOpType::STRING_NUMBER: {
2774514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> leftHandle(thread, left);
2784514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> rightHandle(thread, right);
2794514f5e3Sopenharmony_ci            leftDouble = JSTaggedValue::ToNumber(thread, leftHandle).GetNumber();
2804514f5e3Sopenharmony_ci            RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, ComparisonResult::UNDEFINED);
2814514f5e3Sopenharmony_ci            rightDouble = rightHandle.GetTaggedValue().GetNumber();
2824514f5e3Sopenharmony_ci            ret = JSTaggedValue::StrictNumberCompare(leftDouble, rightDouble);
2834514f5e3Sopenharmony_ci            break;
2844514f5e3Sopenharmony_ci        }
2854514f5e3Sopenharmony_ci        case CompareOpType::STRING_BOOLEAN: {
2864514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> leftHandle(thread, left);
2874514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> rightHandle(thread, right);
2884514f5e3Sopenharmony_ci            leftDouble = JSTaggedValue::ToNumber(thread, leftHandle).GetNumber();
2894514f5e3Sopenharmony_ci            RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, ComparisonResult::UNDEFINED);
2904514f5e3Sopenharmony_ci            if (rightHandle.GetTaggedValue().GetRawData() == JSTaggedValue::VALUE_TRUE) {
2914514f5e3Sopenharmony_ci                rightDouble = 1;
2924514f5e3Sopenharmony_ci            }
2934514f5e3Sopenharmony_ci            ret = JSTaggedValue::StrictNumberCompare(leftDouble, rightDouble);
2944514f5e3Sopenharmony_ci            break;
2954514f5e3Sopenharmony_ci        }
2964514f5e3Sopenharmony_ci        case CompareOpType::STRING_OBJ: {
2974514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> leftHandle(thread, left);
2984514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> rightHandle(thread, right);
2994514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> rightPrimitive(thread, JSTaggedValue::ToPrimitive(thread, rightHandle));
3004514f5e3Sopenharmony_ci            RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, ComparisonResult::UNDEFINED);
3014514f5e3Sopenharmony_ci            if (rightPrimitive->IsNumber()) {
3024514f5e3Sopenharmony_ci                ret = Compare(thread, leftHandle.GetTaggedValue(),
3034514f5e3Sopenharmony_ci                              rightPrimitive.GetTaggedValue(), CompareOpType::NUMBER_STRING);
3044514f5e3Sopenharmony_ci            } else if (rightPrimitive->IsString()) {
3054514f5e3Sopenharmony_ci                ret = Compare(thread, leftHandle.GetTaggedValue(),
3064514f5e3Sopenharmony_ci                              rightPrimitive.GetTaggedValue(), CompareOpType::STRING_STRING);
3074514f5e3Sopenharmony_ci            } else if (rightPrimitive->IsBoolean()) {
3084514f5e3Sopenharmony_ci                ret = Compare(thread, leftHandle.GetTaggedValue(),
3094514f5e3Sopenharmony_ci                              rightPrimitive.GetTaggedValue(), CompareOpType::STRING_BOOLEAN);
3104514f5e3Sopenharmony_ci            }
3114514f5e3Sopenharmony_ci            break;
3124514f5e3Sopenharmony_ci        }
3134514f5e3Sopenharmony_ci        case CompareOpType::BOOLEAN_BOOLEAN: {
3144514f5e3Sopenharmony_ci            if (left.GetRawData() == JSTaggedValue::VALUE_TRUE) {
3154514f5e3Sopenharmony_ci                leftDouble = 1;
3164514f5e3Sopenharmony_ci            }
3174514f5e3Sopenharmony_ci            if (right.GetRawData() == JSTaggedValue::VALUE_TRUE) {
3184514f5e3Sopenharmony_ci                rightDouble = 1;
3194514f5e3Sopenharmony_ci            }
3204514f5e3Sopenharmony_ci            ret = JSTaggedValue::StrictNumberCompare(leftDouble, rightDouble);
3214514f5e3Sopenharmony_ci            break;
3224514f5e3Sopenharmony_ci        }
3234514f5e3Sopenharmony_ci
3244514f5e3Sopenharmony_ci        case CompareOpType::BOOLEAN_NUMBER: {
3254514f5e3Sopenharmony_ci            if (left.GetRawData() == JSTaggedValue::VALUE_TRUE) {
3264514f5e3Sopenharmony_ci                leftDouble = 1;
3274514f5e3Sopenharmony_ci            }
3284514f5e3Sopenharmony_ci            rightDouble = right.GetNumber();
3294514f5e3Sopenharmony_ci            ret = JSTaggedValue::StrictNumberCompare(leftDouble, rightDouble);
3304514f5e3Sopenharmony_ci            break;
3314514f5e3Sopenharmony_ci        }
3324514f5e3Sopenharmony_ci
3334514f5e3Sopenharmony_ci        case CompareOpType::BOOLEAN_STRING: {
3344514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> leftHandle(thread, left);
3354514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> rightHandle(thread, right);
3364514f5e3Sopenharmony_ci            rightDouble = JSTaggedValue::ToNumber(thread, rightHandle).GetNumber();
3374514f5e3Sopenharmony_ci            RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, ComparisonResult::UNDEFINED);
3384514f5e3Sopenharmony_ci            if (leftHandle.GetTaggedValue().GetRawData() == JSTaggedValue::VALUE_TRUE) {
3394514f5e3Sopenharmony_ci                leftDouble = 1;
3404514f5e3Sopenharmony_ci            }
3414514f5e3Sopenharmony_ci            ret = JSTaggedValue::StrictNumberCompare(leftDouble, rightDouble);
3424514f5e3Sopenharmony_ci            break;
3434514f5e3Sopenharmony_ci        }
3444514f5e3Sopenharmony_ci
3454514f5e3Sopenharmony_ci        case CompareOpType::BOOLEAN_OBJ: {
3464514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> leftHandle(thread, left);
3474514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> rightHandle(thread, right);
3484514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> rightPrimitive(thread, JSTaggedValue::ToPrimitive(thread, rightHandle));
3494514f5e3Sopenharmony_ci            RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, ComparisonResult::UNDEFINED);
3504514f5e3Sopenharmony_ci            if (rightPrimitive->IsNumber()) {
3514514f5e3Sopenharmony_ci                ret = Compare(thread, rightPrimitive.GetTaggedValue(),
3524514f5e3Sopenharmony_ci                              leftHandle.GetTaggedValue(), CompareOpType::NUMBER_BOOLEAN);
3534514f5e3Sopenharmony_ci            } else if (rightPrimitive->IsString()) {
3544514f5e3Sopenharmony_ci                ret = Compare(thread, rightPrimitive.GetTaggedValue(),
3554514f5e3Sopenharmony_ci                              leftHandle.GetTaggedValue(), CompareOpType::STRING_BOOLEAN);
3564514f5e3Sopenharmony_ci            } else if (rightPrimitive->IsBoolean()) {
3574514f5e3Sopenharmony_ci                ret = Compare(thread, rightPrimitive.GetTaggedValue(),
3584514f5e3Sopenharmony_ci                              leftHandle.GetTaggedValue(), CompareOpType::BOOLEAN_BOOLEAN);
3594514f5e3Sopenharmony_ci            }
3604514f5e3Sopenharmony_ci            break;
3614514f5e3Sopenharmony_ci        }
3624514f5e3Sopenharmony_ci        case CompareOpType::OBJ_OBJ: {
3634514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> leftHandle(thread, left);
3644514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> rightHandle(thread, right);
3654514f5e3Sopenharmony_ci            ret = JSTaggedValue::Compare(thread, leftHandle, rightHandle);
3664514f5e3Sopenharmony_ci            break;
3674514f5e3Sopenharmony_ci        }
3684514f5e3Sopenharmony_ci        case CompareOpType::OBJ_NUMBER: {
3694514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> leftHandle(thread, left);
3704514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> rightHandle(thread, right);
3714514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> leftPrimitive(thread, JSTaggedValue::ToPrimitive(thread, leftHandle));
3724514f5e3Sopenharmony_ci            RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, ComparisonResult::UNDEFINED);
3734514f5e3Sopenharmony_ci            if (leftPrimitive->IsNumber()) {
3744514f5e3Sopenharmony_ci                ret = Compare(thread, leftPrimitive.GetTaggedValue(),
3754514f5e3Sopenharmony_ci                              rightHandle.GetTaggedValue(), CompareOpType::NUMBER_NUMBER);
3764514f5e3Sopenharmony_ci            } else if (leftPrimitive->IsString()) {
3774514f5e3Sopenharmony_ci                ret = Compare(thread, leftPrimitive.GetTaggedValue(),
3784514f5e3Sopenharmony_ci                              rightHandle.GetTaggedValue(), CompareOpType::STRING_NUMBER);
3794514f5e3Sopenharmony_ci            } else if (leftPrimitive->IsBoolean()) {
3804514f5e3Sopenharmony_ci                ret = Compare(thread, leftPrimitive.GetTaggedValue(),
3814514f5e3Sopenharmony_ci                              rightHandle.GetTaggedValue(), CompareOpType::BOOLEAN_NUMBER);
3824514f5e3Sopenharmony_ci            }
3834514f5e3Sopenharmony_ci            break;
3844514f5e3Sopenharmony_ci        }
3854514f5e3Sopenharmony_ci        case CompareOpType::OBJ_STRING: {
3864514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> leftHandle(thread, left);
3874514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> rightHandle(thread, right);
3884514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> leftPrimitive(thread, JSTaggedValue::ToPrimitive(thread, leftHandle));
3894514f5e3Sopenharmony_ci            RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, ComparisonResult::UNDEFINED);
3904514f5e3Sopenharmony_ci            if (leftPrimitive->IsNumber()) {
3914514f5e3Sopenharmony_ci                ret = Compare(thread, leftPrimitive.GetTaggedValue(),
3924514f5e3Sopenharmony_ci                              rightHandle.GetTaggedValue(), CompareOpType::NUMBER_STRING);
3934514f5e3Sopenharmony_ci            } else if (leftPrimitive->IsString()) {
3944514f5e3Sopenharmony_ci                ret = Compare(thread, leftPrimitive.GetTaggedValue(),
3954514f5e3Sopenharmony_ci                              rightHandle.GetTaggedValue(), CompareOpType::STRING_STRING);
3964514f5e3Sopenharmony_ci            } else if (leftPrimitive->IsBoolean()) {
3974514f5e3Sopenharmony_ci                ret = Compare(thread, leftPrimitive.GetTaggedValue(),
3984514f5e3Sopenharmony_ci                              rightHandle.GetTaggedValue(), CompareOpType::BOOLEAN_STRING);
3994514f5e3Sopenharmony_ci            }
4004514f5e3Sopenharmony_ci            break;
4014514f5e3Sopenharmony_ci        }
4024514f5e3Sopenharmony_ci        case CompareOpType::OBJ_BOOLEAN: {
4034514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> leftHandle(thread, left);
4044514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> rightHandle(thread, right);
4054514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> leftPrimitive(thread, JSTaggedValue::ToPrimitive(thread, leftHandle));
4064514f5e3Sopenharmony_ci            RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, ComparisonResult::UNDEFINED);
4074514f5e3Sopenharmony_ci            if (leftPrimitive->IsNumber()) {
4084514f5e3Sopenharmony_ci                ret = Compare(thread, leftPrimitive.GetTaggedValue(),
4094514f5e3Sopenharmony_ci                              rightHandle.GetTaggedValue(), CompareOpType::NUMBER_BOOLEAN);
4104514f5e3Sopenharmony_ci            } else if (leftPrimitive->IsString()) {
4114514f5e3Sopenharmony_ci                ret = Compare(thread, leftPrimitive.GetTaggedValue(),
4124514f5e3Sopenharmony_ci                              rightHandle.GetTaggedValue(), CompareOpType::STRING_BOOLEAN);
4134514f5e3Sopenharmony_ci            } else if (leftPrimitive->IsBoolean()) {
4144514f5e3Sopenharmony_ci                ret = Compare(thread, leftPrimitive.GetTaggedValue(),
4154514f5e3Sopenharmony_ci                              rightHandle.GetTaggedValue(), CompareOpType::BOOLEAN_BOOLEAN);
4164514f5e3Sopenharmony_ci            }
4174514f5e3Sopenharmony_ci            break;
4184514f5e3Sopenharmony_ci        }
4194514f5e3Sopenharmony_ci        default:
4204514f5e3Sopenharmony_ci            ret = ComparisonResult::UNDEFINED;
4214514f5e3Sopenharmony_ci    }
4224514f5e3Sopenharmony_ci    return ret;
4234514f5e3Sopenharmony_ci}
4244514f5e3Sopenharmony_ci
4254514f5e3Sopenharmony_ciJSTaggedValue CompareOp::LessWithIC(JSThread *thread, JSTaggedValue left,
4264514f5e3Sopenharmony_ci    JSTaggedValue right, CompareOpType operationType)
4274514f5e3Sopenharmony_ci{
4284514f5e3Sopenharmony_ci    INTERPRETER_TRACE(thread, LessWithIC);
4294514f5e3Sopenharmony_ci    bool ret = CompareOp::Compare(thread, left, right, operationType) == ComparisonResult::LESS;
4304514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
4314514f5e3Sopenharmony_ci    return (ret ? JSTaggedValue::True() : JSTaggedValue::False());
4324514f5e3Sopenharmony_ci}
4334514f5e3Sopenharmony_ci
4344514f5e3Sopenharmony_ciJSTaggedValue CompareOp::LessEqWithIC(JSThread *thread, JSTaggedValue left,
4354514f5e3Sopenharmony_ci    JSTaggedValue right, CompareOpType operationType)
4364514f5e3Sopenharmony_ci{
4374514f5e3Sopenharmony_ci    INTERPRETER_TRACE(thread, LessEqWithIC);
4384514f5e3Sopenharmony_ci    bool ret = CompareOp::Compare(thread, left, right, operationType) <= ComparisonResult::EQUAL;
4394514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
4404514f5e3Sopenharmony_ci    return (ret ? JSTaggedValue::True() : JSTaggedValue::False());
4414514f5e3Sopenharmony_ci}
4424514f5e3Sopenharmony_ci
4434514f5e3Sopenharmony_ciJSTaggedValue CompareOp::GreaterWithIC(JSThread *thread, JSTaggedValue left,
4444514f5e3Sopenharmony_ci    JSTaggedValue right, CompareOpType operationType)
4454514f5e3Sopenharmony_ci{
4464514f5e3Sopenharmony_ci    INTERPRETER_TRACE(thread, GreaterWithIC);
4474514f5e3Sopenharmony_ci    bool ret = CompareOp::Compare(thread, left, right, operationType) == ComparisonResult::GREAT;
4484514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
4494514f5e3Sopenharmony_ci    return (ret ? JSTaggedValue::True() : JSTaggedValue::False());
4504514f5e3Sopenharmony_ci}
4514514f5e3Sopenharmony_ci
4524514f5e3Sopenharmony_ciJSTaggedValue CompareOp::GreaterEqWithIC(JSThread *thread, JSTaggedValue left,
4534514f5e3Sopenharmony_ci    JSTaggedValue right, CompareOpType operationType)
4544514f5e3Sopenharmony_ci{
4554514f5e3Sopenharmony_ci    INTERPRETER_TRACE(thread, GreaterEqWithIC);
4564514f5e3Sopenharmony_ci    ComparisonResult comparison = CompareOp::Compare(thread, left, right, operationType);
4574514f5e3Sopenharmony_ci    bool ret = (comparison == ComparisonResult::GREAT) || (comparison == ComparisonResult::EQUAL);
4584514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
4594514f5e3Sopenharmony_ci    return (ret ? JSTaggedValue::True() : JSTaggedValue::False());
4604514f5e3Sopenharmony_ci}
4614514f5e3Sopenharmony_ci}   // namespace panda::ecmascript
462