diff --git a/README.md b/README.md index 6413447..d789e0f 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Just put it in a `jit/` directory within `package.path` or `$LUA_PATH`, typicall **`-jloom[=[,]]`** -`` is a template file (default `'loom.html'`) and `` is an output file name (default `io.stdout`). +`` is a template file and `` is an output file name (default `io.stdout`). Lua API === @@ -44,7 +44,7 @@ That is, both return values (the `traces` and `funcs` arrays) are passed to the **`loom.start(tmpl, out)`** -Implements the `-jloom[=tmpl[,out]]` option. The `tmpl` argument is passed to `loom.template()` to create a reporting function. If omitted, defaults to `'loom.html'`. The `out` parameter is either a writeable open file or a file name where the report is written into (after formatting by the template), defaults to `io.stdout`. When the Lua VM is terminated normally, `loom.off()` is called with the reporting function created by the given template., +Implements the `-jloom[=tmpl[,out]]` option. The `tmpl` argument is passed to `loom.template()` to create a reporting function. If omitted, the default template will be used. The `out` parameter is either a writeable open file or a file name where the report is written into (after formatting by the template), defaults to `io.stdout`. When the Lua VM is terminated normally, `loom.off()` is called with the reporting function created by the given template., ### Utility Functions @@ -100,7 +100,7 @@ Defines template argument names. Each `name` must be a valid Lua variable name Included Template === -The included `loom.html` template renders the trace report as an HTML document. It's divided in two sections: a Sourcecode -> Bytecode -> Traces one, and a list of traces, with the Bytecode -> IR -> mcode progression for each one. +The included template renders the trace report as an HTML document. It's divided in two sections: a Sourcecode -> Bytecode -> Traces one, and a list of traces, with the Bytecode -> IR -> mcode progression for each one. 1.- Source list --- diff --git a/jit/loom.lua b/jit/loom.lua index ec41b79..9966b37 100644 --- a/jit/loom.lua +++ b/jit/loom.lua @@ -895,7 +895,256 @@ do end -------------------------------------- +-------------------------------------- +local loom_html = [[ + + + {@ traces, funcs} + {% + local loom = require 'jit.loom' + local function class(t) + if not t then return '' end + o = {} + for k, v in pairs(t) do + if v then o[#o+1] = k end + end + if #o == 0 then return '' end + return 'class="'..table.concat(o, ' ')..'"' + end + + local _ft_, _fndx_ = {}, 0 + local function funclabel(f) + if not f then return '' end + if _ft_[f] == nil then + _fndx_ = _fndx_+1 + _ft_[f] = ('fn%03d'):format(_fndx_) + end + return _ft_[f] + end + + local function lines(s) + s = s or '' + local o = {} + for l in s:gmatch('[^\r\n]+') do + o[#o+1] = l + end + return o + end + + local function cols(s, cwl) + local o, start = {}, 1 + for i, w in ipairs(cwl) do + o[i] = s:sub(start, start+w-1):gsub('%s+$', '') + start = start+w + end + return o + end + + local function is_irref(f) + if f:match('^%d%d%d%d$') then + return 'ref_'..f + end + end + + local function all_refs(s) + c = {} + for ref in s:gmatch('%d+') do + c[#c+1] = is_irref(ref) + end + return table.concat(c, ' ') + end + + local function table_ir(txt) + local o = lines(txt) + local cwl = {5, 6, 3, 4, 7, 6, 1000} + for i, l in ipairs(o) do + l = cols(l, cwl) + local class = {is_irref(l[1])} + if l[5] == 'SNAP' then + class[#class+1] = 'snap_'..l[6]:sub(2) + l.title = l[7] + l[7] = ('%s'):format(l[7]) + end + l.class = next(class) and table.concat(class, ' ') + o[i] = l + end + return o + end + + local function annot_mcode(txt) + if type(txt) ~= 'string' then return '' end + txt = txt:gsub('%(exit (%d+)/(%d+)%)', function (a, b) + a, b = tonumber(a), tonumber(b) + return ('(exit %d/%d [n=%d])'):format(a, b, traces[a].exits[b] or 0) + end) + txt = _e(txt) + txt = txt:gsub('Trace #(%d+)', function (tr) + return ('Trace #%d'):format( + tr, tr) + end) + return txt + end + + local cmdline = '' + do + local minarg, maxarg = 1000,-1000 + for k in pairs(arg) do + if type(k) == 'number' then + minarg = math.min(k, minarg) + maxarg = math.max(k, maxarg) + end + end + local newarg = {} + for i = minarg, maxarg do + local v = tostring(arg[i]) + if v:find('[^%w.,/=_-]') then + v = ('%q'):format(v) + end + newarg[i] = v + end + cmdline = table.concat(newarg, ' ', minarg, maxarg) + end + + local annotated = loom.annotated(funcs, traces) + %} + + + + + + {{cmdline}} + + +

{{=cmdline:gsub('\\[\r\n]+',"
")}}

+ + {% for filename, filedata in pairs(annotated) do + local lastline + %} + + + + + {% for i, l in loom.sortedpairs(filedata) do + local notsame = l.i ~= lastline + lastline = l.i + %} + + + + + + + + {% end %} + {% end %} +
{{ filename }}Bytecode
{{ notsame and l.i or '' }} {{ notsame and l.src or '' }} {{ l.bc }} {% for i, tr in ipairs(l.tr or {}) do + local trref = ('tr%03d'):format(tr[1]) + local lnref = ('tr%03d_%03d'):format(tr[1], tr[2]) + %} {{tr[1]}}/{{tr[2]}} {% + end %}{% for msg, n in pairs(l.evt or {}) do + %} "{{msg}}" [n={{n}}] {% + end %}
+ + {% for i, tr in loom.allipairs(traces) do local prevsrc%} +
+ + + + + + + + + + + + + + + + {% end %} + + +]] + + +-------------------------------------- local defer return { @@ -903,7 +1152,7 @@ return { off = loomstop, start = function (opt, out) - local tmpl = template(opt or 'loom.html') + local tmpl = template(opt or loom_html) defer = newproxy(true) getmetatable(defer).__gc = function() xpcall(function () local o = loomstop(tmpl) diff --git a/loom.html b/loom.html deleted file mode 100644 index 4c1b3ec..0000000 --- a/loom.html +++ /dev/null @@ -1,244 +0,0 @@ - - - {@ traces, funcs} - {% - local loom = require 'jit.loom' - local function class(t) - if not t then return '' end - o = {} - for k, v in pairs(t) do - if v then o[#o+1] = k end - end - if #o == 0 then return '' end - return 'class="'..table.concat(o, ' ')..'"' - end - - local _ft_, _fndx_ = {}, 0 - local function funclabel(f) - if not f then return '' end - if _ft_[f] == nil then - _fndx_ = _fndx_+1 - _ft_[f] = ('fn%03d'):format(_fndx_) - end - return _ft_[f] - end - - local function lines(s) - s = s or '' - local o = {} - for l in s:gmatch('[^\r\n]+') do - o[#o+1] = l - end - return o - end - - local function cols(s, cwl) - local o, start = {}, 1 - for i, w in ipairs(cwl) do - o[i] = s:sub(start, start+w-1):gsub('%s+$', '') - start = start+w - end - return o - end - - local function is_irref(f) - if f:match('^%d%d%d%d$') then - return 'ref_'..f - end - end - - local function all_refs(s) - c = {} - for ref in s:gmatch('%d+') do - c[#c+1] = is_irref(ref) - end - return table.concat(c, ' ') - end - - local function table_ir(txt) - local o = lines(txt) - local cwl = {5, 6, 3, 4, 7, 6, 1000} - for i, l in ipairs(o) do - l = cols(l, cwl) - local class = {is_irref(l[1])} - if l[5] == 'SNAP' then - class[#class+1] = 'snap_'..l[6]:sub(2) - l.title = l[7] - l[7] = ('%s'):format(l[7]) - end - l.class = next(class) and table.concat(class, ' ') - o[i] = l - end - return o - end - - local function annot_mcode(txt) - if type(txt) ~= 'string' then return '' end - txt = txt:gsub('%(exit (%d+)/(%d+)%)', function (a, b) - a, b = tonumber(a), tonumber(b) - return ('(exit %d/%d [n=%d])'):format(a, b, traces[a].exits[b] or 0) - end) - txt = _e(txt) - txt = txt:gsub('Trace #(%d+)', function (tr) - return ('Trace #%d'):format( - tr, tr) - end) - return txt - end - - local cmdline = '' - do - local minarg, maxarg = 1000,-1000 - for k in pairs(arg) do - if type(k) == 'number' then - minarg = math.min(k, minarg) - maxarg = math.max(k, maxarg) - end - end - local newarg = {} - for i = minarg, maxarg do - local v = tostring(arg[i]) - if v:find('[^%w.,/=_-]') then - v = ('%q'):format(v) - end - newarg[i] = v - end - cmdline = table.concat(newarg, ' ', minarg, maxarg) - end - - local annotated = loom.annotated(funcs, traces) - %} - - - - - - {{cmdline}} - - -

{{=cmdline:gsub('\\[\r\n]+',"
")}}

- - {% for filename, filedata in pairs(annotated) do - local lastline - %} - - - - - {% for i, l in loom.sortedpairs(filedata) do - local notsame = l.i ~= lastline - lastline = l.i - %} - - - - - - - - {% end %} - {% end %} -
{{ filename }}Bytecode
{{ notsame and l.i or '' }} {{ notsame and l.src or '' }} {{ l.bc }} {% for i, tr in ipairs(l.tr or {}) do - local trref = ('tr%03d'):format(tr[1]) - local lnref = ('tr%03d_%03d'):format(tr[1], tr[2]) - %} {{tr[1]}}/{{tr[2]}} {% - end %}{% for msg, n in pairs(l.evt or {}) do - %} "{{msg}}" [n={{n}}] {% - end %}
- - {% for i, tr in loom.allipairs(traces) do local prevsrc%} -
- - - - - - - - - - - - - - - - {% end %} - -