xref: /llvm-project/clang/lib/AST/ByteCode/ByteCodeEmitter.h (revision 83fea8b809b284594e6dd133150bb6d365775e5b)
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