1b1994897Sopenharmony_ci/** 2b1994897Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3b1994897Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4b1994897Sopenharmony_ci * you may not use this file except in compliance with the License. 5b1994897Sopenharmony_ci * You may obtain a copy of the License at 6b1994897Sopenharmony_ci * 7b1994897Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8b1994897Sopenharmony_ci * 9b1994897Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10b1994897Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11b1994897Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12b1994897Sopenharmony_ci * See the License for the specific language governing permissions and 13b1994897Sopenharmony_ci * limitations under the License. 14b1994897Sopenharmony_ci */ 15b1994897Sopenharmony_ci 16b1994897Sopenharmony_ci#ifndef ASSEMBLER_ASSEMBLY_FUNCTION_H 17b1994897Sopenharmony_ci#define ASSEMBLER_ASSEMBLY_FUNCTION_H 18b1994897Sopenharmony_ci 19b1994897Sopenharmony_ci#include <memory> 20b1994897Sopenharmony_ci#include <optional> 21b1994897Sopenharmony_ci#include <string> 22b1994897Sopenharmony_ci#include <string_view> 23b1994897Sopenharmony_ci#include <unordered_map> 24b1994897Sopenharmony_ci#include <vector> 25b1994897Sopenharmony_ci 26b1994897Sopenharmony_ci#include "assembly-ins.h" 27b1994897Sopenharmony_ci#include "assembly-label.h" 28b1994897Sopenharmony_ci#include "assembly-type.h" 29b1994897Sopenharmony_ci#include "assembly-debug.h" 30b1994897Sopenharmony_ci#include "assembly-file-location.h" 31b1994897Sopenharmony_ci#include "bytecode_emitter.h" 32b1994897Sopenharmony_ci#include "extensions/extensions.h" 33b1994897Sopenharmony_ci#include "file_items.h" 34b1994897Sopenharmony_ci#include "file_item_container.h" 35b1994897Sopenharmony_ci#include "ide_helpers.h" 36b1994897Sopenharmony_ci#include "meta.h" 37b1994897Sopenharmony_ci 38b1994897Sopenharmony_cinamespace panda::pandasm { 39b1994897Sopenharmony_ci 40b1994897Sopenharmony_cistruct Function { 41b1994897Sopenharmony_ci struct CatchBlock { 42b1994897Sopenharmony_ci std::string whole_line; 43b1994897Sopenharmony_ci std::string exception_record; 44b1994897Sopenharmony_ci std::string try_begin_label; 45b1994897Sopenharmony_ci std::string try_end_label; 46b1994897Sopenharmony_ci std::string catch_begin_label; 47b1994897Sopenharmony_ci std::string catch_end_label; 48b1994897Sopenharmony_ci }; 49b1994897Sopenharmony_ci 50b1994897Sopenharmony_ci struct TryCatchInfo { 51b1994897Sopenharmony_ci std::unordered_map<std::string_view, size_t> try_catch_labels; 52b1994897Sopenharmony_ci std::unordered_map<std::string, std::vector<const CatchBlock *>> try_catch_map; 53b1994897Sopenharmony_ci std::vector<std::string> try_catch_order; 54b1994897Sopenharmony_ci TryCatchInfo(std::unordered_map<std::string_view, size_t> &labels, 55b1994897Sopenharmony_ci std::unordered_map<std::string, std::vector<const CatchBlock *>> &map, 56b1994897Sopenharmony_ci std::vector<std::string> ¶m_try_catch_order) 57b1994897Sopenharmony_ci : try_catch_labels(labels), try_catch_map(map), try_catch_order(param_try_catch_order) 58b1994897Sopenharmony_ci { 59b1994897Sopenharmony_ci } 60b1994897Sopenharmony_ci }; 61b1994897Sopenharmony_ci 62b1994897Sopenharmony_ci struct Parameter { 63b1994897Sopenharmony_ci Type type; 64b1994897Sopenharmony_ci std::unique_ptr<ParamMetadata> metadata; 65b1994897Sopenharmony_ci 66b1994897Sopenharmony_ci Parameter(Type t, panda::panda_file::SourceLang lang) 67b1994897Sopenharmony_ci : type(std::move(t)), metadata(extensions::MetadataExtension::CreateParamMetadata(lang)) 68b1994897Sopenharmony_ci { 69b1994897Sopenharmony_ci } 70b1994897Sopenharmony_ci }; 71b1994897Sopenharmony_ci 72b1994897Sopenharmony_ci std::string name = ""; 73b1994897Sopenharmony_ci panda::panda_file::SourceLang language; 74b1994897Sopenharmony_ci std::unique_ptr<FunctionMetadata> metadata; 75b1994897Sopenharmony_ci 76b1994897Sopenharmony_ci std::unordered_map<std::string, panda::pandasm::Label> label_table; 77b1994897Sopenharmony_ci std::vector<panda::pandasm::Ins> ins; /* function instruction list */ 78b1994897Sopenharmony_ci std::vector<panda::pandasm::debuginfo::LocalVariable> local_variable_debug; 79b1994897Sopenharmony_ci std::string source_file; /* The file in which the function is defined or empty */ 80b1994897Sopenharmony_ci std::string source_code; 81b1994897Sopenharmony_ci std::vector<CatchBlock> catch_blocks; 82b1994897Sopenharmony_ci int64_t value_of_first_param = -1; 83b1994897Sopenharmony_ci size_t regs_num = 0; 84b1994897Sopenharmony_ci std::vector<Parameter> params; 85b1994897Sopenharmony_ci bool body_presence = false; 86b1994897Sopenharmony_ci Type return_type; 87b1994897Sopenharmony_ci SourceLocation body_location; 88b1994897Sopenharmony_ci std::optional<FileLocation> file_location; 89b1994897Sopenharmony_ci panda::panda_file::FunctionKind function_kind = panda::panda_file::FunctionKind::NONE; 90b1994897Sopenharmony_ci size_t slots_num = 0; 91b1994897Sopenharmony_ci std::vector<int> concurrent_module_requests; 92b1994897Sopenharmony_ci 93b1994897Sopenharmony_ci void SetSlotsNum(size_t num) 94b1994897Sopenharmony_ci { 95b1994897Sopenharmony_ci slots_num = num; 96b1994897Sopenharmony_ci } 97b1994897Sopenharmony_ci 98b1994897Sopenharmony_ci size_t GetSlotsNum() const 99b1994897Sopenharmony_ci { 100b1994897Sopenharmony_ci return slots_num; 101b1994897Sopenharmony_ci } 102b1994897Sopenharmony_ci 103b1994897Sopenharmony_ci void SetFunctionKind(panda::panda_file::FunctionKind kind) 104b1994897Sopenharmony_ci { 105b1994897Sopenharmony_ci function_kind = kind; 106b1994897Sopenharmony_ci } 107b1994897Sopenharmony_ci 108b1994897Sopenharmony_ci panda::panda_file::FunctionKind GetFunctionKind() const 109b1994897Sopenharmony_ci { 110b1994897Sopenharmony_ci return function_kind; 111b1994897Sopenharmony_ci } 112b1994897Sopenharmony_ci 113b1994897Sopenharmony_ci void SetInsDebug(const std::vector<debuginfo::Ins> &ins_debug) 114b1994897Sopenharmony_ci { 115b1994897Sopenharmony_ci ASSERT(ins_debug.size() == ins.size()); 116b1994897Sopenharmony_ci for (std::size_t i = 0; i < ins.size(); i++) { 117b1994897Sopenharmony_ci ins[i].ins_debug = ins_debug[i]; 118b1994897Sopenharmony_ci } 119b1994897Sopenharmony_ci } 120b1994897Sopenharmony_ci 121b1994897Sopenharmony_ci void AddInstruction(const panda::pandasm::Ins &instruction) 122b1994897Sopenharmony_ci { 123b1994897Sopenharmony_ci ins.emplace_back(instruction); 124b1994897Sopenharmony_ci } 125b1994897Sopenharmony_ci 126b1994897Sopenharmony_ci Function(std::string s, panda::panda_file::SourceLang lang, size_t b_l, size_t b_r, std::string f_c, bool d, 127b1994897Sopenharmony_ci size_t l_n) 128b1994897Sopenharmony_ci : name(std::move(s)), 129b1994897Sopenharmony_ci language(lang), 130b1994897Sopenharmony_ci metadata(extensions::MetadataExtension::CreateFunctionMetadata(lang)), 131b1994897Sopenharmony_ci file_location({f_c, b_l, b_r, l_n, d}) 132b1994897Sopenharmony_ci { 133b1994897Sopenharmony_ci } 134b1994897Sopenharmony_ci 135b1994897Sopenharmony_ci Function(std::string s, panda::panda_file::SourceLang lang) 136b1994897Sopenharmony_ci : name(std::move(s)), language(lang), metadata(extensions::MetadataExtension::CreateFunctionMetadata(lang)) 137b1994897Sopenharmony_ci { 138b1994897Sopenharmony_ci } 139b1994897Sopenharmony_ci 140b1994897Sopenharmony_ci std::size_t GetParamsNum() const 141b1994897Sopenharmony_ci { 142b1994897Sopenharmony_ci return params.size(); 143b1994897Sopenharmony_ci } 144b1994897Sopenharmony_ci 145b1994897Sopenharmony_ci std::size_t GetTotalRegs() const 146b1994897Sopenharmony_ci { 147b1994897Sopenharmony_ci return regs_num; 148b1994897Sopenharmony_ci } 149b1994897Sopenharmony_ci 150b1994897Sopenharmony_ci bool IsStatic() const 151b1994897Sopenharmony_ci { 152b1994897Sopenharmony_ci return (metadata->GetAccessFlags() & ACC_STATIC) != 0; 153b1994897Sopenharmony_ci } 154b1994897Sopenharmony_ci 155b1994897Sopenharmony_ci bool Emit(BytecodeEmitter &emitter, panda_file::MethodItem *method, 156b1994897Sopenharmony_ci const std::unordered_map<std::string, panda_file::BaseMethodItem *> &methods, 157b1994897Sopenharmony_ci const std::unordered_map<std::string, panda_file::BaseFieldItem *> &fields, 158b1994897Sopenharmony_ci const std::unordered_map<std::string, panda_file::BaseClassItem *> &classes, 159b1994897Sopenharmony_ci const std::unordered_map<std::string, panda_file::StringItem *> &strings, 160b1994897Sopenharmony_ci const std::unordered_map<std::string, panda_file::LiteralArrayItem *> &literalarrays) const; 161b1994897Sopenharmony_ci 162b1994897Sopenharmony_ci size_t GetLineNumber(size_t i) const; 163b1994897Sopenharmony_ci 164b1994897Sopenharmony_ci uint32_t GetColumnNumber(size_t i) const; 165b1994897Sopenharmony_ci 166b1994897Sopenharmony_ci struct LocalVariablePair { 167b1994897Sopenharmony_ci size_t insn_order; 168b1994897Sopenharmony_ci size_t variable_index; 169b1994897Sopenharmony_ci LocalVariablePair(size_t order, size_t index) : insn_order(order), variable_index(index) {} 170b1994897Sopenharmony_ci }; 171b1994897Sopenharmony_ci void CollectLocalVariable(std::vector<LocalVariablePair> &local_variable_info) const; 172b1994897Sopenharmony_ci void EmitLocalVariable(panda_file::LineNumberProgramItem *program, panda_file::ItemContainer *container, 173b1994897Sopenharmony_ci std::vector<uint8_t> *constant_pool, uint32_t &pc_inc, size_t instruction_number, 174b1994897Sopenharmony_ci size_t variable_index) const; 175b1994897Sopenharmony_ci void EmitNumber(panda_file::LineNumberProgramItem *program, std::vector<uint8_t> *constant_pool, uint32_t pc_inc, 176b1994897Sopenharmony_ci int32_t line_inc) const; 177b1994897Sopenharmony_ci void EmitLineNumber(panda_file::LineNumberProgramItem *program, std::vector<uint8_t> *constant_pool, 178b1994897Sopenharmony_ci int32_t &prev_line_number, uint32_t &pc_inc, size_t instruction_number) const; 179b1994897Sopenharmony_ci 180b1994897Sopenharmony_ci // column number is only for dynamic language now 181b1994897Sopenharmony_ci void EmitColumnNumber(panda_file::LineNumberProgramItem *program, std::vector<uint8_t> *constant_pool, 182b1994897Sopenharmony_ci uint32_t &prev_column_number, uint32_t &pc_inc, size_t instruction_number) const; 183b1994897Sopenharmony_ci 184b1994897Sopenharmony_ci void BuildLineNumberProgram(panda_file::DebugInfoItem *debug_item, const std::vector<uint8_t> &bytecode, 185b1994897Sopenharmony_ci panda_file::ItemContainer *container, std::vector<uint8_t> *constant_pool, 186b1994897Sopenharmony_ci bool emit_debug_info) const; 187b1994897Sopenharmony_ci 188b1994897Sopenharmony_ci Function::TryCatchInfo MakeOrderAndOffsets(const std::vector<uint8_t> &bytecode) const; 189b1994897Sopenharmony_ci 190b1994897Sopenharmony_ci std::vector<panda_file::CodeItem::TryBlock> BuildTryBlocks( 191b1994897Sopenharmony_ci panda_file::MethodItem *method, const std::unordered_map<std::string, panda_file::BaseClassItem *> &class_items, 192b1994897Sopenharmony_ci const std::vector<uint8_t> &bytecode) const; 193b1994897Sopenharmony_ci 194b1994897Sopenharmony_ci bool HasImplementation() const 195b1994897Sopenharmony_ci { 196b1994897Sopenharmony_ci return !metadata->IsForeign(); 197b1994897Sopenharmony_ci } 198b1994897Sopenharmony_ci 199b1994897Sopenharmony_ci bool IsParameter(uint32_t reg_number) const 200b1994897Sopenharmony_ci { 201b1994897Sopenharmony_ci return reg_number >= regs_num; 202b1994897Sopenharmony_ci } 203b1994897Sopenharmony_ci 204b1994897Sopenharmony_ci bool CanThrow() const 205b1994897Sopenharmony_ci { 206b1994897Sopenharmony_ci return std::any_of(ins.cbegin(), ins.cend(), [](const Ins &insn) { return insn.CanThrow(); }); 207b1994897Sopenharmony_ci } 208b1994897Sopenharmony_ci 209b1994897Sopenharmony_ci bool HasDebugInfo() const 210b1994897Sopenharmony_ci { 211b1994897Sopenharmony_ci return std::any_of(ins.cbegin(), ins.cend(), [](const Ins &insn) { return insn.HasDebugInfo(); }); 212b1994897Sopenharmony_ci } 213b1994897Sopenharmony_ci 214b1994897Sopenharmony_ci void DebugDump() const; 215b1994897Sopenharmony_ci 216b1994897Sopenharmony_ci std::set<std::string> CollectStringsFromFunctionInsns() const; 217b1994897Sopenharmony_ci}; 218b1994897Sopenharmony_ci 219b1994897Sopenharmony_ci} // namespace panda::pandasm 220b1994897Sopenharmony_ci 221b1994897Sopenharmony_ci#endif // ASSEMBLER_ASSEMBLY_FUNCTION_H 222