WriteMob:
PUBLIC
PROC[root: MobTree.Link] = {
Notifier: Alloc.Notifier = {
tb ¬ base[treetype];
stb ¬ base[sttype];
ctb ¬ base[cttype];
mtb ¬ base[mttype];
tyb ¬ base[typtype];
tmb ¬ base[tmtype];
etb ¬ base[exptype];
itb ¬ base[imptype];
sgb ¬ base[sgtype];
ftb ¬ base[fttype];
spb ¬ base[sptype];
fpb ¬ base[fptype];
ntb ¬ base[nttype];
ssb ¬ base[sstype];
cxb ¬ base[cxtype];
IF mobh #
NIL
THEN {
IF mobh.bases # MobUtilDefs.nullBases
THEN {
-- CHECK THIS for perf. problems
mobh.bases.ctb ¬ ctb;
mobh.bases.mtb ¬ mtb;
mobh.bases.tyb ¬ tyb;
mobh.bases.tmb ¬ tmb;
mobh.bases.spb ¬ spb;
mobh.bases.fpb ¬ fpb}
};
};
CopyImport: MobTree.Scan = {
OPEN MobSymbols;
sti: STIndex ¬ stNull;
olditi, iti: IMPIndex;
WITH t
SELECT
FROM
symbol => sti ¬ index;
subtree =>
WITH s1:tb[index].son[1]
SELECT
FROM
symbol => sti ¬ s1.index;
ENDCASE => Error[];
ENDCASE => Error[];
olditi ¬ stb[sti].impi;
IF sti = stNull OR olditi = IMPNull THEN RETURN;
iti ¬ MobUtilDefs.EnterImport[mobh, olditi, TRUE];
itb[iti].file ¬ MapFile[itb[iti].file, mobh];
IF mobh.bHeader.firstdummy = 0 THEN mobh.bHeader.firstdummy ¬ itb[iti].modIndex;
mobh.bHeader.nImports ¬ mobh.bHeader.nImports + 1;
mobh.bHeader.nDummies ¬ mobh.bHeader.nDummies + 1};
CopyExport: MobTree.Scan = {
OPEN MobSymbols;
sti: STIndex ¬ stNull;
hti: HTIndex ¬ HTNull;
neweti: EXPIndex ¬ EXPNull;
oldeti: EXPIndex ¬ EXPNull;
WITH t
SELECT
FROM
symbol => sti ¬ index;
subtree =>
WITH s1:tb[index].son[1]
SELECT
FROM
symbol => {sti ¬ s1.index; hti ¬ stb[sti].hti};
ENDCASE => Error[];
ENDCASE => Error[];
WITH s:stb[sti]
SELECT
FROM
external =>
WITH m:s.map
SELECT
FROM
interface => {
OPEN new: etb[neweti];
oldeti ¬ m.expi;
neweti ¬ MobUtilDefs.EnterExport[mobh, oldeti, TRUE];
FOR i: CARD16 IN [0..new.nLinks) DO new[i] ¬ mobh.bases.etb[oldeti][i]; ENDLOOP;
new.file ¬ MapFile[new.file, mobh]};
module => [] ¬ NewExportForModule[m.mti, HTNull];
ENDCASE => RETURN;
ENDCASE => RETURN;
mobh.bHeader.nExports ¬ mobh.bHeader.nExports + 1};
mobh: MobUtilDefs.MobHandle ¬ NIL;
saveIndex: CARDINAL = MobComData.data.textIndex;
node, subNode: MobTree.Index;
symbolMap: SymbolMap ¬ NIL;
copyMap: CopyMap ¬ NIL;
Alloc.AddNotify[MobComData.data.table, Notifier];
node ¬ MobTreeOps.GetNode[root];
[mobh, symbolMap, copyMap] ¬ Initialize[];
CopyConfigs[mobh];
CopyModules[mobh];
CopySpaces[mobh];
CopyFramePacks[mobh];
subNode ¬ MobTreeOps.GetNode[tb[node].son[3]];
MobComData.data.textIndex ¬ tb[subNode].info;
MobTreeOps.ScanList[tb[subNode].son[1], CopyImport];
MobTreeOps.ScanList[tb[subNode].son[2], CopyExport];
IF tb[subNode].attrs[$exportsALL]
THEN
ExportCx[MobUtilDefs.ContextForTree[tb[subNode].son[Sons.name.ORD]], mobh];
IF MobComData.data.copySymbols THEN EnterMissingSymbolFiles[mobh, copyMap];
TableOut[mobh, symbolMap, copyMap];
Finalize[mobh];
symbolMap ¬ NIL;
MobComData.data.textIndex ¬ saveIndex;
Alloc.DropNotify[MobComData.data.table, Notifier];
};
Initialize:
PROC
RETURNS [mobh: MobUtilDefs.MobHandle, symbolMap: SymbolMap, copyMap: CopyMap ¬
NIL] = {
impSize, expSize, sgSize, fSize, nSize, ssSize: CARDINAL;
nSgis: CARDINAL;
b: Table.Base;
desc: ConvertUnsafe.SubString;
table: Alloc.Handle = MobComData.data.table;
vmh: CountedVM.Handle;
symbolMap ¬ NIL;
desc.base ¬ LOOPHOLE[Rope.Flatten[MobComData.data.sourceName]];
desc.offset ¬ 0;
desc.length ¬ Rope.Length[MobComData.data.sourceName];
IF MobComData.data.copySymbols THEN symbolMap ¬ InitSymbolCopy[];
impSize ¬ Alloc.Bounds[table, imptype].size;
expSize ¬ Alloc.Bounds[table, exptype].size;
sgSize ¬ Alloc.Bounds[table, sgtype].size;
nSgis ¬ sgSize/SGRecord.SIZE;
fSize ¬ Alloc.Bounds[table, fttype].size;
nSize ¬ Alloc.Bounds[table, nttype].size;
ssSize ¬ Alloc.Bounds[table, sstype].size;
fileMap ¬ NEW[FileMapSeq[fSize/FTRecord.SIZE]];
FOR i: CARDINAL IN [0..fileMap.length) DO fileMap[i] ¬ FTNull ENDLOOP;
vmh ¬ CountedVM.SimpleAllocate[
Mob.SIZE + impSize + expSize + sgSize + fSize + nSize + ssSize];
mobh ¬ NEW[MobUtilDefs.MobObject ¬ [LOOPHOLE[vmh.pointer], vmh, MobUtilDefs.nullBases, MobUtilDefs.nullLimits]];
b ¬ LOOPHOLE[mobh.bHeader, Table.Base] + Mob.SIZE;
Basics.MoveBytes[dstBase~(mobh.bases.etb ¬ b), dstStart~0, srcBase~etb, srcStart~0, count~expSize*
BYTES[
UNIT]];
b ¬ b + expSize; Alloc.Trim[table, exptype, 0];
Basics.MoveBytes[dstBase~(mobh.bases.itb ¬ b), dstStart~0, srcBase~itb, srcStart~0, count~impSize*
BYTES[
UNIT]];
b ¬ b + impSize; Alloc.Trim[table, imptype,0];
Basics.MoveBytes[dstBase~(mobh.bases.ftb ¬ b), dstStart~0, srcBase~ftb, srcStart~0, count~fSize*
BYTES[
UNIT]];
b ¬ b + fSize; Alloc.Trim[table, fttype,0];
Basics.MoveBytes[dstBase~(mobh.bases.ntb ¬ b), dstStart~0, srcBase~ntb, srcStart~0, count~nSize*
BYTES[
UNIT]];
b ¬ b + nSize; Alloc.Trim[table, nttype,0];
Basics.MoveBytes[dstBase~(mobh.bases.ssb ¬ b), dstStart~0, srcBase~
LOOPHOLE[ssb], srcStart~0, count~ssSize*
BYTES[
UNIT]];
b ¬ b + ssSize;
MobHashOps.Reset[];
InitHeader[
mob: mobh.bHeader,
objectVersion: OSMiscOps.StampToTime[MobComData.data.objectStamp],
source: MobUtilDefs.EnterName[desc],
sourceVersion: MobComData.data.sourceVersion];
mobh.bases.ctb ¬ Alloc.Bounds[table, cttype].base;
mobh.bases.mtb ¬ Alloc.Bounds[table, mttype].base;
mobh.bases.tyb ¬ Alloc.Bounds[table, typtype].base;
mobh.bases.tmb ¬ Alloc.Bounds[table, tmtype].base;
mobh.bases.spb ¬ Alloc.Bounds[table, sptype].base;
mobh.bases.fpb ¬ Alloc.Bounds[table, fptype].base;
IF MobComData.data.copySymbols
THEN {
MapSymbolFiles[mobh, symbolMap];
copyMap ¬ InitCopyMap[nSgis]};
mobh.bases.sgb ¬ Alloc.Bounds[table, sgtype].base;
MapSegments[$code, mobh]; -- CHECK THIS can we get rid of this?
IF ~MobComData.data.copySymbols THEN MapSegments[$symbols, mobh];
};