comparison graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeParser.java @ 19291:f4792a544170

Truffle-DSL: implement new assumptions semantics.
author Christian Humer <christian.humer@gmail.com>
date Wed, 11 Feb 2015 12:13:44 +0100
parents 62c43fcf5be2
children 906367e494ca
comparison
equal deleted inserted replaced
19290:bf166845c7d8 19291:f4792a544170
28 import javax.lang.model.element.*; 28 import javax.lang.model.element.*;
29 import javax.lang.model.type.*; 29 import javax.lang.model.type.*;
30 import javax.lang.model.util.*; 30 import javax.lang.model.util.*;
31 import javax.tools.Diagnostic.Kind; 31 import javax.tools.Diagnostic.Kind;
32 32
33 import com.oracle.truffle.api.*;
33 import com.oracle.truffle.api.dsl.*; 34 import com.oracle.truffle.api.dsl.*;
34 import com.oracle.truffle.api.nodes.*; 35 import com.oracle.truffle.api.nodes.*;
35 import com.oracle.truffle.dsl.processor.*; 36 import com.oracle.truffle.dsl.processor.*;
36 import com.oracle.truffle.dsl.processor.expression.*; 37 import com.oracle.truffle.dsl.processor.expression.*;
37 import com.oracle.truffle.dsl.processor.java.*; 38 import com.oracle.truffle.dsl.processor.java.*;
38 import com.oracle.truffle.dsl.processor.java.compiler.*; 39 import com.oracle.truffle.dsl.processor.java.compiler.*;
40 import com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror;
39 import com.oracle.truffle.dsl.processor.java.model.*; 41 import com.oracle.truffle.dsl.processor.java.model.*;
40 import com.oracle.truffle.dsl.processor.model.*; 42 import com.oracle.truffle.dsl.processor.model.*;
41 import com.oracle.truffle.dsl.processor.model.NodeChildData.Cardinality; 43 import com.oracle.truffle.dsl.processor.model.NodeChildData.Cardinality;
42 import com.oracle.truffle.dsl.processor.model.SpecializationData.SpecializationKind; 44 import com.oracle.truffle.dsl.processor.model.SpecializationData.SpecializationKind;
43 import com.oracle.truffle.dsl.processor.model.TemplateMethod.TypeSignature; 45 import com.oracle.truffle.dsl.processor.model.TemplateMethod.TypeSignature;
134 if (!containsSpecializations(members)) { 136 if (!containsSpecializations(members)) {
135 return null; 137 return null;
136 } 138 }
137 139
138 NodeData node = parseNodeData(templateType, lookupTypes); 140 NodeData node = parseNodeData(templateType, lookupTypes);
139 141 if (node.hasErrors()) {
140 node.getAssumptions().addAll(parseAssumptions(lookupTypes)); 142 return node;
143 }
144
141 node.getFields().addAll(parseFields(lookupTypes, members)); 145 node.getFields().addAll(parseFields(lookupTypes, members));
142 node.getChildren().addAll(parseChildren(lookupTypes, members)); 146 node.getChildren().addAll(parseChildren(lookupTypes, members));
143 node.getChildExecutions().addAll(parseExecutions(node.getChildren(), members)); 147 node.getChildExecutions().addAll(parseExecutions(node.getChildren(), members));
144 node.setExecutableTypes(groupExecutableTypes(new ExecutableTypeMethodParser(context, node, context.getFrameTypes()).parse(members))); 148 node.setExecutableTypes(groupExecutableTypes(new ExecutableTypeMethodParser(context, node, context.getFrameTypes()).parse(members)));
145 149
271 shortName = ElementUtils.getAnnotationValue(String.class, nodeInfoMirror, "shortName"); 275 shortName = ElementUtils.getAnnotationValue(String.class, nodeInfoMirror, "shortName");
272 } 276 }
273 boolean useNodeFactory = findFirstAnnotation(typeHierarchy, GenerateNodeFactory.class) != null; 277 boolean useNodeFactory = findFirstAnnotation(typeHierarchy, GenerateNodeFactory.class) != null;
274 return new NodeData(context, templateType, shortName, typeSystem, useNodeFactory); 278 return new NodeData(context, templateType, shortName, typeSystem, useNodeFactory);
275 279
276 }
277
278 private List<String> parseAssumptions(List<TypeElement> typeHierarchy) {
279 List<String> assumptionsList = new ArrayList<>();
280 for (int i = typeHierarchy.size() - 1; i >= 0; i--) {
281 TypeElement type = typeHierarchy.get(i);
282 AnnotationMirror assumptions = ElementUtils.findAnnotationMirror(context.getEnvironment(), type, NodeAssumptions.class);
283 if (assumptions != null) {
284 List<String> assumptionStrings = ElementUtils.getAnnotationValueList(String.class, assumptions, "value");
285 for (String string : assumptionStrings) {
286 if (assumptionsList.contains(string)) {
287 assumptionsList.remove(string);
288 }
289 assumptionsList.add(string);
290 }
291 }
292 }
293 return assumptionsList;
294 } 280 }
295 281
296 private List<NodeFieldData> parseFields(List<TypeElement> typeHierarchy, List<? extends Element> elements) { 282 private List<NodeFieldData> parseFields(List<TypeElement> typeHierarchy, List<? extends Element> elements) {
297 Set<String> names = new HashSet<>(); 283 Set<String> names = new HashSet<>();
298 284
560 for (ExecutableTypeData execute : allExecutes) { 546 for (ExecutableTypeData execute : allExecutes) {
561 evaluatedCounts.add(execute.getEvaluatedCount()); 547 evaluatedCounts.add(execute.getEvaluatedCount());
562 548
563 Parameter frame = execute.getFrame(); 549 Parameter frame = execute.getFrame();
564 TypeMirror resolvedFrameType; 550 TypeMirror resolvedFrameType;
565 if (frame == null) { 551 if (frame != null) {
566 resolvedFrameType = node.getTypeSystem().getVoidType().getPrimitiveType();
567 } else {
568 resolvedFrameType = frame.getType(); 552 resolvedFrameType = frame.getType();
569 } 553 if (frameType == null) {
570 554 frameType = resolvedFrameType;
571 if (frameType == null) { 555 } else if (!ElementUtils.typeEquals(frameType, resolvedFrameType)) {
572 frameType = resolvedFrameType;
573 } else {
574 if (!ElementUtils.typeEquals(frameType, resolvedFrameType)) {
575 // found inconsistent frame types 556 // found inconsistent frame types
576 inconsistentFrameTypes.add(ElementUtils.getSimpleName(frameType)); 557 inconsistentFrameTypes.add(ElementUtils.getSimpleName(frameType));
577 inconsistentFrameTypes.add(ElementUtils.getSimpleName(resolvedFrameType)); 558 inconsistentFrameTypes.add(ElementUtils.getSimpleName(resolvedFrameType));
578 } 559 }
579 } 560 }
582 // ensure they are sorted somehow 563 // ensure they are sorted somehow
583 List<String> inconsistentFrameTypesList = new ArrayList<>(inconsistentFrameTypes); 564 List<String> inconsistentFrameTypesList = new ArrayList<>(inconsistentFrameTypes);
584 Collections.sort(inconsistentFrameTypesList); 565 Collections.sort(inconsistentFrameTypesList);
585 node.addError("Invalid inconsistent frame types %s found for the declared execute methods. The frame type must be identical for all execute methods.", inconsistentFrameTypesList); 566 node.addError("Invalid inconsistent frame types %s found for the declared execute methods. The frame type must be identical for all execute methods.", inconsistentFrameTypesList);
586 } 567 }
568 if (frameType == null) {
569 frameType = context.getType(void.class);
570 }
571
587 node.setFrameType(frameType); 572 node.setFrameType(frameType);
588 573
589 int totalGenericCount = 0; 574 int totalGenericCount = 0;
590 int totalVoidCount = 0; 575 int totalVoidCount = 0;
591 for (Integer evaluatedCount : evaluatedCounts) { 576 for (Integer evaluatedCount : evaluatedCounts) {
977 initializeGuards(specialization, resolver); 962 initializeGuards(specialization, resolver);
978 if (specialization.hasErrors()) { 963 if (specialization.hasErrors()) {
979 continue; 964 continue;
980 } 965 }
981 initializeLimit(specialization, resolver); 966 initializeLimit(specialization, resolver);
982 } 967 initializeAssumptions(specialization, resolver);
968 }
969 }
970
971 private void initializeAssumptions(SpecializationData specialization, DSLExpressionResolver resolver) {
972 final DeclaredType assumptionType = context.getDeclaredType(Assumption.class);
973 final TypeMirror assumptionArrayType = new ArrayCodeTypeMirror(assumptionType);
974 final List<String> assumptionDefinitions = ElementUtils.getAnnotationValueList(String.class, specialization.getMarkerAnnotation(), "assumptions");
975 List<AssumptionExpression> assumptionExpressions = new ArrayList<>();
976 int assumptionId = 0;
977 for (String assumption : assumptionDefinitions) {
978 AssumptionExpression assumptionExpression;
979 DSLExpression expression = null;
980 try {
981 expression = DSLExpression.parse(assumption);
982 expression.accept(resolver);
983 assumptionExpression = new AssumptionExpression(specialization, expression, "assumption" + assumptionId);
984 if (!ElementUtils.isAssignable(expression.getResolvedType(), assumptionType) && !ElementUtils.isAssignable(expression.getResolvedType(), assumptionArrayType)) {
985 assumptionExpression.addError("Incompatible return type %s. Assumptions must be assignable to %s or %s.", ElementUtils.getSimpleName(expression.getResolvedType()),
986 ElementUtils.getSimpleName(assumptionType), ElementUtils.getSimpleName(assumptionArrayType));
987 }
988 if (specialization.isDynamicParameterBound(expression)) {
989 specialization.addError("Assumption expressions must not bind dynamic parameter values.");
990 }
991 } catch (InvalidExpressionException e) {
992 assumptionExpression = new AssumptionExpression(specialization, null, "assumption" + assumptionId);
993 assumptionExpression.addError("Error parsing expression '%s': %s", assumption, e.getMessage());
994 }
995 assumptionExpressions.add(assumptionExpression);
996 }
997 specialization.setAssumptionExpressions(assumptionExpressions);
983 } 998 }
984 999
985 private void initializeLimit(SpecializationData specialization, DSLExpressionResolver resolver) { 1000 private void initializeLimit(SpecializationData specialization, DSLExpressionResolver resolver) {
986 AnnotationValue annotationValue = ElementUtils.getAnnotationValue(specialization.getMessageAnnotation(), "limit"); 1001 AnnotationValue annotationValue = ElementUtils.getAnnotationValue(specialization.getMessageAnnotation(), "limit");
987 1002