Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dsutils.c
Go to the documentation of this file.
1 /*******************************************************************************
2  *
3  * Module Name: dsutils - Dispatcher utilities
4  *
5  ******************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2012, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  * notice, this list of conditions, and the following disclaimer,
16  * without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  * substantially similar to the "NO WARRANTY" disclaimer below
19  * ("Disclaimer") and any redistribution must be conditioned upon
20  * including a substantially similar Disclaimer requirement for further
21  * binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  * of any contributors may be used to endorse or promote products derived
24  * from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 #include <acpi/acpi.h>
45 #include "accommon.h"
46 #include "acparser.h"
47 #include "amlcode.h"
48 #include "acdispat.h"
49 #include "acinterp.h"
50 #include "acnamesp.h"
51 #include "acdebug.h"
52 
53 #define _COMPONENT ACPI_DISPATCHER
54 ACPI_MODULE_NAME("dsutils")
55 
56 /*******************************************************************************
57  *
58  * FUNCTION: acpi_ds_clear_implicit_return
59  *
60  * PARAMETERS: walk_state - Current State
61  *
62  * RETURN: None.
63  *
64  * DESCRIPTION: Clear and remove a reference on an implicit return value. Used
65  * to delete "stale" return values (if enabled, the return value
66  * from every operator is saved at least momentarily, in case the
67  * parent method exits.)
68  *
69  ******************************************************************************/
71 {
72  ACPI_FUNCTION_NAME(ds_clear_implicit_return);
73 
74  /*
75  * Slack must be enabled for this feature
76  */
78  return;
79  }
80 
81  if (walk_state->implicit_return_obj) {
82  /*
83  * Delete any "stale" implicit return. However, in
84  * complex statements, the implicit return value can be
85  * bubbled up several levels.
86  */
88  "Removing reference on stale implicit return obj %p\n",
89  walk_state->implicit_return_obj));
90 
91  acpi_ut_remove_reference(walk_state->implicit_return_obj);
92  walk_state->implicit_return_obj = NULL;
93  }
94 }
95 
96 #ifndef ACPI_NO_METHOD_EXECUTION
97 /*******************************************************************************
98  *
99  * FUNCTION: acpi_ds_do_implicit_return
100  *
101  * PARAMETERS: return_desc - The return value
102  * walk_state - Current State
103  * add_reference - True if a reference should be added to the
104  * return object
105  *
106  * RETURN: TRUE if implicit return enabled, FALSE otherwise
107  *
108  * DESCRIPTION: Implements the optional "implicit return". We save the result
109  * of every ASL operator and control method invocation in case the
110  * parent method exit. Before storing a new return value, we
111  * delete the previous return value.
112  *
113  ******************************************************************************/
114 
115 u8
117  struct acpi_walk_state *walk_state, u8 add_reference)
118 {
119  ACPI_FUNCTION_NAME(ds_do_implicit_return);
120 
121  /*
122  * Slack must be enabled for this feature, and we must
123  * have a valid return object
124  */
125  if ((!acpi_gbl_enable_interpreter_slack) || (!return_desc)) {
126  return (FALSE);
127  }
128 
130  "Result %p will be implicitly returned; Prev=%p\n",
131  return_desc, walk_state->implicit_return_obj));
132 
133  /*
134  * Delete any "stale" implicit return value first. However, in
135  * complex statements, the implicit return value can be
136  * bubbled up several levels, so we don't clear the value if it
137  * is the same as the return_desc.
138  */
139  if (walk_state->implicit_return_obj) {
140  if (walk_state->implicit_return_obj == return_desc) {
141  return (TRUE);
142  }
143  acpi_ds_clear_implicit_return(walk_state);
144  }
145 
146  /* Save the implicit return value, add a reference if requested */
147 
148  walk_state->implicit_return_obj = return_desc;
149  if (add_reference) {
150  acpi_ut_add_reference(return_desc);
151  }
152 
153  return (TRUE);
154 }
155 
156 /*******************************************************************************
157  *
158  * FUNCTION: acpi_ds_is_result_used
159  *
160  * PARAMETERS: op - Current Op
161  * walk_state - Current State
162  *
163  * RETURN: TRUE if result is used, FALSE otherwise
164  *
165  * DESCRIPTION: Check if a result object will be used by the parent
166  *
167  ******************************************************************************/
168 
169 u8
171  struct acpi_walk_state * walk_state)
172 {
173  const struct acpi_opcode_info *parent_info;
174 
175  ACPI_FUNCTION_TRACE_PTR(ds_is_result_used, op);
176 
177  /* Must have both an Op and a Result Object */
178 
179  if (!op) {
180  ACPI_ERROR((AE_INFO, "Null Op"));
182  }
183 
184  /*
185  * We know that this operator is not a
186  * Return() operator (would not come here.) The following code is the
187  * optional support for a so-called "implicit return". Some AML code
188  * assumes that the last value of the method is "implicitly" returned
189  * to the caller. Just save the last result as the return value.
190  * NOTE: this is optional because the ASL language does not actually
191  * support this behavior.
192  */
193  (void)acpi_ds_do_implicit_return(walk_state->result_obj, walk_state,
194  TRUE);
195 
196  /*
197  * Now determine if the parent will use the result
198  *
199  * If there is no parent, or the parent is a scope_op, we are executing
200  * at the method level. An executing method typically has no parent,
201  * since each method is parsed separately. A method invoked externally
202  * via execute_control_method has a scope_op as the parent.
203  */
204  if ((!op->common.parent) ||
205  (op->common.parent->common.aml_opcode == AML_SCOPE_OP)) {
206 
207  /* No parent, the return value cannot possibly be used */
208 
210  "At Method level, result of [%s] not used\n",
212  aml_opcode)));
214  }
215 
216  /* Get info on the parent. The root_op is AML_SCOPE */
217 
218  parent_info =
219  acpi_ps_get_opcode_info(op->common.parent->common.aml_opcode);
220  if (parent_info->class == AML_CLASS_UNKNOWN) {
221  ACPI_ERROR((AE_INFO, "Unknown parent opcode Op=%p", op));
223  }
224 
225  /*
226  * Decide what to do with the result based on the parent. If
227  * the parent opcode will not use the result, delete the object.
228  * Otherwise leave it as is, it will be deleted when it is used
229  * as an operand later.
230  */
231  switch (parent_info->class) {
232  case AML_CLASS_CONTROL:
233 
234  switch (op->common.parent->common.aml_opcode) {
235  case AML_RETURN_OP:
236 
237  /* Never delete the return value associated with a return opcode */
238 
239  goto result_used;
240 
241  case AML_IF_OP:
242  case AML_WHILE_OP:
243 
244  /*
245  * If we are executing the predicate AND this is the predicate op,
246  * we will use the return value
247  */
248  if ((walk_state->control_state->common.state ==
250  && (walk_state->control_state->control.
251  predicate_op == op)) {
252  goto result_used;
253  }
254  break;
255 
256  default:
257  /* Ignore other control opcodes */
258  break;
259  }
260 
261  /* The general control opcode returns no result */
262 
263  goto result_not_used;
264 
265  case AML_CLASS_CREATE:
266 
267  /*
268  * These opcodes allow term_arg(s) as operands and therefore
269  * the operands can be method calls. The result is used.
270  */
271  goto result_used;
272 
274 
275  if ((op->common.parent->common.aml_opcode == AML_REGION_OP) ||
276  (op->common.parent->common.aml_opcode == AML_DATA_REGION_OP)
277  || (op->common.parent->common.aml_opcode == AML_PACKAGE_OP)
278  || (op->common.parent->common.aml_opcode ==
280  || (op->common.parent->common.aml_opcode == AML_BUFFER_OP)
281  || (op->common.parent->common.aml_opcode ==
283  || (op->common.parent->common.aml_opcode ==
285  /*
286  * These opcodes allow term_arg(s) as operands and therefore
287  * the operands can be method calls. The result is used.
288  */
289  goto result_used;
290  }
291 
292  goto result_not_used;
293 
294  default:
295 
296  /*
297  * In all other cases. the parent will actually use the return
298  * object, so keep it.
299  */
300  goto result_used;
301  }
302 
303  result_used:
305  "Result of [%s] used by Parent [%s] Op=%p\n",
306  acpi_ps_get_opcode_name(op->common.aml_opcode),
307  acpi_ps_get_opcode_name(op->common.parent->common.
308  aml_opcode), op));
309 
311 
312  result_not_used:
314  "Result of [%s] not used by Parent [%s] Op=%p\n",
315  acpi_ps_get_opcode_name(op->common.aml_opcode),
316  acpi_ps_get_opcode_name(op->common.parent->common.
317  aml_opcode), op));
318 
320 }
321 
322 /*******************************************************************************
323  *
324  * FUNCTION: acpi_ds_delete_result_if_not_used
325  *
326  * PARAMETERS: op - Current parse Op
327  * result_obj - Result of the operation
328  * walk_state - Current state
329  *
330  * RETURN: Status
331  *
332  * DESCRIPTION: Used after interpretation of an opcode. If there is an internal
333  * result descriptor, check if the parent opcode will actually use
334  * this result. If not, delete the result now so that it will
335  * not become orphaned.
336  *
337  ******************************************************************************/
338 
339 void
341  union acpi_operand_object *result_obj,
342  struct acpi_walk_state *walk_state)
343 {
344  union acpi_operand_object *obj_desc;
346 
347  ACPI_FUNCTION_TRACE_PTR(ds_delete_result_if_not_used, result_obj);
348 
349  if (!op) {
350  ACPI_ERROR((AE_INFO, "Null Op"));
351  return_VOID;
352  }
353 
354  if (!result_obj) {
355  return_VOID;
356  }
357 
358  if (!acpi_ds_is_result_used(op, walk_state)) {
359 
360  /* Must pop the result stack (obj_desc should be equal to result_obj) */
361 
362  status = acpi_ds_result_pop(&obj_desc, walk_state);
363  if (ACPI_SUCCESS(status)) {
364  acpi_ut_remove_reference(result_obj);
365  }
366  }
367 
368  return_VOID;
369 }
370 
371 /*******************************************************************************
372  *
373  * FUNCTION: acpi_ds_resolve_operands
374  *
375  * PARAMETERS: walk_state - Current walk state with operands on stack
376  *
377  * RETURN: Status
378  *
379  * DESCRIPTION: Resolve all operands to their values. Used to prepare
380  * arguments to a control method invocation (a call from one
381  * method to another.)
382  *
383  ******************************************************************************/
384 
386 {
387  u32 i;
389 
390  ACPI_FUNCTION_TRACE_PTR(ds_resolve_operands, walk_state);
391 
392  /*
393  * Attempt to resolve each of the valid operands
394  * Method arguments are passed by reference, not by value. This means
395  * that the actual objects are passed, not copies of the objects.
396  */
397  for (i = 0; i < walk_state->num_operands; i++) {
398  status =
399  acpi_ex_resolve_to_value(&walk_state->operands[i],
400  walk_state);
401  if (ACPI_FAILURE(status)) {
402  break;
403  }
404  }
405 
406  return_ACPI_STATUS(status);
407 }
408 
409 /*******************************************************************************
410  *
411  * FUNCTION: acpi_ds_clear_operands
412  *
413  * PARAMETERS: walk_state - Current walk state with operands on stack
414  *
415  * RETURN: None
416  *
417  * DESCRIPTION: Clear all operands on the current walk state operand stack.
418  *
419  ******************************************************************************/
420 
421 void acpi_ds_clear_operands(struct acpi_walk_state *walk_state)
422 {
423  u32 i;
424 
425  ACPI_FUNCTION_TRACE_PTR(ds_clear_operands, walk_state);
426 
427  /* Remove a reference on each operand on the stack */
428 
429  for (i = 0; i < walk_state->num_operands; i++) {
430  /*
431  * Remove a reference to all operands, including both
432  * "Arguments" and "Targets".
433  */
434  acpi_ut_remove_reference(walk_state->operands[i]);
435  walk_state->operands[i] = NULL;
436  }
437 
438  walk_state->num_operands = 0;
439  return_VOID;
440 }
441 #endif
442 
443 /*******************************************************************************
444  *
445  * FUNCTION: acpi_ds_create_operand
446  *
447  * PARAMETERS: walk_state - Current walk state
448  * arg - Parse object for the argument
449  * arg_index - Which argument (zero based)
450  *
451  * RETURN: Status
452  *
453  * DESCRIPTION: Translate a parse tree object that is an argument to an AML
454  * opcode to the equivalent interpreter object. This may include
455  * looking up a name or entering a new name into the internal
456  * namespace.
457  *
458  ******************************************************************************/
459 
462  union acpi_parse_object *arg, u32 arg_index)
463 {
465  char *name_string;
466  u32 name_length;
467  union acpi_operand_object *obj_desc;
468  union acpi_parse_object *parent_op;
469  u16 opcode;
470  acpi_interpreter_mode interpreter_mode;
471  const struct acpi_opcode_info *op_info;
472 
473  ACPI_FUNCTION_TRACE_PTR(ds_create_operand, arg);
474 
475  /* A valid name must be looked up in the namespace */
476 
477  if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) &&
478  (arg->common.value.string) &&
479  !(arg->common.flags & ACPI_PARSEOP_IN_STACK)) {
480  ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n",
481  arg));
482 
483  /* Get the entire name string from the AML stream */
484 
485  status =
487  arg->common.value.buffer,
488  &name_string, &name_length);
489 
490  if (ACPI_FAILURE(status)) {
491  return_ACPI_STATUS(status);
492  }
493 
494  /* All prefixes have been handled, and the name is in name_string */
495 
496  /*
497  * Special handling for buffer_field declarations. This is a deferred
498  * opcode that unfortunately defines the field name as the last
499  * parameter instead of the first. We get here when we are performing
500  * the deferred execution, so the actual name of the field is already
501  * in the namespace. We don't want to attempt to look it up again
502  * because we may be executing in a different scope than where the
503  * actual opcode exists.
504  */
505  if ((walk_state->deferred_node) &&
506  (walk_state->deferred_node->type == ACPI_TYPE_BUFFER_FIELD)
507  && (arg_index ==
508  (u32) ((walk_state->opcode ==
509  AML_CREATE_FIELD_OP) ? 3 : 2))) {
510  obj_desc =
512  walk_state->deferred_node);
513  status = AE_OK;
514  } else { /* All other opcodes */
515 
516  /*
517  * Differentiate between a namespace "create" operation
518  * versus a "lookup" operation (IMODE_LOAD_PASS2 vs.
519  * IMODE_EXECUTE) in order to support the creation of
520  * namespace objects during the execution of control methods.
521  */
522  parent_op = arg->common.parent;
523  op_info =
524  acpi_ps_get_opcode_info(parent_op->common.
525  aml_opcode);
526  if ((op_info->flags & AML_NSNODE)
527  && (parent_op->common.aml_opcode !=
529  && (parent_op->common.aml_opcode != AML_REGION_OP)
530  && (parent_op->common.aml_opcode !=
532 
533  /* Enter name into namespace if not found */
534 
535  interpreter_mode = ACPI_IMODE_LOAD_PASS2;
536  } else {
537  /* Return a failure if name not found */
538 
539  interpreter_mode = ACPI_IMODE_EXECUTE;
540  }
541 
542  status =
543  acpi_ns_lookup(walk_state->scope_info, name_string,
544  ACPI_TYPE_ANY, interpreter_mode,
546  ACPI_NS_DONT_OPEN_SCOPE, walk_state,
549  &obj_desc));
550  /*
551  * The only case where we pass through (ignore) a NOT_FOUND
552  * error is for the cond_ref_of opcode.
553  */
554  if (status == AE_NOT_FOUND) {
555  if (parent_op->common.aml_opcode ==
557  /*
558  * For the Conditional Reference op, it's OK if
559  * the name is not found; We just need a way to
560  * indicate this to the interpreter, set the
561  * object to the root
562  */
563  obj_desc = ACPI_CAST_PTR(union
566  status = AE_OK;
567  } else {
568  /*
569  * We just plain didn't find it -- which is a
570  * very serious error at this point
571  */
572  status = AE_AML_NAME_NOT_FOUND;
573  }
574  }
575 
576  if (ACPI_FAILURE(status)) {
577  ACPI_ERROR_NAMESPACE(name_string, status);
578  }
579  }
580 
581  /* Free the namestring created above */
582 
583  ACPI_FREE(name_string);
584 
585  /* Check status from the lookup */
586 
587  if (ACPI_FAILURE(status)) {
588  return_ACPI_STATUS(status);
589  }
590 
591  /* Put the resulting object onto the current object stack */
592 
593  status = acpi_ds_obj_stack_push(obj_desc, walk_state);
594  if (ACPI_FAILURE(status)) {
595  return_ACPI_STATUS(status);
596  }
598  (obj_desc, walk_state));
599  } else {
600  /* Check for null name case */
601 
602  if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) &&
603  !(arg->common.flags & ACPI_PARSEOP_IN_STACK)) {
604  /*
605  * If the name is null, this means that this is an
606  * optional result parameter that was not specified
607  * in the original ASL. Create a Zero Constant for a
608  * placeholder. (Store to a constant is a Noop.)
609  */
610  opcode = AML_ZERO_OP; /* Has no arguments! */
611 
613  "Null namepath: Arg=%p\n", arg));
614  } else {
615  opcode = arg->common.aml_opcode;
616  }
617 
618  /* Get the object type of the argument */
619 
620  op_info = acpi_ps_get_opcode_info(opcode);
621  if (op_info->object_type == ACPI_TYPE_INVALID) {
623  }
624 
625  if ((op_info->flags & AML_HAS_RETVAL)
626  || (arg->common.flags & ACPI_PARSEOP_IN_STACK)) {
628  "Argument previously created, already stacked\n"));
629 
631  (walk_state->
632  operands[walk_state->num_operands -
633  1], walk_state));
634 
635  /*
636  * Use value that was already previously returned
637  * by the evaluation of this argument
638  */
639  status = acpi_ds_result_pop(&obj_desc, walk_state);
640  if (ACPI_FAILURE(status)) {
641  /*
642  * Only error is underflow, and this indicates
643  * a missing or null operand!
644  */
645  ACPI_EXCEPTION((AE_INFO, status,
646  "Missing or null operand"));
647  return_ACPI_STATUS(status);
648  }
649  } else {
650  /* Create an ACPI_INTERNAL_OBJECT for the argument */
651 
652  obj_desc =
654  object_type);
655  if (!obj_desc) {
657  }
658 
659  /* Initialize the new object */
660 
661  status =
662  acpi_ds_init_object_from_op(walk_state, arg, opcode,
663  &obj_desc);
664  if (ACPI_FAILURE(status)) {
665  acpi_ut_delete_object_desc(obj_desc);
666  return_ACPI_STATUS(status);
667  }
668  }
669 
670  /* Put the operand object on the object stack */
671 
672  status = acpi_ds_obj_stack_push(obj_desc, walk_state);
673  if (ACPI_FAILURE(status)) {
674  return_ACPI_STATUS(status);
675  }
676 
678  (obj_desc, walk_state));
679  }
680 
682 }
683 
684 /*******************************************************************************
685  *
686  * FUNCTION: acpi_ds_create_operands
687  *
688  * PARAMETERS: walk_state - Current state
689  * first_arg - First argument of a parser argument tree
690  *
691  * RETURN: Status
692  *
693  * DESCRIPTION: Convert an operator's arguments from a parse tree format to
694  * namespace objects and place those argument object on the object
695  * stack in preparation for evaluation by the interpreter.
696  *
697  ******************************************************************************/
698 
701  union acpi_parse_object *first_arg)
702 {
704  union acpi_parse_object *arg;
705  union acpi_parse_object *arguments[ACPI_OBJ_NUM_OPERANDS];
706  u32 arg_count = 0;
707  u32 index = walk_state->num_operands;
708  u32 i;
709 
710  ACPI_FUNCTION_TRACE_PTR(ds_create_operands, first_arg);
711 
712  /* Get all arguments in the list */
713 
714  arg = first_arg;
715  while (arg) {
716  if (index >= ACPI_OBJ_NUM_OPERANDS) {
718  }
719 
720  arguments[index] = arg;
721  walk_state->operands[index] = NULL;
722 
723  /* Move on to next argument, if any */
724 
725  arg = arg->common.next;
726  arg_count++;
727  index++;
728  }
729 
730  index--;
731 
732  /* It is the appropriate order to get objects from the Result stack */
733 
734  for (i = 0; i < arg_count; i++) {
735  arg = arguments[index];
736 
737  /* Force the filling of the operand stack in inverse order */
738 
739  walk_state->operand_index = (u8) index;
740 
741  status = acpi_ds_create_operand(walk_state, arg, index);
742  if (ACPI_FAILURE(status)) {
743  goto cleanup;
744  }
745 
746  index--;
747 
749  "Arg #%u (%p) done, Arg1=%p\n", index, arg,
750  first_arg));
751  }
752 
753  return_ACPI_STATUS(status);
754 
755  cleanup:
756  /*
757  * We must undo everything done above; meaning that we must
758  * pop everything off of the operand stack and delete those
759  * objects
760  */
761  acpi_ds_obj_stack_pop_and_delete(arg_count, walk_state);
762 
763  ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %u", index));
764  return_ACPI_STATUS(status);
765 }
766 
767 /*****************************************************************************
768  *
769  * FUNCTION: acpi_ds_evaluate_name_path
770  *
771  * PARAMETERS: walk_state - Current state of the parse tree walk,
772  * the opcode of current operation should be
773  * AML_INT_NAMEPATH_OP
774  *
775  * RETURN: Status
776  *
777  * DESCRIPTION: Translate the -name_path- parse tree object to the equivalent
778  * interpreter object, convert it to value, if needed, duplicate
779  * it, if needed, and push it onto the current result stack.
780  *
781  ****************************************************************************/
782 
784 {
786  union acpi_parse_object *op = walk_state->op;
787  union acpi_operand_object **operand = &walk_state->operands[0];
788  union acpi_operand_object *new_obj_desc;
789  u8 type;
790 
791  ACPI_FUNCTION_TRACE_PTR(ds_evaluate_name_path, walk_state);
792 
793  if (!op->common.parent) {
794 
795  /* This happens after certain exception processing */
796 
797  goto exit;
798  }
799 
800  if ((op->common.parent->common.aml_opcode == AML_PACKAGE_OP) ||
801  (op->common.parent->common.aml_opcode == AML_VAR_PACKAGE_OP) ||
802  (op->common.parent->common.aml_opcode == AML_REF_OF_OP)) {
803 
804  /* TBD: Should we specify this feature as a bit of op_info->Flags of these opcodes? */
805 
806  goto exit;
807  }
808 
809  status = acpi_ds_create_operand(walk_state, op, 0);
810  if (ACPI_FAILURE(status)) {
811  goto exit;
812  }
813 
814  if (op->common.flags & ACPI_PARSEOP_TARGET) {
815  new_obj_desc = *operand;
816  goto push_result;
817  }
818 
819  type = (*operand)->common.type;
820 
821  status = acpi_ex_resolve_to_value(operand, walk_state);
822  if (ACPI_FAILURE(status)) {
823  goto exit;
824  }
825 
826  if (type == ACPI_TYPE_INTEGER) {
827 
828  /* It was incremented by acpi_ex_resolve_to_value */
829 
830  acpi_ut_remove_reference(*operand);
831 
832  status =
833  acpi_ut_copy_iobject_to_iobject(*operand, &new_obj_desc,
834  walk_state);
835  if (ACPI_FAILURE(status)) {
836  goto exit;
837  }
838  } else {
839  /*
840  * The object either was anew created or is
841  * a Namespace node - don't decrement it.
842  */
843  new_obj_desc = *operand;
844  }
845 
846  /* Cleanup for name-path operand */
847 
848  status = acpi_ds_obj_stack_pop(1, walk_state);
849  if (ACPI_FAILURE(status)) {
850  walk_state->result_obj = new_obj_desc;
851  goto exit;
852  }
853 
854  push_result:
855 
856  walk_state->result_obj = new_obj_desc;
857 
858  status = acpi_ds_result_push(walk_state->result_obj, walk_state);
859  if (ACPI_SUCCESS(status)) {
860 
861  /* Force to take it from stack */
862 
863  op->common.flags |= ACPI_PARSEOP_IN_STACK;
864  }
865 
866  exit:
867 
868  return_ACPI_STATUS(status);
869 }