ByteCodeEmitter.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. //===--- ByteCodeEmitter.h - Instruction emitter for the VM ---------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // Defines the instruction emitters.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #ifndef LLVM_CLANG_AST_INTERP_LINKEMITTER_H
  13. #define LLVM_CLANG_AST_INTERP_LINKEMITTER_H
  14. #include "ByteCodeGenError.h"
  15. #include "Context.h"
  16. #include "InterpStack.h"
  17. #include "InterpState.h"
  18. #include "PrimType.h"
  19. #include "Program.h"
  20. #include "Source.h"
  21. #include "llvm/Support/Error.h"
  22. namespace clang {
  23. namespace interp {
  24. class Context;
  25. class SourceInfo;
  26. enum Opcode : uint32_t;
  27. /// An emitter which links the program to bytecode for later use.
  28. class ByteCodeEmitter {
  29. protected:
  30. using LabelTy = uint32_t;
  31. using AddrTy = uintptr_t;
  32. using Local = Scope::Local;
  33. public:
  34. /// Compiles the function into the module.
  35. llvm::Expected<Function *> compileFunc(const FunctionDecl *FuncDecl);
  36. protected:
  37. ByteCodeEmitter(Context &Ctx, Program &P) : Ctx(Ctx), P(P) {}
  38. virtual ~ByteCodeEmitter() {}
  39. /// Define a label.
  40. void emitLabel(LabelTy Label);
  41. /// Create a label.
  42. LabelTy getLabel() { return ++NextLabel; }
  43. /// Methods implemented by the compiler.
  44. virtual bool visitFunc(const FunctionDecl *E) = 0;
  45. virtual bool visitExpr(const Expr *E) = 0;
  46. virtual bool visitDecl(const VarDecl *E) = 0;
  47. /// Bails out if a given node cannot be compiled.
  48. bool bail(const Stmt *S) { return bail(S->getBeginLoc()); }
  49. bool bail(const Decl *D) { return bail(D->getBeginLoc()); }
  50. bool bail(const SourceLocation &Loc);
  51. /// Emits jumps.
  52. bool jumpTrue(const LabelTy &Label);
  53. bool jumpFalse(const LabelTy &Label);
  54. bool jump(const LabelTy &Label);
  55. bool fallthrough(const LabelTy &Label);
  56. /// Callback for local registration.
  57. Local createLocal(Descriptor *D);
  58. /// Parameter indices.
  59. llvm::DenseMap<const ParmVarDecl *, unsigned> Params;
  60. /// Local descriptors.
  61. llvm::SmallVector<SmallVector<Local, 8>, 2> Descriptors;
  62. private:
  63. /// Current compilation context.
  64. Context &Ctx;
  65. /// Program to link to.
  66. Program &P;
  67. /// Index of the next available label.
  68. LabelTy NextLabel = 0;
  69. /// Offset of the next local variable.
  70. unsigned NextLocalOffset = 0;
  71. /// Location of a failure.
  72. std::optional<SourceLocation> BailLocation;
  73. /// Label information for linker.
  74. llvm::DenseMap<LabelTy, unsigned> LabelOffsets;
  75. /// Location of label relocations.
  76. llvm::DenseMap<LabelTy, llvm::SmallVector<unsigned, 5>> LabelRelocs;
  77. /// Program code.
  78. std::vector<char> Code;
  79. /// Opcode to expression mapping.
  80. SourceMap SrcMap;
  81. /// Returns the offset for a jump or records a relocation.
  82. int32_t getOffset(LabelTy Label);
  83. /// Emits an opcode.
  84. template <typename... Tys>
  85. bool emitOp(Opcode Op, const Tys &... Args, const SourceInfo &L);
  86. protected:
  87. #define GET_LINK_PROTO
  88. #include "Opcodes.inc"
  89. #undef GET_LINK_PROTO
  90. };
  91. } // namespace interp
  92. } // namespace clang
  93. #endif