BCO linker relies on laziness during resolution, in conflict with needs of unlifted values
One of the final steps in preparing bytecode objects for loading into the heap is linking, where we construct the new BCO's pointer array (which holds pointers to the free variables of the BCO). This array is constructed by GHCi.CreateBCO.mkPtrsArray
:
-- we recursively link any sub-BCOs while making the ptrs array
mkPtrsArray :: Array Int HValue -> Word -> [ResolvedBCOPtr] -> IO PtrsArr
mkPtrsArray arr n_ptrs ptrs = do
marr <- newPtrsArray (fromIntegral n_ptrs)
let
fill (ResolvedBCORef n) i =
writePtrsArrayHValue i (arr ! n) marr -- must be lazy!
...
zipWithM_ fill ptrs [0..]
return marr
As we see here, free variables which are ResolvedBCORef
s (e.g. objects in the same group as the BCO being loaded) are treated lazily. That is, the pointer array will include a thunk of arr ! n
, which will be dereferenced when the BCO attempts to dereference the entry.
This obviously breaks in the presence of unlifted values. We need to figure out what to do about this.