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