00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 #ifndef COMMA_CODEGEN_COMMART_HDR_GUARD
00010 #define COMMA_CODEGEN_COMMART_HDR_GUARD
00011 
00012 #include "comma/ast/AstBase.h"
00013 
00014 #include "llvm/ADT/DenseMap.h"
00015 #include "llvm/Support/IRBuilder.h"
00016 
00017 namespace llvm {
00018 
00019 class TargetData;
00020 
00021 } 
00022 
00023 namespace comma {
00024 
00025 class CodeGen;
00026 class DomainInfo;
00027 class DomainInstance;
00028 class SRFrame;
00029 
00030 class CommaRT {
00031 
00032 public:
00033     CommaRT(CodeGen &CG);
00034 
00035     ~CommaRT();
00036 
00039     CodeGen &getCodeGen() { return CG; }
00040     const CodeGen &getCodeGen() const { return CG; }
00041 
00042     enum TypeId {
00043         CRT_ITable,
00044         CRT_DomainInfo,
00045         CRT_DomainInstance,
00046         CRT_DomainCtor
00047     };
00048 
00049     template <TypeId F>
00050     struct TypeIdTraits {
00051         typedef const llvm::PointerType FieldType;
00052     };
00053 
00054     template <TypeId F>
00055     typename TypeIdTraits<F>::FieldType *getType() const;
00056 
00057     const std::string &getTypeName(TypeId id) const;
00058 
00059     llvm::GlobalVariable *registerCapsule(Domoid *domoid);
00060 
00061     llvm::Value *getDomain(llvm::IRBuilder<> &builder,
00062                            llvm::GlobalValue *capsuleInfo) const;
00063 
00064     llvm::Value *getDomain(llvm::IRBuilder<> &builder,
00065                            std::vector<llvm::Value*> &args) const;
00066 
00067     llvm::Value *getLocalCapsule(llvm::IRBuilder<> &builder,
00068                                  llvm::Value *percent, unsigned ID) const;
00069 
00072     llvm::Value *getCapsuleParameter(llvm::IRBuilder<> &builder,
00073                                      llvm::Value *instance,
00074                                      unsigned index) const;
00075 
00078     const DomainInfo *getDomainInfo() const { return DInfo; }
00079     const DomainInstance *getDomainInstance() const { return DInstance; }
00080 
00085 
00086 
00094     llvm::Constant *registerException(const ExceptionDecl *exception);
00095 
00103     void raise(SRFrame *frame, const ExceptionDecl *exception,
00104                llvm::Value *fileName, llvm::Value *lineNum,
00105                llvm::GlobalVariable *message = 0);
00106 
00119     void raise(SRFrame *frame, const ExceptionDecl *exception,
00120                llvm::Value *fileName, llvm::Value *lineNum,
00121                llvm::Value *message = 0, llvm::Value *length = 0);
00122 
00124     void reraise(SRFrame *frame, llvm::Value *exception);
00125 
00127     void raiseProgramError(SRFrame *frame,
00128                            llvm::Value *fileName, llvm::Value *lineNum,
00129                            llvm::GlobalVariable *message) const;
00130 
00132     void raiseConstraintError(SRFrame *frame,
00133                               llvm::Value *fileName, llvm::Value *lineNum,
00134                               llvm::GlobalVariable *message) const;
00135 
00137     void raiseAssertionError(SRFrame *frame,
00138                              llvm::Value *fileName, llvm::Value *lineNum,
00139                              llvm::Value *message, llvm::Value *length) const;
00140 
00146     void unhandledException(llvm::IRBuilder<> &builder,
00147                             llvm::Value *exception) const;
00148 
00151     llvm::Constant *getEHPersonality() const;
00153 
00155 
00156     llvm::Value *pow_i32_i32(llvm::IRBuilder<> &builder,
00157                              llvm::Value *x, llvm::Value *n) const;
00158     llvm::Value *pow_i64_i32(llvm::IRBuilder<> &builder,
00159                              llvm::Value *x, llvm::Value *n) const;
00161 
00162 
00164 
00165 
00166 
00167     void vstack_alloc(llvm::IRBuilder<> &builder, llvm::Value *size) const;
00168 
00170     void vstack_push(llvm::IRBuilder<> &builder,
00171                      llvm::Value *data, llvm::Value *size) const;
00172 
00174     void vstack_pop(llvm::IRBuilder<> &builder) const;
00175 
00178     llvm::Value *vstack(llvm::IRBuilder<> &builder,
00179                         const llvm::Type *ptrTy) const;
00181 
00183 
00184     llvm::Value *comma_alloc(llvm::IRBuilder<> &builder,
00185                              uint64_t size, unsigned alignment) const;
00186 
00187     llvm::Value *comma_alloc(llvm::IRBuilder<> &builder,
00188                              llvm::Value *size, unsigned alignment) const;
00189 
00191 
00192 private:
00193     CodeGen &CG;
00194 
00195     
00196     std::string InvalidName;
00197     std::string ITableName;
00198     std::string DomainCtorName;
00199 
00200     DomainInfo *DInfo;
00201     const llvm::PointerType *DomainInfoPtrTy;
00202 
00203     DomainInstance *DInstance;
00204     const llvm::PointerType *DomainInstancePtrTy;
00205 
00206     const llvm::PointerType *ITablePtrTy;
00207     const llvm::PointerType *DomainCtorPtrTy;
00208 
00209     
00210     llvm::Function *getDomainFn;
00211     llvm::Function *EHPersonalityFn;
00212     llvm::Function *unhandledExceptionFn;
00213     llvm::Function *raiseStaticExceptionFn;
00214     llvm::Function *raiseUserExceptionFn;
00215     llvm::Function *reraiseExceptionFn;
00216     llvm::Function *pow_i32_i32_Fn;
00217     llvm::Function *pow_i64_i32_Fn;
00218     llvm::Function *vstack_alloc_Fn;
00219     llvm::Function *vstack_push_Fn;
00220     llvm::Function *vstack_pop_Fn;
00221     llvm::Function *alloc_Fn;
00222 
00223     
00224     llvm::GlobalVariable *vstack_Var;
00225 
00226     
00227     
00228     typedef llvm::DenseMap<const ExceptionDecl*,
00229                            llvm::GlobalVariable*> ExceptionMap;
00230     ExceptionMap registeredExceptions;
00231 
00232     
00233     
00234     llvm::Constant *theProgramErrorExinfo;
00235     llvm::Constant *theConstraintErrorExinfo;
00236     llvm::Constant *theAssertErrorExinfo;
00237 
00238     const llvm::PointerType *getDomainCtorPtrTy();
00239     const llvm::PointerType *getITablePtrTy();
00240 
00241     
00242     void defineGetDomain();
00243     void defineEHPersonality();
00244     void defineUnhandledException();
00245     void defineRaiseException();
00246     void defineExinfos();
00247     void define_pow_i32_i32();
00248     void define_pow_i64_i32();
00249     void define_vstack_alloc();
00250     void define_vstack_push();
00251     void define_vstack_pop();
00252     void define_vstack();
00253     void define_alloc();
00254 
00255     
00256     void generateRuntimeTypes();
00257 
00258     
00259     
00260     void generateRuntimeFunctions();
00261 
00264     llvm::Constant *genExinfoInitializer(const ExceptionDecl *exception);
00265 
00268     llvm::Constant *checkAndConvertMessage(llvm::GlobalVariable *message) const;
00269 
00272     void raiseExinfo(SRFrame *frame, llvm::Value *exinfo,
00273                      llvm::Value *fileName, llvm::Value *lineNum,
00274                      llvm::GlobalVariable *message) const;
00275 
00278     void raiseExinfo(SRFrame *frame, llvm::Value *exinfo,
00279                      llvm::Value *fileName, llvm::Value *lineNum,
00280                      llvm::Value *message, llvm::Value *length) const;
00281 };
00282 
00283 template <> inline
00284 CommaRT::TypeIdTraits<CommaRT::CRT_ITable>::FieldType *
00285 CommaRT::getType<CommaRT::CRT_ITable>() const {
00286     return ITablePtrTy;
00287 }
00288 
00289 template <> inline
00290 CommaRT::TypeIdTraits<CommaRT::CRT_DomainInfo>::FieldType *
00291 CommaRT::getType<CommaRT::CRT_DomainInfo>() const {
00292     return DomainInfoPtrTy;
00293 }
00294 
00295 template <> inline
00296 CommaRT::TypeIdTraits<CommaRT::CRT_DomainInstance>::FieldType *
00297 CommaRT::getType<CommaRT::CRT_DomainInstance>() const {
00298     return DomainInstancePtrTy;
00299 }
00300 
00301 template <> inline
00302 CommaRT::TypeIdTraits<CommaRT::CRT_DomainCtor>::FieldType *
00303 CommaRT::getType<CommaRT::CRT_DomainCtor>() const {
00304     return DomainCtorPtrTy;
00305 }
00306 
00307 } 
00308 
00309 #endif
00310