diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/node-res.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/node-res.lua | 288 |
1 files changed, 180 insertions, 108 deletions
diff --git a/Master/texmf-dist/tex/context/base/node-res.lua b/Master/texmf-dist/tex/context/base/node-res.lua index a8ea8745a72..7f737ea7040 100644 --- a/Master/texmf-dist/tex/context/base/node-res.lua +++ b/Master/texmf-dist/tex/context/base/node-res.lua @@ -7,38 +7,45 @@ if not modules then modules = { } end modules ['node-res'] = { } local gmatch, format = string.gmatch, string.format -local copy_node, free_node, free_list, new_node, node_type, node_id = node.copy, node.free, node.flush_list, node.new, node.type, node.id local tonumber, round = tonumber, math.round -local glyph_node = node_id("glyph") - --[[ldx-- <p>The next function is not that much needed but in <l n='context'/> we use for debugging <l n='luatex'/> node management.</p> --ldx]]-- -nodes = nodes or { } +local report_nodes = logs.reporter("nodes","housekeeping") -nodes.whatsits = { } -- table.swapped(node.whatsits()) +local nodes, node = nodes, node -local reserved = { } -local whatsits = nodes.whatsits +local copy_node = node.copy +local free_node = node.free +local free_list = node.flush_list +local new_node = node.new -for k, v in next, node.whatsits() do - whatsits[k], whatsits[v] = v, k -- two way -end +nodes.pool = nodes.pool or { } +local pool = nodes.pool + +local whatsitcodes = nodes.whatsitcodes +local skipcodes = nodes.skipcodes +local nodecodes = nodes.nodecodes + +local glyph_code = nodecodes.glyph + +local reserved, nofreserved = { }, 0 local function register_node(n) - reserved[#reserved+1] = n + nofreserved = nofreserved + 1 + reserved[nofreserved] = n return n end -nodes.register = register_node +pool.register = register_node -function nodes.cleanup_reserved(nofboxes) -- todo +function pool.cleanup(nofboxes) -- todo nodes.tracers.steppers.reset() -- todo: make a registration subsystem - local nr, nl = #reserved, 0 - for i=1,nr do + local nl, nr = 0, nofreserved + for i=1,nofreserved do local ri = reserved[i] -- if not (ri.id == glue_spec and not ri.is_writable) then free_node(reserved[i]) @@ -55,10 +62,11 @@ function nodes.cleanup_reserved(nofboxes) -- todo end end reserved = { } + nofreserved = 0 return nr, nl, nofboxes -- can be nil end -function nodes.usage() +function pool.usage() local t = { } for n, tag in gmatch(status.node_mem_usage,"(%d+) ([a-z_]+)") do t[tag] = n @@ -72,22 +80,23 @@ local penalty = register_node(new_node("penalty")) local glue = register_node(new_node("glue")) -- glue.spec = nil local glue_spec = register_node(new_node("glue_spec")) local glyph = register_node(new_node("glyph",0)) -local textdir = register_node(new_node("whatsit",whatsits.dir)) -- 7 (6 is local par node) +local textdir = register_node(new_node("whatsit",whatsitcodes.dir)) local rule = register_node(new_node("rule")) -local latelua = register_node(new_node("whatsit",whatsits.late_lua)) -- 35 -local user_n = register_node(new_node("whatsit",whatsits.user_defined)) user_n.type = 100 -- 44 -local user_l = register_node(new_node("whatsit",whatsits.user_defined)) user_l.type = 110 -- 44 -local user_s = register_node(new_node("whatsit",whatsits.user_defined)) user_s.type = 115 -- 44 -local user_t = register_node(new_node("whatsit",whatsits.user_defined)) user_t.type = 116 -- 44 +local latelua = register_node(new_node("whatsit",whatsitcodes.latelua)) +local user_n = register_node(new_node("whatsit",whatsitcodes.userdefined)) user_n.type = 100 -- 44 +local user_l = register_node(new_node("whatsit",whatsitcodes.userdefined)) user_l.type = 110 -- 44 +local user_s = register_node(new_node("whatsit",whatsitcodes.userdefined)) user_s.type = 115 -- 44 +local user_t = register_node(new_node("whatsit",whatsitcodes.userdefined)) user_t.type = 116 -- 44 local left_margin_kern = register_node(new_node("margin_kern",0)) local right_margin_kern = register_node(new_node("margin_kern",1)) -local lineskip = register_node(new_node("glue",1)) -local baselineskip = register_node(new_node("glue",2)) -local leftskip = register_node(new_node("glue",8)) -local rightskip = register_node(new_node("glue",9)) +local lineskip = register_node(new_node("glue",skipcodes.lineskip)) +local baselineskip = register_node(new_node("glue",skipcodes.baselineskip)) +local leftskip = register_node(new_node("glue",skipcodes.leftskip)) +local rightskip = register_node(new_node("glue",skipcodes.rightskip)) local temp = register_node(new_node("temp",0)) +local noad = register_node(new_node("noad")) -function nodes.zeroglue(n) +function pool.zeroglue(n) local s = n.spec return not writable or ( s.width == 0 @@ -98,38 +107,46 @@ function nodes.zeroglue(n) ) end -function nodes.glyph(fnt,chr) +function pool.glyph(fnt,chr) local n = copy_node(glyph) if fnt then n.font = fnt end if chr then n.char = chr end return n end -function nodes.penalty(p) +function pool.penalty(p) local n = copy_node(penalty) n.penalty = p return n end -function nodes.kern(k) +function pool.kern(k) local n = copy_node(kern) n.kern = k return n end -function nodes.glue_spec(width,stretch,shrink) +function pool.gluespec(width,stretch,shrink,stretch_order,shrink_order) local s = copy_node(glue_spec) - s.width, s.stretch, s.shrink = width, stretch, shrink + if width then s.width = width end + if stretch then s.stretch = stretch end + if shrink then s.shrink = shrink end + if stretch_order then s.stretch_order = stretch_order end + if shrink_order then s.shrink_order = shrink_order end return s end -local function someskip(skip,width,stretch,shrink) +local function someskip(skip,width,stretch,shrink,stretch_order,shrink_order) local n = copy_node(skip) if not width then -- no spec - elseif tonumber(width) then + elseif width == false or tonumber(width) then local s = copy_node(glue_spec) - s.width, s.stretch, s.shrink = width, stretch, shrink + if width then s.width = width end + if stretch then s.stretch = stretch end + if shrink then s.shrink = shrink end + if stretch_order then s.stretch_order = stretch_order end + if shrink_order then s.shrink_order = shrink_order end n.spec = s else -- shared @@ -138,33 +155,66 @@ local function someskip(skip,width,stretch,shrink) return n end -function nodes.glue(width,stretch,shrink) - return someskip(glue,width,stretch,shrink) +function pool.stretch(a,b) + local n = copy_node(glue) + local s = copy_node(glue_spec) + if b then + s.stretch = a + s.stretch_order = b + else + s.stretch = 1 + s.stretch_order = a or 1 + end + n.spec = s + return n end -function nodes.leftskip(width,stretch,shrink) - return someskip(leftskip,width,stretch,shrink) + +function pool.shrink(a,b) + local n = copy_node(glue) + local s = copy_node(glue_spec) + if b then + s.shrink = a + s.shrink_order = b + else + s.shrink = 1 + s.shrink_order = a or 1 + end + n.spec = s + return n end -function nodes.rightskip(width,stretch,shrink) - return someskip(rightskip,width,stretch,shrink) + + +function pool.glue(width,stretch,shrink,stretch_order,shrink_order) + return someskip(glue,width,stretch,shrink,stretch_order,shrink_order) +end + +function pool.leftskip(width,stretch,shrink,stretch_order,shrink_order) + return someskip(leftskip,width,stretch,shrink,stretch_order,shrink_order) end -function nodes.lineskip(width,stretch,shrink) - return someskip(lineskip,width,stretch,shrink) + +function pool.rightskip(width,stretch,shrink,stretch_order,shrink_order) + return someskip(rightskip,width,stretch,shrink,stretch_order,shrink_order) +end + +function pool.lineskip(width,stretch,shrink,stretch_order,shrink_order) + return someskip(lineskip,width,stretch,shrink,stretch_order,shrink_order) end -function nodes.baselineskip(width,stretch,shrink) + +function pool.baselineskip(width,stretch,shrink) return someskip(baselineskip,width,stretch,shrink) end -function nodes.disc() +function pool.disc() return copy_node(disc) end -function nodes.textdir(dir) +function pool.textdir(dir) local t = copy_node(textdir) t.dir = dir return t end -function nodes.rule(width,height,depth,dir) +function pool.rule(width,height,depth,dir) local n = copy_node(rule) if width then n.width = width end if height then n.height = height end @@ -173,18 +223,26 @@ function nodes.rule(width,height,depth,dir) return n end -function nodes.latelua(code) - local n = copy_node(latelua) - n.data = code - return n +if node.has_field(latelua,'string') then + function pool.latelua(code) + local n = copy_node(latelua) + n.string = code + return n + end +else + function pool.latelua(code) + local n = copy_node(latelua) + n.data = code + return n + end end -function nodes.leftmarginkern(glyph,width) +function pool.leftmarginkern(glyph,width) local n = copy_node(left_margin_kern) if not glyph then - logs.fatal("nodes","invalid pointer to left margin glyph node") - elseif glyph.id ~= glyph_node then - logs.fatal("nodes","invalid node type %s for left margin glyph node",node_type(glyph)) + report_nodes("invalid pointer to left margin glyph node") + elseif glyph.id ~= glyph_code then + report_nodes("invalid node type %s for left margin glyph node",nodecodes[glyph]) else n.glyph = glyph end @@ -194,12 +252,12 @@ function nodes.leftmarginkern(glyph,width) return n end -function nodes.rightmarginkern(glyph,width) +function pool.rightmarginkern(glyph,width) local n = copy_node(right_margin_kern) if not glyph then - logs.fatal("nodes","invalid pointer to right margin glyph node") - elseif glyph.id ~= glyph_node then - logs.fatal("nodes","invalid node type %s for right margin glyph node",node_type(p)) + report_nodes("invalid pointer to right margin glyph node") + elseif glyph.id ~= glyph_code then + report_nodes("invalid node type %s for right margin glyph node",nodecodes[p]) else n.glyph = glyph end @@ -209,9 +267,14 @@ function nodes.rightmarginkern(glyph,width) return n end -function nodes.temp() +function pool.temp() return copy_node(temp) end + +function pool.noad() + return copy_node(noad) +end + --[[ <p>At some point we ran into a problem that the glue specification of the zeropoint dimension was overwritten when adapting a glue spec @@ -225,78 +288,87 @@ and hide it for the user. And yes, LuaTeX now gives a warning as well.</p> ]]-- -if tex.luatexversion > 51 then - - function nodes.writable_spec(n) - local spec = n.spec - if not spec then - spec = copy_node(glue_spec) - n.spec = spec - elseif not spec.writable then - spec = copy_node(spec) - n.spec = spec - end - return spec +function nodes.writable_spec(n) -- not pool + local spec = n.spec + if not spec then + spec = copy_node(glue_spec) + n.spec = spec + elseif not spec.writable then + spec = copy_node(spec) + n.spec = spec end + return spec +end -else +-- local num = userids["my id"] +-- local str = userids[num] + +local userids = utilities.storage.allocate() pool.userids = userids +local lastid = 0 - function nodes.writable_spec(n) - local spec = n.spec - if not spec then - spec = copy_node(glue_spec) +setmetatable(userids, { + __index = function(t,k) + if type(k) == "string" then + lastid = lastid + 1 + rawset(userids,lastid,k) + rawset(userids,k,lastid) + return lastid else - spec = copy_node(spec) + rawset(userids,k,k) + return k end - n.spec = spec - return spec + end, + __call = function(t,k) + return t[k] end - -end - -local cache = { } - -function nodes.usernumber(num) - local n = cache[num] - if n then - return copy_node(n) - else - local n = copy_node(user_n) - if num then n.value = num end - return n +} ) + +function pool.usernumber(id,num) + local n = copy_node(user_n) + if num then + n.user_id, n.value = id, num + elseif id then + n.value = id end + return n end -function nodes.userlist(list) +function pool.userlist(id,list) local n = copy_node(user_l) - if list then n.value = list end + if list then + n.user_id, n.value =id, list + else + n.value = id + end return n end -local cache = { } -- we could use the same cache - -function nodes.userstring(str) - local n = cache[str] - if n then - return copy_node(n) +function pool.userstring(id,str) + local n = copy_node(user_s) + if str then + n.user_id, n.value =id, str else - local n = copy_node(user_s) - n.type = 115 - if str then n.value = str end - return n + n.value = id end + return n end -function nodes.usertokens(tokens) +function pool.usertokens(id,tokens) local n = copy_node(user_t) - if tokens then n.value = tokens end + if tokens then + n.user_id, n.value =id, tokens + else + n.value = id + end return n end statistics.register("cleaned up reserved nodes", function() - return format("%s nodes, %s lists of %s", nodes.cleanup_reserved(tex.count["lastallocatedbox"])) + return format("%s nodes, %s lists of %s", pool.cleanup(tex.count["lastallocatedbox"])) end) -- \topofboxstack statistics.register("node memory usage", function() -- comes after cleanup ! return status.node_mem_usage end) + +lua.registerfinalizer(pool.cleanup, "cleanup reserved nodes") |