# HG changeset patch # User Christian Humer # Date 1385918313 -3600 # Node ID 2b9fcffd6f36ae983f41a1f2e471a236ba7c52cf # Parent 401e1473c54675ca687147f27c24c0c6d3472545 Truffle-DSL: added support for generating execute methods with java varargs. diff -r 401e1473c546 -r 2b9fcffd6f36 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ExecuteEvaluatedTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ExecuteEvaluatedTest.java Sat Nov 30 19:09:55 2013 +0100 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ExecuteEvaluatedTest.java Sun Dec 01 18:18:33 2013 +0100 @@ -26,8 +26,19 @@ import com.oracle.truffle.api.*; import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.*; -import com.oracle.truffle.api.dsl.test.TypeSystemTest.*; +import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.DoubleEvaluatedNodeFactory; +import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.EvaluatedNodeFactory; +import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.TestEvaluatedGenerationFactory; +import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.TestEvaluatedVarArgs0Factory; +import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.TestEvaluatedVarArgs1Factory; +import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.TestEvaluatedVarArgs2Factory; +import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.UseDoubleEvaluatedNodeFactory; +import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.UseEvaluatedNodeFactory; +import com.oracle.truffle.api.dsl.test.TypeSystemTest.ArgumentNode; +import com.oracle.truffle.api.dsl.test.TypeSystemTest.ChildrenNode; +import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestArguments; +import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; +import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; @@ -126,4 +137,70 @@ } } + @Test + public void test0VarArgs1() { + TestRootNode root = TestHelper.createRoot(TestEvaluatedVarArgs0Factory.getInstance()); + Assert.assertEquals(42, root.getNode().execute1(null)); + } + + abstract static class TestEvaluatedVarArgs0 extends ChildrenNode { + + public abstract Object execute1(VirtualFrame frame, Object... value); + + @Specialization + int call() { + return 42; + } + } + + @Test + public void test1VarArgs1() { + TestRootNode root = TestHelper.createRoot(TestEvaluatedVarArgs1Factory.getInstance()); + Assert.assertEquals(42, root.getNode().execute1(null, 42)); + } + + @Test(expected = AssertionError.class) + public void test1VarArgs2() { + TestRootNode root = TestHelper.createRoot(TestEvaluatedVarArgs2Factory.getInstance()); + Assert.assertEquals(-1, root.getNode().execute1(null)); + } + + abstract static class TestEvaluatedVarArgs1 extends ChildrenNode { + + public abstract Object execute1(VirtualFrame frame, Object... value); + + @Specialization + int call(int exp0) { + return exp0; + } + } + + @Test + public void test2VarArgs1() { + TestRootNode root = TestHelper.createRoot(TestEvaluatedVarArgs2Factory.getInstance()); + Assert.assertEquals(42, root.getNode().execute1(null, 21, 21)); + } + + @Test(expected = AssertionError.class) + public void test2VarArgs2() { + TestRootNode root = TestHelper.createRoot(TestEvaluatedVarArgs2Factory.getInstance()); + Assert.assertEquals(-1, root.getNode().execute1(null, 42)); + } + + @Test(expected = AssertionError.class) + public void test2VarArgs3() { + TestRootNode root = TestHelper.createRoot(TestEvaluatedVarArgs2Factory.getInstance()); + Assert.assertEquals(-1, root.getNode().execute1(null)); + } + + abstract static class TestEvaluatedVarArgs2 extends ChildrenNode { + + public abstract Object execute1(VirtualFrame frame, Object... value); + + @Specialization + int call(int exp0, int exp1) { + return exp0 + exp1; + } + } + } diff -r 401e1473c546 -r 2b9fcffd6f36 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeExecutableElement.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeExecutableElement.java Sat Nov 30 19:09:55 2013 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeExecutableElement.java Sun Dec 01 18:18:33 2013 +0100 @@ -113,6 +113,11 @@ return name; } + public CodeTreeBuilder getBuilder() { + CodeTree tree = this.bodyTree; + return createBuilder().tree(tree); + } + public CodeTreeBuilder createBuilder() { CodeTreeBuilder builder = new CodeTreeBuilder(null); this.bodyTree = builder.getTree(); diff -r 401e1473c546 -r 2b9fcffd6f36 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/codewriter/AbstractCodeWriter.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/codewriter/AbstractCodeWriter.java Sat Nov 30 19:09:55 2013 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/codewriter/AbstractCodeWriter.java Sun Dec 01 18:18:33 2013 +0100 @@ -274,16 +274,28 @@ } } } else { + Element enclosing = f.getEnclosingElement(); writeModifiers(f.getModifiers()); - write(useImport(f, f.asType())); - if (f.getEnclosingElement().getKind() == ElementKind.METHOD) { - ExecutableElement method = (ExecutableElement) f.getEnclosingElement(); + boolean varArgs = false; + if (enclosing.getKind() == ElementKind.METHOD) { + ExecutableElement method = (ExecutableElement) enclosing; if (method.isVarArgs() && method.getParameters().indexOf(f) == method.getParameters().size() - 1) { - write("..."); + varArgs = true; } } + TypeMirror varType = f.asType(); + if (varArgs) { + if (varType.getKind() == TypeKind.ARRAY) { + varType = ((ArrayType) varType).getComponentType(); + } + write(useImport(f, varType)); + write("..."); + } else { + write(useImport(f, varType)); + } + write(" "); write(f.getSimpleName()); if (init != null) { diff -r 401e1473c546 -r 2b9fcffd6f36 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java Sat Nov 30 19:09:55 2013 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java Sun Dec 01 18:18:33 2013 +0100 @@ -1015,7 +1015,7 @@ CodeTreeBuilder access = builder.create(); access.string("this.").string(child.getName()); if (child.getCardinality().isMany()) { - access.string("[").string(String.valueOf(param.getIndex())).string("]"); + access.string("[").string(String.valueOf(param.getSpecificationIndex())).string("]"); } String oldName = "old" + Utils.firstLetterUpperCase(param.getLocalName()); @@ -2102,7 +2102,7 @@ return null; } String prefix = expect ? "expect" : "execute"; - return prefix + Utils.firstLetterUpperCase(child.getName()) + Utils.firstLetterUpperCase(Utils.getSimpleName(param.getType())) + param.getIndex(); + return prefix + Utils.firstLetterUpperCase(child.getName()) + Utils.firstLetterUpperCase(Utils.getSimpleName(param.getType())) + param.getSpecificationIndex(); } private List createExecuteChilds(ActualParameter param, Set expectTypes) { @@ -2418,7 +2418,7 @@ throw new AssertionError(); } if (targetParameter.getSpecification().isIndexed()) { - builder.string("[" + targetParameter.getIndex() + "]"); + builder.string("[" + targetParameter.getSpecificationIndex() + "]"); } return builder.getRoot(); } @@ -2729,7 +2729,7 @@ } CodeExecutableElement executeMethod = createExecutableTypeOverride(execType, true); clazz.add(executeMethod); - CodeTreeBuilder builder = executeMethod.createBuilder(); + CodeTreeBuilder builder = executeMethod.getBuilder(); CodeTree result = createExecuteBody(builder, specialization, execType); if (result != null) { builder.tree(result); @@ -2757,7 +2757,7 @@ ExecutableTypeData execType = parser.parse(Arrays.asList(executeCached)).get(0); CodeExecutableElement executeMethod = createExecutableTypeOverride(execType, false); - CodeTreeBuilder builder = executeMethod.createBuilder(); + CodeTreeBuilder builder = executeMethod.getBuilder(); if (specialization.isGeneric() || specialization.isPolymorphic()) { builder.startThrow().startNew(getContext().getType(AssertionError.class)); @@ -2851,15 +2851,43 @@ private CodeExecutableElement createExecutableTypeOverride(ExecutableTypeData execType, boolean evaluated) { CodeExecutableElement method = CodeExecutableElement.clone(getContext().getEnvironment(), execType.getMethod()); + CodeTreeBuilder builder = method.createBuilder(); int i = 0; + int signatureIndex = -1; for (VariableElement param : method.getParameters()) { CodeVariableElement var = CodeVariableElement.clone(param); ActualParameter actualParameter = execType.getParameters().get(i); + if (actualParameter.getSpecification().isSignature()) { + signatureIndex++; + } + + String name; if (evaluated && actualParameter.getSpecification().isSignature()) { - var.setName(valueNameEvaluated(actualParameter)); + name = valueNameEvaluated(actualParameter); } else { - var.setName(valueName(actualParameter)); + name = valueName(actualParameter); } + + int varArgCount = getModel().getSignatureSize() - signatureIndex; + if (evaluated && actualParameter.isVarArgs()) { + ActualParameter baseVarArgs = actualParameter; + name = valueName(baseVarArgs) + "Args"; + + builder.startAssert().string(name).string(" != null").end(); + builder.startAssert().string(name).string(".length == ").string(String.valueOf(varArgCount)).end(); + if (varArgCount > 0) { + List varArgsParameter = execType.getParameters().subList(i, execType.getParameters().size()); + + for (ActualParameter varArg : varArgsParameter) { + TypeMirror type = baseVarArgs.getType(); + if (type.getKind() == TypeKind.ARRAY) { + type = ((ArrayType) type).getComponentType(); + } + builder.declaration(type, valueNameEvaluated(varArg), name + "[" + varArg.getVarArgsIndex() + "]"); + } + } + } + var.setName(name); method.getParameters().set(i, var); i++; } diff -r 401e1473c546 -r 2b9fcffd6f36 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeData.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeData.java Sat Nov 30 19:09:55 2013 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeData.java Sun Dec 01 18:18:33 2013 +0100 @@ -78,6 +78,13 @@ this.assumptions = splitSource.assumptions; } + public int getSignatureSize() { + if (getSpecializations() != null && !getSpecializations().isEmpty()) { + return getSpecializations().get(0).getSignatureSize(); + } + return 0; + } + public boolean needsFrame(ProcessorContext context) { for (SpecializationData specialization : specializations) { if (!specialization.isReachable()) { diff -r 401e1473c546 -r 2b9fcffd6f36 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeParser.java Sat Nov 30 19:09:55 2013 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeParser.java Sun Dec 01 18:18:33 2013 +0100 @@ -205,6 +205,7 @@ finalizeSpecializations(elements, splittedNode); verifyNode(splittedNode, elements); + expandExecutableTypeVarArgs(splittedNode); createPolymorphicSpecializations(splittedNode); assignShortCircuitsToSpecializations(splittedNode); } @@ -217,6 +218,26 @@ return node; } + private static void expandExecutableTypeVarArgs(NodeData node) { + for (ExecutableTypeData executableMethod : node.getExecutableTypes()) { + if (!(executableMethod.getMethod().isVarArgs() && executableMethod.getSpecification().isVariableRequiredArguments())) { + continue; + } + int expandArguments = node.getSignatureSize() - executableMethod.getSignatureSize(); + if (expandArguments > 0) { + int signatureSize = executableMethod.getSignatureSize(); + ActualParameter parameter = executableMethod.getSignatureParameter(signatureSize - 1); + for (int i = 0; i < expandArguments; i++) { + int newVarArgsIndex = parameter.getVarArgsIndex() + i + 1; + int newSpecificationIndex = parameter.getSpecificationIndex() + i + 1; + executableMethod.getParameters().add( + new ActualParameter(parameter.getSpecification(), parameter.getTypeSystemType(), newSpecificationIndex, newVarArgsIndex, parameter.isImplicit())); + } + + } + } + } + private void createPolymorphicSpecializations(NodeData node) { if (!node.needsRewrites(context) || !node.isPolymorphic()) { node.setPolymorphicSpecializations(Collections. emptyList()); diff -r 401e1473c546 -r 2b9fcffd6f36 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationData.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationData.java Sat Nov 30 19:09:55 2013 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationData.java Sun Dec 01 18:18:33 2013 +0100 @@ -261,7 +261,7 @@ if (getParameters().isEmpty() || !Utils.typeEquals(getParameters().get(0).getType(), frameType)) { ParameterSpec frameSpec = getSpecification().findParameterSpec("frame"); if (frameSpec != null) { - getParameters().add(0, new ActualParameter(frameSpec, frameType, -1, false)); + getParameters().add(0, new ActualParameter(frameSpec, frameType, -1, -1, false)); } } } diff -r 401e1473c546 -r 2b9fcffd6f36 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/ActualParameter.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/ActualParameter.java Sat Nov 30 19:09:55 2013 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/ActualParameter.java Sun Dec 01 18:18:33 2013 +0100 @@ -33,49 +33,56 @@ private TypeData typeSystemType; private TemplateMethod method; private final String localName; - private final int index; + private final int specificationIndex; + private final int varArgsIndex; private final boolean implicit; private final TypeMirror type; - public ActualParameter(ParameterSpec specification, TypeMirror actualType, int index, boolean implicit) { + public ActualParameter(ParameterSpec specification, TypeMirror actualType, int specificationIndex, int varArgsIndex, boolean implicit) { this.specification = specification; this.type = actualType; this.typeSystemType = null; - this.index = index; + this.specificationIndex = specificationIndex; this.implicit = implicit; String valueName = specification.getName() + "Value"; if (specification.isIndexed()) { - valueName += index; + valueName += specificationIndex; } + this.varArgsIndex = varArgsIndex; this.localName = valueName; } - public ActualParameter(ParameterSpec specification, TypeData actualType, int index, boolean implicit) { - this(specification, actualType.getPrimitiveType(), index, implicit); + public ActualParameter(ParameterSpec specification, TypeData actualType, int specificationIndex, int varArgsIndex, boolean implicit) { + this(specification, actualType.getPrimitiveType(), specificationIndex, varArgsIndex, implicit); this.typeSystemType = actualType; } public ActualParameter(ActualParameter parameter, TypeData otherType) { - this(parameter.specification, otherType, parameter.index, parameter.implicit); + this(parameter.specification, otherType, parameter.specificationIndex, parameter.varArgsIndex, parameter.implicit); } public ActualParameter(ActualParameter parameter) { this.specification = parameter.specification; this.type = parameter.type; this.typeSystemType = parameter.typeSystemType; - this.index = parameter.index; + this.specificationIndex = parameter.specificationIndex; this.implicit = parameter.implicit; this.localName = parameter.localName; + this.varArgsIndex = parameter.varArgsIndex; + } + + public int getVarArgsIndex() { + return varArgsIndex; } public boolean isImplicit() { return implicit; } - public int getIndex() { - return index; + public int getSpecificationIndex() { + return specificationIndex; } public String getLocalName() { @@ -102,6 +109,10 @@ return typeSystemType; } + public boolean isVarArgs() { + return varArgsIndex >= 0; + } + public ActualParameter getPreviousParameter() { return method.getPreviousParam(this); } diff -r 401e1473c546 -r 2b9fcffd6f36 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MethodSpec.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MethodSpec.java Sat Nov 30 19:09:55 2013 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MethodSpec.java Sun Dec 01 18:18:33 2013 +0100 @@ -37,6 +37,7 @@ private final List optional = new ArrayList<>(); private final List required = new ArrayList<>(); + private int minimumRequiredArguments; private boolean variableRequiredArguments; private List typeDefinitions; @@ -44,6 +45,14 @@ this.returnType = returnType; } + public void setMinimumRequiredArguments(int minimumRequiredArguments) { + this.minimumRequiredArguments = minimumRequiredArguments; + } + + public int getMinimumRequiredArguments() { + return minimumRequiredArguments; + } + public void setVariableRequiredArguments(boolean variableArguments) { this.variableRequiredArguments = variableArguments; } diff -r 401e1473c546 -r 2b9fcffd6f36 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethod.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethod.java Sat Nov 30 19:09:55 2013 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethod.java Sun Dec 01 18:18:33 2013 +0100 @@ -202,6 +202,17 @@ return prev; } + public int getSignatureSize() { + int signatureSize = 0; + for (ActualParameter parameter : getParameters()) { + if (!parameter.getSpecification().isSignature()) { + continue; + } + signatureSize++; + } + return signatureSize; + } + public Signature getSignature() { Signature signature = new Signature(); for (ActualParameter parameter : getReturnTypeAndParameters()) { diff -r 401e1473c546 -r 2b9fcffd6f36 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethodParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethodParser.java Sat Nov 30 19:09:55 2013 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethodParser.java Sun Dec 01 18:18:33 2013 +0100 @@ -140,7 +140,7 @@ ParameterSpec returnTypeSpec = methodSpecification.getReturnType(); - ActualParameter returnTypeMirror = matchParameter(returnTypeSpec, method.getReturnType(), template, 0, false); + ActualParameter returnTypeMirror = matchParameter(returnTypeSpec, method.getReturnType(), template, 0, -1, false); if (returnTypeMirror == null) { if (emitErrors) { E invalidMethod = create(new TemplateMethod(id, template, methodSpecification, method, annotation, returnTypeMirror, Collections. emptyList()), true); @@ -161,7 +161,7 @@ parameterTypes.add(var.asType()); } - List parameters = parseParameters(methodSpecification, parameterTypes); + List parameters = parseParameters(methodSpecification, parameterTypes, method.isVarArgs()); if (parameters == null) { if (isEmitErrors()) { E invalidMethod = create(new TemplateMethod(id, template, methodSpecification, method, annotation, returnTypeMirror, Collections. emptyList()), true); @@ -201,7 +201,7 @@ * ones are cut and used to parse the optional parameters. All those remaining parameters must * be consumed otherwise its an error. */ - private List parseParameters(MethodSpec spec, List parameterTypes) { + private List parseParameters(MethodSpec spec, List parameterTypes, boolean varArgs) { List implicitTypes = spec.getImplicitRequiredTypes(); int offset = -1; @@ -211,7 +211,7 @@ offset++; types = new ConsumableListIterator<>(new ArrayList<>(implicitTypes)); types.data.addAll(parameterTypes.subList(offset, parameterTypes.size())); - parsedRequired = parseParametersRequired(spec, types); + parsedRequired = parseParametersRequired(spec, types, varArgs); } if (parsedRequired == null && offset >= 0) { @@ -244,7 +244,7 @@ int oldIndex = types.getIndex(); int optionalCount = 1; for (ParameterSpec paramspec : optionals) { - ActualParameter optionalParam = matchParameter(paramspec, type, template, 0, false); + ActualParameter optionalParam = matchParameter(paramspec, type, template, 0, -1, false); if (optionalParam != null) { optionals.consume(optionalCount); types.consume(); @@ -264,9 +264,10 @@ return parsedParams; } - private List parseParametersRequired(MethodSpec spec, ConsumableListIterator types) { + private List parseParametersRequired(MethodSpec spec, ConsumableListIterator types, boolean varArgs) { List parsedParams = new ArrayList<>(); + int varArgsParameterIndex = -1; int specificationParameterIndex = 0; ConsumableListIterator required = new ConsumableListIterator<>(spec.getRequired()); while (required.get() != null || types.get() != null) { @@ -278,8 +279,15 @@ } break; } + TypeMirror actualType = types.get(); + if (varArgs && types.isLast()) { + if (actualType.getKind() == TypeKind.ARRAY) { + actualType = ((ArrayType) actualType).getComponentType(); + } + varArgsParameterIndex++; + } boolean implicit = types.getIndex() < spec.getImplicitRequiredTypes().size(); - ActualParameter resolvedParameter = matchParameter(required.get(), types.get(), template, specificationParameterIndex, implicit); + ActualParameter resolvedParameter = matchParameter(required.get(), actualType, template, specificationParameterIndex, varArgsParameterIndex, implicit); if (resolvedParameter == null) { if (required.get().getCardinality() == Cardinality.MANY) { required.consume(); @@ -289,7 +297,16 @@ return null; } else { parsedParams.add(resolvedParameter); - types.consume(); + + if (varArgs && types.isLast()) { + /* Both varargs spec and varargs definition. Need to consume to terminate. */ + if (required.get().getCardinality() == Cardinality.MANY) { + types.consume(); + } + } else { + types.consume(); + } + if (required.get().getCardinality() == Cardinality.ONE) { required.consume(); specificationParameterIndex = 0; @@ -299,7 +316,7 @@ } } - if (!types.toList().isEmpty()) { + if (!types.toList().isEmpty() && !(varArgs && types.isLast())) { // additional types -> error return null; } @@ -311,7 +328,7 @@ return parsedParams; } - private ActualParameter matchParameter(ParameterSpec specification, TypeMirror mirror, Template originalTemplate, int index, boolean implicit) { + private ActualParameter matchParameter(ParameterSpec specification, TypeMirror mirror, Template originalTemplate, int specificationIndex, int varArgsIndex, boolean implicit) { TypeMirror resolvedType = mirror; if (hasError(resolvedType)) { resolvedType = context.resolveNotYetCompiledType(mirror, originalTemplate); @@ -323,9 +340,9 @@ TypeData resolvedTypeData = getTypeSystem().findTypeData(resolvedType); if (resolvedTypeData != null) { - return new ActualParameter(specification, resolvedTypeData, index, implicit); + return new ActualParameter(specification, resolvedTypeData, specificationIndex, varArgsIndex, implicit); } else { - return new ActualParameter(specification, resolvedType, index, implicit); + return new ActualParameter(specification, resolvedType, specificationIndex, varArgsIndex, implicit); } } @@ -346,6 +363,10 @@ return data.get(index); } + public boolean isLast() { + return index == data.size() - 1; + } + public E consume() { return consume(1); } diff -r 401e1473c546 -r 2b9fcffd6f36 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardParser.java Sat Nov 30 19:09:55 2013 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardParser.java Sun Dec 01 18:18:33 2013 +0100 @@ -93,9 +93,11 @@ } else { ActualParameter p; if (parameter.getTypeSystemType() != null) { - p = new ActualParameter(specializationParameter.getSpecification(), parameter.getTypeSystemType(), specializationParameter.getIndex(), parameter.isImplicit()); + p = new ActualParameter(specializationParameter.getSpecification(), parameter.getTypeSystemType(), specializationParameter.getSpecificationIndex(), + specializationParameter.getVarArgsIndex(), parameter.isImplicit()); } else { - p = new ActualParameter(specializationParameter.getSpecification(), parameter.getType(), specializationParameter.getIndex(), parameter.isImplicit()); + p = new ActualParameter(specializationParameter.getSpecification(), parameter.getType(), specializationParameter.getSpecificationIndex(), + specializationParameter.getVarArgsIndex(), parameter.isImplicit()); } newParameters.add(p); }