text:
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//

//

#include "stdafx.h"
#include "unwinder_amd64.h"

typedef DPTR(M128A)  PTR_M128A;

//---------------------------------------------------------------------------------------
//
// Read 64 bit unsigned value from the specified address. When the unwinder is built
// for jitted code unwinding on non-Windows systems, this is just a plain memory read.
// When the unwinder is built for DAC though, this reads data from the target debugged
// process.
//
// Arguments:
//    addr - address to read from
//
// Return Value:
//    The value that was read
//
// Notes:
//    If the memory read fails in the DAC mode, the failure is reported as an exception
//    via the DacError function.
//
static ULONG64 MemoryRead64(PULONG64 addr)
{
    return *dac_cast<PTR_ULONG64>((TADDR)addr);
}

//---------------------------------------------------------------------------------------
//
// Read 128 bit value from the specified address. When the unwinder is built
// for jitted code unwinding on non-Windows systems, this is just a plain memory read.
// When the unwinder is built for DAC though, this reads data from the target debugged
// process.
//
// Arguments:
//    addr - address to read from
//
// Return Value:
//    The value that was read
//
// Notes:
//    If the memory read fails in the DAC mode, the failure is reported as an exception
//    via the DacError function.
//
static M128A MemoryRead128(PM128A addr)
{
    return *dac_cast<PTR_M128A>((TADDR)addr);
}

#ifdef DACCESS_COMPILE

// Report failure in the unwinder if the condition is FALSE
#define UNWINDER_ASSERT(Condition) if (!(Condition)) DacError(CORDBG_E_TARGET_INCONSISTENT)

//---------------------------------------------------------------------------------------
//
// The InstructionBuffer class abstracts accessing assembler instructions in the function
// being unwound. It behaves as a memory byte pointer, but it reads the instruction codes
// from the target process being debugged and removes all changes that the debugger
// may have made to the code, e.g. breakpoint instructions.
//
class InstructionBuffer
{
    UINT m_offset;
    SIZE_T m_address;
    UCHAR m_buffer[32];

    // Load the instructions from the target process being debugged
    HRESULT Load()
    {
        HRESULT hr = DacReadAll(TO_TADDR(m_address), m_buffer, sizeof(m_buffer), false);
        if (SUCCEEDED(hr))
        {
            // On X64, we need to replace any patches which are within the requested memory range.
            // This is because the X64 unwinder needs to disassemble the native instructions in order to determine
            // whether the IP is in an epilog.
            MemoryRange range(dac_cast<PTR_VOID>((TADDR)m_address), sizeof(m_buffer));
            hr = DacReplacePatchesInHostMemory(range, m_buffer);
        }

        return hr;
    }

public:

    // Construct the InstructionBuffer for the given address in the target process
    InstructionBuffer(SIZE_T address)
      : m_offset(0),
        m_address(address)
    {
        HRESULT hr = Load();
        if (FAILED(hr))
        {
            // If we have failed to read from the target process, just pretend
            // we've read zeros.
            // The InstructionBuffer is used in code driven epilogue unwinding
            // when we read processor instructions and simulate them.
            // It's very rare to be stopped in an epilogue when
            // getting a stack trace, so if we can't read the
            // code just assume we aren't in an epilogue instead of failing
            // the unwind.
            memset(m_buffer, 0, sizeof(m_buffer));
        }
    }

    // Move to the next byte in the buffer
    InstructionBuffer& operator++()
    {
        m_offset++;
        return *this;
    }

    // Skip delta bytes in the buffer
    InstructionBuffer& operator+=(INT delta)
    {
        m_offset += delta;
        return *this;
    }

    // Return address of the current byte in the buffer
    explicit operator ULONG64()
    {
        return m_address + m_offset;
    }

    // Get the byte at the given index from the current position
    // Invoke DacError if the index is out of the buffer
    UCHAR operator[](int index)
    {
        int realIndex = m_offset + index;
        UNWINDER_ASSERT(realIndex < sizeof(m_buffer));
        return m_buffer[realIndex];
    }
};

//---------------------------------------------------------------------------------------
//
// Given the target address of an UNWIND_INFO structure, this function retrieves all the memory used for
// the UNWIND_INFO, including the variable size array of UNWIND_CODE.  The function returns a host copy
// of the UNWIND_INFO.
//
// Arguments:
//    taUnwindInfo - the target address of an UNWIND_INFO
//
// Return Value:
//    Return a host copy of the UNWIND_INFO, including the array of UNWIND_CODE.
//
// Notes:
//    The host copy of UNWIND_INFO is created from DAC memory, which will be flushed when the DAC cache
//    is flushed (i.e. when the debugee is continued).  Thus, the caller doesn't need to worry about freeing
//    this memory.
//
UNWIND_INFO * DacGetUnwindInfo(TADDR taUnwindInfo)
{
    PTR_UNWIND_INFO pUnwindInfo = PTR_UNWIND_INFO(taUnwindInfo);
    DWORD cbUnwindInfo = offsetof(UNWIND_INFO, UnwindCode) +
        pUnwindInfo->CountOfUnwindCodes * sizeof(UNWIND_CODE);

    // Check if there is a chained unwind info.  If so, it has an extra RUNTIME_FUNCTION tagged to the end.
    if ((pUnwindInfo->Flags & UNW_FLAG_CHAININFO) != 0)
    {
        // If there is an odd number of UNWIND_CODE, we need to adjust for alignment.
        if ((pUnwindInfo->CountOfUnwindCodes & 1) != 0)
        {
            cbUnwindInfo += sizeof(UNWIND_CODE);
        }
        cbUnwindInfo += sizeof(RUNTIME_FUNCTION);
    }
    return reinterpret_cast<UNWIND_INFO *>(DacInstantiateTypeByAddress(taUnwindInfo, cbUnwindInfo, true));
}

//---------------------------------------------------------------------------------------
//
// This function just wraps the DacGetUnwindInfo.
// The DacGetUnwindInfo is called from other places outside of the unwinder, so it
// cannot be merged into the body of this method.
//
UNWIND_INFO * OOPStackUnwinderAMD64::GetUnwindInfo(TADDR taUnwindInfo)
{
    return DacGetUnwindInfo(taUnwindInfo);
}

//---------------------------------------------------------------------------------------
//
// This function is just a wrapper over OOPStackUnwinder.  The runtime can call this function to
// virtually unwind a CONTEXT out-of-process.
//
// Arguments:
//    pContext - This is an in-out parameter.  On entry, this is the CONTEXT to be unwound.
//               On exit, this is the caller CONTEXT.
//
// Return Value:
//    TRUE if the unwinding is successful
//
// Notes:
//    This function overwrites the specified CONTEXT to store the caller CONTEXT.
//

BOOL DacUnwindStackFrame(CONTEXT * pContext, KNONVOLATILE_CONTEXT_POINTERS* pContextPointers)
{
    BOOL res = OOPStackUnwinderAMD64::Unwind(pContext);

    if (res && pContextPointers)
    {
        for (int i = 0; i < 16; i++)
        {
            *(&pContextPointers->Rax + i) = &pContext->Rax + i;
        }
    }

    return res;
}

//---------------------------------------------------------------------------------------
//
// Unwind the given CONTEXT to the caller CONTEXT.  The given CONTEXT will be overwritten.
//
// Arguments:
//    pContext - in-out parameter storing the specified CONTEXT on entry and the unwound CONTEXT on exit
//
// Return Value:
//    TRUE if the unwinding is successful
//

BOOL OOPStackUnwinderAMD64::Unwind(CONTEXT * pContext)
{
    HRESULT hr = E_FAIL;

    ULONG64 uControlPC = (DWORD64)dac_cast<PCODE>(::GetIP(pContext));

    // get the module base
    ULONG64 uImageBase;
    hr = GetModuleBase(uControlPC, &uImageBase);
    if (FAILED(hr))
    {
        return FALSE;
    }

    // get the function entry
    IMAGE_RUNTIME_FUNCTION_ENTRY functionEntry;
    hr = GetFunctionEntry(uControlPC, &functionEntry, sizeof(functionEntry));
    if (FAILED(hr))
    {
        return FALSE;
    }

    // call VirtualUnwind() to do the real work
    ULONG64 EstablisherFrame;
    hr = VirtualUnwind(0, uImageBase, uControlPC, &functionEntry, pContext, NULL, &EstablisherFrame, NULL, NULL);

    return (hr == S_OK);
}

#else // DACCESS_COMPILE

// Report failure in the unwinder if the condition is FALSE
#define UNWINDER_ASSERT _ASSERTE

// For unwinding of the jitted code on non-Windows platforms, the Instruction buffer is
// just a plain pointer to the instruction data.
typedef UCHAR * InstructionBuffer;

//---------------------------------------------------------------------------------------
//
// Return UNWIND_INFO pointer for the given address.
//
UNWIND_INFO * OOPStackUnwinderAMD64::GetUnwindInfo(TADDR taUnwindInfo)
{
    return (UNWIND_INFO *)taUnwindInfo;
}

//---------------------------------------------------------------------------------------
//
// This function behaves like the RtlVirtualUnwind in Windows.
// It virtually unwinds the specified function by executing its
// prologue code backward or its epilogue code forward.
//
// If a context pointers record is specified, then the address where each
// nonvolatile registers is restored from is recorded in the appropriate
// element of the context pointers record.
//
// Arguments:
//
//     HandlerType - Supplies the handler type expected for the virtual unwind.
//         This may be either an exception or an unwind handler. A flag may
//         optionally be supplied to avoid epilogue detection if it is known
//         the specified control PC is not located inside a function epilogue.
//
//     ImageBase - Supplies the base address of the image that contains the
//         function being unwound.
//
//     ControlPc - Supplies the address where control left the specified
//         function.
//
//     FunctionEntry - Supplies the address of the function table entry for the
//         specified function.
//
//     ContextRecord - Supplies the address of a context record.
//
//     HandlerData - Supplies a pointer to a variable that receives a pointer
//         the the language handler data.
//
//     EstablisherFrame - Supplies a pointer to a variable that receives the
//         the establisher frame pointer value.
//
//     ContextPointers - Supplies an optional pointer to a context pointers
//         record.
//
// Return value:
//
//     The handler routine address.  If control did not leave the specified
//     function in either the prologue or an epilogue and a handler of the
//     proper type is associated with the function, then the address of the
//     language specific exception handler is returned. Otherwise, NULL is
//     returned.
//
PEXCEPTION_ROUTINE RtlVirtualUnwind_Unsafe(
    __in ULONG HandlerType,
    __in ULONG64 ImageBase,
    __in ULONG64 ControlPc,
    __in PRUNTIME_FUNCTION FunctionEntry,
    __in OUT PCONTEXT ContextRecord,
    __out PVOID *HandlerData,
    __out PULONG64 EstablisherFrame,
    __inout_opt PKNONVOLATILE_CONTEXT_POINTERS ContextPointers
    )
{
    PEXCEPTION_ROUTINE handlerRoutine;

    HRESULT res = OOPStackUnwinderAMD64::VirtualUnwind(
        HandlerType,
        ImageBase,
        ControlPc,
        (_PIMAGE_RUNTIME_FUNCTION_ENTRY)FunctionEntry,
        ContextRecord,
        HandlerData,
        EstablisherFrame,
        ContextPointers,
        &handlerRoutine);

    _ASSERTE(SUCCEEDED(res));

    return handlerRoutine;
}

#endif // DACCESS_COMPILE

//
//
// <NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE>
//
// Everything below is borrowed from minkernel\ntos\rtl\amd64\exdsptch.c file from Windows
//
// <NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE>
//
//

//----------------------------------------------------------------------------
//
// Copied OS code.
//
// This must be kept in sync with the system unwinder.
// minkernel\ntos\rtl\amd64\exdsptch.c
//
//----------------------------------------------------------------------------

//
// ****** temp - defin elsewhere ******
//

#define SIZE64_PREFIX 0x48
#define ADD_IMM8_OP 0x83
#define ADD_IMM32_OP 0x81
#define JMP_IMM8_OP 0xeb
#define JMP_IMM32_OP 0xe9
#define JMP_IND_OP 0xff
#define LEA_OP 0x8d
#define REPNE_PREFIX 0xf2
#define REP_PREFIX 0xf3
#define POP_OP 0x58
#define RET_OP 0xc3
#define RET_OP_2 0xc2

#define IS_REX_PREFIX(x) (((x) & 0xf0) == 0x40)

#define UNWIND_CHAIN_LIMIT 32

HRESULT
OOPStackUnwinderAMD64::UnwindEpilogue(
    __in ULONG64 ImageBase,
    __in ULONG64 ControlPc,
    __in ULONG EpilogueOffset,
    __in _PIMAGE_RUNTIME_FUNCTION_ENTRY FunctionEntry,
    __inout PCONTEXT ContextRecord,
    __inout_opt PKNONVOLATILE_CONTEXT_POINTERS ContextPointers
)

/*++

Routine Description:

    This function emulates the state change associated with a function
    epilogue by using the corresponding prologue unwind codes of the
    primary function entry corresponding to the specified function.

    The prologue unwind codes can be used to reverse the epilogue since
    the epilogue operations are structured as a mirror-image of the initial
    prologue instructions prior to the establishment of the frame.

Arguments:

    ImageBase - Supplies the base address of the image that contains the
        function being unwound.

    ControlPc - Supplies the address where control left the specified function.

    EpilogueOffset - Supplies the offset within an epilogue of the specified
        instruction pointer address.

    FunctionEntry - Supplies a pointer to the function table entry for the
        specified function. If appropriate, this has already been probed.

    ContextRecord - Supplies a pointer to a context record.

    ContextPointers - Supplies an optional pointer to a context pointers record.

Return Value:

HRESULT.

--*/

{

    ULONG ChainCount;
    ULONG CountOfCodes;
    ULONG CurrentOffset;
    ULONG FirstPushIndex;
    ULONG Index;
    PULONG64 IntegerAddress;
    PULONG64 IntegerRegister;
    ULONG OpInfo;
    PULONG64 ReturnAddress;
    PULONG64 StackAddress;
    NTSTATUS Status;
    PUNWIND_INFO UnwindInfo;
    UNWIND_CODE UnwindOp;

    //
    // A canonical epilogue sequence consists of the following operations:
    //
    // 1. Optional cleanup of fixed and dynamic stack allocations, which is
    //    considered to be outside of the epilogue region.
    //
    //    add rsp, imm
    //        or
    //    lea rsp, disp[fp]
    //
    // 2. Zero or more pop nonvolatile-integer-register[0..15] instructions,
    //    which are unwound using the corresponding UWOP_PUSH_NONVOL opcodes.
    //
    //    pop r64
    //        or
    //    REX.R pop r64
    //
    // 3. An optional one-byte pop r64 to a volatile register to clean up an
    //    RFLAGS register pushed with pushfq. This is marked with a
    //    UWOP_ALLOC_SMALL 8 opcode.
    //
    //    pop rcx
    //
    // 4. A control transfer instruction (ret or jump). In both cases, there
    //    will be no prologue unwind codes remaining after the previous set of
    //    recognized operations are emulated.
    //
    //    ret 0
    //        or
    //    jmp imm
    //        or
    //    jmp [target]
    //        or
    //    iretq
    //
    // N.B. The correctness of these assumptions is based on the ordering
    //      of unwind codes and the mirroring of epilogue and prologue
    //      regions.
    //
    // Find the function's primary entry, which contains the relevant frame
    // adjustment unwind codes.
    //
    // Locate the first push unwind code. This code requires that all pushes
    // occur within a single function entry, though not necessarily within the
    // root function entry of a chained function.
    //

    ChainCount = 0;
    for (;;) {
        UnwindInfo = GetUnwindInfo(FunctionEntry->UnwindInfoAddress + ImageBase);
        if (UnwindInfo == NULL)
        {
            return HRESULT_FROM_WIN32(ERROR_READ_FAULT);
        }
        CountOfCodes = UnwindInfo->CountOfUnwindCodes;
        FirstPushIndex = 0;
        while (FirstPushIndex < CountOfCodes) {
            UnwindOp = UnwindInfo->UnwindCode[FirstPushIndex];
            if ((UnwindOp.UnwindOp == UWOP_PUSH_NONVOL) ||
                (UnwindOp.UnwindOp == UWOP_PUSH_MACHFRAME)) {

                break;
            }

            FirstPushIndex += UnwindOpSlots(UnwindOp);
        }

        if (FirstPushIndex < CountOfCodes) {
            break;
        }

        //
        // If a chained parent function entry exists, continue looking for
        // push opcodes in the parent.
        //

        if ((UnwindInfo->Flags & UNW_FLAG_CHAININFO) == 0) {
            break;
        }

        ChainCount += 1;
        if (ChainCount > UNWIND_CHAIN_LIMIT) {
            return E_FAIL;
        }

        Index = CountOfCodes;
        if (Index % 2 != 0) {
            Index += 1;
        }

        FunctionEntry = (_PIMAGE_RUNTIME_FUNCTION_ENTRY)&UnwindInfo->UnwindCode[Index];
    }

    //
    // Unwind any push codes that have not already been reversed by the
    // epilogue.
    //

    CurrentOffset = 0;
    IntegerRegister = &ContextRecord->Rax;
    for (Index = FirstPushIndex; Index < CountOfCodes; Index += 1) {
        UnwindOp = UnwindInfo->UnwindCode[Index];
        OpInfo = UnwindOp.OpInfo;

        if (UnwindOp.UnwindOp != UWOP_PUSH_NONVOL) {
            break;
        }

        if (CurrentOffset >= EpilogueOffset) {
            IntegerAddress = (PULONG64)(ContextRecord->Rsp);

            ContextRecord->Rsp += 8;
            IntegerRegister[OpInfo] = MemoryRead64(IntegerAddress);
            if (ARGUMENT_PRESENT(ContextPointers)) {
                ContextPointers->IntegerContext[OpInfo] = IntegerAddress;
            }
        }

        //
        // POP r64 is encoded as (58h + r64) for the lower 8 general-purpose
        // registers and REX.R, (58h + r64) for r8 - r15.
        //

        CurrentOffset += 1;
        if (OpInfo >= 8) {
            CurrentOffset += 1;
        }
    }

    //
    // Check for an UWOP_ALLOC_SMALL 8 directive, which corresponds to a push
    // of the FLAGS register.
    //

    if ((Index < CountOfCodes) &&
        (UnwindOp.UnwindOp == UWOP_ALLOC_SMALL) && (OpInfo == 0)) {

        if (CurrentOffset >= EpilogueOffset) {
            ContextRecord->Rsp += 8;
        }

        CurrentOffset += 1;
        Index += 1;
    }

    //
    // Check for a machine frame.
    //

    if (Index < CountOfCodes) {
        UnwindOp = UnwindInfo->UnwindCode[Index];
        if (UnwindOp.UnwindOp == UWOP_PUSH_MACHFRAME) {
            ReturnAddress = (PULONG64)(ContextRecord->Rsp);
            StackAddress = (PULONG64)(ContextRecord->Rsp + (3 * 8));

            ContextRecord->Rip = MemoryRead64(ReturnAddress);
            ContextRecord->Rsp = MemoryRead64(StackAddress);
            return S_OK;
        }

        //
        // Any remaining operation must be a machine frame.
        //

        UNWINDER_ASSERT(FALSE);
    }

    //
    // Emulate a return operation.
    //

    IntegerAddress = (PULONG64)(ContextRecord->Rsp);

    ContextRecord->Rip = MemoryRead64(IntegerAddress);
    ContextRecord->Rsp += 8;
    return S_OK;
}

HRESULT
OOPStackUnwinderAMD64::UnwindPrologue(
    __in ULONG64 ImageBase,
    __in ULONG64 ControlPc,
    __in ULONG64 FrameBase,
    __in _PIMAGE_RUNTIME_FUNCTION_ENTRY FunctionEntry,
    __inout PCONTEXT ContextRecord,
    __inout_opt PKNONVOLATILE_CONTEXT_POINTERS ContextPointers,
    __deref_out _PIMAGE_RUNTIME_FUNCTION_ENTRY *FinalFunctionEntry
    )

/*++

Routine Description:

    This function processes unwind codes and reverses the state change
    effects of a prologue. If the specified unwind information contains
    chained unwind information, then that prologue is unwound recursively.
    As the prologue is unwound state changes are recorded in the specified
    context structure and optionally in the specified context pointers
    structures.

Arguments:

    ImageBase - Supplies the base address of the image that contains the
        function being unwound.

    ControlPc - Supplies the address where control left the specified
        function.

    FrameBase - Supplies the base of the stack frame subject function stack
         frame.

    FunctionEntry - Supplies the address of the function table entry for the
        specified function.

    ContextRecord - Supplies the address of a context record.

    ContextPointers - Supplies an optional pointer to a context pointers
        record.

    FinalFunctionEntry - Supplies a pointer to a variable that receives the
        final function entry after the specified function entry and all
        descendent chained entries have been unwound. This will have been
        probed as appropriate.

Return Value:

    HRESULT.

--*/

{

    ULONG ChainCount;
    PM128A FloatingAddress;
    PM128A FloatingRegister;
    ULONG FrameOffset;
    ULONG Index;
    PULONG64 IntegerAddress;
    PULONG64 IntegerRegister;
    BOOLEAN MachineFrame;
    ULONG OpInfo;
    ULONG PrologOffset;
    PULONG64 ReturnAddress;
    PULONG64 StackAddress;
    PUNWIND_INFO UnwindInfo;
    ULONG UnwindOp;

    //
    // Process the unwind codes for the specified function entry and all its
    // descendent chained function entries.
    //

    ChainCount = 0;
    FloatingRegister = &ContextRecord->Xmm0;
    IntegerRegister = &ContextRecord->Rax;
    do {
        Index = 0;
        MachineFrame = FALSE;
        PrologOffset = (ULONG)(ControlPc - (FunctionEntry->BeginAddress + ImageBase));

        UnwindInfo = GetUnwindInfo(ImageBase + FunctionEntry->UnwindInfoAddress);
        if (UnwindInfo == NULL)
        {
            return HRESULT_FROM_WIN32(ERROR_READ_FAULT);
        }

        while (Index < UnwindInfo->CountOfUnwindCodes) {

            //
            // If the prologue offset is greater than the next unwind code
            // offset, then simulate the effect of the unwind code.
            //

            UnwindOp = UnwindInfo->UnwindCode[Index].UnwindOp;
            if (UnwindOp > UWOP_PUSH_MACHFRAME) {
                return E_UNEXPECTED;
            }

            OpInfo = UnwindInfo->UnwindCode[Index].OpInfo;
            if (PrologOffset >= UnwindInfo->UnwindCode[Index].CodeOffset) {
                switch (UnwindOp) {

                    //
                    // Push nonvolatile integer register.
                    //
                    // The operation information is the register number of
                    // the register than was pushed.
                    //

                case UWOP_PUSH_NONVOL:
                    IntegerAddress = (PULONG64)ContextRecord->Rsp;
                    IntegerRegister[OpInfo] = MemoryRead64(IntegerAddress);

                    if (ARGUMENT_PRESENT(ContextPointers)) {
                        ContextPointers->IntegerContext[OpInfo] = IntegerAddress;
                    }

                    ContextRecord->Rsp += 8;
                    break;

                    //
                    // Allocate a large sized area on the stack.
                    //
                    // The operation information determines if the size is
                    // 16- or 32-bits.
                    //

                case UWOP_ALLOC_LARGE:
                    Index += 1;
                    FrameOffset = UnwindInfo->UnwindCode[Index].FrameOffset;
                    if (OpInfo != 0) {
                        Index += 1;
                        FrameOffset += (UnwindInfo->UnwindCode[Index].FrameOffset << 16);

                    } else {
                        // The 16-bit form is scaled.
                        FrameOffset *= 8;
                    }

                    ContextRecord->Rsp += FrameOffset;
                    break;

                    //
                    // Allocate a small sized area on the stack.
                    //
                    // The operation information is the size of the unscaled
                    // allocation size (8 is the scale factor) minus 8.
                    //

                case UWOP_ALLOC_SMALL:
                    ContextRecord->Rsp += (OpInfo * 8) + 8;
                    break;

                    //
                    // Establish the the frame pointer register.
                    //
                    // The operation information is not used.
                    //

                case UWOP_SET_FPREG:
                    ContextRecord->Rsp = IntegerRegister[UnwindInfo->FrameRegister];
                    ContextRecord->Rsp -= UnwindInfo->FrameOffset * 16;
                    break;

                    //
                    // Save nonvolatile integer register on the stack using a
                    // 16-bit displacment.
                    //
                    // The operation information is the register number.
                    //

                case UWOP_SAVE_NONVOL:
                    Index += 1;
                    FrameOffset = UnwindInfo->UnwindCode[Index].FrameOffset * 8;
                    IntegerAddress = (PULONG64)(FrameBase + FrameOffset);
                    IntegerRegister[OpInfo] = MemoryRead64(IntegerAddress);

                    if (ARGUMENT_PRESENT(ContextPointers)) {
                        ContextPointers->IntegerContext[OpInfo] = IntegerAddress;
                    }

                    break;

                    //
                    // Save nonvolatile integer register on the stack using a
                    // 32-bit displacment.
                    //
                    // The operation information is the register number.
                    //

                case UWOP_SAVE_NONVOL_FAR:
                    Index += 2;
                    FrameOffset = UnwindInfo->UnwindCode[Index - 1].FrameOffset;
                    FrameOffset += UnwindInfo->UnwindCode[Index].FrameOffset << 16;
                    IntegerAddress = (PULONG64)(FrameBase + FrameOffset);
                    IntegerRegister[OpInfo] = MemoryRead64(IntegerAddress);

                    if (ARGUMENT_PRESENT(ContextPointers)) {
                        ContextPointers->IntegerContext[OpInfo] = IntegerAddress;
                    }

                    break;

                    //
                    // Function epilog marker (ignored for prologue unwind).
                    //

               case UWOP_EPILOG:
                    Index += 1;
                    break;

                    //
                    // Spare unused codes.
                    //

                case UWOP_SPARE_CODE:

                    UNWINDER_ASSERT(FALSE);

                    Index += 2;
                    break;

                    //
                    // Save a nonvolatile XMM(128) register on the stack using a
                    // 16-bit displacement.
                    //
                    // The operation information is the register number.
                    //

                case UWOP_SAVE_XMM128:
                    Index += 1;
                    FrameOffset = UnwindInfo->UnwindCode[Index].FrameOffset * 16;
                    FloatingAddress = (PM128A)(FrameBase + FrameOffset);
                    FloatingRegister[OpInfo] = MemoryRead128(FloatingAddress);

                    if (ARGUMENT_PRESENT(ContextPointers)) {
                        ContextPointers->FloatingContext[OpInfo] = FloatingAddress;
                    }

                    break;

                    //
                    // Save a nonvolatile XMM(128) register on the stack using
                    // a 32-bit displacement.
                    //
                    // The operation information is the register number.
                    //

                case UWOP_SAVE_XMM128_FAR:
                    Index += 2;
                    FrameOffset = UnwindInfo->UnwindCode[Index - 1].FrameOffset;
                    FrameOffset += UnwindInfo->UnwindCode[Index].FrameOffset << 16;
                    FloatingAddress = (PM128A)(FrameBase + FrameOffset);
                    FloatingRegister[OpInfo] = MemoryRead128(FloatingAddress);

                    if (ARGUMENT_PRESENT(ContextPointers)) {
                        ContextPointers->FloatingContext[OpInfo] = FloatingAddress;
                    }

                    break;

                    //
                    // Push a machine frame on the stack.
                    //
                    // The operation information determines whether the
                    // machine frame contains an error code or not.
                    //

                case UWOP_PUSH_MACHFRAME:
                    MachineFrame = TRUE;
                    ReturnAddress = (PULONG64)ContextRecord->Rsp;
                    StackAddress = (PULONG64)(ContextRecord->Rsp + (3 * 8));
                    if (OpInfo != 0) {
                        ReturnAddress += 1;
                        StackAddress +=  1;
                    }

                    ContextRecord->Rip = MemoryRead64(ReturnAddress);
                    ContextRecord->Rsp = MemoryRead64(StackAddress);

                    break;

                    //
                    // Unused codes.
                    //

                default:
                    //RtlRaiseStatus(STATUS_BAD_FUNCTION_TABLE);
                    break;
                }

                Index += 1;

            } else {

                //
                // Skip this unwind operation by advancing the slot index
                // by the number of slots consumed by this operation.
                //

                Index += UnwindOpSlots(UnwindInfo->UnwindCode[Index]);
            }
        }

        //
        // If chained unwind information is specified, then set the function
        // entry address to the chained function entry and continue the scan.
        // Otherwise, determine the return address if a machine frame was not
        // encountered during the scan of the unwind codes and terminate the
        // scan.
        //

        if ((UnwindInfo->Flags & UNW_FLAG_CHAININFO) != 0) {

            _PIMAGE_RUNTIME_FUNCTION_ENTRY ChainEntry;

            Index = UnwindInfo->CountOfUnwindCodes;
            if ((Index & 1) != 0) {
                Index += 1;
            }

            // GetUnwindInfo looks for CHAININFO and reads
            // the trailing RUNTIME_FUNCTION so we can just
            // directly use the data sitting in UnwindInfo.
            FunctionEntry = (_PIMAGE_RUNTIME_FUNCTION_ENTRY)
                &UnwindInfo->UnwindCode[Index];
        } else {

            if (MachineFrame == FALSE) {
                ContextRecord->Rip = MemoryRead64((PULONG64)ContextRecord->Rsp);
                ContextRecord->Rsp += 8;
            }

            break;
        }

        //
        // Limit the number of iterations possible for chained function table
        // entries.
        //

        ChainCount += 1;
        UNWINDER_ASSERT(ChainCount <= UNWIND_CHAIN_LIMIT);

    } while (TRUE);

    *FinalFunctionEntry = FunctionEntry;
    return S_OK;
}

HRESULT
OOPStackUnwinderAMD64::VirtualUnwind(
    __in DWORD HandlerType,
    __in ULONG64 ImageBase,
    __in ULONG64 ControlPc,
    __in _PIMAGE_RUNTIME_FUNCTION_ENTRY FunctionEntry,
    __inout PCONTEXT ContextRecord,
    __out PVOID *HandlerData,
    __out PULONG64 EstablisherFrame,
    __inout_opt PKNONVOLATILE_CONTEXT_POINTERS ContextPointers,
    __deref_opt_out_opt PEXCEPTION_ROUTINE *HandlerRoutine
    )

/*++

Routine Description:

    This function virtually unwinds the specified function by executing its
    prologue code backward or its epilogue code forward.

    If a context pointers record is specified, then the address where each
    nonvolatile registers is restored from is recorded in the appropriate
    element of the context pointers record.

Arguments:

    HandlerType - Supplies the handler type expected for the virtual unwind.
        This may be either an exception or an unwind handler. A flag may
        optionally be supplied to avoid epilogue detection if it is known
        the specified control PC is not located inside a function epilogue.

    ImageBase - Supplies the base address of the image that contains the
        function being unwound.

    ControlPc - Supplies the address where control left the specified
        function.

    FunctionEntry - Supplies the address of the function table entry for the
        specified function.

    ContextRecord - Supplies the address of a context record.

    HandlerData - Supplies a pointer to a variable that receives a pointer
        the the language handler data.

    EstablisherFrame - Supplies a pointer to a variable that receives the
        the establisher frame pointer value.

    ContextPointers - Supplies an optional pointer to a context pointers
        record.

    HandlerRoutine - Supplies an optional pointer to a variable that receives
        the handler routine address.  If control did not leave the specified
        function in either the prologue or an epilogue and a handler of the
        proper type is associated with the function, then the address of the
        language specific exception handler is returned. Otherwise, NULL is
        returned.
--*/

{

    ULONG64 BranchTarget;
    LONG Displacement;
    ULONG EpilogueOffset;
    ULONG EpilogueSize;
    PEXCEPTION_ROUTINE FoundHandler;
    ULONG FrameRegister;
    ULONG Index;
    BOOL InEpilogue;
    PULONG64 IntegerAddress;
    PULONG64 IntegerRegister;
    _PIMAGE_RUNTIME_FUNCTION_ENTRY PrimaryFunctionEntry;
    ULONG PrologOffset;
    ULONG RegisterNumber;
    ULONG RelativePc;
    HRESULT Status;
    PUNWIND_INFO UnwindInfo;
    ULONG UnwindVersion;
    UNWIND_CODE UnwindOp;

    FoundHandler = NULL;
    UnwindInfo = GetUnwindInfo(ImageBase + FunctionEntry->UnwindInfoAddress);
    if (UnwindInfo == NULL)
    {
        return HRESULT_FROM_WIN32(ERROR_READ_FAULT);
    }

    UnwindVersion = UnwindInfo->Version;

    //
    // If the specified function does not use a frame pointer, then the
    // establisher frame is the contents of the stack pointer. This may
    // not actually be the real establisher frame if control left the
    // function from within the prologue. In this case the establisher
    // frame may be not required since control has not actually entered
    // the function and prologue entries cannot refer to the establisher
    // frame before it has been established, i.e., if it has not been
    // established, then no save unwind codes should be encountered during
    // the unwind operation.
    //
    // If the specified function uses a frame pointer and control left the
    // function outside of the prologue or the unwind information contains
    // a chained information structure, then the establisher frame is the
    // contents of the frame pointer.
    //
    // If the specified function uses a frame pointer and control left the
    // function from within the prologue, then the set frame pointer unwind
    // code must be looked up in the unwind codes to determine if the
    // contents of the stack pointer or the contents of the frame pointer
    // should be used for the establisher frame. This may not actually be
    // the real establisher frame. In this case the establisher frame may
    // not be required since control has not actually entered the function
    // and prologue entries cannot refer to the establisher frame before it
    // has been established, i.e., if it has not been established, then no
    // save unwind codes should be encountered during the unwind operation.
    //
    // N.B. The correctness of these assumptions is based on the ordering of
    //      unwind codes.
    //

    PrologOffset = (ULONG)(ControlPc - (FunctionEntry->BeginAddress + ImageBase));
    if (UnwindInfo->FrameRegister == 0) {
        *EstablisherFrame = ContextRecord->Rsp;

    } else if ((PrologOffset >= UnwindInfo->SizeOfProlog) ||
               ((UnwindInfo->Flags & UNW_FLAG_CHAININFO) != 0)) {

        *EstablisherFrame = (&ContextRecord->Rax)[UnwindInfo->FrameRegister];
        *EstablisherFrame -= UnwindInfo->FrameOffset * 16;

    } else {
        Index = 0;
        while (Index < UnwindInfo->CountOfUnwindCodes) {
            UnwindOp = UnwindInfo->UnwindCode[Index];
            if (UnwindOp.UnwindOp == UWOP_SET_FPREG) {
                break;
            }

            Index += UnwindOpSlots(UnwindOp);
        }

        if (PrologOffset >= UnwindInfo->UnwindCode[Index].CodeOffset) {
            *EstablisherFrame = (&ContextRecord->Rax)[UnwindInfo->FrameRegister];
            *EstablisherFrame -= UnwindInfo->FrameOffset * 16;

        } else {
            *EstablisherFrame = ContextRecord->Rsp;
        }
    }

    //
    // Check if control left the specified function during an epilogue
    // sequence and emulate the execution of the epilogue forward and
    // return no exception handler.
    //
    // If the unwind version indicates the absence of epilogue unwind codes
    // this is done by emulating the instruction stream. Otherwise, epilogue
    // detection and emulation is performed using the function unwind codes.
    //

    InEpilogue = FALSE;
    if (UnwindVersion < 2) {
        InstructionBuffer InstrBuffer = (InstructionBuffer)ControlPc;
        InstructionBuffer NextByte = InstrBuffer;

        //
        // Check for one of:
        //
        //   add rsp, imm8
        //       or
        //   add rsp, imm32
        //       or
        //   lea rsp, -disp8[fp]
        //       or
        //   lea rsp, -disp32[fp]
        //

        if ((NextByte[0] == SIZE64_PREFIX) &&
            (NextByte[1] == ADD_IMM8_OP) &&
            (NextByte[2] == 0xc4)) {

            //
            // add rsp, imm8.
            //

            NextByte += 4;

        } else if ((NextByte[0] == SIZE64_PREFIX) &&
                   (NextByte[1] == ADD_IMM32_OP) &&
                   (NextByte[2] == 0xc4)) {

            //
            // add rsp, imm32.
            //

            NextByte += 7;

        } else if (((NextByte[0] & 0xfe) == SIZE64_PREFIX) &&
                (NextByte[1] == LEA_OP)) {

            FrameRegister = ((NextByte[0] & 0x1) << 3) | (NextByte[2] & 0x7);
            if ((FrameRegister != 0) &&
                (FrameRegister == UnwindInfo->FrameRegister)) {

                if ((NextByte[2] & 0xf8) == 0x60) {

                    //
                    // lea rsp, disp8[fp].
                    //

                    NextByte += 4;

                } else if ((NextByte[2] &0xf8) == 0xa0) {

                    //
                    // lea rsp, disp32[fp].
                    //

                    NextByte += 7;
                }
            }
        }

        //
        // Check for any number of:
        //
        //   pop nonvolatile-integer-register[0..15].
        //

        while (TRUE) {
            if ((NextByte[0] & 0xf8) == POP_OP) {
                NextByte += 1;

            } else if (IS_REX_PREFIX(NextByte[0]) &&
                       ((NextByte[1] & 0xf8) == POP_OP)) {

                NextByte += 2;

            } else {
                break;
            }
        }

        //
        // A REPNE prefix may optionally precede a control transfer
        // instruction with no effect on unwinding.
        //

        if (NextByte[0] == REPNE_PREFIX) {
            NextByte += 1;
        }

        //
        // If the next instruction is a return or an appropriate jump, then
        // control is currently in an epilogue and execution of the epilogue
        // should be emulated. Otherwise, execution is not in an epilogue and
        // the prologue should be unwound.
        //

        InEpilogue = FALSE;
        if ( ((NextByte[0] == RET_OP) ||
              (NextByte[0] == RET_OP_2)) ||
            (((NextByte[0] == REP_PREFIX) && (NextByte[1] == RET_OP)))) {

            //
            // A return is an unambiguous indication of an epilogue.
            //

            InEpilogue = TRUE;

        } else if ((NextByte[0] == JMP_IMM8_OP) ||
                   (NextByte[0] == JMP_IMM32_OP)) {

            //
            // An unconditional branch to a target that is equal to the start of
            // or outside of this routine is logically a call to another function.
            //

            BranchTarget = (ULONG64)NextByte - ImageBase;
            if (NextByte[0] == JMP_IMM8_OP) {
                BranchTarget += 2 + (CHAR)NextByte[1];

            } else {
                LONG32 delta = NextByte[1] | (NextByte[2] << 8) |
                               (NextByte[3] << 16) | (NextByte[4] << 24);
                BranchTarget += 5 + delta;

            }

            //
            // Determine whether the branch target refers to code within this
            // function. If not, then it is an epilogue indicator.
            //
            // A branch to the start of self implies a recursive call, so
            // is treated as an epilogue.
            //

            if (BranchTarget < FunctionEntry->BeginAddress ||
                BranchTarget >= FunctionEntry->EndAddress) {

                //
                // The branch target is outside of the region described by
                // this function entry.  See whether it is contained within
                // an indirect function entry associated with this same
                // function.
                //
                // If not, then the branch target really is outside of
                // this function.
                //

                PrimaryFunctionEntry =
                    SameFunction(FunctionEntry,
                                 ImageBase,
                                 BranchTarget + ImageBase);

                if ((PrimaryFunctionEntry == NULL) ||
                    (BranchTarget == PrimaryFunctionEntry->BeginAddress)) {

                    InEpilogue = TRUE;
                }

            } else if ((BranchTarget == FunctionEntry->BeginAddress) &&
                       ((UnwindInfo->Flags & UNW_FLAG_CHAININFO) == 0)) {

                InEpilogue = TRUE;
            }

        } else if ((NextByte[0] == JMP_IND_OP) && (NextByte[1] == 0x25)) {

            //
            // An unconditional jump indirect.
            //
            // This is a jmp outside of the function, probably a tail call
            // to an import function.
            //

            InEpilogue = TRUE;

        } else if (((NextByte[0] & 0xf8) == SIZE64_PREFIX) &&
                   (NextByte[1] == 0xff) &&
                   (NextByte[2] & 0x38) == 0x20) {

            //
            // This is an indirect jump opcode: 0x48 0xff /4.  The 64-bit
            // flag (REX.W) is always redundant here, so its presence is
            // overloaded to indicate a branch out of the function - a tail
            // call.
            //
            // Such an opcode is an unambiguous epilogue indication.
            //

            InEpilogue = TRUE;
        }

        if (InEpilogue != FALSE) {
            IntegerRegister = &ContextRecord->Rax;
            NextByte = InstrBuffer;

            //
            // Emulate one of (if any):
            //
            //   add rsp, imm8
            //       or
            //   add rsp, imm32
            //       or
            //   lea rsp, disp8[frame-register]
            //       or
            //   lea rsp, disp32[frame-register]
            //

            if ((NextByte[0] & 0xf8) == SIZE64_PREFIX) {

                if (NextByte[1] == ADD_IMM8_OP) {

                    //
                    // add rsp, imm8.
                    //

                    ContextRecord->Rsp += (CHAR)NextByte[3];
                    NextByte += 4;

                }
                else if (NextByte[1] == ADD_IMM32_OP) {

                    //
                    // add rsp, imm32.
                    //

                    Displacement = NextByte[3] | (NextByte[4] << 8);
                    Displacement |= (NextByte[5] << 16) | (NextByte[6] << 24);
                    ContextRecord->Rsp += Displacement;
                    NextByte += 7;

                }
                else if (NextByte[1] == LEA_OP) {
                    if ((NextByte[2] & 0xf8) == 0x60) {

                        //
                        // lea rsp, disp8[frame-register].
                        //

                        ContextRecord->Rsp = IntegerRegister[FrameRegister];
                        ContextRecord->Rsp += (CHAR)NextByte[3];
                        NextByte += 4;

                    }
                    else if ((NextByte[2] & 0xf8) == 0xa0) {

                        //
                        // lea rsp, disp32[frame-register].
                        //

                        Displacement = NextByte[3] | (NextByte[4] << 8);
                        Displacement |= (NextByte[5] << 16) | (NextByte[6] << 24);
                        ContextRecord->Rsp = IntegerRegister[FrameRegister];
                        ContextRecord->Rsp += Displacement;
                        NextByte += 7;
                    }
                }
            }

            //
            // Emulate any number of (if any):
            //
            //   pop nonvolatile-integer-register.
            //

            while (TRUE) {
                if ((NextByte[0] & 0xf8) == POP_OP) {

                    //
                    // pop nonvolatile-integer-register[0..7]
                    //

                    RegisterNumber = NextByte[0] & 0x7;
                    IntegerAddress = (PULONG64)ContextRecord->Rsp;
                    IntegerRegister[RegisterNumber] = MemoryRead64(IntegerAddress);

                    if (ARGUMENT_PRESENT(ContextPointers)) {
                        ContextPointers->IntegerContext[RegisterNumber] = IntegerAddress;
                    }

                    ContextRecord->Rsp += 8;
                    NextByte += 1;

                }
                else if (IS_REX_PREFIX(NextByte[0]) &&
                    (NextByte[1] & 0xf8) == POP_OP) {

                    //
                    // pop nonvolatile-integer-register[8..15]
                    //

                    RegisterNumber = ((NextByte[0] & 1) << 3) | (NextByte[1] & 0x7);
                    IntegerAddress = (PULONG64)ContextRecord->Rsp;
                    IntegerRegister[RegisterNumber] = MemoryRead64(IntegerAddress);

                    if (ARGUMENT_PRESENT(ContextPointers)) {
                        ContextPointers->IntegerContext[RegisterNumber] = IntegerAddress;
                    }

                    ContextRecord->Rsp += 8;
                    NextByte += 2;

                }
                else {
                    break;
                }
            }

            //
            // Emulate return and return null exception handler.
            //
            // Note: This instruction might in fact be a jmp, however
            //       we want to emulate a return regardless.
            //

            ContextRecord->Rip = MemoryRead64((PULONG64)ContextRecord->Rsp);
            ContextRecord->Rsp += 8;
            goto ExitSetHandler;
        }

    } else if (UnwindInfo->CountOfUnwindCodes != 0) {

        UNWINDER_ASSERT(UnwindVersion >= 2);

        //
        // Capture the first unwind code and check if it is an epilogue code.
        // If it is not an epilogue code, the current function entry does not
        // contain any epilogues (it could represent a body region of a
        // separated function or it could represent a function which never
        // returns).
        //

        UnwindOp = UnwindInfo->UnwindCode[0];
        if (UnwindOp.UnwindOp == UWOP_EPILOG) {
            EpilogueSize = UnwindOp.CodeOffset;

            UNWINDER_ASSERT(EpilogueSize != 0);
            //
            // If the low bit of the OpInfo field of the first epilogue code
            // is set, the function has a single epilogue at the end of the
            // function. Otherwise, subsequent epilogue unwind codes indicate
            // the offset of the epilogue(s) from the function end and the
            // relative PC must be compared against each epilogue record.
            //
            // N.B. The relative instruction pointer may not be within the
            //      bounds of the runtime function entry if control left the
            //      function in a region described by an indirect function
            //      entry. Such a region cannot contain any epilogues.
            //

            RelativePc = (ULONG)(ControlPc - ImageBase);
            if ((UnwindOp.OpInfo & 1) != 0) {
                EpilogueOffset = FunctionEntry->EndAddress - EpilogueSize;
                if (RelativePc - EpilogueOffset < EpilogueSize) {
                    InEpilogue = TRUE;
                }
            }

            if (InEpilogue == FALSE) {
                for (Index = 1; Index < UnwindInfo->CountOfUnwindCodes; Index += 1) {
                    UnwindOp = UnwindInfo->UnwindCode[Index];

                    if (UnwindOp.UnwindOp == UWOP_EPILOG) {
                        EpilogueOffset = UnwindOp.EpilogueCode.OffsetLow +
                                            UnwindOp.EpilogueCode.OffsetHigh * 256;

                        //
                        // An epilogue offset of 0 indicates that this is
                        // a padding entry (the number of epilogue codes
                        // is a multiple of 2).
                        //

                        if (EpilogueOffset == 0) {
                            break;
                        }

                        EpilogueOffset = FunctionEntry->EndAddress - EpilogueOffset;
                        if (RelativePc - EpilogueOffset < EpilogueSize) {

                            UNWINDER_ASSERT(EpilogueOffset != FunctionEntry->EndAddress);
                            InEpilogue = TRUE;
                            break;
                        }

                    } else {
                        break;
                    }
                }
            }

            if (InEpilogue != FALSE) {
                Status = UnwindEpilogue(ImageBase,
                                        ControlPc,
                                        RelativePc - EpilogueOffset,
                                        FunctionEntry,
                                        ContextRecord,
                                        ContextPointers);

                goto ExitSetHandler;
            }
        }
    }

    //
    // Control left the specified function outside an epilogue. Unwind the
    // subject function and any chained unwind information.
    //

    Status = UnwindPrologue(ImageBase,
                            ControlPc,
                            *EstablisherFrame,
                            FunctionEntry,
                            ContextRecord,
                            ContextPointers,
                            &FunctionEntry);

    if (Status != S_OK) {
        return Status;
    }

    //
    // If control left the specified function outside of the prologue and
    // the function has a handler that matches the specified type, then
    // return the address of the language specific exception handler.
    // Otherwise, return NULL.
    //

    if (HandlerType != 0) {
        PrologOffset = (ULONG)(ControlPc - (FunctionEntry->BeginAddress + ImageBase));
        UnwindInfo = GetUnwindInfo(FunctionEntry->UnwindInfoAddress + ImageBase);
        if (UnwindInfo == NULL)
        {
            return HRESULT_FROM_WIN32(ERROR_READ_FAULT);
        }
        if ((PrologOffset >= UnwindInfo->SizeOfProlog) &&
            ((UnwindInfo->Flags & HandlerType) != 0)) {

            Index = UnwindInfo->CountOfUnwindCodes;
            if ((Index & 1) != 0) {
                Index += 1;
            }

            *HandlerData = &UnwindInfo->UnwindCode[Index + 2];
            FoundHandler = (PEXCEPTION_ROUTINE)(*((PULONG)&UnwindInfo->UnwindCode[Index]) + ImageBase);
        }
    }

ExitSetHandler:
    if (ARGUMENT_PRESENT(HandlerRoutine)) {
        *HandlerRoutine = FoundHandler;
    }

    return S_OK;
}

_PIMAGE_RUNTIME_FUNCTION_ENTRY
OOPStackUnwinderAMD64::LookupPrimaryFunctionEntry(
    __in _PIMAGE_RUNTIME_FUNCTION_ENTRY FunctionEntry,
    __in ULONG64 ImageBase

    )

/*++

Routine Description:

    This function determines whether the supplied function entry is a primary
    function entry or a chained function entry. If it is a chained function
    entry, then the primary function entry is returned.

Arguments:

    FunctionEntry - Supplies a pointer to the function entry for which the
        associated primary function entry will be located.

    ImageBase - Supplies the base address of the image containing the
        supplied function entry.

Return Value:

    A pointer to the primary function entry is returned as the function value.

--*/

{

    ULONG ChainCount;
    ULONG Index;
    PUNWIND_INFO UnwindInfo;

    //
    // Locate the unwind information and determine whether it is chained.
    // If the unwind information is chained, then locate the parent function
    // entry and loop again.
    //

    ChainCount = 0;
    do {
        UnwindInfo = GetUnwindInfo(FunctionEntry->UnwindInfoAddress + ImageBase);
        if ((UnwindInfo == NULL) || ((UnwindInfo->Flags & UNW_FLAG_CHAININFO) == 0))
        {
            break;
        }

        Index = UnwindInfo->CountOfUnwindCodes;
        if ((Index & 1) != 0) {
            Index += 1;
        }

        FunctionEntry = (_PIMAGE_RUNTIME_FUNCTION_ENTRY)&UnwindInfo->UnwindCode[Index];

        //
        // Limit the number of iterations possible for chained function table
        // entries.
        //

        ChainCount += 1;
        UNWINDER_ASSERT(ChainCount <= UNWIND_CHAIN_LIMIT);

    } while (TRUE);

    return FunctionEntry;
}

_PIMAGE_RUNTIME_FUNCTION_ENTRY
OOPStackUnwinderAMD64::SameFunction(
    __in _PIMAGE_RUNTIME_FUNCTION_ENTRY FunctionEntry,
    __in ULONG64 ImageBase,
    __in ULONG64 ControlPc
    )

/*++

Routine Description:

    This function determines whether the address supplied by ControlPc lies
    anywhere within the function associated with FunctionEntry.

Arguments:

    FunctionEntry - Supplies a pointer to a function entry (primary or chained)
        associated with the function.

    ImageBase - Supplies the base address of the image containing the supplied
        function entry.

    ControlPc - Supplies the address that will be tested for inclusion within
        the function associated with FunctionEntry.

Return Value:

    If the address of the unwind information for the specified function is
    equal to the address of the unwind information for the control PC, then
    a pointer to a function table entry that describes the primary function
    table entry is returned as the function value. Otherwise, NULL is returned.

--*/

{
    _PIMAGE_RUNTIME_FUNCTION_ENTRY PrimaryFunctionEntry;
    _IMAGE_RUNTIME_FUNCTION_ENTRY TargetFunctionEntry;
    ULONG64 TargetImageBase;

    //
    // Find the unwind information referenced by the primary function entry
    // associated with the specified function entry.
    //

    PrimaryFunctionEntry = LookupPrimaryFunctionEntry(FunctionEntry,
                                                      ImageBase);

    //
    // Determine the function entry containing the control Pc and similarly
    // resolve its primary function entry.  If no function entry can be
    // found then the control pc resides in a different function.
    //

    if (GetModuleBase(ControlPc, &TargetImageBase) != S_OK ||
        GetFunctionEntry(ControlPc,
                         &TargetFunctionEntry,
                         sizeof(TargetFunctionEntry)) != S_OK) {
        return NULL;
    }

    //
    // Lookup the primary function entry associated with the target function
    // entry.
    //

    TargetFunctionEntry = *LookupPrimaryFunctionEntry(&TargetFunctionEntry,
                                                      TargetImageBase);

    //
    // If the beginning offset of the two function entries are equal, then
    // return the address of the primary function entry. Otherwise, return
    // NULL.
    //

    if (PrimaryFunctionEntry->BeginAddress ==  TargetFunctionEntry.BeginAddress) {
        return PrimaryFunctionEntry;

    } else {
        return NULL;
    }
}

ULONG OOPStackUnwinderAMD64::UnwindOpSlots(__in UNWIND_CODE UnwindCode)
/*++

Routine Description:

    This routine determines the number of unwind code slots ultimately
    consumed by an unwind code sequence.

Arguments:

    UnwindCode - Supplies the first unwind code in the sequence.

Return Value:

    Returns the total count of the number of slots consumed by the unwind
    code sequence.

--*/
{

    ULONG Slots;
    ULONG UnwindOp;

    //
    // UWOP_SPARE_CODE may be found in very old x64 images.
    //

    UnwindOp = UnwindCode.UnwindOp;

    UNWINDER_ASSERT(UnwindOp != UWOP_SPARE_CODE);
    UNWINDER_ASSERT(UnwindOp < sizeof(UnwindOpExtraSlotTable));

    Slots = UnwindOpExtraSlotTable[UnwindOp] + 1;
    if ((UnwindOp == UWOP_ALLOC_LARGE) && (UnwindCode.OpInfo != 0)) {
        Slots += 1;
    }

    return Slots;
}


text:
<?php
/**
 * A composite field for date and time entry,
 * based on {@link DateField} and {@link TimeField}.
 * Usually saves into a single {@link SS_Datetime} database column.
 * If you want to save into {@link Date} or {@link Time} columns,
 * please instanciate the fields separately.
 *
 * # Configuration
 *
 * All options in {@link setConfig()} are passed through to {@link DateField} and {@link TimeField}.
 *
 * @package sapphire
 * @subpackage forms
 */
class DatetimeField extends FormField {

	/**
	 * @var DateField
	 */
	protected $dateField = null;

	/**
	 * @var TimeField
	 */
	protected $timeField = null;

	/**
	 * @var array
	 */
	protected $config = array(
		'datavalueformat' => 'YYYY-MM-dd HH:mm:ss'
	);

	function __construct($name, $title = null, $value = ""){
		$this->dateField = new DateField($name . '[date]', false);
		$this->timeField = new TimeField($name . '[time]', false);

		parent::__construct($name, $title, $value);
	}

	function setForm($form) {
		parent::setForm($form);

		$this->dateField->setForm($form);
		$this->timeField->setForm($form);
	}

	function Field() {
		Requirements::css(SAPPHIRE_DIR . '/css/DatetimeField.css');

		return $this->dateField->FieldHolder() . $this->timeField->FieldHolder() . '

';
	}

	/**
	 * Sets the internal value to ISO date format.
	 *
	 * @param string|array $val String expects an ISO date format. Array notation with 'date' and 'time'
	 *  keys can contain localized strings. If the 'dmyfields' option is used for {@link DateField},
	 *  the 'date' value may contain array notation was well (see {@link DateField->setValue()}).
	 */
	function setValue($val) {
		if(empty($val)) {
			$this->dateField->setValue(null);
			$this->timeField->setValue(null);
		} else {
			// String setting is only possible from the database, so we don't allow anything but ISO format
			if(is_string($val) && Zend_Date::isDate($val, $this->getConfig('datavalueformat'), $this->locale)) {
				// split up in date and time string values.
				$valueObj = new Zend_Date($val, $this->getConfig('datavalueformat'), $this->locale);
				// set date either as array, or as string
				if($this->dateField->getConfig('dmyfields')) {
					$this->dateField->setValue($valueObj->toArray());
				} else {
					$this->dateField->setValue($valueObj->get($this->dateField->getConfig('dateformat'), $this->locale));
				}
				// set time
				$this->timeField->setValue($valueObj->get($this->timeField->getConfig('timeformat'), $this->locale));
			}
			// Setting from form submission
			elseif(is_array($val) && array_key_exists('date', $val) && array_key_exists('time', $val)) {
				$this->dateField->setValue($val['date']);
				$this->timeField->setValue($val['time']);
			} else {
				$this->dateField->setValue($val);
				$this->timeField->setValue($val);
			}
		}
	}

	function dataValue() {
		$valDate = $this->dateField->dataValue();
		$valTime = $this->timeField->dataValue();

		// Only date is actually required, time is optional
		if($valDate) {
			if(!$valTime) $valTime = '00:00:00';
			return $valDate . ' ' . $valTime;
		} else {
			// TODO
			return null;
		}
	}

	/**
	 * @return DateField
	 */
	function getDateField() {
		return $this->dateField;
	}

	/**
	 * @return TimeField
	 */
	function getTimeField() {
		return $this->timeField;
	}

	function setLocale($locale) {
		$this->dateField->setLocale($locale);
		$this->timeField->setLocale($locale);
	}

	function getLocale() {
		return $this->dateField->getLocale();
	}

	/**
	 * Note: Use {@link getDateField()} and {@link getTimeField()}
	 * to set field-specific config options.
	 *
	 * @param string $name
	 * @param mixed $val
	 */
	function setConfig($name, $val) {
		$this->config[$name] = $val;
	}

	/**
	 * Note: Use {@link getDateField()} and {@link getTimeField()}
	 * to get field-specific config options.
	 *
	 * @param String $name
	 * @return mixed
	 */
	function getConfig($name) {
		return $this->config[$name];
	}

	function validate($validator) {
		$dateValid = $this->dateField->validate($validator);
		$timeValid = $this->timeField->validate($validator);

		return ($dateValid && $timeValid);
	}

	function jsValidation() {
		return $this->dateField->jsValidation() . $this->timeField->jsValidation();
	}

	function performReadonlyTransformation() {
		$field = new DatetimeField_Readonly($this->name, $this->title, $this->dataValue());
		$field->setForm($this->form);

		return $field;
	}
}

/**
 * The readonly class for our {@link DatetimeField}.
 *
 * @package forms
 * @subpackage fields-datetime
 */
class DatetimeField_Readonly extends DatetimeField {

	protected $readonly = true;

	function Field() {
		$valDate = $this->dateField->dataValue();
		$valTime = $this->timeField->dataValue();
		if($valDate && $valTime) {
			$format = $this->dateField->getConfig('dateformat') . ' ' . $this->timeField->getConfig('timeformat');
			$valueObj = new Zend_Date(
				$valDate . ' ' . $valTime,
				$this->getConfig('datavalueformat'),
				$this->dateField->getLocale()
			);
			$val = $valueObj->toString($format);
		} else {
			// TODO Localization
			$val = '(not set)';
		}

		return "id() . "\">$val";
	}

	function jsValidation() {
		return null;
	}

	function validate($validator) {
		return true;
	}
}
?>

redpajama_set_name: RedPajamaGithub


text:
package com.intellij.execution.testframework;

import com.intellij.execution.ExecutionBundle;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.configurations.RunProfile;
import com.intellij.execution.runners.PreferredPlace;
import com.intellij.execution.runners.RunTab;
import com.intellij.execution.testframework.actions.ScrollToTestSourceAction;
import com.intellij.execution.testframework.actions.TestFrameworkActions;
import com.intellij.execution.testframework.actions.TestTreeExpander;
import com.intellij.execution.testframework.autotest.AdjustAutotestDelayActionGroup;
import com.intellij.execution.testframework.export.ExportTestResultsAction;
import com.intellij.execution.testframework.ui.AbstractTestTreeBuilderBase;
import com.intellij.execution.ui.UIExperiment;
import com.intellij.icons.AllIcons;
import com.intellij.ide.CommonActionsManager;
import com.intellij.ide.OccurenceNavigator;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.impl.MoreActionGroup;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.DumbAware;
import com.intellij.util.config.DumbAwareToggleBooleanProperty;
import com.intellij.util.config.DumbAwareToggleInvertedBooleanProperty;
import com.intellij.util.config.ToggleBooleanProperty;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;

public class ToolbarPanel extends JPanel implements OccurenceNavigator, Disposable {
  private static final Logger LOG = Logger.getInstance(ToolbarPanel.class);
  protected final TestTreeExpander myTreeExpander = new TestTreeExpander();
  protected final FailedTestsNavigator myOccurenceNavigator;
  protected final ScrollToTestSourceAction myScrollToSource;
  private @Nullable ExportTestResultsAction myExportAction;

  private final ArrayList<ToggleModelAction> myActions = new ArrayList<>();

  public ToolbarPanel(final TestConsoleProperties properties,
                      final JComponent parent) {
    super(new BorderLayout());
    DefaultActionGroup actionGroup = new DefaultActionGroup();
    actionGroup.addAction(new DumbAwareToggleInvertedBooleanProperty(ExecutionBundle.message("junit.run.hide.passed.action.name"), ExecutionBundle.message("junit.run.hide.passed.action.description"),
                                                                     AllIcons.RunConfigurations.ShowPassed,
                                                                     properties, TestConsoleProperties.HIDE_PASSED_TESTS));
    actionGroup.add(new DumbAwareToggleInvertedBooleanProperty(TestRunnerBundle.message("action.show.ignored.text"),
                                                               TestRunnerBundle.message("action.show.ignored.description"), AllIcons.RunConfigurations.ShowIgnored,
                                                               properties, TestConsoleProperties.HIDE_IGNORED_TEST));
    actionGroup.addSeparator();

    boolean isNewLayout = UIExperiment.isNewDebuggerUIEnabled();

    var sortGroup = !isNewLayout ? actionGroup : DefaultActionGroup.createPopupGroup(() -> ExecutionBundle.message("junit.runing.info.sort.group.name"));
    DumbAwareToggleBooleanProperty suitesAlwaysOnTop =
      new DumbAwareToggleBooleanProperty(ExecutionBundle.message("junit.runing.info.folders.on.top.action.name"),
                                         ExecutionBundle.message("junit.runing.info.folders.on.top.action.description"),
                                         null,
                                         properties, TestConsoleProperties.SUITES_ALWAYS_ON_TOP);
    if (isNewLayout) {
      sortGroup.addAction(suitesAlwaysOnTop);
    }
    sortGroup.addAction(new DumbAwareToggleBooleanProperty(ExecutionBundle.message("junit.runing.info.sort.alphabetically.action.name"),
                                                             ExecutionBundle.message("junit.runing.info.sort.alphabetically.action.description"),
                                                             AllIcons.ObjectBrowser.Sorted,
                                                             properties, TestConsoleProperties.SORT_ALPHABETICALLY));

    final ToggleModelAction sortByStatistics = new SortByDurationAction(properties);
    myActions.add(sortByStatistics);
    sortGroup.addAction(sortByStatistics);

    if (isNewLayout) {
      sortGroup.getTemplatePresentation().setIcon(sortByStatistics.getTemplatePresentation().getIcon());
      actionGroup.add(sortGroup);
    } else {
      actionGroup.addSeparator();
    }

    DefaultActionGroup moreGroup = isNewLayout ? new MoreActionGroup() : actionGroup;
    AnAction action = CommonActionsManager.getInstance().createExpandAllAction(myTreeExpander, parent);
    action.getTemplatePresentation().setDescription(ExecutionBundle.messagePointer("junit.runing.info.expand.test.action.name"));
    moreGroup.add(action);

    action = CommonActionsManager.getInstance().createCollapseAllAction(myTreeExpander, parent);
    action.getTemplatePresentation().setDescription(ExecutionBundle.messagePointer("junit.runing.info.collapse.test.action.name"));
    moreGroup.add(action);

    moreGroup.addSeparator();
    final CommonActionsManager actionsManager = CommonActionsManager.getInstance();
    myOccurenceNavigator = new FailedTestsNavigator();
    moreGroup.add(actionsManager.createPrevOccurenceAction(myOccurenceNavigator));
    moreGroup.add(actionsManager.createNextOccurenceAction(myOccurenceNavigator));

    for (ToggleModelActionProvider actionProvider : ToggleModelActionProvider.EP_NAME.getExtensionList()) {
      final ToggleModelAction toggleModelAction = actionProvider.createToggleModelAction(properties);
      myActions.add(toggleModelAction);
      actionGroup.add(toggleModelAction);
    }

    final AnAction[] importActions = properties.createImportActions();
    if (importActions != null) {
      for (AnAction importAction : importActions) {
        if (importAction.getTemplatePresentation().getClientProperty(RunTab.PREFERRED_PLACE) == PreferredPlace.TOOLBAR) {
          actionGroup.add(importAction);
        } else {
          moreGroup.add(importAction);
        }
      }
    }

    final RunProfile configuration = properties.getConfiguration();
    if (configuration instanceof RunConfiguration) {
      myExportAction = ExportTestResultsAction.create(properties.getExecutor().getToolWindowId(), (RunConfiguration)configuration, parent);
      moreGroup.addAction(myExportAction);
    }

    final DefaultActionGroup secondaryGroup = new DefaultActionGroup();
    secondaryGroup.setPopup(true);
    secondaryGroup.getTemplatePresentation().setText(ExecutionBundle.message("junit.runing.info.test.runner.options.group.name"));
    secondaryGroup.getTemplatePresentation().setIcon(AllIcons.General.GearPlain);
    secondaryGroup.add(new DumbAwareToggleBooleanProperty(ExecutionBundle.message("junit.runing.info.track.test.action.name"),
                                                 ExecutionBundle.message("junit.runing.info.track.test.action.description"),
                                                 null, properties, TestConsoleProperties.TRACK_RUNNING_TEST));
    secondaryGroup.add(new DumbAwareToggleBooleanProperty(TestRunnerBundle.message("action.show.inline.statistics.text"), TestRunnerBundle
      .message("action.toggle.visibility.test.duration.in.tree.description"),
                                                          null, properties, TestConsoleProperties.SHOW_INLINE_STATISTICS));
    if (!isNewLayout) {
      secondaryGroup.add(suitesAlwaysOnTop);
    }

    secondaryGroup.addSeparator();
    secondaryGroup.add(new DumbAwareToggleBooleanProperty(ExecutionBundle.message("junit.runing.info.scroll.to.stacktrace.action.name"),
                                                 ExecutionBundle.message("junit.runing.info.scroll.to.stacktrace.action.description"),
                                                 null, properties, TestConsoleProperties.SCROLL_TO_STACK_TRACE));
    secondaryGroup.add(new ToggleBooleanProperty(ExecutionBundle.message("junit.runing.info.open.source.at.exception.action.name"),
                                                 ExecutionBundle.message("junit.runing.info.open.source.at.exception.action.description"),
                                                 null, properties, TestConsoleProperties.OPEN_FAILURE_LINE));
    myScrollToSource = new ScrollToTestSourceAction(properties);
    secondaryGroup.add(myScrollToSource);

    secondaryGroup.add(new AdjustAutotestDelayActionGroup(parent));
    secondaryGroup.addSeparator();
    secondaryGroup.add(new DumbAwareToggleBooleanProperty(ExecutionBundle.message("junit.runing.info.select.first.failed.action.name"),
                                                 null, null, properties, TestConsoleProperties.SELECT_FIRST_DEFECT));
    properties.appendAdditionalActions(secondaryGroup, parent, properties);
    moreGroup.addSeparator();
    moreGroup.add(secondaryGroup);

    if (isNewLayout) {
      actionGroup.add(moreGroup);
      actionGroup = new RunTab.ToolbarActionGroup(actionGroup);
    }

    ActionToolbar actionToolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.TESTTREE_VIEW_TOOLBAR, actionGroup, true);
    actionToolbar.setTargetComponent(parent);
    add(actionToolbar.getComponent(), BorderLayout.CENTER);
  }

  public void setModel(final TestFrameworkRunningModel model) {
    TestFrameworkActions.installFilterAction(model);
    myScrollToSource.setModel(model);
    myTreeExpander.setModel(model);
    myOccurenceNavigator.setModel(model);
    if (myExportAction != null) {
      myExportAction.setModel(model);
    }
    for (ToggleModelAction action : myActions) {
      action.setModel(model);
    }
    TestFrameworkActions.addPropertyListener(TestConsoleProperties.SORT_ALPHABETICALLY, createComparatorPropertyListener(model), model, true);
    TestFrameworkActions.addPropertyListener(TestConsoleProperties.SORT_BY_DURATION, createComparatorPropertyListener(model), model, true);
    TestFrameworkActions.addPropertyListener(TestConsoleProperties.SUITES_ALWAYS_ON_TOP, createComparatorPropertyListener(model), model, true);
  }

  private static TestFrameworkPropertyListener<Boolean> createComparatorPropertyListener(TestFrameworkRunningModel model) {
    return new TestFrameworkPropertyListener<>() {
      @Override
      public void onChanged(Boolean value) {
        try {
          //todo reflection to avoid binary incompatibility with substeps plugin
          final AbstractTestTreeBuilderBase builder =
            (AbstractTestTreeBuilderBase)model.getClass().getMethod("getTreeBuilder").invoke(model);
          if (builder != null) {
            builder.setTestsComparator(model);
          }
        }
        catch (Exception e) {
          LOG.error(e);
        }
      }
    };
  }

  @Override
  public boolean hasNextOccurence() {
    return myOccurenceNavigator.hasNextOccurence();
  }

  @Override
  public boolean hasPreviousOccurence() {
    return myOccurenceNavigator.hasPreviousOccurence();
  }

  @Override
  public OccurenceInfo goNextOccurence() {
    return myOccurenceNavigator.goNextOccurence();
  }

  @Override
  public OccurenceInfo goPreviousOccurence() {
    return myOccurenceNavigator.goPreviousOccurence();
  }

  @NotNull
  @Override
  public String getNextOccurenceActionName() {
    return myOccurenceNavigator.getNextOccurenceActionName();
  }

  @NotNull
  @Override
  public String getPreviousOccurenceActionName() {
    return myOccurenceNavigator.getPreviousOccurenceActionName();
  }

  @Override
  public void dispose() {
    myScrollToSource.setModel(null);
    if (myExportAction != null) {
      myExportAction.setModel(null);
    }
  }

  private static class SortByDurationAction extends ToggleModelAction implements DumbAware {

    private TestFrameworkRunningModel myModel;

    SortByDurationAction(TestConsoleProperties properties) {
      super(ExecutionBundle.message("junit.runing.info.sort.by.statistics.action.name"),
            ExecutionBundle.message("junit.runing.info.sort.by.statistics.action.description"),
            AllIcons.RunConfigurations.SortbyDuration, properties,
            TestConsoleProperties.SORT_BY_DURATION);
    }

    @Override
    protected boolean isEnabled() {
      final TestFrameworkRunningModel model = myModel;
      return model != null && !model.isRunning();
    }

    @Override
    public void setModel(TestFrameworkRunningModel model) {
      myModel = model;
    }
  }
}


text:
import { AbstractControl } from '@angular/forms';

// import { CanHide } from '../form-entry/control-hiders-disablers/can-hide';
// import { CanDisable } from '../form-entry/control-hiders-disablers/can-disable';

export class ControlRelation {
    private _control: AbstractControl;
    private _relatedTo: AbstractControl;
    private _lastUpdateValue: any;

    constructor(control: AbstractControl, relatedTo: AbstractControl) {
        this._control = control;
        this._relatedTo = relatedTo;
        this._registerForChangesFromRelatedControl();
    }

    get control(): AbstractControl {
        return this._control;
    }

    get relatedTo(): AbstractControl {
        return this._relatedTo;
    }

    get lastUpdateValue(): any {
        return this._lastUpdateValue;
    }

    updateControlBasedOnRelation(newValue: any): boolean {
        if (newValue !== this._lastUpdateValue) {
            this._lastUpdateValue = newValue;

            if ((this._control as any).updateCalculatedValue) {
              (this._control as any).updateCalculatedValue();
            }

            this._control.updateValueAndValidity();
            if ((this._control as any).updateHiddenState) {
                (this._control as any).updateHiddenState();
            }

            if ((this._control as any).updateDisabledState) {
                (this._control as any).updateDisabledState();
            }

            if ((this._control as any).updateAlert) {
                (this._control as any).updateAlert();
            }
            return true;
        }
        return false;
    }

    private _registerForChangesFromRelatedControl() {

      this._relatedTo.valueChanges.subscribe((value) => {
        this.updateControlBasedOnRelation(value);
      });
    }
}


text:
/**
 * Brand Create
 */
Meteor.methods({
  "Brand.Create": function (brandName) {
    if (brandName.trim() === '') {
      throw new Meteor.Error('bad-brand-name', 'The Brand Name cannot be blank');
    }

    Brands.insert({
      brandName: brandName
    });
  }
});


text:
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.Serialization;

namespace Zyan.InterLinq.Types.Anonymous
{
	/// <summary>
	/// Class that represents a property of an anonymous type.
	/// </summary>
	[Serializable]
	[DataContract]
	public class AnonymousMetaProperty
	{
		#region Properties

		/// <summary>
		/// The <see cref="InterLinqType"/> of the property.
		/// </summary>
		[DataMember]
		public InterLinqType PropertyType { get; set; }

		/// <summary>
		/// The name of the property.
		/// </summary>
		[DataMember]
		public string Name { get; set; }

		#endregion

		#region Constructors

		/// <summary>
		/// Default constructor for serialization
		/// </summary>
		public AnonymousMetaProperty() { }

		/// <summary>
		/// Instance an instance of the class <see cref="AnonymousMetaProperty"/> with a <see cref="PropertyInfo"/>.
		/// </summary>
		/// <param name="property"><see cref="PropertyInfo"/> to create a <see cref="AnonymousMetaProperty"/> from.</param>
		public AnonymousMetaProperty(PropertyInfo property)
		{
			if (property == null)
			{
				throw new ArgumentNullException("property");
			}
			Name = property.Name;
			PropertyType = InterLinqTypeSystem.Instance.GetInterLinqVersionOf<InterLinqType>(property.PropertyType);
		}

		#endregion

		#region Methods

		/// <summary>
		/// Overrides the equality check.
		/// </summary>
		/// <param name="obj">Object to compare with.</param>
		/// <returns>True, if the other <see langword="object"/> is equal to this. False, if not.</returns>
		public override bool Equals(object obj)
		{
			if (obj == null || GetType() != obj.GetType())
			{
				return false;
			}

			AnonymousMetaProperty other = (AnonymousMetaProperty)obj;
			return other.Name == Name && other.PropertyType.Equals(PropertyType);
		}

		/// <summary>
		/// Serves as a hash function for a particular type.
		/// </summary>
		/// <returns>A hash code for the current <see langword="object"/>.</returns>
		public override int GetHashCode()
		{
			int num = -871466652;
			num ^= EqualityComparer<InterLinqType>.Default.GetHashCode(PropertyType);
			num ^= EqualityComparer<string>.Default.GetHashCode(Name);
			return num;
		}

		#endregion
	}
}


text:
package com.redisdoc.command;

import com.redisdoc.command.util.AbstractCommand;
import com.redisdoc.exception.CommandParameterException;

public class CommandDset extends AbstractCommand {

	@Override
	public void executeCommand(String[] strings) throws CommandParameterException {
		// save documentation
		jedisRedisdoc.set(strings[1], strings[2]);
	}

	public String[] getCommand() {
		return new String[] { "dset" };
	}

	public String[] getUsage() {
		return new String[] { "dset <doc-name (pattern)> <description>", "set documentation key (pattern) with description" };
	}

	public int[] getParamCount() {
		return new int[] { 3 };
	}
}


text:
package com.emental.mindraider.core.rest.properties;

import javax.xml.namespace.QName;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;

import com.mindcognition.mindraider.tools.GlobalIdGenerator;
import com.mindcognition.mindraider.utils.PullParsing;

/**
 * Origin URI property is a global ID that is used e.g. in the integration with MindForger.
 *
 *  @see GlobalIdGenerator
 */
public class OriginProperty implements ResourceProperty {

    public static final String ELEMENT_SOURCE_TWIKI_FILE = "originProperty";
    public static final String ELEMENT_URI = "uri";
    public static String label;
    public static QName qname;

    private String uri;

    static {
        qname = new QName("", ELEMENT_SOURCE_TWIKI_FILE);
        label = "Origin";
    }

    public OriginProperty() {
    }

    public OriginProperty(String uri) {
        this();
        this.uri = uri;
    }

    public QName getQName() {
        return qname;
    }

    public String getLabel() {
        return label;
    }

    public void fromXml(XmlPullParser xpp) throws Exception {
        // start element already parsed

        PullParsing.startElement(xpp, ELEMENT_URI);
        uri = xpp.nextText();

        PullParsing.endElement(xpp, ELEMENT_SOURCE_TWIKI_FILE);
    }

    public void toXml(XmlSerializer xs) throws Exception {
        xs.startTag("", ELEMENT_SOURCE_TWIKI_FILE);
        PullParsing.serializeTextElement(xs, ELEMENT_URI, uri);
        xs.endTag("", ELEMENT_SOURCE_TWIKI_FILE);
    }

    public String getUri() {
        return this.uri;
    }
}


text:
What is "WebUIStats"?
=======================
WebUIStats is the component that generates web UI interface with charts from your stats.

Screenshots
============
![Example 1](https://github.com/ofertix/WebUIStats/raw/master/doc/resources/stats1.png "Example 1")

![Example2](https://github.com/ofertix/WebUIStats/raw/master/doc/resources/stats2.png "Example2")

Requirements
============
- PHP 5.3.2 and up.
- RabbitMQ or ZMQ.

Libraries and services used
===========================

- PHP
	- Pimple
	- Symfony Components:
		- ClassLoader
		- YAML
		- Console
	- Monolog
- ExtJS 4
- HighStocks

Installation
============

The best way to install is to clone the repository and then configure as you need. See "Configuration" section.

After cloning you must install dependencies using "composer":

	php composer.phar update

Usage
=====

Generate your charts using:

	php app/generator.php interface:generate app/config/test/app.yml

Optional: You could copy generated code in `web/app` to somewhere you want.

In your browser insert the url where it is the generated code, example:

	http://localhost/WebUIStats/web/index.html

Configuration
=============

All configuration is done using a YAML files.

Config files are structured in one main file (app.yml) and some screens config files (screen_foo.yml).

app.yml:

- output_path:

	- directory where to write generated code.

- title:
	- title that will appears in the browser.

- menu:
	- menu items that links our charts.

- charts:
	- default charts options.

screen_foo.yml:

- charts:

	- chart title, options and data series.

- display:

	- set template that defines charts layout.

See config file for more details.

Extra notes
===========

Use of ZMQ is discontinued because a memory leak using ZMQ with OpenPGM PUB/SUB.


text:
<?php

return [
    'interfaces' => [
        'testing.resourcenames.ResourceNames' => [
            'FileLevelChildTypeRefMethod' => [
                'method' => 'post',
                'uriTemplate' => '/path:fileLevelChildTypeRefMethod',
                'body' => '*',
            ],
            'FileLevelTypeRefMethod' => [
                'method' => 'post',
                'uriTemplate' => '/path:fileLevelTypeRefMethod',
                'body' => '*',
            ],
            'MultiPatternMethod' => [
                'method' => 'post',
                'uriTemplate' => '/path:multiPatternMethod',
                'body' => '*',
            ],
            'SinglePatternMethod' => [
                'method' => 'post',
                'uriTemplate' => '/path:singlePatternMethod',
                'body' => '*',
            ],
            'WildcardChildReferenceMethod' => [
                'method' => 'post',
                'uriTemplate' => '/path:wildcardChildReference',
                'body' => '*',
            ],
            'WildcardMethod' => [
                'method' => 'post',
                'uriTemplate' => '/path:wildcardMethod',
                'body' => '*',
            ],
            'WildcardMultiMethod' => [
                'method' => 'post',
                'uriTemplate' => '/path:wildcardMultiMethod',
                'body' => '*',
            ],
            'WildcardReferenceMethod' => [
                'method' => 'post',
                'uriTemplate' => '/path:wildcardReference',
                'body' => '*',
            ],
        ],
    ],
    'numericEnums' => true,
];


text:
import unittest.mock as mock
import batch_analysis.task_manager
import batch_analysis.tasks.import_dataset_task as idt
import batch_analysis.tasks.generate_dataset_task as gdt
import batch_analysis.tasks.train_system_task as tst
import batch_analysis.tasks.run_system_task as rst
import batch_analysis.tasks.benchmark_trial_task as btt
import batch_analysis.tasks.compare_trials_task as ctt
import batch_analysis.tasks.compare_benchmarks_task as cbt

class ZombieTaskManager:
    """
    A wrapper for a mock task manager that hooks into it's mock methods, so that they actually work.
    The object is still a MagicMock, and can be inspected for all the normal properties .
    This means that the task manager can be injected in, and will provide the correct output as the code expects,
    while

    All the state is held externally in this object, to avoid polluting the TaskManager interface and retain
    the benefits of using a spec.
    """

    def __init__(self, mock_task_manager: mock.Mock):
        self._import_dataset_tasks = {}
        self._generate_dataset_tasks = {}
        self._train_system_tasks = {}
        self._run_system_tasks = {}
        self._benchmark_tasks = {}
        self._compare_trials_tasks = {}
        self._compare_benchmarks_tasks = {}
        self._tasks_to_do = []

        # Set up the mock object to call the methods on this object as their side effect
        # I'm using some lamba context binding to link back to the zombie object, and filter out extra arguments.
        mock_task_manager.get_import_dataset_task.side_effect = (
            lambda module_name, path, *_, **__:
                self.get_import_dataset_task(module_name, path))
        mock_task_manager.get_generate_dataset_task.side_effect = (
            lambda controller_id, simulator_id, simulator_config, *_, **__:
                self.get_generate_dataset_task(controller_id, simulator_id, simulator_config))
        mock_task_manager.get_train_system_task.side_effect = (
            lambda trainer_id, trainee_id, *_, **__:
                self.get_train_system_task(trainer_id, trainee_id))
        mock_task_manager.get_run_system_task.side_effect = (
            lambda system_id, image_source_id, *_, **__:
                self.get_run_system_task(system_id, image_source_id))
        mock_task_manager.get_benchmark_task.side_effect = (
            lambda trial_result_id, benchmark_id, *_, **__:
                self.get_benchmark_task(trial_result_id, benchmark_id))
        mock_task_manager.get_trial_comparison_task.side_effect = (
            lambda trial_result1_id, trial_result2_id, comparison_id, *_, **__:
                self.get_trial_comparison_task(trial_result1_id, trial_result2_id, comparison_id))
        mock_task_manager.get_benchmark_comparison_task.side_effect = (
            lambda benchmark_result1_id, benchmark_result2_id, comparison_id, *_, **__:
                self.get_benchmark_comparison_task(benchmark_result1_id, benchmark_result2_id, comparison_id))
        self._mock_task_manager = mock_task_manager

    @property
    def mock(self) -> mock.Mock:
        """
        Get the mock task manager this is attached to
        :return:
        """
        return self._mock_task_manager

    def get_all_tasks(self):
        """
        Get all the tasks this object is holding, in no particular order.
        You cant use the various get methods for this, because they will create the task if it is missing.
        :return:
        """
        return ([task for inner in self._import_dataset_tasks.values() for task in inner.values()] +
                [task for inner in self._generate_dataset_tasks.values() for task in inner.values()] +
                [task for inner in self._train_system_tasks.values() for task in inner.values()] +
                [task for inner in self._run_system_tasks.values() for task in inner.values()] +
                [task for inner in self._benchmark_tasks.values() for task in inner.values()] +
                [task for inner1 in self._compare_trials_tasks.values() for inner2 in inner1.values()
                 for task in inner2.values()] +
                [task for inner1 in self._compare_benchmarks_tasks.values() for inner2 in inner1.values()
                 for task in inner2.values()])

    def add_import_dataset_task(self, task: idt.ImportDatasetTask):
        """
        Add an import dataset task. Use this to set up the initial state of the task manager
        :param task: The import dataset task to add. Should have all it's parameters set.
        :return: void
        """
        if task.module_name not in self._import_dataset_tasks:
            self._import_dataset_tasks[task.module_name] = {}
        self._import_dataset_tasks[task.module_name][task.path] = task

    def get_import_dataset_task(self, module_name, path):
        """
        Get a task to import a dataset. This is called by the mock object.
        :param module_name: The name of the python module to use to do the import as a string.
        :param path: The root file or directory describing the dataset to import
        :return: An ImportDatasetTask containing the task state.
        """
        if module_name not in self._import_dataset_tasks:
            self._import_dataset_tasks[module_name] = {}
        if path not in self._import_dataset_tasks[module_name]:
            self._import_dataset_tasks[module_name][path] = idt.ImportDatasetTask(
                module_name=module_name,
                path=path,
            )
        return self._import_dataset_tasks[module_name][path]

    def get_generate_dataset_task(self, controller_id, simulator_id, simulator_config, *_, **__):
        """
        Get a task to generate a synthetic dataset.
        :param controller_id: The id of the controller to use
        :param simulator_id: The id of the simulator to use
        :param simulator_config: configuration parameters passed to the simulator at run time.
        :return: An ImportDatasetTask containing the task state.
        """
        if controller_id not in self._generate_dataset_tasks:
            self._generate_dataset_tasks[controller_id] = {}
        if simulator_id not in self._generate_dataset_tasks[controller_id]:
            self._generate_dataset_tasks[controller_id][simulator_id] = gdt.GenerateDatasetTask(
                controller_id=controller_id,
                simulator_id=simulator_id,
                simulator_config=simulator_config
            )
        return self._generate_dataset_tasks[simulator_id][controller_id]

    def get_train_system_task(self, trainer_id, trainee_id):
        """
        Create a task to train a system.
        Most of the parameters are resources requirements passed to the job system.
        :param trainer_id: The id of the trainer to do the training
        :param trainee_id: The id of the trainee to train
        :return: A TrainSystemTask
        """
        if trainer_id not in self._train_system_tasks:
            self._train_system_tasks[trainer_id] = {}
        if trainee_id not in self._train_system_tasks[trainer_id]:
            self._train_system_tasks[trainer_id][trainee_id] = tst.TrainSystemTask(
                trainer_id=trainer_id,
                trainee_id=trainee_id
            )
        return self._train_system_tasks[trainer_id][trainee_id]

    def get_run_system_task(self, system_id, image_source_id):
        """
        Get a task to run a system.
        Most of the parameters are resources requirements passed to the job system.
        :param system_id: The id of the vision system to test
        :param image_source_id: The id of the image source to test with
        :return: A RunSystemTask
        """
        if system_id not in self._run_system_tasks:
            self._run_system_tasks[system_id] = {}
        if image_source_id not in self._run_system_tasks[system_id]:
            self._run_system_tasks[system_id][image_source_id] = rst.RunSystemTask(
                system_id=system_id,
                image_source_id=image_source_id
            )
        return self._run_system_tasks[system_id][image_source_id]

    def get_benchmark_task(self, trial_result_id, benchmark_id):
        """
        Get a task to benchmark a trial result.
        Most of the parameters are resources requirements passed to the job system.
        :param trial_result_id: The id of the trial result to benchmark
        :param benchmark_id: The id of the benchmark to use
        :return: A BenchmarkTrialTask
        """
        if trial_result_id not in self._benchmark_tasks:
            self._benchmark_tasks[trial_result_id] = {}
        if benchmark_id not in self._benchmark_tasks[trial_result_id]:
            self._benchmark_tasks[trial_result_id][benchmark_id] = btt.BenchmarkTrialTask(
                trial_result_id=trial_result_id,
                benchmark_id=benchmark_id
            )
        return self._benchmark_tasks[trial_result_id][benchmark_id]

    def get_trial_comparison_task(self, trial_result1_id, trial_result2_id, comparison_id):
        """
        Get a task to compare two trial results.
        Most of the parameters are resources requirements passed to the job system.
        :param trial_result1_id: The id of the first trial result to compare
        :param trial_result2_id: The id of the second trial result to compare
        :param comparison_id: The comparison benchmark to use
        :return: A CompareTrialTask
        """
        if comparison_id not in self._compare_trials_tasks:
            self._compare_trials_tasks[comparison_id] = {}
        if trial_result1_id not in self._compare_trials_tasks[comparison_id]:
            self._compare_trials_tasks[comparison_id][trial_result1_id] = {}
        if trial_result2_id not in self._compare_trials_tasks[comparison_id][trial_result1_id]:
            self._compare_trials_tasks[comparison_id][trial_result1_id][trial_result2_id] = ctt.CompareTrialTask(
                trial_result1_id=trial_result1_id,
                trial_result2_id=trial_result2_id,
                comparison_id=comparison_id
            )
        return self._compare_trials_tasks[comparison_id][trial_result1_id][trial_result2_id]

    def get_benchmark_comparison_task(self, benchmark_result1_id, benchmark_result2_id, comparison_id):
        """
        Get a task to compare two benchmark results.
        Most of the parameters are resources requirements passed to the job system.
        :param benchmark_result1_id: The id of the first benchmark result to compare
        :param benchmark_result2_id: The id of the second benchmark result to compare
        :param comparison_id: The id of the benchmark to perform the comparison
        :return: A CompareBenchmarksTask
        """
        if comparison_id not in self._compare_benchmarks_tasks:
            self._compare_benchmarks_tasks[comparison_id] = {}
        if benchmark_result1_id not in self._compare_benchmarks_tasks[comparison_id]:
            self._compare_benchmarks_tasks[comparison_id][benchmark_result1_id] = {}
        if benchmark_result2_id not in self._compare_benchmarks_tasks[comparison_id][benchmark_result1_id]:
            self._compare_benchmarks_tasks[comparison_id][benchmark_result1_id][benchmark_result2_id] = \
                cbt.CompareBenchmarksTask(
                benchmark_result1_id=benchmark_result1_id,
                benchmark_result2_id=benchmark_result2_id,
                comparison_id=comparison_id
            )
        return self._compare_benchmarks_tasks[comparison_id][benchmark_result1_id][benchmark_result2_id]

def create() -> ZombieTaskManager:
    """
    Create a new zombie task manager.
    The zombie task manager wraps a mock task manager that is set up to actually
    behave as a real task manager, and can be injected into objects as part of a test.
    Use the zombie object itself to construct the initial state, and then inject the mock object.
    :return: A new ZombieTaskManager
    """
    return ZombieTaskManager(mock.create_autospec(batch_analysis.task_manager.TaskManager))


text:
'use strict';

import React from 'react';
import {cursors, shoppingCart} from '../services/ShoppingCart.js';

/**
 * Basket Component
 * @extends {React.Component}
 */
export default class BasketComponent extends React.Component {

  /**
   * @desc sets initial state from shoppingCart items
   */
  constructor () {
    super();
    this.state = {items: shoppingCart.items()};
  }

  /**
   * @desc assigns a baobab listener after component has been mounted
   */
  componentDidMount () {
    cursors.basketItems.on('update', () => {
      this.setState({
        items: shoppingCart.items()
      });
    });
  }

  /**
   * @param item {string}
   */
  removeItemFromBasket (item) {
    shoppingCart.removeItem(item);
  }

  /**
   * @returns {XML}
   */
  render () {
    return

      Basket ({this.state.items.length})

        {this.state.items.map(
          item => {
            return
{item} <button onClick={this.removeItemFromBasket.bind(this, item)}>Remove</button>
;
          }
        )}

;
  }

}