Inter-Office MemorandumToCedar UsersDateFebruary 15, 1982FromEd Satterthwaite and Jim DonahueLocationPalo AltoSubjectCedar 7T11 Language and Compiler ChangesOrganizationCSLXEROX Filed on: [Indigo]Doc>Cedar7T11.BravoDRAFTThe document [Indigo]Lang>Cedar6T5.press describes the Cedar language. This memosummarizes the significant changes to the language and compiler since that document was prepared.Types in CedarThis section sketches some current thinking about the Cedar type system and might help you tounderstand the motivation for some of the changes described below. (See also Lampson, Cedarabstract machine [CedarAM.memo, February 1980].)Types as PredicatesEvery type is characterized by some predicate; a value x has type T iff x satisfies the predicate forT. In general, such predicates are defined in terms of a set of marks (tags, etc.) carried by eachvalue; however, the Mesa type system is designed so that most mark manipulation can be donestatically (by the compiler), and the usual representations of most values do not include explicitmarks.A given expression has some fixed syntactic type that depends upon the form of the expression andthe declared types of constituent identifiers. The value denoted by an expression always satisfies thepredicate characterizing its syntactic type, but such a value will often satisfy predicates characterizingother types as well. In this sense, a Cedar value may have an arbitrary number of types. Forexample:If Thing is a variant record type with a variant red, a reference to a Thing might simultaneouslysatisfy the predicates for REF ANY, REF Thing, and REF Thing[red] (formerly REF red Thing, seebelow).An opaque type and the corresponding concrete type are distinct, even within an exporter of theconcrete type, but the predicates for the two types are identical.Roughly speaking, the primary job of the predicates associated with types is to provide correctanswers to questions about low-level representational conventions so that, e.g., the Cedar garbagecollector can operate correctly.The form ISTYPE[x, T] returns the result of applying the predicate characterizing T to the value x.In Cedar 7T11, ISTYPE has been redefined to work in a somewhat more general and uniform way,and the operations of NARROWing and (type-based) SELECTion have been defined in terms of ISTYPE.]gpi c8q]rX -q7Br ]q]r-q7Br Yq]r(-q 7BrSsr MqF0?u Gr= Et%< ARvX >rG <\"5w :r 5wX 2pr -wr wrwr 0wr"@ /!$7 -zE + ("w r1 &!F %5j #> ! kwr)wrwr qrqrwrqrwrwr qrwrwr  [ B (7 H ] qrwrwr>wr wr gqr) qrqrqr > y>^3Cedar 7T11 Changes2Types as Clusters of OperationsIn addition to its predicate, a cluster of operations (sometimes called a group) can be associated witha type. The main purposes of this grouping are to provide a number of packaging conveniencesand to support so-called "object oriented" notation. If x has (syntactic) type T, x.Op[args] meansOp[x, args] where Op is found by looking in the cluster associated with T. Two types may becharacterized by the same predicate but have different associated clusters; in current Cedar, this istrue of, e.g., an opaque type and the corresponding concrete type.Each of the type constructors in Cedar supplies a standard and implicitly defined cluster for eachtype that it constructs. The only mechanism currently available for the explicit construction of sucha cluster is the interface module, and previous versions of Cedar have limited support of thismechanism to opaque types. If T is an opaque type declared by, e.g., T: TYPE;in some interface Defs, operations (procedures) declared in Defs become components of the clusterassociated with T and may be invoked using object notation. Cedar 7T11 extends this support toallow construction of similar clusters for record types. If T is declared in Defs by T: TYPE = RECORD [ ... ];the operations declared in Defs become part of the cluster associated with T. In this case, however,they augment the operations already supplied for T by the RECORD type constructor.Defining clusters in this way has some drawbacks. The use of interfaces as the units of groupingsomewhat overloads the existing notion of an interface; note that all operations declared in aninterface become parts of the clusters of all types declared in that interface. Also, requiring a typeand the operations in its cluster to be defined in the same interface occasionally conflicts with othercriteria for partitioning interfaces. On the other hand, this method of defining clusters seems tocover the important cases well enough to be acceptable in practice. In addition, there is a fairlywell worked-out plan for supporting clusters in a comprehensive, uniform way and for using themto explain parts of the Cedar abstract machine. We therefore recommend the following styleguidelines for your Cedar programming:Partition interfaces so that a single interface defines both a main type T (record or opaque) andall the operations to be provided in the cluster of T (or REF T). Define multiple main typeswithin an interface only if the sets of meaningful operation names for those types are disjoint.Use object notation in clients of interfaces designed to support it; i.e., use x.Op[args] inpreference to Defs.Op[x, args].(For Humus veterans) Avoid interface designs that require clients to write x.Op[x, args],x.ops.Op[x, args] or the like. Use an inline definition of Op within Defs to achieve such aneffect. LANGUAGE CHANGESSyntax for Discriminated TypesIf V is a type expression designating some variant record type with variant a, V[a] is a typeexpression designating the discriminated type. Thus forms such asObject[red] Object[red][short] Object[red][long][80]are equivalent to the old formsred Object short red Object long red Object[80].In Cedar 7T11, both forms are acceptable. fvG bwX ^rwr#wr ]( Q [5wrwrwrwrwr Ywrwrwrwrwr X2U VB S<Y Qa O&8 NFwr% Lwrqr Jwr&wr! IPwrN G=wrwr Fwrqrqr DZwrwr B1wrqr ?dD =7( <-: :n\ 8>% 76- 5xT 3&5 2)& /Iwr .3wrqrwr ,_` )Jwrwrwr (= wrwrwrwr %7wrwrwrwr $wrwrwrwrwr,wrwr  "s QvX / rwrHwrwrwr 9A wrwrXwrwrwrwrwrwrwr  CwrXwrwrwrwrwrwrwrwr ) T=YCedar 7T11 Changes3Dynamically Typed ProceduresCedar 7T11 provides dynamically typed procedures as well as dynamically typed references. If Uand V are (possibly empty) field lists, then the type PROC [U] RETURNS [V] conforms to any of thefollowing types:PROC ANY RETURNS ANYPROC [U] RETURNS ANYPROC ANY RETURNS [V]Furthermore, the last two types also conform to the first. Similar types are available for declarationand manipulation of dynamically typed signals or errors.In all three cases, the corresponding values are dynamically typed, and you must narrow ordisciminate such a value before using it to invoke any kind of transfer operation. The formsavailable for doing this exactly parallel the forms available for REF ANY discrimination and aredescribed in the next section. Note, however, that discrimination of procedure values is significantly moreexpensive than discrimination of reference values as implemented in 7T11.Type DiscriminationCedar 7T11 unifies the mechanisms for discriminating variant records with those for discriminatingvalues with types REF ANY, PROC [U] RETURNS ANY, PROC ANY RETURNS [V], or PROC ANY RETURNSANY. This unification affects the operators ISTYPE and NARROW as well as discriminating selection.Type TestingThe primitive function ISTYPE tests whether a given value satisfies the predicate characterizing aspecified type. You will probably have little direct use for ISTYPE; its importance lies in its use todefine other, more common operations as described below. Let x be an expression with syntactictype S. In Cedar 7T11, the value of ISTYPE[x, T] is determined as follows, where V is any variantrecord type:(1) It is TRUE (at compile time) ifS and T are equivalent types; orS is an opaque type and T is the corresponding concrete type; orS is a concrete type exported as the opaque type T.The last two cases are recognized only within program modules that export the concrete type.(2) It is determined dynamically by a test of the value x, yielding TRUE or FALSE, ifS is REF ANY and T is REF U for any U except ANY; orS is PROC ANY RETURNS ANY, PROC ANY RETURNS [U] or PROC [V] RETURNS ANY and T is PROC[U] RETURNS [V] for any U and V except ANY; orS is equivalent to V and T is equivalent to V[a]; orS is equivalent to REF V and T is equivalent to REF V[a]; orS is equivalent to (LONG) POINTER TO V and T is equivalent to (LONG) POINTER TO V[a];where V[a] is a particular variant of V, perhaps discriminated to several levels. Note that the resultis TRUE if the value of x is NIL. fvG bX ^rMw ](rwrqrwrqrwr [ X2qrXqrqrq Vrwrqrq Trqrqrwr QW O8 LT JK IP"qr Gt9 F$I B%vX >rL =/qrqrwrqrwrqrq ;rqrqr% 6wX 3Crqr& 1.qr# /8wr .Mwrqrwrwr"wr , )WX qrM&wrwrM%5wrwr'M#wr0wrM!6tF\  rX8wr qrqrMwrqFrXwrqrwrwrqrMwrqFrXqF rXwrqFrXqrwrqF rXwrqMmrwrqFrwrXwrwrqrMwrwrwrwrwrMKwrqrwrwrqrwrwrMwrqFrXwrwrqF rXwrwr )wrwrwr@ qrwrqr :=ZCedar 7T11 Changes4(3) In all other cases, ISTYPE is unimplemented and is treated as a compile-time error.Note that ISTYPE cannot currently be used to test a value for membership in a subrange.NarrowingNARROW[x, T] allows a value x to be viewed as a value of type T and succeeds iff ISTYPE[x, T] isTRUE. More precisely, NARROW[x, T] has (syntactic) type T, and its value is given byIF ISTYPE[x, T] THEN x ELSE ERROR where isRTTypesBasic.NarrowRefFault[x, CODE[T]]if ISTYPE[x, REF ANY]RTTypesBasic.NarrowFault[]otherwise.The following situations correspond to the three cases enumerated in the definition of ISTYPE above:(1) NARROW[x, T] is guaranteed (at compile time) to succeed.(2) NARROW[x, T] may succeed or fail at run time.(3) NARROW[x, T] is unimplemented.Case (2) arises only when the syntactic type of x is related to T in one of the ways described abovefor ISTYPE. In Cedar 7T11, case (3) is treated as a compile-time type error. Fine point: NARROW[x, T]is also considered a compile-time error if the only possible value of x yielding TRUE is NIL. Use x = NIL instead.In case (1), NARROW is an identity operation but can be useful to change the (syntactic) type of xwithout using a LOOPHOLE or requiring any code to be executed. Example:Defs: DEFINITIONS = { T: TYPE; R: TYPE = RECORD [g: REF T, ... ]; Pn: PROC [r: REF R]; ... }.Impl: PROGRAM EXPORTS Defs = { T: PUBLIC TYPE = RECORD [n: NAT, ...]; Pn: PUBLIC PROC [r: REF Defs.R] = { r.g.n _ 0; -- invalid; r.g^ is opaque, with no field selection operations NARROW[r.g, REF T].n _ 0;-- valid (because Impl exports Defs) ...}; }.As before, NARROW[x, T] may be written as NARROW[x] when the target type T is implied bycontext.Discriminating SelectionThe syntactic form of WITH ... SELECT that is currently used for REF ANY discrimination has beenextended to discriminate any value for which ISTYPE performs a dynamic test of that value (see case(2) in the discussion of ISTYPE). The form fvG brXqr9 ^ qr3 Yw Vqrwrwrwrwrqrwrwr Tqrqrwrwrwr RhqFrwrXwrqrwrqFrX O Mrw rw rwrqrwr'qrwrqFr Kw rw r' H|#4qr FXqrwrwr- DZqrwrwr" Bqrwrwr @7wrwr# >qrEt qtxtxt = .xt qtqtxtqt 9r qrJw 89rqr0 5wrXq r 4wrqr 2pwrqrqrwrqrwr 0wrqrwrqrwr /! ,wrqFrXwr *wrqF rXqrwrqr )WwrqF rXwrqrwr 'wrwrwr wrwr/ & qrwrwrqrwrwr wrwr $a " k qrwrwrqrwrwr  wX rqrqr qr0 1qr  =V!Cedar 7T11 Changes5WITH v SELECT FROM v1: T1 => s1; v2: T2 => s2; ... vn: Tn => sn; ENDCASE => se;is, by definition, equivalent tou: T = v;IF u # NIL AND ISTYPE[u, T1] THEN {v1: T1 _ NARROW[u]; s1}ELSE IF u # NIL AND ISTYPE[u, T2] THEN {v2: T2 _ NARROW[u]; s2} ...ELSE IF u # NIL AND ISTYPE[u, Tn] THEN {vn: Tn _ NARROW[u]; sn}ELSE se;where T is the (syntactic) type of v. The tests against NIL are omitted if T does not have a NILvalue.Note that this form always copies the discriminated value. Thusr: REF V;. . .WITH r SELECT FROM x: REF V[a] => { ... x ...};-- x is a copy of r with type REF V[a] ... ENDCASE;WITH r^ SELECT FROM x: V[a] => { ... x ...};-- x is a copy of r^ with type V[a] ... ENDCASE;Contrast these with the old form of variant record discrimination, which does not copy thediscriminated value and reevaluates the discriminating expression each time that it is used:WITH x: r SELECT FROM a => { ... x ... };-- x is a synonym for r^ (but with syntactic type V[a]) ... ENDCASE;The new forms are easier to make type-safe, and you should use them whenever possible.Unfortunately, the old form is still required, at least outside the checked language, for dealing with computed variantsand with pointers having non-standard dereferencing operations, such as the current relative pointers).Interaction with Opaque TypesIf T is any exported type, REF T must have the "standard" implementation of type discrimination.We impose this requirement in anticipation of making REF ANY discrimination work correctly withopaque types (it still doesn't in 7T11). As a consequence, discriminated variant record types cannotbe exported as the concrete values of opaque types. fvG bqrXwrqF `rXwrwrwr _wrwrwr ]q \rwrwrwr Zqrwr W; TwrXwrwr S_qFwrXqF wrXwrqrwrwrqrwrwr QqFwrXqF wrXwrqrwrwrqrwrwr PWq NFwrXqF wrXwrqrwrwrqrwrwr MOqFwr Jwrwrqrwrq I-r E@ CwrXqrwr ARqF ?rXwrqF =rXwrqrwrwr wrwr wr qrwrwr <q :rqr 89qrwrqF 6rXwrwrwr wrwr wr wr 51q 3rqr 0_2( .\ ,SCedar 7T11 Changes6Object NotationThe form x.Op[args] is interpreted as Defs.Op[x, args] if the type of x is (REF | POINTER TO)* Tfor some opaque type T declared in an interface, the principal instance of which is Defs. In otherwords, all the operations defined in Defs become part of the cluster of the type T.This convention applies within the corresponding DEFINITIONS module (for writing inlines, etc.) aswell as within importers of such modules. This is only a notational extension; the bindings ofimplicitly imported values are determined as before.The clustering mechanism has also been extended in Cedar so that all operations declared in aninterface become components of the clusters of any record types defined in that interface. With thisextension, Op can be inline in more interesting ways. In addition, you may now be able to useobject notation more extensively to invoke operations in existing interfaces, many of which arewritten in terms of (concrete) record types.Note that every operation declared in an interface module becomes part of the cluster of every(record or opaque) type declared in that interface. Although the type of a particular operationnormally will make it a useful component of only one cluster, its name appears in every othercluster and potentially hides or precludes a more appropriate definition of that name for thatcluster. You therefore should define more than one main type per interface only if the sets ofmeaningful operation names for those types are disjoint.Other points to note when using this convention with record types include the following:In determining the binding of Op, the field identifiers declared in T take precedence over theidentifiers declared in the interface Defs.A value x with a record type T having a single component can be coerced to a value with thetype of that component. In the form x.id, the lookup of id considers first the field identifier ofthe single component, then identifiers declared in the interface defining T, and finally anyinterpretation given to id by applying the coercion. You abuse this feature at your own risk(but see the discussion of clusters above). Example:Defs1: DEFINITIONS = { ... T1: TYPE = RECORD [f1: REF Defs2.T2]; ... OpN: PROC [self: T1, ...]; ...}.Defs2: DEFINITIONS = { ... T2: TYPE = RECORD [ ... ]; ... OpM: PROC [self: REF T2, ...]; OpN: PROC [self: REF T2, ...]; ...} r1: Defs1.T1; r2: REF Defs2.T2; ... r1.OpN[...] means Defs1.OpN[r1, ...]-- from the cluster defined by Defs1 ... r1.OpM[...] means Defs2.OpM[r1.f1, ...]-- from the cluster defined by Defs2 (after coercion) ... r2.OpN[...] means Defs2.OpN[r2, ...] ... r1.f1.OpN[...] means Defs2.OpN[r1.f1, ...]-- dubious style fvG bX ^r wrwrwrwrwrwrwrwrqrq rw ](rwr(wr [%wr(w X2r1q r& VG T4 QB O.7 NF wr> LP J, GE FH` DQ C@1- A8' @78 = X 9 wr$wr 8]&wr 51wrwr- 3%wrwrwr( 2) @wr 0wr@ /!5 +wrXq r *r (wrqrqrwrqrwrwr 'i %wrqrwrwr $a !Ywrq r  Qwrqrqr  Iwrqrwrqrwr wrqrwrqrwr A 9wrwrwr wrqrwrwr wrwr wrwrwr){w )rwrwr wrwrwrwr){wr wrwr wrwrwr wrwrwr wrwrwrwr){ =\2Cedar 7T11 Changes7Predeclared TypesTo support the currently recommended Cedar standards, the types BOOL, INT and CHAR arepredeclared, with the following definitions: BOOL: TYPE = BOOLEAN; CHAR: TYPE = CHARACTER; INT: TYPE = LONG INTEGER;Also, the definition of the predeclared type CONDITION has been changed. The default value forthe timeout interval now is effectively infinite; i.e., a WAIT on a condition variable with defaultinitialization will never time out. (The previous default provided a timeout after 100 ticks.) Use aruntime procedure such as Process.SetTimeout to change the default setting.Numeric Types and ConversionsCedar 7T11 provides automatic conversion from types LONG INTEGER and LONG CARDINAL totypes INTEGER, CARDINAL and any subranges thereof. If you request bounds checking, any lossof information in such a conversion causes the signal Runtime.BoundsFault to be raised.In addition, you may use types such as INT that are equivalent to LONG INTEGER or LONGCARDINAL to define subrange types; however, any subrange type T must satisfy the constraintsthat-215 < FIRST[T] < 215 and |LAST[T] - FIRST[T]| < 216-1.Furthermore, any numeric index type used to define an array or sequence type must satisfy thesame constraints.Rope LiteralsThe Cedar language now provides rope literals. Such a literal is denoted by a quoted string, e.g.,"This is a rope literal". Its value is a reference to a rope object in the standard (counted) zoneprovided by the Cedar system.The target type established by the context in which a quoted string literal appears determines theinterpretation of that literal. There are three cases:If the target type is Rope.ROPE, Rope.Ref or Rope.Text, the quoted string denotes a rope literaland has type Rope.Ref.If the target type is any other REF type, the literal has type REF TEXT.Otherwise, the literal has type STRING.In the first case, the test is actually for equivalence between the target type and either REF Rope.RopeRep or REFRope.TextRep. The matching is performed on the names of the interface (Rope) and referent type (RopeRep or TextRep),not on the structure of the referent type. Since this is a loophole in the type checking, use nonstandard versions of theRope interface very cautiously. fvG bX ^r*wrwrwr ]n, ZCXwrqrwr Xwrqrwr W;wrqrqrwr Twr) R:qr% QM Owrw r KavX Hr-qrwrqrwr FkwrwrE D6xw r Au'wrqrwrq ?wr5wr >& ;<8t;rXyrqrwr<8t;rqrwrqryr<8t;r 8]L 6 2vX /Dr$? -6- + (S '7 $wrwrwrwrwrwr* " wrwr bXqrqFr Xqr t[qtxtxtq [xtxtxtxtxt Z xt w=QfCedar 7T11 Changes8Escape Convention for LiteralsCedar provides an escape convention to allow denotations of nonprinting characters in character andstring literals (cf. the escape convention for the language C). The escape character is \, and thefollowing codes are recognized: Code Interpretation\n, \N, \r, \RAscii.CR\t, \TAscii.TAB\b, \BAscii.BS\f, \FAscii.FF\l, \LAscii.LF-- note that \n = LF in C\ddddddC-- where d is an octal digit, ddd < 377B\\\\''\""Anything else following a \ is an error.You can use the escape convention in character literals (e.g., '\n or '\032) or string literals (e.g.,"abc\ndef").APPLY and RETURNCedar is based upon a model of interprocedural control transfer in which the construction of anargument record is clearly separated from the actual transfer of control. In the usual forms forspecifying call or return, however, these operations are syntactically indivisible. There are nowalternative syntactic forms that allow you to invoke transfer operations using already constructedargument records.This extension is not fully general. The existing record must have a type compatible with the type required by thetransfer operation, and the only types compatible with argument record types are other argument record types. Suchtypes are defined implicitly by the definitions of transfer types, and they are always anonymous. Thus you cannotdeclare variables having such types, nor can you construct values with such types unless the target type is established bya transfer operation of some sort. The operator APPLY is used to apply a value with some transfer type to an argument record. Thesyntactic form isCall ::=...|APPLY [ Expression , Expression ]|APPLY [ Expression , Expression ! CatchSeries ]The type of the first Expression must be some transfer type (i.e., a type built using PROC, SIGNAL,ERROR, PROCESS, PORT or PROGRAM), and the second Expression must have a record type asgood as the argument type required for the transfer (see below). The effect is to invoke the transferoperation appropriate to the type of the first Expression, i.e., to call a procedure, raise a signal,join a process, etc. The scope of the optional catch phrase is just the transfer itself.Note that the first Expression implies a target type for the second, which can be (but normallywould not be) a constructor. For example,p[x, y]can be written asAPPLY[p, [x, y]]q[x]can be written asAPPLY[q, [x]] -- not APPLY[q, x]The corresponding forms for returning an existing record are fvG bX ^rR ]nX [ YoXY#YoY5Yo V wrw UMr wrw Sr wrw Qr wrw PWr wrw.r Nw wr.wrwryr M r Ka r I r Gb( E .8 C ?dzvXz <8rA :O 90)9 7&< 6( 3 tE. 1F- 0b /hz .*# +"r qr4 ) '#{rX %| qr{ r{ r# qr{ r{ r{ r { rqrqr %qrqrqrqr{ r  [ /{ r" Y m{ r0 * nwrwrXwr qrwrwrwr wrwr qrwrwr.qrwrwr < T=YCedar 7T11 Changes9ReturnStmt ::=...|RETURN Call|RETURN ( Expression )ResumeStmt ::=...|RESUME Call|RESUME ( Expression )In these forms, the required type is established by the context in which the statement appears. Thetype of the Call or Expression must be a record type as good as the result type of the procedurebody in which the ReturnStmt appears (or of the catch phrase in which the ResumeStmtappears).An argument record type T1 is as good as an argument record type T2 if both of the followingconditions are satisfied:T1 and T2 have the same number of fields, say n.For each i, 1 < i < n, the type of the i-th component of T1 is as good as the type of the i-thcomponent of T2; in addition, if both these components are named, the names are identical (i.e.,names of field selectors must match, but an anonymous component matches any namedcomponent). Note that this rule is more liberal than the rule for explicitly declared record types.In the terminology of the Mesa 5 manual, T1 is as good as T2 iff T1 conforms freely to T2; e.g., [0..10) is as good as[0..100). In the new view of types, we would say that T1 is as good as T2 iff the predicate for T1 implies the predicatefor T2.In Cedar 7T11, the constructs described above do not work for empty argument records; i.e., you cannot nest applicationsof procedures taking/returning nothing.Examples:P1: PROC [x, y: INT] RETURNS [m, n: INT] = {...};P2: PROC [m, n: INT] RETURNS [u, v: INT] = {...};P3: PROC [a, b: INT] RETURNS [u, v: INT] = { RETURN APPLY[P2, P1[a, b]]};i, j: INT;. . .[i, j] _ APPLY[P2, IF i < j THEN P1[i, j] ELSE [j, i]];[i, j] _ APPLY[P3, [0, 0] ! s => {GOTO L}]; -- [i, j] _ P3[0, 0 ! s => {GOTO L}]Safe Subset CheckingThe Cedar 6T5 document defines a "safe subset" of Cedar in which even incorrect programs cannotinterfere with the reliable operation of the garbage collector. To quote from Cedar 6T5,"We intend that the vast majority of programs will be written primarily in the safesubset. However, we recognize that is it not presently feasible to provideacceptably efficient substitutes for all uses of Mesa's unsafe features. Instead, wewill provide textual means for indicating that some regions of a program areunchecked. This will inhibit compiler enforcement of the safety restrictions andsimultaneously indicate that the programmer has assumed the additionalresponsibility of ensuring that these regions of the program cannot violate theintegrity of the system." fvG b{ rX `v qr{^r qr{ r \T{ r Z qr{Yr qr{ r UU TV {r{ rB R{ r{ QNr N# wMtN#r'wMtN#r LX IwIPtIrXwIPtIr%wr GwryrwryrwrwrwFtGrwr E wE.tEr2 C$- BI ?W =t)x=/t= x=/t=x=/t=x=/t= <7x;t< x;t<x;t< :nx9t:n 8]U# 7' 4w 1rXqrwrwrwrqrwrwrwr /!wrqrwrwrwrqrwrwrwr ,wrqrwrwrwrqrwrwrwr *qrqrwrwrwrwr (wrwrqr & %5wrwrqrqrwrwrqrwrwrwrqrwrwr #wrwrqrwr wrqrwr.wrwrwrwrqrwr kv rX uY'SKH 1.wr7j/k ;-"  L=\Cedar 7T11 Changes10In Cedar 7T11, operations are classified as SAFE or UNSAFE. The precise description of SAFEoperations is given below. A region of program text, bracketed to form a block, may be prefixedwith one of the keywords CHECKED, TRUSTED or UNCHECKED. If a block is CHECKED, then withinthat block only safe operations may be used, and the block itself implements a SAFE operation. If itis UNCHECKED, unsafe operations may be used internally, and the block itself is considered UNSAFE.A TRUSTED block may also invoke unsafe operations, but it is assumed to present an externalinterface that is SAFE. Thus TRUSTED is an assertion by the programmer that a region using unsafeoperations nevertheless preserves the Cedar system invariants as described in Cedar 6T5. Such anassertion cannot be checked by the compiler, and TRUSTED is a restricted form of LOOPHOLE.Safe OperationsAn operation is safe if it is guaranteed not to produce a result that would allow violation of theintegrity of the system, including the code and the various data structures maintained by the presentruntime system. In particular, the type integrity of the system must be preserved; in the presenceof a garbage collector, this means that all operations that reference storage through paths unknownto the garbage collector must be regarded as potentially unsafe. Thus, the following primitive Cedaroperations are not allowed to appear in CHECKED regions:@ and the functions DESCRIPTOR and BASE that manipulate array descriptors,^ or FREE applied to a value of type POINTER or LONG POINTER, and all pointer arithmetic,variant discrimination that does not copy the discriminated value or a reference to it (see above),JOIN or port call.In addition, any use of LOOPHOLE to produce a value with an RC type is prohibited. Finally,assignment is restricted within CHECKED regions by:restricting the type UNSPECIFIED to conform only to itself so that, e.g., you cannot assign a valueof type UNSPECIFIED to any variable of type other than UNSPECIFIED,prohibiting assignment of locally declared procedures to any procedure variable and prohibitingpassing such procedures as arguments in FORKed calls (thus guaranteeing that procedure valuescannot contain references to frames that may have been reclaimed).prohibiting assignments that change the tags of variant records.The transfer types of Cedar have been extended to allow the programmer to specify that aparticular procedure or signal or process or program is SAFE or UNSAFE; inside CHECKED regionsonly transfer values with SAFE types can be used. Moreover, the bodies that are associated withSAFE procedures, processes or signals must themselves be safe. There are two ways to achieve this:one is to declare the body (either in the declaration of a procedure or the catch phrase for a signal)to be CHECKED, thus guaranteeing that the compiler will enforce the necessary safety; the other is todeclare the body to be TRUSTED, in which case the body is UNCHECKED and the programmer takesupon himself the obligation to guarantee that the necessary system invariants are preserved. Thus,the following combinations are allowed:P: PROGRAM = CHECKED{ F1: SAFE PROC[] RETURNS[ INTEGER ] = { RETURN[ 1 ] }; F2: SAFE PROC[] RETURNS[ INTEGER ] = TRUSTED{ RETURN[ LOOPHOLE[ 'A ] ] }; F3: UNSAFE PROC[] RETURNS[ INTEGER ] = UNCHECKED{ RETURN[ LOOPHOLE[ 'A ] ] }; [] _ F1[]; [] _ F2[]; UNCHECKED{ [] _ F3[] } }.ERRORs are treated differently from SIGNALs in this regard. SIGNALs (like procedures) may bedeclared as either SAFE or UNSAFE; if a SIGNAL is SAFE, then all of the catch phrases associated with fvG? br,qrqrq `vr'9 ^qrqrqrqr ](;qr [qrGqr Yqr5 X2qrqr' Va T1qrqr OwX Lrb J@% IPZ G W FH DZ(qr AqrXq rqr# ?dqrqrqrqF rX ]LCedar 7T11 Changes11it must either be CHECKED or TRUSTED. ERRORs on the other hand are not considered SAFE orUNSAFE; a catch phrase associated with an ERROR must be CHECKED or TRUSTED if the surroundingscope is CHECKED, i.e., the body of the error must behave like a SAFE procedure (that may or maynot be called) if it is used in a CHECKED region. The same rule applies to catch phrases for UNWIND.(This treatment of ERROR is consistent with a termination semantics for ERRORs; we have adoptedthis view of safety in anticipation of adopting the semantics in the near future.)DefaultsOne of the major problems in introducing the safe Cedar subset is the use of old (potentially)unsafe interfaces in new (CHECKED) programs. Thus, we have adopted the following rules forsetting defaults: If the module begins with ModuleId: CEDAR . . ., then the outermost block is to beCHECKED and all interfaces are assumed to be SAFE; otherwise, the outermost block is to beUNCHECKED and all interfaces are assumed to be UNSAFE.Unless you explicilty use one of the keywords SAFE or UNSAFE, the safety of each transfer type thatyou define is determined by the default established in the module header. On the other hand, thechecking attribute is inherited. By default, a nested block is CHECKED if the textually enclosingblock is CHECKED; otherwise, it is UNCHECKED.COMPILER CHANGESVersion StampsIn its intermodule type checking, Cedar uses so-called version stamps to identify independentlycompiled modules. The version stamps computed by the Cedar 7T11 compiler are functions of theidentity of that compiler and of its inputs. You can now recompile the same source file, with thesame included modules, the same compiler and the same switch settings to get an object file withthe same version stamp.This stamp, which is essentially a 48 bit hash, is computed recursively as follows. Assume that anyexisting derived object (including the compiler itself) has a version stamp. The stamp for a newderived object is a hash ofthe creation time of the source filethe version stamp of each bcd mentioned in the DIRECTORY clausethe version stamp of the compilerthe compiler switches (with those controlling only compile-time feedback masked off)There is also a 7T11 binder that computes version stamps for its output in the same way.NoteIn the past, the version stamp has been a concatenation of a machine identifier and the creationtime of the derived object. Many existing utility programs therefore print the version stampformatted as a machine and network number, a date and a time. These programs give strange-looking output but, in all cases known to us, perform correctly. fvG? brqrqrqr&qr `vqr#qrqrqr ^qr1qr ]("qr4qr [qr+qr YR Tw Qr1- Oqr( NFwq r# Lqrqr) Jqr&qr G $qrqr' F W DZ<qr Bqrqr ! 3M 2)C 05+ . +"B );& (= %X$ #/qr " ! T ZX /w r'9  2+ e1* @ j w>U/Cedar 7T11 Changes12Tioga Source FilesThe compiler and binder ignore text in Tioga trailers. Any occurrence of a pair of NUL characters(characters with value 0C) in a source file marks the logical end of that source file.File LockingThe Cedar 7T11 compiler is designed to be run under control of the system modeller. It alsoexports an interface allowing it to be run from Tajo or from the temporary Cedar executive. Whenit is run in this mode, the (rather minimal) facilities in PreCascade for obtaining exclusive access toa file are bypassed. Use caution.Compiler SwitchesThe Cedar compiler is no longer able to generate object code for an Alto (or D-machine emulatingan Alto). The switch /a is ignored. The switch /l has a new interpretation; if it is set (thedefault), the compiler leaves space for code links in the BCD that it produces.There is a Cedar switch /c; if it is set (the default), the code for FORK assumes the availability ofthe Cedar runtime. If you plan to run your program directly under Pilot, compile with /-c. Ifyou are in doubt about how your processes will interact with the Cedar runtime, consult a wizard. fvG? bX ^r,6 ]nV YLvX V!r)3 TJ Sb Q" MrvX J#rN H||r|r# FO C|r qr A"5|r @7at ?=( TIMESROMAN  HELVETICA TIMESROMAN LOGO TIMESROMAN HELVETICA TIMESROMAN  TIMESROMAN  TIMESROMAN MATH   HELVETICA  HELVETICA  GACHA  KJOD#E+2i9A qKS~Wj/Z X# Cedar7T11.bravo SatterthwaiteFebruary 15, 1982 12:54 PM