# HG changeset patch # User Christian Humer # Date 1377634132 -7200 # Node ID f406557f1a0dd881ff9906856e3824a373893af6 # Parent efe58aa92f86fa1a20e7258afa86750282764694# Parent 58b72cc1710906c644b3b67ea624493541c8d269 Merge. diff -r 58b72cc17109 -r f406557f1a0d graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/GuardsTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/GuardsTest.java Tue Aug 27 10:14:06 2013 +0200 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/GuardsTest.java Tue Aug 27 22:08:52 2013 +0200 @@ -29,7 +29,16 @@ import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.dsl.test.GuardsTestFactory.GlobalFlagGuardFactory; +import com.oracle.truffle.api.dsl.test.GuardsTestFactory.GuardWithBaseClassFactory; +import com.oracle.truffle.api.dsl.test.GuardsTestFactory.GuardWithBaseInterfaceFactory; +import com.oracle.truffle.api.dsl.test.GuardsTestFactory.GuardWithBoxedPrimitiveFactory; +import com.oracle.truffle.api.dsl.test.GuardsTestFactory.GuardWithObjectFactory; import com.oracle.truffle.api.dsl.test.GuardsTestFactory.InvocationGuardFactory; +import com.oracle.truffle.api.dsl.test.GuardsTestFactory.TestGuardResolve1Factory; +import com.oracle.truffle.api.dsl.test.GuardsTestFactory.TestGuardResolve2Factory; +import com.oracle.truffle.api.dsl.test.GuardsTestFactory.TestGuardResolve3Factory; +import com.oracle.truffle.api.dsl.test.NodeContainerTest.Str; +import com.oracle.truffle.api.dsl.test.NodeContainerTest.StrBase; import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; @@ -107,4 +116,159 @@ } } + @Test + public void testGuardWithBaseClass() { + TestRootNode root = createRoot(GuardWithBaseClassFactory.getInstance()); + + assertEquals(42, executeWith(root, new Str("42"))); + } + + @NodeChild("expression") + public abstract static class GuardWithBaseClass extends ValueNode { + + boolean baseGuard(StrBase base) { + return true; + } + + @Specialization(guards = "baseGuard") + int doSpecialized(Str value0) { + return 42; + } + } + + @Test + public void testGuardWithBaseInterface() { + TestRootNode root = createRoot(GuardWithBaseInterfaceFactory.getInstance()); + + assertEquals(42, executeWith(root, "anything")); + } + + @NodeChild("expression") + public abstract static class GuardWithBaseInterface extends ValueNode { + + boolean baseGuard(CharSequence base) { + return true; + } + + @Specialization(guards = "baseGuard") + int doSpecialized(String value0) { + return 42; + } + } + + @Test + public void testGuardWithPrimitive() { + TestRootNode root = createRoot(GuardWithBoxedPrimitiveFactory.getInstance()); + + assertEquals(42, executeWith(root, 42)); + } + + @NodeChild("expression") + public abstract static class GuardWithBoxedPrimitive extends ValueNode { + + boolean baseGuard(Integer primitive) { + return true; + } + + @Specialization(guards = "baseGuard") + int doSpecialized(int value0) { + return value0; + } + } + + @Test + public void testGuardWithObject() { + TestRootNode root = createRoot(GuardWithObjectFactory.getInstance()); + + assertEquals(42, executeWith(root, 42)); + } + + @NodeChild("expression") + public abstract static class GuardWithObject extends ValueNode { + + boolean baseGuard(Object primitive) { + return true; + } + + @Specialization(guards = "baseGuard") + int doSpecialized(int value0) { + return value0; + } + } + + @Test + public void testGuardResolve1() { + TestRootNode root = createRoot(TestGuardResolve1Factory.getInstance()); + + assertEquals(42, executeWith(root, 42)); + } + + @NodeChild("expression") + public abstract static class TestGuardResolve1 extends ValueNode { + + boolean guard(Object primitive) { + return false; + } + + boolean guard(int primitive) { + return true; + } + + @Specialization(guards = "guard") + int doSpecialized(int value0) { + return value0; + } + } + + @Test + public void testGuardResolve2() { + TestRootNode root = createRoot(TestGuardResolve2Factory.getInstance()); + assertEquals(42, executeWith(root, new Str(""))); + } + + @NodeChild("expression") + public abstract static class TestGuardResolve2 extends ValueNode { + + boolean guard(Object primitive) { + return false; + } + + boolean guard(StrBase primitive) { + return true; + } + + @Specialization(guards = "guard") + int doSpecialized(Str value0) { + return 42; + } + } + + @Test + public void testGuardResolve3() { + TestRootNode root = createRoot(TestGuardResolve3Factory.getInstance()); + + assertEquals(42, executeWith(root, new Str(""))); + } + + @NodeChild("expression") + public abstract static class TestGuardResolve3 extends ValueNode { + + boolean guard(Object primitive) { + return false; + } + + boolean guard(StrBase primitive) { + return false; + } + + boolean guard(Str primitive) { + return true; + } + + @Specialization(guards = "guard") + int doSpecialized(Str value0) { + return 42; + } + } + } diff -r 58b72cc17109 -r f406557f1a0d graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NodeContainerTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NodeContainerTest.java Tue Aug 27 10:14:06 2013 +0200 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NodeContainerTest.java Tue Aug 27 22:08:52 2013 +0200 @@ -96,8 +96,12 @@ assertSame(context, executeWith(node)); } + static class StrBase { + + } + @NodeContainer(BuiltinNode.class) - static class Str { + static class Str extends StrBase { private final String internal; diff -r 58b72cc17109 -r f406557f1a0d graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/Utils.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/Utils.java Tue Aug 27 10:14:06 2013 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/Utils.java Tue Aug 27 22:08:52 2013 +0200 @@ -32,7 +32,7 @@ import javax.lang.model.util.*; import com.oracle.truffle.dsl.processor.ast.*; -import com.oracle.truffle.dsl.processor.ast.CodeTypeMirror.*; +import com.oracle.truffle.dsl.processor.ast.CodeTypeMirror.DeclaredCodeTypeMirror; import com.oracle.truffle.dsl.processor.compiler.*; /** @@ -50,6 +50,19 @@ return null; } + public static boolean needsCastTo(ProcessorContext context, TypeMirror sourceType, TypeMirror targetType) { + if (typeEquals(sourceType, targetType)) { + return false; + } else if (isObject(targetType)) { + return false; + } else if (isVoid(targetType)) { + return false; + } else if (isAssignable(context, sourceType, targetType)) { + return false; + } + return true; + } + public static VariableElement findVariableElement(DeclaredType type, String name) { List elements = ElementFilter.fieldsIn(type.asElement().getEnclosedElements()); for (VariableElement variableElement : elements) { @@ -502,6 +515,24 @@ return types; } + public static List getAssignableTypes(ProcessorContext context, TypeMirror type) { + if (isPrimitive(type)) { + return Arrays.asList(type, boxType(context, type), context.getType(Object.class)); + } else if (type.getKind() == TypeKind.ARRAY) { + return Arrays.asList(type, context.getType(Object.class)); + } else if (type.getKind() == TypeKind.DECLARED) { + List types = getSuperTypes(fromTypeMirror(type)); + List mirrors = new ArrayList<>(types.size()); + mirrors.add(type); + for (TypeElement typeElement : types) { + mirrors.add(typeElement.asType()); + } + return mirrors; + } else { + return Collections.emptyList(); + } + } + public static List getSuperTypes(TypeElement element) { List types = new ArrayList<>(); List superTypes = null; diff -r 58b72cc17109 -r f406557f1a0d 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 Tue Aug 27 10:14:06 2013 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java Tue Aug 27 22:08:52 2013 +0200 @@ -258,15 +258,15 @@ if (valueParameter == null) { valueParameter = targetParameter; } - TypeData targetType = targetParameter.getTypeSystemType(); + TypeMirror targetType = targetParameter.getType(); if (targetParameter.isImplicit() || valueParameter.isImplicit()) { continue; } - TypeData valueType = null; + TypeMirror valueType = null; if (valueParameter != null) { - valueType = valueParameter.getTypeSystemType(); + valueType = valueParameter.getType(); } if (signatureIndex < customSignatureValueNames.length && targetParameter.getSpecification().isSignature()) { @@ -283,14 +283,8 @@ builder.end(); } else if (unexpectedValueName != null && targetParameter.getLocalName().equals(unexpectedValueName)) { builder.string("ex.getResult()"); - } else if (targetType == null || targetType.isGeneric() || (valueType != null && valueType.equalsType(targetType))) { + } else if (!Utils.needsCastTo(getContext(), valueType, targetType)) { builder.startGroup(); - - if (valueType != null && sourceMethod.getMethodName().equals(targetMethod.getMethodName()) && !valueType.isGeneric() && targetType.isGeneric()) { - builder.string("("); - builder.type(targetType.getPrimitiveType()); - builder.string(") "); - } builder.string(valueName(targetParameter)); builder.end(); } else { diff -r 58b72cc17109 -r f406557f1a0d 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 Tue Aug 27 10:14:06 2013 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationData.java Tue Aug 27 22:08:52 2013 +0200 @@ -256,7 +256,9 @@ public void forceFrame(TypeMirror frameType) { if (getParameters().isEmpty() || !Utils.typeEquals(getParameters().get(0).getType(), frameType)) { ParameterSpec frameSpec = getSpecification().findParameterSpec("frame"); - getParameters().add(0, new ActualParameter(frameSpec, frameType, -1, false)); + if (frameSpec != null) { + getParameters().add(0, new ActualParameter(frameSpec, frameType, -1, false)); + } } } diff -r 58b72cc17109 -r f406557f1a0d 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 Tue Aug 27 10:14:06 2013 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/ActualParameter.java Tue Aug 27 22:08:52 2013 +0200 @@ -24,6 +24,7 @@ import javax.lang.model.type.*; +import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.typesystem.*; public class ActualParameter { @@ -104,4 +105,9 @@ public ActualParameter getPreviousParameter() { return method.getPreviousParam(this); } + + @Override + public String toString() { + return Utils.getSimpleName(type); + } } diff -r 58b72cc17109 -r f406557f1a0d 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 Tue Aug 27 10:14:06 2013 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethod.java Tue Aug 27 22:08:52 2013 +0200 @@ -278,20 +278,23 @@ } public int compareBySignature(TemplateMethod compareMethod) { - TypeSystemData typeSystem = getTemplate().getTypeSystem(); + final TypeSystemData typeSystem = getTemplate().getTypeSystem(); if (typeSystem != compareMethod.getTemplate().getTypeSystem()) { throw new IllegalStateException("Cannot compare two methods with different type systems."); } - Signature signature1 = getSignature(); - Signature signature2 = compareMethod.getSignature(); + List signature1 = getSignatureTypes(); + List signature2 = compareMethod.getSignatureTypes(); if (signature1.size() != signature2.size()) { return signature2.size() - signature1.size(); } int result = 0; for (int i = 1; i < signature1.size(); i++) { - int typeResult = compareActualParameter(typeSystem, signature1.get(i), signature2.get(i)); + TypeMirror t1 = signature1.get(i); + TypeMirror t2 = signature2.get(i); + + int typeResult = compareParameter(typeSystem, t1, t2); if (result == 0) { result = typeResult; } else if (typeResult != 0 && Math.signum(result) != Math.signum(typeResult)) { @@ -300,16 +303,44 @@ } } if (result == 0 && signature1.size() > 0) { - result = compareActualParameter(typeSystem, signature1.get(0), signature2.get(0)); + result = compareParameter(typeSystem, signature1.get(0), signature2.get(0)); } return result; } - private static int compareActualParameter(TypeSystemData typeSystem, TypeData t1, TypeData t2) { - int index1 = typeSystem.findType(t1); - int index2 = typeSystem.findType(t2); - return index1 - index2; + private static int compareParameter(TypeSystemData data, TypeMirror signature1, TypeMirror signature2) { + if (Utils.typeEquals(signature1, signature2)) { + return 0; + } + + int index1 = data.findType(signature1); + int index2 = data.findType(signature2); + if (index1 != -1 && index2 != -1) { + return index1 - index2; + } + + if (signature1.getKind() == TypeKind.DECLARED && signature2.getKind() == TypeKind.DECLARED) { + TypeElement element1 = Utils.fromTypeMirror(signature1); + TypeElement element2 = Utils.fromTypeMirror(signature2); + + if (Utils.getDirectSuperTypes(element1).contains(element2)) { + return -1; + } else if (Utils.getDirectSuperTypes(element2).contains(element1)) { + return 1; + } + } + return Utils.getSimpleName(signature1).compareTo(Utils.getSimpleName(signature2)); + } + + public List getSignatureTypes() { + List types = new ArrayList<>(); + for (ActualParameter param : getReturnTypeAndParameters()) { + if (param.getSpecification().isSignature()) { + types.add(param.getType()); + } + } + return types; } public static class Signature implements Iterable, Comparable { diff -r 58b72cc17109 -r f406557f1a0d graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardData.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardData.java Tue Aug 27 10:14:06 2013 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardData.java Tue Aug 27 22:08:52 2013 +0200 @@ -60,7 +60,7 @@ @Override public String toString() { - return getMethodName(); + return getMethodName() + getParameters().toString(); } } diff -r 58b72cc17109 -r f406557f1a0d 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 Tue Aug 27 10:14:06 2013 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardParser.java Tue Aug 27 22:08:52 2013 +0200 @@ -26,6 +26,7 @@ import java.util.*; import javax.lang.model.element.*; +import javax.lang.model.type.*; import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.node.*; @@ -58,7 +59,8 @@ spec.getRequired().clear(); for (ActualParameter parameter : specialization.getRequiredParameters()) { - ParameterSpec paramSpec = new ParameterSpec(parameter.getLocalName(), parameter.getType(), getNode().getTypeSystem().getGenericType()); + List assignableTypes = Utils.getAssignableTypes(getContext(), parameter.getType()); + ParameterSpec paramSpec = new ParameterSpec(parameter.getLocalName(), assignableTypes); paramSpec.setSignature(true); spec.addRequired(paramSpec); } @@ -89,7 +91,13 @@ if (specializationParameter == null) { newParameters.add(parameter); } else { - newParameters.add(new ActualParameter(specializationParameter.getSpecification(), parameter.getTypeSystemType(), specializationParameter.getIndex(), parameter.isImplicit())); + ActualParameter p; + if (parameter.getTypeSystemType() != null) { + p = new ActualParameter(specializationParameter.getSpecification(), parameter.getTypeSystemType(), specializationParameter.getIndex(), parameter.isImplicit()); + } else { + p = new ActualParameter(specializationParameter.getSpecification(), parameter.getType(), specializationParameter.getIndex(), parameter.isImplicit()); + } + newParameters.add(p); } } guard.setParameters(newParameters); diff -r 58b72cc17109 -r f406557f1a0d graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeData.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeData.java Tue Aug 27 10:14:06 2013 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeData.java Tue Aug 27 22:08:52 2013 +0200 @@ -120,16 +120,7 @@ } public boolean needsCastTo(ProcessorContext context, TypeData targetType) { - if (this.equals(targetType)) { - return false; - } else if (targetType.isGeneric()) { - return false; - } else if (targetType.isVoid()) { - return false; - } else if (Utils.isAssignable(context, getPrimitiveType(), targetType.getPrimitiveType())) { - return false; - } - return true; + return Utils.needsCastTo(context, getPrimitiveType(), targetType.getPrimitiveType()); } public boolean isPrimitive() {