mirror of
https://github.com/acpica/acpica/
synced 2025-02-25 18:04:08 +03:00
Disassembler: Fix missing code problem with ElseIf conversion
During conversion of Else...If sequences to ASL ElseIf statements, blocks of code can become detached from the parse tree and lost. This change fixes the problem.
This commit is contained in:
parent
d14099ff86
commit
39ec745ded
@ -136,6 +136,10 @@ static void
|
||||
AcpiDmConvertToElseIf (
|
||||
ACPI_PARSE_OBJECT *Op);
|
||||
|
||||
static void
|
||||
AcpiDmPromoteSubtree (
|
||||
ACPI_PARSE_OBJECT *StartOp);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
@ -1139,16 +1143,26 @@ AcpiDmConvertToElseIf (
|
||||
* be the only blocks under the original Else.
|
||||
*/
|
||||
IfOp = OriginalElseOp->Common.Value.Arg;
|
||||
|
||||
if (!IfOp ||
|
||||
(IfOp->Common.AmlOpcode != AML_IF_OP) ||
|
||||
(IfOp->Asl.Next && (IfOp->Asl.Next->Common.AmlOpcode != AML_ELSE_OP)))
|
||||
{
|
||||
/* Not an Else..If sequence, cannot convert to ElseIf */
|
||||
/* Not a proper Else..If sequence, cannot convert to ElseIf */
|
||||
|
||||
AcpiOsPrintf ("%s", "Else");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Cannot have anything following the If...Else block */
|
||||
|
||||
ElseOp = IfOp->Common.Next;
|
||||
if (ElseOp && ElseOp->Common.Next)
|
||||
{
|
||||
AcpiOsPrintf ("%s", "Else");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Emit ElseIf, mark the IF as now an ELSEIF */
|
||||
|
||||
AcpiOsPrintf ("%s", "ElseIf");
|
||||
@ -1172,7 +1186,10 @@ AcpiDmConvertToElseIf (
|
||||
/* If an ELSE matches the IF, promote it also */
|
||||
|
||||
ElseOp->Common.Parent = OriginalElseOp->Common.Parent;
|
||||
ElseOp->Common.Next = OriginalElseOp->Common.Next;
|
||||
|
||||
/* Promote the entire block under the ElseIf (All Next OPs) */
|
||||
|
||||
AcpiDmPromoteSubtree (OriginalElseOp);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1194,3 +1211,48 @@ AcpiDmConvertToElseIf (
|
||||
|
||||
OriginalElseOp->Common.Next = IfOp;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: AcpiDmPromoteSubtree
|
||||
*
|
||||
* PARAMETERS: StartOpOp - Original parent of the entire subtree
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Promote an entire parse subtree up one level.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
static void
|
||||
AcpiDmPromoteSubtree (
|
||||
ACPI_PARSE_OBJECT *StartOp)
|
||||
{
|
||||
ACPI_PARSE_OBJECT *Op;
|
||||
ACPI_PARSE_OBJECT *ParentOp;
|
||||
|
||||
|
||||
/* New parent for subtree elements */
|
||||
|
||||
ParentOp = StartOp->Common.Parent;
|
||||
|
||||
/* First child starts the subtree */
|
||||
|
||||
Op = StartOp->Common.Value.Arg;
|
||||
|
||||
/* Walk the top-level elements of the subtree */
|
||||
|
||||
while (Op)
|
||||
{
|
||||
Op->Common.Parent = ParentOp;
|
||||
if (!Op->Common.Next)
|
||||
{
|
||||
/* Last Op in list, update its next field */
|
||||
|
||||
Op->Common.Next = StartOp->Common.Next;
|
||||
break;
|
||||
}
|
||||
Op = Op->Common.Next;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user