1efcc2a30SJung-uk Kim /****************************************************************************** 2efcc2a30SJung-uk Kim * 3efcc2a30SJung-uk Kim * Module Name: aslmethod.c - Control method analysis walk 4efcc2a30SJung-uk Kim * 5efcc2a30SJung-uk Kim *****************************************************************************/ 6efcc2a30SJung-uk Kim 7efcc2a30SJung-uk Kim /* 81c0e1b6dSJung-uk Kim * Copyright (C) 2000 - 2015, Intel Corp. 9efcc2a30SJung-uk Kim * All rights reserved. 10efcc2a30SJung-uk Kim * 11efcc2a30SJung-uk Kim * Redistribution and use in source and binary forms, with or without 12efcc2a30SJung-uk Kim * modification, are permitted provided that the following conditions 13efcc2a30SJung-uk Kim * are met: 14efcc2a30SJung-uk Kim * 1. Redistributions of source code must retain the above copyright 15efcc2a30SJung-uk Kim * notice, this list of conditions, and the following disclaimer, 16efcc2a30SJung-uk Kim * without modification. 17efcc2a30SJung-uk Kim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18efcc2a30SJung-uk Kim * substantially similar to the "NO WARRANTY" disclaimer below 19efcc2a30SJung-uk Kim * ("Disclaimer") and any redistribution must be conditioned upon 20efcc2a30SJung-uk Kim * including a substantially similar Disclaimer requirement for further 21efcc2a30SJung-uk Kim * binary redistribution. 22efcc2a30SJung-uk Kim * 3. Neither the names of the above-listed copyright holders nor the names 23efcc2a30SJung-uk Kim * of any contributors may be used to endorse or promote products derived 24efcc2a30SJung-uk Kim * from this software without specific prior written permission. 25efcc2a30SJung-uk Kim * 26efcc2a30SJung-uk Kim * Alternatively, this software may be distributed under the terms of the 27efcc2a30SJung-uk Kim * GNU General Public License ("GPL") version 2 as published by the Free 28efcc2a30SJung-uk Kim * Software Foundation. 29efcc2a30SJung-uk Kim * 30efcc2a30SJung-uk Kim * NO WARRANTY 31efcc2a30SJung-uk Kim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32efcc2a30SJung-uk Kim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33efcc2a30SJung-uk Kim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34efcc2a30SJung-uk Kim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35efcc2a30SJung-uk Kim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36efcc2a30SJung-uk Kim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37efcc2a30SJung-uk Kim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38efcc2a30SJung-uk Kim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39efcc2a30SJung-uk Kim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40efcc2a30SJung-uk Kim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41efcc2a30SJung-uk Kim * POSSIBILITY OF SUCH DAMAGES. 42efcc2a30SJung-uk Kim */ 43efcc2a30SJung-uk Kim 44efcc2a30SJung-uk Kim #include <contrib/dev/acpica/compiler/aslcompiler.h> 45efcc2a30SJung-uk Kim #include "aslcompiler.y.h" 46a9d8d09cSJung-uk Kim #include <contrib/dev/acpica/include/acparser.h> 47a9d8d09cSJung-uk Kim #include <contrib/dev/acpica/include/amlcode.h> 48efcc2a30SJung-uk Kim 49efcc2a30SJung-uk Kim 50efcc2a30SJung-uk Kim #define _COMPONENT ACPI_COMPILER 51efcc2a30SJung-uk Kim ACPI_MODULE_NAME ("aslmethod") 52efcc2a30SJung-uk Kim 53efcc2a30SJung-uk Kim 54a9d8d09cSJung-uk Kim /* Local prototypes */ 55a9d8d09cSJung-uk Kim 56a9d8d09cSJung-uk Kim void 57a9d8d09cSJung-uk Kim MtCheckNamedObjectInMethod ( 58a9d8d09cSJung-uk Kim ACPI_PARSE_OBJECT *Op, 59a9d8d09cSJung-uk Kim ASL_METHOD_INFO *MethodInfo); 60a9d8d09cSJung-uk Kim 61a9d8d09cSJung-uk Kim 62efcc2a30SJung-uk Kim /******************************************************************************* 63efcc2a30SJung-uk Kim * 64efcc2a30SJung-uk Kim * FUNCTION: MtMethodAnalysisWalkBegin 65efcc2a30SJung-uk Kim * 66efcc2a30SJung-uk Kim * PARAMETERS: ASL_WALK_CALLBACK 67efcc2a30SJung-uk Kim * 68efcc2a30SJung-uk Kim * RETURN: Status 69efcc2a30SJung-uk Kim * 70efcc2a30SJung-uk Kim * DESCRIPTION: Descending callback for the analysis walk. Check methods for: 71efcc2a30SJung-uk Kim * 1) Initialized local variables 72efcc2a30SJung-uk Kim * 2) Valid arguments 73efcc2a30SJung-uk Kim * 3) Return types 74efcc2a30SJung-uk Kim * 75efcc2a30SJung-uk Kim ******************************************************************************/ 76efcc2a30SJung-uk Kim 77efcc2a30SJung-uk Kim ACPI_STATUS 78efcc2a30SJung-uk Kim MtMethodAnalysisWalkBegin ( 79efcc2a30SJung-uk Kim ACPI_PARSE_OBJECT *Op, 80efcc2a30SJung-uk Kim UINT32 Level, 81efcc2a30SJung-uk Kim void *Context) 82efcc2a30SJung-uk Kim { 83efcc2a30SJung-uk Kim ASL_ANALYSIS_WALK_INFO *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context; 84efcc2a30SJung-uk Kim ASL_METHOD_INFO *MethodInfo = WalkInfo->MethodStack; 85efcc2a30SJung-uk Kim ACPI_PARSE_OBJECT *Next; 86efcc2a30SJung-uk Kim UINT32 RegisterNumber; 87efcc2a30SJung-uk Kim UINT32 i; 88efcc2a30SJung-uk Kim char LocalName[] = "Local0"; 89efcc2a30SJung-uk Kim char ArgName[] = "Arg0"; 90efcc2a30SJung-uk Kim ACPI_PARSE_OBJECT *ArgNode; 91efcc2a30SJung-uk Kim ACPI_PARSE_OBJECT *NextType; 92efcc2a30SJung-uk Kim ACPI_PARSE_OBJECT *NextParamType; 93efcc2a30SJung-uk Kim UINT8 ActualArgs = 0; 94efcc2a30SJung-uk Kim 95efcc2a30SJung-uk Kim 96efcc2a30SJung-uk Kim switch (Op->Asl.ParseOpcode) 97efcc2a30SJung-uk Kim { 98efcc2a30SJung-uk Kim case PARSEOP_METHOD: 99efcc2a30SJung-uk Kim 100efcc2a30SJung-uk Kim TotalMethods++; 101efcc2a30SJung-uk Kim 102efcc2a30SJung-uk Kim /* Create and init method info */ 103efcc2a30SJung-uk Kim 104efcc2a30SJung-uk Kim MethodInfo = UtLocalCalloc (sizeof (ASL_METHOD_INFO)); 105efcc2a30SJung-uk Kim MethodInfo->Next = WalkInfo->MethodStack; 106efcc2a30SJung-uk Kim MethodInfo->Op = Op; 107efcc2a30SJung-uk Kim 108efcc2a30SJung-uk Kim WalkInfo->MethodStack = MethodInfo; 109efcc2a30SJung-uk Kim 110313a0c13SJung-uk Kim /* 111313a0c13SJung-uk Kim * Special handling for _PSx methods. Dependency rules (same scope): 112313a0c13SJung-uk Kim * 113313a0c13SJung-uk Kim * 1) _PS0 - One of these must exist: _PS1, _PS2, _PS3 114313a0c13SJung-uk Kim * 2) _PS1/_PS2/_PS3: A _PS0 must exist 115313a0c13SJung-uk Kim */ 116313a0c13SJung-uk Kim if (ACPI_COMPARE_NAME (METHOD_NAME__PS0, Op->Asl.NameSeg)) 117313a0c13SJung-uk Kim { 118313a0c13SJung-uk Kim /* For _PS0, one of _PS1/_PS2/_PS3 must exist */ 119313a0c13SJung-uk Kim 120313a0c13SJung-uk Kim if ((!ApFindNameInScope (METHOD_NAME__PS1, Op)) && 121313a0c13SJung-uk Kim (!ApFindNameInScope (METHOD_NAME__PS2, Op)) && 122313a0c13SJung-uk Kim (!ApFindNameInScope (METHOD_NAME__PS3, Op))) 123313a0c13SJung-uk Kim { 124313a0c13SJung-uk Kim AslError (ASL_WARNING, ASL_MSG_MISSING_DEPENDENCY, Op, 125313a0c13SJung-uk Kim "_PS0 requires one of _PS1/_PS2/_PS3 in same scope"); 126313a0c13SJung-uk Kim } 127313a0c13SJung-uk Kim } 128313a0c13SJung-uk Kim else if ( 129313a0c13SJung-uk Kim ACPI_COMPARE_NAME (METHOD_NAME__PS1, Op->Asl.NameSeg) || 130313a0c13SJung-uk Kim ACPI_COMPARE_NAME (METHOD_NAME__PS2, Op->Asl.NameSeg) || 131313a0c13SJung-uk Kim ACPI_COMPARE_NAME (METHOD_NAME__PS3, Op->Asl.NameSeg)) 132313a0c13SJung-uk Kim { 133313a0c13SJung-uk Kim /* For _PS1/_PS2/_PS3, a _PS0 must exist */ 134313a0c13SJung-uk Kim 135313a0c13SJung-uk Kim if (!ApFindNameInScope (METHOD_NAME__PS0, Op)) 136313a0c13SJung-uk Kim { 137313a0c13SJung-uk Kim sprintf (MsgBuffer, 138313a0c13SJung-uk Kim "%4.4s requires _PS0 in same scope", Op->Asl.NameSeg); 139313a0c13SJung-uk Kim 140313a0c13SJung-uk Kim AslError (ASL_WARNING, ASL_MSG_MISSING_DEPENDENCY, Op, 141313a0c13SJung-uk Kim MsgBuffer); 142313a0c13SJung-uk Kim } 143313a0c13SJung-uk Kim } 144313a0c13SJung-uk Kim 145313a0c13SJung-uk Kim /* Get the name node */ 146efcc2a30SJung-uk Kim 147efcc2a30SJung-uk Kim Next = Op->Asl.Child; 148efcc2a30SJung-uk Kim 149efcc2a30SJung-uk Kim /* Get the NumArguments node */ 150efcc2a30SJung-uk Kim 151efcc2a30SJung-uk Kim Next = Next->Asl.Next; 152efcc2a30SJung-uk Kim MethodInfo->NumArguments = (UINT8) 153efcc2a30SJung-uk Kim (((UINT8) Next->Asl.Value.Integer) & 0x07); 154efcc2a30SJung-uk Kim 155efcc2a30SJung-uk Kim /* Get the SerializeRule and SyncLevel nodes, ignored here */ 156efcc2a30SJung-uk Kim 157efcc2a30SJung-uk Kim Next = Next->Asl.Next; 158a9d8d09cSJung-uk Kim MethodInfo->ShouldBeSerialized = (UINT8) Next->Asl.Value.Integer; 159a9d8d09cSJung-uk Kim 160efcc2a30SJung-uk Kim Next = Next->Asl.Next; 161efcc2a30SJung-uk Kim ArgNode = Next; 162efcc2a30SJung-uk Kim 163efcc2a30SJung-uk Kim /* Get the ReturnType node */ 164efcc2a30SJung-uk Kim 165efcc2a30SJung-uk Kim Next = Next->Asl.Next; 166efcc2a30SJung-uk Kim 167efcc2a30SJung-uk Kim NextType = Next->Asl.Child; 168efcc2a30SJung-uk Kim while (NextType) 169efcc2a30SJung-uk Kim { 170efcc2a30SJung-uk Kim /* Get and map each of the ReturnTypes */ 171efcc2a30SJung-uk Kim 172efcc2a30SJung-uk Kim MethodInfo->ValidReturnTypes |= AnMapObjTypeToBtype (NextType); 173efcc2a30SJung-uk Kim NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 174efcc2a30SJung-uk Kim NextType = NextType->Asl.Next; 175efcc2a30SJung-uk Kim } 176efcc2a30SJung-uk Kim 177efcc2a30SJung-uk Kim /* Get the ParameterType node */ 178efcc2a30SJung-uk Kim 179efcc2a30SJung-uk Kim Next = Next->Asl.Next; 180efcc2a30SJung-uk Kim 181efcc2a30SJung-uk Kim NextType = Next->Asl.Child; 182efcc2a30SJung-uk Kim while (NextType) 183efcc2a30SJung-uk Kim { 184efcc2a30SJung-uk Kim if (NextType->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 185efcc2a30SJung-uk Kim { 186efcc2a30SJung-uk Kim NextParamType = NextType->Asl.Child; 187efcc2a30SJung-uk Kim while (NextParamType) 188efcc2a30SJung-uk Kim { 189efcc2a30SJung-uk Kim MethodInfo->ValidArgTypes[ActualArgs] |= AnMapObjTypeToBtype (NextParamType); 190efcc2a30SJung-uk Kim NextParamType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 191efcc2a30SJung-uk Kim NextParamType = NextParamType->Asl.Next; 192efcc2a30SJung-uk Kim } 193efcc2a30SJung-uk Kim } 194efcc2a30SJung-uk Kim else 195efcc2a30SJung-uk Kim { 196efcc2a30SJung-uk Kim MethodInfo->ValidArgTypes[ActualArgs] = 197efcc2a30SJung-uk Kim AnMapObjTypeToBtype (NextType); 198efcc2a30SJung-uk Kim NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 199efcc2a30SJung-uk Kim ActualArgs++; 200efcc2a30SJung-uk Kim } 201efcc2a30SJung-uk Kim 202efcc2a30SJung-uk Kim NextType = NextType->Asl.Next; 203efcc2a30SJung-uk Kim } 204efcc2a30SJung-uk Kim 205efcc2a30SJung-uk Kim if ((MethodInfo->NumArguments) && 206efcc2a30SJung-uk Kim (MethodInfo->NumArguments != ActualArgs)) 207efcc2a30SJung-uk Kim { 208efcc2a30SJung-uk Kim /* error: Param list did not match number of args */ 209efcc2a30SJung-uk Kim } 210efcc2a30SJung-uk Kim 211efcc2a30SJung-uk Kim /* Allow numarguments == 0 for Function() */ 212efcc2a30SJung-uk Kim 213efcc2a30SJung-uk Kim if ((!MethodInfo->NumArguments) && (ActualArgs)) 214efcc2a30SJung-uk Kim { 215efcc2a30SJung-uk Kim MethodInfo->NumArguments = ActualArgs; 216efcc2a30SJung-uk Kim ArgNode->Asl.Value.Integer |= ActualArgs; 217efcc2a30SJung-uk Kim } 218efcc2a30SJung-uk Kim 219efcc2a30SJung-uk Kim /* 220efcc2a30SJung-uk Kim * Actual arguments are initialized at method entry. 221efcc2a30SJung-uk Kim * All other ArgX "registers" can be used as locals, so we 222efcc2a30SJung-uk Kim * track their initialization. 223efcc2a30SJung-uk Kim */ 224efcc2a30SJung-uk Kim for (i = 0; i < MethodInfo->NumArguments; i++) 225efcc2a30SJung-uk Kim { 226efcc2a30SJung-uk Kim MethodInfo->ArgInitialized[i] = TRUE; 227efcc2a30SJung-uk Kim } 228efcc2a30SJung-uk Kim break; 229efcc2a30SJung-uk Kim 230efcc2a30SJung-uk Kim case PARSEOP_METHODCALL: 231efcc2a30SJung-uk Kim 232efcc2a30SJung-uk Kim if (MethodInfo && 233efcc2a30SJung-uk Kim (Op->Asl.Node == MethodInfo->Op->Asl.Node)) 234efcc2a30SJung-uk Kim { 235efcc2a30SJung-uk Kim AslError (ASL_REMARK, ASL_MSG_RECURSION, Op, Op->Asl.ExternalName); 236efcc2a30SJung-uk Kim } 237efcc2a30SJung-uk Kim break; 238efcc2a30SJung-uk Kim 239efcc2a30SJung-uk Kim case PARSEOP_LOCAL0: 240efcc2a30SJung-uk Kim case PARSEOP_LOCAL1: 241efcc2a30SJung-uk Kim case PARSEOP_LOCAL2: 242efcc2a30SJung-uk Kim case PARSEOP_LOCAL3: 243efcc2a30SJung-uk Kim case PARSEOP_LOCAL4: 244efcc2a30SJung-uk Kim case PARSEOP_LOCAL5: 245efcc2a30SJung-uk Kim case PARSEOP_LOCAL6: 246efcc2a30SJung-uk Kim case PARSEOP_LOCAL7: 247efcc2a30SJung-uk Kim 248efcc2a30SJung-uk Kim if (!MethodInfo) 249efcc2a30SJung-uk Kim { 250efcc2a30SJung-uk Kim /* 251efcc2a30SJung-uk Kim * Local was used outside a control method, or there was an error 252efcc2a30SJung-uk Kim * in the method declaration. 253efcc2a30SJung-uk Kim */ 254efcc2a30SJung-uk Kim AslError (ASL_REMARK, ASL_MSG_LOCAL_OUTSIDE_METHOD, Op, Op->Asl.ExternalName); 255efcc2a30SJung-uk Kim return (AE_ERROR); 256efcc2a30SJung-uk Kim } 257efcc2a30SJung-uk Kim 258fe0f0bbbSJung-uk Kim RegisterNumber = (Op->Asl.AmlOpcode & 0x0007); 259efcc2a30SJung-uk Kim 260efcc2a30SJung-uk Kim /* 261efcc2a30SJung-uk Kim * If the local is being used as a target, mark the local 262efcc2a30SJung-uk Kim * initialized 263efcc2a30SJung-uk Kim */ 264efcc2a30SJung-uk Kim if (Op->Asl.CompileFlags & NODE_IS_TARGET) 265efcc2a30SJung-uk Kim { 266efcc2a30SJung-uk Kim MethodInfo->LocalInitialized[RegisterNumber] = TRUE; 267efcc2a30SJung-uk Kim } 268efcc2a30SJung-uk Kim 269efcc2a30SJung-uk Kim /* 270efcc2a30SJung-uk Kim * Otherwise, this is a reference, check if the local 271efcc2a30SJung-uk Kim * has been previously initialized. 272efcc2a30SJung-uk Kim * 273efcc2a30SJung-uk Kim * The only operator that accepts an uninitialized value is ObjectType() 274efcc2a30SJung-uk Kim */ 275efcc2a30SJung-uk Kim else if ((!MethodInfo->LocalInitialized[RegisterNumber]) && 276efcc2a30SJung-uk Kim (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE)) 277efcc2a30SJung-uk Kim { 278efcc2a30SJung-uk Kim LocalName[strlen (LocalName) -1] = (char) (RegisterNumber + 0x30); 279efcc2a30SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_LOCAL_INIT, Op, LocalName); 280efcc2a30SJung-uk Kim } 281efcc2a30SJung-uk Kim break; 282efcc2a30SJung-uk Kim 283efcc2a30SJung-uk Kim case PARSEOP_ARG0: 284efcc2a30SJung-uk Kim case PARSEOP_ARG1: 285efcc2a30SJung-uk Kim case PARSEOP_ARG2: 286efcc2a30SJung-uk Kim case PARSEOP_ARG3: 287efcc2a30SJung-uk Kim case PARSEOP_ARG4: 288efcc2a30SJung-uk Kim case PARSEOP_ARG5: 289efcc2a30SJung-uk Kim case PARSEOP_ARG6: 290efcc2a30SJung-uk Kim 291efcc2a30SJung-uk Kim if (!MethodInfo) 292efcc2a30SJung-uk Kim { 293efcc2a30SJung-uk Kim /* 294efcc2a30SJung-uk Kim * Arg was used outside a control method, or there was an error 295efcc2a30SJung-uk Kim * in the method declaration. 296efcc2a30SJung-uk Kim */ 297efcc2a30SJung-uk Kim AslError (ASL_REMARK, ASL_MSG_LOCAL_OUTSIDE_METHOD, Op, Op->Asl.ExternalName); 298efcc2a30SJung-uk Kim return (AE_ERROR); 299efcc2a30SJung-uk Kim } 300efcc2a30SJung-uk Kim 301efcc2a30SJung-uk Kim RegisterNumber = (Op->Asl.AmlOpcode & 0x000F) - 8; 302efcc2a30SJung-uk Kim ArgName[strlen (ArgName) -1] = (char) (RegisterNumber + 0x30); 303efcc2a30SJung-uk Kim 304efcc2a30SJung-uk Kim /* 305efcc2a30SJung-uk Kim * If the Arg is being used as a target, mark the local 306efcc2a30SJung-uk Kim * initialized 307efcc2a30SJung-uk Kim */ 308efcc2a30SJung-uk Kim if (Op->Asl.CompileFlags & NODE_IS_TARGET) 309efcc2a30SJung-uk Kim { 310efcc2a30SJung-uk Kim MethodInfo->ArgInitialized[RegisterNumber] = TRUE; 311efcc2a30SJung-uk Kim } 312efcc2a30SJung-uk Kim 313efcc2a30SJung-uk Kim /* 314efcc2a30SJung-uk Kim * Otherwise, this is a reference, check if the Arg 315efcc2a30SJung-uk Kim * has been previously initialized. 316efcc2a30SJung-uk Kim * 317efcc2a30SJung-uk Kim * The only operator that accepts an uninitialized value is ObjectType() 318efcc2a30SJung-uk Kim */ 319efcc2a30SJung-uk Kim else if ((!MethodInfo->ArgInitialized[RegisterNumber]) && 320efcc2a30SJung-uk Kim (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE)) 321efcc2a30SJung-uk Kim { 322efcc2a30SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_ARG_INIT, Op, ArgName); 323efcc2a30SJung-uk Kim } 324efcc2a30SJung-uk Kim 325efcc2a30SJung-uk Kim /* Flag this arg if it is not a "real" argument to the method */ 326efcc2a30SJung-uk Kim 327efcc2a30SJung-uk Kim if (RegisterNumber >= MethodInfo->NumArguments) 328efcc2a30SJung-uk Kim { 329efcc2a30SJung-uk Kim AslError (ASL_REMARK, ASL_MSG_NOT_PARAMETER, Op, ArgName); 330efcc2a30SJung-uk Kim } 331efcc2a30SJung-uk Kim break; 332efcc2a30SJung-uk Kim 333efcc2a30SJung-uk Kim case PARSEOP_RETURN: 334efcc2a30SJung-uk Kim 335efcc2a30SJung-uk Kim if (!MethodInfo) 336efcc2a30SJung-uk Kim { 337efcc2a30SJung-uk Kim /* 338efcc2a30SJung-uk Kim * Probably was an error in the method declaration, 339efcc2a30SJung-uk Kim * no additional error here 340efcc2a30SJung-uk Kim */ 341efcc2a30SJung-uk Kim ACPI_WARNING ((AE_INFO, "%p, No parent method", Op)); 342efcc2a30SJung-uk Kim return (AE_ERROR); 343efcc2a30SJung-uk Kim } 344efcc2a30SJung-uk Kim 345efcc2a30SJung-uk Kim /* 346efcc2a30SJung-uk Kim * A child indicates a possible return value. A simple Return or 347efcc2a30SJung-uk Kim * Return() is marked with NODE_IS_NULL_RETURN by the parser so 348efcc2a30SJung-uk Kim * that it is not counted as a "real" return-with-value, although 349efcc2a30SJung-uk Kim * the AML code that is actually emitted is Return(0). The AML 350efcc2a30SJung-uk Kim * definition of Return has a required parameter, so we are 351efcc2a30SJung-uk Kim * forced to convert a null return to Return(0). 352efcc2a30SJung-uk Kim */ 353efcc2a30SJung-uk Kim if ((Op->Asl.Child) && 354efcc2a30SJung-uk Kim (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) && 355efcc2a30SJung-uk Kim (!(Op->Asl.Child->Asl.CompileFlags & NODE_IS_NULL_RETURN))) 356efcc2a30SJung-uk Kim { 357efcc2a30SJung-uk Kim MethodInfo->NumReturnWithValue++; 358efcc2a30SJung-uk Kim } 359efcc2a30SJung-uk Kim else 360efcc2a30SJung-uk Kim { 361efcc2a30SJung-uk Kim MethodInfo->NumReturnNoValue++; 362efcc2a30SJung-uk Kim } 363efcc2a30SJung-uk Kim break; 364efcc2a30SJung-uk Kim 365efcc2a30SJung-uk Kim case PARSEOP_BREAK: 366efcc2a30SJung-uk Kim case PARSEOP_CONTINUE: 367efcc2a30SJung-uk Kim 368efcc2a30SJung-uk Kim Next = Op->Asl.Parent; 369efcc2a30SJung-uk Kim while (Next) 370efcc2a30SJung-uk Kim { 371efcc2a30SJung-uk Kim if (Next->Asl.ParseOpcode == PARSEOP_WHILE) 372efcc2a30SJung-uk Kim { 373efcc2a30SJung-uk Kim break; 374efcc2a30SJung-uk Kim } 375efcc2a30SJung-uk Kim Next = Next->Asl.Parent; 376efcc2a30SJung-uk Kim } 377efcc2a30SJung-uk Kim 378efcc2a30SJung-uk Kim if (!Next) 379efcc2a30SJung-uk Kim { 380efcc2a30SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_NO_WHILE, Op, NULL); 381efcc2a30SJung-uk Kim } 382efcc2a30SJung-uk Kim break; 383efcc2a30SJung-uk Kim 384efcc2a30SJung-uk Kim case PARSEOP_STALL: 385efcc2a30SJung-uk Kim 386efcc2a30SJung-uk Kim /* We can range check if the argument is an integer */ 387efcc2a30SJung-uk Kim 388efcc2a30SJung-uk Kim if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) && 389efcc2a30SJung-uk Kim (Op->Asl.Child->Asl.Value.Integer > ACPI_UINT8_MAX)) 390efcc2a30SJung-uk Kim { 391efcc2a30SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_INVALID_TIME, Op, NULL); 392efcc2a30SJung-uk Kim } 393efcc2a30SJung-uk Kim break; 394efcc2a30SJung-uk Kim 395efcc2a30SJung-uk Kim case PARSEOP_DEVICE: 396313a0c13SJung-uk Kim 397313a0c13SJung-uk Kim Next = Op->Asl.Child; 398313a0c13SJung-uk Kim 399313a0c13SJung-uk Kim if (!ApFindNameInScope (METHOD_NAME__HID, Next) && 400313a0c13SJung-uk Kim !ApFindNameInScope (METHOD_NAME__ADR, Next)) 401313a0c13SJung-uk Kim { 402313a0c13SJung-uk Kim AslError (ASL_WARNING, ASL_MSG_MISSING_DEPENDENCY, Op, 403313a0c13SJung-uk Kim "Device object requires a _HID or _ADR in same scope"); 404313a0c13SJung-uk Kim } 405313a0c13SJung-uk Kim break; 406313a0c13SJung-uk Kim 407efcc2a30SJung-uk Kim case PARSEOP_EVENT: 408efcc2a30SJung-uk Kim case PARSEOP_MUTEX: 409efcc2a30SJung-uk Kim case PARSEOP_OPERATIONREGION: 410efcc2a30SJung-uk Kim case PARSEOP_POWERRESOURCE: 411efcc2a30SJung-uk Kim case PARSEOP_PROCESSOR: 412efcc2a30SJung-uk Kim case PARSEOP_THERMALZONE: 413efcc2a30SJung-uk Kim 414efcc2a30SJung-uk Kim /* 415efcc2a30SJung-uk Kim * The first operand is a name to be created in the namespace. 416efcc2a30SJung-uk Kim * Check against the reserved list. 417efcc2a30SJung-uk Kim */ 418efcc2a30SJung-uk Kim i = ApCheckForPredefinedName (Op, Op->Asl.NameSeg); 419efcc2a30SJung-uk Kim if (i < ACPI_VALID_RESERVED_NAME_MAX) 420efcc2a30SJung-uk Kim { 421efcc2a30SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_RESERVED_USE, Op, Op->Asl.ExternalName); 422efcc2a30SJung-uk Kim } 423efcc2a30SJung-uk Kim break; 424efcc2a30SJung-uk Kim 425efcc2a30SJung-uk Kim case PARSEOP_NAME: 426efcc2a30SJung-uk Kim 427efcc2a30SJung-uk Kim /* Typecheck any predefined names statically defined with Name() */ 428efcc2a30SJung-uk Kim 429efcc2a30SJung-uk Kim ApCheckForPredefinedObject (Op, Op->Asl.NameSeg); 430efcc2a30SJung-uk Kim 431efcc2a30SJung-uk Kim /* Special typechecking for _HID */ 432efcc2a30SJung-uk Kim 4335ef50723SJung-uk Kim if (!strcmp (METHOD_NAME__HID, Op->Asl.NameSeg)) 434efcc2a30SJung-uk Kim { 435efcc2a30SJung-uk Kim Next = Op->Asl.Child->Asl.Next; 436efcc2a30SJung-uk Kim AnCheckId (Next, ASL_TYPE_HID); 437efcc2a30SJung-uk Kim } 438efcc2a30SJung-uk Kim 439efcc2a30SJung-uk Kim /* Special typechecking for _CID */ 440efcc2a30SJung-uk Kim 4415ef50723SJung-uk Kim else if (!strcmp (METHOD_NAME__CID, Op->Asl.NameSeg)) 442efcc2a30SJung-uk Kim { 443efcc2a30SJung-uk Kim Next = Op->Asl.Child->Asl.Next; 444efcc2a30SJung-uk Kim 445efcc2a30SJung-uk Kim if ((Next->Asl.ParseOpcode == PARSEOP_PACKAGE) || 446efcc2a30SJung-uk Kim (Next->Asl.ParseOpcode == PARSEOP_VAR_PACKAGE)) 447efcc2a30SJung-uk Kim { 448efcc2a30SJung-uk Kim Next = Next->Asl.Child; 449efcc2a30SJung-uk Kim while (Next) 450efcc2a30SJung-uk Kim { 451efcc2a30SJung-uk Kim AnCheckId (Next, ASL_TYPE_CID); 452efcc2a30SJung-uk Kim Next = Next->Asl.Next; 453efcc2a30SJung-uk Kim } 454efcc2a30SJung-uk Kim } 455efcc2a30SJung-uk Kim else 456efcc2a30SJung-uk Kim { 457efcc2a30SJung-uk Kim AnCheckId (Next, ASL_TYPE_CID); 458efcc2a30SJung-uk Kim } 459efcc2a30SJung-uk Kim } 460313a0c13SJung-uk Kim 461efcc2a30SJung-uk Kim break; 462efcc2a30SJung-uk Kim 463efcc2a30SJung-uk Kim default: 464a9d8d09cSJung-uk Kim 465efcc2a30SJung-uk Kim break; 466efcc2a30SJung-uk Kim } 467efcc2a30SJung-uk Kim 468a9d8d09cSJung-uk Kim /* Check for named object creation within a non-serialized method */ 469a9d8d09cSJung-uk Kim 470a9d8d09cSJung-uk Kim MtCheckNamedObjectInMethod (Op, MethodInfo); 471efcc2a30SJung-uk Kim return (AE_OK); 472efcc2a30SJung-uk Kim } 473efcc2a30SJung-uk Kim 474efcc2a30SJung-uk Kim 475efcc2a30SJung-uk Kim /******************************************************************************* 476efcc2a30SJung-uk Kim * 477a9d8d09cSJung-uk Kim * FUNCTION: MtCheckNamedObjectInMethod 478a9d8d09cSJung-uk Kim * 479a9d8d09cSJung-uk Kim * PARAMETERS: Op - Current parser op 480a9d8d09cSJung-uk Kim * MethodInfo - Info for method being parsed 481a9d8d09cSJung-uk Kim * 482a9d8d09cSJung-uk Kim * RETURN: None 483a9d8d09cSJung-uk Kim * 484a9d8d09cSJung-uk Kim * DESCRIPTION: Detect if a non-serialized method is creating a named object, 485a9d8d09cSJung-uk Kim * which could possibly cause problems if two threads execute 486a9d8d09cSJung-uk Kim * the method concurrently. Emit a remark in this case. 487a9d8d09cSJung-uk Kim * 488a9d8d09cSJung-uk Kim ******************************************************************************/ 489a9d8d09cSJung-uk Kim 490a9d8d09cSJung-uk Kim void 491a9d8d09cSJung-uk Kim MtCheckNamedObjectInMethod ( 492a9d8d09cSJung-uk Kim ACPI_PARSE_OBJECT *Op, 493a9d8d09cSJung-uk Kim ASL_METHOD_INFO *MethodInfo) 494a9d8d09cSJung-uk Kim { 495a9d8d09cSJung-uk Kim const ACPI_OPCODE_INFO *OpInfo; 496a9d8d09cSJung-uk Kim 497a9d8d09cSJung-uk Kim 498a9d8d09cSJung-uk Kim /* We don't care about actual method declarations */ 499a9d8d09cSJung-uk Kim 500a9d8d09cSJung-uk Kim if (Op->Asl.AmlOpcode == AML_METHOD_OP) 501a9d8d09cSJung-uk Kim { 502a9d8d09cSJung-uk Kim return; 503a9d8d09cSJung-uk Kim } 504a9d8d09cSJung-uk Kim 505a9d8d09cSJung-uk Kim /* Determine if we are creating a named object */ 506a9d8d09cSJung-uk Kim 507a9d8d09cSJung-uk Kim OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); 508a9d8d09cSJung-uk Kim if (OpInfo->Class == AML_CLASS_NAMED_OBJECT) 509a9d8d09cSJung-uk Kim { 510a9d8d09cSJung-uk Kim /* 511a9d8d09cSJung-uk Kim * If we have a named object created within a non-serialized method, 512a9d8d09cSJung-uk Kim * emit a remark that the method should be serialized. 513a9d8d09cSJung-uk Kim * 514a9d8d09cSJung-uk Kim * Reason: If a thread blocks within the method for any reason, and 515a9d8d09cSJung-uk Kim * another thread enters the method, the method will fail because an 516a9d8d09cSJung-uk Kim * attempt will be made to create the same object twice. 517a9d8d09cSJung-uk Kim */ 518a9d8d09cSJung-uk Kim if (MethodInfo && !MethodInfo->ShouldBeSerialized) 519a9d8d09cSJung-uk Kim { 520a9d8d09cSJung-uk Kim AslError (ASL_REMARK, ASL_MSG_SERIALIZED_REQUIRED, MethodInfo->Op, 521a9d8d09cSJung-uk Kim "due to creation of named objects within"); 522a9d8d09cSJung-uk Kim 523a9d8d09cSJung-uk Kim /* Emit message only ONCE per method */ 524a9d8d09cSJung-uk Kim 525a9d8d09cSJung-uk Kim MethodInfo->ShouldBeSerialized = TRUE; 526a9d8d09cSJung-uk Kim } 527a9d8d09cSJung-uk Kim } 528a9d8d09cSJung-uk Kim } 529a9d8d09cSJung-uk Kim 530a9d8d09cSJung-uk Kim 531a9d8d09cSJung-uk Kim /******************************************************************************* 532a9d8d09cSJung-uk Kim * 533efcc2a30SJung-uk Kim * FUNCTION: MtMethodAnalysisWalkEnd 534efcc2a30SJung-uk Kim * 535efcc2a30SJung-uk Kim * PARAMETERS: ASL_WALK_CALLBACK 536efcc2a30SJung-uk Kim * 537efcc2a30SJung-uk Kim * RETURN: Status 538efcc2a30SJung-uk Kim * 539efcc2a30SJung-uk Kim * DESCRIPTION: Ascending callback for analysis walk. Complete method 540efcc2a30SJung-uk Kim * return analysis. 541efcc2a30SJung-uk Kim * 542efcc2a30SJung-uk Kim ******************************************************************************/ 543efcc2a30SJung-uk Kim 544efcc2a30SJung-uk Kim ACPI_STATUS 545efcc2a30SJung-uk Kim MtMethodAnalysisWalkEnd ( 546efcc2a30SJung-uk Kim ACPI_PARSE_OBJECT *Op, 547efcc2a30SJung-uk Kim UINT32 Level, 548efcc2a30SJung-uk Kim void *Context) 549efcc2a30SJung-uk Kim { 550efcc2a30SJung-uk Kim ASL_ANALYSIS_WALK_INFO *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context; 551efcc2a30SJung-uk Kim ASL_METHOD_INFO *MethodInfo = WalkInfo->MethodStack; 552efcc2a30SJung-uk Kim 553efcc2a30SJung-uk Kim 554efcc2a30SJung-uk Kim switch (Op->Asl.ParseOpcode) 555efcc2a30SJung-uk Kim { 556efcc2a30SJung-uk Kim case PARSEOP_METHOD: 557efcc2a30SJung-uk Kim case PARSEOP_RETURN: 558a9d8d09cSJung-uk Kim 559efcc2a30SJung-uk Kim if (!MethodInfo) 560efcc2a30SJung-uk Kim { 561efcc2a30SJung-uk Kim printf ("No method info for method! [%s]\n", Op->Asl.Namepath); 562efcc2a30SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op, 563efcc2a30SJung-uk Kim "No method info for this method"); 564efcc2a30SJung-uk Kim 565efcc2a30SJung-uk Kim CmCleanupAndExit (); 566efcc2a30SJung-uk Kim return (AE_AML_INTERNAL); 567efcc2a30SJung-uk Kim } 568efcc2a30SJung-uk Kim break; 569efcc2a30SJung-uk Kim 570efcc2a30SJung-uk Kim default: 571a9d8d09cSJung-uk Kim 572efcc2a30SJung-uk Kim break; 573efcc2a30SJung-uk Kim } 574efcc2a30SJung-uk Kim 575efcc2a30SJung-uk Kim switch (Op->Asl.ParseOpcode) 576efcc2a30SJung-uk Kim { 577efcc2a30SJung-uk Kim case PARSEOP_METHOD: 578efcc2a30SJung-uk Kim 579efcc2a30SJung-uk Kim WalkInfo->MethodStack = MethodInfo->Next; 580efcc2a30SJung-uk Kim 581efcc2a30SJung-uk Kim /* 582efcc2a30SJung-uk Kim * Check if there is no return statement at the end of the 583efcc2a30SJung-uk Kim * method AND we can actually get there -- i.e., the execution 584efcc2a30SJung-uk Kim * of the method can possibly terminate without a return statement. 585efcc2a30SJung-uk Kim */ 586efcc2a30SJung-uk Kim if ((!AnLastStatementIsReturn (Op)) && 587efcc2a30SJung-uk Kim (!(Op->Asl.CompileFlags & NODE_HAS_NO_EXIT))) 588efcc2a30SJung-uk Kim { 589efcc2a30SJung-uk Kim /* 590efcc2a30SJung-uk Kim * No return statement, and execution can possibly exit 591efcc2a30SJung-uk Kim * via this path. This is equivalent to Return () 592efcc2a30SJung-uk Kim */ 593efcc2a30SJung-uk Kim MethodInfo->NumReturnNoValue++; 594efcc2a30SJung-uk Kim } 595efcc2a30SJung-uk Kim 596efcc2a30SJung-uk Kim /* 597efcc2a30SJung-uk Kim * Check for case where some return statements have a return value 598efcc2a30SJung-uk Kim * and some do not. Exit without a return statement is a return with 599efcc2a30SJung-uk Kim * no value 600efcc2a30SJung-uk Kim */ 601efcc2a30SJung-uk Kim if (MethodInfo->NumReturnNoValue && 602efcc2a30SJung-uk Kim MethodInfo->NumReturnWithValue) 603efcc2a30SJung-uk Kim { 604efcc2a30SJung-uk Kim AslError (ASL_WARNING, ASL_MSG_RETURN_TYPES, Op, 605efcc2a30SJung-uk Kim Op->Asl.ExternalName); 606efcc2a30SJung-uk Kim } 607efcc2a30SJung-uk Kim 608efcc2a30SJung-uk Kim /* 609efcc2a30SJung-uk Kim * If there are any RETURN() statements with no value, or there is a 610efcc2a30SJung-uk Kim * control path that allows the method to exit without a return value, 611efcc2a30SJung-uk Kim * we mark the method as a method that does not return a value. This 612efcc2a30SJung-uk Kim * knowledge can be used to check method invocations that expect a 613efcc2a30SJung-uk Kim * returned value. 614efcc2a30SJung-uk Kim */ 615efcc2a30SJung-uk Kim if (MethodInfo->NumReturnNoValue) 616efcc2a30SJung-uk Kim { 617efcc2a30SJung-uk Kim if (MethodInfo->NumReturnWithValue) 618efcc2a30SJung-uk Kim { 619efcc2a30SJung-uk Kim Op->Asl.CompileFlags |= NODE_METHOD_SOME_NO_RETVAL; 620efcc2a30SJung-uk Kim } 621efcc2a30SJung-uk Kim else 622efcc2a30SJung-uk Kim { 623efcc2a30SJung-uk Kim Op->Asl.CompileFlags |= NODE_METHOD_NO_RETVAL; 624efcc2a30SJung-uk Kim } 625efcc2a30SJung-uk Kim } 626efcc2a30SJung-uk Kim 627efcc2a30SJung-uk Kim /* 628efcc2a30SJung-uk Kim * Check predefined method names for correct return behavior 629efcc2a30SJung-uk Kim * and correct number of arguments. Also, some special checks 630efcc2a30SJung-uk Kim * For GPE and _REG methods. 631efcc2a30SJung-uk Kim */ 632efcc2a30SJung-uk Kim if (ApCheckForPredefinedMethod (Op, MethodInfo)) 633efcc2a30SJung-uk Kim { 634efcc2a30SJung-uk Kim /* Special check for two names like _L01 and _E01 in same scope */ 635efcc2a30SJung-uk Kim 636efcc2a30SJung-uk Kim ApCheckForGpeNameConflict (Op); 637efcc2a30SJung-uk Kim 638efcc2a30SJung-uk Kim /* 639efcc2a30SJung-uk Kim * Special check for _REG: Must have an operation region definition 640efcc2a30SJung-uk Kim * within the same scope! 641efcc2a30SJung-uk Kim */ 642efcc2a30SJung-uk Kim ApCheckRegMethod (Op); 643efcc2a30SJung-uk Kim } 644efcc2a30SJung-uk Kim 645efcc2a30SJung-uk Kim ACPI_FREE (MethodInfo); 646efcc2a30SJung-uk Kim break; 647efcc2a30SJung-uk Kim 648efcc2a30SJung-uk Kim case PARSEOP_NAME: 649efcc2a30SJung-uk Kim 650efcc2a30SJung-uk Kim /* Special check for two names like _L01 and _E01 in same scope */ 651efcc2a30SJung-uk Kim 652efcc2a30SJung-uk Kim ApCheckForGpeNameConflict (Op); 653efcc2a30SJung-uk Kim break; 654efcc2a30SJung-uk Kim 655efcc2a30SJung-uk Kim case PARSEOP_RETURN: 656efcc2a30SJung-uk Kim 657efcc2a30SJung-uk Kim /* 658efcc2a30SJung-uk Kim * If the parent is a predefined method name, attempt to typecheck 659efcc2a30SJung-uk Kim * the return value. Only static types can be validated. 660efcc2a30SJung-uk Kim */ 661efcc2a30SJung-uk Kim ApCheckPredefinedReturnValue (Op, MethodInfo); 662efcc2a30SJung-uk Kim 663efcc2a30SJung-uk Kim /* 664efcc2a30SJung-uk Kim * The parent block does not "exit" and continue execution -- the 665efcc2a30SJung-uk Kim * method is terminated here with the Return() statement. 666efcc2a30SJung-uk Kim */ 667efcc2a30SJung-uk Kim Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT; 668efcc2a30SJung-uk Kim 669efcc2a30SJung-uk Kim /* Used in the "typing" pass later */ 670efcc2a30SJung-uk Kim 671efcc2a30SJung-uk Kim Op->Asl.ParentMethod = MethodInfo->Op; 672efcc2a30SJung-uk Kim 673efcc2a30SJung-uk Kim /* 674efcc2a30SJung-uk Kim * If there is a peer node after the return statement, then this 675efcc2a30SJung-uk Kim * node is unreachable code -- i.e., it won't be executed because of 676efcc2a30SJung-uk Kim * the preceding Return() statement. 677efcc2a30SJung-uk Kim */ 678efcc2a30SJung-uk Kim if (Op->Asl.Next) 679efcc2a30SJung-uk Kim { 680efcc2a30SJung-uk Kim AslError (ASL_WARNING, ASL_MSG_UNREACHABLE_CODE, Op->Asl.Next, NULL); 681efcc2a30SJung-uk Kim } 682efcc2a30SJung-uk Kim break; 683efcc2a30SJung-uk Kim 684efcc2a30SJung-uk Kim case PARSEOP_IF: 685efcc2a30SJung-uk Kim 686efcc2a30SJung-uk Kim if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) && 687efcc2a30SJung-uk Kim (Op->Asl.Next) && 688efcc2a30SJung-uk Kim (Op->Asl.Next->Asl.ParseOpcode == PARSEOP_ELSE)) 689efcc2a30SJung-uk Kim { 690efcc2a30SJung-uk Kim /* 691efcc2a30SJung-uk Kim * This IF has a corresponding ELSE. The IF block has no exit, 692efcc2a30SJung-uk Kim * (it contains an unconditional Return) 693efcc2a30SJung-uk Kim * mark the ELSE block to remember this fact. 694efcc2a30SJung-uk Kim */ 695efcc2a30SJung-uk Kim Op->Asl.Next->Asl.CompileFlags |= NODE_IF_HAS_NO_EXIT; 696efcc2a30SJung-uk Kim } 697efcc2a30SJung-uk Kim break; 698efcc2a30SJung-uk Kim 699efcc2a30SJung-uk Kim case PARSEOP_ELSE: 700efcc2a30SJung-uk Kim 701efcc2a30SJung-uk Kim if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) && 702efcc2a30SJung-uk Kim (Op->Asl.CompileFlags & NODE_IF_HAS_NO_EXIT)) 703efcc2a30SJung-uk Kim { 704efcc2a30SJung-uk Kim /* 705efcc2a30SJung-uk Kim * This ELSE block has no exit and the corresponding IF block 706efcc2a30SJung-uk Kim * has no exit either. Therefore, the parent node has no exit. 707efcc2a30SJung-uk Kim */ 708efcc2a30SJung-uk Kim Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT; 709efcc2a30SJung-uk Kim } 710efcc2a30SJung-uk Kim break; 711efcc2a30SJung-uk Kim 712efcc2a30SJung-uk Kim 713efcc2a30SJung-uk Kim default: 714efcc2a30SJung-uk Kim 715efcc2a30SJung-uk Kim if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) && 716efcc2a30SJung-uk Kim (Op->Asl.Parent)) 717efcc2a30SJung-uk Kim { 718efcc2a30SJung-uk Kim /* If this node has no exit, then the parent has no exit either */ 719efcc2a30SJung-uk Kim 720efcc2a30SJung-uk Kim Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT; 721efcc2a30SJung-uk Kim } 722efcc2a30SJung-uk Kim break; 723efcc2a30SJung-uk Kim } 724efcc2a30SJung-uk Kim 725efcc2a30SJung-uk Kim return (AE_OK); 726efcc2a30SJung-uk Kim } 727