comparison graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java @ 13271:2b9fcffd6f36

Truffle-DSL: added support for generating execute methods with java varargs.
author Christian Humer <christian.humer@gmail.com>
date Sun, 01 Dec 2013 18:18:33 +0100
parents 9b23caa3ad31
children 0b8335a4fb13
comparison
equal deleted inserted replaced
13203:401e1473c546 13271:2b9fcffd6f36
1013 NodeChildData child = getModel().getNode().findChild(param.getSpecification().getName()); 1013 NodeChildData child = getModel().getNode().findChild(param.getSpecification().getName());
1014 1014
1015 CodeTreeBuilder access = builder.create(); 1015 CodeTreeBuilder access = builder.create();
1016 access.string("this.").string(child.getName()); 1016 access.string("this.").string(child.getName());
1017 if (child.getCardinality().isMany()) { 1017 if (child.getCardinality().isMany()) {
1018 access.string("[").string(String.valueOf(param.getIndex())).string("]"); 1018 access.string("[").string(String.valueOf(param.getSpecificationIndex())).string("]");
1019 } 1019 }
1020 1020
1021 String oldName = "old" + Utils.firstLetterUpperCase(param.getLocalName()); 1021 String oldName = "old" + Utils.firstLetterUpperCase(param.getLocalName());
1022 oldBuilder.declaration(child.getNodeData().getNodeType(), oldName, access); 1022 oldBuilder.declaration(child.getNodeData().getNodeType(), oldName, access);
1023 nullBuilder.startStatement().tree(access.getRoot()).string(" = null").end(); 1023 nullBuilder.startStatement().tree(access.getRoot()).string(" = null").end();
2100 List<TypeData> sourceTypes = child.getNodeData().getTypeSystem().lookupSourceTypes(param.getTypeSystemType()); 2100 List<TypeData> sourceTypes = child.getNodeData().getTypeSystem().lookupSourceTypes(param.getTypeSystemType());
2101 if (sourceTypes.size() <= 1) { 2101 if (sourceTypes.size() <= 1) {
2102 return null; 2102 return null;
2103 } 2103 }
2104 String prefix = expect ? "expect" : "execute"; 2104 String prefix = expect ? "expect" : "execute";
2105 return prefix + Utils.firstLetterUpperCase(child.getName()) + Utils.firstLetterUpperCase(Utils.getSimpleName(param.getType())) + param.getIndex(); 2105 return prefix + Utils.firstLetterUpperCase(child.getName()) + Utils.firstLetterUpperCase(Utils.getSimpleName(param.getType())) + param.getSpecificationIndex();
2106 } 2106 }
2107 2107
2108 private List<CodeExecutableElement> createExecuteChilds(ActualParameter param, Set<TypeData> expectTypes) { 2108 private List<CodeExecutableElement> createExecuteChilds(ActualParameter param, Set<TypeData> expectTypes) {
2109 CodeExecutableElement executeMethod = createExecuteChild(param, null); 2109 CodeExecutableElement executeMethod = createExecuteChild(param, null);
2110 if (executeMethod == null) { 2110 if (executeMethod == null) {
2416 builder.string("this.").string(accessElement.getSimpleName().toString()); 2416 builder.string("this.").string(accessElement.getSimpleName().toString());
2417 } else { 2417 } else {
2418 throw new AssertionError(); 2418 throw new AssertionError();
2419 } 2419 }
2420 if (targetParameter.getSpecification().isIndexed()) { 2420 if (targetParameter.getSpecification().isIndexed()) {
2421 builder.string("[" + targetParameter.getIndex() + "]"); 2421 builder.string("[" + targetParameter.getSpecificationIndex() + "]");
2422 } 2422 }
2423 return builder.getRoot(); 2423 return builder.getRoot();
2424 } 2424 }
2425 2425
2426 private CodeTree createShortCircuitTree(CodeTreeBuilder parent, CodeTree body, SpecializationData specialization, ActualParameter parameter, ActualParameter exceptionParam) { 2426 private CodeTree createShortCircuitTree(CodeTreeBuilder parent, CodeTree body, SpecializationData specialization, ActualParameter parameter, ActualParameter exceptionParam) {
2727 if (execType.isFinal()) { 2727 if (execType.isFinal()) {
2728 continue; 2728 continue;
2729 } 2729 }
2730 CodeExecutableElement executeMethod = createExecutableTypeOverride(execType, true); 2730 CodeExecutableElement executeMethod = createExecutableTypeOverride(execType, true);
2731 clazz.add(executeMethod); 2731 clazz.add(executeMethod);
2732 CodeTreeBuilder builder = executeMethod.createBuilder(); 2732 CodeTreeBuilder builder = executeMethod.getBuilder();
2733 CodeTree result = createExecuteBody(builder, specialization, execType); 2733 CodeTree result = createExecuteBody(builder, specialization, execType);
2734 if (result != null) { 2734 if (result != null) {
2735 builder.tree(result); 2735 builder.tree(result);
2736 } else { 2736 } else {
2737 clazz.remove(executeMethod); 2737 clazz.remove(executeMethod);
2755 2755
2756 ExecutableTypeMethodParser parser = new ExecutableTypeMethodParser(getContext(), node); 2756 ExecutableTypeMethodParser parser = new ExecutableTypeMethodParser(getContext(), node);
2757 ExecutableTypeData execType = parser.parse(Arrays.asList(executeCached)).get(0); 2757 ExecutableTypeData execType = parser.parse(Arrays.asList(executeCached)).get(0);
2758 2758
2759 CodeExecutableElement executeMethod = createExecutableTypeOverride(execType, false); 2759 CodeExecutableElement executeMethod = createExecutableTypeOverride(execType, false);
2760 CodeTreeBuilder builder = executeMethod.createBuilder(); 2760 CodeTreeBuilder builder = executeMethod.getBuilder();
2761 2761
2762 if (specialization.isGeneric() || specialization.isPolymorphic()) { 2762 if (specialization.isGeneric() || specialization.isPolymorphic()) {
2763 builder.startThrow().startNew(getContext().getType(AssertionError.class)); 2763 builder.startThrow().startNew(getContext().getType(AssertionError.class));
2764 builder.doubleQuote("Should not be reached."); 2764 builder.doubleQuote("Should not be reached.");
2765 builder.end().end(); 2765 builder.end().end();
2849 } 2849 }
2850 2850
2851 private CodeExecutableElement createExecutableTypeOverride(ExecutableTypeData execType, boolean evaluated) { 2851 private CodeExecutableElement createExecutableTypeOverride(ExecutableTypeData execType, boolean evaluated) {
2852 CodeExecutableElement method = CodeExecutableElement.clone(getContext().getEnvironment(), execType.getMethod()); 2852 CodeExecutableElement method = CodeExecutableElement.clone(getContext().getEnvironment(), execType.getMethod());
2853 2853
2854 CodeTreeBuilder builder = method.createBuilder();
2854 int i = 0; 2855 int i = 0;
2856 int signatureIndex = -1;
2855 for (VariableElement param : method.getParameters()) { 2857 for (VariableElement param : method.getParameters()) {
2856 CodeVariableElement var = CodeVariableElement.clone(param); 2858 CodeVariableElement var = CodeVariableElement.clone(param);
2857 ActualParameter actualParameter = execType.getParameters().get(i); 2859 ActualParameter actualParameter = execType.getParameters().get(i);
2860 if (actualParameter.getSpecification().isSignature()) {
2861 signatureIndex++;
2862 }
2863
2864 String name;
2858 if (evaluated && actualParameter.getSpecification().isSignature()) { 2865 if (evaluated && actualParameter.getSpecification().isSignature()) {
2859 var.setName(valueNameEvaluated(actualParameter)); 2866 name = valueNameEvaluated(actualParameter);
2860 } else { 2867 } else {
2861 var.setName(valueName(actualParameter)); 2868 name = valueName(actualParameter);
2862 } 2869 }
2870
2871 int varArgCount = getModel().getSignatureSize() - signatureIndex;
2872 if (evaluated && actualParameter.isVarArgs()) {
2873 ActualParameter baseVarArgs = actualParameter;
2874 name = valueName(baseVarArgs) + "Args";
2875
2876 builder.startAssert().string(name).string(" != null").end();
2877 builder.startAssert().string(name).string(".length == ").string(String.valueOf(varArgCount)).end();
2878 if (varArgCount > 0) {
2879 List<ActualParameter> varArgsParameter = execType.getParameters().subList(i, execType.getParameters().size());
2880
2881 for (ActualParameter varArg : varArgsParameter) {
2882 TypeMirror type = baseVarArgs.getType();
2883 if (type.getKind() == TypeKind.ARRAY) {
2884 type = ((ArrayType) type).getComponentType();
2885 }
2886 builder.declaration(type, valueNameEvaluated(varArg), name + "[" + varArg.getVarArgsIndex() + "]");
2887 }
2888 }
2889 }
2890 var.setName(name);
2863 method.getParameters().set(i, var); 2891 method.getParameters().set(i, var);
2864 i++; 2892 i++;
2865 } 2893 }
2866 2894
2867 method.getAnnotationMirrors().clear(); 2895 method.getAnnotationMirrors().clear();