mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-11-27 04:00:37 +00:00
!5313 JSON Parse Refactor
Merge pull request !5313 from 许杰/jsonparse_refactor
This commit is contained in:
commit
9cc8a59978
@ -53,10 +53,23 @@ enum class Tokens : uint8_t {
|
||||
TOKEN_ILLEGAL,
|
||||
};
|
||||
|
||||
struct JsonContinuation {
|
||||
enum class ContinuationType : uint8_t {
|
||||
RETURN = 0,
|
||||
ARRAY,
|
||||
OBJECT,
|
||||
};
|
||||
JsonContinuation(ContinuationType type, size_t index) : type_(type), index_(index) {}
|
||||
|
||||
ContinuationType type_ {ContinuationType::RETURN};
|
||||
size_t index_ {0};
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class JsonParser {
|
||||
protected:
|
||||
using Text = const T *;
|
||||
using ContType = JsonContinuation::ContinuationType;
|
||||
// Instantiation of the class is prohibited
|
||||
JsonParser() = default;
|
||||
explicit JsonParser(JSThread *thread) : thread_(thread) {}
|
||||
@ -78,6 +91,11 @@ protected:
|
||||
auto vm = thread_->GetEcmaVM();
|
||||
factory_ = vm->GetFactory();
|
||||
env_ = *vm->GetGlobalEnv();
|
||||
JSHandle<JSFunction> arrayFunc(env_->GetArrayFunction());
|
||||
initialJSArrayClass_ = JSHandle<JSHClass>(thread_, JSFunction::GetOrCreateInitialJSHClass(thread_, arrayFunc));
|
||||
JSHandle<JSFunction> objectFunc(env_->GetObjectFunction());
|
||||
initialJSObjectClass_ =
|
||||
JSHandle<JSHClass>(thread_, JSFunction::GetOrCreateInitialJSHClass(thread_, objectFunc));
|
||||
|
||||
SkipEndWhiteSpace();
|
||||
range_ = end_;
|
||||
@ -85,30 +103,197 @@ protected:
|
||||
return JSHandle<JSTaggedValue>(thread_, result);
|
||||
}
|
||||
|
||||
JSTaggedValue ParseJSONText(bool inObjorArr = false)
|
||||
inline bool IsInObjOrArray(ContType type)
|
||||
{
|
||||
SkipStartWhiteSpace();
|
||||
Tokens token = ParseToken();
|
||||
switch (token) {
|
||||
case Tokens::OBJECT:
|
||||
return ParseObject(inObjorArr);
|
||||
case Tokens::ARRAY:
|
||||
return ParseArray(inObjorArr);
|
||||
case Tokens::LITERAL_TRUE:
|
||||
return ParseLiteralTrue();
|
||||
case Tokens::LITERAL_FALSE:
|
||||
return ParseLiteralFalse();
|
||||
case Tokens::LITERAL_NULL:
|
||||
return ParseLiteralNull();
|
||||
case Tokens::NUMBER:
|
||||
return ParseNumber(inObjorArr);
|
||||
case Tokens::STRING:
|
||||
return ParseString(inObjorArr);
|
||||
default:
|
||||
THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Text in JSON", JSTaggedValue::Exception());
|
||||
return type == ContType::ARRAY || type == ContType::OBJECT;
|
||||
}
|
||||
|
||||
inline bool EmptyArrayCheck()
|
||||
{
|
||||
GetNextNonSpaceChar();
|
||||
return *current_ == ']';
|
||||
}
|
||||
|
||||
inline bool EmptyObjectCheck()
|
||||
{
|
||||
GetNextNonSpaceChar();
|
||||
return *current_ == '}';
|
||||
}
|
||||
|
||||
JSTaggedValue ParseJSONText()
|
||||
{
|
||||
JSHandle<JSTaggedValue> parseValue;
|
||||
std::vector<JsonContinuation> continuationList;
|
||||
std::vector<JSHandle<JSTaggedValue>> elementsList;
|
||||
std::vector<JSHandle<JSTaggedValue>> propertyList;
|
||||
continuationList.reserve(16); // 16: initial capacity
|
||||
elementsList.reserve(16); // 16: initial capacity
|
||||
propertyList.reserve(16); // 16: initial capacity
|
||||
JsonContinuation continuation(ContType::RETURN, 0);
|
||||
while (true) {
|
||||
while (true) {
|
||||
SkipStartWhiteSpace();
|
||||
Tokens token = ParseToken();
|
||||
switch (token) {
|
||||
case Tokens::OBJECT:
|
||||
if (EmptyObjectCheck()) {
|
||||
parseValue = JSHandle<JSTaggedValue>(factory_->NewJSObject(initialJSObjectClass_));
|
||||
GetNextNonSpaceChar();
|
||||
break;
|
||||
}
|
||||
continuationList.emplace_back(std::move(continuation));
|
||||
continuation = JsonContinuation(ContType::OBJECT, propertyList.size());
|
||||
|
||||
SkipStartWhiteSpace();
|
||||
if (*current_ == '"') {
|
||||
propertyList.emplace_back(JSHandle<JSTaggedValue>(thread_, ParseString(true)));
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread_);
|
||||
} else {
|
||||
THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Object Prop in JSON",
|
||||
JSTaggedValue::Exception());
|
||||
}
|
||||
SkipStartWhiteSpace();
|
||||
if (*current_ == ':') {
|
||||
Advance();
|
||||
} else {
|
||||
THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Object in JSON",
|
||||
JSTaggedValue::Exception());
|
||||
}
|
||||
continue;
|
||||
case Tokens::ARRAY:
|
||||
if (EmptyArrayCheck()) {
|
||||
parseValue = JSHandle<JSTaggedValue>(factory_->NewJSArray(0, initialJSArrayClass_));
|
||||
GetNextNonSpaceChar();
|
||||
break;
|
||||
}
|
||||
continuationList.emplace_back(std::move(continuation));
|
||||
continuation = JsonContinuation(ContType::ARRAY, elementsList.size());
|
||||
continue;
|
||||
case Tokens::LITERAL_TRUE:
|
||||
parseValue = JSHandle<JSTaggedValue>(thread_, ParseLiteralTrue());
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread_);
|
||||
break;
|
||||
case Tokens::LITERAL_FALSE:
|
||||
parseValue = JSHandle<JSTaggedValue>(thread_, ParseLiteralFalse());
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread_);
|
||||
break;
|
||||
case Tokens::LITERAL_NULL:
|
||||
parseValue = JSHandle<JSTaggedValue>(thread_, ParseLiteralNull());
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread_);
|
||||
break;
|
||||
case Tokens::NUMBER:
|
||||
parseValue = JSHandle<JSTaggedValue>(thread_, ParseNumber(IsInObjOrArray(continuation.type_)));
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread_);
|
||||
break;
|
||||
case Tokens::STRING:
|
||||
parseValue = JSHandle<JSTaggedValue>(thread_, ParseString(IsInObjOrArray(continuation.type_)));
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread_);
|
||||
break;
|
||||
default:
|
||||
THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Text in JSON", JSTaggedValue::Exception());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
switch (continuation.type_) {
|
||||
case ContType::RETURN:
|
||||
ASSERT(continuationList.empty());
|
||||
ASSERT(elementsList.empty());
|
||||
ASSERT(propertyList.empty());
|
||||
if (current_ <= range_) {
|
||||
THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Text in JSON",
|
||||
JSTaggedValue::Exception());
|
||||
}
|
||||
return parseValue.GetTaggedValue();
|
||||
case ContType::ARRAY: {
|
||||
elementsList.emplace_back(parseValue);
|
||||
SkipStartWhiteSpace();
|
||||
if (*current_ == ',') {
|
||||
Advance();
|
||||
break;
|
||||
}
|
||||
parseValue = CreateJsonArray(continuation, elementsList);
|
||||
if (*current_ != ']') {
|
||||
THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Array in JSON",
|
||||
JSTaggedValue::Exception());
|
||||
}
|
||||
GetNextNonSpaceChar();
|
||||
elementsList.resize(continuation.index_);
|
||||
continuation = std::move(continuationList.back());
|
||||
continuationList.pop_back();
|
||||
continue;
|
||||
}
|
||||
case ContType::OBJECT: {
|
||||
propertyList.emplace_back(parseValue);
|
||||
SkipStartWhiteSpace();
|
||||
if (*current_ == ',') {
|
||||
GetNextNonSpaceChar();
|
||||
if (*current_ == '"') {
|
||||
propertyList.emplace_back(JSHandle<JSTaggedValue>(thread_, ParseString(true)));
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread_);
|
||||
} else {
|
||||
THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Object Prop in JSON",
|
||||
JSTaggedValue::Exception());
|
||||
}
|
||||
SkipStartWhiteSpace();
|
||||
if (*current_ == ':') {
|
||||
Advance();
|
||||
} else {
|
||||
THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Object in JSON",
|
||||
JSTaggedValue::Exception());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
parseValue = CreateJsonObject(continuation, propertyList);
|
||||
if (*current_ == '}') {
|
||||
GetNextNonSpaceChar();
|
||||
} else {
|
||||
THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Object in JSON",
|
||||
JSTaggedValue::Exception());
|
||||
}
|
||||
propertyList.resize(continuation.index_);
|
||||
continuation = std::move(continuationList.back());
|
||||
continuationList.pop_back();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JSHandle<JSTaggedValue> CreateJsonArray(JsonContinuation continuation,
|
||||
std::vector<JSHandle<JSTaggedValue>> &elementsList)
|
||||
{
|
||||
size_t start = continuation.index_;
|
||||
size_t size = elementsList.size() - start;
|
||||
JSHandle<JSArray> array = factory_->NewJSArray(size, initialJSArrayClass_);
|
||||
JSHandle<TaggedArray> elements = factory_->NewJsonFixedArray(start, size, elementsList);
|
||||
JSHandle<JSObject> obj(array);
|
||||
obj->SetElements(thread_, elements);
|
||||
return JSHandle<JSTaggedValue>(array);
|
||||
}
|
||||
|
||||
JSHandle<JSTaggedValue> CreateJsonObject(JsonContinuation continuation,
|
||||
std::vector<JSHandle<JSTaggedValue>> &propertyList)
|
||||
{
|
||||
size_t start = continuation.index_;
|
||||
size_t size = propertyList.size() - start;
|
||||
JSHandle<JSObject> obj = factory_->NewJSObject(initialJSObjectClass_);
|
||||
for (size_t i = 0; i < size; i += 2) { // 2: prop name and value
|
||||
JSTaggedValue res = ObjectFastOperator::SetPropertyByValue<true>(thread_, obj.GetTaggedValue(),
|
||||
propertyList[start + i].GetTaggedValue(), propertyList[start + i + 1].GetTaggedValue());
|
||||
if (res.IsHole()) {
|
||||
// slow path
|
||||
JSTaggedValue::SetProperty(thread_, JSHandle<JSTaggedValue>(obj), propertyList[start + i],
|
||||
propertyList[start + i + 1], true);
|
||||
}
|
||||
}
|
||||
return JSHandle<JSTaggedValue>(obj);
|
||||
}
|
||||
|
||||
JSTaggedValue ParseNumber(bool inObjorArr = false)
|
||||
{
|
||||
if (inObjorArr) {
|
||||
@ -116,7 +301,8 @@ protected:
|
||||
int32_t fastInteger = 0;
|
||||
bool isNumber = ReadNumberRange(isFast, fastInteger);
|
||||
if (!isNumber) {
|
||||
THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Number in JSON", JSTaggedValue::Exception());
|
||||
THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Number in JSON Array Or Object",
|
||||
JSTaggedValue::Exception());
|
||||
}
|
||||
if (isFast) {
|
||||
return JSTaggedValue(fastInteger);
|
||||
@ -143,7 +329,7 @@ protected:
|
||||
}
|
||||
|
||||
std::string strNum(current, end_ + 1);
|
||||
current_ = end_;
|
||||
current_ = end_ + 1;
|
||||
errno = 0; // reset errno to 0 to avoid errno has been changed
|
||||
double v = std::strtod(strNum.c_str(), nullptr);
|
||||
if (errno == ERANGE) {
|
||||
@ -221,6 +407,7 @@ protected:
|
||||
}
|
||||
}
|
||||
ASSERT(res.size() <= static_cast<size_t>(UINT32_MAX));
|
||||
Advance();
|
||||
return factory_->NewFromUtf8Literal(reinterpret_cast<const uint8_t *>(res.c_str()), res.size())
|
||||
.GetTaggedValue();
|
||||
}
|
||||
@ -229,111 +416,6 @@ protected:
|
||||
|
||||
virtual JSTaggedValue ParseString(bool inObjorArr = false) = 0;
|
||||
|
||||
JSTaggedValue ParseArray(bool inObjorArr = false)
|
||||
{
|
||||
if (UNLIKELY(*range_ != ']' && !inObjorArr)) {
|
||||
THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Array in JSON", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
Advance();
|
||||
SkipStartWhiteSpace();
|
||||
|
||||
if (*current_ == ']') {
|
||||
JSHandle<JSArray> arr = factory_->NewJSArray();
|
||||
return arr.GetTaggedValue();
|
||||
}
|
||||
|
||||
JSTaggedValue value;
|
||||
std::vector<JSHandle<JSTaggedValue>> vec;
|
||||
while (current_ <= range_) {
|
||||
value = ParseJSONText(true);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread_);
|
||||
vec.emplace_back(JSHandle<JSTaggedValue>(thread_, value));
|
||||
GetNextNonSpaceChar();
|
||||
if (*current_ == ',') {
|
||||
Advance();
|
||||
} else if (*current_ == ']') {
|
||||
if (inObjorArr || current_ == range_) {
|
||||
return CreateJsonArray(vec);
|
||||
} else {
|
||||
THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Array in JSON", JSTaggedValue::Exception());
|
||||
}
|
||||
}
|
||||
}
|
||||
THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Array in JSON", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
inline JSTaggedValue CreateJsonArray(std::vector<JSHandle<JSTaggedValue>> &vec)
|
||||
{
|
||||
JSHandle<JSArray> array = factory_->NewJSArray();
|
||||
size_t arrayLength = vec.size();
|
||||
array->SetArrayLength(thread_, arrayLength);
|
||||
JSHandle<TaggedArray> newElements = factory_->NewTaggedArray(arrayLength);
|
||||
for (size_t i = 0; i < arrayLength; i++) {
|
||||
newElements->Set(thread_, i, vec[i]);
|
||||
}
|
||||
JSHandle<JSObject> obj(array);
|
||||
obj->SetElements(thread_, newElements);
|
||||
return array.GetTaggedValue();
|
||||
}
|
||||
|
||||
JSTaggedValue ParseObject(bool inObjorArr = false)
|
||||
{
|
||||
if (UNLIKELY(*range_ != '}' && !inObjorArr)) {
|
||||
THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Object in JSON", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
JSHandle<JSFunction> proto(env_->GetObjectFunction());
|
||||
JSHandle<JSObject> result = factory_->NewJSObjectByConstructor(proto);
|
||||
Advance();
|
||||
if (*current_ == '}') {
|
||||
return result.GetTaggedValue();
|
||||
}
|
||||
|
||||
JSMutableHandle<JSTaggedValue> keyHandle(thread_, JSTaggedValue::Undefined());
|
||||
JSTaggedValue value;
|
||||
while (current_ <= range_) {
|
||||
SkipStartWhiteSpace();
|
||||
if (*current_ == '"') {
|
||||
keyHandle.Update(ParseString(true));
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread_);
|
||||
} else {
|
||||
if (*current_ == '}' && (inObjorArr || current_ == range_)) {
|
||||
return result.GetTaggedValue();
|
||||
}
|
||||
THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Object in JSON", JSTaggedValue::Exception());
|
||||
}
|
||||
GetNextNonSpaceChar();
|
||||
if (*current_ == ':') {
|
||||
Advance();
|
||||
} else {
|
||||
THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Object in JSON", JSTaggedValue::Exception());
|
||||
}
|
||||
value = ParseJSONText(true);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread_);
|
||||
// fast path
|
||||
JSTaggedValue res = ObjectFastOperator::SetPropertyByValue<true>(thread_, result.GetTaggedValue(),
|
||||
keyHandle.GetTaggedValue(), value);
|
||||
if (res.IsHole()) {
|
||||
// slow path
|
||||
JSTaggedValue::SetProperty(thread_, JSHandle<JSTaggedValue>(result), keyHandle,
|
||||
JSHandle<JSTaggedValue>(thread_, value), true);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread_);
|
||||
}
|
||||
GetNextNonSpaceChar();
|
||||
if (*current_ == ',') {
|
||||
Advance();
|
||||
} else if (*current_ == '}') {
|
||||
if (inObjorArr || current_ == range_) {
|
||||
return result.GetTaggedValue();
|
||||
} else {
|
||||
THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Object in JSON", JSTaggedValue::Exception());
|
||||
}
|
||||
}
|
||||
}
|
||||
THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Object in JSON", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
void SkipEndWhiteSpace()
|
||||
{
|
||||
while (current_ != end_) {
|
||||
@ -401,7 +483,7 @@ protected:
|
||||
if (UNLIKELY(remainingLength < 3)) { // 3: literalTrue length - 1
|
||||
THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Text in JSON", JSTaggedValue::Exception());
|
||||
}
|
||||
bool isMatch = MatchText(literalTrue, 3); // 3: literalTrue length - 1
|
||||
bool isMatch = MatchText(literalTrue, 4); // 4: literalTrue length
|
||||
if (LIKELY(isMatch)) {
|
||||
return JSTaggedValue::True();
|
||||
}
|
||||
@ -415,7 +497,7 @@ protected:
|
||||
if (UNLIKELY(remainingLength < 4)) { // 4: literalFalse length - 1
|
||||
THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Text in JSON", JSTaggedValue::Exception());
|
||||
}
|
||||
bool isMatch = MatchText(literalFalse, 4); // 4: literalFalse length - 1
|
||||
bool isMatch = MatchText(literalFalse, 5); // 5: literalFalse length
|
||||
if (LIKELY(isMatch)) {
|
||||
return JSTaggedValue::False();
|
||||
}
|
||||
@ -429,7 +511,7 @@ protected:
|
||||
if (UNLIKELY(remainingLength < 3)) { // 3: literalNull length - 1
|
||||
THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Text in JSON", JSTaggedValue::Exception());
|
||||
}
|
||||
bool isMatch = MatchText(literalNull, 3); // 3: literalNull length - 1
|
||||
bool isMatch = MatchText(literalNull, 4); // 4: literalNull length
|
||||
if (LIKELY(isMatch)) {
|
||||
return JSTaggedValue::Null();
|
||||
}
|
||||
@ -439,7 +521,7 @@ protected:
|
||||
bool MatchText(const char *str, uint32_t matchLen)
|
||||
{
|
||||
// first char is already matched
|
||||
for (uint32_t pos = 1; pos <= matchLen; ++pos) {
|
||||
for (uint32_t pos = 1; pos < matchLen; ++pos) {
|
||||
if (current_[pos] != str[pos]) {
|
||||
return false;
|
||||
}
|
||||
@ -472,7 +554,7 @@ protected:
|
||||
i = (i * 10) + ((*current) - '0');
|
||||
}
|
||||
fastInteger = i * sign;
|
||||
current_ = advance - 1;
|
||||
current_ = advance;
|
||||
return true;
|
||||
}
|
||||
isFast = false;
|
||||
@ -679,6 +761,8 @@ protected:
|
||||
JSThread *thread_ {nullptr};
|
||||
ObjectFactory *factory_ {nullptr};
|
||||
GlobalEnv *env_ {nullptr};
|
||||
JSHandle<JSHClass> initialJSArrayClass_;
|
||||
JSHandle<JSHClass> initialJSObjectClass_;
|
||||
};
|
||||
|
||||
class Utf8JsonParser : public JsonParser<uint8_t> {
|
||||
@ -692,10 +776,11 @@ public:
|
||||
JSHandle<JSTaggedValue> Parse(EcmaString *str)
|
||||
{
|
||||
ASSERT(str != nullptr);
|
||||
uint32_t len = EcmaStringAccessor(str).GetLength();
|
||||
auto stringAccessor = EcmaStringAccessor(str);
|
||||
uint32_t len = stringAccessor.GetLength();
|
||||
ASSERT(len != UINT32_MAX);
|
||||
CVector<uint8_t> buf(len + 1);
|
||||
EcmaStringAccessor(str).WriteToFlatUtf8(buf.data(), len);
|
||||
stringAccessor.WriteToFlatUtf8(buf.data(), len);
|
||||
Text begin = buf.data();
|
||||
return Launch(begin, begin + len);
|
||||
}
|
||||
@ -720,7 +805,7 @@ private:
|
||||
ASSERT(strLength <= static_cast<size_t>(UINT32_MAX));
|
||||
JSTaggedValue res = factory_->NewCompressedUtf8(
|
||||
reinterpret_cast<const uint8_t *>(current_), strLength).GetTaggedValue();
|
||||
current_ = end_;
|
||||
current_ = end_ + 1;
|
||||
return res;
|
||||
}
|
||||
} else {
|
||||
@ -733,6 +818,7 @@ private:
|
||||
}
|
||||
if (LIKELY(isFastString)) {
|
||||
std::string_view value(reinterpret_cast<const char *>(current_), end_ - current_);
|
||||
current_ = end_ + 1;
|
||||
ASSERT(value.size() <= static_cast<size_t>(UINT32_MAX));
|
||||
return factory_->NewFromUtf8LiteralCompress(
|
||||
reinterpret_cast<const uint8_t *>(value.data()), value.size()).GetTaggedValue();
|
||||
@ -812,13 +898,13 @@ private:
|
||||
if (isFastString) {
|
||||
if (isAscii) {
|
||||
std::string value(current_, end_); // from uint16_t* to std::string, can't use std::string_view
|
||||
current_ = end_;
|
||||
current_ = end_ + 1;
|
||||
ASSERT(value.size() <= static_cast<size_t>(UINT32_MAX));
|
||||
return factory_->NewFromUtf8LiteralCompress(
|
||||
reinterpret_cast<const uint8_t *>(value.c_str()), value.size()).GetTaggedValue();
|
||||
}
|
||||
std::u16string_view value(reinterpret_cast<const char16_t *>(current_), end_ - current_);
|
||||
current_ = end_;
|
||||
current_ = end_ + 1;
|
||||
ASSERT(value.size() <= static_cast<size_t>(UINT32_MAX));
|
||||
return factory_->NewFromUtf16LiteralNotCompress(
|
||||
reinterpret_cast<const uint16_t *>(value.data()), value.size()).GetTaggedValue();
|
||||
@ -835,11 +921,13 @@ private:
|
||||
if (isAscii) {
|
||||
std::string value(current_, end_); // from uint16_t* to std::string, can't use std::string_view
|
||||
ASSERT(value.size() <= static_cast<size_t>(UINT32_MAX));
|
||||
current_ = end_ + 1;
|
||||
return factory_->NewFromUtf8LiteralCompress(
|
||||
reinterpret_cast<const uint8_t *>(value.c_str()), value.size()).GetTaggedValue();
|
||||
}
|
||||
std::u16string_view value(reinterpret_cast<const char16_t *>(current_), end_ - current_);
|
||||
ASSERT(value.size() <= static_cast<size_t>(UINT32_MAX));
|
||||
current_ = end_ + 1;
|
||||
return factory_->NewFromUtf16LiteralNotCompress(
|
||||
reinterpret_cast<const uint16_t *>(value.data()), value.size()).GetTaggedValue();
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ HWTEST_F_L0(JsonParserTest, Parser_003)
|
||||
|
||||
JSHandle<JSTaggedValue> handleMsg(factory->NewFromASCII(
|
||||
"\t\r \n{\t\r \n \"json\"\t\r\n:\t\r \n{\t\r \n}\t\r \n,\t\r \n \"prop2\"\t\r \n:\t\r \n [\t\r \nfalse\t\r"
|
||||
"\n,\t\r \nnull\t\r \ntrue\t\r,123.456\t\r \n]\t\r \n}\t\r \n"));
|
||||
"\n,\t\r \nnull\t\r, \ntrue\t\r,123.456\t\r \n]\t\r \n}\t\r \n"));
|
||||
JSHandle<EcmaString> handleStr(JSTaggedValue::ToString(thread, handleMsg)); // JSON Object
|
||||
JSHandle<JSTaggedValue> result = parser.Parse(*handleStr);
|
||||
EXPECT_TRUE(result->IsECMAObject());
|
||||
|
@ -671,6 +671,32 @@ JSHandle<JSArray> ObjectFactory::NewJSArray()
|
||||
return JSHandle<JSArray>(NewJSObjectByConstructor(function));
|
||||
}
|
||||
|
||||
JSHandle<JSArray> ObjectFactory::NewJSArray(size_t length, JSHandle<JSHClass> &hclass)
|
||||
{
|
||||
JSHandle<JSObject> obj = NewJSObject(hclass);
|
||||
JSArray::Cast(*obj)->SetLength(length);
|
||||
JSArray::Cast(*obj)->SetTrackInfo(thread_, JSTaggedValue::Undefined());
|
||||
auto accessor = thread_->GlobalConstants()->GetArrayLengthAccessor();
|
||||
JSArray::Cast(*obj)->SetPropertyInlinedProps(thread_, JSArray::LENGTH_INLINE_PROPERTY_INDEX, accessor);
|
||||
return JSHandle<JSArray>(obj);
|
||||
}
|
||||
|
||||
JSHandle<TaggedArray> ObjectFactory::NewJsonFixedArray(size_t start, size_t length,
|
||||
const std::vector<JSHandle<JSTaggedValue>> &vec)
|
||||
{
|
||||
if (length == 0) {
|
||||
return EmptyArray();
|
||||
}
|
||||
|
||||
MemSpaceType spaceType = length < LENGTH_THRESHOLD ? MemSpaceType::SEMI_SPACE : MemSpaceType::OLD_SPACE;
|
||||
JSHandle<TaggedArray> array = NewTaggedArrayWithoutInit(length, spaceType);
|
||||
array->SetExtraLength(0);
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
array->Set(thread_, i, vec[start + i]);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
JSHandle<JSForInIterator> ObjectFactory::NewJSForinIterator(const JSHandle<JSTaggedValue> &obj,
|
||||
const JSHandle<JSTaggedValue> keys,
|
||||
const JSHandle<JSTaggedValue> cachedHclass)
|
||||
|
@ -317,6 +317,9 @@ public:
|
||||
JSHandle<job::PendingJob> NewPendingJob(const JSHandle<JSFunction> &func, const JSHandle<TaggedArray> &argv);
|
||||
|
||||
JSHandle<JSArray> NewJSArray();
|
||||
JSHandle<JSArray> NewJSArray(size_t length, JSHandle<JSHClass> &hclass);
|
||||
JSHandle<TaggedArray> NewJsonFixedArray(size_t start, size_t length,
|
||||
const std::vector<JSHandle<JSTaggedValue>> &vec);
|
||||
|
||||
JSHandle<JSProxy> NewJSProxy(const JSHandle<JSTaggedValue> &target, const JSHandle<JSTaggedValue> &handler);
|
||||
JSHandle<JSRealm> NewJSRealm();
|
||||
|
@ -11,7 +11,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
SyntaxError: Unexpected Array in JSON
|
||||
SyntaxError: Unexpected Number in JSON Array Or Object
|
||||
exception_case1.js:18:18
|
||||
exception_case1.js:20:1
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
SyntaxError: Unexpected Array in JSON
|
||||
SyntaxError: Unexpected Number in JSON Array Or Object
|
||||
exception_case11.ts:22:22
|
||||
exception_case11.ts:25:1
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
SyntaxError: Unexpected Array in JSON
|
||||
SyntaxError: Unexpected Number in JSON Array Or Object
|
||||
exception_case12.ts:21:21
|
||||
exception_case12.ts:24:1
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
SyntaxError: Unexpected Array in JSON
|
||||
SyntaxError: Unexpected Number in JSON Array Or Object
|
||||
exception_case8.js:18:18
|
||||
exception_case8.js:22:22
|
||||
exception_case8.js:24:1
|
||||
|
@ -11,7 +11,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
SyntaxError: Unexpected Array in JSON
|
||||
SyntaxError: Unexpected Number in JSON Array Or Object
|
||||
at foo1 (maybe inlined). depth: 2
|
||||
at foo3 (maybe inlined). depth: 1
|
||||
at foo4 (maybe inlined). depth: 0
|
||||
|
@ -11,7 +11,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
SyntaxError: Unexpected Array in JSON
|
||||
SyntaxError: Unexpected Number in JSON Array Or Object
|
||||
at Student (hidden:26:26)
|
||||
at foo1 (maybe inlined). depth: 1
|
||||
at foo2 (maybe inlined). depth: 0
|
||||
|
Loading…
Reference in New Issue
Block a user