Mercurial > hg > truffle
comparison graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationData.java @ 10597:79041ab43660
Truffle-DSL: API-change: Renamed truffle.api.codegen to truffle.api.dsl for all projects and packages.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Mon, 01 Jul 2013 20:58:32 +0200 |
parents | |
children | b8fe1fe004ec |
comparison
equal
deleted
inserted
replaced
10596:f43eb2f1bbbc | 10597:79041ab43660 |
---|---|
1 /* | |
2 * Copyright (c) 2012, 2012, 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. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
20 * or visit www.oracle.com if you need additional information or have any | |
21 * questions. | |
22 */ | |
23 package com.oracle.truffle.dsl.processor.node; | |
24 | |
25 import java.util.*; | |
26 | |
27 import javax.lang.model.type.*; | |
28 | |
29 import com.oracle.truffle.api.dsl.*; | |
30 import com.oracle.truffle.dsl.processor.*; | |
31 import com.oracle.truffle.dsl.processor.template.*; | |
32 import com.oracle.truffle.dsl.processor.typesystem.*; | |
33 | |
34 public class SpecializationData extends TemplateMethod { | |
35 | |
36 private final int order; | |
37 private final boolean generic; | |
38 private final boolean polymorphic; | |
39 private final boolean uninitialized; | |
40 private final List<SpecializationThrowsData> exceptions; | |
41 private List<String> guardDefinitions = Collections.emptyList(); | |
42 private List<GuardData> guards = Collections.emptyList(); | |
43 private List<ShortCircuitData> shortCircuits; | |
44 private List<String> assumptions = Collections.emptyList(); | |
45 private NodeData node; | |
46 private boolean reachable; | |
47 | |
48 public SpecializationData(TemplateMethod template, int order, List<SpecializationThrowsData> exceptions) { | |
49 super(template); | |
50 this.order = order; | |
51 this.generic = false; | |
52 this.uninitialized = false; | |
53 this.polymorphic = false; | |
54 this.exceptions = exceptions; | |
55 | |
56 for (SpecializationThrowsData exception : exceptions) { | |
57 exception.setSpecialization(this); | |
58 } | |
59 } | |
60 | |
61 public SpecializationData(TemplateMethod template, boolean generic, boolean uninitialized, boolean polymorphic) { | |
62 super(template); | |
63 this.order = Specialization.DEFAULT_ORDER; | |
64 this.generic = generic; | |
65 this.uninitialized = uninitialized; | |
66 this.polymorphic = polymorphic; | |
67 this.exceptions = Collections.emptyList(); | |
68 } | |
69 | |
70 public void setReachable(boolean reachable) { | |
71 this.reachable = reachable; | |
72 } | |
73 | |
74 public boolean isReachable() { | |
75 return reachable; | |
76 } | |
77 | |
78 public boolean isPolymorphic() { | |
79 return polymorphic; | |
80 } | |
81 | |
82 @Override | |
83 protected List<MessageContainer> findChildContainers() { | |
84 List<MessageContainer> sinks = new ArrayList<>(); | |
85 if (exceptions != null) { | |
86 sinks.addAll(exceptions); | |
87 } | |
88 if (guards != null) { | |
89 sinks.addAll(guards); | |
90 } | |
91 return sinks; | |
92 } | |
93 | |
94 public boolean isGenericSpecialization(ProcessorContext context) { | |
95 if (isGeneric()) { | |
96 return true; | |
97 } | |
98 if (hasRewrite(context)) { | |
99 return false; | |
100 } | |
101 | |
102 for (ActualParameter parameter : getParameters()) { | |
103 if (!parameter.getSpecification().isSignature()) { | |
104 continue; | |
105 } | |
106 NodeChildData child = getNode().findChild(parameter.getSpecification().getName()); | |
107 if (child == null) { | |
108 continue; | |
109 } | |
110 if (!parameter.getTypeSystemType().isGeneric()) { | |
111 return false; | |
112 } | |
113 } | |
114 | |
115 return true; | |
116 } | |
117 | |
118 public boolean hasRewrite(ProcessorContext context) { | |
119 if (!getExceptions().isEmpty()) { | |
120 return true; | |
121 } | |
122 if (!getGuards().isEmpty()) { | |
123 return true; | |
124 } | |
125 if (!getAssumptions().isEmpty()) { | |
126 return true; | |
127 } | |
128 for (ActualParameter parameter : getParameters()) { | |
129 NodeChildData child = getNode().findChild(parameter.getSpecification().getName()); | |
130 if (child == null) { | |
131 continue; | |
132 } | |
133 ExecutableTypeData type = child.findExecutableType(context, parameter.getTypeSystemType()); | |
134 if (type.hasUnexpectedValue(context)) { | |
135 return true; | |
136 } | |
137 if (type.getReturnType().getTypeSystemType().needsCastTo(context, parameter.getTypeSystemType())) { | |
138 return true; | |
139 } | |
140 | |
141 } | |
142 return false; | |
143 } | |
144 | |
145 @Override | |
146 public int compareBySignature(TemplateMethod other) { | |
147 if (this == other) { | |
148 return 0; | |
149 } else if (!(other instanceof SpecializationData)) { | |
150 return super.compareBySignature(other); | |
151 } | |
152 | |
153 SpecializationData m2 = (SpecializationData) other; | |
154 | |
155 if (getOrder() != Specialization.DEFAULT_ORDER && m2.getOrder() != Specialization.DEFAULT_ORDER) { | |
156 return getOrder() - m2.getOrder(); | |
157 } else if (isUninitialized() ^ m2.isUninitialized()) { | |
158 return isUninitialized() ? -1 : 1; | |
159 } else if (isGeneric() ^ m2.isGeneric()) { | |
160 return isGeneric() ? 1 : -1; | |
161 } | |
162 | |
163 if (getTemplate() != m2.getTemplate()) { | |
164 throw new UnsupportedOperationException("Cannot compare two specializations with different templates."); | |
165 } | |
166 | |
167 return super.compareBySignature(m2); | |
168 } | |
169 | |
170 public NodeData getNode() { | |
171 return node; | |
172 } | |
173 | |
174 public void setNode(NodeData node) { | |
175 this.node = node; | |
176 } | |
177 | |
178 public void setGuards(List<GuardData> guards) { | |
179 this.guards = guards; | |
180 } | |
181 | |
182 public void setGuardDefinitions(List<String> guardDefinitions) { | |
183 this.guardDefinitions = guardDefinitions; | |
184 } | |
185 | |
186 public int getOrder() { | |
187 return order; | |
188 } | |
189 | |
190 public boolean isGeneric() { | |
191 return generic; | |
192 } | |
193 | |
194 public boolean isUninitialized() { | |
195 return uninitialized; | |
196 } | |
197 | |
198 public List<SpecializationThrowsData> getExceptions() { | |
199 return exceptions; | |
200 } | |
201 | |
202 public List<String> getGuardDefinitions() { | |
203 return guardDefinitions; | |
204 } | |
205 | |
206 public List<GuardData> getGuards() { | |
207 return guards; | |
208 } | |
209 | |
210 public void setShortCircuits(List<ShortCircuitData> shortCircuits) { | |
211 this.shortCircuits = shortCircuits; | |
212 } | |
213 | |
214 public List<ShortCircuitData> getShortCircuits() { | |
215 return shortCircuits; | |
216 } | |
217 | |
218 public List<String> getAssumptions() { | |
219 return assumptions; | |
220 } | |
221 | |
222 void setAssumptions(List<String> assumptions) { | |
223 this.assumptions = assumptions; | |
224 } | |
225 | |
226 public SpecializationData findNextSpecialization() { | |
227 List<SpecializationData> specializations = node.getSpecializations(); | |
228 for (int i = 0; i < specializations.size() - 1; i++) { | |
229 if (specializations.get(i) == this) { | |
230 return specializations.get(i + 1); | |
231 } | |
232 } | |
233 return null; | |
234 } | |
235 | |
236 public boolean hasDynamicGuards() { | |
237 return !getGuards().isEmpty(); | |
238 } | |
239 | |
240 @Override | |
241 public String toString() { | |
242 return String.format("%s [id = %s, method = %s, guards = %s, signature = %s]", getClass().getSimpleName(), getId(), getMethod(), getGuards(), getSignature()); | |
243 } | |
244 | |
245 public void forceFrame(TypeMirror frameType) { | |
246 if (getParameters().isEmpty() || !Utils.typeEquals(getParameters().get(0).getType(), frameType)) { | |
247 ParameterSpec frameSpec = getSpecification().findParameterSpec("frame"); | |
248 getParameters().add(0, new ActualParameter(frameSpec, frameType, -1, false)); | |
249 } | |
250 } | |
251 } |