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 <cassert>
10 #include "InterpStack.h"
11 
12 using namespace clang;
13 using namespace clang::interp;
14 
15 InterpStack::~InterpStack() {
16   clear();
17 }
18 
19 void InterpStack::clear() {
20   if (Chunk && Chunk->Next)
21     free(Chunk->Next);
22   if (Chunk)
23     free(Chunk);
24   Chunk = nullptr;
25   StackSize = 0;
26 }
27 
28 void *InterpStack::grow(size_t Size) {
29   assert(Size < ChunkSize - sizeof(StackChunk) && "Object too large");
30 
31   if (!Chunk || sizeof(StackChunk) + Chunk->size() + Size > ChunkSize) {
32     if (Chunk && Chunk->Next) {
33       Chunk = Chunk->Next;
34     } else {
35       StackChunk *Next = new (malloc(ChunkSize)) StackChunk(Chunk);
36       if (Chunk)
37         Chunk->Next = Next;
38       Chunk = Next;
39     }
40   }
41 
42   auto *Object = reinterpret_cast<void *>(Chunk->End);
43   Chunk->End += Size;
44   StackSize += Size;
45   return Object;
46 }
47 
48 void *InterpStack::peek(size_t Size) {
49   assert(Chunk && "Stack is empty!");
50 
51   StackChunk *Ptr = Chunk;
52   while (Size > Ptr->size()) {
53     Size -= Ptr->size();
54     Ptr = Ptr->Prev;
55     assert(Ptr && "Offset too large");
56   }
57 
58   return reinterpret_cast<void *>(Ptr->End - Size);
59 }
60 
61 void InterpStack::shrink(size_t Size) {
62   assert(Chunk && "Chunk is empty!");
63 
64   while (Size > Chunk->size()) {
65     Size -= Chunk->size();
66     if (Chunk->Next) {
67       free(Chunk->Next);
68       Chunk->Next = nullptr;
69     }
70     Chunk->End = Chunk->start();
71     Chunk = Chunk->Prev;
72     assert(Chunk && "Offset too large");
73   }
74 
75   Chunk->End -= Size;
76   StackSize -= Size;
77 }
78