• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2025 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 "intrinsics.h"
17 #include "plugins/ets/runtime/ets_utils.h"
18 #include "helpers/json_helper.h"
19 
20 namespace ark::ets::intrinsics {
21 
GetInstanceFieldByName(EtsClass * cls,EtsString * name)22 static EtsField *GetInstanceFieldByName(EtsClass *cls, EtsString *name)
23 {
24     auto fieldName = name->GetMutf8();
25     auto instanceField = ManglingUtils::GetFieldIDByDisplayName(cls, fieldName);
26     return instanceField;
27 }
28 
EscompatJSONGetJSONStringifyIgnoreByIdx(EtsClass * cls,EtsLong idx)29 EtsBoolean EscompatJSONGetJSONStringifyIgnoreByIdx(EtsClass *cls, EtsLong idx)
30 {
31     EtsField *field = cls->GetFieldByIndex(idx);
32     bool ret = false;
33     if (field == nullptr) {
34         return static_cast<EtsBoolean>(ret);
35     }
36     auto *runtimeClass = field->GetDeclaringClass()->GetRuntimeClass();
37     const panda_file::File &pf = *runtimeClass->GetPandaFile();
38     panda_file::FieldDataAccessor fda(pf, field->GetRuntimeField()->GetFileId());
39     fda.EnumerateAnnotations([&pf, &ret](panda_file::File::EntityId annId) {
40         panda_file::AnnotationDataAccessor ada(pf, annId);
41         const char *className = utf::Mutf8AsCString(pf.GetStringData(ada.GetClassId()).data);
42         if (className == panda_file_items::class_descriptors::JSON_STRINGIFY_IGNORE) {
43             ret = true;
44         }
45     });
46     return static_cast<EtsBoolean>(ret);
47 }
48 
EscompatJSONGetJSONStringifyIgnoreByName(EtsClass * cls,EtsString * name)49 EtsBoolean EscompatJSONGetJSONStringifyIgnoreByName(EtsClass *cls, EtsString *name)
50 {
51     EtsField *field = GetInstanceFieldByName(cls, name);
52     bool ret = false;
53     if (field == nullptr) {
54         return static_cast<EtsBoolean>(ret);
55     }
56     auto *runtimeClass = field->GetDeclaringClass()->GetRuntimeClass();
57     const panda_file::File &pf = *runtimeClass->GetPandaFile();
58     panda_file::FieldDataAccessor fda(pf, field->GetRuntimeField()->GetFileId());
59     fda.EnumerateAnnotations([&pf, &ret](panda_file::File::EntityId annId) {
60         panda_file::AnnotationDataAccessor ada(pf, annId);
61         const char *className = utf::Mutf8AsCString(pf.GetStringData(ada.GetClassId()).data);
62         if (className == panda_file_items::class_descriptors::JSON_STRINGIFY_IGNORE) {
63             ret = true;
64         }
65     });
66     return static_cast<EtsBoolean>(ret);
67 }
68 
EscompatJSONGetJSONParseIgnoreFromAnnotation(EtsClass * cls,EtsLong idx)69 EtsBoolean EscompatJSONGetJSONParseIgnoreFromAnnotation(EtsClass *cls, EtsLong idx)
70 {
71     EtsField *field = cls->GetFieldByIndex(idx);
72     bool ret = false;
73     if (field == nullptr) {
74         return static_cast<EtsBoolean>(ret);
75     }
76     auto *runtimeClass = field->GetDeclaringClass()->GetRuntimeClass();
77     const panda_file::File &pf = *runtimeClass->GetPandaFile();
78     panda_file::FieldDataAccessor fda(pf, field->GetRuntimeField()->GetFileId());
79     fda.EnumerateAnnotations([&pf, &ret](panda_file::File::EntityId annId) {
80         panda_file::AnnotationDataAccessor ada(pf, annId);
81         const char *className = utf::Mutf8AsCString(pf.GetStringData(ada.GetClassId()).data);
82         if (className == panda_file_items::class_descriptors::JSON_PARSE_IGNORE) {
83             ret = true;
84         }
85     });
86     return static_cast<EtsBoolean>(ret);
87 }
88 
EscompatJSONGetJSONRenameByIdx(EtsClass * cls,EtsLong idx)89 EtsString *EscompatJSONGetJSONRenameByIdx(EtsClass *cls, EtsLong idx)
90 {
91     auto *thread = ManagedThread::GetCurrent();
92     [[maybe_unused]] HandleScope<ObjectHeader *> scope(thread);
93 
94     EtsField *field = cls->GetFieldByIndex(idx);
95     VMHandle<EtsString> retStrHandle;
96     if (field == nullptr) {
97         return VMHandle<EtsString>(thread, EtsString::CreateNewEmptyString()->GetCoreType()).GetPtr();
98     }
99     auto *runtimeClass = field->GetDeclaringClass()->GetRuntimeClass();
100     const panda_file::File &pf = *runtimeClass->GetPandaFile();
101     panda_file::FieldDataAccessor fda(pf, field->GetRuntimeField()->GetFileId());
102     fda.EnumerateAnnotations([&pf, &retStrHandle, &thread](panda_file::File::EntityId annId) {
103         panda_file::AnnotationDataAccessor ada(pf, annId);
104         const char *className = utf::Mutf8AsCString(pf.GetStringData(ada.GetClassId()).data);
105         if (className == panda_file_items::class_descriptors::JSON_RENAME) {
106             const auto value = ada.GetElement(0).GetScalarValue();
107             const auto id = value.Get<panda_file::File::EntityId>();
108             auto stringData = pf.GetStringData(id);
109             retStrHandle = VMHandle<EtsString>(
110                 thread, EtsString::CreateFromMUtf8(reinterpret_cast<const char *>(stringData.data))->GetCoreType());
111         }
112     });
113     return retStrHandle.GetPtr();
114 }
115 
EscompatJSONGetJSONRenameByName(EtsClass * cls,EtsString * name)116 EtsString *EscompatJSONGetJSONRenameByName(EtsClass *cls, EtsString *name)
117 {
118     auto *thread = ManagedThread::GetCurrent();
119     [[maybe_unused]] HandleScope<ObjectHeader *> scope(thread);
120 
121     EtsField *field = GetInstanceFieldByName(cls, name);
122     VMHandle<EtsString> retStrHandle;
123     if (field == nullptr) {
124         return VMHandle<EtsString>(thread, EtsString::CreateNewEmptyString()->GetCoreType()).GetPtr();
125     }
126     auto *runtimeClass = field->GetDeclaringClass()->GetRuntimeClass();
127     const panda_file::File &pf = *runtimeClass->GetPandaFile();
128     panda_file::FieldDataAccessor fda(pf, field->GetRuntimeField()->GetFileId());
129     fda.EnumerateAnnotations([&pf, &retStrHandle, &thread](panda_file::File::EntityId annId) {
130         panda_file::AnnotationDataAccessor ada(pf, annId);
131         const char *className = utf::Mutf8AsCString(pf.GetStringData(ada.GetClassId()).data);
132         if (className == panda_file_items::class_descriptors::JSON_RENAME) {
133             const auto value = ada.GetElement(0).GetScalarValue();
134             const auto id = value.Get<panda_file::File::EntityId>();
135             auto stringData = pf.GetStringData(id);
136             retStrHandle = VMHandle<EtsString>(
137                 thread, EtsString::CreateFromMUtf8(reinterpret_cast<const char *>(stringData.data))->GetCoreType());
138         }
139     });
140     return retStrHandle.GetPtr();
141 }
142 
EscompatJSONStringifyFast(EtsObject * value)143 extern "C" EtsString *EscompatJSONStringifyFast(EtsObject *value)
144 {
145     auto coro = EtsCoroutine::GetCurrent();
146     ASSERT(coro->HasPendingException() == false);
147 
148     EtsHandleScope scope(coro);
149     EtsHandle<EtsObject> valueHandle(coro, value);
150 
151     helpers::JSONStringifier stringifier;
152     return stringifier.Stringify(valueHandle);
153 }
154 
155 }  // namespace ark::ets::intrinsics
156