Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/AST/Interp/InterpStack.cpp
35291 views
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 "Floating.h"
12
#include "Integral.h"
13
#include "MemberPointer.h"
14
#include "Pointer.h"
15
#include <cassert>
16
#include <cstdlib>
17
18
using namespace clang;
19
using namespace clang::interp;
20
21
InterpStack::~InterpStack() {
22
clear();
23
}
24
25
void InterpStack::clear() {
26
if (Chunk && Chunk->Next)
27
std::free(Chunk->Next);
28
if (Chunk)
29
std::free(Chunk);
30
Chunk = nullptr;
31
StackSize = 0;
32
#ifndef NDEBUG
33
ItemTypes.clear();
34
#endif
35
}
36
37
void *InterpStack::grow(size_t Size) {
38
assert(Size < ChunkSize - sizeof(StackChunk) && "Object too large");
39
40
if (!Chunk || sizeof(StackChunk) + Chunk->size() + Size > ChunkSize) {
41
if (Chunk && Chunk->Next) {
42
Chunk = Chunk->Next;
43
} else {
44
StackChunk *Next = new (std::malloc(ChunkSize)) StackChunk(Chunk);
45
if (Chunk)
46
Chunk->Next = Next;
47
Chunk = Next;
48
}
49
}
50
51
auto *Object = reinterpret_cast<void *>(Chunk->End);
52
Chunk->End += Size;
53
StackSize += Size;
54
return Object;
55
}
56
57
void *InterpStack::peekData(size_t Size) const {
58
assert(Chunk && "Stack is empty!");
59
60
StackChunk *Ptr = Chunk;
61
while (Size > Ptr->size()) {
62
Size -= Ptr->size();
63
Ptr = Ptr->Prev;
64
assert(Ptr && "Offset too large");
65
}
66
67
return reinterpret_cast<void *>(Ptr->End - Size);
68
}
69
70
void InterpStack::shrink(size_t Size) {
71
assert(Chunk && "Chunk is empty!");
72
73
while (Size > Chunk->size()) {
74
Size -= Chunk->size();
75
if (Chunk->Next) {
76
std::free(Chunk->Next);
77
Chunk->Next = nullptr;
78
}
79
Chunk->End = Chunk->start();
80
Chunk = Chunk->Prev;
81
assert(Chunk && "Offset too large");
82
}
83
84
Chunk->End -= Size;
85
StackSize -= Size;
86
}
87
88
void InterpStack::dump() const {
89
#ifndef NDEBUG
90
llvm::errs() << "Items: " << ItemTypes.size() << ". Size: " << size() << '\n';
91
if (ItemTypes.empty())
92
return;
93
94
size_t Index = 0;
95
size_t Offset = 0;
96
97
// The type of the item on the top of the stack is inserted to the back
98
// of the vector, so the iteration has to happen backwards.
99
for (auto TyIt = ItemTypes.rbegin(); TyIt != ItemTypes.rend(); ++TyIt) {
100
Offset += align(primSize(*TyIt));
101
102
llvm::errs() << Index << '/' << Offset << ": ";
103
TYPE_SWITCH(*TyIt, {
104
const T &V = peek<T>(Offset);
105
llvm::errs() << V;
106
});
107
llvm::errs() << '\n';
108
109
++Index;
110
}
111
#endif
112
}
113
114