1 /*
 2  * Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved.
 3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 4  *
 5  * This code is free software; you can redistribute it and/or modify it
 6  * under the terms of the GNU General Public License version 2 only, as
 7  * published by the Free Software Foundation.  Oracle designates this
 8  * particular file as subject to the "Classpath" exception as provided
 9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 package jdk.incubator.code.extern;
26 
27 import jdk.incubator.code.*;
28 
29 import java.util.List;
30 import java.util.Map;
31 
32 /**
33  * An operation's externalized state (a record) that can be utilized to construct an instance
34  * of an {@link Op} associated with that state, such as the operation's name.
35  *
36  * @param name            the operation name
37  * @param location        the source location associated with the operation, may be null
38  * @param operands        the list of operands
39  * @param successors      the list of successors
40  * @param resultType      the operation result type
41  * @param attributes      the operation's specific state as a map of attributes
42  * @param bodyDefinitions the list of body builders for building the operation's bodies
43  * @apiNote Deserializers of operations may utilize this record to construct operations,
44  * thereby separating the specifics of deserializing from construction.
45  */
46 public record ExternalizedOp(String name,
47                              Op.Location location,
48                              List<Value> operands,
49                              List<Block.Reference> successors,
50                              CodeType resultType,
51                              Map<String, Object> attributes,
52                              List<Body.Builder> bodyDefinitions) {
53 
54     /**
55      * The attribute value that represents the external null value.
56      */
57     public static final Object NULL_ATTRIBUTE_VALUE = new Object();
58 
59     /**
60      * Constructs a new externalized operation
61      * @param name            the operation name
62      * @param location        the source location associated with the operation, may be null
63      * @param operands        the list of operands
64      * @param successors      the list of successors
65      * @param resultType      the operation result type
66      * @param attributes      the operation's specific state as a map of attributes
67      * @param bodyDefinitions the list of body builders for building the operation's bodies
68      */
69     public ExternalizedOp {
70         attributes = Map.copyOf(attributes);
71     }
72 
73     /**
74      * Externalizes an operation's content.
75      * <p>
76      * If the operation is an instanceof {@code ExternalizableOp} then the operation's
77      * specific content is externalized to an attribute map, otherwise the attribute map
78      * is empty.
79      *
80      * @param cc the code context
81      * @param op the operation
82      * @return the operation's content.
83      */
84     public static ExternalizedOp externalizeOp(CodeContext cc, Op op) {
85         return new ExternalizedOp(
86                 op.externalizeOpName(),
87                 op.location(),
88                 cc.getValues(op.operands()),
89                 op.successors().stream().map(cc::getReferenceOrCreate).toList(),
90                 op.resultType(),
91                 op.externalize(),
92                 op.bodies().stream().map(b -> b.transform(cc, CodeTransformer.COPYING_TRANSFORMER)).toList()
93         );
94     }
95 }