Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add Stack and StackFrame #196

Merged
merged 2 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
}
}