Mercurial > hg > graal-jvmci-8
diff graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java @ 8251:cb70ed101b5f
Added automatic generation of generic specialization which throws unsupported operation if reached.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Wed, 13 Mar 2013 11:32:43 +0100 |
parents | c4c3f50fa9c2 |
children | 0905d796944a |
line wrap: on
line diff
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java Tue Mar 12 11:38:52 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java Wed Mar 13 11:32:43 2013 +0100 @@ -120,6 +120,10 @@ return null; // not a node } + if (type.getModifiers().contains(Modifier.PRIVATE)) { + return null; // not visible + } + TypeElement nodeType; boolean needsSplit; if (methodNodes != null) { @@ -130,10 +134,6 @@ nodeType = type; } - if (type.getModifiers().contains(Modifier.PRIVATE)) { - return null; // not visible - } - NodeData nodeData = parseNodeData(type, nodeType); if (nodeData == null) { return null; @@ -271,28 +271,63 @@ } } + if (generics.size() == 1 && specializations.size() == 1) { + for (SpecializationData generic : generics) { + log.error(generic.getMethod(), "@%s defined but no @%s.", Generic.class.getSimpleName(), Specialization.class.getSimpleName()); + } + } + SpecializationData genericSpecialization = null; if (generics.size() > 1) { for (SpecializationData generic : generics) { - log.error(generic.getMethod(), "Only one method with @%s is allowed per operation.", Generic.class.getSimpleName()); + log.error(generic.getMethod(), "Only @%s is allowed per operation.", Generic.class.getSimpleName()); } return false; } else if (generics.size() == 1) { genericSpecialization = generics.get(0); - } else { - // TODO support generation of generic if not ambiguous. - } + if (!node.needsRewrites(context)) { + log.error(genericSpecialization.getMethod(), "Generic specialization is not reachable.", Generic.class.getSimpleName()); + return false; + } + } else if (node.needsRewrites(context)) { + SpecializationData specialization = specializations.get(0); + GenericParser parser = new GenericParser(context, node); + MethodSpec specification = parser.createDefaultMethodSpec(specialization.getMethod(), null, null); + + ExecutableTypeData anyGenericReturnType = node.findAnyGenericExecutableType(context); + if (anyGenericReturnType == null) { + // TODO fail invalid executable type. should be validated by field. (assertion +// failure!?) + } - if (specializations.size() > 1 && genericSpecialization == null) { - log.error(node.getTemplateType(), "Need a @%s method.", Generic.class.getSimpleName()); - return false; + ActualParameter returnType = new ActualParameter(specification.getReturnType(), anyGenericReturnType.getType().getPrimitiveType(), 0, false); + List<ActualParameter> parameters = new ArrayList<>(); + for (ActualParameter specializationParameter : specialization.getParameters()) { + ParameterSpec parameterSpec = specification.findParameterSpec(specializationParameter.getSpecification().getName()); + NodeFieldData field = node.findField(parameterSpec.getName()); + TypeMirror actualType; + if (field == null) { + actualType = specializationParameter.getActualType(); + } else { + ExecutableTypeData paramType = field.getNodeData().findAnyGenericExecutableType(context); + if (paramType == null) { + // TODO fail + } + actualType = paramType.getType().getPrimitiveType(); + } + parameters.add(new ActualParameter(parameterSpec, actualType, specializationParameter.getIndex(), specializationParameter.isHidden())); + } + TemplateMethod genericMethod = new TemplateMethod("Generic", node, specification, null, null, returnType, parameters); + genericSpecialization = new SpecializationData(genericMethod, true, false, true); + + specializations.add(genericSpecialization); } if (genericSpecialization != null) { CodeExecutableElement uninitializedMethod = new CodeExecutableElement(Utils.modifiers(Modifier.PUBLIC), context.getType(void.class), "doUninitialized"); - TemplateMethod uninializedMethod = new TemplateMethod(genericSpecialization.getId(), node, genericSpecialization.getSpecification(), uninitializedMethod, - genericSpecialization.getMarkerAnnotation(), genericSpecialization.getReturnType(), genericSpecialization.getParameters()); - specializations.add(new SpecializationData(uninializedMethod, false, true)); + TemplateMethod uninializedMethod = new TemplateMethod("Uninitialized", node, genericSpecialization.getSpecification(), uninitializedMethod, genericSpecialization.getMarkerAnnotation(), + genericSpecialization.getReturnType(), genericSpecialization.getParameters()); + specializations.add(new SpecializationData(uninializedMethod, false, true, true)); } Collections.sort(specializations, new Comparator<SpecializationData>() {