% \iffalse meta-comment % % Copyright 2009, 2010 by Élie Roux % Copyright 2010, 2011 by Manuel Pégourié-Gonnard % % This work is under the CC0 license. % % This work consists of the main source file luatexbase-regs.dtx % and the derived files % luatexbase-regs.pdf luatexbase-regs.sty % test-regs-plain.tex test-regs-latex.tex % % Unpacking: % tex luatexbase-regs.dtx % Documentation: % pdflatex luatexbase-regs.dtx % %<*ignore> \begingroup \def\x{LaTeX2e}% \expandafter\endgroup \ifcase 0\ifx\install y1\fi\expandafter \ifx\csname processbatchFile\endcsname\relax\else1\fi \ifx\fmtname\x\else 1\fi\relax \else\csname fi\endcsname % %<*install> \input docstrip.tex \keepsilent \askforoverwritefalse \preamble See the aforementioned source file(s) for copyright and licensing information. \endpreamble \generate{% \usedir{tex/luatex/luatexbase}% \file{luatexbase-regs.sty}{\from{luatexbase-regs.dtx}{texpackage}}% } \generate{% \usedir{doc/luatex/luatexbase}% \file{test-regs-plain.tex}{\from{luatexbase-regs.dtx}{testplain}}% \file{test-regs-latex.tex}{\from{luatexbase-regs.dtx}{testlatex}}% } \obeyspaces \Msg{************************************************************************} \Msg{*} \Msg{* To finish the installation you have to move the following} \Msg{* files into a directory searched by TeX:} \Msg{*} \Msg{* luatexbase-regs.sty} \Msg{*} \Msg{* Happy TeXing!} \Msg{*} \Msg{************************************************************************} \endbatchfile % %<*ignore> \fi % %<*driver> \NeedsTeXFormat{LaTeX2e} \documentclass{ltxdoc} \input lltxb-dtxstyle.tex \EnableCrossrefs \CodelineIndex \begin{document} \DocInput{luatexbase-regs.dtx}% \end{document} % % \fi % % \CheckSum{0} % % \CharacterTable % {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z % Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z % Digits \0\1\2\3\4\5\6\7\8\9 % Exclamation \! Double quote \" Hash (number) \# % Dollar \$ Percent \% Ampersand \& % Acute accent \' Left paren \( Right paren \) % Asterisk \* Plus \+ Comma \, % Minus \- Point \. Solidus \/ % Colon \: Semicolon \; Less than \< % Equals \= Greater than \> Question mark \? % Commercial at \@ Left bracket \[ Backslash \\ % Right bracket \] Circumflex \^ Underscore \_ % Grave accent \` Left brace \{ Vertical bar \| % Right brace \} Tilde \~} % % \pkdate{luatexbase-regs}{2011/05/24 v0.4} % % \maketitle % % \begin{abstract} % This package extends the register allocation scheme of \plaintex and % \latex to take advantage of the increased number of registers available in % \luatex. % \end{abstract} % % \tableofcontents % % \section{Documentation} % % Since the \plaintex and \latex formats are both frozen, they fail to take % into account the extended resources provided by newer \tex-like engines. % This package focuses on the allocation scheme for registers. \texe provides % $6$ kinds or registers: count, dimen, skip, muskip, box and toks and has % $256$ registers of each kind. \eTeX\ and most of its descendants add one % kind of register (marks) and offers $2^{15} = 32768$ of each kind. \luatex % provides $2^{16} = 65536$ registers of each kind. (It also provides new % register-like resources, but this package addresses only the resources % inherited from \eTeX.) % % More precisely, \pk{luatexbase-regs} loads the \pk{etex} package (or % makes sure it is preloaded in the format) and then adapts it to the new % limits of \luatex. Thus, all macros defined by the \pk{etex} package are % made available (most notably, |\loccount|, |\globcountblk|, % |\loccountblk| and alike). However, if a register of some kind has been % locally allocated before this package is loaded, then the number of % allocatable registers of this kind will not be extended to $65536$. To avoid % this, load \pk{luatexbase-regs} earlier. % % The \plaintex and \latex formats define a new kind of resource: % \emph{inserts} which are merely a family (count, dimen, skip, box) of % registers with the same number. Inserts allocation begins at $255$ and goes % toward $0$. Thus we can make room for more inserts by making allocation of % count-, dimen-, skip- and box-registers start from $256$. With real \etex, % it may be a bad idea since registers with index greater than $256$ have % degraded performance due to implementation details, but with \luatex the % performance is uniform, so we just do it. % % \section{Implementation} % % \begin{macrocode} %<*texpackage> % \end{macrocode} % % \subsection{Preliminaries} % % Catcode defenses and reload protection. % % \begin{macrocode} \begingroup\catcode61\catcode48\catcode32=10\relax% = and space \catcode123 1 % { \catcode125 2 % } \catcode 35 6 % # \toks0\expandafter{\expandafter\endlinechar\the\endlinechar}% \edef\x{\endlinechar13}% \def\y#1 #2 {% \toks0\expandafter{\the\toks0 \catcode#1 \the\catcode#1}% \edef\x{\x \catcode#1 #2}}% \y 13 5 % carriage return \y 61 12 % = \y 32 10 % space \y 123 1 % { \y 125 2 % } \y 35 6 % # \y 64 11 % @ (letter) \y 10 12 % new line ^^J \y 33 12 % ! \y 36 3 % $ $ (in etex.sty) \y 39 12 % ' \y 40 12 % ( \y 41 12 % ) \y 42 12 % * (in etex.sty) \y 43 12 % + (in etex.sty) \y 44 12 % , (in etex.sty) \y 45 12 % - \y 46 12 % . \y 47 12 % / \y 58 12 % : \y 60 12 % < (in etex.sty) \y 62 12 % > (in etex.sty) \y 91 12 % [ \y 93 12 % ] \y 94 7 % ^ \y 96 12 % ` \toks0\expandafter{\the\toks0 \relax\noexpand\endinput}% \edef\y#1{\noexpand\expandafter\endgroup% \noexpand\ifx#1\relax \edef#1{\the\toks0}\x\relax% \noexpand\else \noexpand\expandafter\noexpand\endinput% \noexpand\fi}% \expandafter\y\csname luatexbase@regs@sty@endinput\endcsname% % \end{macrocode} % % Package declaration. % % \begin{macrocode} \begingroup \expandafter\ifx\csname ProvidesPackage\endcsname\relax \def\x#1[#2]{\immediate\write16{Package: #1 #2}} \else \let\x\ProvidesPackage \fi \expandafter\endgroup \x{luatexbase-regs}[2011/05/24 v0.4 Registers allocation for LuaTeX] % \end{macrocode} % % Make sure \luatex is used. % % \begin{macrocode} \begingroup\expandafter\expandafter\expandafter\endgroup \expandafter\ifx\csname RequirePackage\endcsname\relax \input ifluatex.sty \else \RequirePackage{ifluatex} \fi \ifluatex\else \begingroup \expandafter\ifx\csname PackageError\endcsname\relax \def\x#1#2#3{\begingroup \newlinechar10 \errhelp{#3}\errmessage{Package #1 error: #2}\endgroup} \else \let\x\PackageError \fi \expandafter\endgroup \x{luatexbase-regs}{LuaTeX is required for this package. Aborting.}{% This package can only be used with the LuaTeX engine^^J% (command `lualatex' or `luatex').^^J% Package loading has been stopped to prevent additional errors.} \expandafter\luatexbase@regs@sty@endinput% \fi % \end{macrocode} % % \subsection{Ensure etex.sty is loaded} % % If running \latex, load \file{etex.sty}. If not, either % \file{etex.src} was loaded at format generation time, or we cannot do % anything. % % \begin{macrocode} \begingroup\expandafter\expandafter\expandafter\endgroup \expandafter\ifx\csname RequirePackage\endcsname\relax \else \RequirePackage{etex}[1998/03/26] \fi % \end{macrocode} % % To the best of my (mpg) knowledge, all Plain-based formats built with % \etex-enabled engines in \texlive load \file{etex.src}. However, % let's be careful and check that \file{etex.sty} or \file{etex.src} is % loaded. % % \begin{macrocode} \begingroup\expandafter\expandafter\expandafter\endgroup \expandafter\ifx\csname et@xins\endcsname\relax \begingroup \expandafter\ifx\csname PackageWarningNoLine\endcsname\relax \def\x#1#2{\begingroup\newlinechar10 \immediate\write16{Package #1 warning: #2}\endgroup} \else \let\x\PackageWarningNoLine \fi \expandafter\endgroup \x{luatexbase-regs}{etex macros not loaded!^^J% Registers allocation scheme will not be extended.} \else % \end{macrocode} % % \subsection{Adapt range} % % First, increase the upper bound for all kinds of registers. Copy code to % avoid defining a macro. % % \begin{macrocode} \ifnum\count270=32768 \count270=65536 \fi \ifnum\count271=32768 \count271=65536 \fi \ifnum\count272=32768 \count272=65536 \fi \ifnum\count273=32768 \count272=65536 \fi \ifnum\count273=32768 \count273=65536 \fi \ifnum\count274=32768 \count274=65536 \fi \ifnum\count275=32768 \count275=65536 \fi \ifnum\count276=32768 \count276=65536 \fi % \end{macrocode} % % \subsection{Patch macros that used \cs{mathchardef}} % % |\box| registers and |\mark|s were previously defined % using |\mathchardef| since it had the biggest range under \etex % (15-bit number). However, this is not enough for \luatex's extended % registers. Fortunately, |\chardef|'s range is extended, and now large % enough, so use it everywhere instead of |\mathchardef|. Do this % inside a group and use |\toks0| to store the list of actions. % % \begin{macrocode} \begingroup \toks0{} \def\@namedef #1{\expandafter \def\csname#1\endcsname} \def\@outerdef#1{\expandafter\outer\expandafter\def\csname#1\endcsname} % \end{macrocode} % % Notice that the auxiliary macros will automatically expand to the desired % level when necessary, see below. % % First, here are the definitions from \file{etex.src}, in a form adapted % to our needs. % % \begin{macrocode} \def\def@globbox #1#2{\@outerdef{#1}{\et@xglob 4 \box #2}} \def\def@locbox #1#2{\@namedef {#1}{\et@xloc 4 \box #2}} \def\def@globmarks #1#2{\@outerdef{#1}{\et@xglob 6 \marks #2}} \def\def@locmarks #1#2{\@namedef {#1}{\et@xloc 6 \marks #2}} \def\def@et@xgblk#1#2{\@namedef{#1}##1##2##3##4% {\et@xchkblk ##1##2{##4}% {\allocationnumber=\count 26##1 \global \advance \count 26##1 by ##4% \global #2##3=\allocationnumber \wlog {\string ##3=\string ##2blk{\number ##4} at \the \allocationnumber}% }% }} \def\def@et@xlblk#1#2{\@namedef{#1}##1##2##3##4% {\et@xchkblk ##1##2{##4}% {\advance \count 27##1 by -##4% \allocationnumber=\count 27##1 #2##3=\allocationnumber \wlog {\string ##3=\string ##2blk{\number ##4} at \the \allocationnumber \space (local)% }% }% }} % \end{macrocode} % % Then, the definitions from \file{etex.sty} since they are subtly % different (|\outer| status, but also optional spaces or |=| % signs). % % \begin{macrocode} \def\alt@globbox #1#2{\@namedef{#1}{\et@xglob 4\box #2}} \def\alt@locbox #1#2{\@namedef{#1}{\et@xloc 4\box #2}} \def\alt@globmarks #1#2{\@namedef{#1}{\et@xglob 6\marks #2}} \def\alt@locmarks #1#2{\@namedef{#1}{\et@xloc 6\marks #2}} \def\alt@et@xgblk#1#2{\@namedef{#1}##1##2##3##4% {\et@xchkblk##1##2{##4}% {\allocationnumber\count26##1% \global\advance\count26##1by##4% \global#2##3\allocationnumber \wlog{\string##3=\string##2blk{\number##4} at \the\allocationnumber}% }% }} \def\alt@et@xlblk#1#2{\@namedef{#1}##1##2##3##4% {\et@xchkblk##1##2{##4}% {\advance\count27##1-##4% \allocationnumber\count27##1% #2##3\allocationnumber \et@xwlog{\string##3=\string##2blk{\number##4} at \the\allocationnumber\space(local)}% }% }} % \end{macrocode} % % Now, a macro checking the definitions, and making the appropriate % re-definition. % % \begin{macrocode} \def\check@def#1{% \csname def@#1\endcsname{test@#1}\mathchardef \expandafter\ifx\csname test@#1\expandafter\endcsname \csname #1\endcsname \expandafter\let\csname #1\endcsname\relax \toks0\expandafter{\the\toks0\csname def@#1\endcsname{#1}\chardef} \else \csname alt@#1\endcsname{test@#1}\mathchardef \expandafter\ifx\csname test@#1\expandafter\endcsname \csname #1\endcsname \toks0\expandafter{\the\toks0\csname alt@#1\endcsname{#1}\chardef} \else \expandafter\show\csname BAD#1\endcsname \fi \fi} % \end{macrocode} % % Now, actually do it. % % \begin{macrocode} \check@def{globbox} \check@def{locbox} \check@def{globmarks} \check@def{locmarks} \check@def{et@xgblk} \check@def{et@xlblk} \expandafter \endgroup \the\toks0 % \end{macrocode} % % \subsection{Make room for inserts} % % Finally, make allocation of |\count|, |\dimen|, |skip| and % |\box| start with numbers $>255$, in order to free the lower numbers % for insertions. Be careful with |\new...| macros which are % |\outer| in Plain, since we're in the middle of an |\if| test. % % \begin{macrocode} \expandafter\let\csname newcount\endcsname\globcount \expandafter\let\csname newdimen\endcsname\globdimen \expandafter\let\csname newskip\endcsname\globskip \expandafter\let\csname newbox\endcsname\globbox \fi % \end{macrocode} % % That's all folks! % % \begin{macrocode} \luatexbase@regs@sty@endinput% % % \end{macrocode} % % \section{Test files} % % Here we test only the two main formats: \plaintex (with \file{etex.src} % loaded) and \latex, both with the \luatex engine. Those correspond to % the \cmdname{luatex} and \cmdname{lualatex} commands in \texlive. % % We want to make sure we can globally and locally allocate $30000$ % registers of each kind, and still globally allocate $100$ |\insert|s. % Next we globally allocate a bloc of $3000$ registers of each kind, and % locally a block of $1000$. (Those numbers are not optimal, but they % should be enough for testing purposes.) % % \begin{macrocode} %\input luatexbase-regs.sty %\RequirePackage{luatexbase-regs} %<*testplain,testlatex> \def\checkregister#1{% \edef\newregister{\expandafter\noexpand\csname new#1\endcsname}% \edef\locregister{\expandafter\noexpand\csname loc#1\endcsname}% \count0 1 \loop \newregister\dummy \locregister\dummy \ifnum\count0<30000 \advance\count0 1 \repeat} \checkregister{count} \checkregister{dimen} \checkregister{skip} \checkregister{muskip} \checkregister{box} \checkregister{toks} \checkregister{marks} \count0 1 \loop \ifnum\count0<100 \csname newinsert\endcsname\dummy \advance\count0 1 \repeat \globcountblk \dummy{3000} \globdimenblk \dummy{3000} \globskipblk \dummy{3000} \globmuskipblk\dummy{3000} \globboxblk \dummy{3000} \globtoksblk \dummy{3000} \globmarksblk \dummy{3000} \loccountblk \dummy{1000} \locdimenblk \dummy{1000} \locskipblk \dummy{1000} \locmuskipblk \dummy{1000} \locboxblk \dummy{1000} \loctoksblk \dummy{1000} \locmarksblk \dummy{1000} % %\bye %\stop % \end{macrocode} % % % \Finale \endinput