1 //===--- InterpStack.cpp - Stack implementation for the VM ------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #include "InterpStack.h"
17 using namespace clang
;
18 using namespace clang::interp
;
20 InterpStack::~InterpStack() {
24 void InterpStack::clear() {
25 if (Chunk
&& Chunk
->Next
)
26 std::free(Chunk
->Next
);
36 void *InterpStack::grow(size_t Size
) {
37 assert(Size
< ChunkSize
- sizeof(StackChunk
) && "Object too large");
39 if (!Chunk
|| sizeof(StackChunk
) + Chunk
->size() + Size
> ChunkSize
) {
40 if (Chunk
&& Chunk
->Next
) {
43 StackChunk
*Next
= new (std::malloc(ChunkSize
)) StackChunk(Chunk
);
50 auto *Object
= reinterpret_cast<void *>(Chunk
->End
);
56 void *InterpStack::peekData(size_t Size
) const {
57 assert(Chunk
&& "Stack is empty!");
59 StackChunk
*Ptr
= Chunk
;
60 while (Size
> Ptr
->size()) {
63 assert(Ptr
&& "Offset too large");
66 return reinterpret_cast<void *>(Ptr
->End
- Size
);
69 void InterpStack::shrink(size_t Size
) {
70 assert(Chunk
&& "Chunk is empty!");
72 while (Size
> Chunk
->size()) {
73 Size
-= Chunk
->size();
75 std::free(Chunk
->Next
);
76 Chunk
->Next
= nullptr;
78 Chunk
->End
= Chunk
->start();
80 assert(Chunk
&& "Offset too large");
87 void InterpStack::dump() const {
89 llvm::errs() << "Items: " << ItemTypes
.size() << ". Size: " << size() << '\n';
90 if (ItemTypes
.empty())
96 // The type of the item on the top of the stack is inserted to the back
97 // of the vector, so the iteration has to happen backwards.
98 for (auto TyIt
= ItemTypes
.rbegin(); TyIt
!= ItemTypes
.rend(); ++TyIt
) {
99 Offset
+= align(primSize(*TyIt
));
101 llvm::errs() << Index
<< '/' << Offset
<< ": ";
103 const T
&V
= peek
<T
>(Offset
);
106 llvm::errs() << '\n';