1 /*
2 * Copyright (c) 2022 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 "metadata/metadata_builder.h"
17 #include <cstring>
18 #include "securec.h"
19 #include "ast/ast_array_type.h"
20 #include "ast/ast_list_type.h"
21 #include "ast/ast_map_type.h"
22 #include "util/logger.h"
23
24 #define ALIGN8(v) (((v) + 7) & ~7)
25
26 namespace OHOS {
27 namespace Idl {
28 const char* MetadataBuilder::tag = "MetadataBuilder";
Build()29 std::shared_ptr<MetaComponent> MetadataBuilder::Build()
30 {
31 if (!module_->IsValid()) {
32 Logger::E(tag, "The module is not validate.");
33 return nullptr;
34 }
35
36 size_ = CalculateMetadataSize();
37 if (size_ > 0) {
38 void* metadata = calloc(size_, 1);
39 if (metadata == nullptr) {
40 Logger::E(tag, "Out of memory.");
41 return nullptr;
42 }
43 metaComponent_.reset(
44 new(metadata) MetaComponent, [](MetaComponent* p) { free(p); });
45
46 WriteMetadata(reinterpret_cast<uintptr_t>(metadata));
47 } else {
48 return nullptr;
49 }
50
51 return metaComponent_;
52 }
53
CalculateMetadataSize()54 size_t MetadataBuilder::CalculateMetadataSize()
55 {
56 baseAddr_ = 0;
57 CalculateMetaComponent(module_);
58 return baseAddr_;
59 }
60
CalculateMetaComponent(ASTModule * module)61 void MetadataBuilder::CalculateMetaComponent(ASTModule* module)
62 {
63 size_t namespaceNumber = module->GetNamespaceNumber();
64 size_t sequenceableNumber = module->GetSequenceableNumber();
65 size_t interfaceNumber = module->GetInterfaceNumber();
66 size_t typeNumber = module->GetTypeNumber();
67
68 // begin address
69 baseAddr_ = ALIGN8(baseAddr_);
70 // stringPool_'s address
71 stringPool_.Add(module_->GetName());
72 baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaComponent));
73 // namespaces_'s address
74 baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaNamespace*) * namespaceNumber);
75 // sequenceables_'s address
76 baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaSequenceable*) * sequenceableNumber);
77 // interfaces_'s address
78 baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaInterface*) * interfaceNumber);
79 // types_'s address
80 baseAddr_ = baseAddr_ + sizeof(MetaType*) * typeNumber;
81
82 for (size_t i = 0; i < namespaceNumber; i++) {
83 CalculateMetaNamespace(module->GetNamespace(i));
84 }
85
86 for (size_t i = 0; i < sequenceableNumber; i++) {
87 CalculateMetaSequenceable(module->GetSequenceable(i));
88 }
89
90 for (size_t i = 0; i < interfaceNumber; i++) {
91 CalculateMetaInterface(module->GetInterface(i));
92 }
93
94 const ASTModule::TypeStringMap& types = module_->GetTypes();
95 for (const auto& pair : types) {
96 CalculateMetaType(pair.second);
97 }
98
99 // end address
100 CalculateStringPool();
101 }
102
CalculateMetaNamespace(ASTNamespace * nspace)103 void MetadataBuilder::CalculateMetaNamespace(ASTNamespace* nspace)
104 {
105 size_t sequenceableNumber = nspace->GetSequenceableNumber();
106 size_t interfaceNumber = nspace->GetInterfaceNumber();
107 size_t namespaceNumber = nspace->GetNamespaceNumber();
108
109 // begin address
110 baseAddr_ = ALIGN8(baseAddr_);
111 stringPool_.Add(nspace->GetName());
112 // sequenceables_'s address
113 baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaNamespace));
114 // interfaces_'s address
115 baseAddr_ = ALIGN8(baseAddr_ + sizeof(int) * sequenceableNumber);
116 // namespaces_'s address
117 baseAddr_ = ALIGN8(baseAddr_ + sizeof(int) * interfaceNumber);
118 // end address
119 baseAddr_ = baseAddr_ + sizeof(MetaNamespace*) * namespaceNumber;
120
121 for (size_t i = 0; i < namespaceNumber; i++) {
122 CalculateMetaNamespace(nspace->GetNamespace(i));
123 }
124 }
125
CalculateMetaSequenceable(ASTSequenceableType * sequenceable)126 void MetadataBuilder::CalculateMetaSequenceable(ASTSequenceableType* sequenceable)
127 {
128 // begin address
129 baseAddr_ = ALIGN8(baseAddr_);
130 stringPool_.Add(sequenceable->GetName());
131 stringPool_.Add(sequenceable->GetNamespace()->ToString());
132 // end address
133 baseAddr_ = baseAddr_ + sizeof(MetaSequenceable);
134 }
135
CalculateMetaInterface(ASTInterfaceType * interface)136 void MetadataBuilder::CalculateMetaInterface(ASTInterfaceType* interface)
137 {
138 size_t methodNumber = interface->GetMethodNumber();
139
140 // begin address
141 baseAddr_ = ALIGN8(baseAddr_);
142 stringPool_.Add(interface->GetLicense());
143 stringPool_.Add(interface->GetName());
144 stringPool_.Add(interface->GetNamespace()->ToString());
145 // methods_'s address
146 baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaInterface));
147 // end address
148 baseAddr_ = baseAddr_ + sizeof(MetaMethod*) * methodNumber;
149
150 for (size_t i = 0; i < methodNumber; i++) {
151 CalculateMetaMethod(interface->GetMethod(i));
152 }
153 }
154
CalculateMetaMethod(ASTMethod * method)155 void MetadataBuilder::CalculateMetaMethod(ASTMethod* method)
156 {
157 size_t parameterNumber = method->GetParameterNumber();
158
159 // begin address
160 baseAddr_ = ALIGN8(baseAddr_);
161 stringPool_.Add(method->GetName());
162 stringPool_.Add(method->GetSignature());
163 // parameters_'s address
164 baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaMethod));
165 // end address
166 baseAddr_ = baseAddr_ + sizeof(MetaParameter*) * parameterNumber;
167
168 for (size_t i = 0; i < parameterNumber; i++) {
169 CalculateMetaParameter(method->GetParameter(i));
170 }
171 }
172
CalculateMetaParameter(ASTParameter * parameter)173 void MetadataBuilder::CalculateMetaParameter(ASTParameter* parameter)
174 {
175 // begin address
176 baseAddr_ = ALIGN8(baseAddr_);
177 stringPool_.Add(parameter->GetName());
178 // end address
179 baseAddr_ = baseAddr_ + sizeof(MetaParameter);
180 }
181
CalculateMetaType(ASTType * type)182 void MetadataBuilder::CalculateMetaType(ASTType* type)
183 {
184 // begin address
185 baseAddr_ = ALIGN8(baseAddr_);
186 // nestedTypeIndexes_'s address
187 baseAddr_ = baseAddr_ + sizeof(MetaType);
188 if (type->IsListType()) {
189 baseAddr_ = ALIGN8(baseAddr_);
190 // end address
191 baseAddr_ = baseAddr_ + sizeof(int*);
192 } else if (type->IsMapType()) {
193 // end address
194 size_t typeNumber = 2;
195 baseAddr_ = baseAddr_ + sizeof(int*) * typeNumber;
196 } else if (type->IsArrayType()) {
197 baseAddr_ = baseAddr_ + sizeof(int*);
198 }
199 }
200
CalculateStringPool()201 void MetadataBuilder::CalculateStringPool()
202 {
203 // begin address
204 baseAddr_ = ALIGN8(baseAddr_);
205 // end address
206 baseAddr_ = baseAddr_ + stringPool_.GetSize();
207 }
208
WriteMetadata(uintptr_t base)209 void MetadataBuilder::WriteMetadata(uintptr_t base)
210 {
211 baseAddr_ = base;
212 WriteMetaComponent(module_);
213 }
214
WriteMetaComponent(ASTModule * module)215 void MetadataBuilder::WriteMetaComponent(ASTModule* module)
216 {
217 size_t namespaceNumber = module->GetNamespaceNumber();
218 size_t sequenceableNumber = module->GetSequenceableNumber();
219 size_t interfaceNumber = module->GetInterfaceNumber();
220 size_t typeNumber = module->GetTypeNumber();
221 bool hasCacheableProxyMethods = module->GetHasCacheableProxyMethods();
222
223 // begin address
224 baseAddr_ = ALIGN8(baseAddr_);
225 MetaComponent* mc = reinterpret_cast<MetaComponent*>(baseAddr_);
226 mc->magic_ = METADATA_MAGIC_NUMBER;
227 mc->size_ = static_cast<int>(size_);
228 mc->namespaceNumber_ = static_cast<int>(namespaceNumber);
229 mc->sequenceableNumber_ = static_cast<int>(sequenceableNumber);
230 mc->interfaceNumber_ = static_cast<int>(interfaceNumber);
231 mc->typeNumber_ = static_cast<int>(typeNumber);
232 mc->hasCacheableProxyMethods_ = hasCacheableProxyMethods;
233 mc->stringPoolSize_ = stringPool_.GetSize();
234 // namespaces_'s address
235 baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaComponent));
236 mc->namespaces_ = reinterpret_cast<MetaNamespace**>(baseAddr_);
237 // sequenceables_'s address
238 baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaNamespace*) * namespaceNumber);
239 mc->sequenceables_ = reinterpret_cast<MetaSequenceable**>(baseAddr_);
240 // interfaces_'s address
241 baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaSequenceable*) * sequenceableNumber);
242 mc->interfaces_ = reinterpret_cast<MetaInterface**>(baseAddr_);
243 // types_'s address
244 baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaInterface*) * interfaceNumber);
245 mc->types_ = reinterpret_cast<MetaType**>(baseAddr_);
246 // stringPool_'s address
247 baseAddr_ = baseAddr_ + sizeof(MetaType*) * typeNumber;
248 mc->stringPool_ = reinterpret_cast<char*>(baseAddr_);
249 // end address
250 baseAddr_ = baseAddr_ + stringPool_.GetSize();
251 (void)memcpy_s(mc->stringPool_, stringPool_.GetSize(), stringPool_.GetData(), stringPool_.GetSize());
252
253 mc->name_ = WriteString(module->GetName());
254
255 for (size_t i = 0; i < namespaceNumber; i++) {
256 mc->namespaces_[i] = WriteMetaNamespace(module->GetNamespace(i));
257 }
258
259 for (size_t i = 0; i < sequenceableNumber; i++) {
260 mc->sequenceables_[i] = WriteMetaSequenceable(module->GetSequenceable(i));
261 }
262
263 for (size_t i = 0; i < interfaceNumber; i++) {
264 mc->interfaces_[i] = WriteMetaInterface(module->GetInterface(i));
265 }
266
267 const ASTModule::TypeStringMap& types = module->GetTypes();
268 int i = 0;
269 for (const auto& pair : types) {
270 mc->types_[i++] = WriteMetaType(pair.second);
271 }
272 }
273
WriteMetaNamespace(ASTNamespace * nspace)274 MetaNamespace* MetadataBuilder::WriteMetaNamespace(ASTNamespace* nspace)
275 {
276 size_t sequenceableNumber = nspace->GetSequenceableNumber();
277 size_t interfaceNumber = nspace->GetInterfaceNumber();
278 size_t namespaceNumber = nspace->GetNamespaceNumber();
279
280 // begin address
281 baseAddr_ = ALIGN8(baseAddr_);
282 MetaNamespace* mn = reinterpret_cast<MetaNamespace*>(baseAddr_);
283 mn->name_ = WriteString(nspace->GetName());
284 mn->sequenceableNumber_ = static_cast<int>(sequenceableNumber);
285 mn->interfaceNumber_ = static_cast<int>(interfaceNumber);
286 mn->namespaceNumber_ = static_cast<int>(namespaceNumber);
287 // sequenceables_'s address
288 baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaNamespace));
289 mn->sequenceableIndexes_ = reinterpret_cast<int*>(baseAddr_);
290 // interfaces_'s address
291 baseAddr_ = ALIGN8(baseAddr_ + sizeof(int) * sequenceableNumber);
292 mn->interfaceIndexes_ = reinterpret_cast<int*>(baseAddr_);
293 // namespaces_'s address
294 baseAddr_ = ALIGN8(baseAddr_ + sizeof(int) * interfaceNumber);
295 mn->namespaces_ = reinterpret_cast<MetaNamespace**>(baseAddr_);
296 // end address
297 baseAddr_ = baseAddr_ + sizeof(MetaNamespace*) * namespaceNumber;
298
299 for (size_t i = 0; i < sequenceableNumber; i++) {
300 AutoPtr<ASTSequenceableType> sequenceable = nspace->GetSequenceable(i);
301 mn->sequenceableIndexes_[i] = module_->IndexOf(sequenceable);
302 }
303
304 for (size_t i = 0; i < interfaceNumber; i++) {
305 AutoPtr<ASTInterfaceType> interface = nspace->GetInterface(i);
306 mn->interfaceIndexes_[i] = module_->IndexOf(interface);
307 }
308
309 for (size_t i = 0; i < namespaceNumber; i++) {
310 AutoPtr<ASTNamespace> inner = nspace->GetNamespace(i);
311 mn->namespaces_[i] = WriteMetaNamespace(inner);
312 }
313
314 return mn;
315 }
316
WriteMetaSequenceable(ASTSequenceableType * parcelabe)317 MetaSequenceable* MetadataBuilder::WriteMetaSequenceable(ASTSequenceableType* parcelabe)
318 {
319 // begin address
320 baseAddr_ = ALIGN8(baseAddr_);
321 MetaSequenceable* mp = reinterpret_cast<MetaSequenceable*>(baseAddr_);
322 mp->name_ = WriteString(parcelabe->GetName());
323 mp->namespace_ = WriteString(parcelabe->GetNamespace()->ToString());
324 // end address
325 baseAddr_ = baseAddr_ + sizeof(MetaSequenceable);
326
327 return mp;
328 }
329
WriteMetaInterface(ASTInterfaceType * interface)330 MetaInterface* MetadataBuilder::WriteMetaInterface(ASTInterfaceType* interface)
331 {
332 size_t methodNumber = interface->GetMethodNumber();
333
334 // begin address
335 baseAddr_ = ALIGN8(baseAddr_);
336 MetaInterface* mi = reinterpret_cast<MetaInterface*>(baseAddr_);
337 mi->license_ = WriteString(interface->GetLicense());
338 mi->name_ = WriteString(interface->GetName());
339 mi->namespace_ = WriteString(interface->GetNamespace()->ToString());
340 mi->properties_ = interface->IsOneway() ? INTERFACE_PROPERTY_ONEWAY : 0;
341 mi->methodNumber_ = static_cast<int>(methodNumber);
342 mi->external_ = interface->IsExternal();
343 // methods_'s address
344 baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaInterface));
345 mi->methods_ = reinterpret_cast<MetaMethod**>(baseAddr_);
346 // end address
347 baseAddr_ = baseAddr_ + sizeof(MetaMethod*) * methodNumber;
348
349 for (size_t i = 0; i < methodNumber; i++) {
350 mi->methods_[i] = WriteMetaMethod(interface->GetMethod(i));
351 }
352
353 return mi;
354 }
355
WriteMetaMethod(ASTMethod * method)356 MetaMethod* MetadataBuilder::WriteMetaMethod(ASTMethod* method)
357 {
358 size_t parameterNumber = method->GetParameterNumber();
359
360 // begin address
361 baseAddr_ = ALIGN8(baseAddr_);
362 MetaMethod* mm = reinterpret_cast<MetaMethod*>(baseAddr_);
363 mm->name_ = WriteString(method->GetName());
364 mm->signature_ = WriteString(method->GetSignature());
365 mm->properties_ = method->IsOneway() ? METHOD_PROPERTY_ONEWAY : 0;
366 mm->returnTypeIndex_ = module_->IndexOf(method->GetReturnType());
367 // cacheable time
368 mm->cacheable_ = method->GetCacheable();
369 if (mm->cacheable_ == true) {
370 mm->cacheabletime_ = method->GetCacheableTime();
371 }
372 mm->parameterNumber_ = static_cast<int>(parameterNumber);
373 // parameters_'s address
374 baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaMethod));
375 mm->parameters_ = reinterpret_cast<MetaParameter**>(baseAddr_);
376 // end address
377 baseAddr_ = baseAddr_ + sizeof(MetaParameter*) * parameterNumber;
378
379 for (size_t i = 0; i < parameterNumber; i++) {
380 mm->parameters_[i] = WriteMetaParameter(method->GetParameter(i));
381 }
382
383 return mm;
384 }
385
WriteMetaParameter(ASTParameter * parameter)386 MetaParameter* MetadataBuilder::WriteMetaParameter(ASTParameter* parameter)
387 {
388 // begin address
389 baseAddr_ = ALIGN8(baseAddr_);
390 MetaParameter* mp = reinterpret_cast<MetaParameter*>(baseAddr_);
391 mp->name_ = WriteString(parameter->GetName());
392 if (parameter->IsInParameter()) {
393 mp->attributes_ |= ATTR_IN;
394 }
395 if (parameter->IsOutParameter()) {
396 mp->attributes_ |= ATTR_OUT;
397 }
398 mp->typeIndex_ = module_->IndexOf(parameter->GetType());
399 // end address
400 baseAddr_ = baseAddr_ + sizeof(MetaParameter);
401
402 return mp;
403 }
404
WriteMetaType(ASTType * type)405 MetaType* MetadataBuilder::WriteMetaType(ASTType* type)
406 {
407 // begin address
408 baseAddr_ = ALIGN8(baseAddr_);
409 MetaType* mt = reinterpret_cast<MetaType*>(baseAddr_);
410 mt->kind_ = Type2Kind(type);
411 if (type->IsSequenceableType()) {
412 mt->index_ = module_->IndexOf(static_cast<ASTSequenceableType*>(type));
413 } else if (type->IsInterfaceType()) {
414 mt->index_ = module_->IndexOf(static_cast<ASTInterfaceType*>(type));
415 } else {
416 mt->index_ = module_->IndexOf(type);
417 }
418 baseAddr_ = baseAddr_ + sizeof(MetaType);
419 if (type->IsListType()) {
420 mt->nestedTypeNumber_ = 1;
421 // nestedTypeIndexes_'s address
422 baseAddr_ = ALIGN8(baseAddr_);
423 mt->nestedTypeIndexes_ = reinterpret_cast<int*>(baseAddr_);
424 AutoPtr<ASTType> elementType = (static_cast<ASTListType*>(type))->GetElementType();
425 mt->nestedTypeIndexes_[0] = module_->IndexOf(elementType);
426 // end address
427 baseAddr_ = baseAddr_ + sizeof(int*);
428 } else if (type->IsMapType()) {
429 size_t typeNumber = 2;
430 mt->nestedTypeNumber_ = static_cast<int>(typeNumber);
431 // nestedTypeIndexes_'s address
432 baseAddr_ = ALIGN8(baseAddr_);
433 mt->nestedTypeIndexes_ = reinterpret_cast<int*>(baseAddr_);
434 AutoPtr<ASTType> keyType = (static_cast<ASTMapType*>(type))->GetKeyType();
435 AutoPtr<ASTType> valueType = (static_cast<ASTMapType*>(type))->GetValueType();
436 mt->nestedTypeIndexes_[0] = module_->IndexOf(keyType);
437 mt->nestedTypeIndexes_[1] = module_->IndexOf(valueType);
438 // end address
439 baseAddr_ = baseAddr_ + sizeof(int*) * typeNumber;
440 } else if (type->IsArrayType()) {
441 mt->nestedTypeNumber_ = 1;
442 // nestedTypeIndexes_'s address
443 baseAddr_ = ALIGN8(baseAddr_);
444 mt->nestedTypeIndexes_ = reinterpret_cast<int*>(baseAddr_);
445 AutoPtr<ASTType> elementType = (static_cast<ASTArrayType*>(type))->GetElementType();
446 mt->nestedTypeIndexes_[0] = module_->IndexOf(elementType);
447 // end address
448 baseAddr_ = baseAddr_ + sizeof(int*);
449 }
450
451 return mt;
452 }
453
WriteString(const String & string)454 char* MetadataBuilder::WriteString(const String& string)
455 {
456 return string.IsNull() ? nullptr : metaComponent_->stringPool_ + stringPool_.GetOffset(string);
457 }
458
Type2Kind(ASTType * type)459 TypeKind MetadataBuilder::Type2Kind(ASTType* type)
460 {
461 if (type->IsCharType()) {
462 return TypeKind::Char;
463 } else if (type->IsBooleanType()) {
464 return TypeKind::Boolean;
465 } else if (type->IsByteType()) {
466 return TypeKind::Byte;
467 } else if (type->IsShortType()) {
468 return TypeKind::Short;
469 } else if (type->IsIntegerType()) {
470 return TypeKind::Integer;
471 } else if (type->IsLongType()) {
472 return TypeKind::Long;
473 } else if (type->IsFloatType()) {
474 return TypeKind::Float;
475 } else if (type->IsDoubleType()) {
476 return TypeKind::Double;
477 } else if (type->IsStringType()) {
478 return TypeKind::String;
479 } else if (type->IsVoidType()) {
480 return TypeKind::Void;
481 } else if (type->IsSequenceableType()) {
482 return TypeKind::Sequenceable;
483 } else if (type->IsInterfaceType()) {
484 return TypeKind::Interface;
485 } else if (type->IsListType()) {
486 return TypeKind::List;
487 } else if (type->IsMapType()) {
488 return TypeKind::Map;
489 } else if (type->IsArrayType()) {
490 return TypeKind::Array;
491 }
492 return TypeKind::Unknown;
493 }
494 } // namespace Idl
495 } // namespace OHOS
496