Mercurial > hg > truffle
diff graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeGenFactory.java @ 19283:08aa0372dad4
Truffle-DSL: implement new guard expression syntax.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Fri, 23 Jan 2015 02:55:23 +0100 |
parents | ae81dd154fb6 |
children | 62c43fcf5be2 |
line wrap: on
line diff
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeGenFactory.java Thu Jan 22 20:44:24 2015 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeGenFactory.java Fri Jan 23 02:55:23 2015 +0100 @@ -43,6 +43,8 @@ import com.oracle.truffle.api.nodes.*; import com.oracle.truffle.api.nodes.Node.Child; import com.oracle.truffle.dsl.processor.*; +import com.oracle.truffle.dsl.processor.expression.*; +import com.oracle.truffle.dsl.processor.expression.DSLExpression.Variable; import com.oracle.truffle.dsl.processor.java.*; import com.oracle.truffle.dsl.processor.java.model.*; import com.oracle.truffle.dsl.processor.model.*; @@ -51,7 +53,7 @@ public class NodeGenFactory { - private static final String FRAME_VALUE = "frameValue"; + private static final String FRAME_VALUE = TemplateMethod.FRAME_NAME; private static final String NAME_SUFFIX = "_"; @@ -318,7 +320,7 @@ return constructor; } - private static boolean mayBeExcluded(SpecializationData specialization) { + public static boolean mayBeExcluded(SpecializationData specialization) { return !specialization.getExceptions().isEmpty() || !specialization.getExcludedBy().isEmpty(); } @@ -1061,7 +1063,7 @@ return true; } - if (!fastPath && group.getSpecialization() != null && !group.getSpecialization().getExceptions().isEmpty()) { + if (!fastPath && group.getSpecialization() != null && mayBeExcluded(group.getSpecialization())) { return true; } @@ -1438,7 +1440,7 @@ List<GuardExpression> elseGuardExpressions = group.findElseConnectableGuards(); List<GuardExpression> guardExpressions = new ArrayList<>(group.getGuards()); guardExpressions.removeAll(elseGuardExpressions); - CodeTree methodGuards = createMethodGuardCheck(guardExpressions, currentValues); + CodeTree methodGuards = createMethodGuardCheck(guardExpressions, group.getSpecialization(), currentValues); if (!group.getAssumptions().isEmpty()) { if (execution.isFastPath() && !forType.isGeneric()) { @@ -1533,14 +1535,13 @@ } private boolean isTypeGuardUsedInAnyGuardBelow(SpecializationGroup group, LocalContext currentValues, TypeGuard typeGuard) { - NodeExecutionData execution = node.getChildExecutions().get(typeGuard.getSignatureIndex()); + LocalVariable localVariable = currentValues.getValue(typeGuard.getSignatureIndex()); for (GuardExpression guard : group.getGuards()) { - List<Parameter> guardParameters = guard.getResolvedGuard().findByExecutionData(execution); - TypeData sourceType = currentValues.getValue(typeGuard.getSignatureIndex()).getType(); - - for (Parameter guardParameter : guardParameters) { - if (sourceType.needsCastTo(guardParameter.getType())) { + Map<Variable, LocalVariable> boundValues = bindLocalValues(guard.getExpression(), group.getSpecialization(), currentValues); + for (Variable var : guard.getExpression().findBoundVariables()) { + LocalVariable target = boundValues.get(var); + if (localVariable.getName().equals(target.getName())) { return true; } } @@ -1946,20 +1947,57 @@ return builder.build(); } - private CodeTree createMethodGuardCheck(List<GuardExpression> guardExpressions, LocalContext currentValues) { + private CodeTree createMethodGuardCheck(List<GuardExpression> guardExpressions, SpecializationData specialization, LocalContext currentValues) { CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); String and = ""; for (GuardExpression guard : guardExpressions) { + DSLExpression expression = guard.getExpression(); + Map<Variable, LocalVariable> bindings = bindLocalValues(expression, specialization, currentValues); + Map<Variable, CodeTree> resolvedBindings = new HashMap<>(); + for (Variable variable : bindings.keySet()) { + LocalVariable localVariable = bindings.get(variable); + CodeTree resolved = CodeTreeBuilder.singleString(localVariable.getName()); + if (!ElementUtils.typeEquals(variable.getResolvedType(), localVariable.getTypeMirror())) { + resolved = CodeTreeBuilder.createBuilder().cast(variable.getResolvedType(), resolved).build(); + } + resolvedBindings.put(variable, resolved); + } + builder.string(and); - if (guard.isNegated()) { - builder.string("!"); - } - builder.tree(callTemplateMethod(accessParent(null), guard.getResolvedGuard(), currentValues)); + builder.tree(DSLExpressionGenerator.write(expression, accessParent(null), resolvedBindings)); and = " && "; } return builder.build(); } + private static Map<Variable, LocalVariable> bindLocalValues(DSLExpression expression, SpecializationData specialization, LocalContext currentValues) throws AssertionError { + Map<Variable, LocalVariable> bindings = new HashMap<>(); + + List<Variable> boundVariables = expression.findBoundVariables(); + if (specialization == null && !boundVariables.isEmpty()) { + throw new AssertionError("Cannot bind guard variable in non-specialization group. yet."); + } + + // resolve bindings for local context + for (Variable variable : boundVariables) { + Parameter resolvedParameter = specialization.findByVariable(variable.getResolvedVariable()); + if (resolvedParameter != null) { + LocalVariable localVariable; + if (resolvedParameter.getSpecification().isSignature()) { + NodeExecutionData execution = resolvedParameter.getSpecification().getExecution(); + localVariable = currentValues.getValue(execution); + } else { + localVariable = currentValues.get(resolvedParameter.getLocalName()); + } + if (localVariable == null) { + throw new AssertionError("Could not resolve local for execution."); + } + bindings.put(variable, localVariable); + } + } + return bindings; + } + private CodeTree[] createTypeCheckAndCast(List<TypeGuard> typeGuards, Set<TypeGuard> castGuards, LocalContext currentValues, SpecializationExecution specializationExecution) { CodeTreeBuilder checksBuilder = CodeTreeBuilder.createBuilder(); CodeTreeBuilder castsBuilder = CodeTreeBuilder.createBuilder();