DWScript news: classes, exceptions, speedups

There have been quite a few changes, fixes and enhancements to DelphiWebScript, available in the SVN version:
  • class visibility is now enforced: private and protected are equivalent to Delphi’s strict private and strict protected. Other levels are public (members accessible to the whole script) and published (default visibility, to be used for external exposure, RPC, persistence, etc.)
  • added support for class abstract and class sealed: an abstract class has to be subclassed before it can be instantiated, a sealed class can’t be subclassed.
  • virtual methods are now based on a Virtual-Method Table, previously they were implemented in a way vaguely similar to Delphi’s “dynamic” methods. The new implementation is much faster, but at the cost of a (hopefully reasonable) memory overhead.  VMTs are shared, and thus only use memory for classes that actually introduce or override a virtual method.
  • fixes and improvements to the exception handling (ExceptObject now available).
  • fixes to the circular reference garbage collector.
  • fixes and improvements to the virtual class methods support, and properties based on class methods.
  • class-less procedures and functions calls are now faster.
  • partial inlining loop unrolling optimization for small statement blocks*.
  • other misc. optimizations, improvements and fixes.

There is also a new JSON support unit, which isn’t currently used by DWS, but has been introduced for testing and investigations. The strict JSON parser is AFAICT about twice faster than the current “fastest” Delphi JSON parser, with still some room for improvements.

*: the impact of those seem to be highly CPU-dependent, f.i. on the “Mandelbrot” demo, the speedup is a few percentage points on an AMD Phenom, but about 40% on my Intel Core i5.

edit: to be more accurate, it brings the Intel processor up to the level of the AMD cpu, the code must have been hitting a weakness in the Core i5 branch predictor.

SamplingProfiler 1.7.7 released

Version 1.7.7 of Sampling Profiler has been released, you can grab it here (642 kB), this version fixes the following issues:

  • Fixed gathering of samples in Monte-Carlo multi-threading mode.
  • Fixed crash when closing a results page with Ctrl+F4.
  • No longer restores to maximized or minimized state.

Leaps and bounds of DWScript

A DWS 2.2 preview zip (199 kB) has been posted, it is an SVN snapshot, and features recent additions to DWS:

  • Contracts are now partially supported: ensure, require and old are available and use the same syntax as Prism contracts, inheritance is supported, class invariants are not in just yet, mostly for syntax indecision reasons, see this thread.
  • the implies operator is now supported, “a implies b” is equivalent to “(not a) or b”, or in other words, it is false only if a is true and b is false.
  • Assert() is supported, and will trigger EAssertionFailed in case of, well, an assertion failure. A compiler option has been added to control the generation of assertions.
  • Exception now has a StackTrace method, which will return a textual stacktrace script-side. Runtime errors now also include a stack trace, and new Delphi-side methods provide access to even more details.
  • the in operator has been extended to allow class overloading, f.i. you can now use “if (aString in someStringList) then…”, the not in form is also supported.

A fair chunk of the error and exception code has been refactored, if you were relying on it, all the preexisting functionality is still there, though it has been shuffled around to (hopefully) more relevant locations.

Threaded script execution

The SVN trunk version of DWS now supports threaded script execution.

Things went quite smoothly given that practically all classes got affected, yet all tests pass, including a special threaded torture test, so I’m reasonably confident ;-). The changes are however breaking backward compatibility, hopefully for the best.

Here are the major changes that will affect your code:

  • Scripts used to compile to a TdwsProgram, they now compile to an IdwsProgram
  • An IdwsProgram is a factory for IdwsProgramExecution
  • Script executions now happen via IdwsProgramExecution
  • Messages are now split between IdwsProgram (compile time messages) and IdwsProgramExecution (runtime messages)

You can now have as many program executions for a given IdwsProgram as you wish, each execution will use memory for its heap & stack only, the compiled expression tree is shared. Both new interfaces use reference-counted memory management.

An IdwsProgramExecution is single threaded, but isn’t attached to any particular thread, meaning that it can be moved across threads freely, and re-run as many times as desired. A given TDelphiWebScript compiler component can still only compile one TdwsProgram at once. That said, you can have multiple TDelphiWebScript components, each compiling a different IdwsProgram in a different thread .

It goes without saying that of course, all the above is only valid if all the functions, classes and events you expose to the scripts are themselves thread-safe!

DWScript 2.1 branched

DWScript 2.1 RC2 has been promoted to stable 2.1.0 status, if you already have 2.1 RC2, you don’t need to download anything new.

If you use SVN, there is a now a “stable-2.1” branch which will see only fixes, evolutions and additions will now resume under “trunk”.

What can be expected for DWS 2.2?

In addition to the previously listed goals, which are still part of the background work, there are a few specific goals for 2.2:

  • separating execution context from the expression tree. Currently a compiled script can be run multiple times, but from only one thread at a a time, if you need to run two, you need to compile two instances (thus using up twice the memory). The goal is to allow the same program to be run from multiple threads at the same time.
  • language support for contracts programming.
  • 85% testing code coverage psychological threshold.
  • more demos/samples, at least a couple showcases of IDE/Debugger support features.

Delphi Web Script 2.1 now at RC2

Thanks to all those who reported issues with RC1!
DWScript 2.1 RC2, available there (186 kB) or from DWScript SVN.

  • fixed D2009 compatibility
  • fixed passing of “const” open arrays
  • fixed support of exceptions raised during optimization
  • fixed memory leaks in one of the demos and in some cases of script errors
  • component “uglicons” are now visible again
  • added hints for function calls with no effect (detected after optimization)
  • added some more unit tests
  • improved error messages for various cases of incorrect code

Unless anything major is uncovered, this should be it for 2.1, and a branch will be made in SVN before 2.2 begins.

DWScript RC1 now available

Delphi Web Script 2.1 RC1 is now available from google code DWS page, you can also download it directly as a zip here (184kB).

Changes since the last SVN update are:

  • Added support for FreePascal-like compile-time $INCLUDE “macros”:
    • %FILE% and %LINE% insert the current filename and line number into the source
    • %FUNCTION% inserts the current function name, or class.method name into the source
    • %DATE% and %TIME% allow inserting the compile date/time
  • Various minor optimizations for integers and maths
  • Fixes for some corner-cases, ambiguous error reporting, a few new test cases

Everything’s got to end some day…

…and DWScript will likely enter RC phase before the year ends, as almost all of what I had in mind for 2.1 will be there!

Recent SVN additions since the last update:

  • 75% of the DWScript core code is now covered by unit tests (this was a psychological milestone for 2.1!).
  • class operators have been added, currently those are “+=”, “-=”, “*=” and “/=”, they follow a syntax similar to properties, in that a class operator isn’t defined as a special method, but as syntax sugar for a regular method (see below).
  • Function call overhead has been reduced for in-script functions & methods, as well as TdwsUnit-based functions & methods.
  • TProgramInfo now has ParamAsXxx[] properties, which allow accessing parameters by index and in a more efficient (is less-safe)  fashion.
  • Sqr() became a special function, it will now return an integer and not a float when operating on an integer.
  • Various fixes and error message clarifications (thanks Alexey Kasantsev).

(more…)