FreeBSD/sys/contrib/dev/acpica/components/parser/psparse.c
/*******************************************************************************
 *
 * FUNCTION:    AcpiPsCompleteThisOp
 *
 * PARAMETERS:  WalkState       - Current State
 *              Op              - Op to complete
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Perform any cleanup at the completion of an Op.
 *
 ******************************************************************************/
AcpiPsCompleteThisOp
PARAMETERS:  WalkState       - Current State
Op              - Op to complete

Status

Perform any cleanup at the completion of an Op.
AcpiPsCompleteThisOp PARAMETERS : WalkState - Current State Op - Op to complete Status Perform any cleanup at the completion of an Op .
ACPI_STATUS
AcpiPsCompleteThisOp (
    ACPI_WALK_STATE         *WalkState,
    ACPI_PARSE_OBJECT       *Op)
{
    ACPI_PARSE_OBJECT       *Prev;
    ACPI_PARSE_OBJECT       *Next;
    const ACPI_OPCODE_INFO  *ParentInfo;
    ACPI_PARSE_OBJECT       *ReplacementOp = NULL;
    ACPI_STATUS             Status = AE_OK;
    ACPI_FUNCTION_TRACE_PTR (PsCompleteThisOp, Op);
    if (!Op)
    {
        return_ACPI_STATUS (AE_OK);  
    }
    AcpiExStopTraceOpcode (Op, WalkState);
    if (((WalkState->ParseFlags & ACPI_PARSE_TREE_MASK) != ACPI_PARSE_DELETE_TREE) ||
         (WalkState->OpInfo->Class == AML_CLASS_ARGUMENT))
    {
        return_ACPI_STATUS (AE_OK);
    }
    if (Op->Common.Parent)
    {
        Prev = Op->Common.Parent->Common.Value.Arg;
        if (!Prev)
        {
            goto Cleanup;
        }
        ParentInfo = AcpiPsGetOpcodeInfo (Op->Common.Parent->Common.AmlOpcode);
        switch (ParentInfo->Class)
        {
        case AML_CLASS_CONTROL:
            break;
        case AML_CLASS_CREATE:
            ReplacementOp = AcpiPsAllocOp (
                AML_INT_RETURN_VALUE_OP, Op->Common.Aml);
            if (!ReplacementOp)
            {
                Status = AE_NO_MEMORY;
            }
            break;
        case AML_CLASS_NAMED_OBJECT:
            if ((Op->Common.Parent->Common.AmlOpcode == AML_REGION_OP)       ||
                (Op->Common.Parent->Common.AmlOpcode == AML_DATA_REGION_OP)  ||
                (Op->Common.Parent->Common.AmlOpcode == AML_BUFFER_OP)       ||
                (Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP)      ||
                (Op->Common.Parent->Common.AmlOpcode == AML_BANK_FIELD_OP)   ||
                (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))
            {
                ReplacementOp = AcpiPsAllocOp (
                    AML_INT_RETURN_VALUE_OP, Op->Common.Aml);
                if (!ReplacementOp)
                {
                    Status = AE_NO_MEMORY;
                }
            }
            else if ((Op->Common.Parent->Common.AmlOpcode == AML_NAME_OP) &&
                     (WalkState->PassNumber <= ACPI_IMODE_LOAD_PASS2))
            {
                if ((Op->Common.AmlOpcode == AML_BUFFER_OP) ||
                    (Op->Common.AmlOpcode == AML_PACKAGE_OP) ||
                    (Op->Common.AmlOpcode == AML_VAR_PACKAGE_OP))
                {
                    ReplacementOp = AcpiPsAllocOp (Op->Common.AmlOpcode,
                        Op->Common.Aml);
                    if (!ReplacementOp)
                    {
                        Status = AE_NO_MEMORY;
                    }
                    else
                    {
                        ReplacementOp->Named.Data = Op->Named.Data;
                        ReplacementOp->Named.Length = Op->Named.Length;
                    }
                }
            }
            break;
        default:
            ReplacementOp = AcpiPsAllocOp (
                AML_INT_RETURN_VALUE_OP, Op->Common.Aml);
            if (!ReplacementOp)
            {
                Status = AE_NO_MEMORY;
            }
        }
        if (Prev == Op)
        {
            if (ReplacementOp)
            {
                ReplacementOp->Common.Parent = Op->Common.Parent;
                ReplacementOp->Common.Value.Arg = NULL;
                ReplacementOp->Common.Node = Op->Common.Node;
                Op->Common.Parent->Common.Value.Arg = ReplacementOp;
                ReplacementOp->Common.Next = Op->Common.Next;
            }
            else
            {
                Op->Common.Parent->Common.Value.Arg = Op->Common.Next;
            }
        }
        else while (Prev)
        {
            Next = Prev->Common.Next;
            if (Next == Op)
            {
                if (ReplacementOp)
                {
                    ReplacementOp->Common.Parent = Op->Common.Parent;
                    ReplacementOp->Common.Value.Arg = NULL;
                    ReplacementOp->Common.Node = Op->Common.Node;
                    Prev->Common.Next = ReplacementOp;
                    ReplacementOp->Common.Next = Op->Common.Next;
                    Next = NULL;
                }
                else
                {
                    Prev->Common.Next = Op->Common.Next;
                    Next = NULL;
                }
            }
            Prev = Next;
        }
    }
Cleanup:
    AcpiPsDeleteParseTree (Op);
    return_ACPI_STATUS (Status);
}
ACPI_STATUS AcpiPsCompleteThisOp ( ACPI_WALK_STATE * WalkState , ACPI_PARSE_OBJECT * Op ) { ACPI_PARSE_OBJECT * Prev ; ACPI_PARSE_OBJECT * Next ; const ACPI_OPCODE_INFO * ParentInfo ; ACPI_PARSE_OBJECT * ReplacementOp = NULL ; ACPI_STATUS Status = AE_OK ; ACPI_FUNCTION_TRACE_PTR ( PsCompleteThisOp , Op ) ; if ( ! Op ) { return_ACPI_STATUS ( AE_OK ) ; } AcpiExStopTraceOpcode ( Op , WalkState ) ; if ( ( ( WalkState -> ParseFlags & ACPI_PARSE_TREE_MASK ) != ACPI_PARSE_DELETE_TREE ) || ( WalkState -> OpInfo -> Class == AML_CLASS_ARGUMENT ) ) { return_ACPI_STATUS ( AE_OK ) ; } if ( Op -> Common . Parent ) { Prev = Op -> Common . Parent -> Common . Value . Arg ; if ( ! Prev ) { goto Cleanup ; } ParentInfo = AcpiPsGetOpcodeInfo ( Op -> Common . Parent -> Common . AmlOpcode ) ; switch ( ParentInfo -> Class ) { case AML_CLASS_CONTROL : break ; case AML_CLASS_CREATE : ReplacementOp = AcpiPsAllocOp ( AML_INT_RETURN_VALUE_OP , Op -> Common . Aml ) ; if ( ! ReplacementOp ) { Status = AE_NO_MEMORY ; } break ; case AML_CLASS_NAMED_OBJECT : if ( ( Op -> Common . Parent -> Common . AmlOpcode == AML_REGION_OP ) || ( Op -> Common . Parent -> Common . AmlOpcode == AML_DATA_REGION_OP ) || ( Op -> Common . Parent -> Common . AmlOpcode == AML_BUFFER_OP ) || ( Op -> Common . Parent -> Common . AmlOpcode == AML_PACKAGE_OP ) || ( Op -> Common . Parent -> Common . AmlOpcode == AML_BANK_FIELD_OP ) || ( Op -> Common . Parent -> Common . AmlOpcode == AML_VAR_PACKAGE_OP ) ) { ReplacementOp = AcpiPsAllocOp ( AML_INT_RETURN_VALUE_OP , Op -> Common . Aml ) ; if ( ! ReplacementOp ) { Status = AE_NO_MEMORY ; } } else if ( ( Op -> Common . Parent -> Common . AmlOpcode == AML_NAME_OP ) && ( WalkState -> PassNumber <= ACPI_IMODE_LOAD_PASS2 ) ) { if ( ( Op -> Common . AmlOpcode == AML_BUFFER_OP ) || ( Op -> Common . AmlOpcode == AML_PACKAGE_OP ) || ( Op -> Common . AmlOpcode == AML_VAR_PACKAGE_OP ) ) { ReplacementOp = AcpiPsAllocOp ( Op -> Common . AmlOpcode , Op -> Common . Aml ) ; if ( ! ReplacementOp ) { Status = AE_NO_MEMORY ; } else { ReplacementOp -> Named . Data = Op -> Named . Data ; ReplacementOp -> Named . Length = Op -> Named . Length ; } } } break ; default : ReplacementOp = AcpiPsAllocOp ( AML_INT_RETURN_VALUE_OP , Op -> Common . Aml ) ; if ( ! ReplacementOp ) { Status = AE_NO_MEMORY ; } } if ( Prev == Op ) { if ( ReplacementOp ) { ReplacementOp -> Common . Parent = Op -> Common . Parent ; ReplacementOp -> Common . Value . Arg = NULL ; ReplacementOp -> Common . Node = Op -> Common . Node ; Op -> Common . Parent -> Common . Value . Arg = ReplacementOp ; ReplacementOp -> Common . Next = Op -> Common . Next ; } else { Op -> Common . Parent -> Common . Value . Arg = Op -> Common . Next ; } } else while ( Prev ) { Next = Prev -> Common . Next ; if ( Next == Op ) { if ( ReplacementOp ) { ReplacementOp -> Common . Parent = Op -> Common . Parent ; ReplacementOp -> Common . Value . Arg = NULL ; ReplacementOp -> Common . Node = Op -> Common . Node ; Prev -> Common . Next = ReplacementOp ; ReplacementOp -> Common . Next = Op -> Common . Next ; Next = NULL ; } else { Prev -> Common . Next = Op -> Common . Next ; Next = NULL ; } } Prev = Next ; } } Cleanup : AcpiPsDeleteParseTree ( Op ) ; return_ACPI_STATUS ( Status ) ; }
FUNCTION:    AcpiPsCompleteThisOp
 PARAMETERS:  WalkState       - Current State
              Op              - Op to complete
FUNCTION : AcpiPsCompleteThisOp PARAMETERS : WalkState - Current State Op - Op to complete
/* Check for null Op, can happen if AML code is corrupt */ /* OK for now */ /* Delete this op and the subtree below it if asked to */ /* Make sure that we only delete this subtree */ /* Nothing more to do */ /*
         * Check if we need to replace the operator and its subtree
         * with a return value op (placeholder op)
         */ /*
             * These opcodes contain TermArg operands. The current
             * op must be replaced by a placeholder return op
             */ /*
             * These opcodes contain TermArg operands. The current
             * op must be replaced by a placeholder return op
             */ /* We must unlink this op from the parent tree */ /* This op is the first in the list */ /* Search the parent list */ /* Traverse all siblings in the parent's argument list */ /* Now we can actually delete the subtree rooted at Op */