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