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 "assemblyFunctionProto.h"
17 #include "libpandafile/file_items.h"
18
19 namespace panda::proto {
Serialize(const panda::pandasm::Function::CatchBlock & block,protoPanda::CatchBlock & protoBlock)20 void CatchBlock::Serialize(const panda::pandasm::Function::CatchBlock &block, protoPanda::CatchBlock &protoBlock)
21 {
22 protoBlock.set_wholeline(block.whole_line);
23 protoBlock.set_exceptionrecord(block.exception_record);
24 protoBlock.set_trybeginlabel(block.try_begin_label);
25 protoBlock.set_tryendlabel(block.try_end_label);
26 protoBlock.set_catchbeginlabel(block.catch_begin_label);
27 protoBlock.set_catchendlabel(block.catch_end_label);
28 }
29
Deserialize(const protoPanda::CatchBlock & protoBlock,panda::pandasm::Function::CatchBlock & block)30 void CatchBlock::Deserialize(const protoPanda::CatchBlock &protoBlock, panda::pandasm::Function::CatchBlock &block)
31 {
32 block.whole_line = protoBlock.wholeline();
33 block.exception_record = protoBlock.exceptionrecord();
34 block.try_begin_label = protoBlock.trybeginlabel();
35 block.try_end_label = protoBlock.tryendlabel();
36 block.catch_begin_label = protoBlock.catchbeginlabel();
37 block.catch_end_label = protoBlock.catchendlabel();
38 }
39
Serialize(const panda::pandasm::Function::Parameter & param,protoPanda::Parameter & protoParam)40 void Parameter::Serialize(const panda::pandasm::Function::Parameter ¶m, protoPanda::Parameter &protoParam)
41 {
42 auto *type = protoParam.mutable_type();
43 Type::Serialize(param.type, *type);
44 }
45
Serialize(const panda::pandasm::Function & function,protoPanda::Function & protoFunction)46 void Function::Serialize(const panda::pandasm::Function &function, protoPanda::Function &protoFunction)
47 {
48 protoFunction.set_name(function.name);
49 protoFunction.set_language(static_cast<uint32_t>(function.language));
50
51 auto *protoFuncMeta = protoFunction.mutable_metadata();
52 FunctionMetadata::Serialize(*function.metadata, *protoFuncMeta);
53
54 for (const auto &[name, label] : function.label_table) {
55 auto *labelMap = protoFunction.add_labeltable();
56 labelMap->set_key(name);
57 auto *protoLabel = labelMap->mutable_value();
58 Label::Serialize(label, *protoLabel);
59 }
60
61 for (const auto &insn : function.ins) {
62 auto *protoIns = protoFunction.add_ins();
63 Ins::Serialize(insn, *protoIns);
64 }
65
66 for (const auto &debug : function.local_variable_debug) {
67 auto *protoDebug = protoFunction.add_localvariabledebug();
68 LocalVariable::Serialize(debug, *protoDebug);
69 }
70
71 protoFunction.set_sourcefile(function.source_file);
72 protoFunction.set_sourcecode(function.source_code);
73
74 for (const auto &block : function.catch_blocks) {
75 auto *protoBlock = protoFunction.add_catchblocks();
76 CatchBlock::Serialize(block, *protoBlock);
77 }
78
79 protoFunction.set_valueoffirstparam(function.value_of_first_param);
80 protoFunction.set_regsnum(function.regs_num);
81
82 for (const auto ¶m : function.params) {
83 auto *protoParam = protoFunction.add_params();
84 Parameter::Serialize(param, *protoParam);
85 }
86
87 protoFunction.set_bodypresence(function.body_presence);
88
89 auto *protoReturnType = protoFunction.mutable_returntype();
90 Type::Serialize(function.return_type, *protoReturnType);
91
92 auto *protoBodyLocation = protoFunction.mutable_bodylocation();
93 SourceLocation::Serialize(function.body_location, *protoBodyLocation);
94
95 const auto &fileLocation = function.file_location;
96 if (fileLocation.has_value()) {
97 auto *protoFileLocation = protoFunction.mutable_filelocation();
98 FileLocation::Serialize(fileLocation.value(), *protoFileLocation);
99 }
100 protoFunction.set_function_kind(static_cast<uint8_t>(function.function_kind));
101 protoFunction.set_slotsnum(function.slots_num);
102
103 for (const auto &moduleRequestId : function.concurrent_module_requests) {
104 protoFunction.add_concurrent_module_requests(moduleRequestId);
105 }
106 }
107
DeserializeLabels(const protoPanda::Function & protoFunction,panda::pandasm::Function & function,panda::ArenaAllocator * allocator)108 void Function::DeserializeLabels(const protoPanda::Function &protoFunction, panda::pandasm::Function &function,
109 panda::ArenaAllocator *allocator)
110 {
111 function.label_table.reserve(protoFunction.labeltable_size());
112 for (const auto &labelUnit : protoFunction.labeltable()) {
113 auto &name = labelUnit.key();
114 auto &protoLabel = labelUnit.value();
115 panda::pandasm::Label label(name);
116 Label::Deserialize(protoLabel, label);
117 function.label_table.insert({name, label});
118 }
119 }
120
DeserializeProtoIns(const protoPanda::Function & protoFunction,panda::pandasm::Function & function,panda::ArenaAllocator * allocator)121 void Function::DeserializeProtoIns(const protoPanda::Function &protoFunction, panda::pandasm::Function &function,
122 panda::ArenaAllocator *allocator)
123 {
124 function.ins.reserve(protoFunction.ins_size());
125 for (const auto &protoIns : protoFunction.ins()) {
126 panda::pandasm::Ins ins;
127 Ins::Deserialize(protoIns, ins);
128 function.ins.emplace_back(std::move(ins));
129 }
130 }
131
DeserializeProtoLocalVariable(const protoPanda::Function & protoFunction,panda::pandasm::Function & function,panda::ArenaAllocator * allocator)132 void Function::DeserializeProtoLocalVariable(const protoPanda::Function &protoFunction,
133 panda::pandasm::Function &function,
134 panda::ArenaAllocator *allocator)
135 {
136 function.local_variable_debug.reserve(protoFunction.localvariabledebug_size());
137 for (const auto &protoLocalVariable : protoFunction.localvariabledebug()) {
138 panda::pandasm::debuginfo::LocalVariable localVariable;
139 LocalVariable::Deserialize(protoLocalVariable, localVariable);
140 function.local_variable_debug.emplace_back(std::move(localVariable));
141 }
142 }
143
Deserialize(const protoPanda::Function & protoFunction,panda::pandasm::Function & function,panda::ArenaAllocator * allocator)144 void Function::Deserialize(const protoPanda::Function &protoFunction, panda::pandasm::Function &function,
145 panda::ArenaAllocator *allocator)
146 {
147 FunctionMetadata::Deserialize(protoFunction.metadata(), function.metadata, allocator);
148 DeserializeLabels(protoFunction, function, allocator);
149 DeserializeProtoIns(protoFunction, function, allocator);
150 DeserializeProtoLocalVariable(protoFunction, function, allocator);
151
152 function.source_file = protoFunction.sourcefile();
153 function.source_code = protoFunction.sourcecode();
154
155 function.catch_blocks.reserve(protoFunction.catchblocks_size());
156 for (const auto &protoCatchBlock : protoFunction.catchblocks()) {
157 auto *catchBlock = allocator->New<panda::pandasm::Function::CatchBlock>();
158 CHECK_NOT_NULL(catchBlock);
159 CatchBlock::Deserialize(protoCatchBlock, *catchBlock);
160 function.catch_blocks.emplace_back(std::move(*catchBlock));
161 }
162
163 function.value_of_first_param = protoFunction.valueoffirstparam();
164 function.regs_num = protoFunction.regsnum();
165
166 function.params.reserve(protoFunction.params_size());
167 for (const auto &protoParam : protoFunction.params()) {
168 auto ¶mType = Type::Deserialize(protoParam.type(), allocator);
169 panda::pandasm::Function::Parameter param(paramType, panda::panda_file::SourceLang::ECMASCRIPT);
170 function.params.emplace_back(std::move(param));
171 }
172
173 function.body_presence = protoFunction.bodypresence();
174 function.return_type = Type::Deserialize(protoFunction.returntype(), allocator);
175 SourceLocation::Deserialize(protoFunction.bodylocation(), function.body_location);
176
177 if (protoFunction.has_filelocation()) {
178 FileLocation::Deserialize(protoFunction.filelocation(), function.file_location);
179 }
180 function.SetFunctionKind(static_cast<panda::panda_file::FunctionKind>(protoFunction.function_kind()));
181 function.SetSlotsNum(protoFunction.slotsnum());
182
183 for (const auto &moduleRequestId : protoFunction.concurrent_module_requests()) {
184 function.concurrent_module_requests.emplace_back(moduleRequestId);
185 }
186 }
187 } // panda::proto
188