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