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 #ifndef ECMASCRIPT_BASE_JSON_PARSE_INL_H 17 #define ECMASCRIPT_BASE_JSON_PARSE_INL_H 18 19 #include "ecmascript/base/json_parser.h" 20 #include "ecmascript/base/builtins_base.h" 21 #include "ecmascript/base/number_helper.h" 22 #include "ecmascript/base/string_helper.h" 23 #include "ecmascript/base/utf_helper.h" 24 #include "ecmascript/ecma_string-inl.h" 25 #include "ecmascript/ecma_string.h" 26 #include "ecmascript/internal_call_params.h" 27 #include "ecmascript/interpreter/fast_runtime_stub-inl.h" 28 #include "ecmascript/js_array.h" 29 #include "ecmascript/js_function.h" 30 #include "ecmascript/js_handle.h" 31 #include "ecmascript/js_tagged_value.h" 32 #include "ecmascript/object_factory.h" 33 34 namespace panda::ecmascript::base { 35 constexpr unsigned int UNICODE_DIGIT_LENGTH = 4; 36 constexpr unsigned int NUMBER_TEN = 10; 37 constexpr unsigned int NUMBER_SIXTEEN = 16; 38 39 constexpr unsigned char CODE_SPACE = 0x20; 40 constexpr unsigned char ASCII_END = 0X7F; 41 enum class Tokens : uint8_t { 42 // six structural tokens 43 OBJECT = 0, 44 ARRAY, 45 NUMBER, 46 STRING, 47 LITERAL_TRUE, 48 LITERAL_FALSE, 49 LITERAL_NULL, 50 TOKEN_ILLEGAL, 51 }; 52 53 template<typename T> 54 class JsonParser { 55 public: 56 using Text = const T *; 57 explicit JsonParser() = default; JsonParser(JSThread * thread)58 explicit JsonParser(JSThread *thread) : thread_(thread) {} 59 ~JsonParser() = default; 60 NO_COPY_SEMANTIC(JsonParser); 61 NO_MOVE_SEMANTIC(JsonParser); Parse(Text begin,Text end)62 JSHandle<JSTaggedValue> Parse(Text begin, Text end) 63 { 64 end_ = end - 1; 65 current_ = begin; 66 67 auto vm = thread_->GetEcmaVM(); 68 factory_ = vm->GetFactory(); 69 env_ = *vm->GetGlobalEnv(); 70 71 SkipEndWhiteSpace(); 72 range_ = end_; 73 JSTaggedValue result = ParseJSONText<false>(); 74 return JSHandle<JSTaggedValue>(thread_, result); 75 } 76 ParseUtf8(EcmaString * str)77 JSHandle<JSTaggedValue> ParseUtf8(EcmaString *str) 78 { 79 ASSERT(str != nullptr); 80 isAsciiString_ = true; 81 uint32_t len = str->GetUtf8Length(); 82 CVector<T> buf(len); 83 str->CopyDataUtf8(buf.data(), len); 84 Text begin = buf.data(); 85 return Parse(begin, begin + str->GetLength()); 86 } 87 ParseUtf16(EcmaString * str)88 JSHandle<JSTaggedValue> ParseUtf16(EcmaString *str) 89 { 90 ASSERT(str != nullptr); 91 uint32_t len = str->GetLength(); 92 CVector<T> buf(len); 93 str->CopyDataUtf16(buf.data(), len); 94 Text begin = buf.data(); 95 return Parse(begin, begin + len); 96 } 97 98 private: 99 template<bool inObjorArr = false> ParseJSONText()100 JSTaggedValue ParseJSONText() 101 { 102 SkipStartWhiteSpace(); 103 Tokens token = ParseToken(); 104 switch (token) { 105 case Tokens::OBJECT: 106 return ParseObject<inObjorArr>(); 107 case Tokens::ARRAY: 108 return ParseArray<inObjorArr>(); 109 case Tokens::LITERAL_TRUE: 110 return ParseLiteral("true", Tokens::LITERAL_TRUE); 111 case Tokens::LITERAL_FALSE: 112 return ParseLiteral("false", Tokens::LITERAL_FALSE); 113 case Tokens::LITERAL_NULL: 114 return ParseLiteral("null", Tokens::LITERAL_NULL); 115 case Tokens::NUMBER: 116 return ParseNumber<inObjorArr>(); 117 case Tokens::STRING: 118 return ParseString<inObjorArr>(); 119 default: 120 THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Text in JSON", JSTaggedValue::Exception()); 121 } 122 } 123 124 template<bool inObjOrArr = false> ParseNumber()125 JSTaggedValue ParseNumber() 126 { 127 if (inObjOrArr) { 128 bool isFast = true; 129 bool isNumber = ReadNumberRange(isFast); 130 if (!isNumber) { 131 THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Number in JSON", JSTaggedValue::Exception()); 132 } 133 if (isFast) { 134 std::string strNum(current_, end_ + 1); 135 current_ = end_; 136 return JSTaggedValue(std::stod(strNum)); 137 } 138 } 139 140 Text current = current_; 141 bool hasExponent = false; 142 if (*current_ == '-') { 143 if (UNLIKELY(current_++ == end_)) { 144 THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Number in JSON", JSTaggedValue::Exception()); 145 } 146 } 147 if (*current_ == '0') { 148 if (!CheckZeroBeginNumber(hasExponent)) { 149 THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Number in JSON", JSTaggedValue::Exception()); 150 } 151 } else if (*current_ >= '1' && *current_ <= '9') { 152 if (!CheckNonZeroBeginNumber(hasExponent)) { 153 THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Number in JSON", JSTaggedValue::Exception()); 154 } 155 } else { 156 THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Number in JSON", JSTaggedValue::Exception()); 157 } 158 159 std::string strNum(current, end_ + 1); 160 current_ = end_; 161 return JSTaggedValue(std::stod(strNum)); 162 } 163 ReadJsonStringRange(bool & isFastString,bool & isAscii)164 bool ReadJsonStringRange(bool &isFastString, bool &isAscii) 165 { 166 current_++; 167 if (isAsciiString_) { 168 return ReadAsciiStringRange(isFastString); 169 } 170 return ReadStringRange(isFastString, isAscii); 171 } 172 IsFastParseJsonString(bool & isFastString,bool & isAscii)173 bool IsFastParseJsonString(bool &isFastString, bool &isAscii) 174 { 175 current_++; 176 if (isAsciiString_) { 177 return IsFastParseAsciiString(isFastString); 178 } 179 return IsFastParseString(isFastString, isAscii); 180 } 181 ParseBackslash(CString & res)182 bool ParseBackslash(CString &res) 183 { 184 if (current_ == end_) { 185 return false; 186 } 187 current_++; 188 switch (*current_) { 189 case '\"': 190 res += "\""; 191 break; 192 case '\\': 193 res += "\\"; 194 break; 195 case '/': 196 res += "/"; 197 break; 198 case 'b': 199 res += "\b"; 200 break; 201 case 'f': 202 res += "\f"; 203 break; 204 case 'n': 205 res += "\n"; 206 break; 207 case 'r': 208 res += "\r"; 209 break; 210 case 't': 211 res += "\t"; 212 break; 213 case 'u': { 214 CVector<uint16_t> vec; 215 if (UNLIKELY(!ConvertStringUnicode(vec))) { 216 return false; 217 } 218 std::u16string u16Str; 219 u16Str.assign(vec.begin(), vec.end()); 220 res += base::StringHelper::U16stringToString(u16Str); 221 break; 222 } 223 default: 224 return false; 225 } 226 return true; 227 } 228 SlowParseString()229 JSTaggedValue SlowParseString() 230 { 231 end_--; 232 CString res; 233 while (current_ <= end_) { 234 if (*current_ == '\\') { 235 bool isLegalChar = ParseBackslash(res); 236 if (!isLegalChar) { 237 THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected string in JSON", JSTaggedValue::Exception()); 238 } 239 current_++; 240 } else if (UNLIKELY(*current_ > ASCII_END)) { 241 if (UNLIKELY(*current_ > utf_helper::DECODE_LEAD_LOW && *current_ < utf_helper::DECODE_LEAD_HIGH && 242 *(current_ + 1) > utf_helper::DECODE_TRAIL_LOW && 243 *(current_ + 1) < utf_helper::DECODE_TRAIL_HIGH)) { 244 std::u16string str(current_, current_ + 2); // 2 means twice as many bytes as normal u16string 245 res += ConvertToString(StringHelper::U16stringToString(str)); 246 current_ += 2; // 2 means twice as many bytes as normal u16string 247 } else { 248 std::u16string str(current_, current_ + 1); 249 res += ConvertToString(StringHelper::U16stringToString(str)); 250 current_++; 251 } 252 } else { 253 res += *current_; 254 current_++; 255 } 256 } 257 return factory_->NewFromUtf8Literal(reinterpret_cast<const uint8_t *>(res.c_str()), res.length()) 258 .GetTaggedValue(); 259 } 260 261 template<bool inObjorArr = false> ParseString()262 JSTaggedValue ParseString() 263 { 264 bool isFastString = true; 265 bool isAscii = true; 266 bool isLegal = true; 267 if (inObjorArr) { 268 isLegal = ReadJsonStringRange(isFastString, isAscii); 269 if (!isLegal) { 270 THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected end Text in JSON", JSTaggedValue::Exception()); 271 } 272 if (isFastString) { 273 if (isAscii) { 274 CString value(current_, end_); 275 current_ = end_; 276 return factory_->NewFromUtf8Literal( 277 reinterpret_cast<const uint8_t *>(value.c_str()), value.length()).GetTaggedValue(); 278 } 279 std::u16string value(current_, end_); 280 current_ = end_; 281 return factory_->NewFromUtf16Literal( 282 reinterpret_cast<const uint16_t *>(value.c_str()), value.length()).GetTaggedValue(); 283 } 284 } else { 285 if (*end_ != '"' || current_ == end_) { 286 THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected end Text in JSON", JSTaggedValue::Exception()); 287 } 288 isLegal = IsFastParseJsonString(isFastString, isAscii); 289 if (!isLegal) { 290 THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected end Text in JSON", JSTaggedValue::Exception()); 291 } 292 if (LIKELY(isFastString)) { 293 if (isAscii) { 294 CString value(current_, end_); 295 return factory_->NewFromUtf8Literal( 296 reinterpret_cast<const uint8_t *>(value.c_str()), value.length()).GetTaggedValue(); 297 } 298 std::u16string value(current_, end_); 299 return factory_->NewFromUtf16Literal( 300 reinterpret_cast<const uint16_t *>(value.c_str()), value.length()).GetTaggedValue(); 301 } 302 } 303 return SlowParseString(); 304 } 305 306 template<bool inObjorArr = false> ParseArray()307 JSTaggedValue ParseArray() 308 { 309 if (UNLIKELY(*range_ != ']' && !inObjorArr)) { 310 THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Array in JSON", JSTaggedValue::Exception()); 311 } 312 313 current_++; 314 JSHandle<JSArray> arr = factory_->NewJSArray(); 315 if (*current_ == ']') { 316 return arr.GetTaggedValue(); 317 } 318 319 JSTaggedValue value; 320 uint32_t index = 0; 321 while (current_ <= range_) { 322 value = ParseJSONText<true>(); 323 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread_); 324 FastRuntimeStub::SetPropertyByIndex<true>(thread_, arr.GetTaggedValue(), index++, value); 325 GetNextNonSpaceChar(); 326 if (*current_ == ',') { 327 current_++; 328 } else if (*current_ == ']') { 329 if (inObjorArr || current_ == range_) { 330 return arr.GetTaggedValue(); 331 } else { 332 THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Array in JSON", JSTaggedValue::Exception()); 333 } 334 } 335 } 336 THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Array in JSON", JSTaggedValue::Exception()); 337 } 338 339 template<bool inObjorArr = false> ParseObject()340 JSTaggedValue ParseObject() 341 { 342 if (UNLIKELY(*range_ != '}' && !inObjorArr)) { 343 THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Object in JSON", JSTaggedValue::Exception()); 344 } 345 346 JSHandle<JSTaggedValue> proto = env_->GetObjectFunction(); 347 JSHandle<JSObject> result = factory_->NewJSObjectByConstructor(JSHandle<JSFunction>(proto), proto); 348 current_++; 349 if (*current_ == '}') { 350 return result.GetTaggedValue(); 351 } 352 353 JSMutableHandle<JSTaggedValue> keyHandle(thread_, JSTaggedValue::Undefined()); 354 JSTaggedValue value; 355 while (current_ <= range_) { 356 SkipStartWhiteSpace(); 357 if (*current_ == '"') { 358 keyHandle.Update(ParseString<true>()); 359 } else { 360 if (*current_ == '}' && (inObjorArr || current_ == range_)) { 361 return result.GetTaggedValue(); 362 } 363 THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Object in JSON", JSTaggedValue::Exception()); 364 } 365 GetNextNonSpaceChar(); 366 if (*current_ == ':') { 367 current_++; 368 } else { 369 THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Object in JSON", JSTaggedValue::Exception()); 370 } 371 value = ParseJSONText<true>(); 372 FastRuntimeStub::SetPropertyByValue<true>( 373 thread_, result.GetTaggedValue(), keyHandle.GetTaggedValue(), value); 374 GetNextNonSpaceChar(); 375 if (*current_ == ',') { 376 current_++; 377 } else if (*current_ == '}') { 378 if (inObjorArr || current_ == range_) { 379 return result.GetTaggedValue(); 380 } else { 381 THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Object in JSON", JSTaggedValue::Exception()); 382 } 383 } 384 } 385 THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Object in JSON", JSTaggedValue::Exception()); 386 } 387 SkipEndWhiteSpace()388 void SkipEndWhiteSpace() 389 { 390 while (current_ != end_) { 391 if (*end_ == ' ' || *end_ == '\r' || *end_ == '\n' || *end_ == '\t') { 392 end_--; 393 } else { 394 break; 395 } 396 } 397 } 398 SkipStartWhiteSpace()399 void SkipStartWhiteSpace() 400 { 401 while (current_ != end_) { 402 if (*current_ == ' ' || *current_ == '\r' || *current_ == '\n' || *current_ == '\t') { 403 current_++; 404 } else { 405 break; 406 } 407 } 408 } 409 GetNextNonSpaceChar()410 void GetNextNonSpaceChar() 411 { 412 current_++; 413 SkipStartWhiteSpace(); 414 } 415 ParseToken()416 Tokens ParseToken() 417 { 418 switch (*current_) { 419 case '{': 420 return Tokens::OBJECT; 421 case '[': 422 return Tokens::ARRAY; 423 case '"': 424 return Tokens::STRING; 425 case '0': 426 case '1': 427 case '2': 428 case '3': 429 case '4': 430 case '5': 431 case '6': 432 case '7': 433 case '8': 434 case '9': 435 case '-': 436 return Tokens::NUMBER; 437 case 't': 438 return Tokens::LITERAL_TRUE; 439 case 'f': 440 return Tokens::LITERAL_FALSE; 441 case 'n': 442 return Tokens::LITERAL_NULL; 443 default: 444 return Tokens::TOKEN_ILLEGAL; 445 } 446 } 447 ParseLiteral(CString str,Tokens literalToken)448 JSTaggedValue ParseLiteral(CString str, Tokens literalToken) 449 { 450 uint32_t strLen = str.size() - 1; 451 uint32_t remainingLength = range_ - current_; 452 if (UNLIKELY(remainingLength < strLen)) { 453 THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Text in JSON", JSTaggedValue::Exception()); 454 } 455 456 bool isMatch = MatchText(str, strLen); 457 if (LIKELY(isMatch)) { 458 switch (literalToken) { 459 case Tokens::LITERAL_TRUE: 460 return JSTaggedValue::True(); 461 case Tokens::LITERAL_FALSE: 462 return JSTaggedValue::False(); 463 case Tokens::LITERAL_NULL: 464 return JSTaggedValue::Null(); 465 default: 466 UNREACHABLE(); 467 } 468 } 469 THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Text in JSON", JSTaggedValue::Exception()); 470 } 471 MatchText(CString str,uint32_t matchLen)472 bool MatchText(CString str, uint32_t matchLen) 473 { 474 const char *text = str.c_str(); 475 uint32_t pos = 1; 476 while (pos <= matchLen) { 477 if (current_[pos] != text[pos]) { 478 return false; 479 } 480 pos++; 481 } 482 current_ += matchLen; 483 return true; 484 } 485 ReadNumberRange(bool & isFast)486 bool ReadNumberRange(bool &isFast) 487 { 488 Text current = current_; 489 if (*current == '0') { 490 isFast = false; 491 current++; 492 } else if (*current == '-') { 493 current++; 494 if (*current == '0') { 495 isFast = false; 496 current++; 497 } 498 } 499 500 while (current != range_) { 501 if (IsNumberCharacter(*current)) { 502 current++; 503 continue; 504 } else if (IsNumberSignalCharacter(*current)) { 505 isFast = false; 506 current++; 507 continue; 508 } 509 Text end = current; 510 while (current != range_) { 511 if (*current == ' ' || *current == '\r' || *current == '\n' || *current == '\t') { 512 current++; 513 } else if (*current == ',' || *current == ']' || *current == '}') { 514 end_ = end - 1; 515 return true; 516 } else { 517 return false; 518 } 519 } 520 if (*current == ']' || *current == '}') { 521 end_ = end - 1; 522 return true; 523 } 524 return false; 525 } 526 end_ = range_ - 1; 527 return true; 528 } 529 IsNumberCharacter(T ch)530 bool IsNumberCharacter(T ch) 531 { 532 if (ch >= '0' && ch <= '9') { 533 return true; 534 } 535 return false; 536 } 537 IsNumberSignalCharacter(T ch)538 bool IsNumberSignalCharacter(T ch) 539 { 540 return ch == '.' || ch == 'e' || ch == 'E' || ch == '+' || ch == '-'; 541 } 542 IsExponentNumber()543 bool IsExponentNumber() 544 { 545 if (IsNumberCharacter(*current_)) { 546 return true; 547 } else if (*current_ == '-' || *current_ == '+') { 548 if (current_ == end_) { 549 return false; 550 } 551 current_++; 552 if (IsNumberCharacter(*current_)) { 553 return true; 554 } 555 } 556 return false; 557 } 558 IsDecimalsLegal(bool & hasExponent)559 bool IsDecimalsLegal(bool &hasExponent) 560 { 561 if (current_ == end_ && !IsNumberCharacter(*++current_)) { 562 return false; 563 } 564 565 while (current_ != end_) { 566 current_++; 567 if (IsNumberCharacter(*current_)) { 568 continue; 569 } else if (*current_ == 'e' || *current_ == 'E') { 570 if (hasExponent || current_ == end_) { 571 return false; 572 } 573 current_++; 574 if (!IsExponentNumber()) { 575 return false; 576 } 577 hasExponent = true; 578 } else { 579 return false; 580 } 581 } 582 return true; 583 } 584 IsExponentLegal(bool & hasExponent)585 bool IsExponentLegal(bool &hasExponent) 586 { 587 if (hasExponent || current_ == end_) { 588 return false; 589 } 590 current_++; 591 if (!IsExponentNumber()) { 592 return false; 593 } 594 while (current_ != end_) { 595 if (!IsNumberCharacter(*current_)) { 596 return false; 597 } 598 current_++; 599 } 600 return true; 601 } 602 ReadStringRange(bool & isFast,bool & isAscii)603 bool ReadStringRange(bool &isFast, bool &isAscii) 604 { 605 T c = 0; 606 Text current = current_; 607 608 while (current != range_) { 609 c = *current; 610 if (c == '"') { 611 end_ = current; 612 return true; 613 } else if (UNLIKELY(c == '\\')) { 614 current++; 615 isFast = false; 616 } 617 if (!IsLegalAsciiCharacter(c, isAscii)) { 618 return false; 619 } 620 current++; 621 } 622 return false; 623 } 624 ReadAsciiStringRange(bool & isFast)625 bool ReadAsciiStringRange(bool &isFast) 626 { 627 T c = 0; 628 Text current = current_; 629 630 while (current != range_) { 631 c = *current; 632 if (c == '"') { 633 end_ = current; 634 return true; 635 } else if (UNLIKELY(c == '\\')) { 636 current++; 637 isFast = false; 638 } else if (UNLIKELY(c < CODE_SPACE)) { 639 return false; 640 } 641 current++; 642 } 643 return false; 644 } 645 IsFastParseString(bool & isFast,bool & isAscii)646 bool IsFastParseString(bool &isFast, bool &isAscii) 647 { 648 Text current = current_; 649 while (current != end_) { 650 if (!IsLegalAsciiCharacter(*current, isAscii)) { 651 return false; 652 } 653 if (*current == '\\') { 654 isFast = false; 655 } 656 current++; 657 } 658 return true; 659 } 660 IsFastParseAsciiString(bool & isFast)661 bool IsFastParseAsciiString(bool &isFast) 662 { 663 Text current = current_; 664 while (current != end_) { 665 if (*current < CODE_SPACE) { 666 return false; 667 } else if (*current == '\\') { 668 isFast = false; 669 } 670 current++; 671 } 672 return true; 673 } 674 ConvertStringUnicode(CVector<uint16_t> & vec)675 bool ConvertStringUnicode(CVector<uint16_t> &vec) 676 { 677 uint32_t remainingLength = end_ - current_; 678 if (remainingLength < UNICODE_DIGIT_LENGTH) { 679 return false; 680 } 681 uint16_t res = 0; 682 uint32_t exponent = UNICODE_DIGIT_LENGTH; 683 for (uint32_t pos = 0; pos < UNICODE_DIGIT_LENGTH; pos++) { 684 current_++; 685 exponent--; 686 if (*current_ >= '0' && *current_ <= '9') { 687 res += (*current_ - '0') * pow(NUMBER_SIXTEEN, exponent); 688 } else if (*current_ >= 'a' && *current_ <= 'f') { 689 res += (*current_ - 'a' + NUMBER_TEN) * pow(NUMBER_SIXTEEN, exponent); 690 } else if (*current_ >= 'A' && *current_ <= 'F') { 691 res += (*current_ - 'A' + NUMBER_TEN) * pow(NUMBER_SIXTEEN, exponent); 692 } else { 693 return false; 694 } 695 } 696 697 vec.emplace_back(res); 698 699 if (*(current_ + 1) == '\\' && *(current_ + 2) == 'u') { // 2: next two chars 700 current_ += 2; // 2: point moves backwards by two digits 701 return ConvertStringUnicode(vec); 702 } 703 return true; 704 } 705 CheckZeroBeginNumber(bool & hasExponent)706 bool CheckZeroBeginNumber(bool &hasExponent) 707 { 708 if (current_++ != end_) { 709 if (*current_ == '.') { 710 if (!IsDecimalsLegal(hasExponent)) { 711 return false; 712 } 713 } else if (*current_ == 'e' || *current_ == 'E') { 714 if (!IsExponentLegal(hasExponent)) { 715 return false; 716 } 717 } else { 718 return false; 719 } 720 } 721 return true; 722 } 723 CheckNonZeroBeginNumber(bool & hasExponent)724 bool CheckNonZeroBeginNumber(bool &hasExponent) 725 { 726 while (current_ != end_) { 727 current_++; 728 if (IsNumberCharacter(*current_)) { 729 continue; 730 } else if (*current_ == '.') { 731 if (!IsDecimalsLegal(hasExponent)) { 732 return false; 733 } 734 } else if (*current_ == 'e' || *current_ == 'E') { 735 if (!IsExponentLegal(hasExponent)) { 736 return false; 737 } 738 } else { 739 return false; 740 } 741 } 742 return true; 743 } 744 IsLegalAsciiCharacter(T c,bool & isAscii)745 bool IsLegalAsciiCharacter(T c, bool &isAscii) 746 { 747 if (c <= ASCII_END) { 748 if (c >= CODE_SPACE) { 749 return true; 750 } 751 return false; 752 } 753 isAscii = false; 754 return true; 755 } 756 757 bool isAsciiString_{false}; 758 Text end_{nullptr}; 759 Text current_{nullptr}; 760 Text range_{nullptr}; 761 JSThread *thread_{nullptr}; 762 ObjectFactory *factory_{nullptr}; 763 GlobalEnv *env_{nullptr}; 764 }; 765 766 class Internalize { 767 public: 768 static JSHandle<JSTaggedValue> InternalizeJsonProperty(JSThread *thread, const JSHandle<JSObject> &holder, 769 const JSHandle<JSTaggedValue> &name, 770 const JSHandle<JSTaggedValue> &receiver); 771 private: 772 static bool RecurseAndApply(JSThread *thread, const JSHandle<JSObject> &holder, const JSHandle<JSTaggedValue> &name, 773 const JSHandle<JSTaggedValue> &receiver); 774 }; 775 } // namespace panda::ecmascript::base 776 777 #endif // ECMASCRIPT_BASE_JSON_PARSE_INL_H 778