% \iffalse meta-comment
%
%% File: l3alloc.dtx
%
% Copyright (C) 1990-2012,2014-2019 The LaTeX3 Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
% license or (at your option) any later version.  The latest version
% of this license is in the file
%
%    https://www.latex-project.org/lppl.txt
%
% This file is part of the "l3kernel bundle" (The Work in LPPL)
% and all files in that bundle must be distributed together.
%
% -----------------------------------------------------------------------
%
% The development version of the bundle can be found at
%
%    https://github.com/latex3/latex3
%
% for those people who are interested.
%
%<*driver>
\documentclass[full,kernel]{l3doc}
\begin{document}
  \DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
%
% \title{^^A
%   The \pkg{l3alloc} package\\ Register allocation^^A
% }
%
% \author{^^A
%  The \LaTeX3 Project\thanks
%    {^^A
%      E-mail:
%        \href{mailto:latex-team@latex-project.org}
%          {latex-team@latex-project.org}^^A
%    }^^A
% }
%
% \date{Released 2019-04-06}
%
% \maketitle
%
% \begin{documentation}
%
% This module provides the basic mechanism for allocating \TeX{}'s
% registers when operating in format mode. When loaded as a package on
% an existing format, the mechanisms from the latter are used.
%
% The approach used here is informed by the mechanisms used in plain
% \TeX{}/\LaTeX{} but noting that newer engines provide us much more
% flexibility. In addition to this, we do not need allocators for all
% register types: for example \texttt{toks} are not used by \LaTeX3 whilst
% reads/writes are handled using a pool and thus do not need a classical
% allocator.
%
% In classical (non-\LuaTeX{}) engines, there are various restriction on
% registers, for example |\box255| is hard-coded as the output box and
% inserts have to be allocated below this (not in the extended pool). Rather
% than worry about this, allocations for the registers affected (\TeX{}
% |box|, |count|, |dimen| and |skip| types) are simply made only from the
% extended pool. (There is a performance impact in engines other than
% \LuaTeX{} but the free use of registers in \pkg{expl3} means that code
% cannot be sure of obtaining a low-numbered register in any case.)
%
% \end{documentation}
%
% \begin{implementation}
%
% \section{\pkg{l3alloc} implementation}
%
%    \begin{macrocode}
%<*initex>
%    \end{macrocode}
%
%    \begin{macrocode}
%<@@=alloc>
%    \end{macrocode}
%
% \begin{variable}
%   {
%     \g_@@_int_int    ,
%     \g_@@_dim_int    ,
%     \g_@@_muskip_int ,
%     \g_@@_int_int    ,
%     \g_@@_box_int
%   }
%   The core register tracking is done using the same raw \TeX{} count
%   registers as reserved by plain \TeX{} and \LaTeXe{}, as there may be the
%   odd piece of generic code that needs to work by number. However, as not
%   all of our variables work the same way, some of the older registers are
%   simply ignored. For the same reason, there is no special status for the
%   low-numbers registers other than counts. To avoid having to worry about
%   inserts and reflecting the register availability in \eTeX{}, the lower
%   register space is unused here (though is available for hard-coded
%   use).
%    \begin{macrocode}
\tex_countdef:D \g_@@_int_int    = 10 ~
\tex_countdef:D \g_@@_dim_int    = 11 ~
\tex_countdef:D \g_@@_skip_int   = 12 ~
\tex_countdef:D \g_@@_muskip_int = 13 ~
\tex_countdef:D \g_@@_box_int    = 14 ~
\g_@@_int_int    = 255 ~
\g_@@_dim_int    = 255 ~
\g_@@_skip_int   = 255 ~
\g_@@_muskip_int =   0 ~
\g_@@_box_int    = 255 ~
%    \end{macrocode}
% \end{variable}
%
% \begin{variable}
%   {
%     \g_@@_attribute_int ,
%     \g_@@_bytecode_int  ,
%     \g_@@_chunkname_int ,
%     \g_@@_whatsit_int
%   }
%   To allow \LuaTeX{} to load |ltluatex.lua| for generic \Lua{} support, a
%   small number of counts have to be correctly named at the \TeX{} level.
%   At present there are no \pkg{expl3} allocators for these concepts so the
%   names and numbers of the tracking variables may change.
%    \begin{macrocode}
\tex_ifdefined:D \tex_luatexversion:D
  \tex_global:D \tex_countdef:D \g_@@_attribute_int  = 21 ~
  \tex_global:D \tex_countdef:D \g_@@_bytecode_int   = 22 ~
  \tex_global:D \tex_countdef:D \g_@@_chunkname_int  = 23 ~
  \tex_global:D \tex_countdef:D \g_@@_whatsit_int    = 24 ~
\tex_fi:D
%    \end{macrocode}
% \end{variable}
%
% \begin{macro}
%   {\box_new:N, \dim_new:N, \int_new:N, \muskip_new:N \skip_new:N}
%   Each of the public allocators is a wrapper around the one internal
%   function needed here.
%    \begin{macrocode}
\cs_new_protected:Npx \box_new:N #1
  {
    \exp_not:N \@@_reg:nNnN { box }
      \cs_if_exist:NTF \tex_luatexversion:D
        { \tex_chardef:D }
        { \tex_mathchardef:D }
      \c_max_register_int
      #1
  }
\cs_new_protected:Npn \dim_new:N #1
  { \@@_reg:nNnN { dim } \tex_dimendef:D \c_max_register_int #1 }
\cs_new_protected:Npn \int_new:N #1
  { \@@_reg:nNnN { int } \tex_countdef:D \c_max_register_int #1 }
\cs_new_protected:Npn \muskip_new:N #1
  { \@@_reg:nNnN { muskip } \tex_muskipdef:D \c_max_register_int #1 }
\cs_new_protected:Npn \skip_new:N #1
  { \@@_reg:nNnN { skip } \tex_skipdef:D \c_max_register_int #1 }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_reg:nNNN}
%   The allocator itself is modelled somewhat on \LaTeXe{}'s \tn{e@alloc},
%   though there is no need to set \tn{allocationnumber}.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_reg:nNnN #1#2#3#4
  {
    \__kernel_chk_if_free_cs:N #4
    \int_compare:nNnTF { \int_use:c { g_@@_ #1 _int } } < {#3}
      {
        \int_gincr:c { g_@@_ #1 _int }
        \tex_global:D #2 #4 \int_use:c { g_@@_ #1 _int }
        \iow_log:x
          {
            \token_to_str:N #4 ~=~ #1 ~register~
            \int_use:c { g_@@_ #1 _int }
          }
      }
      { \__kernel_msg_fatal:nnx { kernel } { out-of-registers } {#1} }
  }
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
%</initex>
%    \end{macrocode}
%
% \end{implementation}
%
% \PrintIndex
