use of com.oracle.truffle.dsl.processor.model.ImplicitCastData in project graal by oracle.
the class FlatNodeGenFactory method createExecuteChildImplicitCast.
private ChildExecutionResult createExecuteChildImplicitCast(CodeTreeBuilder parent, FrameState originalFrameState, FrameState frameState, NodeExecutionData execution, LocalVariable target) {
CodeTreeBuilder builder = parent.create();
List<TypeMirror> originalSourceTypes = typeSystem.lookupSourceTypes(target.getTypeMirror());
List<TypeMirror> sourceTypes = resolveOptimizedImplicitSourceTypes(execution, target.getTypeMirror());
TypeGuard typeGuard = new TypeGuard(target.getTypeMirror(), execution.getIndex());
boolean throwsUnexpected = false;
boolean elseIf = false;
for (TypeMirror sourceType : sourceTypes) {
ExecutableTypeData executableType = resolveTargetExecutable(execution, sourceType);
elseIf = builder.startIf(elseIf);
throwsUnexpected |= executableType.hasUnexpectedValue(context);
builder.startGroup();
builder.tree(state.createContainsOnly(frameState, originalSourceTypes.indexOf(sourceType), 1, new Object[] { typeGuard }, new Object[] { typeGuard }));
builder.string(" && ");
builder.tree(state.createIsNotAny(frameState, reachableSpecializationsArray));
builder.end();
builder.end();
builder.startBlock();
CodeTree value = callChildExecuteMethod(execution, executableType, frameState);
value = expect(executableType.getReturnType(), sourceType, value);
throwsUnexpected |= needsCastTo(executableType.getReturnType(), sourceType);
ImplicitCastData cast = typeSystem.lookupCast(sourceType, target.getTypeMirror());
if (cast != null) {
// we need to store the original value to restore it in
// case of a deopt
String localName = createSourceTypeLocalName(target, sourceType);
builder.startStatement().string(localName).string(" = ").tree(value).end();
value = callMethod(null, cast.getMethod(), CodeTreeBuilder.singleString(localName));
}
builder.startStatement().string(target.getName()).string(" = ").tree(value).end();
builder.end();
}
if (elseIf) {
builder.startElseBlock();
}
LocalVariable genericValue = target.makeGeneric(context).nextName();
builder.tree(createAssignExecuteChild(originalFrameState, frameState, builder, execution, node.getGenericExecutableType(null), genericValue));
builder.startStatement().string(target.getName()).string(" = ");
CodeTree implicitState = state.createExtractInteger(frameState, typeGuard);
builder.tree(TypeSystemCodeGenerator.implicitExpectFlat(typeSystem, target.getTypeMirror(), genericValue.createReference(), implicitState));
builder.end();
if (!sourceTypes.isEmpty()) {
builder.end();
}
return new ChildExecutionResult(builder.build(), throwsUnexpected);
}
use of com.oracle.truffle.dsl.processor.model.ImplicitCastData in project graal by oracle.
the class TypeSystemParser method parse.
@Override
protected TypeSystemData parse(Element element, AnnotationMirror mirror) {
TypeElement templateType = (TypeElement) element;
AnnotationMirror templateTypeAnnotation = mirror;
TypeSystemData typeSystem = new TypeSystemData(context, templateType, templateTypeAnnotation, false);
// annotation type on class path!?
TypeElement annotationTypeElement = processingEnv.getElementUtils().getTypeElement(getAnnotationType().getCanonicalName());
if (annotationTypeElement == null) {
typeSystem.addError("Required class %s is not on the classpath.", getAnnotationType().getName());
}
if (templateType.getModifiers().contains(Modifier.PRIVATE)) {
typeSystem.addError("A @%s must have at least package protected visibility.", getAnnotationType().getName());
}
if (templateType.getModifiers().contains(Modifier.FINAL)) {
typeSystem.addError("The @%s must not be final.", getAnnotationType().getName());
}
if (typeSystem.hasErrors()) {
return typeSystem;
}
if (typeSystem.hasErrors()) {
return typeSystem;
}
verifyExclusiveMethodAnnotation(typeSystem, TypeCast.class, TypeCheck.class);
List<Element> elements = newElementList(context.getEnvironment().getElementUtils().getAllMembers(templateType));
List<ImplicitCastData> implicitCasts = new ImplicitCastParser(context, typeSystem).parse(elements);
List<TypeCastData> casts = new TypeCastParser(context, typeSystem).parse(elements);
List<TypeCheckData> checks = new TypeCheckParser(context, typeSystem).parse(elements);
if (casts == null || checks == null || implicitCasts == null) {
return typeSystem;
}
List<TypeMirror> legacyTypes = ElementUtils.getAnnotationValueList(TypeMirror.class, typeSystem.getTemplateTypeAnnotation(), "value");
for (int i = 0; i < legacyTypes.size(); i++) {
legacyTypes.set(i, ElementUtils.fillInGenericWildcards(legacyTypes.get(i)));
}
typeSystem.getLegacyTypes().addAll(legacyTypes);
verifyTypes(typeSystem);
typeSystem.getLegacyTypes().add(context.getType(Object.class));
typeSystem.getLegacyTypes().add(context.getType(void.class));
verifyNamesUnique(typeSystem);
typeSystem.getImplicitCasts().addAll(implicitCasts);
typeSystem.getCasts().addAll(casts);
typeSystem.getChecks().addAll(checks);
if (typeSystem.hasErrors()) {
return typeSystem;
}
return typeSystem;
}
use of com.oracle.truffle.dsl.processor.model.ImplicitCastData in project graal by oracle.
the class ImplicitCastParser method create.
@Override
public ImplicitCastData create(TemplateMethod method, boolean invalid) {
if (invalid) {
return new ImplicitCastData(method, null, null);
}
Parameter target = method.findParameter("targetValue");
Parameter source = method.findParameter("sourceValue");
TypeMirror targetType = target.getType();
TypeMirror sourceType = source.getType();
if (ElementUtils.typeEquals(targetType, sourceType)) {
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);
}
use of com.oracle.truffle.dsl.processor.model.ImplicitCastData in project graal by oracle.
the class FlatNodeGenFactory method createTypeCheckOrCast.
private IfTriple createTypeCheckOrCast(FrameState frameState, SpecializationGroup group, TypeGuard typeGuard, NodeExecutionMode specializationExecution, boolean castOnly, boolean forceImplicitCast) {
CodeTreeBuilder prepareBuilder = CodeTreeBuilder.createBuilder();
CodeTreeBuilder checkBuilder = CodeTreeBuilder.createBuilder();
int signatureIndex = typeGuard.getSignatureIndex();
LocalVariable value = frameState.getValue(signatureIndex);
TypeMirror targetType = typeGuard.getType();
if (!ElementUtils.needsCastTo(value.getTypeMirror(), targetType)) {
boolean foundImplicitSubType = false;
if (forceImplicitCast) {
List<ImplicitCastData> casts = typeSystem.lookupByTargetType(targetType);
for (ImplicitCastData cast : casts) {
if (ElementUtils.isSubtype(cast.getSourceType(), targetType)) {
foundImplicitSubType = true;
break;
}
}
}
if (!foundImplicitSubType) {
return null;
}
}
NodeExecutionData execution = node.getChildExecutions().get(signatureIndex);
CodeTreeBuilder castBuilder = prepareBuilder.create();
List<ImplicitCastData> sourceTypes = typeSystem.lookupByTargetType(targetType);
CodeTree valueReference = value.createReference();
if (sourceTypes.isEmpty()) {
checkBuilder.tree(TypeSystemCodeGenerator.check(typeSystem, targetType, valueReference));
castBuilder.tree(TypeSystemCodeGenerator.cast(typeSystem, targetType, valueReference));
} else {
List<SpecializationData> specializations = group.collectSpecializations();
List<Parameter> parameters = new ArrayList<>();
for (SpecializationData otherSpecialization : specializations) {
parameters.add(otherSpecialization.findParameterOrDie(execution));
}
if (specializationExecution.isFastPath() || specializationExecution.isGuardFallback()) {
CodeTree implicitState;
if (specializationExecution.isGuardFallback()) {
implicitState = CodeTreeBuilder.singleString("0b" + allsetMask(sourceTypes.size() + 1));
} else {
implicitState = state.createExtractInteger(frameState, typeGuard);
}
checkBuilder.tree(TypeSystemCodeGenerator.implicitCheckFlat(typeSystem, targetType, valueReference, implicitState));
castBuilder.tree(TypeSystemCodeGenerator.implicitCastFlat(typeSystem, targetType, valueReference, implicitState));
} else {
Parameter parameter = parameters.get(0);
String implicitStateName = createImplicitTypeStateLocalName(parameter);
CodeTree defaultValue = null;
prepareBuilder.declaration(context.getType(int.class), implicitStateName, defaultValue);
CodeTree specializeCall = TypeSystemCodeGenerator.implicitSpecializeFlat(typeSystem, targetType, valueReference);
checkBuilder.startParantheses();
checkBuilder.string(implicitStateName, " = ").tree(specializeCall);
checkBuilder.end();
checkBuilder.string(" != 0");
castBuilder.tree(TypeSystemCodeGenerator.implicitCastFlat(typeSystem, targetType, valueReference, CodeTreeBuilder.singleString(implicitStateName)));
}
}
if (castOnly) {
LocalVariable currentValue = frameState.getValue(execution);
CodeTreeBuilder localsBuilder = CodeTreeBuilder.createBuilder();
LocalVariable castVariable = currentValue.nextName().newType(typeGuard.getType()).accessWith(null);
frameState.setValue(execution, castVariable);
localsBuilder.tree(castVariable.createDeclaration(castBuilder.build()));
return new IfTriple(localsBuilder.build(), null, null);
} else {
return new IfTriple(prepareBuilder.build(), checkBuilder.build(), null);
}
}
Aggregations