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