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