import re

SRC = open('/tmp/opencode/make_runner.py').read()
shim = re.search(r"shim = r'''(.*?)'''", SRC, re.S).group(1)

extra = r'''
function __V(x)
  local t = type(x)
  if t == "string" then local s=x:sub(1,64):gsub("%c","."); return string.format("str#%d:%q",#x,s)
  elseif t == "number" then return string.format("%.10g", x)
  elseif t == "table" then local n=0 for _ in pairs(x) do n=n+1 if n>100000 then break end end return "tbl#"..#x.."/"..n
  elseif t == "function" then return "fn" end
  return t..":"..tostring(x)
end
local function __g(t,k) local ok,v=pcall(function() return t[k] end); if ok then return v end return nil end
__TAG={} __NINS={}
local function __nins(O) local n=__NINS[O]; if n then return n end; local o3=__g(O,3); if type(o3)=="table" then n=#o3 else n=-1 end; __NINS[O]=n; return n end
function __MAKETAG(O, m)
  local n=__nins(O)
  if n==140 then __TAG[O]="N140" end
  if n==31 then __TAG[O]="N31" end
  if n==41 or n==42 then
    __UPN = (__UPN or 0) + 1
    if __UPN <= 12 then
      local cnt=0; local parts={}
      if type(m)=="table" then
        for k,v in pairs(m) do cnt=cnt+1; if cnt<=30 then parts[#parts+1]=tostring(k).."="..__V(v) end end
      end
      __realprint("UP", "n"..tostring(n), "mtype", type(m), "npairs", cnt, table.concat(parts," "))
    end
  end
end
__FNMAP=setmetatable({},{__mode="k"})
__DUMPED_CLOSURE=false
function __DUMPCLOSURE(O, why)
  if __DUMPED_CLOSURE then return end
  __DUMPED_CLOSURE=true
  __realprint("CLOSURE", why, tostring(O), "nins", __nins(O))
  for k=1,12 do __realprint("CF", k, __V(__g(O,k))) end
  for _,f in ipairs({7,8,9,10}) do
    local t=__g(O,f)
    if type(t)=="table" then
      local ks={} for kk in pairs(t) do ks[#ks+1]=kk end
      table.sort(ks,function(a,b) if type(a)==type(b) and type(a)=="number" then return a<b end return tostring(a)<tostring(b) end)
      __realprint("CPOOL", f, "n", #ks)
      for i=1,math.min(#ks,80) do local kk=ks[i]; __realprint("CPV", f, tostring(kk), __V(t[kk])) end
    end
  end
  local o3,o4,o5,o10,o7,o9,o8=__g(O,3),__g(O,4),__g(O,5),__g(O,10),__g(O,7),__g(O,9),__g(O,8)
  local n=type(o3)=="table" and #o3 or 0
  for i=1,math.min(n,60) do __realprint("CI", i, "op", __V(o3[i]), "t", __V(o4[i]), "d", __V(o5[i]), "P", __V(o10[i]), "b", __V(o7[i]), "y", __V(o9[i]), "p", __V(o8[i])) end
end
__OPN=0
function __OP(O,pc,z,a,b,c,d,e,f,regs)
  local n=__nins(O)
  if n==140 and pc>=42 and pc<=44 then
    local f2=regs[2]
    if type(f2)=="function" then
      local FO=__FNMAP[f2]
      __realprint("PC43FN", "pc", pc, "nins", FO and __nins(FO) or -1, "O", tostring(FO))
      if FO then __DUMPCLOSURE(FO, "pc"..tostring(pc)) end
    end
  end
end
'''

shim += extra

raw = open('/tmp/opencode/stage2.lua').read()
rhex = re.search(r'__RHEX__\t([0-9a-f]+)', open('/tmp/opencode/cap4.txt').read()).group(1)
rbytes = bytes.fromhex(rhex)
rlit = '"' + ''.join('\\x%02x' % b for b in rbytes) + '"'

s = raw
s = 'local R=buffer.fromstring(' + rlit + ');' + s[len('local R=...;'):]
old_factory = '(l)[55]=function(O,m,A)'
assert s.count(old_factory) == 1
s = s.replace(old_factory, '(l)[55]=function(O,m,A)__MAKETAG(O,m);', 1)
old_ret = 'return h;end;if not T[13084]'
assert s.count(old_ret) == 1
s = s.replace(old_ret, '__FNMAP[h]=O;return h;end;if not T[13084]', 1)

head = 'while true do local Z=o[Q];'
assert s.count(head) == 1
s = s.replace(head, 'while true do local Z=o[Q];__OP(O,Q,Z,t[Q],d[Q],P[Q],y[Q],b[Q],p[Q],q);', 1)

tail = r'''
local __ok,__err = pcall(function()
''' + s + r'''
end)
__realprint("EXEC1", __ok, type(__err))
if __ok then
  local __ok2,__err2 = pcall(__err)
  __realprint("EXEC2", __ok2, tostring(__err2))
end
'''
open('/tmp/opencode/probe_closure.luau','w').write(shim + tail)
print("wrote")
