Tarantool development patches archive
 help / color / mirror / Atom feed
* [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite
@ 2021-03-26  7:42 Sergey Kaplun via Tarantool-patches
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 01/30] test: add " Sergey Kaplun via Tarantool-patches
                   ` (31 more replies)
  0 siblings, 32 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26  7:42 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

Branch: https://github.com/tarantool/luajit/tree/skaplun/gh-5845-adapt-puc-rio-test-suite-v2
Test branch: https://github.com/tarantool/tarantool/tree/skaplun/gh-5845-adapt-puc-rio-test-suite-v2

Side note: I reword commit about variable names in error messages a
little, so the commit is different but the conten is the same.

Issues:
* https://github.com/tarantool/tarantool/issues/5845
* https://github.com/tarantool/tarantool/issues/4473

Suite is taken intact exept trailing whitespaces.
Command to check:
| $ diff -ruZ --color ../test/PUC-Lua-5.1-tests/ ~/Downloads/lua5.1-tests/
| Only in ../test/PUC-Lua-5.1-tests/: CMakeLists.txt
| Only in ../test/PUC-Lua-5.1-tests/libs: CMakeLists.txt
| Only in ~/Downloads/lua5.1-tests/libs: makefile
| Only in ~/Downloads/lua5.1-tests/libs: P1

Changes in the v2:
* split commits to atomic changes
* more verbose comments for some tests
* some test fixed instead commenting

Sergey Kaplun (30):
  test: add PUC-Rio Lua 5.1 test suite
  test: add compiling for C libs from PUC-Rio-Lua5.1
  test: adapt Lua 5.1 suite for out-of-source build
  test: remove quotes in progname from <main.lua>
  test: adapt arg availability test from Lua suite
  test: disable PUC Lua tests confused by -v output
  test: disable Lua tests for bytecode with header
  test: disable JIT for GC step counting tests
  test: disable Lua suite tests for line hook
  test: adapt test for debug.setlocal in Lua suite
  test: adapt getlocal PUC test for vararg func
  test: adapt PUC Lua test with count hooks
  test: disable PUC Lua test for tail call info
  test: adapt activeline check in the PUC Lua test
  test: disable PUC-Lua test for per-coroutine hooks
  test: adapt PUC Lua test for %q in fmt for LuaJIT
  test: disable locale-depended tests for Lua suite
  test: replace math.mod to math.fmod for Lua tests
  test: remove assert for string.gfind check
  test: adapt PUC Lua test for args in vararg func
  test: disable test for getfenv in closure tailcall
  test: disable PUC Lua test for var names in error
  test: disable PUC Lua test for fast function name
  test: disable PUC Lua test for non-asci identifier
  test: disable PUC Lua error test for syntax level
  test: disable tests with multiple -l options
  test: disable PUC Lua test for checking arg layout
  test: disable PUC Lua test checking -h option
  test: disable PUC Lua hanging GC test
  test: disable too depth recursive PUC Lua test

 .luacheckrc                                |    5 +-
 test/CMakeLists.txt                        |    2 +
 test/PUC-Lua-5.1-tests/CMakeLists.txt      |   46 +
 test/PUC-Lua-5.1-tests/README              |   41 +
 test/PUC-Lua-5.1-tests/all.lua             |  146 +++
 test/PUC-Lua-5.1-tests/api.lua             |  711 ++++++++++++
 test/PUC-Lua-5.1-tests/attrib.lua          |  339 ++++++
 test/PUC-Lua-5.1-tests/big.lua             |  381 +++++++
 test/PUC-Lua-5.1-tests/calls.lua           |  294 +++++
 test/PUC-Lua-5.1-tests/checktable.lua      |   77 ++
 test/PUC-Lua-5.1-tests/closure.lua         |  430 ++++++++
 test/PUC-Lua-5.1-tests/code.lua            |  143 +++
 test/PUC-Lua-5.1-tests/constructs.lua      |  242 +++++
 test/PUC-Lua-5.1-tests/db.lua              |  576 ++++++++++
 test/PUC-Lua-5.1-tests/errors.lua          |  269 +++++
 test/PUC-Lua-5.1-tests/etc/ltests.c        | 1147 ++++++++++++++++++++
 test/PUC-Lua-5.1-tests/etc/ltests.h        |   92 ++
 test/PUC-Lua-5.1-tests/events.lua          |  360 ++++++
 test/PUC-Lua-5.1-tests/files.lua           |  324 ++++++
 test/PUC-Lua-5.1-tests/gc.lua              |  325 ++++++
 test/PUC-Lua-5.1-tests/libs/CMakeLists.txt |   64 ++
 test/PUC-Lua-5.1-tests/libs/lib1.c         |   40 +
 test/PUC-Lua-5.1-tests/libs/lib11.c        |   18 +
 test/PUC-Lua-5.1-tests/libs/lib2.c         |   28 +
 test/PUC-Lua-5.1-tests/libs/lib21.c        |   18 +
 test/PUC-Lua-5.1-tests/literals.lua        |  181 +++
 test/PUC-Lua-5.1-tests/locals.lua          |  127 +++
 test/PUC-Lua-5.1-tests/main.lua            |  212 ++++
 test/PUC-Lua-5.1-tests/math.lua            |  209 ++++
 test/PUC-Lua-5.1-tests/nextvar.lua         |  397 +++++++
 test/PUC-Lua-5.1-tests/pm.lua              |  276 +++++
 test/PUC-Lua-5.1-tests/sort.lua            |   74 ++
 test/PUC-Lua-5.1-tests/strings.lua         |  191 ++++
 test/PUC-Lua-5.1-tests/vararg.lua          |  134 +++
 test/PUC-Lua-5.1-tests/verybig.lua         |  102 ++
 35 files changed, 8019 insertions(+), 2 deletions(-)
 create mode 100644 test/PUC-Lua-5.1-tests/CMakeLists.txt
 create mode 100644 test/PUC-Lua-5.1-tests/README
 create mode 100755 test/PUC-Lua-5.1-tests/all.lua
 create mode 100644 test/PUC-Lua-5.1-tests/api.lua
 create mode 100644 test/PUC-Lua-5.1-tests/attrib.lua
 create mode 100644 test/PUC-Lua-5.1-tests/big.lua
 create mode 100644 test/PUC-Lua-5.1-tests/calls.lua
 create mode 100644 test/PUC-Lua-5.1-tests/checktable.lua
 create mode 100644 test/PUC-Lua-5.1-tests/closure.lua
 create mode 100644 test/PUC-Lua-5.1-tests/code.lua
 create mode 100644 test/PUC-Lua-5.1-tests/constructs.lua
 create mode 100644 test/PUC-Lua-5.1-tests/db.lua
 create mode 100644 test/PUC-Lua-5.1-tests/errors.lua
 create mode 100644 test/PUC-Lua-5.1-tests/etc/ltests.c
 create mode 100644 test/PUC-Lua-5.1-tests/etc/ltests.h
 create mode 100644 test/PUC-Lua-5.1-tests/events.lua
 create mode 100644 test/PUC-Lua-5.1-tests/files.lua
 create mode 100644 test/PUC-Lua-5.1-tests/gc.lua
 create mode 100644 test/PUC-Lua-5.1-tests/libs/CMakeLists.txt
 create mode 100644 test/PUC-Lua-5.1-tests/libs/lib1.c
 create mode 100644 test/PUC-Lua-5.1-tests/libs/lib11.c
 create mode 100644 test/PUC-Lua-5.1-tests/libs/lib2.c
 create mode 100644 test/PUC-Lua-5.1-tests/libs/lib21.c
 create mode 100644 test/PUC-Lua-5.1-tests/literals.lua
 create mode 100644 test/PUC-Lua-5.1-tests/locals.lua
 create mode 100644 test/PUC-Lua-5.1-tests/main.lua
 create mode 100644 test/PUC-Lua-5.1-tests/math.lua
 create mode 100644 test/PUC-Lua-5.1-tests/nextvar.lua
 create mode 100644 test/PUC-Lua-5.1-tests/pm.lua
 create mode 100644 test/PUC-Lua-5.1-tests/sort.lua
 create mode 100644 test/PUC-Lua-5.1-tests/strings.lua
 create mode 100644 test/PUC-Lua-5.1-tests/vararg.lua
 create mode 100644 test/PUC-Lua-5.1-tests/verybig.lua

-- 
2.31.0


^ permalink raw reply	[flat|nested] 153+ messages in thread

* [Tarantool-patches] [PATCH v2 luajit 01/30] test: add PUC-Rio Lua 5.1 test suite
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
@ 2021-03-26  7:42 ` Sergey Kaplun via Tarantool-patches
  2021-03-26 10:14   ` Sergey Ostanevich via Tarantool-patches
  2021-03-30 22:13   ` Igor Munkin via Tarantool-patches
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 02/30] test: add compiling for C libs from PUC-Rio-Lua5.1 Sergey Kaplun via Tarantool-patches
                   ` (30 subsequent siblings)
  31 siblings, 2 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26  7:42 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=UTF-8, Size: 210215 bytes --]

This patch adds PUC-Rio Lua 5.1 test suite as a part of the LuaJIT test
suite. Source code taken verbatim (except trailing whitespaces) from
https://www.lua.org/tests/lua5.1-tests.tar.gz.

Some tests may fail after this commit. They will be disabled
or adapted in the next patches.

Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 .luacheckrc                                |    5 +-
 test/CMakeLists.txt                        |    2 +
 test/PUC-Lua-5.1-tests/CMakeLists.txt      |   45 +
 test/PUC-Lua-5.1-tests/README              |   41 +
 test/PUC-Lua-5.1-tests/all.lua             |  137 +++
 test/PUC-Lua-5.1-tests/api.lua             |  711 ++++++++++++
 test/PUC-Lua-5.1-tests/attrib.lua          |  339 ++++++
 test/PUC-Lua-5.1-tests/big.lua             |  381 +++++++
 test/PUC-Lua-5.1-tests/calls.lua           |  294 +++++
 test/PUC-Lua-5.1-tests/checktable.lua      |   77 ++
 test/PUC-Lua-5.1-tests/closure.lua         |  422 +++++++
 test/PUC-Lua-5.1-tests/code.lua            |  143 +++
 test/PUC-Lua-5.1-tests/constructs.lua      |  240 ++++
 test/PUC-Lua-5.1-tests/db.lua              |  499 +++++++++
 test/PUC-Lua-5.1-tests/errors.lua          |  250 +++++
 test/PUC-Lua-5.1-tests/etc/ltests.c        | 1147 ++++++++++++++++++++
 test/PUC-Lua-5.1-tests/etc/ltests.h        |   92 ++
 test/PUC-Lua-5.1-tests/events.lua          |  360 ++++++
 test/PUC-Lua-5.1-tests/files.lua           |  324 ++++++
 test/PUC-Lua-5.1-tests/gc.lua              |  312 ++++++
 test/PUC-Lua-5.1-tests/libs/CMakeLists.txt |   18 +
 test/PUC-Lua-5.1-tests/libs/lib1.c         |   40 +
 test/PUC-Lua-5.1-tests/libs/lib11.c        |   18 +
 test/PUC-Lua-5.1-tests/libs/lib2.c         |   28 +
 test/PUC-Lua-5.1-tests/libs/lib21.c        |   18 +
 test/PUC-Lua-5.1-tests/literals.lua        |  176 +++
 test/PUC-Lua-5.1-tests/locals.lua          |  127 +++
 test/PUC-Lua-5.1-tests/main.lua            |  159 +++
 test/PUC-Lua-5.1-tests/math.lua            |  208 ++++
 test/PUC-Lua-5.1-tests/nextvar.lua         |  396 +++++++
 test/PUC-Lua-5.1-tests/pm.lua              |  273 +++++
 test/PUC-Lua-5.1-tests/sort.lua            |   74 ++
 test/PUC-Lua-5.1-tests/strings.lua         |  176 +++
 test/PUC-Lua-5.1-tests/vararg.lua          |  126 +++
 test/PUC-Lua-5.1-tests/verybig.lua         |  100 ++
 35 files changed, 7756 insertions(+), 2 deletions(-)
 create mode 100644 test/PUC-Lua-5.1-tests/CMakeLists.txt
 create mode 100644 test/PUC-Lua-5.1-tests/README
 create mode 100755 test/PUC-Lua-5.1-tests/all.lua
 create mode 100644 test/PUC-Lua-5.1-tests/api.lua
 create mode 100644 test/PUC-Lua-5.1-tests/attrib.lua
 create mode 100644 test/PUC-Lua-5.1-tests/big.lua
 create mode 100644 test/PUC-Lua-5.1-tests/calls.lua
 create mode 100644 test/PUC-Lua-5.1-tests/checktable.lua
 create mode 100644 test/PUC-Lua-5.1-tests/closure.lua
 create mode 100644 test/PUC-Lua-5.1-tests/code.lua
 create mode 100644 test/PUC-Lua-5.1-tests/constructs.lua
 create mode 100644 test/PUC-Lua-5.1-tests/db.lua
 create mode 100644 test/PUC-Lua-5.1-tests/errors.lua
 create mode 100644 test/PUC-Lua-5.1-tests/etc/ltests.c
 create mode 100644 test/PUC-Lua-5.1-tests/etc/ltests.h
 create mode 100644 test/PUC-Lua-5.1-tests/events.lua
 create mode 100644 test/PUC-Lua-5.1-tests/files.lua
 create mode 100644 test/PUC-Lua-5.1-tests/gc.lua
 create mode 100644 test/PUC-Lua-5.1-tests/libs/CMakeLists.txt
 create mode 100644 test/PUC-Lua-5.1-tests/libs/lib1.c
 create mode 100644 test/PUC-Lua-5.1-tests/libs/lib11.c
 create mode 100644 test/PUC-Lua-5.1-tests/libs/lib2.c
 create mode 100644 test/PUC-Lua-5.1-tests/libs/lib21.c
 create mode 100644 test/PUC-Lua-5.1-tests/literals.lua
 create mode 100644 test/PUC-Lua-5.1-tests/locals.lua
 create mode 100644 test/PUC-Lua-5.1-tests/main.lua
 create mode 100644 test/PUC-Lua-5.1-tests/math.lua
 create mode 100644 test/PUC-Lua-5.1-tests/nextvar.lua
 create mode 100644 test/PUC-Lua-5.1-tests/pm.lua
 create mode 100644 test/PUC-Lua-5.1-tests/sort.lua
 create mode 100644 test/PUC-Lua-5.1-tests/strings.lua
 create mode 100644 test/PUC-Lua-5.1-tests/vararg.lua
 create mode 100644 test/PUC-Lua-5.1-tests/verybig.lua

diff --git a/.luacheckrc b/.luacheckrc
index 4e5dbdf..fd5583b 100644
--- a/.luacheckrc
+++ b/.luacheckrc
@@ -3,11 +3,12 @@ std = 'luajit'
 -- This fork also introduces a new global for misc API namespace.
 read_globals = { 'misc' }
 
--- These files are inherited from the vanilla LuaJIT and need to
--- be coherent with the upstream.
+-- These files are inherited from the vanilla LuaJIT or different
+-- test suites and need to be coherent with the upstream.
 exclude_files = {
   'dynasm/',
   'src/',
   'test/LuaJIT-tests/',
+  'test/PUC-Lua-5.1-tests/',
   'test/lua-Harness-tests/',
 }
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 02fb2ed..30cbf87 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -44,11 +44,13 @@ set(LUAJIT_TEST_COMMAND "${LUAJIT_TEST_BINARY} -e dofile[[${LUAJIT_TEST_INIT}]]"
 separate_arguments(LUAJIT_TEST_COMMAND)
 
 add_subdirectory(LuaJIT-tests)
+add_subdirectory(PUC-Lua-5.1-tests)
 add_subdirectory(lua-Harness-tests)
 add_subdirectory(tarantool-tests)
 
 add_custom_target(${PROJECT_NAME}-test DEPENDS
   LuaJIT-tests
+  PUC-Lua-5.1-tests
   lua-Harness-tests
   tarantool-tests
 )
diff --git a/test/PUC-Lua-5.1-tests/CMakeLists.txt b/test/PUC-Lua-5.1-tests/CMakeLists.txt
new file mode 100644
index 0000000..773db0d
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/CMakeLists.txt
@@ -0,0 +1,45 @@
+# Test suite that has been added from PUC-Rio Lua 5.1 test archive
+# in scope of https://github.com/tarantool/tarantool/issues/5845.
+
+# See the rationale in the root CMakeLists.txt.
+cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
+
+# XXX: There are two ways to set up the proper environment
+# described in the suite's README:
+# * set LUA_PATH to "?;./?.lua"
+# * or, better yet, set LUA_PATH to "./?.lua;;" and LUA_INIT to
+#   "package.path = '?;'..package.path"
+# Unfortunately, Tarantool doesn't support LUA_INIT and most
+# likely it never will. For more info, see
+# https://github.com/tarantool/tarantool/issues/5744
+# Hence, there is no way other than set LUA_PATH environment
+# variable as proposed in the first case.
+set(LUA_PATH "?\;${CMAKE_CURRENT_SOURCE_DIR}/?.lua")
+
+# Set PUC-Lua-5.1-tests-prepare target that creates <libs/P1>
+# subdirectory.
+add_subdirectory(libs)
+
+# TODO: PUC-Rio Lua 5.1 test suite also has special header
+# <ltests.h> and <ltests.c> translation unit to check some
+# internal behaviour of the Lua implementation (see etc/
+# directory). It modifies realloc function to check memory
+# consistency and also contains tests for yield in hooks
+# and for the Lua C API.
+# But, unfortunately, <ltests.c> depends on specific PUC-Rio
+# Lua 5.1 internal headers and should be adapted for LuaJIT.
+
+add_custom_target(PUC-Lua-5.1-tests
+  DEPENDS ${LUAJIT_TEST_BINARY} PUC-Lua-5.1-tests-prepare
+)
+
+add_custom_command(TARGET PUC-Lua-5.1-tests
+  COMMENT "Running PUC-Rio Lua 5.1 tests"
+  COMMAND
+  env
+    LUA_PATH="${LUA_PATH}\;\;"
+    ${LUAJIT_TEST_COMMAND} ${CMAKE_CURRENT_SOURCE_DIR}/all.lua
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+# vim: expandtab tabstop=2 shiftwidth=2
diff --git a/test/PUC-Lua-5.1-tests/README b/test/PUC-Lua-5.1-tests/README
new file mode 100644
index 0000000..e2d4b28
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/README
@@ -0,0 +1,41 @@
+This tarball contains the official test scripts for Lua 5.1.
+Unlike Lua itself, these tests do not aim portability, small footprint,
+or easy of use. (Their main goal is to try to crash Lua.) They are not
+intended for general use. You are wellcome to use them, but expect to
+have to "dirt your hands".
+
+The tarball should expand in the following contents:
+  - several .lua scripts with the tests
+  - a main "all.lua" Lua script that invokes all the other scripts
+  - a subdirectory "libs" with an empty subdirectory "libs/P1",
+    to be used by the scripts
+  - a subdirectory "etc" with some extra files
+
+To run the tests, do as follows:
+
+- go to the test directory
+
+- set LUA_PATH to "?;./?.lua" (or, better yet, set LUA_PATH to "./?.lua;;"
+  and LUA_INIT to "package.path = '?;'..package.path")
+
+- run "lua all.lua"
+
+
+--------------------------------------------
+Internal tests
+--------------------------------------------
+
+Some tests need a special library, "testC", that gives access to
+several internal structures in Lua.
+This library is only available when Lua is compiled in debug mode.
+The scripts automatically detect its absence and skip those tests.
+
+If you want to run these tests, move etc/ltests.c and etc/ltests.h to
+the directory with the source Lua files, and recompile Lua with
+the option -DLUA_USER_H='"ltests.h"' (or its equivalent to define
+LUA_USER_H as the string "ltests.h", including the quotes). This
+option not only adds the testC library, but it adds several other
+internal tests as well. After the recompilation, run the tests
+as before.
+
+
diff --git a/test/PUC-Lua-5.1-tests/all.lua b/test/PUC-Lua-5.1-tests/all.lua
new file mode 100755
index 0000000..8c4afac
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/all.lua
@@ -0,0 +1,137 @@
+#!../lua
+
+math.randomseed(0)
+
+collectgarbage("setstepmul", 180)
+collectgarbage("setpause", 190)
+
+
+--[=[
+  example of a long [comment],
+  [[spanning several [lines]]]
+
+]=]
+
+print("current path:\n  " .. string.gsub(package.path, ";", "\n  "))
+
+
+local msgs = {}
+function Message (m)
+  print(m)
+  msgs[#msgs+1] = string.sub(m, 3, -3)
+end
+
+
+local c = os.clock()
+
+assert(os.setlocale"C")
+
+local T,print,gcinfo,format,write,assert,type =
+      T,print,gcinfo,string.format,io.write,assert,type
+
+local function formatmem (m)
+  if m < 1024 then return m
+  else
+    m = m/1024 - m/1024%1
+    if m < 1024 then return m.."K"
+    else
+      m = m/1024 - m/1024%1
+      return m.."M"
+    end
+  end
+end
+
+local showmem = function ()
+  if not T then
+    print(format("    ---- total memory: %s ----\n", formatmem(gcinfo())))
+  else
+    T.checkmemory()
+    local a,b,c = T.totalmem()
+    local d,e = gcinfo()
+    print(format(
+  "\n    ---- total memory: %s (%dK), max use: %s,  blocks: %d\n",
+                        formatmem(a),  d,      formatmem(c),           b))
+  end
+end
+
+
+--
+-- redefine dofile to run files through dump/undump
+--
+dofile = function (n)
+  showmem()
+  local f = assert(loadfile(n))
+  local b = string.dump(f)
+  f = assert(loadstring(b))
+  return f()
+end
+
+dofile('main.lua')
+
+do
+  local u = newproxy(true)
+  local newproxy, stderr = newproxy, io.stderr
+  getmetatable(u).__gc = function (o)
+    stderr:write'.'
+    newproxy(o)
+  end
+end
+
+local f = assert(loadfile('gc.lua'))
+f()
+dofile('db.lua')
+assert(dofile('calls.lua') == deep and deep)
+dofile('strings.lua')
+dofile('literals.lua')
+assert(dofile('attrib.lua') == 27)
+assert(dofile('locals.lua') == 5)
+dofile('constructs.lua')
+dofile('code.lua')
+do
+  local f = coroutine.wrap(assert(loadfile('big.lua')))
+  assert(f() == 'b')
+  assert(f() == 'a')
+end
+dofile('nextvar.lua')
+dofile('pm.lua')
+dofile('api.lua')
+assert(dofile('events.lua') == 12)
+dofile('vararg.lua')
+dofile('closure.lua')
+dofile('errors.lua')
+dofile('math.lua')
+dofile('sort.lua')
+assert(dofile('verybig.lua') == 10); collectgarbage()
+dofile('files.lua')
+
+if #msgs > 0 then
+  print("\ntests not performed:")
+  for i=1,#msgs do
+    print(msgs[i])
+  end
+  print()
+end
+
+print("final OK !!!")
+print('cleaning all!!!!')
+
+debug.sethook(function (a) assert(type(a) == 'string') end, "cr")
+
+local _G, collectgarbage, showmem, print, format, clock =
+      _G, collectgarbage, showmem, print, format, os.clock
+
+local a={}
+for n in pairs(_G) do a[n] = 1 end
+a.tostring = nil
+a.___Glob = nil
+for n in pairs(a) do _G[n] = nil end
+
+a = nil
+collectgarbage()
+collectgarbage()
+collectgarbage()
+collectgarbage()
+collectgarbage()
+collectgarbage();showmem()
+
+print(format("\n\ntotal time: %.2f\n", clock()-c))
diff --git a/test/PUC-Lua-5.1-tests/api.lua b/test/PUC-Lua-5.1-tests/api.lua
new file mode 100644
index 0000000..c955ebf
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/api.lua
@@ -0,0 +1,711 @@
+
+if T==nil then
+  (Message or print)('\a\n >>> testC not active: skipping API tests <<<\n\a')
+  return
+end
+
+
+
+function tcheck (t1, t2)
+  table.remove(t1, 1)  -- remove code
+  assert(table.getn(t1) == table.getn(t2))
+  for i=1,table.getn(t1) do assert(t1[i] == t2[i]) end
+end
+
+function pack(...) return arg end
+
+
+print('testing C API')
+
+-- testing allignment
+a = T.d2s(12458954321123)
+assert(string.len(a) == 8)   -- sizeof(double)
+assert(T.s2d(a) == 12458954321123)
+
+a,b,c = T.testC("pushnum 1; pushnum 2; pushnum 3; return 2")
+assert(a == 2 and b == 3 and not c)
+
+-- test that all trues are equal
+a,b,c = T.testC("pushbool 1; pushbool 2; pushbool 0; return 3")
+assert(a == b and a == true and c == false)
+a,b,c = T.testC"pushbool 0; pushbool 10; pushnil;\
+                      tobool -3; tobool -3; tobool -3; return 3"
+assert(a==0 and b==1 and c==0)
+
+
+a,b,c = T.testC("gettop; return 2", 10, 20, 30, 40)
+assert(a == 40 and b == 5 and not c)
+
+t = pack(T.testC("settop 5; gettop; return .", 2, 3))
+tcheck(t, {n=4,2,3})
+
+t = pack(T.testC("settop 0; settop 15; return 10", 3, 1, 23))
+assert(t.n == 10 and t[1] == nil and t[10] == nil)
+
+t = pack(T.testC("remove -2; gettop; return .", 2, 3, 4))
+tcheck(t, {n=2,2,4})
+
+t = pack(T.testC("insert -1; gettop; return .", 2, 3))
+tcheck(t, {n=2,2,3})
+
+t = pack(T.testC("insert 3; gettop; return .", 2, 3, 4, 5))
+tcheck(t, {n=4,2,5,3,4})
+
+t = pack(T.testC("replace 2; gettop; return .", 2, 3, 4, 5))
+tcheck(t, {n=3,5,3,4})
+
+t = pack(T.testC("replace -2; gettop; return .", 2, 3, 4, 5))
+tcheck(t, {n=3,2,3,5})
+
+t = pack(T.testC("remove 3; gettop; return .", 2, 3, 4, 5))
+tcheck(t, {n=3,2,4,5})
+
+t = pack(T.testC("insert 3; pushvalue 3; remove 3; pushvalue 2; remove 2; \
+                  insert 2; pushvalue 1; remove 1; insert 1; \
+      insert -2; pushvalue -2; remove -3; gettop; return .",
+      2, 3, 4, 5, 10, 40, 90))
+tcheck(t, {n=7,2,3,4,5,10,40,90})
+
+t = pack(T.testC("concat 5; gettop; return .", "alo", 2, 3, "joao", 12))
+tcheck(t, {n=1,"alo23joao12"})
+
+-- testing MULTRET
+t = pack(T.testC("rawcall 2,-1; gettop; return .",
+     function (a,b) return 1,2,3,4,a,b end, "alo", "joao"))
+tcheck(t, {n=6,1,2,3,4,"alo", "joao"})
+
+do  -- test returning more results than fit in the caller stack
+  local a = {}
+  for i=1,1000 do a[i] = true end; a[999] = 10
+  local b = T.testC([[call 1 -1; pop 1; tostring -1; return 1]], unpack, a)
+  assert(b == "10")
+end
+
+
+-- testing lessthan
+assert(T.testC("lessthan 2 5, return 1", 3, 2, 2, 4, 2, 2))
+assert(T.testC("lessthan 5 2, return 1", 4, 2, 2, 3, 2, 2))
+assert(not T.testC("lessthan 2 -3, return 1", "4", "2", "2", "3", "2", "2"))
+assert(not T.testC("lessthan -3 2, return 1", "3", "2", "2", "4", "2", "2"))
+
+local b = {__lt = function (a,b) return a[1] < b[1] end}
+local a1,a3,a4 = setmetatable({1}, b),
+                 setmetatable({3}, b),
+                 setmetatable({4}, b)
+assert(T.testC("lessthan 2 5, return 1", a3, 2, 2, a4, 2, 2))
+assert(T.testC("lessthan 5 -6, return 1", a4, 2, 2, a3, 2, 2))
+a,b = T.testC("lessthan 5 -6, return 2", a1, 2, 2, a3, 2, 20)
+assert(a == 20 and b == false)
+
+
+-- testing lua_is
+
+function count (x, n)
+  n = n or 2
+  local prog = [[
+    isnumber %d;
+    isstring %d;
+    isfunction %d;
+    iscfunction %d;
+    istable %d;
+    isuserdata %d;
+    isnil %d;
+    isnull %d;
+    return 8
+  ]]
+  prog = string.format(prog, n, n, n, n, n, n, n, n)
+  local a,b,c,d,e,f,g,h = T.testC(prog, x)
+  return a+b+c+d+e+f+g+(100*h)
+end
+
+assert(count(3) == 2)
+assert(count('alo') == 1)
+assert(count('32') == 2)
+assert(count({}) == 1)
+assert(count(print) == 2)
+assert(count(function () end) == 1)
+assert(count(nil) == 1)
+assert(count(io.stdin) == 1)
+assert(count(nil, 15) == 100)
+
+-- testing lua_to...
+
+function to (s, x, n)
+  n = n or 2
+  return T.testC(string.format("%s %d; return 1", s, n), x)
+end
+
+assert(to("tostring", {}) == nil)
+assert(to("tostring", "alo") == "alo")
+assert(to("tostring", 12) == "12")
+assert(to("tostring", 12, 3) == nil)
+assert(to("objsize", {}) == 0)
+assert(to("objsize", "alo\0\0a") == 6)
+assert(to("objsize", T.newuserdata(0)) == 0)
+assert(to("objsize", T.newuserdata(101)) == 101)
+assert(to("objsize", 12) == 2)
+assert(to("objsize", 12, 3) == 0)
+assert(to("tonumber", {}) == 0)
+assert(to("tonumber", "12") == 12)
+assert(to("tonumber", "s2") == 0)
+assert(to("tonumber", 1, 20) == 0)
+a = to("tocfunction", math.deg)
+assert(a(3) == math.deg(3) and a ~= math.deg)
+
+
+-- testing errors
+
+a = T.testC([[
+  loadstring 2; call 0,1;
+  pushvalue 3; insert -2; call 1, 1;
+  call 0, 0;
+  return 1
+]], "x=150", function (a) assert(a==nil); return 3 end)
+
+assert(type(a) == 'string' and x == 150)
+
+function check3(p, ...)
+  assert(arg.n == 3)
+  assert(string.find(arg[3], p))
+end
+check3(":1:", T.testC("loadstring 2; gettop; return .", "x="))
+check3("cannot read", T.testC("loadfile 2; gettop; return .", "."))
+check3("cannot open xxxx", T.testC("loadfile 2; gettop; return .", "xxxx"))
+
+-- testing table access
+
+a = {x=0, y=12}
+x, y = T.testC("gettable 2; pushvalue 4; gettable 2; return 2",
+                a, 3, "y", 4, "x")
+assert(x == 0 and y == 12)
+T.testC("settable -5", a, 3, 4, "x", 15)
+assert(a.x == 15)
+a[a] = print
+x = T.testC("gettable 2; return 1", a)  -- table and key are the same object!
+assert(x == print)
+T.testC("settable 2", a, "x")    -- table and key are the same object!
+assert(a[a] == "x")
+
+b = setmetatable({p = a}, {})
+getmetatable(b).__index = function (t, i) return t.p[i] end
+k, x = T.testC("gettable 3, return 2", 4, b, 20, 35, "x")
+assert(x == 15 and k == 35)
+getmetatable(b).__index = function (t, i) return a[i] end
+getmetatable(b).__newindex = function (t, i,v ) a[i] = v end
+y = T.testC("insert 2; gettable -5; return 1", 2, 3, 4, "y", b)
+assert(y == 12)
+k = T.testC("settable -5, return 1", b, 3, 4, "x", 16)
+assert(a.x == 16 and k == 4)
+a[b] = 'xuxu'
+y = T.testC("gettable 2, return 1", b)
+assert(y == 'xuxu')
+T.testC("settable 2", b, 19)
+assert(a[b] == 19)
+
+-- testing next
+a = {}
+t = pack(T.testC("next; gettop; return .", a, nil))
+tcheck(t, {n=1,a})
+a = {a=3}
+t = pack(T.testC("next; gettop; return .", a, nil))
+tcheck(t, {n=3,a,'a',3})
+t = pack(T.testC("next; pop 1; next; gettop; return .", a, nil))
+tcheck(t, {n=1,a})
+
+
+
+-- testing upvalues
+
+do
+  local A = T.testC[[ pushnum 10; pushnum 20; pushcclosure 2; return 1]]
+  t, b, c = A([[pushvalue U0; pushvalue U1; pushvalue U2; return 3]])
+  assert(b == 10 and c == 20 and type(t) == 'table')
+  a, b = A([[tostring U3; tonumber U4; return 2]])
+  assert(a == nil and b == 0)
+  A([[pushnum 100; pushnum 200; replace U2; replace U1]])
+  b, c = A([[pushvalue U1; pushvalue U2; return 2]])
+  assert(b == 100 and c == 200)
+  A([[replace U2; replace U1]], {x=1}, {x=2})
+  b, c = A([[pushvalue U1; pushvalue U2; return 2]])
+  assert(b.x == 1 and c.x == 2)
+  T.checkmemory()
+end
+
+local f = T.testC[[ pushnum 10; pushnum 20; pushcclosure 2; return 1]]
+assert(T.upvalue(f, 1) == 10 and
+       T.upvalue(f, 2) == 20 and
+       T.upvalue(f, 3) == nil)
+T.upvalue(f, 2, "xuxu")
+assert(T.upvalue(f, 2) == "xuxu")
+
+
+-- testing environments
+
+assert(T.testC"pushvalue G; return 1" == _G)
+assert(T.testC"pushvalue E; return 1" == _G)
+local a = {}
+T.testC("replace E; return 1", a)
+assert(T.testC"pushvalue G; return 1" == _G)
+assert(T.testC"pushvalue E; return 1" == a)
+assert(debug.getfenv(T.testC) == a)
+assert(debug.getfenv(T.upvalue) == _G)
+-- userdata inherit environment
+local u = T.testC"newuserdata 0; return 1"
+assert(debug.getfenv(u) == a)
+-- functions inherit environment
+u = T.testC"pushcclosure 0; return 1"
+assert(debug.getfenv(u) == a)
+debug.setfenv(T.testC, _G)
+assert(T.testC"pushvalue E; return 1" == _G)
+
+local b = newproxy()
+assert(debug.getfenv(b) == _G)
+assert(debug.setfenv(b, a))
+assert(debug.getfenv(b) == a)
+
+
+
+-- testing locks (refs)
+
+-- reuse of references
+local i = T.ref{}
+T.unref(i)
+assert(T.ref{} == i)
+
+Arr = {}
+Lim = 100
+for i=1,Lim do   -- lock many objects
+  Arr[i] = T.ref({})
+end
+
+assert(T.ref(nil) == -1 and T.getref(-1) == nil)
+T.unref(-1); T.unref(-1)
+
+for i=1,Lim do   -- unlock all them
+  T.unref(Arr[i])
+end
+
+function printlocks ()
+  local n = T.testC("gettable R; return 1", "n")
+  print("n", n)
+  for i=0,n do
+    print(i, T.testC("gettable R; return 1", i))
+  end
+end
+
+
+for i=1,Lim do   -- lock many objects
+  Arr[i] = T.ref({})
+end
+
+for i=1,Lim,2 do   -- unlock half of them
+  T.unref(Arr[i])
+end
+
+assert(type(T.getref(Arr[2])) == 'table')
+
+
+assert(T.getref(-1) == nil)
+
+
+a = T.ref({})
+
+collectgarbage()
+
+assert(type(T.getref(a)) == 'table')
+
+
+-- colect in cl the `val' of all collected userdata
+tt = {}
+cl = {n=0}
+A = nil; B = nil
+local F
+F = function (x)
+  local udval = T.udataval(x)
+  table.insert(cl, udval)
+  local d = T.newuserdata(100)   -- cria lixo
+  d = nil
+  assert(debug.getmetatable(x).__gc == F)
+  loadstring("table.insert({}, {})")()   -- cria mais lixo
+  collectgarbage()   -- forca coleta de lixo durante coleta!
+  assert(debug.getmetatable(x).__gc == F)   -- coleta anterior nao melou isso?
+  local dummy = {}    -- cria lixo durante coleta
+  if A ~= nil then
+    assert(type(A) == "userdata")
+    assert(T.udataval(A) == B)
+    debug.getmetatable(A)    -- just acess it
+  end
+  A = x   -- ressucita userdata
+  B = udval
+  return 1,2,3
+end
+tt.__gc = F
+
+-- test whether udate collection frees memory in the right time
+do
+  collectgarbage();
+  collectgarbage();
+  local x = collectgarbage("count");
+  local a = T.newuserdata(5001)
+  assert(T.testC("objsize 2; return 1", a) == 5001)
+  assert(collectgarbage("count") >= x+4)
+  a = nil
+  collectgarbage();
+  assert(collectgarbage("count") <= x+1)
+  -- udata without finalizer
+  x = collectgarbage("count")
+  collectgarbage("stop")
+  for i=1,1000 do newproxy(false) end
+  assert(collectgarbage("count") > x+10)
+  collectgarbage()
+  assert(collectgarbage("count") <= x+1)
+  -- udata with finalizer
+  x = collectgarbage("count")
+  collectgarbage()
+  collectgarbage("stop")
+  a = newproxy(true)
+  getmetatable(a).__gc = function () end
+  for i=1,1000 do newproxy(a) end
+  assert(collectgarbage("count") >= x+10)
+  collectgarbage()  -- this collection only calls TM, without freeing memory
+  assert(collectgarbage("count") >= x+10)
+  collectgarbage()  -- now frees memory
+  assert(collectgarbage("count") <= x+1)
+end
+
+
+collectgarbage("stop")
+
+-- create 3 userdatas with tag `tt'
+a = T.newuserdata(0); debug.setmetatable(a, tt); na = T.udataval(a)
+b = T.newuserdata(0); debug.setmetatable(b, tt); nb = T.udataval(b)
+c = T.newuserdata(0); debug.setmetatable(c, tt); nc = T.udataval(c)
+
+-- create userdata without meta table
+x = T.newuserdata(4)
+y = T.newuserdata(0)
+
+assert(debug.getmetatable(x) == nil and debug.getmetatable(y) == nil)
+
+d=T.ref(a);
+e=T.ref(b);
+f=T.ref(c);
+t = {T.getref(d), T.getref(e), T.getref(f)}
+assert(t[1] == a and t[2] == b and t[3] == c)
+
+t=nil; a=nil; c=nil;
+T.unref(e); T.unref(f)
+
+collectgarbage()
+
+-- check that unref objects have been collected
+assert(table.getn(cl) == 1 and cl[1] == nc)
+
+x = T.getref(d)
+assert(type(x) == 'userdata' and debug.getmetatable(x) == tt)
+x =nil
+tt.b = b  -- create cycle
+tt=nil    -- frees tt for GC
+A = nil
+b = nil
+T.unref(d);
+n5 = T.newuserdata(0)
+debug.setmetatable(n5, {__gc=F})
+n5 = T.udataval(n5)
+collectgarbage()
+assert(table.getn(cl) == 4)
+-- check order of collection
+assert(cl[2] == n5 and cl[3] == nb and cl[4] == na)
+
+
+a, na = {}, {}
+for i=30,1,-1 do
+  a[i] = T.newuserdata(0)
+  debug.setmetatable(a[i], {__gc=F})
+  na[i] = T.udataval(a[i])
+end
+cl = {}
+a = nil; collectgarbage()
+assert(table.getn(cl) == 30)
+for i=1,30 do assert(cl[i] == na[i]) end
+na = nil
+
+
+for i=2,Lim,2 do   -- unlock the other half
+  T.unref(Arr[i])
+end
+
+x = T.newuserdata(41); debug.setmetatable(x, {__gc=F})
+assert(T.testC("objsize 2; return 1", x) == 41)
+cl = {}
+a = {[x] = 1}
+x = T.udataval(x)
+collectgarbage()
+-- old `x' cannot be collected (`a' still uses it)
+assert(table.getn(cl) == 0)
+for n in pairs(a) do a[n] = nil end
+collectgarbage()
+assert(table.getn(cl) == 1 and cl[1] == x)   -- old `x' must be collected
+
+-- testing lua_equal
+assert(T.testC("equal 2 4; return 1", print, 1, print, 20))
+assert(T.testC("equal 3 2; return 1", 'alo', "alo"))
+assert(T.testC("equal 2 3; return 1", nil, nil))
+assert(not T.testC("equal 2 3; return 1", {}, {}))
+assert(not T.testC("equal 2 3; return 1"))
+assert(not T.testC("equal 2 3; return 1", 3))
+
+-- testing lua_equal with fallbacks
+do
+  local map = {}
+  local t = {__eq = function (a,b) return map[a] == map[b] end}
+  local function f(x)
+    local u = T.newuserdata(0)
+    debug.setmetatable(u, t)
+    map[u] = x
+    return u
+  end
+  assert(f(10) == f(10))
+  assert(f(10) ~= f(11))
+  assert(T.testC("equal 2 3; return 1", f(10), f(10)))
+  assert(not T.testC("equal 2 3; return 1", f(10), f(20)))
+  t.__eq = nil
+  assert(f(10) ~= f(10))
+end
+
+print'+'
+
+
+
+-------------------------------------------------------------------------
+do   -- testing errors during GC
+  local a = {}
+  for i=1,20 do
+    a[i] = T.newuserdata(i)   -- creates several udata
+  end
+  for i=1,20,2 do   -- mark half of them to raise error during GC
+    debug.setmetatable(a[i], {__gc = function (x) error("error inside gc") end})
+  end
+  for i=2,20,2 do   -- mark the other half to count and to create more garbage
+    debug.setmetatable(a[i], {__gc = function (x) loadstring("A=A+1")() end})
+  end
+  _G.A = 0
+  a = 0
+  while 1 do
+  if xpcall(collectgarbage, function (s) a=a+1 end) then
+    break   -- stop if no more errors
+  end
+  end
+  assert(a == 10)  -- number of errors
+  assert(A == 10)  -- number of normal collections
+end
+-------------------------------------------------------------------------
+-- test for userdata vals
+do
+  local a = {}; local lim = 30
+  for i=0,lim do a[i] = T.pushuserdata(i) end
+  for i=0,lim do assert(T.udataval(a[i]) == i) end
+  for i=0,lim do assert(T.pushuserdata(i) == a[i]) end
+  for i=0,lim do a[a[i]] = i end
+  for i=0,lim do a[T.pushuserdata(i)] = i end
+  assert(type(tostring(a[1])) == "string")
+end
+
+
+-------------------------------------------------------------------------
+-- testing multiple states
+T.closestate(T.newstate());
+L1 = T.newstate()
+assert(L1)
+assert(pack(T.doremote(L1, "function f () return 'alo', 3 end; f()")).n == 0)
+
+a, b = T.doremote(L1, "return f()")
+assert(a == 'alo' and b == '3')
+
+T.doremote(L1, "_ERRORMESSAGE = nil")
+-- error: `sin' is not defined
+a, b = T.doremote(L1, "return sin(1)")
+assert(a == nil and b == 2)   -- 2 == run-time error
+
+-- error: syntax error
+a, b, c = T.doremote(L1, "return a+")
+assert(a == nil and b == 3 and type(c) == "string")   -- 3 == syntax error
+
+T.loadlib(L1)
+a, b = T.doremote(L1, [[
+  a = strlibopen()
+  a = packageopen()
+  a = baselibopen(); assert(a == _G and require("_G") == a)
+  a = iolibopen(); assert(type(a.read) == "function")
+  assert(require("io") == a)
+  a = tablibopen(); assert(type(a.insert) == "function")
+  a = dblibopen(); assert(type(a.getlocal) == "function")
+  a = mathlibopen(); assert(type(a.sin) == "function")
+  return string.sub('okinama', 1, 2)
+]])
+assert(a == "ok")
+
+T.closestate(L1);
+
+L1 = T.newstate()
+T.loadlib(L1)
+T.doremote(L1, "a = {}")
+T.testC(L1, [[pushstring a; gettable G; pushstring x; pushnum 1;
+             settable -3]])
+assert(T.doremote(L1, "return a.x") == "1")
+
+T.closestate(L1)
+
+L1 = nil
+
+print('+')
+
+-------------------------------------------------------------------------
+-- testing memory limits
+-------------------------------------------------------------------------
+collectgarbage()
+T.totalmem(T.totalmem()+5000)   -- set low memory limit (+5k)
+assert(not pcall(loadstring"local a={}; for i=1,100000 do a[i]=i end"))
+T.totalmem(1000000000)          -- restore high limit
+
+
+local function stack(x) if x>0 then stack(x-1) end end
+
+-- test memory errors; increase memory limit in small steps, so that
+-- we get memory errors in different parts of a given task, up to there
+-- is enough memory to complete the task without errors
+function testamem (s, f)
+  collectgarbage()
+  stack(10)    -- ensure minimum stack size
+  local M = T.totalmem()
+  local oldM = M
+  local a,b = nil
+  while 1 do
+    M = M+3   -- increase memory limit in small steps
+    T.totalmem(M)
+    a, b = pcall(f)
+    if a and b then break end       -- stop when no more errors
+    collectgarbage()
+    if not a and not string.find(b, "memory") then   -- `real' error?
+      T.totalmem(1000000000)  -- restore high limit
+      error(b, 0)
+    end
+  end
+  T.totalmem(1000000000)  -- restore high limit
+  print("\nlimit for " .. s .. ": " .. M-oldM)
+  return b
+end
+
+
+-- testing memory errors when creating a new state
+
+b = testamem("state creation", T.newstate)
+T.closestate(b);  -- close new state
+
+
+-- testing threads
+
+function expand (n,s)
+  if n==0 then return "" end
+  local e = string.rep("=", n)
+  return string.format("T.doonnewstack([%s[ %s;\n collectgarbage(); %s]%s])\n",
+                              e, s, expand(n-1,s), e)
+end
+
+G=0; collectgarbage(); a =collectgarbage("count")
+loadstring(expand(20,"G=G+1"))()
+assert(G==20); collectgarbage();  -- assert(gcinfo() <= a+1)
+
+testamem("thread creation", function ()
+  return T.doonnewstack("x=1") == 0  -- try to create thread
+end)
+
+
+-- testing memory x compiler
+
+testamem("loadstring", function ()
+  return loadstring("x=1")  -- try to do a loadstring
+end)
+
+
+local testprog = [[
+local function foo () return end
+local t = {"x"}
+a = "aaa"
+for _, v in ipairs(t) do a=a..v end
+return true
+]]
+
+-- testing memory x dofile
+_G.a = nil
+local t =os.tmpname()
+local f = assert(io.open(t, "w"))
+f:write(testprog)
+f:close()
+testamem("dofile", function ()
+  local a = loadfile(t)
+  return a and a()
+end)
+assert(os.remove(t))
+assert(_G.a == "aaax")
+
+
+-- other generic tests
+
+testamem("string creation", function ()
+  local a, b = string.gsub("alo alo", "(a)", function (x) return x..'b' end)
+  return (a == 'ablo ablo')
+end)
+
+testamem("dump/undump", function ()
+  local a = loadstring(testprog)
+  local b = a and string.dump(a)
+  a = b and loadstring(b)
+  return a and a()
+end)
+
+local t = os.tmpname()
+testamem("file creation", function ()
+  local f = assert(io.open(t, 'w'))
+  assert (not io.open"nomenaoexistente")
+  io.close(f);
+  return not loadfile'nomenaoexistente'
+end)
+assert(os.remove(t))
+
+testamem("table creation", function ()
+  local a, lim = {}, 10
+  for i=1,lim do a[i] = i; a[i..'a'] = {} end
+  return (type(a[lim..'a']) == 'table' and a[lim] == lim)
+end)
+
+local a = 1
+close = nil
+testamem("closure creation", function ()
+  function close (b,c)
+   return function (x) return a+b+c+x end
+  end
+  return (close(2,3)(4) == 10)
+end)
+
+testamem("coroutines", function ()
+  local a = coroutine.wrap(function ()
+              coroutine.yield(string.rep("a", 10))
+              return {}
+            end)
+  assert(string.len(a()) == 10)
+  return a()
+end)
+
+print'+'
+
+-- testing some auxlib functions
+assert(T.gsub("alo.alo.uhuh.", ".", "//") == "alo//alo//uhuh//")
+assert(T.gsub("alo.alo.uhuh.", "alo", "//") == "//.//.uhuh.")
+assert(T.gsub("", "alo", "//") == "")
+assert(T.gsub("...", ".", "/.") == "/././.")
+assert(T.gsub("...", "...", "") == "")
+
+
+print'OK'
+
diff --git a/test/PUC-Lua-5.1-tests/attrib.lua b/test/PUC-Lua-5.1-tests/attrib.lua
new file mode 100644
index 0000000..655669b
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/attrib.lua
@@ -0,0 +1,339 @@
+do --[
+
+print "testing require"
+
+assert(require"string" == string)
+assert(require"math" == math)
+assert(require"table" == table)
+assert(require"io" == io)
+assert(require"os" == os)
+assert(require"debug" == debug)
+assert(require"coroutine" == coroutine)
+
+assert(type(package.path) == "string")
+assert(type(package.cpath) == "string")
+assert(type(package.loaded) == "table")
+assert(type(package.preload) == "table")
+
+
+local DIR = "libs/"
+
+local function createfiles (files, preextras, posextras)
+  for n,c in pairs(files) do
+    io.output(DIR..n)
+    io.write(string.format(preextras, n))
+    io.write(c)
+    io.write(string.format(posextras, n))
+    io.close(io.output())
+  end
+end
+
+function removefiles (files)
+  for n in pairs(files) do
+    os.remove(DIR..n)
+  end
+end
+
+local files = {
+  ["A.lua"] = "",
+  ["B.lua"] = "assert(...=='B');require 'A'",
+  ["A.lc"] = "",
+  ["A"] = "",
+  ["L"] = "",
+  ["XXxX"] = "",
+  ["C.lua"] = "package.loaded[...] = 25; require'C'"
+}
+
+AA = nil
+local extras = [[
+NAME = '%s'
+REQUIRED = ...
+return AA]]
+
+createfiles(files, "", extras)
+
+
+local oldpath = package.path
+
+package.path = string.gsub("D/?.lua;D/?.lc;D/?;D/??x?;D/L", "D/", DIR)
+
+local try = function (p, n, r)
+  NAME = nil
+  local rr = require(p)
+  assert(NAME == n)
+  assert(REQUIRED == p)
+  assert(rr == r)
+end
+
+assert(require"C" == 25)
+assert(require"C" == 25)
+AA = nil
+try('B', 'B.lua', true)
+assert(package.loaded.B)
+assert(require"B" == true)
+assert(package.loaded.A)
+package.loaded.A = nil
+try('B', nil, true)   -- should not reload package
+try('A', 'A.lua', true)
+package.loaded.A = nil
+os.remove(DIR..'A.lua')
+AA = {}
+try('A', 'A.lc', AA)  -- now must find second option
+assert(require("A") == AA)
+AA = false
+try('K', 'L', false)     -- default option
+try('K', 'L', false)     -- default option (should reload it)
+assert(rawget(_G, "_REQUIREDNAME") == nil)
+
+AA = "x"
+try("X", "XXxX", AA)
+
+
+removefiles(files)
+
+
+-- testing require of sub-packages
+
+package.path = string.gsub("D/?.lua;D/?/init.lua", "D/", DIR)
+
+files = {
+  ["P1/init.lua"] = "AA = 10",
+  ["P1/xuxu.lua"] = "AA = 20",
+}
+
+createfiles(files, "module(..., package.seeall)\n", "")
+AA = 0
+
+local m = assert(require"P1")
+assert(m == P1 and m._NAME == "P1" and AA == 0 and m.AA == 10)
+assert(require"P1" == P1 and P1 == m)
+assert(require"P1" == P1)
+assert(P1._PACKAGE == "")
+
+local m = assert(require"P1.xuxu")
+assert(m == P1.xuxu and m._NAME == "P1.xuxu" and AA == 0 and m.AA == 20)
+assert(require"P1.xuxu" == P1.xuxu and P1.xuxu == m)
+assert(require"P1.xuxu" == P1.xuxu)
+assert(require"P1" == P1)
+assert(P1.xuxu._PACKAGE == "P1.")
+assert(P1.AA == 10 and P1._PACKAGE == "")
+assert(P1._G == _G and P1.xuxu._G == _G)
+
+
+
+removefiles(files)
+
+
+package.path = ""
+assert(not pcall(require, "file_does_not_exist"))
+package.path = "??\0?"
+assert(not pcall(require, "file_does_not_exist1"))
+
+package.path = oldpath
+
+-- check 'require' error message
+local fname = "file_does_not_exist2"
+local m, err = pcall(require, fname)
+for t in string.gmatch(package.path..";"..package.cpath, "[^;]+") do
+  t = string.gsub(t, "?", fname)
+  assert(string.find(err, t, 1, true))
+end
+
+
+local function import(...)
+  local f = {...}
+  return function (m)
+    for i=1, #f do m[f[i]] = _G[f[i]] end
+  end
+end
+
+local assert, module, package = assert, module, package
+X = nil; x = 0; assert(_G.x == 0)   -- `x' must be a global variable
+module"X"; x = 1; assert(_M.x == 1)
+module"X.a.b.c"; x = 2; assert(_M.x == 2)
+module("X.a.b", package.seeall); x = 3
+assert(X._NAME == "X" and X.a.b.c._NAME == "X.a.b.c" and X.a.b._NAME == "X.a.b")
+assert(X._M == X and X.a.b.c._M == X.a.b.c and X.a.b._M == X.a.b)
+assert(X.x == 1 and X.a.b.c.x == 2 and X.a.b.x == 3)
+assert(X._PACKAGE == "" and X.a.b.c._PACKAGE == "X.a.b." and
+       X.a.b._PACKAGE == "X.a.")
+assert(_PACKAGE.."c" == "X.a.c")
+assert(X.a._NAME == nil and X.a._M == nil)
+module("X.a", import("X")) ; x = 4
+assert(X.a._NAME == "X.a" and X.a.x == 4 and X.a._M == X.a)
+module("X.a.b", package.seeall); assert(x == 3); x = 5
+assert(_NAME == "X.a.b" and X.a.b.x == 5)
+
+assert(X._G == nil and X.a._G == nil and X.a.b._G == _G and X.a.b.c._G == nil)
+
+setfenv(1, _G)
+assert(x == 0)
+
+assert(not pcall(module, "x"))
+assert(not pcall(module, "math.sin"))
+
+
+-- testing C libraries
+
+
+local p = ""   -- On Mac OS X, redefine this to "_"
+
+-- assert(loadlib == package.loadlib)   -- only for compatibility
+local f, err, when = package.loadlib("libs/lib1.so", p.."luaopen_lib1")
+if not f then
+  (Message or print)('\a\n >>> cannot load dynamic library <<<\n\a')
+  print(err, when)
+else
+  f()   -- open library
+  assert(require("lib1") == lib1)
+  collectgarbage()
+  assert(lib1.id("x") == "x")
+  f = assert(package.loadlib("libs/lib1.so", p.."anotherfunc"))
+  assert(f(10, 20) == "1020\n")
+  f, err, when = package.loadlib("libs/lib1.so", p.."xuxu")
+  assert(not f and type(err) == "string" and when == "init")
+  package.cpath = "libs/?.so"
+  require"lib2"
+  assert(lib2.id("x") == "x")
+  local fs = require"lib1.sub"
+  assert(fs == lib1.sub and next(lib1.sub) == nil)
+  module("lib2", package.seeall)
+  f = require"-lib2"
+  assert(f.id("x") == "x" and _M == f and _NAME == "lib2")
+  module("lib1.sub", package.seeall)
+  assert(_M == fs)
+  setfenv(1, _G)
+
+end
+f, err, when = package.loadlib("donotexist", p.."xuxu")
+assert(not f and type(err) == "string" and (when == "open" or when == "absent"))
+
+
+-- testing preload
+
+do
+  local p = package
+  package = {}
+  p.preload.pl = function (...)
+    module(...)
+    function xuxu (x) return x+20 end
+  end
+
+  require"pl"
+  assert(require"pl" == pl)
+  assert(pl.xuxu(10) == 30)
+
+  package = p
+  assert(type(package.path) == "string")
+end
+
+
+
+end  --]
+
+print('+')
+
+print("testing assignments, logical operators, and constructors")
+
+local res, res2 = 27
+
+a, b = 1, 2+3
+assert(a==1 and b==5)
+a={}
+function f() return 10, 11, 12 end
+a.x, b, a[1] = 1, 2, f()
+assert(a.x==1 and b==2 and a[1]==10)
+a[f()], b, a[f()+3] = f(), a, 'x'
+assert(a[10] == 10 and b == a and a[13] == 'x')
+
+do
+  local f = function (n) local x = {}; for i=1,n do x[i]=i end;
+                         return unpack(x) end;
+  local a,b,c
+  a,b = 0, f(1)
+  assert(a == 0 and b == 1)
+  A,b = 0, f(1)
+  assert(A == 0 and b == 1)
+  a,b,c = 0,5,f(4)
+  assert(a==0 and b==5 and c==1)
+  a,b,c = 0,5,f(0)
+  assert(a==0 and b==5 and c==nil)
+end
+
+
+a, b, c, d = 1 and nil, 1 or nil, (1 and (nil or 1)), 6
+assert(not a and b and c and d==6)
+
+d = 20
+a, b, c, d = f()
+assert(a==10 and b==11 and c==12 and d==nil)
+a,b = f(), 1, 2, 3, f()
+assert(a==10 and b==1)
+
+assert(a<b == false and a>b == true)
+assert((10 and 2) == 2)
+assert((10 or 2) == 10)
+assert((10 or assert(nil)) == 10)
+assert(not (nil and assert(nil)))
+assert((nil or "alo") == "alo")
+assert((nil and 10) == nil)
+assert((false and 10) == false)
+assert((true or 10) == true)
+assert((false or 10) == 10)
+assert(false ~= nil)
+assert(nil ~= false)
+assert(not nil == true)
+assert(not not nil == false)
+assert(not not 1 == true)
+assert(not not a == true)
+assert(not not (6 or nil) == true)
+assert(not not (nil and 56) == false)
+assert(not not (nil and true) == false)
+print('+')
+
+a = {}
+a[true] = 20
+a[false] = 10
+assert(a[1<2] == 20 and a[1>2] == 10)
+
+function f(a) return a end
+
+local a = {}
+for i=3000,-3000,-1 do a[i] = i; end
+a[10e30] = "alo"; a[true] = 10; a[false] = 20
+assert(a[10e30] == 'alo' and a[not 1] == 20 and a[10<20] == 10)
+for i=3000,-3000,-1 do assert(a[i] == i); end
+a[print] = assert
+a[f] = print
+a[a] = a
+assert(a[a][a][a][a][print] == assert)
+a[print](a[a[f]] == a[print])
+a = nil
+
+a = {10,9,8,7,6,5,4,3,2; [-3]='a', [f]=print, a='a', b='ab'}
+a, a.x, a.y = a, a[-3]
+assert(a[1]==10 and a[-3]==a.a and a[f]==print and a.x=='a' and not a.y)
+a[1], f(a)[2], b, c = {['alo']=assert}, 10, a[1], a[f], 6, 10, 23, f(a), 2
+a[1].alo(a[2]==10 and b==10 and c==print)
+
+a[2^31] = 10; a[2^31+1] = 11; a[-2^31] = 12;
+a[2^32] = 13; a[-2^32] = 14; a[2^32+1] = 15; a[10^33] = 16;
+
+assert(a[2^31] == 10 and a[2^31+1] == 11 and a[-2^31] == 12 and
+       a[2^32] == 13 and a[-2^32] == 14 and a[2^32+1] == 15 and
+       a[10^33] == 16)
+
+a = nil
+
+
+do
+  local a,i,j,b
+  a = {'a', 'b'}; i=1; j=2; b=a
+  i, a[i], a, j, a[j], a[i+j] = j, i, i, b, j, i
+  assert(i == 2 and b[1] == 1 and a == 1 and j == b and b[2] == 2 and
+         b[3] == 1)
+end
+
+print('OK')
+
+return res
diff --git a/test/PUC-Lua-5.1-tests/big.lua b/test/PUC-Lua-5.1-tests/big.lua
new file mode 100644
index 0000000..9261288
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/big.lua
@@ -0,0 +1,381 @@
+print "testing string length overflow"
+
+local longs = string.rep("\0", 2^25)
+local function catter (i)
+  return assert(loadstring(
+    string.format("return function(a) return a%s end",
+                     string.rep("..a", i-1))))()
+end
+rep129 = catter(129)
+local a, b = pcall(rep129, longs)
+assert(not a and string.find(b, "overflow"))
+print('+')
+
+
+require "checktable"
+
+--[[ lots of empty lines (to force SETLINEW)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+--]]
+
+
+a,b = nil,nil
+while not b do
+if a then
+b = {  -- lots of strings (to force JMPW and PUSHCONSTANTW)
+"n1", "n2", "n3", "n4", "n5", "n6", "n7", "n8", "n9", "n10",
+"n11", "n12", "j301", "j302", "j303", "j304", "j305", "j306", "j307", "j308",
+"j309", "a310", "n311", "n312", "n313", "n314", "n315", "n316", "n317", "n318",
+"n319", "n320", "n321", "n322", "n323", "n324", "n325", "n326", "n327", "n328",
+"a329", "n330", "n331", "n332", "n333", "n334", "n335", "n336", "n337", "n338",
+"n339", "n340", "n341", "z342", "n343", "n344", "n345", "n346", "n347", "n348",
+"n349", "n350", "n351", "n352", "r353", "n354", "n355", "n356", "n357", "n358",
+"n359", "n360", "n361", "n362", "n363", "n364", "n365", "n366", "z367", "n368",
+"n369", "n370", "n371", "n372", "n373", "n374", "n375", "a376", "n377", "n378",
+"n379", "n380", "n381", "n382", "n383", "n384", "n385", "n386", "n387", "n388",
+"n389", "n390", "n391", "n392", "n393", "n394", "n395", "n396", "n397", "n398",
+"n399", "n400", "n13", "n14", "n15", "n16", "n17", "n18", "n19", "n20",
+"n21", "n22", "n23", "a24", "n25", "n26", "n27", "n28", "n29", "j30",
+"n31", "n32", "n33", "n34", "n35", "n36", "n37", "n38", "n39", "n40",
+"n41", "n42", "n43", "n44", "n45", "n46", "n47", "n48", "n49", "n50",
+"n51", "n52", "n53", "n54", "n55", "n56", "n57", "n58", "n59", "n60",
+"n61", "n62", "n63", "n64", "n65", "a66", "z67", "n68", "n69", "n70",
+"n71", "n72", "n73", "n74", "n75", "n76", "n77", "n78", "n79", "n80",
+"n81", "n82", "n83", "n84", "n85", "n86", "n87", "n88", "n89", "n90",
+"n91", "n92", "n93", "n94", "n95", "n96", "n97", "n98", "n99", "n100",
+"n201", "n202", "n203", "n204", "n205", "n206", "n207", "n208", "n209", "n210",
+"n211", "n212", "n213", "n214", "n215", "n216", "n217", "n218", "n219", "n220",
+"n221", "n222", "n223", "n224", "n225", "n226", "n227", "n228", "n229", "n230",
+"n231", "n232", "n233", "n234", "n235", "n236", "n237", "n238", "n239", "a240",
+"a241", "a242", "a243", "a244", "a245", "a246", "a247", "a248", "a249", "n250",
+"n251", "n252", "n253", "n254", "n255", "n256", "n257", "n258", "n259", "n260",
+"n261", "n262", "n263", "n264", "n265", "n266", "n267", "n268", "n269", "n270",
+"n271", "n272", "n273", "n274", "n275", "n276", "n277", "n278", "n279", "n280",
+"n281", "n282", "n283", "n284", "n285", "n286", "n287", "n288", "n289", "n290",
+"n291", "n292", "n293", "n294", "n295", "n296", "n297", "n298", "n299"
+; x=23}
+else a = 1 end
+
+
+end
+
+assert(b.x == 23)
+print('+')
+
+stat(b)
+
+repeat
+a = {
+n1 = 1.5, n2 = 2.5, n3 = 3.5, n4 = 4.5, n5 = 5.5, n6 = 6.5, n7 = 7.5,
+n8 = 8.5, n9 = 9.5, n10 = 10.5, n11 = 11.5, n12 = 12.5,
+j301 = 301.5, j302 = 302.5, j303 = 303.5, j304 = 304.5, j305 = 305.5,
+j306 = 306.5, j307 = 307.5, j308 = 308.5, j309 = 309.5, a310 = 310.5,
+n311 = 311.5, n312 = 312.5, n313 = 313.5, n314 = 314.5, n315 = 315.5,
+n316 = 316.5, n317 = 317.5, n318 = 318.5, n319 = 319.5, n320 = 320.5,
+n321 = 321.5, n322 = 322.5, n323 = 323.5, n324 = 324.5, n325 = 325.5,
+n326 = 326.5, n327 = 327.5, n328 = 328.5, a329 = 329.5, n330 = 330.5,
+n331 = 331.5, n332 = 332.5, n333 = 333.5, n334 = 334.5, n335 = 335.5,
+n336 = 336.5, n337 = 337.5, n338 = 338.5, n339 = 339.5, n340 = 340.5,
+n341 = 341.5, z342 = 342.5, n343 = 343.5, n344 = 344.5, n345 = 345.5,
+n346 = 346.5, n347 = 347.5, n348 = 348.5, n349 = 349.5, n350 = 350.5,
+n351 = 351.5, n352 = 352.5, r353 = 353.5, n354 = 354.5, n355 = 355.5,
+n356 = 356.5, n357 = 357.5, n358 = 358.5, n359 = 359.5, n360 = 360.5,
+n361 = 361.5, n362 = 362.5, n363 = 363.5, n364 = 364.5, n365 = 365.5,
+n366 = 366.5, z367 = 367.5, n368 = 368.5, n369 = 369.5, n370 = 370.5,
+n371 = 371.5, n372 = 372.5, n373 = 373.5, n374 = 374.5, n375 = 375.5,
+a376 = 376.5, n377 = 377.5, n378 = 378.5, n379 = 379.5, n380 = 380.5,
+n381 = 381.5, n382 = 382.5, n383 = 383.5, n384 = 384.5, n385 = 385.5,
+n386 = 386.5, n387 = 387.5, n388 = 388.5, n389 = 389.5, n390 = 390.5,
+n391 = 391.5, n392 = 392.5, n393 = 393.5, n394 = 394.5, n395 = 395.5,
+n396 = 396.5, n397 = 397.5, n398 = 398.5, n399 = 399.5, n400 = 400.5,
+n13 = 13.5, n14 = 14.5, n15 = 15.5, n16 = 16.5, n17 = 17.5,
+n18 = 18.5, n19 = 19.5, n20 = 20.5, n21 = 21.5, n22 = 22.5,
+n23 = 23.5, a24 = 24.5, n25 = 25.5, n26 = 26.5, n27 = 27.5,
+n28 = 28.5, n29 = 29.5, j30 = 30.5, n31 = 31.5, n32 = 32.5,
+n33 = 33.5, n34 = 34.5, n35 = 35.5, n36 = 36.5, n37 = 37.5,
+n38 = 38.5, n39 = 39.5, n40 = 40.5, n41 = 41.5, n42 = 42.5,
+n43 = 43.5, n44 = 44.5, n45 = 45.5, n46 = 46.5, n47 = 47.5,
+n48 = 48.5, n49 = 49.5, n50 = 50.5, n51 = 51.5, n52 = 52.5,
+n53 = 53.5, n54 = 54.5, n55 = 55.5, n56 = 56.5, n57 = 57.5,
+n58 = 58.5, n59 = 59.5, n60 = 60.5, n61 = 61.5, n62 = 62.5,
+n63 = 63.5, n64 = 64.5, n65 = 65.5, a66 = 66.5, z67 = 67.5,
+n68 = 68.5, n69 = 69.5, n70 = 70.5, n71 = 71.5, n72 = 72.5,
+n73 = 73.5, n74 = 74.5, n75 = 75.5, n76 = 76.5, n77 = 77.5,
+n78 = 78.5, n79 = 79.5, n80 = 80.5, n81 = 81.5, n82 = 82.5,
+n83 = 83.5, n84 = 84.5, n85 = 85.5, n86 = 86.5, n87 = 87.5,
+n88 = 88.5, n89 = 89.5, n90 = 90.5, n91 = 91.5, n92 = 92.5,
+n93 = 93.5, n94 = 94.5, n95 = 95.5, n96 = 96.5, n97 = 97.5,
+n98 = 98.5, n99 = 99.5, n100 = 100.5, n201 = 201.5, n202 = 202.5,
+n203 = 203.5, n204 = 204.5, n205 = 205.5, n206 = 206.5, n207 = 207.5,
+n208 = 208.5, n209 = 209.5, n210 = 210.5, n211 = 211.5, n212 = 212.5,
+n213 = 213.5, n214 = 214.5, n215 = 215.5, n216 = 216.5, n217 = 217.5,
+n218 = 218.5, n219 = 219.5, n220 = 220.5, n221 = 221.5, n222 = 222.5,
+n223 = 223.5, n224 = 224.5, n225 = 225.5, n226 = 226.5, n227 = 227.5,
+n228 = 228.5, n229 = 229.5, n230 = 230.5, n231 = 231.5, n232 = 232.5,
+n233 = 233.5, n234 = 234.5, n235 = 235.5, n236 = 236.5, n237 = 237.5,
+n238 = 238.5, n239 = 239.5, a240 = 240.5, a241 = 241.5, a242 = 242.5,
+a243 = 243.5, a244 = 244.5, a245 = 245.5, a246 = 246.5, a247 = 247.5,
+a248 = 248.5, a249 = 249.5, n250 = 250.5, n251 = 251.5, n252 = 252.5,
+n253 = 253.5, n254 = 254.5, n255 = 255.5, n256 = 256.5, n257 = 257.5,
+n258 = 258.5, n259 = 259.5, n260 = 260.5, n261 = 261.5, n262 = 262.5,
+n263 = 263.5, n264 = 264.5, n265 = 265.5, n266 = 266.5, n267 = 267.5,
+n268 = 268.5, n269 = 269.5, n270 = 270.5, n271 = 271.5, n272 = 272.5,
+n273 = 273.5, n274 = 274.5, n275 = 275.5, n276 = 276.5, n277 = 277.5,
+n278 = 278.5, n279 = 279.5, n280 = 280.5, n281 = 281.5, n282 = 282.5,
+n283 = 283.5, n284 = 284.5, n285 = 285.5, n286 = 286.5, n287 = 287.5,
+n288 = 288.5, n289 = 289.5, n290 = 290.5, n291 = 291.5, n292 = 292.5,
+n293 = 293.5, n294 = 294.5, n295 = 295.5, n296 = 296.5, n297 = 297.5,
+n298 = 298.5, n299 = 299.5, j300 = 300} or 1
+until 1
+
+assert(a.n299 == 299.5)
+xxx = 1
+assert(xxx == 1)
+
+stat(a)
+
+function a:findfield (f)
+  local i,v = next(self, nil)
+  while i ~= f do
+    if not i then return end
+    i,v = next(self, i)
+  end
+  return v
+end
+
+local ii = 0
+i = 1
+while b[i] do
+  local r = a:findfield(b[i]);
+  assert(a[b[i]] == r)
+  ii = math.max(ii,i)
+  i = i+1
+end
+
+assert(ii == 299)
+
+function xxxx (x) coroutine.yield('b'); return ii+x end
+
+assert(xxxx(10) == 309)
+
+a = nil
+b = nil
+a1 = nil
+
+print("tables with table indices:")
+i = 1; a={}
+while i <= 1023 do a[{}] = i; i=i+1 end
+stat(a)
+a = nil
+
+print("tables with function indices:")
+a={}
+for i=1,511 do local x; a[function () return x end] = i end
+stat(a)
+a = nil
+
+print'OK'
+
+return 'a'
diff --git a/test/PUC-Lua-5.1-tests/calls.lua b/test/PUC-Lua-5.1-tests/calls.lua
new file mode 100644
index 0000000..788f9a1
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/calls.lua
@@ -0,0 +1,294 @@
+print("testing functions and calls")
+
+-- get the opportunity to test 'type' too ;)
+
+assert(type(1<2) == 'boolean')
+assert(type(true) == 'boolean' and type(false) == 'boolean')
+assert(type(nil) == 'nil' and type(-3) == 'number' and type'x' == 'string' and
+       type{} == 'table' and type(type) == 'function')
+
+assert(type(assert) == type(print))
+f = nil
+function f (x) return a:x (x) end
+assert(type(f) == 'function')
+
+
+-- testing local-function recursion
+fact = false
+do
+  local res = 1
+  local function fact (n)
+    if n==0 then return res
+    else return n*fact(n-1)
+    end
+  end
+  assert(fact(5) == 120)
+end
+assert(fact == false)
+
+-- testing declarations
+a = {i = 10}
+self = 20
+function a:x (x) return x+self.i end
+function a.y (x) return x+self end
+
+assert(a:x(1)+10 == a.y(1))
+
+a.t = {i=-100}
+a["t"].x = function (self, a,b) return self.i+a+b end
+
+assert(a.t:x(2,3) == -95)
+
+do
+  local a = {x=0}
+  function a:add (x) self.x, a.y = self.x+x, 20; return self end
+  assert(a:add(10):add(20):add(30).x == 60 and a.y == 20)
+end
+
+local a = {b={c={}}}
+
+function a.b.c.f1 (x) return x+1 end
+function a.b.c:f2 (x,y) self[x] = y end
+assert(a.b.c.f1(4) == 5)
+a.b.c:f2('k', 12); assert(a.b.c.k == 12)
+
+print('+')
+
+t = nil   -- 'declare' t
+function f(a,b,c) local d = 'a'; t={a,b,c,d} end
+
+f(      -- this line change must be valid
+  1,2)
+assert(t[1] == 1 and t[2] == 2 and t[3] == nil and t[4] == 'a')
+f(1,2,   -- this one too
+      3,4)
+assert(t[1] == 1 and t[2] == 2 and t[3] == 3 and t[4] == 'a')
+
+function fat(x)
+  if x <= 1 then return 1
+  else return x*loadstring("return fat(" .. x-1 .. ")")()
+  end
+end
+
+assert(loadstring "loadstring 'assert(fat(6)==720)' () ")()
+a = loadstring('return fat(5), 3')
+a,b = a()
+assert(a == 120 and b == 3)
+print('+')
+
+function err_on_n (n)
+  if n==0 then error(); exit(1);
+  else err_on_n (n-1); exit(1);
+  end
+end
+
+do
+  function dummy (n)
+    if n > 0 then
+      assert(not pcall(err_on_n, n))
+      dummy(n-1)
+    end
+  end
+end
+
+dummy(10)
+
+function deep (n)
+  if n>0 then deep(n-1) end
+end
+deep(10)
+deep(200)
+
+-- testing tail call
+function deep (n) if n>0 then return deep(n-1) else return 101 end end
+assert(deep(30000) == 101)
+a = {}
+function a:deep (n) if n>0 then return self:deep(n-1) else return 101 end end
+assert(a:deep(30000) == 101)
+
+print('+')
+
+
+a = nil
+(function (x) a=x end)(23)
+assert(a == 23 and (function (x) return x*2 end)(20) == 40)
+
+
+local x,y,z,a
+a = {}; lim = 2000
+for i=1, lim do a[i]=i end
+assert(select(lim, unpack(a)) == lim and select('#', unpack(a)) == lim)
+x = unpack(a)
+assert(x == 1)
+x = {unpack(a)}
+assert(table.getn(x) == lim and x[1] == 1 and x[lim] == lim)
+x = {unpack(a, lim-2)}
+assert(table.getn(x) == 3 and x[1] == lim-2 and x[3] == lim)
+x = {unpack(a, 10, 6)}
+assert(next(x) == nil)   -- no elements
+x = {unpack(a, 11, 10)}
+assert(next(x) == nil)   -- no elements
+x,y = unpack(a, 10, 10)
+assert(x == 10 and y == nil)
+x,y,z = unpack(a, 10, 11)
+assert(x == 10 and y == 11 and z == nil)
+a,x = unpack{1}
+assert(a==1 and x==nil)
+a,x = unpack({1,2}, 1, 1)
+assert(a==1 and x==nil)
+
+
+-- testing closures
+
+-- fixed-point operator
+Y = function (le)
+      local function a (f)
+        return le(function (x) return f(f)(x) end)
+      end
+      return a(a)
+    end
+
+
+-- non-recursive factorial
+
+F = function (f)
+      return function (n)
+               if n == 0 then return 1
+               else return n*f(n-1) end
+             end
+    end
+
+fat = Y(F)
+
+assert(fat(0) == 1 and fat(4) == 24 and Y(F)(5)==5*Y(F)(4))
+
+local function g (z)
+  local function f (a,b,c,d)
+    return function (x,y) return a+b+c+d+a+x+y+z end
+  end
+  return f(z,z+1,z+2,z+3)
+end
+
+f = g(10)
+assert(f(9, 16) == 10+11+12+13+10+9+16+10)
+
+Y, F, f = nil
+print('+')
+
+-- testing multiple returns
+
+function unlpack (t, i)
+  i = i or 1
+  if (i <= table.getn(t)) then
+    return t[i], unlpack(t, i+1)
+  end
+end
+
+function equaltab (t1, t2)
+  assert(table.getn(t1) == table.getn(t2))
+  for i,v1 in ipairs(t1) do
+    assert(v1 == t2[i])
+  end
+end
+
+local function pack (...)
+  local x = {...}
+  x.n = select('#', ...)
+  return x
+end
+
+function f() return 1,2,30,4 end
+function ret2 (a,b) return a,b end
+
+local a,b,c,d = unlpack{1,2,3}
+assert(a==1 and b==2 and c==3 and d==nil)
+a = {1,2,3,4,false,10,'alo',false,assert}
+equaltab(pack(unlpack(a)), a)
+equaltab(pack(unlpack(a), -1), {1,-1})
+a,b,c,d = ret2(f()), ret2(f())
+assert(a==1 and b==1 and c==2 and d==nil)
+a,b,c,d = unlpack(pack(ret2(f()), ret2(f())))
+assert(a==1 and b==1 and c==2 and d==nil)
+a,b,c,d = unlpack(pack(ret2(f()), (ret2(f()))))
+assert(a==1 and b==1 and c==nil and d==nil)
+
+a = ret2{ unlpack{1,2,3}, unlpack{3,2,1}, unlpack{"a", "b"}}
+assert(a[1] == 1 and a[2] == 3 and a[3] == "a" and a[4] == "b")
+
+
+-- testing calls with 'incorrect' arguments
+rawget({}, "x", 1)
+rawset({}, "x", 1, 2)
+assert(math.sin(1,2) == math.sin(1))
+table.sort({10,9,8,4,19,23,0,0}, function (a,b) return a<b end, "extra arg")
+
+
+-- test for generic load
+x = "-- a comment\0\0\0\n  x = 10 + \n23; \
+     local a = function () x = 'hi' end; \
+     return '\0'"
+local i = 0
+function read1 (x)
+  return function ()
+    collectgarbage()
+    i=i+1
+    return string.sub(x, i, i)
+  end
+end
+
+a = assert(load(read1(x), "modname"))
+assert(a() == "\0" and _G.x == 33)
+assert(debug.getinfo(a).source == "modname")
+
+x = string.dump(loadstring("x = 1; return x"))
+i = 0
+a = assert(load(read1(x)))
+assert(a() == 1 and _G.x == 1)
+
+i = 0
+local a, b = load(read1("*a = 123"))
+assert(not a and type(b) == "string" and i == 2)
+
+a, b = load(function () error("hhi") end)
+assert(not a and string.find(b, "hhi"))
+
+-- test generic load with nested functions
+x = [[
+  return function (x)
+    return function (y)
+     return function (z)
+       return x+y+z
+     end
+   end
+  end
+]]
+
+a = assert(load(read1(x)))
+assert(a()(2)(3)(10) == 15)
+
+
+-- test for dump/undump with upvalues
+local a, b = 20, 30
+x = loadstring(string.dump(function (x)
+  if x == "set" then a = 10+b; b = b+1 else
+  return a
+  end
+end))
+assert(x() == nil)
+assert(debug.setupvalue(x, 1, "hi") == "a")
+assert(x() == "hi")
+assert(debug.setupvalue(x, 2, 13) == "b")
+assert(not debug.setupvalue(x, 3, 10))   -- only 2 upvalues
+x("set")
+assert(x() == 23)
+x("set")
+assert(x() == 24)
+
+
+-- test for bug in parameter adjustment
+assert((function () return nil end)(4) == nil)
+assert((function () local a; return a end)(4) == nil)
+assert((function (a) return a end)() == nil)
+
+print('OK')
+return deep
diff --git a/test/PUC-Lua-5.1-tests/checktable.lua b/test/PUC-Lua-5.1-tests/checktable.lua
new file mode 100644
index 0000000..f0938be
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/checktable.lua
@@ -0,0 +1,77 @@
+
+assert(rawget(_G, "stat") == nil)  -- module not loaded before
+
+if T == nil then
+  stat = function () print"`querytab' nao ativo" end
+  return
+end
+
+
+function checktable (t)
+  local asize, hsize, ff = T.querytab(t)
+  local l = {}
+  for i=0,hsize-1 do
+    local key,val,next = T.querytab(t, i + asize)
+    if key == nil then
+      assert(l[i] == nil and val==nil and next==nil)
+    elseif key == "<undef>" then
+      assert(val==nil)
+    else
+      assert(t[key] == val)
+      local mp = T.hash(key, t)
+      if l[i] then
+        assert(l[i] == mp)
+      elseif mp ~= i then
+        l[i] = mp
+      else  -- list head
+        l[mp] = {mp}   -- first element
+        while next do
+          assert(ff <= next and next < hsize)
+          if l[next] then assert(l[next] == mp) else l[next] = mp end
+          table.insert(l[mp], next)
+          key,val,next = T.querytab(t, next)
+          assert(key)
+        end
+      end
+    end
+  end
+  l.asize = asize; l.hsize = hsize; l.ff = ff
+  return l
+end
+
+function mostra (t)
+  local asize, hsize, ff = T.querytab(t)
+  print(asize, hsize, ff)
+  print'------'
+  for i=0,asize-1 do
+    local _, v = T.querytab(t, i)
+    print(string.format("[%d] -", i), v)
+  end
+  print'------'
+  for i=0,hsize-1 do
+    print(i, T.querytab(t, i+asize))
+  end
+  print'-------------'
+end
+
+function stat (t)
+  t = checktable(t)
+  local nelem, nlist = 0, 0
+  local maxlist = {}
+  for i=0,t.hsize-1 do
+    if type(t[i]) == 'table' then
+      local n = table.getn(t[i])
+      nlist = nlist+1
+      nelem = nelem + n
+      if not maxlist[n] then maxlist[n] = 0 end
+      maxlist[n] = maxlist[n]+1
+    end
+  end
+  print(string.format("hsize=%d  elements=%d  load=%.2f  med.len=%.2f (asize=%d)",
+          t.hsize, nelem, nelem/t.hsize, nelem/nlist, t.asize))
+  for i=1,table.getn(maxlist) do
+    local n = maxlist[i] or 0
+    print(string.format("%5d %10d %.2f%%", i, n, n*100/nlist))
+  end
+end
+
diff --git a/test/PUC-Lua-5.1-tests/closure.lua b/test/PUC-Lua-5.1-tests/closure.lua
new file mode 100644
index 0000000..27ca0ad
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/closure.lua
@@ -0,0 +1,422 @@
+print "testing closures and coroutines"
+
+local A,B = 0,{g=10}
+function f(x)
+  local a = {}
+  for i=1,1000 do
+    local y = 0
+    do
+      a[i] = function () B.g = B.g+1; y = y+x; return y+A end
+    end
+  end
+  local dummy = function () return a[A] end
+  collectgarbage()
+  A = 1; assert(dummy() == a[1]); A = 0;
+  assert(a[1]() == x)
+  assert(a[3]() == x)
+  collectgarbage()
+  assert(B.g == 12)
+  return a
+end
+
+a = f(10)
+-- force a GC in this level
+local x = {[1] = {}}   -- to detect a GC
+setmetatable(x, {__mode = 'kv'})
+while x[1] do   -- repeat until GC
+  local a = A..A..A..A  -- create garbage
+  A = A+1
+end
+assert(a[1]() == 20+A)
+assert(a[1]() == 30+A)
+assert(a[2]() == 10+A)
+collectgarbage()
+assert(a[2]() == 20+A)
+assert(a[2]() == 30+A)
+assert(a[3]() == 20+A)
+assert(a[8]() == 10+A)
+assert(getmetatable(x).__mode == 'kv')
+assert(B.g == 19)
+
+-- testing closures with 'for' control variable
+a = {}
+for i=1,10 do
+  a[i] = {set = function(x) i=x end, get = function () return i end}
+  if i == 3 then break end
+end
+assert(a[4] == nil)
+a[1].set(10)
+assert(a[2].get() == 2)
+a[2].set('a')
+assert(a[3].get() == 3)
+assert(a[2].get() == 'a')
+
+a = {}
+for i, k in pairs{'a', 'b'} do
+  a[i] = {set = function(x, y) i=x; k=y end,
+          get = function () return i, k end}
+  if i == 2 then break end
+end
+a[1].set(10, 20)
+local r,s = a[2].get()
+assert(r == 2 and s == 'b')
+r,s = a[1].get()
+assert(r == 10 and s == 20)
+a[2].set('a', 'b')
+r,s = a[2].get()
+assert(r == "a" and s == "b")
+
+
+-- testing closures with 'for' control variable x break
+for i=1,3 do
+  f = function () return i end
+  break
+end
+assert(f() == 1)
+
+for k, v in pairs{"a", "b"} do
+  f = function () return k, v end
+  break
+end
+assert(({f()})[1] == 1)
+assert(({f()})[2] == "a")
+
+
+-- testing closure x break x return x errors
+
+local b
+function f(x)
+  local first = 1
+  while 1 do
+    if x == 3 and not first then return end
+    local a = 'xuxu'
+    b = function (op, y)
+          if op == 'set' then
+            a = x+y
+          else
+            return a
+          end
+        end
+    if x == 1 then do break end
+    elseif x == 2 then return
+    else if x ~= 3 then error() end
+    end
+    first = nil
+  end
+end
+
+for i=1,3 do
+  f(i)
+  assert(b('get') == 'xuxu')
+  b('set', 10); assert(b('get') == 10+i)
+  b = nil
+end
+
+pcall(f, 4);
+assert(b('get') == 'xuxu')
+b('set', 10); assert(b('get') == 14)
+
+
+local w
+-- testing multi-level closure
+function f(x)
+  return function (y)
+    return function (z) return w+x+y+z end
+  end
+end
+
+y = f(10)
+w = 1.345
+assert(y(20)(30) == 60+w)
+
+-- testing closures x repeat-until
+
+local a = {}
+local i = 1
+repeat
+  local x = i
+  a[i] = function () i = x+1; return x end
+until i > 10 or a[i]() ~= x
+assert(i == 11 and a[1]() == 1 and a[3]() == 3 and i == 4)
+
+print'+'
+
+
+-- test for correctly closing upvalues in tail calls of vararg functions
+local function t ()
+  local function c(a,b) assert(a=="test" and b=="OK") end
+  local function v(f, ...) c("test", f() ~= 1 and "FAILED" or "OK") end
+  local x = 1
+  return v(function() return x end)
+end
+t()
+
+
+-- coroutine tests
+
+local f
+
+assert(coroutine.running() == nil)
+
+
+-- tests for global environment
+
+local function foo (a)
+  setfenv(0, a)
+  coroutine.yield(getfenv())
+  assert(getfenv(0) == a)
+  assert(getfenv(1) == _G)
+  assert(getfenv(loadstring"") == a)
+  return getfenv()
+end
+
+f = coroutine.wrap(foo)
+local a = {}
+assert(f(a) == _G)
+local a,b = pcall(f)
+assert(a and b == _G)
+
+
+-- tests for multiple yield/resume arguments
+
+local function eqtab (t1, t2)
+  assert(table.getn(t1) == table.getn(t2))
+  for i,v in ipairs(t1) do
+    assert(t2[i] == v)
+  end
+end
+
+_G.x = nil   -- declare x
+function foo (a, ...)
+  assert(coroutine.running() == f)
+  assert(coroutine.status(f) == "running")
+  local arg = {...}
+  for i=1,table.getn(arg) do
+    _G.x = {coroutine.yield(unpack(arg[i]))}
+  end
+  return unpack(a)
+end
+
+f = coroutine.create(foo)
+assert(type(f) == "thread" and coroutine.status(f) == "suspended")
+assert(string.find(tostring(f), "thread"))
+local s,a,b,c,d
+s,a,b,c,d = coroutine.resume(f, {1,2,3}, {}, {1}, {'a', 'b', 'c'})
+assert(s and a == nil and coroutine.status(f) == "suspended")
+s,a,b,c,d = coroutine.resume(f)
+eqtab(_G.x, {})
+assert(s and a == 1 and b == nil)
+s,a,b,c,d = coroutine.resume(f, 1, 2, 3)
+eqtab(_G.x, {1, 2, 3})
+assert(s and a == 'a' and b == 'b' and c == 'c' and d == nil)
+s,a,b,c,d = coroutine.resume(f, "xuxu")
+eqtab(_G.x, {"xuxu"})
+assert(s and a == 1 and b == 2 and c == 3 and d == nil)
+assert(coroutine.status(f) == "dead")
+s, a = coroutine.resume(f, "xuxu")
+assert(not s and string.find(a, "dead") and coroutine.status(f) == "dead")
+
+
+-- yields in tail calls
+local function foo (i) return coroutine.yield(i) end
+f = coroutine.wrap(function ()
+  for i=1,10 do
+    assert(foo(i) == _G.x)
+  end
+  return 'a'
+end)
+for i=1,10 do _G.x = i; assert(f(i) == i) end
+_G.x = 'xuxu'; assert(f('xuxu') == 'a')
+
+-- recursive
+function pf (n, i)
+  coroutine.yield(n)
+  pf(n*i, i+1)
+end
+
+f = coroutine.wrap(pf)
+local s=1
+for i=1,10 do
+  assert(f(1, 1) == s)
+  s = s*i
+end
+
+-- sieve
+function gen (n)
+  return coroutine.wrap(function ()
+    for i=2,n do coroutine.yield(i) end
+  end)
+end
+
+
+function filter (p, g)
+  return coroutine.wrap(function ()
+    while 1 do
+      local n = g()
+      if n == nil then return end
+      if math.mod(n, p) ~= 0 then coroutine.yield(n) end
+    end
+  end)
+end
+
+local x = gen(100)
+local a = {}
+while 1 do
+  local n = x()
+  if n == nil then break end
+  table.insert(a, n)
+  x = filter(n, x)
+end
+
+assert(table.getn(a) == 25 and a[table.getn(a)] == 97)
+
+
+-- errors in coroutines
+function foo ()
+  assert(debug.getinfo(1).currentline == debug.getinfo(foo).linedefined + 1)
+  assert(debug.getinfo(2).currentline == debug.getinfo(goo).linedefined)
+  coroutine.yield(3)
+  error(foo)
+end
+
+function goo() foo() end
+x = coroutine.wrap(goo)
+assert(x() == 3)
+local a,b = pcall(x)
+assert(not a and b == foo)
+
+x = coroutine.create(goo)
+a,b = coroutine.resume(x)
+assert(a and b == 3)
+a,b = coroutine.resume(x)
+assert(not a and b == foo and coroutine.status(x) == "dead")
+a,b = coroutine.resume(x)
+assert(not a and string.find(b, "dead") and coroutine.status(x) == "dead")
+
+
+-- co-routines x for loop
+function all (a, n, k)
+  if k == 0 then coroutine.yield(a)
+  else
+    for i=1,n do
+      a[k] = i
+      all(a, n, k-1)
+    end
+  end
+end
+
+local a = 0
+for t in coroutine.wrap(function () all({}, 5, 4) end) do
+  a = a+1
+end
+assert(a == 5^4)
+
+
+-- access to locals of collected corroutines
+local C = {}; setmetatable(C, {__mode = "kv"})
+local x = coroutine.wrap (function ()
+            local a = 10
+            local function f () a = a+10; return a end
+            while true do
+              a = a+1
+              coroutine.yield(f)
+            end
+          end)
+
+C[1] = x;
+
+local f = x()
+assert(f() == 21 and x()() == 32 and x() == f)
+x = nil
+collectgarbage()
+assert(C[1] == nil)
+assert(f() == 43 and f() == 53)
+
+
+-- old bug: attempt to resume itself
+
+function co_func (current_co)
+  assert(coroutine.running() == current_co)
+  assert(coroutine.resume(current_co) == false)
+  assert(coroutine.resume(current_co) == false)
+  return 10
+end
+
+local co = coroutine.create(co_func)
+local a,b = coroutine.resume(co, co)
+assert(a == true and b == 10)
+assert(coroutine.resume(co, co) == false)
+assert(coroutine.resume(co, co) == false)
+
+-- access to locals of erroneous coroutines
+local x = coroutine.create (function ()
+            local a = 10
+            _G.f = function () a=a+1; return a end
+            error('x')
+          end)
+
+assert(not coroutine.resume(x))
+-- overwrite previous position of local `a'
+assert(not coroutine.resume(x, 1, 1, 1, 1, 1, 1, 1))
+assert(_G.f() == 11)
+assert(_G.f() == 12)
+
+
+if not T then
+  (Message or print)('\a\n >>> testC not active: skipping yield/hook tests <<<\n\a')
+else
+
+  local turn
+
+  function fact (t, x)
+    assert(turn == t)
+    if x == 0 then return 1
+    else return x*fact(t, x-1)
+    end
+  end
+
+  local A,B,a,b = 0,0,0,0
+
+  local x = coroutine.create(function ()
+    T.setyhook("", 2)
+    A = fact("A", 10)
+  end)
+
+  local y = coroutine.create(function ()
+    T.setyhook("", 3)
+    B = fact("B", 11)
+  end)
+
+  while A==0 or B==0 do
+    if A==0 then turn = "A"; T.resume(x) end
+    if B==0 then turn = "B"; T.resume(y) end
+  end
+
+  assert(B/A == 11)
+end
+
+
+-- leaving a pending coroutine open
+_X = coroutine.wrap(function ()
+      local a = 10
+      local x = function () a = a+1 end
+      coroutine.yield()
+    end)
+
+_X()
+
+
+-- coroutine environments
+co = coroutine.create(function ()
+       coroutine.yield(getfenv(0))
+       return loadstring("return a")()
+     end)
+
+a = {a = 15}
+debug.setfenv(co, a)
+assert(debug.getfenv(co) == a)
+assert(select(2, coroutine.resume(co)) == a)
+assert(select(2, coroutine.resume(co)) == a.a)
+
+
+print'OK'
diff --git a/test/PUC-Lua-5.1-tests/code.lua b/test/PUC-Lua-5.1-tests/code.lua
new file mode 100644
index 0000000..875d488
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/code.lua
@@ -0,0 +1,143 @@
+
+if T==nil then
+  (Message or print)('\a\n >>> testC not active: skipping opcode tests <<<\n\a')
+  return
+end
+print "testing code generation and optimizations"
+
+
+-- this code gave an error for the code checker
+do
+  local function f (a)
+  for k,v,w in a do end
+  end
+end
+
+
+function check (f, ...)
+  local c = T.listcode(f)
+  for i=1, arg.n do
+    -- print(arg[i], c[i])
+    assert(string.find(c[i], '- '..arg[i]..' *%d'))
+  end
+  assert(c[arg.n+2] == nil)
+end
+
+
+function checkequal (a, b)
+  a = T.listcode(a)
+  b = T.listcode(b)
+  for i = 1, table.getn(a) do
+    a[i] = string.gsub(a[i], '%b()', '')   -- remove line number
+    b[i] = string.gsub(b[i], '%b()', '')   -- remove line number
+    assert(a[i] == b[i])
+  end
+end
+
+
+-- some basic instructions
+check(function ()
+  (function () end){f()}
+end, 'CLOSURE', 'NEWTABLE', 'GETGLOBAL', 'CALL', 'SETLIST', 'CALL', 'RETURN')
+
+
+-- sequence of LOADNILs
+check(function ()
+  local a,b,c
+  local d; local e;
+  a = nil; d=nil
+end, 'RETURN')
+
+
+-- single return
+check (function (a,b,c) return a end, 'RETURN')
+
+
+-- infinite loops
+check(function () while true do local a = -1 end end,
+'LOADK', 'JMP', 'RETURN')
+
+check(function () while 1 do local a = -1 end end,
+'LOADK', 'JMP', 'RETURN')
+
+check(function () repeat local x = 1 until false end,
+'LOADK', 'JMP', 'RETURN')
+
+check(function () repeat local x until nil end,
+'LOADNIL', 'JMP', 'RETURN')
+
+check(function () repeat local x = 1 until true end,
+'LOADK', 'RETURN')
+
+
+-- concat optimization
+check(function (a,b,c,d) return a..b..c..d end,
+  'MOVE', 'MOVE', 'MOVE', 'MOVE', 'CONCAT', 'RETURN')
+
+-- not
+check(function () return not not nil end, 'LOADBOOL', 'RETURN')
+check(function () return not not false end, 'LOADBOOL', 'RETURN')
+check(function () return not not true end, 'LOADBOOL', 'RETURN')
+check(function () return not not 1 end, 'LOADBOOL', 'RETURN')
+
+-- direct access to locals
+check(function ()
+  local a,b,c,d
+  a = b*2
+  c[4], a[b] = -((a + d/-20.5 - a[b]) ^ a.x), b
+end,
+  'MUL',
+  'DIV', 'ADD', 'GETTABLE', 'SUB', 'GETTABLE', 'POW',
+    'UNM', 'SETTABLE', 'SETTABLE', 'RETURN')
+
+
+-- direct access to constants
+check(function ()
+  local a,b
+  a.x = 0
+  a.x = b
+  a[b] = 'y'
+  a = 1 - a
+  b = 1/a
+  b = 5+4
+  a[true] = false
+end,
+  'SETTABLE', 'SETTABLE', 'SETTABLE', 'SUB', 'DIV', 'LOADK',
+  'SETTABLE', 'RETURN')
+
+local function f () return -((2^8 + -(-1)) % 8)/2 * 4 - 3 end
+
+check(f, 'LOADK', 'RETURN')
+assert(f() == -5)
+
+check(function ()
+  local a,b,c
+  b[c], a = c, b
+  b[a], a = c, b
+  a, b = c, a
+  a = a
+end,
+  'MOVE', 'MOVE', 'SETTABLE',
+  'MOVE', 'MOVE', 'MOVE', 'SETTABLE',
+  'MOVE', 'MOVE', 'MOVE',
+  -- no code for a = a
+  'RETURN')
+
+
+-- x == nil , x ~= nil
+checkequal(function () if (a==nil) then a=1 end; if a~=nil then a=1 end end,
+           function () if (a==9) then a=1 end; if a~=9 then a=1 end end)
+
+check(function () if a==nil then a=1 end end,
+'GETGLOBAL', 'EQ', 'JMP', 'LOADK', 'SETGLOBAL', 'RETURN')
+
+-- de morgan
+checkequal(function () local a; if not (a or b) then b=a end end,
+           function () local a; if (not a and not b) then b=a end end)
+
+checkequal(function (l) local a; return 0 <= a and a <= l end,
+           function (l) local a; return not (not(a >= 0) or not(a <= l)) end)
+
+
+print 'OK'
+
diff --git a/test/PUC-Lua-5.1-tests/constructs.lua b/test/PUC-Lua-5.1-tests/constructs.lua
new file mode 100644
index 0000000..5fb3798
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/constructs.lua
@@ -0,0 +1,240 @@
+print "testing syntax"
+
+-- testing priorities
+
+assert(2^3^2 == 2^(3^2));
+assert(2^3*4 == (2^3)*4);
+assert(2^-2 == 1/4 and -2^- -2 == - - -4);
+assert(not nil and 2 and not(2>3 or 3<2));
+assert(-3-1-5 == 0+0-9);
+assert(-2^2 == -4 and (-2)^2 == 4 and 2*2-3-1 == 0);
+assert(2*1+3/3 == 3 and 1+2 .. 3*1 == "33");
+assert(not(2+1 > 3*1) and "a".."b" > "a");
+
+assert(not ((true or false) and nil))
+assert(      true or false  and nil)
+
+local a,b = 1,nil;
+assert(-(1 or 2) == -1 and (1 and 2)+(-1.25 or -4) == 0.75);
+x = ((b or a)+1 == 2 and (10 or a)+1 == 11); assert(x);
+x = (((2<3) or 1) == true and (2<3 and 4) == 4); assert(x);
+
+x,y=1,2;
+assert((x>y) and x or y == 2);
+x,y=2,1;
+assert((x>y) and x or y == 2);
+
+assert(1234567890 == tonumber('1234567890') and 1234567890+1 == 1234567891)
+
+
+-- silly loops
+repeat until 1; repeat until true;
+while false do end; while nil do end;
+
+do  -- test old bug (first name could not be an `upvalue')
+ local a; function f(x) x={a=1}; x={x=1}; x={G=1} end
+end
+
+function f (i)
+  if type(i) ~= 'number' then return i,'jojo'; end;
+  if i > 0 then return i, f(i-1); end;
+end
+
+x = {f(3), f(5), f(10);};
+assert(x[1] == 3 and x[2] == 5 and x[3] == 10 and x[4] == 9 and x[12] == 1);
+assert(x[nil] == nil)
+x = {f'alo', f'xixi', nil};
+assert(x[1] == 'alo' and x[2] == 'xixi' and x[3] == nil);
+x = {f'alo'..'xixi'};
+assert(x[1] == 'aloxixi')
+x = {f{}}
+assert(x[2] == 'jojo' and type(x[1]) == 'table')
+
+
+local f = function (i)
+  if i < 10 then return 'a';
+  elseif i < 20 then return 'b';
+  elseif i < 30 then return 'c';
+  end;
+end
+
+assert(f(3) == 'a' and f(12) == 'b' and f(26) == 'c' and f(100) == nil)
+
+for i=1,1000 do break; end;
+n=100;
+i=3;
+t = {};
+a=nil
+while not a do
+  a=0; for i=1,n do for i=i,1,-1 do a=a+1; t[i]=1; end; end;
+end
+assert(a == n*(n+1)/2 and i==3);
+assert(t[1] and t[n] and not t[0] and not t[n+1])
+
+function f(b)
+  local x = 1;
+  repeat
+    local a;
+    if b==1 then local b=1; x=10; break
+    elseif b==2 then x=20; break;
+    elseif b==3 then x=30;
+    else local a,b,c,d=math.sin(1); x=x+1;
+    end
+  until x>=12;
+  return x;
+end;
+
+assert(f(1) == 10 and f(2) == 20 and f(3) == 30 and f(4)==12)
+
+
+local f = function (i)
+  if i < 10 then return 'a'
+  elseif i < 20 then return 'b'
+  elseif i < 30 then return 'c'
+  else return 8
+  end
+end
+
+assert(f(3) == 'a' and f(12) == 'b' and f(26) == 'c' and f(100) == 8)
+
+local a, b = nil, 23
+x = {f(100)*2+3 or a, a or b+2}
+assert(x[1] == 19 and x[2] == 25)
+x = {f=2+3 or a, a = b+2}
+assert(x.f == 5 and x.a == 25)
+
+a={y=1}
+x = {a.y}
+assert(x[1] == 1)
+
+function f(i)
+  while 1 do
+    if i>0 then i=i-1;
+    else return; end;
+  end;
+end;
+
+function g(i)
+  while 1 do
+    if i>0 then i=i-1
+    else return end
+  end
+end
+
+f(10); g(10);
+
+do
+  function f () return 1,2,3; end
+  local a, b, c = f();
+  assert(a==1 and b==2 and c==3)
+  a, b, c = (f());
+  assert(a==1 and b==nil and c==nil)
+end
+
+local a,b = 3 and f();
+assert(a==1 and b==nil)
+
+function g() f(); return; end;
+assert(g() == nil)
+function g() return nil or f() end
+a,b = g()
+assert(a==1 and b==nil)
+
+print'+';
+
+
+f = [[
+return function ( a , b , c , d , e )
+  local x = a >= b or c or ( d and e ) or nil
+  return x
+end , { a = 1 , b = 2 >= 1 , } or { 1 };
+]]
+f = string.gsub(f, "%s+", "\n");   -- force a SETLINE between opcodes
+f,a = loadstring(f)();
+assert(a.a == 1 and a.b)
+
+function g (a,b,c,d,e)
+  if not (a>=b or c or d and e or nil) then return 0; else return 1; end;
+end
+
+function h (a,b,c,d,e)
+  while (a>=b or c or (d and e) or nil) do return 1; end;
+  return 0;
+end;
+
+assert(f(2,1) == true and g(2,1) == 1 and h(2,1) == 1)
+assert(f(1,2,'a') == 'a' and g(1,2,'a') == 1 and h(1,2,'a') == 1)
+assert(f(1,2,'a')
+~=          -- force SETLINE before nil
+nil, "")
+assert(f(1,2,'a') == 'a' and g(1,2,'a') == 1 and h(1,2,'a') == 1)
+assert(f(1,2,nil,1,'x') == 'x' and g(1,2,nil,1,'x') == 1 and
+                                   h(1,2,nil,1,'x') == 1)
+assert(f(1,2,nil,nil,'x') == nil and g(1,2,nil,nil,'x') == 0 and
+                                     h(1,2,nil,nil,'x') == 0)
+assert(f(1,2,nil,1,nil) == nil and g(1,2,nil,1,nil) == 0 and
+                                   h(1,2,nil,1,nil) == 0)
+
+assert(1 and 2<3 == true and 2<3 and 'a'<'b' == true)
+x = 2<3 and not 3; assert(x==false)
+x = 2<1 or (2>1 and 'a'); assert(x=='a')
+
+
+do
+  local a; if nil then a=1; else a=2; end;    -- this nil comes as PUSHNIL 2
+  assert(a==2)
+end
+
+function F(a)
+  assert(debug.getinfo(1, "n").name == 'F')
+  return a,2,3
+end
+
+a,b = F(1)~=nil; assert(a == true and b == nil);
+a,b = F(nil)==nil; assert(a == true and b == nil)
+
+----------------------------------------------------------------
+-- creates all combinations of
+-- [not] ([not] arg op [not] (arg op [not] arg ))
+-- and tests each one
+
+function ID(x) return x end
+
+function f(t, i)
+  local b = t.n
+  local res = math.mod(math.floor(i/c), b)+1
+  c = c*b
+  return t[res]
+end
+
+local arg = {" ( 1 < 2 ) ", " ( 1 >= 2 ) ", " F ( ) ", "  nil "; n=4}
+
+local op = {" and ", " or ", " == ", " ~= "; n=4}
+
+local neg = {" ", " not "; n=2}
+
+local i = 0
+repeat
+  c = 1
+  local s = f(neg, i)..'ID('..f(neg, i)..f(arg, i)..f(op, i)..
+            f(neg, i)..'ID('..f(arg, i)..f(op, i)..f(neg, i)..f(arg, i)..'))'
+  local s1 = string.gsub(s, 'ID', '')
+  K,X,NX,WX1,WX2 = nil
+  s = string.format([[
+      local a = %s
+      local b = not %s
+      K = b
+      local xxx;
+      if %s then X = a  else X = b end
+      if %s then NX = b  else NX = a end
+      while %s do WX1 = a; break end
+      while %s do WX2 = a; break end
+      repeat if (%s) then break end; assert(b)  until not(%s)
+  ]], s1, s, s1, s, s1, s, s1, s, s)
+  assert(loadstring(s))()
+  assert(X and not NX and not WX1 == K and not WX2 == K)
+  if math.mod(i,4000) == 0 then print('+') end
+  i = i+1
+until i==c
+
+print'OK'
diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua
new file mode 100644
index 0000000..9d2c86f
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/db.lua
@@ -0,0 +1,499 @@
+-- testing debug library
+
+local function dostring(s) return assert(loadstring(s))() end
+
+print"testing debug library and debug information"
+
+do
+local a=1
+end
+
+function test (s, l, p)
+  collectgarbage()   -- avoid gc during trace
+  local function f (event, line)
+    assert(event == 'line')
+    local l = table.remove(l, 1)
+    if p then print(l, line) end
+    assert(l == line, "wrong trace!!")
+  end
+  debug.sethook(f,"l"); loadstring(s)(); debug.sethook()
+  assert(table.getn(l) == 0)
+end
+
+
+do
+  local a = debug.getinfo(print)
+  assert(a.what == "C" and a.short_src == "[C]")
+  local b = debug.getinfo(test, "SfL")
+  assert(b.name == nil and b.what == "Lua" and b.linedefined == 11 and
+         b.lastlinedefined == b.linedefined + 10 and
+         b.func == test and not string.find(b.short_src, "%["))
+  assert(b.activelines[b.linedefined + 1] and
+         b.activelines[b.lastlinedefined])
+  assert(not b.activelines[b.linedefined] and
+         not b.activelines[b.lastlinedefined + 1])
+end
+
+
+-- test file and string names truncation
+a = "function f () end"
+local function dostring (s, x) return loadstring(s, x)() end
+dostring(a)
+assert(debug.getinfo(f).short_src == string.format('[string "%s"]', a))
+dostring(a..string.format("; %s\n=1", string.rep('p', 400)))
+assert(string.find(debug.getinfo(f).short_src, '^%[string [^\n]*%.%.%."%]$'))
+dostring("\n"..a)
+assert(debug.getinfo(f).short_src == '[string "..."]')
+dostring(a, "")
+assert(debug.getinfo(f).short_src == '[string ""]')
+dostring(a, "@xuxu")
+assert(debug.getinfo(f).short_src == "xuxu")
+dostring(a, "@"..string.rep('p', 1000)..'t')
+assert(string.find(debug.getinfo(f).short_src, "^%.%.%.p*t$"))
+dostring(a, "=xuxu")
+assert(debug.getinfo(f).short_src == "xuxu")
+dostring(a, string.format("=%s", string.rep('x', 500)))
+assert(string.find(debug.getinfo(f).short_src, "^x*"))
+dostring(a, "=")
+assert(debug.getinfo(f).short_src == "")
+a = nil; f = nil;
+
+
+repeat
+  local g = {x = function ()
+    local a = debug.getinfo(2)
+    assert(a.name == 'f' and a.namewhat == 'local')
+    a = debug.getinfo(1)
+    assert(a.name == 'x' and a.namewhat == 'field')
+    return 'xixi'
+  end}
+  local f = function () return 1+1 and (not 1 or g.x()) end
+  assert(f() == 'xixi')
+  g = debug.getinfo(f)
+  assert(g.what == "Lua" and g.func == f and g.namewhat == "" and not g.name)
+
+  function f (x, name)   -- local!
+    name = name or 'f'
+    local a = debug.getinfo(1)
+    assert(a.name == name and a.namewhat == 'local')
+    return x
+  end
+
+  -- breaks in different conditions
+  if 3>4 then break end; f()
+  if 3<4 then a=1 else break end; f()
+  while 1 do local x=10; break end; f()
+  local b = 1
+  if 3>4 then return math.sin(1) end; f()
+  a = 3<4; f()
+  a = 3<4 or 1; f()
+  repeat local x=20; if 4>3 then f() else break end; f() until 1
+  g = {}
+  f(g).x = f(2) and f(10)+f(9)
+  assert(g.x == f(19))
+  function g(x) if not x then return 3 end return (x('a', 'x')) end
+  assert(g(f) == 'a')
+until 1
+
+test([[if
+math.sin(1)
+then
+  a=1
+else
+  a=2
+end
+]], {2,4,7})
+
+test([[--
+if nil then
+  a=1
+else
+  a=2
+end
+]], {2,5,6})
+
+test([[a=1
+repeat
+  a=a+1
+until a==3
+]], {1,3,4,3,4})
+
+test([[ do
+  return
+end
+]], {2})
+
+test([[local a
+a=1
+while a<=3 do
+  a=a+1
+end
+]], {2,3,4,3,4,3,4,3,5})
+
+test([[while math.sin(1) do
+  if math.sin(1)
+  then
+    break
+  end
+end
+a=1]], {1,2,4,7})
+
+test([[for i=1,3 do
+  a=i
+end
+]], {1,2,1,2,1,2,1,3})
+
+test([[for i,v in pairs{'a','b'} do
+  a=i..v
+end
+]], {1,2,1,2,1,3})
+
+test([[for i=1,4 do a=1 end]], {1,1,1,1,1})
+
+
+
+print'+'
+
+a = {}; L = nil
+local glob = 1
+local oldglob = glob
+debug.sethook(function (e,l)
+  collectgarbage()   -- force GC during a hook
+  local f, m, c = debug.gethook()
+  assert(m == 'crl' and c == 0)
+  if e == "line" then
+    if glob ~= oldglob then
+      L = l-1   -- get the first line where "glob" has changed
+      oldglob = glob
+    end
+  elseif e == "call" then
+      local f = debug.getinfo(2, "f").func
+      a[f] = 1
+  else assert(e == "return")
+  end
+end, "crl")
+
+function f(a,b)
+  collectgarbage()
+  local _, x = debug.getlocal(1, 1)
+  local _, y = debug.getlocal(1, 2)
+  assert(x == a and y == b)
+  assert(debug.setlocal(2, 3, "pera") == "AA".."AA")
+  assert(debug.setlocal(2, 4, "maçã") == "B")
+  x = debug.getinfo(2)
+  assert(x.func == g and x.what == "Lua" and x.name == 'g' and
+         x.nups == 0 and string.find(x.source, "^@.*db%.lua"))
+  glob = glob+1
+  assert(debug.getinfo(1, "l").currentline == L+1)
+  assert(debug.getinfo(1, "l").currentline == L+2)
+end
+
+function foo()
+  glob = glob+1
+  assert(debug.getinfo(1, "l").currentline == L+1)
+end; foo()  -- set L
+-- check line counting inside strings and empty lines
+
+_ = 'alo\
+alo' .. [[
+
+]]
+--[[
+]]
+assert(debug.getinfo(1, "l").currentline == L+11)  -- check count of lines
+
+
+function g(...)
+  do local a,b,c; a=math.sin(40); end
+  local feijao
+  local AAAA,B = "xuxu", "mamão"
+  f(AAAA,B)
+  assert(AAAA == "pera" and B == "maçã")
+  do
+     local B = 13
+     local x,y = debug.getlocal(1,5)
+     assert(x == 'B' and y == 13)
+  end
+end
+
+g()
+
+
+assert(a[f] and a[g] and a[assert] and a[debug.getlocal] and not a[print])
+
+
+-- tests for manipulating non-registered locals (C and Lua temporaries)
+
+local n, v = debug.getlocal(0, 1)
+assert(v == 0 and n == "(*temporary)")
+local n, v = debug.getlocal(0, 2)
+assert(v == 2 and n == "(*temporary)")
+assert(not debug.getlocal(0, 3))
+assert(not debug.getlocal(0, 0))
+
+function f()
+  assert(select(2, debug.getlocal(2,3)) == 1)
+  assert(not debug.getlocal(2,4))
+  debug.setlocal(2, 3, 10)
+  return 20
+end
+
+function g(a,b) return (a+1) + f() end
+
+assert(g(0,0) == 30)
+
+
+debug.sethook(nil);
+assert(debug.gethook() == nil)
+
+
+-- testing access to function arguments
+
+X = nil
+a = {}
+function a:f (a, b, ...) local c = 13 end
+debug.sethook(function (e)
+  assert(e == "call")
+  dostring("XX = 12")  -- test dostring inside hooks
+  -- testing errors inside hooks
+  assert(not pcall(loadstring("a='joao'+1")))
+  debug.sethook(function (e, l)
+    assert(debug.getinfo(2, "l").currentline == l)
+    local f,m,c = debug.gethook()
+    assert(e == "line")
+    assert(m == 'l' and c == 0)
+    debug.sethook(nil)  -- hook is called only once
+    assert(not X)       -- check that
+    X = {}; local i = 1
+    local x,y
+    while 1 do
+      x,y = debug.getlocal(2, i)
+      if x==nil then break end
+      X[x] = y
+      i = i+1
+    end
+  end, "l")
+end, "c")
+
+a:f(1,2,3,4,5)
+assert(X.self == a and X.a == 1   and X.b == 2 and X.arg.n == 3 and X.c == nil)
+assert(XX == 12)
+assert(debug.gethook() == nil)
+
+
+-- testing upvalue access
+local function getupvalues (f)
+  local t = {}
+  local i = 1
+  while true do
+    local name, value = debug.getupvalue(f, i)
+    if not name then break end
+    assert(not t[name])
+    t[name] = value
+    i = i + 1
+  end
+  return t
+end
+
+local a,b,c = 1,2,3
+local function foo1 (a) b = a; return c end
+local function foo2 (x) a = x; return c+b end
+assert(debug.getupvalue(foo1, 3) == nil)
+assert(debug.getupvalue(foo1, 0) == nil)
+assert(debug.setupvalue(foo1, 3, "xuxu") == nil)
+local t = getupvalues(foo1)
+assert(t.a == nil and t.b == 2 and t.c == 3)
+t = getupvalues(foo2)
+assert(t.a == 1 and t.b == 2 and t.c == 3)
+assert(debug.setupvalue(foo1, 1, "xuxu") == "b")
+assert(({debug.getupvalue(foo2, 3)})[2] == "xuxu")
+-- cannot manipulate C upvalues from Lua
+assert(debug.getupvalue(io.read, 1) == nil)
+assert(debug.setupvalue(io.read, 1, 10) == nil)
+
+
+-- testing count hooks
+local a=0
+debug.sethook(function (e) a=a+1 end, "", 1)
+a=0; for i=1,1000 do end; assert(1000 < a and a < 1012)
+debug.sethook(function (e) a=a+1 end, "", 4)
+a=0; for i=1,1000 do end; assert(250 < a and a < 255)
+local f,m,c = debug.gethook()
+assert(m == "" and c == 4)
+debug.sethook(function (e) a=a+1 end, "", 4000)
+a=0; for i=1,1000 do end; assert(a == 0)
+debug.sethook(print, "", 2^24 - 1)   -- count upperbound
+local f,m,c = debug.gethook()
+assert(({debug.gethook()})[3] == 2^24 - 1)
+debug.sethook()
+
+
+-- tests for tail calls
+local function f (x)
+  if x then
+    assert(debug.getinfo(1, "S").what == "Lua")
+    local tail = debug.getinfo(2)
+    assert(not pcall(getfenv, 3))
+    assert(tail.what == "tail" and tail.short_src == "(tail call)" and
+           tail.linedefined == -1 and tail.func == nil)
+    assert(debug.getinfo(3, "f").func == g1)
+    assert(getfenv(3))
+    assert(debug.getinfo(4, "S").what == "tail")
+    assert(not pcall(getfenv, 5))
+    assert(debug.getinfo(5, "S").what == "main")
+    assert(getfenv(5))
+    print"+"
+    end
+end
+
+function g(x) return f(x) end
+
+function g1(x) g(x) end
+
+local function h (x) local f=g1; return f(x) end
+
+h(true)
+
+local b = {}
+debug.sethook(function (e) table.insert(b, e) end, "cr")
+h(false)
+debug.sethook()
+local res = {"return",   -- first return (from sethook)
+  "call", "call", "call", "call",
+  "return", "tail return", "return", "tail return",
+  "call",    -- last call (to sethook)
+}
+for _, k in ipairs(res) do assert(k == table.remove(b, 1)) end
+
+
+lim = 30000
+local function foo (x)
+  if x==0 then
+    assert(debug.getinfo(lim+2).what == "main")
+    for i=2,lim do assert(debug.getinfo(i, "S").what == "tail") end
+  else return foo(x-1)
+  end
+end
+
+foo(lim)
+
+
+print"+"
+
+
+-- testing traceback
+
+assert(debug.traceback(print) == print)
+assert(debug.traceback(print, 4) == print)
+assert(string.find(debug.traceback("hi", 4), "^hi\n"))
+assert(string.find(debug.traceback("hi"), "^hi\n"))
+assert(not string.find(debug.traceback("hi"), "'traceback'"))
+assert(string.find(debug.traceback("hi", 0), "'traceback'"))
+assert(string.find(debug.traceback(), "^stack traceback:\n"))
+
+-- testing debugging of coroutines
+
+local function checktraceback (co, p)
+  local tb = debug.traceback(co)
+  local i = 0
+  for l in string.gmatch(tb, "[^\n]+\n?") do
+    assert(i == 0 or string.find(l, p[i]))
+    i = i+1
+  end
+  assert(p[i] == nil)
+end
+
+
+local function f (n)
+  if n > 0 then return f(n-1)
+  else coroutine.yield() end
+end
+
+local co = coroutine.create(f)
+coroutine.resume(co, 3)
+checktraceback(co, {"yield", "db.lua", "tail", "tail", "tail"})
+
+
+co = coroutine.create(function (x)
+       local a = 1
+       coroutine.yield(debug.getinfo(1, "l"))
+       coroutine.yield(debug.getinfo(1, "l").currentline)
+       return a
+     end)
+
+local tr = {}
+local foo = function (e, l) table.insert(tr, l) end
+debug.sethook(co, foo, "l")
+
+local _, l = coroutine.resume(co, 10)
+local x = debug.getinfo(co, 1, "lfLS")
+assert(x.currentline == l.currentline and x.activelines[x.currentline])
+assert(type(x.func) == "function")
+for i=x.linedefined + 1, x.lastlinedefined do
+  assert(x.activelines[i])
+  x.activelines[i] = nil
+end
+assert(next(x.activelines) == nil)   -- no 'extra' elements
+assert(debug.getinfo(co, 2) == nil)
+local a,b = debug.getlocal(co, 1, 1)
+assert(a == "x" and b == 10)
+a,b = debug.getlocal(co, 1, 2)
+assert(a == "a" and b == 1)
+debug.setlocal(co, 1, 2, "hi")
+assert(debug.gethook(co) == foo)
+assert(table.getn(tr) == 2 and
+       tr[1] == l.currentline-1 and tr[2] == l.currentline)
+
+a,b,c = pcall(coroutine.resume, co)
+assert(a and b and c == l.currentline+1)
+checktraceback(co, {"yield", "in function <"})
+
+a,b = coroutine.resume(co)
+assert(a and b == "hi")
+assert(table.getn(tr) == 4 and tr[4] == l.currentline+2)
+assert(debug.gethook(co) == foo)
+assert(debug.gethook() == nil)
+checktraceback(co, {})
+
+
+-- check traceback of suspended (or dead with error) coroutines
+
+function f(i) if i==0 then error(i) else coroutine.yield(); f(i-1) end end
+
+co = coroutine.create(function (x) f(x) end)
+a, b = coroutine.resume(co, 3)
+t = {"'yield'", "'f'", "in function <"}
+while coroutine.status(co) == "suspended" do
+  checktraceback(co, t)
+  a, b = coroutine.resume(co)
+  table.insert(t, 2, "'f'")   -- one more recursive call to 'f'
+end
+t[1] = "'error'"
+checktraceback(co, t)
+
+
+-- test acessing line numbers of a coroutine from a resume inside
+-- a C function (this is a known bug in Lua 5.0)
+
+local function g(x)
+    coroutine.yield(x)
+end
+
+local function f (i)
+  debug.sethook(function () end, "l")
+  for j=1,1000 do
+    g(i+j)
+  end
+end
+
+local co = coroutine.wrap(f)
+co(10)
+pcall(co)
+pcall(co)
+
+
+assert(type(debug.getregistry()) == "table")
+
+
+print"OK"
+
diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua
new file mode 100644
index 0000000..e881211
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/errors.lua
@@ -0,0 +1,250 @@
+print("testing errors")
+
+function doit (s)
+  local f, msg = loadstring(s)
+  if f == nil then return msg end
+  local cond, msg = pcall(f)
+  return (not cond) and msg
+end
+
+
+function checkmessage (prog, msg)
+  assert(string.find(doit(prog), msg, 1, true))
+end
+
+function checksyntax (prog, extra, token, line)
+  local msg = doit(prog)
+  token = string.gsub(token, "(%p)", "%%%1")
+  local pt = string.format([[^%%[string ".*"%%]:%d: .- near '%s'$]],
+                           line, token)
+  assert(string.find(msg, pt))
+  assert(string.find(msg, msg, 1, true))
+end
+
+
+-- test error message with no extra info
+assert(doit("error('hi', 0)") == 'hi')
+
+-- test error message with no info
+assert(doit("error()") == nil)
+
+
+-- test common errors/errors that crashed in the past
+assert(doit("unpack({}, 1, n=2^30)"))
+assert(doit("a=math.sin()"))
+assert(not doit("tostring(1)") and doit("tostring()"))
+assert(doit"tonumber()")
+assert(doit"repeat until 1; a")
+checksyntax("break label", "", "label", 1)
+assert(doit";")
+assert(doit"a=1;;")
+assert(doit"return;;")
+assert(doit"assert(false)")
+assert(doit"assert(nil)")
+assert(doit"a=math.sin\n(3)")
+assert(doit("function a (... , ...) end"))
+assert(doit("function a (, ...) end"))
+
+checksyntax([[
+  local a = {4
+
+]], "'}' expected (to close '{' at line 1)", "<eof>", 3)
+
+
+-- tests for better error messages
+
+checkmessage("a=1; bbbb=2; a=math.sin(3)+bbbb(3)", "global 'bbbb'")
+checkmessage("a=1; local a,bbbb=2,3; a = math.sin(1) and bbbb(3)",
+       "local 'bbbb'")
+checkmessage("a={}; do local a=1 end a:bbbb(3)", "method 'bbbb'")
+checkmessage("local a={}; a.bbbb(3)", "field 'bbbb'")
+assert(not string.find(doit"a={13}; local bbbb=1; a[bbbb](3)", "'bbbb'"))
+checkmessage("a={13}; local bbbb=1; a[bbbb](3)", "number")
+
+aaa = nil
+checkmessage("aaa.bbb:ddd(9)", "global 'aaa'")
+checkmessage("local aaa={bbb=1}; aaa.bbb:ddd(9)", "field 'bbb'")
+checkmessage("local aaa={bbb={}}; aaa.bbb:ddd(9)", "method 'ddd'")
+checkmessage("local a,b,c; (function () a = b+1 end)()", "upvalue 'b'")
+assert(not doit"local aaa={bbb={ddd=next}}; aaa.bbb:ddd(nil)")
+
+checkmessage("b=1; local aaa='a'; x=aaa+b", "local 'aaa'")
+checkmessage("aaa={}; x=3/aaa", "global 'aaa'")
+checkmessage("aaa='2'; b=nil;x=aaa*b", "global 'b'")
+checkmessage("aaa={}; x=-aaa", "global 'aaa'")
+assert(not string.find(doit"aaa={}; x=(aaa or aaa)+(aaa and aaa)", "'aaa'"))
+assert(not string.find(doit"aaa={}; (aaa or aaa)()", "'aaa'"))
+
+checkmessage([[aaa=9
+repeat until 3==3
+local x=math.sin(math.cos(3))
+if math.sin(1) == x then return math.sin(1) end   -- tail call
+local a,b = 1, {
+  {x='a'..'b'..'c', y='b', z=x},
+  {1,2,3,4,5} or 3+3<=3+3,
+  3+1>3+1,
+  {d = x and aaa[x or y]}}
+]], "global 'aaa'")
+
+checkmessage([[
+local x,y = {},1
+if math.sin(1) == 0 then return 3 end    -- return
+x.a()]], "field 'a'")
+
+checkmessage([[
+prefix = nil
+insert = nil
+while 1 do
+  local a
+  if nil then break end
+  insert(prefix, a)
+end]], "global 'insert'")
+
+checkmessage([[  -- tail call
+  return math.sin("a")
+]], "'sin'")
+
+checkmessage([[collectgarbage("nooption")]], "invalid option")
+
+checkmessage([[x = print .. "a"]], "concatenate")
+
+checkmessage("getmetatable(io.stdin).__gc()", "no value")
+
+print'+'
+
+
+-- testing line error
+
+function lineerror (s)
+  local err,msg = pcall(loadstring(s))
+  local line = string.match(msg, ":(%d+):")
+  return line and line+0
+end
+
+assert(lineerror"local a\n for i=1,'a' do \n print(i) \n end" == 2)
+assert(lineerror"\n local a \n for k,v in 3 \n do \n print(k) \n end" == 3)
+assert(lineerror"\n\n for k,v in \n 3 \n do \n print(k) \n end" == 4)
+assert(lineerror"function a.x.y ()\na=a+1\nend" == 1)
+
+local p = [[
+function g() f() end
+function f(x) error('a', X) end
+g()
+]]
+X=3;assert(lineerror(p) == 3)
+X=0;assert(lineerror(p) == nil)
+X=1;assert(lineerror(p) == 2)
+X=2;assert(lineerror(p) == 1)
+
+lineerror = nil
+
+C = 0
+local l = debug.getinfo(1, "l").currentline; function y () C=C+1; y() end
+
+local function checkstackmessage (m)
+  return (string.find(m, "^.-:%d+: stack overflow"))
+end
+assert(checkstackmessage(doit('y()')))
+assert(checkstackmessage(doit('y()')))
+assert(checkstackmessage(doit('y()')))
+-- teste de linhas em erro
+C = 0
+local l1
+local function g()
+  l1 = debug.getinfo(1, "l").currentline; y()
+end
+local _, stackmsg = xpcall(g, debug.traceback)
+local stack = {}
+for line in string.gmatch(stackmsg, "[^\n]*") do
+  local curr = string.match(line, ":(%d+):")
+  if curr then table.insert(stack, tonumber(curr)) end
+end
+local i=1
+while stack[i] ~= l1 do
+  assert(stack[i] == l)
+  i = i+1
+end
+assert(i > 15)
+
+
+-- error in error handling
+local res, msg = xpcall(error, error)
+assert(not res and type(msg) == 'string')
+
+local function f (x)
+  if x==0 then error('a\n')
+  else
+    local aux = function () return f(x-1) end
+    local a,b = xpcall(aux, aux)
+    return a,b
+  end
+end
+f(3)
+
+-- non string messages
+function f() error{msg='x'} end
+res, msg = xpcall(f, function (r) return {msg=r.msg..'y'} end)
+assert(msg.msg == 'xy')
+
+print('+')
+checksyntax("syntax error", "", "error", 1)
+checksyntax("1.000", "", "1.000", 1)
+checksyntax("[[a]]", "", "[[a]]", 1)
+checksyntax("'aa'", "", "'aa'", 1)
+
+-- test 255 as first char in a chunk
+checksyntax("\255a = 1", "", "\255", 1)
+
+doit('I = loadstring("a=9+"); a=3')
+assert(a==3 and I == nil)
+print('+')
+
+lim = 1000
+if rawget(_G, "_soft") then lim = 100 end
+for i=1,lim do
+  doit('a = ')
+  doit('a = 4+nil')
+end
+
+
+-- testing syntax limits
+local function testrep (init, rep)
+  local s = "local a; "..init .. string.rep(rep, 400)
+  local a,b = loadstring(s)
+  assert(not a and string.find(b, "syntax levels"))
+end
+testrep("a=", "{")
+testrep("a=", "(")
+testrep("", "a(")
+testrep("", "do ")
+testrep("", "while a do ")
+testrep("", "if a then else ")
+testrep("", "function foo () ")
+testrep("a=", "a..")
+testrep("a=", "a^")
+
+
+-- testing other limits
+-- upvalues
+local  s = "function foo ()\n  local "
+for j = 1,70 do
+  s = s.."a"..j..", "
+end
+s = s.."b\n"
+for j = 1,70 do
+  s = s.."function foo"..j.." ()\n a"..j.."=3\n"
+end
+local a,b = loadstring(s)
+assert(string.find(b, "line 3"))
+
+-- local variables
+s = "\nfunction foo ()\n  local "
+for j = 1,300 do
+  s = s.."a"..j..", "
+end
+s = s.."b\n"
+local a,b = loadstring(s)
+assert(string.find(b, "line 2"))
+
+
+print('OK')
diff --git a/test/PUC-Lua-5.1-tests/etc/ltests.c b/test/PUC-Lua-5.1-tests/etc/ltests.c
new file mode 100644
index 0000000..be949e5
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/etc/ltests.c
@@ -0,0 +1,1147 @@
+/*
+** $Id: ltests.c,v 2.36 2006/01/10 13:13:06 roberto Exp $
+** Internal Module for Debugging of the Lua Implementation
+** See Copyright Notice in lua.h
+*/
+
+
+#include <ctype.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define ltests_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "lapi.h"
+#include "lauxlib.h"
+#include "lcode.h"
+#include "ldebug.h"
+#include "ldo.h"
+#include "lfunc.h"
+#include "lmem.h"
+#include "lopcodes.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "ltable.h"
+#include "lualib.h"
+
+
+
+/*
+** The whole module only makes sense with LUA_DEBUG on
+*/
+#if defined(LUA_DEBUG)
+
+
+int Trick = 0;
+
+
+static lua_State *lua_state = NULL;
+
+int islocked = 0;
+
+
+#define obj_at(L,k)	(L->ci->base+(k) - 1)
+
+
+static void setnameval (lua_State *L, const char *name, int val) {
+  lua_pushstring(L, name);
+  lua_pushinteger(L, val);
+  lua_settable(L, -3);
+}
+
+
+/*
+** {======================================================================
+** Controlled version for realloc.
+** =======================================================================
+*/
+
+#define MARK		0x55  /* 01010101 (a nice pattern) */
+
+#ifndef EXTERNMEMCHECK
+/* full memory check */
+#define HEADER	(sizeof(L_Umaxalign)) /* ensures maximum alignment for HEADER */
+#define MARKSIZE	16  /* size of marks after each block */
+#define blockhead(b)	(cast(char *, b) - HEADER)
+#define setsize(newblock, size)	(*cast(size_t *, newblock) = size)
+#define checkblocksize(b, size) (size == (*cast(size_t *, blockhead(b))))
+#define fillmem(mem,size)	memset(mem, -MARK, size)
+#else
+/* external memory check: don't do it twice */
+#define HEADER		0
+#define MARKSIZE	0
+#define blockhead(b)	(b)
+#define setsize(newblock, size)	/* empty */
+#define checkblocksize(b,size)	(1)
+#define fillmem(mem,size)	/* empty */
+#endif
+
+
+Memcontrol memcontrol = {0L, 0L, 0L, ULONG_MAX};
+
+
+static void *checkblock (void *block, size_t size) {
+  void *b = blockhead(block);
+  int i;
+  for (i=0;i<MARKSIZE;i++)
+    lua_assert(*(cast(char *, b)+HEADER+size+i) == MARK+i); /* corrupted block? */
+  return b;
+}
+
+
+static void freeblock (Memcontrol *mc, void *block, size_t size) {
+  if (block) {
+    lua_assert(checkblocksize(block, size));
+    block = checkblock(block, size);
+    fillmem(block, size+HEADER+MARKSIZE);  /* erase block */
+    free(block);  /* free original block */
+    mc->numblocks--;
+    mc->total -= size;
+  }
+}
+
+
+void *debug_realloc (void *ud, void *block, size_t oldsize, size_t size) {
+  Memcontrol *mc = cast(Memcontrol *, ud);
+  lua_assert(oldsize == 0 || checkblocksize(block, oldsize));
+  if (size == 0) {
+    freeblock(mc, block, oldsize);
+    return NULL;
+  }
+  else if (size > oldsize && mc->total+size-oldsize > mc->memlimit)
+    return NULL;  /* to test memory allocation errors */
+  else {
+    void *newblock;
+    int i;
+    size_t realsize = HEADER+size+MARKSIZE;
+    size_t commonsize = (oldsize < size) ? oldsize : size;
+    if (realsize < size) return NULL;  /* overflow! */
+    newblock = malloc(realsize);  /* alloc a new block */
+    if (newblock == NULL) return NULL;
+    if (block) {
+      memcpy(cast(char *, newblock)+HEADER, block, commonsize);
+      freeblock(mc, block, oldsize);  /* erase (and check) old copy */
+    }
+    /* initialize new part of the block with something `weird' */
+    fillmem(cast(char *, newblock)+HEADER+commonsize, size-commonsize);
+    mc->total += size;
+    if (mc->total > mc->maxmem)
+      mc->maxmem = mc->total;
+    mc->numblocks++;
+    setsize(newblock, size);
+    for (i=0;i<MARKSIZE;i++)
+      *(cast(char *, newblock)+HEADER+size+i) = cast(char, MARK+i);
+    return cast(char *, newblock)+HEADER;
+  }
+}
+
+
+/* }====================================================================== */
+
+
+
+/*
+** {======================================================
+** Functions to check memory consistency
+** =======================================================
+*/
+
+static int testobjref1 (global_State *g, GCObject *f, GCObject *t) {
+  if (isdead(g,t)) return 0;
+  if (g->gcstate == GCSpropagate)
+    return !isblack(f) || !iswhite(t);
+  else if (g->gcstate == GCSfinalize)
+    return iswhite(f);
+  else
+    return 1;
+}
+
+
+static void printobj (global_State *g, GCObject *o) {
+  int i = 0;
+  GCObject *p;
+  for (p = g->rootgc; p != o && p != NULL; p = p->gch.next) i++;
+  if (p == NULL) i = -1;
+  printf("%d:%s(%p)-%c(%02X)", i, luaT_typenames[o->gch.tt], (void *)o,
+           isdead(g,o)?'d':isblack(o)?'b':iswhite(o)?'w':'g', o->gch.marked);
+}
+
+
+static int testobjref (global_State *g, GCObject *f, GCObject *t) {
+  int r = testobjref1(g,f,t);
+  if (!r) {
+    printf("%d(%02X) - ", g->gcstate, g->currentwhite);
+    printobj(g, f);
+    printf("\t-> ");
+    printobj(g, t);
+    printf("\n");
+  }
+  return r;
+}
+
+#define checkobjref(g,f,t) lua_assert(testobjref(g,f,obj2gco(t)))
+
+#define checkvalref(g,f,t) lua_assert(!iscollectable(t) || \
+	((ttype(t) == (t)->value.gc->gch.tt) && testobjref(g,f,gcvalue(t))))
+
+
+
+static void checktable (global_State *g, Table *h) {
+  int i;
+  int weakkey = 0;
+  int weakvalue = 0;
+  const TValue *mode;
+  GCObject *hgc = obj2gco(h);
+  if (h->metatable)
+    checkobjref(g, hgc, h->metatable);
+  mode = gfasttm(g, h->metatable, TM_MODE);
+  if (mode && ttisstring(mode)) {  /* is there a weak mode? */
+    weakkey = (strchr(svalue(mode), 'k') != NULL);
+    weakvalue = (strchr(svalue(mode), 'v') != NULL);
+  }
+  i = h->sizearray;
+  while (i--)
+    checkvalref(g, hgc, &h->array[i]);
+  i = sizenode(h);
+  while (i--) {
+    Node *n = gnode(h, i);
+    if (!ttisnil(gval(n))) {
+      lua_assert(!ttisnil(gkey(n)));
+      checkvalref(g, hgc, gkey(n));
+      checkvalref(g, hgc, gval(n));
+    }
+  }
+}
+
+
+/*
+** All marks are conditional because a GC may happen while the
+** prototype is still being created
+*/
+static void checkproto (global_State *g, Proto *f) {
+  int i;
+  GCObject *fgc = obj2gco(f);
+  if (f->source) checkobjref(g, fgc, f->source);
+  for (i=0; i<f->sizek; i++) {
+    if (ttisstring(f->k+i))
+      checkobjref(g, fgc, rawtsvalue(f->k+i));
+  }
+  for (i=0; i<f->sizeupvalues; i++) {
+    if (f->upvalues[i])
+      checkobjref(g, fgc, f->upvalues[i]);
+  }
+  for (i=0; i<f->sizep; i++) {
+    if (f->p[i])
+      checkobjref(g, fgc, f->p[i]);
+  }
+  for (i=0; i<f->sizelocvars; i++) {
+    if (f->locvars[i].varname)
+      checkobjref(g, fgc, f->locvars[i].varname);
+  }
+}
+
+
+
+static void checkclosure (global_State *g, Closure *cl) {
+  GCObject *clgc = obj2gco(cl);
+  checkobjref(g, clgc, cl->l.env);
+  if (cl->c.isC) {
+    int i;
+    for (i=0; i<cl->c.nupvalues; i++)
+      checkvalref(g, clgc, &cl->c.upvalue[i]);
+  }
+  else {
+    int i;
+    lua_assert(cl->l.nupvalues == cl->l.p->nups);
+    checkobjref(g, clgc, cl->l.p);
+    for (i=0; i<cl->l.nupvalues; i++) {
+      if (cl->l.upvals[i]) {
+        lua_assert(cl->l.upvals[i]->tt == LUA_TUPVAL);
+        checkobjref(g, clgc, cl->l.upvals[i]);
+      }
+    }
+  }
+}
+
+
+static void checkstack (global_State *g, lua_State *L1) {
+  StkId o;
+  CallInfo *ci;
+  GCObject *uvo;
+  lua_assert(!isdead(g, obj2gco(L1)));
+  for (uvo = L1->openupval; uvo != NULL; uvo = uvo->gch.next) {
+    UpVal *uv = gco2uv(uvo);
+    lua_assert(uv->v != &uv->u.value);  /* must be open */
+    lua_assert(!isblack(uvo));  /* open upvalues cannot be black */
+  }
+  checkliveness(g, gt(L1));
+  if (L1->base_ci) {
+    for (ci = L1->base_ci; ci <= L1->ci; ci++) {
+      lua_assert(ci->top <= L1->stack_last);
+      lua_assert(lua_checkpc(L1, ci));
+    }
+  }
+  else lua_assert(L1->size_ci == 0);
+  if (L1->stack) {
+    for (o = L1->stack; o < L1->top; o++)
+      checkliveness(g, o);
+  }
+  else lua_assert(L1->stacksize == 0);
+}
+
+
+static void checkobject (global_State *g, GCObject *o) {
+  if (isdead(g, o))
+/*    lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep);*/
+{ if (!(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep))
+printf(">>> %d  %s  %02x\n", g->gcstate, luaT_typenames[o->gch.tt], o->gch.marked);
+}
+  else {
+    if (g->gcstate == GCSfinalize)
+      lua_assert(iswhite(o));
+    switch (o->gch.tt) {
+      case LUA_TUPVAL: {
+        UpVal *uv = gco2uv(o);
+        lua_assert(uv->v == &uv->u.value);  /* must be closed */
+        lua_assert(!isgray(o));  /* closed upvalues are never gray */
+        checkvalref(g, o, uv->v);
+        break;
+      }
+      case LUA_TUSERDATA: {
+        Table *mt = gco2u(o)->metatable;
+        if (mt) checkobjref(g, o, mt);
+        break;
+      }
+      case LUA_TTABLE: {
+        checktable(g, gco2h(o));
+        break;
+      }
+      case LUA_TTHREAD: {
+        checkstack(g, gco2th(o));
+        break;
+      }
+      case LUA_TFUNCTION: {
+        checkclosure(g, gco2cl(o));
+        break;
+      }
+      case LUA_TPROTO: {
+        checkproto(g, gco2p(o));
+        break;
+      }
+      default: lua_assert(0);
+    }
+  }
+}
+
+
+int lua_checkpc (lua_State *L, pCallInfo ci) {
+  if (ci == L->base_ci || !f_isLua(ci)) return 1;
+  else {
+    Proto *p = ci_func(ci)->l.p;
+    if (ci < L->ci)
+      return p->code <= ci->savedpc && ci->savedpc <= p->code + p->sizecode;
+    else
+      return p->code <= L->savedpc && L->savedpc <= p->code + p->sizecode;
+  }
+}
+
+
+int lua_checkmemory (lua_State *L) {
+  global_State *g = G(L);
+  GCObject *o;
+  UpVal *uv;
+  checkstack(g, g->mainthread);
+  for (o = g->rootgc; o != obj2gco(g->mainthread); o = o->gch.next)
+    checkobject(g, o);
+  for (o = o->gch.next; o != NULL; o = o->gch.next) {
+    lua_assert(o->gch.tt == LUA_TUSERDATA);
+    checkobject(g, o);
+  }
+  for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) {
+    lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
+    lua_assert(uv->v != &uv->u.value);  /* must be open */
+    lua_assert(!isblack(obj2gco(uv)));  /* open upvalues are never black */
+    checkvalref(g, obj2gco(uv), uv->v);
+  }
+  return 0;
+}
+
+/* }====================================================== */
+
+
+
+/*
+** {======================================================
+** Disassembler
+** =======================================================
+*/
+
+
+static char *buildop (Proto *p, int pc, char *buff) {
+  Instruction i = p->code[pc];
+  OpCode o = GET_OPCODE(i);
+  const char *name = luaP_opnames[o];
+  int line = getline(p, pc);
+  sprintf(buff, "(%4d) %4d - ", line, pc);
+  switch (getOpMode(o)) {
+    case iABC:
+      sprintf(buff+strlen(buff), "%-12s%4d %4d %4d", name,
+              GETARG_A(i), GETARG_B(i), GETARG_C(i));
+      break;
+    case iABx:
+      sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_Bx(i));
+      break;
+    case iAsBx:
+      sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_sBx(i));
+      break;
+  }
+  return buff;
+}
+
+
+#if 0
+void luaI_printcode (Proto *pt, int size) {
+  int pc;
+  for (pc=0; pc<size; pc++) {
+    char buff[100];
+    printf("%s\n", buildop(pt, pc, buff));
+  }
+  printf("-------\n");
+}
+#endif
+
+
+static int listcode (lua_State *L) {
+  int pc;
+  Proto *p;
+  luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
+                 1, "Lua function expected");
+  p = clvalue(obj_at(L, 1))->l.p;
+  lua_newtable(L);
+  setnameval(L, "maxstack", p->maxstacksize);
+  setnameval(L, "numparams", p->numparams);
+  for (pc=0; pc<p->sizecode; pc++) {
+    char buff[100];
+    lua_pushinteger(L, pc+1);
+    lua_pushstring(L, buildop(p, pc, buff));
+    lua_settable(L, -3);
+  }
+  return 1;
+}
+
+
+static int listk (lua_State *L) {
+  Proto *p;
+  int i;
+  luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
+                 1, "Lua function expected");
+  p = clvalue(obj_at(L, 1))->l.p;
+  lua_createtable(L, p->sizek, 0);
+  for (i=0; i<p->sizek; i++) {
+    luaA_pushobject(L, p->k+i);
+    lua_rawseti(L, -2, i+1);
+  }
+  return 1;
+}
+
+
+static int listlocals (lua_State *L) {
+  Proto *p;
+  int pc = luaL_checkint(L, 2) - 1;
+  int i = 0;
+  const char *name;
+  luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
+                 1, "Lua function expected");
+  p = clvalue(obj_at(L, 1))->l.p;
+  while ((name = luaF_getlocalname(p, ++i, pc)) != NULL)
+    lua_pushstring(L, name);
+  return i-1;
+}
+
+/* }====================================================== */
+
+
+
+
+static int get_limits (lua_State *L) {
+  lua_createtable(L, 0, 5);
+  setnameval(L, "BITS_INT", LUAI_BITSINT);
+  setnameval(L, "LFPF", LFIELDS_PER_FLUSH);
+  setnameval(L, "MAXVARS", LUAI_MAXVARS);
+  setnameval(L, "MAXSTACK", MAXSTACK);
+  setnameval(L, "MAXUPVALUES", LUAI_MAXUPVALUES);
+  setnameval(L, "NUM_OPCODES", NUM_OPCODES);
+  return 1;
+}
+
+
+static int mem_query (lua_State *L) {
+  if (lua_isnone(L, 1)) {
+    lua_pushinteger(L, memcontrol.total);
+    lua_pushinteger(L, memcontrol.numblocks);
+    lua_pushinteger(L, memcontrol.maxmem);
+    return 3;
+  }
+  else {
+    memcontrol.memlimit = luaL_checkint(L, 1);
+    return 0;
+  }
+}
+
+
+static int settrick (lua_State *L) {
+  Trick = lua_tointeger(L, 1);
+  return 0;
+}
+
+
+/*static int set_gcstate (lua_State *L) {
+  static const char *const state[] = {"propagate", "sweep", "finalize"};
+  return 0;
+}*/
+
+
+static int get_gccolor (lua_State *L) {
+  TValue *o;
+  luaL_checkany(L, 1);
+  o = obj_at(L, 1);
+  if (!iscollectable(o))
+    lua_pushstring(L, "no collectable");
+  else
+    lua_pushstring(L, iswhite(gcvalue(o)) ? "white" :
+                      isblack(gcvalue(o)) ? "black" : "grey");
+  return 1;
+}
+
+
+static int gcstate (lua_State *L) {
+  switch(G(L)->gcstate) {
+    case GCSpropagate: lua_pushstring(L, "propagate"); break;
+    case GCSsweepstring: lua_pushstring(L, "sweep strings"); break;
+    case GCSsweep: lua_pushstring(L, "sweep"); break;
+    case GCSfinalize: lua_pushstring(L, "finalize"); break;
+  }
+  return 1;
+}
+
+
+static int hash_query (lua_State *L) {
+  if (lua_isnone(L, 2)) {
+    luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "string expected");
+    lua_pushinteger(L, tsvalue(obj_at(L, 1))->hash);
+  }
+  else {
+    TValue *o = obj_at(L, 1);
+    Table *t;
+    luaL_checktype(L, 2, LUA_TTABLE);
+    t = hvalue(obj_at(L, 2));
+    lua_pushinteger(L, luaH_mainposition(t, o) - t->node);
+  }
+  return 1;
+}
+
+
+static int stacklevel (lua_State *L) {
+  unsigned long a = 0;
+  lua_pushinteger(L, (L->top - L->stack));
+  lua_pushinteger(L, (L->stack_last - L->stack));
+  lua_pushinteger(L, (L->ci - L->base_ci));
+  lua_pushinteger(L, (L->end_ci - L->base_ci));
+  lua_pushinteger(L, (unsigned long)&a);
+  return 5;
+}
+
+
+static int table_query (lua_State *L) {
+  const Table *t;
+  int i = luaL_optint(L, 2, -1);
+  luaL_checktype(L, 1, LUA_TTABLE);
+  t = hvalue(obj_at(L, 1));
+  if (i == -1) {
+    lua_pushinteger(L, t->sizearray);
+    lua_pushinteger(L, luaH_isdummy(t->node) ? 0 : sizenode(t));
+    lua_pushinteger(L, t->lastfree - t->node);
+  }
+  else if (i < t->sizearray) {
+    lua_pushinteger(L, i);
+    luaA_pushobject(L, &t->array[i]);
+    lua_pushnil(L);
+  }
+  else if ((i -= t->sizearray) < sizenode(t)) {
+    if (!ttisnil(gval(gnode(t, i))) ||
+        ttisnil(gkey(gnode(t, i))) ||
+        ttisnumber(gkey(gnode(t, i)))) {
+      luaA_pushobject(L, key2tval(gnode(t, i)));
+    }
+    else
+      lua_pushliteral(L, "<undef>");
+    luaA_pushobject(L, gval(gnode(t, i)));
+    if (gnext(&t->node[i]))
+      lua_pushinteger(L, gnext(&t->node[i]) - t->node);
+    else
+      lua_pushnil(L);
+  }
+  return 3;
+}
+
+
+static int string_query (lua_State *L) {
+  stringtable *tb = &G(L)->strt;
+  int s = luaL_optint(L, 2, 0) - 1;
+  if (s==-1) {
+    lua_pushinteger(L ,tb->nuse);
+    lua_pushinteger(L ,tb->size);
+    return 2;
+  }
+  else if (s < tb->size) {
+    GCObject *ts;
+    int n = 0;
+    for (ts = tb->hash[s]; ts; ts = ts->gch.next) {
+      setsvalue2s(L, L->top, gco2ts(ts));
+      incr_top(L);
+      n++;
+    }
+    return n;
+  }
+  return 0;
+}
+
+
+static int tref (lua_State *L) {
+  int level = lua_gettop(L);
+  int lock = luaL_optint(L, 2, 1);
+  luaL_checkany(L, 1);
+  lua_pushvalue(L, 1);
+  lua_pushinteger(L, lua_ref(L, lock));
+  lua_assert(lua_gettop(L) == level+1);  /* +1 for result */
+  return 1;
+}
+
+static int getref (lua_State *L) {
+  int level = lua_gettop(L);
+  lua_getref(L, luaL_checkint(L, 1));
+  lua_assert(lua_gettop(L) == level+1);
+  return 1;
+}
+
+static int unref (lua_State *L) {
+  int level = lua_gettop(L);
+  lua_unref(L, luaL_checkint(L, 1));
+  lua_assert(lua_gettop(L) == level);
+  return 0;
+}
+
+
+static int upvalue (lua_State *L) {
+  int n = luaL_checkint(L, 2);
+  luaL_checktype(L, 1, LUA_TFUNCTION);
+  if (lua_isnone(L, 3)) {
+    const char *name = lua_getupvalue(L, 1, n);
+    if (name == NULL) return 0;
+    lua_pushstring(L, name);
+    return 2;
+  }
+  else {
+    const char *name = lua_setupvalue(L, 1, n);
+    lua_pushstring(L, name);
+    return 1;
+  }
+}
+
+
+static int newuserdata (lua_State *L) {
+  size_t size = luaL_checkint(L, 1);
+  char *p = cast(char *, lua_newuserdata(L, size));
+  while (size--) *p++ = '\0';
+  return 1;
+}
+
+
+static int pushuserdata (lua_State *L) {
+  lua_pushlightuserdata(L, cast(void *, luaL_checkint(L, 1)));
+  return 1;
+}
+
+
+static int udataval (lua_State *L) {
+  lua_pushinteger(L, cast(long, lua_touserdata(L, 1)));
+  return 1;
+}
+
+
+static int doonnewstack (lua_State *L) {
+  lua_State *L1 = lua_newthread(L);
+  size_t l;
+  const char *s = luaL_checklstring(L, 1, &l);
+  int status = luaL_loadbuffer(L1, s, l, s);
+  if (status == 0)
+    status = lua_pcall(L1, 0, 0, 0);
+  lua_pushinteger(L, status);
+  return 1;
+}
+
+
+static int s2d (lua_State *L) {
+  lua_pushnumber(L, *cast(const double *, luaL_checkstring(L, 1)));
+  return 1;
+}
+
+
+static int d2s (lua_State *L) {
+  double d = luaL_checknumber(L, 1);
+  lua_pushlstring(L, cast(char *, &d), sizeof(d));
+  return 1;
+}
+
+
+static int num2int (lua_State *L) {
+  lua_pushinteger(L, lua_tointeger(L, 1));
+  return 1;
+}
+
+
+static int newstate (lua_State *L) {
+  void *ud;
+  lua_Alloc f = lua_getallocf(L, &ud);
+  lua_State *L1 = lua_newstate(f, ud);
+  if (L1)
+    lua_pushinteger(L, (unsigned long)L1);
+  else
+    lua_pushnil(L);
+  return 1;
+}
+
+
+static int loadlib (lua_State *L) {
+  static const luaL_Reg libs[] = {
+    {"baselibopen", luaopen_base},
+    {"dblibopen", luaopen_debug},
+    {"iolibopen", luaopen_io},
+    {"mathlibopen", luaopen_math},
+    {"strlibopen", luaopen_string},
+    {"tablibopen", luaopen_table},
+    {"packageopen", luaopen_package},
+    {NULL, NULL}
+  };
+  lua_State *L1 = cast(lua_State *,
+                       cast(unsigned long, luaL_checknumber(L, 1)));
+  lua_pushvalue(L1, LUA_GLOBALSINDEX);
+  luaL_register(L1, NULL, libs);
+  return 0;
+}
+
+static int closestate (lua_State *L) {
+  lua_State *L1 = cast(lua_State *, cast(unsigned long, luaL_checknumber(L, 1)));
+  lua_close(L1);
+  return 0;
+}
+
+static int doremote (lua_State *L) {
+  lua_State *L1 = cast(lua_State *,cast(unsigned long,luaL_checknumber(L, 1)));
+  size_t lcode;
+  const char *code = luaL_checklstring(L, 2, &lcode);
+  int status;
+  lua_settop(L1, 0);
+  status = luaL_loadbuffer(L1, code, lcode, code);
+  if (status == 0)
+    status = lua_pcall(L1, 0, LUA_MULTRET, 0);
+  if (status != 0) {
+    lua_pushnil(L);
+    lua_pushinteger(L, status);
+    lua_pushstring(L, lua_tostring(L1, -1));
+    return 3;
+  }
+  else {
+    int i = 0;
+    while (!lua_isnone(L1, ++i))
+      lua_pushstring(L, lua_tostring(L1, i));
+    lua_pop(L1, i-1);
+    return i-1;
+  }
+}
+
+
+static int log2_aux (lua_State *L) {
+  lua_pushinteger(L, luaO_log2(luaL_checkint(L, 1)));
+  return 1;
+}
+
+static int int2fb_aux (lua_State *L) {
+  int b = luaO_int2fb(luaL_checkint(L, 1));
+  lua_pushinteger(L, b);
+  lua_pushinteger(L, luaO_fb2int(b));
+  return 2;
+}
+
+
+
+/*
+** {======================================================
+** function to test the API with C. It interprets a kind of assembler
+** language with calls to the API, so the test can be driven by Lua code
+** =======================================================
+*/
+
+static const char *const delimits = " \t\n,;";
+
+static void skip (const char **pc) {
+  while (**pc != '\0' && strchr(delimits, **pc)) (*pc)++;
+}
+
+static int getnum_aux (lua_State *L, const char **pc) {
+  int res = 0;
+  int sig = 1;
+  skip(pc);
+  if (**pc == '.') {
+    res = cast_int(lua_tonumber(L, -1));
+    lua_pop(L, 1);
+    (*pc)++;
+    return res;
+  }
+  else if (**pc == '-') {
+    sig = -1;
+    (*pc)++;
+  }
+  while (isdigit(cast_int(**pc))) res = res*10 + (*(*pc)++) - '0';
+  return sig*res;
+}
+
+static const char *getname_aux (char *buff, const char **pc) {
+  int i = 0;
+  skip(pc);
+  while (**pc != '\0' && !strchr(delimits, **pc))
+    buff[i++] = *(*pc)++;
+  buff[i] = '\0';
+  return buff;
+}
+
+
+static int getindex_aux (lua_State *L, const char **pc) {
+  skip(pc);
+  switch (*(*pc)++) {
+    case 'R': return LUA_REGISTRYINDEX;
+    case 'G': return LUA_GLOBALSINDEX;
+    case 'E': return LUA_ENVIRONINDEX;
+    case 'U': return lua_upvalueindex(getnum_aux(L, pc));
+    default: (*pc)--; return getnum_aux(L, pc);
+  }
+}
+
+#define EQ(s1)	(strcmp(s1, inst) == 0)
+
+#define getnum	(getnum_aux(L, &pc))
+#define getname	(getname_aux(buff, &pc))
+#define getindex (getindex_aux(L, &pc))
+
+
+static int testC (lua_State *L) {
+  char buff[30];
+  lua_State *L1;
+  const char *pc;
+  if (lua_isnumber(L, 1)) {
+    L1 = cast(lua_State *,cast(unsigned long,luaL_checknumber(L, 1)));
+    pc = luaL_checkstring(L, 2);
+  }
+  else {
+    L1 = L;
+    pc = luaL_checkstring(L, 1);
+  }
+  for (;;) {
+    const char *inst = getname;
+    if EQ("") return 0;
+    else if EQ("isnumber") {
+      lua_pushinteger(L1, lua_isnumber(L1, getindex));
+    }
+    else if EQ("isstring") {
+      lua_pushinteger(L1, lua_isstring(L1, getindex));
+    }
+    else if EQ("istable") {
+      lua_pushinteger(L1, lua_istable(L1, getindex));
+    }
+    else if EQ("iscfunction") {
+      lua_pushinteger(L1, lua_iscfunction(L1, getindex));
+    }
+    else if EQ("isfunction") {
+      lua_pushinteger(L1, lua_isfunction(L1, getindex));
+    }
+    else if EQ("isuserdata") {
+      lua_pushinteger(L1, lua_isuserdata(L1, getindex));
+    }
+    else if EQ("isudataval") {
+      lua_pushinteger(L1, lua_islightuserdata(L1, getindex));
+    }
+    else if EQ("isnil") {
+      lua_pushinteger(L1, lua_isnil(L1, getindex));
+    }
+    else if EQ("isnull") {
+      lua_pushinteger(L1, lua_isnone(L1, getindex));
+    }
+    else if EQ("tonumber") {
+      lua_pushnumber(L1, lua_tonumber(L1, getindex));
+    }
+    else if EQ("tostring") {
+      const char *s = lua_tostring(L1, getindex);
+      lua_pushstring(L1, s);
+    }
+    else if EQ("objsize") {
+      lua_pushinteger(L1, lua_objlen(L1, getindex));
+    }
+    else if EQ("tocfunction") {
+      lua_pushcfunction(L1, lua_tocfunction(L1, getindex));
+    }
+    else if EQ("return") {
+      return getnum;
+    }
+    else if EQ("gettop") {
+      lua_pushinteger(L1, lua_gettop(L1));
+    }
+    else if EQ("settop") {
+      lua_settop(L1, getnum);
+    }
+    else if EQ("pop") {
+      lua_pop(L1, getnum);
+    }
+    else if EQ("pushnum") {
+      lua_pushinteger(L1, getnum);
+    }
+    else if EQ("pushstring") {
+      lua_pushstring(L1, getname);
+    }
+    else if EQ("pushnil") {
+      lua_pushnil(L1);
+    }
+    else if EQ("pushbool") {
+      lua_pushboolean(L1, getnum);
+    }
+    else if EQ("newuserdata") {
+      lua_newuserdata(L1, getnum);
+    }
+    else if EQ("tobool") {
+      lua_pushinteger(L1, lua_toboolean(L1, getindex));
+    }
+    else if EQ("pushvalue") {
+      lua_pushvalue(L1, getindex);
+    }
+    else if EQ("pushcclosure") {
+      lua_pushcclosure(L1, testC, getnum);
+    }
+    else if EQ("remove") {
+      lua_remove(L1, getnum);
+    }
+    else if EQ("insert") {
+      lua_insert(L1, getnum);
+    }
+    else if EQ("replace") {
+      lua_replace(L1, getindex);
+    }
+    else if EQ("gettable") {
+      lua_gettable(L1, getindex);
+    }
+    else if EQ("settable") {
+      lua_settable(L1, getindex);
+    }
+    else if EQ("next") {
+      lua_next(L1, -2);
+    }
+    else if EQ("concat") {
+      lua_concat(L1, getnum);
+    }
+    else if EQ("lessthan") {
+      int a = getindex;
+      lua_pushboolean(L1, lua_lessthan(L1, a, getindex));
+    }
+    else if EQ("equal") {
+      int a = getindex;
+      lua_pushboolean(L1, lua_equal(L1, a, getindex));
+    }
+    else if EQ("rawcall") {
+      int narg = getnum;
+      int nres = getnum;
+      lua_call(L1, narg, nres);
+    }
+    else if EQ("call") {
+      int narg = getnum;
+      int nres = getnum;
+      lua_pcall(L1, narg, nres, 0);
+    }
+    else if EQ("loadstring") {
+      size_t sl;
+      const char *s = luaL_checklstring(L1, getnum, &sl);
+      luaL_loadbuffer(L1, s, sl, s);
+    }
+    else if EQ("loadfile") {
+      luaL_loadfile(L1, luaL_checkstring(L1, getnum));
+    }
+    else if EQ("setmetatable") {
+      lua_setmetatable(L1, getindex);
+    }
+    else if EQ("getmetatable") {
+      if (lua_getmetatable(L1, getindex) == 0)
+        lua_pushnil(L1);
+    }
+    else if EQ("type") {
+      lua_pushstring(L1, luaL_typename(L1, getnum));
+    }
+    else if EQ("getn") {
+      int i = getindex;
+      lua_pushinteger(L1, luaL_getn(L1, i));
+    }
+#ifndef luaL_setn
+    else if EQ("setn") {
+      int i = getindex;
+      int n = cast_int(lua_tonumber(L1, -1));
+      luaL_setn(L1, i, n);
+      lua_pop(L1, 1);
+    }
+#endif
+    else if EQ("throw") {
+#if defined(__cplusplus)
+static struct X { int x; } x;
+      throw x;
+#else
+      luaL_error(L1, "C++");
+#endif
+      break;
+    }
+    else luaL_error(L, "unknown instruction %s", buff);
+  }
+  return 0;
+}
+
+/* }====================================================== */
+
+
+/*
+** {======================================================
+** tests for yield inside hooks
+** =======================================================
+*/
+
+static void yieldf (lua_State *L, lua_Debug *ar) {
+  lua_yield(L, 0);
+}
+
+static int setyhook (lua_State *L) {
+  if (lua_isnoneornil(L, 1))
+    lua_sethook(L, NULL, 0, 0);  /* turn off hooks */
+  else {
+    const char *smask = luaL_checkstring(L, 1);
+    int count = luaL_optint(L, 2, 0);
+    int mask = 0;
+    if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
+    if (count > 0) mask |= LUA_MASKCOUNT;
+    lua_sethook(L, yieldf, mask, count);
+  }
+  return 0;
+}
+
+
+static int coresume (lua_State *L) {
+  int status;
+  lua_State *co = lua_tothread(L, 1);
+  luaL_argcheck(L, co, 1, "coroutine expected");
+  status = lua_resume(co, 0);
+  if (status != 0) {
+    lua_pushboolean(L, 0);
+    lua_insert(L, -2);
+    return 2;  /* return false + error message */
+  }
+  else {
+    lua_pushboolean(L, 1);
+    return 1;
+  }
+}
+
+/* }====================================================== */
+
+
+
+/*
+** {======================================================
+** tests auxlib functions
+** =======================================================
+*/
+
+static int auxgsub (lua_State *L) {
+  const char *s1 = luaL_checkstring(L, 1);
+  const char *s2 = luaL_checkstring(L, 2);
+  const char *s3 = luaL_checkstring(L, 3);
+  lua_settop(L, 3);
+  luaL_gsub(L, s1, s2, s3);
+  lua_assert(lua_gettop(L) == 4);
+  return 1;
+}
+
+
+/* }====================================================== */
+
+
+
+static const struct luaL_Reg tests_funcs[] = {
+  {"checkmemory", lua_checkmemory},
+  {"closestate", closestate},
+  {"d2s", d2s},
+  {"doonnewstack", doonnewstack},
+  {"doremote", doremote},
+  {"gccolor", get_gccolor},
+  {"gcstate", gcstate},
+  {"getref", getref},
+  {"gsub", auxgsub},
+  {"hash", hash_query},
+  {"int2fb", int2fb_aux},
+  {"limits", get_limits},
+  {"listcode", listcode},
+  {"listk", listk},
+  {"listlocals", listlocals},
+  {"loadlib", loadlib},
+  {"log2", log2_aux},
+  {"newstate", newstate},
+  {"newuserdata", newuserdata},
+  {"num2int", num2int},
+  {"pushuserdata", pushuserdata},
+  {"querystr", string_query},
+  {"querytab", table_query},
+  {"ref", tref},
+  {"resume", coresume},
+  {"s2d", s2d},
+  {"setyhook", setyhook},
+  {"stacklevel", stacklevel},
+  {"testC", testC},
+  {"totalmem", mem_query},
+  {"trick", settrick},
+  {"udataval", udataval},
+  {"unref", unref},
+  {"upvalue", upvalue},
+  {NULL, NULL}
+};
+
+
+int luaB_opentests (lua_State *L) {
+  void *ud;
+  lua_assert(lua_getallocf(L, &ud) == debug_realloc);
+  lua_assert(ud == cast(void *, &memcontrol));
+  lua_setallocf(L, lua_getallocf(L, NULL), ud);
+  lua_state = L;  /* keep first state to be opened */
+  luaL_register(L, "T", tests_funcs);
+  return 0;
+}
+
+
+#undef main
+int main (int argc, char *argv[]) {
+  int ret;
+  char *limit = getenv("MEMLIMIT");
+  if (limit)
+    memcontrol.memlimit = strtoul(limit, NULL, 10);
+  ret = l_main(argc, argv);
+  lua_assert(memcontrol.numblocks == 0);
+  lua_assert(memcontrol.total == 0);
+  return ret;
+}
+
+#endif
diff --git a/test/PUC-Lua-5.1-tests/etc/ltests.h b/test/PUC-Lua-5.1-tests/etc/ltests.h
new file mode 100644
index 0000000..e570212
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/etc/ltests.h
@@ -0,0 +1,92 @@
+/*
+** $Id: ltests.h,v 2.17 2005/12/27 17:12:00 roberto Exp $
+** Internal Header for Debugging of the Lua Implementation
+** See Copyright Notice in lua.h
+*/
+
+#ifndef ltests_h
+#define ltests_h
+
+
+#include <stdlib.h>
+
+
+#define LUA_DEBUG
+
+#undef NDEBUG
+#include <assert.h>
+#define lua_assert(c)           assert(c)
+
+
+/* to avoid warnings, and to make sure value is really unused */
+#define UNUSED(x)       (x=0, (void)(x))
+
+
+/* memory allocator control variables */
+typedef struct Memcontrol {
+  unsigned long numblocks;
+  unsigned long total;
+  unsigned long maxmem;
+  unsigned long memlimit;
+} Memcontrol;
+
+LUAI_DATA Memcontrol memcontrol;
+
+
+/*
+** generic variable for debug tricks
+*/
+LUAI_DATA int Trick;
+
+
+void *debug_realloc (void *ud, void *block, size_t osize, size_t nsize);
+
+#ifdef lua_c
+#define luaL_newstate()	lua_newstate(debug_realloc, &memcontrol)
+#endif
+
+
+typedef struct CallInfo *pCallInfo;
+
+int lua_checkmemory (lua_State *L);
+int lua_checkpc (lua_State *L, pCallInfo ci);
+
+
+/* test for lock/unlock */
+#undef luai_userstateopen
+#undef luai_userstatethread
+#undef lua_lock
+#undef lua_unlock
+#undef LUAI_EXTRASPACE
+
+struct L_EXTRA { int lock; int *plock; };
+#define LUAI_EXTRASPACE		sizeof(struct L_EXTRA)
+#define getlock(l)	(cast(struct L_EXTRA *, l) - 1)
+#define luai_userstateopen(l)  \
+	(getlock(l)->lock = 0, getlock(l)->plock = &(getlock(l)->lock))
+#define luai_userstatethread(l,l1)  (getlock(l1)->plock = getlock(l)->plock)
+#define lua_lock(l)     lua_assert((*getlock(l)->plock)++ == 0)
+#define lua_unlock(l)   lua_assert(--(*getlock(l)->plock) == 0)
+
+
+int luaB_opentests (lua_State *L);
+
+#ifdef lua_c
+#define luaL_openlibs(L)	{ (luaL_openlibs)(L); luaB_opentests(L); }
+#endif
+
+
+
+/* real main will be defined at `ltests.c' */
+int l_main (int argc, char *argv[]);
+#define main	l_main
+
+
+
+/* change some sizes to give some bugs a chance */
+
+#undef LUAL_BUFFERSIZE
+#define LUAL_BUFFERSIZE		27
+#define MINSTRTABSIZE		2
+
+#endif
diff --git a/test/PUC-Lua-5.1-tests/events.lua b/test/PUC-Lua-5.1-tests/events.lua
new file mode 100644
index 0000000..5234b00
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/events.lua
@@ -0,0 +1,360 @@
+print('testing metatables')
+
+X = 20; B = 30
+
+setfenv(1, setmetatable({}, {__index=_G}))
+
+collectgarbage()
+
+X = X+10
+assert(X == 30 and _G.X == 20)
+B = false
+assert(B == false)
+B = nil
+assert(B == 30)
+
+assert(getmetatable{} == nil)
+assert(getmetatable(4) == nil)
+assert(getmetatable(nil) == nil)
+a={}; setmetatable(a, {__metatable = "xuxu",
+                    __tostring=function(x) return x.name end})
+assert(getmetatable(a) == "xuxu")
+assert(tostring(a) == nil)
+-- cannot change a protected metatable
+assert(pcall(setmetatable, a, {}) == false)
+a.name = "gororoba"
+assert(tostring(a) == "gororoba")
+
+local a, t = {10,20,30; x="10", y="20"}, {}
+assert(setmetatable(a,t) == a)
+assert(getmetatable(a) == t)
+assert(setmetatable(a,nil) == a)
+assert(getmetatable(a) == nil)
+assert(setmetatable(a,t) == a)
+
+
+function f (t, i, e)
+  assert(not e)
+  local p = rawget(t, "parent")
+  return (p and p[i]+3), "dummy return"
+end
+
+t.__index = f
+
+a.parent = {z=25, x=12, [4] = 24}
+assert(a[1] == 10 and a.z == 28 and a[4] == 27 and a.x == "10")
+
+collectgarbage()
+
+a = setmetatable({}, t)
+function f(t, i, v) rawset(t, i, v-3) end
+t.__newindex = f
+a[1] = 30; a.x = "101"; a[5] = 200
+assert(a[1] == 27 and a.x == 98 and a[5] == 197)
+
+
+local c = {}
+a = setmetatable({}, t)
+t.__newindex = c
+a[1] = 10; a[2] = 20; a[3] = 90
+assert(c[1] == 10 and c[2] == 20 and c[3] == 90)
+
+
+do
+  local a;
+  a = setmetatable({}, {__index = setmetatable({},
+                     {__index = setmetatable({},
+                     {__index = function (_,n) return a[n-3]+4, "lixo" end})})})
+  a[0] = 20
+  for i=0,10 do
+    assert(a[i*3] == 20 + i*4)
+  end
+end
+
+
+do  -- newindex
+  local foi
+  local a = {}
+  for i=1,10 do a[i] = 0; a['a'..i] = 0; end
+  setmetatable(a, {__newindex = function (t,k,v) foi=true; rawset(t,k,v) end})
+  foi = false; a[1]=0; assert(not foi)
+  foi = false; a['a1']=0; assert(not foi)
+  foi = false; a['a11']=0; assert(foi)
+  foi = false; a[11]=0; assert(foi)
+  foi = false; a[1]=nil; assert(not foi)
+  foi = false; a[1]=nil; assert(foi)
+end
+
+
+function f (t, ...) return t, {...} end
+t.__call = f
+
+do
+  local x,y = a(unpack{'a', 1})
+  assert(x==a and y[1]=='a' and y[2]==1 and y[3]==nil)
+  x,y = a()
+  assert(x==a and y[1]==nil)
+end
+
+
+local b = setmetatable({}, t)
+setmetatable(b,t)
+
+function f(op)
+  return function (...) cap = {[0] = op, ...} ; return (...) end
+end
+t.__add = f("add")
+t.__sub = f("sub")
+t.__mul = f("mul")
+t.__div = f("div")
+t.__mod = f("mod")
+t.__unm = f("unm")
+t.__pow = f("pow")
+
+assert(b+5 == b)
+assert(cap[0] == "add" and cap[1] == b and cap[2] == 5 and cap[3]==nil)
+assert(b+'5' == b)
+assert(cap[0] == "add" and cap[1] == b and cap[2] == '5' and cap[3]==nil)
+assert(5+b == 5)
+assert(cap[0] == "add" and cap[1] == 5 and cap[2] == b and cap[3]==nil)
+assert('5'+b == '5')
+assert(cap[0] == "add" and cap[1] == '5' and cap[2] == b and cap[3]==nil)
+b=b-3; assert(getmetatable(b) == t)
+assert(5-a == 5)
+assert(cap[0] == "sub" and cap[1] == 5 and cap[2] == a and cap[3]==nil)
+assert('5'-a == '5')
+assert(cap[0] == "sub" and cap[1] == '5' and cap[2] == a and cap[3]==nil)
+assert(a*a == a)
+assert(cap[0] == "mul" and cap[1] == a and cap[2] == a and cap[3]==nil)
+assert(a/0 == a)
+assert(cap[0] == "div" and cap[1] == a and cap[2] == 0 and cap[3]==nil)
+assert(a%2 == a)
+assert(cap[0] == "mod" and cap[1] == a and cap[2] == 2 and cap[3]==nil)
+assert(-a == a)
+assert(cap[0] == "unm" and cap[1] == a)
+assert(a^4 == a)
+assert(cap[0] == "pow" and cap[1] == a and cap[2] == 4 and cap[3]==nil)
+assert(a^'4' == a)
+assert(cap[0] == "pow" and cap[1] == a and cap[2] == '4' and cap[3]==nil)
+assert(4^a == 4)
+assert(cap[0] == "pow" and cap[1] == 4 and cap[2] == a and cap[3]==nil)
+assert('4'^a == '4')
+assert(cap[0] == "pow" and cap[1] == '4' and cap[2] == a and cap[3]==nil)
+
+
+t = {}
+t.__lt = function (a,b,c)
+  collectgarbage()
+  assert(c == nil)
+  if type(a) == 'table' then a = a.x end
+  if type(b) == 'table' then b = b.x end
+ return a<b, "dummy"
+end
+
+function Op(x) return setmetatable({x=x}, t) end
+
+local function test ()
+  assert(not(Op(1)<Op(1)) and (Op(1)<Op(2)) and not(Op(2)<Op(1)))
+  assert(not(Op('a')<Op('a')) and (Op('a')<Op('b')) and not(Op('b')<Op('a')))
+  assert((Op(1)<=Op(1)) and (Op(1)<=Op(2)) and not(Op(2)<=Op(1)))
+  assert((Op('a')<=Op('a')) and (Op('a')<=Op('b')) and not(Op('b')<=Op('a')))
+  assert(not(Op(1)>Op(1)) and not(Op(1)>Op(2)) and (Op(2)>Op(1)))
+  assert(not(Op('a')>Op('a')) and not(Op('a')>Op('b')) and (Op('b')>Op('a')))
+  assert((Op(1)>=Op(1)) and not(Op(1)>=Op(2)) and (Op(2)>=Op(1)))
+  assert((Op('a')>=Op('a')) and not(Op('a')>=Op('b')) and (Op('b')>=Op('a')))
+end
+
+test()
+
+t.__le = function (a,b,c)
+  assert(c == nil)
+  if type(a) == 'table' then a = a.x end
+  if type(b) == 'table' then b = b.x end
+ return a<=b, "dummy"
+end
+
+test()  -- retest comparisons, now using both `lt' and `le'
+
+
+-- test `partial order'
+
+local function Set(x)
+  local y = {}
+  for _,k in pairs(x) do y[k] = 1 end
+  return setmetatable(y, t)
+end
+
+t.__lt = function (a,b)
+  for k in pairs(a) do
+    if not b[k] then return false end
+    b[k] = nil
+  end
+  return next(b) ~= nil
+end
+
+t.__le = nil
+
+assert(Set{1,2,3} < Set{1,2,3,4})
+assert(not(Set{1,2,3,4} < Set{1,2,3,4}))
+assert((Set{1,2,3,4} <= Set{1,2,3,4}))
+assert((Set{1,2,3,4} >= Set{1,2,3,4}))
+assert((Set{1,3} <= Set{3,5}))   -- wrong!! model needs a `le' method ;-)
+
+t.__le = function (a,b)
+  for k in pairs(a) do
+    if not b[k] then return false end
+  end
+  return true
+end
+
+assert(not (Set{1,3} <= Set{3,5}))   -- now its OK!
+assert(not(Set{1,3} <= Set{3,5}))
+assert(not(Set{1,3} >= Set{3,5}))
+
+t.__eq = function (a,b)
+  for k in pairs(a) do
+    if not b[k] then return false end
+    b[k] = nil
+  end
+  return next(b) == nil
+end
+
+local s = Set{1,3,5}
+assert(s == Set{3,5,1})
+assert(not rawequal(s, Set{3,5,1}))
+assert(rawequal(s, s))
+assert(Set{1,3,5,1} == Set{3,5,1})
+assert(Set{1,3,5} ~= Set{3,5,1,6})
+t[Set{1,3,5}] = 1
+assert(t[Set{1,3,5}] == nil)   -- `__eq' is not valid for table accesses
+
+
+t.__concat = function (a,b,c)
+  assert(c == nil)
+  if type(a) == 'table' then a = a.val end
+  if type(b) == 'table' then b = b.val end
+  if A then return a..b
+  else
+    return setmetatable({val=a..b}, t)
+  end
+end
+
+c = {val="c"}; setmetatable(c, t)
+d = {val="d"}; setmetatable(d, t)
+
+A = true
+assert(c..d == 'cd')
+assert(0 .."a".."b"..c..d.."e".."f"..(5+3).."g" == "0abcdef8g")
+
+A = false
+x = c..d
+assert(getmetatable(x) == t and x.val == 'cd')
+x = 0 .."a".."b"..c..d.."e".."f".."g"
+assert(x.val == "0abcdefg")
+
+
+-- test comparison compatibilities
+local t1, t2, c, d
+t1 = {};  c = {}; setmetatable(c, t1)
+d = {}
+t1.__eq = function () return true end
+t1.__lt = function () return true end
+assert(c ~= d and not pcall(function () return c < d end))
+setmetatable(d, t1)
+assert(c == d and c < d and not(d <= c))
+t2 = {}
+t2.__eq = t1.__eq
+t2.__lt = t1.__lt
+setmetatable(d, t2)
+assert(c == d and c < d and not(d <= c))
+
+
+
+-- test for several levels of calls
+local i
+local tt = {
+  __call = function (t, ...)
+    i = i+1
+    if t.f then return t.f(...)
+    else return {...}
+    end
+  end
+}
+
+local a = setmetatable({}, tt)
+local b = setmetatable({f=a}, tt)
+local c = setmetatable({f=b}, tt)
+
+i = 0
+x = c(3,4,5)
+assert(i == 3 and x[1] == 3 and x[3] == 5)
+
+
+assert(_G.X == 20)
+assert(_G == getfenv(0))
+
+print'+'
+
+local _g = _G
+setfenv(1, setmetatable({}, {__index=function (_,k) return _g[k] end}))
+
+-- testing proxies
+assert(getmetatable(newproxy()) == nil)
+assert(getmetatable(newproxy(false)) == nil)
+
+local u = newproxy(true)
+
+getmetatable(u).__newindex = function (u,k,v)
+  getmetatable(u)[k] = v
+end
+
+getmetatable(u).__index = function (u,k)
+  return getmetatable(u)[k]
+end
+
+for i=1,10 do u[i] = i end
+for i=1,10 do assert(u[i] == i) end
+
+local k = newproxy(u)
+assert(getmetatable(k) == getmetatable(u))
+
+
+a = {}
+rawset(a, "x", 1, 2, 3)
+assert(a.x == 1 and rawget(a, "x", 3) == 1)
+
+print '+'
+
+-- testing metatables for basic types
+mt = {}
+debug.setmetatable(10, mt)
+assert(getmetatable(-2) == mt)
+mt.__index = function (a,b) return a+b end
+assert((10)[3] == 13)
+assert((10)["3"] == 13)
+debug.setmetatable(23, nil)
+assert(getmetatable(-2) == nil)
+
+debug.setmetatable(true, mt)
+assert(getmetatable(false) == mt)
+mt.__index = function (a,b) return a or b end
+assert((true)[false] == true)
+assert((false)[false] == false)
+debug.setmetatable(false, nil)
+assert(getmetatable(true) == nil)
+
+debug.setmetatable(nil, mt)
+assert(getmetatable(nil) == mt)
+mt.__add = function (a,b) return (a or 0) + (b or 0) end
+assert(10 + nil == 10)
+assert(nil + 23 == 23)
+assert(nil + nil == 0)
+debug.setmetatable(nil, nil)
+assert(getmetatable(nil) == nil)
+
+debug.setmetatable(nil, {})
+
+
+print 'OK'
+
+return 12
diff --git a/test/PUC-Lua-5.1-tests/files.lua b/test/PUC-Lua-5.1-tests/files.lua
new file mode 100644
index 0000000..903488c
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/files.lua
@@ -0,0 +1,324 @@
+
+print('testing i/o')
+
+assert(io.input(io.stdin) == io.stdin)
+assert(io.output(io.stdout) == io.stdout)
+
+
+assert(type(io.input()) == "userdata" and io.type(io.output()) == "file")
+assert(io.type(8) == nil)
+local a = {}; setmetatable(a, {})
+assert(io.type(a) == nil)
+
+local a,b,c = io.open('xuxu_nao_existe')
+assert(not a and type(b) == "string" and type(c) == "number")
+
+a,b,c = io.open('/a/b/c/d', 'w')
+assert(not a and type(b) == "string" and type(c) == "number")
+
+local file = os.tmpname()
+local otherfile = os.tmpname()
+
+assert(os.setlocale('C', 'all'))
+
+io.input(io.stdin); io.output(io.stdout);
+
+os.remove(file)
+assert(loadfile(file) == nil)
+assert(io.open(file) == nil)
+io.output(file)
+assert(io.output() ~= io.stdout)
+
+assert(io.output():seek() == 0)
+assert(io.write("alo alo"))
+assert(io.output():seek() == string.len("alo alo"))
+assert(io.output():seek("cur", -3) == string.len("alo alo")-3)
+assert(io.write("joao"))
+assert(io.output():seek("end") == string.len("alo joao"))
+
+assert(io.output():seek("set") == 0)
+
+assert(io.write('"álo"', "{a}\n", "second line\n", "third line \n"))
+assert(io.write('çfourth_line'))
+io.output(io.stdout)
+collectgarbage()  -- file should be closed by GC
+assert(io.input() == io.stdin and rawequal(io.output(), io.stdout))
+print('+')
+
+-- test GC for files
+collectgarbage()
+for i=1,120 do
+  for i=1,5 do
+    io.input(file)
+    assert(io.open(file, 'r'))
+    io.lines(file)
+  end
+  collectgarbage()
+end
+
+assert(os.rename(file, otherfile))
+assert(os.rename(file, otherfile) == nil)
+
+io.output(io.open(otherfile, "a"))
+assert(io.write("\n\n\t\t  3450\n"));
+io.close()
+
+-- test line generators
+assert(os.rename(otherfile, file))
+io.output(otherfile)
+local f = io.lines(file)
+while f() do end;
+assert(not pcall(f))  -- read lines after EOF
+assert(not pcall(f))  -- read lines after EOF
+-- copy from file to otherfile
+for l in io.lines(file) do io.write(l, "\n") end
+io.close()
+-- copy from otherfile back to file
+local f = assert(io.open(otherfile))
+assert(io.type(f) == "file")
+io.output(file)
+assert(io.output():read() == nil)
+for l in f:lines() do io.write(l, "\n") end
+assert(f:close()); io.close()
+assert(not pcall(io.close, f))   -- error trying to close again
+assert(tostring(f) == "file (closed)")
+assert(io.type(f) == "closed file")
+io.input(file)
+f = io.open(otherfile):lines()
+for l in io.lines() do assert(l == f()) end
+assert(os.remove(otherfile))
+
+io.input(file)
+do  -- test error returns
+  local a,b,c = io.input():write("xuxu")
+  assert(not a and type(b) == "string" and type(c) == "number")
+end
+assert(io.read(0) == "")   -- not eof
+assert(io.read(5, '*l') == '"álo"')
+assert(io.read(0) == "")
+assert(io.read() == "second line")
+local x = io.input():seek()
+assert(io.read() == "third line ")
+assert(io.input():seek("set", x))
+assert(io.read('*l') == "third line ")
+assert(io.read(1) == "ç")
+assert(io.read(string.len"fourth_line") == "fourth_line")
+assert(io.input():seek("cur", -string.len"fourth_line"))
+assert(io.read() == "fourth_line")
+assert(io.read() == "")  -- empty line
+assert(io.read('*n') == 3450)
+assert(io.read(1) == '\n')
+assert(io.read(0) == nil)  -- end of file
+assert(io.read(1) == nil)  -- end of file
+assert(({io.read(1)})[2] == nil)
+assert(io.read() == nil)  -- end of file
+assert(({io.read()})[2] == nil)
+assert(io.read('*n') == nil)  -- end of file
+assert(({io.read('*n')})[2] == nil)
+assert(io.read('*a') == '')  -- end of file (OK for `*a')
+assert(io.read('*a') == '')  -- end of file (OK for `*a')
+collectgarbage()
+print('+')
+io.close(io.input())
+assert(not pcall(io.read))
+
+assert(os.remove(file))
+
+local t = '0123456789'
+for i=1,12 do t = t..t; end
+assert(string.len(t) == 10*2^12)
+
+io.output(file)
+io.write("alo\n")
+io.close()
+assert(not pcall(io.write))
+local f = io.open(file, "a")
+io.output(f)
+collectgarbage()
+
+assert(io.write(' ' .. t .. ' '))
+assert(io.write(';', 'end of file\n'))
+f:flush(); io.flush()
+f:close()
+print('+')
+
+io.input(file)
+assert(io.read() == "alo")
+assert(io.read(1) == ' ')
+assert(io.read(string.len(t)) == t)
+assert(io.read(1) == ' ')
+assert(io.read(0))
+assert(io.read('*a') == ';end of file\n')
+assert(io.read(0) == nil)
+assert(io.close(io.input()))
+
+assert(os.remove(file))
+print('+')
+
+local x1 = "string\n\n\\com \"\"''coisas [[estranhas]] ]]'"
+io.output(file)
+assert(io.write(string.format("x2 = %q\n-- comment without ending EOS", x1)))
+io.close()
+assert(loadfile(file))()
+assert(x1 == x2)
+print('+')
+assert(os.remove(file))
+assert(os.remove(file) == nil)
+assert(os.remove(otherfile) == nil)
+
+io.output(file)
+assert(io.write("qualquer coisa\n"))
+assert(io.write("mais qualquer coisa"))
+io.close()
+io.output(assert(io.open(otherfile, 'wb')))
+assert(io.write("outra coisa\0\1\3\0\0\0\0\255\0"))
+io.close()
+
+local filehandle = assert(io.open(file, 'r'))
+local otherfilehandle = assert(io.open(otherfile, 'rb'))
+assert(filehandle ~= otherfilehandle)
+assert(type(filehandle) == "userdata")
+assert(filehandle:read('*l') == "qualquer coisa")
+io.input(otherfilehandle)
+assert(io.read(string.len"outra coisa") == "outra coisa")
+assert(filehandle:read('*l') == "mais qualquer coisa")
+filehandle:close();
+assert(type(filehandle) == "userdata")
+io.input(otherfilehandle)
+assert(io.read(4) == "\0\1\3\0")
+assert(io.read(3) == "\0\0\0")
+assert(io.read(0) == "")        -- 255 is not eof
+assert(io.read(1) == "\255")
+assert(io.read('*a') == "\0")
+assert(not io.read(0))
+assert(otherfilehandle == io.input())
+otherfilehandle:close()
+assert(os.remove(file))
+assert(os.remove(otherfile))
+collectgarbage()
+
+io.output(file)
+io.write[[
+ 123.4	-56e-2  not a number
+second line
+third line
+
+and the rest of the file
+]]
+io.close()
+io.input(file)
+local _,a,b,c,d,e,h,__ = io.read(1, '*n', '*n', '*l', '*l', '*l', '*a', 10)
+assert(io.close(io.input()))
+assert(_ == ' ' and __ == nil)
+assert(type(a) == 'number' and a==123.4 and b==-56e-2)
+assert(d=='second line' and e=='third line')
+assert(h==[[
+
+and the rest of the file
+]])
+assert(os.remove(file))
+collectgarbage()
+
+-- testing buffers
+do
+  local f = assert(io.open(file, "w"))
+  local fr = assert(io.open(file, "r"))
+  assert(f:setvbuf("full", 2000))
+  f:write("x")
+  assert(fr:read("*all") == "")  -- full buffer; output not written yet
+  f:close()
+  fr:seek("set")
+  assert(fr:read("*all") == "x")   -- `close' flushes it
+  f = assert(io.open(file), "w")
+  assert(f:setvbuf("no"))
+  f:write("x")
+  fr:seek("set")
+  assert(fr:read("*all") == "x")  -- no buffer; output is ready
+  f:close()
+  f = assert(io.open(file, "a"))
+  assert(f:setvbuf("line"))
+  f:write("x")
+  fr:seek("set", 1)
+  assert(fr:read("*all") == "")   -- line buffer; no output without `\n'
+  f:write("a\n")
+  fr:seek("set", 1)
+  assert(fr:read("*all") == "xa\n")  -- now we have a whole line
+  f:close(); fr:close()
+end
+
+
+-- testing large files (> BUFSIZ)
+io.output(file)
+for i=1,5001 do io.write('0123456789123') end
+io.write('\n12346')
+io.close()
+io.input(file)
+local x = io.read('*a')
+io.input():seek('set', 0)
+local y = io.read(30001)..io.read(1005)..io.read(0)..io.read(1)..io.read(100003)
+assert(x == y and string.len(x) == 5001*13 + 6)
+io.input():seek('set', 0)
+y = io.read()  -- huge line
+assert(x == y..'\n'..io.read())
+assert(io.read() == nil)
+io.close(io.input())
+assert(os.remove(file))
+x = nil; y = nil
+
+x, y = pcall(io.popen, "ls")
+if x then
+  assert(y:read("*a"))
+  assert(y:close())
+else
+  (Message or print)('\a\n >>> popen not available<<<\n\a')
+end
+
+print'+'
+
+local t = os.time()
+T = os.date("*t", t)
+loadstring(os.date([[assert(T.year==%Y and T.month==%m and T.day==%d and
+  T.hour==%H and T.min==%M and T.sec==%S and
+  T.wday==%w+1 and T.yday==%j and type(T.isdst) == 'boolean')]], t))()
+
+assert(os.time(T) == t)
+
+T = os.date("!*t", t)
+loadstring(os.date([[!assert(T.year==%Y and T.month==%m and T.day==%d and
+  T.hour==%H and T.min==%M and T.sec==%S and
+  T.wday==%w+1 and T.yday==%j and type(T.isdst) == 'boolean')]], t))()
+
+do
+  local T = os.date("*t")
+  local t = os.time(T)
+  assert(type(T.isdst) == 'boolean')
+  T.isdst = nil
+  local t1 = os.time(T)
+  assert(t == t1)   -- if isdst is absent uses correct default
+end
+
+t = os.time(T)
+T.year = T.year-1;
+local t1 = os.time(T)
+-- allow for leap years
+assert(math.abs(os.difftime(t,t1)/(24*3600) - 365) < 2)
+
+t = os.time()
+t1 = os.time(os.date("*t"))
+assert(os.difftime(t1,t) <= 2)
+
+local t1 = os.time{year=2000, month=10, day=1, hour=23, min=12, sec=17}
+local t2 = os.time{year=2000, month=10, day=1, hour=23, min=10, sec=19}
+assert(os.difftime(t1,t2) == 60*2-2)
+
+io.output(io.stdout)
+local d = os.date('%d')
+local m = os.date('%m')
+local a = os.date('%Y')
+local ds = os.date('%w') + 1
+local h = os.date('%H')
+local min = os.date('%M')
+local s = os.date('%S')
+io.write(string.format('test done on %2.2d/%2.2d/%d', d, m, a))
+io.write(string.format(', at %2.2d:%2.2d:%2.2d\n', h, min, s))
+io.write(string.format('%s\n', _VERSION))
diff --git a/test/PUC-Lua-5.1-tests/gc.lua b/test/PUC-Lua-5.1-tests/gc.lua
new file mode 100644
index 0000000..86a9f75
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/gc.lua
@@ -0,0 +1,312 @@
+print('testing garbage collection')
+
+collectgarbage()
+
+_G["while"] = 234
+
+limit = 5000
+
+
+
+contCreate = 0
+
+print('tables')
+while contCreate <= limit do
+  local a = {}; a = nil
+  contCreate = contCreate+1
+end
+
+a = "a"
+
+contCreate = 0
+print('strings')
+while contCreate <= limit do
+  a = contCreate .. "b";
+  a = string.gsub(a, '(%d%d*)', string.upper)
+  a = "a"
+  contCreate = contCreate+1
+end
+
+
+contCreate = 0
+
+a = {}
+
+print('functions')
+function a:test ()
+  while contCreate <= limit do
+    loadstring(string.format("function temp(a) return 'a%d' end", contCreate))()
+    assert(temp() == string.format('a%d', contCreate))
+    contCreate = contCreate+1
+  end
+end
+
+a:test()
+
+-- collection of functions without locals, globals, etc.
+do local f = function () end end
+
+
+print("functions with errors")
+prog = [[
+do
+  a = 10;
+  function foo(x,y)
+    a = sin(a+0.456-0.23e-12);
+    return function (z) return sin(%x+z) end
+  end
+  local x = function (w) a=a+w; end
+end
+]]
+do
+  local step = 1
+  if rawget(_G, "_soft") then step = 13 end
+  for i=1, string.len(prog), step do
+    for j=i, string.len(prog), step do
+      pcall(loadstring(string.sub(prog, i, j)))
+    end
+  end
+end
+
+print('long strings')
+x = "01234567890123456789012345678901234567890123456789012345678901234567890123456789"
+assert(string.len(x)==80)
+s = ''
+n = 0
+k = 300
+while n < k do s = s..x; n=n+1; j=tostring(n)  end
+assert(string.len(s) == k*80)
+s = string.sub(s, 1, 20000)
+s, i = string.gsub(s, '(%d%d%d%d)', math.sin)
+assert(i==20000/4)
+s = nil
+x = nil
+
+assert(_G["while"] == 234)
+
+
+local bytes = gcinfo()
+while 1 do
+  local nbytes = gcinfo()
+  if nbytes < bytes then break end   -- run until gc
+  bytes = nbytes
+  a = {}
+end
+
+
+local function dosteps (siz)
+  collectgarbage()
+  collectgarbage"stop"
+  local a = {}
+  for i=1,100 do a[i] = {{}}; local b = {} end
+  local x = gcinfo()
+  local i = 0
+  repeat
+    i = i+1
+  until collectgarbage("step", siz)
+  assert(gcinfo() < x)
+  return i
+end
+
+assert(dosteps(0) > 10)
+assert(dosteps(6) < dosteps(2))
+assert(dosteps(10000) == 1)
+assert(collectgarbage("step", 1000000) == true)
+assert(collectgarbage("step", 1000000))
+
+
+do
+  local x = gcinfo()
+  collectgarbage()
+  collectgarbage"stop"
+  repeat
+    local a = {}
+  until gcinfo() > 1000
+  collectgarbage"restart"
+  repeat
+    local a = {}
+  until gcinfo() < 1000
+end
+
+lim = 15
+a = {}
+-- fill a with `collectable' indices
+for i=1,lim do a[{}] = i end
+b = {}
+for k,v in pairs(a) do b[k]=v end
+-- remove all indices and collect them
+for n in pairs(b) do
+  a[n] = nil
+  assert(type(n) == 'table' and next(n) == nil)
+  collectgarbage()
+end
+b = nil
+collectgarbage()
+for n in pairs(a) do error'cannot be here' end
+for i=1,lim do a[i] = i end
+for i=1,lim do assert(a[i] == i) end
+
+
+print('weak tables')
+a = {}; setmetatable(a, {__mode = 'k'});
+-- fill a with some `collectable' indices
+for i=1,lim do a[{}] = i end
+-- and some non-collectable ones
+for i=1,lim do local t={}; a[t]=t end
+for i=1,lim do a[i] = i end
+for i=1,lim do local s=string.rep('@', i); a[s] = s..'#' end
+collectgarbage()
+local i = 0
+for k,v in pairs(a) do assert(k==v or k..'#'==v); i=i+1 end
+assert(i == 3*lim)
+
+a = {}; setmetatable(a, {__mode = 'v'});
+a[1] = string.rep('b', 21)
+collectgarbage()
+assert(a[1])   -- strings are *values*
+a[1] = nil
+-- fill a with some `collectable' values (in both parts of the table)
+for i=1,lim do a[i] = {} end
+for i=1,lim do a[i..'x'] = {} end
+-- and some non-collectable ones
+for i=1,lim do local t={}; a[t]=t end
+for i=1,lim do a[i+lim]=i..'x' end
+collectgarbage()
+local i = 0
+for k,v in pairs(a) do assert(k==v or k-lim..'x' == v); i=i+1 end
+assert(i == 2*lim)
+
+a = {}; setmetatable(a, {__mode = 'vk'});
+local x, y, z = {}, {}, {}
+-- keep only some items
+a[1], a[2], a[3] = x, y, z
+a[string.rep('$', 11)] = string.rep('$', 11)
+-- fill a with some `collectable' values
+for i=4,lim do a[i] = {} end
+for i=1,lim do a[{}] = i end
+for i=1,lim do local t={}; a[t]=t end
+collectgarbage()
+assert(next(a) ~= nil)
+local i = 0
+for k,v in pairs(a) do
+  assert((k == 1 and v == x) or
+         (k == 2 and v == y) or
+         (k == 3 and v == z) or k==v);
+  i = i+1
+end
+assert(i == 4)
+x,y,z=nil
+collectgarbage()
+assert(next(a) == string.rep('$', 11))
+
+
+-- testing userdata
+collectgarbage("stop")   -- stop collection
+local u = newproxy(true)
+local s = 0
+local a = {[u] = 0}; setmetatable(a, {__mode = 'vk'})
+for i=1,10 do a[newproxy(u)] = i end
+for k in pairs(a) do assert(getmetatable(k) == getmetatable(u)) end
+local a1 = {}; for k,v in pairs(a) do a1[k] = v end
+for k,v in pairs(a1) do a[v] = k end
+for i =1,10 do assert(a[i]) end
+getmetatable(u).a = a1
+getmetatable(u).u = u
+do
+  local u = u
+  getmetatable(u).__gc = function (o)
+    assert(a[o] == 10-s)
+    assert(a[10-s] == nil) -- udata already removed from weak table
+    assert(getmetatable(o) == getmetatable(u))
+    assert(getmetatable(o).a[o] == 10-s)
+    s=s+1
+  end
+end
+a1, u = nil
+assert(next(a) ~= nil)
+collectgarbage()
+assert(s==11)
+collectgarbage()
+assert(next(a) == nil)  -- finalized keys are removed in two cycles
+
+
+-- __gc x weak tables
+local u = newproxy(true)
+setmetatable(getmetatable(u), {__mode = "v"})
+getmetatable(u).__gc = function (o) os.exit(1) end  -- cannot happen
+collectgarbage()
+
+local u = newproxy(true)
+local m = getmetatable(u)
+m.x = {[{0}] = 1; [0] = {1}}; setmetatable(m.x, {__mode = "kv"});
+m.__gc = function (o)
+  assert(next(getmetatable(o).x) == nil)
+  m = 10
+end
+u, m = nil
+collectgarbage()
+assert(m==10)
+
+
+-- errors during collection
+u = newproxy(true)
+getmetatable(u).__gc = function () error "!!!" end
+u = nil
+assert(not pcall(collectgarbage))
+
+
+if not rawget(_G, "_soft") then
+  print("deep structures")
+  local a = {}
+  for i = 1,200000 do
+    a = {next = a}
+  end
+  collectgarbage()
+end
+
+-- create many threads with self-references and open upvalues
+local thread_id = 0
+local threads = {}
+
+function fn(thread)
+    local x = {}
+    threads[thread_id] = function()
+                             thread = x
+                         end
+    coroutine.yield()
+end
+
+while thread_id < 1000 do
+    local thread = coroutine.create(fn)
+    coroutine.resume(thread, thread)
+    thread_id = thread_id + 1
+end
+
+
+
+-- create a userdata to be collected when state is closed
+do
+  local newproxy,assert,type,print,getmetatable =
+        newproxy,assert,type,print,getmetatable
+  local u = newproxy(true)
+  local tt = getmetatable(u)
+  ___Glob = {u}   -- avoid udata being collected before program end
+  tt.__gc = function (o)
+    assert(getmetatable(o) == tt)
+    -- create new objects during GC
+    local a = 'xuxu'..(10+3)..'joao', {}
+    ___Glob = o  -- ressurect object!
+    newproxy(o)  -- creates a new one with same metatable
+    print(">>> closing state " .. "<<<\n")
+  end
+end
+
+-- create several udata to raise errors when collected while closing state
+do
+  local u = newproxy(true)
+  getmetatable(u).__gc = function (o) return o + 1 end
+  table.insert(___Glob, u)  -- preserve udata until the end
+  for i = 1,10 do table.insert(___Glob, newproxy(u)) end
+end
+
+print('OK')
diff --git a/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt
new file mode 100644
index 0000000..f24e7f3
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt
@@ -0,0 +1,18 @@
+# Test suite that has been added from PUC-Rio Lua 5.1 test archive
+# in scope of https://github.com/tarantool/tarantool/issues/5845.
+
+# See the rationale in the root CMakeLists.txt.
+cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
+
+# The original tarball contains subdirectory "libs" with an empty
+# subdirectory "libs/P1", to be used by tests.
+# Instead of tracking empty directory with some anchor-file for
+# git, create this directory via CMake.
+add_custom_target(PUC-Lua-5.1-tests-prepare)
+add_custom_command(TARGET PUC-Lua-5.1-tests-prepare
+  COMMENT "Create directory for PUC-Rio Lua 5.1 tests"
+  COMMAND ${CMAKE_COMMAND} -E make_directory P1
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+# vim: expandtab tabstop=2 shiftwidth=2
diff --git a/test/PUC-Lua-5.1-tests/libs/lib1.c b/test/PUC-Lua-5.1-tests/libs/lib1.c
new file mode 100644
index 0000000..812bb9a
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/libs/lib1.c
@@ -0,0 +1,40 @@
+/*
+** compile with
+** Linux: gcc -Wall -O2 -I.. -ansi -shared -o lib1.so lib1.c
+** Mac OS X: export MACOSX_DEPLOYMENT_TARGET=10.3
+**     gcc -bundle -undefined dynamic_lookup -Wall -O2 -o lib1.so lib1.c
+*/
+
+
+#include "lua.h"
+#include "lauxlib.h"
+
+static int id (lua_State *L) {
+  return lua_gettop(L);
+}
+
+
+static const struct luaL_reg funcs[] = {
+  {"id", id},
+  {NULL, NULL}
+};
+
+
+int anotherfunc (lua_State *L) {
+  lua_pushfstring(L, "%f%f\n", lua_tonumber(L, 1), lua_tonumber(L, 2));
+  return 1;
+}
+
+
+int luaopen_lib1_sub (lua_State *L) {
+  luaL_register(L, "lib1.sub", funcs + 1);
+  return 1;
+}
+
+
+int luaopen_lib1 (lua_State *L) {
+  luaL_register(L, "lib1", funcs);
+  return 1;
+}
+
+
diff --git a/test/PUC-Lua-5.1-tests/libs/lib11.c b/test/PUC-Lua-5.1-tests/libs/lib11.c
new file mode 100644
index 0000000..3efa3d3
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/libs/lib11.c
@@ -0,0 +1,18 @@
+/*
+** compile with
+** Linux: gcc -Wall -O2 -I.. -ansi -shared -o lib1.so lib1.c
+** Mac OS X: export MACOSX_DEPLOYMENT_TARGET=10.3
+**     gcc -bundle -undefined dynamic_lookup -Wall -O2 -o lib1.so lib1.c
+*/
+
+
+#include "lua.h"
+
+
+int luaopen_lib1 (lua_State *L);
+
+int luaopen_lib11 (lua_State *L) {
+  return luaopen_lib1(L);
+}
+
+
diff --git a/test/PUC-Lua-5.1-tests/libs/lib2.c b/test/PUC-Lua-5.1-tests/libs/lib2.c
new file mode 100644
index 0000000..9972cbe
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/libs/lib2.c
@@ -0,0 +1,28 @@
+/*
+** compile with
+** 	gcc -Wall -O2 -I.. -ansi -shared -o lib1.so lib1.c
+*/
+
+
+#include "lua.h"
+#include "lauxlib.h"
+
+static int id (lua_State *L) {
+  return lua_gettop(L);
+}
+
+
+static const struct luaL_reg funcs[] = {
+  {"id", id},
+  {NULL, NULL}
+};
+
+
+int luaopen_lib2 (lua_State *L) {
+  luaL_register(L, "lib2", funcs);
+  lua_pushnumber(L, 0.5);
+  lua_setglobal(L, "x");
+  return 1;
+}
+
+
diff --git a/test/PUC-Lua-5.1-tests/libs/lib21.c b/test/PUC-Lua-5.1-tests/libs/lib21.c
new file mode 100644
index 0000000..167507f
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/libs/lib21.c
@@ -0,0 +1,18 @@
+/*
+** compile with
+** Linux: gcc -Wall -O2 -I.. -ansi -shared -o lib1.so lib1.c
+** Mac OS X: export MACOSX_DEPLOYMENT_TARGET=10.3
+**     gcc -bundle -undefined dynamic_lookup -Wall -O2 -o lib1.so lib1.c
+*/
+
+
+#include "lua.h"
+
+
+int luaopen_lib2 (lua_State *L);
+
+int luaopen_lib21 (lua_State *L) {
+  return luaopen_lib2(L);
+}
+
+
diff --git a/test/PUC-Lua-5.1-tests/literals.lua b/test/PUC-Lua-5.1-tests/literals.lua
new file mode 100644
index 0000000..01d84d5
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/literals.lua
@@ -0,0 +1,176 @@
+print('testing scanner')
+
+local function dostring (x) return assert(loadstring(x))() end
+
+dostring("x = 'a\0a'")
+assert(x == 'a\0a' and string.len(x) == 3)
+
+-- escape sequences
+assert('\n\"\'\\' == [[
+
+"'\]])
+
+assert(string.find("\a\b\f\n\r\t\v", "^%c%c%c%c%c%c%c$"))
+
+-- assume ASCII just for tests:
+assert("\09912" == 'c12')
+assert("\99ab" == 'cab')
+assert("\099" == '\99')
+assert("\099\n" == 'c\10')
+assert('\0\0\0alo' == '\0' .. '\0\0' .. 'alo')
+
+assert(010 .. 020 .. -030 == "1020-30")
+
+-- long variable names
+
+var = string.rep('a', 15000)
+prog = string.format("%s = 5", var)
+dostring(prog)
+assert(_G[var] == 5)
+var = nil
+print('+')
+
+-- escapes --
+assert("\n\t" == [[
+
+	]])
+assert([[
+
+ $debug]] == "\n $debug")
+assert([[ [ ]] ~= [[ ] ]])
+-- long strings --
+b = "001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789"
+assert(string.len(b) == 960)
+prog = [=[
+print('+')
+
+a1 = [["isto e' um string com várias 'aspas'"]]
+a2 = "'aspas'"
+
+assert(string.find(a1, a2) == 31)
+print('+')
+
+a1 = [==[temp = [[um valor qualquer]]; ]==]
+assert(loadstring(a1))()
+assert(temp == 'um valor qualquer')
+-- long strings --
+b = "001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789"
+assert(string.len(b) == 960)
+print('+')
+
+a = [[00123456789012345678901234567890123456789123456789012345678901234567890123456789
+00123456789012345678901234567890123456789123456789012345678901234567890123456789
+00123456789012345678901234567890123456789123456789012345678901234567890123456789
+00123456789012345678901234567890123456789123456789012345678901234567890123456789
+00123456789012345678901234567890123456789123456789012345678901234567890123456789
+00123456789012345678901234567890123456789123456789012345678901234567890123456789
+00123456789012345678901234567890123456789123456789012345678901234567890123456789
+00123456789012345678901234567890123456789123456789012345678901234567890123456789
+00123456789012345678901234567890123456789123456789012345678901234567890123456789
+00123456789012345678901234567890123456789123456789012345678901234567890123456789
+00123456789012345678901234567890123456789123456789012345678901234567890123456789
+00123456789012345678901234567890123456789123456789012345678901234567890123456789
+00123456789012345678901234567890123456789123456789012345678901234567890123456789
+00123456789012345678901234567890123456789123456789012345678901234567890123456789
+00123456789012345678901234567890123456789123456789012345678901234567890123456789
+00123456789012345678901234567890123456789123456789012345678901234567890123456789
+00123456789012345678901234567890123456789123456789012345678901234567890123456789
+00123456789012345678901234567890123456789123456789012345678901234567890123456789
+00123456789012345678901234567890123456789123456789012345678901234567890123456789
+00123456789012345678901234567890123456789123456789012345678901234567890123456789
+00123456789012345678901234567890123456789123456789012345678901234567890123456789
+00123456789012345678901234567890123456789123456789012345678901234567890123456789
+00123456789012345678901234567890123456789123456789012345678901234567890123456789
+]]
+assert(string.len(a) == 1863)
+assert(string.sub(a, 1, 40) == string.sub(b, 1, 40))
+x = 1
+]=]
+
+print('+')
+x = nil
+dostring(prog)
+assert(x)
+
+prog = nil
+a = nil
+b = nil
+
+
+-- testing line ends
+prog = [[
+a = 1        -- a comment
+b = 2
+
+
+x = [=[
+hi
+]=]
+y = "\
+hello\r\n\
+"
+return debug.getinfo(1).currentline
+]]
+
+for _, n in pairs{"\n", "\r", "\n\r", "\r\n"} do
+  local prog, nn = string.gsub(prog, "\n", n)
+  assert(dostring(prog) == nn)
+  assert(_G.x == "hi\n" and _G.y == "\nhello\r\n\n")
+end
+
+
+-- testing comments and strings with long brackets
+a = [==[]=]==]
+assert(a == "]=")
+
+a = [==[[===[[=[]]=][====[]]===]===]==]
+assert(a == "[===[[=[]]=][====[]]===]===")
+
+a = [====[[===[[=[]]=][====[]]===]===]====]
+assert(a == "[===[[=[]]=][====[]]===]===")
+
+a = [=[]]]]]]]]]=]
+assert(a == "]]]]]]]]")
+
+
+--[===[
+x y z [==[ blu foo
+]==
+]
+]=]==]
+error error]=]===]
+
+-- generate all strings of four of these chars
+local x = {"=", "[", "]", "\n"}
+local len = 4
+local function gen (c, n)
+  if n==0 then coroutine.yield(c)
+  else
+    for _, a in pairs(x) do
+      gen(c..a, n-1)
+    end
+  end
+end
+
+for s in coroutine.wrap(function () gen("", len) end) do
+  assert(s == loadstring("return [====[\n"..s.."]====]")())
+end
+
+
+-- testing decimal point locale
+if os.setlocale("pt_BR") or os.setlocale("ptb") then
+  assert(tonumber("3,4") == 3.4 and tonumber"3.4" == nil)
+  assert(assert(loadstring("return 3.4"))() == 3.4)
+  assert(assert(loadstring("return .4,3"))() == .4)
+  assert(assert(loadstring("return 4."))() == 4.)
+  assert(assert(loadstring("return 4.+.5"))() == 4.5)
+  local a,b = loadstring("return 4.5.")
+  assert(string.find(b, "'4%.5%.'"))
+  assert(os.setlocale("C"))
+else
+  (Message or print)(
+   '\a\n >>> pt_BR locale not available: skipping decimal point tests <<<\n\a')
+end
+
+
+print('OK')
diff --git a/test/PUC-Lua-5.1-tests/locals.lua b/test/PUC-Lua-5.1-tests/locals.lua
new file mode 100644
index 0000000..011645a
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/locals.lua
@@ -0,0 +1,127 @@
+print('testing local variables plus some extra stuff')
+
+do
+  local i = 10
+  do local i = 100; assert(i==100) end
+  do local i = 1000; assert(i==1000) end
+  assert(i == 10)
+  if i ~= 10 then
+    local i = 20
+  else
+    local i = 30
+    assert(i == 30)
+  end
+end
+
+
+
+f = nil
+
+local f
+x = 1
+
+a = nil
+loadstring('local a = {}')()
+assert(type(a) ~= 'table')
+
+function f (a)
+  local _1, _2, _3, _4, _5
+  local _6, _7, _8, _9, _10
+  local x = 3
+  local b = a
+  local c,d = a,b
+  if (d == b) then
+    local x = 'q'
+    x = b
+    assert(x == 2)
+  else
+    assert(nil)
+  end
+  assert(x == 3)
+  local f = 10
+end
+
+local b=10
+local a; repeat local b; a,b=1,2; assert(a+1==b); until a+b==3
+
+
+assert(x == 1)
+
+f(2)
+assert(type(f) == 'function')
+
+
+-- testing globals ;-)
+do
+  local f = {}
+  local _G = _G
+  for i=1,10 do f[i] = function (x) A=A+1; return A, _G.getfenv(x) end end
+  A=10; assert(f[1]() == 11)
+  for i=1,10 do assert(setfenv(f[i], {A=i}) == f[i]) end
+  assert(f[3]() == 4 and A == 11)
+  local a,b = f[8](1)
+  assert(b.A == 9)
+  a,b = f[8](0)
+  assert(b.A == 11)   -- `real' global
+  local g
+  local function f () assert(setfenv(2, {a='10'}) == g) end
+  g = function () f(); _G.assert(_G.getfenv(1).a == '10') end
+  g(); assert(getfenv(g).a == '10')
+end
+
+-- test for global table of loaded chunks
+local function foo (s)
+  return loadstring(s)
+end
+
+assert(getfenv(foo("")) == _G)
+local a = {loadstring = loadstring}
+setfenv(foo, a)
+assert(getfenv(foo("")) == _G)
+setfenv(0, a)  -- change global environment
+assert(getfenv(foo("")) == a)
+setfenv(0, _G)
+
+
+-- testing limits for special instructions
+
+local a
+local p = 4
+for i=2,31 do
+  for j=-3,3 do
+    assert(loadstring(string.format([[local a=%s;a=a+
+                                            %s;
+                                      assert(a
+                                      ==2^%s)]], j, p-j, i))) ()
+    assert(loadstring(string.format([[local a=%s;
+                                      a=a-%s;
+                                      assert(a==-2^%s)]], -j, p-j, i))) ()
+    assert(loadstring(string.format([[local a,b=0,%s;
+                                      a=b-%s;
+                                      assert(a==-2^%s)]], -j, p-j, i))) ()
+  end
+  p =2*p
+end
+
+print'+'
+
+
+if rawget(_G, "querytab") then
+  -- testing clearing of dead elements from tables
+  collectgarbage("stop")   -- stop GC
+  local a = {[{}] = 4, [3] = 0, alo = 1,
+             a1234567890123456789012345678901234567890 = 10}
+
+  local t = querytab(a)
+
+  for k,_ in pairs(a) do a[k] = nil end
+  collectgarbage()   -- restore GC and collect dead fiels in `a'
+  for i=0,t-1 do
+    local k = querytab(a, i)
+    assert(k == nil or type(k) == 'number' or k == 'alo')
+  end
+end
+
+print('OK')
+
+return 5,f
diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua
new file mode 100644
index 0000000..f520896
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/main.lua
@@ -0,0 +1,159 @@
+# testing special comment on first line
+
+print ("testing lua.c options")
+
+assert(os.execute() ~= 0)   -- machine has a system command
+
+prog = os.tmpname()
+otherprog = os.tmpname()
+out = os.tmpname()
+
+do
+  local i = 0
+  while arg[i] do i=i-1 end
+  progname = '"'..arg[i+1]..'"'
+end
+print(progname)
+
+local prepfile = function (s, p)
+  p = p or prog
+  io.output(p)
+  io.write(s)
+  assert(io.close())
+end
+
+function checkout (s)
+  io.input(out)
+  local t = io.read("*a")
+  io.input():close()
+  assert(os.remove(out))
+  if s ~= t then print(string.format("'%s' - '%s'\n", s, t)) end
+  assert(s == t)
+  return t
+end
+
+function auxrun (...)
+  local s = string.format(...)
+  s = string.gsub(s, "lua", progname, 1)
+  return os.execute(s)
+end
+
+function RUN (...)
+  assert(auxrun(...) == 0)
+end
+
+function NoRun (...)
+  print("\n(the next error is expected by the test)")
+  assert(auxrun(...) ~= 0)
+end
+
+-- test 2 files
+prepfile("print(1); a=2")
+prepfile("print(a)", otherprog)
+RUN("lua -l %s -l%s -lstring -l io %s > %s", prog, otherprog, otherprog, out)
+checkout("1\n2\n2\n")
+
+local a = [[
+  assert(table.getn(arg) == 3 and arg[1] == 'a' and
+         arg[2] == 'b' and arg[3] == 'c')
+  assert(arg[-1] == '--' and arg[-2] == "-e " and arg[-3] == %s)
+  assert(arg[4] == nil and arg[-4] == nil)
+  local a, b, c = ...
+  assert(... == 'a' and a == 'a' and b == 'b' and c == 'c')
+]]
+a = string.format(a, progname)
+prepfile(a)
+RUN('lua "-e " -- %s a b c', prog)
+
+prepfile"assert(arg==nil)"
+prepfile("assert(arg)", otherprog)
+RUN("lua -l%s - < %s", prog, otherprog)
+
+prepfile""
+RUN("lua - < %s > %s", prog, out)
+checkout("")
+
+-- test many arguments
+prepfile[[print(({...})[30])]]
+RUN("lua %s %s > %s", prog, string.rep(" a", 30), out)
+checkout("a\n")
+
+RUN([[lua "-eprint(1)" -ea=3 -e "print(a)" > %s]], out)
+checkout("1\n3\n")
+
+prepfile[[
+  print(
+1, a
+)
+]]
+RUN("lua - < %s > %s", prog, out)
+checkout("1\tnil\n")
+
+prepfile[[
+= (6*2-6) -- ===
+a
+= 10
+print(a)
+= a]]
+RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
+checkout("6\n10\n10\n\n")
+
+prepfile("a = [[b\nc\nd\ne]]\n=a")
+print(prog)
+RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
+checkout("b\nc\nd\ne\n\n")
+
+prompt = "alo"
+prepfile[[ --
+a = 2
+]]
+RUN([[lua "-e_PROMPT='%s'" -i < %s > %s]], prompt, prog, out)
+checkout(string.rep(prompt, 3).."\n")
+
+s = [=[ --
+function f ( x )
+  local a = [[
+xuxu
+]]
+  local b = "\
+xuxu\n"
+  if x == 11 then return 1 , 2 end  --[[ test multiple returns ]]
+  return x + 1
+  --\\
+end
+=( f( 10 ) )
+assert( a == b )
+=f( 11 )  ]=]
+s = string.gsub(s, ' ', '\n\n')
+prepfile(s)
+RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
+checkout("11\n1\t2\n\n")
+
+prepfile[[#comment in 1st line without \n at the end]]
+RUN("lua %s", prog)
+
+prepfile("#comment with a binary file\n"..string.dump(loadstring("print(1)")))
+RUN("lua %s > %s", prog, out)
+checkout("1\n")
+
+prepfile("#comment with a binary file\r\n"..string.dump(loadstring("print(1)")))
+RUN("lua %s > %s", prog, out)
+checkout("1\n")
+
+-- close Lua with an open file
+prepfile(string.format([[io.output(%q); io.write('alo')]], out))
+RUN("lua %s", prog)
+checkout('alo')
+
+assert(os.remove(prog))
+assert(os.remove(otherprog))
+assert(not os.remove(out))
+
+RUN("lua -v")
+
+NoRun("lua -h")
+NoRun("lua -e")
+NoRun("lua -e a")
+NoRun("lua -f")
+
+print("OK")
diff --git a/test/PUC-Lua-5.1-tests/math.lua b/test/PUC-Lua-5.1-tests/math.lua
new file mode 100644
index 0000000..5076f38
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/math.lua
@@ -0,0 +1,208 @@
+print("testing numbers and math lib")
+
+do
+  local a,b,c = "2", " 3e0 ", " 10  "
+  assert(a+b == 5 and -b == -3 and b+"2" == 5 and "10"-c == 0)
+  assert(type(a) == 'string' and type(b) == 'string' and type(c) == 'string')
+  assert(a == "2" and b == " 3e0 " and c == " 10  " and -c == -"  10 ")
+  assert(c%a == 0 and a^b == 8)
+end
+
+
+do
+  local a,b = math.modf(3.5)
+  assert(a == 3 and b == 0.5)
+  assert(math.huge > 10e30)
+  assert(-math.huge < -10e30)
+end
+
+function f(...)
+  if select('#', ...) == 1 then
+    return (...)
+  else
+    return "***"
+  end
+end
+
+assert(tonumber{} == nil)
+assert(tonumber'+0.01' == 1/100 and tonumber'+.01' == 0.01 and
+       tonumber'.01' == 0.01    and tonumber'-1.' == -1 and
+       tonumber'+1.' == 1)
+assert(tonumber'+ 0.01' == nil and tonumber'+.e1' == nil and
+       tonumber'1e' == nil     and tonumber'1.0e+' == nil and
+       tonumber'.' == nil)
+assert(tonumber('-12') == -10-2)
+assert(tonumber('-1.2e2') == - - -120)
+assert(f(tonumber('1  a')) == nil)
+assert(f(tonumber('e1')) == nil)
+assert(f(tonumber('e  1')) == nil)
+assert(f(tonumber(' 3.4.5 ')) == nil)
+assert(f(tonumber('')) == nil)
+assert(f(tonumber('', 8)) == nil)
+assert(f(tonumber('  ')) == nil)
+assert(f(tonumber('  ', 9)) == nil)
+assert(f(tonumber('99', 8)) == nil)
+assert(tonumber('  1010  ', 2) == 10)
+assert(tonumber('10', 36) == 36)
+--assert(tonumber('\n  -10  \n', 36) == -36)
+--assert(tonumber('-fFfa', 16) == -(10+(16*(15+(16*(15+(16*15)))))))
+assert(tonumber('fFfa', 15) == nil)
+--assert(tonumber(string.rep('1', 42), 2) + 1 == 2^42)
+assert(tonumber(string.rep('1', 32), 2) + 1 == 2^32)
+--assert(tonumber('-fffffFFFFF', 16)-1 == -2^40)
+assert(tonumber('ffffFFFF', 16)+1 == 2^32)
+
+assert(1.1 == 1.+.1)
+assert(100.0 == 1E2 and .01 == 1e-2)
+assert(1111111111111111-1111111111111110== 1000.00e-03)
+--     1234567890123456
+assert(1.1 == '1.'+'.1')
+assert('1111111111111111'-'1111111111111110' == tonumber"  +0.001e+3 \n\t")
+
+function eq (a,b,limit)
+  if not limit then limit = 10E-10 end
+  return math.abs(a-b) <= limit
+end
+
+assert(0.1e-30 > 0.9E-31 and 0.9E30 < 0.1e31)
+
+assert(0.123456 > 0.123455)
+
+assert(tonumber('+1.23E30') == 1.23*10^30)
+
+-- testing order operators
+assert(not(1<1) and (1<2) and not(2<1))
+assert(not('a'<'a') and ('a'<'b') and not('b'<'a'))
+assert((1<=1) and (1<=2) and not(2<=1))
+assert(('a'<='a') and ('a'<='b') and not('b'<='a'))
+assert(not(1>1) and not(1>2) and (2>1))
+assert(not('a'>'a') and not('a'>'b') and ('b'>'a'))
+assert((1>=1) and not(1>=2) and (2>=1))
+assert(('a'>='a') and not('a'>='b') and ('b'>='a'))
+
+-- testing mod operator
+assert(-4%3 == 2)
+assert(4%-3 == -2)
+assert(math.pi - math.pi % 1 == 3)
+assert(math.pi - math.pi % 0.001 == 3.141)
+
+local function testbit(a, n)
+  return a/2^n % 2 >= 1
+end
+
+assert(eq(math.sin(-9.8)^2 + math.cos(-9.8)^2, 1))
+assert(eq(math.tan(math.pi/4), 1))
+assert(eq(math.sin(math.pi/2), 1) and eq(math.cos(math.pi/2), 0))
+assert(eq(math.atan(1), math.pi/4) and eq(math.acos(0), math.pi/2) and
+       eq(math.asin(1), math.pi/2))
+assert(eq(math.deg(math.pi/2), 90) and eq(math.rad(90), math.pi/2))
+assert(math.abs(-10) == 10)
+assert(eq(math.atan2(1,0), math.pi/2))
+assert(math.ceil(4.5) == 5.0)
+assert(math.floor(4.5) == 4.0)
+assert(math.mod(10,3) == 1)
+assert(eq(math.sqrt(10)^2, 10))
+assert(eq(math.log10(2), math.log(2)/math.log(10)))
+assert(eq(math.exp(0), 1))
+assert(eq(math.sin(10), math.sin(10%(2*math.pi))))
+local v,e = math.frexp(math.pi)
+assert(eq(math.ldexp(v,e), math.pi))
+
+assert(eq(math.tanh(3.5), math.sinh(3.5)/math.cosh(3.5)))
+
+assert(tonumber(' 1.3e-2 ') == 1.3e-2)
+assert(tonumber(' -1.00000000000001 ') == -1.00000000000001)
+
+-- testing constant limits
+-- 2^23 = 8388608
+assert(8388609 + -8388609 == 0)
+assert(8388608 + -8388608 == 0)
+assert(8388607 + -8388607 == 0)
+
+if rawget(_G, "_soft") then return end
+
+f = io.tmpfile()
+assert(f)
+f:write("a = {")
+i = 1
+repeat
+  f:write("{", math.sin(i), ", ", math.cos(i), ", ", i/3, "},\n")
+  i=i+1
+until i > 1000
+f:write("}")
+f:seek("set", 0)
+assert(loadstring(f:read('*a')))()
+assert(f:close())
+
+assert(eq(a[300][1], math.sin(300)))
+assert(eq(a[600][1], math.sin(600)))
+assert(eq(a[500][2], math.cos(500)))
+assert(eq(a[800][2], math.cos(800)))
+assert(eq(a[200][3], 200/3))
+assert(eq(a[1000][3], 1000/3, 0.001))
+print('+')
+
+do   -- testing NaN
+  local NaN = 10e500 - 10e400
+  assert(NaN ~= NaN)
+  assert(not (NaN < NaN))
+  assert(not (NaN <= NaN))
+  assert(not (NaN > NaN))
+  assert(not (NaN >= NaN))
+  assert(not (0 < NaN))
+  assert(not (NaN < 0))
+  local a = {}
+  assert(not pcall(function () a[NaN] = 1 end))
+  assert(a[NaN] == nil)
+  a[1] = 1
+  assert(not pcall(function () a[NaN] = 1 end))
+  assert(a[NaN] == nil)
+end
+
+require "checktable"
+stat(a)
+
+a = nil
+
+-- testing implicit convertions
+
+local a,b = '10', '20'
+assert(a*b == 200 and a+b == 30 and a-b == -10 and a/b == 0.5 and -b == -20)
+assert(a == '10' and b == '20')
+
+
+math.randomseed(0)
+
+local i = 0
+local Max = 0
+local Min = 2
+repeat
+  local t = math.random()
+  Max = math.max(Max, t)
+  Min = math.min(Min, t)
+  i=i+1
+  flag = eq(Max, 1, 0.001) and eq(Min, 0, 0.001)
+until flag or i>10000
+assert(0 <= Min and Max<1)
+assert(flag);
+
+for i=1,10 do
+  local t = math.random(5)
+  assert(1 <= t and t <= 5)
+end
+
+i = 0
+Max = -200
+Min = 200
+repeat
+  local t = math.random(-10,0)
+  Max = math.max(Max, t)
+  Min = math.min(Min, t)
+  i=i+1
+  flag = (Max == 0 and Min == -10)
+until flag or i>10000
+assert(-10 <= Min and Max<=0)
+assert(flag);
+
+
+print('OK')
diff --git a/test/PUC-Lua-5.1-tests/nextvar.lua b/test/PUC-Lua-5.1-tests/nextvar.lua
new file mode 100644
index 0000000..7ceaa75
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/nextvar.lua
@@ -0,0 +1,396 @@
+print('testing tables, next, and for')
+
+local a = {}
+
+-- make sure table has lots of space in hash part
+for i=1,100 do a[i.."+"] = true end
+for i=1,100 do a[i.."+"] = nil end
+-- fill hash part with numeric indices testing size operator
+for i=1,100 do
+  a[i] = true
+  assert(#a == i)
+end
+
+
+if T then
+-- testing table sizes
+
+local l2 = math.log(2)
+local function log2 (x) return math.log(x)/l2 end
+
+local function mp2 (n)   -- minimum power of 2 >= n
+  local mp = 2^math.ceil(log2(n))
+  assert(n == 0 or (mp/2 < n and n <= mp))
+  return mp
+end
+
+local function fb (n)
+  local r, nn = T.int2fb(n)
+  assert(r < 256)
+  return nn
+end
+
+-- test fb function
+local a = 1
+local lim = 2^30
+while a < lim do
+  local n = fb(a)
+  assert(a <= n and n <= a*1.125)
+  a = math.ceil(a*1.3)
+end
+
+
+local function check (t, na, nh)
+  local a, h = T.querytab(t)
+  if a ~= na or h ~= nh then
+    print(na, nh, a, h)
+    assert(nil)
+  end
+end
+
+-- testing constructor sizes
+local lim = 40
+local s = 'return {'
+for i=1,lim do
+  s = s..i..','
+  local s = s
+  for k=0,lim do
+    local t = loadstring(s..'}')()
+    assert(#t == i)
+    check(t, fb(i), mp2(k))
+    s = string.format('%sa%d=%d,', s, k, k)
+  end
+end
+
+
+-- tests with unknown number of elements
+local a = {}
+for i=1,lim do a[i] = i end   -- build auxiliary table
+for k=0,lim do
+  local a = {unpack(a,1,k)}
+  assert(#a == k)
+  check(a, k, 0)
+  a = {1,2,3,unpack(a,1,k)}
+  check(a, k+3, 0)
+  assert(#a == k + 3)
+end
+
+
+print'+'
+
+-- testing tables dynamically built
+local lim = 130
+local a = {}; a[2] = 1; check(a, 0, 1)
+a = {}; a[0] = 1; check(a, 0, 1); a[2] = 1; check(a, 0, 2)
+a = {}; a[0] = 1; a[1] = 1; check(a, 1, 1)
+a = {}
+for i = 1,lim do
+  a[i] = 1
+  assert(#a == i)
+  check(a, mp2(i), 0)
+end
+
+a = {}
+for i = 1,lim do
+  a['a'..i] = 1
+  assert(#a == 0)
+  check(a, 0, mp2(i))
+end
+
+a = {}
+for i=1,16 do a[i] = i end
+check(a, 16, 0)
+for i=1,11 do a[i] = nil end
+for i=30,40 do a[i] = nil end   -- force a rehash (?)
+check(a, 0, 8)
+a[10] = 1
+for i=30,40 do a[i] = nil end   -- force a rehash (?)
+check(a, 0, 8)
+for i=1,14 do a[i] = nil end
+for i=30,50 do a[i] = nil end   -- force a rehash (?)
+check(a, 0, 4)
+
+-- reverse filling
+for i=1,lim do
+  local a = {}
+  for i=i,1,-1 do a[i] = i end   -- fill in reverse
+  check(a, mp2(i), 0)
+end
+
+-- size tests for vararg
+lim = 35
+function foo (n, ...)
+  local arg = {...}
+  check(arg, n, 0)
+  assert(select('#', ...) == n)
+  arg[n+1] = true
+  check(arg, mp2(n+1), 0)
+  arg.x = true
+  check(arg, mp2(n+1), 1)
+end
+local a = {}
+for i=1,lim do a[i] = true; foo(i, unpack(a)) end
+
+end
+
+
+-- test size operation on empty tables
+assert(#{} == 0)
+assert(#{nil} == 0)
+assert(#{nil, nil} == 0)
+assert(#{nil, nil, nil} == 0)
+assert(#{nil, nil, nil, nil} == 0)
+print'+'
+
+
+local nofind = {}
+
+a,b,c = 1,2,3
+a,b,c = nil
+
+local function find (name)
+  local n,v
+  while 1 do
+    n,v = next(_G, n)
+    if not n then return nofind end
+    assert(v ~= nil)
+    if n == name then return v end
+  end
+end
+
+local function find1 (name)
+  for n,v in pairs(_G) do
+    if n==name then return v end
+  end
+  return nil  -- not found
+end
+
+do   -- create 10000 new global variables
+  for i=1,10000 do _G[i] = i end
+end
+
+
+a = {x=90, y=8, z=23}
+assert(table.foreach(a, function(i,v) if i=='x' then return v end end) == 90)
+assert(table.foreach(a, function(i,v) if i=='a' then return v end end) == nil)
+table.foreach({}, error)
+
+table.foreachi({x=10, y=20}, error)
+local a = {n = 1}
+table.foreachi({n=3}, function (i, v)
+  assert(a.n == i and not v)
+  a.n=a.n+1
+end)
+a = {10,20,30,nil,50}
+table.foreachi(a, function (i,v) assert(a[i] == v) end)
+assert(table.foreachi({'a', 'b', 'c'}, function (i,v)
+         if i==2 then return v end
+       end) == 'b')
+
+
+assert(print==find("print") and print == find1("print"))
+assert(_G["print"]==find("print"))
+assert(assert==find1("assert"))
+assert(nofind==find("return"))
+assert(not find1("return"))
+_G["ret" .. "urn"] = nil
+assert(nofind==find("return"))
+_G["xxx"] = 1
+assert(xxx==find("xxx"))
+print('+')
+
+a = {}
+for i=0,10000 do
+  if math.mod(i,10) ~= 0 then
+    a['x'..i] = i
+  end
+end
+
+n = {n=0}
+for i,v in pairs(a) do
+  n.n = n.n+1
+  assert(i and v and a[i] == v)
+end
+assert(n.n == 9000)
+a = nil
+
+-- remove those 10000 new global variables
+for i=1,10000 do _G[i] = nil end
+
+do   -- clear global table
+  local a = {}
+  local preserve = {io = 1, string = 1, debug = 1, os = 1,
+                    coroutine = 1, table = 1, math = 1}
+  for n,v in pairs(_G) do a[n]=v end
+  for n,v in pairs(a) do
+    if not preserve[n] and type(v) ~= "function" and
+       not string.find(n, "^[%u_]") then
+     _G[n] = nil
+    end
+    collectgarbage()
+  end
+end
+
+local function foo ()
+  local getfenv, setfenv, assert, next =
+        getfenv, setfenv, assert, next
+  local n = {gl1=3}
+  setfenv(foo, n)
+  assert(getfenv(foo) == getfenv(1))
+  assert(getfenv(foo) == n)
+  assert(print == nil and gl1 == 3)
+  gl1 = nil
+  gl = 1
+  assert(n.gl == 1 and next(n, 'gl') == nil)
+end
+foo()
+
+print'+'
+
+local function checknext (a)
+  local b = {}
+  table.foreach(a, function (k,v) b[k] = v end)
+  for k,v in pairs(b) do assert(a[k] == v) end
+  for k,v in pairs(a) do assert(b[k] == v) end
+  b = {}
+  do local k,v = next(a); while k do b[k] = v; k,v = next(a,k) end end
+  for k,v in pairs(b) do assert(a[k] == v) end
+  for k,v in pairs(a) do assert(b[k] == v) end
+end
+
+checknext{1,x=1,y=2,z=3}
+checknext{1,2,x=1,y=2,z=3}
+checknext{1,2,3,x=1,y=2,z=3}
+checknext{1,2,3,4,x=1,y=2,z=3}
+checknext{1,2,3,4,5,x=1,y=2,z=3}
+
+assert(table.getn{} == 0)
+assert(table.getn{[-1] = 2} == 0)
+assert(table.getn{1,2,3,nil,nil} == 3)
+for i=0,40 do
+  local a = {}
+  for j=1,i do a[j]=j end
+  assert(table.getn(a) == i)
+end
+
+
+assert(table.maxn{} == 0)
+assert(table.maxn{["1000"] = true} == 0)
+assert(table.maxn{["1000"] = true, [24.5] = 3} == 24.5)
+assert(table.maxn{[1000] = true} == 1000)
+assert(table.maxn{[10] = true, [100*math.pi] = print} == 100*math.pi)
+
+
+-- int overflow
+a = {}
+for i=0,50 do a[math.pow(2,i)] = true end
+assert(a[table.getn(a)])
+
+print("+")
+
+
+-- erasing values
+local t = {[{1}] = 1, [{2}] = 2, [string.rep("x ", 4)] = 3,
+           [100.3] = 4, [4] = 5}
+
+local n = 0
+for k, v in pairs( t ) do
+  n = n+1
+  assert(t[k] == v)
+  t[k] = nil
+  collectgarbage()
+  assert(t[k] == nil)
+end
+assert(n == 5)
+
+
+local function test (a)
+  table.insert(a, 10); table.insert(a, 2, 20);
+  table.insert(a, 1, -1); table.insert(a, 40);
+  table.insert(a, table.getn(a)+1, 50)
+  table.insert(a, 2, -2)
+  assert(table.remove(a,1) == -1)
+  assert(table.remove(a,1) == -2)
+  assert(table.remove(a,1) == 10)
+  assert(table.remove(a,1) == 20)
+  assert(table.remove(a,1) == 40)
+  assert(table.remove(a,1) == 50)
+  assert(table.remove(a,1) == nil)
+end
+
+a = {n=0, [-7] = "ban"}
+test(a)
+assert(a.n == 0 and a[-7] == "ban")
+
+a = {[-7] = "ban"};
+test(a)
+assert(a.n == nil and table.getn(a) == 0 and a[-7] == "ban")
+
+
+table.insert(a, 1, 10); table.insert(a, 1, 20); table.insert(a, 1, -1)
+assert(table.remove(a) == 10)
+assert(table.remove(a) == 20)
+assert(table.remove(a) == -1)
+
+a = {'c', 'd'}
+table.insert(a, 3, 'a')
+table.insert(a, 'b')
+assert(table.remove(a, 1) == 'c')
+assert(table.remove(a, 1) == 'd')
+assert(table.remove(a, 1) == 'a')
+assert(table.remove(a, 1) == 'b')
+assert(table.getn(a) == 0 and a.n == nil)
+print("+")
+
+a = {}
+for i=1,1000 do
+  a[i] = i; a[i-1] = nil
+end
+assert(next(a,nil) == 1000 and next(a,1000) == nil)
+
+assert(next({}) == nil)
+assert(next({}, nil) == nil)
+
+for a,b in pairs{} do error"not here" end
+for i=1,0 do error'not here' end
+for i=0,1,-1 do error'not here' end
+a = nil; for i=1,1 do assert(not a); a=1 end; assert(a)
+a = nil; for i=1,1,-1 do assert(not a); a=1 end; assert(a)
+
+a = 0; for i=0, 1, 0.1 do a=a+1 end; assert(a==11)
+-- precision problems
+--a = 0; for i=1, 0, -0.01 do a=a+1 end; assert(a==101)
+a = 0; for i=0, 0.999999999, 0.1 do a=a+1 end; assert(a==10)
+a = 0; for i=1, 1, 1 do a=a+1 end; assert(a==1)
+a = 0; for i=1e10, 1e10, -1 do a=a+1 end; assert(a==1)
+a = 0; for i=1, 0.99999, 1 do a=a+1 end; assert(a==0)
+a = 0; for i=99999, 1e5, -1 do a=a+1 end; assert(a==0)
+a = 0; for i=1, 0.99999, -1 do a=a+1 end; assert(a==1)
+
+-- conversion
+a = 0; for i="10","1","-2" do a=a+1 end; assert(a==5)
+
+
+collectgarbage()
+
+
+-- testing generic 'for'
+
+local function f (n, p)
+  local t = {}; for i=1,p do t[i] = i*10 end
+  return function (_,n)
+           if n > 0 then
+             n = n-1
+             return n, unpack(t)
+           end
+         end, nil, n
+end
+
+local x = 0
+for n,a,b,c,d in f(5,3) do
+  x = x+1
+  assert(a == 10 and b == 20 and c == 30 and d == nil)
+end
+assert(x == 5)
+
+print"OK"
diff --git a/test/PUC-Lua-5.1-tests/pm.lua b/test/PUC-Lua-5.1-tests/pm.lua
new file mode 100644
index 0000000..fa125dc
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/pm.lua
@@ -0,0 +1,273 @@
+print('testing pattern matching')
+
+function f(s, p)
+  local i,e = string.find(s, p)
+  if i then return string.sub(s, i, e) end
+end
+
+function f1(s, p)
+  p = string.gsub(p, "%%([0-9])", function (s) return "%" .. (s+1) end)
+  p = string.gsub(p, "^(^?)", "%1()", 1)
+  p = string.gsub(p, "($?)$", "()%1", 1)
+  local t = {string.match(s, p)}
+  return string.sub(s, t[1], t[#t] - 1)
+end
+
+a,b = string.find('', '')    -- empty patterns are tricky
+assert(a == 1 and b == 0);
+a,b = string.find('alo', '')
+assert(a == 1 and b == 0)
+a,b = string.find('a\0o a\0o a\0o', 'a', 1)   -- first position
+assert(a == 1 and b == 1)
+a,b = string.find('a\0o a\0o a\0o', 'a\0o', 2)   -- starts in the midle
+assert(a == 5 and b == 7)
+a,b = string.find('a\0o a\0o a\0o', 'a\0o', 9)   -- starts in the midle
+assert(a == 9 and b == 11)
+a,b = string.find('a\0a\0a\0a\0\0ab', '\0ab', 2);  -- finds at the end
+assert(a == 9 and b == 11);
+a,b = string.find('a\0a\0a\0a\0\0ab', 'b')    -- last position
+assert(a == 11 and b == 11)
+assert(string.find('a\0a\0a\0a\0\0ab', 'b\0') == nil)   -- check ending
+assert(string.find('', '\0') == nil)
+assert(string.find('alo123alo', '12') == 4)
+assert(string.find('alo123alo', '^12') == nil)
+
+assert(f('aloALO', '%l*') == 'alo')
+assert(f('aLo_ALO', '%a*') == 'aLo')
+
+assert(f('aaab', 'a*') == 'aaa');
+assert(f('aaa', '^.*$') == 'aaa');
+assert(f('aaa', 'b*') == '');
+assert(f('aaa', 'ab*a') == 'aa')
+assert(f('aba', 'ab*a') == 'aba')
+assert(f('aaab', 'a+') == 'aaa')
+assert(f('aaa', '^.+$') == 'aaa')
+assert(f('aaa', 'b+') == nil)
+assert(f('aaa', 'ab+a') == nil)
+assert(f('aba', 'ab+a') == 'aba')
+assert(f('a$a', '.$') == 'a')
+assert(f('a$a', '.%$') == 'a$')
+assert(f('a$a', '.$.') == 'a$a')
+assert(f('a$a', '$$') == nil)
+assert(f('a$b', 'a$') == nil)
+assert(f('a$a', '$') == '')
+assert(f('', 'b*') == '')
+assert(f('aaa', 'bb*') == nil)
+assert(f('aaab', 'a-') == '')
+assert(f('aaa', '^.-$') == 'aaa')
+assert(f('aabaaabaaabaaaba', 'b.*b') == 'baaabaaabaaab')
+assert(f('aabaaabaaabaaaba', 'b.-b') == 'baaab')
+assert(f('alo xo', '.o$') == 'xo')
+assert(f(' \n isto é assim', '%S%S*') == 'isto')
+assert(f(' \n isto é assim', '%S*$') == 'assim')
+assert(f(' \n isto é assim', '[a-z]*$') == 'assim')
+assert(f('um caracter ? extra', '[^%sa-z]') == '?')
+assert(f('', 'a?') == '')
+assert(f('á', 'á?') == 'á')
+assert(f('ábl', 'á?b?l?') == 'ábl')
+assert(f('  ábl', 'á?b?l?') == '')
+assert(f('aa', '^aa?a?a') == 'aa')
+assert(f(']]]áb', '[^]]') == 'á')
+assert(f("0alo alo", "%x*") == "0a")
+assert(f("alo alo", "%C+") == "alo alo")
+print('+')
+
+assert(f1('alo alx 123 b\0o b\0o', '(..*) %1') == "b\0o b\0o")
+assert(f1('axz123= 4= 4 34', '(.+)=(.*)=%2 %1') == '3= 4= 4 3')
+assert(f1('=======', '^(=*)=%1$') == '=======')
+assert(string.match('==========', '^([=]*)=%1$') == nil)
+
+local function range (i, j)
+  if i <= j then
+    return i, range(i+1, j)
+  end
+end
+
+local abc = string.char(range(0, 255));
+
+assert(string.len(abc) == 256)
+
+function strset (p)
+  local res = {s=''}
+  string.gsub(abc, p, function (c) res.s = res.s .. c end)
+  return res.s
+end;
+
+assert(string.len(strset('[\200-\210]')) == 11)
+
+assert(strset('[a-z]') == "abcdefghijklmnopqrstuvwxyz")
+assert(strset('[a-z%d]') == strset('[%da-uu-z]'))
+assert(strset('[a-]') == "-a")
+assert(strset('[^%W]') == strset('[%w]'))
+assert(strset('[]%%]') == '%]')
+assert(strset('[a%-z]') == '-az')
+assert(strset('[%^%[%-a%]%-b]') == '-[]^ab')
+assert(strset('%Z') == strset('[\1-\255]'))
+assert(strset('.') == strset('[\1-\255%z]'))
+print('+');
+
+assert(string.match("alo xyzK", "(%w+)K") == "xyz")
+assert(string.match("254 K", "(%d*)K") == "")
+assert(string.match("alo ", "(%w*)$") == "")
+assert(string.match("alo ", "(%w+)$") == nil)
+assert(string.find("(álo)", "%(á") == 1)
+local a, b, c, d, e = string.match("âlo alo", "^(((.).).* (%w*))$")
+assert(a == 'âlo alo' and b == 'âl' and c == 'â' and d == 'alo' and e == nil)
+a, b, c, d  = string.match('0123456789', '(.+(.?)())')
+assert(a == '0123456789' and b == '' and c == 11 and d == nil)
+print('+')
+
+assert(string.gsub('ülo ülo', 'ü', 'x') == 'xlo xlo')
+assert(string.gsub('alo úlo  ', ' +$', '') == 'alo úlo')  -- trim
+assert(string.gsub('  alo alo  ', '^%s*(.-)%s*$', '%1') == 'alo alo')  -- double trim
+assert(string.gsub('alo  alo  \n 123\n ', '%s+', ' ') == 'alo alo 123 ')
+t = "abç d"
+a, b = string.gsub(t, '(.)', '%1@')
+assert('@'..a == string.gsub(t, '', '@') and b == 5)
+a, b = string.gsub('abçd', '(.)', '%0@', 2)
+assert(a == 'a@b@çd' and b == 2)
+assert(string.gsub('alo alo', '()[al]', '%1') == '12o 56o')
+assert(string.gsub("abc=xyz", "(%w*)(%p)(%w+)", "%3%2%1-%0") ==
+              "xyz=abc-abc=xyz")
+assert(string.gsub("abc", "%w", "%1%0") == "aabbcc")
+assert(string.gsub("abc", "%w+", "%0%1") == "abcabc")
+assert(string.gsub('áéí', '$', '\0óú') == 'áéí\0óú')
+assert(string.gsub('', '^', 'r') == 'r')
+assert(string.gsub('', '$', 'r') == 'r')
+print('+')
+
+assert(string.gsub("um (dois) tres (quatro)", "(%(%w+%))", string.upper) ==
+            "um (DOIS) tres (QUATRO)")
+
+do
+  local function setglobal (n,v) rawset(_G, n, v) end
+  string.gsub("a=roberto,roberto=a", "(%w+)=(%w%w*)", setglobal)
+  assert(_G.a=="roberto" and _G.roberto=="a")
+end
+
+function f(a,b) return string.gsub(a,'.',b) end
+assert(string.gsub("trocar tudo em |teste|b| é |beleza|al|", "|([^|]*)|([^|]*)|", f) ==
+            "trocar tudo em bbbbb é alalalalalal")
+
+local function dostring (s) return loadstring(s)() or "" end
+assert(string.gsub("alo $a=1$ novamente $return a$", "$([^$]*)%$", dostring) ==
+            "alo  novamente 1")
+
+x = string.gsub("$x=string.gsub('alo', '.', string.upper)$ assim vai para $return x$",
+         "$([^$]*)%$", dostring)
+assert(x == ' assim vai para ALO')
+
+t = {}
+s = 'a alo jose  joao'
+r = string.gsub(s, '()(%w+)()', function (a,w,b)
+      assert(string.len(w) == b-a);
+      t[a] = b-a;
+    end)
+assert(s == r and t[1] == 1 and t[3] == 3 and t[7] == 4 and t[13] == 4)
+
+
+function isbalanced (s)
+  return string.find(string.gsub(s, "%b()", ""), "[()]") == nil
+end
+
+assert(isbalanced("(9 ((8))(\0) 7) \0\0 a b ()(c)() a"))
+assert(not isbalanced("(9 ((8) 7) a b (\0 c) a"))
+assert(string.gsub("alo 'oi' alo", "%b''", '"') == 'alo " alo')
+
+
+local t = {"apple", "orange", "lime"; n=0}
+assert(string.gsub("x and x and x", "x", function () t.n=t.n+1; return t[t.n] end)
+        == "apple and orange and lime")
+
+t = {n=0}
+string.gsub("first second word", "%w%w*", function (w) t.n=t.n+1; t[t.n] = w end)
+assert(t[1] == "first" and t[2] == "second" and t[3] == "word" and t.n == 3)
+
+t = {n=0}
+assert(string.gsub("first second word", "%w+",
+         function (w) t.n=t.n+1; t[t.n] = w end, 2) == "first second word")
+assert(t[1] == "first" and t[2] == "second" and t[3] == nil)
+
+assert(not pcall(string.gsub, "alo", "(.", print))
+assert(not pcall(string.gsub, "alo", ".)", print))
+assert(not pcall(string.gsub, "alo", "(.", {}))
+assert(not pcall(string.gsub, "alo", "(.)", "%2"))
+assert(not pcall(string.gsub, "alo", "(%1)", "a"))
+assert(not pcall(string.gsub, "alo", "(%0)", "a"))
+
+-- big strings
+local a = string.rep('a', 300000)
+assert(string.find(a, '^a*.?$'))
+assert(not string.find(a, '^a*.?b$'))
+assert(string.find(a, '^a-.?$'))
+
+-- deep nest of gsubs
+function rev (s)
+  return string.gsub(s, "(.)(.+)", function (c,s1) return rev(s1)..c end)
+end
+
+local x = string.rep('012345', 10)
+assert(rev(rev(x)) == x)
+
+
+-- gsub with tables
+assert(string.gsub("alo alo", ".", {}) == "alo alo")
+assert(string.gsub("alo alo", "(.)", {a="AA", l=""}) == "AAo AAo")
+assert(string.gsub("alo alo", "(.).", {a="AA", l="K"}) == "AAo AAo")
+assert(string.gsub("alo alo", "((.)(.?))", {al="AA", o=false}) == "AAo AAo")
+
+assert(string.gsub("alo alo", "().", {2,5,6}) == "256 alo")
+
+t = {}; setmetatable(t, {__index = function (t,s) return string.upper(s) end})
+assert(string.gsub("a alo b hi", "%w%w+", t) == "a ALO b HI")
+
+
+-- tests for gmatch
+assert(string.gfind == string.gmatch)
+local a = 0
+for i in string.gmatch('abcde', '()') do assert(i == a+1); a=i end
+assert(a==6)
+
+t = {n=0}
+for w in string.gmatch("first second word", "%w+") do
+      t.n=t.n+1; t[t.n] = w
+end
+assert(t[1] == "first" and t[2] == "second" and t[3] == "word")
+
+t = {3, 6, 9}
+for i in string.gmatch ("xuxx uu ppar r", "()(.)%2") do
+  assert(i == table.remove(t, 1))
+end
+assert(table.getn(t) == 0)
+
+t = {}
+for i,j in string.gmatch("13 14 10 = 11, 15= 16, 22=23", "(%d+)%s*=%s*(%d+)") do
+  t[i] = j
+end
+a = 0
+for k,v in pairs(t) do assert(k+1 == v+0); a=a+1 end
+assert(a == 3)
+
+
+-- tests for `%f' (`frontiers')
+
+assert(string.gsub("aaa aa a aaa a", "%f[%w]a", "x") == "xaa xa x xaa x")
+assert(string.gsub("[[]] [][] [[[[", "%f[[].", "x") == "x[]] x]x] x[[[")
+assert(string.gsub("01abc45de3", "%f[%d]", ".") == ".01abc.45de.3")
+assert(string.gsub("01abc45 de3x", "%f[%D]%w", ".") == "01.bc45 de3.")
+assert(string.gsub("function", "%f[\1-\255]%w", ".") == ".unction")
+assert(string.gsub("function", "%f[^\1-\255]", ".") == "function.")
+
+local i, e = string.find(" alo aalo allo", "%f[%S].-%f[%s].-%f[%S]")
+assert(i == 2 and e == 5)
+local k = string.match(" alo aalo allo", "%f[%S](.-%f[%s].-%f[%S])")
+assert(k == 'alo ')
+
+local a = {1, 5, 9, 14, 17,}
+for k in string.gmatch("alo alo th02 is 1hat", "()%f[%w%d]") do
+  assert(table.remove(a, 1) == k)
+end
+assert(table.getn(a) == 0)
+
+
+print('OK')
diff --git a/test/PUC-Lua-5.1-tests/sort.lua b/test/PUC-Lua-5.1-tests/sort.lua
new file mode 100644
index 0000000..6fccd49
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/sort.lua
@@ -0,0 +1,74 @@
+print"testing sort"
+
+
+function check (a, f)
+  f = f or function (x,y) return x<y end;
+  for n=table.getn(a),2,-1 do
+    assert(not f(a[n], a[n-1]))
+  end
+end
+
+a = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
+     "Oct", "Nov", "Dec"}
+
+table.sort(a)
+check(a)
+
+limit = 30000
+if rawget(_G, "_soft") then limit = 5000 end
+
+a = {}
+for i=1,limit do
+  a[i] = math.random()
+end
+
+local x = os.clock()
+table.sort(a)
+print(string.format("Sorting %d elements in %.2f sec.", limit, os.clock()-x))
+check(a)
+
+x = os.clock()
+table.sort(a)
+print(string.format("Re-sorting %d elements in %.2f sec.", limit, os.clock()-x))
+check(a)
+
+a = {}
+for i=1,limit do
+  a[i] = math.random()
+end
+
+x = os.clock(); i=0
+table.sort(a, function(x,y) i=i+1; return y<x end)
+print(string.format("Invert-sorting other %d elements in %.2f sec., with %i comparisons",
+      limit, os.clock()-x, i))
+check(a, function(x,y) return y<x end)
+
+
+table.sort{}  -- empty array
+
+for i=1,limit do a[i] = false end
+x = os.clock();
+table.sort(a, function(x,y) return nil end)
+print(string.format("Sorting %d equal elements in %.2f sec.", limit, os.clock()-x))
+check(a, function(x,y) return nil end)
+for i,v in pairs(a) do assert(not v or i=='n' and v==limit) end
+
+a = {"álo", "\0first :-)", "alo", "then this one", "45", "and a new"}
+table.sort(a)
+check(a)
+
+table.sort(a, function (x, y)
+          loadstring(string.format("a[%q] = ''", x))()
+          collectgarbage()
+          return x<y
+        end)
+
+
+tt = {__lt = function (a,b) return a.val < b.val end}
+a = {}
+for i=1,10 do  a[i] = {val=math.random(100)}; setmetatable(a[i], tt); end
+table.sort(a)
+check(a, tt.__lt)
+check(a)
+
+print"OK"
diff --git a/test/PUC-Lua-5.1-tests/strings.lua b/test/PUC-Lua-5.1-tests/strings.lua
new file mode 100644
index 0000000..237dbad
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/strings.lua
@@ -0,0 +1,176 @@
+print('testing strings and string library')
+
+assert('alo' < 'alo1')
+assert('' < 'a')
+assert('alo\0alo' < 'alo\0b')
+assert('alo\0alo\0\0' > 'alo\0alo\0')
+assert('alo' < 'alo\0')
+assert('alo\0' > 'alo')
+assert('\0' < '\1')
+assert('\0\0' < '\0\1')
+assert('\1\0a\0a' <= '\1\0a\0a')
+assert(not ('\1\0a\0b' <= '\1\0a\0a'))
+assert('\0\0\0' < '\0\0\0\0')
+assert(not('\0\0\0\0' < '\0\0\0'))
+assert('\0\0\0' <= '\0\0\0\0')
+assert(not('\0\0\0\0' <= '\0\0\0'))
+assert('\0\0\0' <= '\0\0\0')
+assert('\0\0\0' >= '\0\0\0')
+assert(not ('\0\0b' < '\0\0a\0'))
+print('+')
+
+assert(string.sub("123456789",2,4) == "234")
+assert(string.sub("123456789",7) == "789")
+assert(string.sub("123456789",7,6) == "")
+assert(string.sub("123456789",7,7) == "7")
+assert(string.sub("123456789",0,0) == "")
+assert(string.sub("123456789",-10,10) == "123456789")
+assert(string.sub("123456789",1,9) == "123456789")
+assert(string.sub("123456789",-10,-20) == "")
+assert(string.sub("123456789",-1) == "9")
+assert(string.sub("123456789",-4) == "6789")
+assert(string.sub("123456789",-6, -4) == "456")
+assert(string.sub("\000123456789",3,5) == "234")
+assert(("\000123456789"):sub(8) == "789")
+print('+')
+
+assert(string.find("123456789", "345") == 3)
+a,b = string.find("123456789", "345")
+assert(string.sub("123456789", a, b) == "345")
+assert(string.find("1234567890123456789", "345", 3) == 3)
+assert(string.find("1234567890123456789", "345", 4) == 13)
+assert(string.find("1234567890123456789", "346", 4) == nil)
+assert(string.find("1234567890123456789", ".45", -9) == 13)
+assert(string.find("abcdefg", "\0", 5, 1) == nil)
+assert(string.find("", "") == 1)
+assert(string.find('', 'aaa', 1) == nil)
+assert(('alo(.)alo'):find('(.)', 1, 1) == 4)
+print('+')
+
+assert(string.len("") == 0)
+assert(string.len("\0\0\0") == 3)
+assert(string.len("1234567890") == 10)
+
+assert(#"" == 0)
+assert(#"\0\0\0" == 3)
+assert(#"1234567890" == 10)
+
+assert(string.byte("a") == 97)
+assert(string.byte("á") > 127)
+assert(string.byte(string.char(255)) == 255)
+assert(string.byte(string.char(0)) == 0)
+assert(string.byte("\0") == 0)
+assert(string.byte("\0\0alo\0x", -1) == string.byte('x'))
+assert(string.byte("ba", 2) == 97)
+assert(string.byte("\n\n", 2, -1) == 10)
+assert(string.byte("\n\n", 2, 2) == 10)
+assert(string.byte("") == nil)
+assert(string.byte("hi", -3) == nil)
+assert(string.byte("hi", 3) == nil)
+assert(string.byte("hi", 9, 10) == nil)
+assert(string.byte("hi", 2, 1) == nil)
+assert(string.char() == "")
+assert(string.char(0, 255, 0) == "\0\255\0")
+assert(string.char(0, string.byte("á"), 0) == "\0á\0")
+assert(string.char(string.byte("ál\0óu", 1, -1)) == "ál\0óu")
+assert(string.char(string.byte("ál\0óu", 1, 0)) == "")
+assert(string.char(string.byte("ál\0óu", -10, 100)) == "ál\0óu")
+print('+')
+
+assert(string.upper("ab\0c") == "AB\0C")
+assert(string.lower("\0ABCc%$") == "\0abcc%$")
+assert(string.rep('teste', 0) == '')
+assert(string.rep('tés\00tê', 2) == 'tés\0têtés\000tê')
+assert(string.rep('', 10) == '')
+
+assert(string.reverse"" == "")
+assert(string.reverse"\0\1\2\3" == "\3\2\1\0")
+assert(string.reverse"\0001234" == "4321\0")
+
+for i=0,30 do assert(string.len(string.rep('a', i)) == i) end
+
+assert(type(tostring(nil)) == 'string')
+assert(type(tostring(12)) == 'string')
+assert(''..12 == '12' and type(12 .. '') == 'string')
+assert(string.find(tostring{}, 'table:'))
+assert(string.find(tostring(print), 'function:'))
+assert(tostring(1234567890123) == '1234567890123')
+assert(#tostring('\0') == 1)
+assert(tostring(true) == "true")
+assert(tostring(false) == "false")
+print('+')
+
+x = '"ílo"\n\\'
+assert(string.format('%q%s', x, x) == '"\\"ílo\\"\\\n\\\\""ílo"\n\\')
+assert(string.format('%q', "\0") == [["\000"]])
+assert(string.format("\0%c\0%c%x\0", string.byte("á"), string.byte("b"), 140) ==
+              "\0á\0b8c\0")
+assert(string.format('') == "")
+assert(string.format("%c",34)..string.format("%c",48)..string.format("%c",90)..string.format("%c",100) ==
+       string.format("%c%c%c%c", 34, 48, 90, 100))
+assert(string.format("%s\0 is not \0%s", 'not be', 'be') == 'not be\0 is not \0be')
+assert(string.format("%%%d %010d", 10, 23) == "%10 0000000023")
+assert(tonumber(string.format("%f", 10.3)) == 10.3)
+x = string.format('"%-50s"', 'a')
+assert(#x == 52)
+assert(string.sub(x, 1, 4) == '"a  ')
+
+assert(string.format("-%.20s.20s", string.rep("%", 2000)) == "-"..string.rep("%", 20)..".20s")
+assert(string.format('"-%20s.20s"', string.rep("%", 2000)) ==
+       string.format("%q", "-"..string.rep("%", 2000)..".20s"))
+
+
+-- longest number that can be formated
+assert(string.len(string.format('%99.99f', -1e308)) >= 100)
+
+assert(loadstring("return 1\n--comentário sem EOL no final")() == 1)
+
+
+assert(table.concat{} == "")
+assert(table.concat({}, 'x') == "")
+assert(table.concat({'\0', '\0\1', '\0\1\2'}, '.\0.') == "\0.\0.\0\1.\0.\0\1\2")
+local a = {}; for i=1,3000 do a[i] = "xuxu" end
+assert(table.concat(a, "123").."123" == string.rep("xuxu123", 3000))
+assert(table.concat(a, "b", 20, 20) == "xuxu")
+assert(table.concat(a, "", 20, 21) == "xuxuxuxu")
+assert(table.concat(a, "", 22, 21) == "")
+assert(table.concat(a, "3", 2999) == "xuxu3xuxu")
+
+a = {"a","b","c"}
+assert(table.concat(a, ",", 1, 0) == "")
+assert(table.concat(a, ",", 1, 1) == "a")
+assert(table.concat(a, ",", 1, 2) == "a,b")
+assert(table.concat(a, ",", 2) == "b,c")
+assert(table.concat(a, ",", 3) == "c")
+assert(table.concat(a, ",", 4) == "")
+
+local locales = { "ptb", "ISO-8859-1", "pt_BR" }
+local function trylocale (w)
+  for _, l in ipairs(locales) do
+    if os.setlocale(l, w) then return true end
+  end
+  return false
+end
+
+if not trylocale("collate")  then
+  print("locale not supported")
+else
+  assert("alo" < "álo" and "álo" < "amo")
+end
+
+if not trylocale("ctype") then
+  print("locale not supported")
+else
+  assert(string.gsub("áéíóú", "%a", "x") == "xxxxx")
+  assert(string.gsub("áÁéÉ", "%l", "x") == "xÁxÉ")
+  assert(string.gsub("áÁéÉ", "%u", "x") == "áxéx")
+  assert(string.upper"áÁé{xuxu}ção" == "ÁÁÉ{XUXU}ÇÃO")
+end
+
+os.setlocale("C")
+assert(os.setlocale() == 'C')
+assert(os.setlocale(nil, "numeric") == 'C')
+
+print('OK')
+
+
diff --git a/test/PUC-Lua-5.1-tests/vararg.lua b/test/PUC-Lua-5.1-tests/vararg.lua
new file mode 100644
index 0000000..ae068fa
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/vararg.lua
@@ -0,0 +1,126 @@
+print('testing vararg')
+
+_G.arg = nil
+
+function f(a, ...)
+  assert(type(arg) == 'table')
+  assert(type(arg.n) == 'number')
+  for i=1,arg.n do assert(a[i]==arg[i]) end
+  return arg.n
+end
+
+function c12 (...)
+  assert(arg == nil)
+  local x = {...}; x.n = table.getn(x)
+  local res = (x.n==2 and x[1] == 1 and x[2] == 2)
+  if res then res = 55 end
+  return res, 2
+end
+
+function vararg (...) return arg end
+
+local call = function (f, args) return f(unpack(args, 1, args.n)) end
+
+assert(f() == 0)
+assert(f({1,2,3}, 1, 2, 3) == 3)
+assert(f({"alo", nil, 45, f, nil}, "alo", nil, 45, f, nil) == 5)
+
+assert(c12(1,2)==55)
+a,b = assert(call(c12, {1,2}))
+assert(a == 55 and b == 2)
+a = call(c12, {1,2;n=2})
+assert(a == 55 and b == 2)
+a = call(c12, {1,2;n=1})
+assert(not a)
+assert(c12(1,2,3) == false)
+local a = vararg(call(next, {_G,nil;n=2}))
+local b,c = next(_G)
+assert(a[1] == b and a[2] == c and a.n == 2)
+a = vararg(call(call, {c12, {1,2}}))
+assert(a.n == 2 and a[1] == 55 and a[2] == 2)
+a = call(print, {'+'})
+assert(a == nil)
+
+local t = {1, 10}
+function t:f (...) return self[arg[1]]+arg.n end
+assert(t:f(1,4) == 3 and t:f(2) == 11)
+print('+')
+
+lim = 20
+local i, a = 1, {}
+while i <= lim do a[i] = i+0.3; i=i+1 end
+
+function f(a, b, c, d, ...)
+  local more = {...}
+  assert(a == 1.3 and more[1] == 5.3 and
+         more[lim-4] == lim+0.3 and not more[lim-3])
+end
+
+function g(a,b,c)
+  assert(a == 1.3 and b == 2.3 and c == 3.3)
+end
+
+call(f, a)
+call(g, a)
+
+a = {}
+i = 1
+while i <= lim do a[i] = i; i=i+1 end
+assert(call(math.max, a) == lim)
+
+print("+")
+
+
+-- new-style varargs
+
+function oneless (a, ...) return ... end
+
+function f (n, a, ...)
+  local b
+  assert(arg == nil)
+  if n == 0 then
+    local b, c, d = ...
+    return a, b, c, d, oneless(oneless(oneless(...)))
+  else
+    n, b, a = n-1, ..., a
+    assert(b == ...)
+    return f(n, a, ...)
+  end
+end
+
+a,b,c,d,e = assert(f(10,5,4,3,2,1))
+assert(a==5 and b==4 and c==3 and d==2 and e==1)
+
+a,b,c,d,e = f(4)
+assert(a==nil and b==nil and c==nil and d==nil and e==nil)
+
+
+-- varargs for main chunks
+f = loadstring[[ return {...} ]]
+x = f(2,3)
+assert(x[1] == 2 and x[2] == 3 and x[3] == nil)
+
+
+f = loadstring[[
+  local x = {...}
+  for i=1,select('#', ...) do assert(x[i] == select(i, ...)) end
+  assert(x[select('#', ...)+1] == nil)
+  return true
+]]
+
+assert(f("a", "b", nil, {}, assert))
+assert(f())
+
+a = {select(3, unpack{10,20,30,40})}
+assert(table.getn(a) == 2 and a[1] == 30 and a[2] == 40)
+a = {select(1)}
+assert(next(a) == nil)
+a = {select(-1, 3, 5, 7)}
+assert(a[1] == 7 and a[2] == nil)
+a = {select(-2, 3, 5, 7)}
+assert(a[1] == 5 and a[2] == 7 and a[3] == nil)
+pcall(select, 10000)
+pcall(select, -10000)
+
+print('OK')
+
diff --git a/test/PUC-Lua-5.1-tests/verybig.lua b/test/PUC-Lua-5.1-tests/verybig.lua
new file mode 100644
index 0000000..59e0142
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/verybig.lua
@@ -0,0 +1,100 @@
+if rawget(_G, "_soft") then return 10 end
+
+print "testing large programs (>64k)"
+
+-- template to create a very big test file
+prog = [[$
+
+local a,b
+
+b = {$1$
+  b30009 = 65534,
+  b30010 = 65535,
+  b30011 = 65536,
+  b30012 = 65537,
+  b30013 = 16777214,
+  b30014 = 16777215,
+  b30015 = 16777216,
+  b30016 = 16777217,
+  b30017 = 4294967294,
+  b30018 = 4294967295,
+  b30019 = 4294967296,
+  b30020 = 4294967297,
+  b30021 = -65534,
+  b30022 = -65535,
+  b30023 = -65536,
+  b30024 = -4294967297,
+  b30025 = 15012.5,
+  $2$
+};
+
+assert(b.a50008 == 25004 and b["a11"] == 5.5)
+assert(b.a33007 == 16503.5 and b.a50009 == 25004.5)
+assert(b["b"..30024] == -4294967297)
+
+function b:xxx (a,b) return a+b end
+assert(b:xxx(10, 12) == 22)   -- pushself with non-constant index
+b.xxx = nil
+
+s = 0; n=0
+for a,b in pairs(b) do s=s+b; n=n+1 end
+assert(s==13977183656.5  and n==70001)
+
+require "checktable"
+stat(b)
+
+a = nil; b = nil
+print'+'
+
+function f(x) b=x end
+
+a = f{$3$} or 10
+
+assert(a==10)
+assert(b[1] == "a10" and b[2] == 5 and b[table.getn(b)-1] == "a50009")
+
+
+function xxxx (x) return b[x] end
+
+assert(xxxx(3) == "a11")
+
+a = nil; b=nil
+xxxx = nil
+
+return 10
+
+]]
+
+-- functions to fill in the $n$
+F = {
+function ()   -- $1$
+  for i=10,50009 do
+    io.write('a', i, ' = ', 5+((i-10)/2), ',\n')
+  end
+end,
+
+function ()   -- $2$
+  for i=30026,50009 do
+    io.write('b', i, ' = ', 15013+((i-30026)/2), ',\n')
+  end
+end,
+
+function ()   -- $3$
+  for i=10,50009 do
+    io.write('"a', i, '", ', 5+((i-10)/2), ',\n')
+  end
+end,
+}
+
+file = os.tmpname()
+io.output(file)
+for s in string.gmatch(prog, "$([^$]+)") do
+  local n = tonumber(s)
+  if not n then io.write(s) else F[n]() end
+end
+io.close()
+result = dofile(file)
+assert(os.remove(file))
+print'OK'
+return result
+
-- 
2.31.0


^ permalink raw reply	[flat|nested] 153+ messages in thread

* [Tarantool-patches] [PATCH v2 luajit 02/30] test: add compiling for C libs from PUC-Rio-Lua5.1
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 01/30] test: add " Sergey Kaplun via Tarantool-patches
@ 2021-03-26  7:42 ` Sergey Kaplun via Tarantool-patches
  2021-03-26 11:01   ` Sergey Ostanevich via Tarantool-patches
  2021-03-30 22:14   ` Igor Munkin via Tarantool-patches
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 03/30] test: adapt Lua 5.1 suite for out-of-source build Sergey Kaplun via Tarantool-patches
                   ` (29 subsequent siblings)
  31 siblings, 2 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26  7:42 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

This patch adds commands to create additional LuaC libraries for tests
in <attrib.lua>. Also, it renames `luaL_reg` to `luaL_Reg` in <lib1.c>
and <lib2.c> to be consistent with the current LuaJIT's LuaC API.

Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 test/PUC-Lua-5.1-tests/CMakeLists.txt      |  3 +-
 test/PUC-Lua-5.1-tests/libs/CMakeLists.txt | 48 +++++++++++++++++++++-
 test/PUC-Lua-5.1-tests/libs/lib1.c         |  2 +-
 test/PUC-Lua-5.1-tests/libs/lib2.c         |  2 +-
 4 files changed, 51 insertions(+), 4 deletions(-)

diff --git a/test/PUC-Lua-5.1-tests/CMakeLists.txt b/test/PUC-Lua-5.1-tests/CMakeLists.txt
index 773db0d..3c31aae 100644
--- a/test/PUC-Lua-5.1-tests/CMakeLists.txt
+++ b/test/PUC-Lua-5.1-tests/CMakeLists.txt
@@ -16,7 +16,8 @@ cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
 # variable as proposed in the first case.
 set(LUA_PATH "?\;${CMAKE_CURRENT_SOURCE_DIR}/?.lua")
 
-# Set PUC-Lua-5.1-tests-prepare target that creates <libs/P1>
+# Set PUC-Lua-5.1-tests-prepare target that contains rules
+# for <libs/*> libraries compilation and creates <libs/P1>
 # subdirectory.
 add_subdirectory(libs)
 
diff --git a/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt
index f24e7f3..aa64a44 100644
--- a/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt
+++ b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt
@@ -4,11 +4,57 @@
 # See the rationale in the root CMakeLists.txt.
 cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
 
+# Build additional C libraries for tests.
+macro(BuildTestCLib lib sources)
+  add_library(${lib} SHARED EXCLUDE_FROM_ALL ${sources})
+  target_include_directories(${lib} PRIVATE
+    ${LUAJIT_SOURCE_DIR}
+  )
+  set_target_properties(${lib} PROPERTIES
+    LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
+    PREFIX ""
+  )
+  # XXX: The dynamic libraries are loaded with LuaJIT binary and
+  # use symbols from it. So it is totally OK to have unresolved
+  # symbols at build time.
+  if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+    set_target_properties(${lib} PROPERTIES
+      LINK_FLAGS "-undefined dynamic_lookup"
+    )
+  elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+    # XXX: This is necessary mostly for openSUSE builds, see also
+    # https://bugzilla.suse.com/show_bug.cgi?id=1012388.
+    # Just strip out the linker flag to suppress this linker
+    # option.
+    string(REPLACE "-Wl,--no-undefined" ""
+      CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}"
+    )
+  endif()
+  list(APPEND TESTLIBS ${lib})
+endmacro()
+
+BuildTestCLib(lib1  lib1.c)
+BuildTestCLib(lib11 lib1.c lib11.c)
+BuildTestCLib(lib2  lib2.c)
+BuildTestCLib(lib21 lib2.c lib21.c)
+
+# Create exact copy of the lib2 library for tests in attrib.lua.
+set(LIB2ORIG "${CMAKE_CURRENT_BINARY_DIR}/lib2${CMAKE_SHARED_LIBRARY_SUFFIX}")
+set(LIB2COPY "${CMAKE_CURRENT_BINARY_DIR}/-lib2${CMAKE_SHARED_LIBRARY_SUFFIX}")
+add_custom_command(
+  OUTPUT ${LIB2COPY}
+  COMMENT "Copying lib2 to -lib2 for PUC-Rio Lua 5.1 tests"
+  COMMAND ${CMAKE_COMMAND} -E copy ${LIB2ORIG} ${LIB2COPY}
+  DEPENDS ${TESTLIBS}
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+)
+list(APPEND TESTLIBS ${LIB2COPY})
+
 # The original tarball contains subdirectory "libs" with an empty
 # subdirectory "libs/P1", to be used by tests.
 # Instead of tracking empty directory with some anchor-file for
 # git, create this directory via CMake.
-add_custom_target(PUC-Lua-5.1-tests-prepare)
+add_custom_target(PUC-Lua-5.1-tests-prepare DEPENDS ${TESTLIBS})
 add_custom_command(TARGET PUC-Lua-5.1-tests-prepare
   COMMENT "Create directory for PUC-Rio Lua 5.1 tests"
   COMMAND ${CMAKE_COMMAND} -E make_directory P1
diff --git a/test/PUC-Lua-5.1-tests/libs/lib1.c b/test/PUC-Lua-5.1-tests/libs/lib1.c
index 812bb9a..22fe6de 100644
--- a/test/PUC-Lua-5.1-tests/libs/lib1.c
+++ b/test/PUC-Lua-5.1-tests/libs/lib1.c
@@ -14,7 +14,7 @@ static int id (lua_State *L) {
 }
 
 
-static const struct luaL_reg funcs[] = {
+static const struct luaL_Reg funcs[] = {
   {"id", id},
   {NULL, NULL}
 };
diff --git a/test/PUC-Lua-5.1-tests/libs/lib2.c b/test/PUC-Lua-5.1-tests/libs/lib2.c
index 9972cbe..876a212 100644
--- a/test/PUC-Lua-5.1-tests/libs/lib2.c
+++ b/test/PUC-Lua-5.1-tests/libs/lib2.c
@@ -12,7 +12,7 @@ static int id (lua_State *L) {
 }
 
 
-static const struct luaL_reg funcs[] = {
+static const struct luaL_Reg funcs[] = {
   {"id", id},
   {NULL, NULL}
 };
-- 
2.31.0


^ permalink raw reply	[flat|nested] 153+ messages in thread

* [Tarantool-patches] [PATCH v2 luajit 03/30] test: adapt Lua 5.1 suite for out-of-source build
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 01/30] test: add " Sergey Kaplun via Tarantool-patches
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 02/30] test: add compiling for C libs from PUC-Rio-Lua5.1 Sergey Kaplun via Tarantool-patches
@ 2021-03-26  7:42 ` Sergey Kaplun via Tarantool-patches
  2021-03-26 11:07   ` Sergey Ostanevich via Tarantool-patches
  2021-03-31 22:58   ` Igor Munkin via Tarantool-patches
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 04/30] test: remove quotes in progname from <main.lua> Sergey Kaplun via Tarantool-patches
                   ` (28 subsequent siblings)
  31 siblings, 2 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26  7:42 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

When tests are run out-of-source redefined `dofile()` function
failed to find file to load. So, fullpath is detected considering
`arg[0]` value. Moreover, some tests use `loadfile()` instead, so
their argument is adjusted to the full path to the files.

However, test in <verybig.lua> creates a temporary file
and executes it via `dofile()` too, so this case is handled by
the second argument -- `prefix` equals an empty string for
current working directory.

Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 test/PUC-Lua-5.1-tests/all.lua     | 17 +++++++++++++----
 test/PUC-Lua-5.1-tests/verybig.lua |  4 +++-
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/test/PUC-Lua-5.1-tests/all.lua b/test/PUC-Lua-5.1-tests/all.lua
index 8c4afac..85beff8 100755
--- a/test/PUC-Lua-5.1-tests/all.lua
+++ b/test/PUC-Lua-5.1-tests/all.lua
@@ -58,9 +58,18 @@ end
 --
 -- redefine dofile to run files through dump/undump
 --
-dofile = function (n)
+-- LuaJIT: Adapt tests for testing with out-of-source build.
+-- XXX: Test in <verybig.lua> creates a temporary file
+-- and executes it via `dofile()` too, so this case is handled by
+-- the second argument -- `prefix` equals an empty string for
+-- current working directory.
+-- <all.lua> is in the same directory, where are other common
+-- executed files situated.
+local path_to_sources = arg[0]:gsub('([^/]+)%.lua$', '')
+dofile = function (n, prefix)
+  local pr = prefix or path_to_sources
   showmem()
-  local f = assert(loadfile(n))
+  local f = assert(loadfile(pr..n))
   local b = string.dump(f)
   f = assert(loadstring(b))
   return f()
@@ -77,7 +86,7 @@ do
   end
 end
 
-local f = assert(loadfile('gc.lua'))
+local f = assert(loadfile(path_to_sources..'gc.lua'))
 f()
 dofile('db.lua')
 assert(dofile('calls.lua') == deep and deep)
@@ -88,7 +97,7 @@ assert(dofile('locals.lua') == 5)
 dofile('constructs.lua')
 dofile('code.lua')
 do
-  local f = coroutine.wrap(assert(loadfile('big.lua')))
+  local f = coroutine.wrap(assert(loadfile(path_to_sources..'big.lua')))
   assert(f() == 'b')
   assert(f() == 'a')
 end
diff --git a/test/PUC-Lua-5.1-tests/verybig.lua b/test/PUC-Lua-5.1-tests/verybig.lua
index 59e0142..edb170d 100644
--- a/test/PUC-Lua-5.1-tests/verybig.lua
+++ b/test/PUC-Lua-5.1-tests/verybig.lua
@@ -93,7 +93,9 @@ for s in string.gmatch(prog, "$([^$]+)") do
   if not n then io.write(s) else F[n]() end
 end
 io.close()
-result = dofile(file)
+-- LuaJIT: Adapt test for testing with out-of-source build.
+-- See comment in <all.lua> near `dofile()` redefinition.
+result = dofile(file, "")
 assert(os.remove(file))
 print'OK'
 return result
-- 
2.31.0


^ permalink raw reply	[flat|nested] 153+ messages in thread

* [Tarantool-patches] [PATCH v2 luajit 04/30] test: remove quotes in progname from <main.lua>
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
                   ` (2 preceding siblings ...)
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 03/30] test: adapt Lua 5.1 suite for out-of-source build Sergey Kaplun via Tarantool-patches
@ 2021-03-26  7:42 ` Sergey Kaplun via Tarantool-patches
  2021-03-26 11:12   ` Sergey Ostanevich via Tarantool-patches
  2021-03-31 22:58   ` Igor Munkin via Tarantool-patches
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 05/30] test: adapt arg availability test from Lua suite Sergey Kaplun via Tarantool-patches
                   ` (27 subsequent siblings)
  31 siblings, 2 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26  7:42 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

When LUAJIT_TEST_COMMAND extend the least `arg` with
some string containing double quotes, bash failed to exec this
command for child test.

This patch removes edged '"' to be able run extended command
containing '"' and run other test suites.

Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 test/PUC-Lua-5.1-tests/main.lua | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua
index f520896..4f8b8bf 100644
--- a/test/PUC-Lua-5.1-tests/main.lua
+++ b/test/PUC-Lua-5.1-tests/main.lua
@@ -11,7 +11,9 @@ out = os.tmpname()
 do
   local i = 0
   while arg[i] do i=i-1 end
-  progname = '"'..arg[i+1]..'"'
+  -- LuaJIT: remove edged '"' to be able run extended command
+  -- containing '"' and run other test suites.
+  progname = arg[i+1]
 end
 print(progname)
 
@@ -53,10 +55,12 @@ prepfile("print(a)", otherprog)
 RUN("lua -l %s -l%s -lstring -l io %s > %s", prog, otherprog, otherprog, out)
 checkout("1\n2\n2\n")
 
+-- LuaJIT: test file is adapted for LuaJIT's test system, see
+-- the comment near `progname` initialization.
 local a = [[
   assert(table.getn(arg) == 3 and arg[1] == 'a' and
          arg[2] == 'b' and arg[3] == 'c')
-  assert(arg[-1] == '--' and arg[-2] == "-e " and arg[-3] == %s)
+  assert(arg[-1] == '--' and arg[-2] == "-e " and arg[-3] == '%s')
   assert(arg[4] == nil and arg[-4] == nil)
   local a, b, c = ...
   assert(... == 'a' and a == 'a' and b == 'b' and c == 'c')
-- 
2.31.0


^ permalink raw reply	[flat|nested] 153+ messages in thread

* [Tarantool-patches] [PATCH v2 luajit 05/30] test: adapt arg availability test from Lua suite
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
                   ` (3 preceding siblings ...)
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 04/30] test: remove quotes in progname from <main.lua> Sergey Kaplun via Tarantool-patches
@ 2021-03-26  7:42 ` Sergey Kaplun via Tarantool-patches
  2021-03-26 11:22   ` Sergey Ostanevich via Tarantool-patches
  2021-03-31 22:58   ` Igor Munkin via Tarantool-patches
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 06/30] test: disable PUC Lua tests confused by -v output Sergey Kaplun via Tarantool-patches
                   ` (26 subsequent siblings)
  31 siblings, 2 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26  7:42 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

The argument table `arg` can be read (and modified) by `LUA_INIT` and
`-e` chunks since the commit 92d9ff211ae864777a8580b5a7326d5f408161ce
(Set arg table before evaluating LUA_INIT and -e chunks.).

This behaviour is similar to Lua 5.3, so the test was adapted
considering PUC-Rio Lua 5.3 test suite taken from
https://www.lua.org/tests/lua-5.3.0-tests.tar.gz.

Closes tarantool/tarantool#5686
Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 test/PUC-Lua-5.1-tests/main.lua | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua
index 4f8b8bf..c11a576 100644
--- a/test/PUC-Lua-5.1-tests/main.lua
+++ b/test/PUC-Lua-5.1-tests/main.lua
@@ -69,9 +69,19 @@ a = string.format(a, progname)
 prepfile(a)
 RUN('lua "-e " -- %s a b c', prog)
 
-prepfile"assert(arg==nil)"
+-- test 'arg' availability in libraries
+-- LuaJIT: LuaJIT v2.1.0-beta3 has extension from Lua 5.3:
+-- The argument table `arg` can be read (and modified)
+-- by `LUA_INIT` and `-e` chunks.
+-- See commit 92d9ff211ae864777a8580b5a7326d5f408161ce
+-- (Set arg table before evaluating LUA_INIT and -e chunks.).
+-- See also https://github.com/tarantool/tarantool/issues/5686.
+-- In Lua 5.3 this feature was introduced via commit
+-- 23f0ff95177eda2e0a80e3a48562cc6837705735.
+-- Test is adapted from PUC-Rio Lua 5.3 test suite.
+prepfile"assert(arg)"
 prepfile("assert(arg)", otherprog)
-RUN("lua -l%s - < %s", prog, otherprog)
+RUN('env LUA_PATH="?;;" lua -l%s - < %s', prog, otherprog)
 
 prepfile""
 RUN("lua - < %s > %s", prog, out)
-- 
2.31.0


^ permalink raw reply	[flat|nested] 153+ messages in thread

* [Tarantool-patches] [PATCH v2 luajit 06/30] test: disable PUC Lua tests confused by -v output
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
                   ` (4 preceding siblings ...)
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 05/30] test: adapt arg availability test from Lua suite Sergey Kaplun via Tarantool-patches
@ 2021-03-26  7:42 ` Sergey Kaplun via Tarantool-patches
  2021-03-26 11:26   ` Sergey Ostanevich via Tarantool-patches
  2021-03-31 22:58   ` Igor Munkin via Tarantool-patches
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 07/30] test: disable Lua tests for bytecode with header Sergey Kaplun via Tarantool-patches
                   ` (25 subsequent siblings)
  31 siblings, 2 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26  7:42 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

Version and status are printed in stdout instead stderr since
LuaJIT-2.0.0-beta11 (as it is not an error message).
See commit 0bd1a66f2f055211ef55834ccebca3b82d03c735
(Print version and JIT status to stdout, not stderr.).
This behavior is the same as in Lua 5.2.

This patch disables tests confused by unexpected -v output to stdout.

Relates to tarantool/tarantool#5687
Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 test/PUC-Lua-5.1-tests/main.lua | 28 ++++++++++++++++++++--------
 1 file changed, 20 insertions(+), 8 deletions(-)

diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua
index c11a576..56f56a0 100644
--- a/test/PUC-Lua-5.1-tests/main.lua
+++ b/test/PUC-Lua-5.1-tests/main.lua
@@ -103,26 +103,37 @@ prepfile[[
 RUN("lua - < %s > %s", prog, out)
 checkout("1\tnil\n")
 
+-- Version and status are printed in stdout instead stderr since
+-- LuaJIT-2.0.0-beta11 (as it is not an error message).
+-- See commit 0bd1a66f2f055211ef55834ccebca3b82d03c735
+-- (Print version and JIT status to stdout, not stderr.).
+-- This behavior is the same as in Lua 5.2.
+-- In Lua 5.2 this feature was introduced via commit
+-- 9e7de9473c65baee1f567852a778f2d33a47ea83.
+-- See also https://github.com/tarantool/tarantool/issues/5687.
 prepfile[[
 = (6*2-6) -- ===
 a
 = 10
 print(a)
 = a]]
-RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
-checkout("6\n10\n10\n\n")
+-- FIXME: Behavior is different for LuaJIT. See the comment above.
+-- RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
+-- checkout("6\n10\n10\n\n")
 
 prepfile("a = [[b\nc\nd\ne]]\n=a")
 print(prog)
-RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
-checkout("b\nc\nd\ne\n\n")
+-- FIXME: Behavior is different for LuaJIT. See the comment above.
+-- RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
+-- checkout("b\nc\nd\ne\n\n")
 
 prompt = "alo"
 prepfile[[ --
 a = 2
 ]]
-RUN([[lua "-e_PROMPT='%s'" -i < %s > %s]], prompt, prog, out)
-checkout(string.rep(prompt, 3).."\n")
+-- FIXME: Behavior is different for LuaJIT. See the comment above.
+-- RUN([[lua "-e_PROMPT='%s'" -i < %s > %s]], prompt, prog, out)
+-- checkout(string.rep(prompt, 3).."\n")
 
 s = [=[ --
 function f ( x )
@@ -140,8 +151,9 @@ assert( a == b )
 =f( 11 )  ]=]
 s = string.gsub(s, ' ', '\n\n')
 prepfile(s)
-RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
-checkout("11\n1\t2\n\n")
+-- FIXME: Behavior is different for LuaJIT. See the comment above.
+-- RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
+-- checkout("11\n1\t2\n\n")
 
 prepfile[[#comment in 1st line without \n at the end]]
 RUN("lua %s", prog)
-- 
2.31.0


^ permalink raw reply	[flat|nested] 153+ messages in thread

* [Tarantool-patches] [PATCH v2 luajit 07/30] test: disable Lua tests for bytecode with header
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
                   ` (5 preceding siblings ...)
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 06/30] test: disable PUC Lua tests confused by -v output Sergey Kaplun via Tarantool-patches
@ 2021-03-26  7:42 ` Sergey Kaplun via Tarantool-patches
  2021-03-26 11:30   ` Sergey Ostanevich via Tarantool-patches
  2021-03-31 22:59   ` Igor Munkin via Tarantool-patches
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 08/30] test: disable JIT for GC step counting tests Sergey Kaplun via Tarantool-patches
                   ` (24 subsequent siblings)
  31 siblings, 2 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26  7:42 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

Loading bytecode with an extra header (BOM or "#") is disabled
for security reasons since LuaJIT-2.0.0-beta10.
For more information see comment for `lj_lex_setup()`
in <src/lj_lex.c>.
Also see commit 53a285c0c3544ff5dea7c67b741c3c2d06d22b47
(Disable loading bytecode with an extra header (BOM or #!).).

These tests are disabled for LuaJIT.

Relates to tarantool/tarantool#5691
Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 test/PUC-Lua-5.1-tests/main.lua | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua
index 56f56a0..cf6d533 100644
--- a/test/PUC-Lua-5.1-tests/main.lua
+++ b/test/PUC-Lua-5.1-tests/main.lua
@@ -158,13 +158,23 @@ prepfile(s)
 prepfile[[#comment in 1st line without \n at the end]]
 RUN("lua %s", prog)
 
+-- Loading bytecode with an extra header (BOM or "#") is disabled
+-- for security reasons since LuaJIT-2.0.0-beta10.
+-- For more information see comment for `lj_lex_setup()`
+-- in <src/lj_lex.c>.
+-- Also see commit 53a285c0c3544ff5dea7c67b741c3c2d06d22b47
+-- (Disable loading bytecode with an extra header (BOM or #!).).
+-- See also https://github.com/tarantool/tarantool/issues/5691.
+-- FIXME: test is disabled for LuaJIT.
 prepfile("#comment with a binary file\n"..string.dump(loadstring("print(1)")))
-RUN("lua %s > %s", prog, out)
-checkout("1\n")
+-- RUN("lua %s > %s", prog, out)
+-- checkout("1\n")
 
 prepfile("#comment with a binary file\r\n"..string.dump(loadstring("print(1)")))
-RUN("lua %s > %s", prog, out)
-checkout("1\n")
+-- Behavior is different for LuaJIT. See the comment above.
+-- FIXME: test is disabled for LuaJIT.
+-- RUN("lua %s > %s", prog, out)
+-- checkout("1\n")
 
 -- close Lua with an open file
 prepfile(string.format([[io.output(%q); io.write('alo')]], out))
-- 
2.31.0


^ permalink raw reply	[flat|nested] 153+ messages in thread

* [Tarantool-patches] [PATCH v2 luajit 08/30] test: disable JIT for GC step counting tests
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
                   ` (6 preceding siblings ...)
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 07/30] test: disable Lua tests for bytecode with header Sergey Kaplun via Tarantool-patches
@ 2021-03-26  7:42 ` Sergey Kaplun via Tarantool-patches
  2021-03-26 11:32   ` Sergey Ostanevich via Tarantool-patches
  2021-03-30 22:14   ` Igor Munkin via Tarantool-patches
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 09/30] test: disable Lua suite tests for line hook Sergey Kaplun via Tarantool-patches
                   ` (23 subsequent siblings)
  31 siblings, 2 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26  7:42 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

JIT compilation can unpredictable allocate or reference objects (or
traces itself). So, the amount of GC steps can vary from run to run.

This patch disables JIT machinery, if it is enabled, for stable GC
results.

Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 test/PUC-Lua-5.1-tests/gc.lua | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/test/PUC-Lua-5.1-tests/gc.lua b/test/PUC-Lua-5.1-tests/gc.lua
index 86a9f75..072bbe9 100644
--- a/test/PUC-Lua-5.1-tests/gc.lua
+++ b/test/PUC-Lua-5.1-tests/gc.lua
@@ -108,11 +108,21 @@ local function dosteps (siz)
   return i
 end
 
+-- LuaJIT: JIT compilation can unpredictable allocate or reference
+-- objects (or traces itself). Disable it if necessary for
+-- this chunk for stable GC results.
+local jit_is_enabled = jit.status()
+if jit_is_enabled then
+  jit.off()
+end
 assert(dosteps(0) > 10)
 assert(dosteps(6) < dosteps(2))
 assert(dosteps(10000) == 1)
 assert(collectgarbage("step", 1000000) == true)
 assert(collectgarbage("step", 1000000))
+if jit_is_enabled then
+  jit.on()
+end
 
 
 do
-- 
2.31.0


^ permalink raw reply	[flat|nested] 153+ messages in thread

* [Tarantool-patches] [PATCH v2 luajit 09/30] test: disable Lua suite tests for line hook
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
                   ` (7 preceding siblings ...)
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 08/30] test: disable JIT for GC step counting tests Sergey Kaplun via Tarantool-patches
@ 2021-03-26  7:42 ` Sergey Kaplun via Tarantool-patches
  2021-03-26 11:35   ` Sergey Ostanevich via Tarantool-patches
  2021-03-31 22:59   ` Igor Munkin via Tarantool-patches
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 10/30] test: adapt test for debug.setlocal in Lua suite Sergey Kaplun via Tarantool-patches
                   ` (22 subsequent siblings)
  31 siblings, 2 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26  7:42 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

FIXME: LuaJIT interprets a return from a new function loaded by
`loadstring()` with a change line number for bytecode position
unlike Lua does. This looks like "implementation-defined behaviour"
mentioned in https://luajit.org/status.html.

All tests checked the debug hook for a new line of code are affected
and disabled by this patch.

Relates to tarantool/tarantool#5693
Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 test/PUC-Lua-5.1-tests/db.lua | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua
index 9d2c86f..a8c7196 100644
--- a/test/PUC-Lua-5.1-tests/db.lua
+++ b/test/PUC-Lua-5.1-tests/db.lua
@@ -95,6 +95,23 @@ repeat
   assert(g(f) == 'a')
 until 1
 
+-- FIXME: LuaJIT interprets a return from calling result of
+-- `loadstring()` with a new line number unlike Lua does.
+-- Here is an example (it is joined in one line intend):
+--[[
+debug.sethook(function(_, l) print("LINE: "..l) end, "l") loadstring("\n\ns=nil")() debug.sethook()
+--]]
+-- This chunk prints for LuaJIT:
+--[[
+LINE: 3
+LINE: 1
+--]]
+-- But for Lua 5.1 it is only "LINE: 3" in the output.
+-- See also https://github.com/tarantool/tarantool/issues/5693.
+-- Considering implementation-defined behaviour diference
+-- (see also https://luajit.org/status.html) test is disabled for
+-- LuaJIT.
+--[=[
 test([[if
 math.sin(1)
 then
@@ -149,7 +166,7 @@ end
 ]], {1,2,1,2,1,3})
 
 test([[for i=1,4 do a=1 end]], {1,1,1,1,1})
-
+--]=]
 
 
 print'+'
-- 
2.31.0


^ permalink raw reply	[flat|nested] 153+ messages in thread

* [Tarantool-patches] [PATCH v2 luajit 10/30] test: adapt test for debug.setlocal in Lua suite
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
                   ` (8 preceding siblings ...)
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 09/30] test: disable Lua suite tests for line hook Sergey Kaplun via Tarantool-patches
@ 2021-03-26  7:42 ` Sergey Kaplun via Tarantool-patches
  2021-03-26 11:44   ` Sergey Ostanevich via Tarantool-patches
  2021-03-30 22:14   ` Igor Munkin via Tarantool-patches
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 11/30] test: adapt getlocal PUC test for vararg func Sergey Kaplun via Tarantool-patches
                   ` (21 subsequent siblings)
  31 siblings, 2 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26  7:42 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=UTF-8, Size: 1262 bytes --]

LuaJIT: Lua 5.1 interprets `...` in the vararg functions like
an additional first argument unlike LuaJIT does.
This behaviour is extension is from Lua 5.2.

This patch adapted test considering LuaJIT's and Lua 5.2 behaviour.
The test is adapted like it done in Lua 5.2 test suite taken from
https://www.lua.org/tests/lua-5.2.0-tests.tar.gz.

Closes tarantool/tarantool#5694
Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 test/PUC-Lua-5.1-tests/db.lua | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua
index a8c7196..e5d8885 100644
--- a/test/PUC-Lua-5.1-tests/db.lua
+++ b/test/PUC-Lua-5.1-tests/db.lua
@@ -221,6 +221,13 @@ assert(debug.getinfo(1, "l").currentline == L+11)  -- check count of lines
 
 
 function g(...)
+  -- LuaJIT: Lua 5.1 interprets `...` in the vararg functions like
+  -- an additional first argument unlike LuaJIT does.
+  -- This extension is from Lua 5.2.
+  -- See also https://github.com/tarantool/tarantool/issues/5694.
+  -- Test is adapted from PUC-Rio Lua 5.2 test suite by adding
+  -- additional variable `arg`.
+  local arg = {...}
   do local a,b,c; a=math.sin(40); end
   local feijao
   local AAAA,B = "xuxu", "mamão"
-- 
2.31.0


^ permalink raw reply	[flat|nested] 153+ messages in thread

* [Tarantool-patches] [PATCH v2 luajit 11/30] test: adapt getlocal PUC test for vararg func
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
                   ` (9 preceding siblings ...)
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 10/30] test: adapt test for debug.setlocal in Lua suite Sergey Kaplun via Tarantool-patches
@ 2021-03-26  7:42 ` Sergey Kaplun via Tarantool-patches
  2021-03-26 11:47   ` Sergey Ostanevich via Tarantool-patches
  2021-03-30 22:15   ` Igor Munkin via Tarantool-patches
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 12/30] test: adapt PUC Lua test with count hooks Sergey Kaplun via Tarantool-patches
                   ` (20 subsequent siblings)
  31 siblings, 2 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26  7:42 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

Lua 5.1 interprets `...` in the vararg functions like an additional
first argument unlike LuaJIT does. So, `a:f()` function will not set
corresponding table `arg`, as test expects.

Implicit `arg` parameter for old-style vararg functions was finally
removed in Lua 5.2. The test is adapted from PUC-Rio Lua 5.2 test suite
by removing additional check for amountt of arguments via `arg.n`.
Lua 5.2 test suite is taken from
https://www.lua.org/tests/lua-5.2.0-tests.tar.gz.

Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 test/PUC-Lua-5.1-tests/db.lua | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua
index e5d8885..6985c29 100644
--- a/test/PUC-Lua-5.1-tests/db.lua
+++ b/test/PUC-Lua-5.1-tests/db.lua
@@ -300,7 +300,16 @@ debug.sethook(function (e)
 end, "c")
 
 a:f(1,2,3,4,5)
-assert(X.self == a and X.a == 1   and X.b == 2 and X.arg.n == 3 and X.c == nil)
+
+-- LuaJIT: Lua 5.1 interprets `...` in the vararg functions like
+-- an additional first argument unlike LuaJIT does.
+-- So, `a:f()` function will not set corresponding table `arg`,
+-- as test expects.
+-- Implicit `arg` parameter for old-style vararg functions was
+-- finally removed in Lua 5.2
+-- The test is adapted from PUC-Rio Lua 5.2 test suite by removing
+-- additional `arg.n == 3` check.
+assert(X.self == a and X.a == 1   and X.b == 2 and X.c == nil)
 assert(XX == 12)
 assert(debug.gethook() == nil)
 
-- 
2.31.0


^ permalink raw reply	[flat|nested] 153+ messages in thread

* [Tarantool-patches] [PATCH v2 luajit 12/30] test: adapt PUC Lua test with count hooks
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
                   ` (10 preceding siblings ...)
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 11/30] test: adapt getlocal PUC test for vararg func Sergey Kaplun via Tarantool-patches
@ 2021-03-26  7:42 ` Sergey Kaplun via Tarantool-patches
  2021-03-26 11:49   ` Sergey Ostanevich via Tarantool-patches
  2021-03-30 22:15   ` Igor Munkin via Tarantool-patches
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 13/30] test: disable PUC Lua test for tail call info Sergey Kaplun via Tarantool-patches
                   ` (19 subsequent siblings)
  31 siblings, 2 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26  7:42 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

LuaJIT does not check hooks at traces without defined
-DLUAJIT_ENABLE_CHECKHOOK. For more information see <src/lj_record.c>
or commit 6bce6b118eeb2bb7f36157de158e5cccf0ea68e5 (Add compile-time
option LUAJIT_ENABLE_CHECKHOOK. Disabled by default.).

This patch adapts these tests for LuaJIT by disabling JIT while testing
count hooks.

Closes tarantool/tarantool#5701
Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 test/PUC-Lua-5.1-tests/db.lua | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua
index 6985c29..c1a635a 100644
--- a/test/PUC-Lua-5.1-tests/db.lua
+++ b/test/PUC-Lua-5.1-tests/db.lua
@@ -347,6 +347,18 @@ assert(debug.setupvalue(io.read, 1, 10) == nil)
 
 -- testing count hooks
 local a=0
+-- LuaJIT: LuaJIT does not check hooks at traces without defined
+-- -DLUAJIT_ENABLE_CHECKHOOK.
+-- For more information see <src/lj_record.c> or commit
+-- 6bce6b118eeb2bb7f36157de158e5cccf0ea68e5 (Add compile-time
+-- option LUAJIT_ENABLE_CHECKHOOK. Disabled by default.).
+-- See also https://github.com/tarantool/tarantool/issues/5701
+-- Test is adapted for LuaJIT by disabling JIT while
+-- testing count hooks.
+local jit_is_enabled = jit.status()
+if jit_is_enabled then
+  jit.off()
+end
 debug.sethook(function (e) a=a+1 end, "", 1)
 a=0; for i=1,1000 do end; assert(1000 < a and a < 1012)
 debug.sethook(function (e) a=a+1 end, "", 4)
@@ -359,6 +371,9 @@ debug.sethook(print, "", 2^24 - 1)   -- count upperbound
 local f,m,c = debug.gethook()
 assert(({debug.gethook()})[3] == 2^24 - 1)
 debug.sethook()
+if jit_is_enabled then
+  jit.on()
+end
 
 
 -- tests for tail calls
-- 
2.31.0


^ permalink raw reply	[flat|nested] 153+ messages in thread

* [Tarantool-patches] [PATCH v2 luajit 13/30] test: disable PUC Lua test for tail call info
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
                   ` (11 preceding siblings ...)
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 12/30] test: adapt PUC Lua test with count hooks Sergey Kaplun via Tarantool-patches
@ 2021-03-26  7:42 ` Sergey Kaplun via Tarantool-patches
  2021-03-26 14:43   ` Sergey Ostanevich via Tarantool-patches
  2021-03-30 22:15   ` Igor Munkin via Tarantool-patches
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 14/30] test: adapt activeline check in the PUC Lua test Sergey Kaplun via Tarantool-patches
                   ` (18 subsequent siblings)
  31 siblings, 2 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26  7:42 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

LuaJIT does not provide information about tail calls in debug.getinfo(),
unlike Lua does. This missed feature is described in
https://luajit.org/status.html.

This patch disables tests for tail call checks and getfenv() checks,
because tail calls do not provide an additional level for LuaJIT
and level number given to getfenv() should be changed.

Relates to tarantool/tarantool#5702
Relates to tarantool/tarantool#5703
Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 test/PUC-Lua-5.1-tests/db.lua | 30 ++++++++++++++++++++++--------
 1 file changed, 22 insertions(+), 8 deletions(-)

diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua
index c1a635a..b363abc 100644
--- a/test/PUC-Lua-5.1-tests/db.lua
+++ b/test/PUC-Lua-5.1-tests/db.lua
@@ -400,19 +400,29 @@ function g1(x) g(x) end
 
 local function h (x) local f=g1; return f(x) end
 
-h(true)
+-- LuaJIT does not provide information about tail calls,
+-- unlike Lua does. See also https://luajit.org/status.html.
+-- getfenv() behaviour is also different here,
+-- because tail calls do not provide additional level for LuaJIT
+-- and level number should be changed.
+-- FIXME: Test is disabled for LuaJIT.
+-- See also https://github.com/tarantool/tarantool/issues/5702.
+-- h(true)
 
 local b = {}
-debug.sethook(function (e) table.insert(b, e) end, "cr")
-h(false)
-debug.sethook()
+-- Behavior is different for LuaJIT. See the comment above.
+-- FIXME: Test is disabled for LuaJIT.
+-- debug.sethook(function (e) table.insert(b, e) end, "cr")
+-- h(false)
+-- debug.sethook()
 local res = {"return",   -- first return (from sethook)
   "call", "call", "call", "call",
   "return", "tail return", "return", "tail return",
   "call",    -- last call (to sethook)
 }
-for _, k in ipairs(res) do assert(k == table.remove(b, 1)) end
-
+-- Behavior is different for LuaJIT. See the comment above.
+-- FIXME: Test is disabled for LuaJIT.
+-- for _, k in ipairs(res) do assert(k == table.remove(b, 1)) end
 
 lim = 30000
 local function foo (x)
@@ -423,7 +433,9 @@ local function foo (x)
   end
 end
 
-foo(lim)
+-- Behavior is different for LuaJIT. See the comment above.
+-- FIXME: Test is disabled for LuaJIT.
+-- foo(lim)
 
 
 print"+"
@@ -459,7 +471,9 @@ end
 
 local co = coroutine.create(f)
 coroutine.resume(co, 3)
-checktraceback(co, {"yield", "db.lua", "tail", "tail", "tail"})
+-- Behavior is different for LuaJIT. See the comment to h() above.
+-- FIXME: Test is disabled for LuaJIT.
+-- checktraceback(co, {"yield", "db.lua", "tail", "tail", "tail"})
 
 
 co = coroutine.create(function (x)
-- 
2.31.0


^ permalink raw reply	[flat|nested] 153+ messages in thread

* [Tarantool-patches] [PATCH v2 luajit 14/30] test: adapt activeline check in the PUC Lua test
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
                   ` (12 preceding siblings ...)
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 13/30] test: disable PUC Lua test for tail call info Sergey Kaplun via Tarantool-patches
@ 2021-03-26  7:42 ` Sergey Kaplun via Tarantool-patches
  2021-03-26 14:50   ` Sergey Ostanevich via Tarantool-patches
  2021-03-30 22:15   ` Igor Munkin via Tarantool-patches
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 15/30] test: disable PUC-Lua test for per-coroutine hooks Sergey Kaplun via Tarantool-patches
                   ` (17 subsequent siblings)
  31 siblings, 2 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26  7:42 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

LuaJIT does not report line with single "end" statement
(the last line of the function) as an active line in
debug.getinfo(), unlike Lua does. There is no bytecode
related to this line, so it is "unreachable" and
may be considered not active.

This patch excludes the last line of a function from the check,
considering LuaJIT's behaviour.

Closes tarantool/tarantool#5708
Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 test/PUC-Lua-5.1-tests/db.lua | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua
index b363abc..c704877 100644
--- a/test/PUC-Lua-5.1-tests/db.lua
+++ b/test/PUC-Lua-5.1-tests/db.lua
@@ -491,7 +491,15 @@ local _, l = coroutine.resume(co, 10)
 local x = debug.getinfo(co, 1, "lfLS")
 assert(x.currentline == l.currentline and x.activelines[x.currentline])
 assert(type(x.func) == "function")
-for i=x.linedefined + 1, x.lastlinedefined do
+-- LuaJIT does not report line with single "end" statement
+-- (the last line of the function) as an active line in
+-- debug.getinfo(), unlike Lua does. There is no bytecode
+-- related to this line, so it is "unreachable" and
+-- may be considered not active.
+-- See also https://github.com/tarantool/tarantool/issues/5708.
+-- LuaJIT: Test is adapted for LuaJIT's behaviour by avoiding
+-- the last line check.
+for i=x.linedefined + 1, x.lastlinedefined - 1 do
   assert(x.activelines[i])
   x.activelines[i] = nil
 end
-- 
2.31.0


^ permalink raw reply	[flat|nested] 153+ messages in thread

* [Tarantool-patches] [PATCH v2 luajit 15/30] test: disable PUC-Lua test for per-coroutine hooks
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
                   ` (13 preceding siblings ...)
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 14/30] test: adapt activeline check in the PUC Lua test Sergey Kaplun via Tarantool-patches
@ 2021-03-26  7:42 ` Sergey Kaplun via Tarantool-patches
  2021-03-26 14:54   ` Sergey Ostanevich via Tarantool-patches
  2021-03-30 22:16   ` Igor Munkin via Tarantool-patches
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 16/30] test: adapt PUC Lua test for %q in fmt for LuaJIT Sergey Kaplun via Tarantool-patches
                   ` (16 subsequent siblings)
  31 siblings, 2 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26  7:42 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

LuaJIT does not support per-coroutine hooks.
See actual status at https://luajit.org/status.html.

This patch disables tests for per-coroutine hooks in <db.lua>.

Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 test/PUC-Lua-5.1-tests/db.lua | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua
index c704877..8ea6af7 100644
--- a/test/PUC-Lua-5.1-tests/db.lua
+++ b/test/PUC-Lua-5.1-tests/db.lua
@@ -511,8 +511,11 @@ a,b = debug.getlocal(co, 1, 2)
 assert(a == "a" and b == 1)
 debug.setlocal(co, 1, 2, "hi")
 assert(debug.gethook(co) == foo)
-assert(table.getn(tr) == 2 and
-       tr[1] == l.currentline-1 and tr[2] == l.currentline)
+-- LuaJIT does not support per-coroutine hooks.
+-- See also https://luajit.org/status.html.
+-- LuaJIT: Test is disabled for LuaJIT.
+-- assert(table.getn(tr) == 2 and
+--        tr[1] == l.currentline-1 and tr[2] == l.currentline)
 
 a,b,c = pcall(coroutine.resume, co)
 assert(a and b and c == l.currentline+1)
@@ -520,9 +523,13 @@ checktraceback(co, {"yield", "in function <"})
 
 a,b = coroutine.resume(co)
 assert(a and b == "hi")
-assert(table.getn(tr) == 4 and tr[4] == l.currentline+2)
+-- Behavior is different for LuaJIT. See the comment above.
+-- LuaJIT: Test is disabled for LuaJIT.
+-- assert(table.getn(tr) == 4 and tr[4] == l.currentline+2)
 assert(debug.gethook(co) == foo)
-assert(debug.gethook() == nil)
+-- Behavior is different for LuaJIT. See the comment above.
+-- LuaJIT: Test is disabled for LuaJIT.
+-- assert(debug.gethook() == nil)
 checktraceback(co, {})
 
 
-- 
2.31.0


^ permalink raw reply	[flat|nested] 153+ messages in thread

* [Tarantool-patches] [PATCH v2 luajit 16/30] test: adapt PUC Lua test for %q in fmt for LuaJIT
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
                   ` (14 preceding siblings ...)
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 15/30] test: disable PUC-Lua test for per-coroutine hooks Sergey Kaplun via Tarantool-patches
@ 2021-03-26  7:42 ` Sergey Kaplun via Tarantool-patches
  2021-03-26 14:56   ` Sergey Ostanevich via Tarantool-patches
  2021-03-30 22:16   ` Igor Munkin via Tarantool-patches
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 17/30] test: disable locale-depended tests for Lua suite Sergey Kaplun via Tarantool-patches
                   ` (15 subsequent siblings)
  31 siblings, 2 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26  7:42 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=UTF-8, Size: 1945 bytes --]

LuaJIT: LuaJIT since v2.0.0-beta6 has extension from Lua 5.2:
string.format(): %q reversible.
See also https://luajit.org/extensions.html#lua52.

In Lua 5.1 string.format() does not accept string values containing
embedded zeros, except as arguments to the '%q' option.
In Lua 5.2 '\0' is not handled differently from other
control chars in string.format('%q', ...).
See commit 7cc981c14067d4b0e774a6bfb0acfc2f5c911f0d
(string.format("%q", str) is now fully reversible
(from Lua 5.2).).

This patch adapts test for LuaJIT and Lua 5.2 behaviour considering
test from Lua 5.2 test suite taken from
https://www.lua.org/tests/lua-5.2.0-tests.tar.gz.

Closes tarantool/tarantool#5710
Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 test/PUC-Lua-5.1-tests/strings.lua | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/test/PUC-Lua-5.1-tests/strings.lua b/test/PUC-Lua-5.1-tests/strings.lua
index 237dbad..7c1dfb8 100644
--- a/test/PUC-Lua-5.1-tests/strings.lua
+++ b/test/PUC-Lua-5.1-tests/strings.lua
@@ -102,7 +102,17 @@ print('+')
 
 x = '"ílo"\n\\'
 assert(string.format('%q%s', x, x) == '"\\"ílo\\"\\\n\\\\""ílo"\n\\')
-assert(string.format('%q', "\0") == [["\000"]])
+-- LuaJIT: LuaJIT since v2.0.0-beta6 has extension from Lua 5.2:
+-- string.format(): %q reversible.
+-- In Lua 5.1 string.format() does not accept string values
+-- containing embedded zeros, except as arguments to the q option.
+-- In Lua 5.2 '\0' is not handled differently from other
+-- control chars in string.format('%q', ...).
+-- See commit 7cc981c14067d4b0e774a6bfb0acfc2f5c911f0d
+-- (string.format("%q", str) is now fully reversible
+-- (from Lua 5.2).).
+-- Test is adapted from PUC-Rio Lua 5.2 test suite.
+assert(string.format('%q', "\0") == [["\0"]])
 assert(string.format("\0%c\0%c%x\0", string.byte("á"), string.byte("b"), 140) ==
               "\0á\0b8c\0")
 assert(string.format('') == "")
-- 
2.31.0


^ permalink raw reply	[flat|nested] 153+ messages in thread

* [Tarantool-patches] [PATCH v2 luajit 17/30] test: disable locale-depended tests for Lua suite
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
                   ` (15 preceding siblings ...)
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 16/30] test: adapt PUC Lua test for %q in fmt for LuaJIT Sergey Kaplun via Tarantool-patches
@ 2021-03-26  7:43 ` Sergey Kaplun via Tarantool-patches
  2021-03-26 14:58   ` Sergey Ostanevich via Tarantool-patches
  2021-03-30 22:16   ` Igor Munkin via Tarantool-patches
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 18/30] test: replace math.mod to math.fmod for Lua tests Sergey Kaplun via Tarantool-patches
                   ` (14 subsequent siblings)
  31 siblings, 2 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26  7:43 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=UTF-8, Size: 1932 bytes --]

LuaJIT doesn't compare strings by `strcoll()`, like Lua 5.1 does.
So locale-depended tests in <strings.lua> are disabled.

Also, LuaJIT doesn't use `strtod()` depended on the locale for parsing,
unlike Lua does. See <src/lj_strscan.c> for more info.
Locale-depended tests in <literals.lua> are disabled.

Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 test/PUC-Lua-5.1-tests/literals.lua | 5 +++++
 test/PUC-Lua-5.1-tests/strings.lua  | 5 +++++
 2 files changed, 10 insertions(+)

diff --git a/test/PUC-Lua-5.1-tests/literals.lua b/test/PUC-Lua-5.1-tests/literals.lua
index 01d84d5..1b4f664 100644
--- a/test/PUC-Lua-5.1-tests/literals.lua
+++ b/test/PUC-Lua-5.1-tests/literals.lua
@@ -158,6 +158,10 @@ end
 
 
 -- testing decimal point locale
+-- LuaJIT: LuaJIT doesn't use `strtod()` depended on the locale,
+-- unlike Lua does. See <src/lj_strscan.c> for more info.
+-- Tests are disabled for LuaJIT.
+--[[
 if os.setlocale("pt_BR") or os.setlocale("ptb") then
   assert(tonumber("3,4") == 3.4 and tonumber"3.4" == nil)
   assert(assert(loadstring("return 3.4"))() == 3.4)
@@ -171,6 +175,7 @@ else
   (Message or print)(
    '\a\n >>> pt_BR locale not available: skipping decimal point tests <<<\n\a')
 end
+--]]
 
 
 print('OK')
diff --git a/test/PUC-Lua-5.1-tests/strings.lua b/test/PUC-Lua-5.1-tests/strings.lua
index 7c1dfb8..6ae3f51 100644
--- a/test/PUC-Lua-5.1-tests/strings.lua
+++ b/test/PUC-Lua-5.1-tests/strings.lua
@@ -162,6 +162,10 @@ local function trylocale (w)
   return false
 end
 
+-- LuaJIT: LuaJIT doesn't compare strings by `strcoll()`,
+-- like Lua 5.1 does.
+-- Tests are disabled for LuaJIT.
+--[[
 if not trylocale("collate")  then
   print("locale not supported")
 else
@@ -176,6 +180,7 @@ else
   assert(string.gsub("áÁéÉ", "%u", "x") == "áxéx")
   assert(string.upper"áÁé{xuxu}ção" == "ÁÁÉ{XUXU}ÇÃO")
 end
+--]]
 
 os.setlocale("C")
 assert(os.setlocale() == 'C')
-- 
2.31.0


^ permalink raw reply	[flat|nested] 153+ messages in thread

* [Tarantool-patches] [PATCH v2 luajit 18/30] test: replace math.mod to math.fmod for Lua tests
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
                   ` (16 preceding siblings ...)
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 17/30] test: disable locale-depended tests for Lua suite Sergey Kaplun via Tarantool-patches
@ 2021-03-26  7:43 ` Sergey Kaplun via Tarantool-patches
  2021-03-26 15:12   ` Sergey Ostanevich via Tarantool-patches
                     ` (2 more replies)
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 19/30] test: remove assert for string.gfind check Sergey Kaplun via Tarantool-patches
                   ` (13 subsequent siblings)
  31 siblings, 3 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26  7:43 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

In Lua 5.1 math.mod() is renamed to math.fmod() if build Lua 5.1 without
flag `-DLUA_COMPAT_MOD`.
LuaJIT has math.fmod() instead old-style math.mod() built-in.

This patch replaces usage of math.mod with new-style math.fmod
in the following files:
* closure.lua
* constructs.lua
* math.lua
* nextvar.lua

Closes tarantool/tarantool#5711
Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 test/PUC-Lua-5.1-tests/closure.lua    | 3 ++-
 test/PUC-Lua-5.1-tests/constructs.lua | 6 ++++--
 test/PUC-Lua-5.1-tests/math.lua       | 3 ++-
 test/PUC-Lua-5.1-tests/nextvar.lua    | 3 ++-
 4 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/test/PUC-Lua-5.1-tests/closure.lua b/test/PUC-Lua-5.1-tests/closure.lua
index 27ca0ad..7f56ab8 100644
--- a/test/PUC-Lua-5.1-tests/closure.lua
+++ b/test/PUC-Lua-5.1-tests/closure.lua
@@ -254,7 +254,8 @@ function filter (p, g)
     while 1 do
       local n = g()
       if n == nil then return end
-      if math.mod(n, p) ~= 0 then coroutine.yield(n) end
+      -- LuaJIT: use `math.fmod()` instead old-style `math.mod()`.
+      if math.fmod(n, p) ~= 0 then coroutine.yield(n) end
     end
   end)
 end
diff --git a/test/PUC-Lua-5.1-tests/constructs.lua b/test/PUC-Lua-5.1-tests/constructs.lua
index 5fb3798..18d1789 100644
--- a/test/PUC-Lua-5.1-tests/constructs.lua
+++ b/test/PUC-Lua-5.1-tests/constructs.lua
@@ -202,7 +202,8 @@ function ID(x) return x end
 
 function f(t, i)
   local b = t.n
-  local res = math.mod(math.floor(i/c), b)+1
+  -- LuaJIT: use `math.fmod()` instead old-style `math.mod()`.
+  local res = math.fmod(math.floor(i/c), b)+1
   c = c*b
   return t[res]
 end
@@ -233,7 +234,8 @@ repeat
   ]], s1, s, s1, s, s1, s, s1, s, s)
   assert(loadstring(s))()
   assert(X and not NX and not WX1 == K and not WX2 == K)
-  if math.mod(i,4000) == 0 then print('+') end
+  -- LuaJIT: use `math.fmod()` instead old-style `math.mod()`.
+  if math.fmod(i,4000) == 0 then print('+') end
   i = i+1
 until i==c
 
diff --git a/test/PUC-Lua-5.1-tests/math.lua b/test/PUC-Lua-5.1-tests/math.lua
index 5076f38..8f0526f 100644
--- a/test/PUC-Lua-5.1-tests/math.lua
+++ b/test/PUC-Lua-5.1-tests/math.lua
@@ -100,7 +100,8 @@ assert(math.abs(-10) == 10)
 assert(eq(math.atan2(1,0), math.pi/2))
 assert(math.ceil(4.5) == 5.0)
 assert(math.floor(4.5) == 4.0)
-assert(math.mod(10,3) == 1)
+-- LuaJIT: use `math.fmod()` instead old-style `math.mod()`.
+assert(math.fmod(10,3) == 1)
 assert(eq(math.sqrt(10)^2, 10))
 assert(eq(math.log10(2), math.log(2)/math.log(10)))
 assert(eq(math.exp(0), 1))
diff --git a/test/PUC-Lua-5.1-tests/nextvar.lua b/test/PUC-Lua-5.1-tests/nextvar.lua
index 7ceaa75..81159dc 100644
--- a/test/PUC-Lua-5.1-tests/nextvar.lua
+++ b/test/PUC-Lua-5.1-tests/nextvar.lua
@@ -201,7 +201,8 @@ print('+')
 
 a = {}
 for i=0,10000 do
-  if math.mod(i,10) ~= 0 then
+  -- LuaJIT: use `math.fmod()` instead old-style `math.mod()`.
+  if math.fmod(i,10) ~= 0 then
     a['x'..i] = i
   end
 end
-- 
2.31.0


^ permalink raw reply	[flat|nested] 153+ messages in thread

* [Tarantool-patches] [PATCH v2 luajit 19/30] test: remove assert for string.gfind check
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
                   ` (17 preceding siblings ...)
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 18/30] test: replace math.mod to math.fmod for Lua tests Sergey Kaplun via Tarantool-patches
@ 2021-03-26  7:43 ` Sergey Kaplun via Tarantool-patches
  2021-03-26 15:14   ` Sergey Ostanevich via Tarantool-patches
  2021-03-30 22:17   ` Igor Munkin via Tarantool-patches
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 20/30] test: adapt PUC Lua test for args in vararg func Sergey Kaplun via Tarantool-patches
                   ` (12 subsequent siblings)
  31 siblings, 2 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26  7:43 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

In Lua 5.1 function `string.gfind()` was renamed to `string.gmatch()`.
You can use it if Lua 5.1 is built with compile-time option
`-DLUA_COMPAT_GFIND`.
This built-in is removed from LuaJIT.

This patch removes test checking that `string.gfind()` and
`string.gmatch() is the same function.

Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 test/PUC-Lua-5.1-tests/pm.lua | 1 -
 1 file changed, 1 deletion(-)

diff --git a/test/PUC-Lua-5.1-tests/pm.lua b/test/PUC-Lua-5.1-tests/pm.lua
index fa125dc..b159b6b 100644
--- a/test/PUC-Lua-5.1-tests/pm.lua
+++ b/test/PUC-Lua-5.1-tests/pm.lua
@@ -223,7 +223,6 @@ assert(string.gsub("a alo b hi", "%w%w+", t) == "a ALO b HI")
 
 
 -- tests for gmatch
-assert(string.gfind == string.gmatch)
 local a = 0
 for i in string.gmatch('abcde', '()') do assert(i == a+1); a=i end
 assert(a==6)
-- 
2.31.0


^ permalink raw reply	[flat|nested] 153+ messages in thread

* [Tarantool-patches] [PATCH v2 luajit 20/30] test: adapt PUC Lua test for args in vararg func
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
                   ` (18 preceding siblings ...)
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 19/30] test: remove assert for string.gfind check Sergey Kaplun via Tarantool-patches
@ 2021-03-26  7:43 ` Sergey Kaplun via Tarantool-patches
  2021-03-26 14:54   ` Sergey Kaplun via Tarantool-patches
  2021-03-31  9:51   ` Igor Munkin via Tarantool-patches
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 21/30] test: disable test for getfenv in closure tailcall Sergey Kaplun via Tarantool-patches
                   ` (11 subsequent siblings)
  31 siblings, 2 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26  7:43 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

Lua 5.1 interprets ... in the vararg functions like additional first
argument, unlike LuaJIT does. All extra arguments is set into `arg`
variable.

Implicit `arg` parameter for old-style vararg functions was finally
removed in Lua 5.2. This patch adjust tests in vararg.lua considering
Lua 5.2 test suite taken from
https://www.lua.org/tests/lua-5.2.0-tests.tar.gz.

Closes tarantool/tarantool#5712
Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 test/PUC-Lua-5.1-tests/vararg.lua | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/test/PUC-Lua-5.1-tests/vararg.lua b/test/PUC-Lua-5.1-tests/vararg.lua
index ae068fa..efb76c5 100644
--- a/test/PUC-Lua-5.1-tests/vararg.lua
+++ b/test/PUC-Lua-5.1-tests/vararg.lua
@@ -2,9 +2,13 @@ print('testing vararg')
 
 _G.arg = nil
 
+-- Lua 5.1 interprets ... in the vararg functions like additional
+-- first argument, unlike LuaJIT does. All extra arguments is set
+-- into `arg` variable. This extension is from Lua 5.2.
+-- See also https://github.com/tarantool/tarantool/issues/5712.
+-- LuaJIT: Test is adapted from PUC-Rio Lua 5.2 test suite.
 function f(a, ...)
-  assert(type(arg) == 'table')
-  assert(type(arg.n) == 'number')
+  local arg = {n = select('#', ...), ...}
   for i=1,arg.n do assert(a[i]==arg[i]) end
   return arg.n
 end
@@ -17,7 +21,9 @@ function c12 (...)
   return res, 2
 end
 
-function vararg (...) return arg end
+-- LuaJIT: Test chunk is adapted from PUC-Rio Lua 5.2 test suite.
+-- See the comment above.
+function vararg (...) return {n = select('#', ...), ...} end
 
 local call = function (f, args) return f(unpack(args, 1, args.n)) end
 
@@ -42,7 +48,9 @@ a = call(print, {'+'})
 assert(a == nil)
 
 local t = {1, 10}
-function t:f (...) return self[arg[1]]+arg.n end
+-- LuaJIT: Test chunk is adapted from PUC-Rio Lua 5.2 test suite.
+-- See the comment above.
+function t:f (...) local arg = {...}; return self[...]+#arg end
 assert(t:f(1,4) == 3 and t:f(2) == 11)
 print('+')
 
-- 
2.31.0


^ permalink raw reply	[flat|nested] 153+ messages in thread

* [Tarantool-patches] [PATCH v2 luajit 21/30] test: disable test for getfenv in closure tailcall
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
                   ` (19 preceding siblings ...)
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 20/30] test: adapt PUC Lua test for args in vararg func Sergey Kaplun via Tarantool-patches
@ 2021-03-26  7:43 ` Sergey Kaplun via Tarantool-patches
  2021-03-26 15:41   ` Sergey Ostanevich via Tarantool-patches
  2021-03-31  9:51   ` Igor Munkin via Tarantool-patches
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 22/30] test: disable PUC Lua test for var names in error Sergey Kaplun via Tarantool-patches
                   ` (10 subsequent siblings)
  31 siblings, 2 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26  7:43 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

LuaJIT doesn't take into account tail calls for call-level counting, so
getfenv() behaviour is different from Lua 5.1 in tail calls.

This patch disables test for the return result of tail call getfenv().
Default value (equals 1) of getfenv() function's argument (function
level) is invalid for this tail call -- LuaJIT can't provide necessary
debug information for the frame.

Relates to tarantool/tarantool#5713
Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 test/PUC-Lua-5.1-tests/closure.lua | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/test/PUC-Lua-5.1-tests/closure.lua b/test/PUC-Lua-5.1-tests/closure.lua
index 7f56ab8..7af842f 100644
--- a/test/PUC-Lua-5.1-tests/closure.lua
+++ b/test/PUC-Lua-5.1-tests/closure.lua
@@ -174,7 +174,14 @@ f = coroutine.wrap(foo)
 local a = {}
 assert(f(a) == _G)
 local a,b = pcall(f)
-assert(a and b == _G)
+-- LuaJIT doesn't take into account tail calls for call-level
+-- counting, so getfenv() behaviour is different in tail calls.
+-- For example, this `pcall()` returns false, because getfenv()
+-- default level is 1 which is invalid for this case when
+-- is called from tail call (lj_debug_frame() returns NULL).
+-- See also https://github.com/tarantool/tarantool/issues/5713.
+-- FIXME: Test is disabled for LuaJIT for now.
+-- assert(a and b == _G)
 
 
 -- tests for multiple yield/resume arguments
-- 
2.31.0


^ permalink raw reply	[flat|nested] 153+ messages in thread

* [Tarantool-patches] [PATCH v2 luajit 22/30] test: disable PUC Lua test for var names in error
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
                   ` (20 preceding siblings ...)
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 21/30] test: disable test for getfenv in closure tailcall Sergey Kaplun via Tarantool-patches
@ 2021-03-26  7:43 ` Sergey Kaplun via Tarantool-patches
  2021-03-26 15:44   ` Sergey Ostanevich via Tarantool-patches
  2021-03-31 19:23   ` Igor Munkin via Tarantool-patches
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 23/30] test: disable PUC Lua test for fast function name Sergey Kaplun via Tarantool-patches
                   ` (9 subsequent siblings)
  31 siblings, 2 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26  7:43 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

LuaJIT includes variable name to the error report, when try to
call non-function object without __call methamethod.
Also, LuaJIT includes variable name to the error report, when try to
perform unacceptable arifmetic operation with the variable.
Lua 5.1 doesn't report variable name in these errors.

Test ckecked that variable name aren't reported are disabled by
this patch.

Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 test/PUC-Lua-5.1-tests/errors.lua | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua
index e881211..cf24e40 100644
--- a/test/PUC-Lua-5.1-tests/errors.lua
+++ b/test/PUC-Lua-5.1-tests/errors.lua
@@ -72,8 +72,13 @@ checkmessage("b=1; local aaa='a'; x=aaa+b", "local 'aaa'")
 checkmessage("aaa={}; x=3/aaa", "global 'aaa'")
 checkmessage("aaa='2'; b=nil;x=aaa*b", "global 'b'")
 checkmessage("aaa={}; x=-aaa", "global 'aaa'")
-assert(not string.find(doit"aaa={}; x=(aaa or aaa)+(aaa and aaa)", "'aaa'"))
-assert(not string.find(doit"aaa={}; (aaa or aaa)()", "'aaa'"))
+-- LuaJIT: LuaJIT includes variable name to the error report.
+-- It looks like:
+-- "attempt to perform arithmetic on global 'aaa' (a table value)"
+-- Lua 5.1 doesn't report variable name here.
+-- Tests are disabled for LuaJIT.
+-- assert(not string.find(doit"aaa={}; x=(aaa or aaa)+(aaa and aaa)", "'aaa'"))
+-- assert(not string.find(doit"aaa={}; (aaa or aaa)()", "'aaa'"))
 
 checkmessage([[aaa=9
 repeat until 3==3
-- 
2.31.0


^ permalink raw reply	[flat|nested] 153+ messages in thread

* [Tarantool-patches] [PATCH v2 luajit 23/30] test: disable PUC Lua test for fast function name
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
                   ` (21 preceding siblings ...)
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 22/30] test: disable PUC Lua test for var names in error Sergey Kaplun via Tarantool-patches
@ 2021-03-26  7:43 ` Sergey Kaplun via Tarantool-patches
  2021-03-26 15:45   ` Sergey Ostanevich via Tarantool-patches
  2021-03-31 19:23   ` Igor Munkin via Tarantool-patches
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 24/30] test: disable PUC Lua test for non-asci identifier Sergey Kaplun via Tarantool-patches
                   ` (8 subsequent siblings)
  31 siblings, 2 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26  7:43 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

LuaJIT can't determine bytecode position for non Lua functions
(in particular for fast functions) and, therefore, detect built-in
function names for errors in tail calls.

This patch disables test that checks name of built-in functions
reported in error in tail call.

Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 test/PUC-Lua-5.1-tests/errors.lua | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua
index cf24e40..af776a7 100644
--- a/test/PUC-Lua-5.1-tests/errors.lua
+++ b/test/PUC-Lua-5.1-tests/errors.lua
@@ -105,9 +105,13 @@ while 1 do
   insert(prefix, a)
 end]], "global 'insert'")
 
-checkmessage([[  -- tail call
-  return math.sin("a")
-]], "'sin'")
+-- LuaJIT: Can't determine bytecode position for non Lua functions
+-- (in particular for fast functions) and, therefore, detect fast
+-- function names for errors in tail calls.
+-- The test is disabled for LuaJIT.
+-- checkmessage([[  -- tail call
+--   return math.sin("a")
+-- ]], "'sin'")
 
 checkmessage([[collectgarbage("nooption")]], "invalid option")
 
-- 
2.31.0


^ permalink raw reply	[flat|nested] 153+ messages in thread

* [Tarantool-patches] [PATCH v2 luajit 24/30] test: disable PUC Lua test for non-asci identifier
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
                   ` (22 preceding siblings ...)
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 23/30] test: disable PUC Lua test for fast function name Sergey Kaplun via Tarantool-patches
@ 2021-03-26  7:43 ` Sergey Kaplun via Tarantool-patches
  2021-03-26 15:46   ` Sergey Ostanevich via Tarantool-patches
  2021-03-31 19:23   ` Igor Munkin via Tarantool-patches
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 25/30] test: disable PUC Lua error test for syntax level Sergey Kaplun via Tarantool-patches
                   ` (7 subsequent siblings)
  31 siblings, 2 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26  7:43 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

LuaJIT does not avoid to use non-alphanumeric symbols as identifiers,
unlike Lua does.

This patch disables test that expects an error during parsing variable
contains octal \255 as the first char in a variable name.

Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 test/PUC-Lua-5.1-tests/errors.lua | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua
index af776a7..028224c 100644
--- a/test/PUC-Lua-5.1-tests/errors.lua
+++ b/test/PUC-Lua-5.1-tests/errors.lua
@@ -202,7 +202,11 @@ checksyntax("[[a]]", "", "[[a]]", 1)
 checksyntax("'aa'", "", "'aa'", 1)
 
 -- test 255 as first char in a chunk
-checksyntax("\255a = 1", "", "\255", 1)
+-- LuaJIT does not avoid to use non-alphanumeric symbols
+-- as identifiers, unlike Lua does.
+-- For more details see <src/lj_char.c> and <src/lj_lex.c>.
+-- LuaJIT: Test is disabled for LuaJIT.
+-- checksyntax("\255a = 1", "", "\255", 1)
 
 doit('I = loadstring("a=9+"); a=3')
 assert(a==3 and I == nil)
-- 
2.31.0


^ permalink raw reply	[flat|nested] 153+ messages in thread

* [Tarantool-patches] [PATCH v2 luajit 25/30] test: disable PUC Lua error test for syntax level
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
                   ` (23 preceding siblings ...)
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 24/30] test: disable PUC Lua test for non-asci identifier Sergey Kaplun via Tarantool-patches
@ 2021-03-26  7:43 ` Sergey Kaplun via Tarantool-patches
  2021-03-26 15:52   ` Sergey Ostanevich via Tarantool-patches
  2021-03-31 19:24   ` Igor Munkin via Tarantool-patches
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 26/30] test: disable tests with multiple -l options Sergey Kaplun via Tarantool-patches
                   ` (6 subsequent siblings)
  31 siblings, 2 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26  7:43 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

When LuaJIT is compiled with LUAJIT_ENABLE_GC64, LJ_MAX_SLOTS limit is
reached and error LJ_ERR_XSLOTS ("function or expression too complex")
is raised earlier, than LJ_MAX_XLEVEL limit is reached and error
LJ_ERR_XLEVELS ("chunk has too many syntax levels") is raised.

This patch disabled test expected the LJ_ERR_XLEVEL error, but
failing with the LJ_ERR_XSLOTS error.

Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 test/PUC-Lua-5.1-tests/errors.lua | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua
index 028224c..328976e 100644
--- a/test/PUC-Lua-5.1-tests/errors.lua
+++ b/test/PUC-Lua-5.1-tests/errors.lua
@@ -228,7 +228,13 @@ local function testrep (init, rep)
 end
 testrep("a=", "{")
 testrep("a=", "(")
-testrep("", "a(")
+-- LuaJIT: When compiled with LUAJIT_ENABLE_GC64, LJ_MAX_SLOTS
+-- limit is reached and error LJ_ERR_XSLOTS ("function or
+-- expression too complex") is raised earlier, than LJ_MAX_XLEVEL
+-- limit is reached and error LJ_ERR_XLEVELS ("chunk has too many
+-- syntax levels") is raised.
+-- Test is disabled for LuaJIT.
+-- testrep("", "a(")
 testrep("", "do ")
 testrep("", "while a do ")
 testrep("", "if a then else ")
-- 
2.31.0


^ permalink raw reply	[flat|nested] 153+ messages in thread

* [Tarantool-patches] [PATCH v2 luajit 26/30] test: disable tests with multiple -l options
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
                   ` (24 preceding siblings ...)
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 25/30] test: disable PUC Lua error test for syntax level Sergey Kaplun via Tarantool-patches
@ 2021-03-26  7:43 ` Sergey Kaplun via Tarantool-patches
  2021-03-26 15:56   ` Sergey Ostanevich via Tarantool-patches
  2021-03-31 19:24   ` Igor Munkin via Tarantool-patches
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 27/30] test: disable PUC Lua test for checking arg layout Sergey Kaplun via Tarantool-patches
                   ` (5 subsequent siblings)
  31 siblings, 2 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26  7:43 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

Tarantool may crash when -e or -l option and their argument are not
separated by space.

This patch disables tests leading to crash.

Relates to tarantool/tarantool#5747
Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 test/PUC-Lua-5.1-tests/main.lua | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua
index cf6d533..73bff52 100644
--- a/test/PUC-Lua-5.1-tests/main.lua
+++ b/test/PUC-Lua-5.1-tests/main.lua
@@ -52,8 +52,12 @@ end
 -- test 2 files
 prepfile("print(1); a=2")
 prepfile("print(a)", otherprog)
-RUN("lua -l %s -l%s -lstring -l io %s > %s", prog, otherprog, otherprog, out)
-checkout("1\n2\n2\n")
+-- FIXME: Tarantool may crash when -e or -l option and their
+-- argument are not separated by space.
+-- The test is disabled for the Tarantool binary.
+-- See https://github.com/tarantool/tarantool/issues/5747.
+-- RUN("lua -l %s -l%s -lstring -l io %s > %s", prog, otherprog, otherprog, out)
+-- checkout("1\n2\n2\n")
 
 -- LuaJIT: test file is adapted for LuaJIT's test system, see
 -- the comment near `progname` initialization.
@@ -92,8 +96,12 @@ prepfile[[print(({...})[30])]]
 RUN("lua %s %s > %s", prog, string.rep(" a", 30), out)
 checkout("a\n")
 
-RUN([[lua "-eprint(1)" -ea=3 -e "print(a)" > %s]], out)
-checkout("1\n3\n")
+-- FIXME: Tarantool may crash when -e or -l option and their
+-- argument are not separated by space.
+-- The test is disabled for the Tarantool binary.
+-- See https://github.com/tarantool/tarantool/issues/5747.
+-- RUN([[lua "-eprint(1)" -ea=3 -e "print(a)" > %s]], out)
+-- checkout("1\n3\n")
 
 prepfile[[
   print(
-- 
2.31.0


^ permalink raw reply	[flat|nested] 153+ messages in thread

* [Tarantool-patches] [PATCH v2 luajit 27/30] test: disable PUC Lua test for checking arg layout
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
                   ` (25 preceding siblings ...)
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 26/30] test: disable tests with multiple -l options Sergey Kaplun via Tarantool-patches
@ 2021-03-26  7:43 ` Sergey Kaplun via Tarantool-patches
  2021-03-26 15:58   ` Sergey Ostanevich via Tarantool-patches
  2021-03-31 19:24   ` Igor Munkin via Tarantool-patches
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 28/30] test: disable PUC Lua test checking -h option Sergey Kaplun via Tarantool-patches
                   ` (4 subsequent siblings)
  31 siblings, 2 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26  7:43 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

Unlike LuaJIT, Tarantool doesn't store the given CLI flags in `arg`,
so the table has the following layout:
* arg[-1] -- the binary name
* arg[0]  -- the script name
* arg[N]  -- the script argument for all N in [1, #arg]

This patch disables test checking `arg` layout by negative indexes.

Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 test/PUC-Lua-5.1-tests/main.lua | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua
index 73bff52..acc50a6 100644
--- a/test/PUC-Lua-5.1-tests/main.lua
+++ b/test/PUC-Lua-5.1-tests/main.lua
@@ -71,7 +71,13 @@ local a = [[
 ]]
 a = string.format(a, progname)
 prepfile(a)
-RUN('lua "-e " -- %s a b c', prog)
+-- FIXME: Unlike LuaJIT, Tarantool doesn't store the given
+-- CLI flags in `arg`, so the table has the following layout:
+-- * arg[-1] -- the binary name
+-- * arg[0]  -- the script name
+-- * arg[N]  -- the script argument for all N in [1, #arg]
+-- Test is disabled for the Tarantool binary.
+-- RUN('lua "-e " -- %s a b c', prog)
 
 -- test 'arg' availability in libraries
 -- LuaJIT: LuaJIT v2.1.0-beta3 has extension from Lua 5.3:
-- 
2.31.0


^ permalink raw reply	[flat|nested] 153+ messages in thread

* [Tarantool-patches] [PATCH v2 luajit 28/30] test: disable PUC Lua test checking -h option
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
                   ` (26 preceding siblings ...)
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 27/30] test: disable PUC Lua test for checking arg layout Sergey Kaplun via Tarantool-patches
@ 2021-03-26  7:43 ` Sergey Kaplun via Tarantool-patches
  2021-03-26 15:58   ` Sergey Ostanevich via Tarantool-patches
  2021-03-31 19:24   ` Igor Munkin via Tarantool-patches
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 29/30] test: disable PUC Lua hanging GC test Sergey Kaplun via Tarantool-patches
                   ` (3 subsequent siblings)
  31 siblings, 2 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26  7:43 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

Tarantool returns zero status at exit with -h option, unlike Lua or
LuaJIT does.

This patch disables test checking returning status, when binary
runs with -h option.

Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 test/PUC-Lua-5.1-tests/main.lua | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua
index acc50a6..0ca7ef4 100644
--- a/test/PUC-Lua-5.1-tests/main.lua
+++ b/test/PUC-Lua-5.1-tests/main.lua
@@ -201,7 +201,10 @@ assert(not os.remove(out))
 
 RUN("lua -v")
 
-NoRun("lua -h")
+-- FIXME: Tarantool returns zero status at exit with -h option,
+-- unlike Lua or LuaJIT does.
+-- The test is disabled for Tarantool binary.
+-- NoRun("lua -h")
 NoRun("lua -e")
 NoRun("lua -e a")
 NoRun("lua -f")
-- 
2.31.0


^ permalink raw reply	[flat|nested] 153+ messages in thread

* [Tarantool-patches] [PATCH v2 luajit 29/30] test: disable PUC Lua hanging GC test
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
                   ` (27 preceding siblings ...)
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 28/30] test: disable PUC Lua test checking -h option Sergey Kaplun via Tarantool-patches
@ 2021-03-26  7:43 ` Sergey Kaplun via Tarantool-patches
  2021-03-26 16:03   ` Sergey Ostanevich via Tarantool-patches
  2021-03-31 19:24   ` Igor Munkin via Tarantool-patches
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 30/30] test: disable too depth recursive PUC Lua test Sergey Kaplun via Tarantool-patches
                   ` (2 subsequent siblings)
  31 siblings, 2 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26  7:43 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

Tarantool has too many objects at start. `gcinfo()` result is always
greater than 1000 expected by the test. It leads to infinite loop in the
test.

This patch disables GC test leading to hanging for Tarantool binary.

Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 test/PUC-Lua-5.1-tests/gc.lua | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/test/PUC-Lua-5.1-tests/gc.lua b/test/PUC-Lua-5.1-tests/gc.lua
index 072bbe9..7f9880f 100644
--- a/test/PUC-Lua-5.1-tests/gc.lua
+++ b/test/PUC-Lua-5.1-tests/gc.lua
@@ -133,9 +133,12 @@ do
     local a = {}
   until gcinfo() > 1000
   collectgarbage"restart"
-  repeat
-    local a = {}
-  until gcinfo() < 1000
+  -- Tarantool has too many objects at start. `gcinfo()` result
+  -- is always greater than 1000.
+  -- LuaJIT: The test is disabled for Tarantool binary.
+  -- repeat
+  --   local a = {}
+  -- until gcinfo() < 1000
 end
 
 lim = 15
-- 
2.31.0


^ permalink raw reply	[flat|nested] 153+ messages in thread

* [Tarantool-patches] [PATCH v2 luajit 30/30] test: disable too depth recursive PUC Lua test
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
                   ` (28 preceding siblings ...)
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 29/30] test: disable PUC Lua hanging GC test Sergey Kaplun via Tarantool-patches
@ 2021-03-26  7:43 ` Sergey Kaplun via Tarantool-patches
  2021-03-26 16:28   ` Sergey Ostanevich via Tarantool-patches
  2021-03-31 19:24   ` Igor Munkin via Tarantool-patches
  2021-03-26 11:09 ` [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Ostanevich via Tarantool-patches
  2021-03-30 22:17 ` Igor Munkin via Tarantool-patches
  31 siblings, 2 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26  7:43 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

The first Tarantool's fiber has only 512Kb of stack.
It is not enough for depth recursive call in the test for
`string.gsub()`.

This patch disables test leads to Tarantool crash.

Relates to tarantool/tarantool#5782
Resolves tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 test/PUC-Lua-5.1-tests/pm.lua | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/test/PUC-Lua-5.1-tests/pm.lua b/test/PUC-Lua-5.1-tests/pm.lua
index b159b6b..c6e42df 100644
--- a/test/PUC-Lua-5.1-tests/pm.lua
+++ b/test/PUC-Lua-5.1-tests/pm.lua
@@ -207,7 +207,11 @@ function rev (s)
 end
 
 local x = string.rep('012345', 10)
-assert(rev(rev(x)) == x)
+-- The first Tarantool's fiber has only 512Kb of stack.
+-- It is not enough for this recursive call.
+-- See also https://github.com/tarantool/tarantool/issues/5782.
+-- FIXME: The test is disabled for Tarantool binary.
+-- assert(rev(rev(x)) == x)
 
 
 -- gsub with tables
-- 
2.31.0


^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 01/30] test: add PUC-Rio Lua 5.1 test suite
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 01/30] test: add " Sergey Kaplun via Tarantool-patches
@ 2021-03-26 10:14   ` Sergey Ostanevich via Tarantool-patches
  2021-03-30 22:13   ` Igor Munkin via Tarantool-patches
  1 sibling, 0 replies; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 10:14 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Hi! Thanks for the patch, verified with

$ for i in `find .  -type f` ; do ii=`basename $i`; \
> diff -iwhite $i `find ../../test/PUC-Lua-5.1-tests/ -name $ii` ; done
diff: missing operand after `./libs/makefile'
diff: Try `diff --help' for more information.
$

LGTM.

Sergos

> On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> This patch adds PUC-Rio Lua 5.1 test suite as a part of the LuaJIT test
> suite. Source code taken verbatim (except trailing whitespaces) from
> https://www.lua.org/tests/lua5.1-tests.tar.gz.
> 
> Some tests may fail after this commit. They will be disabled
> or adapted in the next patches.
> 
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
> .luacheckrc                                |    5 +-
> test/CMakeLists.txt                        |    2 +
> test/PUC-Lua-5.1-tests/CMakeLists.txt      |   45 +
> test/PUC-Lua-5.1-tests/README              |   41 +
> test/PUC-Lua-5.1-tests/all.lua             |  137 +++
> test/PUC-Lua-5.1-tests/api.lua             |  711 ++++++++++++
> test/PUC-Lua-5.1-tests/attrib.lua          |  339 ++++++
> test/PUC-Lua-5.1-tests/big.lua             |  381 +++++++
> test/PUC-Lua-5.1-tests/calls.lua           |  294 +++++
> test/PUC-Lua-5.1-tests/checktable.lua      |   77 ++
> test/PUC-Lua-5.1-tests/closure.lua         |  422 +++++++
> test/PUC-Lua-5.1-tests/code.lua            |  143 +++
> test/PUC-Lua-5.1-tests/constructs.lua      |  240 ++++
> test/PUC-Lua-5.1-tests/db.lua              |  499 +++++++++
> test/PUC-Lua-5.1-tests/errors.lua          |  250 +++++
> test/PUC-Lua-5.1-tests/etc/ltests.c        | 1147 ++++++++++++++++++++
> test/PUC-Lua-5.1-tests/etc/ltests.h        |   92 ++
> test/PUC-Lua-5.1-tests/events.lua          |  360 ++++++
> test/PUC-Lua-5.1-tests/files.lua           |  324 ++++++
> test/PUC-Lua-5.1-tests/gc.lua              |  312 ++++++
> test/PUC-Lua-5.1-tests/libs/CMakeLists.txt |   18 +
> test/PUC-Lua-5.1-tests/libs/lib1.c         |   40 +
> test/PUC-Lua-5.1-tests/libs/lib11.c        |   18 +
> test/PUC-Lua-5.1-tests/libs/lib2.c         |   28 +
> test/PUC-Lua-5.1-tests/libs/lib21.c        |   18 +
> test/PUC-Lua-5.1-tests/literals.lua        |  176 +++
> test/PUC-Lua-5.1-tests/locals.lua          |  127 +++
> test/PUC-Lua-5.1-tests/main.lua            |  159 +++
> test/PUC-Lua-5.1-tests/math.lua            |  208 ++++
> test/PUC-Lua-5.1-tests/nextvar.lua         |  396 +++++++
> test/PUC-Lua-5.1-tests/pm.lua              |  273 +++++
> test/PUC-Lua-5.1-tests/sort.lua            |   74 ++
> test/PUC-Lua-5.1-tests/strings.lua         |  176 +++
> test/PUC-Lua-5.1-tests/vararg.lua          |  126 +++
> test/PUC-Lua-5.1-tests/verybig.lua         |  100 ++
> 35 files changed, 7756 insertions(+), 2 deletions(-)
> create mode 100644 test/PUC-Lua-5.1-tests/CMakeLists.txt
> create mode 100644 test/PUC-Lua-5.1-tests/README
> create mode 100755 test/PUC-Lua-5.1-tests/all.lua
> create mode 100644 test/PUC-Lua-5.1-tests/api.lua
> create mode 100644 test/PUC-Lua-5.1-tests/attrib.lua
> create mode 100644 test/PUC-Lua-5.1-tests/big.lua
> create mode 100644 test/PUC-Lua-5.1-tests/calls.lua
> create mode 100644 test/PUC-Lua-5.1-tests/checktable.lua
> create mode 100644 test/PUC-Lua-5.1-tests/closure.lua
> create mode 100644 test/PUC-Lua-5.1-tests/code.lua
> create mode 100644 test/PUC-Lua-5.1-tests/constructs.lua
> create mode 100644 test/PUC-Lua-5.1-tests/db.lua
> create mode 100644 test/PUC-Lua-5.1-tests/errors.lua
> create mode 100644 test/PUC-Lua-5.1-tests/etc/ltests.c
> create mode 100644 test/PUC-Lua-5.1-tests/etc/ltests.h
> create mode 100644 test/PUC-Lua-5.1-tests/events.lua
> create mode 100644 test/PUC-Lua-5.1-tests/files.lua
> create mode 100644 test/PUC-Lua-5.1-tests/gc.lua
> create mode 100644 test/PUC-Lua-5.1-tests/libs/CMakeLists.txt
> create mode 100644 test/PUC-Lua-5.1-tests/libs/lib1.c
> create mode 100644 test/PUC-Lua-5.1-tests/libs/lib11.c
> create mode 100644 test/PUC-Lua-5.1-tests/libs/lib2.c
> create mode 100644 test/PUC-Lua-5.1-tests/libs/lib21.c
> create mode 100644 test/PUC-Lua-5.1-tests/literals.lua
> create mode 100644 test/PUC-Lua-5.1-tests/locals.lua
> create mode 100644 test/PUC-Lua-5.1-tests/main.lua
> create mode 100644 test/PUC-Lua-5.1-tests/math.lua
> create mode 100644 test/PUC-Lua-5.1-tests/nextvar.lua
> create mode 100644 test/PUC-Lua-5.1-tests/pm.lua
> create mode 100644 test/PUC-Lua-5.1-tests/sort.lua
> create mode 100644 test/PUC-Lua-5.1-tests/strings.lua
> create mode 100644 test/PUC-Lua-5.1-tests/vararg.lua
> create mode 100644 test/PUC-Lua-5.1-tests/verybig.lua
> 
> diff --git a/.luacheckrc b/.luacheckrc
> index 4e5dbdf..fd5583b 100644
> --- a/.luacheckrc
> +++ b/.luacheckrc
> @@ -3,11 +3,12 @@ std = 'luajit'
> -- This fork also introduces a new global for misc API namespace.
> read_globals = { 'misc' }
> 
> --- These files are inherited from the vanilla LuaJIT and need to
> --- be coherent with the upstream.
> +-- These files are inherited from the vanilla LuaJIT or different
> +-- test suites and need to be coherent with the upstream.
> exclude_files = {
>   'dynasm/',
>   'src/',
>   'test/LuaJIT-tests/',
> +  'test/PUC-Lua-5.1-tests/',
>   'test/lua-Harness-tests/',
> }
> diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
> index 02fb2ed..30cbf87 100644
> --- a/test/CMakeLists.txt
> +++ b/test/CMakeLists.txt
> @@ -44,11 +44,13 @@ set(LUAJIT_TEST_COMMAND "${LUAJIT_TEST_BINARY} -e dofile[[${LUAJIT_TEST_INIT}]]"
> separate_arguments(LUAJIT_TEST_COMMAND)
> 
> add_subdirectory(LuaJIT-tests)
> +add_subdirectory(PUC-Lua-5.1-tests)
> add_subdirectory(lua-Harness-tests)
> add_subdirectory(tarantool-tests)
> 
> add_custom_target(${PROJECT_NAME}-test DEPENDS
>   LuaJIT-tests
> +  PUC-Lua-5.1-tests
>   lua-Harness-tests
>   tarantool-tests
> )
> diff --git a/test/PUC-Lua-5.1-tests/CMakeLists.txt b/test/PUC-Lua-5.1-tests/CMakeLists.txt
> new file mode 100644
> index 0000000..773db0d
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/CMakeLists.txt
> @@ -0,0 +1,45 @@
> +# Test suite that has been added from PUC-Rio Lua 5.1 test archive
> +# in scope of https://github.com/tarantool/tarantool/issues/5845.
> +
> +# See the rationale in the root CMakeLists.txt.
> +cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
> +
> +# XXX: There are two ways to set up the proper environment
> +# described in the suite's README:
> +# * set LUA_PATH to "?;./?.lua"
> +# * or, better yet, set LUA_PATH to "./?.lua;;" and LUA_INIT to
> +#   "package.path = '?;'..package.path"
> +# Unfortunately, Tarantool doesn't support LUA_INIT and most
> +# likely it never will. For more info, see
> +# https://github.com/tarantool/tarantool/issues/5744
> +# Hence, there is no way other than set LUA_PATH environment
> +# variable as proposed in the first case.
> +set(LUA_PATH "?\;${CMAKE_CURRENT_SOURCE_DIR}/?.lua")
> +
> +# Set PUC-Lua-5.1-tests-prepare target that creates <libs/P1>
> +# subdirectory.
> +add_subdirectory(libs)
> +
> +# TODO: PUC-Rio Lua 5.1 test suite also has special header
> +# <ltests.h> and <ltests.c> translation unit to check some
> +# internal behaviour of the Lua implementation (see etc/
> +# directory). It modifies realloc function to check memory
> +# consistency and also contains tests for yield in hooks
> +# and for the Lua C API.
> +# But, unfortunately, <ltests.c> depends on specific PUC-Rio
> +# Lua 5.1 internal headers and should be adapted for LuaJIT.
> +
> +add_custom_target(PUC-Lua-5.1-tests
> +  DEPENDS ${LUAJIT_TEST_BINARY} PUC-Lua-5.1-tests-prepare
> +)
> +
> +add_custom_command(TARGET PUC-Lua-5.1-tests
> +  COMMENT "Running PUC-Rio Lua 5.1 tests"
> +  COMMAND
> +  env
> +    LUA_PATH="${LUA_PATH}\;\;"
> +    ${LUAJIT_TEST_COMMAND} ${CMAKE_CURRENT_SOURCE_DIR}/all.lua
> +  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
> +)
> +
> +# vim: expandtab tabstop=2 shiftwidth=2
> diff --git a/test/PUC-Lua-5.1-tests/README b/test/PUC-Lua-5.1-tests/README
> new file mode 100644
> index 0000000..e2d4b28
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/README
> @@ -0,0 +1,41 @@
> +This tarball contains the official test scripts for Lua 5.1.
> +Unlike Lua itself, these tests do not aim portability, small footprint,
> +or easy of use. (Their main goal is to try to crash Lua.) They are not
> +intended for general use. You are wellcome to use them, but expect to
> +have to "dirt your hands".
> +
> +The tarball should expand in the following contents:
> +  - several .lua scripts with the tests
> +  - a main "all.lua" Lua script that invokes all the other scripts
> +  - a subdirectory "libs" with an empty subdirectory "libs/P1",
> +    to be used by the scripts
> +  - a subdirectory "etc" with some extra files
> +
> +To run the tests, do as follows:
> +
> +- go to the test directory
> +
> +- set LUA_PATH to "?;./?.lua" (or, better yet, set LUA_PATH to "./?.lua;;"
> +  and LUA_INIT to "package.path = '?;'..package.path")
> +
> +- run "lua all.lua"
> +
> +
> +--------------------------------------------
> +Internal tests
> +--------------------------------------------
> +
> +Some tests need a special library, "testC", that gives access to
> +several internal structures in Lua.
> +This library is only available when Lua is compiled in debug mode.
> +The scripts automatically detect its absence and skip those tests.
> +
> +If you want to run these tests, move etc/ltests.c and etc/ltests.h to
> +the directory with the source Lua files, and recompile Lua with
> +the option -DLUA_USER_H='"ltests.h"' (or its equivalent to define
> +LUA_USER_H as the string "ltests.h", including the quotes). This
> +option not only adds the testC library, but it adds several other
> +internal tests as well. After the recompilation, run the tests
> +as before.
> +
> +
> diff --git a/test/PUC-Lua-5.1-tests/all.lua b/test/PUC-Lua-5.1-tests/all.lua
> new file mode 100755
> index 0000000..8c4afac
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/all.lua
> @@ -0,0 +1,137 @@
> +#!../lua
> +
> +math.randomseed(0)
> +
> +collectgarbage("setstepmul", 180)
> +collectgarbage("setpause", 190)
> +
> +
> +--[=[
> +  example of a long [comment],
> +  [[spanning several [lines]]]
> +
> +]=]
> +
> +print("current path:\n  " .. string.gsub(package.path, ";", "\n  "))
> +
> +
> +local msgs = {}
> +function Message (m)
> +  print(m)
> +  msgs[#msgs+1] = string.sub(m, 3, -3)
> +end
> +
> +
> +local c = os.clock()
> +
> +assert(os.setlocale"C")
> +
> +local T,print,gcinfo,format,write,assert,type =
> +      T,print,gcinfo,string.format,io.write,assert,type
> +
> +local function formatmem (m)
> +  if m < 1024 then return m
> +  else
> +    m = m/1024 - m/1024%1
> +    if m < 1024 then return m.."K"
> +    else
> +      m = m/1024 - m/1024%1
> +      return m.."M"
> +    end
> +  end
> +end
> +
> +local showmem = function ()
> +  if not T then
> +    print(format("    ---- total memory: %s ----\n", formatmem(gcinfo())))
> +  else
> +    T.checkmemory()
> +    local a,b,c = T.totalmem()
> +    local d,e = gcinfo()
> +    print(format(
> +  "\n    ---- total memory: %s (%dK), max use: %s,  blocks: %d\n",
> +                        formatmem(a),  d,      formatmem(c),           b))
> +  end
> +end
> +
> +
> +--
> +-- redefine dofile to run files through dump/undump
> +--
> +dofile = function (n)
> +  showmem()
> +  local f = assert(loadfile(n))
> +  local b = string.dump(f)
> +  f = assert(loadstring(b))
> +  return f()
> +end
> +
> +dofile('main.lua')
> +
> +do
> +  local u = newproxy(true)
> +  local newproxy, stderr = newproxy, io.stderr
> +  getmetatable(u).__gc = function (o)
> +    stderr:write'.'
> +    newproxy(o)
> +  end
> +end
> +
> +local f = assert(loadfile('gc.lua'))
> +f()
> +dofile('db.lua')
> +assert(dofile('calls.lua') == deep and deep)
> +dofile('strings.lua')
> +dofile('literals.lua')
> +assert(dofile('attrib.lua') == 27)
> +assert(dofile('locals.lua') == 5)
> +dofile('constructs.lua')
> +dofile('code.lua')
> +do
> +  local f = coroutine.wrap(assert(loadfile('big.lua')))
> +  assert(f() == 'b')
> +  assert(f() == 'a')
> +end
> +dofile('nextvar.lua')
> +dofile('pm.lua')
> +dofile('api.lua')
> +assert(dofile('events.lua') == 12)
> +dofile('vararg.lua')
> +dofile('closure.lua')
> +dofile('errors.lua')
> +dofile('math.lua')
> +dofile('sort.lua')
> +assert(dofile('verybig.lua') == 10); collectgarbage()
> +dofile('files.lua')
> +
> +if #msgs > 0 then
> +  print("\ntests not performed:")
> +  for i=1,#msgs do
> +    print(msgs[i])
> +  end
> +  print()
> +end
> +
> +print("final OK !!!")
> +print('cleaning all!!!!')
> +
> +debug.sethook(function (a) assert(type(a) == 'string') end, "cr")
> +
> +local _G, collectgarbage, showmem, print, format, clock =
> +      _G, collectgarbage, showmem, print, format, os.clock
> +
> +local a={}
> +for n in pairs(_G) do a[n] = 1 end
> +a.tostring = nil
> +a.___Glob = nil
> +for n in pairs(a) do _G[n] = nil end
> +
> +a = nil
> +collectgarbage()
> +collectgarbage()
> +collectgarbage()
> +collectgarbage()
> +collectgarbage()
> +collectgarbage();showmem()
> +
> +print(format("\n\ntotal time: %.2f\n", clock()-c))
> diff --git a/test/PUC-Lua-5.1-tests/api.lua b/test/PUC-Lua-5.1-tests/api.lua
> new file mode 100644
> index 0000000..c955ebf
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/api.lua
> @@ -0,0 +1,711 @@
> +
> +if T==nil then
> +  (Message or print)('\a\n >>> testC not active: skipping API tests <<<\n\a')
> +  return
> +end
> +
> +
> +
> +function tcheck (t1, t2)
> +  table.remove(t1, 1)  -- remove code
> +  assert(table.getn(t1) == table.getn(t2))
> +  for i=1,table.getn(t1) do assert(t1[i] == t2[i]) end
> +end
> +
> +function pack(...) return arg end
> +
> +
> +print('testing C API')
> +
> +-- testing allignment
> +a = T.d2s(12458954321123)
> +assert(string.len(a) == 8)   -- sizeof(double)
> +assert(T.s2d(a) == 12458954321123)
> +
> +a,b,c = T.testC("pushnum 1; pushnum 2; pushnum 3; return 2")
> +assert(a == 2 and b == 3 and not c)
> +
> +-- test that all trues are equal
> +a,b,c = T.testC("pushbool 1; pushbool 2; pushbool 0; return 3")
> +assert(a == b and a == true and c == false)
> +a,b,c = T.testC"pushbool 0; pushbool 10; pushnil;\
> +                      tobool -3; tobool -3; tobool -3; return 3"
> +assert(a==0 and b==1 and c==0)
> +
> +
> +a,b,c = T.testC("gettop; return 2", 10, 20, 30, 40)
> +assert(a == 40 and b == 5 and not c)
> +
> +t = pack(T.testC("settop 5; gettop; return .", 2, 3))
> +tcheck(t, {n=4,2,3})
> +
> +t = pack(T.testC("settop 0; settop 15; return 10", 3, 1, 23))
> +assert(t.n == 10 and t[1] == nil and t[10] == nil)
> +
> +t = pack(T.testC("remove -2; gettop; return .", 2, 3, 4))
> +tcheck(t, {n=2,2,4})
> +
> +t = pack(T.testC("insert -1; gettop; return .", 2, 3))
> +tcheck(t, {n=2,2,3})
> +
> +t = pack(T.testC("insert 3; gettop; return .", 2, 3, 4, 5))
> +tcheck(t, {n=4,2,5,3,4})
> +
> +t = pack(T.testC("replace 2; gettop; return .", 2, 3, 4, 5))
> +tcheck(t, {n=3,5,3,4})
> +
> +t = pack(T.testC("replace -2; gettop; return .", 2, 3, 4, 5))
> +tcheck(t, {n=3,2,3,5})
> +
> +t = pack(T.testC("remove 3; gettop; return .", 2, 3, 4, 5))
> +tcheck(t, {n=3,2,4,5})
> +
> +t = pack(T.testC("insert 3; pushvalue 3; remove 3; pushvalue 2; remove 2; \
> +                  insert 2; pushvalue 1; remove 1; insert 1; \
> +      insert -2; pushvalue -2; remove -3; gettop; return .",
> +      2, 3, 4, 5, 10, 40, 90))
> +tcheck(t, {n=7,2,3,4,5,10,40,90})
> +
> +t = pack(T.testC("concat 5; gettop; return .", "alo", 2, 3, "joao", 12))
> +tcheck(t, {n=1,"alo23joao12"})
> +
> +-- testing MULTRET
> +t = pack(T.testC("rawcall 2,-1; gettop; return .",
> +     function (a,b) return 1,2,3,4,a,b end, "alo", "joao"))
> +tcheck(t, {n=6,1,2,3,4,"alo", "joao"})
> +
> +do  -- test returning more results than fit in the caller stack
> +  local a = {}
> +  for i=1,1000 do a[i] = true end; a[999] = 10
> +  local b = T.testC([[call 1 -1; pop 1; tostring -1; return 1]], unpack, a)
> +  assert(b == "10")
> +end
> +
> +
> +-- testing lessthan
> +assert(T.testC("lessthan 2 5, return 1", 3, 2, 2, 4, 2, 2))
> +assert(T.testC("lessthan 5 2, return 1", 4, 2, 2, 3, 2, 2))
> +assert(not T.testC("lessthan 2 -3, return 1", "4", "2", "2", "3", "2", "2"))
> +assert(not T.testC("lessthan -3 2, return 1", "3", "2", "2", "4", "2", "2"))
> +
> +local b = {__lt = function (a,b) return a[1] < b[1] end}
> +local a1,a3,a4 = setmetatable({1}, b),
> +                 setmetatable({3}, b),
> +                 setmetatable({4}, b)
> +assert(T.testC("lessthan 2 5, return 1", a3, 2, 2, a4, 2, 2))
> +assert(T.testC("lessthan 5 -6, return 1", a4, 2, 2, a3, 2, 2))
> +a,b = T.testC("lessthan 5 -6, return 2", a1, 2, 2, a3, 2, 20)
> +assert(a == 20 and b == false)
> +
> +
> +-- testing lua_is
> +
> +function count (x, n)
> +  n = n or 2
> +  local prog = [[
> +    isnumber %d;
> +    isstring %d;
> +    isfunction %d;
> +    iscfunction %d;
> +    istable %d;
> +    isuserdata %d;
> +    isnil %d;
> +    isnull %d;
> +    return 8
> +  ]]
> +  prog = string.format(prog, n, n, n, n, n, n, n, n)
> +  local a,b,c,d,e,f,g,h = T.testC(prog, x)
> +  return a+b+c+d+e+f+g+(100*h)
> +end
> +
> +assert(count(3) == 2)
> +assert(count('alo') == 1)
> +assert(count('32') == 2)
> +assert(count({}) == 1)
> +assert(count(print) == 2)
> +assert(count(function () end) == 1)
> +assert(count(nil) == 1)
> +assert(count(io.stdin) == 1)
> +assert(count(nil, 15) == 100)
> +
> +-- testing lua_to...
> +
> +function to (s, x, n)
> +  n = n or 2
> +  return T.testC(string.format("%s %d; return 1", s, n), x)
> +end
> +
> +assert(to("tostring", {}) == nil)
> +assert(to("tostring", "alo") == "alo")
> +assert(to("tostring", 12) == "12")
> +assert(to("tostring", 12, 3) == nil)
> +assert(to("objsize", {}) == 0)
> +assert(to("objsize", "alo\0\0a") == 6)
> +assert(to("objsize", T.newuserdata(0)) == 0)
> +assert(to("objsize", T.newuserdata(101)) == 101)
> +assert(to("objsize", 12) == 2)
> +assert(to("objsize", 12, 3) == 0)
> +assert(to("tonumber", {}) == 0)
> +assert(to("tonumber", "12") == 12)
> +assert(to("tonumber", "s2") == 0)
> +assert(to("tonumber", 1, 20) == 0)
> +a = to("tocfunction", math.deg)
> +assert(a(3) == math.deg(3) and a ~= math.deg)
> +
> +
> +-- testing errors
> +
> +a = T.testC([[
> +  loadstring 2; call 0,1;
> +  pushvalue 3; insert -2; call 1, 1;
> +  call 0, 0;
> +  return 1
> +]], "x=150", function (a) assert(a==nil); return 3 end)
> +
> +assert(type(a) == 'string' and x == 150)
> +
> +function check3(p, ...)
> +  assert(arg.n == 3)
> +  assert(string.find(arg[3], p))
> +end
> +check3(":1:", T.testC("loadstring 2; gettop; return .", "x="))
> +check3("cannot read", T.testC("loadfile 2; gettop; return .", "."))
> +check3("cannot open xxxx", T.testC("loadfile 2; gettop; return .", "xxxx"))
> +
> +-- testing table access
> +
> +a = {x=0, y=12}
> +x, y = T.testC("gettable 2; pushvalue 4; gettable 2; return 2",
> +                a, 3, "y", 4, "x")
> +assert(x == 0 and y == 12)
> +T.testC("settable -5", a, 3, 4, "x", 15)
> +assert(a.x == 15)
> +a[a] = print
> +x = T.testC("gettable 2; return 1", a)  -- table and key are the same object!
> +assert(x == print)
> +T.testC("settable 2", a, "x")    -- table and key are the same object!
> +assert(a[a] == "x")
> +
> +b = setmetatable({p = a}, {})
> +getmetatable(b).__index = function (t, i) return t.p[i] end
> +k, x = T.testC("gettable 3, return 2", 4, b, 20, 35, "x")
> +assert(x == 15 and k == 35)
> +getmetatable(b).__index = function (t, i) return a[i] end
> +getmetatable(b).__newindex = function (t, i,v ) a[i] = v end
> +y = T.testC("insert 2; gettable -5; return 1", 2, 3, 4, "y", b)
> +assert(y == 12)
> +k = T.testC("settable -5, return 1", b, 3, 4, "x", 16)
> +assert(a.x == 16 and k == 4)
> +a[b] = 'xuxu'
> +y = T.testC("gettable 2, return 1", b)
> +assert(y == 'xuxu')
> +T.testC("settable 2", b, 19)
> +assert(a[b] == 19)
> +
> +-- testing next
> +a = {}
> +t = pack(T.testC("next; gettop; return .", a, nil))
> +tcheck(t, {n=1,a})
> +a = {a=3}
> +t = pack(T.testC("next; gettop; return .", a, nil))
> +tcheck(t, {n=3,a,'a',3})
> +t = pack(T.testC("next; pop 1; next; gettop; return .", a, nil))
> +tcheck(t, {n=1,a})
> +
> +
> +
> +-- testing upvalues
> +
> +do
> +  local A = T.testC[[ pushnum 10; pushnum 20; pushcclosure 2; return 1]]
> +  t, b, c = A([[pushvalue U0; pushvalue U1; pushvalue U2; return 3]])
> +  assert(b == 10 and c == 20 and type(t) == 'table')
> +  a, b = A([[tostring U3; tonumber U4; return 2]])
> +  assert(a == nil and b == 0)
> +  A([[pushnum 100; pushnum 200; replace U2; replace U1]])
> +  b, c = A([[pushvalue U1; pushvalue U2; return 2]])
> +  assert(b == 100 and c == 200)
> +  A([[replace U2; replace U1]], {x=1}, {x=2})
> +  b, c = A([[pushvalue U1; pushvalue U2; return 2]])
> +  assert(b.x == 1 and c.x == 2)
> +  T.checkmemory()
> +end
> +
> +local f = T.testC[[ pushnum 10; pushnum 20; pushcclosure 2; return 1]]
> +assert(T.upvalue(f, 1) == 10 and
> +       T.upvalue(f, 2) == 20 and
> +       T.upvalue(f, 3) == nil)
> +T.upvalue(f, 2, "xuxu")
> +assert(T.upvalue(f, 2) == "xuxu")
> +
> +
> +-- testing environments
> +
> +assert(T.testC"pushvalue G; return 1" == _G)
> +assert(T.testC"pushvalue E; return 1" == _G)
> +local a = {}
> +T.testC("replace E; return 1", a)
> +assert(T.testC"pushvalue G; return 1" == _G)
> +assert(T.testC"pushvalue E; return 1" == a)
> +assert(debug.getfenv(T.testC) == a)
> +assert(debug.getfenv(T.upvalue) == _G)
> +-- userdata inherit environment
> +local u = T.testC"newuserdata 0; return 1"
> +assert(debug.getfenv(u) == a)
> +-- functions inherit environment
> +u = T.testC"pushcclosure 0; return 1"
> +assert(debug.getfenv(u) == a)
> +debug.setfenv(T.testC, _G)
> +assert(T.testC"pushvalue E; return 1" == _G)
> +
> +local b = newproxy()
> +assert(debug.getfenv(b) == _G)
> +assert(debug.setfenv(b, a))
> +assert(debug.getfenv(b) == a)
> +
> +
> +
> +-- testing locks (refs)
> +
> +-- reuse of references
> +local i = T.ref{}
> +T.unref(i)
> +assert(T.ref{} == i)
> +
> +Arr = {}
> +Lim = 100
> +for i=1,Lim do   -- lock many objects
> +  Arr[i] = T.ref({})
> +end
> +
> +assert(T.ref(nil) == -1 and T.getref(-1) == nil)
> +T.unref(-1); T.unref(-1)
> +
> +for i=1,Lim do   -- unlock all them
> +  T.unref(Arr[i])
> +end
> +
> +function printlocks ()
> +  local n = T.testC("gettable R; return 1", "n")
> +  print("n", n)
> +  for i=0,n do
> +    print(i, T.testC("gettable R; return 1", i))
> +  end
> +end
> +
> +
> +for i=1,Lim do   -- lock many objects
> +  Arr[i] = T.ref({})
> +end
> +
> +for i=1,Lim,2 do   -- unlock half of them
> +  T.unref(Arr[i])
> +end
> +
> +assert(type(T.getref(Arr[2])) == 'table')
> +
> +
> +assert(T.getref(-1) == nil)
> +
> +
> +a = T.ref({})
> +
> +collectgarbage()
> +
> +assert(type(T.getref(a)) == 'table')
> +
> +
> +-- colect in cl the `val' of all collected userdata
> +tt = {}
> +cl = {n=0}
> +A = nil; B = nil
> +local F
> +F = function (x)
> +  local udval = T.udataval(x)
> +  table.insert(cl, udval)
> +  local d = T.newuserdata(100)   -- cria lixo
> +  d = nil
> +  assert(debug.getmetatable(x).__gc == F)
> +  loadstring("table.insert({}, {})")()   -- cria mais lixo
> +  collectgarbage()   -- forca coleta de lixo durante coleta!
> +  assert(debug.getmetatable(x).__gc == F)   -- coleta anterior nao melou isso?
> +  local dummy = {}    -- cria lixo durante coleta
> +  if A ~= nil then
> +    assert(type(A) == "userdata")
> +    assert(T.udataval(A) == B)
> +    debug.getmetatable(A)    -- just acess it
> +  end
> +  A = x   -- ressucita userdata
> +  B = udval
> +  return 1,2,3
> +end
> +tt.__gc = F
> +
> +-- test whether udate collection frees memory in the right time
> +do
> +  collectgarbage();
> +  collectgarbage();
> +  local x = collectgarbage("count");
> +  local a = T.newuserdata(5001)
> +  assert(T.testC("objsize 2; return 1", a) == 5001)
> +  assert(collectgarbage("count") >= x+4)
> +  a = nil
> +  collectgarbage();
> +  assert(collectgarbage("count") <= x+1)
> +  -- udata without finalizer
> +  x = collectgarbage("count")
> +  collectgarbage("stop")
> +  for i=1,1000 do newproxy(false) end
> +  assert(collectgarbage("count") > x+10)
> +  collectgarbage()
> +  assert(collectgarbage("count") <= x+1)
> +  -- udata with finalizer
> +  x = collectgarbage("count")
> +  collectgarbage()
> +  collectgarbage("stop")
> +  a = newproxy(true)
> +  getmetatable(a).__gc = function () end
> +  for i=1,1000 do newproxy(a) end
> +  assert(collectgarbage("count") >= x+10)
> +  collectgarbage()  -- this collection only calls TM, without freeing memory
> +  assert(collectgarbage("count") >= x+10)
> +  collectgarbage()  -- now frees memory
> +  assert(collectgarbage("count") <= x+1)
> +end
> +
> +
> +collectgarbage("stop")
> +
> +-- create 3 userdatas with tag `tt'
> +a = T.newuserdata(0); debug.setmetatable(a, tt); na = T.udataval(a)
> +b = T.newuserdata(0); debug.setmetatable(b, tt); nb = T.udataval(b)
> +c = T.newuserdata(0); debug.setmetatable(c, tt); nc = T.udataval(c)
> +
> +-- create userdata without meta table
> +x = T.newuserdata(4)
> +y = T.newuserdata(0)
> +
> +assert(debug.getmetatable(x) == nil and debug.getmetatable(y) == nil)
> +
> +d=T.ref(a);
> +e=T.ref(b);
> +f=T.ref(c);
> +t = {T.getref(d), T.getref(e), T.getref(f)}
> +assert(t[1] == a and t[2] == b and t[3] == c)
> +
> +t=nil; a=nil; c=nil;
> +T.unref(e); T.unref(f)
> +
> +collectgarbage()
> +
> +-- check that unref objects have been collected
> +assert(table.getn(cl) == 1 and cl[1] == nc)
> +
> +x = T.getref(d)
> +assert(type(x) == 'userdata' and debug.getmetatable(x) == tt)
> +x =nil
> +tt.b = b  -- create cycle
> +tt=nil    -- frees tt for GC
> +A = nil
> +b = nil
> +T.unref(d);
> +n5 = T.newuserdata(0)
> +debug.setmetatable(n5, {__gc=F})
> +n5 = T.udataval(n5)
> +collectgarbage()
> +assert(table.getn(cl) == 4)
> +-- check order of collection
> +assert(cl[2] == n5 and cl[3] == nb and cl[4] == na)
> +
> +
> +a, na = {}, {}
> +for i=30,1,-1 do
> +  a[i] = T.newuserdata(0)
> +  debug.setmetatable(a[i], {__gc=F})
> +  na[i] = T.udataval(a[i])
> +end
> +cl = {}
> +a = nil; collectgarbage()
> +assert(table.getn(cl) == 30)
> +for i=1,30 do assert(cl[i] == na[i]) end
> +na = nil
> +
> +
> +for i=2,Lim,2 do   -- unlock the other half
> +  T.unref(Arr[i])
> +end
> +
> +x = T.newuserdata(41); debug.setmetatable(x, {__gc=F})
> +assert(T.testC("objsize 2; return 1", x) == 41)
> +cl = {}
> +a = {[x] = 1}
> +x = T.udataval(x)
> +collectgarbage()
> +-- old `x' cannot be collected (`a' still uses it)
> +assert(table.getn(cl) == 0)
> +for n in pairs(a) do a[n] = nil end
> +collectgarbage()
> +assert(table.getn(cl) == 1 and cl[1] == x)   -- old `x' must be collected
> +
> +-- testing lua_equal
> +assert(T.testC("equal 2 4; return 1", print, 1, print, 20))
> +assert(T.testC("equal 3 2; return 1", 'alo', "alo"))
> +assert(T.testC("equal 2 3; return 1", nil, nil))
> +assert(not T.testC("equal 2 3; return 1", {}, {}))
> +assert(not T.testC("equal 2 3; return 1"))
> +assert(not T.testC("equal 2 3; return 1", 3))
> +
> +-- testing lua_equal with fallbacks
> +do
> +  local map = {}
> +  local t = {__eq = function (a,b) return map[a] == map[b] end}
> +  local function f(x)
> +    local u = T.newuserdata(0)
> +    debug.setmetatable(u, t)
> +    map[u] = x
> +    return u
> +  end
> +  assert(f(10) == f(10))
> +  assert(f(10) ~= f(11))
> +  assert(T.testC("equal 2 3; return 1", f(10), f(10)))
> +  assert(not T.testC("equal 2 3; return 1", f(10), f(20)))
> +  t.__eq = nil
> +  assert(f(10) ~= f(10))
> +end
> +
> +print'+'
> +
> +
> +
> +-------------------------------------------------------------------------
> +do   -- testing errors during GC
> +  local a = {}
> +  for i=1,20 do
> +    a[i] = T.newuserdata(i)   -- creates several udata
> +  end
> +  for i=1,20,2 do   -- mark half of them to raise error during GC
> +    debug.setmetatable(a[i], {__gc = function (x) error("error inside gc") end})
> +  end
> +  for i=2,20,2 do   -- mark the other half to count and to create more garbage
> +    debug.setmetatable(a[i], {__gc = function (x) loadstring("A=A+1")() end})
> +  end
> +  _G.A = 0
> +  a = 0
> +  while 1 do
> +  if xpcall(collectgarbage, function (s) a=a+1 end) then
> +    break   -- stop if no more errors
> +  end
> +  end
> +  assert(a == 10)  -- number of errors
> +  assert(A == 10)  -- number of normal collections
> +end
> +-------------------------------------------------------------------------
> +-- test for userdata vals
> +do
> +  local a = {}; local lim = 30
> +  for i=0,lim do a[i] = T.pushuserdata(i) end
> +  for i=0,lim do assert(T.udataval(a[i]) == i) end
> +  for i=0,lim do assert(T.pushuserdata(i) == a[i]) end
> +  for i=0,lim do a[a[i]] = i end
> +  for i=0,lim do a[T.pushuserdata(i)] = i end
> +  assert(type(tostring(a[1])) == "string")
> +end
> +
> +
> +-------------------------------------------------------------------------
> +-- testing multiple states
> +T.closestate(T.newstate());
> +L1 = T.newstate()
> +assert(L1)
> +assert(pack(T.doremote(L1, "function f () return 'alo', 3 end; f()")).n == 0)
> +
> +a, b = T.doremote(L1, "return f()")
> +assert(a == 'alo' and b == '3')
> +
> +T.doremote(L1, "_ERRORMESSAGE = nil")
> +-- error: `sin' is not defined
> +a, b = T.doremote(L1, "return sin(1)")
> +assert(a == nil and b == 2)   -- 2 == run-time error
> +
> +-- error: syntax error
> +a, b, c = T.doremote(L1, "return a+")
> +assert(a == nil and b == 3 and type(c) == "string")   -- 3 == syntax error
> +
> +T.loadlib(L1)
> +a, b = T.doremote(L1, [[
> +  a = strlibopen()
> +  a = packageopen()
> +  a = baselibopen(); assert(a == _G and require("_G") == a)
> +  a = iolibopen(); assert(type(a.read) == "function")
> +  assert(require("io") == a)
> +  a = tablibopen(); assert(type(a.insert) == "function")
> +  a = dblibopen(); assert(type(a.getlocal) == "function")
> +  a = mathlibopen(); assert(type(a.sin) == "function")
> +  return string.sub('okinama', 1, 2)
> +]])
> +assert(a == "ok")
> +
> +T.closestate(L1);
> +
> +L1 = T.newstate()
> +T.loadlib(L1)
> +T.doremote(L1, "a = {}")
> +T.testC(L1, [[pushstring a; gettable G; pushstring x; pushnum 1;
> +             settable -3]])
> +assert(T.doremote(L1, "return a.x") == "1")
> +
> +T.closestate(L1)
> +
> +L1 = nil
> +
> +print('+')
> +
> +-------------------------------------------------------------------------
> +-- testing memory limits
> +-------------------------------------------------------------------------
> +collectgarbage()
> +T.totalmem(T.totalmem()+5000)   -- set low memory limit (+5k)
> +assert(not pcall(loadstring"local a={}; for i=1,100000 do a[i]=i end"))
> +T.totalmem(1000000000)          -- restore high limit
> +
> +
> +local function stack(x) if x>0 then stack(x-1) end end
> +
> +-- test memory errors; increase memory limit in small steps, so that
> +-- we get memory errors in different parts of a given task, up to there
> +-- is enough memory to complete the task without errors
> +function testamem (s, f)
> +  collectgarbage()
> +  stack(10)    -- ensure minimum stack size
> +  local M = T.totalmem()
> +  local oldM = M
> +  local a,b = nil
> +  while 1 do
> +    M = M+3   -- increase memory limit in small steps
> +    T.totalmem(M)
> +    a, b = pcall(f)
> +    if a and b then break end       -- stop when no more errors
> +    collectgarbage()
> +    if not a and not string.find(b, "memory") then   -- `real' error?
> +      T.totalmem(1000000000)  -- restore high limit
> +      error(b, 0)
> +    end
> +  end
> +  T.totalmem(1000000000)  -- restore high limit
> +  print("\nlimit for " .. s .. ": " .. M-oldM)
> +  return b
> +end
> +
> +
> +-- testing memory errors when creating a new state
> +
> +b = testamem("state creation", T.newstate)
> +T.closestate(b);  -- close new state
> +
> +
> +-- testing threads
> +
> +function expand (n,s)
> +  if n==0 then return "" end
> +  local e = string.rep("=", n)
> +  return string.format("T.doonnewstack([%s[ %s;\n collectgarbage(); %s]%s])\n",
> +                              e, s, expand(n-1,s), e)
> +end
> +
> +G=0; collectgarbage(); a =collectgarbage("count")
> +loadstring(expand(20,"G=G+1"))()
> +assert(G==20); collectgarbage();  -- assert(gcinfo() <= a+1)
> +
> +testamem("thread creation", function ()
> +  return T.doonnewstack("x=1") == 0  -- try to create thread
> +end)
> +
> +
> +-- testing memory x compiler
> +
> +testamem("loadstring", function ()
> +  return loadstring("x=1")  -- try to do a loadstring
> +end)
> +
> +
> +local testprog = [[
> +local function foo () return end
> +local t = {"x"}
> +a = "aaa"
> +for _, v in ipairs(t) do a=a..v end
> +return true
> +]]
> +
> +-- testing memory x dofile
> +_G.a = nil
> +local t =os.tmpname()
> +local f = assert(io.open(t, "w"))
> +f:write(testprog)
> +f:close()
> +testamem("dofile", function ()
> +  local a = loadfile(t)
> +  return a and a()
> +end)
> +assert(os.remove(t))
> +assert(_G.a == "aaax")
> +
> +
> +-- other generic tests
> +
> +testamem("string creation", function ()
> +  local a, b = string.gsub("alo alo", "(a)", function (x) return x..'b' end)
> +  return (a == 'ablo ablo')
> +end)
> +
> +testamem("dump/undump", function ()
> +  local a = loadstring(testprog)
> +  local b = a and string.dump(a)
> +  a = b and loadstring(b)
> +  return a and a()
> +end)
> +
> +local t = os.tmpname()
> +testamem("file creation", function ()
> +  local f = assert(io.open(t, 'w'))
> +  assert (not io.open"nomenaoexistente")
> +  io.close(f);
> +  return not loadfile'nomenaoexistente'
> +end)
> +assert(os.remove(t))
> +
> +testamem("table creation", function ()
> +  local a, lim = {}, 10
> +  for i=1,lim do a[i] = i; a[i..'a'] = {} end
> +  return (type(a[lim..'a']) == 'table' and a[lim] == lim)
> +end)
> +
> +local a = 1
> +close = nil
> +testamem("closure creation", function ()
> +  function close (b,c)
> +   return function (x) return a+b+c+x end
> +  end
> +  return (close(2,3)(4) == 10)
> +end)
> +
> +testamem("coroutines", function ()
> +  local a = coroutine.wrap(function ()
> +              coroutine.yield(string.rep("a", 10))
> +              return {}
> +            end)
> +  assert(string.len(a()) == 10)
> +  return a()
> +end)
> +
> +print'+'
> +
> +-- testing some auxlib functions
> +assert(T.gsub("alo.alo.uhuh.", ".", "//") == "alo//alo//uhuh//")
> +assert(T.gsub("alo.alo.uhuh.", "alo", "//") == "//.//.uhuh.")
> +assert(T.gsub("", "alo", "//") == "")
> +assert(T.gsub("...", ".", "/.") == "/././.")
> +assert(T.gsub("...", "...", "") == "")
> +
> +
> +print'OK'
> +
> diff --git a/test/PUC-Lua-5.1-tests/attrib.lua b/test/PUC-Lua-5.1-tests/attrib.lua
> new file mode 100644
> index 0000000..655669b
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/attrib.lua
> @@ -0,0 +1,339 @@
> +do --[
> +
> +print "testing require"
> +
> +assert(require"string" == string)
> +assert(require"math" == math)
> +assert(require"table" == table)
> +assert(require"io" == io)
> +assert(require"os" == os)
> +assert(require"debug" == debug)
> +assert(require"coroutine" == coroutine)
> +
> +assert(type(package.path) == "string")
> +assert(type(package.cpath) == "string")
> +assert(type(package.loaded) == "table")
> +assert(type(package.preload) == "table")
> +
> +
> +local DIR = "libs/"
> +
> +local function createfiles (files, preextras, posextras)
> +  for n,c in pairs(files) do
> +    io.output(DIR..n)
> +    io.write(string.format(preextras, n))
> +    io.write(c)
> +    io.write(string.format(posextras, n))
> +    io.close(io.output())
> +  end
> +end
> +
> +function removefiles (files)
> +  for n in pairs(files) do
> +    os.remove(DIR..n)
> +  end
> +end
> +
> +local files = {
> +  ["A.lua"] = "",
> +  ["B.lua"] = "assert(...=='B');require 'A'",
> +  ["A.lc"] = "",
> +  ["A"] = "",
> +  ["L"] = "",
> +  ["XXxX"] = "",
> +  ["C.lua"] = "package.loaded[...] = 25; require'C'"
> +}
> +
> +AA = nil
> +local extras = [[
> +NAME = '%s'
> +REQUIRED = ...
> +return AA]]
> +
> +createfiles(files, "", extras)
> +
> +
> +local oldpath = package.path
> +
> +package.path = string.gsub("D/?.lua;D/?.lc;D/?;D/??x?;D/L", "D/", DIR)
> +
> +local try = function (p, n, r)
> +  NAME = nil
> +  local rr = require(p)
> +  assert(NAME == n)
> +  assert(REQUIRED == p)
> +  assert(rr == r)
> +end
> +
> +assert(require"C" == 25)
> +assert(require"C" == 25)
> +AA = nil
> +try('B', 'B.lua', true)
> +assert(package.loaded.B)
> +assert(require"B" == true)
> +assert(package.loaded.A)
> +package.loaded.A = nil
> +try('B', nil, true)   -- should not reload package
> +try('A', 'A.lua', true)
> +package.loaded.A = nil
> +os.remove(DIR..'A.lua')
> +AA = {}
> +try('A', 'A.lc', AA)  -- now must find second option
> +assert(require("A") == AA)
> +AA = false
> +try('K', 'L', false)     -- default option
> +try('K', 'L', false)     -- default option (should reload it)
> +assert(rawget(_G, "_REQUIREDNAME") == nil)
> +
> +AA = "x"
> +try("X", "XXxX", AA)
> +
> +
> +removefiles(files)
> +
> +
> +-- testing require of sub-packages
> +
> +package.path = string.gsub("D/?.lua;D/?/init.lua", "D/", DIR)
> +
> +files = {
> +  ["P1/init.lua"] = "AA = 10",
> +  ["P1/xuxu.lua"] = "AA = 20",
> +}
> +
> +createfiles(files, "module(..., package.seeall)\n", "")
> +AA = 0
> +
> +local m = assert(require"P1")
> +assert(m == P1 and m._NAME == "P1" and AA == 0 and m.AA == 10)
> +assert(require"P1" == P1 and P1 == m)
> +assert(require"P1" == P1)
> +assert(P1._PACKAGE == "")
> +
> +local m = assert(require"P1.xuxu")
> +assert(m == P1.xuxu and m._NAME == "P1.xuxu" and AA == 0 and m.AA == 20)
> +assert(require"P1.xuxu" == P1.xuxu and P1.xuxu == m)
> +assert(require"P1.xuxu" == P1.xuxu)
> +assert(require"P1" == P1)
> +assert(P1.xuxu._PACKAGE == "P1.")
> +assert(P1.AA == 10 and P1._PACKAGE == "")
> +assert(P1._G == _G and P1.xuxu._G == _G)
> +
> +
> +
> +removefiles(files)
> +
> +
> +package.path = ""
> +assert(not pcall(require, "file_does_not_exist"))
> +package.path = "??\0?"
> +assert(not pcall(require, "file_does_not_exist1"))
> +
> +package.path = oldpath
> +
> +-- check 'require' error message
> +local fname = "file_does_not_exist2"
> +local m, err = pcall(require, fname)
> +for t in string.gmatch(package.path..";"..package.cpath, "[^;]+") do
> +  t = string.gsub(t, "?", fname)
> +  assert(string.find(err, t, 1, true))
> +end
> +
> +
> +local function import(...)
> +  local f = {...}
> +  return function (m)
> +    for i=1, #f do m[f[i]] = _G[f[i]] end
> +  end
> +end
> +
> +local assert, module, package = assert, module, package
> +X = nil; x = 0; assert(_G.x == 0)   -- `x' must be a global variable
> +module"X"; x = 1; assert(_M.x == 1)
> +module"X.a.b.c"; x = 2; assert(_M.x == 2)
> +module("X.a.b", package.seeall); x = 3
> +assert(X._NAME == "X" and X.a.b.c._NAME == "X.a.b.c" and X.a.b._NAME == "X.a.b")
> +assert(X._M == X and X.a.b.c._M == X.a.b.c and X.a.b._M == X.a.b)
> +assert(X.x == 1 and X.a.b.c.x == 2 and X.a.b.x == 3)
> +assert(X._PACKAGE == "" and X.a.b.c._PACKAGE == "X.a.b." and
> +       X.a.b._PACKAGE == "X.a.")
> +assert(_PACKAGE.."c" == "X.a.c")
> +assert(X.a._NAME == nil and X.a._M == nil)
> +module("X.a", import("X")) ; x = 4
> +assert(X.a._NAME == "X.a" and X.a.x == 4 and X.a._M == X.a)
> +module("X.a.b", package.seeall); assert(x == 3); x = 5
> +assert(_NAME == "X.a.b" and X.a.b.x == 5)
> +
> +assert(X._G == nil and X.a._G == nil and X.a.b._G == _G and X.a.b.c._G == nil)
> +
> +setfenv(1, _G)
> +assert(x == 0)
> +
> +assert(not pcall(module, "x"))
> +assert(not pcall(module, "math.sin"))
> +
> +
> +-- testing C libraries
> +
> +
> +local p = ""   -- On Mac OS X, redefine this to "_"
> +
> +-- assert(loadlib == package.loadlib)   -- only for compatibility
> +local f, err, when = package.loadlib("libs/lib1.so", p.."luaopen_lib1")
> +if not f then
> +  (Message or print)('\a\n >>> cannot load dynamic library <<<\n\a')
> +  print(err, when)
> +else
> +  f()   -- open library
> +  assert(require("lib1") == lib1)
> +  collectgarbage()
> +  assert(lib1.id("x") == "x")
> +  f = assert(package.loadlib("libs/lib1.so", p.."anotherfunc"))
> +  assert(f(10, 20) == "1020\n")
> +  f, err, when = package.loadlib("libs/lib1.so", p.."xuxu")
> +  assert(not f and type(err) == "string" and when == "init")
> +  package.cpath = "libs/?.so"
> +  require"lib2"
> +  assert(lib2.id("x") == "x")
> +  local fs = require"lib1.sub"
> +  assert(fs == lib1.sub and next(lib1.sub) == nil)
> +  module("lib2", package.seeall)
> +  f = require"-lib2"
> +  assert(f.id("x") == "x" and _M == f and _NAME == "lib2")
> +  module("lib1.sub", package.seeall)
> +  assert(_M == fs)
> +  setfenv(1, _G)
> +
> +end
> +f, err, when = package.loadlib("donotexist", p.."xuxu")
> +assert(not f and type(err) == "string" and (when == "open" or when == "absent"))
> +
> +
> +-- testing preload
> +
> +do
> +  local p = package
> +  package = {}
> +  p.preload.pl = function (...)
> +    module(...)
> +    function xuxu (x) return x+20 end
> +  end
> +
> +  require"pl"
> +  assert(require"pl" == pl)
> +  assert(pl.xuxu(10) == 30)
> +
> +  package = p
> +  assert(type(package.path) == "string")
> +end
> +
> +
> +
> +end  --]
> +
> +print('+')
> +
> +print("testing assignments, logical operators, and constructors")
> +
> +local res, res2 = 27
> +
> +a, b = 1, 2+3
> +assert(a==1 and b==5)
> +a={}
> +function f() return 10, 11, 12 end
> +a.x, b, a[1] = 1, 2, f()
> +assert(a.x==1 and b==2 and a[1]==10)
> +a[f()], b, a[f()+3] = f(), a, 'x'
> +assert(a[10] == 10 and b == a and a[13] == 'x')
> +
> +do
> +  local f = function (n) local x = {}; for i=1,n do x[i]=i end;
> +                         return unpack(x) end;
> +  local a,b,c
> +  a,b = 0, f(1)
> +  assert(a == 0 and b == 1)
> +  A,b = 0, f(1)
> +  assert(A == 0 and b == 1)
> +  a,b,c = 0,5,f(4)
> +  assert(a==0 and b==5 and c==1)
> +  a,b,c = 0,5,f(0)
> +  assert(a==0 and b==5 and c==nil)
> +end
> +
> +
> +a, b, c, d = 1 and nil, 1 or nil, (1 and (nil or 1)), 6
> +assert(not a and b and c and d==6)
> +
> +d = 20
> +a, b, c, d = f()
> +assert(a==10 and b==11 and c==12 and d==nil)
> +a,b = f(), 1, 2, 3, f()
> +assert(a==10 and b==1)
> +
> +assert(a<b == false and a>b == true)
> +assert((10 and 2) == 2)
> +assert((10 or 2) == 10)
> +assert((10 or assert(nil)) == 10)
> +assert(not (nil and assert(nil)))
> +assert((nil or "alo") == "alo")
> +assert((nil and 10) == nil)
> +assert((false and 10) == false)
> +assert((true or 10) == true)
> +assert((false or 10) == 10)
> +assert(false ~= nil)
> +assert(nil ~= false)
> +assert(not nil == true)
> +assert(not not nil == false)
> +assert(not not 1 == true)
> +assert(not not a == true)
> +assert(not not (6 or nil) == true)
> +assert(not not (nil and 56) == false)
> +assert(not not (nil and true) == false)
> +print('+')
> +
> +a = {}
> +a[true] = 20
> +a[false] = 10
> +assert(a[1<2] == 20 and a[1>2] == 10)
> +
> +function f(a) return a end
> +
> +local a = {}
> +for i=3000,-3000,-1 do a[i] = i; end
> +a[10e30] = "alo"; a[true] = 10; a[false] = 20
> +assert(a[10e30] == 'alo' and a[not 1] == 20 and a[10<20] == 10)
> +for i=3000,-3000,-1 do assert(a[i] == i); end
> +a[print] = assert
> +a[f] = print
> +a[a] = a
> +assert(a[a][a][a][a][print] == assert)
> +a[print](a[a[f]] == a[print])
> +a = nil
> +
> +a = {10,9,8,7,6,5,4,3,2; [-3]='a', [f]=print, a='a', b='ab'}
> +a, a.x, a.y = a, a[-3]
> +assert(a[1]==10 and a[-3]==a.a and a[f]==print and a.x=='a' and not a.y)
> +a[1], f(a)[2], b, c = {['alo']=assert}, 10, a[1], a[f], 6, 10, 23, f(a), 2
> +a[1].alo(a[2]==10 and b==10 and c==print)
> +
> +a[2^31] = 10; a[2^31+1] = 11; a[-2^31] = 12;
> +a[2^32] = 13; a[-2^32] = 14; a[2^32+1] = 15; a[10^33] = 16;
> +
> +assert(a[2^31] == 10 and a[2^31+1] == 11 and a[-2^31] == 12 and
> +       a[2^32] == 13 and a[-2^32] == 14 and a[2^32+1] == 15 and
> +       a[10^33] == 16)
> +
> +a = nil
> +
> +
> +do
> +  local a,i,j,b
> +  a = {'a', 'b'}; i=1; j=2; b=a
> +  i, a[i], a, j, a[j], a[i+j] = j, i, i, b, j, i
> +  assert(i == 2 and b[1] == 1 and a == 1 and j == b and b[2] == 2 and
> +         b[3] == 1)
> +end
> +
> +print('OK')
> +
> +return res
> diff --git a/test/PUC-Lua-5.1-tests/big.lua b/test/PUC-Lua-5.1-tests/big.lua
> new file mode 100644
> index 0000000..9261288
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/big.lua
> @@ -0,0 +1,381 @@
> +print "testing string length overflow"
> +
> +local longs = string.rep("\0", 2^25)
> +local function catter (i)
> +  return assert(loadstring(
> +    string.format("return function(a) return a%s end",
> +                     string.rep("..a", i-1))))()
> +end
> +rep129 = catter(129)
> +local a, b = pcall(rep129, longs)
> +assert(not a and string.find(b, "overflow"))
> +print('+')
> +
> +
> +require "checktable"
> +
> +--[[ lots of empty lines (to force SETLINEW)
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +--]]
> +
> +
> +a,b = nil,nil
> +while not b do
> +if a then
> +b = {  -- lots of strings (to force JMPW and PUSHCONSTANTW)
> +"n1", "n2", "n3", "n4", "n5", "n6", "n7", "n8", "n9", "n10",
> +"n11", "n12", "j301", "j302", "j303", "j304", "j305", "j306", "j307", "j308",
> +"j309", "a310", "n311", "n312", "n313", "n314", "n315", "n316", "n317", "n318",
> +"n319", "n320", "n321", "n322", "n323", "n324", "n325", "n326", "n327", "n328",
> +"a329", "n330", "n331", "n332", "n333", "n334", "n335", "n336", "n337", "n338",
> +"n339", "n340", "n341", "z342", "n343", "n344", "n345", "n346", "n347", "n348",
> +"n349", "n350", "n351", "n352", "r353", "n354", "n355", "n356", "n357", "n358",
> +"n359", "n360", "n361", "n362", "n363", "n364", "n365", "n366", "z367", "n368",
> +"n369", "n370", "n371", "n372", "n373", "n374", "n375", "a376", "n377", "n378",
> +"n379", "n380", "n381", "n382", "n383", "n384", "n385", "n386", "n387", "n388",
> +"n389", "n390", "n391", "n392", "n393", "n394", "n395", "n396", "n397", "n398",
> +"n399", "n400", "n13", "n14", "n15", "n16", "n17", "n18", "n19", "n20",
> +"n21", "n22", "n23", "a24", "n25", "n26", "n27", "n28", "n29", "j30",
> +"n31", "n32", "n33", "n34", "n35", "n36", "n37", "n38", "n39", "n40",
> +"n41", "n42", "n43", "n44", "n45", "n46", "n47", "n48", "n49", "n50",
> +"n51", "n52", "n53", "n54", "n55", "n56", "n57", "n58", "n59", "n60",
> +"n61", "n62", "n63", "n64", "n65", "a66", "z67", "n68", "n69", "n70",
> +"n71", "n72", "n73", "n74", "n75", "n76", "n77", "n78", "n79", "n80",
> +"n81", "n82", "n83", "n84", "n85", "n86", "n87", "n88", "n89", "n90",
> +"n91", "n92", "n93", "n94", "n95", "n96", "n97", "n98", "n99", "n100",
> +"n201", "n202", "n203", "n204", "n205", "n206", "n207", "n208", "n209", "n210",
> +"n211", "n212", "n213", "n214", "n215", "n216", "n217", "n218", "n219", "n220",
> +"n221", "n222", "n223", "n224", "n225", "n226", "n227", "n228", "n229", "n230",
> +"n231", "n232", "n233", "n234", "n235", "n236", "n237", "n238", "n239", "a240",
> +"a241", "a242", "a243", "a244", "a245", "a246", "a247", "a248", "a249", "n250",
> +"n251", "n252", "n253", "n254", "n255", "n256", "n257", "n258", "n259", "n260",
> +"n261", "n262", "n263", "n264", "n265", "n266", "n267", "n268", "n269", "n270",
> +"n271", "n272", "n273", "n274", "n275", "n276", "n277", "n278", "n279", "n280",
> +"n281", "n282", "n283", "n284", "n285", "n286", "n287", "n288", "n289", "n290",
> +"n291", "n292", "n293", "n294", "n295", "n296", "n297", "n298", "n299"
> +; x=23}
> +else a = 1 end
> +
> +
> +end
> +
> +assert(b.x == 23)
> +print('+')
> +
> +stat(b)
> +
> +repeat
> +a = {
> +n1 = 1.5, n2 = 2.5, n3 = 3.5, n4 = 4.5, n5 = 5.5, n6 = 6.5, n7 = 7.5,
> +n8 = 8.5, n9 = 9.5, n10 = 10.5, n11 = 11.5, n12 = 12.5,
> +j301 = 301.5, j302 = 302.5, j303 = 303.5, j304 = 304.5, j305 = 305.5,
> +j306 = 306.5, j307 = 307.5, j308 = 308.5, j309 = 309.5, a310 = 310.5,
> +n311 = 311.5, n312 = 312.5, n313 = 313.5, n314 = 314.5, n315 = 315.5,
> +n316 = 316.5, n317 = 317.5, n318 = 318.5, n319 = 319.5, n320 = 320.5,
> +n321 = 321.5, n322 = 322.5, n323 = 323.5, n324 = 324.5, n325 = 325.5,
> +n326 = 326.5, n327 = 327.5, n328 = 328.5, a329 = 329.5, n330 = 330.5,
> +n331 = 331.5, n332 = 332.5, n333 = 333.5, n334 = 334.5, n335 = 335.5,
> +n336 = 336.5, n337 = 337.5, n338 = 338.5, n339 = 339.5, n340 = 340.5,
> +n341 = 341.5, z342 = 342.5, n343 = 343.5, n344 = 344.5, n345 = 345.5,
> +n346 = 346.5, n347 = 347.5, n348 = 348.5, n349 = 349.5, n350 = 350.5,
> +n351 = 351.5, n352 = 352.5, r353 = 353.5, n354 = 354.5, n355 = 355.5,
> +n356 = 356.5, n357 = 357.5, n358 = 358.5, n359 = 359.5, n360 = 360.5,
> +n361 = 361.5, n362 = 362.5, n363 = 363.5, n364 = 364.5, n365 = 365.5,
> +n366 = 366.5, z367 = 367.5, n368 = 368.5, n369 = 369.5, n370 = 370.5,
> +n371 = 371.5, n372 = 372.5, n373 = 373.5, n374 = 374.5, n375 = 375.5,
> +a376 = 376.5, n377 = 377.5, n378 = 378.5, n379 = 379.5, n380 = 380.5,
> +n381 = 381.5, n382 = 382.5, n383 = 383.5, n384 = 384.5, n385 = 385.5,
> +n386 = 386.5, n387 = 387.5, n388 = 388.5, n389 = 389.5, n390 = 390.5,
> +n391 = 391.5, n392 = 392.5, n393 = 393.5, n394 = 394.5, n395 = 395.5,
> +n396 = 396.5, n397 = 397.5, n398 = 398.5, n399 = 399.5, n400 = 400.5,
> +n13 = 13.5, n14 = 14.5, n15 = 15.5, n16 = 16.5, n17 = 17.5,
> +n18 = 18.5, n19 = 19.5, n20 = 20.5, n21 = 21.5, n22 = 22.5,
> +n23 = 23.5, a24 = 24.5, n25 = 25.5, n26 = 26.5, n27 = 27.5,
> +n28 = 28.5, n29 = 29.5, j30 = 30.5, n31 = 31.5, n32 = 32.5,
> +n33 = 33.5, n34 = 34.5, n35 = 35.5, n36 = 36.5, n37 = 37.5,
> +n38 = 38.5, n39 = 39.5, n40 = 40.5, n41 = 41.5, n42 = 42.5,
> +n43 = 43.5, n44 = 44.5, n45 = 45.5, n46 = 46.5, n47 = 47.5,
> +n48 = 48.5, n49 = 49.5, n50 = 50.5, n51 = 51.5, n52 = 52.5,
> +n53 = 53.5, n54 = 54.5, n55 = 55.5, n56 = 56.5, n57 = 57.5,
> +n58 = 58.5, n59 = 59.5, n60 = 60.5, n61 = 61.5, n62 = 62.5,
> +n63 = 63.5, n64 = 64.5, n65 = 65.5, a66 = 66.5, z67 = 67.5,
> +n68 = 68.5, n69 = 69.5, n70 = 70.5, n71 = 71.5, n72 = 72.5,
> +n73 = 73.5, n74 = 74.5, n75 = 75.5, n76 = 76.5, n77 = 77.5,
> +n78 = 78.5, n79 = 79.5, n80 = 80.5, n81 = 81.5, n82 = 82.5,
> +n83 = 83.5, n84 = 84.5, n85 = 85.5, n86 = 86.5, n87 = 87.5,
> +n88 = 88.5, n89 = 89.5, n90 = 90.5, n91 = 91.5, n92 = 92.5,
> +n93 = 93.5, n94 = 94.5, n95 = 95.5, n96 = 96.5, n97 = 97.5,
> +n98 = 98.5, n99 = 99.5, n100 = 100.5, n201 = 201.5, n202 = 202.5,
> +n203 = 203.5, n204 = 204.5, n205 = 205.5, n206 = 206.5, n207 = 207.5,
> +n208 = 208.5, n209 = 209.5, n210 = 210.5, n211 = 211.5, n212 = 212.5,
> +n213 = 213.5, n214 = 214.5, n215 = 215.5, n216 = 216.5, n217 = 217.5,
> +n218 = 218.5, n219 = 219.5, n220 = 220.5, n221 = 221.5, n222 = 222.5,
> +n223 = 223.5, n224 = 224.5, n225 = 225.5, n226 = 226.5, n227 = 227.5,
> +n228 = 228.5, n229 = 229.5, n230 = 230.5, n231 = 231.5, n232 = 232.5,
> +n233 = 233.5, n234 = 234.5, n235 = 235.5, n236 = 236.5, n237 = 237.5,
> +n238 = 238.5, n239 = 239.5, a240 = 240.5, a241 = 241.5, a242 = 242.5,
> +a243 = 243.5, a244 = 244.5, a245 = 245.5, a246 = 246.5, a247 = 247.5,
> +a248 = 248.5, a249 = 249.5, n250 = 250.5, n251 = 251.5, n252 = 252.5,
> +n253 = 253.5, n254 = 254.5, n255 = 255.5, n256 = 256.5, n257 = 257.5,
> +n258 = 258.5, n259 = 259.5, n260 = 260.5, n261 = 261.5, n262 = 262.5,
> +n263 = 263.5, n264 = 264.5, n265 = 265.5, n266 = 266.5, n267 = 267.5,
> +n268 = 268.5, n269 = 269.5, n270 = 270.5, n271 = 271.5, n272 = 272.5,
> +n273 = 273.5, n274 = 274.5, n275 = 275.5, n276 = 276.5, n277 = 277.5,
> +n278 = 278.5, n279 = 279.5, n280 = 280.5, n281 = 281.5, n282 = 282.5,
> +n283 = 283.5, n284 = 284.5, n285 = 285.5, n286 = 286.5, n287 = 287.5,
> +n288 = 288.5, n289 = 289.5, n290 = 290.5, n291 = 291.5, n292 = 292.5,
> +n293 = 293.5, n294 = 294.5, n295 = 295.5, n296 = 296.5, n297 = 297.5,
> +n298 = 298.5, n299 = 299.5, j300 = 300} or 1
> +until 1
> +
> +assert(a.n299 == 299.5)
> +xxx = 1
> +assert(xxx == 1)
> +
> +stat(a)
> +
> +function a:findfield (f)
> +  local i,v = next(self, nil)
> +  while i ~= f do
> +    if not i then return end
> +    i,v = next(self, i)
> +  end
> +  return v
> +end
> +
> +local ii = 0
> +i = 1
> +while b[i] do
> +  local r = a:findfield(b[i]);
> +  assert(a[b[i]] == r)
> +  ii = math.max(ii,i)
> +  i = i+1
> +end
> +
> +assert(ii == 299)
> +
> +function xxxx (x) coroutine.yield('b'); return ii+x end
> +
> +assert(xxxx(10) == 309)
> +
> +a = nil
> +b = nil
> +a1 = nil
> +
> +print("tables with table indices:")
> +i = 1; a={}
> +while i <= 1023 do a[{}] = i; i=i+1 end
> +stat(a)
> +a = nil
> +
> +print("tables with function indices:")
> +a={}
> +for i=1,511 do local x; a[function () return x end] = i end
> +stat(a)
> +a = nil
> +
> +print'OK'
> +
> +return 'a'
> diff --git a/test/PUC-Lua-5.1-tests/calls.lua b/test/PUC-Lua-5.1-tests/calls.lua
> new file mode 100644
> index 0000000..788f9a1
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/calls.lua
> @@ -0,0 +1,294 @@
> +print("testing functions and calls")
> +
> +-- get the opportunity to test 'type' too ;)
> +
> +assert(type(1<2) == 'boolean')
> +assert(type(true) == 'boolean' and type(false) == 'boolean')
> +assert(type(nil) == 'nil' and type(-3) == 'number' and type'x' == 'string' and
> +       type{} == 'table' and type(type) == 'function')
> +
> +assert(type(assert) == type(print))
> +f = nil
> +function f (x) return a:x (x) end
> +assert(type(f) == 'function')
> +
> +
> +-- testing local-function recursion
> +fact = false
> +do
> +  local res = 1
> +  local function fact (n)
> +    if n==0 then return res
> +    else return n*fact(n-1)
> +    end
> +  end
> +  assert(fact(5) == 120)
> +end
> +assert(fact == false)
> +
> +-- testing declarations
> +a = {i = 10}
> +self = 20
> +function a:x (x) return x+self.i end
> +function a.y (x) return x+self end
> +
> +assert(a:x(1)+10 == a.y(1))
> +
> +a.t = {i=-100}
> +a["t"].x = function (self, a,b) return self.i+a+b end
> +
> +assert(a.t:x(2,3) == -95)
> +
> +do
> +  local a = {x=0}
> +  function a:add (x) self.x, a.y = self.x+x, 20; return self end
> +  assert(a:add(10):add(20):add(30).x == 60 and a.y == 20)
> +end
> +
> +local a = {b={c={}}}
> +
> +function a.b.c.f1 (x) return x+1 end
> +function a.b.c:f2 (x,y) self[x] = y end
> +assert(a.b.c.f1(4) == 5)
> +a.b.c:f2('k', 12); assert(a.b.c.k == 12)
> +
> +print('+')
> +
> +t = nil   -- 'declare' t
> +function f(a,b,c) local d = 'a'; t={a,b,c,d} end
> +
> +f(      -- this line change must be valid
> +  1,2)
> +assert(t[1] == 1 and t[2] == 2 and t[3] == nil and t[4] == 'a')
> +f(1,2,   -- this one too
> +      3,4)
> +assert(t[1] == 1 and t[2] == 2 and t[3] == 3 and t[4] == 'a')
> +
> +function fat(x)
> +  if x <= 1 then return 1
> +  else return x*loadstring("return fat(" .. x-1 .. ")")()
> +  end
> +end
> +
> +assert(loadstring "loadstring 'assert(fat(6)==720)' () ")()
> +a = loadstring('return fat(5), 3')
> +a,b = a()
> +assert(a == 120 and b == 3)
> +print('+')
> +
> +function err_on_n (n)
> +  if n==0 then error(); exit(1);
> +  else err_on_n (n-1); exit(1);
> +  end
> +end
> +
> +do
> +  function dummy (n)
> +    if n > 0 then
> +      assert(not pcall(err_on_n, n))
> +      dummy(n-1)
> +    end
> +  end
> +end
> +
> +dummy(10)
> +
> +function deep (n)
> +  if n>0 then deep(n-1) end
> +end
> +deep(10)
> +deep(200)
> +
> +-- testing tail call
> +function deep (n) if n>0 then return deep(n-1) else return 101 end end
> +assert(deep(30000) == 101)
> +a = {}
> +function a:deep (n) if n>0 then return self:deep(n-1) else return 101 end end
> +assert(a:deep(30000) == 101)
> +
> +print('+')
> +
> +
> +a = nil
> +(function (x) a=x end)(23)
> +assert(a == 23 and (function (x) return x*2 end)(20) == 40)
> +
> +
> +local x,y,z,a
> +a = {}; lim = 2000
> +for i=1, lim do a[i]=i end
> +assert(select(lim, unpack(a)) == lim and select('#', unpack(a)) == lim)
> +x = unpack(a)
> +assert(x == 1)
> +x = {unpack(a)}
> +assert(table.getn(x) == lim and x[1] == 1 and x[lim] == lim)
> +x = {unpack(a, lim-2)}
> +assert(table.getn(x) == 3 and x[1] == lim-2 and x[3] == lim)
> +x = {unpack(a, 10, 6)}
> +assert(next(x) == nil)   -- no elements
> +x = {unpack(a, 11, 10)}
> +assert(next(x) == nil)   -- no elements
> +x,y = unpack(a, 10, 10)
> +assert(x == 10 and y == nil)
> +x,y,z = unpack(a, 10, 11)
> +assert(x == 10 and y == 11 and z == nil)
> +a,x = unpack{1}
> +assert(a==1 and x==nil)
> +a,x = unpack({1,2}, 1, 1)
> +assert(a==1 and x==nil)
> +
> +
> +-- testing closures
> +
> +-- fixed-point operator
> +Y = function (le)
> +      local function a (f)
> +        return le(function (x) return f(f)(x) end)
> +      end
> +      return a(a)
> +    end
> +
> +
> +-- non-recursive factorial
> +
> +F = function (f)
> +      return function (n)
> +               if n == 0 then return 1
> +               else return n*f(n-1) end
> +             end
> +    end
> +
> +fat = Y(F)
> +
> +assert(fat(0) == 1 and fat(4) == 24 and Y(F)(5)==5*Y(F)(4))
> +
> +local function g (z)
> +  local function f (a,b,c,d)
> +    return function (x,y) return a+b+c+d+a+x+y+z end
> +  end
> +  return f(z,z+1,z+2,z+3)
> +end
> +
> +f = g(10)
> +assert(f(9, 16) == 10+11+12+13+10+9+16+10)
> +
> +Y, F, f = nil
> +print('+')
> +
> +-- testing multiple returns
> +
> +function unlpack (t, i)
> +  i = i or 1
> +  if (i <= table.getn(t)) then
> +    return t[i], unlpack(t, i+1)
> +  end
> +end
> +
> +function equaltab (t1, t2)
> +  assert(table.getn(t1) == table.getn(t2))
> +  for i,v1 in ipairs(t1) do
> +    assert(v1 == t2[i])
> +  end
> +end
> +
> +local function pack (...)
> +  local x = {...}
> +  x.n = select('#', ...)
> +  return x
> +end
> +
> +function f() return 1,2,30,4 end
> +function ret2 (a,b) return a,b end
> +
> +local a,b,c,d = unlpack{1,2,3}
> +assert(a==1 and b==2 and c==3 and d==nil)
> +a = {1,2,3,4,false,10,'alo',false,assert}
> +equaltab(pack(unlpack(a)), a)
> +equaltab(pack(unlpack(a), -1), {1,-1})
> +a,b,c,d = ret2(f()), ret2(f())
> +assert(a==1 and b==1 and c==2 and d==nil)
> +a,b,c,d = unlpack(pack(ret2(f()), ret2(f())))
> +assert(a==1 and b==1 and c==2 and d==nil)
> +a,b,c,d = unlpack(pack(ret2(f()), (ret2(f()))))
> +assert(a==1 and b==1 and c==nil and d==nil)
> +
> +a = ret2{ unlpack{1,2,3}, unlpack{3,2,1}, unlpack{"a", "b"}}
> +assert(a[1] == 1 and a[2] == 3 and a[3] == "a" and a[4] == "b")
> +
> +
> +-- testing calls with 'incorrect' arguments
> +rawget({}, "x", 1)
> +rawset({}, "x", 1, 2)
> +assert(math.sin(1,2) == math.sin(1))
> +table.sort({10,9,8,4,19,23,0,0}, function (a,b) return a<b end, "extra arg")
> +
> +
> +-- test for generic load
> +x = "-- a comment\0\0\0\n  x = 10 + \n23; \
> +     local a = function () x = 'hi' end; \
> +     return '\0'"
> +local i = 0
> +function read1 (x)
> +  return function ()
> +    collectgarbage()
> +    i=i+1
> +    return string.sub(x, i, i)
> +  end
> +end
> +
> +a = assert(load(read1(x), "modname"))
> +assert(a() == "\0" and _G.x == 33)
> +assert(debug.getinfo(a).source == "modname")
> +
> +x = string.dump(loadstring("x = 1; return x"))
> +i = 0
> +a = assert(load(read1(x)))
> +assert(a() == 1 and _G.x == 1)
> +
> +i = 0
> +local a, b = load(read1("*a = 123"))
> +assert(not a and type(b) == "string" and i == 2)
> +
> +a, b = load(function () error("hhi") end)
> +assert(not a and string.find(b, "hhi"))
> +
> +-- test generic load with nested functions
> +x = [[
> +  return function (x)
> +    return function (y)
> +     return function (z)
> +       return x+y+z
> +     end
> +   end
> +  end
> +]]
> +
> +a = assert(load(read1(x)))
> +assert(a()(2)(3)(10) == 15)
> +
> +
> +-- test for dump/undump with upvalues
> +local a, b = 20, 30
> +x = loadstring(string.dump(function (x)
> +  if x == "set" then a = 10+b; b = b+1 else
> +  return a
> +  end
> +end))
> +assert(x() == nil)
> +assert(debug.setupvalue(x, 1, "hi") == "a")
> +assert(x() == "hi")
> +assert(debug.setupvalue(x, 2, 13) == "b")
> +assert(not debug.setupvalue(x, 3, 10))   -- only 2 upvalues
> +x("set")
> +assert(x() == 23)
> +x("set")
> +assert(x() == 24)
> +
> +
> +-- test for bug in parameter adjustment
> +assert((function () return nil end)(4) == nil)
> +assert((function () local a; return a end)(4) == nil)
> +assert((function (a) return a end)() == nil)
> +
> +print('OK')
> +return deep
> diff --git a/test/PUC-Lua-5.1-tests/checktable.lua b/test/PUC-Lua-5.1-tests/checktable.lua
> new file mode 100644
> index 0000000..f0938be
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/checktable.lua
> @@ -0,0 +1,77 @@
> +
> +assert(rawget(_G, "stat") == nil)  -- module not loaded before
> +
> +if T == nil then
> +  stat = function () print"`querytab' nao ativo" end
> +  return
> +end
> +
> +
> +function checktable (t)
> +  local asize, hsize, ff = T.querytab(t)
> +  local l = {}
> +  for i=0,hsize-1 do
> +    local key,val,next = T.querytab(t, i + asize)
> +    if key == nil then
> +      assert(l[i] == nil and val==nil and next==nil)
> +    elseif key == "<undef>" then
> +      assert(val==nil)
> +    else
> +      assert(t[key] == val)
> +      local mp = T.hash(key, t)
> +      if l[i] then
> +        assert(l[i] == mp)
> +      elseif mp ~= i then
> +        l[i] = mp
> +      else  -- list head
> +        l[mp] = {mp}   -- first element
> +        while next do
> +          assert(ff <= next and next < hsize)
> +          if l[next] then assert(l[next] == mp) else l[next] = mp end
> +          table.insert(l[mp], next)
> +          key,val,next = T.querytab(t, next)
> +          assert(key)
> +        end
> +      end
> +    end
> +  end
> +  l.asize = asize; l.hsize = hsize; l.ff = ff
> +  return l
> +end
> +
> +function mostra (t)
> +  local asize, hsize, ff = T.querytab(t)
> +  print(asize, hsize, ff)
> +  print'------'
> +  for i=0,asize-1 do
> +    local _, v = T.querytab(t, i)
> +    print(string.format("[%d] -", i), v)
> +  end
> +  print'------'
> +  for i=0,hsize-1 do
> +    print(i, T.querytab(t, i+asize))
> +  end
> +  print'-------------'
> +end
> +
> +function stat (t)
> +  t = checktable(t)
> +  local nelem, nlist = 0, 0
> +  local maxlist = {}
> +  for i=0,t.hsize-1 do
> +    if type(t[i]) == 'table' then
> +      local n = table.getn(t[i])
> +      nlist = nlist+1
> +      nelem = nelem + n
> +      if not maxlist[n] then maxlist[n] = 0 end
> +      maxlist[n] = maxlist[n]+1
> +    end
> +  end
> +  print(string.format("hsize=%d  elements=%d  load=%.2f  med.len=%.2f (asize=%d)",
> +          t.hsize, nelem, nelem/t.hsize, nelem/nlist, t.asize))
> +  for i=1,table.getn(maxlist) do
> +    local n = maxlist[i] or 0
> +    print(string.format("%5d %10d %.2f%%", i, n, n*100/nlist))
> +  end
> +end
> +
> diff --git a/test/PUC-Lua-5.1-tests/closure.lua b/test/PUC-Lua-5.1-tests/closure.lua
> new file mode 100644
> index 0000000..27ca0ad
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/closure.lua
> @@ -0,0 +1,422 @@
> +print "testing closures and coroutines"
> +
> +local A,B = 0,{g=10}
> +function f(x)
> +  local a = {}
> +  for i=1,1000 do
> +    local y = 0
> +    do
> +      a[i] = function () B.g = B.g+1; y = y+x; return y+A end
> +    end
> +  end
> +  local dummy = function () return a[A] end
> +  collectgarbage()
> +  A = 1; assert(dummy() == a[1]); A = 0;
> +  assert(a[1]() == x)
> +  assert(a[3]() == x)
> +  collectgarbage()
> +  assert(B.g == 12)
> +  return a
> +end
> +
> +a = f(10)
> +-- force a GC in this level
> +local x = {[1] = {}}   -- to detect a GC
> +setmetatable(x, {__mode = 'kv'})
> +while x[1] do   -- repeat until GC
> +  local a = A..A..A..A  -- create garbage
> +  A = A+1
> +end
> +assert(a[1]() == 20+A)
> +assert(a[1]() == 30+A)
> +assert(a[2]() == 10+A)
> +collectgarbage()
> +assert(a[2]() == 20+A)
> +assert(a[2]() == 30+A)
> +assert(a[3]() == 20+A)
> +assert(a[8]() == 10+A)
> +assert(getmetatable(x).__mode == 'kv')
> +assert(B.g == 19)
> +
> +-- testing closures with 'for' control variable
> +a = {}
> +for i=1,10 do
> +  a[i] = {set = function(x) i=x end, get = function () return i end}
> +  if i == 3 then break end
> +end
> +assert(a[4] == nil)
> +a[1].set(10)
> +assert(a[2].get() == 2)
> +a[2].set('a')
> +assert(a[3].get() == 3)
> +assert(a[2].get() == 'a')
> +
> +a = {}
> +for i, k in pairs{'a', 'b'} do
> +  a[i] = {set = function(x, y) i=x; k=y end,
> +          get = function () return i, k end}
> +  if i == 2 then break end
> +end
> +a[1].set(10, 20)
> +local r,s = a[2].get()
> +assert(r == 2 and s == 'b')
> +r,s = a[1].get()
> +assert(r == 10 and s == 20)
> +a[2].set('a', 'b')
> +r,s = a[2].get()
> +assert(r == "a" and s == "b")
> +
> +
> +-- testing closures with 'for' control variable x break
> +for i=1,3 do
> +  f = function () return i end
> +  break
> +end
> +assert(f() == 1)
> +
> +for k, v in pairs{"a", "b"} do
> +  f = function () return k, v end
> +  break
> +end
> +assert(({f()})[1] == 1)
> +assert(({f()})[2] == "a")
> +
> +
> +-- testing closure x break x return x errors
> +
> +local b
> +function f(x)
> +  local first = 1
> +  while 1 do
> +    if x == 3 and not first then return end
> +    local a = 'xuxu'
> +    b = function (op, y)
> +          if op == 'set' then
> +            a = x+y
> +          else
> +            return a
> +          end
> +        end
> +    if x == 1 then do break end
> +    elseif x == 2 then return
> +    else if x ~= 3 then error() end
> +    end
> +    first = nil
> +  end
> +end
> +
> +for i=1,3 do
> +  f(i)
> +  assert(b('get') == 'xuxu')
> +  b('set', 10); assert(b('get') == 10+i)
> +  b = nil
> +end
> +
> +pcall(f, 4);
> +assert(b('get') == 'xuxu')
> +b('set', 10); assert(b('get') == 14)
> +
> +
> +local w
> +-- testing multi-level closure
> +function f(x)
> +  return function (y)
> +    return function (z) return w+x+y+z end
> +  end
> +end
> +
> +y = f(10)
> +w = 1.345
> +assert(y(20)(30) == 60+w)
> +
> +-- testing closures x repeat-until
> +
> +local a = {}
> +local i = 1
> +repeat
> +  local x = i
> +  a[i] = function () i = x+1; return x end
> +until i > 10 or a[i]() ~= x
> +assert(i == 11 and a[1]() == 1 and a[3]() == 3 and i == 4)
> +
> +print'+'
> +
> +
> +-- test for correctly closing upvalues in tail calls of vararg functions
> +local function t ()
> +  local function c(a,b) assert(a=="test" and b=="OK") end
> +  local function v(f, ...) c("test", f() ~= 1 and "FAILED" or "OK") end
> +  local x = 1
> +  return v(function() return x end)
> +end
> +t()
> +
> +
> +-- coroutine tests
> +
> +local f
> +
> +assert(coroutine.running() == nil)
> +
> +
> +-- tests for global environment
> +
> +local function foo (a)
> +  setfenv(0, a)
> +  coroutine.yield(getfenv())
> +  assert(getfenv(0) == a)
> +  assert(getfenv(1) == _G)
> +  assert(getfenv(loadstring"") == a)
> +  return getfenv()
> +end
> +
> +f = coroutine.wrap(foo)
> +local a = {}
> +assert(f(a) == _G)
> +local a,b = pcall(f)
> +assert(a and b == _G)
> +
> +
> +-- tests for multiple yield/resume arguments
> +
> +local function eqtab (t1, t2)
> +  assert(table.getn(t1) == table.getn(t2))
> +  for i,v in ipairs(t1) do
> +    assert(t2[i] == v)
> +  end
> +end
> +
> +_G.x = nil   -- declare x
> +function foo (a, ...)
> +  assert(coroutine.running() == f)
> +  assert(coroutine.status(f) == "running")
> +  local arg = {...}
> +  for i=1,table.getn(arg) do
> +    _G.x = {coroutine.yield(unpack(arg[i]))}
> +  end
> +  return unpack(a)
> +end
> +
> +f = coroutine.create(foo)
> +assert(type(f) == "thread" and coroutine.status(f) == "suspended")
> +assert(string.find(tostring(f), "thread"))
> +local s,a,b,c,d
> +s,a,b,c,d = coroutine.resume(f, {1,2,3}, {}, {1}, {'a', 'b', 'c'})
> +assert(s and a == nil and coroutine.status(f) == "suspended")
> +s,a,b,c,d = coroutine.resume(f)
> +eqtab(_G.x, {})
> +assert(s and a == 1 and b == nil)
> +s,a,b,c,d = coroutine.resume(f, 1, 2, 3)
> +eqtab(_G.x, {1, 2, 3})
> +assert(s and a == 'a' and b == 'b' and c == 'c' and d == nil)
> +s,a,b,c,d = coroutine.resume(f, "xuxu")
> +eqtab(_G.x, {"xuxu"})
> +assert(s and a == 1 and b == 2 and c == 3 and d == nil)
> +assert(coroutine.status(f) == "dead")
> +s, a = coroutine.resume(f, "xuxu")
> +assert(not s and string.find(a, "dead") and coroutine.status(f) == "dead")
> +
> +
> +-- yields in tail calls
> +local function foo (i) return coroutine.yield(i) end
> +f = coroutine.wrap(function ()
> +  for i=1,10 do
> +    assert(foo(i) == _G.x)
> +  end
> +  return 'a'
> +end)
> +for i=1,10 do _G.x = i; assert(f(i) == i) end
> +_G.x = 'xuxu'; assert(f('xuxu') == 'a')
> +
> +-- recursive
> +function pf (n, i)
> +  coroutine.yield(n)
> +  pf(n*i, i+1)
> +end
> +
> +f = coroutine.wrap(pf)
> +local s=1
> +for i=1,10 do
> +  assert(f(1, 1) == s)
> +  s = s*i
> +end
> +
> +-- sieve
> +function gen (n)
> +  return coroutine.wrap(function ()
> +    for i=2,n do coroutine.yield(i) end
> +  end)
> +end
> +
> +
> +function filter (p, g)
> +  return coroutine.wrap(function ()
> +    while 1 do
> +      local n = g()
> +      if n == nil then return end
> +      if math.mod(n, p) ~= 0 then coroutine.yield(n) end
> +    end
> +  end)
> +end
> +
> +local x = gen(100)
> +local a = {}
> +while 1 do
> +  local n = x()
> +  if n == nil then break end
> +  table.insert(a, n)
> +  x = filter(n, x)
> +end
> +
> +assert(table.getn(a) == 25 and a[table.getn(a)] == 97)
> +
> +
> +-- errors in coroutines
> +function foo ()
> +  assert(debug.getinfo(1).currentline == debug.getinfo(foo).linedefined + 1)
> +  assert(debug.getinfo(2).currentline == debug.getinfo(goo).linedefined)
> +  coroutine.yield(3)
> +  error(foo)
> +end
> +
> +function goo() foo() end
> +x = coroutine.wrap(goo)
> +assert(x() == 3)
> +local a,b = pcall(x)
> +assert(not a and b == foo)
> +
> +x = coroutine.create(goo)
> +a,b = coroutine.resume(x)
> +assert(a and b == 3)
> +a,b = coroutine.resume(x)
> +assert(not a and b == foo and coroutine.status(x) == "dead")
> +a,b = coroutine.resume(x)
> +assert(not a and string.find(b, "dead") and coroutine.status(x) == "dead")
> +
> +
> +-- co-routines x for loop
> +function all (a, n, k)
> +  if k == 0 then coroutine.yield(a)
> +  else
> +    for i=1,n do
> +      a[k] = i
> +      all(a, n, k-1)
> +    end
> +  end
> +end
> +
> +local a = 0
> +for t in coroutine.wrap(function () all({}, 5, 4) end) do
> +  a = a+1
> +end
> +assert(a == 5^4)
> +
> +
> +-- access to locals of collected corroutines
> +local C = {}; setmetatable(C, {__mode = "kv"})
> +local x = coroutine.wrap (function ()
> +            local a = 10
> +            local function f () a = a+10; return a end
> +            while true do
> +              a = a+1
> +              coroutine.yield(f)
> +            end
> +          end)
> +
> +C[1] = x;
> +
> +local f = x()
> +assert(f() == 21 and x()() == 32 and x() == f)
> +x = nil
> +collectgarbage()
> +assert(C[1] == nil)
> +assert(f() == 43 and f() == 53)
> +
> +
> +-- old bug: attempt to resume itself
> +
> +function co_func (current_co)
> +  assert(coroutine.running() == current_co)
> +  assert(coroutine.resume(current_co) == false)
> +  assert(coroutine.resume(current_co) == false)
> +  return 10
> +end
> +
> +local co = coroutine.create(co_func)
> +local a,b = coroutine.resume(co, co)
> +assert(a == true and b == 10)
> +assert(coroutine.resume(co, co) == false)
> +assert(coroutine.resume(co, co) == false)
> +
> +-- access to locals of erroneous coroutines
> +local x = coroutine.create (function ()
> +            local a = 10
> +            _G.f = function () a=a+1; return a end
> +            error('x')
> +          end)
> +
> +assert(not coroutine.resume(x))
> +-- overwrite previous position of local `a'
> +assert(not coroutine.resume(x, 1, 1, 1, 1, 1, 1, 1))
> +assert(_G.f() == 11)
> +assert(_G.f() == 12)
> +
> +
> +if not T then
> +  (Message or print)('\a\n >>> testC not active: skipping yield/hook tests <<<\n\a')
> +else
> +
> +  local turn
> +
> +  function fact (t, x)
> +    assert(turn == t)
> +    if x == 0 then return 1
> +    else return x*fact(t, x-1)
> +    end
> +  end
> +
> +  local A,B,a,b = 0,0,0,0
> +
> +  local x = coroutine.create(function ()
> +    T.setyhook("", 2)
> +    A = fact("A", 10)
> +  end)
> +
> +  local y = coroutine.create(function ()
> +    T.setyhook("", 3)
> +    B = fact("B", 11)
> +  end)
> +
> +  while A==0 or B==0 do
> +    if A==0 then turn = "A"; T.resume(x) end
> +    if B==0 then turn = "B"; T.resume(y) end
> +  end
> +
> +  assert(B/A == 11)
> +end
> +
> +
> +-- leaving a pending coroutine open
> +_X = coroutine.wrap(function ()
> +      local a = 10
> +      local x = function () a = a+1 end
> +      coroutine.yield()
> +    end)
> +
> +_X()
> +
> +
> +-- coroutine environments
> +co = coroutine.create(function ()
> +       coroutine.yield(getfenv(0))
> +       return loadstring("return a")()
> +     end)
> +
> +a = {a = 15}
> +debug.setfenv(co, a)
> +assert(debug.getfenv(co) == a)
> +assert(select(2, coroutine.resume(co)) == a)
> +assert(select(2, coroutine.resume(co)) == a.a)
> +
> +
> +print'OK'
> diff --git a/test/PUC-Lua-5.1-tests/code.lua b/test/PUC-Lua-5.1-tests/code.lua
> new file mode 100644
> index 0000000..875d488
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/code.lua
> @@ -0,0 +1,143 @@
> +
> +if T==nil then
> +  (Message or print)('\a\n >>> testC not active: skipping opcode tests <<<\n\a')
> +  return
> +end
> +print "testing code generation and optimizations"
> +
> +
> +-- this code gave an error for the code checker
> +do
> +  local function f (a)
> +  for k,v,w in a do end
> +  end
> +end
> +
> +
> +function check (f, ...)
> +  local c = T.listcode(f)
> +  for i=1, arg.n do
> +    -- print(arg[i], c[i])
> +    assert(string.find(c[i], '- '..arg[i]..' *%d'))
> +  end
> +  assert(c[arg.n+2] == nil)
> +end
> +
> +
> +function checkequal (a, b)
> +  a = T.listcode(a)
> +  b = T.listcode(b)
> +  for i = 1, table.getn(a) do
> +    a[i] = string.gsub(a[i], '%b()', '')   -- remove line number
> +    b[i] = string.gsub(b[i], '%b()', '')   -- remove line number
> +    assert(a[i] == b[i])
> +  end
> +end
> +
> +
> +-- some basic instructions
> +check(function ()
> +  (function () end){f()}
> +end, 'CLOSURE', 'NEWTABLE', 'GETGLOBAL', 'CALL', 'SETLIST', 'CALL', 'RETURN')
> +
> +
> +-- sequence of LOADNILs
> +check(function ()
> +  local a,b,c
> +  local d; local e;
> +  a = nil; d=nil
> +end, 'RETURN')
> +
> +
> +-- single return
> +check (function (a,b,c) return a end, 'RETURN')
> +
> +
> +-- infinite loops
> +check(function () while true do local a = -1 end end,
> +'LOADK', 'JMP', 'RETURN')
> +
> +check(function () while 1 do local a = -1 end end,
> +'LOADK', 'JMP', 'RETURN')
> +
> +check(function () repeat local x = 1 until false end,
> +'LOADK', 'JMP', 'RETURN')
> +
> +check(function () repeat local x until nil end,
> +'LOADNIL', 'JMP', 'RETURN')
> +
> +check(function () repeat local x = 1 until true end,
> +'LOADK', 'RETURN')
> +
> +
> +-- concat optimization
> +check(function (a,b,c,d) return a..b..c..d end,
> +  'MOVE', 'MOVE', 'MOVE', 'MOVE', 'CONCAT', 'RETURN')
> +
> +-- not
> +check(function () return not not nil end, 'LOADBOOL', 'RETURN')
> +check(function () return not not false end, 'LOADBOOL', 'RETURN')
> +check(function () return not not true end, 'LOADBOOL', 'RETURN')
> +check(function () return not not 1 end, 'LOADBOOL', 'RETURN')
> +
> +-- direct access to locals
> +check(function ()
> +  local a,b,c,d
> +  a = b*2
> +  c[4], a[b] = -((a + d/-20.5 - a[b]) ^ a.x), b
> +end,
> +  'MUL',
> +  'DIV', 'ADD', 'GETTABLE', 'SUB', 'GETTABLE', 'POW',
> +    'UNM', 'SETTABLE', 'SETTABLE', 'RETURN')
> +
> +
> +-- direct access to constants
> +check(function ()
> +  local a,b
> +  a.x = 0
> +  a.x = b
> +  a[b] = 'y'
> +  a = 1 - a
> +  b = 1/a
> +  b = 5+4
> +  a[true] = false
> +end,
> +  'SETTABLE', 'SETTABLE', 'SETTABLE', 'SUB', 'DIV', 'LOADK',
> +  'SETTABLE', 'RETURN')
> +
> +local function f () return -((2^8 + -(-1)) % 8)/2 * 4 - 3 end
> +
> +check(f, 'LOADK', 'RETURN')
> +assert(f() == -5)
> +
> +check(function ()
> +  local a,b,c
> +  b[c], a = c, b
> +  b[a], a = c, b
> +  a, b = c, a
> +  a = a
> +end,
> +  'MOVE', 'MOVE', 'SETTABLE',
> +  'MOVE', 'MOVE', 'MOVE', 'SETTABLE',
> +  'MOVE', 'MOVE', 'MOVE',
> +  -- no code for a = a
> +  'RETURN')
> +
> +
> +-- x == nil , x ~= nil
> +checkequal(function () if (a==nil) then a=1 end; if a~=nil then a=1 end end,
> +           function () if (a==9) then a=1 end; if a~=9 then a=1 end end)
> +
> +check(function () if a==nil then a=1 end end,
> +'GETGLOBAL', 'EQ', 'JMP', 'LOADK', 'SETGLOBAL', 'RETURN')
> +
> +-- de morgan
> +checkequal(function () local a; if not (a or b) then b=a end end,
> +           function () local a; if (not a and not b) then b=a end end)
> +
> +checkequal(function (l) local a; return 0 <= a and a <= l end,
> +           function (l) local a; return not (not(a >= 0) or not(a <= l)) end)
> +
> +
> +print 'OK'
> +
> diff --git a/test/PUC-Lua-5.1-tests/constructs.lua b/test/PUC-Lua-5.1-tests/constructs.lua
> new file mode 100644
> index 0000000..5fb3798
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/constructs.lua
> @@ -0,0 +1,240 @@
> +print "testing syntax"
> +
> +-- testing priorities
> +
> +assert(2^3^2 == 2^(3^2));
> +assert(2^3*4 == (2^3)*4);
> +assert(2^-2 == 1/4 and -2^- -2 == - - -4);
> +assert(not nil and 2 and not(2>3 or 3<2));
> +assert(-3-1-5 == 0+0-9);
> +assert(-2^2 == -4 and (-2)^2 == 4 and 2*2-3-1 == 0);
> +assert(2*1+3/3 == 3 and 1+2 .. 3*1 == "33");
> +assert(not(2+1 > 3*1) and "a".."b" > "a");
> +
> +assert(not ((true or false) and nil))
> +assert(      true or false  and nil)
> +
> +local a,b = 1,nil;
> +assert(-(1 or 2) == -1 and (1 and 2)+(-1.25 or -4) == 0.75);
> +x = ((b or a)+1 == 2 and (10 or a)+1 == 11); assert(x);
> +x = (((2<3) or 1) == true and (2<3 and 4) == 4); assert(x);
> +
> +x,y=1,2;
> +assert((x>y) and x or y == 2);
> +x,y=2,1;
> +assert((x>y) and x or y == 2);
> +
> +assert(1234567890 == tonumber('1234567890') and 1234567890+1 == 1234567891)
> +
> +
> +-- silly loops
> +repeat until 1; repeat until true;
> +while false do end; while nil do end;
> +
> +do  -- test old bug (first name could not be an `upvalue')
> + local a; function f(x) x={a=1}; x={x=1}; x={G=1} end
> +end
> +
> +function f (i)
> +  if type(i) ~= 'number' then return i,'jojo'; end;
> +  if i > 0 then return i, f(i-1); end;
> +end
> +
> +x = {f(3), f(5), f(10);};
> +assert(x[1] == 3 and x[2] == 5 and x[3] == 10 and x[4] == 9 and x[12] == 1);
> +assert(x[nil] == nil)
> +x = {f'alo', f'xixi', nil};
> +assert(x[1] == 'alo' and x[2] == 'xixi' and x[3] == nil);
> +x = {f'alo'..'xixi'};
> +assert(x[1] == 'aloxixi')
> +x = {f{}}
> +assert(x[2] == 'jojo' and type(x[1]) == 'table')
> +
> +
> +local f = function (i)
> +  if i < 10 then return 'a';
> +  elseif i < 20 then return 'b';
> +  elseif i < 30 then return 'c';
> +  end;
> +end
> +
> +assert(f(3) == 'a' and f(12) == 'b' and f(26) == 'c' and f(100) == nil)
> +
> +for i=1,1000 do break; end;
> +n=100;
> +i=3;
> +t = {};
> +a=nil
> +while not a do
> +  a=0; for i=1,n do for i=i,1,-1 do a=a+1; t[i]=1; end; end;
> +end
> +assert(a == n*(n+1)/2 and i==3);
> +assert(t[1] and t[n] and not t[0] and not t[n+1])
> +
> +function f(b)
> +  local x = 1;
> +  repeat
> +    local a;
> +    if b==1 then local b=1; x=10; break
> +    elseif b==2 then x=20; break;
> +    elseif b==3 then x=30;
> +    else local a,b,c,d=math.sin(1); x=x+1;
> +    end
> +  until x>=12;
> +  return x;
> +end;
> +
> +assert(f(1) == 10 and f(2) == 20 and f(3) == 30 and f(4)==12)
> +
> +
> +local f = function (i)
> +  if i < 10 then return 'a'
> +  elseif i < 20 then return 'b'
> +  elseif i < 30 then return 'c'
> +  else return 8
> +  end
> +end
> +
> +assert(f(3) == 'a' and f(12) == 'b' and f(26) == 'c' and f(100) == 8)
> +
> +local a, b = nil, 23
> +x = {f(100)*2+3 or a, a or b+2}
> +assert(x[1] == 19 and x[2] == 25)
> +x = {f=2+3 or a, a = b+2}
> +assert(x.f == 5 and x.a == 25)
> +
> +a={y=1}
> +x = {a.y}
> +assert(x[1] == 1)
> +
> +function f(i)
> +  while 1 do
> +    if i>0 then i=i-1;
> +    else return; end;
> +  end;
> +end;
> +
> +function g(i)
> +  while 1 do
> +    if i>0 then i=i-1
> +    else return end
> +  end
> +end
> +
> +f(10); g(10);
> +
> +do
> +  function f () return 1,2,3; end
> +  local a, b, c = f();
> +  assert(a==1 and b==2 and c==3)
> +  a, b, c = (f());
> +  assert(a==1 and b==nil and c==nil)
> +end
> +
> +local a,b = 3 and f();
> +assert(a==1 and b==nil)
> +
> +function g() f(); return; end;
> +assert(g() == nil)
> +function g() return nil or f() end
> +a,b = g()
> +assert(a==1 and b==nil)
> +
> +print'+';
> +
> +
> +f = [[
> +return function ( a , b , c , d , e )
> +  local x = a >= b or c or ( d and e ) or nil
> +  return x
> +end , { a = 1 , b = 2 >= 1 , } or { 1 };
> +]]
> +f = string.gsub(f, "%s+", "\n");   -- force a SETLINE between opcodes
> +f,a = loadstring(f)();
> +assert(a.a == 1 and a.b)
> +
> +function g (a,b,c,d,e)
> +  if not (a>=b or c or d and e or nil) then return 0; else return 1; end;
> +end
> +
> +function h (a,b,c,d,e)
> +  while (a>=b or c or (d and e) or nil) do return 1; end;
> +  return 0;
> +end;
> +
> +assert(f(2,1) == true and g(2,1) == 1 and h(2,1) == 1)
> +assert(f(1,2,'a') == 'a' and g(1,2,'a') == 1 and h(1,2,'a') == 1)
> +assert(f(1,2,'a')
> +~=          -- force SETLINE before nil
> +nil, "")
> +assert(f(1,2,'a') == 'a' and g(1,2,'a') == 1 and h(1,2,'a') == 1)
> +assert(f(1,2,nil,1,'x') == 'x' and g(1,2,nil,1,'x') == 1 and
> +                                   h(1,2,nil,1,'x') == 1)
> +assert(f(1,2,nil,nil,'x') == nil and g(1,2,nil,nil,'x') == 0 and
> +                                     h(1,2,nil,nil,'x') == 0)
> +assert(f(1,2,nil,1,nil) == nil and g(1,2,nil,1,nil) == 0 and
> +                                   h(1,2,nil,1,nil) == 0)
> +
> +assert(1 and 2<3 == true and 2<3 and 'a'<'b' == true)
> +x = 2<3 and not 3; assert(x==false)
> +x = 2<1 or (2>1 and 'a'); assert(x=='a')
> +
> +
> +do
> +  local a; if nil then a=1; else a=2; end;    -- this nil comes as PUSHNIL 2
> +  assert(a==2)
> +end
> +
> +function F(a)
> +  assert(debug.getinfo(1, "n").name == 'F')
> +  return a,2,3
> +end
> +
> +a,b = F(1)~=nil; assert(a == true and b == nil);
> +a,b = F(nil)==nil; assert(a == true and b == nil)
> +
> +----------------------------------------------------------------
> +-- creates all combinations of
> +-- [not] ([not] arg op [not] (arg op [not] arg ))
> +-- and tests each one
> +
> +function ID(x) return x end
> +
> +function f(t, i)
> +  local b = t.n
> +  local res = math.mod(math.floor(i/c), b)+1
> +  c = c*b
> +  return t[res]
> +end
> +
> +local arg = {" ( 1 < 2 ) ", " ( 1 >= 2 ) ", " F ( ) ", "  nil "; n=4}
> +
> +local op = {" and ", " or ", " == ", " ~= "; n=4}
> +
> +local neg = {" ", " not "; n=2}
> +
> +local i = 0
> +repeat
> +  c = 1
> +  local s = f(neg, i)..'ID('..f(neg, i)..f(arg, i)..f(op, i)..
> +            f(neg, i)..'ID('..f(arg, i)..f(op, i)..f(neg, i)..f(arg, i)..'))'
> +  local s1 = string.gsub(s, 'ID', '')
> +  K,X,NX,WX1,WX2 = nil
> +  s = string.format([[
> +      local a = %s
> +      local b = not %s
> +      K = b
> +      local xxx;
> +      if %s then X = a  else X = b end
> +      if %s then NX = b  else NX = a end
> +      while %s do WX1 = a; break end
> +      while %s do WX2 = a; break end
> +      repeat if (%s) then break end; assert(b)  until not(%s)
> +  ]], s1, s, s1, s, s1, s, s1, s, s)
> +  assert(loadstring(s))()
> +  assert(X and not NX and not WX1 == K and not WX2 == K)
> +  if math.mod(i,4000) == 0 then print('+') end
> +  i = i+1
> +until i==c
> +
> +print'OK'
> diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua
> new file mode 100644
> index 0000000..9d2c86f
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/db.lua
> @@ -0,0 +1,499 @@
> +-- testing debug library
> +
> +local function dostring(s) return assert(loadstring(s))() end
> +
> +print"testing debug library and debug information"
> +
> +do
> +local a=1
> +end
> +
> +function test (s, l, p)
> +  collectgarbage()   -- avoid gc during trace
> +  local function f (event, line)
> +    assert(event == 'line')
> +    local l = table.remove(l, 1)
> +    if p then print(l, line) end
> +    assert(l == line, "wrong trace!!")
> +  end
> +  debug.sethook(f,"l"); loadstring(s)(); debug.sethook()
> +  assert(table.getn(l) == 0)
> +end
> +
> +
> +do
> +  local a = debug.getinfo(print)
> +  assert(a.what == "C" and a.short_src == "[C]")
> +  local b = debug.getinfo(test, "SfL")
> +  assert(b.name == nil and b.what == "Lua" and b.linedefined == 11 and
> +         b.lastlinedefined == b.linedefined + 10 and
> +         b.func == test and not string.find(b.short_src, "%["))
> +  assert(b.activelines[b.linedefined + 1] and
> +         b.activelines[b.lastlinedefined])
> +  assert(not b.activelines[b.linedefined] and
> +         not b.activelines[b.lastlinedefined + 1])
> +end
> +
> +
> +-- test file and string names truncation
> +a = "function f () end"
> +local function dostring (s, x) return loadstring(s, x)() end
> +dostring(a)
> +assert(debug.getinfo(f).short_src == string.format('[string "%s"]', a))
> +dostring(a..string.format("; %s\n=1", string.rep('p', 400)))
> +assert(string.find(debug.getinfo(f).short_src, '^%[string [^\n]*%.%.%."%]$'))
> +dostring("\n"..a)
> +assert(debug.getinfo(f).short_src == '[string "..."]')
> +dostring(a, "")
> +assert(debug.getinfo(f).short_src == '[string ""]')
> +dostring(a, "@xuxu")
> +assert(debug.getinfo(f).short_src == "xuxu")
> +dostring(a, "@"..string.rep('p', 1000)..'t')
> +assert(string.find(debug.getinfo(f).short_src, "^%.%.%.p*t$"))
> +dostring(a, "=xuxu")
> +assert(debug.getinfo(f).short_src == "xuxu")
> +dostring(a, string.format("=%s", string.rep('x', 500)))
> +assert(string.find(debug.getinfo(f).short_src, "^x*"))
> +dostring(a, "=")
> +assert(debug.getinfo(f).short_src == "")
> +a = nil; f = nil;
> +
> +
> +repeat
> +  local g = {x = function ()
> +    local a = debug.getinfo(2)
> +    assert(a.name == 'f' and a.namewhat == 'local')
> +    a = debug.getinfo(1)
> +    assert(a.name == 'x' and a.namewhat == 'field')
> +    return 'xixi'
> +  end}
> +  local f = function () return 1+1 and (not 1 or g.x()) end
> +  assert(f() == 'xixi')
> +  g = debug.getinfo(f)
> +  assert(g.what == "Lua" and g.func == f and g.namewhat == "" and not g.name)
> +
> +  function f (x, name)   -- local!
> +    name = name or 'f'
> +    local a = debug.getinfo(1)
> +    assert(a.name == name and a.namewhat == 'local')
> +    return x
> +  end
> +
> +  -- breaks in different conditions
> +  if 3>4 then break end; f()
> +  if 3<4 then a=1 else break end; f()
> +  while 1 do local x=10; break end; f()
> +  local b = 1
> +  if 3>4 then return math.sin(1) end; f()
> +  a = 3<4; f()
> +  a = 3<4 or 1; f()
> +  repeat local x=20; if 4>3 then f() else break end; f() until 1
> +  g = {}
> +  f(g).x = f(2) and f(10)+f(9)
> +  assert(g.x == f(19))
> +  function g(x) if not x then return 3 end return (x('a', 'x')) end
> +  assert(g(f) == 'a')
> +until 1
> +
> +test([[if
> +math.sin(1)
> +then
> +  a=1
> +else
> +  a=2
> +end
> +]], {2,4,7})
> +
> +test([[--
> +if nil then
> +  a=1
> +else
> +  a=2
> +end
> +]], {2,5,6})
> +
> +test([[a=1
> +repeat
> +  a=a+1
> +until a==3
> +]], {1,3,4,3,4})
> +
> +test([[ do
> +  return
> +end
> +]], {2})
> +
> +test([[local a
> +a=1
> +while a<=3 do
> +  a=a+1
> +end
> +]], {2,3,4,3,4,3,4,3,5})
> +
> +test([[while math.sin(1) do
> +  if math.sin(1)
> +  then
> +    break
> +  end
> +end
> +a=1]], {1,2,4,7})
> +
> +test([[for i=1,3 do
> +  a=i
> +end
> +]], {1,2,1,2,1,2,1,3})
> +
> +test([[for i,v in pairs{'a','b'} do
> +  a=i..v
> +end
> +]], {1,2,1,2,1,3})
> +
> +test([[for i=1,4 do a=1 end]], {1,1,1,1,1})
> +
> +
> +
> +print'+'
> +
> +a = {}; L = nil
> +local glob = 1
> +local oldglob = glob
> +debug.sethook(function (e,l)
> +  collectgarbage()   -- force GC during a hook
> +  local f, m, c = debug.gethook()
> +  assert(m == 'crl' and c == 0)
> +  if e == "line" then
> +    if glob ~= oldglob then
> +      L = l-1   -- get the first line where "glob" has changed
> +      oldglob = glob
> +    end
> +  elseif e == "call" then
> +      local f = debug.getinfo(2, "f").func
> +      a[f] = 1
> +  else assert(e == "return")
> +  end
> +end, "crl")
> +
> +function f(a,b)
> +  collectgarbage()
> +  local _, x = debug.getlocal(1, 1)
> +  local _, y = debug.getlocal(1, 2)
> +  assert(x == a and y == b)
> +  assert(debug.setlocal(2, 3, "pera") == "AA".."AA")
> +  assert(debug.setlocal(2, 4, "ma��") == "B")
> +  x = debug.getinfo(2)
> +  assert(x.func == g and x.what == "Lua" and x.name == 'g' and
> +         x.nups == 0 and string.find(x.source, "^@.*db%.lua"))
> +  glob = glob+1
> +  assert(debug.getinfo(1, "l").currentline == L+1)
> +  assert(debug.getinfo(1, "l").currentline == L+2)
> +end
> +
> +function foo()
> +  glob = glob+1
> +  assert(debug.getinfo(1, "l").currentline == L+1)
> +end; foo()  -- set L
> +-- check line counting inside strings and empty lines
> +
> +_ = 'alo\
> +alo' .. [[
> +
> +]]
> +--[[
> +]]
> +assert(debug.getinfo(1, "l").currentline == L+11)  -- check count of lines
> +
> +
> +function g(...)
> +  do local a,b,c; a=math.sin(40); end
> +  local feijao
> +  local AAAA,B = "xuxu", "mam�o"
> +  f(AAAA,B)
> +  assert(AAAA == "pera" and B == "ma��")
> +  do
> +     local B = 13
> +     local x,y = debug.getlocal(1,5)
> +     assert(x == 'B' and y == 13)
> +  end
> +end
> +
> +g()
> +
> +
> +assert(a[f] and a[g] and a[assert] and a[debug.getlocal] and not a[print])
> +
> +
> +-- tests for manipulating non-registered locals (C and Lua temporaries)
> +
> +local n, v = debug.getlocal(0, 1)
> +assert(v == 0 and n == "(*temporary)")
> +local n, v = debug.getlocal(0, 2)
> +assert(v == 2 and n == "(*temporary)")
> +assert(not debug.getlocal(0, 3))
> +assert(not debug.getlocal(0, 0))
> +
> +function f()
> +  assert(select(2, debug.getlocal(2,3)) == 1)
> +  assert(not debug.getlocal(2,4))
> +  debug.setlocal(2, 3, 10)
> +  return 20
> +end
> +
> +function g(a,b) return (a+1) + f() end
> +
> +assert(g(0,0) == 30)
> +
> +
> +debug.sethook(nil);
> +assert(debug.gethook() == nil)
> +
> +
> +-- testing access to function arguments
> +
> +X = nil
> +a = {}
> +function a:f (a, b, ...) local c = 13 end
> +debug.sethook(function (e)
> +  assert(e == "call")
> +  dostring("XX = 12")  -- test dostring inside hooks
> +  -- testing errors inside hooks
> +  assert(not pcall(loadstring("a='joao'+1")))
> +  debug.sethook(function (e, l)
> +    assert(debug.getinfo(2, "l").currentline == l)
> +    local f,m,c = debug.gethook()
> +    assert(e == "line")
> +    assert(m == 'l' and c == 0)
> +    debug.sethook(nil)  -- hook is called only once
> +    assert(not X)       -- check that
> +    X = {}; local i = 1
> +    local x,y
> +    while 1 do
> +      x,y = debug.getlocal(2, i)
> +      if x==nil then break end
> +      X[x] = y
> +      i = i+1
> +    end
> +  end, "l")
> +end, "c")
> +
> +a:f(1,2,3,4,5)
> +assert(X.self == a and X.a == 1   and X.b == 2 and X.arg.n == 3 and X.c == nil)
> +assert(XX == 12)
> +assert(debug.gethook() == nil)
> +
> +
> +-- testing upvalue access
> +local function getupvalues (f)
> +  local t = {}
> +  local i = 1
> +  while true do
> +    local name, value = debug.getupvalue(f, i)
> +    if not name then break end
> +    assert(not t[name])
> +    t[name] = value
> +    i = i + 1
> +  end
> +  return t
> +end
> +
> +local a,b,c = 1,2,3
> +local function foo1 (a) b = a; return c end
> +local function foo2 (x) a = x; return c+b end
> +assert(debug.getupvalue(foo1, 3) == nil)
> +assert(debug.getupvalue(foo1, 0) == nil)
> +assert(debug.setupvalue(foo1, 3, "xuxu") == nil)
> +local t = getupvalues(foo1)
> +assert(t.a == nil and t.b == 2 and t.c == 3)
> +t = getupvalues(foo2)
> +assert(t.a == 1 and t.b == 2 and t.c == 3)
> +assert(debug.setupvalue(foo1, 1, "xuxu") == "b")
> +assert(({debug.getupvalue(foo2, 3)})[2] == "xuxu")
> +-- cannot manipulate C upvalues from Lua
> +assert(debug.getupvalue(io.read, 1) == nil)
> +assert(debug.setupvalue(io.read, 1, 10) == nil)
> +
> +
> +-- testing count hooks
> +local a=0
> +debug.sethook(function (e) a=a+1 end, "", 1)
> +a=0; for i=1,1000 do end; assert(1000 < a and a < 1012)
> +debug.sethook(function (e) a=a+1 end, "", 4)
> +a=0; for i=1,1000 do end; assert(250 < a and a < 255)
> +local f,m,c = debug.gethook()
> +assert(m == "" and c == 4)
> +debug.sethook(function (e) a=a+1 end, "", 4000)
> +a=0; for i=1,1000 do end; assert(a == 0)
> +debug.sethook(print, "", 2^24 - 1)   -- count upperbound
> +local f,m,c = debug.gethook()
> +assert(({debug.gethook()})[3] == 2^24 - 1)
> +debug.sethook()
> +
> +
> +-- tests for tail calls
> +local function f (x)
> +  if x then
> +    assert(debug.getinfo(1, "S").what == "Lua")
> +    local tail = debug.getinfo(2)
> +    assert(not pcall(getfenv, 3))
> +    assert(tail.what == "tail" and tail.short_src == "(tail call)" and
> +           tail.linedefined == -1 and tail.func == nil)
> +    assert(debug.getinfo(3, "f").func == g1)
> +    assert(getfenv(3))
> +    assert(debug.getinfo(4, "S").what == "tail")
> +    assert(not pcall(getfenv, 5))
> +    assert(debug.getinfo(5, "S").what == "main")
> +    assert(getfenv(5))
> +    print"+"
> +    end
> +end
> +
> +function g(x) return f(x) end
> +
> +function g1(x) g(x) end
> +
> +local function h (x) local f=g1; return f(x) end
> +
> +h(true)
> +
> +local b = {}
> +debug.sethook(function (e) table.insert(b, e) end, "cr")
> +h(false)
> +debug.sethook()
> +local res = {"return",   -- first return (from sethook)
> +  "call", "call", "call", "call",
> +  "return", "tail return", "return", "tail return",
> +  "call",    -- last call (to sethook)
> +}
> +for _, k in ipairs(res) do assert(k == table.remove(b, 1)) end
> +
> +
> +lim = 30000
> +local function foo (x)
> +  if x==0 then
> +    assert(debug.getinfo(lim+2).what == "main")
> +    for i=2,lim do assert(debug.getinfo(i, "S").what == "tail") end
> +  else return foo(x-1)
> +  end
> +end
> +
> +foo(lim)
> +
> +
> +print"+"
> +
> +
> +-- testing traceback
> +
> +assert(debug.traceback(print) == print)
> +assert(debug.traceback(print, 4) == print)
> +assert(string.find(debug.traceback("hi", 4), "^hi\n"))
> +assert(string.find(debug.traceback("hi"), "^hi\n"))
> +assert(not string.find(debug.traceback("hi"), "'traceback'"))
> +assert(string.find(debug.traceback("hi", 0), "'traceback'"))
> +assert(string.find(debug.traceback(), "^stack traceback:\n"))
> +
> +-- testing debugging of coroutines
> +
> +local function checktraceback (co, p)
> +  local tb = debug.traceback(co)
> +  local i = 0
> +  for l in string.gmatch(tb, "[^\n]+\n?") do
> +    assert(i == 0 or string.find(l, p[i]))
> +    i = i+1
> +  end
> +  assert(p[i] == nil)
> +end
> +
> +
> +local function f (n)
> +  if n > 0 then return f(n-1)
> +  else coroutine.yield() end
> +end
> +
> +local co = coroutine.create(f)
> +coroutine.resume(co, 3)
> +checktraceback(co, {"yield", "db.lua", "tail", "tail", "tail"})
> +
> +
> +co = coroutine.create(function (x)
> +       local a = 1
> +       coroutine.yield(debug.getinfo(1, "l"))
> +       coroutine.yield(debug.getinfo(1, "l").currentline)
> +       return a
> +     end)
> +
> +local tr = {}
> +local foo = function (e, l) table.insert(tr, l) end
> +debug.sethook(co, foo, "l")
> +
> +local _, l = coroutine.resume(co, 10)
> +local x = debug.getinfo(co, 1, "lfLS")
> +assert(x.currentline == l.currentline and x.activelines[x.currentline])
> +assert(type(x.func) == "function")
> +for i=x.linedefined + 1, x.lastlinedefined do
> +  assert(x.activelines[i])
> +  x.activelines[i] = nil
> +end
> +assert(next(x.activelines) == nil)   -- no 'extra' elements
> +assert(debug.getinfo(co, 2) == nil)
> +local a,b = debug.getlocal(co, 1, 1)
> +assert(a == "x" and b == 10)
> +a,b = debug.getlocal(co, 1, 2)
> +assert(a == "a" and b == 1)
> +debug.setlocal(co, 1, 2, "hi")
> +assert(debug.gethook(co) == foo)
> +assert(table.getn(tr) == 2 and
> +       tr[1] == l.currentline-1 and tr[2] == l.currentline)
> +
> +a,b,c = pcall(coroutine.resume, co)
> +assert(a and b and c == l.currentline+1)
> +checktraceback(co, {"yield", "in function <"})
> +
> +a,b = coroutine.resume(co)
> +assert(a and b == "hi")
> +assert(table.getn(tr) == 4 and tr[4] == l.currentline+2)
> +assert(debug.gethook(co) == foo)
> +assert(debug.gethook() == nil)
> +checktraceback(co, {})
> +
> +
> +-- check traceback of suspended (or dead with error) coroutines
> +
> +function f(i) if i==0 then error(i) else coroutine.yield(); f(i-1) end end
> +
> +co = coroutine.create(function (x) f(x) end)
> +a, b = coroutine.resume(co, 3)
> +t = {"'yield'", "'f'", "in function <"}
> +while coroutine.status(co) == "suspended" do
> +  checktraceback(co, t)
> +  a, b = coroutine.resume(co)
> +  table.insert(t, 2, "'f'")   -- one more recursive call to 'f'
> +end
> +t[1] = "'error'"
> +checktraceback(co, t)
> +
> +
> +-- test acessing line numbers of a coroutine from a resume inside
> +-- a C function (this is a known bug in Lua 5.0)
> +
> +local function g(x)
> +    coroutine.yield(x)
> +end
> +
> +local function f (i)
> +  debug.sethook(function () end, "l")
> +  for j=1,1000 do
> +    g(i+j)
> +  end
> +end
> +
> +local co = coroutine.wrap(f)
> +co(10)
> +pcall(co)
> +pcall(co)
> +
> +
> +assert(type(debug.getregistry()) == "table")
> +
> +
> +print"OK"
> +
> diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua
> new file mode 100644
> index 0000000..e881211
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/errors.lua
> @@ -0,0 +1,250 @@
> +print("testing errors")
> +
> +function doit (s)
> +  local f, msg = loadstring(s)
> +  if f == nil then return msg end
> +  local cond, msg = pcall(f)
> +  return (not cond) and msg
> +end
> +
> +
> +function checkmessage (prog, msg)
> +  assert(string.find(doit(prog), msg, 1, true))
> +end
> +
> +function checksyntax (prog, extra, token, line)
> +  local msg = doit(prog)
> +  token = string.gsub(token, "(%p)", "%%%1")
> +  local pt = string.format([[^%%[string ".*"%%]:%d: .- near '%s'$]],
> +                           line, token)
> +  assert(string.find(msg, pt))
> +  assert(string.find(msg, msg, 1, true))
> +end
> +
> +
> +-- test error message with no extra info
> +assert(doit("error('hi', 0)") == 'hi')
> +
> +-- test error message with no info
> +assert(doit("error()") == nil)
> +
> +
> +-- test common errors/errors that crashed in the past
> +assert(doit("unpack({}, 1, n=2^30)"))
> +assert(doit("a=math.sin()"))
> +assert(not doit("tostring(1)") and doit("tostring()"))
> +assert(doit"tonumber()")
> +assert(doit"repeat until 1; a")
> +checksyntax("break label", "", "label", 1)
> +assert(doit";")
> +assert(doit"a=1;;")
> +assert(doit"return;;")
> +assert(doit"assert(false)")
> +assert(doit"assert(nil)")
> +assert(doit"a=math.sin\n(3)")
> +assert(doit("function a (... , ...) end"))
> +assert(doit("function a (, ...) end"))
> +
> +checksyntax([[
> +  local a = {4
> +
> +]], "'}' expected (to close '{' at line 1)", "<eof>", 3)
> +
> +
> +-- tests for better error messages
> +
> +checkmessage("a=1; bbbb=2; a=math.sin(3)+bbbb(3)", "global 'bbbb'")
> +checkmessage("a=1; local a,bbbb=2,3; a = math.sin(1) and bbbb(3)",
> +       "local 'bbbb'")
> +checkmessage("a={}; do local a=1 end a:bbbb(3)", "method 'bbbb'")
> +checkmessage("local a={}; a.bbbb(3)", "field 'bbbb'")
> +assert(not string.find(doit"a={13}; local bbbb=1; a[bbbb](3)", "'bbbb'"))
> +checkmessage("a={13}; local bbbb=1; a[bbbb](3)", "number")
> +
> +aaa = nil
> +checkmessage("aaa.bbb:ddd(9)", "global 'aaa'")
> +checkmessage("local aaa={bbb=1}; aaa.bbb:ddd(9)", "field 'bbb'")
> +checkmessage("local aaa={bbb={}}; aaa.bbb:ddd(9)", "method 'ddd'")
> +checkmessage("local a,b,c; (function () a = b+1 end)()", "upvalue 'b'")
> +assert(not doit"local aaa={bbb={ddd=next}}; aaa.bbb:ddd(nil)")
> +
> +checkmessage("b=1; local aaa='a'; x=aaa+b", "local 'aaa'")
> +checkmessage("aaa={}; x=3/aaa", "global 'aaa'")
> +checkmessage("aaa='2'; b=nil;x=aaa*b", "global 'b'")
> +checkmessage("aaa={}; x=-aaa", "global 'aaa'")
> +assert(not string.find(doit"aaa={}; x=(aaa or aaa)+(aaa and aaa)", "'aaa'"))
> +assert(not string.find(doit"aaa={}; (aaa or aaa)()", "'aaa'"))
> +
> +checkmessage([[aaa=9
> +repeat until 3==3
> +local x=math.sin(math.cos(3))
> +if math.sin(1) == x then return math.sin(1) end   -- tail call
> +local a,b = 1, {
> +  {x='a'..'b'..'c', y='b', z=x},
> +  {1,2,3,4,5} or 3+3<=3+3,
> +  3+1>3+1,
> +  {d = x and aaa[x or y]}}
> +]], "global 'aaa'")
> +
> +checkmessage([[
> +local x,y = {},1
> +if math.sin(1) == 0 then return 3 end    -- return
> +x.a()]], "field 'a'")
> +
> +checkmessage([[
> +prefix = nil
> +insert = nil
> +while 1 do
> +  local a
> +  if nil then break end
> +  insert(prefix, a)
> +end]], "global 'insert'")
> +
> +checkmessage([[  -- tail call
> +  return math.sin("a")
> +]], "'sin'")
> +
> +checkmessage([[collectgarbage("nooption")]], "invalid option")
> +
> +checkmessage([[x = print .. "a"]], "concatenate")
> +
> +checkmessage("getmetatable(io.stdin).__gc()", "no value")
> +
> +print'+'
> +
> +
> +-- testing line error
> +
> +function lineerror (s)
> +  local err,msg = pcall(loadstring(s))
> +  local line = string.match(msg, ":(%d+):")
> +  return line and line+0
> +end
> +
> +assert(lineerror"local a\n for i=1,'a' do \n print(i) \n end" == 2)
> +assert(lineerror"\n local a \n for k,v in 3 \n do \n print(k) \n end" == 3)
> +assert(lineerror"\n\n for k,v in \n 3 \n do \n print(k) \n end" == 4)
> +assert(lineerror"function a.x.y ()\na=a+1\nend" == 1)
> +
> +local p = [[
> +function g() f() end
> +function f(x) error('a', X) end
> +g()
> +]]
> +X=3;assert(lineerror(p) == 3)
> +X=0;assert(lineerror(p) == nil)
> +X=1;assert(lineerror(p) == 2)
> +X=2;assert(lineerror(p) == 1)
> +
> +lineerror = nil
> +
> +C = 0
> +local l = debug.getinfo(1, "l").currentline; function y () C=C+1; y() end
> +
> +local function checkstackmessage (m)
> +  return (string.find(m, "^.-:%d+: stack overflow"))
> +end
> +assert(checkstackmessage(doit('y()')))
> +assert(checkstackmessage(doit('y()')))
> +assert(checkstackmessage(doit('y()')))
> +-- teste de linhas em erro
> +C = 0
> +local l1
> +local function g()
> +  l1 = debug.getinfo(1, "l").currentline; y()
> +end
> +local _, stackmsg = xpcall(g, debug.traceback)
> +local stack = {}
> +for line in string.gmatch(stackmsg, "[^\n]*") do
> +  local curr = string.match(line, ":(%d+):")
> +  if curr then table.insert(stack, tonumber(curr)) end
> +end
> +local i=1
> +while stack[i] ~= l1 do
> +  assert(stack[i] == l)
> +  i = i+1
> +end
> +assert(i > 15)
> +
> +
> +-- error in error handling
> +local res, msg = xpcall(error, error)
> +assert(not res and type(msg) == 'string')
> +
> +local function f (x)
> +  if x==0 then error('a\n')
> +  else
> +    local aux = function () return f(x-1) end
> +    local a,b = xpcall(aux, aux)
> +    return a,b
> +  end
> +end
> +f(3)
> +
> +-- non string messages
> +function f() error{msg='x'} end
> +res, msg = xpcall(f, function (r) return {msg=r.msg..'y'} end)
> +assert(msg.msg == 'xy')
> +
> +print('+')
> +checksyntax("syntax error", "", "error", 1)
> +checksyntax("1.000", "", "1.000", 1)
> +checksyntax("[[a]]", "", "[[a]]", 1)
> +checksyntax("'aa'", "", "'aa'", 1)
> +
> +-- test 255 as first char in a chunk
> +checksyntax("\255a = 1", "", "\255", 1)
> +
> +doit('I = loadstring("a=9+"); a=3')
> +assert(a==3 and I == nil)
> +print('+')
> +
> +lim = 1000
> +if rawget(_G, "_soft") then lim = 100 end
> +for i=1,lim do
> +  doit('a = ')
> +  doit('a = 4+nil')
> +end
> +
> +
> +-- testing syntax limits
> +local function testrep (init, rep)
> +  local s = "local a; "..init .. string.rep(rep, 400)
> +  local a,b = loadstring(s)
> +  assert(not a and string.find(b, "syntax levels"))
> +end
> +testrep("a=", "{")
> +testrep("a=", "(")
> +testrep("", "a(")
> +testrep("", "do ")
> +testrep("", "while a do ")
> +testrep("", "if a then else ")
> +testrep("", "function foo () ")
> +testrep("a=", "a..")
> +testrep("a=", "a^")
> +
> +
> +-- testing other limits
> +-- upvalues
> +local  s = "function foo ()\n  local "
> +for j = 1,70 do
> +  s = s.."a"..j..", "
> +end
> +s = s.."b\n"
> +for j = 1,70 do
> +  s = s.."function foo"..j.." ()\n a"..j.."=3\n"
> +end
> +local a,b = loadstring(s)
> +assert(string.find(b, "line 3"))
> +
> +-- local variables
> +s = "\nfunction foo ()\n  local "
> +for j = 1,300 do
> +  s = s.."a"..j..", "
> +end
> +s = s.."b\n"
> +local a,b = loadstring(s)
> +assert(string.find(b, "line 2"))
> +
> +
> +print('OK')
> diff --git a/test/PUC-Lua-5.1-tests/etc/ltests.c b/test/PUC-Lua-5.1-tests/etc/ltests.c
> new file mode 100644
> index 0000000..be949e5
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/etc/ltests.c
> @@ -0,0 +1,1147 @@
> +/*
> +** $Id: ltests.c,v 2.36 2006/01/10 13:13:06 roberto Exp $
> +** Internal Module for Debugging of the Lua Implementation
> +** See Copyright Notice in lua.h
> +*/
> +
> +
> +#include <ctype.h>
> +#include <limits.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +
> +#define ltests_c
> +#define LUA_CORE
> +
> +#include "lua.h"
> +
> +#include "lapi.h"
> +#include "lauxlib.h"
> +#include "lcode.h"
> +#include "ldebug.h"
> +#include "ldo.h"
> +#include "lfunc.h"
> +#include "lmem.h"
> +#include "lopcodes.h"
> +#include "lstate.h"
> +#include "lstring.h"
> +#include "ltable.h"
> +#include "lualib.h"
> +
> +
> +
> +/*
> +** The whole module only makes sense with LUA_DEBUG on
> +*/
> +#if defined(LUA_DEBUG)
> +
> +
> +int Trick = 0;
> +
> +
> +static lua_State *lua_state = NULL;
> +
> +int islocked = 0;
> +
> +
> +#define obj_at(L,k)	(L->ci->base+(k) - 1)
> +
> +
> +static void setnameval (lua_State *L, const char *name, int val) {
> +  lua_pushstring(L, name);
> +  lua_pushinteger(L, val);
> +  lua_settable(L, -3);
> +}
> +
> +
> +/*
> +** {======================================================================
> +** Controlled version for realloc.
> +** =======================================================================
> +*/
> +
> +#define MARK		0x55  /* 01010101 (a nice pattern) */
> +
> +#ifndef EXTERNMEMCHECK
> +/* full memory check */
> +#define HEADER	(sizeof(L_Umaxalign)) /* ensures maximum alignment for HEADER */
> +#define MARKSIZE	16  /* size of marks after each block */
> +#define blockhead(b)	(cast(char *, b) - HEADER)
> +#define setsize(newblock, size)	(*cast(size_t *, newblock) = size)
> +#define checkblocksize(b, size) (size == (*cast(size_t *, blockhead(b))))
> +#define fillmem(mem,size)	memset(mem, -MARK, size)
> +#else
> +/* external memory check: don't do it twice */
> +#define HEADER		0
> +#define MARKSIZE	0
> +#define blockhead(b)	(b)
> +#define setsize(newblock, size)	/* empty */
> +#define checkblocksize(b,size)	(1)
> +#define fillmem(mem,size)	/* empty */
> +#endif
> +
> +
> +Memcontrol memcontrol = {0L, 0L, 0L, ULONG_MAX};
> +
> +
> +static void *checkblock (void *block, size_t size) {
> +  void *b = blockhead(block);
> +  int i;
> +  for (i=0;i<MARKSIZE;i++)
> +    lua_assert(*(cast(char *, b)+HEADER+size+i) == MARK+i); /* corrupted block? */
> +  return b;
> +}
> +
> +
> +static void freeblock (Memcontrol *mc, void *block, size_t size) {
> +  if (block) {
> +    lua_assert(checkblocksize(block, size));
> +    block = checkblock(block, size);
> +    fillmem(block, size+HEADER+MARKSIZE);  /* erase block */
> +    free(block);  /* free original block */
> +    mc->numblocks--;
> +    mc->total -= size;
> +  }
> +}
> +
> +
> +void *debug_realloc (void *ud, void *block, size_t oldsize, size_t size) {
> +  Memcontrol *mc = cast(Memcontrol *, ud);
> +  lua_assert(oldsize == 0 || checkblocksize(block, oldsize));
> +  if (size == 0) {
> +    freeblock(mc, block, oldsize);
> +    return NULL;
> +  }
> +  else if (size > oldsize && mc->total+size-oldsize > mc->memlimit)
> +    return NULL;  /* to test memory allocation errors */
> +  else {
> +    void *newblock;
> +    int i;
> +    size_t realsize = HEADER+size+MARKSIZE;
> +    size_t commonsize = (oldsize < size) ? oldsize : size;
> +    if (realsize < size) return NULL;  /* overflow! */
> +    newblock = malloc(realsize);  /* alloc a new block */
> +    if (newblock == NULL) return NULL;
> +    if (block) {
> +      memcpy(cast(char *, newblock)+HEADER, block, commonsize);
> +      freeblock(mc, block, oldsize);  /* erase (and check) old copy */
> +    }
> +    /* initialize new part of the block with something `weird' */
> +    fillmem(cast(char *, newblock)+HEADER+commonsize, size-commonsize);
> +    mc->total += size;
> +    if (mc->total > mc->maxmem)
> +      mc->maxmem = mc->total;
> +    mc->numblocks++;
> +    setsize(newblock, size);
> +    for (i=0;i<MARKSIZE;i++)
> +      *(cast(char *, newblock)+HEADER+size+i) = cast(char, MARK+i);
> +    return cast(char *, newblock)+HEADER;
> +  }
> +}
> +
> +
> +/* }====================================================================== */
> +
> +
> +
> +/*
> +** {======================================================
> +** Functions to check memory consistency
> +** =======================================================
> +*/
> +
> +static int testobjref1 (global_State *g, GCObject *f, GCObject *t) {
> +  if (isdead(g,t)) return 0;
> +  if (g->gcstate == GCSpropagate)
> +    return !isblack(f) || !iswhite(t);
> +  else if (g->gcstate == GCSfinalize)
> +    return iswhite(f);
> +  else
> +    return 1;
> +}
> +
> +
> +static void printobj (global_State *g, GCObject *o) {
> +  int i = 0;
> +  GCObject *p;
> +  for (p = g->rootgc; p != o && p != NULL; p = p->gch.next) i++;
> +  if (p == NULL) i = -1;
> +  printf("%d:%s(%p)-%c(%02X)", i, luaT_typenames[o->gch.tt], (void *)o,
> +           isdead(g,o)?'d':isblack(o)?'b':iswhite(o)?'w':'g', o->gch.marked);
> +}
> +
> +
> +static int testobjref (global_State *g, GCObject *f, GCObject *t) {
> +  int r = testobjref1(g,f,t);
> +  if (!r) {
> +    printf("%d(%02X) - ", g->gcstate, g->currentwhite);
> +    printobj(g, f);
> +    printf("\t-> ");
> +    printobj(g, t);
> +    printf("\n");
> +  }
> +  return r;
> +}
> +
> +#define checkobjref(g,f,t) lua_assert(testobjref(g,f,obj2gco(t)))
> +
> +#define checkvalref(g,f,t) lua_assert(!iscollectable(t) || \
> +	((ttype(t) == (t)->value.gc->gch.tt) && testobjref(g,f,gcvalue(t))))
> +
> +
> +
> +static void checktable (global_State *g, Table *h) {
> +  int i;
> +  int weakkey = 0;
> +  int weakvalue = 0;
> +  const TValue *mode;
> +  GCObject *hgc = obj2gco(h);
> +  if (h->metatable)
> +    checkobjref(g, hgc, h->metatable);
> +  mode = gfasttm(g, h->metatable, TM_MODE);
> +  if (mode && ttisstring(mode)) {  /* is there a weak mode? */
> +    weakkey = (strchr(svalue(mode), 'k') != NULL);
> +    weakvalue = (strchr(svalue(mode), 'v') != NULL);
> +  }
> +  i = h->sizearray;
> +  while (i--)
> +    checkvalref(g, hgc, &h->array[i]);
> +  i = sizenode(h);
> +  while (i--) {
> +    Node *n = gnode(h, i);
> +    if (!ttisnil(gval(n))) {
> +      lua_assert(!ttisnil(gkey(n)));
> +      checkvalref(g, hgc, gkey(n));
> +      checkvalref(g, hgc, gval(n));
> +    }
> +  }
> +}
> +
> +
> +/*
> +** All marks are conditional because a GC may happen while the
> +** prototype is still being created
> +*/
> +static void checkproto (global_State *g, Proto *f) {
> +  int i;
> +  GCObject *fgc = obj2gco(f);
> +  if (f->source) checkobjref(g, fgc, f->source);
> +  for (i=0; i<f->sizek; i++) {
> +    if (ttisstring(f->k+i))
> +      checkobjref(g, fgc, rawtsvalue(f->k+i));
> +  }
> +  for (i=0; i<f->sizeupvalues; i++) {
> +    if (f->upvalues[i])
> +      checkobjref(g, fgc, f->upvalues[i]);
> +  }
> +  for (i=0; i<f->sizep; i++) {
> +    if (f->p[i])
> +      checkobjref(g, fgc, f->p[i]);
> +  }
> +  for (i=0; i<f->sizelocvars; i++) {
> +    if (f->locvars[i].varname)
> +      checkobjref(g, fgc, f->locvars[i].varname);
> +  }
> +}
> +
> +
> +
> +static void checkclosure (global_State *g, Closure *cl) {
> +  GCObject *clgc = obj2gco(cl);
> +  checkobjref(g, clgc, cl->l.env);
> +  if (cl->c.isC) {
> +    int i;
> +    for (i=0; i<cl->c.nupvalues; i++)
> +      checkvalref(g, clgc, &cl->c.upvalue[i]);
> +  }
> +  else {
> +    int i;
> +    lua_assert(cl->l.nupvalues == cl->l.p->nups);
> +    checkobjref(g, clgc, cl->l.p);
> +    for (i=0; i<cl->l.nupvalues; i++) {
> +      if (cl->l.upvals[i]) {
> +        lua_assert(cl->l.upvals[i]->tt == LUA_TUPVAL);
> +        checkobjref(g, clgc, cl->l.upvals[i]);
> +      }
> +    }
> +  }
> +}
> +
> +
> +static void checkstack (global_State *g, lua_State *L1) {
> +  StkId o;
> +  CallInfo *ci;
> +  GCObject *uvo;
> +  lua_assert(!isdead(g, obj2gco(L1)));
> +  for (uvo = L1->openupval; uvo != NULL; uvo = uvo->gch.next) {
> +    UpVal *uv = gco2uv(uvo);
> +    lua_assert(uv->v != &uv->u.value);  /* must be open */
> +    lua_assert(!isblack(uvo));  /* open upvalues cannot be black */
> +  }
> +  checkliveness(g, gt(L1));
> +  if (L1->base_ci) {
> +    for (ci = L1->base_ci; ci <= L1->ci; ci++) {
> +      lua_assert(ci->top <= L1->stack_last);
> +      lua_assert(lua_checkpc(L1, ci));
> +    }
> +  }
> +  else lua_assert(L1->size_ci == 0);
> +  if (L1->stack) {
> +    for (o = L1->stack; o < L1->top; o++)
> +      checkliveness(g, o);
> +  }
> +  else lua_assert(L1->stacksize == 0);
> +}
> +
> +
> +static void checkobject (global_State *g, GCObject *o) {
> +  if (isdead(g, o))
> +/*    lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep);*/
> +{ if (!(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep))
> +printf(">>> %d  %s  %02x\n", g->gcstate, luaT_typenames[o->gch.tt], o->gch.marked);
> +}
> +  else {
> +    if (g->gcstate == GCSfinalize)
> +      lua_assert(iswhite(o));
> +    switch (o->gch.tt) {
> +      case LUA_TUPVAL: {
> +        UpVal *uv = gco2uv(o);
> +        lua_assert(uv->v == &uv->u.value);  /* must be closed */
> +        lua_assert(!isgray(o));  /* closed upvalues are never gray */
> +        checkvalref(g, o, uv->v);
> +        break;
> +      }
> +      case LUA_TUSERDATA: {
> +        Table *mt = gco2u(o)->metatable;
> +        if (mt) checkobjref(g, o, mt);
> +        break;
> +      }
> +      case LUA_TTABLE: {
> +        checktable(g, gco2h(o));
> +        break;
> +      }
> +      case LUA_TTHREAD: {
> +        checkstack(g, gco2th(o));
> +        break;
> +      }
> +      case LUA_TFUNCTION: {
> +        checkclosure(g, gco2cl(o));
> +        break;
> +      }
> +      case LUA_TPROTO: {
> +        checkproto(g, gco2p(o));
> +        break;
> +      }
> +      default: lua_assert(0);
> +    }
> +  }
> +}
> +
> +
> +int lua_checkpc (lua_State *L, pCallInfo ci) {
> +  if (ci == L->base_ci || !f_isLua(ci)) return 1;
> +  else {
> +    Proto *p = ci_func(ci)->l.p;
> +    if (ci < L->ci)
> +      return p->code <= ci->savedpc && ci->savedpc <= p->code + p->sizecode;
> +    else
> +      return p->code <= L->savedpc && L->savedpc <= p->code + p->sizecode;
> +  }
> +}
> +
> +
> +int lua_checkmemory (lua_State *L) {
> +  global_State *g = G(L);
> +  GCObject *o;
> +  UpVal *uv;
> +  checkstack(g, g->mainthread);
> +  for (o = g->rootgc; o != obj2gco(g->mainthread); o = o->gch.next)
> +    checkobject(g, o);
> +  for (o = o->gch.next; o != NULL; o = o->gch.next) {
> +    lua_assert(o->gch.tt == LUA_TUSERDATA);
> +    checkobject(g, o);
> +  }
> +  for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) {
> +    lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
> +    lua_assert(uv->v != &uv->u.value);  /* must be open */
> +    lua_assert(!isblack(obj2gco(uv)));  /* open upvalues are never black */
> +    checkvalref(g, obj2gco(uv), uv->v);
> +  }
> +  return 0;
> +}
> +
> +/* }====================================================== */
> +
> +
> +
> +/*
> +** {======================================================
> +** Disassembler
> +** =======================================================
> +*/
> +
> +
> +static char *buildop (Proto *p, int pc, char *buff) {
> +  Instruction i = p->code[pc];
> +  OpCode o = GET_OPCODE(i);
> +  const char *name = luaP_opnames[o];
> +  int line = getline(p, pc);
> +  sprintf(buff, "(%4d) %4d - ", line, pc);
> +  switch (getOpMode(o)) {
> +    case iABC:
> +      sprintf(buff+strlen(buff), "%-12s%4d %4d %4d", name,
> +              GETARG_A(i), GETARG_B(i), GETARG_C(i));
> +      break;
> +    case iABx:
> +      sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_Bx(i));
> +      break;
> +    case iAsBx:
> +      sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_sBx(i));
> +      break;
> +  }
> +  return buff;
> +}
> +
> +
> +#if 0
> +void luaI_printcode (Proto *pt, int size) {
> +  int pc;
> +  for (pc=0; pc<size; pc++) {
> +    char buff[100];
> +    printf("%s\n", buildop(pt, pc, buff));
> +  }
> +  printf("-------\n");
> +}
> +#endif
> +
> +
> +static int listcode (lua_State *L) {
> +  int pc;
> +  Proto *p;
> +  luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
> +                 1, "Lua function expected");
> +  p = clvalue(obj_at(L, 1))->l.p;
> +  lua_newtable(L);
> +  setnameval(L, "maxstack", p->maxstacksize);
> +  setnameval(L, "numparams", p->numparams);
> +  for (pc=0; pc<p->sizecode; pc++) {
> +    char buff[100];
> +    lua_pushinteger(L, pc+1);
> +    lua_pushstring(L, buildop(p, pc, buff));
> +    lua_settable(L, -3);
> +  }
> +  return 1;
> +}
> +
> +
> +static int listk (lua_State *L) {
> +  Proto *p;
> +  int i;
> +  luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
> +                 1, "Lua function expected");
> +  p = clvalue(obj_at(L, 1))->l.p;
> +  lua_createtable(L, p->sizek, 0);
> +  for (i=0; i<p->sizek; i++) {
> +    luaA_pushobject(L, p->k+i);
> +    lua_rawseti(L, -2, i+1);
> +  }
> +  return 1;
> +}
> +
> +
> +static int listlocals (lua_State *L) {
> +  Proto *p;
> +  int pc = luaL_checkint(L, 2) - 1;
> +  int i = 0;
> +  const char *name;
> +  luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
> +                 1, "Lua function expected");
> +  p = clvalue(obj_at(L, 1))->l.p;
> +  while ((name = luaF_getlocalname(p, ++i, pc)) != NULL)
> +    lua_pushstring(L, name);
> +  return i-1;
> +}
> +
> +/* }====================================================== */
> +
> +
> +
> +
> +static int get_limits (lua_State *L) {
> +  lua_createtable(L, 0, 5);
> +  setnameval(L, "BITS_INT", LUAI_BITSINT);
> +  setnameval(L, "LFPF", LFIELDS_PER_FLUSH);
> +  setnameval(L, "MAXVARS", LUAI_MAXVARS);
> +  setnameval(L, "MAXSTACK", MAXSTACK);
> +  setnameval(L, "MAXUPVALUES", LUAI_MAXUPVALUES);
> +  setnameval(L, "NUM_OPCODES", NUM_OPCODES);
> +  return 1;
> +}
> +
> +
> +static int mem_query (lua_State *L) {
> +  if (lua_isnone(L, 1)) {
> +    lua_pushinteger(L, memcontrol.total);
> +    lua_pushinteger(L, memcontrol.numblocks);
> +    lua_pushinteger(L, memcontrol.maxmem);
> +    return 3;
> +  }
> +  else {
> +    memcontrol.memlimit = luaL_checkint(L, 1);
> +    return 0;
> +  }
> +}
> +
> +
> +static int settrick (lua_State *L) {
> +  Trick = lua_tointeger(L, 1);
> +  return 0;
> +}
> +
> +
> +/*static int set_gcstate (lua_State *L) {
> +  static const char *const state[] = {"propagate", "sweep", "finalize"};
> +  return 0;
> +}*/
> +
> +
> +static int get_gccolor (lua_State *L) {
> +  TValue *o;
> +  luaL_checkany(L, 1);
> +  o = obj_at(L, 1);
> +  if (!iscollectable(o))
> +    lua_pushstring(L, "no collectable");
> +  else
> +    lua_pushstring(L, iswhite(gcvalue(o)) ? "white" :
> +                      isblack(gcvalue(o)) ? "black" : "grey");
> +  return 1;
> +}
> +
> +
> +static int gcstate (lua_State *L) {
> +  switch(G(L)->gcstate) {
> +    case GCSpropagate: lua_pushstring(L, "propagate"); break;
> +    case GCSsweepstring: lua_pushstring(L, "sweep strings"); break;
> +    case GCSsweep: lua_pushstring(L, "sweep"); break;
> +    case GCSfinalize: lua_pushstring(L, "finalize"); break;
> +  }
> +  return 1;
> +}
> +
> +
> +static int hash_query (lua_State *L) {
> +  if (lua_isnone(L, 2)) {
> +    luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "string expected");
> +    lua_pushinteger(L, tsvalue(obj_at(L, 1))->hash);
> +  }
> +  else {
> +    TValue *o = obj_at(L, 1);
> +    Table *t;
> +    luaL_checktype(L, 2, LUA_TTABLE);
> +    t = hvalue(obj_at(L, 2));
> +    lua_pushinteger(L, luaH_mainposition(t, o) - t->node);
> +  }
> +  return 1;
> +}
> +
> +
> +static int stacklevel (lua_State *L) {
> +  unsigned long a = 0;
> +  lua_pushinteger(L, (L->top - L->stack));
> +  lua_pushinteger(L, (L->stack_last - L->stack));
> +  lua_pushinteger(L, (L->ci - L->base_ci));
> +  lua_pushinteger(L, (L->end_ci - L->base_ci));
> +  lua_pushinteger(L, (unsigned long)&a);
> +  return 5;
> +}
> +
> +
> +static int table_query (lua_State *L) {
> +  const Table *t;
> +  int i = luaL_optint(L, 2, -1);
> +  luaL_checktype(L, 1, LUA_TTABLE);
> +  t = hvalue(obj_at(L, 1));
> +  if (i == -1) {
> +    lua_pushinteger(L, t->sizearray);
> +    lua_pushinteger(L, luaH_isdummy(t->node) ? 0 : sizenode(t));
> +    lua_pushinteger(L, t->lastfree - t->node);
> +  }
> +  else if (i < t->sizearray) {
> +    lua_pushinteger(L, i);
> +    luaA_pushobject(L, &t->array[i]);
> +    lua_pushnil(L);
> +  }
> +  else if ((i -= t->sizearray) < sizenode(t)) {
> +    if (!ttisnil(gval(gnode(t, i))) ||
> +        ttisnil(gkey(gnode(t, i))) ||
> +        ttisnumber(gkey(gnode(t, i)))) {
> +      luaA_pushobject(L, key2tval(gnode(t, i)));
> +    }
> +    else
> +      lua_pushliteral(L, "<undef>");
> +    luaA_pushobject(L, gval(gnode(t, i)));
> +    if (gnext(&t->node[i]))
> +      lua_pushinteger(L, gnext(&t->node[i]) - t->node);
> +    else
> +      lua_pushnil(L);
> +  }
> +  return 3;
> +}
> +
> +
> +static int string_query (lua_State *L) {
> +  stringtable *tb = &G(L)->strt;
> +  int s = luaL_optint(L, 2, 0) - 1;
> +  if (s==-1) {
> +    lua_pushinteger(L ,tb->nuse);
> +    lua_pushinteger(L ,tb->size);
> +    return 2;
> +  }
> +  else if (s < tb->size) {
> +    GCObject *ts;
> +    int n = 0;
> +    for (ts = tb->hash[s]; ts; ts = ts->gch.next) {
> +      setsvalue2s(L, L->top, gco2ts(ts));
> +      incr_top(L);
> +      n++;
> +    }
> +    return n;
> +  }
> +  return 0;
> +}
> +
> +
> +static int tref (lua_State *L) {
> +  int level = lua_gettop(L);
> +  int lock = luaL_optint(L, 2, 1);
> +  luaL_checkany(L, 1);
> +  lua_pushvalue(L, 1);
> +  lua_pushinteger(L, lua_ref(L, lock));
> +  lua_assert(lua_gettop(L) == level+1);  /* +1 for result */
> +  return 1;
> +}
> +
> +static int getref (lua_State *L) {
> +  int level = lua_gettop(L);
> +  lua_getref(L, luaL_checkint(L, 1));
> +  lua_assert(lua_gettop(L) == level+1);
> +  return 1;
> +}
> +
> +static int unref (lua_State *L) {
> +  int level = lua_gettop(L);
> +  lua_unref(L, luaL_checkint(L, 1));
> +  lua_assert(lua_gettop(L) == level);
> +  return 0;
> +}
> +
> +
> +static int upvalue (lua_State *L) {
> +  int n = luaL_checkint(L, 2);
> +  luaL_checktype(L, 1, LUA_TFUNCTION);
> +  if (lua_isnone(L, 3)) {
> +    const char *name = lua_getupvalue(L, 1, n);
> +    if (name == NULL) return 0;
> +    lua_pushstring(L, name);
> +    return 2;
> +  }
> +  else {
> +    const char *name = lua_setupvalue(L, 1, n);
> +    lua_pushstring(L, name);
> +    return 1;
> +  }
> +}
> +
> +
> +static int newuserdata (lua_State *L) {
> +  size_t size = luaL_checkint(L, 1);
> +  char *p = cast(char *, lua_newuserdata(L, size));
> +  while (size--) *p++ = '\0';
> +  return 1;
> +}
> +
> +
> +static int pushuserdata (lua_State *L) {
> +  lua_pushlightuserdata(L, cast(void *, luaL_checkint(L, 1)));
> +  return 1;
> +}
> +
> +
> +static int udataval (lua_State *L) {
> +  lua_pushinteger(L, cast(long, lua_touserdata(L, 1)));
> +  return 1;
> +}
> +
> +
> +static int doonnewstack (lua_State *L) {
> +  lua_State *L1 = lua_newthread(L);
> +  size_t l;
> +  const char *s = luaL_checklstring(L, 1, &l);
> +  int status = luaL_loadbuffer(L1, s, l, s);
> +  if (status == 0)
> +    status = lua_pcall(L1, 0, 0, 0);
> +  lua_pushinteger(L, status);
> +  return 1;
> +}
> +
> +
> +static int s2d (lua_State *L) {
> +  lua_pushnumber(L, *cast(const double *, luaL_checkstring(L, 1)));
> +  return 1;
> +}
> +
> +
> +static int d2s (lua_State *L) {
> +  double d = luaL_checknumber(L, 1);
> +  lua_pushlstring(L, cast(char *, &d), sizeof(d));
> +  return 1;
> +}
> +
> +
> +static int num2int (lua_State *L) {
> +  lua_pushinteger(L, lua_tointeger(L, 1));
> +  return 1;
> +}
> +
> +
> +static int newstate (lua_State *L) {
> +  void *ud;
> +  lua_Alloc f = lua_getallocf(L, &ud);
> +  lua_State *L1 = lua_newstate(f, ud);
> +  if (L1)
> +    lua_pushinteger(L, (unsigned long)L1);
> +  else
> +    lua_pushnil(L);
> +  return 1;
> +}
> +
> +
> +static int loadlib (lua_State *L) {
> +  static const luaL_Reg libs[] = {
> +    {"baselibopen", luaopen_base},
> +    {"dblibopen", luaopen_debug},
> +    {"iolibopen", luaopen_io},
> +    {"mathlibopen", luaopen_math},
> +    {"strlibopen", luaopen_string},
> +    {"tablibopen", luaopen_table},
> +    {"packageopen", luaopen_package},
> +    {NULL, NULL}
> +  };
> +  lua_State *L1 = cast(lua_State *,
> +                       cast(unsigned long, luaL_checknumber(L, 1)));
> +  lua_pushvalue(L1, LUA_GLOBALSINDEX);
> +  luaL_register(L1, NULL, libs);
> +  return 0;
> +}
> +
> +static int closestate (lua_State *L) {
> +  lua_State *L1 = cast(lua_State *, cast(unsigned long, luaL_checknumber(L, 1)));
> +  lua_close(L1);
> +  return 0;
> +}
> +
> +static int doremote (lua_State *L) {
> +  lua_State *L1 = cast(lua_State *,cast(unsigned long,luaL_checknumber(L, 1)));
> +  size_t lcode;
> +  const char *code = luaL_checklstring(L, 2, &lcode);
> +  int status;
> +  lua_settop(L1, 0);
> +  status = luaL_loadbuffer(L1, code, lcode, code);
> +  if (status == 0)
> +    status = lua_pcall(L1, 0, LUA_MULTRET, 0);
> +  if (status != 0) {
> +    lua_pushnil(L);
> +    lua_pushinteger(L, status);
> +    lua_pushstring(L, lua_tostring(L1, -1));
> +    return 3;
> +  }
> +  else {
> +    int i = 0;
> +    while (!lua_isnone(L1, ++i))
> +      lua_pushstring(L, lua_tostring(L1, i));
> +    lua_pop(L1, i-1);
> +    return i-1;
> +  }
> +}
> +
> +
> +static int log2_aux (lua_State *L) {
> +  lua_pushinteger(L, luaO_log2(luaL_checkint(L, 1)));
> +  return 1;
> +}
> +
> +static int int2fb_aux (lua_State *L) {
> +  int b = luaO_int2fb(luaL_checkint(L, 1));
> +  lua_pushinteger(L, b);
> +  lua_pushinteger(L, luaO_fb2int(b));
> +  return 2;
> +}
> +
> +
> +
> +/*
> +** {======================================================
> +** function to test the API with C. It interprets a kind of assembler
> +** language with calls to the API, so the test can be driven by Lua code
> +** =======================================================
> +*/
> +
> +static const char *const delimits = " \t\n,;";
> +
> +static void skip (const char **pc) {
> +  while (**pc != '\0' && strchr(delimits, **pc)) (*pc)++;
> +}
> +
> +static int getnum_aux (lua_State *L, const char **pc) {
> +  int res = 0;
> +  int sig = 1;
> +  skip(pc);
> +  if (**pc == '.') {
> +    res = cast_int(lua_tonumber(L, -1));
> +    lua_pop(L, 1);
> +    (*pc)++;
> +    return res;
> +  }
> +  else if (**pc == '-') {
> +    sig = -1;
> +    (*pc)++;
> +  }
> +  while (isdigit(cast_int(**pc))) res = res*10 + (*(*pc)++) - '0';
> +  return sig*res;
> +}
> +
> +static const char *getname_aux (char *buff, const char **pc) {
> +  int i = 0;
> +  skip(pc);
> +  while (**pc != '\0' && !strchr(delimits, **pc))
> +    buff[i++] = *(*pc)++;
> +  buff[i] = '\0';
> +  return buff;
> +}
> +
> +
> +static int getindex_aux (lua_State *L, const char **pc) {
> +  skip(pc);
> +  switch (*(*pc)++) {
> +    case 'R': return LUA_REGISTRYINDEX;
> +    case 'G': return LUA_GLOBALSINDEX;
> +    case 'E': return LUA_ENVIRONINDEX;
> +    case 'U': return lua_upvalueindex(getnum_aux(L, pc));
> +    default: (*pc)--; return getnum_aux(L, pc);
> +  }
> +}
> +
> +#define EQ(s1)	(strcmp(s1, inst) == 0)
> +
> +#define getnum	(getnum_aux(L, &pc))
> +#define getname	(getname_aux(buff, &pc))
> +#define getindex (getindex_aux(L, &pc))
> +
> +
> +static int testC (lua_State *L) {
> +  char buff[30];
> +  lua_State *L1;
> +  const char *pc;
> +  if (lua_isnumber(L, 1)) {
> +    L1 = cast(lua_State *,cast(unsigned long,luaL_checknumber(L, 1)));
> +    pc = luaL_checkstring(L, 2);
> +  }
> +  else {
> +    L1 = L;
> +    pc = luaL_checkstring(L, 1);
> +  }
> +  for (;;) {
> +    const char *inst = getname;
> +    if EQ("") return 0;
> +    else if EQ("isnumber") {
> +      lua_pushinteger(L1, lua_isnumber(L1, getindex));
> +    }
> +    else if EQ("isstring") {
> +      lua_pushinteger(L1, lua_isstring(L1, getindex));
> +    }
> +    else if EQ("istable") {
> +      lua_pushinteger(L1, lua_istable(L1, getindex));
> +    }
> +    else if EQ("iscfunction") {
> +      lua_pushinteger(L1, lua_iscfunction(L1, getindex));
> +    }
> +    else if EQ("isfunction") {
> +      lua_pushinteger(L1, lua_isfunction(L1, getindex));
> +    }
> +    else if EQ("isuserdata") {
> +      lua_pushinteger(L1, lua_isuserdata(L1, getindex));
> +    }
> +    else if EQ("isudataval") {
> +      lua_pushinteger(L1, lua_islightuserdata(L1, getindex));
> +    }
> +    else if EQ("isnil") {
> +      lua_pushinteger(L1, lua_isnil(L1, getindex));
> +    }
> +    else if EQ("isnull") {
> +      lua_pushinteger(L1, lua_isnone(L1, getindex));
> +    }
> +    else if EQ("tonumber") {
> +      lua_pushnumber(L1, lua_tonumber(L1, getindex));
> +    }
> +    else if EQ("tostring") {
> +      const char *s = lua_tostring(L1, getindex);
> +      lua_pushstring(L1, s);
> +    }
> +    else if EQ("objsize") {
> +      lua_pushinteger(L1, lua_objlen(L1, getindex));
> +    }
> +    else if EQ("tocfunction") {
> +      lua_pushcfunction(L1, lua_tocfunction(L1, getindex));
> +    }
> +    else if EQ("return") {
> +      return getnum;
> +    }
> +    else if EQ("gettop") {
> +      lua_pushinteger(L1, lua_gettop(L1));
> +    }
> +    else if EQ("settop") {
> +      lua_settop(L1, getnum);
> +    }
> +    else if EQ("pop") {
> +      lua_pop(L1, getnum);
> +    }
> +    else if EQ("pushnum") {
> +      lua_pushinteger(L1, getnum);
> +    }
> +    else if EQ("pushstring") {
> +      lua_pushstring(L1, getname);
> +    }
> +    else if EQ("pushnil") {
> +      lua_pushnil(L1);
> +    }
> +    else if EQ("pushbool") {
> +      lua_pushboolean(L1, getnum);
> +    }
> +    else if EQ("newuserdata") {
> +      lua_newuserdata(L1, getnum);
> +    }
> +    else if EQ("tobool") {
> +      lua_pushinteger(L1, lua_toboolean(L1, getindex));
> +    }
> +    else if EQ("pushvalue") {
> +      lua_pushvalue(L1, getindex);
> +    }
> +    else if EQ("pushcclosure") {
> +      lua_pushcclosure(L1, testC, getnum);
> +    }
> +    else if EQ("remove") {
> +      lua_remove(L1, getnum);
> +    }
> +    else if EQ("insert") {
> +      lua_insert(L1, getnum);
> +    }
> +    else if EQ("replace") {
> +      lua_replace(L1, getindex);
> +    }
> +    else if EQ("gettable") {
> +      lua_gettable(L1, getindex);
> +    }
> +    else if EQ("settable") {
> +      lua_settable(L1, getindex);
> +    }
> +    else if EQ("next") {
> +      lua_next(L1, -2);
> +    }
> +    else if EQ("concat") {
> +      lua_concat(L1, getnum);
> +    }
> +    else if EQ("lessthan") {
> +      int a = getindex;
> +      lua_pushboolean(L1, lua_lessthan(L1, a, getindex));
> +    }
> +    else if EQ("equal") {
> +      int a = getindex;
> +      lua_pushboolean(L1, lua_equal(L1, a, getindex));
> +    }
> +    else if EQ("rawcall") {
> +      int narg = getnum;
> +      int nres = getnum;
> +      lua_call(L1, narg, nres);
> +    }
> +    else if EQ("call") {
> +      int narg = getnum;
> +      int nres = getnum;
> +      lua_pcall(L1, narg, nres, 0);
> +    }
> +    else if EQ("loadstring") {
> +      size_t sl;
> +      const char *s = luaL_checklstring(L1, getnum, &sl);
> +      luaL_loadbuffer(L1, s, sl, s);
> +    }
> +    else if EQ("loadfile") {
> +      luaL_loadfile(L1, luaL_checkstring(L1, getnum));
> +    }
> +    else if EQ("setmetatable") {
> +      lua_setmetatable(L1, getindex);
> +    }
> +    else if EQ("getmetatable") {
> +      if (lua_getmetatable(L1, getindex) == 0)
> +        lua_pushnil(L1);
> +    }
> +    else if EQ("type") {
> +      lua_pushstring(L1, luaL_typename(L1, getnum));
> +    }
> +    else if EQ("getn") {
> +      int i = getindex;
> +      lua_pushinteger(L1, luaL_getn(L1, i));
> +    }
> +#ifndef luaL_setn
> +    else if EQ("setn") {
> +      int i = getindex;
> +      int n = cast_int(lua_tonumber(L1, -1));
> +      luaL_setn(L1, i, n);
> +      lua_pop(L1, 1);
> +    }
> +#endif
> +    else if EQ("throw") {
> +#if defined(__cplusplus)
> +static struct X { int x; } x;
> +      throw x;
> +#else
> +      luaL_error(L1, "C++");
> +#endif
> +      break;
> +    }
> +    else luaL_error(L, "unknown instruction %s", buff);
> +  }
> +  return 0;
> +}
> +
> +/* }====================================================== */
> +
> +
> +/*
> +** {======================================================
> +** tests for yield inside hooks
> +** =======================================================
> +*/
> +
> +static void yieldf (lua_State *L, lua_Debug *ar) {
> +  lua_yield(L, 0);
> +}
> +
> +static int setyhook (lua_State *L) {
> +  if (lua_isnoneornil(L, 1))
> +    lua_sethook(L, NULL, 0, 0);  /* turn off hooks */
> +  else {
> +    const char *smask = luaL_checkstring(L, 1);
> +    int count = luaL_optint(L, 2, 0);
> +    int mask = 0;
> +    if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
> +    if (count > 0) mask |= LUA_MASKCOUNT;
> +    lua_sethook(L, yieldf, mask, count);
> +  }
> +  return 0;
> +}
> +
> +
> +static int coresume (lua_State *L) {
> +  int status;
> +  lua_State *co = lua_tothread(L, 1);
> +  luaL_argcheck(L, co, 1, "coroutine expected");
> +  status = lua_resume(co, 0);
> +  if (status != 0) {
> +    lua_pushboolean(L, 0);
> +    lua_insert(L, -2);
> +    return 2;  /* return false + error message */
> +  }
> +  else {
> +    lua_pushboolean(L, 1);
> +    return 1;
> +  }
> +}
> +
> +/* }====================================================== */
> +
> +
> +
> +/*
> +** {======================================================
> +** tests auxlib functions
> +** =======================================================
> +*/
> +
> +static int auxgsub (lua_State *L) {
> +  const char *s1 = luaL_checkstring(L, 1);
> +  const char *s2 = luaL_checkstring(L, 2);
> +  const char *s3 = luaL_checkstring(L, 3);
> +  lua_settop(L, 3);
> +  luaL_gsub(L, s1, s2, s3);
> +  lua_assert(lua_gettop(L) == 4);
> +  return 1;
> +}
> +
> +
> +/* }====================================================== */
> +
> +
> +
> +static const struct luaL_Reg tests_funcs[] = {
> +  {"checkmemory", lua_checkmemory},
> +  {"closestate", closestate},
> +  {"d2s", d2s},
> +  {"doonnewstack", doonnewstack},
> +  {"doremote", doremote},
> +  {"gccolor", get_gccolor},
> +  {"gcstate", gcstate},
> +  {"getref", getref},
> +  {"gsub", auxgsub},
> +  {"hash", hash_query},
> +  {"int2fb", int2fb_aux},
> +  {"limits", get_limits},
> +  {"listcode", listcode},
> +  {"listk", listk},
> +  {"listlocals", listlocals},
> +  {"loadlib", loadlib},
> +  {"log2", log2_aux},
> +  {"newstate", newstate},
> +  {"newuserdata", newuserdata},
> +  {"num2int", num2int},
> +  {"pushuserdata", pushuserdata},
> +  {"querystr", string_query},
> +  {"querytab", table_query},
> +  {"ref", tref},
> +  {"resume", coresume},
> +  {"s2d", s2d},
> +  {"setyhook", setyhook},
> +  {"stacklevel", stacklevel},
> +  {"testC", testC},
> +  {"totalmem", mem_query},
> +  {"trick", settrick},
> +  {"udataval", udataval},
> +  {"unref", unref},
> +  {"upvalue", upvalue},
> +  {NULL, NULL}
> +};
> +
> +
> +int luaB_opentests (lua_State *L) {
> +  void *ud;
> +  lua_assert(lua_getallocf(L, &ud) == debug_realloc);
> +  lua_assert(ud == cast(void *, &memcontrol));
> +  lua_setallocf(L, lua_getallocf(L, NULL), ud);
> +  lua_state = L;  /* keep first state to be opened */
> +  luaL_register(L, "T", tests_funcs);
> +  return 0;
> +}
> +
> +
> +#undef main
> +int main (int argc, char *argv[]) {
> +  int ret;
> +  char *limit = getenv("MEMLIMIT");
> +  if (limit)
> +    memcontrol.memlimit = strtoul(limit, NULL, 10);
> +  ret = l_main(argc, argv);
> +  lua_assert(memcontrol.numblocks == 0);
> +  lua_assert(memcontrol.total == 0);
> +  return ret;
> +}
> +
> +#endif
> diff --git a/test/PUC-Lua-5.1-tests/etc/ltests.h b/test/PUC-Lua-5.1-tests/etc/ltests.h
> new file mode 100644
> index 0000000..e570212
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/etc/ltests.h
> @@ -0,0 +1,92 @@
> +/*
> +** $Id: ltests.h,v 2.17 2005/12/27 17:12:00 roberto Exp $
> +** Internal Header for Debugging of the Lua Implementation
> +** See Copyright Notice in lua.h
> +*/
> +
> +#ifndef ltests_h
> +#define ltests_h
> +
> +
> +#include <stdlib.h>
> +
> +
> +#define LUA_DEBUG
> +
> +#undef NDEBUG
> +#include <assert.h>
> +#define lua_assert(c)           assert(c)
> +
> +
> +/* to avoid warnings, and to make sure value is really unused */
> +#define UNUSED(x)       (x=0, (void)(x))
> +
> +
> +/* memory allocator control variables */
> +typedef struct Memcontrol {
> +  unsigned long numblocks;
> +  unsigned long total;
> +  unsigned long maxmem;
> +  unsigned long memlimit;
> +} Memcontrol;
> +
> +LUAI_DATA Memcontrol memcontrol;
> +
> +
> +/*
> +** generic variable for debug tricks
> +*/
> +LUAI_DATA int Trick;
> +
> +
> +void *debug_realloc (void *ud, void *block, size_t osize, size_t nsize);
> +
> +#ifdef lua_c
> +#define luaL_newstate()	lua_newstate(debug_realloc, &memcontrol)
> +#endif
> +
> +
> +typedef struct CallInfo *pCallInfo;
> +
> +int lua_checkmemory (lua_State *L);
> +int lua_checkpc (lua_State *L, pCallInfo ci);
> +
> +
> +/* test for lock/unlock */
> +#undef luai_userstateopen
> +#undef luai_userstatethread
> +#undef lua_lock
> +#undef lua_unlock
> +#undef LUAI_EXTRASPACE
> +
> +struct L_EXTRA { int lock; int *plock; };
> +#define LUAI_EXTRASPACE		sizeof(struct L_EXTRA)
> +#define getlock(l)	(cast(struct L_EXTRA *, l) - 1)
> +#define luai_userstateopen(l)  \
> +	(getlock(l)->lock = 0, getlock(l)->plock = &(getlock(l)->lock))
> +#define luai_userstatethread(l,l1)  (getlock(l1)->plock = getlock(l)->plock)
> +#define lua_lock(l)     lua_assert((*getlock(l)->plock)++ == 0)
> +#define lua_unlock(l)   lua_assert(--(*getlock(l)->plock) == 0)
> +
> +
> +int luaB_opentests (lua_State *L);
> +
> +#ifdef lua_c
> +#define luaL_openlibs(L)	{ (luaL_openlibs)(L); luaB_opentests(L); }
> +#endif
> +
> +
> +
> +/* real main will be defined at `ltests.c' */
> +int l_main (int argc, char *argv[]);
> +#define main	l_main
> +
> +
> +
> +/* change some sizes to give some bugs a chance */
> +
> +#undef LUAL_BUFFERSIZE
> +#define LUAL_BUFFERSIZE		27
> +#define MINSTRTABSIZE		2
> +
> +#endif
> diff --git a/test/PUC-Lua-5.1-tests/events.lua b/test/PUC-Lua-5.1-tests/events.lua
> new file mode 100644
> index 0000000..5234b00
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/events.lua
> @@ -0,0 +1,360 @@
> +print('testing metatables')
> +
> +X = 20; B = 30
> +
> +setfenv(1, setmetatable({}, {__index=_G}))
> +
> +collectgarbage()
> +
> +X = X+10
> +assert(X == 30 and _G.X == 20)
> +B = false
> +assert(B == false)
> +B = nil
> +assert(B == 30)
> +
> +assert(getmetatable{} == nil)
> +assert(getmetatable(4) == nil)
> +assert(getmetatable(nil) == nil)
> +a={}; setmetatable(a, {__metatable = "xuxu",
> +                    __tostring=function(x) return x.name end})
> +assert(getmetatable(a) == "xuxu")
> +assert(tostring(a) == nil)
> +-- cannot change a protected metatable
> +assert(pcall(setmetatable, a, {}) == false)
> +a.name = "gororoba"
> +assert(tostring(a) == "gororoba")
> +
> +local a, t = {10,20,30; x="10", y="20"}, {}
> +assert(setmetatable(a,t) == a)
> +assert(getmetatable(a) == t)
> +assert(setmetatable(a,nil) == a)
> +assert(getmetatable(a) == nil)
> +assert(setmetatable(a,t) == a)
> +
> +
> +function f (t, i, e)
> +  assert(not e)
> +  local p = rawget(t, "parent")
> +  return (p and p[i]+3), "dummy return"
> +end
> +
> +t.__index = f
> +
> +a.parent = {z=25, x=12, [4] = 24}
> +assert(a[1] == 10 and a.z == 28 and a[4] == 27 and a.x == "10")
> +
> +collectgarbage()
> +
> +a = setmetatable({}, t)
> +function f(t, i, v) rawset(t, i, v-3) end
> +t.__newindex = f
> +a[1] = 30; a.x = "101"; a[5] = 200
> +assert(a[1] == 27 and a.x == 98 and a[5] == 197)
> +
> +
> +local c = {}
> +a = setmetatable({}, t)
> +t.__newindex = c
> +a[1] = 10; a[2] = 20; a[3] = 90
> +assert(c[1] == 10 and c[2] == 20 and c[3] == 90)
> +
> +
> +do
> +  local a;
> +  a = setmetatable({}, {__index = setmetatable({},
> +                     {__index = setmetatable({},
> +                     {__index = function (_,n) return a[n-3]+4, "lixo" end})})})
> +  a[0] = 20
> +  for i=0,10 do
> +    assert(a[i*3] == 20 + i*4)
> +  end
> +end
> +
> +
> +do  -- newindex
> +  local foi
> +  local a = {}
> +  for i=1,10 do a[i] = 0; a['a'..i] = 0; end
> +  setmetatable(a, {__newindex = function (t,k,v) foi=true; rawset(t,k,v) end})
> +  foi = false; a[1]=0; assert(not foi)
> +  foi = false; a['a1']=0; assert(not foi)
> +  foi = false; a['a11']=0; assert(foi)
> +  foi = false; a[11]=0; assert(foi)
> +  foi = false; a[1]=nil; assert(not foi)
> +  foi = false; a[1]=nil; assert(foi)
> +end
> +
> +
> +function f (t, ...) return t, {...} end
> +t.__call = f
> +
> +do
> +  local x,y = a(unpack{'a', 1})
> +  assert(x==a and y[1]=='a' and y[2]==1 and y[3]==nil)
> +  x,y = a()
> +  assert(x==a and y[1]==nil)
> +end
> +
> +
> +local b = setmetatable({}, t)
> +setmetatable(b,t)
> +
> +function f(op)
> +  return function (...) cap = {[0] = op, ...} ; return (...) end
> +end
> +t.__add = f("add")
> +t.__sub = f("sub")
> +t.__mul = f("mul")
> +t.__div = f("div")
> +t.__mod = f("mod")
> +t.__unm = f("unm")
> +t.__pow = f("pow")
> +
> +assert(b+5 == b)
> +assert(cap[0] == "add" and cap[1] == b and cap[2] == 5 and cap[3]==nil)
> +assert(b+'5' == b)
> +assert(cap[0] == "add" and cap[1] == b and cap[2] == '5' and cap[3]==nil)
> +assert(5+b == 5)
> +assert(cap[0] == "add" and cap[1] == 5 and cap[2] == b and cap[3]==nil)
> +assert('5'+b == '5')
> +assert(cap[0] == "add" and cap[1] == '5' and cap[2] == b and cap[3]==nil)
> +b=b-3; assert(getmetatable(b) == t)
> +assert(5-a == 5)
> +assert(cap[0] == "sub" and cap[1] == 5 and cap[2] == a and cap[3]==nil)
> +assert('5'-a == '5')
> +assert(cap[0] == "sub" and cap[1] == '5' and cap[2] == a and cap[3]==nil)
> +assert(a*a == a)
> +assert(cap[0] == "mul" and cap[1] == a and cap[2] == a and cap[3]==nil)
> +assert(a/0 == a)
> +assert(cap[0] == "div" and cap[1] == a and cap[2] == 0 and cap[3]==nil)
> +assert(a%2 == a)
> +assert(cap[0] == "mod" and cap[1] == a and cap[2] == 2 and cap[3]==nil)
> +assert(-a == a)
> +assert(cap[0] == "unm" and cap[1] == a)
> +assert(a^4 == a)
> +assert(cap[0] == "pow" and cap[1] == a and cap[2] == 4 and cap[3]==nil)
> +assert(a^'4' == a)
> +assert(cap[0] == "pow" and cap[1] == a and cap[2] == '4' and cap[3]==nil)
> +assert(4^a == 4)
> +assert(cap[0] == "pow" and cap[1] == 4 and cap[2] == a and cap[3]==nil)
> +assert('4'^a == '4')
> +assert(cap[0] == "pow" and cap[1] == '4' and cap[2] == a and cap[3]==nil)
> +
> +
> +t = {}
> +t.__lt = function (a,b,c)
> +  collectgarbage()
> +  assert(c == nil)
> +  if type(a) == 'table' then a = a.x end
> +  if type(b) == 'table' then b = b.x end
> + return a<b, "dummy"
> +end
> +
> +function Op(x) return setmetatable({x=x}, t) end
> +
> +local function test ()
> +  assert(not(Op(1)<Op(1)) and (Op(1)<Op(2)) and not(Op(2)<Op(1)))
> +  assert(not(Op('a')<Op('a')) and (Op('a')<Op('b')) and not(Op('b')<Op('a')))
> +  assert((Op(1)<=Op(1)) and (Op(1)<=Op(2)) and not(Op(2)<=Op(1)))
> +  assert((Op('a')<=Op('a')) and (Op('a')<=Op('b')) and not(Op('b')<=Op('a')))
> +  assert(not(Op(1)>Op(1)) and not(Op(1)>Op(2)) and (Op(2)>Op(1)))
> +  assert(not(Op('a')>Op('a')) and not(Op('a')>Op('b')) and (Op('b')>Op('a')))
> +  assert((Op(1)>=Op(1)) and not(Op(1)>=Op(2)) and (Op(2)>=Op(1)))
> +  assert((Op('a')>=Op('a')) and not(Op('a')>=Op('b')) and (Op('b')>=Op('a')))
> +end
> +
> +test()
> +
> +t.__le = function (a,b,c)
> +  assert(c == nil)
> +  if type(a) == 'table' then a = a.x end
> +  if type(b) == 'table' then b = b.x end
> + return a<=b, "dummy"
> +end
> +
> +test()  -- retest comparisons, now using both `lt' and `le'
> +
> +
> +-- test `partial order'
> +
> +local function Set(x)
> +  local y = {}
> +  for _,k in pairs(x) do y[k] = 1 end
> +  return setmetatable(y, t)
> +end
> +
> +t.__lt = function (a,b)
> +  for k in pairs(a) do
> +    if not b[k] then return false end
> +    b[k] = nil
> +  end
> +  return next(b) ~= nil
> +end
> +
> +t.__le = nil
> +
> +assert(Set{1,2,3} < Set{1,2,3,4})
> +assert(not(Set{1,2,3,4} < Set{1,2,3,4}))
> +assert((Set{1,2,3,4} <= Set{1,2,3,4}))
> +assert((Set{1,2,3,4} >= Set{1,2,3,4}))
> +assert((Set{1,3} <= Set{3,5}))   -- wrong!! model needs a `le' method ;-)
> +
> +t.__le = function (a,b)
> +  for k in pairs(a) do
> +    if not b[k] then return false end
> +  end
> +  return true
> +end
> +
> +assert(not (Set{1,3} <= Set{3,5}))   -- now its OK!
> +assert(not(Set{1,3} <= Set{3,5}))
> +assert(not(Set{1,3} >= Set{3,5}))
> +
> +t.__eq = function (a,b)
> +  for k in pairs(a) do
> +    if not b[k] then return false end
> +    b[k] = nil
> +  end
> +  return next(b) == nil
> +end
> +
> +local s = Set{1,3,5}
> +assert(s == Set{3,5,1})
> +assert(not rawequal(s, Set{3,5,1}))
> +assert(rawequal(s, s))
> +assert(Set{1,3,5,1} == Set{3,5,1})
> +assert(Set{1,3,5} ~= Set{3,5,1,6})
> +t[Set{1,3,5}] = 1
> +assert(t[Set{1,3,5}] == nil)   -- `__eq' is not valid for table accesses
> +
> +
> +t.__concat = function (a,b,c)
> +  assert(c == nil)
> +  if type(a) == 'table' then a = a.val end
> +  if type(b) == 'table' then b = b.val end
> +  if A then return a..b
> +  else
> +    return setmetatable({val=a..b}, t)
> +  end
> +end
> +
> +c = {val="c"}; setmetatable(c, t)
> +d = {val="d"}; setmetatable(d, t)
> +
> +A = true
> +assert(c..d == 'cd')
> +assert(0 .."a".."b"..c..d.."e".."f"..(5+3).."g" == "0abcdef8g")
> +
> +A = false
> +x = c..d
> +assert(getmetatable(x) == t and x.val == 'cd')
> +x = 0 .."a".."b"..c..d.."e".."f".."g"
> +assert(x.val == "0abcdefg")
> +
> +
> +-- test comparison compatibilities
> +local t1, t2, c, d
> +t1 = {};  c = {}; setmetatable(c, t1)
> +d = {}
> +t1.__eq = function () return true end
> +t1.__lt = function () return true end
> +assert(c ~= d and not pcall(function () return c < d end))
> +setmetatable(d, t1)
> +assert(c == d and c < d and not(d <= c))
> +t2 = {}
> +t2.__eq = t1.__eq
> +t2.__lt = t1.__lt
> +setmetatable(d, t2)
> +assert(c == d and c < d and not(d <= c))
> +
> +
> +
> +-- test for several levels of calls
> +local i
> +local tt = {
> +  __call = function (t, ...)
> +    i = i+1
> +    if t.f then return t.f(...)
> +    else return {...}
> +    end
> +  end
> +}
> +
> +local a = setmetatable({}, tt)
> +local b = setmetatable({f=a}, tt)
> +local c = setmetatable({f=b}, tt)
> +
> +i = 0
> +x = c(3,4,5)
> +assert(i == 3 and x[1] == 3 and x[3] == 5)
> +
> +
> +assert(_G.X == 20)
> +assert(_G == getfenv(0))
> +
> +print'+'
> +
> +local _g = _G
> +setfenv(1, setmetatable({}, {__index=function (_,k) return _g[k] end}))
> +
> +-- testing proxies
> +assert(getmetatable(newproxy()) == nil)
> +assert(getmetatable(newproxy(false)) == nil)
> +
> +local u = newproxy(true)
> +
> +getmetatable(u).__newindex = function (u,k,v)
> +  getmetatable(u)[k] = v
> +end
> +
> +getmetatable(u).__index = function (u,k)
> +  return getmetatable(u)[k]
> +end
> +
> +for i=1,10 do u[i] = i end
> +for i=1,10 do assert(u[i] == i) end
> +
> +local k = newproxy(u)
> +assert(getmetatable(k) == getmetatable(u))
> +
> +
> +a = {}
> +rawset(a, "x", 1, 2, 3)
> +assert(a.x == 1 and rawget(a, "x", 3) == 1)
> +
> +print '+'
> +
> +-- testing metatables for basic types
> +mt = {}
> +debug.setmetatable(10, mt)
> +assert(getmetatable(-2) == mt)
> +mt.__index = function (a,b) return a+b end
> +assert((10)[3] == 13)
> +assert((10)["3"] == 13)
> +debug.setmetatable(23, nil)
> +assert(getmetatable(-2) == nil)
> +
> +debug.setmetatable(true, mt)
> +assert(getmetatable(false) == mt)
> +mt.__index = function (a,b) return a or b end
> +assert((true)[false] == true)
> +assert((false)[false] == false)
> +debug.setmetatable(false, nil)
> +assert(getmetatable(true) == nil)
> +
> +debug.setmetatable(nil, mt)
> +assert(getmetatable(nil) == mt)
> +mt.__add = function (a,b) return (a or 0) + (b or 0) end
> +assert(10 + nil == 10)
> +assert(nil + 23 == 23)
> +assert(nil + nil == 0)
> +debug.setmetatable(nil, nil)
> +assert(getmetatable(nil) == nil)
> +
> +debug.setmetatable(nil, {})
> +
> +
> +print 'OK'
> +
> +return 12
> diff --git a/test/PUC-Lua-5.1-tests/files.lua b/test/PUC-Lua-5.1-tests/files.lua
> new file mode 100644
> index 0000000..903488c
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/files.lua
> @@ -0,0 +1,324 @@
> +
> +print('testing i/o')
> +
> +assert(io.input(io.stdin) == io.stdin)
> +assert(io.output(io.stdout) == io.stdout)
> +
> +
> +assert(type(io.input()) == "userdata" and io.type(io.output()) == "file")
> +assert(io.type(8) == nil)
> +local a = {}; setmetatable(a, {})
> +assert(io.type(a) == nil)
> +
> +local a,b,c = io.open('xuxu_nao_existe')
> +assert(not a and type(b) == "string" and type(c) == "number")
> +
> +a,b,c = io.open('/a/b/c/d', 'w')
> +assert(not a and type(b) == "string" and type(c) == "number")
> +
> +local file = os.tmpname()
> +local otherfile = os.tmpname()
> +
> +assert(os.setlocale('C', 'all'))
> +
> +io.input(io.stdin); io.output(io.stdout);
> +
> +os.remove(file)
> +assert(loadfile(file) == nil)
> +assert(io.open(file) == nil)
> +io.output(file)
> +assert(io.output() ~= io.stdout)
> +
> +assert(io.output():seek() == 0)
> +assert(io.write("alo alo"))
> +assert(io.output():seek() == string.len("alo alo"))
> +assert(io.output():seek("cur", -3) == string.len("alo alo")-3)
> +assert(io.write("joao"))
> +assert(io.output():seek("end") == string.len("alo joao"))
> +
> +assert(io.output():seek("set") == 0)
> +
> +assert(io.write('"�lo"', "{a}\n", "second line\n", "third line \n"))
> +assert(io.write('�fourth_line'))
> +io.output(io.stdout)
> +collectgarbage()  -- file should be closed by GC
> +assert(io.input() == io.stdin and rawequal(io.output(), io.stdout))
> +print('+')
> +
> +-- test GC for files
> +collectgarbage()
> +for i=1,120 do
> +  for i=1,5 do
> +    io.input(file)
> +    assert(io.open(file, 'r'))
> +    io.lines(file)
> +  end
> +  collectgarbage()
> +end
> +
> +assert(os.rename(file, otherfile))
> +assert(os.rename(file, otherfile) == nil)
> +
> +io.output(io.open(otherfile, "a"))
> +assert(io.write("\n\n\t\t  3450\n"));
> +io.close()
> +
> +-- test line generators
> +assert(os.rename(otherfile, file))
> +io.output(otherfile)
> +local f = io.lines(file)
> +while f() do end;
> +assert(not pcall(f))  -- read lines after EOF
> +assert(not pcall(f))  -- read lines after EOF
> +-- copy from file to otherfile
> +for l in io.lines(file) do io.write(l, "\n") end
> +io.close()
> +-- copy from otherfile back to file
> +local f = assert(io.open(otherfile))
> +assert(io.type(f) == "file")
> +io.output(file)
> +assert(io.output():read() == nil)
> +for l in f:lines() do io.write(l, "\n") end
> +assert(f:close()); io.close()
> +assert(not pcall(io.close, f))   -- error trying to close again
> +assert(tostring(f) == "file (closed)")
> +assert(io.type(f) == "closed file")
> +io.input(file)
> +f = io.open(otherfile):lines()
> +for l in io.lines() do assert(l == f()) end
> +assert(os.remove(otherfile))
> +
> +io.input(file)
> +do  -- test error returns
> +  local a,b,c = io.input():write("xuxu")
> +  assert(not a and type(b) == "string" and type(c) == "number")
> +end
> +assert(io.read(0) == "")   -- not eof
> +assert(io.read(5, '*l') == '"�lo"')
> +assert(io.read(0) == "")
> +assert(io.read() == "second line")
> +local x = io.input():seek()
> +assert(io.read() == "third line ")
> +assert(io.input():seek("set", x))
> +assert(io.read('*l') == "third line ")
> +assert(io.read(1) == "�")
> +assert(io.read(string.len"fourth_line") == "fourth_line")
> +assert(io.input():seek("cur", -string.len"fourth_line"))
> +assert(io.read() == "fourth_line")
> +assert(io.read() == "")  -- empty line
> +assert(io.read('*n') == 3450)
> +assert(io.read(1) == '\n')
> +assert(io.read(0) == nil)  -- end of file
> +assert(io.read(1) == nil)  -- end of file
> +assert(({io.read(1)})[2] == nil)
> +assert(io.read() == nil)  -- end of file
> +assert(({io.read()})[2] == nil)
> +assert(io.read('*n') == nil)  -- end of file
> +assert(({io.read('*n')})[2] == nil)
> +assert(io.read('*a') == '')  -- end of file (OK for `*a')
> +assert(io.read('*a') == '')  -- end of file (OK for `*a')
> +collectgarbage()
> +print('+')
> +io.close(io.input())
> +assert(not pcall(io.read))
> +
> +assert(os.remove(file))
> +
> +local t = '0123456789'
> +for i=1,12 do t = t..t; end
> +assert(string.len(t) == 10*2^12)
> +
> +io.output(file)
> +io.write("alo\n")
> +io.close()
> +assert(not pcall(io.write))
> +local f = io.open(file, "a")
> +io.output(f)
> +collectgarbage()
> +
> +assert(io.write(' ' .. t .. ' '))
> +assert(io.write(';', 'end of file\n'))
> +f:flush(); io.flush()
> +f:close()
> +print('+')
> +
> +io.input(file)
> +assert(io.read() == "alo")
> +assert(io.read(1) == ' ')
> +assert(io.read(string.len(t)) == t)
> +assert(io.read(1) == ' ')
> +assert(io.read(0))
> +assert(io.read('*a') == ';end of file\n')
> +assert(io.read(0) == nil)
> +assert(io.close(io.input()))
> +
> +assert(os.remove(file))
> +print('+')
> +
> +local x1 = "string\n\n\\com \"\"''coisas [[estranhas]] ]]'"
> +io.output(file)
> +assert(io.write(string.format("x2 = %q\n-- comment without ending EOS", x1)))
> +io.close()
> +assert(loadfile(file))()
> +assert(x1 == x2)
> +print('+')
> +assert(os.remove(file))
> +assert(os.remove(file) == nil)
> +assert(os.remove(otherfile) == nil)
> +
> +io.output(file)
> +assert(io.write("qualquer coisa\n"))
> +assert(io.write("mais qualquer coisa"))
> +io.close()
> +io.output(assert(io.open(otherfile, 'wb')))
> +assert(io.write("outra coisa\0\1\3\0\0\0\0\255\0"))
> +io.close()
> +
> +local filehandle = assert(io.open(file, 'r'))
> +local otherfilehandle = assert(io.open(otherfile, 'rb'))
> +assert(filehandle ~= otherfilehandle)
> +assert(type(filehandle) == "userdata")
> +assert(filehandle:read('*l') == "qualquer coisa")
> +io.input(otherfilehandle)
> +assert(io.read(string.len"outra coisa") == "outra coisa")
> +assert(filehandle:read('*l') == "mais qualquer coisa")
> +filehandle:close();
> +assert(type(filehandle) == "userdata")
> +io.input(otherfilehandle)
> +assert(io.read(4) == "\0\1\3\0")
> +assert(io.read(3) == "\0\0\0")
> +assert(io.read(0) == "")        -- 255 is not eof
> +assert(io.read(1) == "\255")
> +assert(io.read('*a') == "\0")
> +assert(not io.read(0))
> +assert(otherfilehandle == io.input())
> +otherfilehandle:close()
> +assert(os.remove(file))
> +assert(os.remove(otherfile))
> +collectgarbage()
> +
> +io.output(file)
> +io.write[[
> + 123.4	-56e-2  not a number
> +second line
> +third line
> +
> +and the rest of the file
> +]]
> +io.close()
> +io.input(file)
> +local _,a,b,c,d,e,h,__ = io.read(1, '*n', '*n', '*l', '*l', '*l', '*a', 10)
> +assert(io.close(io.input()))
> +assert(_ == ' ' and __ == nil)
> +assert(type(a) == 'number' and a==123.4 and b==-56e-2)
> +assert(d=='second line' and e=='third line')
> +assert(h==[[
> +
> +and the rest of the file
> +]])
> +assert(os.remove(file))
> +collectgarbage()
> +
> +-- testing buffers
> +do
> +  local f = assert(io.open(file, "w"))
> +  local fr = assert(io.open(file, "r"))
> +  assert(f:setvbuf("full", 2000))
> +  f:write("x")
> +  assert(fr:read("*all") == "")  -- full buffer; output not written yet
> +  f:close()
> +  fr:seek("set")
> +  assert(fr:read("*all") == "x")   -- `close' flushes it
> +  f = assert(io.open(file), "w")
> +  assert(f:setvbuf("no"))
> +  f:write("x")
> +  fr:seek("set")
> +  assert(fr:read("*all") == "x")  -- no buffer; output is ready
> +  f:close()
> +  f = assert(io.open(file, "a"))
> +  assert(f:setvbuf("line"))
> +  f:write("x")
> +  fr:seek("set", 1)
> +  assert(fr:read("*all") == "")   -- line buffer; no output without `\n'
> +  f:write("a\n")
> +  fr:seek("set", 1)
> +  assert(fr:read("*all") == "xa\n")  -- now we have a whole line
> +  f:close(); fr:close()
> +end
> +
> +
> +-- testing large files (> BUFSIZ)
> +io.output(file)
> +for i=1,5001 do io.write('0123456789123') end
> +io.write('\n12346')
> +io.close()
> +io.input(file)
> +local x = io.read('*a')
> +io.input():seek('set', 0)
> +local y = io.read(30001)..io.read(1005)..io.read(0)..io.read(1)..io.read(100003)
> +assert(x == y and string.len(x) == 5001*13 + 6)
> +io.input():seek('set', 0)
> +y = io.read()  -- huge line
> +assert(x == y..'\n'..io.read())
> +assert(io.read() == nil)
> +io.close(io.input())
> +assert(os.remove(file))
> +x = nil; y = nil
> +
> +x, y = pcall(io.popen, "ls")
> +if x then
> +  assert(y:read("*a"))
> +  assert(y:close())
> +else
> +  (Message or print)('\a\n >>> popen not available<<<\n\a')
> +end
> +
> +print'+'
> +
> +local t = os.time()
> +T = os.date("*t", t)
> +loadstring(os.date([[assert(T.year==%Y and T.month==%m and T.day==%d and
> +  T.hour==%H and T.min==%M and T.sec==%S and
> +  T.wday==%w+1 and T.yday==%j and type(T.isdst) == 'boolean')]], t))()
> +
> +assert(os.time(T) == t)
> +
> +T = os.date("!*t", t)
> +loadstring(os.date([[!assert(T.year==%Y and T.month==%m and T.day==%d and
> +  T.hour==%H and T.min==%M and T.sec==%S and
> +  T.wday==%w+1 and T.yday==%j and type(T.isdst) == 'boolean')]], t))()
> +
> +do
> +  local T = os.date("*t")
> +  local t = os.time(T)
> +  assert(type(T.isdst) == 'boolean')
> +  T.isdst = nil
> +  local t1 = os.time(T)
> +  assert(t == t1)   -- if isdst is absent uses correct default
> +end
> +
> +t = os.time(T)
> +T.year = T.year-1;
> +local t1 = os.time(T)
> +-- allow for leap years
> +assert(math.abs(os.difftime(t,t1)/(24*3600) - 365) < 2)
> +
> +t = os.time()
> +t1 = os.time(os.date("*t"))
> +assert(os.difftime(t1,t) <= 2)
> +
> +local t1 = os.time{year=2000, month=10, day=1, hour=23, min=12, sec=17}
> +local t2 = os.time{year=2000, month=10, day=1, hour=23, min=10, sec=19}
> +assert(os.difftime(t1,t2) == 60*2-2)
> +
> +io.output(io.stdout)
> +local d = os.date('%d')
> +local m = os.date('%m')
> +local a = os.date('%Y')
> +local ds = os.date('%w') + 1
> +local h = os.date('%H')
> +local min = os.date('%M')
> +local s = os.date('%S')
> +io.write(string.format('test done on %2.2d/%2.2d/%d', d, m, a))
> +io.write(string.format(', at %2.2d:%2.2d:%2.2d\n', h, min, s))
> +io.write(string.format('%s\n', _VERSION))
> diff --git a/test/PUC-Lua-5.1-tests/gc.lua b/test/PUC-Lua-5.1-tests/gc.lua
> new file mode 100644
> index 0000000..86a9f75
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/gc.lua
> @@ -0,0 +1,312 @@
> +print('testing garbage collection')
> +
> +collectgarbage()
> +
> +_G["while"] = 234
> +
> +limit = 5000
> +
> +
> +
> +contCreate = 0
> +
> +print('tables')
> +while contCreate <= limit do
> +  local a = {}; a = nil
> +  contCreate = contCreate+1
> +end
> +
> +a = "a"
> +
> +contCreate = 0
> +print('strings')
> +while contCreate <= limit do
> +  a = contCreate .. "b";
> +  a = string.gsub(a, '(%d%d*)', string.upper)
> +  a = "a"
> +  contCreate = contCreate+1
> +end
> +
> +
> +contCreate = 0
> +
> +a = {}
> +
> +print('functions')
> +function a:test ()
> +  while contCreate <= limit do
> +    loadstring(string.format("function temp(a) return 'a%d' end", contCreate))()
> +    assert(temp() == string.format('a%d', contCreate))
> +    contCreate = contCreate+1
> +  end
> +end
> +
> +a:test()
> +
> +-- collection of functions without locals, globals, etc.
> +do local f = function () end end
> +
> +
> +print("functions with errors")
> +prog = [[
> +do
> +  a = 10;
> +  function foo(x,y)
> +    a = sin(a+0.456-0.23e-12);
> +    return function (z) return sin(%x+z) end
> +  end
> +  local x = function (w) a=a+w; end
> +end
> +]]
> +do
> +  local step = 1
> +  if rawget(_G, "_soft") then step = 13 end
> +  for i=1, string.len(prog), step do
> +    for j=i, string.len(prog), step do
> +      pcall(loadstring(string.sub(prog, i, j)))
> +    end
> +  end
> +end
> +
> +print('long strings')
> +x = "01234567890123456789012345678901234567890123456789012345678901234567890123456789"
> +assert(string.len(x)==80)
> +s = ''
> +n = 0
> +k = 300
> +while n < k do s = s..x; n=n+1; j=tostring(n)  end
> +assert(string.len(s) == k*80)
> +s = string.sub(s, 1, 20000)
> +s, i = string.gsub(s, '(%d%d%d%d)', math.sin)
> +assert(i==20000/4)
> +s = nil
> +x = nil
> +
> +assert(_G["while"] == 234)
> +
> +
> +local bytes = gcinfo()
> +while 1 do
> +  local nbytes = gcinfo()
> +  if nbytes < bytes then break end   -- run until gc
> +  bytes = nbytes
> +  a = {}
> +end
> +
> +
> +local function dosteps (siz)
> +  collectgarbage()
> +  collectgarbage"stop"
> +  local a = {}
> +  for i=1,100 do a[i] = {{}}; local b = {} end
> +  local x = gcinfo()
> +  local i = 0
> +  repeat
> +    i = i+1
> +  until collectgarbage("step", siz)
> +  assert(gcinfo() < x)
> +  return i
> +end
> +
> +assert(dosteps(0) > 10)
> +assert(dosteps(6) < dosteps(2))
> +assert(dosteps(10000) == 1)
> +assert(collectgarbage("step", 1000000) == true)
> +assert(collectgarbage("step", 1000000))
> +
> +
> +do
> +  local x = gcinfo()
> +  collectgarbage()
> +  collectgarbage"stop"
> +  repeat
> +    local a = {}
> +  until gcinfo() > 1000
> +  collectgarbage"restart"
> +  repeat
> +    local a = {}
> +  until gcinfo() < 1000
> +end
> +
> +lim = 15
> +a = {}
> +-- fill a with `collectable' indices
> +for i=1,lim do a[{}] = i end
> +b = {}
> +for k,v in pairs(a) do b[k]=v end
> +-- remove all indices and collect them
> +for n in pairs(b) do
> +  a[n] = nil
> +  assert(type(n) == 'table' and next(n) == nil)
> +  collectgarbage()
> +end
> +b = nil
> +collectgarbage()
> +for n in pairs(a) do error'cannot be here' end
> +for i=1,lim do a[i] = i end
> +for i=1,lim do assert(a[i] == i) end
> +
> +
> +print('weak tables')
> +a = {}; setmetatable(a, {__mode = 'k'});
> +-- fill a with some `collectable' indices
> +for i=1,lim do a[{}] = i end
> +-- and some non-collectable ones
> +for i=1,lim do local t={}; a[t]=t end
> +for i=1,lim do a[i] = i end
> +for i=1,lim do local s=string.rep('@', i); a[s] = s..'#' end
> +collectgarbage()
> +local i = 0
> +for k,v in pairs(a) do assert(k==v or k..'#'==v); i=i+1 end
> +assert(i == 3*lim)
> +
> +a = {}; setmetatable(a, {__mode = 'v'});
> +a[1] = string.rep('b', 21)
> +collectgarbage()
> +assert(a[1])   -- strings are *values*
> +a[1] = nil
> +-- fill a with some `collectable' values (in both parts of the table)
> +for i=1,lim do a[i] = {} end
> +for i=1,lim do a[i..'x'] = {} end
> +-- and some non-collectable ones
> +for i=1,lim do local t={}; a[t]=t end
> +for i=1,lim do a[i+lim]=i..'x' end
> +collectgarbage()
> +local i = 0
> +for k,v in pairs(a) do assert(k==v or k-lim..'x' == v); i=i+1 end
> +assert(i == 2*lim)
> +
> +a = {}; setmetatable(a, {__mode = 'vk'});
> +local x, y, z = {}, {}, {}
> +-- keep only some items
> +a[1], a[2], a[3] = x, y, z
> +a[string.rep('$', 11)] = string.rep('$', 11)
> +-- fill a with some `collectable' values
> +for i=4,lim do a[i] = {} end
> +for i=1,lim do a[{}] = i end
> +for i=1,lim do local t={}; a[t]=t end
> +collectgarbage()
> +assert(next(a) ~= nil)
> +local i = 0
> +for k,v in pairs(a) do
> +  assert((k == 1 and v == x) or
> +         (k == 2 and v == y) or
> +         (k == 3 and v == z) or k==v);
> +  i = i+1
> +end
> +assert(i == 4)
> +x,y,z=nil
> +collectgarbage()
> +assert(next(a) == string.rep('$', 11))
> +
> +
> +-- testing userdata
> +collectgarbage("stop")   -- stop collection
> +local u = newproxy(true)
> +local s = 0
> +local a = {[u] = 0}; setmetatable(a, {__mode = 'vk'})
> +for i=1,10 do a[newproxy(u)] = i end
> +for k in pairs(a) do assert(getmetatable(k) == getmetatable(u)) end
> +local a1 = {}; for k,v in pairs(a) do a1[k] = v end
> +for k,v in pairs(a1) do a[v] = k end
> +for i =1,10 do assert(a[i]) end
> +getmetatable(u).a = a1
> +getmetatable(u).u = u
> +do
> +  local u = u
> +  getmetatable(u).__gc = function (o)
> +    assert(a[o] == 10-s)
> +    assert(a[10-s] == nil) -- udata already removed from weak table
> +    assert(getmetatable(o) == getmetatable(u))
> +    assert(getmetatable(o).a[o] == 10-s)
> +    s=s+1
> +  end
> +end
> +a1, u = nil
> +assert(next(a) ~= nil)
> +collectgarbage()
> +assert(s==11)
> +collectgarbage()
> +assert(next(a) == nil)  -- finalized keys are removed in two cycles
> +
> +
> +-- __gc x weak tables
> +local u = newproxy(true)
> +setmetatable(getmetatable(u), {__mode = "v"})
> +getmetatable(u).__gc = function (o) os.exit(1) end  -- cannot happen
> +collectgarbage()
> +
> +local u = newproxy(true)
> +local m = getmetatable(u)
> +m.x = {[{0}] = 1; [0] = {1}}; setmetatable(m.x, {__mode = "kv"});
> +m.__gc = function (o)
> +  assert(next(getmetatable(o).x) == nil)
> +  m = 10
> +end
> +u, m = nil
> +collectgarbage()
> +assert(m==10)
> +
> +
> +-- errors during collection
> +u = newproxy(true)
> +getmetatable(u).__gc = function () error "!!!" end
> +u = nil
> +assert(not pcall(collectgarbage))
> +
> +
> +if not rawget(_G, "_soft") then
> +  print("deep structures")
> +  local a = {}
> +  for i = 1,200000 do
> +    a = {next = a}
> +  end
> +  collectgarbage()
> +end
> +
> +-- create many threads with self-references and open upvalues
> +local thread_id = 0
> +local threads = {}
> +
> +function fn(thread)
> +    local x = {}
> +    threads[thread_id] = function()
> +                             thread = x
> +                         end
> +    coroutine.yield()
> +end
> +
> +while thread_id < 1000 do
> +    local thread = coroutine.create(fn)
> +    coroutine.resume(thread, thread)
> +    thread_id = thread_id + 1
> +end
> +
> +
> +
> +-- create a userdata to be collected when state is closed
> +do
> +  local newproxy,assert,type,print,getmetatable =
> +        newproxy,assert,type,print,getmetatable
> +  local u = newproxy(true)
> +  local tt = getmetatable(u)
> +  ___Glob = {u}   -- avoid udata being collected before program end
> +  tt.__gc = function (o)
> +    assert(getmetatable(o) == tt)
> +    -- create new objects during GC
> +    local a = 'xuxu'..(10+3)..'joao', {}
> +    ___Glob = o  -- ressurect object!
> +    newproxy(o)  -- creates a new one with same metatable
> +    print(">>> closing state " .. "<<<\n")
> +  end
> +end
> +
> +-- create several udata to raise errors when collected while closing state
> +do
> +  local u = newproxy(true)
> +  getmetatable(u).__gc = function (o) return o + 1 end
> +  table.insert(___Glob, u)  -- preserve udata until the end
> +  for i = 1,10 do table.insert(___Glob, newproxy(u)) end
> +end
> +
> +print('OK')
> diff --git a/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt
> new file mode 100644
> index 0000000..f24e7f3
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt
> @@ -0,0 +1,18 @@
> +# Test suite that has been added from PUC-Rio Lua 5.1 test archive
> +# in scope of https://github.com/tarantool/tarantool/issues/5845.
> +
> +# See the rationale in the root CMakeLists.txt.
> +cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
> +
> +# The original tarball contains subdirectory "libs" with an empty
> +# subdirectory "libs/P1", to be used by tests.
> +# Instead of tracking empty directory with some anchor-file for
> +# git, create this directory via CMake.
> +add_custom_target(PUC-Lua-5.1-tests-prepare)
> +add_custom_command(TARGET PUC-Lua-5.1-tests-prepare
> +  COMMENT "Create directory for PUC-Rio Lua 5.1 tests"
> +  COMMAND ${CMAKE_COMMAND} -E make_directory P1
> +  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
> +)
> +
> +# vim: expandtab tabstop=2 shiftwidth=2
> diff --git a/test/PUC-Lua-5.1-tests/libs/lib1.c b/test/PUC-Lua-5.1-tests/libs/lib1.c
> new file mode 100644
> index 0000000..812bb9a
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/libs/lib1.c
> @@ -0,0 +1,40 @@
> +/*
> +** compile with
> +** Linux: gcc -Wall -O2 -I.. -ansi -shared -o lib1.so lib1.c
> +** Mac OS X: export MACOSX_DEPLOYMENT_TARGET=10.3
> +**     gcc -bundle -undefined dynamic_lookup -Wall -O2 -o lib1.so lib1.c
> +*/
> +
> +
> +#include "lua.h"
> +#include "lauxlib.h"
> +
> +static int id (lua_State *L) {
> +  return lua_gettop(L);
> +}
> +
> +
> +static const struct luaL_reg funcs[] = {
> +  {"id", id},
> +  {NULL, NULL}
> +};
> +
> +
> +int anotherfunc (lua_State *L) {
> +  lua_pushfstring(L, "%f%f\n", lua_tonumber(L, 1), lua_tonumber(L, 2));
> +  return 1;
> +}
> +
> +
> +int luaopen_lib1_sub (lua_State *L) {
> +  luaL_register(L, "lib1.sub", funcs + 1);
> +  return 1;
> +}
> +
> +
> +int luaopen_lib1 (lua_State *L) {
> +  luaL_register(L, "lib1", funcs);
> +  return 1;
> +}
> +
> +
> diff --git a/test/PUC-Lua-5.1-tests/libs/lib11.c b/test/PUC-Lua-5.1-tests/libs/lib11.c
> new file mode 100644
> index 0000000..3efa3d3
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/libs/lib11.c
> @@ -0,0 +1,18 @@
> +/*
> +** compile with
> +** Linux: gcc -Wall -O2 -I.. -ansi -shared -o lib1.so lib1.c
> +** Mac OS X: export MACOSX_DEPLOYMENT_TARGET=10.3
> +**     gcc -bundle -undefined dynamic_lookup -Wall -O2 -o lib1.so lib1.c
> +*/
> +
> +
> +#include "lua.h"
> +
> +
> +int luaopen_lib1 (lua_State *L);
> +
> +int luaopen_lib11 (lua_State *L) {
> +  return luaopen_lib1(L);
> +}
> +
> +
> diff --git a/test/PUC-Lua-5.1-tests/libs/lib2.c b/test/PUC-Lua-5.1-tests/libs/lib2.c
> new file mode 100644
> index 0000000..9972cbe
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/libs/lib2.c
> @@ -0,0 +1,28 @@
> +/*
> +** compile with
> +** 	gcc -Wall -O2 -I.. -ansi -shared -o lib1.so lib1.c
> +*/
> +
> +
> +#include "lua.h"
> +#include "lauxlib.h"
> +
> +static int id (lua_State *L) {
> +  return lua_gettop(L);
> +}
> +
> +
> +static const struct luaL_reg funcs[] = {
> +  {"id", id},
> +  {NULL, NULL}
> +};
> +
> +
> +int luaopen_lib2 (lua_State *L) {
> +  luaL_register(L, "lib2", funcs);
> +  lua_pushnumber(L, 0.5);
> +  lua_setglobal(L, "x");
> +  return 1;
> +}
> +
> +
> diff --git a/test/PUC-Lua-5.1-tests/libs/lib21.c b/test/PUC-Lua-5.1-tests/libs/lib21.c
> new file mode 100644
> index 0000000..167507f
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/libs/lib21.c
> @@ -0,0 +1,18 @@
> +/*
> +** compile with
> +** Linux: gcc -Wall -O2 -I.. -ansi -shared -o lib1.so lib1.c
> +** Mac OS X: export MACOSX_DEPLOYMENT_TARGET=10.3
> +**     gcc -bundle -undefined dynamic_lookup -Wall -O2 -o lib1.so lib1.c
> +*/
> +
> +
> +#include "lua.h"
> +
> +
> +int luaopen_lib2 (lua_State *L);
> +
> +int luaopen_lib21 (lua_State *L) {
> +  return luaopen_lib2(L);
> +}
> +
> +
> diff --git a/test/PUC-Lua-5.1-tests/literals.lua b/test/PUC-Lua-5.1-tests/literals.lua
> new file mode 100644
> index 0000000..01d84d5
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/literals.lua
> @@ -0,0 +1,176 @@
> +print('testing scanner')
> +
> +local function dostring (x) return assert(loadstring(x))() end
> +
> +dostring("x = 'a\0a'")
> +assert(x == 'a\0a' and string.len(x) == 3)
> +
> +-- escape sequences
> +assert('\n\"\'\\' == [[
> +
> +"'\]])
> +
> +assert(string.find("\a\b\f\n\r\t\v", "^%c%c%c%c%c%c%c$"))
> +
> +-- assume ASCII just for tests:
> +assert("\09912" == 'c12')
> +assert("\99ab" == 'cab')
> +assert("\099" == '\99')
> +assert("\099\n" == 'c\10')
> +assert('\0\0\0alo' == '\0' .. '\0\0' .. 'alo')
> +
> +assert(010 .. 020 .. -030 == "1020-30")
> +
> +-- long variable names
> +
> +var = string.rep('a', 15000)
> +prog = string.format("%s = 5", var)
> +dostring(prog)
> +assert(_G[var] == 5)
> +var = nil
> +print('+')
> +
> +-- escapes --
> +assert("\n\t" == [[
> +
> +	]])
> +assert([[
> +
> + $debug]] == "\n $debug")
> +assert([[ [ ]] ~= [[ ] ]])
> +-- long strings --
> +b = "001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789"
> +assert(string.len(b) == 960)
> +prog = [=[
> +print('+')
> +
> +a1 = [["isto e' um string com v�rias 'aspas'"]]
> +a2 = "'aspas'"
> +
> +assert(string.find(a1, a2) == 31)
> +print('+')
> +
> +a1 = [==[temp = [[um valor qualquer]]; ]==]
> +assert(loadstring(a1))()
> +assert(temp == 'um valor qualquer')
> +-- long strings --
> +b = "001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789"
> +assert(string.len(b) == 960)
> +print('+')
> +
> +a = [[00123456789012345678901234567890123456789123456789012345678901234567890123456789
> +00123456789012345678901234567890123456789123456789012345678901234567890123456789
> +00123456789012345678901234567890123456789123456789012345678901234567890123456789
> +00123456789012345678901234567890123456789123456789012345678901234567890123456789
> +00123456789012345678901234567890123456789123456789012345678901234567890123456789
> +00123456789012345678901234567890123456789123456789012345678901234567890123456789
> +00123456789012345678901234567890123456789123456789012345678901234567890123456789
> +00123456789012345678901234567890123456789123456789012345678901234567890123456789
> +00123456789012345678901234567890123456789123456789012345678901234567890123456789
> +00123456789012345678901234567890123456789123456789012345678901234567890123456789
> +00123456789012345678901234567890123456789123456789012345678901234567890123456789
> +00123456789012345678901234567890123456789123456789012345678901234567890123456789
> +00123456789012345678901234567890123456789123456789012345678901234567890123456789
> +00123456789012345678901234567890123456789123456789012345678901234567890123456789
> +00123456789012345678901234567890123456789123456789012345678901234567890123456789
> +00123456789012345678901234567890123456789123456789012345678901234567890123456789
> +00123456789012345678901234567890123456789123456789012345678901234567890123456789
> +00123456789012345678901234567890123456789123456789012345678901234567890123456789
> +00123456789012345678901234567890123456789123456789012345678901234567890123456789
> +00123456789012345678901234567890123456789123456789012345678901234567890123456789
> +00123456789012345678901234567890123456789123456789012345678901234567890123456789
> +00123456789012345678901234567890123456789123456789012345678901234567890123456789
> +00123456789012345678901234567890123456789123456789012345678901234567890123456789
> +]]
> +assert(string.len(a) == 1863)
> +assert(string.sub(a, 1, 40) == string.sub(b, 1, 40))
> +x = 1
> +]=]
> +
> +print('+')
> +x = nil
> +dostring(prog)
> +assert(x)
> +
> +prog = nil
> +a = nil
> +b = nil
> +
> +
> +-- testing line ends
> +prog = [[
> +a = 1        -- a comment
> +b = 2
> +
> +
> +x = [=[
> +hi
> +]=]
> +y = "\
> +hello\r\n\
> +"
> +return debug.getinfo(1).currentline
> +]]
> +
> +for _, n in pairs{"\n", "\r", "\n\r", "\r\n"} do
> +  local prog, nn = string.gsub(prog, "\n", n)
> +  assert(dostring(prog) == nn)
> +  assert(_G.x == "hi\n" and _G.y == "\nhello\r\n\n")
> +end
> +
> +
> +-- testing comments and strings with long brackets
> +a = [==[]=]==]
> +assert(a == "]=")
> +
> +a = [==[[===[[=[]]=][====[]]===]===]==]
> +assert(a == "[===[[=[]]=][====[]]===]===")
> +
> +a = [====[[===[[=[]]=][====[]]===]===]====]
> +assert(a == "[===[[=[]]=][====[]]===]===")
> +
> +a = [=[]]]]]]]]]=]
> +assert(a == "]]]]]]]]")
> +
> +
> +--[===[
> +x y z [==[ blu foo
> +]==
> +]
> +]=]==]
> +error error]=]===]
> +
> +-- generate all strings of four of these chars
> +local x = {"=", "[", "]", "\n"}
> +local len = 4
> +local function gen (c, n)
> +  if n==0 then coroutine.yield(c)
> +  else
> +    for _, a in pairs(x) do
> +      gen(c..a, n-1)
> +    end
> +  end
> +end
> +
> +for s in coroutine.wrap(function () gen("", len) end) do
> +  assert(s == loadstring("return [====[\n"..s.."]====]")())
> +end
> +
> +
> +-- testing decimal point locale
> +if os.setlocale("pt_BR") or os.setlocale("ptb") then
> +  assert(tonumber("3,4") == 3.4 and tonumber"3.4" == nil)
> +  assert(assert(loadstring("return 3.4"))() == 3.4)
> +  assert(assert(loadstring("return .4,3"))() == .4)
> +  assert(assert(loadstring("return 4."))() == 4.)
> +  assert(assert(loadstring("return 4.+.5"))() == 4.5)
> +  local a,b = loadstring("return 4.5.")
> +  assert(string.find(b, "'4%.5%.'"))
> +  assert(os.setlocale("C"))
> +else
> +  (Message or print)(
> +   '\a\n >>> pt_BR locale not available: skipping decimal point tests <<<\n\a')
> +end
> +
> +
> +print('OK')
> diff --git a/test/PUC-Lua-5.1-tests/locals.lua b/test/PUC-Lua-5.1-tests/locals.lua
> new file mode 100644
> index 0000000..011645a
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/locals.lua
> @@ -0,0 +1,127 @@
> +print('testing local variables plus some extra stuff')
> +
> +do
> +  local i = 10
> +  do local i = 100; assert(i==100) end
> +  do local i = 1000; assert(i==1000) end
> +  assert(i == 10)
> +  if i ~= 10 then
> +    local i = 20
> +  else
> +    local i = 30
> +    assert(i == 30)
> +  end
> +end
> +
> +
> +
> +f = nil
> +
> +local f
> +x = 1
> +
> +a = nil
> +loadstring('local a = {}')()
> +assert(type(a) ~= 'table')
> +
> +function f (a)
> +  local _1, _2, _3, _4, _5
> +  local _6, _7, _8, _9, _10
> +  local x = 3
> +  local b = a
> +  local c,d = a,b
> +  if (d == b) then
> +    local x = 'q'
> +    x = b
> +    assert(x == 2)
> +  else
> +    assert(nil)
> +  end
> +  assert(x == 3)
> +  local f = 10
> +end
> +
> +local b=10
> +local a; repeat local b; a,b=1,2; assert(a+1==b); until a+b==3
> +
> +
> +assert(x == 1)
> +
> +f(2)
> +assert(type(f) == 'function')
> +
> +
> +-- testing globals ;-)
> +do
> +  local f = {}
> +  local _G = _G
> +  for i=1,10 do f[i] = function (x) A=A+1; return A, _G.getfenv(x) end end
> +  A=10; assert(f[1]() == 11)
> +  for i=1,10 do assert(setfenv(f[i], {A=i}) == f[i]) end
> +  assert(f[3]() == 4 and A == 11)
> +  local a,b = f[8](1)
> +  assert(b.A == 9)
> +  a,b = f[8](0)
> +  assert(b.A == 11)   -- `real' global
> +  local g
> +  local function f () assert(setfenv(2, {a='10'}) == g) end
> +  g = function () f(); _G.assert(_G.getfenv(1).a == '10') end
> +  g(); assert(getfenv(g).a == '10')
> +end
> +
> +-- test for global table of loaded chunks
> +local function foo (s)
> +  return loadstring(s)
> +end
> +
> +assert(getfenv(foo("")) == _G)
> +local a = {loadstring = loadstring}
> +setfenv(foo, a)
> +assert(getfenv(foo("")) == _G)
> +setfenv(0, a)  -- change global environment
> +assert(getfenv(foo("")) == a)
> +setfenv(0, _G)
> +
> +
> +-- testing limits for special instructions
> +
> +local a
> +local p = 4
> +for i=2,31 do
> +  for j=-3,3 do
> +    assert(loadstring(string.format([[local a=%s;a=a+
> +                                            %s;
> +                                      assert(a
> +                                      ==2^%s)]], j, p-j, i))) ()
> +    assert(loadstring(string.format([[local a=%s;
> +                                      a=a-%s;
> +                                      assert(a==-2^%s)]], -j, p-j, i))) ()
> +    assert(loadstring(string.format([[local a,b=0,%s;
> +                                      a=b-%s;
> +                                      assert(a==-2^%s)]], -j, p-j, i))) ()
> +  end
> +  p =2*p
> +end
> +
> +print'+'
> +
> +
> +if rawget(_G, "querytab") then
> +  -- testing clearing of dead elements from tables
> +  collectgarbage("stop")   -- stop GC
> +  local a = {[{}] = 4, [3] = 0, alo = 1,
> +             a1234567890123456789012345678901234567890 = 10}
> +
> +  local t = querytab(a)
> +
> +  for k,_ in pairs(a) do a[k] = nil end
> +  collectgarbage()   -- restore GC and collect dead fiels in `a'
> +  for i=0,t-1 do
> +    local k = querytab(a, i)
> +    assert(k == nil or type(k) == 'number' or k == 'alo')
> +  end
> +end
> +
> +print('OK')
> +
> +return 5,f
> diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua
> new file mode 100644
> index 0000000..f520896
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/main.lua
> @@ -0,0 +1,159 @@
> +# testing special comment on first line
> +
> +print ("testing lua.c options")
> +
> +assert(os.execute() ~= 0)   -- machine has a system command
> +
> +prog = os.tmpname()
> +otherprog = os.tmpname()
> +out = os.tmpname()
> +
> +do
> +  local i = 0
> +  while arg[i] do i=i-1 end
> +  progname = '"'..arg[i+1]..'"'
> +end
> +print(progname)
> +
> +local prepfile = function (s, p)
> +  p = p or prog
> +  io.output(p)
> +  io.write(s)
> +  assert(io.close())
> +end
> +
> +function checkout (s)
> +  io.input(out)
> +  local t = io.read("*a")
> +  io.input():close()
> +  assert(os.remove(out))
> +  if s ~= t then print(string.format("'%s' - '%s'\n", s, t)) end
> +  assert(s == t)
> +  return t
> +end
> +
> +function auxrun (...)
> +  local s = string.format(...)
> +  s = string.gsub(s, "lua", progname, 1)
> +  return os.execute(s)
> +end
> +
> +function RUN (...)
> +  assert(auxrun(...) == 0)
> +end
> +
> +function NoRun (...)
> +  print("\n(the next error is expected by the test)")
> +  assert(auxrun(...) ~= 0)
> +end
> +
> +-- test 2 files
> +prepfile("print(1); a=2")
> +prepfile("print(a)", otherprog)
> +RUN("lua -l %s -l%s -lstring -l io %s > %s", prog, otherprog, otherprog, out)
> +checkout("1\n2\n2\n")
> +
> +local a = [[
> +  assert(table.getn(arg) == 3 and arg[1] == 'a' and
> +         arg[2] == 'b' and arg[3] == 'c')
> +  assert(arg[-1] == '--' and arg[-2] == "-e " and arg[-3] == %s)
> +  assert(arg[4] == nil and arg[-4] == nil)
> +  local a, b, c = ...
> +  assert(... == 'a' and a == 'a' and b == 'b' and c == 'c')
> +]]
> +a = string.format(a, progname)
> +prepfile(a)
> +RUN('lua "-e " -- %s a b c', prog)
> +
> +prepfile"assert(arg==nil)"
> +prepfile("assert(arg)", otherprog)
> +RUN("lua -l%s - < %s", prog, otherprog)
> +
> +prepfile""
> +RUN("lua - < %s > %s", prog, out)
> +checkout("")
> +
> +-- test many arguments
> +prepfile[[print(({...})[30])]]
> +RUN("lua %s %s > %s", prog, string.rep(" a", 30), out)
> +checkout("a\n")
> +
> +RUN([[lua "-eprint(1)" -ea=3 -e "print(a)" > %s]], out)
> +checkout("1\n3\n")
> +
> +prepfile[[
> +  print(
> +1, a
> +)
> +]]
> +RUN("lua - < %s > %s", prog, out)
> +checkout("1\tnil\n")
> +
> +prepfile[[
> += (6*2-6) -- ===
> +a
> += 10
> +print(a)
> += a]]
> +RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
> +checkout("6\n10\n10\n\n")
> +
> +prepfile("a = [[b\nc\nd\ne]]\n=a")
> +print(prog)
> +RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
> +checkout("b\nc\nd\ne\n\n")
> +
> +prompt = "alo"
> +prepfile[[ --
> +a = 2
> +]]
> +RUN([[lua "-e_PROMPT='%s'" -i < %s > %s]], prompt, prog, out)
> +checkout(string.rep(prompt, 3).."\n")
> +
> +s = [=[ --
> +function f ( x )
> +  local a = [[
> +xuxu
> +]]
> +  local b = "\
> +xuxu\n"
> +  if x == 11 then return 1 , 2 end  --[[ test multiple returns ]]
> +  return x + 1
> +  --\\
> +end
> +=( f( 10 ) )
> +assert( a == b )
> +=f( 11 )  ]=]
> +s = string.gsub(s, ' ', '\n\n')
> +prepfile(s)
> +RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
> +checkout("11\n1\t2\n\n")
> +
> +prepfile[[#comment in 1st line without \n at the end]]
> +RUN("lua %s", prog)
> +
> +prepfile("#comment with a binary file\n"..string.dump(loadstring("print(1)")))
> +RUN("lua %s > %s", prog, out)
> +checkout("1\n")
> +
> +prepfile("#comment with a binary file\r\n"..string.dump(loadstring("print(1)")))
> +RUN("lua %s > %s", prog, out)
> +checkout("1\n")
> +
> +-- close Lua with an open file
> +prepfile(string.format([[io.output(%q); io.write('alo')]], out))
> +RUN("lua %s", prog)
> +checkout('alo')
> +
> +assert(os.remove(prog))
> +assert(os.remove(otherprog))
> +assert(not os.remove(out))
> +
> +RUN("lua -v")
> +
> +NoRun("lua -h")
> +NoRun("lua -e")
> +NoRun("lua -e a")
> +NoRun("lua -f")
> +
> +print("OK")
> diff --git a/test/PUC-Lua-5.1-tests/math.lua b/test/PUC-Lua-5.1-tests/math.lua
> new file mode 100644
> index 0000000..5076f38
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/math.lua
> @@ -0,0 +1,208 @@
> +print("testing numbers and math lib")
> +
> +do
> +  local a,b,c = "2", " 3e0 ", " 10  "
> +  assert(a+b == 5 and -b == -3 and b+"2" == 5 and "10"-c == 0)
> +  assert(type(a) == 'string' and type(b) == 'string' and type(c) == 'string')
> +  assert(a == "2" and b == " 3e0 " and c == " 10  " and -c == -"  10 ")
> +  assert(c%a == 0 and a^b == 8)
> +end
> +
> +
> +do
> +  local a,b = math.modf(3.5)
> +  assert(a == 3 and b == 0.5)
> +  assert(math.huge > 10e30)
> +  assert(-math.huge < -10e30)
> +end
> +
> +function f(...)
> +  if select('#', ...) == 1 then
> +    return (...)
> +  else
> +    return "***"
> +  end
> +end
> +
> +assert(tonumber{} == nil)
> +assert(tonumber'+0.01' == 1/100 and tonumber'+.01' == 0.01 and
> +       tonumber'.01' == 0.01    and tonumber'-1.' == -1 and
> +       tonumber'+1.' == 1)
> +assert(tonumber'+ 0.01' == nil and tonumber'+.e1' == nil and
> +       tonumber'1e' == nil     and tonumber'1.0e+' == nil and
> +       tonumber'.' == nil)
> +assert(tonumber('-12') == -10-2)
> +assert(tonumber('-1.2e2') == - - -120)
> +assert(f(tonumber('1  a')) == nil)
> +assert(f(tonumber('e1')) == nil)
> +assert(f(tonumber('e  1')) == nil)
> +assert(f(tonumber(' 3.4.5 ')) == nil)
> +assert(f(tonumber('')) == nil)
> +assert(f(tonumber('', 8)) == nil)
> +assert(f(tonumber('  ')) == nil)
> +assert(f(tonumber('  ', 9)) == nil)
> +assert(f(tonumber('99', 8)) == nil)
> +assert(tonumber('  1010  ', 2) == 10)
> +assert(tonumber('10', 36) == 36)
> +--assert(tonumber('\n  -10  \n', 36) == -36)
> +--assert(tonumber('-fFfa', 16) == -(10+(16*(15+(16*(15+(16*15)))))))
> +assert(tonumber('fFfa', 15) == nil)
> +--assert(tonumber(string.rep('1', 42), 2) + 1 == 2^42)
> +assert(tonumber(string.rep('1', 32), 2) + 1 == 2^32)
> +--assert(tonumber('-fffffFFFFF', 16)-1 == -2^40)
> +assert(tonumber('ffffFFFF', 16)+1 == 2^32)
> +
> +assert(1.1 == 1.+.1)
> +assert(100.0 == 1E2 and .01 == 1e-2)
> +assert(1111111111111111-1111111111111110== 1000.00e-03)
> +--     1234567890123456
> +assert(1.1 == '1.'+'.1')
> +assert('1111111111111111'-'1111111111111110' == tonumber"  +0.001e+3 \n\t")
> +
> +function eq (a,b,limit)
> +  if not limit then limit = 10E-10 end
> +  return math.abs(a-b) <= limit
> +end
> +
> +assert(0.1e-30 > 0.9E-31 and 0.9E30 < 0.1e31)
> +
> +assert(0.123456 > 0.123455)
> +
> +assert(tonumber('+1.23E30') == 1.23*10^30)
> +
> +-- testing order operators
> +assert(not(1<1) and (1<2) and not(2<1))
> +assert(not('a'<'a') and ('a'<'b') and not('b'<'a'))
> +assert((1<=1) and (1<=2) and not(2<=1))
> +assert(('a'<='a') and ('a'<='b') and not('b'<='a'))
> +assert(not(1>1) and not(1>2) and (2>1))
> +assert(not('a'>'a') and not('a'>'b') and ('b'>'a'))
> +assert((1>=1) and not(1>=2) and (2>=1))
> +assert(('a'>='a') and not('a'>='b') and ('b'>='a'))
> +
> +-- testing mod operator
> +assert(-4%3 == 2)
> +assert(4%-3 == -2)
> +assert(math.pi - math.pi % 1 == 3)
> +assert(math.pi - math.pi % 0.001 == 3.141)
> +
> +local function testbit(a, n)
> +  return a/2^n % 2 >= 1
> +end
> +
> +assert(eq(math.sin(-9.8)^2 + math.cos(-9.8)^2, 1))
> +assert(eq(math.tan(math.pi/4), 1))
> +assert(eq(math.sin(math.pi/2), 1) and eq(math.cos(math.pi/2), 0))
> +assert(eq(math.atan(1), math.pi/4) and eq(math.acos(0), math.pi/2) and
> +       eq(math.asin(1), math.pi/2))
> +assert(eq(math.deg(math.pi/2), 90) and eq(math.rad(90), math.pi/2))
> +assert(math.abs(-10) == 10)
> +assert(eq(math.atan2(1,0), math.pi/2))
> +assert(math.ceil(4.5) == 5.0)
> +assert(math.floor(4.5) == 4.0)
> +assert(math.mod(10,3) == 1)
> +assert(eq(math.sqrt(10)^2, 10))
> +assert(eq(math.log10(2), math.log(2)/math.log(10)))
> +assert(eq(math.exp(0), 1))
> +assert(eq(math.sin(10), math.sin(10%(2*math.pi))))
> +local v,e = math.frexp(math.pi)
> +assert(eq(math.ldexp(v,e), math.pi))
> +
> +assert(eq(math.tanh(3.5), math.sinh(3.5)/math.cosh(3.5)))
> +
> +assert(tonumber(' 1.3e-2 ') == 1.3e-2)
> +assert(tonumber(' -1.00000000000001 ') == -1.00000000000001)
> +
> +-- testing constant limits
> +-- 2^23 = 8388608
> +assert(8388609 + -8388609 == 0)
> +assert(8388608 + -8388608 == 0)
> +assert(8388607 + -8388607 == 0)
> +
> +if rawget(_G, "_soft") then return end
> +
> +f = io.tmpfile()
> +assert(f)
> +f:write("a = {")
> +i = 1
> +repeat
> +  f:write("{", math.sin(i), ", ", math.cos(i), ", ", i/3, "},\n")
> +  i=i+1
> +until i > 1000
> +f:write("}")
> +f:seek("set", 0)
> +assert(loadstring(f:read('*a')))()
> +assert(f:close())
> +
> +assert(eq(a[300][1], math.sin(300)))
> +assert(eq(a[600][1], math.sin(600)))
> +assert(eq(a[500][2], math.cos(500)))
> +assert(eq(a[800][2], math.cos(800)))
> +assert(eq(a[200][3], 200/3))
> +assert(eq(a[1000][3], 1000/3, 0.001))
> +print('+')
> +
> +do   -- testing NaN
> +  local NaN = 10e500 - 10e400
> +  assert(NaN ~= NaN)
> +  assert(not (NaN < NaN))
> +  assert(not (NaN <= NaN))
> +  assert(not (NaN > NaN))
> +  assert(not (NaN >= NaN))
> +  assert(not (0 < NaN))
> +  assert(not (NaN < 0))
> +  local a = {}
> +  assert(not pcall(function () a[NaN] = 1 end))
> +  assert(a[NaN] == nil)
> +  a[1] = 1
> +  assert(not pcall(function () a[NaN] = 1 end))
> +  assert(a[NaN] == nil)
> +end
> +
> +require "checktable"
> +stat(a)
> +
> +a = nil
> +
> +-- testing implicit convertions
> +
> +local a,b = '10', '20'
> +assert(a*b == 200 and a+b == 30 and a-b == -10 and a/b == 0.5 and -b == -20)
> +assert(a == '10' and b == '20')
> +
> +
> +math.randomseed(0)
> +
> +local i = 0
> +local Max = 0
> +local Min = 2
> +repeat
> +  local t = math.random()
> +  Max = math.max(Max, t)
> +  Min = math.min(Min, t)
> +  i=i+1
> +  flag = eq(Max, 1, 0.001) and eq(Min, 0, 0.001)
> +until flag or i>10000
> +assert(0 <= Min and Max<1)
> +assert(flag);
> +
> +for i=1,10 do
> +  local t = math.random(5)
> +  assert(1 <= t and t <= 5)
> +end
> +
> +i = 0
> +Max = -200
> +Min = 200
> +repeat
> +  local t = math.random(-10,0)
> +  Max = math.max(Max, t)
> +  Min = math.min(Min, t)
> +  i=i+1
> +  flag = (Max == 0 and Min == -10)
> +until flag or i>10000
> +assert(-10 <= Min and Max<=0)
> +assert(flag);
> +
> +
> +print('OK')
> diff --git a/test/PUC-Lua-5.1-tests/nextvar.lua b/test/PUC-Lua-5.1-tests/nextvar.lua
> new file mode 100644
> index 0000000..7ceaa75
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/nextvar.lua
> @@ -0,0 +1,396 @@
> +print('testing tables, next, and for')
> +
> +local a = {}
> +
> +-- make sure table has lots of space in hash part
> +for i=1,100 do a[i.."+"] = true end
> +for i=1,100 do a[i.."+"] = nil end
> +-- fill hash part with numeric indices testing size operator
> +for i=1,100 do
> +  a[i] = true
> +  assert(#a == i)
> +end
> +
> +
> +if T then
> +-- testing table sizes
> +
> +local l2 = math.log(2)
> +local function log2 (x) return math.log(x)/l2 end
> +
> +local function mp2 (n)   -- minimum power of 2 >= n
> +  local mp = 2^math.ceil(log2(n))
> +  assert(n == 0 or (mp/2 < n and n <= mp))
> +  return mp
> +end
> +
> +local function fb (n)
> +  local r, nn = T.int2fb(n)
> +  assert(r < 256)
> +  return nn
> +end
> +
> +-- test fb function
> +local a = 1
> +local lim = 2^30
> +while a < lim do
> +  local n = fb(a)
> +  assert(a <= n and n <= a*1.125)
> +  a = math.ceil(a*1.3)
> +end
> +
> +
> +local function check (t, na, nh)
> +  local a, h = T.querytab(t)
> +  if a ~= na or h ~= nh then
> +    print(na, nh, a, h)
> +    assert(nil)
> +  end
> +end
> +
> +-- testing constructor sizes
> +local lim = 40
> +local s = 'return {'
> +for i=1,lim do
> +  s = s..i..','
> +  local s = s
> +  for k=0,lim do
> +    local t = loadstring(s..'}')()
> +    assert(#t == i)
> +    check(t, fb(i), mp2(k))
> +    s = string.format('%sa%d=%d,', s, k, k)
> +  end
> +end
> +
> +
> +-- tests with unknown number of elements
> +local a = {}
> +for i=1,lim do a[i] = i end   -- build auxiliary table
> +for k=0,lim do
> +  local a = {unpack(a,1,k)}
> +  assert(#a == k)
> +  check(a, k, 0)
> +  a = {1,2,3,unpack(a,1,k)}
> +  check(a, k+3, 0)
> +  assert(#a == k + 3)
> +end
> +
> +
> +print'+'
> +
> +-- testing tables dynamically built
> +local lim = 130
> +local a = {}; a[2] = 1; check(a, 0, 1)
> +a = {}; a[0] = 1; check(a, 0, 1); a[2] = 1; check(a, 0, 2)
> +a = {}; a[0] = 1; a[1] = 1; check(a, 1, 1)
> +a = {}
> +for i = 1,lim do
> +  a[i] = 1
> +  assert(#a == i)
> +  check(a, mp2(i), 0)
> +end
> +
> +a = {}
> +for i = 1,lim do
> +  a['a'..i] = 1
> +  assert(#a == 0)
> +  check(a, 0, mp2(i))
> +end
> +
> +a = {}
> +for i=1,16 do a[i] = i end
> +check(a, 16, 0)
> +for i=1,11 do a[i] = nil end
> +for i=30,40 do a[i] = nil end   -- force a rehash (?)
> +check(a, 0, 8)
> +a[10] = 1
> +for i=30,40 do a[i] = nil end   -- force a rehash (?)
> +check(a, 0, 8)
> +for i=1,14 do a[i] = nil end
> +for i=30,50 do a[i] = nil end   -- force a rehash (?)
> +check(a, 0, 4)
> +
> +-- reverse filling
> +for i=1,lim do
> +  local a = {}
> +  for i=i,1,-1 do a[i] = i end   -- fill in reverse
> +  check(a, mp2(i), 0)
> +end
> +
> +-- size tests for vararg
> +lim = 35
> +function foo (n, ...)
> +  local arg = {...}
> +  check(arg, n, 0)
> +  assert(select('#', ...) == n)
> +  arg[n+1] = true
> +  check(arg, mp2(n+1), 0)
> +  arg.x = true
> +  check(arg, mp2(n+1), 1)
> +end
> +local a = {}
> +for i=1,lim do a[i] = true; foo(i, unpack(a)) end
> +
> +end
> +
> +
> +-- test size operation on empty tables
> +assert(#{} == 0)
> +assert(#{nil} == 0)
> +assert(#{nil, nil} == 0)
> +assert(#{nil, nil, nil} == 0)
> +assert(#{nil, nil, nil, nil} == 0)
> +print'+'
> +
> +
> +local nofind = {}
> +
> +a,b,c = 1,2,3
> +a,b,c = nil
> +
> +local function find (name)
> +  local n,v
> +  while 1 do
> +    n,v = next(_G, n)
> +    if not n then return nofind end
> +    assert(v ~= nil)
> +    if n == name then return v end
> +  end
> +end
> +
> +local function find1 (name)
> +  for n,v in pairs(_G) do
> +    if n==name then return v end
> +  end
> +  return nil  -- not found
> +end
> +
> +do   -- create 10000 new global variables
> +  for i=1,10000 do _G[i] = i end
> +end
> +
> +
> +a = {x=90, y=8, z=23}
> +assert(table.foreach(a, function(i,v) if i=='x' then return v end end) == 90)
> +assert(table.foreach(a, function(i,v) if i=='a' then return v end end) == nil)
> +table.foreach({}, error)
> +
> +table.foreachi({x=10, y=20}, error)
> +local a = {n = 1}
> +table.foreachi({n=3}, function (i, v)
> +  assert(a.n == i and not v)
> +  a.n=a.n+1
> +end)
> +a = {10,20,30,nil,50}
> +table.foreachi(a, function (i,v) assert(a[i] == v) end)
> +assert(table.foreachi({'a', 'b', 'c'}, function (i,v)
> +         if i==2 then return v end
> +       end) == 'b')
> +
> +
> +assert(print==find("print") and print == find1("print"))
> +assert(_G["print"]==find("print"))
> +assert(assert==find1("assert"))
> +assert(nofind==find("return"))
> +assert(not find1("return"))
> +_G["ret" .. "urn"] = nil
> +assert(nofind==find("return"))
> +_G["xxx"] = 1
> +assert(xxx==find("xxx"))
> +print('+')
> +
> +a = {}
> +for i=0,10000 do
> +  if math.mod(i,10) ~= 0 then
> +    a['x'..i] = i
> +  end
> +end
> +
> +n = {n=0}
> +for i,v in pairs(a) do
> +  n.n = n.n+1
> +  assert(i and v and a[i] == v)
> +end
> +assert(n.n == 9000)
> +a = nil
> +
> +-- remove those 10000 new global variables
> +for i=1,10000 do _G[i] = nil end
> +
> +do   -- clear global table
> +  local a = {}
> +  local preserve = {io = 1, string = 1, debug = 1, os = 1,
> +                    coroutine = 1, table = 1, math = 1}
> +  for n,v in pairs(_G) do a[n]=v end
> +  for n,v in pairs(a) do
> +    if not preserve[n] and type(v) ~= "function" and
> +       not string.find(n, "^[%u_]") then
> +     _G[n] = nil
> +    end
> +    collectgarbage()
> +  end
> +end
> +
> +local function foo ()
> +  local getfenv, setfenv, assert, next =
> +        getfenv, setfenv, assert, next
> +  local n = {gl1=3}
> +  setfenv(foo, n)
> +  assert(getfenv(foo) == getfenv(1))
> +  assert(getfenv(foo) == n)
> +  assert(print == nil and gl1 == 3)
> +  gl1 = nil
> +  gl = 1
> +  assert(n.gl == 1 and next(n, 'gl') == nil)
> +end
> +foo()
> +
> +print'+'
> +
> +local function checknext (a)
> +  local b = {}
> +  table.foreach(a, function (k,v) b[k] = v end)
> +  for k,v in pairs(b) do assert(a[k] == v) end
> +  for k,v in pairs(a) do assert(b[k] == v) end
> +  b = {}
> +  do local k,v = next(a); while k do b[k] = v; k,v = next(a,k) end end
> +  for k,v in pairs(b) do assert(a[k] == v) end
> +  for k,v in pairs(a) do assert(b[k] == v) end
> +end
> +
> +checknext{1,x=1,y=2,z=3}
> +checknext{1,2,x=1,y=2,z=3}
> +checknext{1,2,3,x=1,y=2,z=3}
> +checknext{1,2,3,4,x=1,y=2,z=3}
> +checknext{1,2,3,4,5,x=1,y=2,z=3}
> +
> +assert(table.getn{} == 0)
> +assert(table.getn{[-1] = 2} == 0)
> +assert(table.getn{1,2,3,nil,nil} == 3)
> +for i=0,40 do
> +  local a = {}
> +  for j=1,i do a[j]=j end
> +  assert(table.getn(a) == i)
> +end
> +
> +
> +assert(table.maxn{} == 0)
> +assert(table.maxn{["1000"] = true} == 0)
> +assert(table.maxn{["1000"] = true, [24.5] = 3} == 24.5)
> +assert(table.maxn{[1000] = true} == 1000)
> +assert(table.maxn{[10] = true, [100*math.pi] = print} == 100*math.pi)
> +
> +
> +-- int overflow
> +a = {}
> +for i=0,50 do a[math.pow(2,i)] = true end
> +assert(a[table.getn(a)])
> +
> +print("+")
> +
> +
> +-- erasing values
> +local t = {[{1}] = 1, [{2}] = 2, [string.rep("x ", 4)] = 3,
> +           [100.3] = 4, [4] = 5}
> +
> +local n = 0
> +for k, v in pairs( t ) do
> +  n = n+1
> +  assert(t[k] == v)
> +  t[k] = nil
> +  collectgarbage()
> +  assert(t[k] == nil)
> +end
> +assert(n == 5)
> +
> +
> +local function test (a)
> +  table.insert(a, 10); table.insert(a, 2, 20);
> +  table.insert(a, 1, -1); table.insert(a, 40);
> +  table.insert(a, table.getn(a)+1, 50)
> +  table.insert(a, 2, -2)
> +  assert(table.remove(a,1) == -1)
> +  assert(table.remove(a,1) == -2)
> +  assert(table.remove(a,1) == 10)
> +  assert(table.remove(a,1) == 20)
> +  assert(table.remove(a,1) == 40)
> +  assert(table.remove(a,1) == 50)
> +  assert(table.remove(a,1) == nil)
> +end
> +
> +a = {n=0, [-7] = "ban"}
> +test(a)
> +assert(a.n == 0 and a[-7] == "ban")
> +
> +a = {[-7] = "ban"};
> +test(a)
> +assert(a.n == nil and table.getn(a) == 0 and a[-7] == "ban")
> +
> +
> +table.insert(a, 1, 10); table.insert(a, 1, 20); table.insert(a, 1, -1)
> +assert(table.remove(a) == 10)
> +assert(table.remove(a) == 20)
> +assert(table.remove(a) == -1)
> +
> +a = {'c', 'd'}
> +table.insert(a, 3, 'a')
> +table.insert(a, 'b')
> +assert(table.remove(a, 1) == 'c')
> +assert(table.remove(a, 1) == 'd')
> +assert(table.remove(a, 1) == 'a')
> +assert(table.remove(a, 1) == 'b')
> +assert(table.getn(a) == 0 and a.n == nil)
> +print("+")
> +
> +a = {}
> +for i=1,1000 do
> +  a[i] = i; a[i-1] = nil
> +end
> +assert(next(a,nil) == 1000 and next(a,1000) == nil)
> +
> +assert(next({}) == nil)
> +assert(next({}, nil) == nil)
> +
> +for a,b in pairs{} do error"not here" end
> +for i=1,0 do error'not here' end
> +for i=0,1,-1 do error'not here' end
> +a = nil; for i=1,1 do assert(not a); a=1 end; assert(a)
> +a = nil; for i=1,1,-1 do assert(not a); a=1 end; assert(a)
> +
> +a = 0; for i=0, 1, 0.1 do a=a+1 end; assert(a==11)
> +-- precision problems
> +--a = 0; for i=1, 0, -0.01 do a=a+1 end; assert(a==101)
> +a = 0; for i=0, 0.999999999, 0.1 do a=a+1 end; assert(a==10)
> +a = 0; for i=1, 1, 1 do a=a+1 end; assert(a==1)
> +a = 0; for i=1e10, 1e10, -1 do a=a+1 end; assert(a==1)
> +a = 0; for i=1, 0.99999, 1 do a=a+1 end; assert(a==0)
> +a = 0; for i=99999, 1e5, -1 do a=a+1 end; assert(a==0)
> +a = 0; for i=1, 0.99999, -1 do a=a+1 end; assert(a==1)
> +
> +-- conversion
> +a = 0; for i="10","1","-2" do a=a+1 end; assert(a==5)
> +
> +
> +collectgarbage()
> +
> +
> +-- testing generic 'for'
> +
> +local function f (n, p)
> +  local t = {}; for i=1,p do t[i] = i*10 end
> +  return function (_,n)
> +           if n > 0 then
> +             n = n-1
> +             return n, unpack(t)
> +           end
> +         end, nil, n
> +end
> +
> +local x = 0
> +for n,a,b,c,d in f(5,3) do
> +  x = x+1
> +  assert(a == 10 and b == 20 and c == 30 and d == nil)
> +end
> +assert(x == 5)
> +
> +print"OK"
> diff --git a/test/PUC-Lua-5.1-tests/pm.lua b/test/PUC-Lua-5.1-tests/pm.lua
> new file mode 100644
> index 0000000..fa125dc
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/pm.lua
> @@ -0,0 +1,273 @@
> +print('testing pattern matching')
> +
> +function f(s, p)
> +  local i,e = string.find(s, p)
> +  if i then return string.sub(s, i, e) end
> +end
> +
> +function f1(s, p)
> +  p = string.gsub(p, "%%([0-9])", function (s) return "%" .. (s+1) end)
> +  p = string.gsub(p, "^(^?)", "%1()", 1)
> +  p = string.gsub(p, "($?)$", "()%1", 1)
> +  local t = {string.match(s, p)}
> +  return string.sub(s, t[1], t[#t] - 1)
> +end
> +
> +a,b = string.find('', '')    -- empty patterns are tricky
> +assert(a == 1 and b == 0);
> +a,b = string.find('alo', '')
> +assert(a == 1 and b == 0)
> +a,b = string.find('a\0o a\0o a\0o', 'a', 1)   -- first position
> +assert(a == 1 and b == 1)
> +a,b = string.find('a\0o a\0o a\0o', 'a\0o', 2)   -- starts in the midle
> +assert(a == 5 and b == 7)
> +a,b = string.find('a\0o a\0o a\0o', 'a\0o', 9)   -- starts in the midle
> +assert(a == 9 and b == 11)
> +a,b = string.find('a\0a\0a\0a\0\0ab', '\0ab', 2);  -- finds at the end
> +assert(a == 9 and b == 11);
> +a,b = string.find('a\0a\0a\0a\0\0ab', 'b')    -- last position
> +assert(a == 11 and b == 11)
> +assert(string.find('a\0a\0a\0a\0\0ab', 'b\0') == nil)   -- check ending
> +assert(string.find('', '\0') == nil)
> +assert(string.find('alo123alo', '12') == 4)
> +assert(string.find('alo123alo', '^12') == nil)
> +
> +assert(f('aloALO', '%l*') == 'alo')
> +assert(f('aLo_ALO', '%a*') == 'aLo')
> +
> +assert(f('aaab', 'a*') == 'aaa');
> +assert(f('aaa', '^.*$') == 'aaa');
> +assert(f('aaa', 'b*') == '');
> +assert(f('aaa', 'ab*a') == 'aa')
> +assert(f('aba', 'ab*a') == 'aba')
> +assert(f('aaab', 'a+') == 'aaa')
> +assert(f('aaa', '^.+$') == 'aaa')
> +assert(f('aaa', 'b+') == nil)
> +assert(f('aaa', 'ab+a') == nil)
> +assert(f('aba', 'ab+a') == 'aba')
> +assert(f('a$a', '.$') == 'a')
> +assert(f('a$a', '.%$') == 'a$')
> +assert(f('a$a', '.$.') == 'a$a')
> +assert(f('a$a', '$$') == nil)
> +assert(f('a$b', 'a$') == nil)
> +assert(f('a$a', '$') == '')
> +assert(f('', 'b*') == '')
> +assert(f('aaa', 'bb*') == nil)
> +assert(f('aaab', 'a-') == '')
> +assert(f('aaa', '^.-$') == 'aaa')
> +assert(f('aabaaabaaabaaaba', 'b.*b') == 'baaabaaabaaab')
> +assert(f('aabaaabaaabaaaba', 'b.-b') == 'baaab')
> +assert(f('alo xo', '.o$') == 'xo')
> +assert(f(' \n isto � assim', '%S%S*') == 'isto')
> +assert(f(' \n isto � assim', '%S*$') == 'assim')
> +assert(f(' \n isto � assim', '[a-z]*$') == 'assim')
> +assert(f('um caracter ? extra', '[^%sa-z]') == '?')
> +assert(f('', 'a?') == '')
> +assert(f('�', '�?') == '�')
> +assert(f('�bl', '�?b?l?') == '�bl')
> +assert(f('  �bl', '�?b?l?') == '')
> +assert(f('aa', '^aa?a?a') == 'aa')
> +assert(f(']]]�b', '[^]]') == '�')
> +assert(f("0alo alo", "%x*") == "0a")
> +assert(f("alo alo", "%C+") == "alo alo")
> +print('+')
> +
> +assert(f1('alo alx 123 b\0o b\0o', '(..*) %1') == "b\0o b\0o")
> +assert(f1('axz123= 4= 4 34', '(.+)=(.*)=%2 %1') == '3= 4= 4 3')
> +assert(f1('=======', '^(=*)=%1$') == '=======')
> +assert(string.match('==========', '^([=]*)=%1$') == nil)
> +
> +local function range (i, j)
> +  if i <= j then
> +    return i, range(i+1, j)
> +  end
> +end
> +
> +local abc = string.char(range(0, 255));
> +
> +assert(string.len(abc) == 256)
> +
> +function strset (p)
> +  local res = {s=''}
> +  string.gsub(abc, p, function (c) res.s = res.s .. c end)
> +  return res.s
> +end;
> +
> +assert(string.len(strset('[\200-\210]')) == 11)
> +
> +assert(strset('[a-z]') == "abcdefghijklmnopqrstuvwxyz")
> +assert(strset('[a-z%d]') == strset('[%da-uu-z]'))
> +assert(strset('[a-]') == "-a")
> +assert(strset('[^%W]') == strset('[%w]'))
> +assert(strset('[]%%]') == '%]')
> +assert(strset('[a%-z]') == '-az')
> +assert(strset('[%^%[%-a%]%-b]') == '-[]^ab')
> +assert(strset('%Z') == strset('[\1-\255]'))
> +assert(strset('.') == strset('[\1-\255%z]'))
> +print('+');
> +
> +assert(string.match("alo xyzK", "(%w+)K") == "xyz")
> +assert(string.match("254 K", "(%d*)K") == "")
> +assert(string.match("alo ", "(%w*)$") == "")
> +assert(string.match("alo ", "(%w+)$") == nil)
> +assert(string.find("(�lo)", "%(�") == 1)
> +local a, b, c, d, e = string.match("�lo alo", "^(((.).).* (%w*))$")
> +assert(a == '�lo alo' and b == '�l' and c == '�' and d == 'alo' and e == nil)
> +a, b, c, d  = string.match('0123456789', '(.+(.?)())')
> +assert(a == '0123456789' and b == '' and c == 11 and d == nil)
> +print('+')
> +
> +assert(string.gsub('�lo �lo', '�', 'x') == 'xlo xlo')
> +assert(string.gsub('alo �lo  ', ' +$', '') == 'alo �lo')  -- trim
> +assert(string.gsub('  alo alo  ', '^%s*(.-)%s*$', '%1') == 'alo alo')  -- double trim
> +assert(string.gsub('alo  alo  \n 123\n ', '%s+', ' ') == 'alo alo 123 ')
> +t = "ab� d"
> +a, b = string.gsub(t, '(.)', '%1@')
> +assert('@'..a == string.gsub(t, '', '@') and b == 5)
> +a, b = string.gsub('ab�d', '(.)', '%0@', 2)
> +assert(a == 'a@b@�d' and b == 2)
> +assert(string.gsub('alo alo', '()[al]', '%1') == '12o 56o')
> +assert(string.gsub("abc=xyz", "(%w*)(%p)(%w+)", "%3%2%1-%0") ==
> +              "xyz=abc-abc=xyz")
> +assert(string.gsub("abc", "%w", "%1%0") == "aabbcc")
> +assert(string.gsub("abc", "%w+", "%0%1") == "abcabc")
> +assert(string.gsub('���', '$', '\0�') == '���\0�')
> +assert(string.gsub('', '^', 'r') == 'r')
> +assert(string.gsub('', '$', 'r') == 'r')
> +print('+')
> +
> +assert(string.gsub("um (dois) tres (quatro)", "(%(%w+%))", string.upper) ==
> +            "um (DOIS) tres (QUATRO)")
> +
> +do
> +  local function setglobal (n,v) rawset(_G, n, v) end
> +  string.gsub("a=roberto,roberto=a", "(%w+)=(%w%w*)", setglobal)
> +  assert(_G.a=="roberto" and _G.roberto=="a")
> +end
> +
> +function f(a,b) return string.gsub(a,'.',b) end
> +assert(string.gsub("trocar tudo em |teste|b| � |beleza|al|", "|([^|]*)|([^|]*)|", f) ==
> +            "trocar tudo em bbbbb � alalalalalal")
> +
> +local function dostring (s) return loadstring(s)() or "" end
> +assert(string.gsub("alo $a=1$ novamente $return a$", "$([^$]*)%$", dostring) ==
> +            "alo  novamente 1")
> +
> +x = string.gsub("$x=string.gsub('alo', '.', string.upper)$ assim vai para $return x$",
> +         "$([^$]*)%$", dostring)
> +assert(x == ' assim vai para ALO')
> +
> +t = {}
> +s = 'a alo jose  joao'
> +r = string.gsub(s, '()(%w+)()', function (a,w,b)
> +      assert(string.len(w) == b-a);
> +      t[a] = b-a;
> +    end)
> +assert(s == r and t[1] == 1 and t[3] == 3 and t[7] == 4 and t[13] == 4)
> +
> +
> +function isbalanced (s)
> +  return string.find(string.gsub(s, "%b()", ""), "[()]") == nil
> +end
> +
> +assert(isbalanced("(9 ((8))(\0) 7) \0\0 a b ()(c)() a"))
> +assert(not isbalanced("(9 ((8) 7) a b (\0 c) a"))
> +assert(string.gsub("alo 'oi' alo", "%b''", '"') == 'alo " alo')
> +
> +
> +local t = {"apple", "orange", "lime"; n=0}
> +assert(string.gsub("x and x and x", "x", function () t.n=t.n+1; return t[t.n] end)
> +        == "apple and orange and lime")
> +
> +t = {n=0}
> +string.gsub("first second word", "%w%w*", function (w) t.n=t.n+1; t[t.n] = w end)
> +assert(t[1] == "first" and t[2] == "second" and t[3] == "word" and t.n == 3)
> +
> +t = {n=0}
> +assert(string.gsub("first second word", "%w+",
> +         function (w) t.n=t.n+1; t[t.n] = w end, 2) == "first second word")
> +assert(t[1] == "first" and t[2] == "second" and t[3] == nil)
> +
> +assert(not pcall(string.gsub, "alo", "(.", print))
> +assert(not pcall(string.gsub, "alo", ".)", print))
> +assert(not pcall(string.gsub, "alo", "(.", {}))
> +assert(not pcall(string.gsub, "alo", "(.)", "%2"))
> +assert(not pcall(string.gsub, "alo", "(%1)", "a"))
> +assert(not pcall(string.gsub, "alo", "(%0)", "a"))
> +
> +-- big strings
> +local a = string.rep('a', 300000)
> +assert(string.find(a, '^a*.?$'))
> +assert(not string.find(a, '^a*.?b$'))
> +assert(string.find(a, '^a-.?$'))
> +
> +-- deep nest of gsubs
> +function rev (s)
> +  return string.gsub(s, "(.)(.+)", function (c,s1) return rev(s1)..c end)
> +end
> +
> +local x = string.rep('012345', 10)
> +assert(rev(rev(x)) == x)
> +
> +
> +-- gsub with tables
> +assert(string.gsub("alo alo", ".", {}) == "alo alo")
> +assert(string.gsub("alo alo", "(.)", {a="AA", l=""}) == "AAo AAo")
> +assert(string.gsub("alo alo", "(.).", {a="AA", l="K"}) == "AAo AAo")
> +assert(string.gsub("alo alo", "((.)(.?))", {al="AA", o=false}) == "AAo AAo")
> +
> +assert(string.gsub("alo alo", "().", {2,5,6}) == "256 alo")
> +
> +t = {}; setmetatable(t, {__index = function (t,s) return string.upper(s) end})
> +assert(string.gsub("a alo b hi", "%w%w+", t) == "a ALO b HI")
> +
> +
> +-- tests for gmatch
> +assert(string.gfind == string.gmatch)
> +local a = 0
> +for i in string.gmatch('abcde', '()') do assert(i == a+1); a=i end
> +assert(a==6)
> +
> +t = {n=0}
> +for w in string.gmatch("first second word", "%w+") do
> +      t.n=t.n+1; t[t.n] = w
> +end
> +assert(t[1] == "first" and t[2] == "second" and t[3] == "word")
> +
> +t = {3, 6, 9}
> +for i in string.gmatch ("xuxx uu ppar r", "()(.)%2") do
> +  assert(i == table.remove(t, 1))
> +end
> +assert(table.getn(t) == 0)
> +
> +t = {}
> +for i,j in string.gmatch("13 14 10 = 11, 15= 16, 22=23", "(%d+)%s*=%s*(%d+)") do
> +  t[i] = j
> +end
> +a = 0
> +for k,v in pairs(t) do assert(k+1 == v+0); a=a+1 end
> +assert(a == 3)
> +
> +
> +-- tests for `%f' (`frontiers')
> +
> +assert(string.gsub("aaa aa a aaa a", "%f[%w]a", "x") == "xaa xa x xaa x")
> +assert(string.gsub("[[]] [][] [[[[", "%f[[].", "x") == "x[]] x]x] x[[[")
> +assert(string.gsub("01abc45de3", "%f[%d]", ".") == ".01abc.45de.3")
> +assert(string.gsub("01abc45 de3x", "%f[%D]%w", ".") == "01.bc45 de3.")
> +assert(string.gsub("function", "%f[\1-\255]%w", ".") == ".unction")
> +assert(string.gsub("function", "%f[^\1-\255]", ".") == "function.")
> +
> +local i, e = string.find(" alo aalo allo", "%f[%S].-%f[%s].-%f[%S]")
> +assert(i == 2 and e == 5)
> +local k = string.match(" alo aalo allo", "%f[%S](.-%f[%s].-%f[%S])")
> +assert(k == 'alo ')
> +
> +local a = {1, 5, 9, 14, 17,}
> +for k in string.gmatch("alo alo th02 is 1hat", "()%f[%w%d]") do
> +  assert(table.remove(a, 1) == k)
> +end
> +assert(table.getn(a) == 0)
> +
> +
> +print('OK')
> diff --git a/test/PUC-Lua-5.1-tests/sort.lua b/test/PUC-Lua-5.1-tests/sort.lua
> new file mode 100644
> index 0000000..6fccd49
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/sort.lua
> @@ -0,0 +1,74 @@
> +print"testing sort"
> +
> +
> +function check (a, f)
> +  f = f or function (x,y) return x<y end;
> +  for n=table.getn(a),2,-1 do
> +    assert(not f(a[n], a[n-1]))
> +  end
> +end
> +
> +a = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
> +     "Oct", "Nov", "Dec"}
> +
> +table.sort(a)
> +check(a)
> +
> +limit = 30000
> +if rawget(_G, "_soft") then limit = 5000 end
> +
> +a = {}
> +for i=1,limit do
> +  a[i] = math.random()
> +end
> +
> +local x = os.clock()
> +table.sort(a)
> +print(string.format("Sorting %d elements in %.2f sec.", limit, os.clock()-x))
> +check(a)
> +
> +x = os.clock()
> +table.sort(a)
> +print(string.format("Re-sorting %d elements in %.2f sec.", limit, os.clock()-x))
> +check(a)
> +
> +a = {}
> +for i=1,limit do
> +  a[i] = math.random()
> +end
> +
> +x = os.clock(); i=0
> +table.sort(a, function(x,y) i=i+1; return y<x end)
> +print(string.format("Invert-sorting other %d elements in %.2f sec., with %i comparisons",
> +      limit, os.clock()-x, i))
> +check(a, function(x,y) return y<x end)
> +
> +
> +table.sort{}  -- empty array
> +
> +for i=1,limit do a[i] = false end
> +x = os.clock();
> +table.sort(a, function(x,y) return nil end)
> +print(string.format("Sorting %d equal elements in %.2f sec.", limit, os.clock()-x))
> +check(a, function(x,y) return nil end)
> +for i,v in pairs(a) do assert(not v or i=='n' and v==limit) end
> +
> +a = {"�lo", "\0first :-)", "alo", "then this one", "45", "and a new"}
> +table.sort(a)
> +check(a)
> +
> +table.sort(a, function (x, y)
> +          loadstring(string.format("a[%q] = ''", x))()
> +          collectgarbage()
> +          return x<y
> +        end)
> +
> +
> +tt = {__lt = function (a,b) return a.val < b.val end}
> +a = {}
> +for i=1,10 do  a[i] = {val=math.random(100)}; setmetatable(a[i], tt); end
> +table.sort(a)
> +check(a, tt.__lt)
> +check(a)
> +
> +print"OK"
> diff --git a/test/PUC-Lua-5.1-tests/strings.lua b/test/PUC-Lua-5.1-tests/strings.lua
> new file mode 100644
> index 0000000..237dbad
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/strings.lua
> @@ -0,0 +1,176 @@
> +print('testing strings and string library')
> +
> +assert('alo' < 'alo1')
> +assert('' < 'a')
> +assert('alo\0alo' < 'alo\0b')
> +assert('alo\0alo\0\0' > 'alo\0alo\0')
> +assert('alo' < 'alo\0')
> +assert('alo\0' > 'alo')
> +assert('\0' < '\1')
> +assert('\0\0' < '\0\1')
> +assert('\1\0a\0a' <= '\1\0a\0a')
> +assert(not ('\1\0a\0b' <= '\1\0a\0a'))
> +assert('\0\0\0' < '\0\0\0\0')
> +assert(not('\0\0\0\0' < '\0\0\0'))
> +assert('\0\0\0' <= '\0\0\0\0')
> +assert(not('\0\0\0\0' <= '\0\0\0'))
> +assert('\0\0\0' <= '\0\0\0')
> +assert('\0\0\0' >= '\0\0\0')
> +assert(not ('\0\0b' < '\0\0a\0'))
> +print('+')
> +
> +assert(string.sub("123456789",2,4) == "234")
> +assert(string.sub("123456789",7) == "789")
> +assert(string.sub("123456789",7,6) == "")
> +assert(string.sub("123456789",7,7) == "7")
> +assert(string.sub("123456789",0,0) == "")
> +assert(string.sub("123456789",-10,10) == "123456789")
> +assert(string.sub("123456789",1,9) == "123456789")
> +assert(string.sub("123456789",-10,-20) == "")
> +assert(string.sub("123456789",-1) == "9")
> +assert(string.sub("123456789",-4) == "6789")
> +assert(string.sub("123456789",-6, -4) == "456")
> +assert(string.sub("\000123456789",3,5) == "234")
> +assert(("\000123456789"):sub(8) == "789")
> +print('+')
> +
> +assert(string.find("123456789", "345") == 3)
> +a,b = string.find("123456789", "345")
> +assert(string.sub("123456789", a, b) == "345")
> +assert(string.find("1234567890123456789", "345", 3) == 3)
> +assert(string.find("1234567890123456789", "345", 4) == 13)
> +assert(string.find("1234567890123456789", "346", 4) == nil)
> +assert(string.find("1234567890123456789", ".45", -9) == 13)
> +assert(string.find("abcdefg", "\0", 5, 1) == nil)
> +assert(string.find("", "") == 1)
> +assert(string.find('', 'aaa', 1) == nil)
> +assert(('alo(.)alo'):find('(.)', 1, 1) == 4)
> +print('+')
> +
> +assert(string.len("") == 0)
> +assert(string.len("\0\0\0") == 3)
> +assert(string.len("1234567890") == 10)
> +
> +assert(#"" == 0)
> +assert(#"\0\0\0" == 3)
> +assert(#"1234567890" == 10)
> +
> +assert(string.byte("a") == 97)
> +assert(string.byte("�") > 127)
> +assert(string.byte(string.char(255)) == 255)
> +assert(string.byte(string.char(0)) == 0)
> +assert(string.byte("\0") == 0)
> +assert(string.byte("\0\0alo\0x", -1) == string.byte('x'))
> +assert(string.byte("ba", 2) == 97)
> +assert(string.byte("\n\n", 2, -1) == 10)
> +assert(string.byte("\n\n", 2, 2) == 10)
> +assert(string.byte("") == nil)
> +assert(string.byte("hi", -3) == nil)
> +assert(string.byte("hi", 3) == nil)
> +assert(string.byte("hi", 9, 10) == nil)
> +assert(string.byte("hi", 2, 1) == nil)
> +assert(string.char() == "")
> +assert(string.char(0, 255, 0) == "\0\255\0")
> +assert(string.char(0, string.byte("�"), 0) == "\0�\0")
> +assert(string.char(string.byte("�l\0�u", 1, -1)) == "�l\0�u")
> +assert(string.char(string.byte("�l\0�u", 1, 0)) == "")
> +assert(string.char(string.byte("�l\0�u", -10, 100)) == "�l\0�u")
> +print('+')
> +
> +assert(string.upper("ab\0c") == "AB\0C")
> +assert(string.lower("\0ABCc%$") == "\0abcc%$")
> +assert(string.rep('teste', 0) == '')
> +assert(string.rep('t�s\00t�', 2) == 't�s\0t�t�s\000t�')
> +assert(string.rep('', 10) == '')
> +
> +assert(string.reverse"" == "")
> +assert(string.reverse"\0\1\2\3" == "\3\2\1\0")
> +assert(string.reverse"\0001234" == "4321\0")
> +
> +for i=0,30 do assert(string.len(string.rep('a', i)) == i) end
> +
> +assert(type(tostring(nil)) == 'string')
> +assert(type(tostring(12)) == 'string')
> +assert(''..12 == '12' and type(12 .. '') == 'string')
> +assert(string.find(tostring{}, 'table:'))
> +assert(string.find(tostring(print), 'function:'))
> +assert(tostring(1234567890123) == '1234567890123')
> +assert(#tostring('\0') == 1)
> +assert(tostring(true) == "true")
> +assert(tostring(false) == "false")
> +print('+')
> +
> +x = '"�lo"\n\\'
> +assert(string.format('%q%s', x, x) == '"\\"�lo\\"\\\n\\\\""�lo"\n\\')
> +assert(string.format('%q', "\0") == [["\000"]])
> +assert(string.format("\0%c\0%c%x\0", string.byte("�"), string.byte("b"), 140) ==
> +              "\0�\0b8c\0")
> +assert(string.format('') == "")
> +assert(string.format("%c",34)..string.format("%c",48)..string.format("%c",90)..string.format("%c",100) ==
> +       string.format("%c%c%c%c", 34, 48, 90, 100))
> +assert(string.format("%s\0 is not \0%s", 'not be', 'be') == 'not be\0 is not \0be')
> +assert(string.format("%%%d %010d", 10, 23) == "%10 0000000023")
> +assert(tonumber(string.format("%f", 10.3)) == 10.3)
> +x = string.format('"%-50s"', 'a')
> +assert(#x == 52)
> +assert(string.sub(x, 1, 4) == '"a  ')
> +
> +assert(string.format("-%.20s.20s", string.rep("%", 2000)) == "-"..string.rep("%", 20)..".20s")
> +assert(string.format('"-%20s.20s"', string.rep("%", 2000)) ==
> +       string.format("%q", "-"..string.rep("%", 2000)..".20s"))
> +
> +
> +-- longest number that can be formated
> +assert(string.len(string.format('%99.99f', -1e308)) >= 100)
> +
> +assert(loadstring("return 1\n--coment�rio sem EOL no final")() == 1)
> +
> +
> +assert(table.concat{} == "")
> +assert(table.concat({}, 'x') == "")
> +assert(table.concat({'\0', '\0\1', '\0\1\2'}, '.\0.') == "\0.\0.\0\1.\0.\0\1\2")
> +local a = {}; for i=1,3000 do a[i] = "xuxu" end
> +assert(table.concat(a, "123").."123" == string.rep("xuxu123", 3000))
> +assert(table.concat(a, "b", 20, 20) == "xuxu")
> +assert(table.concat(a, "", 20, 21) == "xuxuxuxu")
> +assert(table.concat(a, "", 22, 21) == "")
> +assert(table.concat(a, "3", 2999) == "xuxu3xuxu")
> +
> +a = {"a","b","c"}
> +assert(table.concat(a, ",", 1, 0) == "")
> +assert(table.concat(a, ",", 1, 1) == "a")
> +assert(table.concat(a, ",", 1, 2) == "a,b")
> +assert(table.concat(a, ",", 2) == "b,c")
> +assert(table.concat(a, ",", 3) == "c")
> +assert(table.concat(a, ",", 4) == "")
> +
> +local locales = { "ptb", "ISO-8859-1", "pt_BR" }
> +local function trylocale (w)
> +  for _, l in ipairs(locales) do
> +    if os.setlocale(l, w) then return true end
> +  end
> +  return false
> +end
> +
> +if not trylocale("collate")  then
> +  print("locale not supported")
> +else
> +  assert("alo" < "�lo" and "�lo" < "amo")
> +end
> +
> +if not trylocale("ctype") then
> +  print("locale not supported")
> +else
> +  assert(string.gsub("����", "%a", "x") == "xxxxx")
> +  assert(string.gsub("����", "%l", "x") == "x�x�")
> +  assert(string.gsub("����", "%u", "x") == "�x�x")
> +  assert(string.upper"���{xuxu}��o" == "���{XUXU}��O")
> +end
> +
> +os.setlocale("C")
> +assert(os.setlocale() == 'C')
> +assert(os.setlocale(nil, "numeric") == 'C')
> +
> +print('OK')
> +
> +
> diff --git a/test/PUC-Lua-5.1-tests/vararg.lua b/test/PUC-Lua-5.1-tests/vararg.lua
> new file mode 100644
> index 0000000..ae068fa
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/vararg.lua
> @@ -0,0 +1,126 @@
> +print('testing vararg')
> +
> +_G.arg = nil
> +
> +function f(a, ...)
> +  assert(type(arg) == 'table')
> +  assert(type(arg.n) == 'number')
> +  for i=1,arg.n do assert(a[i]==arg[i]) end
> +  return arg.n
> +end
> +
> +function c12 (...)
> +  assert(arg == nil)
> +  local x = {...}; x.n = table.getn(x)
> +  local res = (x.n==2 and x[1] == 1 and x[2] == 2)
> +  if res then res = 55 end
> +  return res, 2
> +end
> +
> +function vararg (...) return arg end
> +
> +local call = function (f, args) return f(unpack(args, 1, args.n)) end
> +
> +assert(f() == 0)
> +assert(f({1,2,3}, 1, 2, 3) == 3)
> +assert(f({"alo", nil, 45, f, nil}, "alo", nil, 45, f, nil) == 5)
> +
> +assert(c12(1,2)==55)
> +a,b = assert(call(c12, {1,2}))
> +assert(a == 55 and b == 2)
> +a = call(c12, {1,2;n=2})
> +assert(a == 55 and b == 2)
> +a = call(c12, {1,2;n=1})
> +assert(not a)
> +assert(c12(1,2,3) == false)
> +local a = vararg(call(next, {_G,nil;n=2}))
> +local b,c = next(_G)
> +assert(a[1] == b and a[2] == c and a.n == 2)
> +a = vararg(call(call, {c12, {1,2}}))
> +assert(a.n == 2 and a[1] == 55 and a[2] == 2)
> +a = call(print, {'+'})
> +assert(a == nil)
> +
> +local t = {1, 10}
> +function t:f (...) return self[arg[1]]+arg.n end
> +assert(t:f(1,4) == 3 and t:f(2) == 11)
> +print('+')
> +
> +lim = 20
> +local i, a = 1, {}
> +while i <= lim do a[i] = i+0.3; i=i+1 end
> +
> +function f(a, b, c, d, ...)
> +  local more = {...}
> +  assert(a == 1.3 and more[1] == 5.3 and
> +         more[lim-4] == lim+0.3 and not more[lim-3])
> +end
> +
> +function g(a,b,c)
> +  assert(a == 1.3 and b == 2.3 and c == 3.3)
> +end
> +
> +call(f, a)
> +call(g, a)
> +
> +a = {}
> +i = 1
> +while i <= lim do a[i] = i; i=i+1 end
> +assert(call(math.max, a) == lim)
> +
> +print("+")
> +
> +
> +-- new-style varargs
> +
> +function oneless (a, ...) return ... end
> +
> +function f (n, a, ...)
> +  local b
> +  assert(arg == nil)
> +  if n == 0 then
> +    local b, c, d = ...
> +    return a, b, c, d, oneless(oneless(oneless(...)))
> +  else
> +    n, b, a = n-1, ..., a
> +    assert(b == ...)
> +    return f(n, a, ...)
> +  end
> +end
> +
> +a,b,c,d,e = assert(f(10,5,4,3,2,1))
> +assert(a==5 and b==4 and c==3 and d==2 and e==1)
> +
> +a,b,c,d,e = f(4)
> +assert(a==nil and b==nil and c==nil and d==nil and e==nil)
> +
> +
> +-- varargs for main chunks
> +f = loadstring[[ return {...} ]]
> +x = f(2,3)
> +assert(x[1] == 2 and x[2] == 3 and x[3] == nil)
> +
> +
> +f = loadstring[[
> +  local x = {...}
> +  for i=1,select('#', ...) do assert(x[i] == select(i, ...)) end
> +  assert(x[select('#', ...)+1] == nil)
> +  return true
> +]]
> +
> +assert(f("a", "b", nil, {}, assert))
> +assert(f())
> +
> +a = {select(3, unpack{10,20,30,40})}
> +assert(table.getn(a) == 2 and a[1] == 30 and a[2] == 40)
> +a = {select(1)}
> +assert(next(a) == nil)
> +a = {select(-1, 3, 5, 7)}
> +assert(a[1] == 7 and a[2] == nil)
> +a = {select(-2, 3, 5, 7)}
> +assert(a[1] == 5 and a[2] == 7 and a[3] == nil)
> +pcall(select, 10000)
> +pcall(select, -10000)
> +
> +print('OK')
> +
> diff --git a/test/PUC-Lua-5.1-tests/verybig.lua b/test/PUC-Lua-5.1-tests/verybig.lua
> new file mode 100644
> index 0000000..59e0142
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/verybig.lua
> @@ -0,0 +1,100 @@
> +if rawget(_G, "_soft") then return 10 end
> +
> +print "testing large programs (>64k)"
> +
> +-- template to create a very big test file
> +prog = [[$
> +
> +local a,b
> +
> +b = {$1$
> +  b30009 = 65534,
> +  b30010 = 65535,
> +  b30011 = 65536,
> +  b30012 = 65537,
> +  b30013 = 16777214,
> +  b30014 = 16777215,
> +  b30015 = 16777216,
> +  b30016 = 16777217,
> +  b30017 = 4294967294,
> +  b30018 = 4294967295,
> +  b30019 = 4294967296,
> +  b30020 = 4294967297,
> +  b30021 = -65534,
> +  b30022 = -65535,
> +  b30023 = -65536,
> +  b30024 = -4294967297,
> +  b30025 = 15012.5,
> +  $2$
> +};
> +
> +assert(b.a50008 == 25004 and b["a11"] == 5.5)
> +assert(b.a33007 == 16503.5 and b.a50009 == 25004.5)
> +assert(b["b"..30024] == -4294967297)
> +
> +function b:xxx (a,b) return a+b end
> +assert(b:xxx(10, 12) == 22)   -- pushself with non-constant index
> +b.xxx = nil
> +
> +s = 0; n=0
> +for a,b in pairs(b) do s=s+b; n=n+1 end
> +assert(s==13977183656.5  and n==70001)
> +
> +require "checktable"
> +stat(b)
> +
> +a = nil; b = nil
> +print'+'
> +
> +function f(x) b=x end
> +
> +a = f{$3$} or 10
> +
> +assert(a==10)
> +assert(b[1] == "a10" and b[2] == 5 and b[table.getn(b)-1] == "a50009")
> +
> +
> +function xxxx (x) return b[x] end
> +
> +assert(xxxx(3) == "a11")
> +
> +a = nil; b=nil
> +xxxx = nil
> +
> +return 10
> +
> +]]
> +
> +-- functions to fill in the $n$
> +F = {
> +function ()   -- $1$
> +  for i=10,50009 do
> +    io.write('a', i, ' = ', 5+((i-10)/2), ',\n')
> +  end
> +end,
> +
> +function ()   -- $2$
> +  for i=30026,50009 do
> +    io.write('b', i, ' = ', 15013+((i-30026)/2), ',\n')
> +  end
> +end,
> +
> +function ()   -- $3$
> +  for i=10,50009 do
> +    io.write('"a', i, '", ', 5+((i-10)/2), ',\n')
> +  end
> +end,
> +}
> +
> +file = os.tmpname()
> +io.output(file)
> +for s in string.gmatch(prog, "$([^$]+)") do
> +  local n = tonumber(s)
> +  if not n then io.write(s) else F[n]() end
> +end
> +io.close()
> +result = dofile(file)
> +assert(os.remove(file))
> +print'OK'
> +return result
> +
> -- 
> 2.31.0
> 


^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 02/30] test: add compiling for C libs from PUC-Rio-Lua5.1
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 02/30] test: add compiling for C libs from PUC-Rio-Lua5.1 Sergey Kaplun via Tarantool-patches
@ 2021-03-26 11:01   ` Sergey Ostanevich via Tarantool-patches
  2021-03-30 22:14   ` Igor Munkin via Tarantool-patches
  1 sibling, 0 replies; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 11:01 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

LGTM.

> On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> This patch adds commands to create additional LuaC libraries for tests
> in <attrib.lua>. Also, it renames `luaL_reg` to `luaL_Reg` in <lib1.c>
> and <lib2.c> to be consistent with the current LuaJIT's LuaC API.
> 
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
> test/PUC-Lua-5.1-tests/CMakeLists.txt      |  3 +-
> test/PUC-Lua-5.1-tests/libs/CMakeLists.txt | 48 +++++++++++++++++++++-
> test/PUC-Lua-5.1-tests/libs/lib1.c         |  2 +-
> test/PUC-Lua-5.1-tests/libs/lib2.c         |  2 +-
> 4 files changed, 51 insertions(+), 4 deletions(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/CMakeLists.txt b/test/PUC-Lua-5.1-tests/CMakeLists.txt
> index 773db0d..3c31aae 100644
> --- a/test/PUC-Lua-5.1-tests/CMakeLists.txt
> +++ b/test/PUC-Lua-5.1-tests/CMakeLists.txt
> @@ -16,7 +16,8 @@ cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
> # variable as proposed in the first case.
> set(LUA_PATH "?\;${CMAKE_CURRENT_SOURCE_DIR}/?.lua")
> 
> -# Set PUC-Lua-5.1-tests-prepare target that creates <libs/P1>
> +# Set PUC-Lua-5.1-tests-prepare target that contains rules
> +# for <libs/*> libraries compilation and creates <libs/P1>
> # subdirectory.
> add_subdirectory(libs)
> 
> diff --git a/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt
> index f24e7f3..aa64a44 100644
> --- a/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt
> +++ b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt
> @@ -4,11 +4,57 @@
> # See the rationale in the root CMakeLists.txt.
> cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
> 
> +# Build additional C libraries for tests.
> +macro(BuildTestCLib lib sources)
> +  add_library(${lib} SHARED EXCLUDE_FROM_ALL ${sources})
> +  target_include_directories(${lib} PRIVATE
> +    ${LUAJIT_SOURCE_DIR}
> +  )
> +  set_target_properties(${lib} PROPERTIES
> +    LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
> +    PREFIX ""
> +  )
> +  # XXX: The dynamic libraries are loaded with LuaJIT binary and
> +  # use symbols from it. So it is totally OK to have unresolved
> +  # symbols at build time.
> +  if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
> +    set_target_properties(${lib} PROPERTIES
> +      LINK_FLAGS "-undefined dynamic_lookup"
> +    )
> +  elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
> +    # XXX: This is necessary mostly for openSUSE builds, see also
> +    # https://bugzilla.suse.com/show_bug.cgi?id=1012388.
> +    # Just strip out the linker flag to suppress this linker
> +    # option.
> +    string(REPLACE "-Wl,--no-undefined" ""
> +      CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}"
> +    )
> +  endif()
> +  list(APPEND TESTLIBS ${lib})
> +endmacro()
> +
> +BuildTestCLib(lib1  lib1.c)
> +BuildTestCLib(lib11 lib1.c lib11.c)
> +BuildTestCLib(lib2  lib2.c)
> +BuildTestCLib(lib21 lib2.c lib21.c)
> +
> +# Create exact copy of the lib2 library for tests in attrib.lua.
> +set(LIB2ORIG "${CMAKE_CURRENT_BINARY_DIR}/lib2${CMAKE_SHARED_LIBRARY_SUFFIX}")
> +set(LIB2COPY "${CMAKE_CURRENT_BINARY_DIR}/-lib2${CMAKE_SHARED_LIBRARY_SUFFIX}")
> +add_custom_command(
> +  OUTPUT ${LIB2COPY}
> +  COMMENT "Copying lib2 to -lib2 for PUC-Rio Lua 5.1 tests"
> +  COMMAND ${CMAKE_COMMAND} -E copy ${LIB2ORIG} ${LIB2COPY}
> +  DEPENDS ${TESTLIBS}
> +  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
> +)
> +list(APPEND TESTLIBS ${LIB2COPY})
> +
> # The original tarball contains subdirectory "libs" with an empty
> # subdirectory "libs/P1", to be used by tests.
> # Instead of tracking empty directory with some anchor-file for
> # git, create this directory via CMake.
> -add_custom_target(PUC-Lua-5.1-tests-prepare)
> +add_custom_target(PUC-Lua-5.1-tests-prepare DEPENDS ${TESTLIBS})
> add_custom_command(TARGET PUC-Lua-5.1-tests-prepare
>   COMMENT "Create directory for PUC-Rio Lua 5.1 tests"
>   COMMAND ${CMAKE_COMMAND} -E make_directory P1
> diff --git a/test/PUC-Lua-5.1-tests/libs/lib1.c b/test/PUC-Lua-5.1-tests/libs/lib1.c
> index 812bb9a..22fe6de 100644
> --- a/test/PUC-Lua-5.1-tests/libs/lib1.c
> +++ b/test/PUC-Lua-5.1-tests/libs/lib1.c
> @@ -14,7 +14,7 @@ static int id (lua_State *L) {
> }
> 
> 
> -static const struct luaL_reg funcs[] = {
> +static const struct luaL_Reg funcs[] = {
>   {"id", id},
>   {NULL, NULL}
> };
> diff --git a/test/PUC-Lua-5.1-tests/libs/lib2.c b/test/PUC-Lua-5.1-tests/libs/lib2.c
> index 9972cbe..876a212 100644
> --- a/test/PUC-Lua-5.1-tests/libs/lib2.c
> +++ b/test/PUC-Lua-5.1-tests/libs/lib2.c
> @@ -12,7 +12,7 @@ static int id (lua_State *L) {
> }
> 
> 
> -static const struct luaL_reg funcs[] = {
> +static const struct luaL_Reg funcs[] = {
>   {"id", id},
>   {NULL, NULL}
> };
> -- 
> 2.31.0
> 


^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 03/30] test: adapt Lua 5.1 suite for out-of-source build
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 03/30] test: adapt Lua 5.1 suite for out-of-source build Sergey Kaplun via Tarantool-patches
@ 2021-03-26 11:07   ` Sergey Ostanevich via Tarantool-patches
  2021-03-26 14:25     ` Sergey Kaplun via Tarantool-patches
  2021-03-31 22:58   ` Igor Munkin via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 11:07 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

LGTM, just minor changes to commit message.

Sergos


> On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> When tests are run out-of-source redefined `dofile()` function
                                  ^ I had problem reading here the 
‘out-of-source redefined’. Can you put the ‘when..’ to the appropriate
place at the end of the sentence? ’The redefined … when … ‘
 
> failed to find file to load. So, fullpath is detected considering
> `arg[0]` value. Moreover, some tests use `loadfile()` instead, so
> their argument is adjusted to the full path to the files.
> 
> However, test in <verybig.lua> creates a temporary file
> and executes it via `dofile()` too, so this case is handled by
> the second argument -- `prefix` equals an empty string for
> current working directory.
> 
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
> test/PUC-Lua-5.1-tests/all.lua     | 17 +++++++++++++----
> test/PUC-Lua-5.1-tests/verybig.lua |  4 +++-
> 2 files changed, 16 insertions(+), 5 deletions(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/all.lua b/test/PUC-Lua-5.1-tests/all.lua
> index 8c4afac..85beff8 100755
> --- a/test/PUC-Lua-5.1-tests/all.lua
> +++ b/test/PUC-Lua-5.1-tests/all.lua
> @@ -58,9 +58,18 @@ end
> --
> -- redefine dofile to run files through dump/undump
> --
> -dofile = function (n)
> +-- LuaJIT: Adapt tests for testing with out-of-source build.
> +-- XXX: Test in <verybig.lua> creates a temporary file
> +-- and executes it via `dofile()` too, so this case is handled by
> +-- the second argument -- `prefix` equals an empty string for
> +-- current working directory.
> +-- <all.lua> is in the same directory, where are other common
> +-- executed files situated.
> +local path_to_sources = arg[0]:gsub('([^/]+)%.lua$', '')
> +dofile = function (n, prefix)
> +  local pr = prefix or path_to_sources
>   showmem()
> -  local f = assert(loadfile(n))
> +  local f = assert(loadfile(pr..n))
>   local b = string.dump(f)
>   f = assert(loadstring(b))
>   return f()
> @@ -77,7 +86,7 @@ do
>   end
> end
> 
> -local f = assert(loadfile('gc.lua'))
> +local f = assert(loadfile(path_to_sources..'gc.lua'))
> f()
> dofile('db.lua')
> assert(dofile('calls.lua') == deep and deep)
> @@ -88,7 +97,7 @@ assert(dofile('locals.lua') == 5)
> dofile('constructs.lua')
> dofile('code.lua')
> do
> -  local f = coroutine.wrap(assert(loadfile('big.lua')))
> +  local f = coroutine.wrap(assert(loadfile(path_to_sources..'big.lua')))
>   assert(f() == 'b')
>   assert(f() == 'a')
> end
> diff --git a/test/PUC-Lua-5.1-tests/verybig.lua b/test/PUC-Lua-5.1-tests/verybig.lua
> index 59e0142..edb170d 100644
> --- a/test/PUC-Lua-5.1-tests/verybig.lua
> +++ b/test/PUC-Lua-5.1-tests/verybig.lua
> @@ -93,7 +93,9 @@ for s in string.gmatch(prog, "$([^$]+)") do
>   if not n then io.write(s) else F[n]() end
> end
> io.close()
> -result = dofile(file)
> +-- LuaJIT: Adapt test for testing with out-of-source build.
> +-- See comment in <all.lua> near `dofile()` redefinition.
> +result = dofile(file, "")
> assert(os.remove(file))
> print'OK'
> return result
> -- 
> 2.31.0
> 


^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
                   ` (29 preceding siblings ...)
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 30/30] test: disable too depth recursive PUC Lua test Sergey Kaplun via Tarantool-patches
@ 2021-03-26 11:09 ` Sergey Ostanevich via Tarantool-patches
  2021-03-26 14:12   ` Sergey Kaplun via Tarantool-patches
  2021-03-30 22:17 ` Igor Munkin via Tarantool-patches
  31 siblings, 1 reply; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 11:09 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Hi!

Thanks for the patch set!

Overall I’m not happy with amount of output from the testing.
Can we put some redirection about it? 

Sergos

log example:
———————————

    —— total memory: 23K ----

testing debug library and debug information
+
...................................................................................................................+
OK
    ---- total memory: 2K ----

testing functions and calls
+
+
+
+
......................................................................................................................................................................................................................................................................OK
    ---- total memory: 1K ----

testing strings and string library
+
+
+
+
+
OK
    ---- total memory: 2K ----


> On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> Branch: https://github.com/tarantool/luajit/tree/skaplun/gh-5845-adapt-puc-rio-test-suite-v2
> Test branch: https://github.com/tarantool/tarantool/tree/skaplun/gh-5845-adapt-puc-rio-test-suite-v2
> 
> Side note: I reword commit about variable names in error messages a
> little, so the commit is different but the conten is the same.
> 
> Issues:
> * https://github.com/tarantool/tarantool/issues/5845
> * https://github.com/tarantool/tarantool/issues/4473
> 
> Suite is taken intact exept trailing whitespaces.
> Command to check:
> | $ diff -ruZ --color ../test/PUC-Lua-5.1-tests/ ~/Downloads/lua5.1-tests/
> | Only in ../test/PUC-Lua-5.1-tests/: CMakeLists.txt
> | Only in ../test/PUC-Lua-5.1-tests/libs: CMakeLists.txt
> | Only in ~/Downloads/lua5.1-tests/libs: makefile
> | Only in ~/Downloads/lua5.1-tests/libs: P1
> 
> Changes in the v2:
> * split commits to atomic changes
> * more verbose comments for some tests
> * some test fixed instead commenting
> 
> Sergey Kaplun (30):
>  test: add PUC-Rio Lua 5.1 test suite
>  test: add compiling for C libs from PUC-Rio-Lua5.1
>  test: adapt Lua 5.1 suite for out-of-source build
>  test: remove quotes in progname from <main.lua>
>  test: adapt arg availability test from Lua suite
>  test: disable PUC Lua tests confused by -v output
>  test: disable Lua tests for bytecode with header
>  test: disable JIT for GC step counting tests
>  test: disable Lua suite tests for line hook
>  test: adapt test for debug.setlocal in Lua suite
>  test: adapt getlocal PUC test for vararg func
>  test: adapt PUC Lua test with count hooks
>  test: disable PUC Lua test for tail call info
>  test: adapt activeline check in the PUC Lua test
>  test: disable PUC-Lua test for per-coroutine hooks
>  test: adapt PUC Lua test for %q in fmt for LuaJIT
>  test: disable locale-depended tests for Lua suite
>  test: replace math.mod to math.fmod for Lua tests
>  test: remove assert for string.gfind check
>  test: adapt PUC Lua test for args in vararg func
>  test: disable test for getfenv in closure tailcall
>  test: disable PUC Lua test for var names in error
>  test: disable PUC Lua test for fast function name
>  test: disable PUC Lua test for non-asci identifier
>  test: disable PUC Lua error test for syntax level
>  test: disable tests with multiple -l options
>  test: disable PUC Lua test for checking arg layout
>  test: disable PUC Lua test checking -h option
>  test: disable PUC Lua hanging GC test
>  test: disable too depth recursive PUC Lua test
> 
> .luacheckrc                                |    5 +-
> test/CMakeLists.txt                        |    2 +
> test/PUC-Lua-5.1-tests/CMakeLists.txt      |   46 +
> test/PUC-Lua-5.1-tests/README              |   41 +
> test/PUC-Lua-5.1-tests/all.lua             |  146 +++
> test/PUC-Lua-5.1-tests/api.lua             |  711 ++++++++++++
> test/PUC-Lua-5.1-tests/attrib.lua          |  339 ++++++
> test/PUC-Lua-5.1-tests/big.lua             |  381 +++++++
> test/PUC-Lua-5.1-tests/calls.lua           |  294 +++++
> test/PUC-Lua-5.1-tests/checktable.lua      |   77 ++
> test/PUC-Lua-5.1-tests/closure.lua         |  430 ++++++++
> test/PUC-Lua-5.1-tests/code.lua            |  143 +++
> test/PUC-Lua-5.1-tests/constructs.lua      |  242 +++++
> test/PUC-Lua-5.1-tests/db.lua              |  576 ++++++++++
> test/PUC-Lua-5.1-tests/errors.lua          |  269 +++++
> test/PUC-Lua-5.1-tests/etc/ltests.c        | 1147 ++++++++++++++++++++
> test/PUC-Lua-5.1-tests/etc/ltests.h        |   92 ++
> test/PUC-Lua-5.1-tests/events.lua          |  360 ++++++
> test/PUC-Lua-5.1-tests/files.lua           |  324 ++++++
> test/PUC-Lua-5.1-tests/gc.lua              |  325 ++++++
> test/PUC-Lua-5.1-tests/libs/CMakeLists.txt |   64 ++
> test/PUC-Lua-5.1-tests/libs/lib1.c         |   40 +
> test/PUC-Lua-5.1-tests/libs/lib11.c        |   18 +
> test/PUC-Lua-5.1-tests/libs/lib2.c         |   28 +
> test/PUC-Lua-5.1-tests/libs/lib21.c        |   18 +
> test/PUC-Lua-5.1-tests/literals.lua        |  181 +++
> test/PUC-Lua-5.1-tests/locals.lua          |  127 +++
> test/PUC-Lua-5.1-tests/main.lua            |  212 ++++
> test/PUC-Lua-5.1-tests/math.lua            |  209 ++++
> test/PUC-Lua-5.1-tests/nextvar.lua         |  397 +++++++
> test/PUC-Lua-5.1-tests/pm.lua              |  276 +++++
> test/PUC-Lua-5.1-tests/sort.lua            |   74 ++
> test/PUC-Lua-5.1-tests/strings.lua         |  191 ++++
> test/PUC-Lua-5.1-tests/vararg.lua          |  134 +++
> test/PUC-Lua-5.1-tests/verybig.lua         |  102 ++
> 35 files changed, 8019 insertions(+), 2 deletions(-)
> create mode 100644 test/PUC-Lua-5.1-tests/CMakeLists.txt
> create mode 100644 test/PUC-Lua-5.1-tests/README
> create mode 100755 test/PUC-Lua-5.1-tests/all.lua
> create mode 100644 test/PUC-Lua-5.1-tests/api.lua
> create mode 100644 test/PUC-Lua-5.1-tests/attrib.lua
> create mode 100644 test/PUC-Lua-5.1-tests/big.lua
> create mode 100644 test/PUC-Lua-5.1-tests/calls.lua
> create mode 100644 test/PUC-Lua-5.1-tests/checktable.lua
> create mode 100644 test/PUC-Lua-5.1-tests/closure.lua
> create mode 100644 test/PUC-Lua-5.1-tests/code.lua
> create mode 100644 test/PUC-Lua-5.1-tests/constructs.lua
> create mode 100644 test/PUC-Lua-5.1-tests/db.lua
> create mode 100644 test/PUC-Lua-5.1-tests/errors.lua
> create mode 100644 test/PUC-Lua-5.1-tests/etc/ltests.c
> create mode 100644 test/PUC-Lua-5.1-tests/etc/ltests.h
> create mode 100644 test/PUC-Lua-5.1-tests/events.lua
> create mode 100644 test/PUC-Lua-5.1-tests/files.lua
> create mode 100644 test/PUC-Lua-5.1-tests/gc.lua
> create mode 100644 test/PUC-Lua-5.1-tests/libs/CMakeLists.txt
> create mode 100644 test/PUC-Lua-5.1-tests/libs/lib1.c
> create mode 100644 test/PUC-Lua-5.1-tests/libs/lib11.c
> create mode 100644 test/PUC-Lua-5.1-tests/libs/lib2.c
> create mode 100644 test/PUC-Lua-5.1-tests/libs/lib21.c
> create mode 100644 test/PUC-Lua-5.1-tests/literals.lua
> create mode 100644 test/PUC-Lua-5.1-tests/locals.lua
> create mode 100644 test/PUC-Lua-5.1-tests/main.lua
> create mode 100644 test/PUC-Lua-5.1-tests/math.lua
> create mode 100644 test/PUC-Lua-5.1-tests/nextvar.lua
> create mode 100644 test/PUC-Lua-5.1-tests/pm.lua
> create mode 100644 test/PUC-Lua-5.1-tests/sort.lua
> create mode 100644 test/PUC-Lua-5.1-tests/strings.lua
> create mode 100644 test/PUC-Lua-5.1-tests/vararg.lua
> create mode 100644 test/PUC-Lua-5.1-tests/verybig.lua
> 
> -- 
> 2.31.0
> 


^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 04/30] test: remove quotes in progname from <main.lua>
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 04/30] test: remove quotes in progname from <main.lua> Sergey Kaplun via Tarantool-patches
@ 2021-03-26 11:12   ` Sergey Ostanevich via Tarantool-patches
  2021-03-31 22:58   ` Igor Munkin via Tarantool-patches
  1 sibling, 0 replies; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 11:12 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

LGTM.

Sergos

> On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> When LUAJIT_TEST_COMMAND extend the least `arg` with
> some string containing double quotes, bash failed to exec this
> command for child test.
> 
> This patch removes edged '"' to be able run extended command
> containing '"' and run other test suites.
> 
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
> test/PUC-Lua-5.1-tests/main.lua | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua
> index f520896..4f8b8bf 100644
> --- a/test/PUC-Lua-5.1-tests/main.lua
> +++ b/test/PUC-Lua-5.1-tests/main.lua
> @@ -11,7 +11,9 @@ out = os.tmpname()
> do
>   local i = 0
>   while arg[i] do i=i-1 end
> -  progname = '"'..arg[i+1]..'"'
> +  -- LuaJIT: remove edged '"' to be able run extended command
> +  -- containing '"' and run other test suites.
> +  progname = arg[i+1]
> end
> print(progname)
> 
> @@ -53,10 +55,12 @@ prepfile("print(a)", otherprog)
> RUN("lua -l %s -l%s -lstring -l io %s > %s", prog, otherprog, otherprog, out)
> checkout("1\n2\n2\n")
> 
> +-- LuaJIT: test file is adapted for LuaJIT's test system, see
> +-- the comment near `progname` initialization.
> local a = [[
>   assert(table.getn(arg) == 3 and arg[1] == 'a' and
>          arg[2] == 'b' and arg[3] == 'c')
> -  assert(arg[-1] == '--' and arg[-2] == "-e " and arg[-3] == %s)
> +  assert(arg[-1] == '--' and arg[-2] == "-e " and arg[-3] == '%s')
>   assert(arg[4] == nil and arg[-4] == nil)
>   local a, b, c = ...
>   assert(... == 'a' and a == 'a' and b == 'b' and c == 'c')
> -- 
> 2.31.0
> 


^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 05/30] test: adapt arg availability test from Lua suite
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 05/30] test: adapt arg availability test from Lua suite Sergey Kaplun via Tarantool-patches
@ 2021-03-26 11:22   ` Sergey Ostanevich via Tarantool-patches
  2021-03-31 22:58   ` Igor Munkin via Tarantool-patches
  1 sibling, 0 replies; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 11:22 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

[-- Attachment #1: Type: text/plain, Size: 1944 bytes --]

LGTM.

Although, I can’t support the `s = string.gsub(s, "lua", progname, 1)`
technique. 

Sergos

> On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> The argument table `arg` can be read (and modified) by `LUA_INIT` and
> `-e` chunks since the commit 92d9ff211ae864777a8580b5a7326d5f408161ce
> (Set arg table before evaluating LUA_INIT and -e chunks.).
> 
> This behaviour is similar to Lua 5.3, so the test was adapted
> considering PUC-Rio Lua 5.3 test suite taken from
> https://www.lua.org/tests/lua-5.3.0-tests.tar.gz.
> 
> Closes tarantool/tarantool#5686
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
> test/PUC-Lua-5.1-tests/main.lua | 14 ++++++++++++--
> 1 file changed, 12 insertions(+), 2 deletions(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua
> index 4f8b8bf..c11a576 100644
> --- a/test/PUC-Lua-5.1-tests/main.lua
> +++ b/test/PUC-Lua-5.1-tests/main.lua
> @@ -69,9 +69,19 @@ a = string.format(a, progname)
> prepfile(a)
> RUN('lua "-e " -- %s a b c', prog)
> 
> -prepfile"assert(arg==nil)"
> +-- test 'arg' availability in libraries
> +-- LuaJIT: LuaJIT v2.1.0-beta3 has extension from Lua 5.3:
> +-- The argument table `arg` can be read (and modified)
> +-- by `LUA_INIT` and `-e` chunks.
> +-- See commit 92d9ff211ae864777a8580b5a7326d5f408161ce
> +-- (Set arg table before evaluating LUA_INIT and -e chunks.).
> +-- See also https://github.com/tarantool/tarantool/issues/5686.
> +-- In Lua 5.3 this feature was introduced via commit
> +-- 23f0ff95177eda2e0a80e3a48562cc6837705735.
> +-- Test is adapted from PUC-Rio Lua 5.3 test suite.
> +prepfile"assert(arg)"
> prepfile("assert(arg)", otherprog)
> -RUN("lua -l%s - < %s", prog, otherprog)
> +RUN('env LUA_PATH="?;;" lua -l%s - < %s', prog, otherprog)
> 
> prepfile""
> RUN("lua - < %s > %s", prog, out)
> -- 
> 2.31.0
> 


[-- Attachment #2: Type: text/html, Size: 4252 bytes --]

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 06/30] test: disable PUC Lua tests confused by -v output
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 06/30] test: disable PUC Lua tests confused by -v output Sergey Kaplun via Tarantool-patches
@ 2021-03-26 11:26   ` Sergey Ostanevich via Tarantool-patches
  2021-03-26 14:31     ` Sergey Kaplun via Tarantool-patches
  2021-03-31 22:58   ` Igor Munkin via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 11:26 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Any follow-up ticket for this? Mention it in the commit message, and it's

LGTM.

Sergos


> On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> Version and status are printed in stdout instead stderr since
> LuaJIT-2.0.0-beta11 (as it is not an error message).
> See commit 0bd1a66f2f055211ef55834ccebca3b82d03c735
> (Print version and JIT status to stdout, not stderr.).
> This behavior is the same as in Lua 5.2.
> 
> This patch disables tests confused by unexpected -v output to stdout.
> 
> Relates to tarantool/tarantool#5687
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
> test/PUC-Lua-5.1-tests/main.lua | 28 ++++++++++++++++++++--------
> 1 file changed, 20 insertions(+), 8 deletions(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua
> index c11a576..56f56a0 100644
> --- a/test/PUC-Lua-5.1-tests/main.lua
> +++ b/test/PUC-Lua-5.1-tests/main.lua
> @@ -103,26 +103,37 @@ prepfile[[
> RUN("lua - < %s > %s", prog, out)
> checkout("1\tnil\n")
> 
> +-- Version and status are printed in stdout instead stderr since
> +-- LuaJIT-2.0.0-beta11 (as it is not an error message).
> +-- See commit 0bd1a66f2f055211ef55834ccebca3b82d03c735
> +-- (Print version and JIT status to stdout, not stderr.).
> +-- This behavior is the same as in Lua 5.2.
> +-- In Lua 5.2 this feature was introduced via commit
> +-- 9e7de9473c65baee1f567852a778f2d33a47ea83.
> +-- See also https://github.com/tarantool/tarantool/issues/5687.
> prepfile[[
> = (6*2-6) -- ===
> a
> = 10
> print(a)
> = a]]
> -RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
> -checkout("6\n10\n10\n\n")
> +-- FIXME: Behavior is different for LuaJIT. See the comment above.
> +-- RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
> +-- checkout("6\n10\n10\n\n")
> 
> prepfile("a = [[b\nc\nd\ne]]\n=a")
> print(prog)
> -RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
> -checkout("b\nc\nd\ne\n\n")
> +-- FIXME: Behavior is different for LuaJIT. See the comment above.
> +-- RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
> +-- checkout("b\nc\nd\ne\n\n")
> 
> prompt = "alo"
> prepfile[[ --
> a = 2
> ]]
> -RUN([[lua "-e_PROMPT='%s'" -i < %s > %s]], prompt, prog, out)
> -checkout(string.rep(prompt, 3).."\n")
> +-- FIXME: Behavior is different for LuaJIT. See the comment above.
> +-- RUN([[lua "-e_PROMPT='%s'" -i < %s > %s]], prompt, prog, out)
> +-- checkout(string.rep(prompt, 3).."\n")
> 
> s = [=[ --
> function f ( x )
> @@ -140,8 +151,9 @@ assert( a == b )
> =f( 11 )  ]=]
> s = string.gsub(s, ' ', '\n\n')
> prepfile(s)
> -RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
> -checkout("11\n1\t2\n\n")
> +-- FIXME: Behavior is different for LuaJIT. See the comment above.
> +-- RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
> +-- checkout("11\n1\t2\n\n")
> 
> prepfile[[#comment in 1st line without \n at the end]]
> RUN("lua %s", prog)
> -- 
> 2.31.0
> 


^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 07/30] test: disable Lua tests for bytecode with header
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 07/30] test: disable Lua tests for bytecode with header Sergey Kaplun via Tarantool-patches
@ 2021-03-26 11:30   ` Sergey Ostanevich via Tarantool-patches
  2021-03-31 22:59   ` Igor Munkin via Tarantool-patches
  1 sibling, 0 replies; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 11:30 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

LGTM.

Sergos


> On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> Loading bytecode with an extra header (BOM or "#") is disabled
> for security reasons since LuaJIT-2.0.0-beta10.
> For more information see comment for `lj_lex_setup()`
> in <src/lj_lex.c>.
> Also see commit 53a285c0c3544ff5dea7c67b741c3c2d06d22b47
> (Disable loading bytecode with an extra header (BOM or #!).).
> 
> These tests are disabled for LuaJIT.
> 
> Relates to tarantool/tarantool#5691
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
> test/PUC-Lua-5.1-tests/main.lua | 18 ++++++++++++++----
> 1 file changed, 14 insertions(+), 4 deletions(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua
> index 56f56a0..cf6d533 100644
> --- a/test/PUC-Lua-5.1-tests/main.lua
> +++ b/test/PUC-Lua-5.1-tests/main.lua
> @@ -158,13 +158,23 @@ prepfile(s)
> prepfile[[#comment in 1st line without \n at the end]]
> RUN("lua %s", prog)
> 
> +-- Loading bytecode with an extra header (BOM or "#") is disabled
> +-- for security reasons since LuaJIT-2.0.0-beta10.
> +-- For more information see comment for `lj_lex_setup()`
> +-- in <src/lj_lex.c>.
> +-- Also see commit 53a285c0c3544ff5dea7c67b741c3c2d06d22b47
> +-- (Disable loading bytecode with an extra header (BOM or #!).).
> +-- See also https://github.com/tarantool/tarantool/issues/5691.
> +-- FIXME: test is disabled for LuaJIT.
> prepfile("#comment with a binary file\n"..string.dump(loadstring("print(1)")))
> -RUN("lua %s > %s", prog, out)
> -checkout("1\n")
> +-- RUN("lua %s > %s", prog, out)
> +-- checkout("1\n")
> 
> prepfile("#comment with a binary file\r\n"..string.dump(loadstring("print(1)")))
> -RUN("lua %s > %s", prog, out)
> -checkout("1\n")
> +-- Behavior is different for LuaJIT. See the comment above.
> +-- FIXME: test is disabled for LuaJIT.
> +-- RUN("lua %s > %s", prog, out)
> +-- checkout("1\n")
> 
> -- close Lua with an open file
> prepfile(string.format([[io.output(%q); io.write('alo')]], out))
> -- 
> 2.31.0
> 


^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 08/30] test: disable JIT for GC step counting tests
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 08/30] test: disable JIT for GC step counting tests Sergey Kaplun via Tarantool-patches
@ 2021-03-26 11:32   ` Sergey Ostanevich via Tarantool-patches
  2021-03-30 22:14   ` Igor Munkin via Tarantool-patches
  1 sibling, 0 replies; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 11:32 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

LGTM.

Sergos

> On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> JIT compilation can unpredictable allocate or reference objects (or
> traces itself). So, the amount of GC steps can vary from run to run.
> 
> This patch disables JIT machinery, if it is enabled, for stable GC
> results.
> 
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
> test/PUC-Lua-5.1-tests/gc.lua | 10 ++++++++++
> 1 file changed, 10 insertions(+)
> 
> diff --git a/test/PUC-Lua-5.1-tests/gc.lua b/test/PUC-Lua-5.1-tests/gc.lua
> index 86a9f75..072bbe9 100644
> --- a/test/PUC-Lua-5.1-tests/gc.lua
> +++ b/test/PUC-Lua-5.1-tests/gc.lua
> @@ -108,11 +108,21 @@ local function dosteps (siz)
>   return i
> end
> 
> +-- LuaJIT: JIT compilation can unpredictable allocate or reference
> +-- objects (or traces itself). Disable it if necessary for
> +-- this chunk for stable GC results.
> +local jit_is_enabled = jit.status()
> +if jit_is_enabled then
> +  jit.off()
> +end
> assert(dosteps(0) > 10)
> assert(dosteps(6) < dosteps(2))
> assert(dosteps(10000) == 1)
> assert(collectgarbage("step", 1000000) == true)
> assert(collectgarbage("step", 1000000))
> +if jit_is_enabled then
> +  jit.on()
> +end
> 
> 
> do
> -- 
> 2.31.0
> 


^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 09/30] test: disable Lua suite tests for line hook
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 09/30] test: disable Lua suite tests for line hook Sergey Kaplun via Tarantool-patches
@ 2021-03-26 11:35   ` Sergey Ostanevich via Tarantool-patches
  2021-03-26 14:33     ` Sergey Kaplun via Tarantool-patches
  2021-03-31 22:59   ` Igor Munkin via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 11:35 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Follow-up ticket ?

LGTM.
Sergos

> On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> FIXME: LuaJIT interprets a return from a new function loaded by
> `loadstring()` with a change line number for bytecode position
> unlike Lua does. This looks like "implementation-defined behaviour"
> mentioned in https://luajit.org/status.html.
> 
> All tests checked the debug hook for a new line of code are affected
> and disabled by this patch.
> 
> Relates to tarantool/tarantool#5693
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
> test/PUC-Lua-5.1-tests/db.lua | 19 ++++++++++++++++++-
> 1 file changed, 18 insertions(+), 1 deletion(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua
> index 9d2c86f..a8c7196 100644
> --- a/test/PUC-Lua-5.1-tests/db.lua
> +++ b/test/PUC-Lua-5.1-tests/db.lua
> @@ -95,6 +95,23 @@ repeat
>   assert(g(f) == 'a')
> until 1
> 
> +-- FIXME: LuaJIT interprets a return from calling result of
> +-- `loadstring()` with a new line number unlike Lua does.
> +-- Here is an example (it is joined in one line intend):
> +--[[
> +debug.sethook(function(_, l) print("LINE: "..l) end, "l") loadstring("\n\ns=nil")() debug.sethook()
> +--]]
> +-- This chunk prints for LuaJIT:
> +--[[
> +LINE: 3
> +LINE: 1
> +--]]
> +-- But for Lua 5.1 it is only "LINE: 3" in the output.
> +-- See also https://github.com/tarantool/tarantool/issues/5693.
> +-- Considering implementation-defined behaviour diference
> +-- (see also https://luajit.org/status.html) test is disabled for
> +-- LuaJIT.
> +--[=[
> test([[if
> math.sin(1)
> then
> @@ -149,7 +166,7 @@ end
> ]], {1,2,1,2,1,3})
> 
> test([[for i=1,4 do a=1 end]], {1,1,1,1,1})
> -
> +--]=]
> 
> 
> print'+'
> -- 
> 2.31.0
> 


^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 10/30] test: adapt test for debug.setlocal in Lua suite
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 10/30] test: adapt test for debug.setlocal in Lua suite Sergey Kaplun via Tarantool-patches
@ 2021-03-26 11:44   ` Sergey Ostanevich via Tarantool-patches
  2021-03-26 14:45     ` Sergey Kaplun via Tarantool-patches
  2021-03-30 22:14   ` Igor Munkin via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 11:44 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

LGTM, minor update to message

Sergos

> On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> LuaJIT: Lua 5.1 interprets `...` in the vararg functions like
> an additional first argument unlike LuaJIT does.
               ^^^^^^^^^^^ means local? 
So, that getlocal() later in g() works as expected?

> This behaviour is extension is from Lua 5.2.
> 
> This patch adapted test considering LuaJIT's and Lua 5.2 behaviour.
> The test is adapted like it done in Lua 5.2 test suite taken from
> https://www.lua.org/tests/lua-5.2.0-tests.tar.gz.
> 
> Closes tarantool/tarantool#5694
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
> test/PUC-Lua-5.1-tests/db.lua | 7 +++++++
> 1 file changed, 7 insertions(+)
> 
> diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua
> index a8c7196..e5d8885 100644
> --- a/test/PUC-Lua-5.1-tests/db.lua
> +++ b/test/PUC-Lua-5.1-tests/db.lua
> @@ -221,6 +221,13 @@ assert(debug.getinfo(1, "l").currentline == L+11)  -- check count of lines
> 
> 
> function g(...)
> +  -- LuaJIT: Lua 5.1 interprets `...` in the vararg functions like
> +  -- an additional first argument unlike LuaJIT does.
> +  -- This extension is from Lua 5.2.
> +  -- See also https://github.com/tarantool/tarantool/issues/5694.
> +  -- Test is adapted from PUC-Rio Lua 5.2 test suite by adding
> +  -- additional variable `arg`.
> +  local arg = {...}
>   do local a,b,c; a=math.sin(40); end
>   local feijao
>   local AAAA,B = "xuxu", "mam�o"
> -- 
> 2.31.0
> 


^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 11/30] test: adapt getlocal PUC test for vararg func
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 11/30] test: adapt getlocal PUC test for vararg func Sergey Kaplun via Tarantool-patches
@ 2021-03-26 11:47   ` Sergey Ostanevich via Tarantool-patches
  2021-03-26 14:52     ` Sergey Kaplun via Tarantool-patches
  2021-03-30 22:15   ` Igor Munkin via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 11:47 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

LGTM

Sergos

> On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> Lua 5.1 interprets `...` in the vararg functions like an additional
> first argument unlike LuaJIT does. So, `a:f()` function will not set
> corresponding table `arg`, as test expects.
> 
> Implicit `arg` parameter for old-style vararg functions was finally
> removed in Lua 5.2. The test is adapted from PUC-Rio Lua 5.2 test suite
> by removing additional check for amountt of arguments via `arg.n`.
> Lua 5.2 test suite is taken from
> https://www.lua.org/tests/lua-5.2.0-tests.tar.gz.
> 
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
> test/PUC-Lua-5.1-tests/db.lua | 11 ++++++++++-
> 1 file changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua
> index e5d8885..6985c29 100644
> --- a/test/PUC-Lua-5.1-tests/db.lua
> +++ b/test/PUC-Lua-5.1-tests/db.lua
> @@ -300,7 +300,16 @@ debug.sethook(function (e)
> end, "c")
> 
> a:f(1,2,3,4,5)
> -assert(X.self == a and X.a == 1   and X.b == 2 and X.arg.n == 3 and X.c == nil)
> +
> +-- LuaJIT: Lua 5.1 interprets `...` in the vararg functions like
> +-- an additional first argument unlike LuaJIT does.
> +-- So, `a:f()` function will not set corresponding table `arg`,
> +-- as test expects.
> +-- Implicit `arg` parameter for old-style vararg functions was
> +-- finally removed in Lua 5.2
> +-- The test is adapted from PUC-Rio Lua 5.2 test suite by removing
> +-- additional `arg.n == 3` check.
> +assert(X.self == a and X.a == 1   and X.b == 2 and X.c == nil)
> assert(XX == 12)
> assert(debug.gethook() == nil)
> 
> -- 
> 2.31.0
> 


^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 12/30] test: adapt PUC Lua test with count hooks
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 12/30] test: adapt PUC Lua test with count hooks Sergey Kaplun via Tarantool-patches
@ 2021-03-26 11:49   ` Sergey Ostanevich via Tarantool-patches
  2021-03-30 22:15   ` Igor Munkin via Tarantool-patches
  1 sibling, 0 replies; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 11:49 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

LGTM.
Sergos

> On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> LuaJIT does not check hooks at traces without defined
> -DLUAJIT_ENABLE_CHECKHOOK. For more information see <src/lj_record.c>
> or commit 6bce6b118eeb2bb7f36157de158e5cccf0ea68e5 (Add compile-time
> option LUAJIT_ENABLE_CHECKHOOK. Disabled by default.).
> 
> This patch adapts these tests for LuaJIT by disabling JIT while testing
> count hooks.
> 
> Closes tarantool/tarantool#5701
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
> test/PUC-Lua-5.1-tests/db.lua | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
> 
> diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua
> index 6985c29..c1a635a 100644
> --- a/test/PUC-Lua-5.1-tests/db.lua
> +++ b/test/PUC-Lua-5.1-tests/db.lua
> @@ -347,6 +347,18 @@ assert(debug.setupvalue(io.read, 1, 10) == nil)
> 
> -- testing count hooks
> local a=0
> +-- LuaJIT: LuaJIT does not check hooks at traces without defined
> +-- -DLUAJIT_ENABLE_CHECKHOOK.
> +-- For more information see <src/lj_record.c> or commit
> +-- 6bce6b118eeb2bb7f36157de158e5cccf0ea68e5 (Add compile-time
> +-- option LUAJIT_ENABLE_CHECKHOOK. Disabled by default.).
> +-- See also https://github.com/tarantool/tarantool/issues/5701
> +-- Test is adapted for LuaJIT by disabling JIT while
> +-- testing count hooks.
> +local jit_is_enabled = jit.status()
> +if jit_is_enabled then
> +  jit.off()
> +end
> debug.sethook(function (e) a=a+1 end, "", 1)
> a=0; for i=1,1000 do end; assert(1000 < a and a < 1012)
> debug.sethook(function (e) a=a+1 end, "", 4)
> @@ -359,6 +371,9 @@ debug.sethook(print, "", 2^24 - 1)   -- count upperbound
> local f,m,c = debug.gethook()
> assert(({debug.gethook()})[3] == 2^24 - 1)
> debug.sethook()
> +if jit_is_enabled then
> +  jit.on()
> +end
> 
> 
> -- tests for tail calls
> -- 
> 2.31.0
> 


^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite
  2021-03-26 11:09 ` [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Ostanevich via Tarantool-patches
@ 2021-03-26 14:12   ` Sergey Kaplun via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 14:12 UTC (permalink / raw)
  To: Sergey Ostanevich; +Cc: tarantool-patches

Hi, Sergos!

Thanks for the review!

On 26.03.21, Sergey Ostanevich wrote:
> Hi!
> 
> Thanks for the patch set!
> 
> Overall I’m not happy with amount of output from the testing.
> Can we put some redirection about it? 

If we just redirect the output, we get no information about failures.
Instead, we can (and should as I think) rewrite test suite runner, but it
is out of the scope of these series.

> 
> Sergos
> 
> log example:
> ———————————
> 
>     —— total memory: 23K ----
> 
> testing debug library and debug information
> +
> ...................................................................................................................+
> OK
>     ---- total memory: 2K ----
> 
> testing functions and calls
> +
> +
> +
> +
> ......................................................................................................................................................................................................................................................................OK
>     ---- total memory: 1K ----
> 
> testing strings and string library
> +
> +
> +
> +
> +
> OK
>     ---- total memory: 2K ----
> 
> 

<snipped>

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 03/30] test: adapt Lua 5.1 suite for out-of-source build
  2021-03-26 11:07   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-26 14:25     ` Sergey Kaplun via Tarantool-patches
  2021-03-31 22:58       ` Igor Munkin via Tarantool-patches
  0 siblings, 1 reply; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 14:25 UTC (permalink / raw)
  To: Sergey Ostanevich; +Cc: tarantool-patches

Hi!

Thanks for the review!

On 26.03.21, Sergey Ostanevich wrote:
> LGTM, just minor changes to commit message.
> 
> Sergos
> 
> 
> > On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote:
> > 
> > When tests are run out-of-source redefined `dofile()` function
>                                   ^ I had problem reading here the 
> ‘out-of-source redefined’. Can you put the ‘when..’ to the appropriate
> place at the end of the sentence? ’The redefined … when … ‘

Fixed.

The new committ message is the following (branch is force-pushed):

===================================================================
test: adapt Lua 5.1 suite for out-of-source build

When tests are run out-of-source redefined `dofile()` function failed to
find the test file to load. So, fullpath is detected considering
`arg[0]` value. Moreover, some tests use `loadfile()` instead, so their
argument is adjusted to the full path to the files.

However, test in <verybig.lua> creates a temporary file
and executes it via `dofile()` too, so this case is handled by
the second argument -- `prefix` equals an empty string for
current working directory.

Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
===================================================================

>  
> > failed to find file to load. So, fullpath is detected considering
> > `arg[0]` value. Moreover, some tests use `loadfile()` instead, so
> > their argument is adjusted to the full path to the files.
> > 
> > However, test in <verybig.lua> creates a temporary file
> > and executes it via `dofile()` too, so this case is handled by
> > the second argument -- `prefix` equals an empty string for
> > current working directory.
> > 
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ---
> > test/PUC-Lua-5.1-tests/all.lua     | 17 +++++++++++++----
> > test/PUC-Lua-5.1-tests/verybig.lua |  4 +++-
> > 2 files changed, 16 insertions(+), 5 deletions(-)
> > 
> > diff --git a/test/PUC-Lua-5.1-tests/all.lua b/test/PUC-Lua-5.1-tests/all.lua
> > index 8c4afac..85beff8 100755
> > --- a/test/PUC-Lua-5.1-tests/all.lua
> > +++ b/test/PUC-Lua-5.1-tests/all.lua
> > @@ -58,9 +58,18 @@ end
> > --
> > -- redefine dofile to run files through dump/undump
> > --
> > -dofile = function (n)
> > +-- LuaJIT: Adapt tests for testing with out-of-source build.
> > +-- XXX: Test in <verybig.lua> creates a temporary file
> > +-- and executes it via `dofile()` too, so this case is handled by
> > +-- the second argument -- `prefix` equals an empty string for
> > +-- current working directory.
> > +-- <all.lua> is in the same directory, where are other common
> > +-- executed files situated.
> > +local path_to_sources = arg[0]:gsub('([^/]+)%.lua$', '')
> > +dofile = function (n, prefix)
> > +  local pr = prefix or path_to_sources
> >   showmem()
> > -  local f = assert(loadfile(n))
> > +  local f = assert(loadfile(pr..n))
> >   local b = string.dump(f)
> >   f = assert(loadstring(b))
> >   return f()
> > @@ -77,7 +86,7 @@ do
> >   end
> > end
> > 
> > -local f = assert(loadfile('gc.lua'))
> > +local f = assert(loadfile(path_to_sources..'gc.lua'))
> > f()
> > dofile('db.lua')
> > assert(dofile('calls.lua') == deep and deep)
> > @@ -88,7 +97,7 @@ assert(dofile('locals.lua') == 5)
> > dofile('constructs.lua')
> > dofile('code.lua')
> > do
> > -  local f = coroutine.wrap(assert(loadfile('big.lua')))
> > +  local f = coroutine.wrap(assert(loadfile(path_to_sources..'big.lua')))
> >   assert(f() == 'b')
> >   assert(f() == 'a')
> > end
> > diff --git a/test/PUC-Lua-5.1-tests/verybig.lua b/test/PUC-Lua-5.1-tests/verybig.lua
> > index 59e0142..edb170d 100644
> > --- a/test/PUC-Lua-5.1-tests/verybig.lua
> > +++ b/test/PUC-Lua-5.1-tests/verybig.lua
> > @@ -93,7 +93,9 @@ for s in string.gmatch(prog, "$([^$]+)") do
> >   if not n then io.write(s) else F[n]() end
> > end
> > io.close()
> > -result = dofile(file)
> > +-- LuaJIT: Adapt test for testing with out-of-source build.
> > +-- See comment in <all.lua> near `dofile()` redefinition.
> > +result = dofile(file, "")
> > assert(os.remove(file))
> > print'OK'
> > return result
> > -- 
> > 2.31.0
> > 
> 

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 06/30] test: disable PUC Lua tests confused by -v output
  2021-03-26 11:26   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-26 14:31     ` Sergey Kaplun via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 14:31 UTC (permalink / raw)
  To: Sergey Ostanevich; +Cc: tarantool-patches

Hi!

Thanks for the review!

On 26.03.21, Sergey Ostanevich wrote:
> Any follow-up ticket for this? Mention it in the commit message, and it's

It is mentioned via the folowing line:
| Relates to tarantool/tarantool#5687

> 
> LGTM.
> 
> Sergos
> 
> 
> > On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote:
> > 
> > Version and status are printed in stdout instead stderr since
> > LuaJIT-2.0.0-beta11 (as it is not an error message).
> > See commit 0bd1a66f2f055211ef55834ccebca3b82d03c735
> > (Print version and JIT status to stdout, not stderr.).
> > This behavior is the same as in Lua 5.2.
> > 
> > This patch disables tests confused by unexpected -v output to stdout.
> > 
> > Relates to tarantool/tarantool#5687
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ---
> > test/PUC-Lua-5.1-tests/main.lua | 28 ++++++++++++++++++++--------
> > 1 file changed, 20 insertions(+), 8 deletions(-)
> > 
> > diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua
> > index c11a576..56f56a0 100644
> > --- a/test/PUC-Lua-5.1-tests/main.lua
> > +++ b/test/PUC-Lua-5.1-tests/main.lua
> > @@ -103,26 +103,37 @@ prepfile[[
> > RUN("lua - < %s > %s", prog, out)
> > checkout("1\tnil\n")
> > 
> > +-- Version and status are printed in stdout instead stderr since
> > +-- LuaJIT-2.0.0-beta11 (as it is not an error message).
> > +-- See commit 0bd1a66f2f055211ef55834ccebca3b82d03c735
> > +-- (Print version and JIT status to stdout, not stderr.).
> > +-- This behavior is the same as in Lua 5.2.
> > +-- In Lua 5.2 this feature was introduced via commit
> > +-- 9e7de9473c65baee1f567852a778f2d33a47ea83.
> > +-- See also https://github.com/tarantool/tarantool/issues/5687.
> > prepfile[[
> > = (6*2-6) -- ===
> > a
> > = 10
> > print(a)
> > = a]]
> > -RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
> > -checkout("6\n10\n10\n\n")
> > +-- FIXME: Behavior is different for LuaJIT. See the comment above.
> > +-- RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
> > +-- checkout("6\n10\n10\n\n")
> > 
> > prepfile("a = [[b\nc\nd\ne]]\n=a")
> > print(prog)
> > -RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
> > -checkout("b\nc\nd\ne\n\n")
> > +-- FIXME: Behavior is different for LuaJIT. See the comment above.
> > +-- RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
> > +-- checkout("b\nc\nd\ne\n\n")
> > 
> > prompt = "alo"
> > prepfile[[ --
> > a = 2
> > ]]
> > -RUN([[lua "-e_PROMPT='%s'" -i < %s > %s]], prompt, prog, out)
> > -checkout(string.rep(prompt, 3).."\n")
> > +-- FIXME: Behavior is different for LuaJIT. See the comment above.
> > +-- RUN([[lua "-e_PROMPT='%s'" -i < %s > %s]], prompt, prog, out)
> > +-- checkout(string.rep(prompt, 3).."\n")
> > 
> > s = [=[ --
> > function f ( x )
> > @@ -140,8 +151,9 @@ assert( a == b )
> > =f( 11 )  ]=]
> > s = string.gsub(s, ' ', '\n\n')
> > prepfile(s)
> > -RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
> > -checkout("11\n1\t2\n\n")
> > +-- FIXME: Behavior is different for LuaJIT. See the comment above.
> > +-- RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
> > +-- checkout("11\n1\t2\n\n")
> > 
> > prepfile[[#comment in 1st line without \n at the end]]
> > RUN("lua %s", prog)
> > -- 
> > 2.31.0
> > 
> 

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 09/30] test: disable Lua suite tests for line hook
  2021-03-26 11:35   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-26 14:33     ` Sergey Kaplun via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 14:33 UTC (permalink / raw)
  To: Sergey Ostanevich; +Cc: tarantool-patches

Hi!

Thanks for the review!

On 26.03.21, Sergey Ostanevich wrote:
> Follow-up ticket ?

It is mentioned by this line (IIUYC):
| Relates to tarantool/tarantool#5693

> 
> LGTM.
> Sergos
> 
> > On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote:
> > 
> > FIXME: LuaJIT interprets a return from a new function loaded by
> > `loadstring()` with a change line number for bytecode position
> > unlike Lua does. This looks like "implementation-defined behaviour"
> > mentioned in https://luajit.org/status.html.
> > 
> > All tests checked the debug hook for a new line of code are affected
> > and disabled by this patch.
> > 
> > Relates to tarantool/tarantool#5693
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ---
> > test/PUC-Lua-5.1-tests/db.lua | 19 ++++++++++++++++++-
> > 1 file changed, 18 insertions(+), 1 deletion(-)
> > 
> > diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua
> > index 9d2c86f..a8c7196 100644
> > --- a/test/PUC-Lua-5.1-tests/db.lua
> > +++ b/test/PUC-Lua-5.1-tests/db.lua
> > @@ -95,6 +95,23 @@ repeat
> >   assert(g(f) == 'a')
> > until 1
> > 
> > +-- FIXME: LuaJIT interprets a return from calling result of
> > +-- `loadstring()` with a new line number unlike Lua does.
> > +-- Here is an example (it is joined in one line intend):
> > +--[[
> > +debug.sethook(function(_, l) print("LINE: "..l) end, "l") loadstring("\n\ns=nil")() debug.sethook()
> > +--]]
> > +-- This chunk prints for LuaJIT:
> > +--[[
> > +LINE: 3
> > +LINE: 1
> > +--]]
> > +-- But for Lua 5.1 it is only "LINE: 3" in the output.
> > +-- See also https://github.com/tarantool/tarantool/issues/5693.
> > +-- Considering implementation-defined behaviour diference
> > +-- (see also https://luajit.org/status.html) test is disabled for
> > +-- LuaJIT.
> > +--[=[
> > test([[if
> > math.sin(1)
> > then
> > @@ -149,7 +166,7 @@ end
> > ]], {1,2,1,2,1,3})
> > 
> > test([[for i=1,4 do a=1 end]], {1,1,1,1,1})
> > -
> > +--]=]
> > 
> > 
> > print'+'
> > -- 
> > 2.31.0
> > 
> 

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 13/30] test: disable PUC Lua test for tail call info
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 13/30] test: disable PUC Lua test for tail call info Sergey Kaplun via Tarantool-patches
@ 2021-03-26 14:43   ` Sergey Ostanevich via Tarantool-patches
  2021-03-30 22:15   ` Igor Munkin via Tarantool-patches
  1 sibling, 0 replies; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 14:43 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

LGTM.
Sergos

> On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> LuaJIT does not provide information about tail calls in debug.getinfo(),
> unlike Lua does. This missed feature is described in
> https://luajit.org/status.html.
> 
> This patch disables tests for tail call checks and getfenv() checks,
> because tail calls do not provide an additional level for LuaJIT
> and level number given to getfenv() should be changed.
> 
> Relates to tarantool/tarantool#5702
> Relates to tarantool/tarantool#5703
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
> test/PUC-Lua-5.1-tests/db.lua | 30 ++++++++++++++++++++++--------
> 1 file changed, 22 insertions(+), 8 deletions(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua
> index c1a635a..b363abc 100644
> --- a/test/PUC-Lua-5.1-tests/db.lua
> +++ b/test/PUC-Lua-5.1-tests/db.lua
> @@ -400,19 +400,29 @@ function g1(x) g(x) end
> 
> local function h (x) local f=g1; return f(x) end
> 
> -h(true)
> +-- LuaJIT does not provide information about tail calls,
> +-- unlike Lua does. See also https://luajit.org/status.html.
> +-- getfenv() behaviour is also different here,
> +-- because tail calls do not provide additional level for LuaJIT
> +-- and level number should be changed.
> +-- FIXME: Test is disabled for LuaJIT.
> +-- See also https://github.com/tarantool/tarantool/issues/5702.
> +-- h(true)
> 
> local b = {}
> -debug.sethook(function (e) table.insert(b, e) end, "cr")
> -h(false)
> -debug.sethook()
> +-- Behavior is different for LuaJIT. See the comment above.
> +-- FIXME: Test is disabled for LuaJIT.
> +-- debug.sethook(function (e) table.insert(b, e) end, "cr")
> +-- h(false)
> +-- debug.sethook()
> local res = {"return",   -- first return (from sethook)
>   "call", "call", "call", "call",
>   "return", "tail return", "return", "tail return",
>   "call",    -- last call (to sethook)
> }
> -for _, k in ipairs(res) do assert(k == table.remove(b, 1)) end
> -
> +-- Behavior is different for LuaJIT. See the comment above.
> +-- FIXME: Test is disabled for LuaJIT.
> +-- for _, k in ipairs(res) do assert(k == table.remove(b, 1)) end
> 
> lim = 30000
> local function foo (x)
> @@ -423,7 +433,9 @@ local function foo (x)
>   end
> end
> 
> -foo(lim)
> +-- Behavior is different for LuaJIT. See the comment above.
> +-- FIXME: Test is disabled for LuaJIT.
> +-- foo(lim)
> 
> 
> print"+"
> @@ -459,7 +471,9 @@ end
> 
> local co = coroutine.create(f)
> coroutine.resume(co, 3)
> -checktraceback(co, {"yield", "db.lua", "tail", "tail", "tail"})
> +-- Behavior is different for LuaJIT. See the comment to h() above.
> +-- FIXME: Test is disabled for LuaJIT.
> +-- checktraceback(co, {"yield", "db.lua", "tail", "tail", "tail"})
> 
> 
> co = coroutine.create(function (x)
> -- 
> 2.31.0
> 


^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 10/30] test: adapt test for debug.setlocal in Lua suite
  2021-03-26 11:44   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-26 14:45     ` Sergey Kaplun via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 14:45 UTC (permalink / raw)
  To: Sergey Ostanevich; +Cc: tarantool-patches

Hi, thanks for the review!

On 26.03.21, Sergey Ostanevich wrote:
> LGTM, minor update to message
> 
> Sergos
> 
> > On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote:
> > 
> > LuaJIT: Lua 5.1 interprets `...` in the vararg functions like
> > an additional first argument unlike LuaJIT does.
>                ^^^^^^^^^^^ means local? 
> So, that getlocal() later in g() works as expected?

Yes, local is correct. Update commit message and the comment, branch is
force-pushed. See the iterative patch below.

The new commit message is:
===================================================================
test: adapt test for debug.setlocal in Lua suite

LuaJIT: Lua 5.1 interprets `...` in the vararg functions like
an additional local argument unlike LuaJIT does.
This behaviour is extension is from Lua 5.2.

This patch adapted test considering LuaJIT's and Lua 5.2 behaviour.
The test is adapted like it done in Lua 5.2 test suite taken from
https://www.lua.org/tests/lua-5.2.0-tests.tar.gz.

Part of tarantool/tarantool#5694
Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
===================================================================

===================================================================
diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua
index e5d8885..6535594 100644
--- a/test/PUC-Lua-5.1-tests/db.lua
+++ b/test/PUC-Lua-5.1-tests/db.lua
@@ -222,7 +222,7 @@ assert(debug.getinfo(1, "l").currentline == L+11)  -- check count of lines
 
 function g(...)
   -- LuaJIT: Lua 5.1 interprets `...` in the vararg functions like
-  -- an additional first argument unlike LuaJIT does.
+  -- an additional local argument unlike LuaJIT does.
   -- This extension is from Lua 5.2.
   -- See also https://github.com/tarantool/tarantool/issues/5694.
   -- Test is adapted from PUC-Rio Lua 5.2 test suite by adding
===================================================================

> 
> > This behaviour is extension is from Lua 5.2.
> > 
> > This patch adapted test considering LuaJIT's and Lua 5.2 behaviour.
> > The test is adapted like it done in Lua 5.2 test suite taken from
> > https://www.lua.org/tests/lua-5.2.0-tests.tar.gz.
> > 
> > Closes tarantool/tarantool#5694

Part of is more correct here.

> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ---
> > test/PUC-Lua-5.1-tests/db.lua | 7 +++++++
> > 1 file changed, 7 insertions(+)
> > 
> > diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua
> > index a8c7196..e5d8885 100644
> > --- a/test/PUC-Lua-5.1-tests/db.lua
> > +++ b/test/PUC-Lua-5.1-tests/db.lua
> > @@ -221,6 +221,13 @@ assert(debug.getinfo(1, "l").currentline == L+11)  -- check count of lines
> > 
> > 
> > function g(...)
> > +  -- LuaJIT: Lua 5.1 interprets `...` in the vararg functions like
> > +  -- an additional first argument unlike LuaJIT does.
> > +  -- This extension is from Lua 5.2.
> > +  -- See also https://github.com/tarantool/tarantool/issues/5694.
> > +  -- Test is adapted from PUC-Rio Lua 5.2 test suite by adding
> > +  -- additional variable `arg`.
> > +  local arg = {...}
> >   do local a,b,c; a=math.sin(40); end
> >   local feijao
> >   local AAAA,B = "xuxu", "mam�o"
> > -- 
> > 2.31.0
> > 
> 

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 14/30] test: adapt activeline check in the PUC Lua test
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 14/30] test: adapt activeline check in the PUC Lua test Sergey Kaplun via Tarantool-patches
@ 2021-03-26 14:50   ` Sergey Ostanevich via Tarantool-patches
  2021-03-30 22:15   ` Igor Munkin via Tarantool-patches
  1 sibling, 0 replies; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 14:50 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

LGTM.
Sergos

> On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> LuaJIT does not report line with single "end" statement
> (the last line of the function) as an active line in
> debug.getinfo(), unlike Lua does. There is no bytecode
> related to this line, so it is "unreachable” and
> c be considered not active.
> 
> This patch excludes the last line of a function from the check,
> considering LuaJIT's behaviour.
> 
> Closes tarantool/tarantool#5708
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
> test/PUC-Lua-5.1-tests/db.lua | 10 +++++++++-
> 1 file changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua
> index b363abc..c704877 100644
> --- a/test/PUC-Lua-5.1-tests/db.lua
> +++ b/test/PUC-Lua-5.1-tests/db.lua
> @@ -491,7 +491,15 @@ local _, l = coroutine.resume(co, 10)
> local x = debug.getinfo(co, 1, "lfLS")
> assert(x.currentline == l.currentline and x.activelines[x.currentline])
> assert(type(x.func) == "function")
> -for i=x.linedefined + 1, x.lastlinedefined do
> +-- LuaJIT does not report line with single "end" statement
> +-- (the last line of the function) as an active line in
> +-- debug.getinfo(), unlike Lua does. There is no bytecode
> +-- related to this line, so it is "unreachable" and
> +-- may be considered not active.
> +-- See also https://github.com/tarantool/tarantool/issues/5708.
> +-- LuaJIT: Test is adapted for LuaJIT's behaviour by avoiding
> +-- the last line check.
> +for i=x.linedefined + 1, x.lastlinedefined - 1 do
>   assert(x.activelines[i])
>   x.activelines[i] = nil
> end
> -- 
> 2.31.0
> 


^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 11/30] test: adapt getlocal PUC test for vararg func
  2021-03-26 11:47   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-26 14:52     ` Sergey Kaplun via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 14:52 UTC (permalink / raw)
  To: Sergey Ostanevich; +Cc: tarantool-patches

Hi, thanks for the review!

I've changed s/first/local/ in the commit message and the comment,
considering your comment for the previous patch.
Also, I've added link to the issue to close.

===================================================================
test: adapt getlocal PUC test for vararg func

Lua 5.1 interprets `...` in the vararg functions like an additional
local argument unlike LuaJIT does. So, `a:f()` function will not set
corresponding table `arg`, as test expects.

Implicit `arg` parameter for old-style vararg functions was finally
removed in Lua 5.2. The test is adapted from PUC-Rio Lua 5.2 test suite
by removing additional check for amountt of arguments via `arg.n`.
Lua 5.2 test suite is taken from
https://www.lua.org/tests/lua-5.2.0-tests.tar.gz.

Closes tarantool/tarantool#5694
Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
===================================================================

===================================================================
diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua
index 8ea6af7..69e19b6 100644
--- a/test/PUC-Lua-5.1-tests/db.lua
+++ b/test/PUC-Lua-5.1-tests/db.lua
@@ -302,7 +302,7 @@ end, "c")
 a:f(1,2,3,4,5)
 
 -- LuaJIT: Lua 5.1 interprets `...` in the vararg functions like
--- an additional first argument unlike LuaJIT does.
+-- an additional local argument unlike LuaJIT does.
 -- So, `a:f()` function will not set corresponding table `arg`,
 -- as test expects.
 -- Implicit `arg` parameter for old-style vararg functions was
===================================================================

On 26.03.21, Sergey Ostanevich wrote:
> LGTM
> 
> Sergos
> 
> > On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote:
> > 
> > Lua 5.1 interprets `...` in the vararg functions like an additional
> > first argument unlike LuaJIT does. So, `a:f()` function will not set
> > corresponding table `arg`, as test expects.
> > 
> > Implicit `arg` parameter for old-style vararg functions was finally
> > removed in Lua 5.2. The test is adapted from PUC-Rio Lua 5.2 test suite
> > by removing additional check for amountt of arguments via `arg.n`.
> > Lua 5.2 test suite is taken from
> > https://www.lua.org/tests/lua-5.2.0-tests.tar.gz.
> > 
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ---
> > test/PUC-Lua-5.1-tests/db.lua | 11 ++++++++++-
> > 1 file changed, 10 insertions(+), 1 deletion(-)
> > 
> > diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua
> > index e5d8885..6985c29 100644
> > --- a/test/PUC-Lua-5.1-tests/db.lua
> > +++ b/test/PUC-Lua-5.1-tests/db.lua
> > @@ -300,7 +300,16 @@ debug.sethook(function (e)
> > end, "c")
> > 
> > a:f(1,2,3,4,5)
> > -assert(X.self == a and X.a == 1   and X.b == 2 and X.arg.n == 3 and X.c == nil)
> > +
> > +-- LuaJIT: Lua 5.1 interprets `...` in the vararg functions like
> > +-- an additional first argument unlike LuaJIT does.
> > +-- So, `a:f()` function will not set corresponding table `arg`,
> > +-- as test expects.
> > +-- Implicit `arg` parameter for old-style vararg functions was
> > +-- finally removed in Lua 5.2
> > +-- The test is adapted from PUC-Rio Lua 5.2 test suite by removing
> > +-- additional `arg.n == 3` check.
> > +assert(X.self == a and X.a == 1   and X.b == 2 and X.c == nil)
> > assert(XX == 12)
> > assert(debug.gethook() == nil)
> > 
> > -- 
> > 2.31.0
> > 
> 

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 20/30] test: adapt PUC Lua test for args in vararg func
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 20/30] test: adapt PUC Lua test for args in vararg func Sergey Kaplun via Tarantool-patches
@ 2021-03-26 14:54   ` Sergey Kaplun via Tarantool-patches
  2021-03-26 15:22     ` Sergey Ostanevich via Tarantool-patches
  2021-03-31  9:51   ` Igor Munkin via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 14:54 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches


I've changed s/first/local/ in the commit message and the comment,
considering comment by Sergos for the previous patch.

===================================================================
test: adapt PUC Lua test for args in vararg func

Lua 5.1 interprets ... in the vararg functions like additional local
argument, unlike LuaJIT does. All extra arguments is set into `arg`
variable.

Implicit `arg` parameter for old-style vararg functions was finally
removed in Lua 5.2. This patch adjust tests in vararg.lua considering
Lua 5.2 test suite taken from
https://www.lua.org/tests/lua-5.2.0-tests.tar.gz.

Closes tarantool/tarantool#5712
Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
===================================================================

===================================================================
diff --git a/test/PUC-Lua-5.1-tests/vararg.lua b/test/PUC-Lua-5.1-tests/vararg.lua
index efb76c5..4d6ec6d 100644
--- a/test/PUC-Lua-5.1-tests/vararg.lua
+++ b/test/PUC-Lua-5.1-tests/vararg.lua
@@ -3,7 +3,7 @@ print('testing vararg')
 _G.arg = nil
 
 -- Lua 5.1 interprets ... in the vararg functions like additional
--- first argument, unlike LuaJIT does. All extra arguments is set
+-- local argument, unlike LuaJIT does. All extra arguments is set
 -- into `arg` variable. This extension is from Lua 5.2.
 -- See also https://github.com/tarantool/tarantool/issues/5712.
 -- LuaJIT: Test is adapted from PUC-Rio Lua 5.2 test suite.
===================================================================


On 26.03.21, Sergey Kaplun wrote:
> Lua 5.1 interprets ... in the vararg functions like additional first
> argument, unlike LuaJIT does. All extra arguments is set into `arg`
> variable.
> 
> Implicit `arg` parameter for old-style vararg functions was finally
> removed in Lua 5.2. This patch adjust tests in vararg.lua considering
> Lua 5.2 test suite taken from
> https://www.lua.org/tests/lua-5.2.0-tests.tar.gz.
> 
> Closes tarantool/tarantool#5712
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
>  test/PUC-Lua-5.1-tests/vararg.lua | 16 ++++++++++++----
>  1 file changed, 12 insertions(+), 4 deletions(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/vararg.lua b/test/PUC-Lua-5.1-tests/vararg.lua
> index ae068fa..efb76c5 100644
> --- a/test/PUC-Lua-5.1-tests/vararg.lua
> +++ b/test/PUC-Lua-5.1-tests/vararg.lua
> @@ -2,9 +2,13 @@ print('testing vararg')
>  
>  _G.arg = nil
>  
> +-- Lua 5.1 interprets ... in the vararg functions like additional
> +-- first argument, unlike LuaJIT does. All extra arguments is set
> +-- into `arg` variable. This extension is from Lua 5.2.
> +-- See also https://github.com/tarantool/tarantool/issues/5712.
> +-- LuaJIT: Test is adapted from PUC-Rio Lua 5.2 test suite.
>  function f(a, ...)
> -  assert(type(arg) == 'table')
> -  assert(type(arg.n) == 'number')
> +  local arg = {n = select('#', ...), ...}
>    for i=1,arg.n do assert(a[i]==arg[i]) end
>    return arg.n
>  end
> @@ -17,7 +21,9 @@ function c12 (...)
>    return res, 2
>  end
>  
> -function vararg (...) return arg end
> +-- LuaJIT: Test chunk is adapted from PUC-Rio Lua 5.2 test suite.
> +-- See the comment above.
> +function vararg (...) return {n = select('#', ...), ...} end
>  
>  local call = function (f, args) return f(unpack(args, 1, args.n)) end
>  
> @@ -42,7 +48,9 @@ a = call(print, {'+'})
>  assert(a == nil)
>  
>  local t = {1, 10}
> -function t:f (...) return self[arg[1]]+arg.n end
> +-- LuaJIT: Test chunk is adapted from PUC-Rio Lua 5.2 test suite.
> +-- See the comment above.
> +function t:f (...) local arg = {...}; return self[...]+#arg end
>  assert(t:f(1,4) == 3 and t:f(2) == 11)
>  print('+')
>  
> -- 
> 2.31.0
> 

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 15/30] test: disable PUC-Lua test for per-coroutine hooks
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 15/30] test: disable PUC-Lua test for per-coroutine hooks Sergey Kaplun via Tarantool-patches
@ 2021-03-26 14:54   ` Sergey Ostanevich via Tarantool-patches
  2021-03-30 22:16   ` Igor Munkin via Tarantool-patches
  1 sibling, 0 replies; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 14:54 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

LGTM.
Sergos


> On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> LuaJIT does not support per-coroutine hooks.
> See actual status at https://luajit.org/status.html.
> 
> This patch disables tests for per-coroutine hooks in <db.lua>.
> 
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
> test/PUC-Lua-5.1-tests/db.lua | 15 +++++++++++----
> 1 file changed, 11 insertions(+), 4 deletions(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua
> index c704877..8ea6af7 100644
> --- a/test/PUC-Lua-5.1-tests/db.lua
> +++ b/test/PUC-Lua-5.1-tests/db.lua
> @@ -511,8 +511,11 @@ a,b = debug.getlocal(co, 1, 2)
> assert(a == "a" and b == 1)
> debug.setlocal(co, 1, 2, "hi")
> assert(debug.gethook(co) == foo)
> -assert(table.getn(tr) == 2 and
> -       tr[1] == l.currentline-1 and tr[2] == l.currentline)
> +-- LuaJIT does not support per-coroutine hooks.
> +-- See also https://luajit.org/status.html.
> +-- LuaJIT: Test is disabled for LuaJIT.
> +-- assert(table.getn(tr) == 2 and
> +--        tr[1] == l.currentline-1 and tr[2] == l.currentline)
> 
> a,b,c = pcall(coroutine.resume, co)
> assert(a and b and c == l.currentline+1)
> @@ -520,9 +523,13 @@ checktraceback(co, {"yield", "in function <"})
> 
> a,b = coroutine.resume(co)
> assert(a and b == "hi")
> -assert(table.getn(tr) == 4 and tr[4] == l.currentline+2)
> +-- Behavior is different for LuaJIT. See the comment above.
> +-- LuaJIT: Test is disabled for LuaJIT.
> +-- assert(table.getn(tr) == 4 and tr[4] == l.currentline+2)
> assert(debug.gethook(co) == foo)
> -assert(debug.gethook() == nil)
> +-- Behavior is different for LuaJIT. See the comment above.
> +-- LuaJIT: Test is disabled for LuaJIT.
> +-- assert(debug.gethook() == nil)
> checktraceback(co, {})
> 
> 
> -- 
> 2.31.0
> 


^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 16/30] test: adapt PUC Lua test for %q in fmt for LuaJIT
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 16/30] test: adapt PUC Lua test for %q in fmt for LuaJIT Sergey Kaplun via Tarantool-patches
@ 2021-03-26 14:56   ` Sergey Ostanevich via Tarantool-patches
  2021-03-30 22:16   ` Igor Munkin via Tarantool-patches
  1 sibling, 0 replies; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 14:56 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

LGTM.
Sergos


> On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> LuaJIT: LuaJIT since v2.0.0-beta6 has extension from Lua 5.2:
> string.format(): %q reversible.
> See also https://luajit.org/extensions.html#lua52.
> 
> In Lua 5.1 string.format() does not accept string values containing
> embedded zeros, except as arguments to the '%q' option.
> In Lua 5.2 '\0' is not handled differently from other
> control chars in string.format('%q', ...).
> See commit 7cc981c14067d4b0e774a6bfb0acfc2f5c911f0d
> (string.format("%q", str) is now fully reversible
> (from Lua 5.2).).
> 
> This patch adapts test for LuaJIT and Lua 5.2 behaviour considering
> test from Lua 5.2 test suite taken from
> https://www.lua.org/tests/lua-5.2.0-tests.tar.gz.
> 
> Closes tarantool/tarantool#5710
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
> test/PUC-Lua-5.1-tests/strings.lua | 12 +++++++++++-
> 1 file changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/strings.lua b/test/PUC-Lua-5.1-tests/strings.lua
> index 237dbad..7c1dfb8 100644
> --- a/test/PUC-Lua-5.1-tests/strings.lua
> +++ b/test/PUC-Lua-5.1-tests/strings.lua
> @@ -102,7 +102,17 @@ print('+')
> 
> x = '"�lo"\n\\'
> assert(string.format('%q%s', x, x) == '"\\"�lo\\"\\\n\\\\""�lo"\n\\')
> -assert(string.format('%q', "\0") == [["\000"]])
> +-- LuaJIT: LuaJIT since v2.0.0-beta6 has extension from Lua 5.2:
> +-- string.format(): %q reversible.
> +-- In Lua 5.1 string.format() does not accept string values
> +-- containing embedded zeros, except as arguments to the q option.
> +-- In Lua 5.2 '\0' is not handled differently from other
> +-- control chars in string.format('%q', ...).
> +-- See commit 7cc981c14067d4b0e774a6bfb0acfc2f5c911f0d
> +-- (string.format("%q", str) is now fully reversible
> +-- (from Lua 5.2).).
> +-- Test is adapted from PUC-Rio Lua 5.2 test suite.
> +assert(string.format('%q', "\0") == [["\0"]])
> assert(string.format("\0%c\0%c%x\0", string.byte("�"), string.byte("b"), 140) ==
>               "\0�\0b8c\0")
> assert(string.format('') == "")
> -- 
> 2.31.0
> 


^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 17/30] test: disable locale-depended tests for Lua suite
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 17/30] test: disable locale-depended tests for Lua suite Sergey Kaplun via Tarantool-patches
@ 2021-03-26 14:58   ` Sergey Ostanevich via Tarantool-patches
  2021-03-30 22:16   ` Igor Munkin via Tarantool-patches
  1 sibling, 0 replies; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 14:58 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

LGTM.
Sergos


> On 26 Mar 2021, at 10:43, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> LuaJIT doesn't compare strings by `strcoll()`, like Lua 5.1 does.
> So locale-depended tests in <strings.lua> are disabled.
> 
> Also, LuaJIT doesn't use `strtod()` depended on the locale for parsing,
> unlike Lua does. See <src/lj_strscan.c> for more info.
> Locale-depended tests in <literals.lua> are disabled.
> 
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
> test/PUC-Lua-5.1-tests/literals.lua | 5 +++++
> test/PUC-Lua-5.1-tests/strings.lua  | 5 +++++
> 2 files changed, 10 insertions(+)
> 
> diff --git a/test/PUC-Lua-5.1-tests/literals.lua b/test/PUC-Lua-5.1-tests/literals.lua
> index 01d84d5..1b4f664 100644
> --- a/test/PUC-Lua-5.1-tests/literals.lua
> +++ b/test/PUC-Lua-5.1-tests/literals.lua
> @@ -158,6 +158,10 @@ end
> 
> 
> -- testing decimal point locale
> +-- LuaJIT: LuaJIT doesn't use `strtod()` depended on the locale,
> +-- unlike Lua does. See <src/lj_strscan.c> for more info.
> +-- Tests are disabled for LuaJIT.
> +--[[
> if os.setlocale("pt_BR") or os.setlocale("ptb") then
>   assert(tonumber("3,4") == 3.4 and tonumber"3.4" == nil)
>   assert(assert(loadstring("return 3.4"))() == 3.4)
> @@ -171,6 +175,7 @@ else
>   (Message or print)(
>    '\a\n >>> pt_BR locale not available: skipping decimal point tests <<<\n\a')
> end
> +--]]
> 
> 
> print('OK')
> diff --git a/test/PUC-Lua-5.1-tests/strings.lua b/test/PUC-Lua-5.1-tests/strings.lua
> index 7c1dfb8..6ae3f51 100644
> --- a/test/PUC-Lua-5.1-tests/strings.lua
> +++ b/test/PUC-Lua-5.1-tests/strings.lua
> @@ -162,6 +162,10 @@ local function trylocale (w)
>   return false
> end
> 
> +-- LuaJIT: LuaJIT doesn't compare strings by `strcoll()`,
> +-- like Lua 5.1 does.
> +-- Tests are disabled for LuaJIT.
> +--[[
> if not trylocale("collate")  then
>   print("locale not supported")
> else
> @@ -176,6 +180,7 @@ else
>   assert(string.gsub("����", "%u", "x") == "�x�x")
>   assert(string.upper"���{xuxu}��o" == "���{XUXU}��O")
> end
> +--]]
> 
> os.setlocale("C")
> assert(os.setlocale() == 'C')
> -- 
> 2.31.0
> 


^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 18/30] test: replace math.mod to math.fmod for Lua tests
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 18/30] test: replace math.mod to math.fmod for Lua tests Sergey Kaplun via Tarantool-patches
@ 2021-03-26 15:12   ` Sergey Ostanevich via Tarantool-patches
  2021-03-30 22:17     ` Igor Munkin via Tarantool-patches
  2021-03-26 15:16   ` Sergey Ostanevich via Tarantool-patches
  2021-03-30 22:16   ` Igor Munkin via Tarantool-patches
  2 siblings, 1 reply; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 15:12 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Hmmm. Is it better to mokeypatch it as ‘math.mod = math.fmod or math.mod’?

Sergos.


> On 26 Mar 2021, at 10:43, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> In Lua 5.1 math.mod() is renamed to math.fmod() if build Lua 5.1 without
> flag `-DLUA_COMPAT_MOD`.
> LuaJIT has math.fmod() instead old-style math.mod() built-in.
> 
> This patch replaces usage of math.mod with new-style math.fmod
> in the following files:
> * closure.lua
> * constructs.lua
> * math.lua
> * nextvar.lua
> 
> Closes tarantool/tarantool#5711
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
> test/PUC-Lua-5.1-tests/closure.lua    | 3 ++-
> test/PUC-Lua-5.1-tests/constructs.lua | 6 ++++--
> test/PUC-Lua-5.1-tests/math.lua       | 3 ++-
> test/PUC-Lua-5.1-tests/nextvar.lua    | 3 ++-
> 4 files changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/closure.lua b/test/PUC-Lua-5.1-tests/closure.lua
> index 27ca0ad..7f56ab8 100644
> --- a/test/PUC-Lua-5.1-tests/closure.lua
> +++ b/test/PUC-Lua-5.1-tests/closure.lua
> @@ -254,7 +254,8 @@ function filter (p, g)
>     while 1 do
>       local n = g()
>       if n == nil then return end
> -      if math.mod(n, p) ~= 0 then coroutine.yield(n) end
> +      -- LuaJIT: use `math.fmod()` instead old-style `math.mod()`.
> +      if math.fmod(n, p) ~= 0 then coroutine.yield(n) end
>     end
>   end)
> end
> diff --git a/test/PUC-Lua-5.1-tests/constructs.lua b/test/PUC-Lua-5.1-tests/constructs.lua
> index 5fb3798..18d1789 100644
> --- a/test/PUC-Lua-5.1-tests/constructs.lua
> +++ b/test/PUC-Lua-5.1-tests/constructs.lua
> @@ -202,7 +202,8 @@ function ID(x) return x end
> 
> function f(t, i)
>   local b = t.n
> -  local res = math.mod(math.floor(i/c), b)+1
> +  -- LuaJIT: use `math.fmod()` instead old-style `math.mod()`.
> +  local res = math.fmod(math.floor(i/c), b)+1
>   c = c*b
>   return t[res]
> end
> @@ -233,7 +234,8 @@ repeat
>   ]], s1, s, s1, s, s1, s, s1, s, s)
>   assert(loadstring(s))()
>   assert(X and not NX and not WX1 == K and not WX2 == K)
> -  if math.mod(i,4000) == 0 then print('+') end
> +  -- LuaJIT: use `math.fmod()` instead old-style `math.mod()`.
> +  if math.fmod(i,4000) == 0 then print('+') end
>   i = i+1
> until i==c
> 
> diff --git a/test/PUC-Lua-5.1-tests/math.lua b/test/PUC-Lua-5.1-tests/math.lua
> index 5076f38..8f0526f 100644
> --- a/test/PUC-Lua-5.1-tests/math.lua
> +++ b/test/PUC-Lua-5.1-tests/math.lua
> @@ -100,7 +100,8 @@ assert(math.abs(-10) == 10)
> assert(eq(math.atan2(1,0), math.pi/2))
> assert(math.ceil(4.5) == 5.0)
> assert(math.floor(4.5) == 4.0)
> -assert(math.mod(10,3) == 1)
> +-- LuaJIT: use `math.fmod()` instead old-style `math.mod()`.
> +assert(math.fmod(10,3) == 1)
> assert(eq(math.sqrt(10)^2, 10))
> assert(eq(math.log10(2), math.log(2)/math.log(10)))
> assert(eq(math.exp(0), 1))
> diff --git a/test/PUC-Lua-5.1-tests/nextvar.lua b/test/PUC-Lua-5.1-tests/nextvar.lua
> index 7ceaa75..81159dc 100644
> --- a/test/PUC-Lua-5.1-tests/nextvar.lua
> +++ b/test/PUC-Lua-5.1-tests/nextvar.lua
> @@ -201,7 +201,8 @@ print('+')
> 
> a = {}
> for i=0,10000 do
> -  if math.mod(i,10) ~= 0 then
> +  -- LuaJIT: use `math.fmod()` instead old-style `math.mod()`.
> +  if math.fmod(i,10) ~= 0 then
>     a['x'..i] = i
>   end
> end
> -- 
> 2.31.0
> 


^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 19/30] test: remove assert for string.gfind check
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 19/30] test: remove assert for string.gfind check Sergey Kaplun via Tarantool-patches
@ 2021-03-26 15:14   ` Sergey Ostanevich via Tarantool-patches
  2021-03-30 22:17   ` Igor Munkin via Tarantool-patches
  1 sibling, 0 replies; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 15:14 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

LGTM.
Sergos

> On 26 Mar 2021, at 10:43, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> In Lua 5.1 function `string.gfind()` was renamed to `string.gmatch()`.
> You can use it if Lua 5.1 is built with compile-time option
> `-DLUA_COMPAT_GFIND`.
> This built-in is removed from LuaJIT.
> 
> This patch removes test checking that `string.gfind()` and
> `string.gmatch() is the same function.
> 
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
> test/PUC-Lua-5.1-tests/pm.lua | 1 -
> 1 file changed, 1 deletion(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/pm.lua b/test/PUC-Lua-5.1-tests/pm.lua
> index fa125dc..b159b6b 100644
> --- a/test/PUC-Lua-5.1-tests/pm.lua
> +++ b/test/PUC-Lua-5.1-tests/pm.lua
> @@ -223,7 +223,6 @@ assert(string.gsub("a alo b hi", "%w%w+", t) == "a ALO b HI")
> 
> 
> -- tests for gmatch
> -assert(string.gfind == string.gmatch)
> local a = 0
> for i in string.gmatch('abcde', '()') do assert(i == a+1); a=i end
> assert(a==6)
> -- 
> 2.31.0
> 


^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 18/30] test: replace math.mod to math.fmod for Lua tests
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 18/30] test: replace math.mod to math.fmod for Lua tests Sergey Kaplun via Tarantool-patches
  2021-03-26 15:12   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-26 15:16   ` Sergey Ostanevich via Tarantool-patches
  2021-03-30 22:16   ` Igor Munkin via Tarantool-patches
  2 siblings, 0 replies; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 15:16 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Hmmm. Is it better to mokeypatch it as ‘math.mod = math.fmod or math.mod’?

Sergos.


> On 26 Mar 2021, at 10:43, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> In Lua 5.1 math.mod() is renamed to math.fmod() if build Lua 5.1 without
> flag `-DLUA_COMPAT_MOD`.
> LuaJIT has math.fmod() instead old-style math.mod() built-in.
> 
> This patch replaces usage of math.mod with new-style math.fmod
> in the following files:
> * closure.lua
> * constructs.lua
> * math.lua
> * nextvar.lua
> 
> Closes tarantool/tarantool#5711
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
> test/PUC-Lua-5.1-tests/closure.lua    | 3 ++-
> test/PUC-Lua-5.1-tests/constructs.lua | 6 ++++--
> test/PUC-Lua-5.1-tests/math.lua       | 3 ++-
> test/PUC-Lua-5.1-tests/nextvar.lua    | 3 ++-
> 4 files changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/closure.lua b/test/PUC-Lua-5.1-tests/closure.lua
> index 27ca0ad..7f56ab8 100644
> --- a/test/PUC-Lua-5.1-tests/closure.lua
> +++ b/test/PUC-Lua-5.1-tests/closure.lua
> @@ -254,7 +254,8 @@ function filter (p, g)
>    while 1 do
>      local n = g()
>      if n == nil then return end
> -      if math.mod(n, p) ~= 0 then coroutine.yield(n) end
> +      -- LuaJIT: use `math.fmod()` instead old-style `math.mod()`.
> +      if math.fmod(n, p) ~= 0 then coroutine.yield(n) end
>    end
>  end)
> end
> diff --git a/test/PUC-Lua-5.1-tests/constructs.lua b/test/PUC-Lua-5.1-tests/constructs.lua
> index 5fb3798..18d1789 100644
> --- a/test/PUC-Lua-5.1-tests/constructs.lua
> +++ b/test/PUC-Lua-5.1-tests/constructs.lua
> @@ -202,7 +202,8 @@ function ID(x) return x end
> 
> function f(t, i)
>  local b = t.n
> -  local res = math.mod(math.floor(i/c), b)+1
> +  -- LuaJIT: use `math.fmod()` instead old-style `math.mod()`.
> +  local res = math.fmod(math.floor(i/c), b)+1
>  c = c*b
>  return t[res]
> end
> @@ -233,7 +234,8 @@ repeat
>  ]], s1, s, s1, s, s1, s, s1, s, s)
>  assert(loadstring(s))()
>  assert(X and not NX and not WX1 == K and not WX2 == K)
> -  if math.mod(i,4000) == 0 then print('+') end
> +  -- LuaJIT: use `math.fmod()` instead old-style `math.mod()`.
> +  if math.fmod(i,4000) == 0 then print('+') end
>  i = i+1
> until i==c
> 
> diff --git a/test/PUC-Lua-5.1-tests/math.lua b/test/PUC-Lua-5.1-tests/math.lua
> index 5076f38..8f0526f 100644
> --- a/test/PUC-Lua-5.1-tests/math.lua
> +++ b/test/PUC-Lua-5.1-tests/math.lua
> @@ -100,7 +100,8 @@ assert(math.abs(-10) == 10)
> assert(eq(math.atan2(1,0), math.pi/2))
> assert(math.ceil(4.5) == 5.0)
> assert(math.floor(4.5) == 4.0)
> -assert(math.mod(10,3) == 1)
> +-- LuaJIT: use `math.fmod()` instead old-style `math.mod()`.
> +assert(math.fmod(10,3) == 1)
> assert(eq(math.sqrt(10)^2, 10))
> assert(eq(math.log10(2), math.log(2)/math.log(10)))
> assert(eq(math.exp(0), 1))
> diff --git a/test/PUC-Lua-5.1-tests/nextvar.lua b/test/PUC-Lua-5.1-tests/nextvar.lua
> index 7ceaa75..81159dc 100644
> --- a/test/PUC-Lua-5.1-tests/nextvar.lua
> +++ b/test/PUC-Lua-5.1-tests/nextvar.lua
> @@ -201,7 +201,8 @@ print('+')
> 
> a = {}
> for i=0,10000 do
> -  if math.mod(i,10) ~= 0 then
> +  -- LuaJIT: use `math.fmod()` instead old-style `math.mod()`.
> +  if math.fmod(i,10) ~= 0 then
>    a['x'..i] = i
>  end
> end
> -- 
> 2.31.0
> 


^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 20/30] test: adapt PUC Lua test for args in vararg func
  2021-03-26 14:54   ` Sergey Kaplun via Tarantool-patches
@ 2021-03-26 15:22     ` Sergey Ostanevich via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 15:22 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

LGTM.
Sergos

> On 26 Mar 2021, at 17:54, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> 
> I've changed s/first/local/ in the commit message and the comment,
> considering comment by Sergos for the previous patch.
> 
> ===================================================================
> test: adapt PUC Lua test for args in vararg func
> 
> Lua 5.1 interprets ... in the vararg functions like additional local
> argument, unlike LuaJIT does. All extra arguments is set into `arg`
> variable.
> 
> Implicit `arg` parameter for old-style vararg functions was finally
> removed in Lua 5.2. This patch adjust tests in vararg.lua considering
> Lua 5.2 test suite taken from
> https://www.lua.org/tests/lua-5.2.0-tests.tar.gz.
> 
> Closes tarantool/tarantool#5712
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ===================================================================
> 
> ===================================================================
> diff --git a/test/PUC-Lua-5.1-tests/vararg.lua b/test/PUC-Lua-5.1-tests/vararg.lua
> index efb76c5..4d6ec6d 100644
> --- a/test/PUC-Lua-5.1-tests/vararg.lua
> +++ b/test/PUC-Lua-5.1-tests/vararg.lua
> @@ -3,7 +3,7 @@ print('testing vararg')
> _G.arg = nil
> 
> -- Lua 5.1 interprets ... in the vararg functions like additional
> --- first argument, unlike LuaJIT does. All extra arguments is set
> +-- local argument, unlike LuaJIT does. All extra arguments is set
> -- into `arg` variable. This extension is from Lua 5.2.
> -- See also https://github.com/tarantool/tarantool/issues/5712.
> -- LuaJIT: Test is adapted from PUC-Rio Lua 5.2 test suite.
> ===================================================================
> 
> 
> On 26.03.21, Sergey Kaplun wrote:
>> Lua 5.1 interprets ... in the vararg functions like additional first
>> argument, unlike LuaJIT does. All extra arguments is set into `arg`
>> variable.
>> 
>> Implicit `arg` parameter for old-style vararg functions was finally
>> removed in Lua 5.2. This patch adjust tests in vararg.lua considering
>> Lua 5.2 test suite taken from
>> https://www.lua.org/tests/lua-5.2.0-tests.tar.gz.
>> 
>> Closes tarantool/tarantool#5712
>> Part of tarantool/tarantool#5845
>> Part of tarantool/tarantool#4473
>> ---
>> test/PUC-Lua-5.1-tests/vararg.lua | 16 ++++++++++++----
>> 1 file changed, 12 insertions(+), 4 deletions(-)
>> 
>> diff --git a/test/PUC-Lua-5.1-tests/vararg.lua b/test/PUC-Lua-5.1-tests/vararg.lua
>> index ae068fa..efb76c5 100644
>> --- a/test/PUC-Lua-5.1-tests/vararg.lua
>> +++ b/test/PUC-Lua-5.1-tests/vararg.lua
>> @@ -2,9 +2,13 @@ print('testing vararg')
>> 
>> _G.arg = nil
>> 
>> +-- Lua 5.1 interprets ... in the vararg functions like additional
>> +-- first argument, unlike LuaJIT does. All extra arguments is set
>> +-- into `arg` variable. This extension is from Lua 5.2.
>> +-- See also https://github.com/tarantool/tarantool/issues/5712.
>> +-- LuaJIT: Test is adapted from PUC-Rio Lua 5.2 test suite.
>> function f(a, ...)
>> -  assert(type(arg) == 'table')
>> -  assert(type(arg.n) == 'number')
>> +  local arg = {n = select('#', ...), ...}
>>   for i=1,arg.n do assert(a[i]==arg[i]) end
>>   return arg.n
>> end
>> @@ -17,7 +21,9 @@ function c12 (...)
>>   return res, 2
>> end
>> 
>> -function vararg (...) return arg end
>> +-- LuaJIT: Test chunk is adapted from PUC-Rio Lua 5.2 test suite.
>> +-- See the comment above.
>> +function vararg (...) return {n = select('#', ...), ...} end
>> 
>> local call = function (f, args) return f(unpack(args, 1, args.n)) end
>> 
>> @@ -42,7 +48,9 @@ a = call(print, {'+'})
>> assert(a == nil)
>> 
>> local t = {1, 10}
>> -function t:f (...) return self[arg[1]]+arg.n end
>> +-- LuaJIT: Test chunk is adapted from PUC-Rio Lua 5.2 test suite.
>> +-- See the comment above.
>> +function t:f (...) local arg = {...}; return self[...]+#arg end
>> assert(t:f(1,4) == 3 and t:f(2) == 11)
>> print('+')
>> 
>> -- 
>> 2.31.0
>> 
> 
> -- 
> Best regards,
> Sergey Kaplun


^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 21/30] test: disable test for getfenv in closure tailcall
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 21/30] test: disable test for getfenv in closure tailcall Sergey Kaplun via Tarantool-patches
@ 2021-03-26 15:41   ` Sergey Ostanevich via Tarantool-patches
  2021-03-31  9:51   ` Igor Munkin via Tarantool-patches
  1 sibling, 0 replies; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 15:41 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

LGTM.
Sergos

> On 26 Mar 2021, at 10:43, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> LuaJIT doesn't take into account tail calls for call-level counting, so
> getfenv() behaviour is different from Lua 5.1 in tail calls.
> 
> This patch disables test for the return result of tail call getfenv().
> Default value (equals 1) of getfenv() function's argument (function
> level) is invalid for this tail call -- LuaJIT can't provide necessary
> debug information for the frame.
> 
> Relates to tarantool/tarantool#5713
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
> test/PUC-Lua-5.1-tests/closure.lua | 9 ++++++++-
> 1 file changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/closure.lua b/test/PUC-Lua-5.1-tests/closure.lua
> index 7f56ab8..7af842f 100644
> --- a/test/PUC-Lua-5.1-tests/closure.lua
> +++ b/test/PUC-Lua-5.1-tests/closure.lua
> @@ -174,7 +174,14 @@ f = coroutine.wrap(foo)
> local a = {}
> assert(f(a) == _G)
> local a,b = pcall(f)
> -assert(a and b == _G)
> +-- LuaJIT doesn't take into account tail calls for call-level
> +-- counting, so getfenv() behaviour is different in tail calls.
> +-- For example, this `pcall()` returns false, because getfenv()
> +-- default level is 1 which is invalid for this case when
> +-- is called from tail call (lj_debug_frame() returns NULL).
> +-- See also https://github.com/tarantool/tarantool/issues/5713.
> +-- FIXME: Test is disabled for LuaJIT for now.
> +-- assert(a and b == _G)
> 
> 
> -- tests for multiple yield/resume arguments
> -- 
> 2.31.0
> 


^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 22/30] test: disable PUC Lua test for var names in error
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 22/30] test: disable PUC Lua test for var names in error Sergey Kaplun via Tarantool-patches
@ 2021-03-26 15:44   ` Sergey Ostanevich via Tarantool-patches
  2021-03-26 16:01     ` Sergey Kaplun via Tarantool-patches
  2021-03-31 19:23   ` Igor Munkin via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 15:44 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Nit in message, LGTM.
Sergos

> On 26 Mar 2021, at 10:43, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> LuaJIT includes variable name to the error report, when try to
> call non-function object without __call methamethod.
> Also, LuaJIT includes variable name to the error report, when try to
> perform unacceptable arifmetic operation with the variable.
                       arithmetic
> Lua 5.1 doesn't report variable name in these errors.
> 
> Test ckecked that variable name aren't reported are disabled by
> this patch.
> 
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
> test/PUC-Lua-5.1-tests/errors.lua | 9 +++++++--
> 1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua
> index e881211..cf24e40 100644
> --- a/test/PUC-Lua-5.1-tests/errors.lua
> +++ b/test/PUC-Lua-5.1-tests/errors.lua
> @@ -72,8 +72,13 @@ checkmessage("b=1; local aaa='a'; x=aaa+b", "local 'aaa'")
> checkmessage("aaa={}; x=3/aaa", "global 'aaa'")
> checkmessage("aaa='2'; b=nil;x=aaa*b", "global 'b'")
> checkmessage("aaa={}; x=-aaa", "global 'aaa'")
> -assert(not string.find(doit"aaa={}; x=(aaa or aaa)+(aaa and aaa)", "'aaa'"))
> -assert(not string.find(doit"aaa={}; (aaa or aaa)()", "'aaa'"))
> +-- LuaJIT: LuaJIT includes variable name to the error report.
> +-- It looks like:
> +-- "attempt to perform arithmetic on global 'aaa' (a table value)"
> +-- Lua 5.1 doesn't report variable name here.
> +-- Tests are disabled for LuaJIT.
> +-- assert(not string.find(doit"aaa={}; x=(aaa or aaa)+(aaa and aaa)", "'aaa'"))
> +-- assert(not string.find(doit"aaa={}; (aaa or aaa)()", "'aaa'"))
> 
> checkmessage([[aaa=9
> repeat until 3==3
> -- 
> 2.31.0
> 


^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 23/30] test: disable PUC Lua test for fast function name
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 23/30] test: disable PUC Lua test for fast function name Sergey Kaplun via Tarantool-patches
@ 2021-03-26 15:45   ` Sergey Ostanevich via Tarantool-patches
  2021-03-31 19:23   ` Igor Munkin via Tarantool-patches
  1 sibling, 0 replies; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 15:45 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

LGTM.
Sergos

> On 26 Mar 2021, at 10:43, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> LuaJIT can't determine bytecode position for non Lua functions
> (in particular for fast functions) and, therefore, detect built-in
> function names for errors in tail calls.
> 
> This patch disables test that checks name of built-in functions
> reported in error in tail call.
> 
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
> test/PUC-Lua-5.1-tests/errors.lua | 10 +++++++---
> 1 file changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua
> index cf24e40..af776a7 100644
> --- a/test/PUC-Lua-5.1-tests/errors.lua
> +++ b/test/PUC-Lua-5.1-tests/errors.lua
> @@ -105,9 +105,13 @@ while 1 do
>   insert(prefix, a)
> end]], "global 'insert'")
> 
> -checkmessage([[  -- tail call
> -  return math.sin("a")
> -]], "'sin'")
> +-- LuaJIT: Can't determine bytecode position for non Lua functions
> +-- (in particular for fast functions) and, therefore, detect fast
> +-- function names for errors in tail calls.
> +-- The test is disabled for LuaJIT.
> +-- checkmessage([[  -- tail call
> +--   return math.sin("a")
> +-- ]], "'sin'")
> 
> checkmessage([[collectgarbage("nooption")]], "invalid option")
> 
> -- 
> 2.31.0
> 


^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 24/30] test: disable PUC Lua test for non-asci identifier
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 24/30] test: disable PUC Lua test for non-asci identifier Sergey Kaplun via Tarantool-patches
@ 2021-03-26 15:46   ` Sergey Ostanevich via Tarantool-patches
  2021-03-31 19:23   ` Igor Munkin via Tarantool-patches
  1 sibling, 0 replies; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 15:46 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

LGTM.
Sergos

> On 26 Mar 2021, at 10:43, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> LuaJIT does not avoid to use non-alphanumeric symbols as identifiers,
> unlike Lua does.
> 
> This patch disables test that expects an error during parsing variable
> contains octal \255 as the first char in a variable name.
> 
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
> test/PUC-Lua-5.1-tests/errors.lua | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua
> index af776a7..028224c 100644
> --- a/test/PUC-Lua-5.1-tests/errors.lua
> +++ b/test/PUC-Lua-5.1-tests/errors.lua
> @@ -202,7 +202,11 @@ checksyntax("[[a]]", "", "[[a]]", 1)
> checksyntax("'aa'", "", "'aa'", 1)
> 
> -- test 255 as first char in a chunk
> -checksyntax("\255a = 1", "", "\255", 1)
> +-- LuaJIT does not avoid to use non-alphanumeric symbols
> +-- as identifiers, unlike Lua does.
> +-- For more details see <src/lj_char.c> and <src/lj_lex.c>.
> +-- LuaJIT: Test is disabled for LuaJIT.
> +-- checksyntax("\255a = 1", "", "\255", 1)
> 
> doit('I = loadstring("a=9+"); a=3')
> assert(a==3 and I == nil)
> -- 
> 2.31.0
> 


^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 25/30] test: disable PUC Lua error test for syntax level
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 25/30] test: disable PUC Lua error test for syntax level Sergey Kaplun via Tarantool-patches
@ 2021-03-26 15:52   ` Sergey Ostanevich via Tarantool-patches
  2021-03-31 19:24   ` Igor Munkin via Tarantool-patches
  1 sibling, 0 replies; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 15:52 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

LGTM.
Sergos

> On 26 Mar 2021, at 10:43, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> When LuaJIT is compiled with LUAJIT_ENABLE_GC64, LJ_MAX_SLOTS limit is
> reached and error LJ_ERR_XSLOTS ("function or expression too complex")
> is raised earlier, than LJ_MAX_XLEVEL limit is reached and error
> LJ_ERR_XLEVELS ("chunk has too many syntax levels") is raised.
> 
> This patch disabled test expected the LJ_ERR_XLEVEL error, but
> failing with the LJ_ERR_XSLOTS error.
> 
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
> test/PUC-Lua-5.1-tests/errors.lua | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua
> index 028224c..328976e 100644
> --- a/test/PUC-Lua-5.1-tests/errors.lua
> +++ b/test/PUC-Lua-5.1-tests/errors.lua
> @@ -228,7 +228,13 @@ local function testrep (init, rep)
> end
> testrep("a=", "{")
> testrep("a=", "(")
> -testrep("", "a(")
> +-- LuaJIT: When compiled with LUAJIT_ENABLE_GC64, LJ_MAX_SLOTS
> +-- limit is reached and error LJ_ERR_XSLOTS ("function or
> +-- expression too complex") is raised earlier, than LJ_MAX_XLEVEL
> +-- limit is reached and error LJ_ERR_XLEVELS ("chunk has too many
> +-- syntax levels") is raised.
> +-- Test is disabled for LuaJIT.
> +-- testrep("", "a(")
> testrep("", "do ")
> testrep("", "while a do ")
> testrep("", "if a then else ")
> -- 
> 2.31.0
> 


^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 26/30] test: disable tests with multiple -l options
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 26/30] test: disable tests with multiple -l options Sergey Kaplun via Tarantool-patches
@ 2021-03-26 15:56   ` Sergey Ostanevich via Tarantool-patches
  2021-03-31 19:24   ` Igor Munkin via Tarantool-patches
  1 sibling, 0 replies; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 15:56 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

LGTM.
Sergos 

> On 26 Mar 2021, at 10:43, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> Tarantool may crash when -e or -l option and their argument are not
> separated by space.
> 
> This patch disables tests leading to crash.
> 
> Relates to tarantool/tarantool#5747
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
> test/PUC-Lua-5.1-tests/main.lua | 16 ++++++++++++----
> 1 file changed, 12 insertions(+), 4 deletions(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua
> index cf6d533..73bff52 100644
> --- a/test/PUC-Lua-5.1-tests/main.lua
> +++ b/test/PUC-Lua-5.1-tests/main.lua
> @@ -52,8 +52,12 @@ end
> -- test 2 files
> prepfile("print(1); a=2")
> prepfile("print(a)", otherprog)
> -RUN("lua -l %s -l%s -lstring -l io %s > %s", prog, otherprog, otherprog, out)
> -checkout("1\n2\n2\n")
> +-- FIXME: Tarantool may crash when -e or -l option and their
> +-- argument are not separated by space.
> +-- The test is disabled for the Tarantool binary.
> +-- See https://github.com/tarantool/tarantool/issues/5747.
> +-- RUN("lua -l %s -l%s -lstring -l io %s > %s", prog, otherprog, otherprog, out)
> +-- checkout("1\n2\n2\n")
> 
> -- LuaJIT: test file is adapted for LuaJIT's test system, see
> -- the comment near `progname` initialization.
> @@ -92,8 +96,12 @@ prepfile[[print(({...})[30])]]
> RUN("lua %s %s > %s", prog, string.rep(" a", 30), out)
> checkout("a\n")
> 
> -RUN([[lua "-eprint(1)" -ea=3 -e "print(a)" > %s]], out)
> -checkout("1\n3\n")
> +-- FIXME: Tarantool may crash when -e or -l option and their
> +-- argument are not separated by space.
> +-- The test is disabled for the Tarantool binary.
> +-- See https://github.com/tarantool/tarantool/issues/5747.
> +-- RUN([[lua "-eprint(1)" -ea=3 -e "print(a)" > %s]], out)
> +-- checkout("1\n3\n")
> 
> prepfile[[
>   print(
> -- 
> 2.31.0
> 


^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 27/30] test: disable PUC Lua test for checking arg layout
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 27/30] test: disable PUC Lua test for checking arg layout Sergey Kaplun via Tarantool-patches
@ 2021-03-26 15:58   ` Sergey Ostanevich via Tarantool-patches
  2021-03-31 19:24   ` Igor Munkin via Tarantool-patches
  1 sibling, 0 replies; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 15:58 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

LGTM.
Sergos

> On 26 Mar 2021, at 10:43, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> Unlike LuaJIT, Tarantool doesn't store the given CLI flags in `arg`,
> so the table has the following layout:
> * arg[-1] -- the binary name
> * arg[0]  -- the script name
> * arg[N]  -- the script argument for all N in [1, #arg]
> 
> This patch disables test checking `arg` layout by negative indexes.
> 
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
> test/PUC-Lua-5.1-tests/main.lua | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua
> index 73bff52..acc50a6 100644
> --- a/test/PUC-Lua-5.1-tests/main.lua
> +++ b/test/PUC-Lua-5.1-tests/main.lua
> @@ -71,7 +71,13 @@ local a = [[
> ]]
> a = string.format(a, progname)
> prepfile(a)
> -RUN('lua "-e " -- %s a b c', prog)
> +-- FIXME: Unlike LuaJIT, Tarantool doesn't store the given
> +-- CLI flags in `arg`, so the table has the following layout:
> +-- * arg[-1] -- the binary name
> +-- * arg[0]  -- the script name
> +-- * arg[N]  -- the script argument for all N in [1, #arg]
> +-- Test is disabled for the Tarantool binary.
> +-- RUN('lua "-e " -- %s a b c', prog)
> 
> -- test 'arg' availability in libraries
> -- LuaJIT: LuaJIT v2.1.0-beta3 has extension from Lua 5.3:
> -- 
> 2.31.0
> 


^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 28/30] test: disable PUC Lua test checking -h option
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 28/30] test: disable PUC Lua test checking -h option Sergey Kaplun via Tarantool-patches
@ 2021-03-26 15:58   ` Sergey Ostanevich via Tarantool-patches
  2021-03-31 19:24   ` Igor Munkin via Tarantool-patches
  1 sibling, 0 replies; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 15:58 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

LGTM.
Sergos

> On 26 Mar 2021, at 10:43, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> Tarantool returns zero status at exit with -h option, unlike Lua or
> LuaJIT does.
> 
> This patch disables test checking returning status, when binary
> runs with -h option.
> 
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
> test/PUC-Lua-5.1-tests/main.lua | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua
> index acc50a6..0ca7ef4 100644
> --- a/test/PUC-Lua-5.1-tests/main.lua
> +++ b/test/PUC-Lua-5.1-tests/main.lua
> @@ -201,7 +201,10 @@ assert(not os.remove(out))
> 
> RUN("lua -v")
> 
> -NoRun("lua -h")
> +-- FIXME: Tarantool returns zero status at exit with -h option,
> +-- unlike Lua or LuaJIT does.
> +-- The test is disabled for Tarantool binary.
> +-- NoRun("lua -h")
> NoRun("lua -e")
> NoRun("lua -e a")
> NoRun("lua -f")
> -- 
> 2.31.0
> 


^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 22/30] test: disable PUC Lua test for var names in error
  2021-03-26 15:44   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-26 16:01     ` Sergey Kaplun via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 16:01 UTC (permalink / raw)
  To: Sergey Ostanevich; +Cc: tarantool-patches

Hi!

Thanks for the review!

On 26.03.21, Sergey Ostanevich wrote:
> Nit in message, LGTM.
> Sergos
> 
> > On 26 Mar 2021, at 10:43, Sergey Kaplun <skaplun@tarantool.org> wrote:
> > 
> > LuaJIT includes variable name to the error report, when try to
> > call non-function object without __call methamethod.
> > Also, LuaJIT includes variable name to the error report, when try to
> > perform unacceptable arifmetic operation with the variable.
>                        arithmetic

Thanks! The new commit message is the following:

===================================================================
test: disable PUC Lua test for var names in error

LuaJIT includes a variable name to the error report, when try to
call non-function object without __call methamethod.
Also, LuaJIT includes a variable name to the error report, when try to
perform unacceptable arithmetic operation with the variable.
Lua 5.1 doesn't report variable name in these errors.

The test checked that variable name aren't reported are disabled by this
patch.

Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
===================================================================

> > Lua 5.1 doesn't report variable name in these errors.
> > 
> > Test ckecked that variable name aren't reported are disabled by
> > this patch.
> > 
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ---
> > test/PUC-Lua-5.1-tests/errors.lua | 9 +++++++--
> > 1 file changed, 7 insertions(+), 2 deletions(-)
> > 
> > diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua
> > index e881211..cf24e40 100644
> > --- a/test/PUC-Lua-5.1-tests/errors.lua
> > +++ b/test/PUC-Lua-5.1-tests/errors.lua
> > @@ -72,8 +72,13 @@ checkmessage("b=1; local aaa='a'; x=aaa+b", "local 'aaa'")
> > checkmessage("aaa={}; x=3/aaa", "global 'aaa'")
> > checkmessage("aaa='2'; b=nil;x=aaa*b", "global 'b'")
> > checkmessage("aaa={}; x=-aaa", "global 'aaa'")
> > -assert(not string.find(doit"aaa={}; x=(aaa or aaa)+(aaa and aaa)", "'aaa'"))
> > -assert(not string.find(doit"aaa={}; (aaa or aaa)()", "'aaa'"))
> > +-- LuaJIT: LuaJIT includes variable name to the error report.
> > +-- It looks like:
> > +-- "attempt to perform arithmetic on global 'aaa' (a table value)"
> > +-- Lua 5.1 doesn't report variable name here.
> > +-- Tests are disabled for LuaJIT.
> > +-- assert(not string.find(doit"aaa={}; x=(aaa or aaa)+(aaa and aaa)", "'aaa'"))
> > +-- assert(not string.find(doit"aaa={}; (aaa or aaa)()", "'aaa'"))
> > 
> > checkmessage([[aaa=9
> > repeat until 3==3
> > -- 
> > 2.31.0
> > 
> 

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 29/30] test: disable PUC Lua hanging GC test
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 29/30] test: disable PUC Lua hanging GC test Sergey Kaplun via Tarantool-patches
@ 2021-03-26 16:03   ` Sergey Ostanevich via Tarantool-patches
  2021-03-31 19:24     ` Igor Munkin via Tarantool-patches
  2021-03-31 19:24   ` Igor Munkin via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 16:03 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Can it be more relevant fix s/1000/n+1000/ for these two loops?

Although I start talking about an in-place fix, rather than a follow-up.

LGTM.
Sergos

> On 26 Mar 2021, at 10:43, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> Tarantool has too many objects at start. `gcinfo()` result is always
> greater than 1000 expected by the test. It leads to infinite loop in the
> test.
> 
> This patch disables GC test leading to hanging for Tarantool binary.
> 
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
> test/PUC-Lua-5.1-tests/gc.lua | 9 ++++++---
> 1 file changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/gc.lua b/test/PUC-Lua-5.1-tests/gc.lua
> index 072bbe9..7f9880f 100644
> --- a/test/PUC-Lua-5.1-tests/gc.lua
> +++ b/test/PUC-Lua-5.1-tests/gc.lua
> @@ -133,9 +133,12 @@ do
>     local a = {}
>   until gcinfo() > 1000
>   collectgarbage"restart"
> -  repeat
> -    local a = {}
> -  until gcinfo() < 1000
> +  -- Tarantool has too many objects at start. `gcinfo()` result
> +  -- is always greater than 1000.
> +  -- LuaJIT: The test is disabled for Tarantool binary.
> +  -- repeat
> +  --   local a = {}
> +  -- until gcinfo() < 1000
> end
> 
> lim = 15
> -- 
> 2.31.0
> 


^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 30/30] test: disable too depth recursive PUC Lua test
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 30/30] test: disable too depth recursive PUC Lua test Sergey Kaplun via Tarantool-patches
@ 2021-03-26 16:28   ` Sergey Ostanevich via Tarantool-patches
  2021-03-26 16:45     ` Sergey Kaplun via Tarantool-patches
  2021-03-31 19:24   ` Igor Munkin via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 16:28 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

[-- Attachment #1: Type: text/plain, Size: 1283 bytes --]

Did you look into the fiber_new_ex() interface?
I bet it’s doable to create a fiber with big enough stack.

Again, not about follow-ups: LGTM.
Sergos


> On 26 Mar 2021, at 10:43, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> The first Tarantool's fiber has only 512Kb of stack.
> It is not enough for depth recursive call in the test for
> `string.gsub()`.
> 
> This patch disables test leads to Tarantool crash.
> 
> Relates to tarantool/tarantool#5782
> Resolves tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
> test/PUC-Lua-5.1-tests/pm.lua | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/pm.lua b/test/PUC-Lua-5.1-tests/pm.lua
> index b159b6b..c6e42df 100644
> --- a/test/PUC-Lua-5.1-tests/pm.lua
> +++ b/test/PUC-Lua-5.1-tests/pm.lua
> @@ -207,7 +207,11 @@ function rev (s)
> end
> 
> local x = string.rep('012345', 10)
> -assert(rev(rev(x)) == x)
> +-- The first Tarantool's fiber has only 512Kb of stack.
> +-- It is not enough for this recursive call.
> +-- See also https://github.com/tarantool/tarantool/issues/5782.
> +-- FIXME: The test is disabled for Tarantool binary.
> +-- assert(rev(rev(x)) == x)
> 
> 
> -- gsub with tables
> -- 
> 2.31.0
> 


[-- Attachment #2: Type: text/html, Size: 3273 bytes --]

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 30/30] test: disable too depth recursive PUC Lua test
  2021-03-26 16:28   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-26 16:45     ` Sergey Kaplun via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 16:45 UTC (permalink / raw)
  To: Sergey Ostanevich; +Cc: tarantool-patches

Hi, thanks for the review!

On 26.03.21, Sergey Ostanevich wrote:
> Did you look into the fiber_new_ex() interface?
> I bet it’s doable to create a fiber with big enough stack.

Yes, there is necessary `stack_size` field in given
`struct fiber_attr`. But I don't see a Lua interface for stack
manipulation. May be it is necessary to create fiber via preparing
chunk in <luajit-test-init.lua> and use it. Looks like out of scope of
this ticket. Is it necessary to create a follow-up ticket?

> 
> Again, not about follow-ups: LGTM.
> Sergos
> 
> 
> > On 26 Mar 2021, at 10:43, Sergey Kaplun <skaplun@tarantool.org> wrote:
> > 
> > The first Tarantool's fiber has only 512Kb of stack.
> > It is not enough for depth recursive call in the test for
> > `string.gsub()`.
> > 
> > This patch disables test leads to Tarantool crash.
> > 
> > Relates to tarantool/tarantool#5782
> > Resolves tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ---
> > test/PUC-Lua-5.1-tests/pm.lua | 6 +++++-
> > 1 file changed, 5 insertions(+), 1 deletion(-)
> > 
> > diff --git a/test/PUC-Lua-5.1-tests/pm.lua b/test/PUC-Lua-5.1-tests/pm.lua
> > index b159b6b..c6e42df 100644
> > --- a/test/PUC-Lua-5.1-tests/pm.lua
> > +++ b/test/PUC-Lua-5.1-tests/pm.lua
> > @@ -207,7 +207,11 @@ function rev (s)
> > end
> > 
> > local x = string.rep('012345', 10)
> > -assert(rev(rev(x)) == x)
> > +-- The first Tarantool's fiber has only 512Kb of stack.
> > +-- It is not enough for this recursive call.
> > +-- See also https://github.com/tarantool/tarantool/issues/5782.
> > +-- FIXME: The test is disabled for Tarantool binary.
> > +-- assert(rev(rev(x)) == x)
> > 
> > 
> > -- gsub with tables
> > -- 
> > 2.31.0
> > 
> 

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 01/30] test: add PUC-Rio Lua 5.1 test suite
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 01/30] test: add " Sergey Kaplun via Tarantool-patches
  2021-03-26 10:14   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-30 22:13   ` Igor Munkin via Tarantool-patches
  2021-04-01  8:11     ` Sergey Kaplun via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-30 22:13 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the patch! LGTM, except the nits below.

On 26.03.21, Sergey Kaplun wrote:
> This patch adds PUC-Rio Lua 5.1 test suite as a part of the LuaJIT test
> suite. Source code taken verbatim (except trailing whitespaces) from

Typo: s/code taken/code is taken/.
Typo: I believe it's always singular: whitespace.

> https://www.lua.org/tests/lua5.1-tests.tar.gz.
> 
> Some tests may fail after this commit. They will be disabled
> or adapted in the next patches.
> 
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
>  .luacheckrc                                |    5 +-
>  test/CMakeLists.txt                        |    2 +
>  test/PUC-Lua-5.1-tests/CMakeLists.txt      |   45 +
>  test/PUC-Lua-5.1-tests/README              |   41 +
>  test/PUC-Lua-5.1-tests/all.lua             |  137 +++
>  test/PUC-Lua-5.1-tests/api.lua             |  711 ++++++++++++
>  test/PUC-Lua-5.1-tests/attrib.lua          |  339 ++++++
>  test/PUC-Lua-5.1-tests/big.lua             |  381 +++++++
>  test/PUC-Lua-5.1-tests/calls.lua           |  294 +++++
>  test/PUC-Lua-5.1-tests/checktable.lua      |   77 ++
>  test/PUC-Lua-5.1-tests/closure.lua         |  422 +++++++
>  test/PUC-Lua-5.1-tests/code.lua            |  143 +++
>  test/PUC-Lua-5.1-tests/constructs.lua      |  240 ++++
>  test/PUC-Lua-5.1-tests/db.lua              |  499 +++++++++
>  test/PUC-Lua-5.1-tests/errors.lua          |  250 +++++
>  test/PUC-Lua-5.1-tests/etc/ltests.c        | 1147 ++++++++++++++++++++
>  test/PUC-Lua-5.1-tests/etc/ltests.h        |   92 ++
>  test/PUC-Lua-5.1-tests/events.lua          |  360 ++++++
>  test/PUC-Lua-5.1-tests/files.lua           |  324 ++++++
>  test/PUC-Lua-5.1-tests/gc.lua              |  312 ++++++
>  test/PUC-Lua-5.1-tests/libs/CMakeLists.txt |   18 +
>  test/PUC-Lua-5.1-tests/libs/lib1.c         |   40 +
>  test/PUC-Lua-5.1-tests/libs/lib11.c        |   18 +
>  test/PUC-Lua-5.1-tests/libs/lib2.c         |   28 +
>  test/PUC-Lua-5.1-tests/libs/lib21.c        |   18 +
>  test/PUC-Lua-5.1-tests/literals.lua        |  176 +++
>  test/PUC-Lua-5.1-tests/locals.lua          |  127 +++
>  test/PUC-Lua-5.1-tests/main.lua            |  159 +++
>  test/PUC-Lua-5.1-tests/math.lua            |  208 ++++
>  test/PUC-Lua-5.1-tests/nextvar.lua         |  396 +++++++
>  test/PUC-Lua-5.1-tests/pm.lua              |  273 +++++
>  test/PUC-Lua-5.1-tests/sort.lua            |   74 ++
>  test/PUC-Lua-5.1-tests/strings.lua         |  176 +++
>  test/PUC-Lua-5.1-tests/vararg.lua          |  126 +++
>  test/PUC-Lua-5.1-tests/verybig.lua         |  100 ++
>  35 files changed, 7756 insertions(+), 2 deletions(-)
>  create mode 100644 test/PUC-Lua-5.1-tests/CMakeLists.txt
>  create mode 100644 test/PUC-Lua-5.1-tests/README
>  create mode 100755 test/PUC-Lua-5.1-tests/all.lua

Minor: I doubt all.lua need to be an executable. Feel free to ignore.

>  create mode 100644 test/PUC-Lua-5.1-tests/api.lua
>  create mode 100644 test/PUC-Lua-5.1-tests/attrib.lua
>  create mode 100644 test/PUC-Lua-5.1-tests/big.lua
>  create mode 100644 test/PUC-Lua-5.1-tests/calls.lua
>  create mode 100644 test/PUC-Lua-5.1-tests/checktable.lua
>  create mode 100644 test/PUC-Lua-5.1-tests/closure.lua
>  create mode 100644 test/PUC-Lua-5.1-tests/code.lua
>  create mode 100644 test/PUC-Lua-5.1-tests/constructs.lua
>  create mode 100644 test/PUC-Lua-5.1-tests/db.lua
>  create mode 100644 test/PUC-Lua-5.1-tests/errors.lua
>  create mode 100644 test/PUC-Lua-5.1-tests/etc/ltests.c
>  create mode 100644 test/PUC-Lua-5.1-tests/etc/ltests.h
>  create mode 100644 test/PUC-Lua-5.1-tests/events.lua
>  create mode 100644 test/PUC-Lua-5.1-tests/files.lua
>  create mode 100644 test/PUC-Lua-5.1-tests/gc.lua
>  create mode 100644 test/PUC-Lua-5.1-tests/libs/CMakeLists.txt
>  create mode 100644 test/PUC-Lua-5.1-tests/libs/lib1.c
>  create mode 100644 test/PUC-Lua-5.1-tests/libs/lib11.c
>  create mode 100644 test/PUC-Lua-5.1-tests/libs/lib2.c
>  create mode 100644 test/PUC-Lua-5.1-tests/libs/lib21.c
>  create mode 100644 test/PUC-Lua-5.1-tests/literals.lua
>  create mode 100644 test/PUC-Lua-5.1-tests/locals.lua
>  create mode 100644 test/PUC-Lua-5.1-tests/main.lua
>  create mode 100644 test/PUC-Lua-5.1-tests/math.lua
>  create mode 100644 test/PUC-Lua-5.1-tests/nextvar.lua
>  create mode 100644 test/PUC-Lua-5.1-tests/pm.lua
>  create mode 100644 test/PUC-Lua-5.1-tests/sort.lua
>  create mode 100644 test/PUC-Lua-5.1-tests/strings.lua
>  create mode 100644 test/PUC-Lua-5.1-tests/vararg.lua
>  create mode 100644 test/PUC-Lua-5.1-tests/verybig.lua
> 

<snipped>

> diff --git a/test/PUC-Lua-5.1-tests/CMakeLists.txt b/test/PUC-Lua-5.1-tests/CMakeLists.txt
> new file mode 100644
> index 0000000..773db0d
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/CMakeLists.txt
> @@ -0,0 +1,45 @@
> +# Test suite that has been added from PUC-Rio Lua 5.1 test archive
> +# in scope of https://github.com/tarantool/tarantool/issues/5845.
> +
> +# See the rationale in the root CMakeLists.txt.
> +cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
> +
> +# XXX: There are two ways to set up the proper environment
> +# described in the suite's README:
> +# * set LUA_PATH to "?;./?.lua"
> +# * or, better yet, set LUA_PATH to "./?.lua;;" and LUA_INIT to
> +#   "package.path = '?;'..package.path"
> +# Unfortunately, Tarantool doesn't support LUA_INIT and most
> +# likely it never will. For more info, see
> +# https://github.com/tarantool/tarantool/issues/5744
> +# Hence, there is no way other than set LUA_PATH environment
> +# variable as proposed in the first case.
> +set(LUA_PATH "?\;${CMAKE_CURRENT_SOURCE_DIR}/?.lua")
> +
> +# Set PUC-Lua-5.1-tests-prepare target that creates <libs/P1>

Minor: IMHO, "set" fits worse here than "create" or "introduce". Feel
free to ignore.

> +# subdirectory.
> +add_subdirectory(libs)
> +
> +# TODO: PUC-Rio Lua 5.1 test suite also has special header
> +# <ltests.h> and <ltests.c> translation unit to check some
> +# internal behaviour of the Lua implementation (see etc/
> +# directory). It modifies realloc function to check memory
> +# consistency and also contains tests for yield in hooks
> +# and for the Lua C API.
> +# But, unfortunately, <ltests.c> depends on specific PUC-Rio
> +# Lua 5.1 internal headers and should be adapted for LuaJIT.
> +
> +add_custom_target(PUC-Lua-5.1-tests
> +  DEPENDS ${LUAJIT_TEST_BINARY} PUC-Lua-5.1-tests-prepare
> +)
> +
> +add_custom_command(TARGET PUC-Lua-5.1-tests
> +  COMMENT "Running PUC-Rio Lua 5.1 tests"
> +  COMMAND
> +  env
> +    LUA_PATH="${LUA_PATH}\;\;"
> +    ${LUAJIT_TEST_COMMAND} ${CMAKE_CURRENT_SOURCE_DIR}/all.lua
> +  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
> +)
> +
> +# vim: expandtab tabstop=2 shiftwidth=2

<snipped>

> diff --git a/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt
> new file mode 100644
> index 0000000..f24e7f3
> --- /dev/null
> +++ b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt
> @@ -0,0 +1,18 @@
> +# Test suite that has been added from PUC-Rio Lua 5.1 test archive
> +# in scope of https://github.com/tarantool/tarantool/issues/5845.
> +
> +# See the rationale in the root CMakeLists.txt.
> +cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
> +

Minor: What about TODO for building libs/*.c sources? Anyway, you did it
in the following patch, so feel free to ignore.

> +# The original tarball contains subdirectory "libs" with an empty
> +# subdirectory "libs/P1", to be used by tests.
> +# Instead of tracking empty directory with some anchor-file for
> +# git, create this directory via CMake.
> +add_custom_target(PUC-Lua-5.1-tests-prepare)
> +add_custom_command(TARGET PUC-Lua-5.1-tests-prepare
> +  COMMENT "Create directory for PUC-Rio Lua 5.1 tests"
> +  COMMAND ${CMAKE_COMMAND} -E make_directory P1
> +  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
> +)
> +
> +# vim: expandtab tabstop=2 shiftwidth=2

<snipped>

> -- 
> 2.31.0
> 

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 02/30] test: add compiling for C libs from PUC-Rio-Lua5.1
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 02/30] test: add compiling for C libs from PUC-Rio-Lua5.1 Sergey Kaplun via Tarantool-patches
  2021-03-26 11:01   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-30 22:14   ` Igor Munkin via Tarantool-patches
  2021-04-01  8:21     ` Sergey Kaplun via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-30 22:14 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the patch! LGTM, except the nits below.

I propose the following rewording for commit subject:
| test: build auxiliary C libs from PUC-Rio-Lua5.1

On 26.03.21, Sergey Kaplun wrote:
> This patch adds commands to create additional LuaC libraries for tests

Minor: these are not "commands" but "rules".

> in <attrib.lua>. Also, it renames `luaL_reg` to `luaL_Reg` in <lib1.c>
> and <lib2.c> to be consistent with the current LuaJIT's LuaC API.
> 
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
>  test/PUC-Lua-5.1-tests/CMakeLists.txt      |  3 +-
>  test/PUC-Lua-5.1-tests/libs/CMakeLists.txt | 48 +++++++++++++++++++++-
>  test/PUC-Lua-5.1-tests/libs/lib1.c         |  2 +-
>  test/PUC-Lua-5.1-tests/libs/lib2.c         |  2 +-
>  4 files changed, 51 insertions(+), 4 deletions(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/CMakeLists.txt b/test/PUC-Lua-5.1-tests/CMakeLists.txt
> index 773db0d..3c31aae 100644
> --- a/test/PUC-Lua-5.1-tests/CMakeLists.txt
> +++ b/test/PUC-Lua-5.1-tests/CMakeLists.txt
> @@ -16,7 +16,8 @@ cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
>  # variable as proposed in the first case.
>  set(LUA_PATH "?\;${CMAKE_CURRENT_SOURCE_DIR}/?.lua")

Side note: I see no LUA_CPATH, but I grepped the spots where lib*.so are
required and found that package.cpath is tweaked right there. Hence
LUA_CPATH is excess, isn't it?

>  

<snipped>

> diff --git a/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt
> index f24e7f3..aa64a44 100644
> --- a/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt
> +++ b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt
> @@ -4,11 +4,57 @@
>  # See the rationale in the root CMakeLists.txt.
>  cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
>  
> +# Build additional C libraries for tests.
> +macro(BuildTestCLib lib sources)

<snipped>

> +  elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")

Minor: I personally would strip this option out for all remaining
systems (i.e. *BSD too), since we have no guarantee the CMake defaults
won't be broken on other distros sometime. Feel free to ignore (but
it'll be on your conscience).

> +    # XXX: This is necessary mostly for openSUSE builds, see also
> +    # https://bugzilla.suse.com/show_bug.cgi?id=1012388.
> +    # Just strip out the linker flag to suppress this linker
> +    # option.
> +    string(REPLACE "-Wl,--no-undefined" ""
> +      CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}"
> +    )
> +  endif()

<snipped>

> +endmacro()
> +
> +BuildTestCLib(lib1  lib1.c)

Typo: excess whitespace.

> +BuildTestCLib(lib11 lib1.c lib11.c)
> +BuildTestCLib(lib2  lib2.c)

Typo: excess whitespace.

> +BuildTestCLib(lib21 lib2.c lib21.c)
> +
> +# Create exact copy of the lib2 library for tests in attrib.lua.

Typo: s/create exact copy/create the exact copy/.

> +set(LIB2ORIG "${CMAKE_CURRENT_BINARY_DIR}/lib2${CMAKE_SHARED_LIBRARY_SUFFIX}")
> +set(LIB2COPY "${CMAKE_CURRENT_BINARY_DIR}/-lib2${CMAKE_SHARED_LIBRARY_SUFFIX}")

<snipped>

> -- 
> 2.31.0
> 

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 08/30] test: disable JIT for GC step counting tests
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 08/30] test: disable JIT for GC step counting tests Sergey Kaplun via Tarantool-patches
  2021-03-26 11:32   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-30 22:14   ` Igor Munkin via Tarantool-patches
  2021-04-01 10:10     ` Sergey Kaplun via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-30 22:14 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the patch! LGTM, except the nits below.

I propose the following rewording for commit subject:
| test: disable JIT for the tests counting GC steps

On 26.03.21, Sergey Kaplun wrote:
> JIT compilation can unpredictable allocate or reference objects (or

Typo: s/unpredictable/unpredictably/.

> traces itself). So, the amount of GC steps can vary from run to run.
> 
> This patch disables JIT machinery, if it is enabled, for stable GC
> results.
> 
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
>  test/PUC-Lua-5.1-tests/gc.lua | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/test/PUC-Lua-5.1-tests/gc.lua b/test/PUC-Lua-5.1-tests/gc.lua
> index 86a9f75..072bbe9 100644
> --- a/test/PUC-Lua-5.1-tests/gc.lua
> +++ b/test/PUC-Lua-5.1-tests/gc.lua
> @@ -108,11 +108,21 @@ local function dosteps (siz)
>    return i
>  end
>  
> +-- LuaJIT: JIT compilation can unpredictable allocate or reference

Typo: s/unpredictable/unpredictably/.

> +-- objects (or traces itself). Disable it if necessary for
> +-- this chunk for stable GC results.

<snipped>

> -- 
> 2.31.0
> 

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 10/30] test: adapt test for debug.setlocal in Lua suite
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 10/30] test: adapt test for debug.setlocal in Lua suite Sergey Kaplun via Tarantool-patches
  2021-03-26 11:44   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-30 22:14   ` Igor Munkin via Tarantool-patches
  2021-04-01 10:16     ` Sergey Kaplun via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-30 22:14 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the patch! LGTM, considering your changes on the branch. Also
consider the comments below.

On 26.03.21, Sergey Kaplun wrote:
> LuaJIT: Lua 5.1 interprets `...` in the vararg functions like

Looks like you just copied the comment below. There is no need for
'LuaJIT:' here.

> an additional first argument unlike LuaJIT does.
> This behaviour is extension is from Lua 5.2.

Typo: s/is extension is/is extension/.

> 
> This patch adapted test considering LuaJIT's and Lua 5.2 behaviour.

Side note: Here it is -- you wrote LuaJIT's but Lua 5.2 (neither Lua's
5.2 nor Lua 5.2's). How come?

> The test is adapted like it done in Lua 5.2 test suite taken from
> https://www.lua.org/tests/lua-5.2.0-tests.tar.gz.
> 
> Closes tarantool/tarantool#5694

As we discussed before: s/Closes/Resolves/.

> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---

<snipped>

> -- 
> 2.31.0
> 

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 11/30] test: adapt getlocal PUC test for vararg func
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 11/30] test: adapt getlocal PUC test for vararg func Sergey Kaplun via Tarantool-patches
  2021-03-26 11:47   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-30 22:15   ` Igor Munkin via Tarantool-patches
  2021-04-01 11:37     ` Sergey Kaplun via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-30 22:15 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the patch! I can't understand why this patch is separated
from the previous one. Could you provide a rationale for this, please?
BTW as we discussed before: s/Closes/Resolves/, considering your changes
on the branch. Also consider the comments below.

On 26.03.21, Sergey Kaplun wrote:
> Lua 5.1 interprets `...` in the vararg functions like an additional

Typo: s/like/as/.

> first argument unlike LuaJIT does. So, `a:f()` function will not set
> corresponding table `arg`, as test expects.

Typo: s/set corresponding table `arg`/set the corresponding `arg` table/.

> 
> Implicit `arg` parameter for old-style vararg functions was finally
> removed in Lua 5.2. The test is adapted from PUC-Rio Lua 5.2 test suite
> by removing additional check for amountt of arguments via `arg.n`.

Typo: s/amountt/amount/.

> Lua 5.2 test suite is taken from
> https://www.lua.org/tests/lua-5.2.0-tests.tar.gz.
> 
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
>  test/PUC-Lua-5.1-tests/db.lua | 11 ++++++++++-
>  1 file changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua
> index e5d8885..6985c29 100644
> --- a/test/PUC-Lua-5.1-tests/db.lua
> +++ b/test/PUC-Lua-5.1-tests/db.lua
> @@ -300,7 +300,16 @@ debug.sethook(function (e)

<snipped>

> +-- LuaJIT: Lua 5.1 interprets `...` in the vararg functions like

Typo: s/like/as/.

> +-- an additional first argument unlike LuaJIT does.
> +-- So, `a:f()` function will not set corresponding table `arg`,

Typo: s/set corresponding table `arg`/set the corresponding `arg` table/.

> +-- as test expects.

<snipped>

> -- 
> 2.31.0
> 

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 12/30] test: adapt PUC Lua test with count hooks
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 12/30] test: adapt PUC Lua test with count hooks Sergey Kaplun via Tarantool-patches
  2021-03-26 11:49   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-30 22:15   ` Igor Munkin via Tarantool-patches
  2021-04-01 11:42     ` Sergey Kaplun via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-30 22:15 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the patch! LGTM, except the single nit below.

On 26.03.21, Sergey Kaplun wrote:
> LuaJIT does not check hooks at traces without defined
> -DLUAJIT_ENABLE_CHECKHOOK. For more information see <src/lj_record.c>
> or commit 6bce6b118eeb2bb7f36157de158e5cccf0ea68e5 (Add compile-time
> option LUAJIT_ENABLE_CHECKHOOK. Disabled by default.).
> 
> This patch adapts these tests for LuaJIT by disabling JIT while testing
> count hooks.
> 
> Closes tarantool/tarantool#5701

As we discussed before: s/Closes/Resolves/.

> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473

<snipped>

> -- 
> 2.31.0
> 

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 13/30] test: disable PUC Lua test for tail call info
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 13/30] test: disable PUC Lua test for tail call info Sergey Kaplun via Tarantool-patches
  2021-03-26 14:43   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-30 22:15   ` Igor Munkin via Tarantool-patches
  2021-04-01 11:52     ` Sergey Kaplun via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-30 22:15 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the patch! LGTM, except the nits below.

On 26.03.21, Sergey Kaplun wrote:
> LuaJIT does not provide information about tail calls in debug.getinfo(),
> unlike Lua does. This missed feature is described in
> https://luajit.org/status.html.
> 
> This patch disables tests for tail call checks and getfenv() checks,
> because tail calls do not provide an additional level for LuaJIT

It's not "level", but "call frame", AFAIU.

> and level number given to getfenv() should be changed.
> 
> Relates to tarantool/tarantool#5702
> Relates to tarantool/tarantool#5703
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
>  test/PUC-Lua-5.1-tests/db.lua | 30 ++++++++++++++++++++++--------
>  1 file changed, 22 insertions(+), 8 deletions(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua
> index c1a635a..b363abc 100644
> --- a/test/PUC-Lua-5.1-tests/db.lua
> +++ b/test/PUC-Lua-5.1-tests/db.lua
> @@ -400,19 +400,29 @@ function g1(x) g(x) end
>  
>  local function h (x) local f=g1; return f(x) end
>  
> -h(true)
> +-- LuaJIT does not provide information about tail calls,
> +-- unlike Lua does. See also https://luajit.org/status.html.
> +-- getfenv() behaviour is also different here,

Typo: looks like line underfull (in LaTeX terms, heh).

> +-- because tail calls do not provide additional level for LuaJIT
> +-- and level number should be changed.
> +-- FIXME: Test is disabled for LuaJIT.
> +-- See also https://github.com/tarantool/tarantool/issues/5702.
> +-- h(true)

<snipped>

> -for _, k in ipairs(res) do assert(k == table.remove(b, 1)) end
> -

Typo: excess whitespace change.

> +-- Behavior is different for LuaJIT. See the comment above.
> +-- FIXME: Test is disabled for LuaJIT.
> +-- for _, k in ipairs(res) do assert(k == table.remove(b, 1)) end

<snipped>

> -- 
> 2.31.0
> 

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 14/30] test: adapt activeline check in the PUC Lua test
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 14/30] test: adapt activeline check in the PUC Lua test Sergey Kaplun via Tarantool-patches
  2021-03-26 14:50   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-30 22:15   ` Igor Munkin via Tarantool-patches
  2021-04-01 11:58     ` Sergey Kaplun via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-30 22:15 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the patch! LGTM, except the nits below.

On 26.03.21, Sergey Kaplun wrote:
> LuaJIT does not report line with single "end" statement

Typo: s/report line/report the line/.

> (the last line of the function) as an active line in
> debug.getinfo(), unlike Lua does. There is no bytecode
> related to this line, so it is "unreachable" and
> may be considered not active.
> 
> This patch excludes the last line of a function from the check,

Typo: s/a function/the function/.

> considering LuaJIT's behaviour.
> 
> Closes tarantool/tarantool#5708

As we discussed before: s/Closes/Resolves/.

> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
>  test/PUC-Lua-5.1-tests/db.lua | 10 +++++++++-
>  1 file changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua
> index b363abc..c704877 100644
> --- a/test/PUC-Lua-5.1-tests/db.lua
> +++ b/test/PUC-Lua-5.1-tests/db.lua
> @@ -491,7 +491,15 @@ local _, l = coroutine.resume(co, 10)
>  local x = debug.getinfo(co, 1, "lfLS")
>  assert(x.currentline == l.currentline and x.activelines[x.currentline])
>  assert(type(x.func) == "function")
> -for i=x.linedefined + 1, x.lastlinedefined do
> +-- LuaJIT does not report line with single "end" statement

Typo: s/report line/report the line/.

> +-- (the last line of the function) as an active line in
> +-- debug.getinfo(), unlike Lua does. There is no bytecode
> +-- related to this line, so it is "unreachable" and
> +-- may be considered not active.
> +-- See also https://github.com/tarantool/tarantool/issues/5708.
> +-- LuaJIT: Test is adapted for LuaJIT's behaviour by avoiding
> +-- the last line check.
> +for i=x.linedefined + 1, x.lastlinedefined - 1 do
>    assert(x.activelines[i])
>    x.activelines[i] = nil
>  end
> -- 
> 2.31.0
> 

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 15/30] test: disable PUC-Lua test for per-coroutine hooks
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 15/30] test: disable PUC-Lua test for per-coroutine hooks Sergey Kaplun via Tarantool-patches
  2021-03-26 14:54   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-30 22:16   ` Igor Munkin via Tarantool-patches
  2021-04-01 12:03     ` Sergey Kaplun via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-30 22:16 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the patch! LGTM, except the one nit: I would explicitly
mention that hook is set *but* for the whole VM instead of the given
coroutine. Hence hooks work, but assertions are disabled.

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 16/30] test: adapt PUC Lua test for %q in fmt for LuaJIT
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 16/30] test: adapt PUC Lua test for %q in fmt for LuaJIT Sergey Kaplun via Tarantool-patches
  2021-03-26 14:56   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-30 22:16   ` Igor Munkin via Tarantool-patches
  2021-04-01 12:33     ` Sergey Kaplun via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-30 22:16 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for your patch! Please consider my comments below.

On 26.03.21, Sergey Kaplun wrote:
> LuaJIT: LuaJIT since v2.0.0-beta6 has extension from Lua 5.2:

Looks like you just copied the comment below. There is no need for
'LuaJIT:' here.

> string.format(): %q reversible.
> See also https://luajit.org/extensions.html#lua52.
> 
> In Lua 5.1 string.format() does not accept string values containing
> embedded zeros, except as arguments to the '%q' option.
> In Lua 5.2 '\0' is not handled differently from other
> control chars in string.format('%q', ...).
> See commit 7cc981c14067d4b0e774a6bfb0acfc2f5c911f0d
> (string.format("%q", str) is now fully reversible
> (from Lua 5.2).).

Well, I honestly don't understand what is changed in *semantics*. I've
tried the following command with Lua 5.2, Lua 5.1 and LuaJIT 2.0.5 as an
interpreter being tested
| <interp> -e 'print(string.format("%q", "\0"))'

I understand the semantics of "%q", but was it just a bug in Lua 5.1?
What does "fully reversible" mean in this context?

I understand only the fact the behaviour differs and you reimplemented
the test assertion according to Lua 5.2 testing suite. That's all.

I found not a single word regarding this issue in Lua bugs[1] page,
except invalid handling of \r[2]. Is there any issue/page with a more
verbose explanation what has been changed in 7cc981c?

> 
> This patch adapts test for LuaJIT and Lua 5.2 behaviour considering
> test from Lua 5.2 test suite taken from

Typo: s/considering test/considering the test/.

> https://www.lua.org/tests/lua-5.2.0-tests.tar.gz.
> 
> Closes tarantool/tarantool#5710

As we discussed before: s/Closes/Resolves/.

> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
>  test/PUC-Lua-5.1-tests/strings.lua | 12 +++++++++++-
>  1 file changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/strings.lua b/test/PUC-Lua-5.1-tests/strings.lua
> index 237dbad..7c1dfb8 100644
> --- a/test/PUC-Lua-5.1-tests/strings.lua
> +++ b/test/PUC-Lua-5.1-tests/strings.lua
> @@ -102,7 +102,17 @@ print('+')
>  
>  x = '"?lo"\n\\'
>  assert(string.format('%q%s', x, x) == '"\\"?lo\\"\\\n\\\\""?lo"\n\\')
> -assert(string.format('%q', "\0") == [["\000"]])
> +-- LuaJIT: LuaJIT since v2.0.0-beta6 has extension from Lua 5.2:
> +-- string.format(): %q reversible.
> +-- In Lua 5.1 string.format() does not accept string values
> +-- containing embedded zeros, except as arguments to the q option.
> +-- In Lua 5.2 '\0' is not handled differently from other
> +-- control chars in string.format('%q', ...).
> +-- See commit 7cc981c14067d4b0e774a6bfb0acfc2f5c911f0d
> +-- (string.format("%q", str) is now fully reversible
> +-- (from Lua 5.2).).
> +-- Test is adapted from PUC-Rio Lua 5.2 test suite.
> +assert(string.format('%q', "\0") == [["\0"]])
>  assert(string.format("\0%c\0%c%x\0", string.byte("?"), string.byte("b"), 140) ==
>                "\0?\0b8c\0")
>  assert(string.format('') == "")
> -- 
> 2.31.0
> 

[1]: https://www.lua.org/bugs.html#5.1
[2]: https://www.lua.org/bugs.html#5.1-4

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 17/30] test: disable locale-depended tests for Lua suite
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 17/30] test: disable locale-depended tests for Lua suite Sergey Kaplun via Tarantool-patches
  2021-03-26 14:58   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-30 22:16   ` Igor Munkin via Tarantool-patches
  2021-04-01 19:12     ` Sergey Kaplun via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-30 22:16 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the patch! LGTM, except the nits below.

On 26.03.21, Sergey Kaplun wrote:
> LuaJIT doesn't compare strings by `strcoll()`, like Lua 5.1 does.
> So locale-depended tests in <strings.lua> are disabled.

Side note: unfortunately, this is not mentioned anywhere except the
sources... Classic.

> 
> Also, LuaJIT doesn't use `strtod()` depended on the locale for parsing,

Typo: s/depended/dependent/.

> unlike Lua does. See <src/lj_strscan.c> for more info.
> Locale-depended tests in <literals.lua> are disabled.

Minor: Please, refer the docs[1] or the patch[2] changing the behaviour
in the commit message.

> 
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
>  test/PUC-Lua-5.1-tests/literals.lua | 5 +++++
>  test/PUC-Lua-5.1-tests/strings.lua  | 5 +++++
>  2 files changed, 10 insertions(+)
> 
> diff --git a/test/PUC-Lua-5.1-tests/literals.lua b/test/PUC-Lua-5.1-tests/literals.lua
> index 01d84d5..1b4f664 100644
> --- a/test/PUC-Lua-5.1-tests/literals.lua
> +++ b/test/PUC-Lua-5.1-tests/literals.lua
> @@ -158,6 +158,10 @@ end
>  
>  
>  -- testing decimal point locale
> +-- LuaJIT: LuaJIT doesn't use `strtod()` depended on the locale,

Typo: s/depended/dependent/.

> +-- unlike Lua does. See <src/lj_strscan.c> for more info.
> +-- Tests are disabled for LuaJIT.
> +--[[
>  if os.setlocale("pt_BR") or os.setlocale("ptb") then
>    assert(tonumber("3,4") == 3.4 and tonumber"3.4" == nil)
>    assert(assert(loadstring("return 3.4"))() == 3.4)

<snipped>

> -- 
> 2.31.0
> 

[1]: http://luajit.org/extensions.html#tonumber
[2]: https://github.com/tarantool/luajit/commit/4c882fe

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 18/30] test: replace math.mod to math.fmod for Lua tests
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 18/30] test: replace math.mod to math.fmod for Lua tests Sergey Kaplun via Tarantool-patches
  2021-03-26 15:12   ` Sergey Ostanevich via Tarantool-patches
  2021-03-26 15:16   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-30 22:16   ` Igor Munkin via Tarantool-patches
  2021-04-01 19:36     ` Sergey Kaplun via Tarantool-patches
  2 siblings, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-30 22:16 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the patch! LGTM, except the nits below.

There is a typo in commit subject:
s/replace math.mod to math.fmod/replace math.mod with math.fmod/.

On 26.03.21, Sergey Kaplun wrote:
> In Lua 5.1 math.mod() is renamed to math.fmod() if build Lua 5.1 without

Typo: s/if build Lua 5.1/if Lua 5.1 is built/ or
      s/if build Lua 5.1/if one build Lua 5.1/.

> flag `-DLUA_COMPAT_MOD`.

Typo: s/flag `-DLUA_COMPAT_MOD`/`-DLUA_COMPAT_MOD` flag/.

> LuaJIT has math.fmod() instead old-style math.mod() built-in.

Typo: s/instead old-style/instead of old-style/.

You can also mention the commit[1] where this is done.

> 
> This patch replaces usage of math.mod with new-style math.fmod
> in the following files:
> * closure.lua
> * constructs.lua
> * math.lua
> * nextvar.lua
> 
> Closes tarantool/tarantool#5711

As we discussed before: s/Closes/Resolves/.

> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
>  test/PUC-Lua-5.1-tests/closure.lua    | 3 ++-
>  test/PUC-Lua-5.1-tests/constructs.lua | 6 ++++--
>  test/PUC-Lua-5.1-tests/math.lua       | 3 ++-
>  test/PUC-Lua-5.1-tests/nextvar.lua    | 3 ++-
>  4 files changed, 10 insertions(+), 5 deletions(-)

Typo: s/instead old-style/instead of old-style/g in all chunks.

> 

<snipped>

> -- 
> 2.31.0
> 

[1]: https://github.com/tarantool/luajit/commit/de5568e

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 18/30] test: replace math.mod to math.fmod for Lua tests
  2021-03-26 15:12   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-30 22:17     ` Igor Munkin via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-30 22:17 UTC (permalink / raw)
  To: Sergey Ostanevich; +Cc: tarantool-patches

Sergos,

On 26.03.21, Sergey Ostanevich wrote:
> Hmmm. Is it better to mokeypatch it as ‘math.mod = math.fmod or math.mod’?

No, it's not (IMHO): <math.mod> (as well as <string.gfind>) is
completely removed in scope of this patch[1].

> 
> Sergos.
> 
> 

<snipped>

> 

[1]: https://github.com/tarantool/luajit/commit/de5568e

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 19/30] test: remove assert for string.gfind check
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 19/30] test: remove assert for string.gfind check Sergey Kaplun via Tarantool-patches
  2021-03-26 15:14   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-30 22:17   ` Igor Munkin via Tarantool-patches
  2021-04-02  7:05     ` Sergey Kaplun via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-30 22:17 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the patch! LGTM, except the single nit.

On 26.03.21, Sergey Kaplun wrote:
> In Lua 5.1 function `string.gfind()` was renamed to `string.gmatch()`.
> You can use it if Lua 5.1 is built with compile-time option
> `-DLUA_COMPAT_GFIND`.
> This built-in is removed from LuaJIT.

Please mention the patch[1] where this builtin is removed.

> 
> This patch removes test checking that `string.gfind()` and
> `string.gmatch() is the same function.
> 
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
>  test/PUC-Lua-5.1-tests/pm.lua | 1 -
>  1 file changed, 1 deletion(-)
> 

<snipped>

> -- 
> 2.31.0
> 

[1]: https://github.com/tarantool/luajit/commit/de5568e

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite
  2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
                   ` (30 preceding siblings ...)
  2021-03-26 11:09 ` [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Ostanevich via Tarantool-patches
@ 2021-03-30 22:17 ` Igor Munkin via Tarantool-patches
  2021-03-31  9:41   ` Sergey Kaplun via Tarantool-patches
  31 siblings, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-30 22:17 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the series! I have two global comments for it:
* 'LuaJIT:' tag usage looks inconsistent: let's move all of them to the
  beginning of the related comments.
* Typo: s/LuaJIT's/LuaJIT/g.
  E.g. you never say "room's door" or "street's name". If you find the
  rule of possessives adjectives usage with inanimate subjects, please,
  share it with me.
* You use "PUC-Lua", "PUC Lua" and just "PUC" or "Lua" in commit
  subjects. Let's choose the single way referencing this Lua language
  implementation (and the corresponding test suite).

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite
  2021-03-30 22:17 ` Igor Munkin via Tarantool-patches
@ 2021-03-31  9:41   ` Sergey Kaplun via Tarantool-patches
  2021-03-31 10:49     ` Igor Munkin via Tarantool-patches
  0 siblings, 1 reply; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-31  9:41 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

Thanks for the review!

On 31.03.21, Igor Munkin wrote:
> Sergey,
> 
> Thanks for the series! I have two global comments for it:
> * 'LuaJIT:' tag usage looks inconsistent: let's move all of them to the
>   beginning of the related comments.

OK, I'll fix it with the new one series version, if you don't mind.

> * Typo: s/LuaJIT's/LuaJIT/g.
>   E.g. you never say "room's door" or "street's name". If you find the
>   rule of possessives adjectives usage with inanimate subjects, please,
>   share it with me.

According to "The Oxford Dictionary of American Usage and Style" by
Bryan A.  Garner, **POSSESIVES**, **H Inanimate things** section,
page 262:

| **Inanimate Things**. Possessives of nouns denoting inanimate objects
| are generally unobjectionable. Indeed, they allow writers to avoid
| awkward uses of `of` -- e.g.: `the book's title`, `the article's main
| point`, `the system's hub`, `the envelope's contents`, `the car's
| price tag`.
|
| The old line was that it's better to use an "`of` phrase rather than
| the `'s` to indicate possession when the possessor is an inanimate
| object. Write `foot of the bed`, not `the bed's foot`" (Robert C.
| Whitford & James R. Foster, Concise Dictionary of American and Usage,
| 1955). `Foot of the bed`, of course, is a SET PHRASE, the example is
| not a fair one. As a general principle, though, whenever it's not a
| violation of idiom, the possessive in `'s` is preferable <the hotel's
| front entrance> - <the earth's surface>.
|
| But such possessives can be overdone for example, avoid using the
| possessive form of a year -- e.g.: "Mr. Rogers, 41, took the show by
| storm in 1993 winning 28 blue ribbons and the Show Sweepstakes with a
| total of 1,120 points (which really upped the ante: `1992's winner`
| [read `the 1992 winner`] scored only 387 points" (N. Y. Times).

> * You use "PUC-Lua", "PUC Lua" and just "PUC" or "Lua" in commit
>   subjects. Let's choose the single way referencing this Lua language
>   implementation (and the corresponding test suite).

Let's use "PUC" phrase everywhere, if you don't mind --
"test:" prefix of commit message defines belonging to the test suite.

> 
> -- 
> Best regards,
> IM

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 20/30] test: adapt PUC Lua test for args in vararg func
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 20/30] test: adapt PUC Lua test for args in vararg func Sergey Kaplun via Tarantool-patches
  2021-03-26 14:54   ` Sergey Kaplun via Tarantool-patches
@ 2021-03-31  9:51   ` Igor Munkin via Tarantool-patches
  2021-04-02  7:21     ` Sergey Kaplun via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-31  9:51 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the patch! I can't understand why this patch is separated
from the previous two (10 and 11). Could you provide a rationale for
this, please? Also consider the comments below.

On 26.03.21, Sergey Kaplun wrote:
> Lua 5.1 interprets ... in the vararg functions like additional first

Typo: s/like additional/as an additional/.

> argument, unlike LuaJIT does. All extra arguments is set into `arg`

Typo: s/arguments is set/arguments are set/.

> variable.
> 
> Implicit `arg` parameter for old-style vararg functions was finally
> removed in Lua 5.2. This patch adjust tests in vararg.lua considering

Minor: Did LuaJIT always respect such behaviour? If no, please mention
the commit where it has been changed.

> Lua 5.2 test suite taken from
> https://www.lua.org/tests/lua-5.2.0-tests.tar.gz.
> 
> Closes tarantool/tarantool#5712

As we discussed before: s/Closes/Resolves/.

> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
>  test/PUC-Lua-5.1-tests/vararg.lua | 16 ++++++++++++----
>  1 file changed, 12 insertions(+), 4 deletions(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/vararg.lua b/test/PUC-Lua-5.1-tests/vararg.lua
> index ae068fa..efb76c5 100644
> --- a/test/PUC-Lua-5.1-tests/vararg.lua
> +++ b/test/PUC-Lua-5.1-tests/vararg.lua
> @@ -2,9 +2,13 @@ print('testing vararg')
>  
>  _G.arg = nil
>  
> +-- Lua 5.1 interprets ... in the vararg functions like additional

Typo: s/like additional/as an additional/.

> +-- first argument, unlike LuaJIT does. All extra arguments is set

Typo: s/arguments is set/arguments are set/.

> +-- into `arg` variable. This extension is from Lua 5.2.
> +-- See also https://github.com/tarantool/tarantool/issues/5712.

Side note: What is the difference between #5712 and #5694? They look
like duplicates to me, and so provide another rationale for squashing
all three patches into a single one.

> +-- LuaJIT: Test is adapted from PUC-Rio Lua 5.2 test suite.
>  function f(a, ...)
> -  assert(type(arg) == 'table')
> -  assert(type(arg.n) == 'number')
> +  local arg = {n = select('#', ...), ...}

Why did you drop the assertions above? They are trivial (as many of
others in this suite), but still check that everything is fine (e.g.
that <select> yields a number).

>    for i=1,arg.n do assert(a[i]==arg[i]) end
>    return arg.n
>  end

<snipped>

> @@ -42,7 +48,9 @@ a = call(print, {'+'})
>  assert(a == nil)
>  
>  local t = {1, 10}
> -function t:f (...) return self[arg[1]]+arg.n end
> +-- LuaJIT: Test chunk is adapted from PUC-Rio Lua 5.2 test suite.
> +-- See the comment above.
> +function t:f (...) local arg = {...}; return self[...]+#arg end

Why didn't you create the same structure as elsewhere above? Why did you
change <self> indexing? AFAIU, after creating the *right* <arg> variable
everything should work with no other changes.

>  assert(t:f(1,4) == 3 and t:f(2) == 11)
>  print('+')
>  
> -- 
> 2.31.0
> 

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 21/30] test: disable test for getfenv in closure tailcall
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 21/30] test: disable test for getfenv in closure tailcall Sergey Kaplun via Tarantool-patches
  2021-03-26 15:41   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-31  9:51   ` Igor Munkin via Tarantool-patches
  2021-04-02  7:40     ` Sergey Kaplun via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-31  9:51 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the patch! LGTM, except the comments related to the wording.

On 26.03.21, Sergey Kaplun wrote:
> LuaJIT doesn't take into account tail calls for call-level counting, so

Minor: This is a good example, when the passive voice makes the sense
clearer. Consider the following:
| Tail calls are not taken into account for call-level counting.

Otherwise it seems like LuaJIT doesn't take into account *tail calls for
call-level counting* (i.e. tail calls that are not used for call-level
counting are taken into). Or simply try to use another preposition.

> getfenv() behaviour is different from Lua 5.1 in tail calls.

Minor: You use both "tailcall" and "tail call" within this commit.
Please choose one and use it everywhere.

> 
> This patch disables test for the return result of tail call getfenv().

Typo: s/tail call getfenv()/getfenv() tail call/.

> Default value (equals 1) of getfenv() function's argument (function

Typo: s/equals 1/equals to 1/.

> level) is invalid for this tail call -- LuaJIT can't provide necessary
> debug information for the frame.

Minor: I would explicitly mention, that there is no a separate frame for
tail call. LuaJIT simply uses the existing one created for the caller.

> 
> Relates to tarantool/tarantool#5713
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
>  test/PUC-Lua-5.1-tests/closure.lua | 9 ++++++++-
>  1 file changed, 8 insertions(+), 1 deletion(-)
> 

<snipped>

> -- 
> 2.31.0
> 

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite
  2021-03-31  9:41   ` Sergey Kaplun via Tarantool-patches
@ 2021-03-31 10:49     ` Igor Munkin via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-31 10:49 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

On 31.03.21, Sergey Kaplun wrote:
> Igor,
> 
> Thanks for the review!
> 
> On 31.03.21, Igor Munkin wrote:
> > Sergey,
> > 
> > Thanks for the series! I have two global comments for it:
> > * 'LuaJIT:' tag usage looks inconsistent: let's move all of them to the
> >   beginning of the related comments.
> 
> OK, I'll fix it with the new one series version, if you don't mind.

I don't.

> 
> > * Typo: s/LuaJIT's/LuaJIT/g.
> >   E.g. you never say "room's door" or "street's name". If you find the
> >   rule of possessives adjectives usage with inanimate subjects, please,
> >   share it with me.
> 
> According to "The Oxford Dictionary of American Usage and Style" by
> Bryan A.  Garner, **POSSESIVES**, **H Inanimate things** section,
> page 262:

OK, I also spent a little time surfing the internet and found one[1]
too. Hence this is the reason why your usage is so unnatural to me: as
you mentioned you're writing with respect to the American dialect, but I
was drilling Murphy a lot when I was younger, so "the old line" is stuck
in my head forever. Therefore, it looks I can't stop you from using the
language the way you want, but please *be consistent*. Good luck with
using the "American Usage" for Lua 5.2 case :)

> 
> | **Inanimate Things**. Possessives of nouns denoting inanimate objects
> | are generally unobjectionable. Indeed, they allow writers to avoid
> | awkward uses of `of` -- e.g.: `the book's title`, `the article's main
> | point`, `the system's hub`, `the envelope's contents`, `the car's
> | price tag`.
> |
> | The old line was that it's better to use an "`of` phrase rather than
> | the `'s` to indicate possession when the possessor is an inanimate
> | object. Write `foot of the bed`, not `the bed's foot`" (Robert C.
> | Whitford & James R. Foster, Concise Dictionary of American and Usage,
> | 1955). `Foot of the bed`, of course, is a SET PHRASE, the example is
> | not a fair one. As a general principle, though, whenever it's not a
> | violation of idiom, the possessive in `'s` is preferable <the hotel's
> | front entrance> - <the earth's surface>.
> |
> | But such possessives can be overdone for example, avoid using the
> | possessive form of a year -- e.g.: "Mr. Rogers, 41, took the show by
> | storm in 1993 winning 28 blue ribbons and the Show Sweepstakes with a
> | total of 1,120 points (which really upped the ante: `1992's winner`
> | [read `the 1992 winner`] scored only 387 points" (N. Y. Times).
> 
> > * You use "PUC-Lua", "PUC Lua" and just "PUC" or "Lua" in commit
> >   subjects. Let's choose the single way referencing this Lua language
> >   implementation (and the corresponding test suite).
> 
> Let's use "PUC" phrase everywhere, if you don't mind --
> "test:" prefix of commit message defines belonging to the test suite.

I don't, but formally it's PUC-Rio.

> 
> > 
> > -- 
> > Best regards,
> > IM
> 
> -- 
> Best regards,
> Sergey Kaplun


[1]: https://dictionary.cambridge.org/grammar/british-grammar/possession-john-s-car-a-friend-of-mine

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 22/30] test: disable PUC Lua test for var names in error
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 22/30] test: disable PUC Lua test for var names in error Sergey Kaplun via Tarantool-patches
  2021-03-26 15:44   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-31 19:23   ` Igor Munkin via Tarantool-patches
  2021-04-02  7:48     ` Sergey Kaplun via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-31 19:23 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the patch! LGTM, except the nits below.

On 26.03.21, Sergey Kaplun wrote:
> LuaJIT includes variable name to the error report, when try to

Minor: "error message" is more correct than "error report" here.

> call non-function object without __call methamethod.

Typo: s/methamethod/metamethod/.

> Also, LuaJIT includes variable name to the error report, when try to

Typo: s/includes variable name/includes the variable name/.

> perform unacceptable arifmetic operation with the variable.
> Lua 5.1 doesn't report variable name in these errors.
> 
> Test ckecked that variable name aren't reported are disabled by

Typo: s/Test checked/Tests checking/.
Typo: s/name aren't reported/name isn't reported/.

> this patch.
> 
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
>  test/PUC-Lua-5.1-tests/errors.lua | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua
> index e881211..cf24e40 100644
> --- a/test/PUC-Lua-5.1-tests/errors.lua
> +++ b/test/PUC-Lua-5.1-tests/errors.lua
> @@ -72,8 +72,13 @@ checkmessage("b=1; local aaa='a'; x=aaa+b", "local 'aaa'")
>  checkmessage("aaa={}; x=3/aaa", "global 'aaa'")
>  checkmessage("aaa='2'; b=nil;x=aaa*b", "global 'b'")
>  checkmessage("aaa={}; x=-aaa", "global 'aaa'")
> -assert(not string.find(doit"aaa={}; x=(aaa or aaa)+(aaa and aaa)", "'aaa'"))
> -assert(not string.find(doit"aaa={}; (aaa or aaa)()", "'aaa'"))
> +-- LuaJIT: LuaJIT includes variable name to the error report.

Minor: "error message" fits better than "error report".

> +-- It looks like:
> +-- "attempt to perform arithmetic on global 'aaa' (a table value)"
> +-- Lua 5.1 doesn't report variable name here.

Typo: s/report variable name/report the variable name/.

> +-- Tests are disabled for LuaJIT.
> +-- assert(not string.find(doit"aaa={}; x=(aaa or aaa)+(aaa and aaa)", "'aaa'"))
> +-- assert(not string.find(doit"aaa={}; (aaa or aaa)()", "'aaa'"))
>  
>  checkmessage([[aaa=9
>  repeat until 3==3
> -- 
> 2.31.0
> 

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 23/30] test: disable PUC Lua test for fast function name
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 23/30] test: disable PUC Lua test for fast function name Sergey Kaplun via Tarantool-patches
  2021-03-26 15:45   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-31 19:23   ` Igor Munkin via Tarantool-patches
  2021-04-02  8:14     ` Sergey Kaplun via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-31 19:23 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the patch! Please consider the comments below.

On 26.03.21, Sergey Kaplun wrote:
> LuaJIT can't determine bytecode position for non Lua functions
> (in particular for fast functions) and, therefore, detect built-in
> function names for errors in tail calls.

Side note: here is the inconsistency in your usage of possessive nouns.

> 
> This patch disables test that checks name of built-in functions

Typo: s/disables test/disables the test/.
Typo: s/checks name/checks the name/.

> reported in error in tail call.
> 
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
>  test/PUC-Lua-5.1-tests/errors.lua | 10 +++++++---
>  1 file changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua
> index cf24e40..af776a7 100644
> --- a/test/PUC-Lua-5.1-tests/errors.lua
> +++ b/test/PUC-Lua-5.1-tests/errors.lua
> @@ -105,9 +105,13 @@ while 1 do
>    insert(prefix, a)
>  end]], "global 'insert'")
>  
> -checkmessage([[  -- tail call
> -  return math.sin("a")
> -]], "'sin'")
> +-- LuaJIT: Can't determine bytecode position for non Lua functions
> +-- (in particular for fast functions) and, therefore, detect fast
> +-- function names for errors in tail calls.

This is kinda gibberish. I've tried the following snippets and can't
understand what do you mean by this comment.

| $ luajit -e 'function q(a) return math.sin(a) end q("a")'
| luajit: (command line):1: bad argument #1 to 'q' (number expected, got string)
| stack traceback:
|         [C]: in function 'q'
|         (command line):1: in main chunk
|         [C]: at 0x5610e8497eb0
| $ luajit -e 'loadstring("return math.sin([[a]])")()'
| luajit: (command line):1: bad argument #1 to '?' (number expected, got string)
| stack traceback:
|         [builtin#43]: at 0x7fc0f807ad10
|         (command line):1: in main chunk
|         [C]: at 0x55c1e85c7eb0

I understand the first result. The second result surprised me, but I've
never investigated how loadstring call works (it looks like specifics of
VARG frame, but this is a wild guess). But neither of them fits your
explanation. The root cause is the same: callee uses caller frame, since
caller doesn't need it anymore. Could you please clarify yours?

> +-- The test is disabled for LuaJIT.
> +-- checkmessage([[  -- tail call
> +--   return math.sin("a")
> +-- ]], "'sin'")
>  
>  checkmessage([[collectgarbage("nooption")]], "invalid option")
>  
> -- 
> 2.31.0
> 

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 24/30] test: disable PUC Lua test for non-asci identifier
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 24/30] test: disable PUC Lua test for non-asci identifier Sergey Kaplun via Tarantool-patches
  2021-03-26 15:46   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-31 19:23   ` Igor Munkin via Tarantool-patches
  2021-04-02  8:20     ` Sergey Kaplun via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-31 19:23 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the patch! LGTM, except the nits below.

On 26.03.21, Sergey Kaplun wrote:
> LuaJIT does not avoid to use non-alphanumeric symbols as identifiers,

Typo: s/avoid to use/forbid using/.

> unlike Lua does.
> 
> This patch disables test that expects an error during parsing variable

Typo: s/disables test/disables the test/.
Typo: s/parsing variable/parsing the variable name/.

> contains octal \255 as the first char in a variable name.

Typo: s/contains/containing/.

> 
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
>  test/PUC-Lua-5.1-tests/errors.lua | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua
> index af776a7..028224c 100644
> --- a/test/PUC-Lua-5.1-tests/errors.lua
> +++ b/test/PUC-Lua-5.1-tests/errors.lua
> @@ -202,7 +202,11 @@ checksyntax("[[a]]", "", "[[a]]", 1)
>  checksyntax("'aa'", "", "'aa'", 1)
>  
>  -- test 255 as first char in a chunk
> -checksyntax("\255a = 1", "", "\255", 1)
> +-- LuaJIT does not avoid to use non-alphanumeric symbols

Typo: s/avoid to use/forbid using/.

> +-- as identifiers, unlike Lua does.
> +-- For more details see <src/lj_char.c> and <src/lj_lex.c>.
> +-- LuaJIT: Test is disabled for LuaJIT.
> +-- checksyntax("\255a = 1", "", "\255", 1)
>  
>  doit('I = loadstring("a=9+"); a=3')
>  assert(a==3 and I == nil)
> -- 
> 2.31.0
> 

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 25/30] test: disable PUC Lua error test for syntax level
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 25/30] test: disable PUC Lua error test for syntax level Sergey Kaplun via Tarantool-patches
  2021-03-26 15:52   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-31 19:24   ` Igor Munkin via Tarantool-patches
  2021-04-02  8:30     ` Sergey Kaplun via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-31 19:24 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the patch! LGTM, except the nits below.

On 26.03.21, Sergey Kaplun wrote:
> When LuaJIT is compiled with LUAJIT_ENABLE_GC64, LJ_MAX_SLOTS limit is
> reached and error LJ_ERR_XSLOTS ("function or expression too complex")
> is raised earlier, than LJ_MAX_XLEVEL limit is reached and error
> LJ_ERR_XLEVELS ("chunk has too many syntax levels") is raised.
> 
> This patch disabled test expected the LJ_ERR_XLEVEL error, but

Typo: s/disabled test/disables the test/.

> failing with the LJ_ERR_XSLOTS error.
> 
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
>  test/PUC-Lua-5.1-tests/errors.lua | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua
> index 028224c..328976e 100644
> --- a/test/PUC-Lua-5.1-tests/errors.lua
> +++ b/test/PUC-Lua-5.1-tests/errors.lua
> @@ -228,7 +228,13 @@ local function testrep (init, rep)
>  end
>  testrep("a=", "{")
>  testrep("a=", "(")
> -testrep("", "a(")
> +-- LuaJIT: When compiled with LUAJIT_ENABLE_GC64, LJ_MAX_SLOTS
> +-- limit is reached and error LJ_ERR_XSLOTS ("function or
> +-- expression too complex") is raised earlier, than LJ_MAX_XLEVEL
> +-- limit is reached and error LJ_ERR_XLEVELS ("chunk has too many
> +-- syntax levels") is raised.

Side note: It would be nice if you also mention the root cause. AFAIU,
LuaJIT frontend checks "virtual" stack size at the translation time,
right? Therefore, when GC64 support is enabled every call needs twice
more slots on the coroutine stack (since LJ_FR2 is also set).

> +-- Test is disabled for LuaJIT.
> +-- testrep("", "a(")
>  testrep("", "do ")
>  testrep("", "while a do ")
>  testrep("", "if a then else ")
> -- 
> 2.31.0
> 

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 26/30] test: disable tests with multiple -l options
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 26/30] test: disable tests with multiple -l options Sergey Kaplun via Tarantool-patches
  2021-03-26 15:56   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-31 19:24   ` Igor Munkin via Tarantool-patches
  1 sibling, 0 replies; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-31 19:24 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the patch! LGTM.

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 27/30] test: disable PUC Lua test for checking arg layout
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 27/30] test: disable PUC Lua test for checking arg layout Sergey Kaplun via Tarantool-patches
  2021-03-26 15:58   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-31 19:24   ` Igor Munkin via Tarantool-patches
  2021-04-02  8:35     ` Sergey Kaplun via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-31 19:24 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the patch! LGTM, except the single nit. I see you added FIXME
here, so we can uncomment the test, if we separate LuaJIT regular
testing from Tarantool CI sometime...

On 26.03.21, Sergey Kaplun wrote:
> Unlike LuaJIT, Tarantool doesn't store the given CLI flags in `arg`,
> so the table has the following layout:
> * arg[-1] -- the binary name
> * arg[0]  -- the script name
> * arg[N]  -- the script argument for all N in [1, #arg]
> 
> This patch disables test checking `arg` layout by negative indexes.

Typo: s/disables test/disables the test/.

> 
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473

<snipped>

> -- 
> 2.31.0
> 

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 28/30] test: disable PUC Lua test checking -h option
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 28/30] test: disable PUC Lua test checking -h option Sergey Kaplun via Tarantool-patches
  2021-03-26 15:58   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-31 19:24   ` Igor Munkin via Tarantool-patches
  2021-04-02  8:39     ` Sergey Kaplun via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-31 19:24 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the patch! LGTM, except the nits below. I see you added FIXME
here, so we can uncomment the test, if we separate LuaJIT regular
testing from Tarantool CI sometime...

On 26.03.21, Sergey Kaplun wrote:
> Tarantool returns zero status at exit with -h option, unlike Lua or
> LuaJIT does.
> 
> This patch disables test checking returning status, when binary

Typo: s/disables test/disables the test/.
Typo: s/checking returning status/checking the exit code/.

> runs with -h option.
> 
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---

<snipped>

> -- 
> 2.31.0
> 

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 29/30] test: disable PUC Lua hanging GC test
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 29/30] test: disable PUC Lua hanging GC test Sergey Kaplun via Tarantool-patches
  2021-03-26 16:03   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-31 19:24   ` Igor Munkin via Tarantool-patches
  2021-04-02  8:45     ` Sergey Kaplun via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-31 19:24 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the patch! LGTM, except the nits below.

On 26.03.21, Sergey Kaplun wrote:
> Tarantool has too many objects at start. `gcinfo()` result is always
> greater than 1000 expected by the test. It leads to infinite loop in the
> test.
> 
> This patch disables GC test leading to hanging for Tarantool binary.

Minor: I propose the following rewording:
| This patch disables GC test leading to Tarantool binary hang.

> 
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
>  test/PUC-Lua-5.1-tests/gc.lua | 9 ++++++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/gc.lua b/test/PUC-Lua-5.1-tests/gc.lua
> index 072bbe9..7f9880f 100644
> --- a/test/PUC-Lua-5.1-tests/gc.lua
> +++ b/test/PUC-Lua-5.1-tests/gc.lua
> @@ -133,9 +133,12 @@ do
>      local a = {}
>    until gcinfo() > 1000
>    collectgarbage"restart"
> -  repeat
> -    local a = {}
> -  until gcinfo() < 1000
> +  -- Tarantool has too many objects at start. `gcinfo()` result

I dare to guess that you're talking about *alive* objects here. Please
mention this explicitly, if I'm right.

> +  -- is always greater than 1000.
> +  -- LuaJIT: The test is disabled for Tarantool binary.
> +  -- repeat
> +  --   local a = {}
> +  -- until gcinfo() < 1000
>  end
>  
>  lim = 15
> -- 
> 2.31.0
> 

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 29/30] test: disable PUC Lua hanging GC test
  2021-03-26 16:03   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-31 19:24     ` Igor Munkin via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-31 19:24 UTC (permalink / raw)
  To: Sergey Ostanevich; +Cc: tarantool-patches

Sergos,

On 26.03.21, Sergey Ostanevich wrote:
> Can it be more relevant fix s/1000/n+1000/ for these two loops?
> 
> Although I start talking about an in-place fix, rather than a follow-up.

If you're talking about some constant value, then this solution is still
fragile: one can introduce a new Lua objects in Tarantool builtins and
the test is broken again. However, if you're talking about saving the
value yielded by "collectgarbage('count')" call after the series of
collectgarbage('collect') calls and use 1000 as a *relative* memory
growth, then it looks like a nice follow-up patch. Or Sergey can do it
in this series if he wants to.

> 
> LGTM.
> Sergos
> 
> > On 26 Mar 2021, at 10:43, Sergey Kaplun <skaplun@tarantool.org> wrote:
> > 
> > Tarantool has too many objects at start. `gcinfo()` result is always
> > greater than 1000 expected by the test. It leads to infinite loop in the
> > test.
> > 
> > This patch disables GC test leading to hanging for Tarantool binary.
> > 
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ---
> > test/PUC-Lua-5.1-tests/gc.lua | 9 ++++++---
> > 1 file changed, 6 insertions(+), 3 deletions(-)
> > 
> > diff --git a/test/PUC-Lua-5.1-tests/gc.lua b/test/PUC-Lua-5.1-tests/gc.lua
> > index 072bbe9..7f9880f 100644
> > --- a/test/PUC-Lua-5.1-tests/gc.lua
> > +++ b/test/PUC-Lua-5.1-tests/gc.lua
> > @@ -133,9 +133,12 @@ do
> >     local a = {}
> >   until gcinfo() > 1000
> >   collectgarbage"restart"
> > -  repeat
> > -    local a = {}
> > -  until gcinfo() < 1000
> > +  -- Tarantool has too many objects at start. `gcinfo()` result
> > +  -- is always greater than 1000.
> > +  -- LuaJIT: The test is disabled for Tarantool binary.
> > +  -- repeat
> > +  --   local a = {}
> > +  -- until gcinfo() < 1000
> > end
> > 
> > lim = 15
> > -- 
> > 2.31.0
> > 
> 

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 30/30] test: disable too depth recursive PUC Lua test
  2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 30/30] test: disable too depth recursive PUC Lua test Sergey Kaplun via Tarantool-patches
  2021-03-26 16:28   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-31 19:24   ` Igor Munkin via Tarantool-patches
  2021-04-02  8:47     ` Sergey Kaplun via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-31 19:24 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the patch! LGTM, except the nits below.

On 26.03.21, Sergey Kaplun wrote:
> The first Tarantool's fiber has only 512Kb of stack.
> It is not enough for depth recursive call in the test for

Typo: s/depth/deep/.

> `string.gsub()`.
> 
> This patch disables test leads to Tarantool crash.

Typo: s/disables test/disables the test/.

> 
> Relates to tarantool/tarantool#5782
> Resolves tarantool/tarantool#5845
> Part of tarantool/tarantool#4473

<snipped>

> -- 
> 2.31.0
> 

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 03/30] test: adapt Lua 5.1 suite for out-of-source build
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 03/30] test: adapt Lua 5.1 suite for out-of-source build Sergey Kaplun via Tarantool-patches
  2021-03-26 11:07   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-31 22:58   ` Igor Munkin via Tarantool-patches
  2021-04-01  8:40     ` Sergey Kaplun via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-31 22:58 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the patch! Honestly, I'm not fond of the solution you
implemented, though it allows to make as little changes as possible.
I propose to implement something similar to the solution you've made
within lua-Harness series:
* You need two <dofile> functions: one for launching source files for
  additional checks and another one for running temporary Lua chunks.
* You also need two <loadstring> functions for the same reason.

Mind the fact <dofile> is implemented via <loadstring>, so basically,
there might be no so much changes made for <dofile>. Thoughts?

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 03/30] test: adapt Lua 5.1 suite for out-of-source build
  2021-03-26 14:25     ` Sergey Kaplun via Tarantool-patches
@ 2021-03-31 22:58       ` Igor Munkin via Tarantool-patches
  2021-04-01  8:43         ` Sergey Kaplun via Tarantool-patches
  0 siblings, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-31 22:58 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

On 26.03.21, Sergey Kaplun wrote:
> Hi!
> 
> Thanks for the review!
> 
> On 26.03.21, Sergey Ostanevich wrote:
> > LGTM, just minor changes to commit message.
> > 
> > Sergos
> > 
> > 
> > > On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote:
> > > 
> > > When tests are run out-of-source redefined `dofile()` function
> >                                   ^ I had problem reading here the 
> > ‘out-of-source redefined’. Can you put the ‘when..’ to the appropriate
> > place at the end of the sentence? ’The redefined … when … ‘
> 
> Fixed.
> 
> The new committ message is the following (branch is force-pushed):

But what is fixed in the new version? I see the sentence Sergos asked to
reword is left intact.

> 
> ===================================================================
> test: adapt Lua 5.1 suite for out-of-source build
> 
> When tests are run out-of-source redefined `dofile()` function failed to
> find the test file to load. So, fullpath is detected considering
> `arg[0]` value. Moreover, some tests use `loadfile()` instead, so their
> argument is adjusted to the full path to the files.
> 
> However, test in <verybig.lua> creates a temporary file
> and executes it via `dofile()` too, so this case is handled by
> the second argument -- `prefix` equals an empty string for
> current working directory.
> 
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ===================================================================
> 
> >  
> > > failed to find file to load. So, fullpath is detected considering
> > > `arg[0]` value. Moreover, some tests use `loadfile()` instead, so
> > > their argument is adjusted to the full path to the files.
> > > 
> > > However, test in <verybig.lua> creates a temporary file
> > > and executes it via `dofile()` too, so this case is handled by
> > > the second argument -- `prefix` equals an empty string for
> > > current working directory.
> > > 
> > > Part of tarantool/tarantool#5845
> > > Part of tarantool/tarantool#4473

<snipped>

> > > -- 
> > > 2.31.0
> > > 
> > 
> 
> -- 
> Best regards,
> Sergey Kaplun

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 04/30] test: remove quotes in progname from <main.lua>
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 04/30] test: remove quotes in progname from <main.lua> Sergey Kaplun via Tarantool-patches
  2021-03-26 11:12   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-31 22:58   ` Igor Munkin via Tarantool-patches
  2021-04-01  8:50     ` Sergey Kaplun via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-31 22:58 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the patch! LGTM, except the nits below.

On 26.03.21, Sergey Kaplun wrote:
> When LUAJIT_TEST_COMMAND extend the least `arg` with

Typo: s/LUAJIT_TEST_COMMAND extend/LUAJIT_TEST_COMMAND extends/.
Typo: s/the least `arg`/the least `arg` slot/.

> some string containing double quotes, bash failed to exec this

Minor: I believe you're not talking about bash here, but rather
about <os.execute> and hence system(3) command, IIRC.

> command for child test.
> 
> This patch removes edged '"' to be able run extended command

Minor: I guess "framing" fits better than "edging".
Typo: s/to be able run extended/to be able to run an extended/.

> containing '"' and run other test suites.
> 
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
>  test/PUC-Lua-5.1-tests/main.lua | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua
> index f520896..4f8b8bf 100644
> --- a/test/PUC-Lua-5.1-tests/main.lua
> +++ b/test/PUC-Lua-5.1-tests/main.lua
> @@ -11,7 +11,9 @@ out = os.tmpname()
>  do
>    local i = 0
>    while arg[i] do i=i-1 end
> -  progname = '"'..arg[i+1]..'"'
> +  -- LuaJIT: remove edged '"' to be able run extended command

Minor: I guess "framing" fits better than "edging".
Typo: s/to be able run extended/to be able to run an extended/.

> +  -- containing '"' and run other test suites.
> +  progname = arg[i+1]
>  end
>  print(progname)
>  

<snipped>

> -- 
> 2.31.0
> 

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 05/30] test: adapt arg availability test from Lua suite
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 05/30] test: adapt arg availability test from Lua suite Sergey Kaplun via Tarantool-patches
  2021-03-26 11:22   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-31 22:58   ` Igor Munkin via Tarantool-patches
  2021-04-01  9:37     ` Sergey Kaplun via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-31 22:58 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the patch! Please consider the comments below.

On 26.03.21, Sergey Kaplun wrote:
> The argument table `arg` can be read (and modified) by `LUA_INIT` and
> `-e` chunks since the commit 92d9ff211ae864777a8580b5a7326d5f408161ce
> (Set arg table before evaluating LUA_INIT and -e chunks.).
> 
> This behaviour is similar to Lua 5.3, so the test was adapted
> considering PUC-Rio Lua 5.3 test suite taken from
> https://www.lua.org/tests/lua-5.3.0-tests.tar.gz.
> 
> Closes tarantool/tarantool#5686

As we discussed before: s/Closes/Resolves/.

> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
>  test/PUC-Lua-5.1-tests/main.lua | 14 ++++++++++++--
>  1 file changed, 12 insertions(+), 2 deletions(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua
> index 4f8b8bf..c11a576 100644
> --- a/test/PUC-Lua-5.1-tests/main.lua
> +++ b/test/PUC-Lua-5.1-tests/main.lua
> @@ -69,9 +69,19 @@ a = string.format(a, progname)
>  prepfile(a)
>  RUN('lua "-e " -- %s a b c', prog)
>  
> -prepfile"assert(arg==nil)"
> +-- test 'arg' availability in libraries
> +-- LuaJIT: LuaJIT v2.1.0-beta3 has extension from Lua 5.3:
> +-- The argument table `arg` can be read (and modified)
> +-- by `LUA_INIT` and `-e` chunks.
> +-- See commit 92d9ff211ae864777a8580b5a7326d5f408161ce
> +-- (Set arg table before evaluating LUA_INIT and -e chunks.).
> +-- See also https://github.com/tarantool/tarantool/issues/5686.
> +-- In Lua 5.3 this feature was introduced via commit
> +-- 23f0ff95177eda2e0a80e3a48562cc6837705735.
> +-- Test is adapted from PUC-Rio Lua 5.3 test suite.
> +prepfile"assert(arg)"
>  prepfile("assert(arg)", otherprog)
> -RUN("lua -l%s - < %s", prog, otherprog)
> +RUN('env LUA_PATH="?;;" lua -l%s - < %s', prog, otherprog)

Why LUA_PATH is tweaked here?

>  
>  prepfile""
>  RUN("lua - < %s > %s", prog, out)
> -- 
> 2.31.0
> 

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 06/30] test: disable PUC Lua tests confused by -v output
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 06/30] test: disable PUC Lua tests confused by -v output Sergey Kaplun via Tarantool-patches
  2021-03-26 11:26   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-31 22:58   ` Igor Munkin via Tarantool-patches
  2021-04-01  9:56     ` Sergey Kaplun via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-31 22:58 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the patch! LGTM, except the nits below.

On 26.03.21, Sergey Kaplun wrote:
> Version and status are printed in stdout instead stderr since

Typo: s/printed in stdout/printed to stdout/.
Typo: s/instead stderr/instead of stderr/.

> LuaJIT-2.0.0-beta11 (as it is not an error message).
> See commit 0bd1a66f2f055211ef55834ccebca3b82d03c735
> (Print version and JIT status to stdout, not stderr.).
> This behavior is the same as in Lua 5.2.
> 
> This patch disables tests confused by unexpected -v output to stdout.
> 
> Relates to tarantool/tarantool#5687
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
>  test/PUC-Lua-5.1-tests/main.lua | 28 ++++++++++++++++++++--------
>  1 file changed, 20 insertions(+), 8 deletions(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua
> index c11a576..56f56a0 100644
> --- a/test/PUC-Lua-5.1-tests/main.lua
> +++ b/test/PUC-Lua-5.1-tests/main.lua
> @@ -103,26 +103,37 @@ prepfile[[
>  RUN("lua - < %s > %s", prog, out)
>  checkout("1\tnil\n")
>  
> +-- Version and status are printed in stdout instead stderr since
> +-- LuaJIT-2.0.0-beta11 (as it is not an error message).

Typo: s/printed in stdout/printed to stdout/.
Typo: s/instead stderr/instead of stderr/.

> +-- See commit 0bd1a66f2f055211ef55834ccebca3b82d03c735
> +-- (Print version and JIT status to stdout, not stderr.).
> +-- This behavior is the same as in Lua 5.2.
> +-- In Lua 5.2 this feature was introduced via commit
> +-- 9e7de9473c65baee1f567852a778f2d33a47ea83.
> +-- See also https://github.com/tarantool/tarantool/issues/5687.

<snipped>

> -- 
> 2.31.0
> 

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 07/30] test: disable Lua tests for bytecode with header
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 07/30] test: disable Lua tests for bytecode with header Sergey Kaplun via Tarantool-patches
  2021-03-26 11:30   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-31 22:59   ` Igor Munkin via Tarantool-patches
  1 sibling, 0 replies; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-31 22:59 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the patch! LGTM.

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 09/30] test: disable Lua suite tests for line hook
  2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 09/30] test: disable Lua suite tests for line hook Sergey Kaplun via Tarantool-patches
  2021-03-26 11:35   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-31 22:59   ` Igor Munkin via Tarantool-patches
  2021-04-01 10:06     ` Sergey Kaplun via Tarantool-patches
  1 sibling, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-31 22:59 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the patch! Please consider the comments below.

On 26.03.21, Sergey Kaplun wrote:
> FIXME: LuaJIT interprets a return from a new function loaded by

Typo: FIXME is excess here (looks like the comment copy-paste).

> `loadstring()` with a change line number for bytecode position
> unlike Lua does. This looks like "implementation-defined behaviour"

Sorry, I can't understand what is written here, though I understand that
there is a difference between Lua and LuaJIT behaviour and the example
below. Could you please clarify the sentence above?

> mentioned in https://luajit.org/status.html.
> 
> All tests checked the debug hook for a new line of code are affected

Typo: s/tests checked/tests checking/.

> and disabled by this patch.
> 
> Relates to tarantool/tarantool#5693
> Part of tarantool/tarantool#5845
> Part of tarantool/tarantool#4473
> ---
>  test/PUC-Lua-5.1-tests/db.lua | 19 ++++++++++++++++++-
>  1 file changed, 18 insertions(+), 1 deletion(-)
> 
> diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua
> index 9d2c86f..a8c7196 100644
> --- a/test/PUC-Lua-5.1-tests/db.lua
> +++ b/test/PUC-Lua-5.1-tests/db.lua
> @@ -95,6 +95,23 @@ repeat
>    assert(g(f) == 'a')
>  until 1
>  
> +-- FIXME: LuaJIT interprets a return from calling result of
> +-- `loadstring()` with a new line number unlike Lua does.

Meh, I also failed to understand the wording here...

> +-- Here is an example (it is joined in one line intend):
> +--[[
> +debug.sethook(function(_, l) print("LINE: "..l) end, "l") loadstring("\n\ns=nil")() debug.sethook()
> +--]]
> +-- This chunk prints for LuaJIT:
> +--[[
> +LINE: 3
> +LINE: 1
> +--]]
> +-- But for Lua 5.1 it is only "LINE: 3" in the output.
> +-- See also https://github.com/tarantool/tarantool/issues/5693.
> +-- Considering implementation-defined behaviour diference

Typo: s/diference/difference/.

> +-- (see also https://luajit.org/status.html) test is disabled for
> +-- LuaJIT.
> +--[=[
>  test([[if
>  math.sin(1)
>  then
> @@ -149,7 +166,7 @@ end
>  ]], {1,2,1,2,1,3})
>  
>  test([[for i=1,4 do a=1 end]], {1,1,1,1,1})
> -
> +--]=]
>  
>  
>  print'+'
> -- 
> 2.31.0
> 

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 01/30] test: add PUC-Rio Lua 5.1 test suite
  2021-03-30 22:13   ` Igor Munkin via Tarantool-patches
@ 2021-04-01  8:11     ` Sergey Kaplun via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-01  8:11 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

Thanks for the review!

On 31.03.21, Igor Munkin wrote:
> Sergey,
> 
> Thanks for the patch! LGTM, except the nits below.
> 
> On 26.03.21, Sergey Kaplun wrote:
> > This patch adds PUC-Rio Lua 5.1 test suite as a part of the LuaJIT test
> > suite. Source code taken verbatim (except trailing whitespaces) from
> 
> Typo: s/code taken/code is taken/.
> Typo: I believe it's always singular: whitespace.

Fixed.

> 
> > https://www.lua.org/tests/lua5.1-tests.tar.gz.
> > 
> > Some tests may fail after this commit. They will be disabled
> > or adapted in the next patches.
> > 
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ---
> >  .luacheckrc                                |    5 +-
> >  test/CMakeLists.txt                        |    2 +
> >  test/PUC-Lua-5.1-tests/CMakeLists.txt      |   45 +
> >  test/PUC-Lua-5.1-tests/README              |   41 +
> >  test/PUC-Lua-5.1-tests/all.lua             |  137 +++
> >  test/PUC-Lua-5.1-tests/api.lua             |  711 ++++++++++++
> >  test/PUC-Lua-5.1-tests/attrib.lua          |  339 ++++++
> >  test/PUC-Lua-5.1-tests/big.lua             |  381 +++++++
> >  test/PUC-Lua-5.1-tests/calls.lua           |  294 +++++
> >  test/PUC-Lua-5.1-tests/checktable.lua      |   77 ++
> >  test/PUC-Lua-5.1-tests/closure.lua         |  422 +++++++
> >  test/PUC-Lua-5.1-tests/code.lua            |  143 +++
> >  test/PUC-Lua-5.1-tests/constructs.lua      |  240 ++++
> >  test/PUC-Lua-5.1-tests/db.lua              |  499 +++++++++
> >  test/PUC-Lua-5.1-tests/errors.lua          |  250 +++++
> >  test/PUC-Lua-5.1-tests/etc/ltests.c        | 1147 ++++++++++++++++++++
> >  test/PUC-Lua-5.1-tests/etc/ltests.h        |   92 ++
> >  test/PUC-Lua-5.1-tests/events.lua          |  360 ++++++
> >  test/PUC-Lua-5.1-tests/files.lua           |  324 ++++++
> >  test/PUC-Lua-5.1-tests/gc.lua              |  312 ++++++
> >  test/PUC-Lua-5.1-tests/libs/CMakeLists.txt |   18 +
> >  test/PUC-Lua-5.1-tests/libs/lib1.c         |   40 +
> >  test/PUC-Lua-5.1-tests/libs/lib11.c        |   18 +
> >  test/PUC-Lua-5.1-tests/libs/lib2.c         |   28 +
> >  test/PUC-Lua-5.1-tests/libs/lib21.c        |   18 +
> >  test/PUC-Lua-5.1-tests/literals.lua        |  176 +++
> >  test/PUC-Lua-5.1-tests/locals.lua          |  127 +++
> >  test/PUC-Lua-5.1-tests/main.lua            |  159 +++
> >  test/PUC-Lua-5.1-tests/math.lua            |  208 ++++
> >  test/PUC-Lua-5.1-tests/nextvar.lua         |  396 +++++++
> >  test/PUC-Lua-5.1-tests/pm.lua              |  273 +++++
> >  test/PUC-Lua-5.1-tests/sort.lua            |   74 ++
> >  test/PUC-Lua-5.1-tests/strings.lua         |  176 +++
> >  test/PUC-Lua-5.1-tests/vararg.lua          |  126 +++
> >  test/PUC-Lua-5.1-tests/verybig.lua         |  100 ++
> >  35 files changed, 7756 insertions(+), 2 deletions(-)
> >  create mode 100644 test/PUC-Lua-5.1-tests/CMakeLists.txt
> >  create mode 100644 test/PUC-Lua-5.1-tests/README
> >  create mode 100755 test/PUC-Lua-5.1-tests/all.lua
> 
> Minor: I doubt all.lua need to be an executable. Feel free to ignore.

The suite is taken with no change; this file was executable, and I see no
reason to change it. Also, it highlights this file as the suite runner.
Ignoring for now.

> 
> >  create mode 100644 test/PUC-Lua-5.1-tests/api.lua
> >  create mode 100644 test/PUC-Lua-5.1-tests/attrib.lua
> >  create mode 100644 test/PUC-Lua-5.1-tests/big.lua
> >  create mode 100644 test/PUC-Lua-5.1-tests/calls.lua
> >  create mode 100644 test/PUC-Lua-5.1-tests/checktable.lua
> >  create mode 100644 test/PUC-Lua-5.1-tests/closure.lua
> >  create mode 100644 test/PUC-Lua-5.1-tests/code.lua
> >  create mode 100644 test/PUC-Lua-5.1-tests/constructs.lua
> >  create mode 100644 test/PUC-Lua-5.1-tests/db.lua
> >  create mode 100644 test/PUC-Lua-5.1-tests/errors.lua
> >  create mode 100644 test/PUC-Lua-5.1-tests/etc/ltests.c
> >  create mode 100644 test/PUC-Lua-5.1-tests/etc/ltests.h
> >  create mode 100644 test/PUC-Lua-5.1-tests/events.lua
> >  create mode 100644 test/PUC-Lua-5.1-tests/files.lua
> >  create mode 100644 test/PUC-Lua-5.1-tests/gc.lua
> >  create mode 100644 test/PUC-Lua-5.1-tests/libs/CMakeLists.txt
> >  create mode 100644 test/PUC-Lua-5.1-tests/libs/lib1.c
> >  create mode 100644 test/PUC-Lua-5.1-tests/libs/lib11.c
> >  create mode 100644 test/PUC-Lua-5.1-tests/libs/lib2.c
> >  create mode 100644 test/PUC-Lua-5.1-tests/libs/lib21.c
> >  create mode 100644 test/PUC-Lua-5.1-tests/literals.lua
> >  create mode 100644 test/PUC-Lua-5.1-tests/locals.lua
> >  create mode 100644 test/PUC-Lua-5.1-tests/main.lua
> >  create mode 100644 test/PUC-Lua-5.1-tests/math.lua
> >  create mode 100644 test/PUC-Lua-5.1-tests/nextvar.lua
> >  create mode 100644 test/PUC-Lua-5.1-tests/pm.lua
> >  create mode 100644 test/PUC-Lua-5.1-tests/sort.lua
> >  create mode 100644 test/PUC-Lua-5.1-tests/strings.lua
> >  create mode 100644 test/PUC-Lua-5.1-tests/vararg.lua
> >  create mode 100644 test/PUC-Lua-5.1-tests/verybig.lua
> > 
> 
> <snipped>
> 
> > diff --git a/test/PUC-Lua-5.1-tests/CMakeLists.txt b/test/PUC-Lua-5.1-tests/CMakeLists.txt
> > new file mode 100644
> > index 0000000..773db0d
> > --- /dev/null
> > +++ b/test/PUC-Lua-5.1-tests/CMakeLists.txt
> > @@ -0,0 +1,45 @@
> > +# Test suite that has been added from PUC-Rio Lua 5.1 test archive
> > +# in scope of https://github.com/tarantool/tarantool/issues/5845.
> > +
> > +# See the rationale in the root CMakeLists.txt.
> > +cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
> > +
> > +# XXX: There are two ways to set up the proper environment
> > +# described in the suite's README:
> > +# * set LUA_PATH to "?;./?.lua"
> > +# * or, better yet, set LUA_PATH to "./?.lua;;" and LUA_INIT to
> > +#   "package.path = '?;'..package.path"
> > +# Unfortunately, Tarantool doesn't support LUA_INIT and most
> > +# likely it never will. For more info, see
> > +# https://github.com/tarantool/tarantool/issues/5744
> > +# Hence, there is no way other than set LUA_PATH environment
> > +# variable as proposed in the first case.
> > +set(LUA_PATH "?\;${CMAKE_CURRENT_SOURCE_DIR}/?.lua")
> > +
> > +# Set PUC-Lua-5.1-tests-prepare target that creates <libs/P1>
> 
> Minor: IMHO, "set" fits worse here than "create" or "introduce". Feel
> free to ignore.

Changed to "Establish" ("Introduce" fits more for the new
functionality, not single target, in my opinion). I wanted to use
"Create" first, but it invokes a tautology with "creates" later
in the sentence. May be "Set up" will be better here.

> 
> > +# subdirectory.
> > +add_subdirectory(libs)
> > +
> > +# TODO: PUC-Rio Lua 5.1 test suite also has special header
> > +# <ltests.h> and <ltests.c> translation unit to check some
> > +# internal behaviour of the Lua implementation (see etc/
> > +# directory). It modifies realloc function to check memory
> > +# consistency and also contains tests for yield in hooks
> > +# and for the Lua C API.
> > +# But, unfortunately, <ltests.c> depends on specific PUC-Rio
> > +# Lua 5.1 internal headers and should be adapted for LuaJIT.
> > +
> > +add_custom_target(PUC-Lua-5.1-tests
> > +  DEPENDS ${LUAJIT_TEST_BINARY} PUC-Lua-5.1-tests-prepare
> > +)
> > +
> > +add_custom_command(TARGET PUC-Lua-5.1-tests
> > +  COMMENT "Running PUC-Rio Lua 5.1 tests"
> > +  COMMAND
> > +  env
> > +    LUA_PATH="${LUA_PATH}\;\;"
> > +    ${LUAJIT_TEST_COMMAND} ${CMAKE_CURRENT_SOURCE_DIR}/all.lua
> > +  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
> > +)
> > +
> > +# vim: expandtab tabstop=2 shiftwidth=2
> 
> <snipped>
> 
> > diff --git a/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt
> > new file mode 100644
> > index 0000000..f24e7f3
> > --- /dev/null
> > +++ b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt
> > @@ -0,0 +1,18 @@
> > +# Test suite that has been added from PUC-Rio Lua 5.1 test archive
> > +# in scope of https://github.com/tarantool/tarantool/issues/5845.
> > +
> > +# See the rationale in the root CMakeLists.txt.
> > +cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
> > +
> 
> Minor: What about TODO for building libs/*.c sources? Anyway, you did it
> in the following patch, so feel free to ignore.

Yep, ignoring, because the are added in the next patch for consistency.

> 
> > +# The original tarball contains subdirectory "libs" with an empty
> > +# subdirectory "libs/P1", to be used by tests.
> > +# Instead of tracking empty directory with some anchor-file for
> > +# git, create this directory via CMake.
> > +add_custom_target(PUC-Lua-5.1-tests-prepare)
> > +add_custom_command(TARGET PUC-Lua-5.1-tests-prepare
> > +  COMMENT "Create directory for PUC-Rio Lua 5.1 tests"
> > +  COMMAND ${CMAKE_COMMAND} -E make_directory P1
> > +  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
> > +)
> > +
> > +# vim: expandtab tabstop=2 shiftwidth=2
> 
> <snipped>
> 
> > -- 
> > 2.31.0
> > 
> 
> -- 
> Best regards,
> IM

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 02/30] test: add compiling for C libs from PUC-Rio-Lua5.1
  2021-03-30 22:14   ` Igor Munkin via Tarantool-patches
@ 2021-04-01  8:21     ` Sergey Kaplun via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-01  8:21 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

Thanks for the review!

On 31.03.21, Igor Munkin wrote:
> Sergey,
> 
> Thanks for the patch! LGTM, except the nits below.
> 
> I propose the following rewording for commit subject:
> | test: build auxiliary C libs from PUC-Rio-Lua5.1

Applied, thanks.

> 
> On 26.03.21, Sergey Kaplun wrote:
> > This patch adds commands to create additional LuaC libraries for tests
> 
> Minor: these are not "commands" but "rules".

Fixed.

> 
> > in <attrib.lua>. Also, it renames `luaL_reg` to `luaL_Reg` in <lib1.c>
> > and <lib2.c> to be consistent with the current LuaJIT's LuaC API.
> > 
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ---
> >  test/PUC-Lua-5.1-tests/CMakeLists.txt      |  3 +-
> >  test/PUC-Lua-5.1-tests/libs/CMakeLists.txt | 48 +++++++++++++++++++++-
> >  test/PUC-Lua-5.1-tests/libs/lib1.c         |  2 +-
> >  test/PUC-Lua-5.1-tests/libs/lib2.c         |  2 +-
> >  4 files changed, 51 insertions(+), 4 deletions(-)
> > 
> > diff --git a/test/PUC-Lua-5.1-tests/CMakeLists.txt b/test/PUC-Lua-5.1-tests/CMakeLists.txt
> > index 773db0d..3c31aae 100644
> > --- a/test/PUC-Lua-5.1-tests/CMakeLists.txt
> > +++ b/test/PUC-Lua-5.1-tests/CMakeLists.txt
> > @@ -16,7 +16,8 @@ cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
> >  # variable as proposed in the first case.
> >  set(LUA_PATH "?\;${CMAKE_CURRENT_SOURCE_DIR}/?.lua")
> 
> Side note: I see no LUA_CPATH, but I grepped the spots where lib*.so are
> required and found that package.cpath is tweaked right there. Hence
> LUA_CPATH is excess, isn't it?

Yep. Also, `LUA_CPATH` isn't mentioned in suite's README.

> 
> >  
> 
> <snipped>
> 
> > diff --git a/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt
> > index f24e7f3..aa64a44 100644
> > --- a/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt
> > +++ b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt
> > @@ -4,11 +4,57 @@
> >  # See the rationale in the root CMakeLists.txt.
> >  cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
> >  
> > +# Build additional C libraries for tests.
> > +macro(BuildTestCLib lib sources)
> 
> <snipped>
> 
> > +  elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
> 
> Minor: I personally would strip this option out for all remaining
> systems (i.e. *BSD too), since we have no guarantee the CMake defaults
> won't be broken on other distros sometime. Feel free to ignore (but
> it'll be on your conscience).

I prefer not to do this -- if there is another one system with the same
behaviour, it should be mentioned explicitly here, to avoid questions
in the future.
Ignoring.

> 
> > +    # XXX: This is necessary mostly for openSUSE builds, see also
> > +    # https://bugzilla.suse.com/show_bug.cgi?id=1012388.
> > +    # Just strip out the linker flag to suppress this linker
> > +    # option.
> > +    string(REPLACE "-Wl,--no-undefined" ""
> > +      CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}"
> > +    )
> > +  endif()
> 
> <snipped>
> 
> > +endmacro()
> > +
> > +BuildTestCLib(lib1  lib1.c)
> 
> Typo: excess whitespace.
> 
> > +BuildTestCLib(lib11 lib1.c lib11.c)
> > +BuildTestCLib(lib2  lib2.c)
> 
> Typo: excess whitespace.

Strictly saying they are not excess -- I want to align library
sources for easier reading :). Removed.

> 
> > +BuildTestCLib(lib21 lib2.c lib21.c)
> > +
> > +# Create exact copy of the lib2 library for tests in attrib.lua.
> 
> Typo: s/create exact copy/create the exact copy/.

Fixed.

> 
> > +set(LIB2ORIG "${CMAKE_CURRENT_BINARY_DIR}/lib2${CMAKE_SHARED_LIBRARY_SUFFIX}")
> > +set(LIB2COPY "${CMAKE_CURRENT_BINARY_DIR}/-lib2${CMAKE_SHARED_LIBRARY_SUFFIX}")
> 
> <snipped>
> 
> > -- 
> > 2.31.0
> > 
> 
> -- 
> Best regards,
> IM

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 03/30] test: adapt Lua 5.1 suite for out-of-source build
  2021-03-31 22:58   ` Igor Munkin via Tarantool-patches
@ 2021-04-01  8:40     ` Sergey Kaplun via Tarantool-patches
  2021-04-06 16:56       ` Igor Munkin via Tarantool-patches
  0 siblings, 1 reply; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-01  8:40 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

Thanks for the review!

On 01.04.21, Igor Munkin wrote:
> Sergey,
> 
> Thanks for the patch! Honestly, I'm not fond of the solution you
> implemented, though it allows to make as little changes as possible.
> I propose to implement something similar to the solution you've made
> within lua-Harness series:
> * You need two <dofile> functions: one for launching source files for
>   additional checks and another one for running temporary Lua chunks.
> * You also need two <loadstring> functions for the same reason.
> 
> Mind the fact <dofile> is implemented via <loadstring>, so basically,
> there might be no so much changes made for <dofile>. Thoughts?

I prefer to use one function, and two wrappers around it.
For example, let it be `absolute_dofile()` and `cwd_dofile()`.

But honestly, it is not the single one problem of this suite (no test
isolation, global variables, huge excess output, hardcoded limit
values, etc).
It looks like we need to refactor this suite later (plus adapt test
for LuaJIT extensions from Lua 5.2+). I propose to do all this work
via that refactoring, not now. Otherwise, it looks like a patch, which
will still need to be refactored later.

Thoughts?

> 
> -- 
> Best regards,
> IM

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 03/30] test: adapt Lua 5.1 suite for out-of-source build
  2021-03-31 22:58       ` Igor Munkin via Tarantool-patches
@ 2021-04-01  8:43         ` Sergey Kaplun via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-01  8:43 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

On 01.04.21, Igor Munkin wrote:
> Sergey,
> 
> On 26.03.21, Sergey Kaplun wrote:
> > Hi!
> > 
> > Thanks for the review!
> > 
> > On 26.03.21, Sergey Ostanevich wrote:
> > > LGTM, just minor changes to commit message.
> > > 
> > > Sergos
> > > 
> > > 
> > > > On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote:
> > > > 
> > > > When tests are run out-of-source redefined `dofile()` function
> > >                                   ^ I had problem reading here the 
> > > ‘out-of-source redefined’. Can you put the ‘when..’ to the appropriate
> > > place at the end of the sentence? ’The redefined … when … ‘
> > 
> > Fixed.
> > 
> > The new committ message is the following (branch is force-pushed):
> 
> But what is fixed in the new version? I see the sentence Sergos asked to
> reword is left intact.

Brr, sorry. Looks like I changed it twice. Thanks for the catch!
The new version (checked twice):

===================================================================
test: adapt Lua 5.1 suite for out-of-source build

The redefined `dofile()` function failed to find the test file to load,
when tests are run out-of-source. So, fullpath is detected considering
`arg[0]` value. Moreover, some tests use `loadfile()` instead, so their
argument is adjusted to the full path to the files.

However, test in <verybig.lua> creates a temporary file
and executes it via `dofile()` too, so this case is handled by
the second argument -- `prefix` equals an empty string for
current working directory.

Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
===================================================================

> 
> > 
> > ===================================================================
> > test: adapt Lua 5.1 suite for out-of-source build
> > 
> > When tests are run out-of-source redefined `dofile()` function failed to
> > find the test file to load. So, fullpath is detected considering
> > `arg[0]` value. Moreover, some tests use `loadfile()` instead, so their
> > argument is adjusted to the full path to the files.
> > 
> > However, test in <verybig.lua> creates a temporary file
> > and executes it via `dofile()` too, so this case is handled by
> > the second argument -- `prefix` equals an empty string for
> > current working directory.
> > 
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ===================================================================
> > 
> > >  
> > > > failed to find file to load. So, fullpath is detected considering
> > > > `arg[0]` value. Moreover, some tests use `loadfile()` instead, so
> > > > their argument is adjusted to the full path to the files.
> > > > 
> > > > However, test in <verybig.lua> creates a temporary file
> > > > and executes it via `dofile()` too, so this case is handled by
> > > > the second argument -- `prefix` equals an empty string for
> > > > current working directory.
> > > > 
> > > > Part of tarantool/tarantool#5845
> > > > Part of tarantool/tarantool#4473
> 
> <snipped>
> 
> > > > -- 
> > > > 2.31.0
> > > > 
> > > 
> > 
> > -- 
> > Best regards,
> > Sergey Kaplun
> 
> -- 
> Best regards,
> IM

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 04/30] test: remove quotes in progname from <main.lua>
  2021-03-31 22:58   ` Igor Munkin via Tarantool-patches
@ 2021-04-01  8:50     ` Sergey Kaplun via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-01  8:50 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

Thanks for the review!

On 01.04.21, Igor Munkin wrote:
> Sergey,
> 
> Thanks for the patch! LGTM, except the nits below.
> 
> On 26.03.21, Sergey Kaplun wrote:
> > When LUAJIT_TEST_COMMAND extend the least `arg` with
> 
> Typo: s/LUAJIT_TEST_COMMAND extend/LUAJIT_TEST_COMMAND extends/.
> Typo: s/the least `arg`/the least `arg` slot/.

Fixed.

> 
> > some string containing double quotes, bash failed to exec this
> 
> Minor: I believe you're not talking about bash here, but rather
> about <os.execute> and hence system(3) command, IIRC.

Fixed. Thanks!

> 
> > command for child test.
> > 
> > This patch removes edged '"' to be able run extended command
> 
> Minor: I guess "framing" fits better than "edging".
> Typo: s/to be able run extended/to be able to run an extended/.

Fixed.

> 
> > containing '"' and run other test suites.
> > 
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ---
> >  test/PUC-Lua-5.1-tests/main.lua | 8 ++++++--
> >  1 file changed, 6 insertions(+), 2 deletions(-)
> > 
> > diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua
> > index f520896..4f8b8bf 100644
> > --- a/test/PUC-Lua-5.1-tests/main.lua
> > +++ b/test/PUC-Lua-5.1-tests/main.lua
> > @@ -11,7 +11,9 @@ out = os.tmpname()
> >  do
> >    local i = 0
> >    while arg[i] do i=i-1 end
> > -  progname = '"'..arg[i+1]..'"'
> > +  -- LuaJIT: remove edged '"' to be able run extended command
> 
> Minor: I guess "framing" fits better than "edging".
> Typo: s/to be able run extended/to be able to run an extended/.

Fixed.

> 
> > +  -- containing '"' and run other test suites.
> > +  progname = arg[i+1]
> >  end
> >  print(progname)
> >  
> 
> <snipped>
> 
> > -- 
> > 2.31.0
> > 
> 
> -- 
> Best regards,
> IM

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 05/30] test: adapt arg availability test from Lua suite
  2021-03-31 22:58   ` Igor Munkin via Tarantool-patches
@ 2021-04-01  9:37     ` Sergey Kaplun via Tarantool-patches
  2021-04-06 15:24       ` Igor Munkin via Tarantool-patches
  0 siblings, 1 reply; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-01  9:37 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

Thanks for the review!

On 01.04.21, Igor Munkin wrote:
> Sergey,
> 
> Thanks for the patch! Please consider the comments below.
> 
> On 26.03.21, Sergey Kaplun wrote:
> > The argument table `arg` can be read (and modified) by `LUA_INIT` and
> > `-e` chunks since the commit 92d9ff211ae864777a8580b5a7326d5f408161ce
> > (Set arg table before evaluating LUA_INIT and -e chunks.).
> > 
> > This behaviour is similar to Lua 5.3, so the test was adapted
> > considering PUC-Rio Lua 5.3 test suite taken from
> > https://www.lua.org/tests/lua-5.3.0-tests.tar.gz.
> > 
> > Closes tarantool/tarantool#5686
> 
> As we discussed before: s/Closes/Resolves/.

I used here Closes intentionly:
I suppose, that the issue is not appeared in Tarantool's repo, so
it is closed as far as the final version of patchset does not
contain the issue.
Looks that it is confusing, changed back to Resolves.

Here and in the patches later.

> 
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ---
> >  test/PUC-Lua-5.1-tests/main.lua | 14 ++++++++++++--
> >  1 file changed, 12 insertions(+), 2 deletions(-)
> > 
> > diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua
> > index 4f8b8bf..c11a576 100644
> > --- a/test/PUC-Lua-5.1-tests/main.lua
> > +++ b/test/PUC-Lua-5.1-tests/main.lua
> > @@ -69,9 +69,19 @@ a = string.format(a, progname)
> >  prepfile(a)
> >  RUN('lua "-e " -- %s a b c', prog)
> >  
> > -prepfile"assert(arg==nil)"
> > +-- test 'arg' availability in libraries
> > +-- LuaJIT: LuaJIT v2.1.0-beta3 has extension from Lua 5.3:
> > +-- The argument table `arg` can be read (and modified)
> > +-- by `LUA_INIT` and `-e` chunks.
> > +-- See commit 92d9ff211ae864777a8580b5a7326d5f408161ce
> > +-- (Set arg table before evaluating LUA_INIT and -e chunks.).
> > +-- See also https://github.com/tarantool/tarantool/issues/5686.
> > +-- In Lua 5.3 this feature was introduced via commit
> > +-- 23f0ff95177eda2e0a80e3a48562cc6837705735.
> > +-- Test is adapted from PUC-Rio Lua 5.3 test suite.
> > +prepfile"assert(arg)"
> >  prepfile("assert(arg)", otherprog)
> > -RUN("lua -l%s - < %s", prog, otherprog)
> > +RUN('env LUA_PATH="?;;" lua -l%s - < %s', prog, otherprog)
> 
> Why LUA_PATH is tweaked here?

Looks like Roberto avoids to load some files with the same name
that can be loaded by the old `LUA_PATH`. I preferred to take it intact
from the Lua 5.3 test suite (even comment about `arg` availability).

> 
> >  
> >  prepfile""
> >  RUN("lua - < %s > %s", prog, out)
> > -- 
> > 2.31.0
> > 
> 
> -- 
> Best regards,
> IM

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 06/30] test: disable PUC Lua tests confused by -v output
  2021-03-31 22:58   ` Igor Munkin via Tarantool-patches
@ 2021-04-01  9:56     ` Sergey Kaplun via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-01  9:56 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

Thanks for the review!

On 01.04.21, Igor Munkin wrote:
> Sergey,
> 
> Thanks for the patch! LGTM, except the nits below.
> 
> On 26.03.21, Sergey Kaplun wrote:
> > Version and status are printed in stdout instead stderr since
> 
> Typo: s/printed in stdout/printed to stdout/.
> Typo: s/instead stderr/instead of stderr/.

Fixed.

> 
> > LuaJIT-2.0.0-beta11 (as it is not an error message).
> > See commit 0bd1a66f2f055211ef55834ccebca3b82d03c735
> > (Print version and JIT status to stdout, not stderr.).
> > This behavior is the same as in Lua 5.2.
> > 
> > This patch disables tests confused by unexpected -v output to stdout.
> > 
> > Relates to tarantool/tarantool#5687
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ---
> >  test/PUC-Lua-5.1-tests/main.lua | 28 ++++++++++++++++++++--------
> >  1 file changed, 20 insertions(+), 8 deletions(-)
> > 
> > diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua
> > index c11a576..56f56a0 100644
> > --- a/test/PUC-Lua-5.1-tests/main.lua
> > +++ b/test/PUC-Lua-5.1-tests/main.lua
> > @@ -103,26 +103,37 @@ prepfile[[
> >  RUN("lua - < %s > %s", prog, out)
> >  checkout("1\tnil\n")
> >  
> > +-- Version and status are printed in stdout instead stderr since
> > +-- LuaJIT-2.0.0-beta11 (as it is not an error message).
> 
> Typo: s/printed in stdout/printed to stdout/.
> Typo: s/instead stderr/instead of stderr/.

Fixed.

> 
> > +-- See commit 0bd1a66f2f055211ef55834ccebca3b82d03c735
> > +-- (Print version and JIT status to stdout, not stderr.).
> > +-- This behavior is the same as in Lua 5.2.
> > +-- In Lua 5.2 this feature was introduced via commit
> > +-- 9e7de9473c65baee1f567852a778f2d33a47ea83.
> > +-- See also https://github.com/tarantool/tarantool/issues/5687.
> 
> <snipped>
> 
> > -- 
> > 2.31.0
> > 
> 
> -- 
> Best regards,
> IM

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 09/30] test: disable Lua suite tests for line hook
  2021-03-31 22:59   ` Igor Munkin via Tarantool-patches
@ 2021-04-01 10:06     ` Sergey Kaplun via Tarantool-patches
  2021-04-06 19:45       ` Igor Munkin via Tarantool-patches
  0 siblings, 1 reply; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-01 10:06 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

Thanks for the review!

On 01.04.21, Igor Munkin wrote:
> Sergey,
> 
> Thanks for the patch! Please consider the comments below.
> 
> On 26.03.21, Sergey Kaplun wrote:
> > FIXME: LuaJIT interprets a return from a new function loaded by
> 
> Typo: FIXME is excess here (looks like the comment copy-paste).

Fixed.

> 
> > `loadstring()` with a change line number for bytecode position
> > unlike Lua does. This looks like "implementation-defined behaviour"
> 
> Sorry, I can't understand what is written here, though I understand that
> there is a difference between Lua and LuaJIT behaviour and the example
> below. Could you please clarify the sentence above?

===================================================================
test: disable Lua suite tests for line hook

The LuaJIT's virtual machine interprets the bytecode following the
return from function (i.e. the one succeeding the call made) and located
on the line other than that return bytecode, as a new line trigger for
line hooks, unlike Lua does. This looks like "implementation-defined
behaviour" mentioned in https://luajit.org/status.html.

All tests checking the debug hook for a new line of code are affected
and disabled by this patch.

Relates to tarantool/tarantool#5693
Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
===================================================================

> 
> > mentioned in https://luajit.org/status.html.
> > 
> > All tests checked the debug hook for a new line of code are affected
> 
> Typo: s/tests checked/tests checking/.

Fixed.

> 
> > and disabled by this patch.
> > 
> > Relates to tarantool/tarantool#5693
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ---
> >  test/PUC-Lua-5.1-tests/db.lua | 19 ++++++++++++++++++-
> >  1 file changed, 18 insertions(+), 1 deletion(-)
> > 
> > diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua
> > index 9d2c86f..a8c7196 100644
> > --- a/test/PUC-Lua-5.1-tests/db.lua
> > +++ b/test/PUC-Lua-5.1-tests/db.lua
> > @@ -95,6 +95,23 @@ repeat
> >    assert(g(f) == 'a')
> >  until 1
> >  
> > +-- FIXME: LuaJIT interprets a return from calling result of
> > +-- `loadstring()` with a new line number unlike Lua does.
> 
> Meh, I also failed to understand the wording here...

Reformulated as:

===================================================================
-- FIXME: The LuaJIT's virtual machine interprets the bytecode
-- following the return from function (i.e. the one succeeding
-- the call made) and located on the line other than that return
-- bytecode, as a new line trigger for line hooks,
-- unlike Lua does.
===================================================================

> 
> > +-- Here is an example (it is joined in one line intend):
> > +--[[
> > +debug.sethook(function(_, l) print("LINE: "..l) end, "l") loadstring("\n\ns=nil")() debug.sethook()
> > +--]]
> > +-- This chunk prints for LuaJIT:
> > +--[[
> > +LINE: 3
> > +LINE: 1
> > +--]]
> > +-- But for Lua 5.1 it is only "LINE: 3" in the output.
> > +-- See also https://github.com/tarantool/tarantool/issues/5693.
> > +-- Considering implementation-defined behaviour diference
> 
> Typo: s/diference/difference/.

Fixed, thanks!

> 
> > +-- (see also https://luajit.org/status.html) test is disabled for
> > +-- LuaJIT.
> > +--[=[
> >  test([[if
> >  math.sin(1)
> >  then
> > @@ -149,7 +166,7 @@ end
> >  ]], {1,2,1,2,1,3})
> >  
> >  test([[for i=1,4 do a=1 end]], {1,1,1,1,1})
> > -
> > +--]=]
> >  
> >  
> >  print'+'
> > -- 
> > 2.31.0
> > 
> 
> -- 
> Best regards,
> IM

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 08/30] test: disable JIT for GC step counting tests
  2021-03-30 22:14   ` Igor Munkin via Tarantool-patches
@ 2021-04-01 10:10     ` Sergey Kaplun via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-01 10:10 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

Thanks for the review!

On 31.03.21, Igor Munkin wrote:
> Sergey,
> 
> Thanks for the patch! LGTM, except the nits below.
> 
> I propose the following rewording for commit subject:
> | test: disable JIT for the tests counting GC steps

Thanks, applied!

> 
> On 26.03.21, Sergey Kaplun wrote:
> > JIT compilation can unpredictable allocate or reference objects (or
> 
> Typo: s/unpredictable/unpredictably/.

Fixed, thanks.

> 
> > traces itself). So, the amount of GC steps can vary from run to run.
> > 
> > This patch disables JIT machinery, if it is enabled, for stable GC
> > results.
> > 
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ---
> >  test/PUC-Lua-5.1-tests/gc.lua | 10 ++++++++++
> >  1 file changed, 10 insertions(+)
> > 
> > diff --git a/test/PUC-Lua-5.1-tests/gc.lua b/test/PUC-Lua-5.1-tests/gc.lua
> > index 86a9f75..072bbe9 100644
> > --- a/test/PUC-Lua-5.1-tests/gc.lua
> > +++ b/test/PUC-Lua-5.1-tests/gc.lua
> > @@ -108,11 +108,21 @@ local function dosteps (siz)
> >    return i
> >  end
> >  
> > +-- LuaJIT: JIT compilation can unpredictable allocate or reference
> 
> Typo: s/unpredictable/unpredictably/.

Fixed.

> 
> > +-- objects (or traces itself). Disable it if necessary for
> > +-- this chunk for stable GC results.
> 
> <snipped>
> 
> > -- 
> > 2.31.0
> > 
> 
> -- 
> Best regards,
> IM

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 10/30] test: adapt test for debug.setlocal in Lua suite
  2021-03-30 22:14   ` Igor Munkin via Tarantool-patches
@ 2021-04-01 10:16     ` Sergey Kaplun via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-01 10:16 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

Thanks for the review!

On 31.03.21, Igor Munkin wrote:
> Sergey,
> 
> Thanks for the patch! LGTM, considering your changes on the branch. Also
> consider the comments below.
> 
> On 26.03.21, Sergey Kaplun wrote:
> > LuaJIT: Lua 5.1 interprets `...` in the vararg functions like
> 
> Looks like you just copied the comment below. There is no need for
> 'LuaJIT:' here.
> 
> > an additional first argument unlike LuaJIT does.
> > This behaviour is extension is from Lua 5.2.
> 
> Typo: s/is extension is/is extension/.
> 
> > 
> > This patch adapted test considering LuaJIT's and Lua 5.2 behaviour.
> 
> Side note: Here it is -- you wrote LuaJIT's but Lua 5.2 (neither Lua's
> 5.2 nor Lua 5.2's). How come?
> 
> > The test is adapted like it done in Lua 5.2 test suite taken from
> > https://www.lua.org/tests/lua-5.2.0-tests.tar.gz.
> > 
> > Closes tarantool/tarantool#5694
> 
> As we discussed before: s/Closes/Resolves/.
> 
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ---

The new version of the commit message:
===================================================================
test: adapt test for debug.setlocal in Lua suite

Lua 5.1 interprets `...` in the vararg functions like an additional
local argument unlike LuaJIT does. This behaviour is extension from
Lua 5.2.

This patch adapted test considering behaviour of LuaJIT and Lua 5.2.
The test is adapted like it done in Lua 5.2 test suite taken from
https://www.lua.org/tests/lua-5.2.0-tests.tar.gz.

Part of tarantool/tarantool#5694
Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
===================================================================

> 
> <snipped>
> 
> > -- 
> > 2.31.0
> > 
> 
> -- 
> Best regards,
> IM

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 11/30] test: adapt getlocal PUC test for vararg func
  2021-03-30 22:15   ` Igor Munkin via Tarantool-patches
@ 2021-04-01 11:37     ` Sergey Kaplun via Tarantool-patches
  2021-04-06 20:09       ` Igor Munkin via Tarantool-patches
  0 siblings, 1 reply; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-01 11:37 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

Thanks for the review!

On 31.03.21, Igor Munkin wrote:
> Sergey,
> 
> Thanks for the patch! I can't understand why this patch is separated
> from the previous one. Could you provide a rationale for this, please?
> BTW as we discussed before: s/Closes/Resolves/, considering your changes
> on the branch. Also consider the comments below.

The root reason of the previous patch is about counting of local
variable in caller. Here this local variable is used for counting
arguments amount.

> 
> On 26.03.21, Sergey Kaplun wrote:
> > Lua 5.1 interprets `...` in the vararg functions like an additional
> 
> Typo: s/like/as/.

Fixed.

> 
> > first argument unlike LuaJIT does. So, `a:f()` function will not set
> > corresponding table `arg`, as test expects.
> 
> Typo: s/set corresponding table `arg`/set the corresponding `arg` table/.

Fixed.

> 
> > 
> > Implicit `arg` parameter for old-style vararg functions was finally
> > removed in Lua 5.2. The test is adapted from PUC-Rio Lua 5.2 test suite
> > by removing additional check for amountt of arguments via `arg.n`.
> 
> Typo: s/amountt/amount/.

Fixed.

> 
> > Lua 5.2 test suite is taken from
> > https://www.lua.org/tests/lua-5.2.0-tests.tar.gz.
> > 
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ---
> >  test/PUC-Lua-5.1-tests/db.lua | 11 ++++++++++-
> >  1 file changed, 10 insertions(+), 1 deletion(-)
> > 
> > diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua
> > index e5d8885..6985c29 100644
> > --- a/test/PUC-Lua-5.1-tests/db.lua
> > +++ b/test/PUC-Lua-5.1-tests/db.lua
> > @@ -300,7 +300,16 @@ debug.sethook(function (e)
> 
> <snipped>
> 
> > +-- LuaJIT: Lua 5.1 interprets `...` in the vararg functions like
> 
> Typo: s/like/as/.

Fixed.

> 
> > +-- an additional first argument unlike LuaJIT does.
> > +-- So, `a:f()` function will not set corresponding table `arg`,
> 
> Typo: s/set corresponding table `arg`/set the corresponding `arg` table/.

Fixed.

> 
> > +-- as test expects.
> 
> <snipped>
> 
> > -- 
> > 2.31.0
> > 
> 
> -- 
> Best regards,
> IM

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 12/30] test: adapt PUC Lua test with count hooks
  2021-03-30 22:15   ` Igor Munkin via Tarantool-patches
@ 2021-04-01 11:42     ` Sergey Kaplun via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-01 11:42 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

Thanks for the review!

On 31.03.21, Igor Munkin wrote:
> Sergey,
> 
> Thanks for the patch! LGTM, except the single nit below.
> 
> On 26.03.21, Sergey Kaplun wrote:
> > LuaJIT does not check hooks at traces without defined
> > -DLUAJIT_ENABLE_CHECKHOOK. For more information see <src/lj_record.c>
> > or commit 6bce6b118eeb2bb7f36157de158e5cccf0ea68e5 (Add compile-time
> > option LUAJIT_ENABLE_CHECKHOOK. Disabled by default.).
> > 
> > This patch adapts these tests for LuaJIT by disabling JIT while testing
> > count hooks.
> > 
> > Closes tarantool/tarantool#5701
> 
> As we discussed before: s/Closes/Resolves/.

Fixed.

> 
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> 
> <snipped>
> 
> > -- 
> > 2.31.0
> > 
> 
> -- 
> Best regards,
> IM

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 13/30] test: disable PUC Lua test for tail call info
  2021-03-30 22:15   ` Igor Munkin via Tarantool-patches
@ 2021-04-01 11:52     ` Sergey Kaplun via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-01 11:52 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

Thanks for the review!

On 31.03.21, Igor Munkin wrote:
> Sergey,
> 
> Thanks for the patch! LGTM, except the nits below.
> 
> On 26.03.21, Sergey Kaplun wrote:
> > LuaJIT does not provide information about tail calls in debug.getinfo(),
> > unlike Lua does. This missed feature is described in
> > https://luajit.org/status.html.
> > 
> > This patch disables tests for tail call checks and getfenv() checks,
> > because tail calls do not provide an additional level for LuaJIT
> 
> It's not "level", but "call frame", AFAIU.

Fixed.

> 
> > and level number given to getfenv() should be changed.
> > 
> > Relates to tarantool/tarantool#5702
> > Relates to tarantool/tarantool#5703
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ---
> >  test/PUC-Lua-5.1-tests/db.lua | 30 ++++++++++++++++++++++--------
> >  1 file changed, 22 insertions(+), 8 deletions(-)
> > 
> > diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua
> > index c1a635a..b363abc 100644
> > --- a/test/PUC-Lua-5.1-tests/db.lua
> > +++ b/test/PUC-Lua-5.1-tests/db.lua
> > @@ -400,19 +400,29 @@ function g1(x) g(x) end
> >  
> >  local function h (x) local f=g1; return f(x) end
> >  
> > -h(true)
> > +-- LuaJIT does not provide information about tail calls,
> > +-- unlike Lua does. See also https://luajit.org/status.html.
> > +-- getfenv() behaviour is also different here,
> 
> Typo: looks like line underfull (in LaTeX terms, heh).

Fixed.

> 
> > +-- because tail calls do not provide additional level for LuaJIT
> > +-- and level number should be changed.
> > +-- FIXME: Test is disabled for LuaJIT.
> > +-- See also https://github.com/tarantool/tarantool/issues/5702.
> > +-- h(true)
> 
> <snipped>
> 
> > -for _, k in ipairs(res) do assert(k == table.remove(b, 1)) end
> > -
> 
> Typo: excess whitespace change.

Fixed.

> 
> > +-- Behavior is different for LuaJIT. See the comment above.
> > +-- FIXME: Test is disabled for LuaJIT.
> > +-- for _, k in ipairs(res) do assert(k == table.remove(b, 1)) end
> 
> <snipped>
> 
> > -- 
> > 2.31.0
> > 
> 
> -- 
> Best regards,
> IM

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 14/30] test: adapt activeline check in the PUC Lua test
  2021-03-30 22:15   ` Igor Munkin via Tarantool-patches
@ 2021-04-01 11:58     ` Sergey Kaplun via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-01 11:58 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

Thanks for the review!

On 31.03.21, Igor Munkin wrote:
> Sergey,
> 
> Thanks for the patch! LGTM, except the nits below.
> 
> On 26.03.21, Sergey Kaplun wrote:
> > LuaJIT does not report line with single "end" statement
> 
> Typo: s/report line/report the line/.

Fixed.

> 
> > (the last line of the function) as an active line in
> > debug.getinfo(), unlike Lua does. There is no bytecode
> > related to this line, so it is "unreachable" and
> > may be considered not active.
> > 
> > This patch excludes the last line of a function from the check,
> 
> Typo: s/a function/the function/.

Fixed.

> 
> > considering LuaJIT's behaviour.
> > 
> > Closes tarantool/tarantool#5708
> 
> As we discussed before: s/Closes/Resolves/.

Fixed.

> 
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ---
> >  test/PUC-Lua-5.1-tests/db.lua | 10 +++++++++-
> >  1 file changed, 9 insertions(+), 1 deletion(-)
> > 
> > diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua
> > index b363abc..c704877 100644
> > --- a/test/PUC-Lua-5.1-tests/db.lua
> > +++ b/test/PUC-Lua-5.1-tests/db.lua
> > @@ -491,7 +491,15 @@ local _, l = coroutine.resume(co, 10)
> >  local x = debug.getinfo(co, 1, "lfLS")
> >  assert(x.currentline == l.currentline and x.activelines[x.currentline])
> >  assert(type(x.func) == "function")
> > -for i=x.linedefined + 1, x.lastlinedefined do
> > +-- LuaJIT does not report line with single "end" statement
> 
> Typo: s/report line/report the line/.

Fixed.

> 
> > +-- (the last line of the function) as an active line in
> > +-- debug.getinfo(), unlike Lua does. There is no bytecode
> > +-- related to this line, so it is "unreachable" and
> > +-- may be considered not active.
> > +-- See also https://github.com/tarantool/tarantool/issues/5708.
> > +-- LuaJIT: Test is adapted for LuaJIT's behaviour by avoiding
> > +-- the last line check.
> > +for i=x.linedefined + 1, x.lastlinedefined - 1 do
> >    assert(x.activelines[i])
> >    x.activelines[i] = nil
> >  end
> > -- 
> > 2.31.0
> > 
> 
> -- 
> Best regards,
> IM

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 15/30] test: disable PUC-Lua test for per-coroutine hooks
  2021-03-30 22:16   ` Igor Munkin via Tarantool-patches
@ 2021-04-01 12:03     ` Sergey Kaplun via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-01 12:03 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

Thanks for the review!

On 31.03.21, Igor Munkin wrote:
> Sergey,
> 
> Thanks for the patch! LGTM, except the one nit: I would explicitly
> mention that hook is set *but* for the whole VM instead of the given
> coroutine. Hence hooks work, but assertions are disabled.

Added to the commit message and the comment in the code.

> 
> -- 
> Best regards,
> IM

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 16/30] test: adapt PUC Lua test for %q in fmt for LuaJIT
  2021-03-30 22:16   ` Igor Munkin via Tarantool-patches
@ 2021-04-01 12:33     ` Sergey Kaplun via Tarantool-patches
  2021-04-06 21:37       ` Igor Munkin via Tarantool-patches
  0 siblings, 1 reply; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-01 12:33 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

Thanks for the review!

On 31.03.21, Igor Munkin wrote:
> Sergey,
> 
> Thanks for your patch! Please consider my comments below.
> 
> On 26.03.21, Sergey Kaplun wrote:
> > LuaJIT: LuaJIT since v2.0.0-beta6 has extension from Lua 5.2:
> 
> Looks like you just copied the comment below. There is no need for
> 'LuaJIT:' here.

Fixed.

> 
> > string.format(): %q reversible.
> > See also https://luajit.org/extensions.html#lua52.
> > 
> > In Lua 5.1 string.format() does not accept string values containing
> > embedded zeros, except as arguments to the '%q' option.
> > In Lua 5.2 '\0' is not handled differently from other
> > control chars in string.format('%q', ...).
> > See commit 7cc981c14067d4b0e774a6bfb0acfc2f5c911f0d
> > (string.format("%q", str) is now fully reversible
> > (from Lua 5.2).).
> 
> Well, I honestly don't understand what is changed in *semantics*. I've
> tried the following command with Lua 5.2, Lua 5.1 and LuaJIT 2.0.5 as an
> interpreter being tested
> | <interp> -e 'print(string.format("%q", "\0"))'
> 
> I understand the semantics of "%q", but was it just a bug in Lua 5.1?

A bug with the test for it???

> What does "fully reversible" mean in this context?
> 
> I understand only the fact the behaviour differs and you reimplemented
> the test assertion according to Lua 5.2 testing suite. That's all.
> 
> I found not a single word regarding this issue in Lua bugs[1] page,
> except invalid handling of \r[2]. Is there any issue/page with a more

It looks unrelated to these changes.

> verbose explanation what has been changed in 7cc981c?

I just read these lines in Lua 5.1 reference manual :):
| This function does not accept string values containing embedded
| zeros, except as arguments to the q option.

As for me, it is just new behaviour of Lua 5.2 -- patterns now accept
'\0' as a reqular character (see
4541243355a299a9b75042d207feb87295872c3a (patterns now accept '\0' as a
regular character) from Lua repository). So, according to commit
658ea8752b979102627e2fede7b7ddfbb67ba6c9 (no need to handle '\0'
differently from other control chars in format '%q')) from Lua
repository, this behaviour is excess.

Also, it is mentioned here [2].

> 
> > 
> > This patch adapts test for LuaJIT and Lua 5.2 behaviour considering
> > test from Lua 5.2 test suite taken from
> 
> Typo: s/considering test/considering the test/.

Fixed.

> 
> > https://www.lua.org/tests/lua-5.2.0-tests.tar.gz.
> > 
> > Closes tarantool/tarantool#5710
> 
> As we discussed before: s/Closes/Resolves/.

Fixed.

> 
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ---
> >  test/PUC-Lua-5.1-tests/strings.lua | 12 +++++++++++-
> >  1 file changed, 11 insertions(+), 1 deletion(-)
> > 
> > diff --git a/test/PUC-Lua-5.1-tests/strings.lua b/test/PUC-Lua-5.1-tests/strings.lua
> > index 237dbad..7c1dfb8 100644
> > --- a/test/PUC-Lua-5.1-tests/strings.lua
> > +++ b/test/PUC-Lua-5.1-tests/strings.lua
> > @@ -102,7 +102,17 @@ print('+')
> >  
> >  x = '"?lo"\n\\'
> >  assert(string.format('%q%s', x, x) == '"\\"?lo\\"\\\n\\\\""?lo"\n\\')
> > -assert(string.format('%q', "\0") == [["\000"]])
> > +-- LuaJIT: LuaJIT since v2.0.0-beta6 has extension from Lua 5.2:
> > +-- string.format(): %q reversible.
> > +-- In Lua 5.1 string.format() does not accept string values
> > +-- containing embedded zeros, except as arguments to the q option.
> > +-- In Lua 5.2 '\0' is not handled differently from other
> > +-- control chars in string.format('%q', ...).
> > +-- See commit 7cc981c14067d4b0e774a6bfb0acfc2f5c911f0d
> > +-- (string.format("%q", str) is now fully reversible
> > +-- (from Lua 5.2).).
> > +-- Test is adapted from PUC-Rio Lua 5.2 test suite.
> > +assert(string.format('%q', "\0") == [["\0"]])
> >  assert(string.format("\0%c\0%c%x\0", string.byte("?"), string.byte("b"), 140) ==
> >                "\0?\0b8c\0")
> >  assert(string.format('') == "")
> > -- 
> > 2.31.0
> > 
> 
> [1]: https://www.lua.org/bugs.html#5.1
> [2]: https://www.lua.org/bugs.html#5.1-4
> 
> -- 
> Best regards,
> IM

[1]: https://www.lua.org/manual/5.1/manual.html#pdf-string.format
[2]: https://www.lua.org/manual/5.2/manual.html#8.2

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 17/30] test: disable locale-depended tests for Lua suite
  2021-03-30 22:16   ` Igor Munkin via Tarantool-patches
@ 2021-04-01 19:12     ` Sergey Kaplun via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-01 19:12 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

Thanks for the review!

On 31.03.21, Igor Munkin wrote:
> Sergey,
> 
> Thanks for the patch! LGTM, except the nits below.
> 
> On 26.03.21, Sergey Kaplun wrote:
> > LuaJIT doesn't compare strings by `strcoll()`, like Lua 5.1 does.
> > So locale-depended tests in <strings.lua> are disabled.
> 
> Side note: unfortunately, this is not mentioned anywhere except the
> sources... Classic.
> 
> > 
> > Also, LuaJIT doesn't use `strtod()` depended on the locale for parsing,
> 
> Typo: s/depended/dependent/.

Fixed.

> 
> > unlike Lua does. See <src/lj_strscan.c> for more info.
> > Locale-depended tests in <literals.lua> are disabled.
> 
> Minor: Please, refer the docs[1] or the patch[2] changing the behaviour
> in the commit message.

Refered docs.

> 
> > 
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ---
> >  test/PUC-Lua-5.1-tests/literals.lua | 5 +++++
> >  test/PUC-Lua-5.1-tests/strings.lua  | 5 +++++
> >  2 files changed, 10 insertions(+)
> > 
> > diff --git a/test/PUC-Lua-5.1-tests/literals.lua b/test/PUC-Lua-5.1-tests/literals.lua
> > index 01d84d5..1b4f664 100644
> > --- a/test/PUC-Lua-5.1-tests/literals.lua
> > +++ b/test/PUC-Lua-5.1-tests/literals.lua
> > @@ -158,6 +158,10 @@ end
> >  
> >  
> >  -- testing decimal point locale
> > +-- LuaJIT: LuaJIT doesn't use `strtod()` depended on the locale,
> 
> Typo: s/depended/dependent/.

Fixed.

> 
> > +-- unlike Lua does. See <src/lj_strscan.c> for more info.
> > +-- Tests are disabled for LuaJIT.
> > +--[[
> >  if os.setlocale("pt_BR") or os.setlocale("ptb") then
> >    assert(tonumber("3,4") == 3.4 and tonumber"3.4" == nil)
> >    assert(assert(loadstring("return 3.4"))() == 3.4)
> 
> <snipped>
> 
> > -- 
> > 2.31.0
> > 
> 
> [1]: http://luajit.org/extensions.html#tonumber
> [2]: https://github.com/tarantool/luajit/commit/4c882fe
> 
> -- 
> Best regards,
> IM

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 18/30] test: replace math.mod to math.fmod for Lua tests
  2021-03-30 22:16   ` Igor Munkin via Tarantool-patches
@ 2021-04-01 19:36     ` Sergey Kaplun via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-01 19:36 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

Thanks for the review!

On 31.03.21, Igor Munkin wrote:
> Sergey,
> 
> Thanks for the patch! LGTM, except the nits below.
> 
> There is a typo in commit subject:
> s/replace math.mod to math.fmod/replace math.mod with math.fmod/.

Fixed.

> 
> On 26.03.21, Sergey Kaplun wrote:
> > In Lua 5.1 math.mod() is renamed to math.fmod() if build Lua 5.1 without
> 
> Typo: s/if build Lua 5.1/if Lua 5.1 is built/ or
>       s/if build Lua 5.1/if one build Lua 5.1/.

Fixed.

> 
> > flag `-DLUA_COMPAT_MOD`.
> 
> Typo: s/flag `-DLUA_COMPAT_MOD`/`-DLUA_COMPAT_MOD` flag/.

Fixed.

> 
> > LuaJIT has math.fmod() instead old-style math.mod() built-in.
> 
> Typo: s/instead old-style/instead of old-style/.

Fixed.

> 
> You can also mention the commit[1] where this is done.

Done.

> 
> > 
> > This patch replaces usage of math.mod with new-style math.fmod
> > in the following files:
> > * closure.lua
> > * constructs.lua
> > * math.lua
> > * nextvar.lua
> > 
> > Closes tarantool/tarantool#5711
> 
> As we discussed before: s/Closes/Resolves/.

Fixed.

> 
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ---
> >  test/PUC-Lua-5.1-tests/closure.lua    | 3 ++-
> >  test/PUC-Lua-5.1-tests/constructs.lua | 6 ++++--
> >  test/PUC-Lua-5.1-tests/math.lua       | 3 ++-
> >  test/PUC-Lua-5.1-tests/nextvar.lua    | 3 ++-
> >  4 files changed, 10 insertions(+), 5 deletions(-)
> 
> Typo: s/instead old-style/instead of old-style/g in all chunks.

Fixed.

> 
> > 
> 
> <snipped>
> 
> > -- 
> > 2.31.0
> > 
> 
> [1]: https://github.com/tarantool/luajit/commit/de5568e
> 
> -- 
> Best regards,
> IM

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 19/30] test: remove assert for string.gfind check
  2021-03-30 22:17   ` Igor Munkin via Tarantool-patches
@ 2021-04-02  7:05     ` Sergey Kaplun via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-02  7:05 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

Thanks for the review!

On 31.03.21, Igor Munkin wrote:
> Sergey,
> 
> Thanks for the patch! LGTM, except the single nit.
> 
> On 26.03.21, Sergey Kaplun wrote:
> > In Lua 5.1 function `string.gfind()` was renamed to `string.gmatch()`.
> > You can use it if Lua 5.1 is built with compile-time option
> > `-DLUA_COMPAT_GFIND`.
> > This built-in is removed from LuaJIT.
> 
> Please mention the patch[1] where this builtin is removed.

Done.

> 
> > 
> > This patch removes test checking that `string.gfind()` and
> > `string.gmatch() is the same function.
> > 
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ---
> >  test/PUC-Lua-5.1-tests/pm.lua | 1 -
> >  1 file changed, 1 deletion(-)
> > 
> 
> <snipped>
> 
> > -- 
> > 2.31.0
> > 
> 
> [1]: https://github.com/tarantool/luajit/commit/de5568e
> 
> -- 
> Best regards,
> IM

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 20/30] test: adapt PUC Lua test for args in vararg func
  2021-03-31  9:51   ` Igor Munkin via Tarantool-patches
@ 2021-04-02  7:21     ` Sergey Kaplun via Tarantool-patches
  2021-04-06 20:45       ` Igor Munkin via Tarantool-patches
  0 siblings, 1 reply; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-02  7:21 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

Thanks for the review!

On 31.03.21, Igor Munkin wrote:
> Sergey,
> 
> Thanks for the patch! I can't understand why this patch is separated
> from the previous two (10 and 11). Could you provide a rationale for
> this, please? Also consider the comments below.

Answered about difference with 10th here [1].
I'm totally OK to squash it with 11th.

> 
> On 26.03.21, Sergey Kaplun wrote:
> > Lua 5.1 interprets ... in the vararg functions like additional first
> 
> Typo: s/like additional/as an additional/.

Fixed.

> 
> > argument, unlike LuaJIT does. All extra arguments is set into `arg`
> 
> Typo: s/arguments is set/arguments are set/.

Fixed.

> 
> > variable.
> > 
> > Implicit `arg` parameter for old-style vararg functions was finally
> > removed in Lua 5.2. This patch adjust tests in vararg.lua considering
> 
> Minor: Did LuaJIT always respect such behaviour? If no, please mention
> the commit where it has been changed.

Yes, at least since LuaJIT-2.0.0-beta1, AFAICS.
| $ src/luajit -v -e 'local function f(...) print(arg) end f(1, 3, 4)'
| LuaJIT 2.0.0-beta1 -- Copyright (C) 2005-2009 Mike Pall. http://luajit.org/
| nil

> 
> > Lua 5.2 test suite taken from
> > https://www.lua.org/tests/lua-5.2.0-tests.tar.gz.
> > 
> > Closes tarantool/tarantool#5712
> 
> As we discussed before: s/Closes/Resolves/.

Fixed.

> 
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ---
> >  test/PUC-Lua-5.1-tests/vararg.lua | 16 ++++++++++++----
> >  1 file changed, 12 insertions(+), 4 deletions(-)
> > 
> > diff --git a/test/PUC-Lua-5.1-tests/vararg.lua b/test/PUC-Lua-5.1-tests/vararg.lua
> > index ae068fa..efb76c5 100644
> > --- a/test/PUC-Lua-5.1-tests/vararg.lua
> > +++ b/test/PUC-Lua-5.1-tests/vararg.lua
> > @@ -2,9 +2,13 @@ print('testing vararg')
> >  
> >  _G.arg = nil
> >  
> > +-- Lua 5.1 interprets ... in the vararg functions like additional
> 
> Typo: s/like additional/as an additional/.

Fixed.

> 
> > +-- first argument, unlike LuaJIT does. All extra arguments is set
> 
> Typo: s/arguments is set/arguments are set/.

Fixed.

> 
> > +-- into `arg` variable. This extension is from Lua 5.2.
> > +-- See also https://github.com/tarantool/tarantool/issues/5712.
> 
> Side note: What is the difference between #5712 and #5694? They look
> like duplicates to me, and so provide another rationale for squashing
> all three patches into a single one.

Answered about difference with 10th here [1]. Different tickets was
created to be able "to eat mamonth by parts" -- to fix later not all,
but single patch.
I'm totally OK to squash it with 11th.

> 
> > +-- LuaJIT: Test is adapted from PUC-Rio Lua 5.2 test suite.
> >  function f(a, ...)
> > -  assert(type(arg) == 'table')
> > -  assert(type(arg.n) == 'number')
> > +  local arg = {n = select('#', ...), ...}
> 
> Why did you drop the assertions above? They are trivial (as many of
> others in this suite), but still check that everything is fine (e.g.
> that <select> yields a number).

Just following Lua 5.2 test suite behaviour.
Side note: we do not test that select returns number here, and the
first assert is totally redundant.

> 
> >    for i=1,arg.n do assert(a[i]==arg[i]) end
> >    return arg.n
> >  end
> 
> <snipped>
> 
> > @@ -42,7 +48,9 @@ a = call(print, {'+'})
> >  assert(a == nil)
> >  
> >  local t = {1, 10}
> > -function t:f (...) return self[arg[1]]+arg.n end
> > +-- LuaJIT: Test chunk is adapted from PUC-Rio Lua 5.2 test suite.
> > +-- See the comment above.
> > +function t:f (...) local arg = {...}; return self[...]+#arg end
> 
> Why didn't you create the same structure as elsewhere above? Why did you
> change <self> indexing? AFAIU, after creating the *right* <arg> variable
> everything should work with no other changes.

Just following Lua 5.2 test suite behaviour. Your solution is good too.

> 
> >  assert(t:f(1,4) == 3 and t:f(2) == 11)
> >  print('+')
> >  
> > -- 
> > 2.31.0
> > 
> 
> -- 
> Best regards,
> IM

[1]: https://lists.tarantool.org/pipermail/tarantool-patches/2021-April/023220.html

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 21/30] test: disable test for getfenv in closure tailcall
  2021-03-31  9:51   ` Igor Munkin via Tarantool-patches
@ 2021-04-02  7:40     ` Sergey Kaplun via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-02  7:40 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

Thanks for the review!

On 31.03.21, Igor Munkin wrote:
> Sergey,
> 
> Thanks for the patch! LGTM, except the comments related to the wording.
> 
> On 26.03.21, Sergey Kaplun wrote:
> > LuaJIT doesn't take into account tail calls for call-level counting, so
> 
> Minor: This is a good example, when the passive voice makes the sense
> clearer. Consider the following:
> | Tail calls are not taken into account for call-level counting.
> 
> Otherwise it seems like LuaJIT doesn't take into account *tail calls for
> call-level counting* (i.e. tail calls that are not used for call-level
> counting are taken into). Or simply try to use another preposition.

Yes, see it. Thanks! Fixed.

> 
> > getfenv() behaviour is different from Lua 5.1 in tail calls.
> 
> Minor: You use both "tailcall" and "tail call" within this commit.
> Please choose one and use it everywhere.

Fixed.

> 
> > 
> > This patch disables test for the return result of tail call getfenv().
> 
> Typo: s/tail call getfenv()/getfenv() tail call/.

Fixed.

> 
> > Default value (equals 1) of getfenv() function's argument (function
> 
> Typo: s/equals 1/equals to 1/.

Fixed.

> 
> > level) is invalid for this tail call -- LuaJIT can't provide necessary
> > debug information for the frame.
> 
> Minor: I would explicitly mention, that there is no a separate frame for
> tail call. LuaJIT simply uses the existing one created for the caller.

Fixed.

> 
> > 
> > Relates to tarantool/tarantool#5713
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ---
> >  test/PUC-Lua-5.1-tests/closure.lua | 9 ++++++++-
> >  1 file changed, 8 insertions(+), 1 deletion(-)
> > 
> 
> <snipped>
> 
> > -- 
> > 2.31.0
> > 
> 
> -- 
> Best regards,
> IM

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 22/30] test: disable PUC Lua test for var names in error
  2021-03-31 19:23   ` Igor Munkin via Tarantool-patches
@ 2021-04-02  7:48     ` Sergey Kaplun via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-02  7:48 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

Thanks for the review!

On 31.03.21, Igor Munkin wrote:
> Sergey,
> 
> Thanks for the patch! LGTM, except the nits below.
> 
> On 26.03.21, Sergey Kaplun wrote:
> > LuaJIT includes variable name to the error report, when try to
> 
> Minor: "error message" is more correct than "error report" here.

Fixed.

> 
> > call non-function object without __call methamethod.
> 
> Typo: s/methamethod/metamethod/.

Fixed.

> 
> > Also, LuaJIT includes variable name to the error report, when try to
> 
> Typo: s/includes variable name/includes the variable name/.

Fixed.

> 
> > perform unacceptable arifmetic operation with the variable.
> > Lua 5.1 doesn't report variable name in these errors.
> > 
> > Test ckecked that variable name aren't reported are disabled by
> 
> Typo: s/Test checked/Tests checking/.
> Typo: s/name aren't reported/name isn't reported/.

Fixed.

> 
> > this patch.
> > 
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ---
> >  test/PUC-Lua-5.1-tests/errors.lua | 9 +++++++--
> >  1 file changed, 7 insertions(+), 2 deletions(-)
> > 
> > diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua
> > index e881211..cf24e40 100644
> > --- a/test/PUC-Lua-5.1-tests/errors.lua
> > +++ b/test/PUC-Lua-5.1-tests/errors.lua
> > @@ -72,8 +72,13 @@ checkmessage("b=1; local aaa='a'; x=aaa+b", "local 'aaa'")
> >  checkmessage("aaa={}; x=3/aaa", "global 'aaa'")
> >  checkmessage("aaa='2'; b=nil;x=aaa*b", "global 'b'")
> >  checkmessage("aaa={}; x=-aaa", "global 'aaa'")
> > -assert(not string.find(doit"aaa={}; x=(aaa or aaa)+(aaa and aaa)", "'aaa'"))
> > -assert(not string.find(doit"aaa={}; (aaa or aaa)()", "'aaa'"))
> > +-- LuaJIT: LuaJIT includes variable name to the error report.
> 
> Minor: "error message" fits better than "error report".

Fixed.

> 
> > +-- It looks like:
> > +-- "attempt to perform arithmetic on global 'aaa' (a table value)"
> > +-- Lua 5.1 doesn't report variable name here.
> 
> Typo: s/report variable name/report the variable name/.

Fixed.

> 
> > +-- Tests are disabled for LuaJIT.
> > +-- assert(not string.find(doit"aaa={}; x=(aaa or aaa)+(aaa and aaa)", "'aaa'"))
> > +-- assert(not string.find(doit"aaa={}; (aaa or aaa)()", "'aaa'"))
> >  
> >  checkmessage([[aaa=9
> >  repeat until 3==3
> > -- 
> > 2.31.0
> > 
> 
> -- 
> Best regards,
> IM

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 23/30] test: disable PUC Lua test for fast function name
  2021-03-31 19:23   ` Igor Munkin via Tarantool-patches
@ 2021-04-02  8:14     ` Sergey Kaplun via Tarantool-patches
  2021-04-06 21:37       ` Igor Munkin via Tarantool-patches
  0 siblings, 1 reply; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-02  8:14 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

Thanks for the review!

On 31.03.21, Igor Munkin wrote:
> Sergey,
> 
> Thanks for the patch! Please consider the comments below.
> 
> On 26.03.21, Sergey Kaplun wrote:
> > LuaJIT can't determine bytecode position for non Lua functions
> > (in particular for fast functions) and, therefore, detect built-in
> > function names for errors in tail calls.
> 
> Side note: here is the inconsistency in your usage of possessive nouns.

Fixed.

> 
> > 
> > This patch disables test that checks name of built-in functions
> 
> Typo: s/disables test/disables the test/.
> Typo: s/checks name/checks the name/.

Fixed.

> 
> > reported in error in tail call.
> > 
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ---
> >  test/PUC-Lua-5.1-tests/errors.lua | 10 +++++++---
> >  1 file changed, 7 insertions(+), 3 deletions(-)
> > 
> > diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua
> > index cf24e40..af776a7 100644
> > --- a/test/PUC-Lua-5.1-tests/errors.lua
> > +++ b/test/PUC-Lua-5.1-tests/errors.lua
> > @@ -105,9 +105,13 @@ while 1 do
> >    insert(prefix, a)
> >  end]], "global 'insert'")
> >  
> > -checkmessage([[  -- tail call
> > -  return math.sin("a")
> > -]], "'sin'")
> > +-- LuaJIT: Can't determine bytecode position for non Lua functions
> > +-- (in particular for fast functions) and, therefore, detect fast
> > +-- function names for errors in tail calls.
> 
> This is kinda gibberish. I've tried the following snippets and can't
> understand what do you mean by this comment.
> 
> | $ luajit -e 'function q(a) return math.sin(a) end q("a")'
> | luajit: (command line):1: bad argument #1 to 'q' (number expected, got string)
> | stack traceback:
> |         [C]: in function 'q'
> |         (command line):1: in main chunk
> |         [C]: at 0x5610e8497eb0
> | $ luajit -e 'loadstring("return math.sin([[a]])")()'
> | luajit: (command line):1: bad argument #1 to '?' (number expected, got string)
> | stack traceback:
> |         [builtin#43]: at 0x7fc0f807ad10
> |         (command line):1: in main chunk
> |         [C]: at 0x55c1e85c7eb0
> 
> I understand the first result. The second result surprised me, but I've
> never investigated how loadstring call works (it looks like specifics of
> VARG frame, but this is a wild guess). But neither of them fits your
> explanation. The root cause is the same: callee uses caller frame, since
> caller doesn't need it anymore. Could you please clarify yours?

This is not about `loadstring()` at all:

| luajit -e 'return math.sin"a"'
| luajit: bad argument #1 to '?' (number expected, got string)
| stack traceback:
|         [builtin#43]: at 0x7f7c2ca6dbe0
|         [C]: at 0x558b0cd4cec0

The guest frame is looked like the following (when the error thrown):
| 0x40001938            [    ] VALUE: string "number expected, got string" @ 0x40008380
| 0x40001930            [ B  ] VALUE: string "a" @ 0x40008250
| 0x40001928            [    ] FRAME: [CP] delta=3, fast function #44

When LuaJIT tries to detect function's name it determines bytecode
position first, via `debug_framepc()`. But it can't determine bytecode
position for non-Lua functions:

| if (!isluafunc(fn)) {  /* Cannot derive a PC for non-Lua functions. */
|   return NO_BCPOS;

> 
> > +-- The test is disabled for LuaJIT.
> > +-- checkmessage([[  -- tail call
> > +--   return math.sin("a")
> > +-- ]], "'sin'")
> >  
> >  checkmessage([[collectgarbage("nooption")]], "invalid option")
> >  
> > -- 
> > 2.31.0
> > 
> 
> -- 
> Best regards,
> IM

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 24/30] test: disable PUC Lua test for non-asci identifier
  2021-03-31 19:23   ` Igor Munkin via Tarantool-patches
@ 2021-04-02  8:20     ` Sergey Kaplun via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-02  8:20 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

Thanks for the review!

On 31.03.21, Igor Munkin wrote:
> Sergey,
> 
> Thanks for the patch! LGTM, except the nits below.
> 
> On 26.03.21, Sergey Kaplun wrote:
> > LuaJIT does not avoid to use non-alphanumeric symbols as identifiers,
> 
> Typo: s/avoid to use/forbid using/.

Fixed.

> 
> > unlike Lua does.
> > 
> > This patch disables test that expects an error during parsing variable
> 
> Typo: s/disables test/disables the test/.
> Typo: s/parsing variable/parsing the variable name/.

Fixed.

> 
> > contains octal \255 as the first char in a variable name.
> 
> Typo: s/contains/containing/.

Fixed.

> 
> > 
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ---
> >  test/PUC-Lua-5.1-tests/errors.lua | 6 +++++-
> >  1 file changed, 5 insertions(+), 1 deletion(-)
> > 
> > diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua
> > index af776a7..028224c 100644
> > --- a/test/PUC-Lua-5.1-tests/errors.lua
> > +++ b/test/PUC-Lua-5.1-tests/errors.lua
> > @@ -202,7 +202,11 @@ checksyntax("[[a]]", "", "[[a]]", 1)
> >  checksyntax("'aa'", "", "'aa'", 1)
> >  
> >  -- test 255 as first char in a chunk
> > -checksyntax("\255a = 1", "", "\255", 1)
> > +-- LuaJIT does not avoid to use non-alphanumeric symbols
> 
> Typo: s/avoid to use/forbid using/.

Fixed.

> 
> > +-- as identifiers, unlike Lua does.
> > +-- For more details see <src/lj_char.c> and <src/lj_lex.c>.
> > +-- LuaJIT: Test is disabled for LuaJIT.
> > +-- checksyntax("\255a = 1", "", "\255", 1)
> >  
> >  doit('I = loadstring("a=9+"); a=3')
> >  assert(a==3 and I == nil)
> > -- 
> > 2.31.0
> > 
> 
> -- 
> Best regards,
> IM

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 25/30] test: disable PUC Lua error test for syntax level
  2021-03-31 19:24   ` Igor Munkin via Tarantool-patches
@ 2021-04-02  8:30     ` Sergey Kaplun via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-02  8:30 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

Thanks for the review.

On 31.03.21, Igor Munkin wrote:
> Sergey,
> 
> Thanks for the patch! LGTM, except the nits below.
> 
> On 26.03.21, Sergey Kaplun wrote:
> > When LuaJIT is compiled with LUAJIT_ENABLE_GC64, LJ_MAX_SLOTS limit is
> > reached and error LJ_ERR_XSLOTS ("function or expression too complex")
> > is raised earlier, than LJ_MAX_XLEVEL limit is reached and error
> > LJ_ERR_XLEVELS ("chunk has too many syntax levels") is raised.
> > 
> > This patch disabled test expected the LJ_ERR_XLEVEL error, but
> 
> Typo: s/disabled test/disables the test/.

Fixed.

> 
> > failing with the LJ_ERR_XSLOTS error.
> > 
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ---
> >  test/PUC-Lua-5.1-tests/errors.lua | 8 +++++++-
> >  1 file changed, 7 insertions(+), 1 deletion(-)
> > 
> > diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua
> > index 028224c..328976e 100644
> > --- a/test/PUC-Lua-5.1-tests/errors.lua
> > +++ b/test/PUC-Lua-5.1-tests/errors.lua
> > @@ -228,7 +228,13 @@ local function testrep (init, rep)
> >  end
> >  testrep("a=", "{")
> >  testrep("a=", "(")
> > -testrep("", "a(")
> > +-- LuaJIT: When compiled with LUAJIT_ENABLE_GC64, LJ_MAX_SLOTS
> > +-- limit is reached and error LJ_ERR_XSLOTS ("function or
> > +-- expression too complex") is raised earlier, than LJ_MAX_XLEVEL
> > +-- limit is reached and error LJ_ERR_XLEVELS ("chunk has too many
> > +-- syntax levels") is raised.
> 
> Side note: It would be nice if you also mention the root cause. AFAIU,
> LuaJIT frontend checks "virtual" stack size at the translation time,
> right? Therefore, when GC64 support is enabled every call needs twice
> more slots on the coroutine stack (since LJ_FR2 is also set).

Added to the comment and the commit message.

> 
> > +-- Test is disabled for LuaJIT.
> > +-- testrep("", "a(")
> >  testrep("", "do ")
> >  testrep("", "while a do ")
> >  testrep("", "if a then else ")
> > -- 
> > 2.31.0
> > 
> 
> -- 
> Best regards,
> IM

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 27/30] test: disable PUC Lua test for checking arg layout
  2021-03-31 19:24   ` Igor Munkin via Tarantool-patches
@ 2021-04-02  8:35     ` Sergey Kaplun via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-02  8:35 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

Thanks for the review!

On 31.03.21, Igor Munkin wrote:
> Sergey,
> 
> Thanks for the patch! LGTM, except the single nit. I see you added FIXME
> here, so we can uncomment the test, if we separate LuaJIT regular
> testing from Tarantool CI sometime...

Yes, or even will make their behaviour the same.

> 
> On 26.03.21, Sergey Kaplun wrote:
> > Unlike LuaJIT, Tarantool doesn't store the given CLI flags in `arg`,
> > so the table has the following layout:
> > * arg[-1] -- the binary name
> > * arg[0]  -- the script name
> > * arg[N]  -- the script argument for all N in [1, #arg]
> > 
> > This patch disables test checking `arg` layout by negative indexes.
> 
> Typo: s/disables test/disables the test/.

Fixed.

> 
> > 
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> 
> <snipped>
> 
> > -- 
> > 2.31.0
> > 
> 
> -- 
> Best regards,
> IM

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 28/30] test: disable PUC Lua test checking -h option
  2021-03-31 19:24   ` Igor Munkin via Tarantool-patches
@ 2021-04-02  8:39     ` Sergey Kaplun via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-02  8:39 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

Thanks for the review!

On 31.03.21, Igor Munkin wrote:
> Sergey,
> 
> Thanks for the patch! LGTM, except the nits below. I see you added FIXME
> here, so we can uncomment the test, if we separate LuaJIT regular
> testing from Tarantool CI sometime...

Yep, or will change Tarantool's behaviour.

> 
> On 26.03.21, Sergey Kaplun wrote:
> > Tarantool returns zero status at exit with -h option, unlike Lua or
> > LuaJIT does.
> > 
> > This patch disables test checking returning status, when binary
> 
> Typo: s/disables test/disables the test/.
> Typo: s/checking returning status/checking the exit code/.

Fixed.

> 
> > runs with -h option.
> > 
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ---
> 
> <snipped>
> 
> > -- 
> > 2.31.0
> > 
> 
> -- 
> Best regards,
> IM

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 29/30] test: disable PUC Lua hanging GC test
  2021-03-31 19:24   ` Igor Munkin via Tarantool-patches
@ 2021-04-02  8:45     ` Sergey Kaplun via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-02  8:45 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

Thanks for the review!

On 31.03.21, Igor Munkin wrote:
> Sergey,
> 
> Thanks for the patch! LGTM, except the nits below.
> 
> On 26.03.21, Sergey Kaplun wrote:
> > Tarantool has too many objects at start. `gcinfo()` result is always
> > greater than 1000 expected by the test. It leads to infinite loop in the
> > test.
> > 
> > This patch disables GC test leading to hanging for Tarantool binary.
> 
> Minor: I propose the following rewording:
> | This patch disables GC test leading to Tarantool binary hang.

Like it! Applied.

> 
> > 
> > Part of tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> > ---
> >  test/PUC-Lua-5.1-tests/gc.lua | 9 ++++++---
> >  1 file changed, 6 insertions(+), 3 deletions(-)
> > 
> > diff --git a/test/PUC-Lua-5.1-tests/gc.lua b/test/PUC-Lua-5.1-tests/gc.lua
> > index 072bbe9..7f9880f 100644
> > --- a/test/PUC-Lua-5.1-tests/gc.lua
> > +++ b/test/PUC-Lua-5.1-tests/gc.lua
> > @@ -133,9 +133,12 @@ do
> >      local a = {}
> >    until gcinfo() > 1000
> >    collectgarbage"restart"
> > -  repeat
> > -    local a = {}
> > -  until gcinfo() < 1000
> > +  -- Tarantool has too many objects at start. `gcinfo()` result
> 
> I dare to guess that you're talking about *alive* objects here. Please
> mention this explicitly, if I'm right.

Added here and in the commit message.

> 
> > +  -- is always greater than 1000.
> > +  -- LuaJIT: The test is disabled for Tarantool binary.
> > +  -- repeat
> > +  --   local a = {}
> > +  -- until gcinfo() < 1000
> >  end
> >  
> >  lim = 15
> > -- 
> > 2.31.0
> > 
> 
> -- 
> Best regards,
> IM

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 30/30] test: disable too depth recursive PUC Lua test
  2021-03-31 19:24   ` Igor Munkin via Tarantool-patches
@ 2021-04-02  8:47     ` Sergey Kaplun via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-02  8:47 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

Thanks for the review!

On 31.03.21, Igor Munkin wrote:
> Sergey,
> 
> Thanks for the patch! LGTM, except the nits below.
> 
> On 26.03.21, Sergey Kaplun wrote:
> > The first Tarantool's fiber has only 512Kb of stack.
> > It is not enough for depth recursive call in the test for
> 
> Typo: s/depth/deep/.

Fixed.

> 
> > `string.gsub()`.
> > 
> > This patch disables test leads to Tarantool crash.
> 
> Typo: s/disables test/disables the test/.

Fixed.

> 
> > 
> > Relates to tarantool/tarantool#5782
> > Resolves tarantool/tarantool#5845
> > Part of tarantool/tarantool#4473
> 
> <snipped>
> 
> > -- 
> > 2.31.0
> > 
> 
> -- 
> Best regards,
> IM

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 05/30] test: adapt arg availability test from Lua suite
  2021-04-01  9:37     ` Sergey Kaplun via Tarantool-patches
@ 2021-04-06 15:24       ` Igor Munkin via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-04-06 15:24 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

On 01.04.21, Sergey Kaplun wrote:
> Igor,
> 

<snipped>

> > > -RUN("lua -l%s - < %s", prog, otherprog)
> > > +RUN('env LUA_PATH="?;;" lua -l%s - < %s', prog, otherprog)
> > 
> > Why LUA_PATH is tweaked here?
> 
> Looks like Roberto avoids to load some files with the same name
> that can be loaded by the old `LUA_PATH`. I preferred to take it intact
> from the Lua 5.3 test suite (even comment about `arg` availability).

OK, then LGTM.

> 

<snipped>

> 
> -- 
> Best regards,
> Sergey Kaplun

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 03/30] test: adapt Lua 5.1 suite for out-of-source build
  2021-04-01  8:40     ` Sergey Kaplun via Tarantool-patches
@ 2021-04-06 16:56       ` Igor Munkin via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-04-06 16:56 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

On 01.04.21, Sergey Kaplun wrote:
> Igor,
> 
> Thanks for the review!
> 
> On 01.04.21, Igor Munkin wrote:
> > Sergey,
> > 
> > Thanks for the patch! Honestly, I'm not fond of the solution you
> > implemented, though it allows to make as little changes as possible.
> > I propose to implement something similar to the solution you've made
> > within lua-Harness series:
> > * You need two <dofile> functions: one for launching source files for
> >   additional checks and another one for running temporary Lua chunks.
> > * You also need two <loadstring> functions for the same reason.
> > 
> > Mind the fact <dofile> is implemented via <loadstring>, so basically,
> > there might be no so much changes made for <dofile>. Thoughts?
> 
> I prefer to use one function, and two wrappers around it.
> For example, let it be `absolute_dofile()` and `cwd_dofile()`.

Why do you need the second one?

> 
> But honestly, it is not the single one problem of this suite (no test
> isolation, global variables, huge excess output, hardcoded limit
> values, etc).

Yes, the whole suite is a single problem, but you've already fixed
something. This patch can fix the base problem we've resolved while
adopting lua-Harness. Why do you want to omit it here?

> It looks like we need to refactor this suite later (plus adapt test
> for LuaJIT extensions from Lua 5.2+). I propose to do all this work
> via that refactoring, not now. Otherwise, it looks like a patch, which
> will still need to be refactored later.

It's not about refactoring, it's about the general approach. François
proposed an elegant solution with <_dofile> that can be overloaded in
luajit-test-init.lua (and we have to introduce one into LuaJIT then), so
I see no reason to postpone such simple change. Of course this issue can
be done within #5790 (or not, again, since it relates to another suite),
so if you don't want to do this, let's close the eyes and leave such
unsighty workaround.

Consider you have my LGTM here if nobody else is bothered. I'll just
glance the patch once more.

> 
> Thoughts?
> 
> > 
> > -- 
> > Best regards,
> > IM
> 
> -- 
> Best regards,
> Sergey Kaplun

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 09/30] test: disable Lua suite tests for line hook
  2021-04-01 10:06     ` Sergey Kaplun via Tarantool-patches
@ 2021-04-06 19:45       ` Igor Munkin via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-04-06 19:45 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the fixes! LGTM now.

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 11/30] test: adapt getlocal PUC test for vararg func
  2021-04-01 11:37     ` Sergey Kaplun via Tarantool-patches
@ 2021-04-06 20:09       ` Igor Munkin via Tarantool-patches
  2021-04-06 20:40         ` Igor Munkin via Tarantool-patches
  0 siblings, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-04-06 20:09 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

On 01.04.21, Sergey Kaplun wrote:
> Igor,
> 
> Thanks for the review!
> 
> On 31.03.21, Igor Munkin wrote:
> > Sergey,
> > 
> > Thanks for the patch! I can't understand why this patch is separated
> > from the previous one. Could you provide a rationale for this, please?
> > BTW as we discussed before: s/Closes/Resolves/, considering your changes
> > on the branch. Also consider the comments below.
> 
> The root reason of the previous patch is about counting of local
> variable in caller. Here this local variable is used for counting
> arguments amount.

OK, now I get it. Let's then squash 11 and 16 patches, since they solves
the one problem and leave 10 as is, since it fixes a different one. BTW,
I'm even fine if you leave everything as is. So, here is my LGTM and
feel free to adjust these patches on your own.

> 

<snipped>

> 
> -- 
> Best regards,
> Sergey Kaplun

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 11/30] test: adapt getlocal PUC test for vararg func
  2021-04-06 20:09       ` Igor Munkin via Tarantool-patches
@ 2021-04-06 20:40         ` Igor Munkin via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-04-06 20:40 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

On 06.04.21, Igor Munkin wrote:
> Sergey,
> 
> On 01.04.21, Sergey Kaplun wrote:
> > Igor,
> > 
> > Thanks for the review!
> > 
> > On 31.03.21, Igor Munkin wrote:
> > > Sergey,
> > > 
> > > Thanks for the patch! I can't understand why this patch is separated
> > > from the previous one. Could you provide a rationale for this, please?
> > > BTW as we discussed before: s/Closes/Resolves/, considering your changes
> > > on the branch. Also consider the comments below.
> > 
> > The root reason of the previous patch is about counting of local
> > variable in caller. Here this local variable is used for counting
> > arguments amount.
> 
> OK, now I get it. Let's then squash 11 and 16 patches, since they solves

It's a typo: s/16/20/ while reading please.

> the one problem and leave 10 as is, since it fixes a different one. BTW,
> I'm even fine if you leave everything as is. So, here is my LGTM and
> feel free to adjust these patches on your own.
> 
> > 
> 
> <snipped>
> 
> > 
> > -- 
> > Best regards,
> > Sergey Kaplun
> 
> -- 
> Best regards,
> IM

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 20/30] test: adapt PUC Lua test for args in vararg func
  2021-04-02  7:21     ` Sergey Kaplun via Tarantool-patches
@ 2021-04-06 20:45       ` Igor Munkin via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-04-06 20:45 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

Thanks for the changes and clarification! LGTM now.

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 16/30] test: adapt PUC Lua test for %q in fmt for LuaJIT
  2021-04-01 12:33     ` Sergey Kaplun via Tarantool-patches
@ 2021-04-06 21:37       ` Igor Munkin via Tarantool-patches
  2021-04-07 15:50         ` Sergey Kaplun via Tarantool-patches
  0 siblings, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-04-06 21:37 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

On 01.04.21, Sergey Kaplun wrote:
> Igor,
> 
> Thanks for the review!
> 
> On 31.03.21, Igor Munkin wrote:
> > Sergey,
> > 

<snipped>

> > 
> > > string.format(): %q reversible.
> > > See also https://luajit.org/extensions.html#lua52.
> > > 
> > > In Lua 5.1 string.format() does not accept string values containing
> > > embedded zeros, except as arguments to the '%q' option.
> > > In Lua 5.2 '\0' is not handled differently from other
> > > control chars in string.format('%q', ...).
> > > See commit 7cc981c14067d4b0e774a6bfb0acfc2f5c911f0d
> > > (string.format("%q", str) is now fully reversible
> > > (from Lua 5.2).).
> > 
> > Well, I honestly don't understand what is changed in *semantics*. I've
> > tried the following command with Lua 5.2, Lua 5.1 and LuaJIT 2.0.5 as an
> > interpreter being tested
> > | <interp> -e 'print(string.format("%q", "\0"))'
> > 
> > I understand the semantics of "%q", but was it just a bug in Lua 5.1?
> 
> A bug with the test for it???

Well, I can remind you the bug with <tonumber> we fixed the last year.
There might be no test for it though, but all in all it has not been
fixed in Lua 5.1.

> 
> > What does "fully reversible" mean in this context?

This question is left unaddressed.

> > 
> > I understand only the fact the behaviour differs and you reimplemented
> > the test assertion according to Lua 5.2 testing suite. That's all.
> > 
> > I found not a single word regarding this issue in Lua bugs[1] page,
> > except invalid handling of \r[2]. Is there any issue/page with a more
> 
> It looks unrelated to these changes.
> 
> > verbose explanation what has been changed in 7cc981c?
> 
> I just read these lines in Lua 5.1 reference manual :):
> | This function does not accept string values containing embedded
> | zeros, except as arguments to the q option.

So what? This means literally nothing to me... BTW, I can pass such
string to the function and it can yield any bullshit the developer
wanted to. That's why we decided to comment such places in a clear and
verbose way, didn't we?

> 
> As for me, it is just new behaviour of Lua 5.2 -- patterns now accept
> '\0' as a reqular character (see
> 4541243355a299a9b75042d207feb87295872c3a (patterns now accept '\0' as a
> regular character) from Lua repository). So, according to commit
> 658ea8752b979102627e2fede7b7ddfbb67ba6c9 (no need to handle '\0'
> differently from other control chars in format '%q')) from Lua
> repository, this behaviour is excess.
> 
> Also, it is mentioned here [2].

I see nothing regarding this change there.

> 

<snipped>

> > 
> > [1]: https://www.lua.org/bugs.html#5.1
> > [2]: https://www.lua.org/bugs.html#5.1-4
> > 
> > -- 
> > Best regards,
> > IM
> 
> [1]: https://www.lua.org/manual/5.1/manual.html#pdf-string.format
> [2]: https://www.lua.org/manual/5.2/manual.html#8.2
> 
> -- 
> Best regards,
> Sergey Kaplun

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 23/30] test: disable PUC Lua test for fast function name
  2021-04-02  8:14     ` Sergey Kaplun via Tarantool-patches
@ 2021-04-06 21:37       ` Igor Munkin via Tarantool-patches
  2021-04-07 16:06         ` Sergey Kaplun via Tarantool-patches
  0 siblings, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-04-06 21:37 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

On 02.04.21, Sergey Kaplun wrote:
> Igor,
> 
> Thanks for the review!
> 
> On 31.03.21, Igor Munkin wrote:
> > Sergey,
> > 
> > Thanks for the patch! Please consider the comments below.
> > 
> > On 26.03.21, Sergey Kaplun wrote:
> > > LuaJIT can't determine bytecode position for non Lua functions
> > > (in particular for fast functions) and, therefore, detect built-in
> > > function names for errors in tail calls.
> > 
> > Side note: here is the inconsistency in your usage of possessive nouns.
> 
> Fixed.

No, it's not, but this doesn't bother me anymore.

> 

<snipped>

> > > diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua
> > > index cf24e40..af776a7 100644
> > > --- a/test/PUC-Lua-5.1-tests/errors.lua
> > > +++ b/test/PUC-Lua-5.1-tests/errors.lua
> > > @@ -105,9 +105,13 @@ while 1 do
> > >    insert(prefix, a)
> > >  end]], "global 'insert'")
> > >  
> > > -checkmessage([[  -- tail call
> > > -  return math.sin("a")
> > > -]], "'sin'")
> > > +-- LuaJIT: Can't determine bytecode position for non Lua functions
> > > +-- (in particular for fast functions) and, therefore, detect fast
> > > +-- function names for errors in tail calls.
> > 
> > This is kinda gibberish. I've tried the following snippets and can't
> > understand what do you mean by this comment.
> > 
> > | $ luajit -e 'function q(a) return math.sin(a) end q("a")'
> > | luajit: (command line):1: bad argument #1 to 'q' (number expected, got string)
> > | stack traceback:
> > |         [C]: in function 'q'
> > |         (command line):1: in main chunk
> > |         [C]: at 0x5610e8497eb0
> > | $ luajit -e 'loadstring("return math.sin([[a]])")()'
> > | luajit: (command line):1: bad argument #1 to '?' (number expected, got string)
> > | stack traceback:
> > |         [builtin#43]: at 0x7fc0f807ad10
> > |         (command line):1: in main chunk
> > |         [C]: at 0x55c1e85c7eb0
> > 
> > I understand the first result. The second result surprised me, but I've
> > never investigated how loadstring call works (it looks like specifics of
> > VARG frame, but this is a wild guess). But neither of them fits your
> > explanation. The root cause is the same: callee uses caller frame, since
> > caller doesn't need it anymore. Could you please clarify yours?
> 
> This is not about `loadstring()` at all:
> 
> | luajit -e 'return math.sin"a"'
> | luajit: bad argument #1 to '?' (number expected, got string)
> | stack traceback:
> |         [builtin#43]: at 0x7f7c2ca6dbe0
> |         [C]: at 0x558b0cd4cec0
> 
> The guest frame is looked like the following (when the error thrown):
> | 0x40001938            [    ] VALUE: string "number expected, got string" @ 0x40008380
> | 0x40001930            [ B  ] VALUE: string "a" @ 0x40008250
> | 0x40001928            [    ] FRAME: [CP] delta=3, fast function #44
> 
> When LuaJIT tries to detect function's name it determines bytecode
> position first, via `debug_framepc()`. But it can't determine bytecode
> position for non-Lua functions:

What? Both luajit-gdb.py and LuaJIT itself reports the fast function ID
and this is its name.

> 
> | if (!isluafunc(fn)) {  /* Cannot derive a PC for non-Lua functions. */
> |   return NO_BCPOS;
> 
> > 
> > > +-- The test is disabled for LuaJIT.
> > > +-- checkmessage([[  -- tail call
> > > +--   return math.sin("a")
> > > +-- ]], "'sin'")
> > >  
> > >  checkmessage([[collectgarbage("nooption")]], "invalid option")
> > >  
> > > -- 
> > > 2.31.0
> > > 
> > 
> > -- 
> > Best regards,
> > IM
> 
> -- 
> Best regards,
> Sergey Kaplun

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 16/30] test: adapt PUC Lua test for %q in fmt for LuaJIT
  2021-04-06 21:37       ` Igor Munkin via Tarantool-patches
@ 2021-04-07 15:50         ` Sergey Kaplun via Tarantool-patches
  2021-04-07 16:31           ` Igor Munkin via Tarantool-patches
  0 siblings, 1 reply; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-07 15:50 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

On 07.04.21, Igor Munkin wrote:
> Sergey,
> 
> On 01.04.21, Sergey Kaplun wrote:
> > Igor,
> > 
> > Thanks for the review!
> > 
> > On 31.03.21, Igor Munkin wrote:
> > > Sergey,
> > > 
> 
> <snipped>
> 
> > > 
> > > > string.format(): %q reversible.
> > > > See also https://luajit.org/extensions.html#lua52.
> > > > 
> > > > In Lua 5.1 string.format() does not accept string values containing
> > > > embedded zeros, except as arguments to the '%q' option.
> > > > In Lua 5.2 '\0' is not handled differently from other
> > > > control chars in string.format('%q', ...).
> > > > See commit 7cc981c14067d4b0e774a6bfb0acfc2f5c911f0d
> > > > (string.format("%q", str) is now fully reversible
> > > > (from Lua 5.2).).
> > > 
> > > Well, I honestly don't understand what is changed in *semantics*. I've
> > > tried the following command with Lua 5.2, Lua 5.1 and LuaJIT 2.0.5 as an
> > > interpreter being tested
> > > | <interp> -e 'print(string.format("%q", "\0"))'
> > > 
> > > I understand the semantics of "%q", but was it just a bug in Lua 5.1?
> > 
> > A bug with the test for it???
> 
> Well, I can remind you the bug with <tonumber> we fixed the last year.
> There might be no test for it though, but all in all it has not been
> fixed in Lua 5.1.

I mean that this behaviour is verificated by the test. When behaviour is
changed the test is changed too.

> 
> > 
> > > What does "fully reversible" mean in this context?
> 
> This question is left unaddressed.

I don't know what does Mike mean by these.

> 
> > > 
> > > I understand only the fact the behaviour differs and you reimplemented
> > > the test assertion according to Lua 5.2 testing suite. That's all.
> > > 
> > > I found not a single word regarding this issue in Lua bugs[1] page,
> > > except invalid handling of \r[2]. Is there any issue/page with a more
> > 
> > It looks unrelated to these changes.
> > 
> > > verbose explanation what has been changed in 7cc981c?
> > 
> > I just read these lines in Lua 5.1 reference manual :):
> > | This function does not accept string values containing embedded
> > | zeros, except as arguments to the q option.
> 
> So what? This means literally nothing to me... BTW, I can pass such
> string to the function and it can yield any bullshit the developer
> wanted to. That's why we decided to comment such places in a clear and
> verbose way, didn't we?

Don't get you point here. AFAIU it means that `%q` is the only one
option that can contain embeded zeros, so it handles it in the special
way.

> 
> > 
> > As for me, it is just new behaviour of Lua 5.2 -- patterns now accept
> > '\0' as a reqular character (see
> > 4541243355a299a9b75042d207feb87295872c3a (patterns now accept '\0' as a
> > regular character) from Lua repository). So, according to commit
> > 658ea8752b979102627e2fede7b7ddfbb67ba6c9 (no need to handle '\0'
> > differently from other control chars in format '%q')) from Lua
> > repository, this behaviour is excess.
> > 
> > Also, it is mentioned here [2].
> 
> I see nothing regarding this change there.

I am talking about this part:

| Character class %z in patterns is deprecated, as now patterns may
| contain '\0' as a regular character.

> 
> > 
> 
> <snipped>
> 
> > > 
> > > [1]: https://www.lua.org/bugs.html#5.1
> > > [2]: https://www.lua.org/bugs.html#5.1-4
> > > 
> > > -- 
> > > Best regards,
> > > IM
> > 
> > [1]: https://www.lua.org/manual/5.1/manual.html#pdf-string.format
> > [2]: https://www.lua.org/manual/5.2/manual.html#8.2
> > 
> > -- 
> > Best regards,
> > Sergey Kaplun
> 
> -- 
> Best regards,
> IM

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 23/30] test: disable PUC Lua test for fast function name
  2021-04-06 21:37       ` Igor Munkin via Tarantool-patches
@ 2021-04-07 16:06         ` Sergey Kaplun via Tarantool-patches
  2021-04-07 16:11           ` Igor Munkin via Tarantool-patches
  0 siblings, 1 reply; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-07 16:06 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

On 07.04.21, Igor Munkin wrote:
> Sergey,
> 
> On 02.04.21, Sergey Kaplun wrote:
> > Igor,
> > 
> > Thanks for the review!
> > 
> > On 31.03.21, Igor Munkin wrote:
> > > Sergey,
> > > 
> > > Thanks for the patch! Please consider the comments below.
> > > 
> > > On 26.03.21, Sergey Kaplun wrote:
> > > > LuaJIT can't determine bytecode position for non Lua functions
> > > > (in particular for fast functions) and, therefore, detect built-in
> > > > function names for errors in tail calls.
> > > 
> > > Side note: here is the inconsistency in your usage of possessive nouns.
> > 
> > Fixed.
> 
> No, it's not, but this doesn't bother me anymore.

Why? Please expalin where I'm wrong.

> 
> > 
> 
> <snipped>
> 
> > > > diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua
> > > > index cf24e40..af776a7 100644
> > > > --- a/test/PUC-Lua-5.1-tests/errors.lua
> > > > +++ b/test/PUC-Lua-5.1-tests/errors.lua
> > > > @@ -105,9 +105,13 @@ while 1 do
> > > >    insert(prefix, a)
> > > >  end]], "global 'insert'")
> > > >  
> > > > -checkmessage([[  -- tail call
> > > > -  return math.sin("a")
> > > > -]], "'sin'")
> > > > +-- LuaJIT: Can't determine bytecode position for non Lua functions
> > > > +-- (in particular for fast functions) and, therefore, detect fast
> > > > +-- function names for errors in tail calls.
> > > 
> > > This is kinda gibberish. I've tried the following snippets and can't
> > > understand what do you mean by this comment.
> > > 
> > > | $ luajit -e 'function q(a) return math.sin(a) end q("a")'
> > > | luajit: (command line):1: bad argument #1 to 'q' (number expected, got string)
> > > | stack traceback:
> > > |         [C]: in function 'q'
> > > |         (command line):1: in main chunk
> > > |         [C]: at 0x5610e8497eb0
> > > | $ luajit -e 'loadstring("return math.sin([[a]])")()'
> > > | luajit: (command line):1: bad argument #1 to '?' (number expected, got string)
> > > | stack traceback:
> > > |         [builtin#43]: at 0x7fc0f807ad10
> > > |         (command line):1: in main chunk
> > > |         [C]: at 0x55c1e85c7eb0
> > > 
> > > I understand the first result. The second result surprised me, but I've
> > > never investigated how loadstring call works (it looks like specifics of
> > > VARG frame, but this is a wild guess). But neither of them fits your
> > > explanation. The root cause is the same: callee uses caller frame, since
> > > caller doesn't need it anymore. Could you please clarify yours?
> > 
> > This is not about `loadstring()` at all:
> > 
> > | luajit -e 'return math.sin"a"'
> > | luajit: bad argument #1 to '?' (number expected, got string)
> > | stack traceback:
> > |         [builtin#43]: at 0x7f7c2ca6dbe0
> > |         [C]: at 0x558b0cd4cec0
> > 
> > The guest frame is looked like the following (when the error thrown):
> > | 0x40001938            [    ] VALUE: string "number expected, got string" @ 0x40008380
> > | 0x40001930            [ B  ] VALUE: string "a" @ 0x40008250
> > | 0x40001928            [    ] FRAME: [CP] delta=3, fast function #44
> > 
> > When LuaJIT tries to detect function's name it determines bytecode
> > position first, via `debug_framepc()`. But it can't determine bytecode
> > position for non-Lua functions:
> 
> What? Both luajit-gdb.py and LuaJIT itself reports the fast function ID
> and this is its name.

Yes, what is your question about?

> 
> > 
> > | if (!isluafunc(fn)) {  /* Cannot derive a PC for non-Lua functions. */
> > |   return NO_BCPOS;
> > 
> > > 
> > > > +-- The test is disabled for LuaJIT.
> > > > +-- checkmessage([[  -- tail call
> > > > +--   return math.sin("a")
> > > > +-- ]], "'sin'")
> > > >  
> > > >  checkmessage([[collectgarbage("nooption")]], "invalid option")
> > > >  
> > > > -- 
> > > > 2.31.0
> > > > 
> > > 
> > > -- 
> > > Best regards,
> > > IM
> > 
> > -- 
> > Best regards,
> > Sergey Kaplun
> 
> -- 
> Best regards,
> IM

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 23/30] test: disable PUC Lua test for fast function name
  2021-04-07 16:06         ` Sergey Kaplun via Tarantool-patches
@ 2021-04-07 16:11           ` Igor Munkin via Tarantool-patches
  2021-04-07 19:57             ` Sergey Kaplun via Tarantool-patches
  0 siblings, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-04-07 16:11 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

On 07.04.21, Sergey Kaplun wrote:
> Igor,
> 

<snipped>

> > > > > diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua
> > > > > index cf24e40..af776a7 100644
> > > > > --- a/test/PUC-Lua-5.1-tests/errors.lua
> > > > > +++ b/test/PUC-Lua-5.1-tests/errors.lua
> > > > > @@ -105,9 +105,13 @@ while 1 do
> > > > >    insert(prefix, a)
> > > > >  end]], "global 'insert'")
> > > > >  
> > > > > -checkmessage([[  -- tail call
> > > > > -  return math.sin("a")
> > > > > -]], "'sin'")
> > > > > +-- LuaJIT: Can't determine bytecode position for non Lua functions
> > > > > +-- (in particular for fast functions) and, therefore, detect fast
> > > > > +-- function names for errors in tail calls.
> > > > 
> > > > This is kinda gibberish. I've tried the following snippets and can't
> > > > understand what do you mean by this comment.
> > > > 
> > > > | $ luajit -e 'function q(a) return math.sin(a) end q("a")'
> > > > | luajit: (command line):1: bad argument #1 to 'q' (number expected, got string)
> > > > | stack traceback:
> > > > |         [C]: in function 'q'
> > > > |         (command line):1: in main chunk
> > > > |         [C]: at 0x5610e8497eb0
> > > > | $ luajit -e 'loadstring("return math.sin([[a]])")()'
> > > > | luajit: (command line):1: bad argument #1 to '?' (number expected, got string)
> > > > | stack traceback:
> > > > |         [builtin#43]: at 0x7fc0f807ad10
> > > > |         (command line):1: in main chunk
> > > > |         [C]: at 0x55c1e85c7eb0
> > > > 
> > > > I understand the first result. The second result surprised me, but I've
> > > > never investigated how loadstring call works (it looks like specifics of
> > > > VARG frame, but this is a wild guess). But neither of them fits your
> > > > explanation. The root cause is the same: callee uses caller frame, since
> > > > caller doesn't need it anymore. Could you please clarify yours?
> > > 
> > > This is not about `loadstring()` at all:
> > > 
> > > | luajit -e 'return math.sin"a"'
> > > | luajit: bad argument #1 to '?' (number expected, got string)
> > > | stack traceback:
> > > |         [builtin#43]: at 0x7f7c2ca6dbe0
> > > |         [C]: at 0x558b0cd4cec0
> > > 
> > > The guest frame is looked like the following (when the error thrown):
> > > | 0x40001938            [    ] VALUE: string "number expected, got string" @ 0x40008380
> > > | 0x40001930            [ B  ] VALUE: string "a" @ 0x40008250
> > > | 0x40001928            [    ] FRAME: [CP] delta=3, fast function #44
> > > 
> > > When LuaJIT tries to detect function's name it determines bytecode
> > > position first, via `debug_framepc()`. But it can't determine bytecode
> > > position for non-Lua functions:
> > 
> > What? Both luajit-gdb.py and LuaJIT itself reports the fast function ID
> > and this is its name.
> 
> Yes, what is your question about?

Then what's the problem with name resolving?

> 
> > 
> > > 
> > > | if (!isluafunc(fn)) {  /* Cannot derive a PC for non-Lua functions. */
> > > |   return NO_BCPOS;
> > > 
> > > > 
> > > > > +-- The test is disabled for LuaJIT.
> > > > > +-- checkmessage([[  -- tail call
> > > > > +--   return math.sin("a")
> > > > > +-- ]], "'sin'")
> > > > >  
> > > > >  checkmessage([[collectgarbage("nooption")]], "invalid option")
> > > > >  

<snipped>

> 
> -- 
> Best regards,
> Sergey Kaplun

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 16/30] test: adapt PUC Lua test for %q in fmt for LuaJIT
  2021-04-07 15:50         ` Sergey Kaplun via Tarantool-patches
@ 2021-04-07 16:31           ` Igor Munkin via Tarantool-patches
  2021-04-08  8:51             ` Sergey Kaplun via Tarantool-patches
  0 siblings, 1 reply; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-04-07 16:31 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

On 07.04.21, Sergey Kaplun wrote:
> Igor,
> 

<snipped>

> > > > > string.format(): %q reversible.
> > > > > See also https://luajit.org/extensions.html#lua52.
> > > > > 
> > > > > In Lua 5.1 string.format() does not accept string values containing
> > > > > embedded zeros, except as arguments to the '%q' option.
> > > > > In Lua 5.2 '\0' is not handled differently from other
> > > > > control chars in string.format('%q', ...).
> > > > > See commit 7cc981c14067d4b0e774a6bfb0acfc2f5c911f0d
> > > > > (string.format("%q", str) is now fully reversible
> > > > > (from Lua 5.2).).
> > > > 
> > > > Well, I honestly don't understand what is changed in *semantics*. I've
> > > > tried the following command with Lua 5.2, Lua 5.1 and LuaJIT 2.0.5 as an
> > > > interpreter being tested
> > > > | <interp> -e 'print(string.format("%q", "\0"))'
> > > > 
> > > > I understand the semantics of "%q", but was it just a bug in Lua 5.1?
> > > 
> > > A bug with the test for it???
> > 
> > Well, I can remind you the bug with <tonumber> we fixed the last year.
> > There might be no test for it though, but all in all it has not been
> > fixed in Lua 5.1.
> 
> I mean that this behaviour is verificated by the test. When behaviour is
> changed the test is changed too.
> 
> > 
> > > 
> > > > What does "fully reversible" mean in this context?
> > 
> > This question is left unaddressed.
> 
> I don't know what does Mike mean by these.

Then it would be great to describe the changes on your own. I can hardly
split the comment into yours words and ones taked from Lua Reference
manual or git log, but you are writing that "In Lua 5.2 '\0' is not
handled differently from other control chars". Could you please clarify
the difference you are talking about? Or provide the links describing
it? May be some parts from PIL?

> 
> > 
> > > > 
> > > > I understand only the fact the behaviour differs and you reimplemented
> > > > the test assertion according to Lua 5.2 testing suite. That's all.
> > > > 
> > > > I found not a single word regarding this issue in Lua bugs[1] page,
> > > > except invalid handling of \r[2]. Is there any issue/page with a more
> > > 
> > > It looks unrelated to these changes.
> > > 
> > > > verbose explanation what has been changed in 7cc981c?
> > > 
> > > I just read these lines in Lua 5.1 reference manual :):
> > > | This function does not accept string values containing embedded
> > > | zeros, except as arguments to the q option.
> > 
> > So what? This means literally nothing to me... BTW, I can pass such
> > string to the function and it can yield any bullshit the developer
> > wanted to. That's why we decided to comment such places in a clear and
> > verbose way, didn't we?
> 
> Don't get you point here. AFAIU it means that `%q` is the only one
> option that can contain embeded zeros, so it handles it in the special
> way.

My point relates to the fact, nobody except you can understand the
comment near the change. Hence one need to make the similar
investigation you made. Then what is the sense of commenting the changes
in suite?

> 
> > 
> > > 
> > > As for me, it is just new behaviour of Lua 5.2 -- patterns now accept
> > > '\0' as a reqular character (see
> > > 4541243355a299a9b75042d207feb87295872c3a (patterns now accept '\0' as a
> > > regular character) from Lua repository). So, according to commit
> > > 658ea8752b979102627e2fede7b7ddfbb67ba6c9 (no need to handle '\0'
> > > differently from other control chars in format '%q')) from Lua
> > > repository, this behaviour is excess.
> > > 
> > > Also, it is mentioned here [2].
> > 
> > I see nothing regarding this change there.
> 
> I am talking about this part:
> 
> | Character class %z in patterns is deprecated, as now patterns may
> | contain '\0' as a regular character.

Patterns, not options, right?

> 

<snipped>

> > > > [1]: https://www.lua.org/bugs.html#5.1
> > > > [2]: https://www.lua.org/bugs.html#5.1-4
> > > > 
> > > > -- 
> > > > Best regards,
> > > > IM
> > > 
> > > [1]: https://www.lua.org/manual/5.1/manual.html#pdf-string.format
> > > [2]: https://www.lua.org/manual/5.2/manual.html#8.2

<snipped>

> 
> -- 
> Best regards,
> Sergey Kaplun

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 23/30] test: disable PUC Lua test for fast function name
  2021-04-07 16:11           ` Igor Munkin via Tarantool-patches
@ 2021-04-07 19:57             ` Sergey Kaplun via Tarantool-patches
  2021-04-12  9:36               ` Igor Munkin via Tarantool-patches
  0 siblings, 1 reply; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-07 19:57 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

On 07.04.21, Igor Munkin wrote:
> Sergey,
> 
> On 07.04.21, Sergey Kaplun wrote:
> > Igor,
> > 
> 
> <snipped>
> 
> > > > > > diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua
> > > > > > index cf24e40..af776a7 100644
> > > > > > --- a/test/PUC-Lua-5.1-tests/errors.lua
> > > > > > +++ b/test/PUC-Lua-5.1-tests/errors.lua
> > > > > > @@ -105,9 +105,13 @@ while 1 do
> > > > > >    insert(prefix, a)
> > > > > >  end]], "global 'insert'")
> > > > > >  
> > > > > > -checkmessage([[  -- tail call
> > > > > > -  return math.sin("a")
> > > > > > -]], "'sin'")
> > > > > > +-- LuaJIT: Can't determine bytecode position for non Lua functions
> > > > > > +-- (in particular for fast functions) and, therefore, detect fast
> > > > > > +-- function names for errors in tail calls.
> > > > > 
> > > > > This is kinda gibberish. I've tried the following snippets and can't
> > > > > understand what do you mean by this comment.
> > > > > 
> > > > > | $ luajit -e 'function q(a) return math.sin(a) end q("a")'
> > > > > | luajit: (command line):1: bad argument #1 to 'q' (number expected, got string)
> > > > > | stack traceback:
> > > > > |         [C]: in function 'q'
> > > > > |         (command line):1: in main chunk
> > > > > |         [C]: at 0x5610e8497eb0
> > > > > | $ luajit -e 'loadstring("return math.sin([[a]])")()'
> > > > > | luajit: (command line):1: bad argument #1 to '?' (number expected, got string)
> > > > > | stack traceback:
> > > > > |         [builtin#43]: at 0x7fc0f807ad10
> > > > > |         (command line):1: in main chunk
> > > > > |         [C]: at 0x55c1e85c7eb0
> > > > > 
> > > > > I understand the first result. The second result surprised me, but I've
> > > > > never investigated how loadstring call works (it looks like specifics of
> > > > > VARG frame, but this is a wild guess). But neither of them fits your
> > > > > explanation. The root cause is the same: callee uses caller frame, since
> > > > > caller doesn't need it anymore. Could you please clarify yours?
> > > > 
> > > > This is not about `loadstring()` at all:
> > > > 
> > > > | luajit -e 'return math.sin"a"'
> > > > | luajit: bad argument #1 to '?' (number expected, got string)
> > > > | stack traceback:
> > > > |         [builtin#43]: at 0x7f7c2ca6dbe0
> > > > |         [C]: at 0x558b0cd4cec0
> > > > 
> > > > The guest frame is looked like the following (when the error thrown):
> > > > | 0x40001938            [    ] VALUE: string "number expected, got string" @ 0x40008380
> > > > | 0x40001930            [ B  ] VALUE: string "a" @ 0x40008250
> > > > | 0x40001928            [    ] FRAME: [CP] delta=3, fast function #44
> > > > 
> > > > When LuaJIT tries to detect function's name it determines bytecode
> > > > position first, via `debug_framepc()`. But it can't determine bytecode
> > > > position for non-Lua functions:
> > > 
> > > What? Both luajit-gdb.py and LuaJIT itself reports the fast function ID
> > > and this is its name.
> > 
> > Yes, what is your question about?
> 
> Then what's the problem with name resolving?

As I said before for tailcall there is no creation of additional Lua
frame. Without it guest frame is looks like the following:

| 0x40001950            [  T ]
| 0x40001948            [    ] VALUE: string "number expected, got string" @ 0x40008380
| 0x40001940            [ B  ] VALUE: string "a" @ 0x40008280
| 0x40001938            [    ] FRAME: [LP] delta=1, fast function #44
| 0x40001930            [    ] FRAME: [V] delta=1, Lua function @ 0x40008248, 0 upvalues, "=(command line)":0
| 0x40001928            [    ] FRAME: [CP] delta=3, Lua function @ 0x40008248, 0 upvalues, "=(command line)":0

`err_argmsg()` function uses `lj_debug_funcname()`, which uses
`debug_framepc()`, which can't get bcpos required for function prototype
detection (see explanation with code sources above). So, LuaJIT can't
detect fast function names for tailcalls on C frame.

> 
> > 
> > > 
> > > > 
> > > > | if (!isluafunc(fn)) {  /* Cannot derive a PC for non-Lua functions. */
> > > > |   return NO_BCPOS;
> > > > 
> > > > > 
> > > > > > +-- The test is disabled for LuaJIT.
> > > > > > +-- checkmessage([[  -- tail call
> > > > > > +--   return math.sin("a")
> > > > > > +-- ]], "'sin'")
> > > > > >  
> > > > > >  checkmessage([[collectgarbage("nooption")]], "invalid option")
> > > > > >  
> 
> <snipped>
> 
> > 
> > -- 
> > Best regards,
> > Sergey Kaplun
> 
> -- 
> Best regards,
> IM

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 16/30] test: adapt PUC Lua test for %q in fmt for LuaJIT
  2021-04-07 16:31           ` Igor Munkin via Tarantool-patches
@ 2021-04-08  8:51             ` Sergey Kaplun via Tarantool-patches
  2021-04-12 10:26               ` Igor Munkin via Tarantool-patches
  0 siblings, 1 reply; 153+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-04-08  8:51 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

On 07.04.21, Igor Munkin wrote:
> Sergey,
> 
> On 07.04.21, Sergey Kaplun wrote:
> > Igor,
> > 
> 
> <snipped>
> 
> > > > > > string.format(): %q reversible.
> > > > > > See also https://luajit.org/extensions.html#lua52.
> > > > > > 
> > > > > > In Lua 5.1 string.format() does not accept string values containing
> > > > > > embedded zeros, except as arguments to the '%q' option.
> > > > > > In Lua 5.2 '\0' is not handled differently from other
> > > > > > control chars in string.format('%q', ...).
> > > > > > See commit 7cc981c14067d4b0e774a6bfb0acfc2f5c911f0d
> > > > > > (string.format("%q", str) is now fully reversible
> > > > > > (from Lua 5.2).).
> > > > > 
> > > > > Well, I honestly don't understand what is changed in *semantics*. I've
> > > > > tried the following command with Lua 5.2, Lua 5.1 and LuaJIT 2.0.5 as an
> > > > > interpreter being tested
> > > > > | <interp> -e 'print(string.format("%q", "\0"))'
> > > > > 
> > > > > I understand the semantics of "%q", but was it just a bug in Lua 5.1?
> > > > 
> > > > A bug with the test for it???
> > > 
> > > Well, I can remind you the bug with <tonumber> we fixed the last year.
> > > There might be no test for it though, but all in all it has not been
> > > fixed in Lua 5.1.
> > 
> > I mean that this behaviour is verificated by the test. When behaviour is
> > changed the test is changed too.
> > 
> > > 
> > > > 
> > > > > What does "fully reversible" mean in this context?
> > > 
> > > This question is left unaddressed.
> > 
> > I don't know what does Mike mean by these.
> 
> Then it would be great to describe the changes on your own. I can hardly
> split the comment into yours words and ones taked from Lua Reference
> manual or git log, but you are writing that "In Lua 5.2 '\0' is not
> handled differently from other control chars". Could you please clarify
> the difference you are talking about? Or provide the links describing
> it? May be some parts from PIL?
> 
> > 
> > > 
> > > > > 
> > > > > I understand only the fact the behaviour differs and you reimplemented
> > > > > the test assertion according to Lua 5.2 testing suite. That's all.
> > > > > 
> > > > > I found not a single word regarding this issue in Lua bugs[1] page,
> > > > > except invalid handling of \r[2]. Is there any issue/page with a more
> > > > 
> > > > It looks unrelated to these changes.
> > > > 
> > > > > verbose explanation what has been changed in 7cc981c?
> > > > 
> > > > I just read these lines in Lua 5.1 reference manual :):
> > > > | This function does not accept string values containing embedded
> > > > | zeros, except as arguments to the q option.
> > > 
> > > So what? This means literally nothing to me... BTW, I can pass such
> > > string to the function and it can yield any bullshit the developer
> > > wanted to. That's why we decided to comment such places in a clear and
> > > verbose way, didn't we?
> > 
> > Don't get you point here. AFAIU it means that `%q` is the only one
> > option that can contain embeded zeros, so it handles it in the special
> > way.
> 
> My point relates to the fact, nobody except you can understand the
> comment near the change. Hence one need to make the similar
> investigation you made. Then what is the sense of commenting the changes
> in suite?
> 
> > 
> > > 
> > > > 
> > > > As for me, it is just new behaviour of Lua 5.2 -- patterns now accept
> > > > '\0' as a reqular character (see
> > > > 4541243355a299a9b75042d207feb87295872c3a (patterns now accept '\0' as a
> > > > regular character) from Lua repository). So, according to commit
> > > > 658ea8752b979102627e2fede7b7ddfbb67ba6c9 (no need to handle '\0'
> > > > differently from other control chars in format '%q')) from Lua
> > > > repository, this behaviour is excess.
> > > > 
> > > > Also, it is mentioned here [2].
> > > 
> > > I see nothing regarding this change there.
> > 
> > I am talking about this part:
> > 
> > | Character class %z in patterns is deprecated, as now patterns may
> > | contain '\0' as a regular character.
> 
> Patterns, not options, right?
> 
> > 
> 
> <snipped>

I haven't found no more verbose descriptions about %q specifier
neither in the PIL, nor in the Lua Reference Manual, nor in the Lua
mailing list, nor in the LuaJIT mailing list.
So, I am appealing to the commits in the Lua repository.

Going back to the definition of specifier %q from Lua 5.1 Reference
manual:
| The q option formats a string in a form suitable to be safely read
| back by the Lua interpreter: ...

Answering your previous question -- "reversible" means (in my
understanding now) that `string.format("% q", binary)` should return
the same-looking `binary` string that was presented to the
interpreter and `string.format()` first (perhaps, it can expand
control characters like '\r', '\n', and turn symbol "\65" into "A").
This is why I was referencing zero-bytes in patterns (unfortunately,
wrongly).

Historically, in Lua 5.2, control characters are written as \nnn
when needed, see d62a21b9d379a576bae7426c80039ca1a4d2bb07 ("when
formatting with '%q', all control characters are coded as \nnn.") [1].
In this patch, %q specifier starts writing control characters
to a new string in the same way through \n, instead of their binary
representation as it is. If the control character is followed by a
digit, then for the correct work of the parser, it is necessary to
extend the escape sequence to 3 significant characters (otherwise,
the transition "\0002" -> "\02" corrupts string).
For this patch, the expansion is performed unconditionally (the check
for the next symbol is not performed) if this first symbol is a zero
byte. You may notice that the additional check for '\0' is
unnecessary - if after it comes a digit, then a branch with expanding
the format to 3 significant characters will be selected. Consistent
work with the zero byte processing was added in the commit
658ea8752b979102627e2fede7b7ddfbb67ba6c9 ("no need to handle '\0'
differently from other control chars in format '%q'") [2]. Note that
this patch does not change the semantics of %q specifier - the new
string can still be "safely read back by the Lua interpreter".

As we know, in Lua 5.1, '\0' was converted to "\000" unconditionally.
This was partly done to avoid unnecessary logic, as I suppose, since
before the d62a21b commit, all other characters were transmitted
as-is in the new string, and there was no inconsistency.

Is it worth mentioning the first commit clarifying the cause of the
inconsistency, because it does not directly relate to changes? The
initial comment, in my opinion, reflects the reason for the failing
test -- '\0' began to be processed in the same way as other
controlled characters in Lua 5.2. LuaJIT has adopted this practice in
a related commit. The curious reader can independently search the
commit history for these changes. Please let me know, if you think
these clarifications are necessary to describe the problem.

> 
> > > > > [1]: https://www.lua.org/bugs.html#5.1
> > > > > [2]: https://www.lua.org/bugs.html#5.1-4
> > > > > 
> > > > > -- 
> > > > > Best regards,
> > > > > IM
> > > > 
> > > > [1]: https://www.lua.org/manual/5.1/manual.html#pdf-string.format
> > > > [2]: https://www.lua.org/manual/5.2/manual.html#8.2
> 
> <snipped>
> 
> > 
> > -- 
> > Best regards,
> > Sergey Kaplun
> 
> -- 
> Best regards,
> IM

[1]: https://github.com/lua/lua/commit/d62a21b9d379a576bae7426c80039ca1a4d2bb07
[2]: https://github.com/lua/lua/commit/658ea8752b979102627e2fede7b7ddfbb67ba6c9

-- 
Best regards,
Sergey Kaplun

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 23/30] test: disable PUC Lua test for fast function name
  2021-04-07 19:57             ` Sergey Kaplun via Tarantool-patches
@ 2021-04-12  9:36               ` Igor Munkin via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-04-12  9:36 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

On 07.04.21, Sergey Kaplun wrote:
> Igor,
> 
> On 07.04.21, Igor Munkin wrote:
> > Sergey,
> > 
> > On 07.04.21, Sergey Kaplun wrote:
> > > Igor,
> > > 
> > 
> > <snipped>
> > 
> > > > > > > diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua
> > > > > > > index cf24e40..af776a7 100644
> > > > > > > --- a/test/PUC-Lua-5.1-tests/errors.lua
> > > > > > > +++ b/test/PUC-Lua-5.1-tests/errors.lua
> > > > > > > @@ -105,9 +105,13 @@ while 1 do
> > > > > > >    insert(prefix, a)
> > > > > > >  end]], "global 'insert'")
> > > > > > >  
> > > > > > > -checkmessage([[  -- tail call
> > > > > > > -  return math.sin("a")
> > > > > > > -]], "'sin'")
> > > > > > > +-- LuaJIT: Can't determine bytecode position for non Lua functions
> > > > > > > +-- (in particular for fast functions) and, therefore, detect fast
> > > > > > > +-- function names for errors in tail calls.
> > > > > > 
> > > > > > This is kinda gibberish. I've tried the following snippets and can't
> > > > > > understand what do you mean by this comment.
> > > > > > 
> > > > > > | $ luajit -e 'function q(a) return math.sin(a) end q("a")'
> > > > > > | luajit: (command line):1: bad argument #1 to 'q' (number expected, got string)
> > > > > > | stack traceback:
> > > > > > |         [C]: in function 'q'
> > > > > > |         (command line):1: in main chunk
> > > > > > |         [C]: at 0x5610e8497eb0
> > > > > > | $ luajit -e 'loadstring("return math.sin([[a]])")()'
> > > > > > | luajit: (command line):1: bad argument #1 to '?' (number expected, got string)
> > > > > > | stack traceback:
> > > > > > |         [builtin#43]: at 0x7fc0f807ad10
> > > > > > |         (command line):1: in main chunk
> > > > > > |         [C]: at 0x55c1e85c7eb0
> > > > > > 
> > > > > > I understand the first result. The second result surprised me, but I've
> > > > > > never investigated how loadstring call works (it looks like specifics of
> > > > > > VARG frame, but this is a wild guess). But neither of them fits your
> > > > > > explanation. The root cause is the same: callee uses caller frame, since
> > > > > > caller doesn't need it anymore. Could you please clarify yours?
> > > > > 
> > > > > This is not about `loadstring()` at all:
> > > > > 
> > > > > | luajit -e 'return math.sin"a"'
> > > > > | luajit: bad argument #1 to '?' (number expected, got string)
> > > > > | stack traceback:
> > > > > |         [builtin#43]: at 0x7f7c2ca6dbe0
> > > > > |         [C]: at 0x558b0cd4cec0
> > > > > 
> > > > > The guest frame is looked like the following (when the error thrown):
> > > > > | 0x40001938            [    ] VALUE: string "number expected, got string" @ 0x40008380
> > > > > | 0x40001930            [ B  ] VALUE: string "a" @ 0x40008250
> > > > > | 0x40001928            [    ] FRAME: [CP] delta=3, fast function #44
> > > > > 
> > > > > When LuaJIT tries to detect function's name it determines bytecode
> > > > > position first, via `debug_framepc()`. But it can't determine bytecode
> > > > > position for non-Lua functions:
> > > > 
> > > > What? Both luajit-gdb.py and LuaJIT itself reports the fast function ID
> > > > and this is its name.
> > > 
> > > Yes, what is your question about?
> > 
> > Then what's the problem with name resolving?
> 
> As I said before for tailcall there is no creation of additional Lua
> frame. Without it guest frame is looks like the following:
> 
> | 0x40001950            [  T ]
> | 0x40001948            [    ] VALUE: string "number expected, got string" @ 0x40008380
> | 0x40001940            [ B  ] VALUE: string "a" @ 0x40008280
> | 0x40001938            [    ] FRAME: [LP] delta=1, fast function #44
> | 0x40001930            [    ] FRAME: [V] delta=1, Lua function @ 0x40008248, 0 upvalues, "=(command line)":0
> | 0x40001928            [    ] FRAME: [CP] delta=3, Lua function @ 0x40008248, 0 upvalues, "=(command line)":0
> 
> `err_argmsg()` function uses `lj_debug_funcname()`, which uses
> `debug_framepc()`, which can't get bcpos required for function prototype
> detection (see explanation with code sources above). So, LuaJIT can't
> detect fast function names for tailcalls on C frame.

And *this* is finally a good explanation of the issue you resolved here.
Please adjust the original comment considering the wording above. After
this change made, the patch LGTM, thanks!

> 
> > 
> > > 
> > > > 
> > > > > 
> > > > > | if (!isluafunc(fn)) {  /* Cannot derive a PC for non-Lua functions. */
> > > > > |   return NO_BCPOS;
> > > > > 
> > > > > > 
> > > > > > > +-- The test is disabled for LuaJIT.
> > > > > > > +-- checkmessage([[  -- tail call
> > > > > > > +--   return math.sin("a")
> > > > > > > +-- ]], "'sin'")
> > > > > > >  
> > > > > > >  checkmessage([[collectgarbage("nooption")]], "invalid option")
> > > > > > >  
> > 
> > <snipped>
> > 
> > > 
> > > -- 
> > > Best regards,
> > > Sergey Kaplun
> > 
> > -- 
> > Best regards,
> > IM
> 
> -- 
> Best regards,
> Sergey Kaplun

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 luajit 16/30] test: adapt PUC Lua test for %q in fmt for LuaJIT
  2021-04-08  8:51             ` Sergey Kaplun via Tarantool-patches
@ 2021-04-12 10:26               ` Igor Munkin via Tarantool-patches
  0 siblings, 0 replies; 153+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-04-12 10:26 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

On 08.04.21, Sergey Kaplun wrote:
> Igor,
> 
> On 07.04.21, Igor Munkin wrote:
> > Sergey,
> > 
> > On 07.04.21, Sergey Kaplun wrote:
> > > Igor,
> > > 
> > 
> > <snipped>
> > 
> > > > > > > string.format(): %q reversible.
> > > > > > > See also https://luajit.org/extensions.html#lua52.
> > > > > > > 
> > > > > > > In Lua 5.1 string.format() does not accept string values containing
> > > > > > > embedded zeros, except as arguments to the '%q' option.
> > > > > > > In Lua 5.2 '\0' is not handled differently from other
> > > > > > > control chars in string.format('%q', ...).
> > > > > > > See commit 7cc981c14067d4b0e774a6bfb0acfc2f5c911f0d
> > > > > > > (string.format("%q", str) is now fully reversible
> > > > > > > (from Lua 5.2).).
> > > > > > 
> > > > > > Well, I honestly don't understand what is changed in *semantics*. I've
> > > > > > tried the following command with Lua 5.2, Lua 5.1 and LuaJIT 2.0.5 as an
> > > > > > interpreter being tested
> > > > > > | <interp> -e 'print(string.format("%q", "\0"))'
> > > > > > 
> > > > > > I understand the semantics of "%q", but was it just a bug in Lua 5.1?
> > > > > 
> > > > > A bug with the test for it???
> > > > 
> > > > Well, I can remind you the bug with <tonumber> we fixed the last year.
> > > > There might be no test for it though, but all in all it has not been
> > > > fixed in Lua 5.1.
> > > 
> > > I mean that this behaviour is verificated by the test. When behaviour is
> > > changed the test is changed too.
> > > 
> > > > 
> > > > > 
> > > > > > What does "fully reversible" mean in this context?
> > > > 
> > > > This question is left unaddressed.
> > > 
> > > I don't know what does Mike mean by these.
> > 
> > Then it would be great to describe the changes on your own. I can hardly
> > split the comment into yours words and ones taked from Lua Reference
> > manual or git log, but you are writing that "In Lua 5.2 '\0' is not
> > handled differently from other control chars". Could you please clarify
> > the difference you are talking about? Or provide the links describing
> > it? May be some parts from PIL?
> > 
> > > 
> > > > 
> > > > > > 
> > > > > > I understand only the fact the behaviour differs and you reimplemented
> > > > > > the test assertion according to Lua 5.2 testing suite. That's all.
> > > > > > 
> > > > > > I found not a single word regarding this issue in Lua bugs[1] page,
> > > > > > except invalid handling of \r[2]. Is there any issue/page with a more
> > > > > 
> > > > > It looks unrelated to these changes.
> > > > > 
> > > > > > verbose explanation what has been changed in 7cc981c?
> > > > > 
> > > > > I just read these lines in Lua 5.1 reference manual :):
> > > > > | This function does not accept string values containing embedded
> > > > > | zeros, except as arguments to the q option.
> > > > 
> > > > So what? This means literally nothing to me... BTW, I can pass such
> > > > string to the function and it can yield any bullshit the developer
> > > > wanted to. That's why we decided to comment such places in a clear and
> > > > verbose way, didn't we?
> > > 
> > > Don't get you point here. AFAIU it means that `%q` is the only one
> > > option that can contain embeded zeros, so it handles it in the special
> > > way.
> > 
> > My point relates to the fact, nobody except you can understand the
> > comment near the change. Hence one need to make the similar
> > investigation you made. Then what is the sense of commenting the changes
> > in suite?
> > 
> > > 
> > > > 
> > > > > 
> > > > > As for me, it is just new behaviour of Lua 5.2 -- patterns now accept
> > > > > '\0' as a reqular character (see
> > > > > 4541243355a299a9b75042d207feb87295872c3a (patterns now accept '\0' as a
> > > > > regular character) from Lua repository). So, according to commit
> > > > > 658ea8752b979102627e2fede7b7ddfbb67ba6c9 (no need to handle '\0'
> > > > > differently from other control chars in format '%q')) from Lua
> > > > > repository, this behaviour is excess.
> > > > > 
> > > > > Also, it is mentioned here [2].
> > > > 
> > > > I see nothing regarding this change there.
> > > 
> > > I am talking about this part:
> > > 
> > > | Character class %z in patterns is deprecated, as now patterns may
> > > | contain '\0' as a regular character.
> > 
> > Patterns, not options, right?
> > 
> > > 
> > 
> > <snipped>
> 
> I haven't found no more verbose descriptions about %q specifier
> neither in the PIL, nor in the Lua Reference Manual, nor in the Lua
> mailing list, nor in the LuaJIT mailing list.
> So, I am appealing to the commits in the Lua repository.
> 
> Going back to the definition of specifier %q from Lua 5.1 Reference
> manual:
> | The q option formats a string in a form suitable to be safely read
> | back by the Lua interpreter: ...
> 
> Answering your previous question -- "reversible" means (in my
> understanding now) that `string.format("% q", binary)` should return
> the same-looking `binary` string that was presented to the
> interpreter and `string.format()` first (perhaps, it can expand
> control characters like '\r', '\n', and turn symbol "\65" into "A").
> This is why I was referencing zero-bytes in patterns (unfortunately,
> wrongly).
> 
> Historically, in Lua 5.2, control characters are written as \nnn
> when needed, see d62a21b9d379a576bae7426c80039ca1a4d2bb07 ("when
> formatting with '%q', all control characters are coded as \nnn.") [1].
> In this patch, %q specifier starts writing control characters
> to a new string in the same way through \n, instead of their binary
> representation as it is. If the control character is followed by a
> digit, then for the correct work of the parser, it is necessary to
> extend the escape sequence to 3 significant characters (otherwise,
> the transition "\0002" -> "\02" corrupts string).
> For this patch, the expansion is performed unconditionally (the check
> for the next symbol is not performed) if this first symbol is a zero
> byte. You may notice that the additional check for '\0' is
> unnecessary - if after it comes a digit, then a branch with expanding
> the format to 3 significant characters will be selected. Consistent
> work with the zero byte processing was added in the commit
> 658ea8752b979102627e2fede7b7ddfbb67ba6c9 ("no need to handle '\0'
> differently from other control chars in format '%q'") [2]. Note that
> this patch does not change the semantics of %q specifier - the new
> string can still be "safely read back by the Lua interpreter".
> 
> As we know, in Lua 5.1, '\0' was converted to "\000" unconditionally.
> This was partly done to avoid unnecessary logic, as I suppose, since
> before the d62a21b commit, all other characters were transmitted
> as-is in the new string, and there was no inconsistency.
> 
> Is it worth mentioning the first commit clarifying the cause of the
> inconsistency, because it does not directly relate to changes? The
> initial comment, in my opinion, reflects the reason for the failing
> test -- '\0' began to be processed in the same way as other
> controlled characters in Lua 5.2. LuaJIT has adopted this practice in
> a related commit. The curious reader can independently search the
> commit history for these changes. Please let me know, if you think
> these clarifications are necessary to describe the problem.

IMHO, it's worth mentioning everything above! Thanks for such deep
digging and clarification: now I understand the original semantics and
your change. It was totally unclear that Lua converts \0 to \000
considering it as an octet. Please enrich the comment with some parts
above (honestly, you can put the whole explanation to the comment if you
want), and after this change, the patch LGTM. Again, thanks a lot for
your investigation!

> 
> > 
> > > > > > [1]: https://www.lua.org/bugs.html#5.1
> > > > > > [2]: https://www.lua.org/bugs.html#5.1-4
> > > > > > 
> > > > > > -- 
> > > > > > Best regards,
> > > > > > IM
> > > > > 
> > > > > [1]: https://www.lua.org/manual/5.1/manual.html#pdf-string.format
> > > > > [2]: https://www.lua.org/manual/5.2/manual.html#8.2
> > 
> > <snipped>
> > 
> > > 
> > > -- 
> > > Best regards,
> > > Sergey Kaplun
> > 
> > -- 
> > Best regards,
> > IM
> 
> [1]: https://github.com/lua/lua/commit/d62a21b9d379a576bae7426c80039ca1a4d2bb07
> [2]: https://github.com/lua/lua/commit/658ea8752b979102627e2fede7b7ddfbb67ba6c9
> 
> -- 
> Best regards,
> Sergey Kaplun

-- 
Best regards,
IM

^ permalink raw reply	[flat|nested] 153+ messages in thread

end of thread, other threads:[~2021-04-12 10:26 UTC | newest]

Thread overview: 153+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-26  7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 01/30] test: add " Sergey Kaplun via Tarantool-patches
2021-03-26 10:14   ` Sergey Ostanevich via Tarantool-patches
2021-03-30 22:13   ` Igor Munkin via Tarantool-patches
2021-04-01  8:11     ` Sergey Kaplun via Tarantool-patches
2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 02/30] test: add compiling for C libs from PUC-Rio-Lua5.1 Sergey Kaplun via Tarantool-patches
2021-03-26 11:01   ` Sergey Ostanevich via Tarantool-patches
2021-03-30 22:14   ` Igor Munkin via Tarantool-patches
2021-04-01  8:21     ` Sergey Kaplun via Tarantool-patches
2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 03/30] test: adapt Lua 5.1 suite for out-of-source build Sergey Kaplun via Tarantool-patches
2021-03-26 11:07   ` Sergey Ostanevich via Tarantool-patches
2021-03-26 14:25     ` Sergey Kaplun via Tarantool-patches
2021-03-31 22:58       ` Igor Munkin via Tarantool-patches
2021-04-01  8:43         ` Sergey Kaplun via Tarantool-patches
2021-03-31 22:58   ` Igor Munkin via Tarantool-patches
2021-04-01  8:40     ` Sergey Kaplun via Tarantool-patches
2021-04-06 16:56       ` Igor Munkin via Tarantool-patches
2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 04/30] test: remove quotes in progname from <main.lua> Sergey Kaplun via Tarantool-patches
2021-03-26 11:12   ` Sergey Ostanevich via Tarantool-patches
2021-03-31 22:58   ` Igor Munkin via Tarantool-patches
2021-04-01  8:50     ` Sergey Kaplun via Tarantool-patches
2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 05/30] test: adapt arg availability test from Lua suite Sergey Kaplun via Tarantool-patches
2021-03-26 11:22   ` Sergey Ostanevich via Tarantool-patches
2021-03-31 22:58   ` Igor Munkin via Tarantool-patches
2021-04-01  9:37     ` Sergey Kaplun via Tarantool-patches
2021-04-06 15:24       ` Igor Munkin via Tarantool-patches
2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 06/30] test: disable PUC Lua tests confused by -v output Sergey Kaplun via Tarantool-patches
2021-03-26 11:26   ` Sergey Ostanevich via Tarantool-patches
2021-03-26 14:31     ` Sergey Kaplun via Tarantool-patches
2021-03-31 22:58   ` Igor Munkin via Tarantool-patches
2021-04-01  9:56     ` Sergey Kaplun via Tarantool-patches
2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 07/30] test: disable Lua tests for bytecode with header Sergey Kaplun via Tarantool-patches
2021-03-26 11:30   ` Sergey Ostanevich via Tarantool-patches
2021-03-31 22:59   ` Igor Munkin via Tarantool-patches
2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 08/30] test: disable JIT for GC step counting tests Sergey Kaplun via Tarantool-patches
2021-03-26 11:32   ` Sergey Ostanevich via Tarantool-patches
2021-03-30 22:14   ` Igor Munkin via Tarantool-patches
2021-04-01 10:10     ` Sergey Kaplun via Tarantool-patches
2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 09/30] test: disable Lua suite tests for line hook Sergey Kaplun via Tarantool-patches
2021-03-26 11:35   ` Sergey Ostanevich via Tarantool-patches
2021-03-26 14:33     ` Sergey Kaplun via Tarantool-patches
2021-03-31 22:59   ` Igor Munkin via Tarantool-patches
2021-04-01 10:06     ` Sergey Kaplun via Tarantool-patches
2021-04-06 19:45       ` Igor Munkin via Tarantool-patches
2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 10/30] test: adapt test for debug.setlocal in Lua suite Sergey Kaplun via Tarantool-patches
2021-03-26 11:44   ` Sergey Ostanevich via Tarantool-patches
2021-03-26 14:45     ` Sergey Kaplun via Tarantool-patches
2021-03-30 22:14   ` Igor Munkin via Tarantool-patches
2021-04-01 10:16     ` Sergey Kaplun via Tarantool-patches
2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 11/30] test: adapt getlocal PUC test for vararg func Sergey Kaplun via Tarantool-patches
2021-03-26 11:47   ` Sergey Ostanevich via Tarantool-patches
2021-03-26 14:52     ` Sergey Kaplun via Tarantool-patches
2021-03-30 22:15   ` Igor Munkin via Tarantool-patches
2021-04-01 11:37     ` Sergey Kaplun via Tarantool-patches
2021-04-06 20:09       ` Igor Munkin via Tarantool-patches
2021-04-06 20:40         ` Igor Munkin via Tarantool-patches
2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 12/30] test: adapt PUC Lua test with count hooks Sergey Kaplun via Tarantool-patches
2021-03-26 11:49   ` Sergey Ostanevich via Tarantool-patches
2021-03-30 22:15   ` Igor Munkin via Tarantool-patches
2021-04-01 11:42     ` Sergey Kaplun via Tarantool-patches
2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 13/30] test: disable PUC Lua test for tail call info Sergey Kaplun via Tarantool-patches
2021-03-26 14:43   ` Sergey Ostanevich via Tarantool-patches
2021-03-30 22:15   ` Igor Munkin via Tarantool-patches
2021-04-01 11:52     ` Sergey Kaplun via Tarantool-patches
2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 14/30] test: adapt activeline check in the PUC Lua test Sergey Kaplun via Tarantool-patches
2021-03-26 14:50   ` Sergey Ostanevich via Tarantool-patches
2021-03-30 22:15   ` Igor Munkin via Tarantool-patches
2021-04-01 11:58     ` Sergey Kaplun via Tarantool-patches
2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 15/30] test: disable PUC-Lua test for per-coroutine hooks Sergey Kaplun via Tarantool-patches
2021-03-26 14:54   ` Sergey Ostanevich via Tarantool-patches
2021-03-30 22:16   ` Igor Munkin via Tarantool-patches
2021-04-01 12:03     ` Sergey Kaplun via Tarantool-patches
2021-03-26  7:42 ` [Tarantool-patches] [PATCH v2 luajit 16/30] test: adapt PUC Lua test for %q in fmt for LuaJIT Sergey Kaplun via Tarantool-patches
2021-03-26 14:56   ` Sergey Ostanevich via Tarantool-patches
2021-03-30 22:16   ` Igor Munkin via Tarantool-patches
2021-04-01 12:33     ` Sergey Kaplun via Tarantool-patches
2021-04-06 21:37       ` Igor Munkin via Tarantool-patches
2021-04-07 15:50         ` Sergey Kaplun via Tarantool-patches
2021-04-07 16:31           ` Igor Munkin via Tarantool-patches
2021-04-08  8:51             ` Sergey Kaplun via Tarantool-patches
2021-04-12 10:26               ` Igor Munkin via Tarantool-patches
2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 17/30] test: disable locale-depended tests for Lua suite Sergey Kaplun via Tarantool-patches
2021-03-26 14:58   ` Sergey Ostanevich via Tarantool-patches
2021-03-30 22:16   ` Igor Munkin via Tarantool-patches
2021-04-01 19:12     ` Sergey Kaplun via Tarantool-patches
2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 18/30] test: replace math.mod to math.fmod for Lua tests Sergey Kaplun via Tarantool-patches
2021-03-26 15:12   ` Sergey Ostanevich via Tarantool-patches
2021-03-30 22:17     ` Igor Munkin via Tarantool-patches
2021-03-26 15:16   ` Sergey Ostanevich via Tarantool-patches
2021-03-30 22:16   ` Igor Munkin via Tarantool-patches
2021-04-01 19:36     ` Sergey Kaplun via Tarantool-patches
2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 19/30] test: remove assert for string.gfind check Sergey Kaplun via Tarantool-patches
2021-03-26 15:14   ` Sergey Ostanevich via Tarantool-patches
2021-03-30 22:17   ` Igor Munkin via Tarantool-patches
2021-04-02  7:05     ` Sergey Kaplun via Tarantool-patches
2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 20/30] test: adapt PUC Lua test for args in vararg func Sergey Kaplun via Tarantool-patches
2021-03-26 14:54   ` Sergey Kaplun via Tarantool-patches
2021-03-26 15:22     ` Sergey Ostanevich via Tarantool-patches
2021-03-31  9:51   ` Igor Munkin via Tarantool-patches
2021-04-02  7:21     ` Sergey Kaplun via Tarantool-patches
2021-04-06 20:45       ` Igor Munkin via Tarantool-patches
2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 21/30] test: disable test for getfenv in closure tailcall Sergey Kaplun via Tarantool-patches
2021-03-26 15:41   ` Sergey Ostanevich via Tarantool-patches
2021-03-31  9:51   ` Igor Munkin via Tarantool-patches
2021-04-02  7:40     ` Sergey Kaplun via Tarantool-patches
2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 22/30] test: disable PUC Lua test for var names in error Sergey Kaplun via Tarantool-patches
2021-03-26 15:44   ` Sergey Ostanevich via Tarantool-patches
2021-03-26 16:01     ` Sergey Kaplun via Tarantool-patches
2021-03-31 19:23   ` Igor Munkin via Tarantool-patches
2021-04-02  7:48     ` Sergey Kaplun via Tarantool-patches
2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 23/30] test: disable PUC Lua test for fast function name Sergey Kaplun via Tarantool-patches
2021-03-26 15:45   ` Sergey Ostanevich via Tarantool-patches
2021-03-31 19:23   ` Igor Munkin via Tarantool-patches
2021-04-02  8:14     ` Sergey Kaplun via Tarantool-patches
2021-04-06 21:37       ` Igor Munkin via Tarantool-patches
2021-04-07 16:06         ` Sergey Kaplun via Tarantool-patches
2021-04-07 16:11           ` Igor Munkin via Tarantool-patches
2021-04-07 19:57             ` Sergey Kaplun via Tarantool-patches
2021-04-12  9:36               ` Igor Munkin via Tarantool-patches
2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 24/30] test: disable PUC Lua test for non-asci identifier Sergey Kaplun via Tarantool-patches
2021-03-26 15:46   ` Sergey Ostanevich via Tarantool-patches
2021-03-31 19:23   ` Igor Munkin via Tarantool-patches
2021-04-02  8:20     ` Sergey Kaplun via Tarantool-patches
2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 25/30] test: disable PUC Lua error test for syntax level Sergey Kaplun via Tarantool-patches
2021-03-26 15:52   ` Sergey Ostanevich via Tarantool-patches
2021-03-31 19:24   ` Igor Munkin via Tarantool-patches
2021-04-02  8:30     ` Sergey Kaplun via Tarantool-patches
2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 26/30] test: disable tests with multiple -l options Sergey Kaplun via Tarantool-patches
2021-03-26 15:56   ` Sergey Ostanevich via Tarantool-patches
2021-03-31 19:24   ` Igor Munkin via Tarantool-patches
2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 27/30] test: disable PUC Lua test for checking arg layout Sergey Kaplun via Tarantool-patches
2021-03-26 15:58   ` Sergey Ostanevich via Tarantool-patches
2021-03-31 19:24   ` Igor Munkin via Tarantool-patches
2021-04-02  8:35     ` Sergey Kaplun via Tarantool-patches
2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 28/30] test: disable PUC Lua test checking -h option Sergey Kaplun via Tarantool-patches
2021-03-26 15:58   ` Sergey Ostanevich via Tarantool-patches
2021-03-31 19:24   ` Igor Munkin via Tarantool-patches
2021-04-02  8:39     ` Sergey Kaplun via Tarantool-patches
2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 29/30] test: disable PUC Lua hanging GC test Sergey Kaplun via Tarantool-patches
2021-03-26 16:03   ` Sergey Ostanevich via Tarantool-patches
2021-03-31 19:24     ` Igor Munkin via Tarantool-patches
2021-03-31 19:24   ` Igor Munkin via Tarantool-patches
2021-04-02  8:45     ` Sergey Kaplun via Tarantool-patches
2021-03-26  7:43 ` [Tarantool-patches] [PATCH v2 luajit 30/30] test: disable too depth recursive PUC Lua test Sergey Kaplun via Tarantool-patches
2021-03-26 16:28   ` Sergey Ostanevich via Tarantool-patches
2021-03-26 16:45     ` Sergey Kaplun via Tarantool-patches
2021-03-31 19:24   ` Igor Munkin via Tarantool-patches
2021-04-02  8:47     ` Sergey Kaplun via Tarantool-patches
2021-03-26 11:09 ` [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Ostanevich via Tarantool-patches
2021-03-26 14:12   ` Sergey Kaplun via Tarantool-patches
2021-03-30 22:17 ` Igor Munkin via Tarantool-patches
2021-03-31  9:41   ` Sergey Kaplun via Tarantool-patches
2021-03-31 10:49     ` Igor Munkin via Tarantool-patches

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox