-
Notifications
You must be signed in to change notification settings - Fork 23
/
STStackFrame.h
81 lines (65 loc) · 2.09 KB
/
STStackFrame.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/******************************************************************************
File: STStackFrame.h
Description:
VM representation of Smalltalk stack frames (not real objects),
******************************************************************************/
#pragma once
#include "STContext.h"
#include "STMethod.h"
namespace ST
{
// Stack frame layout - not a real object.
struct StackFrame
{
MethodOTE* m_method; // Oop of method for which this frame is an activation
Oop m_environment; // Oop of Environment object, if any, otherwise SmallInteger zero
Oop m_caller; // Process index of sending StackFrame
Oop m_ip; // Index into byte codes of method
Oop m_sp; // Process index of top of stack for this frame
Oop m_bp; // SmallInteger BP - always points into stack now
Oop* stackPointer() const { return reinterpret_cast<Oop*>(m_sp - 1); }
void setStackPointer(Oop* value);
void setInstructionPointer(int nOffset);
Oop* basePointer() const;
BOOL isBlockFrame() const;
Oop receiver() const;
BOOL hasContext() const;
StackFrame* caller() const
{
return FromFrameOop(m_caller);
}
static StackFrame* FromFrameOop(Oop frameIndex);
};
///////////////////////////////////////////////////////////////////////////////
inline void StackFrame::setStackPointer(Oop* value)
{
ASSERT(!(Oop(value) & 1));
m_sp = Oop(value) + 1;
}
inline void StackFrame::setInstructionPointer(int nOffset)
{
m_ip = integerObjectOf(nOffset);
}
inline Oop* StackFrame::basePointer() const
{
ASSERT(isIntegerObject(m_bp));
return reinterpret_cast<Oop*>(m_bp - 1);
}
inline BOOL StackFrame::hasContext() const
{
return !isIntegerObject(m_environment);
}
inline BOOL StackFrame::isBlockFrame() const
{
return hasContext() ? reinterpret_cast<ContextOTE*>(m_environment)->m_location->isBlockContext() : FALSE;
}
inline StackFrame* StackFrame::FromFrameOop(Oop framePointer)
{
HARDASSERT(isIntegerObject(framePointer));
return reinterpret_cast<StackFrame*>(framePointer - 1);
}
inline Oop StackFrame::receiver() const
{
return basePointer()[-1];
}
}