8

I am trying to load a pre-complied RemObjects Pascal Script in Delphi at run-time. However when I try to load it Delphi excepts with 'Cannot Import VALUE_TEAMCODE.' Value_TeamCode is a function in my Delphi app that I have already registered with Pascal Script.

Here is what I am doing. Rough pseudo code below - actual code is split over multiple files. Also the SetCompiled call below occurs much later in the app when the script is required to run.

Note regarding code: FPascalScript is a TPSScriptDebugger

...

//Register custom functions with Pascal Script
FuncsRegister;  

//Load script
FPascalScript.Script.AddStrings(AContent);

//Compile script
FPascalScript.Compile;

//Get compiled script
FPascalScript.GetCompiled(sCompiledScript)

//Try and set script back in - ERROR Here 'Cannot Import VALUE_TEAMCODE'
FPascalScript.PascalScript.Debugger.SetCompiled(sCompiledScript);

...

Maybe I am going about this wrong. I am not sure if it is even possible to load a pre-compiled script.

I searched on RemObjects WebSite Wiki but the Pascal Script help is deleted. I also searched various topics here on StackOverflow but none appear to be related to this issue.

Just another note. I already have scripts compiling and executing at run-time with no issues. I need to pre-compile for performance reasons.

Any help appreciated.

Update:

Current work around is to have one script engine per script in my system. These engines then stay in memory after pre-compilation. This removes the 30ms per script compilation overhead I have otherwise. It also uses bit more memory but not enough to be a concern.

I would still rather use just the one script engine though.(Hence the need to load pre-compiled script)

Peter Mayes
  • 133
  • 8
  • Are you sure the wiki / documentation is deleted? A google search for 'RemObjects Pascal Script Documentation' took me to a [useful-looking page](https://github.com/remobjects/pascalscript/wiki). – David Jun 14 '13 at 09:22
  • Yep I read those. Unfortunatley they are explaining more how the script works and how to register classes, methods etc. I have a work around though now - basically one script engine object per script which stays in memory after pre-compilation. – Peter Mayes Jun 17 '13 at 00:00
  • Just out or curiosity.. What made you choose RO pascalscript over DWS? Would you recommend it? – Wouter van Nifterick Jun 17 '13 at 00:37
  • RO PascalScript due to legacy code. – Peter Mayes Jun 18 '13 at 01:55

2 Answers2

1

Thanks to a response over on RemObject Connect beta forum I have a solution. (For post see http://connect.remobjects.com/discussion/comment/13540#Comment_13540)

Thanks go to poster vovanl.

I had to import my functions via the OnExecImport event as follows:

...

FPascalScript.OnExecImport := OnExecImport;
FPascalScript.SetCompiled(sCompiledScript);

...

TMyClass.OnExecImport(Sender: TObject; se: TPSExec; x: TPSRuntimeClassImporter);
begin
  se.RegisterDelphiFunction(@Value_TeamCode, 'Value_TeamCode', cdRegister);
end;

...

It appears SetCompiled clears all existing registrations and so you MUST hook OnExecImport to re-register functions, procedures, methods etc.

Note that it appears loading pre compiled script (ie changing out one script for another) does appear to add some extra time overhead. I have found my initial work around is in fact faster by around 6 times.

Peter Mayes
  • 133
  • 8
0

Rather than the how of this, I am going to counter with why?

Compiled scripts will likely be version bound, probably even platform/target bound - and they usually compile fast enough that you never notice the time hit. Are you really use the scripts intensely enough that compile time is an issue?

Sometimes the best answer is "do you really need to do this at all?"

  • if he is using it within a web server and the loading of compiled script is faster than the parsing + compilation process, then it's a must even if 5 ms it gained IMO. –  Jun 14 '13 at 08:19
  • This isn't an answer. It's a (good) comment to the original question, but it does nothing to answer the question asked here. – Ken White Jun 15 '13 at 01:07
  • The why is for perfomance reasons. My application is time critcial and any extra overhead adds up quiclky. Compiling at time of need takes 30ms. I have 20 odd scripts being compiled. That takes 600ms. I have a work around at the moment now though - basically one script engine object per script which stays in memory after pre-compilation. That way I don't have to load scripts. Uses more memory but not enough to be a concern. I would rather use just the one script engine though. – Peter Mayes Jun 17 '13 at 00:08
  • A few additional thoughts: Does your application change the scripts often enough to require the complexity and time penalties involved in scripting? Have you considered alternatives like DelphiWebScript? That is a very active scripting project right now with a serious focus on performance that might be more in line with your time sensitive requirements. – account deleted Jun 22 '13 at 16:15