123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- #include "Engine.h"
- #include "codegen/il2cpp-codegen.h"
- #include "Interpreter.h"
- #include "MemoryUtil.h"
- #include "../metadata/InterpreterImage.h"
- #include "../metadata/MetadataModule.h"
- namespace hybridclr
- {
- namespace interpreter
- {
- #if HYBRIDCLR_ENABLE_STRACKTRACE
- #define PUSH_STACK_FRAME(method, rawIp) do { \
- Il2CppStackFrameInfo stackFrameInfo = { method, rawIp }; \
- il2cpp::vm::StackTrace::PushFrame(stackFrameInfo); \
- } while(0)
- #define POP_STACK_FRAME() do { il2cpp::vm::StackTrace::PopFrame(); } while(0)
- #else
- #define PUSH_STACK_FRAME(method, rawIp)
- #define POP_STACK_FRAME()
- #endif
- InterpFrame* InterpFrameGroup::EnterFrameFromInterpreter(const MethodInfo* method, StackObject* argBase)
- {
- #if HYBRIDCLR_ENABLE_PROFILER
- il2cpp_codegen_profiler_method_enter(method);
- #endif
- const InterpMethodInfo* imi = (const InterpMethodInfo*)method->interpData;
- int32_t oldStackTop = _machineState.GetStackTop();
- StackObject* stackBasePtr = _machineState.AllocStackSlot(imi->maxStackSize - imi->argStackObjectSize);
- InterpFrame* newFrame = _machineState.PushFrame();
- *newFrame = { method, argBase, oldStackTop, nullptr, nullptr, nullptr, 0, 0, _machineState.GetLocalPoolBottomIdx() };
- PUSH_STACK_FRAME(method, (uintptr_t)newFrame);
- return newFrame;
- }
- InterpFrame* InterpFrameGroup::EnterFrameFromNative(const MethodInfo* method, StackObject* argBase)
- {
- #if HYBRIDCLR_ENABLE_PROFILER
- il2cpp_codegen_profiler_method_enter(method);
- #endif
- const InterpMethodInfo* imi = (const InterpMethodInfo*)method->interpData;
- int32_t oldStackTop = _machineState.GetStackTop();
- StackObject* stackBasePtr = _machineState.AllocStackSlot(imi->maxStackSize);
- InterpFrame* newFrame = _machineState.PushFrame();
- *newFrame = { method, stackBasePtr, oldStackTop, nullptr, nullptr, nullptr, 0, 0, _machineState.GetLocalPoolBottomIdx() };
- // if not prepare arg stack. copy from args
- if (imi->args)
- {
- IL2CPP_ASSERT(imi->argCount == metadata::GetActualArgumentNum(method));
- CopyStackObject(stackBasePtr, argBase, imi->argStackObjectSize);
- }
- PUSH_STACK_FRAME(method, (uintptr_t)newFrame);
- return newFrame;
- }
- InterpFrame* InterpFrameGroup::LeaveFrame()
- {
- IL2CPP_ASSERT(_machineState.GetFrameTopIdx() > _frameBaseIdx);
- POP_STACK_FRAME();
- InterpFrame* frame = _machineState.GetTopFrame();
- #if HYBRIDCLR_ENABLE_PROFILER
- il2cpp_codegen_profiler_method_exit(frame->method);
- #endif
- if (frame->exFlowBase)
- {
- _machineState.SetExceptionFlowTop(frame->exFlowBase);
- }
- _machineState.PopFrame();
- _machineState.SetStackTop(frame->oldStackTop);
- _machineState.SetLocalPoolBottomIdx(frame->oldLocalPoolBottomIdx);
- return _machineState.GetFrameTopIdx() > _frameBaseIdx ? _machineState.GetTopFrame() : nullptr;
- }
- static bool FrameNeedsSkipped(const Il2CppStackFrameInfo& frame)
- {
- const MethodInfo* method = frame.method;
- const Il2CppClass* klass = method->klass;
- return (strcmp(klass->namespaze, "System.Diagnostics") == 0 &&
- (strcmp(klass->name, "StackFrame") == 0 || strcmp(klass->name, "StackTrace") == 0))
- || (strcmp(klass->namespaze, "UnityEngine") == 0
- && (strcmp(klass->name, "StackTraceUtility") == 0
- || strcmp(klass->name, "Debug") == 0
- || strcmp(klass->name, "Logger") == 0
- || strcmp(klass->name, "DebugLogHandler") == 0));
- }
- static void SetupStackFrameInfo(const InterpFrame* frame, Il2CppStackFrameInfo& stackFrame)
- {
- const MethodInfo* method = frame->method;
- const InterpMethodInfo* imi = (const InterpMethodInfo*)method->interpData;
- const byte* actualIp = (const byte*)frame->ip;
- stackFrame.method = method;
- stackFrame.raw_ip = (uintptr_t)frame;
- if (!hybridclr::metadata::IsInterpreterMethod(method))
- {
- return;
- }
-
- hybridclr::metadata::InterpreterImage* interpImage = hybridclr::metadata::MetadataModule::GetImage(method);
- if (!interpImage)
- {
- return;
- }
- hybridclr::metadata::PDBImage* pdbImage = interpImage->GetPDBImage();
- if (!pdbImage)
- {
- return;
- }
- pdbImage->SetupStackFrameInfo(method, actualIp, stackFrame);
- }
- void MachineState::CollectFrames(il2cpp::vm::StackFrames* stackFrames)
- {
- if (_frameTopIdx <= 0)
- {
- return;
- }
- size_t insertIndex = 0;
- for (; insertIndex < stackFrames->size(); insertIndex++)
- {
- if (FrameNeedsSkipped((*stackFrames)[insertIndex]))
- {
- break;
- }
- }
- stackFrames->insert(stackFrames->begin() + insertIndex, _frameTopIdx, Il2CppStackFrameInfo());
- for (int32_t i = 0; i < _frameTopIdx; i++)
- {
- SetupStackFrameInfo(_frameBase + i, (*stackFrames)[insertIndex + i]);
- }
- }
- void MachineState::SetupFramesDebugInfo(il2cpp::vm::StackFrames* stackFrames)
- {
- for (Il2CppStackFrameInfo& frame : *stackFrames)
- {
- if (frame.method && hybridclr::metadata::IsInterpreterImplement(frame.method))
- {
- hybridclr::metadata::InterpreterImage* interpImage = hybridclr::metadata::MetadataModule::GetImage(frame.method);
- if (interpImage)
- {
- hybridclr::metadata::PDBImage* pdbImage = interpImage->GetPDBImage();
- if (pdbImage)
- {
- pdbImage->SetupStackFrameInfo(frame.method, (const byte*)(((InterpFrame*)frame.raw_ip)->ip), frame);
- }
- }
- }
- }
- }
- }
- }
|