Skip to content

Commit

Permalink
Some updates to the JavaScript target
Browse files Browse the repository at this point in the history
- pre.js is now included with the omc sources
- It is now possible to use nodejs to run the generated code. An executable wrapper script is generated and the simulate() command now works
- The XML files are embedded within the JS code now (just like we do for FMI)
- We use -override arguments to pass stopTime,stepSize,tolerance and outputFormat instead of a full xml-file in a virtual file system


git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@19251 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
sjoelund committed Feb 22, 2014
1 parent 1a8e0b5 commit 455c848
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 35 deletions.
3 changes: 2 additions & 1 deletion Compiler/BackEnd/SimCodeMain.mo
Expand Up @@ -452,7 +452,8 @@ algorithm
then ();

case (_, _, "JavaScript") equation
callTargetTemplates(simCode,inQSSrequiredData,"C");
Tpl.tplNoret(CodegenC.translateModel, simCode);
Tpl.tplNoret2(SimCodeDump.dumpSimCodeToC, simCode, false);
Tpl.tplNoret(CodegenJS.markdownFile, simCode);
then ();

Expand Down
1 change: 0 additions & 1 deletion Compiler/Script/CevalScript.mo
Expand Up @@ -3961,7 +3961,6 @@ algorithm
st2 = st;// Interactive.replaceSymbolTableProgram(st,p);
timeCompile = System.realtimeTock(GlobalScript.RT_CLOCK_BUILD_MODEL);
resultValues = ("timeCompile",Values.REAL(timeCompile)) :: resultValues;
filenameprefix = Util.if_(stringEq(Config.simCodeTarget(),"JavaScript"), filenameprefix +& ".js", filenameprefix);
then
(cache,st2,compileDir,filenameprefix,method_str,outputFormat_str,init_filename,simflags,resultValues);

Expand Down
11 changes: 8 additions & 3 deletions Compiler/Template/CodegenC.tpl
Expand Up @@ -71,7 +71,10 @@ template translateModel(SimCode simCode)

let()= textFile(recordsFile(fileNamePrefix, recordDecls), '<%fileNamePrefix%>_records.c')

let _ = if simulationSettingsOpt then //tests the Option<> for SOME()
let _ = if stringEq(Config.simCodeTarget(),"JavaScript") then
let()= textFile(simulationInitFileCString(simulationInitFile(simCode,guid)), '<%fileNamePrefix%>_init.c')
""
else if simulationSettingsOpt then //tests the Option<> for SOME()
let()= textFile(simulationInitFile(simCode,guid), '<%fileNamePrefix%>_init.xml')
""
else
Expand Down Expand Up @@ -4400,7 +4403,7 @@ case SIMCODE(modelInfo=MODELINFO(__), makefileParams=MAKEFILE_PARAMS(__), simula
DLLEXT=<%makefileParams.dllext%>
CFLAGS_BASED_ON_INIT_FILE=<%extraCflags%>
CFLAGS=$(CFLAGS_BASED_ON_INIT_FILE) <%makefileParams.cflags%> <%match sopt case SOME(s as SIMULATION_SETTINGS(__)) then '<%s.cflags%> ' /* From the simulate() command */%>
CPPFLAGS=-I"<%makefileParams.omhome%>/include/omc/c" -I. <%makefileParams.includes ; separator=" "%> -DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME
CPPFLAGS=-I"<%makefileParams.omhome%>/include/omc/c" -I. <%makefileParams.includes ; separator=" "%> <% if not stringEq(Config.simCodeTarget(),"JavaScript") then "-DOPENMODELICA_XML_FROM_FILE_AT_RUNTIME"%>
LDFLAGS=<%dirExtra%> <%
if stringEq(Config.simCodeTarget(),"JavaScript") then <<-L'<%makefileParams.omhome%>/lib/omc/emcc' -lblas -llapack -lexpat -lSimulationRuntimeC -lf2c --llvm-lto 2 -s TOTAL_MEMORY=268435456 -s MAX_SETJMPS=2000 -s OUTLINING_LIMIT=20000 --pre-js <%makefileParams.omhome%>/lib/omc/emcc/pre.js>>
else <<-L"<%makefileParams.omhome%>/lib/omc" -L"<%makefileParams.omhome%>/lib" -Wl,<% if stringEq(makefileParams.platform, "win32") then "--stack,0x2000000,"%>-rpath,"<%makefileParams.omhome%>/lib/omc" -Wl,-rpath,"<%makefileParams.omhome%>/lib" <%ParModelicaLibs%> <%makefileParams.ldflags%> <%makefileParams.runtimelibs%>>>
Expand All @@ -4420,7 +4423,9 @@ case SIMCODE(modelInfo=MODELINFO(__), makefileParams=MAKEFILE_PARAMS(__), simula

omc_main_target: $(MAINOBJ) <%fileNamePrefix%>_functions.h <%fileNamePrefix%>_literals.h $(OFILES)
<%\t%>$(CC) -I. -o <%fileNamePrefix%>$(EXEEXT) $(MAINOBJ) $(OFILES) $(CPPFLAGS) <%dirExtra%> <%libsPos1%> <%libsPos2%> $(CFLAGS) $(LDFLAGS)

<% if stringEq(Config.simCodeTarget(),"JavaScript") then '<%\t%>rm -f <%fileNamePrefix%>'%>
<% if stringEq(Config.simCodeTarget(),"JavaScript") then '<%\t%>ln -s <%fileNamePrefix%>.node.js <%fileNamePrefix%>'%>
<% if stringEq(Config.simCodeTarget(),"JavaScript") then '<%\t%>chmod +x <%fileNamePrefix%>.node.js'%>
clean:
<%\t%>@rm -f <%fileNamePrefix%>_records.o $(MAINOBJ)

Expand Down
7 changes: 0 additions & 7 deletions Compiler/Template/CodegenFMU.tpl
Expand Up @@ -74,13 +74,6 @@ case sc as SIMCODE(modelInfo=modelInfo as MODELINFO(__)) then
"" // Return empty result since result written to files directly
end translateModel;

template simulationInitFileCString(Text text)
::=
<<
data->modelData.initXMLData = "<%Util.escapeModelicaStringToCString(text)%>";
>>
end simulationInitFileCString;

template fmuModelDescriptionFile(SimCode simCode, String guid)
"Generates code for ModelDescription file for FMU target."
::=
Expand Down
41 changes: 21 additions & 20 deletions Compiler/Template/CodegenJS.tpl
Expand Up @@ -7,9 +7,28 @@ import CodegenUtil.*;

template markdownFile(SimCode simCode)
::=
match simCode case SIMCODE(__) then textFile(markdownContents(simCode), '<%fileNamePrefix%>.md')
match simCode case SIMCODE(__) then
let () = textFile(markdownContents(simCode), '<%fileNamePrefix%>.md')
let () = textFile(nodeJSDriver(simCode), '<%fileNamePrefix%>.node.js')
""
end markdownFile;

template nodeJSDriver(SimCode simCode)
::=
match simCode
case SIMCODE(simulationSettingsOpt = SOME(s as SIMULATION_SETTINGS(__)))
then
<<
#!/usr/bin/env nodejs
var mod = require('./<%fileNamePrefix%>.js');
mod.callMain(process.argv.slice(2));
var fs = require('fs');
var fname = '<%fileNamePrefix%>_res.<%s.outputFormat%>';
var content = mod.OpenModelica_readFile(fname);
fs.writeFileSync(fname,content);
>>
end nodeJSDriver;

template markdownContents(SimCode simCode)
::=
match simCode
Expand All @@ -24,10 +43,6 @@ then
- lib/tinytimer.js
```

```yaml script=dataloader
xml: <%fileNamePrefix%>_init.xml
```

<style media="screen" type="text/css">
label {font-weight:normal; size: 0.9em}
</style>
Expand Down Expand Up @@ -71,20 +86,6 @@ html:
if (typeof(isRunning) == "undefined") isRunning = false

if (typeof(timer) != "undefined") {clearInterval(timer.interval); timer = null};
$xml = $(xml)

// Set the default simulation parameters
defex = $xml.find("DefaultExperiment")
defex.attr("stopTime", stopTime)
defex.attr("stepSize", +stopTime / intervals)
defex.attr("tolerance", tolerance)

// Set some model parameters
// Example:
// $xml.find("ScalarVariable[name = 'LAC']").find("Real").attr("start", LAC)

// Write out the initialization file
xmlstring = new XMLSerializer().serializeToString(xml)

$("#statustext").html('Simulation running')
$("#statustimer").html("");
Expand All @@ -99,7 +100,7 @@ if (typeof(wworker) != "undefined" && isRunning) wworker.terminate()
if (typeof(wworker) == "undefined" || isRunning) wworker = new Worker(basename + ".js")
isRunning = true

wworker.postMessage({basename: basename, xmlstring: xmlstring})
wworker.postMessage({basename: basename, stopTime: stopTime, tolerance: tolerance, stepSize: +stopTime / intervals})
wworker.addEventListener('error', function(event) {
});

Expand Down
7 changes: 7 additions & 0 deletions Compiler/Template/CodegenUtil.tpl
Expand Up @@ -303,6 +303,13 @@ let() = Tpl.addTemplateError(errMessage)
>>
end errorMsg;

template simulationInitFileCString(Text text)
::=
<<
data->modelData.initXMLData = "<%Util.escapeModelicaStringToCString(text)%>";
>>
end simulationInitFileCString;

end CodegenUtil;

// vim: filetype=susan sw=2 sts=2
2 changes: 1 addition & 1 deletion SimulationRuntime/c/Makefile.common
Expand Up @@ -94,7 +94,7 @@ RUNTIMEINITIALIZATION_HEADERS = \
# ./simulation/solver/solver_main.h \
# ./util/list.h \

.PHONY : clean all $(LIBF2C)
.PHONY : clean all $(LIBF2C) emcc emcc-clean

all : install

Expand Down
5 changes: 3 additions & 2 deletions SimulationRuntime/c/Makefile.in
Expand Up @@ -42,9 +42,10 @@ include Makefile.common
Makefile: Makefile.in
cd $(top_builddir); ./config.status

emcc: Makefile
cp -u /usr/include/expat*.h
emcc: Makefile emcc/pre.js
cp /usr/include/expat*.h .
emmake $(MAKE) OBJ_EXT=.bc CC=emcc CXX=emcc CFLAGS="$(CFLAGS) -DOMC_EMCC -DNO_INTERACTIVE_DEPENDENCY -I./simulation/libf2c/" libSimulationRuntimeC.bc
emmake $(MAKE) -C simulation/libf2c OBJ_EXT=.bc CC=emcc CXX=emcc libf2c.bc
cp emcc/pre.js libSimulationRuntimeC.bc simulation/libf2c/libf2c.bc $(builddir_lib)/emcc/
emcc-clean: Makefile
$(MAKE) OBJ_EXT=.bc clean
25 changes: 25 additions & 0 deletions SimulationRuntime/c/emcc/pre.js
@@ -0,0 +1,25 @@
var Module = {};

Module['noInitialRun'] = true;
Module['OpenModelica_readFile'] = function(fname) {
return intArrayToString(FS.findObject(fname).contents);
};

try { // Try to add an event listener like a webworker thread
self.addEventListener('message', function(e) {
var data = e.data;
if (!data) return;
var result = {};
try {
shouldRunNow = true;
var args = ['-override','outputFormat=csv,stopTime=' + data.stopTime +',tolerance=' + data.tolerance + ',stepSize=' + data.stepSize];
Module.callMain(args);
result.csv = intArrayToString(FS.findObject(data.basename + "_res.csv").contents);
result.status = "Simulation finished";
} catch(err) {
result.status = "Simulation failed";
};
self.postMessage(result);
}, false);
} catch (e) {
}

0 comments on commit 455c848

Please sign in to comment.