From 6e582898d649d11f5e46efeb477cf80074262762 Mon Sep 17 00:00:00 2001 From: Marius Date: Thu, 22 Nov 2012 19:00:17 +0200 Subject: beta 2012.11.22 17:45 --- scripts/context/lua/mtxrun.lua | 322 ++++++++++++-------- scripts/context/stubs/mswin/mtxrun.lua | 322 ++++++++++++-------- scripts/context/stubs/unix/mtxrun | 322 ++++++++++++-------- tex/context/base/cont-new.mkii | 2 +- tex/context/base/cont-new.mkiv | 2 +- tex/context/base/context-version.pdf | Bin 4149 -> 4150 bytes tex/context/base/context-version.png | Bin 40689 -> 40738 bytes tex/context/base/context.mkii | 2 +- tex/context/base/context.mkiv | 2 +- tex/context/base/luat-sto.lua | 19 +- tex/context/base/status-files.pdf | Bin 24547 -> 24564 bytes tex/context/base/status-lua.pdf | Bin 198697 -> 198673 bytes tex/context/base/util-lua.lua | 336 +++++++++++++-------- tex/generic/context/luatex/luatex-fonts-merged.lua | 2 +- 14 files changed, 830 insertions(+), 501 deletions(-) diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua index 3c03006a8..897c39260 100644 --- a/scripts/context/lua/mtxrun.lua +++ b/scripts/context/lua/mtxrun.lua @@ -5404,23 +5404,118 @@ luautilities.nofstrippedbytes = 0 local strippedchunks = { } -- allocate() luautilities.strippedchunks = strippedchunks +local function fatalerror(name) + utilities.report(format("fatal error in %q",name or "unknown")) +end --- The next function was posted by Peter Cawley on the lua list and strips line --- number information etc. from the bytecode data blob. We only apply this trick --- when we store data tables. Stripping makes the compressed format file about --- 1MB smaller (and uncompressed we save at least 6MB). --- --- You can consider this feature an experiment, so it might disappear. There is --- no noticeable gain in runtime although the memory footprint should be somewhat --- smaller (and the file system has a bit less to deal with). --- --- Begin of borrowed code ... works for Lua 5.1 which LuaTeX currently uses ... +if jit then -local strip_code_pc, strippedbytecode + local function register(name) + if tracestripping then + utilities.report("stripped bytecode: %s",name or "unknown") + end + strippedchunks[#strippedchunks+1] = name + luautilities.nofstrippedchunks = luautilities.nofstrippedchunks + 1 + end -if jit then + local function stupidcompile(luafile,lucfile,strip) + local code = io.loaddata(luafile) + if code and code ~= "" then + code = loadstring(code) + if code then + code = dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode) + if code and code ~= "" then + register(name) + io.savedata(lucfile,code) + return true, 0 + end + else + fatalerror() + end + else + fatalerror() + end + return false, 0 + end + + -- quite subtle ... doing this wrong incidentally can give more bytes + + function luautilities.loadedluacode(fullname,forcestrip,name) + -- quite subtle ... doing this wrong incidentally can give more bytes + name = name or fullname + local code = loadfile(fullname) + if code then + code() + end + if forcestrip and luautilities.stripcode then + if type(forcestrip) == "function" then + forcestrip = forcestrip(fullname) + end + if forcestrip or luautilities.alwaysstripcode then + register(name) + return loadstring(dump(code,true)), 0 + else + return code, 0 + end + elseif luautilities.alwaysstripcode then + register(name) + return loadstring(dump(code,true)), 0 + else + return code, 0 + end + end - strip_code_pc = function(dump,name) + function luautilities.strippedloadstring(code,forcestrip,name) -- not executed + if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then + code = loadstring(code) + if not code then + fatalerror(name) + end + register(name) + code = dump(code,true) + end + return loadstring(code), 0 + end + + function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) -- defaults: cleanup=false strip=true + utilities.report("lua: compiling %s into %s",luafile,lucfile) + os.remove(lucfile) + local done = stupidcompile(luafile,lucfile,strip ~= false) + if done then + utilities.report("lua: %s dumped into %s (stripped)",luafile,lucfile) + if cleanup == true and lfs.isfile(lucfile) and lfs.isfile(luafile) then + utilities.report("lua: removing %s",luafile) + os.remove(luafile) + end + end + return done + end + +else + + -- The next function was posted by Peter Cawley on the lua list and strips line + -- number information etc. from the bytecode data blob. We only apply this trick + -- when we store data tables. Stripping makes the compressed format file about + -- 1MB smaller (and uncompressed we save at least 6MB). + -- + -- You can consider this feature an experiment, so it might disappear. There is + -- no noticeable gain in runtime although the memory footprint should be somewhat + -- smaller (and the file system has a bit less to deal with). + -- + -- Begin of borrowed code ... works for Lua 5.1 which LuaTeX currently uses ... + + local function register(name,before,after) + local delta = before - after + if tracestripping then + utilities.report("stripped bytecode: %s, before %s, after %s, delta %s",name or "unknown",before,after,delta) + end + strippedchunks[#strippedchunks+1] = name + luautilities.nofstrippedchunks = luautilities.nofstrippedchunks + 1 + luautilities.nofstrippedbytes = luautilities.nofstrippedbytes + delta + return delta + end + + local function strip_code_pc(dump,name) local before = #dump local version, format, endian, int, size, ins, num = byte(dump,5,11) local subint @@ -5479,138 +5574,127 @@ if jit then end dump = sub(dump,1,12) .. strip_function(sub(dump,13,-1)) local after = #dump - local delta = before-after - if tracestripping then - utilities.report("stripped bytecode: %s, before %s, after %s, delta %s",name or "unknown",before,after,delta) - end - strippedchunks[#strippedchunks+1] = name - luautilities.nofstrippedchunks = luautilities.nofstrippedchunks + 1 - luautilities.nofstrippedbytes = luautilities.nofstrippedbytes + delta + local delta = register(name,before,after) return dump, delta end -- ... end of borrowed code. - strippedbytecode = function(code,forcestrip,name) - if (forcestrip and luautilities.stripcode) or luautilities.alwaysstripcode then - return strip_code_pc(code,name) - else - return code, 0 - end - end - -else - - strip_code_pc = function(str) return str, 0 end - strippedbytecode = strip_code_pc - -end - -luautilities.stripbytecode = strip_code_pc -luautilities.strippedbytecode = strippedbytecode - -local function fatalerror(name) - utilities.report(format("fatal error in %q",name or "unknown")) -end - --- quite subtle ... doing this wrong incidentally can give more bytes - - -function luautilities.loadedluacode(fullname,forcestrip,name) -- quite subtle ... doing this wrong incidentally can give more bytes - name = name or fullname - local code = loadfile(fullname) - if code then - code() - end - if forcestrip and luautilities.stripcode then - if type(forcestrip) == "function" then - forcestrip = forcestrip(fullname) - end - if forcestrip then - local code, n = strip_code_pc(dump(code,name)) - return loadstring(code), n + + function luautilities.loadedluacode(fullname,forcestrip,name) + -- quite subtle ... doing this wrong incidentally can give more bytes + name = name or fullname + local code = loadfile(fullname) + if code then + code() + end + if forcestrip and luautilities.stripcode then + if type(forcestrip) == "function" then + forcestrip = forcestrip(fullname) + end + if forcestrip then + local code, n = strip_code_pc(dump(code),name) + return loadstring(code), n + elseif luautilities.alwaysstripcode then + return loadstring(strip_code_pc(dump(code),name)) + else + return code, 0 + end elseif luautilities.alwaysstripcode then return loadstring(strip_code_pc(dump(code),name)) else return code, 0 end - elseif luautilities.alwaysstripcode then - return loadstring(strip_code_pc(dump(code),name)) - else - return code, 0 end -end -function luautilities.strippedloadstring(code,forcestrip,name) -- not executed - local n = 0 - if (forcestrip and luautilities.stripcode) or luautilities.alwaysstripcode then - code = loadstring(code) - if not code then - fatalerror(name) + function luautilities.strippedloadstring(code,forcestrip,name) -- not executed + local n = 0 + if (forcestrip and luautilities.stripcode) or luautilities.alwaysstripcode then + code = loadstring(code) + if not code then + fatalerror(name) + end + code, n = strip_code_pc(dump(code),name) end - code, n = strip_code_pc(dump(code),name) + return loadstring(code), n end - return loadstring(code), n -end -local function stupidcompile(luafile,lucfile,strip) - local code = io.loaddata(luafile) - local n = 0 - if code and code ~= "" then - code = loadstring(code) - if not code then - fatalerror() - end - code = dump(code) - if strip then - code, n = strippedbytecode(code,true,luafile) -- last one is reported - end + local function stupidcompile(luafile,lucfile,strip) + local code = io.loaddata(luafile) + local n = 0 if code and code ~= "" then - io.savedata(lucfile,code) + code = loadstring(code) + if not code then + fatalerror() + end + code = dump(code) + if strip then + code, n = strip_code_pc(code,luautilities.stripcode or luautilities.alwaysstripcode,luafile) -- last one is reported + end + if code and code ~= "" then + io.savedata(lucfile,code) + end end + return n end - return n -end -local luac_normal = "texluac -o %q %q" -local luac_strip = "texluac -s -o %q %q" + local luac_normal = "texluac -o %q %q" + local luac_strip = "texluac -s -o %q %q" -function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) -- defaults: cleanup=false strip=true - utilities.report("lua: compiling %s into %s",luafile,lucfile) - os.remove(lucfile) - local done = false - if strip ~= false then - strip = true - end - if forcestupidcompile then - fallback = true - elseif strip then - done = os.spawn(format(luac_strip, lucfile,luafile)) == 0 - else - done = os.spawn(format(luac_normal,lucfile,luafile)) == 0 - end - if not done and fallback then - local n = stupidcompile(luafile,lucfile,strip) - if n > 0 then - utilities.report("lua: %s dumped into %s (%i bytes stripped)",luafile,lucfile,n) + function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) -- defaults: cleanup=false strip=true + utilities.report("lua: compiling %s into %s",luafile,lucfile) + os.remove(lucfile) + local done = false + if strip ~= false then + strip = true + end + if forcestupidcompile then + fallback = true + elseif strip then + done = os.spawn(format(luac_strip, lucfile,luafile)) == 0 else - utilities.report("lua: %s dumped into %s (unstripped)",luafile,lucfile) + done = os.spawn(format(luac_normal,lucfile,luafile)) == 0 end - cleanup = false -- better see how bad it is - end - if done and cleanup == true and lfs.isfile(lucfile) and lfs.isfile(luafile) then - utilities.report("lua: removing %s",luafile) - os.remove(luafile) + if not done and fallback then + local n = stupidcompile(luafile,lucfile,strip) + if n > 0 then + utilities.report("lua: %s dumped into %s (%i bytes stripped)",luafile,lucfile,n) + else + utilities.report("lua: %s dumped into %s (unstripped)",luafile,lucfile) + end + cleanup = false -- better see how bad it is + end + if done and cleanup == true and lfs.isfile(lucfile) and lfs.isfile(luafile) then + utilities.report("lua: removing %s",luafile) + os.remove(luafile) + end + return done end - return done -end - - - - +end +-- local getmetatable, type = getmetatable, type +-- +-- local types = { } +-- +-- function luautilities.registerdatatype(d,name) +-- types[getmetatable(d)] = name +-- end +-- +-- function luautilities.datatype(d) +-- local t = type(d) +-- if t == "userdata" then +-- local m = getmetatable(d) +-- return m and types[m] or "userdata" +-- else +-- return t +-- end +-- end +-- +-- luautilities.registerdatatype(lpeg.P("!"),"lpeg") +-- +-- print(luautilities.datatype(lpeg.P("oeps"))) end -- of closure diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua index 3c03006a8..897c39260 100644 --- a/scripts/context/stubs/mswin/mtxrun.lua +++ b/scripts/context/stubs/mswin/mtxrun.lua @@ -5404,23 +5404,118 @@ luautilities.nofstrippedbytes = 0 local strippedchunks = { } -- allocate() luautilities.strippedchunks = strippedchunks +local function fatalerror(name) + utilities.report(format("fatal error in %q",name or "unknown")) +end --- The next function was posted by Peter Cawley on the lua list and strips line --- number information etc. from the bytecode data blob. We only apply this trick --- when we store data tables. Stripping makes the compressed format file about --- 1MB smaller (and uncompressed we save at least 6MB). --- --- You can consider this feature an experiment, so it might disappear. There is --- no noticeable gain in runtime although the memory footprint should be somewhat --- smaller (and the file system has a bit less to deal with). --- --- Begin of borrowed code ... works for Lua 5.1 which LuaTeX currently uses ... +if jit then -local strip_code_pc, strippedbytecode + local function register(name) + if tracestripping then + utilities.report("stripped bytecode: %s",name or "unknown") + end + strippedchunks[#strippedchunks+1] = name + luautilities.nofstrippedchunks = luautilities.nofstrippedchunks + 1 + end -if jit then + local function stupidcompile(luafile,lucfile,strip) + local code = io.loaddata(luafile) + if code and code ~= "" then + code = loadstring(code) + if code then + code = dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode) + if code and code ~= "" then + register(name) + io.savedata(lucfile,code) + return true, 0 + end + else + fatalerror() + end + else + fatalerror() + end + return false, 0 + end + + -- quite subtle ... doing this wrong incidentally can give more bytes + + function luautilities.loadedluacode(fullname,forcestrip,name) + -- quite subtle ... doing this wrong incidentally can give more bytes + name = name or fullname + local code = loadfile(fullname) + if code then + code() + end + if forcestrip and luautilities.stripcode then + if type(forcestrip) == "function" then + forcestrip = forcestrip(fullname) + end + if forcestrip or luautilities.alwaysstripcode then + register(name) + return loadstring(dump(code,true)), 0 + else + return code, 0 + end + elseif luautilities.alwaysstripcode then + register(name) + return loadstring(dump(code,true)), 0 + else + return code, 0 + end + end - strip_code_pc = function(dump,name) + function luautilities.strippedloadstring(code,forcestrip,name) -- not executed + if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then + code = loadstring(code) + if not code then + fatalerror(name) + end + register(name) + code = dump(code,true) + end + return loadstring(code), 0 + end + + function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) -- defaults: cleanup=false strip=true + utilities.report("lua: compiling %s into %s",luafile,lucfile) + os.remove(lucfile) + local done = stupidcompile(luafile,lucfile,strip ~= false) + if done then + utilities.report("lua: %s dumped into %s (stripped)",luafile,lucfile) + if cleanup == true and lfs.isfile(lucfile) and lfs.isfile(luafile) then + utilities.report("lua: removing %s",luafile) + os.remove(luafile) + end + end + return done + end + +else + + -- The next function was posted by Peter Cawley on the lua list and strips line + -- number information etc. from the bytecode data blob. We only apply this trick + -- when we store data tables. Stripping makes the compressed format file about + -- 1MB smaller (and uncompressed we save at least 6MB). + -- + -- You can consider this feature an experiment, so it might disappear. There is + -- no noticeable gain in runtime although the memory footprint should be somewhat + -- smaller (and the file system has a bit less to deal with). + -- + -- Begin of borrowed code ... works for Lua 5.1 which LuaTeX currently uses ... + + local function register(name,before,after) + local delta = before - after + if tracestripping then + utilities.report("stripped bytecode: %s, before %s, after %s, delta %s",name or "unknown",before,after,delta) + end + strippedchunks[#strippedchunks+1] = name + luautilities.nofstrippedchunks = luautilities.nofstrippedchunks + 1 + luautilities.nofstrippedbytes = luautilities.nofstrippedbytes + delta + return delta + end + + local function strip_code_pc(dump,name) local before = #dump local version, format, endian, int, size, ins, num = byte(dump,5,11) local subint @@ -5479,138 +5574,127 @@ if jit then end dump = sub(dump,1,12) .. strip_function(sub(dump,13,-1)) local after = #dump - local delta = before-after - if tracestripping then - utilities.report("stripped bytecode: %s, before %s, after %s, delta %s",name or "unknown",before,after,delta) - end - strippedchunks[#strippedchunks+1] = name - luautilities.nofstrippedchunks = luautilities.nofstrippedchunks + 1 - luautilities.nofstrippedbytes = luautilities.nofstrippedbytes + delta + local delta = register(name,before,after) return dump, delta end -- ... end of borrowed code. - strippedbytecode = function(code,forcestrip,name) - if (forcestrip and luautilities.stripcode) or luautilities.alwaysstripcode then - return strip_code_pc(code,name) - else - return code, 0 - end - end - -else - - strip_code_pc = function(str) return str, 0 end - strippedbytecode = strip_code_pc - -end - -luautilities.stripbytecode = strip_code_pc -luautilities.strippedbytecode = strippedbytecode - -local function fatalerror(name) - utilities.report(format("fatal error in %q",name or "unknown")) -end - --- quite subtle ... doing this wrong incidentally can give more bytes - - -function luautilities.loadedluacode(fullname,forcestrip,name) -- quite subtle ... doing this wrong incidentally can give more bytes - name = name or fullname - local code = loadfile(fullname) - if code then - code() - end - if forcestrip and luautilities.stripcode then - if type(forcestrip) == "function" then - forcestrip = forcestrip(fullname) - end - if forcestrip then - local code, n = strip_code_pc(dump(code,name)) - return loadstring(code), n + + function luautilities.loadedluacode(fullname,forcestrip,name) + -- quite subtle ... doing this wrong incidentally can give more bytes + name = name or fullname + local code = loadfile(fullname) + if code then + code() + end + if forcestrip and luautilities.stripcode then + if type(forcestrip) == "function" then + forcestrip = forcestrip(fullname) + end + if forcestrip then + local code, n = strip_code_pc(dump(code),name) + return loadstring(code), n + elseif luautilities.alwaysstripcode then + return loadstring(strip_code_pc(dump(code),name)) + else + return code, 0 + end elseif luautilities.alwaysstripcode then return loadstring(strip_code_pc(dump(code),name)) else return code, 0 end - elseif luautilities.alwaysstripcode then - return loadstring(strip_code_pc(dump(code),name)) - else - return code, 0 end -end -function luautilities.strippedloadstring(code,forcestrip,name) -- not executed - local n = 0 - if (forcestrip and luautilities.stripcode) or luautilities.alwaysstripcode then - code = loadstring(code) - if not code then - fatalerror(name) + function luautilities.strippedloadstring(code,forcestrip,name) -- not executed + local n = 0 + if (forcestrip and luautilities.stripcode) or luautilities.alwaysstripcode then + code = loadstring(code) + if not code then + fatalerror(name) + end + code, n = strip_code_pc(dump(code),name) end - code, n = strip_code_pc(dump(code),name) + return loadstring(code), n end - return loadstring(code), n -end -local function stupidcompile(luafile,lucfile,strip) - local code = io.loaddata(luafile) - local n = 0 - if code and code ~= "" then - code = loadstring(code) - if not code then - fatalerror() - end - code = dump(code) - if strip then - code, n = strippedbytecode(code,true,luafile) -- last one is reported - end + local function stupidcompile(luafile,lucfile,strip) + local code = io.loaddata(luafile) + local n = 0 if code and code ~= "" then - io.savedata(lucfile,code) + code = loadstring(code) + if not code then + fatalerror() + end + code = dump(code) + if strip then + code, n = strip_code_pc(code,luautilities.stripcode or luautilities.alwaysstripcode,luafile) -- last one is reported + end + if code and code ~= "" then + io.savedata(lucfile,code) + end end + return n end - return n -end -local luac_normal = "texluac -o %q %q" -local luac_strip = "texluac -s -o %q %q" + local luac_normal = "texluac -o %q %q" + local luac_strip = "texluac -s -o %q %q" -function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) -- defaults: cleanup=false strip=true - utilities.report("lua: compiling %s into %s",luafile,lucfile) - os.remove(lucfile) - local done = false - if strip ~= false then - strip = true - end - if forcestupidcompile then - fallback = true - elseif strip then - done = os.spawn(format(luac_strip, lucfile,luafile)) == 0 - else - done = os.spawn(format(luac_normal,lucfile,luafile)) == 0 - end - if not done and fallback then - local n = stupidcompile(luafile,lucfile,strip) - if n > 0 then - utilities.report("lua: %s dumped into %s (%i bytes stripped)",luafile,lucfile,n) + function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) -- defaults: cleanup=false strip=true + utilities.report("lua: compiling %s into %s",luafile,lucfile) + os.remove(lucfile) + local done = false + if strip ~= false then + strip = true + end + if forcestupidcompile then + fallback = true + elseif strip then + done = os.spawn(format(luac_strip, lucfile,luafile)) == 0 else - utilities.report("lua: %s dumped into %s (unstripped)",luafile,lucfile) + done = os.spawn(format(luac_normal,lucfile,luafile)) == 0 end - cleanup = false -- better see how bad it is - end - if done and cleanup == true and lfs.isfile(lucfile) and lfs.isfile(luafile) then - utilities.report("lua: removing %s",luafile) - os.remove(luafile) + if not done and fallback then + local n = stupidcompile(luafile,lucfile,strip) + if n > 0 then + utilities.report("lua: %s dumped into %s (%i bytes stripped)",luafile,lucfile,n) + else + utilities.report("lua: %s dumped into %s (unstripped)",luafile,lucfile) + end + cleanup = false -- better see how bad it is + end + if done and cleanup == true and lfs.isfile(lucfile) and lfs.isfile(luafile) then + utilities.report("lua: removing %s",luafile) + os.remove(luafile) + end + return done end - return done -end - - - - +end +-- local getmetatable, type = getmetatable, type +-- +-- local types = { } +-- +-- function luautilities.registerdatatype(d,name) +-- types[getmetatable(d)] = name +-- end +-- +-- function luautilities.datatype(d) +-- local t = type(d) +-- if t == "userdata" then +-- local m = getmetatable(d) +-- return m and types[m] or "userdata" +-- else +-- return t +-- end +-- end +-- +-- luautilities.registerdatatype(lpeg.P("!"),"lpeg") +-- +-- print(luautilities.datatype(lpeg.P("oeps"))) end -- of closure diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun index 3c03006a8..897c39260 100644 --- a/scripts/context/stubs/unix/mtxrun +++ b/scripts/context/stubs/unix/mtxrun @@ -5404,23 +5404,118 @@ luautilities.nofstrippedbytes = 0 local strippedchunks = { } -- allocate() luautilities.strippedchunks = strippedchunks +local function fatalerror(name) + utilities.report(format("fatal error in %q",name or "unknown")) +end --- The next function was posted by Peter Cawley on the lua list and strips line --- number information etc. from the bytecode data blob. We only apply this trick --- when we store data tables. Stripping makes the compressed format file about --- 1MB smaller (and uncompressed we save at least 6MB). --- --- You can consider this feature an experiment, so it might disappear. There is --- no noticeable gain in runtime although the memory footprint should be somewhat --- smaller (and the file system has a bit less to deal with). --- --- Begin of borrowed code ... works for Lua 5.1 which LuaTeX currently uses ... +if jit then -local strip_code_pc, strippedbytecode + local function register(name) + if tracestripping then + utilities.report("stripped bytecode: %s",name or "unknown") + end + strippedchunks[#strippedchunks+1] = name + luautilities.nofstrippedchunks = luautilities.nofstrippedchunks + 1 + end -if jit then + local function stupidcompile(luafile,lucfile,strip) + local code = io.loaddata(luafile) + if code and code ~= "" then + code = loadstring(code) + if code then + code = dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode) + if code and code ~= "" then + register(name) + io.savedata(lucfile,code) + return true, 0 + end + else + fatalerror() + end + else + fatalerror() + end + return false, 0 + end + + -- quite subtle ... doing this wrong incidentally can give more bytes + + function luautilities.loadedluacode(fullname,forcestrip,name) + -- quite subtle ... doing this wrong incidentally can give more bytes + name = name or fullname + local code = loadfile(fullname) + if code then + code() + end + if forcestrip and luautilities.stripcode then + if type(forcestrip) == "function" then + forcestrip = forcestrip(fullname) + end + if forcestrip or luautilities.alwaysstripcode then + register(name) + return loadstring(dump(code,true)), 0 + else + return code, 0 + end + elseif luautilities.alwaysstripcode then + register(name) + return loadstring(dump(code,true)), 0 + else + return code, 0 + end + end - strip_code_pc = function(dump,name) + function luautilities.strippedloadstring(code,forcestrip,name) -- not executed + if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then + code = loadstring(code) + if not code then + fatalerror(name) + end + register(name) + code = dump(code,true) + end + return loadstring(code), 0 + end + + function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) -- defaults: cleanup=false strip=true + utilities.report("lua: compiling %s into %s",luafile,lucfile) + os.remove(lucfile) + local done = stupidcompile(luafile,lucfile,strip ~= false) + if done then + utilities.report("lua: %s dumped into %s (stripped)",luafile,lucfile) + if cleanup == true and lfs.isfile(lucfile) and lfs.isfile(luafile) then + utilities.report("lua: removing %s",luafile) + os.remove(luafile) + end + end + return done + end + +else + + -- The next function was posted by Peter Cawley on the lua list and strips line + -- number information etc. from the bytecode data blob. We only apply this trick + -- when we store data tables. Stripping makes the compressed format file about + -- 1MB smaller (and uncompressed we save at least 6MB). + -- + -- You can consider this feature an experiment, so it might disappear. There is + -- no noticeable gain in runtime although the memory footprint should be somewhat + -- smaller (and the file system has a bit less to deal with). + -- + -- Begin of borrowed code ... works for Lua 5.1 which LuaTeX currently uses ... + + local function register(name,before,after) + local delta = before - after + if tracestripping then + utilities.report("stripped bytecode: %s, before %s, after %s, delta %s",name or "unknown",before,after,delta) + end + strippedchunks[#strippedchunks+1] = name + luautilities.nofstrippedchunks = luautilities.nofstrippedchunks + 1 + luautilities.nofstrippedbytes = luautilities.nofstrippedbytes + delta + return delta + end + + local function strip_code_pc(dump,name) local before = #dump local version, format, endian, int, size, ins, num = byte(dump,5,11) local subint @@ -5479,138 +5574,127 @@ if jit then end dump = sub(dump,1,12) .. strip_function(sub(dump,13,-1)) local after = #dump - local delta = before-after - if tracestripping then - utilities.report("stripped bytecode: %s, before %s, after %s, delta %s",name or "unknown",before,after,delta) - end - strippedchunks[#strippedchunks+1] = name - luautilities.nofstrippedchunks = luautilities.nofstrippedchunks + 1 - luautilities.nofstrippedbytes = luautilities.nofstrippedbytes + delta + local delta = register(name,before,after) return dump, delta end -- ... end of borrowed code. - strippedbytecode = function(code,forcestrip,name) - if (forcestrip and luautilities.stripcode) or luautilities.alwaysstripcode then - return strip_code_pc(code,name) - else - return code, 0 - end - end - -else - - strip_code_pc = function(str) return str, 0 end - strippedbytecode = strip_code_pc - -end - -luautilities.stripbytecode = strip_code_pc -luautilities.strippedbytecode = strippedbytecode - -local function fatalerror(name) - utilities.report(format("fatal error in %q",name or "unknown")) -end - --- quite subtle ... doing this wrong incidentally can give more bytes - - -function luautilities.loadedluacode(fullname,forcestrip,name) -- quite subtle ... doing this wrong incidentally can give more bytes - name = name or fullname - local code = loadfile(fullname) - if code then - code() - end - if forcestrip and luautilities.stripcode then - if type(forcestrip) == "function" then - forcestrip = forcestrip(fullname) - end - if forcestrip then - local code, n = strip_code_pc(dump(code,name)) - return loadstring(code), n + + function luautilities.loadedluacode(fullname,forcestrip,name) + -- quite subtle ... doing this wrong incidentally can give more bytes + name = name or fullname + local code = loadfile(fullname) + if code then + code() + end + if forcestrip and luautilities.stripcode then + if type(forcestrip) == "function" then + forcestrip = forcestrip(fullname) + end + if forcestrip then + local code, n = strip_code_pc(dump(code),name) + return loadstring(code), n + elseif luautilities.alwaysstripcode then + return loadstring(strip_code_pc(dump(code),name)) + else + return code, 0 + end elseif luautilities.alwaysstripcode then return loadstring(strip_code_pc(dump(code),name)) else return code, 0 end - elseif luautilities.alwaysstripcode then - return loadstring(strip_code_pc(dump(code),name)) - else - return code, 0 end -end -function luautilities.strippedloadstring(code,forcestrip,name) -- not executed - local n = 0 - if (forcestrip and luautilities.stripcode) or luautilities.alwaysstripcode then - code = loadstring(code) - if not code then - fatalerror(name) + function luautilities.strippedloadstring(code,forcestrip,name) -- not executed + local n = 0 + if (forcestrip and luautilities.stripcode) or luautilities.alwaysstripcode then + code = loadstring(code) + if not code then + fatalerror(name) + end + code, n = strip_code_pc(dump(code),name) end - code, n = strip_code_pc(dump(code),name) + return loadstring(code), n end - return loadstring(code), n -end -local function stupidcompile(luafile,lucfile,strip) - local code = io.loaddata(luafile) - local n = 0 - if code and code ~= "" then - code = loadstring(code) - if not code then - fatalerror() - end - code = dump(code) - if strip then - code, n = strippedbytecode(code,true,luafile) -- last one is reported - end + local function stupidcompile(luafile,lucfile,strip) + local code = io.loaddata(luafile) + local n = 0 if code and code ~= "" then - io.savedata(lucfile,code) + code = loadstring(code) + if not code then + fatalerror() + end + code = dump(code) + if strip then + code, n = strip_code_pc(code,luautilities.stripcode or luautilities.alwaysstripcode,luafile) -- last one is reported + end + if code and code ~= "" then + io.savedata(lucfile,code) + end end + return n end - return n -end -local luac_normal = "texluac -o %q %q" -local luac_strip = "texluac -s -o %q %q" + local luac_normal = "texluac -o %q %q" + local luac_strip = "texluac -s -o %q %q" -function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) -- defaults: cleanup=false strip=true - utilities.report("lua: compiling %s into %s",luafile,lucfile) - os.remove(lucfile) - local done = false - if strip ~= false then - strip = true - end - if forcestupidcompile then - fallback = true - elseif strip then - done = os.spawn(format(luac_strip, lucfile,luafile)) == 0 - else - done = os.spawn(format(luac_normal,lucfile,luafile)) == 0 - end - if not done and fallback then - local n = stupidcompile(luafile,lucfile,strip) - if n > 0 then - utilities.report("lua: %s dumped into %s (%i bytes stripped)",luafile,lucfile,n) + function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) -- defaults: cleanup=false strip=true + utilities.report("lua: compiling %s into %s",luafile,lucfile) + os.remove(lucfile) + local done = false + if strip ~= false then + strip = true + end + if forcestupidcompile then + fallback = true + elseif strip then + done = os.spawn(format(luac_strip, lucfile,luafile)) == 0 else - utilities.report("lua: %s dumped into %s (unstripped)",luafile,lucfile) + done = os.spawn(format(luac_normal,lucfile,luafile)) == 0 end - cleanup = false -- better see how bad it is - end - if done and cleanup == true and lfs.isfile(lucfile) and lfs.isfile(luafile) then - utilities.report("lua: removing %s",luafile) - os.remove(luafile) + if not done and fallback then + local n = stupidcompile(luafile,lucfile,strip) + if n > 0 then + utilities.report("lua: %s dumped into %s (%i bytes stripped)",luafile,lucfile,n) + else + utilities.report("lua: %s dumped into %s (unstripped)",luafile,lucfile) + end + cleanup = false -- better see how bad it is + end + if done and cleanup == true and lfs.isfile(lucfile) and lfs.isfile(luafile) then + utilities.report("lua: removing %s",luafile) + os.remove(luafile) + end + return done end - return done -end - - - - +end +-- local getmetatable, type = getmetatable, type +-- +-- local types = { } +-- +-- function luautilities.registerdatatype(d,name) +-- types[getmetatable(d)] = name +-- end +-- +-- function luautilities.datatype(d) +-- local t = type(d) +-- if t == "userdata" then +-- local m = getmetatable(d) +-- return m and types[m] or "userdata" +-- else +-- return t +-- end +-- end +-- +-- luautilities.registerdatatype(lpeg.P("!"),"lpeg") +-- +-- print(luautilities.datatype(lpeg.P("oeps"))) end -- of closure diff --git a/tex/context/base/cont-new.mkii b/tex/context/base/cont-new.mkii index 40af090f9..e2e20d643 100644 --- a/tex/context/base/cont-new.mkii +++ b/tex/context/base/cont-new.mkii @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2012.11.22 14:55} +\newcontextversion{2012.11.22 17:45} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv index cd705db36..7fb3d7c79 100644 --- a/tex/context/base/cont-new.mkiv +++ b/tex/context/base/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2012.11.22 14:55} +\newcontextversion{2012.11.22 17:45} %D This file is loaded at runtime, thereby providing an excellent place for %D hacks, patches, extensions and new features. diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf index 7193df418..431381226 100644 Binary files a/tex/context/base/context-version.pdf and b/tex/context/base/context-version.pdf differ diff --git a/tex/context/base/context-version.png b/tex/context/base/context-version.png index d40f681be..25a9b6fea 100644 Binary files a/tex/context/base/context-version.png and b/tex/context/base/context-version.png differ diff --git a/tex/context/base/context.mkii b/tex/context/base/context.mkii index 3060c6534..21f99c291 100644 --- a/tex/context/base/context.mkii +++ b/tex/context/base/context.mkii @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2012.11.22 14:55} +\edef\contextversion{2012.11.22 17:45} %D For those who want to use this: diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv index f2c50f11f..40758d4c3 100644 --- a/tex/context/base/context.mkiv +++ b/tex/context/base/context.mkiv @@ -25,7 +25,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2012.11.22 14:55} +\edef\contextversion{2012.11.22 17:45} %D For those who want to use this: diff --git a/tex/context/base/luat-sto.lua b/tex/context/base/luat-sto.lua index a9952ceb9..6ebfbab98 100644 --- a/tex/context/base/luat-sto.lua +++ b/tex/context/base/luat-sto.lua @@ -117,14 +117,23 @@ statistics.register("stored bytecode data", function() local tofmodules = storage.tofmodules or 0 local tofdumps = storage.toftables or 0 if environment.initex then - local luautilities = utilities.lua - if luautilities.nofstrippedbytes > 0 then - -- print(concat(luautilities.strippedchunks," ")) - return format("%s modules, %s tables, %s chunks, %s bytes stripped (%s chunks)", + local luautilities = utilities.lua + local nofstrippedbytes = luautilities.nofstrippedbytes + local nofstrippedchunks = luautilities.nofstrippedchunks + if nofstrippedbytes > 0 then + return format("%s modules, %s tables, %s chunks, %s chunks stripped (%s bytes)", nofmodules, nofdumps, nofmodules + nofdumps, - luautilities.nofstrippedbytes, luautilities.nofstrippedchunks + nofstrippedchunks, + nofstrippedbytes + ) + elseif nofstrippedchunks > 0 then + return format("%s modules, %s tables, %s chunks, %s chunks stripped", + nofmodules, + nofdumps, + nofmodules + nofdumps, + nofstrippedchunks ) else return format("%s modules, %s tables, %s chunks", diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf index d15bd8eb1..00e218eee 100644 Binary files a/tex/context/base/status-files.pdf and b/tex/context/base/status-files.pdf differ diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf index f6452600f..06def773d 100644 Binary files a/tex/context/base/status-lua.pdf and b/tex/context/base/status-lua.pdf differ diff --git a/tex/context/base/util-lua.lua b/tex/context/base/util-lua.lua index e21f2587e..df69bba0e 100644 --- a/tex/context/base/util-lua.lua +++ b/tex/context/base/util-lua.lua @@ -25,23 +25,118 @@ luautilities.nofstrippedbytes = 0 local strippedchunks = { } -- allocate() luautilities.strippedchunks = strippedchunks +local function fatalerror(name) + utilities.report(format("fatal error in %q",name or "unknown")) +end --- The next function was posted by Peter Cawley on the lua list and strips line --- number information etc. from the bytecode data blob. We only apply this trick --- when we store data tables. Stripping makes the compressed format file about --- 1MB smaller (and uncompressed we save at least 6MB). --- --- You can consider this feature an experiment, so it might disappear. There is --- no noticeable gain in runtime although the memory footprint should be somewhat --- smaller (and the file system has a bit less to deal with). --- --- Begin of borrowed code ... works for Lua 5.1 which LuaTeX currently uses ... +if jit then -local strip_code_pc, strippedbytecode + local function register(name) + if tracestripping then + utilities.report("stripped bytecode: %s",name or "unknown") + end + strippedchunks[#strippedchunks+1] = name + luautilities.nofstrippedchunks = luautilities.nofstrippedchunks + 1 + end -if jit then + local function stupidcompile(luafile,lucfile,strip) + local code = io.loaddata(luafile) + if code and code ~= "" then + code = loadstring(code) + if code then + code = dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode) + if code and code ~= "" then + register(name) + io.savedata(lucfile,code) + return true, 0 + end + else + fatalerror() + end + else + fatalerror() + end + return false, 0 + end + + -- quite subtle ... doing this wrong incidentally can give more bytes - strip_code_pc = function(dump,name) + function luautilities.loadedluacode(fullname,forcestrip,name) + -- quite subtle ... doing this wrong incidentally can give more bytes + name = name or fullname + local code = loadfile(fullname) + if code then + code() + end + if forcestrip and luautilities.stripcode then + if type(forcestrip) == "function" then + forcestrip = forcestrip(fullname) + end + if forcestrip or luautilities.alwaysstripcode then + register(name) + return loadstring(dump(code,true)), 0 + else + return code, 0 + end + elseif luautilities.alwaysstripcode then + register(name) + return loadstring(dump(code,true)), 0 + else + return code, 0 + end + end + + function luautilities.strippedloadstring(code,forcestrip,name) -- not executed + if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then + code = loadstring(code) + if not code then + fatalerror(name) + end + register(name) + code = dump(code,true) + end + return loadstring(code), 0 + end + + function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) -- defaults: cleanup=false strip=true + utilities.report("lua: compiling %s into %s",luafile,lucfile) + os.remove(lucfile) + local done = stupidcompile(luafile,lucfile,strip ~= false) + if done then + utilities.report("lua: %s dumped into %s (stripped)",luafile,lucfile) + if cleanup == true and lfs.isfile(lucfile) and lfs.isfile(luafile) then + utilities.report("lua: removing %s",luafile) + os.remove(luafile) + end + end + return done + end + +else + + -- The next function was posted by Peter Cawley on the lua list and strips line + -- number information etc. from the bytecode data blob. We only apply this trick + -- when we store data tables. Stripping makes the compressed format file about + -- 1MB smaller (and uncompressed we save at least 6MB). + -- + -- You can consider this feature an experiment, so it might disappear. There is + -- no noticeable gain in runtime although the memory footprint should be somewhat + -- smaller (and the file system has a bit less to deal with). + -- + -- Begin of borrowed code ... works for Lua 5.1 which LuaTeX currently uses ... + + local function register(name,before,after) + local delta = before - after + if tracestripping then + utilities.report("stripped bytecode: %s, before %s, after %s, delta %s",name or "unknown",before,after,delta) + end + strippedchunks[#strippedchunks+1] = name + luautilities.nofstrippedchunks = luautilities.nofstrippedchunks + 1 + luautilities.nofstrippedbytes = luautilities.nofstrippedbytes + delta + return delta + end + + local function strip_code_pc(dump,name) local before = #dump local version, format, endian, int, size, ins, num = byte(dump,5,11) local subint @@ -100,151 +195,124 @@ if jit then end dump = sub(dump,1,12) .. strip_function(sub(dump,13,-1)) local after = #dump - local delta = before-after - if tracestripping then - utilities.report("stripped bytecode: %s, before %s, after %s, delta %s",name or "unknown",before,after,delta) - end - strippedchunks[#strippedchunks+1] = name - luautilities.nofstrippedchunks = luautilities.nofstrippedchunks + 1 - luautilities.nofstrippedbytes = luautilities.nofstrippedbytes + delta + local delta = register(name,before,after) return dump, delta end -- ... end of borrowed code. - strippedbytecode = function(code,forcestrip,name) - if (forcestrip and luautilities.stripcode) or luautilities.alwaysstripcode then - return strip_code_pc(code,name) - else - return code, 0 - end - end - -else - - strip_code_pc = function(str) return str, 0 end - strippedbytecode = strip_code_pc - -end - -luautilities.stripbytecode = strip_code_pc -luautilities.strippedbytecode = strippedbytecode - -local function fatalerror(name) - utilities.report(format("fatal error in %q",name or "unknown")) -end - --- quite subtle ... doing this wrong incidentally can give more bytes - - -function luautilities.loadedluacode(fullname,forcestrip,name) -- quite subtle ... doing this wrong incidentally can give more bytes - name = name or fullname - local code = loadfile(fullname) - if code then - code() - end - if forcestrip and luautilities.stripcode then - if type(forcestrip) == "function" then - forcestrip = forcestrip(fullname) + + function luautilities.loadedluacode(fullname,forcestrip,name) + -- quite subtle ... doing this wrong incidentally can give more bytes + name = name or fullname + local code = loadfile(fullname) + if code then + code() end - if forcestrip then - local code, n = strip_code_pc(dump(code,name)) - return loadstring(code), n + if forcestrip and luautilities.stripcode then + if type(forcestrip) == "function" then + forcestrip = forcestrip(fullname) + end + if forcestrip then + local code, n = strip_code_pc(dump(code),name) + return loadstring(code), n + elseif luautilities.alwaysstripcode then + return loadstring(strip_code_pc(dump(code),name)) + else + return code, 0 + end elseif luautilities.alwaysstripcode then return loadstring(strip_code_pc(dump(code),name)) else return code, 0 end - elseif luautilities.alwaysstripcode then - return loadstring(strip_code_pc(dump(code),name)) - else - return code, 0 end -end -function luautilities.strippedloadstring(code,forcestrip,name) -- not executed - local n = 0 - if (forcestrip and luautilities.stripcode) or luautilities.alwaysstripcode then - code = loadstring(code) - if not code then - fatalerror(name) + function luautilities.strippedloadstring(code,forcestrip,name) -- not executed + local n = 0 + if (forcestrip and luautilities.stripcode) or luautilities.alwaysstripcode then + code = loadstring(code) + if not code then + fatalerror(name) + end + code, n = strip_code_pc(dump(code),name) end - code, n = strip_code_pc(dump(code),name) + return loadstring(code), n end - return loadstring(code), n -end -local function stupidcompile(luafile,lucfile,strip) - local code = io.loaddata(luafile) - local n = 0 - if code and code ~= "" then - code = loadstring(code) - if not code then - fatalerror() - end - code = dump(code) - if strip then - code, n = strippedbytecode(code,true,luafile) -- last one is reported - end + local function stupidcompile(luafile,lucfile,strip) + local code = io.loaddata(luafile) + local n = 0 if code and code ~= "" then - io.savedata(lucfile,code) + code = loadstring(code) + if not code then + fatalerror() + end + code = dump(code) + if strip then + code, n = strip_code_pc(code,luautilities.stripcode or luautilities.alwaysstripcode,luafile) -- last one is reported + end + if code and code ~= "" then + io.savedata(lucfile,code) + end end + return n end - return n -end -local luac_normal = "texluac -o %q %q" -local luac_strip = "texluac -s -o %q %q" + local luac_normal = "texluac -o %q %q" + local luac_strip = "texluac -s -o %q %q" -function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) -- defaults: cleanup=false strip=true - utilities.report("lua: compiling %s into %s",luafile,lucfile) - os.remove(lucfile) - local done = false - if strip ~= false then - strip = true - end - if forcestupidcompile then - fallback = true - elseif strip then - done = os.spawn(format(luac_strip, lucfile,luafile)) == 0 - else - done = os.spawn(format(luac_normal,lucfile,luafile)) == 0 - end - if not done and fallback then - local n = stupidcompile(luafile,lucfile,strip) - if n > 0 then - utilities.report("lua: %s dumped into %s (%i bytes stripped)",luafile,lucfile,n) + function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) -- defaults: cleanup=false strip=true + utilities.report("lua: compiling %s into %s",luafile,lucfile) + os.remove(lucfile) + local done = false + if strip ~= false then + strip = true + end + if forcestupidcompile then + fallback = true + elseif strip then + done = os.spawn(format(luac_strip, lucfile,luafile)) == 0 else - utilities.report("lua: %s dumped into %s (unstripped)",luafile,lucfile) + done = os.spawn(format(luac_normal,lucfile,luafile)) == 0 end - cleanup = false -- better see how bad it is - end - if done and cleanup == true and lfs.isfile(lucfile) and lfs.isfile(luafile) then - utilities.report("lua: removing %s",luafile) - os.remove(luafile) + if not done and fallback then + local n = stupidcompile(luafile,lucfile,strip) + if n > 0 then + utilities.report("lua: %s dumped into %s (%i bytes stripped)",luafile,lucfile,n) + else + utilities.report("lua: %s dumped into %s (unstripped)",luafile,lucfile) + end + cleanup = false -- better see how bad it is + end + if done and cleanup == true and lfs.isfile(lucfile) and lfs.isfile(luafile) then + utilities.report("lua: removing %s",luafile) + os.remove(luafile) + end + return done end - return done -end - ---~ local getmetatable, type = getmetatable, type - ---~ local types = { } - ---~ function luautilities.registerdatatype(d,name) ---~ types[getmetatable(d)] = name ---~ end - ---~ function luautilities.datatype(d) ---~ local t = type(d) ---~ if t == "userdata" then ---~ local m = getmetatable(d) ---~ return m and types[m] or "userdata" ---~ else ---~ return t ---~ end ---~ end ---~ luautilities.registerdatatype(lpeg.P("!"),"lpeg") +end ---~ print(luautilities.datatype(lpeg.P("oeps"))) +-- local getmetatable, type = getmetatable, type +-- +-- local types = { } +-- +-- function luautilities.registerdatatype(d,name) +-- types[getmetatable(d)] = name +-- end +-- +-- function luautilities.datatype(d) +-- local t = type(d) +-- if t == "userdata" then +-- local m = getmetatable(d) +-- return m and types[m] or "userdata" +-- else +-- return t +-- end +-- end +-- +-- luautilities.registerdatatype(lpeg.P("!"),"lpeg") +-- +-- print(luautilities.datatype(lpeg.P("oeps"))) diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 68ef3450d..835d60321 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : luatex-fonts-merged.lua -- parent file : luatex-fonts.lua --- merge date : 11/22/12 14:55:44 +-- merge date : 11/22/12 17:45:27 do -- begin closure to overcome local limits and interference -- cgit v1.2.3