Skip to content

Commit

Permalink
Fix the issue with non-positive parent.width in RuntimeRange by addin…
Browse files Browse the repository at this point in the history
…g logic for inferring width from connections into width() function of ASTUtils.java.
  • Loading branch information
hokeun authored and cmnrd committed Jul 12, 2022
1 parent 8301987 commit 5a10005
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 43 deletions.
93 changes: 54 additions & 39 deletions org.lflang/src/org/lflang/ASTUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -1434,44 +1434,7 @@ public static int width(WidthSpec spec, List<Instantiation> instantiations) {
return 1;
}
if (spec.isOfVariableLength() && spec.eContainer() instanceof Instantiation) {
// We may be able to infer the width by examining the connections of
// the enclosing reactor definition. This works, for example, with
// delays between multiports or banks of reactors.
// Attempt to infer the width.
for (Connection c : ((Reactor) spec.eContainer().eContainer()).getConnections()) {
int leftWidth = 0;
int rightWidth = 0;
int leftOrRight = 0;
for (VarRef leftPort : c.getLeftPorts()) {
if (leftPort.getContainer() == spec.eContainer()) {
if (leftOrRight != 0) {
throw new InvalidSourceException("Multiple ports with variable width on a connection.");
}
// Indicate that the port is on the left.
leftOrRight = -1;
} else {
leftWidth += inferPortWidth(leftPort, c, instantiations);
}
}
for (VarRef rightPort : c.getRightPorts()) {
if (rightPort.getContainer() == spec.eContainer()) {
if (leftOrRight != 0) {
throw new InvalidSourceException("Multiple ports with variable width on a connection.");
}
// Indicate that the port is on the right.
leftOrRight = 1;
} else {
rightWidth += inferPortWidth(rightPort, c, instantiations);
}
}
if (leftOrRight < 0) {
return rightWidth - leftWidth;
} else if (leftOrRight > 0) {
return leftWidth - rightWidth;
}
}
// A connection was not found with the instantiation.
return -1;
return inferWidthFromConnections(spec, instantiations);
}
var result = 0;
for (WidthTerm term: spec.getTerms()) {
Expand All @@ -1485,7 +1448,11 @@ public static int width(WidthSpec spec, List<Instantiation> instantiations) {
} else if (term.getWidth() > 0) {
result += term.getWidth();
} else {
return -1;
// If the width cannot be determined because term's width <= 0, which means the term's width
// must be inferred, try to infer the width using connections.
if (spec.eContainer() instanceof Instantiation) {
return inferWidthFromConnections(spec, instantiations);
}
}
}
return result;
Expand Down Expand Up @@ -1840,4 +1807,52 @@ private static LinkedHashSet<Reactor> superClasses(Reactor reactor, Set<Reactor>
}
return result;
}

/**
* We may be able to infer the width by examining the connections of
* the enclosing reactor definition. This works, for example, with
* delays between multiports or banks of reactors.
* Attempt to infer the width from connections and return -1 if the width cannot be inferred.
*
* @param spec The width specification or null (to return 1).
* @param instantiations The (optional) list of instantiations.
*
* @return The width, or -1 if the width could not be inferred from connections.
*/
private static int inferWidthFromConnections(WidthSpec spec, List<Instantiation> instantiations) {
for (Connection c : ((Reactor) spec.eContainer().eContainer()).getConnections()) {
int leftWidth = 0;
int rightWidth = 0;
int leftOrRight = 0;
for (VarRef leftPort : c.getLeftPorts()) {
if (leftPort.getContainer() == spec.eContainer()) {
if (leftOrRight != 0) {
throw new InvalidSourceException("Multiple ports with variable width on a connection.");
}
// Indicate that the port is on the left.
leftOrRight = -1;
} else {
leftWidth += inferPortWidth(leftPort, c, instantiations);
}
}
for (VarRef rightPort : c.getRightPorts()) {
if (rightPort.getContainer() == spec.eContainer()) {
if (leftOrRight != 0) {
throw new InvalidSourceException("Multiple ports with variable width on a connection.");
}
// Indicate that the port is on the right.
leftOrRight = 1;
} else {
rightWidth += inferPortWidth(rightPort, c, instantiations);
}
}
if (leftOrRight < 0) {
return rightWidth - leftWidth;
} else if (leftOrRight > 0) {
return leftWidth - rightWidth;
}
}
// A connection was not found with the instantiation.
return -1;
}
}
5 changes: 1 addition & 4 deletions org.lflang/src/org/lflang/generator/RuntimeRange.java
Original file line number Diff line number Diff line change
Expand Up @@ -210,10 +210,7 @@ public RuntimeRange(
int maxWidth = instance.width; // Initial value.
NamedInstance<?> parent = instance.parent;
while (parent.depth > 0) {
if (parent.width > 0) {
// Skip when width is not positive (e.g., delay reactor instance)
maxWidth *= parent.width;
}
maxWidth *= parent.width;
parent = parent.parent;
}
this.maxWidth = maxWidth;
Expand Down

0 comments on commit 5a10005

Please # to comment.