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