DIRECTORY PrincOps USING [ CSegPrefix, FrameHandle, GFT, GFTIndex, GlobalFrameHandle, MainBodyIndex, NullFrame, NullGlobalFrame, sCopy, SD, sGFTLength, sSelfDestruct, sUnNew], PrincOpsUtils USING [ Alloc, BITAND, Codebase, COPY, EnterGlobalFrame, Free, GetFrame, GetReturnFrame, GFTFull, GlobalFrame, InvalidGlobalFrame, MakeFsi, RemoveGlobalFrame, SetReturnLink, UnNew, ValidateGlobalFrame]; NewAndUnnew: MONITOR IMPORTS PrincOpsUtils = BEGIN OPEN PrincOps, PrincOpsUtils; zCopy: ENTRY PROC [old: GlobalFrameHandle] RETURNS [new: GlobalFrameHandle] = BEGIN AllocGlobalFrame: PROC [old: GlobalFrameHandle, cp: LONG POINTER TO CSegPrefix] RETURNS [frame: GlobalFrameHandle, linkspace: CARDINAL] = { pbody: LONG POINTER = cp + CARDINAL[cp.entry[MainBodyIndex].initialpc]; nlinks: CARDINAL = cp.header.info.nlinks; linkspace _ IF old.codelinks THEN 0 ELSE nlinks + BITAND[-LOOPHOLE[nlinks, INTEGER], 3B]; frame _ Alloc[MakeFsi[(pbody - 1)^ + linkspace]]; }; linkspace: CARDINAL; codebase: LONG POINTER TO CSegPrefix; ValidateGlobalFrame[old ! InvalidGlobalFrame => GO TO invalid]; codebase _ Codebase[LOOPHOLE[old, PROGRAM]]; [new, linkspace] _ AllocGlobalFrame[old, codebase]; new _ new + linkspace; new^ _ [ gfi: , alloced: TRUE, shared: TRUE, copied: TRUE, started: FALSE, trapxfers: FALSE, codelinks: old.codelinks, code: old.code, global:]; new.code.out _ TRUE; -- cause start trap new.global[0] _ NullGlobalFrame; IF linkspace ~= 0 THEN COPY[from: old - linkspace, to: new - linkspace, nwords: linkspace]; [] _ EnterGlobalFrame[new, codebase.header.info.ngfi ! GFTFull => GO TO full]; old.shared _ TRUE; EXITS invalid => RETURN WITH ERROR InvalidGlobalFrame[old]; full => RETURN WITH ERROR GFTFull; END; zUnNew: ENTRY PROC [frame: GlobalFrameHandle] = BEGIN sharer: GlobalFrameHandle _ NullGlobalFrame; original: GlobalFrameHandle _ NullGlobalFrame; copy: GlobalFrameHandle _ NullGlobalFrame; codebase: LONG POINTER TO CSegPrefix; nothers: CARDINAL _ 0; nlinks: CARDINAL; ValidateGlobalFrame[frame ! InvalidGlobalFrame => GO TO invalid]; codebase _ Codebase[LOOPHOLE[frame, PROGRAM]]; nlinks _ codebase.header.info.nlinks; FOR gfi: GFTIndex IN [1..SD[sGFTLength]) DO f: GlobalFrameHandle = GetFrame[GFT[gfi]]; IF frame = NullGlobalFrame OR GFT[gfi].epbias ~= 0 THEN LOOP; IF f ~= frame THEN { IF f.global[0] = frame AND ~f.started THEN f.global[0] _ NullFrame; IF Codebase[LOOPHOLE[f, PROGRAM]] = codebase THEN IF f.copied THEN copy _ f ELSE original _ f; }; ENDLOOP; IF original = NullGlobalFrame AND ~frame.copied AND copy # NullGlobalFrame THEN GO TO invalid; RemoveGlobalFrame[frame]; IF frame.alloced THEN { Align: PROC [POINTER, WORD] RETURNS [POINTER] = LOOPHOLE[BITAND]; IF frame.codelinks THEN Free[frame] ELSE Free[Align[frame - nlinks, 177774B]] }; EXITS invalid => RETURN WITH ERROR InvalidGlobalFrame[frame]; END; zSelfDestruct: PROC = { destructee: FrameHandle = GetReturnFrame[]; SetReturnLink[destructee.returnlink]; UnNew[LOOPHOLE[GlobalFrame[destructee]]]; Free[destructee]; }; SD[sCopy] _ zCopy; SD[sUnNew] _ zUnNew; SD[sSelfDestruct] _ zSelfDestruct; END. <NewAndUnNew.mesa last edited by Levin on May 9, 1983 9:04 am conceptually, Copy is PUBLIC, but it is accessed via the System Dispatch table. conceptually, (z)UnNew is PUBLIC, but is accessed via the System Dispatch table. conceptually, (z)SelfDestruct is PUBLIC, but is accessed via the System Dispatch table. Êù˜Jšœ™J™+J˜šÏk ˜ šœ œ˜JšœœQœ%˜”—šœœ˜Jšœœ œ¥˜Â——J˜šœ ˜Jšœ˜—J˜Jš˜J˜Jšœ˜J˜šœœœœ˜MJšœO™OJš˜š Ïnœœœœœ ˜OJšœ'œ˜;Jšœœœœ$˜GJšœœ˜)Jš œ œœœ œœ œ˜YJ˜1Jšœ˜—Jšœ œ˜Jšœ œœœ ˜%Jšœ0œœ ˜?Jšœœœ˜,J˜3J˜˜Jš œœ œ œ œ˜AJšœ œ5˜E—JšœœÏc˜)J˜ šœ˜Jšœ@˜D—JšœBœœ˜NJšœ œ˜š˜Jšœ œœœ˜5Jšœœœœ ˜"—Jšœ˜J˜—šœœœ˜/JšœP™PJš˜J˜,J˜.J˜*Jšœ œœœ ˜%Jšœ œ˜Jšœœ˜Jšœ2œœ ˜AJšœœœ˜.J˜%šœœœ˜+Jšœ œ˜*Jš œœœœœ˜=šœ œ˜Jšœœ œ˜Cšœ œœ˜1Jšœ œ œ˜,—Jšœ˜—Jšœ˜—šœœœ˜OJšœœ ˜—J˜šœœ˜Jšžœœœœœœœœ˜AJšœœ ˜#Jšœ%˜)Jšœ˜—š˜Jšœ œœœ˜7—Jšœ˜J˜—šœœ˜JšœW™WJ˜+J˜%Jšœœ˜)J˜J˜—J˜Jšœ˜Jšœ˜Jšœ ˜"J˜Jšœ˜J˜—…— I