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