RegisterRefLiteralImpl.mesa
Copyright Ó 1987, 1991 by Xerox Corporation. All rights reserved.
Mark Weiser, February 19, 1988 10:46:12 am PST
Carl Hauser, March 8, 1988 10:59:43 am PST
Chauser, January 3, 1991 11:26 am PST
Willie-s, May 30, 1991 11:40 am PDT
Doug Wyatt, August 24, 1991 10:33 pm PDT
Michael Plass, September 24, 1992 9:38 pm PDT
This module registers general procs for making the world safe for ref literals. It also registers the first four procs, for handling the compiler built-in ref literal types of Rope.ROPE, Rope.Text, REF TEXT, and Atom.
DIRECTORY
AtomPrivate,
ConvertUnsafe,
RegisterRefLiteral,
Rope,
SafeStorage;
RegisterRefLiteralImpl: CEDAR MONITOR
IMPORTS AtomPrivate, ConvertUnsafe
EXPORTS RegisterRefLiteral
~ BEGIN
tab: LIST OF TypeCreator ¬ NIL;
the global list of all REF-literal types together with their creator procs
TypeCreator: TYPE = RECORD [
type: SafeStorage.Type,
proc: RegisterRefLiteral.RegisteredProc
];
UnknownType: PUBLIC ERROR [type: SafeStorage.Type, string: LONG STRING] = CODE;
Registrar: TYPE = PROC [p: RegisterRefLiteral.RegisteredProc, type: SafeStorage.Type];
ExternalNames: PROC = TRUSTED MACHINE CODE {
"^ExternalNames\n";
"Create XR←GetRefLiteral\n";
"RegisterType XR←RegisterRefLiteralCreator\n";
};
RegisterType: PUBLIC ENTRY Registrar ~ { -- aka XR¬RegisterRefLiteralCreator
Registers "p" to be used to create REF literals of type "type" from LONG STRINGs.
Note that the REF type, not the referent type, is used to register the procedure.
FOR l: LIST OF TypeCreator ¬ tab, l.rest UNTIL l=NIL DO
IF l.first.type = type THEN {l.first.proc ¬ p; RETURN};
ENDLOOP;
tab ¬ CONS[[type: type, proc: p], tab];
};
Uninit: RegisterRefLiteral.RegisteredProc ~ {
this procedure should never be called.
ERROR;
};
LookupType: INTERNAL PROC [type: SafeStorage.Type] RETURNS [found: BOOL, p: RegisterRefLiteral.RegisteredProc] ~ {
FOR l: LIST OF TypeCreator ¬ tab, l.rest UNTIL l=NIL DO
IF l.first.type = type THEN {RETURN[TRUE, l.first.proc]};
ENDLOOP;
RETURN[FALSE, Uninit];
};
Creator: TYPE = PROC [type: SafeStorage.Type, string: LONG STRING] RETURNS [REF];
Create: PUBLIC ENTRY Creator ~ { -- aka XR¬GetRefLiteral
Called by the runtime during installation of each REF literal. It looks up the type, and calls the appropriate registered proc. If there isn't one, it raises an error.
found: BOOL;
p: RegisterRefLiteral.RegisteredProc;
Somebody introduced REF literals in CedarCore; that's a no-no but until its fixed we'll press on.
IF tab = NIL THEN -- RETURN WITH ERROR UnknownType[type, string] -- TRUSTED {RETURN[LOOPHOLE[string]]};
[found, p] ¬ LookupType[type];
IF found THEN RETURN p[string]
ELSE {
The most likely cause of this is an interface version mismatch with Rope. But we find out about it here before importing Rope because the compiler generates REF literal registration before imports.
RETURN WITH ERROR UnknownType[type, string];
};
};
CreateTEXT: RegisterRefLiteral.RegisteredProc = TRUSTED {
RETURN [IF string = NIL THEN NIL ELSE ConvertUnsafe.ToRefText[string]]
};
CreateROPE: RegisterRefLiteral.RegisteredProc = TRUSTED {
RETURN [IF string = NIL THEN NIL ELSE ConvertUnsafe.ToRope[string]]
};
CreateATOM: RegisterRefLiteral.RegisteredProc = TRUSTED {
RETURN [AtomPrivate.UnsafeMakeAtomFromString[string]]
};
Here is the start code. It registers handlers for the first four types.
ExternalNames[];
RegisterType[CreateROPE, CODE[Rope.ROPE]];
RegisterType[CreateROPE, CODE[Rope.Text]];
RegisterType[CreateTEXT, CODE[REF TEXT]];
RegisterType[CreateATOM, CODE[ATOM]];
END.