1353942Sdim//===--- ByteCodeEmitter.h - Instruction emitter for the VM ---------*- C++ -*-===// 2353942Sdim// 3353942Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353942Sdim// See https://llvm.org/LICENSE.txt for license information. 5353942Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6353942Sdim// 7353942Sdim//===----------------------------------------------------------------------===// 8353942Sdim// 9353942Sdim// Defines the instruction emitters. 10353942Sdim// 11353942Sdim//===----------------------------------------------------------------------===// 12353942Sdim 13353942Sdim#ifndef LLVM_CLANG_AST_INTERP_LINKEMITTER_H 14353942Sdim#define LLVM_CLANG_AST_INTERP_LINKEMITTER_H 15353942Sdim 16353942Sdim#include "ByteCodeGenError.h" 17353942Sdim#include "Context.h" 18353942Sdim#include "InterpStack.h" 19353942Sdim#include "InterpState.h" 20353942Sdim#include "PrimType.h" 21353942Sdim#include "Program.h" 22353942Sdim#include "Source.h" 23353942Sdim#include "llvm/Support/Error.h" 24353942Sdim 25353942Sdimnamespace clang { 26353942Sdimnamespace interp { 27353942Sdimclass Context; 28353942Sdimclass SourceInfo; 29353942Sdimenum Opcode : uint32_t; 30353942Sdim 31353942Sdim/// An emitter which links the program to bytecode for later use. 32353942Sdimclass ByteCodeEmitter { 33353942Sdimprotected: 34353942Sdim using LabelTy = uint32_t; 35353942Sdim using AddrTy = uintptr_t; 36353942Sdim using Local = Scope::Local; 37353942Sdim 38353942Sdimpublic: 39353942Sdim /// Compiles the function into the module. 40353942Sdim llvm::Expected<Function *> compileFunc(const FunctionDecl *F); 41353942Sdim 42353942Sdimprotected: 43353942Sdim ByteCodeEmitter(Context &Ctx, Program &P) : Ctx(Ctx), P(P) {} 44353942Sdim 45353942Sdim virtual ~ByteCodeEmitter() {} 46353942Sdim 47353942Sdim /// Define a label. 48353942Sdim void emitLabel(LabelTy Label); 49353942Sdim /// Create a label. 50353942Sdim LabelTy getLabel() { return ++NextLabel; } 51353942Sdim 52353942Sdim /// Methods implemented by the compiler. 53353942Sdim virtual bool visitFunc(const FunctionDecl *E) = 0; 54353942Sdim virtual bool visitExpr(const Expr *E) = 0; 55353942Sdim virtual bool visitDecl(const VarDecl *E) = 0; 56353942Sdim 57353942Sdim /// Bails out if a given node cannot be compiled. 58353942Sdim bool bail(const Stmt *S) { return bail(S->getBeginLoc()); } 59353942Sdim bool bail(const Decl *D) { return bail(D->getBeginLoc()); } 60353942Sdim bool bail(const SourceLocation &Loc); 61353942Sdim 62353942Sdim /// Emits jumps. 63353942Sdim bool jumpTrue(const LabelTy &Label); 64353942Sdim bool jumpFalse(const LabelTy &Label); 65353942Sdim bool jump(const LabelTy &Label); 66353942Sdim bool fallthrough(const LabelTy &Label); 67353942Sdim 68353942Sdim /// Callback for local registration. 69353942Sdim Local createLocal(Descriptor *D); 70353942Sdim 71353942Sdim /// Parameter indices. 72353942Sdim llvm::DenseMap<const ParmVarDecl *, unsigned> Params; 73353942Sdim /// Local descriptors. 74353942Sdim llvm::SmallVector<SmallVector<Local, 8>, 2> Descriptors; 75353942Sdim 76353942Sdimprivate: 77353942Sdim /// Current compilation context. 78353942Sdim Context &Ctx; 79353942Sdim /// Program to link to. 80353942Sdim Program &P; 81353942Sdim /// Index of the next available label. 82353942Sdim LabelTy NextLabel = 0; 83353942Sdim /// Offset of the next local variable. 84353942Sdim unsigned NextLocalOffset = 0; 85353942Sdim /// Location of a failure. 86353942Sdim llvm::Optional<SourceLocation> BailLocation; 87353942Sdim /// Label information for linker. 88353942Sdim llvm::DenseMap<LabelTy, unsigned> LabelOffsets; 89353942Sdim /// Location of label relocations. 90353942Sdim llvm::DenseMap<LabelTy, llvm::SmallVector<unsigned, 5>> LabelRelocs; 91353942Sdim /// Program code. 92353942Sdim std::vector<char> Code; 93353942Sdim /// Opcode to expression mapping. 94353942Sdim SourceMap SrcMap; 95353942Sdim 96353942Sdim /// Returns the offset for a jump or records a relocation. 97353942Sdim int32_t getOffset(LabelTy Label); 98353942Sdim 99353942Sdim /// Emits an opcode. 100353942Sdim template <typename... Tys> 101353942Sdim bool emitOp(Opcode Op, const Tys &... Args, const SourceInfo &L); 102353942Sdim 103353942Sdimprotected: 104353942Sdim#define GET_LINK_PROTO 105353942Sdim#include "Opcodes.inc" 106353942Sdim#undef GET_LINK_PROTO 107353942Sdim}; 108353942Sdim 109353942Sdim} // namespace interp 110353942Sdim} // namespace clang 111353942Sdim 112353942Sdim#endif 113