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 20namespace panda::ecmascript { 21JSTaggedValue 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 206JSTaggedValue 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 214ComparisonResult 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 425JSTaggedValue 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 434JSTaggedValue 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 443JSTaggedValue 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 452JSTaggedValue 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