diff options
author | Luigi Scarso <luigi.scarso@gmail.com> | 2018-01-09 23:43:20 +0000 |
---|---|---|
committer | Luigi Scarso <luigi.scarso@gmail.com> | 2018-01-09 23:43:20 +0000 |
commit | aa5d0e8bf3515c424ba0594a2d4e06ae31da7796 (patch) | |
tree | e56fd10d89732547ddb207c1998a1ded4360382e /Build | |
parent | d33684eeca435784c95c62c7981dd02f7818b263 (diff) |
Imported Luatex 1.06.3 (Lua 5.2.4)
git-svn-id: svn://tug.org/texlive/trunk@46269 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build')
302 files changed, 8891 insertions, 3841 deletions
diff --git a/Build/source/libs/lua52/Makefile.in b/Build/source/libs/lua52/Makefile.in index 52c2fc26edd..d4828f487e6 100644 --- a/Build/source/libs/lua52/Makefile.in +++ b/Build/source/libs/lua52/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -612,6 +612,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -1351,7 +1352,7 @@ distdir: $(DISTFILES) ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir @@ -1377,7 +1378,7 @@ dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir @@ -1395,7 +1396,7 @@ dist dist-all: distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ - eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ @@ -1405,7 +1406,7 @@ distcheck: dist *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ - eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac diff --git a/Build/source/libs/lua52/aclocal.m4 b/Build/source/libs/lua52/aclocal.m4 index d903b740f4d..457e4ee7dfa 100644 --- a/Build/source/libs/lua52/aclocal.m4 +++ b/Build/source/libs/lua52/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.15.1 -*- Autoconf -*- +# generated automatically by aclocal 1.15 -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -20,7 +20,7 @@ You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) -# Copyright (C) 2002-2017 Free Software Foundation, Inc. +# Copyright (C) 2002-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -35,7 +35,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.15' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.15.1], [], +m4_if([$1], [1.15], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -51,14 +51,14 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.15.1])dnl +[AM_AUTOMAKE_VERSION([1.15])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -110,7 +110,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd` # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2017 Free Software Foundation, Inc. +# Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -141,7 +141,7 @@ AC_CONFIG_COMMANDS_PRE( Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -332,7 +332,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -408,7 +408,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -605,7 +605,7 @@ for _am_header in $config_headers :; do done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -626,7 +626,7 @@ if test x"${install_sh+set}" != xset; then fi AC_SUBST([install_sh])]) -# Copyright (C) 2003-2017 Free Software Foundation, Inc. +# Copyright (C) 2003-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -648,7 +648,7 @@ AC_SUBST([am__leading_dot])]) # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -683,7 +683,7 @@ AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -733,7 +733,7 @@ rm -f confinc confmf # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2017 Free Software Foundation, Inc. +# Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -772,7 +772,7 @@ fi # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -801,7 +801,7 @@ AC_DEFUN([_AM_SET_OPTIONS], AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -848,7 +848,7 @@ AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -867,7 +867,7 @@ AC_DEFUN([AM_RUN_LOG], # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -948,7 +948,7 @@ AC_CONFIG_COMMANDS_PRE( rm -f conftest.file ]) -# Copyright (C) 2009-2017 Free Software Foundation, Inc. +# Copyright (C) 2009-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1008,7 +1008,7 @@ AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1036,7 +1036,7 @@ fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2017 Free Software Foundation, Inc. +# Copyright (C) 2006-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1055,7 +1055,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2017 Free Software Foundation, Inc. +# Copyright (C) 2004-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/Build/source/libs/lua52/configure b/Build/source/libs/lua52/configure index 52d36d37680..04644e4ecf2 100755 --- a/Build/source/libs/lua52/configure +++ b/Build/source/libs/lua52/configure @@ -741,6 +741,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -825,6 +826,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1077,6 +1079,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1214,7 +1225,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1367,6 +1378,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -13546,7 +13558,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -13592,7 +13604,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -13616,7 +13628,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -13661,7 +13673,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -13685,7 +13697,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; diff --git a/Build/source/libs/lua52/include/Makefile.in b/Build/source/libs/lua52/include/Makefile.in index 7116b86833e..e54b67c57e5 100644 --- a/Build/source/libs/lua52/include/Makefile.in +++ b/Build/source/libs/lua52/include/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -246,6 +246,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ diff --git a/Build/source/libs/luajit/ChangeLog b/Build/source/libs/luajit/ChangeLog index 3416535e953..a5335fcc839 100644 --- a/Build/source/libs/luajit/ChangeLog +++ b/Build/source/libs/luajit/ChangeLog @@ -1,3 +1,9 @@ +2017-20-06 Luigi Scarso <luigi.scarso@gmail.com> + + Import LuaJIT-2.1.0-beta3. + * version.ac: Adjust. + + 2016-03-09 Luigi Scarso <luigi.scarso@gmail.com> Import LuaJIT-2.1.0-beta2. diff --git a/Build/source/libs/luajit/LuaJIT-src/COPYRIGHT b/Build/source/libs/luajit/LuaJIT-src/COPYRIGHT index b614d3eb4b7..6ed40025ae0 100644 --- a/Build/source/libs/luajit/LuaJIT-src/COPYRIGHT +++ b/Build/source/libs/luajit/LuaJIT-src/COPYRIGHT @@ -1,7 +1,7 @@ =============================================================================== LuaJIT -- a Just-In-Time Compiler for Lua. http://luajit.org/ -Copyright (C) 2005-2016 Mike Pall. All rights reserved. +Copyright (C) 2005-2017 Mike Pall. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Build/source/libs/luajit/LuaJIT-src/Makefile b/Build/source/libs/luajit/LuaJIT-src/Makefile index f6446ba4d3f..0f9330893fd 100644 --- a/Build/source/libs/luajit/LuaJIT-src/Makefile +++ b/Build/source/libs/luajit/LuaJIT-src/Makefile @@ -10,13 +10,13 @@ # For MSVC, please follow the instructions given in src/msvcbuild.bat. # For MinGW and Cygwin, cd to src and run make with the Makefile there. # -# Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +# Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h ############################################################################## MAJVER= 2 MINVER= 1 RELVER= 0 -PREREL= -beta2 +PREREL= -beta3 VERSION= $(MAJVER).$(MINVER).$(RELVER)$(PREREL) ABIVER= 5.1 @@ -47,17 +47,18 @@ INSTALL_PKGCONFIG= $(INSTALL_LIB)/pkgconfig INSTALL_TNAME= luajit-$(VERSION) INSTALL_TSYMNAME= luajit INSTALL_ANAME= libluajit-$(ABIVER).a -INSTALL_SONAME= libluajit-$(ABIVER).so.$(MAJVER).$(MINVER).$(RELVER) -INSTALL_SOSHORT= libluajit-$(ABIVER).so -INSTALL_DYLIBNAME= libluajit-$(ABIVER).$(MAJVER).$(MINVER).$(RELVER).dylib +INSTALL_SOSHORT1= libluajit-$(ABIVER).so +INSTALL_SOSHORT2= libluajit-$(ABIVER).so.$(MAJVER) +INSTALL_SONAME= $(INSTALL_SOSHORT2).$(MINVER).$(RELVER) INSTALL_DYLIBSHORT1= libluajit-$(ABIVER).dylib INSTALL_DYLIBSHORT2= libluajit-$(ABIVER).$(MAJVER).dylib +INSTALL_DYLIBNAME= libluajit-$(ABIVER).$(MAJVER).$(MINVER).$(RELVER).dylib INSTALL_PCNAME= luajit.pc INSTALL_STATIC= $(INSTALL_LIB)/$(INSTALL_ANAME) INSTALL_DYN= $(INSTALL_LIB)/$(INSTALL_SONAME) -INSTALL_SHORT1= $(INSTALL_LIB)/$(INSTALL_SOSHORT) -INSTALL_SHORT2= $(INSTALL_LIB)/$(INSTALL_SOSHORT) +INSTALL_SHORT1= $(INSTALL_LIB)/$(INSTALL_SOSHORT1) +INSTALL_SHORT2= $(INSTALL_LIB)/$(INSTALL_SOSHORT2) INSTALL_T= $(INSTALL_BIN)/$(INSTALL_TNAME) INSTALL_TSYM= $(INSTALL_BIN)/$(INSTALL_TSYMNAME) INSTALL_PC= $(INSTALL_PKGCONFIG)/$(INSTALL_PCNAME) @@ -85,16 +86,22 @@ FILE_MAN= luajit.1 FILE_PC= luajit.pc FILES_INC= lua.h lualib.h lauxlib.h luaconf.h lua.hpp luajit.h FILES_JITLIB= bc.lua bcsave.lua dump.lua p.lua v.lua zone.lua \ - dis_x86.lua dis_x64.lua dis_arm.lua dis_ppc.lua \ - dis_mips.lua dis_mipsel.lua vmdef.lua + dis_x86.lua dis_x64.lua dis_arm.lua dis_arm64.lua \ + dis_arm64be.lua dis_ppc.lua dis_mips.lua dis_mipsel.lua \ + dis_mips64.lua dis_mips64el.lua vmdef.lua ifeq (,$(findstring Windows,$(OS))) - ifeq (Darwin,$(shell uname -s)) - INSTALL_SONAME= $(INSTALL_DYLIBNAME) - INSTALL_SHORT1= $(INSTALL_LIB)/$(INSTALL_DYLIBSHORT1) - INSTALL_SHORT2= $(INSTALL_LIB)/$(INSTALL_DYLIBSHORT2) - LDCONFIG= : - endif + HOST_SYS:= $(shell uname -s) +else + HOST_SYS= Windows +endif +TARGET_SYS?= $(HOST_SYS) + +ifeq (Darwin,$(TARGET_SYS)) + INSTALL_SONAME= $(INSTALL_DYLIBNAME) + INSTALL_SOSHORT1= $(INSTALL_DYLIBSHORT1) + INSTALL_SOSHORT2= $(INSTALL_DYLIBSHORT2) + LDCONFIG= : endif ############################################################################## diff --git a/Build/source/libs/luajit/LuaJIT-src/README b/Build/source/libs/luajit/LuaJIT-src/README index 01fd4a0c937..2b9ae9d2231 100644 --- a/Build/source/libs/luajit/LuaJIT-src/README +++ b/Build/source/libs/luajit/LuaJIT-src/README @@ -1,11 +1,11 @@ -README for LuaJIT 2.1.0-beta2 +README for LuaJIT 2.1.0-beta3 ----------------------------- LuaJIT is a Just-In-Time (JIT) compiler for the Lua programming language. Project Homepage: http://luajit.org/ -LuaJIT is Copyright (C) 2005-2016 Mike Pall. +LuaJIT is Copyright (C) 2005-2017 Mike Pall. LuaJIT is free software, released under the MIT license. See full Copyright Notice in the COPYRIGHT file or in luajit.h. diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/bluequad-print.css b/Build/source/libs/luajit/LuaJIT-src/doc/bluequad-print.css index 975a55bfa31..62e1c165909 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/bluequad-print.css +++ b/Build/source/libs/luajit/LuaJIT-src/doc/bluequad-print.css @@ -1,4 +1,4 @@ -/* Copyright (C) 2004-2016 Mike Pall. +/* Copyright (C) 2004-2017 Mike Pall. * * You are welcome to use the general ideas of this design for your own sites. * But please do not steal the stylesheet, the layout or the color scheme. diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/bluequad.css b/Build/source/libs/luajit/LuaJIT-src/doc/bluequad.css index 5dca9064e82..be2c4bf2d51 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/bluequad.css +++ b/Build/source/libs/luajit/LuaJIT-src/doc/bluequad.css @@ -1,4 +1,4 @@ -/* Copyright (C) 2004-2016 Mike Pall. +/* Copyright (C) 2004-2017 Mike Pall. * * You are welcome to use the general ideas of this design for your own sites. * But please do not steal the stylesheet, the layout or the color scheme. diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/changes.html b/Build/source/libs/luajit/LuaJIT-src/doc/changes.html index 9684d7c0a19..a66a8d95049 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/changes.html +++ b/Build/source/libs/luajit/LuaJIT-src/doc/changes.html @@ -4,7 +4,7 @@ <title>LuaJIT Change History</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="Author" content="Mike Pall"> -<meta name="Copyright" content="Copyright (C) 2005-2016, Mike Pall"> +<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall"> <meta name="Language" content="en"> <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> @@ -65,7 +65,7 @@ div.major { max-width: 600px; padding: 1em; margin: 1em 0 1em 0; } <div id="main"> <p> This is a list of changes between the released versions of LuaJIT.<br> -The current <span style="color: #0000c0;">stable version</span> is <strong>LuaJIT 2.0.4</strong>.<br> +The current <span style="color: #0000c0;">stable version</span> is <strong>LuaJIT 2.0.5</strong>.<br> </p> <p> Please check the @@ -74,6 +74,30 @@ to see whether newer versions are available. </p> <div class="major" style="background: #d0d0ff;"> +<h2 id="LuaJIT-2.1.0-beta3">LuaJIT 2.1.0-beta3 — 2017-05-01</h2> +<ul> +<li>Rewrite memory block allocator.</li> +<li>Add various extension from Lua 5.2/5.3.</li> +<li>Remove old Lua 5.0 compatibility defines.</li> +<li>Set arg table before evaluating <tt>LUA_INIT</tt> and <tt>-e</tt> chunks.</li> +<li>Fix FOLD rules for <tt>math.abs()</tt> and FP negation.</li> +<li>Fix soft-float <tt>math.abs()</tt> and negation.</li> +<li>Fix formatting of some small denormals at low precision.</li> +<li>LJ_GC64: Add JIT compiler support.</li> +<li>x64/LJ_GC64: Add JIT compiler backend.</li> +<li>x86/x64: Generate BMI2 shifts and rotates, if available.</li> +<li>Windows/x86: Add full exception interoperability.</li> +<li>ARM64: Add big-endian support.</li> +<li>ARM64: Add JIT compiler backend.</li> +<li>MIPS: Fix <tt>TSETR</tt> barrier.</li> +<li>MIPS: Support MIPS16 interlinking.</li> +<li>MIPS soft-float: Fix code generation for <tt>HREF</tt>.</li> +<li>MIPS64: Add MIPS64 hard-float JIT compiler backend.</li> +<li>MIPS64: Add MIPS64 hard-float/soft-float support to interpreter.</li> +<li>FFI: Compile bitfield loads/stores.</li> +<li>Various fixes common with the 2.0 branch.</li> +</ul> + <h2 id="LuaJIT-2.1.0-beta2">LuaJIT 2.1.0-beta2 — 2016-03-03</h2> <ul> <li>Enable trace stitching.</li> @@ -140,6 +164,48 @@ Please take a look at the commit history for more details. </div> <div class="major" style="background: #ffffd0;"> +<h2 id="LuaJIT-2.0.5">LuaJIT 2.0.5 — 2017-05-01</h2> +<ul> +<li>Add workaround for MSVC 2015 stdio changes.</li> +<li>Limit mcode alloc probing, depending on the available pool size.</li> +<li>Fix overly restrictive range calculation in mcode allocation.</li> +<li>Fix out-of-scope goto handling in parser.</li> +<li>Remove internal <tt>__mode = "K"</tt> and replace with safe check.</li> +<li>Add "proto" field to <tt>jit.util.funcinfo()</tt>.</li> +<li>Fix GC step size calculation.</li> +<li>Initialize <tt>uv->immutable</tt> for upvalues of loaded chunks.</li> +<li>Fix for cdata vs. non-cdata arithmetics/comparisons.</li> +<li>Drop leftover regs in 'for' iterator assignment, too.</li> +<li>Fix PHI remarking in SINK pass.</li> +<li>Don't try to record outermost <tt>pcall()</tt> return to lower frame.</li> +<li>Add guard for obscure aliasing between open upvalues and SSA slots.</li> +<li>Remove assumption that <tt>lj_math_random_step()</tt> doesn't clobber FPRs.</li> +<li>Fix handling of non-numeric strings in arithmetic coercions.</li> +<li>Fix recording of <tt>select(n, ...)</tt> with off-trace varargs</li> +<li>Fix install for cross-builds.</li> +<li>Don't allocate unused 2nd result register in JIT compiler backend.</li> +<li>Drop marks from replayed instructions when sinking.</li> +<li>Fix unsinking check.</li> +<li>Properly handle OOM in <tt>trace_save()</tt>.</li> +<li>Limit number of arguments given to <tt>io.lines()</tt> and <tt>fp:lines()</tt>.</li> +<li>Fix narrowing of <tt>TOBIT</tt>.</li> +<li>OSX: Fix build with recent XCode.</li> +<li>x86/x64: Don't spill an explicit <tt>REF_BASE</tt> in the IR.</li> +<li>x86/x64: Fix instruction length decoder.</li> +<li>x86/x64: Search for exit jumps with instruction length decoder.</li> +<li>ARM: Fix <tt>BLX</tt> encoding for Thumb interworking calls.</li> +<li>MIPS: Don't use <tt>RID_GP</tt> as a scratch register.</li> +<li>MIPS: Fix emitted code for U32 to float conversion.</li> +<li>MIPS: Backport workaround for compact unwind tables.</li> +<li>MIPS: Fix cross-endian jit.bcsave.</li> +<li>MIPS: Fix <tt>BC_ISNEXT</tt> fallback path.</li> +<li>MIPS: Fix use of ffgccheck delay slots in interpreter.</li> +<li>FFI: Fix FOLD rules for <tt>int64_t</tt> comparisons.</li> +<li>FFI: Fix SPLIT pass for <tt>CONV i64.u64</tt>.</li> +<li>FFI: Fix <tt>ipairs()</tt> recording.</li> +<li>FFI: Don't propagate qualifiers into subtypes of complex.</li> +</ul> + <h2 id="LuaJIT-2.0.4">LuaJIT 2.0.4 — 2015-05-14</h2> <ul> <li>Fix stack check in narrowing optimization.</li> @@ -807,7 +873,7 @@ no point in listing differences over earlier versions.</li> </div> <div id="foot"> <hr class="hide"> -Copyright © 2005-2016 Mike Pall +Copyright © 2005-2017 Mike Pall <span class="noprint"> · <a href="contact.html">Contact</a> diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/contact.html b/Build/source/libs/luajit/LuaJIT-src/doc/contact.html index 5262376464c..fe4751c0ead 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/contact.html +++ b/Build/source/libs/luajit/LuaJIT-src/doc/contact.html @@ -4,7 +4,7 @@ <title>Contact</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="Author" content="Mike Pall"> -<meta name="Copyright" content="Copyright (C) 2005-2016, Mike Pall"> +<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall"> <meta name="Language" content="en"> <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> @@ -61,8 +61,15 @@ </div> <div id="main"> <p> +If you want to report bugs, propose fixes or suggest enhancements, +please use the +<a href="https://github.com/LuaJIT/LuaJIT/issues">GitHub issue tracker</a>. +</p> +<p> Please send general questions to the <a href="http://luajit.org/list.html"><span class="ext">»</span> LuaJIT mailing list</a>. +</p> +<p> You can also send any questions you have directly to me: </p> @@ -86,7 +93,7 @@ xD("fyZKB8xv\"FJytmz8.KAB0u52D") <h2>Copyright</h2> <p> All documentation is -Copyright © 2005-2016 Mike Pall. +Copyright © 2005-2017 Mike Pall. </p> @@ -94,7 +101,7 @@ Copyright © 2005-2016 Mike Pall. </div> <div id="foot"> <hr class="hide"> -Copyright © 2005-2016 Mike Pall +Copyright © 2005-2017 Mike Pall <span class="noprint"> · <a href="contact.html">Contact</a> diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/ext_c_api.html b/Build/source/libs/luajit/LuaJIT-src/doc/ext_c_api.html index e1af3ed004d..ad462c63e51 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/ext_c_api.html +++ b/Build/source/libs/luajit/LuaJIT-src/doc/ext_c_api.html @@ -4,7 +4,7 @@ <title>Lua/C API Extensions</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="Author" content="Mike Pall"> -<meta name="Copyright" content="Copyright (C) 2005-2016, Mike Pall"> +<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall"> <meta name="Language" content="en"> <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> @@ -179,7 +179,7 @@ Also note that this mechanism is not without overhead. </div> <div id="foot"> <hr class="hide"> -Copyright © 2005-2016 Mike Pall +Copyright © 2005-2017 Mike Pall <span class="noprint"> · <a href="contact.html">Contact</a> diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi.html b/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi.html index d814f4d04a3..5e1daaf54b7 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi.html +++ b/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi.html @@ -4,7 +4,7 @@ <title>FFI Library</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="Author" content="Mike Pall"> -<meta name="Copyright" content="Copyright (C) 2005-2016, Mike Pall"> +<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall"> <meta name="Language" content="en"> <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> @@ -322,7 +322,7 @@ without undue conversion penalties. </div> <div id="foot"> <hr class="hide"> -Copyright © 2005-2016 Mike Pall +Copyright © 2005-2017 Mike Pall <span class="noprint"> · <a href="contact.html">Contact</a> diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi_api.html b/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi_api.html index 6d405960092..91af2e1d43d 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi_api.html +++ b/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi_api.html @@ -4,7 +4,7 @@ <title>ffi.* API Functions</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="Author" content="Mike Pall"> -<meta name="Copyright" content="Copyright (C) 2005-2016, Mike Pall"> +<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall"> <meta name="Language" content="en"> <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> @@ -560,7 +560,7 @@ named <tt>i</tt>. </div> <div id="foot"> <hr class="hide"> -Copyright © 2005-2016 Mike Pall +Copyright © 2005-2017 Mike Pall <span class="noprint"> · <a href="contact.html">Contact</a> diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi_semantics.html b/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi_semantics.html index 15843d7cc57..800b6b18a0e 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi_semantics.html +++ b/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi_semantics.html @@ -4,7 +4,7 @@ <title>FFI Semantics</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="Author" content="Mike Pall"> -<meta name="Copyright" content="Copyright (C) 2005-2016, Mike Pall"> +<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall"> <meta name="Language" content="en"> <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> @@ -1221,13 +1221,12 @@ The following operations are currently not compiled and may exhibit suboptimal performance, especially when used in inner loops: </p> <ul> -<li>Bitfield accesses and initializations.</li> <li>Vector operations.</li> <li>Table initializers.</li> <li>Initialization of nested <tt>struct</tt>/<tt>union</tt> types.</li> <li>Non-default initialization of VLA/VLS or large C types (> 128 bytes or > 16 array elements.</li> -<li>Conversions from lightuserdata to <tt>void *</tt>.</li> +<li>Bitfield initializations.</li> <li>Pointer differences for element sizes that are not a power of two.</li> <li>Calls to C functions with aggregates passed or returned by @@ -1253,7 +1252,7 @@ compiled.</li> </div> <div id="foot"> <hr class="hide"> -Copyright © 2005-2016 Mike Pall +Copyright © 2005-2017 Mike Pall <span class="noprint"> · <a href="contact.html">Contact</a> diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi_tutorial.html b/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi_tutorial.html index 01200c45c11..3650066440a 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi_tutorial.html +++ b/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi_tutorial.html @@ -4,7 +4,7 @@ <title>FFI Tutorial</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="Author" content="Mike Pall"> -<meta name="Copyright" content="Copyright (C) 2005-2016, Mike Pall"> +<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall"> <meta name="Language" content="en"> <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> @@ -593,7 +593,7 @@ it to a local variable in the function scope is unnecessary. </div> <div id="foot"> <hr class="hide"> -Copyright © 2005-2016 Mike Pall +Copyright © 2005-2017 Mike Pall <span class="noprint"> · <a href="contact.html">Contact</a> diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/ext_jit.html b/Build/source/libs/luajit/LuaJIT-src/doc/ext_jit.html index 9489c6f5cfb..e4088bcbd20 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/ext_jit.html +++ b/Build/source/libs/luajit/LuaJIT-src/doc/ext_jit.html @@ -4,7 +4,7 @@ <title>jit.* Library</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="Author" content="Mike Pall"> -<meta name="Copyright" content="Copyright (C) 2005-2016, Mike Pall"> +<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall"> <meta name="Language" content="en"> <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> @@ -153,7 +153,7 @@ Contains the target OS name: <h3 id="jit_arch"><tt>jit.arch</tt></h3> <p> Contains the target architecture name: -"x86", "x64", "arm", "ppc", or "mips". +"x86", "x64", "arm", "arm64", "ppc", "mips" or "mips64". </p> <h2 id="jit_opt"><tt>jit.opt.*</tt> — JIT compiler optimization control</h2> @@ -191,7 +191,7 @@ if you want to know more. </div> <div id="foot"> <hr class="hide"> -Copyright © 2005-2016 Mike Pall +Copyright © 2005-2017 Mike Pall <span class="noprint"> · <a href="contact.html">Contact</a> diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/ext_profiler.html b/Build/source/libs/luajit/LuaJIT-src/doc/ext_profiler.html index 69ea25dbeba..71b8c03339e 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/ext_profiler.html +++ b/Build/source/libs/luajit/LuaJIT-src/doc/ext_profiler.html @@ -4,7 +4,7 @@ <title>Profiler</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="Author" content="Mike Pall"> -<meta name="Copyright" content="Copyright (C) 2005-2016, Mike Pall"> +<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall"> <meta name="Language" content="en"> <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> @@ -355,7 +355,7 @@ use. </div> <div id="foot"> <hr class="hide"> -Copyright © 2005-2016 Mike Pall +Copyright © 2005-2017 Mike Pall <span class="noprint"> · <a href="contact.html">Contact</a> diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/extensions.html b/Build/source/libs/luajit/LuaJIT-src/doc/extensions.html index 7f712a62144..d7cc9693beb 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/extensions.html +++ b/Build/source/libs/luajit/LuaJIT-src/doc/extensions.html @@ -4,7 +4,7 @@ <title>Extensions</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="Author" content="Mike Pall"> -<meta name="Copyright" content="Copyright (C) 2005-2016, Mike Pall"> +<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall"> <meta name="Language" content="en"> <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> @@ -210,7 +210,8 @@ bytecode (e.g. from Lua 5.1) is incompatible and cannot be loaded. <p> Note: <tt>LJ_GC64</tt> mode requires a different frame layout, which implies a different, incompatible bytecode format for ports that use this mode (e.g. -ARM64). This may be rectified in the future. +ARM64 or MIPS64) or when explicitly enabled for x64. This may be rectified +in the future. </p> <h3 id="table_new"><tt>table.new(narray, nhash)</tt> allocates a pre-sized table</h3> @@ -291,8 +292,8 @@ enabled: <li><tt>load(string|reader [, chunkname [,mode [,env]]])</tt>.</li> <li><tt>loadstring()</tt> is an alias for <tt>load()</tt>.</li> <li><tt>loadfile(filename [,mode [,env]])</tt>.</li> -<li><tt>math.log(x [,base])</tt>. -<li><tt>string.rep(s, n [,sep])</tt>. +<li><tt>math.log(x [,base])</tt>.</li> +<li><tt>string.rep(s, n [,sep])</tt>.</li> <li><tt>string.format()</tt>: <tt>%q</tt> reversible. <tt>%s</tt> checks <tt>__tostring</tt>. <tt>%a</tt> and <tt>"%A</tt> added.</li> @@ -311,6 +312,26 @@ indexes for varargs.</li> <li><tt>debug.getupvalue()</tt> and <tt>debug.setupvalue()</tt> handle C functions.</li> <li><tt>debug.upvalueid()</tt> and <tt>debug.upvaluejoin()</tt>.</li> +<li>Lua/C API extensions: +<tt>lua_version()</tt> +<tt>lua_upvalueid()</tt> +<tt>lua_upvaluejoin()</tt> +<tt>lua_loadx()</tt> +<tt>lua_copy()</tt> +<tt>lua_tonumberx()</tt> +<tt>lua_tointegerx()</tt> +<tt>luaL_fileresult()</tt> +<tt>luaL_execresult()</tt> +<tt>luaL_loadfilex()</tt> +<tt>luaL_loadbufferx()</tt> +<tt>luaL_traceback()</tt> +<tt>luaL_setfuncs()</tt> +<tt>luaL_pushmodule()</tt> +<tt>luaL_newlibtable()</tt> +<tt>luaL_newlib()</tt> +<tt>luaL_testudata()</tt> +<tt>luaL_setmetatable()</tt> +</li> <li>Command line option <tt>-E</tt>.</li> <li>Command line checks <tt>__tostring</tt> for errors.</li> </ul> @@ -335,7 +356,9 @@ instead of <tt>true</tt>.</li> exit status.</li> <li><tt>debug.setmetatable()</tt> returns object.</li> <li><tt>debug.getuservalue()</tt> and <tt>debug.setuservalue()</tt>.</li> -<li>Remove <tt>math.mod()</tt>, <tt>string.gfind()</tt>. +<li>Remove <tt>math.mod()</tt>, <tt>string.gfind()</tt>.</li> +<li><tt>package.searchers</tt>.</li> +<li><tt>module()</tt> returns the module table.</li> </ul> <p> Note: this provides only partial compatibility with Lua 5.2 at the @@ -349,6 +372,13 @@ break the Lua/C API and ABI (e.g. <tt>_ENV</tt>). LuaJIT supports some extensions from Lua 5.3: <ul> <li>Unicode escape <tt>'\u{XX...}'</tt> embeds the UTF-8 encoding in string literals.</li> +<li>The argument table <tt>arg</tt> can be read (and modified) by <tt>LUA_INIT</tt> and <tt>-e</tt> chunks.</li> +<li><tt>io.read()</tt> and <tt>file:read()</tt> accept formats with or without a leading <tt>*</tt>.</li> +<li><tt>table.move(a1, f, e, t [,a2])</tt>.</li> +<li><tt>coroutine.isyieldable()</tt>.</li> +<li>Lua/C API extensions: +<tt>lua_isyieldable()</tt> +</li> </ul> <h2 id="exceptions">C++ Exception Interoperability</h2> @@ -365,25 +395,30 @@ the toolchain used to compile LuaJIT: </tr> <tr class="odd separate"> <td class="excplatform">POSIX/x64, DWARF2 unwinding</td> -<td class="exccompiler">GCC 4.3+</td> +<td class="exccompiler">GCC 4.3+, Clang</td> <td class="excinterop"><b style="color: #00a000;">Full</b></td> </tr> <tr class="even"> +<td class="excplatform">ARM <tt>-DLUAJIT_UNWIND_EXTERNAL</tt></td> +<td class="exccompiler">GCC, Clang</td> +<td class="excinterop"><b style="color: #00a000;">Full</b></td> +</tr> +<tr class="odd"> <td class="excplatform">Other platforms, DWARF2 unwinding</td> -<td class="exccompiler">GCC</td> +<td class="exccompiler">GCC, Clang</td> <td class="excinterop"><b style="color: #c06000;">Limited</b></td> </tr> -<tr class="odd"> +<tr class="even"> <td class="excplatform">Windows/x64</td> <td class="exccompiler">MSVC or WinSDK</td> <td class="excinterop"><b style="color: #00a000;">Full</b></td> </tr> -<tr class="even"> +<tr class="odd"> <td class="excplatform">Windows/x86</td> <td class="exccompiler">Any</td> -<td class="excinterop"><b style="color: #a00000;">No</b></td> +<td class="excinterop"><b style="color: #00a000;">Full</b></td> </tr> -<tr class="odd"> +<tr class="even"> <td class="excplatform">Other platforms</td> <td class="exccompiler">Other compilers</td> <td class="excinterop"><b style="color: #a00000;">No</b></td> @@ -432,20 +467,12 @@ C++ destructors.</li> <li>Lua errors <b>cannot</b> be caught on the C++ side.</li> <li>Throwing Lua errors across C++ frames will <b>not</b> call C++ destructors.</li> -<li>Additionally, on Windows/x86 with SEH-based C++ exceptions: -it's <b>not</b> safe to throw a Lua error across any frames containing -a C++ function with any try/catch construct or using variables with -(implicit) destructors. This also applies to any functions which may be -inlined in such a function. It doesn't matter whether <tt>lua_error()</tt> -is called inside or outside of a try/catch or whether any object actually -needs to be destroyed: the SEH chain is corrupted and this will eventually -lead to the termination of the process.</li> </ul> <br class="flush"> </div> <div id="foot"> <hr class="hide"> -Copyright © 2005-2016 Mike Pall +Copyright © 2005-2017 Mike Pall <span class="noprint"> · <a href="contact.html">Contact</a> diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/faq.html b/Build/source/libs/luajit/LuaJIT-src/doc/faq.html index 605fdd0a2ce..2c930743ddf 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/faq.html +++ b/Build/source/libs/luajit/LuaJIT-src/doc/faq.html @@ -4,7 +4,7 @@ <title>Frequently Asked Questions (FAQ)</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="Author" content="Mike Pall"> -<meta name="Copyright" content="Copyright (C) 2005-2016, Mike Pall"> +<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall"> <meta name="Language" content="en"> <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> @@ -176,7 +176,7 @@ the development of certain features, if they are important to you. </div> <div id="foot"> <hr class="hide"> -Copyright © 2005-2016 Mike Pall +Copyright © 2005-2017 Mike Pall <span class="noprint"> · <a href="contact.html">Contact</a> diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/install.html b/Build/source/libs/luajit/LuaJIT-src/doc/install.html index dba63fd868d..c491c601432 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/install.html +++ b/Build/source/libs/luajit/LuaJIT-src/doc/install.html @@ -4,7 +4,7 @@ <title>Installation</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="Author" content="Mike Pall"> -<meta name="Copyright" content="Copyright (C) 2005-2016, Mike Pall"> +<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall"> <meta name="Language" content="en"> <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> @@ -122,7 +122,7 @@ operating systems, CPUs and compilers: <tr class="even"> <td class="compatcpu">x64 (64 bit)</td> <td class="compatos">GCC 4.2+</td> -<td class="compatos">ORBIS (<a href="#ps4">PS4</a>)</td> +<td class="compatos">GCC 4.2+<br>ORBIS (<a href="#ps4">PS4</a>)</td> <td class="compatos">XCode 5.0+<br>Clang</td> <td class="compatos">MSVC + SDK v7.0<br>WinSDK v7.0<br>Durango (<a href="#xboxone">Xbox One</a>)</td> </tr> @@ -148,7 +148,7 @@ operating systems, CPUs and compilers: <td class="compatos">XEDK (<a href="#xbox360">Xbox 360</a>)</td> </tr> <tr class="even"> -<td class="compatcpu"><a href="#cross2">MIPS</a></td> +<td class="compatcpu"><a href="#cross2">MIPS32<br>MIPS64</a></td> <td class="compatos">GCC 4.3+</td> <td class="compatos">GCC 4.3+</td> <td class="compatos compatno"> </td> @@ -175,6 +175,14 @@ MSVC or WinSDK.</li> Please read the instructions given in these files, before changing any settings. </p> +<p> +LuaJIT on x64 currently uses 32 bit GC objects by default. +<tt>LJ_GC64</tt> mode may be explicitly enabled: +add <tt>XCFLAGS=-DLUAJIT_ENABLE_GC64</tt> to the make command or run +<tt>msvcbuild gc64</tt> for MSVC/WinSDK. Please check the note +about the <a href="extensions.html#string_dump">bytecode format</a> +differences, too. +</p> <h2 id="posix">POSIX Systems (Linux, OSX, *BSD etc.)</h2> <h3>Prerequisites</h3> @@ -190,8 +198,8 @@ open a terminal window and change to this directory. Now unpack the archive and change to the newly created directory: </p> <pre class="code"> -tar zxf LuaJIT-2.0.4.tar.gz -cd LuaJIT-2.0.4</pre> +tar zxf LuaJIT-2.0.5.tar.gz +cd LuaJIT-2.0.5</pre> <h3>Building LuaJIT</h3> <p> The supplied Makefiles try to auto-detect the settings needed for your @@ -202,7 +210,7 @@ which is probably the default on your system, anyway. Simply run: make </pre> <p> -This always builds a native x86, x64 or PPC binary, depending on the host OS +This always builds a native binary, depending on the host OS you're running this command on. Check the section on <a href="#cross">cross-compilation</a> for more options. </p> @@ -333,22 +341,36 @@ directory where <tt>luajit.exe</tt> is installed <h2 id="cross">Cross-compiling LuaJIT</h2> <p> +First, let's clear up some terminology: +</p> +<ul> +<li>Host: This is your development system, usually based on a x64 or x86 CPU.</li> +<li>Target: This is the target system you want LuaJIT to run on, e.g. Android/ARM.</li> +<li>Toolchain: This comprises a C compiler, linker, assembler and a matching C library.</li> +<li>Host (or system) toolchain: This is the toolchain used to build native binaries for your host system.</li> +<li>Cross-compile toolchain: This is the toolchain used to build binaries for the target system. They can only be run on the target system.</li> +</ul> +<p> The GNU Makefile-based build system allows cross-compiling on any host -for any supported target, as long as both architectures have the same -pointer size. If you want to cross-compile to any 32 bit target on an -x64 OS, you need to install the multilib development package (e.g. -<tt>libc6-dev-i386</tt> on Debian/Ubuntu) and build a 32 bit host part -(<tt>HOST_CC="gcc -m32"</tt>). +for any supported target: </p> +<ul> +<li>Yes, you need a toolchain for both your host <em>and</em> your target!</li> +<li>Both host and target architectures must have the same pointer size.</li> +<li>E.g. if you want to cross-compile to a 32 bit target on a 64 bit host, you need to install the multilib development package (e.g. <tt>libc6-dev-i386</tt> on Debian/Ubuntu) and build a 32 bit host part (<tt>HOST_CC="gcc -m32"</tt>).</li> +<li>64 bit targets always require compilation on a 64 bit host.</li> +</ul> <p> You need to specify <tt>TARGET_SYS</tt> whenever the host OS and the -target OS differ, or you'll get assembler or linker errors. E.g. if -you're compiling on a Windows or OSX host for embedded Linux or Android, -you need to add <tt>TARGET_SYS=Linux</tt> to the examples below. For a -minimal target OS, you may need to disable the built-in allocator in -<tt>src/Makefile</tt> and use <tt>TARGET_SYS=Other</tt>. The examples -below only show some popular targets — please check the comments -in <tt>src/Makefile</tt> for more details. +target OS differ, or you'll get assembler or linker errors: +</p> +<ul> +<li>E.g. if you're compiling on a Windows or OSX host for embedded Linux or Android, you need to add <tt>TARGET_SYS=Linux</tt> to the examples below.</li> +<li>For a minimal target OS, you may need to disable the built-in allocator in <tt>src/Makefile</tt> and use <tt>TARGET_SYS=Other</tt>.</li> +<li>Don't forget to specify the same <tt>TARGET_SYS</tt> for the install step, too.</li> +</ul> +<p> +Here are some examples where host and target have the same CPU: </p> <pre class="code"> # Cross-compile to a 32 bit binary on a multilib x64 OS @@ -366,38 +388,47 @@ use the canonical toolchain triplets for Linux. </p> <p> Since there's often no easy way to detect CPU features at runtime, it's -important to compile with the proper CPU or architecture settings. You -can specify these when building the toolchain yourself. Or add -<tt>-mcpu=...</tt> or <tt>-march=...</tt> to <tt>TARGET_CFLAGS</tt>. For -ARM it's important to have the correct <tt>-mfloat-abi=...</tt> setting, -too. Otherwise LuaJIT may not run at the full performance of your target -CPU. +important to compile with the proper CPU or architecture settings: +</o> +<ul> +<li>The best way to get consistent results is to specify the correct settings when building the toolchain yourself.</li> +<li>For a pre-built, generic toolchain add <tt>-mcpu=...</tt> or <tt>-march=...</tt> and other necessary flags to <tt>TARGET_CFLAGS</tt>.</li> +<li>For ARM it's important to have the correct <tt>-mfloat-abi=...</tt> setting, too. Otherwise LuaJIT may not run at the full performance of your target CPU.</li> +<li>For MIPS it's important to select a supported ABI (o32 on MIPS32, n64 on MIPS64) and consistently compile your project either with hard-float or soft-float compiler settings.</li> +</ul> +<p> +Here are some examples for targets with a different CPU than the host: </p> <pre class="code"> # ARM soft-float make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabi- \ TARGET_CFLAGS="-mfloat-abi=soft" -# ARM soft-float ABI with VFP (example for Cortex-A8) +# ARM soft-float ABI with VFP (example for Cortex-A9) make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabi- \ - TARGET_CFLAGS="-mcpu=cortex-a8 -mfloat-abi=softfp" + TARGET_CFLAGS="-mcpu=cortex-a9 -mfloat-abi=softfp" -# ARM hard-float ABI with VFP (armhf, requires recent toolchain) +# ARM hard-float ABI with VFP (armhf, most modern toolchains) make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabihf- -# ARM64 (requires x64 host) +# ARM64 make CROSS=aarch64-linux- # PPC make HOST_CC="gcc -m32" CROSS=powerpc-linux-gnu- -# MIPS big-endian +# MIPS32 big-endian make HOST_CC="gcc -m32" CROSS=mips-linux- -# MIPS little-endian +# MIPS32 little-endian make HOST_CC="gcc -m32" CROSS=mipsel-linux- + +# MIPS64 big-endian +make CROSS=mips-linux- TARGET_CFLAGS="-mips64r2 -mabi=64" +# MIPS64 little-endian +make CROSS=mipsel-linux- TARGET_CFLAGS="-mips64r2 -mabi=64" </pre> <p> -You can cross-compile for <b id="android">Android</b> using the <a href="http://developer.android.com/sdk/ndk/index.html"><span class="ext">»</span> Android NDK</a>. +You can cross-compile for <b id="android">Android</b> using the <a href="https://developer.android.com/ndk/index.html">Android NDK</a>. The environment variables need to match the install locations and the desired target platform. E.g. Android 4.0 corresponds to ABI level 14. For details check the folder <tt>docs</tt> in the NDK directory. @@ -411,7 +442,7 @@ to build/deploy or which lowest common denominator you want to pick: # Android/ARM, armeabi (ARMv5TE soft-float), Android 2.2+ (Froyo) NDK=/opt/android/ndk NDKABI=8 -NDKVER=$NDK/toolchains/arm-linux-androideabi-4.6 +NDKVER=$NDK/toolchains/arm-linux-androideabi-4.9 NDKP=$NDKVER/prebuilt/linux-x86/bin/arm-linux-androideabi- NDKF="--sysroot $NDK/platforms/android-$NDKABI/arch-arm" make HOST_CC="gcc -m32" CROSS=$NDKP TARGET_FLAGS="$NDKF" @@ -419,16 +450,16 @@ make HOST_CC="gcc -m32" CROSS=$NDKP TARGET_FLAGS="$NDKF" # Android/ARM, armeabi-v7a (ARMv7 VFP), Android 4.0+ (ICS) NDK=/opt/android/ndk NDKABI=14 -NDKVER=$NDK/toolchains/arm-linux-androideabi-4.6 +NDKVER=$NDK/toolchains/arm-linux-androideabi-4.9 NDKP=$NDKVER/prebuilt/linux-x86/bin/arm-linux-androideabi- NDKF="--sysroot $NDK/platforms/android-$NDKABI/arch-arm" NDKARCH="-march=armv7-a -mfloat-abi=softfp -Wl,--fix-cortex-a8" make HOST_CC="gcc -m32" CROSS=$NDKP TARGET_FLAGS="$NDKF $NDKARCH" -# Android/MIPS, mips (MIPS32R1 hard-float), Android 4.0+ (ICS) +# Android/MIPS, mipsel (MIPS32R1 hard-float), Android 4.0+ (ICS) NDK=/opt/android/ndk NDKABI=14 -NDKVER=$NDK/toolchains/mipsel-linux-android-4.6 +NDKVER=$NDK/toolchains/mipsel-linux-android-4.9 NDKP=$NDKVER/prebuilt/linux-x86/bin/mipsel-linux-android- NDKF="--sysroot $NDK/platforms/android-$NDKABI/arch-mips" make HOST_CC="gcc -m32" CROSS=$NDKP TARGET_FLAGS="$NDKF" @@ -436,7 +467,7 @@ make HOST_CC="gcc -m32" CROSS=$NDKP TARGET_FLAGS="$NDKF" # Android/x86, x86 (i686 SSE3), Android 4.0+ (ICS) NDK=/opt/android/ndk NDKABI=14 -NDKVER=$NDK/toolchains/x86-4.6 +NDKVER=$NDK/toolchains/x86-4.9 NDKP=$NDKVER/prebuilt/linux-x86/bin/i686-linux-android- NDKF="--sysroot $NDK/platforms/android-$NDKABI/arch-x86" make HOST_CC="gcc -m32" CROSS=$NDKP TARGET_FLAGS="$NDKF" @@ -456,14 +487,15 @@ Or use Android. :-p ISDKP=$(xcrun --sdk iphoneos --show-sdk-path) ICC=$(xcrun --sdk iphoneos --find clang) ISDKF="-arch armv7 -isysroot $ISDKP" -make HOST_CC="clang -m32 -arch i386" CROSS="$(dirname $ICC)/" \ - TARGET_FLAGS="$ISDKF" TARGET_SYS=iOS +make DEFAULT_CC=clang HOST_CC="clang -m32 -arch i386" \ + CROSS="$(dirname $ICC)/" TARGET_FLAGS="$ISDKF" TARGET_SYS=iOS # iOS/ARM64 ISDKP=$(xcrun --sdk iphoneos --show-sdk-path) ICC=$(xcrun --sdk iphoneos --find clang) ISDKF="-arch arm64 -isysroot $ISDKP" -make CROSS="$(dirname $ICC)/" TARGET_FLAGS="$ISDKF" TARGET_SYS=iOS +make DEFAULT_CC=clang CROSS="$(dirname $ICC)/" \ + TARGET_FLAGS="$ISDKF" TARGET_SYS=iOS </pre> <h3 id="consoles">Cross-compiling for consoles</h3> @@ -560,14 +592,11 @@ intend to load Lua/C modules at runtime. </li> <li> If you're building a 64 bit application on OSX which links directly or -indirectly against LuaJIT, you need to link your main executable -with these flags: +indirectly against LuaJIT which is not built for <tt>LJ_GC64</tt> mode, +you need to link your main executable with these flags: <pre class="code"> -pagezero_size 10000 -image_base 100000000 </pre> -Also, it's recommended to <tt>rebase</tt> all (self-compiled) shared libraries -which are loaded at runtime on OSX/x64 (e.g. C extension modules for Lua). -See: <tt>man rebase</tt> </li> </ul> <p>Additional hints for initializing LuaJIT using the C API functions:</p> @@ -653,7 +682,7 @@ to me (the upstream) and not you (the package maintainer), anyway. </div> <div id="foot"> <hr class="hide"> -Copyright © 2005-2016 Mike Pall +Copyright © 2005-2017 Mike Pall <span class="noprint"> · <a href="contact.html">Contact</a> diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/luajit.html b/Build/source/libs/luajit/LuaJIT-src/doc/luajit.html index c7a92b86cdc..ef5b824c1b3 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/luajit.html +++ b/Build/source/libs/luajit/LuaJIT-src/doc/luajit.html @@ -4,7 +4,7 @@ <title>LuaJIT</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="Author" content="Mike Pall"> -<meta name="Copyright" content="Copyright (C) 2005-2016, Mike Pall"> +<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall"> <meta name="Language" content="en"> <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> @@ -152,7 +152,7 @@ Lua is a powerful, dynamic and light-weight programming language. It may be embedded or used as a general-purpose, stand-alone language. </p> <p> -LuaJIT is Copyright © 2005-2016 Mike Pall, released under the +LuaJIT is Copyright © 2005-2017 Mike Pall, released under the <a href="http://www.opensource.org/licenses/mit-license.php"><span class="ext">»</span> MIT open source license</a>. </p> <p> @@ -169,10 +169,10 @@ LuaJIT is Copyright © 2005-2016 Mike Pall, released under the <tr><td>PS3</td><td>PS4</td><td>PS Vita</td><td>Xbox 360</td><td>Xbox One</td></tr> </table> <table class="feature compiler"> -<tr><td>GCC</td><td>CLANG<br>LLVM</td><td>MSVC</td></tr> +<tr><td>GCC</td><td>Clang<br>LLVM</td><td>MSVC</td></tr> </table> <table class="feature cpu"> -<tr><td>x86</td><td>x64</td><td>ARM</td><td>ARM64</td><td>PPC</td><td>MIPS</td></tr> +<tr><td>x86<br>x64</td><td>ARM<br>ARM64</td><td>PPC</td><td>MIPS32<br>MIPS64</td></tr> </table> <table class="feature fcompat"> <tr><td>Lua 5.1<br>API+ABI</td><td>+ JIT</td><td>+ BitOp</td><td>+ FFI</td><td>Drop-in<br>DLL/.so</td></tr> @@ -226,7 +226,7 @@ Please select a sub-topic in the navigation bar to learn more about LuaJIT. </div> <div id="foot"> <hr class="hide"> -Copyright © 2005-2016 Mike Pall +Copyright © 2005-2017 Mike Pall <span class="noprint"> · <a href="contact.html">Contact</a> diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/running.html b/Build/source/libs/luajit/LuaJIT-src/doc/running.html index 28a732641b8..666b0abca81 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/running.html +++ b/Build/source/libs/luajit/LuaJIT-src/doc/running.html @@ -4,7 +4,7 @@ <title>Running LuaJIT</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="Author" content="Mike Pall"> -<meta name="Copyright" content="Copyright (C) 2005-2016, Mike Pall"> +<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall"> <meta name="Language" content="en"> <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> @@ -189,7 +189,7 @@ itself. For a description of their options and output format, please read the comment block at the start of their source. They can be found in the <tt>lib</tt> directory of the source distribution or installed under the <tt>jit</tt> directory. By default -this is <tt>/usr/local/share/luajit-2.0.4/jit</tt> on POSIX +this is <tt>/usr/local/share/luajit-2.0.5/jit</tt> on POSIX systems. </p> @@ -299,7 +299,7 @@ Here are the parameters and their default settings: </div> <div id="foot"> <hr class="hide"> -Copyright © 2005-2016 Mike Pall +Copyright © 2005-2017 Mike Pall <span class="noprint"> · <a href="contact.html">Contact</a> diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/status.html b/Build/source/libs/luajit/LuaJIT-src/doc/status.html index 6f57db1bb97..cad6ca65468 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/status.html +++ b/Build/source/libs/luajit/LuaJIT-src/doc/status.html @@ -4,7 +4,7 @@ <title>Status</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="Author" content="Mike Pall"> -<meta name="Copyright" content="Copyright (C) 2005-2016, Mike Pall"> +<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall"> <meta name="Language" content="en"> <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> @@ -91,24 +91,29 @@ hooks for non-Lua functions) and shows slightly different behavior in LuaJIT (no per-coroutine hooks, no tail call counting). </li> <li> -Some checks are missing in the JIT-compiled code for obscure situations -with <b>open upvalues aliasing</b> one of the SSA slots later on (or -vice versa). Bonus points, if you can find a real world test case for -this. -</li> -<li> Currently some <b>out-of-memory</b> errors from <b>on-trace code</b> are not handled correctly. The error may fall through an on-trace <tt>pcall</tt> or it may be passed on to the function set with <tt>lua_atpanic</tt> on x64. This issue will be fixed with the new garbage collector. </li> +<li> +LuaJIT on 64 bit systems provides a <b>limited range</b> of 47 bits for the +<b>legacy <tt>lightuserdata</tt></b> data type. +This is only relevant on x64 systems which use the negative part of the +virtual address space in user mode, e.g. Solaris/x64, and on ARM64 systems +configured with a 48 bit or 52 bit VA. +Avoid using <tt>lightuserdata</tt> to hold pointers that may point outside +of that range, e.g. variables on the stack. In general, avoid this data +type for new code and replace it with (much more performant) FFI bindings. +FFI cdata pointers can address the full 64 bit range. +</li> </ul> <br class="flush"> </div> <div id="foot"> <hr class="hide"> -Copyright © 2005-2016 Mike Pall +Copyright © 2005-2017 Mike Pall <span class="noprint"> · <a href="contact.html">Contact</a> diff --git a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm.h b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm.h index 0fa69ac06f9..a43f7c6645c 100644 --- a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm.h +++ b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm.h @@ -1,6 +1,6 @@ /* ** DynASM ARM encoding engine. -** Copyright (C) 2005-2016 Mike Pall. All rights reserved. +** Copyright (C) 2005-2017 Mike Pall. All rights reserved. ** Released under the MIT license. See dynasm.lua for full copyright notice. */ diff --git a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm.lua b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm.lua index e2ed922a3c6..32f595afff2 100644 --- a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm.lua +++ b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm.lua @@ -1,7 +1,7 @@ ------------------------------------------------------------------------------ -- DynASM ARM module. -- --- Copyright (C) 2005-2016 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- See dynasm.lua for full copyright notice. ------------------------------------------------------------------------------ diff --git a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm64.h b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm64.h index d64e60a3e6e..47e1e074939 100644 --- a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm64.h +++ b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm64.h @@ -1,6 +1,6 @@ /* ** DynASM ARM64 encoding engine. -** Copyright (C) 2005-2016 Mike Pall. All rights reserved. +** Copyright (C) 2005-2017 Mike Pall. All rights reserved. ** Released under the MIT license. See dynasm.lua for full copyright notice. */ diff --git a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm64.lua b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm64.lua index 4a7d8dfeeb5..8a5f735d7c3 100644 --- a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm64.lua +++ b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm64.lua @@ -1,7 +1,7 @@ ------------------------------------------------------------------------------ -- DynASM ARM64 module. -- --- Copyright (C) 2005-2016 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- See dynasm.lua for full copyright notice. ------------------------------------------------------------------------------ diff --git a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_mips.h b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_mips.h index c10528fab98..4b49fd8c7c6 100644 --- a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_mips.h +++ b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_mips.h @@ -1,6 +1,6 @@ /* ** DynASM MIPS encoding engine. -** Copyright (C) 2005-2016 Mike Pall. All rights reserved. +** Copyright (C) 2005-2017 Mike Pall. All rights reserved. ** Released under the MIT license. See dynasm.lua for full copyright notice. */ @@ -21,7 +21,7 @@ enum { /* The following actions need a buffer position. */ DASM_ALIGN, DASM_REL_LG, DASM_LABEL_LG, /* The following actions also have an argument. */ - DASM_REL_PC, DASM_LABEL_PC, DASM_IMM, + DASM_REL_PC, DASM_LABEL_PC, DASM_IMM, DASM_IMMS, DASM__MAX }; @@ -231,7 +231,7 @@ void dasm_put(Dst_DECL, int start, ...) *pl = -pos; /* Label exists now. */ b[pos++] = ofs; /* Store pass1 offset estimate. */ break; - case DASM_IMM: + case DASM_IMM: case DASM_IMMS: #ifdef DASM_CHECKS CK((n & ((1<<((ins>>10)&31))-1)) == 0, RANGE_I); #endif @@ -299,7 +299,7 @@ int dasm_link(Dst_DECL, size_t *szp) case DASM_ALIGN: ofs -= (b[pos++] + ofs) & (ins & 255); break; case DASM_REL_LG: case DASM_REL_PC: pos++; break; case DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break; - case DASM_IMM: pos++; break; + case DASM_IMM: case DASM_IMMS: pos++; break; } } stop: (void)0; @@ -356,7 +356,7 @@ int dasm_encode(Dst_DECL, void *buffer) if (ins & 2048) n = n - (int)((char *)cp - base); else - n = (n + (int)base) & 0x0fffffff; + n = (n + (int)(size_t)base) & 0x0fffffff; patchrel: CK((n & 3) == 0 && ((n + ((ins & 2048) ? 0x00020000 : 0)) >> @@ -367,6 +367,9 @@ int dasm_encode(Dst_DECL, void *buffer) ins &= 2047; if (ins >= 20) D->globals[ins-10] = (void *)(base + n); break; case DASM_LABEL_PC: break; + case DASM_IMMS: + cp[-1] |= ((n>>3) & 4); n &= 0x1f; + /* fallthrough */ case DASM_IMM: cp[-1] |= (n & ((1<<((ins>>5)&31))-1)) << (ins&31); break; diff --git a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_mips.lua b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_mips.lua index c5a5595c1aa..78a4e34a090 100644 --- a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_mips.lua +++ b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_mips.lua @@ -1,17 +1,19 @@ ------------------------------------------------------------------------------ --- DynASM MIPS module. +-- DynASM MIPS32/MIPS64 module. -- --- Copyright (C) 2005-2016 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- See dynasm.lua for full copyright notice. ------------------------------------------------------------------------------ +local mips64 = mips64 + -- Module information: local _info = { - arch = "mips", - description = "DynASM MIPS module", + arch = mips64 and "mips64" or "mips", + description = "DynASM MIPS32/MIPS64 module", version = "1.4.0", vernum = 10400, - release = "2015-10-18", + release = "2016-05-24", author = "Mike Pall", license = "MIT", } @@ -27,7 +29,8 @@ local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char local match, gmatch = _s.match, _s.gmatch local concat, sort = table.concat, table.sort local bit = bit or require("bit") -local band, shl, sar, tohex = bit.band, bit.lshift, bit.arshift, bit.tohex +local band, shl, shr, sar = bit.band, bit.lshift, bit.rshift, bit.arshift +local tohex = bit.tohex -- Inherited tables and callbacks. local g_opt, g_arch @@ -38,7 +41,7 @@ local wline, werror, wfatal, wwarn local action_names = { "STOP", "SECTION", "ESC", "REL_EXT", "ALIGN", "REL_LG", "LABEL_LG", - "REL_PC", "LABEL_PC", "IMM", + "REL_PC", "LABEL_PC", "IMM", "IMMS", } -- Maximum number of section buffer positions for dasm_put(). @@ -251,6 +254,10 @@ local map_op = { bnel_3 = "54000000STB", blezl_2 = "58000000SB", bgtzl_2 = "5c000000SB", + daddi_3 = mips64 and "60000000TSI", + daddiu_3 = mips64 and "64000000TSI", + ldl_2 = mips64 and "68000000TO", + ldr_2 = mips64 and "6c000000TO", lb_2 = "80000000TO", lh_2 = "84000000TO", lwl_2 = "88000000TO", @@ -258,23 +265,30 @@ local map_op = { lbu_2 = "90000000TO", lhu_2 = "94000000TO", lwr_2 = "98000000TO", + lwu_2 = mips64 and "9c000000TO", sb_2 = "a0000000TO", sh_2 = "a4000000TO", swl_2 = "a8000000TO", sw_2 = "ac000000TO", + sdl_2 = mips64 and "b0000000TO", + sdr_2 = mips64 and "b1000000TO", swr_2 = "b8000000TO", cache_2 = "bc000000NO", ll_2 = "c0000000TO", lwc1_2 = "c4000000HO", pref_2 = "cc000000NO", ldc1_2 = "d4000000HO", + ld_2 = mips64 and "dc000000TO", sc_2 = "e0000000TO", swc1_2 = "e4000000HO", + scd_2 = mips64 and "f0000000TO", sdc1_2 = "f4000000HO", + sd_2 = mips64 and "fc000000TO", -- Opcode SPECIAL. nop_0 = "00000000", sll_3 = "00000000DTA", + sextw_2 = "00000000DT", movf_2 = "00000001DS", movf_3 = "00000001DSC", movt_2 = "00010001DS", @@ -285,6 +299,7 @@ local map_op = { sllv_3 = "00000004DTS", srlv_3 = "00000006DTS", rotrv_3 = "00000046DTS", + drotrv_3 = mips64 and "00000056DTS", srav_3 = "00000007DTS", jr_1 = "00000008S", jalr_1 = "0000f809S", @@ -300,15 +315,22 @@ local map_op = { mthi_1 = "00000011S", mflo_1 = "00000012D", mtlo_1 = "00000013S", + dsllv_3 = mips64 and "00000014DTS", + dsrlv_3 = mips64 and "00000016DTS", + dsrav_3 = mips64 and "00000017DTS", mult_2 = "00000018ST", multu_2 = "00000019ST", div_2 = "0000001aST", divu_2 = "0000001bST", + dmult_2 = mips64 and "0000001cST", + dmultu_2 = mips64 and "0000001dST", + ddiv_2 = mips64 and "0000001eST", + ddivu_2 = mips64 and "0000001fST", add_3 = "00000020DST", - move_2 = "00000021DS", + move_2 = mips64 and "00000025DS" or "00000021DS", addu_3 = "00000021DST", sub_3 = "00000022DST", - negu_2 = "00000023DT", + negu_2 = mips64 and "0000002fDT" or "00000023DT", subu_3 = "00000023DST", and_3 = "00000024DST", or_3 = "00000025DST", @@ -317,6 +339,10 @@ local map_op = { nor_3 = "00000027DST", slt_3 = "0000002aDST", sltu_3 = "0000002bDST", + dadd_3 = mips64 and "0000002cDST", + daddu_3 = mips64 and "0000002dDST", + dsub_3 = mips64 and "0000002eDST", + dsubu_3 = mips64 and "0000002fDST", tge_2 = "00000030ST", tge_3 = "00000030STZ", tgeu_2 = "00000031ST", @@ -329,6 +355,14 @@ local map_op = { teq_3 = "00000034STZ", tne_2 = "00000036ST", tne_3 = "00000036STZ", + dsll_3 = mips64 and "00000038DTa", + dsrl_3 = mips64 and "0000003aDTa", + drotr_3 = mips64 and "0020003aDTa", + dsra_3 = mips64 and "0000003bDTa", + dsll32_3 = mips64 and "0000003cDTA", + dsrl32_3 = mips64 and "0000003eDTA", + drotr32_3 = mips64 and "0020003eDTA", + dsra32_3 = mips64 and "0000003fDTA", -- Opcode REGIMM. bltz_2 = "04000000SB", @@ -356,13 +390,24 @@ local map_op = { msubu_2 = "70000005ST", clz_2 = "70000020DS=", clo_2 = "70000021DS=", + dclz_2 = mips64 and "70000024DS=", + dclo_2 = mips64 and "70000025DS=", sdbbp_0 = "7000003f", sdbbp_1 = "7000003fY", -- Opcode SPECIAL3. ext_4 = "7c000000TSAM", -- Note: last arg is msbd = size-1 + dextm_4 = mips64 and "7c000001TSAM", -- Args: pos | size-1-32 + dextu_4 = mips64 and "7c000002TSAM", -- Args: pos-32 | size-1 + dext_4 = mips64 and "7c000003TSAM", -- Args: pos | size-1 + zextw_2 = mips64 and "7c00f803TS", ins_4 = "7c000004TSAM", -- Note: last arg is msb = pos+size-1 + dinsm_4 = mips64 and "7c000005TSAM", -- Args: pos | pos+size-33 + dinsu_4 = mips64 and "7c000006TSAM", -- Args: pos-32 | pos+size-33 + dins_4 = mips64 and "7c000007TSAM", -- Args: pos | pos+size-1 wsbh_2 = "7c0000a0DT", + dsbh_2 = mips64 and "7c0000a4DT", + dshd_2 = mips64 and "7c000164DT", seb_2 = "7c000420DT", seh_2 = "7c000620DT", rdhwr_2 = "7c00003bTD", @@ -370,8 +415,12 @@ local map_op = { -- Opcode COP0. mfc0_2 = "40000000TD", mfc0_3 = "40000000TDW", + dmfc0_2 = mips64 and "40200000TD", + dmfc0_3 = mips64 and "40200000TDW", mtc0_2 = "40800000TD", mtc0_3 = "40800000TDW", + dmtc0_2 = mips64 and "40a00000TD", + dmtc0_3 = mips64 and "40a00000TDW", rdpgpr_2 = "41400000DT", di_0 = "41606000", di_1 = "41606000T", @@ -388,9 +437,11 @@ local map_op = { -- Opcode COP1. mfc1_2 = "44000000TG", + dmfc1_2 = mips64 and "44200000TG", cfc1_2 = "44400000TG", mfhc1_2 = "44600000TG", mtc1_2 = "44800000TG", + dmtc1_2 = mips64 and "44a00000TG", ctc1_2 = "44c00000TG", mthc1_2 = "44e00000TG", @@ -633,7 +684,7 @@ local function parse_fpr(expr) werror("bad register name `"..expr.."'") end -local function parse_imm(imm, bits, shift, scale, signed) +local function parse_imm(imm, bits, shift, scale, signed, action) local n = tonumber(imm) if n then local m = sar(n, scale) @@ -651,7 +702,8 @@ local function parse_imm(imm, bits, shift, scale, signed) match(imm, "^([%w_]+):([rf][1-3]?[0-9])$") then werror("expected immediate operand, got register") else - waction("IMM", (signed and 32768 or 0)+scale*1024+bits*32+shift, imm) + waction(action or "IMM", + (signed and 32768 or 0)+shl(scale, 10)+shl(bits, 5)+shift, imm) return 0 end end @@ -763,6 +815,9 @@ map_op[".template__"] = function(params, template, nparams) n = n + 1 elseif p == "A" then op = op + parse_imm(params[n], 5, 6, 0, false); n = n + 1 + elseif p == "a" then + local m = parse_imm(params[n], 6, 6, 0, false, "IMMS"); n = n + 1 + op = op + band(m, 0x7c0) + band(shr(m, 9), 4) elseif p == "M" then op = op + parse_imm(params[n], 5, 11, 0, false); n = n + 1 elseif p == "N" then diff --git a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_ppc.h b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_ppc.h index 3f267fb8240..3a7ee9b0e9a 100644 --- a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_ppc.h +++ b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_ppc.h @@ -1,6 +1,6 @@ /* ** DynASM PPC/PPC64 encoding engine. -** Copyright (C) 2005-2016 Mike Pall. All rights reserved. +** Copyright (C) 2005-2017 Mike Pall. All rights reserved. ** Released under the MIT license. See dynasm.lua for full copyright notice. */ diff --git a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_ppc.lua b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_ppc.lua index e2f704ec18a..f73974dd7f9 100644 --- a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_ppc.lua +++ b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_ppc.lua @@ -1,7 +1,7 @@ ------------------------------------------------------------------------------ -- DynASM PPC/PPC64 module. -- --- Copyright (C) 2005-2016 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- See dynasm.lua for full copyright notice. -- -- Support for various extensions contributed by Caio Souza Oliveira. diff --git a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_proto.h b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_proto.h index 22a654cbfd9..59d9e2b2dd7 100644 --- a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_proto.h +++ b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_proto.h @@ -1,6 +1,6 @@ /* ** DynASM encoding engine prototypes. -** Copyright (C) 2005-2016 Mike Pall. All rights reserved. +** Copyright (C) 2005-2017 Mike Pall. All rights reserved. ** Released under the MIT license. See dynasm.lua for full copyright notice. */ diff --git a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_x64.lua b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_x64.lua index 2133355644f..e8bdeb37d4d 100644 --- a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_x64.lua +++ b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_x64.lua @@ -1,7 +1,7 @@ ------------------------------------------------------------------------------ -- DynASM x64 module. -- --- Copyright (C) 2005-2016 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- See dynasm.lua for full copyright notice. ------------------------------------------------------------------------------ -- This module just sets 64 bit mode for the combined x86/x64 module. diff --git a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_x86.h b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_x86.h index bf5b729633b..bc636357a65 100644 --- a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_x86.h +++ b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_x86.h @@ -1,6 +1,6 @@ /* ** DynASM x86 encoding engine. -** Copyright (C) 2005-2016 Mike Pall. All rights reserved. +** Copyright (C) 2005-2017 Mike Pall. All rights reserved. ** Released under the MIT license. See dynasm.lua for full copyright notice. */ diff --git a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_x86.lua b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_x86.lua index 1f21a2673cc..4c031e2cd67 100644 --- a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_x86.lua +++ b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_x86.lua @@ -1,7 +1,7 @@ ------------------------------------------------------------------------------ -- DynASM x86/x64 module. -- --- Copyright (C) 2005-2016 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- See dynasm.lua for full copyright notice. ------------------------------------------------------------------------------ @@ -1673,6 +1673,10 @@ local map_op = { vpsravd_3 = "rrmoy:660F38V46rM", vpsrlvd_3 = "rrmoy:660F38V45rM", vpsrlvq_3 = "rrmoy:660F38VX45rM", + + -- Intel ADX + adcx_2 = "rmqd:660F38F6rM", + adox_2 = "rmqd:F30F38F6rM", } ------------------------------------------------------------------------------ diff --git a/Build/source/libs/luajit/LuaJIT-src/dynasm/dynasm.lua b/Build/source/libs/luajit/LuaJIT-src/dynasm/dynasm.lua index 1e5899a4bf0..5ec21a7979a 100644 --- a/Build/source/libs/luajit/LuaJIT-src/dynasm/dynasm.lua +++ b/Build/source/libs/luajit/LuaJIT-src/dynasm/dynasm.lua @@ -2,7 +2,7 @@ -- DynASM. A dynamic assembler for code generation engines. -- Originally designed and implemented for LuaJIT. -- --- Copyright (C) 2005-2016 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- See below for full copyright notice. ------------------------------------------------------------------------------ @@ -17,7 +17,7 @@ local _info = { url = "http://luajit.org/dynasm.html", license = "MIT", copyright = [[ -Copyright (C) 2005-2016 Mike Pall. All rights reserved. +Copyright (C) 2005-2017 Mike Pall. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/Build/source/libs/luajit/LuaJIT-src/etc/luajit.1 b/Build/source/libs/luajit/LuaJIT-src/etc/luajit.1 index 11e88c04481..0d263db79fd 100644 --- a/Build/source/libs/luajit/LuaJIT-src/etc/luajit.1 +++ b/Build/source/libs/luajit/LuaJIT-src/etc/luajit.1 @@ -74,7 +74,7 @@ luajit \-jv \-e "for i=1,10 do for j=1,10 do for k=1,100 do end end end" Runs some nested loops and shows the resulting traces. .SH COPYRIGHT .PP -\fBLuaJIT\fR is Copyright \(co 2005-2016 Mike Pall. +\fBLuaJIT\fR is Copyright \(co 2005-2017 Mike Pall. .br \fBLuaJIT\fR is open source software, released under the MIT license. .SH SEE ALSO diff --git a/Build/source/libs/luajit/LuaJIT-src/etc/luajit.pc b/Build/source/libs/luajit/LuaJIT-src/etc/luajit.pc index 0fdd1efd9b0..a78f1746e8f 100644 --- a/Build/source/libs/luajit/LuaJIT-src/etc/luajit.pc +++ b/Build/source/libs/luajit/LuaJIT-src/etc/luajit.pc @@ -2,7 +2,7 @@ majver=2 minver=1 relver=0 -version=${majver}.${minver}.${relver}-beta2 +version=${majver}.${minver}.${relver}-beta3 abiver=5.1 prefix=/usr/local diff --git a/Build/source/libs/luajit/LuaJIT-src/src/Makefile b/Build/source/libs/luajit/LuaJIT-src/src/Makefile index 5139ccd2774..34c5e974a43 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/Makefile +++ b/Build/source/libs/luajit/LuaJIT-src/src/Makefile @@ -7,7 +7,7 @@ # Also works with MinGW and Cygwin on Windows. # Please check msvcbuild.bat for building with MSVC on Windows. # -# Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +# Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h ############################################################################## MAJVER= 2 @@ -110,6 +110,9 @@ XCFLAGS+= -DLUAJIT_ENABLE_LUA52COMPAT #XCFLAGS+= -DLUAJIT_NUMMODE=1 #XCFLAGS+= -DLUAJIT_NUMMODE=2 # +# Enable GC64 mode for x64. +#XCFLAGS+= -DLUAJIT_ENABLE_GC64 +# ############################################################################## ############################################################################## @@ -121,8 +124,8 @@ XCFLAGS+= -DLUAJIT_ENABLE_LUA52COMPAT # # Use the system provided memory allocator (realloc) instead of the # bundled memory allocator. This is slower, but sometimes helpful for -# debugging. This option cannot be enabled on x64, since realloc usually -# doesn't return addresses in the right address range. +# debugging. This option cannot be enabled on x64 without GC64, since +# realloc usually doesn't return addresses in the right address range. # OTOH this option is mandatory for Valgrind's memcheck tool on x64 and # the only way to get useful results from it for all other architectures. #XCFLAGS+= -DLUAJIT_USE_SYSMALLOC @@ -166,10 +169,6 @@ else HOST_SYS= Windows HOST_MSYS= cygwin endif - # Use Clang for OSX host. - ifeq (Darwin,$(HOST_SYS)) - DEFAULT_CC= clang - endif endif ############################################################################## @@ -210,7 +209,7 @@ TARGET_CC= $(STATIC_CC) TARGET_STCC= $(STATIC_CC) TARGET_DYNCC= $(DYNAMIC_CC) TARGET_LD= $(CROSS)$(CC) -TARGET_AR= $(CROSS)ar rcus +TARGET_AR= $(CROSS)ar rcus 2>/dev/null TARGET_STRIP= $(CROSS)strip TARGET_LIBPATH= $(or $(PREFIX),/usr/local)/$(or $(MULTILIB),lib) @@ -243,6 +242,9 @@ ifneq (,$(findstring LJ_TARGET_ARM ,$(TARGET_TESTARCH))) TARGET_LJARCH= arm else ifneq (,$(findstring LJ_TARGET_ARM64 ,$(TARGET_TESTARCH))) + ifneq (,$(findstring __AARCH64EB__ ,$(TARGET_TESTARCH))) + TARGET_ARCH= -D__AARCH64EB__=1 + endif TARGET_LJARCH= arm64 else ifneq (,$(findstring LJ_TARGET_PPC ,$(TARGET_TESTARCH))) @@ -257,7 +259,11 @@ ifneq (,$(findstring LJ_TARGET_MIPS ,$(TARGET_TESTARCH))) ifneq (,$(findstring MIPSEL ,$(TARGET_TESTARCH))) TARGET_ARCH= -D__MIPSEL__=1 endif - TARGET_LJARCH= mips + ifneq (,$(findstring LJ_TARGET_MIPS64 ,$(TARGET_TESTARCH))) + TARGET_LJARCH= mips64 + else + TARGET_LJARCH= mips + endif else $(error Unsupported target architecture) endif @@ -310,7 +316,6 @@ ifeq (Darwin,$(TARGET_SYS)) export MACOSX_DEPLOYMENT_TARGET=10.4 endif TARGET_STRIP+= -x - TARGET_AR+= 2>/dev/null TARGET_XSHLDFLAGS= -dynamiclib -single_module -undefined dynamic_lookup -fPIC TARGET_DYNXLDOPTS= TARGET_XSHLDFLAGS+= -install_name $(TARGET_DYLIBPATH) -compatibility_version $(MAJVER).$(MINVER) -current_version $(MAJVER).$(MINVER).$(RELVER) @@ -321,7 +326,6 @@ ifeq (Darwin,$(TARGET_SYS)) else ifeq (iOS,$(TARGET_SYS)) TARGET_STRIP+= -x - TARGET_AR+= 2>/dev/null TARGET_XSHLDFLAGS= -dynamiclib -single_module -undefined dynamic_lookup -fPIC TARGET_DYNXLDOPTS= TARGET_XSHLDFLAGS+= -install_name $(TARGET_DYLIBPATH) -compatibility_version $(MAJVER).$(MINVER) -current_version $(MAJVER).$(MINVER).$(RELVER) diff --git a/Build/source/libs/luajit/LuaJIT-src/src/Makefile.dep b/Build/source/libs/luajit/LuaJIT-src/src/Makefile.dep index 7fc5ade4e18..44d66f198f6 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/Makefile.dep +++ b/Build/source/libs/luajit/LuaJIT-src/src/Makefile.dep @@ -3,8 +3,8 @@ lib_aux.o: lib_aux.c lua.h luaconf.h lauxlib.h lj_obj.h lj_def.h \ lj_dispatch.h lj_bc.h lj_traceerr.h lj_lib.h lj_alloc.h lib_base.o: lib_base.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h \ - lj_tab.h lj_meta.h lj_state.h lj_ctype.h lj_cconv.h lj_bc.h lj_ff.h \ - lj_ffdef.h lj_dispatch.h lj_jit.h lj_ir.h lj_char.h lj_strscan.h \ + lj_tab.h lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_cconv.h \ + lj_ff.h lj_ffdef.h lj_dispatch.h lj_jit.h lj_ir.h lj_char.h lj_strscan.h \ lj_strfmt.h lj_lib.h lj_libdef.h lbitlib.o: lbitlib.c lua.h luaconf.h lauxlib.h lualib.h lib_bit.o: lib_bit.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \ @@ -164,7 +164,7 @@ lj_opt_sink.o: lj_opt_sink.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ lj_ir.h lj_jit.h lj_iropt.h lj_target.h lj_target_*.h lj_opt_split.o: lj_opt_split.c lj_obj.h lua.h luaconf.h lj_def.h \ lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_ir.h \ - lj_jit.h lj_ircall.h lj_iropt.h lj_vm.h + lj_jit.h lj_ircall.h lj_iropt.h lj_dispatch.h lj_bc.h lj_vm.h lj_parse.o: lj_parse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_buf.h lj_str.h lj_tab.h \ lj_func.h lj_state.h lj_bc.h lj_ctype.h lj_strfmt.h lj_lex.h lj_parse.h \ @@ -216,19 +216,19 @@ ljamalg.o: ljamalg.c lua.h luaconf.h lauxlib.h lj_gc.c lj_obj.h lj_def.h \ lj_func.c lj_udata.c lj_meta.c lj_strscan.h lj_lib.h lj_debug.c \ lj_state.c lj_lex.h lj_alloc.h luajit.h lj_dispatch.c lj_ccallback.h \ lj_profile.h lj_vmevent.c lj_vmevent.h lj_vmmath.c lj_strscan.c \ - lj_strfmt.c lj_api.c lj_profile.c lj_lex.c lualib.h lj_parse.h \ - lj_parse.c lj_bcread.c lj_bcdump.h lj_bcwrite.c lj_load.c lj_ctype.c \ - lj_cdata.c lj_cconv.h lj_cconv.c lj_ccall.c lj_ccall.h lj_ccallback.c \ - lj_target.h lj_target_*.h lj_mcode.h lj_carith.c lj_carith.h lj_clib.c \ - lj_clib.h lj_cparse.c lj_cparse.h lj_lib.c lj_ir.c lj_ircall.h \ - lj_iropt.h lj_opt_mem.c lj_opt_fold.c lj_folddef.h lj_opt_narrow.c \ - lj_opt_dce.c lj_opt_loop.c lj_snap.h lj_opt_split.c lj_opt_sink.c \ - lj_mcode.c lj_snap.c lj_record.c lj_record.h lj_ffrecord.h lj_crecord.c \ - lj_crecord.h lj_ffrecord.c lj_recdef.h lj_asm.c lj_asm.h lj_emit_*.h \ - lj_asm_*.h lj_trace.c lj_gdbjit.h lj_gdbjit.c lj_alloc.c lib_aux.c \ - lib_base.c lj_libdef.h lib_math.c lib_string.c lib_table.c lib_io.c \ - lib_os.c lib_package.c lib_debug.c lib_bit.c lib_jit.c lib_ffi.c \ - lib_init.c + lj_strfmt.c lj_strfmt_num.c lj_api.c lj_profile.c lj_lex.c lualib.h \ + lj_parse.h lj_parse.c lj_bcread.c lj_bcdump.h lj_bcwrite.c lj_load.c \ + lj_ctype.c lj_cdata.c lj_cconv.h lj_cconv.c lj_ccall.c lj_ccall.h \ + lj_ccallback.c lj_target.h lj_target_*.h lj_mcode.h lj_carith.c \ + lj_carith.h lj_clib.c lj_clib.h lj_cparse.c lj_cparse.h lj_lib.c lj_ir.c \ + lj_ircall.h lj_iropt.h lj_opt_mem.c lj_opt_fold.c lj_folddef.h \ + lj_opt_narrow.c lj_opt_dce.c lj_opt_loop.c lj_snap.h lj_opt_split.c \ + lj_opt_sink.c lj_mcode.c lj_snap.c lj_record.c lj_record.h lj_ffrecord.h \ + lj_crecord.c lj_crecord.h lj_ffrecord.c lj_recdef.h lj_asm.c lj_asm.h \ + lj_emit_*.h lj_asm_*.h lj_trace.c lj_gdbjit.h lj_gdbjit.c lj_alloc.c \ + lib_aux.c lib_base.c lj_libdef.h lib_math.c lib_string.c lib_table.c \ + lib_io.c lib_os.c lib_package.c lib_debug.c lib_bit.c lib_jit.c \ + lib_ffi.c lib_init.c luajit.o: luajit.c lua.h luaconf.h lauxlib.h lualib.h luajit.h lj_arch.h host/buildvm.o: host/buildvm.c host/buildvm.h lj_def.h lua.h luaconf.h \ lj_arch.h lj_obj.h lj_def.h lj_arch.h lj_gc.h lj_obj.h lj_bc.h lj_ir.h \ diff --git a/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm.c b/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm.c index 3feae49f6fd..98a7a57a40c 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm.c @@ -1,6 +1,6 @@ /* ** LuaJIT VM builder. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h ** ** This is a tool to build the hand-tuned assembler code required for ** LuaJIT's bytecode interpreter. It supports a variety of output formats @@ -110,7 +110,7 @@ static const char *sym_decorate(BuildCtx *ctx, if (p) { #if LJ_TARGET_X86ORX64 if (!LJ_64 && (ctx->mode == BUILD_coffasm || ctx->mode == BUILD_peobj)) - name[0] = '@'; + name[0] = name[1] == 'R' ? '_' : '@'; /* Just for _RtlUnwind@16. */ else *p = '\0'; #elif LJ_TARGET_PPC && !LJ_TARGET_OSX && !LJ_TARGET_CONSOLE diff --git a/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm.h b/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm.h index 90d21b15f65..b90428dc48f 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm.h @@ -1,6 +1,6 @@ /* ** LuaJIT VM builder. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _BUILDVM_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_asm.c b/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_asm.c index 28419c077a4..ffd14903c64 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_asm.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_asm.c @@ -1,6 +1,6 @@ /* ** LuaJIT VM builder: Assembler source code emitter. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #include "buildvm.h" @@ -93,10 +93,14 @@ static void emit_asm_words(BuildCtx *ctx, uint8_t *p, int n) { int i; for (i = 0; i < n; i += 4) { + uint32_t ins = *(uint32_t *)(p+i); +#if LJ_TARGET_ARM64 && LJ_BE + ins = lj_bswap(ins); /* ARM64 instructions are always little-endian. */ +#endif if ((i & 15) == 0) - fprintf(ctx->fp, "\t.long 0x%08x", *(uint32_t *)(p+i)); + fprintf(ctx->fp, "\t.long 0x%08x", ins); else - fprintf(ctx->fp, ",0x%08x", *(uint32_t *)(p+i)); + fprintf(ctx->fp, ",0x%08x", ins); if ((i & 15) == 12) putc('\n', ctx->fp); } if ((n & 15) != 0) putc('\n', ctx->fp); @@ -214,7 +218,8 @@ static void emit_asm_label(BuildCtx *ctx, const char *name, int size, int isfunc case BUILD_machasm: fprintf(ctx->fp, "\n\t.private_extern %s\n" - "%s:\n", name, name); + "\t.no_dead_strip %s\n" + "%s:\n", name, name, name); break; default: break; diff --git a/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_fold.c b/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_fold.c index eec1af1cbac..d579f4d416a 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_fold.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_fold.c @@ -1,6 +1,6 @@ /* ** LuaJIT VM builder: IR folding hash table generator. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #include "buildvm.h" @@ -9,7 +9,7 @@ /* Context for the folding hash table generator. */ static int lineno; -static int funcidx; +static uint32_t funcidx; static uint32_t foldkeys[BUILD_MAX_FOLD]; static uint32_t nkeys; diff --git a/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_lib.c b/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_lib.c index 1adc3cbd60a..2956fdb6cd0 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_lib.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_lib.c @@ -1,6 +1,6 @@ /* ** LuaJIT VM builder: library definition compiler. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #include "buildvm.h" diff --git a/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_libbc.h b/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_libbc.h index 45f8f8cbdf2..b2600bd5905 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_libbc.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_libbc.h @@ -15,7 +15,12 @@ static const uint8_t libbc_code[] = { 8,2,0,0,88,3,23,128,59,3,2,0,43,4,0,0,64,4,2,0,76,3,2,0,88,3,18,128,16,1,14, 0,41,3,1,0,3,3,1,0,88,3,14,128,3,1,2,0,88,3,12,128,59,3,1,0,22,4,1,1,18,5,2, 0,41,6,1,0,77,4,4,128,23,8,1,7,59,9,7,0,64,9,8,0,79,4,252,127,43,4,0,0,64,4, -2,0,76,3,2,0,75,0,1,0,0,2,0 +2,0,76,3,2,0,75,0,1,0,0,2,0,5,12,0,0,0,35,16,0,12,0,16,1,14,0,16,2,14,0,16, +3,14,0,11,4,0,0,88,5,1,128,18,4,0,0,16,4,12,0,3,1,2,0,88,5,24,128,33,5,1,3, +0,2,3,0,88,6,4,128,2,3,1,0,88,6,2,128,4,4,0,0,88,6,9,128,18,6,1,0,18,7,2,0, +41,8,1,0,77,6,4,128,32,10,5,9,59,11,9,0,64,11,10,4,79,6,252,127,88,6,8,128, +18,6,2,0,18,7,1,0,41,8,255,255,77,6,4,128,32,10,5,9,59,11,9,0,64,11,10,4,79, +6,252,127,76,4,2,0,0 #else 0,1,2,0,0,1,2,24,1,0,0,76,1,2,0,241,135,158,166,3,220,203,178,130,4,0,1,2,0, 0,1,2,24,1,0,0,76,1,2,0,243,244,148,165,20,198,190,199,252,3,0,1,2,0,0,0,3, @@ -28,7 +33,12 @@ static const uint8_t libbc_code[] = { 8,2,0,0,88,3,23,128,59,3,2,0,43,4,0,0,64,4,2,0,76,3,2,0,88,3,18,128,16,1,14, 0,41,3,1,0,3,3,1,0,88,3,14,128,3,1,2,0,88,3,12,128,59,3,1,0,22,4,1,1,18,5,2, 0,41,6,1,0,77,4,4,128,23,8,1,7,59,9,7,0,64,9,8,0,79,4,252,127,43,4,0,0,64,4, -2,0,76,3,2,0,75,0,1,0,0,2,0 +2,0,76,3,2,0,75,0,1,0,0,2,0,5,12,0,0,0,35,16,0,12,0,16,1,14,0,16,2,14,0,16, +3,14,0,11,4,0,0,88,5,1,128,18,4,0,0,16,4,12,0,3,1,2,0,88,5,24,128,33,5,1,3, +0,2,3,0,88,6,4,128,2,3,1,0,88,6,2,128,4,4,0,0,88,6,9,128,18,6,1,0,18,7,2,0, +41,8,1,0,77,6,4,128,32,10,5,9,59,11,9,0,64,11,10,4,79,6,252,127,88,6,8,128, +18,6,2,0,18,7,1,0,41,8,255,255,77,6,4,128,32,10,5,9,59,11,9,0,64,11,10,4,79, +6,252,127,76,4,2,0,0 #endif }; @@ -40,6 +50,7 @@ static const struct { const char *name; int ofs; } libbc_map[] = { {"table_foreach",136}, {"table_getn",207}, {"table_remove",226}, -{NULL,355} +{"table_move",355}, +{NULL,502} }; diff --git a/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_peobj.c b/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_peobj.c index e8c927d8bf9..2eb2bb7bb33 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_peobj.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_peobj.c @@ -1,6 +1,6 @@ /* ** LuaJIT VM builder: PE object emitter. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h ** ** Only used for building on Windows, since we cannot assume the presence ** of a suitable assembler. The host and target byte order must match. @@ -109,6 +109,8 @@ enum { #if LJ_TARGET_X64 PEOBJ_SECT_PDATA, PEOBJ_SECT_XDATA, +#elif LJ_TARGET_X86 + PEOBJ_SECT_SXDATA, #endif PEOBJ_SECT_RDATA_Z, PEOBJ_NSECTIONS @@ -208,6 +210,13 @@ void emit_peobj(BuildCtx *ctx) sofs += (pesect[PEOBJ_SECT_XDATA].nreloc = 1) * PEOBJ_RELOC_SIZE; /* Flags: 40 = read, 30 = align4, 40 = initialized data. */ pesect[PEOBJ_SECT_XDATA].flags = 0x40300040; +#elif LJ_TARGET_X86 + memcpy(pesect[PEOBJ_SECT_SXDATA].name, ".sxdata", sizeof(".sxdata")-1); + pesect[PEOBJ_SECT_SXDATA].ofs = sofs; + sofs += (pesect[PEOBJ_SECT_SXDATA].size = 4); + pesect[PEOBJ_SECT_SXDATA].relocofs = sofs; + /* Flags: 40 = read, 30 = align4, 02 = lnk_info, 40 = initialized data. */ + pesect[PEOBJ_SECT_SXDATA].flags = 0x40300240; #endif memcpy(pesect[PEOBJ_SECT_RDATA_Z].name, ".rdata$Z", sizeof(".rdata$Z")-1); @@ -232,7 +241,7 @@ void emit_peobj(BuildCtx *ctx) nrsym = ctx->nrelocsym; pehdr.nsyms = 1+PEOBJ_NSECTIONS*2 + 1+ctx->nsym + nrsym; #if LJ_TARGET_X64 - pehdr.nsyms += 1; /* Symbol for lj_err_unwind_win64. */ + pehdr.nsyms += 1; /* Symbol for lj_err_unwind_win. */ #endif /* Write PE object header and all sections. */ @@ -312,6 +321,19 @@ void emit_peobj(BuildCtx *ctx) reloc.type = PEOBJ_RELOC_ADDR32NB; owrite(ctx, &reloc, PEOBJ_RELOC_SIZE); } +#elif LJ_TARGET_X86 + /* Write .sxdata section. */ + for (i = 0; i < nrsym; i++) { + if (!strcmp(ctx->relocsym[i], "_lj_err_unwind_win")) { + uint32_t symidx = 1+2+i; + owrite(ctx, &symidx, 4); + break; + } + } + if (i == nrsym) { + fprintf(stderr, "Error: extern lj_err_unwind_win not used\n"); + exit(1); + } #endif /* Write .rdata$Z section. */ @@ -333,8 +355,10 @@ void emit_peobj(BuildCtx *ctx) #if LJ_TARGET_X64 emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_PDATA); emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_XDATA); - emit_peobj_sym(ctx, "lj_err_unwind_win64", 0, + emit_peobj_sym(ctx, "lj_err_unwind_win", 0, PEOBJ_SECT_UNDEF, PEOBJ_TYPE_FUNC, PEOBJ_SCL_EXTERN); +#elif LJ_TARGET_X86 + emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_SXDATA); #endif emit_peobj_sym(ctx, ctx->beginsym, 0, diff --git a/Build/source/libs/luajit/LuaJIT-src/src/host/genlibbc.lua b/Build/source/libs/luajit/LuaJIT-src/src/host/genlibbc.lua index 7a17a3d06b8..6f5a05cce51 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/host/genlibbc.lua +++ b/Build/source/libs/luajit/LuaJIT-src/src/host/genlibbc.lua @@ -2,7 +2,7 @@ -- Lua script to dump the bytecode of the library functions written in Lua. -- The resulting 'buildvm_libbc.h' is used for the build process of LuaJIT. ---------------------------------------------------------------------------- --- Copyright (C) 2005-2016 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- diff --git a/Build/source/libs/luajit/LuaJIT-src/src/host/genminilua.lua b/Build/source/libs/luajit/LuaJIT-src/src/host/genminilua.lua index 0a4690c1d2f..50feff014d0 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/host/genminilua.lua +++ b/Build/source/libs/luajit/LuaJIT-src/src/host/genminilua.lua @@ -2,7 +2,7 @@ -- Lua script to generate a customized, minified version of Lua. -- The resulting 'minilua' is used for the build process of LuaJIT. ---------------------------------------------------------------------------- --- Copyright (C) 2005-2016 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- @@ -157,11 +157,11 @@ local function merge_includes(src) if includes[name] then return "" end includes[name] = true local fp = assert(io.open(LUA_SOURCE..name, "r")) - local src = fp:read("*a") + local inc = fp:read("*a") assert(fp:close()) - src = gsub(src, "#ifndef%s+%w+_h\n#define%s+%w+_h\n", "") - src = gsub(src, "#endif%s*$", "") - return merge_includes(src) + inc = gsub(inc, "#ifndef%s+%w+_h\n#define%s+%w+_h\n", "") + inc = gsub(inc, "#endif%s*$", "") + return merge_includes(inc) end) end @@ -300,6 +300,7 @@ local function strip_unused3(src) src = gsub(src, "if%([^\n]*hookmask[^\n]*&&\n[^\n]*%b{}\n", "") src = gsub(src, "(twoto%b()%()", "%1(size_t)") src = gsub(src, "i<sizenode", "i<(int)sizenode") + src = gsub(src, "cast%(unsigned int,key%-1%)", "cast(unsigned int,key)-1") return gsub(src, "\n\n+", "\n") end diff --git a/Build/source/libs/luajit/LuaJIT-src/src/host/minilua.c b/Build/source/libs/luajit/LuaJIT-src/src/host/minilua.c index aee192a710c..79150286cfc 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/host/minilua.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/host/minilua.c @@ -1606,7 +1606,7 @@ luaC_barriert(L,t,key); return gval(mp); } static const TValue*luaH_getnum(Table*t,int key){ -if(cast(unsigned int,key-1)<cast(unsigned int,t->sizearray)) +if(cast(unsigned int,key)-1<cast(unsigned int,t->sizearray)) return&t->array[key-1]; else{ lua_Number nk=cast_num(key); diff --git a/Build/source/libs/luajit/LuaJIT-src/src/jit/bc.lua b/Build/source/libs/luajit/LuaJIT-src/src/jit/bc.lua index a8cb8496e43..193cf01f939 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/jit/bc.lua +++ b/Build/source/libs/luajit/LuaJIT-src/src/jit/bc.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- LuaJIT bytecode listing module. -- --- Copyright (C) 2005-2016 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- diff --git a/Build/source/libs/luajit/LuaJIT-src/src/jit/bcsave.lua b/Build/source/libs/luajit/LuaJIT-src/src/jit/bcsave.lua index d0968b18760..c17c88e0ff1 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/jit/bcsave.lua +++ b/Build/source/libs/luajit/LuaJIT-src/src/jit/bcsave.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- LuaJIT module to save/list bytecode. -- --- Copyright (C) 2005-2016 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- @@ -63,8 +63,8 @@ local map_type = { } local map_arch = { - x86 = true, x64 = true, arm = true, arm64 = true, ppc = true, - mips = true, mipsel = true, + x86 = true, x64 = true, arm = true, arm64 = true, arm64be = true, + ppc = true, mips = true, mipsel = true, } local map_os = { @@ -125,12 +125,12 @@ extern "C" #ifdef _WIN32 __declspec(dllexport) #endif -const char %s%s[] = { +const unsigned char %s%s[] = { ]], LJBC_PREFIX, ctx.modname)) else fp:write(string.format([[ #define %s%s_SIZE %d -static const char %s%s[] = { +static const unsigned char %s%s[] = { ]], LJBC_PREFIX, ctx.modname, #s, LJBC_PREFIX, ctx.modname)) end local t, n, m = {}, 0, 0 @@ -200,7 +200,7 @@ typedef struct { ]] local symname = LJBC_PREFIX..ctx.modname local is64, isbe = false, false - if ctx.arch == "x64" or ctx.arch == "arm64" then + if ctx.arch == "x64" or ctx.arch == "arm64" or ctx.arch == "arm64be" then is64 = true elseif ctx.arch == "ppc" or ctx.arch == "mips" then isbe = true @@ -237,9 +237,9 @@ typedef struct { hdr.eendian = isbe and 2 or 1 hdr.eversion = 1 hdr.type = f16(1) - hdr.machine = f16(({ x86=3, x64=62, arm=40, arm64=183, ppc=20, mips=8, mipsel=8 })[ctx.arch]) + hdr.machine = f16(({ x86=3, x64=62, arm=40, arm64=183, arm64be=183, ppc=20, mips=8, mipsel=8 })[ctx.arch]) if ctx.arch == "mips" or ctx.arch == "mipsel" then - hdr.flags = 0x50001006 + hdr.flags = f32(0x50001006) end hdr.version = f32(1) hdr.shofs = fofs(ffi.offsetof(o, "sect")) diff --git a/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_arm.lua b/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_arm.lua index 1296d816be0..c2dd776991f 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_arm.lua +++ b/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_arm.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- LuaJIT ARM disassembler module. -- --- Copyright (C) 2005-2016 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- This is a helper module used by the LuaJIT machine code dumper module. @@ -12,7 +12,7 @@ local type = type local sub, byte, format = string.sub, string.byte, string.format -local match, gmatch, gsub = string.match, string.gmatch, string.gsub +local match, gmatch = string.match, string.gmatch local concat = table.concat local bit = require("bit") local band, bor, ror, tohex = bit.band, bit.bor, bit.ror, bit.tohex diff --git a/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_mips.lua b/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_mips.lua index 2bf8b389c36..a12b8e62f3b 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_mips.lua +++ b/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_mips.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- LuaJIT MIPS disassembler module. -- --- Copyright (C) 2005-2016 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT/X license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- This is a helper module used by the LuaJIT machine code dumper module. @@ -11,8 +11,8 @@ ------------------------------------------------------------------------------ local type = type -local sub, byte, format = string.sub, string.byte, string.format -local match, gmatch, gsub = string.match, string.gmatch, string.gsub +local byte, format = string.byte, string.format +local match, gmatch = string.match, string.gmatch local concat = table.concat local bit = require("bit") local band, bor, tohex = bit.band, bit.bor, bit.tohex @@ -34,15 +34,17 @@ local map_special = { "jrS", "jalrD1S", "movzDST", "movnDST", "syscallY", "breakY", false, "sync", "mfhiD", "mthiS", "mfloD", "mtloS", - false, false, false, false, + "dsllvDST", false, "dsrlvDST", "dsravDST", "multST", "multuST", "divST", "divuST", - false, false, false, false, + "dmultST", "dmultuST", "ddivST", "ddivuST", "addDST", "addu|moveDST0", "subDST", "subu|neguDS0T", - "andDST", "orDST", "xorDST", "nor|notDST0", + "andDST", "or|moveDST0", "xorDST", "nor|notDST0", false, false, "sltDST", "sltuDST", - false, false, false, false, + "daddDST", "dadduDST", "dsubDST", "dsubuDST", "tgeSTZ", "tgeuSTZ", "tltSTZ", "tltuSTZ", - "teqSTZ", false, "tneSTZ", + "teqSTZ", false, "tneSTZ", false, + "dsllDTA", false, "dsrlDTA", "dsraDTA", + "dsll32DTA", false, "dsrl32DTA", "dsra32DTA", } local map_special2 = { @@ -60,11 +62,17 @@ local map_bshfl = { [24] = "sehDT", } +local map_dbshfl = { + shift = 6, mask = 31, + [2] = "dsbhDT", + [5] = "dshdDT", +} + local map_special3 = { shift = 0, mask = 63, - [0] = "extTSAK", [4] = "insTSAL", - [32] = map_bshfl, - [59] = "rdhwrTD", + [0] = "extTSAK", [1] = "dextmTSAP", [3] = "dextTSAK", + [4] = "insTSAL", [6] = "dinsuTSEQ", [7] = "dinsTSAL", + [32] = map_bshfl, [36] = map_dbshfl, [59] = "rdhwrTD", } local map_regimm = { @@ -178,8 +186,8 @@ local map_cop1bc = { local map_cop1 = { shift = 21, mask = 31, - [0] = "mfc1TG", false, "cfc1TG", "mfhc1TG", - "mtc1TG", false, "ctc1TG", "mthc1TG", + [0] = "mfc1TG", "dmfc1TG", "cfc1TG", "mfhc1TG", + "mtc1TG", "dmtc1TG", "ctc1TG", "mthc1TG", map_cop1bc, false, false, false, false, false, false, false, map_cop1s, map_cop1d, false, false, @@ -213,16 +221,16 @@ local map_pri = { "andiTSU", "ori|liTS0U", "xoriTSU", "luiTU", map_cop0, map_cop1, false, map_cop1x, "beql|beqzlST0B", "bnel|bnezlST0B", "blezlSB", "bgtzlSB", - false, false, false, false, - map_special2, false, false, map_special3, + "daddiTSI", "daddiuTSI", false, false, + map_special2, "jalxJ", false, map_special3, "lbTSO", "lhTSO", "lwlTSO", "lwTSO", "lbuTSO", "lhuTSO", "lwrTSO", false, "sbTSO", "shTSO", "swlTSO", "swTSO", false, false, "swrTSO", "cacheNSO", "llTSO", "lwc1HSO", "lwc2TSO", "prefNSO", - false, "ldc1HSO", "ldc2TSO", false, + false, "ldc1HSO", "ldc2TSO", "ldTSO", "scTSO", "swc1HSO", "swc2TSO", false, - false, "sdc1HSO", "sdc2TSO", false, + false, "sdc1HSO", "sdc2TSO", "sdTSO", } ------------------------------------------------------------------------------ @@ -306,6 +314,8 @@ local function disass_ins(ctx) x = "f"..band(rshift(op, 21), 31) elseif p == "A" then x = band(rshift(op, 6), 31) + elseif p == "E" then + x = band(rshift(op, 6), 31) + 32 elseif p == "M" then x = band(rshift(op, 11), 31) elseif p == "N" then @@ -315,8 +325,12 @@ local function disass_ins(ctx) if x == 0 then x = nil end elseif p == "K" then x = band(rshift(op, 11), 31) + 1 + elseif p == "P" then + x = band(rshift(op, 11), 31) + 33 elseif p == "L" then x = band(rshift(op, 11), 31) - last + 1 + elseif p == "Q" then + x = band(rshift(op, 11), 31) - last + 33 elseif p == "I" then x = arshift(lshift(op, 16), 16) elseif p == "U" then @@ -330,11 +344,12 @@ local function disass_ins(ctx) elseif p == "B" then x = ctx.addr + ctx.pos + arshift(lshift(op, 16), 16)*4 + 4 ctx.rel = x - x = "0x"..tohex(x) + x = format("0x%08x", x) elseif p == "J" then - x = band(ctx.addr + ctx.pos, 0xf0000000) + band(op, 0x03ffffff)*4 + local a = ctx.addr + ctx.pos + x = a - band(a, 0x0fffffff) + band(op, 0x03ffffff)*4 ctx.rel = x - x = "0x"..tohex(x) + x = format("0x%08x", x) elseif p == "V" then x = band(rshift(op, 8), 7) if x == 0 then x = nil end diff --git a/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_mipsel.lua b/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_mipsel.lua index 3f2f6efc98f..f69b11f01fd 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_mipsel.lua +++ b/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_mipsel.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- LuaJIT MIPSEL disassembler wrapper module. -- --- Copyright (C) 2005-2016 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- This module just exports the little-endian functions from the diff --git a/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_ppc.lua b/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_ppc.lua index 30f51ecdc14..2aeb1b29244 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_ppc.lua +++ b/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_ppc.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- LuaJIT PPC disassembler module. -- --- Copyright (C) 2005-2016 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT/X license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- This is a helper module used by the LuaJIT machine code dumper module. @@ -13,7 +13,7 @@ ------------------------------------------------------------------------------ local type = type -local sub, byte, format = string.sub, string.byte, string.format +local byte, format = string.byte, string.format local match, gmatch, gsub = string.match, string.gmatch, string.gsub local concat = table.concat local bit = require("bit") diff --git a/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_x64.lua b/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_x64.lua index 077b1b127ca..d5714ee1f70 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_x64.lua +++ b/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_x64.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- LuaJIT x64 disassembler wrapper module. -- --- Copyright (C) 2005-2016 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- This module just exports the 64 bit functions from the combined diff --git a/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_x86.lua b/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_x86.lua index f8a21ff30ec..4371233d2b4 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_x86.lua +++ b/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_x86.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- LuaJIT x86/x64 disassembler module. -- --- Copyright (C) 2005-2016 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- This is a helper module used by the LuaJIT machine code dumper module. @@ -244,6 +244,7 @@ nil,"||psrlvVSXrvm","||psravdXrvm","||psllvVSXrvm", [0xde] = "||aesdecXrvm", [0xdf] = "||aesdeclastXrvm", --Fx [0xf0] = "|||crc32TrBmt",[0xf1] = "|||crc32TrVmt", +[0xf7] = "| sarxVrmv| shlxVrmv| shrxVrmv", }, ["3a"] = { -- [66] 0f 3a xx @@ -273,6 +274,8 @@ nil,nil,nil,nil, [0x60] = "||pcmpestrmXrmu",[0x61] = "||pcmpestriXrmu", [0x62] = "||pcmpistrmXrmu",[0x63] = "||pcmpistriXrmu", [0xdf] = "||aeskeygenassistXrmu", +--Fx +[0xf0] = "||| rorxVrmu", }, } @@ -414,8 +417,8 @@ local function putop(ctx, text, operands) (ctx.rexx and "x" or "")..(ctx.rexb and "b" or "").. (ctx.vexl and "l" or "") if ctx.vexv and ctx.vexv ~= 0 then t = t.."v"..ctx.vexv end - if t ~= "" then text = ctx.rex.."."..t.." "..text - elseif ctx.rex == "vex" then text = "v"..text end + if t ~= "" then text = ctx.rex.."."..t.." "..gsub(text, "^ ", "") + elseif ctx.rex == "vex" then text = gsub("v"..text, "^v ", "") end ctx.rexw = false; ctx.rexr = false; ctx.rexx = false; ctx.rexb = false ctx.rex = false; ctx.vexl = false; ctx.vexv = false end @@ -815,7 +818,7 @@ map_act = { m = b%32; b = (b-m)/32 local nb = b%2; b = (b-nb)/2 if nb == 0 then ctx.rexb = true end - local nx = b%2; b = (b-nx)/2 + local nx = b%2 if nx == 0 then ctx.rexx = true end b = byte(ctx.code, pos, pos) if not b then return incomplete(ctx) end diff --git a/Build/source/libs/luajit/LuaJIT-src/src/jit/dump.lua b/Build/source/libs/luajit/LuaJIT-src/src/jit/dump.lua index 9d8330e1838..2bea652bf81 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/jit/dump.lua +++ b/Build/source/libs/luajit/LuaJIT-src/src/jit/dump.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- LuaJIT compiler dump module. -- --- Copyright (C) 2005-2016 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- @@ -63,9 +63,9 @@ local traceinfo, traceir, tracek = jutil.traceinfo, jutil.traceir, jutil.tracek local tracemc, tracesnap = jutil.tracemc, jutil.tracesnap local traceexitstub, ircalladdr = jutil.traceexitstub, jutil.ircalladdr local bit = require("bit") -local band, shl, shr, tohex = bit.band, bit.lshift, bit.rshift, bit.tohex +local band, shr, tohex = bit.band, bit.rshift, bit.tohex local sub, gsub, format = string.sub, string.gsub, string.format -local byte, char, rep = string.byte, string.char, string.rep +local byte, rep = string.byte, string.rep local type, tostring = type, tostring local stdout, stderr = io.stdout, io.stderr @@ -85,7 +85,7 @@ local nexitsym = 0 local function fillsymtab_tr(tr, nexit) local t = {} symtabmt.__index = t - if jit.arch == "mips" or jit.arch == "mipsel" then + if jit.arch:sub(1, 4) == "mips" then t[traceexitstub(tr, 0)] = "exit" return end @@ -213,7 +213,7 @@ local colortype_ansi = { "\027[35m%s\027[m", } -local function colorize_text(s, t) +local function colorize_text(s) return s end @@ -310,15 +310,17 @@ local function fmtfunc(func, pc) end end -local function formatk(tr, idx) +local function formatk(tr, idx, sn) local k, t, slot = tracek(tr, idx) local tn = type(k) local s if tn == "number" then - if k == 2^52+2^51 then + if band(sn or 0, 0x30000) ~= 0 then + s = band(sn, 0x20000) ~= 0 and "contpc" or "ftsz" + elseif k == 2^52+2^51 then s = "bias" else - s = format("%+.14g", k) + s = format(0 < k and k < 0x1p-1026 and "%+a" or "%+.14g", k) end elseif tn == "string" then s = format(#k > 20 and '"%.20s"~' or '"%s"', gsub(k, "%c", ctlsub)) @@ -331,11 +333,13 @@ local function formatk(tr, idx) s = format("userdata:%p", k) else s = format("[%p]", k) - if s == "[0x00000000]" then s = "NULL" end + if s == "[NULL]" then s = "NULL" end end elseif t == 21 then -- int64_t s = sub(tostring(k), 1, -3) if sub(s, 1, 1) ~= "-" then s = "+"..s end + elseif sn == 0x1057fff then -- SNAP(1, SNAP_FRAME | SNAP_NORESTORE, REF_NIL) + return "----" -- Special case for LJ_FR2 slot 1. else s = tostring(k) -- For primitives. end @@ -354,7 +358,7 @@ local function printsnap(tr, snap) n = n + 1 local ref = band(sn, 0xffff) - 0x8000 -- REF_BIAS if ref < 0 then - out:write(formatk(tr, ref)) + out:write(formatk(tr, ref, sn)) elseif band(sn, 0x80000) ~= 0 then -- SNAP_SOFTFPNUM out:write(colorize(format("%04d/%04d", ref, ref+1), 14)) else @@ -552,7 +556,7 @@ local function dump_trace(what, tr, func, pc, otr, oex) if what == "start" then if dumpmode.H then out:write('<pre class="ljdump">\n') end out:write("---- TRACE ", tr, " ", what) - if otr then out:write(" ", otr, "/", oex) end + if otr then out:write(" ", otr, "/", oex == -1 and "stitch" or oex) end out:write(" ", fmtfunc(func, pc), "\n") elseif what == "stop" or what == "abort" then out:write("---- TRACE ", tr, " ", what) @@ -651,7 +655,8 @@ end local function dumpon(opt, outfile) if active then dumpoff() end - local colormode = os.getenv("COLORTERM") and "A" or "T" + local term = os.getenv("TERM") + local colormode = (term and term:match("color") or os.getenv("COLORTERM")) and "A" or "T" if opt then opt = gsub(opt, "[TAH]", function(mode) colormode = mode; return ""; end) end diff --git a/Build/source/libs/luajit/LuaJIT-src/src/jit/p.lua b/Build/source/libs/luajit/LuaJIT-src/src/jit/p.lua index 5323728b1df..7be105863d3 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/jit/p.lua +++ b/Build/source/libs/luajit/LuaJIT-src/src/jit/p.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- LuaJIT profiler. -- --- Copyright (C) 2005-2016 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- @@ -120,7 +120,7 @@ end -- Show top N list. local function prof_top(count1, count2, samples, indent) local t, n = {}, 0 - for k, v in pairs(count1) do + for k in pairs(count1) do n = n + 1 t[n] = k end @@ -156,6 +156,7 @@ local function prof_annotate(count1, samples) ms = math.max(ms, v) if pct >= prof_min then local file, line = k:match("^(.*):(%d+)$") + if not file then file = k; line = 0 end local fl = files[file] if not fl then fl = {}; files[file] = fl; files[#files+1] = file end line = tonumber(line) diff --git a/Build/source/libs/luajit/LuaJIT-src/src/jit/v.lua b/Build/source/libs/luajit/LuaJIT-src/src/jit/v.lua index 60c8b05aa4e..934de9859c7 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/jit/v.lua +++ b/Build/source/libs/luajit/LuaJIT-src/src/jit/v.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- Verbose mode of the LuaJIT compiler. -- --- Copyright (C) 2005-2016 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- @@ -99,7 +99,7 @@ end local function dump_trace(what, tr, func, pc, otr, oex) if what == "start" then startloc = fmtfunc(func, pc) - startex = otr and "("..otr.."/"..oex..") " or "" + startex = otr and "("..otr.."/"..(oex == -1 and "stitch" or oex)..") " or "" else if what == "abort" then local loc = fmtfunc(func, pc) diff --git a/Build/source/libs/luajit/LuaJIT-src/src/jit/zone.lua b/Build/source/libs/luajit/LuaJIT-src/src/jit/zone.lua index f5f9656af63..fa702c4e989 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/jit/zone.lua +++ b/Build/source/libs/luajit/LuaJIT-src/src/jit/zone.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- LuaJIT profiler zones. -- --- Copyright (C) 2005-2016 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lauxlib.h b/Build/source/libs/luajit/LuaJIT-src/src/lauxlib.h index ef0fd54dacc..dcb5d72346f 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lauxlib.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lauxlib.h @@ -15,9 +15,6 @@ #include "lua.h" -#define luaL_getn(L,i) ((int)lua_objlen(L, i)) -#define luaL_setn(L,i,j) ((void)0) /* no op! */ - /* extra error code for `luaL_load' */ #define LUA_ERRFILE (LUA_ERRERR+1) @@ -58,6 +55,10 @@ LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def, const char *const lst[]); +/* pre-defined references */ +#define LUA_NOREF (-2) +#define LUA_REFNIL (-1) + LUALIB_API int (luaL_ref) (lua_State *L, int t); LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); @@ -84,6 +85,11 @@ LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz, const char *name, const char *mode); LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, const char *msg, int level); +LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup); +LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname, + int sizehint); +LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname); +LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname); @@ -111,7 +117,6 @@ typedef struct luaL_Stream { - /* ** =============================================================== ** some useful macros @@ -139,6 +144,11 @@ typedef struct luaL_Stream { #define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) +/* From Lua 5.2. */ +#define luaL_newlibtable(L, l) \ + lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1) +#define luaL_newlib(L, l) (luaL_newlibtable(L, l), luaL_setfuncs(L, l, 0)) + /* ** {====================================================== ** Generic Buffer manipulation @@ -175,21 +185,4 @@ LUALIB_API int (RESERVED_load_aux_JIT) (lua_State *L, int status, int envarg); /* }====================================================== */ - -/* compatibility with ref system */ - -/* pre-defined references */ -#define LUA_NOREF (-2) -#define LUA_REFNIL (-1) - -#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \ - (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0)) - -#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref)) - -#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref)) - - -#define luaL_reg luaL_Reg - #endif diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lib_aux.c b/Build/source/libs/luajit/LuaJIT-src/src/lib_aux.c index 0e61d951a24..c40565c340d 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lib_aux.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lib_aux.c @@ -1,6 +1,6 @@ /* ** Auxiliary library for the Lua/C API. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h ** ** Major parts taken verbatim or adapted from the Lua interpreter. ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h @@ -107,38 +107,36 @@ LUALIB_API const char *luaL_findtable(lua_State *L, int idx, static int libsize(const luaL_Reg *l) { int size = 0; - for (; l->name; l++) size++; + for (; l && l->name; l++) size++; return size; } +LUALIB_API void luaL_pushmodule(lua_State *L, const char *modname, int sizehint) +{ + luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 16); + lua_getfield(L, -1, modname); + if (!lua_istable(L, -1)) { + lua_pop(L, 1); + if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, sizehint) != NULL) + lj_err_callerv(L, LJ_ERR_BADMODN, modname); + lua_pushvalue(L, -1); + lua_setfield(L, -3, modname); /* _LOADED[modname] = new table. */ + } + lua_remove(L, -2); /* Remove _LOADED table. */ +} + LUALIB_API void luaL_openlib(lua_State *L, const char *libname, const luaL_Reg *l, int nup) { lj_lib_checkfpu(L); if (libname) { - int size = libsize(l); - /* check whether lib already exists */ - luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 16); - lua_getfield(L, -1, libname); /* get _LOADED[libname] */ - if (!lua_istable(L, -1)) { /* not found? */ - lua_pop(L, 1); /* remove previous result */ - /* try global variable (and create one if it does not exist) */ - if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != NULL) - lj_err_callerv(L, LJ_ERR_BADMODN, libname); - lua_pushvalue(L, -1); - lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */ - } - lua_remove(L, -2); /* remove _LOADED table */ - lua_insert(L, -(nup+1)); /* move library table to below upvalues */ - } - for (; l->name; l++) { - int i; - for (i = 0; i < nup; i++) /* copy upvalues to the top */ - lua_pushvalue(L, -nup); - lua_pushcclosure(L, l->func, nup); - lua_setfield(L, -(nup+2), l->name); + luaL_pushmodule(L, libname, libsize(l)); + lua_insert(L, -(nup + 1)); /* Move module table below upvalues. */ } - lua_pop(L, nup); /* remove upvalues */ + if (l) + luaL_setfuncs(L, l, nup); + else + lua_pop(L, nup); /* Remove upvalues. */ } LUALIB_API void luaL_register(lua_State *L, const char *libname, @@ -147,6 +145,19 @@ LUALIB_API void luaL_register(lua_State *L, const char *libname, luaL_openlib(L, libname, l, 0); } +LUALIB_API void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup) +{ + luaL_checkstack(L, nup, "too many upvalues"); + for (; l->name; l++) { + int i; + for (i = 0; i < nup; i++) /* Copy upvalues to the top. */ + lua_pushvalue(L, -nup); + lua_pushcclosure(L, l->func, nup); + lua_setfield(L, -(nup + 2), l->name); + } + lua_pop(L, nup); /* Remove upvalues. */ +} + LUALIB_API const char *luaL_gsub(lua_State *L, const char *s, const char *p, const char *r) { @@ -302,7 +313,7 @@ static int panic(lua_State *L) #ifdef LUAJIT_USE_SYSMALLOC -#if LJ_64 && !defined(LUAJIT_USE_VALGRIND) +#if LJ_64 && !LJ_GC64 && !defined(LUAJIT_USE_VALGRIND) #error "Must use builtin allocator for 64 bit target" #endif @@ -334,7 +345,7 @@ LUALIB_API lua_State *luaL_newstate(void) lua_State *L; void *ud = lj_alloc_create(); if (ud == NULL) return NULL; -#if LJ_64 +#if LJ_64 && !LJ_GC64 L = lj_state_newstate(lj_alloc_f, ud); #else L = lua_newstate(lj_alloc_f, ud); @@ -343,7 +354,7 @@ LUALIB_API lua_State *luaL_newstate(void) return L; } -#if LJ_64 +#if LJ_64 && !LJ_GC64 LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud) { UNUSED(f); UNUSED(ud); diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lib_base.c b/Build/source/libs/luajit/LuaJIT-src/src/lib_base.c index 6107bde0066..3a757870aa3 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lib_base.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lib_base.c @@ -1,6 +1,6 @@ /* ** Base and coroutine library. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h ** ** Major portions taken verbatim or adapted from the Lua interpreter. ** Copyright (C) 1994-2011 Lua.org, PUC-Rio. See Copyright Notice in lua.h @@ -23,6 +23,7 @@ #include "lj_tab.h" #include "lj_meta.h" #include "lj_state.h" +#include "lj_frame.h" #if LJ_HASFFI #include "lj_ctype.h" #include "lj_cconv.h" @@ -345,7 +346,7 @@ LJLIB_ASM_(xpcall) LJLIB_REC(.) static int load_aux(lua_State *L, int status, int envarg) { - if (status == 0) { + if (status == LUA_OK) { if (tvistab(L->base+envarg-1)) { GCfunc *fn = funcV(L->top-1); GCtab *t = tabV(L->base+envarg-1); @@ -418,7 +419,7 @@ LJLIB_CF(dofile) GCstr *fname = lj_lib_optstr(L, 1); setnilV(L->top); L->top = L->base+1; - if (luaL_loadfile(L, fname ? strdata(fname) : NULL) != 0) + if (luaL_loadfile(L, fname ? strdata(fname) : NULL) != LUA_OK) lua_error(L); lua_call(L, 0, LUA_MULTRET); return (int)(L->top - L->base) - 1; @@ -536,7 +537,7 @@ LJLIB_CF(coroutine_status) co = threadV(L->base); if (co == L) s = "running"; else if (co->status == LUA_YIELD) s = "suspended"; - else if (co->status != 0) s = "dead"; + else if (co->status != LUA_OK) s = "dead"; else if (co->base > tvref(co->stack)+1+LJ_FR2) s = "normal"; else if (co->top == co->base) s = "dead"; else s = "suspended"; @@ -557,6 +558,12 @@ LJLIB_CF(coroutine_running) #endif } +LJLIB_CF(coroutine_isyieldable) +{ + setboolV(L->top++, cframe_canyield(L->cframe)); + return 1; +} + LJLIB_CF(coroutine_create) { lua_State *L1; @@ -576,7 +583,7 @@ LJLIB_ASM(coroutine_yield) static int ffh_resume(lua_State *L, lua_State *co, int wrap) { if (co->cframe != NULL || co->status > LUA_YIELD || - (co->status == 0 && co->top == co->base)) { + (co->status == LUA_OK && co->top == co->base)) { ErrMsg em = co->cframe ? LJ_ERR_CORUN : LJ_ERR_CODEAD; if (wrap) lj_err_caller(L, em); setboolV(L->base-1-LJ_FR2, 0); diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lib_bit.c b/Build/source/libs/luajit/LuaJIT-src/src/lib_bit.c index 1344d24d9fa..c979a44839c 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lib_bit.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lib_bit.c @@ -1,6 +1,6 @@ /* ** Bit manipulation library. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lib_bit_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lib_debug.c b/Build/source/libs/luajit/LuaJIT-src/src/lib_debug.c index cda7137efc0..f112b5bc870 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lib_debug.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lib_debug.c @@ -1,6 +1,6 @@ /* ** Debug library. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h ** ** Major portions taken verbatim or adapted from the Lua interpreter. ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h @@ -283,13 +283,13 @@ LJLIB_CF(debug_setuservalue) /* ------------------------------------------------------------------------ */ -static const char KEY_HOOK = 'h'; +#define KEY_HOOK ((void *)0x3004) static void hookf(lua_State *L, lua_Debug *ar) { static const char *const hooknames[] = {"call", "return", "line", "count", "tail return"}; - lua_pushlightuserdata(L, (void *)&KEY_HOOK); + lua_pushlightuserdata(L, KEY_HOOK); lua_rawget(L, LUA_REGISTRYINDEX); if (lua_isfunction(L, -1)) { lua_pushstring(L, hooknames[(int)ar->event]); @@ -334,7 +334,7 @@ LJLIB_CF(debug_sethook) count = luaL_optint(L, arg+3, 0); func = hookf; mask = makemask(smask, count); } - lua_pushlightuserdata(L, (void *)&KEY_HOOK); + lua_pushlightuserdata(L, KEY_HOOK); lua_pushvalue(L, arg+1); lua_rawset(L, LUA_REGISTRYINDEX); lua_sethook(L, func, mask, count); @@ -349,7 +349,7 @@ LJLIB_CF(debug_gethook) if (hook != NULL && hook != hookf) { /* external hook? */ lua_pushliteral(L, "external hook"); } else { - lua_pushlightuserdata(L, (void *)&KEY_HOOK); + lua_pushlightuserdata(L, KEY_HOOK); lua_rawget(L, LUA_REGISTRYINDEX); /* get hook */ } lua_pushstring(L, unmakemask(mask, buff)); diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lib_ffi.c b/Build/source/libs/luajit/LuaJIT-src/src/lib_ffi.c index 1feee2157f9..136e98e8963 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lib_ffi.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lib_ffi.c @@ -1,6 +1,6 @@ /* ** FFI library. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lib_ffi_c @@ -829,7 +829,7 @@ static GCtab *ffi_finalizer(lua_State *L) settabV(L, L->top++, t); setgcref(t->metatable, obj2gco(t)); setstrV(L, lj_tab_setstr(L, t, lj_str_newlit(L, "__mode")), - lj_str_newlit(L, "K")); + lj_str_newlit(L, "k")); t->nomm = (uint8_t)(~(1u<<MM_mode)); return t; } diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lib_init.c b/Build/source/libs/luajit/LuaJIT-src/src/lib_init.c index bbb99ec0efd..405471dac0e 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lib_init.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lib_init.c @@ -1,6 +1,6 @@ /* ** Library initialization. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h ** ** Major parts taken verbatim from the Lua interpreter. ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lib_io.c b/Build/source/libs/luajit/LuaJIT-src/src/lib_io.c index 31f0ea97521..9763ed466fe 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lib_io.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lib_io.c @@ -1,6 +1,6 @@ /* ** I/O library. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h ** ** Major portions taken verbatim or adapted from the Lua interpreter. ** Copyright (C) 1994-2011 Lua.org, PUC-Rio. See Copyright Notice in lua.h @@ -203,13 +203,12 @@ static int io_file_read(lua_State *L, FILE *fp, int start) for (n = start; nargs-- && ok; n++) { if (tvisstr(L->base+n)) { const char *p = strVdata(L->base+n); - if (p[0] != '*') - lj_err_arg(L, n+1, LJ_ERR_INVOPT); - if (p[1] == 'n') + if (p[0] == '*') p++; + if (p[0] == 'n') ok = io_file_readnum(L, fp); - else if ((p[1] & ~0x20) == 'L') - ok = io_file_readline(L, fp, (p[1] == 'l')); - else if (p[1] == 'a') + else if ((p[0] & ~0x20) == 'L') + ok = io_file_readline(L, fp, (p[0] == 'l')); + else if (p[0] == 'a') io_file_readall(L, fp); else lj_err_arg(L, n+1, LJ_ERR_INVFMT); diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lib_jit.c b/Build/source/libs/luajit/LuaJIT-src/src/lib_jit.c index 402ca35c7eb..22ca0a1a249 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lib_jit.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lib_jit.c @@ -1,6 +1,6 @@ /* ** JIT library. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lib_jit_c @@ -204,6 +204,7 @@ LJLIB_CF(jit_util_funcinfo) lua_setfield(L, -2, "source"); lj_debug_pushloc(L, pt, pc); lua_setfield(L, -2, "loc"); + setprotoV(L, lj_tab_setstr(L, t, lj_str_newlit(L, "proto")), pt); } else { GCfunc *fn = funcV(L->base); GCtab *t; @@ -668,6 +669,11 @@ static uint32_t jit_cpudetect(lua_State *L) if (fam >= 0x00000f00) /* K8, K10. */ flags |= JIT_F_PREFER_IMUL; } + if (vendor[0] >= 7) { + uint32_t xfeatures[4]; + lj_vm_cpuid(7, xfeatures); + flags |= ((xfeatures[1] >> 8)&1) * JIT_F_BMI2; + } #endif } /* Check for required instruction set support on x86 (unnecessary on x64). */ @@ -710,15 +716,19 @@ static uint32_t jit_cpudetect(lua_State *L) #if LJ_HASJIT /* Compile-time MIPS CPU detection. */ #if LJ_ARCH_VERSION >= 20 - flags |= JIT_F_MIPS32R2; + flags |= JIT_F_MIPSXXR2; #endif /* Runtime MIPS CPU detection. */ #if defined(__GNUC__) - if (!(flags & JIT_F_MIPS32R2)) { + if (!(flags & JIT_F_MIPSXXR2)) { int x; +#ifdef __mips16 + x = 0; /* Runtime detection is difficult. Ensure optimal -march flags. */ +#else /* On MIPS32R1 rotr is treated as srl. rotr r2,r2,1 -> srl r2,r2,1. */ __asm__("li $2, 1\n\t.long 0x00221042\n\tmove %0, $2" : "=r"(x) : : "$2"); - if (x) flags |= JIT_F_MIPS32R2; /* Either 0x80000000 (R2) or 0 (R1). */ +#endif + if (x) flags |= JIT_F_MIPSXXR2; /* Either 0x80000000 (R2) or 0 (R1). */ } #endif #endif diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lib_math.c b/Build/source/libs/luajit/LuaJIT-src/src/lib_math.c index f90dd331c44..ef9dda2da66 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lib_math.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lib_math.c @@ -1,6 +1,6 @@ /* ** Math library. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #include <math.h> @@ -221,10 +221,6 @@ LUALIB_API int luaopen_math(lua_State *L) rs = (RandomState *)lua_newuserdata(L, sizeof(RandomState)); rs->valid = 0; /* Use lazy initialization to save some time on startup. */ LJ_LIB_REG(L, LUA_MATHLIBNAME, math); -#if defined(LUA_COMPAT_MOD) && !LJ_52 - lua_getfield(L, -1, "fmod"); - lua_setfield(L, -2, "mod"); -#endif return 1; } diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lib_os.c b/Build/source/libs/luajit/LuaJIT-src/src/lib_os.c index 941c2a5db0b..9e78d49ac3c 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lib_os.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lib_os.c @@ -1,6 +1,6 @@ /* ** OS library. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h ** ** Major portions taken verbatim or adapted from the Lua interpreter. ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lib_package.c b/Build/source/libs/luajit/LuaJIT-src/src/lib_package.c index ed56156e583..18adf09177f 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lib_package.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lib_package.c @@ -1,6 +1,6 @@ /* ** Package library. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h ** ** Major portions taken verbatim or adapted from the Lua interpreter. ** Copyright (C) 1994-2012 Lua.org, PUC-Rio. See Copyright Notice in lua.h @@ -193,8 +193,7 @@ static void **ll_register(lua_State *L, const char *path) lua_pop(L, 1); plib = (void **)lua_newuserdata(L, sizeof(void *)); *plib = NULL; - luaL_getmetatable(L, "_LOADLIB"); - lua_setmetatable(L, -2); + luaL_setmetatable(L, "_LOADLIB"); lua_pushfstring(L, "LOADLIB: %s", path); lua_pushvalue(L, -2); lua_settable(L, LUA_REGISTRYINDEX); @@ -362,9 +361,9 @@ static int lj_cf_package_loader_c(lua_State *L) return 1; /* library loaded successfully */ } -#define LUA_POF "luaopen_" -#define LUA_OFSEP "_" -#define POF LUA_POF +#define LUA_POF "luaopen_" +#define LUA_OFSEP "_" +#define POF LUA_POF static const char *mkfuncname (lua_State *L, const char *modname) { const char *funcname; @@ -376,7 +375,6 @@ static const char *mkfuncname (lua_State *L, const char *modname) { return funcname; } - int loader_C_luatex (lua_State *L, const char *name, const char *filename) { const char *funcname; funcname = mkfuncname(L, name); @@ -418,7 +416,6 @@ int loader_Call_luatex (lua_State *L, const char *name, const char *filename) { return 1; /* library loaded successfully */ } - static int lj_cf_package_loader_preload(lua_State *L) { const char *name = luaL_checkstring(L, 1); @@ -437,8 +434,7 @@ static int lj_cf_package_loader_preload(lua_State *L) /* ------------------------------------------------------------------------ */ -static const int sentinel_ = 0; -#define sentinel ((void *)&sentinel_) +#define sentinel ((void *)0x4004) static int lj_cf_package_require(lua_State *L) { @@ -528,29 +524,19 @@ static void modinit(lua_State *L, const char *modname) static int lj_cf_package_module(lua_State *L) { const char *modname = luaL_checkstring(L, 1); - int loaded = lua_gettop(L) + 1; /* index of _LOADED table */ - lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); - lua_getfield(L, loaded, modname); /* get _LOADED[modname] */ - if (!lua_istable(L, -1)) { /* not found? */ - lua_pop(L, 1); /* remove previous result */ - /* try global variable (and create one if it does not exist) */ - if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, 1) != NULL) - lj_err_callerv(L, LJ_ERR_BADMODN, modname); - lua_pushvalue(L, -1); - lua_setfield(L, loaded, modname); /* _LOADED[modname] = new table */ - } - /* check whether table already has a _NAME field */ + int lastarg = (int)(L->top - L->base); + luaL_pushmodule(L, modname, 1); lua_getfield(L, -1, "_NAME"); - if (!lua_isnil(L, -1)) { /* is table an initialized module? */ + if (!lua_isnil(L, -1)) { /* Module already initialized? */ lua_pop(L, 1); - } else { /* no; initialize it */ + } else { lua_pop(L, 1); modinit(L, modname); } lua_pushvalue(L, -1); setfenv(L); - dooptions(L, loaded - 1); - return 0; + dooptions(L, lastarg); + return LJ_52; } static int lj_cf_package_seeall(lua_State *L) @@ -621,13 +607,16 @@ LUALIB_API int luaopen_package(lua_State *L) lj_lib_pushcf(L, lj_cf_package_unloadlib, 1); lua_setfield(L, -2, "__gc"); luaL_register(L, LUA_LOADLIBNAME, package_lib); - lua_pushvalue(L, -1); - lua_replace(L, LUA_ENVIRONINDEX); + lua_copy(L, -1, LUA_ENVIRONINDEX); lua_createtable(L, sizeof(package_loaders)/sizeof(package_loaders[0])-1, 0); for (i = 0; package_loaders[i] != NULL; i++) { lj_lib_pushcf(L, package_loaders[i], 1); lua_rawseti(L, -2, i+1); } +#if LJ_52 + lua_pushvalue(L, -1); + lua_setfield(L, -3, "searchers"); +#endif lua_setfield(L, -2, "loaders"); lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); noenv = lua_toboolean(L, -1); diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lib_string.c b/Build/source/libs/luajit/LuaJIT-src/src/lib_string.c index 46b54a5e584..76b0730aca3 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lib_string.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lib_string.c @@ -1,6 +1,6 @@ /* ** String library. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h ** ** Major portions taken verbatim or adapted from the Lua interpreter. ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h @@ -737,10 +737,6 @@ LUALIB_API int luaopen_string(lua_State *L) GCtab *mt; global_State *g; LJ_LIB_REG(L, LUA_STRLIBNAME, string); -#if defined(LUA_COMPAT_GFIND) && !LJ_52 - lua_getfield(L, -1, "gmatch"); - lua_setfield(L, -2, "gfind"); -#endif mt = lj_tab_new(L, 0, 1); /* NOBARRIER: basemt is a GC root. */ g = G(L); diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lib_table.c b/Build/source/libs/luajit/LuaJIT-src/src/lib_table.c index f9a3693dfcb..0450f1f684b 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lib_table.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lib_table.c @@ -1,6 +1,6 @@ /* ** Table library. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h ** ** Major portions taken verbatim or adapted from the Lua interpreter. ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h @@ -129,6 +129,26 @@ LJLIB_LUA(table_remove) /* end */ +LJLIB_LUA(table_move) /* + function(a1, f, e, t, a2) + CHECK_tab(a1) + CHECK_int(f) + CHECK_int(e) + CHECK_int(t) + if a2 == nil then a2 = a1 end + CHECK_tab(a2) + if e >= f then + local d = t - f + if t > e or t <= f or a2 ~= a1 then + for i=f,e do a2[i+d] = a1[i] end + else + for i=e,f,-1 do a2[i+d] = a1[i] end + end + end + return a2 + end +*/ + LJLIB_CF(table_concat) LJLIB_REC(.) { GCtab *t = lj_lib_checktab(L, 1); diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj.supp b/Build/source/libs/luajit/LuaJIT-src/src/lj.supp index acb9e789d08..217f7c8904f 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj.supp +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj.supp @@ -27,15 +27,15 @@ { Optimized string compare Memcheck:Addr4 - fun:lj_str_fastcmp + fun:str_fastcmp } { Optimized string compare Memcheck:Addr1 - fun:lj_str_fastcmp + fun:str_fastcmp } { Optimized string compare Memcheck:Cond - fun:lj_str_fastcmp + fun:str_fastcmp } diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_alloc.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_alloc.c index ddd50cae4f1..95d15d046ad 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_alloc.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_alloc.c @@ -72,13 +72,56 @@ #define IS_DIRECT_BIT (SIZE_T_ONE) + +/* Determine system-specific block allocation method. */ #if LJ_TARGET_WINDOWS #define WIN32_LEAN_AND_MEAN #include <windows.h> +#define LJ_ALLOC_VIRTUALALLOC 1 + #if LJ_64 && !LJ_GC64 +#define LJ_ALLOC_NTAVM 1 +#endif + +#else + +#include <errno.h> +/* If this include fails, then rebuild with: -DLUAJIT_USE_SYSMALLOC */ +#include <sys/mman.h> + +#define LJ_ALLOC_MMAP 1 + +#if LJ_64 + +#define LJ_ALLOC_MMAP_PROBE 1 + +#if LJ_GC64 +#define LJ_ALLOC_MBITS 47 /* 128 TB in LJ_GC64 mode. */ +#elif LJ_TARGET_X64 && LJ_HASJIT +/* Due to limitations in the x64 compiler backend. */ +#define LJ_ALLOC_MBITS 31 /* 2 GB on x64 with !LJ_GC64. */ +#else +#define LJ_ALLOC_MBITS 32 /* 4 GB on other archs with !LJ_GC64. */ +#endif + +#endif + +#if LJ_64 && !LJ_GC64 && defined(MAP_32BIT) +#define LJ_ALLOC_MMAP32 1 +#endif + +#if LJ_TARGET_LINUX +#define LJ_ALLOC_MREMAP 1 +#endif + +#endif + +#if LJ_ALLOC_VIRTUALALLOC + +#if LJ_ALLOC_NTAVM /* Undocumented, but hey, that's what we all love so much about Windows. */ typedef long (*PNTAVM)(HANDLE handle, void **addr, ULONG zbits, size_t *size, ULONG alloctype, ULONG prot); @@ -89,14 +132,15 @@ static PNTAVM ntavm; */ #define NTAVM_ZEROBITS 1 -static void INIT_MMAP(void) +static void init_mmap(void) { ntavm = (PNTAVM)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtAllocateVirtualMemory"); } +#define INIT_MMAP() init_mmap() /* Win64 32 bit MMAP via NtAllocateVirtualMemory. */ -static LJ_AINLINE void *CALL_MMAP(size_t size) +static void *CALL_MMAP(size_t size) { DWORD olderr = GetLastError(); void *ptr = NULL; @@ -107,7 +151,7 @@ static LJ_AINLINE void *CALL_MMAP(size_t size) } /* For direct MMAP, use MEM_TOP_DOWN to minimize interference */ -static LJ_AINLINE void *DIRECT_MMAP(size_t size) +static void *DIRECT_MMAP(size_t size) { DWORD olderr = GetLastError(); void *ptr = NULL; @@ -119,10 +163,8 @@ static LJ_AINLINE void *DIRECT_MMAP(size_t size) #else -#define INIT_MMAP() ((void)0) - /* Win32 MMAP via VirtualAlloc */ -static LJ_AINLINE void *CALL_MMAP(size_t size) +static void *CALL_MMAP(size_t size) { DWORD olderr = GetLastError(); void *ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); @@ -131,7 +173,7 @@ static LJ_AINLINE void *CALL_MMAP(size_t size) } /* For direct MMAP, use MEM_TOP_DOWN to minimize interference */ -static LJ_AINLINE void *DIRECT_MMAP(size_t size) +static void *DIRECT_MMAP(size_t size) { DWORD olderr = GetLastError(); void *ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, @@ -143,7 +185,7 @@ static LJ_AINLINE void *DIRECT_MMAP(size_t size) #endif /* This function supports releasing coalesed segments */ -static LJ_AINLINE int CALL_MUNMAP(void *ptr, size_t size) +static int CALL_MUNMAP(void *ptr, size_t size) { DWORD olderr = GetLastError(); MEMORY_BASIC_INFORMATION minfo; @@ -163,10 +205,7 @@ static LJ_AINLINE int CALL_MUNMAP(void *ptr, size_t size) return 0; } -#else - -#include <errno.h> -#include <sys/mman.h> +#elif LJ_ALLOC_MMAP #define MMAP_PROT (PROT_READ|PROT_WRITE) #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) @@ -174,107 +213,151 @@ static LJ_AINLINE int CALL_MUNMAP(void *ptr, size_t size) #endif #define MMAP_FLAGS (MAP_PRIVATE|MAP_ANONYMOUS) -#if LJ_64 && !LJ_GC64 -/* 64 bit mode with 32 bit pointers needs special support for allocating -** memory in the lower 2GB. -*/ - -#if defined(MAP_32BIT) +#if LJ_ALLOC_MMAP_PROBE -#if defined(__sun__) -#define MMAP_REGION_START ((uintptr_t)0x1000) +#ifdef MAP_TRYFIXED +#define MMAP_FLAGS_PROBE (MMAP_FLAGS|MAP_TRYFIXED) #else -/* Actually this only gives us max. 1GB in current Linux kernels. */ -#define MMAP_REGION_START ((uintptr_t)0) +#define MMAP_FLAGS_PROBE MMAP_FLAGS #endif -static LJ_AINLINE void *CALL_MMAP(size_t size) -{ - int olderr = errno; - void *ptr = mmap((void *)MMAP_REGION_START, size, MMAP_PROT, MAP_32BIT|MMAP_FLAGS, -1, 0); - errno = olderr; - return ptr; -} +#define LJ_ALLOC_MMAP_PROBE_MAX 30 +#define LJ_ALLOC_MMAP_PROBE_LINEAR 5 -#elif LJ_TARGET_OSX || LJ_TARGET_PS4 || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__sun__) || defined(__CYGWIN__) +#define LJ_ALLOC_MMAP_PROBE_LOWER ((uintptr_t)0x4000) -/* OSX and FreeBSD mmap() use a naive first-fit linear search. -** That's perfect for us. Except that -pagezero_size must be set for OSX, -** otherwise the lower 4GB are blocked. And the 32GB RLIMIT_DATA needs -** to be reduced to 250MB on FreeBSD. +/* No point in a giant ifdef mess. Just try to open /dev/urandom. +** It doesn't really matter if this fails, since we get some ASLR bits from +** every unsuitable allocation, too. And we prefer linear allocation, anyway. */ -#if LJ_TARGET_OSX || defined(__DragonFly__) -#define MMAP_REGION_START ((uintptr_t)0x10000) -#elif LJ_TARGET_PS4 -#define MMAP_REGION_START ((uintptr_t)0x4000) -#else -#define MMAP_REGION_START ((uintptr_t)0x10000000) -#endif -#define MMAP_REGION_END ((uintptr_t)0x80000000) +#include <fcntl.h> +#include <unistd.h> -#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) && !LJ_TARGET_PS4 -#include <sys/resource.h> -#endif +static uintptr_t mmap_probe_seed(void) +{ + uintptr_t val; + int fd = open("/dev/urandom", O_RDONLY); + if (fd != -1) { + int ok = ((size_t)read(fd, &val, sizeof(val)) == sizeof(val)); + (void)close(fd); + if (ok) return val; + } + return 1; /* Punt. */ +} -static LJ_AINLINE void *CALL_MMAP(size_t size) +static void *mmap_probe(size_t size) { - int olderr = errno; /* Hint for next allocation. Doesn't need to be thread-safe. */ - static uintptr_t alloc_hint = MMAP_REGION_START; - int retry = 0; -#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) && !LJ_TARGET_PS4 - static int rlimit_modified = 0; - if (LJ_UNLIKELY(rlimit_modified == 0)) { - struct rlimit rlim; - rlim.rlim_cur = rlim.rlim_max = MMAP_REGION_START; - setrlimit(RLIMIT_DATA, &rlim); /* Ignore result. May fail below. */ - rlimit_modified = 1; - } -#endif - for (;;) { - void *p = mmap((void *)alloc_hint, size, MMAP_PROT, MMAP_FLAGS, -1, 0); - if ((uintptr_t)p >= MMAP_REGION_START && - (uintptr_t)p + size < MMAP_REGION_END) { - alloc_hint = (uintptr_t)p + size; + static uintptr_t hint_addr = 0; + static uintptr_t hint_prng = 0; + int olderr = errno; + int retry; + for (retry = 0; retry < LJ_ALLOC_MMAP_PROBE_MAX; retry++) { + void *p = mmap((void *)hint_addr, size, MMAP_PROT, MMAP_FLAGS_PROBE, -1, 0); + uintptr_t addr = (uintptr_t)p; + if ((addr >> LJ_ALLOC_MBITS) == 0 && addr >= LJ_ALLOC_MMAP_PROBE_LOWER) { + /* We got a suitable address. Bump the hint address. */ + hint_addr = addr + size; errno = olderr; return p; } - if (p != CMFAIL) munmap(p, size); -#if defined(__sun__) || defined(__DragonFly__) - alloc_hint += 0x1000000; /* Need near-exhaustive linear scan. */ - if (alloc_hint + size < MMAP_REGION_END) continue; -#endif - if (retry) break; - retry = 1; - alloc_hint = MMAP_REGION_START; + if (p != MFAIL) { + munmap(p, size); + } else if (errno == ENOMEM) { + return MFAIL; + } + if (hint_addr) { + /* First, try linear probing. */ + if (retry < LJ_ALLOC_MMAP_PROBE_LINEAR) { + hint_addr += 0x1000000; + if (((hint_addr + size) >> LJ_ALLOC_MBITS) != 0) + hint_addr = 0; + continue; + } else if (retry == LJ_ALLOC_MMAP_PROBE_LINEAR) { + /* Next, try a no-hint probe to get back an ASLR address. */ + hint_addr = 0; + continue; + } + } + /* Finally, try pseudo-random probing. */ + if (LJ_UNLIKELY(hint_prng == 0)) { + hint_prng = mmap_probe_seed(); + } + /* The unsuitable address we got has some ASLR PRNG bits. */ + hint_addr ^= addr & ~((uintptr_t)(LJ_PAGESIZE-1)); + do { /* The PRNG itself is very weak, but see above. */ + hint_prng = hint_prng * 1103515245 + 12345; + hint_addr ^= hint_prng * (uintptr_t)LJ_PAGESIZE; + hint_addr &= (((uintptr_t)1 << LJ_ALLOC_MBITS)-1); + } while (hint_addr < LJ_ALLOC_MMAP_PROBE_LOWER); } errno = olderr; - return CMFAIL; + return MFAIL; } +#endif + +#if LJ_ALLOC_MMAP32 + +#if defined(__sun__) +#define LJ_ALLOC_MMAP32_START ((uintptr_t)0x1000) #else +#define LJ_ALLOC_MMAP32_START ((uintptr_t)0) +#endif -#error "NYI: need an equivalent of MAP_32BIT for this 64 bit OS" +static void *mmap_map32(size_t size) +{ +#if LJ_ALLOC_MMAP_PROBE + static int fallback = 0; + if (fallback) + return mmap_probe(size); +#endif + { + int olderr = errno; + void *ptr = mmap((void *)LJ_ALLOC_MMAP32_START, size, MMAP_PROT, MAP_32BIT|MMAP_FLAGS, -1, 0); + errno = olderr; + /* This only allows 1GB on Linux. So fallback to probing to get 2GB. */ +#if LJ_ALLOC_MMAP_PROBE + if (ptr == MFAIL) { + fallback = 1; + return mmap_probe(size); + } +#endif + return ptr; + } +} #endif +#if LJ_ALLOC_MMAP32 +#define CALL_MMAP(size) mmap_map32(size) +#elif LJ_ALLOC_MMAP_PROBE +#define CALL_MMAP(size) mmap_probe(size) #else - -/* 32 bit mode and GC64 mode is easy. */ -static LJ_AINLINE void *CALL_MMAP(size_t size) +static void *CALL_MMAP(size_t size) { int olderr = errno; void *ptr = mmap(NULL, size, MMAP_PROT, MMAP_FLAGS, -1, 0); errno = olderr; return ptr; } - #endif -#define INIT_MMAP() ((void)0) -#define DIRECT_MMAP(s) CALL_MMAP(s) +#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) && !LJ_TARGET_PS4 + +#include <sys/resource.h> + +static void init_mmap(void) +{ + struct rlimit rlim; + rlim.rlim_cur = rlim.rlim_max = 0x10000; + setrlimit(RLIMIT_DATA, &rlim); /* Ignore result. May fail later. */ +} +#define INIT_MMAP() init_mmap() + +#endif -static LJ_AINLINE int CALL_MUNMAP(void *ptr, size_t size) +static int CALL_MUNMAP(void *ptr, size_t size) { int olderr = errno; int ret = munmap(ptr, size); @@ -282,10 +365,9 @@ static LJ_AINLINE int CALL_MUNMAP(void *ptr, size_t size) return ret; } -#if LJ_TARGET_LINUX +#if LJ_ALLOC_MREMAP /* Need to define _GNU_SOURCE to get the mremap prototype. */ -static LJ_AINLINE void *CALL_MREMAP_(void *ptr, size_t osz, size_t nsz, - int flags) +static void *CALL_MREMAP_(void *ptr, size_t osz, size_t nsz, int flags) { int olderr = errno; ptr = mremap(ptr, osz, nsz, flags); @@ -305,6 +387,15 @@ static LJ_AINLINE void *CALL_MREMAP_(void *ptr, size_t osz, size_t nsz, #endif + +#ifndef INIT_MMAP +#define INIT_MMAP() ((void)0) +#endif + +#ifndef DIRECT_MMAP +#define DIRECT_MMAP(s) CALL_MMAP(s) +#endif + #ifndef CALL_MREMAP #define CALL_MREMAP(addr, osz, nsz, mv) ((void)osz, MFAIL) #endif diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_api.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_api.c index 0fbb9256343..d17a5754d40 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_api.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_api.c @@ -1,6 +1,6 @@ /* ** Public Lua/C API. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h ** ** Major portions taken verbatim or adapted from the Lua interpreter. ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h @@ -112,6 +112,13 @@ LUA_API void lua_xmove(lua_State *from, lua_State *to, int n) from->top = f; } +LUA_API const lua_Number *lua_version(lua_State *L) +{ + static const lua_Number version = LUA_VERSION_NUM; + UNUSED(L); + return &version; +} + /* -- Stack manipulation -------------------------------------------------- */ LUA_API int lua_gettop(lua_State *L) @@ -152,30 +159,40 @@ LUA_API void lua_insert(lua_State *L, int idx) copyTV(L, p, L->top); } -LUA_API void lua_replace(lua_State *L, int idx) +static void copy_slot(lua_State *L, TValue *f, int idx) { - api_checknelems(L, 1); if (idx == LUA_GLOBALSINDEX) { - api_check(L, tvistab(L->top-1)); + api_check(L, tvistab(f)); /* NOBARRIER: A thread (i.e. L) is never black. */ - setgcref(L->env, obj2gco(tabV(L->top-1))); + setgcref(L->env, obj2gco(tabV(f))); } else if (idx == LUA_ENVIRONINDEX) { GCfunc *fn = curr_func(L); if (fn->c.gct != ~LJ_TFUNC) lj_err_msg(L, LJ_ERR_NOENV); - api_check(L, tvistab(L->top-1)); - setgcref(fn->c.env, obj2gco(tabV(L->top-1))); - lj_gc_barrier(L, fn, L->top-1); + api_check(L, tvistab(f)); + setgcref(fn->c.env, obj2gco(tabV(f))); + lj_gc_barrier(L, fn, f); } else { TValue *o = index2adr(L, idx); api_checkvalidindex(L, o); - copyTV(L, o, L->top-1); + copyTV(L, o, f); if (idx < LUA_GLOBALSINDEX) /* Need a barrier for upvalues. */ - lj_gc_barrier(L, curr_func(L), L->top-1); + lj_gc_barrier(L, curr_func(L), f); } +} + +LUA_API void lua_replace(lua_State *L, int idx) +{ + api_checknelems(L, 1); + copy_slot(L, L->top - 1, idx); L->top--; } +LUA_API void lua_copy(lua_State *L, int fromidx, int toidx) +{ + copy_slot(L, index2adr(L, fromidx), toidx); +} + LUA_API void lua_pushvalue(lua_State *L, int idx) { copyTV(L, L->top, index2adr(L, idx)); @@ -325,6 +342,22 @@ LUA_API lua_Number lua_tonumber(lua_State *L, int idx) return 0; } +LUA_API lua_Number lua_tonumberx(lua_State *L, int idx, int *ok) +{ + cTValue *o = index2adr(L, idx); + TValue tmp; + if (LJ_LIKELY(tvisnumber(o))) { + if (ok) *ok = 1; + return numberVnum(o); + } else if (tvisstr(o) && lj_strscan_num(strV(o), &tmp)) { + if (ok) *ok = 1; + return numV(&tmp); + } else { + if (ok) *ok = 0; + return 0; + } +} + LUALIB_API lua_Number luaL_checknumber(lua_State *L, int idx) { cTValue *o = index2adr(L, idx); @@ -362,7 +395,7 @@ LUA_API lua_Integer lua_tointeger(lua_State *L, int idx) if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp))) return 0; if (tvisint(&tmp)) - return (lua_Integer)intV(&tmp); + return intV(&tmp); n = numV(&tmp); } #if LJ_64 @@ -372,6 +405,35 @@ LUA_API lua_Integer lua_tointeger(lua_State *L, int idx) #endif } +LUA_API lua_Integer lua_tointegerx(lua_State *L, int idx, int *ok) +{ + cTValue *o = index2adr(L, idx); + TValue tmp; + lua_Number n; + if (LJ_LIKELY(tvisint(o))) { + if (ok) *ok = 1; + return intV(o); + } else if (LJ_LIKELY(tvisnum(o))) { + n = numV(o); + } else { + if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp))) { + if (ok) *ok = 0; + return 0; + } + if (tvisint(&tmp)) { + if (ok) *ok = 1; + return intV(&tmp); + } + n = numV(&tmp); + } + if (ok) *ok = 1; +#if LJ_64 + return (lua_Integer)n; +#else + return lj_num2int(n); +#endif +} + LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int idx) { cTValue *o = index2adr(L, idx); @@ -858,7 +920,7 @@ LUA_API void lua_upvaluejoin(lua_State *L, int idx1, int n1, int idx2, int n2) lj_gc_objbarrier(L, fn1, gcref(fn1->l.uvptr[n1])); } -LUALIB_API void *luaL_checkudata(lua_State *L, int idx, const char *tname) +LUALIB_API void *luaL_testudata(lua_State *L, int idx, const char *tname) { cTValue *o = index2adr(L, idx); if (tvisudata(o)) { @@ -867,8 +929,14 @@ LUALIB_API void *luaL_checkudata(lua_State *L, int idx, const char *tname) if (tv && tvistab(tv) && tabV(tv) == tabref(ud->metatable)) return uddata(ud); } - lj_err_argtype(L, idx, tname); - return NULL; /* unreachable */ + return NULL; /* value is not a userdata with a metatable */ +} + +LUALIB_API void *luaL_checkudata(lua_State *L, int idx, const char *tname) +{ + void *p = luaL_testudata(L, idx, tname); + if (!p) lj_err_argtype(L, idx, tname); + return p; } /* -- Object setters ------------------------------------------------------ */ @@ -977,6 +1045,12 @@ LUA_API int lua_setmetatable(lua_State *L, int idx) return 1; } +LUALIB_API void luaL_setmetatable(lua_State *L, const char *tname) +{ + lua_getfield(L, LUA_REGISTRYINDEX, tname); + lua_setmetatable(L, -2); +} + LUA_API int lua_setfenv(lua_State *L, int idx) { cTValue *o = index2adr(L, idx); @@ -1032,7 +1106,7 @@ static TValue *api_call_base(lua_State *L, int nargs) LUA_API void lua_call(lua_State *L, int nargs, int nresults) { - api_check(L, L->status == 0 || L->status == LUA_ERRERR); + api_check(L, L->status == LUA_OK || L->status == LUA_ERRERR); api_checknelems(L, nargs+1); lj_vm_call(L, api_call_base(L, nargs), nresults+1); } @@ -1043,7 +1117,7 @@ LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc) uint8_t oldh = hook_save(g); ptrdiff_t ef; int status; - api_check(L, L->status == 0 || L->status == LUA_ERRERR); + api_check(L, L->status == LUA_OK || L->status == LUA_ERRERR); api_checknelems(L, nargs+1); if (errfunc == 0) { ef = 0; @@ -1075,7 +1149,7 @@ LUA_API int lua_cpcall(lua_State *L, lua_CFunction func, void *ud) global_State *g = G(L); uint8_t oldh = hook_save(g); int status; - api_check(L, L->status == 0 || L->status == LUA_ERRERR); + api_check(L, L->status == LUA_OK || L->status == LUA_ERRERR); status = lj_vm_cpcall(L, func, ud, cpcall); if (status) hook_restore(g, oldh); return status; @@ -1096,6 +1170,11 @@ LUALIB_API int luaL_callmeta(lua_State *L, int idx, const char *field) /* -- Coroutine yield and resume ------------------------------------------ */ +LUA_API int lua_isyieldable(lua_State *L) +{ + return cframe_canyield(L->cframe); +} + LUA_API int lua_yield(lua_State *L, int nresults) { void *cf = L->cframe; @@ -1140,7 +1219,7 @@ LUA_API int lua_resume(lua_State *L, int nargs) { if (L->cframe == NULL && L->status <= LUA_YIELD) return lj_vm_resume(L, - L->status == 0 ? api_call_base(L, nargs) : L->top - nargs, + L->status == LUA_OK ? api_call_base(L, nargs) : L->top - nargs, 0, 0); L->top = L->base; setstrV(L, L->top, lj_err_str(L, LJ_ERR_COSUSP)); diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_arch.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_arch.h index d95848fe5cf..e8ad844ff1d 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_arch.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_arch.h @@ -1,6 +1,6 @@ /* ** Target architecture selection. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_ARCH_H @@ -25,6 +25,10 @@ #define LUAJIT_ARCH_ppc 5 #define LUAJIT_ARCH_MIPS 6 #define LUAJIT_ARCH_mips 6 +#define LUAJIT_ARCH_MIPS32 6 +#define LUAJIT_ARCH_mips32 6 +#define LUAJIT_ARCH_MIPS64 7 +#define LUAJIT_ARCH_mips64 7 /* Target OS. */ #define LUAJIT_OS_OTHER 0 @@ -47,8 +51,10 @@ #define LUAJIT_TARGET LUAJIT_ARCH_ARM64 #elif defined(__ppc__) || defined(__ppc) || defined(__PPC__) || defined(__PPC) || defined(__powerpc__) || defined(__powerpc) || defined(__POWERPC__) || defined(__POWERPC) || defined(_M_PPC) #define LUAJIT_TARGET LUAJIT_ARCH_PPC +#elif defined(__mips64__) || defined(__mips64) || defined(__MIPS64__) || defined(__MIPS64) +#define LUAJIT_TARGET LUAJIT_ARCH_MIPS64 #elif defined(__mips__) || defined(__mips) || defined(__MIPS__) || defined(__MIPS) -#define LUAJIT_TARGET LUAJIT_ARCH_MIPS +#define LUAJIT_TARGET LUAJIT_ARCH_MIPS32 #else #error "No support for this architecture (yet)" #endif @@ -68,7 +74,10 @@ defined(__NetBSD__) || defined(__OpenBSD__) || \ defined(__DragonFly__)) && !defined(__ORBIS__) #define LUAJIT_OS LUAJIT_OS_BSD -#elif (defined(__sun__) && defined(__svr4__)) || defined(__CYGWIN__) +#elif (defined(__sun__) && defined(__svr4__)) || defined(__HAIKU__) +#define LUAJIT_OS LUAJIT_OS_POSIX +#elif defined(__CYGWIN__) +#define LJ_TARGET_CYGWIN 1 #define LUAJIT_OS LUAJIT_OS_POSIX #else #define LUAJIT_OS LUAJIT_OS_OTHER @@ -137,7 +146,7 @@ #define LJ_ARCH_NAME "x86" #define LJ_ARCH_BITS 32 #define LJ_ARCH_ENDIAN LUAJIT_LE -#if LJ_TARGET_WINDOWS || __CYGWIN__ +#if LJ_TARGET_WINDOWS || LJ_TARGET_CYGWIN #define LJ_ABI_WIN 1 #else #define LJ_ABI_WIN 0 @@ -155,7 +164,7 @@ #define LJ_ARCH_NAME "x64" #define LJ_ARCH_BITS 64 #define LJ_ARCH_ENDIAN LUAJIT_LE -#if LJ_TARGET_WINDOWS || __CYGWIN__ +#if LJ_TARGET_WINDOWS || LJ_TARGET_CYGWIN #define LJ_ABI_WIN 1 #else #define LJ_ABI_WIN 0 @@ -206,9 +215,14 @@ #elif LUAJIT_TARGET == LUAJIT_ARCH_ARM64 -#define LJ_ARCH_NAME "arm64" #define LJ_ARCH_BITS 64 +#if defined(__AARCH64EB__) +#define LJ_ARCH_NAME "arm64be" +#define LJ_ARCH_ENDIAN LUAJIT_BE +#else +#define LJ_ARCH_NAME "arm64" #define LJ_ARCH_ENDIAN LUAJIT_LE +#endif #define LJ_TARGET_ARM64 1 #define LJ_TARGET_EHRETREG 0 #define LJ_TARGET_JUMPRANGE 27 /* +-2^27 = +-128MB */ @@ -217,7 +231,6 @@ #define LJ_TARGET_UNIFYROT 2 /* Want only IR_BROR. */ #define LJ_TARGET_GC64 1 #define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL -#define LJ_ARCH_NOJIT 1 /* NYI */ #define LJ_ARCH_VERSION 80 @@ -286,13 +299,21 @@ #define LJ_ARCH_XENON 1 #endif -#elif LUAJIT_TARGET == LUAJIT_ARCH_MIPS +#elif LUAJIT_TARGET == LUAJIT_ARCH_MIPS32 || LUAJIT_TARGET == LUAJIT_ARCH_MIPS64 #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) +#if LUAJIT_TARGET == LUAJIT_ARCH_MIPS32 #define LJ_ARCH_NAME "mipsel" +#else +#define LJ_ARCH_NAME "mips64el" +#endif #define LJ_ARCH_ENDIAN LUAJIT_LE #else +#if LUAJIT_TARGET == LUAJIT_ARCH_MIPS32 #define LJ_ARCH_NAME "mips" +#else +#define LJ_ARCH_NAME "mips64" +#endif #define LJ_ARCH_ENDIAN LUAJIT_BE #endif @@ -304,11 +325,6 @@ #endif #endif -/* Temporarily disable features until the code has been merged. */ -#if !defined(LUAJIT_NO_UNWIND) && __GNU_COMPACT_EH__ -#define LUAJIT_NO_UNWIND 1 -#endif - #if !defined(LJ_ABI_SOFTFP) #ifdef __mips_soft_float #define LJ_ABI_SOFTFP 1 @@ -317,7 +333,17 @@ #endif #endif +#if LUAJIT_TARGET == LUAJIT_ARCH_MIPS32 #define LJ_ARCH_BITS 32 +#define LJ_TARGET_MIPS32 1 +#else +#if LJ_ABI_SOFTFP || !LJ_ARCH_HASFPU +#define LJ_ARCH_NOJIT 1 /* NYI */ +#endif +#define LJ_ARCH_BITS 64 +#define LJ_TARGET_MIPS64 1 +#define LJ_TARGET_GC64 1 +#endif #define LJ_TARGET_MIPS 1 #define LJ_TARGET_EHRETREG 4 #define LJ_TARGET_JUMPRANGE 27 /* 2*2^27 = 256MB-aligned region */ @@ -326,7 +352,7 @@ #define LJ_TARGET_UNIFYROT 2 /* Want only IR_BROR. */ #define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL -#if _MIPS_ARCH_MIPS32R2 +#if _MIPS_ARCH_MIPS32R2 || _MIPS_ARCH_MIPS64R2 #define LJ_ARCH_VERSION 20 #else #define LJ_ARCH_VERSION 10 @@ -350,13 +376,13 @@ #if __GNUC__ < 4 #error "Need at least GCC 4.0 or newer" #endif -#elif LJ_TARGET_ARM || LJ_TARGET_PPC +#elif LJ_TARGET_ARM || LJ_TARGET_PPC #if (__GNUC__ < 4) || ((__GNUC__ == 4) && __GNUC_MINOR__ < 2) #error "Need at least GCC 4.2 or newer" #endif #elif LJ_TARGET_ARM64 #if __clang__ -#if (__clang_major__ < 3) || ((__clang_major__ == 3) && __clang_minor__ < 5) +#if ((__clang_major__ < 3) || ((__clang_major__ == 3) && __clang_minor__ < 5)) && !defined(__NX_TOOLCHAIN_MAJOR__) #error "Need at least Clang 3.5 or newer" #endif #else @@ -388,9 +414,6 @@ #error "Only ARM EABI or iOS 3.0+ ABI is supported" #endif #elif LJ_TARGET_ARM64 -#if defined(__AARCH64EB__) -#error "No support for big-endian ARM64" -#endif #if defined(_ILP32) #error "No support for ILP32 model on ARM64" #endif @@ -407,9 +430,13 @@ #ifdef __NO_FPRS__ #error "No support for PPC/e500 anymore (use LuaJIT 2.0)" #endif -#elif LJ_TARGET_MIPS -#if defined(_LP64) -#error "No support for MIPS64" +#elif LJ_TARGET_MIPS32 +#if !((defined(_MIPS_SIM_ABI32) && _MIPS_SIM == _MIPS_SIM_ABI32) || (defined(_ABIO32) && _MIPS_SIM == _ABIO32)) +#error "Only o32 ABI supported for MIPS32" +#endif +#elif LJ_TARGET_MIPS64 +#if !((defined(_MIPS_SIM_ABI64) && _MIPS_SIM == _MIPS_SIM_ABI64) || (defined(_ABI64) && _MIPS_SIM == _ABI64)) +#error "Only n64 ABI supported for MIPS64" #endif #endif #endif @@ -450,7 +477,7 @@ #endif /* Disable or enable the JIT compiler. */ -#if defined(LUAJIT_DISABLE_JIT) || defined(LJ_ARCH_NOJIT) || defined(LJ_OS_NOJIT) || LJ_FR2 || LJ_GC64 +#if defined(LUAJIT_DISABLE_JIT) || defined(LJ_ARCH_NOJIT) || defined(LJ_OS_NOJIT) #define LJ_HASJIT 0 #else #define LJ_HASJIT 1 @@ -521,6 +548,11 @@ #define LJ_NO_SYSTEM 1 #endif +#if !defined(LUAJIT_NO_UNWIND) && __GNU_COMPACT_EH__ +/* NYI: no support for compact unwind specification, yet. */ +#define LUAJIT_NO_UNWIND 1 +#endif + #if defined(LUAJIT_NO_UNWIND) || defined(__symbian__) || LJ_TARGET_IOS || LJ_TARGET_PS3 || LJ_TARGET_PS4 #define LJ_NO_UNWIND 1 #endif diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_asm.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_asm.c index 93f6bcd6c96..c2cf5a95a5b 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_asm.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_asm.c @@ -1,6 +1,6 @@ /* ** IR assembler (SSA IR -> machine code). -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_asm_c @@ -91,7 +91,7 @@ typedef struct ASMState { MCode *realign; /* Realign loop if not NULL. */ #ifdef RID_NUM_KREF - int32_t krefk[RID_NUM_KREF]; + intptr_t krefk[RID_NUM_KREF]; #endif IRRef1 phireg[RID_MAX]; /* PHI register references. */ uint16_t parentmap[LJ_MAX_JSLOTS]; /* Parent instruction to RegSP map. */ @@ -144,7 +144,7 @@ static LJ_AINLINE void checkmclim(ASMState *as) #define ra_krefreg(ref) ((Reg)(RID_MIN_KREF + (Reg)(ref))) #define ra_krefk(as, ref) (as->krefk[(ref)]) -static LJ_AINLINE void ra_setkref(ASMState *as, Reg r, int32_t k) +static LJ_AINLINE void ra_setkref(ASMState *as, Reg r, intptr_t k) { IRRef ref = (IRRef)(r - RID_MIN_KREF); as->krefk[ref] = k; @@ -171,6 +171,8 @@ IRFLDEF(FLOFS) #include "lj_emit_x86.h" #elif LJ_TARGET_ARM #include "lj_emit_arm.h" +#elif LJ_TARGET_ARM64 +#include "lj_emit_arm64.h" #elif LJ_TARGET_PPC #include "lj_emit_ppc.h" #elif LJ_TARGET_MIPS @@ -322,7 +324,11 @@ static Reg ra_rematk(ASMState *as, IRRef ref) lua_assert(!rset_test(as->freeset, r)); ra_free(as, r); ra_modified(as, r); +#if LJ_64 + emit_loadu64(as, r, ra_krefk(as, ref)); +#else emit_loadi(as, r, ra_krefk(as, ref)); +#endif return r; } ir = IR(ref); @@ -334,7 +340,7 @@ static Reg ra_rematk(ASMState *as, IRRef ref) RA_DBGX((as, "remat $i $r", ir, r)); #if !LJ_SOFTFP if (ir->o == IR_KNUM) { - emit_loadn(as, r, ir_knum(ir)); + emit_loadk64(as, r, ir); } else #endif if (emit_canremat(REF_BASE) && ir->o == IR_BASE) { @@ -346,6 +352,12 @@ static Reg ra_rematk(ASMState *as, IRRef ref) #if LJ_64 } else if (ir->o == IR_KINT64) { emit_loadu64(as, r, ir_kint64(ir)->u64); +#if LJ_GC64 + } else if (ir->o == IR_KGC) { + emit_loadu64(as, r, (uintptr_t)ir_kgc(ir)); + } else if (ir->o == IR_KPTR || ir->o == IR_KKPTR) { + emit_loadu64(as, r, (uintptr_t)ir_kptr(ir)); +#endif #endif } else { lua_assert(ir->o == IR_KINT || ir->o == IR_KGC || @@ -518,7 +530,7 @@ static void ra_evictk(ASMState *as) #ifdef RID_NUM_KREF /* Allocate a register for a constant. */ -static Reg ra_allock(ASMState *as, int32_t k, RegSet allow) +static Reg ra_allock(ASMState *as, intptr_t k, RegSet allow) { /* First try to find a register which already holds the same constant. */ RegSet pick, work = ~as->freeset & RSET_GPR; @@ -527,9 +539,31 @@ static Reg ra_allock(ASMState *as, int32_t k, RegSet allow) IRRef ref; r = rset_pickbot(work); ref = regcost_ref(as->cost[r]); +#if LJ_64 + if (ref < ASMREF_L) { + if (ra_iskref(ref)) { + if (k == ra_krefk(as, ref)) + return r; + } else { + IRIns *ir = IR(ref); + if ((ir->o == IR_KINT64 && k == (int64_t)ir_kint64(ir)->u64) || +#if LJ_GC64 + (ir->o == IR_KINT && k == ir->i) || + (ir->o == IR_KGC && k == (intptr_t)ir_kgc(ir)) || + ((ir->o == IR_KPTR || ir->o == IR_KKPTR) && + k == (intptr_t)ir_kptr(ir)) +#else + (ir->o != IR_KINT64 && k == ir->i) +#endif + ) + return r; + } + } +#else if (ref < ASMREF_L && k == (ra_iskref(ref) ? ra_krefk(as, ref) : IR(ref)->i)) return r; +#endif rset_clear(work, r); } pick = as->freeset & allow; @@ -549,7 +583,7 @@ static Reg ra_allock(ASMState *as, int32_t k, RegSet allow) } /* Allocate a specific register for a constant. */ -static void ra_allockreg(ASMState *as, int32_t k, Reg r) +static void ra_allockreg(ASMState *as, intptr_t k, Reg r) { Reg kr = ra_allock(as, k, RID2RSET(r)); if (kr != r) { @@ -619,10 +653,20 @@ static Reg ra_alloc1(ASMState *as, IRRef ref, RegSet allow) return r; } +/* Add a register rename to the IR. */ +static void ra_addrename(ASMState *as, Reg down, IRRef ref, SnapNo snapno) +{ + IRRef ren; + lj_ir_set(as->J, IRT(IR_RENAME, IRT_NIL), ref, snapno); + ren = tref_ref(lj_ir_emit(as->J)); + as->J->cur.ir[ren].r = (uint8_t)down; + as->J->cur.ir[ren].s = SPS_NONE; +} + /* Rename register allocation and emit move. */ static void ra_rename(ASMState *as, Reg down, Reg up) { - IRRef ren, ref = regcost_ref(as->cost[up] = as->cost[down]); + IRRef ref = regcost_ref(as->cost[up] = as->cost[down]); IRIns *ir = IR(ref); ir->r = (uint8_t)up; as->cost[down] = 0; @@ -635,11 +679,7 @@ static void ra_rename(ASMState *as, Reg down, Reg up) RA_DBGX((as, "rename $f $r $r", regcost_ref(as->cost[up]), down, up)); emit_movrr(as, ir, down, up); /* Backwards codegen needs inverse move. */ if (!ra_hasspill(IR(ref)->s)) { /* Add the rename to the IR. */ - lj_ir_set(as->J, IRT(IR_RENAME, IRT_NIL), ref, as->snapno); - ren = tref_ref(lj_ir_emit(as->J)); - as->ir = as->T->ir; /* The IR may have been reallocated. */ - IR(ren)->r = (uint8_t)down; - IR(ren)->s = SPS_NONE; + ra_addrename(as, down, ref, as->snapno); } } @@ -689,17 +729,21 @@ static void ra_left(ASMState *as, Reg dest, IRRef lref) if (ra_noreg(left)) { if (irref_isk(lref)) { if (ir->o == IR_KNUM) { - cTValue *tv = ir_knum(ir); /* FP remat needs a load except for +0. Still better than eviction. */ - if (tvispzero(tv) || !(as->freeset & RSET_FPR)) { - emit_loadn(as, dest, tv); + if (tvispzero(ir_knum(ir)) || !(as->freeset & RSET_FPR)) { + emit_loadk64(as, dest, ir); return; } #if LJ_64 } else if (ir->o == IR_KINT64) { - emit_loadu64(as, dest, ir_kint64(ir)->u64); + emit_loadk64(as, dest, ir); + return; +#if LJ_GC64 + } else if (ir->o == IR_KGC || ir->o == IR_KPTR || ir->o == IR_KKPTR) { + emit_loadk64(as, dest, ir); return; #endif +#endif } else if (ir->o != IR_KPRI) { lua_assert(ir->o == IR_KINT || ir->o == IR_KGC || ir->o == IR_KPTR || ir->o == IR_KKPTR || ir->o == IR_KNULL); @@ -941,7 +985,7 @@ static void asm_snap_prep(ASMState *as) } else { /* Process any renames above the highwater mark. */ for (; as->snaprename < as->T->nins; as->snaprename++) { - IRIns *ir = IR(as->snaprename); + IRIns *ir = &as->T->ir[as->snaprename]; if (asm_snap_checkrename(as, ir->op1)) ir->op2 = REF_BIAS-1; /* Kill rename. */ } @@ -1055,7 +1099,7 @@ static void asm_bufhdr(ASMState *as, IRIns *ir) } } else { Reg tmp = ra_scratch(as, rset_exclude(RSET_GPR, sb)); - /* Passing ir isn't strictly correct, but it's an IRT_P32, too. */ + /* Passing ir isn't strictly correct, but it's an IRT_PGC, too. */ emit_storeofs(as, ir, tmp, sb, offsetof(SBuf, p)); emit_loadofs(as, ir, tmp, sb, offsetof(SBuf, b)); } @@ -1472,12 +1516,7 @@ static void asm_phi_fixup(ASMState *as) irt_clearmark(ir->t); /* Left PHI gained a spill slot before the loop? */ if (ra_hasspill(ir->s)) { - IRRef ren; - lj_ir_set(as->J, IRT(IR_RENAME, IRT_NIL), lref, as->loopsnapno); - ren = tref_ref(lj_ir_emit(as->J)); - as->ir = as->T->ir; /* The IR may have been reallocated. */ - IR(ren)->r = (uint8_t)r; - IR(ren)->s = SPS_NONE; + ra_addrename(as, r, lref, as->loopsnapno); } } rset_clear(work, r); @@ -1552,6 +1591,8 @@ static void asm_loop(ASMState *as) #include "lj_asm_x86.h" #elif LJ_TARGET_ARM #include "lj_asm_arm.h" +#elif LJ_TARGET_ARM64 +#include "lj_asm_arm64.h" #elif LJ_TARGET_PPC #include "lj_asm_ppc.h" #elif LJ_TARGET_MIPS @@ -1888,7 +1929,7 @@ static BCReg asm_baseslot(ASMState *as, SnapShot *snap, int *gotframe) SnapEntry sn = map[n-1]; if ((sn & SNAP_FRAME)) { *gotframe = 1; - return snap_slot(sn); + return snap_slot(sn) - LJ_FR2; } } return 0; @@ -1908,16 +1949,20 @@ static void asm_tail_link(ASMState *as) if (as->T->link == 0) { /* Setup fixed registers for exit to interpreter. */ - const BCIns *pc = snap_pc(as->T->snapmap[snap->mapofs + snap->nent]); + const BCIns *pc = snap_pc(&as->T->snapmap[snap->mapofs + snap->nent]); int32_t mres; if (bc_op(*pc) == BC_JLOOP) { /* NYI: find a better way to do this. */ BCIns *retpc = &traceref(as->J, bc_d(*pc))->startins; if (bc_isret(bc_op(*retpc))) pc = retpc; } +#if LJ_GC64 + emit_loadu64(as, RID_LPC, u64ptr(pc)); +#else ra_allockreg(as, i32ptr(J2GG(as->J)->dispatch), RID_DISPATCH); ra_allockreg(as, i32ptr(pc), RID_LPC); - mres = (int32_t)(snap->nslots - baseslot); +#endif + mres = (int32_t)(snap->nslots - baseslot - LJ_FR2); switch (bc_op(*pc)) { case BC_CALLM: case BC_CALLMT: mres -= (int32_t)(1 + LJ_FR2 + bc_a(*pc) + bc_c(*pc)); break; @@ -1932,6 +1977,11 @@ static void asm_tail_link(ASMState *as) } emit_addptr(as, RID_BASE, 8*(int32_t)baseslot); + if (as->J->ktrace) { /* Patch ktrace slot with the final GCtrace pointer. */ + setgcref(IR(as->J->ktrace)[LJ_GC64].gcr, obj2gco(as->J->curfinal)); + IR(as->J->ktrace)->o = IR_KGC; + } + /* Sync the interpreter state with the on-trace state. */ asm_stack_restore(as, snap); @@ -1957,17 +2007,22 @@ static void asm_setup_regsp(ASMState *as) ra_setup(as); /* Clear reg/sp for constants. */ - for (ir = IR(T->nk), lastir = IR(REF_BASE); ir < lastir; ir++) + for (ir = IR(T->nk), lastir = IR(REF_BASE); ir < lastir; ir++) { ir->prev = REGSP_INIT; + if (irt_is64(ir->t) && ir->o != IR_KNULL) { +#if LJ_GC64 + ir->i = 0; /* Will become non-zero only for RIP-relative addresses. */ +#else + /* Make life easier for backends by putting address of constant in i. */ + ir->i = (int32_t)(intptr_t)(ir+1); +#endif + ir++; + } + } /* REF_BASE is used for implicit references to the BASE register. */ lastir->prev = REGSP_HINT(RID_BASE); - ir = IR(nins-1); - if (ir->o == IR_RENAME) { - do { ir--; nins--; } while (ir->o == IR_RENAME); - T->nins = nins; /* Remove any renames left over from ASM restart. */ - } as->snaprename = nins; as->snapref = nins; as->snapno = T->nsnap; @@ -2150,7 +2205,10 @@ static void asm_setup_regsp(ASMState *as) #endif #if LJ_TARGET_X86ORX64 /* Non-constant shift counts need to be in RID_ECX on x86/x64. */ - case IR_BSHL: case IR_BSHR: case IR_BSAR: case IR_BROL: case IR_BROR: + case IR_BSHL: case IR_BSHR: case IR_BSAR: + if ((as->flags & JIT_F_BMI2)) /* Except if BMI2 is available. */ + break; + case IR_BROL: case IR_BROR: if (!irref_isk(ir->op2) && !ra_hashint(IR(ir->op2)->r)) { IR(ir->op2)->r = REGSP_HINT(RID_ECX); if (inloop) @@ -2196,14 +2254,25 @@ void lj_asm_trace(jit_State *J, GCtrace *T) ASMState *as = &as_; MCode *origtop; + /* Remove nops/renames left over from ASM restart due to LJ_TRERR_MCODELM. */ + { + IRRef nins = T->nins; + IRIns *ir = &T->ir[nins-1]; + if (ir->o == IR_NOP || ir->o == IR_RENAME) { + do { ir--; nins--; } while (ir->o == IR_NOP || ir->o == IR_RENAME); + T->nins = nins; + } + } + /* Ensure an initialized instruction beyond the last one for HIOP checks. */ - J->cur.nins = lj_ir_nextins(J); - J->cur.ir[J->cur.nins].o = IR_NOP; + /* This also allows one RENAME to be added without reallocating curfinal. */ + as->orignins = lj_ir_nextins(J); + J->cur.ir[as->orignins].o = IR_NOP; /* Setup initial state. Copy some fields to reduce indirections. */ as->J = J; as->T = T; - as->ir = T->ir; + J->curfinal = lj_trace_alloc(J->L, T); /* This copies the IR, too. */ as->flags = J->flags; as->loopref = J->loopref; as->realign = NULL; @@ -2216,12 +2285,41 @@ void lj_asm_trace(jit_State *J, GCtrace *T) as->mclim = as->mcbot + MCLIM_REDZONE; asm_setup_target(as); - do { + /* + ** This is a loop, because the MCode may have to be (re-)assembled + ** multiple times: + ** + ** 1. as->realign is set (and the assembly aborted), if the arch-specific + ** backend wants the MCode to be aligned differently. + ** + ** This is currently only the case on x86/x64, where small loops get + ** an aligned loop body plus a short branch. Not much effort is wasted, + ** because the abort happens very quickly and only once. + ** + ** 2. The IR is immovable, since the MCode embeds pointers to various + ** constants inside the IR. But RENAMEs may need to be added to the IR + ** during assembly, which might grow and reallocate the IR. We check + ** at the end if the IR (in J->cur.ir) has actually grown, resize the + ** copy (in J->curfinal.ir) and try again. + ** + ** 95% of all traces have zero RENAMEs, 3% have one RENAME, 1.5% have + ** 2 RENAMEs and only 0.5% have more than that. That's why we opt to + ** always have one spare slot in the IR (see above), which means we + ** have to redo the assembly for only ~2% of all traces. + ** + ** Very, very rarely, this needs to be done repeatedly, since the + ** location of constants inside the IR (actually, reachability from + ** a global pointer) may affect register allocation and thus the + ** number of RENAMEs. + */ + for (;;) { as->mcp = as->mctop; #ifdef LUA_USE_ASSERT as->mcp_prev = as->mcp; #endif - as->curins = T->nins; + as->ir = J->curfinal->ir; /* Use the copied IR. */ + as->curins = J->cur.nins = as->orignins; + RA_DBG_START(); RA_DBGX((as, "===== STOP =====")); @@ -2249,22 +2347,40 @@ void lj_asm_trace(jit_State *J, GCtrace *T) checkmclim(as); asm_ir(as, ir); } - } while (as->realign); /* Retry in case the MCode needs to be realigned. */ - /* Emit head of trace. */ - RA_DBG_REF(); - checkmclim(as); - if (as->gcsteps > 0) { - as->curins = as->T->snap[0].ref; - asm_snap_prep(as); /* The GC check is a guard. */ - asm_gc_check(as); + if (as->realign && J->curfinal->nins >= T->nins) + continue; /* Retry in case only the MCode needs to be realigned. */ + + /* Emit head of trace. */ + RA_DBG_REF(); + checkmclim(as); + if (as->gcsteps > 0) { + as->curins = as->T->snap[0].ref; + asm_snap_prep(as); /* The GC check is a guard. */ + asm_gc_check(as); + as->curins = as->stopins; + } + ra_evictk(as); + if (as->parent) + asm_head_side(as); + else + asm_head_root(as); + asm_phi_fixup(as); + + if (J->curfinal->nins >= T->nins) { /* IR didn't grow? */ + lua_assert(J->curfinal->nk == T->nk); + memcpy(J->curfinal->ir + as->orignins, T->ir + as->orignins, + (T->nins - as->orignins) * sizeof(IRIns)); /* Copy RENAMEs. */ + T->nins = J->curfinal->nins; + break; /* Done. */ + } + + /* Otherwise try again with a bigger IR. */ + lj_trace_free(J2G(J), J->curfinal); + J->curfinal = NULL; /* In case lj_trace_alloc() OOMs. */ + J->curfinal = lj_trace_alloc(J->L, T); + as->realign = NULL; } - ra_evictk(as); - if (as->parent) - asm_head_side(as); - else - asm_head_root(as); - asm_phi_fixup(as); RA_DBGX((as, "===== START ====")); RA_DBG_FLUSH(); @@ -2277,6 +2393,9 @@ void lj_asm_trace(jit_State *J, GCtrace *T) if (!as->loopref) asm_tail_fixup(as, T->link); /* Note: this may change as->mctop! */ T->szmcode = (MSize)((char *)as->mctop - (char *)as->mcp); +#if LJ_TARGET_MCODE_FIXUP + asm_mcode_fixup(T->mcode, T->szmcode); +#endif lj_mcode_sync(T->mcode, origtop); } diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_asm.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_asm.h index 9f4654ec0a8..2819481b6de 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_asm.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_asm.h @@ -1,6 +1,6 @@ /* ** IR assembler (SSA IR -> machine code). -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_ASM_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_arm.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_arm.h index ff4068a37fa..37bfa40f2fa 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_arm.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_arm.h @@ -1,6 +1,6 @@ /* ** ARM IR assembler (SSA IR -> machine code). -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ /* -- Register allocator extensions --------------------------------------- */ @@ -909,7 +909,6 @@ static void asm_hrefk(ASMState *as, IRIns *ir) static void asm_uref(ASMState *as, IRIns *ir) { - /* NYI: Check that UREFO is still open and not aliasing a slot. */ Reg dest = ra_dest(as, ir, RSET_GPR); if (irref_isk(ir->op1)) { GCfunc *fn = ir_kfunc(IR(ir->op1)); @@ -998,22 +997,26 @@ static ARMIns asm_fxstoreins(IRIns *ir) static void asm_fload(ASMState *as, IRIns *ir) { - Reg dest = ra_dest(as, ir, RSET_GPR); - Reg idx = ra_alloc1(as, ir->op1, RSET_GPR); - ARMIns ai = asm_fxloadins(ir); - int32_t ofs; - if (ir->op2 == IRFL_TAB_ARRAY) { - ofs = asm_fuseabase(as, ir->op1); - if (ofs) { /* Turn the t->array load into an add for colocated arrays. */ - emit_dn(as, ARMI_ADD|ARMI_K12|ofs, dest, idx); - return; + if (ir->op1 == REF_NIL) { + lua_assert(!ra_used(ir)); /* We can end up here if DCE is turned off. */ + } else { + Reg dest = ra_dest(as, ir, RSET_GPR); + Reg idx = ra_alloc1(as, ir->op1, RSET_GPR); + ARMIns ai = asm_fxloadins(ir); + int32_t ofs; + if (ir->op2 == IRFL_TAB_ARRAY) { + ofs = asm_fuseabase(as, ir->op1); + if (ofs) { /* Turn the t->array load into an add for colocated arrays. */ + emit_dn(as, ARMI_ADD|ARMI_K12|ofs, dest, idx); + return; + } } + ofs = field_ofs[ir->op2]; + if ((ai & 0x04000000)) + emit_lso(as, ai, dest, idx, ofs); + else + emit_lsox(as, ai, dest, idx, ofs); } - ofs = field_ofs[ir->op2]; - if ((ai & 0x04000000)) - emit_lso(as, ai, dest, idx, ofs); - else - emit_lsox(as, ai, dest, idx, ofs); } static void asm_fstore(ASMState *as, IRIns *ir) diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_mips.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_mips.h index 9b7f89b096a..affe7d89962 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_mips.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_mips.h @@ -1,6 +1,6 @@ /* ** MIPS IR assembler (SSA IR -> machine code). -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ /* -- Register allocator extensions --------------------------------------- */ @@ -23,7 +23,7 @@ static Reg ra_alloc1z(ASMState *as, IRRef ref, RegSet allow) { Reg r = IR(ref)->r; if (ra_noreg(r)) { - if (!(allow & RSET_FPR) && irref_isk(ref) && IR(ref)->i == 0) + if (!(allow & RSET_FPR) && irref_isk(ref) && get_kval(IR(ref)) == 0) return RID_ZERO; r = ra_allocref(as, ref, allow); } else { @@ -166,9 +166,9 @@ static Reg asm_fuseahuref(ASMState *as, IRRef ref, int32_t *ofsp, RegSet allow) } else if (ir->o == IR_UREFC) { if (irref_isk(ir->op1)) { GCfunc *fn = ir_kfunc(IR(ir->op1)); - int32_t ofs = i32ptr(&gcref(fn->l.uvptr[(ir->op2 >> 8)])->uv.tv); - int32_t jgl = (intptr_t)J2G(as->J); - if ((uint32_t)(ofs-jgl) < 65536) { + intptr_t ofs = (intptr_t)&gcref(fn->l.uvptr[(ir->op2 >> 8)])->uv.tv; + intptr_t jgl = (intptr_t)J2G(as->J); + if ((uintptr_t)(ofs-jgl) < 65536) { *ofsp = ofs-jgl-32768; return RID_JGL; } else { @@ -190,20 +190,21 @@ static void asm_fusexref(ASMState *as, MIPSIns mi, Reg rt, IRRef ref, Reg base; if (ra_noreg(ir->r) && canfuse(as, ir)) { if (ir->o == IR_ADD) { - int32_t ofs2; - if (irref_isk(ir->op2) && (ofs2 = ofs + IR(ir->op2)->i, checki16(ofs2))) { + intptr_t ofs2; + if (irref_isk(ir->op2) && (ofs2 = ofs + get_kval(IR(ir->op2)), + checki16(ofs2))) { ref = ir->op1; - ofs = ofs2; + ofs = (int32_t)ofs2; } } else if (ir->o == IR_STRREF) { - int32_t ofs2 = 65536; + intptr_t ofs2 = 65536; lua_assert(ofs == 0); ofs = (int32_t)sizeof(GCstr); if (irref_isk(ir->op2)) { - ofs2 = ofs + IR(ir->op2)->i; + ofs2 = ofs + get_kval(IR(ir->op2)); ref = ir->op1; } else if (irref_isk(ir->op1)) { - ofs2 = ofs + IR(ir->op1)->i; + ofs2 = ofs + get_kval(IR(ir->op1)); ref = ir->op2; } if (!checki16(ofs2)) { @@ -211,7 +212,7 @@ static void asm_fusexref(ASMState *as, MIPSIns mi, Reg rt, IRRef ref, Reg right, left = ra_alloc2(as, ir, allow); right = (left >> 8); left &= 255; emit_hsi(as, mi, rt, RID_TMP, ofs); - emit_dst(as, MIPSI_ADDU, RID_TMP, left, right); + emit_dst(as, MIPSI_AADDU, RID_TMP, left, right); return; } ofs = ofs2; @@ -227,7 +228,7 @@ static void asm_fusexref(ASMState *as, MIPSIns mi, Reg rt, IRRef ref, static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args) { uint32_t n, nargs = CCI_XNARGS(ci); - int32_t ofs = 16; + int32_t ofs = LJ_32 ? 16 : 0; #if LJ_SOFTFP Reg gpr = REGARG_FIRSTGPR; #else @@ -249,15 +250,15 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args) !(ci->flags & CCI_VARARG)) { lua_assert(rset_test(as->freeset, fpr)); /* Already evicted. */ ra_leftov(as, fpr, ref); - fpr += 2; - gpr += irt_isnum(ir->t) ? 2 : 1; + fpr += LJ_32 ? 2 : 1; + gpr += (LJ_32 && irt_isnum(ir->t)) ? 2 : 1; } else #endif { -#if !LJ_SOFTFP +#if LJ_32 && !LJ_SOFTFP fpr = REGARG_LASTFPR+1; #endif - if (irt_isnum(ir->t)) gpr = (gpr+1) & ~1; + if (LJ_32 && irt_isnum(ir->t)) gpr = (gpr+1) & ~1; if (gpr <= REGARG_LASTGPR) { lua_assert(rset_test(as->freeset, gpr)); /* Already evicted. */ #if !LJ_SOFTFP @@ -269,35 +270,55 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args) r = ra_alloc1(as, ref, RSET_FPR); as->freeset |= (of & RSET_RANGE(REGARG_FIRSTGPR, REGARG_LASTGPR+1)); if (irt_isnum(ir->t)) { +#if LJ_32 emit_tg(as, MIPSI_MFC1, gpr+(LJ_BE?0:1), r+1); emit_tg(as, MIPSI_MFC1, gpr+(LJ_BE?1:0), r); lua_assert(rset_test(as->freeset, gpr+1)); /* Already evicted. */ gpr += 2; +#else + emit_tg(as, MIPSI_DMFC1, gpr, r); + gpr++; fpr++; +#endif } else if (irt_isfloat(ir->t)) { emit_tg(as, MIPSI_MFC1, gpr, r); gpr++; +#if LJ_64 + fpr++; +#endif } } else #endif { ra_leftov(as, gpr, ref); gpr++; +#if LJ_64 + fpr++; +#endif } } else { Reg r = ra_alloc1z(as, ref, !LJ_SOFTFP && irt_isfp(ir->t) ? RSET_FPR : RSET_GPR); +#if LJ_32 if (irt_isnum(ir->t)) ofs = (ofs + 4) & ~4; emit_spstore(as, ir, r, ofs); ofs += irt_isnum(ir->t) ? 8 : 4; +#else + emit_spstore(as, ir, r, ofs + ((LJ_BE && (LJ_SOFTFP || r < RID_MAX_GPR) && !irt_is64(ir->t)) ? 4 : 0)); + ofs += 8; +#endif } } } else { #if !LJ_SOFTFP fpr = REGARG_LASTFPR+1; #endif - if (gpr <= REGARG_LASTGPR) + if (gpr <= REGARG_LASTGPR) { gpr++; - else - ofs += 4; +#if LJ_64 + fpr++; +#endif + } else { + ofs += LJ_32 ? 4 : 8; + } } checkmclim(as); } @@ -307,15 +328,19 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args) static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci) { RegSet drop = RSET_SCRATCH; +#if LJ_32 int hiop = ((ir+1)->o == IR_HIOP && !irt_isnil((ir+1)->t)); +#endif #if !LJ_SOFTFP if ((ci->flags & CCI_NOFPRCLOBBER)) drop &= ~RSET_FPR; #endif if (ra_hasreg(ir->r)) rset_clear(drop, ir->r); /* Dest reg handled below. */ +#if LJ_32 if (hiop && ra_hasreg((ir+1)->r)) rset_clear(drop, (ir+1)->r); /* Dest reg handled below. */ +#endif ra_evictset(as, drop); /* Evictions must be performed first. */ if (ra_used(ir)) { lua_assert(!irt_ispri(ir->t)); @@ -326,18 +351,28 @@ static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci) if (ra_hasreg(dest)) { ra_free(as, dest); ra_modified(as, dest); +#if LJ_32 emit_tg(as, MIPSI_MTC1, RID_RETHI, dest+1); emit_tg(as, MIPSI_MTC1, RID_RETLO, dest); +#else + emit_tg(as, MIPSI_DMTC1, RID_RET, dest); +#endif } if (ofs) { +#if LJ_32 emit_tsi(as, MIPSI_SW, RID_RETLO, RID_SP, ofs+(LJ_BE?4:0)); emit_tsi(as, MIPSI_SW, RID_RETHI, RID_SP, ofs+(LJ_BE?0:4)); +#else + emit_tsi(as, MIPSI_SD, RID_RET, RID_SP, ofs); +#endif } } else { ra_destreg(as, ir, RID_FPRET); } +#if LJ_32 } else if (hiop) { ra_destpair(as, ir); +#endif } else { ra_destreg(as, ir, RID_RET); } @@ -356,7 +391,7 @@ static void asm_callx(ASMState *as, IRIns *ir) func = ir->op2; irf = IR(func); if (irf->o == IR_CARG) { func = irf->op1; irf = IR(func); } if (irref_isk(func)) { /* Call to constant address. */ - ci.func = (ASMFunction)(void *)(irf->i); + ci.func = (ASMFunction)(void *)get_kval(irf); } else { /* Need specific register for indirect calls. */ Reg r = ra_alloc1(as, func, RID2RSET(RID_CFUNCADDR)); MCode *p = as->mcp; @@ -399,8 +434,8 @@ static void asm_retf(ASMState *as, IRIns *ir) emit_setgl(as, base, jit_base); emit_addptr(as, base, -8*delta); asm_guard(as, MIPSI_BNE, RID_TMP, - ra_allock(as, i32ptr(pc), rset_exclude(RSET_GPR, base))); - emit_tsi(as, MIPSI_LW, RID_TMP, base, -8); + ra_allock(as, igcptr(pc), rset_exclude(RSET_GPR, base))); + emit_tsi(as, MIPSI_AL, RID_TMP, base, -8); } /* -- Type conversions ---------------------------------------------------- */ @@ -435,10 +470,15 @@ static void asm_conv(ASMState *as, IRIns *ir) #if !LJ_SOFTFP int stfp = (st == IRT_NUM || st == IRT_FLOAT); #endif +#if LJ_64 + int st64 = (st == IRT_I64 || st == IRT_U64 || st == IRT_P64); +#endif IRRef lref = ir->op1; +#if LJ_32 lua_assert(!(irt_isint64(ir->t) || (st == IRT_I64 || st == IRT_U64))); /* Handled by SPLIT. */ -#if LJ_SOFTFP +#endif +#if LJ_32 && LJ_SOFTFP /* FP conversions are handled by SPLIT. */ lua_assert(!irt_isfp(ir->t) && !(st == IRT_NUM || st == IRT_FLOAT)); /* Can't check for same types: SPLIT uses CONV int.int + BXOR for sfp NEG. */ @@ -453,26 +493,50 @@ static void asm_conv(ASMState *as, IRIns *ir) /* y = (x ^ 0x8000000) + 2147483648.0 */ Reg left = ra_alloc1(as, lref, RSET_GPR); Reg tmp = ra_scratch(as, rset_exclude(RSET_FPR, dest)); - emit_fgh(as, irt_isfloat(ir->t) ? MIPSI_ADD_S : MIPSI_ADD_D, - dest, dest, tmp); - emit_fg(as, irt_isfloat(ir->t) ? MIPSI_CVT_S_W : MIPSI_CVT_D_W, - dest, dest); if (irt_isfloat(ir->t)) - emit_lsptr(as, MIPSI_LWC1, (tmp & 31), - (void *)lj_ir_k64_find(as->J, U64x(4f000000,4f000000)), - RSET_GPR); - else - emit_lsptr(as, MIPSI_LDC1, (tmp & 31), - (void *)lj_ir_k64_find(as->J, U64x(41e00000,00000000)), - RSET_GPR); + emit_fg(as, MIPSI_CVT_S_D, dest, dest); + /* Must perform arithmetic with doubles to keep the precision. */ + emit_fgh(as, MIPSI_ADD_D, dest, dest, tmp); + emit_fg(as, MIPSI_CVT_D_W, dest, dest); + emit_lsptr(as, MIPSI_LDC1, (tmp & 31), + (void *)&as->J->k64[LJ_K64_2P31], RSET_GPR); emit_tg(as, MIPSI_MTC1, RID_TMP, dest); emit_dst(as, MIPSI_XOR, RID_TMP, RID_TMP, left); emit_ti(as, MIPSI_LUI, RID_TMP, 0x8000); +#if LJ_64 + } else if(st == IRT_U64) { /* U64 to FP conversion. */ + /* if (x >= 1u<<63) y = (double)(int64_t)(x&(1u<<63)-1) + pow(2.0, 63) */ + Reg left = ra_alloc1(as, lref, RSET_GPR); + Reg tmp = ra_scratch(as, rset_exclude(RSET_FPR, dest)); + MCLabel l_end = emit_label(as); + if (irt_isfloat(ir->t)) { + emit_fgh(as, MIPSI_ADD_S, dest, dest, tmp); + emit_lsptr(as, MIPSI_LWC1, (tmp & 31), (void *)&as->J->k32[LJ_K32_2P63], + rset_exclude(RSET_GPR, left)); + emit_fg(as, MIPSI_CVT_S_L, dest, dest); + } else { + emit_fgh(as, MIPSI_ADD_D, dest, dest, tmp); + emit_lsptr(as, MIPSI_LDC1, (tmp & 31), (void *)&as->J->k64[LJ_K64_2P63], + rset_exclude(RSET_GPR, left)); + emit_fg(as, MIPSI_CVT_D_L, dest, dest); + } + emit_branch(as, MIPSI_BGEZ, left, RID_ZERO, l_end); + emit_tg(as, MIPSI_DMTC1, RID_TMP, dest); + emit_tsml(as, MIPSI_DEXTM, RID_TMP, left, 30, 0); +#endif } else { /* Integer to FP conversion. */ Reg left = ra_alloc1(as, lref, RSET_GPR); +#if LJ_32 emit_fg(as, irt_isfloat(ir->t) ? MIPSI_CVT_S_W : MIPSI_CVT_D_W, dest, dest); emit_tg(as, MIPSI_MTC1, left, dest); +#else + MIPSIns mi = irt_isfloat(ir->t) ? + (st64 ? MIPSI_CVT_S_L : MIPSI_CVT_S_W) : + (st64 ? MIPSI_CVT_D_L : MIPSI_CVT_D_W); + emit_fg(as, mi, dest, dest); + emit_tg(as, st64 ? MIPSI_DMTC1 : MIPSI_MTC1, left, dest); +#endif } } else if (stfp) { /* FP to integer conversion. */ if (irt_isguard(ir->t)) { @@ -483,7 +547,7 @@ static void asm_conv(ASMState *as, IRIns *ir) Reg dest = ra_dest(as, ir, RSET_GPR); Reg left = ra_alloc1(as, lref, RSET_FPR); Reg tmp = ra_scratch(as, rset_exclude(RSET_FPR, left)); - if (irt_isu32(ir->t)) { + if (irt_isu32(ir->t)) { /* FP to U32 conversion. */ /* y = (int)floor(x - 2147483648.0) ^ 0x80000000 */ emit_dst(as, MIPSI_XOR, dest, dest, RID_TMP); emit_ti(as, MIPSI_LUI, RID_TMP, 0x8000); @@ -494,16 +558,54 @@ static void asm_conv(ASMState *as, IRIns *ir) tmp, left, tmp); if (st == IRT_FLOAT) emit_lsptr(as, MIPSI_LWC1, (tmp & 31), - (void *)lj_ir_k64_find(as->J, U64x(4f000000,4f000000)), - RSET_GPR); + (void *)&as->J->k32[LJ_K32_2P31], RSET_GPR); else emit_lsptr(as, MIPSI_LDC1, (tmp & 31), - (void *)lj_ir_k64_find(as->J, U64x(41e00000,00000000)), - RSET_GPR); + (void *)&as->J->k64[LJ_K64_2P31], RSET_GPR); +#if LJ_64 + } else if (irt_isu64(ir->t)) { /* FP to U64 conversion. */ + MCLabel l_end; + emit_tg(as, MIPSI_DMFC1, dest, tmp); + l_end = emit_label(as); + /* For inputs >= 2^63 add -2^64 and convert again. */ + if (st == IRT_NUM) { + emit_fg(as, MIPSI_TRUNC_L_D, tmp, tmp); + emit_fgh(as, MIPSI_ADD_D, tmp, left, tmp); + emit_lsptr(as, MIPSI_LDC1, (tmp & 31), + (void *)&as->J->k64[LJ_K64_M2P64], + rset_exclude(RSET_GPR, dest)); + emit_fg(as, MIPSI_TRUNC_L_D, tmp, left); /* Delay slot. */ + emit_branch(as, MIPSI_BC1T, 0, 0, l_end); + emit_fgh(as, MIPSI_C_OLT_D, 0, left, tmp); + emit_lsptr(as, MIPSI_LDC1, (tmp & 31), + (void *)&as->J->k64[LJ_K64_2P63], + rset_exclude(RSET_GPR, dest)); + } else { + emit_fg(as, MIPSI_TRUNC_L_S, tmp, tmp); + emit_fgh(as, MIPSI_ADD_S, tmp, left, tmp); + emit_lsptr(as, MIPSI_LWC1, (tmp & 31), + (void *)&as->J->k32[LJ_K32_M2P64], + rset_exclude(RSET_GPR, dest)); + emit_fg(as, MIPSI_TRUNC_L_S, tmp, left); /* Delay slot. */ + emit_branch(as, MIPSI_BC1T, 0, 0, l_end); + emit_fgh(as, MIPSI_C_OLT_S, 0, left, tmp); + emit_lsptr(as, MIPSI_LWC1, (tmp & 31), + (void *)&as->J->k32[LJ_K32_2P63], + rset_exclude(RSET_GPR, dest)); + } +#endif } else { +#if LJ_32 emit_tg(as, MIPSI_MFC1, dest, tmp); emit_fg(as, st == IRT_FLOAT ? MIPSI_TRUNC_W_S : MIPSI_TRUNC_W_D, tmp, left); +#else + MIPSIns mi = irt_is64(ir->t) ? + (st == IRT_NUM ? MIPSI_TRUNC_L_D : MIPSI_TRUNC_L_S) : + (st == IRT_NUM ? MIPSI_TRUNC_W_D : MIPSI_TRUNC_W_S); + emit_tg(as, irt_is64(ir->t) ? MIPSI_DMFC1 : MIPSI_MFC1, dest, left); + emit_fg(as, mi, left, left); +#endif } } } else @@ -514,7 +616,7 @@ static void asm_conv(ASMState *as, IRIns *ir) Reg left = ra_alloc1(as, ir->op1, RSET_GPR); lua_assert(irt_isint(ir->t) || irt_isu32(ir->t)); if ((ir->op2 & IRCONV_SEXT)) { - if ((as->flags & JIT_F_MIPS32R2)) { + if (LJ_64 || (as->flags & JIT_F_MIPSXXR2)) { emit_dst(as, st == IRT_I8 ? MIPSI_SEB : MIPSI_SEH, dest, 0, left); } else { uint32_t shift = st == IRT_I8 ? 24 : 16; @@ -526,8 +628,35 @@ static void asm_conv(ASMState *as, IRIns *ir) (int32_t)(st == IRT_U8 ? 0xff : 0xffff)); } } else { /* 32/64 bit integer conversions. */ +#if LJ_32 /* Only need to handle 32/32 bit no-op (cast) on 32 bit archs. */ ra_leftov(as, dest, lref); /* Do nothing, but may need to move regs. */ +#else + if (irt_is64(ir->t)) { + if (st64) { + /* 64/64 bit no-op (cast)*/ + ra_leftov(as, dest, lref); + } else { + Reg left = ra_alloc1(as, lref, RSET_GPR); + if ((ir->op2 & IRCONV_SEXT)) { /* 32 to 64 bit sign extension. */ + emit_dta(as, MIPSI_SLL, dest, left, 0); + } else { /* 32 to 64 bit zero extension. */ + emit_tsml(as, MIPSI_DEXT, dest, left, 31, 0); + } + } + } else { + if (st64) { + /* This is either a 32 bit reg/reg mov which zeroes the hiword + ** or a load of the loword from a 64 bit address. + */ + Reg left = ra_alloc1(as, lref, RSET_GPR); + emit_tsml(as, MIPSI_DEXT, dest, left, 31, 0); + } else { /* 32/32 bit no-op (cast). */ + /* Do nothing, but may need to move regs. */ + ra_leftov(as, dest, lref); + } + } +#endif } } } @@ -570,23 +699,50 @@ static void asm_strto(ASMState *as, IRIns *ir) args[1] = ASMREF_TMP1; /* TValue *n */ asm_gencall(as, ci, args); /* Store the result to the spill slot or temp slots. */ - emit_tsi(as, MIPSI_ADDIU, ra_releasetmp(as, ASMREF_TMP1), + emit_tsi(as, MIPSI_AADDIU, ra_releasetmp(as, ASMREF_TMP1), RID_SP, ofs); } /* -- Memory references --------------------------------------------------- */ +#if LJ_64 +/* Store tagged value for ref at base+ofs. */ +static void asm_tvstore64(ASMState *as, Reg base, int32_t ofs, IRRef ref) +{ + RegSet allow = rset_exclude(RSET_GPR, base); + IRIns *ir = IR(ref); + lua_assert(irt_ispri(ir->t) || irt_isaddr(ir->t) || irt_isinteger(ir->t)); + if (irref_isk(ref)) { + TValue k; + lj_ir_kvalue(as->J->L, &k, ir); + emit_tsi(as, MIPSI_SD, ra_allock(as, (int64_t)k.u64, allow), base, ofs); + } else { + Reg src = ra_alloc1(as, ref, allow); + Reg type = ra_allock(as, (int64_t)irt_toitype(ir->t) << 47, + rset_exclude(allow, src)); + emit_tsi(as, MIPSI_SD, RID_TMP, base, ofs); + if (irt_isinteger(ir->t)) { + emit_dst(as, MIPSI_DADDU, RID_TMP, RID_TMP, type); + emit_tsml(as, MIPSI_DEXT, RID_TMP, src, 31, 0); + } else { + emit_dst(as, MIPSI_DADDU, RID_TMP, src, type); + } + } +} +#endif + /* Get pointer to TValue. */ static void asm_tvptr(ASMState *as, Reg dest, IRRef ref) { IRIns *ir = IR(ref); if (irt_isnum(ir->t)) { if (irref_isk(ref)) /* Use the number constant itself as a TValue. */ - ra_allockreg(as, i32ptr(ir_knum(ir)), dest); + ra_allockreg(as, igcptr(ir_knum(ir)), dest); else /* Otherwise force a spill and use the spill slot. */ - emit_tsi(as, MIPSI_ADDIU, dest, RID_SP, ra_spill(as, ir)); + emit_tsi(as, MIPSI_AADDIU, dest, RID_SP, ra_spill(as, ir)); } else { /* Otherwise use g->tmptv to hold the TValue. */ +#if LJ_32 RegSet allow = rset_exclude(RSET_GPR, dest); Reg type; emit_tsi(as, MIPSI_ADDIU, dest, RID_JGL, (int32_t)(offsetof(global_State, tmptv)-32768)); @@ -599,6 +755,11 @@ static void asm_tvptr(ASMState *as, Reg dest, IRRef ref) else type = ra_allock(as, (int32_t)irt_toitype(ir->t), allow); emit_setgl(as, type, tmptv.it); +#else + asm_tvstore64(as, dest, 0, ref); + emit_tsi(as, MIPSI_DADDIU, dest, RID_JGL, + (int32_t)(offsetof(global_State, tmptv)-32768)); +#endif } } @@ -613,13 +774,13 @@ static void asm_aref(ASMState *as, IRIns *ir) ofs += 8*IR(ir->op2)->i; if (checki16(ofs)) { base = ra_alloc1(as, refa, RSET_GPR); - emit_tsi(as, MIPSI_ADDIU, dest, base, ofs); + emit_tsi(as, MIPSI_AADDIU, dest, base, ofs); return; } } base = ra_alloc1(as, ir->op1, RSET_GPR); idx = ra_alloc1(as, ir->op2, rset_exclude(RSET_GPR, base)); - emit_dst(as, MIPSI_ADDU, dest, RID_TMP, base); + emit_dst(as, MIPSI_AADDU, dest, RID_TMP, base); emit_dta(as, MIPSI_SLL, RID_TMP, idx, 3); } @@ -640,19 +801,19 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge) Reg key = RID_NONE, type = RID_NONE, tmpnum = RID_NONE, tmp1 = RID_TMP, tmp2; IRRef refkey = ir->op2; IRIns *irkey = IR(refkey); + int isk = irref_isk(refkey); IRType1 kt = irkey->t; uint32_t khash; MCLabel l_end, l_loop, l_next; rset_clear(allow, tab); -#if LJ_SOFTFP - if (!irref_isk(refkey)) { +#if LJ_32 && LJ_SOFTFP + if (!isk) { key = ra_alloc1(as, refkey, allow); rset_clear(allow, key); if (irkey[1].o == IR_HIOP) { if (ra_hasreg((irkey+1)->r)) { - tmpnum = (irkey+1)->r; - type = RID_TMP; + type = tmpnum = (irkey+1)->r; tmp1 = ra_scratch(as, allow); rset_clear(allow, tmp1); ra_noweak(as, tmpnum); @@ -672,8 +833,10 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge) } else if (!irt_ispri(kt)) { key = ra_alloc1(as, refkey, allow); rset_clear(allow, key); +#if LJ_32 type = ra_allock(as, (int32_t)irt_toitype(irkey->t), allow); rset_clear(allow, type); +#endif } #endif tmp2 = ra_scratch(as, allow); @@ -687,9 +850,9 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge) else if (destused) emit_loada(as, dest, niltvg(J2G(as->J))); /* Follow hash chain until the end. */ - emit_move(as, dest, tmp2); + emit_move(as, dest, tmp1); l_loop = --as->mcp; - emit_tsi(as, MIPSI_LW, tmp2, dest, (int32_t)offsetof(Node, next)); + emit_tsi(as, MIPSI_AL, tmp1, dest, (int32_t)offsetof(Node, next)); l_next = emit_label(as); /* Type and value comparison. */ @@ -701,38 +864,66 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge) emit_branch(as, MIPSI_BC1T, 0, 0, l_end); emit_fgh(as, MIPSI_C_EQ_D, 0, tmpnum, key); *--as->mcp = MIPSI_NOP; /* Avoid NaN comparison overhead. */ - emit_branch(as, MIPSI_BEQ, tmp2, RID_ZERO, l_next); - emit_tsi(as, MIPSI_SLTIU, tmp2, tmp2, (int32_t)LJ_TISNUM); + emit_branch(as, MIPSI_BEQ, tmp1, RID_ZERO, l_next); + emit_tsi(as, MIPSI_SLTIU, tmp1, tmp1, (int32_t)LJ_TISNUM); +#if LJ_32 emit_hsi(as, MIPSI_LDC1, tmpnum, dest, (int32_t)offsetof(Node, key.n)); } else { if (irt_ispri(kt)) { - emit_branch(as, MIPSI_BEQ, tmp2, type, l_end); + emit_branch(as, MIPSI_BEQ, tmp1, type, l_end); } else { - emit_branch(as, MIPSI_BEQ, tmp1, key, l_end); - emit_tsi(as, MIPSI_LW, tmp1, dest, (int32_t)offsetof(Node, key.gcr)); - emit_branch(as, MIPSI_BNE, tmp2, type, l_next); + emit_branch(as, MIPSI_BEQ, tmp2, key, l_end); + emit_tsi(as, MIPSI_LW, tmp2, dest, (int32_t)offsetof(Node, key.gcr)); + emit_branch(as, MIPSI_BNE, tmp1, type, l_next); + } + } + emit_tsi(as, MIPSI_LW, tmp1, dest, (int32_t)offsetof(Node, key.it)); + *l_loop = MIPSI_BNE | MIPSF_S(tmp1) | ((as->mcp-l_loop-1) & 0xffffu); +#else + emit_dta(as, MIPSI_DSRA32, tmp1, tmp1, 15); + emit_tg(as, MIPSI_DMTC1, tmp1, tmpnum); + emit_tsi(as, MIPSI_LD, tmp1, dest, (int32_t)offsetof(Node, key.u64)); + } else if (irt_isaddr(kt)) { + Reg refk = tmp2; + if (isk) { + int64_t k = ((int64_t)irt_toitype(irkey->t) << 47) | irkey[1].tv.u64; + refk = ra_allock(as, k, allow); + rset_clear(allow, refk); } + emit_branch(as, MIPSI_BEQ, tmp1, refk, l_end); + emit_tsi(as, MIPSI_LD, tmp1, dest, offsetof(Node, key)); + } else { + Reg pri = ra_allock(as, ~((int64_t)~irt_toitype(ir->t) << 47), allow); + rset_clear(allow, pri); + lua_assert(irt_ispri(kt) && !irt_isnil(kt)); + emit_branch(as, MIPSI_BEQ, tmp1, pri, l_end); + emit_tsi(as, MIPSI_LD, tmp1, dest, offsetof(Node, key)); + } + *l_loop = MIPSI_BNE | MIPSF_S(tmp1) | ((as->mcp-l_loop-1) & 0xffffu); + if (!isk && irt_isaddr(kt)) { + type = ra_allock(as, (int64_t)irt_toitype(kt) << 47, allow); + emit_dst(as, MIPSI_DADDU, tmp2, key, type); + rset_clear(allow, type); } - emit_tsi(as, MIPSI_LW, tmp2, dest, (int32_t)offsetof(Node, key.it)); - *l_loop = MIPSI_BNE | MIPSF_S(tmp2) | ((as->mcp-l_loop-1) & 0xffffu); +#endif /* Load main position relative to tab->node into dest. */ - khash = irref_isk(refkey) ? ir_khash(irkey) : 1; + khash = isk ? ir_khash(irkey) : 1; if (khash == 0) { - emit_tsi(as, MIPSI_LW, dest, tab, (int32_t)offsetof(GCtab, node)); + emit_tsi(as, MIPSI_AL, dest, tab, (int32_t)offsetof(GCtab, node)); } else { Reg tmphash = tmp1; - if (irref_isk(refkey)) + if (isk) tmphash = ra_allock(as, khash, allow); - emit_dst(as, MIPSI_ADDU, dest, dest, tmp1); + emit_dst(as, MIPSI_AADDU, dest, dest, tmp1); lua_assert(sizeof(Node) == 24); emit_dst(as, MIPSI_SUBU, tmp1, tmp2, tmp1); emit_dta(as, MIPSI_SLL, tmp1, tmp1, 3); emit_dta(as, MIPSI_SLL, tmp2, tmp1, 5); emit_dst(as, MIPSI_AND, tmp1, tmp2, tmphash); - emit_tsi(as, MIPSI_LW, dest, tab, (int32_t)offsetof(GCtab, node)); + emit_tsi(as, MIPSI_AL, dest, tab, (int32_t)offsetof(GCtab, node)); emit_tsi(as, MIPSI_LW, tmp2, tab, (int32_t)offsetof(GCtab, hmask)); - if (irref_isk(refkey)) { + if (isk) { /* Nothing to do. */ } else if (irt_isstr(kt)) { emit_tsi(as, MIPSI_LW, tmp1, key, (int32_t)offsetof(GCstr, hash)); @@ -742,9 +933,10 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge) emit_dst(as, MIPSI_XOR, tmp1, tmp1, tmp2); emit_rotr(as, tmp1, tmp1, dest, (-HASH_ROT2-HASH_ROT1)&31); emit_dst(as, MIPSI_SUBU, tmp2, tmp2, dest); +#if LJ_32 if (LJ_SOFTFP ? (irkey[1].o == IR_HIOP) : irt_isnum(kt)) { emit_dst(as, MIPSI_XOR, tmp2, tmp2, tmp1); - if ((as->flags & JIT_F_MIPS32R2)) { + if ((as->flags & JIT_F_MIPSXXR2)) { emit_dta(as, MIPSI_ROTR, dest, tmp1, (-HASH_ROT1)&31); } else { emit_dst(as, MIPSI_OR, dest, dest, tmp1); @@ -764,6 +956,23 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge) emit_rotr(as, dest, tmp1, tmp2, (-HASH_ROT1)&31); emit_dst(as, MIPSI_ADDU, tmp1, key, ra_allock(as, HASH_BIAS, allow)); } +#else + emit_dst(as, MIPSI_XOR, tmp2, tmp2, tmp1); + emit_dta(as, MIPSI_ROTR, dest, tmp1, (-HASH_ROT1)&31); + if (irt_isnum(kt)) { + emit_dst(as, MIPSI_ADDU, tmp1, tmp1, tmp1); + emit_dta(as, MIPSI_DSRA32, tmp1, tmp1, 0); + emit_dta(as, MIPSI_SLL, tmp2, LJ_SOFTFP ? key : tmp1, 0); +#if !LJ_SOFTFP + emit_tg(as, MIPSI_DMFC1, tmp1, key); +#endif + } else { + checkmclim(as); + emit_dta(as, MIPSI_DSRA32, tmp1, tmp1, 0); + emit_dta(as, MIPSI_SLL, tmp2, key, 0); + emit_dst(as, MIPSI_DADDU, tmp1, key, type); + } +#endif } } } @@ -776,17 +985,24 @@ static void asm_hrefk(ASMState *as, IRIns *ir) int32_t kofs = ofs + (int32_t)offsetof(Node, key); Reg dest = (ra_used(ir)||ofs > 32736) ? ra_dest(as, ir, RSET_GPR) : RID_NONE; Reg node = ra_alloc1(as, ir->op1, RSET_GPR); - Reg key = RID_NONE, type = RID_TMP, idx = node; RegSet allow = rset_exclude(RSET_GPR, node); + Reg idx = node; +#if LJ_32 + Reg key = RID_NONE, type = RID_TMP; int32_t lo, hi; +#else + Reg key = ra_scratch(as, allow); + int64_t k; +#endif lua_assert(ofs % sizeof(Node) == 0); if (ofs > 32736) { idx = dest; rset_clear(allow, dest); kofs = (int32_t)offsetof(Node, key); } else if (ra_hasreg(dest)) { - emit_tsi(as, MIPSI_ADDIU, dest, node, ofs); + emit_tsi(as, MIPSI_AADDIU, dest, node, ofs); } +#if LJ_32 if (!irt_ispri(irkey->t)) { key = ra_scratch(as, allow); rset_clear(allow, key); @@ -805,30 +1021,41 @@ nolo: asm_guard(as, MIPSI_BNE, type, hi ? ra_allock(as, hi, allow) : RID_ZERO); if (ra_hasreg(key)) emit_tsi(as, MIPSI_LW, key, idx, kofs+(LJ_BE?4:0)); emit_tsi(as, MIPSI_LW, type, idx, kofs+(LJ_BE?0:4)); +#else + if (irt_ispri(irkey->t)) { + lua_assert(!irt_isnil(irkey->t)); + k = ~((int64_t)~irt_toitype(irkey->t) << 47); + } else if (irt_isnum(irkey->t)) { + k = (int64_t)ir_knum(irkey)->u64; + } else { + k = ((int64_t)irt_toitype(irkey->t) << 47) | (int64_t)ir_kgc(irkey); + } + asm_guard(as, MIPSI_BNE, key, ra_allock(as, k, allow)); + emit_tsi(as, MIPSI_LD, key, idx, kofs); +#endif if (ofs > 32736) - emit_tsi(as, MIPSI_ADDU, dest, node, ra_allock(as, ofs, allow)); + emit_tsi(as, MIPSI_AADDU, dest, node, ra_allock(as, ofs, allow)); } static void asm_uref(ASMState *as, IRIns *ir) { - /* NYI: Check that UREFO is still open and not aliasing a slot. */ Reg dest = ra_dest(as, ir, RSET_GPR); if (irref_isk(ir->op1)) { GCfunc *fn = ir_kfunc(IR(ir->op1)); MRef *v = &gcref(fn->l.uvptr[(ir->op2 >> 8)])->uv.v; - emit_lsptr(as, MIPSI_LW, dest, v, RSET_GPR); + emit_lsptr(as, MIPSI_AL, dest, v, RSET_GPR); } else { Reg uv = ra_scratch(as, RSET_GPR); Reg func = ra_alloc1(as, ir->op1, RSET_GPR); if (ir->o == IR_UREFC) { asm_guard(as, MIPSI_BEQ, RID_TMP, RID_ZERO); - emit_tsi(as, MIPSI_ADDIU, dest, uv, (int32_t)offsetof(GCupval, tv)); + emit_tsi(as, MIPSI_AADDIU, dest, uv, (int32_t)offsetof(GCupval, tv)); emit_tsi(as, MIPSI_LBU, RID_TMP, uv, (int32_t)offsetof(GCupval, closed)); } else { - emit_tsi(as, MIPSI_LW, dest, uv, (int32_t)offsetof(GCupval, v)); + emit_tsi(as, MIPSI_AL, dest, uv, (int32_t)offsetof(GCupval, v)); } - emit_tsi(as, MIPSI_LW, uv, func, - (int32_t)offsetof(GCfuncL, uvptr) + 4*(int32_t)(ir->op2 >> 8)); + emit_tsi(as, MIPSI_AL, uv, func, (int32_t)offsetof(GCfuncL, uvptr) + + (int32_t)sizeof(MRef) * (int32_t)(ir->op2 >> 8)); } } @@ -840,6 +1067,7 @@ static void asm_fref(ASMState *as, IRIns *ir) static void asm_strref(ASMState *as, IRIns *ir) { +#if LJ_32 Reg dest = ra_dest(as, ir, RSET_GPR); IRRef ref = ir->op2, refk = ir->op1; int32_t ofs = (int32_t)sizeof(GCstr); @@ -871,6 +1099,20 @@ static void asm_strref(ASMState *as, IRIns *ir) else emit_dst(as, MIPSI_ADDU, dest, r, ra_allock(as, ofs, rset_exclude(RSET_GPR, r))); +#else + RegSet allow = RSET_GPR; + Reg dest = ra_dest(as, ir, allow); + Reg base = ra_alloc1(as, ir->op1, allow); + IRIns *irr = IR(ir->op2); + int32_t ofs = sizeof(GCstr); + rset_clear(allow, base); + if (irref_isk(ir->op2) && checki16(ofs + irr->i)) { + emit_tsi(as, MIPSI_DADDIU, dest, base, ofs + irr->i); + } else { + emit_tsi(as, MIPSI_DADDIU, dest, dest, ofs); + emit_dst(as, MIPSI_DADDU, dest, base, ra_alloc1(as, ir->op2, allow)); + } +#endif } /* -- Loads and stores ---------------------------------------------------- */ @@ -884,7 +1126,7 @@ static MIPSIns asm_fxloadins(IRIns *ir) case IRT_U16: return MIPSI_LHU; case IRT_NUM: lua_assert(!LJ_SOFTFP); return MIPSI_LDC1; case IRT_FLOAT: if (!LJ_SOFTFP) return MIPSI_LWC1; - default: return MIPSI_LW; + default: return (LJ_64 && irt_is64(ir->t)) ? MIPSI_LD : MIPSI_LW; } } @@ -895,24 +1137,30 @@ static MIPSIns asm_fxstoreins(IRIns *ir) case IRT_I16: case IRT_U16: return MIPSI_SH; case IRT_NUM: lua_assert(!LJ_SOFTFP); return MIPSI_SDC1; case IRT_FLOAT: if (!LJ_SOFTFP) return MIPSI_SWC1; - default: return MIPSI_SW; + default: return (LJ_64 && irt_is64(ir->t)) ? MIPSI_SD : MIPSI_SW; } } static void asm_fload(ASMState *as, IRIns *ir) { Reg dest = ra_dest(as, ir, RSET_GPR); - Reg idx = ra_alloc1(as, ir->op1, RSET_GPR); MIPSIns mi = asm_fxloadins(ir); + Reg idx; int32_t ofs; - if (ir->op2 == IRFL_TAB_ARRAY) { - ofs = asm_fuseabase(as, ir->op1); - if (ofs) { /* Turn the t->array load into an add for colocated arrays. */ - emit_tsi(as, MIPSI_ADDIU, dest, idx, ofs); - return; + if (ir->op1 == REF_NIL) { + idx = RID_JGL; + ofs = (ir->op2 << 2) - 32768 - GG_OFS(g); + } else { + idx = ra_alloc1(as, ir->op1, RSET_GPR); + if (ir->op2 == IRFL_TAB_ARRAY) { + ofs = asm_fuseabase(as, ir->op1); + if (ofs) { /* Turn the t->array load into an add for colocated arrays. */ + emit_tsi(as, MIPSI_AADDIU, dest, idx, ofs); + return; + } } + ofs = field_ofs[ir->op2]; } - ofs = field_ofs[ir->op2]; lua_assert(!irt_isfp(ir->t)); emit_tsi(as, mi, dest, idx, ofs); } @@ -952,36 +1200,59 @@ static void asm_xstore_(ASMState *as, IRIns *ir, int32_t ofs) static void asm_ahuvload(ASMState *as, IRIns *ir) { - int hiop = (LJ_SOFTFP && (ir+1)->o == IR_HIOP); - IRType t = hiop ? IRT_NUM : irt_type(ir->t); + int hiop = (LJ_32 && LJ_SOFTFP && (ir+1)->o == IR_HIOP); Reg dest = RID_NONE, type = RID_TMP, idx; RegSet allow = RSET_GPR; int32_t ofs = 0; - if (hiop && ra_used(ir+1)) { - type = ra_dest(as, ir+1, allow); - rset_clear(allow, type); + IRType1 t = ir->t; + if (hiop) { + t.irt = IRT_NUM; + if (ra_used(ir+1)) { + type = ra_dest(as, ir+1, allow); + rset_clear(allow, type); + } } if (ra_used(ir)) { lua_assert((LJ_SOFTFP ? 0 : irt_isnum(ir->t)) || irt_isint(ir->t) || irt_isaddr(ir->t)); - dest = ra_dest(as, ir, (!LJ_SOFTFP && t == IRT_NUM) ? RSET_FPR : allow); + dest = ra_dest(as, ir, (!LJ_SOFTFP && irt_isnum(t)) ? RSET_FPR : allow); rset_clear(allow, dest); +#if LJ_64 + if (irt_isaddr(t)) + emit_tsml(as, MIPSI_DEXTM, dest, dest, 14, 0); + else if (irt_isint(t)) + emit_dta(as, MIPSI_SLL, dest, dest, 0); +#endif } idx = asm_fuseahuref(as, ir->op1, &ofs, allow); rset_clear(allow, idx); - if (t == IRT_NUM) { + if (irt_isnum(t)) { asm_guard(as, MIPSI_BEQ, RID_TMP, RID_ZERO); emit_tsi(as, MIPSI_SLTIU, RID_TMP, type, (int32_t)LJ_TISNUM); } else { - asm_guard(as, MIPSI_BNE, type, ra_allock(as, irt_toitype_(t), allow)); + asm_guard(as, MIPSI_BNE, type, + ra_allock(as, (int32_t)irt_toitype(t), allow)); } +#if LJ_32 if (ra_hasreg(dest)) { - if (!LJ_SOFTFP && t == IRT_NUM) + if (!LJ_SOFTFP && irt_isnum(t)) emit_hsi(as, MIPSI_LDC1, dest, idx, ofs); else emit_tsi(as, MIPSI_LW, dest, idx, ofs+(LJ_BE?4:0)); } emit_tsi(as, MIPSI_LW, type, idx, ofs+(LJ_BE?0:4)); +#else + if (ra_hasreg(dest)) { + if (!LJ_SOFTFP && irt_isnum(t)) { + emit_hsi(as, MIPSI_LDC1, dest, idx, ofs); + dest = type; + } + } else { + dest = type; + } + emit_dta(as, MIPSI_DSRA32, type, dest, 15); + emit_tsi(as, MIPSI_LD, dest, idx, ofs); +#endif } static void asm_ahustore(ASMState *as, IRIns *ir) @@ -993,103 +1264,159 @@ static void asm_ahustore(ASMState *as, IRIns *ir) return; if (!LJ_SOFTFP && irt_isnum(ir->t)) { src = ra_alloc1(as, ir->op2, RSET_FPR); + idx = asm_fuseahuref(as, ir->op1, &ofs, allow); + emit_hsi(as, MIPSI_SDC1, src, idx, ofs); } else { - int hiop = (LJ_SOFTFP && (ir+1)->o == IR_HIOP); +#if LJ_32 if (!irt_ispri(ir->t)) { src = ra_alloc1(as, ir->op2, allow); rset_clear(allow, src); } - if (hiop) + if (LJ_SOFTFP && (ir+1)->o == IR_HIOP) type = ra_alloc1(as, (ir+1)->op2, allow); else type = ra_allock(as, (int32_t)irt_toitype(ir->t), allow); rset_clear(allow, type); - } - idx = asm_fuseahuref(as, ir->op1, &ofs, allow); - if (!LJ_SOFTFP && irt_isnum(ir->t)) { - emit_hsi(as, MIPSI_SDC1, src, idx, ofs); - } else { + idx = asm_fuseahuref(as, ir->op1, &ofs, allow); if (ra_hasreg(src)) emit_tsi(as, MIPSI_SW, src, idx, ofs+(LJ_BE?4:0)); emit_tsi(as, MIPSI_SW, type, idx, ofs+(LJ_BE?0:4)); +#else + Reg tmp = RID_TMP; + if (irt_ispri(ir->t)) { + tmp = ra_allock(as, ~((int64_t)~irt_toitype(ir->t) << 47), allow); + rset_clear(allow, tmp); + } else { + src = ra_alloc1(as, ir->op2, allow); + rset_clear(allow, src); + type = ra_allock(as, (int64_t)irt_toitype(ir->t) << 47, allow); + rset_clear(allow, type); + } + idx = asm_fuseahuref(as, ir->op1, &ofs, allow); + emit_tsi(as, MIPSI_SD, tmp, idx, ofs); + if (ra_hasreg(src)) { + if (irt_isinteger(ir->t)) { + emit_dst(as, MIPSI_DADDU, tmp, tmp, type); + emit_tsml(as, MIPSI_DEXT, tmp, src, 31, 0); + } else { + emit_dst(as, MIPSI_DADDU, tmp, src, type); + } + } +#endif } } static void asm_sload(ASMState *as, IRIns *ir) { - int32_t ofs = 8*((int32_t)ir->op1-1) + ((ir->op2 & IRSLOAD_FRAME) ? 4 : 0); - int hiop = (LJ_SOFTFP && (ir+1)->o == IR_HIOP); - IRType t = hiop ? IRT_NUM : irt_type(ir->t); Reg dest = RID_NONE, type = RID_NONE, base; RegSet allow = RSET_GPR; + IRType1 t = ir->t; +#if LJ_32 + int32_t ofs = 8*((int32_t)ir->op1-1) + ((ir->op2 & IRSLOAD_FRAME) ? 4 : 0); + int hiop = (LJ_32 && LJ_SOFTFP && (ir+1)->o == IR_HIOP); + if (hiop) + t.irt = IRT_NUM; +#else + int32_t ofs = 8*((int32_t)ir->op1-2); +#endif lua_assert(!(ir->op2 & IRSLOAD_PARENT)); /* Handled by asm_head_side(). */ lua_assert(irt_isguard(ir->t) || !(ir->op2 & IRSLOAD_TYPECHECK)); -#if LJ_SOFTFP +#if LJ_32 && LJ_SOFTFP lua_assert(!(ir->op2 & IRSLOAD_CONVERT)); /* Handled by LJ_SOFTFP SPLIT. */ if (hiop && ra_used(ir+1)) { type = ra_dest(as, ir+1, allow); rset_clear(allow, type); } #else - if ((ir->op2 & IRSLOAD_CONVERT) && irt_isguard(ir->t) && t == IRT_INT) { + if ((ir->op2 & IRSLOAD_CONVERT) && irt_isguard(t) && irt_isint(t)) { dest = ra_scratch(as, RSET_FPR); asm_tointg(as, ir, dest); - t = IRT_NUM; /* Continue with a regular number type check. */ + t.irt = IRT_NUM; /* Continue with a regular number type check. */ } else #endif if (ra_used(ir)) { lua_assert((LJ_SOFTFP ? 0 : irt_isnum(ir->t)) || irt_isint(ir->t) || irt_isaddr(ir->t)); - dest = ra_dest(as, ir, (!LJ_SOFTFP && t == IRT_NUM) ? RSET_FPR : allow); + dest = ra_dest(as, ir, (!LJ_SOFTFP && irt_isnum(t)) ? RSET_FPR : allow); rset_clear(allow, dest); base = ra_alloc1(as, REF_BASE, allow); rset_clear(allow, base); if (!LJ_SOFTFP && (ir->op2 & IRSLOAD_CONVERT)) { - if (t == IRT_INT) { + if (irt_isint(t)) { Reg tmp = ra_scratch(as, RSET_FPR); emit_tg(as, MIPSI_MFC1, dest, tmp); emit_fg(as, MIPSI_TRUNC_W_D, tmp, tmp); dest = tmp; - t = IRT_NUM; /* Check for original type. */ + t.irt = IRT_NUM; /* Check for original type. */ } else { Reg tmp = ra_scratch(as, RSET_GPR); emit_fg(as, MIPSI_CVT_D_W, dest, dest); emit_tg(as, MIPSI_MTC1, tmp, dest); dest = tmp; - t = IRT_INT; /* Check for original type. */ + t.irt = IRT_INT; /* Check for original type. */ } } +#if LJ_64 + else if (irt_isaddr(t)) { + /* Clear type from pointers. */ + emit_tsml(as, MIPSI_DEXTM, dest, dest, 14, 0); + } else if (irt_isint(t) && (ir->op2 & IRSLOAD_TYPECHECK)) { + /* Sign-extend integers. */ + emit_dta(as, MIPSI_SLL, dest, dest, 0); + } +#endif goto dotypecheck; } base = ra_alloc1(as, REF_BASE, allow); rset_clear(allow, base); dotypecheck: +#if LJ_32 if ((ir->op2 & IRSLOAD_TYPECHECK)) { - if (ra_noreg(type)) { - if (ofs < 256 && ra_hasreg(dest) && (dest & 1) == 0 && - rset_test((as->freeset & allow), dest+1)) { - type = dest+1; - ra_modified(as, type); - } else { - type = RID_TMP; - } - } - if (t == IRT_NUM) { + if (ra_noreg(type)) + type = RID_TMP; + if (irt_isnum(t)) { asm_guard(as, MIPSI_BEQ, RID_TMP, RID_ZERO); emit_tsi(as, MIPSI_SLTIU, RID_TMP, type, (int32_t)LJ_TISNUM); } else { - Reg ktype = ra_allock(as, irt_toitype_(t), allow); + Reg ktype = ra_allock(as, irt_toitype(t), allow); asm_guard(as, MIPSI_BNE, type, ktype); } } if (ra_hasreg(dest)) { - if (!LJ_SOFTFP && t == IRT_NUM) + if (!LJ_SOFTFP && irt_isnum(t)) emit_hsi(as, MIPSI_LDC1, dest, base, ofs); else emit_tsi(as, MIPSI_LW, dest, base, ofs ^ (LJ_BE?4:0)); } if (ra_hasreg(type)) emit_tsi(as, MIPSI_LW, type, base, ofs ^ (LJ_BE?0:4)); +#else + if ((ir->op2 & IRSLOAD_TYPECHECK)) { + type = dest < RID_MAX_GPR ? dest : RID_TMP; + if (irt_ispri(t)) { + asm_guard(as, MIPSI_BNE, type, + ra_allock(as, ~((int64_t)~irt_toitype(t) << 47) , allow)); + } else { + if (irt_isnum(t)) { + asm_guard(as, MIPSI_BEQ, RID_TMP, RID_ZERO); + emit_tsi(as, MIPSI_SLTIU, RID_TMP, RID_TMP, (int32_t)LJ_TISNUM); + if (ra_hasreg(dest)) + emit_hsi(as, MIPSI_LDC1, dest, base, ofs); + } else { + asm_guard(as, MIPSI_BNE, RID_TMP, + ra_allock(as, (int32_t)irt_toitype(t), allow)); + } + emit_dta(as, MIPSI_DSRA32, RID_TMP, type, 15); + } + emit_tsi(as, MIPSI_LD, type, base, ofs); + } else if (ra_hasreg(dest)) { + if (irt_isnum(t)) + emit_hsi(as, MIPSI_LDC1, dest, base, ofs); + else + emit_tsi(as, irt_isint(t) ? MIPSI_LW : MIPSI_LD, dest, base, + ofs ^ ((LJ_BE && irt_isint(t)) ? 4 : 0)); + } +#endif } /* -- Allocations --------------------------------------------------------- */ @@ -1116,8 +1443,8 @@ static void asm_cnew(ASMState *as, IRIns *ir) /* Initialize immutable cdata object. */ if (ir->o == IR_CNEWI) { RegSet allow = (RSET_GPR & ~RSET_SCRATCH); +#if LJ_32 int32_t ofs = sizeof(GCcdata); - lua_assert(sz == 4 || sz == 8); if (sz == 8) { ofs += 4; lua_assert((ir+1)->o == IR_HIOP); @@ -1130,6 +1457,11 @@ static void asm_cnew(ASMState *as, IRIns *ir) if (ofs == sizeof(GCcdata)) break; ofs -= 4; if (LJ_BE) ir++; else ir--; } +#else + emit_tsi(as, MIPSI_SD, ra_alloc1(as, ir->op2, allow), + RID_RET, sizeof(GCcdata)); +#endif + lua_assert(sz == 4 || sz == 8); } else if (ir->op2 != REF_NIL) { /* Create VLA/VLS/aligned cdata. */ ci = &lj_ir_callinfo[IRCALL_lj_cdata_newv]; args[0] = ASMREF_L; /* lua_State *L */ @@ -1164,7 +1496,7 @@ static void asm_tbar(ASMState *as, IRIns *ir) Reg mark = ra_scratch(as, rset_exclude(RSET_GPR, tab)); Reg link = RID_TMP; MCLabel l_end = emit_label(as); - emit_tsi(as, MIPSI_SW, link, tab, (int32_t)offsetof(GCtab, gclist)); + emit_tsi(as, MIPSI_AS, link, tab, (int32_t)offsetof(GCtab, gclist)); emit_tsi(as, MIPSI_SB, mark, tab, (int32_t)offsetof(GCtab, marked)); emit_setgl(as, tab, gc.grayagain); emit_getgl(as, link, gc.grayagain); @@ -1187,7 +1519,7 @@ static void asm_obar(ASMState *as, IRIns *ir) args[0] = ASMREF_TMP1; /* global_State *g */ args[1] = ir->op1; /* TValue *tv */ asm_gencall(as, ci, args); - emit_tsi(as, MIPSI_ADDIU, ra_releasetmp(as, ASMREF_TMP1), RID_JGL, -32768); + emit_tsi(as, MIPSI_AADDIU, ra_releasetmp(as, ASMREF_TMP1), RID_JGL, -32768); obj = IR(ir->op1)->r; tmp = ra_scratch(as, rset_exclude(RSET_GPR, obj)); emit_branch(as, MIPSI_BEQ, RID_TMP, RID_ZERO, l_end); @@ -1233,8 +1565,9 @@ static void asm_fpmath(ASMState *as, IRIns *ir) static void asm_add(ASMState *as, IRIns *ir) { + IRType1 t = ir->t; #if !LJ_SOFTFP - if (irt_isnum(ir->t)) { + if (irt_isnum(t)) { asm_fparith(as, ir, MIPSI_ADD_D); } else #endif @@ -1242,14 +1575,16 @@ static void asm_add(ASMState *as, IRIns *ir) Reg dest = ra_dest(as, ir, RSET_GPR); Reg right, left = ra_hintalloc(as, ir->op1, dest, RSET_GPR); if (irref_isk(ir->op2)) { - int32_t k = IR(ir->op2)->i; + intptr_t k = get_kval(IR(ir->op2)); if (checki16(k)) { - emit_tsi(as, MIPSI_ADDIU, dest, left, k); + emit_tsi(as, (LJ_64 && irt_is64(t)) ? MIPSI_DADDIU : MIPSI_ADDIU, dest, + left, k); return; } } right = ra_alloc1(as, ir->op2, rset_exclude(RSET_GPR, left)); - emit_dst(as, MIPSI_ADDU, dest, left, right); + emit_dst(as, (LJ_64 && irt_is64(t)) ? MIPSI_DADDU : MIPSI_ADDU, dest, + left, right); } } @@ -1264,7 +1599,8 @@ static void asm_sub(ASMState *as, IRIns *ir) Reg dest = ra_dest(as, ir, RSET_GPR); Reg right, left = ra_alloc2(as, ir, RSET_GPR); right = (left >> 8); left &= 255; - emit_dst(as, MIPSI_SUBU, dest, left, right); + emit_dst(as, (LJ_64 && irt_is64(ir->t)) ? MIPSI_DSUBU : MIPSI_SUBU, dest, + left, right); } } @@ -1279,13 +1615,49 @@ static void asm_mul(ASMState *as, IRIns *ir) Reg dest = ra_dest(as, ir, RSET_GPR); Reg right, left = ra_alloc2(as, ir, RSET_GPR); right = (left >> 8); left &= 255; - emit_dst(as, MIPSI_MUL, dest, left, right); + if (LJ_64 && irt_is64(ir->t)) { + emit_dst(as, MIPSI_MFLO, dest, 0, 0); + emit_dst(as, MIPSI_DMULT, 0, left, right); + } else { + emit_dst(as, MIPSI_MUL, dest, left, right); + } } } -#define asm_div(as, ir) asm_fparith(as, ir, MIPSI_DIV_D) -#define asm_mod(as, ir) asm_callid(as, ir, IRCALL_lj_vm_modi) -#define asm_pow(as, ir) asm_callid(as, ir, IRCALL_lj_vm_powi) +static void asm_mod(ASMState *as, IRIns *ir) +{ +#if LJ_64 && LJ_HASFFI + if (!irt_isint(ir->t)) + asm_callid(as, ir, irt_isi64(ir->t) ? IRCALL_lj_carith_modi64 : + IRCALL_lj_carith_modu64); + else +#endif + asm_callid(as, ir, IRCALL_lj_vm_modi); +} + +#if !LJ_SOFTFP +static void asm_pow(ASMState *as, IRIns *ir) +{ +#if LJ_64 && LJ_HASFFI + if (!irt_isnum(ir->t)) + asm_callid(as, ir, irt_isi64(ir->t) ? IRCALL_lj_carith_powi64 : + IRCALL_lj_carith_powu64); + else +#endif + asm_callid(as, ir, IRCALL_lj_vm_powi); +} + +static void asm_div(ASMState *as, IRIns *ir) +{ +#if LJ_64 && LJ_HASFFI + if (!irt_isnum(ir->t)) + asm_callid(as, ir, irt_isi64(ir->t) ? IRCALL_lj_carith_divi64 : + IRCALL_lj_carith_divu64); + else +#endif + asm_fparith(as, ir, MIPSI_DIV_D); +} +#endif static void asm_neg(ASMState *as, IRIns *ir) { @@ -1297,7 +1669,8 @@ static void asm_neg(ASMState *as, IRIns *ir) { Reg dest = ra_dest(as, ir, RSET_GPR); Reg left = ra_hintalloc(as, ir->op1, dest, RSET_GPR); - emit_dst(as, MIPSI_SUBU, dest, RID_ZERO, left); + emit_dst(as, (LJ_64 && irt_is64(ir->t)) ? MIPSI_DSUBU : MIPSI_SUBU, dest, + RID_ZERO, left); } } @@ -1308,6 +1681,7 @@ static void asm_neg(ASMState *as, IRIns *ir) static void asm_arithov(ASMState *as, IRIns *ir) { Reg right, left, tmp, dest = ra_dest(as, ir, RSET_GPR); + lua_assert(!irt_is64(ir->t)); if (irref_isk(ir->op2)) { int k = IR(ir->op2)->i; if (ir->o == IR_SUBOV) k = -k; @@ -1355,7 +1729,7 @@ static void asm_mulov(ASMState *as, IRIns *ir) emit_dst(as, MIPSI_MULT, 0, left, right); } -#if LJ_HASFFI +#if LJ_32 && LJ_HASFFI static void asm_add64(ASMState *as, IRIns *ir) { Reg dest = ra_dest(as, ir, RSET_GPR); @@ -1457,7 +1831,8 @@ static void asm_bswap(ASMState *as, IRIns *ir) { Reg dest = ra_dest(as, ir, RSET_GPR); Reg left = ra_alloc1(as, ir->op1, RSET_GPR); - if ((as->flags & JIT_F_MIPS32R2)) { +#if LJ_32 + if ((as->flags & JIT_F_MIPSXXR2)) { emit_dta(as, MIPSI_ROTR, dest, RID_TMP, 16); emit_dst(as, MIPSI_WSBH, RID_TMP, 0, left); } else { @@ -1472,6 +1847,15 @@ static void asm_bswap(ASMState *as, IRIns *ir) emit_dta(as, MIPSI_SRL, tmp, left, 24); emit_dta(as, MIPSI_SLL, RID_TMP, left, 24); } +#else + if (irt_is64(ir->t)) { + emit_dst(as, MIPSI_DSHD, dest, 0, RID_TMP); + emit_dst(as, MIPSI_DSBH, RID_TMP, 0, left); + } else { + emit_dta(as, MIPSI_ROTR, dest, RID_TMP, 16); + emit_dst(as, MIPSI_WSBH, RID_TMP, 0, left); + } +#endif } static void asm_bitop(ASMState *as, IRIns *ir, MIPSIns mi, MIPSIns mik) @@ -1479,7 +1863,7 @@ static void asm_bitop(ASMState *as, IRIns *ir, MIPSIns mi, MIPSIns mik) Reg dest = ra_dest(as, ir, RSET_GPR); Reg right, left = ra_hintalloc(as, ir->op1, dest, RSET_GPR); if (irref_isk(ir->op2)) { - int32_t k = IR(ir->op2)->i; + intptr_t k = get_kval(IR(ir->op2)); if (checku16(k)) { emit_tsi(as, mik, dest, left, k); return; @@ -1497,11 +1881,14 @@ static void asm_bitshift(ASMState *as, IRIns *ir, MIPSIns mi, MIPSIns mik) { Reg dest = ra_dest(as, ir, RSET_GPR); if (irref_isk(ir->op2)) { /* Constant shifts. */ - uint32_t shift = (uint32_t)(IR(ir->op2)->i & 31); - emit_dta(as, mik, dest, ra_hintalloc(as, ir->op1, dest, RSET_GPR), shift); + uint32_t shift = (uint32_t)IR(ir->op2)->i; + if (LJ_64 && irt_is64(ir->t)) mik |= (shift & 32) ? MIPSI_D32 : MIPSI_D; + emit_dta(as, mik, dest, ra_hintalloc(as, ir->op1, dest, RSET_GPR), + (shift & 31)); } else { Reg right, left = ra_alloc2(as, ir, RSET_GPR); right = (left >> 8); left &= 255; + if (LJ_64 && irt_is64(ir->t)) mi |= MIPSI_DV; emit_dst(as, mi, dest, right, left); /* Shift amount is in rs. */ } } @@ -1513,7 +1900,7 @@ static void asm_bitshift(ASMState *as, IRIns *ir, MIPSIns mi, MIPSIns mik) static void asm_bror(ASMState *as, IRIns *ir) { - if ((as->flags & JIT_F_MIPS32R2)) { + if (LJ_64 || (as->flags & JIT_F_MIPSXXR2)) { asm_bitshift(as, ir, MIPSI_ROTRV, MIPSI_ROTR); } else { Reg dest = ra_dest(as, ir, RSET_GPR); @@ -1532,7 +1919,7 @@ static void asm_bror(ASMState *as, IRIns *ir) } } -#if LJ_SOFTFP +#if LJ_32 && LJ_SOFTFP static void asm_sfpmin_max(ASMState *as, IRIns *ir) { CCallInfo ci = lj_ir_callinfo[(IROp)ir->o == IR_MIN ? IRCALL_lj_vm_sfmin : IRCALL_lj_vm_sfmax]; @@ -1581,7 +1968,7 @@ static void asm_min_max(ASMState *as, IRIns *ir, int ismax) /* -- Comparisons --------------------------------------------------------- */ -#if LJ_SOFTFP +#if LJ_32 && LJ_SOFTFP /* SFP comparisons. */ static void asm_sfpcomp(ASMState *as, IRIns *ir) { @@ -1654,13 +2041,13 @@ static void asm_comp(ASMState *as, IRIns *ir) } else { Reg right, left = ra_alloc1(as, ir->op1, RSET_GPR); if (op == IR_ABC) op = IR_UGT; - if ((op&4) == 0 && irref_isk(ir->op2) && IR(ir->op2)->i == 0) { + if ((op&4) == 0 && irref_isk(ir->op2) && get_kval(IR(ir->op2)) == 0) { MIPSIns mi = (op&2) ? ((op&1) ? MIPSI_BLEZ : MIPSI_BGTZ) : ((op&1) ? MIPSI_BLTZ : MIPSI_BGEZ); asm_guard(as, mi, left, 0); } else { if (irref_isk(ir->op2)) { - int32_t k = IR(ir->op2)->i; + intptr_t k = get_kval(IR(ir->op2)); if ((op&2)) k++; if (checki16(k)) { asm_guard(as, (op&1) ? MIPSI_BNE : MIPSI_BEQ, RID_TMP, RID_ZERO); @@ -1679,7 +2066,8 @@ static void asm_comp(ASMState *as, IRIns *ir) static void asm_equal(ASMState *as, IRIns *ir) { - Reg right, left = ra_alloc2(as, ir, (!LJ_SOFTFP && irt_isnum(ir->t)) ? RSET_FPR : RSET_GPR); + Reg right, left = ra_alloc2(as, ir, (!LJ_SOFTFP && irt_isnum(ir->t)) ? + RSET_FPR : RSET_GPR); right = (left >> 8); left &= 255; if (!LJ_SOFTFP && irt_isnum(ir->t)) { asm_guard(as, (ir->o & 1) ? MIPSI_BC1T : MIPSI_BC1F, 0, 0); @@ -1689,7 +2077,7 @@ static void asm_equal(ASMState *as, IRIns *ir) } } -#if LJ_HASFFI +#if LJ_32 && LJ_HASFFI /* 64 bit integer comparisons. */ static void asm_comp64(ASMState *as, IRIns *ir) { @@ -1731,7 +2119,7 @@ static void asm_comp64eq(ASMState *as, IRIns *ir) /* Hiword op of a split 64 bit op. Previous op must be the loword op. */ static void asm_hiop(ASMState *as, IRIns *ir) { -#if LJ_HASFFI || LJ_SOFTFP +#if LJ_32 && (LJ_HASFFI || LJ_SOFTFP) /* HIOP is marked as a store because it needs its own DCE logic. */ int uselo = ra_used(ir-1), usehi = ra_used(ir); /* Loword/hiword used? */ if (LJ_UNLIKELY(!(as->flags & JIT_F_OPT_DCE))) uselo = usehi = 1; @@ -1835,36 +2223,42 @@ static void asm_stack_check(ASMState *as, BCReg topslot, Reg tmp, pbase = irp ? (ra_hasreg(irp->r) ? irp->r : RID_TMP) : RID_BASE; ExitNo oldsnap = as->snapno; rset_clear(allow, pbase); +#if LJ_32 tmp = allow ? rset_pickbot(allow) : (pbase == RID_RETHI ? RID_RETLO : RID_RETHI); +#else + tmp = allow ? rset_pickbot(allow) : RID_RET; +#endif as->snapno = exitno; asm_guard(as, MIPSI_BNE, RID_TMP, RID_ZERO); as->snapno = oldsnap; if (allow == RSET_EMPTY) /* Restore temp. register. */ - emit_tsi(as, MIPSI_LW, tmp, RID_SP, 0); + emit_tsi(as, MIPSI_AL, tmp, RID_SP, 0); else ra_modified(as, tmp); emit_tsi(as, MIPSI_SLTIU, RID_TMP, RID_TMP, (int32_t)(8*topslot)); - emit_dst(as, MIPSI_SUBU, RID_TMP, tmp, pbase); - emit_tsi(as, MIPSI_LW, tmp, tmp, offsetof(lua_State, maxstack)); + emit_dst(as, MIPSI_ASUBU, RID_TMP, tmp, pbase); + emit_tsi(as, MIPSI_AL, tmp, tmp, offsetof(lua_State, maxstack)); if (pbase == RID_TMP) emit_getgl(as, RID_TMP, jit_base); emit_getgl(as, tmp, cur_L); if (allow == RSET_EMPTY) /* Spill temp. register. */ - emit_tsi(as, MIPSI_SW, tmp, RID_SP, 0); + emit_tsi(as, MIPSI_AS, tmp, RID_SP, 0); } /* Restore Lua stack from on-trace state. */ static void asm_stack_restore(ASMState *as, SnapShot *snap) { SnapEntry *map = &as->T->snapmap[snap->mapofs]; - SnapEntry *flinks = &as->T->snapmap[snap_nextofs(as->T, snap)-1]; +#if LJ_32 || defined(LUA_USE_ASSERT) + SnapEntry *flinks = &as->T->snapmap[snap_nextofs(as->T, snap)-1-LJ_FR2]; +#endif MSize n, nent = snap->nent; /* Store the value of all modified slots to the Lua stack. */ for (n = 0; n < nent; n++) { SnapEntry sn = map[n]; BCReg s = snap_slot(sn); - int32_t ofs = 8*((int32_t)s-1); + int32_t ofs = 8*((int32_t)s-1-LJ_FR2); IRRef ref = snap_ref(sn); IRIns *ir = IR(ref); if ((sn & SNAP_NORESTORE)) @@ -1884,8 +2278,9 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap) emit_hsi(as, MIPSI_SDC1, src, RID_BASE, ofs); #endif } else { - Reg type; +#if LJ_32 RegSet allow = rset_exclude(RSET_GPR, RID_BASE); + Reg type; lua_assert(irt_ispri(ir->t) || irt_isaddr(ir->t) || irt_isinteger(ir->t)); if (!irt_ispri(ir->t)) { Reg src = ra_alloc1(as, ref, allow); @@ -1903,6 +2298,9 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap) type = ra_allock(as, (int32_t)irt_toitype(ir->t), allow); } emit_tsi(as, MIPSI_SW, type, RID_BASE, ofs+(LJ_BE?0:4)); +#else + asm_tvstore64(as, RID_BASE, ofs, ref); +#endif } checkmclim(as); } @@ -1926,7 +2324,7 @@ static void asm_gc_check(ASMState *as) args[0] = ASMREF_TMP1; /* global_State *g */ args[1] = ASMREF_TMP2; /* MSize steps */ asm_gencall(as, ci, args); - emit_tsi(as, MIPSI_ADDIU, ra_releasetmp(as, ASMREF_TMP1), RID_JGL, -32768); + emit_tsi(as, MIPSI_AADDIU, ra_releasetmp(as, ASMREF_TMP1), RID_JGL, -32768); tmp = ra_releasetmp(as, ASMREF_TMP2); emit_loadi(as, tmp, as->gcsteps); /* Jump around GC step if GC total < GC threshold. */ @@ -2001,7 +2399,7 @@ static void asm_tail_fixup(ASMState *as, TraceNo lnk) MCode *target = lnk ? traceref(as->J,lnk)->mcode : (MCode *)lj_vm_exit_interp; int32_t spadj = as->T->spadjust; MCode *p = as->mctop-1; - *p = spadj ? (MIPSI_ADDIU|MIPSF_T(RID_SP)|MIPSF_S(RID_SP)|spadj) : MIPSI_NOP; + *p = spadj ? (MIPSI_AADDIU|MIPSF_T(RID_SP)|MIPSF_S(RID_SP)|spadj) : MIPSI_NOP; p[-1] = MIPSI_J|(((uintptr_t)target>>2)&0x03ffffffu); } @@ -2019,9 +2417,14 @@ static Reg asm_setup_call_slots(ASMState *as, IRIns *ir, const CCallInfo *ci) { IRRef args[CCI_NARGS_MAX*2]; uint32_t i, nargs = CCI_XNARGS(ci); +#if LJ_32 int nslots = 4, ngpr = REGARG_NUMGPR, nfpr = REGARG_NUMFPR; +#else + int nslots = 0, ngpr = REGARG_NUMGPR; +#endif asm_collectargs(as, ir, ci, args); for (i = 0; i < nargs; i++) { +#if LJ_32 if (!LJ_SOFTFP && args[i] && irt_isfp(IR(args[i])->t) && nfpr > 0 && !(ci->flags & CCI_VARARG)) { nfpr--; @@ -2034,6 +2437,9 @@ static Reg asm_setup_call_slots(ASMState *as, IRIns *ir, const CCallInfo *ci) nfpr = 0; if (ngpr > 0) ngpr--; else nslots++; } +#else + if (ngpr > 0) ngpr--; else nslots += 2; +#endif } if (nslots > as->evenspill) /* Leave room for args in stack slots. */ as->evenspill = nslots; diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_ppc.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_ppc.h index 0ebed40fdaa..6daa861b91a 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_ppc.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_ppc.h @@ -1,6 +1,6 @@ /* ** PPC IR assembler (SSA IR -> machine code). -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ /* -- Register allocator extensions --------------------------------------- */ @@ -393,8 +393,7 @@ static void asm_tointg(ASMState *as, IRIns *ir, Reg left) emit_asi(as, PPCI_XORIS, RID_TMP, dest, 0x8000); emit_tai(as, PPCI_LWZ, dest, RID_SP, SPOFS_TMPLO); emit_lsptr(as, PPCI_LFS, (fbias & 31), - (void *)lj_ir_k64_find(as->J, U64x(59800004,59800000)), - RSET_GPR); + (void *)&as->J->k32[LJ_K32_2P52_2P31], RSET_GPR); emit_fai(as, PPCI_STFD, tmp, RID_SP, SPOFS_TMP); emit_fb(as, PPCI_FCTIWZ, tmp, left); } @@ -433,13 +432,11 @@ static void asm_conv(ASMState *as, IRIns *ir) Reg left = ra_alloc1(as, lref, allow); Reg hibias = ra_allock(as, 0x43300000, rset_clear(allow, left)); Reg fbias = ra_scratch(as, rset_exclude(RSET_FPR, dest)); - const float *kbias; if (irt_isfloat(ir->t)) emit_fb(as, PPCI_FRSP, dest, dest); emit_fab(as, PPCI_FSUB, dest, dest, fbias); emit_fai(as, PPCI_LFD, dest, RID_SP, SPOFS_TMP); - kbias = (const float *)lj_ir_k64_find(as->J, U64x(59800004,59800000)); - if (st == IRT_U32) kbias++; - emit_lsptr(as, PPCI_LFS, (fbias & 31), (void *)kbias, + emit_lsptr(as, PPCI_LFS, (fbias & 31), + &as->J->k32[st == IRT_U32 ? LJ_K32_2P52 : LJ_K32_2P52_2P31], rset_clear(allow, hibias)); emit_tai(as, PPCI_STW, st == IRT_U32 ? left : RID_TMP, RID_SP, SPOFS_TMPLO); @@ -472,8 +469,7 @@ static void asm_conv(ASMState *as, IRIns *ir) emit_fb(as, PPCI_FCTIWZ, tmp, tmp); emit_fab(as, PPCI_FSUB, tmp, left, tmp); emit_lsptr(as, PPCI_LFS, (tmp & 31), - (void *)lj_ir_k64_find(as->J, U64x(4f000000,00000000)), - RSET_GPR); + (void *)&as->J->k32[LJ_K32_2P31], RSET_GPR); } else { emit_tai(as, PPCI_LWZ, dest, RID_SP, SPOFS_TMPLO); emit_fai(as, PPCI_STFD, tmp, RID_SP, SPOFS_TMP); @@ -717,7 +713,6 @@ static void asm_hrefk(ASMState *as, IRIns *ir) static void asm_uref(ASMState *as, IRIns *ir) { - /* NYI: Check that UREFO is still open and not aliasing a slot. */ Reg dest = ra_dest(as, ir, RSET_GPR); if (irref_isk(ir->op1)) { GCfunc *fn = ir_kfunc(IR(ir->op1)); @@ -809,17 +804,23 @@ static PPCIns asm_fxstoreins(IRIns *ir) static void asm_fload(ASMState *as, IRIns *ir) { Reg dest = ra_dest(as, ir, RSET_GPR); - Reg idx = ra_alloc1(as, ir->op1, RSET_GPR); PPCIns pi = asm_fxloadins(ir); + Reg idx; int32_t ofs; - if (ir->op2 == IRFL_TAB_ARRAY) { - ofs = asm_fuseabase(as, ir->op1); - if (ofs) { /* Turn the t->array load into an add for colocated arrays. */ - emit_tai(as, PPCI_ADDI, dest, idx, ofs); - return; + if (ir->op1 == REF_NIL) { + idx = RID_JGL; + ofs = (ir->op2 << 2) - 32768; + } else { + idx = ra_alloc1(as, ir->op1, RSET_GPR); + if (ir->op2 == IRFL_TAB_ARRAY) { + ofs = asm_fuseabase(as, ir->op1); + if (ofs) { /* Turn the t->array load into an add for colocated arrays. */ + emit_tai(as, PPCI_ADDI, dest, idx, ofs); + return; + } } + ofs = field_ofs[ir->op2]; } - ofs = field_ofs[ir->op2]; lua_assert(!irt_isi8(ir->t)); emit_tai(as, pi, dest, idx, ofs); } @@ -975,7 +976,7 @@ static void asm_sload(ASMState *as, IRIns *ir) emit_fab(as, PPCI_FSUB, dest, dest, fbias); emit_fai(as, PPCI_LFD, dest, RID_SP, SPOFS_TMP); emit_lsptr(as, PPCI_LFS, (fbias & 31), - (void *)lj_ir_k64_find(as->J, U64x(59800004,59800000)), + (void *)&as->J->k32[LJ_K32_2P52_2P31], rset_clear(allow, hibias)); emit_tai(as, PPCI_STW, tmp, RID_SP, SPOFS_TMPLO); emit_tai(as, PPCI_STW, hibias, RID_SP, SPOFS_TMPHI); diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_x86.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_x86.h index 512e05346e6..3e189b1d04e 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_x86.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_x86.h @@ -1,6 +1,6 @@ /* ** x86/x64 IR assembler (SSA IR -> machine code). -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ /* -- Guard handling ------------------------------------------------------ */ @@ -21,12 +21,14 @@ static MCode *asm_exitstub_gen(ASMState *as, ExitNo group) } /* Push the high byte of the exitno for each exit stub group. */ *mxp++ = XI_PUSHi8; *mxp++ = (MCode)((group*EXITSTUBS_PER_GROUP)>>8); +#if !LJ_GC64 /* Store DISPATCH at original stack slot 0. Account for the two push ops. */ *mxp++ = XI_MOVmi; *mxp++ = MODRM(XM_OFS8, 0, RID_ESP); *mxp++ = MODRM(XM_SCALE1, RID_ESP, RID_ESP); *mxp++ = 2*sizeof(void *); *(int32_t *)mxp = ptr2addr(J2GG(as->J)->dispatch); mxp += 4; +#endif /* Jump to exit handler which fills in the ExitState. */ *mxp++ = XI_JMP; mxp += 4; *((int32_t *)(mxp-4)) = jmprel(mxp, (MCode *)(void *)lj_vm_exit_handler); @@ -62,10 +64,14 @@ static void asm_guardcc(ASMState *as, int cc) target = p; cc ^= 1; if (as->realign) { + if (LJ_GC64 && LJ_UNLIKELY(as->mrm.base == RID_RIP)) + as->mrm.ofs += 2; /* Fixup RIP offset for pending fused load. */ emit_sjcc(as, cc, target); return; } } + if (LJ_GC64 && LJ_UNLIKELY(as->mrm.base == RID_RIP)) + as->mrm.ofs += 6; /* Fixup RIP offset for pending fused load. */ emit_jcc(as, cc, target); } @@ -79,6 +85,15 @@ static int asm_isk32(ASMState *as, IRRef ref, int32_t *k) { if (irref_isk(ref)) { IRIns *ir = IR(ref); +#if LJ_GC64 + if (ir->o == IR_KNULL || !irt_is64(ir->t)) { + *k = ir->i; + return 1; + } else if (checki32((int64_t)ir_k64(ir)->u64)) { + *k = (int32_t)ir_k64(ir)->u64; + return 1; + } +#else if (ir->o != IR_KINT64) { *k = ir->i; return 1; @@ -86,6 +101,7 @@ static int asm_isk32(ASMState *as, IRRef ref, int32_t *k) *k = (int32_t)ir_kint64(ir)->u64; return 1; } +#endif } return 0; } @@ -185,9 +201,19 @@ static void asm_fuseahuref(ASMState *as, IRRef ref, RegSet allow) if (irref_isk(ir->op1)) { GCfunc *fn = ir_kfunc(IR(ir->op1)); GCupval *uv = &gcref(fn->l.uvptr[(ir->op2 >> 8)])->uv; +#if LJ_GC64 + int64_t ofs = dispofs(as, &uv->tv); + if (checki32(ofs) && checki32(ofs+4)) { + as->mrm.ofs = (int32_t)ofs; + as->mrm.base = RID_DISPATCH; + as->mrm.idx = RID_NONE; + return; + } +#else as->mrm.ofs = ptr2addr(&uv->tv); as->mrm.base = as->mrm.idx = RID_NONE; return; +#endif } break; default: @@ -205,14 +231,40 @@ static void asm_fuseahuref(ASMState *as, IRRef ref, RegSet allow) static void asm_fusefref(ASMState *as, IRIns *ir, RegSet allow) { lua_assert(ir->o == IR_FLOAD || ir->o == IR_FREF); - as->mrm.ofs = field_ofs[ir->op2]; as->mrm.idx = RID_NONE; + if (ir->op1 == REF_NIL) { +#if LJ_GC64 + as->mrm.ofs = (int32_t)(ir->op2 << 2) - GG_OFS(dispatch); + as->mrm.base = RID_DISPATCH; +#else + as->mrm.ofs = (int32_t)(ir->op2 << 2) + ptr2addr(J2GG(as->J)); + as->mrm.base = RID_NONE; +#endif + return; + } + as->mrm.ofs = field_ofs[ir->op2]; if (irref_isk(ir->op1)) { - as->mrm.ofs += IR(ir->op1)->i; + IRIns *op1 = IR(ir->op1); +#if LJ_GC64 + if (ir->op1 == REF_NIL) { + as->mrm.ofs -= GG_OFS(dispatch); + as->mrm.base = RID_DISPATCH; + return; + } else if (op1->o == IR_KPTR || op1->o == IR_KKPTR) { + intptr_t ofs = dispofs(as, ir_kptr(op1)); + if (checki32(as->mrm.ofs + ofs)) { + as->mrm.ofs += (int32_t)ofs; + as->mrm.base = RID_DISPATCH; + return; + } + } +#else + as->mrm.ofs += op1->i; as->mrm.base = RID_NONE; - } else { - as->mrm.base = (uint8_t)ra_alloc1(as, ir->op1, allow); + return; +#endif } + as->mrm.base = (uint8_t)ra_alloc1(as, ir->op1, allow); } /* Fuse string reference into memory operand. */ @@ -223,7 +275,7 @@ static void asm_fusestrref(ASMState *as, IRIns *ir, RegSet allow) as->mrm.base = as->mrm.idx = RID_NONE; as->mrm.scale = XM_SCALE1; as->mrm.ofs = sizeof(GCstr); - if (irref_isk(ir->op1)) { + if (!LJ_GC64 && irref_isk(ir->op1)) { as->mrm.ofs += IR(ir->op1)->i; } else { Reg r = ra_alloc1(as, ir->op1, allow); @@ -255,10 +307,20 @@ static void asm_fusexref(ASMState *as, IRRef ref, RegSet allow) IRIns *ir = IR(ref); as->mrm.idx = RID_NONE; if (ir->o == IR_KPTR || ir->o == IR_KKPTR) { +#if LJ_GC64 + intptr_t ofs = dispofs(as, ir_kptr(ir)); + if (checki32(ofs)) { + as->mrm.ofs = (int32_t)ofs; + as->mrm.base = RID_DISPATCH; + return; + } + } if (0) { +#else as->mrm.ofs = ir->i; as->mrm.base = RID_NONE; } else if (ir->o == IR_STRREF) { asm_fusestrref(as, ir, allow); +#endif } else { as->mrm.ofs = 0; if (canfuse(as, ir) && ir->o == IR_ADD && ra_noreg(ir->r)) { @@ -301,7 +363,45 @@ static void asm_fusexref(ASMState *as, IRRef ref, RegSet allow) } } -/* Fuse load into memory operand. */ +/* Fuse load of 64 bit IR constant into memory operand. */ +static Reg asm_fuseloadk64(ASMState *as, IRIns *ir) +{ + const uint64_t *k = &ir_k64(ir)->u64; + if (!LJ_GC64 || checki32((intptr_t)k)) { + as->mrm.ofs = ptr2addr(k); + as->mrm.base = RID_NONE; +#if LJ_GC64 + } else if (checki32(dispofs(as, k))) { + as->mrm.ofs = (int32_t)dispofs(as, k); + as->mrm.base = RID_DISPATCH; + } else if (checki32(mcpofs(as, k)) && checki32(mcpofs(as, k+1)) && + checki32(mctopofs(as, k)) && checki32(mctopofs(as, k+1))) { + as->mrm.ofs = (int32_t)mcpofs(as, k); + as->mrm.base = RID_RIP; + } else { + if (ir->i) { + lua_assert(*k == *(uint64_t*)(as->mctop - ir->i)); + } else { + while ((uintptr_t)as->mcbot & 7) *as->mcbot++ = XI_INT3; + *(uint64_t*)as->mcbot = *k; + ir->i = (int32_t)(as->mctop - as->mcbot); + as->mcbot += 8; + as->mclim = as->mcbot + MCLIM_REDZONE; + } + as->mrm.ofs = (int32_t)mcpofs(as, as->mctop - ir->i); + as->mrm.base = RID_RIP; +#endif + } + as->mrm.idx = RID_NONE; + return RID_MRM; +} + +/* Fuse load into memory operand. +** +** Important caveat: this may emit RIP-relative loads! So don't place any +** code emitters between this function and the use of its result. +** The only permitted exception is asm_guardcc(). +*/ static Reg asm_fuseload(ASMState *as, IRRef ref, RegSet allow) { IRIns *ir = IR(ref); @@ -320,26 +420,35 @@ static Reg asm_fuseload(ASMState *as, IRRef ref, RegSet allow) if (ir->o == IR_KNUM) { RegSet avail = as->freeset & ~as->modset & RSET_FPR; lua_assert(allow != RSET_EMPTY); - if (!(avail & (avail-1))) { /* Fuse if less than two regs available. */ - as->mrm.ofs = ptr2addr(ir_knum(ir)); - as->mrm.base = as->mrm.idx = RID_NONE; - return RID_MRM; - } - } else if (ir->o == IR_KINT64) { + if (!(avail & (avail-1))) /* Fuse if less than two regs available. */ + return asm_fuseloadk64(as, ir); + } else if (ref == REF_BASE || ir->o == IR_KINT64) { RegSet avail = as->freeset & ~as->modset & RSET_GPR; lua_assert(allow != RSET_EMPTY); if (!(avail & (avail-1))) { /* Fuse if less than two regs available. */ - as->mrm.ofs = ptr2addr(ir_kint64(ir)); - as->mrm.base = as->mrm.idx = RID_NONE; - return RID_MRM; + if (ref == REF_BASE) { +#if LJ_GC64 + as->mrm.ofs = (int32_t)dispofs(as, &J2G(as->J)->jit_base); + as->mrm.base = RID_DISPATCH; +#else + as->mrm.ofs = ptr2addr(&J2G(as->J)->jit_base); + as->mrm.base = RID_NONE; +#endif + as->mrm.idx = RID_NONE; + return RID_MRM; + } else { + return asm_fuseloadk64(as, ir); + } } } else if (mayfuse(as, ref)) { RegSet xallow = (allow & RSET_GPR) ? allow : RSET_GPR; if (ir->o == IR_SLOAD) { if (!(ir->op2 & (IRSLOAD_PARENT|IRSLOAD_CONVERT)) && - noconflict(as, ref, IR_RETF, 0)) { + noconflict(as, ref, IR_RETF, 0) && + !(LJ_GC64 && irt_isaddr(ir->t))) { as->mrm.base = (uint8_t)ra_alloc1(as, REF_BASE, xallow); - as->mrm.ofs = 8*((int32_t)ir->op1-1) + ((ir->op2&IRSLOAD_FRAME)?4:0); + as->mrm.ofs = 8*((int32_t)ir->op1-1-LJ_FR2) + + (!LJ_FR2 && (ir->op2 & IRSLOAD_FRAME) ? 4 : 0); as->mrm.idx = RID_NONE; return RID_MRM; } @@ -351,7 +460,8 @@ static Reg asm_fuseload(ASMState *as, IRRef ref, RegSet allow) return RID_MRM; } } else if (ir->o == IR_ALOAD || ir->o == IR_HLOAD || ir->o == IR_ULOAD) { - if (noconflict(as, ref, ir->o + IRDELTA_L2S, 0)) { + if (noconflict(as, ref, ir->o + IRDELTA_L2S, 0) && + !(LJ_GC64 && irt_isaddr(ir->t))) { asm_fuseahuref(as, ir->op1, xallow); return RID_MRM; } @@ -364,12 +474,16 @@ static Reg asm_fuseload(ASMState *as, IRRef ref, RegSet allow) asm_fusexref(as, ir->op1, xallow); return RID_MRM; } - } else if (ir->o == IR_VLOAD) { + } else if (ir->o == IR_VLOAD && !(LJ_GC64 && irt_isaddr(ir->t))) { asm_fuseahuref(as, ir->op1, xallow); return RID_MRM; } } - if (!(as->freeset & allow) && !irref_isk(ref) && + if (ir->o == IR_FLOAD && ir->op1 == REF_NIL) { + asm_fusefref(as, ir, RSET_EMPTY); + return RID_MRM; + } + if (!(as->freeset & allow) && !emit_canremat(ref) && (allow == RSET_EMPTY || ra_hasspill(ir->s) || iscrossref(as, ref))) goto fusespill; return ra_allocref(as, ref, allow); @@ -485,8 +599,8 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args) if (r) { /* Argument is in a register. */ if (r < RID_MAX_GPR && ref < ASMREF_TMP1) { #if LJ_64 - if (ir->o == IR_KINT64) - emit_loadu64(as, r, ir_kint64(ir)->u64); + if (LJ_GC64 ? !(ir->o == IR_KINT || ir->o == IR_KNULL) : ir->o == IR_KINT64) + emit_loadu64(as, r, ir_k64(ir)->u64); else #endif emit_loadi(as, r, ir->i); @@ -642,6 +756,9 @@ static void asm_callx(ASMState *as, IRIns *ir) static void asm_retf(ASMState *as, IRIns *ir) { Reg base = ra_alloc1(as, REF_BASE, RSET_GPR); +#if LJ_FR2 + Reg rpc = ra_scratch(as, rset_exclude(RSET_GPR, base)); +#endif void *pc = ir_kptr(IR(ir->op2)); int32_t delta = 1+LJ_FR2+bc_a(*((const BCIns *)pc - 1)); as->topslot -= (BCReg)delta; @@ -650,7 +767,12 @@ static void asm_retf(ASMState *as, IRIns *ir) emit_setgl(as, base, jit_base); emit_addptr(as, base, -8*delta); asm_guardcc(as, CC_NE); +#if LJ_FR2 + emit_rmro(as, XO_CMP, rpc|REX_GC64, base, -8); + emit_loadu64(as, rpc, u64ptr(pc)); +#else emit_gmroi(as, XG_ARITHi(XOg_CMP), base, -4, ptr2addr(pc)); +#endif } /* -- Type conversions ---------------------------------------------------- */ @@ -674,8 +796,9 @@ static void asm_tobit(ASMState *as, IRIns *ir) Reg tmp = ra_noreg(IR(ir->op1)->r) ? ra_alloc1(as, ir->op1, RSET_FPR) : ra_scratch(as, RSET_FPR); - Reg right = asm_fuseload(as, ir->op2, rset_exclude(RSET_FPR, tmp)); + Reg right; emit_rr(as, XO_MOVDto, tmp, dest); + right = asm_fuseload(as, ir->op2, rset_exclude(RSET_FPR, tmp)); emit_mrm(as, XO_ADDSD, tmp, right); ra_left(as, tmp, ir->op1); } @@ -696,13 +819,13 @@ static void asm_conv(ASMState *as, IRIns *ir) if (left == dest) return; /* Avoid the XO_XORPS. */ } else if (LJ_32 && st == IRT_U32) { /* U32 to FP conversion on x86. */ /* number = (2^52+2^51 .. u32) - (2^52+2^51) */ - cTValue *k = lj_ir_k64_find(as->J, U64x(43380000,00000000)); + cTValue *k = &as->J->k64[LJ_K64_TOBIT]; Reg bias = ra_scratch(as, rset_exclude(RSET_FPR, dest)); if (irt_isfloat(ir->t)) emit_rr(as, XO_CVTSD2SS, dest, dest); emit_rr(as, XO_SUBSD, dest, bias); /* Subtract 2^52+2^51 bias. */ emit_rr(as, XO_XORPS, dest, bias); /* Merge bias and integer. */ - emit_loadn(as, bias, k); + emit_rma(as, XO_MOVSD, bias, k); emit_mrm(as, XO_MOVD, dest, asm_fuseload(as, lref, RSET_GPR)); return; } else { /* Integer to FP conversion. */ @@ -711,7 +834,7 @@ static void asm_conv(ASMState *as, IRIns *ir) asm_fuseloadm(as, lref, RSET_GPR, st64); if (LJ_64 && st == IRT_U64) { MCLabel l_end = emit_label(as); - const void *k = lj_ir_k64_find(as->J, U64x(43f00000,00000000)); + cTValue *k = &as->J->k64[LJ_K64_2P64]; emit_rma(as, XO_ADDSD, dest, k); /* Add 2^64 to compensate. */ emit_sjcc(as, CC_NS, l_end); emit_rr(as, XO_TEST, left|REX_64, left); /* Check if u64 >= 2^63. */ @@ -738,23 +861,20 @@ static void asm_conv(ASMState *as, IRIns *ir) emit_gri(as, XG_ARITHi(XOg_ADD), dest, (int32_t)0x80000000); emit_rr(as, op, dest|REX_64, tmp); if (st == IRT_NUM) - emit_rma(as, XO_ADDSD, tmp, lj_ir_k64_find(as->J, - LJ_64 ? U64x(c3f00000,00000000) : U64x(c1e00000,00000000))); + emit_rma(as, XO_ADDSD, tmp, &as->J->k64[LJ_K64_M2P64_31]); else - emit_rma(as, XO_ADDSS, tmp, lj_ir_k64_find(as->J, - LJ_64 ? U64x(00000000,df800000) : U64x(00000000,cf000000))); + emit_rma(as, XO_ADDSS, tmp, &as->J->k32[LJ_K32_M2P64_31]); emit_sjcc(as, CC_NS, l_end); emit_rr(as, XO_TEST, dest|REX_64, dest); /* Check if dest negative. */ emit_rr(as, op, dest|REX_64, tmp); ra_left(as, tmp, lref); } else { - Reg left = asm_fuseload(as, lref, RSET_FPR); if (LJ_64 && irt_isu32(ir->t)) emit_rr(as, XO_MOV, dest, dest); /* Zero hiword. */ emit_mrm(as, op, dest|((LJ_64 && (irt_is64(ir->t) || irt_isu32(ir->t))) ? REX_64 : 0), - left); + asm_fuseload(as, lref, RSET_FPR)); } } } else if (st >= IRT_I8 && st <= IRT_U16) { /* Extend to 32 bit integer. */ @@ -828,8 +948,7 @@ static void asm_conv_fp_int64(ASMState *as, IRIns *ir) if (((ir-1)->op2 & IRCONV_SRCMASK) == IRT_U64) { /* For inputs in [2^63,2^64-1] add 2^64 to compensate. */ MCLabel l_end = emit_label(as); - emit_rma(as, XO_FADDq, XOg_FADDq, - lj_ir_k64_find(as->J, U64x(43f00000,00000000))); + emit_rma(as, XO_FADDq, XOg_FADDq, &as->J->k64[LJ_K64_2P64]); emit_sjcc(as, CC_NS, l_end); emit_rr(as, XO_TEST, hi, hi); /* Check if u64 >= 2^63. */ } else { @@ -869,8 +988,7 @@ static void asm_conv_int64_fp(ASMState *as, IRIns *ir) emit_rmro(as, XO_FISTTPq, XOg_FISTTPq, RID_ESP, 0); else emit_rmro(as, XO_FISTPq, XOg_FISTPq, RID_ESP, 0); - emit_rma(as, XO_FADDq, XOg_FADDq, - lj_ir_k64_find(as->J, U64x(c3f00000,00000000))); + emit_rma(as, XO_FADDq, XOg_FADDq, &as->J->k64[LJ_K64_M2P64]); emit_sjcc(as, CC_NS, l_pop); emit_rr(as, XO_TEST, hi, hi); /* Check if out-of-range (2^63). */ } @@ -934,6 +1052,25 @@ static void asm_tvptr(ASMState *as, Reg dest, IRRef ref) emit_rmro(as, XO_LEA, dest|REX_64, RID_ESP, ra_spill(as, ir)); } else { /* Otherwise use g->tmptv to hold the TValue. */ +#if LJ_GC64 + if (irref_isk(ref)) { + TValue k; + lj_ir_kvalue(as->J->L, &k, ir); + emit_movmroi(as, dest, 4, k.u32.hi); + emit_movmroi(as, dest, 0, k.u32.lo); + } else { + /* TODO: 64 bit store + 32 bit load-modify-store is suboptimal. */ + Reg src = ra_alloc1(as, ref, rset_exclude(RSET_GPR, dest)); + if (irt_is64(ir->t)) { + emit_u32(as, irt_toitype(ir->t) << 15); + emit_rmro(as, XO_ARITHi, XOg_OR, dest, 4); + } else { + /* Currently, no caller passes integers that might end up here. */ + emit_movmroi(as, dest, 4, (irt_toitype(ir->t) << 15)); + } + emit_movtomro(as, REX_64IR(ir, src), dest, 0); + } +#else if (!irref_isk(ref)) { Reg src = ra_alloc1(as, ref, rset_exclude(RSET_GPR, dest)); emit_movtomro(as, REX_64IR(ir, src), dest, 0); @@ -942,6 +1079,7 @@ static void asm_tvptr(ASMState *as, Reg dest, IRRef ref) } if (!(LJ_64 && irt_islightud(ir->t))) emit_movmroi(as, dest, 4, irt_toitype(ir->t)); +#endif emit_loada(as, dest, &J2G(as->J)->tmptv); } } @@ -951,9 +1089,9 @@ static void asm_aref(ASMState *as, IRIns *ir) Reg dest = ra_dest(as, ir, RSET_GPR); asm_fusearef(as, ir, RSET_GPR); if (!(as->mrm.idx == RID_NONE && as->mrm.ofs == 0)) - emit_mrm(as, XO_LEA, dest, RID_MRM); + emit_mrm(as, XO_LEA, dest|REX_GC64, RID_MRM); else if (as->mrm.base != dest) - emit_rr(as, XO_MOV, dest, as->mrm.base); + emit_rr(as, XO_MOV, dest|REX_GC64, as->mrm.base); } /* Inlined hash lookup. Specialized for key type and for const keys. @@ -980,7 +1118,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge) if (!isk) { rset_clear(allow, tab); key = ra_alloc1(as, ir->op2, irt_isnum(kt) ? RSET_FPR : allow); - if (!irt_isstr(kt)) + if (LJ_GC64 || !irt_isstr(kt)) tmp = ra_scratch(as, rset_exclude(allow, key)); } @@ -993,8 +1131,8 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge) /* Follow hash chain until the end. */ l_loop = emit_sjcc_label(as, CC_NZ); - emit_rr(as, XO_TEST, dest, dest); - emit_rmro(as, XO_MOV, dest, dest, offsetof(Node, next)); + emit_rr(as, XO_TEST, dest|REX_GC64, dest); + emit_rmro(as, XO_MOV, dest|REX_GC64, dest, offsetof(Node, next)); l_next = emit_label(as); /* Type and value comparison. */ @@ -1015,7 +1153,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge) emit_rmro(as, XO_UCOMISD, key, dest, offsetof(Node, key.n)); emit_sjcc(as, CC_AE, l_next); /* The type check avoids NaN penalties and complaints from Valgrind. */ -#if LJ_64 +#if LJ_64 && !LJ_GC64 emit_u32(as, LJ_TISNUM); emit_rmro(as, XO_ARITHi, XOg_CMP, dest, offsetof(Node, key.it)); #else @@ -1023,10 +1161,28 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge) emit_rmro(as, XO_ARITHi8, XOg_CMP, dest, offsetof(Node, key.it)); #endif } -#if LJ_64 +#if LJ_64 && !LJ_GC64 } else if (irt_islightud(kt)) { emit_rmro(as, XO_CMP, key|REX_64, dest, offsetof(Node, key.u64)); #endif +#if LJ_GC64 + } else if (irt_isaddr(kt)) { + if (isk) { + TValue k; + k.u64 = ((uint64_t)irt_toitype(irkey->t) << 47) | irkey[1].tv.u64; + emit_gmroi(as, XG_ARITHi(XOg_CMP), dest, offsetof(Node, key.u32.lo), + k.u32.lo); + emit_sjcc(as, CC_NE, l_next); + emit_gmroi(as, XG_ARITHi(XOg_CMP), dest, offsetof(Node, key.u32.hi), + k.u32.hi); + } else { + emit_rmro(as, XO_CMP, tmp|REX_64, dest, offsetof(Node, key.u64)); + } + } else { + lua_assert(irt_ispri(kt) && !irt_isnil(kt)); + emit_u32(as, (irt_toitype(kt)<<15)|0x7fff); + emit_rmro(as, XO_ARITHi, XOg_CMP, dest, offsetof(Node, key.it)); +#else } else { if (!irt_ispri(kt)) { lua_assert(irt_isaddr(kt)); @@ -1040,16 +1196,23 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge) lua_assert(!irt_isnil(kt)); emit_i8(as, irt_toitype(kt)); emit_rmro(as, XO_ARITHi8, XOg_CMP, dest, offsetof(Node, key.it)); +#endif } emit_sfixup(as, l_loop); checkmclim(as); +#if LJ_GC64 + if (!isk && irt_isaddr(kt)) { + emit_rr(as, XO_OR, tmp|REX_64, key); + emit_loadu64(as, tmp, (uint64_t)irt_toitype(kt) << 47); + } +#endif /* Load main position relative to tab->node into dest. */ khash = isk ? ir_khash(irkey) : 1; if (khash == 0) { - emit_rmro(as, XO_MOV, dest, tab, offsetof(GCtab, node)); + emit_rmro(as, XO_MOV, dest|REX_GC64, tab, offsetof(GCtab, node)); } else { - emit_rmro(as, XO_ARITH(XOg_ADD), dest, tab, offsetof(GCtab, node)); + emit_rmro(as, XO_ARITH(XOg_ADD), dest|REX_GC64, tab, offsetof(GCtab,node)); if ((as->flags & JIT_F_PREFER_IMUL)) { emit_i8(as, sizeof(Node)); emit_rr(as, XO_IMULi8, dest, dest); @@ -1084,7 +1247,19 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge) #endif } else { emit_rr(as, XO_MOV, tmp, key); +#if LJ_GC64 + checkmclim(as); + emit_gri(as, XG_ARITHi(XOg_XOR), dest, irt_toitype(kt) << 15); + if ((as->flags & JIT_F_BMI2)) { + emit_i8(as, 32); + emit_mrm(as, XV_RORX|VEX_64, dest, key); + } else { + emit_shifti(as, XOg_SHR|REX_64, dest, 32); + emit_rr(as, XO_MOV, dest|REX_64, key|REX_64); + } +#else emit_rmro(as, XO_LEA, dest, key, HASH_BIAS); +#endif } } } @@ -1104,11 +1279,11 @@ static void asm_hrefk(ASMState *as, IRIns *ir) if (ra_hasreg(dest)) { if (ofs != 0) { if (dest == node && !(as->flags & JIT_F_LEA_AGU)) - emit_gri(as, XG_ARITHi(XOg_ADD), dest, ofs); + emit_gri(as, XG_ARITHi(XOg_ADD), dest|REX_GC64, ofs); else - emit_rmro(as, XO_LEA, dest, node, ofs); + emit_rmro(as, XO_LEA, dest|REX_GC64, node, ofs); } else if (dest != node) { - emit_rr(as, XO_MOV, dest, node); + emit_rr(as, XO_MOV, dest|REX_GC64, node); } } asm_guardcc(as, CC_NE); @@ -1120,13 +1295,24 @@ static void asm_hrefk(ASMState *as, IRIns *ir) lua_assert(irt_isnum(irkey->t) || irt_isgcv(irkey->t)); /* Assumes -0.0 is already canonicalized to +0.0. */ emit_loadu64(as, key, irt_isnum(irkey->t) ? ir_knum(irkey)->u64 : +#if LJ_GC64 + ((uint64_t)irt_toitype(irkey->t) << 47) | + (uint64_t)ir_kgc(irkey)); +#else ((uint64_t)irt_toitype(irkey->t) << 32) | (uint64_t)(uint32_t)ptr2addr(ir_kgc(irkey))); +#endif } else { lua_assert(!irt_isnil(irkey->t)); +#if LJ_GC64 + emit_i32(as, (irt_toitype(irkey->t)<<15)|0x7fff); + emit_rmro(as, XO_ARITHi, XOg_CMP, node, + ofs + (int32_t)offsetof(Node, key.it)); +#else emit_i8(as, irt_toitype(irkey->t)); emit_rmro(as, XO_ARITHi8, XOg_CMP, node, ofs + (int32_t)offsetof(Node, key.it)); +#endif } #else l_exit = emit_label(as); @@ -1157,25 +1343,25 @@ static void asm_hrefk(ASMState *as, IRIns *ir) static void asm_uref(ASMState *as, IRIns *ir) { - /* NYI: Check that UREFO is still open and not aliasing a slot. */ Reg dest = ra_dest(as, ir, RSET_GPR); if (irref_isk(ir->op1)) { GCfunc *fn = ir_kfunc(IR(ir->op1)); MRef *v = &gcref(fn->l.uvptr[(ir->op2 >> 8)])->uv.v; - emit_rma(as, XO_MOV, dest, v); + emit_rma(as, XO_MOV, dest|REX_GC64, v); } else { Reg uv = ra_scratch(as, RSET_GPR); Reg func = ra_alloc1(as, ir->op1, RSET_GPR); if (ir->o == IR_UREFC) { - emit_rmro(as, XO_LEA, dest, uv, offsetof(GCupval, tv)); + emit_rmro(as, XO_LEA, dest|REX_GC64, uv, offsetof(GCupval, tv)); asm_guardcc(as, CC_NE); emit_i8(as, 1); emit_rmro(as, XO_ARITHib, XOg_CMP, uv, offsetof(GCupval, closed)); } else { - emit_rmro(as, XO_MOV, dest, uv, offsetof(GCupval, v)); + emit_rmro(as, XO_MOV, dest|REX_GC64, uv, offsetof(GCupval, v)); } - emit_rmro(as, XO_MOV, uv, func, - (int32_t)offsetof(GCfuncL, uvptr) + 4*(int32_t)(ir->op2 >> 8)); + emit_rmro(as, XO_MOV, uv|REX_GC64, func, + (int32_t)offsetof(GCfuncL, uvptr) + + (int32_t)sizeof(MRef) * (int32_t)(ir->op2 >> 8)); } } @@ -1193,9 +1379,9 @@ static void asm_strref(ASMState *as, IRIns *ir) if (as->mrm.base == RID_NONE) emit_loadi(as, dest, as->mrm.ofs); else if (as->mrm.base == dest && as->mrm.idx == RID_NONE) - emit_gri(as, XG_ARITHi(XOg_ADD), dest, as->mrm.ofs); + emit_gri(as, XG_ARITHi(XOg_ADD), dest|REX_GC64, as->mrm.ofs); else - emit_mrm(as, XO_LEA, dest, RID_MRM); + emit_mrm(as, XO_LEA, dest|REX_GC64, RID_MRM); } /* -- Loads and stores ---------------------------------------------------- */ @@ -1264,7 +1450,7 @@ static void asm_fxstore(ASMState *as, IRIns *ir) case IRT_I16: case IRT_U16: xo = XO_MOVtow; break; case IRT_NUM: xo = XO_MOVSDto; break; case IRT_FLOAT: xo = XO_MOVSSto; break; -#if LJ_64 +#if LJ_64 && !LJ_GC64 case IRT_LIGHTUD: lua_assert(0); /* NYI: mask 64 bit lightuserdata. */ #endif default: @@ -1296,7 +1482,7 @@ static void asm_fxstore(ASMState *as, IRIns *ir) #define asm_fstore(as, ir) asm_fxstore(as, ir) #define asm_xstore(as, ir) asm_fxstore(as, ir) -#if LJ_64 +#if LJ_64 && !LJ_GC64 static Reg asm_load_lightud64(ASMState *as, IRIns *ir, int typecheck) { if (ra_used(ir) || typecheck) { @@ -1318,9 +1504,12 @@ static Reg asm_load_lightud64(ASMState *as, IRIns *ir, int typecheck) static void asm_ahuvload(ASMState *as, IRIns *ir) { +#if LJ_GC64 + Reg tmp = RID_NONE; +#endif lua_assert(irt_isnum(ir->t) || irt_ispri(ir->t) || irt_isaddr(ir->t) || (LJ_DUALNUM && irt_isint(ir->t))); -#if LJ_64 +#if LJ_64 && !LJ_GC64 if (irt_islightud(ir->t)) { Reg dest = asm_load_lightud64(as, ir, 1); if (ra_hasreg(dest)) { @@ -1334,20 +1523,64 @@ static void asm_ahuvload(ASMState *as, IRIns *ir) RegSet allow = irt_isnum(ir->t) ? RSET_FPR : RSET_GPR; Reg dest = ra_dest(as, ir, allow); asm_fuseahuref(as, ir->op1, RSET_GPR); +#if LJ_GC64 + if (irt_isaddr(ir->t)) { + emit_shifti(as, XOg_SHR|REX_64, dest, 17); + asm_guardcc(as, CC_NE); + emit_i8(as, irt_toitype(ir->t)); + emit_rr(as, XO_ARITHi8, XOg_CMP, dest); + emit_i8(as, XI_O16); + if ((as->flags & JIT_F_BMI2)) { + emit_i8(as, 47); + emit_mrm(as, XV_RORX|VEX_64, dest, RID_MRM); + } else { + emit_shifti(as, XOg_ROR|REX_64, dest, 47); + emit_mrm(as, XO_MOV, dest|REX_64, RID_MRM); + } + return; + } else +#endif emit_mrm(as, dest < RID_MAX_GPR ? XO_MOV : XO_MOVSD, dest, RID_MRM); } else { - asm_fuseahuref(as, ir->op1, RSET_GPR); + RegSet gpr = RSET_GPR; +#if LJ_GC64 + if (irt_isaddr(ir->t)) { + tmp = ra_scratch(as, RSET_GPR); + gpr = rset_exclude(gpr, tmp); + } +#endif + asm_fuseahuref(as, ir->op1, gpr); } /* Always do the type check, even if the load result is unused. */ as->mrm.ofs += 4; asm_guardcc(as, irt_isnum(ir->t) ? CC_AE : CC_NE); if (LJ_64 && irt_type(ir->t) >= IRT_NUM) { lua_assert(irt_isinteger(ir->t) || irt_isnum(ir->t)); +#if LJ_GC64 + emit_u32(as, LJ_TISNUM << 15); +#else emit_u32(as, LJ_TISNUM); +#endif + emit_mrm(as, XO_ARITHi, XOg_CMP, RID_MRM); +#if LJ_GC64 + } else if (irt_isaddr(ir->t)) { + as->mrm.ofs -= 4; + emit_i8(as, irt_toitype(ir->t)); + emit_mrm(as, XO_ARITHi8, XOg_CMP, tmp); + emit_shifti(as, XOg_SAR|REX_64, tmp, 47); + emit_mrm(as, XO_MOV, tmp|REX_64, RID_MRM); + } else if (irt_isnil(ir->t)) { + as->mrm.ofs -= 4; + emit_i8(as, -1); + emit_mrm(as, XO_ARITHi8, XOg_CMP|REX_64, RID_MRM); + } else { + emit_u32(as, (irt_toitype(ir->t) << 15) | 0x7fff); emit_mrm(as, XO_ARITHi, XOg_CMP, RID_MRM); +#else } else { emit_i8(as, irt_toitype(ir->t)); emit_mrm(as, XO_ARITHi8, XOg_CMP, RID_MRM); +#endif } } @@ -1359,12 +1592,28 @@ static void asm_ahustore(ASMState *as, IRIns *ir) Reg src = ra_alloc1(as, ir->op2, RSET_FPR); asm_fuseahuref(as, ir->op1, RSET_GPR); emit_mrm(as, XO_MOVSDto, src, RID_MRM); -#if LJ_64 +#if LJ_64 && !LJ_GC64 } else if (irt_islightud(ir->t)) { Reg src = ra_alloc1(as, ir->op2, RSET_GPR); asm_fuseahuref(as, ir->op1, rset_exclude(RSET_GPR, src)); emit_mrm(as, XO_MOVto, src|REX_64, RID_MRM); #endif +#if LJ_GC64 + } else if (irref_isk(ir->op2)) { + TValue k; + lj_ir_kvalue(as->J->L, &k, IR(ir->op2)); + asm_fuseahuref(as, ir->op1, RSET_GPR); + if (tvisnil(&k)) { + emit_i32(as, -1); + emit_mrm(as, XO_MOVmi, REX_64, RID_MRM); + } else { + emit_u32(as, k.u32.lo); + emit_mrm(as, XO_MOVmi, 0, RID_MRM); + as->mrm.ofs += 4; + emit_u32(as, k.u32.hi); + emit_mrm(as, XO_MOVmi, 0, RID_MRM); + } +#endif } else { IRIns *irr = IR(ir->op2); RegSet allow = RSET_GPR; @@ -1375,6 +1624,17 @@ static void asm_ahustore(ASMState *as, IRIns *ir) } asm_fuseahuref(as, ir->op1, allow); if (ra_hasreg(src)) { +#if LJ_GC64 + if (!(LJ_DUALNUM && irt_isinteger(ir->t))) { + /* TODO: 64 bit store + 32 bit load-modify-store is suboptimal. */ + as->mrm.ofs += 4; + emit_u32(as, irt_toitype(ir->t) << 15); + emit_mrm(as, XO_ARITHi, XOg_OR, RID_MRM); + as->mrm.ofs -= 4; + emit_mrm(as, XO_MOVto, src|REX_64, RID_MRM); + return; + } +#endif emit_mrm(as, XO_MOVto, src, RID_MRM); } else if (!irt_ispri(irr->t)) { lua_assert(irt_isaddr(ir->t) || (LJ_DUALNUM && irt_isinteger(ir->t))); @@ -1382,14 +1642,20 @@ static void asm_ahustore(ASMState *as, IRIns *ir) emit_mrm(as, XO_MOVmi, 0, RID_MRM); } as->mrm.ofs += 4; +#if LJ_GC64 + lua_assert(LJ_DUALNUM && irt_isinteger(ir->t)); + emit_i32(as, LJ_TNUMX << 15); +#else emit_i32(as, (int32_t)irt_toitype(ir->t)); +#endif emit_mrm(as, XO_MOVmi, 0, RID_MRM); } } static void asm_sload(ASMState *as, IRIns *ir) { - int32_t ofs = 8*((int32_t)ir->op1-1) + ((ir->op2 & IRSLOAD_FRAME) ? 4 : 0); + int32_t ofs = 8*((int32_t)ir->op1-1-LJ_FR2) + + (!LJ_FR2 && (ir->op2 & IRSLOAD_FRAME) ? 4 : 0); IRType1 t = ir->t; Reg base; lua_assert(!(ir->op2 & IRSLOAD_PARENT)); /* Handled by asm_head_side(). */ @@ -1402,7 +1668,7 @@ static void asm_sload(ASMState *as, IRIns *ir) base = ra_alloc1(as, REF_BASE, RSET_GPR); emit_rmro(as, XO_MOVSD, left, base, ofs); t.irt = IRT_NUM; /* Continue with a regular number type check. */ -#if LJ_64 +#if LJ_64 && !LJ_GC64 } else if (irt_islightud(t)) { Reg dest = asm_load_lightud64(as, ir, (ir->op2 & IRSLOAD_TYPECHECK)); if (ra_hasreg(dest)) { @@ -1420,6 +1686,36 @@ static void asm_sload(ASMState *as, IRIns *ir) t.irt = irt_isint(t) ? IRT_NUM : IRT_INT; /* Check for original type. */ emit_rmro(as, irt_isint(t) ? XO_CVTSI2SD : XO_CVTTSD2SI, dest, base, ofs); } else { +#if LJ_GC64 + if (irt_isaddr(t)) { + /* LJ_GC64 type check + tag removal without BMI2 and with BMI2: + ** + ** mov r64, [addr] rorx r64, [addr], 47 + ** ror r64, 47 + ** cmp r16, itype cmp r16, itype + ** jne ->exit jne ->exit + ** shr r64, 16 shr r64, 16 + */ + emit_shifti(as, XOg_SHR|REX_64, dest, 17); + if ((ir->op2 & IRSLOAD_TYPECHECK)) { + asm_guardcc(as, CC_NE); + emit_i8(as, irt_toitype(t)); + emit_rr(as, XO_ARITHi8, XOg_CMP, dest); + emit_i8(as, XI_O16); + } + if ((as->flags & JIT_F_BMI2)) { + emit_i8(as, 47); + emit_rmro(as, XV_RORX|VEX_64, dest, base, ofs); + } else { + if ((ir->op2 & IRSLOAD_TYPECHECK)) + emit_shifti(as, XOg_ROR|REX_64, dest, 47); + else + emit_shifti(as, XOg_SHL|REX_64, dest, 17); + emit_rmro(as, XO_MOV, dest|REX_64, base, ofs); + } + return; + } else +#endif emit_rmro(as, irt_isnum(t) ? XO_MOVSD : XO_MOV, dest, base, ofs); } } else { @@ -1432,11 +1728,42 @@ static void asm_sload(ASMState *as, IRIns *ir) asm_guardcc(as, irt_isnum(t) ? CC_AE : CC_NE); if (LJ_64 && irt_type(t) >= IRT_NUM) { lua_assert(irt_isinteger(t) || irt_isnum(t)); +#if LJ_GC64 + emit_u32(as, LJ_TISNUM << 15); +#else emit_u32(as, LJ_TISNUM); +#endif + emit_rmro(as, XO_ARITHi, XOg_CMP, base, ofs+4); +#if LJ_GC64 + } else if (irt_isnil(t)) { + /* LJ_GC64 type check for nil: + ** + ** cmp qword [addr], -1 + ** jne ->exit + */ + emit_i8(as, -1); + emit_rmro(as, XO_ARITHi8, XOg_CMP|REX_64, base, ofs); + } else if (irt_ispri(t)) { + emit_u32(as, (irt_toitype(t) << 15) | 0x7fff); emit_rmro(as, XO_ARITHi, XOg_CMP, base, ofs+4); } else { + /* LJ_GC64 type check only: + ** + ** mov r64, [addr] + ** sar r64, 47 + ** cmp r32, itype + ** jne ->exit + */ + Reg tmp = ra_scratch(as, rset_exclude(RSET_GPR, base)); + emit_i8(as, irt_toitype(t)); + emit_rr(as, XO_ARITHi8, XOg_CMP, tmp); + emit_shifti(as, XOg_SAR|REX_64, tmp, 47); + emit_rmro(as, XO_MOV, tmp|REX_64, base, ofs+4); +#else + } else { emit_i8(as, irt_toitype(t)); emit_rmro(as, XO_ARITHi8, XOg_CMP, base, ofs+4); +#endif } } } @@ -1464,8 +1791,9 @@ static void asm_cnew(ASMState *as, IRIns *ir) Reg r64 = sz == 8 ? REX_64 : 0; if (irref_isk(ir->op2)) { IRIns *irk = IR(ir->op2); - uint64_t k = irk->o == IR_KINT64 ? ir_k64(irk)->u64 : - (uint64_t)(uint32_t)irk->i; + uint64_t k = (irk->o == IR_KINT64 || + (LJ_GC64 && (irk->o == IR_KPTR || irk->o == IR_KKPTR))) ? + ir_k64(irk)->u64 : (uint64_t)(uint32_t)irk->i; if (sz == 4 || checki32((int64_t)k)) { emit_i32(as, (int32_t)k); emit_rmro(as, XO_MOVmi, r64, RID_RET, sizeof(GCcdata)); @@ -1530,7 +1858,7 @@ static void asm_tbar(ASMState *as, IRIns *ir) Reg tab = ra_alloc1(as, ir->op1, RSET_GPR); Reg tmp = ra_scratch(as, rset_exclude(RSET_GPR, tab)); MCLabel l_end = emit_label(as); - emit_movtomro(as, tmp, tab, offsetof(GCtab, gclist)); + emit_movtomro(as, tmp|REX_GC64, tab, offsetof(GCtab, gclist)); emit_setgl(as, tab, gc.grayagain); emit_getgl(as, tmp, gc.grayagain); emit_i8(as, ~LJ_GC_BLACK); @@ -1956,7 +2284,7 @@ static void asm_bswap(ASMState *as, IRIns *ir) #define asm_bor(as, ir) asm_intarith(as, ir, XOg_OR) #define asm_bxor(as, ir) asm_intarith(as, ir, XOg_XOR) -static void asm_bitshift(ASMState *as, IRIns *ir, x86Shift xs) +static void asm_bitshift(ASMState *as, IRIns *ir, x86Shift xs, x86Op xv) { IRRef rref = ir->op2; IRIns *irr = IR(rref); @@ -1965,11 +2293,27 @@ static void asm_bitshift(ASMState *as, IRIns *ir, x86Shift xs) int shift; dest = ra_dest(as, ir, RSET_GPR); shift = irr->i & (irt_is64(ir->t) ? 63 : 31); + if (!xv && shift && (as->flags & JIT_F_BMI2)) { + Reg left = asm_fuseloadm(as, ir->op1, RSET_GPR, irt_is64(ir->t)); + if (left != dest) { /* BMI2 rotate right by constant. */ + emit_i8(as, xs == XOg_ROL ? -shift : shift); + emit_mrm(as, VEX_64IR(ir, XV_RORX), dest, left); + return; + } + } switch (shift) { case 0: break; case 1: emit_rr(as, XO_SHIFT1, REX_64IR(ir, xs), dest); break; default: emit_shifti(as, REX_64IR(ir, xs), dest, shift); break; } + } else if ((as->flags & JIT_F_BMI2) && xv) { /* BMI2 variable shifts. */ + Reg left, right; + dest = ra_dest(as, ir, RSET_GPR); + right = ra_alloc1(as, rref, RSET_GPR); + left = asm_fuseloadm(as, ir->op1, rset_exclude(RSET_GPR, right), + irt_is64(ir->t)); + emit_mrm(as, VEX_64IR(ir, xv) ^ (right << 19), dest, left); + return; } else { /* Variable shifts implicitly use register cl (i.e. ecx). */ Reg right; dest = ra_dest(as, ir, rset_exclude(RSET_GPR, RID_ECX)); @@ -1995,11 +2339,11 @@ static void asm_bitshift(ASMState *as, IRIns *ir, x86Shift xs) */ } -#define asm_bshl(as, ir) asm_bitshift(as, ir, XOg_SHL) -#define asm_bshr(as, ir) asm_bitshift(as, ir, XOg_SHR) -#define asm_bsar(as, ir) asm_bitshift(as, ir, XOg_SAR) -#define asm_brol(as, ir) asm_bitshift(as, ir, XOg_ROL) -#define asm_bror(as, ir) asm_bitshift(as, ir, XOg_ROR) +#define asm_bshl(as, ir) asm_bitshift(as, ir, XOg_SHL, XV_SHLX) +#define asm_bshr(as, ir) asm_bitshift(as, ir, XOg_SHR, XV_SHRX) +#define asm_bsar(as, ir) asm_bitshift(as, ir, XOg_SAR, XV_SARX) +#define asm_brol(as, ir) asm_bitshift(as, ir, XOg_ROL, 0) +#define asm_bror(as, ir) asm_bitshift(as, ir, XOg_ROR, 0) /* -- Comparisons --------------------------------------------------------- */ @@ -2050,7 +2394,6 @@ static void asm_comp(ASMState *as, IRIns *ir) cc ^= (VCC_PS|(5<<4)); /* A <-> B, AE <-> BE, PS <-> none */ } left = ra_alloc1(as, lref, RSET_FPR); - right = asm_fuseload(as, rref, rset_exclude(RSET_FPR, left)); l_around = emit_label(as); asm_guardcc(as, cc >> 4); if (cc & VCC_P) { /* Extra CC_P branch required? */ @@ -2067,6 +2410,7 @@ static void asm_comp(ASMState *as, IRIns *ir) emit_jcc(as, CC_P, as->mcp); } } + right = asm_fuseload(as, rref, rset_exclude(RSET_FPR, left)); emit_mrm(as, XO_UCOMISD, left, right); } else { IRRef lref = ir->op1, rref = ir->op2; @@ -2343,13 +2687,18 @@ static void asm_stack_check(ASMState *as, BCReg topslot, emit_rmro(as, XO_MOV, r|REX_64, RID_ESP, 0); else ra_modified(as, r); - emit_gri(as, XG_ARITHi(XOg_CMP), r, (int32_t)(8*topslot)); + emit_gri(as, XG_ARITHi(XOg_CMP), r|REX_GC64, (int32_t)(8*topslot)); if (ra_hasreg(pbase) && pbase != r) - emit_rr(as, XO_ARITH(XOg_SUB), r, pbase); + emit_rr(as, XO_ARITH(XOg_SUB), r|REX_GC64, pbase); else +#if LJ_GC64 + emit_rmro(as, XO_ARITH(XOg_SUB), r|REX_64, RID_DISPATCH, + (int32_t)dispofs(as, &J2G(as->J)->jit_base)); +#else emit_rmro(as, XO_ARITH(XOg_SUB), r, RID_NONE, ptr2addr(&J2G(as->J)->jit_base)); - emit_rmro(as, XO_MOV, r, r, offsetof(lua_State, maxstack)); +#endif + emit_rmro(as, XO_MOV, r|REX_GC64, r, offsetof(lua_State, maxstack)); emit_getgl(as, r, cur_L); if (allow == RSET_EMPTY) /* Spill temp. register. */ emit_rmro(as, XO_MOVto, r|REX_64, RID_ESP, 0); @@ -2359,13 +2708,15 @@ static void asm_stack_check(ASMState *as, BCReg topslot, static void asm_stack_restore(ASMState *as, SnapShot *snap) { SnapEntry *map = &as->T->snapmap[snap->mapofs]; - SnapEntry *flinks = &as->T->snapmap[snap_nextofs(as->T, snap)-1]; +#if !LJ_FR2 || defined(LUA_USE_ASSERT) + SnapEntry *flinks = &as->T->snapmap[snap_nextofs(as->T, snap)-1-LJ_FR2]; +#endif MSize n, nent = snap->nent; /* Store the value of all modified slots to the Lua stack. */ for (n = 0; n < nent; n++) { SnapEntry sn = map[n]; BCReg s = snap_slot(sn); - int32_t ofs = 8*((int32_t)s-1); + int32_t ofs = 8*((int32_t)s-1-LJ_FR2); IRRef ref = snap_ref(sn); IRIns *ir = IR(ref); if ((sn & SNAP_NORESTORE)) @@ -2378,16 +2729,44 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap) (LJ_DUALNUM && irt_isinteger(ir->t))); if (!irref_isk(ref)) { Reg src = ra_alloc1(as, ref, rset_exclude(RSET_GPR, RID_BASE)); +#if LJ_GC64 + if (irt_is64(ir->t)) { + /* TODO: 64 bit store + 32 bit load-modify-store is suboptimal. */ + emit_u32(as, irt_toitype(ir->t) << 15); + emit_rmro(as, XO_ARITHi, XOg_OR, RID_BASE, ofs+4); + } else if (LJ_DUALNUM && irt_isinteger(ir->t)) { + emit_movmroi(as, RID_BASE, ofs+4, LJ_TISNUM << 15); + } else { + emit_movmroi(as, RID_BASE, ofs+4, (irt_toitype(ir->t)<<15)|0x7fff); + } +#endif emit_movtomro(as, REX_64IR(ir, src), RID_BASE, ofs); +#if LJ_GC64 + } else { + TValue k; + lj_ir_kvalue(as->J->L, &k, ir); + if (tvisnil(&k)) { + emit_i32(as, -1); + emit_rmro(as, XO_MOVmi, REX_64, RID_BASE, ofs); + } else { + emit_movmroi(as, RID_BASE, ofs+4, k.u32.hi); + emit_movmroi(as, RID_BASE, ofs, k.u32.lo); + } +#else } else if (!irt_ispri(ir->t)) { emit_movmroi(as, RID_BASE, ofs, ir->i); +#endif } if ((sn & (SNAP_CONT|SNAP_FRAME))) { +#if !LJ_FR2 if (s != 0) /* Do not overwrite link to previous frame. */ emit_movmroi(as, RID_BASE, ofs+4, (int32_t)(*flinks--)); +#endif +#if !LJ_GC64 } else { if (!(LJ_64 && irt_islightud(ir->t))) emit_movmroi(as, RID_BASE, ofs+4, irt_toitype(ir->t)); +#endif } } checkmclim(as); @@ -2413,11 +2792,15 @@ static void asm_gc_check(ASMState *as) args[1] = ASMREF_TMP2; /* MSize steps */ asm_gencall(as, ci, args); tmp = ra_releasetmp(as, ASMREF_TMP1); +#if LJ_GC64 + emit_rmro(as, XO_LEA, tmp|REX_64, RID_DISPATCH, GG_DISP2G); +#else emit_loada(as, tmp, J2G(as->J)); +#endif emit_loadi(as, ra_releasetmp(as, ASMREF_TMP2), as->gcsteps); /* Jump around GC step if GC total < GC threshold. */ emit_sjcc(as, CC_B, l_end); - emit_opgl(as, XO_ARITH(XOg_CMP), tmp, gc.threshold); + emit_opgl(as, XO_ARITH(XOg_CMP), tmp|REX_GC64, gc.threshold); emit_getgl(as, tmp, gc.total); as->gcsteps = 0; checkmclim(as); @@ -2482,7 +2865,7 @@ static void asm_head_root_base(ASMState *as) if (rset_test(as->modset, r) || irt_ismarked(ir->t)) ir->r = RID_INIT; /* No inheritance for modified BASE register. */ if (r != RID_BASE) - emit_rr(as, XO_MOV, r, RID_BASE); + emit_rr(as, XO_MOV, r|REX_GC64, RID_BASE); } } @@ -2498,8 +2881,9 @@ static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow) if (irp->r == r) { rset_clear(allow, r); /* Mark same BASE register as coalesced. */ } else if (ra_hasreg(irp->r) && rset_test(as->freeset, irp->r)) { + /* Move from coalesced parent reg. */ rset_clear(allow, irp->r); - emit_rr(as, XO_MOV, r, irp->r); /* Move from coalesced parent reg. */ + emit_rr(as, XO_MOV, r|REX_GC64, irp->r); } else { emit_getgl(as, r, jit_base); /* Otherwise reload BASE. */ } @@ -2600,10 +2984,111 @@ static Reg asm_setup_call_slots(ASMState *as, IRIns *ir, const CCallInfo *ci) static void asm_setup_target(ASMState *as) { asm_exitstub_setup(as, as->T->nsnap); + as->mrm.base = 0; } /* -- Trace patching ------------------------------------------------------ */ +static const uint8_t map_op1[256] = { +0x92,0x92,0x92,0x92,0x52,0x45,0x51,0x51,0x92,0x92,0x92,0x92,0x52,0x45,0x51,0x20, +0x92,0x92,0x92,0x92,0x52,0x45,0x51,0x51,0x92,0x92,0x92,0x92,0x52,0x45,0x51,0x51, +0x92,0x92,0x92,0x92,0x52,0x45,0x10,0x51,0x92,0x92,0x92,0x92,0x52,0x45,0x10,0x51, +0x92,0x92,0x92,0x92,0x52,0x45,0x10,0x51,0x92,0x92,0x92,0x92,0x52,0x45,0x10,0x51, +#if LJ_64 +0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14, +#else +0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51, +#endif +0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51, +0x51,0x51,0x92,0x92,0x10,0x10,0x12,0x11,0x45,0x86,0x52,0x93,0x51,0x51,0x51,0x51, +0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52, +0x93,0x86,0x93,0x93,0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92, +0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x47,0x51,0x51,0x51,0x51,0x51, +#if LJ_64 +0x59,0x59,0x59,0x59,0x51,0x51,0x51,0x51,0x52,0x45,0x51,0x51,0x51,0x51,0x51,0x51, +#else +0x55,0x55,0x55,0x55,0x51,0x51,0x51,0x51,0x52,0x45,0x51,0x51,0x51,0x51,0x51,0x51, +#endif +0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05, +0x93,0x93,0x53,0x51,0x70,0x71,0x93,0x86,0x54,0x51,0x53,0x51,0x51,0x52,0x51,0x51, +0x92,0x92,0x92,0x92,0x52,0x52,0x51,0x51,0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92, +0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x45,0x45,0x47,0x52,0x51,0x51,0x51,0x51, +0x10,0x51,0x10,0x10,0x51,0x51,0x63,0x66,0x51,0x51,0x51,0x51,0x51,0x51,0x92,0x92 +}; + +static const uint8_t map_op2[256] = { +0x93,0x93,0x93,0x93,0x52,0x52,0x52,0x52,0x52,0x52,0x51,0x52,0x51,0x93,0x52,0x94, +0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93, +0x53,0x53,0x53,0x53,0x53,0x53,0x53,0x53,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93, +0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x34,0x51,0x35,0x51,0x51,0x51,0x51,0x51, +0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93, +0x53,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93, +0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93, +0x94,0x54,0x54,0x54,0x93,0x93,0x93,0x52,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93, +0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46, +0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93, +0x52,0x52,0x52,0x93,0x94,0x93,0x51,0x51,0x52,0x52,0x52,0x93,0x94,0x93,0x93,0x93, +0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x94,0x93,0x93,0x93,0x93,0x93, +0x93,0x93,0x94,0x93,0x94,0x94,0x94,0x93,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52, +0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93, +0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93, +0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x52 +}; + +static uint32_t asm_x86_inslen(const uint8_t* p) +{ + uint32_t result = 0; + uint32_t prefixes = 0; + uint32_t x = map_op1[*p]; + for (;;) { + switch (x >> 4) { + case 0: return result + x + (prefixes & 4); + case 1: prefixes |= x; x = map_op1[*++p]; result++; break; + case 2: x = map_op2[*++p]; break; + case 3: p++; goto mrm; + case 4: result -= (prefixes & 2); /* fallthrough */ + case 5: return result + (x & 15); + case 6: /* Group 3. */ + if (p[1] & 0x38) x = 2; + else if ((prefixes & 2) && (x == 0x66)) x = 4; + goto mrm; + case 7: /* VEX c4/c5. */ + if (LJ_32 && p[1] < 0xc0) { + x = 2; + goto mrm; + } + if (x == 0x70) { + x = *++p & 0x1f; + result++; + if (x >= 2) { + p += 2; + result += 2; + goto mrm; + } + } + p++; + result++; + x = map_op2[*++p]; + break; + case 8: result -= (prefixes & 2); /* fallthrough */ + case 9: mrm: /* ModR/M and possibly SIB. */ + result += (x & 15); + x = *++p; + switch (x >> 6) { + case 0: if ((x & 7) == 5) return result + 4; break; + case 1: result++; break; + case 2: result += 4; break; + case 3: return result; + } + if ((x & 7) == 4) { + result++; + if (x < 0x40 && (p[1] & 7) == 5) result += 4; + } + return result; + } + } +} + /* Patch exit jumps of existing machine code to a new target. */ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target) { @@ -2612,22 +3097,23 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target) MSize len = T->szmcode; MCode *px = exitstub_addr(J, exitno) - 6; MCode *pe = p+len-6; - uint32_t stateaddr = u32ptr(&J2G(J)->vmstate); +#if LJ_GC64 + uint32_t statei = (uint32_t)(GG_OFS(g.vmstate) - GG_OFS(dispatch)); +#else + uint32_t statei = u32ptr(&J2G(J)->vmstate); +#endif if (len > 5 && p[len-5] == XI_JMP && p+len-6 + *(int32_t *)(p+len-4) == px) *(int32_t *)(p+len-4) = jmprel(p+len, target); /* Do not patch parent exit for a stack check. Skip beyond vmstate update. */ - for (; p < pe; p++) - if (*(uint32_t *)(p+(LJ_64 ? 3 : 2)) == stateaddr && p[0] == XI_MOVmi) { - p += LJ_64 ? 11 : 10; + for (; p < pe; p += asm_x86_inslen(p)) { + intptr_t ofs = LJ_GC64 ? (p[0] & 0xf0) == 0x40 : LJ_64; + if (*(uint32_t *)(p+2+ofs) == statei && p[ofs+LJ_GC64-LJ_64] == XI_MOVmi) break; - } + } lua_assert(p < pe); - for (; p < pe; p++) { - if ((*(uint16_t *)p & 0xf0ff) == 0x800f && p + *(int32_t *)(p+2) == px) { + for (; p < pe; p += asm_x86_inslen(p)) + if ((*(uint16_t *)p & 0xf0ff) == 0x800f && p + *(int32_t *)(p+2) == px) *(int32_t *)(p+2) = jmprel(p+6, target); - p += 5; - } - } lj_mcode_sync(T->mcode, T->mcode + T->szmcode); lj_mcode_patch(J, mcarea, 1); } diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_bc.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_bc.c index f038769c220..a597692cab4 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_bc.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_bc.c @@ -1,6 +1,6 @@ /* ** Bytecode instruction modes. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_bc_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_bc.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_bc.h index 78826068693..69a45f281e9 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_bc.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_bc.h @@ -1,6 +1,6 @@ /* ** Bytecode instruction format. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_BC_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_bcdump.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_bcdump.h index 3752f151249..fdfc6ec0c6e 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_bcdump.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_bcdump.h @@ -1,6 +1,6 @@ /* ** Bytecode dump definitions. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_BCDUMP_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_bcread.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_bcread.c index 455c9d8242d..48c5e7c7f5a 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_bcread.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_bcread.c @@ -1,6 +1,6 @@ /* ** Bytecode reader. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_bcread_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_bcwrite.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_bcwrite.c index 4728305932a..5e05caeaf5d 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_bcwrite.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_bcwrite.c @@ -1,6 +1,6 @@ /* ** Bytecode writer. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_bcwrite_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_buf.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_buf.c index 6251b075af2..0dfe7f98075 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_buf.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_buf.c @@ -1,6 +1,6 @@ /* ** Buffer handling. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_buf_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_buf.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_buf.h index fb632ee231c..a4051694445 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_buf.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_buf.h @@ -1,6 +1,6 @@ /* ** Buffer handling. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_BUF_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_carith.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_carith.c index 6102dcaa776..218abd260f4 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_carith.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_carith.c @@ -1,6 +1,6 @@ /* ** C data arithmetic. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #include "lj_obj.h" diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_carith.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_carith.h index b3bdff8a761..67d976bf0c0 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_carith.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_carith.h @@ -1,6 +1,6 @@ /* ** C data arithmetic. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_CARITH_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_ccall.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_ccall.c index eb7c1ee0d58..5c252e5b683 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_ccall.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_ccall.c @@ -1,6 +1,6 @@ /* ** FFI C call handling. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #include "lj_obj.h" @@ -301,7 +301,7 @@ unsigned int cl = ccall_classify_struct(cts, ctr); \ if ((cl & 4)) { /* Combine float HFA from separate registers. */ \ CTSize i = (cl >> 8) - 1; \ - do { ((uint32_t *)dp)[i] = cc->fpr[i].u32; } while (i--); \ + do { ((uint32_t *)dp)[i] = cc->fpr[i].lo; } while (i--); \ } else { \ if (cl > 1) sp = (uint8_t *)&cc->fpr[0]; \ memcpy(dp, sp, ctr->size); \ @@ -331,7 +331,7 @@ #define CCALL_HANDLE_COMPLEXARG \ /* Pass complex by value in separate (!) FPRs or on stack. */ \ - isfp = ctr->size == 2*sizeof(float) ? 2 : 1; + isfp = sz == 2*sizeof(float) ? 2 : 1; #define CCALL_HANDLE_REGARG \ if (LJ_TARGET_IOS && isva) { \ @@ -359,6 +359,13 @@ } \ } +#if LJ_BE +#define CCALL_HANDLE_RET \ + if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \ + sp = (uint8_t *)&cc->fpr[0].f; +#endif + + #elif LJ_TARGET_PPC /* -- PPC calling conventions --------------------------------------------- */ @@ -407,8 +414,8 @@ if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \ ctr = ctype_get(cts, CTID_DOUBLE); /* FPRs always hold doubles. */ -#elif LJ_TARGET_MIPS -/* -- MIPS calling conventions -------------------------------------------- */ +#elif LJ_TARGET_MIPS32 +/* -- MIPS o32 calling conventions ---------------------------------------- */ #define CCALL_HANDLE_STRUCTRET \ cc->retref = 1; /* Return all structs by reference. */ \ @@ -483,6 +490,78 @@ sp = (uint8_t *)&cc->fpr[0].f; #endif +#elif LJ_TARGET_MIPS64 +/* -- MIPS n64 calling conventions ---------------------------------------- */ + +#define CCALL_HANDLE_STRUCTRET \ + cc->retref = !(sz <= 16); \ + if (cc->retref) cc->gpr[ngpr++] = (GPRArg)dp; + +#define CCALL_HANDLE_STRUCTRET2 \ + ccall_copy_struct(cc, ctr, dp, sp, ccall_classify_struct(cts, ctr, ct)); + +#define CCALL_HANDLE_COMPLEXRET \ + /* Complex values are returned in 1 or 2 FPRs. */ \ + cc->retref = 0; + +#if LJ_ABI_SOFTFP /* MIPS64 soft-float */ + +#define CCALL_HANDLE_COMPLEXRET2 \ + if (ctr->size == 2*sizeof(float)) { /* Copy complex float from GPRs. */ \ + ((intptr_t *)dp)[0] = cc->gpr[0]; \ + } else { /* Copy complex double from GPRs. */ \ + ((intptr_t *)dp)[0] = cc->gpr[0]; \ + ((intptr_t *)dp)[1] = cc->gpr[1]; \ + } + +#define CCALL_HANDLE_COMPLEXARG \ + /* Pass complex by value in 2 or 4 GPRs. */ + +/* Position of soft-float 'float' return value depends on endianess. */ +#define CCALL_HANDLE_RET \ + if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \ + sp = (uint8_t *)cc->gpr + LJ_ENDIAN_SELECT(0, 4); + +#else /* MIPS64 hard-float */ + +#define CCALL_HANDLE_COMPLEXRET2 \ + if (ctr->size == 2*sizeof(float)) { /* Copy complex float from FPRs. */ \ + ((float *)dp)[0] = cc->fpr[0].f; \ + ((float *)dp)[1] = cc->fpr[1].f; \ + } else { /* Copy complex double from FPRs. */ \ + ((double *)dp)[0] = cc->fpr[0].d; \ + ((double *)dp)[1] = cc->fpr[1].d; \ + } + +#define CCALL_HANDLE_COMPLEXARG \ + if (sz == 2*sizeof(float)) { \ + isfp = 2; \ + if (ngpr < maxgpr) \ + sz *= 2; \ + } + +#define CCALL_HANDLE_RET \ + if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \ + sp = (uint8_t *)&cc->fpr[0].f; + +#endif + +#define CCALL_HANDLE_STRUCTARG \ + /* Pass all structs by value in registers and/or on the stack. */ + +#define CCALL_HANDLE_REGARG \ + if (ngpr < maxgpr) { \ + dp = &cc->gpr[ngpr]; \ + if (ngpr + n > maxgpr) { \ + nsp += ngpr + n - maxgpr; /* Assumes contiguous gpr/stack fields. */ \ + if (nsp > CCALL_MAXSTACK) goto err_nyi; /* Too many arguments. */ \ + ngpr = maxgpr; \ + } else { \ + ngpr += n; \ + } \ + goto done; \ + } + #else #error "Missing calling convention definitions for this architecture" #endif @@ -722,6 +801,78 @@ noth: /* Not a homogeneous float/double aggregate. */ #endif +/* -- MIPS64 ABI struct classification ---------------------------- */ + +#if LJ_TARGET_MIPS64 + +#define FTYPE_FLOAT 1 +#define FTYPE_DOUBLE 2 + +/* Classify FP fields (max. 2) and their types. */ +static unsigned int ccall_classify_struct(CTState *cts, CType *ct, CType *ctf) +{ + int n = 0, ft = 0; + if ((ctf->info & CTF_VARARG) || (ct->info & CTF_UNION)) + goto noth; + while (ct->sib) { + CType *sct; + ct = ctype_get(cts, ct->sib); + if (n == 2) { + goto noth; + } else if (ctype_isfield(ct->info)) { + sct = ctype_rawchild(cts, ct); + if (ctype_isfp(sct->info)) { + ft |= (sct->size == 4 ? FTYPE_FLOAT : FTYPE_DOUBLE) << 2*n; + n++; + } else { + goto noth; + } + } else if (ctype_isbitfield(ct->info) || + ctype_isxattrib(ct->info, CTA_SUBTYPE)) { + goto noth; + } + } + if (n <= 2) + return ft; +noth: /* Not a homogeneous float/double aggregate. */ + return 0; /* Struct is in GPRs. */ +} + +void ccall_copy_struct(CCallState *cc, CType *ctr, void *dp, void *sp, int ft) +{ + if (LJ_ABI_SOFTFP ? ft : + ((ft & 3) == FTYPE_FLOAT || (ft >> 2) == FTYPE_FLOAT)) { + int i, ofs = 0; + for (i = 0; ft != 0; i++, ft >>= 2) { + if ((ft & 3) == FTYPE_FLOAT) { +#if LJ_ABI_SOFTFP + /* The 2nd FP struct result is in CARG1 (gpr[2]) and not CRET2. */ + memcpy((uint8_t *)dp + ofs, + (uint8_t *)&cc->gpr[2*i] + LJ_ENDIAN_SELECT(0, 4), 4); +#else + *(float *)((uint8_t *)dp + ofs) = cc->fpr[i].f; +#endif + ofs += 4; + } else { + ofs = (ofs + 7) & ~7; /* 64 bit alignment. */ +#if LJ_ABI_SOFTFP + *(intptr_t *)((uint8_t *)dp + ofs) = cc->gpr[2*i]; +#else + *(double *)((uint8_t *)dp + ofs) = cc->fpr[i].d; +#endif + ofs += 8; + } + } + } else { +#if !LJ_ABI_SOFTFP + if (ft) sp = (uint8_t *)&cc->fpr[0]; +#endif + memcpy(dp, sp, ctr->size); + } +} + +#endif + /* -- Common C call handling ---------------------------------------------- */ /* Infer the destination CTypeID for a vararg argument. */ @@ -889,6 +1040,19 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct, *(int32_t *)dp = d->size == 1 ? (int32_t)*(int8_t *)dp : (int32_t)*(int16_t *)dp; } +#if LJ_TARGET_ARM64 && LJ_BE + if (isfp && d->size == sizeof(float)) + ((float *)dp)[1] = ((float *)dp)[0]; /* Floats occupy high slot. */ +#endif +#if LJ_TARGET_MIPS64 || (LJ_TARGET_ARM64 && LJ_BE) + if ((ctype_isinteger_or_bool(d->info) || ctype_isenum(d->info) +#if LJ_TARGET_MIPS64 + || (isfp && nsp == 0) +#endif + ) && d->size <= 4) { + *(int64_t *)dp = (int64_t)*(int32_t *)dp; /* Sign-extend to 64 bit. */ + } +#endif #if LJ_TARGET_X64 && LJ_ABI_WIN if (isva) { /* Windows/x64 mirrors varargs in both register sets. */ if (nfpr == ngpr) @@ -904,7 +1068,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct, cc->fpr[nfpr-1].d[0] = cc->fpr[nfpr-2].d[1]; /* Split complex double. */ cc->fpr[nfpr-2].d[1] = 0; } -#elif LJ_TARGET_ARM64 +#elif LJ_TARGET_ARM64 || (LJ_TARGET_MIPS64 && !LJ_ABI_SOFTFP) if (isfp == 2 && (uint8_t *)dp < (uint8_t *)cc->stack) { /* Split float HFA or complex float into separate registers. */ CTSize i = (sz >> 2) - 1; @@ -951,7 +1115,8 @@ static int ccall_get_results(lua_State *L, CTState *cts, CType *ct, CCALL_HANDLE_COMPLEXRET2 return 1; /* One GC step. */ } - if (LJ_BE && ctype_isinteger_or_bool(ctr->info) && ctr->size < CTSIZE_PTR) + if (LJ_BE && ctr->size < CTSIZE_PTR && + (ctype_isinteger_or_bool(ctr->info) || ctype_isenum(ctr->info))) sp += (CTSIZE_PTR - ctr->size); #if CCALL_NUM_FPR if (ctype_isfp(ctr->info) || ctype_isvector(ctr->info)) diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_ccall.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_ccall.h index a77afae3f87..59f664817a2 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_ccall.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_ccall.h @@ -1,6 +1,6 @@ /* ** FFI C call handling. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_CCALL_H @@ -79,8 +79,8 @@ typedef union FPRArg { typedef intptr_t GPRArg; typedef union FPRArg { double d; - float f; - uint32_t u32; + struct { LJ_ENDIAN_LOHI(float f; , float g;) }; + struct { LJ_ENDIAN_LOHI(uint32_t lo; , uint32_t hi;) }; } FPRArg; #elif LJ_TARGET_PPC @@ -95,11 +95,11 @@ typedef union FPRArg { typedef intptr_t GPRArg; typedef double FPRArg; -#elif LJ_TARGET_MIPS +#elif LJ_TARGET_MIPS32 #define CCALL_NARG_GPR 4 #define CCALL_NARG_FPR (LJ_ABI_SOFTFP ? 0 : 2) -#define CCALL_NRET_GPR 2 +#define CCALL_NRET_GPR (LJ_ABI_SOFTFP ? 4 : 2) #define CCALL_NRET_FPR (LJ_ABI_SOFTFP ? 0 : 2) #define CCALL_SPS_EXTRA 7 #define CCALL_SPS_FREE 1 @@ -110,6 +110,22 @@ typedef union FPRArg { struct { LJ_ENDIAN_LOHI(float f; , float g;) }; } FPRArg; +#elif LJ_TARGET_MIPS64 + +/* FP args are positional and overlay the GPR array. */ +#define CCALL_NARG_GPR 8 +#define CCALL_NARG_FPR 0 +#define CCALL_NRET_GPR 2 +#define CCALL_NRET_FPR (LJ_ABI_SOFTFP ? 0 : 2) +#define CCALL_SPS_EXTRA 3 +#define CCALL_SPS_FREE 1 + +typedef intptr_t GPRArg; +typedef union FPRArg { + double d; + struct { LJ_ENDIAN_LOHI(float f; , float g;) }; +} FPRArg; + #else #error "Missing calling convention definitions for this architecture" #endif diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_ccallback.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_ccallback.c index 43c29e41265..846827b119b 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_ccallback.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_ccallback.c @@ -1,6 +1,6 @@ /* ** FFI C callback handling. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #include "lj_obj.h" @@ -63,9 +63,13 @@ static MSize CALLBACK_OFS2SLOT(MSize ofs) #define CALLBACK_MCODE_HEAD 24 -#elif LJ_TARGET_MIPS +#elif LJ_TARGET_MIPS32 -#define CALLBACK_MCODE_HEAD 24 +#define CALLBACK_MCODE_HEAD 20 + +#elif LJ_TARGET_MIPS64 + +#define CALLBACK_MCODE_HEAD 52 #else @@ -169,16 +173,16 @@ static void callback_mcode_init(global_State *g, uint32_t *page) uint32_t *p = page; void *target = (void *)lj_vm_ffi_callback; MSize slot; - *p++ = A64I_LDRLx | A64F_D(RID_X11) | A64F_S19(4); - *p++ = A64I_LDRLx | A64F_D(RID_X10) | A64F_S19(5); - *p++ = A64I_BR | A64F_N(RID_X11); - *p++ = A64I_NOP; + *p++ = A64I_LE(A64I_LDRLx | A64F_D(RID_X11) | A64F_S19(4)); + *p++ = A64I_LE(A64I_LDRLx | A64F_D(RID_X10) | A64F_S19(5)); + *p++ = A64I_LE(A64I_BR | A64F_N(RID_X11)); + *p++ = A64I_LE(A64I_NOP); ((void **)p)[0] = target; ((void **)p)[1] = g; p += 4; for (slot = 0; slot < CALLBACK_MAX_SLOT; slot++) { - *p++ = A64I_MOVZw | A64F_D(RID_X9) | A64F_U16(slot); - *p = A64I_B | A64F_S26((page-p) & 0x03ffffffu); + *p++ = A64I_LE(A64I_MOVZw | A64F_D(RID_X9) | A64F_U16(slot)); + *p = A64I_LE(A64I_B | A64F_S26((page-p) & 0x03ffffffu)); p++; } lua_assert(p - page <= CALLBACK_MCODE_SIZE); @@ -206,14 +210,27 @@ static void callback_mcode_init(global_State *g, uint32_t *page) static void callback_mcode_init(global_State *g, uint32_t *page) { uint32_t *p = page; - void *target = (void *)lj_vm_ffi_callback; + uintptr_t target = (uintptr_t)(void *)lj_vm_ffi_callback; + uintptr_t ug = (uintptr_t)(void *)g; MSize slot; - *p++ = MIPSI_SW | MIPSF_T(RID_R1)|MIPSF_S(RID_SP) | 0; - *p++ = MIPSI_LUI | MIPSF_T(RID_R3) | (u32ptr(target) >> 16); - *p++ = MIPSI_LUI | MIPSF_T(RID_R2) | (u32ptr(g) >> 16); - *p++ = MIPSI_ORI | MIPSF_T(RID_R3)|MIPSF_S(RID_R3) |(u32ptr(target)&0xffff); +#if LJ_TARGET_MIPS32 + *p++ = MIPSI_LUI | MIPSF_T(RID_R3) | (target >> 16); + *p++ = MIPSI_LUI | MIPSF_T(RID_R2) | (ug >> 16); +#else + *p++ = MIPSI_LUI | MIPSF_T(RID_R3) | (target >> 48); + *p++ = MIPSI_LUI | MIPSF_T(RID_R2) | (ug >> 48); + *p++ = MIPSI_ORI | MIPSF_T(RID_R3)|MIPSF_S(RID_R3) | ((target >> 32) & 0xffff); + *p++ = MIPSI_ORI | MIPSF_T(RID_R2)|MIPSF_S(RID_R2) | ((ug >> 32) & 0xffff); + *p++ = MIPSI_DSLL | MIPSF_D(RID_R3)|MIPSF_T(RID_R3) | MIPSF_A(16); + *p++ = MIPSI_DSLL | MIPSF_D(RID_R2)|MIPSF_T(RID_R2) | MIPSF_A(16); + *p++ = MIPSI_ORI | MIPSF_T(RID_R3)|MIPSF_S(RID_R3) | ((target >> 16) & 0xffff); + *p++ = MIPSI_ORI | MIPSF_T(RID_R2)|MIPSF_S(RID_R2) | ((ug >> 16) & 0xffff); + *p++ = MIPSI_DSLL | MIPSF_D(RID_R3)|MIPSF_T(RID_R3) | MIPSF_A(16); + *p++ = MIPSI_DSLL | MIPSF_D(RID_R2)|MIPSF_T(RID_R2) | MIPSF_A(16); +#endif + *p++ = MIPSI_ORI | MIPSF_T(RID_R3)|MIPSF_S(RID_R3) | (target & 0xffff); *p++ = MIPSI_JR | MIPSF_S(RID_R3); - *p++ = MIPSI_ORI | MIPSF_T(RID_R2)|MIPSF_S(RID_R2) | (u32ptr(g)&0xffff); + *p++ = MIPSI_ORI | MIPSF_T(RID_R2)|MIPSF_S(RID_R2) | (ug & 0xffff); for (slot = 0; slot < CALLBACK_MAX_SLOT; slot++) { *p = MIPSI_B | ((page-p-1) & 0x0000ffffu); p++; @@ -425,7 +442,7 @@ void lj_ccallback_mcode_free(CTState *cts) if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \ *(double *)dp = *(float *)dp; /* FPRs always hold doubles. */ -#elif LJ_TARGET_MIPS +#elif LJ_TARGET_MIPS32 #define CALLBACK_HANDLE_GPR \ if (n > 1) ngpr = (ngpr + 1u) & ~1u; /* Align to regpair. */ \ @@ -455,6 +472,29 @@ void lj_ccallback_mcode_free(CTState *cts) if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \ ((float *)dp)[1] = *(float *)dp; +#elif LJ_TARGET_MIPS64 + +#if !LJ_ABI_SOFTFP /* MIPS64 hard-float */ +#define CALLBACK_HANDLE_REGARG \ + if (ngpr + n <= maxgpr) { \ + sp = isfp ? (void*) &cts->cb.fpr[ngpr] : (void*) &cts->cb.gpr[ngpr]; \ + ngpr += n; \ + goto done; \ + } +#else /* MIPS64 soft-float */ +#define CALLBACK_HANDLE_REGARG \ + if (ngpr + n <= maxgpr) { \ + UNUSED(isfp); \ + sp = (void*) &cts->cb.gpr[ngpr]; \ + ngpr += n; \ + goto done; \ + } +#endif + +#define CALLBACK_HANDLE_RET \ + if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \ + ((float *)dp)[1] = *(float *)dp; + #else #error "Missing calling convention definitions for this architecture" #endif @@ -542,7 +582,11 @@ static void callback_conv_args(CTState *cts, lua_State *L) nsp += n; done: - if (LJ_BE && cta->size < CTSIZE_PTR) + if (LJ_BE && cta->size < CTSIZE_PTR +#if LJ_TARGET_MIPS64 + && !(isfp && nsp) +#endif + ) sp = (void *)((uint8_t *)sp + CTSIZE_PTR-cta->size); gcsteps += lj_cconv_tv_ct(cts, cta, 0, o++, sp); } @@ -580,6 +624,10 @@ static void callback_conv_result(CTState *cts, lua_State *L, TValue *o) if (ctype_isfp(ctr->info)) dp = (uint8_t *)&cts->cb.fpr[0]; #endif +#if LJ_TARGET_ARM64 && LJ_BE + if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) + dp = (uint8_t *)&cts->cb.fpr[0].f[1]; +#endif lj_cconv_ct_tv(cts, ctr, dp, o, 0); #ifdef CALLBACK_HANDLE_RET CALLBACK_HANDLE_RET @@ -593,6 +641,12 @@ static void callback_conv_result(CTState *cts, lua_State *L, TValue *o) *(int32_t *)dp = ctr->size == 1 ? (int32_t)*(int8_t *)dp : (int32_t)*(int16_t *)dp; } +#if LJ_TARGET_MIPS64 || (LJ_TARGET_ARM64 && LJ_BE) + /* Always sign-extend results to 64 bits. Even a soft-fp 'float'. */ + if (ctr->size <= 4 && + (LJ_ABI_SOFTFP || ctype_isinteger_or_bool(ctr->info))) + *(int64_t *)dp = (int64_t)*(int32_t *)dp; +#endif #if LJ_TARGET_X86 if (ctype_isfp(ctr->info)) cts->cb.gpr[2] = ctr->size == sizeof(float) ? 1 : 2; diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_ccallback.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_ccallback.h index 99c778d1a50..a8cdad38630 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_ccallback.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_ccallback.h @@ -1,6 +1,6 @@ /* ** FFI C callback handling. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_CCALLBACK_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_cconv.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_cconv.c index 81f3c871c57..13b8230dc83 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_cconv.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_cconv.c @@ -1,6 +1,6 @@ /* ** C type conversions. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #include "lj_obj.h" @@ -448,8 +448,10 @@ int lj_cconv_tv_bf(CTState *cts, CType *s, TValue *o, uint8_t *sp) setintV(o, (int32_t)val); } } else { + uint32_t b = (val >> pos) & 1; lua_assert(bsz == 1); - setboolV(o, (val >> pos) & 1); + setboolV(o, b); + setboolV(&cts->g->tmptv2, b); /* Remember for trace recorder. */ } return 0; /* No GC step needed. */ } diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_cconv.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_cconv.h index 35e72cbb00a..0a0b66c909a 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_cconv.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_cconv.h @@ -1,6 +1,6 @@ /* ** C type conversions. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_CCONV_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_cdata.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_cdata.c index 05e27dad1ab..68e16d76fc9 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_cdata.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_cdata.c @@ -1,6 +1,6 @@ /* ** C data management. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #include "lj_obj.h" @@ -93,11 +93,13 @@ void lj_cdata_setfin(lua_State *L, GCcdata *cd, GCobj *obj, uint32_t it) setcdataV(L, &tmp, cd); lj_gc_anybarriert(L, t); tv = lj_tab_set(L, t, &tmp); - setgcV(L, tv, obj, it); - if (!tvisnil(tv)) - cd->marked |= LJ_GC_CDATA_FIN; - else + if (it == LJ_TNIL) { + setnilV(tv); cd->marked &= ~LJ_GC_CDATA_FIN; + } else { + setgcV(L, tv, obj, it); + cd->marked |= LJ_GC_CDATA_FIN; + } } } diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_cdata.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_cdata.h index ee5b740dbd7..5bb0f5dca24 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_cdata.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_cdata.h @@ -1,6 +1,6 @@ /* ** C data management. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_CDATA_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_clib.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_clib.c index 922dbfaec8c..614265903ac 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_clib.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_clib.c @@ -1,6 +1,6 @@ /* ** FFI C library loader. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #include "lj_obj.h" @@ -40,7 +40,7 @@ LJ_NORET LJ_NOINLINE static void clib_error_(lua_State *L) #define clib_error(L, fmt, name) clib_error_(L) -#if defined(__CYGWIN__) +#if LJ_TARGET_CYGWIN #define CLIB_SOPREFIX "cyg" #else #define CLIB_SOPREFIX "lib" @@ -48,7 +48,7 @@ LJ_NORET LJ_NOINLINE static void clib_error_(lua_State *L) #if LJ_TARGET_OSX #define CLIB_SOEXT "%s.dylib" -#elif defined(__CYGWIN__) +#elif LJ_TARGET_CYGWIN #define CLIB_SOEXT "%s.dll" #else #define CLIB_SOEXT "%s.so" @@ -57,14 +57,14 @@ LJ_NORET LJ_NOINLINE static void clib_error_(lua_State *L) static const char *clib_extname(lua_State *L, const char *name) { if (!strchr(name, '/') -#ifdef __CYGWIN__ +#if LJ_TARGET_CYGWIN && !strchr(name, '\\') #endif ) { if (!strchr(name, '.')) { name = lj_strfmt_pushf(L, CLIB_SOEXT, name); L->top--; -#ifdef __CYGWIN__ +#if LJ_TARGET_CYGWIN } else { return name; #endif diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_clib.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_clib.h index ce3ab85a8bb..fcc9dac5920 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_clib.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_clib.h @@ -1,6 +1,6 @@ /* ** FFI C library loader. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_CLIB_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_cparse.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_cparse.c index 7ec4a5eebfa..83cfd1128b3 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_cparse.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_cparse.c @@ -1,6 +1,6 @@ /* ** C declaration parser. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #include "lj_obj.h" @@ -297,13 +297,17 @@ static CPToken cp_next_(CPState *cp) else return '/'; break; case '|': - if (cp_get(cp) != '|') return '|'; cp_get(cp); return CTOK_OROR; + if (cp_get(cp) != '|') return '|'; + cp_get(cp); return CTOK_OROR; case '&': - if (cp_get(cp) != '&') return '&'; cp_get(cp); return CTOK_ANDAND; + if (cp_get(cp) != '&') return '&'; + cp_get(cp); return CTOK_ANDAND; case '=': - if (cp_get(cp) != '=') return '='; cp_get(cp); return CTOK_EQ; + if (cp_get(cp) != '=') return '='; + cp_get(cp); return CTOK_EQ; case '!': - if (cp_get(cp) != '=') return '!'; cp_get(cp); return CTOK_NE; + if (cp_get(cp) != '=') return '!'; + cp_get(cp); return CTOK_NE; case '<': if (cp_get(cp) == '=') { cp_get(cp); return CTOK_LE; } else if (cp->c == '<') { cp_get(cp); return CTOK_SHL; } @@ -313,7 +317,8 @@ static CPToken cp_next_(CPState *cp) else if (cp->c == '>') { cp_get(cp); return CTOK_SHR; } return '>'; case '-': - if (cp_get(cp) != '>') return '-'; cp_get(cp); return CTOK_DEREF; + if (cp_get(cp) != '>') return '-'; + cp_get(cp); return CTOK_DEREF; case '$': return cp_param(cp); case '\0': return CTOK_EOF; diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_cparse.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_cparse.h index bfd1a9bb4d0..bad1060bbc9 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_cparse.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_cparse.h @@ -1,6 +1,6 @@ /* ** C declaration parser. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_CPARSE_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_crecord.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_crecord.c index c0f7e3d7957..e32ae23e187 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_crecord.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_crecord.c @@ -1,6 +1,6 @@ /* ** Trace recorder for C data operations. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_ffrecord_c @@ -712,6 +712,19 @@ static TRef crec_reassoc_ofs(jit_State *J, TRef tr, ptrdiff_t *ofsp, MSize sz) return tr; } +/* Tailcall to function. */ +static void crec_tailcall(jit_State *J, RecordFFData *rd, cTValue *tv) +{ + TRef kfunc = lj_ir_kfunc(J, funcV(tv)); +#if LJ_FR2 + J->base[-2] = kfunc; + J->base[-1] = TREF_FRAME; +#else + J->base[-1] = kfunc | TREF_FRAME; +#endif + rd->nres = -1; /* Pending tailcall. */ +} + /* Record ctype __index/__newindex metamethods. */ static void crec_index_meta(jit_State *J, CTState *cts, CType *ct, RecordFFData *rd) @@ -721,8 +734,7 @@ static void crec_index_meta(jit_State *J, CTState *cts, CType *ct, if (!tv) lj_trace_err(J, LJ_TRERR_BADTYPE); if (tvisfunc(tv)) { - J->base[-1] = lj_ir_kfunc(J, funcV(tv)) | TREF_FRAME; - rd->nres = -1; /* Pending tailcall. */ + crec_tailcall(J, rd, tv); } else if (rd->data == 0 && tvistab(tv) && tref_isstr(J->base[1])) { /* Specialize to result of __index lookup. */ cTValue *o = lj_tab_get(J->L, tabV(tv), &rd->argv[1]); @@ -739,6 +751,48 @@ static void crec_index_meta(jit_State *J, CTState *cts, CType *ct, } } +/* Record bitfield load/store. */ +static void crec_index_bf(jit_State *J, RecordFFData *rd, TRef ptr, CTInfo info) +{ + IRType t = IRT_I8 + 2*lj_fls(ctype_bitcsz(info)) + ((info&CTF_UNSIGNED)?1:0); + TRef tr = emitir(IRT(IR_XLOAD, t), ptr, 0); + CTSize pos = ctype_bitpos(info), bsz = ctype_bitbsz(info), shift = 32 - bsz; + lua_assert(t <= IRT_U32); /* NYI: 64 bit bitfields. */ + if (rd->data == 0) { /* __index metamethod. */ + if ((info & CTF_BOOL)) { + tr = emitir(IRTI(IR_BAND), tr, lj_ir_kint(J, (int32_t)((1u << pos)))); + /* Assume not equal to zero. Fixup and emit pending guard later. */ + lj_ir_set(J, IRTGI(IR_NE), tr, lj_ir_kint(J, 0)); + J->postproc = LJ_POST_FIXGUARD; + tr = TREF_TRUE; + } else if (!(info & CTF_UNSIGNED)) { + tr = emitir(IRTI(IR_BSHL), tr, lj_ir_kint(J, shift - pos)); + tr = emitir(IRTI(IR_BSAR), tr, lj_ir_kint(J, shift)); + } else { + lua_assert(bsz < 32); /* Full-size fields cannot end up here. */ + tr = emitir(IRTI(IR_BSHR), tr, lj_ir_kint(J, pos)); + tr = emitir(IRTI(IR_BAND), tr, lj_ir_kint(J, (int32_t)((1u << bsz)-1))); + /* We can omit the U32 to NUM conversion, since bsz < 32. */ + } + J->base[0] = tr; + } else { /* __newindex metamethod. */ + CTState *cts = ctype_ctsG(J2G(J)); + CType *ct = ctype_get(cts, + (info & CTF_BOOL) ? CTID_BOOL : + (info & CTF_UNSIGNED) ? CTID_UINT32 : CTID_INT32); + int32_t mask = (int32_t)(((1u << bsz)-1) << pos); + TRef sp = crec_ct_tv(J, ct, 0, J->base[2], &rd->argv[2]); + sp = emitir(IRTI(IR_BSHL), sp, lj_ir_kint(J, pos)); + /* Use of the target type avoids forwarding conversions. */ + sp = emitir(IRT(IR_BAND, t), sp, lj_ir_kint(J, mask)); + tr = emitir(IRT(IR_BAND, t), tr, lj_ir_kint(J, (int32_t)~mask)); + tr = emitir(IRT(IR_BOR, t), tr, sp); + emitir(IRT(IR_XSTORE, t), ptr, tr); + rd->nres = 0; + J->needsnap = 1; + } +} + void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd) { TRef idx, ptr = J->base[0]; @@ -813,6 +867,7 @@ again: CType *fct; fct = lj_ctype_getfield(cts, ct, name, &fofs); if (fct) { + ofs += (ptrdiff_t)fofs; /* Always specialize to the field name. */ emitir(IRTG(IR_EQ, IRT_STR), idx, lj_ir_kstr(J, name)); if (ctype_isconstval(fct->info)) { @@ -824,12 +879,14 @@ again: J->base[0] = lj_ir_kint(J, (int32_t)fct->size); return; /* Interpreter will throw for newindex. */ } else if (ctype_isbitfield(fct->info)) { - lj_trace_err(J, LJ_TRERR_NYICONV); + if (ofs) + ptr = emitir(IRT(IR_ADD, IRT_PTR), ptr, lj_ir_kintp(J, ofs)); + crec_index_bf(J, rd, ptr, fct->info); + return; } else { lua_assert(ctype_isfield(fct->info)); sid = ctype_cid(fct->info); } - ofs += (ptrdiff_t)fofs; } } else if (ctype_iscomplex(ct->info)) { if (name->len == 2 && @@ -1119,20 +1176,20 @@ static void crec_snap_caller(jit_State *J) lua_State *L = J->L; TValue *base = L->base, *top = L->top; const BCIns *pc = J->pc; - TRef ftr = J->base[-1]; + TRef ftr = J->base[-1-LJ_FR2]; ptrdiff_t delta; if (!frame_islua(base-1) || J->framedepth <= 0) lj_trace_err(J, LJ_TRERR_NYICALL); J->pc = frame_pc(base-1); delta = 1+LJ_FR2+bc_a(J->pc[-1]); L->top = base; L->base = base - delta; - J->base[-1] = TREF_FALSE; + J->base[-1-LJ_FR2] = TREF_FALSE; J->base -= delta; J->baseslot -= (BCReg)delta; - J->maxslot = (BCReg)delta; J->framedepth--; + J->maxslot = (BCReg)delta-LJ_FR2; J->framedepth--; lj_snap_add(J); L->base = base; L->top = top; J->framedepth++; J->maxslot = 1; J->base += delta; J->baseslot += (BCReg)delta; - J->base[-1] = ftr; J->pc = pc; + J->base[-1-LJ_FR2] = ftr; J->pc = pc; } /* Record function call. */ @@ -1224,8 +1281,7 @@ void LJ_FASTCALL recff_cdata_call(jit_State *J, RecordFFData *rd) tv = lj_ctype_meta(cts, ctype_isptr(ct->info) ? ctype_cid(ct->info) : id, mm); if (tv) { if (tvisfunc(tv)) { - J->base[-1] = lj_ir_kfunc(J, funcV(tv)) | TREF_FRAME; - rd->nres = -1; /* Pending tailcall. */ + crec_tailcall(J, rd, tv); return; } } else if (mm == MM_new) { @@ -1238,7 +1294,7 @@ void LJ_FASTCALL recff_cdata_call(jit_State *J, RecordFFData *rd) static TRef crec_arith_int64(jit_State *J, TRef *sp, CType **s, MMS mm) { - if (ctype_isnum(s[0]->info) && ctype_isnum(s[1]->info)) { + if (sp[0] && sp[1] && ctype_isnum(s[0]->info) && ctype_isnum(s[1]->info)) { IRType dt; CTypeID id; TRef tr; @@ -1296,6 +1352,7 @@ static TRef crec_arith_ptr(jit_State *J, TRef *sp, CType **s, MMS mm) { CTState *cts = ctype_ctsG(J2G(J)); CType *ctp = s[0]; + if (!(sp[0] && sp[1])) return 0; if (ctype_isptr(ctp->info) || ctype_isrefarray(ctp->info)) { if ((mm == MM_sub || mm == MM_eq || mm == MM_lt || mm == MM_le) && (ctype_isptr(s[1]->info) || ctype_isrefarray(s[1]->info))) { @@ -1373,8 +1430,7 @@ static TRef crec_arith_meta(jit_State *J, TRef *sp, CType **s, CTState *cts, } if (tv) { if (tvisfunc(tv)) { - J->base[-1] = lj_ir_kfunc(J, funcV(tv)) | TREF_FRAME; - rd->nres = -1; /* Pending tailcall. */ + crec_tailcall(J, rd, tv); return 0; } /* NYI: non-function metamethods. */ } else if ((MMS)rd->data == MM_eq) { /* Fallback cdata pointer comparison. */ diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_crecord.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_crecord.h index 7a058813191..c165def4755 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_crecord.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_crecord.h @@ -1,6 +1,6 @@ /* ** Trace recorder for C data operations. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_CRECORD_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_ctype.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_ctype.c index bc47cc5b927..0ea89c7486a 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_ctype.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_ctype.c @@ -1,6 +1,6 @@ /* ** C type management. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #include "lj_obj.h" diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_ctype.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_ctype.h index e9b426f0dc9..0c220a88866 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_ctype.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_ctype.h @@ -1,6 +1,6 @@ /* ** C type management. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_CTYPE_H @@ -42,18 +42,18 @@ LJ_STATIC_ASSERT(((int)CT_STRUCT & (int)CT_ARRAY) == CT_STRUCT); ** ---------- info ------------ ** |type flags... A cid | size | sib | next | name | ** +----------------------------+--------+-------+-------+-------+-- -** |NUM BFvcUL.. A | size | | type | | -** |STRUCT ..vcU..V A | size | field | name? | name? | -** |PTR ..vcR... A cid | size | | type | | -** |ARRAY VCvc...V A cid | size | | type | | -** |VOID ..vc.... A | size | | type | | +** |NUM BFcvUL.. A | size | | type | | +** |STRUCT ..cvU..V A | size | field | name? | name? | +** |PTR ..cvR... A cid | size | | type | | +** |ARRAY VCcv...V A cid | size | | type | | +** |VOID ..cv.... A | size | | type | | ** |ENUM A cid | size | const | name? | name? | ** |FUNC ....VS.. cc cid | nargs | field | name? | name? | ** |TYPEDEF cid | | | name | name | ** |ATTRIB attrnum cid | attr | sib? | type? | | ** |FIELD cid | offset | field | | name? | -** |BITFIELD B.vcU csz bsz pos | offset | field | | name? | -** |CONSTVAL c cid | value | const | name | name | +** |BITFIELD B.cvU csz bsz pos | offset | field | | name? | +** |CONSTVAL c cid | value | const | name | name | ** |EXTERN cid | | sib? | name | name | ** |KW tok | size | | name | name | ** +----------------------------+--------+-------+-------+-------+-- diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_debug.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_debug.c index 153035a90b2..959dc289c7c 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_debug.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_debug.c @@ -1,6 +1,6 @@ /* ** Debugging and introspection. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_debug_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_debug.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_debug.h index 1028688d145..5917c00bc6f 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_debug.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_debug.h @@ -1,6 +1,6 @@ /* ** Debugging and introspection. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_DEBUG_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_def.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_def.h index 6b898838ef2..517921ddecf 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_def.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_def.h @@ -1,6 +1,6 @@ /* ** LuaJIT common internal definitions. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_DEF_H @@ -95,6 +95,9 @@ typedef unsigned int uintptr_t; #define U64x(hi, lo) (((uint64_t)0x##hi << 32) + (uint64_t)0x##lo) #define i32ptr(p) ((int32_t)(intptr_t)(void *)(p)) #define u32ptr(p) ((uint32_t)(intptr_t)(void *)(p)) +#define i64ptr(p) ((int64_t)(intptr_t)(void *)(p)) +#define u64ptr(p) ((uint64_t)(intptr_t)(void *)(p)) +#define igcptr(p) (LJ_GC64 ? i64ptr(p) : i32ptr(p)) #define checki8(x) ((x) == (int32_t)(int8_t)(x)) #define checku8(x) ((x) == (int32_t)(uint8_t)(x)) @@ -103,14 +106,8 @@ typedef unsigned int uintptr_t; #define checki32(x) ((x) == (int32_t)(x)) #define checku32(x) ((x) == (uint32_t)(x)) #define checkptr32(x) ((uintptr_t)(x) == (uint32_t)(uintptr_t)(x)) -#define checkptr47(x) (((uint64_t)(x) >> 47) == 0) -#if LJ_GC64 -#define checkptrGC(x) (checkptr47((x))) -#elif LJ_64 -#define checkptrGC(x) (checkptr32((x))) -#else -#define checkptrGC(x) 1 -#endif +#define checkptr47(x) (((uint64_t)(uintptr_t)(x) >> 47) == 0) +#define checkptrGC(x) (LJ_GC64 ? checkptr47((x)) : LJ_64 ? checkptr32((x)) :1) /* Every half-decent C compiler transforms this into a rotate instruction. */ #define lj_rol(x, n) (((x)<<(n)) | ((x)>>(-(int)(n)&(8*sizeof(x)-1)))) diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_dispatch.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_dispatch.c index 36b920add7f..5d6795f88e3 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_dispatch.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_dispatch.c @@ -1,6 +1,6 @@ /* ** Instruction dispatch handling. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_dispatch_c @@ -75,7 +75,7 @@ void lj_dispatch_init(GG_State *GG) for (i = 0; i < GG_NUM_ASMFF; i++) GG->bcff[i] = BCINS_AD(BC__MAX+i, 0, 0); #if LJ_TARGET_MIPS - memcpy(GG->got, dispatch_got, LJ_GOT__MAX*4); + memcpy(GG->got, dispatch_got, LJ_GOT__MAX*sizeof(ASMFunction *)); #endif } @@ -267,7 +267,7 @@ int luaJIT_setmode(lua_State *L, int idx, int mode) case LUAJIT_MODE_FUNC: case LUAJIT_MODE_ALLFUNC: case LUAJIT_MODE_ALLSUBFUNC: { - cTValue *tv = idx == 0 ? frame_prev(L->base-1) : + cTValue *tv = idx == 0 ? frame_prev(L->base-1)-LJ_FR2 : idx > 0 ? L->base + (idx-1) : L->top + idx; GCproto *pt; if ((idx == 0 || tvisfunc(tv)) && isluafunc(&gcval(tv)->fn)) diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_dispatch.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_dispatch.h index 827080770da..5bda51a2137 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_dispatch.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_dispatch.h @@ -1,6 +1,6 @@ /* ** Instruction dispatch handling. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_DISPATCH_H @@ -107,6 +107,7 @@ typedef struct GG_State { #define J2G(J) (&J2GG(J)->g) #define G2J(gl) (&G2GG(gl)->J) #define L2J(L) (&L2GG(L)->J) +#define GG_G2J (GG_OFS(J) - GG_OFS(g)) #define GG_G2DISP (GG_OFS(dispatch) - GG_OFS(g)) #define GG_DISP2G (GG_OFS(g) - GG_OFS(dispatch)) #define GG_DISP2J (GG_OFS(J) - GG_OFS(dispatch)) diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_arm.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_arm.h index 47fee5fcd85..dee8bdccd19 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_arm.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_arm.h @@ -1,6 +1,6 @@ /* ** ARM instruction emitter. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ /* -- Constant encoding --------------------------------------------------- */ @@ -207,7 +207,7 @@ static void emit_loadi(ASMState *as, Reg r, int32_t i) #define emit_loada(as, r, addr) emit_loadi(as, (r), i32ptr((addr))) -static Reg ra_allock(ASMState *as, int32_t k, RegSet allow); +static Reg ra_allock(ASMState *as, intptr_t k, RegSet allow); /* Get/set from constant pointer. */ static void emit_lsptr(ASMState *as, ARMIns ai, Reg r, void *p) @@ -219,8 +219,9 @@ static void emit_lsptr(ASMState *as, ARMIns ai, Reg r, void *p) #if !LJ_SOFTFP /* Load a number constant into an FPR. */ -static void emit_loadn(ASMState *as, Reg r, cTValue *tv) +static void emit_loadk64(ASMState *as, Reg r, IRIns *ir) { + cTValue *tv = ir_knum(ir); int32_t i; if ((as->flags & JIT_F_VFPV3) && !tv->u32.lo) { uint32_t hi = tv->u32.hi; @@ -273,7 +274,7 @@ static void emit_call(ASMState *as, void *target) ptrdiff_t delta = ((char *)target - (char *)p) - 8; if ((((delta>>2) + 0x00800000) >> 24) == 0) { if ((delta & 1)) - *p = ARMI_BLX | ((uint32_t)(delta>>2) & 0x00ffffffu) | ((delta&2) << 27); + *p = ARMI_BLX | ((uint32_t)(delta>>2) & 0x00ffffffu) | ((delta&2) << 23); else *p = ARMI_BL | ((uint32_t)(delta>>2) & 0x00ffffffu); } else { /* Target out of range: need indirect call. But don't use R0-R3. */ diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_mips.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_mips.h index fdebe94b49b..8a9ee24dce7 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_mips.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_mips.h @@ -1,8 +1,30 @@ /* ** MIPS instruction emitter. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ +#if LJ_64 +static intptr_t get_k64val(IRIns *ir) +{ + if (ir->o == IR_KINT64) { + return (intptr_t)ir_kint64(ir)->u64; + } else if (ir->o == IR_KGC) { + return (intptr_t)ir_kgc(ir); + } else if (ir->o == IR_KPTR || ir->o == IR_KKPTR) { + return (intptr_t)ir_kptr(ir); + } else { + lua_assert(ir->o == IR_KINT || ir->o == IR_KNULL); + return ir->i; /* Sign-extended. */ + } +} +#endif + +#if LJ_64 +#define get_kval(ir) get_k64val(ir) +#else +#define get_kval(ir) ((ir)->i) +#endif + /* -- Emit basic instructions --------------------------------------------- */ static void emit_dst(ASMState *as, MIPSIns mi, Reg rd, Reg rs, Reg rt) @@ -35,7 +57,7 @@ static void emit_fgh(ASMState *as, MIPSIns mi, Reg rf, Reg rg, Reg rh) static void emit_rotr(ASMState *as, Reg dest, Reg src, Reg tmp, uint32_t shift) { - if ((as->flags & JIT_F_MIPS32R2)) { + if (LJ_64 || (as->flags & JIT_F_MIPSXXR2)) { emit_dta(as, MIPSI_ROTR, dest, src, shift); } else { emit_dst(as, MIPSI_OR, dest, dest, tmp); @@ -44,13 +66,21 @@ static void emit_rotr(ASMState *as, Reg dest, Reg src, Reg tmp, uint32_t shift) } } +#if LJ_64 +static void emit_tsml(ASMState *as, MIPSIns mi, Reg rt, Reg rs, uint32_t msb, + uint32_t lsb) +{ + *--as->mcp = mi | MIPSF_T(rt) | MIPSF_S(rs) | MIPSF_M(msb) | MIPSF_L(lsb); +} +#endif + /* -- Emit loads/stores --------------------------------------------------- */ /* Prefer rematerialization of BASE/L from global_State over spills. */ #define emit_canremat(ref) ((ref) <= REF_BASE) /* Try to find a one step delta relative to another constant. */ -static int emit_kdelta1(ASMState *as, Reg t, int32_t i) +static int emit_kdelta1(ASMState *as, Reg t, intptr_t i) { RegSet work = ~as->freeset & RSET_GPR; while (work) { @@ -58,9 +88,10 @@ static int emit_kdelta1(ASMState *as, Reg t, int32_t i) IRRef ref = regcost_ref(as->cost[r]); lua_assert(r != t); if (ref < ASMREF_L) { - int32_t delta = i - (ra_iskref(ref) ? ra_krefk(as, ref) : IR(ref)->i); + intptr_t delta = (intptr_t)((uintptr_t)i - + (uintptr_t)(ra_iskref(ref) ? ra_krefk(as, ref) : get_kval(IR(ref)))); if (checki16(delta)) { - emit_tsi(as, MIPSI_ADDIU, t, r, delta); + emit_tsi(as, MIPSI_AADDIU, t, r, delta); return 1; } } @@ -76,8 +107,8 @@ static void emit_loadi(ASMState *as, Reg r, int32_t i) emit_ti(as, MIPSI_LI, r, i); } else { if ((i & 0xffff)) { - int32_t jgl = i32ptr(J2G(as->J)); - if ((uint32_t)(i-jgl) < 65536) { + intptr_t jgl = (intptr_t)(void *)J2G(as->J); + if ((uintptr_t)(i-jgl) < 65536) { emit_tsi(as, MIPSI_ADDIU, r, RID_JGL, i-jgl-32768); return; } else if (emit_kdelta1(as, r, i)) { @@ -92,16 +123,48 @@ static void emit_loadi(ASMState *as, Reg r, int32_t i) } } +#if LJ_64 +/* Load a 64 bit constant into a GPR. */ +static void emit_loadu64(ASMState *as, Reg r, uint64_t u64) +{ + if (checki32((int64_t)u64)) { + emit_loadi(as, r, (int32_t)u64); + } else { + uint64_t delta = u64 - (uint64_t)(void *)J2G(as->J); + if (delta < 65536) { + emit_tsi(as, MIPSI_DADDIU, r, RID_JGL, (int32_t)(delta-32768)); + } else if (emit_kdelta1(as, r, (intptr_t)u64)) { + return; + } else { + if ((u64 & 0xffff)) { + emit_tsi(as, MIPSI_ORI, r, r, u64 & 0xffff); + } + if (((u64 >> 16) & 0xffff)) { + emit_dta(as, MIPSI_DSLL, r, r, 16); + emit_tsi(as, MIPSI_ORI, r, r, (u64 >> 16) & 0xffff); + emit_dta(as, MIPSI_DSLL, r, r, 16); + } else { + emit_dta(as, MIPSI_DSLL32, r, r, 0); + } + emit_loadi(as, r, (int32_t)(u64 >> 32)); + } + /* TODO: There are probably more optimization opportunities. */ + } +} + +#define emit_loada(as, r, addr) emit_loadu64(as, (r), u64ptr((addr))) +#else #define emit_loada(as, r, addr) emit_loadi(as, (r), i32ptr((addr))) +#endif -static Reg ra_allock(ASMState *as, int32_t k, RegSet allow); -static void ra_allockreg(ASMState *as, int32_t k, Reg r); +static Reg ra_allock(ASMState *as, intptr_t k, RegSet allow); +static void ra_allockreg(ASMState *as, intptr_t k, Reg r); /* Get/set from constant pointer. */ static void emit_lsptr(ASMState *as, MIPSIns mi, Reg r, void *p, RegSet allow) { - int32_t jgl = i32ptr(J2G(as->J)); - int32_t i = i32ptr(p); + intptr_t jgl = (intptr_t)(J2G(as->J)); + intptr_t i = (intptr_t)(p); Reg base; if ((uint32_t)(i-jgl) < 65536) { i = i-jgl-32768; @@ -112,8 +175,24 @@ static void emit_lsptr(ASMState *as, MIPSIns mi, Reg r, void *p, RegSet allow) emit_tsi(as, mi, r, base, i); } -#define emit_loadn(as, r, tv) \ - emit_lsptr(as, MIPSI_LDC1, ((r) & 31), (void *)(tv), RSET_GPR) +#if LJ_64 +static void emit_loadk64(ASMState *as, Reg r, IRIns *ir) +{ + const uint64_t *k = &ir_k64(ir)->u64; + Reg r64 = r; + if (rset_test(RSET_FPR, r)) { + r64 = RID_TMP; + emit_tg(as, MIPSI_DMTC1, r64, r); + } + if ((uint32_t)((intptr_t)k-(intptr_t)J2G(as->J)) < 65536) + emit_lsptr(as, MIPSI_LD, r64, (void *)k, 0); + else + emit_loadu64(as, r64, *k); +} +#else +#define emit_loadk64(as, r, ir) \ + emit_lsptr(as, MIPSI_LDC1, ((r) & 31), (void *)&ir_knum((ir))->u64, RSET_GPR) +#endif /* Get/set global_State fields. */ static void emit_lsglptr(ASMState *as, MIPSIns mi, Reg r, int32_t ofs) @@ -122,9 +201,9 @@ static void emit_lsglptr(ASMState *as, MIPSIns mi, Reg r, int32_t ofs) } #define emit_getgl(as, r, field) \ - emit_lsglptr(as, MIPSI_LW, (r), (int32_t)offsetof(global_State, field)) + emit_lsglptr(as, MIPSI_AL, (r), (int32_t)offsetof(global_State, field)) #define emit_setgl(as, r, field) \ - emit_lsglptr(as, MIPSI_SW, (r), (int32_t)offsetof(global_State, field)) + emit_lsglptr(as, MIPSI_AS, (r), (int32_t)offsetof(global_State, field)) /* Trace number is determined from per-trace exit stubs. */ #define emit_setvmstate(as, i) UNUSED(i) @@ -157,13 +236,14 @@ static void emit_call(ASMState *as, void *target, int needcfa) MCode *p = as->mcp; *--p = MIPSI_NOP; if ((((uintptr_t)target ^ (uintptr_t)p) >> 28) == 0) { - *--p = MIPSI_JAL | (((uintptr_t)target >>2) & 0x03ffffffu); + *--p = (((uintptr_t)target & 1) ? MIPSI_JALX : MIPSI_JAL) | + (((uintptr_t)target >>2) & 0x03ffffffu); } else { /* Target out of range: need indirect call. */ *--p = MIPSI_JALR | MIPSF_S(RID_CFUNCADDR); needcfa = 1; } as->mcp = p; - if (needcfa) ra_allockreg(as, i32ptr(target), RID_CFUNCADDR); + if (needcfa) ra_allockreg(as, (intptr_t)target, RID_CFUNCADDR); } /* -- Emit generic operations --------------------------------------------- */ @@ -184,7 +264,7 @@ static void emit_movrr(ASMState *as, IRIns *ir, Reg dst, Reg src) static void emit_loadofs(ASMState *as, IRIns *ir, Reg r, Reg base, int32_t ofs) { if (r < RID_MAX_GPR) - emit_tsi(as, MIPSI_LW, r, base, ofs); + emit_tsi(as, irt_is64(ir->t) ? MIPSI_LD : MIPSI_LW, r, base, ofs); else emit_tsi(as, irt_isnum(ir->t) ? MIPSI_LDC1 : MIPSI_LWC1, (r & 31), base, ofs); @@ -194,7 +274,7 @@ static void emit_loadofs(ASMState *as, IRIns *ir, Reg r, Reg base, int32_t ofs) static void emit_storeofs(ASMState *as, IRIns *ir, Reg r, Reg base, int32_t ofs) { if (r < RID_MAX_GPR) - emit_tsi(as, MIPSI_SW, r, base, ofs); + emit_tsi(as, irt_is64(ir->t) ? MIPSI_SD : MIPSI_SW, r, base, ofs); else emit_tsi(as, irt_isnum(ir->t) ? MIPSI_SDC1 : MIPSI_SWC1, (r&31), base, ofs); @@ -205,7 +285,7 @@ static void emit_addptr(ASMState *as, Reg r, int32_t ofs) { if (ofs) { lua_assert(checki16(ofs)); - emit_tsi(as, MIPSI_ADDIU, r, r, ofs); + emit_tsi(as, MIPSI_AADDIU, r, r, ofs); } } diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_ppc.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_ppc.h index 4eb933ea549..21c3c2ace70 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_ppc.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_ppc.h @@ -1,6 +1,6 @@ /* ** PPC instruction emitter. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ /* -- Emit basic instructions --------------------------------------------- */ @@ -98,7 +98,7 @@ static void emit_loadi(ASMState *as, Reg r, int32_t i) #define emit_loada(as, r, addr) emit_loadi(as, (r), i32ptr((addr))) -static Reg ra_allock(ASMState *as, int32_t k, RegSet allow); +static Reg ra_allock(ASMState *as, intptr_t k, RegSet allow); /* Get/set from constant pointer. */ static void emit_lsptr(ASMState *as, PPCIns pi, Reg r, void *p, RegSet allow) @@ -115,8 +115,8 @@ static void emit_lsptr(ASMState *as, PPCIns pi, Reg r, void *p, RegSet allow) emit_tai(as, pi, r, base, i); } -#define emit_loadn(as, r, tv) \ - emit_lsptr(as, PPCI_LFD, ((r) & 31), (void *)(tv), RSET_GPR) +#define emit_loadk64(as, r, ir) \ + emit_lsptr(as, PPCI_LFD, ((r) & 31), (void *)&ir_knum((ir))->u64, RSET_GPR) /* Get/set global_State fields. */ static void emit_lsglptr(ASMState *as, PPCIns pi, Reg r, int32_t ofs) diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_x86.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_x86.h index caf30859ace..5207f9dada5 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_x86.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_x86.h @@ -1,6 +1,6 @@ /* ** x86/x64 instruction emitter. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ /* -- Emit basic instructions --------------------------------------------- */ @@ -13,10 +13,17 @@ if (rex != 0x40) *--(p) = rex; } #define FORCE_REX 0x200 #define REX_64 (FORCE_REX|0x080000) +#define VEX_64 0x800000 #else #define REXRB(p, rr, rb) ((void)0) #define FORCE_REX 0 #define REX_64 0 +#define VEX_64 0 +#endif +#if LJ_GC64 +#define REX_GC64 REX_64 +#else +#define REX_GC64 0 #endif #define emit_i8(as, i) (*--as->mcp = (MCode)(i)) @@ -31,6 +38,13 @@ static LJ_AINLINE MCode *emit_op(x86Op xo, Reg rr, Reg rb, Reg rx, MCode *p, int delta) { int n = (int8_t)xo; + if (n == -60) { /* VEX-encoded instruction */ +#if LJ_64 + xo ^= (((rr>>1)&4)+((rx>>2)&2)+((rb>>3)&1))<<13; +#endif + *(uint32_t *)(p+delta-5) = (uint32_t)xo; + return p+delta-5; + } #if defined(__GNUC__) if (__builtin_constant_p(xo) && n == -2) p[delta-2] = (MCode)(xo >> 24); @@ -85,26 +99,17 @@ static int32_t ptr2addr(const void *p) #define ptr2addr(p) (i32ptr((p))) #endif -/* op r, [addr] */ -static void emit_rma(ASMState *as, x86Op xo, Reg rr, const void *addr) -{ - MCode *p = as->mcp; - *(int32_t *)(p-4) = ptr2addr(addr); -#if LJ_64 - p[-5] = MODRM(XM_SCALE1, RID_ESP, RID_EBP); - as->mcp = emit_opm(xo, XM_OFS0, rr, RID_ESP, p, -5); -#else - as->mcp = emit_opm(xo, XM_OFS0, rr, RID_EBP, p, -4); -#endif -} - /* op r, [base+ofs] */ static void emit_rmro(ASMState *as, x86Op xo, Reg rr, Reg rb, int32_t ofs) { MCode *p = as->mcp; x86Mode mode; if (ra_hasreg(rb)) { - if (ofs == 0 && (rb&7) != RID_EBP) { + if (LJ_GC64 && rb == RID_RIP) { + mode = XM_OFS0; + p -= 4; + *(int32_t *)p = ofs; + } else if (ofs == 0 && (rb&7) != RID_EBP) { mode = XM_OFS0; } else if (checki8(ofs)) { *--p = (MCode)ofs; @@ -202,6 +207,11 @@ static void emit_mrm(ASMState *as, x86Op xo, Reg rr, Reg rb) *--p = MODRM(XM_SCALE1, RID_ESP, RID_EBP); rb = RID_ESP; #endif + } else if (LJ_GC64 && rb == RID_RIP) { + lua_assert(as->mrm.idx == RID_NONE); + mode = XM_OFS0; + p -= 4; + *(int32_t *)p = as->mrm.ofs; } else { if (as->mrm.ofs == 0 && (rb&7) != RID_EBP) { mode = XM_OFS0; @@ -255,8 +265,8 @@ static void emit_movmroi(ASMState *as, Reg base, int32_t ofs, int32_t i) /* Get/set global_State fields. */ #define emit_opgl(as, xo, r, field) \ emit_rma(as, (xo), (r), (void *)&J2G(as->J)->field) -#define emit_getgl(as, r, field) emit_opgl(as, XO_MOV, (r), field) -#define emit_setgl(as, r, field) emit_opgl(as, XO_MOVto, (r), field) +#define emit_getgl(as, r, field) emit_opgl(as, XO_MOV, (r)|REX_GC64, field) +#define emit_setgl(as, r, field) emit_opgl(as, XO_MOVto, (r)|REX_GC64, field) #define emit_setvmstate(as, i) \ (emit_i32(as, i), emit_opgl(as, XO_MOVmi, 0, vmstate)) @@ -279,9 +289,21 @@ static void emit_loadi(ASMState *as, Reg r, int32_t i) } } +#if LJ_GC64 +#define dispofs(as, k) \ + ((intptr_t)((uintptr_t)(k) - (uintptr_t)J2GG(as->J)->dispatch)) +#define mcpofs(as, k) \ + ((intptr_t)((uintptr_t)(k) - (uintptr_t)as->mcp)) +#define mctopofs(as, k) \ + ((intptr_t)((uintptr_t)(k) - (uintptr_t)as->mctop)) +/* mov r, addr */ +#define emit_loada(as, r, addr) \ + emit_loadu64(as, (r), (uintptr_t)(addr)) +#else /* mov r, addr */ #define emit_loada(as, r, addr) \ emit_loadi(as, (r), ptr2addr((addr))) +#endif #if LJ_64 /* mov r, imm64 or shorter 32 bit extended load. */ @@ -293,6 +315,15 @@ static void emit_loadu64(ASMState *as, Reg r, uint64_t u64) MCode *p = as->mcp; *(int32_t *)(p-4) = (int32_t)u64; as->mcp = emit_opm(XO_MOVmi, XM_REG, REX_64, r, p, -4); +#if LJ_GC64 + } else if (checki32(dispofs(as, u64))) { + emit_rmro(as, XO_LEA, r|REX_64, RID_DISPATCH, (int32_t)dispofs(as, u64)); + } else if (checki32(mcpofs(as, u64)) && checki32(mctopofs(as, u64))) { + /* Since as->realign assumes the code size doesn't change, check + ** RIP-relative addressing reachability for both as->mcp and as->mctop. + */ + emit_rmro(as, XO_LEA, r|REX_64, RID_RIP, (int32_t)mcpofs(as, u64)); +#endif } else { /* Full-size 64 bit load. */ MCode *p = as->mcp; *(uint64_t *)(p-8) = u64; @@ -304,13 +335,71 @@ static void emit_loadu64(ASMState *as, Reg r, uint64_t u64) } #endif -/* movsd r, [&tv->n] / xorps r, r */ -static void emit_loadn(ASMState *as, Reg r, cTValue *tv) +/* op r, [addr] */ +static void emit_rma(ASMState *as, x86Op xo, Reg rr, const void *addr) { - if (tvispzero(tv)) /* Use xor only for +0. */ - emit_rr(as, XO_XORPS, r, r); - else - emit_rma(as, XO_MOVSD, r, &tv->n); +#if LJ_GC64 + if (checki32(dispofs(as, addr))) { + emit_rmro(as, xo, rr, RID_DISPATCH, (int32_t)dispofs(as, addr)); + } else if (checki32(mcpofs(as, addr)) && checki32(mctopofs(as, addr))) { + emit_rmro(as, xo, rr, RID_RIP, (int32_t)mcpofs(as, addr)); + } else if (!checki32((intptr_t)addr) && (xo == XO_MOV || xo == XO_MOVSD)) { + emit_rmro(as, xo, rr, rr, 0); + emit_loadu64(as, rr, (uintptr_t)addr); + } else +#endif + { + MCode *p = as->mcp; + *(int32_t *)(p-4) = ptr2addr(addr); +#if LJ_64 + p[-5] = MODRM(XM_SCALE1, RID_ESP, RID_EBP); + as->mcp = emit_opm(xo, XM_OFS0, rr, RID_ESP, p, -5); +#else + as->mcp = emit_opm(xo, XM_OFS0, rr, RID_EBP, p, -4); +#endif + } +} + +/* Load 64 bit IR constant into register. */ +static void emit_loadk64(ASMState *as, Reg r, IRIns *ir) +{ + Reg r64; + x86Op xo; + const uint64_t *k = &ir_k64(ir)->u64; + if (rset_test(RSET_FPR, r)) { + r64 = r; + xo = XO_MOVSD; + } else { + r64 = r | REX_64; + xo = XO_MOV; + } + if (*k == 0) { + emit_rr(as, rset_test(RSET_FPR, r) ? XO_XORPS : XO_ARITH(XOg_XOR), r, r); +#if LJ_GC64 + } else if (checki32((intptr_t)k) || checki32(dispofs(as, k)) || + (checki32(mcpofs(as, k)) && checki32(mctopofs(as, k)))) { + emit_rma(as, xo, r64, k); + } else { + if (ir->i) { + lua_assert(*k == *(uint64_t*)(as->mctop - ir->i)); + } else if (as->curins <= as->stopins && rset_test(RSET_GPR, r)) { + emit_loadu64(as, r, *k); + return; + } else { + /* If all else fails, add the FP constant at the MCode area bottom. */ + while ((uintptr_t)as->mcbot & 7) *as->mcbot++ = XI_INT3; + *(uint64_t *)as->mcbot = *k; + ir->i = (int32_t)(as->mctop - as->mcbot); + as->mcbot += 8; + as->mclim = as->mcbot + MCLIM_REDZONE; + lj_mcode_commitbot(as->J, as->mcbot); + } + emit_rmro(as, xo, r64, RID_RIP, (int32_t)mcpofs(as, as->mctop - ir->i)); +#else + } else { + emit_rma(as, xo, r64, k); +#endif + } } /* -- Emit control-flow instructions -------------------------------------- */ @@ -412,8 +501,10 @@ static void emit_call_(ASMState *as, MCode *target) /* Use 64 bit operations to handle 64 bit IR types. */ #if LJ_64 #define REX_64IR(ir, r) ((r) + (irt_is64((ir)->t) ? REX_64 : 0)) +#define VEX_64IR(ir, r) ((r) + (irt_is64((ir)->t) ? VEX_64 : 0)) #else #define REX_64IR(ir, r) (r) +#define VEX_64IR(ir, r) (r) #endif /* Generic move between two regs. */ @@ -449,9 +540,9 @@ static void emit_addptr(ASMState *as, Reg r, int32_t ofs) { if (ofs) { if ((as->flags & JIT_F_LEA_AGU)) - emit_rmro(as, XO_LEA, r, r, ofs); + emit_rmro(as, XO_LEA, r|REX_GC64, r, ofs); else - emit_gri(as, XG_ARITHi(XOg_ADD), r, ofs); + emit_gri(as, XG_ARITHi(XOg_ADD), r|REX_GC64, ofs); } } diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_err.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_err.c index a847ca07db2..b6be357e791 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_err.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_err.c @@ -1,6 +1,6 @@ /* ** Error handling. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_err_c @@ -46,7 +46,8 @@ ** the wrapper function feature. Lua errors thrown through C++ frames ** cannot be caught by C++ code and C++ destructors are not run. ** -** EXT is the default on x64 systems, INT is the default on all other systems. +** EXT is the default on x64 systems and on Windows, INT is the default on all +** other systems. ** ** EXT can be manually enabled on POSIX systems using GCC and DWARF2 stack ** unwinding with -DLUAJIT_UNWIND_EXTERNAL. *All* C code must be compiled @@ -55,7 +56,6 @@ ** and all C libraries that have callbacks which may be used to call back ** into Lua. C++ code must *not* be compiled with -fno-exceptions. ** -** EXT cannot be enabled on WIN32 since system exceptions use code-driven SEH. ** EXT is mandatory on WIN64 since the calling convention has an abundance ** of callee-saved registers (rbx, rbp, rsi, rdi, r12-r15, xmm6-xmm15). ** The POSIX/x64 interpreter only saves r12/r13 for INT (e.g. PS4). @@ -63,7 +63,7 @@ #if defined(__GNUC__) && (LJ_TARGET_X64 || defined(LUAJIT_UNWIND_EXTERNAL)) && !LJ_NO_UNWIND #define LJ_UNWIND_EXT 1 -#elif LJ_TARGET_X64 && LJ_TARGET_WINDOWS +#elif LJ_TARGET_WINDOWS #define LJ_UNWIND_EXT 1 #endif @@ -384,7 +384,7 @@ static void err_raise_ext(int errcode) #endif /* LJ_TARGET_ARM */ -#elif LJ_TARGET_X64 && LJ_ABI_WIN +#elif LJ_ABI_WIN /* ** Someone in Redmond owes me several days of my life. A lot of this is @@ -402,6 +402,7 @@ static void err_raise_ext(int errcode) #define WIN32_LEAN_AND_MEAN #include <windows.h> +#if LJ_TARGET_X64 /* Taken from: http://www.nynaeve.net/?p=99 */ typedef struct UndocumentedDispatcherContext { ULONG64 ControlPc; @@ -416,11 +417,14 @@ typedef struct UndocumentedDispatcherContext { ULONG ScopeIndex; ULONG Fill0; } UndocumentedDispatcherContext; +#else +typedef void *UndocumentedDispatcherContext; +#endif /* Another wild guess. */ extern void __DestructExceptionObject(EXCEPTION_RECORD *rec, int nothrow); -#ifdef MINGW_SDK_INIT +#if LJ_TARGET_X64 && defined(MINGW_SDK_INIT) /* Workaround for broken MinGW64 declaration. */ VOID RtlUnwindEx_FIXED(PVOID,PVOID,PVOID,PVOID,PVOID,PVOID) asm("RtlUnwindEx"); #define RtlUnwindEx RtlUnwindEx_FIXED @@ -434,10 +438,15 @@ VOID RtlUnwindEx_FIXED(PVOID,PVOID,PVOID,PVOID,PVOID,PVOID) asm("RtlUnwindEx"); #define LJ_EXCODE_CHECK(cl) (((cl) ^ LJ_EXCODE) <= 0xff) #define LJ_EXCODE_ERRCODE(cl) ((int)((cl) & 0xff)) -/* Win64 exception handler for interpreter frame. */ -LJ_FUNCA EXCEPTION_DISPOSITION lj_err_unwind_win64(EXCEPTION_RECORD *rec, - void *cf, CONTEXT *ctx, UndocumentedDispatcherContext *dispatch) +/* Windows exception handler for interpreter frame. */ +LJ_FUNCA int lj_err_unwind_win(EXCEPTION_RECORD *rec, + void *f, CONTEXT *ctx, UndocumentedDispatcherContext *dispatch) { +#if LJ_TARGET_X64 + void *cf = f; +#else + void *cf = (char *)f - CFRAME_OFS_SEH; +#endif lua_State *L = cframe_L(cf); int errcode = LJ_EXCODE_CHECK(rec->ExceptionCode) ? LJ_EXCODE_ERRCODE(rec->ExceptionCode) : LUA_ERRRUN; @@ -455,8 +464,9 @@ LJ_FUNCA EXCEPTION_DISPOSITION lj_err_unwind_win64(EXCEPTION_RECORD *rec, setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRCPP)); } else if (!LJ_EXCODE_CHECK(rec->ExceptionCode)) { /* Don't catch access violations etc. */ - return ExceptionContinueSearch; + return 1; /* ExceptionContinueSearch */ } +#if LJ_TARGET_X64 /* Unwind the stack and call all handlers for all lower C frames ** (including ourselves) again with EH_UNWINDING set. Then set ** rsp = cf, rax = errcode and jump to the specified target. @@ -466,9 +476,21 @@ LJ_FUNCA EXCEPTION_DISPOSITION lj_err_unwind_win64(EXCEPTION_RECORD *rec, lj_vm_unwind_c_eh), rec, (void *)(uintptr_t)errcode, ctx, dispatch->HistoryTable); /* RtlUnwindEx should never return. */ +#else + UNUSED(ctx); + UNUSED(dispatch); + /* Call all handlers for all lower C frames (including ourselves) again + ** with EH_UNWINDING set. Then call the specified function, passing cf + ** and errcode. + */ + lj_vm_rtlunwind(cf, (void *)rec, + (cframe_unwind_ff(cf2) && errcode != LUA_YIELD) ? + (void *)lj_vm_unwind_ff : (void *)lj_vm_unwind_c, errcode); + /* lj_vm_rtlunwind does not return. */ +#endif } } - return ExceptionContinueSearch; + return 1; /* ExceptionContinueSearch */ } /* Raise Windows exception. */ @@ -487,7 +509,7 @@ LJ_NOINLINE void LJ_FASTCALL lj_err_throw(lua_State *L, int errcode) global_State *g = G(L); lj_trace_abort(g); setmref(g->jit_base, NULL); - L->status = 0; + L->status = LUA_OK; #if LJ_UNWIND_EXT err_raise_ext(errcode); /* diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_err.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_err.h index 6c7576137b5..cba5fb7149e 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_err.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_err.h @@ -1,6 +1,6 @@ /* ** Error handling. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_ERR_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_errmsg.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_errmsg.h index 0ed8f4e7398..060a9f89750 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_errmsg.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_errmsg.h @@ -1,6 +1,6 @@ /* ** VM error messages. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ /* This file may be included multiple times with different ERRDEF macros. */ diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_ff.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_ff.h index 9af3b12d265..31d65a00dba 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_ff.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_ff.h @@ -1,6 +1,6 @@ /* ** Fast function IDs. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_FF_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_ffrecord.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_ffrecord.c index d05dc5d710d..dfdee2dbfe1 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_ffrecord.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_ffrecord.c @@ -1,6 +1,6 @@ /* ** Fast function call recorder. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_ffrecord_c @@ -102,42 +102,41 @@ static void recff_stitch(jit_State *J) ASMFunction cont = lj_cont_stitch; lua_State *L = J->L; TValue *base = L->base; + BCReg nslot = J->maxslot + 1 + LJ_FR2; + TValue *nframe = base + 1 + LJ_FR2; const BCIns *pc = frame_pc(base-1); TValue *pframe = frame_prevl(base-1); - TRef trcont; - lua_assert(!LJ_FR2); /* TODO_FR2: handle frame shift. */ /* Move func + args up in Lua stack and insert continuation. */ - memmove(&base[1], &base[-1], sizeof(TValue)*(J->maxslot+1)); - setframe_ftsz(base+1, ((char *)(base+1) - (char *)pframe) + FRAME_CONT); - setcont(base, cont); + memmove(&base[1], &base[-1-LJ_FR2], sizeof(TValue)*nslot); + setframe_ftsz(nframe, ((char *)nframe - (char *)pframe) + FRAME_CONT); + setcont(base-LJ_FR2, cont); setframe_pc(base, pc); - setnilV(base-1); /* Incorrect, but rec_check_slots() won't run anymore. */ - L->base += 2; - L->top += 2; + setnilV(base-1-LJ_FR2); /* Incorrect, but rec_check_slots() won't run anymore. */ + L->base += 2 + LJ_FR2; + L->top += 2 + LJ_FR2; /* Ditto for the IR. */ - memmove(&J->base[1], &J->base[-1], sizeof(TRef)*(J->maxslot+1)); -#if LJ_64 - trcont = lj_ir_kptr(J, (void *)((int64_t)cont-(int64_t)lj_vm_asm_begin)); + memmove(&J->base[1], &J->base[-1-LJ_FR2], sizeof(TRef)*nslot); +#if LJ_FR2 + J->base[2] = TREF_FRAME; + J->base[-1] = lj_ir_k64(J, IR_KNUM, u64ptr(contptr(cont))); + J->base[0] = lj_ir_k64(J, IR_KNUM, u64ptr(pc)) | TREF_CONT; #else - trcont = lj_ir_kptr(J, (void *)cont); + J->base[0] = lj_ir_kptr(J, contptr(cont)) | TREF_CONT; #endif - J->base[0] = trcont | TREF_CONT; - J->ktracep = lj_ir_k64_reserve(J); - lua_assert(irt_toitype_(IRT_P64) == LJ_TTRACE); - J->base[-1] = emitir(IRT(IR_XLOAD, IRT_P64), lj_ir_kptr(J, &J->ktracep->gcr), 0); - J->base += 2; - J->baseslot += 2; + J->ktrace = tref_ref((J->base[-1-LJ_FR2] = lj_ir_ktrace(J))); + J->base += 2 + LJ_FR2; + J->baseslot += 2 + LJ_FR2; J->framedepth++; lj_record_stop(J, LJ_TRLINK_STITCH, 0); /* Undo Lua stack changes. */ - memmove(&base[-1], &base[1], sizeof(TValue)*(J->maxslot+1)); + memmove(&base[-1-LJ_FR2], &base[1], sizeof(TValue)*nslot); setframe_pc(base-1, pc); - L->base -= 2; - L->top -= 2; + L->base -= 2 + LJ_FR2; + L->top -= 2 + LJ_FR2; } /* Fallback handler for fast functions that are not recorded (yet). */ @@ -179,7 +178,7 @@ static void LJ_FASTCALL recff_nyi(jit_State *J, RecordFFData *rd) /* Emit BUFHDR for the global temporary buffer. */ static TRef recff_bufhdr(jit_State *J) { - return emitir(IRT(IR_BUFHDR, IRT_P32), + return emitir(IRT(IR_BUFHDR, IRT_PGC), lj_ir_kptr(J, &J2G(J)->tmpbuf), IRBUFHDR_RESET); } @@ -229,7 +228,7 @@ static void LJ_FASTCALL recff_setmetatable(jit_State *J, RecordFFData *rd) ix.tab = tr; copyTV(J->L, &ix.tabv, &rd->argv[0]); lj_record_mm_lookup(J, &ix, MM_metatable); /* Guard for no __metatable. */ - fref = emitir(IRT(IR_FREF, IRT_P32), tr, IRFL_TAB_META); + fref = emitir(IRT(IR_FREF, IRT_PGC), tr, IRFL_TAB_META); mtref = tref_isnil(mt) ? lj_ir_knull(J, IRT_TAB) : mt; emitir(IRT(IR_FSTORE, IRT_TAB), fref, mtref); if (!tref_isnil(mt)) @@ -295,7 +294,7 @@ int32_t lj_ffrecord_select_mode(jit_State *J, TRef tr, TValue *tv) if (strV(tv)->len == 1) { emitir(IRTG(IR_EQ, IRT_STR), tr, lj_ir_kstr(J, strV(tv))); } else { - TRef trptr = emitir(IRT(IR_STRREF, IRT_P32), tr, lj_ir_kint(J, 0)); + TRef trptr = emitir(IRT(IR_STRREF, IRT_PGC), tr, lj_ir_kint(J, 0)); TRef trchar = emitir(IRT(IR_XLOAD, IRT_U8), trptr, IRXLOAD_READONLY); emitir(IRTG(IR_EQ, IRT_INT), trchar, lj_ir_kint(J, '#')); } @@ -380,10 +379,10 @@ static int recff_metacall(jit_State *J, RecordFFData *rd, MMS mm) int errcode; TValue argv0; /* Temporarily insert metamethod below object. */ - J->base[1] = J->base[0]; + J->base[1+LJ_FR2] = J->base[0]; J->base[0] = ix.mobj; copyTV(J->L, &argv0, &rd->argv[0]); - copyTV(J->L, &rd->argv[1], &rd->argv[0]); + copyTV(J->L, &rd->argv[1+LJ_FR2], &rd->argv[0]); copyTV(J->L, &rd->argv[0], &ix.mobjv); /* Need to protect lj_record_tailcall because it may throw. */ errcode = lj_vm_cpcall(J->L, NULL, J, recff_metacall_cp); @@ -450,6 +449,10 @@ static void LJ_FASTCALL recff_xpairs(jit_State *J, RecordFFData *rd) static void LJ_FASTCALL recff_pcall(jit_State *J, RecordFFData *rd) { if (J->maxslot >= 1) { +#if LJ_FR2 + /* Shift function arguments up. */ + memmove(J->base + 1, J->base, sizeof(TRef) * J->maxslot); +#endif lj_record_call(J, 0, J->maxslot - 1); rd->nres = -1; /* Pending call. */ } /* else: Interpreter will throw. */ @@ -469,13 +472,16 @@ static void LJ_FASTCALL recff_xpcall(jit_State *J, RecordFFData *rd) TValue argv0, argv1; TRef tmp; int errcode; - lua_assert(!LJ_FR2); /* TODO_FR2: handle different frame setup. */ /* Swap function and traceback. */ tmp = J->base[0]; J->base[0] = J->base[1]; J->base[1] = tmp; copyTV(J->L, &argv0, &rd->argv[0]); copyTV(J->L, &argv1, &rd->argv[1]); copyTV(J->L, &rd->argv[0], &argv1); copyTV(J->L, &rd->argv[1], &argv0); +#if LJ_FR2 + /* Shift function arguments up. */ + memmove(J->base + 2, J->base + 1, sizeof(TRef) * (J->maxslot-1)); +#endif /* Need to protect lj_record_call because it may throw. */ errcode = lj_vm_cpcall(J->L, NULL, J, recff_xpcall_cp); /* Always undo Lua stack swap to avoid confusing the interpreter. */ @@ -504,7 +510,7 @@ static void LJ_FASTCALL recff_getfenv(jit_State *J, RecordFFData *rd) static void LJ_FASTCALL recff_math_abs(jit_State *J, RecordFFData *rd) { TRef tr = lj_ir_tonum(J, J->base[0]); - J->base[0] = emitir(IRTN(IR_ABS), tr, lj_ir_knum_abs(J)); + J->base[0] = emitir(IRTN(IR_ABS), tr, lj_ir_ksimd(J, LJ_KSIMD_ABS)); UNUSED(rd); } @@ -613,10 +619,8 @@ static void LJ_FASTCALL recff_math_modf(jit_State *J, RecordFFData *rd) static void LJ_FASTCALL recff_math_pow(jit_State *J, RecordFFData *rd) { - TRef tr = lj_ir_tonum(J, J->base[0]); - if (!tref_isnumber_str(J->base[1])) - lj_trace_err(J, LJ_TRERR_BADTYPE); - J->base[0] = lj_opt_narrow_pow(J, tr, J->base[1], &rd->argv[1]); + J->base[0] = lj_opt_narrow_pow(J, J->base[0], J->base[1], + &rd->argv[0], &rd->argv[1]); UNUSED(rd); } @@ -822,7 +826,7 @@ static void LJ_FASTCALL recff_string_range(jit_State *J, RecordFFData *rd) /* Also handle empty range here, to avoid extra traces. */ TRef trptr, trslen = emitir(IRTI(IR_SUB), trend, trstart); emitir(IRTGI(IR_GE), trslen, tr0); - trptr = emitir(IRT(IR_STRREF, IRT_P32), trstr, trstart); + trptr = emitir(IRT(IR_STRREF, IRT_PGC), trstr, trstart); J->base[0] = emitir(IRT(IR_SNEW, IRT_STR), trptr, trslen); } else { /* Range underflow: return empty string. */ emitir(IRTGI(IR_LT), trend, trstart); @@ -838,7 +842,7 @@ static void LJ_FASTCALL recff_string_range(jit_State *J, RecordFFData *rd) rd->nres = len; for (i = 0; i < len; i++) { TRef tmp = emitir(IRTI(IR_ADD), trstart, lj_ir_kint(J, (int32_t)i)); - tmp = emitir(IRT(IR_STRREF, IRT_P32), trstr, tmp); + tmp = emitir(IRT(IR_STRREF, IRT_PGC), trstr, tmp); J->base[i] = emitir(IRT(IR_XLOAD, IRT_U8), tmp, IRXLOAD_READONLY); } } else { /* Empty range or range underflow: return no results. */ @@ -860,7 +864,7 @@ static void LJ_FASTCALL recff_string_char(jit_State *J, RecordFFData *rd) if (i > 1) { /* Concatenate the strings, if there's more than one. */ TRef hdr = recff_bufhdr(J), tr = hdr; for (i = 0; J->base[i] != 0; i++) - tr = emitir(IRT(IR_BUFPUT, IRT_P32), tr, J->base[i]); + tr = emitir(IRT(IR_BUFPUT, IRT_PGC), tr, J->base[i]); J->base[0] = emitir(IRT(IR_BUFSTR, IRT_STR), tr, hdr); } UNUSED(rd); @@ -877,14 +881,14 @@ static void LJ_FASTCALL recff_string_rep(jit_State *J, RecordFFData *rd) emitir(IRTGI(vrep > 1 ? IR_GT : IR_LE), rep, lj_ir_kint(J, 1)); if (vrep > 1) { TRef hdr2 = recff_bufhdr(J); - TRef tr2 = emitir(IRT(IR_BUFPUT, IRT_P32), hdr2, sep); - tr2 = emitir(IRT(IR_BUFPUT, IRT_P32), tr2, str); + TRef tr2 = emitir(IRT(IR_BUFPUT, IRT_PGC), hdr2, sep); + tr2 = emitir(IRT(IR_BUFPUT, IRT_PGC), tr2, str); str2 = emitir(IRT(IR_BUFSTR, IRT_STR), tr2, hdr2); } } tr = hdr = recff_bufhdr(J); if (str2) { - tr = emitir(IRT(IR_BUFPUT, IRT_P32), tr, str); + tr = emitir(IRT(IR_BUFPUT, IRT_PGC), tr, str); str = str2; rep = emitir(IRTI(IR_ADD), rep, lj_ir_kint(J, -1)); } @@ -935,8 +939,8 @@ static void LJ_FASTCALL recff_string_find(jit_State *J, RecordFFData *rd) if ((J->base[2] && tref_istruecond(J->base[3])) || (emitir(IRTG(IR_EQ, IRT_STR), trpat, lj_ir_kstr(J, pat)), !lj_str_haspattern(pat))) { /* Search for fixed string. */ - TRef trsptr = emitir(IRT(IR_STRREF, IRT_P32), trstr, trstart); - TRef trpptr = emitir(IRT(IR_STRREF, IRT_P32), trpat, tr0); + TRef trsptr = emitir(IRT(IR_STRREF, IRT_PGC), trstr, trstart); + TRef trpptr = emitir(IRT(IR_STRREF, IRT_PGC), trpat, tr0); TRef trslen = emitir(IRTI(IR_SUB), trlen, trstart); TRef trplen = emitir(IRTI(IR_FLOAD), trpat, IRFL_STR_LEN); TRef tr = lj_ir_call(J, IRCALL_lj_str_find, trsptr, trpptr, trslen, trplen); @@ -944,13 +948,13 @@ static void LJ_FASTCALL recff_string_find(jit_State *J, RecordFFData *rd) if (lj_str_find(strdata(str)+(MSize)start, strdata(pat), str->len-(MSize)start, pat->len)) { TRef pos; - emitir(IRTG(IR_NE, IRT_P32), tr, trp0); - pos = emitir(IRTI(IR_SUB), tr, emitir(IRT(IR_STRREF, IRT_P32), trstr, tr0)); + emitir(IRTG(IR_NE, IRT_PGC), tr, trp0); + pos = emitir(IRTI(IR_SUB), tr, emitir(IRT(IR_STRREF, IRT_PGC), trstr, tr0)); J->base[0] = emitir(IRTI(IR_ADD), pos, lj_ir_kint(J, 1)); J->base[1] = emitir(IRTI(IR_ADD), pos, trplen); rd->nres = 2; } else { - emitir(IRTG(IR_EQ, IRT_P32), tr, trp0); + emitir(IRTG(IR_EQ, IRT_PGC), tr, trp0); J->base[0] = TREF_NIL; } } else { /* Search for pattern. */ @@ -977,7 +981,7 @@ static void LJ_FASTCALL recff_string_format(jit_State *J, RecordFFData *rd) IRCallID id; switch (STRFMT_TYPE(sf)) { case STRFMT_LIT: - tr = emitir(IRT(IR_BUFPUT, IRT_P32), tr, + tr = emitir(IRT(IR_BUFPUT, IRT_PGC), tr, lj_ir_kstr(J, lj_str_new(J->L, fs.str, fs.len))); break; case STRFMT_INT: @@ -986,7 +990,7 @@ static void LJ_FASTCALL recff_string_format(jit_State *J, RecordFFData *rd) if (!tref_isinteger(tra)) goto handle_num; if (sf == STRFMT_INT) { /* Shortcut for plain %d. */ - tr = emitir(IRT(IR_BUFPUT, IRT_P32), tr, + tr = emitir(IRT(IR_BUFPUT, IRT_PGC), tr, emitir(IRT(IR_TOSTR, IRT_STR), tra, IRTOSTR_INT)); } else { #if LJ_HASFFI @@ -1016,7 +1020,7 @@ static void LJ_FASTCALL recff_string_format(jit_State *J, RecordFFData *rd) return; } if (sf == STRFMT_STR) /* Shortcut for plain %s. */ - tr = emitir(IRT(IR_BUFPUT, IRT_P32), tr, tra); + tr = emitir(IRT(IR_BUFPUT, IRT_PGC), tr, tra); else if ((sf & STRFMT_T_QUOTED)) tr = lj_ir_call(J, IRCALL_lj_strfmt_putquoted, tr, tra); else @@ -1025,7 +1029,7 @@ static void LJ_FASTCALL recff_string_format(jit_State *J, RecordFFData *rd) case STRFMT_CHAR: tra = lj_opt_narrow_toint(J, tra); if (sf == STRFMT_CHAR) /* Shortcut for plain %c. */ - tr = emitir(IRT(IR_BUFPUT, IRT_P32), tr, + tr = emitir(IRT(IR_BUFPUT, IRT_PGC), tr, emitir(IRT(IR_TOSTR, IRT_STR), tra, IRTOSTR_CHAR)); else tr = lj_ir_call(J, IRCALL_lj_strfmt_putfchar, tr, trsf, tra); @@ -1110,8 +1114,13 @@ static TRef recff_io_fp(jit_State *J, TRef *udp, int32_t id) { TRef tr, ud, fp; if (id) { /* io.func() */ +#if LJ_GC64 + /* TODO: fix ARM32 asm_fload(), so we can use this for all archs. */ + ud = lj_ir_ggfload(J, IRT_UDATA, GG_OFS(g.gcroot[id])); +#else tr = lj_ir_kptr(J, &J2G(J)->gcroot[id]); ud = emitir(IRT(IR_XLOAD, IRT_UDATA), tr, 0); +#endif } else { /* fp:method() */ ud = J->base[0]; if (!tref_isudata(ud)) @@ -1133,7 +1142,7 @@ static void LJ_FASTCALL recff_io_write(jit_State *J, RecordFFData *rd) ptrdiff_t i = rd->data == 0 ? 1 : 0; for (; J->base[i]; i++) { TRef str = lj_ir_tostr(J, J->base[i]); - TRef buf = emitir(IRT(IR_STRREF, IRT_P32), str, zero); + TRef buf = emitir(IRT(IR_STRREF, IRT_PGC), str, zero); TRef len = emitir(IRTI(IR_FLOAD), str, IRFL_STR_LEN); if (tref_isk(len) && IR(tref_ref(len))->i == 1) { IRIns *irs = IR(tref_ref(str)); diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_ffrecord.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_ffrecord.h index 7a188beb298..3b407450d58 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_ffrecord.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_ffrecord.h @@ -1,6 +1,6 @@ /* ** Fast function call recorder. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_FFRECORD_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_frame.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_frame.h index fc0e281c2e0..19c49a4aef4 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_frame.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_frame.h @@ -1,6 +1,6 @@ /* ** Stack frames. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_FRAME_H @@ -116,6 +116,17 @@ enum { LJ_CONT_TAILCALL, LJ_CONT_FFI_CALLBACK }; /* Special continuations. */ /* These definitions must match with the arch-specific *.dasc files. */ #if LJ_TARGET_X86 +#if LJ_ABI_WIN +#define CFRAME_OFS_ERRF (19*4) +#define CFRAME_OFS_NRES (18*4) +#define CFRAME_OFS_PREV (17*4) +#define CFRAME_OFS_L (16*4) +#define CFRAME_OFS_SEH (9*4) +#define CFRAME_OFS_PC (6*4) +#define CFRAME_OFS_MULTRES (5*4) +#define CFRAME_SIZE (16*4) +#define CFRAME_SHIFT_MULTRES 0 +#else #define CFRAME_OFS_ERRF (15*4) #define CFRAME_OFS_NRES (14*4) #define CFRAME_OFS_PREV (13*4) @@ -124,6 +135,7 @@ enum { LJ_CONT_TAILCALL, LJ_CONT_FFI_CALLBACK }; /* Special continuations. */ #define CFRAME_OFS_MULTRES (5*4) #define CFRAME_SIZE (12*4) #define CFRAME_SHIFT_MULTRES 0 +#endif #elif LJ_TARGET_X64 #if LJ_ABI_WIN #define CFRAME_OFS_PREV (13*8) @@ -217,26 +229,41 @@ enum { LJ_CONT_TAILCALL, LJ_CONT_FFI_CALLBACK }; /* Special continuations. */ #define CFRAME_SIZE 272 #define CFRAME_SHIFT_MULTRES 3 #endif -#elif LJ_TARGET_MIPS +#elif LJ_TARGET_MIPS32 #if LJ_ARCH_HASFPU #define CFRAME_OFS_ERRF 124 #define CFRAME_OFS_NRES 120 #define CFRAME_OFS_PREV 116 #define CFRAME_OFS_L 112 -#define CFRAME_OFS_PC 20 -#define CFRAME_OFS_MULTRES 16 #define CFRAME_SIZE 112 -#define CFRAME_SHIFT_MULTRES 3 #else #define CFRAME_OFS_ERRF 76 #define CFRAME_OFS_NRES 72 #define CFRAME_OFS_PREV 68 #define CFRAME_OFS_L 64 +#define CFRAME_SIZE 64 +#endif #define CFRAME_OFS_PC 20 #define CFRAME_OFS_MULTRES 16 -#define CFRAME_SIZE 64 #define CFRAME_SHIFT_MULTRES 3 +#elif LJ_TARGET_MIPS64 +#if LJ_ARCH_HASFPU +#define CFRAME_OFS_ERRF 188 +#define CFRAME_OFS_NRES 184 +#define CFRAME_OFS_PREV 176 +#define CFRAME_OFS_L 168 +#define CFRAME_OFS_PC 160 +#define CFRAME_SIZE 192 +#else +#define CFRAME_OFS_ERRF 124 +#define CFRAME_OFS_NRES 120 +#define CFRAME_OFS_PREV 112 +#define CFRAME_OFS_L 104 +#define CFRAME_OFS_PC 96 +#define CFRAME_SIZE 128 #endif +#define CFRAME_OFS_MULTRES 0 +#define CFRAME_SHIFT_MULTRES 3 #else #error "Missing CFRAME_* definitions for this architecture" #endif diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_func.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_func.c index 431a56d76df..639dad87684 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_func.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_func.c @@ -1,6 +1,6 @@ /* ** Function handling (prototypes, functions and upvalues). -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h ** ** Portions taken verbatim or adapted from the Lua interpreter. ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h @@ -140,7 +140,9 @@ GCfunc *lj_func_newL_empty(lua_State *L, GCproto *pt, GCtab *env) /* NOBARRIER: The GCfunc is new (marked white). */ for (i = 0; i < nuv; i++) { GCupval *uv = func_emptyuv(L); - uv->dhash = (uint32_t)(uintptr_t)pt ^ ((uint32_t)proto_uv(pt)[i] << 24); + int32_t v = proto_uv(pt)[i]; + uv->immutable = ((v / PROTO_UV_IMMUTABLE) & 1); + uv->dhash = (uint32_t)(uintptr_t)pt ^ (v << 24); setgcref(fn->l.uvptr[i], obj2gco(uv)); } fn->l.nupvalues = (uint8_t)nuv; diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_func.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_func.h index e0c3c555ed3..901751b9813 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_func.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_func.h @@ -1,6 +1,6 @@ /* ** Function handling (prototypes, functions and upvalues). -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_FUNC_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_gc.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_gc.c index 53f1d974cf3..2aaf5b2c4f7 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_gc.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_gc.c @@ -1,6 +1,6 @@ /* ** Garbage collector. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h ** ** Major portions taken verbatim or adapted from the Lua interpreter. ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h @@ -169,12 +169,19 @@ static int gc_traverse_tab(global_State *g, GCtab *t) while ((c = *modestr++)) { if (c == 'k') weak |= LJ_GC_WEAKKEY; else if (c == 'v') weak |= LJ_GC_WEAKVAL; - else if (c == 'K') weak = (int)(~0u & ~LJ_GC_WEAKVAL); } - if (weak > 0) { /* Weak tables are cleared in the atomic phase. */ - t->marked = (uint8_t)((t->marked & ~LJ_GC_WEAK) | weak); - setgcrefr(t->gclist, g->gc.weak); - setgcref(g->gc.weak, obj2gco(t)); + if (weak) { /* Weak tables are cleared in the atomic phase. */ +#if LJ_HASFFI + CTState *cts = ctype_ctsG(g); + if (cts && cts->finalizer == t) { + weak = (int)(~0u & ~LJ_GC_WEAKVAL); + } else +#endif + { + t->marked = (uint8_t)((t->marked & ~LJ_GC_WEAK) | weak); + setgcrefr(t->gclist, g->gc.weak); + setgcref(g->gc.weak, obj2gco(t)); + } } } if (weak == LJ_GC_WEAK) /* Nothing to mark if both keys/values are weak. */ @@ -238,6 +245,8 @@ static void gc_traverse_trace(global_State *g, GCtrace *T) IRIns *ir = &T->ir[ref]; if (ir->o == IR_KGC) gc_markobj(g, ir_kgc(ir)); + if (irt_is64(ir->t) && ir->o != IR_KNULL) + ref++; } if (T->link) gc_marktrace(g, T->link); if (T->nextroot) gc_marktrace(g, T->nextroot); @@ -308,7 +317,7 @@ static size_t propagatemark(global_State *g) if (gc_traverse_tab(g, t) > 0) black2gray(o); /* Keep weak tables gray. */ return sizeof(GCtab) + sizeof(TValue) * t->asize + - sizeof(Node) * (t->hmask + 1); + (t->hmask ? sizeof(Node) * (t->hmask + 1) : 0); } else if (LJ_LIKELY(gct == ~LJ_TFUNC)) { GCfunc *fn = gco2func(o); gc_traverse_func(g, fn); diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_gc.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_gc.h index eee09afb5a5..669bbe92403 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_gc.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_gc.h @@ -1,6 +1,6 @@ /* ** Garbage collector. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_GC_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_gdbjit.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_gdbjit.c index f2bd865e600..c219ffac0a8 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_gdbjit.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_gdbjit.c @@ -1,6 +1,6 @@ /* ** Client for the GDB JIT API. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_gdbjit_c @@ -296,6 +296,9 @@ enum { #elif LJ_TARGET_ARM DW_REG_SP = 13, DW_REG_RA = 14, +#elif LJ_TARGET_ARM64 + DW_REG_SP = 31, + DW_REG_RA = 30, #elif LJ_TARGET_PPC DW_REG_SP = 1, DW_REG_RA = 65, @@ -374,6 +377,8 @@ static const ELFheader elfhdr_template = { .machine = 62, #elif LJ_TARGET_ARM .machine = 40, +#elif LJ_TARGET_ARM64 + .machine = 183, #elif LJ_TARGET_PPC .machine = 20, #elif LJ_TARGET_MIPS @@ -563,6 +568,13 @@ static void LJ_FASTCALL gdbjit_ehframe(GDBJITctx *ctx) int i; for (i = 11; i >= 4; i--) { DB(DW_CFA_offset|i); DUV(2+(11-i)); } } +#elif LJ_TARGET_ARM64 + { + int i; + DB(DW_CFA_offset|31); DUV(2); + for (i = 28; i >= 19; i--) { DB(DW_CFA_offset|i); DUV(3+(28-i)); } + for (i = 15; i >= 8; i--) { DB(DW_CFA_offset|32|i); DUV(28-i); } + } #elif LJ_TARGET_PPC { int i; @@ -719,6 +731,20 @@ static void gdbjit_buildobj(GDBJITctx *ctx) /* -- Interface to GDB JIT API -------------------------------------------- */ +static int gdbjit_lock; + +static void gdbjit_lock_acquire() +{ + while (__sync_lock_test_and_set(&gdbjit_lock, 1)) { + /* Just spin; futexes or pthreads aren't worth the portability cost. */ + } +} + +static void gdbjit_lock_release() +{ + __sync_lock_release(&gdbjit_lock); +} + /* Add new entry to GDB JIT symbol chain. */ static void gdbjit_newentry(lua_State *L, GDBJITctx *ctx) { @@ -730,6 +756,7 @@ static void gdbjit_newentry(lua_State *L, GDBJITctx *ctx) ctx->T->gdbjit_entry = (void *)eo; /* Link new entry to chain and register it. */ eo->entry.prev_entry = NULL; + gdbjit_lock_acquire(); eo->entry.next_entry = __jit_debug_descriptor.first_entry; if (eo->entry.next_entry) eo->entry.next_entry->prev_entry = &eo->entry; @@ -739,6 +766,7 @@ static void gdbjit_newentry(lua_State *L, GDBJITctx *ctx) __jit_debug_descriptor.relevant_entry = &eo->entry; __jit_debug_descriptor.action_flag = GDBJIT_REGISTER; __jit_debug_register_code(); + gdbjit_lock_release(); } /* Add debug info for newly compiled trace and notify GDB. */ @@ -770,6 +798,7 @@ void lj_gdbjit_deltrace(jit_State *J, GCtrace *T) { GDBJITentryobj *eo = (GDBJITentryobj *)T->gdbjit_entry; if (eo) { + gdbjit_lock_acquire(); if (eo->entry.prev_entry) eo->entry.prev_entry->next_entry = eo->entry.next_entry; else @@ -779,6 +808,7 @@ void lj_gdbjit_deltrace(jit_State *J, GCtrace *T) __jit_debug_descriptor.relevant_entry = &eo->entry; __jit_debug_descriptor.action_flag = GDBJIT_UNREGISTER; __jit_debug_register_code(); + gdbjit_lock_release(); lj_mem_free(J2G(J), eo, eo->sz); } } diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_gdbjit.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_gdbjit.h index 1043bc69862..bbaa1568c44 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_gdbjit.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_gdbjit.h @@ -1,6 +1,6 @@ /* ** Client for the GDB JIT API. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_GDBJIT_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_ir.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_ir.c index 63c9825475f..5baece67e63 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_ir.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_ir.c @@ -1,6 +1,6 @@ /* ** SSA IR (Intermediate Representation) emitter. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_ir_c @@ -91,7 +91,7 @@ static void lj_ir_growbot(jit_State *J) IRIns *baseir = J->irbuf + J->irbotlim; MSize szins = J->irtoplim - J->irbotlim; lua_assert(szins != 0); - lua_assert(J->cur.nk == J->irbotlim); + lua_assert(J->cur.nk == J->irbotlim || J->cur.nk-1 == J->irbotlim); if (J->cur.nins + (szins >> 1) < J->irtoplim) { /* More than half of the buffer is free on top: shift up by a quarter. */ MSize ofs = szins >> 2; @@ -145,6 +145,16 @@ TRef lj_ir_call(jit_State *J, IRCallID id, ...) return emitir(CCI_OPTYPE(ci), tr, id); } +/* Load field of type t from GG_State + offset. Must be 32 bit aligned. */ +LJ_FUNC TRef lj_ir_ggfload(jit_State *J, IRType t, uintptr_t ofs) +{ + lua_assert((ofs & 3) == 0); + ofs >>= 2; + lua_assert(ofs >= IRFL__MAX && ofs <= 0x3ff); /* 10 bit FOLD key limit. */ + lj_ir_set(J, IRT(IR_FLOAD, t), REF_NIL, ofs); + return lj_opt_fold(J); +} + /* -- Interning of constants ---------------------------------------------- */ /* @@ -165,6 +175,24 @@ static LJ_AINLINE IRRef ir_nextk(jit_State *J) return ref; } +/* Get ref of next 64 bit IR constant and optionally grow IR. +** Note: this may invalidate all IRIns *! +*/ +static LJ_AINLINE IRRef ir_nextk64(jit_State *J) +{ + IRRef ref = J->cur.nk - 2; + lua_assert(J->state != LJ_TRACE_ASM); + if (LJ_UNLIKELY(ref < J->irbotlim)) lj_ir_growbot(J); + J->cur.nk = ref; + return ref; +} + +#if LJ_GC64 +#define ir_nextkgc ir_nextk64 +#else +#define ir_nextkgc ir_nextk +#endif + /* Intern int32_t constant. */ TRef LJ_FASTCALL lj_ir_kint(jit_State *J, int32_t k) { @@ -184,95 +212,21 @@ found: return TREF(ref, IRT_INT); } -/* The MRef inside the KNUM/KINT64 IR instructions holds the address of the -** 64 bit constant. The constants themselves are stored in a chained array -** and shared across traces. -** -** Rationale for choosing this data structure: -** - The address of the constants is embedded in the generated machine code -** and must never move. A resizable array or hash table wouldn't work. -** - Most apps need very few non-32 bit integer constants (less than a dozen). -** - Linear search is hard to beat in terms of speed and low complexity. -*/ -typedef struct K64Array { - MRef next; /* Pointer to next list. */ - MSize numk; /* Number of used elements in this array. */ - TValue k[LJ_MIN_K64SZ]; /* Array of constants. */ -} K64Array; - -/* Free all chained arrays. */ -void lj_ir_k64_freeall(jit_State *J) -{ - K64Array *k; - for (k = mref(J->k64, K64Array); k; ) { - K64Array *next = mref(k->next, K64Array); - lj_mem_free(J2G(J), k, sizeof(K64Array)); - k = next; - } - setmref(J->k64, NULL); -} - -/* Get new 64 bit constant slot. */ -static TValue *ir_k64_add(jit_State *J, K64Array *kp, uint64_t u64) -{ - TValue *ntv; - if (!(kp && kp->numk < LJ_MIN_K64SZ)) { /* Allocate a new array. */ - K64Array *kn = lj_mem_newt(J->L, sizeof(K64Array), K64Array); - setmref(kn->next, NULL); - kn->numk = 0; - if (kp) - setmref(kp->next, kn); /* Chain to the end of the list. */ - else - setmref(J->k64, kn); /* Link first array. */ - kp = kn; - } - ntv = &kp->k[kp->numk++]; /* Add to current array. */ - ntv->u64 = u64; - return ntv; -} - -/* Find 64 bit constant in chained array or add it. */ -cTValue *lj_ir_k64_find(jit_State *J, uint64_t u64) -{ - K64Array *k, *kp = NULL; - MSize idx; - /* Search for the constant in the whole chain of arrays. */ - for (k = mref(J->k64, K64Array); k; k = mref(k->next, K64Array)) { - kp = k; /* Remember previous element in list. */ - for (idx = 0; idx < k->numk; idx++) { /* Search one array. */ - TValue *tv = &k->k[idx]; - if (tv->u64 == u64) /* Needed for +-0/NaN/absmask. */ - return tv; - } - } - /* Otherwise add a new constant. */ - return ir_k64_add(J, kp, u64); -} - -TValue *lj_ir_k64_reserve(jit_State *J) -{ - K64Array *k, *kp = NULL; - lj_ir_k64_find(J, 0); /* Intern dummy 0 to protect the reserved slot. */ - /* Find last K64Array, if any. */ - for (k = mref(J->k64, K64Array); k; k = mref(k->next, K64Array)) kp = k; - return ir_k64_add(J, kp, 0); /* Set to 0. Final value is set later. */ -} - -/* Intern 64 bit constant, given by its address. */ -TRef lj_ir_k64(jit_State *J, IROp op, cTValue *tv) +/* Intern 64 bit constant, given by its 64 bit pattern. */ +TRef lj_ir_k64(jit_State *J, IROp op, uint64_t u64) { IRIns *ir, *cir = J->cur.ir; IRRef ref; IRType t = op == IR_KNUM ? IRT_NUM : IRT_I64; for (ref = J->chain[op]; ref; ref = cir[ref].prev) - if (ir_k64(&cir[ref]) == tv) + if (ir_k64(&cir[ref])->u64 == u64) goto found; - ref = ir_nextk(J); + ref = ir_nextk64(J); ir = IR(ref); - lua_assert(checkptrGC(tv)); - setmref(ir->ptr, tv); + ir[1].tv.u64 = u64; ir->t.irt = t; ir->o = op; + ir->op12 = 0; ir->prev = J->chain[op]; J->chain[op] = (IRRef1)ref; found: @@ -282,13 +236,13 @@ found: /* Intern FP constant, given by its 64 bit pattern. */ TRef lj_ir_knum_u64(jit_State *J, uint64_t u64) { - return lj_ir_k64(J, IR_KNUM, lj_ir_k64_find(J, u64)); + return lj_ir_k64(J, IR_KNUM, u64); } /* Intern 64 bit integer constant. */ TRef lj_ir_kint64(jit_State *J, uint64_t u64) { - return lj_ir_k64(J, IR_KINT64, lj_ir_k64_find(J, u64)); + return lj_ir_k64(J, IR_KINT64, u64); } /* Check whether a number is int and return it. -0 is NOT considered an int. */ @@ -323,15 +277,15 @@ TRef lj_ir_kgc(jit_State *J, GCobj *o, IRType t) { IRIns *ir, *cir = J->cur.ir; IRRef ref; - lua_assert(!LJ_GC64); /* TODO_GC64: major changes required. */ lua_assert(!isdead(J2G(J), o)); for (ref = J->chain[IR_KGC]; ref; ref = cir[ref].prev) if (ir_kgc(&cir[ref]) == o) goto found; - ref = ir_nextk(J); + ref = ir_nextkgc(J); ir = IR(ref); /* NOBARRIER: Current trace is a GC root. */ - setgcref(ir->gcr, o); + ir->op12 = 0; + setgcref(ir[LJ_GC64].gcr, o); ir->t.irt = (uint8_t)t; ir->o = IR_KGC; ir->prev = J->chain[IR_KGC]; @@ -340,24 +294,44 @@ found: return TREF(ref, t); } -/* Intern 32 bit pointer constant. */ +/* Allocate GCtrace constant placeholder (no interning). */ +TRef lj_ir_ktrace(jit_State *J) +{ + IRRef ref = ir_nextkgc(J); + IRIns *ir = IR(ref); + lua_assert(irt_toitype_(IRT_P64) == LJ_TTRACE); + ir->t.irt = IRT_P64; + ir->o = LJ_GC64 ? IR_KNUM : IR_KNULL; /* Not IR_KGC yet, but same size. */ + ir->op12 = 0; + ir->prev = 0; + return TREF(ref, IRT_P64); +} + +/* Intern pointer constant. */ TRef lj_ir_kptr_(jit_State *J, IROp op, void *ptr) { IRIns *ir, *cir = J->cur.ir; IRRef ref; - lua_assert((void *)(intptr_t)i32ptr(ptr) == ptr); +#if LJ_64 && !LJ_GC64 + lua_assert((void *)(uintptr_t)u32ptr(ptr) == ptr); +#endif for (ref = J->chain[op]; ref; ref = cir[ref].prev) - if (mref(cir[ref].ptr, void) == ptr) + if (ir_kptr(&cir[ref]) == ptr) goto found; +#if LJ_GC64 + ref = ir_nextk64(J); +#else ref = ir_nextk(J); +#endif ir = IR(ref); - setmref(ir->ptr, ptr); - ir->t.irt = IRT_P32; + ir->op12 = 0; + setmref(ir[LJ_GC64].ptr, ptr); + ir->t.irt = IRT_PGC; ir->o = op; ir->prev = J->chain[op]; J->chain[op] = (IRRef1)ref; found: - return TREF(ref, IRT_P32); + return TREF(ref, IRT_PGC); } /* Intern typed NULL constant. */ @@ -412,9 +386,8 @@ void lj_ir_kvalue(lua_State *L, TValue *tv, const IRIns *ir) case IR_KPRI: setpriV(tv, irt_toitype(ir->t)); break; case IR_KINT: setintV(tv, ir->i); break; case IR_KGC: setgcV(L, tv, ir_kgc(ir), irt_toitype(ir->t)); break; - case IR_KPTR: case IR_KKPTR: case IR_KNULL: - setlightudV(tv, mref(ir->ptr, void)); - break; + case IR_KPTR: case IR_KKPTR: setlightudV(tv, ir_kptr(ir)); break; + case IR_KNULL: setlightudV(tv, NULL); break; case IR_KNUM: setnumV(tv, ir_knum(ir)->n); break; #if LJ_HASFFI case IR_KINT64: { diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_ir.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_ir.h index cd8df59d39d..34c27853948 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_ir.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_ir.h @@ -1,6 +1,6 @@ /* ** SSA IR (Intermediate Representation) format. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_IR_H @@ -220,7 +220,7 @@ IRFLDEF(FLENUM) /* SLOAD mode bits, stored in op2. */ #define IRSLOAD_PARENT 0x01 /* Coalesce with parent trace. */ -#define IRSLOAD_FRAME 0x02 /* Load hiword of frame. */ +#define IRSLOAD_FRAME 0x02 /* Load 32 bits of ftsz. */ #define IRSLOAD_TYPECHECK 0x04 /* Needs type check. */ #define IRSLOAD_CONVERT 0x08 /* Number to integer conversion. */ #define IRSLOAD_READONLY 0x10 /* Read-only, omit slot store. */ @@ -294,7 +294,9 @@ LJ_DATA const uint8_t lj_ir_mode[IR__MAX+1]; /* -- IR instruction types ------------------------------------------------ */ -/* Map of itypes to non-negative numbers. ORDER LJ_T. +#define IRTSIZE_PGC (LJ_GC64 ? 8 : 4) + +/* Map of itypes to non-negative numbers and their sizes. ORDER LJ_T. ** LJ_TUPVAL/LJ_TTRACE never appear in a TValue. Use these itypes for ** IRT_P32 and IRT_P64, which never escape the IR. ** The various integers are only used in the IR and can only escape to @@ -302,12 +304,13 @@ LJ_DATA const uint8_t lj_ir_mode[IR__MAX+1]; ** contiguous and next to IRT_NUM (see the typerange macros below). */ #define IRTDEF(_) \ - _(NIL, 4) _(FALSE, 4) _(TRUE, 4) _(LIGHTUD, LJ_64 ? 8 : 4) _(STR, 4) \ - _(P32, 4) _(THREAD, 4) _(PROTO, 4) _(FUNC, 4) _(P64, 8) _(CDATA, 4) \ - _(TAB, 4) _(UDATA, 4) \ + _(NIL, 4) _(FALSE, 4) _(TRUE, 4) _(LIGHTUD, LJ_64 ? 8 : 4) \ + _(STR, IRTSIZE_PGC) _(P32, 4) _(THREAD, IRTSIZE_PGC) _(PROTO, IRTSIZE_PGC) \ + _(FUNC, IRTSIZE_PGC) _(P64, 8) _(CDATA, IRTSIZE_PGC) _(TAB, IRTSIZE_PGC) \ + _(UDATA, IRTSIZE_PGC) \ _(FLOAT, 4) _(NUM, 8) _(I8, 1) _(U8, 1) _(I16, 2) _(U16, 2) \ _(INT, 4) _(U32, 4) _(I64, 8) _(U64, 8) \ - _(SOFTFP, 4) /* There is room for 9 more types. */ + _(SOFTFP, 4) /* There is room for 8 more types. */ /* IR result type and flags (8 bit). */ typedef enum { @@ -318,9 +321,10 @@ IRTDEF(IRTENUM) /* Native pointer type and the corresponding integer type. */ IRT_PTR = LJ_64 ? IRT_P64 : IRT_P32, + IRT_PGC = LJ_GC64 ? IRT_P64 : IRT_P32, + IRT_IGC = LJ_GC64 ? IRT_I64 : IRT_INT, IRT_INTP = LJ_64 ? IRT_I64 : IRT_INT, IRT_UINTP = LJ_64 ? IRT_U64 : IRT_U32, - /* TODO_GC64: major changes required for all uses of IRT_P32. */ /* Additional flags. */ IRT_MARK = 0x20, /* Marker for misc. purposes. */ @@ -408,7 +412,7 @@ static LJ_AINLINE IRType itype2irt(const TValue *tv) static LJ_AINLINE uint32_t irt_toitype_(IRType t) { - lua_assert(!LJ_64 || t != IRT_LIGHTUD); + lua_assert(!LJ_64 || LJ_GC64 || t != IRT_LIGHTUD); if (LJ_DUALNUM && t > IRT_NUM) { return LJ_TISNUM; } else { @@ -521,7 +525,9 @@ typedef uint32_t TRef; ** +-------+-------+---+---+---+---+ ** | op1 | op2 | t | o | r | s | ** +-------+-------+---+---+---+---+ -** | op12/i/gco | ot | prev | (alternative fields in union) +** | op12/i/gco32 | ot | prev | (alternative fields in union) +** +-------+-------+---+---+---+---+ +** | TValue/gco64 | (2nd IR slot for 64 bit constants) ** +---------------+-------+-------+ ** 32 16 16 ** @@ -549,22 +555,27 @@ typedef union IRIns { ) }; int32_t i; /* 32 bit signed integer literal (overlaps op12). */ - GCRef gcr; /* GCobj constant (overlaps op12). */ - MRef ptr; /* Pointer constant (overlaps op12). */ + GCRef gcr; /* GCobj constant (overlaps op12 or entire slot). */ + MRef ptr; /* Pointer constant (overlaps op12 or entire slot). */ + TValue tv; /* TValue constant (overlaps entire slot). */ } IRIns; -/* TODO_GC64: major changes required. */ -#define ir_kgc(ir) check_exp((ir)->o == IR_KGC, gcref((ir)->gcr)) +#define ir_kgc(ir) check_exp((ir)->o == IR_KGC, gcref((ir)[LJ_GC64].gcr)) #define ir_kstr(ir) (gco2str(ir_kgc((ir)))) #define ir_ktab(ir) (gco2tab(ir_kgc((ir)))) #define ir_kfunc(ir) (gco2func(ir_kgc((ir)))) #define ir_kcdata(ir) (gco2cd(ir_kgc((ir)))) -#define ir_knum(ir) check_exp((ir)->o == IR_KNUM, mref((ir)->ptr, cTValue)) -#define ir_kint64(ir) check_exp((ir)->o == IR_KINT64, mref((ir)->ptr,cTValue)) +#define ir_knum(ir) check_exp((ir)->o == IR_KNUM, &(ir)[1].tv) +#define ir_kint64(ir) check_exp((ir)->o == IR_KINT64, &(ir)[1].tv) #define ir_k64(ir) \ - check_exp((ir)->o == IR_KNUM || (ir)->o == IR_KINT64, mref((ir)->ptr,cTValue)) + check_exp((ir)->o == IR_KNUM || (ir)->o == IR_KINT64 || \ + (LJ_GC64 && \ + ((ir)->o == IR_KGC || \ + (ir)->o == IR_KPTR || (ir)->o == IR_KKPTR)), \ + &(ir)[1].tv) #define ir_kptr(ir) \ - check_exp((ir)->o == IR_KPTR || (ir)->o == IR_KKPTR, mref((ir)->ptr, void)) + check_exp((ir)->o == IR_KPTR || (ir)->o == IR_KKPTR, \ + mref((ir)[LJ_GC64].ptr, void)) /* A store or any other op with a non-weak guard has a side-effect. */ static LJ_AINLINE int ir_sideeff(IRIns *ir) diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_ircall.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_ircall.h index 144135a4a7f..973c36e6ec9 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_ircall.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_ircall.h @@ -1,6 +1,6 @@ /* ** IR CALL* instruction definitions. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_IRCALL_H @@ -78,13 +78,13 @@ typedef struct CCallInfo { #define IRCALLCOND_SOFTFP_FFI(x) NULL #endif -#if LJ_SOFTFP && LJ_TARGET_MIPS +#if LJ_SOFTFP && LJ_TARGET_MIPS32 #define IRCALLCOND_SOFTFP_MIPS(x) x #else #define IRCALLCOND_SOFTFP_MIPS(x) NULL #endif -#define LJ_NEED_FP64 (LJ_TARGET_ARM || LJ_TARGET_PPC || LJ_TARGET_MIPS) +#define LJ_NEED_FP64 (LJ_TARGET_ARM || LJ_TARGET_PPC || LJ_TARGET_MIPS32) #if LJ_HASFFI && (LJ_SOFTFP || LJ_NEED_FP64) #define IRCALLCOND_FP64_FFI(x) x @@ -104,12 +104,6 @@ typedef struct CCallInfo { #define IRCALLCOND_FFI32(x) NULL #endif -#if LJ_TARGET_X86 -#define CCI_RANDFPR 0 /* Clang on OSX/x86 is overzealous. */ -#else -#define CCI_RANDFPR CCI_NOFPRCLOBBER -#endif - #if LJ_SOFTFP #define XA_FP CCI_XA #define XA2_FP (CCI_XA+CCI_XA) @@ -129,40 +123,40 @@ typedef struct CCallInfo { /* Function definitions for CALL* instructions. */ #define IRCALLDEF(_) \ _(ANY, lj_str_cmp, 2, FN, INT, CCI_NOFPRCLOBBER) \ - _(ANY, lj_str_find, 4, N, P32, 0) \ + _(ANY, lj_str_find, 4, N, PGC, 0) \ _(ANY, lj_str_new, 3, S, STR, CCI_L) \ _(ANY, lj_strscan_num, 2, FN, INT, 0) \ _(ANY, lj_strfmt_int, 2, FN, STR, CCI_L) \ _(ANY, lj_strfmt_num, 2, FN, STR, CCI_L) \ _(ANY, lj_strfmt_char, 2, FN, STR, CCI_L) \ - _(ANY, lj_strfmt_putint, 2, FL, P32, 0) \ - _(ANY, lj_strfmt_putnum, 2, FL, P32, 0) \ - _(ANY, lj_strfmt_putquoted, 2, FL, P32, 0) \ - _(ANY, lj_strfmt_putfxint, 3, L, P32, XA_64) \ - _(ANY, lj_strfmt_putfnum_int, 3, L, P32, XA_FP) \ - _(ANY, lj_strfmt_putfnum_uint, 3, L, P32, XA_FP) \ - _(ANY, lj_strfmt_putfnum, 3, L, P32, XA_FP) \ - _(ANY, lj_strfmt_putfstr, 3, L, P32, 0) \ - _(ANY, lj_strfmt_putfchar, 3, L, P32, 0) \ - _(ANY, lj_buf_putmem, 3, S, P32, 0) \ - _(ANY, lj_buf_putstr, 2, FL, P32, 0) \ - _(ANY, lj_buf_putchar, 2, FL, P32, 0) \ - _(ANY, lj_buf_putstr_reverse, 2, FL, P32, 0) \ - _(ANY, lj_buf_putstr_lower, 2, FL, P32, 0) \ - _(ANY, lj_buf_putstr_upper, 2, FL, P32, 0) \ - _(ANY, lj_buf_putstr_rep, 3, L, P32, 0) \ - _(ANY, lj_buf_puttab, 5, L, P32, 0) \ + _(ANY, lj_strfmt_putint, 2, FL, PGC, 0) \ + _(ANY, lj_strfmt_putnum, 2, FL, PGC, 0) \ + _(ANY, lj_strfmt_putquoted, 2, FL, PGC, 0) \ + _(ANY, lj_strfmt_putfxint, 3, L, PGC, XA_64) \ + _(ANY, lj_strfmt_putfnum_int, 3, L, PGC, XA_FP) \ + _(ANY, lj_strfmt_putfnum_uint, 3, L, PGC, XA_FP) \ + _(ANY, lj_strfmt_putfnum, 3, L, PGC, XA_FP) \ + _(ANY, lj_strfmt_putfstr, 3, L, PGC, 0) \ + _(ANY, lj_strfmt_putfchar, 3, L, PGC, 0) \ + _(ANY, lj_buf_putmem, 3, S, PGC, 0) \ + _(ANY, lj_buf_putstr, 2, FL, PGC, 0) \ + _(ANY, lj_buf_putchar, 2, FL, PGC, 0) \ + _(ANY, lj_buf_putstr_reverse, 2, FL, PGC, 0) \ + _(ANY, lj_buf_putstr_lower, 2, FL, PGC, 0) \ + _(ANY, lj_buf_putstr_upper, 2, FL, PGC, 0) \ + _(ANY, lj_buf_putstr_rep, 3, L, PGC, 0) \ + _(ANY, lj_buf_puttab, 5, L, PGC, 0) \ _(ANY, lj_buf_tostr, 1, FL, STR, 0) \ _(ANY, lj_tab_new_ah, 3, A, TAB, CCI_L) \ _(ANY, lj_tab_new1, 2, FS, TAB, CCI_L) \ _(ANY, lj_tab_dup, 2, FS, TAB, CCI_L) \ _(ANY, lj_tab_clear, 1, FS, NIL, 0) \ - _(ANY, lj_tab_newkey, 3, S, P32, CCI_L) \ + _(ANY, lj_tab_newkey, 3, S, PGC, CCI_L) \ _(ANY, lj_tab_len, 1, FL, INT, 0) \ _(ANY, lj_gc_step_jit, 2, FS, NIL, CCI_L) \ _(ANY, lj_gc_barrieruv, 2, FS, NIL, 0) \ - _(ANY, lj_mem_newgco, 2, FS, P32, CCI_L) \ - _(ANY, lj_math_random_step, 1, FS, NUM, CCI_CASTU64|CCI_RANDFPR)\ + _(ANY, lj_mem_newgco, 2, FS, PGC, CCI_L) \ + _(ANY, lj_math_random_step, 1, FS, NUM, CCI_CASTU64) \ _(ANY, lj_vm_modi, 2, FN, INT, 0) \ _(ANY, sinh, 1, N, NUM, XA_FP) \ _(ANY, cosh, 1, N, NUM, XA_FP) \ diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_iropt.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_iropt.h index 953740443cd..73aef0ef38e 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_iropt.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_iropt.h @@ -1,6 +1,6 @@ /* ** Common header for IR emitter and optimizations. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_IROPT_H @@ -36,12 +36,11 @@ static LJ_AINLINE IRRef lj_ir_nextins(jit_State *J) return ref; } +LJ_FUNC TRef lj_ir_ggfload(jit_State *J, IRType t, uintptr_t ofs); + /* Interning of constants. */ LJ_FUNC TRef LJ_FASTCALL lj_ir_kint(jit_State *J, int32_t k); -LJ_FUNC void lj_ir_k64_freeall(jit_State *J); -LJ_FUNC TRef lj_ir_k64(jit_State *J, IROp op, cTValue *tv); -LJ_FUNC TValue *lj_ir_k64_reserve(jit_State *J); -LJ_FUNC cTValue *lj_ir_k64_find(jit_State *J, uint64_t u64); +LJ_FUNC TRef lj_ir_k64(jit_State *J, IROp op, uint64_t u64); LJ_FUNC TRef lj_ir_knum_u64(jit_State *J, uint64_t u64); LJ_FUNC TRef lj_ir_knumint(jit_State *J, lua_Number n); LJ_FUNC TRef lj_ir_kint64(jit_State *J, uint64_t u64); @@ -49,6 +48,7 @@ LJ_FUNC TRef lj_ir_kgc(jit_State *J, GCobj *o, IRType t); LJ_FUNC TRef lj_ir_kptr_(jit_State *J, IROp op, void *ptr); LJ_FUNC TRef lj_ir_knull(jit_State *J, IRType t); LJ_FUNC TRef lj_ir_kslot(jit_State *J, TRef key, IRRef slot); +LJ_FUNC TRef lj_ir_ktrace(jit_State *J); #if LJ_64 #define lj_ir_kintp(J, k) lj_ir_kint64(J, (uint64_t)(k)) @@ -75,8 +75,8 @@ static LJ_AINLINE TRef lj_ir_knum(jit_State *J, lua_Number n) #define lj_ir_knum_tobit(J) lj_ir_knum_u64(J, U64x(43380000,00000000)) /* Special 128 bit SIMD constants. */ -#define lj_ir_knum_abs(J) lj_ir_k64(J, IR_KNUM, LJ_KSIMD(J, LJ_KSIMD_ABS)) -#define lj_ir_knum_neg(J) lj_ir_k64(J, IR_KNUM, LJ_KSIMD(J, LJ_KSIMD_NEG)) +#define lj_ir_ksimd(J, idx) \ + lj_ir_ggfload(J, IRT_NUM, (uintptr_t)LJ_KSIMD(J, idx) - (uintptr_t)J2GG(J)) /* Access to constants. */ LJ_FUNC void lj_ir_kvalue(lua_State *L, TValue *tv, const IRIns *ir); @@ -143,8 +143,8 @@ LJ_FUNC TRef LJ_FASTCALL lj_opt_narrow_cindex(jit_State *J, TRef key); LJ_FUNC TRef lj_opt_narrow_arith(jit_State *J, TRef rb, TRef rc, TValue *vb, TValue *vc, IROp op); LJ_FUNC TRef lj_opt_narrow_unm(jit_State *J, TRef rc, TValue *vc); -LJ_FUNC TRef lj_opt_narrow_mod(jit_State *J, TRef rb, TRef rc, TValue *vc); -LJ_FUNC TRef lj_opt_narrow_pow(jit_State *J, TRef rb, TRef rc, TValue *vc); +LJ_FUNC TRef lj_opt_narrow_mod(jit_State *J, TRef rb, TRef rc, TValue *vb, TValue *vc); +LJ_FUNC TRef lj_opt_narrow_pow(jit_State *J, TRef rb, TRef rc, TValue *vb, TValue *vc); LJ_FUNC IRType lj_opt_narrow_forl(jit_State *J, cTValue *forbase); /* Optimization passes. */ diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_jit.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_jit.h index 5a51357e077..92054e3df60 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_jit.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_jit.h @@ -1,6 +1,6 @@ /* ** Common definitions for the JIT compiler. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_JIT_H @@ -19,10 +19,11 @@ #define JIT_F_SSE4_1 0x00000040 #define JIT_F_PREFER_IMUL 0x00000080 #define JIT_F_LEA_AGU 0x00000100 +#define JIT_F_BMI2 0x00000200 /* Names for the CPU-specific flags. Must match the order above. */ #define JIT_F_CPU_FIRST JIT_F_SSE2 -#define JIT_F_CPUSTRING "\4SSE2\4SSE3\6SSE4.1\3AMD\4ATOM" +#define JIT_F_CPUSTRING "\4SSE2\4SSE3\6SSE4.1\3AMD\4ATOM\4BMI2" #elif LJ_TARGET_ARM #define JIT_F_ARMV6_ 0x00000010 #define JIT_F_ARMV6T2_ 0x00000020 @@ -45,12 +46,16 @@ #define JIT_F_CPU_FIRST JIT_F_SQRT #define JIT_F_CPUSTRING "\4SQRT\5ROUND" #elif LJ_TARGET_MIPS -#define JIT_F_MIPS32R2 0x00000010 +#define JIT_F_MIPSXXR2 0x00000010 /* Names for the CPU-specific flags. Must match the order above. */ -#define JIT_F_CPU_FIRST JIT_F_MIPS32R2 +#define JIT_F_CPU_FIRST JIT_F_MIPSXXR2 +#if LJ_TARGET_MIPS32 #define JIT_F_CPUSTRING "\010MIPS32R2" #else +#define JIT_F_CPUSTRING "\010MIPS64R2" +#endif +#else #define JIT_F_CPU_FIRST 0 #define JIT_F_CPUSTRING "" #endif @@ -178,14 +183,26 @@ LJ_STATIC_ASSERT(SNAP_CONT == TREF_CONT); #define SNAP(slot, flags, ref) (((SnapEntry)(slot) << 24) + (flags) + (ref)) #define SNAP_TR(slot, tr) \ (((SnapEntry)(slot) << 24) + ((tr) & (TREF_CONT|TREF_FRAME|TREF_REFMASK))) +#if !LJ_FR2 #define SNAP_MKPC(pc) ((SnapEntry)u32ptr(pc)) +#endif #define SNAP_MKFTSZ(ftsz) ((SnapEntry)(ftsz)) #define snap_ref(sn) ((sn) & 0xffff) #define snap_slot(sn) ((BCReg)((sn) >> 24)) #define snap_isframe(sn) ((sn) & SNAP_FRAME) -#define snap_pc(sn) ((const BCIns *)(uintptr_t)(sn)) #define snap_setref(sn, ref) (((sn) & (0xffff0000&~SNAP_NORESTORE)) | (ref)) +static LJ_AINLINE const BCIns *snap_pc(SnapEntry *sn) +{ +#if LJ_FR2 + uint64_t pcbase; + memcpy(&pcbase, sn, sizeof(uint64_t)); + return (const BCIns *)(pcbase >> 8); +#else + return (const BCIns *)(uintptr_t)*sn; +#endif +} + /* Snapshot and exit numbers. */ typedef uint32_t SnapNo; typedef uint32_t ExitNo; @@ -307,6 +324,45 @@ enum { LJ_KSIMD__MAX }; +enum { +#if LJ_TARGET_X86ORX64 + LJ_K64_TOBIT, /* 2^52 + 2^51 */ + LJ_K64_2P64, /* 2^64 */ + LJ_K64_M2P64, /* -2^64 */ +#if LJ_32 + LJ_K64_M2P64_31, /* -2^64 or -2^31 */ +#else + LJ_K64_M2P64_31 = LJ_K64_M2P64, +#endif +#endif +#if LJ_TARGET_MIPS + LJ_K64_2P31, /* 2^31 */ +#if LJ_64 + LJ_K64_2P63, /* 2^63 */ + LJ_K64_M2P64, /* -2^64 */ +#endif +#endif + LJ_K64__MAX, +}; + +enum { +#if LJ_TARGET_X86ORX64 + LJ_K32_M2P64_31, /* -2^64 or -2^31 */ +#endif +#if LJ_TARGET_PPC + LJ_K32_2P52_2P31, /* 2^52 + 2^31 */ + LJ_K32_2P52, /* 2^52 */ +#endif +#if LJ_TARGET_PPC || LJ_TARGET_MIPS + LJ_K32_2P31, /* 2^31 */ +#endif +#if LJ_TARGET_MIPS64 + LJ_K32_2P63, /* 2^63 */ + LJ_K32_M2P64, /* -2^64 */ +#endif + LJ_K32__MAX +}; + /* Get 16 byte aligned pointer to SIMD constant. */ #define LJ_KSIMD(J, n) \ ((TValue *)(((intptr_t)&J->ksimd[2*(n)] + 15) & ~(intptr_t)15)) @@ -323,13 +379,14 @@ enum { /* Fold state is used to fold instructions on-the-fly. */ typedef struct FoldState { IRIns ins; /* Currently emitted instruction. */ - IRIns left; /* Instruction referenced by left operand. */ - IRIns right; /* Instruction referenced by right operand. */ + IRIns left[2]; /* Instruction referenced by left operand. */ + IRIns right[2]; /* Instruction referenced by right operand. */ } FoldState; /* JIT compiler state. */ typedef struct jit_State { GCtrace cur; /* Current trace. */ + GCtrace *curfinal; /* Final address of current trace (set during asm). */ lua_State *L; /* Current Lua state. */ const BCIns *pc; /* Current PC. */ @@ -359,8 +416,9 @@ typedef struct jit_State { int32_t framedepth; /* Current frame depth. */ int32_t retdepth; /* Return frame depth (count of RETF). */ - MRef k64; /* Pointer to chained array of 64 bit constants. */ TValue ksimd[LJ_KSIMD__MAX*2+1]; /* 16 byte aligned SIMD constants. */ + TValue k64[LJ_K64__MAX]; /* Common 8 byte constants used by backends. */ + uint32_t k32[LJ_K32__MAX]; /* Ditto for 4 byte constants. */ IRIns *irbuf; /* Temp. IR instruction buffer. Biased with REF_BIAS. */ IRRef irtoplim; /* Upper limit of instuction buffer (biased). */ @@ -381,7 +439,7 @@ typedef struct jit_State { GCRef *trace; /* Array of traces. */ TraceNo freetrace; /* Start of scan for next free trace. */ MSize sizetrace; /* Size of trace array. */ - TValue *ktracep; /* Pointer to K64Array slot with GCtrace pointer. */ + IRRef1 ktrace; /* Reference to KGC with GCtrace. */ IRRef1 chain[IR__MAX]; /* IR instruction skip-list chain anchors. */ TRef slot[LJ_MAX_JSLOTS+LJ_STACK_EXTRA]; /* Stack slot map. */ diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_lex.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_lex.c index 0187c4267a2..2d2f8194cfd 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_lex.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_lex.c @@ -1,6 +1,6 @@ /* ** Lexical analyzer. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h ** ** Major portions taken verbatim or adapted from the Lua interpreter. ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_lex.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_lex.h index 7fed1fd6137..33fa8657262 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_lex.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_lex.h @@ -1,6 +1,6 @@ /* ** Lexical analyzer. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_LEX_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_lib.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_lib.c index 8bdf6912a8d..b8638de6a08 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_lib.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_lib.c @@ -1,6 +1,6 @@ /* ** Library function support. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_lib_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_lib.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_lib.h index dbc04055b44..37ec9d78007 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_lib.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_lib.h @@ -1,6 +1,6 @@ /* ** Library function support. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_LIB_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_load.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_load.c index 7783eee0504..c046402dbed 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_load.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_load.c @@ -1,6 +1,6 @@ /* ** Load and dump code. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #include <errno.h> @@ -166,6 +166,8 @@ LUA_API int lua_dump(lua_State *L, lua_Writer writer, void *data) return 1; } + + /* -- Luajittex needs this one because it overloads loadfile -- */ LUALIB_API int RESERVED_load_aux_JIT(lua_State *L, int status, int envarg) { @@ -182,3 +184,4 @@ LUALIB_API int RESERVED_load_aux_JIT(lua_State *L, int status, int envarg) return 2; } } + diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_mcode.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_mcode.c index 3eaee0546e7..77035bf72a4 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_mcode.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_mcode.c @@ -1,6 +1,6 @@ /* ** Machine code management. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_mcode_c @@ -204,8 +204,8 @@ static void mcode_protect(jit_State *J, int prot) /* -- MCode area allocation ----------------------------------------------- */ -#if LJ_TARGET_X64 -#define mcode_validptr(p) ((p) && (uintptr_t)(p) < (uintptr_t)1<<47) +#if LJ_64 +#define mcode_validptr(p) (p) #else #define mcode_validptr(p) ((p) && (uintptr_t)(p) < 0xffff0000) #endif @@ -221,8 +221,8 @@ static void *mcode_alloc(jit_State *J, size_t sz) */ #if LJ_TARGET_MIPS /* Use the middle of the 256MB-aligned region. */ - uintptr_t target = ((uintptr_t)(void *)lj_vm_exit_handler & 0xf0000000u) + - 0x08000000u; + uintptr_t target = ((uintptr_t)(void *)lj_vm_exit_handler & + ~(uintptr_t)0x0fffffffu) + 0x08000000u; #else uintptr_t target = (uintptr_t)(void *)lj_vm_exit_handler & ~(uintptr_t)0xffff; #endif @@ -230,7 +230,8 @@ static void *mcode_alloc(jit_State *J, size_t sz) /* First try a contiguous area below the last one. */ uintptr_t hint = J->mcarea ? (uintptr_t)J->mcarea - sz : 0; int i; - for (i = 0; i < 32; i++) { /* 32 attempts ought to be enough ... */ + /* Limit probing iterations, depending on the available pool size. */ + for (i = 0; i < LJ_TARGET_JUMPRANGE; i++) { if (mcode_validptr(hint)) { void *p = mcode_alloc_at(J, hint, sz, MCPROT_GEN); @@ -239,11 +240,11 @@ static void *mcode_alloc(jit_State *J, size_t sz) return p; if (p) mcode_free(J, p, sz); /* Free badly placed area. */ } - /* Next try probing pseudo-random addresses. */ + /* Next try probing 64K-aligned pseudo-random addresses. */ do { - hint = (0x78fb ^ LJ_PRNG_BITS(J, 15)) << 16; /* 64K aligned. */ - } while (!(hint + sz < range)); - hint = target + hint - (range>>1); + hint = LJ_PRNG_BITS(J, LJ_TARGET_JUMPRANGE-16) << 16; + } while (!(hint + sz < range+range)); + hint = target + hint - range; } lj_trace_err(J, LJ_TRERR_MCODEAL); /* Give up. OS probably ignores hints? */ return NULL; diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_mcode.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_mcode.h index 503e001974f..f0847e931e5 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_mcode.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_mcode.h @@ -1,6 +1,6 @@ /* ** Machine code management. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_MCODE_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_meta.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_meta.c index c7993ad6264..0bd4d8429b6 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_meta.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_meta.c @@ -1,6 +1,6 @@ /* ** Metamethod handling. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h ** ** Portions taken verbatim or adapted from the Lua interpreter. ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_meta.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_meta.h index 52e85cba2d1..73b45724735 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_meta.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_meta.h @@ -1,6 +1,6 @@ /* ** Metamethod handling. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_META_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_obj.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_obj.c index 1daea817ace..ee33aeb3a8e 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_obj.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_obj.c @@ -1,6 +1,6 @@ /* ** Miscellaneous object handling. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_obj_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_obj.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_obj.h index 059eb13250a..52372c3e7e5 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_obj.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_obj.h @@ -1,6 +1,6 @@ /* ** LuaJIT VM tags, values and objects. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h ** ** Portions taken verbatim or adapted from the Lua interpreter. ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h @@ -843,12 +843,16 @@ static LJ_AINLINE void setlightudV(TValue *o, void *p) #endif #if LJ_FR2 -#define setcont(o, f) ((o)->u64 = (uint64_t)(uintptr_t)(void *)(f)) +#define contptr(f) ((void *)(f)) +#define setcont(o, f) ((o)->u64 = (uint64_t)(uintptr_t)contptr(f)) #elif LJ_64 +#define contptr(f) \ + ((void *)(uintptr_t)(uint32_t)((intptr_t)(f) - (intptr_t)lj_vm_asm_begin)) #define setcont(o, f) \ ((o)->u64 = (uint64_t)(void *)(f) - (uint64_t)lj_vm_asm_begin) #else -#define setcont(o, f) setlightudV((o), (void *)(f)) +#define contptr(f) ((void *)(f)) +#define setcont(o, f) setlightudV((o), contptr(f)) #endif #define tvchecklive(L, o) \ diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_dce.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_dce.c index e5a096af561..2417f3242aa 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_dce.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_dce.c @@ -1,6 +1,6 @@ /* ** DCE: Dead Code Elimination. Pre-LOOP only -- ASM already performs DCE. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_opt_dce_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_fold.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_fold.c index e1d136915cb..acbf36a5c7c 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_fold.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_fold.c @@ -2,7 +2,7 @@ ** FOLD: Constant Folding, Algebraic Simplifications and Reassociation. ** ABCelim: Array Bounds Check Elimination. ** CSE: Common-Subexpression Elimination. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_opt_fold_c @@ -136,8 +136,8 @@ /* Some local macros to save typing. Undef'd at the end. */ #define IR(ref) (&J->cur.ir[(ref)]) #define fins (&J->fold.ins) -#define fleft (&J->fold.left) -#define fright (&J->fold.right) +#define fleft (J->fold.left) +#define fright (J->fold.right) #define knumleft (ir_knum(fleft)->n) #define knumright (ir_knum(fright)->n) @@ -173,8 +173,6 @@ LJFOLD(ADD KNUM KNUM) LJFOLD(SUB KNUM KNUM) LJFOLD(MUL KNUM KNUM) LJFOLD(DIV KNUM KNUM) -LJFOLD(NEG KNUM KNUM) -LJFOLD(ABS KNUM KNUM) LJFOLD(ATAN2 KNUM KNUM) LJFOLD(LDEXP KNUM KNUM) LJFOLD(MIN KNUM KNUM) @@ -187,6 +185,15 @@ LJFOLDF(kfold_numarith) return lj_ir_knum(J, y); } +LJFOLD(NEG KNUM FLOAD) +LJFOLD(ABS KNUM FLOAD) +LJFOLDF(kfold_numabsneg) +{ + lua_Number a = knumleft; + lua_Number y = lj_vm_foldarith(a, a, fins->o - IR_ADD); + return lj_ir_knum(J, y); +} + LJFOLD(LDEXP KNUM KINT) LJFOLDF(kfold_ldexp) { @@ -347,6 +354,11 @@ static uint64_t kfold_int64arith(uint64_t k1, uint64_t k2, IROp op) case IR_BAND: k1 &= k2; break; case IR_BOR: k1 |= k2; break; case IR_BXOR: k1 ^= k2; break; + case IR_BSHL: k1 <<= (k2 & 63); break; + case IR_BSHR: k1 = (int32_t)((uint32_t)k1 >> (k2 & 63)); break; + case IR_BSAR: k1 >>= (k2 & 63); break; + case IR_BROL: k1 = (int32_t)lj_rol((uint32_t)k1, (k2 & 63)); break; + case IR_BROR: k1 = (int32_t)lj_ror((uint32_t)k1, (k2 & 63)); break; #endif default: UNUSED(k2); lua_assert(0); break; } @@ -436,14 +448,14 @@ LJFOLDF(kfold_int64comp) #if LJ_HASFFI uint64_t a = ir_k64(fleft)->u64, b = ir_k64(fright)->u64; switch ((IROp)fins->o) { - case IR_LT: return CONDFOLD(a < b); - case IR_GE: return CONDFOLD(a >= b); - case IR_LE: return CONDFOLD(a <= b); - case IR_GT: return CONDFOLD(a > b); - case IR_ULT: return CONDFOLD((uint64_t)a < (uint64_t)b); - case IR_UGE: return CONDFOLD((uint64_t)a >= (uint64_t)b); - case IR_ULE: return CONDFOLD((uint64_t)a <= (uint64_t)b); - case IR_UGT: return CONDFOLD((uint64_t)a > (uint64_t)b); + case IR_LT: return CONDFOLD((int64_t)a < (int64_t)b); + case IR_GE: return CONDFOLD((int64_t)a >= (int64_t)b); + case IR_LE: return CONDFOLD((int64_t)a <= (int64_t)b); + case IR_GT: return CONDFOLD((int64_t)a > (int64_t)b); + case IR_ULT: return CONDFOLD(a < b); + case IR_UGE: return CONDFOLD(a >= b); + case IR_ULE: return CONDFOLD(a <= b); + case IR_UGT: return CONDFOLD(a > b); default: lua_assert(0); return FAILFOLD; } #else @@ -502,7 +514,7 @@ LJFOLDF(kfold_strref_snew) PHIBARRIER(ir); fins->op2 = emitir(IRTI(IR_ADD), ir->op2, fins->op2); /* Clobbers fins! */ fins->op1 = str; - fins->ot = IRT(IR_STRREF, IRT_P32); + fins->ot = IRT(IR_STRREF, IRT_PGC); return RETRYFOLD; } } @@ -911,13 +923,13 @@ LJFOLDF(shortcut_round) return NEXTFOLD; } -LJFOLD(ABS ABS KNUM) +LJFOLD(ABS ABS FLOAD) LJFOLDF(shortcut_left) { return LEFTFOLD; /* f(g(x)) ==> g(x) */ } -LJFOLD(ABS NEG KNUM) +LJFOLD(ABS NEG FLOAD) LJFOLDF(shortcut_dropleft) { PHIBARRIER(fleft); @@ -998,8 +1010,10 @@ LJFOLDF(simplify_nummuldiv_k) if (n == 1.0) { /* x o 1 ==> x */ return LEFTFOLD; } else if (n == -1.0) { /* x o -1 ==> -x */ + IRRef op1 = fins->op1; + fins->op2 = (IRRef1)lj_ir_ksimd(J, LJ_KSIMD_NEG); /* Modifies fins. */ + fins->op1 = op1; fins->o = IR_NEG; - fins->op2 = (IRRef1)lj_ir_knum_neg(J); return RETRYFOLD; } else if (fins->o == IR_MUL && n == 2.0) { /* x * 2 ==> x + x */ fins->o = IR_ADD; @@ -1651,6 +1665,14 @@ LJFOLDF(simplify_shiftk_andk) fins->op2 = (IRRef1)lj_ir_kint(J, k); fins->ot = IRTI(IR_BAND); return RETRYFOLD; + } else if (irk->o == IR_KINT64) { + uint64_t k = kfold_int64arith(ir_k64(irk)->u64, fright->i, (IROp)fins->o); + IROpT ot = fleft->ot; + fins->op1 = fleft->op1; + fins->op1 = (IRRef1)lj_opt_fold(J); + fins->op2 = (IRRef1)lj_ir_kint64(J, k); + fins->ot = ot; + return RETRYFOLD; } return NEXTFOLD; } @@ -1666,6 +1688,47 @@ LJFOLDF(simplify_andk_shiftk) return NEXTFOLD; } +LJFOLD(BAND BOR KINT) +LJFOLD(BOR BAND KINT) +LJFOLDF(simplify_andor_k) +{ + IRIns *irk = IR(fleft->op2); + PHIBARRIER(fleft); + if (irk->o == IR_KINT) { + int32_t k = kfold_intop(irk->i, fright->i, (IROp)fins->o); + /* (i | k1) & k2 ==> i & k2, if (k1 & k2) == 0. */ + /* (i & k1) | k2 ==> i | k2, if (k1 | k2) == -1. */ + if (k == (fins->o == IR_BAND ? 0 : -1)) { + fins->op1 = fleft->op1; + return RETRYFOLD; + } + } + return NEXTFOLD; +} + +LJFOLD(BAND BOR KINT64) +LJFOLD(BOR BAND KINT64) +LJFOLDF(simplify_andor_k64) +{ +#if LJ_HASFFI + IRIns *irk = IR(fleft->op2); + PHIBARRIER(fleft); + if (irk->o == IR_KINT64) { + uint64_t k = kfold_int64arith(ir_k64(irk)->u64, + ir_k64(fright)->u64, (IROp)fins->o); + /* (i | k1) & k2 ==> i & k2, if (k1 & k2) == 0. */ + /* (i & k1) | k2 ==> i | k2, if (k1 | k2) == -1. */ + if (k == (fins->o == IR_BAND ? (uint64_t)0 : ~(uint64_t)0)) { + fins->op1 = fleft->op1; + return RETRYFOLD; + } + } + return NEXTFOLD; +#else + UNUSED(J); lua_assert(0); return FAILFOLD; +#endif +} + /* -- Reassociation ------------------------------------------------------- */ LJFOLD(ADD ADD KINT) @@ -2393,10 +2456,14 @@ retry: if (fins->op1 >= J->cur.nk) { key += (uint32_t)IR(fins->op1)->o << 10; *fleft = *IR(fins->op1); + if (fins->op1 < REF_TRUE) + fleft[1] = IR(fins->op1)[1]; } if (fins->op2 >= J->cur.nk) { key += (uint32_t)IR(fins->op2)->o; *fright = *IR(fins->op2); + if (fins->op2 < REF_TRUE) + fright[1] = IR(fins->op2)[1]; } else { key += (fins->op2 & 0x3ffu); /* Literal mask. Must include IRCONV_*MASK. */ } diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_loop.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_loop.c index 7978f3eeafc..04c6d06ddff 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_loop.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_loop.c @@ -1,6 +1,6 @@ /* ** LOOP: Loop Optimizations. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_opt_loop_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_mem.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_mem.c index 5549b0d02dd..cc177d39e8b 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_mem.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_mem.c @@ -3,7 +3,7 @@ ** AA: Alias Analysis using high-level semantic disambiguation. ** FWD: Load Forwarding (L2L) + Store Forwarding (S2L). ** DSE: Dead-Store Elimination. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_opt_mem_c @@ -22,8 +22,8 @@ /* Some local macros to save typing. Undef'd at the end. */ #define IR(ref) (&J->cur.ir[(ref)]) #define fins (&J->fold.ins) -#define fleft (&J->fold.left) -#define fright (&J->fold.right) +#define fleft (J->fold.left) +#define fright (J->fold.right) /* ** Caveat #1: return value is not always a TRef -- only use with tref_ref(). diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_narrow.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_narrow.c index b1ab5ba8eeb..cd96ca4b4f9 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_narrow.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_narrow.c @@ -1,7 +1,7 @@ /* ** NARROW: Narrowing of numbers to integers (double to int32_t). ** STRIPOV: Stripping of overflow checks. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_opt_narrow_c @@ -517,18 +517,24 @@ static int numisint(lua_Number n) return (n == (lua_Number)lj_num2int(n)); } +/* Convert string to number. Error out for non-numeric string values. */ +static TRef conv_str_tonum(jit_State *J, TRef tr, TValue *o) +{ + if (tref_isstr(tr)) { + tr = emitir(IRTG(IR_STRTO, IRT_NUM), tr, 0); + /* Would need an inverted STRTO for this rare and useless case. */ + if (!lj_strscan_num(strV(o), o)) /* Convert in-place. Value used below. */ + lj_trace_err(J, LJ_TRERR_BADTYPE); /* Punt if non-numeric. */ + } + return tr; +} + /* Narrowing of arithmetic operations. */ TRef lj_opt_narrow_arith(jit_State *J, TRef rb, TRef rc, TValue *vb, TValue *vc, IROp op) { - if (tref_isstr(rb)) { - rb = emitir(IRTG(IR_STRTO, IRT_NUM), rb, 0); - lj_strscan_num(strV(vb), vb); - } - if (tref_isstr(rc)) { - rc = emitir(IRTG(IR_STRTO, IRT_NUM), rc, 0); - lj_strscan_num(strV(vc), vc); - } + rb = conv_str_tonum(J, rb, vb); + rc = conv_str_tonum(J, rc, vc); /* Must not narrow MUL in non-DUALNUM variant, because it loses -0. */ if ((op >= IR_ADD && op <= (LJ_DUALNUM ? IR_MUL : IR_SUB)) && tref_isinteger(rb) && tref_isinteger(rc) && @@ -543,24 +549,21 @@ TRef lj_opt_narrow_arith(jit_State *J, TRef rb, TRef rc, /* Narrowing of unary minus operator. */ TRef lj_opt_narrow_unm(jit_State *J, TRef rc, TValue *vc) { - if (tref_isstr(rc)) { - rc = emitir(IRTG(IR_STRTO, IRT_NUM), rc, 0); - lj_strscan_num(strV(vc), vc); - } + rc = conv_str_tonum(J, rc, vc); if (tref_isinteger(rc)) { if ((uint32_t)numberVint(vc) != 0x80000000u) return emitir(IRTGI(IR_SUBOV), lj_ir_kint(J, 0), rc); rc = emitir(IRTN(IR_CONV), rc, IRCONV_NUM_INT); } - return emitir(IRTN(IR_NEG), rc, lj_ir_knum_neg(J)); + return emitir(IRTN(IR_NEG), rc, lj_ir_ksimd(J, LJ_KSIMD_NEG)); } /* Narrowing of modulo operator. */ -TRef lj_opt_narrow_mod(jit_State *J, TRef rb, TRef rc, TValue *vc) +TRef lj_opt_narrow_mod(jit_State *J, TRef rb, TRef rc, TValue *vb, TValue *vc) { TRef tmp; - if (tvisstr(vc) && !lj_strscan_num(strV(vc), vc)) - lj_trace_err(J, LJ_TRERR_BADTYPE); + rb = conv_str_tonum(J, rb, vb); + rc = conv_str_tonum(J, rc, vc); if ((LJ_DUALNUM || (J->flags & JIT_F_OPT_NARROW)) && tref_isinteger(rb) && tref_isinteger(rc) && (tvisint(vc) ? intV(vc) != 0 : !tviszero(vc))) { @@ -577,10 +580,11 @@ TRef lj_opt_narrow_mod(jit_State *J, TRef rb, TRef rc, TValue *vc) } /* Narrowing of power operator or math.pow. */ -TRef lj_opt_narrow_pow(jit_State *J, TRef rb, TRef rc, TValue *vc) +TRef lj_opt_narrow_pow(jit_State *J, TRef rb, TRef rc, TValue *vb, TValue *vc) { - if (tvisstr(vc) && !lj_strscan_num(strV(vc), vc)) - lj_trace_err(J, LJ_TRERR_BADTYPE); + rb = conv_str_tonum(J, rb, vb); + rb = lj_ir_tonum(J, rb); /* Left arg is always treated as an FP number. */ + rc = conv_str_tonum(J, rc, vc); /* Narrowing must be unconditional to preserve (-x)^i semantics. */ if (tvisint(vc) || numisint(numV(vc))) { int checkrange = 0; @@ -591,8 +595,6 @@ TRef lj_opt_narrow_pow(jit_State *J, TRef rb, TRef rc, TValue *vc) checkrange = 1; } if (!tref_isinteger(rc)) { - if (tref_isstr(rc)) - rc = emitir(IRTG(IR_STRTO, IRT_NUM), rc, 0); /* Guarded conversion to integer! */ rc = emitir(IRTGI(IR_CONV), rc, IRCONV_INT_NUM|IRCONV_CHECK); } diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_sink.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_sink.c index 975ee831d91..929ccb61877 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_sink.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_sink.c @@ -1,6 +1,6 @@ /* ** SINK: Allocation Sinking and Store Sinking. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_opt_sink_c @@ -153,10 +153,9 @@ static void sink_remark_phi(jit_State *J) remark = 0; for (ir = IR(J->cur.nins-1); ir->o == IR_PHI; ir--) { IRIns *irl = IR(ir->op1), *irr = IR(ir->op2); - if (((irl->t.irt ^ irr->t.irt) & IRT_MARK)) - remark = 1; - else if (irl->prev == irr->prev) + if (!((irl->t.irt ^ irr->t.irt) & IRT_MARK) && irl->prev == irr->prev) continue; + remark |= (~(irl->t.irt & irr->t.irt) & IRT_MARK); irt_setmark(IR(ir->op1)->t); irt_setmark(IR(ir->op2)->t); } @@ -166,8 +165,8 @@ static void sink_remark_phi(jit_State *J) /* Sweep instructions and tag sunken allocations and stores. */ static void sink_sweep_ins(jit_State *J) { - IRIns *ir, *irfirst = IR(J->cur.nk); - for (ir = IR(J->cur.nins-1) ; ir >= irfirst; ir--) { + IRIns *ir, *irbase = IR(REF_BASE); + for (ir = IR(J->cur.nins-1) ; ir >= irbase; ir--) { switch (ir->o) { case IR_ASTORE: case IR_HSTORE: case IR_FSTORE: case IR_XSTORE: { IRIns *ira = sink_checkalloc(J, ir); @@ -217,6 +216,12 @@ static void sink_sweep_ins(jit_State *J) break; } } + for (ir = IR(J->cur.nk); ir < irbase; ir++) { + irt_clearmark(ir->t); + ir->prev = REGSP_INIT; + if (irt_is64(ir->t) && ir->o != IR_KNULL) + ir++; + } } /* Allocation sinking and store sinking. diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_split.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_split.c index 6def4161aa3..fc9352042ed 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_split.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_split.c @@ -1,6 +1,6 @@ /* ** SPLIT: Split 64 bit IR instructions into 32 bit IR instructions. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_opt_split_c @@ -16,6 +16,7 @@ #include "lj_jit.h" #include "lj_ircall.h" #include "lj_iropt.h" +#include "lj_dispatch.h" #include "lj_vm.h" /* SPLIT pass: @@ -353,6 +354,8 @@ static void split_ir(jit_State *J) ir->prev = ref; /* Identity substitution for loword. */ hisubst[ref] = 0; } + if (irt_is64(ir->t) && ir->o != IR_KNULL) + ref++; } /* Process old IR instructions. */ @@ -433,7 +436,8 @@ static void split_ir(jit_State *J) nir->o = IR_CONV; /* Pass through loword. */ nir->op2 = (IRT_INT << 5) | IRT_INT; hi = split_emit(J, IRT(ir->o == IR_NEG ? IR_BXOR : IR_BAND, IRT_SOFTFP), - hisubst[ir->op1], hisubst[ir->op2]); + hisubst[ir->op1], + lj_ir_kint(J, (int32_t)(0x7fffffffu + (ir->o == IR_NEG)))); break; case IR_SLOAD: if ((nir->op2 & IRSLOAD_CONVERT)) { /* Convert from int to number. */ @@ -448,6 +452,11 @@ static void split_ir(jit_State *J) case IR_STRTO: hi = split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), nref, nref); break; + case IR_FLOAD: + lua_assert(ir->op1 == REF_NIL); + hi = lj_ir_kint(J, *(int32_t*)((char*)J2GG(J) + ir->op2 + LJ_LE*4)); + nir->op2 += LJ_BE*4; + break; case IR_XLOAD: { IRIns inslo = *nir; /* Save/undo the emit of the lo XLOAD. */ J->cur.nins--; diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_parse.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_parse.c index 610c861480e..08f7cfa6ac5 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_parse.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_parse.c @@ -1,6 +1,6 @@ /* ** Lua parser (source code -> bytecode). -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h ** ** Major portions taken verbatim or adapted from the Lua interpreter. ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h @@ -1282,12 +1282,14 @@ static void fscope_end(FuncState *fs) MSize idx = gola_new(ls, NAME_BREAK, VSTACK_LABEL, fs->pc); ls->vtop = idx; /* Drop break label immediately. */ gola_resolve(ls, bl, idx); + } else { /* Need the fixup step to propagate the breaks. */ + gola_fixup(ls, bl); return; - } /* else: need the fixup step to propagate the breaks. */ - } else if (!(bl->flags & FSCOPE_GOLA)) { - return; + } + } + if ((bl->flags & FSCOPE_GOLA)) { + gola_fixup(ls, bl); } - gola_fixup(ls, bl); } /* Mark scope as having an upvalue. */ @@ -2177,6 +2179,8 @@ static void assign_adjust(LexState *ls, BCReg nvars, BCReg nexps, ExpDesc *e) bcemit_nil(fs, reg, (BCReg)extra); } } + if (nexps > nvars) + ls->fs->freereg -= nexps - nvars; /* Drop leftover regs. */ } /* Recursively parse assignment statement. */ @@ -2210,8 +2214,6 @@ static void parse_assignment(LexState *ls, LHSVarList *lh, BCReg nvars) return; } assign_adjust(ls, nvars, nexps, &e); - if (nexps > nvars) - ls->fs->freereg -= nexps - nvars; /* Drop leftover regs. */ } /* Assign RHS to LHS and recurse downwards. */ expr_init(&e, VNONRELOC, ls->fs->freereg-1); diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_parse.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_parse.h index b383c8971b1..ceeab6994ff 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_parse.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_parse.h @@ -1,6 +1,6 @@ /* ** Lua parser (source code -> bytecode). -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_PARSE_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_profile.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_profile.c index 95b0a621e84..116998e1e8f 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_profile.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_profile.c @@ -1,6 +1,6 @@ /* ** Low-overhead profiling. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_profile_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_profile.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_profile.h index 14c3fc0881f..0cccfd78cd7 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_profile.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_profile.h @@ -1,6 +1,6 @@ /* ** Low-overhead profiling. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_PROFILE_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_record.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_record.c index 90f53af3e6b..9d0469c4251 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_record.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_record.c @@ -1,6 +1,6 @@ /* ** Trace recorder (bytecode -> SSA IR). -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_record_c @@ -51,7 +51,7 @@ static void rec_check_ir(jit_State *J) { IRRef i, nins = J->cur.nins, nk = J->cur.nk; lua_assert(nk <= REF_BIAS && nins >= REF_BIAS && nins < 65536); - for (i = nins-1; i >= nk; i--) { + for (i = nk; i < nins; i++) { IRIns *ir = IR(i); uint32_t mode = lj_ir_mode[ir->o]; IRRef op1 = ir->op1; @@ -61,7 +61,10 @@ static void rec_check_ir(jit_State *J) case IRMref: lua_assert(op1 >= nk); lua_assert(i >= REF_BIAS ? op1 < i : op1 > i); break; case IRMlit: break; - case IRMcst: lua_assert(i < REF_BIAS); continue; + case IRMcst: lua_assert(i < REF_BIAS); + if (irt_is64(ir->t) && ir->o != IR_KNULL) + i++; + continue; } switch (irm_op2(mode)) { case IRMnone: lua_assert(op2 == 0); break; @@ -84,30 +87,48 @@ static void rec_check_slots(jit_State *J) BCReg s, nslots = J->baseslot + J->maxslot; int32_t depth = 0; cTValue *base = J->L->base - J->baseslot; - lua_assert(J->baseslot >= 1 && J->baseslot < LJ_MAX_JSLOTS); - lua_assert(J->baseslot == 1 || (J->slot[J->baseslot-1] & TREF_FRAME)); + lua_assert(J->baseslot >= 1+LJ_FR2 && J->baseslot < LJ_MAX_JSLOTS); + lua_assert(J->baseslot == 1+LJ_FR2 || (J->slot[J->baseslot-1] & TREF_FRAME)); lua_assert(nslots < LJ_MAX_JSLOTS); for (s = 0; s < nslots; s++) { TRef tr = J->slot[s]; if (tr) { cTValue *tv = &base[s]; IRRef ref = tref_ref(tr); - IRIns *ir; - lua_assert(ref >= J->cur.nk && ref < J->cur.nins); - ir = IR(ref); - lua_assert(irt_t(ir->t) == tref_t(tr)); + IRIns *ir = NULL; /* Silence compiler. */ + if (!LJ_FR2 || ref || !(tr & (TREF_FRAME | TREF_CONT))) { + lua_assert(ref >= J->cur.nk && ref < J->cur.nins); + ir = IR(ref); + lua_assert(irt_t(ir->t) == tref_t(tr)); + } if (s == 0) { lua_assert(tref_isfunc(tr)); +#if LJ_FR2 + } else if (s == 1) { + lua_assert((tr & ~TREF_FRAME) == 0); +#endif } else if ((tr & TREF_FRAME)) { GCfunc *fn = gco2func(frame_gc(tv)); BCReg delta = (BCReg)(tv - frame_prev(tv)); +#if LJ_FR2 + if (ref) + lua_assert(ir_knum(ir)->u64 == tv->u64); + tr = J->slot[s-1]; + ir = IR(tref_ref(tr)); +#endif lua_assert(tref_isfunc(tr)); if (tref_isk(tr)) lua_assert(fn == ir_kfunc(ir)); - lua_assert(s > delta ? (J->slot[s-delta] & TREF_FRAME) : (s == delta)); + lua_assert(s > delta + LJ_FR2 ? (J->slot[s-delta] & TREF_FRAME) + : (s == delta + LJ_FR2)); depth++; } else if ((tr & TREF_CONT)) { +#if LJ_FR2 + if (ref) + lua_assert(ir_knum(ir)->u64 == tv->u64); +#else lua_assert(ir_kptr(ir) == gcrefp(tv->gcr, void)); - lua_assert((J->slot[s+1] & TREF_FRAME)); +#endif + lua_assert((J->slot[s+1+LJ_FR2] & TREF_FRAME)); depth++; } else { if (tvisnumber(tv)) @@ -159,10 +180,10 @@ static TRef sload(jit_State *J, int32_t slot) /* Get TRef for current function. */ static TRef getcurrf(jit_State *J) { - if (J->base[-1]) - return J->base[-1]; - lua_assert(J->baseslot == 1); - return sloadt(J, -1, IRT_FUNC, IRSLOAD_READONLY); + if (J->base[-1-LJ_FR2]) + return J->base[-1-LJ_FR2]; + lua_assert(J->baseslot == 1+LJ_FR2); + return sloadt(J, -1-LJ_FR2, IRT_FUNC, IRSLOAD_READONLY); } /* Compare for raw object equality. @@ -506,7 +527,6 @@ static LoopEvent rec_for(jit_State *J, const BCIns *fori, int isforl) static LoopEvent rec_iterl(jit_State *J, const BCIns iterins) { BCReg ra = bc_a(iterins); - lua_assert(!LJ_FR2); /* TODO_FR2: handle different frame setup. */ if (!tref_isnil(getslot(J, ra))) { /* Looping back? */ J->base[ra-1] = J->base[ra]; /* Copy result of ITERC to control var. */ J->maxslot = ra-1+bc_b(J->pc[-1]); @@ -643,8 +663,8 @@ static TRef rec_call_specialize(jit_State *J, GCfunc *fn, TRef tr) GCproto *pt = funcproto(fn); /* Too many closures created? Probably not a monomorphic function. */ if (pt->flags >= PROTO_CLC_POLY) { /* Specialize to prototype instead. */ - TRef trpt = emitir(IRT(IR_FLOAD, IRT_P32), tr, IRFL_FUNC_PC); - emitir(IRTG(IR_EQ, IRT_P32), trpt, lj_ir_kptr(J, proto_bc(pt))); + TRef trpt = emitir(IRT(IR_FLOAD, IRT_PGC), tr, IRFL_FUNC_PC); + emitir(IRTG(IR_EQ, IRT_PGC), trpt, lj_ir_kptr(J, proto_bc(pt))); (void)lj_ir_kgc(J, obj2gco(pt), IRT_PROTO); /* Prevent GC of proto. */ return tr; } @@ -675,22 +695,31 @@ static void rec_call_setup(jit_State *J, BCReg func, ptrdiff_t nargs) { RecordIndex ix; TValue *functv = &J->L->base[func]; - TRef *fbase = &J->base[func]; + TRef kfunc, *fbase = &J->base[func]; ptrdiff_t i; - lua_assert(!LJ_FR2); /* TODO_FR2: handle different frame setup. */ - for (i = 0; i <= nargs; i++) - (void)getslot(J, func+i); /* Ensure func and all args have a reference. */ + (void)getslot(J, func); /* Ensure func has a reference. */ + for (i = 1; i <= nargs; i++) + (void)getslot(J, func+LJ_FR2+i); /* Ensure all args have a reference. */ if (!tref_isfunc(fbase[0])) { /* Resolve __call metamethod. */ ix.tab = fbase[0]; copyTV(J->L, &ix.tabv, functv); if (!lj_record_mm_lookup(J, &ix, MM_call) || !tref_isfunc(ix.mobj)) lj_trace_err(J, LJ_TRERR_NOMM); - for (i = ++nargs; i > 0; i--) /* Shift arguments up. */ - fbase[i] = fbase[i-1]; + for (i = ++nargs; i > LJ_FR2; i--) /* Shift arguments up. */ + fbase[i+LJ_FR2] = fbase[i+LJ_FR2-1]; +#if LJ_FR2 + fbase[2] = fbase[0]; +#endif fbase[0] = ix.mobj; /* Replace function. */ functv = &ix.mobjv; } - fbase[0] = TREF_FRAME | rec_call_specialize(J, funcV(functv), fbase[0]); + kfunc = rec_call_specialize(J, funcV(functv), fbase[0]); +#if LJ_FR2 + fbase[0] = kfunc; + fbase[1] = TREF_FRAME; +#else + fbase[0] = kfunc | TREF_FRAME; +#endif J->maxslot = (BCReg)nargs; } @@ -700,8 +729,8 @@ void lj_record_call(jit_State *J, BCReg func, ptrdiff_t nargs) rec_call_setup(J, func, nargs); /* Bump frame. */ J->framedepth++; - J->base += func+1; - J->baseslot += func+1; + J->base += func+1+LJ_FR2; + J->baseslot += func+1+LJ_FR2; } /* Record tail call. */ @@ -717,7 +746,9 @@ void lj_record_tailcall(jit_State *J, BCReg func, ptrdiff_t nargs) func += cbase; } /* Move func + args down. */ - memmove(&J->base[-1], &J->base[func], sizeof(TRef)*(J->maxslot+1)); + if (LJ_FR2 && J->baseslot == 2) + J->base[func+1] = TREF_FRAME; + memmove(&J->base[-1-LJ_FR2], &J->base[func], sizeof(TRef)*(J->maxslot+1+LJ_FR2)); /* Note: the new TREF_FRAME is now at J->base[-1] (even for slot #0). */ /* Tailcalls can form a loop, so count towards the loop unroll limit. */ if (++J->tailcalled > J->loopunroll) @@ -758,9 +789,9 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults) (void)getslot(J, rbase+i); /* Ensure all results have a reference. */ while (frame_ispcall(frame)) { /* Immediately resolve pcall() returns. */ BCReg cbase = (BCReg)frame_delta(frame); - if (--J->framedepth < 0) + if (--J->framedepth <= 0) lj_trace_err(J, LJ_TRERR_NYIRETL); - lua_assert(J->baseslot > 1); + lua_assert(J->baseslot > 1+LJ_FR2); gotresults++; rbase += cbase; J->baseslot -= (BCReg)cbase; @@ -784,7 +815,7 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults) BCReg cbase = (BCReg)frame_delta(frame); if (--J->framedepth < 0) /* NYI: return of vararg func to lower frame. */ lj_trace_err(J, LJ_TRERR_NYIRETL); - lua_assert(J->baseslot > 1); + lua_assert(J->baseslot > 1+LJ_FR2); rbase += cbase; J->baseslot -= (BCReg)cbase; J->base -= cbase; @@ -794,8 +825,7 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults) BCIns callins = *(frame_pc(frame)-1); ptrdiff_t nresults = bc_b(callins) ? (ptrdiff_t)bc_b(callins)-1 :gotresults; BCReg cbase = bc_a(callins); - GCproto *pt = funcproto(frame_func(frame - (cbase+1-LJ_FR2))); - lua_assert(!LJ_FR2); /* TODO_FR2: handle different frame teardown. */ + GCproto *pt = funcproto(frame_func(frame - (cbase+1+LJ_FR2))); if ((pt->flags & PROTO_NOJIT)) lj_trace_err(J, LJ_TRERR_CJITOFF); if (J->framedepth == 0 && J->pt && frame == J->L->base - 1) { @@ -808,13 +838,13 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults) lj_snap_add(J); } for (i = 0; i < nresults; i++) /* Adjust results. */ - J->base[i-1] = i < gotresults ? J->base[rbase+i] : TREF_NIL; + J->base[i-1-LJ_FR2] = i < gotresults ? J->base[rbase+i] : TREF_NIL; J->maxslot = cbase+(BCReg)nresults; if (J->framedepth > 0) { /* Return to a frame that is part of the trace. */ J->framedepth--; - lua_assert(J->baseslot > cbase+1); - J->baseslot -= cbase+1; - J->base -= cbase+1; + lua_assert(J->baseslot > cbase+1+LJ_FR2); + J->baseslot -= cbase+1+LJ_FR2; + J->base -= cbase+1+LJ_FR2; } else if (J->parent == 0 && J->exitno == 0 && !bc_isret(bc_op(J->cur.startins))) { /* Return to lower frame would leave the loop in a root trace. */ @@ -824,13 +854,13 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults) } else { /* Return to lower frame. Guard for the target we return to. */ TRef trpt = lj_ir_kgc(J, obj2gco(pt), IRT_PROTO); TRef trpc = lj_ir_kptr(J, (void *)frame_pc(frame)); - emitir(IRTG(IR_RETF, IRT_P32), trpt, trpc); + emitir(IRTG(IR_RETF, IRT_PGC), trpt, trpc); J->retdepth++; J->needsnap = 1; - lua_assert(J->baseslot == 1); + lua_assert(J->baseslot == 1+LJ_FR2); /* Shift result slots up and clear the slots of the new frame below. */ - memmove(J->base + cbase, J->base-1, sizeof(TRef)*nresults); - memset(J->base-1, 0, sizeof(TRef)*(cbase+1)); + memmove(J->base + cbase, J->base-1-LJ_FR2, sizeof(TRef)*nresults); + memset(J->base-1-LJ_FR2, 0, sizeof(TRef)*(cbase+1+LJ_FR2)); } } else if (frame_iscont(frame)) { /* Return to continuation frame. */ ASMFunction cont = frame_contf(frame); @@ -839,32 +869,39 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults) lj_trace_err(J, LJ_TRERR_NYIRETL); J->baseslot -= (BCReg)cbase; J->base -= cbase; - J->maxslot = cbase-2; + J->maxslot = cbase-(2<<LJ_FR2); if (cont == lj_cont_ra) { /* Copy result to destination slot. */ BCReg dst = bc_a(*(frame_contpc(frame)-1)); J->base[dst] = gotresults ? J->base[cbase+rbase] : TREF_NIL; - if (dst >= J->maxslot) J->maxslot = dst+1; + if (dst >= J->maxslot) { + J->maxslot = dst+1; + } } else if (cont == lj_cont_nop) { /* Nothing to do here. */ } else if (cont == lj_cont_cat) { BCReg bslot = bc_b(*(frame_contpc(frame)-1)); TRef tr = gotresults ? J->base[cbase+rbase] : TREF_NIL; - if (bslot != cbase-2) { /* Concatenate the remainder. */ + if (bslot != J->maxslot) { /* Concatenate the remainder. */ TValue *b = J->L->base, save; /* Simulate lower frame and result. */ - J->base[cbase-2] = tr; - copyTV(J->L, &save, b-2); - if (gotresults) copyTV(J->L, b-2, b+rbase); else setnilV(b-2); + J->base[J->maxslot] = tr; + copyTV(J->L, &save, b-(2<<LJ_FR2)); + if (gotresults) + copyTV(J->L, b-(2<<LJ_FR2), b+rbase); + else + setnilV(b-(2<<LJ_FR2)); J->L->base = b - cbase; - tr = rec_cat(J, bslot, cbase-2); + tr = rec_cat(J, bslot, cbase-(2<<LJ_FR2)); b = J->L->base + cbase; /* Undo. */ J->L->base = b; - copyTV(J->L, b-2, &save); + copyTV(J->L, b-(2<<LJ_FR2), &save); } if (tr) { /* Store final result. */ BCReg dst = bc_a(*(frame_contpc(frame)-1)); J->base[dst] = tr; - if (dst >= J->maxslot) J->maxslot = dst+1; + if (dst >= J->maxslot) { + J->maxslot = dst+1; + } } /* Otherwise continue with another __concat call. */ } else { /* Result type already specialized. */ @@ -873,7 +910,7 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults) } else { lj_trace_err(J, LJ_TRERR_NYIRETL); /* NYI: handle return to C frame. */ } - lua_assert(J->baseslot >= 1); + lua_assert(J->baseslot >= 1+LJ_FR2); } /* -- Metamethod handling ------------------------------------------------- */ @@ -882,16 +919,16 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults) static BCReg rec_mm_prep(jit_State *J, ASMFunction cont) { BCReg s, top = cont == lj_cont_cat ? J->maxslot : curr_proto(J->L)->framesize; -#if LJ_64 - TRef trcont = lj_ir_kptr(J, (void *)((int64_t)cont-(int64_t)lj_vm_asm_begin)); +#if LJ_FR2 + J->base[top] = lj_ir_k64(J, IR_KNUM, u64ptr(contptr(cont))); + J->base[top+1] = TREF_CONT; #else - TRef trcont = lj_ir_kptr(J, (void *)cont); + J->base[top] = lj_ir_kptr(J, contptr(cont)) | TREF_CONT; #endif - J->base[top] = trcont | TREF_CONT; J->framedepth++; for (s = J->maxslot; s < top; s++) J->base[s] = 0; /* Clear frame gap to avoid resurrecting previous refs. */ - return top+1; + return top+1+LJ_FR2; } /* Record metamethod lookup. */ @@ -910,7 +947,7 @@ int lj_record_mm_lookup(jit_State *J, RecordIndex *ix, MMS mm) cTValue *mo; if (LJ_HASFFI && udtype == UDTYPE_FFI_CLIB) { /* Specialize to the C library namespace object. */ - emitir(IRTG(IR_EQ, IRT_P32), ix->tab, lj_ir_kptr(J, udataV(&ix->tabv))); + emitir(IRTG(IR_EQ, IRT_PGC), ix->tab, lj_ir_kptr(J, udataV(&ix->tabv))); } else { /* Specialize to the type of userdata. */ TRef tr = emitir(IRT(IR_FLOAD, IRT_U8), ix->tab, IRFL_UDATA_UDTYPE); @@ -939,7 +976,13 @@ int lj_record_mm_lookup(jit_State *J, RecordIndex *ix, MMS mm) } /* The cdata metatable is treated as immutable. */ if (LJ_HASFFI && tref_iscdata(ix->tab)) goto immutable_mt; +#if LJ_GC64 + /* TODO: fix ARM32 asm_fload(), so we can use this for all archs. */ + ix->mt = mix.tab = lj_ir_ggfload(J, IRT_TAB, + GG_OFS(g.gcroot[GCROOT_BASEMT+itypemap(&ix->tabv)])); +#else ix->mt = mix.tab = lj_ir_ktab(J, mt); +#endif goto nocheck; } ix->mt = mt ? mix.tab : TREF_NIL; @@ -969,9 +1012,9 @@ static TRef rec_mm_arith(jit_State *J, RecordIndex *ix, MMS mm) BCReg func = rec_mm_prep(J, mm == MM_concat ? lj_cont_cat : lj_cont_ra); TRef *base = J->base + func; TValue *basev = J->L->base + func; - base[1] = ix->tab; base[2] = ix->key; - copyTV(J->L, basev+1, &ix->tabv); - copyTV(J->L, basev+2, &ix->keyv); + base[1+LJ_FR2] = ix->tab; base[2+LJ_FR2] = ix->key; + copyTV(J->L, basev+1+LJ_FR2, &ix->tabv); + copyTV(J->L, basev+2+LJ_FR2, &ix->keyv); if (!lj_record_mm_lookup(J, ix, mm)) { /* Lookup mm on 1st operand. */ if (mm != MM_unm) { ix->tab = ix->key; @@ -982,8 +1025,10 @@ static TRef rec_mm_arith(jit_State *J, RecordIndex *ix, MMS mm) lj_trace_err(J, LJ_TRERR_NOMM); } ok: - lua_assert(!LJ_FR2); /* TODO_FR2: handle different frame setup. */ base[0] = ix->mobj; +#if LJ_FR2 + base[1] = 0; +#endif copyTV(J->L, basev+0, &ix->mobjv); lj_record_call(J, func, 2); return 0; /* No result yet. */ @@ -999,8 +1044,9 @@ static TRef rec_mm_len(jit_State *J, TRef tr, TValue *tv) BCReg func = rec_mm_prep(J, lj_cont_ra); TRef *base = J->base + func; TValue *basev = J->L->base + func; - lua_assert(!LJ_FR2); /* TODO_FR2: handle different frame setup. */ base[0] = ix.mobj; copyTV(J->L, basev+0, &ix.mobjv); + base += LJ_FR2; + basev += LJ_FR2; base[1] = tr; copyTV(J->L, basev+1, tv); #if LJ_52 base[2] = tr; copyTV(J->L, basev+2, tv); @@ -1020,11 +1066,10 @@ static TRef rec_mm_len(jit_State *J, TRef tr, TValue *tv) static void rec_mm_callcomp(jit_State *J, RecordIndex *ix, int op) { BCReg func = rec_mm_prep(J, (op&1) ? lj_cont_condf : lj_cont_condt); - TRef *base = J->base + func; - TValue *tv = J->L->base + func; - lua_assert(!LJ_FR2); /* TODO_FR2: handle different frame setup. */ - base[0] = ix->mobj; base[1] = ix->val; base[2] = ix->key; - copyTV(J->L, tv+0, &ix->mobjv); + TRef *base = J->base + func + LJ_FR2; + TValue *tv = J->L->base + func + LJ_FR2; + base[-LJ_FR2] = ix->mobj; base[1] = ix->val; base[2] = ix->key; + copyTV(J->L, tv-LJ_FR2, &ix->mobjv); copyTV(J->L, tv+1, &ix->valv); copyTV(J->L, tv+2, &ix->keyv); lj_record_call(J, func, 2); @@ -1257,8 +1302,8 @@ static TRef rec_idx_key(jit_State *J, RecordIndex *ix, IRRef *rbref, if ((MSize)k < t->asize) { /* Currently an array key? */ TRef arrayref; rec_idx_abc(J, asizeref, ikey, t->asize); - arrayref = emitir(IRT(IR_FLOAD, IRT_P32), ix->tab, IRFL_TAB_ARRAY); - return emitir(IRT(IR_AREF, IRT_P32), arrayref, ikey); + arrayref = emitir(IRT(IR_FLOAD, IRT_PGC), ix->tab, IRFL_TAB_ARRAY); + return emitir(IRT(IR_AREF, IRT_PGC), arrayref, ikey); } else { /* Currently not in array (may be an array extension)? */ emitir(IRTGI(IR_ULE), asizeref, ikey); /* Inv. bounds check. */ if (k == 0 && tref_isk(key)) @@ -1298,13 +1343,13 @@ static TRef rec_idx_key(jit_State *J, RecordIndex *ix, IRRef *rbref, *rbguard = J->guardemit; hm = emitir(IRTI(IR_FLOAD), ix->tab, IRFL_TAB_HMASK); emitir(IRTGI(IR_EQ), hm, lj_ir_kint(J, (int32_t)t->hmask)); - node = emitir(IRT(IR_FLOAD, IRT_P32), ix->tab, IRFL_TAB_NODE); + node = emitir(IRT(IR_FLOAD, IRT_PGC), ix->tab, IRFL_TAB_NODE); kslot = lj_ir_kslot(J, key, hslot / sizeof(Node)); - return emitir(IRTG(IR_HREFK, IRT_P32), node, kslot); + return emitir(IRTG(IR_HREFK, IRT_PGC), node, kslot); } } /* Fall back to a regular hash lookup. */ - return emitir(IRT(IR_HREF, IRT_P32), ix->tab, key); + return emitir(IRT(IR_HREF, IRT_PGC), ix->tab, key); } /* Determine whether a key is NOT one of the fast metamethod names. */ @@ -1341,11 +1386,10 @@ TRef lj_record_idx(jit_State *J, RecordIndex *ix) handlemm: if (tref_isfunc(ix->mobj)) { /* Handle metamethod call. */ BCReg func = rec_mm_prep(J, ix->val ? lj_cont_nop : lj_cont_ra); - TRef *base = J->base + func; - TValue *tv = J->L->base + func; - lua_assert(!LJ_FR2); /* TODO_FR2: handle different frame setup. */ - base[0] = ix->mobj; base[1] = ix->tab; base[2] = ix->key; - setfuncV(J->L, tv+0, funcV(&ix->mobjv)); + TRef *base = J->base + func + LJ_FR2; + TValue *tv = J->L->base + func + LJ_FR2; + base[-LJ_FR2] = ix->mobj; base[1] = ix->tab; base[2] = ix->key; + setfuncV(J->L, tv-LJ_FR2, funcV(&ix->mobjv)); copyTV(J->L, tv+1, &ix->tabv); copyTV(J->L, tv+2, &ix->keyv); if (ix->val) { @@ -1387,7 +1431,7 @@ TRef lj_record_idx(jit_State *J, RecordIndex *ix) IRType t = itype2irt(oldv); TRef res; if (oldv == niltvg(J2G(J))) { - emitir(IRTG(IR_EQ, IRT_P32), xref, lj_ir_kkptr(J, niltvg(J2G(J)))); + emitir(IRTG(IR_EQ, IRT_PGC), xref, lj_ir_kkptr(J, niltvg(J2G(J)))); res = TREF_NIL; } else { res = emitir(IRTG(loadop, t), xref, 0); @@ -1417,7 +1461,7 @@ TRef lj_record_idx(jit_State *J, RecordIndex *ix) if (hasmm) emitir(IRTG(loadop, IRT_NIL), xref, 0); /* Guard for nil value. */ else if (xrefop == IR_HREF) - emitir(IRTG(oldv == niltvg(J2G(J)) ? IR_EQ : IR_NE, IRT_P32), + emitir(IRTG(oldv == niltvg(J2G(J)) ? IR_EQ : IR_NE, IRT_PGC), xref, lj_ir_kkptr(J, niltvg(J2G(J)))); if (ix->idxchain && lj_record_mm_lookup(J, ix, MM_newindex)) { lua_assert(hasmm); @@ -1428,7 +1472,7 @@ TRef lj_record_idx(jit_State *J, RecordIndex *ix) TRef key = ix->key; if (tref_isinteger(key)) /* NEWREF needs a TValue as a key. */ key = emitir(IRTN(IR_CONV), key, IRCONV_NUM_INT); - xref = emitir(IRT(IR_NEWREF, IRT_P32), ix->tab, key); + xref = emitir(IRT(IR_NEWREF, IRT_PGC), ix->tab, key); keybarrier = 0; /* NEWREF already takes care of the key barrier. */ #ifdef LUAJIT_ENABLE_TABLE_BUMP if ((J->flags & JIT_F_OPT_SINK)) /* Avoid a separate flag. */ @@ -1438,7 +1482,7 @@ TRef lj_record_idx(jit_State *J, RecordIndex *ix) } else if (!lj_opt_fwd_wasnonnil(J, loadop, tref_ref(xref))) { /* Cannot derive that the previous value was non-nil, must do checks. */ if (xrefop == IR_HREF) /* Guard against store to niltv. */ - emitir(IRTG(IR_NE, IRT_P32), xref, lj_ir_kkptr(J, niltvg(J2G(J)))); + emitir(IRTG(IR_NE, IRT_PGC), xref, lj_ir_kkptr(J, niltvg(J2G(J)))); if (ix->idxchain) { /* Metamethod lookup required? */ /* A check for NULL metatable is cheaper (hoistable) than a load. */ if (!mt) { @@ -1460,7 +1504,7 @@ TRef lj_record_idx(jit_State *J, RecordIndex *ix) emitir(IRT(IR_TBAR, IRT_NIL), ix->tab, 0); /* Invalidate neg. metamethod cache for stores with certain string keys. */ if (!nommstr(J, ix->key)) { - TRef fref = emitir(IRT(IR_FREF, IRT_P32), ix->tab, IRFL_TAB_NOMM); + TRef fref = emitir(IRT(IR_FREF, IRT_PGC), ix->tab, IRFL_TAB_NOMM); emitir(IRT(IR_FSTORE, IRT_U8), fref, lj_ir_kint(J, 0)); } J->needsnap = 1; @@ -1535,7 +1579,11 @@ static TRef rec_upvalue(jit_State *J, uint32_t uv, TRef val) goto noconstify; kfunc = lj_ir_kfunc(J, J->fn); emitir(IRTG(IR_EQ, IRT_FUNC), fn, kfunc); - J->base[-1] = TREF_FRAME | kfunc; +#if LJ_FR2 + J->base[-2] = kfunc; +#else + J->base[-1] = kfunc | TREF_FRAME; +#endif fn = kfunc; } tr = lj_record_constify(J, uvval(uvp)); @@ -1546,13 +1594,17 @@ noconstify: /* Note: this effectively limits LJ_MAX_UPVAL to 127. */ uv = (uv << 8) | (hashrot(uvp->dhash, uvp->dhash + HASH_BIAS) & 0xff); if (!uvp->closed) { + uref = tref_ref(emitir(IRTG(IR_UREFO, IRT_PGC), fn, uv)); /* In current stack? */ if (uvval(uvp) >= tvref(J->L->stack) && uvval(uvp) < tvref(J->L->maxstack)) { int32_t slot = (int32_t)(uvval(uvp) - (J->L->base - J->baseslot)); if (slot >= 0) { /* Aliases an SSA slot? */ + emitir(IRTG(IR_EQ, IRT_PGC), + REF_BASE, + emitir(IRT(IR_ADD, IRT_PGC), uref, + lj_ir_kint(J, (slot - 1 - LJ_FR2) * -8))); slot -= (int32_t)J->baseslot; /* Note: slot number may be negative! */ - /* NYI: add IR to guard that it's still aliasing the same slot. */ if (val == 0) { return getslot(J, slot); } else { @@ -1562,10 +1614,12 @@ noconstify: } } } - uref = tref_ref(emitir(IRTG(IR_UREFO, IRT_P32), fn, uv)); + emitir(IRTG(IR_UGT, IRT_PGC), + emitir(IRT(IR_SUB, IRT_PGC), uref, REF_BASE), + lj_ir_kint(J, (J->baseslot + J->maxslot) * 8)); } else { needbarrier = 1; - uref = tref_ref(emitir(IRTG(IR_UREFC, IRT_P32), fn, uv)); + uref = tref_ref(emitir(IRTG(IR_UREFC, IRT_PGC), fn, uv)); } if (val == 0) { /* Upvalue load */ IRType t = itype2irt(uvval(uvp)); @@ -1640,11 +1694,14 @@ static void rec_func_setup(jit_State *J) static void rec_func_vararg(jit_State *J) { GCproto *pt = J->pt; - BCReg s, fixargs, vframe = J->maxslot+1; + BCReg s, fixargs, vframe = J->maxslot+1+LJ_FR2; lua_assert((pt->flags & PROTO_VARARG)); if (J->baseslot + vframe + pt->framesize >= LJ_MAX_JSLOTS) lj_trace_err(J, LJ_TRERR_STACKOV); - J->base[vframe-1] = J->base[-1]; /* Copy function up. */ + J->base[vframe-1-LJ_FR2] = J->base[-1-LJ_FR2]; /* Copy function up. */ +#if LJ_FR2 + J->base[vframe-1] = TREF_FRAME; +#endif /* Copy fixarg slots up and set their original slots to nil. */ fixargs = pt->numparams < J->maxslot ? pt->numparams : J->maxslot; for (s = 0; s < fixargs; s++) { @@ -1693,8 +1750,11 @@ static int select_detect(jit_State *J) BCIns ins = J->pc[1]; if (bc_op(ins) == BC_CALLM && bc_b(ins) == 2 && bc_c(ins) == 1) { cTValue *func = &J->L->base[bc_a(ins)]; - if (tvisfunc(func) && funcV(func)->c.ffid == FF_select) + if (tvisfunc(func) && funcV(func)->c.ffid == FF_select) { + TRef kfunc = lj_ir_kfunc(J, funcV(func)); + emitir(IRTG(IR_EQ, IRT_FUNC), getslot(J, bc_a(ins)), kfunc); return 1; + } } return 0; } @@ -1703,8 +1763,10 @@ static int select_detect(jit_State *J) static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults) { int32_t numparams = J->pt->numparams; - ptrdiff_t nvararg = frame_delta(J->L->base-1) - numparams - 1; + ptrdiff_t nvararg = frame_delta(J->L->base-1) - numparams - 1 - LJ_FR2; lua_assert(frame_isvarg(J->L->base-1)); + if (LJ_FR2 && dst > J->maxslot) + J->base[dst-1] = 0; /* Prevent resurrection of unrelated slot. */ if (J->framedepth > 0) { /* Simple case: varargs defined on-trace. */ ptrdiff_t i; if (nvararg < 0) nvararg = 0; @@ -1715,10 +1777,10 @@ static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults) J->maxslot = dst + (BCReg)nresults; } for (i = 0; i < nresults; i++) - J->base[dst+i] = i < nvararg ? getslot(J, i - nvararg - 1) : TREF_NIL; + J->base[dst+i] = i < nvararg ? getslot(J, i - nvararg - 1 - LJ_FR2) : TREF_NIL; } else { /* Unknown number of varargs passed to trace. */ - TRef fr = emitir(IRTI(IR_SLOAD), 0, IRSLOAD_READONLY|IRSLOAD_FRAME); - int32_t frofs = 8*(1+numparams)+FRAME_VARG; + TRef fr = emitir(IRTI(IR_SLOAD), LJ_FR2, IRSLOAD_READONLY|IRSLOAD_FRAME); + int32_t frofs = 8*(1+LJ_FR2+numparams)+FRAME_VARG; if (nresults >= 0) { /* Known fixed number of results. */ ptrdiff_t i; if (nvararg > 0) { @@ -1729,11 +1791,11 @@ static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults) else emitir(IRTGI(IR_EQ), fr, lj_ir_kint(J, (int32_t)frame_ftsz(J->L->base-1))); - vbase = emitir(IRTI(IR_SUB), REF_BASE, fr); - vbase = emitir(IRT(IR_ADD, IRT_P32), vbase, lj_ir_kint(J, frofs-8)); + vbase = emitir(IRT(IR_SUB, IRT_IGC), REF_BASE, fr); + vbase = emitir(IRT(IR_ADD, IRT_PGC), vbase, lj_ir_kint(J, frofs-8)); for (i = 0; i < nload; i++) { - IRType t = itype2irt(&J->L->base[i-1-nvararg]); - TRef aref = emitir(IRT(IR_AREF, IRT_P32), + IRType t = itype2irt(&J->L->base[i-1-LJ_FR2-nvararg]); + TRef aref = emitir(IRT(IR_AREF, IRT_PGC), vbase, lj_ir_kint(J, (int32_t)i)); TRef tr = emitir(IRTG(IR_VLOAD, t), aref, 0); if (irtype_ispri(t)) tr = TREF_PRI(t); /* Canonicalize primitives. */ @@ -1779,15 +1841,16 @@ static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults) } if (idx != 0 && idx <= nvararg) { IRType t; - TRef aref, vbase = emitir(IRTI(IR_SUB), REF_BASE, fr); - vbase = emitir(IRT(IR_ADD, IRT_P32), vbase, lj_ir_kint(J, frofs-8)); - t = itype2irt(&J->L->base[idx-2-nvararg]); - aref = emitir(IRT(IR_AREF, IRT_P32), vbase, tridx); + TRef aref, vbase = emitir(IRT(IR_SUB, IRT_IGC), REF_BASE, fr); + vbase = emitir(IRT(IR_ADD, IRT_PGC), vbase, + lj_ir_kint(J, frofs-(8<<LJ_FR2))); + t = itype2irt(&J->L->base[idx-2-LJ_FR2-nvararg]); + aref = emitir(IRT(IR_AREF, IRT_PGC), vbase, tridx); tr = emitir(IRTG(IR_VLOAD, t), aref, 0); if (irtype_ispri(t)) tr = TREF_PRI(t); /* Canonicalize primitives. */ } - J->base[dst-2] = tr; - J->maxslot = dst-1; + J->base[dst-2-LJ_FR2] = tr; + J->maxslot = dst-1-LJ_FR2; J->bcskip = 2; /* Skip CALLM + select. */ } else { nyivarg: @@ -1836,10 +1899,10 @@ static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot) break; } xbase = ++trp; - tr = hdr = emitir(IRT(IR_BUFHDR, IRT_P32), + tr = hdr = emitir(IRT(IR_BUFHDR, IRT_PGC), lj_ir_kptr(J, &J2G(J)->tmpbuf), IRBUFHDR_RESET); do { - tr = emitir(IRT(IR_BUFPUT, IRT_P32), tr, *trp++); + tr = emitir(IRT(IR_BUFPUT, IRT_PGC), tr, *trp++); } while (trp <= top); tr = emitir(IRT(IR_BUFSTR, IRT_STR), tr, hdr); J->maxslot = (BCReg)(xbase - J->base); @@ -1880,7 +1943,15 @@ static void rec_comp_fixup(jit_State *J, const BCIns *pc, int cond) const BCIns *npc = pc + 2 + (cond ? bc_j(jmpins) : 0); SnapShot *snap = &J->cur.snap[J->cur.nsnap-1]; /* Set PC to opposite target to avoid re-recording the comp. in side trace. */ +#if LJ_FR2 + SnapEntry *flink = &J->cur.snapmap[snap->mapofs + snap->nent]; + uint64_t pcbase; + memcpy(&pcbase, flink, sizeof(uint64_t)); + pcbase = (pcbase & 0xff) | (u64ptr(npc) << 8); + memcpy(flink, &pcbase, sizeof(uint64_t)); +#else J->cur.snapmap[snap->mapofs + snap->nent] = SNAP_MKPC(npc); +#endif J->needsnap = 1; if (bc_a(jmpins) < J->maxslot) J->maxslot = bc_a(jmpins); lj_snap_shrink(J); /* Shrink last snapshot if possible. */ @@ -2156,14 +2227,14 @@ void lj_record_ins(jit_State *J) case BC_MODVN: case BC_MODVV: recmod: if (tref_isnumber_str(rb) && tref_isnumber_str(rc)) - rc = lj_opt_narrow_mod(J, rb, rc, rcv); + rc = lj_opt_narrow_mod(J, rb, rc, rbv, rcv); else rc = rec_mm_arith(J, &ix, MM_mod); break; case BC_POW: if (tref_isnumber_str(rb) && tref_isnumber_str(rc)) - rc = lj_opt_narrow_pow(J, lj_ir_tonum(J, rb), rc, rcv); + rc = lj_opt_narrow_pow(J, rb, rc, rbv, rcv); else rc = rec_mm_arith(J, &ix, MM_pow); break; @@ -2178,7 +2249,13 @@ void lj_record_ins(jit_State *J) case BC_MOV: /* Clear gap of method call to avoid resurrecting previous refs. */ - if (ra > J->maxslot) J->base[ra-1] = 0; + if (ra > J->maxslot) { +#if LJ_FR2 + memset(J->base + J->maxslot, 0, (ra - J->maxslot) * sizeof(TRef)); +#else + J->base[ra-1] = 0; +#endif + } break; case BC_KSTR: case BC_KNUM: case BC_KPRI: break; @@ -2186,6 +2263,8 @@ void lj_record_ins(jit_State *J) rc = lj_ir_kint(J, (int32_t)(int16_t)rc); break; case BC_KNIL: + if (LJ_FR2 && ra > J->maxslot) + J->base[ra-1] = 0; while (ra <= rc) J->base[ra++] = TREF_NIL; if (rc >= J->maxslot) J->maxslot = rc+1; @@ -2247,14 +2326,14 @@ void lj_record_ins(jit_State *J) /* -- Calls and vararg handling ----------------------------------------- */ case BC_ITERC: - J->base[ra] = getslot(J, ra-3-LJ_FR2); - J->base[ra+1] = getslot(J, ra-2-LJ_FR2); - J->base[ra+2] = getslot(J, ra-1-LJ_FR2); + J->base[ra] = getslot(J, ra-3); + J->base[ra+1+LJ_FR2] = getslot(J, ra-2); + J->base[ra+2+LJ_FR2] = getslot(J, ra-1); { /* Do the actual copy now because lj_record_call needs the values. */ TValue *b = &J->L->base[ra]; - copyTV(J->L, b, b-3-LJ_FR2); - copyTV(J->L, b+1, b-2-LJ_FR2); - copyTV(J->L, b+2, b-1-LJ_FR2); + copyTV(J->L, b, b-3); + copyTV(J->L, b+1+LJ_FR2, b-2); + copyTV(J->L, b+2+LJ_FR2, b-1); } lj_record_call(J, ra, (ptrdiff_t)rc-1); break; @@ -2377,7 +2456,12 @@ void lj_record_ins(jit_State *J) /* rc == 0 if we have no result yet, e.g. pending __index metamethod call. */ if (bcmode_a(op) == BCMdst && rc) { J->base[ra] = rc; - if (ra >= J->maxslot) J->maxslot = ra+1; + if (ra >= J->maxslot) { +#if LJ_FR2 + if (ra > J->maxslot) J->base[ra-1] = 0; +#endif + J->maxslot = ra+1; + } } #undef rav @@ -2462,7 +2546,7 @@ void lj_record_setup(jit_State *J) J->scev.idx = REF_NIL; setmref(J->scev.pc, NULL); - J->baseslot = 1; /* Invoking function is at base[-1]. */ + J->baseslot = 1+LJ_FR2; /* Invoking function is at base[-1-LJ_FR2]. */ J->base = J->slot + J->baseslot; J->maxslot = 0; J->framedepth = 0; @@ -2477,7 +2561,7 @@ void lj_record_setup(jit_State *J) J->bc_extent = ~(MSize)0; /* Emit instructions for fixed references. Also triggers initial IR alloc. */ - emitir_raw(IRT(IR_BASE, IRT_P32), J->parent, J->exitno); + emitir_raw(IRT(IR_BASE, IRT_PGC), J->parent, J->exitno); for (i = 0; i <= 2; i++) { IRIns *ir = IR(REF_NIL-i); ir->i = 0; diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_record.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_record.h index cb184e8f6b9..93d374d2494 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_record.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_record.h @@ -1,6 +1,6 @@ /* ** Trace recorder (bytecode -> SSA IR). -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_RECORD_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_snap.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_snap.c index 8638d9edbfd..bb063c2b652 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_snap.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_snap.c @@ -1,6 +1,6 @@ /* ** Snapshot handling. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_snap_c @@ -68,10 +68,22 @@ static MSize snapshot_slots(jit_State *J, SnapEntry *map, BCReg nslots) for (s = 0; s < nslots; s++) { TRef tr = J->slot[s]; IRRef ref = tref_ref(tr); +#if LJ_FR2 + if (s == 1) { /* Ignore slot 1 in LJ_FR2 mode, except if tailcalled. */ + if ((tr & TREF_FRAME)) + map[n++] = SNAP(1, SNAP_FRAME | SNAP_NORESTORE, REF_NIL); + continue; + } + if ((tr & (TREF_FRAME | TREF_CONT)) && !ref) { + cTValue *base = J->L->base - J->baseslot; + tr = J->slot[s] = (tr & 0xff0000) | lj_ir_k64(J, IR_KNUM, base[s].u64); + ref = tref_ref(tr); + } +#endif if (ref) { SnapEntry sn = SNAP_TR(s, tr); IRIns *ir = &J->cur.ir[ref]; - if (!(sn & (SNAP_CONT|SNAP_FRAME)) && + if ((LJ_FR2 || !(sn & (SNAP_CONT|SNAP_FRAME))) && ir->o == IR_SLOAD && ir->op1 == s && ref > retf) { /* No need to snapshot unmodified non-inherited slots. */ if (!(ir->op2 & IRSLOAD_INHERIT)) @@ -90,34 +102,51 @@ static MSize snapshot_slots(jit_State *J, SnapEntry *map, BCReg nslots) } /* Add frame links at the end of the snapshot. */ -static BCReg snapshot_framelinks(jit_State *J, SnapEntry *map) +static MSize snapshot_framelinks(jit_State *J, SnapEntry *map, uint8_t *topslot) { cTValue *frame = J->L->base - 1; - cTValue *lim = J->L->base - J->baseslot; + cTValue *lim = J->L->base - J->baseslot + LJ_FR2; GCfunc *fn = frame_func(frame); cTValue *ftop = isluafunc(fn) ? (frame+funcproto(fn)->framesize) : J->L->top; +#if LJ_FR2 + uint64_t pcbase = (u64ptr(J->pc) << 8) | (J->baseslot - 2); + lua_assert(2 <= J->baseslot && J->baseslot <= 257); + memcpy(map, &pcbase, sizeof(uint64_t)); +#else MSize f = 0; - lua_assert(!LJ_FR2); /* TODO_FR2: store 64 bit PCs. */ map[f++] = SNAP_MKPC(J->pc); /* The current PC is always the first entry. */ +#endif while (frame > lim) { /* Backwards traversal of all frames above base. */ if (frame_islua(frame)) { +#if !LJ_FR2 map[f++] = SNAP_MKPC(frame_pc(frame)); +#endif frame = frame_prevl(frame); } else if (frame_iscont(frame)) { +#if !LJ_FR2 map[f++] = SNAP_MKFTSZ(frame_ftsz(frame)); map[f++] = SNAP_MKPC(frame_contpc(frame)); +#endif frame = frame_prevd(frame); } else { lua_assert(!frame_isc(frame)); +#if !LJ_FR2 map[f++] = SNAP_MKFTSZ(frame_ftsz(frame)); +#endif frame = frame_prevd(frame); continue; } if (frame + funcproto(frame_func(frame))->framesize > ftop) ftop = frame + funcproto(frame_func(frame))->framesize; } + *topslot = (uint8_t)(ftop - lim); +#if LJ_FR2 + lua_assert(sizeof(SnapEntry) * 2 == sizeof(uint64_t)); + return 2; +#else lua_assert(f == (MSize)(1 + J->framedepth)); - return (BCReg)(ftop - lim); + return f; +#endif } /* Take a snapshot of the current stack. */ @@ -127,16 +156,16 @@ static void snapshot_stack(jit_State *J, SnapShot *snap, MSize nsnapmap) MSize nent; SnapEntry *p; /* Conservative estimate. */ - lj_snap_grow_map(J, nsnapmap + nslots + (MSize)J->framedepth+1); + lj_snap_grow_map(J, nsnapmap + nslots + (MSize)(LJ_FR2?2:J->framedepth+1)); p = &J->cur.snapmap[nsnapmap]; nent = snapshot_slots(J, p, nslots); - snap->topslot = (uint8_t)snapshot_framelinks(J, p + nent); + snap->nent = (uint8_t)nent; + nent += snapshot_framelinks(J, p + nent, &snap->topslot); snap->mapofs = (uint16_t)nsnapmap; snap->ref = (IRRef1)J->cur.nins; - snap->nent = (uint8_t)nent; snap->nslots = (uint8_t)nslots; snap->count = 0; - J->cur.nsnapmap = (uint16_t)(nsnapmap + nent + 1 + J->framedepth); + J->cur.nsnapmap = (uint16_t)(nsnapmap + nent); } /* Add or merge a snapshot. */ @@ -284,8 +313,8 @@ void lj_snap_shrink(jit_State *J) MSize n, m, nlim, nent = snap->nent; uint8_t udf[SNAP_USEDEF_SLOTS]; BCReg maxslot = J->maxslot; - BCReg minslot = snap_usedef(J, udf, snap_pc(map[nent]), maxslot); BCReg baseslot = J->baseslot; + BCReg minslot = snap_usedef(J, udf, snap_pc(&map[nent]), maxslot); maxslot += baseslot; minslot += baseslot; snap->nslots = (uint8_t)maxslot; @@ -371,8 +400,8 @@ static TRef snap_replay_const(jit_State *J, IRIns *ir) case IR_KPRI: return TREF_PRI(irt_type(ir->t)); case IR_KINT: return lj_ir_kint(J, ir->i); case IR_KGC: return lj_ir_kgc(J, ir_kgc(ir), irt_t(ir->t)); - case IR_KNUM: return lj_ir_k64(J, IR_KNUM, ir_knum(ir)); - case IR_KINT64: return lj_ir_k64(J, IR_KINT64, ir_kint64(ir)); + case IR_KNUM: case IR_KINT64: + return lj_ir_k64(J, (IROp)ir->o, ir_k64(ir)->u64); case IR_KPTR: return lj_ir_kptr(J, ir_kptr(ir)); /* Continuation. */ default: lua_assert(0); return TREF_NIL; break; } @@ -445,7 +474,11 @@ void lj_snap_replay(jit_State *J, GCtrace *T) goto setslot; bloomset(seen, ref); if (irref_isk(ref)) { - tr = snap_replay_const(J, ir); + /* See special treatment of LJ_FR2 slot 1 in snapshot_slots() above. */ + if (LJ_FR2 && (sn == SNAP(1, SNAP_FRAME | SNAP_NORESTORE, REF_NIL))) + tr = 0; + else + tr = snap_replay_const(J, ir); } else if (!regsp_used(ir->prev)) { pass23 = 1; lua_assert(s != 0); @@ -459,7 +492,7 @@ void lj_snap_replay(jit_State *J, GCtrace *T) } setslot: J->slot[s] = tr | (sn&(SNAP_CONT|SNAP_FRAME)); /* Same as TREF_* flags. */ - J->framedepth += ((sn & (SNAP_CONT|SNAP_FRAME)) && s); + J->framedepth += ((sn & (SNAP_CONT|SNAP_FRAME)) && (s != LJ_FR2)); if ((sn & SNAP_FRAME)) J->baseslot = s+1; } @@ -555,8 +588,7 @@ void lj_snap_replay(jit_State *J, GCtrace *T) if (irref_isk(irs->op2) && irref_isk((irs+1)->op2)) { uint64_t k = (uint32_t)T->ir[irs->op2].i + ((uint64_t)T->ir[(irs+1)->op2].i << 32); - val = lj_ir_k64(J, t == IRT_I64 ? IR_KINT64 : IR_KNUM, - lj_ir_k64_find(J, k)); + val = lj_ir_k64(J, t == IRT_I64 ? IR_KINT64 : IR_KNUM, k); } else { val = emitir_raw(IRT(IR_HIOP, t), val, snap_pref(J, T, map, nent, seen, (irs+1)->op2)); @@ -599,7 +631,6 @@ static void snap_restoreval(jit_State *J, GCtrace *T, ExitState *ex, } if (LJ_UNLIKELY(bloomtest(rfilt, ref))) rs = snap_renameref(T, snapno, ref, rs); - lua_assert(!LJ_GC64); /* TODO_GC64: handle 64 bit references. */ if (ra_hasspill(regsp_spill(rs))) { /* Restore from spill slot. */ int32_t *sps = &ex->spill[regsp_spill(rs)]; if (irt_isinteger(t)) { @@ -608,9 +639,11 @@ static void snap_restoreval(jit_State *J, GCtrace *T, ExitState *ex, } else if (irt_isnum(t)) { o->u64 = *(uint64_t *)sps; #endif - } else if (LJ_64 && irt_islightud(t)) { +#if LJ_64 && !LJ_GC64 + } else if (irt_islightud(t)) { /* 64 bit lightuserdata which may escape already has the tag bits. */ o->u64 = *(uint64_t *)sps; +#endif } else { lua_assert(!irt_ispri(t)); /* PRI refs never have a spill slot. */ setgcV(J->L, o, (GCobj *)(uintptr_t)*(GCSize *)sps, irt_toitype(t)); @@ -628,9 +661,11 @@ static void snap_restoreval(jit_State *J, GCtrace *T, ExitState *ex, } else if (irt_isnum(t)) { setnumV(o, ex->fpr[r-RID_MIN_FPR]); #endif - } else if (LJ_64 && irt_is64(t)) { +#if LJ_64 && !LJ_GC64 + } else if (irt_is64(t)) { /* 64 bit values that already have the tag bits. */ o->u64 = ex->gpr[r-RID_MIN_GPR]; +#endif } else if (irt_ispri(t)) { setpriV(o, irt_toitype(t)); } else { @@ -651,7 +686,7 @@ static void snap_restoredata(GCtrace *T, ExitState *ex, uint64_t tmp; if (irref_isk(ref)) { if (ir->o == IR_KNUM || ir->o == IR_KINT64) { - src = mref(ir->ptr, int32_t); + src = (int32_t *)&ir[1]; } else if (sz == 8) { tmp = (uint64_t)(uint32_t)ir->i; src = (int32_t *)&tmp; @@ -688,8 +723,9 @@ static void snap_restoredata(GCtrace *T, ExitState *ex, #else if (LJ_BE && sz == 4) src++; #endif - } + } else #endif + if (LJ_64 && LJ_BE && sz == 4) src++; } } lua_assert(sz == 1 || sz == 2 || sz == 4 || sz == 8); @@ -795,11 +831,15 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr) SnapShot *snap = &T->snap[snapno]; MSize n, nent = snap->nent; SnapEntry *map = &T->snapmap[snap->mapofs]; - SnapEntry *flinks = &T->snapmap[snap_nextofs(T, snap)-1]; +#if !LJ_FR2 || defined(LUA_USE_ASSERT) + SnapEntry *flinks = &T->snapmap[snap_nextofs(T, snap)-1-LJ_FR2]; +#endif +#if !LJ_FR2 ptrdiff_t ftsz0; +#endif TValue *frame; BloomFilter rfilt = snap_renamefilter(T, snapno); - const BCIns *pc = snap_pc(map[nent]); + const BCIns *pc = snap_pc(&map[nent]); lua_State *L = J->L; /* Set interpreter PC to the next PC to get correct error messages. */ @@ -812,8 +852,10 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr) } /* Fill stack slots with data from the registers and spill slots. */ - frame = L->base-1; + frame = L->base-1-LJ_FR2; +#if !LJ_FR2 ftsz0 = frame_ftsz(frame); /* Preserve link to previous frame in slot #0. */ +#endif for (n = 0; n < nent; n++) { SnapEntry sn = map[n]; if (!(sn & SNAP_NORESTORE)) { @@ -836,14 +878,18 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr) TValue tmp; snap_restoreval(J, T, ex, snapno, rfilt, ref+1, &tmp); o->u32.hi = tmp.u32.lo; +#if !LJ_FR2 } else if ((sn & (SNAP_CONT|SNAP_FRAME))) { - lua_assert(!LJ_FR2); /* TODO_FR2: store 64 bit PCs. */ /* Overwrite tag with frame link. */ setframe_ftsz(o, snap_slot(sn) != 0 ? (int32_t)*flinks-- : ftsz0); L->base = o+1; +#endif } } } +#if LJ_FR2 + L->base += (map[nent+LJ_BE] & 0xff); +#endif lua_assert(map + nent == flinks); /* Compute current stack top. */ diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_snap.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_snap.h index 1d3379bc6f4..2c9ae3d643a 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_snap.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_snap.h @@ -1,6 +1,6 @@ /* ** Snapshot handling. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_SNAP_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_state.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_state.c index 66bf439f822..632dd07e5f9 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_state.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_state.c @@ -1,6 +1,6 @@ /* ** State and stack handling. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h ** ** Portions taken verbatim or adapted from the Lua interpreter. ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h @@ -180,7 +180,7 @@ static void close_state(lua_State *L) g->allocf(g->allocd, G2GG(g), sizeof(GG_State), 0); } -#if LJ_64 && !(defined(LUAJIT_USE_VALGRIND) && defined(LUAJIT_USE_SYSMALLOC)) +#if LJ_64 && !LJ_GC64 && !(defined(LUAJIT_USE_VALGRIND) && defined(LUAJIT_USE_SYSMALLOC)) lua_State *lj_state_newstate(lua_Alloc f, void *ud) #else LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud) @@ -224,7 +224,7 @@ LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud) close_state(L); return NULL; } - L->status = 0; + L->status = LUA_OK; return L; } @@ -256,10 +256,10 @@ LUA_API void lua_close(lua_State *L) #endif for (i = 0;;) { hook_enter(g); - L->status = 0; + L->status = LUA_OK; L->base = L->top = tvref(L->stack) + 1 + LJ_FR2; L->cframe = NULL; - if (lj_vm_cpcall(L, NULL, NULL, cpfinalize) == 0) { + if (lj_vm_cpcall(L, NULL, NULL, cpfinalize) == LUA_OK) { if (++i >= 10) break; lj_gc_separateudata(g, 1); /* Separate udata again. */ if (gcref(g->gc.mmudata) == NULL) /* Until nothing is left to do. */ @@ -274,7 +274,7 @@ lua_State *lj_state_new(lua_State *L) lua_State *L1 = lj_mem_newobj(L, lua_State); L1->gct = ~LJ_TTHREAD; L1->dummy_ffid = FF_C; - L1->status = 0; + L1->status = LUA_OK; L1->stacksize = 0; setmref(L1->stack, NULL); L1->cframe = NULL; diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_state.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_state.h index e128d3211b3..02a0eafa332 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_state.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_state.h @@ -1,6 +1,6 @@ /* ** State and stack handling. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_STATE_H @@ -28,7 +28,7 @@ static LJ_AINLINE void lj_state_checkstack(lua_State *L, MSize need) LJ_FUNC lua_State *lj_state_new(lua_State *L); LJ_FUNC void LJ_FASTCALL lj_state_free(global_State *g, lua_State *L); -#if LJ_64 +#if LJ_64 && !LJ_GC64 && !(defined(LUAJIT_USE_VALGRIND) && defined(LUAJIT_USE_SYSMALLOC)) LJ_FUNC lua_State *lj_state_newstate(lua_Alloc f, void *ud); #endif diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_str.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_str.c index 086072c3807..ec11ab00c9e 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_str.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_str.c @@ -1,6 +1,6 @@ /* ** String handling. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_str_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_str.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_str.h index bb306c142ba..85c1e405bd7 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_str.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_str.h @@ -1,6 +1,6 @@ /* ** String handling. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_STR_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_strfmt.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_strfmt.c index 7c7d81d360f..d7893ce981b 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_strfmt.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_strfmt.c @@ -1,6 +1,6 @@ /* ** String formatting. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #include <stdio.h> @@ -98,11 +98,15 @@ char * LJ_FASTCALL lj_strfmt_wint(char *p, int32_t k) uint32_t u = (uint32_t)k; if (k < 0) { u = (uint32_t)-k; *p++ = '-'; } if (u < 10000) { - if (u < 10) goto dig1; if (u < 100) goto dig2; if (u < 1000) goto dig3; + if (u < 10) goto dig1; + if (u < 100) goto dig2; + if (u < 1000) goto dig3; } else { uint32_t v = u / 10000; u -= v * 10000; if (v < 10000) { - if (v < 10) goto dig5; if (v < 100) goto dig6; if (v < 1000) goto dig7; + if (v < 10) goto dig5; + if (v < 100) goto dig6; + if (v < 1000) goto dig7; } else { uint32_t w = v / 10000; v -= w * 10000; if (w >= 10) WINT_R(w, 10, 10) diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_strfmt.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_strfmt.h index a38bc7c38e1..6e1d9017e62 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_strfmt.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_strfmt.h @@ -1,6 +1,6 @@ /* ** String formatting. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_STRFMT_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_strfmt_num.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_strfmt_num.c index ab84fda76d2..9271f68a117 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_strfmt_num.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_strfmt_num.c @@ -1,6 +1,6 @@ /* ** String formatting for floating-point numbers. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h ** Contributed by Peter Cawley. */ @@ -138,7 +138,7 @@ static uint32_t nd_mul2k(uint32_t* nd, uint32_t ndhi, uint32_t k, } if (carry_in) { nd[++ndhi] = carry_in; carry_in = 0; - if(start++ == ndlo) ++ndlo; + if (start++ == ndlo) ++ndlo; } k -= ND_MUL2K_MAX_SHIFT; } @@ -364,6 +364,7 @@ static char *lj_strfmt_wfnum(SBuf *sb, SFormat sf, lua_Number n, char *p) /* Precision is sufficiently low that rescaling will probably work. */ if ((ndebias = rescale_e[e >> 6])) { t.n = n * rescale_n[e >> 6]; + if (LJ_UNLIKELY(!e)) t.n *= 1e10, ndebias -= 10; t.u64 -= 2; /* Convert 2ulp below (later we convert 2ulp above). */ nd[0] = 0x100000 | (t.u32.hi & 0xfffff); e = ((t.u32.hi >> 20) & 0x7ff) - 1075 - (ND_MUL2K_MAX_SHIFT < 29); @@ -479,7 +480,7 @@ static char *lj_strfmt_wfnum(SBuf *sb, SFormat sf, lua_Number n, char *p) if ((prec | (sf & STRFMT_F_ALT))) { /* Emit fractional part. */ p[1] = '.'; p += 2; - prec -= (q - p); p = q; /* Account for the digits already emitted. */ + prec -= (MSize)(q - p); p = q; /* Account for digits already emitted. */ /* Then emit chunks of 9 digits (this may emit 8 digits too many). */ for (i = ndhi; (int32_t)prec > 0 && i != ndlo; prec -= 9) { i = (i - 1) & 0x3f; diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_strscan.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_strscan.c index 7c5171328e8..f5f35c96028 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_strscan.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_strscan.c @@ -1,6 +1,6 @@ /* ** String scanning. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #include <math.h> diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_strscan.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_strscan.h index b3ee9e528df..6fb0dda08cd 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_strscan.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_strscan.h @@ -1,6 +1,6 @@ /* ** String scanning. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_STRSCAN_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_tab.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_tab.c index 8011212f1b1..47c0cfd34af 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_tab.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_tab.c @@ -1,6 +1,6 @@ /* ** Table handling. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h ** ** Major portions taken verbatim or adapted from the Lua interpreter. ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h @@ -28,7 +28,6 @@ static LJ_AINLINE Node *hashmask(const GCtab *t, uint32_t hash) #define hashlohi(t, lo, hi) hashmask((t), hashrot((lo), (hi))) #define hashnum(t, o) hashlohi((t), (o)->u32.lo, ((o)->u32.hi << 1)) -#define hashptr(t, p) hashlohi((t), u32ptr(p), u32ptr(p) + HASH_BIAS) #if LJ_GC64 #define hashgcref(t, r) \ hashlohi((t), (uint32_t)gcrefu(r), (uint32_t)(gcrefu(r) >> 32)) diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_tab.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_tab.h index f06fcf611ad..71e34945e8a 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_tab.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_tab.h @@ -1,6 +1,6 @@ /* ** Table handling. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_TAB_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_target.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_target.h index abea8d5b216..8dcae957f0e 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_target.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_target.h @@ -1,6 +1,6 @@ /* ** Definitions for target CPU. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_TARGET_H @@ -55,7 +55,7 @@ typedef uint32_t RegSP; /* Bitset for registers. 32 registers suffice for most architectures. ** Note that one set holds bits for both GPRs and FPRs. */ -#if LJ_TARGET_PPC || LJ_TARGET_MIPS +#if LJ_TARGET_PPC || LJ_TARGET_MIPS || LJ_TARGET_ARM64 typedef uint64_t RegSet; #else typedef uint32_t RegSet; @@ -69,7 +69,7 @@ typedef uint32_t RegSet; #define rset_set(rs, r) (rs |= RID2RSET(r)) #define rset_clear(rs, r) (rs &= ~RID2RSET(r)) #define rset_exclude(rs, r) (rs & ~RID2RSET(r)) -#if LJ_TARGET_PPC || LJ_TARGET_MIPS +#if LJ_TARGET_PPC || LJ_TARGET_MIPS || LJ_TARGET_ARM64 #define rset_picktop(rs) ((Reg)(__builtin_clzll(rs)^63)) #define rset_pickbot(rs) ((Reg)__builtin_ctzll(rs)) #else diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_target_arm.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_target_arm.h index 36959dbcc4e..5551b1f1cef 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_target_arm.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_target_arm.h @@ -1,6 +1,6 @@ /* ** Definitions for ARM CPUs. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_TARGET_ARM_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_target_arm64.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_target_arm64.h index 57ab134f98e..520023ae218 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_target_arm64.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_target_arm64.h @@ -1,6 +1,6 @@ /* ** Definitions for ARM64 CPUs. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_TARGET_ARM64_H @@ -55,7 +55,8 @@ enum { /* Make use of all registers, except for x18, fp, lr and sp. */ #define RSET_FIXED \ - (RID2RSET(RID_X18)|RID2RSET(RID_FP)|RID2RSET(RID_LR)|RID2RSET(RID_SP)) + (RID2RSET(RID_X18)|RID2RSET(RID_FP)|RID2RSET(RID_LR)|RID2RSET(RID_SP)|\ + RID2RSET(RID_GL)) #define RSET_GPR (RSET_RANGE(RID_MIN_GPR, RID_MAX_GPR) - RSET_FIXED) #define RSET_FPR RSET_RANGE(RID_MIN_FPR, RID_MAX_FPR) #define RSET_ALL (RSET_GPR|RSET_FPR) @@ -73,25 +74,256 @@ enum { #define REGARG_LASTFPR RID_D7 #define REGARG_NUMFPR 8 +/* -- Spill slots --------------------------------------------------------- */ + +/* Spill slots are 32 bit wide. An even/odd pair is used for FPRs. +** +** SPS_FIXED: Available fixed spill slots in interpreter frame. +** This definition must match with the vm_arm64.dasc file. +** Pre-allocate some slots to avoid sp adjust in every root trace. +** +** SPS_FIRST: First spill slot for general use. Reserve min. two 32 bit slots. +*/ +#define SPS_FIXED 4 +#define SPS_FIRST 2 + +#define SPOFS_TMP 0 + +#define sps_scale(slot) (4 * (int32_t)(slot)) +#define sps_align(slot) (((slot) - SPS_FIXED + 3) & ~3) + +/* -- Exit state ---------------------------------------------------------- */ + +/* This definition must match with the *.dasc file(s). */ +typedef struct { + lua_Number fpr[RID_NUM_FPR]; /* Floating-point registers. */ + intptr_t gpr[RID_NUM_GPR]; /* General-purpose registers. */ + int32_t spill[256]; /* Spill slots. */ +} ExitState; + +/* Highest exit + 1 indicates stack check. */ +#define EXITSTATE_CHECKEXIT 1 + +/* Return the address of a per-trace exit stub. */ +static LJ_AINLINE uint32_t *exitstub_trace_addr_(uint32_t *p, uint32_t exitno) +{ + while (*p == (LJ_LE ? 0xd503201f : 0x1f2003d5)) p++; /* Skip A64I_NOP. */ + return p + 3 + exitno; +} +/* Avoid dependence on lj_jit.h if only including lj_target.h. */ +#define exitstub_trace_addr(T, exitno) \ + exitstub_trace_addr_((MCode *)((char *)(T)->mcode + (T)->szmcode), (exitno)) + /* -- Instructions -------------------------------------------------------- */ +/* ARM64 instructions are always little-endian. Swap for ARM64BE. */ +#if LJ_BE +#define A64I_LE(x) (lj_bswap(x)) +#else +#define A64I_LE(x) (x) +#endif + /* Instruction fields. */ #define A64F_D(r) (r) -#define A64F_N(r) ((r) << 5) -#define A64F_A(r) ((r) << 10) -#define A64F_M(r) ((r) << 16) +#define A64F_N(r) ((r) << 5) +#define A64F_A(r) ((r) << 10) +#define A64F_M(r) ((r) << 16) +#define A64F_IMMS(x) ((x) << 10) +#define A64F_IMMR(x) ((x) << 16) #define A64F_U16(x) ((x) << 5) +#define A64F_U12(x) ((x) << 10) #define A64F_S26(x) (x) -#define A64F_S19(x) ((x) << 5) +#define A64F_S19(x) (((uint32_t)(x) & 0x7ffffu) << 5) +#define A64F_S14(x) ((x) << 5) +#define A64F_S9(x) ((x) << 12) +#define A64F_BIT(x) ((x) << 19) +#define A64F_SH(sh, x) (((sh) << 22) | ((x) << 10)) +#define A64F_EX(ex) (A64I_EX | ((ex) << 13)) +#define A64F_EXSH(ex,x) (A64I_EX | ((ex) << 13) | ((x) << 10)) +#define A64F_FP8(x) ((x) << 13) +#define A64F_CC(cc) ((cc) << 12) +#define A64F_LSL16(x) (((x) / 16) << 21) +#define A64F_BSH(sh) ((sh) << 10) typedef enum A64Ins { + A64I_S = 0x20000000, + A64I_X = 0x80000000, + A64I_EX = 0x00200000, + A64I_ON = 0x00200000, + A64I_K12 = 0x1a000000, + A64I_K13 = 0x18000000, + A64I_LS_U = 0x01000000, + A64I_LS_S = 0x00800000, + A64I_LS_R = 0x01200800, + A64I_LS_SH = 0x00001000, + A64I_LS_UXTWx = 0x00004000, + A64I_LS_SXTWx = 0x0000c000, + A64I_LS_SXTXx = 0x0000e000, + A64I_LS_LSLx = 0x00006000, + + A64I_ADDw = 0x0b000000, + A64I_ADDx = 0x8b000000, + A64I_ADDSw = 0x2b000000, + A64I_ADDSx = 0xab000000, + A64I_NEGw = 0x4b0003e0, + A64I_NEGx = 0xcb0003e0, + A64I_SUBw = 0x4b000000, + A64I_SUBx = 0xcb000000, + A64I_SUBSw = 0x6b000000, + A64I_SUBSx = 0xeb000000, + + A64I_MULw = 0x1b007c00, + A64I_MULx = 0x9b007c00, + A64I_SMULL = 0x9b207c00, + + A64I_ANDw = 0x0a000000, + A64I_ANDx = 0x8a000000, + A64I_ANDSw = 0x6a000000, + A64I_ANDSx = 0xea000000, + A64I_EORw = 0x4a000000, + A64I_EORx = 0xca000000, + A64I_ORRw = 0x2a000000, + A64I_ORRx = 0xaa000000, + A64I_TSTw = 0x6a00001f, + A64I_TSTx = 0xea00001f, + + A64I_CMPw = 0x6b00001f, + A64I_CMPx = 0xeb00001f, + A64I_CMNw = 0x2b00001f, + A64I_CMNx = 0xab00001f, + A64I_CCMPw = 0x7a400000, + A64I_CCMPx = 0xfa400000, + A64I_CSELw = 0x1a800000, + A64I_CSELx = 0x9a800000, + + A64I_ASRw = 0x13007c00, + A64I_ASRx = 0x9340fc00, + A64I_LSLx = 0xd3400000, + A64I_LSRx = 0xd340fc00, + A64I_SHRw = 0x1ac02000, + A64I_SHRx = 0x9ac02000, /* lsl/lsr/asr/ror x0, x0, x0 */ + A64I_REVw = 0x5ac00800, + A64I_REVx = 0xdac00c00, + + A64I_EXTRw = 0x13800000, + A64I_EXTRx = 0x93c00000, + A64I_SBFMw = 0x13000000, + A64I_SBFMx = 0x93400000, + A64I_SXTBw = 0x13001c00, + A64I_SXTHw = 0x13003c00, + A64I_SXTW = 0x93407c00, + A64I_UBFMw = 0x53000000, + A64I_UBFMx = 0xd3400000, + A64I_UXTBw = 0x53001c00, + A64I_UXTHw = 0x53003c00, + + A64I_MOVw = 0x2a0003e0, + A64I_MOVx = 0xaa0003e0, + A64I_MVNw = 0x2a2003e0, + A64I_MVNx = 0xaa2003e0, + A64I_MOVKw = 0x72800000, + A64I_MOVKx = 0xf2800000, A64I_MOVZw = 0x52800000, A64I_MOVZx = 0xd2800000, + A64I_MOVNw = 0x12800000, + A64I_MOVNx = 0x92800000, + + A64I_LDRB = 0x39400000, + A64I_LDRH = 0x79400000, + A64I_LDRw = 0xb9400000, + A64I_LDRx = 0xf9400000, A64I_LDRLw = 0x18000000, A64I_LDRLx = 0x58000000, - A64I_NOP = 0xd503201f, + A64I_STRB = 0x39000000, + A64I_STRH = 0x79000000, + A64I_STRw = 0xb9000000, + A64I_STRx = 0xf9000000, + A64I_STPw = 0x29000000, + A64I_STPx = 0xa9000000, + A64I_LDPw = 0x29400000, + A64I_LDPx = 0xa9400000, + A64I_B = 0x14000000, + A64I_BCC = 0x54000000, + A64I_BL = 0x94000000, A64I_BR = 0xd61f0000, + A64I_BLR = 0xd63f0000, + A64I_TBZ = 0x36000000, + A64I_TBNZ = 0x37000000, + A64I_CBZ = 0x34000000, + A64I_CBNZ = 0x35000000, + + A64I_NOP = 0xd503201f, + + /* FP */ + A64I_FADDd = 0x1e602800, + A64I_FSUBd = 0x1e603800, + A64I_FMADDd = 0x1f400000, + A64I_FMSUBd = 0x1f408000, + A64I_FNMADDd = 0x1f600000, + A64I_FNMSUBd = 0x1f608000, + A64I_FMULd = 0x1e600800, + A64I_FDIVd = 0x1e601800, + A64I_FNEGd = 0x1e614000, + A64I_FABS = 0x1e60c000, + A64I_FSQRTd = 0x1e61c000, + A64I_LDRs = 0xbd400000, + A64I_LDRd = 0xfd400000, + A64I_STRs = 0xbd000000, + A64I_STRd = 0xfd000000, + A64I_LDPs = 0x2d400000, + A64I_LDPd = 0x6d400000, + A64I_STPs = 0x2d000000, + A64I_STPd = 0x6d000000, + A64I_FCMPd = 0x1e602000, + A64I_FCMPZd = 0x1e602008, + A64I_FCSELd = 0x1e600c00, + A64I_FRINTMd = 0x1e654000, + A64I_FRINTPd = 0x1e64c000, + A64I_FRINTZd = 0x1e65c000, + + A64I_FCVT_F32_F64 = 0x1e624000, + A64I_FCVT_F64_F32 = 0x1e22c000, + A64I_FCVT_F32_S32 = 0x1e220000, + A64I_FCVT_F64_S32 = 0x1e620000, + A64I_FCVT_F32_U32 = 0x1e230000, + A64I_FCVT_F64_U32 = 0x1e630000, + A64I_FCVT_F32_S64 = 0x9e220000, + A64I_FCVT_F64_S64 = 0x9e620000, + A64I_FCVT_F32_U64 = 0x9e230000, + A64I_FCVT_F64_U64 = 0x9e630000, + A64I_FCVT_S32_F64 = 0x1e780000, + A64I_FCVT_S32_F32 = 0x1e380000, + A64I_FCVT_U32_F64 = 0x1e790000, + A64I_FCVT_U32_F32 = 0x1e390000, + A64I_FCVT_S64_F64 = 0x9e780000, + A64I_FCVT_S64_F32 = 0x9e380000, + A64I_FCVT_U64_F64 = 0x9e790000, + A64I_FCVT_U64_F32 = 0x9e390000, + + A64I_FMOV_S = 0x1e204000, + A64I_FMOV_D = 0x1e604000, + A64I_FMOV_R_S = 0x1e260000, + A64I_FMOV_S_R = 0x1e270000, + A64I_FMOV_R_D = 0x9e660000, + A64I_FMOV_D_R = 0x9e670000, + A64I_FMOV_DI = 0x1e601000, } A64Ins; +typedef enum A64Shift { + A64SH_LSL, A64SH_LSR, A64SH_ASR, A64SH_ROR +} A64Shift; + +typedef enum A64Extend { + A64EX_UXTB, A64EX_UXTH, A64EX_UXTW, A64EX_UXTX, + A64EX_SXTB, A64EX_SXTH, A64EX_SXTW, A64EX_SXTX, +} A64Extend; + +/* ARM condition codes. */ +typedef enum A64CC { + CC_EQ, CC_NE, CC_CS, CC_CC, CC_MI, CC_PL, CC_VS, CC_VC, + CC_HI, CC_LS, CC_GE, CC_LT, CC_GT, CC_LE, CC_AL, + CC_HS = CC_CS, CC_LO = CC_CC +} A64CC; + #endif diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_target_mips.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_target_mips.h index bafa817a38a..740687b355d 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_target_mips.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_target_mips.h @@ -1,6 +1,6 @@ /* ** Definitions for MIPS CPUs. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_TARGET_MIPS_H @@ -32,6 +32,7 @@ enum { RID_MAX, RID_ZERO = RID_R0, RID_TMP = RID_RA, + RID_GP = RID_R28, /* Calling conventions. */ RID_RET = RID_R2, @@ -74,46 +75,64 @@ enum { /* -- Register sets ------------------------------------------------------- */ -/* Make use of all registers, except ZERO, TMP, SP, SYS1, SYS2 and JGL. */ +/* Make use of all registers, except ZERO, TMP, SP, SYS1, SYS2, JGL and GP. */ #define RSET_FIXED \ (RID2RSET(RID_ZERO)|RID2RSET(RID_TMP)|RID2RSET(RID_SP)|\ - RID2RSET(RID_SYS1)|RID2RSET(RID_SYS2)|RID2RSET(RID_JGL)) + RID2RSET(RID_SYS1)|RID2RSET(RID_SYS2)|RID2RSET(RID_JGL)|RID2RSET(RID_GP)) #define RSET_GPR (RSET_RANGE(RID_MIN_GPR, RID_MAX_GPR) - RSET_FIXED) #if LJ_SOFTFP -#define RSET_FPR 0 +#define RSET_FPR 0 #else +#if LJ_32 #define RSET_FPR \ (RID2RSET(RID_F0)|RID2RSET(RID_F2)|RID2RSET(RID_F4)|RID2RSET(RID_F6)|\ RID2RSET(RID_F8)|RID2RSET(RID_F10)|RID2RSET(RID_F12)|RID2RSET(RID_F14)|\ RID2RSET(RID_F16)|RID2RSET(RID_F18)|RID2RSET(RID_F20)|RID2RSET(RID_F22)|\ RID2RSET(RID_F24)|RID2RSET(RID_F26)|RID2RSET(RID_F28)|RID2RSET(RID_F30)) +#else +#define RSET_FPR RSET_RANGE(RID_MIN_FPR, RID_MAX_FPR) +#endif #endif -#define RSET_ALL (RSET_GPR|RSET_FPR) -#define RSET_INIT RSET_ALL +#define RSET_ALL (RSET_GPR|RSET_FPR) +#define RSET_INIT RSET_ALL #define RSET_SCRATCH_GPR \ (RSET_RANGE(RID_R1, RID_R15+1)|\ - RID2RSET(RID_R24)|RID2RSET(RID_R25)|RID2RSET(RID_R28)) + RID2RSET(RID_R24)|RID2RSET(RID_R25)) #if LJ_SOFTFP #define RSET_SCRATCH_FPR 0 #else +#if LJ_32 #define RSET_SCRATCH_FPR \ (RID2RSET(RID_F0)|RID2RSET(RID_F2)|RID2RSET(RID_F4)|RID2RSET(RID_F6)|\ RID2RSET(RID_F8)|RID2RSET(RID_F10)|RID2RSET(RID_F12)|RID2RSET(RID_F14)|\ RID2RSET(RID_F16)|RID2RSET(RID_F18)) +#else +#define RSET_SCRATCH_FPR RSET_RANGE(RID_F0, RID_F24) +#endif #endif #define RSET_SCRATCH (RSET_SCRATCH_GPR|RSET_SCRATCH_FPR) #define REGARG_FIRSTGPR RID_R4 +#if LJ_32 #define REGARG_LASTGPR RID_R7 #define REGARG_NUMGPR 4 +#else +#define REGARG_LASTGPR RID_R11 +#define REGARG_NUMGPR 8 +#endif #if LJ_ABI_SOFTFP #define REGARG_FIRSTFPR 0 #define REGARG_LASTFPR 0 #define REGARG_NUMFPR 0 #else #define REGARG_FIRSTFPR RID_F12 +#if LJ_32 #define REGARG_LASTFPR RID_F14 #define REGARG_NUMFPR 2 +#else +#define REGARG_LASTFPR RID_F19 +#define REGARG_NUMFPR 8 +#endif #endif /* -- Spill slots --------------------------------------------------------- */ @@ -125,7 +144,11 @@ enum { ** ** SPS_FIRST: First spill slot for general use. */ +#if LJ_32 #define SPS_FIXED 5 +#else +#define SPS_FIXED 4 +#endif #define SPS_FIRST 4 #define SPOFS_TMP 0 @@ -140,7 +163,7 @@ typedef struct { #if !LJ_SOFTFP lua_Number fpr[RID_NUM_FPR]; /* Floating-point registers. */ #endif - int32_t gpr[RID_NUM_GPR]; /* General-purpose registers. */ + intptr_t gpr[RID_NUM_GPR]; /* General-purpose registers. */ int32_t spill[256]; /* Spill slots. */ } ExitState; @@ -169,32 +192,41 @@ static LJ_AINLINE uint32_t *exitstub_trace_addr_(uint32_t *p) #define MIPSF_F(r) ((r) << 6) #define MIPSF_A(n) ((n) << 6) #define MIPSF_M(n) ((n) << 11) +#define MIPSF_L(n) ((n) << 6) typedef enum MIPSIns { + MIPSI_D = 0x38, + MIPSI_DV = 0x10, + MIPSI_D32 = 0x3c, /* Integer instructions. */ - MIPSI_MOVE = 0x00000021, + MIPSI_MOVE = 0x00000025, MIPSI_NOP = 0x00000000, MIPSI_LI = 0x24000000, MIPSI_LU = 0x34000000, MIPSI_LUI = 0x3c000000, - MIPSI_ADDIU = 0x24000000, + MIPSI_AND = 0x00000024, MIPSI_ANDI = 0x30000000, + MIPSI_OR = 0x00000025, MIPSI_ORI = 0x34000000, + MIPSI_XOR = 0x00000026, MIPSI_XORI = 0x38000000, + MIPSI_NOR = 0x00000027, + + MIPSI_SLT = 0x0000002a, + MIPSI_SLTU = 0x0000002b, MIPSI_SLTI = 0x28000000, MIPSI_SLTIU = 0x2c000000, MIPSI_ADDU = 0x00000021, + MIPSI_ADDIU = 0x24000000, + MIPSI_SUB = 0x00000022, MIPSI_SUBU = 0x00000023, MIPSI_MUL = 0x70000002, - MIPSI_AND = 0x00000024, - MIPSI_OR = 0x00000025, - MIPSI_XOR = 0x00000026, - MIPSI_NOR = 0x00000027, - MIPSI_SLT = 0x0000002a, - MIPSI_SLTU = 0x0000002b, + MIPSI_DIV = 0x0000001a, + MIPSI_DIVU = 0x0000001b, + MIPSI_MOVZ = 0x0000000a, MIPSI_MOVN = 0x0000000b, MIPSI_MFHI = 0x00000010, @@ -204,19 +236,24 @@ typedef enum MIPSIns { MIPSI_SLL = 0x00000000, MIPSI_SRL = 0x00000002, MIPSI_SRA = 0x00000003, - MIPSI_ROTR = 0x00200002, /* MIPS32R2 */ + MIPSI_ROTR = 0x00200002, /* MIPSXXR2 */ + MIPSI_DROTR = 0x0020003a, + MIPSI_DROTR32 = 0x0020003e, MIPSI_SLLV = 0x00000004, MIPSI_SRLV = 0x00000006, MIPSI_SRAV = 0x00000007, - MIPSI_ROTRV = 0x00000046, /* MIPS32R2 */ + MIPSI_ROTRV = 0x00000046, /* MIPSXXR2 */ + MIPSI_DROTRV = 0x00000056, - MIPSI_SEB = 0x7c000420, /* MIPS32R2 */ - MIPSI_SEH = 0x7c000620, /* MIPS32R2 */ - MIPSI_WSBH = 0x7c0000a0, /* MIPS32R2 */ + MIPSI_SEB = 0x7c000420, /* MIPSXXR2 */ + MIPSI_SEH = 0x7c000620, /* MIPSXXR2 */ + MIPSI_WSBH = 0x7c0000a0, /* MIPSXXR2 */ + MIPSI_DSBH = 0x7c0000a4, MIPSI_B = 0x10000000, MIPSI_J = 0x08000000, MIPSI_JAL = 0x0c000000, + MIPSI_JALX = 0x74000000, MIPSI_JR = 0x00000008, MIPSI_JALR = 0x0000f809, @@ -229,7 +266,9 @@ typedef enum MIPSIns { /* Load/store instructions. */ MIPSI_LW = 0x8c000000, + MIPSI_LD = 0xdc000000, MIPSI_SW = 0xac000000, + MIPSI_SD = 0xfc000000, MIPSI_LB = 0x80000000, MIPSI_SB = 0xa0000000, MIPSI_LH = 0x84000000, @@ -241,6 +280,50 @@ typedef enum MIPSIns { MIPSI_LDC1 = 0xd4000000, MIPSI_SDC1 = 0xf4000000, + /* MIPS64 instructions. */ + MIPSI_DADD = 0x0000002c, + MIPSI_DADDI = 0x60000000, + MIPSI_DADDU = 0x0000002d, + MIPSI_DADDIU = 0x64000000, + MIPSI_DSUB = 0x0000002e, + MIPSI_DSUBU = 0x0000002f, + MIPSI_DDIV = 0x0000001e, + MIPSI_DDIVU = 0x0000001f, + MIPSI_DMULT = 0x0000001c, + MIPSI_DMULTU = 0x0000001d, + + MIPSI_DSLL = 0x00000038, + MIPSI_DSRL = 0x0000003a, + MIPSI_DSLLV = 0x00000014, + MIPSI_DSRLV = 0x00000016, + MIPSI_DSRA = 0x0000003b, + MIPSI_DSRAV = 0x00000017, + MIPSI_DSRA32 = 0x0000003f, + MIPSI_DSLL32 = 0x0000003c, + MIPSI_DSRL32 = 0x0000003e, + MIPSI_DSHD = 0x7c000164, + + MIPSI_AADDU = LJ_32 ? MIPSI_ADDU : MIPSI_DADDU, + MIPSI_AADDIU = LJ_32 ? MIPSI_ADDIU : MIPSI_DADDIU, + MIPSI_ASUBU = LJ_32 ? MIPSI_SUBU : MIPSI_DSUBU, + MIPSI_AL = LJ_32 ? MIPSI_LW : MIPSI_LD, + MIPSI_AS = LJ_32 ? MIPSI_SW : MIPSI_SD, + + /* Extract/insert instructions. */ + MIPSI_DEXTM = 0x7c000001, + MIPSI_DEXTU = 0x7c000002, + MIPSI_DEXT = 0x7c000003, + MIPSI_DINSM = 0x7c000005, + MIPSI_DINSU = 0x7c000006, + MIPSI_DINS = 0x7c000007, + + MIPSI_RINT_D = 0x4620001a, + MIPSI_RINT_S = 0x4600001a, + MIPSI_RINT = 0x4400001a, + MIPSI_FLOOR_D = 0x4620000b, + MIPSI_CEIL_D = 0x4620000a, + MIPSI_ROUND_D = 0x46200008, + /* FP instructions. */ MIPSI_MOV_S = 0x46000006, MIPSI_MOV_D = 0x46200006, @@ -265,24 +348,30 @@ typedef enum MIPSIns { MIPSI_CVT_W_D = 0x46200024, MIPSI_CVT_S_W = 0x46800020, MIPSI_CVT_D_W = 0x46800021, + MIPSI_CVT_S_L = 0x46a00020, + MIPSI_CVT_D_L = 0x46a00021, MIPSI_TRUNC_W_S = 0x4600000d, MIPSI_TRUNC_W_D = 0x4620000d, + MIPSI_TRUNC_L_S = 0x46000009, + MIPSI_TRUNC_L_D = 0x46200009, MIPSI_FLOOR_W_S = 0x4600000f, MIPSI_FLOOR_W_D = 0x4620000f, MIPSI_MFC1 = 0x44000000, MIPSI_MTC1 = 0x44800000, + MIPSI_DMTC1 = 0x44a00000, + MIPSI_DMFC1 = 0x44200000, MIPSI_BC1F = 0x45000000, MIPSI_BC1T = 0x45010000, MIPSI_C_EQ_D = 0x46200032, + MIPSI_C_OLT_S = 0x46000034, MIPSI_C_OLT_D = 0x46200034, MIPSI_C_ULT_D = 0x46200035, MIPSI_C_OLE_D = 0x46200036, MIPSI_C_ULE_D = 0x46200037, - } MIPSIns; #endif diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_target_ppc.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_target_ppc.h index bbf22390c46..c5c991a377a 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_target_ppc.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_target_ppc.h @@ -1,6 +1,6 @@ /* ** Definitions for PPC CPUs. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_TARGET_PPC_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_target_x86.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_target_x86.h index 289f83e1c8b..356f792459b 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_target_x86.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_target_x86.h @@ -1,6 +1,6 @@ /* ** Definitions for x86 and x64 CPUs. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_TARGET_X86_H @@ -22,7 +22,7 @@ _(XMM0) _(XMM1) _(XMM2) _(XMM3) _(XMM4) _(XMM5) _(XMM6) _(XMM7) #endif #define VRIDDEF(_) \ - _(MRM) + _(MRM) _(RIP) #define RIDENUM(name) RID_##name, @@ -31,6 +31,7 @@ enum { FPRDEF(RIDENUM) /* Floating-point registers (FPRs). */ RID_MAX, RID_MRM = RID_MAX, /* Pseudo-id for ModRM operand. */ + RID_RIP = RID_MAX+5, /* Pseudo-id for RIP (x64 only), rm bits = 5. */ /* Calling conventions. */ RID_SP = RID_ESP, @@ -63,8 +64,10 @@ enum { /* -- Register sets ------------------------------------------------------- */ -/* Make use of all registers, except the stack pointer. */ -#define RSET_GPR (RSET_RANGE(RID_MIN_GPR, RID_MAX_GPR)-RID2RSET(RID_ESP)) +/* Make use of all registers, except the stack pointer (and maybe DISPATCH). */ +#define RSET_GPR (RSET_RANGE(RID_MIN_GPR, RID_MAX_GPR) \ + - RID2RSET(RID_ESP) \ + - LJ_GC64*RID2RSET(RID_DISPATCH)) #define RSET_FPR (RSET_RANGE(RID_MIN_FPR, RID_MAX_FPR)) #define RSET_ALL (RSET_GPR|RSET_FPR) #define RSET_INIT RSET_ALL @@ -189,12 +192,18 @@ typedef struct { #define XO_f20f(o) ((uint32_t)(0x0ff2fc + (0x##o<<24))) #define XO_f30f(o) ((uint32_t)(0x0ff3fc + (0x##o<<24))) +#define XV_660f38(o) ((uint32_t)(0x79e2c4 + (0x##o<<24))) +#define XV_f20f38(o) ((uint32_t)(0x7be2c4 + (0x##o<<24))) +#define XV_f20f3a(o) ((uint32_t)(0x7be3c4 + (0x##o<<24))) +#define XV_f30f38(o) ((uint32_t)(0x7ae2c4 + (0x##o<<24))) + /* This list of x86 opcodes is not intended to be complete. Opcodes are only ** included when needed. Take a look at DynASM or jit.dis_x86 to see the ** whole mess. */ typedef enum { /* Fixed length opcodes. XI_* prefix. */ + XI_O16 = 0x66, XI_NOP = 0x90, XI_XCHGa = 0x90, XI_CALL = 0xe8, @@ -212,6 +221,7 @@ typedef enum { XI_PUSHi8 = 0x6a, XI_TESTb = 0x84, XI_TEST = 0x85, + XI_INT3 = 0xcc, XI_MOVmi = 0xc7, XI_GROUP5 = 0xff, @@ -231,7 +241,14 @@ typedef enum { XI_FSCALE = 0xfdd9, XI_FYL2X = 0xf1d9, + /* VEX-encoded instructions. XV_* prefix. */ + XV_RORX = XV_f20f3a(f0), + XV_SARX = XV_f30f38(f7), + XV_SHLX = XV_660f38(f7), + XV_SHRX = XV_f20f38(f7), + /* Variable-length opcodes. XO_* prefix. */ + XO_OR = XO_(0b), XO_MOV = XO_(8b), XO_MOVto = XO_(89), XO_MOVtow = XO_66(89), diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_trace.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_trace.c index 7970aba6ae0..d85b47f8013 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_trace.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_trace.c @@ -1,6 +1,6 @@ /* ** Trace management. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_trace_c @@ -117,15 +117,26 @@ static void perftools_addtrace(GCtrace *T) } #endif -/* Allocate space for copy of trace. */ -static GCtrace *trace_save_alloc(jit_State *J) +/* Allocate space for copy of T. */ +GCtrace * LJ_FASTCALL lj_trace_alloc(lua_State *L, GCtrace *T) { size_t sztr = ((sizeof(GCtrace)+7)&~7); - size_t szins = (J->cur.nins-J->cur.nk)*sizeof(IRIns); + size_t szins = (T->nins-T->nk)*sizeof(IRIns); size_t sz = sztr + szins + - J->cur.nsnap*sizeof(SnapShot) + - J->cur.nsnapmap*sizeof(SnapEntry); - return lj_mem_newt(J->L, (MSize)sz, GCtrace); + T->nsnap*sizeof(SnapShot) + + T->nsnapmap*sizeof(SnapEntry); + GCtrace *T2 = lj_mem_newt(L, (MSize)sz, GCtrace); + char *p = (char *)T2 + sztr; + T2->gct = ~LJ_TTRACE; + T2->marked = 0; + T2->traceno = 0; + T2->ir = (IRIns *)p - T->nk; + T2->nins = T->nins; + T2->nk = T->nk; + T2->nsnap = T->nsnap; + T2->nsnapmap = T->nsnapmap; + memcpy(p, T->ir + T->nk, szins); + return T2; } /* Save current trace by copying and compacting it. */ @@ -139,12 +150,12 @@ static void trace_save(jit_State *J, GCtrace *T) setgcrefp(J2G(J)->gc.root, T); newwhite(J2G(J), T); T->gct = ~LJ_TTRACE; - T->ir = (IRIns *)p - J->cur.nk; - memcpy(p, J->cur.ir+J->cur.nk, szins); + T->ir = (IRIns *)p - J->cur.nk; /* The IR has already been copied above. */ p += szins; TRACE_APPENDVEC(snap, nsnap, SnapShot) TRACE_APPENDVEC(snapmap, nsnapmap, SnapEntry) J->cur.traceno = 0; + J->curfinal = NULL; setgcrefp(J->trace[T->traceno], T); lj_gc_barriertrace(J2G(J), T->traceno); lj_gdbjit_addtrace(J, T); @@ -284,7 +295,6 @@ int lj_trace_flushall(lua_State *L) memset(J->penalty, 0, sizeof(J->penalty)); /* Free the whole machine code and invalidate all exit stub groups. */ lj_mcode_free(J); - lj_ir_k64_freeall(J); memset(J->exitstubgroup, 0, sizeof(J->exitstubgroup)); lj_vmevent_send(L, TRACE, setstrV(L, L->top++, lj_str_newlit(L, "flush")); @@ -297,13 +307,42 @@ void lj_trace_initstate(global_State *g) { jit_State *J = G2J(g); TValue *tv; - /* Initialize SIMD constants. */ + + /* Initialize aligned SIMD constants. */ tv = LJ_KSIMD(J, LJ_KSIMD_ABS); tv[0].u64 = U64x(7fffffff,ffffffff); tv[1].u64 = U64x(7fffffff,ffffffff); tv = LJ_KSIMD(J, LJ_KSIMD_NEG); tv[0].u64 = U64x(80000000,00000000); tv[1].u64 = U64x(80000000,00000000); + + /* Initialize 32/64 bit constants. */ +#if LJ_TARGET_X86ORX64 + J->k64[LJ_K64_TOBIT].u64 = U64x(43380000,00000000); +#if LJ_32 + J->k64[LJ_K64_M2P64_31].u64 = U64x(c1e00000,00000000); +#endif + J->k64[LJ_K64_2P64].u64 = U64x(43f00000,00000000); + J->k32[LJ_K32_M2P64_31] = LJ_64 ? 0xdf800000 : 0xcf000000; +#endif +#if LJ_TARGET_X86ORX64 || LJ_TARGET_MIPS64 + J->k64[LJ_K64_M2P64].u64 = U64x(c3f00000,00000000); +#endif +#if LJ_TARGET_PPC + J->k32[LJ_K32_2P52_2P31] = 0x59800004; + J->k32[LJ_K32_2P52] = 0x59800000; +#endif +#if LJ_TARGET_PPC || LJ_TARGET_MIPS + J->k32[LJ_K32_2P31] = 0x4f000000; +#endif +#if LJ_TARGET_MIPS + J->k64[LJ_K64_2P31].u64 = U64x(41e00000,00000000); +#if LJ_64 + J->k64[LJ_K64_2P63].u64 = U64x(43e00000,00000000); + J->k32[LJ_K32_2P63] = 0x5f000000; + J->k32[LJ_K32_M2P64] = 0xdf800000; +#endif +#endif } /* Free everything associated with the JIT compiler state. */ @@ -318,7 +357,6 @@ void lj_trace_freestate(global_State *g) } #endif lj_mcode_free(J); - lj_ir_k64_freeall(J); lj_mem_freevec(g, J->snapmapbuf, J->sizesnapmap, SnapEntry); lj_mem_freevec(g, J->snapbuf, J->sizesnap, SnapShot); lj_mem_freevec(g, J->irbuf + J->irbotlim, J->irtoplim - J->irbotlim, IRIns); @@ -403,7 +441,7 @@ static void trace_start(jit_State *J) J->postproc = LJ_POST_NONE; lj_resetsplit(J); J->retryrec = 0; - J->ktracep = NULL; + J->ktrace = 0; setgcref(J->cur.startpt, obj2gco(J->pt)); L = J->L; @@ -415,6 +453,12 @@ static void trace_start(jit_State *J) if (J->parent) { setintV(L->top++, J->parent); setintV(L->top++, J->exitno); + } else { + BCOp op = bc_op(*J->pc); + if (op == BC_CALLM || op == BC_CALL || op == BC_ITERC) { + setintV(L->top++, J->exitno); /* Parent of stitched trace. */ + setintV(L->top++, -1); + } } ); lj_record_setup(J); @@ -427,7 +471,7 @@ static void trace_stop(jit_State *J) BCOp op = bc_op(J->cur.startins); GCproto *pt = &gcref(J->cur.startpt)->pt; TraceNo traceno = J->cur.traceno; - GCtrace *T = trace_save_alloc(J); /* Do this first. May throw OOM. */ + GCtrace *T = J->curfinal; lua_State *L; switch (op) { @@ -479,9 +523,6 @@ static void trace_stop(jit_State *J) lj_mcode_commit(J, J->cur.mcode); J->postproc = LJ_POST_NONE; trace_save(J, T); - if (J->ktracep) { /* Patch K64Array slot with the final GCtrace pointer. */ - setgcV(J->L, J->ktracep, obj2gco(T), LJ_TTRACE); - } L = J->L; lj_vmevent_send(L, TRACE, @@ -515,6 +556,10 @@ static int trace_abort(jit_State *J) J->postproc = LJ_POST_NONE; lj_mcode_abort(J); + if (J->curfinal) { + lj_trace_free(J2G(J), J->curfinal); + J->curfinal = NULL; + } if (tvisnumber(L->top-1)) e = (TraceError)numberVint(L->top-1); if (e == LJ_TRERR_MCODELM) { @@ -849,7 +894,7 @@ int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr) ERRNO_RESTORE switch (bc_op(*pc)) { case BC_CALLM: case BC_CALLMT: - return (int)((BCReg)(L->top - L->base) - bc_a(*pc) - bc_c(*pc) + LJ_FR2); + return (int)((BCReg)(L->top - L->base) - bc_a(*pc) - bc_c(*pc) - LJ_FR2); case BC_RETM: return (int)((BCReg)(L->top - L->base) + 1 - bc_a(*pc) - bc_d(*pc)); case BC_TSETM: diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_trace.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_trace.h index 6faa1aa3cde..22cae741f3f 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_trace.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_trace.h @@ -1,6 +1,6 @@ /* ** Trace management. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_TRACE_H @@ -23,6 +23,7 @@ LJ_FUNC_NORET void lj_trace_err(jit_State *J, TraceError e); LJ_FUNC_NORET void lj_trace_err_info(jit_State *J, TraceError e); /* Trace management. */ +LJ_FUNC GCtrace * LJ_FASTCALL lj_trace_alloc(lua_State *L, GCtrace *T); LJ_FUNC void LJ_FASTCALL lj_trace_free(global_State *g, GCtrace *T); LJ_FUNC void lj_trace_reenableproto(GCproto *pt); LJ_FUNC void lj_trace_flushproto(global_State *g, GCproto *pt); diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_traceerr.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_traceerr.h index 9c01ffb7ac5..1363c4f3272 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_traceerr.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_traceerr.h @@ -1,6 +1,6 @@ /* ** Trace compiler error messages. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ /* This file may be included multiple times with different TREDEF macros. */ diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_udata.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_udata.c index 71697a42fb9..bd0321b834b 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_udata.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_udata.c @@ -1,6 +1,6 @@ /* ** Userdata handling. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_udata_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_udata.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_udata.h index 81c15816da5..f271a42d327 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_udata.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_udata.h @@ -1,6 +1,6 @@ /* ** Userdata handling. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_UDATA_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_vm.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_vm.h index be35295d261..1cc7eed782f 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_vm.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_vm.h @@ -1,6 +1,6 @@ /* ** Assembler VM interface definitions. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_VM_H @@ -17,6 +17,10 @@ LJ_ASMF int lj_vm_cpcall(lua_State *L, lua_CFunction func, void *ud, LJ_ASMF int lj_vm_resume(lua_State *L, TValue *base, int nres1, ptrdiff_t ef); LJ_ASMF_NORET void LJ_FASTCALL lj_vm_unwind_c(void *cframe, int errcode); LJ_ASMF_NORET void LJ_FASTCALL lj_vm_unwind_ff(void *cframe); +#if LJ_ABI_WIN && LJ_TARGET_X86 +LJ_ASMF_NORET void LJ_FASTCALL lj_vm_rtlunwind(void *cframe, void *excptrec, + void *unwinder, int errcode); +#endif LJ_ASMF void lj_vm_unwind_c_eh(void); LJ_ASMF void lj_vm_unwind_ff_eh(void); #if LJ_TARGET_X86ORX64 diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_vmevent.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_vmevent.c index 3acdd2534e6..86640804bed 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_vmevent.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_vmevent.c @@ -1,6 +1,6 @@ /* ** VM event handling. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #include <stdio.h> diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_vmevent.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_vmevent.h index b9495b4f9ec..050fb4dd24a 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_vmevent.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_vmevent.h @@ -1,6 +1,6 @@ /* ** VM event handling. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_VMEVENT_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_vmmath.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_vmmath.c index e6622650503..b231d3e811e 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_vmmath.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_vmmath.c @@ -1,6 +1,6 @@ /* ** Math helper functions for assembler VM. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_vmmath_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/ljamalg.c b/Build/source/libs/luajit/LuaJIT-src/src/ljamalg.c index 4c44de27ad8..f1f28623fa9 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/ljamalg.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/ljamalg.c @@ -1,6 +1,6 @@ /* ** LuaJIT core and libraries amalgamation. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ /* diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lua.h b/Build/source/libs/luajit/LuaJIT-src/src/lua.h index fb4e69f4076..b918366cbdf 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lua.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lua.h @@ -39,7 +39,8 @@ #define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i)) -/* thread status; 0 is OK */ +/* thread status */ +#define LUA_OK 0 #define LUA_YIELD 1 #define LUA_ERRRUN 2 #define LUA_ERRSYNTAX 3 @@ -102,11 +103,9 @@ typedef LUA_NUMBER lua_Number; /* type for integer functions */ typedef LUA_INTEGER lua_Integer; - /* communication with LuaJiTTeX */ LUA_API int luajittex_choose_hash_function; - /* ** state manipulation */ @@ -350,16 +349,21 @@ LUA_API void *lua_upvalueid (lua_State *L, int idx, int n); LUA_API void lua_upvaluejoin (lua_State *L, int idx1, int n1, int idx2, int n2); LUA_API int lua_loadx (lua_State *L, lua_Reader reader, void *dt, const char *chunkname, const char *mode); +LUA_API const lua_Number *lua_version (lua_State *L); +LUA_API void lua_copy (lua_State *L, int fromidx, int toidx); +LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *isnum); +LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *isnum); #define LUA_OPEQ 0 #define LUA_OPLT 1 #define LUA_OPLE 2 -#define LUA_OK 0 - + /* see http://comments.gmane.org/gmane.comp.programming.swig/18673 */ # define lua_rawlen lua_objlen +/* From Lua 5.3. */ +LUA_API int lua_isyieldable (lua_State *L); struct lua_Debug { diff --git a/Build/source/libs/luajit/LuaJIT-src/src/luaconf.h b/Build/source/libs/luajit/LuaJIT-src/src/luaconf.h index 4c24bb1a0e2..c2d29d94922 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/luaconf.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/luaconf.h @@ -1,6 +1,6 @@ /* ** Configuration header. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef luaconf_h @@ -37,7 +37,7 @@ #endif #define LUA_LROOT "/usr/local" #define LUA_LUADIR "/lua/5.1/" -#define LUA_LJDIR "/luajit-2.1.0-beta2/" +#define LUA_LJDIR "/luajit-2.1.0-beta3/" #ifdef LUA_ROOT #define LUA_JROOT LUA_ROOT @@ -79,7 +79,7 @@ #define LUA_IGMARK "-" #define LUA_PATH_CONFIG \ LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n" \ - LUA_EXECDIR "\n" LUA_IGMARK + LUA_EXECDIR "\n" LUA_IGMARK "\n" /* Quoting in error messages. */ #define LUA_QL(x) "'" x "'" @@ -92,10 +92,6 @@ #define LUAI_GCMUL 200 /* Run GC at 200% of allocation speed. */ #define LUA_MAXCAPTURES 32 /* Max. pattern captures. */ -/* Compatibility with older library function names. */ -#define LUA_COMPAT_MOD /* OLD: math.mod, NEW: math.fmod */ -#define LUA_COMPAT_GFIND /* OLD: string.gfind, NEW: string.gmatch */ - /* Configuration for the frontend (the luajit executable). */ #if defined(luajit_c) #define LUA_PROGNAME "luajit" /* Fallback frontend name. */ diff --git a/Build/source/libs/luajit/LuaJIT-src/src/luajit.c b/Build/source/libs/luajit/LuaJIT-src/src/luajit.c index 00e12bd32e3..1ca243011fb 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/luajit.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/luajit.c @@ -1,6 +1,6 @@ /* ** LuaJIT frontend. Runs commands, scripts, read-eval-print (REPL) etc. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h ** ** Major portions taken verbatim or adapted from the Lua interpreter. ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h @@ -124,7 +124,7 @@ static int docall(lua_State *L, int narg, int clear) #endif lua_remove(L, base); /* remove traceback function */ /* force a complete garbage collection in case of errors */ - if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0); + if (status != LUA_OK) lua_gc(L, LUA_GCCOLLECT, 0); return status; } @@ -152,22 +152,15 @@ static void print_jit_status(lua_State *L) putc('\n', stdout); } -static int getargs(lua_State *L, char **argv, int n) +static void createargtable(lua_State *L, char **argv, int argc, int argf) { - int narg; int i; - int argc = 0; - while (argv[argc]) argc++; /* count total number of arguments */ - narg = argc - (n + 1); /* number of arguments to the script */ - luaL_checkstack(L, narg + 3, "too many arguments to script"); - for (i = n+1; i < argc; i++) - lua_pushstring(L, argv[i]); - lua_createtable(L, narg, n + 1); + lua_createtable(L, argc - argf, argf); for (i = 0; i < argc; i++) { lua_pushstring(L, argv[i]); - lua_rawseti(L, -2, i - n); + lua_rawseti(L, -2, i - argf); } - return narg; + lua_setglobal(L, "arg"); } static int dofile(lua_State *L, const char *name) @@ -256,9 +249,9 @@ static void dotty(lua_State *L) const char *oldprogname = progname; progname = NULL; while ((status = loadline(L)) != -1) { - if (status == 0) status = docall(L, 0, 0); + if (status == LUA_OK) status = docall(L, 0, 0); report(L, status); - if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */ + if (status == LUA_OK && lua_gettop(L) > 0) { /* any result to print? */ lua_getglobal(L, "print"); lua_insert(L, 1); if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0) @@ -273,21 +266,30 @@ static void dotty(lua_State *L) progname = oldprogname; } -static int handle_script(lua_State *L, char **argv, int n) +static int handle_script(lua_State *L, char **argx) { int status; - const char *fname; - int narg = getargs(L, argv, n); /* collect arguments */ - lua_setglobal(L, "arg"); - fname = argv[n]; - if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0) + const char *fname = argx[0]; + if (strcmp(fname, "-") == 0 && strcmp(argx[-1], "--") != 0) fname = NULL; /* stdin */ status = luaL_loadfile(L, fname); - lua_insert(L, -(narg+1)); - if (status == 0) + if (status == LUA_OK) { + /* Fetch args from arg table. LUA_INIT or -e might have changed them. */ + int narg = 0; + lua_getglobal(L, "arg"); + if (lua_istable(L, -1)) { + do { + narg++; + lua_rawgeti(L, -narg, narg); + } while (!lua_isnil(L, -1)); + lua_pop(L, 1); + lua_remove(L, -narg); + narg--; + } else { + lua_pop(L, 1); + } status = docall(L, narg, 0); - else - lua_pop(L, narg); + } return report(L, status); } @@ -384,7 +386,8 @@ static int dobytecode(lua_State *L, char **argv) } for (argv++; *argv != NULL; narg++, argv++) lua_pushstring(L, *argv); - return report(L, lua_pcall(L, narg, 0, 0)); + report(L, lua_pcall(L, narg, 0, 0)); + return -1; } /* check that argument has no extra characters at the end */ @@ -405,7 +408,7 @@ static int collectargs(char **argv, int *flags) switch (argv[i][1]) { /* Check option. */ case '-': notail(argv[i]); - return (argv[i+1] != NULL ? i+1 : 0); + return i+1; case '\0': return i; case 'i': @@ -430,23 +433,23 @@ static int collectargs(char **argv, int *flags) case 'b': /* LuaJIT extension */ if (*flags) return -1; *flags |= FLAGS_EXEC; - return 0; + return i+1; case 'E': *flags |= FLAGS_NOENV; break; default: return -1; /* invalid option */ } } - return 0; + return i; } -static int runargs(lua_State *L, char **argv, int n) +static int runargs(lua_State *L, char **argv, int argn) { int i; - for (i = 1; i < n; i++) { + for (i = 1; i < argn; i++) { if (argv[i] == NULL) continue; lua_assert(argv[i][0] == '-'); - switch (argv[i][1]) { /* option */ + switch (argv[i][1]) { case 'e': { const char *chunk = argv[i] + 2; if (*chunk == '\0') chunk = argv[++i]; @@ -460,10 +463,10 @@ static int runargs(lua_State *L, char **argv, int n) if (*filename == '\0') filename = argv[++i]; lua_assert(filename != NULL); if (dolibrary(L, filename)) - return 1; /* stop if file fails */ + return 1; break; } - case 'j': { /* LuaJIT extension */ + case 'j': { /* LuaJIT extension. */ const char *cmd = argv[i] + 2; if (*cmd == '\0') cmd = argv[++i]; lua_assert(cmd != NULL); @@ -471,16 +474,16 @@ static int runargs(lua_State *L, char **argv, int n) return 1; break; } - case 'O': /* LuaJIT extension */ + case 'O': /* LuaJIT extension. */ if (dojitopt(L, argv[i] + 2)) return 1; break; - case 'b': /* LuaJIT extension */ + case 'b': /* LuaJIT extension. */ return dobytecode(L, argv+i); default: break; } } - return 0; + return LUA_OK; } static int handle_luainit(lua_State *L) @@ -491,7 +494,7 @@ static int handle_luainit(lua_State *L) const char *init = getenv(LUA_INIT); #endif if (init == NULL) - return 0; /* status OK */ + return LUA_OK; else if (init[0] == '@') return dofile(L, init+1); else @@ -508,45 +511,57 @@ static int pmain(lua_State *L) { struct Smain *s = &smain; char **argv = s->argv; - int script; + int argn; int flags = 0; globalL = L; if (argv[0] && argv[0][0]) progname = argv[0]; - LUAJIT_VERSION_SYM(); /* linker-enforced version check */ - script = collectargs(argv, &flags); - if (script < 0) { /* invalid args? */ + + LUAJIT_VERSION_SYM(); /* Linker-enforced version check. */ + + argn = collectargs(argv, &flags); + if (argn < 0) { /* Invalid args? */ print_usage(); s->status = 1; return 0; } + if ((flags & FLAGS_NOENV)) { lua_pushboolean(L, 1); lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); } - lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */ - luaL_openlibs(L); /* open libraries */ + + /* Stop collector during library initialization. */ + lua_gc(L, LUA_GCSTOP, 0); + luaL_openlibs(L); lua_gc(L, LUA_GCRESTART, -1); + + createargtable(L, argv, s->argc, argn); + if (!(flags & FLAGS_NOENV)) { s->status = handle_luainit(L); - if (s->status != 0) return 0; + if (s->status != LUA_OK) return 0; } + if ((flags & FLAGS_VERSION)) print_version(); - s->status = runargs(L, argv, (script > 0) ? script : s->argc); - if (s->status != 0) return 0; - if (script) { - s->status = handle_script(L, argv, script); - if (s->status != 0) return 0; + + s->status = runargs(L, argv, argn); + if (s->status != LUA_OK) return 0; + + if (s->argc > argn) { + s->status = handle_script(L, argv + argn); + if (s->status != LUA_OK) return 0; } + if ((flags & FLAGS_INTERACTIVE)) { print_jit_status(L); dotty(L); - } else if (script == 0 && !(flags & (FLAGS_EXEC|FLAGS_VERSION))) { + } else if (s->argc == argn && !(flags & (FLAGS_EXEC|FLAGS_VERSION))) { if (lua_stdin_is_tty()) { print_version(); print_jit_status(L); dotty(L); } else { - dofile(L, NULL); /* executes stdin as a file */ + dofile(L, NULL); /* Executes stdin as a file. */ } } return 0; @@ -555,7 +570,7 @@ static int pmain(lua_State *L) int main(int argc, char **argv) { int status; - lua_State *L = lua_open(); /* create state */ + lua_State *L = lua_open(); if (L == NULL) { l_message(argv[0], "cannot create state: not enough memory"); return EXIT_FAILURE; @@ -565,6 +580,6 @@ int main(int argc, char **argv) status = lua_cpcall(L, pmain, NULL); report(L, status); lua_close(L); - return (status || smain.status) ? EXIT_FAILURE : EXIT_SUCCESS; + return (status || smain.status > 0) ? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/Build/source/libs/luajit/LuaJIT-src/src/luajit.h b/Build/source/libs/luajit/LuaJIT-src/src/luajit.h index 1d0a558cabc..708a5a11fdb 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/luajit.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/luajit.h @@ -1,7 +1,7 @@ /* ** LuaJIT -- a Just-In-Time Compiler for Lua. http://luajit.org/ ** -** Copyright (C) 2005-2016 Mike Pall. All rights reserved. +** Copyright (C) 2005-2017 Mike Pall. All rights reserved. ** ** Permission is hereby granted, free of charge, to any person obtaining ** a copy of this software and associated documentation files (the @@ -30,10 +30,10 @@ #include "lua.h" -#define LUAJIT_VERSION "LuaJIT 2.1.0-beta2" +#define LUAJIT_VERSION "LuaJIT 2.1.0-beta3" #define LUAJIT_VERSION_NUM 20100 /* Version 2.1.0 = 02.01.00. */ -#define LUAJIT_VERSION_SYM luaJIT_version_2_1_0_beta2 -#define LUAJIT_COPYRIGHT "Copyright (C) 2005-2016 Mike Pall" +#define LUAJIT_VERSION_SYM luaJIT_version_2_1_0_beta3 +#define LUAJIT_COPYRIGHT "Copyright (C) 2005-2017 Mike Pall" #define LUAJIT_URL "http://luajit.org/" /* Modes for luaJIT_setmode. */ diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lualib.h b/Build/source/libs/luajit/LuaJIT-src/src/lualib.h index f2d9b486e6f..aed323428eb 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lualib.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lualib.h @@ -1,6 +1,6 @@ /* ** Standard library header. -** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LUALIB_H @@ -23,7 +23,7 @@ #define LUA_FFILIBNAME "ffi" #define LUA_BITLIBNAME_32 "bit32" - + LUALIB_API int luaopen_base(lua_State *L); LUALIB_API int luaopen_math(lua_State *L); LUALIB_API int luaopen_string(lua_State *L); diff --git a/Build/source/libs/luajit/LuaJIT-src/src/msvcbuild.bat b/Build/source/libs/luajit/LuaJIT-src/src/msvcbuild.bat index 9c6b5320ae7..71bde7598dc 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/msvcbuild.bat +++ b/Build/source/libs/luajit/LuaJIT-src/src/msvcbuild.bat @@ -1,5 +1,5 @@ @rem Script to build LuaJIT with MSVC.
-@rem Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
+@rem Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
@rem
@rem Either open a "Visual Studio .NET Command Prompt"
@rem (Note that the Express Edition does not contain an x64 compiler)
@@ -14,12 +14,13 @@ @if not defined INCLUDE goto :FAIL
@setlocal
-@set LJCOMPILE=cl /nologo /c /O2 /W3 /D_CRT_SECURE_NO_DEPRECATE
+@set LJCOMPILE=cl /nologo /c /O2 /W3 /D_CRT_SECURE_NO_DEPRECATE /D_CRT_STDIO_INLINE=__declspec(dllexport)__inline
@set LJLINK=link /nologo
@set LJMT=mt /nologo
@set LJLIB=lib /nologo /nodefaultlib
@set DASMDIR=..\dynasm
@set DASM=%DASMDIR%\dynasm.lua
+@set DASC=vm_x86.dasc
@set LJDLLNAME=lua51.dll
@set LJLIBNAME=lua51.lib
@set ALL_LIB=lib_base.c lib_math.c lib_bit.c lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c lib_jit.c lib_ffi.c
@@ -39,7 +40,12 @@ if exist minilua.exe.manifest^ @set LJARCH=x86
@set LJCOMPILE=%LJCOMPILE% /arch:SSE2
:X64
-minilua %DASM% -LN %DASMFLAGS% -o host\buildvm_arch.h vm_x86.dasc
+@if "%1" neq "gc64" goto :NOGC64
+@shift
+@set DASC=vm_x64.dasc
+@set LJCOMPILE=%LJCOMPILE% /DLUAJIT_ENABLE_GC64
+:NOGC64
+minilua %DASM% -LN %DASMFLAGS% -o host\buildvm_arch.h %DASC%
@if errorlevel 1 goto :BAD
%LJCOMPILE% /I "." /I %DASMDIR% host\buildvm*.c
@@ -67,7 +73,7 @@ buildvm -m folddef -o lj_folddef.h lj_opt_fold.c @if "%1" neq "debug" goto :NODEBUG
@shift
@set LJCOMPILE=%LJCOMPILE% /Zi
-@set LJLINK=%LJLINK% /debug
+@set LJLINK=%LJLINK% /debug /opt:ref /opt:icf /incremental:no
:NODEBUG
@if "%1"=="amalg" goto :AMALGDLL
@if "%1"=="static" goto :STATIC
@@ -99,6 +105,8 @@ if exist luajit.exe.manifest^ %LJMT% -manifest luajit.exe.manifest -outputresource:luajit.exe
@del *.obj *.manifest minilua.exe buildvm.exe
+@del host\buildvm_arch.h
+@del lj_bcdef.h lj_ffdef.h lj_libdef.h lj_recdef.h lj_folddef.h
@echo.
@echo === Successfully built LuaJIT for Windows/%LJARCH% ===
diff --git a/Build/source/libs/luajit/LuaJIT-src/src/vm_arm.dasc b/Build/source/libs/luajit/LuaJIT-src/src/vm_arm.dasc index 882884cdf76..780cc16e6de 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/vm_arm.dasc +++ b/Build/source/libs/luajit/LuaJIT-src/src/vm_arm.dasc @@ -1,6 +1,6 @@ |// Low-level VM code for ARM CPUs. |// Bytecode interpreter, fast functions and helper functions. -|// Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +|// Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h | |.arch arm |.section code_op, code_sub diff --git a/Build/source/libs/luajit/LuaJIT-src/src/vm_arm64.dasc b/Build/source/libs/luajit/LuaJIT-src/src/vm_arm64.dasc index 7a881bdd34c..3eaf37638e6 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/vm_arm64.dasc +++ b/Build/source/libs/luajit/LuaJIT-src/src/vm_arm64.dasc @@ -1,6 +1,6 @@ |// Low-level VM code for ARM64 CPUs. |// Bytecode interpreter, fast functions and helper functions. -|// Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +|// Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h | |.arch arm64 |.section code_op, code_sub @@ -151,6 +151,21 @@ |.define FRAME_FUNC, #-16 |.define FRAME_PC, #-8 | +|// Endian-specific defines. +|.if ENDIAN_LE +|.define LO, 0 +|.define OFS_RD, 2 +|.define OFS_RB, 3 +|.define OFS_RA, 1 +|.define OFS_OP, 0 +|.else +|.define LO, 4 +|.define OFS_RD, 0 +|.define OFS_RB, 0 +|.define OFS_RA, 2 +|.define OFS_OP, 3 +|.endif +| |.macro decode_RA, dst, ins; ubfx dst, ins, #8, #8; .endmacro |.macro decode_RB, dst, ins; ubfx dst, ins, #24, #8; .endmacro |.macro decode_RC, dst, ins; ubfx dst, ins, #16, #8; .endmacro @@ -236,12 +251,17 @@ |.macro mov_false, reg; movn reg, #0x8000, lsl #32; .endmacro |.macro mov_true, reg; movn reg, #0x0001, lsl #48; .endmacro | -#define GL_J(field) (GG_OFS(J) + (int)offsetof(jit_State, field)) +#define GL_J(field) (GG_G2J + (int)offsetof(jit_State, field)) | #define PC2PROTO(field) ((int)offsetof(GCproto, field)-(int)sizeof(GCproto)) | |.macro hotcheck, delta -| NYI +| lsr CARG1, PC, #1 +| and CARG1, CARG1, #126 +| add CARG1, CARG1, #GG_G2DISP+GG_DISP2HOT +| ldrh CARG2w, [GL, CARG1] +| subs CARG2, CARG2, #delta +| strh CARG2w, [GL, CARG1] |.endmacro | |.macro hotloop @@ -712,7 +732,7 @@ static void build_subroutines(BuildCtx *ctx) | cmp CRET1, #1 | bhi ->vmeta_binop |4: - | ldrh RBw, [PC, #2] + | ldrh RBw, [PC, # OFS_RD] | add PC, PC, #4 | add RB, PC, RB, lsl #2 | sub RB, RB, #0x20000 @@ -869,7 +889,7 @@ static void build_subroutines(BuildCtx *ctx) | bl extern lj_meta_for // (lua_State *L, TValue *base) | ldr INSw, [PC, #-4] |.if JIT - | uxtb TMP0, INS + | uxtb TMP0w, INSw |.endif | decode_RA RA, INS | decode_RD RC, INS @@ -1495,7 +1515,12 @@ static void build_subroutines(BuildCtx *ctx) | bne ->fff_fallback | checkint CARG1, ->fff_fallback | mov CARG3, #1 - | mov CARG2, BASE // Points to stack. Little-endian. + | // Point to the char inside the integer in the stack slot. + |.if ENDIAN_LE + | mov CARG2, BASE + |.else + | add CARG2, BASE, #7 + |.endif |->fff_newstr: | // CARG2 = str, CARG3 = len. | str BASE, L->base @@ -1698,7 +1723,7 @@ static void build_subroutines(BuildCtx *ctx) | ands TMP0, PC, #FRAME_TYPE | and TMP1, PC, #~FRAME_TYPEP | bne >3 - | ldrb RAw, [PC, #-3] + | ldrb RAw, [PC, #-4+OFS_RA] | lsl RA, RA, #3 | add TMP1, RA, #16 |3: @@ -1732,7 +1757,20 @@ static void build_subroutines(BuildCtx *ctx) |//----------------------------------------------------------------------- | |->vm_record: // Dispatch target for recording phase. - | NYI + |.if JIT + | ldrb CARG1w, GL->hookmask + | tst CARG1, #HOOK_VMEVENT // No recording while in vmevent. + | bne >5 + | // Decrement the hookcount for consistency, but always do the call. + | ldr CARG2w, GL->hookcount + | tst CARG1, #HOOK_ACTIVE + | bne >1 + | sub CARG2w, CARG2w, #1 + | tst CARG1, #LUA_MASKLINE|LUA_MASKCOUNT + | beq >1 + | str CARG2w, GL->hookcount + | b >1 + |.endif | |->vm_rethook: // Dispatch target for return hooks. | ldrb TMP2w, GL->hookmask @@ -1774,7 +1812,21 @@ static void build_subroutines(BuildCtx *ctx) | b <4 | |->vm_hotloop: // Hot loop counter underflow. - | NYI + |.if JIT + | ldr LFUNC:CARG3, [BASE, FRAME_FUNC] // Same as curr_topL(L). + | add CARG1, GL, #GG_G2DISP+GG_DISP2J + | and LFUNC:CARG3, CARG3, #LJ_GCVMASK + | str PC, SAVE_PC + | ldr CARG3, LFUNC:CARG3->pc + | mov CARG2, PC + | str L, [GL, #GL_J(L)] + | ldrb CARG3w, [CARG3, #PC2PROTO(framesize)] + | str BASE, L->base + | add CARG3, BASE, CARG3, lsl #3 + | str CARG3, L->top + | bl extern lj_trace_hot // (jit_State *J, const BCIns *pc) + | b <3 + |.endif | |->vm_callhook: // Dispatch target for call hooks. | mov CARG2, PC @@ -1804,7 +1856,54 @@ static void build_subroutines(BuildCtx *ctx) | br CRET1 | |->cont_stitch: // Trace stitching. - | NYI + |.if JIT + | // RA = resultptr, CARG4 = meta base + | ldr RBw, SAVE_MULTRES + | ldr INSw, [PC, #-4] + | ldr TRACE:CARG3, [CARG4, #-40] // Save previous trace. + | subs RB, RB, #8 + | decode_RA RC, INS // Call base. + | and CARG3, CARG3, #LJ_GCVMASK + | beq >2 + |1: // Move results down. + | ldr CARG1, [RA] + | add RA, RA, #8 + | subs RB, RB, #8 + | str CARG1, [BASE, RC, lsl #3] + | add RC, RC, #1 + | bne <1 + |2: + | decode_RA RA, INS + | decode_RB RB, INS + | add RA, RA, RB + |3: + | cmp RA, RC + | bhi >9 // More results wanted? + | + | ldrh RAw, TRACE:CARG3->traceno + | ldrh RCw, TRACE:CARG3->link + | cmp RCw, RAw + | beq ->cont_nop // Blacklisted. + | cmp RCw, #0 + | bne =>BC_JLOOP // Jump to stitched trace. + | + | // Stitch a new trace to the previous trace. + | mov CARG1, #GL_J(exitno) + | str RAw, [GL, CARG1] + | mov CARG1, #GL_J(L) + | str L, [GL, CARG1] + | str BASE, L->base + | add CARG1, GL, #GG_G2J + | mov CARG2, PC + | bl extern lj_dispatch_stitch // (jit_State *J, const BCIns *pc) + | ldr BASE, L->base + | b ->cont_nop + | + |9: // Fill up results with nil. + | str TISNIL, [BASE, RC, lsl #3] + | add RC, RC, #1 + | b <3 + |.endif | |->vm_profhook: // Dispatch target for profiler hook. #if LJ_HASPROFILE @@ -1822,10 +1921,122 @@ static void build_subroutines(BuildCtx *ctx) |//-- Trace exit handler ------------------------------------------------- |//----------------------------------------------------------------------- | + |.macro savex_, a, b + | stp d..a, d..b, [sp, #a*8] + | stp x..a, x..b, [sp, #32*8+a*8] + |.endmacro + | |->vm_exit_handler: - | NYI + |.if JIT + | sub sp, sp, #(64*8) + | savex_, 0, 1 + | savex_, 2, 3 + | savex_, 4, 5 + | savex_, 6, 7 + | savex_, 8, 9 + | savex_, 10, 11 + | savex_, 12, 13 + | savex_, 14, 15 + | savex_, 16, 17 + | savex_, 18, 19 + | savex_, 20, 21 + | savex_, 22, 23 + | savex_, 24, 25 + | savex_, 26, 27 + | savex_, 28, 29 + | stp d30, d31, [sp, #30*8] + | ldr CARG1, [sp, #64*8] // Load original value of lr. + | add CARG3, sp, #64*8 // Recompute original value of sp. + | mv_vmstate CARG4w, EXIT + | stp xzr, CARG3, [sp, #62*8] // Store 0/sp in RID_LR/RID_SP. + | sub CARG1, CARG1, lr + | ldr L, GL->cur_L + | lsr CARG1, CARG1, #2 + | ldr BASE, GL->jit_base + | sub CARG1, CARG1, #2 + | ldr CARG2w, [lr] // Load trace number. + | st_vmstate CARG4w + |.if ENDIAN_BE + | rev32 CARG2, CARG2 + |.endif + | str BASE, L->base + | ubfx CARG2w, CARG2w, #5, #16 + | str CARG1w, [GL, #GL_J(exitno)] + | str CARG2w, [GL, #GL_J(parent)] + | str L, [GL, #GL_J(L)] + | str xzr, GL->jit_base + | add CARG1, GL, #GG_G2J + | mov CARG2, sp + | bl extern lj_trace_exit // (jit_State *J, ExitState *ex) + | // Returns MULTRES (unscaled) or negated error code. + | ldr CARG2, L->cframe + | ldr BASE, L->base + | and sp, CARG2, #CFRAME_RAWMASK + | ldr PC, SAVE_PC // Get SAVE_PC. + | str L, SAVE_L // Set SAVE_L (on-trace resume/yield). + | b >1 + |.endif + | |->vm_exit_interp: - | NYI + | // CARG1 = MULTRES or negated error code, BASE, PC and GL set. + |.if JIT + | ldr L, SAVE_L + |1: + | cmp CARG1w, #0 + | blt >9 // Check for error from exit. + | lsl RC, CARG1, #3 + | ldr LFUNC:CARG2, [BASE, FRAME_FUNC] + | movz TISNUM, #(LJ_TISNUM>>1)&0xffff, lsl #48 + | movz TISNUMhi, #(LJ_TISNUM>>1)&0xffff, lsl #16 + | movn TISNIL, #0 + | and LFUNC:CARG2, CARG2, #LJ_GCVMASK + | str RCw, SAVE_MULTRES + | str BASE, L->base + | ldr CARG2, LFUNC:CARG2->pc + | str xzr, GL->jit_base + | mv_vmstate CARG4w, INTERP + | ldr KBASE, [CARG2, #PC2PROTO(k)] + | // Modified copy of ins_next which handles function header dispatch, too. + | ldrb RBw, [PC, # OFS_OP] + | ldr INSw, [PC], #4 + | st_vmstate CARG4w + | cmp RBw, #BC_FUNCC+2 // Fast function? + | add TMP1, GL, INS, uxtb #3 + | bhs >4 + |2: + | cmp RBw, #BC_FUNCF // Function header? + | add TMP0, GL, RB, uxtb #3 + | ldr RB, [TMP0, #GG_G2DISP] + | decode_RA RA, INS + | lsr TMP0, INS, #16 + | csel RC, TMP0, RC, lo + | blo >5 + | ldr CARG3, [BASE, FRAME_FUNC] + | sub RC, RC, #8 + | add RA, BASE, RA, lsl #3 // Yes: RA = BASE+framesize*8, RC = nargs*8 + | and LFUNC:CARG3, CARG3, #LJ_GCVMASK + |5: + | br RB + | + |4: // Check frame below fast function. + | ldr CARG1, [BASE, FRAME_PC] + | ands CARG2, CARG1, #FRAME_TYPE + | bne <2 // Trace stitching continuation? + | // Otherwise set KBASE for Lua function below fast function. + | ldr CARG3w, [CARG1, #-4] + | decode_RA CARG1, CARG3 + | sub CARG2, BASE, CARG1, lsl #3 + | ldr LFUNC:CARG3, [CARG2, #-32] + | and LFUNC:CARG3, CARG3, #LJ_GCVMASK + | ldr CARG3, LFUNC:CARG3->pc + | ldr KBASE, [CARG3, #PC2PROTO(k)] + | b <2 + | + |9: // Rethrow error from the right C frame. + | neg CARG2, CARG1 + | mov CARG1, L + | bl extern lj_err_throw // (lua_State *L, int errcode) + |.endif | |//----------------------------------------------------------------------- |//-- Math helper functions ---------------------------------------------- @@ -1965,7 +2176,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT: | // RA = src1, RC = src2, JMP with RC = target | ldr CARG1, [BASE, RA, lsl #3] - | ldrh RBw, [PC, #2] + | ldrh RBw, [PC, # OFS_RD] | ldr CARG2, [BASE, RC, lsl #3] | add PC, PC, #4 | add RB, PC, RB, lsl #2 @@ -2022,7 +2233,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | // RA = src1, RC = src2, JMP with RC = target | ldr CARG1, [BASE, RA, lsl #3] | add RC, BASE, RC, lsl #3 - | ldrh RBw, [PC, #2] + | ldrh RBw, [PC, # OFS_RD] | ldr CARG3, [RC] | add PC, PC, #4 | add RB, PC, RB, lsl #2 @@ -2083,7 +2294,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | // RA = src, RC = str_const (~), JMP with RC = target | ldr CARG1, [BASE, RA, lsl #3] | mvn RC, RC - | ldrh RBw, [PC, #2] + | ldrh RBw, [PC, # OFS_RD] | ldr CARG2, [KBASE, RC, lsl #3] | add PC, PC, #4 | movn TMP0, #~LJ_TSTR @@ -2111,7 +2322,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | // RA = src, RC = num_const (~), JMP with RC = target | ldr CARG1, [BASE, RA, lsl #3] | add RC, KBASE, RC, lsl #3 - | ldrh RBw, [PC, #2] + | ldrh RBw, [PC, # OFS_RD] | ldr CARG3, [RC] | add PC, PC, #4 | add RB, PC, RB, lsl #2 @@ -2171,7 +2382,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) vk = op == BC_ISEQP; | // RA = src, RC = primitive_type (~), JMP with RC = target | ldr TMP0, [BASE, RA, lsl #3] - | ldrh RBw, [PC, #2] + | ldrh RBw, [PC, # OFS_RD] | add PC, PC, #4 | add RC, RC, #1 | add RB, PC, RB, lsl #2 @@ -2196,7 +2407,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) case BC_ISTC: case BC_ISFC: case BC_IST: case BC_ISF: | // RA = dst or unused, RC = src, JMP with RC = target - | ldrh RBw, [PC, #2] + | ldrh RBw, [PC, # OFS_RD] | ldr TMP0, [BASE, RC, lsl #3] | add PC, PC, #4 | mov_false TMP1 @@ -2443,7 +2654,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | str PC, SAVE_PC | bl extern lj_meta_cat // (lua_State *L, TValue *top, int left) | // Returns NULL (finished) or TValue * (metamethod). - | ldrb RBw, [PC, #-1] + | ldrb RBw, [PC, #-4+OFS_RB] | ldr BASE, L->base | cbnz CRET1, ->vmeta_binop | ldr TMP0, [BASE, RB, lsl #3] @@ -3074,7 +3285,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | ins_callt | |5: // Tailcall to a fast function with a Lua frame below. - | ldrb RAw, [PC, #-3] + | ldrb RAw, [PC, #-4+OFS_RA] | sub CARG1, BASE, RA, lsl #3 | ldr LFUNC:CARG1, [CARG1, #-32] | and LFUNC:CARG1, CARG1, #LJ_GCVMASK @@ -3115,8 +3326,8 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) |.endif | add RA, BASE, RA, lsl #3 | ldr TAB:RB, [RA, #-16] - | ldrh TMP3w, [PC, #2] - | ldr CARG1w, [RA, #-8] // Get index from control var. + | ldrh TMP3w, [PC, # OFS_RD] + | ldr CARG1w, [RA, #-8+LO] // Get index from control var. | add PC, PC, #4 | add TMP3, PC, TMP3, lsl #2 | and TAB:RB, RB, #LJ_GCVMASK @@ -3135,7 +3346,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | stp CARG1, TMP0, [RA] | add CARG1, CARG1, #1 |3: - | str CARG1w, [RA, #-8] // Update control var. + | str CARG1w, [RA, #-8+LO] // Update control var. | mov PC, TMP3 |4: | ins_next @@ -3181,8 +3392,8 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) |5: // Despecialize bytecode if any of the checks fail. | mov TMP0, #BC_JMP | mov TMP1, #BC_ITERC - | strb TMP0w, [PC, #-4] - | strb TMP1w, [RC] + | strb TMP0w, [PC, #-4+OFS_OP] + | strb TMP1w, [RC, # OFS_OP] | b <1 break; @@ -3387,7 +3598,8 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) if (op == BC_FORI) { | csel PC, RC, PC, gt } else if (op == BC_JFORI) { - | ldrh RCw, [RC, #-2] + | mov PC, RC + | ldrh RCw, [RC, #-4+OFS_RD] } else if (op == BC_IFORL) { | csel PC, RC, PC, le } @@ -3428,7 +3640,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) if (op == BC_FORI) { | csel PC, RC, PC, hi } else if (op == BC_JFORI) { - | ldrh RCw, [RC, #-2] + | ldrh RCw, [RC, #-4+OFS_RD] | bls =>BC_JLOOP } else if (op == BC_IFORL) { | csel PC, RC, PC, ls @@ -3488,7 +3700,16 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) case BC_JLOOP: |.if JIT - | NYI + | // RA = base (ignored), RC = traceno + | ldr CARG1, [GL, #GL_J(trace)] + | mov CARG2w, #0 // Traces on ARM64 don't store the trace #, so use 0. + | ldr TRACE:RC, [CARG1, RC, lsl #3] + | st_vmstate CARG2w + | ldr RA, TRACE:RC->mcode + | str BASE, GL->jit_base + | str L, GL->tmpbuf.L + | sub sp, sp, #16 // See SPS_FIXED. Avoids sp adjust in every root trace. + | br RA |.endif break; @@ -3546,10 +3767,12 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) case BC_IFUNCV: | // BASE = new base, RA = BASE+framesize*8, CARG3 = LFUNC, RC = nargs*8 | ldr CARG1, L->maxstack + | movn TMP0, #~LJ_TFUNC | add TMP2, BASE, RC + | add LFUNC:CARG3, CARG3, TMP0, lsl #47 | add RA, RA, RC | add TMP0, RC, #16+FRAME_VARG - | str LFUNC:CARG3, [TMP2], #8 // Store (untagged) copy of LFUNC. + | str LFUNC:CARG3, [TMP2], #8 // Store (tagged) copy of LFUNC. | ldr KBASE, [PC, #-4+PC2PROTO(k)] | cmp RA, CARG1 | str TMP0, [TMP2], #8 // Store delta + FRAME_VARG. @@ -3736,8 +3959,8 @@ static void emit_asm_debug(BuildCtx *ctx) "\t.uleb128 0x1\n" "\t.sleb128 -8\n" "\t.byte 30\n" /* Return address is in lr. */ - "\t.uleb128 1\n" /* augmentation length */ - "\t.byte 0x1b\n" /* pcrel|sdata4 */ + "\t.uleb128 1\n" /* augmentation length */ + "\t.byte 0x1b\n" /* pcrel|sdata4 */ "\t.byte 0xc\n\t.uleb128 31\n\t.uleb128 0\n" /* def_cfa sp */ "\t.align 3\n" ".LECIE2:\n\n"); @@ -3748,7 +3971,7 @@ static void emit_asm_debug(BuildCtx *ctx) "\t.long .LASFDE3-.Lframe2\n" "\t.long lj_vm_ffi_call-.\n" "\t.long %d\n" - "\t.uleb128 0\n" /* augmentation length */ + "\t.uleb128 0\n" /* augmentation length */ "\t.byte 0xe\n\t.uleb128 32\n" /* def_cfa_offset */ "\t.byte 0x9d\n\t.uleb128 4\n" /* offset fp */ "\t.byte 0x9e\n\t.uleb128 3\n" /* offset lr */ diff --git a/Build/source/libs/luajit/LuaJIT-src/src/vm_mips.dasc b/Build/source/libs/luajit/LuaJIT-src/src/vm_mips.dasc index 03b3084e88a..1afd61187a7 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/vm_mips.dasc +++ b/Build/source/libs/luajit/LuaJIT-src/src/vm_mips.dasc @@ -1,6 +1,6 @@ |// Low-level VM code for MIPS CPUs. |// Bytecode interpreter, fast functions and helper functions. -|// Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +|// Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h |// |// MIPS soft-float support contributed by Djordje Kovacevic and |// Stefan Pejic from RT-RK.com, sponsored by Cisco Systems, Inc. @@ -57,7 +57,7 @@ |.define TMP2, r14 |.define TMP3, r15 | -|// Calling conventions. +|// MIPS o32 calling convention. |.define CFUNCADDR, r25 |.define CARG1, r4 |.define CARG2, r5 @@ -1875,7 +1875,8 @@ static void build_subroutines(BuildCtx *ctx) | |.ffunc string_char // Only handle the 1-arg case here. | ffgccheck - |. lw CARG3, HI(BASE) + |. nop + | lw CARG3, HI(BASE) | lw CARG1, LO(BASE) | li TMP1, 255 | xori AT, NARGS8:RC, 8 // Exactly 1 argument. @@ -1902,7 +1903,8 @@ static void build_subroutines(BuildCtx *ctx) | |.ffunc string_sub | ffgccheck - |. addiu AT, NARGS8:RC, -16 + |. nop + | addiu AT, NARGS8:RC, -16 | lw CARG3, 16+HI(BASE) | lw TMP0, HI(BASE) | lw STR:CARG1, LO(BASE) @@ -1946,7 +1948,8 @@ static void build_subroutines(BuildCtx *ctx) |.macro ffstring_op, name | .ffunc string_ .. name | ffgccheck - |. lw CARG3, HI(BASE) + |. nop + | lw CARG3, HI(BASE) | lw STR:CARG2, LO(BASE) | beqz NARGS8:RC, ->fff_fallback |. li AT, LJ_TSTR @@ -4314,7 +4317,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | ins_next2 | |7: // Possible table write barrier for the value. Skip valiswhite check. - | barrierback TAB:RB, TMP3, TMP0, <2 + | barrierback TAB:CARG2, TMP3, TMP0, <2 break; case BC_TSETM: @@ -4543,24 +4546,24 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) case BC_ISNEXT: | // RA = base*8, RD = target (points to ITERN) | addu RA, BASE, RA - | lw TMP0, -24+HI(RA) - | lw CFUNC:TMP1, -24+LO(RA) - | lw TMP2, -16+HI(RA) - | lw TMP3, -8+HI(RA) + | srl TMP0, RD, 1 + | lw CARG1, -24+HI(RA) + | lw CFUNC:CARG2, -24+LO(RA) + | addu TMP0, PC, TMP0 + | lw CARG3, -16+HI(RA) + | lw CARG4, -8+HI(RA) | li AT, LJ_TFUNC - | bne TMP0, AT, >5 - |. addiu TMP2, TMP2, -LJ_TTAB - | lbu TMP1, CFUNC:TMP1->ffid - | addiu TMP3, TMP3, -LJ_TNIL - | srl TMP0, RD, 1 - | or TMP2, TMP2, TMP3 - | addiu TMP1, TMP1, -FF_next_N - | addu TMP0, PC, TMP0 - | or TMP1, TMP1, TMP2 - | bnez TMP1, >5 - |. lui TMP2, (-(BCBIAS_J*4 >> 16) & 65535) + | bne CARG1, AT, >5 + |. lui TMP2, (-(BCBIAS_J*4 >> 16) & 65535) + | lbu CARG2, CFUNC:CARG2->ffid + | addiu CARG3, CARG3, -LJ_TTAB + | addiu CARG4, CARG4, -LJ_TNIL + | or CARG3, CARG3, CARG4 + | addiu CARG2, CARG2, -FF_next_N + | or CARG2, CARG2, CARG3 + | bnez CARG2, >5 + |. lui TMP1, 0xfffe | addu PC, TMP0, TMP2 - | lui TMP1, 0xfffe | ori TMP1, TMP1, 0x7fff | sw r0, -8+LO(RA) // Initialize control var. | sw TMP1, -8+HI(RA) @@ -4570,7 +4573,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | li TMP3, BC_JMP | li TMP1, BC_ITERC | sb TMP3, -4+OFS_OP(PC) - | addu PC, TMP0, TMP2 + | addu PC, TMP0, TMP2 | b <1 |. sb TMP1, OFS_OP(PC) break; diff --git a/Build/source/libs/luajit/LuaJIT-src/src/vm_ppc.dasc b/Build/source/libs/luajit/LuaJIT-src/src/vm_ppc.dasc index be4356e7480..b4260ebc107 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/vm_ppc.dasc +++ b/Build/source/libs/luajit/LuaJIT-src/src/vm_ppc.dasc @@ -1,6 +1,6 @@ |// Low-level VM code for PowerPC 32 bit or 32on64 bit mode. |// Bytecode interpreter, fast functions and helper functions. -|// Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +|// Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h | |.arch ppc |.section code_op, code_sub diff --git a/Build/source/libs/luajit/LuaJIT-src/src/vm_x64.dasc b/Build/source/libs/luajit/LuaJIT-src/src/vm_x64.dasc index a6b6853e1e9..a003fb4f6bf 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/vm_x64.dasc +++ b/Build/source/libs/luajit/LuaJIT-src/src/vm_x64.dasc @@ -1,6 +1,6 @@ |// Low-level VM code for x64 CPUs in LJ_GC64 mode. |// Bytecode interpreter, fast functions and helper functions. -|// Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +|// Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h | |.arch x64 |.section code_op, code_sub @@ -250,11 +250,11 @@ |// Macros to clear or set tags. |.macro cleartp, reg; shl reg, 17; shr reg, 17; .endmacro |.macro settp, reg, tp -| mov64 ITYPE, ((int64_t)tp<<47) +| mov64 ITYPE, ((uint64_t)tp<<47) | or reg, ITYPE |.endmacro |.macro settp, dst, reg, tp -| mov64 dst, ((int64_t)tp<<47) +| mov64 dst, ((uint64_t)tp<<47) | or dst, reg |.endmacro |.macro setint, reg @@ -1105,11 +1105,11 @@ static void build_subroutines(BuildCtx *ctx) | mov BASE, L:RB->base | mov NARGS:RDd, TMP1d | mov LFUNC:RB, [RA-16] - | cleartp LFUNC:RB | add NARGS:RDd, 1 | // This is fragile. L->base must not move, KBASE must always be defined. | cmp KBASE, BASE // Continue with CALLT if flag set. | je ->BC_CALLT_Z + | cleartp LFUNC:RB | mov BASE, RA | ins_call // Otherwise call resolved metamethod. | @@ -1469,7 +1469,7 @@ static void build_subroutines(BuildCtx *ctx) | mov [BASE-16], CFUNC:RD | mov [BASE-8], TMPR |.if DUALNUM - | mov64 RD, ((int64_t)LJ_TISNUM<<47) + | mov64 RD, ((uint64_t)LJ_TISNUM<<47) | mov [BASE], RD |.else | mov qword [BASE], 0 @@ -1804,12 +1804,12 @@ static void build_subroutines(BuildCtx *ctx) | jmp ->fff_res1 | |.ffunc_n math_frexp + | mov RB, BASE |.if X64WIN - | lea CARG2, TMP1 + | lea CARG2, TMP1 // Caveat: CARG2 == BASE |.else | lea CARG1, TMP1 |.endif - | mov RB, BASE | call extern frexp | mov BASE, RB | mov RBd, TMP1d @@ -1826,13 +1826,12 @@ static void build_subroutines(BuildCtx *ctx) | jmp ->fff_res | |.ffunc_n math_modf + | mov RB, BASE |.if X64WIN - | lea CARG2, [BASE-16] + | lea CARG2, [BASE-16] // Caveat: CARG2 == BASE |.else | lea CARG1, [BASE-16] |.endif - | mov PC, [BASE-8] - | mov RB, BASE | call extern modf | mov BASE, RB | mov PC, [BASE-8] @@ -2325,7 +2324,8 @@ static void build_subroutines(BuildCtx *ctx) |->cont_stitch: // Trace stitching. |.if JIT | // BASE = base, RC = result, RB = mbase - | mov ITYPEd, [RB-24] // Save previous trace number. + | mov TRACE:ITYPE, [RB-40] // Save previous trace. + | cleartp TRACE:ITYPE | mov TMPRd, MULTRES | movzx RAd, PC_RA | lea RA, [BASE+RA*8] // Call base. @@ -2347,11 +2347,10 @@ static void build_subroutines(BuildCtx *ctx) | cmp RC, RA | ja >9 // More results wanted? | - | mov RA, [DISPATCH+DISPATCH_J(trace)] - | mov TRACE:RD, [RA+ITYPE*8] - | test TRACE:RD, TRACE:RD + | test TRACE:ITYPE, TRACE:ITYPE | jz ->cont_nop - | movzx RDd, word TRACE:RD->link + | movzx RBd, word TRACE:ITYPE->traceno + | movzx RDd, word TRACE:ITYPE->link | cmp RDd, RBd | je ->cont_nop // Blacklisted. | test RDd, RDd @@ -2402,12 +2401,11 @@ static void build_subroutines(BuildCtx *ctx) | movzx RCd, byte [rbp-8] // Reconstruct exit number. | mov RCH, byte [rbp-16] | mov [rbp-8], r15; mov [rbp-16], r14 - | // Caveat: DISPATCH is rbx. - | mov DISPATCH, [ebp] - | mov RA, [DISPATCH+DISPATCH_GL(vmstate)] // Get trace number. + | // DISPATCH is preserved on-trace in LJ_GC64 mode. + | mov RAd, [DISPATCH+DISPATCH_GL(vmstate)] // Get trace number. | set_vmstate EXIT - | mov [DISPATCH+DISPATCH_J(exitno)], RC - | mov [DISPATCH+DISPATCH_J(parent)], RA + | mov [DISPATCH+DISPATCH_J(exitno)], RCd + | mov [DISPATCH+DISPATCH_J(parent)], RAd |.if X64WIN | sub rsp, 16*8+4*8 // Room for SSE regs + save area. |.else @@ -2433,7 +2431,7 @@ static void build_subroutines(BuildCtx *ctx) | mov CARG2, rsp |.endif | lea CARG1, [DISPATCH+GG_DISP2J] - | mov dword [DISPATCH+DISPATCH_GL(jit_base)], 0 + | mov qword [DISPATCH+DISPATCH_GL(jit_base)], 0 | call extern lj_trace_exit // (jit_State *J, ExitState *ex) | // MULTRES or negated error code returned in eax (RD). | mov RA, L:RB->cframe @@ -2480,7 +2478,7 @@ static void build_subroutines(BuildCtx *ctx) | mov KBASE, LFUNC:KBASE->pc | mov KBASE, [KBASE+PC2PROTO(k)] | mov L:RB->base, BASE - | mov dword [DISPATCH+DISPATCH_GL(jit_base)], 0 + | mov qword [DISPATCH+DISPATCH_GL(jit_base)], 0 | set_vmstate INTERP | // Modified copy of ins_next which handles function header dispatch, too. | mov RCd, [PC] @@ -2504,7 +2502,7 @@ static void build_subroutines(BuildCtx *ctx) | // Otherwise set KBASE for Lua function below fast function. | movzx RCd, byte [RC-3] | neg RC - | mov LFUNC:KBASE, [BASE+RC*8-24] + | mov LFUNC:KBASE, [BASE+RC*8-32] | cleartp LFUNC:KBASE | mov KBASE, LFUNC:KBASE->pc | mov KBASE, [KBASE+PC2PROTO(k)] @@ -2639,6 +2637,7 @@ static void build_subroutines(BuildCtx *ctx) | mov eax, CARG1d | .if X64WIN; push rsi; mov rsi, CARG2; .endif | push rbx + | xor ecx, ecx | cpuid | mov [rsi], eax | mov [rsi+4], ebx @@ -3516,7 +3515,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | ins_AD // RA = level, RD = target | branchPC RD // Do this first to free RD. | mov L:RB, SAVE_L - | cmp dword L:RB->openupval, 0 + | cmp aword L:RB->openupval, 0 | je >1 | mov L:RB->base, BASE | lea CARG2, [BASE+RA*8] // Caveat: CARG2 == BASE @@ -4050,7 +4049,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | mov RC, [RA-24] // Copy control var. fb[1] = fb[-3]. | mov [RA], RB | mov [RA+8], RC - | mov LFUNC:RB, [RA-40] // Copy callable. fb[-1] = fb[-5] + | mov LFUNC:RB, [RA-40] // Copy callable. fb[-2] = fb[-5] | mov [RA-16], LFUNC:RB | mov NARGS:RDd, 2+1 // Handle like a regular 2-arg call. | checkfunc LFUNC:RB, ->vmeta_call diff --git a/Build/source/libs/luajit/LuaJIT-src/src/vm_x86.dasc b/Build/source/libs/luajit/LuaJIT-src/src/vm_x86.dasc index fcef660c420..211ae7b922a 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/vm_x86.dasc +++ b/Build/source/libs/luajit/LuaJIT-src/src/vm_x86.dasc @@ -1,6 +1,6 @@ |// Low-level VM code for x86 CPUs. |// Bytecode interpreter, fast functions and helper functions. -|// Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +|// Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h | |.if P64 |.arch x64 @@ -121,19 +121,68 @@ |//----------------------------------------------------------------------- |.if not X64 // x86 stack layout. | -|.define CFRAME_SPACE, aword*7 // Delta for esp (see <--). +|.if WIN +| +|.define CFRAME_SPACE, aword*9 // Delta for esp (see <--). |.macro saveregs_ | push edi; push esi; push ebx +| push extern lj_err_unwind_win +| fs; push dword [0] +| fs; mov [0], esp | sub esp, CFRAME_SPACE |.endmacro -|.macro saveregs -| push ebp; saveregs_ +|.macro restoreregs +| add esp, CFRAME_SPACE +| fs; pop dword [0] +| pop edi // Short for esp += 4. +| pop ebx; pop esi; pop edi; pop ebp +|.endmacro +| +|.else +| +|.define CFRAME_SPACE, aword*7 // Delta for esp (see <--). +|.macro saveregs_ +| push edi; push esi; push ebx +| sub esp, CFRAME_SPACE |.endmacro |.macro restoreregs | add esp, CFRAME_SPACE | pop ebx; pop esi; pop edi; pop ebp |.endmacro | +|.endif +| +|.macro saveregs +| push ebp; saveregs_ +|.endmacro +| +|.if WIN +|.define SAVE_ERRF, aword [esp+aword*19] // vm_pcall/vm_cpcall only. +|.define SAVE_NRES, aword [esp+aword*18] +|.define SAVE_CFRAME, aword [esp+aword*17] +|.define SAVE_L, aword [esp+aword*16] +|//----- 16 byte aligned, ^^^ arguments from C caller +|.define SAVE_RET, aword [esp+aword*15] //<-- esp entering interpreter. +|.define SAVE_R4, aword [esp+aword*14] +|.define SAVE_R3, aword [esp+aword*13] +|.define SAVE_R2, aword [esp+aword*12] +|//----- 16 byte aligned +|.define SAVE_R1, aword [esp+aword*11] +|.define SEH_FUNC, aword [esp+aword*10] +|.define SEH_NEXT, aword [esp+aword*9] //<-- esp after register saves. +|.define UNUSED2, aword [esp+aword*8] +|//----- 16 byte aligned +|.define UNUSED1, aword [esp+aword*7] +|.define SAVE_PC, aword [esp+aword*6] +|.define TMP2, aword [esp+aword*5] +|.define TMP1, aword [esp+aword*4] +|//----- 16 byte aligned +|.define ARG4, aword [esp+aword*3] +|.define ARG3, aword [esp+aword*2] +|.define ARG2, aword [esp+aword*1] +|.define ARG1, aword [esp] //<-- esp while in interpreter. +|//----- 16 byte aligned, ^^^ arguments for C callee +|.else |.define SAVE_ERRF, aword [esp+aword*15] // vm_pcall/vm_cpcall only. |.define SAVE_NRES, aword [esp+aword*14] |.define SAVE_CFRAME, aword [esp+aword*13] @@ -154,6 +203,7 @@ |.define ARG2, aword [esp+aword*1] |.define ARG1, aword [esp] //<-- esp while in interpreter. |//----- 16 byte aligned, ^^^ arguments for C callee +|.endif | |// FPARGx overlaps ARGx and ARG(x+1) on x86. |.define FPARG3, qword [esp+qword*1] @@ -554,6 +604,10 @@ static void build_subroutines(BuildCtx *ctx) |.else | mov eax, FCARG2 // Error return status for vm_pcall. | mov esp, FCARG1 + |.if WIN + | lea FCARG1, SEH_NEXT + | fs; mov [0], FCARG1 + |.endif |.endif |->vm_unwind_c_eh: // Landing pad for external unwinder. | mov L:RB, SAVE_L @@ -577,6 +631,10 @@ static void build_subroutines(BuildCtx *ctx) |.else | and FCARG1, CFRAME_RAWMASK | mov esp, FCARG1 + |.if WIN + | lea FCARG1, SEH_NEXT + | fs; mov [0], FCARG1 + |.endif |.endif |->vm_unwind_ff_eh: // Landing pad for external unwinder. | mov L:RB, SAVE_L @@ -590,6 +648,19 @@ static void build_subroutines(BuildCtx *ctx) | set_vmstate INTERP | jmp ->vm_returnc // Increments RD/MULTRES and returns. | + |.if WIN and not X64 + |->vm_rtlunwind@16: // Thin layer around RtlUnwind. + | // (void *cframe, void *excptrec, void *unwinder, int errcode) + | mov [esp], FCARG1 // Return value for RtlUnwind. + | push FCARG2 // Exception record for RtlUnwind. + | push 0 // Ignored by RtlUnwind. + | push dword [FCARG1+CFRAME_OFS_SEH] + | call extern RtlUnwind@16 // Violates ABI (clobbers too much). + | mov FCARG1, eax + | mov FCARG2, [esp+4] // errcode (for vm_unwind_c). + | ret // Jump to unwinder. + |.endif + | |//----------------------------------------------------------------------- |//-- Grow stack for calls ----------------------------------------------- |//----------------------------------------------------------------------- @@ -3026,6 +3097,7 @@ static void build_subroutines(BuildCtx *ctx) | mov eax, CARG1d | .if X64WIN; push rsi; mov rsi, CARG2; .endif | push rbx + | xor ecx, ecx | cpuid | mov [rsi], eax | mov [rsi+4], ebx @@ -3049,6 +3121,7 @@ static void build_subroutines(BuildCtx *ctx) | mov eax, [esp+4] // Argument 1 is function number. | push edi | push ebx + | xor ecx, ecx | cpuid | mov edi, [esp+16] // Argument 2 is result area. | mov [edi], eax diff --git a/Build/source/libs/luajit/Makefile.in b/Build/source/libs/luajit/Makefile.in index fe781a489e6..8390a96fc36 100644 --- a/Build/source/libs/luajit/Makefile.in +++ b/Build/source/libs/luajit/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -662,6 +662,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -1528,7 +1529,7 @@ distdir: $(DISTFILES) ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir @@ -1554,7 +1555,7 @@ dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir @@ -1572,7 +1573,7 @@ dist dist-all: distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ - eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ @@ -1582,7 +1583,7 @@ distcheck: dist *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ - eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac diff --git a/Build/source/libs/luajit/TLpatches/ChangeLog b/Build/source/libs/luajit/TLpatches/ChangeLog index b74ee1d6be4..2e29cb46ab0 100644 --- a/Build/source/libs/luajit/TLpatches/ChangeLog +++ b/Build/source/libs/luajit/TLpatches/ChangeLog @@ -1,3 +1,8 @@ +2017-20-06 Luigi Scarso <luigi.scarso@gmail.com> + * Luajit-2.1.0-beta3 + * Removed lj_bcdef.h, lj_ffdef.h, lj_folddef.h, lj_libdef.h + lj_recdef.h, they are generated at building time. + 2016-03-07 Luigi Scarso <luigi.scarso@gmail.com> Luajit-2.1.0-beta2 diff --git a/Build/source/libs/luajit/TLpatches/patch-01 b/Build/source/libs/luajit/TLpatches/patch-01 new file mode 100644 index 00000000000..7fcb2cadf0b --- /dev/null +++ b/Build/source/libs/luajit/TLpatches/patch-01 @@ -0,0 +1,21 @@ +diff -bur LuaJIT-2.1.0-beta3-orig/src/Makefile LuaJIT-2.1.0-beta3/src/Makefile +--- LuaJIT-2.1.0-beta3-orig/src/Makefile 2017-05-01 21:05:00.000000000 +0200 ++++ LuaJIT-2.1.0-beta3/src/Makefile 2017-06-16 17:14:56.792102569 +0200 +@@ -99,7 +99,7 @@ + # enabled by default. Some other features that *might* break some existing + # code (e.g. __pairs or os.execute() return values) can be enabled here. + # Note: this does not provide full compatibility with Lua 5.2 at this time. +-#XCFLAGS+= -DLUAJIT_ENABLE_LUA52COMPAT ++XCFLAGS+= -DLUAJIT_ENABLE_LUA52COMPAT + # + # Disable the JIT compiler, i.e. turn LuaJIT into a pure interpreter. + #XCFLAGS+= -DLUAJIT_DISABLE_JIT +@@ -475,7 +475,7 @@ + LJVM_BOUT= $(LJVM_S) + LJVM_MODE= elfasm + +-LJLIB_O= lib_base.o lib_math.o lib_bit.o lib_string.o lib_table.o \ ++LJLIB_O= lib_base.o lib_math.o lbitlib.o lib_bit.o lib_string.o lib_table.o \ + lib_io.o lib_os.o lib_package.o lib_debug.o lib_jit.o lib_ffi.o + LJLIB_C= $(LJLIB_O:.o=.c) + diff --git a/Build/source/libs/luajit/TLpatches/patch-01-LuaJITTeX b/Build/source/libs/luajit/TLpatches/patch-01-LuaJITTeX deleted file mode 100644 index 2e8220e0c36..00000000000 --- a/Build/source/libs/luajit/TLpatches/patch-01-LuaJITTeX +++ /dev/null @@ -1,221 +0,0 @@ -diff -bur LuaJIT-src-orig/src/lauxlib.h LuaJIT-src/src/lauxlib.h ---- LuaJIT-src-orig/src/lauxlib.h 2016-03-07 09:43:42.708069718 +0100 -+++ LuaJIT-src/src/lauxlib.h 2016-03-04 16:52:23.000000000 +0100 -@@ -86,6 +86,32 @@ - int level); - - -+ -+/* -+** {====================================================== -+** File handles for IO library -+** ======================================================= -+*/ -+ -+/* -+** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and -+** initial structure 'luaL_Stream' (it may contain other fields -+** after that initial structure). -+*/ -+ -+#define LUA_FILEHANDLE "FILE*" -+ -+ -+typedef struct luaL_Stream { -+ FILE *f; /* stream (NULL for incompletely created streams) */ -+ lua_CFunction closef; /* to close stream (NULL for closed streams) */ -+} luaL_Stream; -+ -+/* }====================================================== */ -+ -+ -+ -+ - /* - ** =============================================================== - ** some useful macros -@@ -144,6 +170,8 @@ - LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); - LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); - -+/* Luajittex needs this one because it overloads loadfile */ -+LUALIB_API int (RESERVED_load_aux_JIT) (lua_State *L, int status, int envarg); - - /* }====================================================== */ - -diff -bur LuaJIT-src-orig/src/lib_init.c LuaJIT-src/src/lib_init.c ---- LuaJIT-src-orig/src/lib_init.c 2016-03-07 09:43:42.720069718 +0100 -+++ LuaJIT-src/src/lib_init.c 2016-03-07 11:47:15.847946480 +0100 -@@ -26,6 +26,7 @@ - { LUA_DBLIBNAME, luaopen_debug }, - { LUA_BITLIBNAME, luaopen_bit }, - { LUA_JITLIBNAME, luaopen_jit }, -+ { LUA_BITLIBNAME_32, luaopen_bit32 }, - { NULL, NULL } - }; - -diff -bur LuaJIT-src-orig/src/lib_package.c LuaJIT-src/src/lib_package.c ---- LuaJIT-src-orig/src/lib_package.c 2016-03-07 09:43:42.712069718 +0100 -+++ LuaJIT-src/src/lib_package.c 2016-03-07 11:49:15.655944489 +0100 -@@ -362,6 +362,29 @@ - return 1; /* library loaded successfully */ - } - -+#define LUA_POF "luaopen_" -+#define LUA_OFSEP "_" -+#define POF LUA_POF -+ -+static const char *mkfuncname (lua_State *L, const char *modname) { -+ const char *funcname; -+ const char *mark = strchr(modname, *LUA_IGMARK); -+ if (mark) modname = mark + 1; -+ funcname = luaL_gsub(L, modname, ".", LUA_OFSEP); -+ funcname = lua_pushfstring(L, POF"%s", funcname); -+ lua_remove(L, -2); /* remove 'gsub' result */ -+ return funcname; -+} -+ -+ -+int loader_C_luatex (lua_State *L, const char *name, const char *filename) { -+ const char *funcname; -+ funcname = mkfuncname(L, name); -+ if (ll_loadfunc(L, filename, funcname,0) != 0) -+ loaderror(L, filename); -+ return 1; /* library loaded successfully */ -+} -+ - static int lj_cf_package_loader_croot(lua_State *L) - { - const char *filename; -@@ -381,6 +404,21 @@ - return 1; - } - -+int loader_Call_luatex (lua_State *L, const char *name, const char *filename) { -+ const char *funcname; -+ int stat; -+ if (filename == NULL) return 1; /* root not found */ -+ funcname = mkfuncname(L, name); -+ if ((stat = ll_loadfunc(L, filename, funcname,0)) != 0) { -+ if (stat != PACKAGE_ERR_FUNC) loaderror(L, filename); /* real error */ -+ lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS, -+ name, filename); -+ return 1; /* function not found */ -+ } -+ return 1; /* library loaded successfully */ -+} -+ -+ - static int lj_cf_package_loader_preload(lua_State *L) - { - const char *name = luaL_checkstring(L, 1); - -diff -bur LuaJIT-src-orig/src/lj_load.c LuaJIT-src/src/lj_load.c ---- LuaJIT-src-orig/src/lj_load.c 2016-03-07 09:43:42.716069718 +0100 -+++ LuaJIT-src/src/lj_load.c 2016-03-07 12:09:10.771924621 +0100 -@@ -166,3 +166,19 @@ - return 1; - } - -+/* -- Luajittex needs this one because it overloads loadfile -- */ -+LUALIB_API int RESERVED_load_aux_JIT(lua_State *L, int status, int envarg) -+{ -+ if (status == 0) { -+ if (tvistab(L->base+envarg-1)) { -+ GCfunc *fn = funcV(L->top-1); -+ GCtab *t = tabV(L->base+envarg-1); -+ setgcref(fn->c.env, obj2gco(t)); -+ lj_gc_objbarrier(L, fn, t); -+ } -+ return 1; -+ } else { -+ setnilV(L->top-2); -+ return 2; -+ } -+} - -diff -bur LuaJIT-src-orig/src/lua.h LuaJIT-src/src/lua.h ---- LuaJIT-src-orig/src/lua.h 2016-03-07 09:43:42.716069718 +0100 -+++ LuaJIT-src/src/lua.h 2016-03-07 11:56:24.855937353 +0100 -@@ -103,6 +103,9 @@ - typedef LUA_INTEGER lua_Integer; - - -+/* communication with LuaJiTTeX */ -+LUA_API int luajittex_choose_hash_function; -+ - - /* - ** state manipulation -@@ -349,6 +352,16 @@ - const char *chunkname, const char *mode); - - -+#define LUA_OPEQ 0 -+#define LUA_OPLT 1 -+#define LUA_OPLE 2 -+#define LUA_OK 0 -+ -+/* see http://comments.gmane.org/gmane.comp.programming.swig/18673 */ -+# define lua_rawlen lua_objlen -+ -+ -+ - struct lua_Debug { - int event; - const char *name; /* (n) */ - -diff -bur LuaJIT-src-orig/src/lualib.h LuaJIT-src/src/lualib.h ---- LuaJIT-src-orig/src/lualib.h 2016-03-07 09:43:42.724069718 +0100 -+++ LuaJIT-src/src/lualib.h 2016-03-07 11:58:19.151935453 +0100 -@@ -22,6 +22,8 @@ - #define LUA_JITLIBNAME "jit" - #define LUA_FFILIBNAME "ffi" - -+#define LUA_BITLIBNAME_32 "bit32" -+ - LUALIB_API int luaopen_base(lua_State *L); - LUALIB_API int luaopen_math(lua_State *L); - LUALIB_API int luaopen_string(lua_State *L); -@@ -34,6 +36,8 @@ - LUALIB_API int luaopen_jit(lua_State *L); - LUALIB_API int luaopen_ffi(lua_State *L); - -+LUALIB_API int luaopen_bit32(lua_State *L); -+ - LUALIB_API void luaL_openlibs(lua_State *L); - - #ifndef lua_assert - -diff -bur LuaJIT-src-orig/src/Makefile LuaJIT-src/src/Makefile ---- LuaJIT-src-orig/src/Makefile 2016-03-07 09:43:42.716069718 +0100 -+++ LuaJIT-src/src/Makefile 2016-03-07 12:02:42.319931078 +0100 -@@ -99,7 +99,7 @@ - # enabled by default. Some other features that *might* break some existing - # code (e.g. __pairs or os.execute() return values) can be enabled here. - # Note: this does not provide full compatibility with Lua 5.2 at this time. --#XCFLAGS+= -DLUAJIT_ENABLE_LUA52COMPAT -+XCFLAGS+= -DLUAJIT_ENABLE_LUA52COMPAT - # - # Disable the JIT compiler, i.e. turn LuaJIT into a pure interpreter. - #XCFLAGS+= -DLUAJIT_DISABLE_JIT -@@ -471,7 +471,7 @@ - LJVM_BOUT= $(LJVM_S) - LJVM_MODE= elfasm - --LJLIB_O= lib_base.o lib_math.o lib_bit.o lib_string.o lib_table.o \ -+LJLIB_O= lib_base.o lib_math.o lbitlib.o lib_bit.o lib_string.o lib_table.o \ - lib_io.o lib_os.o lib_package.o lib_debug.o lib_jit.o lib_ffi.o - LJLIB_C= $(LJLIB_O:.o=.c) - -diff -bur LuaJIT-src-orig/src/Makefile.dep LuaJIT-src/src/Makefile.dep ---- LuaJIT-src-orig/src/Makefile.dep 2016-03-07 09:43:42.696069718 +0100 -+++ LuaJIT-src/src/Makefile.dep 2016-03-07 12:05:19.343928468 +0100 -@@ -6,6 +6,7 @@ - lj_tab.h lj_meta.h lj_state.h lj_ctype.h lj_cconv.h lj_bc.h lj_ff.h \ - lj_ffdef.h lj_dispatch.h lj_jit.h lj_ir.h lj_char.h lj_strscan.h \ - lj_strfmt.h lj_lib.h lj_libdef.h -+lbitlib.o: lbitlib.c lua.h luaconf.h lauxlib.h lualib.h - lib_bit.o: lib_bit.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \ - lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_strscan.h \ - lj_strfmt.h lj_ctype.h lj_cdata.h lj_cconv.h lj_carith.h lj_ff.h \ diff --git a/Build/source/libs/luajit/TLpatches/patch-02 b/Build/source/libs/luajit/TLpatches/patch-02 new file mode 100644 index 00000000000..2f75f8b84f5 --- /dev/null +++ b/Build/source/libs/luajit/TLpatches/patch-02 @@ -0,0 +1,11 @@ +diff -bur LuaJIT-2.1.0-beta3-orig/src/Makefile.dep LuaJIT-2.1.0-beta3/src/Makefile.dep +--- LuaJIT-2.1.0-beta3-orig/src/Makefile.dep 2017-05-01 21:05:00.000000000 +0200 ++++ LuaJIT-2.1.0-beta3/src/Makefile.dep 2017-06-16 18:35:00.582631351 +0200 +@@ -6,6 +6,7 @@ + lj_tab.h lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_cconv.h \ + lj_ff.h lj_ffdef.h lj_dispatch.h lj_jit.h lj_ir.h lj_char.h lj_strscan.h \ + lj_strfmt.h lj_lib.h lj_libdef.h ++lbitlib.o: lbitlib.c lua.h luaconf.h lauxlib.h lualib.h + lib_bit.o: lib_bit.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \ + lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_strscan.h \ + lj_strfmt.h lj_ctype.h lj_cdata.h lj_cconv.h lj_carith.h lj_ff.h \ diff --git a/Build/source/libs/luajit/TLpatches/patch-03 b/Build/source/libs/luajit/TLpatches/patch-03 new file mode 100644 index 00000000000..0caddf8bfd4 --- /dev/null +++ b/Build/source/libs/luajit/TLpatches/patch-03 @@ -0,0 +1,12 @@ +diff -bur LuaJIT-2.1.0-beta3-orig/src/host/buildvm.c LuaJIT-2.1.0-beta3/src/host/buildvm.c +--- LuaJIT-2.1.0-beta3-orig/src/host/buildvm.c 2017-05-01 21:05:00.000000000 +0200 ++++ LuaJIT-2.1.0-beta3/src/host/buildvm.c 2017-06-16 18:56:14.538560987 +0200 +@@ -113,7 +113,7 @@ + name[0] = name[1] == 'R' ? '_' : '@'; /* Just for _RtlUnwind@16. */ + else + *p = '\0'; +-#elif LJ_TARGET_PPC && !LJ_TARGET_CONSOLE ++#elif LJ_TARGET_PPC && !LJ_TARGET_OSX && !LJ_TARGET_CONSOLE + /* Keep @plt etc. */ + #else + *p = '\0'; diff --git a/Build/source/libs/luajit/TLpatches/patch-04 b/Build/source/libs/luajit/TLpatches/patch-04 new file mode 100644 index 00000000000..83881026a1d --- /dev/null +++ b/Build/source/libs/luajit/TLpatches/patch-04 @@ -0,0 +1,44 @@ +diff -bur LuaJIT-2.1.0-beta3-orig/src/lauxlib.h LuaJIT-2.1.0-beta3/src/lauxlib.h +--- LuaJIT-2.1.0-beta3-orig/src/lauxlib.h 2017-05-01 21:05:00.000000000 +0200 ++++ LuaJIT-2.1.0-beta3/src/lauxlib.h 2017-06-16 19:12:18.325405265 +0200 +@@ -92,6 +92,31 @@ + LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname); + + ++ ++/* ++** {====================================================== ++** File handles for IO library ++** ======================================================= ++*/ ++ ++/* ++** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and ++** initial structure 'luaL_Stream' (it may contain other fields ++** after that initial structure). ++*/ ++ ++#define LUA_FILEHANDLE "FILE*" ++ ++ ++typedef struct luaL_Stream { ++ FILE *f; /* stream (NULL for incompletely created streams) */ ++ lua_CFunction closef; /* to close stream (NULL for closed streams) */ ++} luaL_Stream; ++ ++/* }====================================================== */ ++ ++ ++ + /* + ** =============================================================== + ** some useful macros +@@ -155,6 +180,8 @@ + LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); + LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); + ++/* Luajittex needs this one because it overloads loadfile */ ++LUALIB_API int (RESERVED_load_aux_JIT) (lua_State *L, int status, int envarg); + + /* }====================================================== */ + diff --git a/Build/source/libs/luajit/TLpatches/patch-05 b/Build/source/libs/luajit/TLpatches/patch-05 new file mode 100644 index 00000000000..6014f5597c1 --- /dev/null +++ b/Build/source/libs/luajit/TLpatches/patch-05 @@ -0,0 +1,11 @@ +diff -bur LuaJIT-2.1.0-beta3-orig/src/lib_init.c LuaJIT-2.1.0-beta3/src/lib_init.c +--- LuaJIT-2.1.0-beta3-orig/src/lib_init.c 2017-05-01 21:05:00.000000000 +0200 ++++ LuaJIT-2.1.0-beta3/src/lib_init.c 2017-06-16 19:19:00.352961298 +0200 +@@ -26,6 +26,7 @@ + { LUA_DBLIBNAME, luaopen_debug }, + { LUA_BITLIBNAME, luaopen_bit }, + { LUA_JITLIBNAME, luaopen_jit }, ++ { LUA_BITLIBNAME_32, luaopen_bit32 }, + { NULL, NULL } + }; + diff --git a/Build/source/libs/luajit/TLpatches/patch-06 b/Build/source/libs/luajit/TLpatches/patch-06 new file mode 100644 index 00000000000..8786dd4d621 --- /dev/null +++ b/Build/source/libs/luajit/TLpatches/patch-06 @@ -0,0 +1,53 @@ +diff -bur LuaJIT-2.1.0-beta3-orig/src/lib_package.c LuaJIT-2.1.0-beta3/src/lib_package.c +--- LuaJIT-2.1.0-beta3-orig/src/lib_package.c 2017-05-01 21:05:00.000000000 +0200 ++++ LuaJIT-2.1.0-beta3/src/lib_package.c 2017-06-19 16:54:20.092831408 +0200 +@@ -361,6 +361,28 @@ + return 1; /* library loaded successfully */ + } + ++#define LUA_POF "luaopen_" ++#define LUA_OFSEP "_" ++#define POF LUA_POF ++ ++static const char *mkfuncname (lua_State *L, const char *modname) { ++ const char *funcname; ++ const char *mark = strchr(modname, *LUA_IGMARK); ++ if (mark) modname = mark + 1; ++ funcname = luaL_gsub(L, modname, ".", LUA_OFSEP); ++ funcname = lua_pushfstring(L, POF"%s", funcname); ++ lua_remove(L, -2); /* remove 'gsub' result */ ++ return funcname; ++} ++ ++int loader_C_luatex (lua_State *L, const char *name, const char *filename) { ++ const char *funcname; ++ funcname = mkfuncname(L, name); ++ if (ll_loadfunc(L, filename, funcname,0) != 0) ++ loaderror(L, filename); ++ return 1; /* library loaded successfully */ ++} ++ + static int lj_cf_package_loader_croot(lua_State *L) + { + const char *filename; +@@ -380,6 +402,20 @@ + return 1; + } + ++int loader_Call_luatex (lua_State *L, const char *name, const char *filename) { ++ const char *funcname; ++ int stat; ++ if (filename == NULL) return 1; /* root not found */ ++ funcname = mkfuncname(L, name); ++ if ((stat = ll_loadfunc(L, filename, funcname,0)) != 0) { ++ if (stat != PACKAGE_ERR_FUNC) loaderror(L, filename); /* real error */ ++ lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS, ++ name, filename); ++ return 1; /* function not found */ ++ } ++ return 1; /* library loaded successfully */ ++} ++ + static int lj_cf_package_loader_preload(lua_State *L) + { + const char *name = luaL_checkstring(L, 1); diff --git a/Build/source/libs/luajit/TLpatches/patch-06-ppc-darwin b/Build/source/libs/luajit/TLpatches/patch-06-ppc-darwin deleted file mode 100644 index cc4855ea8de..00000000000 --- a/Build/source/libs/luajit/TLpatches/patch-06-ppc-darwin +++ /dev/null @@ -1,25 +0,0 @@ -diff -bur LuaJIT-src-orig/src/host/buildvm.c LuaJIT-src/src/host/buildvm.c ---- LuaJIT-src-orig/src/host/buildvm.c 2016-03-07 09:43:42.728069718 +0100 -+++ LuaJIT-src/src/host/buildvm.c 2016-03-07 12:29:03.891904786 +0100 -@@ -113,7 +113,7 @@ - name[0] = '@'; - else - *p = '\0'; --#elif LJ_TARGET_PPC && !LJ_TARGET_CONSOLE -+#elif LJ_TARGET_PPC && !LJ_TARGET_OSX && !LJ_TARGET_CONSOLE - /* Keep @plt etc. */ - #else - *p = '\0'; - -diff -bur LuaJIT-src-orig/src/lj_arch.h LuaJIT-src/src/lj_arch.h ---- LuaJIT-src-orig/src/lj_arch.h 2016-03-07 09:43:42.712069718 +0100 -+++ LuaJIT-src/src/lj_arch.h 2016-03-07 12:31:33.351902301 +0100 -@@ -350,7 +350,7 @@ - #if __GNUC__ < 4 - #error "Need at least GCC 4.0 or newer" - #endif --#elif LJ_TARGET_ARM -+#elif LJ_TARGET_ARM || LJ_TARGET_PPC - #if (__GNUC__ < 4) || ((__GNUC__ == 4) && __GNUC_MINOR__ < 2) - #error "Need at least GCC 4.2 or newer" - #endif diff --git a/Build/source/libs/luajit/TLpatches/patch-07 b/Build/source/libs/luajit/TLpatches/patch-07 new file mode 100644 index 00000000000..f37d1ded06d --- /dev/null +++ b/Build/source/libs/luajit/TLpatches/patch-07 @@ -0,0 +1,12 @@ +diff -bur LuaJIT-2.1.0-beta3-orig/src/lj_arch.h LuaJIT-2.1.0-beta3/src/lj_arch.h +--- LuaJIT-2.1.0-beta3-orig/src/lj_arch.h 2017-05-01 21:05:00.000000000 +0200 ++++ LuaJIT-2.1.0-beta3/src/lj_arch.h 2017-06-19 17:51:41.683624004 +0200 +@@ -376,7 +376,7 @@ + #if __GNUC__ < 4 + #error "Need at least GCC 4.0 or newer" + #endif +-#elif LJ_TARGET_ARM ++#elif LJ_TARGET_ARM || LJ_TARGET_PPC + #if (__GNUC__ < 4) || ((__GNUC__ == 4) && __GNUC_MINOR__ < 2) + #error "Need at least GCC 4.2 or newer" + #endif diff --git a/Build/source/libs/luajit/TLpatches/patch-07-x86_64-cygwin b/Build/source/libs/luajit/TLpatches/patch-07-x86_64-cygwin deleted file mode 100644 index 4b278dd2c99..00000000000 --- a/Build/source/libs/luajit/TLpatches/patch-07-x86_64-cygwin +++ /dev/null @@ -1,12 +0,0 @@ -diff -bur LuaJIT-src-orig/src/lj_arch.h LuaJIT-src/src/lj_arch.h ---- LuaJIT-src-orig/src/lj_arch.h 2016-03-07 09:43:42.712069718 +0100 -+++ LuaJIT-src/src/lj_arch.h 2016-03-07 12:31:33.351902301 +0100 -@@ -350,7 +350,7 @@ - #if __GNUC__ < 4 - #error "Need at least GCC 4.0 or newer" - #endif --#elif LJ_TARGET_ARM -+#elif LJ_TARGET_ARM || LJ_TARGET_PPC - #if (__GNUC__ < 4) || ((__GNUC__ == 4) && __GNUC_MINOR__ < 2) - #error "Need at least GCC 4.2 or newer" - #endif diff --git a/Build/source/libs/luajit/TLpatches/patch-08 b/Build/source/libs/luajit/TLpatches/patch-08 new file mode 100644 index 00000000000..80a214fb39d --- /dev/null +++ b/Build/source/libs/luajit/TLpatches/patch-08 @@ -0,0 +1,12 @@ +diff -bur LuaJIT-2.1.0-beta3-orig/src/lj_def.h LuaJIT-2.1.0-beta3/src/lj_def.h +--- LuaJIT-2.1.0-beta3-orig/src/lj_def.h 2017-05-01 21:05:00.000000000 +0200 ++++ LuaJIT-2.1.0-beta3/src/lj_def.h 2017-06-19 17:52:54.085933629 +0200 +@@ -66,7 +66,7 @@ + #define LJ_MAX_BCINS (1<<26) /* Max. # of bytecode instructions. */ + #define LJ_MAX_SLOTS 250 /* Max. # of slots in a Lua func. */ + #define LJ_MAX_LOCVAR 200 /* Max. # of local variables. */ +-#define LJ_MAX_UPVAL 60 /* Max. # of upvalues. */ ++#define LJ_MAX_UPVAL 249 /* Max. # of upvalues. */ + + #define LJ_MAX_IDXCHAIN 100 /* __index/__newindex chain limit. */ + #define LJ_STACK_EXTRA (5+2*LJ_FR2) /* Extra stack space (metamethods). */ diff --git a/Build/source/libs/luajit/TLpatches/patch-09 b/Build/source/libs/luajit/TLpatches/patch-09 new file mode 100644 index 00000000000..312031f36f2 --- /dev/null +++ b/Build/source/libs/luajit/TLpatches/patch-09 @@ -0,0 +1,26 @@ +diff -bur LuaJIT-2.1.0-beta3-orig/src/lj_load.c LuaJIT-2.1.0-beta3/src/lj_load.c +--- LuaJIT-2.1.0-beta3-orig/src/lj_load.c 2017-05-01 21:05:00.000000000 +0200 ++++ LuaJIT-2.1.0-beta3/src/lj_load.c 2017-06-19 18:05:35.864190001 +0200 +@@ -166,3 +166,22 @@ + return 1; + } + ++ ++ ++/* -- Luajittex needs this one because it overloads loadfile -- */ ++LUALIB_API int RESERVED_load_aux_JIT(lua_State *L, int status, int envarg) ++{ ++ if (status == 0) { ++ if (tvistab(L->base+envarg-1)) { ++ GCfunc *fn = funcV(L->top-1); ++ GCtab *t = tabV(L->base+envarg-1); ++ setgcref(fn->c.env, obj2gco(t)); ++ lj_gc_objbarrier(L, fn, t); ++ } ++ return 1; ++ } else { ++ setnilV(L->top-2); ++ return 2; ++ } ++} ++ diff --git a/Build/source/libs/luajit/TLpatches/patch-05-LuaJITTeX b/Build/source/libs/luajit/TLpatches/patch-10 index 884d3392bf7..840f154b1dd 100644 --- a/Build/source/libs/luajit/TLpatches/patch-05-LuaJITTeX +++ b/Build/source/libs/luajit/TLpatches/patch-10 @@ -1,19 +1,6 @@ -diff -bur LuaJIT-src-orig/src/lj_def.h LuaJIT-src/src/lj_def.h ---- LuaJIT-src-orig/src/lj_def.h 2016-03-07 09:43:42.728069718 +0100 -+++ LuaJIT-src/src/lj_def.h 2016-03-07 12:23:43.327910115 +0100 -@@ -66,7 +66,7 @@ - #define LJ_MAX_BCINS (1<<26) /* Max. # of bytecode instructions. */ - #define LJ_MAX_SLOTS 250 /* Max. # of slots in a Lua func. */ - #define LJ_MAX_LOCVAR 200 /* Max. # of local variables. */ --#define LJ_MAX_UPVAL 60 /* Max. # of upvalues. */ -+#define LJ_MAX_UPVAL 249 /* Max. # of upvalues. */ - - #define LJ_MAX_IDXCHAIN 100 /* __index/__newindex chain limit. */ - #define LJ_STACK_EXTRA (5+2*LJ_FR2) /* Extra stack space (metamethods). */ - -diff -bur LuaJIT-src-orig/src/lj_str.c LuaJIT-src/src/lj_str.c ---- LuaJIT-src-orig/src/lj_str.c 2016-03-07 09:43:42.696069718 +0100 -+++ LuaJIT-src/src/lj_str.c 2016-03-07 12:25:22.031908474 +0100 +diff -bur LuaJIT-2.1.0-beta3-orig/src/lj_str.c LuaJIT-2.1.0-beta3/src/lj_str.c +--- LuaJIT-2.1.0-beta3-orig/src/lj_str.c 2017-05-01 21:05:00.000000000 +0200 ++++ LuaJIT-2.1.0-beta3/src/lj_str.c 2017-06-19 18:20:09.668443066 +0200 @@ -118,6 +118,16 @@ g->strhash = newhash; } @@ -70,17 +57,3 @@ diff -bur LuaJIT-src-orig/src/lj_str.c LuaJIT-src/src/lj_str.c /* Check if the string has already been interned. */ o = gcref(g->strhash[h & g->strmask]); if (LJ_LIKELY((((uintptr_t)str+len-1) & (LJ_PAGESIZE-1)) <= LJ_PAGESIZE-4)) { - -diff -bur LuaJIT-src-orig/src/lj_err.c LuaJIT-src/src/lj_err.c ---- LuaJIT-src-orig/src/lj_err.c 2016-03-15 12:06:56.844436191 +0100 -+++ LuaJIT-src/src/lj_err.c 2016-03-15 11:58:30.000000000 +0100 -@@ -310,7 +310,6 @@ - #define _US_FORCE_UNWIND 8 - - typedef struct _Unwind_Control_Block _Unwind_Control_Block; --typedef struct _Unwind_Context _Unwind_Context; - - struct _Unwind_Control_Block { - uint64_t exclass; - - diff --git a/Build/source/libs/luajit/TLpatches/patch-11 b/Build/source/libs/luajit/TLpatches/patch-11 new file mode 100644 index 00000000000..b4b187813fc --- /dev/null +++ b/Build/source/libs/luajit/TLpatches/patch-11 @@ -0,0 +1,28 @@ +diff -bur LuaJIT-2.1.0-beta3-orig/src/lua.h LuaJIT-2.1.0-beta3/src/lua.h +--- LuaJIT-2.1.0-beta3-orig/src/lua.h 2017-05-01 21:05:00.000000000 +0200 ++++ LuaJIT-2.1.0-beta3/src/lua.h 2017-06-19 18:26:51.143299683 +0200 +@@ -103,7 +103,8 @@ + /* type for integer functions */ + typedef LUA_INTEGER lua_Integer; + +- ++/* communication with LuaJiTTeX */ ++LUA_API int luajittex_choose_hash_function; + + /* + ** state manipulation +@@ -353,6 +354,14 @@ + LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *isnum); + LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *isnum); + ++ ++#define LUA_OPEQ 0 ++#define LUA_OPLT 1 ++#define LUA_OPLE 2 ++ ++/* see http://comments.gmane.org/gmane.comp.programming.swig/18673 */ ++# define lua_rawlen lua_objlen ++ + /* From Lua 5.3. */ + LUA_API int lua_isyieldable (lua_State *L); + diff --git a/Build/source/libs/luajit/TLpatches/patch-12 b/Build/source/libs/luajit/TLpatches/patch-12 new file mode 100644 index 00000000000..27be2c8cdaa --- /dev/null +++ b/Build/source/libs/luajit/TLpatches/patch-12 @@ -0,0 +1,21 @@ +diff -bur LuaJIT-2.1.0-beta3-orig/src/lualib.h LuaJIT-2.1.0-beta3/src/lualib.h +--- LuaJIT-2.1.0-beta3-orig/src/lualib.h 2017-05-01 21:05:00.000000000 +0200 ++++ LuaJIT-2.1.0-beta3/src/lualib.h 2017-06-19 18:27:55.065836605 +0200 +@@ -22,6 +22,8 @@ + #define LUA_JITLIBNAME "jit" + #define LUA_FFILIBNAME "ffi" + ++#define LUA_BITLIBNAME_32 "bit32" ++ + LUALIB_API int luaopen_base(lua_State *L); + LUALIB_API int luaopen_math(lua_State *L); + LUALIB_API int luaopen_string(lua_State *L); +@@ -34,6 +36,8 @@ + LUALIB_API int luaopen_jit(lua_State *L); + LUALIB_API int luaopen_ffi(lua_State *L); + ++LUALIB_API int luaopen_bit32(lua_State *L); ++ + LUALIB_API void luaL_openlibs(lua_State *L); + + #ifndef lua_assert diff --git a/Build/source/libs/luajit/aclocal.m4 b/Build/source/libs/luajit/aclocal.m4 index 6997c961d3e..b01b5a7535f 100644 --- a/Build/source/libs/luajit/aclocal.m4 +++ b/Build/source/libs/luajit/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.15.1 -*- Autoconf -*- +# generated automatically by aclocal 1.15 -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -20,7 +20,7 @@ You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) -# Copyright (C) 2002-2017 Free Software Foundation, Inc. +# Copyright (C) 2002-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -35,7 +35,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.15' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.15.1], [], +m4_if([$1], [1.15], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -51,14 +51,14 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.15.1])dnl +[AM_AUTOMAKE_VERSION([1.15])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # Figure out how to run the assembler. -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -78,7 +78,7 @@ _AM_IF_OPTION([no-dependencies],, [_AM_DEPENDENCIES([CCAS])])dnl # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -130,7 +130,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd` # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2017 Free Software Foundation, Inc. +# Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -161,7 +161,7 @@ AC_CONFIG_COMMANDS_PRE( Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -352,7 +352,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -428,7 +428,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -625,7 +625,7 @@ for _am_header in $config_headers :; do done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -646,7 +646,7 @@ if test x"${install_sh+set}" != xset; then fi AC_SUBST([install_sh])]) -# Copyright (C) 2003-2017 Free Software Foundation, Inc. +# Copyright (C) 2003-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -668,7 +668,7 @@ AC_SUBST([am__leading_dot])]) # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -703,7 +703,7 @@ AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -753,7 +753,7 @@ rm -f confinc confmf # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2017 Free Software Foundation, Inc. +# Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -792,7 +792,7 @@ fi # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -821,7 +821,7 @@ AC_DEFUN([_AM_SET_OPTIONS], AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -868,7 +868,7 @@ AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -887,7 +887,7 @@ AC_DEFUN([AM_RUN_LOG], # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -968,7 +968,7 @@ AC_CONFIG_COMMANDS_PRE( rm -f conftest.file ]) -# Copyright (C) 2009-2017 Free Software Foundation, Inc. +# Copyright (C) 2009-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1028,7 +1028,7 @@ AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1056,7 +1056,7 @@ fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2017 Free Software Foundation, Inc. +# Copyright (C) 2006-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1075,7 +1075,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2017 Free Software Foundation, Inc. +# Copyright (C) 2004-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/Build/source/libs/luajit/configure b/Build/source/libs/luajit/configure index 90b89f2aa3f..9afdd329857 100755 --- a/Build/source/libs/luajit/configure +++ b/Build/source/libs/luajit/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for luajit for TeX Live 2.1.0-beta2. +# Generated by GNU Autoconf 2.69 for luajit for TeX Live 2.1.0-beta3. # # Report bugs to <tex-k@tug.org>. # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='luajit for TeX Live' PACKAGE_TARNAME='luajit-for-tex-live' -PACKAGE_VERSION='2.1.0-beta2' -PACKAGE_STRING='luajit for TeX Live 2.1.0-beta2' +PACKAGE_VERSION='2.1.0-beta3' +PACKAGE_STRING='luajit for TeX Live 2.1.0-beta3' PACKAGE_BUGREPORT='tex-k@tug.org' PACKAGE_URL='' @@ -758,6 +758,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -844,6 +845,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1096,6 +1098,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1233,7 +1244,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1346,7 +1357,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures luajit for TeX Live 2.1.0-beta2 to adapt to many kinds of systems. +\`configure' configures luajit for TeX Live 2.1.0-beta3 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1386,6 +1397,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -1417,7 +1429,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of luajit for TeX Live 2.1.0-beta2:";; + short | recursive ) echo "Configuration of luajit for TeX Live 2.1.0-beta3:";; esac cat <<\_ACEOF @@ -1536,7 +1548,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -luajit for TeX Live configure 2.1.0-beta2 +luajit for TeX Live configure 2.1.0-beta3 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2043,7 +2055,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by luajit for TeX Live $as_me 2.1.0-beta2, which was +It was created by luajit for TeX Live $as_me 2.1.0-beta3, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3966,7 +3978,7 @@ fi # Define the identity of the package. PACKAGE='luajit-for-tex-live' - VERSION='2.1.0-beta2' + VERSION='2.1.0-beta3' cat >>confdefs.h <<_ACEOF @@ -5384,7 +5396,7 @@ $as_echo "no, using $LN_S" >&6; } fi -LUAJITVERSION=2.1.0-beta2 +LUAJITVERSION=2.1.0-beta3 LUAJIT_LT_VERSINFO=3:0:1 @@ -13902,7 +13914,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -13948,7 +13960,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -13972,7 +13984,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -14017,7 +14029,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -14041,7 +14053,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -14973,7 +14985,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by luajit for TeX Live $as_me 2.1.0-beta2, which was +This file was extended by luajit for TeX Live $as_me 2.1.0-beta3, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -15039,7 +15051,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -luajit for TeX Live config.status 2.1.0-beta2 +luajit for TeX Live config.status 2.1.0-beta3 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/Build/source/libs/luajit/include/Makefile.in b/Build/source/libs/luajit/include/Makefile.in index c24a2577e76..fcbc7068b13 100644 --- a/Build/source/libs/luajit/include/Makefile.in +++ b/Build/source/libs/luajit/include/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -257,6 +257,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ diff --git a/Build/source/libs/luajit/native/Makefile.in b/Build/source/libs/luajit/native/Makefile.in index a679467240a..a390a3f53c7 100644 --- a/Build/source/libs/luajit/native/Makefile.in +++ b/Build/source/libs/luajit/native/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -303,6 +303,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -612,7 +613,7 @@ distdir: $(DISTFILES) ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir @@ -638,7 +639,7 @@ dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir @@ -656,7 +657,7 @@ dist dist-all: distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ - eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ @@ -666,7 +667,7 @@ distcheck: dist *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ - eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac diff --git a/Build/source/libs/luajit/native/aclocal.m4 b/Build/source/libs/luajit/native/aclocal.m4 index f78e58987bb..f8f53e2fae8 100644 --- a/Build/source/libs/luajit/native/aclocal.m4 +++ b/Build/source/libs/luajit/native/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.15.1 -*- Autoconf -*- +# generated automatically by aclocal 1.15 -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -20,7 +20,7 @@ You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) -# Copyright (C) 2002-2017 Free Software Foundation, Inc. +# Copyright (C) 2002-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -35,7 +35,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.15' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.15.1], [], +m4_if([$1], [1.15], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -51,14 +51,14 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.15.1])dnl +[AM_AUTOMAKE_VERSION([1.15])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -110,7 +110,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd` # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2017 Free Software Foundation, Inc. +# Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -141,7 +141,7 @@ AC_CONFIG_COMMANDS_PRE( Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -332,7 +332,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -408,7 +408,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -605,7 +605,7 @@ for _am_header in $config_headers :; do done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -626,7 +626,7 @@ if test x"${install_sh+set}" != xset; then fi AC_SUBST([install_sh])]) -# Copyright (C) 2003-2017 Free Software Foundation, Inc. +# Copyright (C) 2003-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -648,7 +648,7 @@ AC_SUBST([am__leading_dot])]) # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -683,7 +683,7 @@ AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -733,7 +733,7 @@ rm -f confinc confmf # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2017 Free Software Foundation, Inc. +# Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -772,7 +772,7 @@ fi # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -801,7 +801,7 @@ AC_DEFUN([_AM_SET_OPTIONS], AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -848,7 +848,7 @@ AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -867,7 +867,7 @@ AC_DEFUN([AM_RUN_LOG], # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -948,7 +948,7 @@ AC_CONFIG_COMMANDS_PRE( rm -f conftest.file ]) -# Copyright (C) 2009-2017 Free Software Foundation, Inc. +# Copyright (C) 2009-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1008,7 +1008,7 @@ AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1036,7 +1036,7 @@ fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2017 Free Software Foundation, Inc. +# Copyright (C) 2006-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1055,7 +1055,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2017 Free Software Foundation, Inc. +# Copyright (C) 2004-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/Build/source/libs/luajit/native/configure b/Build/source/libs/luajit/native/configure index 2b9fc667715..1ff833398bd 100755 --- a/Build/source/libs/luajit/native/configure +++ b/Build/source/libs/luajit/native/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for luajit native 2.1.0-beta2. +# Generated by GNU Autoconf 2.69 for luajit native 2.1.0-beta3. # # Report bugs to <tex-k@tug.org>. # @@ -580,8 +580,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='luajit native' PACKAGE_TARNAME='luajit-native' -PACKAGE_VERSION='2.1.0-beta2' -PACKAGE_STRING='luajit native 2.1.0-beta2' +PACKAGE_VERSION='2.1.0-beta3' +PACKAGE_STRING='luajit native 2.1.0-beta3' PACKAGE_BUGREPORT='tex-k@tug.org' PACKAGE_URL='' @@ -710,6 +710,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -784,6 +785,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1036,6 +1038,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1173,7 +1184,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1286,7 +1297,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures luajit native 2.1.0-beta2 to adapt to many kinds of systems. +\`configure' configures luajit native 2.1.0-beta3 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1326,6 +1337,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -1356,7 +1368,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of luajit native 2.1.0-beta2:";; + short | recursive ) echo "Configuration of luajit native 2.1.0-beta3:";; esac cat <<\_ACEOF @@ -1453,7 +1465,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -luajit native configure 2.1.0-beta2 +luajit native configure 2.1.0-beta3 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1847,7 +1859,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by luajit native $as_me 2.1.0-beta2, which was +It was created by luajit native $as_me 2.1.0-beta3, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3770,7 +3782,7 @@ fi # Define the identity of the package. PACKAGE='luajit-native' - VERSION='2.1.0-beta2' + VERSION='2.1.0-beta3' cat >>confdefs.h <<_ACEOF @@ -5851,7 +5863,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by luajit native $as_me 2.1.0-beta2, which was +This file was extended by luajit native $as_me 2.1.0-beta3, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -5917,7 +5929,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -luajit native config.status 2.1.0-beta2 +luajit native config.status 2.1.0-beta3 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/Build/source/libs/luajit/version.ac b/Build/source/libs/luajit/version.ac index 3ea364f8924..4c6b5b3b67c 100644 --- a/Build/source/libs/luajit/version.ac +++ b/Build/source/libs/luajit/version.ac @@ -8,4 +8,4 @@ dnl dnl -------------------------------------------------------- dnl dnl m4-include this file to define the current luajit version -m4_define([luajit_version], [2.1.0-beta2]) +m4_define([luajit_version], [2.1.0-beta3]) diff --git a/Build/source/texk/web2c/luatexdir/ChangeLog b/Build/source/texk/web2c/luatexdir/ChangeLog index 24f4d69dff5..89c26f5ce1e 100644 --- a/Build/source/texk/web2c/luatexdir/ChangeLog +++ b/Build/source/texk/web2c/luatexdir/ChangeLog @@ -1,24 +1,65 @@ -2017-09-18 Akira Kakuto <kakuto@fuk.kindai.ac.jp> +2017-10-03 Luigi Scarso <luigi.scarso@gmail.com> + A not exhaustive list of changes: - * luatex.c : Import comment from the upstream. + * luaffi/: Fix to compile with gcc 7.1, + patch for callbacks. + * lpeg/: version 1.0.1 + + * luatex.c: We conform to the way Web2c does handle trailing tabs and spaces. This + decade old behaviour was changed in September 2017 and can introduce + compatibility issues in existing workflows. Because we don't want too + many differences with upstream TeXlive we just follow up on that patch + and it's up to macro packages to deal with possible issues (which can be + done via the usual callbacks. One can wonder why we then still prune + spaces but we leave that to the reader. + + * option to set exit code (status.setexitcode) (HH). Changed paths: + luatexdir/tex/errors.h, luatexdir/tex/errors.w + + * missing_glyph callback (HH). Changed paths: + luatexdir/font/texfont.h, luatexdir/font/texfont.w,luatexdir/lua/lcallbacklib.c + luatexdir/luatexcallbackids.h, luatexdir/pdf/pdffont.w, luatexdir/pdf/pdfglyph.w; + + * \mathdelimitersmode (see manual) (HH). Changed paths: + luatexdir/tex/mlist.w, luatexdir/tex/texnodes.h + + * fixes in protect/unprotect and list support in set/getglue (HH). Changed paths: + luatexdir/lua/lnodelib.c + + * 'class' string in pdf vf command optional (HH). Changed paths: + luatexdir/font/luafont.w + + * cleanup expansion (HH). Changed paths: + luatexdir/font/luafont.w, luatexdir/font/texfont.h, luatexdir/font/texfont.w + luatexdir/lua/lfontlib.c, luatexdir/lua/luatex-api.h, luatexdir/tex/dumpdata.w + + * possibly better fix for extended font embedding (HH). Changed paths: + luatexdir/font/writefont.w + + * protect_glyphs accepts range and also made consistent with manual (HH). Changed path: + luatexdir/lua/lnodelib.c + + * some more control over syntex fields (HH). Changed paths: + luatexdir/tex/texnodes.w + + * fix for neg display skips (HH). Changed paths: + luatexdir/tex/texmath.w + + * \breakafterdirmode (value 1 will honor glue breaks after a dir node) (HH). Changed paths: + luatexdir/tex/commands.w, luatexdir/tex/dumpdata.w, luatexdir/tex/equivalents.h, + luatexdir/tex/linebreak.w, luatexdir/tex/texnodes.h + + * fix width array of extended font (shared with normal)(HH). Changed paths: + luatexdir/font/writefont.w -2017-09-05 Karl Berry <karl@tug.org> - and Akira Kakuto <kakuto@fuk.kindai.ac.jp> - * luatex.c (IS_SPC_OR_EOL): new macro. - (topenin): use it, instead of ISBLANK. - (input_line): remove only trailing space characters - instead of using ISBLANK. - See also analogous change in lib/texmfmp.c. - Original bug report from Evan Aad, - http://tug.org/pipermail/tex-k/2017-August/002801.html. - Fix a bug to skip BOM (w32 only). 2017-02-07 Luigi Scarso <luigi.scarso@gmail.com> * luaffi/: First attempt to implement the ffi module in lua compatible with the ffi module of luajit. + 2015-11-01 Akira Kakuto <kakuto@fuk.kindai.ac.jp> * luatex.c: Improve a little (w32 only). @@ -529,11 +570,11 @@ * lua/lepdflib.cc: No need to test for Annot::decRefCnt with poppler 0.18 or better. -2012-11-06 Akira Kakuto <kakuto@fuk.kindai.ac.jp> +2012-11-06 Akira Kakuto <kakuto@fuk.kinidai.ac.jp> * pdf/pdflistout.w: sync with r4471 (a bug fix by H. Henkel). -2012-10-13 Akira Kakuto <kakuto@fuk.kindai.ac.jp> +2012-10-13 Akira Kakuto <kakuto@fuk.kinidai.ac.jp> * tex/texfileio.w: input by pipe was impossible. enable it. @@ -541,7 +582,7 @@ * lua/luainit.w (lua_initialize): Free two malloc()ed strings. -2012-10-10 Akira Kakuto <kakuto@fuk.kindai.ac.jp> +2012-10-10 Akira Kakuto <kakuto@fuk.kinidai.ac.jp> * luatex.c: Modify determination of fullpath for restricted shell escape commands. @@ -567,7 +608,7 @@ * lua/luainit.w (parse_options): Avoid cast const => non-const. -2012-09-13 Akira Kakuto <kakuto@fuk.kindai.ac.jp> +2012-09-13 Akira Kakuto <kakuto@fuk.kinidai.ac.jp> * lua/luainit.w (parse_options): allow lualatex "\input" "a b" on Windows. @@ -577,7 +618,7 @@ * luatex-api.h: Avoid conflicting extern declaration of environ, declared in <stdlib.h> for WIN32 (from W32TeX). -2012-08-21 Akira Kakuto <kakuto@fuk.kindai.ac.jp> +2012-08-21 Akira Kakuto <kakuto@fuk.kinidai.ac.jp> * tex/texdeffont.w (tex_def_font): Recover the old code, because the new code seems not to work. diff --git a/Build/source/texk/web2c/luatexdir/am/luatex.am b/Build/source/texk/web2c/luatexdir/am/luatex.am index 2436d8891d4..41b8610a251 100644 --- a/Build/source/texk/web2c/luatexdir/am/luatex.am +++ b/Build/source/texk/web2c/luatexdir/am/luatex.am @@ -72,8 +72,7 @@ luatex_sources = \ mplibdir/lmplib.c EXTRA_DIST += \ - $(luatex_sources) \ - luatexdir/getluatexsvnversion.sh + $(luatex_sources) call_luatex_CPPFLAGS = -DEXEPROG=\"luatex.exe\" nodist_call_luatex_SOURCES = callexe.c diff --git a/Build/source/texk/web2c/luatexdir/font/luafont.w b/Build/source/texk/web2c/luatexdir/font/luafont.w index 4e874d9becb..7065f96d904 100644 --- a/Build/source/texk/web2c/luatexdir/font/luafont.w +++ b/Build/source/texk/web2c/luatexdir/font/luafont.w @@ -461,9 +461,6 @@ int font_to_lua(lua_State * L, int f) if (font_step(f) != 0) { dump_intfield(L,step,font_step(f)); } - if (font_auto_expand(f) != 0) { - dump_booleanfield(L,auto_expand,font_auto_expand(f)); - } if (pdf_font_attr(f) != 0) { char *s = makecstring(pdf_font_attr(f)); dump_stringfield(L,attributes,s); @@ -623,6 +620,7 @@ static int n_some_field(lua_State * L, int name_index) static int count_char_packet_bytes(lua_State * L) { register int i; + register int ts; register int l = 0; int ff = 0; for (i = 1; i <= (int) lua_rawlen(L, -1); i++) { @@ -642,39 +640,57 @@ static int count_char_packet_bytes(lua_State * L) ff = 1; } else if (lua_key_eq(s, slot)) { l += 10; - ff = 1; } else if (lua_key_eq(s, comment) || lua_key_eq(s, nop)) { ; } else if (lua_key_eq(s, push) || lua_key_eq(s, pop)) { l++; } else if (lua_key_eq(s, rule)) { l += 9; - } else if (lua_key_eq(s, right) || lua_key_eq(s, node) - || lua_key_eq(s, down) || lua_key_eq(s, image)) { + } else if (lua_key_eq(s, right) || lua_key_eq(s, node) || lua_key_eq(s, down) || lua_key_eq(s, image)) { l += 5; } else if (lua_key_eq(s, scale)) { l += sizeof(float) + 1; + } else if (lua_key_eq(s, pdf)) { + size_t len; + l += 5; + ts = lua_rawlen(L, -2); + lua_rawgeti(L, -2, 2); + if (ts == 3) { + if (lua_type(L,-1) == LUA_TSTRING) { + /* no need to do something */ + } else if (lua_type(L,-1) == LUA_TNUMBER) { + /* no need to do something */ + } else { + normal_error("vf command","invalid packet pdf literal category"); + } + lua_rawgeti(L, -3, 3); + } + if (lua_type(L,-1) == LUA_TSTRING) { + (void) lua_tolstring(L, -1, &len); + if (len > 0) { + l = (int) (l + 5 + (int) len); + } + } else { + normal_error("vf command","invalid packet pdf literal"); + } + lua_pop(L, ts == 3 ? 2 : 1); } else if (lua_key_eq(s, special) || lua_key_eq(s, lua)) { size_t len; lua_rawgeti(L, -2, 2); if (lua_type(L,-1) == LUA_TSTRING) { (void) lua_tolstring(L, -1, &len); - lua_pop(L, 1); if (len > 0) { l = (int) (l + 5 + (int) len); } } else { - lua_pop(L, 1); normal_error("vf command","invalid packet special"); - /* fprintf(stdout, "invalid packet special!\n"); */ } + lua_pop(L, 1); } else { normal_error("vf command","unknown packet command"); - /* fprintf(stdout, "unknown packet command %s!\n", s); */ } } else { normal_error("vf command","no packet command"); - /* fprintf(stdout, "no packet command!\n"); */ } lua_pop(L, 1); /* command name */ } @@ -700,6 +716,8 @@ static void read_char_packets(lua_State * L, int *l_fonts, charinfo * co, intern const char *s; eight_bits *cpackets, *cp; int ff = 0; + int sf = 0; + int ts = 0; int max_f = 0; int pc = count_char_packet_bytes(L); if (pc <= 0) @@ -725,19 +743,20 @@ static void read_char_packets(lua_State * L, int *l_fonts, charinfo * co, intern do_store_four(ff); } } else if (lua_key_eq(s, slot)) { + /* we could be sparse but no real reason */ cmd = packet_nop_code; lua_rawgeti(L, -2, 2); - n = (int) luaL_checkinteger(L, -1); - if (n ==0) { - ff = f; + n = (int) lua_roundnumber(L, -1); + if (n == 0) { + sf = f; } else { - ff = (n > max_f ? l_fonts[1] : l_fonts[n]); + sf = (n > max_f ? l_fonts[1] : l_fonts[n]); } lua_rawgeti(L, -3, 3); - n = (int) luaL_checkinteger(L, -1); + n = (int) lua_roundnumber(L, -1); lua_pop(L, 2); append_packet(packet_font_code); - do_store_four(ff); + do_store_four(sf); append_packet(packet_char_code); do_store_four(n); } else if (lua_key_eq(s, comment) || lua_key_eq(s, nop)) { @@ -754,6 +773,8 @@ static void read_char_packets(lua_State * L, int *l_fonts, charinfo * co, intern cmd = packet_right_code; } else if (lua_key_eq(s, down)) { cmd = packet_down_code; + } else if (lua_key_eq(s, pdf)) { + cmd = packet_pdf_code; } else if (lua_key_eq(s, special)) { cmd = packet_special_code; } else if (lua_key_eq(s, image)) { @@ -771,7 +792,7 @@ static void read_char_packets(lua_State * L, int *l_fonts, charinfo * co, intern case packet_font_code: append_packet(cmd); lua_rawgeti(L, -2, 2); - n = (int) luaL_checkinteger(L, -1); + n = (int) lua_roundnumber(L, -1); if (n == 0) { ff = n; } else { @@ -790,7 +811,7 @@ static void read_char_packets(lua_State * L, int *l_fonts, charinfo * co, intern case packet_char_code: append_packet(cmd); lua_rawgeti(L, -2, 2); - n = (int) luaL_checkinteger(L, -1); + n = (int) lua_roundnumber(L, -1); do_store_four(n); lua_pop(L, 1); break; @@ -798,20 +819,62 @@ static void read_char_packets(lua_State * L, int *l_fonts, charinfo * co, intern case packet_down_code: append_packet(cmd); lua_rawgeti(L, -2, 2); - n = (int) luaL_checkinteger(L, -1); + n = (int) lua_roundnumber(L, -1); do_store_four(sp_to_dvi(n, atsize)); lua_pop(L, 1); break; case packet_rule_code: append_packet(cmd); lua_rawgeti(L, -2, 2); - n = (int) luaL_checkinteger(L, -1); + n = (int) lua_roundnumber(L, -1); do_store_four(sp_to_dvi(n, atsize)); lua_rawgeti(L, -3, 3); - n = (int) luaL_checkinteger(L, -1); + n = (int) lua_roundnumber(L, -1); do_store_four(sp_to_dvi(n, atsize)); lua_pop(L, 2); break; + case packet_pdf_code: + append_packet(cmd); + ts = (int) lua_rawlen(L, -2); + lua_rawgeti(L, -2, 2); + if (ts == 3) { + if (lua_type(L, -1) == LUA_TSTRING) { + s = lua_tostring(L, -1); + if (lua_key_eq(s, direct)) { + n = direct_always; + } else if (lua_key_eq(s, page)) { + n = direct_page; + } else if (lua_key_eq(s, raw)) { + n = direct_raw; + } else if (lua_key_eq(s, origin)) { + n = set_origin; + } else { + /* normal_warning("vf command","invalid pdf literal type"); */ + n = set_origin ; + } + } else { + n = (int) lua_roundnumber(L, -1); + if (n < set_origin || n > direct_raw) { + n = set_origin ; + } + } + lua_rawgeti(L, -3, 3); + } else { + n = set_origin; + } + do_store_four(n); + s = luaL_checklstring(L, -1, &l); + if (l > 0) { + do_store_four(l); + m = (int) l; + while (m > 0) { + n = *s++; + m--; + append_packet(n); + } + } + lua_pop(L,ts == 3 ? 2 : 1); + break; case packet_special_code: case packet_lua_code: append_packet(cmd); @@ -1144,8 +1207,7 @@ static void font_char_from_lua(lua_State * L, internal_font_number f, int i, int set_charinfo_tag(co, ext_tag); set_charinfo_extensible(co, top, bot, mid, rep); } else { - formatted_warning("font", "lua-loaded font %s char U+%X has an invalid extensible field", - font_name(f), (int) i); + formatted_warning("font", "lua-loaded font %s char U+%X has an invalid extensible field", font_name(f), (int) i); } } lua_pop(L, 1); @@ -1248,8 +1310,7 @@ static void font_char_from_lua(lua_State * L, internal_font_number f, int i, int set_kern_item(ckerns[ctr], k, j); ctr++; } else { - formatted_warning("font", "lua-loaded font %s char U+%X has an invalid kern field", - font_name(f), (int) i); + formatted_warning("font", "lua-loaded font %s char U+%X has an invalid kern field", font_name(f), (int) i); } lua_pop(L, 1); } @@ -1258,13 +1319,13 @@ static void font_char_from_lua(lua_State * L, internal_font_number f, int i, int set_kern_item(ckerns[ctr], end_kern, 0); set_charinfo_kerns(co, ckerns); } else { - formatted_warning("font", "lua-loaded font %s char U+%X has an invalid kerns field", - font_name(f), (int) i); + formatted_warning("font", "lua-loaded font %s char U+%X has an invalid kerns field", font_name(f), (int) i); } lua_pop(L, 1); } /* packet commands */ + lua_key_rawgeti(commands); if (lua_istable(L, -1)) { lua_pushnil(L); /* first key */ @@ -1307,8 +1368,7 @@ static void font_char_from_lua(lua_State * L, internal_font_number f, int i, int set_ligature_item(cligs[ctr], (char) ((t * 2) + 1), k, r); ctr++; } else { - formatted_warning("font", "lua-loaded font %s char U+%X has an invalid ligature field", - font_name(f), (int) i); + formatted_warning("font", "lua-loaded font %s char U+%X has an invalid ligature field", font_name(f), (int) i); } lua_pop(L, 1); /* iterator value */ } @@ -1317,8 +1377,7 @@ static void font_char_from_lua(lua_State * L, internal_font_number f, int i, int set_ligature_item(cligs[ctr], 0, end_ligature, 0); set_charinfo_ligatures(co, cligs); } else { - formatted_warning("font", "lua-loaded font %s char U+%X has an invalid ligatures field", - font_name(f), (int) i); + formatted_warning("font", "lua-loaded font %s char U+%X has an invalid ligatures field", font_name(f), (int) i); } lua_pop(L, 1); /* ligatures table */ } @@ -1353,7 +1412,6 @@ int font_from_lua(lua_State * L, int f) lua_pop(L,1); /* the table is at stack index -1 */ - s = n_string_field_copy(L,lua_key_index(area), ""); set_font_area(f, s); s = n_string_field_copy(L, lua_key_index(filename), NULL); @@ -1468,20 +1526,19 @@ int font_from_lua(lua_State * L, int f) l_fonts[i] = find_font_id(ss, t); lua_settop(L, s_top); } else { - formatted_error("font","invalid local font in lua-loaded font '%s'", font_name(f)); + formatted_error("font","invalid local font at index %i in lua-loaded font '%s' (1)",i,font_name(f)); } lua_pop(L, 1); /* pop list entry */ } lua_pop(L, 1); /* pop font table */ } else if (font_type(f) == virtual_font_type) { - formatted_error("font","invalid local fonts in lua-loaded font '%s'", font_name(f)); + formatted_error("font","invalid local fonts in lua-loaded font '%s' (2)", font_name(f)); } else { l_fonts = xmalloc(3 * sizeof(int)); l_fonts[0] = 0; l_fonts[1] = f; l_fonts[2] = 0; } - /* parameters */ no_math = n_boolean_field(L, lua_key_index(nomath), 0); read_lua_parameters(L, f); @@ -1536,11 +1593,9 @@ int font_from_lua(lua_State * L, int f) } else if (lt == LUA_TSTRING) { const char *ss1 = lua_tostring(L, -2); if (lua_key_eq(ss1, left_boundary)) { - font_char_from_lua(L, f, left_boundarychar, l_fonts, - !no_math); + font_char_from_lua(L, f, left_boundarychar, l_fonts, !no_math); } else if (lua_key_eq(ss1, right_boundary)) { - font_char_from_lua(L, f, right_boundarychar, l_fonts, - !no_math); + font_char_from_lua(L, f, right_boundarychar, l_fonts, !no_math); } } lua_pop(L, 1); @@ -1561,7 +1616,6 @@ int font_from_lua(lua_State * L, int f) if (fstep != 0) { int fshrink = lua_numeric_field_by_index(L, lua_key_index(shrink), 0); int fstretch =lua_numeric_field_by_index(L, lua_key_index(stretch), 0); - int fexpand = n_boolean_field(L, lua_key_index(auto_expand), 0); if (fshrink < 0) fshrink = 0; if (fshrink > 500) @@ -1576,7 +1630,7 @@ int font_from_lua(lua_State * L, int f) fstretch -= (fstretch % fstep); if (fstretch < 0) fstretch = 0; - set_expand_params(f, fexpand, fstretch, fshrink, fstep); + set_expand_params(f, fstretch, fshrink, fstep); } } @@ -1601,6 +1655,129 @@ int font_from_lua(lua_State * L, int f) return true; } +int characters_from_lua(lua_State * L, int f) +{ + int i, n, t, lt; + int *l_fonts = NULL; + int s_top; + const char *ss; + boolean no_math = false; + /* speedup */ + no_math = n_boolean_field(L, lua_key_index(nomath), 0); + /* type */ + i = n_enum_field(L, lua_key_index(type), font_type(f), font_type_strings); + set_font_type(f, i); + /* fonts */ + count_hash_items(L, fonts, n); + if (n > 0) { + /* font table still on stack */ + l_fonts = xmalloc((unsigned) ((unsigned) (n + 2) * sizeof(int))); + memset(l_fonts, 0, (size_t) ((unsigned) (n + 2) * sizeof(int))); + for (i = 1; i <= n; i++) { + lua_rawgeti(L, -1, i); + if (lua_istable(L, -1)) { + lua_key_rawgeti(id); + if (lua_isnumber(L, -1)) { + l_fonts[i] = (int) lua_tointeger(L, -1); + if (l_fonts[i] == 0) { + l_fonts[i] = (int) f; + } + lua_pop(L, 2); /* pop id and entry */ + continue; + } + lua_pop(L, 1); /* pop id */ + }; + ss = NULL; + if (lua_istable(L, -1)) { + ss = n_string_field(L, lua_key_index(name)); + /* string is anchored */ + lua_pop(L,1); + } + if (ss != NULL) { + t = lua_numeric_field_by_index(L, lua_key_index(size), -1000); + /* TODO: the stack is messed up, otherwise this explicit resizing would not be needed */ + s_top = lua_gettop(L); + if (strcmp(font_name(f), ss) == 0) + l_fonts[i] = f; + else + l_fonts[i] = find_font_id(ss, t); + lua_settop(L, s_top); + } else { + formatted_error("font","invalid local font in lua-loaded font '%s' (3)", font_name(f)); + } + lua_pop(L, 1); /* pop list entry */ + } + lua_pop(L, 1); /* pop font table */ + } else if (font_type(f) == virtual_font_type) { + formatted_error("font","invalid local fonts in lua-loaded font '%s' (4)", font_name(f)); + } else { + l_fonts = xmalloc(3 * sizeof(int)); + l_fonts[0] = 0; + l_fonts[1] = f; + l_fonts[2] = 0; + } + /* characters */ + lua_key_rawgeti(characters); + if (lua_istable(L, -1)) { + /* find the array size values */ + int num = 0; /* number of charinfo's to add */ + int todo = 0; + int bc = font_bc(f); + int ec = font_ec(f); + lua_pushnil(L); /* first key */ + while (lua_next(L, -2) != 0) { + if (lua_isnumber(L, -2)) { + i = (int) lua_tointeger(L, -2); + if (i >= 0) { + if (lua_istable(L, -1)) { + todo++; + if (! quick_char_exists(f,i)) { + num++; + if (i > ec) + ec = i; + if (bc < 0) + bc = i; + if (bc >= 0 && i < bc) + bc = i; + } + } + } + } + lua_pop(L, 1); + } + if (todo > 0) { + font_malloc_charinfo(f, num); + set_font_bc(f, bc); + set_font_ec(f, ec); + lua_pushnil(L); /* first key */ + while (lua_next(L, -2) != 0) { + lt = lua_type(L,-2); + if (lt == LUA_TNUMBER) { + i = (int) lua_tointeger(L, -2); + if (i >= 0) { + if (quick_char_exists(f,i)) { + charinfo *co = char_info(f, i); + set_charinfo_name(co, NULL); + set_charinfo_tounicode(co, NULL); + set_charinfo_packets(co, NULL); + set_charinfo_ligatures(co, NULL); + set_charinfo_kerns(co, NULL); + set_charinfo_vert_variants(co, NULL); + set_charinfo_hor_variants(co, NULL); + } + font_char_from_lua(L, f, i, l_fonts, !no_math); + } + } + lua_pop(L, 1); + } + lua_pop(L, 1); + } + } + if (l_fonts != NULL) + free(l_fonts); + return true; +} + @* Ligaturing. @c @@ -1995,8 +2172,9 @@ halfword handle_ligaturing(halfword head, halfword tail) vlink(tail) = null; } - /* |if (fix_node_lists)| */ - fix_node_list(head); + if (fix_node_lists) { + fix_node_list(head); + } prev = head; cur = vlink(prev); @@ -2184,7 +2362,9 @@ static halfword run_lua_ligkern_callback(halfword head, halfword tail, int callb luatex_error(Luas, (i == LUA_ERRRUN ? 0 : 1)); return tail; } - fix_node_list(head); + if (fix_node_lists) { + fix_node_list(head); + } lua_settop(Luas, top); return tail; } diff --git a/Build/source/texk/web2c/luatexdir/font/texfont.h b/Build/source/texk/web2c/luatexdir/font/texfont.h index 98557992f97..d415460b1e1 100644 --- a/Build/source/texk/web2c/luatexdir/font/texfont.h +++ b/Build/source/texk/web2c/luatexdir/font/texfont.h @@ -144,7 +144,6 @@ typedef struct texfont { int font_max_shrink; int font_max_stretch; int _font_step; /* amount of one step of expansion */ - boolean _font_auto_expand; /* this font is auto-expanded? */ char _font_tounicode; /* 1 if info is present */ fm_entry *_font_map; @@ -345,9 +344,6 @@ boolean cmp_font_area(int, str_number); # define font_step(a) font_tables[a]->_font_step # define set_font_step(a,b) font_step(a) = b -# define font_auto_expand(a) font_tables[a]->_font_auto_expand -# define set_font_auto_expand(a,b) font_auto_expand(a) = b - # define font_tounicode(a) font_tables[a]->_font_tounicode # define set_font_tounicode(a,b) font_tounicode(a) = b @@ -439,6 +435,7 @@ typedef enum { extern charinfo *get_charinfo(internal_font_number f, int c); extern int char_exists(internal_font_number f, int c); +extern int lua_glyph_not_found_callback(internal_font_number f, int c); extern charinfo *char_info(internal_font_number f, int c); /* @@ -627,6 +624,7 @@ typedef enum { packet_char_code, packet_end_code, packet_scale_code, packet_lua_code, + packet_pdf_code, } packet_command_codes; extern scaled store_scaled_f(scaled sq, int fw); @@ -655,9 +653,7 @@ extern internal_font_number tfm_lookup(char *s, scaled fs); extern int fix_expand_value(internal_font_number f, int e); -extern void set_expand_params(internal_font_number f, boolean auto_expand, - int stretch_limit, int shrink_limit, - int font_step); +extern void set_expand_params(internal_font_number f, int stretch_limit, int shrink_limit, int font_step); extern void read_expand_font(void); extern void new_letterspaced_font(small_number a); diff --git a/Build/source/texk/web2c/luatexdir/font/texfont.w b/Build/source/texk/web2c/luatexdir/font/texfont.w index 0c64045752e..ce463326a86 100644 --- a/Build/source/texk/web2c/luatexdir/font/texfont.w +++ b/Build/source/texk/web2c/luatexdir/font/texfont.w @@ -348,12 +348,11 @@ int char_exists(internal_font_number f, int c) } @ @c -#if 0 -static int lua_char_exists_callback(internal_font_number f, int c) +int lua_glyph_not_found_callback(internal_font_number f, int c) { int callback_id; int ret = 0; - callback_id = callback_defined(char_exists_callback); + callback_id = callback_defined(glyph_not_found_callback); if (callback_id != 0) { if (!get_callback(Luas, callback_id)) { lua_pop(Luas, 2); @@ -368,10 +367,11 @@ static int lua_char_exists_callback(internal_font_number f, int c) } else { ret = lua_toboolean(Luas, -1); } + } else { + char_warning(f,c); } return ret; } -#endif @ @c extinfo *new_variant(int glyph, int startconnect, int endconnect, @@ -1535,7 +1535,6 @@ static void dump_font_entry(texfont * f) dump_int(f->font_max_shrink); dump_int(f->font_max_stretch); dump_int(f->_font_step); - dump_int(f->_font_auto_expand); dump_int(f->_font_tounicode); dump_int(f->_font_type); dump_int(f->_font_format); @@ -1715,7 +1714,6 @@ static void undump_font_entry(texfont * f) undump_int(x); f->font_max_shrink = x; undump_int(x); f->font_max_stretch = x; undump_int(x); f->_font_step = x; - undump_int(x); f->_font_auto_expand = x; undump_int(x); f->_font_tounicode = (char)x; undump_int(x); f->_font_type = x; undump_int(x); f->_font_format = x; @@ -1845,11 +1843,9 @@ int fix_expand_value(internal_font_number f, int e) } @ @c -void set_expand_params(internal_font_number f, boolean auto_expand, - int stretch_limit, int shrink_limit, int font_step) -{ /* expand a font with given parameters */ +void set_expand_params(internal_font_number f, int stretch_limit, int shrink_limit, int font_step) +{ set_font_step(f, font_step); - set_font_auto_expand(f, auto_expand); set_font_max_shrink(f, shrink_limit); set_font_max_stretch(f, stretch_limit); } @@ -1859,7 +1855,6 @@ void read_expand_font(void) { /* read font expansion spec and load expanded font */ int shrink_limit, stretch_limit, font_step; internal_font_number f; - boolean auto_expand; /* read font expansion parameters */ scan_font_ident(); f = cur_val; @@ -1885,15 +1880,13 @@ void read_expand_font(void) shrink_limit = 0; if ((stretch_limit == 0) && (shrink_limit == 0)) normal_error("font expansion", "invalid limit(s)"); - auto_expand = false; if (scan_keyword("autoexpand")) { - auto_expand = true; + normal_warning("font expansion", "autoexpand not supported"); /* Scan an optional space */ get_x_token(); if (cur_cmd != spacer_cmd) back_input(); } - if (font_step(f) != 0) { /* this font has been expanded, ensure the expansion parameters are identical */ if (font_step(f) != font_step) @@ -1908,14 +1901,10 @@ void read_expand_font(void) ((font_max_shrink(f) > 0) && (font_max_shrink(f) != shrink_limit))) normal_error("font expansion","font has been expanded with different shrink limit"); - - if (font_auto_expand(f) != auto_expand) - normal_error("font expansion","font has been expanded with different auto expansion value"); } else { if (font_used(f)) normal_warning("font expansion", "font should be expanded before its first use"); - set_expand_params(f, auto_expand, stretch_limit, shrink_limit, - font_step); + set_expand_params(f, stretch_limit, shrink_limit, font_step); } } diff --git a/Build/source/texk/web2c/luatexdir/font/vfpacket.w b/Build/source/texk/web2c/luatexdir/font/vfpacket.w index 5b76eb81f40..14a6ca61169 100644 --- a/Build/source/texk/web2c/luatexdir/font/vfpacket.w +++ b/Build/source/texk/web2c/luatexdir/font/vfpacket.w @@ -88,6 +88,9 @@ int vf_packet_bytes(charinfo * co) case packet_rule_code: vfp += 8; break; + case packet_pdf_code: + vfp += 4; + /* plus a string so we fall through */ case packet_special_code: packet_number(k); /* +4 */ vfp += (int) k; @@ -104,7 +107,7 @@ int vf_packet_bytes(charinfo * co) @c const char *packet_command_names[] = { "char", "font", "pop", "push", "special", "image", - "right", "down", "rule", "node", "nop", "end", "scale", "lua", NULL + "right", "down", "rule", "node", "nop", "end", "scale", "lua", "pdf", NULL }; @ @c @@ -135,7 +138,7 @@ void do_vf_packet(PDF pdf, internal_font_number vf_f, int c, int ex_glyph) eight_bits *vfp; posstructure *save_posstruct, localpos; vf_struct *save_vfstruct, localvfstruct, *vp; - int cmd, w; + int cmd, w, mode; unsigned k; scaledpos size; scaled i; @@ -218,7 +221,7 @@ void do_vf_packet(PDF pdf, internal_font_number vf_f, int c, int ex_glyph) packet_scaled(size.h, vp->fs_f); if (size.h > 0 && size.v > 0) backend_out[rule_node](pdf, 0, size); /* the 0 is unused */ - mat_p->pos.h += size.h; + mat_p->pos.h += size.h; break; case packet_right_code: packet_scaled(i, vp->fs_f); @@ -228,6 +231,18 @@ void do_vf_packet(PDF pdf, internal_font_number vf_f, int c, int ex_glyph) packet_scaled(i, vp->fs_f); mat_p->pos.v += i; break; + case packet_pdf_code: + packet_number(mode); + packet_number(k); + str_room(k); + while (k > 0) { + k--; + append_char(*(vfp++)); + } + s = make_string(); + pdf_literal(pdf, s, mode, false); + flush_str(s); + break; case packet_special_code: packet_number(k); str_room(k); @@ -387,6 +402,9 @@ replace_packet_fonts(internal_font_number f, int *old_fontid, case packet_rule_code: vfp += 8; break; + case packet_pdf_code: + vfp += 4; + /* plus a string so we fall through */ case packet_special_code: packet_number(k); vfp += k; diff --git a/Build/source/texk/web2c/luatexdir/font/writefont.w b/Build/source/texk/web2c/luatexdir/font/writefont.w index 76d88b68bc4..2ba81d61749 100644 --- a/Build/source/texk/web2c/luatexdir/font/writefont.w +++ b/Build/source/texk/web2c/luatexdir/font/writefont.w @@ -578,7 +578,7 @@ static void write_fontdescriptor(PDF pdf, fd_entry * fd) assert(0); } } - if ((! pdf->omit_cidset) && (cidset != 0)) { + if ((! pdf->omit_cidset) && (pdf->major_version == 1) && (cidset != 0) ) { pdf_dict_add_ref(pdf, "CIDSet", cidset); } /* @@ -901,6 +901,13 @@ ids, but the strings that are written out use CID indexes, and those are limited to 16-bit values. @c +/* + This is old code ... it fails when the order of using the same font at + different extends changes. Probably because widths get overwritten or + set wrong. The loop also looks kind of weird (why a loop). +*/ + +/* static void mark_cid_subset_glyphs(fo_entry * fo, internal_font_number f) { int i, k, l; @@ -925,6 +932,32 @@ static void mark_cid_subset_glyphs(fo_entry * fo, internal_font_number f) } } } +*/ + +/* + So, let's try the following. +*/ + +static void mark_cid_subset_glyphs(fo_entry * fo, internal_font_number f) +{ + glw_entry *j; + void *aa; + int l = font_size(f); + int i; + for (i = font_bc(f); i <= font_ec(f); i++) { + if (quick_char_exists(f, i) && char_used(f, i)) { + j = xtalloc(1, glw_entry); + j->id = (unsigned) char_index(f, i); + j->wd = divide_scaled_n(char_width(f, i), l, 10000.0); + if ((glw_entry *) avl_find(fo->fd->gl_tree, j) == NULL) { + aa = avl_probe(fo->fd->gl_tree, j); + assert(aa != NULL); + } else { + xfree(j); + } + } + } +} @ It is possible to compress the widths array even better, by using the alternate 'range' syntax and possibly even using /DW to set a default diff --git a/Build/source/texk/web2c/luatexdir/font/writetype2.w b/Build/source/texk/web2c/luatexdir/font/writetype2.w index dc1821c5e5f..81aefb1fb69 100644 --- a/Build/source/texk/web2c/luatexdir/font/writetype2.w +++ b/Build/source/texk/web2c/luatexdir/font/writetype2.w @@ -387,24 +387,26 @@ boolean make_tt_subset(PDF pdf, fd_entry * fd, unsigned char *buff, int buflen) /* CIDSet: a table of bits indexed by cid, bytes with high order bit first, each (set) bit is a (present) CID. */ if (is_subsetted(fd->fm)) { - cidset = pdf_create_obj(pdf, obj_type_others, 0); - if (cidset != 0) { - size_t l = (last_cid / 8) + 1; - char *stream = xmalloc(l); - memset(stream, 0, l); - for (cid = 1; cid <= (long) last_cid; cid++) { - if (used_chars[cid]) { - stream[(cid / 8)] |= (1 << (7 - (cid % 8))); + if ((! pdf->omit_cidset) && (pdf->major_version == 1)) { + cidset = pdf_create_obj(pdf, obj_type_others, 0); + if (cidset != 0) { + size_t l = (last_cid / 8) + 1; + char *stream = xmalloc(l); + memset(stream, 0, l); + for (cid = 1; cid <= (long) last_cid; cid++) { + if (used_chars[cid]) { + stream[(cid / 8)] |= (1 << (7 - (cid % 8))); + } } + pdf_begin_obj(pdf, cidset, OBJSTM_NEVER); + pdf_begin_dict(pdf); + pdf_dict_add_streaminfo(pdf); + pdf_end_dict(pdf); + pdf_begin_stream(pdf); + pdf_out_block(pdf, stream, l); + pdf_end_stream(pdf); + pdf_end_obj(pdf); } - pdf_begin_obj(pdf, cidset, OBJSTM_NEVER); - pdf_begin_dict(pdf); - pdf_dict_add_streaminfo(pdf); - pdf_end_dict(pdf); - pdf_begin_stream(pdf); - pdf_out_block(pdf, stream, l); - pdf_end_stream(pdf); - pdf_end_obj(pdf); } } diff --git a/Build/source/texk/web2c/luatexdir/image/image.h b/Build/source/texk/web2c/luatexdir/image/image.h index 2ff07d448bd..7c79723f1df 100644 --- a/Build/source/texk/web2c/luatexdir/image/image.h +++ b/Build/source/texk/web2c/luatexdir/image/image.h @@ -126,6 +126,7 @@ typedef struct { int luaref ; boolean keepopen; int errorlevel; + int pdfmajorversion; int pdfminorversion; union { pdf_stream_struct *pdfstream; @@ -171,6 +172,7 @@ typedef struct { # define img_luaref(N) ((N)->luaref) # define img_keepopen(N) ((N)->keepopen) # define img_errorlevel(N) ((N)->errorlevel) +# define img_pdfmajorversion(N) ((N)->pdfmajorversion) # define img_pdfminorversion(N) ((N)->pdfminorversion) # define img_pdfstream_ptr(N) ((N)->img_struct.pdfstream) diff --git a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.w b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.w index 0f3e75d002c..09dcd251584 100644 --- a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.w +++ b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.w @@ -27,6 +27,10 @@ /* This file is mostly C and not very much C++; it's just used to interface the functions of poppler, which happens to be written in C++. + Patches for the new poppler 0.59 from + https://www.mail-archive.com/arch-commits@archlinux.org/msg357548.html + with some modifications to comply the poppler API. + */ extern void md5(Guchar *msg, int msgLen, Guchar *digest); @@ -71,7 +75,7 @@ static char *get_file_checksum(const char *a, file_error_mode fe) ck = (char *) malloc(PDF_CHECKSUM_SIZE); if (ck == NULL) formatted_error("pdf inclusion","out of memory while processing '%s'", a); - snprintf(ck, PDF_CHECKSUM_SIZE, "%" PRIu64 "_%" PRIu64, (uint64_t) size,(uint64_t) mtime); + snprintf(ck, PDF_CHECKSUM_SIZE, "%"@= @>PRIu64@= @>"_%"@= @>PRIu64, (uint64_t) size,(uint64_t) mtime); } else { switch (fe) { case FE_FAIL: @@ -224,7 +228,7 @@ PdfDocument *refMemStreamPdfDocument(char *docstream, unsigned long long streams free(checksum); } if (pdf_doc->doc == NULL) { - docmemstream = new MemStream( docstream,0,streamsize, obj.initNull() ); + docmemstream = new MemStream( docstream,0,streamsize, Object(objNull) ); doc = new PDFDoc(docmemstream); /* takes ownership of docmemstream */ pdf_doc->pc++; if (!doc->isOk() || !doc->okToPrint()) { @@ -408,9 +412,8 @@ static void copyArray(PDF pdf, PdfDocument * pdf_doc, Array * array) Object obj1; pdf_begin_array(pdf); for (i = 0, l = array->getLength(); i < l; ++i) { - array->getNF(i, &obj1); + obj1 = array->getNF(i); copyObject(pdf, pdf_doc, &obj1); - obj1.free(); } pdf_end_array(pdf); } @@ -422,9 +425,8 @@ static void copyDict(PDF pdf, PdfDocument * pdf_doc, Dict * dict) pdf_begin_dict(pdf); for (i = 0, l = dict->getLength(); i < l; ++i) { copyName(pdf, dict->getKey(i)); - dict->getValNF(i, &obj1); + obj1 = dict->getValNF(i); copyObject(pdf, pdf_doc, &obj1); - obj1.free(); } pdf_end_dict(pdf); } @@ -510,13 +512,12 @@ static void writeRefs(PDF pdf, PdfDocument * pdf_doc) PDFDoc *doc = pdf_doc->doc; xref = doc->getXRef(); for (r = pdf_doc->inObjList; r != NULL;) { - xref->fetch(r->ref.num, r->ref.gen, &obj1); + obj1 = xref->fetch(r->ref.num, r->ref.gen); if (obj1.isStream()) pdf_begin_obj(pdf, r->num, OBJSTM_NEVER); else pdf_begin_obj(pdf, r->num, 2); copyObject(pdf, pdf_doc, &obj1); - obj1.free(); pdf_end_obj(pdf); n = r->next; delete r; @@ -596,7 +597,7 @@ void read_pdf_info(image_dict * idict) pdf_doc = refPdfDocument(img_filepath(idict), FE_FAIL); else if (img_type(idict) == IMG_TYPE_PDFMEMSTREAM) { pdf_doc = findPdfDocument(img_filepath(idict)) ; - if (pdf_doc == NULL ) + if (pdf_doc == NULL ) normal_error("pdf inclusion", "memstream not initialized"); if (pdf_doc->doc == NULL) normal_error("pdf inclusion", "memstream document is empty"); @@ -613,12 +614,12 @@ void read_pdf_info(image_dict * idict) */ pdf_major_version_found = doc->getPDFMajorVersion(); pdf_minor_version_found = doc->getPDFMinorVersion(); - if ((pdf_major_version_found > 1) || (pdf_minor_version_found > img_pdfminorversion(idict))) { - const char *msg = "PDF inclusion: found PDF version '%d.%d', but at most version '1.%d' allowed"; + if ((100 * pdf_major_version_found + pdf_major_version_found) > (100 * img_pdfmajorversion(idict) + img_pdfminorversion(idict))) { + const char *msg = "PDF inclusion: found PDF version '%d.%d', but at most version '%d.%d' allowed"; if (img_errorlevel(idict) > 0) { - formatted_error("pdf inclusion",msg, pdf_major_version_found, pdf_minor_version_found, img_pdfminorversion(idict)); + formatted_error("pdf inclusion",msg, pdf_major_version_found, pdf_minor_version_found, img_pdfmajorversion(idict), img_pdfminorversion(idict)); } else { - formatted_warning("pdf inclusion",msg, pdf_major_version_found, pdf_minor_version_found, img_pdfminorversion(idict)); + formatted_warning("pdf inclusion",msg, pdf_major_version_found, pdf_minor_version_found, img_pdfmajorversion(idict), img_pdfminorversion(idict)); } } img_totalpages(idict) = catalog->getNumPages(); @@ -740,7 +741,7 @@ void write_epdf(PDF pdf, image_dict * idict, int suppress_optional_info) catalog = doc->getCatalog(); page = catalog->getPage(img_pagenum(idict)); pageref = catalog->getPageRef(img_pagenum(idict)); - doc->getXRef()->fetch(pageref->num, pageref->gen, &pageobj); + pageobj = doc->getXRef()->fetch(pageref->num, pageref->gen); pageDict = pageobj.getDict(); /* write the Page header */ pdf_begin_obj(pdf, img_objnum(idict), OBJSTM_NEVER); @@ -757,12 +758,11 @@ void write_epdf(PDF pdf, image_dict * idict, int suppress_optional_info) pdf_dict_add_int(pdf, "PTEX.PageNumber", (int) img_pagenum(idict)); } if ((suppress_optional_info & 8) == 0) { - doc->getDocInfoNF(&obj1); + obj1 = doc->getDocInfoNF(); if (obj1.isRef()) { /* the info dict must be indirect (PDF Ref p. 61) */ pdf_dict_add_ref(pdf, "PTEX.InfoDict", addInObj(pdf, pdf_doc, obj1.getRef())); } - obj1.free(); } if (img_is_bbox(idict)) { bbox[0] = sp2bp(img_bbox(idict)[0]); @@ -788,19 +788,17 @@ void write_epdf(PDF pdf, image_dict * idict, int suppress_optional_info) Now all relevant parts of the Page dictionary are copied. Metadata validity check is needed(as a stream it must be indirect). */ - pageDict->lookupNF("Metadata", &obj1); + obj1 = pageDict->lookupNF("Metadata"); if (!obj1.isNull() && !obj1.isRef()) formatted_warning("pdf inclusion","/Metadata must be indirect object"); - obj1.free(); /* copy selected items in Page dictionary */ for (i = 0; pagedictkeys[i] != NULL; i++) { - pageDict->lookupNF(pagedictkeys[i], &obj1); + obj1 = pageDict->lookupNF(pagedictkeys[i]); if (!obj1.isNull()) { pdf_add_name(pdf, pagedictkeys[i]); /* preserves indirection */ copyObject(pdf, pdf_doc, &obj1); } - obj1.free(); } /* If there are no Resources in the Page dict of the embedded page, @@ -808,32 +806,28 @@ void write_epdf(PDF pdf, image_dict * idict, int suppress_optional_info) PDF file, climbing up the tree until the Resources are found. (This fixes a problem with Scribus 1.3.3.14.) */ - pageDict->lookupNF("Resources", &obj1); + obj1 = pageDict->lookupNF("Resources"); if (obj1.isNull()) { op1 = &pagesobj1; op2 = &pagesobj2; - pageDict->lookup("Parent", op1); + *op1 = pageDict->lookup("Parent"); while (op1->isDict()) { - obj1.free(); - op1->dictLookupNF("Resources", &obj1); + obj1 = op1->dictLookupNF("Resources"); if (!obj1.isNull()) { pdf_add_name(pdf, "Resources"); copyObject(pdf, pdf_doc, &obj1); break; } - op1->dictLookup("Parent", op2); + *op2 = op1->dictLookup("Parent"); optmp = op1; op1 = op2; op2 = optmp; - op2->free(); }; if (!op1->isDict()) formatted_warning("pdf inclusion","Page /Resources missing"); - op1->free(); } - obj1.free(); /* Write the Page contents. */ - page->getContents(&contents); + contents = page->getContents(); if (contents.isStream()) { /* Variant A: get stream and recompress under control of \pdfcompresslevel @@ -844,27 +838,23 @@ void write_epdf(PDF pdf, image_dict * idict, int suppress_optional_info) Variant B: copy stream without recompressing */ - contents.streamGetDict()->lookup("F", &obj1); + obj1 = contents.streamGetDict()->lookup("F"); if (!obj1.isNull()) { normal_error("pdf inclusion","unsupported external stream"); } - obj1.free(); - contents.streamGetDict()->lookup("Length", &obj1); + obj1 = contents.streamGetDict()->lookup("Length"); pdf_add_name(pdf, "Length"); copyObject(pdf, pdf_doc, &obj1); - obj1.free(); - contents.streamGetDict()->lookup("Filter", &obj1); + obj1 = contents.streamGetDict()->lookup("Filter"); if (!obj1.isNull()) { pdf_add_name(pdf, "Filter"); copyObject(pdf, pdf_doc, &obj1); - obj1.free(); - contents.streamGetDict()->lookup("DecodeParms", &obj1); + obj1 = contents.streamGetDict()->lookup("DecodeParms"); if (!obj1.isNull()) { pdf_add_name(pdf, "DecodeParms"); copyObject(pdf, pdf_doc, &obj1); } } - obj1.free(); pdf_end_dict(pdf); pdf_begin_stream(pdf); copyStreamStream(pdf, contents.getStream()->getUndecodedStream()); @@ -875,8 +865,8 @@ void write_epdf(PDF pdf, image_dict * idict, int suppress_optional_info) pdf_end_dict(pdf); pdf_begin_stream(pdf); for (i = 0, l = contents.arrayGetLength(); i < l; ++i) { - copyStreamStream(pdf, (contents.arrayGet(i, &obj1))->getStream()); - obj1.free(); + obj1 = contents.arrayGet(i); + copyStreamStream(pdf, obj1.getStream()); if (i < (l - 1)) { /* Put a space between streams to be on the safe side (streams @@ -897,8 +887,6 @@ void write_epdf(PDF pdf, image_dict * idict, int suppress_optional_info) } /* write out all indirect objects */ writeRefs(pdf, pdf_doc); - contents.free(); - pageobj.free(); /* unrefPdfDocument() must come after contents.free() and pageobj.free()! TH: The next line makes repeated pdf inclusion unacceptably slow diff --git a/Build/source/texk/web2c/luatexdir/image/writeimg.w b/Build/source/texk/web2c/luatexdir/image/writeimg.w index 0944509c044..95e1ec3049d 100644 --- a/Build/source/texk/web2c/luatexdir/image/writeimg.w +++ b/Build/source/texk/web2c/luatexdir/image/writeimg.w @@ -100,7 +100,7 @@ that a type has been found. #define HEADER_PNG "\x89PNG\r\n\x1A\n" #define HEADER_JBIG2 "\x97\x4A\x42\x32\x0D\x0A\x1A\x0A" #define HEADER_JP2 "\x6A\x50\x20\x20" -#define HEADER_PDF "%PDF-1." +#define HEADER_PDF "%PDF-" #define MAX_HEADER (sizeof(HEADER_PNG)-1) #define HEADER_PDF_MEMSTREAM "data:application/pdf," /* see epdf.h */ #define LEN_PDF_MEMSTREAM 21 /* see epdf.h */ @@ -217,7 +217,8 @@ image_dict *new_image_dict(void) img_index(p) = -1; /* -1 = unused, used count from 0 */ img_luaref(p) = 0; img_errorlevel(p) = pdf_inclusion_errorlevel; - fix_pdf_minorversion(static_pdf); + fix_pdf_version(static_pdf); + img_pdfmajorversion(p) = pdf_major_version; img_pdfminorversion(p) = pdf_minor_version; return p; } diff --git a/Build/source/texk/web2c/luatexdir/image/writejbig2.w b/Build/source/texk/web2c/luatexdir/image/writejbig2.w index d1ed0a408d4..a58313ce8d8 100644 --- a/Build/source/texk/web2c/luatexdir/image/writejbig2.w +++ b/Build/source/texk/web2c/luatexdir/image/writejbig2.w @@ -762,7 +762,7 @@ static void wr_jbig2(PDF pdf, image_dict * idict, FILEINFO * fip, @ @c boolean supported_jbig2(image_dict * idict) { - if (img_pdfminorversion(idict) < 4) { + if (img_pdfmajorversion(idict) < 2 && img_pdfminorversion(idict) < 4) { normal_error("readjbig2","you need to generate at least PDF 1.4"); return false; } else { diff --git a/Build/source/texk/web2c/luatexdir/image/writejpg.w b/Build/source/texk/web2c/luatexdir/image/writejpg.w index 7d463b77374..54ed47f0f92 100644 --- a/Build/source/texk/web2c/luatexdir/image/writejpg.w +++ b/Build/source/texk/web2c/luatexdir/image/writejpg.w @@ -132,9 +132,9 @@ static unsigned int read_exif_bytes(unsigned char **p, int n, int b) XResolution, YResolution and ResolutionUnit (tag 282, 283 and 296) as well as PixelPerUnitX, PixelPerUnitY and PixelUnit (tag 0x5111, 0x5112 and 0x5110). Tags 282, 293 and 296 have the priority, -with ResolutionUnit set to inch by default, then +with ResolutionUnit set to inch by default, then tag 0x5110, 0x5111 and 0x5112, where the only valid value for PixelUnit is 0.0254, -and finally the given value xx and yy, +and finally the given value xx and yy, choosen if the Exif x and y resolution are not strictly positive. @@ -256,7 +256,7 @@ static void read_APP1_Exif (FILE *fp, unsigned short length, int *xx, int *yy, i res_unit_ms = 0.0254; /* Unit is meter */ break; default: - res_unit_ms = 0; + res_unit_ms = 0; } case 0x5111: /* PixelPerUnitX */ found_x_ms = true ; @@ -269,13 +269,13 @@ static void read_APP1_Exif (FILE *fp, unsigned short length, int *xx, int *yy, i } - } + } if (found_x && found_y && res_unit>0) { - found_res = true; + found_res = true; tempx = (int)(xres * res_unit+0.5); tempy = (int)(yres * res_unit+0.5); } else if (found_x_ms && found_y_ms && res_unit_ms==0.0254) { - found_res = true; + found_res = true; tempx = (int)(xres_ms * res_unit_ms+0.5); tempy = (int)(yres_ms * res_unit_ms+0.5); } @@ -394,7 +394,7 @@ void read_jpg_info(image_dict * idict) formatted_error("readjpg","unsupported compression SOF_%d", i - M_SOF0); break; case M_SOF2: - if (img_pdfminorversion(idict) <= 2) { + if (img_pdfmajorversion(idict) < 2 && img_pdfminorversion(idict) <= 2) { normal_error("readjpg","progressive DCT with PDF-1.2 is not permitted"); } case M_SOF0: diff --git a/Build/source/texk/web2c/luatexdir/lang/hyphen.w b/Build/source/texk/web2c/luatexdir/lang/hyphen.w index 8e13896090d..35befb743de 100644 --- a/Build/source/texk/web2c/luatexdir/lang/hyphen.w +++ b/Build/source/texk/web2c/luatexdir/lang/hyphen.w @@ -776,6 +776,8 @@ void hnj_hyphen_load(HyphenDict * dict, const unsigned char *f) } @ @c +extern halfword insert_syllable_discretionary(halfword t, lang_variables * lan); + void hnj_hyphen_hyphenate(HyphenDict * dict, halfword first1, halfword last1, @@ -791,9 +793,9 @@ void hnj_hyphen_hyphenate(HyphenDict * dict, char *hyphens = hnj_malloc(hyphen_len + 1); /* Add a '.' to beginning and end to facilitate matching */ - set_vlink(begin_point, first1); - set_vlink(end_point, get_vlink(last1)); - set_vlink(last1, end_point); + vlink(begin_point) = first1; + vlink(end_point) = vlink(last1); + vlink(last1) = end_point; for (char_num = 0; char_num < hyphen_len; char_num++) { hyphens[char_num] = '0'; @@ -801,16 +803,16 @@ void hnj_hyphen_hyphenate(HyphenDict * dict, hyphens[hyphen_len] = 0; /* now, run the finite state machine */ - for (char_num = 0, here = begin_point; here != get_vlink(end_point); - here = get_vlink(here)) { + for (char_num = 0, here = begin_point; here != vlink(end_point); + here = vlink(here)) { int ch; if (here == begin_point || here == end_point) { ch = '.'; } else { - ch = get_hj_code(char_lang(here),get_character(here)); + ch = get_hj_code(char_lang(here),character(here)); if (ch <= 32) { - ch = get_character(here); + ch = character(here); } } while (state != -1) { @@ -857,14 +859,14 @@ void hnj_hyphen_hyphenate(HyphenDict * dict, } /* restore the correct pointers */ - set_vlink(last1, get_vlink(end_point)); + vlink(last1) = vlink(end_point); /* pattern is \.{\^.\^w\^o\^r\^d\^.\^} |word_len|=4, |ext_word_len|=6, |hyphens|=7 * check \.{ \^ \^ \^ } so drop first two and stop after |word_len-1| */ - for (here = first1, char_num = 2; here != left; here = get_vlink(here)) + for (here = first1, char_num = 2; here != left; here = vlink(here)) char_num++; - for (; here != right; here = get_vlink(here)) { + for (; here != right; here = vlink(here)) { if (hyphens[char_num] & 1) here = insert_syllable_discretionary(here, lan); char_num++; diff --git a/Build/source/texk/web2c/luatexdir/lang/texlang.h b/Build/source/texk/web2c/luatexdir/lang/texlang.h index 5e7a046195f..0fa11d4c82f 100644 --- a/Build/source/texk/web2c/luatexdir/lang/texlang.h +++ b/Build/source/texk/web2c/luatexdir/lang/texlang.h @@ -67,7 +67,7 @@ extern int get_post_exhyphen_char(int lan); extern void set_hyphenation_min(int lan, int val); extern int get_hyphenation_min(int lan); -extern halfword compound_word_break(halfword t, int clang); +/* extern halfword compound_word_break(halfword t, int clang); */ extern void dump_language_data(void); extern void undump_language_data(void); @@ -82,5 +82,7 @@ extern void new_post_exhyphen_char(void); extern void new_hyphenation_min(void); extern void new_hj_code(void); +extern void set_disc_field(halfword f, halfword t); +extern halfword insert_syllable_discretionary(halfword t, lang_variables * lan); #endif diff --git a/Build/source/texk/web2c/luatexdir/lang/texlang.w b/Build/source/texk/web2c/luatexdir/lang/texlang.w index bd519af632a..337d2eca51d 100644 --- a/Build/source/texk/web2c/luatexdir/lang/texlang.w +++ b/Build/source/texk/web2c/luatexdir/lang/texlang.w @@ -60,7 +60,8 @@ struct tex_language *new_language(int n) lang->post_exhyphen_char = 0; lang->hyphenation_min = -1; if (saving_hyph_codes_par) { - hj_codes_from_lc_codes(l); /* for now, we might just use specific value for whatever task */ + /* for now, we might just use specific value for whatever task */ + hj_codes_from_lc_codes(l); } return lang; } else { @@ -198,10 +199,10 @@ void load_tex_patterns(int curlang, halfword head) const char *clean_hyphenation(int id, const char *buff, char **cleaned) { int items = 0; - unsigned char word[MAX_WORD_LEN + 1]; /* work buffer for bytes */ - unsigned uword[MAX_WORD_LEN + 1] = { 0 }; /* work buffer for unicode */ - int u = 0; /* unicode buffer value */ - int i = 0; /* index into buffer */ + unsigned char word[MAX_WORD_LEN + 1]; /* work buffer for bytes */ + unsigned uword[MAX_WORD_LEN + 1] = { 0 }; /* work buffer for unicode */ + int u = 0; /* unicode buffer value */ + int i = 0; /* index into buffer */ char *uindex = (char *)word; const char *s = buff; @@ -218,12 +219,12 @@ const char *clean_hyphenation(int id, const char *buff, char **cleaned) /* now convert the input to unicode */ word[i] = '\0'; utf2uni_strcpy(uword, (const char *)word); - /* build the new word string */ i = 0; while (uword[i]>0) { u = uword[i++]; - if (u == '-') { /* skip */ + if (u == '-') { + /* skip */ } else if (u == '=') { STORE_CHAR(id,'-'); } else if (u == '{') { @@ -253,7 +254,7 @@ const char *clean_hyphenation(int id, const char *buff, char **cleaned) if (u == '}') { items++; } - if (items != 3) { /* syntax error */ + if (items != 3) { *cleaned = NULL; tex_error("exception syntax error", NULL); return s; @@ -322,51 +323,61 @@ void load_tex_hyphenation(int curlang, halfword head) } @ @c -halfword insert_discretionary(halfword t, halfword pre, halfword post, halfword replace, int penalty) +static halfword insert_discretionary(halfword t, halfword pre, halfword post, halfword replace, int penalty) { - halfword g, n; + halfword g; int f; - n = new_node(disc_node, syllable_disc); - disc_penalty(n) = penalty; - try_couple_nodes(n, vlink(t)); - couple_nodes(t, n); - if (replace != null) + halfword d = new_node(disc_node, syllable_disc); + int attr = node_attr(t) ; + disc_penalty(d) = penalty; + if (t == replace) { + /* prev disc next-next */ + try_couple_nodes(d, vlink(t)); + try_couple_nodes(alink(t), d); + alink(t) = null; + vlink(t) = null; + replace = t ; + } else { + /* prev disc next */ + try_couple_nodes(d, vlink(t)); + couple_nodes(t, d); + } + if (replace != null) { f = font(replace); - else - f = get_cur_font(); /* for compound words following explicit hyphens */ + } else { + /* For compound words following explicit hyphens. */ + f = get_cur_font(); + } for (g = pre; g != null; g = vlink(g)) { font(g) = f; - if (node_attr(t) != null) { + if (attr != null) { delete_attribute_ref(node_attr(g)); - node_attr(g) = node_attr(t); - attr_list_ref(node_attr(t)) += 1; + node_attr(g) = attr; + attr_list_ref(attr) += 1; } } for (g = post; g != null; g = vlink(g)) { font(g) = f; - if (node_attr(t) != null) { + if (attr != null) { delete_attribute_ref(node_attr(g)); - node_attr(g) = node_attr(t); - attr_list_ref(node_attr(t)) += 1; + node_attr(g) = attr; + attr_list_ref(attr) += 1; } } - for (g = replace; g != null; g = vlink(g)) { - if (node_attr(t) != null) { + if (attr != null) { + for (g = replace; g != null; g = vlink(g)) { delete_attribute_ref(node_attr(g)); - node_attr(g) = node_attr(t); - attr_list_ref(node_attr(t)) += 1; + node_attr(g) = attr; + attr_list_ref(attr) += 1; } + delete_attribute_ref(node_attr(d)); + node_attr(d) = attr; + attr_list_ref(attr) += 1; } - if (node_attr(t) != null) { - delete_attribute_ref(node_attr(vlink(t))); - node_attr(vlink(t)) = node_attr(t); - attr_list_ref(node_attr(t)) += 1; - } - t = vlink(t); - set_disc_field(pre_break(t), pre); - set_disc_field(post_break(t), post); - set_disc_field(no_break(t), replace); - return t; + set_disc_field(pre_break(d), pre); + set_disc_field(post_break(d), post); + set_disc_field(no_break(d), replace); + return d; } halfword insert_syllable_discretionary(halfword t, lang_variables * lan) @@ -413,43 +424,38 @@ halfword insert_syllable_discretionary(halfword t, lang_variables * lan) } @ @c -halfword compound_word_break(halfword t, int clang) +static halfword insert_character(halfword t, int c) +{ + halfword p; + p = new_node(glyph_node, 0); + set_to_character(p); + character(p) = c; + if (t != null) { + couple_nodes(t, p); + } + return p; +} + +static halfword compound_word_break(halfword t, int clang) { halfword disc = null; halfword pre = null; halfword pos = null; halfword pre_exhyphen_char = get_pre_exhyphen_char(clang); halfword post_exhyphen_char = get_post_exhyphen_char(clang); - if (pre_exhyphen_char > 0) + if (pre_exhyphen_char > 0) { pre = insert_character(null,pre_exhyphen_char); + } else { + pre = insert_character(null,ex_hyphen_char_par); + } if (post_exhyphen_char > 0) pos = insert_character(null,post_exhyphen_char); - disc = insert_discretionary(t,pre,pos,null,ex_hyphen_penalty_par); + disc = insert_discretionary(t,pre,pos,t,ex_hyphen_penalty_par); subtype(disc) = automatic_disc; set_automatic_disc_penalty(disc); return disc; } -halfword insert_complex_discretionary(halfword t, lang_variables * lan, - halfword pre, halfword pos, - halfword replace) -{ - (void) lan; - return insert_discretionary(t,pre,pos,replace,hyphen_penalty_par); -} - -halfword insert_character(halfword t, int c) -{ - halfword p; - p = new_node(glyph_node, 0); - set_to_character(p); - character(p) = c; - if (t != null) { - couple_nodes(t, p); - } - return p; -} - @ @c void set_disc_field(halfword f, halfword t) { @@ -713,6 +719,20 @@ there was not the best idea ever. */ +/* + We only accept an explicit hyphen when there is a preceding glyph and we skip a sequence of + explicit hyphens as that normally indicates a -- or --- ligature in which case we can in a + worse case usage get bad node lists later on due to messed up ligature building as these + dashes are ligatures in base fonts. This is a side effect of the separating the hyphenation, + ligaturing and kerning steps. A test is cmr with ------. + + A font handler can collapse successive hyphens but it's not nice to put the burden there. A + somewhat messy border case is ---- but in LuaTeX we don't treat -- and --- special. Also, + traditional TeX will break a line at -foo but this can be disabled by setting the automatic + mode to 1. + +*/ + static halfword find_next_wordstart(halfword r, halfword first_language, halfword strict_bound) { register int l; @@ -757,27 +777,31 @@ static halfword find_next_wordstart(halfword r, halfword first_language, halfwor if (is_simple_character(r)) { chr = character(r) ; if (chr == ex_hyphen_char_par) { - /* - We only accept an explicit hyphen when there is a preceding glyph and - we skip a sequence of explicit hyphens as that normally indicates a - -- or --- ligature in which case we can in a worse case usage get bad - node lists later on due to messed up ligature building as these dashes - are ligatures in base fonts. This is a side effect of the separating the - hyphenation, ligaturing and kerning steps. A test is cmr with ------. - */ t = vlink(r) ; - if ((start_ok == 0) && (t!=null) && (type(t) == glyph_node) && (character(t) != ex_hyphen_char_par)) { - compound_word_break(r, char_lang(r)); - start_ok = 1 ; + if ((automatic_hyphen_mode_par == 0) && (t != null) && (type(t) == glyph_node) && (character(t) != ex_hyphen_char_par)) { + /* we have no word yet and the next character is a non hyphen */ + r = compound_word_break(r, char_lang(r)); } else { - start_ok = 0; + /* we jump over the sequence of hyphens */ + while ((t != null) && (type(t) == glyph_node) && (character(t) == ex_hyphen_char_par)) { + r = t ; + t = vlink(r) ; + } + if (t == null) { + /* we reached the end of the list so we have no word start */ + return null; + } } + /* we need a restart */ + start_ok = 0; } else if (start_ok && (char_lang(r)>=first_language) && ((l = get_hj_code(char_lang(r),chr)) > 0)) { if (char_uchyph(r) || l == chr || l <= 32) { return r; } else { start_ok = 0; } + } else { + /* go on */ } } break; @@ -839,18 +863,23 @@ void hnj_hyphenation(halfword head, halfword tail) halfword strict_bound = hyphenation_bounds_par; halfword s, r = head, wordstart = null, save_tail1 = null, left = null, right = null; - /* this first movement assures two things: - \item{a)} that we won't waste lots of time on something that has been - handled already (in that case, none of the glyphs match |simple_character|). - \item{b)} that the first word can be hyphenated. if the movement was - not explicit, then the indentation at the start of a paragraph - list would make |find_next_wordstart()| look too far ahead. - */ + /* + This first movement assures two things: + + \item{a)} that we won't waste lots of time on something that has been handled already + (in that case, none of the glyphs match |simple_character|). + + \item{b)} that the first word can be hyphenated. if the movement was not explicit, + then the indentation at the start of a paragraph list would make |find_next_wordstart()| + look too far ahead. + */ while (r != null && (type(r) != glyph_node || !is_simple_character(r))) { r = vlink(r); } - /* this will make |r| a glyph node with subtype character */ + /* + This will make |r| a glyph node with subtype character. + */ r = find_next_wordstart(r,first_language,strict_bound); if (r == null) return; @@ -860,15 +889,17 @@ void hnj_hyphenation(halfword head, halfword tail) s = new_penalty(0,word_penalty); couple_nodes(tail, s); - while (r != null) { /* could be while(1), but let's be paranoid */ + while (r != null) { /* could be while(1), but let's be paranoid */ int clang, lhmin, rhmin, hmin; halfword hyf_font; halfword end_word = r; wordstart = r; assert(is_simple_character(wordstart)); hyf_font = font(wordstart); - if (hyphen_char(hyf_font) < 0) /* for backward compat */ + if (hyphen_char(hyf_font) < 0) { + /* For backward compatibility: */ hyf_font = 0; + } clang = char_lang(wordstart); lhmin = char_lhmin(wordstart); rhmin = char_rhmin(wordstart); @@ -889,6 +920,7 @@ void hnj_hyphenation(halfword head, halfword tail) ) { if (character(r) == ex_hyphen_char_par) { explicit_hyphen = true; + break; } wordlen++; if (lchar <= 32) { @@ -911,12 +943,27 @@ void hnj_hyphenation(halfword head, halfword tail) lchar = character(r) ; } hy = uni2string(hy, (unsigned) lchar); - /* this should not be needed any more */ - /*if (vlink(r)!=null) alink(vlink(r))=r; */ end_word = r; r = vlink(r); } - if ( valid_wordend(r,strict_bound) + if (explicit_hyphen == true) { + /* we are not at the start, so we only need to look ahead */ + halfword t = vlink(r) ; + if ((automatic_hyphen_mode_par == 0 || automatic_hyphen_mode_par == 1) && (t != null) && ((type(t) == glyph_node) && (character(t) != ex_hyphen_char_par))) { + /* we have a word already but the next character may not be a hyphen too */ + r = compound_word_break(r, char_lang(r)); + } else { + /* we jump over the sequence of hyphens */ + while ((t != null) && (type(t) == glyph_node) && (character(t) == ex_hyphen_char_par)) { + r = t ; + t = vlink(r) ; + } + if (t == null) { + /* we reached the end of the list and will quit the loop later */ + r = null; + } + } + } else if ( valid_wordend(r,strict_bound) && clang >= first_language && wordlen >= lhmin + rhmin && (hmin <= 0 || wordlen >= hmin) @@ -924,35 +971,10 @@ void hnj_hyphenation(halfword head, halfword tail) && (lang = tex_languages[clang]) != NULL ) { *hy = 0; - if ( lang->exceptions != 0 - && (replacement = hyphenation_exception(lang->exceptions, utf8word)) != NULL - ) { -#ifdef VERBOSE - formatted_warning("hyphenation","replacing %s (c=%d) by %s", utf8word, clang, replacement); -#endif + if (lang->exceptions != 0 && (replacement = hyphenation_exception(lang->exceptions, utf8word)) != NULL) { + /* handle the exception and go on to the next word */ do_exception(wordstart, r, replacement); free(replacement); - } else if (explicit_hyphen == true) { - /* - insert an explicit discretionary after each of the last in a - set of explicit hyphens - */ - halfword rr = r; -#ifdef VERBOSE - formatted_warning("hyphenation","explicit hyphen(s) found in %s (c=%d)", utf8word, clang); -#endif - while (rr != wordstart) { - if (is_simple_character(rr)) { - if (character(rr) == ex_hyphen_char_par) { - compound_word_break(rr, clang); - while (character(alink(rr)) == ex_hyphen_char_par) - rr = alink(rr); - if (rr == wordstart) - break; - } - } - rr = alink(rr); - } } else if (lang->patterns != NULL) { left = wordstart; for (i = lhmin; i > 1; i--) { @@ -960,10 +982,7 @@ void hnj_hyphenation(halfword head, halfword tail) while (!is_simple_character(left)) { left = vlink(left); } - /* - if (!left) - break ; - */ + /* if (!left) break; */ /* what is left overruns right .. a bit messy */ } right = r; @@ -972,20 +991,10 @@ void hnj_hyphenation(halfword head, halfword tail) while (!is_simple_character(right)) { right = alink(right); } - /* - if (!right) - break ; - */ + /* if (!right) break; */ /* what is right overruns left .. a bit messy */ } - /* maybe an extra check ... */ - /* |if (left && right) {| */ -#ifdef VERBOSE - formatted_warning("hyphenation","hyphenate %s (c=%d,l=%d,r=%d) from %c to %c", - utf8word, clang, lhmin, rhmin, character(left), character(right)); -#endif - (void) hnj_hyphen_hyphenate(lang->patterns, wordstart, end_word, wordlen, left, right, &langdata); - /* |}| */ + (void) hnj_hyphen_hyphenate(lang->patterns, wordstart, end_word, wordlen, left, right, &langdata); } } explicit_hyphen = false; @@ -1026,7 +1035,7 @@ void new_hyphenation(halfword head, halfword tail) } } -@ dumping and undumping languages +@ Dumping and undumping languages. @c #define dump_string(a) \ @@ -1139,20 +1148,19 @@ void new_hyph_exceptions(void) flush_list(def_ref); } -@ Similarly, when \TeX\ has scanned `\.{\\patterns}', it calls on a -procedure named |new_patterns|. +@ Similarly, when \TeX\ has scanned `\.{\\patterns}', it calls on a procedure named +|new_patterns|. @c void new_patterns(void) -{ /* initializes the hyphenation pattern data */ +{ (void) scan_toks(false, true); load_tex_patterns(language_par, def_ref); flush_list(def_ref); } -@ `\.{\\prehyphenchar}', sets the |pre_break| character, and -`\.{\\posthyphenchar}' the |post_break| character. Their respective defaults are -ascii hyphen ("-") and zero (nul). +@ `\.{\\prehyphenchar}', sets the |pre_break| character, and `\.{\\posthyphenchar}' the +|post_break| character. Their respective defaults are ascii hyphen ("-") and zero (nul). @c void new_pre_hyphen_char(void) @@ -1169,9 +1177,8 @@ void new_post_hyphen_char(void) set_post_hyphen_char(language_par, cur_val); } -@ `\.{\\preexhyphenchar}', sets the |pre_break| character, and -`\.{\\postexhyphenchar}' the |post_break| character. Their defaults are both zero -(nul). +@ `\.{\\preexhyphenchar}', sets the |pre_break| character, and `\.{\\postexhyphenchar}' the +|post_break| character. Their defaults are both zero (nul). @c void new_pre_exhyphen_char(void) diff --git a/Build/source/texk/web2c/luatexdir/lua/lauxlib_bridge.h b/Build/source/texk/web2c/luatexdir/lua/lauxlib_bridge.h index d71a6786845..802ed6f6394 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lauxlib_bridge.h +++ b/Build/source/texk/web2c/luatexdir/lua/lauxlib_bridge.h @@ -36,6 +36,5 @@ LUA_API int lua_compare (lua_State *L, int index1, int index2, int op); #endif #define luaL_newlibtable(L,l) lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1) -#define luaL_newlib(L,l) (luaL_newlibtable(L,l), luaL_setfuncs(L,l,0)) #endif diff --git a/Build/source/texk/web2c/luatexdir/lua/lcallbacklib.c b/Build/source/texk/web2c/luatexdir/lua/lcallbacklib.c index 7944fdfd8a5..adb1ffd52e2 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lcallbacklib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lcallbacklib.c @@ -54,7 +54,7 @@ static const char *const callbacknames[] = { "pre_output_filter", "buildpage_filter", "hpack_filter", "vpack_filter", - "char_exists", + "glyph_not_found", "hyphenate", "ligaturing", "kerning", @@ -75,6 +75,7 @@ static const char *const callbacknames[] = { "call_edit", "build_page_insert", "glyph_stream_provider", + "finish_synctex_callback", NULL }; diff --git a/Build/source/texk/web2c/luatexdir/lua/lepdflib.cc b/Build/source/texk/web2c/luatexdir/lua/lepdflib.cc index 7250ffd1863..cac1bd024b0 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lepdflib.cc +++ b/Build/source/texk/web2c/luatexdir/lua/lepdflib.cc @@ -21,7 +21,9 @@ #include "image/epdf.h" - +// Patches for the new poppler 0.59 from +// https://www.mail-archive.com/arch-commits@archlinux.org/msg357548.html +// with some modifications to comply the poppler API. // define DEBUG @@ -253,6 +255,12 @@ static int l_new_Attribute(lua_State * L) lua_settable(L,-3) +#define OBJECT_TYPE(name) \ + lua_pushstring(L, #name); \ + lua_pushinteger(L, (int)name); \ + lua_settable(L,-3) + + #define STRUCTELEMENT_TYPE_ENTRY(name) \ lua_pushstring(L, #name); \ lua_pushinteger(L, StructElement::name); \ @@ -306,6 +314,28 @@ static int l_Attribute_Type(lua_State * L) { return 1; } +static int l_Object_Type(lua_State * L) { + lua_createtable(L,0,16);/*nr of ObjType values*/ ; + OBJECT_TYPE(objBool); + OBJECT_TYPE(objInt); + OBJECT_TYPE(objReal); + OBJECT_TYPE(objString); + OBJECT_TYPE(objName); + OBJECT_TYPE(objNull); + OBJECT_TYPE(objArray); + OBJECT_TYPE(objDict); + OBJECT_TYPE(objStream); + OBJECT_TYPE(objRef); + OBJECT_TYPE(objCmd); + OBJECT_TYPE(objError); + OBJECT_TYPE(objEOF); + OBJECT_TYPE(objNone); + OBJECT_TYPE(objInt64); + OBJECT_TYPE(objDead); + return 1; +} + + static int l_StructElement_Type(lua_State * L) { lua_createtable (L, 0, 50); STRUCTELEMENT_TYPE_ENTRY(Document); @@ -398,14 +428,136 @@ static int l_new_Dict(lua_State * L) static int l_new_Object(lua_State * L) { udstruct *uout; + int n = lua_gettop(L); // number of arguments uout = new_Object_userdata(L); - uout->d = new Object(); // automatic init to type "none" - uout->atype = ALLOC_LEPDF; - uout->pc = 0; - uout->pd = NULL; // not connected to any PDFDoc + switch(n) { + case 0: + uout->d = new Object(); // automatic init to type "none" + uout->atype = ALLOC_LEPDF; + uout->pc = 0; + uout->pd = NULL; // not connected to any PDFDoc + break; + case 1: + if (lua_isboolean (L,1)) { + uout->d = new Object(lua_toboolean(L, 1)? gTrue : gFalse); + uout->atype = ALLOC_LEPDF; + uout->pc = 0; + uout->pd = NULL; + } else if (lua_isnumber (L,1)) { + double d = lua_tonumber(L,1); + // Missed :Object(long long int64gA) + if (d==((int)d)) { + uout->d = new Object((int)d); + } else { + uout->d = new Object(d); + } + uout->atype = ALLOC_LEPDF; + uout->pc = 0; + uout->pd = NULL; + } else if (lua_isstring (L,1)){ + GooString *gs; + const char *s; + size_t len; + s = luaL_checklstring(L, 2, &len); + gs = new GooString(s, len); + uout->d = new Object(gs); + uout->atype = ALLOC_LEPDF; + uout->pc = 0; + uout->pd = NULL; + } else if (luaL_testudata(L,1,M_Array)){ + udstruct *u; + Array *a; + u = (udstruct *) luaL_checkudata(L, 1, M_Array); + a = (Array *)u->d; + uout->d = new Object(a); + uout->atype = ALLOC_LEPDF; + uout->pc = 0; + uout->pd = NULL; + } else if (luaL_testudata(L,1,M_Dict)){ + udstruct *u; + Dict *d; + u = (udstruct *) luaL_checkudata(L, 1, M_Dict); + d = (Dict *)u->d; + uout->d = new Object(d); + uout->atype = ALLOC_LEPDF; + uout->pc = 0; + uout->pd = NULL; + } else if (luaL_testudata(L,1,M_Stream)){ + udstruct *u; + Stream *s; + u = (udstruct *) luaL_checkudata(L, 1, M_Stream); + s = (Stream *)u->d; + *((Object *) uout->d) = Object(s); + } else + luaL_error(L, "Invalid/unsupported value for Object constructor"); + break; + case 2: + if (lua_isnumber (L,1) && lua_isnumber (L,2)) { + double numA = lua_tonumber(L,1); + double genA = lua_tonumber(L,2); + if ( ((numA)==(int)(numA)) && ((genA)==(int)(genA)) ){ + uout->d = new Object((int)(numA), (int)(genA)); + uout->atype = ALLOC_LEPDF; + uout->pc = 0; + uout->pd = NULL; + } + } else if (lua_isnumber (L,1) && (lua_isstring(L,2)|| lua_isnoneornil(L,2))) { + double d_typeA = lua_tonumber(L,1); + int typeA = (int)(d_typeA); + if (d_typeA==typeA){ + switch((int)(typeA)) { + case objBool: + case objInt: + case objReal: + case objString: + case objName: + case objNull: + case objArray: + case objDict: + case objStream: + case objRef: + case objCmd: + case objError: + case objEOF: + case objNone: + case objInt64: + case objDead: + if (lua_isstring(L,2)) + uout->d = new Object((ObjType)(typeA), luaL_checkstring(L, 2)); + else + uout->d = new Object((ObjType)(typeA)); + uout->atype = ALLOC_LEPDF; + uout->pc = 0; + uout->pd = NULL; + + break; + default: + luaL_error(L, "Invalid values for Object constructor"); + break; + }//switch((int)(d)) + } else // (d_typeA)!=(typeA) + luaL_error(L, "Invalid/unsupported values for Object constructor"); + } // if (lua_isnumber (L,1) && (lua_isstring(L,2)|| lua_isnoneornil(L,2))) + break; + default: + luaL_error(L, "Invalid specification for Object constructor"); + } + lua_settop(L,1); return 1; } +// static int l_new_Object(lua_State * L) +// { +// udstruct *uout; +// uout = new_Object_userdata(L); +// uout->d = new Object(); // automatic init to type "none" +// uout->atype = ALLOC_LEPDF; +// uout->pc = 0; +// uout->pd = NULL; // not connected to any PDFDoc +// return 1; +// } + + // PDFRectangle see Page.h static int l_new_PDFRectangle(lua_State * L) @@ -429,6 +581,7 @@ static const struct luaL_Reg epdflib_f[] = { {"AttributeOwner_Type",l_AttributeOwner_Type}, {"Dict", l_new_Dict}, {"Object", l_new_Object}, + {"Object_Type", l_Object_Type}, {"PDFRectangle", l_new_PDFRectangle}, {NULL, NULL} // sentinel }; @@ -538,7 +691,7 @@ static int m_##in##_##function(lua_State * L) \ pdfdoc_changed_error(L); \ uout = new_Object_userdata(L); \ uout->d = new Object(); \ - ((in *) uin->d)->function((Object *) uout->d); \ + *((Object *)uout->d) = ((in *) uin->d)->function(); \ uout->atype = ALLOC_LEPDF; \ uout->pc = uin->pc; \ uout->pd = uin->pd; \ @@ -665,30 +818,27 @@ static const struct luaL_Reg Annots_m[] = { //********************************************************************** // Array - -static int m_Array_incRef(lua_State * L) -{ - int i; - udstruct *uin; - uin = (udstruct *) luaL_checkudata(L, 1, M_Array); - if (uin->pd != NULL && uin->pd->pc != uin->pc) - pdfdoc_changed_error(L); - i = ((Array *) uin->d)->incRef(); - lua_pushinteger(L, i); - return 1; -} - -static int m_Array_decRef(lua_State * L) -{ - int i; - udstruct *uin; - uin = (udstruct *) luaL_checkudata(L, 1, M_Array); - if (uin->pd != NULL && uin->pd->pc != uin->pc) - pdfdoc_changed_error(L); - i = ((Array *) uin->d)->decRef(); - lua_pushinteger(L, i); - return 1; -} +// Now private +// static int m_Array_incRef(lua_State * L) +// { +// udstruct *uin; +// uin = (udstruct *) luaL_checkudata(L, 1, M_Array); +// if (uin->pd != NULL && uin->pd->pc != uin->pc) +// pdfdoc_changed_error(L); +// lua_pushinteger(L, 1); +// return 1; +// } +// Now private +// static int m_Array_decRef(lua_State * L) +// { +// int i; +// udstruct *uin; +// uin = (udstruct *) luaL_checkudata(L, 1, M_Array); +// if (uin->pd != NULL && uin->pd->pc != uin->pc) +// pdfdoc_changed_error(L); +// lua_pushinteger(L, 1); +// return 1; +// } m_poppler_get_INT(Array, getLength); @@ -702,7 +852,7 @@ static int m_Array_add(lua_State * L) if ((uin->pd != NULL && uin->pd->pc != uin->pc) || (uobj->pd != NULL && uobj->pd->pc != uobj->pc)) pdfdoc_changed_error(L); - ((Array *) uin->d)->add(((Object *) uobj->d)); + ((Array *) uin->d)->add(std::move(*((Object *) uobj->d))); return 0; } @@ -718,7 +868,7 @@ static int m_Array_get(lua_State * L) if (i > 0 && i <= len) { uout = new_Object_userdata(L); uout->d = new Object(); - ((Array *) uin->d)->get(i - 1, (Object *) uout->d); + *((Object *) uout->d) = ((Array *) uin->d)->get(i - 1); uout->atype = ALLOC_LEPDF; uout->pc = uin->pc; uout->pd = uin->pd; @@ -739,7 +889,7 @@ static int m_Array_getNF(lua_State * L) if (i > 0 && i <= len) { uout = new_Object_userdata(L); uout->d = new Object(); - ((Array *) uin->d)->getNF(i - 1, (Object *) uout->d); + *((Object *) uout->d) = ((Array *) uin->d)->getNF(i - 1); uout->atype = ALLOC_LEPDF; uout->pc = uin->pc; uout->pd = uin->pd; @@ -773,8 +923,8 @@ static int m_Array_getString(lua_State * L) m_poppler__tostring(Array); static const struct luaL_Reg Array_m[] = { - {"incRef", m_Array_incRef}, - {"decRef", m_Array_decRef}, + // {"incRef", m_Array_incRef},// Now private + // {"decRef", m_Array_decRef},// Now private {"getLength", m_Array_getLength}, {"add", m_Array_add}, {"get", m_Array_get}, @@ -950,30 +1100,26 @@ static const struct luaL_Reg Catalog_m[] = { //********************************************************************** // Dict - -static int m_Dict_incRef(lua_State * L) -{ - int i; - udstruct *uin; - uin = (udstruct *) luaL_checkudata(L, 1, M_Dict); - if (uin->pd != NULL && uin->pd->pc != uin->pc) - pdfdoc_changed_error(L); - i = ((Dict *) uin->d)->incRef(); - lua_pushinteger(L, i); - return 1; -} - -static int m_Dict_decRef(lua_State * L) -{ - int i; - udstruct *uin; - uin = (udstruct *) luaL_checkudata(L, 1, M_Dict); - if (uin->pd != NULL && uin->pd->pc != uin->pc) - pdfdoc_changed_error(L); - i = ((Dict *) uin->d)->decRef(); - lua_pushinteger(L, i); - return 1; -} +// Now private +// static int m_Dict_incRef(lua_State * L) +// { +// udstruct *uin; +// uin = (udstruct *) luaL_checkudata(L, 1, M_Dict); +// if (uin->pd != NULL && uin->pd->pc != uin->pc) +// pdfdoc_changed_error(L); +// lua_pushinteger(L, 1); +// return 1; +// } +// Now private +// static int m_Dict_decRef(lua_State * L) +// { +// udstruct *uin; +// uin = (udstruct *) luaL_checkudata(L, 1, M_Dict); +// if (uin->pd != NULL && uin->pd->pc != uin->pc) +// pdfdoc_changed_error(L); +// lua_pushinteger(L, 1); +// return 1; +// } m_poppler_get_INT(Dict, getLength); @@ -986,7 +1132,7 @@ static int m_Dict_add(lua_State * L) pdfdoc_changed_error(L); s = copyString(luaL_checkstring(L, 2)); uobj = (udstruct *) luaL_checkudata(L, 3, M_Object); - ((Dict *) uin->d)->add(s, ((Object *) uobj->d)); + ((Dict *) uin->d)->add(s, std::move(*((Object *) uobj->d))); return 0; } @@ -999,7 +1145,7 @@ static int m_Dict_set(lua_State * L) pdfdoc_changed_error(L); s = luaL_checkstring(L, 2); uobj = (udstruct *) luaL_checkudata(L, 3, M_Object); - ((Dict *) uin->d)->set(s, ((Object *) uobj->d)); + ((Dict *) uin->d)->set(s, std::move(*((Object *) uobj->d))); return 0; } @@ -1027,7 +1173,7 @@ static int m_Dict_lookup(lua_State * L) s = luaL_checkstring(L, 2); uout = new_Object_userdata(L); uout->d = new Object(); - ((Dict *) uin->d)->lookup(s, (Object *) uout->d); + *((Object *) uout->d) = ((Dict *) uin->d)->lookup(s); uout->atype = ALLOC_LEPDF; uout->pc = uin->pc; uout->pd = uin->pd; @@ -1044,7 +1190,7 @@ static int m_Dict_lookupNF(lua_State * L) s = luaL_checkstring(L, 2); uout = new_Object_userdata(L); uout->d = new Object(); - ((Dict *) uin->d)->lookupNF(s, (Object *) uout->d); + *((Object *) uout->d) = ((Dict *) uin->d)->lookupNF(s); uout->atype = ALLOC_LEPDF; uout->pc = uin->pc; uout->pd = uin->pd; @@ -1096,7 +1242,7 @@ static int m_Dict_getVal(lua_State * L) if (i > 0 && i <= len) { uout = new_Object_userdata(L); uout->d = new Object(); - ((Dict *) uin->d)->getVal(i - 1, (Object *) uout->d); + *((Object *) uout->d) = ((Dict *) uin->d)->getVal(i - 1); uout->atype = ALLOC_LEPDF; uout->pc = uin->pc; uout->pd = uin->pd; @@ -1117,7 +1263,7 @@ static int m_Dict_getValNF(lua_State * L) if (i > 0 && i <= len) { uout = new_Object_userdata(L); uout->d = new Object(); - ((Dict *) uin->d)->getValNF(i - 1, (Object *) uout->d); + *((Object *) uout->d) = ((Dict *) uin->d)->getValNF(i - 1); uout->atype = ALLOC_LEPDF; uout->pc = uin->pc; uout->pd = uin->pd; @@ -1131,8 +1277,8 @@ m_poppler_check_string(Dict, hasKey); m_poppler__tostring(Dict); static const struct luaL_Reg Dict_m[] = { - {"incRef", m_Dict_incRef}, - {"decRef", m_Dict_decRef}, + // {"incRef", m_Dict_incRef},// Now private + // {"decRef", m_Dict_decRef},// Now private {"getLength", m_Dict_getLength}, {"add", m_Dict_add}, {"set", m_Dict_set}, @@ -1381,9 +1527,9 @@ static int m_Object_initBool(lua_State * L) pdfdoc_changed_error(L); luaL_checktype(L, 2, LUA_TBOOLEAN); if (lua_toboolean(L, 2) != 0) - ((Object *) uin->d)->initBool(gTrue); + *((Object *) uin->d) = Object(gTrue); else - ((Object *) uin->d)->initBool(gFalse); + *((Object *) uin->d) = Object(gFalse); return 0; } @@ -1395,7 +1541,7 @@ static int m_Object_initInt(lua_State * L) if (uin->pd != NULL && uin->pd->pc != uin->pc) pdfdoc_changed_error(L); i = luaL_checkint(L, 2); - ((Object *) uin->d)->initInt(i); + *((Object *) uin->d) = Object(i); return 0; } @@ -1407,7 +1553,7 @@ static int m_Object_initReal(lua_State * L) if (uin->pd != NULL && uin->pd->pc != uin->pc) pdfdoc_changed_error(L); d = luaL_checknumber(L, 2); - ((Object *) uin->d)->initReal(d); + *((Object *) uin->d) = Object(d); return 0; } @@ -1422,7 +1568,7 @@ static int m_Object_initString(lua_State * L) pdfdoc_changed_error(L); s = luaL_checklstring(L, 2, &len); gs = new GooString(s, len); - ((Object *) uin->d)->initString(gs); + *((Object *) uin->d) = Object(gs); return 0; } @@ -1434,7 +1580,7 @@ static int m_Object_initName(lua_State * L) if (uin->pd != NULL && uin->pd->pc != uin->pc) pdfdoc_changed_error(L); s = luaL_checkstring(L, 2); - ((Object *) uin->d)->initName(s); + *((Object *) uin->d) = Object(objName, s); return 0; } @@ -1444,13 +1590,14 @@ static int m_Object_initNull(lua_State * L) uin = (udstruct *) luaL_checkudata(L, 1, M_Object); if (uin->pd != NULL && uin->pd->pc != uin->pc) pdfdoc_changed_error(L); - ((Object *) uin->d)->initNull(); + *((Object *) uin->d) = Object(objNull); return 0; } static int m_Object_initArray(lua_State * L) { udstruct *uin, *uxref; + Array *a; uin = (udstruct *) luaL_checkudata(L, 1, M_Object); uxref = (udstruct *) luaL_checkudata(L, 2, M_XRef); if (uin->pd != NULL && uxref->pd != NULL && uin->pd != uxref->pd) @@ -1458,7 +1605,8 @@ static int m_Object_initArray(lua_State * L) if ((uin->pd != NULL && uin->pd->pc != uin->pc) || (uxref->pd != NULL && uxref->pd->pc != uxref->pc)) pdfdoc_changed_error(L); - ((Object *) uin->d)->initArray((XRef *) uxref->d); + a = new Array((XRef *) uxref->d); + *((Object *) uin->d) = Object(a); return 0; } @@ -1469,6 +1617,7 @@ static int m_Object_initArray(lua_State * L) static int m_Object_initDict(lua_State * L) { udstruct *uin, *uxref; + Dict *d; uin = (udstruct *) luaL_checkudata(L, 1, M_Object); uxref = (udstruct *) luaL_checkudata(L, 2, M_XRef); if (uin->pd != NULL && uxref->pd != NULL && uin->pd != uxref->pd) @@ -1476,7 +1625,8 @@ static int m_Object_initDict(lua_State * L) if ((uin->pd != NULL && uin->pd->pc != uin->pc) || (uxref->pd != NULL && uxref->pd->pc != uxref->pc)) pdfdoc_changed_error(L); - ((Object *) uin->d)->initDict((XRef *) uxref->d); + d = new Dict((XRef *) uxref->d); + *((Object *) uin->d) = Object(d); return 0; } @@ -1490,7 +1640,7 @@ static int m_Object_initStream(lua_State * L) if ((uin->pd != NULL && uin->pd->pc != uin->pc) || (ustream->pd != NULL && ustream->pd->pc != ustream->pc)) pdfdoc_changed_error(L); - ((Object *) uin->d)->initStream((Stream *) ustream->d); + *((Object *) uin->d) = Object((Stream *) ustream->d); return 0; } @@ -1503,7 +1653,7 @@ static int m_Object_initRef(lua_State * L) pdfdoc_changed_error(L); num = luaL_checkint(L, 2); gen = luaL_checkint(L, 3); - ((Object *) uin->d)->initRef(num, gen); + *((Object *) uin->d) = Object(num, gen); return 0; } @@ -1515,7 +1665,7 @@ static int m_Object_initCmd(lua_State * L) if (uin->pd != NULL && uin->pd->pc != uin->pc) pdfdoc_changed_error(L); s = luaL_checkstring(L, 2); - ((Object *) uin->d)->initCmd(CHARP_CAST s); + *((Object *) uin->d) = Object(objCmd, CHARP_CAST s); return 0; } @@ -1525,7 +1675,7 @@ static int m_Object_initError(lua_State * L) uin = (udstruct *) luaL_checkudata(L, 1, M_Object); if (uin->pd != NULL && uin->pd->pc != uin->pc) pdfdoc_changed_error(L); - ((Object *) uin->d)->initError(); + *((Object *) uin->d) = Object(objError); return 0; } @@ -1535,7 +1685,7 @@ static int m_Object_initEOF(lua_State * L) uin = (udstruct *) luaL_checkudata(L, 1, M_Object); if (uin->pd != NULL && uin->pd->pc != uin->pc) pdfdoc_changed_error(L); - ((Object *) uin->d)->initEOF(); + *((Object *) uin->d) = Object(objEOF); return 0; } @@ -1551,7 +1701,7 @@ static int m_Object_fetch(lua_State * L) pdfdoc_changed_error(L); uout = new_Object_userdata(L); uout->d = new Object(); - ((Object *) uin->d)->fetch((XRef *) uxref->d, (Object *) uout->d); + *((Object *) uout->d) = ((Object *) uin->d)->fetch((XRef *) uxref->d); uout->atype = ALLOC_LEPDF; uout->pc = uin->pc; uout->pd = uin->pd; @@ -1816,7 +1966,7 @@ static int m_Object_arrayAdd(lua_State * L) pdfdoc_changed_error(L); if (!((Object *) uin->d)->isArray()) luaL_error(L, "Object is not an Array"); - ((Object *) uin->d)->arrayAdd((Object *) uobj->d); + ((Object *) uin->d)->arrayAdd(std::move(*((Object *) uobj->d))); return 0; } @@ -1833,7 +1983,7 @@ static int m_Object_arrayGet(lua_State * L) if (i > 0 && i <= len) { uout = new_Object_userdata(L); uout->d = new Object(); - ((Object *) uin->d)->arrayGet(i - 1, (Object *) uout->d); + *((Object *) uout->d) = ((Object *) uin->d)->arrayGet(i - 1); uout->atype = ALLOC_LEPDF; uout->pc = uin->pc; uout->pd = uin->pd; @@ -1857,7 +2007,7 @@ static int m_Object_arrayGetNF(lua_State * L) if (i > 0 && i <= len) { uout = new_Object_userdata(L); uout->d = new Object(); - ((Object *) uin->d)->arrayGetNF(i - 1, (Object *) uout->d); + *((Object *) uout->d) = ((Object *) uin->d)->arrayGetNF(i - 1); uout->atype = ALLOC_LEPDF; uout->pc = uin->pc; uout->pd = uin->pd; @@ -1897,7 +2047,7 @@ static int m_Object_dictAdd(lua_State * L) pdfdoc_changed_error(L); if (!((Object *) uin->d)->isDict()) luaL_error(L, "Object is not a Dict"); - ((Object *) uin->d)->dictAdd(copyString(s), (Object *) uobj->d); + ((Object *) uin->d)->dictAdd(copyString(s), std::move(*((Object *) uobj->d))); return 0; } @@ -1915,7 +2065,7 @@ static int m_Object_dictSet(lua_State * L) pdfdoc_changed_error(L); if (!((Object *) uin->d)->isDict()) luaL_error(L, "Object is not a Dict"); - ((Object *) uin->d)->dictSet(s, (Object *) uobj->d); + ((Object *) uin->d)->dictSet(s, std::move(*((Object *) uobj->d))); return 0; } @@ -1930,7 +2080,7 @@ static int m_Object_dictLookup(lua_State * L) if (((Object *) uin->d)->isDict()) { uout = new_Object_userdata(L); uout->d = new Object(); - ((Object *) uin->d)->dictLookup(s, (Object *) uout->d); + *((Object *) uout->d) = ((Object *) uin->d)->dictLookup(s); uout->atype = ALLOC_LEPDF; uout->pc = uin->pc; uout->pd = uin->pd; @@ -1950,7 +2100,7 @@ static int m_Object_dictLookupNF(lua_State * L) if (((Object *) uin->d)->isDict()) { uout = new_Object_userdata(L); uout->d = new Object(); - ((Object *) uin->d)->dictLookupNF(s, (Object *) uout->d); + *((Object *) uout->d) = ((Object *) uin->d)->dictLookupNF(s); uout->atype = ALLOC_LEPDF; uout->pc = uin->pc; uout->pd = uin->pd; @@ -1991,7 +2141,7 @@ static int m_Object_dictGetVal(lua_State * L) if (i > 0 && i <= len) { uout = new_Object_userdata(L); uout->d = new Object(); - ((Object *) uin->d)->dictGetVal(i - 1, (Object *) uout->d); + *((Object *) uout->d) = ((Object *) uin->d)->dictGetVal(i - 1); uout->atype = ALLOC_LEPDF; uout->pc = uin->pc; uout->pd = uin->pd; @@ -2015,7 +2165,7 @@ static int m_Object_dictGetValNF(lua_State * L) if (i > 0 && i <= len) { uout = new_Object_userdata(L); uout->d = new Object(); - ((Object *) uin->d)->dictGetValNF(i - 1, (Object *) uout->d); + *((Object *) uout->d) = ((Object *) uin->d)->dictGetValNF(i - 1); uout->atype = ALLOC_LEPDF; uout->pc = uin->pc; uout->pd = uin->pd; @@ -2243,7 +2393,7 @@ m_poppler_get_poppler(Page, Stream, getMetadata); m_poppler_get_poppler(Page, Dict, getPieceInfo); m_poppler_get_poppler(Page, Dict, getSeparationInfo); m_poppler_get_poppler(Page, Dict, getResourceDict); -m_poppler_get_OBJECT(Page, getAnnots); +m_poppler_get_OBJECT(Page, getAnnotsObject); m_poppler_get_OBJECT(Page, getContents); @@ -2270,7 +2420,7 @@ static const struct luaL_Reg Page_m[] = { {"getPieceInfo", m_Page_getPieceInfo}, {"getSeparationInfo", m_Page_getSeparationInfo}, {"getResourceDict", m_Page_getResourceDict}, - {"getAnnots", m_Page_getAnnots}, + {"getAnnotsObject", m_Page_getAnnotsObject}, {"getContents", m_Page_getContents}, {"__tostring", m_Page__tostring}, {NULL, NULL} // sentinel @@ -2520,7 +2670,7 @@ static int m_PDFDoc_getDocInfo(lua_State * L) if (((PdfDocument *) uin->d)->doc->getXRef()->isOk()) { uout = new_Object_userdata(L); uout->d = new Object(); - ((PdfDocument *) uin->d)->doc->getDocInfo((Object *) uout->d); + *((Object *) uout->d) = ((PdfDocument *) uin->d)->doc->getDocInfo(); uout->atype = ALLOC_LEPDF; uout->pc = uin->pc; uout->pd = uin->pd; @@ -2538,7 +2688,7 @@ static int m_PDFDoc_getDocInfoNF(lua_State * L) if (((PdfDocument *) uin->d)->doc->getXRef()->isOk()) { uout = new_Object_userdata(L); uout->d = new Object(); - ((PdfDocument *) uin->d)->doc->getDocInfoNF((Object *) uout->d); + *((Object *) uout->d) = ((PdfDocument *) uin->d)->doc->getDocInfoNF(); uout->atype = ALLOC_LEPDF; uout->pc = uin->pc; uout->pd = uin->pd; @@ -2841,7 +2991,7 @@ static int m_Attribute_getValue(lua_State * L) uout = new_Object_userdata(L); uout->d = new Object(); origin = (Object *) (((Attribute *) uin->d)->getValue()); - origin->copy ( ((Object *)uout->d) ); + *((Object *) uout->d) = origin->copy(); uout->atype = ALLOC_LEPDF; uout->pc = uin->pc; uout->pd = uin->pd; @@ -3320,7 +3470,8 @@ static int m_StructTreeRoot_findParentElement(lua_State * L) parent = root->findParentElement(i-1); if (parent != NULL) { uout = new_StructElement_userdata(L); - uout->d = new StructElement( *parent ); + // see https://isocpp.org/wiki/faq/const-correctness#aliasing-and-const + uout->d = (StructElement *) parent; uout->atype = ALLOC_LEPDF; uout->pc = uin->pc; uout->pd = uin->pd; @@ -3331,7 +3482,6 @@ static int m_StructTreeRoot_findParentElement(lua_State * L) static const struct luaL_Reg StructTreeRoot_m[] = { - {"findParentElement", m_StructTreeRoot_findParentElement}, {"getDoc",m_StructTreeRoot_getDoc}, {"getRoleMap",m_StructTreeRoot_getRoleMap}, {"getClassMap",m_StructTreeRoot_getClassMap}, @@ -3370,7 +3520,7 @@ static int m_XRef_fetch(lua_State * L) gen = luaL_checkint(L, 3); uout = new_Object_userdata(L); uout->d = new Object(); - ((XRef *) uin->d)->fetch(num, gen, (Object *) uout->d); + *((Object *) uout->d) = ((XRef *) uin->d)->fetch(num, gen); uout->atype = ALLOC_LEPDF; uout->pc = uin->pc; uout->pd = uin->pd; diff --git a/Build/source/texk/web2c/luatexdir/lua/lfontlib.c b/Build/source/texk/web2c/luatexdir/lua/lfontlib.c index 7e35d2360b7..0304be8bd11 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lfontlib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lfontlib.c @@ -155,15 +155,15 @@ static int frozenfont(lua_State * L) static int setfont(lua_State * L) { - int i = luaL_checkinteger(L, -2); + int t = lua_gettop(L); + int i = luaL_checkinteger(L,1); if (i) { - luaL_checktype(L, -1, LUA_TTABLE); + luaL_checktype(L, t, LUA_TTABLE); if (is_valid_font(i)) { - if (!(font_touched(i) || font_used(i))) { + if (! (font_touched(i) || font_used(i))) { font_from_lua(L, i); } else { - luaL_error(L, - "that font has been accessed already, changing it is forbidden"); + luaL_error(L, "that font has been accessed already, changing it is forbidden"); } } else { luaL_error(L, "that integer id is not a valid font"); @@ -172,10 +172,56 @@ static int setfont(lua_State * L) return 0; } +static int addcharacters(lua_State * L) +{ + int t = lua_gettop(L); + int i = luaL_checkinteger(L,1); + if (i) { + luaL_checktype(L, t, LUA_TTABLE); + if (is_valid_font(i)) { + characters_from_lua(L, i); + } else { + luaL_error(L, "that integer id is not a valid font"); + } + } + return 0; +} + +static int setexpansion(lua_State * L) +{ + int f = luaL_checkinteger(L,1); + if (f) { + if (is_valid_font(f)) { + int fstretch = luaL_checkinteger(L,2); + int fshrink = luaL_checkinteger(L,3); + int fstep = luaL_checkinteger(L,4); + set_expand_params(f, fstretch, fshrink, fstep); + } else { + luaL_error(L, "that integer id is not a valid font"); + } + } + return 0; +} + +/* font.define(id,table) */ +/* font.define(table) */ static int deffont(lua_State * L) { - int i = get_fontid(); + int i = 0; + int t = lua_gettop(L); + if (t == 2) { + i = lua_tointeger(L,1); + if ((i <= 0) || ! is_valid_font(i)) { + lua_pop(L, 1); /* pop the broken table */ + luaL_error(L, "font creation failed, invalid id passed"); + } + } else if (t == 1) { + i = get_fontid(); + } else { + luaL_error(L, "font creation failed, no table passed"); + return 0; + } luaL_checktype(L, -1, LUA_TTABLE); if (font_from_lua(L, i)) { lua_pushinteger(L, i); @@ -183,21 +229,25 @@ static int deffont(lua_State * L) } else { lua_pop(L, 1); /* pop the broken table */ delete_font(i); - luaL_error(L, "font creation failed"); + luaL_error(L, "font creation failed, error in table"); } return 0; /* not reached */ } /* this returns the expected (!) next fontid. */ +/* first arg true will keep the id */ + static int nextfontid(lua_State * L) { + int b = ((lua_gettop(L) == 1) && lua_toboolean(L,1)); int i = get_fontid(); lua_pushinteger(L, i); - delete_font(i); + if (b == 0) { + delete_font(i); + } return 1; } - static int getfont(lua_State * L) { int i = luaL_checkinteger(L, -1); @@ -207,7 +257,6 @@ static int getfont(lua_State * L) return 1; } - static int getfontid(lua_State * L) { if (lua_type(L, 1) == LUA_TSTRING) { @@ -228,7 +277,6 @@ static int getfontid(lua_State * L) return 1; } - static const struct luaL_Reg fontlib[] = { {"read_tfm", font_read_tfm}, {"read_vf", font_read_vf}, @@ -237,6 +285,8 @@ static const struct luaL_Reg fontlib[] = { {"each", tex_each_font}, {"getfont", getfont}, {"setfont", setfont}, + {"addcharacters", addcharacters}, + {"setexpansion", setexpansion}, {"define", deffont}, {"nextid", nextfontid}, {"id", getfontid}, diff --git a/Build/source/texk/web2c/luatexdir/lua/liolibext.c b/Build/source/texk/web2c/luatexdir/lua/liolibext.c index 958cbb67b43..7bd6fa4519b 100644 --- a/Build/source/texk/web2c/luatexdir/lua/liolibext.c +++ b/Build/source/texk/web2c/luatexdir/lua/liolibext.c @@ -29,11 +29,9 @@ #endif #include "lualib.h" - - #ifdef LuajitTeX /* luajit has its own way for io, which is a mix of */ -/* lua 5.1 and lua 5.2 . We use the stock luajit. */ +/* lua 5.1 and lua 5.2 . We use the stock luajit. */ #else /* ** {====================================================== @@ -61,7 +59,6 @@ /* }====================================================== */ - #if defined(LUA_USE_POSIX) #define l_fseek(f,o,w) fseeko(f,o,w) @@ -92,9 +89,6 @@ #endif/* #ifdef LuajitTeX */ - - - static FILE *tofile (lua_State *L) { #ifdef LuajitTeX FILE **f = luaL_checkudata(L,1,LUA_FILEHANDLE); @@ -110,6 +104,8 @@ static FILE *tofile (lua_State *L) { #endif } +#define uchar(c) ((unsigned char)(c)) + /* HH: A few helpers to avoid reading numbers as strings. For now we put them in their own namespace. We also have a few helpers that can make io functions tex friendly. @@ -125,6 +121,19 @@ static int readcardinal1(lua_State *L) { return 1; } +static int readcardinal1_s(lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + size_t p = luaL_checkinteger(L, 2) - 1; + if (p < 0 || p >= l) { + lua_pushnil(L); + } else { + int a = uchar(s[p]); + lua_pushinteger(L, a); + } + return 1; +} + static int readcardinal2(lua_State *L) { FILE *f = tofile(L); int a = getc(f); @@ -137,6 +146,20 @@ static int readcardinal2(lua_State *L) { return 1; } +static int readcardinal2_s(lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + size_t p = luaL_checkinteger(L, 2) - 1; + if (p < 0 || p+1 >= l) { + lua_pushnil(L); + } else { + int a = uchar(s[p++]); + int b = uchar(s[p]); + lua_pushinteger(L, 0x100 * a + b); + } + return 1; +} + static int readcardinal3(lua_State *L) { FILE *f = tofile(L); int a = getc(f); @@ -150,6 +173,21 @@ static int readcardinal3(lua_State *L) { return 1; } +static int readcardinal3_s(lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + size_t p = luaL_checkinteger(L, 2) - 1; + if (p < 0 || p+2 >= l) { + lua_pushnil(L); + } else { + int a = uchar(s[p++]); + int b = uchar(s[p++]); + int c = uchar(s[p]); + lua_pushinteger(L, 0x10000 * a + 0x100 * b + c); + } + return 1; +} + static int readcardinal4(lua_State *L) { FILE *f = tofile(L); int a = getc(f); @@ -164,6 +202,22 @@ static int readcardinal4(lua_State *L) { return 1; } +static int readcardinal4_s(lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + size_t p = luaL_checkinteger(L, 2) - 1; + if (p < 0 || p+3 >= l) { + lua_pushnil(L); + } else { + int a = uchar(s[p++]); + int b = uchar(s[p++]); + int c = uchar(s[p++]); + int d = uchar(s[p]); + lua_pushinteger(L,0x1000000 * a + 0x10000 * b + 0x100 * c + d); + } + return 1; +} + static int readinteger1(lua_State *L) { FILE *f = tofile(L); int a = getc(f); @@ -176,6 +230,22 @@ static int readinteger1(lua_State *L) { return 1; } +static int readinteger1_s(lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + size_t p = luaL_checkinteger(L, 2) - 1; + if (p < 0 || p >= l) { + lua_pushnil(L); + } else { + int a = uchar(s[p]); + if (a >= 0x80) + lua_pushinteger(L, a - 0x100); + else + lua_pushinteger(L, a); + } + return 1; +} + static int readinteger2(lua_State *L) { FILE *f = tofile(L); int a = getc(f); @@ -189,6 +259,23 @@ static int readinteger2(lua_State *L) { return 1; } +static int readinteger2_s(lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + size_t p = luaL_checkinteger(L, 2) - 1; + if (p < 0 || p+1 >= l) { + lua_pushnil(L); + } else { + int a = uchar(s[p++]); + int b = uchar(s[p]); + if (a >= 0x80) + lua_pushinteger(L, 0x100 * a + b - 0x10000); + else + lua_pushinteger(L, 0x100 * a + b); + } + return 1; +} + static int readinteger3(lua_State *L) { FILE *f = tofile(L); int a = getc(f); @@ -203,6 +290,24 @@ static int readinteger3(lua_State *L) { return 1; } +static int readinteger3_s(lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + size_t p = luaL_checkinteger(L, 2) - 1; + if (p < 0 || p+2 >= l) { + lua_pushnil(L); + } else { + int a = uchar(s[p++]); + int b = uchar(s[p++]); + int c = uchar(s[p]); + if (a >= 0x80) + lua_pushinteger(L, 0x10000 * a + 0x100 * b + c - 0x1000000); + else + lua_pushinteger(L, 0x10000 * a + 0x100 * b + c); + } + return 1; +} + static int readinteger4(lua_State *L) { FILE *f = tofile(L); int a = getc(f); @@ -218,6 +323,25 @@ static int readinteger4(lua_State *L) { return 1; } +static int readinteger4_s(lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + size_t p = luaL_checkinteger(L, 2) - 1; + if (p < 0 || p+3 >= l) { + lua_pushnil(L); + } else { + int a = uchar(s[p++]); + int b = uchar(s[p++]); + int c = uchar(s[p++]); + int d = uchar(s[p]); + if (a >= 0x80) + lua_pushinteger(L, 0x1000000 * a + 0x10000 * b + 0x100 * c + d - 0x100000000); + else + lua_pushinteger(L, 0x1000000 * a + 0x10000 * b + 0x100 * c + d); + } + return 1; +} + static int readfixed2(lua_State *L) { FILE *f = tofile(L); int a = getc(f); @@ -225,9 +349,26 @@ static int readfixed2(lua_State *L) { if (b == EOF) lua_pushnil(L); else if (a >= 0x80) - lua_pushinteger(L, a + b/0xFFFF - 0x100); + lua_pushinteger(L, (a - 0x100) + b/0x100); else - lua_pushinteger(L, a + b/0xFFFF); + lua_pushinteger(L, (a ) + b/0x100); + return 1; +} + +static int readfixed2_s(lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + size_t p = luaL_checkinteger(L, 2) - 1; + if (p < 0 || p+3 >= l) { + lua_pushnil(L); + } else { + int a = uchar(s[p++]); + int b = uchar(s[p]); + if (a >= 0x80) + lua_pushinteger(L, (a - 0x100) + b/0x100); + else + lua_pushinteger(L, (a ) + b/0x100); + } return 1; } @@ -240,15 +381,34 @@ static int readfixed4(lua_State *L) { if (d == EOF) lua_pushnil(L); else if (a >= 0x80) - lua_pushnumber(L, (0x1000000 * a + 0x10000 * b + 0x100 * c + d - 0x100000000)/65536.0); + lua_pushnumber(L, (0x100 * a + b - 0x10000) + (0x100 * c + d)/0x10000); else - lua_pushnumber(L, (0x1000000 * a + 0x10000 * b + 0x100 * c + d)/65536.0); + lua_pushnumber(L, (0x100 * a + b ) + (0x100 * c + d)/0x10000); /* from ff */ /* int n = 0x1000000 * a + 0x10000 * b + 0x100 * c + d; */ /* lua_pushnumber(L,(real) (n>>16) + ((n&0xffff)/65536.0)); */ return 1; } +static int readfixed4_s(lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + size_t p = luaL_checkinteger(L, 2) - 1; + if (p < 0 || p+3 >= l) { + lua_pushnil(L); + } else { + int a = uchar(s[p++]); + int b = uchar(s[p++]); + int c = uchar(s[p++]); + int d = uchar(s[p]); + if (a >= 0x80) + lua_pushnumber(L, (0x100 * a + b - 0x10000) + (0x100 * c + d)/0x10000); + else + lua_pushnumber(L, (0x100 * a + b ) + (0x100 * c + d)/0x10000); + } + return 1; +} + static int read2dot14(lua_State *L) { FILE *f = tofile(L); int a = getc(f); @@ -263,6 +423,21 @@ static int read2dot14(lua_State *L) { return 1; } +static int read2dot14_s(lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + size_t p = luaL_checkinteger(L, 2) - 1; + if (p < 0 || p+1 >= l) { + lua_pushnil(L); + } else { + int a = uchar(s[p++]); + int b = uchar(s[p]); + int n = 0x100 * a + b; + lua_pushnumber(L,(real) ((n<<16)>>(16+14)) + ((n&0x3fff)/16384.0)); + } + return 1; +} + static int getposition(lua_State *L) { FILE *f = tofile(L); long p = ftell(f); @@ -317,6 +492,28 @@ static int readbytetable(lua_State *L) { return 1; } +static int readbytetable_s(lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + size_t p = luaL_checkinteger(L, 2) - 1; + int n = lua_tointeger(L,3); + if (p < 0 || p >= l) { + lua_pushnil(L); + } else { + int i ; + if (p + n >= l) { + n = l - p ; + } + lua_createtable(L, n, 0); + for (i=1;i<=n;i++) { + int a = uchar(s[p++]); + lua_pushinteger(L, a); + lua_rawseti(L,-2,i); + } + } + return 1; +} + static int readbytes(lua_State *L) { FILE *f = tofile(L); int n = lua_tointeger(L,2); @@ -332,6 +529,27 @@ static int readbytes(lua_State *L) { return n; } +static int readbytes_s(lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + size_t p = luaL_checkinteger(L, 2) - 1; + int n = lua_tointeger(L,3); + if (p < 0 || p >= l) { + return 0; + } else { + int i ; + if (p + n >= l) { + n = l - p ; + } + lua_createtable(L, n, 0); + for (i=1;i<=n;i++) { + int a = uchar(s[p++]); + lua_pushinteger(L, a); + } + return n; + } +} + static int recordfilename(lua_State *L) { const char *fname = luaL_checkstring(L, 1); @@ -374,11 +592,17 @@ static int checkpermission(lua_State *L) lua_pushboolean(L,0); lua_pushliteral(L, "specific command execution disabled"); break; + case 1: + /* doesn't happen */ + lua_pushboolean(L,1); + lua_pushstring(L,filename); + break; case 2: lua_pushboolean(L,1); lua_pushstring(L,safecmd); break; default: + /* -1 */ lua_pushboolean(L,0); lua_pushliteral(L, "bad command line quoting"); break; @@ -444,7 +668,35 @@ static const luaL_Reg fiolib[] = { {NULL, NULL} }; +static const luaL_Reg siolib[] = { + { "readcardinal1", readcardinal1_s }, + { "readcardinal2", readcardinal2_s }, + { "readcardinal3", readcardinal3_s }, + { "readcardinal4", readcardinal4_s }, + { "readinteger1", readinteger1_s }, + { "readinteger2", readinteger2_s }, + { "readinteger3", readinteger3_s }, + { "readinteger4", readinteger4_s }, + { "readfixed2", readfixed2_s }, + { "readfixed4", readfixed4_s }, + { "read2dot14", read2dot14_s }, + { "readbytes", readbytes_s }, + { "readbytetable", readbytetable_s }, + /* done */ + {NULL, NULL} +}; + +/* + The sio helpers are experimental and might be handy at some point. Speed-wise + there is no gain over file access because with ssd and caching we basically + operate in memory too. We keep them as complement to the file ones. I did + consider using an userdata object for the position etc but some simple tests + demonstrated that there is no real gain and the current ones permits to wrap + up whatever interface one likes. +*/ + int luaopen_fio(lua_State *L) { luaL_register(L, "fio", fiolib); + luaL_register(L, "sio", siolib); return 1; } diff --git a/Build/source/texk/web2c/luatexdir/lua/llualib.c b/Build/source/texk/web2c/luatexdir/lua/llualib.c index c094c8ed1d1..461c211472d 100644 --- a/Build/source/texk/web2c/luatexdir/lua/llualib.c +++ b/Build/source/texk/web2c/luatexdir/lua/llualib.c @@ -286,8 +286,7 @@ static int set_luaname(lua_State * L) static int get_luaname(lua_State * L) { - int k; - k = (int) luaL_checkinteger(L, 2); + int k = (int) luaL_checkinteger(L, 2); if (k > 65535 || k < 0) { /* error */ lua_pushnil(L); @@ -306,6 +305,13 @@ static int lua_functions_get_table(lua_State * L) /* hh */ return 1; } +static int new_table(lua_State * L) /* hh */ +{ + int i = (int) luaL_checkinteger(L, 1); + int h = (int) luaL_checkinteger(L, 2); + lua_createtable(L,i,h); + return 1; +} static const struct luaL_Reg lualib[] = { /* *INDENT-OFF* */ @@ -313,6 +319,7 @@ static const struct luaL_Reg lualib[] = { {"setluaname", set_luaname}, {"getbytecode", get_bytecode}, {"setbytecode", set_bytecode}, + {"newtable", new_table}, {"get_functions_table",lua_functions_get_table}, /* *INDENT-ON* */ {NULL, NULL} /* sentinel */ diff --git a/Build/source/texk/web2c/luatexdir/lua/lnodelib.c b/Build/source/texk/web2c/luatexdir/lua/lnodelib.c index 49929fa2792..5ee46a7269d 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lnodelib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lnodelib.c @@ -268,6 +268,19 @@ static int get_valid_node_subtype_id(lua_State * L, int n) return i; } +/* enable fixer ... more fixers can be added in the future */ + +static int lua_nodelib_fix_node_lists(lua_State * L) +{ + if (lua_type(L, -1) == LUA_TBOOLEAN) { + fix_node_lists = lua_toboolean(L,-1); + } else if (lua_type(L, -1) == LUA_TNUMBER) { + fix_node_lists = lua_tointeger(L,-1); + } + return 0; +} + + /* two simple helpers to speed up and simplify lua code (replaced by getnext and getprev) */ static int lua_nodelib_next(lua_State * L) @@ -438,6 +451,8 @@ static int lua_nodelib_direct_getfont(lua_State * L) lua_pushinteger(L, font(n)); } else if ((t == math_char_node) || (t == math_text_char_node)) { lua_pushinteger(L, fam_fnt(math_fam(n), 0)); + } else if (t == delim_node) { + lua_pushinteger(L, fam_fnt(small_fam(n), 0)); } else { lua_pushnil(L); } @@ -473,6 +488,8 @@ static int lua_nodelib_direct_setfont(lua_State * L) lua_pushinteger(L, font(*n)); } else if ((t == math_char_node) || (t == math_text_char_node)) { lua_pushinteger(L, fam_fnt(math_fam(*n), 0)); + } else if (t == delim_node) { + lua_pushinteger(L, fam_fnt(small_fam(*n), 0)); } else { lua_pushnil(L); } @@ -492,6 +509,27 @@ static int lua_nodelib_direct_getchar(lua_State * L) lua_pushinteger(L, character(n)); } else if ((t == math_char_node) || (t == math_text_char_node)) { lua_pushinteger(L, math_character(n)); + } else if (t == delim_node) { + /* used in wide fonts */ + lua_pushinteger(L, small_char(n)); + } else { + lua_pushnil(L); + } + } else { + lua_pushnil(L); + } + return 1; +} + +static int lua_nodelib_direct_getfam(lua_State * L) +{ + halfword n = lua_tointeger(L, 1); + if (n) { + halfword t = type(n); + if ((t == math_char_node) || (t == math_text_char_node)) { + lua_pushinteger(L, math_fam(n)); + } else if (t == delim_node) { + lua_pushinteger(L, small_fam(n)); } else { lua_pushnil(L); } @@ -510,23 +548,47 @@ static int lua_nodelib_direct_setchar(lua_State * L) character(n) = (halfword) lua_tointeger(L, 2); } else if ((t == math_char_node) || (t == math_text_char_node)) { math_character(n) = (halfword) lua_tointeger(L, 2); + } else if (t == delim_node) { + /* used in wide fonts */ + small_char(n) = (halfword) lua_tointeger(L, 2); } } return 0; } +static int lua_nodelib_direct_setfam(lua_State * L) +{ + halfword n = lua_tointeger(L, 1); + if ((n) && (lua_type(L, 2) == LUA_TNUMBER)) { + halfword t = type(n); + if ((t == math_char_node) || (t == math_text_char_node)) { + math_fam(n) = (halfword) lua_tointeger(L, 2); + } else if (t == delim_node) { + small_fam(n) = (halfword) lua_tointeger(L, 2); + } + } + return 0; +} /* node.getchar */ static int lua_nodelib_getchar(lua_State * L) { halfword *n = lua_touserdata(L, 1); - if ( (n == NULL) || (! lua_getmetatable(L,1)) ) { + if ((n == NULL) || (! lua_getmetatable(L,1))) { lua_pushnil(L); - } else if (type(*n) == glyph_node) { - lua_pushinteger(L, character(*n)); - } else if ((type(*n) == math_char_node) || (type(*n) == math_text_char_node)) { - lua_pushinteger(L, math_character(*n)); + } else { + halfword t = type(*n); + if (t == glyph_node) { + lua_pushinteger(L, character(*n)); + } else if ((t == math_char_node) || (t == math_text_char_node)) { + lua_pushinteger(L, math_character(*n)); + } else if (t == delim_node) { + /* used in wide fonts */ + lua_pushinteger(L, small_char(*n)); + } else { + lua_pushnil(L); + } } return 1; } @@ -673,7 +735,7 @@ static int lua_nodelib_direct_getnucleus(lua_State * L) if (n) { halfword t = type(n); if (t == simple_noad || t == accent_noad || t == radical_noad) { - lua_pushinteger(L, nucleus(n)); + nodelib_pushdirect_or_nil(nucleus(n)); return 1; } } @@ -703,7 +765,7 @@ static int lua_nodelib_direct_getsub(lua_State * L) if (n) { halfword t = type(n); if (t == simple_noad || t == accent_noad || t == radical_noad) { - lua_pushinteger(L, subscr(n)); + nodelib_pushdirect_or_nil(subscr(n)); return 1; } } @@ -733,7 +795,7 @@ static int lua_nodelib_direct_getsup(lua_State * L) if (n) { halfword t = type(n); if (t == simple_noad || t == accent_noad || t == radical_noad) { - lua_pushinteger(L, supscr(n)); + nodelib_pushdirect_or_nil(supscr(n)); return 1; } } @@ -785,7 +847,7 @@ static int lua_nodelib_direct_setkern(lua_State * L) halfword t = type(n); if (t == kern_node || t == margin_kern_node) { if (lua_type(L, 2) == LUA_TNUMBER) { - width(n) = (halfword) lua_tointeger(L, 2); + width(n) = (halfword) lua_roundnumber(L, 2); } else { width(n) = 0; } @@ -794,7 +856,7 @@ static int lua_nodelib_direct_setkern(lua_State * L) } } else if (t == math_node) { if (lua_type(L, 2) == LUA_TNUMBER) { - surround(n) = (halfword) lua_tointeger(L, 2); + surround(n) = (halfword) lua_roundnumber(L, 2); } else { surround(n) = 0; } @@ -867,10 +929,10 @@ static int lua_nodelib_direct_setoffsets(lua_State * L) halfword n = lua_tointeger(L, 1); if ((n) && (type(n) == glyph_node)) { if ((lua_type(L, 2) == LUA_TNUMBER)) { - x_displace(n) = (halfword) lua_tointeger(L, 2); + x_displace(n) = (halfword) lua_roundnumber(L, 2); } if ((lua_type(L, 3) == LUA_TNUMBER)) { - y_displace(n) = (halfword) lua_tointeger(L, 3); + y_displace(n) = (halfword) lua_roundnumber(L, 3); } } return 0; @@ -1071,6 +1133,8 @@ static int lua_nodelib_direct_getlist(lua_State * L) nodelib_pushdirect_or_nil_alink(list_ptr(n)); } else if ((t == sub_box_node) || (t == sub_mlist_node)) { nodelib_pushdirect_or_nil_alink(math_list(n)); + } else if (t == ins_node) { + nodelib_pushdirect_or_nil_alink(ins_ptr(n)); } else if (t == adjust_node) { nodelib_pushdirect_or_nil_alink(adjust_ptr(n)); } else { @@ -1097,6 +1161,12 @@ static int lua_nodelib_direct_setlist(lua_State * L) } else { math_list(n) = null; } + } else if (t == ins_node) { + if (lua_type(L,2) == LUA_TNUMBER) { + ins_ptr(n) = (halfword) lua_tointeger(L, 2); + } else { + ins_ptr(n) = null; + } } else if (t == adjust_node) { if (lua_type(L,2) == LUA_TNUMBER) { adjust_ptr(n) = (halfword) lua_tointeger(L, 2); @@ -1120,6 +1190,10 @@ static int lua_nodelib_direct_setlist(lua_State * L) fast_metatable_or_nil_alink(list_ptr(*n)); } else if ((type(*n) == sub_box_node) || (type(*n) == sub_mlist_node)) { fast_metatable_or_nil_alink(math_list(*n)); + } else if (type(*n) == ins_node) { + fast_metatable_or_nil_alink(ins_ptr(*n)); + } else if (type(*n) == adjust_node) { + fast_metatable_or_nil_alink(adjust_ptr(*n)); } else { lua_pushnil(L); } @@ -2999,7 +3073,7 @@ static int lua_nodelib_direct_setwidth(lua_State * L) if (t == hlist_node || t == vlist_node || t == rule_node || t == glue_node || t == glue_spec_node || t == math_node || t == kern_node || t == margin_kern_node || t == ins_node || t == unset_node) { if (lua_type(L, 2) == LUA_TNUMBER) { - width(n) = lua_tointeger(L,2); + width(n) = lua_roundnumber(L,2); } else { width(n) = 0; } @@ -3035,7 +3109,7 @@ static int lua_nodelib_direct_setheight(lua_State * L) halfword t = type(n); if (t == hlist_node || t == vlist_node || t == rule_node || t == unset_node) { if (lua_type(L, 2) == LUA_TNUMBER) { - height(n) = lua_tointeger(L,2); + height(n) = lua_roundnumber(L,2); } else { height(n) = 0; } @@ -3071,7 +3145,7 @@ static int lua_nodelib_direct_setdepth(lua_State * L) halfword t = type(n); if (t == hlist_node || t == vlist_node || t == rule_node || t == unset_node) { if (lua_type(L, 2) == LUA_TNUMBER) { - depth(n) = lua_tointeger(L,2); + depth(n) = lua_roundnumber(L,2); } else { depth(n) = 0; } @@ -3104,7 +3178,7 @@ static int lua_nodelib_direct_setshift(lua_State * L) halfword t = type(n); if (t == hlist_node || t == vlist_node) { if (lua_type(L, 2) == LUA_TNUMBER) { - shift_amount(n) = lua_tointeger(L,2); + shift_amount(n) = lua_roundnumber(L,2); } else { shift_amount(n) = 0; } @@ -3129,6 +3203,11 @@ static int lua_nodelib_direct_get_glue(lua_State * L) lua_pushinteger(L,stretch_order(n)); lua_pushinteger(L,shrink_order(n)); return 5; + } else if (t == hlist_node || t == vlist_node) { + lua_pushnumber(L, (double) glue_set(n)); /* float */ + lua_pushinteger(L,glue_order(n)); + lua_pushinteger(L,glue_sign(n)); + return 3; } } return 0; @@ -3146,6 +3225,11 @@ static int lua_nodelib_direct_set_glue(lua_State * L) shrink(n) = ((top > 3 && lua_type(L, 4) == LUA_TNUMBER)) ? lua_roundnumber(L,4) : 0; stretch_order(n) = ((top > 4 && lua_type(L, 5) == LUA_TNUMBER)) ? lua_tointeger(L,5) : 0; shrink_order(n) = ((top > 5 && lua_type(L, 6) == LUA_TNUMBER)) ? lua_tointeger(L,6) : 0; + } else if (t == hlist_node || t == vlist_node) { + glue_set(n) = ((top > 1 && lua_type(L, 2) == LUA_TNUMBER)) ? (glue_ratio) lua_tonumber(L,2) : 0; + glue_order(n) = ((top > 2 && lua_type(L, 3) == LUA_TNUMBER)) ? lua_tointeger(L,3) : 0; + glue_sign(n) = ((top > 3 && lua_type(L, 4) == LUA_TNUMBER)) ? lua_tointeger(L,4) : 0; + return 3; } } return 0; @@ -3159,9 +3243,12 @@ static int lua_nodelib_direct_is_zero_glue(lua_State * L) if (t == glue_node || t == glue_spec_node || t == math_node || t == ins_node) { lua_pushboolean(L,(width(n) == 0 && stretch(n) == 0 && shrink(n) == 0)); return 1; + } else if (t == hlist_node || t == vlist_node) { + lua_pushboolean(L,(glue_set(n) == 0 && glue_order(n) == 0 && glue_sign(n) == 0)); + return 1; } } - return luaL_error(L, "glue (spec) expected"); + return 0; } /* node.getglue */ @@ -3173,16 +3260,21 @@ static int lua_nodelib_get_glue(lua_State * L) halfword n = *check_isnode(L, 1); if (n) { halfword t = type(n); - if (t == glue_node || t == glue_spec_node || t == math_node || t== ins_node) { + if (t == glue_node || t == glue_spec_node || t == math_node || t == ins_node) { lua_pushinteger(L,width(n)); lua_pushinteger(L,stretch(n)); lua_pushinteger(L,shrink(n)); lua_pushinteger(L,stretch_order(n)); lua_pushinteger(L,shrink_order(n)); return 5; + } else if (t == hlist_node || t == vlist_node) { + lua_pushnumber(L, (double) glue_set(n)); /* float */ + lua_pushinteger(L,glue_order(n)); + lua_pushinteger(L,glue_sign(n)); + return 3; } } - return luaL_error(L, "glue (spec) expected"); + return luaL_error(L, "glue (spec) or list expected"); } static int lua_nodelib_set_glue(lua_State * L) @@ -3197,20 +3289,31 @@ static int lua_nodelib_set_glue(lua_State * L) shrink(n) = ((top > 3 && lua_type(L, 4) == LUA_TNUMBER)) ? lua_roundnumber(L,4) : 0; stretch_order(n) = ((top > 4 && lua_type(L, 5) == LUA_TNUMBER)) ? lua_tointeger(L,5) : 0; shrink_order(n) = ((top > 5 && lua_type(L, 6) == LUA_TNUMBER)) ? lua_tointeger(L,6) : 0; + } else if (t == hlist_node || t == vlist_node) { + glue_set(n) = ((top > 1 && lua_type(L, 2) == LUA_TNUMBER)) ? (glue_ratio) lua_tonumber(L,2) : 0; + glue_order(n) = ((top > 2 && lua_type(L, 3) == LUA_TNUMBER)) ? lua_tointeger(L,3) : 0; + glue_sign(n) = ((top > 3 && lua_type(L, 4) == LUA_TNUMBER)) ? lua_tointeger(L,4) : 0; + return 3; } - return 0; + return 0; } - return luaL_error(L, "glue (spec) expected"); + return luaL_error(L, "glue (spec) or list expected"); } static int lua_nodelib_is_zero_glue(lua_State * L) { halfword n = *check_isnode(L, 1); - if ((n != null) && (type(n) == glue_node || type(n) == glue_spec_node || type(n) == math_node || type(n) == ins_node)) { - lua_pushboolean(L,(width(n) == 0 && stretch(n) == 0 && shrink(n) == 0)); - return 1; + if (n != null) { + halfword t = type(n); + if (t == glue_node || t == glue_spec_node || t == math_node || t == ins_node) { + lua_pushboolean(L,(width(n) == 0 && stretch(n) == 0 && shrink(n) == 0)); + return 1; + } else if (t == hlist_node || t == vlist_node) { + lua_pushboolean(L,(glue_set(n) == 0 && glue_order(n) == 0 && glue_sign(n) == 0)); + return 1; + } } - return luaL_error(L, "glue (spec) expected"); + return luaL_error(L, "glue (spec) or list expected"); } /* iteration */ @@ -4051,6 +4154,8 @@ static int lua_nodelib_fast_getfield(lua_State * L) fast_metatable_or_nil(subscr(n)); } else if (lua_key_eq(s, sup)) { fast_metatable_or_nil(supscr(n)); + } else if (lua_key_eq(s, options)) { + lua_pushinteger(L, noadoptions(n)); } else { lua_pushnil(L); } @@ -4788,6 +4893,8 @@ static int lua_nodelib_direct_getfield(lua_State * L) nodelib_pushdirect_or_nil(subscr(n)); } else if (lua_key_eq(s, sup)) { nodelib_pushdirect_or_nil(supscr(n)); + } else if (lua_key_eq(s, options)) { + lua_pushinteger(L, noadoptions(n)); } else { lua_pushnil(L); } @@ -4835,7 +4942,7 @@ static int lua_nodelib_direct_getfield(lua_State * L) } else if (t == math_node) { if (lua_key_eq(s, surround)) { lua_pushinteger(L, surround(n)); - /* glue */ + /* glue */ } else if (lua_key_eq(s, width)) { lua_pushinteger(L, width(n)); } else if (lua_key_eq(s, stretch)) { @@ -5258,111 +5365,169 @@ static int font_tex_direct_kerning(lua_State * L) } /* node.protect_glyphs (returns also boolean because that signals callback) */ +/* node.unprotect_glyphs (returns also boolean because that signals callback) */ + +#define protect_one_indeed(n) \ + if (n != null) { \ + int s = subtype(n); \ + if (s <= 256) { \ + subtype(n) = (quarterword) (s == 1 ? 256 : 256 + s); \ + } \ + } + +#define protect_all_indeed(n) \ + h = n ; \ + if (h != null) { \ + while (h != null) { \ + if (type(h) == glyph_node) { \ + int s = subtype(h); \ + if (s <= 256) { \ + subtype(h) = (quarterword) (s == 1 ? 256 : 256 + s); \ + } \ + } \ + h = vlink(h); \ + } \ + } + +#define protect_node_indeed(n) \ + if (type(n) == glyph_node) { \ + protect_one_indeed(n); \ + } else if (type(n) == disc_node) { \ + protect_all_indeed(vlink(no_break(n))); \ + protect_all_indeed(vlink(pre_break(n))); \ + protect_all_indeed(vlink(post_break(n))); \ + } + +#define unprotect_one_indeed(n) \ + if (n != null) { \ + int s = subtype(n); \ + if (s > 256) { \ + subtype(n) = (quarterword) (s - 256); \ + } \ + } + +#define unprotect_all_indeed(n) \ + h = n ; \ + if (h != null) { \ + while (h != null) { \ + if (type(h) == glyph_node) { \ + int s = subtype(h); \ + if (s <= 256) { \ + subtype(h) = (quarterword) (s - 256); \ + } \ + } \ + h = vlink(h); \ + } \ + } + +#define unprotect_node_indeed(n) \ + if (type(n) == glyph_node) { \ + unprotect_one_indeed(n); \ + } else if (type(n) == disc_node) { \ + unprotect_all_indeed(vlink(no_break(n))); \ + unprotect_all_indeed(vlink(pre_break(n))); \ + unprotect_all_indeed(vlink(post_break(n))); \ + } + +static int lua_nodelib_protect_glyph(lua_State * L) +{ + halfword n = *check_isnode(L, 1); + halfword h; + protect_node_indeed(n); + return 0; +} + +static int lua_nodelib_unprotect_glyph(lua_State * L) +{ + halfword n = *check_isnode(L, 1); + halfword h; + unprotect_node_indeed(n); + return 0; +} static int lua_nodelib_protect_glyphs(lua_State * L) { - int t = 0; halfword head = *check_isnode(L, 1); + halfword tail = null; + halfword h; + if (lua_gettop(L) > 1) { + tail = *check_isnode(L, 2); + } while (head != null) { - if (type(head) == glyph_node) { - int s = subtype(head); - if (s <= 256) { - t = 1; - subtype(head) = (quarterword) (s == 1 ? 256 : 256 + s); - } + protect_node_indeed(head); + if (head == tail) { + break; } head = vlink(head); } - lua_pushboolean(L, t); - lua_pushvalue(L, 1); - return 2; + return 0; } -static int lua_nodelib_protect_glyph(lua_State * L) +static int lua_nodelib_unprotect_glyphs(lua_State * L) { - halfword n = *check_isnode(L, 1); - if (type(n) == glyph_node) { - int s = subtype(n); - if (s <= 256) { - subtype(n) = (quarterword) (s == 1 ? 256 : 256 + s); + halfword head = *check_isnode(L, 1); + halfword tail = null; + halfword h; + if (lua_gettop(L) > 1) { + tail = *check_isnode(L, 2); + } + while (head != null) { + unprotect_node_indeed(head); + if (head == tail) { + break; } + head = vlink(head); } return 0; } /* node.direct.protect_glyphs */ +/* node.direct.unprotect_glyphs */ -static int lua_nodelib_direct_protect_glyphs(lua_State * L) +static int lua_nodelib_direct_protect_glyph(lua_State * L) { - int t = 0; - halfword head = (halfword) lua_tointeger(L,1); - while (head != null) { - if (type(head) == glyph_node) { - int s = subtype(head); - if (s <= 256) { - t = 1; - subtype(head) = (quarterword) (s == 1 ? 256 : 256 + s); - } - } - head = vlink(head); - } - lua_pushboolean(L, t); - lua_pushvalue(L, 1); - return 2; + halfword n = (halfword) lua_tointeger(L,1); + halfword h; + protect_node_indeed(n); + return 0; } -static int lua_nodelib_direct_protect_glyph(lua_State * L) +static int lua_nodelib_direct_unprotect_glyph(lua_State * L) { halfword n = (halfword) lua_tointeger(L,1); - if ((n != null) && (type(n) == glyph_node)) { - int s = subtype(n); - if (s <= 256) { - subtype(n) = (quarterword) (s == 1 ? 256 : 256 + s); - } - } + halfword h; + unprotect_node_indeed(n); return 0; } -/* node.unprotect_glyphs (returns also boolean because that signals callback) */ - -static int lua_nodelib_unprotect_glyphs(lua_State * L) +static int lua_nodelib_direct_protect_glyphs(lua_State * L) { - int t = 0; - halfword head = *(check_isnode(L, 1)); + halfword head = (halfword) lua_tointeger(L,1); + halfword tail = (halfword) lua_tointeger(L,2); + halfword h; while (head != null) { - if (type(head) == glyph_node) { - int s = subtype(head); - if (s > 256) { - t = 1; - subtype(head) = (quarterword) (s - 256); - } + protect_node_indeed(head); + if (head == tail) { + break; } head = vlink(head); } - lua_pushboolean(L, t); - lua_pushvalue(L, 1); - return 2; + return 0; } -/* node.direct.unprotect_glyphs */ - static int lua_nodelib_direct_unprotect_glyphs(lua_State * L) { - int t = 0; halfword head = (halfword) lua_tointeger(L,1); + halfword tail = (halfword) lua_tointeger(L,2); + halfword h; while (head != null) { - if (type(head) == glyph_node) { - int s = subtype(head); - if (s > 256) { - t = 1; - subtype(head) = (quarterword) (s - 256); - } + unprotect_node_indeed(head); + if (head == tail) { + break; } head = vlink(head); } - lua_pushboolean(L, t); - lua_pushvalue(L, 1); - return 2; + return 0; } /* node.first_glyph */ @@ -6100,6 +6265,8 @@ static int lua_nodelib_fast_setfield(lua_State * L) subscr(n) = nodelib_getlist(L, 3); } else if (lua_key_eq(s, sup)) { supscr(n) = nodelib_getlist(L, 3); + } else if (lua_key_eq(s, options)) { + noadoptions(n) = (quarterword) lua_tointeger(L, 3); } else { return nodelib_cantset(L, n, s); } @@ -6690,6 +6857,55 @@ static int lua_nodelib_direct_is_glyph(lua_State * L) return 2; } +/* uses_font */ +/* direct.uses_font */ + +#define uses_font_disc(what,p,n) \ +p = vlink(what(n)); \ +while (p) { \ + if ((type(p) == glyph_node) && (font(p) == f)) { \ + lua_pushboolean(L,1); \ + return 1; \ + } \ + p = vlink(p); \ +} + + +static int lua_nodelib_direct_uses_font(lua_State * L) +{ + halfword n = lua_tointeger(L,1); + halfword f = lua_tointeger(L,2); + halfword p; + if (type(n) == glyph_node) { + lua_pushboolean(L,font(n) == f); + } else if (type(n) == disc_node) { + uses_font_disc(pre_break,p,n); + uses_font_disc(post_break,p,n); + uses_font_disc(no_break,p,n); + } + /* todo: other node types */ + lua_pushboolean(L,0); + return 1; +} + +static int lua_nodelib_uses_font(lua_State * L) +{ + halfword n = *check_isnode(L, 1); + halfword f = lua_tointeger(L,2); + halfword p; + if (type(n) == glyph_node) { + lua_pushboolean(L,font(n) == f); + } else if (type(n) == disc_node) { + uses_font_disc(pre_break,p,n); + uses_font_disc(post_break,p,n); + uses_font_disc(no_break,p,n); + } + /* todo: other node types */ + lua_pushboolean(L,0); + return 1; +} + + /* direct.setfield */ static int lua_nodelib_direct_setfield(lua_State * L) @@ -6905,6 +7121,8 @@ static int lua_nodelib_direct_setfield(lua_State * L) subscr(n) = nodelib_popdirect(3); } else if (lua_key_eq(s, sup)) { supscr(n) = nodelib_popdirect(3); + } else if (lua_key_eq(s, options)) { + noadoptions(n) = (quarterword) lua_tointeger(L, 3); } else { return nodelib_cantset(L, n, s); } @@ -6939,7 +7157,7 @@ static int lua_nodelib_direct_setfield(lua_State * L) height(n) = (halfword) lua_roundnumber(L, 3); } else if ((lua_key_eq(s, list)) || (lua_key_eq(s, head))) { ins_ptr(n) = nodelib_popdirect(3); - /* glue */ + /* glue */ } else if (lua_key_eq(s, width)) { width(n) = (halfword) lua_roundnumber(L, 3); } else if (lua_key_eq(s, stretch)) { @@ -6958,7 +7176,7 @@ static int lua_nodelib_direct_setfield(lua_State * L) subtype(n) = (quarterword) lua_tointeger(L, 3); } else if (lua_key_eq(s, surround)) { surround(n) = (halfword) lua_roundnumber(L, 3); - /* glue */ + /* glue */ } else if (lua_key_eq(s, width)) { width(n) = (halfword) lua_roundnumber(L, 3); } else if (lua_key_eq(s, stretch)) { @@ -7481,20 +7699,20 @@ static int lua_nodelib_effective_glue(lua_State * L) if ((glue == NULL) || (type(*glue) != glue_node)) { lua_pushnil(L) ; } else { - int w = width(*glue) ; + double w = width(*glue) ; parent = lua_touserdata(L, 2); if ((parent != NULL) && ((type(*parent) == hlist_node) || (type(*parent) == vlist_node))) { - if ((int)glue_sign(*parent) == 1) { + if ((int) glue_sign(*parent) == 1) { if (stretch_order(*glue) == glue_order(*parent)) { - w += stretch(*glue) * glue_set(*parent); + w += stretch(*glue) * (double) glue_set(*parent); } } else if (glue_sign(*parent) == 2) { if (shrink_order(*glue) == glue_order(*parent)) { - w -= shrink(*glue) * glue_set(*parent); + w -= shrink(*glue) * (double) glue_set(*parent); } } } - lua_pushinteger(L,w); + lua_pushinteger(L,round(w)); } return 1; } @@ -7505,20 +7723,20 @@ static int lua_nodelib_direct_effective_glue(lua_State * L) if ((glue == null) || (type(glue) != glue_node)) { lua_pushnil(L) ; } else { - int w = width(glue) ; + double w = (double) width(glue) ; halfword parent = lua_tointeger(L, 2); if ((parent != null) && ((type(parent) == hlist_node) || (type(parent) == vlist_node))) { if ((int)glue_sign(parent) == 1) { if (stretch_order(glue) == glue_order(parent)) { - w += stretch(glue) * glue_set(parent); + w += stretch(glue) * (double) glue_set(parent); } } else if (glue_sign(parent) == 2) { if (shrink_order(glue) == glue_order(parent)) { - w -= shrink(glue) * glue_set(parent); + w -= shrink(glue) * (double) glue_set(parent); } } } - lua_pushinteger(L,w); + lua_pushnumber(L,round(w)); } return 1; } @@ -7563,6 +7781,46 @@ static int lua_nodelib_direct_check_discretionary(lua_State * L) { return 0; } +static int lua_nodelib_direct_flatten_discretionaries(lua_State * L) +{ + halfword head = lua_tointeger(L, 1); + halfword current = head; + halfword next; + halfword d, n, h, t; + int c = 0; + while (current != null) { + next = vlink(current); + if (type(current) == disc_node) { + ++c; + d = current; + n = no_break(d); + h = vlink(n); + t = tlink(n); + if (h != null) { + try_couple_nodes(t,next); + if (current == head) { + head = h; + } else { + try_couple_nodes(alink(current),h); + } + vlink(n) = null ; + //tlink(n) = null; + } else { + if (current == head) { + head = next; + } else { + try_couple_nodes(alink(current),next); + } + } + flush_node(d); + } + current = next; + } + nodelib_pushdirect_or_nil(head); + lua_pushinteger(L,c); + return 2; +} + static int lua_nodelib_check_discretionaries(lua_State * L) { halfword c = *check_isnode(L, 1); halfword p ; @@ -7588,6 +7846,129 @@ static int lua_nodelib_check_discretionary(lua_State * L) { return 0; } +static int lua_nodelib_flatten_discretionaries(lua_State * L) +{ + halfword head = *check_isnode(L, 1); + halfword current = head; + halfword next; + halfword d, n, h, t; + halfword *a; + int c = 0; + while (current != null) { + next = vlink(current); + if (type(current) == disc_node) { + ++c; + d = current; + n = no_break(d); + h = vlink(n); + t = tlink(n); + if (h != null) { + try_couple_nodes(t,next); + if (current == head) { + head = h; + } else { + try_couple_nodes(alink(current),h); + } + vlink(n) = null ; + //tlink(n) = null; + } else { + if (current == head) { + head = next; + } else { + try_couple_nodes(alink(current),next); + } + } + flush_node(d); + } + current = next; + } + fast_metatable_or_nil(head); + lua_pushinteger(L,c); + return 2; +} + +/* synctex but not */ + +static int lua_nodelib_direct_set_synctex_fields(lua_State * L) +{ + halfword n = lua_tointeger(L, 1); + halfword tag = lua_tointeger(L, 2); + halfword line = lua_tointeger(L, 3); + if (n != null) { + switch (type(n)) { + case glyph_node: + if (tag) synctex_tag_glyph(n) = tag; + if (line) synctex_line_glyph(n) = line; + break; + case glue_node: + if (tag) synctex_tag_glue(n) = tag; + if (line) synctex_line_glue(n) = line; + break; + case kern_node: + if (tag) synctex_tag_kern(n) = tag; + if (line) synctex_line_kern(n) = line; + break; + case hlist_node: + case vlist_node: + case unset_node: + if (tag) synctex_tag_box(n) = tag; + if (line) synctex_line_box(n) = line; + break; + case rule_node: + if (tag) synctex_tag_rule(n) = tag; + if (line) synctex_line_rule(n) = line; + break; + case math_node: + if (tag) synctex_tag_math(n) = tag; + if (line) synctex_line_math(n) = line; + break; + } + } + return 0; +} + +static int lua_nodelib_direct_get_synctex_fields(lua_State * L) +{ + halfword n = lua_tointeger(L, 1); + if (n != null) { + switch (type(n)) { + case glyph_node: + lua_pushinteger(L,synctex_tag_glyph(n)); + lua_pushinteger(L,synctex_line_glyph(n)); + break; + case glue_node: + lua_pushinteger(L,synctex_tag_glue(n)); + lua_pushinteger(L,synctex_line_glue(n)); + break; + case kern_node: + lua_pushinteger(L,synctex_tag_kern(n)); + lua_pushinteger(L,synctex_line_kern(n)); + break; + case hlist_node: + case vlist_node: + case unset_node: + lua_pushinteger(L,synctex_tag_box(n)); + lua_pushinteger(L,synctex_line_box(n)); + break; + case rule_node: + lua_pushinteger(L,synctex_tag_rule(n)); + lua_pushinteger(L,synctex_line_rule(n)); + break; + case math_node: + lua_pushinteger(L,synctex_tag_math(n)); + lua_pushinteger(L,synctex_line_math(n)); + break; + default: + return 0; + break; + } + return 2; + } + return 0; +} + +/* done */ + static const struct luaL_Reg nodelib_p[] = { {"__index", lua_nodelib_get_property_t}, {"__newindex", lua_nodelib_set_property_t}, @@ -7641,6 +8022,7 @@ static const struct luaL_Reg direct_nodelib_f[] = { {"getshift", lua_nodelib_direct_getshift}, {"getfield", lua_nodelib_direct_getfield}, {"getfont", lua_nodelib_direct_getfont}, + {"getfam", lua_nodelib_direct_getfam}, {"getid", lua_nodelib_direct_getid}, {"getnext", lua_nodelib_direct_getnext}, {"getprev", lua_nodelib_direct_getprev}, @@ -7659,6 +8041,7 @@ static const struct luaL_Reg direct_nodelib_f[] = { {"has_field", lua_nodelib_direct_has_field}, {"is_char", lua_nodelib_direct_is_char}, {"is_glyph", lua_nodelib_direct_is_glyph}, + {"uses_font", lua_nodelib_direct_uses_font}, {"hpack", lua_nodelib_direct_hpack}, /* {"id", lua_nodelib_id}, */ /* no node argument */ {"insert_after", lua_nodelib_direct_insert_after}, @@ -7681,6 +8064,7 @@ static const struct luaL_Reg direct_nodelib_f[] = { {"setfield", lua_nodelib_direct_setfield}, {"setchar", lua_nodelib_direct_setchar}, {"setfont", lua_nodelib_direct_setfont}, + {"setfam", lua_nodelib_direct_setfam}, {"setcomponents", lua_nodelib_direct_setcomponents}, {"setlang", lua_nodelib_direct_setlang}, {"setkern", lua_nodelib_direct_setkern}, @@ -7716,6 +8100,7 @@ static const struct luaL_Reg direct_nodelib_f[] = { /* {"type", lua_nodelib_type}, */ /* no node argument */ /* {"types", lua_nodelib_types}, */ /* no node argument */ {"unprotect_glyphs", lua_nodelib_direct_unprotect_glyphs}, + {"unprotect_glyph", lua_nodelib_direct_unprotect_glyph}, {"unset_attribute", lua_nodelib_direct_unset_attribute}, {"setglue",lua_nodelib_direct_set_glue}, {"getglue",lua_nodelib_direct_get_glue}, @@ -7732,6 +8117,10 @@ static const struct luaL_Reg direct_nodelib_f[] = { {"effective_glue", lua_nodelib_direct_effective_glue}, {"check_discretionary", lua_nodelib_direct_check_discretionary}, {"check_discretionaries", lua_nodelib_direct_check_discretionaries}, + {"flatten_discretionaries",lua_nodelib_direct_flatten_discretionaries}, + /* done */ + {"set_synctex_fields", lua_nodelib_direct_set_synctex_fields}, + {"get_synctex_fields", lua_nodelib_direct_get_synctex_fields}, /* done */ {NULL, NULL} /* sentinel */ }; @@ -7775,6 +8164,7 @@ static const struct luaL_Reg nodelib_f[] = { {"has_field", lua_nodelib_has_field}, {"is_char", lua_nodelib_is_char}, {"is_glyph", lua_nodelib_is_glyph}, + {"uses_font", lua_nodelib_uses_font}, {"hpack", lua_nodelib_hpack}, {"id", lua_nodelib_id}, {"insert_after", lua_nodelib_insert_after}, @@ -7804,6 +8194,7 @@ static const struct luaL_Reg nodelib_f[] = { {"type", lua_nodelib_type}, {"types", lua_nodelib_types}, {"unprotect_glyphs", lua_nodelib_unprotect_glyphs}, + {"unprotect_glyph", lua_nodelib_unprotect_glyph}, {"unset_attribute", lua_nodelib_unset_attribute}, {"setglue",lua_nodelib_set_glue}, {"getglue",lua_nodelib_get_glue}, @@ -7823,7 +8214,12 @@ static const struct luaL_Reg nodelib_f[] = { {"effective_glue", lua_nodelib_effective_glue}, {"check_discretionary", lua_nodelib_check_discretionary}, {"check_discretionaries", lua_nodelib_check_discretionaries}, + {"flatten_discretionaries",lua_nodelib_flatten_discretionaries}, + /* done */ + /* {"set_synctex_fields", lua_nodelib_set_synctex_fields}, */ + /* {"get_synctex_fields", lua_nodelib_get_synctex_fields}, */ /* done */ + {"fix_node_lists", lua_nodelib_fix_node_lists}, {NULL, NULL} /* sentinel */ }; diff --git a/Build/source/texk/web2c/luatexdir/lua/lpdflib.c b/Build/source/texk/web2c/luatexdir/lua/lpdflib.c index f20604ead8f..88f9eac7c24 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lpdflib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lpdflib.c @@ -949,6 +949,25 @@ static int getpdfcreationdate(lua_State * L) return 1 ; } +static int getpdfmajorversion(lua_State * L) +{ + /* lua_pushinteger(L,static_pdf->major_version); */ + lua_pushinteger(L,pdf_major_version); + return 1 ; +} + +static int setpdfmajorversion(lua_State * L) +{ + if (lua_type(L, 1) == LUA_TNUMBER) { + int c = (int) lua_tointeger(L, 1); + if ((c >= 1) && (c <= 2)) { + static_pdf->major_version = c; + set_pdf_major_version(c); + } + } + return 0 ; +} + static int getpdfminorversion(lua_State * L) { /* lua_pushinteger(L,static_pdf->minor_version); */ @@ -1199,6 +1218,8 @@ static const struct luaL_Reg pdflib[] = { { "xformname", getpdfxformname }, { "getversion", getpdfversion }, { "getcreationdate", getpdfcreationdate }, + { "getmajorversion", getpdfmajorversion }, + { "setmajorversion", setpdfmajorversion }, { "getminorversion", getpdfminorversion }, { "setminorversion", setpdfminorversion }, { "newcolorstack", newpdfcolorstack }, diff --git a/Build/source/texk/web2c/luatexdir/lua/lpdfscannerlib.cc b/Build/source/texk/web2c/luatexdir/lua/lpdfscannerlib.cc index 8bdbcf16535..eb881b63c3d 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lpdfscannerlib.cc +++ b/Build/source/texk/web2c/luatexdir/lua/lpdfscannerlib.cc @@ -944,7 +944,7 @@ LUALIB_API int luaopen_pdfscanner(lua_State * L) luaL_openlib(L, 0, scannerlib_meta, 0); lua_pushvalue(L, -1); lua_setfield(L, -2, "__index"); - luaL_openlib(L, NULL, scannerlib_m, 0); + luaL_register(L, NULL, scannerlib_m); luaL_register(L, "pdfscanner", scannerlib); return 1; } diff --git a/Build/source/texk/web2c/luatexdir/lua/lstatslib.c b/Build/source/texk/web2c/luatexdir/lua/lstatslib.c index 6ec2f0bd488..943cd0fb07a 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lstatslib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lstatslib.c @@ -20,6 +20,7 @@ #include "ptexlib.h" #include "lua/luatex-api.h" +#include "luatex_svnversion.h" typedef struct statistic { const char *name; @@ -260,6 +261,11 @@ static lua_Number kpse_used_state(void) } } +static lua_Number get_development_id(void) +{ + return (lua_Number) luatex_svn_revision ; +} + /* temp, for backward compat */ static int init_pool_ptr = 0; @@ -293,6 +299,7 @@ static struct statistic stats[] = { {"banner", 'S', (void *) &getbanner}, {"luatex_version", 'G', &get_luatexversion}, {"luatex_revision", 'S', (void *) &luatexrevision}, + {"development_id", 'N', &get_development_id}, {"luatex_hashtype", 'S', (void *) &get_luatexhashtype}, {"luatex_hashchars", 'N', &get_luatexhashchars}, {"luatex_engine", 'S', (void *) &getenginename}, @@ -471,9 +478,15 @@ static int resetmessages(lua_State * L) return 0; } +static int setexitcode(lua_State * L) { + defaultexitcode = luaL_checkinteger(L,1); + return 0; +} + static const struct luaL_Reg statslib[] = { {"list", statslist}, {"resetmessages", resetmessages}, + {"setexitcode", setexitcode}, {NULL, NULL} /* sentinel */ }; diff --git a/Build/source/texk/web2c/luatexdir/lua/lstrlibext.c b/Build/source/texk/web2c/luatexdir/lua/lstrlibext.c index 5d5c0d723ac..f7f8cbf10ea 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lstrlibext.c +++ b/Build/source/texk/web2c/luatexdir/lua/lstrlibext.c @@ -359,6 +359,133 @@ static int str_bytetable (lua_State *L) { return 1; } +/* + We provide a few helpers that we derived from the lua utf8 module + and slunicode. That way we're sort of covering a decent mix. + +*/ + +#define MAXUNICODE 0x10FFFF + +/* + This is a combination of slunicode and utf8 converters but without mode + and a bit faster on the average than the utf8 one. +*/ + +static void utf8_enco (luaL_Buffer *b, unsigned c) +{ + if (c > MAXUNICODE) { + /* we silently ignore the bad character */ + return; + } + if (0x80 > c) { + luaL_addchar(b, c); + return; + } + if (0x800 > c) + luaL_addchar(b, 0xC0|(c>>6)); + else { + if (0x10000 > c) + luaL_addchar(b, 0xE0|(c>>12)); + else { + luaL_addchar(b, 0xF0|(c>>18)); + luaL_addchar(b, 0x80|(0x3F&(c>>12))); + } + luaL_addchar(b, 0x80|(0x3F&(c>>6))); + } + luaL_addchar(b, 0x80|(0x3F&c)); +} + +static int str_character (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + int i; + luaL_Buffer b; + luaL_buffinit(L,&b); + for (i = 1; i <= n; i++) { + utf8_enco (&b, (unsigned) lua_tointeger(L, i)); + } + luaL_pushresult(&b); + return 1; +} + +/* + The utf8 codepoint function takes two arguments, being positions in the + string, while slunicode byte takes two arguments representing the number of + utf characters. The variant below always returns all codepoints. + +*/ + +static int str_utfvalue (lua_State *L) { + size_t ls; + int ind = 0; + int num = 0; + const char *s = lua_tolstring(L, 1, &ls); + while (ind<(int)ls) { + unsigned char i = (unsigned)*(s+ind); + if (i<0x80) { + lua_pushinteger(L, i); + num += 1; + ind += 1; + } else if (i>=0xF0) { + if ((ind+3)<(int)ls && ((unsigned)*(s+ind+1))>=0x80 && ((unsigned)*(s+ind+2))>=0x80 && ((unsigned)*(s+ind+3))>=0x80) { + unsigned char j = ((unsigned)*(s+ind+1))-128; + unsigned char k = ((unsigned)*(s+ind+2))-128; + unsigned char l = ((unsigned)*(s+ind+3))-128; + lua_pushinteger(L, (((((i-0xF0)*64) + j)*64) + k)*64 + l); + num += 1; + } + ind += 4; + } else if (i>=0xE0) { + if ((ind+2)<(int)ls && ((unsigned)*(s+ind+1))>=0x80 && ((unsigned)*(s+ind+2))>=0x80) { + unsigned char j = ((unsigned)*(s+ind+1))-128; + unsigned char k = ((unsigned)*(s+ind+2))-128; + lua_pushinteger(L, (((i-0xE0)*64) + j)*64 + k); + num += 1; + } + ind += 3; + } else if (i>=0xC0) { + if ((ind+1)<(int)ls && ((unsigned)*(s+ind+1))>=0x80) { + unsigned char j = ((unsigned)*(s+ind+1))-128; + lua_pushinteger(L, ((i-0xC0)*64) + j); + num += 1; + } + ind += 2; + } else { + ind += 1; + } + } + return num; +} + +/* This is a simplified version of utf8.len but without range. */ + +static int str_utflength (lua_State *L) { + size_t ls; + int ind = 0; + int num = 0; + const char *s = lua_tolstring(L, 1, &ls); + while (ind<(int)ls) { + unsigned char i = (unsigned)*(s+ind); + if (i<0x80) { + ind += 1; + } else if (i>=0xF0) { + ind += 4; + } else if (i>=0xE0) { + ind += 3; + } else if (i>=0xC0) { + ind += 2; + } else { + /* bad news, stupid recovery */ + ind += 1; + } + num += 1; + } + lua_pushinteger(L, num); + return 1; +} + +/* end of convenience inclusion */ + static const luaL_Reg strlibext[] = { {"utfvalues", str_utfvalues}, {"utfcharacters", str_utfcharacters}, @@ -368,6 +495,9 @@ static const luaL_Reg strlibext[] = { {"bytepairs", str_bytepairs}, {"bytetable", str_bytetable}, {"explode", str_split}, + {"utfcharacter", str_character}, + {"utfvalue", str_utfvalue}, + {"utflength", str_utflength}, #ifdef LuajitTeX /* luajit has dump built in */ #else diff --git a/Build/source/texk/web2c/luatexdir/lua/ltexlib.c b/Build/source/texk/web2c/luatexdir/lua/ltexlib.c index b5a110657f4..65e55705e44 100644 --- a/Build/source/texk/web2c/luatexdir/lua/ltexlib.c +++ b/Build/source/texk/web2c/luatexdir/lua/ltexlib.c @@ -789,7 +789,7 @@ static int get_item_index(lua_State * L, int i, int base) static int gettex(lua_State * L); -#define get_item_index_plus(L, where, base, what, value, is_assign, get_register, glue) { \ +#define get_item_index_plus(L, where, base, what, value, is_assign, get_register, texget) { \ size_t len; \ const char *str; \ int key, cs; \ @@ -804,7 +804,7 @@ static int gettex(lua_State * L); if (key >= 0 && key <= 65535) { \ value = get_register(key); \ } else if (is_assign(eq_type(cs))) { \ - gettex(L); /* lazy */ \ + texget = gettex(L); /* lazy */ \ } else { \ luaL_error(L, "incorrect %s name", what); \ } \ @@ -849,7 +849,11 @@ static int setdimen(lua_State * L) static int getdimen(lua_State * L) { int value = 0; - get_item_index_plus(L, lua_gettop(L), scaled_base, "dimen", value, is_dim_assign, get_tex_dimen_register, false); + int texget = 0; + get_item_index_plus(L, lua_gettop(L), scaled_base, "dimen", value, is_dim_assign, get_tex_dimen_register, texget); + if (texget > 0) { + return texget; + } lua_pushinteger(L, value); return 1; } @@ -877,7 +881,11 @@ static int setskip(lua_State * L) static int getskip(lua_State * L) { int value = 0; - get_item_index_plus(L, lua_gettop(L), skip_base, "skip", value, is_glue_assign, get_tex_skip_register, true); + int texget = 0; + get_item_index_plus(L, lua_gettop(L), skip_base, "skip", value, is_glue_assign, get_tex_skip_register, texget); + if (texget > 0) { + return texget; + } if (value == null) { lua_nodelib_push_fast(L, copy_node(zero_glue)); } else { @@ -910,22 +918,47 @@ static int setglue(lua_State * L) static int getglue(lua_State * L) { int value = 0; + int texget = 0; int top = lua_gettop(L); - get_item_index_plus(L, top, skip_base, "skip", value, is_glue_assign, get_tex_skip_register, true); - if (value == null) { - lua_pushinteger(L,0); - lua_pushinteger(L,0); - lua_pushinteger(L,0); - lua_pushinteger(L,0); - lua_pushinteger(L,0); + int dim = -1; + if (top > 1 && lua_type(L,top) == LUA_TBOOLEAN) { + dim = lua_toboolean(L,top); + top = top - 1; } else { - lua_pushinteger(L,width(value)); - lua_pushinteger(L,stretch(value)); - lua_pushinteger(L,shrink(value)); - lua_pushinteger(L,stretch_order(value)); - lua_pushinteger(L,shrink_order(value)); + lua_pushboolean(L,1); + dim = 1 ; + /* no top adaption. somewhat messy, but the gettex fallback checks itself */ + } + /* checks itself for the boolean */ + get_item_index_plus(L, top, skip_base, "glue", value, is_glue_assign, get_tex_skip_register, texget); + if (texget > 0) { + return texget; + } + if (dim == 0) { + /* false */ + if (value == null) { + lua_pushinteger(L,0); + } else { + lua_pushinteger(L,width(value)); + } + return 1; + } else { + /* true and nil */ + if (value == null) { + lua_pushinteger(L,0); + lua_pushinteger(L,0); + lua_pushinteger(L,0); + lua_pushinteger(L,0); + lua_pushinteger(L,0); + } else { + lua_pushinteger(L,width(value)); + lua_pushinteger(L,stretch(value)); + lua_pushinteger(L,shrink(value)); + lua_pushinteger(L,stretch_order(value)); + lua_pushinteger(L,shrink_order(value)); + } + return 5; } - return 5; } static int ismuskip(lua_State * L) @@ -947,7 +980,11 @@ static int setmuskip(lua_State * L) static int getmuskip(lua_State * L) { int value = 0; - get_item_index_plus(L, lua_gettop(L), mu_skip_base, "muskip", value, is_mu_glue_assign, get_tex_mu_skip_register, true); + int texget = 0; + get_item_index_plus(L, lua_gettop(L), mu_skip_base, "muskip", value, is_mu_glue_assign, get_tex_mu_skip_register, texget); + if (texget > 0) { + return texget; + } lua_nodelib_push_fast(L, copy_node(value)); return 1; } @@ -976,16 +1013,45 @@ static int setmuglue(lua_State * L) static int getmuglue(lua_State * L) { int value = 0; - get_item_index_plus(L, lua_gettop(L), mu_skip_base, "muskip", value, is_mu_glue_assign, get_tex_mu_skip_register, true); - if (value == null) { - lua_pushnil(L); - return 1; + int texget = 0; + int top = lua_gettop(L); + int dim = -1; + if (top > 1 && lua_type(L,top) == LUA_TBOOLEAN) { + dim = lua_toboolean(L,top); + top = top - 1; } else { - lua_pushinteger(L,width(value)); - lua_pushinteger(L,stretch(value)); - lua_pushinteger(L,shrink(value)); - lua_pushinteger(L,stretch_order(value)); - lua_pushinteger(L,shrink_order(value)); + lua_pushboolean(L,1); + dim = 1 ; + /* no top adaption. somewhat messy, but the gettex fallback checks itself */ + } + /* checks itself for the boolean */ + get_item_index_plus(L, top, mu_skip_base, "muskip", value, is_mu_glue_assign, get_tex_mu_skip_register, texget); + if (texget > 0) { + return texget; + } + if (dim == 0) { + /* false */ + if (value == null) { + lua_pushinteger(L,0); + } else { + lua_pushinteger(L,width(value)); + } + return 1; + } else { + /* true and nil */ + if (value == null) { + lua_pushinteger(L,0); + lua_pushinteger(L,0); + lua_pushinteger(L,0); + lua_pushinteger(L,0); + lua_pushinteger(L,0); + } else { + lua_pushinteger(L,width(value)); + lua_pushinteger(L,stretch(value)); + lua_pushinteger(L,shrink(value)); + lua_pushinteger(L,stretch_order(value)); + lua_pushinteger(L,shrink_order(value)); + } return 5; } } @@ -1015,7 +1081,11 @@ static int setcount(lua_State * L) static int getcount(lua_State * L) { int value = 0; - get_item_index_plus(L, lua_gettop(L), count_base, "count", value, is_int_assign, get_tex_count_register, false); + int texget = 0; + get_item_index_plus(L, lua_gettop(L), count_base, "count", value, is_int_assign, get_tex_count_register, texget); + if (texget > 0) { + return texget; + } lua_pushinteger(L, value); return 1; } @@ -1047,7 +1117,11 @@ static int setattribute(lua_State * L) static int getattribute(lua_State * L) { int value = 0; - get_item_index_plus(L, lua_gettop(L), attribute_base, "attribute", value, is_attr_assign, get_tex_attribute_register, false); + int texget = 0; + get_item_index_plus(L, lua_gettop(L), attribute_base, "attribute", value, is_attr_assign, get_tex_attribute_register, texget); + if (texget > 0) { + return texget; + } lua_pushinteger(L, value); return 1; } @@ -2278,7 +2352,7 @@ static const struct luaL_Reg nest_m[] = { static void init_nest_lib(lua_State * L) { luaL_newmetatable(L, NEST_METATABLE); - luaL_register(L, NULL, nest_m); + luaL_openlib(L, NULL, nest_m, 0); lua_pop(L, 1); } @@ -2656,7 +2730,7 @@ static int tex_enableprimitives(lua_State * L) #define get_dimen_par(A,B) do { \ lua_key_rawgeti(A); \ if (lua_type(L, -1) == LUA_TNUMBER) { \ - A = (int) lua_tointeger(L, -1); \ + A = (int) lua_roundnumber(L, -1); \ } else { \ A = (B); \ } \ @@ -2937,11 +3011,12 @@ static int tex_run_boot(lua_State * L) /* Initialize synctex primitive */ synctexinitcommand(); /* tex is ready to go, now */ + /* unhide_lua_table(Luas, "tex", tex_table_id); unhide_lua_table(Luas, "pdf", pdf_table_id); unhide_lua_table(Luas, "token", token_table_id); unhide_lua_table(Luas, "node", node_table_id); - + */ lua_pushboolean(L, 1); /* true */ return 1; } @@ -3040,6 +3115,7 @@ static int tex_save_box_resource(lua_State * L) int attributes = null; int resources = null; int type = 0; + int margin = pdf_xform_margin; boolean immediate = false; /* box attributes resources */ halfword boxnumber = lua_tointeger(L,1); @@ -3057,6 +3133,9 @@ static int tex_save_box_resource(lua_State * L) if (lua_type(L,5) == LUA_TNUMBER) { type = lua_tointeger(L, 5); } + if (lua_type(L,6) == LUA_TNUMBER) { + margin = lua_tointeger(L, 6); + } /* more or less same as scanner variant */ boxdata = box(boxnumber); if (boxdata == null) @@ -3073,6 +3152,7 @@ static int tex_save_box_resource(lua_State * L) set_obj_xform_height(static_pdf, index, height(boxdata)); set_obj_xform_depth(static_pdf, index, depth(boxdata)); set_obj_xform_type(static_pdf, index, type); + set_obj_xform_margin(static_pdf, index, margin); box(boxnumber) = null; last_saved_box_index = index; lua_pushinteger(L, index); @@ -3137,14 +3217,16 @@ static int tex_get_box_resource_dimensions(lua_State * L) lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); + lua_pushnil(L); } else { index = lua_tointeger(L,1); check_obj_type(static_pdf, obj_type_xform, index); lua_pushinteger(L, (int) obj_xform_width(static_pdf, index)); lua_pushinteger(L, (int) obj_xform_height(static_pdf, index)); lua_pushinteger(L, (int) obj_xform_depth(static_pdf, index)); + lua_pushinteger(L, (int) obj_xform_margin(static_pdf, index)); } - return 3; + return 4; } static int tex_build_page(lua_State * L) @@ -3153,6 +3235,69 @@ static int tex_build_page(lua_State * L) return 0; } +/* synctex */ + +static int lua_set_synctex_mode(lua_State * L) +{ + halfword mode = lua_tointeger(L, 1); + synctex_set_mode(mode); + return 0; +} +static int lua_get_synctex_mode(lua_State * L) +{ + lua_pushinteger(L,synctex_get_mode()); + return 1; +} + +static int lua_set_synctex_tag(lua_State * L) +{ + halfword tag = lua_tointeger(L, 1); + synctex_set_tag(tag); + return 0; +} + +static int lua_get_synctex_tag(lua_State * L) +{ + lua_pushinteger(L,synctex_get_tag()); + return 1; +} + +static int lua_force_synctex_tag(lua_State * L) +{ + halfword tag = lua_tointeger(L, 1); + synctex_force_tag(tag); + return 0; +} + +static int lua_force_synctex_line(lua_State * L) +{ + halfword line = lua_tointeger(L, 1); + synctex_force_line(line); + return 0; +} + +static int lua_set_synctex_line(lua_State * L) +{ + halfword line = lua_tointeger(L, 1); + synctex_set_line(line); + return 0; +} + +static int lua_get_synctex_line(lua_State * L) +{ + lua_pushinteger(L,synctex_get_line()); + return 1; +} + +static int lua_set_synctex_no_files(lua_State * L) +{ + halfword flag = lua_tointeger(L, 1); + synctex_set_no_files(flag); + return 0; +} + +/* till here */ + void init_tex_table(lua_State * L) { lua_createtable(L, 0, 3); @@ -3252,13 +3397,23 @@ static const struct luaL_Reg texlib[] = { { "getboxresourcedimensions", tex_get_box_resource_dimensions }, /* just for testing: it will probably stay but maybe with options */ { "triggerbuildpage", tex_build_page }, + /* not the best place but better than in node */ + { "set_synctex_mode", lua_set_synctex_mode }, + { "get_synctex_mode", lua_get_synctex_mode }, + { "set_synctex_tag", lua_set_synctex_tag }, + { "get_synctex_tag", lua_get_synctex_tag }, + { "set_synctex_no_files", lua_set_synctex_no_files }, + { "force_synctex_tag", lua_force_synctex_tag }, + { "force_synctex_line", lua_force_synctex_line }, + { "set_synctex_line", lua_set_synctex_line }, + { "get_synctex_line", lua_get_synctex_line }, /* sentinel */ { NULL, NULL } }; int luaopen_tex(lua_State * L) { - luaL_register(L, "tex", texlib); + luaL_openlib(L, "tex", texlib, 0); /* *INDENT-OFF* */ make_table(L, "attribute", "tex.attribute", "getattribute", "setattribute"); make_table(L, "skip", "tex.skip", "getskip", "setskip"); diff --git a/Build/source/texk/web2c/luatexdir/lua/luainit.w b/Build/source/texk/web2c/luatexdir/lua/luainit.w index fa43976b0ac..763ac1a42a5 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luainit.w +++ b/Build/source/texk/web2c/luatexdir/lua/luainit.w @@ -446,7 +446,7 @@ static void parse_options(int ac, char **av) "kpathsea : Karl Berry, Olaf Weber and others\n" "lua : Roberto Ierusalimschy, Waldemar Celes and Luiz Henrique de Figueiredo\n" "metapost : John Hobby, Taco Hoekwater and friends\n" - "poppler : Derek Noonburg, Kristian H\\ogsberg (partial)\n" + "poppler : Derek Noonburg, Kristian Hogsberg (partial)\n" "fontforge : George Williams (partial)\n" "luajit : Mike Pall (used in LuajitTeX)\n"); /* *INDENT-ON* */ @@ -767,10 +767,12 @@ static void setup_lua_path(lua_State * L) @ helper variables for the safe keeping of table ids @c +/* int tex_table_id; int pdf_table_id; int token_table_id; int node_table_id; +*/ @ @c int l_pack_type_index [PACK_TYPE_SIZE] ; @@ -941,8 +943,8 @@ void lua_initialize(int ac, char **av) /* If setlocale fails here, then the state */ /* could be compromised, and we exit. */ env_locale = setlocale (LC_ALL, ""); - if (!env_locale) { - fprintf(stderr,"Unable to read environment locale:exit now.\n"); + if (!env_locale && !lua_only) { + fprintf(stderr,"Unable to read environment locale: exit now.\n"); exit(1); } tmp = setlocale (LC_CTYPE, NULL); @@ -962,7 +964,7 @@ void lua_initialize(int ac, char **av) /* we can't ensure a 'sane' locale for lua. */ env_locale = setlocale (LC_ALL, old_locale); if (!env_locale) { - fprintf(stderr,"Unable to restore original locale:exit now.\n"); + fprintf(stderr,"Unable to restore original locale %s: exit now.\n",old_locale); exit(1); } xfree(old_locale); @@ -1011,47 +1013,53 @@ void lua_initialize(int ac, char **av) /* now run the file */ if (startup_filename != NULL) { char *v1; - /* hide the 'tex' and 'pdf' table */ - tex_table_id = hide_lua_table(Luas, "tex"); - token_table_id = hide_lua_table(Luas, "token"); - node_table_id = hide_lua_table(Luas, "node"); - pdf_table_id = hide_lua_table(Luas, "pdf"); - + int tex_table_id = hide_lua_table(Luas, "tex"); + int token_table_id = hide_lua_table(Luas, "token"); + int node_table_id = hide_lua_table(Luas, "node"); + int pdf_table_id = hide_lua_table(Luas, "pdf"); + if (lua_only) { + /* hide the 'tex' and 'pdf' table */ + if (load_luatex_core_lua(Luas)) { + fprintf(stderr, "Error in execution of luatex-core.lua .\n"); + } + if (luaL_loadfile(Luas, startup_filename)) { + fprintf(stdout, "%s\n", lua_tostring(Luas, -1)); + exit(1); + } + init_tex_table(Luas); /* needed ? */ + if (lua_pcall(Luas, 0, 0, 0)) { + fprintf(stdout, "%s\n", lua_tostring(Luas, -1)); + lua_traceback(Luas); + /* lua_close(Luas); */ + exit(1); + } else { + if (given_file) + free(given_file); + /* lua_close(Luas); */ + exit(0); + } + } + /* a normal tex run */ + init_tex_table(Luas); + unhide_lua_table(Luas, "tex", tex_table_id); + unhide_lua_table(Luas, "pdf", pdf_table_id); + unhide_lua_table(Luas, "token", token_table_id); + unhide_lua_table(Luas, "node", node_table_id); if (luaL_loadfile(Luas, startup_filename)) { fprintf(stdout, "%s\n", lua_tostring(Luas, -1)); exit(1); } - /* */ - init_tex_table(Luas); - if (lua_only) { - if (load_luatex_core_lua(Luas)) - fprintf(stderr, "Error in execution of luatex-core.lua .\n"); - } if (lua_pcall(Luas, 0, 0, 0)) { fprintf(stdout, "%s\n", lua_tostring(Luas, -1)); - lua_traceback(Luas); + lua_traceback(Luas); exit(1); } - /* no filename? quit now! */ if (!input_name) { get_lua_string("texconfig", "jobname", &input_name); } if (!dump_name) { get_lua_string("texconfig", "formatname", &dump_name); } - if (lua_only) { - if (given_file) - free(given_file); - /* this is not strictly needed but it pleases valgrind */ - lua_close(Luas); - exit(0); - } - /* unhide the 'tex' and 'pdf' table */ - unhide_lua_table(Luas, "tex", tex_table_id); - unhide_lua_table(Luas, "pdf", pdf_table_id); - unhide_lua_table(Luas, "token", token_table_id); - unhide_lua_table(Luas, "node", node_table_id); - /* |kpse_init| */ kpse_init = -1; get_lua_boolean("texconfig", "kpse_init", &kpse_init); diff --git a/Build/source/texk/web2c/luatexdir/lua/luanode.w b/Build/source/texk/web2c/luatexdir/lua/luanode.w index af15748bacd..c09cac1ff01 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luanode.w +++ b/Build/source/texk/web2c/luatexdir/lua/luanode.w @@ -96,21 +96,18 @@ void lua_node_filter(int filterid, int extrainfo, halfword head_node, halfword * start_node = vlink(head_node); if (start_node != null) { /* maybe just always slide (harmless and fast) */ - last_node = vlink(start_node); if (fix_node_lists) { - while (last_node != null) { - alink(last_node) = start_node; - start_node = last_node; - last_node = vlink(start_node); - } + /* slides and returns last node */ + *tail_node = fix_node_list(start_node); } else { + last_node = vlink(start_node); while (last_node != null) { start_node = last_node; last_node = vlink(start_node); } + /* we're at the end now */ + *tail_node = start_node; } - /* we're at the end now */ - *tail_node = start_node; } else { /* we're already at the end */ *tail_node = head_node; diff --git a/Build/source/texk/web2c/luatexdir/lua/luastuff.w b/Build/source/texk/web2c/luatexdir/lua/luastuff.w index 6f57e8ee845..7274a683637 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luastuff.w +++ b/Build/source/texk/web2c/luatexdir/lua/luastuff.w @@ -619,34 +619,6 @@ void preset_environment(lua_State * L, const parm_struct * p, const char *s) luajit compatibility layer for luatex lua5.2 */ #ifdef LuajitTeX -LUALIB_API void *luaL_testudata (lua_State *L, int ud, const char *tname) { - void *p = lua_touserdata(L, ud); - if (p != NULL) { /* value is a userdata? */ - if (lua_getmetatable(L, ud)) { /* does it have a metatable? */ - luaL_getmetatable(L, tname); /* get correct metatable */ - if (!lua_rawequal(L, -1, -2)) /* not the same? */ - p = NULL; /* value is a userdata with wrong metatable */ - lua_pop(L, 2); /* remove both metatables */ - return p; - } - } - return NULL; /* value is not a userdata with a metatable */ -} - -@ @c -/* It's not ok. See lua-users.org/wiki/CompatibilityWithLuaFive for another solution */ -LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { - /*luaL_checkversion(L);*/ - luaL_checkstack(L, nup, "too many upvalues"); - for (; l->name != NULL; l++) { /* fill the table with given functions */ - int i; - for (i = 0; i < nup; i++) /* copy upvalues to the top */ - lua_pushvalue(L, -nup); - lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */ - lua_setfield(L, -(nup + 2), l->name); - } - lua_pop(L, nup); /* remove upvalues */ -} @ @c LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) { diff --git a/Build/source/texk/web2c/luatexdir/lua/luatex-api.h b/Build/source/texk/web2c/luatexdir/lua/luatex-api.h index b83745049c8..36b2f5979e1 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luatex-api.h +++ b/Build/source/texk/web2c/luatexdir/lua/luatex-api.h @@ -130,6 +130,7 @@ extern int luaopen_font(lua_State * L); extern int luaopen_vf(lua_State * L); extern int font_to_lua(lua_State * L, int f); extern int font_from_lua(lua_State * L, int f); /* return is boolean */ +extern int characters_from_lua(lua_State * L, int f); /* return is boolean */ extern int luaopen_token(lua_State * L); extern void tokenlist_to_lua(lua_State * L, int p); @@ -224,10 +225,13 @@ extern int loader_Call_luatex(lua_State * L, const char *name, const char *filen extern void init_tex_table(lua_State * L); +/* extern int tex_table_id; extern int pdf_table_id; extern int token_table_id; extern int node_table_id; +*/ + extern int main_initialize(void); extern int do_run_callback(int special, const char *values, va_list vl); @@ -503,7 +507,6 @@ make_lua_key(area);\ make_lua_key(art);\ make_lua_key(attr);\ make_lua_key(attributes);\ -make_lua_key(auto_expand);\ make_lua_key(bbox);\ make_lua_key(before_display);\ make_lua_key(best_ins_ptr);\ @@ -715,6 +718,7 @@ make_lua_key(pagesattributes);\ make_lua_key(parameters);\ make_lua_key(pardir);\ make_lua_key(parshape);\ +make_lua_key(pdf);\ make_lua_key(pdf_data);\ make_lua_key(pdf_destination);\ make_lua_key(pdf_literal);\ @@ -875,7 +879,6 @@ init_lua_key(area);\ init_lua_key(art);\ init_lua_key(attr);\ init_lua_key(attributes);\ -init_lua_key(auto_expand);\ init_lua_key(bbox);\ init_lua_key(before_display);\ init_lua_key(best_ins_ptr);\ @@ -1220,6 +1223,7 @@ init_lua_key_alias(pLTL,"+LTL");\ init_lua_key_alias(pRTT,"+RTT");\ init_lua_key_alias(pTLT,"+TLT");\ init_lua_key_alias(pTRT,"+TRT");\ +init_lua_key_alias(pdf,"pdf");\ init_lua_key_alias(pdf_data,"pdf.data");\ init_lua_key_alias(term_and_log,"term and log") @@ -1294,7 +1298,6 @@ use_lua_key(area); use_lua_key(art); use_lua_key(attr); use_lua_key(attributes); -use_lua_key(auto_expand); use_lua_key(bbox); use_lua_key(before_display); use_lua_key(best_ins_ptr); @@ -1506,6 +1509,7 @@ use_lua_key(pagesattributes); use_lua_key(parameters); use_lua_key(pardir); use_lua_key(parshape); +use_lua_key(pdf); use_lua_key(pdf_data); use_lua_key(pdf_destination); use_lua_key(pdf_literal); diff --git a/Build/source/texk/web2c/luatexdir/lua/luatex-core.c b/Build/source/texk/web2c/luatexdir/lua/luatex-core.c index 631f25c3b99..780c12f4c50 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luatex-core.c +++ b/Build/source/texk/web2c/luatexdir/lua/luatex-core.c @@ -24,7 +24,7 @@ int load_luatex_core_lua (lua_State * L) 0x54, 0x65, 0x58, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x54, 0x65, 0x61, 0x6d, 0x27, 0x2c, 0x0a, 0x2d, 0x2d, 0x20, 0x7d, 0x0a, 0x0a, 0x4c, 0x55, 0x41, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x52, 0x45, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x20, 0x3d, - 0x20, 0x31, 0x2e, 0x30, 0x30, 0x32, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, + 0x20, 0x31, 0x2e, 0x30, 0x30, 0x33, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x4c, 0x75, 0x61, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x72, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x20, @@ -45,214 +45,260 @@ int load_luatex_core_lua (lua_State * L) 0x65, 0x20, 0x3d, 0x20, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x20, 0x6e, 0x65, 0x78, 0x74, 0x2c, 0x20, 0x67, 0x65, 0x74, 0x6d, 0x65, 0x74, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2c, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x69, 0x6e, 0x64, - 0x2c, 0x20, 0x67, 0x73, 0x75, 0x62, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, - 0x66, 0x69, 0x6e, 0x64, 0x2c, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, - 0x62, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x6f, 0x5f, 0x6f, 0x70, 0x65, 0x6e, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x69, - 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x6f, 0x5f, - 0x70, 0x6f, 0x70, 0x65, 0x6e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x3d, 0x20, 0x69, 0x6f, 0x2e, 0x70, 0x6f, 0x70, 0x65, 0x6e, 0x0a, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x20, 0x69, 0x6f, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x69, 0x6f, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x73, - 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x69, 0x6f, 0x5f, 0x72, 0x65, 0x61, 0x64, - 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x66, 0x69, - 0x6f, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x20, 0x66, 0x69, 0x6f, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x66, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, - 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x20, 0x66, 0x69, 0x6f, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x66, 0x69, 0x6c, 0x65, 0x6e, - 0x61, 0x6d, 0x65, 0x20, 0x20, 0x3d, 0x20, 0x66, 0x69, 0x6f, 0x2e, 0x72, 0x65, 0x63, 0x6f, 0x72, - 0x64, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x20, 0x6d, 0x74, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x6d, 0x65, 0x74, 0x61, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x28, 0x69, 0x6f, 0x2e, 0x73, 0x74, 0x64, 0x65, 0x72, 0x72, 0x29, 0x0a, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x74, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x6d, 0x74, 0x2e, 0x6c, 0x69, - 0x6e, 0x65, 0x73, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x61, 0x66, 0x65, 0x72, 0x6f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3d, 0x20, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x73, 0x61, 0x66, 0x65, 0x72, 0x5f, 0x6f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x68, 0x65, 0x6c, 0x6c, 0x65, - 0x73, 0x63, 0x61, 0x70, 0x65, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3d, 0x20, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x73, 0x68, 0x65, 0x6c, 0x6c, 0x5f, 0x65, 0x73, 0x63, - 0x61, 0x70, 0x65, 0x20, 0x2d, 0x2d, 0x20, 0x30, 0x20, 0x28, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, - 0x65, 0x64, 0x29, 0x20, 0x31, 0x20, 0x28, 0x61, 0x6e, 0x79, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x29, - 0x20, 0x32, 0x20, 0x28, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x29, 0x0a, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6b, 0x70, 0x73, 0x65, 0x75, 0x73, 0x65, 0x64, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x2e, 0x6b, 0x70, 0x73, 0x65, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x20, 0x20, 0x20, 0x20, - 0x2d, 0x2d, 0x20, 0x30, 0x20, 0x31, 0x0a, 0x0a, 0x69, 0x6f, 0x2e, 0x73, 0x61, 0x76, 0x65, 0x64, - 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3d, 0x20, 0x69, 0x6f, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x20, 0x20, 0x2d, 0x2d, 0x20, - 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, - 0x0a, 0x2d, 0x2d, 0x20, 0x28, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, - 0x20, 0x74, 0x6c, 0x31, 0x37, 0x20, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x29, 0x20, 0x69, - 0x6f, 0x2e, 0x73, 0x61, 0x76, 0x65, 0x64, 0x5f, 0x70, 0x6f, 0x70, 0x65, 0x6e, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x69, 0x6f, 0x5f, 0x70, 0x6f, - 0x70, 0x65, 0x6e, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x70, 0x72, - 0x6f, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x0a, 0x69, 0x6f, 0x2e, 0x73, 0x61, 0x76, 0x65, 0x64, - 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3d, 0x20, 0x69, 0x6f, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x20, 0x2d, 0x2d, 0x20, - 0x61, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x20, 0x72, 0x65, 0x61, 0x64, 0x6f, 0x6e, 0x6c, 0x79, 0x0a, - 0x6d, 0x74, 0x2e, 0x73, 0x61, 0x76, 0x65, 0x64, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x6d, 0x74, 0x5f, 0x6c, - 0x69, 0x6e, 0x65, 0x73, 0x20, 0x2d, 0x2d, 0x20, 0x61, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x20, 0x72, - 0x65, 0x61, 0x64, 0x6f, 0x6e, 0x6c, 0x79, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, - 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x78, 0x5f, 0x69, - 0x6f, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x68, 0x6f, 0x77, 0x29, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x68, 0x6f, 0x77, 0x20, - 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x6f, 0x77, - 0x20, 0x3d, 0x20, 0x27, 0x72, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x20, 0x3d, 0x20, 0x69, 0x6f, 0x5f, - 0x6f, 0x70, 0x65, 0x6e, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x68, 0x6f, 0x77, 0x29, 0x0a, 0x20, + 0x2c, 0x20, 0x67, 0x73, 0x75, 0x62, 0x2c, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x3d, + 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x2c, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x2c, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x69, 0x6f, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x69, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x0a, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x69, 0x6f, 0x5f, 0x70, 0x6f, 0x70, 0x65, 0x6e, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x69, 0x6f, 0x2e, 0x70, 0x6f, 0x70, + 0x65, 0x6e, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x6f, 0x5f, 0x6c, 0x69, 0x6e, 0x65, + 0x73, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x69, + 0x6f, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, + 0x69, 0x6f, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3d, 0x20, 0x66, 0x69, 0x6f, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, + 0x65, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x69, 0x6f, 0x5f, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x66, 0x69, + 0x6f, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x69, 0x6f, 0x5f, 0x72, 0x65, 0x63, 0x6f, + 0x72, 0x64, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x20, 0x3d, 0x20, 0x66, 0x69, + 0x6f, 0x2e, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, + 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x74, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x67, 0x65, + 0x74, 0x6d, 0x65, 0x74, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x69, 0x6f, 0x2e, 0x73, 0x74, + 0x64, 0x65, 0x72, 0x72, 0x29, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x74, 0x5f, 0x6c, + 0x69, 0x6e, 0x65, 0x73, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3d, 0x20, 0x6d, 0x74, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x73, 0x61, 0x66, 0x65, 0x72, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x73, 0x61, + 0x66, 0x65, 0x72, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x73, 0x68, 0x65, 0x6c, 0x6c, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x73, 0x68, + 0x65, 0x6c, 0x6c, 0x5f, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, 0x20, 0x2d, 0x2d, 0x20, 0x30, 0x20, + 0x28, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x29, 0x20, 0x31, 0x20, 0x28, 0x61, 0x6e, + 0x79, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x29, 0x20, 0x32, 0x20, 0x28, 0x72, 0x65, 0x73, 0x74, 0x72, + 0x69, 0x63, 0x74, 0x65, 0x64, 0x29, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6b, 0x70, 0x73, + 0x65, 0x75, 0x73, 0x65, 0x64, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3d, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x6b, 0x70, 0x73, 0x65, 0x5f, 0x75, + 0x73, 0x65, 0x64, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x30, 0x20, 0x31, 0x0a, 0x0a, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x6e, 0x6c, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x69, 0x6f, + 0x2e, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x6e, 0x6c, 0x0a, 0x0a, 0x69, 0x6f, 0x2e, 0x73, 0x61, + 0x76, 0x65, 0x64, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x69, 0x6f, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x20, + 0x2d, 0x2d, 0x20, 0x61, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x20, 0x72, 0x65, 0x61, 0x64, 0x6f, 0x6e, + 0x6c, 0x79, 0x0a, 0x6d, 0x74, 0x2e, 0x73, 0x61, 0x76, 0x65, 0x64, 0x5f, 0x6c, 0x69, 0x6e, 0x65, + 0x73, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x6d, + 0x74, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x20, 0x2d, 0x2d, 0x20, 0x61, 0x6c, 0x77, 0x61, 0x79, + 0x73, 0x20, 0x72, 0x65, 0x61, 0x64, 0x6f, 0x6e, 0x6c, 0x79, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x75, 0x61, 0x74, 0x65, + 0x78, 0x5f, 0x69, 0x6f, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x68, + 0x6f, 0x77, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x68, + 0x6f, 0x77, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x68, 0x6f, 0x77, 0x20, 0x3d, 0x20, 0x27, 0x72, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x20, 0x3d, 0x20, + 0x69, 0x6f, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x68, 0x6f, 0x77, + 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x66, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x74, 0x79, 0x70, 0x65, 0x28, + 0x68, 0x6f, 0x77, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x27, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x68, 0x6f, 0x77, 0x2c, 0x27, 0x77, + 0x27, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x66, 0x69, 0x6f, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x66, 0x69, + 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x77, 0x27, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x69, 0x6f, 0x5f, 0x72, 0x65, + 0x63, 0x6f, 0x72, 0x64, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x28, 0x6e, 0x61, 0x6d, + 0x65, 0x2c, 0x27, 0x72, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x75, 0x61, 0x74, + 0x65, 0x78, 0x5f, 0x69, 0x6f, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x6f, + 0x6e, 0x6c, 0x79, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x68, 0x6f, 0x77, 0x29, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x69, 0x66, 0x20, 0x68, 0x6f, 0x77, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x6f, 0x77, 0x20, 0x3d, 0x20, 0x27, 0x72, 0x27, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x68, 0x6f, 0x77, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x68, 0x6f, 0x77, 0x2c, + 0x27, 0x5b, 0x5e, 0x72, 0x62, 0x5d, 0x27, 0x2c, 0x27, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x68, 0x6f, 0x77, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x68, 0x6f, 0x77, 0x20, 0x3d, 0x20, 0x27, 0x72, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x20, 0x3d, 0x20, 0x69, 0x6f, + 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x68, 0x6f, 0x77, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x66, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x69, 0x6f, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, + 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x72, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x75, 0x61, 0x74, + 0x65, 0x78, 0x5f, 0x69, 0x6f, 0x5f, 0x70, 0x6f, 0x70, 0x65, 0x6e, 0x28, 0x6e, 0x61, 0x6d, 0x65, + 0x2c, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x6f, 0x6b, 0x61, 0x79, 0x2c, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x69, + 0x6f, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6f, + 0x6b, 0x61, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x69, 0x6f, 0x5f, 0x70, 0x6f, 0x70, 0x65, 0x6e, 0x28, 0x66, 0x6f, 0x75, 0x6e, 0x64, + 0x2c, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x78, 0x5f, 0x69, 0x6f, 0x5f, 0x6c, 0x69, 0x6e, 0x65, + 0x73, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x68, 0x6f, 0x77, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x69, 0x66, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x20, 0x3d, 0x20, 0x69, + 0x6f, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x68, 0x6f, 0x77, 0x20, + 0x6f, 0x72, 0x20, 0x27, 0x72, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x69, 0x66, 0x20, 0x66, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, + 0x69, 0x6f, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x28, 0x66, 0x29, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, + 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x69, 0x6f, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x28, 0x29, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x78, + 0x5f, 0x69, 0x6f, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x28, 0x66, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x69, 0x6f, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, + 0x65, 0x28, 0x66, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, + 0x0a, 0x0a, 0x69, 0x6f, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x6c, 0x75, 0x61, + 0x74, 0x65, 0x78, 0x5f, 0x69, 0x6f, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x0a, 0x6d, 0x74, 0x2e, + 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x78, 0x5f, 0x69, + 0x6f, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x57, + 0x65, 0x20, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x6b, 0x70, 0x73, 0x65, 0x2e, 0x20, 0x54, + 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, + 0x73, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x43, 0x6f, 0x6e, 0x54, 0x65, 0x58, 0x74, 0x2e, 0x0a, 0x0a, + 0x69, 0x66, 0x20, 0x6b, 0x70, 0x73, 0x65, 0x75, 0x73, 0x65, 0x64, 0x20, 0x3d, 0x3d, 0x20, 0x31, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6f, 0x2e, 0x6f, 0x70, + 0x65, 0x6e, 0x20, 0x20, 0x3d, 0x20, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x78, 0x5f, 0x69, 0x6f, 0x5f, + 0x6f, 0x70, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6f, 0x2e, 0x70, 0x6f, 0x70, 0x65, + 0x6e, 0x20, 0x3d, 0x20, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x78, 0x5f, 0x69, 0x6f, 0x5f, 0x70, 0x6f, + 0x70, 0x65, 0x6e, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x69, 0x66, 0x20, 0x73, 0x61, 0x66, + 0x65, 0x72, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x3d, 0x20, 0x31, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x64, 0x75, + 0x6d, 0x6d, 0x79, 0x28, 0x73, 0x74, 0x72, 0x2c, 0x66, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x65, + 0x64, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x6e, 0x6c, + 0x28, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x22, 0x73, 0x61, 0x66, 0x65, 0x72, 0x20, 0x6f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x65, 0x74, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x25, 0x71, 0x20, 0x69, 0x73, 0x20, 0x25, 0x73, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x73, 0x74, 0x72, 0x2c, 0x66, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x22, 0x6c, 0x69, + 0x6d, 0x69, 0x74, 0x65, 0x64, 0x22, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x64, 0x69, 0x73, 0x61, 0x62, + 0x6c, 0x65, 0x64, 0x22, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x20, + 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x66, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x74, 0x79, 0x70, 0x65, 0x28, 0x68, 0x6f, 0x77, - 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x27, 0x20, 0x61, 0x6e, - 0x64, 0x20, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x68, 0x6f, 0x77, 0x2c, 0x27, 0x77, 0x27, 0x29, 0x20, - 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x66, 0x69, 0x6f, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x66, 0x69, 0x6c, 0x65, 0x6e, - 0x61, 0x6d, 0x65, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x77, 0x27, 0x29, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x69, 0x6f, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x72, - 0x64, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, - 0x72, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, - 0x72, 0x6e, 0x20, 0x66, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, - 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x78, 0x5f, - 0x69, 0x6f, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x6f, 0x6e, 0x6c, 0x79, - 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x68, 0x6f, 0x77, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, - 0x66, 0x20, 0x68, 0x6f, 0x77, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x68, 0x6f, 0x77, 0x20, 0x3d, 0x20, 0x27, 0x72, 0x27, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x6f, - 0x77, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x68, 0x6f, 0x77, 0x2c, 0x27, 0x5b, 0x5e, - 0x72, 0x62, 0x5d, 0x27, 0x2c, 0x27, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x69, 0x66, 0x20, 0x68, 0x6f, 0x77, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, - 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, - 0x6f, 0x77, 0x20, 0x3d, 0x20, 0x27, 0x72, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x20, 0x3d, 0x20, 0x69, 0x6f, 0x5f, 0x6f, 0x70, - 0x65, 0x6e, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x68, 0x6f, 0x77, 0x29, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x69, 0x66, 0x20, 0x66, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x66, 0x69, 0x6f, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x66, 0x69, 0x6c, - 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x72, 0x27, 0x29, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, - 0x72, 0x6e, 0x20, 0x66, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, - 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x78, 0x5f, - 0x69, 0x6f, 0x5f, 0x70, 0x6f, 0x70, 0x65, 0x6e, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x2e, 0x2e, - 0x2e, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x6b, 0x61, - 0x79, 0x2c, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x69, 0x6f, 0x5f, 0x63, - 0x68, 0x65, 0x63, 0x6b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x28, 0x6e, - 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6f, 0x6b, 0x61, 0x79, - 0x20, 0x61, 0x6e, 0x64, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, - 0x6f, 0x5f, 0x70, 0x6f, 0x70, 0x65, 0x6e, 0x28, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x2c, 0x2e, 0x2e, - 0x2e, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, - 0x75, 0x61, 0x74, 0x65, 0x78, 0x5f, 0x69, 0x6f, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x28, 0x6e, - 0x61, 0x6d, 0x65, 0x2c, 0x68, 0x6f, 0x77, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, - 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x20, 0x3d, 0x20, 0x69, 0x6f, 0x5f, 0x6f, - 0x70, 0x65, 0x6e, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x68, 0x6f, 0x77, 0x20, 0x6f, 0x72, 0x20, - 0x27, 0x72, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, - 0x66, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x69, 0x6f, 0x5f, - 0x72, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x28, 0x66, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, - 0x69, 0x6f, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, - 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, - 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x78, 0x5f, 0x69, 0x6f, - 0x5f, 0x72, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x28, 0x66, 0x29, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, - 0x6e, 0x20, 0x66, 0x69, 0x6f, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x28, 0x66, - 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x69, - 0x6f, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x78, - 0x5f, 0x69, 0x6f, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x0a, 0x6d, 0x74, 0x2e, 0x6c, 0x69, 0x6e, - 0x65, 0x73, 0x20, 0x3d, 0x20, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x78, 0x5f, 0x69, 0x6f, 0x5f, 0x72, - 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x57, 0x65, 0x20, 0x61, - 0x73, 0x73, 0x75, 0x6d, 0x65, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, - 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x6b, 0x70, 0x73, 0x65, 0x2e, 0x20, 0x54, 0x68, 0x69, 0x73, - 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x73, 0x65, 0x20, - 0x69, 0x6e, 0x20, 0x43, 0x6f, 0x6e, 0x54, 0x65, 0x58, 0x74, 0x2e, 0x0a, 0x0a, 0x69, 0x66, 0x20, - 0x6b, 0x70, 0x73, 0x65, 0x75, 0x73, 0x65, 0x64, 0x20, 0x3d, 0x3d, 0x20, 0x31, 0x20, 0x74, 0x68, - 0x65, 0x6e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x20, - 0x20, 0x3d, 0x20, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x78, 0x5f, 0x69, 0x6f, 0x5f, 0x6f, 0x70, 0x65, - 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6f, 0x2e, 0x70, 0x6f, 0x70, 0x65, 0x6e, 0x20, 0x3d, - 0x20, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x78, 0x5f, 0x69, 0x6f, 0x5f, 0x70, 0x6f, 0x70, 0x65, 0x6e, - 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x69, 0x66, 0x20, 0x73, 0x61, 0x66, 0x65, 0x72, 0x6f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x3d, 0x20, 0x31, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x73, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x20, - 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x73, 0x2e, 0x73, 0x70, 0x61, - 0x77, 0x6e, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, - 0x73, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x20, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x6f, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x65, 0x6e, 0x76, 0x20, 0x20, 0x3d, - 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x73, 0x2e, 0x74, 0x65, 0x6d, 0x70, - 0x64, 0x69, 0x72, 0x20, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, - 0x6f, 0x2e, 0x70, 0x6f, 0x70, 0x65, 0x6e, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x66, 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x28, + 0x73, 0x74, 0x72, 0x2c, 0x66, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x20, 0x3d, 0x20, + 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x6f, 0x73, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x20, 0x3d, 0x20, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x28, 0x22, 0x6f, 0x73, + 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x22, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, + 0x73, 0x2e, 0x73, 0x70, 0x61, 0x77, 0x6e, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6c, 0x6c, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x28, 0x22, 0x6f, 0x73, 0x2e, 0x73, 0x70, 0x61, + 0x77, 0x6e, 0x22, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x73, 0x2e, 0x65, 0x78, 0x65, 0x63, + 0x20, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x64, 0x75, 0x6d, + 0x6d, 0x79, 0x28, 0x22, 0x6f, 0x73, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x22, 0x29, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x6f, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x65, 0x6e, 0x76, 0x20, 0x20, 0x3d, 0x20, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x28, 0x22, 0x6f, 0x73, 0x2e, + 0x73, 0x65, 0x74, 0x65, 0x6e, 0x76, 0x22, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x73, 0x2e, + 0x74, 0x65, 0x6d, 0x70, 0x64, 0x69, 0x72, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, + 0x6c, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x28, 0x22, 0x6f, 0x73, 0x2e, 0x74, 0x65, 0x6d, 0x70, 0x64, + 0x69, 0x72, 0x22, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6f, 0x2e, 0x70, 0x6f, 0x70, + 0x65, 0x6e, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x64, 0x75, + 0x6d, 0x6d, 0x79, 0x28, 0x22, 0x69, 0x6f, 0x2e, 0x70, 0x6f, 0x70, 0x65, 0x6e, 0x22, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x20, 0x20, 0x20, 0x20, 0x3d, - 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x6e, - 0x61, 0x6d, 0x65, 0x20, 0x20, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, - 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x20, 0x20, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x0a, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6f, 0x2e, 0x74, 0x6d, 0x70, 0x66, 0x69, 0x6c, 0x65, 0x20, - 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6f, 0x2e, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x20, 0x20, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x6c, 0x66, 0x73, 0x2e, 0x63, 0x68, 0x64, 0x69, 0x72, 0x20, 0x20, 0x3d, 0x20, 0x6e, 0x69, 0x6c, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x66, 0x73, 0x2e, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x20, 0x20, - 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x66, 0x73, 0x2e, 0x74, 0x6f, - 0x75, 0x63, 0x68, 0x20, 0x20, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, - 0x66, 0x73, 0x2e, 0x72, 0x6d, 0x64, 0x69, 0x72, 0x20, 0x20, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x6c, 0x66, 0x73, 0x2e, 0x6d, 0x6b, 0x64, 0x69, 0x72, 0x20, 0x20, 0x3d, - 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6f, 0x2e, 0x73, 0x61, 0x76, - 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x20, 0x20, 0x3d, 0x20, 0x6c, 0x75, 0x61, 0x74, 0x65, - 0x78, 0x5f, 0x69, 0x6f, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x6f, 0x6e, - 0x6c, 0x79, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x69, 0x66, 0x20, 0x73, 0x61, 0x66, 0x65, - 0x72, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x3d, 0x20, 0x31, 0x20, 0x6f, 0x72, 0x20, - 0x73, 0x68, 0x65, 0x6c, 0x6c, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x31, - 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x66, 0x69, 0x20, 0x3d, - 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x28, 0x27, 0x66, 0x66, 0x69, 0x27, 0x29, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x6b, 0x2c, 0x20, 0x76, 0x20, 0x69, 0x6e, 0x20, - 0x6e, 0x65, 0x78, 0x74, 0x2c, 0x20, 0x66, 0x66, 0x69, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6b, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x67, 0x63, - 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x66, 0x66, 0x69, 0x5b, 0x6b, 0x5d, 0x20, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x66, 0x69, 0x20, 0x3d, 0x20, 0x6e, 0x69, - 0x6c, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x6f, 0x73, 0x2e, 0x5b, 0x65, - 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x7c, 0x6f, 0x73, 0x2e, 0x73, 0x70, 0x61, 0x77, 0x6e, 0x7c, - 0x6f, 0x73, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x5d, 0x20, 0x61, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, - 0x20, 0x61, 0x72, 0x65, 0x20, 0x73, 0x68, 0x65, 0x6c, 0x6c, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, - 0x20, 0x61, 0x77, 0x61, 0x72, 0x65, 0x29, 0x0a, 0x0a, 0x0a, 0x69, 0x66, 0x20, 0x6d, 0x64, 0x35, - 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x20, 0x73, 0x75, 0x6d, 0x20, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x6d, 0x64, 0x35, 0x2e, 0x73, 0x75, - 0x6d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x67, 0x73, 0x75, 0x62, - 0x20, 0x20, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, - 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, - 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x79, 0x74, 0x65, - 0x20, 0x20, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x62, 0x79, 0x74, 0x65, - 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, - 0x64, 0x35, 0x2e, 0x73, 0x75, 0x6d, 0x68, 0x65, 0x78, 0x61, 0x28, 0x6b, 0x29, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x28, 0x67, 0x73, - 0x75, 0x62, 0x28, 0x73, 0x75, 0x6d, 0x28, 0x6b, 0x29, 0x2c, 0x20, 0x22, 0x2e, 0x22, 0x2c, 0x20, - 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x63, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, - 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x22, 0x25, 0x30, 0x32, 0x78, 0x22, 0x2c, 0x62, 0x79, 0x74, - 0x65, 0x28, 0x63, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, - 0x64, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x64, 0x35, 0x2e, 0x73, 0x75, - 0x6d, 0x48, 0x45, 0x58, 0x41, 0x28, 0x6b, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x28, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x75, - 0x6d, 0x28, 0x6b, 0x29, 0x2c, 0x20, 0x22, 0x2e, 0x22, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x28, 0x63, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, - 0x28, 0x22, 0x25, 0x30, 0x32, 0x58, 0x22, 0x2c, 0x62, 0x79, 0x74, 0x65, 0x28, 0x63, 0x29, 0x29, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x29, 0x29, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x00 + 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x28, 0x22, 0x69, + 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x22, 0x2c, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x78, 0x5f, 0x69, + 0x6f, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x6f, 0x6e, 0x6c, 0x79, 0x29, + 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x20, + 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x28, + 0x22, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x29, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x20, 0x20, 0x3d, 0x20, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x28, 0x22, 0x6f, 0x73, 0x2e, 0x72, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x22, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6f, 0x2e, + 0x74, 0x6d, 0x70, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, + 0x6c, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x28, 0x22, 0x69, 0x6f, 0x2e, 0x74, 0x6d, 0x70, 0x66, 0x69, + 0x6c, 0x65, 0x22, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6f, 0x2e, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x20, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x64, 0x75, 0x6d, + 0x6d, 0x79, 0x28, 0x22, 0x69, 0x6f, 0x2e, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0x29, 0x0a, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x66, 0x73, 0x2e, 0x63, 0x68, 0x64, 0x69, 0x72, 0x20, 0x20, + 0x3d, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x28, 0x22, + 0x6c, 0x66, 0x73, 0x2e, 0x63, 0x68, 0x64, 0x69, 0x72, 0x22, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x6c, 0x66, 0x73, 0x2e, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6c, 0x6c, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x28, 0x22, 0x6c, 0x66, 0x73, 0x2e, 0x6c, + 0x6f, 0x63, 0x6b, 0x22, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x66, 0x73, 0x2e, 0x74, 0x6f, + 0x75, 0x63, 0x68, 0x20, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x64, 0x75, + 0x6d, 0x6d, 0x79, 0x28, 0x22, 0x6c, 0x66, 0x73, 0x2e, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x22, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x66, 0x73, 0x2e, 0x72, 0x6d, 0x64, 0x69, 0x72, 0x20, 0x20, + 0x3d, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x28, 0x22, + 0x6c, 0x66, 0x73, 0x2e, 0x72, 0x6d, 0x64, 0x69, 0x72, 0x22, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x6c, 0x66, 0x73, 0x2e, 0x6d, 0x6b, 0x64, 0x69, 0x72, 0x20, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6c, 0x6c, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x28, 0x22, 0x6c, 0x66, 0x73, 0x2e, 0x6d, + 0x6b, 0x64, 0x69, 0x72, 0x22, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x69, 0x66, 0x20, + 0x73, 0x61, 0x66, 0x65, 0x72, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x3d, 0x20, 0x31, + 0x20, 0x6f, 0x72, 0x20, 0x73, 0x68, 0x65, 0x6c, 0x6c, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, 0x20, + 0x7e, 0x3d, 0x20, 0x31, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, + 0x66, 0x69, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x28, 0x27, 0x66, 0x66, + 0x69, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x6b, 0x2c, 0x20, 0x76, + 0x20, 0x69, 0x6e, 0x20, 0x6e, 0x65, 0x78, 0x74, 0x2c, 0x20, 0x66, 0x66, 0x69, 0x20, 0x64, 0x6f, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6b, 0x20, 0x7e, 0x3d, + 0x20, 0x27, 0x67, 0x63, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x66, 0x69, 0x5b, 0x6b, 0x5d, 0x20, 0x3d, 0x20, + 0x6e, 0x69, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x66, 0x69, 0x20, + 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x6f, + 0x73, 0x2e, 0x5b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x7c, 0x6f, 0x73, 0x2e, 0x73, 0x70, + 0x61, 0x77, 0x6e, 0x7c, 0x6f, 0x73, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x5d, 0x20, 0x61, 0x6c, 0x72, + 0x65, 0x61, 0x64, 0x79, 0x20, 0x61, 0x72, 0x65, 0x20, 0x73, 0x68, 0x65, 0x6c, 0x6c, 0x65, 0x73, + 0x63, 0x61, 0x70, 0x65, 0x20, 0x61, 0x77, 0x61, 0x72, 0x65, 0x29, 0x0a, 0x0a, 0x0a, 0x69, 0x66, + 0x20, 0x6d, 0x64, 0x35, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x75, 0x6d, 0x20, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x6d, 0x64, + 0x35, 0x2e, 0x73, 0x75, 0x6d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x67, 0x73, 0x75, 0x62, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x67, 0x73, 0x75, 0x62, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x62, 0x79, 0x74, 0x65, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x62, 0x79, 0x74, 0x65, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6d, 0x64, 0x35, 0x2e, 0x73, 0x75, 0x6d, 0x68, 0x65, 0x78, 0x61, 0x28, 0x6b, + 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x28, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x75, 0x6d, 0x28, 0x6b, 0x29, 0x2c, 0x20, 0x22, + 0x2e, 0x22, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x63, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x22, 0x25, 0x30, 0x32, 0x78, 0x22, + 0x2c, 0x62, 0x79, 0x74, 0x65, 0x28, 0x63, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x65, 0x6e, 0x64, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x64, + 0x35, 0x2e, 0x73, 0x75, 0x6d, 0x48, 0x45, 0x58, 0x41, 0x28, 0x6b, 0x29, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x28, 0x67, 0x73, 0x75, + 0x62, 0x28, 0x73, 0x75, 0x6d, 0x28, 0x6b, 0x29, 0x2c, 0x20, 0x22, 0x2e, 0x22, 0x2c, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x63, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x28, 0x22, 0x25, 0x30, 0x32, 0x58, 0x22, 0x2c, 0x62, 0x79, 0x74, 0x65, + 0x28, 0x63, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, + 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x00 }; return luaL_dostring(L, (const char*) luatex_core_lua); }
\ No newline at end of file diff --git a/Build/source/texk/web2c/luatexdir/lua/luatex-core.lua b/Build/source/texk/web2c/luatexdir/lua/luatex-core.lua index 15e0d8c830d..18bb7fcf0ed 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luatex-core.lua +++ b/Build/source/texk/web2c/luatexdir/lua/luatex-core.lua @@ -1,213 +1,229 @@ --- if not modules then modules = { } end modules ['luatex-core'] = { --- version = 1.001, --- comment = 'companion to luatex', --- author = 'Hans Hagen & Luigi Scarso', --- copyright = 'LuaTeX Development Team', --- } - -LUATEXCOREVERSION = 1.002 - --- This file overloads some Lua functions. The readline variants provide the same --- functionality as LuaTeX <= 1.04 and doing it this way permits us to keep the --- original io libraries clean. Performance is probably even a bit better now. - -local type, next, getmetatable, require = type, next, getmetatable, require -local find, gsub = string.find, string.gsub - -local io_open = io.open -local io_popen = io.popen -local io_lines = io.lines - -local fio_readline = fio.readline -local fio_checkpermission = fio.checkpermission -local fio_recordfilename = fio.recordfilename - -local mt = getmetatable(io.stderr) -local mt_lines = mt.lines -local saferoption = status.safer_option -local shellescape = status.shell_escape -- 0 (disabled) 1 (anything) 2 (restricted) -local kpseused = status.kpse_used -- 0 1 - -io.saved_open = io_open -- can be protected --- (deleted for tl17 rebuild) io.saved_popen = io_popen -- can be protected -io.saved_lines = io_lines -- always readonly -mt.saved_lines = mt_lines -- always readonly - -local function luatex_io_open(name,how) - if not how then - how = 'r' - end - local f = io_open(name,how) - if f then - if type(how) == 'string' and find(how,'w') then - fio_recordfilename(name,'w') - else - fio_recordfilename(name,'r') - end - end - return f -end - -local function luatex_io_open_readonly(name,how) - if how then - how = 'r' - else - how = gsub(how,'[^rb]','') - if how == '' then - how = 'r' - end - end - local f = io_open(name,how) - if f then - fio_recordfilename(name,'r') - end - return f -end - -local function luatex_io_popen(name,...) - local okay, found = fio_checkpermission(name) - if okay and found then - return io_popen(found,...) - end -end - -local function luatex_io_lines(name,how) - if name then - local f = io_open(name,how or 'r') - if f then - return function() - return fio_readline(f) - end - end - else - return io_lines() - end -end - -local function luatex_io_readline(f) - return function() - return fio_readline(f) - end -end - -io.lines = luatex_io_lines -mt.lines = luatex_io_readline - --- We assume management to be provided by the replacement of kpse. This is the --- case in ConTeXt. - -if kpseused == 1 then - - io.open = luatex_io_open - io.popen = luatex_io_popen - -end - -if saferoption == 1 then - - os.execute = nil - os.spawn = nil - os.exec = nil - os.setenv = nil - os.tempdir = nil - - io.popen = nil - io.open = nil - - os.rename = nil - os.remove = nil - - io.tmpfile = nil - io.output = nil - - lfs.chdir = nil - lfs.lock = nil - lfs.touch = nil - lfs.rmdir = nil - lfs.mkdir = nil - - io.saved_open = luatex_io_open_readonly - -end - -if saferoption == 1 or shellescape ~= 1 then - - ffi = require('ffi') - for k, v in next, ffi do - if k ~= 'gc' then - ffi[k] = nil - end - end - ffi = nil - -end - --- os.[execute|os.spawn|os.exec] already are shellescape aware) - - -if md5 then - - local sum = md5.sum - local gsub = string.gsub - local format = string.format - local byte = string.byte - - function md5.sumhexa(k) - return (gsub(sum(k), ".", function(c) - return format("%02x",byte(c)) - end)) - end - - function md5.sumHEXA(k) - return (gsub(sum(k), ".", function(c) - return format("%02X",byte(c)) - end)) - end - -end - -if utilities and utilities.merger and utilities.merger.compact then - - local byte, format, gmatch = string.byte, string.format, string.gmatch - local concat = table.concat - - local data = gsub(io.loaddata('luatex-core.lua'),'if%s+utilities.*','') - local t = { } - local r = { } - local n = 0 - local d = gsub(data,'\r\n','\n') -- be nice for unix - local s = utilities.merger.compact(d) -- no comments and less spaces - - t[#t+1] = '/* generated from and by luatex-core.lua */' - t[#t+1] = '' - -- t[#t+1] = format('/*\n\n%s\n\n*/',d) - -- t[#t+1] = '' - t[#t+1] = '#include "lua.h"' - t[#t+1] = '#include "lauxlib.h"' - t[#t+1] = '' - t[#t+1] = 'int load_luatex_core_lua (lua_State * L);' - t[#t+1] = '' - t[#t+1] = 'int load_luatex_core_lua (lua_State * L)' - t[#t+1] = '{' - t[#t+1] = ' static unsigned char luatex_core_lua[] = {' - for c in gmatch(d,'.') do - if n == 16 then - n = 1 - t[#t+1] = ' ' .. concat(r,', ') .. ',' - else - n = n + 1 - end - r[n] = format('0x%02x',byte(c)) - end - n = n + 1 - r[n] = '0x00' - t[#t+1] = ' ' .. concat(r,', ',1,n) - t[#t+1] = ' };' - -- t[#t+1] = format('unsigned int luatex_core_lua_len = 0x%x;',#d+1) - t[#t+1] = ' return luaL_dostring(L, (const char*) luatex_core_lua);' - t[#t+1] = '}' - - io.savedata('luatex-core.c',concat(t,'\n')) - io.savedata('luatex-core-stripped.lua',s) - -end +-- if not modules then modules = { } end modules ['luatex-core'] = {
+-- version = 1.001,
+-- comment = 'companion to luatex',
+-- author = 'Hans Hagen & Luigi Scarso',
+-- copyright = 'LuaTeX Development Team',
+-- }
+
+LUATEXCOREVERSION = 1.003
+
+-- This file overloads some Lua functions. The readline variants provide the same
+-- functionality as LuaTeX <= 1.04 and doing it this way permits us to keep the
+-- original io libraries clean. Performance is probably even a bit better now.
+
+local type, next, getmetatable, require = type, next, getmetatable, require
+local find, gsub, format = string.find, string.gsub, string.format
+
+local io_open = io.open
+local io_popen = io.popen
+local io_lines = io.lines
+
+local fio_readline = fio.readline
+local fio_checkpermission = fio.checkpermission
+local fio_recordfilename = fio.recordfilename
+
+local mt = getmetatable(io.stderr)
+local mt_lines = mt.lines
+local saferoption = status.safer_option
+local shellescape = status.shell_escape -- 0 (disabled) 1 (anything) 2 (restricted)
+local kpseused = status.kpse_used -- 0 1
+
+local write_nl = texio.write_nl
+
+io.saved_lines = io_lines -- always readonly
+mt.saved_lines = mt_lines -- always readonly
+
+local function luatex_io_open(name,how)
+ if not how then
+ how = 'r'
+ end
+ local f = io_open(name,how)
+ if f then
+ if type(how) == 'string' and find(how,'w') then
+ fio_recordfilename(name,'w')
+ else
+ fio_recordfilename(name,'r')
+ end
+ end
+ return f
+end
+
+local function luatex_io_open_readonly(name,how)
+ if how then
+ how = 'r'
+ else
+ how = gsub(how,'[^rb]','')
+ if how == '' then
+ how = 'r'
+ end
+ end
+ local f = io_open(name,how)
+ if f then
+ fio_recordfilename(name,'r')
+ end
+ return f
+end
+
+local function luatex_io_popen(name,...)
+ local okay, found = fio_checkpermission(name)
+ if okay and found then
+ return io_popen(found,...)
+ end
+end
+
+local function luatex_io_lines(name,how)
+ if name then
+ local f = io_open(name,how or 'r')
+ if f then
+ return function()
+ return fio_readline(f)
+ end
+ end
+ else
+ return io_lines()
+ end
+end
+
+local function luatex_io_readline(f)
+ return function()
+ return fio_readline(f)
+ end
+end
+
+io.lines = luatex_io_lines
+mt.lines = luatex_io_readline
+
+-- We assume management to be provided by the replacement of kpse. This is the
+-- case in ConTeXt.
+
+if kpseused == 1 then
+
+ io.open = luatex_io_open
+ io.popen = luatex_io_popen
+
+end
+
+if saferoption == 1 then
+
+ local function installdummy(str,f)
+ local reported = false
+ return function(...)
+ if not reported then
+ write_nl(format("safer option set, function %q is %s",
+ str,f and "limited" or "disabled"))
+ reported = true
+ end
+ if f then
+ return f(...)
+ end
+ end
+ end
+
+ local function installlimit(str,f)
+ local reported = false
+ end
+
+ os.execute = installdummy("os.execute")
+ os.spawn = installdummy("os.spawn")
+ os.exec = installdummy("os.exec")
+ os.setenv = installdummy("os.setenv")
+ os.tempdir = installdummy("os.tempdir")
+
+ io.popen = installdummy("io.popen")
+ io.open = installdummy("io.open",luatex_io_open_readonly)
+
+ os.rename = installdummy("os.rename")
+ os.remove = installdummy("os.remove")
+
+ io.tmpfile = installdummy("io.tmpfile")
+ io.output = installdummy("io.output")
+
+ lfs.chdir = installdummy("lfs.chdir")
+ lfs.lock = installdummy("lfs.lock")
+ lfs.touch = installdummy("lfs.touch")
+ lfs.rmdir = installdummy("lfs.rmdir")
+ lfs.mkdir = installdummy("lfs.mkdir")
+
+end
+
+if saferoption == 1 or shellescape ~= 1 then
+
+ ffi = require('ffi')
+ for k, v in next, ffi do
+ if k ~= 'gc' then
+ ffi[k] = nil
+ end
+ end
+ ffi = nil
+
+end
+
+-- os.[execute|os.spawn|os.exec] already are shellescape aware)
+
+
+if md5 then
+
+ local sum = md5.sum
+ local gsub = string.gsub
+ local format = string.format
+ local byte = string.byte
+
+ function md5.sumhexa(k)
+ return (gsub(sum(k), ".", function(c)
+ return format("%02x",byte(c))
+ end))
+ end
+
+ function md5.sumHEXA(k)
+ return (gsub(sum(k), ".", function(c)
+ return format("%02X",byte(c))
+ end))
+ end
+
+end
+
+if utilities and utilities.merger and utilities.merger.compact then
+
+ local byte, format, gmatch = string.byte, string.format, string.gmatch
+ local concat = table.concat
+
+ local data = gsub(io.loaddata('luatex-core.lua'),'if%s+utilities.*','')
+ local t = { }
+ local r = { }
+ local n = 0
+ local d = gsub(data,'\r\n','\n') -- be nice for unix
+ local s = utilities.merger.compact(d) -- no comments and less spaces
+
+ t[#t+1] = '/* generated from and by luatex-core.lua */'
+ t[#t+1] = ''
+ -- t[#t+1] = format('/*\n\n%s\n\n*/',d)
+ -- t[#t+1] = ''
+ t[#t+1] = '#include "lua.h"'
+ t[#t+1] = '#include "lauxlib.h"'
+ t[#t+1] = ''
+ t[#t+1] = 'int load_luatex_core_lua (lua_State * L);'
+ t[#t+1] = ''
+ t[#t+1] = 'int load_luatex_core_lua (lua_State * L)'
+ t[#t+1] = '{'
+ t[#t+1] = ' static unsigned char luatex_core_lua[] = {'
+ for c in gmatch(d,'.') do
+ if n == 16 then
+ n = 1
+ t[#t+1] = ' ' .. concat(r,', ') .. ','
+ else
+ n = n + 1
+ end
+ r[n] = format('0x%02x',byte(c))
+ end
+ n = n + 1
+ r[n] = '0x00'
+ t[#t+1] = ' ' .. concat(r,', ',1,n)
+ t[#t+1] = ' };'
+ -- t[#t+1] = format('unsigned int luatex_core_lua_len = 0x%x;',#d+1)
+ t[#t+1] = ' return luaL_dostring(L, (const char*) luatex_core_lua);'
+ t[#t+1] = '}'
+
+ io.savedata('luatex-core.c',concat(t,'\n'))
+ io.savedata('luatex-core-stripped.lua',s)
+
+end
diff --git a/Build/source/texk/web2c/luatexdir/lua/luatoken.w b/Build/source/texk/web2c/luatexdir/lua/luatoken.w index a567c7f7a2b..e9740ffc676 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luatoken.w +++ b/Build/source/texk/web2c/luatexdir/lua/luatoken.w @@ -96,6 +96,7 @@ command_item command_names[] = { {"boundary", boundary_cmd, NULL}, {"radical", radical_cmd, NULL}, {"super_sub_script", super_sub_script_cmd, NULL}, + {"no_super_sub_script", no_super_sub_script_cmd, NULL}, {"math_shift_cs", math_shift_cs_cmd, NULL}, {"end_cs_name", end_cs_name_cmd, NULL}, {"char_ghost", char_ghost_cmd, NULL}, diff --git a/Build/source/texk/web2c/luatexdir/luaffi/ctype.c b/Build/source/texk/web2c/luatexdir/luaffi/ctype.c index c93fea03210..f477ea5bc31 100644 --- a/Build/source/texk/web2c/luatexdir/luaffi/ctype.c +++ b/Build/source/texk/web2c/luatexdir/luaffi/ctype.c @@ -245,6 +245,8 @@ void* to_cdata(lua_State* L, int idx, struct ctype* ct) lua_pop(L, 1); /* mt */ cd = (struct cdata*) lua_touserdata(L, idx); + + if (!cd) {lua_pushnil(L);return NULL;} *ct = cd->type; lua_getuservalue(L, idx); diff --git a/Build/source/texk/web2c/luatexdir/luaffi/ffi.c b/Build/source/texk/web2c/luatexdir/luaffi/ffi.c index abeeb5f1fe0..7771b512db5 100644 --- a/Build/source/texk/web2c/luatexdir/luaffi/ffi.c +++ b/Build/source/texk/web2c/luatexdir/luaffi/ffi.c @@ -387,7 +387,12 @@ static size_t unpack_vararg(lua_State* L, int i, char* to) } else if (ct.type == INT64_TYPE) { *(int64_t*) to = *(int64_t*) p; return sizeof(int64_t); - } + + } else if (ct.type == FUNCTION_PTR_TYPE) { + *(cfunction *) to = *(cfunction *)p; + return sizeof(cfunction); + } + goto err; case LUA_TNIL: diff --git a/Build/source/texk/web2c/luatexdir/luaffi/ffi.h b/Build/source/texk/web2c/luatexdir/luaffi/ffi.h index cfc25424175..8be6eccc192 100644 --- a/Build/source/texk/web2c/luatexdir/luaffi/ffi.h +++ b/Build/source/texk/web2c/luatexdir/luaffi/ffi.h @@ -370,9 +370,9 @@ __declspec(align(16)) #endif struct cdata { const struct ctype type -#ifdef __GNUC__ - __attribute__ ((aligned(16))) -#endif +/*#ifdef __GNUC__*/ +/* __attribute__ ((aligned(16)))*/ +/*#endif*/ ; }; diff --git a/Build/source/texk/web2c/luatexdir/luapeg/lpeg.c b/Build/source/texk/web2c/luatexdir/luapeg/lpeg.c index 30f54522de5..c2a2287dc7f 100644 --- a/Build/source/texk/web2c/luatexdir/luapeg/lpeg.c +++ b/Build/source/texk/web2c/luatexdir/luapeg/lpeg.c @@ -1,7 +1,7 @@ #include "lpeg.h" /* -** $Id: lpprint.c,v 1.9 2015/06/15 16:09:57 roberto Exp $ +** $Id: lpprint.c,v 1.10 2016/09/13 16:06:03 roberto Exp $ ** Copyright 2007, Lua.org & PUC-Rio (see 'lpeg.html' for license) */ @@ -39,13 +39,13 @@ void printcharset (const byte *st) { } -static void printcapkind (int kind) { +static const char *capkind (int kind) { const char *const modes[] = { "close", "position", "constant", "backref", "argument", "simple", "table", "function", "query", "string", "num", "substitution", "fold", "runtime", "group"}; - printf("%s", modes[kind]); + return modes[kind]; } @@ -75,13 +75,12 @@ void printinst (const Instruction *op, const Instruction *p) { break; } case IFullCapture: { - printcapkind(getkind(p)); - printf(" (size = %d) (idx = %d)", getoff(p), p->i.key); + printf("%s (size = %d) (idx = %d)", + capkind(getkind(p)), getoff(p), p->i.key); break; } case IOpenCapture: { - printcapkind(getkind(p)); - printf(" (idx = %d)", p->i.key); + printf("%s (idx = %d)", capkind(getkind(p)), p->i.key); break; } case ISet: { @@ -126,8 +125,8 @@ void printpatt (Instruction *p, int n) { #if defined(LPEG_DEBUG) static void printcap (Capture *cap) { - printcapkind(cap->kind); - printf(" (idx: %d - size: %d) -> %p\n", cap->idx, cap->siz, cap->s); + printf("%s (idx: %d - size: %d) -> %p\n", + capkind(cap->kind), cap->idx, cap->siz, cap->s); } @@ -179,7 +178,8 @@ void printtree (TTree *tree, int ident) { break; } case TOpenCall: case TCall: { - printf(" key: %d\n", tree->key); + assert(sib2(tree)->tag == TRule); + printf(" key: %d (rule: %d)\n", tree->key, sib2(tree)->cap); break; } case TBehind: { @@ -188,7 +188,7 @@ void printtree (TTree *tree, int ident) { break; } case TCapture: { - printf(" cap: %d key: %d n: %d\n", tree->cap, tree->key, tree->u.n); + printf(" kind: '%s' key: %d\n", capkind(tree->cap), tree->key); printtree(sib1(tree), ident + 2); break; } @@ -244,9 +244,8 @@ void printktable (lua_State *L, int idx) { /* }====================================================== */ #endif - /* -** $Id: lpvm.c,v 1.6 2015/09/28 17:01:25 roberto Exp $ +** $Id: lpvm.c,v 1.9 2016/06/03 20:11:18 roberto Exp $ ** Copyright 2007, Lua.org & PUC-Rio (see 'lpeg.html' for license) */ @@ -292,14 +291,16 @@ typedef struct Stack { /* -** Double the size of the array of captures +** Make the size of the array of captures 'cap' twice as large as needed +** (which is 'captop'). ('n' is the number of new elements.) */ -static Capture *doublecap (lua_State *L, Capture *cap, int captop, int ptop) { +static Capture *doublecap (lua_State *L, Capture *cap, int captop, + int n, int ptop) { Capture *newc; if (captop >= INT_MAX/((int)sizeof(Capture) * 2)) luaL_error(L, "too many captures"); newc = (Capture *)lua_newuserdata(L, captop * 2 * sizeof(Capture)); - memcpy(newc, cap, captop * sizeof(Capture)); + memcpy(newc, cap, (captop - n) * sizeof(Capture)); lua_replace(L, caplistidx(ptop)); return newc; } @@ -360,8 +361,8 @@ static int resdyncaptures (lua_State *L, int fr, int curr, int limit) { */ static void adddyncaptures (const char *s, Capture *base, int n, int fd) { int i; - /* Cgroup capture is already there */ - assert(base[0].kind == Cgroup && base[0].siz == 0); + base[0].kind = Cgroup; /* create group capture */ + base[0].siz = 0; base[0].idx = 0; /* make it an anonymous group */ for (i = 1; i <= n; i++) { /* add runtime captures */ base[i].kind = Cruntime; @@ -404,10 +405,11 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, lua_pushlightuserdata(L, stackbase); for (;;) { #if defined(DEBUG) + printf("-------------------------------------\n"); + printcaplist(capture, capture + captop); printf("s: |%s| stck:%d, dyncaps:%d, caps:%d ", - s, stack - getstackbase(L, ptop), ndyncap, captop); + s, (int)(stack - getstackbase(L, ptop)), ndyncap, captop); printinst(op, p); - printcaplist(capture, capture + captop); #endif assert(stackidx(ptop) + ndyncap == lua_gettop(L) && ndyncap <= captop); switch ((Opcode)p->i.code) { @@ -531,6 +533,9 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, ndyncap -= removedyncap(L, capture, stack->caplevel, captop); captop = stack->caplevel; p = stack->p; +#if defined(DEBUG) + printf("**FAIL**\n"); +#endif continue; } case ICloseRunTime: { @@ -540,16 +545,19 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, cs.s = o; cs.L = L; cs.ocap = capture; cs.ptop = ptop; n = runtimecap(&cs, capture + captop, s, &rem); /* call function */ captop -= n; /* remove nested captures */ + ndyncap -= rem; /* update number of dynamic captures */ fr -= rem; /* 'rem' items were popped from Lua stack */ res = resdyncaptures(L, fr, s - o, e - o); /* get result */ if (res == -1) /* fail? */ goto fail; s = o + res; /* else update current position */ n = lua_gettop(L) - fr + 1; /* number of new captures */ - ndyncap += n - rem; /* update number of dynamic captures */ + ndyncap += n; /* update number of dynamic captures */ if (n > 0) { /* any new capture? */ + if (fr + n >= SHRT_MAX) + luaL_error(L, "too many results in match-time capture"); if ((captop += n + 2) >= capsize) { - capture = doublecap(L, capture, captop, ptop); + capture = doublecap(L, capture, captop, n + 2, ptop); capsize = 2 * captop; } /* add new captures to 'capture' list */ @@ -586,7 +594,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, capture[captop].idx = p->i.key; capture[captop].kind = getkind(p); if (++captop >= capsize) { - capture = doublecap(L, capture, captop, ptop); + capture = doublecap(L, capture, captop, 0, ptop); capsize = 2 * captop; } p++; @@ -601,7 +609,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, /* -** $Id: lpcode.c,v 1.23 2015/06/12 18:36:47 roberto Exp $ +** $Id: lpcode.c,v 1.24 2016/09/15 17:46:13 roberto Exp $ ** Copyright 2007, Lua.org & PUC-Rio (see 'lpeg.html' for license) */ @@ -728,6 +736,27 @@ int tocharset (TTree *tree, Charset *cs) { /* +** Visit a TCall node taking care to stop recursion. If node not yet +** visited, return 'f(sib2(tree))', otherwise return 'def' (default +** value) +*/ +static int callrecursive (TTree *tree, int f (TTree *t), int def) { + int key = tree->key; + assert(tree->tag == TCall); + assert(sib2(tree)->tag == TRule); + if (key == 0) /* node already visited? */ + return def; /* return default value */ + else { /* first visit */ + int result; + tree->key = 0; /* mark call as already visited */ + result = f(sib2(tree)); /* go to called rule */ + tree->key = key; /* restore tree */ + return result; + } +} + + +/* ** Check whether a pattern tree has captures */ int hascaptures (TTree *tree) { @@ -736,14 +765,17 @@ int hascaptures (TTree *tree) { case TCapture: case TRunTime: return 1; case TCall: - tree = sib2(tree); goto tailcall; /* return hascaptures(sib2(tree)); */ + return callrecursive(tree, hascaptures, 0); + case TRule: /* do not follow siblings */ + tree = sib1(tree); goto tailcall; case TOpenCall: assert(0); default: { switch (numsiblings[tree->tag]) { case 1: /* return hascaptures(sib1(tree)); */ tree = sib1(tree); goto tailcall; case 2: - if (hascaptures(sib1(tree))) return 1; + if (hascaptures(sib1(tree))) + return 1; /* else return hascaptures(sib2(tree)); */ tree = sib2(tree); goto tailcall; default: assert(numsiblings[tree->tag] == 0); return 0; @@ -810,9 +842,9 @@ int checkaux (TTree *tree, int pred) { /* ** number of characters to match a pattern (or -1 if variable) -** ('count' avoids infinite loops for grammars) */ -int fixedlenx (TTree *tree, int count, int len) { +int fixedlen (TTree *tree) { + int len = 0; /* to accumulate in tail calls */ tailcall: switch (tree->tag) { case TChar: case TSet: case TAny: @@ -822,26 +854,29 @@ int fixedlenx (TTree *tree, int count, int len) { case TRep: case TRunTime: case TOpenCall: return -1; case TCapture: case TRule: case TGrammar: - /* return fixedlenx(sib1(tree), count); */ + /* return fixedlen(sib1(tree)); */ tree = sib1(tree); goto tailcall; - case TCall: - if (count++ >= MAXRULES) - return -1; /* may be a loop */ - /* else return fixedlenx(sib2(tree), count); */ - tree = sib2(tree); goto tailcall; + case TCall: { + int n1 = callrecursive(tree, fixedlen, -1); + if (n1 < 0) + return -1; + else + return len + n1; + } case TSeq: { - len = fixedlenx(sib1(tree), count, len); - if (len < 0) return -1; - /* else return fixedlenx(sib2(tree), count, len); */ - tree = sib2(tree); goto tailcall; + int n1 = fixedlen(sib1(tree)); + if (n1 < 0) + return -1; + /* else return fixedlen(sib2(tree)) + len; */ + len += n1; tree = sib2(tree); goto tailcall; } case TChoice: { - int n1, n2; - n1 = fixedlenx(sib1(tree), count, len); - if (n1 < 0) return -1; - n2 = fixedlenx(sib2(tree), count, len); - if (n1 == n2) return n1; - else return -1; + int n1 = fixedlen(sib1(tree)); + int n2 = fixedlen(sib2(tree)); + if (n1 != n2 || n1 < 0) + return -1; + else + return len + n1; } default: assert(0); return 0; }; @@ -1312,9 +1347,10 @@ static void codeand (CompileState *compst, TTree *tree, int tt) { /* -** Captures: if pattern has fixed (and not too big) length, use -** a single IFullCapture instruction after the match; otherwise, -** enclose the pattern with OpenCapture - CloseCapture. +** Captures: if pattern has fixed (and not too big) length, and it +** has no nested captures, use a single IFullCapture instruction +** after the match; otherwise, enclose the pattern with OpenCapture - +** CloseCapture. */ static void codecapture (CompileState *compst, TTree *tree, int tt, const Charset *fl) { @@ -1586,8 +1622,6 @@ Instruction *compile (lua_State *L, Pattern *p) { /* }====================================================== */ - - /* ** $Id: lpcap.c,v 1.6 2015/06/15 16:09:57 roberto Exp $ ** Copyright 2007, Lua.org & PUC-Rio (see 'lpeg.html' for license) @@ -2126,7 +2160,7 @@ int getcaptures (lua_State *L, const char *s, const char *r, int ptop) { /* -** $Id: lptree.c,v 1.21 2015/09/28 17:01:25 roberto Exp $ +** $Id: lptree.c,v 1.22 2016/09/13 18:10:22 roberto Exp $ ** Copyright 2013, Lua.org & PUC-Rio (see 'lpeg.html' for license) */ @@ -2191,7 +2225,7 @@ static void fixonecall (lua_State *L, int postable, TTree *g, TTree *t) { t->tag = TCall; t->u.ps = n - (t - g); /* position relative to node */ assert(sib2(t)->tag == TRule); - sib2(t)->key = t->key; + sib2(t)->key = t->key; /* fix rule's key */ } @@ -3062,7 +3096,7 @@ static void buildgrammar (lua_State *L, TTree *grammar, int frule, int n) { int rulesize; TTree *rn = gettree(L, ridx, &rulesize); nd->tag = TRule; - nd->key = 0; + nd->key = 0; /* will be fixed when rule is used */ nd->cap = i; /* rule number */ nd->u.ps = rulesize + 1; /* point to next rule */ memcpy(sib1(nd), rn, rulesize * sizeof(TTree)); /* copy rule */ @@ -3096,6 +3130,11 @@ static int checkloops (TTree *tree) { } +/* +** Give appropriate error message for 'verifyrule'. If a rule appears +** twice in 'passed', there is path from it back to itself without +** advancing the subject. +*/ static int verifyerror (lua_State *L, int *passed, int npassed) { int i, j; for (i = npassed - 1; i >= 0; i--) { /* search for a repetition */ @@ -3117,6 +3156,8 @@ static int verifyerror (lua_State *L, int *passed, int npassed) { ** is only relevant if the first is nullable. ** Parameter 'nb' works as an accumulator, to allow tail calls in ** choices. ('nb' true makes function returns true.) +** Parameter 'passed' is a list of already visited rules, 'npassed' +** counts the elements in 'passed'. ** Assume ktable at the top of the stack. */ static int verifyrule (lua_State *L, TTree *tree, int *passed, int npassed, @@ -3414,11 +3455,14 @@ int luaopen_lpeg (lua_State *L) { lua_pushnumber(L, MAXBACK); /* initialize maximum backtracking */ lua_setfield(L, LUA_REGISTRYINDEX, MAXSTACKIDX); luaL_setfuncs(L, metareg, 0); +#if defined(LuajitTeX) + luaL_register(L,"lpeg",pattreg); +#else luaL_newlib(L, pattreg); +#endif lua_pushvalue(L, -1); lua_setfield(L, -3, "__index"); return 1; } /* }====================================================== */ - diff --git a/Build/source/texk/web2c/luatexdir/luapeg/lpeg.h b/Build/source/texk/web2c/luatexdir/luapeg/lpeg.h index f722b887174..9bc79ff74c6 100644 --- a/Build/source/texk/web2c/luatexdir/luapeg/lpeg.h +++ b/Build/source/texk/web2c/luatexdir/luapeg/lpeg.h @@ -1,7 +1,7 @@ /* -** $Id: lptypes.h,v 1.14 2015/09/28 17:17:41 roberto Exp $ +** $Id: lptypes.h,v 1.16 2017/01/13 13:33:17 roberto Exp $ ** LPeg - PEG pattern matching for Lua -** Copyright 2007-2015, Lua.org & PUC-Rio (see 'lpeg.html' for license) +** Copyright 2007-2017, Lua.org & PUC-Rio (see 'lpeg.html' for license) ** written by Roberto Ierusalimschy */ @@ -13,7 +13,7 @@ #if !defined(lptypes_h) #define lptypes_h - +#define LPEG_DEBUG #if !defined(LPEG_DEBUG) #define NDEBUG #endif @@ -29,7 +29,7 @@ #include "lua.h" #include "lauxlib.h" -#define VERSION "1.0.0" +#define VERSION "1.0.1" #define PATTERN_T "lpeg-pattern" @@ -49,8 +49,9 @@ #define lua_rawlen lua_objlen #define luaL_setfuncs(L,f,n) luaL_register(L,NULL,f) +#if !defined(LuajitTeX) #define luaL_newlib(L,f) luaL_register(L,"lpeg",f) - +#endif #endif @@ -158,20 +159,33 @@ typedef struct Charset { #endif /* -** $Id: lpcap.h,v 1.2 2015/02/27 17:13:17 roberto Exp $ +** $Id: lpcap.h,v 1.3 2016/09/13 17:45:58 roberto Exp $ */ #if !defined(lpcap_h) #define lpcap_h -/*#include "lptypes.h"*/ +/* #include "lptypes.h" */ /* kinds of captures */ typedef enum CapKind { - Cclose, Cposition, Cconst, Cbackref, Carg, Csimple, Ctable, Cfunction, - Cquery, Cstring, Cnum, Csubst, Cfold, Cruntime, Cgroup + Cclose, /* not used in trees */ + Cposition, + Cconst, /* ktable[key] is Lua constant */ + Cbackref, /* ktable[key] is "name" of group to get capture */ + Carg, /* 'key' is arg's number */ + Csimple, /* next node is pattern */ + Ctable, /* next node is pattern */ + Cfunction, /* ktable[key] is function; next node is pattern */ + Cquery, /* ktable[key] is table; next node is pattern */ + Cstring, /* ktable[key] is string; next node is pattern */ + Cnum, /* numbered capture; 'key' is number of value to return */ + Csubst, /* substitution capture; next node is pattern */ + Cfold, /* ktable[key] is function; next node is pattern */ + Cruntime, /* not used in trees (is uses another type for tree) */ + Cgroup /* ktable[key] is group's "name" */ } CapKind; @@ -201,52 +215,57 @@ int finddyncap (Capture *cap, Capture *last); /* -** $Id: lptree.h,v 1.2 2013/03/24 13:51:12 roberto Exp $ +** $Id: lptree.h,v 1.3 2016/09/13 18:07:51 roberto Exp $ */ #if !defined(lptree_h) #define lptree_h -/*#include "lptypes.h" */ +/* #include "lptypes.h" */ /* ** types of trees */ typedef enum TTag { - TChar = 0, TSet, TAny, /* standard PEG elements */ - TTrue, TFalse, - TRep, - TSeq, TChoice, - TNot, TAnd, - TCall, - TOpenCall, - TRule, /* sib1 is rule's pattern, sib2 is 'next' rule */ - TGrammar, /* sib1 is initial (and first) rule */ - TBehind, /* match behind */ - TCapture, /* regular capture */ - TRunTime /* run-time capture */ + TChar = 0, /* 'n' = char */ + TSet, /* the set is stored in next CHARSETSIZE bytes */ + TAny, + TTrue, + TFalse, + TRep, /* 'sib1'* */ + TSeq, /* 'sib1' 'sib2' */ + TChoice, /* 'sib1' / 'sib2' */ + TNot, /* !'sib1' */ + TAnd, /* &'sib1' */ + TCall, /* ktable[key] is rule's key; 'sib2' is rule being called */ + TOpenCall, /* ktable[key] is rule's key */ + TRule, /* ktable[key] is rule's key (but key == 0 for unused rules); + 'sib1' is rule's pattern; + 'sib2' is next rule; 'cap' is rule's sequential number */ + TGrammar, /* 'sib1' is initial (and first) rule */ + TBehind, /* 'sib1' is pattern, 'n' is how much to go back */ + TCapture, /* captures: 'cap' is kind of capture (enum 'CapKind'); + ktable[key] is Lua value associated with capture; + 'sib1' is capture body */ + TRunTime /* run-time capture: 'key' is Lua function; + 'sib1' is capture body */ } TTag; -/* number of siblings for each tree */ -extern const byte numsiblings[]; - /* ** Tree trees -** The first sibling of a tree (if there is one) is immediately after -** the tree. A reference to a second sibling (ps) is its position -** relative to the position of the tree itself. A key in ktable -** uses the (unique) address of the original tree that created that -** entry. NULL means no data. +** The first child of a tree (if there is one) is immediately after +** the tree. A reference to a second child (ps) is its position +** relative to the position of the tree itself. */ typedef struct TTree { byte tag; byte cap; /* kind of capture (if it is a capture) */ unsigned short key; /* key in ktable for Lua data (0 if no key) */ union { - int ps; /* occasional second sibling */ + int ps; /* occasional second child */ int n; /* occasional counter */ } u; } TTree; @@ -263,10 +282,10 @@ typedef struct Pattern { } Pattern; -/* number of siblings for each tree */ +/* number of children for each tree */ extern const byte numsiblings[]; -/* access to siblings */ +/* access to children */ #define sib1(t) ((t) + 1) #define sib2(t) ((t) + (t)->u.ps) @@ -277,7 +296,6 @@ extern const byte numsiblings[]; #endif - /* ** $Id: lpvm.h,v 1.3 2014/02/21 13:06:41 roberto Exp $ */ @@ -285,7 +303,7 @@ extern const byte numsiblings[]; #if !defined(lpvm_h) #define lpvm_h -/*#include "lpcap.h"*/ +/* #include "lpcap.h" */ /* Virtual Machine's instructions */ @@ -336,10 +354,8 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, #endif - - /* -** $Id: lpcode.h,v 1.7 2015/06/12 18:24:45 roberto Exp $ +** $Id: lpcode.h,v 1.8 2016/09/15 17:46:13 roberto Exp $ */ #if !defined(lpcode_h) @@ -347,13 +363,13 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, /*#include "lua.h"*/ -/*#include "lptypes.h"*/ -/*#include "lptree.h"*/ -/*#include "lpvm.h"*/ +/* #include "lptypes.h" */ +/* #include "lptree.h" */ +/* #include "lpvm.h" */ int tocharset (TTree *tree, Charset *cs); int checkaux (TTree *tree, int pred); -int fixedlenx (TTree *tree, int count, int len); +int fixedlen (TTree *tree); int hascaptures (TTree *tree); int lp_gc (lua_State *L); Instruction *compile (lua_State *L, Pattern *p); @@ -375,13 +391,9 @@ int sizei (const Instruction *i); */ #define nullable(t) checkaux(t, PEnullable) -#define fixedlen(t) fixedlenx(t, 0, 0) - #endif - - /* ** $Id: lpprint.h,v 1.2 2015/06/12 18:18:08 roberto Exp $ */ diff --git a/Build/source/texk/web2c/luatexdir/luatex.c b/Build/source/texk/web2c/luatexdir/luatex.c index 9590dff1bdf..5dc5d64636a 100644 --- a/Build/source/texk/web2c/luatexdir/luatex.c +++ b/Build/source/texk/web2c/luatexdir/luatex.c @@ -12,6 +12,7 @@ /* We |#define DLLPROC| in order to build LuaTeX and LuajitTeX as DLL for W32TeX. */ + #if defined LuajitTeX #define DLLPROC dllluajittexmain #else @@ -21,20 +22,20 @@ #include "ptexlib.h" #include "luatex.h" #include "lua/luatex-api.h" -/* -#include "luatex_svnversion.h" -*/ - #define TeX -/* for tl17 update, change luatex_date_info but nothing else, - as context depends on the numeric version number. */ -int luatex_version = 100; /* \.{\\luatexversion} */ -int luatex_revision = '4'; /* \.{\\luatexrevision} */ -int luatex_date_info = 2017060901; /* the compile date is now hardwired :YEAR MONTH DAY HOUR*/ -const char *luatex_version_string = "1.0.4"; -const char *engine_name = my_name; /* the name of this engine */ +/* + The version number can be queried with \.{\\luatexversion} and the revision with + with \.{\\luatexrevision}. Traditionally the revision can be any character and + pdf\TeX\ occasionally used no digits. Here we still use a character but we will + stick to "0" upto "9" so users can expect a number represented as string. +*/ + +int luatex_version = 106; +int luatex_revision = '3'; +const char *luatex_version_string = "1.06.3"; +const char *engine_name = my_name; #include <kpathsea/c-ctype.h> #include <kpathsea/line.h> @@ -583,6 +584,7 @@ main (int ac, string *av) return EXIT_SUCCESS; } + /* This is supposed to ``open the terminal for input'', but what we really do is copy command line arguments into TeX's or Metafont's diff --git a/Build/source/texk/web2c/luatexdir/luatex_svnversion.h b/Build/source/texk/web2c/luatexdir/luatex_svnversion.h index bef33fd6cda..3527b8d4049 100644 --- a/Build/source/texk/web2c/luatexdir/luatex_svnversion.h +++ b/Build/source/texk/web2c/luatexdir/luatex_svnversion.h @@ -1 +1 @@ -#define luatex_svn_revision -1 +#define luatex_svn_revision 6501 diff --git a/Build/source/texk/web2c/luatexdir/luatexcallbackids.h b/Build/source/texk/web2c/luatexdir/luatexcallbackids.h index 927c4f1b2f1..32df36a4a1a 100644 --- a/Build/source/texk/web2c/luatexdir/luatexcallbackids.h +++ b/Build/source/texk/web2c/luatexdir/luatexcallbackids.h @@ -47,7 +47,7 @@ typedef enum { pre_output_filter_callback, buildpage_filter_callback, hpack_filter_callback, vpack_filter_callback, - char_exists_callback, + glyph_not_found_callback, hyphenate_callback, ligaturing_callback, kerning_callback, @@ -69,6 +69,7 @@ typedef enum { call_edit_callback, build_page_insert_callback, glyph_stream_provider_callback, + finish_synctex_callback, total_callbacks } callback_callback_types; diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdffont.w b/Build/source/texk/web2c/luatexdir/pdf/pdffont.w index b3f1605154c..278efa9d6fa 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdffont.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdffont.w @@ -41,7 +41,8 @@ scaled_whd output_one_char(PDF pdf, halfword p) int ex_glyph = ex_glyph(p)/1000; scaled_whd ci = get_charinfo_whd(f, c); /* the real width, height and depth of the character */ if (!(char_exists(f,c))) { - char_warning(f,c); + lua_glyph_not_found_callback(f,c); + /* char_warning(f,c); */ return ci; } ci.wd = ext_xn_over_d(ci.wd, 1000000 + ex_glyph(p), 1000000); diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfgen.h b/Build/source/texk/web2c/luatexdir/pdf/pdfgen.h index f2086663c70..01b0e74cd1e 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfgen.h +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfgen.h @@ -81,7 +81,7 @@ extern int ten_pow[10]; extern void pdf_flush(PDF); extern void pdf_room(PDF, int); -extern void fix_pdf_minorversion(PDF); +extern void fix_pdf_version(PDF); /* output a byte to PDF buffer without checking of overflow */ diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfgen.w b/Build/source/texk/web2c/luatexdir/pdf/pdfgen.w index 023f7fd65a3..26b7112ed09 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfgen.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfgen.w @@ -190,6 +190,7 @@ PDF init_pdf_struct(PDF pdf) memset(pdf->obj_tab, 0, sizeof(obj_entry)); pdf->minor_version = -1; + pdf->major_version = -1; pdf->decimal_digits = 4; pdf->gamma = 65536; pdf->image_gamma = 65536; @@ -262,35 +263,43 @@ void fix_o_mode(void) } } -@ This ensures that |pdfminorversion| is set only before any bytes have been -written to the generated \.{PDF} file. Here also all variables for \.{PDF} output -are initialized, the \.{PDF} file is opened by |ensure_pdf_open|, and the \.{PDF} -header is written. +@ This ensures that |pdfmajorversion| and |pdfminorversion| are set only before any +bytes have been written to the generated \.{PDF} file. Here also all variables for +\.{PDF} output are initialized, the \.{PDF} file is opened by |ensure_pdf_open|, and +the \.{PDF} header is written. @c -void fix_pdf_minorversion(PDF pdf) -{ - if (pdf->minor_version < 0) { /* unset */ +void fix_pdf_version(PDF pdf) +{ + if (pdf->major_version < 0) { /* unset */ + if (pdf_major_version == 0) { + normal_warning("pdf backend","unset major version, using 1 instead"); + pdf->major_version = 1; + } else if ((pdf_major_version < 0) || (pdf_major_version > 2)) { + formatted_warning("pdf backend","illegal major version %d, using 1 instead",pdf_major_version); + pdf->major_version = 1; + } else { + pdf->major_version = pdf_major_version; + } + } else if (pdf->major_version != pdf_major_version) { + normal_warning("pdf backend", "the major version cannot be changed after data is written to the PDF file"); + } + if (pdf->minor_version < 0) { /* unset */ if ((pdf_minor_version < 0) || (pdf_minor_version > 9)) { - const char *hlp[] = { "The pdfminorversion must be between 0 and 9.", "I changed this to 4.", NULL }; - char msg[256]; - (void) snprintf(msg, 255, "LuaTeX error (illegal pdfminorversion %d)", (int) pdf_minor_version); - tex_error(msg, hlp); + formatted_warning("pdf backend","illegal minor version %d, using 4 instead",pdf_minor_version); pdf->minor_version = 4; } else { pdf->minor_version = pdf_minor_version; } - } else { - /* Check that variables for \.{PDF} output are unchanged */ - if (pdf->minor_version != pdf_minor_version) - normal_error("pdf backend", "minorversion cannot be changed after data is written to the PDF file"); + } else if (pdf->minor_version != pdf_minor_version) { + normal_warning("pdf backend", "minorversion cannot be changed after data is written to the PDF file"); } } static void fix_pdf_draftmode(PDF pdf) { if (pdf->draftmode != draft_mode_par) - normal_error("pdf backend", "draftmode cannot be changed after data is written to the PDF file"); + normal_warning("pdf backend", "draftmode cannot be changed after data is written to the PDF file"); if (pdf->draftmode != 0) { pdf->compress_level = 0; /* re-fix it, might have been changed inbetween */ pdf->objcompresslevel = 0; @@ -1027,11 +1036,11 @@ static void ensure_output_file_open(PDF pdf, const char *ext) static void ensure_pdf_header_written(PDF pdf) { /* Initialize variables for \.{PDF} output */ - fix_pdf_minorversion(pdf); + fix_pdf_version(pdf); init_pdf_outputparameters(pdf); fix_pdf_draftmode(pdf); /* Write \.{PDF} header */ - pdf_printf(pdf, "%%PDF-1.%d\n", pdf->minor_version); + pdf_printf(pdf, "%%PDF-%d.%d\n", pdf->major_version, pdf->minor_version); /* The next blob will be removed 1.0. */ pdf_out(pdf, '%'); pdf_out(pdf, 'P' + 128); @@ -1732,6 +1741,7 @@ void pdf_begin_page(PDF pdf) pdf_dict_add_int(pdf, "FormType", 1); } xform_attributes = pdf_xform_attr; /* lookup once */ + form_margin = obj_xform_margin(pdf, pdf_cur_form); /* now stored in object */ if (xform_attributes != null) pdf_print_toks(pdf, xform_attributes); if (obj_xform_attr(pdf, pdf_cur_form) != null) { @@ -2062,19 +2072,21 @@ void pdf_end_page(PDF pdf) pdf_end_dict(pdf); } /* Generate ProcSet */ - pdf_add_name(pdf, "ProcSet"); - pdf_begin_array(pdf); - if ((procset & PROCSET_PDF) != 0) - pdf_add_name(pdf, "PDF"); - if ((procset & PROCSET_TEXT) != 0) - pdf_add_name(pdf, "Text"); - if ((procset & PROCSET_IMAGE_B) != 0) - pdf_add_name(pdf, "ImageB"); - if ((procset & PROCSET_IMAGE_C) != 0) - pdf_add_name(pdf, "ImageC"); - if ((procset & PROCSET_IMAGE_I) != 0) - pdf_add_name(pdf, "ImageI"); - pdf_end_array(pdf); + if (pdf->major_version == 1) { + pdf_add_name(pdf, "ProcSet"); + pdf_begin_array(pdf); + if ((procset & PROCSET_PDF) != 0) + pdf_add_name(pdf, "PDF"); + if ((procset & PROCSET_TEXT) != 0) + pdf_add_name(pdf, "Text"); + if ((procset & PROCSET_IMAGE_B) != 0) + pdf_add_name(pdf, "ImageB"); + if ((procset & PROCSET_IMAGE_C) != 0) + pdf_add_name(pdf, "ImageC"); + if ((procset & PROCSET_IMAGE_I) != 0) + pdf_add_name(pdf, "ImageI"); + pdf_end_array(pdf); + } pdf_end_dict(pdf); pdf_end_obj(pdf); } @@ -2182,11 +2194,7 @@ static int pdf_print_info(PDF pdf, int luatexversion, if ((pdf_suppress_optional_info & 128) == 0 && !producer_given) { pdf_add_name(pdf, "Producer"); pdf_puts(pdf, " (LuaTeX-"); - pdf_print_int(pdf, luatexversion / 100); - pdf_out(pdf, '.'); - pdf_print_int(pdf, luatexversion % 100); - pdf_out(pdf, '.'); - pdf_print(pdf, luatexrevision); + pdf_puts(pdf, luatex_version_string); pdf_out(pdf, ')'); } if ((pdf_suppress_optional_info & 16) == 0 && !creator_given) { diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfglyph.w b/Build/source/texk/web2c/luatexdir/pdf/pdfglyph.w index 06755a54bdf..0703beed22c 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfglyph.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfglyph.w @@ -197,8 +197,11 @@ void pdf_place_glyph(PDF pdf, internal_font_number f, int c, int ex) boolean move; pdfstructure *p = pdf->pstruct; scaledpos pos = pdf->posstruct->pos; - if (!char_exists(f, c)) - return; + /* already done: + if (!char_exists(f, c)) { + return; + } + */ if (font_writingmode(f) == vertical_writingmode) { if (p->wmode != WMODE_V) { p->wmode = WMODE_V; diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfliteral.w b/Build/source/texk/web2c/luatexdir/pdf/pdfliteral.w index 64a36dc67bf..35687bf7401 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfliteral.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfliteral.w @@ -103,13 +103,14 @@ void pdf_literal(PDF pdf, str_number s, int literal_mode, boolean warn) if (s >= STRING_OFFSET) { /* needed for |out_save| */ j = 0; - /* the next is obsolete, in fact, specials are obsolete in pdf mode */ + /* unfortunately we always go through this when we have vf specials (and also via temp strings) */ if (literal_mode == scan_special) { if (!(str_in_cstr(s, "PDF:", 0) || str_in_cstr(s, "pdf:", 0))) { if (warn && ((!(str_in_cstr(s, "SRC:", 0) || str_in_cstr(s, "src:", 0))) || (str_length(s) == 0))) tprint_nl("Non-PDF special ignored!"); return; } + /* j = j + (pool_pointer) strlen("PDF:"); if (str_in_cstr(s, "direct:", strlen("PDF:"))) { j = j + (pool_pointer) strlen("direct:"); @@ -120,6 +121,26 @@ void pdf_literal(PDF pdf, str_number s, int literal_mode, boolean warn) } else if (str_in_cstr(s, "raw:", strlen("PDF:"))) { j = j + (pool_pointer) strlen("raw:"); literal_mode = direct_raw; + } else if (str_in_cstr(s, "origin:", strlen("PDF:"))) { + j = j + (pool_pointer) strlen("origin:"); + literal_mode = set_origin; + } else { + literal_mode = set_origin; + } + */ + j = j + (pool_pointer) 4; /* strlen("PDF:") */ + if (str_in_cstr(s, "direct:", 4)) { /* strlen("PDF:") */ + j = j + (pool_pointer) 7; /* strlen("direct:") */ + literal_mode = direct_always; + } else if (str_in_cstr(s, "page:", 4)) { /* strlen("PDF:") */ + j = j + (pool_pointer) 5; /* strlen("page:") */ + literal_mode = direct_page; + } else if (str_in_cstr(s, "raw:", 4)) { /* strlen("PDF:") */ + j = j + (pool_pointer) 4; /* strlen("raw:") */ + literal_mode = direct_raw; + } else if (str_in_cstr(s, "origin:", 4)) { /* strlen("PDF:") */ + j = j + (pool_pointer) 7; /* strlen("origin:") */ + literal_mode = set_origin; } else { literal_mode = set_origin; } diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdftables.h b/Build/source/texk/web2c/luatexdir/pdf/pdftables.h index 9a14d65da45..cfaab5df046 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdftables.h +++ b/Build/source/texk/web2c/luatexdir/pdf/pdftables.h @@ -123,6 +123,7 @@ typedef enum { c_pdf_image_resolution, c_pdf_pk_resolution, c_pdf_unique_resname, + c_pdf_major_version, c_pdf_minor_version, c_pdf_pagebox, c_pdf_inclusion_errorlevel, @@ -170,6 +171,7 @@ extern int pdf_retval; # define pdf_image_resolution get_tex_extension_count_register(c_pdf_image_resolution) # define pdf_pk_resolution get_tex_extension_count_register(c_pdf_pk_resolution) # define pdf_unique_resname get_tex_extension_count_register(c_pdf_unique_resname) +# define pdf_major_version get_tex_extension_count_register(c_pdf_major_version) # define pdf_minor_version get_tex_extension_count_register(c_pdf_minor_version) # define pdf_pagebox get_tex_extension_count_register(c_pdf_pagebox) # define pdf_inclusion_errorlevel get_tex_extension_count_register(c_pdf_inclusion_errorlevel) @@ -200,6 +202,7 @@ extern int pdf_retval; # define pdf_pk_mode get_tex_extension_toks_register(t_pdf_pk_mode) # define pdf_trailer_id get_tex_extension_toks_register(t_pdf_trailer_id) +# define set_pdf_major_version(i) set_tex_extension_count_register(c_pdf_major_version,i) # define set_pdf_minor_version(i) set_tex_extension_count_register(c_pdf_minor_version,i) # define set_pdf_compress_level(i) set_tex_extension_count_register(c_pdf_compress_level,i) # define set_pdf_obj_compress_level(i) set_tex_extension_count_register(c_pdf_obj_compress_level,i) diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdftypes.h b/Build/source/texk/web2c/luatexdir/pdf/pdftypes.h index 34153600d97..c5f0393cc20 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdftypes.h +++ b/Build/source/texk/web2c/luatexdir/pdf/pdftypes.h @@ -293,6 +293,7 @@ typedef struct pdf_output_file_ { int gen_tounicode; int omit_cidset; int inclusion_copy_font; + int major_version; /* fixed major part of the PDF version */ int minor_version; /* fixed minor part of the PDF version */ int compress_level; /* level for zlib object stream compression */ int objcompresslevel; /* fixed level for activating PDF object streams */ diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfxform.h b/Build/source/texk/web2c/luatexdir/pdf/pdfxform.h index 64525d837ea..2d6441ff496 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfxform.h +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfxform.h @@ -22,7 +22,7 @@ #ifndef PDFXFORM_H # define PDFXFORM_H -# define pdfmem_xform_size 9 /* size of memory in |pdf->mem| which |obj_data_ptr| holds */ +# define pdfmem_xform_size 10 /* size of memory in |pdf->mem| which |obj_data_ptr| holds */ # define obj_xform_width(pdf,A) pdf->mem[obj_data_ptr(pdf,A) + 0] # define obj_xform_height(pdf,A) pdf->mem[obj_data_ptr(pdf,A) + 1] @@ -33,6 +33,7 @@ # define obj_xform_attr_str(pdf,A) pdf->mem[obj_data_ptr(pdf,A) + 6] # define obj_xform_resources_str(pdf,A) pdf->mem[obj_data_ptr(pdf,A) + 7] # define obj_xform_type(pdf,A) pdf->mem[obj_data_ptr(pdf,A) + 8] +# define obj_xform_margin(pdf,A) pdf->mem[obj_data_ptr(pdf,A) + 9] # define set_pdf_xform_objnum(A,B) pdf_xform_objnum(A)=B # define set_obj_xform_width(pdf,A,B) obj_xform_width(pdf,A)=B @@ -44,6 +45,7 @@ # define set_obj_xform_attr_str(pdf,A,B) obj_xform_attr_str(pdf,A)=B # define set_obj_xform_resources_str(pdf,A,B) obj_xform_resources_str(pdf,A)=B # define set_obj_xform_type(pdf,A,B) obj_xform_type(pdf,A)=B +# define set_obj_xform_margin(pdf,A,B) obj_xform_margin(pdf,A)=B extern int pdf_cur_form; /* the form being output */ diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfxform.w b/Build/source/texk/web2c/luatexdir/pdf/pdfxform.w index 4c83b024939..731dc229080 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfxform.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfxform.w @@ -89,6 +89,12 @@ void scan_pdfxform(PDF pdf) } else { set_obj_xform_resources(pdf, k, null); } + if (scan_keyword("margin")) { + scan_int(); + set_obj_xform_margin(pdf, k, cur_val); + } else { + set_obj_xform_margin(pdf, k, pdf_xform_margin); + } set_obj_xform_resources_str(pdf, k, null); scan_int(); p = box(cur_val); diff --git a/Build/source/texk/web2c/luatexdir/tex/commands.h b/Build/source/texk/web2c/luatexdir/tex/commands.h index fc61ffd46c8..8eabaa4e7cc 100644 --- a/Build/source/texk/web2c/luatexdir/tex/commands.h +++ b/Build/source/texk/web2c/luatexdir/tex/commands.h @@ -142,6 +142,7 @@ typedef enum { boundary_cmd, /* insert boundry node with value ( \.{\\*boundary} ) */ radical_cmd, /* square root and similar signs ( \.{\\radical} ) */ super_sub_script_cmd, /* explicit super- or subscript */ + no_super_sub_script_cmd, /* explicit no super- or subscript */ math_shift_cs_cmd, /* start- and endmath */ end_cs_name_cmd, /* end control sequence ( \.{\\endcsname} ) */ char_ghost_cmd, /* \.{\\leftghost}, \.{\\rightghost} character for kerning */ @@ -259,7 +260,6 @@ typedef enum { format_name_code, /* command code for \.{\\AlephVersion} */ luatex_banner_code, /* command code for \.{\\luatexbanner}: */ luatex_revision_code, /* command code for \.{\\luatexrevision} */ - luatex_date_code, /* command code for \.{\\luatexdate} */ etex_code, /* command code for \.{\\eTeXVersion} */ eTeX_revision_code, /* command code for \.{\\eTeXrevision} */ font_identifier_code, /* command code for \.{tex.fontidentifier} (virtual) */ diff --git a/Build/source/texk/web2c/luatexdir/tex/commands.w b/Build/source/texk/web2c/luatexdir/tex/commands.w index 84235914c64..0a34b750116 100644 --- a/Build/source/texk/web2c/luatexdir/tex/commands.w +++ b/Build/source/texk/web2c/luatexdir/tex/commands.w @@ -1,4 +1,4 @@ -% commands.w +f% commands.w % % Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org> % @@ -52,6 +52,7 @@ void initialize_commands(void) primitive_tex("thickmuskip", assign_mu_glue_cmd, glue_base + thick_mu_skip_code, glue_base + thin_mu_skip_code); primitive_luatex("mathsurroundskip", assign_glue_cmd, glue_base + math_skip_code, glue_base); primitive_luatex("mathsurroundmode", assign_int_cmd, int_base + math_skip_mode_code, int_base); + primitive_luatex("mathscriptboxmode", assign_int_cmd, int_base + math_script_box_mode_code, int_base); primitive_tex("output", assign_toks_cmd, output_routine_loc, local_base); primitive_tex("everypar", assign_toks_cmd, every_par_loc, local_base); primitive_tex("everymath", assign_toks_cmd, every_math_loc, local_base); @@ -74,9 +75,13 @@ void initialize_commands(void) primitive_tex("displaywidowpenalty", assign_int_cmd, int_base + display_widow_penalty_code, int_base); primitive_tex("brokenpenalty", assign_int_cmd, int_base + broken_penalty_code, int_base); primitive_tex("binoppenalty", assign_int_cmd, int_base + bin_op_penalty_code, int_base); + primitive_luatex("prerelpenalty", assign_int_cmd, int_base + pre_rel_penalty_code, int_base); + primitive_luatex("prebinoppenalty", assign_int_cmd, int_base + pre_bin_op_penalty_code, int_base); primitive_tex("relpenalty", assign_int_cmd, int_base + rel_penalty_code, int_base); primitive_tex("predisplaypenalty", assign_int_cmd, int_base + pre_display_penalty_code, int_base); primitive_tex("postdisplaypenalty", assign_int_cmd, int_base + post_display_penalty_code, int_base); + primitive_luatex("mathpenaltiesmode", assign_int_cmd, int_base + math_penalties_mode_code, int_base); + primitive_luatex("mathdelimitersmode", assign_int_cmd, int_base + math_delimiters_mode_code, int_base); primitive_tex("interlinepenalty", assign_int_cmd, int_base + inter_line_penalty_code, int_base); primitive_tex("doublehyphendemerits", assign_int_cmd, int_base + double_hyphen_demerits_code, int_base); primitive_tex("finalhyphendemerits", assign_int_cmd, int_base + final_hyphen_demerits_code, int_base); @@ -160,6 +165,8 @@ void initialize_commands(void) primitive_luatex("hyphenpenaltymode", assign_int_cmd, int_base + hyphen_penalty_mode_code, int_base); primitive_luatex("automatichyphenpenalty", assign_int_cmd, int_base + automatic_hyphen_penalty_code, int_base); primitive_luatex("explicithyphenpenalty", assign_int_cmd, int_base + explicit_hyphen_penalty_code, int_base); + primitive_luatex("automatichyphenmode", assign_int_cmd, int_base + automatic_hyphen_mode_code, int_base); + primitive_luatex("breakafterdirmode", assign_int_cmd, int_base + break_after_dir_mode_code, int_base); /* Many of \TeX's primitives need no |equiv|, since they are identifiable by their |eq_type| alone. These primitives are loaded into the hash table @@ -317,7 +324,6 @@ void initialize_commands(void) primitive_tex("fontname", convert_cmd, font_name_code, 0); primitive_luatex("fontid", convert_cmd, font_id_code, 0); primitive_luatex("luatexrevision", convert_cmd, luatex_revision_code, 0); - primitive_luatex("luatexdatestamp", convert_cmd, luatex_date_code, 0); primitive_luatex("luatexbanner", convert_cmd, luatex_banner_code, 0); primitive_luatex("leftmarginkern", convert_cmd, left_margin_kern_code, 0); primitive_luatex("rightmarginkern", convert_cmd, right_margin_kern_code, 0); @@ -445,8 +451,10 @@ void initialize_commands(void) primitive_tex("unhcopy", un_hbox_cmd, copy_code, 0); primitive_tex("unvbox", un_vbox_cmd, box_code, 0); primitive_tex("unvcopy", un_vbox_cmd, copy_code, 0); - primitive_tex("-", discretionary_cmd, explicit_disc, 0); + primitive_tex("-", discretionary_cmd, explicit_disc, 0); /* good old tex */ primitive_tex("discretionary", discretionary_cmd, discretionary_disc, 0); + primitive_luatex("explicitdiscretionary", discretionary_cmd, explicit_disc, 0); + primitive_luatex("automaticdiscretionary", discretionary_cmd, automatic_disc, 0); primitive_luatex("localleftbox", assign_local_box_cmd, 0, 0); primitive_luatex("localrightbox", assign_local_box_cmd, 1, 0); @@ -479,6 +487,8 @@ void initialize_commands(void) primitive_luatex("crampedscriptscriptstyle", math_style_cmd, cramped_script_script_style, 0); primitive_luatex("Usuperscript", super_sub_script_cmd, sup_mark_cmd, sup_mark_cmd); primitive_luatex("Usubscript", super_sub_script_cmd, sub_mark_cmd, sup_mark_cmd); + primitive_luatex("Unosuperscript", no_super_sub_script_cmd, sup_mark_cmd, sup_mark_cmd); + primitive_luatex("Unosubscript", no_super_sub_script_cmd, sub_mark_cmd, sup_mark_cmd); primitive_tex("above", above_cmd, above_code, 0); primitive_tex("over", above_cmd, over_code, 0); primitive_tex("atop", above_cmd, atop_code, 0); @@ -752,6 +762,7 @@ void initialize_etex_commands(void) primitive_etex("savinghyphcodes", assign_int_cmd, int_base + saving_hyph_codes_code, int_base); primitive_luatex("suppressfontnotfounderror", assign_int_cmd, int_base + suppress_fontnotfound_error_code, int_base); primitive_luatex("suppresslongerror", assign_int_cmd, int_base + suppress_long_error_code, int_base); + primitive_luatex("suppressprimitiveerror", assign_int_cmd, int_base + suppress_primitive_error_code, int_base); primitive_luatex("suppressmathparerror", assign_int_cmd, int_base + suppress_mathpar_error_code, int_base); primitive_luatex("suppressifcsnameerror", assign_int_cmd, int_base + suppress_ifcsname_error_code, int_base); primitive_luatex("suppressoutererror", assign_int_cmd, int_base + suppress_outer_error_code, int_base); diff --git a/Build/source/texk/web2c/luatexdir/tex/conditional.w b/Build/source/texk/web2c/luatexdir/tex/conditional.w index 268786add75..318775141a8 100644 --- a/Build/source/texk/web2c/luatexdir/tex/conditional.w +++ b/Build/source/texk/web2c/luatexdir/tex/conditional.w @@ -152,6 +152,7 @@ static boolean test_for_cs(void) halfword q; /*for traversing token lists in \.{\\ifx} tests */ halfword n = get_avail(); halfword p = n; /*head of the list of characters */ +is_in_csname += 1; while (1) { get_x_token(); if (cur_cs != 0) @@ -165,6 +166,7 @@ static boolean test_for_cs(void) get_x_token(); } while (cur_cmd != end_cs_name_cmd); flush_list(n); +is_in_csname -= 1; return b; } else { complain_missing_csname(); @@ -205,6 +207,7 @@ static boolean test_for_cs(void) b = (eq_type(cur_cs) != undefined_cs_cmd); flush_list(n); last_cs_name = cur_cs; +is_in_csname -= 1; return b; } diff --git a/Build/source/texk/web2c/luatexdir/tex/dumpdata.w b/Build/source/texk/web2c/luatexdir/tex/dumpdata.w index aa0d1655d6d..9d06f1c8ed4 100644 --- a/Build/source/texk/web2c/luatexdir/tex/dumpdata.w +++ b/Build/source/texk/web2c/luatexdir/tex/dumpdata.w @@ -23,7 +23,7 @@ /* we start with 907: the sum of the values of the bytes of "don knuth" */ -#define FORMAT_ID (907+28) +#define FORMAT_ID (907+37) #if ((FORMAT_ID>=0) && (FORMAT_ID<=256)) #error Wrong value for FORMAT_ID. #endif diff --git a/Build/source/texk/web2c/luatexdir/tex/equivalents.h b/Build/source/texk/web2c/luatexdir/tex/equivalents.h index d7ca036e25a..f478b4a41b2 100644 --- a/Build/source/texk/web2c/luatexdir/tex/equivalents.h +++ b/Build/source/texk/web2c/luatexdir/tex/equivalents.h @@ -291,8 +291,18 @@ the |number_regs| \.{\\dimen} registers. # define hyphen_penalty_mode_code 100 # define automatic_hyphen_penalty_code 101 # define explicit_hyphen_penalty_code 102 +# define automatic_hyphen_mode_code 103 +# define break_after_dir_mode_code 104 -# define math_option_code (explicit_hyphen_penalty_code+1) +# define pre_bin_op_penalty_code 105 +# define pre_rel_penalty_code 106 +# define math_penalties_mode_code 107 +# define math_delimiters_mode_code 108 +# define math_script_box_mode_code 109 + +# define suppress_primitive_error_code 110 + +# define math_option_code (suppress_primitive_error_code+1) # define mathoption_int_base_code (math_option_code+1) /* one reserve */ # define mathoption_int_last_code (mathoption_int_base_code+8) @@ -648,6 +658,11 @@ extern halfword last_cs_name; #define delimiter_factor_par int_par(delimiter_factor_code) #define bin_op_penalty_par int_par(bin_op_penalty_code) #define rel_penalty_par int_par(rel_penalty_code) +#define pre_bin_op_penalty_par int_par(pre_bin_op_penalty_code) +#define pre_rel_penalty_par int_par(pre_rel_penalty_code) +#define math_penalties_mode_par int_par(math_penalties_mode_code) +#define math_delimiters_mode_par int_par(math_delimiters_mode_code) +#define math_script_box_mode_par int_par(math_script_box_mode_code) #define null_delimiter_space_par dimen_par(null_delimiter_space_code) #define disable_lig_par int_par(disable_lig_code) #define disable_kern_par int_par(disable_kern_code) @@ -740,6 +755,7 @@ extern halfword last_cs_name; #define suppress_mathpar_error_par int_par(suppress_mathpar_error_code) #define suppress_fontnotfound_error_par int_par(suppress_fontnotfound_error_code) #define suppress_ifcsname_error_par int_par(suppress_ifcsname_error_code) +#define suppress_primitive_error_par int_par(suppress_primitive_error_code) #define error_context_lines_par int_par(error_context_lines_code) #define math_old_par mathoption_int_par(c_mathoption_old_code) @@ -773,6 +789,8 @@ extern halfword last_cs_name; #define hyphen_penalty_mode_par int_par(hyphen_penalty_mode_code) #define automatic_hyphen_penalty_par int_par(automatic_hyphen_penalty_code) #define explicit_hyphen_penalty_par int_par(explicit_hyphen_penalty_code) +#define automatic_hyphen_mode_par int_par(automatic_hyphen_mode_code) +#define break_after_dir_mode_par int_par(break_after_dir_mode_code) #define cur_lang_par int_par(cur_lang_code) #define cur_font_par equiv(cur_font_loc) diff --git a/Build/source/texk/web2c/luatexdir/tex/errors.h b/Build/source/texk/web2c/luatexdir/tex/errors.h index 3eae1c8a927..39fdf6b46e2 100644 --- a/Build/source/texk/web2c/luatexdir/tex/errors.h +++ b/Build/source/texk/web2c/luatexdir/tex/errors.h @@ -37,6 +37,8 @@ typedef enum { extern int interaction; /* current level of interaction */ extern int interactionoption; /* set from command line */ +extern int defaultexitcode; /* the exit code can be overloaded */ + extern void initialize_errors(void); extern char *last_error; diff --git a/Build/source/texk/web2c/luatexdir/tex/errors.w b/Build/source/texk/web2c/luatexdir/tex/errors.w index cec9a144f1c..93dbe141b91 100644 --- a/Build/source/texk/web2c/luatexdir/tex/errors.w +++ b/Build/source/texk/web2c/luatexdir/tex/errors.w @@ -215,6 +215,8 @@ boolean use_err_help; /* should the |err_help| list be shown? */ exits the program. It is used when there is no recovery from a particular error. @c +int defaultexitcode = 0; /* the exit code can be overloaded */ + __attribute__ ((noreturn)) void do_final_end(void) { @@ -224,7 +226,7 @@ void do_final_end(void) if ((history != spotless) && (history != warning_issued)) uexit(1); else - uexit(0); + uexit(defaultexitcode); } __attribute__ ((noreturn)) diff --git a/Build/source/texk/web2c/luatexdir/tex/expand.w b/Build/source/texk/web2c/luatexdir/tex/expand.w index 731345eb66e..c912863b2a1 100644 --- a/Build/source/texk/web2c/luatexdir/tex/expand.w +++ b/Build/source/texk/web2c/luatexdir/tex/expand.w @@ -209,7 +209,7 @@ void expand(void) iloc = p; istart = p; } - } else { + } else if (suppress_primitive_error_par == 0) { print_err("Missing primitive name"); help2 ("The control sequence marked <to be read again> does not", diff --git a/Build/source/texk/web2c/luatexdir/tex/linebreak.w b/Build/source/texk/web2c/luatexdir/tex/linebreak.w index 48705ad8cad..345a1a42456 100644 --- a/Build/source/texk/web2c/luatexdir/tex/linebreak.w +++ b/Build/source/texk/web2c/luatexdir/tex/linebreak.w @@ -755,6 +755,14 @@ Replacement texts and discretionary texts are supposed to contain only character nodes, kern nodes, and box or rule nodes. @c +#define bad_node_in_disc_error(p) { \ + if (type(p) == whatsit_node) { \ + formatted_error("linebreak","invalid node with type %s and subtype %i found in discretionary",node_data[type(p)].name,subtype(p)); \ + } else { \ + formatted_error("linebreak","invalid node with type %s found in discretionary",node_data[type(p)].name); \ + } \ +} + static void add_to_widths(halfword s, int line_break_dir, int adjust_spacing, scaled * widths) { while (s != null) { @@ -783,7 +791,8 @@ static void add_to_widths(halfword s, int line_break_dir, int adjust_spacing, sc case disc_node: /* TH temp */ break; default: - confusion("invalid node found in discretionary"); /* todo: report type */ + bad_node_in_disc_error(s); + break; } } s = vlink(s); @@ -825,7 +834,7 @@ static void sub_from_widths(halfword s, int line_break_dir, int adjust_spacing, case disc_node: /* TH temp */ break; default: - confusion("invalid node found in discretionary"); /* todo: report type */ + bad_node_in_disc_error(s); break; } } @@ -1857,20 +1866,16 @@ void ext_do_line_break(int paragraph_dir, to see whether or not a breakpoint is legal at |cur_p|, as explained above. - The |precedes_break| test also considers dir nodes and prohibits - a break after an opening dir_node (positive dir). In |\textdir TRT x| - the space after |TRT| is preserved and therefore the dir node - is bound to the |x|. Being more clever makes no sense: users - should code their input properly. + We only break after certain nodes (see texnodes.h), a font related + kern and a dir node when |\breakafterdirmode=1|. */ if (auto_breaking) { halfword prev_p = alink(cur_p); if (prev_p != temp_head && ( is_char_node(prev_p) || precedes_break(prev_p) - || ( (type(prev_p) == kern_node) && ( - subtype(prev_p) == font_kern || subtype(prev_p) == accent_kern) - ) + || precedes_kern(prev_p) + || precedes_dir(prev_p) )) { ext_try_break(0, unhyphenated_node, line_break_dir, adjust_spacing, par_shape_ptr, adj_demerits, diff --git a/Build/source/texk/web2c/luatexdir/tex/mainbody.h b/Build/source/texk/web2c/luatexdir/tex/mainbody.h index 158893631d7..4a5cb93a164 100644 --- a/Build/source/texk/web2c/luatexdir/tex/mainbody.h +++ b/Build/source/texk/web2c/luatexdir/tex/mainbody.h @@ -23,7 +23,6 @@ extern int luatex_version; extern int luatex_revision; -extern int luatex_date_info; extern const char *luatex_version_string; extern const char *engine_name; @@ -218,7 +217,6 @@ is conditionally compiled in the C code. extern int get_luatexversion(void); extern str_number get_luatexrevision(void); -extern int get_luatex_date_info(void); extern int ready_already; diff --git a/Build/source/texk/web2c/luatexdir/tex/mainbody.w b/Build/source/texk/web2c/luatexdir/tex/mainbody.w index faa6e1992da..4d38b9d4a47 100644 --- a/Build/source/texk/web2c/luatexdir/tex/mainbody.w +++ b/Build/source/texk/web2c/luatexdir/tex/mainbody.w @@ -230,12 +230,6 @@ str_number get_luatexrevision(void) return luatex_revision; } -int get_luatex_date_info(void) -{ - return luatex_date_info; /* todo, silly value */ -} - - @ This is it: the part of \TeX\ that executes all those procedures we have written. @@ -524,7 +518,18 @@ void close_files_and_terminate(void) /* rubish, these pdf arguments, passed, needs to be fixed, e.g. with a dummy in dvi */ wrapup_backend(); /* Close {\sl Sync\TeX} file and write status */ - synctexterminate(log_opened_global); /* Let the {\sl Sync\TeX} controller close its files. */ + synctexterminate(log_opened_global); + /* + The following is needed because synctex removes files and we want to keep them which + means renaming a temp file .. we can't bypass the terminate because it might do mem + cleanup. + */ + if (synctex_get_mode() > 0) { + callback_id = callback_defined(finish_synctex_callback); + if (callback_id > 0) { + run_callback(callback_id, "->"); + } + } free_text_codes(); free_math_codes(); if (log_opened_global) { diff --git a/Build/source/texk/web2c/luatexdir/tex/maincontrol.w b/Build/source/texk/web2c/luatexdir/tex/maincontrol.w index 0baba872e8e..7b4cf9065ca 100644 --- a/Build/source/texk/web2c/luatexdir/tex/maincontrol.w +++ b/Build/source/texk/web2c/luatexdir/tex/maincontrol.w @@ -705,6 +705,7 @@ static void init_main_control (void) { non_math(sup_mark_cmd, insert_dollar_sign); non_math(sub_mark_cmd, insert_dollar_sign); non_math(super_sub_script_cmd, insert_dollar_sign); + non_math(no_super_sub_script_cmd, insert_dollar_sign); non_math(math_comp_cmd, insert_dollar_sign); non_math(delim_num_cmd, insert_dollar_sign); non_math(left_right_cmd, insert_dollar_sign); @@ -825,6 +826,7 @@ static void init_main_control (void) { jump_table[mmode + sub_mark_cmd] = sub_sup; jump_table[mmode + sup_mark_cmd] = sub_sup; jump_table[mmode + super_sub_script_cmd] = sub_sup; + jump_table[mmode + no_super_sub_script_cmd] = no_sub_sup; jump_table[mmode + left_right_cmd] = math_left_right; jump_table[mmode + math_shift_cmd] = run_math_shift; jump_table[mmode + math_shift_cs_cmd] = run_math_shift; @@ -1759,18 +1761,42 @@ void append_discretionary(void) if (cur_chr == explicit_disc) { /* \- */ c = get_pre_hyphen_char(cur_lang_par); - if (c != 0) { + if (c > 0) { vlink(pre_break(tail)) = new_char(equiv(cur_font_loc), c); alink(vlink(pre_break(tail))) = pre_break(tail); tlink(pre_break(tail)) = vlink(pre_break(tail)); } c = get_post_hyphen_char(cur_lang_par); - if (c != 0) { + if (c > 0) { vlink(post_break(tail)) = new_char(equiv(cur_font_loc), c); alink(vlink(post_break(tail))) = post_break(tail); tlink(post_break(tail)) = vlink(post_break(tail)); } set_explicit_disc_penalty(tail); + } else if (cur_chr == automatic_disc) { + /* - as done in hyphenator */ + c = get_pre_exhyphen_char(cur_lang_par); + if (c <= 0) { + c = ex_hyphen_char_par; + } + if (c > 0) { + vlink(pre_break(tail)) = new_char(equiv(cur_font_loc), c); + alink(vlink(pre_break(tail))) = pre_break(tail); + tlink(pre_break(tail)) = vlink(pre_break(tail)); + } + c = get_post_exhyphen_char(cur_lang_par); + if (c > 0) { + vlink(post_break(tail)) = new_char(equiv(cur_font_loc), c); + alink(vlink(post_break(tail))) = post_break(tail); + tlink(post_break(tail)) = vlink(post_break(tail)); + } + c = ex_hyphen_char_par; + if (c > 0) { + vlink(no_break(tail)) = new_char(equiv(cur_font_loc), c); + alink(vlink(no_break(tail))) = no_break(tail); + tlink(no_break(tail)) = vlink(no_break(tail)); + } + set_automatic_disc_penalty(tail); } else { /* \discretionary */ if (scan_keyword("penalty")) { @@ -3601,6 +3627,9 @@ void initialize(void) hang_after_par = 1; max_dead_cycles_par = 25; math_pre_display_gap_factor_par = 2000; + pre_bin_op_penalty_par = inf_penalty; + math_script_box_mode_par = 1; + pre_rel_penalty_par = inf_penalty; escape_char_par = '\\'; end_line_char_par = carriage_return; set_del_code('.', 0, 0, 0, 0, level_one); /* this null delimiter is used in error recovery */ @@ -3632,7 +3661,9 @@ void initialize(void) set_eq_level(end_write, level_one); set_eq_type(end_write, outer_call_cmd); set_equiv(end_write, null); - + /* bah */ + set_pdf_major_version(1); + set_pdf_minor_version(0); } synctexoffset = int_base + synctex_code; diff --git a/Build/source/texk/web2c/luatexdir/tex/mlist.w b/Build/source/texk/web2c/luatexdir/tex/mlist.w index 7a002c2843d..291ce8c4868 100644 --- a/Build/source/texk/web2c/luatexdir/tex/mlist.w +++ b/Build/source/texk/web2c/luatexdir/tex/mlist.w @@ -1348,29 +1348,30 @@ static void endless_loop_error(internal_font_number g, int y) tex_error(s, hlp); } -static pointer do_delimiter(pointer q, pointer d, int s, scaled v, boolean flat, int cur_style, boolean shift, boolean *stack, scaled *delta) +static pointer do_delimiter(pointer q, pointer d, int s, scaled v, boolean flat, int cur_style, boolean shift, boolean *stack, scaled *delta, int *same) { - pointer b; /* the box that will be constructed */ - internal_font_number f, g; /* best-so-far and tentative font codes */ - int c, i, x, y; /* best-so-far and tentative character codes */ - scaled u; /* height-plus-depth of a tentative character */ - scaled w; /* largest height-plus-depth so far */ - int z; /* runs through font family members */ - boolean large_attempt; /* are we trying the ``large'' variant? */ - pointer att; /* to save the current attribute list */ - boolean do_parts; + pointer b; /* the box that will be constructed */ + internal_font_number f, g; /* best-so-far and tentative font codes */ + int c, i, x, y; /* best-so-far and tentative character codes */ + scaled u; /* height-plus-depth of a tentative character */ + scaled w = 0; /* largest height-plus-depth so far */ + int z; /* runs through font family members */ + boolean large_attempt = false; /* are we trying the ``large'' variant? */ + pointer att = null; /* to save the current attribute list */ + int emas = 0 ; + boolean do_parts = false; extinfo *ext; - att = null; f = null_font; c = 0; - w = 0; - do_parts = false; - large_attempt = false; if (d == null) goto FOUND; z = small_fam(d); x = small_char(d); i = 0; + if (same != NULL) { + emas = *same ; + same = 0; + } while (true) { /* The search process is complicated slightly by the facts that some of the @@ -1448,6 +1449,9 @@ static pointer do_delimiter(pointer q, pointer d, int s, scaled v, boolean flat, if (stack != NULL) *stack = true ; } else { + if (same != NULL && x == c) { + *same = emas; + } b = char_box(f, c, att); if (!do_new_math(f)) { /* italic gets added to width */ @@ -1475,10 +1479,12 @@ static pointer do_delimiter(pointer q, pointer d, int s, scaled v, boolean flat, *stack = false ; } if (!flat) { - /* vertical variant */ - shift_amount(b) = half(height(b) - depth(b)); - if (shift) { - shift_amount(b) -= math_axis_size(s); + if (emas == 0 || ! delimitermodenoshift) { + /* vertical variant */ + shift_amount(b) = half(height(b) - depth(b)); + if (shift) { + shift_amount(b) -= math_axis_size(s); + } } } delete_attribute_ref(att); @@ -1605,7 +1611,7 @@ static void math_kern(pointer p, scaled m) f = f + unity; } width(p) = mu_mult(width(p)); - subtype(p) = italic_kern; + subtype(p) = italic_kern; /* this is weird, it's not a italic but explicit_kern */ } } @@ -1666,21 +1672,21 @@ static pointer clean_box(pointer p, int s, int cur_style) pointer r; /* temporary pointer */ pointer mlist = null; /* beginning of mlist to be translated */ switch (type(p)) { - case math_char_node: - mlist = new_noad(); - r = math_clone(p); - nucleus(mlist) = r; - break; - case sub_box_node: - q = math_list(p); - goto FOUND; - break; - case sub_mlist_node: - mlist = math_list(p); - break; - default: - q = new_null_box(); - goto FOUND; + case math_char_node: + mlist = new_noad(); + r = math_clone(p); + nucleus(mlist) = r; + break; + case sub_box_node: + q = math_list(p); + goto FOUND; + break; + case sub_mlist_node: + mlist = math_list(p); + break; + default: + q = new_null_box(); + goto FOUND; } mlist_to_hlist(mlist, false, s); q = vlink(temp_head); /* recursive call */ @@ -1857,7 +1863,7 @@ static void make_hextension(pointer q, int cur_style) pointer e, p; halfword w; boolean stack = false; - e = do_delimiter(q, left_delimiter(q), cur_size, radicalwidth(q), true, cur_style, true, &stack, NULL); + e = do_delimiter(q, left_delimiter(q), cur_size, radicalwidth(q), true, cur_style, true, &stack, NULL, NULL); w = width(e); if (!stack&& (radicalwidth(q) != 0) && (radicalwidth(q) != width(e))) { if (radicalmiddle(q)) { @@ -1887,7 +1893,7 @@ static void make_radical(pointer q, int cur_style) if (theta == undefined_math_parameter) { /* a real radical */ theta = fraction_rule(cur_style); - y = do_delimiter(q, left_delimiter(q), cur_size, height(x) + depth(x) + clr + theta, false, cur_style, true, NULL, NULL); + y = do_delimiter(q, left_delimiter(q), cur_size, height(x) + depth(x) + clr + theta, false, cur_style, true, NULL, NULL, NULL); /* If |y| is a composite then set |theta| to the height of its top character, else set it to the height of |y|. @@ -1907,7 +1913,7 @@ static void make_radical(pointer q, int cur_style) } } else { /* not really a radical but we use its node, historical sharing (like in mathml) */ - y = do_delimiter(q, left_delimiter(q), cur_size, height(x) + depth(x) + clr + theta, false, cur_style, true, NULL, NULL); + y = do_delimiter(q, left_delimiter(q), cur_size, height(x) + depth(x) + clr + theta, false, cur_style, true, NULL, NULL, NULL); } left_delimiter(q) = null; delta = (depth(y) + height(y) - theta) - (height(x) + depth(x) + clr); @@ -2034,7 +2040,7 @@ static void make_over_delimiter(pointer q, int cur_style) boolean stack; x = clean_box(nucleus(q), sub_style(cur_style), cur_style); check_widths(q,x); - y = do_delimiter(q, left_delimiter(q), cur_size, wd, true, cur_style, true, &stack, NULL); + y = do_delimiter(q, left_delimiter(q), cur_size, wd, true, cur_style, true, &stack, NULL, NULL); left_delimiter(q) = null; check_radical(q,stack,y,x); fixup_widths(q, x, y); @@ -2061,7 +2067,7 @@ static void make_under_delimiter(pointer q, int cur_style) boolean stack; y = clean_box(nucleus(q), sup_style(cur_style), cur_style); check_widths(q,y); - x = do_delimiter(q, left_delimiter(q), cur_size, wd, true, cur_style, true, &stack, NULL); + x = do_delimiter(q, left_delimiter(q), cur_size, wd, true, cur_style, true, &stack, NULL, NULL); left_delimiter(q) = null; check_radical(q,stack,x,y); fixup_widths(q, x, y); @@ -2088,7 +2094,7 @@ static void make_delimiter_over(pointer q, int cur_style) boolean stack; y = clean_box(nucleus(q), cur_style, cur_style); check_widths(q,y); - x = do_delimiter(q, left_delimiter(q), cur_size + (cur_size == script_script_size ? 0 : 1), wd, true, cur_style, true, &stack, NULL); + x = do_delimiter(q, left_delimiter(q), cur_size + (cur_size == script_script_size ? 0 : 1), wd, true, cur_style, true, &stack, NULL, NULL); left_delimiter(q) = null; check_radical(q,stack,x,y); fixup_widths(q, x, y); @@ -2115,7 +2121,7 @@ static void make_delimiter_under(pointer q, int cur_style) boolean stack; x = clean_box(nucleus(q), cur_style, cur_style); check_widths(q,x); - y = do_delimiter(q, left_delimiter(q), cur_size + (cur_size == script_script_size ? 0 : 1), wd, true, cur_style, true, &stack, NULL); + y = do_delimiter(q, left_delimiter(q), cur_size + (cur_size == script_script_size ? 0 : 1), wd, true, cur_style, true, &stack, NULL, NULL); left_delimiter(q) = null; check_radical(q,stack,y,x); fixup_widths(q, x, y); @@ -2182,11 +2188,24 @@ static boolean compute_accent_skew(pointer q, int flags, scaled *s) * use the positioning of the nucleus of that noad, recursing until * the inner most |accent_noad|. This way multiple stacked accents are * aligned to the inner most one. + + the vlink test was added in version 1.06, so that we only consider a lone + noad: + + $ + \Umathaccent bottom 0 0 "023DF { \Umathaccent fixed 0 0 "00302 { m } r } \quad + \Umathaccent bottom 0 0 "023DF { l \Umathaccent fixed 0 0 "00302 { m } r } \quad + \Umathaccent bottom 0 0 "023DF { l \Umathaccent fixed 0 0 "00302 { m } } \quad + \Umathaccent bottom 0 0 "023DF { \Umathaccent fixed 0 0 "00302 { m } } \quad + \Umathaccent bottom 0 0 "023DF { l r } + $ + */ p = math_list(nucleus(q)); - if (type(p) == accent_noad) { + if (type(p) == accent_noad && vlink(p) == null) { s_is_absolute = compute_accent_skew(p, flags, s); } + } else { } return s_is_absolute; @@ -2423,7 +2442,7 @@ static void make_fraction(pointer q, int cur_style) if (middle_delimiter(q) != null) { delta = 0; - m = do_delimiter(q, middle_delimiter(q), cur_size, delta, false, cur_style, true, NULL, NULL); + m = do_delimiter(q, middle_delimiter(q), cur_size, delta, false, cur_style, true, NULL, NULL, NULL); middle_delimiter(q) = null; } else { m = null ; @@ -2592,9 +2611,9 @@ static void make_fraction(pointer q, int cur_style) } else { delta = fraction_del_size_old(cur_style); } - l = do_delimiter(q, left_delimiter(q), cur_size, delta, false, cur_style, true, NULL, NULL); + l = do_delimiter(q, left_delimiter(q), cur_size, delta, false, cur_style, true, NULL, NULL, NULL); left_delimiter(q) = null; - r = do_delimiter(q, right_delimiter(q), cur_size, delta, false, cur_style, true, NULL, NULL); + r = do_delimiter(q, right_delimiter(q), cur_size, delta, false, cur_style, true, NULL, NULL, NULL); right_delimiter(q) = null; couple_nodes(l,v); couple_nodes(v,r); @@ -2619,7 +2638,7 @@ the limits have been set above and below the operator. In that case, @c static void make_scripts(pointer q, pointer p, scaled it, int cur_style, scaled supshift, scaled subshift); -static pointer check_nucleus_complexity(halfword q, scaled * delta, int cur_style); +static pointer check_nucleus_complexity(halfword q, scaled * delta, int cur_style, int *same); static scaled make_op(pointer q, int cur_style) { @@ -2644,7 +2663,7 @@ static scaled make_op(pointer q, int cur_style) reset_attributes(y, node_attr(q)); small_fam(y) = math_fam(nucleus(q)); small_char(y) = math_character(nucleus(q)); - x = do_delimiter(q, y, text_size, ok_size, false, cur_style, true, NULL, &delta); + x = do_delimiter(q, y, text_size, ok_size, false, cur_style, true, NULL, &delta, NULL); if (delta != 0) { if (do_new_math(cur_f)) { /* we never added italic correction */ @@ -2705,7 +2724,7 @@ static scaled make_op(pointer q, int cur_style) delta = half(delta) ; } */ - p = check_nucleus_complexity(q, &dummy, cur_style); + p = check_nucleus_complexity(q, &dummy, cur_style, NULL); if ((subscr(q) == null) && (supscr(q) == null)) { assign_new_hlist(q, p); } else { @@ -2752,7 +2771,7 @@ static scaled make_op(pointer q, int cur_style) delta = 0; } else { /* similar code then the caller (before CHECK_DIMENSIONS) */ - p = check_nucleus_complexity(q, &delta, cur_style); + p = check_nucleus_complexity(q, &delta, cur_style, NULL); if ((subscr(q) == null) && (supscr(q) == null)) { assign_new_hlist(q, p); } else { @@ -2923,6 +2942,7 @@ static void make_ord(pointer q) /* add italic correction */ if (do_new_math(cur_f) && (char_italic(cur_f,math_character(nucleus(q))) != 0)) { p = new_kern(char_italic(cur_f,math_character(nucleus(q)))); + subtype(p) = italic_kern; reset_attributes(p, node_attr(q)); couple_nodes(p,vlink(q)); couple_nodes(q,p); @@ -3082,7 +3102,8 @@ static scaled find_math_kern(internal_font_number l_f, int l_c, { scaled corr_height_top = 0, corr_height_bot = 0; scaled krn_l = 0, krn_r = 0, krn = 0; - if ((!do_new_math(l_f)) || (!do_new_math(r_f)) || (!char_exists(l_f, l_c)) || (!char_exists(r_f, r_c))) +// if ((!do_new_math(l_f)) || (!do_new_math(r_f)) || (!char_exists(l_f, l_c)) || (!char_exists(r_f, r_c))) + if ((!(do_new_math(l_f) || do_new_math(r_f))) || (!char_exists(l_f, l_c)) || (!char_exists(r_f, r_c))) return MATH_KERN_NOT_FOUND; if (cmd == sup_mark_cmd) { @@ -3203,39 +3224,91 @@ kerns assuming that is italic correction. The heuristics are unreliable for the new fonts so eventualy there will be an option to ignore such corrections. @ @c -#define analyze_script(init,su_n,su_f,su_c) do { \ - su_n = init; \ - if (su_n != null) { \ - if (type(su_n) == sub_mlist_node && math_list(su_n)) { \ - su_n = math_list(su_n); \ - if (su_n != null) { \ - while (su_n) { \ - if ((type(su_n) == kern_node) || (type(su_n) == glue_node)) {\ - su_n = vlink(su_n); \ - } else if (type(su_n) == simple_noad) { \ - su_n = nucleus(su_n); \ - if (type(su_n) != math_char_node) { \ - su_n = null; \ - } \ - break; \ - } else { \ - su_n = null; \ - break; \ - } \ - } \ - } \ - } \ - if ((su_n != null) && (type(su_n) == math_char_node)) { \ - fetch(su_n); \ - if (char_exists(cur_f, cur_c)) { \ - su_f = cur_f; \ - su_c = cur_c; \ - } else { \ - su_n = null; \ - } \ - } \ - } \ - } while (0) +#define analyze_script(init,su_n,su_f,su_c) do { \ + su_n = init; \ + if (su_n != null) { \ + if (math_script_box_mode_par > 0 && type(su_n) == sub_mlist_node) { \ + su_n = math_list(su_n); \ + while (su_n != null) { \ + if ((type(su_n) == kern_node) || (type(su_n) == glue_node)) { \ + su_n = vlink(su_n); \ + } else if (type(su_n) == simple_noad) { \ + su_n = nucleus(su_n); \ + if (type(su_n) == math_char_node) { \ + fetch(su_n); \ + if (char_exists(cur_f, cur_c)) { \ + su_f = cur_f; \ + su_c = cur_c; \ + } else { \ + su_n = null; \ + } \ + } else { \ + su_n = null; \ + } \ + break; \ + } else { \ + su_n = null; \ + break; \ + } \ + } \ + } else if (type(su_n) == sub_box_node) { \ + su_n = math_list(su_n); \ + if (su_n != null) { \ + if (type(su_n) == hlist_node) { \ + su_n = list_ptr(su_n); \ + } \ + if (su_n != null) { \ + if (math_script_box_mode_par == 2) { \ + while (su_n != null) { \ + if ((type(su_n) == kern_node) || (type(su_n) == glue_node)) { \ + su_n = vlink(su_n); \ + } else if (type(su_n) == glyph_node) { \ + if (char_exists(font(su_n), character(su_n))) { \ + su_f = font(su_n); \ + su_c = character(su_n); \ + } else { \ + su_n = null; \ + } \ + break ; \ + } else { \ + su_n = null; \ + break; \ + } \ + } \ + } else if (math_script_box_mode_par == 3) { \ + int boundary = -1; \ + while (su_n != null) { \ + if ((type(su_n) == boundary_node) && (subtype(su_n) == user_boundary)) { \ + boundary = boundary_value(su_n); \ + su_n = vlink(su_n); \ + } else if ((type(su_n) == kern_node) || (type(su_n) == glue_node)) { \ + su_n = vlink(su_n); \ + } else if ((boundary > -1) && (type(su_n) == glyph_node)) { \ + if (char_exists(font(su_n), character(su_n))) { \ + su_f = font(su_n); \ + su_c = character(su_n); \ + } else { \ + su_n = null; \ + } \ + break ; \ + } else { \ + su_n = null; \ + break; \ + } \ + } \ + } \ + } \ + } else { \ + su_n = null; \ + } \ + } else { \ + su_n = null; \ + } \ + } \ + } while (0) \ + +#define x_su_style(n,cur_style,su_style) \ + (noadoptionnosubscript(n) ? cur_style : su_style(cur_style)) static void make_scripts(pointer q, pointer p, scaled it, int cur_style, scaled supshift, scaled subshift) { @@ -3265,6 +3338,7 @@ static void make_scripts(pointer q, pointer p, scaled it, int cur_style, scaled if ((subscr(q) == null) && (delta1 != 0)) { /* todo: selective */ x = new_kern(delta1); /* italic correction */ + subtype(x) = italic_kern; reset_attributes(x, node_attr(nucleus(q))); couple_nodes(p,x); delta1 = 0; @@ -3296,7 +3370,8 @@ static void make_scripts(pointer q, pointer p, scaled it, int cur_style, scaled when there is a subscript without a superscript, the top of the subscript should not exceed the baseline plus four-fifths of the x-height. */ - x = clean_box(subscr(q), sub_style(cur_style), cur_style); + /* x = clean_box(subscr(q), sub_style(cur_style), cur_style); */ + x = clean_box(subscr(q), (noadoptionnosubscript(q) ? cur_style : sub_style(cur_style)), cur_style); width(x) = width(x) + space_after_script(cur_style); switch (math_scripts_mode_par) { case 1: @@ -3346,7 +3421,8 @@ static void make_scripts(pointer q, pointer p, scaled it, int cur_style, scaled the bottom of a superscript should never descend below the baseline plus one-fourth of the x-height. */ - x = clean_box(supscr(q), sup_style(cur_style), cur_style); + /* x = clean_box(supscr(q), sup_style(cur_style), cur_style); */ + x = clean_box(supscr(q), (noadoptionnosupscript(q) ? cur_style : sup_style(cur_style)), cur_style); width(x) = width(x) + space_after_script(cur_style); switch (math_scripts_mode_par) { case 1: @@ -3401,7 +3477,8 @@ static void make_scripts(pointer q, pointer p, scaled it, int cur_style, scaled both subscript and superscript move up so that the bottom of the superscript is at least as high as the baseline plus four-fifths of the x-height */ - y = clean_box(subscr(q), sub_style(cur_style), cur_style); + /* y = clean_box(subscr(q) sub_style(cur_style), cur_style); */ + y = clean_box(subscr(q), (noadoptionnosubscript(q) ? cur_style : sub_style(cur_style)), cur_style); width(y) = width(y) + space_after_script(cur_style); switch (math_scripts_mode_par) { case 1: @@ -3508,23 +3585,17 @@ static small_number make_left_right(pointer q, int style, scaled max_d, scaled m { scaled delta; pointer tmp, lst; - scaled hd_asked = 0; scaled ic = 0; boolean stack = false; boolean axis = false; - /* - scaled hd_done = 0; - boolean fitting = true; - boolean fence = false; - int chr = 0; - int cls = 0; - */ + int same = subtype(q); + setup_cur_size(style); if ((delimiterheight(q)!=0) || (delimiterdepth(q)!=0)) { - hd_asked = delimiterheight(q) + delimiterdepth(q); - tmp = do_delimiter(q, delimiter(q), cur_size, hd_asked, false, style, false, &stack, &ic); + delta = delimiterheight(q) + delimiterdepth(q); + tmp = do_delimiter(q, delimiter(q), cur_size, delta, false, style, false, &stack, &ic, &same); delimiteritalic(q) = ic; /* beware, a stacked delimiter has a shift but no corrected height/depth (yet) */ @@ -3533,19 +3604,6 @@ static small_number make_left_right(pointer q, int style, scaled max_d, scaled m shift_amount(tmp) = delimiterdepth(q); } - /* - hd_done = height(tmp) + depth(tmp); - fitting = stack || ((hd_done-hd_asked) == 0); - - if (type(delimiter(q)) == delim_node && (small_char(delimiter(q)) != 0)) { - chr = small_char(delimiter(q)); - cls = get_math_code(chr).class_value ; - fence = (cls == 4) || (cls == 5) ; - } - - printf("delimiter stack %i fence %i fitting %i\n",stack,fence,fitting); - */ - if (delimiterexact(q)) { delimiterheight(q) = height(tmp) - shift_amount(tmp); delimiterdepth(q) = depth(tmp) + shift_amount(tmp); @@ -3566,19 +3624,18 @@ static small_number make_left_right(pointer q, int style, scaled max_d, scaled m } else { axis = ! delimiternoaxis(q); delta = get_delimiter_height(max_d,max_h,axis); - tmp = do_delimiter(q, delimiter(q), cur_size, delta, false, style, axis, &stack, &ic); + tmp = do_delimiter(q, delimiter(q), cur_size, delta, false, style, axis, &stack, &ic, &same); delimiteritalic(q) = ic; } delimiter(q) = null; assign_new_hlist(q, tmp); + delimitersamesize(q) = same; /* new */ if (delimiterclass(q) >= ord_noad_type) { if (delimiterclass(q) <= inner_noad_type) { return delimiterclass(q); } else { return ord_noad_type; } - } else if (subtype(q) == no_noad_side) { - return open_noad_type; } else if (subtype(q) == left_noad_side) { return open_noad_type; } else { @@ -3797,58 +3854,67 @@ static pointer math_spacing_glue(int l_type, int r_type, int mstyle, scaled mmu) } @ @c -static pointer check_nucleus_complexity(halfword q, scaled * delta, int cur_style) +static pointer check_nucleus_complexity(halfword q, scaled * delta, int cur_style, int *same) { pointer p = null; + pointer t = null; + if (same != NULL) { + *same = 0; + } switch (type(nucleus(q))) { - case math_char_node: - case math_text_char_node: - fetch(nucleus(q)); - if (char_exists(cur_f, cur_c)) { - /* we could look at neighbours */ - if (do_new_math(cur_f)) { - *delta = 0 ; /* cf spec only the last one */ - } else { - *delta = char_italic(cur_f, cur_c); - } - p = new_glyph(cur_f, cur_c); - reset_attributes(p, node_attr(nucleus(q))); - if (do_new_math(cur_f)) { - if (! math_no_char_italic_par) { - /* keep italic, but bad with two successive letters */ - } else if (get_char_cat_code(cur_c) == 11) { + case math_char_node: + case math_text_char_node: + fetch(nucleus(q)); + if (char_exists(cur_f, cur_c)) { + /* we could look at neighbours */ + if (do_new_math(cur_f)) { + *delta = 0 ; /* cf spec only the last one */ + } else { + *delta = char_italic(cur_f, cur_c); + } + p = new_glyph(cur_f, cur_c); + reset_attributes(p, node_attr(nucleus(q))); + if (do_new_math(cur_f)) { + if (! math_no_char_italic_par) { + /* keep italic, but bad with two successive letters */ + } else if (get_char_cat_code(cur_c) == 11) { + /* no italic correction in mid-word of text font */ + *delta = 0; + } + } else { /* no italic correction in mid-word of text font */ - *delta = 0; + if (((type(nucleus(q))) == math_text_char_node) && (space(cur_f) != 0)) { + *delta = 0; + } } - } else { - /* no italic correction in mid-word of text font */ - if (((type(nucleus(q))) == math_text_char_node) && (space(cur_f) != 0)) { + /* so we only add italic correction when we have no scripts */ + if ((subscr(q) == null) && (supscr(q) == null) && (*delta != 0)) { + pointer x = new_kern(*delta); + subtype(x) = italic_kern; + reset_attributes(x, node_attr(nucleus(q))); + couple_nodes(p,x); *delta = 0; + } else /* needs checking but looks ok */ + if (do_new_math(cur_f)) { + *delta = char_italic(cur_f, cur_c); /* must be more selective */ } } - /* so we only add italic correction when we have no scripts */ - if ((subscr(q) == null) && (supscr(q) == null) && (*delta != 0)) { - pointer x = new_kern(*delta); - reset_attributes(x, node_attr(nucleus(q))); - couple_nodes(p,x); - *delta = 0; - } - if (do_new_math(cur_f)) { - *delta = char_italic(cur_f, cur_c); /* must be more selective */ - } - } - break; - case sub_box_node: - p = math_list(nucleus(q)); - break; - case sub_mlist_node: - mlist_to_hlist(math_list(nucleus(q)), false, cur_style); /* recursive call */ - setup_cur_size(cur_style); - p = hpack(vlink(temp_head), 0, additional, -1); - reset_attributes(p, node_attr(nucleus(q))); - break; - default: - confusion("mlist2"); /* this can't happen mlist2 */ + break; + case sub_box_node: + p = math_list(nucleus(q)); + break; + case sub_mlist_node: + t = math_list(nucleus(q)); + mlist_to_hlist(t, false, cur_style); /* recursive call */ +if (same != NULL && type(t) == fence_noad && delimitersamesize(t)) { + *same = delimitersamesize(t) ; +} + setup_cur_size(cur_style); + p = hpack(vlink(temp_head), 0, additional, -1); + reset_attributes(p, node_attr(nucleus(q))); + break; + default: + confusion("mlist2"); /* this can't happen mlist2 */ } return p; } @@ -3867,9 +3933,12 @@ void mlist_to_hlist(pointer mlist, boolean penalties, int cur_style) int t; /* the effective |type| of noad |q| during the second pass */ int t_subtype; /* the effective |subtype| of noad |q| during the second pass */ pointer p = null; + pointer pp = null; pointer z = null; halfword nxt ; + int same = 0; int pen; /* a penalty to be inserted */ + int prepen; /* a penalty to be inserted */ scaled max_hl = 0; /* maximum height of the list translated so far */ scaled max_d = 0; /* maximum depth of the list translated so far */ scaled delta; /* italic correction offset for subscript and superscript */ @@ -3877,6 +3946,10 @@ void mlist_to_hlist(pointer mlist, boolean penalties, int cur_style) r_subtype = op_noad_type_normal; setup_cur_size(cur_style); cur_mu = x_over_n(get_math_quad_size(cur_size), 18); + if (math_penalties_mode_par) { + /* we could do this via the callback but it's nice to have it as primitive too */ + penalties = 1; + } while (q != null) { /* we use the fact that no character nodes appear in an mlist, hence @@ -3891,179 +3964,180 @@ void mlist_to_hlist(pointer mlist, boolean penalties, int cur_style) delta = 0; nxt = vlink(q); switch (type(q)) { - case simple_noad: - switch (subtype(q)) { - case bin_noad_type: - switch (r_type) { - case simple_noad: - switch (r_subtype) { - case bin_noad_type: - case op_noad_type_normal: - case op_noad_type_limits: - case op_noad_type_no_limits: - case rel_noad_type: - case open_noad_type: - case punct_noad_type: - subtype(q) = ord_noad_type; - goto RESWITCH; + case simple_noad: + switch (subtype(q)) { + case bin_noad_type: + switch (r_type) { + case simple_noad: + switch (r_subtype) { + case bin_noad_type: + case op_noad_type_normal: + case op_noad_type_limits: + case op_noad_type_no_limits: + case rel_noad_type: + case open_noad_type: + case punct_noad_type: + subtype(q) = ord_noad_type; + goto RESWITCH; + break; + } + break; + case fence_noad: + if (r_subtype == left_noad_side) { + subtype(q) = ord_noad_type; /* so these can best be the same size */ + goto RESWITCH; + } break; } break; - case fence_noad: - if (r_subtype == left_noad_side) { - subtype(q) = ord_noad_type; /* so these can best be the same size */ - goto RESWITCH; + case over_noad_type: + make_over(q, cur_style, cur_size, math_rules_fam_par); + break; + case under_noad_type: + make_under(q, cur_style, cur_size, math_rules_fam_par); + break; + case vcenter_noad_type: + make_vcenter(q); + break; + case rel_noad_type: + case close_noad_type: + case punct_noad_type: + if (r_type == simple_noad && r_subtype == bin_noad_type) { + type(r) = simple_noad; /* assumes the same size .. can't this go */ + subtype(r) = ord_noad_type; } break; + case op_noad_type_normal: + case op_noad_type_limits: + case op_noad_type_no_limits: + delta = make_op(q, cur_style); + if ((subtype(q) == op_noad_type_limits) || (subtype(q) == op_noad_type_no_limits)) + goto CHECK_DIMENSIONS; + break; + case ord_noad_type: + make_ord(q); + break; + case open_noad_type: + case inner_noad_type: + break; } break; - case over_noad_type: - make_over(q, cur_style, cur_size, math_rules_fam_par); - break; - case under_noad_type: - make_under(q, cur_style, cur_size, math_rules_fam_par); - break; - case vcenter_noad_type: - make_vcenter(q); - break; - case rel_noad_type: - case close_noad_type: - case punct_noad_type: - if (r_type == simple_noad && r_subtype == bin_noad_type) { - type(r) = simple_noad; /* assumes the same size .. can't this go */ - subtype(r) = ord_noad_type; + case fence_noad: + if (subtype(q) != left_noad_side) { + if (r_type == simple_noad && r_subtype == bin_noad_type) { + type(r) = simple_noad; /* assumes the same size */ + subtype(r) = ord_noad_type; + } } + goto DONE_WITH_NOAD; break; - case op_noad_type_normal: - case op_noad_type_limits: - case op_noad_type_no_limits: - delta = make_op(q, cur_style); - if ((subtype(q) == op_noad_type_limits) || (subtype(q) == op_noad_type_no_limits)) - goto CHECK_DIMENSIONS; + case fraction_noad: + make_fraction(q, cur_style); + goto CHECK_DIMENSIONS; break; - case ord_noad_type: - make_ord(q); + case radical_noad: + if (subtype(q) == 7) + make_hextension(q, cur_style); + else if (subtype(q) == 6) + make_delimiter_over(q, cur_style); + else if (subtype(q) == 5) + make_delimiter_under(q, cur_style); + else if (subtype(q) == 4) + make_over_delimiter(q, cur_style); + else if (subtype(q) == 3) + make_under_delimiter(q, cur_style); + else + make_radical(q, cur_style); break; - case open_noad_type: - case inner_noad_type: + case accent_noad: + make_math_accent(q, cur_style); break; - } - break; - case fence_noad: - if (subtype(q) != left_noad_side) - if (r_type == simple_noad && r_subtype == bin_noad_type) { - type(r) = simple_noad; /* assumes the same size */ - subtype(r) = ord_noad_type; - } - goto DONE_WITH_NOAD; - break; - case fraction_noad: - make_fraction(q, cur_style); - goto CHECK_DIMENSIONS; - break; - case radical_noad: - if (subtype(q) == 7) - make_hextension(q, cur_style); - else if (subtype(q) == 6) - make_delimiter_over(q, cur_style); - else if (subtype(q) == 5) - make_delimiter_under(q, cur_style); - else if (subtype(q) == 4) - make_over_delimiter(q, cur_style); - else if (subtype(q) == 3) - make_under_delimiter(q, cur_style); - else - make_radical(q, cur_style); - break; - case accent_noad: - make_math_accent(q, cur_style); - break; - case style_node: - cur_style = subtype(q); - setup_cur_size(cur_style); - cur_mu = x_over_n(get_math_quad_style(cur_style), 18); - goto DONE_WITH_NODE; - break; - case choice_node: - switch (cur_style / 2) { - case 0: /* |display_style=0| */ - choose_mlist(display_mlist); + case style_node: + cur_style = subtype(q); + setup_cur_size(cur_style); + cur_mu = x_over_n(get_math_quad_style(cur_style), 18); + goto DONE_WITH_NODE; break; - case 1: /* |text_style=2| */ - choose_mlist(text_mlist); + case choice_node: + switch (cur_style / 2) { + case 0: /* |display_style=0| */ + choose_mlist(display_mlist); + break; + case 1: /* |text_style=2| */ + choose_mlist(text_mlist); + break; + case 2: /* |script_style=4| */ + choose_mlist(script_mlist); + break; + case 3: /* |script_script_style=6| */ + choose_mlist(script_script_mlist); + break; + } + flush_node_list(display_mlist(q)); + flush_node_list(text_mlist(q)); + flush_node_list(script_mlist(q)); + flush_node_list(script_script_mlist(q)); + type(q) = style_node; + subtype(q) = (quarterword) cur_style; + if (p != null) { + z = vlink(q); + couple_nodes(q,p); + while (vlink(p) != null) + p = vlink(p); + try_couple_nodes(p,z); + } + goto DONE_WITH_NODE; break; - case 2: /* |script_style=4| */ - choose_mlist(script_mlist); + case ins_node: + case mark_node: + case adjust_node: + case boundary_node: + case whatsit_node: + case penalty_node: + case disc_node: + goto DONE_WITH_NODE; break; - case 3: /* |script_script_style=6| */ - choose_mlist(script_script_mlist); + case rule_node: + if (height(q) > max_hl) + max_hl = height(q); + if (depth(q) > max_d) + max_d = depth(q); + goto DONE_WITH_NODE; break; - } - flush_node_list(display_mlist(q)); - flush_node_list(text_mlist(q)); - flush_node_list(script_mlist(q)); - flush_node_list(script_script_mlist(q)); - type(q) = style_node; - subtype(q) = (quarterword) cur_style; - if (p != null) { - z = vlink(q); - couple_nodes(q,p); - while (vlink(p) != null) - p = vlink(p); - try_couple_nodes(p,z); - } - goto DONE_WITH_NODE; - break; - case ins_node: - case mark_node: - case adjust_node: - case boundary_node: - case whatsit_node: - case penalty_node: - case disc_node: - goto DONE_WITH_NODE; - break; - case rule_node: - if (height(q) > max_hl) - max_hl = height(q); - if (depth(q) > max_d) - max_d = depth(q); - goto DONE_WITH_NODE; - break; - case glue_node: - /* - conditional math glue (`\.{\\nonscript}') results in a |glue_node| - pointing to |zero_glue|, with |subtype(q)=cond_math_glue|; in such a case - the node following will be eliminated if it is a glue or kern node and if the - current size is different from |text_size| + case glue_node: + /* + conditional math glue (`\.{\\nonscript}') results in a |glue_node| + pointing to |zero_glue|, with |subtype(q)=cond_math_glue|; in such a case + the node following will be eliminated if it is a glue or kern node and if the + current size is different from |text_size| - unconditional math glue (`\.{\\muskip}') is converted to normal glue by - multiplying the dimensions by |cur_mu| + unconditional math glue (`\.{\\muskip}') is converted to normal glue by + multiplying the dimensions by |cur_mu| - */ - if (subtype(q) == mu_glue) { - math_glue_to_glue(q, cur_mu); - } else if ((cur_size != text_size) && (subtype(q) == cond_math_glue)) { - p = vlink(q); - if (p != null) - if ((type(p) == glue_node) || (type(p) == kern_node)) { - if (vlink(p) != null) { - couple_nodes(q,vlink(p)); - vlink(p) = null; - } else { - vlink(q) = null; + */ + if (subtype(q) == mu_glue) { + math_glue_to_glue(q, cur_mu); + } else if ((cur_size != text_size) && (subtype(q) == cond_math_glue)) { + p = vlink(q); + if (p != null) + if ((type(p) == glue_node) || (type(p) == kern_node)) { + if (vlink(p) != null) { + couple_nodes(q,vlink(p)); + vlink(p) = null; + } else { + vlink(q) = null; + } + flush_node_list(p); } - flush_node_list(p); - } - } - goto DONE_WITH_NODE; - break; - case kern_node: - math_kern(q, cur_mu); - goto DONE_WITH_NODE; - break; - default: - confusion("mlist1"); + } + goto DONE_WITH_NODE; + break; + case kern_node: + math_kern(q, cur_mu); + goto DONE_WITH_NODE; + break; + default: + confusion("mlist1"); } /* When we get to the following part of the program, we have ``fallen through'' @@ -4077,7 +4151,11 @@ void mlist_to_hlist(pointer mlist, boolean penalties, int cur_style) when both are present. */ - p = check_nucleus_complexity(q, &delta, cur_style); +same = 0 ; + p = check_nucleus_complexity(q, &delta, cur_style, &same); +if (same) { + noadextra4(q) = same ; +} if ((subscr(q) == null) && (supscr(q) == null)) { /* Adding italic correction here is kind of fuzzy because some @@ -4094,9 +4172,13 @@ void mlist_to_hlist(pointer mlist, boolean penalties, int cur_style) case open_noad_type: case close_noad_type: case punct_noad_type: - case inner_noad_type: delta = 0; break; + case inner_noad_type: + if (! delimitermodeitalics) { + delta = 0; + } + break; case op_noad_type_normal: case op_noad_type_limits: case op_noad_type_no_limits: @@ -4110,6 +4192,7 @@ void mlist_to_hlist(pointer mlist, boolean penalties, int cur_style) } if (delta != 0) { pointer d = new_kern(delta); + subtype(d) = italic_kern; reset_attributes(d, node_attr(q)); couple_nodes(p,d); } @@ -4178,15 +4261,18 @@ void mlist_to_hlist(pointer mlist, boolean penalties, int cur_style) t = simple_noad; t_subtype = ord_noad_type; pen = inf_penalty; + prepen = inf_penalty; switch (type(q)) { case simple_noad: t_subtype = subtype(q); switch (t_subtype) { case bin_noad_type: pen = bin_op_penalty_par; + prepen = pre_bin_op_penalty_par; break; case rel_noad_type: pen = rel_penalty_par; + prepen = pre_rel_penalty_par; break; case vcenter_noad_type: case over_noad_type: @@ -4233,12 +4319,24 @@ void mlist_to_hlist(pointer mlist, boolean penalties, int cur_style) /* Append inter-element spacing based on |r_type| and |t| */ if (r_type > 0) { /* not the first noad */ + pp = p; +if (delimitermodeordinal && t_subtype == inner_noad_type && noadextra4(q) == 1) { + z = math_spacing_glue(r_subtype, ord_noad_type, cur_style, cur_mu); +} else { z = math_spacing_glue(r_subtype, t_subtype, cur_style, cur_mu); +} if (z != null) { reset_attributes(z, node_attr(p)); couple_nodes(p,z); p = z; } + if (penalties && prepen < inf_penalty && type(pp) != penalty_node) { + /* no checking of prev node type */ + z = new_penalty(prepen,noad_penalty); + reset_attributes(z, node_attr(p)); + couple_nodes(p,z); + p = z; + } } /* Append any |new_hlist| entries for |q|, and any appropriate penalties diff --git a/Build/source/texk/web2c/luatexdir/tex/printing.w b/Build/source/texk/web2c/luatexdir/tex/printing.w index 006392810b9..72444156480 100644 --- a/Build/source/texk/web2c/luatexdir/tex/printing.w +++ b/Build/source/texk/web2c/luatexdir/tex/printing.w @@ -838,25 +838,66 @@ int font_in_short_display; /* an internal font number */ sort of ``complicated'' are indicated only by printing `\.{[]}'. @c + +/* +So, 0, 1 as well as any large value will behave the same as before. The reason +for this extension is that a \name not always makes sense. + +0 \foo xyz +1 \foo (bar) +2 <bar> xyz +3 <bar @@ ..> xyz +4 <id> +5 <id: bar> +6 <id: bar @@ ..> xyz + +*/ + void print_font_identifier(internal_font_number f) { str_number fonttext; fonttext = font_id_text(f); - if (fonttext > 0) { - print_esc(fonttext); + if (tracing_fonts_par >= 2 && tracing_fonts_par <= 6) { + /* < > is less likely to clash with text parenthesis */ + tprint("<"); + if (tracing_fonts_par >= 2 && tracing_fonts_par <= 3) { + print_font_name(f); + if (tracing_fonts_par >= 3 || font_size(f) != font_dsize(f)) { + tprint(" @@ "); + print_scaled(font_size(f)); + tprint("pt"); + } + } else if (tracing_fonts_par >= 4 && tracing_fonts_par <= 6) { + print_int(f); + if (tracing_fonts_par >= 5) { + tprint(": "); + print_font_name(f); + if (tracing_fonts_par >= 6 || font_size(f) != font_dsize(f)) { + tprint(" @@ "); + print_scaled(font_size(f)); + tprint("pt"); + } + } + } + print_char('>'); } else { - tprint_esc("FONT"); - print_int(f); - } - if (tracing_fonts_par > 0) { - tprint(" ("); - print_font_name(f); - if (font_size(f) != font_dsize(f)) { - tprint("@@"); - print_scaled(font_size(f)); - tprint("pt"); + /* old method, inherited from pdftex */ + if (fonttext > 0) { + print_esc(fonttext); + } else { + tprint_esc("FONT"); + print_int(f); + } + if (tracing_fonts_par > 0) { + tprint(" ("); + print_font_name(f); + if (font_size(f) != font_dsize(f)) { + tprint("@@"); + print_scaled(font_size(f)); + tprint("pt"); + } + print_char(')'); } - print_char(')'); } } diff --git a/Build/source/texk/web2c/luatexdir/tex/texfileio.w b/Build/source/texk/web2c/luatexdir/tex/texfileio.w index 2281de12c4c..a10e9ba63d0 100644 --- a/Build/source/texk/web2c/luatexdir/tex/texfileio.w +++ b/Build/source/texk/web2c/luatexdir/tex/texfileio.w @@ -150,9 +150,6 @@ char *luatex_find_file(const char *s, int callback_index) case find_enc_file_callback: ftemp = kpse_find_file(s, kpse_enc_format, 0); break; - case find_sfd_file_callback: - ftemp = kpse_find_file(s, kpse_sfd_format, 0); - break; case find_map_file_callback: ftemp = kpse_find_file(s, kpse_fontmap_format, 0); break; @@ -967,13 +964,13 @@ void start_input(void) update_terminal(); istate = new_line; /* Prepare new file {\sl Sync\TeX} information */ - synctexstartinput(); /* Give control to the {\sl Sync\TeX} controller */ - + if (! synctex_get_no_files()) { + synctexstartinput(); /* Give control to the {\sl Sync\TeX} controller */ + } /* Read the first line of the new file */ /* Here we have to remember to tell the |lua_input_ln| routine not to start with a |get|. If the file is empty, it is considered to contain a single blank line. */ - line = 1; if (lua_input_ln(cur_file, 0, false)) { ; diff --git a/Build/source/texk/web2c/luatexdir/tex/texmath.h b/Build/source/texk/web2c/luatexdir/tex/texmath.h index e5ad6798257..24bb34dc977 100644 --- a/Build/source/texk/web2c/luatexdir/tex/texmath.h +++ b/Build/source/texk/web2c/luatexdir/tex/texmath.h @@ -70,6 +70,7 @@ extern void math_ac(void); extern pointer new_style(small_number); extern void append_choices(void); extern void sub_sup(void); +extern void no_sub_sup(void); extern void math_fraction(void); extern void math_left_right(void); extern void after_math(void); diff --git a/Build/source/texk/web2c/luatexdir/tex/texmath.w b/Build/source/texk/web2c/luatexdir/tex/texmath.w index eeeb75bd792..6d4b87a3864 100644 --- a/Build/source/texk/web2c/luatexdir/tex/texmath.w +++ b/Build/source/texk/web2c/luatexdir/tex/texmath.w @@ -1353,6 +1353,17 @@ is sufficiently large, the |cur_chr| is treated as an active character and nothing is appended. @c +#define math_class_to_type(target,source) \ + switch (source) { \ + case 0: target = ord_noad_type; break; \ + case 1: target = op_noad_type_normal; break; \ + case 2: target = bin_noad_type; break; \ + case 3: target = rel_noad_type; break; \ + case 4: target = open_noad_type; break; \ + case 5: target = close_noad_type; break; \ + case 6: target = punct_noad_type; break; \ + } + void set_math_char(mathcodeval mval) { pointer p; /* the new noad */ @@ -1375,17 +1386,7 @@ void set_math_char(mathcodeval mval) math_fam(nucleus(p)) = cur_fam_par; subtype(p) = ord_noad_type; } else { - switch (mval.class_value) { - /* *INDENT-OFF* */ - case 0: subtype(p) = ord_noad_type; break; - case 1: subtype(p) = op_noad_type_normal; break; - case 2: subtype(p) = bin_noad_type; break; - case 3: subtype(p) = rel_noad_type; break; - case 4: subtype(p) = open_noad_type; break; - case 5: subtype(p) = close_noad_type; break; - case 6: subtype(p) = punct_noad_type; break; - /* *INDENT-ON* */ - } + math_class_to_type(subtype(p),mval.class_value); } vlink(tail) = p; tail = p; @@ -1727,7 +1728,7 @@ void build_choices(void) action procedure called |sub_sup|. @c -void sub_sup(void) +static void do_sub_sup(int no) { pointer q; if (tail == head || (!scripts_allowed(tail))) { @@ -1745,6 +1746,9 @@ void sub_sup(void) nucleus(tail) = q; tex_error("Double superscript", hlp); } + if (no) { + noadoptions(tail) = noadoptions(tail) | noad_option_no_super_script ; + } q = new_node(math_char_node, 0); supscr(tail) = q; (void) scan_math(supscr(tail), sup_style(m_style)); @@ -1758,12 +1762,26 @@ void sub_sup(void) nucleus(tail) = q; tex_error("Double subscript", hlp); } + if (no) { + noadoptions(tail) = noadoptions(tail) | noad_option_no_sub_script ; + } q = new_node(math_char_node, 0); subscr(tail) = q; (void) scan_math(subscr(tail), sub_style(m_style)); } } +void sub_sup(void) +{ + do_sub_sup(0); +} + +void no_sub_sup(void) +{ + do_sub_sup(1); +} + + @ An operation like `\.{\\over}' causes the current mlist to go into a state of suspended animation: |incompleat_noad| points to a |fraction_noad| that contains the mlist-so-far as its numerator, while the denominator @@ -1991,7 +2009,7 @@ void math_left_right(void) options = options | noad_option_exact ; } else if (scan_keyword("class")) { scan_int(); - type = cur_val ; + math_class_to_type(type,cur_val); } else { break; } @@ -2029,9 +2047,9 @@ void math_left_right(void) delimiteroptions(p) = options; delimiterclass(p) = type; delimiteritalic(p) = 0; + delimitersamesize(p) = 0; scan_delimiter(delimiter(p), no_mathcode); - if (t == no_noad_side) { tail_append(new_noad()); subtype(tail) = inner_noad_type; @@ -2133,36 +2151,41 @@ At this time we are in vertical mode (or internal vertical mode). @c #define inject_display_skip_before(g) \ - switch (display_skip_mode_par) { \ - case 0 : /* normal tex */ \ - tail_append(new_param_glue(g)); \ - break;\ - case 1 : /* always */ \ - tail_append(new_param_glue(g)); \ - break; \ - case 2 : /* non-zero */ \ - if (g != 0 && ! glue_is_zero(glue_par(g))) \ + if (g > 0) { \ + switch (display_skip_mode_par) { \ + case 0 : /* normal tex | always */ \ + case 1 : /* always */ \ + tail_append(new_param_glue(g)); \ + break; \ + case 2 : /* non-zero */ \ + if (! glue_is_zero(glue_par(g))) \ + tail_append(new_param_glue(g)); \ + break; \ + case 3: /* ignore */ \ + break; \ + default: /* > 3 reserved for future use */ \ tail_append(new_param_glue(g)); \ - break; \ - case 3: /* ignore */ \ - break; \ + break; \ + } \ } #define inject_display_skip_after(g) \ - switch (display_skip_mode_par) { \ - case 0 : /* normal tex */ \ - if (g != 0 && glue_is_positive(glue_par(g))) \ + if (g > 0) { \ + switch (display_skip_mode_par) { \ + case 0 : /* normal tex | always */ \ + case 1 : /* always */ \ tail_append(new_param_glue(g)); \ - break; \ - case 1 : /* always */ \ - tail_append(new_param_glue(g)); \ - break; \ - case 2 : /* non-zero */ \ - if (g != 0 && ! glue_is_zero(glue_par(g))) \ + break; \ + case 2 : /* non-zero */ \ + if (! glue_is_zero(glue_par(g))) \ + tail_append(new_param_glue(g)); \ + break; \ + case 3: /* ignore */ \ + break; \ + default: /* > 3 reserved for future use */ \ tail_append(new_param_glue(g)); \ - break; \ - case 3: /* ignore */ \ - break; \ + break; \ + } \ } static void finish_displayed_math(boolean l, pointer eqno_box, pointer p) diff --git a/Build/source/texk/web2c/luatexdir/tex/texnodes.h b/Build/source/texk/web2c/luatexdir/tex/texnodes.h index b838dd0a2f9..2bdd432e570 100644 --- a/Build/source/texk/web2c/luatexdir/tex/texnodes.h +++ b/Build/source/texk/web2c/luatexdir/tex/texnodes.h @@ -23,19 +23,6 @@ #ifndef __NODES_H__ # define __NODES_H__ -/* these are in texlang.c */ - -# define set_vlink(a,b) vlink(a)=b -# define get_vlink(a) vlink(a) -# define get_character(a) character(a) - -extern halfword insert_discretionary(halfword t, halfword pre, halfword post, halfword replace, int penalty); -extern halfword insert_syllable_discretionary(halfword t, lang_variables * lan); -extern halfword insert_word_discretionary(halfword t, lang_variables * lan); -extern halfword insert_complex_discretionary(halfword t, lang_variables * lan, halfword pre, halfword post, halfword replace); -extern halfword insert_character(halfword t, int n); -extern void set_disc_field(halfword f, halfword t); - # define varmemcast(a) (memory_word *)(a) extern memory_word *volatile varmem; @@ -297,15 +284,17 @@ typedef enum { # define adjust_pre subtype # define adjust_ptr(a) vlink(a+2) -# define glyph_node_size 6 -# define character(a) vinfo((a)+2) -# define font(a) vlink((a)+2) -# define lang_data(a) vinfo((a)+3) -# define lig_ptr(a) vlink((a)+3) -# define x_displace(a) vinfo((a)+4) -# define y_displace(a) vlink((a)+4) -# define ex_glyph(a) vinfo((a)+5) /* expansion factor (hz) */ -# define x_advance(a) vlink((a)+5) +# define glyph_node_size 7 +# define character(a) vinfo((a)+2) +# define font(a) vlink((a)+2) +# define lang_data(a) vinfo((a)+3) +# define lig_ptr(a) vlink((a)+3) +# define x_displace(a) vinfo((a)+4) +# define y_displace(a) vlink((a)+4) +# define ex_glyph(a) vinfo((a)+5) /* expansion factor (hz) */ +# define x_advance(a) vlink((a)+5) /* obsolete, can become user field */ +# define synctex_tag_glyph(a) vinfo((a)+6) +# define synctex_line_glyph(a) vlink((a)+6) # define is_char_node(a) (a!=null && type(a)==glyph_node) @@ -432,6 +421,8 @@ typedef enum { */ # define precedes_break(a) (type(a)<=last_preceding_break_node) +# define precedes_kern(a) ((type(a) == kern_node) && (subtype(a) == font_kern || subtype(a) == accent_kern)) +# define precedes_dir(a) ((type(a) == dir_node) && (break_after_dir_mode_par == 1)) # define non_discardable(a) (type(a)<=last_non_discardable_node) # define known_node_type(i) ( i >= 0 && i <= MAX_NODE_TYPE) @@ -492,9 +483,9 @@ typedef enum { # define noadheight(a) vlink((a)+5) # define noaddepth(a) vinfo((a)+5) # define noadextra1(a) vlink((a)+6) /* we need to match delimiter (saves copy) */ -# define noadextra2(a) vinfo((a)+6) +# define noadoptions(a) vinfo((a)+6) # define noadextra3(a) vlink((a)+7) /* see (!) below */ -# define noadextra4(a) vinfo((a)+7) +# define noadextra4(a) vinfo((a)+7) /* used to store samesize */ /* accent noads */ @@ -506,28 +497,31 @@ typedef enum { /* left and right noads */ -# define fence_noad_size 8 /* needs to match noad size */ -# define delimiteritalic(a) vlink((a)+4) -/* define delimiterwidth(a) vinfo((a)+4) */ -# define delimiterheight(a) vlink((a)+5) -# define delimiterdepth(a) vinfo((a)+5) -# define delimiter(a) vlink((a)+6) /* |delimiter| field in left and right noads */ -# define delimiteroptions(a) vinfo((a)+6) -# define delimiterclass(a) vlink((a)+7) /* (!) we could probably pack some more in 6 */ -# define delimiterextra1(a) vinfo((a)+7) /* not used */ +# define fence_noad_size 8 /* needs to match noad size */ +# define delimiteritalic(a) vlink((a)+4) +/* define delimiterwidth(a) vinfo((a)+4) */ +# define delimiterheight(a) vlink((a)+5) +# define delimiterdepth(a) vinfo((a)+5) +# define delimiter(a) vlink((a)+6) /* |delimiter| field in left and right noads */ +# define delimiteroptions(a) vinfo((a)+6) +# define delimiterclass(a) vlink((a)+7) /* (!) we could probably pack some more in 6 */ +# define delimitersamesize(a) vinfo((a)+7) /* set by engine */ /* when dimensions then axis else noaxis */ typedef enum { - noad_option_set = 0x08, - noad_option_unused_1 = 0x00 + 0x08, - noad_option_unused_2 = 0x01 + 0x08, - noad_option_axis = 0x02 + 0x08, - noad_option_no_axis = 0x04 + 0x08, - noad_option_exact = 0x10 + 0x08, - noad_option_left = 0x11 + 0x08, - noad_option_middle = 0x12 + 0x08, - noad_option_right = 0x14 + 0x08, + noad_option_set = 0x08, + noad_option_unused_1 = 0x00 + 0x08, + noad_option_unused_2 = 0x01 + 0x08, + noad_option_axis = 0x02 + 0x08, + noad_option_no_axis = 0x04 + 0x08, + noad_option_exact = 0x10 + 0x08, + noad_option_left = 0x11 + 0x08, + noad_option_middle = 0x12 + 0x08, + noad_option_right = 0x14 + 0x08, + noad_option_no_sub_script = 0x21 + 0x08, + noad_option_no_super_script = 0x22 + 0x08, + noad_option_no_script = 0x23 + 0x08, } delimiter_options ; # define delimiteroptionset(a) ((delimiteroptions(a) & noad_option_set ) == noad_option_set ) @@ -535,6 +529,23 @@ typedef enum { # define delimiternoaxis(a) ((delimiteroptions(a) & noad_option_no_axis) == noad_option_no_axis) # define delimiterexact(a) ((delimiteroptions(a) & noad_option_exact ) == noad_option_exact ) +# define noadoptionnosubscript(a) ( (type(a) == simple_noad) && ( \ + ((delimiteroptions(a) & noad_option_no_sub_script ) == noad_option_no_sub_script) || \ + ((delimiteroptions(a) & noad_option_no_script ) == noad_option_no_script ) )) +# define noadoptionnosupscript(a) ( (type(a) == simple_noad) && ( \ + ((delimiteroptions(a) & noad_option_no_super_script) == noad_option_no_super_script) || \ + ((delimiteroptions(a) & noad_option_no_script ) == noad_option_no_script ) )) + +typedef enum { + noad_delimiter_mode_noshift = 0x01, + noad_delimiter_mode_italics = 0x02, + noad_delimiter_mode_ordinal = 0x04, +} delimiter_modes ; + +# define delimitermodenoshift ((math_delimiters_mode_par & noad_delimiter_mode_noshift) == noad_delimiter_mode_noshift) +# define delimitermodeitalics ((math_delimiters_mode_par & noad_delimiter_mode_italics) == noad_delimiter_mode_italics) +# define delimitermodeordinal ((math_delimiters_mode_par & noad_delimiter_mode_ordinal) == noad_delimiter_mode_ordinal) + /* subtype of fence noads */ # define left_noad_side 1 @@ -928,7 +939,7 @@ extern halfword do_copy_node_list(halfword, halfword); extern halfword copy_node_list(halfword); extern halfword copy_node(const halfword); extern void check_node(halfword); -extern void fix_node_list(halfword); +extern halfword fix_node_list(halfword); extern int fix_node_lists; extern char *sprint_node_mem_usage(void); extern halfword raw_glyph_node(void); @@ -1013,5 +1024,16 @@ extern int lua_properties_use_metatable ; extern halfword make_local_par_node(int mode); +extern void synctex_set_mode(int mode); +extern int synctex_get_mode(void); +extern void synctex_set_tag(int tag); +extern void synctex_set_line(int line); +extern void synctex_force_tag(int tag); +extern void synctex_force_line(int tag); +extern int synctex_get_tag(void); +extern void synctex_set_no_files(int flag); +extern int synctex_get_no_files(void); +extern int synctex_get_line(void); + #endif diff --git a/Build/source/texk/web2c/luatexdir/tex/texnodes.w b/Build/source/texk/web2c/luatexdir/tex/texnodes.w index 7967006ec35..d0008b08fc8 100644 --- a/Build/source/texk/web2c/luatexdir/tex/texnodes.w +++ b/Build/source/texk/web2c/luatexdir/tex/texnodes.w @@ -656,11 +656,14 @@ static int test_count = 1; #define check_action_ref(a) { dorangetest(p,a,var_mem_max); } #define check_attribute_ref(a) { dorangetest(p,a,var_mem_max); } -#define check_token_ref(a) { \ + +/* hm, we can just pass p then */ + +#define check_token_ref(p) { \ if (type(p) == whatsit_node) { \ - formatted_error("nodes","fuzzy token cleanup in whatsit node with id %i and subtype %i",type(p),subtype(p)); \ + formatted_error("nodes","fuzzy token cleanup in whatsit node with type %s and subtype %i",node_data[type(p)].name,subtype(p)); \ } else { \ - formatted_error("nodes","fuzzy token cleanup in node with id %i",type(p)); \ + formatted_error("nodes","fuzzy token cleanup in node with type %s",node_data[type(p)].name); \ } \ } @@ -828,6 +831,67 @@ static int copy_error(halfword p) } @ @c +static halfword synctex_anyway_mode = 0; /* 2 also glyphs */ +static halfword synctex_line_field = 0; +static halfword synctex_no_files = 0; + +void synctex_set_mode(int m) +{ + synctex_anyway_mode = m; +}; + +int synctex_get_mode(void) +{ + return synctex_anyway_mode; +}; + +void synctex_set_no_files(int f) +{ + synctex_no_files = f; +}; + +int synctex_get_no_files(void) +{ + return (int) synctex_no_files ; +}; + +void synctex_set_tag(int t) +{ + cur_input.synctex_tag_field = t; +}; + +int synctex_get_tag(void) +{ + return (int) cur_input.synctex_tag_field; +}; + + +int synctex_get_line(void) +{ + return (int) synctex_line_field; +}; + +static int forced_tag = 0; +static int forced_line = 0; + +void synctex_force_tag(int t) +{ + forced_tag = t; +}; + +void synctex_force_line(int t) +{ + forced_line = t; +}; + +void synctex_set_line(int l) +{ + synctex_line_field = l; +}; + +@ @c +/* if_stack is called a lot so maybe optimize */ + halfword new_node(int i, int j) { int s = get_node_size(i, j); @@ -892,13 +956,54 @@ halfword new_node(int i, int j) default: break; } - if (synctex_par) { - /* handle synctex extension */ + if (synctex_anyway_mode) { switch (i) { - case math_node: - synctex_tag_math(n) = cur_input.synctex_tag_field; - synctex_line_math(n) = line; + /* 1 = all but glyphs */ + /* 2 = also glyphs */ + /* 3 = glyphs and glue */ + /* 4 = only glyphs */ + case glyph_node: + if (synctex_anyway_mode > 1) { + synctex_tag_glyph(n) = forced_tag ? forced_tag : cur_input.synctex_tag_field; + synctex_line_glyph(n) = forced_line ? forced_line : synctex_line_field ? synctex_line_field : line; + } + break; + case glue_node: + if (synctex_anyway_mode < 4) { + synctex_tag_glue(n) = forced_tag ? forced_tag : cur_input.synctex_tag_field; + synctex_line_glue(n) = forced_line ? forced_line : synctex_line_field ? synctex_line_field : line; + } + break; + case kern_node: + if (synctex_anyway_mode < 3) { + synctex_tag_kern(n) = forced_tag ? forced_tag : cur_input.synctex_tag_field; + synctex_line_kern(n) = forced_line ? forced_line : synctex_line_field ? synctex_line_field : line; + } + break; + case hlist_node: + case vlist_node: + case unset_node: /* useless */ + if (synctex_anyway_mode < 3) { + synctex_tag_box(n) = forced_tag ? forced_tag : cur_input.synctex_tag_field; + synctex_line_box(n) = forced_line ? forced_line : synctex_line_field ? synctex_line_field : line; + } + break; + case rule_node: + if (synctex_anyway_mode < 3) { + synctex_tag_rule(n) = forced_tag ? forced_tag : cur_input.synctex_tag_field; + synctex_line_rule(n) = forced_line ? forced_line : synctex_line_field ? synctex_line_field : line; + } break; + case math_node: /* noads probably make more sense */ + if (synctex_anyway_mode < 3) { + synctex_tag_math(n) = forced_tag ? forced_tag : cur_input.synctex_tag_field; + synctex_line_math(n) = forced_line ? forced_line : synctex_line_field ? synctex_line_field : line; + } + break; + } + } else if (synctex_par) { + /* handle synctex extension */ + switch (i) { case glue_node: synctex_tag_glue(n) = cur_input.synctex_tag_field; synctex_line_glue(n) = line; @@ -919,6 +1024,10 @@ halfword new_node(int i, int j) synctex_tag_rule(n) = cur_input.synctex_tag_field; synctex_line_rule(n) = line; break; + case math_node: + synctex_tag_math(n) = cur_input.synctex_tag_field; + synctex_line_math(n) = line; + break; } } /* take care of attributes */ @@ -935,6 +1044,10 @@ halfword raw_glyph_node(void) { register halfword n = get_node(glyph_node_size); (void) memset((void *) (varmem + n + 1), 0, (sizeof(memory_word) * (glyph_node_size - 1))); + if (synctex_anyway_mode > 1) { + synctex_tag_glyph(n) = forced_tag ? forced_tag : cur_input.synctex_tag_field; + synctex_line_glyph(n) = forced_line ? forced_line : synctex_line_field ? synctex_line_field : line; + } type(n) = glyph_node; subtype(n) = 0; return n; @@ -944,6 +1057,10 @@ halfword new_glyph_node(void) { register halfword n = get_node(glyph_node_size); (void) memset((void *) (varmem + n + 1), 0, (sizeof(memory_word) * (glyph_node_size - 1))); + if (synctex_anyway_mode > 1) { + synctex_tag_glyph(n) = forced_tag ? forced_tag : cur_input.synctex_tag_field; + synctex_line_glyph(n) = forced_line ? forced_line : synctex_line_field ? synctex_line_field : line; + } type(n) = glyph_node; subtype(n) = 0; build_attribute_list(n); @@ -1102,7 +1219,16 @@ halfword copy_node(const halfword p) } */ - if (synctex_par) { + if (synctex_anyway_mode) { + /* + if (t == glyph_node) { + if (synctex_anyway_mode > 1) { + synctex_tag_glyph(r) = forced_tag ? forced_tag : cur_input.synctex_tag_field; + synctex_line_glyph(r) = forced_line ? forced_line : synctex_line_field ? synctex_line_field : line; + } + } + */ + } else if (synctex_par) { /* handle synctex extension */ switch (t) { case math_node: @@ -1520,7 +1646,7 @@ static void check_node_wrapup_core(halfword p) switch (subtype(p)) { /* frontend code */ case special_node: - check_token_ref(write_tokens(p)); + check_token_ref(p); break; case user_defined_node: switch (user_node_type(p)) { @@ -1528,7 +1654,7 @@ static void check_node_wrapup_core(halfword p) check_attribute_ref(user_node_value(p)); break; case 't': - check_token_ref(user_node_value(p)); + check_token_ref(p); break; case 'n': dorangetest(p, user_node_value(p), var_mem_max); @@ -1558,39 +1684,39 @@ void check_node_wrapup_pdf(halfword p) switch (subtype(p)) { case pdf_literal_node: if (pdf_literal_type(p) == normal) - check_token_ref(pdf_literal_data(p)); + check_token_ref(p); break; case pdf_colorstack_node: if (pdf_colorstack_cmd(p) <= colorstack_data) - check_token_ref(pdf_colorstack_data(p)); + check_token_ref(p); break; case pdf_setmatrix_node: - check_token_ref(pdf_setmatrix_data(p)); + check_token_ref(p); break; case late_lua_node: if (late_lua_name(p) > 0) - check_token_ref(late_lua_name(p)); + check_token_ref(p); if (late_lua_type(p) == normal) - check_token_ref(late_lua_data(p)); + check_token_ref(p); break; case pdf_annot_node: - check_token_ref(pdf_annot_data(p)); + check_token_ref(p); break; case pdf_start_link_node: if (pdf_link_attr(p) != null) - check_token_ref(pdf_link_attr(p)); + check_token_ref(p); check_action_ref(pdf_link_action(p)); break; case pdf_dest_node: if (pdf_dest_named_id(p) > 0) - check_token_ref(pdf_dest_id(p)); + check_token_ref(p); break; case pdf_thread_node: case pdf_start_thread_node: if (pdf_thread_named_id(p) > 0) - check_token_ref(pdf_thread_id(p)); + check_token_ref(p); if (pdf_thread_attr(p) != null) - check_token_ref(pdf_thread_attr(p)); + check_token_ref(p); break; case pdf_save_node: case pdf_restore_node: @@ -1718,18 +1844,19 @@ void check_node(halfword p) } @ @c -void fix_node_list(halfword head) +halfword fix_node_list(halfword head) { - halfword p, q; + halfword next, tail; if (head == null) - return; - p = head; - q = vlink(p); - while (q != null) { - alink(q) = p; - p = q; - q = vlink(p); + return null; + tail = head; + next = vlink(head); + while (next != null) { + alink(next) = tail; + tail = next; + next = vlink(tail); } + return tail; } @ @c diff --git a/Build/source/texk/web2c/luatexdir/tex/textoken.w b/Build/source/texk/web2c/luatexdir/tex/textoken.w index f0b6a0c6e75..bf14a96148e 100644 --- a/Build/source/texk/web2c/luatexdir/tex/textoken.w +++ b/Build/source/texk/web2c/luatexdir/tex/textoken.w @@ -2311,6 +2311,7 @@ static int do_variable_pdf(halfword c) else if (scan_keyword("imageresolution")) { do_variable_backend_int(c_pdf_image_resolution); } else if (scan_keyword("pkresolution")) { do_variable_backend_int(c_pdf_pk_resolution); } else if (scan_keyword("uniqueresname")) { do_variable_backend_int(c_pdf_unique_resname); } + else if (scan_keyword("majorversion")) { do_variable_backend_int(c_pdf_major_version); } else if (scan_keyword("minorversion")) { do_variable_backend_int(c_pdf_minor_version); } else if (scan_keyword("pagebox")) { do_variable_backend_int(c_pdf_pagebox); } else if (scan_keyword("inclusionerrorlevel")) { do_variable_backend_int(c_pdf_inclusion_errorlevel); } @@ -2775,11 +2776,6 @@ void conv_toks(void) print(get_luatexrevision()); pop_selector; break; - case luatex_date_code: - push_selector; - print_int(get_luatex_date_info()); - pop_selector; - break; case etex_code: push_selector; tprint(eTeX_version_string); @@ -3008,9 +3004,6 @@ str_number the_convert_string(halfword c, int i) case luatex_revision_code: print(get_luatexrevision()); break; - case luatex_date_code: - print_int(get_luatex_date_info()); - break; case etex_code: tprint(eTeX_version_string); break; diff --git a/Build/source/texk/web2c/luatexdir/utils/utils.w b/Build/source/texk/web2c/luatexdir/utils/utils.w index e947fb77df5..420f5cfe4e4 100644 --- a/Build/source/texk/web2c/luatexdir/utils/utils.w +++ b/Build/source/texk/web2c/luatexdir/utils/utils.w @@ -36,6 +36,7 @@ #include "md5.h" #include "lua/luatex-api.h" /* for luatex_banner */ +#include "luatex_svnversion.h" #include "png.h" #include "mplib.h" @@ -250,24 +251,39 @@ char *stripzeros(char *a) @ @c void initversionstring(char **versions) { +#ifdef LuajitTeX +#define LUA_VER_STRING LUAJIT_VERSION +#else +#define LUA_VER_STRING "lua version " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR "." LUA_VERSION_RELEASE +#endif +#define STR(tok) STR2(tok) +#define STR2(tok) #tok const_string fmt = "Compiled with libpng %s; using %s\n" - "Compiled with zlib %s; using %s\n" + "Compiled with %s\n" /* Lua or LuaJIT */ + "Compiled with mplib version %s\n" "Compiled with poppler version %s\n" - "Compiled with mplib version %s\n"; + "Compiled with zlib %s; using %s\n" + "\nDevelopment id: %s\n"; size_t len = strlen(fmt) + strlen(PNG_LIBPNG_VER_STRING) + strlen(png_libpng_ver) - + strlen(ZLIB_VERSION) + strlen(zlib_version) - + strlen(POPPLER_VERSION) + + strlen(LUA_VER_STRING) + strlen(mp_metapost_version()) + + strlen(POPPLER_VERSION) + + strlen(ZLIB_VERSION) + strlen(zlib_version) + + strlen(STR(luatex_svn_revision)) + 1; /* len will be more than enough, because of the placeholder chars in fmt that get replaced by the arguments. */ *versions = xmalloc(len); sprintf(*versions, fmt, - PNG_LIBPNG_VER_STRING, png_libpng_ver, - ZLIB_VERSION, zlib_version, POPPLER_VERSION, mp_metapost_version()); + PNG_LIBPNG_VER_STRING, png_libpng_ver, LUA_VER_STRING, + mp_metapost_version(),POPPLER_VERSION, + ZLIB_VERSION, zlib_version,STR(luatex_svn_revision)); +#undef STR2 +#undef STR +#undef LUA_VER_STRING } @ @c @@ -358,9 +374,9 @@ int do_zround(double r) } -@ MSVC doesn't have |rint|. +@ Old MSVC doesn't have |rint|. @c -#ifdef _MSC_VER +#if defined(_MSC_VER) && _MSC_VER <= 1600 # include <math.h> double rint(double x) |