1 /****************************************************************************** 2 * 3 * Module Name: dswexec - Dispatcher method execution callbacks; 4 * dispatch to interpreter. 5 * 6 *****************************************************************************/ 7 8 /* 9 * Copyright (C) 2000 - 2016, Intel Corp. 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions, and the following disclaimer, 17 * without modification. 18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19 * substantially similar to the "NO WARRANTY" disclaimer below 20 * ("Disclaimer") and any redistribution must be conditioned upon 21 * including a substantially similar Disclaimer requirement for further 22 * binary redistribution. 23 * 3. Neither the names of the above-listed copyright holders nor the names 24 * of any contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * Alternatively, this software may be distributed under the terms of the 28 * GNU General Public License ("GPL") version 2 as published by the Free 29 * Software Foundation. 30 * 31 * NO WARRANTY 32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42 * POSSIBILITY OF SUCH DAMAGES. 43 */ 44 45 #include "acpi.h" 46 #include "accommon.h" 47 #include "acparser.h" 48 #include "amlcode.h" 49 #include "acdispat.h" 50 #include "acinterp.h" 51 #include "acnamesp.h" 52 #include "acdebug.h" 53 54 55 #define _COMPONENT ACPI_DISPATCHER 56 ACPI_MODULE_NAME ("dswexec") 57 58 /* 59 * Dispatch table for opcode classes 60 */ 61 static ACPI_EXECUTE_OP AcpiGbl_OpTypeDispatch [] = 62 { 63 AcpiExOpcode_0A_0T_1R, 64 AcpiExOpcode_1A_0T_0R, 65 AcpiExOpcode_1A_0T_1R, 66 AcpiExOpcode_1A_1T_0R, 67 AcpiExOpcode_1A_1T_1R, 68 AcpiExOpcode_2A_0T_0R, 69 AcpiExOpcode_2A_0T_1R, 70 AcpiExOpcode_2A_1T_1R, 71 AcpiExOpcode_2A_2T_1R, 72 AcpiExOpcode_3A_0T_0R, 73 AcpiExOpcode_3A_1T_1R, 74 AcpiExOpcode_6A_0T_1R 75 }; 76 77 78 /***************************************************************************** 79 * 80 * FUNCTION: AcpiDsGetPredicateValue 81 * 82 * PARAMETERS: WalkState - Current state of the parse tree walk 83 * ResultObj - if non-zero, pop result from result stack 84 * 85 * RETURN: Status 86 * 87 * DESCRIPTION: Get the result of a predicate evaluation 88 * 89 ****************************************************************************/ 90 91 ACPI_STATUS 92 AcpiDsGetPredicateValue ( 93 ACPI_WALK_STATE *WalkState, 94 ACPI_OPERAND_OBJECT *ResultObj) 95 { 96 ACPI_STATUS Status = AE_OK; 97 ACPI_OPERAND_OBJECT *ObjDesc; 98 ACPI_OPERAND_OBJECT *LocalObjDesc = NULL; 99 100 101 ACPI_FUNCTION_TRACE_PTR (DsGetPredicateValue, WalkState); 102 103 104 WalkState->ControlState->Common.State = 0; 105 106 if (ResultObj) 107 { 108 Status = AcpiDsResultPop (&ObjDesc, WalkState); 109 if (ACPI_FAILURE (Status)) 110 { 111 ACPI_EXCEPTION ((AE_INFO, Status, 112 "Could not get result from predicate evaluation")); 113 114 return_ACPI_STATUS (Status); 115 } 116 } 117 else 118 { 119 Status = AcpiDsCreateOperand (WalkState, WalkState->Op, 0); 120 if (ACPI_FAILURE (Status)) 121 { 122 return_ACPI_STATUS (Status); 123 } 124 125 Status = AcpiExResolveToValue (&WalkState->Operands [0], WalkState); 126 if (ACPI_FAILURE (Status)) 127 { 128 return_ACPI_STATUS (Status); 129 } 130 131 ObjDesc = WalkState->Operands [0]; 132 } 133 134 if (!ObjDesc) 135 { 136 ACPI_ERROR ((AE_INFO, 137 "No predicate ObjDesc=%p State=%p", 138 ObjDesc, WalkState)); 139 140 return_ACPI_STATUS (AE_AML_NO_OPERAND); 141 } 142 143 /* 144 * Result of predicate evaluation must be an Integer 145 * object. Implicitly convert the argument if necessary. 146 */ 147 Status = AcpiExConvertToInteger (ObjDesc, &LocalObjDesc, 16); 148 if (ACPI_FAILURE (Status)) 149 { 150 goto Cleanup; 151 } 152 153 if (LocalObjDesc->Common.Type != ACPI_TYPE_INTEGER) 154 { 155 ACPI_ERROR ((AE_INFO, 156 "Bad predicate (not an integer) ObjDesc=%p State=%p Type=0x%X", 157 ObjDesc, WalkState, ObjDesc->Common.Type)); 158 159 Status = AE_AML_OPERAND_TYPE; 160 goto Cleanup; 161 } 162 163 /* Truncate the predicate to 32-bits if necessary */ 164 165 (void) AcpiExTruncateFor32bitTable (LocalObjDesc); 166 167 /* 168 * Save the result of the predicate evaluation on 169 * the control stack 170 */ 171 if (LocalObjDesc->Integer.Value) 172 { 173 WalkState->ControlState->Common.Value = TRUE; 174 } 175 else 176 { 177 /* 178 * Predicate is FALSE, we will just toss the 179 * rest of the package 180 */ 181 WalkState->ControlState->Common.Value = FALSE; 182 Status = AE_CTRL_FALSE; 183 } 184 185 /* Predicate can be used for an implicit return value */ 186 187 (void) AcpiDsDoImplicitReturn (LocalObjDesc, WalkState, TRUE); 188 189 190 Cleanup: 191 192 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 193 "Completed a predicate eval=%X Op=%p\n", 194 WalkState->ControlState->Common.Value, WalkState->Op)); 195 196 #ifdef ACPI_DEBUGGER 197 /* Break to debugger to display result */ 198 199 AcpiDbDisplayResultObject (LocalObjDesc, WalkState); 200 #endif 201 202 /* 203 * Delete the predicate result object (we know that 204 * we don't need it anymore) 205 */ 206 if (LocalObjDesc != ObjDesc) 207 { 208 AcpiUtRemoveReference (LocalObjDesc); 209 } 210 AcpiUtRemoveReference (ObjDesc); 211 212 WalkState->ControlState->Common.State = ACPI_CONTROL_NORMAL; 213 return_ACPI_STATUS (Status); 214 } 215 216 217 /***************************************************************************** 218 * 219 * FUNCTION: AcpiDsExecBeginOp 220 * 221 * PARAMETERS: WalkState - Current state of the parse tree walk 222 * OutOp - Where to return op if a new one is created 223 * 224 * RETURN: Status 225 * 226 * DESCRIPTION: Descending callback used during the execution of control 227 * methods. This is where most operators and operands are 228 * dispatched to the interpreter. 229 * 230 ****************************************************************************/ 231 232 ACPI_STATUS 233 AcpiDsExecBeginOp ( 234 ACPI_WALK_STATE *WalkState, 235 ACPI_PARSE_OBJECT **OutOp) 236 { 237 ACPI_PARSE_OBJECT *Op; 238 ACPI_STATUS Status = AE_OK; 239 UINT32 OpcodeClass; 240 241 242 ACPI_FUNCTION_TRACE_PTR (DsExecBeginOp, WalkState); 243 244 245 Op = WalkState->Op; 246 if (!Op) 247 { 248 Status = AcpiDsLoad2BeginOp (WalkState, OutOp); 249 if (ACPI_FAILURE (Status)) 250 { 251 goto ErrorExit; 252 } 253 254 Op = *OutOp; 255 WalkState->Op = Op; 256 WalkState->Opcode = Op->Common.AmlOpcode; 257 WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 258 259 if (AcpiNsOpensScope (WalkState->OpInfo->ObjectType)) 260 { 261 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 262 "(%s) Popping scope for Op %p\n", 263 AcpiUtGetTypeName (WalkState->OpInfo->ObjectType), Op)); 264 265 Status = AcpiDsScopeStackPop (WalkState); 266 if (ACPI_FAILURE (Status)) 267 { 268 goto ErrorExit; 269 } 270 } 271 } 272 273 if (Op == WalkState->Origin) 274 { 275 if (OutOp) 276 { 277 *OutOp = Op; 278 } 279 280 return_ACPI_STATUS (AE_OK); 281 } 282 283 /* 284 * If the previous opcode was a conditional, this opcode 285 * must be the beginning of the associated predicate. 286 * Save this knowledge in the current scope descriptor 287 */ 288 if ((WalkState->ControlState) && 289 (WalkState->ControlState->Common.State == 290 ACPI_CONTROL_CONDITIONAL_EXECUTING)) 291 { 292 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 293 "Exec predicate Op=%p State=%p\n", 294 Op, WalkState)); 295 296 WalkState->ControlState->Common.State = 297 ACPI_CONTROL_PREDICATE_EXECUTING; 298 299 /* Save start of predicate */ 300 301 WalkState->ControlState->Control.PredicateOp = Op; 302 } 303 304 305 OpcodeClass = WalkState->OpInfo->Class; 306 307 /* We want to send namepaths to the load code */ 308 309 if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP) 310 { 311 OpcodeClass = AML_CLASS_NAMED_OBJECT; 312 } 313 314 /* 315 * Handle the opcode based upon the opcode type 316 */ 317 switch (OpcodeClass) 318 { 319 case AML_CLASS_CONTROL: 320 321 Status = AcpiDsExecBeginControlOp (WalkState, Op); 322 break; 323 324 case AML_CLASS_NAMED_OBJECT: 325 326 if (WalkState->WalkType & ACPI_WALK_METHOD) 327 { 328 /* 329 * Found a named object declaration during method execution; 330 * we must enter this object into the namespace. The created 331 * object is temporary and will be deleted upon completion of 332 * the execution of this method. 333 * 334 * Note 10/2010: Except for the Scope() op. This opcode does 335 * not actually create a new object, it refers to an existing 336 * object. However, for Scope(), we want to indeed open a 337 * new scope. 338 */ 339 if (Op->Common.AmlOpcode != AML_SCOPE_OP) 340 { 341 Status = AcpiDsLoad2BeginOp (WalkState, NULL); 342 } 343 else 344 { 345 Status = AcpiDsScopeStackPush ( 346 Op->Named.Node, Op->Named.Node->Type, WalkState); 347 if (ACPI_FAILURE (Status)) 348 { 349 return_ACPI_STATUS (Status); 350 } 351 } 352 } 353 break; 354 355 case AML_CLASS_EXECUTE: 356 case AML_CLASS_CREATE: 357 358 break; 359 360 default: 361 362 break; 363 } 364 365 /* Nothing to do here during method execution */ 366 367 return_ACPI_STATUS (Status); 368 369 370 ErrorExit: 371 Status = AcpiDsMethodError (Status, WalkState); 372 return_ACPI_STATUS (Status); 373 } 374 375 376 /***************************************************************************** 377 * 378 * FUNCTION: AcpiDsExecEndOp 379 * 380 * PARAMETERS: WalkState - Current state of the parse tree walk 381 * 382 * RETURN: Status 383 * 384 * DESCRIPTION: Ascending callback used during the execution of control 385 * methods. The only thing we really need to do here is to 386 * notice the beginning of IF, ELSE, and WHILE blocks. 387 * 388 ****************************************************************************/ 389 390 ACPI_STATUS 391 AcpiDsExecEndOp ( 392 ACPI_WALK_STATE *WalkState) 393 { 394 ACPI_PARSE_OBJECT *Op; 395 ACPI_STATUS Status = AE_OK; 396 UINT32 OpType; 397 UINT32 OpClass; 398 ACPI_PARSE_OBJECT *NextOp; 399 ACPI_PARSE_OBJECT *FirstArg; 400 401 402 ACPI_FUNCTION_TRACE_PTR (DsExecEndOp, WalkState); 403 404 405 Op = WalkState->Op; 406 OpType = WalkState->OpInfo->Type; 407 OpClass = WalkState->OpInfo->Class; 408 409 if (OpClass == AML_CLASS_UNKNOWN) 410 { 411 ACPI_ERROR ((AE_INFO, "Unknown opcode 0x%X", Op->Common.AmlOpcode)); 412 return_ACPI_STATUS (AE_NOT_IMPLEMENTED); 413 } 414 415 FirstArg = Op->Common.Value.Arg; 416 417 /* Init the walk state */ 418 419 WalkState->NumOperands = 0; 420 WalkState->OperandIndex = 0; 421 WalkState->ReturnDesc = NULL; 422 WalkState->ResultObj = NULL; 423 424 #ifdef ACPI_DEBUGGER 425 /* Call debugger for single step support (DEBUG build only) */ 426 427 Status = AcpiDbSingleStep (WalkState, Op, OpClass); 428 if (ACPI_FAILURE (Status)) 429 { 430 return_ACPI_STATUS (Status); 431 } 432 #endif 433 434 /* Decode the Opcode Class */ 435 436 switch (OpClass) 437 { 438 case AML_CLASS_ARGUMENT: /* Constants, literals, etc. */ 439 440 if (WalkState->Opcode == AML_INT_NAMEPATH_OP) 441 { 442 Status = AcpiDsEvaluateNamePath (WalkState); 443 if (ACPI_FAILURE (Status)) 444 { 445 goto Cleanup; 446 } 447 } 448 break; 449 450 case AML_CLASS_EXECUTE: /* Most operators with arguments */ 451 452 /* Build resolved operand stack */ 453 454 Status = AcpiDsCreateOperands (WalkState, FirstArg); 455 if (ACPI_FAILURE (Status)) 456 { 457 goto Cleanup; 458 } 459 460 /* 461 * All opcodes require operand resolution, with the only exceptions 462 * being the ObjectType and SizeOf operators. 463 */ 464 if (!(WalkState->OpInfo->Flags & AML_NO_OPERAND_RESOLVE)) 465 { 466 /* Resolve all operands */ 467 468 Status = AcpiExResolveOperands (WalkState->Opcode, 469 &(WalkState->Operands [WalkState->NumOperands -1]), 470 WalkState); 471 } 472 473 if (ACPI_SUCCESS (Status)) 474 { 475 /* 476 * Dispatch the request to the appropriate interpreter handler 477 * routine. There is one routine per opcode "type" based upon the 478 * number of opcode arguments and return type. 479 */ 480 Status = AcpiGbl_OpTypeDispatch[OpType] (WalkState); 481 } 482 else 483 { 484 /* 485 * Treat constructs of the form "Store(LocalX,LocalX)" as noops when the 486 * Local is uninitialized. 487 */ 488 if ((Status == AE_AML_UNINITIALIZED_LOCAL) && 489 (WalkState->Opcode == AML_STORE_OP) && 490 (WalkState->Operands[0]->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) && 491 (WalkState->Operands[1]->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) && 492 (WalkState->Operands[0]->Reference.Class == 493 WalkState->Operands[1]->Reference.Class) && 494 (WalkState->Operands[0]->Reference.Value == 495 WalkState->Operands[1]->Reference.Value)) 496 { 497 Status = AE_OK; 498 } 499 else 500 { 501 ACPI_EXCEPTION ((AE_INFO, Status, 502 "While resolving operands for [%s]", 503 AcpiPsGetOpcodeName (WalkState->Opcode))); 504 } 505 } 506 507 /* Always delete the argument objects and clear the operand stack */ 508 509 AcpiDsClearOperands (WalkState); 510 511 /* 512 * If a result object was returned from above, push it on the 513 * current result stack 514 */ 515 if (ACPI_SUCCESS (Status) && 516 WalkState->ResultObj) 517 { 518 Status = AcpiDsResultPush (WalkState->ResultObj, WalkState); 519 } 520 break; 521 522 default: 523 524 switch (OpType) 525 { 526 case AML_TYPE_CONTROL: /* Type 1 opcode, IF/ELSE/WHILE/NOOP */ 527 528 /* 1 Operand, 0 ExternalResult, 0 InternalResult */ 529 530 Status = AcpiDsExecEndControlOp (WalkState, Op); 531 532 break; 533 534 case AML_TYPE_METHOD_CALL: 535 /* 536 * If the method is referenced from within a package 537 * declaration, it is not a invocation of the method, just 538 * a reference to it. 539 */ 540 if ((Op->Asl.Parent) && 541 ((Op->Asl.Parent->Asl.AmlOpcode == AML_PACKAGE_OP) || 542 (Op->Asl.Parent->Asl.AmlOpcode == AML_VAR_PACKAGE_OP))) 543 { 544 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 545 "Method Reference in a Package, Op=%p\n", Op)); 546 547 Op->Common.Node = (ACPI_NAMESPACE_NODE *) 548 Op->Asl.Value.Arg->Asl.Node; 549 AcpiUtAddReference (Op->Asl.Value.Arg->Asl.Node->Object); 550 return_ACPI_STATUS (AE_OK); 551 } 552 553 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 554 "Method invocation, Op=%p\n", Op)); 555 556 /* 557 * (AML_METHODCALL) Op->Asl.Value.Arg->Asl.Node contains 558 * the method Node pointer 559 */ 560 /* NextOp points to the op that holds the method name */ 561 562 NextOp = FirstArg; 563 564 /* NextOp points to first argument op */ 565 566 NextOp = NextOp->Common.Next; 567 568 /* 569 * Get the method's arguments and put them on the operand stack 570 */ 571 Status = AcpiDsCreateOperands (WalkState, NextOp); 572 if (ACPI_FAILURE (Status)) 573 { 574 break; 575 } 576 577 /* 578 * Since the operands will be passed to another control method, 579 * we must resolve all local references here (Local variables, 580 * arguments to *this* method, etc.) 581 */ 582 Status = AcpiDsResolveOperands (WalkState); 583 if (ACPI_FAILURE (Status)) 584 { 585 /* On error, clear all resolved operands */ 586 587 AcpiDsClearOperands (WalkState); 588 break; 589 } 590 591 /* 592 * Tell the walk loop to preempt this running method and 593 * execute the new method 594 */ 595 Status = AE_CTRL_TRANSFER; 596 597 /* 598 * Return now; we don't want to disturb anything, 599 * especially the operand count! 600 */ 601 return_ACPI_STATUS (Status); 602 603 case AML_TYPE_CREATE_FIELD: 604 605 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 606 "Executing CreateField Buffer/Index Op=%p\n", Op)); 607 608 Status = AcpiDsLoad2EndOp (WalkState); 609 if (ACPI_FAILURE (Status)) 610 { 611 break; 612 } 613 614 Status = AcpiDsEvalBufferFieldOperands (WalkState, Op); 615 break; 616 617 618 case AML_TYPE_CREATE_OBJECT: 619 620 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 621 "Executing CreateObject (Buffer/Package) Op=%p\n", Op)); 622 623 switch (Op->Common.Parent->Common.AmlOpcode) 624 { 625 case AML_NAME_OP: 626 /* 627 * Put the Node on the object stack (Contains the ACPI Name 628 * of this object) 629 */ 630 WalkState->Operands[0] = (void *) 631 Op->Common.Parent->Common.Node; 632 WalkState->NumOperands = 1; 633 634 Status = AcpiDsCreateNode (WalkState, 635 Op->Common.Parent->Common.Node, Op->Common.Parent); 636 if (ACPI_FAILURE (Status)) 637 { 638 break; 639 } 640 641 /* Fall through */ 642 /*lint -fallthrough */ 643 644 case AML_INT_EVAL_SUBTREE_OP: 645 646 Status = AcpiDsEvalDataObjectOperands (WalkState, Op, 647 AcpiNsGetAttachedObject (Op->Common.Parent->Common.Node)); 648 break; 649 650 default: 651 652 Status = AcpiDsEvalDataObjectOperands (WalkState, Op, NULL); 653 break; 654 } 655 656 /* 657 * If a result object was returned from above, push it on the 658 * current result stack 659 */ 660 if (WalkState->ResultObj) 661 { 662 Status = AcpiDsResultPush (WalkState->ResultObj, WalkState); 663 } 664 break; 665 666 case AML_TYPE_NAMED_FIELD: 667 case AML_TYPE_NAMED_COMPLEX: 668 case AML_TYPE_NAMED_SIMPLE: 669 case AML_TYPE_NAMED_NO_OBJ: 670 671 Status = AcpiDsLoad2EndOp (WalkState); 672 if (ACPI_FAILURE (Status)) 673 { 674 break; 675 } 676 677 if (Op->Common.AmlOpcode == AML_REGION_OP) 678 { 679 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 680 "Executing OpRegion Address/Length Op=%p\n", Op)); 681 682 Status = AcpiDsEvalRegionOperands (WalkState, Op); 683 if (ACPI_FAILURE (Status)) 684 { 685 break; 686 } 687 } 688 else if (Op->Common.AmlOpcode == AML_DATA_REGION_OP) 689 { 690 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 691 "Executing DataTableRegion Strings Op=%p\n", Op)); 692 693 Status = AcpiDsEvalTableRegionOperands (WalkState, Op); 694 if (ACPI_FAILURE (Status)) 695 { 696 break; 697 } 698 } 699 else if (Op->Common.AmlOpcode == AML_BANK_FIELD_OP) 700 { 701 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 702 "Executing BankField Op=%p\n", Op)); 703 704 Status = AcpiDsEvalBankFieldOperands (WalkState, Op); 705 if (ACPI_FAILURE (Status)) 706 { 707 break; 708 } 709 } 710 break; 711 712 case AML_TYPE_UNDEFINED: 713 714 ACPI_ERROR ((AE_INFO, 715 "Undefined opcode type Op=%p", Op)); 716 return_ACPI_STATUS (AE_NOT_IMPLEMENTED); 717 718 case AML_TYPE_BOGUS: 719 720 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 721 "Internal opcode=%X type Op=%p\n", 722 WalkState->Opcode, Op)); 723 break; 724 725 default: 726 727 ACPI_ERROR ((AE_INFO, 728 "Unimplemented opcode, class=0x%X " 729 "type=0x%X Opcode=0x%X Op=%p", 730 OpClass, OpType, Op->Common.AmlOpcode, Op)); 731 732 Status = AE_NOT_IMPLEMENTED; 733 break; 734 } 735 } 736 737 /* 738 * ACPI 2.0 support for 64-bit integers: Truncate numeric 739 * result value if we are executing from a 32-bit ACPI table 740 */ 741 (void) AcpiExTruncateFor32bitTable (WalkState->ResultObj); 742 743 /* 744 * Check if we just completed the evaluation of a 745 * conditional predicate 746 */ 747 if ((ACPI_SUCCESS (Status)) && 748 (WalkState->ControlState) && 749 (WalkState->ControlState->Common.State == 750 ACPI_CONTROL_PREDICATE_EXECUTING) && 751 (WalkState->ControlState->Control.PredicateOp == Op)) 752 { 753 Status = AcpiDsGetPredicateValue (WalkState, WalkState->ResultObj); 754 WalkState->ResultObj = NULL; 755 } 756 757 758 Cleanup: 759 760 if (WalkState->ResultObj) 761 { 762 #ifdef ACPI_DEBUGGER 763 /* Break to debugger to display result */ 764 765 AcpiDbDisplayResultObject (WalkState->ResultObj,WalkState); 766 #endif 767 768 /* 769 * Delete the result op if and only if: 770 * Parent will not use the result -- such as any 771 * non-nested type2 op in a method (parent will be method) 772 */ 773 AcpiDsDeleteResultIfNotUsed (Op, WalkState->ResultObj, WalkState); 774 } 775 776 #ifdef _UNDER_DEVELOPMENT 777 778 if (WalkState->ParserState.Aml == WalkState->ParserState.AmlEnd) 779 { 780 AcpiDbMethodEnd (WalkState); 781 } 782 #endif 783 784 /* Invoke exception handler on error */ 785 786 if (ACPI_FAILURE (Status)) 787 { 788 Status = AcpiDsMethodError (Status, WalkState); 789 } 790 791 /* Always clear the object stack */ 792 793 WalkState->NumOperands = 0; 794 return_ACPI_STATUS (Status); 795 } 796