changeset 18758:3912400fc33a

Truffle-DSL: remove type system singleton
author Christian Humer <christian.humer@gmail.com>
date Mon, 29 Dec 2014 23:38:42 +0100
parents 0ec5f5a2e720
children 86cd6bc305fc
files graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ImplicitCastTest.java graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TypeSystemTest.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeBaseFactory.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/SpecializedNodeFactory.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/TypeSystemCodeGenerator.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeTreeBuilder.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/TypeData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/ImplicitCastParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/TypeCastParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/TypeCheckParser.java
diffstat 10 files changed, 203 insertions(+), 119 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ImplicitCastTest.java	Mon Dec 29 23:38:39 2014 +0100
+++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ImplicitCastTest.java	Mon Dec 29 23:38:42 2014 +0100
@@ -38,12 +38,12 @@
     static class ImplicitCast0Types {
 
         @ImplicitCast
-        boolean castInt(int intvalue) {
+        static boolean castInt(int intvalue) {
             return intvalue == 1 ? true : false;
         }
 
         @ImplicitCast
-        boolean castString(String strvalue) {
+        static boolean castString(String strvalue) {
             return strvalue.equals("1");
         }
 
@@ -160,7 +160,7 @@
 
         @ImplicitCast
         @ExpectError("Target type and source type of an @ImplicitCast must not be the same type.")
-        String castInvalid(@SuppressWarnings("unused") String value) {
+        static String castInvalid(@SuppressWarnings("unused") String value) {
             throw new AssertionError();
         }
 
--- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TypeSystemTest.java	Mon Dec 29 23:38:39 2014 +0100
+++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TypeSystemTest.java	Mon Dec 29 23:38:42 2014 +0100
@@ -26,6 +26,7 @@
 
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.dsl.internal.*;
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.api.nodes.*;
 import com.oracle.truffle.api.source.*;
@@ -34,35 +35,36 @@
 
     @TypeSystem({int.class, long.class, double.class, boolean.class, BigInteger.class, String.class, CallTarget.class, BExtendsAbstract.class, CExtendsAbstract.class, Abstract.class, Interface.class,
                     Object[].class})
+    @DSLOptions(useNewLayout = true)
     static class SimpleTypes {
 
         static int intCheck;
         static int intCast;
 
         @TypeCheck
-        public boolean isInteger(Object value) {
+        public static boolean isInteger(Object value) {
             intCheck++;
             return value instanceof Integer;
         }
 
         @TypeCast
-        public int asInteger(Object value) {
+        public static int asInteger(Object value) {
             intCast++;
             return (int) value;
         }
 
         @ImplicitCast
-        public double castDouble(int value) {
+        public static double castDouble(int value) {
             return value;
         }
 
         @ImplicitCast
-        public long castLong(int value) {
+        public static long castLong(int value) {
             return value;
         }
 
         @ImplicitCast
-        public BigInteger castBigInteger(int value) {
+        public static BigInteger castBigInteger(int value) {
             return BigInteger.valueOf(value);
         }
 
@@ -81,47 +83,47 @@
         }
 
         public int executeInt(VirtualFrame frame) throws UnexpectedResultException {
-            return SimpleTypesGen.SIMPLETYPES.expectInteger(execute(frame));
+            return SimpleTypesGen.expectInteger(execute(frame));
         }
 
         public long executeLong(VirtualFrame frame) throws UnexpectedResultException {
-            return SimpleTypesGen.SIMPLETYPES.expectLong(execute(frame));
+            return SimpleTypesGen.expectLong(execute(frame));
         }
 
         public String executeString(VirtualFrame frame) throws UnexpectedResultException {
-            return SimpleTypesGen.SIMPLETYPES.expectString(execute(frame));
+            return SimpleTypesGen.expectString(execute(frame));
         }
 
         public boolean executeBoolean(VirtualFrame frame) throws UnexpectedResultException {
-            return SimpleTypesGen.SIMPLETYPES.expectBoolean(execute(frame));
+            return SimpleTypesGen.expectBoolean(execute(frame));
         }
 
         public Object[] executeIntArray(VirtualFrame frame) throws UnexpectedResultException {
-            return SimpleTypesGen.SIMPLETYPES.expectObjectArray(execute(frame));
+            return SimpleTypesGen.expectObjectArray(execute(frame));
         }
 
         public BigInteger executeBigInteger(VirtualFrame frame) throws UnexpectedResultException {
-            return SimpleTypesGen.SIMPLETYPES.expectBigInteger(execute(frame));
+            return SimpleTypesGen.expectBigInteger(execute(frame));
         }
 
         public BExtendsAbstract executeBExtendsAbstract(VirtualFrame frame) throws UnexpectedResultException {
-            return SimpleTypesGen.SIMPLETYPES.expectBExtendsAbstract(execute(frame));
+            return SimpleTypesGen.expectBExtendsAbstract(execute(frame));
         }
 
         public CExtendsAbstract executeCExtendsAbstract(VirtualFrame frame) throws UnexpectedResultException {
-            return SimpleTypesGen.SIMPLETYPES.expectCExtendsAbstract(execute(frame));
+            return SimpleTypesGen.expectCExtendsAbstract(execute(frame));
         }
 
         public Abstract executeAbstract(VirtualFrame frame) throws UnexpectedResultException {
-            return SimpleTypesGen.SIMPLETYPES.expectAbstract(execute(frame));
+            return SimpleTypesGen.expectAbstract(execute(frame));
         }
 
         public double executeDouble(VirtualFrame frame) throws UnexpectedResultException {
-            return SimpleTypesGen.SIMPLETYPES.expectDouble(execute(frame));
+            return SimpleTypesGen.expectDouble(execute(frame));
         }
 
         public Interface executeInterface(VirtualFrame frame) throws UnexpectedResultException {
-            return SimpleTypesGen.SIMPLETYPES.expectInterface(execute(frame));
+            return SimpleTypesGen.expectInterface(execute(frame));
         }
 
         public Object execute(@SuppressWarnings("unused") VirtualFrame frame) {
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeBaseFactory.java	Mon Dec 29 23:38:39 2014 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeBaseFactory.java	Mon Dec 29 23:38:42 2014 +0100
@@ -931,8 +931,6 @@
     }
 
     private CodeTree createTypeGuard(CodeTreeBuilder parent, NodeExecutionData execution, Parameter source, TypeData targetType, boolean typedCasts) {
-        NodeData childNode = execution.getChild().getNodeData();
-
         CodeTreeBuilder builder = new CodeTreeBuilder(parent);
 
         TypeData sourceType = source.getTypeSystemType();
@@ -951,25 +949,23 @@
             builder.string(" || ");
         }
 
-        String castMethodName;
-        String castTypeName = null;
         List<TypeData> types = getSpecialization().getNode().getTypeSystem().lookupSourceTypes(targetType);
         if (types.size() > 1) {
-            castMethodName = TypeSystemCodeGenerator.isImplicitTypeMethodName(targetType);
+            String castTypeName = null;
             if (typedCasts) {
                 castTypeName = implicitTypeName(source);
             }
+            CodeTree check;
+            if (castTypeName == null) {
+                check = TypeSystemCodeGenerator.implicitCheck(targetType, valueName(source), null);
+            } else {
+                check = TypeSystemCodeGenerator.implicitCheck(targetType, valueName(source), castTypeName);
+            }
+            builder.tree(check);
         } else {
-            castMethodName = TypeSystemCodeGenerator.isTypeMethodName(targetType);
+            builder.tree(TypeSystemCodeGenerator.check(targetType, valueName(source)));
         }
 
-        startCallTypeSystemMethod(builder, childNode.getTypeSystem(), castMethodName);
-        builder.string(valueName(source));
-        if (castTypeName != null) {
-            builder.string(castTypeName);
-        }
-        builder.end().end(); // call
-
         if (execution.isShortCircuit()) {
             builder.string(")");
         }
@@ -981,7 +977,6 @@
 
     // TODO merge redundancies with #createTypeGuard
     private CodeTree createCast(CodeTreeBuilder parent, NodeExecutionData execution, Parameter source, TypeData targetType, boolean typedCasts) {
-        NodeData childNode = execution.getChild().getNodeData();
         TypeData sourceType = source.getTypeSystemType();
 
         if (!sourceType.needsCastTo(targetType)) {
@@ -995,26 +990,18 @@
             condition = CodeTreeBuilder.singleString(valueName(shortCircuit));
         }
 
-        String castMethodName;
-        String castTypeName = null;
+        CodeTree cast;
         List<TypeData> types = getSpecialization().getNode().getTypeSystem().lookupSourceTypes(targetType);
         if (types.size() > 1) {
-            castMethodName = TypeSystemCodeGenerator.asImplicitTypeMethodName(targetType);
+            String castTypeName = null;
             if (typedCasts) {
                 castTypeName = implicitTypeName(source);
             }
+            cast = TypeSystemCodeGenerator.implicitCast(targetType, valueName(source), castTypeName);
         } else {
-            castMethodName = TypeSystemCodeGenerator.asTypeMethodName(targetType);
+            cast = TypeSystemCodeGenerator.cast(targetType, valueName(source));
         }
 
-        List<CodeTree> args = new ArrayList<>();
-        args.add(CodeTreeBuilder.singleString(valueName(source)));
-        if (castTypeName != null) {
-            args.add(CodeTreeBuilder.singleString(castTypeName));
-        }
-
-        CodeTree cast = createCallTypeSystemMethod(parent, childNode, castMethodName, args.toArray(new CodeTree[0]));
-
         CodeTreeBuilder builder = parent.create();
         builder.tree(createLazyAssignment(parent, castValueName(source), targetType.getPrimitiveType(), condition, cast));
 
@@ -1032,8 +1019,7 @@
         CodeTreeBuilder builder = parent.create();
         List<TypeData> types = getSpecialization().getNode().getTypeSystem().lookupSourceTypes(targetType);
         if (types.size() > 1) {
-            CodeTree castType = createCallTypeSystemMethod(parent, execution.getChild().getNodeData(), TypeSystemCodeGenerator.getImplicitClass(targetType),
-                            CodeTreeBuilder.singleString(valueName(source)));
+            CodeTree castType = TypeSystemCodeGenerator.implicitType(targetType, valueName(source));
             builder.tree(createLazyAssignment(builder, implicitTypeName(source), context.getType(Class.class), condition, castType));
         }
         return builder.getRoot();
@@ -1127,7 +1113,7 @@
                 builder.string("// ignore").newLine();
             } else {
                 builder.startReturn();
-                builder.tree(createExpectExecutableType(node, specialization.getNode().getTypeSystem().getGenericTypeData(), hasUnexpected, executable.getType(),
+                builder.tree(createExpectExecutableType(specialization.getNode().getTypeSystem().getGenericTypeData(), hasUnexpected, executable.getType(),
                                 CodeTreeBuilder.singleString("ex.getResult()")));
                 builder.end();
             }
@@ -1135,7 +1121,7 @@
 
             if (!returnVoid) {
                 builder.startReturn();
-                builder.tree(createExpectExecutableType(node, castExecutable.getReturnType().getTypeSystemType(), hasUnexpected, executable.getType(), CodeTreeBuilder.singleString("value")));
+                builder.tree(createExpectExecutableType(castExecutable.getReturnType().getTypeSystemType(), hasUnexpected, executable.getType(), CodeTreeBuilder.singleString("value")));
                 builder.end();
             }
         } else {
@@ -1143,7 +1129,7 @@
                 builder.statement(primaryExecuteCall);
             } else {
                 builder.startReturn();
-                builder.tree(createExpectExecutableType(node, castExecutable.getReturnType().getTypeSystemType(), hasUnexpected, executable.getType(), primaryExecuteCall));
+                builder.tree(createExpectExecutableType(castExecutable.getReturnType().getTypeSystemType(), hasUnexpected, executable.getType(), primaryExecuteCall));
                 builder.end();
             }
         }
@@ -1151,8 +1137,8 @@
         return builder.getRoot();
     }
 
-    private static CodeTree createExpectExecutableType(NodeData node, TypeData sourceType, boolean hasUnexpected, TypeData exepctedType, CodeTree value) {
-        return createCastType(node.getTypeSystem(), sourceType, exepctedType, hasUnexpected, value);
+    private static CodeTree createExpectExecutableType(TypeData sourceType, boolean hasUnexpected, TypeData exepctedType, CodeTree value) {
+        return createCastType(sourceType, exepctedType, hasUnexpected, value);
     }
 
     protected CodeTree createExecuteChildren(CodeTreeBuilder parent, ExecutableTypeData sourceExecutable, SpecializationData currentSpecialization, List<Parameter> targetParameters,
@@ -1399,10 +1385,9 @@
         }
 
         // target = expectTargetType(implicitCast(expectCastSourceType(source)))
-        TypeSystemData typeSystem = execution.getChild().getNodeData().getTypeSystem();
-        expression = createExpectType(typeSystem, sourceType, castSourceType, expression);
-        expression = createImplicitCast(parent, typeSystem, cast, expression);
-        expression = createExpectType(typeSystem, castTargetType, targetType, expression);
+        expression = createExpectType(sourceType, castSourceType, expression);
+        expression = createImplicitCast(cast, expression);
+        expression = createExpectType(castTargetType, targetType, expression);
 
         CodeTreeBuilder builder = parent.create();
         builder.string(valueName(targetParameter));
@@ -1411,15 +1396,11 @@
         return builder.getRoot();
     }
 
-    private static CodeTree createImplicitCast(CodeTreeBuilder parent, TypeSystemData typeSystem, ImplicitCastData cast, CodeTree expression) {
+    private static CodeTree createImplicitCast(ImplicitCastData cast, CodeTree expression) {
         if (cast == null) {
             return expression;
         }
-        CodeTreeBuilder builder = parent.create();
-        startCallTypeSystemMethod(builder, typeSystem, cast.getMethodName());
-        builder.tree(expression);
-        builder.end().end();
-        return builder.getRoot();
+        return TypeSystemCodeGenerator.invokeImplicitCast(cast, expression);
     }
 
     private boolean containsNewLine(CodeTree tree) {
@@ -1540,7 +1521,7 @@
 
         TypeData sourceType = polymorphic.getReturnType().getTypeSystemType();
 
-        builder.tree(createExpectExecutableType(node, sourceType, currentExecutable.hasUnexpectedValue(context), currentExecutable.getType(), execute.getRoot()));
+        builder.tree(createExpectExecutableType(sourceType, currentExecutable.hasUnexpectedValue(context), currentExecutable.getType(), execute.getRoot()));
 
         builder.end();
         return builder.getRoot();
@@ -1588,7 +1569,7 @@
                     CodeTree value = CodeTreeBuilder.singleString(localName);
 
                     if (sourceType.needsCastTo(targetType)) {
-                        value = createCallTypeSystemMethod(builder, getSpecialization().getNode(), TypeSystemCodeGenerator.asTypeMethodName(targetType), value);
+                        value = TypeSystemCodeGenerator.cast(targetType, value);
                     }
                     builder.tree(value);
                 } else {
@@ -1657,7 +1638,7 @@
         CodeTreeBuilder builder = new CodeTreeBuilder(parent);
 
         builder.startReturn();
-        builder.tree(createExpectExecutableType(node, generic.getReturnType().getTypeSystemType(), hasUnexpected, returnType, specializeCall.getRoot()));
+        builder.tree(createExpectExecutableType(generic.getReturnType().getTypeSystemType(), hasUnexpected, returnType, specializeCall.getRoot()));
         builder.end();
 
         return builder.getRoot();
@@ -1854,23 +1835,6 @@
         return name;
     }
 
-    static CodeTree createCallTypeSystemMethod(CodeTreeBuilder parent, NodeData node, String methodName, CodeTree... args) {
-        CodeTreeBuilder builder = new CodeTreeBuilder(parent);
-        startCallTypeSystemMethod(builder, node.getTypeSystem(), methodName);
-        for (CodeTree arg : args) {
-            builder.tree(arg);
-        }
-        builder.end().end();
-        return builder.getRoot();
-    }
-
-    private static void startCallTypeSystemMethod(CodeTreeBuilder body, TypeSystemData typeSystem, String methodName) {
-        GeneratedTypeMirror typeMirror = new GeneratedTypeMirror(ElementUtils.getPackageName(typeSystem.getTemplateType()), TypeSystemCodeGenerator.typeName(typeSystem));
-        body.startGroup();
-        body.staticReference(typeMirror, TypeSystemCodeGenerator.singletonName(typeSystem));
-        body.string(".").startCall(methodName);
-    }
-
     /**
      * <pre>
      * variant1 $condition != null
@@ -1972,28 +1936,22 @@
         return nodeid;
     }
 
-    private static CodeTree createCastType(TypeSystemData typeSystem, TypeData sourceType, TypeData targetType, boolean expect, CodeTree value) {
+    private static CodeTree createCastType(TypeData sourceType, TypeData targetType, boolean expect, CodeTree value) {
         if (targetType == null) {
             return value;
         } else if (sourceType != null && !sourceType.needsCastTo(targetType)) {
             return value;
         }
 
-        CodeTreeBuilder builder = CodeTreeBuilder.createBuilder();
-        String targetMethodName;
         if (expect) {
-            targetMethodName = TypeSystemCodeGenerator.expectTypeMethodName(targetType);
+            return TypeSystemCodeGenerator.expect(targetType, value);
         } else {
-            targetMethodName = TypeSystemCodeGenerator.asTypeMethodName(targetType);
+            return TypeSystemCodeGenerator.cast(targetType, value);
         }
-        startCallTypeSystemMethod(builder, typeSystem, targetMethodName);
-        builder.tree(value);
-        builder.end().end();
-        return builder.getRoot();
     }
 
-    private static CodeTree createExpectType(TypeSystemData typeSystem, TypeData sourceType, TypeData targetType, CodeTree expression) {
-        return createCastType(typeSystem, sourceType, targetType, true, expression);
+    private static CodeTree createExpectType(TypeData sourceType, TypeData targetType, CodeTree expression) {
+        return createCastType(sourceType, targetType, true, expression);
     }
 
     static CodeTree createDeoptimize(CodeTreeBuilder parent) {
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/SpecializedNodeFactory.java	Mon Dec 29 23:38:39 2014 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/SpecializedNodeFactory.java	Mon Dec 29 23:38:42 2014 +0100
@@ -492,11 +492,13 @@
             if (targetType == null || sourceType == null) {
                 builder.tree(returnBuilder.getRoot());
             } else if (sourceType.needsCastTo(targetType)) {
-                String castMethodName = TypeSystemCodeGenerator.expectTypeMethodName(targetType);
-                if (!executable.hasUnexpectedValue(context)) {
-                    castMethodName = TypeSystemCodeGenerator.asTypeMethodName(targetType);
+                CodeTree cast;
+                if (executable.hasUnexpectedValue(context)) {
+                    cast = TypeSystemCodeGenerator.expect(targetType, returnBuilder.getRoot());
+                } else {
+                    cast = TypeSystemCodeGenerator.cast(targetType, returnBuilder.getRoot());
                 }
-                builder.tree(createCallTypeSystemMethod(parent, node, castMethodName, returnBuilder.getRoot()));
+                builder.tree(cast);
             } else {
                 builder.tree(returnBuilder.getRoot());
             }
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/TypeSystemCodeGenerator.java	Mon Dec 29 23:38:39 2014 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/TypeSystemCodeGenerator.java	Mon Dec 29 23:38:42 2014 +0100
@@ -36,6 +36,105 @@
 
 public class TypeSystemCodeGenerator extends CodeTypeElementFactory<TypeSystemData> {
 
+    public static CodeTree cast(TypeData type, String content) {
+        return cast(type, CodeTreeBuilder.singleString(content));
+    }
+
+    public static CodeTree implicitType(TypeData type, String valueName) {
+        if (type.isGeneric()) {
+            return CodeTreeBuilder.singleString(valueName);
+        }
+        CodeTreeBuilder builder = CodeTreeBuilder.createBuilder();
+        TypeSystemData typeSystem = type.getTypeSystem();
+        builder.startStaticCall(createTypeSystemGen(typeSystem), getImplicitClass(type)).string(valueName);
+        builder.end();
+        return builder.getRoot();
+    }
+
+    public static CodeTree invokeImplicitCast(ImplicitCastData cast, CodeTree expression) {
+        CodeTreeBuilder builder = CodeTreeBuilder.createBuilder();
+        TypeSystemData typeSystem = cast.getTargetType().getTypeSystem();
+        builder.startStaticCall(createTypeSystemGen(typeSystem), cast.getMethodName()).tree(expression);
+        builder.end();
+        return builder.getRoot();
+    }
+
+    public static CodeTree implicitCheck(TypeData type, String valueName, String typeHint) {
+        if (type.isGeneric()) {
+            return CodeTreeBuilder.singleString(valueName);
+        }
+        CodeTreeBuilder builder = CodeTreeBuilder.createBuilder();
+        TypeSystemData typeSystem = type.getTypeSystem();
+        builder.startStaticCall(createTypeSystemGen(typeSystem), isImplicitTypeMethodName(type)).string(valueName);
+        if (typeHint != null) {
+            builder.string(typeHint);
+        }
+        builder.end();
+        return builder.getRoot();
+    }
+
+    public static CodeTree implicitCast(TypeData type, String valueName, String typeHint) {
+        if (type.isGeneric()) {
+            return CodeTreeBuilder.singleString(valueName);
+        }
+        CodeTreeBuilder builder = CodeTreeBuilder.createBuilder();
+        TypeSystemData typeSystem = type.getTypeSystem();
+        builder.startStaticCall(createTypeSystemGen(typeSystem), asImplicitTypeMethodName(type)).string(valueName);
+        if (typeHint != null) {
+            builder.string(typeHint);
+        }
+        builder.end();
+        return builder.getRoot();
+    }
+
+    public static CodeTree cast(TypeData type, CodeTree content) {
+        if (type.isGeneric()) {
+            return content;
+        }
+        CodeTreeBuilder builder = CodeTreeBuilder.createBuilder();
+        TypeSystemData typeSystem = type.getTypeSystem();
+
+        if (type.isDefaultCast()) {
+            builder.cast(type.getPrimitiveType(), content);
+        } else {
+            builder.startStaticCall(typeSystem.getTemplateType().asType(), type.getTypeCasts().get(0).getMethodName()).tree(content).end();
+        }
+        return builder.getRoot();
+    }
+
+    public static CodeTree expect(TypeData type, CodeTree content) {
+        if (type.isGeneric()) {
+            return content;
+        }
+        CodeTreeBuilder builder = CodeTreeBuilder.createBuilder();
+        TypeSystemData typeSystem = type.getTypeSystem();
+        builder.startStaticCall(createTypeSystemGen(typeSystem), expectTypeMethodName(type)).tree(content).end();
+        return builder.getRoot();
+    }
+
+    private static CodeTypeMirror createTypeSystemGen(TypeSystemData typeSystem) {
+        return new GeneratedTypeMirror(ElementUtils.getPackageName(typeSystem.getTemplateType()), typeName(typeSystem));
+    }
+
+    public static CodeTree check(TypeData type, String content) {
+        return check(type, CodeTreeBuilder.singleString(content));
+    }
+
+    public static CodeTree check(TypeData type, CodeTree content) {
+        if (type.isGeneric()) {
+            return content;
+        }
+        CodeTreeBuilder builder = CodeTreeBuilder.createBuilder();
+        TypeSystemData typeSystem = type.getTypeSystem();
+
+        if (type.isDefaultCheck()) {
+            builder.instanceOf(content, type.getBoxedType());
+        } else {
+            builder.startStaticCall(typeSystem.getTemplateType().asType(), type.getTypeChecks().get(0).getMethodName()).tree(content).end();
+        }
+        return builder.getRoot();
+    }
+
     public static String isTypeMethodName(TypeData type) {
         return "is" + ElementUtils.getTypeId(type.getBoxedType());
     }
@@ -124,12 +223,17 @@
             for (TypeCheckData cast : type.getTypeChecks()) {
                 sourceTypes.add(cast.getCheckedType());
             }
+            sourceTypes.remove(type);
             return new ArrayList<>(sourceTypes);
         }
 
         private CodeVariableElement createSingleton(CodeTypeElement clazz) {
             CodeVariableElement field = new CodeVariableElement(modifiers(PUBLIC, STATIC, FINAL), clazz.asType(), singletonName(typeSystem));
             field.createInitBuilder().startNew(clazz.asType()).end();
+
+            CodeAnnotationMirror annotationMirror = new CodeAnnotationMirror((DeclaredType) context.getType(Deprecated.class));
+            field.getAnnotationMirrors().add(annotationMirror);
+
             return field;
         }
 
@@ -138,7 +242,7 @@
             if (casts.isEmpty()) {
                 return null;
             }
-            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), context.getType(boolean.class), TypeSystemCodeGenerator.isImplicitTypeMethodName(type));
+            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, STATIC), context.getType(boolean.class), TypeSystemCodeGenerator.isImplicitTypeMethodName(type));
             method.addParameter(new CodeVariableElement(context.getType(Object.class), LOCAL_VALUE));
             if (typed) {
                 method.addParameter(new CodeVariableElement(context.getType(Class.class), "typeHint"));
@@ -154,7 +258,7 @@
                 if (typed) {
                     builder.string("(typeHint == ").typeLiteral(sourceType.getPrimitiveType()).string(" && ");
                 }
-                builder.startCall(isTypeMethodName(sourceType)).string(LOCAL_VALUE).end();
+                builder.tree(check(sourceType, LOCAL_VALUE));
                 if (typed) {
                     builder.string(")");
                 }
@@ -176,7 +280,7 @@
             if (casts.isEmpty()) {
                 return null;
             }
-            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), type.getPrimitiveType(), TypeSystemCodeGenerator.asImplicitTypeMethodName(type));
+            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, STATIC), type.getPrimitiveType(), TypeSystemCodeGenerator.asImplicitTypeMethodName(type));
             method.addParameter(new CodeVariableElement(context.getType(Object.class), LOCAL_VALUE));
             if (typed) {
                 method.addParameter(new CodeVariableElement(context.getType(Class.class), "typeHint"));
@@ -191,7 +295,7 @@
                 if (typed) {
                     builder.string("typeHint == ").typeLiteral(sourceType.getPrimitiveType());
                 } else {
-                    builder.startCall(isTypeMethodName(sourceType)).string(LOCAL_VALUE).end();
+                    builder.tree(check(sourceType, LOCAL_VALUE));
                 }
 
                 builder.end().startBlock();
@@ -201,7 +305,7 @@
                 if (cast != null) {
                     builder.startCall(cast.getMethodName());
                 }
-                builder.startCall(asTypeMethodName(sourceType)).string(LOCAL_VALUE).end();
+                builder.tree(cast(sourceType, LOCAL_VALUE)).end();
                 if (cast != null) {
                     builder.end();
                 }
@@ -221,7 +325,7 @@
             if (casts.isEmpty()) {
                 return null;
             }
-            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), context.getType(Class.class), TypeSystemCodeGenerator.getImplicitClass(type));
+            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, STATIC), context.getType(Class.class), TypeSystemCodeGenerator.getImplicitClass(type));
             method.addParameter(new CodeVariableElement(context.getType(Object.class), LOCAL_VALUE));
 
             List<TypeData> sourceTypes = typeSystem.lookupSourceTypes(type);
@@ -229,7 +333,7 @@
             boolean elseIf = false;
             for (TypeData sourceType : sourceTypes) {
                 elseIf = builder.startIf(elseIf);
-                builder.startCall(isTypeMethodName(sourceType)).string(LOCAL_VALUE).end();
+                builder.tree(check(sourceType, LOCAL_VALUE)).end();
                 builder.end().startBlock();
                 builder.startReturn().typeLiteral(sourceType.getPrimitiveType()).end();
                 builder.end();
@@ -248,16 +352,11 @@
                 return null;
             }
 
-            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), context.getType(boolean.class), TypeSystemCodeGenerator.isTypeMethodName(type));
+            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, STATIC), context.getType(boolean.class), TypeSystemCodeGenerator.isTypeMethodName(type));
             method.addParameter(new CodeVariableElement(context.getType(Object.class), LOCAL_VALUE));
 
-            DeclaredType suppressWarnings = (DeclaredType) context.getType(SuppressWarnings.class);
-            CodeAnnotationMirror annotationMirror = new CodeAnnotationMirror(suppressWarnings);
-            annotationMirror.setElementValue(annotationMirror.findExecutableElement("value"), new CodeAnnotationValue("static-method"));
-            method.getAnnotationMirrors().add(annotationMirror);
-
             CodeTreeBuilder body = method.createBuilder();
-            body.startReturn().instanceOf(LOCAL_VALUE, type.getBoxedType()).end();
+            body.startReturn().tree(check(type, LOCAL_VALUE)).end();
 
             return method;
         }
@@ -267,25 +366,25 @@
                 return null;
             }
 
-            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), type.getPrimitiveType(), TypeSystemCodeGenerator.asTypeMethodName(type));
+            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, STATIC), type.getPrimitiveType(), TypeSystemCodeGenerator.asTypeMethodName(type));
             method.addParameter(new CodeVariableElement(context.getType(Object.class), LOCAL_VALUE));
 
             CodeTreeBuilder body = method.createBuilder();
             String assertMessage = typeName(typeSystem) + "." + asTypeMethodName(type) + ": " + ElementUtils.getSimpleName(type.getBoxedType()) + " expected";
-            body.startAssert().startCall(isTypeMethodName(type)).string(LOCAL_VALUE).end().string(" : ").doubleQuote(assertMessage).end();
-            body.startReturn().cast(type.getPrimitiveType(), body.create().string(LOCAL_VALUE).getTree()).end();
+            body.startAssert().tree(check(type, LOCAL_VALUE)).string(" : ").doubleQuote(assertMessage).end();
+            body.startReturn().tree(cast(type, LOCAL_VALUE)).end();
 
             return method;
         }
 
         private CodeExecutableElement createExpectTypeMethod(TypeData expectedType, TypeData sourceType) {
-            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), expectedType.getPrimitiveType(), TypeSystemCodeGenerator.expectTypeMethodName(expectedType));
+            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, STATIC), expectedType.getPrimitiveType(), TypeSystemCodeGenerator.expectTypeMethodName(expectedType));
             method.addParameter(new CodeVariableElement(sourceType.getPrimitiveType(), LOCAL_VALUE));
             method.addThrownType(context.getTruffleTypes().getUnexpectedValueException());
 
             CodeTreeBuilder body = method.createBuilder();
-            body.startIf().startCall(TypeSystemCodeGenerator.isTypeMethodName(expectedType)).string(LOCAL_VALUE).end().end().startBlock();
-            body.startReturn().startCall(TypeSystemCodeGenerator.asTypeMethodName(expectedType)).string(LOCAL_VALUE).end().end();
+            body.startIf().tree(check(expectedType, LOCAL_VALUE)).end().startBlock();
+            body.startReturn().tree(cast(expectedType, LOCAL_VALUE)).end().end();
             body.end(); // if-block
             body.startThrow().startNew(context.getTruffleTypes().getUnexpectedValueException()).string(LOCAL_VALUE).end().end();
 
@@ -293,4 +392,5 @@
         }
 
     }
+
 }
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeTreeBuilder.java	Mon Dec 29 23:38:39 2014 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeTreeBuilder.java	Mon Dec 29 23:38:42 2014 +0100
@@ -663,8 +663,11 @@
     }
 
     public CodeTreeBuilder instanceOf(CodeTree var, CodeTree type) {
-        tree(var).string(" instanceof ").tree(type);
-        return this;
+        return tree(var).string(" instanceof ").tree(type);
+    }
+
+    public CodeTreeBuilder instanceOf(CodeTree var, TypeMirror type) {
+        return tree(var).string(" instanceof ").type(type);
     }
 
     public CodeTreeBuilder instanceOf(String var, String type) {
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/TypeData.java	Mon Dec 29 23:38:39 2014 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/TypeData.java	Mon Dec 29 23:38:42 2014 +0100
@@ -52,6 +52,14 @@
         return index;
     }
 
+    public boolean isDefaultCast() {
+        return getTypeCasts().isEmpty();
+    }
+
+    public boolean isDefaultCheck() {
+        return getTypeChecks().isEmpty();
+    }
+
     @Override
     public Element getMessageElement() {
         return typeSystem.getMessageElement();
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/ImplicitCastParser.java	Mon Dec 29 23:38:39 2014 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/ImplicitCastParser.java	Mon Dec 29 23:38:42 2014 +0100
@@ -68,6 +68,10 @@
             method.addError("Target type and source type of an @%s must not be the same type.", ImplicitCast.class.getSimpleName());
         }
 
+        if (!method.getMethod().getModifiers().contains(Modifier.STATIC)) {
+            method.addError("@%s annotated method %s must be static.", ImplicitCast.class.getSimpleName(), method.getMethodName());
+        }
+
         return new ImplicitCastData(method, sourceType, targetType);
     }
 }
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/TypeCastParser.java	Mon Dec 29 23:38:39 2014 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/TypeCastParser.java	Mon Dec 29 23:38:42 2014 +0100
@@ -63,6 +63,10 @@
         }
         TypeCastData cast = new TypeCastData(method, sourceType, targetType);
 
+        if (!method.getMethod().getModifiers().contains(Modifier.STATIC)) {
+            cast.addError("@%s annotated method %s must be static.", TypeCast.class.getSimpleName(), method.getMethodName());
+        }
+
         if (targetType != method.getReturnType().getTypeSystemType()) {
             cast.addError("Cast type %s does not match to the returned type %s.", ElementUtils.getSimpleName(targetType.getPrimitiveType()),
                             method.getReturnType() != null ? ElementUtils.getSimpleName(method.getReturnType().getTypeSystemType().getPrimitiveType()) : null);
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/TypeCheckParser.java	Mon Dec 29 23:38:39 2014 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/TypeCheckParser.java	Mon Dec 29 23:38:42 2014 +0100
@@ -53,6 +53,9 @@
         assert checkedType != null;
         Parameter parameter = method.findParameter("valueValue");
         assert parameter != null;
+        if (!method.getMethod().getModifiers().contains(Modifier.STATIC)) {
+            method.addError("@%s annotated method %s must be static.", TypeCheck.class.getSimpleName(), method.getMethodName());
+        }
         return new TypeCheckData(method, checkedType, parameter.getTypeSystemType());
     }