1 /******************************************************************************
3 * Module Name: asltree - parse tree management
5 *****************************************************************************/
7 /******************************************************************************
11 * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp.
12 * All rights reserved.
16 * 2.1. This is your license from Intel Corp. under its intellectual property
17 * rights. You may have additional license terms from the party that provided
18 * you this software, covering your right to use that party's intellectual
21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22 * copy of the source code appearing in this file ("Covered Code") an
23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24 * base code distributed originally by Intel ("Original Intel Code") to copy,
25 * make derivatives, distribute, use and display any portion of the Covered
26 * Code in any form, with the right to sublicense such rights; and
28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29 * license (with the right to sublicense), under only those claims of Intel
30 * patents that are infringed by the Original Intel Code, to make, use, sell,
31 * offer to sell, and import the Covered Code and derivative works thereof
32 * solely to the minimum extent necessary to exercise the above copyright
33 * license, and in no event shall the patent license extend to any additions
34 * to or modifications of the Original Intel Code. No other license or right
35 * is granted directly or by implication, estoppel or otherwise;
37 * The above copyright and patent license is granted only if the following
42 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43 * Redistribution of source code of any substantial portion of the Covered
44 * Code or modification with rights to further distribute source must include
45 * the above Copyright Notice, the above License, this list of Conditions,
46 * and the following Disclaimer and Export Compliance provision. In addition,
47 * Licensee must cause all Covered Code to which Licensee contributes to
48 * contain a file documenting the changes Licensee made to create that Covered
49 * Code and the date of any change. Licensee must include in that file the
50 * documentation of any changes made by any predecessor Licensee. Licensee
51 * must include a prominent statement that the modification is derived,
52 * directly or indirectly, from Original Intel Code.
54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55 * Redistribution of source code of any substantial portion of the Covered
56 * Code or modification without rights to further distribute source must
57 * include the following Disclaimer and Export Compliance provision in the
58 * documentation and/or other materials provided with distribution. In
59 * addition, Licensee may not authorize further sublicense of source of any
60 * portion of the Covered Code, and must include terms to the effect that the
61 * license from Licensee to its licensee is limited to the intellectual
62 * property embodied in the software Licensee provides to its licensee, and
63 * not to intellectual property embodied in modifications its licensee may
66 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67 * substantial portion of the Covered Code or modification must reproduce the
68 * above Copyright Notice, and the following Disclaimer and Export Compliance
69 * provision in the documentation and/or other materials provided with the
72 * 3.4. Intel retains all right, title, and interest in and to the Original
75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76 * Intel shall be used in advertising or otherwise to promote the sale, use or
77 * other dealings in products derived from or relating to the Covered Code
78 * without prior written authorization from Intel.
80 * 4. Disclaimer and Export Compliance
82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
99 * 4.3. Licensee shall not export, either directly or indirectly, any of this
100 * software or system incorporating such software without first obtaining any
101 * required license or other approval from the U. S. Department of Commerce or
102 * any other agency or department of the United States Government. In the
103 * event Licensee exports any such software from the United States or
104 * re-exports any such software from a foreign destination, Licensee shall
105 * ensure that the distribution and export/re-export of the software is in
106 * compliance with all laws, regulations, orders, or other restrictions of the
107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108 * any of its subsidiaries will export/re-export any technical data, process,
109 * software, or service, directly or indirectly, to any country for which the
110 * United States government or any agency thereof requires an export license,
111 * other governmental approval, or letter of assurance, without first obtaining
112 * such license, approval or letter.
114 *****************************************************************************
116 * Alternatively, you may choose to be licensed under the terms of the
119 * Redistribution and use in source and binary forms, with or without
120 * modification, are permitted provided that the following conditions
122 * 1. Redistributions of source code must retain the above copyright
123 * notice, this list of conditions, and the following disclaimer,
124 * without modification.
125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126 * substantially similar to the "NO WARRANTY" disclaimer below
127 * ("Disclaimer") and any redistribution must be conditioned upon
128 * including a substantially similar Disclaimer requirement for further
129 * binary redistribution.
130 * 3. Neither the names of the above-listed copyright holders nor the names
131 * of any contributors may be used to endorse or promote products derived
132 * from this software without specific prior written permission.
134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
146 * Alternatively, you may choose to be licensed under the terms of the
147 * GNU General Public License ("GPL") version 2 as published by the Free
148 * Software Foundation.
150 *****************************************************************************/
152 #include <contrib/dev/acpica/compiler/aslcompiler.h>
153 #include "aslcompiler.y.h"
154 #include <contrib/dev/acpica/include/acapps.h>
155 #include <contrib/dev/acpica/include/acconvert.h>
158 #define _COMPONENT ACPI_COMPILER
159 ACPI_MODULE_NAME ("asltree")
161 /* Local prototypes */
163 static ACPI_PARSE_OBJECT *
168 /*******************************************************************************
170 * FUNCTION: TrSetParent
172 * PARAMETERS: Op - To be set to new parent
173 * ParentOp - The parent
175 * RETURN: None, sets Op parent directly
177 * DESCRIPTION: Change the parent of a parse op.
179 ******************************************************************************/
183 ACPI_PARSE_OBJECT *Op,
184 ACPI_PARSE_OBJECT *ParentOp)
187 Op->Asl.Parent = ParentOp;
191 /*******************************************************************************
193 * FUNCTION: TrGetNextNode
197 * RETURN: New parse node. Aborts on allocation failure
199 * DESCRIPTION: Allocate a new parse node for the parse tree. Bypass the local
200 * dynamic memory manager for performance reasons (This has a
201 * major impact on the speed of the compiler.)
203 ******************************************************************************/
205 static ACPI_PARSE_OBJECT *
209 ASL_CACHE_INFO *Cache;
212 if (Gbl_ParseOpCacheNext >= Gbl_ParseOpCacheLast)
214 /* Allocate a new buffer */
216 Cache = UtLocalCalloc (sizeof (Cache->Next) +
217 (sizeof (ACPI_PARSE_OBJECT) * ASL_PARSEOP_CACHE_SIZE));
219 /* Link new cache buffer to head of list */
221 Cache->Next = Gbl_ParseOpCacheList;
222 Gbl_ParseOpCacheList = Cache;
224 /* Setup cache management pointers */
226 Gbl_ParseOpCacheNext = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Cache->Buffer);
227 Gbl_ParseOpCacheLast = Gbl_ParseOpCacheNext + ASL_PARSEOP_CACHE_SIZE;
231 return (Gbl_ParseOpCacheNext++);
235 /*******************************************************************************
237 * FUNCTION: TrAllocateNode
239 * PARAMETERS: ParseOpcode - Opcode to be assigned to the node
241 * RETURN: New parse node. Aborts on allocation failure
243 * DESCRIPTION: Allocate and initialize a new parse node for the parse tree
245 ******************************************************************************/
251 ACPI_PARSE_OBJECT *Op;
252 ACPI_PARSE_OBJECT *LatestNode;
255 Op = TrGetNextNode ();
257 Op->Asl.ParseOpcode = (UINT16) ParseOpcode;
258 Op->Asl.Filename = Gbl_Files[ASL_FILE_INPUT].Filename;
259 Op->Asl.LineNumber = Gbl_CurrentLineNumber;
260 Op->Asl.LogicalLineNumber = Gbl_LogicalLineNumber;
261 Op->Asl.LogicalByteOffset = Gbl_CurrentLineOffset;
262 Op->Asl.Column = Gbl_CurrentColumn;
264 UtSetParseOpName (Op);
266 /* The following is for capturing comments */
268 if(Gbl_CaptureComments)
270 LatestNode = Gbl_CommentState.Latest_Parse_Node;
271 Op->Asl.InlineComment = NULL;
272 Op->Asl.EndNodeComment = NULL;
273 Op->Asl.CommentList = NULL;
274 Op->Asl.FileChanged = FALSE;
277 * Check to see if the file name has changed before resetting the
281 (ParseOpcode != PARSEOP_INCLUDE) &&
282 (ParseOpcode != PARSEOP_INCLUDE_END) &&
283 strcmp (LatestNode->Asl.Filename, Op->Asl.Filename))
285 CvDbgPrint ("latest node: %s\n", LatestNode->Asl.ParseOpName);
286 Op->Asl.FileChanged = TRUE;
287 if (Gbl_IncludeFileStack)
289 Op->Asl.ParentFilename = Gbl_IncludeFileStack->Filename;
293 Op->Asl.ParentFilename = NULL;
297 Gbl_CommentState.Latest_Parse_Node = Op;
298 CvDbgPrint ("trallocatenode=Set latest parse node to this node.\n");
299 CvDbgPrint (" Op->Asl.ParseOpName = %s\n",
300 Gbl_CommentState.Latest_Parse_Node->Asl.ParseOpName);
301 CvDbgPrint (" Op->Asl.ParseOpcode = 0x%x\n", ParseOpcode);
303 if (Op->Asl.FileChanged)
305 CvDbgPrint(" file has been changed!\n");
309 * if this parse op's syntax uses () and {} (i.e. Package(1){0x00}) then
310 * set a flag in the comment state. This facilitates paring comments for
311 * these types of opcodes.
313 if ((CvParseOpBlockType(Op) == (BLOCK_PAREN | BLOCK_BRACE)) &&
314 (ParseOpcode != PARSEOP_DEFINITION_BLOCK))
316 CvDbgPrint ("Parsing paren/Brace node now!\n");
317 Gbl_CommentState.ParsingParenBraceNode = Op;
320 if (Gbl_Comment_List_Head)
322 CvDbgPrint ("Transferring...\n");
323 Op->Asl.CommentList = Gbl_Comment_List_Head;
324 Gbl_Comment_List_Head = NULL;
325 Gbl_Comment_List_Tail = NULL;
326 CvDbgPrint (" Transferred current comment list to this node.\n");
327 CvDbgPrint (" %s\n", Op->Asl.CommentList->Comment);
329 if (Gbl_Inline_Comment_Buffer)
331 Op->Asl.InlineComment = Gbl_Inline_Comment_Buffer;
332 Gbl_Inline_Comment_Buffer = NULL;
333 CvDbgPrint ("Transferred current inline comment list to this node.\n");
342 /*******************************************************************************
344 * FUNCTION: TrReleaseNode
346 * PARAMETERS: Op - Op to be released
350 * DESCRIPTION: "release" a node. In truth, nothing is done since the node
351 * is part of a larger buffer
353 ******************************************************************************/
357 ACPI_PARSE_OBJECT *Op)
364 /*******************************************************************************
366 * FUNCTION: TrSetCurrentFilename
368 * PARAMETERS: Op - An existing parse node
372 * DESCRIPTION: Save the include file filename. Used for debug output only.
374 ******************************************************************************/
377 TrSetCurrentFilename (
378 ACPI_PARSE_OBJECT *Op)
380 Op->Asl.Filename = Gbl_PreviousIncludeFilename;
384 /*******************************************************************************
386 * FUNCTION: TrUpdateNode
388 * PARAMETERS: ParseOpcode - New opcode to be assigned to the node
389 * Op - An existing parse node
391 * RETURN: The updated node
393 * DESCRIPTION: Change the parse opcode assigned to a node. Usually used to
394 * change an opcode to DEFAULT_ARG so that the node is ignored
395 * during the code generation. Also used to set generic integers
396 * to a specific size (8, 16, 32, or 64 bits)
398 ******************************************************************************/
403 ACPI_PARSE_OBJECT *Op)
411 DbgPrint (ASL_PARSE_OUTPUT,
412 "\nUpdateNode: Old - %s, New - %s\n",
413 UtGetOpName (Op->Asl.ParseOpcode),
414 UtGetOpName (ParseOpcode));
416 /* Assign new opcode and name */
418 if (Op->Asl.ParseOpcode == PARSEOP_ONES)
422 case PARSEOP_BYTECONST:
424 Op->Asl.Value.Integer = ACPI_UINT8_MAX;
427 case PARSEOP_WORDCONST:
429 Op->Asl.Value.Integer = ACPI_UINT16_MAX;
432 case PARSEOP_DWORDCONST:
434 Op->Asl.Value.Integer = ACPI_UINT32_MAX;
437 /* Don't need to do the QWORD case */
441 /* Don't care about others */
446 Op->Asl.ParseOpcode = (UINT16) ParseOpcode;
447 UtSetParseOpName (Op);
450 * For the BYTE, WORD, and DWORD constants, make sure that the integer
451 * that was passed in will actually fit into the data type
455 case PARSEOP_BYTECONST:
457 UtCheckIntegerRange (Op, 0x00, ACPI_UINT8_MAX);
458 Op->Asl.Value.Integer &= ACPI_UINT8_MAX;
461 case PARSEOP_WORDCONST:
463 UtCheckIntegerRange (Op, 0x00, ACPI_UINT16_MAX);
464 Op->Asl.Value.Integer &= ACPI_UINT16_MAX;
467 case PARSEOP_DWORDCONST:
469 UtCheckIntegerRange (Op, 0x00, ACPI_UINT32_MAX);
470 Op->Asl.Value.Integer &= ACPI_UINT32_MAX;
475 /* Don't care about others, don't need to check QWORD */
480 /* Converter: if this is a method invocation, turn off capture comments. */
481 if (Gbl_CaptureComments &&
482 (ParseOpcode == PARSEOP_METHODCALL))
484 Gbl_CommentState.CaptureComments = FALSE;
491 /*******************************************************************************
493 * FUNCTION: TrPrintNodeCompileFlags
495 * PARAMETERS: Flags - Flags word to be decoded
499 * DESCRIPTION: Decode a flags word to text. Displays all flags that are set.
501 ******************************************************************************/
504 TrPrintNodeCompileFlags (
509 char *FlagName = NULL;
512 for (i = 0; i < 32; i++)
514 switch (Flags & FlagBit)
518 FlagName = "NODE_VISITED";
521 case NODE_AML_PACKAGE:
523 FlagName = "NODE_AML_PACKAGE";
528 FlagName = "NODE_IS_TARGET";
531 case NODE_IS_RESOURCE_DESC:
533 FlagName = "NODE_IS_RESOURCE_DESC";
536 case NODE_IS_RESOURCE_FIELD:
538 FlagName = "NODE_IS_RESOURCE_FIELD";
541 case NODE_HAS_NO_EXIT:
543 FlagName = "NODE_HAS_NO_EXIT";
546 case NODE_IF_HAS_NO_EXIT:
548 FlagName = "NODE_IF_HAS_NO_EXIT";
551 case NODE_NAME_INTERNALIZED:
553 FlagName = "NODE_NAME_INTERNALIZED";
556 case NODE_METHOD_NO_RETVAL:
558 FlagName = "NODE_METHOD_NO_RETVAL";
561 case NODE_METHOD_SOME_NO_RETVAL:
563 FlagName = "NODE_METHOD_SOME_NO_RETVAL";
566 case NODE_RESULT_NOT_USED:
568 FlagName = "NODE_RESULT_NOT_USED";
571 case NODE_METHOD_TYPED:
573 FlagName = "NODE_METHOD_TYPED";
576 case NODE_COULD_NOT_REDUCE:
578 FlagName = "NODE_COULD_NOT_REDUCE";
581 case NODE_COMPILE_TIME_CONST:
583 FlagName = "NODE_COMPILE_TIME_CONST";
586 case NODE_IS_TERM_ARG:
588 FlagName = "NODE_IS_TERM_ARG";
591 case NODE_WAS_ONES_OP:
593 FlagName = "NODE_WAS_ONES_OP";
596 case NODE_IS_NAME_DECLARATION:
598 FlagName = "NODE_IS_NAME_DECLARATION";
601 case NODE_COMPILER_EMITTED:
603 FlagName = "NODE_COMPILER_EMITTED";
606 case NODE_IS_DUPLICATE:
608 FlagName = "NODE_IS_DUPLICATE";
611 case NODE_IS_RESOURCE_DATA:
613 FlagName = "NODE_IS_RESOURCE_DATA";
616 case NODE_IS_NULL_RETURN:
618 FlagName = "NODE_IS_NULL_RETURN";
627 DbgPrint (ASL_PARSE_OUTPUT, " %s", FlagName);
636 /*******************************************************************************
638 * FUNCTION: TrSetNodeFlags
640 * PARAMETERS: Op - An existing parse node
641 * Flags - New flags word
643 * RETURN: The updated parser op
645 * DESCRIPTION: Set bits in the node flags word. Will not clear bits, only set
647 ******************************************************************************/
651 ACPI_PARSE_OBJECT *Op,
660 DbgPrint (ASL_PARSE_OUTPUT,
661 "\nSetNodeFlags: %s Op %p, %8.8X", Op->Asl.ParseOpName, Op, Flags);
663 TrPrintNodeCompileFlags (Flags);
664 DbgPrint (ASL_PARSE_OUTPUT, "\n\n");
666 Op->Asl.CompileFlags |= Flags;
671 /*******************************************************************************
673 * FUNCTION: TrSetNodeAmlLength
675 * PARAMETERS: Op - An existing parse node
676 * Length - AML Length
678 * RETURN: The updated parser op
680 * DESCRIPTION: Set the AML Length in a node. Used by the parser to indicate
681 * the presence of a node that must be reduced to a fixed length
684 ******************************************************************************/
688 ACPI_PARSE_OBJECT *Op,
692 DbgPrint (ASL_PARSE_OUTPUT,
693 "\nSetNodeAmlLength: Op %p, %8.8X\n", Op, Length);
700 Op->Asl.AmlLength = Length;
705 /*******************************************************************************
707 * FUNCTION: TrSetEndLineNumber
709 * PARAMETERS: Op - An existing parse node
713 * DESCRIPTION: Set the ending line numbers (file line and logical line) of a
714 * parse node to the current line numbers.
716 ******************************************************************************/
720 ACPI_PARSE_OBJECT *Op)
723 /* If the end line # is already set, just return */
730 Op->Asl.EndLine = Gbl_CurrentLineNumber;
731 Op->Asl.EndLogicalLine = Gbl_LogicalLineNumber;
735 /*******************************************************************************
737 * FUNCTION: TrCreateAssignmentNode
739 * PARAMETERS: Target - Assignment target
740 * Source - Assignment source
742 * RETURN: Pointer to the new node. Aborts on allocation failure
744 * DESCRIPTION: Implements the C-style '=' operator. It changes the parse
745 * tree if possible to utilize the last argument of the math
746 * operators which is a target operand -- thus saving invocation
747 * of and additional Store() operator. An optimization.
749 ******************************************************************************/
752 TrCreateAssignmentNode (
753 ACPI_PARSE_OBJECT *Target,
754 ACPI_PARSE_OBJECT *Source)
756 ACPI_PARSE_OBJECT *TargetOp;
757 ACPI_PARSE_OBJECT *SourceOp1;
758 ACPI_PARSE_OBJECT *SourceOp2;
759 ACPI_PARSE_OBJECT *Operator;
762 DbgPrint (ASL_PARSE_OUTPUT,
763 "\nTrCreateAssignmentNode Line [%u to %u] Source %s Target %s\n",
764 Source->Asl.LineNumber, Source->Asl.EndLine,
765 UtGetOpName (Source->Asl.ParseOpcode),
766 UtGetOpName (Target->Asl.ParseOpcode));
768 TrSetNodeFlags (Target, NODE_IS_TARGET);
770 switch (Source->Asl.ParseOpcode)
773 * Only these operators can be optimized because they have
781 case PARSEOP_MULTIPLY:
784 case PARSEOP_SHIFTLEFT:
785 case PARSEOP_SHIFTRIGHT:
786 case PARSEOP_SUBTRACT:
791 /* Otherwise, just create a normal Store operator */
799 * Transform the parse tree such that the target is moved to the
800 * last operand of the operator
802 SourceOp1 = Source->Asl.Child;
803 SourceOp2 = SourceOp1->Asl.Next;
805 /* NOT only has one operand, but has a target */
807 if (Source->Asl.ParseOpcode == PARSEOP_NOT)
809 SourceOp2 = SourceOp1;
812 /* DIVIDE has an extra target operand (remainder) */
814 if (Source->Asl.ParseOpcode == PARSEOP_DIVIDE)
816 SourceOp2 = SourceOp2->Asl.Next;
819 TargetOp = SourceOp2->Asl.Next;
822 * Can't perform this optimization if there already is a target
823 * for the operator (ZERO is a "no target" placeholder).
825 if (TargetOp->Asl.ParseOpcode != PARSEOP_ZERO)
830 /* Link in the target as the final operand */
832 SourceOp2->Asl.Next = Target;
833 Target->Asl.Parent = Source;
840 Operator = TrAllocateNode (PARSEOP_STORE);
841 TrLinkChildren (Operator, 2, Source, Target);
843 /* Set the appropriate line numbers for the new node */
845 Operator->Asl.LineNumber = Target->Asl.LineNumber;
846 Operator->Asl.LogicalLineNumber = Target->Asl.LogicalLineNumber;
847 Operator->Asl.LogicalByteOffset = Target->Asl.LogicalByteOffset;
848 Operator->Asl.Column = Target->Asl.Column;
854 /*******************************************************************************
856 * FUNCTION: TrCreateLeafNode
858 * PARAMETERS: ParseOpcode - New opcode to be assigned to the node
860 * RETURN: Pointer to the new node. Aborts on allocation failure
862 * DESCRIPTION: Create a simple leaf node (no children or peers, and no value
863 * assigned to the node)
865 ******************************************************************************/
871 ACPI_PARSE_OBJECT *Op;
874 Op = TrAllocateNode (ParseOpcode);
876 DbgPrint (ASL_PARSE_OUTPUT,
877 "\nCreateLeafNode Ln/Col %u/%u NewNode %p Op %s\n\n",
878 Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName (ParseOpcode));
884 /*******************************************************************************
886 * FUNCTION: TrCreateNullTarget
890 * RETURN: Pointer to the new node. Aborts on allocation failure
892 * DESCRIPTION: Create a "null" target node. This is defined by the ACPI
893 * specification to be a zero AML opcode, and indicates that
894 * no target has been specified for the parent operation
896 ******************************************************************************/
902 ACPI_PARSE_OBJECT *Op;
905 Op = TrAllocateNode (PARSEOP_ZERO);
906 Op->Asl.CompileFlags |= (NODE_IS_TARGET | NODE_COMPILE_TIME_CONST);
908 DbgPrint (ASL_PARSE_OUTPUT,
909 "\nCreateNullTarget Ln/Col %u/%u NewNode %p Op %s\n",
910 Op->Asl.LineNumber, Op->Asl.Column, Op,
911 UtGetOpName (Op->Asl.ParseOpcode));
917 /*******************************************************************************
919 * FUNCTION: TrCreateConstantLeafNode
921 * PARAMETERS: ParseOpcode - The constant opcode
923 * RETURN: Pointer to the new node. Aborts on allocation failure
925 * DESCRIPTION: Create a leaf node (no children or peers) for one of the
926 * special constants - __LINE__, __FILE__, and __DATE__.
928 * Note: An implemenation of __FUNC__ cannot happen here because we don't
929 * have a full parse tree at this time and cannot find the parent control
930 * method. If it is ever needed, __FUNC__ must be implemented later, after
931 * the parse tree has been fully constructed.
933 ******************************************************************************/
936 TrCreateConstantLeafNode (
939 ACPI_PARSE_OBJECT *Op = NULL;
941 char *StaticTimeString;
948 case PARSEOP___LINE__:
950 Op = TrAllocateNode (PARSEOP_INTEGER);
951 Op->Asl.Value.Integer = Op->Asl.LineNumber;
954 case PARSEOP___PATH__:
956 Op = TrAllocateNode (PARSEOP_STRING_LITERAL);
958 /* Op.Asl.Filename contains the full pathname to the file */
960 Op->Asl.Value.String = Op->Asl.Filename;
963 case PARSEOP___FILE__:
965 Op = TrAllocateNode (PARSEOP_STRING_LITERAL);
967 /* Get the simple filename from the full path */
969 FlSplitInputPathname (Op->Asl.Filename, NULL, &Filename);
970 Op->Asl.Value.String = Filename;
973 case PARSEOP___DATE__:
975 Op = TrAllocateNode (PARSEOP_STRING_LITERAL);
977 /* Get a copy of the current time */
979 CurrentTime = time (NULL);
980 StaticTimeString = ctime (&CurrentTime);
981 TimeString = UtLocalCalloc (strlen (StaticTimeString) + 1);
982 strcpy (TimeString, StaticTimeString);
984 TimeString[strlen(TimeString) -1] = 0; /* Remove trailing newline */
985 Op->Asl.Value.String = TimeString;
988 default: /* This would be an internal error */
993 DbgPrint (ASL_PARSE_OUTPUT,
994 "\nCreateConstantLeafNode Ln/Col %u/%u NewNode %p "
995 "Op %s Value %8.8X%8.8X \n",
996 Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName (ParseOpcode),
997 ACPI_FORMAT_UINT64 (Op->Asl.Value.Integer));
1002 /*******************************************************************************
1004 * FUNCTION: TrCreateTargetOperand
1006 * PARAMETERS: OriginalOp - Op to be copied
1008 * RETURN: Pointer to the new node. Aborts on allocation failure
1010 * DESCRIPTION: Copy an existing node (and subtree). Used in ASL+ (C-style)
1011 * expressions where the target is the same as one of the
1012 * operands. A new node and subtree must be created from the
1013 * original so that the parse tree can be linked properly.
1015 * NOTE: This code is specific to target operands that are the last
1016 * operand in an ASL/AML operator. Meaning that the top-level
1017 * parse Op in a possible subtree has a NULL Next pointer.
1018 * This simplifies the recursion.
1021 * DeRefOf (Local1) += 32
1023 * This gets converted to:
1024 * Add (DeRefOf (Local1), 32, DeRefOf (Local1))
1026 * Each DeRefOf has a single child, Local1. Even more complex
1027 * subtrees can be created via the Index and DeRefOf operators.
1029 ******************************************************************************/
1032 TrCreateTargetOperand (
1033 ACPI_PARSE_OBJECT *OriginalOp,
1034 ACPI_PARSE_OBJECT *ParentOp)
1036 ACPI_PARSE_OBJECT *Op;
1044 Op = TrGetNextNode ();
1046 /* Copy the pertinent values (omit link pointer fields) */
1048 Op->Asl.Value = OriginalOp->Asl.Value;
1049 Op->Asl.Filename = OriginalOp->Asl.Filename;
1050 Op->Asl.LineNumber = OriginalOp->Asl.LineNumber;
1051 Op->Asl.LogicalLineNumber = OriginalOp->Asl.LogicalLineNumber;
1052 Op->Asl.LogicalByteOffset = OriginalOp->Asl.LogicalByteOffset;
1053 Op->Asl.Column = OriginalOp->Asl.Column;
1054 Op->Asl.Flags = OriginalOp->Asl.Flags;
1055 Op->Asl.CompileFlags = OriginalOp->Asl.CompileFlags;
1056 Op->Asl.AmlOpcode = OriginalOp->Asl.AmlOpcode;
1057 Op->Asl.ParseOpcode = OriginalOp->Asl.ParseOpcode;
1058 Op->Asl.Parent = ParentOp;
1059 UtSetParseOpName (Op);
1061 /* Copy a possible subtree below this node */
1063 if (OriginalOp->Asl.Child)
1065 Op->Asl.Child = TrCreateTargetOperand (OriginalOp->Asl.Child, Op);
1068 if (OriginalOp->Asl.Next) /* Null for top-level node */
1070 Op->Asl.Next = TrCreateTargetOperand (OriginalOp->Asl.Next, ParentOp);
1077 /*******************************************************************************
1079 * FUNCTION: TrCreateValuedLeafNode
1081 * PARAMETERS: ParseOpcode - New opcode to be assigned to the node
1082 * Value - Value to be assigned to the node
1084 * RETURN: Pointer to the new node. Aborts on allocation failure
1086 * DESCRIPTION: Create a leaf node (no children or peers) with a value
1089 ******************************************************************************/
1092 TrCreateValuedLeafNode (
1096 ACPI_PARSE_OBJECT *Op;
1099 Op = TrAllocateNode (ParseOpcode);
1101 DbgPrint (ASL_PARSE_OUTPUT,
1102 "\nCreateValuedLeafNode Ln/Col %u/%u NewNode %p "
1103 "Op %s Value %8.8X%8.8X ",
1104 Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName(ParseOpcode),
1105 ACPI_FORMAT_UINT64 (Value));
1106 Op->Asl.Value.Integer = Value;
1108 switch (ParseOpcode)
1110 case PARSEOP_STRING_LITERAL:
1112 DbgPrint (ASL_PARSE_OUTPUT, "STRING->%s", Value);
1115 case PARSEOP_NAMESEG:
1117 DbgPrint (ASL_PARSE_OUTPUT, "NAMESEG->%s", Value);
1120 case PARSEOP_NAMESTRING:
1122 DbgPrint (ASL_PARSE_OUTPUT, "NAMESTRING->%s", Value);
1125 case PARSEOP_EISAID:
1127 DbgPrint (ASL_PARSE_OUTPUT, "EISAID->%s", Value);
1130 case PARSEOP_METHOD:
1132 DbgPrint (ASL_PARSE_OUTPUT, "METHOD");
1135 case PARSEOP_INTEGER:
1137 DbgPrint (ASL_PARSE_OUTPUT, "INTEGER->%8.8X%8.8X",
1138 ACPI_FORMAT_UINT64 (Value));
1146 DbgPrint (ASL_PARSE_OUTPUT, "\n\n");
1151 /*******************************************************************************
1153 * FUNCTION: TrCreateNode
1155 * PARAMETERS: ParseOpcode - Opcode to be assigned to the node
1156 * NumChildren - Number of children to follow
1157 * ... - A list of child nodes to link to the new
1158 * node. NumChildren long.
1160 * RETURN: Pointer to the new node. Aborts on allocation failure
1162 * DESCRIPTION: Create a new parse node and link together a list of child
1163 * nodes underneath the new node.
1165 ******************************************************************************/
1173 ACPI_PARSE_OBJECT *Op;
1174 ACPI_PARSE_OBJECT *Child;
1175 ACPI_PARSE_OBJECT *PrevChild;
1181 va_start (ap, NumChildren);
1183 /* Allocate one new node */
1185 Op = TrAllocateNode (ParseOpcode);
1187 DbgPrint (ASL_PARSE_OUTPUT,
1188 "\nCreateNode Ln/Col %u/%u NewParent %p Child %u Op %s ",
1189 Op->Asl.LineNumber, Op->Asl.Column, Op,
1190 NumChildren, UtGetOpName(ParseOpcode));
1192 /* Some extra debug output based on the parse opcode */
1194 switch (ParseOpcode)
1196 case PARSEOP_ASL_CODE:
1198 Gbl_ParseTreeRoot = Op;
1199 Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
1200 DbgPrint (ASL_PARSE_OUTPUT, "ASLCODE (Tree Completed)->");
1203 case PARSEOP_DEFINITION_BLOCK:
1205 DbgPrint (ASL_PARSE_OUTPUT, "DEFINITION_BLOCK (Tree Completed)->");
1208 case PARSEOP_OPERATIONREGION:
1210 DbgPrint (ASL_PARSE_OUTPUT, "OPREGION->");
1215 DbgPrint (ASL_PARSE_OUTPUT, "OR->");
1220 /* Nothing to do for other opcodes */
1225 /* Link the new node to its children */
1229 for (i = 0; i < NumChildren; i++)
1231 /* Get the next child */
1233 Child = va_arg (ap, ACPI_PARSE_OBJECT *);
1234 DbgPrint (ASL_PARSE_OUTPUT, "%p, ", Child);
1237 * If child is NULL, this means that an optional argument
1238 * was omitted. We must create a placeholder with a special
1239 * opcode (DEFAULT_ARG) so that the code generator will know
1240 * that it must emit the correct default for this argument
1244 Child = TrAllocateNode (PARSEOP_DEFAULT_ARG);
1247 /* Link first child to parent */
1252 Op->Asl.Child = Child;
1255 * For the ASL-/ASL+ converter: if the ParseOp is a connection,
1256 * external, offset or accessAs, it means that the comments in the
1257 * FirstChild belongs to their parent due to the parsing order in
1258 * the .y files. To correct this, take the comments in the
1259 * FirstChild place it in the parent. This also means that
1260 * legitimate comments for the child gets put to the parent.
1262 if (Gbl_CaptureComments &&
1263 ((ParseOpcode == PARSEOP_CONNECTION) ||
1264 (ParseOpcode == PARSEOP_EXTERNAL) ||
1265 (ParseOpcode == PARSEOP_OFFSET) ||
1266 (ParseOpcode == PARSEOP_ACCESSAS)))
1268 Op->Asl.CommentList = Child->Asl.CommentList;
1269 Op->Asl.EndBlkComment = Child->Asl.EndBlkComment;
1270 Op->Asl.InlineComment = Child->Asl.InlineComment;
1271 Op->Asl.FileChanged = Child->Asl.FileChanged;
1273 Child->Asl.CommentList = NULL;
1274 Child->Asl.EndBlkComment = NULL;
1275 Child->Asl.InlineComment = NULL;
1276 Child->Asl.FileChanged = FALSE;
1279 * These do not need to be "passed off". They can be copied
1280 * because the code for these opcodes should be printed in the
1283 Op->Asl.Filename = Child->Asl.Filename;
1284 Op->Asl.ParentFilename = Child->Asl.ParentFilename;
1288 /* Point all children to parent */
1290 Child->Asl.Parent = Op;
1292 /* Link children in a peer list */
1296 PrevChild->Asl.Next = Child;
1299 /* Get the comment from last child in the resource template call */
1301 if (Gbl_CaptureComments &&
1302 (Op->Asl.ParseOpcode == PARSEOP_RESOURCETEMPLATE))
1304 CvDbgPrint ("Transferred current comment list to this node.\n");
1305 Op->Asl.CommentList = Child->Asl.CommentList;
1306 Child->Asl.CommentList = NULL;
1307 Op->Asl.InlineComment = Child->Asl.InlineComment;
1308 Child->Asl.InlineComment = NULL;
1312 * This child might be a list, point all nodes in the list
1313 * to the same parent
1315 while (Child->Asl.Next)
1317 Child = Child->Asl.Next;
1318 Child->Asl.Parent = Op;
1325 DbgPrint (ASL_PARSE_OUTPUT, "\n");
1330 /*******************************************************************************
1332 * FUNCTION: TrLinkChildren
1334 * PARAMETERS: Op - An existing parse node
1335 * NumChildren - Number of children to follow
1336 * ... - A list of child nodes to link to the new
1337 * node. NumChildren long.
1339 * RETURN: The updated (linked) node
1341 * DESCRIPTION: Link a group of nodes to an existing parse node
1343 ******************************************************************************/
1347 ACPI_PARSE_OBJECT *Op,
1351 ACPI_PARSE_OBJECT *Child;
1352 ACPI_PARSE_OBJECT *PrevChild;
1358 va_start (ap, NumChildren);
1361 TrSetEndLineNumber (Op);
1363 DbgPrint (ASL_PARSE_OUTPUT,
1364 "\nLinkChildren Line [%u to %u] NewParent %p Child %u Op %s ",
1365 Op->Asl.LineNumber, Op->Asl.EndLine,
1366 Op, NumChildren, UtGetOpName(Op->Asl.ParseOpcode));
1368 switch (Op->Asl.ParseOpcode)
1370 case PARSEOP_ASL_CODE:
1372 Gbl_ParseTreeRoot = Op;
1373 Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
1374 DbgPrint (ASL_PARSE_OUTPUT, "ASLCODE (Tree Completed)->");
1377 case PARSEOP_DEFINITION_BLOCK:
1379 DbgPrint (ASL_PARSE_OUTPUT, "DEFINITION_BLOCK (Tree Completed)->");
1382 case PARSEOP_OPERATIONREGION:
1384 DbgPrint (ASL_PARSE_OUTPUT, "OPREGION->");
1389 DbgPrint (ASL_PARSE_OUTPUT, "OR->");
1394 /* Nothing to do for other opcodes */
1399 /* The following is for capturing comments */
1401 if(Gbl_CaptureComments)
1404 * If there are "regular comments" detected at this point,
1405 * then is an endBlk comment. Categorize it as so and distribute
1406 * all regular comments to this parse node.
1408 if (Gbl_Comment_List_Head)
1410 Op->Asl.EndBlkComment = Gbl_Comment_List_Head;
1411 CvDbgPrint ("EndBlk Comment for %s: %s",
1412 Op->Asl.ParseOpName, Gbl_Comment_List_Head->Comment);
1413 Gbl_Comment_List_Head = NULL;
1414 Gbl_Comment_List_Tail = NULL;
1418 /* Link the new node to it's children */
1422 for (i = 0; i < NumChildren; i++)
1424 Child = va_arg (ap, ACPI_PARSE_OBJECT *);
1426 if ((Child == PrevChild) && (Child != NULL))
1428 AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Child,
1429 "Child node list invalid");
1434 DbgPrint (ASL_PARSE_OUTPUT, "%p, ", Child);
1437 * If child is NULL, this means that an optional argument
1438 * was omitted. We must create a placeholder with a special
1439 * opcode (DEFAULT_ARG) so that the code generator will know
1440 * that it must emit the correct default for this argument
1444 Child = TrAllocateNode (PARSEOP_DEFAULT_ARG);
1447 /* Link first child to parent */
1452 Op->Asl.Child = Child;
1455 /* Point all children to parent */
1457 Child->Asl.Parent = Op;
1459 /* Link children in a peer list */
1463 PrevChild->Asl.Next = Child;
1467 * This child might be a list, point all nodes in the list
1468 * to the same parent
1470 while (Child->Asl.Next)
1472 Child = Child->Asl.Next;
1473 Child->Asl.Parent = Op;
1480 DbgPrint (ASL_PARSE_OUTPUT, "\n\n");
1483 if(Gbl_CaptureComments)
1485 Gbl_CommentState.Latest_Parse_Node = Op;
1486 CvDbgPrint ("trlinkchildren=====Set latest parse node to this node.\n");
1492 /*******************************************************************************
1494 * FUNCTION: TrLinkPeerNode
1496 * PARAMETERS: Op1 - First peer
1499 * RETURN: Op1 or the non-null node.
1501 * DESCRIPTION: Link two nodes as peers. Handles cases where one peer is null.
1503 ******************************************************************************/
1507 ACPI_PARSE_OBJECT *Op1,
1508 ACPI_PARSE_OBJECT *Op2)
1510 ACPI_PARSE_OBJECT *Next;
1513 DbgPrint (ASL_PARSE_OUTPUT,
1514 "\nLinkPeerNode: 1=%p (%s), 2=%p (%s)\n",
1515 Op1, Op1 ? UtGetOpName(Op1->Asl.ParseOpcode) : NULL,
1516 Op2, Op2 ? UtGetOpName(Op2->Asl.ParseOpcode) : NULL);
1519 if ((!Op1) && (!Op2))
1521 DbgPrint (ASL_PARSE_OUTPUT, "\nTwo Null nodes!\n");
1525 /* If one of the nodes is null, just return the non-null node */
1539 DbgPrint (ASL_DEBUG_OUTPUT,
1540 "\n************* Internal error, linking node to itself %p\n",
1542 AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op1,
1543 "Linking node to itself");
1547 Op1->Asl.Parent = Op2->Asl.Parent;
1550 * Op 1 may already have a peer list (such as an IF/ELSE pair),
1551 * so we must walk to the end of the list and attach the new
1555 while (Next->Asl.Next)
1557 Next = Next->Asl.Next;
1560 Next->Asl.Next = Op2;
1565 /*******************************************************************************
1567 * FUNCTION: TrLinkPeerNodes
1569 * PARAMETERS: NumPeers - The number of nodes in the list to follow
1570 * ... - A list of nodes to link together as peers
1572 * RETURN: The first node in the list (head of the peer list)
1574 * DESCRIPTION: Link together an arbitrary number of peer nodes.
1576 ******************************************************************************/
1583 ACPI_PARSE_OBJECT *This;
1584 ACPI_PARSE_OBJECT *Next;
1587 ACPI_PARSE_OBJECT *Start;
1590 DbgPrint (ASL_PARSE_OUTPUT,
1591 "\nLinkPeerNodes: (%u) ", NumPeers);
1593 va_start (ap, NumPeers);
1594 This = va_arg (ap, ACPI_PARSE_OBJECT *);
1600 for (i = 0; i < (NumPeers -1); i++)
1602 DbgPrint (ASL_PARSE_OUTPUT, "%u=%p ", (i+1), This);
1604 while (This->Asl.Next)
1606 This = This->Asl.Next;
1609 /* Get another peer node */
1611 Next = va_arg (ap, ACPI_PARSE_OBJECT *);
1614 Next = TrAllocateNode (PARSEOP_DEFAULT_ARG);
1617 /* link new node to the current node */
1619 This->Asl.Next = Next;
1624 DbgPrint (ASL_PARSE_OUTPUT,"\n");
1629 /*******************************************************************************
1631 * FUNCTION: TrLinkChildNode
1633 * PARAMETERS: Op1 - Parent node
1634 * Op2 - Op to become a child
1636 * RETURN: The parent node
1638 * DESCRIPTION: Link two nodes together as a parent and child
1640 ******************************************************************************/
1644 ACPI_PARSE_OBJECT *Op1,
1645 ACPI_PARSE_OBJECT *Op2)
1647 ACPI_PARSE_OBJECT *Next;
1650 DbgPrint (ASL_PARSE_OUTPUT,
1651 "\nLinkChildNode: Parent=%p (%s), Child=%p (%s)\n",
1652 Op1, Op1 ? UtGetOpName(Op1->Asl.ParseOpcode): NULL,
1653 Op2, Op2 ? UtGetOpName(Op2->Asl.ParseOpcode): NULL);
1656 * Converter: if TrLinkChildNode is called to link a method call,
1657 * turn on capture comments as it signifies that we are done parsing
1660 if (Gbl_CaptureComments && Op1)
1662 if (Op1->Asl.ParseOpcode == PARSEOP_METHODCALL)
1664 Gbl_CommentState.CaptureComments = TRUE;
1666 Gbl_CommentState.Latest_Parse_Node = Op1;
1673 Op1->Asl.Child = Op2;
1675 /* Set the child and all peers of the child to point to the parent */
1680 Next->Asl.Parent = Op1;
1681 Next = Next->Asl.Next;
1688 /*******************************************************************************
1690 * FUNCTION: TrWalkParseTree
1692 * PARAMETERS: Visitation - Type of walk
1693 * DescendingCallback - Called during tree descent
1694 * AscendingCallback - Called during tree ascent
1695 * Context - To be passed to the callbacks
1697 * RETURN: Status from callback(s)
1699 * DESCRIPTION: Walk the entire parse tree.
1701 ******************************************************************************/
1705 ACPI_PARSE_OBJECT *Op,
1707 ASL_WALK_CALLBACK DescendingCallback,
1708 ASL_WALK_CALLBACK AscendingCallback,
1712 BOOLEAN NodePreviouslyVisited;
1713 ACPI_PARSE_OBJECT *StartOp = Op;
1717 if (!Gbl_ParseTreeRoot)
1723 NodePreviouslyVisited = FALSE;
1727 case ASL_WALK_VISIT_DOWNWARD:
1731 if (!NodePreviouslyVisited)
1733 /* Let the callback process the node. */
1735 Status = DescendingCallback (Op, Level, Context);
1736 if (ACPI_SUCCESS (Status))
1738 /* Visit children first, once */
1747 else if (Status != AE_CTRL_DEPTH)
1749 /* Exit immediately on any error */
1755 /* Terminate walk at start op */
1762 /* No more children, visit peers */
1767 NodePreviouslyVisited = FALSE;
1771 /* No children or peers, re-visit parent */
1777 Op = Op->Asl.Parent;
1778 NodePreviouslyVisited = TRUE;
1783 case ASL_WALK_VISIT_UPWARD:
1787 /* Visit leaf node (no children) or parent node on return trip */
1789 if ((!Op->Asl.Child) ||
1790 (NodePreviouslyVisited))
1792 /* Let the callback process the node. */
1794 Status = AscendingCallback (Op, Level, Context);
1795 if (ACPI_FAILURE (Status))
1802 /* Visit children first, once */
1809 /* Terminate walk at start op */
1816 /* No more children, visit peers */
1821 NodePreviouslyVisited = FALSE;
1825 /* No children or peers, re-visit parent */
1831 Op = Op->Asl.Parent;
1832 NodePreviouslyVisited = TRUE;
1837 case ASL_WALK_VISIT_TWICE:
1841 if (NodePreviouslyVisited)
1843 Status = AscendingCallback (Op, Level, Context);
1844 if (ACPI_FAILURE (Status))
1851 /* Let the callback process the node. */
1853 Status = DescendingCallback (Op, Level, Context);
1854 if (ACPI_SUCCESS (Status))
1856 /* Visit children first, once */
1865 else if (Status != AE_CTRL_DEPTH)
1867 /* Exit immediately on any error */
1873 /* Terminate walk at start op */
1880 /* No more children, visit peers */
1885 NodePreviouslyVisited = FALSE;
1889 /* No children or peers, re-visit parent */
1895 Op = Op->Asl.Parent;
1896 NodePreviouslyVisited = TRUE;
1902 /* No other types supported */
1906 /* If we get here, the walk completed with no errors */