// Micro slow symbol lookup
// last edited December 26, 1979  8:42 AM
// Copyright Xerox Corporation 1979

	get "micdecl.d"

external
[		// O.S.
	DoubleAdd
	Puts
		// MICBI
	maxbi
		// MICSYM
	@endhc; @hlast; @hprev; @sw0
]


static [
// Statistics
// *** Assumes statics are allocated in order
	zlook; zlook1	// # of lookups
	zpacked; zpacked1	// # of already looked up symbols
	zlong; zlong1	// # of long symbols
	zchain; zchain1	// # of links followed
	zexit; zexit1	// # of matches on first 2 char.s
	zfail; zfail1	// # of lookups that failed
	ztype = 0	// table of found symbols by type
	zbi = 0	// table of found BUILTINs by #
  ]


let lookup(paddr, pcc) = valof
// A version of lookup that takes statistics and checks for tracing
[	DoubleAdd1(lv zlook)
	if tracesyms then
	[ let old = lchan
	  lchan = erlchan
	  lchr($*S)
	  lblk(paddr, pcc)
	  lchan = old
	]
	if pcc ge 16 then DoubleAdd1(lv zlong)
	let ep = fastlookup(paddr, pcc)
	test (pcc eq 2) & (paddr!1 ls 40b)
	 ifso	// packed value
	[ DoubleAdd1(lv zpacked)
	  if tracesyms then Puts(erlchan, $↑)
	]
	 ifnot
	[ let nc, nc1, nx, nx1 = 0, 0, -1, -1
	  let ptr = hlast
	  let end = (ep eq 0? endhc, hprev eq hlast? ep, hprev)
	  until ptr eq end do
	  [ nc1 = nc1+1
	    if tracesyms then Puts(erlchan, $,)
	    ptr = @ptr
	    if sw0 eq ptr!sname then nx1 = nx1+1
	  ]
	  DoubleAdd(lv zchain, lv nc)
	  DoubleAdd(lv zexit, lv nx)
	]
	test ep eq 0
	 ifso
	[ DoubleAdd1(lv zfail)
	  if tracesyms then Puts(erlchan, $**)
	]
	 ifnot
	[ if ztype eq 0 then	// not allocated yet
	  [ ztype = alloc((maxtype+1)*2)
	    zbi = alloc((maxbi+1)*2)
	  ]
	  DoubleAdd1(ztype+(ep!stype ls 0? adrtype, ep!stype gr maxtype? mactype, ep!stype)*2)
	  if ep!stype eq bitype then DoubleAdd1(zbi+ep!bsno*2)
	]
	resultis ep
]