-- (C) Copyright International Business Machines Corporation 23 January 
-- 1990.  All Rights Reserved. 
--  
-- See the file USERAGREEMENT distributed with this software for full 
-- terms and conditions of use. 
-- File: cgprocinit.pp
-- Author: Andy Lowry
-- SCCS Info: @(#)cgprocinit.pp	1.23 3/13/90

-- This function allocates and initilizes the per-process auxiliary
-- data record passed around in the cgData structure throughout the
-- codegen process

#include "typemark.h"
#include "codegen.h"

cgProcInit: using (cgInternal, common, coercions)

process (Q: cgProcInitQ)

declare
  args: cgProcInit;
  shutQ: signalQ;
  BBData: BBData;
  BB: basicBlock;
  objAddrShut: signalPort;
  empty: empty;
begin
  receive args from Q;

  new args.cgData.Proc;		-- allocate the return record
  args.cgData.Proc.id := args.id; -- copy in the process id

  -- locate process coercions for this process, if any
  block declare
    arb: polymorph;
    c: coercions;
  begin
    inspect a in args.cgData.Prog.annotations[S("Coercions")] begin
      arb := a.thing;
      unwrap c from arb {init};
      args.cgData.Proc.coercions := processCoercions#(c[args.id]);
    end inspect;
  on (NotFound)
    -- No coercions available... set up an empty coercion record
    new args.cgData.Proc.coercions;
    args.cgData.Proc.coercions.id := args.id;
    new args.cgData.Proc.coercions.preCoercions;
    new args.cgData.Proc.coercions.postCoercions;
    new args.cgData.Proc.coercions.handlerCoercions;
  end block;
  
  -- start with an empty map of linked programs
  new args.cgData.Proc.linkedPids;

  new BB;			-- allocate a first basic block
  BB.id <- BBid#(unique);	-- label it
  new BB.code;			-- empty code list
  unite BB.exit.unknown from empty;

  new BBData;			-- allocate a BB program rep
  new BBData.BBs;		-- allocate a BB table
  BBData.entry := BB.id;	-- BB we just created is entry point
  new BBData.BBOrder;		-- allocate the block ordering
  BBData.nreg <- ZERO;		-- no registers used yet

  BBDATA <- BBData;		-- install the BB structure
  CURBB <- BB;			-- currently filling the BB we just created

  -- start up an object mapper for this process
  call FNS.objAddrInit(args.cgData.Prog,args.id,FNS.compOffsets,FNS.lkupType,
      args.cgData.Proc.objAddr, args.cgData.Proc.rootAddr, 
      args.cgData.Proc.objType, args.cgData.Proc.tmpAddr,
      args.cgData.Proc.setAddr, args.cgData.Proc.nRegUsed, objAddrShut);
  
  -- Give them a port to signal us to shut down
  new shutQ;
  connect args.shutdown to shutQ;      
  return args;			-- all finished

  -- Wait for the shutdown signal, then shut down any servers we started
  select
  event shutQ
    send empty to objAddrShut;
  otherwise
    exit cantHappen;
  end select;
  
on exit(cantHappen)
  print S("CantHappen exit taken in cgprocinit");
end process
