OSDN Git Service

use getFOO/setFOO helpers instead of getfield/setfield
[luatex-ja/luatexja.git] / src / ltj-direction.lua
index 3dafb50..c564f87 100644 (file)
@@ -9,25 +9,30 @@ luatexja.direction = {}
 local attr_dir = luatexbase.attributes['ltj@dir']
 local attr_icflag = luatexbase.attributes['ltj@icflag']
 
+local dnode = node.direct
 local cat_lp = luatexbase.catcodetables['latex-package']
-local to_node = node.direct.tonode
-local to_direct = node.direct.todirect
-local has_attr = node.direct.has_attribute
-local set_attr = node.direct.set_attribute
-local insert_before = node.direct.insert_before
-local insert_after = node.direct.insert_after
-local getid = node.direct.getid
-local getsubtype = node.direct.getsubtype
-local getlist = node.direct.getlist
-local setfield = node.direct.setfield
-local getfield = node.direct.getfield
-local node_new = node.direct.new
-local node_tail = node.direct.tail
-local node_free = node.direct.free
-local node_remove = node.direct.remove
-local node_next = node.direct.getnext
-local traverse = node.direct.traverse
-local traverse_id = node.direct.traverse_id
+local to_node = dnode.tonode
+local to_direct = dnode.todirect
+local has_attr = dnode.has_attribute
+local set_attr = dnode.set_attribute
+local insert_before = dnode.insert_before
+local insert_after = dnode.insert_after
+local getid = dnode.getid
+local getsubtype = dnode.getsubtype
+local getlist = dnode.getlist
+local getfield = dnode.getfield
+local getwhd = dnode.getwhd
+local setfield = dnode.setfield
+local setwhd = dnode.setwhd
+local setnext = dnode.setnext
+local setlist = dnode.setlist
+
+local node_new = dnode.new
+local node_free = dnode.flush_node or dnode.free
+local node_remove = dnode.remove
+local node_next = dnode.getnext
+local traverse = dnode.traverse
+local traverse_id = dnode.traverse_id
 local start_time_measure, stop_time_measure
     = ltjb.start_time_measure, ltjb.stop_time_measure
 local abs = math.abs
@@ -37,8 +42,6 @@ local id_hlist   = node.id 'hlist'
 local id_vlist   = node.id 'vlist'
 local id_whatsit = node.id 'whatsit'
 local sid_save   = node.subtype 'pdf_save'
-local sid_restore= node.subtype 'pdf_restore'
-local sid_matrix = node.subtype 'pdf_setmatrix'
 local sid_user   = node.subtype 'user_defined'
 
 local tex_nest = tex.nest
@@ -63,14 +66,14 @@ local page_direction
 --
 local dir_pool
 do
-   local node_copy = node.direct.copy
+   local node_copy = dnode.copy
    dir_pool = {}
    for _,i in pairs({dir_tate, dir_yoko, dir_dtou, dir_utod}) do
       local w = node_new(id_whatsit, sid_user)
-      set_attr(w, attr_dir, i)
+      dnode.setattributelist(w, nil) 
+      set_attr(w, attr_dir, i); set_attr(w, attr_icflag, 0)
       setfield(w, 'user_id', DIR)
-      setfield(w, 'type', 110)
-      setfield(w, 'next', nil)
+      setfield(w, 'type', 110); setnext(w, nil)
       dir_pool[i] = function () return node_copy(w) end
    end
 end
@@ -221,7 +224,7 @@ do
                page_direction = v -- for first call of \yoko (in luatexja-core.sty)
             else
               if luatexja.debug then
-                luatexja.ext_show_node_list(node.direct.tonode(h),'>> ', texio.write_nl)
+                luatexja.ext_show_node_list(dnode.tonode(h),'>> ', texio.write_nl)
               end
               ltjb.package_error(
                  'luatexja',
@@ -283,7 +286,8 @@ do
          if hd  then
             for p in traverse_id(15, hd) do -- unset
                if get_box_dir(p, 0)==0 then
-                  setfield(p, 'head', create_dir_whatsit(getlist(p), 'fin_row', ltjs.list_dir))
+                  setfield(p, 'head', create_dir_whatsit(getfield(p, 'head'), 'fin_row', ltjs.list_dir))
+                  -- We cannot use setlist and getlist, since they don't support unset_node
                end
             end
             set_attr(hd, attr_icflag, PROCESSED_BEGIN_FLAG)
@@ -307,7 +311,7 @@ do
       -- start 側は ltj-debug.lua に
       local new_dir = ltjs.list_dir
       for line in traverse_id(id_hlist, to_direct(h)) do
-         setfield(line, 'head', create_dir_whatsit(getlist(line), gc, new_dir) )
+         setlist(line, create_dir_whatsit(getlist(line), gc, new_dir) )
       end
       ensure_tex_attr(attr_dir, 0)
       return h
@@ -351,7 +355,7 @@ do
          local n = node_next(hd)
          local w = create_dir_whatsit(hd, gc, ltjs.list_dir)
          -- move dir whatsit after hd
-         setfield(hd, 'next', w); setfield(w, 'next', n); 
+         setnext(hd, w); setnext(w, n)
          return hd
       else return create_dir_whatsit(hd, gc, ltjs.list_dir)
       end
@@ -361,6 +365,10 @@ end
 -- dir_node に包む方法を書いたテーブル
 local dir_node_aux
 do
+   local setkern = dnode.setkern
+   local setshift = dnode.setshift
+   local sid_restore= node.subtype 'pdf_restore'
+   local sid_matrix = node.subtype 'pdf_setmatrix'
    local floor = math.floor
    local get_h =function (w,h,d) return h end
    local get_d =function (w,h,d) return d end
@@ -372,6 +380,21 @@ do
    local get_w_neg =function (w,h,d) return -w end
    local get_w =function (w,h,d) return w end
    local zero = function() return 0 end
+   local function gen_kern(arg, b, w,h,d,dw,dh,dd)
+      local nn = node_new(id_kern)
+      setkern(nn, arg(w, h, d, dw, dh, dd)); return nn
+   end
+   local function gen_whatsit(arg)
+      return node_new(id_whatsit, arg)
+   end
+   local function gen_rotate(arg)
+      local nn = node_new(id_whatsit, sid_matrix)
+      setfield(nn, 'data', arg); return nn
+   end
+   local function gen_box(arg, b, w,h,d,dw,dh,dd)
+      local nn = b; setnext(b, nil)
+      setshift(nn, arg(w, h, d, dw, dh, dd)); return nn
+   end
    dir_node_aux = {
       [dir_yoko] = { -- yoko を
          [dir_tate] = { -- tate 中で組む
@@ -379,20 +402,20 @@ do
             height = get_w_half,
             depth  = get_w_half_rem,
             [id_hlist] = {
-               { 'whatsit', sid_save },
-               { 'rotate', '0 1 -1 0' },
-               { 'kern', function(w,h,d,nw,nh,nd) return -nd end },
-               { 'box' , get_h},
-               { 'kern', function(w,h,d,nw,nh,nd) return nd-w end },
-               { 'whatsit', sid_restore },
+               { gen_whatsit, sid_save },
+               { gen_rotate, '0 1 -1 0' },
+               { gen_kern, function(w,h,d,nw,nh,nd) return -nd end },
+               { gen_box , get_h},
+               { gen_kern, function(w,h,d,nw,nh,nd) return nd-w end },
+               { gen_whatsit, sid_restore },
             },
             [id_vlist] = {
-               { 'whatsit', sid_save },
-               { 'rotate', '0 1 -1 0' },
-               { 'kern' , zero },
-               { 'box' , function(w,h,d,nw,nh,nd) return -nh-nd end },
-               { 'kern', get_h_d_neg},
-               { 'whatsit', sid_restore },
+               { gen_whatsit, sid_save },
+               { gen_rotate, '0 1 -1 0' },
+               { gen_kern , zero },
+               { gen_box , function(w,h,d,nw,nh,nd) return -nh-nd end },
+               { gen_kern, get_h_d_neg},
+               { gen_whatsit, sid_restore },
             },
          },
          [dir_dtou] = { -- dtou 中で組む
@@ -400,19 +423,19 @@ do
             height = get_w,
             depth  = zero,
             [id_hlist] = {
-               { 'whatsit', sid_save },
-               { 'rotate', '0 -1 1 0' },
-               { 'kern', function(w,h,d,nw,nh,nd) return -nh end },
-               { 'box', get_d_neg },
-               { 'kern', function(w,h,d,nw,nh,nd) return nh-w end },
-               { 'whatsit', sid_restore },
+               { gen_whatsit, sid_save },
+               { gen_rotate, '0 -1 1 0' },
+               { gen_kern, function(w,h,d,nw,nh,nd) return -nh end },
+               { gen_box, get_d_neg },
+               { gen_kern, function(w,h,d,nw,nh,nd) return nh-w end },
+               { gen_whatsit, sid_restore },
             },
             [id_vlist] = {
-               { 'whatsit', sid_save },
-               { 'rotate', '0 -1 1 0' },
-               { 'kern', get_h_d_neg },
-               { 'box', zero },
-               { 'whatsit', sid_restore },
+               { gen_whatsit, sid_save },
+               { gen_rotate, '0 -1 1 0' },
+               { gen_kern, get_h_d_neg },
+               { gen_box, zero },
+               { gen_whatsit, sid_restore },
             },
          },
       },
@@ -422,19 +445,19 @@ do
             height = get_w,
             depth  = zero,
             [id_hlist] = {
-               { 'whatsit', sid_save },
-               { 'rotate', '0 -1 1 0' },
-               { 'kern', function (w,h,d,nw,nh,nd) return -nh end },
-               { 'box' , get_d_neg },
-               { 'kern', function (w,h,d,nw,nh,nd) return nh-w end },
-               { 'whatsit', sid_restore },
+               { gen_whatsit, sid_save },
+               { gen_rotate, '0 -1 1 0' },
+               { gen_kern, function (w,h,d,nw,nh,nd) return -nh end },
+               { gen_box , get_d_neg },
+               { gen_kern, function (w,h,d,nw,nh,nd) return nh-w end },
+               { gen_whatsit, sid_restore },
             },
             [id_vlist] = {
-               { 'whatsit', sid_save },
-               { 'rotate', '0 -1 1 0' },
-               { 'kern', get_h_d_neg },
-               { 'box', zero },
-               { 'whatsit', sid_restore },
+               { gen_whatsit, sid_save },
+               { gen_rotate, '0 -1 1 0' },
+               { gen_kern, get_h_d_neg },
+               { gen_box, zero },
+               { gen_whatsit, sid_restore },
             },
          },
          [dir_dtou] = { -- dtou 中で組む
@@ -442,18 +465,18 @@ do
             height = get_d,
             depth  = get_h,
             [id_hlist] = {
-               { 'whatsit', sid_save },
-               { 'rotate', '-1 0 0 -1' },
-               { 'kern', get_w_neg },
-               { 'box',  function (w,h,d,nw,nh,nd) return h-nd end },
-               { 'whatsit', sid_restore },
+               { gen_whatsit, sid_save },
+               { gen_rotate, '-1 0 0 -1' },
+               { gen_kern, get_w_neg },
+               { gen_box,  function (w,h,d,nw,nh,nd) return h-nd end },
+               { gen_whatsit, sid_restore },
             },
             [id_vlist] = {
-               { 'whatsit', sid_save },
-               { 'rotate', '-1 0 0 -1' },
-               { 'kern', get_h_d_neg },
-               { 'box', get_w_neg },
-               { 'whatsit', sid_restore },
+               { gen_whatsit, sid_save },
+               { gen_rotate, '-1 0 0 -1' },
+               { gen_kern, get_h_d_neg },
+               { gen_box, get_w_neg },
+               { gen_whatsit, sid_restore },
             },
          },
       },
@@ -463,20 +486,20 @@ do
             height = get_w,
             depth  = zero,
             [id_hlist] = {
-               { 'whatsit', sid_save },
-               { 'rotate', '0 1 -1 0' },
-               { 'kern', function (w,h,d,nw,nh,nd) return -nd end },
-               { 'box', get_h },
-               { 'kern', function (w,h,d,nw,nh,nd) return nd-w end },
-               { 'whatsit', sid_restore },
+               { gen_whatsit, sid_save },
+               { gen_rotate, '0 1 -1 0' },
+               { gen_kern, function (w,h,d,nw,nh,nd) return -nd end },
+               { gen_box, get_h },
+               { gen_kern, function (w,h,d,nw,nh,nd) return nd-w end },
+               { gen_whatsit, sid_restore },
             },
             [id_vlist] = {
-               { 'kern', zero },
-               { 'whatsit', sid_save },
-               { 'rotate', '0 1 -1 0' },
-               { 'box', function (w,h,d,nw,nh,nd) return -nd-nh end },
-               { 'kern', get_h_d_neg },
-               { 'whatsit', sid_restore },
+               { gen_kern, zero },
+               { gen_whatsit, sid_save },
+               { gen_rotate, '0 1 -1 0' },
+               { gen_box, function (w,h,d,nw,nh,nd) return -nd-nh end },
+               { gen_kern, get_h_d_neg },
+               { gen_whatsit, sid_restore },
             },
          },
          [dir_tate] = { -- tate 中で組む
@@ -484,19 +507,19 @@ do
             height = get_d,
             depth  = get_h,
             [id_hlist] = {
-               { 'whatsit', sid_save },
-               { 'rotate', '-1 0 0 -1' },
-               { 'kern', get_w_neg },
-               { 'box', function (w,h,d,nw,nh,nd) return h-nd end },
-               { 'whatsit', sid_restore },
+               { gen_whatsit, sid_save },
+               { gen_rotate, '-1 0 0 -1' },
+               { gen_kern, get_w_neg },
+               { gen_box, function (w,h,d,nw,nh,nd) return h-nd end },
+               { gen_whatsit, sid_restore },
             },
             [id_vlist] = {
-               { 'whatsit', sid_save },
-               { 'rotate', ' -1 0 0 -1' },
-               { 'kern', function (w,h,d,nw,nh,nd) return -nh-nd end },
-               { 'box', get_w_neg },
-               { 'kern', function (w,h,d,nw,nh,nd) return nh+nd-h-d end },
-               { 'whatsit', sid_restore },
+               { gen_whatsit, sid_save },
+               { gen_rotate, ' -1 0 0 -1' },
+               { gen_kern, function (w,h,d,nw,nh,nd) return -nh-nd end },
+               { gen_box, get_w_neg },
+               { gen_kern, function (w,h,d,nw,nh,nd) return nh+nd-h-d end },
+               { gen_whatsit, sid_restore },
             },
          },
       },
@@ -508,8 +531,7 @@ end
 function get_box_dir(b, default)
    start_time_measure 'get_box_dir'
    local dir = has_attr(b, attr_dir) or 0
-   local bh = getfield(b,'head')
-   -- b は insert node となりうるので getlist() は使えない
+   local bh = getfield(b, 'head') -- We cannot use getlist since b may be an unset_node.
    local c
    if bh~=0 then -- bh != nil
       for bh in traverse_id(id_whatsit, bh) do
@@ -548,7 +570,7 @@ do
                      local d = hd
                      nh, hd = node_remove(nh, hd)
                      if is_copy==true and (not dir_backup) then
-                        dir_backup = d; setfield(dir_backup, 'next', nil)
+                        dir_backup = d; setnext(dir_backup, nil)
                      else
                         node_free(d)
                      end
@@ -556,7 +578,7 @@ do
                   hd = node_next(hd)
                end
             end
-            setfield(bd, 'head', nh)
+            setlist(bd, nh)
          end
       end
       if luatexja.global_temp and tex.globaldefs~=luatexja.global_temp then
@@ -569,8 +591,8 @@ do
       if b then
          local bd = to_direct(b)
          if dir_backup then
-            setfield(dir_backup, 'next', getlist(bd))
-            setfield(bd, 'head', dir_backup)
+            setnext(dir_backup, getlist(bd))
+            setlist(bd, dir_backup)
             dir_backup = nil
          end
       end
@@ -587,23 +609,26 @@ local function unwrap_dir_node(b, head, box_dir)
    if head then
       nh = insert_before(head, b, bh)
       nh, nb = node_remove(nh, b)
-      setfield(b, 'next', nil)
-      node_free(b)
+      setnext(b, nil); node_free(b)
    end
    local shift_old, b_dir, wh = nil, get_box_dir(bh, 0)
    if wh then
-      node.direct.flush_list(getfield(wh, 'value'))
+      dnode.flush_list(getfield(wh, 'value'))
       setfield(wh, 'value', nil)
    end
    return nh, nb, bh, b_dir
 end
 
 -- is_manual: 寸法変更に伴うものか?
-local function create_dir_node(b, b_dir, new_dir, is_manual)
+local create_dir_node
+do
+    local getdir = dnode.getdir
+    local setdir = dnode.setdir
+    local setshift = dnode.setshift
+
+create_dir_node = function(b, b_dir, new_dir, is_manual)
    local info = dir_node_aux[b_dir%dir_math_mod][new_dir%dir_math_mod]
-   local w = getfield(b, 'width')
-   local h = getfield(b, 'height')
-   local d = getfield(b, 'depth')
+   local w, h, d = getwhd(b)
    local db = node_new(getid(b)) -- dir_node
    set_attr(db, attr_dir,
             new_dir + (is_manual and dir_node_manual or dir_node_auto))
@@ -611,13 +636,11 @@ local function create_dir_node(b, b_dir, new_dir, is_manual)
    set_attr(b, attr_icflag, PROCESSED)
    ensure_tex_attr(attr_dir, 0)
    ensure_tex_attr(attr_icflag, 0)
-   setfield(db, 'dir', getfield(b, 'dir'))
-   setfield(db, 'shift', 0)
-   setfield(db, 'width',  info.width(w,h,d))
-   setfield(db, 'height', info.height(w,h,d))
-   setfield(db, 'depth',  info.depth(w,h,d))
+   setdir(db, getdir(b)); setshift(db, 0)
+   setwhd(db, info.width(w,h,d), info.height(w,h,d), info.depth(w,h,d))
    return db
 end
+end
 
 -- 異方向のボックスの処理
 local make_dir_whatsit, process_dir_node
@@ -633,14 +656,14 @@ do
       -- 既に b の中身にあるwhatsit
       if (box_dir<dir_node_auto) and (not dn) then
         bh = create_dir_whatsit(bh, 'make_dir_whatsit', dir_yoko)
-        dn = bh; setfield(b, 'head', bh)
+        dn = bh; setlist(b, bh)
       end
       if box_dir%dir_math_mod==new_dir then
          if box_dir>=dir_node_auto then
             -- dir_node としてカプセル化されている
             local _, dnc = get_box_dir(b, 0)
             if dnc then -- free all other dir_node
-               node.direct.flush_list(getfield(dnc, 'value'))
+               dnode.flush_list(getfield(dnc, 'value'))
                setfield(dnc, 'value', nil)
             end
             set_attr(b, attr_dir, box_dir%dir_math_mod + dir_node_auto)
@@ -670,18 +693,13 @@ do
                db=x; break
             end
          end
-         node.direct.flush_list(getfield(dn, 'value'))
+         dnode.flush_list(getfield(dn, 'value'))
          setfield(dn, 'value', nil)
          db = db or create_dir_node(b, box_dir, new_dir, false)
-         local w = getfield(b, 'width')
-         local h = getfield(b, 'height')
-         local d = getfield(b, 'depth')
-         local dn_w = getfield(db, 'width')
-         local dn_h = getfield(db, 'height')
-         local dn_d = getfield(db, 'depth')
+         local w, h, d = getwhd(b)
          nh, nb =  insert_before(head, b, db), nil
          nh, nb = node_remove(nh, b)
-         setfield(b, 'next', nil); setfield(db, 'head', b)
+         setnext(b, nil); setlist(db, b)
          ret, flag = db, true
          return nh, nb, ret, flag
       end
@@ -701,7 +719,7 @@ do
    end
 
    -- lastbox
-   local node_prev = (node.direct~=node) and node.direct.getprev or node.prev
+   local node_prev = dnode.getprev
    local id_glue = node.id 'glue'
    local function lastbox_hook()
       start_time_measure 'box_primitive_hook'
@@ -715,20 +733,20 @@ do
             if p and getid(p)==id_glue and getsubtype(p)==12 then -- tabskip
                local np = node_next(p); local npid = getid(np)
                if npid==id_hlist or npid==id_vlist then
-                  setfield(b, 'head', create_dir_whatsit(p, 'align', get_box_dir(np, 0)))
+                  setlist(b, create_dir_whatsit(p, 'align', get_box_dir(np, 0)))
                end
             end
             local box_dir =  get_box_dir(b, 0)
             if box_dir>= dir_node_auto then -- unwrap dir_node
                local p = node_prev(b)
                local dummy1, dummy2, nb = unwrap_dir_node(b, nil, box_dir)
-               setfield(p, 'next', nb);  tex_nest[tex_nest.ptr].tail = to_node(nb)
-               setfield(b, 'next', nil); setfield(b, 'head', nil)
+               setnext(p, nb);  tex_nest[tex_nest.ptr].tail = to_node(nb)
+               setnext(b, nil); setlist(b, nil)
                node_free(b); b = nb
             end
             local _, wh =  get_box_dir(b, 0) -- clean dir_node attached to the box
             if wh then
-               node.direct.flush_list(getfield(wh, 'value'))
+               dnode.flush_list(getfield(wh, 'value'))
                setfield(wh, 'value', nil)
             end
          end
@@ -756,9 +774,7 @@ do
             end
          end
          if not_found then
-            local w = getfield(s, 'width')
-            local h = getfield(s, 'height')
-            local d = getfield(s, 'depth')
+            local w, h, d = getwhd(s)
             setdimen('ltj@tempdima',
                          dir_node_aux[s_dir][l_dir][key](w,h,d))
          end
@@ -797,7 +813,7 @@ do
       if s_dir ~= l_dir then
          if not wh then
             wh = create_dir_whatsit(getlist(s), 'set_box_dim', s_dir)
-            setfield(s, 'head', wh)
+            setlist(s, wh)
          end
          local db
          local dnh = getfield(wh, 'value')
@@ -808,7 +824,7 @@ do
          end
          if not db then
             db = create_dir_node(s, s_dir, l_dir, true)
-            setfield(db, 'next', dnh)
+            setnext(db, dnh)
             setfield(wh, 'value',to_node(db))
          end
          setfield(db, key, scan_dimen())
@@ -817,15 +833,12 @@ do
          setfield(s, key, scan_dimen())
          if wh then
             -- change dimension of dir_nodes which are created "automatically"
-               local bw, bh, bd
-                  = getfield(s,'width'), getfield(s, 'height'), getfield(s, 'depth')
+               local bw, bh, bd = getwhd(s)
             for x in traverse(getfield(wh, 'value')) do
                local x_dir = has_attr(x, attr_dir)
                if x_dir<dir_node_manual then
                   local info = dir_node_aux[s_dir][x_dir%dir_node_auto]
-                  setfield(x, 'width',  info.width(bw,bh,bd))
-                  setfield(x, 'height', info.height(bw,bh,bd))
-                  setfield(x, 'depth',  info.depth(bw,bh,bd))
+                  setwhd(x, info.width(bw,bh,bd), info.height(bw,bh,bd), info.depth(bw,bh,bd))
                end
             end
          end
@@ -849,16 +862,12 @@ do
          else
             local sid, b = getid(s), getlist(s)
             local info = dir_node_aux[get_box_dir(b,dir_yoko)%dir_math_mod][b_dir%dir_node_auto]
-            local bw, bh, bd
-               = getfield(b,'width'), getfield(b, 'height'), getfield(b, 'depth')
-            local sw, sh, sd
-               = getfield(s,'width'), getfield(s, 'height'), getfield(s, 'depth')
+            local bw, bh, bd = getwhd(b)
+            local sw, sh, sd = getwhd(s)
             if set_box_dim_common(key, b, l_dir) and b_dir<dir_node_manual then
                -- re-calculate dimension of s, if s is created "automatically"
                if b_dir<dir_node_manual then
-                  setfield(s, 'width',  info.width(bw,bh,bd))
-                  setfield(s, 'height', info.height(bw,bh,bd))
-                  setfield(s, 'depth',  info.depth(bw,bh,bd))
+                  setwhd(s, info.width(bw,bh,bd), info.height(bw,bh,bd), info.depth(bw,bh,bd))
                end
             end
          end
@@ -889,7 +898,7 @@ do
 end
 
 do
-   local getbox, setbox, copy_list = tex.getbox, tex.setbox, node.direct.copy_list
+   local getbox, setbox, copy_list = tex.getbox, tex.setbox, dnode.copy_list
    -- raise, lower
    function luatexja.direction.raise_box()
       start_time_measure 'box_primitive_hook'
@@ -923,6 +932,7 @@ end
 -- adjust
 do
    local id_adjust = node.id 'adjust'
+   local last_node = dnode.last_node 
    local scan_keyword = token.scan_keyword
    function luatexja.direction.adjust_begin()
       if scan_keyword 'pre' then tex.sprint(cat_lp, '\\ltj@@vadjust@pre')
@@ -940,7 +950,7 @@ do
                'luatexja',
                'Direction Incompatible',
                "\\vadjust's argument and outer vlist must have same direction.")
-            node.direct.last_node()
+            node_free(last_node())
          end
       end
       stop_time_measure 'box_primitive_hook'
@@ -960,7 +970,7 @@ do
           a = node.tail(tex.lists.page_head); ad = to_direct(a)
       end
       if a and getid(ad)==id_ins then
-         local h = getfield(ad, 'head')
+         local h = getlist(ad)
          if getid(h)==id_whatsit and
             getsubtype(h)==sid_user and getfield(h, 'user_id')==DIR then
                local n = h; h = node_remove(h,h)
@@ -972,7 +982,7 @@ do
             end
          end
          ensure_tex_attr(attr_dir, 0)
-         setfield(ad, 'head', h)
+         setlist(ad, h)
       end
       stop_time_measure 'box_primitive_hook'
    end
@@ -995,7 +1005,7 @@ do
             and node_next(bh) then
             ltjs.list_dir = has_attr(bh, attr_dir)
             local q = node_next(p)
-            setfield(p, 'head', node_remove(bh,bh,bh))
+            setlist(p, (node_remove(bh,bh,bh)))
             split_dir_head = bh
          end
       end
@@ -1053,38 +1063,22 @@ do
    local function finalize_dir_node(db,new_dir)
       local b = getlist(db)
       while b and ((getid(b)~=id_hlist) and (getid(b)~=id_vlist)) do
-         local ob = b; b = node_remove(b,b); setfield(db, 'head', b);
+         local ob = b; b = node_remove(b,b); setlist(db, b);
          node_free(ob)
       end
       finalize_inner(b)
-      local w = getfield(b, 'width')
-      local h = getfield(b, 'height')
-      local d = getfield(b, 'depth')
-      local dn_w = getfield(db, 'width')
-      local dn_h = getfield(db, 'height')
-      local dn_d = getfield(db, 'depth')
+      local w, h, d = getwhd(b)
+      local dw, dh, dd = getwhd(db)
       local db_head, db_tail
       local t = dir_node_aux[get_box_dir(b, dir_yoko)%dir_math_mod][new_dir]
       t = t and t[getid(b)]; if not t then return end
       for _,v in ipairs(t) do
-         local cmd, arg, nn = v[1], v[2]
-         if cmd=='kern' then
-            nn = node_new(id_kern, 1)
-            setfield(nn, 'kern', arg(w, h, d, dn_w, dn_h, dn_d))
-         elseif cmd=='whatsit' then
-            nn = node_new(id_whatsit, arg)
-         elseif cmd=='rotate' then
-            nn = node_new(id_whatsit, sid_matrix)
-            setfield(nn, 'data', arg)
-         elseif cmd=='box' then
-            nn = b; setfield(b, 'next', nil)
-            setfield(nn, 'shift', arg(w, h, d, dn_w, dn_h, dn_d))
-         end
+         local nn = v[1](v[2], b, w, h, d, dw, dh, dd)
          if db_head then
             insert_after(db_head, db_tail, nn)
             db_tail = nn
          else
-            setfield(db, 'head', nn)
+            setlist(db, nn)
             db_head, db_tail = nn, nn
          end
       end
@@ -1092,6 +1086,7 @@ do
 
    tex.setattribute(attr_dir, dir_yoko)
    local shipout_temp =  node_new(id_hlist)
+   dnode.setattributelist(shipout_temp, nil) 
    tex.setattribute(attr_dir, 0)
 
    finalize_inner = function (box)
@@ -1107,17 +1102,17 @@ do
          end
       end
    end
-   local copy = node.direct.copy
+   local copy = dnode.copy
    function luatexja.direction.shipout_lthook (head)
       start_time_measure 'box_primitive_hook'
       local a = to_direct(head)
       local a_dir = get_box_dir(a, dir_yoko)
       if a_dir~=dir_yoko then
          local b = create_dir_node(a, a_dir, dir_yoko, false)
-         setfield(b, 'head', a); a = b
+         setlist(b, a); a = b
       end
-      setfield(shipout_temp, 'head', a); finalize_inner(shipout_temp)
-      a = copy(getlist(shipout_temp)); setfield(shipout_temp, 'head',nil)
+      setlist(shipout_temp, a); finalize_inner(shipout_temp)
+      a = copy(getlist(shipout_temp)); setlist(shipout_temp, nil)
       stop_time_measure 'box_primitive_hook'
       return to_node(a)
    end