# HG changeset patch # User Christian Humer # Date 1420815775 -3600 # Node ID 121748e43a01d4ab3317844c692d9b28d4384439 # Parent 07b61dff860fc01787961675b8e3bfc75d92fc88 Truffle-DSL: fix execute methods with evaluated arguments were not handled correctly with varargs arguments. diff -r 07b61dff860f -r 121748e43a01 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeGenFactory.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeGenFactory.java Fri Jan 09 16:01:11 2015 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeGenFactory.java Fri Jan 09 16:02:55 2015 +0100 @@ -61,6 +61,7 @@ private final TypeData genericType; private final DSLOptions options; private final boolean singleSpecializable; + private final int varArgsThreshold; public NodeGenFactory(ProcessorContext context, NodeData node) { this.context = context; @@ -69,6 +70,21 @@ this.genericType = typeSystem.getGenericTypeData(); this.options = typeSystem.getOptions(); this.singleSpecializable = isSingleSpecializableImpl(); + this.varArgsThreshold = calculateVarArgsThresHold(); + + } + + private int calculateVarArgsThresHold() { + TypeMirror specialization = context.getType(SpecializationNode.class); + TypeElement specializationType = fromTypeMirror(specialization); + + int maxParameters = 0; + for (ExecutableElement element : ElementFilter.methodsIn(specializationType.getEnclosedElements())) { + if (element.getSimpleName().contentEquals("acceptAndExecute")) { + maxParameters = Math.max(maxParameters, element.getParameters().size()); + } + } + return maxParameters; } public static String nodeTypeName(NodeData node) { @@ -760,16 +776,22 @@ final TypeData executedType = execType.getEvaluatedCount() > 0 ? null : returnType; CodeExecutableElement method = cloneExecutableTypeOverride(execType, varArgsName); - LocalContext locals = LocalContext.load(this, execType.getSignatureSize()); + LocalContext locals = LocalContext.load(this, execType.getSignatureSize(), Integer.MAX_VALUE); // rename varargs parameter int signatureIndex = 0; for (Parameter parameter : execType.getSignatureParameters()) { - if (parameter.isTypeVarArgs()) { - String newName = varArgsName + "[" + parameter.getTypeVarArgsIndex() + "]"; - NodeExecutionData execution = node.getChildExecutions().get(signatureIndex); - locals.setValue(execution, locals.getValue(execution).accessWith(CodeTreeBuilder.singleString(newName))); + LocalVariable var = locals.get(parameter, signatureIndex); + if (var != null) { + if (parameter.isTypeVarArgs()) { + var = var.accessWith(CodeTreeBuilder.singleString(varArgsName + "[" + parameter.getTypeVarArgsIndex() + "]")); + } + if (!parameter.getTypeSystemType().isGeneric()) { + var = var.newType(parameter.getTypeSystemType()); + } + locals.setValue(node.getChildExecutions().get(signatureIndex), var); } + signatureIndex++; } @@ -1276,7 +1298,7 @@ private Element createFastPathExecuteMethod(SpecializationData specialization, final TypeData forType, int evaluatedArguments) { TypeData type = forType == null ? genericType : forType; - LocalContext currentLocals = LocalContext.load(this, evaluatedArguments); + LocalContext currentLocals = LocalContext.load(this, evaluatedArguments, varArgsThreshold); CodeExecutableElement executable = currentLocals.createMethod(modifiers(PUBLIC), type.getPrimitiveType(), TypeSystemNodeFactory.executeName(forType), FRAME_VALUE); executable.getAnnotationMirrors().add(new CodeAnnotationMirror(context.getDeclaredType(Override.class))); @@ -1534,7 +1556,7 @@ } private CodeExecutableElement createExecuteChildMethod(NodeExecutionData execution, TypeData targetType) { - LocalContext locals = LocalContext.load(this, 0); + LocalContext locals = LocalContext.load(this, 0, varArgsThreshold); CodeExecutableElement method = locals.createMethod(modifiers(PROTECTED, FINAL), targetType.getPrimitiveType(), executeChildMethodName(execution, targetType), FRAME_VALUE); if (hasUnexpectedResult(execution, targetType)) { @@ -1891,9 +1913,7 @@ } LocalVariable genericValue = target.makeGeneric().nextName(); - LocalVariable genericShortCircuit = resolveShortCircuit(null, execution, currentValues); - - builder.tree(createAssignExecuteChild(execution, genericValue.getType(), genericValue, genericShortCircuit, currentValues)); + builder.tree(createAssignExecuteChild(execution, genericValue.getType(), genericValue, null, currentValues)); if (executableTypes.size() == sourceTypes.size()) { builder.startThrow().startNew(getType(UnexpectedResultException.class)).tree(genericValue.createReference()).end().end(); } else { @@ -2026,14 +2046,14 @@ return method; } - public static LocalContext load(NodeGenFactory factory, int signatureSize) { + public static LocalContext load(NodeGenFactory factory, int signatureSize, int varargsThreshold) { LocalContext context = new LocalContext(factory); - context.loadValues(signatureSize); + context.loadValues(signatureSize, varargsThreshold); return context; } public static LocalContext load(NodeGenFactory factory) { - return load(factory, factory.node.getSignatureSize()); + return load(factory, factory.node.getSignatureSize(), factory.varArgsThreshold); } public LocalContext copy() { @@ -2075,8 +2095,11 @@ LocalVariable var = get(parameter.getLocalName()); if (var == null && parameter.getSpecification().isSignature()) { // lookup by signature index for executeWith - NodeExecutionData execution = factory.node.getChildExecutions().get(signatureIndex); - var = getValue(execution); + List childExecutions = factory.node.getChildExecutions(); + if (signatureIndex < childExecutions.size() && signatureIndex >= 0) { + NodeExecutionData execution = childExecutions.get(signatureIndex); + var = getValue(execution); + } } return var; } @@ -2104,7 +2127,7 @@ values.put(shortCircuitName(execution), var); } - private boolean needsVarargs(boolean requireLoaded) { + private boolean needsVarargs(boolean requireLoaded, int varArgsThreshold) { int size = 0; for (NodeExecutionData execution : factory.node.getChildExecutions()) { if (requireLoaded && getValue(execution) == null) { @@ -2116,10 +2139,10 @@ size++; } } - return size > 4; + return size >= varArgsThreshold; } - private void loadValues(int evaluatedArguments) { + private void loadValues(int evaluatedArguments, int varargsThreshold) { values.put(FRAME_VALUE, new LocalVariable(null, factory.getType(Frame.class), FRAME_VALUE, null)); for (NodeFieldData field : factory.node.getFields()) { @@ -2127,9 +2150,13 @@ values.put(fieldName, new LocalVariable(null, field.getType(), fieldName, factory.accessParent(field.getName()))); } - boolean varargs = needsVarargs(false); + boolean varargs = needsVarargs(false, varargsThreshold); for (int i = 0; i < evaluatedArguments; i++) { - NodeExecutionData execution = factory.node.getChildExecutions().get(i); + List childExecutions = factory.node.getChildExecutions(); + if (i >= childExecutions.size()) { + break; + } + NodeExecutionData execution = childExecutions.get(i); if (execution.isShortCircuit()) { LocalVariable shortCircuit = createShortCircuitValue(execution).makeGeneric(); if (varargs) { @@ -2187,7 +2214,7 @@ method.addParameter(local.createParameter()); } } - if (needsVarargs(true)) { + if (needsVarargs(true, factory.varArgsThreshold)) { method.addParameter(new CodeVariableElement(factory.getType(Object[].class), "args_")); method.setVarArgs(true); } else { diff -r 07b61dff860f -r 121748e43a01 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/ElementUtils.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/ElementUtils.java Fri Jan 09 16:01:11 2015 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/ElementUtils.java Fri Jan 09 16:02:55 2015 +0100 @@ -1079,4 +1079,42 @@ return new DeclaredCodeTypeMirror((TypeElement) declaredType.asElement()); } + public static ExecutableElement findMethod(TypeElement type, Set includeModifiers, Set excludeModifiers, String methodName, List types) { + outer: for (ExecutableElement executable : ElementFilter.methodsIn(type.getEnclosedElements())) { + if (includeModifiers != null) { + if (!executable.getModifiers().containsAll(includeModifiers)) { + continue; + } + } + if (excludeModifiers != null) { + if (executable.getModifiers().containsAll(excludeModifiers)) { + continue; + } + } + if (!executable.getSimpleName().toString().equals(methodName)) { + continue; + } + if (types.size() != executable.getParameters().size()) { + continue; + } + for (int i = 0; i < types.size(); i++) { + TypeMirror var1 = types.get(i); + VariableElement var2 = executable.getParameters().get(i); + if (ElementUtils.typeEquals(var1, var2.asType())) { + continue outer; + } + } + return executable; + } + return null; + } + + public static List asTypes(List elements) { + List types = new ArrayList<>(elements.size()); + for (Element element : elements) { + types.add(element.asType()); + } + return types; + } + }