Mercurial > hg > graal-jvmci-8
comparison graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeBaseFactory.java @ 18753:f6b8787dc113
Truffle-DSL: replace complex factory system with a much simpler version
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Mon, 29 Dec 2014 23:38:21 +0100 |
parents | 1acaa69ff61b |
children | 59bf50cc5a32 |
comparison
equal
deleted
inserted
replaced
18752:1acaa69ff61b | 18753:f6b8787dc113 |
---|---|
40 import com.oracle.truffle.dsl.processor.model.*; | 40 import com.oracle.truffle.dsl.processor.model.*; |
41 import com.oracle.truffle.dsl.processor.model.NodeChildData.Cardinality; | 41 import com.oracle.truffle.dsl.processor.model.NodeChildData.Cardinality; |
42 import com.oracle.truffle.dsl.processor.parser.*; | 42 import com.oracle.truffle.dsl.processor.parser.*; |
43 import com.oracle.truffle.dsl.processor.parser.SpecializationGroup.TypeGuard; | 43 import com.oracle.truffle.dsl.processor.parser.SpecializationGroup.TypeGuard; |
44 | 44 |
45 class NodeBaseFactory extends AbstractClassElementFactory<SpecializationData> { | 45 class NodeBaseFactory { |
46 | 46 |
47 private static final String THIS_NODE_LOCAL_VAR_NAME = "thisNode"; | 47 private static final String THIS_NODE_LOCAL_VAR_NAME = "thisNode"; |
48 | 48 |
49 static final String EXECUTE_CHAINED = "executeChained0"; | 49 static final String EXECUTE_CHAINED = "executeChained0"; |
50 private static final String SPECIALIZE = "specialize0"; | 50 private static final String SPECIALIZE = "specialize0"; |
58 | 58 |
59 static final String EMPTY_CLASS_ARRAY = "EMPTY_CLASS_ARRAY"; | 59 static final String EMPTY_CLASS_ARRAY = "EMPTY_CLASS_ARRAY"; |
60 | 60 |
61 static final String METADATA_FIELD_NAME = "METADATA"; | 61 static final String METADATA_FIELD_NAME = "METADATA"; |
62 | 62 |
63 protected final ProcessorContext context; | |
64 protected final NodeData node; | |
65 protected final SpecializationData specialization; | |
66 | |
67 public NodeBaseFactory(ProcessorContext context, NodeData node, SpecializationData specialization) { | |
68 this.context = context; | |
69 this.node = node; | |
70 this.specialization = specialization; | |
71 } | |
72 | |
73 public CodeTypeElement create() { | |
74 CodeTypeElement clazz = GeneratorUtils.createClass(node, modifiers(PRIVATE, ABSTRACT, STATIC), baseClassName(node), node.getNodeType(), false); | |
75 clazz.getImplements().add(context.getTruffleTypes().getDslNode()); | |
76 | |
77 for (NodeChildData child : node.getChildren()) { | |
78 clazz.add(createChildField(child)); | |
79 | |
80 if (child.getAccessElement() != null && child.getAccessElement().getModifiers().contains(Modifier.ABSTRACT)) { | |
81 ExecutableElement getter = (ExecutableElement) child.getAccessElement(); | |
82 CodeExecutableElement method = CodeExecutableElement.clone(context.getEnvironment(), getter); | |
83 method.getModifiers().remove(Modifier.ABSTRACT); | |
84 CodeTreeBuilder builder = method.createBuilder(); | |
85 builder.startReturn().string("this.").string(child.getName()).end(); | |
86 clazz.add(method); | |
87 } | |
88 } | |
89 | |
90 for (NodeFieldData field : node.getFields()) { | |
91 if (!field.isGenerated()) { | |
92 continue; | |
93 } | |
94 | |
95 clazz.add(new CodeVariableElement(modifiers(PROTECTED, FINAL), field.getType(), field.getName())); | |
96 if (field.getGetter() != null && field.getGetter().getModifiers().contains(Modifier.ABSTRACT)) { | |
97 CodeExecutableElement method = CodeExecutableElement.clone(context.getEnvironment(), field.getGetter()); | |
98 method.getModifiers().remove(Modifier.ABSTRACT); | |
99 method.createBuilder().startReturn().string("this.").string(field.getName()).end(); | |
100 clazz.add(method); | |
101 } | |
102 } | |
103 | |
104 for (String assumption : node.getAssumptions()) { | |
105 clazz.add(createAssumptionField(assumption)); | |
106 } | |
107 | |
108 createConstructors(clazz); | |
109 | |
110 SpecializationGroup rootGroup = createSpecializationGroups(node); | |
111 | |
112 if (node.needsRewrites(context)) { | |
113 if (node.isPolymorphic(context)) { | |
114 | |
115 CodeVariableElement var = new CodeVariableElement(modifiers(PROTECTED), clazz.asType(), "next0"); | |
116 var.getAnnotationMirrors().add(new CodeAnnotationMirror(context.getTruffleTypes().getChildAnnotation())); | |
117 clazz.add(var); | |
118 | |
119 CodeExecutableElement genericCachedExecute = createCachedExecute(node.getPolymorphicSpecialization()); | |
120 clazz.add(genericCachedExecute); | |
121 | |
122 } | |
123 | |
124 for (CodeExecutableElement method : createImplicitChildrenAccessors()) { | |
125 clazz.add(method); | |
126 } | |
127 clazz.add(createInfoMessage()); | |
128 clazz.add(createMonomorphicRewrite()); | |
129 clazz.add(createCreateSpecializationMethod(rootGroup)); | |
130 } | |
131 | |
132 clazz.add(createAdoptChildren0()); | |
133 clazz.add(createGetMetadata0(true)); | |
134 clazz.add(createUpdateTypes0()); | |
135 clazz.add(createGetNext()); | |
136 | |
137 return clazz; | |
138 } | |
139 | |
63 public static List<ExecutableElement> findUserConstructors(TypeMirror nodeType) { | 140 public static List<ExecutableElement> findUserConstructors(TypeMirror nodeType) { |
64 List<ExecutableElement> constructors = new ArrayList<>(); | 141 List<ExecutableElement> constructors = new ArrayList<>(); |
65 for (ExecutableElement constructor : ElementFilter.constructorsIn(ElementUtils.fromTypeMirror(nodeType).getEnclosedElements())) { | 142 for (ExecutableElement constructor : ElementFilter.constructorsIn(ElementUtils.fromTypeMirror(nodeType).getEnclosedElements())) { |
66 if (constructor.getModifiers().contains(PRIVATE)) { | 143 if (constructor.getModifiers().contains(PRIVATE)) { |
67 continue; | 144 continue; |
100 } | 177 } |
101 } | 178 } |
102 return false; | 179 return false; |
103 } | 180 } |
104 | 181 |
105 @Override | 182 public SpecializationData getSpecialization() { |
106 protected CodeTypeElement create(SpecializationData specialization) { | 183 return specialization; |
107 NodeData node = specialization.getNode(); | |
108 CodeTypeElement clazz = createClass(node, modifiers(PRIVATE, ABSTRACT, STATIC), baseClassName(node), node.getNodeType(), false); | |
109 clazz.getImplements().add(context.getTruffleTypes().getDslNode()); | |
110 | |
111 for (NodeChildData child : node.getChildren()) { | |
112 clazz.add(createChildField(child)); | |
113 | |
114 if (child.getAccessElement() != null && child.getAccessElement().getModifiers().contains(Modifier.ABSTRACT)) { | |
115 ExecutableElement getter = (ExecutableElement) child.getAccessElement(); | |
116 CodeExecutableElement method = CodeExecutableElement.clone(getContext().getEnvironment(), getter); | |
117 method.getModifiers().remove(Modifier.ABSTRACT); | |
118 CodeTreeBuilder builder = method.createBuilder(); | |
119 builder.startReturn().string("this.").string(child.getName()).end(); | |
120 clazz.add(method); | |
121 } | |
122 } | |
123 | |
124 for (NodeFieldData field : node.getFields()) { | |
125 if (!field.isGenerated()) { | |
126 continue; | |
127 } | |
128 | |
129 clazz.add(new CodeVariableElement(modifiers(PROTECTED, FINAL), field.getType(), field.getName())); | |
130 if (field.getGetter() != null && field.getGetter().getModifiers().contains(Modifier.ABSTRACT)) { | |
131 CodeExecutableElement method = CodeExecutableElement.clone(getContext().getEnvironment(), field.getGetter()); | |
132 method.getModifiers().remove(Modifier.ABSTRACT); | |
133 method.createBuilder().startReturn().string("this.").string(field.getName()).end(); | |
134 clazz.add(method); | |
135 } | |
136 } | |
137 | |
138 for (String assumption : node.getAssumptions()) { | |
139 clazz.add(createAssumptionField(assumption)); | |
140 } | |
141 | |
142 createConstructors(node, clazz); | |
143 | |
144 return clazz; | |
145 } | |
146 | |
147 @Override | |
148 protected void createChildren(SpecializationData specialization) { | |
149 NodeData node = specialization.getNode(); | |
150 CodeTypeElement clazz = getElement(); | |
151 | |
152 SpecializationGroup rootGroup = createSpecializationGroups(node); | |
153 | |
154 if (node.needsRewrites(context)) { | |
155 if (node.isPolymorphic(context)) { | |
156 | |
157 CodeVariableElement var = new CodeVariableElement(modifiers(PROTECTED), clazz.asType(), "next0"); | |
158 var.getAnnotationMirrors().add(new CodeAnnotationMirror(getContext().getTruffleTypes().getChildAnnotation())); | |
159 clazz.add(var); | |
160 | |
161 CodeExecutableElement genericCachedExecute = createCachedExecute(node, node.getPolymorphicSpecialization()); | |
162 clazz.add(genericCachedExecute); | |
163 | |
164 } | |
165 | |
166 for (CodeExecutableElement method : createImplicitChildrenAccessors()) { | |
167 clazz.add(method); | |
168 } | |
169 clazz.add(createInfoMessage(node)); | |
170 clazz.add(createMonomorphicRewrite()); | |
171 clazz.add(createCreateSpecializationMethod(node, rootGroup)); | |
172 } | |
173 | |
174 clazz.add(createAdoptChildren0()); | |
175 clazz.add(createGetMetadata0(true)); | |
176 clazz.add(createUpdateTypes0()); | |
177 clazz.add(createGetNext()); | |
178 } | 184 } |
179 | 185 |
180 private Element createGetNext() { | 186 private Element createGetNext() { |
181 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, FINAL), context.getType(Node.class), "getNext0"); | 187 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, FINAL), context.getType(Node.class), "getNext0"); |
182 CodeTreeBuilder builder = method.createBuilder(); | 188 CodeTreeBuilder builder = method.createBuilder(); |
183 NodeData node = getModel().getNode(); | |
184 | 189 |
185 if (node.isPolymorphic(context)) { | 190 if (node.isPolymorphic(context)) { |
186 builder.startReturn().string("next0").end(); | 191 builder.startReturn().string("next0").end(); |
187 } else { | 192 } else { |
188 builder.returnNull(); | 193 builder.returnNull(); |
194 protected final CodeExecutableElement createUpdateTypes0() { | 199 protected final CodeExecutableElement createUpdateTypes0() { |
195 ArrayType classArray = new ArrayCodeTypeMirror(context.getType(Class.class)); | 200 ArrayType classArray = new ArrayCodeTypeMirror(context.getType(Class.class)); |
196 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), context.getType(void.class), "updateTypes0"); | 201 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), context.getType(void.class), "updateTypes0"); |
197 method.getParameters().add(new CodeVariableElement(classArray, "types")); | 202 method.getParameters().add(new CodeVariableElement(classArray, "types")); |
198 | 203 |
199 if (getModel().isPolymorphic()) { | 204 if (getSpecialization().isPolymorphic()) { |
200 CodeTreeBuilder builder = method.createBuilder(); | 205 CodeTreeBuilder builder = method.createBuilder(); |
201 | 206 |
202 int index = 0; | 207 int index = 0; |
203 for (NodeExecutionData execution : getModel().getNode().getChildExecutions()) { | 208 for (NodeExecutionData execution : getSpecialization().getNode().getChildExecutions()) { |
204 String fieldName = polymorphicTypeName(execution); | 209 String fieldName = polymorphicTypeName(execution); |
205 | 210 |
206 builder.startStatement(); | 211 builder.startStatement(); |
207 builder.string(fieldName).string(" = ").string("types[").string(String.valueOf(index)).string("]"); | 212 builder.string(fieldName).string(" = ").string("types[").string(String.valueOf(index)).string("]"); |
208 builder.end(); | 213 builder.end(); |
225 | 230 |
226 private CodeExecutableElement createAdoptChildren0() { | 231 private CodeExecutableElement createAdoptChildren0() { |
227 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, FINAL), context.getType(void.class), "adoptChildren0"); | 232 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, FINAL), context.getType(void.class), "adoptChildren0"); |
228 method.getParameters().add(new CodeVariableElement(context.getTruffleTypes().getNode(), "other")); | 233 method.getParameters().add(new CodeVariableElement(context.getTruffleTypes().getNode(), "other")); |
229 method.getParameters().add(new CodeVariableElement(context.getTruffleTypes().getNode(), "newNext")); | 234 method.getParameters().add(new CodeVariableElement(context.getTruffleTypes().getNode(), "newNext")); |
230 NodeData node = getModel().getNode(); | |
231 CodeTreeBuilder builder = method.createBuilder(); | 235 CodeTreeBuilder builder = method.createBuilder(); |
232 List<NodeExecutionData> executions = node.getChildExecutions(); | 236 List<NodeExecutionData> executions = node.getChildExecutions(); |
233 | 237 |
234 if (executions.size() > 0) { | 238 if (executions.size() > 0) { |
235 builder.startIf().string("other == null").end().startBlock(); | 239 builder.startIf().string("other == null").end().startBlock(); |
251 } | 255 } |
252 | 256 |
253 builder.end(); | 257 builder.end(); |
254 } | 258 } |
255 | 259 |
256 if (getModel().getNode().isPolymorphic(context)) { | 260 if (getSpecialization().getNode().isPolymorphic(context)) { |
257 builder.startIf().string("newNext == null").end().startBlock(); | 261 builder.startIf().string("newNext == null").end().startBlock(); |
258 builder.statement("this.next0 = null"); | 262 builder.statement("this.next0 = null"); |
259 builder.end().startElseBlock(); | 263 builder.end().startElseBlock(); |
260 builder.statement("this.next0 = (" + baseClassName(getModel().getNode()) + ") newNext"); | 264 builder.statement("this.next0 = (" + baseClassName(getSpecialization().getNode()) + ") newNext"); |
261 builder.end(); | 265 builder.end(); |
262 } | 266 } |
263 | 267 |
264 return method; | 268 return method; |
265 } | 269 } |
266 | 270 |
267 private List<CodeExecutableElement> createImplicitChildrenAccessors() { | 271 private List<CodeExecutableElement> createImplicitChildrenAccessors() { |
268 NodeData node = getModel().getNode(); | |
269 List<Set<TypeData>> prototype = Collections.nCopies(node.getGenericSpecialization().getParameters().size(), null); | 272 List<Set<TypeData>> prototype = Collections.nCopies(node.getGenericSpecialization().getParameters().size(), null); |
270 List<Set<TypeData>> expectTypes = new ArrayList<>(prototype); | 273 List<Set<TypeData>> expectTypes = new ArrayList<>(prototype); |
271 | 274 |
272 for (ExecutableTypeData executableType : node.getExecutableTypes()) { | 275 for (ExecutableTypeData executableType : node.getExecutableTypes()) { |
273 for (int i = 0; i < executableType.getEvaluatedCount(); i++) { | 276 for (int i = 0; i < executableType.getEvaluatedCount(); i++) { |
315 return methods; | 318 return methods; |
316 } | 319 } |
317 | 320 |
318 private CodeTree truffleBooleanOption(CodeTreeBuilder parent, String name) { | 321 private CodeTree truffleBooleanOption(CodeTreeBuilder parent, String name) { |
319 CodeTreeBuilder builder = parent.create(); | 322 CodeTreeBuilder builder = parent.create(); |
320 builder.staticReference(getContext().getTruffleTypes().getTruffleOptions(), name); | 323 builder.staticReference(context.getTruffleTypes().getTruffleOptions(), name); |
321 return builder.getRoot(); | 324 return builder.getRoot(); |
322 } | 325 } |
323 | 326 |
324 private final void addInternalValueParameters(CodeExecutableElement method, TemplateMethod specialization, boolean forceFrame, boolean disableFrame, boolean evaluated) { | 327 private final void addInternalValueParameters(CodeExecutableElement executableMethod, TemplateMethod method, boolean forceFrame, boolean disableFrame, boolean evaluated) { |
325 if (forceFrame && !disableFrame && specialization.getSpecification().findParameterSpec("frame") != null) { | 328 if (forceFrame && !disableFrame && method.getSpecification().findParameterSpec("frame") != null) { |
326 method.addParameter(new CodeVariableElement(getContext().getTruffleTypes().getFrame(), "frameValue")); | 329 executableMethod.addParameter(new CodeVariableElement(context.getTruffleTypes().getFrame(), "frameValue")); |
327 } | 330 } |
328 for (Parameter parameter : specialization.getParameters()) { | 331 for (Parameter parameter : method.getParameters()) { |
329 ParameterSpec spec = parameter.getSpecification(); | 332 ParameterSpec spec = parameter.getSpecification(); |
330 if ((disableFrame || forceFrame) && spec.getName().equals("frame")) { | 333 if ((disableFrame || forceFrame) && spec.getName().equals("frame")) { |
331 continue; | 334 continue; |
332 } | 335 } |
333 if (spec.isLocal()) { | 336 if (spec.isLocal()) { |
337 String name = valueName(parameter); | 340 String name = valueName(parameter); |
338 if (evaluated && spec.isSignature()) { | 341 if (evaluated && spec.isSignature()) { |
339 name = valueNameEvaluated(parameter); | 342 name = valueNameEvaluated(parameter); |
340 } | 343 } |
341 | 344 |
342 method.addParameter(new CodeVariableElement(parameter.getType(), name)); | 345 executableMethod.addParameter(new CodeVariableElement(parameter.getType(), name)); |
343 } | 346 } |
344 } | 347 } |
345 | 348 |
346 private Element createInfoMessage(NodeData node) { | 349 private Element createInfoMessage() { |
347 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, STATIC), getContext().getType(String.class), CREATE_INFO); | 350 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, STATIC), context.getType(String.class), CREATE_INFO); |
348 method.addParameter(new CodeVariableElement(getContext().getType(String.class), "message")); | 351 method.addParameter(new CodeVariableElement(context.getType(String.class), "message")); |
349 addInternalValueParameters(method, node.getGenericSpecialization(), false, false, false); | 352 addInternalValueParameters(method, node.getGenericSpecialization(), false, false, false); |
350 | 353 |
351 CodeTreeBuilder builder = method.createBuilder(); | 354 CodeTreeBuilder builder = method.createBuilder(); |
352 | 355 |
353 builder.startIf().tree(truffleBooleanOption(builder, TruffleTypes.OPTION_DETAILED_REWRITE_REASONS)).end(); | 356 builder.startIf().tree(truffleBooleanOption(builder, TruffleTypes.OPTION_DETAILED_REWRITE_REASONS)).end(); |
397 builder.end(); | 400 builder.end(); |
398 | 401 |
399 return method; | 402 return method; |
400 } | 403 } |
401 | 404 |
402 private CodeExecutableElement createCachedExecute(NodeData node, SpecializationData polymorph) { | 405 private CodeExecutableElement createCachedExecute(SpecializationData polymorph) { |
403 CodeExecutableElement cachedExecute = new CodeExecutableElement(modifiers(PROTECTED, ABSTRACT), polymorph.getReturnType().getType(), EXECUTE_CHAINED); | 406 CodeExecutableElement cachedExecute = new CodeExecutableElement(modifiers(PROTECTED, ABSTRACT), polymorph.getReturnType().getType(), EXECUTE_CHAINED); |
404 addInternalValueParameters(cachedExecute, polymorph, true, false, false); | 407 addInternalValueParameters(cachedExecute, polymorph, true, false, false); |
405 | 408 |
406 ExecutableTypeData sourceExecutableType = node.findExecutableType(polymorph.getReturnType().getTypeSystemType(), 0); | 409 ExecutableTypeData sourceExecutableType = node.findExecutableType(polymorph.getReturnType().getTypeSystemType(), 0); |
407 boolean sourceThrowsUnexpected = sourceExecutableType != null && sourceExecutableType.hasUnexpectedValue(getContext()); | 410 boolean sourceThrowsUnexpected = sourceExecutableType != null && sourceExecutableType.hasUnexpectedValue(context); |
408 if (sourceThrowsUnexpected && sourceExecutableType.getType().equals(node.getGenericSpecialization().getReturnType().getTypeSystemType())) { | 411 if (sourceThrowsUnexpected && sourceExecutableType.getType().equals(node.getGenericSpecialization().getReturnType().getTypeSystemType())) { |
409 sourceThrowsUnexpected = false; | 412 sourceThrowsUnexpected = false; |
410 } | 413 } |
411 if (sourceThrowsUnexpected) { | 414 if (sourceThrowsUnexpected) { |
412 cachedExecute.getThrownTypes().add(getContext().getType(UnexpectedResultException.class)); | 415 cachedExecute.getThrownTypes().add(context.getType(UnexpectedResultException.class)); |
413 } | 416 } |
414 return cachedExecute; | 417 return cachedExecute; |
415 | 418 |
416 } | 419 } |
417 | 420 |
418 private void createConstructors(NodeData node, CodeTypeElement clazz) { | 421 private void createConstructors(CodeTypeElement clazz) { |
419 List<ExecutableElement> constructors = findUserConstructors(node.getNodeType()); | 422 List<ExecutableElement> constructors = findUserConstructors(node.getNodeType()); |
420 ExecutableElement sourceSectionConstructor = null; | 423 ExecutableElement sourceSectionConstructor = null; |
421 if (constructors.isEmpty()) { | 424 if (constructors.isEmpty()) { |
422 clazz.add(createUserConstructor(clazz, null)); | 425 clazz.add(createUserConstructor(clazz, null)); |
423 } else { | 426 } else { |
426 if (NodeParser.isSourceSectionConstructor(context, constructor)) { | 429 if (NodeParser.isSourceSectionConstructor(context, constructor)) { |
427 sourceSectionConstructor = constructor; | 430 sourceSectionConstructor = constructor; |
428 } | 431 } |
429 } | 432 } |
430 } | 433 } |
431 if (node.needsRewrites(getContext())) { | 434 if (node.needsRewrites(context)) { |
432 ExecutableElement copyConstructor = findCopyConstructor(node.getNodeType()); | 435 ExecutableElement copyConstructor = findCopyConstructor(node.getNodeType()); |
433 clazz.add(createCopyConstructor(clazz, copyConstructor, sourceSectionConstructor)); | 436 clazz.add(createCopyConstructor(clazz, copyConstructor, sourceSectionConstructor)); |
434 } | 437 } |
435 } | 438 } |
436 | 439 |
437 private CodeExecutableElement createUserConstructor(CodeTypeElement type, ExecutableElement superConstructor) { | 440 private CodeExecutableElement createUserConstructor(CodeTypeElement type, ExecutableElement superConstructor) { |
438 CodeExecutableElement method = new CodeExecutableElement(null, type.getSimpleName().toString()); | 441 CodeExecutableElement method = new CodeExecutableElement(null, type.getSimpleName().toString()); |
439 CodeTreeBuilder builder = method.createBuilder(); | 442 CodeTreeBuilder builder = method.createBuilder(); |
440 | |
441 NodeData node = getModel().getNode(); | |
442 | 443 |
443 if (superConstructor != null) { | 444 if (superConstructor != null) { |
444 for (VariableElement param : superConstructor.getParameters()) { | 445 for (VariableElement param : superConstructor.getParameters()) { |
445 method.getParameters().add(CodeVariableElement.clone(param)); | 446 method.getParameters().add(CodeVariableElement.clone(param)); |
446 } | 447 } |
476 } | 477 } |
477 return method; | 478 return method; |
478 } | 479 } |
479 | 480 |
480 private CodeTree createStaticCast(CodeTreeBuilder parent, NodeChildData child, String fieldName) { | 481 private CodeTree createStaticCast(CodeTreeBuilder parent, NodeChildData child, String fieldName) { |
481 NodeData parentNode = getModel().getNode(); | 482 NodeData parentNode = getSpecialization().getNode(); |
482 if (child != null) { | 483 if (child != null) { |
483 CreateCastData createCast = parentNode.findCast(child.getName()); | 484 CreateCastData createCast = parentNode.findCast(child.getName()); |
484 if (createCast != null) { | 485 if (createCast != null) { |
485 return createTemplateMethodCall(parent, null, parentNode.getGenericSpecialization(), createCast, null, fieldName); | 486 return createTemplateMethodCall(parent, null, parentNode.getGenericSpecialization(), createCast, null, fieldName); |
486 } | 487 } |
503 if (var.getModifiers().contains(STATIC) || !var.getModifiers().contains(FINAL)) { | 504 if (var.getModifiers().contains(STATIC) || !var.getModifiers().contains(FINAL)) { |
504 continue; | 505 continue; |
505 } | 506 } |
506 final String varName = var.getSimpleName().toString(); | 507 final String varName = var.getSimpleName().toString(); |
507 final TypeMirror varType = var.asType(); | 508 final TypeMirror varType = var.asType(); |
508 if (ElementUtils.isAssignable(varType, getContext().getTruffleTypes().getNodeArray())) { | 509 if (ElementUtils.isAssignable(varType, context.getTruffleTypes().getNodeArray())) { |
509 CodeTree size = builder.create().string("copy.", varName, ".length").getRoot(); | 510 CodeTree size = builder.create().string("copy.", varName, ".length").getRoot(); |
510 builder.startStatement().string("this.").string(varName).string(" = ").startNewArray((ArrayType) varType, size).end().end(); | 511 builder.startStatement().string("this.").string(varName).string(" = ").startNewArray((ArrayType) varType, size).end().end(); |
511 } else { | 512 } else { |
512 builder.startStatement().string("this.", varName, " = copy.", varName).end(); | 513 builder.startStatement().string("this.", varName, " = copy.", varName).end(); |
513 } | 514 } |
515 | 516 |
516 return method; | 517 return method; |
517 } | 518 } |
518 | 519 |
519 private CodeVariableElement createAssumptionField(String assumption) { | 520 private CodeVariableElement createAssumptionField(String assumption) { |
520 CodeVariableElement var = new CodeVariableElement(getContext().getTruffleTypes().getAssumption(), assumption); | 521 CodeVariableElement var = new CodeVariableElement(context.getTruffleTypes().getAssumption(), assumption); |
521 var.getModifiers().add(Modifier.FINAL); | 522 var.getModifiers().add(Modifier.FINAL); |
522 return var; | 523 return var; |
523 } | 524 } |
524 | 525 |
525 private CodeVariableElement createChildField(NodeChildData child) { | 526 private CodeVariableElement createChildField(NodeChildData child) { |
528 var.getModifiers().add(Modifier.PROTECTED); | 529 var.getModifiers().add(Modifier.PROTECTED); |
529 | 530 |
530 DeclaredType annotationType; | 531 DeclaredType annotationType; |
531 if (child.getCardinality() == Cardinality.MANY) { | 532 if (child.getCardinality() == Cardinality.MANY) { |
532 var.getModifiers().add(Modifier.FINAL); | 533 var.getModifiers().add(Modifier.FINAL); |
533 annotationType = getContext().getTruffleTypes().getChildrenAnnotation(); | 534 annotationType = context.getTruffleTypes().getChildrenAnnotation(); |
534 } else { | 535 } else { |
535 annotationType = getContext().getTruffleTypes().getChildAnnotation(); | 536 annotationType = context.getTruffleTypes().getChildAnnotation(); |
536 } | 537 } |
537 | 538 |
538 var.getAnnotationMirrors().add(new CodeAnnotationMirror(annotationType)); | 539 var.getAnnotationMirrors().add(new CodeAnnotationMirror(annotationType)); |
539 return var; | 540 return var; |
540 } | 541 } |
551 | 552 |
552 return SpecializationGroup.create(filteredSpecializations); | 553 return SpecializationGroup.create(filteredSpecializations); |
553 } | 554 } |
554 | 555 |
555 protected final CodeExecutableElement createExecuteUninitialized() { | 556 protected final CodeExecutableElement createExecuteUninitialized() { |
556 NodeData node = getModel().getNode(); | |
557 SpecializationData generic = node.getGenericSpecialization(); | 557 SpecializationData generic = node.getGenericSpecialization(); |
558 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED), generic.getReturnType().getType(), EXECUTE_UNINITIALIZED); | 558 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED), generic.getReturnType().getType(), EXECUTE_UNINITIALIZED); |
559 addInternalValueParameters(method, generic, true, false, false); | 559 addInternalValueParameters(method, generic, true, false, false); |
560 CodeTreeBuilder builder = method.createBuilder(); | 560 CodeTreeBuilder builder = method.createBuilder(); |
561 | 561 |
562 boolean needsFrame = node.isFrameUsedByAnyGuard(getContext()); | 562 boolean needsFrame = node.isFrameUsedByAnyGuard(context); |
563 CodeTreeBuilder createSpecializationCall = builder.create(); | 563 CodeTreeBuilder createSpecializationCall = builder.create(); |
564 createSpecializationCall.startCall(SPECIALIZE); | 564 createSpecializationCall.startCall(SPECIALIZE); |
565 addInternalValueParameterNames(createSpecializationCall, generic, generic, null, needsFrame, !needsFrame, null); | 565 addInternalValueParameterNames(createSpecializationCall, generic, generic, null, needsFrame, !needsFrame, null); |
566 createSpecializationCall.end(); | 566 createSpecializationCall.end(); |
567 builder.declaration(baseClassName(node), "newNode", createSpecializationCall); | 567 builder.declaration(baseClassName(node), "newNode", createSpecializationCall); |
600 builder.end(); | 600 builder.end(); |
601 return builder.getRoot(); | 601 return builder.getRoot(); |
602 } | 602 } |
603 | 603 |
604 private CodeExecutableElement createMonomorphicRewrite() { | 604 private CodeExecutableElement createMonomorphicRewrite() { |
605 NodeData node = getModel().getNode(); | |
606 | |
607 SpecializationData generic = node.getGenericSpecialization(); | 605 SpecializationData generic = node.getGenericSpecialization(); |
608 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), generic.getReturnType().getType(), REWRITE); | 606 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), generic.getReturnType().getType(), REWRITE); |
609 addInternalValueParameters(method, generic, true, false, false); | 607 addInternalValueParameters(method, generic, true, false, false); |
610 method.addParameter(new CodeVariableElement(getContext().getType(String.class), "reason")); | 608 method.addParameter(new CodeVariableElement(context.getType(String.class), "reason")); |
611 | 609 |
612 boolean needsFrame = node.isFrameUsedByAnyGuard(getContext()); | 610 boolean needsFrame = node.isFrameUsedByAnyGuard(context); |
613 CodeTreeBuilder builder = method.createBuilder(); | 611 CodeTreeBuilder builder = method.createBuilder(); |
614 | 612 |
615 builder.startStatement().startStaticCall(context.getTruffleTypes().getCompilerAsserts(), "neverPartOfCompilation").end().end(); | 613 builder.startStatement().startStaticCall(context.getTruffleTypes().getCompilerAsserts(), "neverPartOfCompilation").end().end(); |
616 String baseClassName = baseClassName(getModel().getNode()); | 614 String baseClassName = baseClassName(getSpecialization().getNode()); |
617 CodeTreeBuilder createSpecializationCall = builder.create(); | 615 CodeTreeBuilder createSpecializationCall = builder.create(); |
618 createSpecializationCall.startCall(SPECIALIZE); | 616 createSpecializationCall.startCall(SPECIALIZE); |
619 addInternalValueParameterNames(createSpecializationCall, generic, generic, null, needsFrame, !needsFrame, null); | 617 addInternalValueParameterNames(createSpecializationCall, generic, generic, null, needsFrame, !needsFrame, null); |
620 createSpecializationCall.end(); | 618 createSpecializationCall.end(); |
621 builder.declaration(baseClassName, "newNode", createSpecializationCall); | 619 builder.declaration(baseClassName, "newNode", createSpecializationCall); |
629 builder.startStatement().string("((", uninitializedName, ") newNode).containsFallback = true").end(); | 627 builder.startStatement().string("((", uninitializedName, ") newNode).containsFallback = true").end(); |
630 } | 628 } |
631 builder.end(); | 629 builder.end(); |
632 | 630 |
633 builder.startStatement(); | 631 builder.startStatement(); |
634 builder.type(getContext().getType(String.class)).string(" message = ").tree(createInfoCall(builder, generic, "reason")); | 632 builder.type(context.getType(String.class)).string(" message = ").tree(createInfoCall(builder, generic, "reason")); |
635 builder.end(); | 633 builder.end(); |
636 | 634 |
637 builder.declaration(baseClassName, "returnNode", | 635 builder.declaration(baseClassName, "returnNode", |
638 builder.create().startStaticCall(context.getTruffleTypes().getDslShare(), DSLSHARE_REWRITE).string("this").string("newNode").string("message").end().getRoot()); | 636 builder.create().startStaticCall(context.getTruffleTypes().getDslShare(), DSLSHARE_REWRITE).string("this").string("newNode").string("message").end().getRoot()); |
639 builder.startIf().string("returnNode == null").end().startBlock(); | 637 builder.startIf().string("returnNode == null").end().startBlock(); |
640 builder.tree(createRewritePolymorphic(builder, node, "this")); | 638 builder.tree(createRewritePolymorphic(builder, "this")); |
641 builder.end(); | 639 builder.end(); |
642 | 640 |
643 builder.startReturn(); | 641 builder.startReturn(); |
644 builder.startCall("returnNode", EXECUTE_CHAINED); | 642 builder.startCall("returnNode", EXECUTE_CHAINED); |
645 addInternalValueParameterNames(builder, node.getGenericSpecialization(), node.getGenericSpecialization(), null, true, false, null); | 643 addInternalValueParameterNames(builder, node.getGenericSpecialization(), node.getGenericSpecialization(), null, true, false, null); |
647 builder.end(); | 645 builder.end(); |
648 | 646 |
649 return method; | 647 return method; |
650 } | 648 } |
651 | 649 |
652 private CodeTree createRewritePolymorphic(CodeTreeBuilder parent, NodeData node, String currentNode) { | 650 private CodeTree createRewritePolymorphic(CodeTreeBuilder parent, String currentNode) { |
653 String polyClassName = nodePolymorphicClassName(node); | 651 String polyClassName = nodePolymorphicClassName(node); |
654 CodeTreeBuilder builder = parent.create(); | 652 CodeTreeBuilder builder = parent.create(); |
655 | 653 |
656 builder.startStatement().string("returnNode = "); | 654 builder.startStatement().string("returnNode = "); |
657 builder.startStaticCall(context.getTruffleTypes().getDslShare(), DSLSHARE_REWRITE_TO_POLYMORHPIC); | 655 builder.startStaticCall(context.getTruffleTypes().getDslShare(), DSLSHARE_REWRITE_TO_POLYMORHPIC); |
665 builder.end(); | 663 builder.end(); |
666 | 664 |
667 return builder.getRoot(); | 665 return builder.getRoot(); |
668 } | 666 } |
669 | 667 |
670 private CodeExecutableElement createCreateSpecializationMethod(NodeData node, SpecializationGroup group) { | 668 private CodeExecutableElement createCreateSpecializationMethod(SpecializationGroup group) { |
671 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), new GeneratedTypeMirror(ElementUtils.getPackageName(node.getTemplateType()), baseClassName(node)), | 669 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), new GeneratedTypeMirror(ElementUtils.getPackageName(node.getTemplateType()), baseClassName(node)), |
672 SPECIALIZE); | 670 SPECIALIZE); |
673 | 671 |
674 final boolean needsFrame = node.isFrameUsedByAnyGuard(getContext()); | 672 final boolean needsFrame = node.isFrameUsedByAnyGuard(context); |
675 | 673 |
676 if (!needsFrame) { | 674 if (!needsFrame) { |
677 method.getAnnotationMirrors().add(new CodeAnnotationMirror(getContext().getTruffleTypes().getTruffleBoundary())); | 675 method.getAnnotationMirrors().add(new CodeAnnotationMirror(context.getTruffleTypes().getTruffleBoundary())); |
678 } | 676 } |
679 | 677 |
680 addInternalValueParameters(method, node.getGenericSpecialization(), needsFrame, !needsFrame, false); | 678 addInternalValueParameters(method, node.getGenericSpecialization(), needsFrame, !needsFrame, false); |
681 final CodeTreeBuilder builder = method.createBuilder(); | 679 final CodeTreeBuilder builder = method.createBuilder(); |
682 builder.tree(createExecuteTree(builder, node.getGenericSpecialization(), group, new CodeBlock<SpecializationData>() { | 680 builder.tree(createExecuteTree(builder, node.getGenericSpecialization(), group, new CodeBlock<SpecializationData>() { |
705 | 703 |
706 if (current.getNode().getGenericSpecialization().isReachable() && useDeoptimize) { | 704 if (current.getNode().getGenericSpecialization().isReachable() && useDeoptimize) { |
707 builder.tree(createDeoptimize(builder)); | 705 builder.tree(createDeoptimize(builder)); |
708 } | 706 } |
709 builder.startReturn(); | 707 builder.startReturn(); |
710 builder.cast(baseClassName(getModel().getNode())); | 708 builder.cast(baseClassName(getSpecialization().getNode())); |
711 builder.startGroup().startCall(className, NodeFactoryFactory.FACTORY_METHOD_NAME).string("this"); | 709 builder.startGroup().startCall(className, NodeFactoryFactory.FACTORY_METHOD_NAME).string("this"); |
712 for (Parameter param : current.getSignatureParameters()) { | 710 for (Parameter param : current.getSignatureParameters()) { |
713 NodeChildData child = param.getSpecification().getExecution().getChild(); | 711 NodeChildData child = param.getSpecification().getExecution().getChild(); |
714 List<TypeData> types = child.getNodeData().getTypeSystem().lookupSourceTypes(param.getTypeSystemType()); | 712 List<TypeData> types = child.getNodeData().getTypeSystem().lookupSourceTypes(param.getTypeSystemType()); |
715 if (types.size() > 1) { | 713 if (types.size() > 1) { |
800 | 798 |
801 return true; | 799 return true; |
802 } | 800 } |
803 | 801 |
804 private int emitGuards(CodeTreeBuilder builder, SpecializationData source, SpecializationGroup group, boolean emitAssumptions, boolean typedCasts, boolean castForGuardsOnly) { | 802 private int emitGuards(CodeTreeBuilder builder, SpecializationData source, SpecializationGroup group, boolean emitAssumptions, boolean typedCasts, boolean castForGuardsOnly) { |
805 NodeData node = source.getNode(); | |
806 | |
807 CodeTreeBuilder guardsBuilder = builder.create(); | 803 CodeTreeBuilder guardsBuilder = builder.create(); |
808 CodeTreeBuilder castBuilder = builder.create(); | 804 CodeTreeBuilder castBuilder = builder.create(); |
809 CodeTreeBuilder guardsCastBuilder = builder.create(); | 805 CodeTreeBuilder guardsCastBuilder = builder.create(); |
810 | 806 |
811 String guardsAnd = ""; | 807 String guardsAnd = ""; |
933 } | 929 } |
934 return false; | 930 return false; |
935 } | 931 } |
936 | 932 |
937 private CodeTree createTypeGuard(CodeTreeBuilder parent, NodeExecutionData execution, Parameter source, TypeData targetType, boolean typedCasts) { | 933 private CodeTree createTypeGuard(CodeTreeBuilder parent, NodeExecutionData execution, Parameter source, TypeData targetType, boolean typedCasts) { |
938 NodeData node = execution.getChild().getNodeData(); | 934 NodeData childNode = execution.getChild().getNodeData(); |
939 | 935 |
940 CodeTreeBuilder builder = new CodeTreeBuilder(parent); | 936 CodeTreeBuilder builder = new CodeTreeBuilder(parent); |
941 | 937 |
942 TypeData sourceType = source.getTypeSystemType(); | 938 TypeData sourceType = source.getTypeSystemType(); |
943 | 939 |
955 builder.string(" || "); | 951 builder.string(" || "); |
956 } | 952 } |
957 | 953 |
958 String castMethodName; | 954 String castMethodName; |
959 String castTypeName = null; | 955 String castTypeName = null; |
960 List<TypeData> types = getModel().getNode().getTypeSystem().lookupSourceTypes(targetType); | 956 List<TypeData> types = getSpecialization().getNode().getTypeSystem().lookupSourceTypes(targetType); |
961 if (types.size() > 1) { | 957 if (types.size() > 1) { |
962 castMethodName = TypeSystemCodeGenerator.isImplicitTypeMethodName(targetType); | 958 castMethodName = TypeSystemCodeGenerator.isImplicitTypeMethodName(targetType); |
963 if (typedCasts) { | 959 if (typedCasts) { |
964 castTypeName = implicitTypeName(source); | 960 castTypeName = implicitTypeName(source); |
965 } | 961 } |
966 } else { | 962 } else { |
967 castMethodName = TypeSystemCodeGenerator.isTypeMethodName(targetType); | 963 castMethodName = TypeSystemCodeGenerator.isTypeMethodName(targetType); |
968 } | 964 } |
969 | 965 |
970 startCallTypeSystemMethod(builder, node.getTypeSystem(), castMethodName); | 966 startCallTypeSystemMethod(builder, childNode.getTypeSystem(), castMethodName); |
971 builder.string(valueName(source)); | 967 builder.string(valueName(source)); |
972 if (castTypeName != null) { | 968 if (castTypeName != null) { |
973 builder.string(castTypeName); | 969 builder.string(castTypeName); |
974 } | 970 } |
975 builder.end().end(); // call | 971 builder.end().end(); // call |
983 return builder.getRoot(); | 979 return builder.getRoot(); |
984 } | 980 } |
985 | 981 |
986 // TODO merge redundancies with #createTypeGuard | 982 // TODO merge redundancies with #createTypeGuard |
987 private CodeTree createCast(CodeTreeBuilder parent, NodeExecutionData execution, Parameter source, TypeData targetType, boolean typedCasts) { | 983 private CodeTree createCast(CodeTreeBuilder parent, NodeExecutionData execution, Parameter source, TypeData targetType, boolean typedCasts) { |
988 NodeData node = execution.getChild().getNodeData(); | 984 NodeData childNode = execution.getChild().getNodeData(); |
989 TypeData sourceType = source.getTypeSystemType(); | 985 TypeData sourceType = source.getTypeSystemType(); |
990 | 986 |
991 if (!sourceType.needsCastTo(targetType)) { | 987 if (!sourceType.needsCastTo(targetType)) { |
992 return null; | 988 return null; |
993 } | 989 } |
999 condition = CodeTreeBuilder.singleString(valueName(shortCircuit)); | 995 condition = CodeTreeBuilder.singleString(valueName(shortCircuit)); |
1000 } | 996 } |
1001 | 997 |
1002 String castMethodName; | 998 String castMethodName; |
1003 String castTypeName = null; | 999 String castTypeName = null; |
1004 List<TypeData> types = getModel().getNode().getTypeSystem().lookupSourceTypes(targetType); | 1000 List<TypeData> types = getSpecialization().getNode().getTypeSystem().lookupSourceTypes(targetType); |
1005 if (types.size() > 1) { | 1001 if (types.size() > 1) { |
1006 castMethodName = TypeSystemCodeGenerator.asImplicitTypeMethodName(targetType); | 1002 castMethodName = TypeSystemCodeGenerator.asImplicitTypeMethodName(targetType); |
1007 if (typedCasts) { | 1003 if (typedCasts) { |
1008 castTypeName = implicitTypeName(source); | 1004 castTypeName = implicitTypeName(source); |
1009 } | 1005 } |
1015 args.add(CodeTreeBuilder.singleString(valueName(source))); | 1011 args.add(CodeTreeBuilder.singleString(valueName(source))); |
1016 if (castTypeName != null) { | 1012 if (castTypeName != null) { |
1017 args.add(CodeTreeBuilder.singleString(castTypeName)); | 1013 args.add(CodeTreeBuilder.singleString(castTypeName)); |
1018 } | 1014 } |
1019 | 1015 |
1020 CodeTree cast = createCallTypeSystemMethod(parent, node, castMethodName, args.toArray(new CodeTree[0])); | 1016 CodeTree cast = createCallTypeSystemMethod(parent, childNode, castMethodName, args.toArray(new CodeTree[0])); |
1021 | 1017 |
1022 CodeTreeBuilder builder = parent.create(); | 1018 CodeTreeBuilder builder = parent.create(); |
1023 builder.tree(createLazyAssignment(parent, castValueName(source), targetType.getPrimitiveType(), condition, cast)); | 1019 builder.tree(createLazyAssignment(parent, castValueName(source), targetType.getPrimitiveType(), condition, cast)); |
1024 | 1020 |
1025 return builder.getRoot(); | 1021 return builder.getRoot(); |
1032 assert shortCircuit != null; | 1028 assert shortCircuit != null; |
1033 condition = CodeTreeBuilder.singleString(valueName(shortCircuit)); | 1029 condition = CodeTreeBuilder.singleString(valueName(shortCircuit)); |
1034 } | 1030 } |
1035 | 1031 |
1036 CodeTreeBuilder builder = parent.create(); | 1032 CodeTreeBuilder builder = parent.create(); |
1037 List<TypeData> types = getModel().getNode().getTypeSystem().lookupSourceTypes(targetType); | 1033 List<TypeData> types = getSpecialization().getNode().getTypeSystem().lookupSourceTypes(targetType); |
1038 if (types.size() > 1) { | 1034 if (types.size() > 1) { |
1039 CodeTree castType = createCallTypeSystemMethod(parent, execution.getChild().getNodeData(), TypeSystemCodeGenerator.getImplicitClass(targetType), | 1035 CodeTree castType = createCallTypeSystemMethod(parent, execution.getChild().getNodeData(), TypeSystemCodeGenerator.getImplicitClass(targetType), |
1040 CodeTreeBuilder.singleString(valueName(source))); | 1036 CodeTreeBuilder.singleString(valueName(source))); |
1041 builder.tree(createLazyAssignment(builder, implicitTypeName(source), getContext().getType(Class.class), condition, castType)); | 1037 builder.tree(createLazyAssignment(builder, implicitTypeName(source), context.getType(Class.class), condition, castType)); |
1042 } | 1038 } |
1043 return builder.getRoot(); | 1039 return builder.getRoot(); |
1044 } | 1040 } |
1045 | 1041 |
1046 private static CodeTree createMethodGuard(CodeTreeBuilder parent, String prefix, SpecializationData source, GuardExpression guard) { | 1042 private static CodeTree createMethodGuard(CodeTreeBuilder parent, String prefix, SpecializationData source, GuardExpression guard) { |
1055 | 1051 |
1056 protected CodeTree createGenericInvoke(CodeTreeBuilder parent, SpecializationData source, SpecializationData current) { | 1052 protected CodeTree createGenericInvoke(CodeTreeBuilder parent, SpecializationData source, SpecializationData current) { |
1057 CodeTreeBuilder builder = new CodeTreeBuilder(parent); | 1053 CodeTreeBuilder builder = new CodeTreeBuilder(parent); |
1058 | 1054 |
1059 if (current.getMethod() == null) { | 1055 if (current.getMethod() == null) { |
1060 emitEncounteredSynthetic(builder, getModel().getNode(), current); | 1056 emitEncounteredSynthetic(builder, getSpecialization().getNode(), current); |
1061 } else { | 1057 } else { |
1062 builder.startReturn().tree(createTemplateMethodCall(builder, null, source, current, null)).end(); | 1058 builder.startReturn().tree(createTemplateMethodCall(builder, null, source, current, null)).end(); |
1063 } | 1059 } |
1064 | 1060 |
1065 return encloseThrowsWithFallThrough(parent, current, builder.getRoot()); | 1061 return encloseThrowsWithFallThrough(parent, current, builder.getRoot()); |
1074 builder.startTryBlock(); | 1070 builder.startTryBlock(); |
1075 builder.tree(tree); | 1071 builder.tree(tree); |
1076 for (SpecializationThrowsData exception : current.getExceptions()) { | 1072 for (SpecializationThrowsData exception : current.getExceptions()) { |
1077 builder.end().startCatchBlock(exception.getJavaClass(), "rewriteEx"); | 1073 builder.end().startCatchBlock(exception.getJavaClass(), "rewriteEx"); |
1078 builder.tree(createDeoptimize(builder)); | 1074 builder.tree(createDeoptimize(builder)); |
1079 builder.tree(createCallRewriteMonomorphic(builder, false, current.getNode().getGenericSpecialization().getReturnType().getTypeSystemType(), current, null, | 1075 builder.tree(createCallRewriteMonomorphic(builder, false, current.getNode().getGenericSpecialization().getReturnType().getTypeSystemType(), null, |
1080 "Thrown " + ElementUtils.getSimpleName(exception.getJavaClass()))); | 1076 "Thrown " + ElementUtils.getSimpleName(exception.getJavaClass()))); |
1081 } | 1077 } |
1082 builder.end(); | 1078 builder.end(); |
1083 | 1079 |
1084 return builder.getRoot(); | 1080 return builder.getRoot(); |
1085 } | 1081 } |
1086 | 1082 |
1087 protected CodeTree createCastingExecute(CodeTreeBuilder parent, SpecializationData specialization, ExecutableTypeData executable, ExecutableTypeData castExecutable) { | 1083 protected CodeTree createCastingExecute(CodeTreeBuilder parent, ExecutableTypeData executable, ExecutableTypeData castExecutable) { |
1088 TypeData type = executable.getType(); | 1084 TypeData type = executable.getType(); |
1089 CodeTreeBuilder builder = new CodeTreeBuilder(parent); | 1085 CodeTreeBuilder builder = new CodeTreeBuilder(parent); |
1090 NodeData node = specialization.getNode(); | |
1091 | 1086 |
1092 TypeData primaryType = castExecutable.getType(); | 1087 TypeData primaryType = castExecutable.getType(); |
1093 | 1088 |
1094 boolean needsTry = castExecutable.hasUnexpectedValue(getContext()); | 1089 boolean needsTry = castExecutable.hasUnexpectedValue(context); |
1095 boolean returnVoid = type.isVoid(); | 1090 boolean returnVoid = type.isVoid(); |
1096 | 1091 |
1097 List<Parameter> executeParameters = new ArrayList<>(); | 1092 List<Parameter> executeParameters = new ArrayList<>(); |
1098 for (Parameter sourceParameter : executable.getSignatureParameters()) { | 1093 for (Parameter sourceParameter : executable.getSignatureParameters()) { |
1099 Parameter targetParameter = castExecutable.findParameter(sourceParameter.getLocalName()); | 1094 Parameter targetParameter = castExecutable.findParameter(sourceParameter.getLocalName()); |
1107 for (int i = 0; i < executeParameterNames.length; i++) { | 1102 for (int i = 0; i < executeParameterNames.length; i++) { |
1108 executeParameterNames[i] = valueName(executeParameters.get(i)); | 1103 executeParameterNames[i] = valueName(executeParameters.get(i)); |
1109 } | 1104 } |
1110 | 1105 |
1111 builder.tree(createExecuteChildren(builder, executable, specialization, executeParameters, null)); | 1106 builder.tree(createExecuteChildren(builder, executable, specialization, executeParameters, null)); |
1112 boolean hasUnexpected = executable.hasUnexpectedValue(getContext()); | 1107 boolean hasUnexpected = executable.hasUnexpectedValue(context); |
1113 | 1108 |
1114 CodeTree primaryExecuteCall = createTemplateMethodCall(builder, null, executable, castExecutable, null, executeParameterNames); | 1109 CodeTree primaryExecuteCall = createTemplateMethodCall(builder, null, executable, castExecutable, null, executeParameterNames); |
1115 if (needsTry) { | 1110 if (needsTry) { |
1116 if (!returnVoid) { | 1111 if (!returnVoid) { |
1117 builder.declaration(primaryType.getPrimitiveType(), "value"); | 1112 builder.declaration(primaryType.getPrimitiveType(), "value"); |
1158 | 1153 |
1159 private static CodeTree createExpectExecutableType(NodeData node, TypeData sourceType, boolean hasUnexpected, TypeData exepctedType, CodeTree value) { | 1154 private static CodeTree createExpectExecutableType(NodeData node, TypeData sourceType, boolean hasUnexpected, TypeData exepctedType, CodeTree value) { |
1160 return createCastType(node.getTypeSystem(), sourceType, exepctedType, hasUnexpected, value); | 1155 return createCastType(node.getTypeSystem(), sourceType, exepctedType, hasUnexpected, value); |
1161 } | 1156 } |
1162 | 1157 |
1163 protected CodeTree createExecuteChildren(CodeTreeBuilder parent, ExecutableTypeData sourceExecutable, SpecializationData specialization, List<Parameter> targetParameters, | 1158 protected CodeTree createExecuteChildren(CodeTreeBuilder parent, ExecutableTypeData sourceExecutable, SpecializationData currentSpecialization, List<Parameter> targetParameters, |
1164 Parameter unexpectedParameter) { | 1159 Parameter unexpectedParameter) { |
1165 CodeTreeBuilder builder = parent.create(); | 1160 CodeTreeBuilder builder = parent.create(); |
1166 for (Parameter targetParameter : targetParameters) { | 1161 for (Parameter targetParameter : targetParameters) { |
1167 if (!targetParameter.getSpecification().isSignature()) { | 1162 if (!targetParameter.getSpecification().isSignature()) { |
1168 continue; | 1163 continue; |
1169 } | 1164 } |
1170 NodeExecutionData execution = targetParameter.getSpecification().getExecution(); | 1165 NodeExecutionData execution = targetParameter.getSpecification().getExecution(); |
1171 CodeTree executionExpressions = createExecuteChild(builder, execution, sourceExecutable, targetParameter, unexpectedParameter); | 1166 CodeTree executionExpressions = createExecuteChild(builder, execution, sourceExecutable, targetParameter, unexpectedParameter); |
1172 CodeTree unexpectedTree = createCatchUnexpectedTree(builder, executionExpressions, specialization, sourceExecutable, targetParameter, execution.isShortCircuit(), unexpectedParameter); | 1167 CodeTree unexpectedTree = createCatchUnexpectedTree(builder, executionExpressions, currentSpecialization, sourceExecutable, targetParameter, execution.isShortCircuit(), |
1173 CodeTree shortCircuitTree = createShortCircuitTree(builder, unexpectedTree, specialization, targetParameter, unexpectedParameter); | 1168 unexpectedParameter); |
1169 CodeTree shortCircuitTree = createShortCircuitTree(builder, unexpectedTree, currentSpecialization, targetParameter, unexpectedParameter); | |
1174 | 1170 |
1175 if (shortCircuitTree == executionExpressions) { | 1171 if (shortCircuitTree == executionExpressions) { |
1176 if (containsNewLine(executionExpressions)) { | 1172 if (containsNewLine(executionExpressions)) { |
1177 builder.declaration(targetParameter.getType(), valueName(targetParameter)); | 1173 builder.declaration(targetParameter.getType(), valueName(targetParameter)); |
1178 builder.tree(shortCircuitTree); | 1174 builder.tree(shortCircuitTree); |
1186 } | 1182 } |
1187 return builder.getRoot(); | 1183 return builder.getRoot(); |
1188 } | 1184 } |
1189 | 1185 |
1190 private ExecutableTypeData resolveExecutableType(NodeExecutionData execution, TypeData type) { | 1186 private ExecutableTypeData resolveExecutableType(NodeExecutionData execution, TypeData type) { |
1191 ExecutableTypeData targetExecutable = execution.getChild().findExecutableType(getContext(), type); | 1187 ExecutableTypeData targetExecutable = execution.getChild().findExecutableType(context, type); |
1192 if (targetExecutable == null) { | 1188 if (targetExecutable == null) { |
1193 targetExecutable = execution.getChild().findAnyGenericExecutableType(getContext()); | 1189 targetExecutable = execution.getChild().findAnyGenericExecutableType(context); |
1194 } | 1190 } |
1195 return targetExecutable; | 1191 return targetExecutable; |
1196 } | 1192 } |
1197 | 1193 |
1198 private CodeTree createExecuteChild(CodeTreeBuilder parent, NodeExecutionData execution, ExecutableTypeData sourceExecutable, Parameter targetParameter, Parameter unexpectedParameter) { | 1194 private CodeTree createExecuteChild(CodeTreeBuilder parent, NodeExecutionData execution, ExecutableTypeData sourceExecutable, Parameter targetParameter, Parameter unexpectedParameter) { |
1199 SpecializationData specialization = getModel(); | |
1200 if (specialization.isPolymorphic() && targetParameter.getTypeSystemType().isGeneric() && unexpectedParameter == null) { | 1195 if (specialization.isPolymorphic() && targetParameter.getTypeSystemType().isGeneric() && unexpectedParameter == null) { |
1201 List<TypeData> possiblePolymorphicTypes = lookupPolymorphicTargetTypes(targetParameter); | 1196 List<TypeData> possiblePolymorphicTypes = lookupPolymorphicTargetTypes(targetParameter); |
1202 if (possiblePolymorphicTypes.size() > 1) { | 1197 if (possiblePolymorphicTypes.size() > 1) { |
1203 CodeTreeBuilder builder = parent.create(); | 1198 CodeTreeBuilder builder = parent.create(); |
1204 | 1199 |
1240 } | 1235 } |
1241 return parameter; | 1236 return parameter; |
1242 } | 1237 } |
1243 | 1238 |
1244 private final List<TypeData> lookupPolymorphicTargetTypes(Parameter param) { | 1239 private final List<TypeData> lookupPolymorphicTargetTypes(Parameter param) { |
1245 SpecializationData specialization = getModel(); | |
1246 Set<TypeData> possiblePolymorphicTypes = new HashSet<>(); | 1240 Set<TypeData> possiblePolymorphicTypes = new HashSet<>(); |
1247 for (SpecializationData otherSpecialization : specialization.getNode().getSpecializations()) { | 1241 for (SpecializationData otherSpecialization : specialization.getNode().getSpecializations()) { |
1248 if (!otherSpecialization.isSpecialized()) { | 1242 if (!otherSpecialization.isSpecialized()) { |
1249 continue; | 1243 continue; |
1250 } | 1244 } |
1330 if (childExecuteName == null) { | 1324 if (childExecuteName == null) { |
1331 return null; | 1325 return null; |
1332 } | 1326 } |
1333 | 1327 |
1334 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, expectType != null ? STATIC : FINAL), param.getType(), childExecuteName); | 1328 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, expectType != null ? STATIC : FINAL), param.getType(), childExecuteName); |
1335 method.getThrownTypes().add(getContext().getTruffleTypes().getUnexpectedValueException()); | 1329 method.getThrownTypes().add(context.getTruffleTypes().getUnexpectedValueException()); |
1336 method.addParameter(new CodeVariableElement(getContext().getTruffleTypes().getFrame(), "frameValue")); | 1330 method.addParameter(new CodeVariableElement(context.getTruffleTypes().getFrame(), "frameValue")); |
1337 if (expectType != null) { | 1331 if (expectType != null) { |
1338 method.addParameter(new CodeVariableElement(expectType.getPrimitiveType(), valueNameEvaluated(param))); | 1332 method.addParameter(new CodeVariableElement(expectType.getPrimitiveType(), valueNameEvaluated(param))); |
1339 } | 1333 } |
1340 method.addParameter(new CodeVariableElement(getContext().getType(Class.class), implicitTypeName(param))); | 1334 method.addParameter(new CodeVariableElement(context.getType(Class.class), implicitTypeName(param))); |
1341 | 1335 |
1342 CodeTreeBuilder builder = method.createBuilder(); | 1336 CodeTreeBuilder builder = method.createBuilder(); |
1343 builder.declaration(param.getType(), valueName(param)); | 1337 builder.declaration(param.getType(), valueName(param)); |
1344 builder.tree(createExecuteChildImplicitExpressions(builder, param, expectType)); | 1338 builder.tree(createExecuteChildImplicitExpressions(builder, param, expectType)); |
1345 builder.startReturn().string(valueName(param)).end(); | 1339 builder.startReturn().string(valueName(param)).end(); |
1347 return method; | 1341 return method; |
1348 } | 1342 } |
1349 | 1343 |
1350 private CodeTree createExecuteChildImplicitExpressions(CodeTreeBuilder parent, Parameter targetParameter, TypeData expectType) { | 1344 private CodeTree createExecuteChildImplicitExpressions(CodeTreeBuilder parent, Parameter targetParameter, TypeData expectType) { |
1351 CodeTreeBuilder builder = parent.create(); | 1345 CodeTreeBuilder builder = parent.create(); |
1352 NodeData node = getModel().getNode(); | |
1353 NodeExecutionData execution = targetParameter.getSpecification().getExecution(); | 1346 NodeExecutionData execution = targetParameter.getSpecification().getExecution(); |
1354 List<TypeData> sourceTypes = node.getTypeSystem().lookupSourceTypes(targetParameter.getTypeSystemType()); | 1347 List<TypeData> sourceTypes = node.getTypeSystem().lookupSourceTypes(targetParameter.getTypeSystemType()); |
1355 boolean elseIf = false; | 1348 boolean elseIf = false; |
1356 int index = 0; | 1349 int index = 0; |
1357 for (TypeData sourceType : sourceTypes) { | 1350 for (TypeData sourceType : sourceTypes) { |
1362 builder.startBlock(); | 1355 builder.startBlock(); |
1363 } else { | 1356 } else { |
1364 builder.startElseBlock(); | 1357 builder.startElseBlock(); |
1365 } | 1358 } |
1366 | 1359 |
1367 ExecutableTypeData implictExecutableTypeData = execution.getChild().findExecutableType(getContext(), sourceType); | 1360 ExecutableTypeData implictExecutableTypeData = execution.getChild().findExecutableType(context, sourceType); |
1368 if (implictExecutableTypeData == null) { | 1361 if (implictExecutableTypeData == null) { |
1369 /* | 1362 /* |
1370 * For children with executeWith.size() > 0 an executable type may not exist so use | 1363 * For children with executeWith.size() > 0 an executable type may not exist so use |
1371 * the generic executable type which is guaranteed to exist. An expect call is | 1364 * the generic executable type which is guaranteed to exist. An expect call is |
1372 * inserted automatically by #createExecuteExpression. | 1365 * inserted automatically by #createExecuteExpression. |
1446 } | 1439 } |
1447 | 1440 |
1448 private boolean hasUnexpected(Parameter sourceParameter, Parameter targetParameter, Parameter unexpectedParameter) { | 1441 private boolean hasUnexpected(Parameter sourceParameter, Parameter targetParameter, Parameter unexpectedParameter) { |
1449 NodeExecutionData execution = targetParameter.getSpecification().getExecution(); | 1442 NodeExecutionData execution = targetParameter.getSpecification().getExecution(); |
1450 | 1443 |
1451 if (getModel().isPolymorphic() && targetParameter.getTypeSystemType().isGeneric() && unexpectedParameter == null) { | 1444 if (getSpecialization().isPolymorphic() && targetParameter.getTypeSystemType().isGeneric() && unexpectedParameter == null) { |
1452 // check for other polymorphic types | 1445 // check for other polymorphic types |
1453 List<TypeData> polymorphicTargetTypes = lookupPolymorphicTargetTypes(targetParameter); | 1446 List<TypeData> polymorphicTargetTypes = lookupPolymorphicTargetTypes(targetParameter); |
1454 if (polymorphicTargetTypes.size() > 1) { | 1447 if (polymorphicTargetTypes.size() > 1) { |
1455 for (TypeData polymorphicTargetType : polymorphicTargetTypes) { | 1448 for (TypeData polymorphicTargetType : polymorphicTargetTypes) { |
1456 if (hasUnexpectedType(execution, sourceParameter, polymorphicTargetType)) { | 1449 if (hasUnexpectedType(execution, sourceParameter, polymorphicTargetType)) { |
1465 } | 1458 } |
1466 return false; | 1459 return false; |
1467 } | 1460 } |
1468 | 1461 |
1469 private boolean hasUnexpectedType(NodeExecutionData execution, Parameter sourceParameter, TypeData targetType) { | 1462 private boolean hasUnexpectedType(NodeExecutionData execution, Parameter sourceParameter, TypeData targetType) { |
1470 List<TypeData> implicitSourceTypes = getModel().getNode().getTypeSystem().lookupSourceTypes(targetType); | 1463 List<TypeData> implicitSourceTypes = getSpecialization().getNode().getTypeSystem().lookupSourceTypes(targetType); |
1471 | 1464 |
1472 for (TypeData implicitSourceType : implicitSourceTypes) { | 1465 for (TypeData implicitSourceType : implicitSourceTypes) { |
1473 TypeData sourceType; | 1466 TypeData sourceType; |
1474 ExecutableTypeData targetExecutable = resolveExecutableType(execution, implicitSourceType); | 1467 ExecutableTypeData targetExecutable = resolveExecutableType(execution, implicitSourceType); |
1475 if (sourceParameter != null) { | 1468 if (sourceParameter != null) { |
1476 sourceType = sourceParameter.getTypeSystemType(); | 1469 sourceType = sourceParameter.getTypeSystemType(); |
1477 } else { | 1470 } else { |
1478 if (targetExecutable.hasUnexpectedValue(getContext())) { | 1471 if (targetExecutable.hasUnexpectedValue(context)) { |
1479 return true; | 1472 return true; |
1480 } | 1473 } |
1481 sourceType = targetExecutable.getType(); | 1474 sourceType = targetExecutable.getType(); |
1482 } | 1475 } |
1483 | 1476 |
1484 ImplicitCastData cast = getModel().getNode().getTypeSystem().lookupCast(implicitSourceType, targetType); | 1477 ImplicitCastData cast = getSpecialization().getNode().getTypeSystem().lookupCast(implicitSourceType, targetType); |
1485 if (cast != null) { | 1478 if (cast != null) { |
1486 if (cast.getSourceType().needsCastTo(targetType)) { | 1479 if (cast.getSourceType().needsCastTo(targetType)) { |
1487 return true; | 1480 return true; |
1488 } | 1481 } |
1489 } | 1482 } |
1493 } | 1486 } |
1494 } | 1487 } |
1495 return false; | 1488 return false; |
1496 } | 1489 } |
1497 | 1490 |
1498 private CodeTree createCatchUnexpectedTree(CodeTreeBuilder parent, CodeTree body, SpecializationData specialization, ExecutableTypeData currentExecutable, Parameter param, boolean shortCircuit, | 1491 private CodeTree createCatchUnexpectedTree(CodeTreeBuilder parent, CodeTree body, SpecializationData currentSpecialization, ExecutableTypeData currentExecutable, Parameter param, |
1499 Parameter unexpectedParameter) { | 1492 boolean shortCircuit, Parameter unexpectedParameter) { |
1500 CodeTreeBuilder builder = new CodeTreeBuilder(parent); | 1493 CodeTreeBuilder builder = new CodeTreeBuilder(parent); |
1501 Parameter sourceParameter = currentExecutable.findParameter(param.getLocalName()); | 1494 Parameter sourceParameter = currentExecutable.findParameter(param.getLocalName()); |
1502 boolean unexpected = hasUnexpected(sourceParameter, param, unexpectedParameter); | 1495 boolean unexpected = hasUnexpected(sourceParameter, param, unexpectedParameter); |
1503 if (!unexpected) { | 1496 if (!unexpected) { |
1504 return body; | 1497 return body; |
1514 } else { | 1507 } else { |
1515 builder.statement(body); | 1508 builder.statement(body); |
1516 } | 1509 } |
1517 | 1510 |
1518 builder.end().startCatchBlock(getUnexpectedValueException(), "ex"); | 1511 builder.end().startCatchBlock(getUnexpectedValueException(), "ex"); |
1519 SpecializationData generic = specialization.getNode().getGenericSpecialization(); | 1512 SpecializationData generic = currentSpecialization.getNode().getGenericSpecialization(); |
1520 Parameter genericParameter = generic.findParameter(param.getLocalName()); | 1513 Parameter genericParameter = generic.findParameter(param.getLocalName()); |
1521 | 1514 |
1522 List<Parameter> genericParameters = generic.getParametersAfter(genericParameter); | 1515 List<Parameter> genericParameters = generic.getParametersAfter(genericParameter); |
1523 builder.tree(createExecuteChildren(parent, currentExecutable, generic, genericParameters, genericParameter)); | 1516 builder.tree(createExecuteChildren(parent, currentExecutable, generic, genericParameters, genericParameter)); |
1524 if (specialization.isPolymorphic()) { | 1517 if (currentSpecialization.isPolymorphic()) { |
1525 builder.tree(createReturnOptimizeTypes(builder, currentExecutable, specialization, param)); | 1518 builder.tree(createReturnOptimizeTypes(builder, currentExecutable, currentSpecialization, param)); |
1526 } else { | 1519 } else { |
1527 builder.tree(createCallRewriteMonomorphic(builder, currentExecutable.hasUnexpectedValue(context), currentExecutable.getType(), specialization, param, "Expected " + param.getLocalName() + | 1520 builder.tree(createCallRewriteMonomorphic(builder, currentExecutable.hasUnexpectedValue(context), currentExecutable.getType(), param, "Expected " + param.getLocalName() + " instanceof " + |
1528 " instanceof " + ElementUtils.getSimpleName(param.getType()))); | 1521 ElementUtils.getSimpleName(param.getType()))); |
1529 } | 1522 } |
1530 builder.end(); // catch block | 1523 builder.end(); // catch block |
1531 | 1524 |
1532 return builder.getRoot(); | 1525 return builder.getRoot(); |
1533 } | 1526 } |
1534 | 1527 |
1535 private CodeTree createReturnOptimizeTypes(CodeTreeBuilder parent, ExecutableTypeData currentExecutable, SpecializationData specialization, Parameter param) { | 1528 private CodeTree createReturnOptimizeTypes(CodeTreeBuilder parent, ExecutableTypeData currentExecutable, SpecializationData currentSpecialization, Parameter param) { |
1536 NodeData node = specialization.getNode(); | |
1537 SpecializationData polymorphic = node.getPolymorphicSpecialization(); | 1529 SpecializationData polymorphic = node.getPolymorphicSpecialization(); |
1538 | 1530 |
1539 CodeTreeBuilder builder = new CodeTreeBuilder(parent); | 1531 CodeTreeBuilder builder = new CodeTreeBuilder(parent); |
1540 builder.startStatement().string(polymorphicTypeName(param.getSpecification().getExecution())).string(" = ").typeLiteral(getContext().getType(Object.class)).end(); | 1532 builder.startStatement().string(polymorphicTypeName(param.getSpecification().getExecution())).string(" = ").typeLiteral(context.getType(Object.class)).end(); |
1541 | 1533 |
1542 builder.startReturn(); | 1534 builder.startReturn(); |
1543 | 1535 |
1544 CodeTreeBuilder execute = new CodeTreeBuilder(builder); | 1536 CodeTreeBuilder execute = new CodeTreeBuilder(builder); |
1545 execute.startCall("next0", EXECUTE_CHAINED); | 1537 execute.startCall("next0", EXECUTE_CHAINED); |
1546 addInternalValueParameterNames(execute, specialization, polymorphic, param.getLocalName(), true, false, null); | 1538 addInternalValueParameterNames(execute, currentSpecialization, polymorphic, param.getLocalName(), true, false, null); |
1547 execute.end(); | 1539 execute.end(); |
1548 | 1540 |
1549 TypeData sourceType = polymorphic.getReturnType().getTypeSystemType(); | 1541 TypeData sourceType = polymorphic.getReturnType().getTypeSystemType(); |
1550 | 1542 |
1551 builder.tree(createExpectExecutableType(node, sourceType, currentExecutable.hasUnexpectedValue(context), currentExecutable.getType(), execute.getRoot())); | 1543 builder.tree(createExpectExecutableType(node, sourceType, currentExecutable.hasUnexpectedValue(context), currentExecutable.getType(), execute.getRoot())); |
1572 } else { | 1564 } else { |
1573 | 1565 |
1574 if (index < targetExecution.getChild().getExecuteWith().size()) { | 1566 if (index < targetExecution.getChild().getExecuteWith().size()) { |
1575 NodeChildData child = targetExecution.getChild().getExecuteWith().get(index); | 1567 NodeChildData child = targetExecution.getChild().getExecuteWith().get(index); |
1576 | 1568 |
1577 ParameterSpec spec = getModel().getSpecification().findParameterSpec(child.getName()); | 1569 ParameterSpec spec = getSpecialization().getSpecification().findParameterSpec(child.getName()); |
1578 List<Parameter> specializationParams = getModel().findParameters(spec); | 1570 List<Parameter> specializationParams = getSpecialization().findParameters(spec); |
1579 | 1571 |
1580 if (specializationParams.isEmpty()) { | 1572 if (specializationParams.isEmpty()) { |
1581 builder.defaultValue(parameter.getType()); | 1573 builder.defaultValue(parameter.getType()); |
1582 continue; | 1574 continue; |
1583 } | 1575 } |
1588 TypeData sourceType = specializationParam.getTypeSystemType(); | 1580 TypeData sourceType = specializationParam.getTypeSystemType(); |
1589 String localName = specializationParam.getLocalName(); | 1581 String localName = specializationParam.getLocalName(); |
1590 | 1582 |
1591 if (unexpectedParameter != null && unexpectedParameter.getLocalName().equals(specializationParam.getLocalName())) { | 1583 if (unexpectedParameter != null && unexpectedParameter.getLocalName().equals(specializationParam.getLocalName())) { |
1592 localName = "ex.getResult()"; | 1584 localName = "ex.getResult()"; |
1593 sourceType = getModel().getNode().getTypeSystem().getGenericTypeData(); | 1585 sourceType = getSpecialization().getNode().getTypeSystem().getGenericTypeData(); |
1594 } | 1586 } |
1595 | 1587 |
1596 CodeTree value = CodeTreeBuilder.singleString(localName); | 1588 CodeTree value = CodeTreeBuilder.singleString(localName); |
1597 | 1589 |
1598 if (sourceType.needsCastTo(targetType)) { | 1590 if (sourceType.needsCastTo(targetType)) { |
1599 value = createCallTypeSystemMethod(builder, getModel().getNode(), TypeSystemCodeGenerator.asTypeMethodName(targetType), value); | 1591 value = createCallTypeSystemMethod(builder, getSpecialization().getNode(), TypeSystemCodeGenerator.asTypeMethodName(targetType), value); |
1600 } | 1592 } |
1601 builder.tree(value); | 1593 builder.tree(value); |
1602 } else { | 1594 } else { |
1603 builder.defaultValue(parameter.getType()); | 1595 builder.defaultValue(parameter.getType()); |
1604 } | 1596 } |
1609 builder.end(); | 1601 builder.end(); |
1610 | 1602 |
1611 return builder.getRoot(); | 1603 return builder.getRoot(); |
1612 } | 1604 } |
1613 | 1605 |
1614 private CodeTree createShortCircuitTree(CodeTreeBuilder parent, CodeTree body, SpecializationData specialization, Parameter parameter, Parameter exceptionParam) { | 1606 private CodeTree createShortCircuitTree(CodeTreeBuilder parent, CodeTree body, SpecializationData currentSpecialization, Parameter parameter, Parameter exceptionParam) { |
1615 NodeExecutionData execution = parameter.getSpecification().getExecution(); | 1607 NodeExecutionData execution = parameter.getSpecification().getExecution(); |
1616 if (execution == null || !execution.isShortCircuit()) { | 1608 if (execution == null || !execution.isShortCircuit()) { |
1617 return body; | 1609 return body; |
1618 } | 1610 } |
1619 | 1611 |
1620 CodeTreeBuilder builder = new CodeTreeBuilder(parent); | 1612 CodeTreeBuilder builder = new CodeTreeBuilder(parent); |
1621 Parameter shortCircuitParam = specialization.getPreviousParam(parameter); | 1613 Parameter shortCircuitParam = currentSpecialization.getPreviousParam(parameter); |
1622 builder.tree(createShortCircuitValue(builder, specialization, execution, shortCircuitParam, exceptionParam)); | 1614 builder.tree(createShortCircuitValue(builder, currentSpecialization, execution, shortCircuitParam, exceptionParam)); |
1623 builder.declaration(parameter.getType(), valueName(parameter), CodeTreeBuilder.createBuilder().defaultValue(parameter.getType())); | 1615 builder.declaration(parameter.getType(), valueName(parameter), CodeTreeBuilder.createBuilder().defaultValue(parameter.getType())); |
1624 builder.startIf().string(shortCircuitParam.getLocalName()).end(); | 1616 builder.startIf().string(shortCircuitParam.getLocalName()).end(); |
1625 builder.startBlock(); | 1617 builder.startBlock(); |
1626 | 1618 |
1627 if (containsNewLine(body)) { | 1619 if (containsNewLine(body)) { |
1652 builder.end(); // statement | 1644 builder.end(); // statement |
1653 | 1645 |
1654 return builder.getRoot(); | 1646 return builder.getRoot(); |
1655 } | 1647 } |
1656 | 1648 |
1657 protected CodeTree createCallRewriteMonomorphic(CodeTreeBuilder parent, boolean hasUnexpected, TypeData returnType, SpecializationData current, Parameter exceptionParam, String reason) { | 1649 protected CodeTree createCallRewriteMonomorphic(CodeTreeBuilder parent, boolean hasUnexpected, TypeData returnType, Parameter exceptionParam, String reason) { |
1658 NodeData node = current.getNode(); | |
1659 SpecializationData generic = node.getGenericSpecialization(); | 1650 SpecializationData generic = node.getGenericSpecialization(); |
1660 CodeTreeBuilder specializeCall = new CodeTreeBuilder(parent); | 1651 CodeTreeBuilder specializeCall = new CodeTreeBuilder(parent); |
1661 specializeCall.startCall(REWRITE); | 1652 specializeCall.startCall(REWRITE); |
1662 addInternalValueParameterNames(specializeCall, generic, node.getGenericSpecialization(), exceptionParam != null ? exceptionParam.getLocalName() : null, true, false, null); | 1653 addInternalValueParameterNames(specializeCall, generic, node.getGenericSpecialization(), exceptionParam != null ? exceptionParam.getLocalName() : null, true, false, null); |
1663 specializeCall.doubleQuote(reason); | 1654 specializeCall.doubleQuote(reason); |
2012 builder.end(); | 2003 builder.end(); |
2013 return builder.getRoot(); | 2004 return builder.getRoot(); |
2014 } | 2005 } |
2015 | 2006 |
2016 private TypeMirror getUnexpectedValueException() { | 2007 private TypeMirror getUnexpectedValueException() { |
2017 return getContext().getTruffleTypes().getUnexpectedValueException(); | 2008 return context.getTruffleTypes().getUnexpectedValueException(); |
2018 } | 2009 } |
2019 | 2010 |
2020 interface CodeBlock<T> { | 2011 interface CodeBlock<T> { |
2021 | 2012 |
2022 CodeTree create(CodeTreeBuilder parent, T value); | 2013 CodeTree create(CodeTreeBuilder parent, T value); |