A while ago, I started planning a new Data Abstract feature: we wanted to support scripting in the .NET parts of the product, for validating business rules on both the client and the server, and for writing server logic, like we already have in Data Abstract for Delphi. There were several options we considered to us to use:
- IronPython/Ruby
- JScript.NET
- Active Scripting JScript COM objects
- CodeDom (C#, VB.NET)
But each came with it’s own problems. CodeDom, IronPython & IronRuby wouldn’t work for the Delphi and OS X side of things, and we wanted the new solution to be compatible across platforms. JScript.NET was deprecated a while ago and isn’t updated anymore, and the JScript COM objects aren’t very easy to manage from .NET, and wouldn’t work on Mono.
So what we did instead was write our own JavaScript (or as it’s properly called ECMAScript) engine. Microsoft had just introduced the new DLR, so we decided to base it on that, to have a good framework that would let us have an implementation with good performance and interoperability with other DLR and non-DLR based languages.
Initially, the development of this went rather slow, as the DLR at the time was very new, not even a 1.0 version was available, there were few docs and the samples online were hopelessly out of date. Adding to that was the problem that every update of the DLR code changed something. But now the DLR is becoming quite stable and parts of it will be in the soon-to-be released .NET 4.0 framework.
Introducing Script for .NET
Script for .NET is the end result of this work, and it’s a free-with-source implementation of ECMAScript (edition 3). It has all the features expected from JavaScript and the default (non-browser) objects like Object, Array, Function, Math, Number, Date, String, Boolean and RegExp. As mentioned above, the engine is based on the Dynamic Language Runtime, but it works on version 2.0 and later of .NET, as well as on Mono.
Debugging Support
The engine includes support for in-process debugging by the host, allowing to step through, step into and step out of the current function, and inspect all the locals and their current state. The following screenshot of one of the included sample applications shows this i action:
To make the engine easier to use, the class library includes an EcmaScriptComponent class which wraps the DLR and Scripting engine, lets the application run and debug arbitrary scripts, as can be seen below.
privatevoid ShowMsg(string s){ MessageBox.Show(s);} ScriptEngine =new EcmaScriptComponent(); ScriptEngine.Globals.SetVariable("ShowMessage", new Action<string>(MessageBox.Show)); ScriptEngine.Source=@" var pi = Math.PI; ShowMessage('Todays value of PI is : '+pi);"; ScriptEngine.Run(); |
ScriptEngine.ExposeAssembly(typeof(System.Object).Assembly);// exposes all namespaces in mscorlib. |
You can read more about RemObjects Script on its product homepage. The project itself is maintained on our code.remobjects.com open source repository, with full access to the SVN and bug tracker. The Spring 2010 release is available for download, now.
With the script engine itself out of the way, we are now working o the integration with Data Abstract, for our Summer releases.