# HG changeset patch # User twisti # Date 1371839927 25200 # Node ID c43c4938e353abf1b7c1f1522794dbbc4c32b716 # Parent cfbe4f978116a919a6de93e4b5cf5969ecd6482a# Parent e4dd840a39de94a613a353b382e5e3a15c6e58d9 Merge diff -r cfbe4f978116 -r c43c4938e353 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizeOp.java diff -r cfbe4f978116 -r c43c4938e353 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64TailcallOp.java diff -r cfbe4f978116 -r c43c4938e353 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Fri Jun 21 11:38:40 2013 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Fri Jun 21 11:38:47 2013 -0700 @@ -126,7 +126,7 @@ Word hub = loadWordFromObject(elementType, arrayKlassOffset()); if (hub.equal(Word.zero())) { // the array class is not yet loaded - DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.Unresolved); + DeoptimizeNode.deopt(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved); } int layoutHelper = readLayoutHelper(hub); @@ -143,8 +143,8 @@ // esz is the element size in bytes //@formatter:on - int headerSize = (layoutHelper >> 16) & 0xFF; - int log2ElementSize = layoutHelper & 0xFF; + int headerSize = (layoutHelper >> layoutHelperHeaderSizeShift()) & layoutHelperHeaderSizeMask(); + int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift()) & layoutHelperLog2ElementSizeMask(); Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION); return allocateArray(hub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents); diff -r cfbe4f978116 -r c43c4938e353 graal/com.oracle.graal.service.processor/src/com/oracle/graal/service/processor/ServiceProviderProcessor.java diff -r cfbe4f978116 -r c43c4938e353 graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/CreateCast.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/CreateCast.java Fri Jun 21 11:38:47 2013 -0700 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.api.codegen; + +import java.lang.annotation.*; + +import com.oracle.truffle.api.nodes.*; + +/** + * Specifies a factory method that creates a {@link Node} which is used to cast this child. + */ +@Retention(RetentionPolicy.CLASS) +@Target({ElementType.METHOD}) +public @interface CreateCast { + + String[] value(); + +} diff -r cfbe4f978116 -r c43c4938e353 graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/ExecuteChildren.java --- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/ExecuteChildren.java Fri Jun 21 11:38:40 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.codegen; - -import java.lang.annotation.*; - -@Retention(RetentionPolicy.CLASS) -@Target({ElementType.TYPE}) -public @interface ExecuteChildren { - - String[] value(); - -} diff -r cfbe4f978116 -r c43c4938e353 graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/ExtensionAnnotation.java --- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/ExtensionAnnotation.java Fri Jun 21 11:38:40 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.codegen; - -import java.lang.annotation.*; - -@Retention(RetentionPolicy.CLASS) -@Target({ElementType.ANNOTATION_TYPE}) -public @interface ExtensionAnnotation { - - String processorClassName(); - -} diff -r cfbe4f978116 -r c43c4938e353 graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeChild.java --- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeChild.java Fri Jun 21 11:38:40 2013 -0700 +++ b/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeChild.java Fri Jun 21 11:38:47 2013 -0700 @@ -26,6 +26,10 @@ import com.oracle.truffle.api.nodes.*; +/** + * A {@link NodeChild} element defines an executable child for the enclosing {@link Node}. A + * {@link Node} contains multiple {@link NodeChildren} specified in linear execution order. + */ @Retention(RetentionPolicy.CLASS) @Target({ElementType.TYPE}) public @interface NodeChild { @@ -35,13 +39,13 @@ Class type() default NodeClass.InheritNode.class; /** - * Executes the {@link NodeChild} with values from other defined {@link NodeChild} elements. - * These referenced children must be defined before the current node in the execution order. The - * current node {@link #type()} attribute must be set to a {@link Node} which supports the - * evaluated execution with the number of {@link #executeWith()} arguments that are defined. For - * example if this child is executed with one argument, the {@link #type()} attribute must - * define a node which publicly declares a method with the signature - * Object execute*(VirtualFrame, Object). + * The {@link #executeWith()} property allows a node to pass the result of one child's + * executable as an input to another child's executable. These referenced children must be + * defined before the current node in the execution order. The current node {@link #type()} + * attribute must be set to a {@link Node} which supports the evaluated execution with the + * number of {@link #executeWith()} arguments that are defined. For example if this child is + * executed with one argument, the {@link #type()} attribute must define a node which publicly + * declares a method with the signature Object execute*(VirtualFrame, Object). */ String[] executeWith() default {}; } diff -r cfbe4f978116 -r c43c4938e353 graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/TypeSystem.java --- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/TypeSystem.java Fri Jun 21 11:38:40 2013 -0700 +++ b/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/TypeSystem.java Fri Jun 21 11:38:47 2013 -0700 @@ -24,42 +24,56 @@ import java.lang.annotation.*; +import com.oracle.truffle.api.nodes.*; + /** *

- * Annotates a type system class that represents type information for a node. Generates code for - * converting and managing types. Methods contained in the type system may be annotated with - * {@link TypeCast} or {@link TypeCheck}. These methods alter the default behavior of the type - * system. + * Each {@link Node} has one {@link TypeSystem} at its root to define the types that can be used + * throughout the system. Multiple {@link TypeSystem}s are allowed, but they cannot be mixed inside + * a single {@link Node} hierarchy. A {@link TypeSystem} defines a list of types as its child + * elements, in which every type precedes its super types.The latter condition ensures that the most + * concrete type is found first when searching the list sequentially for the type of a given generic + * value. *

* - * - * Example: *

- * Shows a @TypeSystem definition with three types. In this example BigIntegers can be - * also treated as integers if their bit width is less than 32. + * Each {@link #value()} is represented as a java type. A type can specify two annotations: + * {@link TypeCheck} and {@link TypeCast}. The {@link TypeCheck} checks whether a given generic + * value matches to the current type. The {@link TypeCast} casts a generic type value to the current + * type. If the {@link TypeCheck} and {@link TypeCast} annotations are not declared in the + * {@link TypeSystem} the a default implementation is provided. The default implementation of + * {@link TypeCheck} returns true only on an exact type match and {@link TypeCast} is + * only a cast to this type. Specified methods with {@link TypeCheck} and {@link TypeCast} may be + * used to extend the definition of a type in the language. In our example, the + * isInteger and asInteger methods are defined in a way so that they + * accept also {@link Integer} values, implicitly converting them to {@link Double} . This example + * points out how we express implicit type conversions. *

* + *

+ * Example: The {@link TypeSystem} contains the types {@link Boolean}, {@link Integer}, and + * {@link Double}. The type {@link Object} is always used implicitly as the generic type represent + * all values. + * *

  * 
- * {@literal @}TypeSystem(types = {int.class, BigInteger.class, String.class}, nodeBaseClass = TypedNode.class)
- * public abstract class Types {
+ * {@literal @}TypeSystem(types = {boolean.class, int.class, double.class})
+ * public abstract class ExampleTypeSystem {
  * 
  *     {@literal @}TypeCheck
  *     public boolean isInteger(Object value) {
- *         return value instanceof Integer || (value instanceof BigInteger && ((BigInteger) value).bitLength() < Integer.SIZE);
+ *         return value instanceof Integer || value instanceof Double;
  *     }
  * 
  *     {@literal @}TypeCast
- *     public int asInteger(Object value) {
- *         if (value instanceof Integer) {
- *             return (int) value;
- *         } else {
- *             return ((BigInteger) value).intValue();
- *         }
+ *     public double asInteger(Object value) {
+ *         return ((Number)value).doubleValue();
  *     }
  * }
  * 
* + *

+ * * @see TypeCast * @see TypeCheck */ @@ -68,8 +82,7 @@ public @interface TypeSystem { /** - * Sets the types contained by this type system. The order of types also determines the order of - * specialization. + * The list of types as child elements of the {@link TypeSystem}. Each precedes its super type. */ Class[] value(); diff -r cfbe4f978116 -r c43c4938e353 graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/TypeSystemReference.java --- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/TypeSystemReference.java Fri Jun 21 11:38:40 2013 -0700 +++ b/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/TypeSystemReference.java Fri Jun 21 11:38:47 2013 -0700 @@ -24,10 +24,20 @@ import java.lang.annotation.*; +import com.oracle.truffle.api.nodes.*; + +/** + * References a {@link TypeSystem} on a node. Must be applied on a {@link Node} class. At least one + * {@link TypeSystem} must be referenced in a {@link Node}'s type hierarchy. + * + * @see TypeSystem + * @see Node + */ @Retention(RetentionPolicy.CLASS) @Target({ElementType.TYPE}) public @interface TypeSystemReference { + /** The {@link TypeSystem} java type. */ Class value(); } diff -r cfbe4f978116 -r c43c4938e353 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Utils.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Utils.java Fri Jun 21 11:38:40 2013 -0700 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Utils.java Fri Jun 21 11:38:47 2013 -0700 @@ -583,8 +583,13 @@ List values = getAnnotationValue(List.class, mirror, name); List result = new ArrayList<>(); - for (AnnotationValue value : values) { - result.add(resolveAnnotationValue(expectedListType, value)); + if (values != null) { + for (AnnotationValue value : values) { + T annotationValue = resolveAnnotationValue(expectedListType, value); + if (annotationValue != null) { + result.add(annotationValue); + } + } } return result; } @@ -595,6 +600,10 @@ @SuppressWarnings({"unchecked"}) private static T resolveAnnotationValue(Class expectedType, AnnotationValue value) { + if (value == null) { + return null; + } + Object unboxedValue = value.accept(new AnnotationValueVisitorImpl(), null); if (unboxedValue != null) { if (expectedType == TypeMirror.class && unboxedValue instanceof String) { diff -r cfbe4f978116 -r c43c4938e353 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTreeBuilder.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTreeBuilder.java Fri Jun 21 11:38:40 2013 -0700 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTreeBuilder.java Fri Jun 21 11:38:47 2013 -0700 @@ -563,7 +563,7 @@ public ExecutableElement findMethod() { Element element = currentElement; - while (element != null && (element.getKind() != ElementKind.METHOD)) { + while (element != null && (element.getKind() != ElementKind.METHOD && (element.getKind() != ElementKind.CONSTRUCTOR))) { element = element.getEnclosingElement(); } ExecutableElement found = element != null ? (ExecutableElement) element : null; diff -r cfbe4f978116 -r c43c4938e353 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ext/ExtensionCodeElementFactory.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ext/ExtensionCodeElementFactory.java Fri Jun 21 11:38:40 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.codegen.processor.ext; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; - -import com.oracle.truffle.codegen.processor.*; -import com.oracle.truffle.codegen.processor.api.element.*; -import com.oracle.truffle.codegen.processor.ast.*; - -final class ExtensionCodeElementFactory implements WritableElementFactory { - - private final ProcessorContext context; - - Element generatorElement; - AnnotationMirror generatorAnnotationMirror; - - public ExtensionCodeElementFactory(ProcessorContext context) { - this.context = context; - } - - @Override - public WritableExecutableElement cloneExecutableElement(ExecutableElement method) { - return updateGenerators(CodeExecutableElement.clone(context.getEnvironment(), method)); - } - - @Override - public WritableVariableElement cloneVariableElement(VariableElement var) { - return updateGenerators(CodeVariableElement.clone(var)); - } - - @Override - public WritableAnnotationMirror cloneAnnotationMirror(AnnotationMirror mirror) { - return CodeAnnotationMirror.clone(mirror); - } - - @Override - public WritableVariableElement createParameter(TypeMirror type, String simpleName) { - return updateGenerators(new CodeVariableElement(Utils.modifiers(), type, simpleName)); - } - - @Override - public WritableExecutableElement createExecutableElement(TypeMirror returnType, String methodName) { - return updateGenerators(new CodeExecutableElement(returnType, methodName)); - } - - @Override - public TypeMirror createTypeMirror(Class javaClass) { - return context.getType(javaClass); - } - - @Override - public WritableAnnotationMirror createAnnotationMirror(DeclaredType typeMirror) { - return new CodeAnnotationMirror(typeMirror); - } - - @Override - public Name createName(String name) { - return CodeNames.of(name); - } - - @Override - public AnnotationValue createAnnotationValue(Object value) { - return new CodeAnnotationValue(value); - } - - private E updateGenerators(E element) { - element.setGeneratorElement(generatorElement); - element.setGeneratorAnnotationMirror(generatorAnnotationMirror); - return element; - } - -} diff -r cfbe4f978116 -r c43c4938e353 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ext/ExtensionContextImpl.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ext/ExtensionContextImpl.java Fri Jun 21 11:38:40 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.codegen.processor.ext; - -import java.util.*; - -import javax.annotation.processing.*; - -import com.oracle.truffle.codegen.processor.api.*; -import com.oracle.truffle.codegen.processor.api.element.*; - -public class ExtensionContextImpl implements ExtensionContext { - - private final ProcessingEnvironment env; - private final RoundEnvironment round; - private final WritableElementFactory factory; - - private final List elements = new ArrayList<>(); - - public ExtensionContextImpl(ProcessingEnvironment env, RoundEnvironment round, WritableElementFactory factory) { - this.env = env; - this.round = round; - this.factory = factory; - } - - List returnElements() { - List returnElements = new ArrayList<>(this.elements); - this.elements.clear(); - return returnElements; - } - - @Override - public ProcessingEnvironment getProcessingEnvironment() { - return env; - } - - @Override - public RoundEnvironment getRoundEnvironment() { - return round; - } - - @Override - public WritableElementFactory getElementFactory() { - return factory; - } - - @Override - public void addGeneratedElement(WritableElement element) { - elements.add(element); - } - - @Override - public void removeGeneratedElement(WritableElement element) { - elements.remove(element); - } - -} diff -r cfbe4f978116 -r c43c4938e353 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ext/ExtensionParser.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ext/ExtensionParser.java Fri Jun 21 11:38:40 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.codegen.processor.ext; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.util.*; - -import com.oracle.truffle.api.codegen.*; -import com.oracle.truffle.codegen.processor.*; -import com.oracle.truffle.codegen.processor.api.*; -import com.oracle.truffle.codegen.processor.api.element.*; -import com.oracle.truffle.codegen.processor.template.*; - -public class ExtensionParser { - - private final Map extensions = new HashMap<>(); - private final ProcessorContext context; - private final ExtensionCodeElementFactory factory; - private final ExtensionContextImpl extensionContext; - - public ExtensionParser(ProcessorContext context) { - this.context = context; - this.factory = new ExtensionCodeElementFactory(context); - this.extensionContext = new ExtensionContextImpl(context.getEnvironment(), null, factory); - } - - public List parseAll(Template template, List elements) { - List generatedMethods = new ArrayList<>(); - parseElement(template, generatedMethods, template.getTemplateType()); - - List methods = ElementFilter.methodsIn(elements); - for (ExecutableElement method : methods) { - for (VariableElement var : method.getParameters()) { - parseElement(template, generatedMethods, var); - } - parseElement(template, generatedMethods, method); - } - - return generatedMethods; - } - - private void parseElement(Template template, List elements, Element element) { - List mirrors = element.getAnnotationMirrors(); - for (AnnotationMirror mirror : mirrors) { - ExtensionProcessor processor = findProcessor(template, mirror); - if (processor != null) { - try { - factory.generatorAnnotationMirror = mirror; - factory.generatorElement = element; - processor.process(extensionContext, mirror, element); - elements.addAll(extensionContext.returnElements()); - } catch (Throwable e) { - template.addError("Processor for '%s' failed with exception: \n\n%s.", Utils.getQualifiedName(mirror.getAnnotationType()), Utils.printException(e)); - } finally { - factory.generatorAnnotationMirror = null; - factory.generatorElement = null; - } - } - } - } - - private ExtensionProcessor findProcessor(Template template, AnnotationMirror mirror) { - String processorName = Utils.getQualifiedName(mirror.getAnnotationType()); - ExtensionProcessor processor = null; - if (extensions.containsKey(processorName)) { - processor = extensions.get(processorName); - } else { - AnnotationMirror foundExtension = Utils.findAnnotationMirror(context.getEnvironment(), mirror.getAnnotationType().asElement(), ExtensionAnnotation.class); - if (foundExtension != null) { - String className = Utils.getAnnotationValue(String.class, foundExtension, "processorClassName"); - Class processorClass; - try { - processorClass = Class.forName(className); - } catch (ClassNotFoundException e) { - template.addError("Could not find processor class '%s' configured in '@%s'.", className, processorName); - return null; - } - try { - processor = (ExtensionProcessor) processorClass.newInstance(); - } catch (InstantiationException e) { - template.addError("Could not instantiate processor class '%s' configured in '@%s'.", className, processorName); - return null; - } catch (IllegalAccessException e) { - template.addError("Could not access processor class '%s' configured in '@%s'.", className, processorName); - return null; - } catch (ClassCastException e) { - template.addError("Processor class '%s' configured in '@%s' does not implement '%s'.", className, processorName, ExtensionProcessor.class.getName()); - return null; - } - } - extensions.put(processorName, processor); - } - return processor; - } - -} diff -r cfbe4f978116 -r c43c4938e353 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/CreateCastData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/CreateCastData.java Fri Jun 21 11:38:47 2013 -0700 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.codegen.processor.node; + +import java.util.*; + +import com.oracle.truffle.codegen.processor.template.*; + +public class CreateCastData extends TemplateMethod { + + private final List childNames; + + public CreateCastData(TemplateMethod method, List childNames) { + super(method); + this.childNames = childNames; + } + + public List getChildNames() { + return childNames; + } + +} diff -r cfbe4f978116 -r c43c4938e353 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/CreateCastParser.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/CreateCastParser.java Fri Jun 21 11:38:47 2013 -0700 @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.codegen.processor.node; + +import java.lang.annotation.*; +import java.util.*; + +import javax.lang.model.element.*; +import javax.lang.model.type.*; + +import com.oracle.truffle.api.codegen.*; +import com.oracle.truffle.codegen.processor.*; +import com.oracle.truffle.codegen.processor.template.*; + +public class CreateCastParser extends NodeMethodParser { + + public CreateCastParser(ProcessorContext context, NodeData operation) { + super(context, operation); + } + + @Override + public Class getAnnotationType() { + return CreateCast.class; + } + + @Override + public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) { + List childNames = Utils.getAnnotationValueList(String.class, mirror, "value"); + TypeMirror baseType = getContext().getTruffleTypes().getNode(); + for (String childName : childNames) { + NodeChildData child = getNode().findChild(childName); + if (child != null) { + baseType = child.getOriginalType(); + break; + } + } + MethodSpec spec = new MethodSpec(new InheritsParameterSpec(getContext(), "child", baseType)); + addDefaultFieldMethodSpec(method, spec); + spec.addRequired(new ParameterSpec("castedChild", baseType)).setSignature(true); + return spec; + } + + @Override + public CreateCastData create(TemplateMethod method) { + AnnotationMirror mirror = method.getMarkerAnnotation(); + List childNames = Utils.getAnnotationValueList(String.class, mirror, "value"); + CreateCastData cast = new CreateCastData(method, childNames); + AnnotationValue value = Utils.getAnnotationValue(mirror, "value"); + TypeMirror type = null; + if (childNames == null || childNames.isEmpty()) { + cast.addError(value, "No value specified but required."); + return cast; + } + + for (String childName : childNames) { + NodeChildData child = getNode().findChild(childName); + if (child == null) { + // error + cast.addError(value, "Specified child '%s' not found.", childName); + continue; + } + if (type == null) { + type = child.getNodeType(); + } else if (!Utils.typeEquals(type, child.getNodeType())) { + cast.addError(value, "All child nodes for a cast must have the same node type."); + continue; + } + } + return cast; + } + + private static class InheritsParameterSpec extends ParameterSpec { + + private final ProcessorContext context; + + public InheritsParameterSpec(ProcessorContext context, String name, TypeMirror... allowedTypes) { + super(name, Arrays.asList(allowedTypes)); + this.context = context; + } + + @Override + public boolean matches(TypeMirror actualType) { + boolean found = false; + for (TypeMirror specType : getAllowedTypes()) { + if (Utils.isAssignable(context, actualType, specType)) { + found = true; + break; + } + } + return found; + } + } +} diff -r cfbe4f978116 -r c43c4938e353 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeChildData.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeChildData.java Fri Jun 21 11:38:40 2013 -0700 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeChildData.java Fri Jun 21 11:38:47 2013 -0700 @@ -54,6 +54,7 @@ private final String name; private final TypeMirror type; + private final TypeMirror originalType; private final Element accessElement; private final Cardinality cardinality; @@ -63,11 +64,13 @@ private NodeData nodeData; - public NodeChildData(Element sourceElement, AnnotationMirror sourceMirror, String name, TypeMirror nodeType, Element accessElement, Cardinality cardinality, ExecutionKind executionKind) { + public NodeChildData(Element sourceElement, AnnotationMirror sourceMirror, String name, TypeMirror nodeType, TypeMirror originalNodeType, Element accessElement, Cardinality cardinality, + ExecutionKind executionKind) { this.sourceElement = sourceElement; this.sourceAnnotationMirror = sourceMirror; this.name = name; this.type = nodeType; + this.originalType = originalNodeType; this.accessElement = accessElement; this.cardinality = cardinality; this.executionKind = executionKind; @@ -101,6 +104,10 @@ return nodeData.getExecutableTypes(getExecuteWith().size()); } + public TypeMirror getOriginalType() { + return originalType; + } + @Override public Element getMessageElement() { return sourceElement; diff -r cfbe4f978116 -r c43c4938e353 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java Fri Jun 21 11:38:40 2013 -0700 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java Fri Jun 21 11:38:47 2013 -0700 @@ -143,7 +143,8 @@ } } - private CodeTree createTemplateMethodCall(CodeTreeBuilder parent, CodeTree target, TemplateMethod sourceMethod, TemplateMethod targetMethod, String unexpectedValueName) { + private CodeTree createTemplateMethodCall(CodeTreeBuilder parent, CodeTree target, TemplateMethod sourceMethod, TemplateMethod targetMethod, String unexpectedValueName, + String... customSignatureValueNames) { CodeTreeBuilder builder = parent.create(); boolean castedValues = sourceMethod != targetMethod; @@ -199,8 +200,13 @@ } builder.startCall(method.getSimpleName().toString()); + int signatureIndex = 0; + for (ActualParameter targetParameter : targetMethod.getParameters()) { - ActualParameter valueParameter = sourceMethod.findParameter(targetParameter.getLocalName()); + ActualParameter valueParameter = null; + if (sourceMethod != null) { + valueParameter = sourceMethod.findParameter(targetParameter.getLocalName()); + } if (valueParameter == null) { valueParameter = targetParameter; } @@ -215,7 +221,10 @@ valueType = valueParameter.getTypeSystemType(); } - if (targetParameter.getSpecification().isLocal()) { + if (signatureIndex < customSignatureValueNames.length && targetParameter.getSpecification().isSignature()) { + builder.string(customSignatureValueNames[signatureIndex]); + signatureIndex++; + } else if (targetParameter.getSpecification().isLocal()) { builder.startGroup(); if (builder.findMethod().getModifiers().contains(Modifier.STATIC)) { builder.string(THIS_NODE_LOCAL_VAR_NAME).string("."); @@ -522,8 +531,25 @@ return builder.getRoot(); } - private void emitEncounteredSynthetic(CodeTreeBuilder builder) { - builder.startThrow().startNew(getContext().getType(UnsupportedOperationException.class)).end().end(); + private void emitEncounteredSynthetic(CodeTreeBuilder builder, SpecializationData current) { + builder.startThrow().startNew(getContext().getType(UnsupportedOperationException.class)); + builder.startGroup(); + String sep = null; + for (ActualParameter parameters : current.getParameters()) { + if (parameters.getSpecification().isSignature()) { + if (sep == null) { + builder.doubleQuote("Unsupported values: " + parameters.getLocalName() + " = "); + sep = ", "; + } else { + builder.string(" + "); + builder.doubleQuote(sep + parameters.getLocalName() + " = "); + } + builder.string(" + "); + builder.string(parameters.getLocalName()); + } + } + builder.end(); + builder.end().end(); } private static List findUserConstructors(TypeMirror nodeType) { @@ -669,7 +695,12 @@ } for (VariableElement var : type.getFields()) { - method.getParameters().add(new CodeVariableElement(var.asType(), var.getSimpleName().toString())); + NodeChildData child = getModel().findChild(var.getSimpleName().toString()); + if (child != null) { + method.getParameters().add(new CodeVariableElement(child.getOriginalType(), child.getName())); + } else { + method.getParameters().add(new CodeVariableElement(var.asType(), var.getSimpleName().toString())); + } } if (superConstructor != null) { @@ -682,14 +713,25 @@ for (VariableElement var : type.getFields()) { builder.startStatement(); - String varName = var.getSimpleName().toString(); - builder.string("this.").string(varName); + String fieldName = var.getSimpleName().toString(); + + CodeTree fieldInit = CodeTreeBuilder.singleString(var.getSimpleName().toString()); + builder.string("this.").string(var.getSimpleName().toString()); + + NodeChildData child = getModel().findChild(fieldName); + if (child != null) { + CreateCastData createCast = getModel().findCast(child.getName()); + if (createCast != null) { + fieldInit = createTemplateMethodCall(builder, null, getModel().getGenericSpecialization(), createCast, null, child.getName()); + } + } + if (Utils.isAssignable(getContext(), var.asType(), getContext().getTruffleTypes().getNode())) { - builder.string(" = adoptChild(").string(varName).string(")"); + builder.string(" = adoptChild(").tree(fieldInit).string(")"); } else if (Utils.isAssignable(getContext(), var.asType(), getContext().getTruffleTypes().getNodeArray())) { - builder.string(" = adoptChildren(").string(varName).string(")"); + builder.string(" = adoptChildren(").tree(fieldInit).string(")"); } else { - builder.string(" = ").string(varName); + builder.string(" = ").tree(fieldInit); } builder.end(); } @@ -832,7 +874,7 @@ unreachableSpecializations.add(specialization); } else { filteredSpecializations.add(specialization); - if (!specialization.isUninitialized() && !specialization.hasRewrite(getContext())) { + if (!specialization.isUninitialized() && specialization.isGenericSpecialization(getContext())) { unreachable = true; } } @@ -877,7 +919,7 @@ } if (specialize && executeCall == null && !current.getNode().getGenericSpecialization().isUseSpecializationsForGeneric()) { - emitEncounteredSynthetic(builder); + emitEncounteredSynthetic(builder, current); } else if (specialize) { if (current.getNode().getGenericSpecialization().isUseSpecializationsForGeneric()) { @@ -890,7 +932,7 @@ } builder.statement("resultIsSet = true"); } else { - emitEncounteredSynthetic(builder); + emitEncounteredSynthetic(builder, current); } builder.end(); } @@ -922,7 +964,7 @@ } } else { if (executeCall == null) { - emitEncounteredSynthetic(builder); + emitEncounteredSynthetic(builder, current); } else { builder.startReturn().tree(executeCall).end(); } @@ -1165,7 +1207,7 @@ CodeTreeBuilder builder = method.createBuilder(); if (!node.needsRewrites(getContext())) { - builder.startThrow().startNew(getContext().getType(UnsupportedOperationException.class)).end().end(); + builder.startThrow().startNew(getContext().getType(UnsupportedOperationException.class)).doubleQuote("No specialized version.").end().end(); } else { builder.startIf(); builder.string("types.length == 1"); @@ -1668,7 +1710,7 @@ returnBuilder.doubleQuote("Uninitialized"); returnBuilder.end(); } else if (specialization.getMethod() == null && !node.needsRewrites(context)) { - emitEncounteredSynthetic(builder); + emitEncounteredSynthetic(builder, specialization); } else if (specialization.isGeneric()) { returnBuilder.startCall("super", EXECUTE_GENERIC_NAME); addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, true); diff -r cfbe4f978116 -r c43c4938e353 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java Fri Jun 21 11:38:40 2013 -0700 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java Fri Jun 21 11:38:47 2013 -0700 @@ -50,6 +50,7 @@ private Map> executableTypes; private List shortCircuits; private List assumptions; + private List casts; private String shortName; @@ -74,6 +75,14 @@ this.assumptions = splitSource.assumptions; } + public List getCasts() { + return casts; + } + + void setCasts(List casts) { + this.casts = casts; + } + void setShortName(String shortName) { this.shortName = shortName; } @@ -133,6 +142,9 @@ if (fields != null) { containerChildren.addAll(fields); } + if (casts != null) { + containerChildren.addAll(casts); + } return containerChildren; } @@ -230,6 +242,9 @@ methods.addAll(getSpecializationListeners()); methods.addAll(getExecutableTypes()); methods.addAll(getShortCircuits()); + if (getCasts() != null) { + methods.addAll(getCasts()); + } return methods; } @@ -367,6 +382,7 @@ dumpProperty(builder, indent, "executableTypes", getExecutableTypes()); dumpProperty(builder, indent, "specializations", getSpecializations()); dumpProperty(builder, indent, "assumptions", getAssumptions()); + dumpProperty(builder, indent, "casts", getCasts()); dumpProperty(builder, indent, "messages", collectMessages()); if (getDeclaredNodes().size() > 0) { builder.append(String.format("\n%s children = [", indent)); @@ -489,4 +505,15 @@ return getClass().getSimpleName() + "[" + getNodeId() + "]"; } + public CreateCastData findCast(String name) { + if (getCasts() != null) { + for (CreateCastData cast : getCasts()) { + if (cast.getChildNames().contains(name)) { + return cast; + } + } + } + return null; + } + } diff -r cfbe4f978116 -r c43c4938e353 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeMethodParser.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeMethodParser.java Fri Jun 21 11:38:40 2013 -0700 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeMethodParser.java Fri Jun 21 11:38:47 2013 -0700 @@ -78,20 +78,15 @@ protected final MethodSpec createDefaultMethodSpec(ExecutableElement method, AnnotationMirror mirror, boolean shortCircuitsEnabled, String shortCircuitName) { MethodSpec methodSpec = new MethodSpec(createReturnParameterSpec()); - if (getNode().supportsFrame()) { - methodSpec.addOptional(new ParameterSpec("frame", getContext().getTruffleTypes().getFrame())); - } - - resolveAndAddImplicitThis(methodSpec, method); + addDefaultFrame(methodSpec); + addDefaultImplicitThis(method, methodSpec); + addDefaultFieldMethodSpec(method, methodSpec); + addDefaultChildren(shortCircuitsEnabled, shortCircuitName, methodSpec); - for (NodeFieldData field : getNode().getFields()) { - if (!Utils.isFieldAccessible(method, field.getVariable())) { - ParameterSpec spec = new ParameterSpec(field.getName(), field.getType()); - spec.setLocal(true); - methodSpec.addOptional(spec); - } - } + return methodSpec; + } + private void addDefaultChildren(boolean shortCircuitsEnabled, String shortCircuitName, MethodSpec methodSpec) { // children are null when parsing executable types if (getNode().getChildren() != null) { for (NodeChildData child : getNode().getChildren()) { @@ -117,11 +112,25 @@ } } } + } - return methodSpec; + private void addDefaultFrame(MethodSpec methodSpec) { + if (getNode().supportsFrame()) { + methodSpec.addOptional(new ParameterSpec("frame", getContext().getTruffleTypes().getFrame())); + } } - protected void resolveAndAddImplicitThis(MethodSpec methodSpec, ExecutableElement method) { + protected void addDefaultFieldMethodSpec(ExecutableElement method, MethodSpec methodSpec) { + for (NodeFieldData field : getNode().getFields()) { + if (!Utils.isFieldAccessible(method, field.getVariable())) { + ParameterSpec spec = new ParameterSpec(field.getName(), field.getType()); + spec.setLocal(true); + methodSpec.addOptional(spec); + } + } + } + + protected void addDefaultImplicitThis(ExecutableElement method, MethodSpec methodSpec) { TypeMirror declaredType = Utils.findNearestEnclosingType(method).asType(); if (!method.getModifiers().contains(Modifier.STATIC) && !Utils.isAssignable(getContext(), declaredType, getContext().getTruffleTypes().getNode())) { diff -r cfbe4f978116 -r c43c4938e353 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java Fri Jun 21 11:38:40 2013 -0700 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java Fri Jun 21 11:38:47 2013 -0700 @@ -42,7 +42,7 @@ public class NodeParser extends TemplateParser { public static final List> ANNOTATIONS = Arrays.asList(Generic.class, TypeSystemReference.class, ShortCircuit.class, Specialization.class, SpecializationListener.class, - ExecuteChildren.class, NodeClass.class, NodeChild.class, NodeChildren.class, NodeId.class); + NodeClass.class, NodeChild.class, NodeChildren.class, NodeId.class); private Map parsedNodes; @@ -211,6 +211,7 @@ private static List splitNodeData(NodeData node) { SortedMap> groupedSpecializations = groupByNodeId(node.getSpecializations()); SortedMap> groupedListeners = groupByNodeId(node.getSpecializationListeners()); + SortedMap> groupedCasts = groupByNodeId(node.getCasts()); Set ids = new TreeSet<>(); ids.addAll(groupedSpecializations.keySet()); @@ -220,6 +221,7 @@ for (String id : ids) { List specializations = groupedSpecializations.get(id); List listeners = groupedListeners.get(id); + List casts = groupedCasts.get(id); if (specializations == null) { specializations = new ArrayList<>(); @@ -238,12 +240,14 @@ copy.setSpecializations(specializations); copy.setSpecializationListeners(listeners); + copy.setCasts(casts); splitted.add(copy); } node.setSpecializations(new ArrayList()); node.setSpecializationListeners(new ArrayList()); + node.setCasts(new ArrayList()); return splitted; } @@ -266,6 +270,7 @@ node.setSpecializationListeners(new SpecializationListenerParser(context, node).parse(elements)); List generics = new GenericParser(context, node).parse(elements); List specializations = new SpecializationMethodParser(context, node).parse(elements); + node.setCasts(new CreateCastParser(context, node).parse(elements)); List allSpecializations = new ArrayList<>(); allSpecializations.addAll(generics); @@ -736,6 +741,18 @@ shortCircuits.add(Utils.getAnnotationValue(String.class, mirror, "value")); } } + Map castNodeTypes = new HashMap<>(); + for (ExecutableElement method : ElementFilter.methodsIn(elements)) { + AnnotationMirror mirror = Utils.findAnnotationMirror(processingEnv, method, CreateCast.class); + if (mirror != null) { + List children = (Utils.getAnnotationValueList(String.class, mirror, "value")); + if (children != null) { + for (String child : children) { + castNodeTypes.put(child, method.getReturnType()); + } + } + } + } List parsedChildren = new ArrayList<>(); List typeHierarchyReversed = new ArrayList<>(typeHierarchy); @@ -754,8 +771,12 @@ } List children = Utils.collectAnnotations(context, nodeChildrenMirror, "value", type, NodeChild.class); + int index = 0; for (AnnotationMirror childMirror : children) { String name = Utils.getAnnotationValue(String.class, childMirror, "value"); + if (name.equals("")) { + name = "child" + index; + } Cardinality cardinality = Cardinality.ONE; @@ -764,6 +785,12 @@ cardinality = Cardinality.MANY; } + TypeMirror originalChildType = childType; + TypeMirror castNodeType = castNodeTypes.get(name); + if (castNodeType != null) { + childType = castNodeType; + } + Element getter = findGetter(elements, name, childType); ExecutionKind kind = ExecutionKind.DEFAULT; @@ -771,7 +798,7 @@ kind = ExecutionKind.SHORT_CIRCUIT; } - NodeChildData nodeChild = new NodeChildData(type, childMirror, name, childType, getter, cardinality, kind); + NodeChildData nodeChild = new NodeChildData(type, childMirror, name, childType, originalChildType, getter, cardinality, kind); parsedChildren.add(nodeChild); @@ -785,7 +812,9 @@ if (fieldNodeData == null) { nodeChild.addError("Node type '%s' is invalid or not a valid Node.", Utils.getQualifiedName(childType)); } + } + index++; } List filteredChildren = new ArrayList<>(); @@ -877,7 +906,7 @@ } for (ExecutableElement method : ElementFilter.methodsIn(elements)) { - if (method.getSimpleName().toString().equals(methodName) && method.getParameters().size() == 0 && Utils.typeEquals(method.getReturnType(), type)) { + if (method.getSimpleName().toString().equals(methodName) && method.getParameters().size() == 0 && Utils.isAssignable(context, type, method.getReturnType())) { return method; } } diff -r cfbe4f978116 -r c43c4938e353 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationData.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationData.java Fri Jun 21 11:38:40 2013 -0700 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationData.java Fri Jun 21 11:38:47 2013 -0700 @@ -74,6 +74,24 @@ return sinks; } + public boolean isGenericSpecialization(ProcessorContext context) { + if (hasRewrite(context)) { + return false; + } + + for (ActualParameter parameter : getParameters()) { + NodeChildData child = getNode().findChild(parameter.getSpecification().getName()); + if (child == null) { + continue; + } + if (!parameter.getTypeSystemType().isGeneric()) { + return false; + } + } + + return true; + } + public boolean hasRewrite(ProcessorContext context) { if (!getExceptions().isEmpty()) { return true; diff -r cfbe4f978116 -r c43c4938e353 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateParser.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateParser.java Fri Jun 21 11:38:40 2013 -0700 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateParser.java Fri Jun 21 11:38:47 2013 -0700 @@ -28,19 +28,11 @@ import javax.lang.model.util.*; import com.oracle.truffle.codegen.processor.*; -import com.oracle.truffle.codegen.processor.ext.*; public abstract class TemplateParser extends AbstractParser { - private final ExtensionParser extensionParser; - public TemplateParser(ProcessorContext c) { super(c); - extensionParser = new ExtensionParser(c); - } - - public ExtensionParser getExtensionParser() { - return extensionParser; } protected void verifyExclusiveMethodAnnotation(Template template, Class... annotationTypes) { diff -r cfbe4f978116 -r c43c4938e353 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemCodeGenerator.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemCodeGenerator.java Fri Jun 21 11:38:40 2013 -0700 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemCodeGenerator.java Fri Jun 21 11:38:47 2013 -0700 @@ -103,8 +103,6 @@ } } - clazz.getEnclosedElements().addAll(typeSystem.getExtensionElements()); - return clazz; } diff -r cfbe4f978116 -r c43c4938e353 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemParser.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemParser.java Fri Jun 21 11:38:40 2013 -0700 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemParser.java Fri Jun 21 11:38:47 2013 -0700 @@ -84,10 +84,6 @@ verifyExclusiveMethodAnnotation(typeSystem, TypeCast.class, TypeCheck.class); List elements = new ArrayList<>(context.getEnvironment().getElementUtils().getAllMembers(templateType)); - typeSystem.setExtensionElements(getExtensionParser().parseAll(typeSystem, elements)); - if (typeSystem.getExtensionElements() != null) { - elements.addAll(typeSystem.getExtensionElements()); - } List casts = new TypeCastParser(context, typeSystem).parse(elements); List checks = new TypeCheckParser(context, typeSystem).parse(elements); diff -r cfbe4f978116 -r c43c4938e353 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/PrintNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/PrintNode.java Fri Jun 21 11:38:40 2013 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/PrintNode.java Fri Jun 21 11:38:47 2013 -0700 @@ -26,7 +26,7 @@ import com.oracle.truffle.api.codegen.*; -@NodeChild(value = "expression", type = TypedNode.class) +@NodeChild(type = TypedNode.class) public abstract class PrintNode extends StatementNode { private final PrintStream output; diff -r cfbe4f978116 -r c43c4938e353 mx/commands.py --- a/mx/commands.py Fri Jun 21 11:38:40 2013 -0700 +++ b/mx/commands.py Fri Jun 21 11:38:47 2013 -0700 @@ -54,6 +54,8 @@ _jacoco = 'off' +_workdir = None + _native_dbg = None _make_eclipse_launch = False @@ -645,6 +647,11 @@ if vm is None: vm = _vm + if cwd is None: + cwd = _workdir + elif _workdir is not None: + mx.abort("conflicting working directories: do not set --workdir for this command") + build = vmbuild if vmbuild is not None else _vmbuild if _vmSourcesAvailable else 'product' jdk = _jdk(build, vmToCheck=vm) mx.expand_project_in_args(args) @@ -1267,7 +1274,6 @@ '--dot-output-base', 'projects'] + args) def mx_init(): - _vmbuild = 'product' commands = { 'build': [build, '[-options]'], 'buildvars': [buildvars, ''], @@ -1298,6 +1304,7 @@ } mx.add_argument('--jacoco', help='instruments com.oracle.* classes using JaCoCo', default='off', choices=['off', 'on', 'append']) + mx.add_argument('--workdir', help='runs the VM in the given directory', default=None) if (_vmSourcesAvailable): mx.add_argument('--vm', action='store', dest='vm', default='graal', choices=_vmChoices, help='the VM to build/run (default: ' + _vmChoices[0] + ')') @@ -1330,6 +1337,8 @@ _make_eclipse_launch = getattr(opts, 'make_eclipse_launch', False) global _jacoco _jacoco = opts.jacoco + global _workdir + _workdir = opts.workdir global _native_dbg _native_dbg = opts.native_dbg