Previous: , Up: Step By Step Procedural Program Execution   [Index]


6.6.1.5 Step By Step Higher Order Function Execution

Executing aime functions step by step when the functions are called via C coded functions (aime available functions, for which the logic is supported by C functions) requires a lot of assistance on the part of the C coded functions.

See Function Pointers.

Regular application introduced functions come in struct x1f4_function_type definitions (and at times, in struct x1f4_linetext_type definitions).

See struct x1f4_function_type.

See struct x1f4_linetext_type.

See Functions.

The logic of the application introduced functions is coded as a C function (of int (*)(void *, void *, void **) signature).

When step by step execution of aime code is envisaged, the (application introduced) C coded functions that execute aime coded functions need to act as filters for the executed functions, to revert control to the interpreter for the execution of the aime code and to pick up their own execution logic from where they interrupted it.

To flag the capacity to execute step by step aime code, functions will include the X1f4_E4_WALK_LINK bit in the flags attribute of their definitions.

See Function Flags.

The C functions implementing the logic of the application introduced (aime) functions that allow aime code step by step execution need to be prepared to execute step by step and in one call.

When executing in one call the C functions will execute their associated logic without further considerations.

When executing step by step, the C functions will make preparations to save their associated logic execution context, revert control to the interpreter and resume executing the associated logic once the control has been returned.

Their second argument will allow the distinction between the two execution modes. When set to x1f4_a1_walk_link, step by step execution is expected, otherwise one call execution is expected and the argument indicates the address at which the logic execution result is to be stored.

The functions third argument for the step by step execution course is a three slots pointer array. The first pointer of it is the address at which the logic execution result is to be stored (would have been the function second argument in the one call execution). The second pointer is the input array (would have been the third argument in the one call execution). The third slot is for the function to write. If the execution of the associated logic has completed, the function will set the third slot to NULL. If the function needs to revert control to the interpreter for the execution of one aime coded function, the function will set the third slot to the address of a struct x1f4_dispatch_type record, describing the aime coded function, its execution context (environment, arguments, output address) and the control returning procedure.

See struct x1f4_dispatch_type.

Once the interpreter has successfully executed the aime coded function, the control is returned to the application introduced function, via the indicated control returning procedure. The procedure describes one function (of int (*)(void *, int, void *, struct x1f4_dispatch_type **) signature) and one pointer control context. The function is passed the control context, the return of the executed supporting function, the address at which the logic execution result is to be stored should the logic execution has completed, and the address of one struct x1f4_dispatch_type record address as arguments, in the indicated order.

If the execution of the (application introduced) function associated logic has completed, the result is to be stored at the indicated address and NULL is to be stored at the address indicated by the third argument. If the execution of another aime coded function is required, the address of a filled struct x1f4_dispatch_type record is to be stored instead.

The interpreter will abort execution if any of the called functions (original logic executor in the struct x1f4_function_type definition or subsequent control returning method) returns a value indicating a non recoverable failure (with zero indicating success).

See Error Classes.

See Limiting The Scope Of Errors.

When a struct x1f4_dispatch_type record is filled, its transfer.input field will indicate the second element in a void * array. The elements starting at transfer.input will describe the input proper of the function to be called, the one element just before transfer.input will be set to the function execution hook required by the procedural interpreter. The hook appears itself just before what would have been the C function input array. Thus, if the C function is defined as:

int
function(void *context, void *output, void **input)
{
    ...
}

the function input proper will be (depending on output) input[1], and the function execution hook the -1 indexed element of it.

    if (output == x1f4_a1_walk_link) {
	struct x1f4_dispatch_type *dispatch_data;
	void **args;

	...

	input[2] = dispatch_data;

	dispatch_data->transfer.input = args + 1;

	*args = ((void **) input[1])[-1];
    } else {
	...
    }

In the above, args + 1 indicates the input proper for the function to be called. The application will set args and dispatch_data properly (not shown here).


Previous: Outside Procedural Interpreter Control, Up: Step By Step Procedural Program Execution   [Index]