diff options
Diffstat (limited to 'source/compiler/aslmethod.c')
| -rw-r--r-- | source/compiler/aslmethod.c | 205 |
1 files changed, 170 insertions, 35 deletions
diff --git a/source/compiler/aslmethod.c b/source/compiler/aslmethod.c index b7b7ec42f3a85..d56f4817c9ef5 100644 --- a/source/compiler/aslmethod.c +++ b/source/compiler/aslmethod.c @@ -151,6 +151,7 @@ #include "aslcompiler.h" #include "aslcompiler.y.h" +#include "acnamesp.h" #include "acparser.h" #include "amlcode.h" @@ -166,6 +167,10 @@ MtCheckNamedObjectInMethod ( ACPI_PARSE_OBJECT *Op, ASL_METHOD_INFO *MethodInfo); +static void +MtCheckStaticOperationRegionInMethod ( + ACPI_PARSE_OBJECT *Op); + /******************************************************************************* * @@ -197,7 +202,6 @@ MtMethodAnalysisWalkBegin ( char ArgName[] = "Arg0"; ACPI_PARSE_OBJECT *ArgNode; ACPI_PARSE_OBJECT *NextType; - ACPI_PARSE_OBJECT *NextParamType; UINT8 ActualArgs = 0; BOOLEAN HidExists; BOOLEAN AdrExists; @@ -282,50 +286,35 @@ MtMethodAnalysisWalkBegin ( Next = Next->Asl.Next; NextType = Next->Asl.Child; - while (NextType) - { - /* Get and map each of the ReturnTypes */ - MethodInfo->ValidReturnTypes |= AnMapObjTypeToBtype (NextType); - NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; - NextType = NextType->Asl.Next; - } + MethodInfo->ValidReturnTypes = MtProcessTypeOp (NextType); /* Get the ParameterType node */ Next = Next->Asl.Next; NextType = Next->Asl.Child; - while (NextType) + if (!NextType) { - if (NextType->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) - { - NextParamType = NextType->Asl.Child; - while (NextParamType) - { - MethodInfo->ValidArgTypes[ActualArgs] |= - AnMapObjTypeToBtype (NextParamType); - - NextParamType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; - NextParamType = NextParamType->Asl.Next; - } - } - else - { - MethodInfo->ValidArgTypes[ActualArgs] = - AnMapObjTypeToBtype (NextType); - - NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; - ActualArgs++; - } - - NextType = NextType->Asl.Next; + /* + * The optional parameter types list was omitted at the source + * level. Use the Argument count parameter instead. + */ + ActualArgs = MethodInfo->NumArguments; + } + else + { + ActualArgs = MtProcessParameterTypeList (NextType, + MethodInfo->ValidArgTypes); } if ((MethodInfo->NumArguments) && (MethodInfo->NumArguments != ActualArgs)) { - /* error: Param list did not match number of args */ + sprintf (AslGbl_MsgBuffer, + "Length = %u", ActualArgs); + AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_MISMATCH, + Op->Asl.Child->Asl.Next, AslGbl_MsgBuffer); } /* Allow numarguments == 0 for Function() */ @@ -576,6 +565,8 @@ MtMethodAnalysisWalkBegin ( AslError (ASL_ERROR, ASL_MSG_RESERVED_USE, Op, Op->Asl.ExternalName); } + + MtCheckStaticOperationRegionInMethod (Op); break; case PARSEOP_NAME: @@ -630,6 +621,71 @@ MtMethodAnalysisWalkBegin ( /******************************************************************************* * + * FUNCTION: MtProcessTypeOp + * + * PARAMETERS: Op - Op representing a btype + * + * RETURN: Btype represented by Op + * + * DESCRIPTION: Process a parse object that represents single parameter type or + * a return type in method, function, and external declarations. + * + ******************************************************************************/ + +UINT32 +MtProcessTypeOp ( + ACPI_PARSE_OBJECT *TypeOp) +{ + UINT32 Btype = ACPI_BTYPE_ANY; + + + while (TypeOp) + { + Btype |= AnMapObjTypeToBtype (TypeOp); + TypeOp->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; + TypeOp = TypeOp->Asl.Next; + } + + return (Btype); +} + + +/******************************************************************************* + * + * FUNCTION: MtProcessParameterTypeList + * + * PARAMETERS: Op - Op representing a btype + * + * RETURN: Btype represented by Op + * + * DESCRIPTION: Process a parse object that represents a parameter type list in + * method, function, and external declarations. + * + ******************************************************************************/ + +UINT8 +MtProcessParameterTypeList ( + ACPI_PARSE_OBJECT *ParamTypeOp, + UINT32 *TypeList) +{ + UINT8 ParameterCount = 0; + + + while (ParamTypeOp) + { + TypeList[ParameterCount] = + MtProcessTypeOp (ParamTypeOp->Asl.Child); + + ParameterCount++; + ParamTypeOp = ParamTypeOp->Asl.Next; + } + + return (ParameterCount); +} + + +/******************************************************************************* + * * FUNCTION: MtCheckNamedObjectInMethod * * PARAMETERS: Op - Current parser op @@ -649,6 +705,7 @@ MtCheckNamedObjectInMethod ( ASL_METHOD_INFO *MethodInfo) { const ACPI_OPCODE_INFO *OpInfo; + char *ExternalPath; /* We don't care about actual method declarations or scopes */ @@ -672,29 +729,99 @@ MtCheckNamedObjectInMethod ( /* * 1) Mark the method as a method that creates named objects. * - * 2) If the method is non-serialized, emit a remark that the method + * 2) Issue a remark indicating the inefficiency of creating named + * objects within a method (Except for compiler-emitted temporary + * variables). + * + * 3) If the method is non-serialized, emit a remark that the method * should be serialized. * * Reason: If a thread blocks within the method for any reason, and * another thread enters the method, the method will fail because * an attempt will be made to create the same object twice. */ + ExternalPath = AcpiNsGetNormalizedPathname (MethodInfo->Op->Asl.Node, TRUE); + + /* No error for compiler temp variables (name starts with "_T_") */ + + if ((Op->Asl.NameSeg[0] != '_') && + (Op->Asl.NameSeg[1] != 'T') && + (Op->Asl.NameSeg[2] != '_')) + { + AslError (ASL_REMARK, ASL_MSG_NAMED_OBJECT_CREATION, Op, + ExternalPath); + } + MethodInfo->CreatesNamedObjects = TRUE; if (!MethodInfo->ShouldBeSerialized) { AslError (ASL_REMARK, ASL_MSG_SERIALIZED_REQUIRED, MethodInfo->Op, - "due to creation of named objects within"); + ExternalPath); /* Emit message only ONCE per method */ MethodInfo->ShouldBeSerialized = TRUE; } + + if (ExternalPath) + { + ACPI_FREE (ExternalPath); + } } } /******************************************************************************* * + * FUNCTION: MtCheckStaticOperationRegionInMethod + * + * PARAMETERS: Op - Current parser op + * + * RETURN: None + * + * DESCRIPTION: Warns if an Operation Region with static address or length + * is declared inside a control method + * + ******************************************************************************/ + +static void +MtCheckStaticOperationRegionInMethod( + ACPI_PARSE_OBJECT* Op) +{ + ACPI_PARSE_OBJECT* AddressOp; + ACPI_PARSE_OBJECT* LengthOp; + + + if (Op->Asl.ParseOpcode != PARSEOP_OPERATIONREGION) + { + return; + } + + /* + * OperationRegion should have 4 arguments defined. At this point, we + * assume that the parse tree is well-formed. + */ + AddressOp = Op->Asl.Child->Asl.Next->Asl.Next; + LengthOp = Op->Asl.Child->Asl.Next->Asl.Next->Asl.Next; + + if (UtGetParentMethodOp (Op) && + AddressOp->Asl.ParseOpcode == PARSEOP_INTEGER && + LengthOp->Asl.ParseOpcode == PARSEOP_INTEGER) + { + /* + * At this point, a static operation region declared inside of a + * control method has been found. Throw a warning because this is + * highly inefficient. + */ + AslError(ASL_WARNING, ASL_MSG_STATIC_OPREGION_IN_METHOD, Op, NULL); + } + + return; +} + + +/******************************************************************************* + * * FUNCTION: MtMethodAnalysisWalkEnd * * PARAMETERS: ASL_WALK_CALLBACK @@ -714,6 +841,7 @@ MtMethodAnalysisWalkEnd ( { ASL_ANALYSIS_WALK_INFO *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context; ASL_METHOD_INFO *MethodInfo = WalkInfo->MethodStack; + char *ExternalPath; switch (Op->Asl.ParseOpcode) @@ -766,8 +894,15 @@ MtMethodAnalysisWalkEnd ( if (MethodInfo->NumReturnNoValue && MethodInfo->NumReturnWithValue) { + ExternalPath = AcpiNsGetNormalizedPathname (Op->Asl.Node, TRUE); + AslError (ASL_WARNING, ASL_MSG_RETURN_TYPES, Op, - Op->Asl.ExternalName); + ExternalPath); + + if (ExternalPath) + { + ACPI_FREE (ExternalPath); + } } /* |
