1 /** 2 * Copyright (c) 2021-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 #ifndef ES2PANDA_COMPILER_IR_EMITTER_H 17 #define ES2PANDA_COMPILER_IR_EMITTER_H 18 19 #include <assembly-literals.h> 20 #include <compiler/core/emitter/moduleRecordEmitter.h> 21 #include <ir/astNode.h> 22 #include <lexer/token/sourceLocation.h> 23 #include <macros.h> 24 #include <util/patchFix.h> 25 #include <util/ustring.h> 26 27 #include <list> 28 #include <mutex> 29 #include <string> 30 #include <unordered_map> 31 #include <unordered_set> 32 #include <vector> 33 34 namespace panda::pandasm { 35 struct Program; 36 struct Function; 37 class Ins; 38 struct Record; 39 } // namespace panda::pandasm 40 41 namespace panda::es2panda::ir { 42 class Statement; 43 } // namespace panda::es2panda::ir 44 45 namespace panda::es2panda::binder { 46 class Scope; 47 } // namespace panda::es2panda::binder 48 49 namespace panda::es2panda::compiler { 50 class PandaGen; 51 class LiteralBuffer; 52 class DebugInfo; 53 class Label; 54 class IRNode; 55 class CompilerContext; 56 57 using Literal = panda::pandasm::LiteralArray::Literal; 58 59 class FunctionEmitter { 60 public: 61 explicit FunctionEmitter(ArenaAllocator *allocator, const PandaGen *pg); 62 ~FunctionEmitter() = default; 63 NO_COPY_SEMANTIC(FunctionEmitter); 64 NO_MOVE_SEMANTIC(FunctionEmitter); 65 Function()66 panda::pandasm::Function *Function() 67 { 68 return func_; 69 } 70 LiteralBuffers()71 auto &LiteralBuffers() 72 { 73 return literalBuffers_; 74 } 75 LiteralArrays()76 auto &LiteralArrays() 77 { 78 return literalArrays_; 79 } 80 ExternalAnnotationRecords()81 auto &ExternalAnnotationRecords() 82 { 83 return externalAnnotationRecords_; 84 } 85 86 void Generate(util::PatchFix *patchFixHelper); 87 const ArenaSet<util::StringView> &Strings() const; 88 89 private: 90 uint32_t UpdateForReturnIns(const ir::AstNode *astNode, panda::pandasm::Ins *pandaIns); 91 void GenInstructionDebugInfo(const IRNode *ins, panda::pandasm::Ins *pandaIns); 92 void GenFunctionInstructions(); 93 void GenFunctionCatchTables(); 94 void GenScopeVariableInfo(const binder::Scope *scope); 95 void GenSourceFileDebugInfo(); 96 void GenVariablesDebugInfo(); 97 void GenFunctionKind(); 98 void GenIcSize(); 99 pandasm::AnnotationElement CreateAnnotationElement(const std::string &propName, const ir::Expression *initValue); 100 pandasm::AnnotationData CreateAnnotation(const ir::Annotation *anno); 101 void GenAnnotations(); 102 util::StringView SourceCode() const; 103 lexer::LineIndex &GetLineIndex() const; 104 105 void GenLiteralBuffers(); 106 void GenBufferLiterals(const LiteralBuffer *buff); 107 void GenConcurrentFunctionModuleRequests(); 108 void GenConcurrentModuleRequestsAnnotation(); 109 void GenExpectedPropertyCountAnnotation(); 110 void GenSlotNumberAnnotation(); 111 bool NeedToAddColumnForPandaIns(panda::pandasm::Ins *pandaIns); 112 113 const PandaGen *pg_; 114 panda::pandasm::Function *func_ {}; 115 ArenaVector<std::pair<int32_t, std::vector<Literal>>> literalBuffers_; 116 size_t offset_ {0}; 117 118 ArenaVector<std::pair<std::string, std::vector<Literal>>> literalArrays_; 119 ArenaVector<panda::pandasm::Record> externalAnnotationRecords_; 120 }; 121 122 class Emitter { 123 public: 124 explicit Emitter(CompilerContext *context); 125 ~Emitter(); 126 NO_COPY_SEMANTIC(Emitter); 127 NO_MOVE_SEMANTIC(Emitter); 128 129 void AddAnnotationRecord(const std::string &annoName, const ir::ClassDeclaration *classDecl); 130 void AddFunction(FunctionEmitter *func, CompilerContext *context); 131 void AddSourceTextModuleRecord(ModuleRecordEmitter *module, CompilerContext *context); 132 void AddScopeNamesRecord(CompilerContext *context); 133 static void GenBufferLiterals(ArenaVector<std::pair<int32_t, std::vector<Literal>>> &literalBuffers, 134 const LiteralBuffer *buff); 135 static void DumpAsm(const panda::pandasm::Program *prog); 136 panda::pandasm::Program *Finalize(bool dumpDebugInfo, util::PatchFix *patchFixHelper); 137 panda::pandasm::Program *GetProgram() const; 138 void GenJsonContentRecord(const CompilerContext *context); 139 void GenRecordNameInfo() const; GetEmitterLock()140 std::mutex &GetEmitterLock() 141 { 142 return m_; 143 }; 144 GetConstantLocalExportSlots()145 const std::unordered_set<uint32_t> &GetConstantLocalExportSlots() 146 { 147 return constant_local_export_slots_; 148 } 149 150 static std::vector<std::pair<std::string, std::vector<Literal>>> CreateLiteralArray(const ir::Expression *array, 151 const std::string &baseName); 152 153 private: 154 void CreateStringClass(); 155 panda::pandasm::Type DeduceArrayEnumType(const ir::Expression *value, uint8_t rank, bool &needToCreateArrayValue); 156 157 void SetCommonjsField(bool isCommonjs); 158 void SetPkgNameField(const std::string &pkgName); 159 void GenCommonjsRecord() const; 160 void AddConcurrentModuleRequestsRecord(); 161 void AddHasTopLevelAwaitRecord(bool hasTLA, const CompilerContext *context); 162 void AddSharedModuleRecord(const CompilerContext *context); 163 void AddSlotNumberRecord(); 164 void AddModuleRequestPhaseRecord(ModuleRecordEmitter *module, CompilerContext *context); 165 void AddExpectedPropertyCountRecord(); 166 167 void CreateEnumProp(const ir::ClassProperty *prop, const std::string &annoName, panda::pandasm::Field &annoProp); 168 void CreateLiteralArrayProp(const ir::ClassProperty *prop, const std::string &annoName, 169 panda::pandasm::Field &annoProp); 170 panda::pandasm::Field CreateAnnotationProp(const ir::ClassProperty *prop, 171 const std::string &annoName); 172 173 std::mutex m_; 174 panda::pandasm::Program *prog_; 175 panda::pandasm::Record *rec_; 176 pandasm::extensions::Language source_lang_ = pandasm::extensions::DEFAULT_LANGUAGE; 177 // Constant local export module variable slots. 178 // Used by the branch elimination optimization to identify initial constants. 179 // Should be replaced by analyzing the stconstmodulevar instruction in the 180 // bytecode file after it is introduced 181 std::unordered_set<uint32_t> constant_local_export_slots_; 182 }; 183 } // namespace panda::es2panda::compiler 184 185 #endif 186