clang 24.0.0git
InterpStack.cpp
Go to the documentation of this file.
1//===--- InterpStack.cpp - Stack implementation 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-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "InterpStack.h"
10#include "Boolean.h"
11#include "Char.h"
12#include "FixedPoint.h"
13#include "Floating.h"
14#include "Integral.h"
15#include "MemberPointer.h"
16#include "Pointer.h"
17#include <cassert>
18#include <cstdlib>
19
20using namespace clang;
21using namespace clang::interp;
22
24 if (Chunk && Chunk->Next)
25 std::free(Chunk->Next);
26 if (Chunk)
27 std::free(Chunk);
28}
29
30// We keep the last chunk around to reuse.
32 for (PrimType Item : llvm::reverse(ItemTypes)) {
33 TYPE_SWITCH(Item, { this->discard<T>(); });
34 }
35 assert(ItemTypes.empty());
36 assert(empty());
37}
38
39void InterpStack::clearTo(size_t NewSize) {
40 if (NewSize == 0)
41 return clear();
42 if (NewSize == size())
43 return;
44
45 assert(NewSize <= size());
46 for (PrimType Item : llvm::reverse(ItemTypes)) {
47 TYPE_SWITCH(Item, { this->discard<T>(); });
48
49 if (size() == NewSize)
50 break;
51 }
52
53 // Note: discard() above already removed the types from ItemTypes.
54 assert(size() == NewSize);
55}
56
57// The "slow" part of peekData().
58void *InterpStack::peekDataSlow(size_t Size) const {
59 StackChunk *Ptr = Chunk;
60 while (Size > Ptr->size()) {
61 Size -= Ptr->size();
62 Ptr = Ptr->Prev;
63 assert(Ptr && "Offset too large");
64 }
65
66 return reinterpret_cast<void *>(Ptr->start() + Ptr->Size - Size);
67}
68
69// The "slow" part of shrink().
70void InterpStack::shrinkSlow(size_t Size) {
71 while (Size > Chunk->size()) {
72 Size -= Chunk->size();
73 if (Chunk->Next) {
74 std::free(Chunk->Next);
75 Chunk->Next = nullptr;
76 }
77 Chunk->Size = 0;
78 Chunk = Chunk->Prev;
79 assert(Chunk && "Offset too large");
80 }
81
82 Chunk->Size -= Size;
83 StackSize -= Size;
84}
85
86void InterpStack::dump() const {
87 llvm::errs() << "Items: " << ItemTypes.size() << ". Size: " << size() << '\n';
88 if (ItemTypes.empty())
89 return;
90
91 size_t Index = 0;
92 size_t Offset = 0;
93
94 // The type of the item on the top of the stack is inserted to the back
95 // of the vector, so the iteration has to happen backwards.
96 for (PrimType Item : llvm::reverse(ItemTypes)) {
97 Offset += align(primSize(Item));
98
99 llvm::errs() << Index << '/' << Offset << ": ";
100 TYPE_SWITCH(Item, {
101 const T &V = peek<T>(Offset);
102 llvm::errs() << V;
103 });
104 llvm::errs() << '\n';
105
106 ++Index;
107 }
108}
109
111 assert(!empty());
112
113 TYPE_SWITCH(ItemTypes.back(), { discard<T>(); });
114}
#define V(N, I)
#define TYPE_SWITCH(Expr, B)
Definition PrimType.h:240
void clearTo(size_t NewSize)
void dump() const
dump the stack contents to stderr.
void clear()
Clears the stack.
size_t size() const
Returns the size of the stack in bytes.
Definition InterpStack.h:79
bool empty() const
Returns whether the stack is empty.
Definition InterpStack.h:86
void discard()
Discards the top value from the stack.
Definition InterpStack.h:51
~InterpStack()
Destroys the stack, freeing up storage.
T & peek() const
Returns a reference to the value on the top of the stack.
Definition InterpStack.h:64
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
Definition PrimType.h:218
PrimType
Enumeration of the primitive types of the VM.
Definition PrimType.h:35
size_t primSize(PrimType Type)
Returns the size of a primitive type in bytes.
Definition PrimType.cpp:25
Top level wrappers for InstallAPI frontend operations.
const FunctionProtoType * T