DelphiWebScript II

Script Programmers Guide

Table of Contents

Introduction

What is DelphiWebScript II?

DelphiWebScript II (DWSII) is a scripting engine for application scripting or for server side scripting. The script language of DWS is a subset of
Delphi(tm) pascal. DelphiWebScript is a component for the programming system "Borland Delphi"

License

DelphiWebScript II is distributed under "Mozilla Public License 1.1" (MPL 1.1). Please refer to the DWS homepage for additional information.

Installation

Delphi 6, Delphi 5, Kylix 1

  1. If you didn't download the archive containing this file from www.dwscript.com, then please check for updates at http://www.dwscript.com or sourceforge (projectname "dws")
  2. Extract the archive (if not already done) to a directory of your choice - I'll call it "<DWSDIR>"

  3. Start Delphi and load the right BorlandProjectGroup file according to your version of Delphi.
    e.g.:
    Delphi 5 -> <DWSDIR>\Delphi5.bpg
    Delphi 6 -> <DWSDIR>\Delphi6.bpg
    Kylix -> <DWSDIR>\Kylix1.bpg

    DWSII only supports Delphi 6, Delphi 5 and Kylix 1 at this time officially. Delphi 4 might work with a few modifications too, but has not been tested.
    For all Borland C++ Builder users: Please send feedback about your experiences with DWSII to the DWS mailinglist!

  4. If you don't see the Delphi ProjectManager, then open it. (DelphiMenu -> View -> ProjectManager)

  5. Compile all dws2XXXRuntimeXX.bpl packages in the project

  6. Install the dclXXXX.bpl package

  7. Add <DWSDIR>\source to your library path
    ATTENTION: When using Kylix be sure to include your bpl output directory in your LD_LIBRARY_PATH variable!
    (See e.g. /etc/profile or ~/.bashrc)
  8. Install the DWSII libraries (optional):
    1. Open Libraries\Delphi5Libraries.bpg
    2. Compile and install the .bpl files of all libraries you need.
  9. Look at the DWSII demo program in <DWSDIR>\Demo


If you need further assistance, please subscribe yourself to the DWS mailinglist. You can do this simply by sending an email to following address: join.dwsforum@dwscript.com
ATTENTION: Write your list-messages to: dwsforum@dwscript.com

If you don't want to subscribe to the list, but still need support, you can use the Web-Forum at sourceforge:
http://sourceforge.net/forum/forum.php?forum_id=64301

First Steps with DelphiWebScript II

If DelphiWebScript II is installed correctly, a new tab "DWS2" appears in your Delphi component palette. To use DWSII in your project execute the following instructions:

  1. Place a TDelphiWebScriptII component on your form.
  2. Add the following code somewhere to your project:

    uses
     
    dws2Exprs, ...
     
    [...] 
    var
      [...] 
      prog: TProgram;
    begin
      [...]
      prog := DelphiWebScriptII1.Compile('PrintLn(''Hello World'');');
      try
        prog.Execute;
        ShowMessage(prog.Result.AsString);  
      finally
        prog.Free;
      end;
      
    end;

This is a very simple example. For more detailed information about using DelphiWebScript II please have a look at the demo program. 

Language Reference

DWSII uses a language that is very similar to Delphi from Borland. So this reference only describes the differences to Delphi pascal. It is assumed that you already know the programming language of Delphi!

Structure of a Script Program

A Delphi program has the following structure:

program ProgramName;
  Declarations
begin
  Instructions
end.

Difference 1: A DWSII script program has no structure. You can place declarations and instructions everywhere you want. For this reason every declaration starts with a keyword and ends with a semicolon. Example:

var i: Integer;
i := 2;
type TPoint = record x, y: Integer; end;
type TRect = record x, y, w, h: Integer end;
var r: TRect;
r.x := 3;
procedure Proc(x: Integer);
begin
end;
Proc(x);

Difference 2: You can't place declarations in the procedure declaration. Example:

BAD:
procedure
Proc(x: Integer);
type
  TMyRec = record a, b: string end; // ERROR!!
begin
end;

GOOD:
procedure
Proc(x: Integer);
begin
  type TMyRec = record a, b: string end; // OK!!
end;

Declarations

Possible declarations are:

const Name = Value;

type Name = TypeName; 
type Name = record ... end;
type
Name = array [x1..x2, ...] of TypeName;
type Name = class ... end;

procedure Name(Param: TypeName; ...);
begin
end;

function Name(Param: TypeName; ...): TypeName;
begin
end;

Delphi has many built in basic data types like "integer", "single", "double", "currency", "ansistring", "shorttring", ... DelphiWebScript II doesn't support all of these types but only the most important ones.

The basic data types of DelphiWebScript II are:

Additional Features (not part of Delphi)

Extended CASE syntax

In Delphi the case statement only works with integer types. But in DWSII you can use all comparative datatypes in the case-instruction: 

var s: string;
s := 'Alpha';
case s of
  'Alpha': DoSomething;
  'Beta', 'Gamma': DoSomethingElse;
end;

Nested Declarations

Because you can declare a variable anywhere in a DWSII program it's also possible to declare it inside a block (begin .. end). The declaration of a variable is only visible in the actual block and in any sub-blocks:

var i: Integer;

if i = 0 then  
begin
  var j: Integer;
  j := 2;

  while j > 0 do 
  begin
    var k: Integer;
    k := 2;
    j := j - k;
  end;

end;

var j: String; // Variable "j" declared inside the
               // if-block is not visible here!

Variable Initialization

It's possible to initialize a variable using the var-statement: 

var s: Integer = 2;
var str: String = 'Hello' + IntToStr(s);

var i: Integer = 12;

is the same as

var i: Integer;
i := 12;

Unsupported Delphi features

Object Pascal

Overloaded Functions / Procedures

Delphi knows a "overload" directive for procedures. You can't declare overloaded functions in DWSII!

Sets and Enumerations

DWSII has no support for sets and enumerations

Compiler directives

DWSII has only two compiler directives. Example:

{$I 'File'}
{$Include 'File'}

{$A 'File'}
{$ADAPTER 'File'}

Important: In difference to Delphi the quotes ('') around the filename are obligatory!

Low Level Features

Low level features are not part of DWSII:

Component Reference

TDelphiWebScriptII

TDelphiWebScriptII is the main component in the DWSII package. It manages all information needed for the compilation. The property "Config" is  storing the include paths, compiler options and so on...

TDelphiWebScriptII Properties

TDelphiWebScriptII.Adapter
The adapter property stores a reference to an Tdws2Adapter component. An adapter has two important purposes: Provide output functionality and process the input (script programs). TDelphiWebScript is also derived from Tdws2Adapter and can be assigned to this property. It offers the two output functions "Print" and "PrintLn". 

TDelphiWebScriptII.Config.CompilerOptions
Available compiler options are:

TDelphiWebScriptII.Config.MaxDataSize
All data in a DWSII script program is stored on a global stack. This stack is able to grow and shrink dynamically at runtime. If you assign a value different to 0 to this property the stack won't grow larger than this value in bytes. If it still grows larger a runtime error is raised. 
This property is useful to avoid recursive program to use up all memory and to prevent users from defining large data structures. But it's not a general protection! There are still many ways to write a script program that uses up all memory!

TDelphiWebScriptII.Config.ScriptPaths
If you use a {$INCLUDE 'file.dws'} compiler switch in your script program and 'file.dws' is not found the compiler tries to find 'file.dws' relative to every path in .ScriptPaths. You can add multiple paths by writing every path on a new line. The path will automatically be terminated by a backslash ("\" or foreslash "/" for Linux).

TDelphiWebScriptII.Config.Timeout
If .Timeout is set to a value different to 0 the script execution will be terminated after .Timeout seconds. This is useful to avoid scripts with endless-loops using up all of the systems resources.

TDelphiWebScriptII.Version
The version of the DelphiWebScript II component package.

TDelphiWebScriptII Methods

constructor TDelphiWebScriptII.Create(AOwner: TComponent);
destructor TDelphiWebScriptII.Destroy;
Creates and destroys instances of the TDelphiWebScriptII component. If you have to create TDelphiWebScriptII components dynamically for some reasons use TDelphiWebScriptII.Create(nil);

function TDelphiWebScriptII.Compile(const Text: string): TProgram;
Compiles the script program in "Text" with the current settings and returns a TProgram object. If compilation errors occurred you can read the error messages in TProgram.Msgs (see als "TProgram properties" below

TProgram

TProgram.Methods

constructor  TProgram.Create(SystemTable: TSymbolTable; Adapter: IAdapter);
destructor  TProgram. Destroy; override;
Creates and destroys an instance of TProgram. You don't have to call Create() yourself. This is done by the compiler. But the destruction of the TProgram object is your task.

function  TProgram.AddObj(Obj: TScriptObj): Integer;
procedure  TProgram.FreeObj(Id: Integer);
function  TProgram.GetObj(Id: Integer): TScriptObj;
function  TProgram.HasObj(Id: Integer): Boolean;
function  TProgram.EnumerateScriptObjs(EnumFunc: Enumerator): TScriptObj;
function  TProgram.FindExternalObject(Obj: TObject): TScriptObj;
DelphiWebScript II maintains a list of object instances created during the execution of a script program. These are the methods to add and remove such object to the list and to query the list. In almost every case you don't need to call these methods.

procedure  TProgram.Execute 
procedure  TProgram.Execute(TimeoutValue: Integer); 
Executes the script program. If you specify a "TimeoutValue" different to 0 (default) this value overrides the one set by TDelphiWebScriptII.Timeout and the script is terminated after TimeoutValue seconds.

procedure  TProgram.ExecuteParam(Params: array of Variant); 
procedure  TProgram.ExecuteParam(Params: array of Variant; TimeoutValue: Integer); 
Same as TProgram.Execute but additionally you have the possibility to pass parameters to the script program. In script code you can read the parameters using the functions "ParamCount: Integer",  "ParamStr(Index: Integer): string" and "Param(Index: Integer): Variant". Parameters are numbered from 0 to ParamCount - 1. You can only pass values of simple types (string, integer, float, boolean, datetime). Example: Prog.ExecuteParam([1, 'Hello', 3.4, false]);

procedure  TProgram. Stop;
Stops the execution of the script program as soon as possible. Remember: If TProgram is executing an external procedure the program won't stop until this procedure returns.

TProgram.Properties

property TProgram.Adapter: IAdapter;
Same as TDelphiWebScriptII.Adapter.

property TProgram. Debugger: IDebugger;
If you assign a value to this property the TProgram object starts to call the debugger every time an instruction is executed. If a debugger is assigned the flag IsDebugging is set to true if you call TProgram.Execute. You can change the debugger at runtime, too. You can download debugger components on the DWS homepage.

property TProgram.Expr: TExpr;
This is the root node of the expression tree that represents the compiled script program. You shouldn't use this property!  

property TProgram.IsDebugging: Boolean;
This property is set to True if a Debugger is assigned and Execute is called. If you set this property to False at runtime the debugging is disabled. If the program is not running (IsRunning = False) this property has no effect.

property TProgram.IsRunning: Boolean;
This property is read-only. It's True if the program is running (TProgram.Execute) and False otherwise

property TProgram. Level: Integer;
This property is only used by the compiler. It determines the nesting level of this "Procedure" which is always 0 for the main program.

property TProgram.Msgs: TMsgs;
The Msgs property is very important. It tells you many things about the state of the TProgram object. If you didn't yet execute the TProgram you can check if there were compiler errors using Msgs.HasSyntaxErrors. The number of error message is Msgs.Count. The first message is Msgs.Msgs[0] and the last one is Msgs.Msgs[Msgs.Count - 1]. You can get the error message unformatted with Msgs.Msgs[x].AsString or with additional information with Msgs.Msgs[x].AsInfo.  

property TProgram. Stack: TStack;
This property is only used by the compiler

property TProgram. Stopped: Boolean;
This property is set to True if you call TProgram.Stop. It remains true until the program is executed again. Remember: It's possible that IsRunning and Stopped are both True.

property TProgram.Table: TSymbolTable;
This property is only for experts.

property TProgram. Timeout: Integer;
This property is used to set and read the actual timeout value. The default value is TDelphiWebScriptII.Timeout. You can also set a timeout value calling TProgram.Execute(TimeoutValue);

property TProgram.TypBoolean: TSymbol;
property
TProgram.TypFloat: TSymbol;
property
TProgram.TypInteger: TSymbol;
property
TProgram.TypNil: TNilSymbol;
property
TProgram.TypObject: TClassSymbol;
property
TProgram.TypString: TSymbol;
property
TProgram.TypVariant: TSymbol;
These properties are only used by the compiler.

Tdws2Unit

Tdws2Unit is mainly used to define external functions for DWS programs. If such a function is called in a script program the call is passed to the corresponding Delphi object (a Tdws2Function in this case) and this object fires it's OnEval event. You can write any Delphi code in this event handler. 

But Tdws2Unit is much more powerful. You can also define arrays, records and classes. The definition of classes is mostly used to create wrapper classes for the classes of your Delphi program. The methods of your Tdws2Unit class call the methods of the Delphi class in their OnEval event handler.

Tdws2Unit.Properties

property Tdws2Unit.Arrays: Tdws2Arrays;
You need the Arrays property if you want to pass an arrays as parameters to your functions. The properties of Tdws2Array are used like this:

type Name = array [LowBound .. HighBound] of DataType

You can only define arrays of one dimension. If you need multi dimensional arrays you have to define every dimension extra:

TSingleDimension = array [0..9] of Integer;
TMultiDimension = array [0..9] of TSingleDimension;

property Tdws2Unit.Classes: Tdws2Classes;
The Classes property is used to define wrapper classes for Delphi classes. The properties of Tdws2Class are used like this:

type Name = class (Ancestor)
  Fields
  Methods
  Properties
end;

property Tdws2Unit.Constants: Tdws2Constants;
The Constants property is used to define constants in a Tdws2Unit. The properties of Tdws2Constant are used like this:

const Name: DataType = Value;

property Tdws2Unit.Dependencies: TStrings;
If use datatypes defined in other Tdws2Units you can add the .UnitName of these Tdws2Units here. E. g. if you'd like to use the record type "TPoint" from Tdws2Unit "Graphics" and the object "TErrorMsg" from Tdws2Unit "Errors" add the strings "Graphics" and "Errors". Place multiple entries on single lines.

property Tdws2Unit.Forwards: Tdws2Forwards;
The Forwards property is used if you want to define cross-link declarations of classes:

TClassB = class;

TClassA = class
  FClassB: ClassB;
end;

TClassB = class
  FClassA: TClassA;
end;

In this case you should add the name "TClassB" to the Forwards property. It's also necessary that TClassA is declared before TClassB in the Classes collection!

property Tdws2Unit.Functions: Tdws2Functions;
This property is used if you want to declare an external function for your DWS scripts. The properties of Tdws2Function are used like this:

function Name (Params): DataType;

property Tdws2Unit.Records: Tdws2Records;
This property is used if you want to declare an external function for your DWS scripts. The properties of Tdws2Function are used like this:

property Tdws2Unit.Script: TDelphiWebScriptII;
You have to assign this property to a TDelphiWebScriptII component on your forms. The functions and data types declared in this Tdws2Unit are only known to scripts that are compiled with that TDelphiWebScriptII component! 

property Tdws2Unit.UnitName: string;
The name of this Tdws2Unit in DWSII programs and in the property .Dependencies of other Tdws2Units. You can also use the syntax "unitname.datatype..." in DWSII programs.

property Tdws2Unit.Variables: Tdws2Variables;
You can also declare variables using the Variables property for use in your script program. But in difference to normal variables of a script these variables have additional capabilities: 
Property AutoInstantiate: If this property is set to True and the property Datatype points to a class and you read this variable the first time in the script this happens: An object of the class Datatype is created and the event OnInstantiate is called. To the script programmer this variable will behave like an object of type Datatype. If the class is a wrapper class for a Delphi object you can assign the Delphi object in the OnInstantiate event. If the script terminates all script objects will be destroyed and the OnCleanup event of this variable will be fired. If necessary you can now destroy the assigned Delphi object. 
Alternatively you can set AutoDestroyExternalObjects to True. Now the assigned Delphi object is automatically freed if the script terminates.
If you assign an event handler to the events OnReadVar and OnWriteVar every time your read or write the variable in the script the corresponding even is fired. You can't use OnReadVar/OnWriteVar together with AutoInstantiate

TProgramInfo

If you defined a function or a method using Tdws2Unit and this function is called in the script code an OnEval event is fired. To write the event handler you need information about the script that called the function. You need the values of the parameters, you have to set the result value or you may want to call another script function. For all this purposes a parameter "Info" of type TProgramInfo is passed to every OnEval event handler.

TProgramInfo Methods

constructor TProgramInfo.Create(Table: TSymbolTable);
Creates a new TProgramInfo object that provides information about the symboltable "Table"

function TProgramInfo.GetTemp(DataType: string): IInfo;
Creates an unnamed temporary variable of type "DataType". Temporary variables are used to assign values to variables of complex types (like records or arrays). 

TProgramInfo Properties

property TProgramInfo. Caller: TProgram;
The caller of this function. 

property TProgramInfo.Data[s: string]: TData;
In most cases you'll use Value to assign values to a variable. But if the value is larger than on variant (e. g. if it's a record/array) you use Data and assign an array of Variant.

property TProgramInfo.Func[s: string]: IInfo;
Returns the interface representing the function, procedure or method "s". See IInfo for more information.

property TProgramInfo.FuncSym: TFuncSymbol;
In most cases TProgramInfo is used to access the variables of the function that was called. In this case FuncSym points to the TFuncSymbol object that represents the Function in the symbol table.

property TProgramInfo.Method[s: string]: IInfo;
Returns the interface representing the function, procedure or method "s". See IInfo for more information.

property TProgramInfo.Obj: TScriptObj;
If the TProgramInfo object is used to access the variables of a method Obj points to the "Self" object. Info.Vars['self'].Obj points to the same object.

property TProgramInfo.Value[s: string]: Variant; default;
This is a shortcut to Info.Vars[s].Value. Because Value is the default property of TProgramInfo you can also omit the property name "Value" an write Info['varname']. 

property TProgramInfo.Vars[s: string]: IInfo;
Returns an interface representing the variable s. See IInfo for more information. 

IInfo

IInfo Methods

function IInfo.Call: IInfo; 
This method is only of interest if the IInfo interface was returned by TProgramInfo.Func[], TProgramInfo.Method[] or IInfo.Method[]. This method executes the call to that function or method. If the function has a result value Call returns the interface representing that value. To pass parameters to this function you should first use IInfo.Parameters[] to set them

function IInfo.Call(Params: array of Variant): IInfo; 
This method is only of interest if the IInfo interface was returned by TProgramInfo.Func[], TProgramInfo.Method[] or IInfo.Method[]. This method executes the call to that function or method. If the function has a result value Call returns the interface representing that value. To pass parameters to this function you can pass an array of variants containing the parameter values. If the parameter values are records or arrays you should use the Call method without arguments and pass the variables using IInfo.Parameter[]

function IInfo.Element(const Indizes: array of Integer): IInfo;
This method is only of interest if the IInfo interface was returned by TProgramInfo.Vars[] and denotes a variable of type array. To select an element of the array you pass an array of integer indices to this function. The result of Elements represents the selected element. 

function IInfo.GetConstructor((MethName: string; ExtObject: TObject): IInfo;
This method is similar to Method[MethName]. It is used to create a script object (using constructor MethdName) and connect it immediately to a Delphi object ExtObject. Example: Info['Result'] := Info.Vars['TList'].GetConstructor('Create', TList.Create).Call.Value; 

property IInfo. Data: TData;
If the IInfo represents a variable of a complex type (record or array) you don't have to set every element of the array or every member of the record one by one. You can also pass all elements of an array of Variants by assigning it to IInfo.Data or get all members of a record in an array of Variants by reading IInfo.Data

property IInfo.Member[s: string]: IInfo;
If the IInfo interface represents a variable of type record you can select a single member using IInfo.Member[]

property IInfo.Method[s: string]: IInfo;
If the IInfo interface represents an object - variable you can get an IInfo interface to call a method of this object.

property IInfo.Obj: TScriptObj;
If the IInfo represents a variable of type class IInfo.Obj points to the corresponding TScriptObj object.

property IInfo.Parameter[s: string]: IInfo;
If the IInfo interface represents a function or method you can set the parameters using IInfo.Parameter[]

property IInfo. Value: Variant;
If the IInfo represents a variable of a simple type you can set or read its value using IInfo.Value.

Tdws2GUIFunctions

If you place this component to the form several utility functions are added to every TDelphiWebScriptII component on the form. The utility functions in Tdws2GUIFunctions are all used to display different kind of message boxes.

Tdws2FileFunctions

If you place this component to the form several utility functions are added to every TDelphiWebScriptII component on the form. The utility functions in Tdws2FileFunctions are all used to read from or write to files.

Tdws2SimpleDebugger

Tdws2SimpleDebugger is the simplest possible debugger that you can imagine. It does nothing else than converting the calls to the debugger to events. More usable debuggers are available on the DWS homepage

property Tdws2SimpleDebugger.OnDebug: TOnDebugEvent;
This event is called for every instruction in the script program. 

property Tdws2SimpleDebugger.OnDebugStart: TOnDebugStartStopEvent;
Is called before OnDebug is fired the first time

property Tdws2SimpleDebugger.OnDebugStop: TOnDebugStartStopEvent;
Is fired after OnDebug was fired the last time

property Tdws2SimpleDebugger.OnEnterFunc: TOnDebugEvent;
Is fired everytime a function is called

property Tdws2SimpleDebugger.OnLeaveFunc: TOnDebugEvent;
Is fired everytime a function call is finished.

Using TProgramInfo / IInfo

If you declare functions or methods in a Tdws2Unit and also in the built-in function a TProgramInfo object is used to exchange data with the running script program. You can read and write parameteres, global variables and set the result value. But you can also call functions and create objects.

For the following explanations we assume that you have defined a function "Func" in a Tdws2Unit. The following code could be part of the OnEval event handler:

procedure TForm1.dws2UnitFunctionsFuncEval(Info: TProgramInfo);
begin
  ...
end;

The following declaration are supposed to be made in a Tdws2Unit but are given in DWSII syntax:

type TPoint = record x, y: Integer; end;
type TNames = array[1..10] of String;

var global: string;

function Func(i: Integer; point: TPoint; names: TNames): float;
begin
   // OnEval event handler
end;

Parameters, Variables and Result Values

You can access the parameters and global variables by their name under the same rules as in a normal script function (e. g. you can't read local variables of other procedures).

Read the value of the parameter "i":

x := Info.Vars['i'].Value;

You can also use the default property of TProgram to shortcut the expression above:

x := Info['i'];

Of course you can also assign a value to a local variable

Info['i'] := 12;

Setting a result value for your function is very simple:

Info['result'] := 3.141592;

Arrays and Records

If the parameter or the variable is of a complex type (array, record) you can read an write values like this:

x := Info.Vars['point'].Member['x'].Value;
Info.Vars['point'].Member['y'].Value := 3;

x := Info.Vars['names'].Element([2]).Value;
Info.Vars['names'].Element([2]).Value := 'Hello World';

Of course it's also possible to cascade such expressions:

Info.Vars['xyz'].Element([2, 4, 5]).Member['aaa'].Element([1]).Value := 'Hello World';

Functions

You can also call functions using the TProgramInfo object:

Info.Func['IntToStr'].Call([345]);

Another possibility to call a function is given below.

var
  inf: IInfo;
  res: Integer;
begin
  inf := Info.Func['StrToInt'];
  inf.Paramter['value'] := '123';
  res := inf.Call.Value;

Use this way if you have to call a function that uses var-parameters and you're interested in the output value. You can use the "Parameter" property after the function call to read the output-value of the var-parameter.

Objects, Fields and Methods

You can also create objects using TProgramInfo. It's also possible to read and write properties and fields and to call methods.

var
  inf: IInfo;
begin
  inf := Info.Vars['TObject'].Method['Create'].Call;
  inf.Member['field'].Value := 'Hello';
  inf.Method['Free'].Call;

Debugger

If you want to debug a DWSII script program you need a debugger component. A very simple debugger component is part of the DWSII package: Tdws2SimpleDebugger. More useful debugger components are available on the DWS homepage. To enable the debugging mode you have to assign an object that implements the IDebugger interface to TProgram.Debugger. For information about how to use the debugger please read the manual of the debugger component.

Adapter

An adapter is also a component and has to be a descendant of Tdws2Adapter. An adapter is responsible for two different tasks:

Connector

The "naked" DWSII component can't talk to the outer world. You have to add functions to a Tdws2Unit component or to assign an adapter. But you may also want to use COM objects in you DWSII scripts or to call functions of your Delphi program. To connect DWSII to external technologies like COM or RMI the Connector concept was introduced.

A connector is a component that is assigned to the TDelphiWebScriptII component. If the compiler finds an element that belongs to a connector it asks the connector to handle it. The connector returns the "executable code" needed to use this element. The DWSII compiler inserts that "executable code" into the already compiled code not knowing what it exactly does.

At runtime the DWSII code is executed by DWSII and the connector-parts are executed by the responsible connector.