|
Our research into object-oriented programming languages in the context of the L1 Project led to the formulation of a new idea known as attribute types [1]. It was shown in a separate note how the bracket routines which can be associated with attribute types can for example be used to implement synchronisation and protection requirements for objects. This is possible because the bracketing code is executed automatically before the code of the explicitly called feature is executed and after it exits. The explicit feature is represented in the bracket code via the statement body. This note extends the idea of bracket routines to allow the bracket code of a second kind of bracket routine, called call brackets, to be automatically executed as an object is about to call another object. In this case the execution of the call to the target object is represented in the bracket code via the statement call. As a simple example an attribute exclusively_synchronised might be programmed as follows: impl es1 for exclusively_synchronised
var sem:semaphore
bracket constr
begin
body
sem:= 1
end
bracket op, enq
begin
P(sem)
body
V(sem)
end
call bracket op, enq
begin
V(sem)
call
P(sem)
end
end es1
| This is a very naive implementation, which simply releases mutual exclusion when another object is called and claims it when the call returns. The synchronisation problems associated with nested monitor calls have been ignored, as the example serves to illustrate the idea of call brackets, not synchronisation techniques! Using Call Brackets for Confinement From the viewpoint of SPEEDOS a much more interesting application of call brackets is to provide a mechanism for implementing a very strict form of confinement, which can be described as "confined to". Suppose that a user does not trust a module such as a spooler, and wishes to ensure that when he calls it, it can call a printer module, but no other module. (This can be expressed in the access rule model as a predicate confined_to (spooler, printer), cf. [2]). Such a confinement requirement can be implemented easily using a call bracket, provided that the Kernel provides information about the destination of a call. First we define an attribute type single_destination: fileattr single_destination
create new
rout
op set_destination (dest: unique_id)
op change_destination (dest: unique_id)
enq destination: unique_id
end single_destination
| This allows a user to define (set_destination) or redefine (change_destination) a single destination to which the attributed module may make calls. The currently permitted destination can be discovered by calling the enquiry destination. Calls to any other modules are rejected, as the following implementation shows. impl single_dest_1 for single_destination
file permitted_destination: unique_id
create new
begin
permitted_destination:= 0
end new
rout
op set_destination (dest: unique_id)
begin
permitted_destination:= dest;
end set_destination
op change_destination (dest: unique_id)
begin
permitted_destination:= dest;
end change_destination
enq destination: unique_id
begin
destination:= permitted_destination
end destination
call bracket ***
begin
if permitted_destination = 0 then
raise (invalid_call)
endif
if (kernel.called_file = permitted_destination) or
(kernel.called_code = permitted_destination) then
call
else
raise (invalid_call)
endif
end call bracket ***
end single_dest_1
| The notation call bracket *** means that calls from all routines of the attributed module are bracketed with this routine. Notice that the Kernel instructions called_file and called_code provide guaranteed information about the destination of the call currently in progress. References [1] Keedy, J. L., Evered, M., Schmolitzky, A. and Menger, G. "Attribute Types and Bracket Implementations", Proceedings of the Conference on Technology of Object-Oriented Languages and Systems, TOOLS 25, Melbourne, Australia 1997, IEEE Computer Society, pp.325-339. [2] Evered, M. and Keedy, J. L. "A Model for Protection in Persistent Object-Oriented Systems", in Security and Persistence, Proceedings of the International Workshop on Computer Architectures to Support Security and Persistence of Information, Springer, 1990.
|