Mercurial > hg > truffle
diff graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeGenFactory.java @ 20984:6361fa2e3321
Truffle-DSL: further fixes for polymorphic execute signatures.
author | Christian Humer <christian.humer@oracle.com> |
---|---|
date | Wed, 15 Apr 2015 21:13:43 +0200 |
parents | 05a2b72c071f |
children | ef2825da2e43 |
line wrap: on
line diff
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeGenFactory.java Wed Apr 15 21:35:51 2015 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeGenFactory.java Wed Apr 15 21:13:43 2015 +0200 @@ -66,7 +66,9 @@ private final boolean singleSpecializable; private final int varArgsThreshold; private final Set<TypeMirror> expectedTypes = new HashSet<>(); + private final Set<NodeExecutionData> usedExecuteChildMethods = new HashSet<>(); private boolean nextUsed; + private List<ExecutableTypeData> usedTypes; private List<SpecializationData> reachableSpecializations; @@ -210,7 +212,7 @@ } for (ExecutableTypeData execType : usedTypes) { - if (execType.getMethod() == null) { + if (!singleSpecializable && execType.getMethod() == null) { continue; } clazz.add(createExecutableTypeOverride(usedTypes, execType)); @@ -273,7 +275,7 @@ private Element createUnsupportedMethod() { LocalContext locals = LocalContext.load(this); - CodeExecutableElement method = locals.createMethod(modifiers(PROTECTED), getType(UnsupportedSpecializationException.class), "unsupported"); + CodeExecutableElement method = locals.createMethod(modifiers(PROTECTED), getType(UnsupportedSpecializationException.class), "unsupported", varArgsThreshold); CodeTreeBuilder builder = method.createBuilder(); builder.startReturn(); @@ -380,6 +382,16 @@ baseSpecialization.addOptional(createCreatePolymorphic(generated)); baseSpecialization.addOptional(createGetNext(baseSpecialization)); + for (NodeExecutionData execution : node.getChildExecutions()) { + Collection<TypeMirror> specializedTypes = node.findSpecializedTypes(execution); + specializedTypes.add(genericType); + for (TypeMirror specializedType : specializedTypes) { + if (isExecuteChildShared(execution, specializedType)) { + baseSpecialization.addOptional(createExecuteChildMethod(execution, specializedType)); + } + } + } + return node.getUninitializedSpecialization(); } @@ -418,28 +430,13 @@ clazz.add(createFastPathExecuteMethod(null, type, usedTypes)); } - for (NodeExecutionData execution : node.getChildExecutions()) { - Collection<TypeMirror> specializedTypes = node.findSpecializedTypes(execution); - specializedTypes.add(genericType); - for (TypeMirror specializedType : specializedTypes) { - if (isExecuteChildShared(execution, specializedType)) { - clazz.add(createExecuteChildMethod(execution, specializedType)); - } - } - } - return clazz; } private Element createAcceptAndExecute() { - - TypeMirror[] parameters = new TypeMirror[node.getSignatureSize()]; - Arrays.fill(parameters, genericType); - - ExecutableTypeData executableElement = new ExecutableTypeData(genericType, "acceptAndExecute", context.getType(Frame.class), Arrays.asList(parameters)); - - LocalContext currentLocals = LocalContext.load(this, node.getSignatureSize(), varArgsThreshold); - CodeExecutableElement executable = createExecuteMethod(null, executableElement, currentLocals, false); + ExecutableTypeData executableElement = createSpecializationNodeSignature(node.getSignatureSize()); + LocalContext currentLocals = LocalContext.load(this, executableElement, varArgsThreshold); + CodeExecutableElement executable = createExecuteMethod(null, executableElement, currentLocals, false, varArgsThreshold); executable.getModifiers().add(FINAL); CodeTreeBuilder builder = executable.createBuilder(); @@ -451,6 +448,12 @@ return executable; } + private ExecutableTypeData createSpecializationNodeSignature(int argumentCount) { + TypeMirror[] parameters = new TypeMirror[argumentCount]; + Arrays.fill(parameters, genericType); + return new ExecutableTypeData(node, genericType, "acceptAndExecute", context.getType(Frame.class), Arrays.asList(parameters)); + } + private boolean shouldImplementExecutableType(SpecializationData specialization, ExecutableTypeData executableType) { // always implement the root execute method. they are declared abstract in the base node. if (executableType.getDelegatedTo() == null) { @@ -458,7 +461,7 @@ } // specializations with more parameters are just ignored - if (executableType.getEvaluatedCount() > node.getSignatureSize()) { + if (executableType.getEvaluatedCount() > node.getExecutionCount()) { return false; } @@ -468,8 +471,9 @@ // the evaluated signature might be compatible to the specialization boolean specializationCompatible = true; - for (int i = 0; i < executableType.getEvaluatedCount(); i++) { - TypeMirror evaluatedType = executableType.getEvaluatedParameters().get(i); + List<TypeMirror> signatureParameters = executableType.getSignatureParameters(); + for (int i = 0; i < signatureParameters.size(); i++) { + TypeMirror evaluatedType = signatureParameters.get(i); TypeMirror specializedType = specialization.findParameterOrDie(node.getChildExecutions().get(i)).getType(); if (!isSubtypeBoxed(context, evaluatedType, specializedType) && !isSubtypeBoxed(context, specializedType, evaluatedType)) { @@ -489,7 +493,7 @@ } // trigger type boxing elimination for unevaluated arguments - for (int i = executableType.getEvaluatedCount(); i < node.getSignatureSize(); i++) { + for (int i = executableType.getEvaluatedCount(); i < node.getExecutionCount(); i++) { NodeExecutionData execution = node.getChildExecutions().get(i); TypeMirror specializedType = specialization.findParameterOrDie(execution).getType(); if (isTypeBoxingOptimized(options.monomorphicTypeBoxingOptimization(), specializedType)) { @@ -512,8 +516,8 @@ } // trigger generation for evaluated assignable type matches other than generic - for (int i = 0; i < executableType.getEvaluatedCount(); i++) { - TypeMirror evaluatedType = executableType.getEvaluatedParameters().get(i); + for (int i = 0; i < signatureParameters.size(); i++) { + TypeMirror evaluatedType = signatureParameters.get(i); NodeExecutionData execution = node.getChildExecutions().get(i); TypeMirror specializedType = specialization.findParameterOrDie(execution).getType(); @@ -664,12 +668,12 @@ return null; } - LocalContext currentLocals = LocalContext.load(this, node.getSignatureSize(), varArgsThreshold); + LocalContext currentLocals = LocalContext.load(this, createSpecializationNodeSignature(node.getSignatureSize()), varArgsThreshold); currentLocals.loadFastPathState(specialization); CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), getType(boolean.class), "isIdentical"); method.addParameter(new CodeVariableElement(getType(SpecializationNode.class), "other")); - currentLocals.addParametersTo(method, FRAME_VALUE); + currentLocals.addParametersTo(method, varArgsThreshold, FRAME_VALUE); method.getAnnotationMirrors().add(new CodeAnnotationMirror(context.getDeclaredType(Override.class))); final CodeTreeBuilder builder = method.createBuilder(); @@ -729,11 +733,11 @@ return null; } TypeMirror specializationNodeType = getType(SpecializationNode.class); - LocalContext currentLocals = LocalContext.load(this, node.getSignatureSize(), varArgsThreshold); + LocalContext currentLocals = LocalContext.load(this, createSpecializationNodeSignature(node.getSignatureSize()), varArgsThreshold); CodeExecutableElement executable = new CodeExecutableElement(modifiers(PUBLIC), specializationNodeType, "merge"); executable.addParameter(new CodeVariableElement(specializationNodeType, "newNode")); - currentLocals.addParametersTo(executable, FRAME_VALUE); + currentLocals.addParametersTo(executable, varArgsThreshold, FRAME_VALUE); executable.getAnnotationMirrors().add(new CodeAnnotationMirror(context.getDeclaredType(Override.class))); CodeTreeBuilder builder = executable.createBuilder(); @@ -802,7 +806,7 @@ private CodeExecutableElement createCreateNext(final Map<SpecializationData, CodeTypeElement> specializationClasses) { final LocalContext locals = LocalContext.load(this); - CodeExecutableElement method = locals.createMethod(modifiers(PROTECTED, FINAL), getType(SpecializationNode.class), "createNext", FRAME_VALUE); + CodeExecutableElement method = locals.createMethod(modifiers(PROTECTED, FINAL), getType(SpecializationNode.class), "createNext", varArgsThreshold, FRAME_VALUE); method.getAnnotationMirrors().add(new CodeAnnotationMirror(context.getDeclaredType(Override.class))); CodeTreeBuilder builder = method.createBuilder(); @@ -834,7 +838,7 @@ locals.removeValue(FRAME_VALUE); } - CodeExecutableElement boundaryMethod = locals.createMethod(modifiers(PRIVATE), getType(boolean.class), "guardFallback", FRAME_VALUE); + CodeExecutableElement boundaryMethod = locals.createMethod(modifiers(PRIVATE), getType(boolean.class), "guardFallback", varArgsThreshold, FRAME_VALUE); if (!frameUsed) { boundaryMethod.getAnnotationMirrors().add(new CodeAnnotationMirror(context.getDeclaredType(TruffleBoundary.class))); } @@ -887,7 +891,7 @@ } LocalContext locals = LocalContext.load(this); - CodeExecutableElement method = locals.createMethod(modifiers(PROTECTED, FINAL), genericType, "unsupported", FRAME_VALUE); + CodeExecutableElement method = locals.createMethod(modifiers(PROTECTED, FINAL), genericType, "unsupported", varArgsThreshold, FRAME_VALUE); method.getAnnotationMirrors().add(new CodeAnnotationMirror(context.getDeclaredType(Override.class))); CodeTreeBuilder builder = method.createBuilder(); @@ -950,8 +954,8 @@ } private CodeExecutableElement createExecutableTypeOverride(List<ExecutableTypeData> usedExecutables, ExecutableTypeData execType) { - LocalContext locals = LocalContext.load(this, execType.getEvaluatedCount(), Integer.MAX_VALUE); - CodeExecutableElement method = createExecuteMethod(null, execType, locals, true); + LocalContext locals = LocalContext.load(this, execType, Integer.MAX_VALUE); + CodeExecutableElement method = createExecuteMethod(null, execType, locals, true, Integer.MAX_VALUE); CodeTreeBuilder builder = method.createBuilder(); if (singleSpecializable) { @@ -1043,17 +1047,38 @@ values.add(createTypeSafeReference(frameLocal, method.getFrameParameter())); } } - for (int parameterIndex = 0; parameterIndex < method.getEvaluatedCount(); parameterIndex++) { - TypeMirror targetParameter = method.getEvaluatedParameters().get(parameterIndex); - LocalVariable variable; - if (executeWith != null && parameterIndex < executeWith.size()) { - variable = currentValues.getValue(executeWith.get(parameterIndex)); + + int evaluatedIndex = 0; + for (int executionIndex = 0; executionIndex < node.getExecutionCount(); executionIndex++) { + NodeExecutionData parameterExecution; + if (executeWith != null && executionIndex < executeWith.size()) { + parameterExecution = executeWith.get(executionIndex); } else { - variable = currentValues.getValue(parameterIndex); + parameterExecution = node.getChildExecutions().get(executionIndex); } - values.add(createTypeSafeReference(variable, targetParameter)); + if (parameterExecution.isShortCircuit()) { + if (evaluatedIndex < method.getEvaluatedCount()) { + TypeMirror targetType = method.getEvaluatedParameters().get(evaluatedIndex); + LocalVariable shortCircuit = currentValues.getShortCircuit(parameterExecution); + if (shortCircuit != null) { + values.add(createTypeSafeReference(shortCircuit, targetType)); + } else { + values.add(CodeTreeBuilder.createBuilder().defaultValue(targetType).build()); + } + evaluatedIndex++; + } + } + if (evaluatedIndex < method.getEvaluatedCount()) { + TypeMirror targetType = method.getEvaluatedParameters().get(evaluatedIndex); + LocalVariable value = currentValues.getValue(parameterExecution); + if (value != null) { + values.add(createTypeSafeReference(value, targetType)); + } else { + values.add(CodeTreeBuilder.createBuilder().defaultValue(targetType).build()); + } + evaluatedIndex++; + } } - return values.toArray(new CodeTree[values.size()]); } @@ -1518,8 +1543,11 @@ } private CodeTree expect(TypeMirror sourceType, TypeMirror forType, CodeTree tree) { - expectedTypes.add(forType); - return TypeSystemCodeGenerator.expect(typeSystem, sourceType, forType, tree); + if (sourceType == null || ElementUtils.needsCastTo(sourceType, forType)) { + expectedTypes.add(forType); + return TypeSystemCodeGenerator.expect(typeSystem, forType, tree); + } + return tree; } private Set<ExecutableTypeData> findSpecializedExecutableTypes(NodeExecutionData execution, TypeMirror type) { @@ -1554,8 +1582,8 @@ } private Element createFastPathExecuteMethod(SpecializationData specialization, ExecutableTypeData executedType, List<ExecutableTypeData> allTypes) { - LocalContext currentLocals = LocalContext.load(this, executedType.getEvaluatedCount(), varArgsThreshold); - CodeExecutableElement executable = createExecuteMethod(specialization, executedType, currentLocals, false); + LocalContext currentLocals = LocalContext.load(this, executedType, Integer.MAX_VALUE); + CodeExecutableElement executable = createExecuteMethod(specialization, executedType, currentLocals, false, Integer.MAX_VALUE); CodeTreeBuilder builder = executable.createBuilder(); if (specialization == null) { if (executedType.getDelegatedTo() == null) { @@ -1569,28 +1597,17 @@ return executable; } - private CodeExecutableElement createExecuteMethod(SpecializationData specialization, ExecutableTypeData executedType, LocalContext currentLocals, boolean originalOverride) { + private static final String VARARGS_NAME = "args"; + + private CodeExecutableElement createExecuteMethod(SpecializationData specialization, ExecutableTypeData executedType, LocalContext currentLocals, boolean originalOverride, int varArgs) { TypeMirror returnType = executedType.getReturnType(); - TypeMirror frame = executedType.getFrameParameter(); - List<TypeMirror> evaluatedParameters = executedType.getEvaluatedParameters(); if (specialization != null) { currentLocals.loadFastPathState(specialization); } - if (frame == null) { - currentLocals.removeValue(FRAME_VALUE); - } else { - currentLocals.set(FRAME_VALUE, currentLocals.get(FRAME_VALUE).newType(frame)); - } - - for (int i = 0; i < Math.min(node.getChildExecutions().size(), evaluatedParameters.size()); i++) { - NodeExecutionData execution = node.getChildExecutions().get(i); - currentLocals.setValue(execution, currentLocals.getValue(execution).newType(evaluatedParameters.get(i))); - } - String methodName; - if (originalOverride) { + if (originalOverride && executedType.getMethod() != null) { methodName = executedType.getMethod().getSimpleName().toString(); } else { methodName = executedType.getUniqueName(); @@ -1608,32 +1625,13 @@ ((CodeVariableElement) executable.getParameters().get(0)).setName(FRAME_VALUE); } - final String varArgsName = "args"; if (executable.isVarArgs()) { - ((CodeVariableElement) executable.getParameters().get(executable.getParameters().size() - 1)).setName(varArgsName); + ((CodeVariableElement) executable.getParameters().get(executable.getParameters().size() - 1)).setName(VARARGS_NAME); } - // rename varargs parameter - int signatureIndex = 0; - for (TypeMirror parameter : executedType.getEvaluatedParameters()) { - LocalVariable var = currentLocals.getValue(signatureIndex); - if (var != null) { - int varArgsIndex = executedType.getVarArgsIndex(executedType.getParameterIndex(signatureIndex)); - if (varArgsIndex >= 0) { - var = var.accessWith(CodeTreeBuilder.singleString(varArgsName + "[" + varArgsIndex + "]")); - } else { - ((CodeVariableElement) executable.getParameters().get(executedType.getParameterIndex(signatureIndex))).setName(var.getName()); - } - if (!isObject(parameter)) { - var = var.newType(parameter); - } - currentLocals.setValue(node.getChildExecutions().get(signatureIndex), var); - } - - signatureIndex++; - } + renameOriginalParameters(executedType, executable, currentLocals); } else { - executable = currentLocals.createMethod(modifiers(PUBLIC), returnType, methodName, FRAME_VALUE); + executable = currentLocals.createMethod(modifiers(PUBLIC), returnType, methodName, varArgs, FRAME_VALUE); } executable.getThrownTypes().clear(); @@ -1644,6 +1642,47 @@ return executable; } + private void renameOriginalParameters(ExecutableTypeData executedType, CodeExecutableElement executable, LocalContext currentLocals) { + // rename varargs parameter + int evaluatedIndex = 0; + for (int executionIndex = 0; executionIndex < node.getExecutionCount(); executionIndex++) { + NodeExecutionData execution = node.getChildExecutions().get(executionIndex); + if (execution.isShortCircuit()) { + if (evaluatedIndex < executedType.getEvaluatedCount()) { + TypeMirror evaluatedType = executedType.getEvaluatedParameters().get(evaluatedIndex); + LocalVariable shortCircuit = currentLocals.getShortCircuit(execution); + if (shortCircuit != null) { + currentLocals.setShortCircuitValue(execution, renameExecutableTypeParameter(executable, executedType, evaluatedIndex, evaluatedType, shortCircuit)); + } + evaluatedIndex++; + } + } + if (evaluatedIndex < executedType.getEvaluatedCount()) { + TypeMirror evaluatedType = executedType.getEvaluatedParameters().get(evaluatedIndex); + LocalVariable value = currentLocals.getValue(execution); + if (value != null) { + currentLocals.setValue(execution, renameExecutableTypeParameter(executable, executedType, evaluatedIndex, evaluatedType, value)); + } + evaluatedIndex++; + } + } + } + + private static LocalVariable renameExecutableTypeParameter(CodeExecutableElement method, ExecutableTypeData executedType, int evaluatedIndex, TypeMirror targetType, LocalVariable var) { + int parameterIndex = executedType.getParameterIndex(evaluatedIndex); + int varArgsIndex = executedType.getVarArgsIndex(parameterIndex); + LocalVariable returnVar = var; + if (varArgsIndex >= 0) { + returnVar = returnVar.accessWith(CodeTreeBuilder.singleString(VARARGS_NAME + "[" + varArgsIndex + "]")); + } else { + ((CodeVariableElement) method.getParameters().get(parameterIndex)).setName(returnVar.getName()); + } + if (!isObject(targetType)) { + returnVar = returnVar.newType(targetType); + } + return returnVar; + } + private boolean needsUnexpectedResultException(ExecutableTypeData executedType) { if (!executedType.hasUnexpectedValue(context)) { return false; @@ -1670,8 +1709,9 @@ delegate = findFastPathDelegate((specialization != null ? specialization.getReturnType().getType() : genericType), executableType, allTypes); } + int delegateSignatureCount = delegate != null ? delegate.getSignatureParameters().size() : 0; for (NodeExecutionData execution : node.getChildExecutions()) { - if (specialization == null && delegate != null && execution.getIndex() >= delegate.getEvaluatedCount()) { + if (specialization == null && delegate != null && execution.getIndex() >= delegateSignatureCount) { // we just evaluate children for the next delegate continue; } else if (specialization != null && delegate != null) { @@ -1794,15 +1834,21 @@ private LocalVariable resolveShortCircuit(SpecializationData specialization, NodeExecutionData execution, LocalContext currentLocals) { LocalVariable shortCircuit = null; - SpecializationData resolvedSpecialization = specialization; - if (specialization == null) { - resolvedSpecialization = node.getGenericSpecialization(); - } - if (execution.isShortCircuit()) { - ShortCircuitData shortCircuitData = resolvedSpecialization.getShortCircuits().get(calculateShortCircuitIndex(execution)); - CodeTree access = callTemplateMethod(accessParent(null), shortCircuitData, currentLocals); - shortCircuit = currentLocals.createShortCircuitValue(execution).accessWith(access); + shortCircuit = currentLocals.getShortCircuit(execution); + + if (shortCircuit == null) { + SpecializationData resolvedSpecialization = specialization; + if (specialization == null) { + resolvedSpecialization = node.getGenericSpecialization(); + } + ShortCircuitData shortCircuitData = resolvedSpecialization.getShortCircuits().get(calculateShortCircuitIndex(execution)); + CodeTree access = callTemplateMethod(accessParent(null), shortCircuitData, currentLocals); + shortCircuit = currentLocals.createShortCircuitValue(execution).accessWith(access); + } else { + CodeTree access = shortCircuit.createReference(); + shortCircuit = shortCircuit.nextName().accessWith(access); + } } return shortCircuit; } @@ -2016,9 +2062,13 @@ } private CodeExecutableElement createExecuteChildMethod(NodeExecutionData execution, TypeMirror targetType) { - LocalContext locals = LocalContext.load(this, 0, varArgsThreshold); - - CodeExecutableElement method = locals.createMethod(modifiers(PROTECTED, FINAL), targetType, executeChildMethodName(execution, targetType), FRAME_VALUE); + if (!usedExecuteChildMethods.contains(execution)) { + return null; + } + + LocalContext locals = LocalContext.load(this, createSpecializationNodeSignature(0), Integer.MAX_VALUE); + + CodeExecutableElement method = locals.createMethod(modifiers(PROTECTED, FINAL), targetType, executeChildMethodName(execution, targetType), Integer.MAX_VALUE, FRAME_VALUE); if (hasChildUnexpectedResult(execution, targetType)) { method.getThrownTypes().add(getType(UnexpectedResultException.class)); } @@ -2047,6 +2097,10 @@ private CodeVariableElement createImplicitProfileParameter(NodeExecutionData execution, TypeMirror targetType) { if (typeSystem.hasImplicitSourceTypes(targetType)) { + if (typeEquals(node.getGenericType(execution), targetType)) { + return null; + } + switch (options.implicitCastOptimization()) { case NONE: return null; @@ -2185,6 +2239,7 @@ if (!isExecuteChildShared(execution, targetValue.getTypeMirror())) { throw new AssertionError("Execute child not shared with method but called."); } + usedExecuteChildMethods.add(execution); CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); builder.tree(targetValue.createReference()).string(" = "); @@ -2594,20 +2649,59 @@ } } - public CodeExecutableElement createMethod(Set<Modifier> modifiers, TypeMirror returnType, String name, String... optionalArguments) { + public CodeExecutableElement createMethod(Set<Modifier> modifiers, TypeMirror returnType, String name, int varArgsThreshold, String... optionalArguments) { CodeExecutableElement method = new CodeExecutableElement(modifiers, returnType, name); - addParametersTo(method, optionalArguments); + addParametersTo(method, varArgsThreshold, optionalArguments); return method; } - public static LocalContext load(NodeGenFactory factory, int signatureSize, int varargsThreshold) { + public static LocalContext load(NodeGenFactory factory, ExecutableTypeData type, int varargsThreshold) { LocalContext context = new LocalContext(factory); - context.loadValues(signatureSize, varargsThreshold); + context.loadEvaluatedValues(type, varargsThreshold); return context; } + private void loadEvaluatedValues(ExecutableTypeData executedType, int varargsThreshold) { + TypeMirror frame = executedType.getFrameParameter(); + if (frame == null) { + removeValue(FRAME_VALUE); + } else { + set(FRAME_VALUE, new LocalVariable(frame, FRAME_VALUE, null, null)); + } + for (NodeFieldData field : factory.node.getFields()) { + String fieldName = fieldValueName(field); + values.put(fieldName, new LocalVariable(field.getType(), fieldName, factory.accessParent(field.getName()), null)); + } + boolean varargs = needsVarargs(false, varargsThreshold); + List<TypeMirror> evaluatedParameter = executedType.getEvaluatedParameters(); + int evaluatedIndex = 0; + for (int executionIndex = 0; executionIndex < factory.node.getExecutionCount(); executionIndex++) { + NodeExecutionData execution = factory.node.getChildExecutions().get(executionIndex); + if (execution.isShortCircuit()) { + if (evaluatedIndex < executedType.getEvaluatedCount()) { + TypeMirror evaluatedType = evaluatedParameter.get(evaluatedIndex); + LocalVariable shortCircuit = createShortCircuitValue(execution).newType(evaluatedType); + if (varargs) { + shortCircuit = shortCircuit.accessWith(createReadVarargs(evaluatedIndex)); + } + values.put(shortCircuit.getName(), shortCircuit.makeOriginal()); + evaluatedIndex++; + } + } + if (evaluatedIndex < executedType.getEvaluatedCount()) { + TypeMirror evaluatedType = evaluatedParameter.get(evaluatedIndex); + LocalVariable value = createValue(execution, evaluatedType); + if (varargs) { + value = value.accessWith(createReadVarargs(evaluatedIndex)); + } + values.put(value.getName(), value.makeOriginal()); + evaluatedIndex++; + } + } + } + public static LocalContext load(NodeGenFactory factory) { - return load(factory, factory.node.getSignatureSize(), factory.varArgsThreshold); + return load(factory, factory.createSpecializationNodeSignature(factory.node.getSignatureSize()), factory.varArgsThreshold); } public LocalContext copy() { @@ -2701,36 +2795,6 @@ return size >= varArgsThreshold; } - private void loadValues(int evaluatedArguments, int varargsThreshold) { - values.put(FRAME_VALUE, new LocalVariable(factory.getType(Frame.class), FRAME_VALUE, null, null)); - - for (NodeFieldData field : factory.node.getFields()) { - String fieldName = fieldValueName(field); - values.put(fieldName, new LocalVariable(field.getType(), fieldName, factory.accessParent(field.getName()), null)); - } - - boolean varargs = needsVarargs(false, varargsThreshold); - for (int i = 0; i < evaluatedArguments; i++) { - List<NodeExecutionData> childExecutions = factory.node.getChildExecutions(); - if (i >= childExecutions.size()) { - break; - } - NodeExecutionData execution = childExecutions.get(i); - if (execution.isShortCircuit()) { - LocalVariable shortCircuit = createShortCircuitValue(execution).makeGeneric(factory.context); - if (varargs) { - shortCircuit = shortCircuit.accessWith(createReadVarargs(i)); - } - values.put(shortCircuit.getName(), shortCircuit.makeOriginal()); - } - LocalVariable value = createValue(execution, factory.genericType); - if (varargs) { - value = value.accessWith(createReadVarargs(i)); - } - values.put(value.getName(), value.makeOriginal()); - } - } - private static CodeTree createReadVarargs(int i) { return CodeTreeBuilder.createBuilder().string("args_[").string(String.valueOf(i)).string("]").build(); } @@ -2766,14 +2830,14 @@ } } - public void addParametersTo(CodeExecutableElement method, String... optionalNames) { + public void addParametersTo(CodeExecutableElement method, int varArgsThreshold, String... optionalNames) { for (String var : optionalNames) { LocalVariable local = values.get(var); if (local != null) { method.addParameter(local.createParameter()); } } - if (needsVarargs(true, factory.varArgsThreshold)) { + if (needsVarargs(true, varArgsThreshold)) { method.addParameter(new CodeVariableElement(factory.getType(Object[].class), "args_")); method.setVarArgs(true); } else {