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