ETSI's Bug Tracker - Part 01: TTCN-3 Core Language
View Issue Details

ID | Project | Category | View Status | Date Submitted | Last Update
0002012 | Part 01: TTCN-3 Core Language | New Feature | public | 18-09-2007 10:53 | 10-12-2009 10:05

Reporter | Gyorgy Rethy |
Assigned To | Gyorgy Rethy |
Priority | high | Severity | feature | Reproducibility | N/A
Status | closed | Resolution | fixed |
Platform |  | OS |  | OS Version |
Product Version |  |
Target Version | v4.1.1 (published 2009-06) | Fixed in Version | v4.1.1 (published 2009-06) |
Clause Reference(s) | new clause(s)
Source (company - Author) | L.M.Ericsson - Gyorgy Rethy

Summary | 0002012: runs on self clause in function reference types

Description

Function References (will) allow(s) calling testcases, functions and altsteps via their references (pointers) using the apply operation. In this case type compatibility is checked, and the type of the reference used in the apply operation shall be compatible with the runs on clause of the entity in which the apply operation is employed.
When writing library functions, some details of the behaviour are use-case dependent and hence the user of the library shall be able to customize it (e.g. send out or wait for a co-ordination message at certain points, while other applications do not need this). This customization can be done by inserting hook points (see the if statement in the function f_LibraryFunctionNow in the example below) into the library functions/altsteps where user defined (so called callback ~) functions are called via reference, if the user stipulates so.
However, the callback function type definition (see CallbackFunctionRefRunsonUserCT below) shall refer to a component type in its runs on clause, which causes a problem. Normally, each library is using its own component type definition, which declares all component constants, variables, timers and ports used by the library (see Library_CT definition in the example below). The user, when writing its own code, shall just extend the library component type(s) with its own constants, variables, timers and ports (see User_CT definition below). Several library component types can be extended simulaneously when defining the user component type. Callback function type definitions shall not use the Library_CT type in their runs on clauses as the user shall be able to use its own declarations within them and they are not defined in Library_CT but in User_CT.
In principle, library functions could also extend a pre-defined (initially empty) user component type however, this is not a solution to the given problem. In this case all user and library components would be forced to run on one single component type throughout the whole test configuration that is very unpractical and resource-consuming; also, libraries have multiple levels (e.g. application libraries that are built on core libraries), where library functions on the higher level shall be able to see the library definitions of the lower library level. Hence, such kind of a turn-about component type extension is not realizable.
In summary, the current runs on compatibility rules of the language do not support using callback functions.
EXAMPLE 1: Using function/altstep references with runs on clauses
module RunsOn_UserCT
{
// THIS MODULE DESCRIBES THE SITUATION TODAY, WITHOUT RUNS ON SELF
type function CallbackFunctionRefRunsonUserCT () runs on User_CT;
type component Library_CT
{
var CallbackFunctionRefRunsonUserCT v_CallbackRef_UserCT := null;
var integer v_Lib;
}
type component User_CT extends Library_CT
{
var integer v_User;
port COORDINATION_PT CP;
}
function f_MyCallbackFunction () runs on User_CT
{/*application/dependent behaviour*/}
function f_LibraryFunctionNow () runs on Library_CT
{
if (v_CallbackRef_UserCT <> null)
{
// Calling the user callback function via reference causes semantic
// ERROR today as the callback function type is using runs on User_CT
v_CallbackRef_UserCT.apply()
}
}// end f_LibraryFunction
function f_MyUserFunctionNow () runs on User_CT
{
v_CallbackRef_UserCT := refers (f_MyCallbackFunction);
f_LibraryFunctionNow();
}//end f_MyUserFunctionNow
} // end of module

Steps To Reproduce |

Additional Information

Proposed solution:
The solution in general is the following: function and altstep type definitions need not specify a concrete component type in their runs on clauses. This is identified by "runs on self" (this syntax uses no new TTCN-3 keyword!). In "normal" cases assignments are checked by inspecting the TYPE of the left and right hand values and their runs on clauses shall be the same or compatible. In the case the type of the left hand value is using "runs on self", the runs on clause of the right hand value's type is checked AGAINST the RUNS ON CLAUSE of the testcase/function/altstep in which the assignment is present.
After this check this reference can safely be used within the given test component to call a function/altstep in any of the functions that is executed on this component (either library or user). No further check is needed at function invocation using the apply operation. See example 2 below.
EXAMPLE 2: Using "runs on self"
module RunsOn_Self
{
// THIS MODULE DESCRIBES THE PROPOSED SOLUTION WITH USING RUNS ON SELF
//=========================================================================
// Function Types
//=========================================================================
// Only function and altstep types may have "runs on self"; nor testcases,
// neither function/altstep/testcase definitions shall have it
type function CallbackFunctionRefRunsonSelf () runs on self;
//=========================================================================
//Component Types
//=========================================================================
type component Library_CT
{
// These declarations are OK
var CallbackFunctionRefRunsonSelf v_CallbackRef_self := null;
var integer v_Lib;
}
type component User_CT extends Library_CT
{
var integer v_User;
}
//=========================================================================
// Functions
//=========================================================================
//-------------------------------------------------------------------------
//EXAMPLE 2: WITH RUNS ON SELF
//-------------------------------------------------------------------------
//----------------------Solution-------------------------------------------
function f_LibraryFunction () runs on Library_CT
{
// Direct call of the callback function still would cause semantic ERROR
f_MyCallbackFunction();
if (v_CallbackRef_self != null)
{
// Calling a function via reference that has a "runs on self" in its header
// is always allowed with the exception of functions/altsteps without runs
// on clause
v_CallbackRef_self.apply();
}
}// end f_LibraryFunction
function f_MyUserFunction () runs on User_CT
{
// This is allowed as f_MyCallbackFunction has runs on clause compatible
// with the runs on clause of this function (f_MyUserFunction)
// The use of function/altstep references with "runs on self" in their
// headers is limited to call them on the given component instance; i.e.
// allowed: assignments, parameterization and activate (the actual function's
// runs on is compared to the runs on of the function in which
// the operation is executed)
// not allowed: start, sending and receiving
// no check is needed for apply!
v_CallbackRef_self := refers (f_MyCallbackFunction);
// This is allowed as Library_CT is a parent of User_CT
// Pls. note, as the function is executing on a User_CT
// instance, it shall never cause a problem of calling
// a callback function with "runs on User_CT" from it.
f_LibraryFunction();
}//end f_MyUserFunctionNow
function f_MyCallbackFunction () runs on User_CT
{/*application/dependent behaviour*/}
} // end of module
However, the function/altstep reference value of a type using "runs on self" shall never leave the test component in which its actual value was assigned. Hence it is NOT allowed to:
- assign it to a function/altstep reference (constant, template, variable, formal parameter) using a concrete component type in the runs on clause of its type definition;
- start a PTC using a function reference with runs on self in its type definition;
- sending and receiving of function/altstep references using runs on self (neither directly nor embedded in structured types).
The detailed rules of using "runs on self" are given in the example below.
EXAMPLE 3: Rules of using "runs on self"
module RunsOn_Self_Rules
{
// THIS MODULE DESCRIBES THE PROPOSED SOLUTION WITH USING RUNS ON SELF
//=========================================================================
// Function Types
//=========================================================================
// Only function and altstep types may have "runs on self"; nor testcases,
// neither function/altstep/testcase definitions shall have it
type function CallbackFunctionRefRunsonLib () runs on Library_CT;
type function CallbackFunctionRefRunsonUser () runs on User_CT;
type function CallbackFunctionRefRunsonSelf () runs on self;
//=========================================================================
//Component Types
//=========================================================================
type component Library_CT
{
// These declarations are OK
var CallbackFunctionRefRunsonSelf v_CallbackRef_self := null;
var CallbackFunctionRefRunsonLib v_CallbackRef_LibCT := null;
var integer v_Lib;
}
type component User_CT extends Library_CT
{
var CallbackFunctionRefRunsonUser v_CallbackRef_UserCT := null;
var integer v_User;
}
//=========================================================================
// Functions
//=========================================================================
//-------------------------------------------------------------------------
//EXAMPLE 2: WITH RUNS ON SELF
//-------------------------------------------------------------------------
//-----------------------Rules of using runs on self-----------------------
function f_Lib() runs on Library_CT
{
log(v_Lib);
}
function f_User() runs on User_CT
{
log(v_Lib);
log(v_User);
}
function f_LibParameterizedwLib (CallbackFunctionRefRunsonLib par_fRef)
runs on Library_CT
{}
function f_LibParameterizedwUser (CallbackFunctionRefRunsonUser par_fRef)
runs on Library_CT
{}
function f_LibParameterizedwSelf (CallbackFunctionRefRunsonSelf par_fRef)
runs on Library_CT
{}
function f_UserParameterizedwLib (CallbackFunctionRefRunsonLib par_fRef)
runs on User_CT
{}
function f_UserParameterizedwUser (CallbackFunctionRefRunsonUser par_fRef)
runs on User_CT
{}
function f_UserParameterizedwSelf (CallbackFunctionRefRunsonSelf par_fRef)
runs on User_CT
{}
function f_LibraryFunction2() runs on Library_CT
{
var Library_CT vl_PTC_LibCT := Library_CT.create;
// --------ASSIGNMENTS AND FUNCTION CALLS--------
// allowed by definition
f_Lib();
// allowed because of the previous
v_CallbackRef_self := refers(f_Lib);
// allowed by definition
v_CallbackRef_LibCT := refers(f_Lib);
// semantic ERROR: NOT ALLOWED because it may refer to non-existent objects
f_User();
// NOT ALLOWED because of the previous!!!
// One of the most important points of the proposal
v_CallbackRef_self := refers(f_User);
// NOT ALLOWED because it refers to non-existent v_User
v_CallbackRef_LibCT := refers(f_User);
// allowed by definition (even if it actually points to f_User)
v_CallbackRef_self.apply();
// allowed by definition
v_CallbackRef_LibCT.apply();
// allowed because of the previous
v_CallbackRef_self := v_CallbackRef_LibCT;
// NOT ALLOWED because v_CallbackRef_LibCT can be exported from this
// component !!!
v_CallbackRef_LibCT := v_CallbackRef_self;
// --------COMPONENT HANDLING--------
// allowed by definition
vl_PTC_LibCT.start(f_Lib());
// allowed by definition
vl_PTC_LibCT.start(derefers(v_CallbackRef_LibCT)());
// NOT ALLOWED because f_User() refers to User_CT
vl_PTC_LibCT.start(f_User());
// NOT ALLOWED by definition
// Another cardinal point of the proposal
vl_PTC_LibCT.start(derefers(v_CallbackRef_self)());
// --------PARAMETERIZATION--------
// This is obviously OK as both the variable and the parameter type has
// the same type (using runs on Library_CT)
f_LibParameterizedwLib(v_CallbackRef_LibCT);
// NOT ALLOWED as the parameter (of the type CallbackFunctionRefRunsonLib!)
// can be exported from the component within f_LibParameterizedwLib
f_LibParameterizedwLib(v_CallbackRef_self);
// This is OK for the same reason as the assignment <v_CallbackRef_self :=
// v_CallbackRef_LibCT;> is allowed; note, use of the parameter is restricted
// within the function f_LibParameterizedwSelf;
f_LibParameterizedwSelf(v_CallbackRef_LibCT);
// This is obviously OK as both the variable and the parameter type has
// the same type (using runs on self)
f_LibParameterizedwSelf(v_CallbackRef_self);
// Makes no sense as no definition with runs on User_CT is known during
// writing library functions
f_LibParameterizedwUser(/*...*/)
}
function f_UserFunction() runs on User_CT
{
var User_CT vl_PTC_UserCT := User_CT.create;
// --------ASSIGNMENTS AND FUNCTION CALLS--------
// allowed because of compatibility
f_Lib();
// allowed because of the previous
v_CallbackRef_self := refers(f_Lib);
// allowed by definition
v_CallbackRef_LibCT := refers(f_Lib);
// allowed by definition
v_CallbackRef_UserCT := refers(f_User);
// allowed by definition
f_User();
// allowed because of the previous
v_CallbackRef_self := refers(f_User);
// NOT ALLOWED because f_User() refers to User_CT and v_CallbackRef_LibCT's
// type refers to its parent, Library_CT
// Pls. note that v_CallbackRef_LibCT can be e.g. started on a PTC of the
// type Library_CT
v_CallbackRef_LibCT := refers(f_User);
// allowed by definition
v_CallbackRef_self.apply();
// allowed because of the previous
v_CallbackRef_self := v_CallbackRef_UserCT;
// allowed because of compatibility
v_CallbackRef_LibCT.apply();
// allowed because of the previous
v_CallbackRef_self := v_CallbackRef_LibCT;
// NOT ALLOWED because v_CallbackRef_self can refer to a function with
// runs on User_CT and v_CallbackRef_LibCT can be exported from this
// component
v_CallbackRef_LibCT := v_CallbackRef_self;
// --------COMPONENT HANDLING--------
// allowed because of compatibility
vl_PTC_UserCT.start(f_Lib());
// allowed by definition
vl_PTC_UserCT.start(f_User());
// NOT ALLOWED by definition
vl_PTC_UserCT.start(derefers(v_CallbackRef_self)());
// allowed because of compatibility
vl_PTC_UserCT.start(derefers(v_CallbackRef_LibCT)());
// --------PARAMETERIZATION--------
// This is obviously OK as both the variable and the parameter type has
// the same type (using runs on Library_CT)
f_UserParameterizedwLib(v_CallbackRef_LibCT);
// NOT ALLOWED as the parameter (of the type CallbackFunctionRefRunsonLib!)
// can be exported from the component within f_UserParameterizedwLib
f_UserParameterizedwLib(v_CallbackRef_self);
// This is OK for the same reason as the assignment <v_CallbackRef_self :=
// v_CallbackRef_UserCT;> is allowed; note, use of the parameter is
// restricted within the function f_UserParameterizedwSelf;
f_UserParameterizedwSelf(v_CallbackRef_UserCT);
// This is obviously OK as both the variable and the parameter type has
// the same type (using runs on self)
f_UserParameterizedwSelf(v_CallbackRef_self);
// NOT ALLOWED as the parameter (of the type CallbackFunctionRefRunsonUser!)
// can be exported from the component within f_UserParameterizedwLib
f_UserParameterizedwUser(v_CallbackRef_self)
}
function f_MyFunctionNoRunson()
{
var Library_CT vl_PTC_LibCT := Library_CT.create;
var User_CT vl_PTC_UserCT := User_CT.create;
// --------ASSIGNMENTS AND FUNCTION CALLS--------
// allowed because of compatibility
vl_PTC_LibCT := vl_PTC_UserCT;
// NOT ALLOWED
vl_PTC_UserCT := vl_PTC_LibCT;
// allowed
var CallbackFunctionRefRunsonSelf vl_CallbackRef_self :=
refers(f_MyFunctionNoRunson);
// --------COMPONENT HANDLING--------
// No new case above those shown above
// --------PARAMETERIZATION--------
// Makes sense only in case of function/altstep references without runs on
// clause that is out of scope of these examples
}
} // end of module

Tags | No tags attached.

Relationships

related to | 0000412 | closed | Tibor CsÃ¶ndes | Function reference

Attached Files | CR_Exx runs on self.doc (150,016) 18-09-2007 10:53 http://oldforge.etsi.org/mantis/file_download.php?file_id=983&type=bug

Issue History
Date Modified | Username | Field | Change
18-09-2007 10:53 | Gyorgy Rethy | New Issue |
18-09-2007 10:53 | Gyorgy Rethy | Status | new => assigned
18-09-2007 10:53 | Gyorgy Rethy | Assigned To | => Gyorgy Rethy
18-09-2007 10:53 | Gyorgy Rethy | File Added: CR_Exx runs on self.doc |
18-09-2007 10:53 | Gyorgy Rethy | Clause Reference(s) | => new clause(s)
18-09-2007 10:53 | Gyorgy Rethy | Source (company - Author) | => L.M.Ericsson - Gyorgy Rethy
19-09-2007 11:31 | Gyorgy Rethy | Severity | major => feature
19-09-2007 11:31 | Gyorgy Rethy | Summary | runs on self clause of function reefrrnce types => runs on self clause in function reference types
13-10-2007 18:54 | Ina Schieferdecker | Assigned To | Gyorgy Rethy => Ina Schieferdecker
13-10-2007 18:54 | Ina Schieferdecker | Assigned To | Ina Schieferdecker => developer_u
17-10-2007 11:22 | Ina Schieferdecker | Note Added: 0003656 |
17-10-2007 12:42 | user10 | Assigned To | developer_u => Thomas DeiÃŸ
18-10-2007 13:43 | Ina Schieferdecker | Project | TTCN-3 Change Requests => Part 01: TTCN-3 Core Language
18-10-2007 13:43 | Ina Schieferdecker | Target Version | => Edition 4.1.1 (not yet published)
17-10-2008 15:38 | Ina Schieferdecker | Relationship added | related to 0000412
12-12-2008 09:50 | Thomas DeiÃŸ | Note Added: 0007674 |
12-12-2008 09:50 | Thomas DeiÃŸ | Assigned To | Thomas DeiÃŸ => Gyorgy Rethy
10-03-2009 10:49 | Ina Schieferdecker | Status | assigned => resolved
10-03-2009 10:49 | Ina Schieferdecker | Resolution | open => fixed
10-03-2009 10:49 | Ina Schieferdecker | Fixed in Version | => Edition 4.1.1 (not yet published)
10-12-2009 10:05 | Gyorgy Rethy | Status | resolved => closed
10-12-2009 10:05 | Gyorgy Rethy | Note Added: 0009133 |

Notes

(0003656)
Ina Schieferdecker
17-10-2007 11:22

To be considered together with CR 412 and also deferred to 2008

(0007674)
Thomas DeiÃŸ
12-12-2008 09:50

solution included in the one for CR412

(0009133)
Gyorgy Rethy
10-12-2009 10:05

Included into the Behaviour Types package, ES 202 785 V1.1.1