1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 #ifndef CMAJOR_CODEGENSX_SYSTEMX_CODEGENERATOR_INCLUDED
  7 #define CMAJOR_CODEGENSX_SYSTEMX_CODEGENERATOR_INCLUDED
  8 #include <cmajor/codegensx/CodeGenSxApi.hpp>
  9 #include <cmajor/codegenbase/CodeGenerator.hpp>
 10 #include <cmajor/cmsxi/CompileUnit.hpp>
 11 #include <cmajor/binder/BoundNodeVisitor.hpp>
 12 #include <cmajor/binder/BoundStatement.hpp>
 13 #include <cmajor/binder/BoundClass.hpp>
 14 #include <cmajor/symbols/SymbolTable.hpp>
 15 #include <cmajor/symbols/Module.hpp>
 16 #include <cmajor/ir/Emitter.hpp>
 17 
 18 namespace cmajor { namespace codegensx {
 19 
 20 using namespace cmajor::binder;
 21 using namespace cmajor::symbols;
 22 
 23 const int64_t fileInfoNodeType = 0;
 24 const int64_t funcInfoNodeType = 1;
 25 const int64_t lineInfoNodeType = 2;
 26 const int64_t beginTryNodeType = 3;
 27 const int64_t endTryNodeType = 4;
 28 const int64_t catchNodeType = 5;
 29 
 30 struct Cleanup 
 31 {
 32     Cleanup(void* cleanupBlock_) : cleanupBlock(cleanupBlock_) {}
 33     void* cleanupBlock;
 34     std::vector<std::std::unique_ptr<BoundFunctionCall>>destructors;
 35 };
 36 
 37 class SystemXCodeGenerator public cmajor::codegenbase::CodeGeneratorpublic BoundNodeVisitorpublic cmajor::ir::EmittingDelegate
 38 {
 39 public:
 40     SystemXCodeGenerator(cmajor::ir::EmittingContext& emittingContext_);
 41     SystemXCodeGenerator(const SystemXCodeGenerator&) = delete;
 42     SystemXCodeGenerator& operator=(const SystemXCodeGenerator&) = delete;
 43     void GenerateCode(void* boundCompileUnit) override;
 44     void Visit(BoundCompileUnit& boundCompileUnit) override;
 45     void Visit(BoundNamespace& boundNamespace) override;
 46     void Visit(BoundClass& boundClass) override;
 47     void Visit(BoundFunction& boundFunction) override;
 48     void Visit(BoundCompoundStatement& boundCompoundStatement) override;
 49     void Visit(BoundReturnStatement& boundReturnStatement) override;
 50     void Visit(BoundGotoCaseStatement& boundGotoCaseStatement) override;
 51     void Visit(BoundGotoDefaultStatement& boundGotoDefaultStatement) override;
 52     void Visit(BoundBreakStatement& boundBreakStatement) override;
 53     void Visit(BoundContinueStatement& boundContinueStatement) override;
 54     void Visit(BoundGotoStatement& boundGotoStatement) override;
 55     void Visit(BoundSequenceStatement& boundSequenceStatement) override;
 56     void Visit(BoundIfStatement& boundIfStatement) override;
 57     void Visit(BoundWhileStatement& boundWhileStatement) override;
 58     void Visit(BoundDoStatement& boundDoStatement) override;
 59     void Visit(BoundForStatement& boundForStatement) override;
 60     void Visit(BoundSwitchStatement& boundSwitchStatement) override;
 61     void Visit(BoundCaseStatement& boundCaseStatement) override;
 62     void Visit(BoundDefaultStatement& boundDefaultStatement) override;
 63     void Visit(BoundExpressionStatement& boundExpressionStatement) override;
 64     void Visit(BoundInitializationStatement& boundInitializationStatement) override;
 65     void Visit(BoundConstructionStatement& boundConstructionStatement) override;
 66     void Visit(BoundAssignmentStatement& boundAssignmentStatement) override;
 67     void Visit(BoundEmptyStatement& boundEmptyStatement) override;
 68     void Visit(BoundSetVmtPtrStatement& boundSetVmtPtrStatement) override;
 69     void Visit(BoundThrowStatement& boundThrowStatement) override;
 70     void Visit(BoundTryStatement& boundTryStatement) override;
 71     void Visit(BoundCatchStatement& boundCatchStatement) override;
 72     void Visit(BoundRethrowStatement& boundRethrowStatement) override;
 73     void Visit(BoundParameter& boundParameter) override;
 74     void Visit(BoundLocalVariable& boundLocalVariable) override;
 75     void Visit(BoundMemberVariable& boundMemberVariable) override;
 76     void Visit(BoundConstant& boundConstant) override;
 77     void Visit(BoundEnumConstant& boundEnumConstant) override;
 78     void Visit(BoundLiteral& boundLiteral) override;
 79     void Visit(BoundTemporary& boundTemporary) override;
 80     void Visit(BoundSizeOfExpression& boundSizeOfExpression) override;
 81     void Visit(BoundAddressOfExpression& boundAddressOfExpression) override;
 82     void Visit(BoundDereferenceExpression& boundDereferenceExpression) override;
 83     void Visit(BoundReferenceToPointerExpression& boundReferenceToPointerExpression) override;
 84     void Visit(BoundFunctionCall& boundFunctionCall) override;
 85     void Visit(BoundDelegateCall& boundDelegateCall) override;
 86     void Visit(BoundClassDelegateCall& boundClassDelegateCall) override;
 87     void Visit(BoundConversion& boundConversion) override;
 88     void Visit(BoundConstructExpression& boundConstructExpression) override;
 89     void Visit(BoundConstructAndReturnTemporaryExpression& boundConstructAndReturnTemporaryExpression) override;
 90     void Visit(BoundClassOrClassDelegateConversionResult& boundClassOrClassDelegateConversionResult) override;
 91     void Visit(BoundIsExpression& boundIsExpression) override;
 92     void Visit(BoundAsExpression& boundAsExpression) override;
 93     void Visit(BoundTypeNameExpression& boundTypeNameExpression) override;
 94     void Visit(BoundBitCast& boundBitCast) override;
 95     void Visit(BoundFunctionPtr& boundFunctionPtr) override;
 96     void Visit(BoundDisjunction& boundDisjunction) override;
 97     void Visit(BoundConjunction& boundConjunction) override;
 98     void Visit(BoundGlobalVariable& boundGlobalVariable) override;
 99     void GenJumpingBoolCode();
100     void SetTarget(BoundStatement* labeledStatement);
101     void ExitBlocks(BoundCompoundStatement* targetBlock);
102     void* GetGlobalStringPtr(int stringId) override;
103     void* GetGlobalWStringConstant(int stringId) override;
104     void* GetGlobalUStringConstant(int stringId) override;
105     void* GetGlobalUuidConstant(int uuidId) override;
106     void* HandlerBlock() override;
107     void* CleanupBlock() override;
108     bool NewCleanupNeeded() override;
109     void CreateCleanup() override;
110     void GenerateCodeForCleanups();
111     bool InTryBlock() const override;
112     int CurrentTryBlockId() const override;
113     int Install(const std::string& str) override;
114     int Install(const std::u16string& str) override;
115     int Install(const std::u32string& str) override;
116 private:
117     cmajor::ir::Emitter* emitter;
118     cmajor::ir::EmittingContext* emittingContext;
119     SymbolTable* symbolTable;
120     Module* module;
121     BoundCompileUnit* compileUnit;
122     cmsxi::CompileUnit* nativeCompileUnit;
123     void* function;
124     void* entryBasicBlock;
125     bool lastInstructionWasRet;
126     bool prevWasTerminator;
127     bool destructorCallGenerated;
128     bool genJumpingBoolCode;
129     void* trueBlock;
130     void* falseBlock;
131     void* breakTarget;
132     void* continueTarget;
133     BoundStatement* sequenceSecond;
134     BoundFunction* currentFunction;
135     BoundCompoundStatement* currentBlock;
136     BoundCompoundStatement* breakTargetBlock;
137     BoundCompoundStatement* continueTargetBlock;
138     std::unordered_map<BoundStatement*void*> labeledStatementMap;
139     std::unordered_map<BoundCompoundStatement*std::std::vector<std::std::unique_ptr<BoundFunctionCall>>>blockDestructionMap;
140     std::vector<std::std::unique_ptr<Cleanup>>cleanups;
141     std::vector<BoundCompoundStatement*> blocks;
142     void* lastAlloca;
143     BoundClass* currentClass;
144     std::stack<BoundClass*> classStack;
145     bool basicBlockOpen;
146     void* defaultDest;
147     std::std::unordered_map<IntegralValuevoid*IntegralValueHash>*currentCaseMap;
148     std::unordered_map<intvoid*> utf8stringMap;
149     std::unordered_map<intvoid*> utf16stringMap;
150     std::unordered_map<intvoid*> utf32stringMap;
151     std::unordered_map<intvoid*> uuidMap;
152     std::string compileUnitId;
153     bool generateLineNumbers;
154     int64_t currentTryBlockId;
155     int64_t nextTryBlockId;
156     void* currentTryNextBlock;
157     void* handlerBlock;
158     void* cleanupBlock;
159     bool newCleanupNeeded;
160     bool inTryBlock;
161 };
162 
163 } } // namespace cmajor::codegensx
164 
165 #endif // CMAJOR_CODEGENSX_SYSTEMX_CODEGENERATOR_INCLUDED