Skip to content

Commit dae9a10

Browse files
committed
Merge pull request #193 in G/truffle from ~CHRISTIAN.HUMER_ORACLE.COM/truffle:dsl_fix_implicit_evaluated_parameters to master
* commit 'cdecd17ca1533cd9ea55f89befd348624e6c184e': Add test for implicit casts for type in evaluated execute methods. Fix use new fallthrough flag also for slow path generation. Fix execute methods with typed evaluated parameters that are implicitely casted with a subtype as source type should do the implicit type guard to inject specialized information.
2 parents 157d6a9 + cdecd17 commit dae9a10

File tree

2 files changed

+59
-42
lines changed

2 files changed

+59
-42
lines changed

truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ImplicitCastTest.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,16 @@
3131
import com.oracle.truffle.api.dsl.Specialization;
3232
import com.oracle.truffle.api.dsl.TypeSystem;
3333
import com.oracle.truffle.api.dsl.TypeSystemReference;
34+
import com.oracle.truffle.api.dsl.internal.DSLOptions;
35+
import com.oracle.truffle.api.dsl.internal.DSLOptions.DSLGenerator;
3436
import com.oracle.truffle.api.dsl.test.ImplicitCastTestFactory.ImplicitCast0NodeFactory;
3537
import com.oracle.truffle.api.dsl.test.ImplicitCastTestFactory.ImplicitCast1NodeFactory;
3638
import com.oracle.truffle.api.dsl.test.ImplicitCastTestFactory.ImplicitCast2NodeFactory;
39+
import com.oracle.truffle.api.dsl.test.ImplicitCastTestFactory.ImplicitCast3NodeGen;
3740
import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode;
3841
import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode;
3942
import com.oracle.truffle.api.frame.VirtualFrame;
43+
import com.oracle.truffle.api.nodes.Node;
4044

4145
public class ImplicitCastTest {
4246

@@ -55,6 +59,20 @@ static boolean castString(String strvalue) {
5559

5660
}
5761

62+
private static int charSequenceCast;
63+
64+
@TypeSystem
65+
@DSLOptions(defaultGenerator = DSLGenerator.FLAT)
66+
static class ImplicitCast1Types {
67+
68+
@ImplicitCast
69+
static CharSequence castCharSequence(String strvalue) {
70+
charSequenceCast++;
71+
return strvalue;
72+
}
73+
74+
}
75+
5876
@TypeSystemReference(ImplicitCast0Types.class)
5977
@NodeChild(value = "operand", type = ImplicitCast0Node.class)
6078
abstract static class ImplicitCast0Node extends ValueNode {
@@ -161,6 +179,28 @@ public void testImplicitCast2() {
161179
Assert.assertEquals(true, root.getNode().executeEvaluated(null, true, true));
162180
}
163181

182+
@TypeSystemReference(ImplicitCast1Types.class)
183+
abstract static class ImplicitCast3Node extends Node {
184+
185+
@Specialization
186+
public CharSequence op0(CharSequence v0, @SuppressWarnings("unused") CharSequence v1) {
187+
return v0;
188+
}
189+
190+
public abstract Object executeEvaluated(CharSequence v1, CharSequence v2);
191+
192+
}
193+
194+
@Test
195+
public void testImplicitCast3() {
196+
ImplicitCast3Node node = ImplicitCast3NodeGen.create();
197+
CharSequence seq1 = "foo";
198+
CharSequence seq2 = "bar";
199+
charSequenceCast = 0;
200+
node.executeEvaluated(seq1, seq2);
201+
Assert.assertEquals(2, charSequenceCast);
202+
}
203+
164204
@TypeSystem({String.class, boolean.class})
165205
static class ImplicitCastError1 {
166206

truffle/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/FlatNodeGenFactory.java

Lines changed: 19 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -783,7 +783,7 @@ private CodeExecutableElement createExecuteAndSpecialize() {
783783

784784
builder.tree(execution);
785785

786-
if (hasFallthrough(group, genericType, originalFrameState)) {
786+
if (group.hasFallthrough()) {
787787
builder.tree(createTransferToInterpreterAndInvalidate());
788788
builder.tree(createThrowUnsupported(builder, originalFrameState));
789789
}
@@ -1454,41 +1454,6 @@ private SpecializationGroup createSpecializationGroups() {
14541454
return SpecializationGroup.createFlat(reachableSpecializations);
14551455
}
14561456

1457-
private boolean hasFallthrough(SpecializationGroup group, TypeMirror forType, FrameState frameState) {
1458-
for (TypeGuard guard : group.getTypeGuards()) {
1459-
if (frameState.getValue(guard.getSignatureIndex()) == null) {
1460-
// not evaluated
1461-
return true;
1462-
}
1463-
LocalVariable value = frameState.getValue(guard.getSignatureIndex());
1464-
if (needsCastTo(value.getTypeMirror(), guard.getType())) {
1465-
return true;
1466-
}
1467-
}
1468-
1469-
List<GuardExpression> guards = new ArrayList<>(group.getGuards());
1470-
SpecializationData specialization = group.getSpecialization();
1471-
1472-
if (!guards.isEmpty()) {
1473-
return true;
1474-
}
1475-
1476-
if (specialization != null && !specialization.getAssumptionExpressions().isEmpty()) {
1477-
return true;
1478-
}
1479-
1480-
if (specialization != null && mayBeExcluded(specialization)) {
1481-
return true;
1482-
}
1483-
1484-
List<SpecializationGroup> groupChildren = group.getChildren();
1485-
if (!groupChildren.isEmpty()) {
1486-
return hasFallthrough(groupChildren.get(groupChildren.size() - 1), forType, frameState);
1487-
}
1488-
1489-
return false;
1490-
}
1491-
14921457
private CodeTree expectOrCast(TypeMirror sourceType, ExecutableTypeData targetType, CodeTree content) {
14931458
if (needsUnexpectedResultException(targetType)) {
14941459
return expect(sourceType, targetType.getReturnType(), content);
@@ -1828,7 +1793,7 @@ private CodeTree visitSpecializationGroup(CodeTreeBuilder parent, Specialization
18281793
}
18291794

18301795
builder.end(ifCount);
1831-
hasFallthrough = ifCount > 0;
1796+
hasFallthrough |= ifCount > 0;
18321797

18331798
} else if (execution.isSlowPath()) {
18341799

@@ -1880,8 +1845,6 @@ private CodeTree visitSpecializationGroup(CodeTreeBuilder parent, Specialization
18801845
builder.end();
18811846
}
18821847

1883-
builder.end(ifCount);
1884-
18851848
} else {
18861849

18871850
List<AssumptionExpression> assumptions = specialization.getAssumptionExpressions();
@@ -2009,6 +1972,7 @@ private CodeTree visitSpecializationGroup(CodeTreeBuilder parent, Specialization
20091972
if (!guards.isEmpty()) {
20101973
builder.startIf().tree(guards).end();
20111974
builder.startBlock();
1975+
hasFallthrough = true;
20121976
}
20131977

20141978
if (!guardAssertions.isEmpty()) {
@@ -2129,6 +2093,7 @@ private CodeTree visitSpecializationGroup(CodeTreeBuilder parent, Specialization
21292093
builder.tree(state.createSet(frameState, new SpecializationData[]{specialization}, true, true));
21302094

21312095
if (needsDuplicationCheck) {
2096+
hasFallthrough = true;
21322097
if (!useSpecializationClass) {
21332098
builder.startStatement().string(duplicateFoundName, " = true").end();
21342099
}
@@ -2155,7 +2120,7 @@ private CodeTree visitSpecializationGroup(CodeTreeBuilder parent, Specialization
21552120
}
21562121

21572122
builder.end(ifCount);
2158-
hasFallthrough = ifCount > 0;
2123+
hasFallthrough |= ifCount > 0;
21592124

21602125
} else if (execution.isGuardFallback()) {
21612126

@@ -2232,7 +2197,7 @@ private CodeTree visitSpecializationGroup(CodeTreeBuilder parent, Specialization
22322197

22332198
builder.end(ifCount);
22342199

2235-
hasFallthrough = ifCount > 0;
2200+
hasFallthrough |= ifCount > 0;
22362201

22372202
} else {
22382203
throw new AssertionError("unexpected path");
@@ -2646,9 +2611,21 @@ private CodeTree[] createTypeCheckAndLocals(SpecializationGroup group, List<Type
26462611
int signatureIndex = typeGuard.getSignatureIndex();
26472612
LocalVariable value = frameState.getValue(signatureIndex);
26482613
TypeMirror targetType = typeGuard.getType();
2614+
26492615
if (!ElementUtils.needsCastTo(value.getTypeMirror(), targetType)) {
2650-
continue;
2616+
List<ImplicitCastData> casts = typeSystem.lookupByTargetType(targetType);
2617+
boolean foundImplicitSubType = false;
2618+
for (ImplicitCastData cast : casts) {
2619+
if (ElementUtils.isSubtype(cast.getSourceType(), targetType)) {
2620+
foundImplicitSubType = true;
2621+
break;
2622+
}
2623+
}
2624+
if (!foundImplicitSubType) {
2625+
continue;
2626+
}
26512627
}
2628+
26522629
NodeExecutionData execution = node.getChildExecutions().get(signatureIndex);
26532630
if (!checksBuilder.isEmpty()) {
26542631
checksBuilder.string(" && ");

0 commit comments

Comments
 (0)