1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4//
5// ZapInnerPtr.h
6//
7
8//
9// ZapNode that points into middle of other ZapNode
10//
11// ======================================================================================
12
13#include "common.h"
14
15#include "zapinnerptr.h"
16
17ZapNode * ZapInnerPtrTable::Get(ZapNode * pBase, SSIZE_T offset)
18{
19 // Nothing to do if the offset is zero
20 if (offset == 0)
21 return pBase;
22
23 // Flatten the hiearchy of inner ptrs. Inner ptrs pointing to other inner ptrs
24 // would not work well during the Resolve phase
25 while (pBase->GetType() == ZapNodeType_InnerPtr)
26 {
27 ZapInnerPtr * pWrapper = (ZapInnerPtr *)pBase;
28
29 offset += pWrapper->GetOffset();
30 pBase = pWrapper->GetBase();
31 }
32
33 ZapInnerPtr * pInnerPtr = m_entries.Lookup(InnerPtrKey(pBase, offset));
34
35 if (pInnerPtr != NULL)
36 return pInnerPtr;
37
38 switch (offset)
39 {
40 case 1:
41 pInnerPtr = new (m_pWriter->GetHeap()) InnerPtrConst<1>(pBase);
42 break;
43 case 2:
44 pInnerPtr = new (m_pWriter->GetHeap()) InnerPtrConst<2>(pBase);
45 break;
46 case 4:
47 pInnerPtr = new (m_pWriter->GetHeap()) InnerPtrConst<4>(pBase);
48 break;
49 case 8:
50 pInnerPtr = new (m_pWriter->GetHeap()) InnerPtrConst<8>(pBase);
51 break;
52 default:
53 pInnerPtr = new (m_pWriter->GetHeap()) InnerPtrVar(pBase, offset);
54 break;
55 }
56
57 m_entries.Add(pInnerPtr);
58 return pInnerPtr;
59}
60
61void ZapInnerPtrTable::Resolve()
62{
63 for (InnerPtrTable::Iterator i = m_entries.Begin(), end = m_entries.End(); i != end; i++)
64 {
65 (*i)->Resolve();
66 }
67}
68