clang 20.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
25 if (Chunk && Chunk->Next)
26 std::free(Chunk->Next);
27 if (Chunk)
28 std::free(Chunk);
29 Chunk = nullptr;
30 StackSize = 0;
31#ifndef NDEBUG
32 ItemTypes.clear();
33#endif
34}
35
36void InterpStack::clearTo(size_t NewSize) {
37 assert(NewSize <= size());
38 size_t ToShrink = size() - NewSize;
39 if (ToShrink == 0)
40 return;
41
42 shrink(ToShrink);
43 assert(size() == NewSize);
44}
45
46void *InterpStack::grow(size_t Size) {
47 assert(Size < ChunkSize - sizeof(StackChunk) && "Object too large");
48
49 if (!Chunk || sizeof(StackChunk) + Chunk->size() + Size > ChunkSize) {
50 if (Chunk && Chunk->Next) {
51 Chunk = Chunk->Next;
52 } else {
53 StackChunk *Next = new (std::malloc(ChunkSize)) StackChunk(Chunk);
54 if (Chunk)
55 Chunk->Next = Next;
56 Chunk = Next;
57 }
58 }
59
60 auto *Object = reinterpret_cast<void *>(Chunk->End);
61 Chunk->End += Size;
62 StackSize += Size;
63 return Object;
64}
65
66void *InterpStack::peekData(size_t Size) const {
67 assert(Chunk && "Stack is empty!");
68
69 StackChunk *Ptr = Chunk;
70 while (Size > Ptr->size()) {
71 Size -= Ptr->size();
72 Ptr = Ptr->Prev;
73 assert(Ptr && "Offset too large");
74 }
75
76 return reinterpret_cast<void *>(Ptr->End - Size);
77}
78
79void InterpStack::shrink(size_t Size) {
80 assert(Chunk && "Chunk is empty!");
81
82 while (Size > Chunk->size()) {
83 Size -= Chunk->size();
84 if (Chunk->Next) {
85 std::free(Chunk->Next);
86 Chunk->Next = nullptr;
87 }
88 Chunk->End = Chunk->start();
89 Chunk = Chunk->Prev;
90 assert(Chunk && "Offset too large");
91 }
92
93 Chunk->End -= Size;
94 StackSize -= Size;
95
96#ifndef NDEBUG
97 size_t TypesSize = 0;
98 for (PrimType T : ItemTypes)
99 TYPE_SWITCH(T, { TypesSize += aligned_size<T>(); });
100
101 size_t StackSize = size();
102 while (TypesSize > StackSize) {
103 TYPE_SWITCH(ItemTypes.back(), {
104 TypesSize -= aligned_size<T>();
105 ItemTypes.pop_back();
106 });
107 }
108 assert(TypesSize == StackSize);
109#endif
110}
111
112void InterpStack::dump() const {
113#ifndef NDEBUG
114 llvm::errs() << "Items: " << ItemTypes.size() << ". Size: " << size() << '\n';
115 if (ItemTypes.empty())
116 return;
117
118 size_t Index = 0;
119 size_t Offset = 0;
120
121 // The type of the item on the top of the stack is inserted to the back
122 // of the vector, so the iteration has to happen backwards.
123 for (auto TyIt = ItemTypes.rbegin(); TyIt != ItemTypes.rend(); ++TyIt) {
124 Offset += align(primSize(*TyIt));
125
126 llvm::errs() << Index << '/' << Offset << ": ";
127 TYPE_SWITCH(*TyIt, {
128 const T &V = peek<T>(Offset);
129 llvm::errs() << V;
130 });
131 llvm::errs() << '\n';
132
133 ++Index;
134 }
135#endif
136}
#define V(N, I)
Definition: ASTContext.h:3443
#define TYPE_SWITCH(Expr, B)
Definition: PrimType.h:153
void clearTo(size_t NewSize)
Definition: InterpStack.cpp:36
void dump() const
dump the stack contents to stderr.
void clear()
Clears the stack without calling any destructors.
Definition: InterpStack.cpp:24
size_t size() const
Returns the size of the stack in bytes.
Definition: InterpStack.h:86
~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:131
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