aboutsummaryrefslogtreecommitdiff
path: root/source/compiler/aslmethod.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/compiler/aslmethod.c')
-rw-r--r--source/compiler/aslmethod.c205
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);
+ }
}
/*