diff options
Diffstat (limited to 'source/compiler/aslmethod.c')
-rw-r--r-- | source/compiler/aslmethod.c | 43 |
1 files changed, 36 insertions, 7 deletions
diff --git a/source/compiler/aslmethod.c b/source/compiler/aslmethod.c index 9734b643efd9..b2bb89c53664 100644 --- a/source/compiler/aslmethod.c +++ b/source/compiler/aslmethod.c @@ -347,10 +347,31 @@ MtMethodAnalysisWalkBegin ( case PARSEOP_METHODCALL: + /* Check for a recursive method call */ + if (MethodInfo && (Op->Asl.Node == MethodInfo->Op->Asl.Node)) { - AslError (ASL_REMARK, ASL_MSG_RECURSION, Op, Op->Asl.ExternalName); + if (MethodInfo->CreatesNamedObjects) + { + /* + * This is an error, as it will fail at runtime on all ACPI + * implementations. Any named object declarations will be + * executed twice, causing failure the second time. Note, + * this is independent of whether the method is declared + * Serialized, because the same thread is attempting to + * reenter the method, and this will always succeed. + */ + AslDualParseOpError (ASL_ERROR, ASL_MSG_ILLEGAL_RECURSION, Op, + Op->Asl.Value.String, ASL_MSG_FOUND_HERE, MethodInfo->Op, + MethodInfo->Op->Asl.ExternalName); + } + else + { + /* Method does not create objects, issue a remark */ + + AslError (ASL_REMARK, ASL_MSG_RECURSION, Op, Op->Asl.ExternalName); + } } break; @@ -622,20 +643,28 @@ MtCheckNamedObjectInMethod ( return; } - /* Determine if we are creating a named object */ + /* Determine if we are creating a named object within a method */ + + if (!MethodInfo) + { + return; + } OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); if (OpInfo->Class == AML_CLASS_NAMED_OBJECT) { /* - * If we have a named object created within a non-serialized method, - * emit a remark that the method should be serialized. + * 1) Mark the method as a method that creates named objects. + * + * 2) 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. + * another thread enters the method, the method will fail because + * an attempt will be made to create the same object twice. */ - if (MethodInfo && !MethodInfo->ShouldBeSerialized) + MethodInfo->CreatesNamedObjects = TRUE; + if (!MethodInfo->ShouldBeSerialized) { AslError (ASL_REMARK, ASL_MSG_SERIALIZED_REQUIRED, MethodInfo->Op, "due to creation of named objects within"); |