Previous: Outside Procedural Interpreter Control, Up: Step By Step Procedural Program Execution [Index]
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).