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