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