Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C Generics #1681

Merged
merged 59 commits into from
May 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
364230e
Start adding templates to C target. WIP.
petervdonovan Mar 21, 2023
c1eafa7
[C-Generics]
mkhubaibumer Mar 27, 2023
1dfb39d
[C-Generics] HashCode missmatch bug
mkhubaibumer Mar 29, 2023
77109fe
[C-Generics] Working Generic Code
mkhubaibumer Mar 29, 2023
4af9040
[C-Generics] Working Generic Code
mkhubaibumer Mar 30, 2023
7208c8f
[C-Generics]
mkhubaibumer Mar 31, 2023
6477a99
[C-Generics]
mkhubaibumer Mar 31, 2023
393a5d2
Merge branch 'c-templates' of https://github.com/lf-lang/lingua-franc…
mkhubaibumer Mar 31, 2023
38e0758
Update submodule ref
mkhubaibumer Mar 31, 2023
56df4a6
Merge branch 'bodyless-reactions' into merge-bodyless-reactions
petervdonovan Mar 31, 2023
b59b3b7
Temporarily remove the generics headers.
petervdonovan Mar 31, 2023
a55a886
Update submodule.
petervdonovan Mar 31, 2023
25aace4
[C-Generics]
mkhubaibumer Apr 4, 2023
03ef8de
[C-Generics] Contained Reactor type collission
mkhubaibumer Apr 5, 2023
ad9a226
[C-Generics]
mkhubaibumer Apr 6, 2023
9f32cef
[C-Generic] Contained Generic Reactor
mkhubaibumer Apr 11, 2023
272dbaa
Update documentation
mkhubaibumer Apr 11, 2023
ee610f0
[C-Generics] Contained Generic Reactor
mkhubaibumer Apr 14, 2023
e066c09
Cosmetic Changes and Cleanup
mkhubaibumer Apr 14, 2023
a2cfcf3
[C-Generics] Resolve Templated-Typed Pointers
mkhubaibumer Apr 14, 2023
40b075a
Update Reactor-C
mkhubaibumer Apr 19, 2023
e39e1e9
[C-Generics]
mkhubaibumer Apr 19, 2023
e28065c
Update in SubModule & Minor Changes in Pair<>
mkhubaibumer May 3, 2023
aa409f8
Update Reactor-C
mkhubaibumer May 11, 2023
cef4c9b
Merge branch 'merge-bodyless-reactions' into c-templates
petervdonovan May 19, 2023
c461cd7
Delete unnecessary complexity from build-lf-cli.
petervdonovan May 18, 2023
e48f7e4
Merge branch 'master' into c-templates
petervdonovan May 19, 2023
4fac0fe
More cleanups after merge.
petervdonovan May 19, 2023
172b01f
Add back missing include.
petervdonovan May 19, 2023
c56adef
Don't make ReactorInstance from insufficient data.
petervdonovan May 19, 2023
ec41b35
Self struct members are named after instance vars.
petervdonovan May 19, 2023
8fa20b8
Update tests according to new test categories.
petervdonovan May 19, 2023
48542d3
Format test.
petervdonovan May 19, 2023
9c3aa67
Merge in changes from reactor-c/main.
petervdonovan May 19, 2023
1dd92eb
Address failing no_inlining tests.
petervdonovan May 19, 2023
6bbee5c
Fix another mismatch between reactor and tpr.
petervdonovan May 19, 2023
d548f19
Update reactor-c to include watchdogs.
petervdonovan May 19, 2023
0f364e3
Merge branch 'master' into c-templates
petervdonovan May 19, 2023
96abdfe
Silence warning.
petervdonovan May 20, 2023
fed3e14
Pass failing template test.
petervdonovan May 20, 2023
ce31b70
Do not use hashcodes as keys.
petervdonovan May 20, 2023
4b5a7c5
Bugfix in CGenerator.java.
petervdonovan May 20, 2023
dd6fd0c
Fix bug introduced by previous commit.
petervdonovan May 20, 2023
331a315
Entirely delete the map from ReactorInstance.
petervdonovan May 22, 2023
f497c2a
Switch submodule ref to main.
petervdonovan May 22, 2023
c6f1a63
Update validator.
petervdonovan May 22, 2023
f13966a
Fix NPE.
petervdonovan May 22, 2023
f3c8ffa
Remove getConcreteType.
petervdonovan May 22, 2023
957500d
Delete Pair.java.
petervdonovan May 22, 2023
fa738b1
Impl of equals must match impl of hashcode.
petervdonovan May 22, 2023
5f52ca9
Fix NPE and (slightly) dignify a hack.
petervdonovan May 22, 2023
5299ca5
Fix another NPE.
petervdonovan May 22, 2023
cccf2aa
Fix passing generics test.
petervdonovan May 22, 2023
0093be7
Fix NPE.
petervdonovan May 22, 2023
76c048c
More of the stars hack.
petervdonovan May 22, 2023
47e97d8
Apply suggestions from code review
petervdonovan May 22, 2023
882dd83
Add comments.
petervdonovan May 22, 2023
2138d7d
Rename tpr.r() -> tpr.reactor().
petervdonovan May 22, 2023
46b3ace
Apply suggestions from code review
petervdonovan May 22, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 17 additions & 6 deletions org.lflang.tests/src/org/lflang/tests/RuntimeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

/**
* A collection of JUnit tests to perform on a given set of targets.
*
*
* @author Marten Lohstroh
*
*/
Expand Down Expand Up @@ -135,12 +135,23 @@ public void runFederatedTests() {
@Test
public void runModalTests() {
runTestsForTargets(Message.DESC_MODAL,
TestCategory.MODAL_MODELS::equals, Configurators::noChanges,
TestLevel.EXECUTION,
false);
TestCategory.MODAL_MODELS::equals, Configurators::noChanges,
TestLevel.EXECUTION,
false);
}

/**
/**
* Run the tests for non-inlined reaction bodies.
*/
@Test
public void runNoInliningTests() {
runTestsForTargets(Message.DESC_MODAL,
TestCategory.NO_INLINING::equals, Configurators::noChanges,
TestLevel.EXECUTION,
false);
}

/**
* Run docker tests, provided that the platform is Linux and the target supports Docker.
* Skip if platform is not Linux or target does not support Docker.
*/
Expand All @@ -154,7 +165,7 @@ public void runDockerTests() {
false);
}

/**
/**
* Run federated docker tests, provided that the platform is Linux, the target supports Docker,
* and the target supports federated execution. If any of these requirements are not met, skip
* the tests.
Expand Down
30 changes: 18 additions & 12 deletions org.lflang.tests/src/org/lflang/tests/runtime/CTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,25 @@
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***************/
package org.lflang.tests.runtime;

import java.util.List;

import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

import org.lflang.Target;
import org.lflang.tests.Configurators;
import org.lflang.tests.RuntimeTest;
import org.lflang.tests.TestRegistry.TestCategory;

/**
* Collection of tests for the C target.
Expand Down Expand Up @@ -112,6 +108,16 @@ public void runFederatedTests() {
super.runFederatedTests();
}

@Test
public void runModalTests() {
super.runModalTests();
}

@Test
public void runNoInliningTests() {
super.runNoInliningTests();
}

@Test
@Override
public void runDockerTests() {
Expand Down
27 changes: 22 additions & 5 deletions org.lflang/src/org/lflang/ASTUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,10 @@
import org.lflang.ast.ToText;
import org.lflang.generator.CodeMap;
import org.lflang.generator.InvalidSourceException;
import org.lflang.generator.NamedInstance;
import org.lflang.generator.ReactorInstance;
import org.lflang.generator.c.CUtil;
import org.lflang.generator.c.TypeParameterizedReactor;
import org.lflang.lf.Action;
import org.lflang.lf.Assignment;
import org.lflang.lf.Code;
Expand Down Expand Up @@ -399,6 +402,21 @@ public static List<Instantiation> allInstantiations(Reactor definition) {
}

/**
* Given a reactor Class, return a set of include names for
* interacting reactors which includes all instantiations of base class that it extends.
*
* @param r Reactor Class
* */
public static HashSet<String> allIncludes(Reactor r) {
var set = new HashSet<String>();
for (var i : allInstantiations(r))
{
set.add(CUtil.getName(new TypeParameterizedReactor(i)));
}
return set;
}

/*
* Given a reactor class, return a stream of reactor classes that it instantiates.
* @param definition Reactor class definition.
* @return A stream of reactor classes.
Expand Down Expand Up @@ -488,11 +506,10 @@ public static List<Mode> allModes(Reactor definition) {
return ASTUtils.collectElements(definition, featurePackage.getReactor_Modes());
}

/** A list of all reactors instantiated, transitively or intransitively, by {@code r}. */
public static List<Reactor> recursiveChildren(ReactorInstance r) {
List<Reactor> ret = new ArrayList<>();
ret.add(r.reactorDefinition);
for (var child : r.children) {
public static List<ReactorInstance> recursiveChildren(ReactorInstance r) {
List<ReactorInstance> ret = new ArrayList<>();
ret.add(r);
for (var child: r.children) {
ret.addAll(recursiveChildren(child));
}
return ret;
Expand Down
7 changes: 4 additions & 3 deletions org.lflang/src/org/lflang/cli/Lfc.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.lflang.generator.LFGeneratorContext;
import org.lflang.generator.LFGeneratorContext.BuildParm;
import org.lflang.generator.MainContext;
import org.lflang.generator.ReactorInstance;

import com.google.inject.Inject;

Expand Down Expand Up @@ -106,7 +107,7 @@ public class Lfc extends CliBase {
@Option(
names = {"-q", "--quiet"},
arity = "0",
description =
description =
"Suppress output of the target compiler and other commands")
private boolean quiet;

Expand Down Expand Up @@ -188,7 +189,7 @@ private void invokeGenerator(

final Resource resource = getResource(path);
if (resource == null) {
reporter.printFatalErrorAndExit(path
reporter.printFatalErrorAndExit(path
+ " is not an LF file. Use the .lf file extension to"
+ " denote LF files.");
} else if (federated) {
Expand Down Expand Up @@ -316,7 +317,7 @@ public Properties getGeneratorArgs() {
if (workers != null) {
props.setProperty(BuildParm.WORKERS.getKey(), workers.toString());
}

return props;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -411,15 +411,15 @@ public String toDOT() {
var currentLevelNodes = groupedNodes.get(level);
for (var node: currentLevelNodes) {
// Draw the node
var label = CUtil.getName(node.getReaction().getParent().reactorDefinition) + "." + node.getReaction().getName();
var label = CUtil.getName(node.getReaction().getParent().tpr) + "." + node.getReaction().getName();
// Need a positive number to name the nodes in GraphViz
var labelHashCode = label.hashCode() & 0xfffffff;
dotRepresentation.pr(" node_" + labelHashCode + " [label=\""+ label +"\"];");

// Draw the edges
var downstreamNodes = getDownstreamAdjacentNodes(node);
for (var downstreamNode: downstreamNodes) {
var downstreamLabel = CUtil.getName(downstreamNode.getReaction().getParent().reactorDefinition) + "." + downstreamNode.getReaction().getName();
var downstreamLabel = CUtil.getName(downstreamNode.getReaction().getParent().tpr) + "." + downstreamNode.getReaction().getName();
edges.append(" node_" + labelHashCode + " -> node_" +
(downstreamLabel.hashCode() & 0xfffffff) + ";\n"
);
Expand Down
25 changes: 14 additions & 11 deletions org.lflang/src/org/lflang/generator/ReactorInstance.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY

package org.lflang.generator;

import static org.lflang.ASTUtils.belongsTo;
import static org.lflang.ASTUtils.getLiteralTimeValue;

import java.util.ArrayList;
Expand All @@ -44,6 +43,7 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
import org.lflang.ErrorReporter;
import org.lflang.TimeValue;
import org.lflang.generator.TriggerInstance.BuiltinTriggerVariable;
import org.lflang.generator.c.TypeParameterizedReactor;
import org.lflang.lf.Action;
import org.lflang.lf.Assignment;
import org.lflang.lf.BuiltinTrigger;
Expand All @@ -53,7 +53,6 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
import org.lflang.lf.Initializer;
import org.lflang.lf.Input;
import org.lflang.lf.Instantiation;
import org.lflang.lf.LfFactory;
import org.lflang.lf.Mode;
import org.lflang.lf.Output;
import org.lflang.lf.Parameter;
Expand Down Expand Up @@ -166,6 +165,8 @@ public ReactorInstance(Reactor reactor, ReactorInstance parent, ErrorReporter re
/** Indicator that this reactor has itself as a parent, an error condition. */
public final boolean recursive;

public TypeParameterizedReactor tpr;

//////////////////////////////////////////////////////
//// Public methods.

Expand Down Expand Up @@ -799,15 +800,16 @@ protected void createWatchdogInstances() {
* @param reporter An error reporter.
* @param desiredDepth The depth to which to expand the hierarchy.
*/
private ReactorInstance(
Instantiation definition,
ReactorInstance parent,
ErrorReporter reporter,
int desiredDepth) {
public ReactorInstance(
Instantiation definition,
ReactorInstance parent,
ErrorReporter reporter,
int desiredDepth) {
super(definition, parent);
this.reporter = reporter;
this.reactorDeclaration = definition.getReactorClass();
this.reactorDefinition = ASTUtils.toDefinition(reactorDeclaration);
this.tpr = new TypeParameterizedReactor(definition);

// check for recursive instantiation
var currentParent = parent;
Expand Down Expand Up @@ -896,6 +898,10 @@ private ReactorInstance(
}
}

public TypeParameterizedReactor getTypeParameterizedReactor() {
return this.tpr;
}

//////////////////////////////////////////////////////
//// Private methods.

Expand Down Expand Up @@ -1178,9 +1184,6 @@ private void setInitialWidth() {
*/
public boolean isGeneratedDelay() {
// FIXME: hacky string matching again...
if (this.definition.getReactorClass().getName().contains(DelayBodyGenerator.GEN_DELAY_CLASS_NAME)) {
return true;
}
return false;
return this.definition.getReactorClass().getName().contains(DelayBodyGenerator.GEN_DELAY_CLASS_NAME);
}
}
22 changes: 10 additions & 12 deletions org.lflang/src/org/lflang/generator/c/CActionGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@
import org.lflang.generator.CodeBuilder;
import org.lflang.generator.ReactorInstance;
import org.lflang.lf.Action;
import org.lflang.lf.Reactor;
import org.lflang.lf.ReactorDecl;

import static org.lflang.generator.c.CGenerator.variableStructType;
/**
* Generates code for actions (logical or physical) for the C and CCpp target.
Expand Down Expand Up @@ -90,19 +89,17 @@ public static String generateTokenInitializer(
/**
* Generate the declarations of actions in the self struct
*
* @param reactor The reactor to generate declarations for
* @param decl The reactor's declaration
* @param body The content of the self struct
* @param constructorCode The constructor code of the reactor
*/
public static void generateDeclarations(
Reactor reactor,
TypeParameterizedReactor tpr,
CodeBuilder body,
CodeBuilder constructorCode
) {
for (Action action : ASTUtils.allActions(reactor)) {
for (Action action : ASTUtils.allActions(tpr.reactor())) {
var actionName = action.getName();
body.pr(action, CGenerator.variableStructType(action, reactor, false)+" _lf_"+actionName+";");
body.pr(action, CGenerator.variableStructType(action, tpr, false)+" _lf_"+actionName+";");
// Initialize the trigger pointer in the action.
constructorCode.pr(action, "self->_lf_"+actionName+".trigger = &self->_lf__"+actionName+";");
}
Expand All @@ -112,15 +109,14 @@ public static void generateDeclarations(
* Generate the struct type definitions for the action of the
* reactor
*
* @param decl The reactor declaration
* @param action The action to generate the struct for
* @param target The target of the code generation (C, CCpp or Python)
* @param types The helper object for types related stuff
* @param federatedExtension The code needed to support federated execution
* @return The auxiliary struct for the port as a string
*/
public static String generateAuxiliaryStruct(
Reactor r,
TypeParameterizedReactor tpr,
Action action,
Target target,
CTypes types,
Expand All @@ -142,10 +138,10 @@ public static String generateAuxiliaryStruct(
"bool has_value;", // From lf_action_base_t
"trigger_t* trigger;" // From lf_action_base_t
));
code.pr(valueDeclaration(action, target, types));
code.pr(valueDeclaration(tpr, action, target, types));
code.pr(federatedExtension.toString());
code.unindent();
code.pr("} " + variableStructType(action, r, userFacing) + ";");
code.pr("} " + variableStructType(action, tpr, userFacing) + ";");
return code.toString();
}

Expand All @@ -157,10 +153,12 @@ public static String generateAuxiliaryStruct(
* int* value;
* ```
* This will return an empty string for an action with no type.
* @param tpr {@link TypeParameterizedReactor}
* @param action The action.
* @return A string providing the value field of the action struct.
*/
private static String valueDeclaration(
TypeParameterizedReactor tpr,
Action action,
Target target,
CTypes types
Expand All @@ -172,6 +170,6 @@ private static String valueDeclaration(
// will be a separate field pointing to the token.
return action.getType() == null && target.requiresTypes ?
"" :
types.getTargetType(action) + " value;";
types.getTargetType(tpr.resolveType(action.getType())) + " value;";
}
}
10 changes: 5 additions & 5 deletions org.lflang/src/org/lflang/generator/c/CConstructorGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ public class CConstructorGenerator {
* go into the constructor.
*/
public static String generateConstructor(
Reactor reactor,
TypeParameterizedReactor tpr,
String constructorCode
) {
var structType = CUtil.selfType(reactor);
var structType = CUtil.selfType(tpr);
var code = new CodeBuilder();
code.pr(structType+"* new_"+CUtil.getName(reactor)+"() {");
code.pr(structType+"* new_"+CUtil.getName(tpr)+"() {");
code.indent();
code.pr(structType+"* self = ("+structType+"*)_lf_new_reactor(sizeof("+structType+"));");
code.pr(constructorCode);
Expand All @@ -30,7 +30,7 @@ public static String generateConstructor(
return code.toString();
}

public static String generateConstructorPrototype(Reactor reactor) {
return CUtil.selfType(reactor)+"* new_"+CUtil.getName(reactor)+"();";
public static String generateConstructorPrototype(TypeParameterizedReactor tpr) {
return CUtil.selfType(tpr)+"* new_"+CUtil.getName(tpr)+"();";
}
}
Loading