clang 22.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 "FixedPoint.h"
12#include "Floating.h"
13#include "Integral.h"
14#include "MemberPointer.h"
15#include "Pointer.h"
16#include <cassert>
17#include <cstdlib>
18
19using namespace clang;
20using namespace clang::interp;
21
23 if (Chunk && Chunk->Next)
24 std::free(Chunk->Next);
25 if (Chunk)
26 std::free(Chunk);
27 Chunk = nullptr;
28 StackSize = 0;
29 ItemTypes.clear();
30}
31
32// We keep the last chunk around to reuse.
34 for (PrimType Item : llvm::reverse(ItemTypes)) {
35 TYPE_SWITCH(Item, { this->discard<T>(); });
36 }
37 assert(ItemTypes.empty());
38 assert(empty());
39}
40
41void InterpStack::clearTo(size_t NewSize) {
42 if (NewSize == 0)
43 return clear();
44 if (NewSize == size())
45 return;
46
47 assert(NewSize <= size());
48 for (PrimType Item : llvm::reverse(ItemTypes)) {
49 TYPE_SWITCH(Item, { this->discard<T>(); });
50
51 if (size() == NewSize)
52 break;
53 }
54
55 // Note: discard() above already removed the types from ItemTypes.
56 assert(size() == NewSize);
57}
58
59void *InterpStack::grow(size_t Size) {
60 assert(Size < ChunkSize - sizeof(StackChunk) && "Object too large");
61
62 if (!Chunk || sizeof(StackChunk) + Chunk->size() + Size > ChunkSize) {
63 if (Chunk && Chunk->Next) {
64 Chunk = Chunk->Next;
65 } else {
66 StackChunk *Next = new (std::malloc(ChunkSize)) StackChunk(Chunk);
67 if (Chunk)
68 Chunk->Next = Next;
69 Chunk = Next;
70 }
71 }
72
73 auto *Object = reinterpret_cast<void *>(Chunk->End);
74 Chunk->End += Size;
75 StackSize += Size;
76 return Object;
77}
78
79void *InterpStack::peekData(size_t Size) const {
80 assert(Chunk && "Stack is empty!");
81
82 StackChunk *Ptr = Chunk;
83 while (Size > Ptr->size()) {
84 Size -= Ptr->size();
85 Ptr = Ptr->Prev;
86 assert(Ptr && "Offset too large");
87 }
88
89 return reinterpret_cast<void *>(Ptr->End - Size);
90}
91
92void InterpStack::shrink(size_t Size) {
93 assert(Chunk && "Chunk is empty!");
94
95 while (Size > Chunk->size()) {
96 Size -= Chunk->size();
97 if (Chunk->Next) {
98 std::free(Chunk->Next);
99 Chunk->Next = nullptr;
100 }
101 Chunk->End = Chunk->start();
102 Chunk = Chunk->Prev;
103 assert(Chunk && "Offset too large");
104 }
105
106 Chunk->End -= Size;
107 StackSize -= Size;
108}
109
110void InterpStack::dump() const {
111 llvm::errs() << "Items: " << ItemTypes.size() << ". Size: " << size() << '\n';
112 if (ItemTypes.empty())
113 return;
114
115 size_t Index = 0;
116 size_t Offset = 0;
117
118 // The type of the item on the top of the stack is inserted to the back
119 // of the vector, so the iteration has to happen backwards.
120 for (PrimType Item : llvm::reverse(ItemTypes)) {
121 Offset += align(primSize(Item));
122
123 llvm::errs() << Index << '/' << Offset << ": ";
124 TYPE_SWITCH(Item, {
125 const T &V = peek<T>(Offset);
126 llvm::errs() << V;
127 });
128 llvm::errs() << '\n';
129
130 ++Index;
131 }
132}
#define V(N, I)
Definition: ASTContext.h:3597
#define TYPE_SWITCH(Expr, B)
Definition: PrimType.h:207
void clearTo(size_t NewSize)
Definition: InterpStack.cpp:41
void dump() const
dump the stack contents to stderr.
void clear()
Clears the stack.
Definition: InterpStack.cpp:33
size_t size() const
Returns the size of the stack in bytes.
Definition: InterpStack.h:77
bool empty() const
Returns whether the stack is empty.
Definition: InterpStack.h:84
~InterpStack()
Destroys the stack, freeing up storage.
Definition: InterpStack.cpp:22
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
Definition: PrimType.h:185
PrimType
Enumeration of the primitive types of the VM.
Definition: PrimType.h:34
size_t primSize(PrimType Type)
Returns the size of a primitive type in bytes.
Definition: PrimType.cpp:23
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T