Skip to content

Commit

Permalink
feat: add Stack and StackFrame (#196)
Browse files Browse the repository at this point in the history
  • Loading branch information
nikitalita authored Oct 25, 2023
1 parent 02c6186 commit ec63dc9
Show file tree
Hide file tree
Showing 5 changed files with 166 additions and 0 deletions.
8 changes: 8 additions & 0 deletions CommonLibSF/include/RE/IDs.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ namespace RE::ID
inline constexpr REL::ID GetProperty{ 196241 };
}

namespace Stack
{
inline constexpr REL::ID ctor{ 196325 };
inline constexpr REL::ID dtor{ 196333 };
inline constexpr REL::ID GetStackFrameVariable{ 196367 };
inline constexpr REL::ID GetPageForFrame{ 196366 };
}

namespace Internal
{
namespace NF_util
Expand Down
107 changes: 107 additions & 0 deletions CommonLibSF/include/RE/S/Stack.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#pragma once

#include "RE/B/BSIntrusiveRefCounted.h"
#include "RE/B/BSTSmartPointer.h"
#include "RE/V/Variable.h"

namespace RE
{
namespace BSScript
{
class IProfilePolicy;
class IStackCallbackFunctor;
class MemoryPage; // stub
class Object;
class StackFrame;

struct IMemoryPagePolicy;

namespace Internal
{
class CodeTasklet;
}

namespace UnlinkedTypes
{
struct Object; // stub
}

class Stack :
public BSIntrusiveRefCounted // 00
{
public:
enum class StackType
{
kNormal,
kPropInit,
kInitEvent
};

enum class FreezeState
{
kUnfrozen,
kFreezing,
kFrozen
};

enum class State
{
kRunning,
kFinished,
kWaitingOnMemory,
kWaitingOnLatentFunction,
kWaitingInOtherStackForCall,
kWaitingInOtherStackForReturn,
kWaitingInOtherStackForReturnNoPop,
kRetryReturnNoPop,
kRetryCall,
kWaitingOnGuard,
kWaitingOnOtherStackForGuard,
};

struct MemoryPageData
{
public:
// members
BSTAutoPointer<MemoryPage> page; // 00
std::uint32_t availableMemoryInBytes; // 08
};
static_assert(sizeof(MemoryPageData) == 0x10);

[[nodiscard]] std::uint32_t GetPageForFrame(const StackFrame* a_frame) const
{
using func_t = decltype(&Stack::GetPageForFrame);
REL::Relocation<func_t> func{ ID::BSScript::Stack::GetPageForFrame };
return func(this, a_frame);
}

[[nodiscard]] Variable& GetStackFrameVariable(const StackFrame* a_frame, std::uint32_t a_index, std::uint32_t a_pageHint)
{
using func_t = decltype(&Stack::GetStackFrameVariable);
REL::Relocation<func_t> func{ ID::BSScript::Stack::GetStackFrameVariable };
return func(this, a_frame, a_index, a_pageHint);
}

// members
IMemoryPagePolicy* policy; // 08
void* unk10; // 10 -- something to do with guards, guardPolicy maybe?
IProfilePolicy* profilePolicy; // 18
void* unk20; // 20
/*BSTSmallArray<MemoryPageData, 3>*/ char pages[0x40]; // 28
StackFrame* top; // 68
BSTSmartPointer<Internal::CodeTasklet> owningTasklet; // 70
BSTSmartPointer<IStackCallbackFunctor> callback; // 78
BSTSmartPointer<Object> objToUnbind; // 80
BSTSmartPointer<Stack> nextStack; // 88
Variable returnValue; // 90
std::uint64_t unk98; // A0
std::uint64_t unkA0; // A8
std::uint32_t frames; // B0
std::uint32_t stackID; // B4
stl::enumeration<State, std::int32_t> state; // B8
stl::enumeration<FreezeState, std::int32_t> freezeState; // BC
stl::enumeration<StackType, std::int32_t> stackType; // C0
};
static_assert(sizeof(Stack) == 0xC8);
}
}
35 changes: 35 additions & 0 deletions CommonLibSF/include/RE/S/StackFrame.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#pragma once

#include "RE/B/BSFixedString.h"
#include "RE/B/BSTSmartPointer.h"
#include "RE/V/Variable.h"

namespace RE
{
namespace BSScript
{
class IFunction;
class ObjectTypeInfo;
class Stack;
class Variable;

class StackFrame
{
public:
[[nodiscard]] std::uint32_t GetPageForFrame() const;
[[nodiscard]] Variable& GetStackFrameVariable(std::uint32_t a_index, std::uint32_t a_pageHint) const;

// members
Stack* parent; // 00
StackFrame* previousFrame; // 08
BSTSmartPointer<IFunction> owningFunction; // 10
BSTSmartPointer<ObjectTypeInfo> owningObjectType; // 18
Variable self; // 20
std::uint32_t index; // 30
std::uint32_t ip; // 34
std::uint32_t size; // 38
bool instructionsValid; // 3C
};
static_assert(sizeof(StackFrame) == 0x40);
}
}
2 changes: 2 additions & 0 deletions CommonLibSF/include/RE/Starfield.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@
#include "RE/S/SettingCollectionList.h"
#include "RE/S/SettingCollectionMap.h"
#include "RE/S/Sexes.h"
#include "RE/S/Stack.h"
#include "RE/S/StackFrame.h"
#include "RE/S/Struct.h"
#include "RE/S/StructTypeInfo.h"
#include "RE/T/TBO_InstanceData.h"
Expand Down
14 changes: 14 additions & 0 deletions CommonLibSF/src/RE/S/StackFrame.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include "RE/S/StackFrame.h"
#include "RE/S/Stack.h"

namespace RE::BSScript
{
std::uint32_t StackFrame::GetPageForFrame() const
{
return parent->GetPageForFrame(this);
}
Variable& StackFrame::GetStackFrameVariable(std::uint32_t a_index, std::uint32_t a_pageHint) const
{
return parent->GetStackFrameVariable(this, a_index, a_pageHint);
}
}

0 comments on commit ec63dc9

Please sign in to comment.