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