Skip to content

Commit

Permalink
- fixes for dynamic loading.
Browse files Browse the repository at this point in the history
git-svn-id: https://openmodelica.org/svn/OpenModelica/branches/OpenModelica1.5.0@4229 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
adrpo committed Sep 16, 2009
1 parent 942fbdb commit 9c03fd4
Show file tree
Hide file tree
Showing 8 changed files with 252 additions and 111 deletions.
97 changes: 49 additions & 48 deletions Compiler/Ceval.mo
Expand Up @@ -87,6 +87,7 @@ protected import Connect;
protected import Error;
protected import Cevalfunc;
protected import CevalScript;
protected import Dump;

public function ceval
"function: ceval
Expand Down Expand Up @@ -227,10 +228,10 @@ algorithm
"Call of record constructors, etc., i.e. functions that can be constant propagated." ;
(cache,newval) = cevalFunction(cache, env, func, vallst, impl, msg);
then
(cache,newval,st);

/* see if function is in CF list and the build time is less than the edit time */
case (cache,env,(e as Exp.CALL(path = func,expLst = expl)),/*(impl as true)*/impl,
(cache,newval,st);
/* adrpo: TODO! this needs more work as if we don't have a symtab we run into unloading of dlls problem */
// see if function is in CF list and the build time is less than the edit time
case (cache,env,(e as Exp.CALL(path = func,expLst = expl)),impl,// (impl as true)
(st as SOME(Interactive.SYMBOLTABLE(p as Absyn.PROGRAM(globalBuildTimes=Absyn.TIMESTAMP(_,edit)),_,_,_,_,cflist,_))),_,msg)
local
Integer funcHandle;
Expand All @@ -250,9 +251,9 @@ algorithm
newval = System.executeFunction(funcHandle, vallst);
then
(cache,newval,st);

/* see if function is in CF list and the build time is less than the edit time */
case (cache,env,(e as Exp.CALL(path = func,expLst = expl)),/*impl as true*/impl,
/* adrpo: TODO! this needs more work as if we don't have a symtab we run into unloading of dlls problem */
// see if function is in CF list and the build time is less than the edit time
case (cache,env,(e as Exp.CALL(path = func,expLst = expl)),impl,// impl as true
(st as SOME(Interactive.SYMBOLTABLE(p as Absyn.PROGRAM(globalBuildTimes=Absyn.TIMESTAMP(_,edit)),_,_,_,_,cflist,_))),_,msg)
local
Integer funcHandle;
Expand All @@ -263,7 +264,11 @@ algorithm

(cache,false) = Static.isExternalObjectFunction(cache,env,func);
(true, funcHandle, buildTime, fOld) = Static.isFunctionInCflist(cflist, func);
Absyn.CLASS(_,_,_,_,Absyn.R_FUNCTION(),_,Absyn.INFO(buildTimes= Absyn.TIMESTAMP(build,_))) = Interactive.getPathedClassInProgram(func, p);
Absyn.CLASS(_,_,_,_,Absyn.R_FUNCTION(),_,Absyn.INFO(fileName = fNew, buildTimes= Absyn.TIMESTAMP(build,_))) =
Interactive.getPathedClassInProgram(func, p);

// note, this should only work for classes that have no file name!
true = stringEqual(fNew,""); // see that we don't have a file!

// see if the build time from the class is the same as the build time from the compiled functions list
//debug_print("edit",edit);
Expand All @@ -276,7 +281,7 @@ algorithm
newval = System.executeFunction(funcHandle, vallst);
then
(cache,newval,st);

/* adrpo: TODO! this needs more work as if we don't have a symtab we run into unloading of dlls problem */
case (cache,env,(e as Exp.CALL(path = funcpath,expLst = expl,builtin = builtin)),impl,st,_,msg)
/* Call functions FIXME: functions are always generated. Put back the check
and write another rule for the false case that generates the function */
Expand All @@ -295,16 +300,6 @@ algorithm
then
(cache,value,SOME(st));

/* Is this case really necessary?
case (cache,env,(e as Exp.CALL(path = funcpath,expLst = expl,builtin = builtin)),impl,st,_,msg)
local String s; list<String> ss;
equation
(cache,vallst) = cevalList(cache,env, expl, impl, st, msg);
(cache,newval,st)= cevalCallFunction(cache,env, e, vallst, msg, st);
then
(cache,newval,st);
*/

case (cache,env,Exp.BINARY(exp1 = lh,operator = Exp.ADD(ty = Exp.STRING()),exp2 = rh),impl,st,_,msg) /* Strings */
local String lhv,rhv;
equation
Expand Down Expand Up @@ -1022,12 +1017,12 @@ algorithm
then
fail();

/* Record constructors */
/* Record constructors */
case(cache,env,(e as Exp.CALL(path = funcpath,ty = Exp.COMPLEX(name=name, varLst=varLst))),vallst,msg,st)
local
list<Exp.Var> varLst; list<String> varNames; String name;
equation
true = RTOpts.debugFlag("evalfunc");
//true = RTOpts.debugFlag("evalfunc");
varNames = Util.listMap(varLst,Exp.varName);
then
(cache,Values.RECORD(Absyn.IDENT(name),vallst,varNames),st);
Expand All @@ -1042,7 +1037,7 @@ algorithm
SCode.ClassDef cdef;
list<DAE.Element> daeList;
equation
true = RTOpts.debugFlag("evalfunc");
//true = RTOpts.debugFlag("evalfunc");
failure(cevalIsExternalObjectConstructor(cache,funcpath,env));
(cache,sc as SCode.CLASS(_,false,_,SCode.R_FUNCTION(),cdef ),env1) =
Lookup.lookupClass(cache,env,funcpath,true);
Expand Down Expand Up @@ -1071,26 +1066,7 @@ algorithm
/**//* Call functions in non-interactive mode. FIXME: functions are always generated.
Put back the check and write another rule for the false case that generates the function
2007-10-20 partially fixed BZ*//**/
case (cache,env,(e as Exp.CALL(path = funcpath,expLst = expl,builtin = builtin)),vallst,msg,st) // crap! we have no symboltable!
local
Integer libHandle, funcHandle;
String funcstr,f;
equation
failure(cevalIsExternalObjectConstructor(cache,funcpath,env));
// make sure is NOT a record constructor!
failure((_,_) = cevalFunction(cache,env,funcpath,vallst,false,msg));
cache = CevalScript.cevalGenerateFunction(cache, env, funcpath);
funcstr = ModUtil.pathStringReplaceDot(funcpath, "_");
Debug.fprintln("dynload", "cevalCallFunction: about to execute " +& funcstr);
libHandle = System.loadLibrary(funcstr);
funcHandle = System.lookupFunction(libHandle, stringAppend("in_", funcstr));
newval = System.executeFunction(funcHandle, vallst);
System.freeFunction(funcHandle);
System.freeLibrary(libHandle);
then
(cache,newval,st);
/* adrpo: TODO! this needs more work as if we don't have a symtab we run into unloading of dlls problem */
case (cache,env,(e as Exp.CALL(path = funcpath,expLst = expl,builtin = builtin)),vallst,msg,
SOME(Interactive.SYMBOLTABLE(p as Absyn.PROGRAM(globalBuildTimes=ts),aDep,a,b,c,cf,lf))) // yeha! we have a symboltable!
local
Expand All @@ -1113,29 +1089,54 @@ algorithm
Absyn.ClassDef body;
Absyn.Info info;
Absyn.Within w;
String funcFileNameStr;
equation
false = RTOpts.debugFlag("nogen");
failure(cevalIsExternalObjectConstructor(cache,funcpath,env));
// make sure is NOT a record constructor!
failure((_,_) = cevalFunction(cache,env,funcpath,vallst,false,msg));
newCF = Interactive.removeCf(funcpath, cf); // remove it as it might be there with an older build time.
cache = CevalScript.cevalGenerateFunction(cache, env, funcpath);
funcstr = ModUtil.pathStringReplaceDot(funcpath, "_");
newCF = Interactive.removeCf(funcpath, cf); // remove it as it might be there with an older build time.
(cache, funcstr) = CevalScript.cevalGenerateFunction(cache, env, funcpath);
Debug.fprintln("dynload", "cevalCallFunction: about to execute " +& funcstr);
libHandle = System.loadLibrary(funcstr);
funcHandle = System.lookupFunction(libHandle, stringAppend("in_", funcstr));
newval = System.executeFunction(funcHandle, vallst);
System.freeLibrary(libHandle);
buildTime = System.getCurrentTime();
buildTime = System.getCurrentTime();
// adrpo: TODO! this needs more work as if we don't have a symtab we run into unloading of dlls problem
// update the build time in the class!
Absyn.CLASS(name,ppref,fpref,epref,Absyn.R_FUNCTION(),body,info) = Interactive.getPathedClassInProgram(funcpath, p);
info = Absyn.setBuildTimeInInfo(buildTime,info);
ts = Absyn.setTimeStampBuild(ts, buildTime);
w = Interactive.buildWithin(funcpath);
p = Interactive.updateProgram(p,Absyn.PROGRAM({Absyn.CLASS(name,ppref,fpref,epref,Absyn.R_FUNCTION(),body,info)},w,ts));
Debug.fprintln("dynload", "Updating build time for function path: " +& Absyn.pathString(funcpath) +& " within: " +& Dump.unparseWithin(0, w) +& "\n");
p = Interactive.updateProgram(Absyn.PROGRAM({Absyn.CLASS(name,ppref,fpref,epref,Absyn.R_FUNCTION(),body,info)},w,ts), p);
f = Absyn.getFileNameFromInfo(info);
then
(cache,newval,SOME(Interactive.SYMBOLTABLE(p, aDep, a, b, c,
(Interactive.CFunction(funcpath,(Types.T_NOTYPE(),SOME(funcpath)),funcHandle,buildTime,f) :: newCF), lf)));
Interactive.CFunction(funcpath,(Types.T_NOTYPE(),SOME(funcpath)),funcHandle,buildTime,f)::newCF, lf)));

case (cache,env,(e as Exp.CALL(path = funcpath,expLst = expl,builtin = builtin)),vallst,msg,NONE()) // crap! we have no symboltable!
local
Integer libHandle, funcHandle;
String funcstr,f,funcFileNameStr;
equation
false = RTOpts.debugFlag("nogen");
failure(cevalIsExternalObjectConstructor(cache,funcpath,env));
// make sure is NOT a record constructor!
failure((_,_) = cevalFunction(cache,env,funcpath,vallst,false,msg));
// we might actually have a function loaded here already!
// we need to unload all functions to not get conflicts!
(cache,funcstr) = CevalScript.cevalGenerateFunction(cache, env, funcpath);
// generate a uniquely named dll!
Debug.fprintln("dynload", "cevalCallFunction: about to execute " +& funcstr);
libHandle = System.loadLibrary(funcstr);
funcHandle = System.lookupFunction(libHandle, stringAppend("in_", funcstr));
newval = System.executeFunction(funcHandle, vallst);
System.freeFunction(funcHandle);
System.freeLibrary(libHandle);
then
(cache,newval,NONE());

case (cache,env,(e as Exp.CALL(path = funcpath,expLst = expl,builtin = builtin)),vallst,msg,st)
local String error_Str;
Expand Down
39 changes: 27 additions & 12 deletions Compiler/CevalScript.mo
Expand Up @@ -1866,7 +1866,7 @@ algorithm
case (cache,env,Exp.CALL(path = Absyn.IDENT(name = "generateCode"),expLst = {Exp.CODE(Absyn.C_TYPENAME(path),_)}),(st as Interactive.SYMBOLTABLE(ast = p,explodedAst = sp,instClsLst = ic,lstVarVal = iv,compiledFunctions = cf)),msg)
equation
cache = cevalGenerateFunction(cache,env, path) " & Inst.instantiate_implicit(p\') => d &" ;
(cache,_) = cevalGenerateFunction(cache,env, path) " & Inst.instantiate_implicit(p\') => d &" ;
then
(cache,Values.BOOL(true),st);
Expand Down Expand Up @@ -2626,6 +2626,7 @@ algorithm
omhome_1,pd,"bin",pd,"Compile"," ",fileprefix," ",noClean});
Debug.fprintln("dynload", "compileModel: running " +& s_call);
0 = System.systemCall(s_call) ;
Debug.fprintln("dynload", "compileModel: successful! ");
then
();
// If compileCommand is set.
Expand All @@ -2639,10 +2640,11 @@ algorithm
libs_str = Util.stringDelimitList(libs, " ");
libsfilename = stringAppend(fileprefix, ".libs");
System.writeFile(libsfilename, libs_str);
s_call = Util.stringAppendList({"set OPENMODELICAHOME=",omhome_1," && ",command," ",fileprefix," ",noClean});
s_call = Util.stringAppendList({"set OPENMODELICAHOME=",omhome_1,"&& ",command," ",fileprefix," ",noClean});
// print(s_call);
Debug.fprintln("dynload", "compileModel: running " +& s_call);
0 = System.systemCall(s_call) ;
Debug.fprintln("dynload", "compileModel: successful! ");
then
();

Expand All @@ -2652,6 +2654,7 @@ algorithm
0 = System.regularFileExists(filename);
str = System.readFile(filename);
Error.addMessage(Error.SIMULATOR_BUILD_ERROR, {str});
Debug.fprintln("dynload", "compileModel: failed!");
then
fail();
case (fileprefix,libs,file_dir,_)
Expand Down Expand Up @@ -3986,14 +3989,24 @@ algorithm
makefilename := Util.stringAppendList({filenameprefix,".makefile"});
end generateMakefilename;

protected function generateFunctionName
"@author adrpo:
generate the function name from a path."
input Absyn.Path functionPath;
output String functionName;
algorithm
functionName := ModUtil.pathStringReplaceDot(functionPath, "_");
end generateFunctionName;

public function cevalGenerateFunction "function: cevalGenerateFunction
Generates code for a given function name."
input Env.Cache inCache;
input Env.Env inEnv;
input Absyn.Path inPath;
output Env.Cache outCache;
output String functionName;
algorithm
outCache :=
(outCache,functionName) :=
matchcontinue (inCache,inEnv,inPath)
local
String pathstr,gencodestr,cfilename,makefilename,omhome,str,libsstr;
Expand All @@ -4002,13 +4015,14 @@ algorithm
Env.Cache cache;
String MakefileHeader;
list<String> libs;
case (cache,env,path)

case (cache, env, path)
equation
false = RTOpts.debugFlag("nogen");
(cache,false) = Static.isExternalObjectFunction(cache,env,path); //ext objs functions not possible to Ceval.ceval.
Debug.fprintln("ceval", "/*- Ceval.cevalGenerateFunction starting*/");
pathstr = ModUtil.pathStringReplaceDot(path, "_");
(cache,gencodestr,_,libs) = cevalGenerateFunctionStr(cache,path, env, {});
(cache,false) = Static.isExternalObjectFunction(cache,env,path); //ext objs functions not possible to Ceval.ceval.
pathstr = generateFunctionName(path);
Debug.fprintln("ceval", "/*- Ceval.cevalGenerateFunction starting*/");
(cache,gencodestr,_,libs) = cevalGenerateFunctionStr(cache, path, env, {});
cfilename = stringAppend(pathstr, ".c");
str = Util.stringAppendList(
{"#include \"modelica.h\"\n#include <stdio.h>\n#include <stdlib.h>\n#include <errno.h>\n\n",
Expand Down Expand Up @@ -4042,13 +4056,14 @@ algorithm
System.writeFile(makefilename, str);
compileModel(pathstr, {}, "", "");
then
(cache);
case (cache,env,path)
(cache,pathstr);
case (cache, env, path)
equation
pathstr = Absyn.pathString(path);
false = RTOpts.debugFlag("nogen");
(cache,false) = Static.isExternalObjectFunction(cache,env,path);
pathstr = generateFunctionName(path);
pathstr = stringAppend("/*- Ceval.cevalGenerateFunction failed(", pathstr);
pathstr = stringAppend(pathstr,")*/\n");
(cache,false) = Static.isExternalObjectFunction(cache,env,path);
Debug.fprint("failtrace", pathstr);
then
fail();
Expand Down
1 change: 1 addition & 0 deletions Compiler/CevalScript_stub.mo
Expand Up @@ -704,6 +704,7 @@ public function cevalGenerateFunction "function: cevalGenerateFunction
input Env.Env inEnv;
input Absyn.Path inPath;
output Env.Cache outCache;
output String functionName;
algorithm
outCache := inCache;
end cevalGenerateFunction;
Expand Down

0 comments on commit 9c03fd4

Please sign in to comment.