Tarantool development patches archive
 help / color / mirror / Atom feed
* [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites
@ 2021-03-04 10:23 Sergey Kaplun via Tarantool-patches
  2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 01/15] test: add PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
                   ` (16 more replies)
  0 siblings, 17 replies; 26+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-04 10:23 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

WARNING: This patch doesn't require full and precise review now.

This draft should be structured (commits at least) from test
suite to test suite if necessary.

You can complain test suites with the following command, for example:
| $ diff --color -urZ test/PUC-Lua-5.1-tests/ ~/Downloads/lua5.1-tests/

Branch: https://github.com/tarantool/luajit/tree/skaplun/gh-4473-adopt-luavela-test-suites
Tarantool's branch: https://github.com/tarantool/tarantool/tree/skaplun/gh-4473-adopt-luavela-test-suites
Epic: https://github.com/tarantool/tarantool/issues/4473
Issues:
* https://github.com/tarantool/tarantool/issues/5845
* https://github.com/tarantool/tarantool/issues/4064
* https://github.com/tarantool/tarantool/issues/5844

CI is red due to ASan failure [0] for PUC-Lua-5.1 test suite.
Looks related to https://github.com/tarantool/tarantool/issues/5747,
but it is hard to tell without backtrace.

Locally, I get tons of errors like this for each of newly added test
suites:
| ==31930==WARNING: ASan is ignoring requested __asan_handle_no_return: stack top: 0x7fffbb603000; bottom 0x7f4e271fd000; size: 0x00b194406000 (762696458240)
| False positive error reports may follow
| For details see https://github.com/google/sanitizers/issues/189

After that there are failures like:

| ==24658==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7f6b741fefa8 at pc 0x000000c91926 bp 0x7f6b741fec90 sp 0x7f6b741fec88
| READ of size 8 at 0x7f6b741fefa8 thread T0
|     #0 0xc91925 in lj_strfmt_pushvf /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_strfmt.c:438:23
|     #1 0xc6f8fe in lj_err_lex /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_err.c:651:9
|     #2 0xce0fa1 in lj_lex_error /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_lex.c:495:3
|     #3 0xce3285 in err_token /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_parse.c:175:3
|     #4 0xcf27bc in parse_stmt /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_parse.c
|     #5 0xce3ceb in parse_chunk /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_parse.c:2684:14
|     #6 0xce3ceb in lj_parse /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_parse.c:2717:3
|     #7 0xc7eeaa in cpparser /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_load.c:41:29
|     #8 0xd8a6b7 in lj_vm_cpcall /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/build/third_party/luajit/src/lj_vm.S:1191
|     #9 0xc7fed6 in lua_loadx /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_load.c:58:12
|     #10 0xc7fed6 in luaL_loadbufferx /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_load.c:143:10
|     #11 0xca9b12 in lj_cf_load /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lib_base.c:401:14
|     #12 0xd8a2fa in lj_BC_FUNCC /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/build/third_party/luajit/src/lj_vm.S:811
|     #13 0xc5be1f in lua_pcall /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_api.c:1158:12
|     #14 0xb2ad71 in luaT_call /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/src/lua/utils.c:1022:6
|     #15 0xb1532c in lua_main /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/src/lua/init.c:559:11
|     #16 0xb14c9a in run_script_f /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/src/lua/init.c:634:7
|     #17 0x526d96 in fiber_cxx_invoke(int (*)(__va_list_tag*), __va_list_tag*) /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/src/lib/core/fiber.h:882:10
|     #18 0xb7f688 in fiber_loop /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/src/lib/core/fiber.c:879:18
|     #19 0x14b3b10 in coro_init /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/coro/coro.c:110:3
|
| Address 0x7f6b741fefa8 is a wild pointer.
| SUMMARY: AddressSanitizer: stack-buffer-overflow /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_strfmt.c:438:23 in lj_strfmt_pushvf
| Shadow bytes around the buggy address:
|   0x0fedee837da0: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
|   0x0fedee837db0: 00 00 00 f3 f3 f3 f3 f3 00 00 00 00 00 00 00 00
|   0x0fedee837dc0: f1 f1 f1 f1 00 00 00 00 00 00 00 04 f3 f3 f3 f3
|   0x0fedee837dd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|   0x0fedee837de0: f1 f1 f1 f1 00 00 00 f3 f3 f3 f3 f3 f2 f2 f2 f2
| =>0x0fedee837df0: f8 f8 f8 f8 f3[f3]f3 f3 00 00 00 00 00 00 00 00
|   0x0fedee837e00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|   0x0fedee837e10: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 f8 f8 f8 f2
|   0x0fedee837e20: f2 f2 f2 f2 f8 f8 f8 f2 f2 f2 f2 f2 f8 f8 f8 f8
|   0x0fedee837e30: f2 f2 f2 f2 f8 f8 f8 f2 f2 f2 f2 f2 f8 f8 f8 f2
|   0x0fedee837e40: f2 f2 f2 f2 f8 f8 f8 f2 f2 f2 f2 f2 f8 f8 f8 f2
| Shadow byte legend (one shadow byte represents 8 application bytes):
|   Addressable:           00
|   Partially addressable: 01 02 03 04 05 06 07 
|   Heap left redzone:       fa
|   Freed heap region:       fd
|   Stack left redzone:      f1
|   Stack mid redzone:       f2
|   Stack right redzone:     f3
|   Stack after return:      f5
|   Stack use after scope:   f8

It can be simply reproduce locally with:
| $ ASAN=ON LSAN_OPTIONS=suppressions=asan/lsan.supp ASAN_OPTIONS=heap_profile=0:unmap_shadow_on_exit=1:detect_invalid_pointer_pairs=1:symbolize=1:detect_leaks=1:dump_instruction_bytes=1:print_suppressions=0:asan_stack=0 src/tarantool -e 'prog = [[ do]] for _=1,3 do pcall(loadstring(string.sub(prog, 1, _))) end'

It may be the reason of failures too, see [1][2].

According to [3], there is no any way except to compile with -asan-stack
flag, but it looks like overkill. So I propose to exclude PUC-Lua-5.1
test suite from ASan job for now (at least this is out of scoupe of the
original issue).

Mergen Imeev (8):
  test: add LuaJIT-test-cleanup test suite
  test: change tests to match de5568e
  test: change tests to match c198167
  test: change tests to match 5a61e1a
  test: change LuaJIT suite tests to match b4e6bf0
  test: adjust LuaJIT test suite for Tarantool
  test: add lua-Harness test suite
  test: adjust lua-Harness test suite for Tarantool

Sergey Kaplun (7):
  test: add PUC-Rio Lua 5.1 test suite
  test: adapt PUC-Rio Lua 5.1 test suite for LuaJIT
  test: adapt Lua 5.1 test suite for Tarantool
  test: disable 305-utf8 of lua-Harness suite
  test: disable 241-standalone of lua-Harness suite
  test: disable 411-luajit of lua-Harness suite
  test: skip test for getenv in 309-os.t

 .gitignore                                    |    1 +
 .luacheckrc                                   |    7 +-
 CMakeLists.txt                                |    8 +
 test/CMakeLists.txt                           |    6 +
 test/LuaJIT-tests/CMakeLists.txt              |   20 +
 test/LuaJIT-tests/README.md                   |  110 ++
 test/LuaJIT-tests/bc/constov.lua              |   16 +
 test/LuaJIT-tests/bc/index                    |    1 +
 test/LuaJIT-tests/common/expect_error.lua     |   16 +
 test/LuaJIT-tests/common/ffi_util.inc         |   41 +
 .../common/test_runner_canary.lua             |    1 +
 test/LuaJIT-tests/computations.lua            |  113 ++
 test/LuaJIT-tests/index                       |    6 +
 test/LuaJIT-tests/lang/andor.lua              |   61 +
 test/LuaJIT-tests/lang/assignment.lua         |   46 +
 test/LuaJIT-tests/lang/compare.lua            |  323 +++++
 test/LuaJIT-tests/lang/compare_nan.lua        |   99 ++
 test/LuaJIT-tests/lang/concat.lua             |  112 ++
 test/LuaJIT-tests/lang/constant/index         |    2 +
 test/LuaJIT-tests/lang/constant/number.lua    |   12 +
 test/LuaJIT-tests/lang/constant/table.lua     |   15 +
 test/LuaJIT-tests/lang/coroutine.lua          |    8 +
 test/LuaJIT-tests/lang/for.lua                |   45 +
 test/LuaJIT-tests/lang/gc.lua                 |   42 +
 test/LuaJIT-tests/lang/goto.lua               |  149 +++
 test/LuaJIT-tests/lang/index                  |   18 +
 test/LuaJIT-tests/lang/length.lua             |   23 +
 test/LuaJIT-tests/lang/meta/arith.lua         |  118 ++
 test/LuaJIT-tests/lang/meta/arith_jit.lua     |   68 +
 test/LuaJIT-tests/lang/meta/call.lua          |   81 ++
 test/LuaJIT-tests/lang/meta/cat.lua           |   61 +
 test/LuaJIT-tests/lang/meta/comp.lua          |  120 ++
 test/LuaJIT-tests/lang/meta/comp_jit.lua      |  104 ++
 test/LuaJIT-tests/lang/meta/debuginfo.lua     |   81 ++
 test/LuaJIT-tests/lang/meta/eq.lua            |   30 +
 test/LuaJIT-tests/lang/meta/eq_jit.lua        |   35 +
 test/LuaJIT-tests/lang/meta/framegap.lua      |   24 +
 test/LuaJIT-tests/lang/meta/index             |   14 +
 test/LuaJIT-tests/lang/meta/index.lua         |   60 +
 test/LuaJIT-tests/lang/meta/len.lua           |   42 +
 test/LuaJIT-tests/lang/meta/newindex.lua      |   69 +
 test/LuaJIT-tests/lang/meta/nomm.lua          |   21 +
 test/LuaJIT-tests/lang/modulo.lua             |   46 +
 test/LuaJIT-tests/lang/self.lua               |   19 +
 test/LuaJIT-tests/lang/table.lua              |   32 +
 test/LuaJIT-tests/lang/tail_recursion.lua     |   20 +
 test/LuaJIT-tests/lang/upvalue/closure.lua    |   84 ++
 test/LuaJIT-tests/lang/upvalue/index          |    1 +
 test/LuaJIT-tests/lang/vararg_jit.lua         |   95 ++
 test/LuaJIT-tests/lib/base/assert.lua         |   33 +
 test/LuaJIT-tests/lib/base/error.lua          |   43 +
 test/LuaJIT-tests/lib/base/getfenv.lua        |   13 +
 .../LuaJIT-tests/lib/base/getsetmetatable.lua |   33 +
 test/LuaJIT-tests/lib/base/index              |   11 +
 test/LuaJIT-tests/lib/base/ipairs.lua         |   41 +
 test/LuaJIT-tests/lib/base/next.lua           |   17 +
 test/LuaJIT-tests/lib/base/pairs.lua          |   73 ++
 test/LuaJIT-tests/lib/base/pcall_jit.lua      |   74 ++
 test/LuaJIT-tests/lib/base/select.lua         |  105 ++
 .../lib/base/tonumber_tostring.lua            |   81 ++
 test/LuaJIT-tests/lib/base/xpcall_jit.lua     |   83 ++
 test/LuaJIT-tests/lib/bit.lua                 |   98 ++
 test/LuaJIT-tests/lib/contents.lua            |  171 +++
 test/LuaJIT-tests/lib/coroutine/index         |    1 +
 test/LuaJIT-tests/lib/coroutine/yield.lua     |  109 ++
 test/LuaJIT-tests/lib/ffi/bit64.lua           |  130 ++
 test/LuaJIT-tests/lib/ffi/cdata_var.lua       |   47 +
 test/LuaJIT-tests/lib/ffi/copy_fill.lua       |   64 +
 test/LuaJIT-tests/lib/ffi/err.lua             |   35 +
 test/LuaJIT-tests/lib/ffi/ffi_arith_ptr.lua   |  106 ++
 test/LuaJIT-tests/lib/ffi/ffi_bitfield.lua    |  108 ++
 test/LuaJIT-tests/lib/ffi/ffi_call.lua        |  266 ++++
 test/LuaJIT-tests/lib/ffi/ffi_callback.lua    |  158 +++
 test/LuaJIT-tests/lib/ffi/ffi_const.lua       |  113 ++
 test/LuaJIT-tests/lib/ffi/ffi_convert.lua     |  787 +++++++++++
 test/LuaJIT-tests/lib/ffi/ffi_enum.lua        |   57 +
 .../lib/ffi/ffi_gcstep_recursive.lua          |   66 +
 test/LuaJIT-tests/lib/ffi/ffi_jit_arith.lua   |  155 +++
 test/LuaJIT-tests/lib/ffi/ffi_jit_call.lua    |  154 +++
 test/LuaJIT-tests/lib/ffi/ffi_jit_conv.lua    |  277 ++++
 test/LuaJIT-tests/lib/ffi/ffi_lex_number.lua  |   51 +
 test/LuaJIT-tests/lib/ffi/ffi_metatype.lua    |  245 ++++
 test/LuaJIT-tests/lib/ffi/ffi_new.lua         |  106 ++
 test/LuaJIT-tests/lib/ffi/ffi_parse_array.lua |   78 ++
 test/LuaJIT-tests/lib/ffi/ffi_parse_basic.lua |  131 ++
 test/LuaJIT-tests/lib/ffi/ffi_parse_cdef.lua  |   77 ++
 .../LuaJIT-tests/lib/ffi/ffi_parse_struct.lua |  259 ++++
 test/LuaJIT-tests/lib/ffi/ffi_tabov.lua       |   12 +
 test/LuaJIT-tests/lib/ffi/index               |   12 +
 test/LuaJIT-tests/lib/ffi/istype.lua          |   88 ++
 test/LuaJIT-tests/lib/ffi/jit_array.lua       |  104 ++
 test/LuaJIT-tests/lib/ffi/jit_complex.lua     |  109 ++
 test/LuaJIT-tests/lib/ffi/jit_misc.lua        |  109 ++
 test/LuaJIT-tests/lib/ffi/jit_struct.lua      |  201 +++
 test/LuaJIT-tests/lib/ffi/meta_tostring.lua   |   55 +
 test/LuaJIT-tests/lib/ffi/redir.lua           |   19 +
 test/LuaJIT-tests/lib/ffi/type_punning.lua    |  138 ++
 test/LuaJIT-tests/lib/index                   |    8 +
 test/LuaJIT-tests/lib/math/abs.lua            |   16 +
 test/LuaJIT-tests/lib/math/constants.lua      |    8 +
 test/LuaJIT-tests/lib/math/index              |    3 +
 test/LuaJIT-tests/lib/math/random.lua         |   47 +
 test/LuaJIT-tests/lib/string/byte.lua         |   92 ++
 test/LuaJIT-tests/lib/string/char.lua         |   29 +
 test/LuaJIT-tests/lib/string/dump.lua         |   31 +
 test/LuaJIT-tests/lib/string/format/index     |    1 +
 test/LuaJIT-tests/lib/string/format/num.lua   |  184 +++
 test/LuaJIT-tests/lib/string/index            |   11 +
 test/LuaJIT-tests/lib/string/len.lua          |   14 +
 test/LuaJIT-tests/lib/string/lower_upper.lua  |   51 +
 test/LuaJIT-tests/lib/string/metatable.lua    |    3 +
 .../lib/string/multiple_functions.lua         |   16 +
 test/LuaJIT-tests/lib/string/rep.lua          |   68 +
 test/LuaJIT-tests/lib/string/reverse.lua      |   13 +
 test/LuaJIT-tests/lib/string/sub.lua          |  189 +++
 test/LuaJIT-tests/lib/table/concat.lua        |   55 +
 test/LuaJIT-tests/lib/table/index             |    6 +
 test/LuaJIT-tests/lib/table/insert.lua        |   17 +
 test/LuaJIT-tests/lib/table/misc.lua          |   58 +
 test/LuaJIT-tests/lib/table/new.lua           |   11 +
 test/LuaJIT-tests/lib/table/pack.lua          |    7 +
 test/LuaJIT-tests/lib/table/remove.lua        |   42 +
 test/LuaJIT-tests/lib/table/sort.lua          |   27 +
 test/LuaJIT-tests/misc/alias_alloc.lua        |   54 +
 test/LuaJIT-tests/misc/api_call.lua           |   98 ++
 test/LuaJIT-tests/misc/catch_wrap.lua         |   45 +
 test/LuaJIT-tests/misc/coro_traceback.lua     |    8 +
 test/LuaJIT-tests/misc/coro_yield.lua         |  111 ++
 test/LuaJIT-tests/misc/debug_gc.lua           |   47 +
 test/LuaJIT-tests/misc/dualnum.lua            |   47 +
 test/LuaJIT-tests/misc/for_dir.lua            |   13 +
 test/LuaJIT-tests/misc/fori_coerce.lua        |   33 +
 test/LuaJIT-tests/misc/gc_rechain.lua         |   32 +
 test/LuaJIT-tests/misc/gc_trace.lua           |   37 +
 test/LuaJIT-tests/misc/gcstep.lua             |   33 +
 test/LuaJIT-tests/misc/hook_active.lua        |   95 ++
 test/LuaJIT-tests/misc/hook_line.lua          |   41 +
 test/LuaJIT-tests/misc/hook_norecord.lua      |   12 +
 test/LuaJIT-tests/misc/hook_record.lua        |    8 +
 test/LuaJIT-tests/misc/hook_top.lua           |   55 +
 test/LuaJIT-tests/misc/jit_flush.lua          |   50 +
 test/LuaJIT-tests/misc/lightud.lua            |   88 ++
 test/LuaJIT-tests/misc/loop_unroll.lua        |   35 +
 test/LuaJIT-tests/misc/parse_comp.lua         |   13 +
 test/LuaJIT-tests/misc/parse_esc.lua          |    7 +
 test/LuaJIT-tests/misc/parse_misc.lua         |   31 +
 test/LuaJIT-tests/misc/phi_conv.lua           |   53 +
 test/LuaJIT-tests/misc/recurse_deep.lua       |   29 +
 test/LuaJIT-tests/misc/recurse_tail.lua       |   22 +
 test/LuaJIT-tests/misc/stack_gc.lua           |   15 +
 test/LuaJIT-tests/misc/stack_purge.lua        |   25 +
 test/LuaJIT-tests/misc/stackov.lua            |   40 +
 test/LuaJIT-tests/misc/stackovc.lua           |    4 +
 test/LuaJIT-tests/misc/tcall_base.lua         |   20 +
 test/LuaJIT-tests/misc/tcall_loop.lua         |    8 +
 test/LuaJIT-tests/misc/tonumber_scan.lua      |  180 +++
 test/LuaJIT-tests/misc/uclo.lua               |   91 ++
 test/LuaJIT-tests/misc/unordered_jit.lua      |   96 ++
 test/LuaJIT-tests/misc/wbarrier.lua           |    7 +
 test/LuaJIT-tests/misc/wbarrier_jit.lua       |   18 +
 test/LuaJIT-tests/misc/wbarrier_obar.lua      |   22 +
 test/LuaJIT-tests/opt/dse/array.lua           |  197 +++
 test/LuaJIT-tests/opt/dse/field.lua           |   70 +
 test/LuaJIT-tests/opt/dse/index               |    2 +
 test/LuaJIT-tests/opt/fold/index              |    1 +
 test/LuaJIT-tests/opt/fold/kfold.lua          |   81 ++
 test/LuaJIT-tests/opt/fuse.lua                |    5 +
 test/LuaJIT-tests/opt/fwd/hrefk_rollback.lua  |   32 +
 test/LuaJIT-tests/opt/fwd/index               |    3 +
 test/LuaJIT-tests/opt/fwd/tnew_tdup.lua       |   69 +
 test/LuaJIT-tests/opt/fwd/upval.lua           |   50 +
 test/LuaJIT-tests/opt/index                   |    6 +
 test/LuaJIT-tests/opt/loop/index              |    1 +
 test/LuaJIT-tests/opt/loop/unroll.lua         |   32 +
 test/LuaJIT-tests/opt/sink/alloc.lua          |  126 ++
 test/LuaJIT-tests/opt/sink/ffi.lua            |  121 ++
 test/LuaJIT-tests/opt/sink/ffi_nosink.lua     |   45 +
 test/LuaJIT-tests/opt/sink/index              |    4 +
 test/LuaJIT-tests/opt/sink/nosink.lua         |  109 ++
 test/LuaJIT-tests/src/cpptest.cpp             |  129 ++
 test/LuaJIT-tests/src/ctest.c                 |  339 +++++
 test/LuaJIT-tests/sysdep/catch_cpp.lua        |   71 +
 test/LuaJIT-tests/sysdep/ffi_include_gtk.lua  |    9 +
 test/LuaJIT-tests/sysdep/ffi_include_std.lua  |   36 +
 test/LuaJIT-tests/sysdep/ffi_lib_c.lua        |   87 ++
 test/LuaJIT-tests/sysdep/ffi_lib_z.lua        |  107 ++
 test/LuaJIT-tests/test.lua                    |  416 ++++++
 test/LuaJIT-tests/trace/exit_frame.lua        |   79 ++
 test/LuaJIT-tests/trace/exit_growstack.lua    |   28 +
 test/LuaJIT-tests/trace/exit_jfuncf.lua       |   30 +
 test/LuaJIT-tests/trace/gc64_slot_revival.lua |   18 +
 test/LuaJIT-tests/trace/index                 |    7 +
 test/LuaJIT-tests/trace/phi/copyspill.lua     |   53 +
 test/LuaJIT-tests/trace/phi/index             |    3 +
 test/LuaJIT-tests/trace/phi/ref.lua           |  131 ++
 test/LuaJIT-tests/trace/phi/rotate.lua        |  149 +++
 test/LuaJIT-tests/trace/snap.lua              |   47 +
 test/LuaJIT-tests/trace/stitch.lua            |   19 +
 .../unportable/ffi_arith_int64.lua            |   68 +
 test/LuaJIT-tests/unportable/math_special.lua |   55 +
 test/PUC-Lua-5.1-tests/CMakeLists.txt         |   92 ++
 test/PUC-Lua-5.1-tests/README                 |   41 +
 test/PUC-Lua-5.1-tests/all.lua                |  145 +++
 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            |  432 +++++++
 test/PUC-Lua-5.1-tests/code.lua               |  143 ++
 test/PUC-Lua-5.1-tests/constructs.lua         |  247 ++++
 test/PUC-Lua-5.1-tests/db.lua                 |  538 ++++++++
 test/PUC-Lua-5.1-tests/errors.lua             |  264 ++++
 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                 |  320 +++++
 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               |  195 +++
 test/PUC-Lua-5.1-tests/math.lua               |  213 +++
 test/PUC-Lua-5.1-tests/nextvar.lua            |  403 ++++++
 test/PUC-Lua-5.1-tests/pm.lua                 |  281 ++++
 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 ++
 test/lua-Harness-tests/000-sanity.t           |   54 +
 test/lua-Harness-tests/001-if.t               |   88 ++
 test/lua-Harness-tests/002-table.t            |   67 +
 test/lua-Harness-tests/011-while.t            |   89 ++
 test/lua-Harness-tests/012-repeat.t           |   85 ++
 test/lua-Harness-tests/014-fornum.t           |  151 +++
 test/lua-Harness-tests/015-forlist.t          |  111 ++
 test/lua-Harness-tests/090-tap.t              |   37 +
 test/lua-Harness-tests/091-profile.t          |   45 +
 test/lua-Harness-tests/101-boolean.t          |  127 ++
 test/lua-Harness-tests/102-function.t         |  206 +++
 test/lua-Harness-tests/103-nil.t              |  127 ++
 test/lua-Harness-tests/104-number.t           |  246 ++++
 test/lua-Harness-tests/105-string.t           |  277 ++++
 test/lua-Harness-tests/106-table.t            |  135 ++
 test/lua-Harness-tests/107-thread.t           |  135 ++
 test/lua-Harness-tests/108-userdata.t         |  132 ++
 test/lua-Harness-tests/200-examples.t         |  104 ++
 test/lua-Harness-tests/201-assign.t           |  150 +++
 test/lua-Harness-tests/202-expr.t             |  157 +++
 test/lua-Harness-tests/203-lexico.t           |  147 +++
 test/lua-Harness-tests/204-grammar.t          |  233 ++++
 test/lua-Harness-tests/211-scope.t            |   86 ++
 test/lua-Harness-tests/212-function.t         |  288 +++++
 test/lua-Harness-tests/213-closure.t          |   98 ++
 test/lua-Harness-tests/214-coroutine.t        |  244 ++++
 test/lua-Harness-tests/221-table.t            |  120 ++
 test/lua-Harness-tests/222-constructor.t      |  119 ++
 test/lua-Harness-tests/223-iterator.t         |  203 +++
 test/lua-Harness-tests/231-metatable.t        |  602 +++++++++
 test/lua-Harness-tests/232-object.t           |  314 +++++
 .../241-standalone.t.disabled                 |  269 ++++
 test/lua-Harness-tests/242-luac.t             |  341 +++++
 test/lua-Harness-tests/301-basic.t            |  859 ++++++++++++
 test/lua-Harness-tests/303-package.t          |  290 +++++
 test/lua-Harness-tests/304-string.t           |  633 +++++++++
 test/lua-Harness-tests/305-utf8.t.disabled    |   55 +
 test/lua-Harness-tests/306-table.t            |  372 ++++++
 test/lua-Harness-tests/307-math.t             |  375 ++++++
 test/lua-Harness-tests/308-io.t               |  397 ++++++
 test/lua-Harness-tests/309-os.t               |  275 ++++
 test/lua-Harness-tests/310-debug.t            |  322 +++++
 test/lua-Harness-tests/311-bit32.t            |  127 ++
 test/lua-Harness-tests/314-regex.t            |  222 ++++
 test/lua-Harness-tests/320-stdin.t            |  133 ++
 test/lua-Harness-tests/401-bitop.t            |  106 ++
 test/lua-Harness-tests/402-ffi.t              |  142 ++
 test/lua-Harness-tests/403-jit.t              |  163 +++
 test/lua-Harness-tests/404-ext.t              |  171 +++
 test/lua-Harness-tests/411-luajit.t.disabled  |  211 +++
 test/lua-Harness-tests/CMakeLists.txt         |   62 +
 test/lua-Harness-tests/lexico52/lexico.t      |   45 +
 test/lua-Harness-tests/lexico53/boolean.t     |   43 +
 test/lua-Harness-tests/lexico53/function.t    |   66 +
 test/lua-Harness-tests/lexico53/lexico.t      |   30 +
 test/lua-Harness-tests/lexico53/nil.t         |   43 +
 test/lua-Harness-tests/lexico53/number.t      |  181 +++
 test/lua-Harness-tests/lexico53/string.t      |  169 +++
 test/lua-Harness-tests/lexico53/table.t       |   43 +
 test/lua-Harness-tests/lexico53/thread.t      |   45 +
 test/lua-Harness-tests/lexico53/userdata.t    |   45 +
 test/lua-Harness-tests/lexico53/utf8.t        |  179 +++
 test/lua-Harness-tests/lexico54/lexico.t      |   19 +
 test/lua-Harness-tests/lexico54/metatable.t   |   38 +
 test/lua-Harness-tests/lexico54/utf8.t        |   54 +
 test/lua-Harness-tests/lexicojit/basic.t      |   27 +
 test/lua-Harness-tests/lexicojit/ext.t        |   52 +
 test/lua-Harness-tests/lexicojit/lexico.t     |   32 +
 test/lua-Harness-tests/profile.lua            |   53 +
 test/lua-Harness-tests/profile_lua51.lua      |   46 +
 .../profile_lua51_strict.lua                  |   46 +
 test/lua-Harness-tests/profile_lua52.lua      |   46 +
 .../profile_lua52_strict.lua                  |   46 +
 test/lua-Harness-tests/profile_lua53.lua      |   52 +
 .../profile_lua53_noconv.lua                  |   55 +
 .../profile_lua53_strict.lua                  |   52 +
 test/lua-Harness-tests/profile_lua54.lua      |   52 +
 .../profile_lua54_noconv.lua                  |   55 +
 .../profile_lua54_strict.lua                  |   53 +
 test/lua-Harness-tests/profile_luajit20.lua   |   53 +
 .../profile_luajit20_compat52.lua             |   53 +
 test/lua-Harness-tests/profile_luajit21.lua   |   53 +
 .../profile_luajit21_compat52.lua             |   53 +
 test/lua-Harness-tests/profile_openresty.lua  |   53 +
 test/lua-Harness-tests/profile_ravi.lua       |   58 +
 test/lua-Harness-tests/profile_tiny_fork.lua  |   60 +
 test/lua-Harness-tests/rx_captures            |   13 +
 test/lua-Harness-tests/rx_charclass           |   38 +
 test/lua-Harness-tests/rx_metachars           |  117 ++
 test/lua-Harness-tests/tap_harness.lua        |  204 +++
 322 files changed, 34168 insertions(+), 2 deletions(-)
 create mode 100644 test/LuaJIT-tests/CMakeLists.txt
 create mode 100644 test/LuaJIT-tests/README.md
 create mode 100644 test/LuaJIT-tests/bc/constov.lua
 create mode 100644 test/LuaJIT-tests/bc/index
 create mode 100644 test/LuaJIT-tests/common/expect_error.lua
 create mode 100644 test/LuaJIT-tests/common/ffi_util.inc
 create mode 100644 test/LuaJIT-tests/common/test_runner_canary.lua
 create mode 100644 test/LuaJIT-tests/computations.lua
 create mode 100644 test/LuaJIT-tests/index
 create mode 100644 test/LuaJIT-tests/lang/andor.lua
 create mode 100644 test/LuaJIT-tests/lang/assignment.lua
 create mode 100644 test/LuaJIT-tests/lang/compare.lua
 create mode 100644 test/LuaJIT-tests/lang/compare_nan.lua
 create mode 100644 test/LuaJIT-tests/lang/concat.lua
 create mode 100644 test/LuaJIT-tests/lang/constant/index
 create mode 100644 test/LuaJIT-tests/lang/constant/number.lua
 create mode 100644 test/LuaJIT-tests/lang/constant/table.lua
 create mode 100644 test/LuaJIT-tests/lang/coroutine.lua
 create mode 100644 test/LuaJIT-tests/lang/for.lua
 create mode 100644 test/LuaJIT-tests/lang/gc.lua
 create mode 100644 test/LuaJIT-tests/lang/goto.lua
 create mode 100644 test/LuaJIT-tests/lang/index
 create mode 100644 test/LuaJIT-tests/lang/length.lua
 create mode 100644 test/LuaJIT-tests/lang/meta/arith.lua
 create mode 100644 test/LuaJIT-tests/lang/meta/arith_jit.lua
 create mode 100644 test/LuaJIT-tests/lang/meta/call.lua
 create mode 100644 test/LuaJIT-tests/lang/meta/cat.lua
 create mode 100644 test/LuaJIT-tests/lang/meta/comp.lua
 create mode 100644 test/LuaJIT-tests/lang/meta/comp_jit.lua
 create mode 100644 test/LuaJIT-tests/lang/meta/debuginfo.lua
 create mode 100644 test/LuaJIT-tests/lang/meta/eq.lua
 create mode 100644 test/LuaJIT-tests/lang/meta/eq_jit.lua
 create mode 100644 test/LuaJIT-tests/lang/meta/framegap.lua
 create mode 100644 test/LuaJIT-tests/lang/meta/index
 create mode 100644 test/LuaJIT-tests/lang/meta/index.lua
 create mode 100644 test/LuaJIT-tests/lang/meta/len.lua
 create mode 100644 test/LuaJIT-tests/lang/meta/newindex.lua
 create mode 100644 test/LuaJIT-tests/lang/meta/nomm.lua
 create mode 100644 test/LuaJIT-tests/lang/modulo.lua
 create mode 100644 test/LuaJIT-tests/lang/self.lua
 create mode 100644 test/LuaJIT-tests/lang/table.lua
 create mode 100644 test/LuaJIT-tests/lang/tail_recursion.lua
 create mode 100644 test/LuaJIT-tests/lang/upvalue/closure.lua
 create mode 100644 test/LuaJIT-tests/lang/upvalue/index
 create mode 100644 test/LuaJIT-tests/lang/vararg_jit.lua
 create mode 100644 test/LuaJIT-tests/lib/base/assert.lua
 create mode 100644 test/LuaJIT-tests/lib/base/error.lua
 create mode 100644 test/LuaJIT-tests/lib/base/getfenv.lua
 create mode 100644 test/LuaJIT-tests/lib/base/getsetmetatable.lua
 create mode 100644 test/LuaJIT-tests/lib/base/index
 create mode 100644 test/LuaJIT-tests/lib/base/ipairs.lua
 create mode 100644 test/LuaJIT-tests/lib/base/next.lua
 create mode 100644 test/LuaJIT-tests/lib/base/pairs.lua
 create mode 100644 test/LuaJIT-tests/lib/base/pcall_jit.lua
 create mode 100644 test/LuaJIT-tests/lib/base/select.lua
 create mode 100644 test/LuaJIT-tests/lib/base/tonumber_tostring.lua
 create mode 100644 test/LuaJIT-tests/lib/base/xpcall_jit.lua
 create mode 100644 test/LuaJIT-tests/lib/bit.lua
 create mode 100644 test/LuaJIT-tests/lib/contents.lua
 create mode 100644 test/LuaJIT-tests/lib/coroutine/index
 create mode 100644 test/LuaJIT-tests/lib/coroutine/yield.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/bit64.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/cdata_var.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/copy_fill.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/err.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_arith_ptr.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_bitfield.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_call.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_callback.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_const.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_convert.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_enum.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_gcstep_recursive.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_jit_arith.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_jit_call.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_jit_conv.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_lex_number.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_metatype.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_new.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_parse_array.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_parse_basic.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_parse_cdef.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_parse_struct.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_tabov.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/index
 create mode 100644 test/LuaJIT-tests/lib/ffi/istype.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/jit_array.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/jit_complex.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/jit_misc.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/jit_struct.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/meta_tostring.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/redir.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/type_punning.lua
 create mode 100644 test/LuaJIT-tests/lib/index
 create mode 100644 test/LuaJIT-tests/lib/math/abs.lua
 create mode 100644 test/LuaJIT-tests/lib/math/constants.lua
 create mode 100644 test/LuaJIT-tests/lib/math/index
 create mode 100644 test/LuaJIT-tests/lib/math/random.lua
 create mode 100644 test/LuaJIT-tests/lib/string/byte.lua
 create mode 100644 test/LuaJIT-tests/lib/string/char.lua
 create mode 100644 test/LuaJIT-tests/lib/string/dump.lua
 create mode 100644 test/LuaJIT-tests/lib/string/format/index
 create mode 100644 test/LuaJIT-tests/lib/string/format/num.lua
 create mode 100644 test/LuaJIT-tests/lib/string/index
 create mode 100644 test/LuaJIT-tests/lib/string/len.lua
 create mode 100644 test/LuaJIT-tests/lib/string/lower_upper.lua
 create mode 100644 test/LuaJIT-tests/lib/string/metatable.lua
 create mode 100644 test/LuaJIT-tests/lib/string/multiple_functions.lua
 create mode 100644 test/LuaJIT-tests/lib/string/rep.lua
 create mode 100644 test/LuaJIT-tests/lib/string/reverse.lua
 create mode 100644 test/LuaJIT-tests/lib/string/sub.lua
 create mode 100644 test/LuaJIT-tests/lib/table/concat.lua
 create mode 100644 test/LuaJIT-tests/lib/table/index
 create mode 100644 test/LuaJIT-tests/lib/table/insert.lua
 create mode 100644 test/LuaJIT-tests/lib/table/misc.lua
 create mode 100644 test/LuaJIT-tests/lib/table/new.lua
 create mode 100644 test/LuaJIT-tests/lib/table/pack.lua
 create mode 100644 test/LuaJIT-tests/lib/table/remove.lua
 create mode 100644 test/LuaJIT-tests/lib/table/sort.lua
 create mode 100644 test/LuaJIT-tests/misc/alias_alloc.lua
 create mode 100644 test/LuaJIT-tests/misc/api_call.lua
 create mode 100644 test/LuaJIT-tests/misc/catch_wrap.lua
 create mode 100644 test/LuaJIT-tests/misc/coro_traceback.lua
 create mode 100644 test/LuaJIT-tests/misc/coro_yield.lua
 create mode 100644 test/LuaJIT-tests/misc/debug_gc.lua
 create mode 100644 test/LuaJIT-tests/misc/dualnum.lua
 create mode 100644 test/LuaJIT-tests/misc/for_dir.lua
 create mode 100644 test/LuaJIT-tests/misc/fori_coerce.lua
 create mode 100644 test/LuaJIT-tests/misc/gc_rechain.lua
 create mode 100644 test/LuaJIT-tests/misc/gc_trace.lua
 create mode 100644 test/LuaJIT-tests/misc/gcstep.lua
 create mode 100644 test/LuaJIT-tests/misc/hook_active.lua
 create mode 100644 test/LuaJIT-tests/misc/hook_line.lua
 create mode 100644 test/LuaJIT-tests/misc/hook_norecord.lua
 create mode 100644 test/LuaJIT-tests/misc/hook_record.lua
 create mode 100644 test/LuaJIT-tests/misc/hook_top.lua
 create mode 100644 test/LuaJIT-tests/misc/jit_flush.lua
 create mode 100644 test/LuaJIT-tests/misc/lightud.lua
 create mode 100644 test/LuaJIT-tests/misc/loop_unroll.lua
 create mode 100644 test/LuaJIT-tests/misc/parse_comp.lua
 create mode 100644 test/LuaJIT-tests/misc/parse_esc.lua
 create mode 100644 test/LuaJIT-tests/misc/parse_misc.lua
 create mode 100644 test/LuaJIT-tests/misc/phi_conv.lua
 create mode 100644 test/LuaJIT-tests/misc/recurse_deep.lua
 create mode 100644 test/LuaJIT-tests/misc/recurse_tail.lua
 create mode 100644 test/LuaJIT-tests/misc/stack_gc.lua
 create mode 100644 test/LuaJIT-tests/misc/stack_purge.lua
 create mode 100644 test/LuaJIT-tests/misc/stackov.lua
 create mode 100644 test/LuaJIT-tests/misc/stackovc.lua
 create mode 100644 test/LuaJIT-tests/misc/tcall_base.lua
 create mode 100644 test/LuaJIT-tests/misc/tcall_loop.lua
 create mode 100644 test/LuaJIT-tests/misc/tonumber_scan.lua
 create mode 100644 test/LuaJIT-tests/misc/uclo.lua
 create mode 100644 test/LuaJIT-tests/misc/unordered_jit.lua
 create mode 100644 test/LuaJIT-tests/misc/wbarrier.lua
 create mode 100644 test/LuaJIT-tests/misc/wbarrier_jit.lua
 create mode 100644 test/LuaJIT-tests/misc/wbarrier_obar.lua
 create mode 100644 test/LuaJIT-tests/opt/dse/array.lua
 create mode 100644 test/LuaJIT-tests/opt/dse/field.lua
 create mode 100644 test/LuaJIT-tests/opt/dse/index
 create mode 100644 test/LuaJIT-tests/opt/fold/index
 create mode 100644 test/LuaJIT-tests/opt/fold/kfold.lua
 create mode 100644 test/LuaJIT-tests/opt/fuse.lua
 create mode 100644 test/LuaJIT-tests/opt/fwd/hrefk_rollback.lua
 create mode 100644 test/LuaJIT-tests/opt/fwd/index
 create mode 100644 test/LuaJIT-tests/opt/fwd/tnew_tdup.lua
 create mode 100644 test/LuaJIT-tests/opt/fwd/upval.lua
 create mode 100644 test/LuaJIT-tests/opt/index
 create mode 100644 test/LuaJIT-tests/opt/loop/index
 create mode 100644 test/LuaJIT-tests/opt/loop/unroll.lua
 create mode 100644 test/LuaJIT-tests/opt/sink/alloc.lua
 create mode 100644 test/LuaJIT-tests/opt/sink/ffi.lua
 create mode 100644 test/LuaJIT-tests/opt/sink/ffi_nosink.lua
 create mode 100644 test/LuaJIT-tests/opt/sink/index
 create mode 100644 test/LuaJIT-tests/opt/sink/nosink.lua
 create mode 100644 test/LuaJIT-tests/src/cpptest.cpp
 create mode 100644 test/LuaJIT-tests/src/ctest.c
 create mode 100644 test/LuaJIT-tests/sysdep/catch_cpp.lua
 create mode 100644 test/LuaJIT-tests/sysdep/ffi_include_gtk.lua
 create mode 100644 test/LuaJIT-tests/sysdep/ffi_include_std.lua
 create mode 100644 test/LuaJIT-tests/sysdep/ffi_lib_c.lua
 create mode 100644 test/LuaJIT-tests/sysdep/ffi_lib_z.lua
 create mode 100644 test/LuaJIT-tests/test.lua
 create mode 100644 test/LuaJIT-tests/trace/exit_frame.lua
 create mode 100644 test/LuaJIT-tests/trace/exit_growstack.lua
 create mode 100644 test/LuaJIT-tests/trace/exit_jfuncf.lua
 create mode 100644 test/LuaJIT-tests/trace/gc64_slot_revival.lua
 create mode 100644 test/LuaJIT-tests/trace/index
 create mode 100644 test/LuaJIT-tests/trace/phi/copyspill.lua
 create mode 100644 test/LuaJIT-tests/trace/phi/index
 create mode 100644 test/LuaJIT-tests/trace/phi/ref.lua
 create mode 100644 test/LuaJIT-tests/trace/phi/rotate.lua
 create mode 100644 test/LuaJIT-tests/trace/snap.lua
 create mode 100644 test/LuaJIT-tests/trace/stitch.lua
 create mode 100644 test/LuaJIT-tests/unportable/ffi_arith_int64.lua
 create mode 100644 test/LuaJIT-tests/unportable/math_special.lua
 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/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
 create mode 100755 test/lua-Harness-tests/000-sanity.t
 create mode 100755 test/lua-Harness-tests/001-if.t
 create mode 100755 test/lua-Harness-tests/002-table.t
 create mode 100755 test/lua-Harness-tests/011-while.t
 create mode 100755 test/lua-Harness-tests/012-repeat.t
 create mode 100755 test/lua-Harness-tests/014-fornum.t
 create mode 100755 test/lua-Harness-tests/015-forlist.t
 create mode 100755 test/lua-Harness-tests/090-tap.t
 create mode 100755 test/lua-Harness-tests/091-profile.t
 create mode 100755 test/lua-Harness-tests/101-boolean.t
 create mode 100755 test/lua-Harness-tests/102-function.t
 create mode 100755 test/lua-Harness-tests/103-nil.t
 create mode 100755 test/lua-Harness-tests/104-number.t
 create mode 100755 test/lua-Harness-tests/105-string.t
 create mode 100755 test/lua-Harness-tests/106-table.t
 create mode 100755 test/lua-Harness-tests/107-thread.t
 create mode 100755 test/lua-Harness-tests/108-userdata.t
 create mode 100755 test/lua-Harness-tests/200-examples.t
 create mode 100755 test/lua-Harness-tests/201-assign.t
 create mode 100755 test/lua-Harness-tests/202-expr.t
 create mode 100755 test/lua-Harness-tests/203-lexico.t
 create mode 100755 test/lua-Harness-tests/204-grammar.t
 create mode 100755 test/lua-Harness-tests/211-scope.t
 create mode 100755 test/lua-Harness-tests/212-function.t
 create mode 100755 test/lua-Harness-tests/213-closure.t
 create mode 100755 test/lua-Harness-tests/214-coroutine.t
 create mode 100755 test/lua-Harness-tests/221-table.t
 create mode 100755 test/lua-Harness-tests/222-constructor.t
 create mode 100755 test/lua-Harness-tests/223-iterator.t
 create mode 100755 test/lua-Harness-tests/231-metatable.t
 create mode 100755 test/lua-Harness-tests/232-object.t
 create mode 100755 test/lua-Harness-tests/241-standalone.t.disabled
 create mode 100755 test/lua-Harness-tests/242-luac.t
 create mode 100755 test/lua-Harness-tests/301-basic.t
 create mode 100755 test/lua-Harness-tests/303-package.t
 create mode 100755 test/lua-Harness-tests/304-string.t
 create mode 100755 test/lua-Harness-tests/305-utf8.t.disabled
 create mode 100755 test/lua-Harness-tests/306-table.t
 create mode 100755 test/lua-Harness-tests/307-math.t
 create mode 100755 test/lua-Harness-tests/308-io.t
 create mode 100755 test/lua-Harness-tests/309-os.t
 create mode 100755 test/lua-Harness-tests/310-debug.t
 create mode 100755 test/lua-Harness-tests/311-bit32.t
 create mode 100755 test/lua-Harness-tests/314-regex.t
 create mode 100755 test/lua-Harness-tests/320-stdin.t
 create mode 100755 test/lua-Harness-tests/401-bitop.t
 create mode 100755 test/lua-Harness-tests/402-ffi.t
 create mode 100755 test/lua-Harness-tests/403-jit.t
 create mode 100755 test/lua-Harness-tests/404-ext.t
 create mode 100755 test/lua-Harness-tests/411-luajit.t.disabled
 create mode 100644 test/lua-Harness-tests/CMakeLists.txt
 create mode 100644 test/lua-Harness-tests/lexico52/lexico.t
 create mode 100644 test/lua-Harness-tests/lexico53/boolean.t
 create mode 100644 test/lua-Harness-tests/lexico53/function.t
 create mode 100644 test/lua-Harness-tests/lexico53/lexico.t
 create mode 100644 test/lua-Harness-tests/lexico53/nil.t
 create mode 100644 test/lua-Harness-tests/lexico53/number.t
 create mode 100644 test/lua-Harness-tests/lexico53/string.t
 create mode 100644 test/lua-Harness-tests/lexico53/table.t
 create mode 100644 test/lua-Harness-tests/lexico53/thread.t
 create mode 100644 test/lua-Harness-tests/lexico53/userdata.t
 create mode 100644 test/lua-Harness-tests/lexico53/utf8.t
 create mode 100644 test/lua-Harness-tests/lexico54/lexico.t
 create mode 100644 test/lua-Harness-tests/lexico54/metatable.t
 create mode 100644 test/lua-Harness-tests/lexico54/utf8.t
 create mode 100644 test/lua-Harness-tests/lexicojit/basic.t
 create mode 100644 test/lua-Harness-tests/lexicojit/ext.t
 create mode 100644 test/lua-Harness-tests/lexicojit/lexico.t
 create mode 100644 test/lua-Harness-tests/profile.lua
 create mode 100644 test/lua-Harness-tests/profile_lua51.lua
 create mode 100644 test/lua-Harness-tests/profile_lua51_strict.lua
 create mode 100644 test/lua-Harness-tests/profile_lua52.lua
 create mode 100644 test/lua-Harness-tests/profile_lua52_strict.lua
 create mode 100644 test/lua-Harness-tests/profile_lua53.lua
 create mode 100644 test/lua-Harness-tests/profile_lua53_noconv.lua
 create mode 100644 test/lua-Harness-tests/profile_lua53_strict.lua
 create mode 100644 test/lua-Harness-tests/profile_lua54.lua
 create mode 100644 test/lua-Harness-tests/profile_lua54_noconv.lua
 create mode 100644 test/lua-Harness-tests/profile_lua54_strict.lua
 create mode 100644 test/lua-Harness-tests/profile_luajit20.lua
 create mode 100644 test/lua-Harness-tests/profile_luajit20_compat52.lua
 create mode 100644 test/lua-Harness-tests/profile_luajit21.lua
 create mode 100644 test/lua-Harness-tests/profile_luajit21_compat52.lua
 create mode 100644 test/lua-Harness-tests/profile_openresty.lua
 create mode 100644 test/lua-Harness-tests/profile_ravi.lua
 create mode 100644 test/lua-Harness-tests/profile_tiny_fork.lua
 create mode 100644 test/lua-Harness-tests/rx_captures
 create mode 100644 test/lua-Harness-tests/rx_charclass
 create mode 100644 test/lua-Harness-tests/rx_metachars
 create mode 100644 test/lua-Harness-tests/tap_harness.lua

-- 
2.28.0

[0]: https://github.com/tarantool/tarantool/runs/2029452344
[1]: https://github.com/google/sanitizers/issues/980
[2]: https://github.com/google/sanitizers/issues/189
[3]: https://github.com/google/sanitizers/wiki/AddressSanitizerFlags

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

* [Tarantool-patches] [WIP luajit 01/15] test: add PUC-Rio Lua 5.1 test suite
  2021-03-04 10:23 [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites Sergey Kaplun via Tarantool-patches
@ 2021-03-04 10:23 ` Sergey Kaplun via Tarantool-patches
  2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 02/15] test: adapt PUC-Rio Lua 5.1 test suite for LuaJIT Sergey Kaplun via Tarantool-patches
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-04 10:23 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: 210272 bytes --]

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

<lib1.c> and <lib2.c> is slightly modified to be consistent with the
current LuaJIT's LuaC API.

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 |   89 ++
 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/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 +++
 34 files changed, 7782 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/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 0a5d001..d49301b 100644
--- a/.luacheckrc
+++ b/.luacheckrc
@@ -3,9 +3,10 @@ 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/PUC-Lua-5.1-tests/',
 }
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index d166c9d..8e6b4f9 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -32,9 +32,11 @@ else()
   )
 endif()
 
+add_subdirectory(PUC-Lua-5.1-tests)
 add_subdirectory(tarantool-tests)
 
 add_custom_target(${PROJECT_NAME}-test DEPENDS
+  PUC-Lua-5.1-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..ed32a84
--- /dev/null
+++ b/test/PUC-Lua-5.1-tests/CMakeLists.txt
@@ -0,0 +1,89 @@
+# Test suite that has been added from PUC-Rio Lua 5.1 test archive
+# in scope of https://github.com/tarantool/tarantool/issues/4473.
+
+# See the rationale in the root CMakeLists.txt.
+cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
+
+set(TEST_RUNNER  ${CMAKE_CURRENT_SOURCE_DIR}/all.lua)
+set(LIB_SOURCES  ${CMAKE_CURRENT_SOURCE_DIR}/libs)
+set(TESTLIB_PATH ${CMAKE_CURRENT_BINARY_DIR}/libs)
+
+# XXX: -fPIC is required to linking with static library.
+if(NOT BUILDMODE STREQUAL "static")
+  # Build additional C libraries for tests.
+  macro(build_lib 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 "${TESTLIB_PATH}"
+      PREFIX ""
+    )
+    if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+      set_target_properties(${lib} PROPERTIES
+        LINK_FLAGS "-undefined dynamic_lookup"
+      )
+    endif()
+    target_link_libraries(${lib} PRIVATE libluajit_shared)
+    list(APPEND TESTLIBS ${lib})
+  endmacro()
+
+  build_lib(lib1  ${LIB_SOURCES}/lib1.c)
+  build_lib(lib11 ${LIB_SOURCES}/lib1.c ${LIB_SOURCES}/lib11.c)
+  build_lib(lib2  ${LIB_SOURCES}/lib2.c)
+  build_lib(lib21 ${LIB_SOURCES}/lib2.c ${LIB_SOURCES}/lib21.c)
+
+  set(LIB2COPY "${TESTLIB_PATH}/lib2${CMAKE_SHARED_LIBRARY_SUFFIX}")
+  set(LIB_COPY "${TESTLIB_PATH}/-lib2${CMAKE_SHARED_LIBRARY_SUFFIX}")
+
+  add_custom_command(
+    COMMENT "Copping lib2 to -lib2 for PUC-Rio Lua 5.1 tests"
+    OUTPUT  ${LIB_COPY}
+    DEPENDS ${TESTLIBS}
+    COMMAND ${CMAKE_COMMAND} -E copy ${LIB2COPY} ${LIB_COPY}
+    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+  )
+  list(APPEND TESTLIBS ${LIB_COPY})
+endif()
+
+set(CUSTOM_TEST_DIR ${TESTLIB_PATH}/P1)
+add_custom_command(
+  COMMENT "Create directory for PUC-Rio Lua 5.1 tests"
+  OUTPUT  ${CUSTOM_TEST_DIR}
+  COMMAND ${CMAKE_COMMAND} -E make_directory ${CUSTOM_TEST_DIR}
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+set(LUA_PATH "?\;${CMAKE_CURRENT_SOURCE_DIR}/?.lua")
+
+# 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 adopted for LuaJIT.
+
+add_custom_target(PUC-Lua-5.1-tests
+  DEPENDS ${LUAJIT_TEST_BINARY} ${TESTLIBS} ${CUSTOM_TEST_DIR}
+)
+
+add_custom_command(TARGET PUC-Lua-5.1-tests
+  COMMENT "Running PUC-Rio Lua 5.1 tests"
+  COMMAND
+  env
+    # Tarantool doesn't support LUA_INIT and most likely it
+    # never will.
+    # See https://github.com/tarantool/tarantool/issues/5744
+    # for more info.
+    # LUA_PATH="${CMAKE_CURRENT_BINARY_DIR}/?.lua\;\;"
+    # LUA_INIT="package.path='?\;'..package.path"
+    # So use less preferable way for tests.
+    LUA_PATH="${LUA_PATH}\;\;"
+    ${LUAJIT_TEST_BINARY} ${TEST_RUNNER}
+  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/lib1.c b/test/PUC-Lua-5.1-tests/libs/lib1.c
new file mode 100644
index 0000000..22fe6de
--- /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..876a212
--- /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.28.0


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

* [Tarantool-patches] [WIP luajit 02/15] test: adapt PUC-Rio Lua 5.1 test suite for LuaJIT
  2021-03-04 10:23 [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites Sergey Kaplun via Tarantool-patches
  2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 01/15] test: add PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
@ 2021-03-04 10:23 ` Sergey Kaplun via Tarantool-patches
  2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 03/15] test: adapt Lua 5.1 test suite for Tarantool Sergey Kaplun via Tarantool-patches
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-04 10:23 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: 22063 bytes --]

In some insignificant details LuaJIT's behaviour is not the same
as the behaviour of Lua 5.1.

Tests in the following files are disabled with corresponding comments:
* closure.lua
* constructs.lua
* db.lua
* errors.lua
* literals.lua
* main.lua
* math.lua
* nextvar.lua
* pm.lua
* strings.lua
* vararg.lua

jit.off() as prologue and jit.on() as epilogue is added to one test
chunk in gc.lua for stable (JIT unrelated) GC test results.

Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 test/PUC-Lua-5.1-tests/closure.lua    | 12 ++++-
 test/PUC-Lua-5.1-tests/constructs.lua |  7 +++
 test/PUC-Lua-5.1-tests/db.lua         | 75 ++++++++++++++++++++-------
 test/PUC-Lua-5.1-tests/errors.lua     | 28 +++++++---
 test/PUC-Lua-5.1-tests/gc.lua         |  5 ++
 test/PUC-Lua-5.1-tests/literals.lua   |  5 ++
 test/PUC-Lua-5.1-tests/main.lua       | 56 ++++++++++++++------
 test/PUC-Lua-5.1-tests/math.lua       |  7 ++-
 test/PUC-Lua-5.1-tests/nextvar.lua    |  7 +++
 test/PUC-Lua-5.1-tests/pm.lua         |  6 ++-
 test/PUC-Lua-5.1-tests/strings.lua    | 17 +++++-
 test/PUC-Lua-5.1-tests/vararg.lua     | 20 ++++---
 12 files changed, 195 insertions(+), 50 deletions(-)

diff --git a/test/PUC-Lua-5.1-tests/closure.lua b/test/PUC-Lua-5.1-tests/closure.lua
index 27ca0ad..e9bd564 100644
--- a/test/PUC-Lua-5.1-tests/closure.lua
+++ b/test/PUC-Lua-5.1-tests/closure.lua
@@ -174,7 +174,10 @@ f = coroutine.wrap(foo)
 local a = {}
 assert(f(a) == _G)
 local a,b = pcall(f)
-assert(a and b == _G)
+-- LuaJIT getfenv() behaviour is different in tail calls.
+-- See also https://github.com/tarantool/tarantool/issues/5713.
+-- Test is disabled for LuaJIT for now.
+-- assert(a and b == _G)
 
 
 -- tests for multiple yield/resume arguments
@@ -261,6 +264,12 @@ end
 
 local x = gen(100)
 local a = {}
+-- In Lua 5.1 math.mod() is renamed to math.fmod() if build
+-- Lua 5.1 without flag `-DLUA_COMPAT_MOD`.
+-- LuaJIT also has math.fmod() instead math.mod() builtin.
+-- See also https://github.com/tarantool/tarantool/issues/5711.
+-- Test is disabled.
+--[=[
 while 1 do
   local n = x()
   if n == nil then break end
@@ -269,6 +278,7 @@ while 1 do
 end
 
 assert(table.getn(a) == 25 and a[table.getn(a)] == 97)
+--]=]
 
 
 -- errors in coroutines
diff --git a/test/PUC-Lua-5.1-tests/constructs.lua b/test/PUC-Lua-5.1-tests/constructs.lua
index 5fb3798..6776ee6 100644
--- a/test/PUC-Lua-5.1-tests/constructs.lua
+++ b/test/PUC-Lua-5.1-tests/constructs.lua
@@ -200,6 +200,12 @@ a,b = F(nil)==nil; assert(a == true and b == nil)
 
 function ID(x) return x end
 
+-- In Lua 5.1 math.mod() is renamed to math.fmod() if build
+-- Lua 5.1 without flag `-DLUA_COMPAT_MOD`.
+-- LuaJIT also has math.fmod() instead math.mod() builtin.
+-- See also https://github.com/tarantool/tarantool/issues/5711.
+-- Test is disabled.
+--[=[
 function f(t, i)
   local b = t.n
   local res = math.mod(math.floor(i/c), b)+1
@@ -236,5 +242,6 @@ repeat
   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
index 9d2c86f..591a006 100644
--- a/test/PUC-Lua-5.1-tests/db.lua
+++ b/test/PUC-Lua-5.1-tests/db.lua
@@ -95,6 +95,10 @@ repeat
   assert(g(f) == 'a')
 until 1
 
+-- LuaJIT interprets a return from calling result of loadstring()
+-- with a new line number unlike Lua does.
+-- See also https://github.com/tarantool/tarantool/issues/5693.
+--[=[
 test([[if
 math.sin(1)
 then
@@ -149,7 +153,7 @@ end
 ]], {1,2,1,2,1,3})
 
 test([[for i=1,4 do a=1 end]], {1,1,1,1,1})
-
+--]=]
 
 
 print'+'
@@ -178,8 +182,13 @@ function f(a,b)
   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")
+  -- f() function is called only from g(...) vararg function.
+  -- Lua 5.1 interprets ... in the vararg functions like additional
+  -- first argument unlike LuaJIT does.
+  -- This extension is from Lua 5.2.
+  -- See also https://github.com/tarantool/tarantool/issues/5694.
+  -- 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"))
@@ -208,11 +217,13 @@ function g(...)
   local feijao
   local AAAA,B = "xuxu", "mamão"
   f(AAAA,B)
-  assert(AAAA == "pera" and B == "maçã")
+  -- Test is disabled for LuaJIT for now. See comment in f().
+  -- assert(AAAA == "pera" and B == "maçã")
   do
      local B = 13
      local x,y = debug.getlocal(1,5)
-     assert(x == 'B' and y == 13)
+     -- Test is disabled for LuaJIT for now. See comment in f().
+     -- assert(x == 'B' and y == 13)
   end
 end
 
@@ -276,7 +287,8 @@ 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)
+-- Test is disabled for LuaJIT for now. See comment in f().
+-- 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)
 
@@ -314,12 +326,20 @@ assert(debug.setupvalue(io.read, 1, 10) == nil)
 
 -- testing count hooks
 local a=0
+-- 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.
+--[[
 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
@@ -352,18 +372,24 @@ 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. getfenv() behaviour is also different here.
+-- Test is disabled for LuaJIT for now.
+-- 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.
+-- 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.
+-- for _, k in ipairs(res) do assert(k == table.remove(b, 1)) end
 
 
 lim = 30000
@@ -375,7 +401,8 @@ local function foo (x)
   end
 end
 
-foo(lim)
+-- Behavior is different for LuaJIT. See the comment above.
+-- foo(lim)
 
 
 print"+"
@@ -411,7 +438,11 @@ end
 
 local co = coroutine.create(f)
 coroutine.resume(co, 3)
-checktraceback(co, {"yield", "db.lua", "tail", "tail", "tail"})
+-- LuaJIT does not provide information about tail calls,
+-- unlike Lua does.
+-- See also https://github.com/tarantool/tarantool/issues/5703.
+-- Test is disabled for LuaJIT for now.
+-- checktraceback(co, {"yield", "db.lua", "tail", "tail", "tail"})
 
 
 co = coroutine.create(function (x)
@@ -429,8 +460,12 @@ 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")
+-- LuaJIT does not report line with single "end" statement as
+-- an active line in debug.getinfo(), unlike Lua does.
+-- See also https://github.com/tarantool/tarantool/issues/5708.
+-- Test is disabled for LuaJIT for now.
 for i=x.linedefined + 1, x.lastlinedefined do
-  assert(x.activelines[i])
+  -- assert(x.activelines[i])
   x.activelines[i] = nil
 end
 assert(next(x.activelines) == nil)   -- no 'extra' elements
@@ -441,8 +476,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)
+-- LuaJIT does not support per-coroutine hooks.
+-- 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)
@@ -450,9 +487,11 @@ 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.
+-- 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.
+-- assert(debug.gethook() == nil)
 checktraceback(co, {})
 
 
diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua
index e881211..3270033 100644
--- a/test/PUC-Lua-5.1-tests/errors.lua
+++ b/test/PUC-Lua-5.1-tests/errors.lua
@@ -72,8 +72,12 @@ 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 reports the error as the following here:
+-- "attempt to perform arithmetic on global 'aaa' (a table value)"
+-- Lua 5.1 doesn't report variable name here.
+-- Test is 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
@@ -100,9 +104,12 @@ while 1 do
   insert(prefix, a)
 end]], "global 'insert'")
 
-checkmessage([[  -- tail call
-  return math.sin("a")
-]], "'sin'")
+-- Implementation of fast functions in LuaJIT does not provide
+-- enough info on failure.
+-- Test is disabled for LuaJIT.
+-- checkmessage([[  -- tail call
+--   return math.sin("a")
+-- ]], "'sin'")
 
 checkmessage([[collectgarbage("nooption")]], "invalid option")
 
@@ -193,7 +200,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-alphabetic symbols
+-- as identifiers, unlike Lua does.
+-- For more details see <src/lj_char.c> and <src/lj_lex.c>.
+-- Test is disabled for LuaJIT.
+-- checksyntax("\255a = 1", "", "\255", 1)
 
 doit('I = loadstring("a=9+"); a=3')
 assert(a==3 and I == nil)
@@ -215,7 +226,10 @@ local function testrep (init, rep)
 end
 testrep("a=", "{")
 testrep("a=", "(")
-testrep("", "a(")
+-- When compiled with LUAJIT_ENABLE_GC64 LJ_MAX_SLOTS limit
+-- is reached and error is LJ_ERR_XSLOTS ("function or expression too
+-- complex"). Test is disabled for LuaJIT.
+-- testrep("", "a(")
 testrep("", "do ")
 testrep("", "while a do ")
 testrep("", "if a then else ")
diff --git a/test/PUC-Lua-5.1-tests/gc.lua b/test/PUC-Lua-5.1-tests/gc.lua
index 86a9f75..b767104 100644
--- a/test/PUC-Lua-5.1-tests/gc.lua
+++ b/test/PUC-Lua-5.1-tests/gc.lua
@@ -108,11 +108,16 @@ local function dosteps (siz)
   return i
 end
 
+-- JIT compilation can unpredictable allocate or reference objects
+-- (or traces itself). Disable it for this chunk for stable
+-- GC results.
+jit.off()
 assert(dosteps(0) > 10)
 assert(dosteps(6) < dosteps(2))
 assert(dosteps(10000) == 1)
 assert(collectgarbage("step", 1000000) == true)
 assert(collectgarbage("step", 1000000))
+jit.on()
 
 
 do
diff --git a/test/PUC-Lua-5.1-tests/literals.lua b/test/PUC-Lua-5.1-tests/literals.lua
index 01d84d5..ee16a3e 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 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/main.lua b/test/PUC-Lua-5.1-tests/main.lua
index f520896..12f3981 100644
--- a/test/PUC-Lua-5.1-tests/main.lua
+++ b/test/PUC-Lua-5.1-tests/main.lua
@@ -65,9 +65,16 @@ 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)
+-- test 'arg' availability in libraries
+-- 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.
+-- prepfile"assert(arg==nil)"
+-- prepfile("assert(arg)", otherprog)
+-- RUN("lua -l%s - < %s", prog, otherprog)
 
 prepfile""
 RUN("lua - < %s > %s", prog, out)
@@ -89,26 +96,35 @@ 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.
+-- 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")
+-- 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")
+-- 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")
+-- 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 )
@@ -126,19 +142,29 @@ 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")
+-- 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)
 
+-- test loading and running bytecode files.
+-- 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.
 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.
+-- 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))
diff --git a/test/PUC-Lua-5.1-tests/math.lua b/test/PUC-Lua-5.1-tests/math.lua
index 5076f38..b46a3f5 100644
--- a/test/PUC-Lua-5.1-tests/math.lua
+++ b/test/PUC-Lua-5.1-tests/math.lua
@@ -100,7 +100,12 @@ 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)
+-- In Lua 5.1 math.mod() is renamed to math.fmod() if build
+-- Lua 5.1 without flag `-DLUA_COMPAT_MOD`.
+-- LuaJIT also has math.fmod() instead math.mod() builtin.
+-- See also https://github.com/tarantool/tarantool/issues/5711.
+-- Test is disabled.
+-- 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))
diff --git a/test/PUC-Lua-5.1-tests/nextvar.lua b/test/PUC-Lua-5.1-tests/nextvar.lua
index 7ceaa75..a63f97e 100644
--- a/test/PUC-Lua-5.1-tests/nextvar.lua
+++ b/test/PUC-Lua-5.1-tests/nextvar.lua
@@ -199,6 +199,12 @@ _G["xxx"] = 1
 assert(xxx==find("xxx"))
 print('+')
 
+-- In Lua 5.1 math.mod() is renamed to math.fmod() if build
+-- Lua 5.1 without flag `-DLUA_COMPAT_MOD`.
+-- LuaJIT also has math.fmod() instead math.mod() builtin.
+-- See also https://github.com/tarantool/tarantool/issues/5711.
+-- Test is disabled.
+--[=[
 a = {}
 for i=0,10000 do
   if math.mod(i,10) ~= 0 then
@@ -213,6 +219,7 @@ for i,v in pairs(a) do
 end
 assert(n.n == 9000)
 a = nil
+--]=]
 
 -- remove those 10000 new global variables
 for i=1,10000 do _G[i] = nil end
diff --git a/test/PUC-Lua-5.1-tests/pm.lua b/test/PUC-Lua-5.1-tests/pm.lua
index fa125dc..366a31c 100644
--- a/test/PUC-Lua-5.1-tests/pm.lua
+++ b/test/PUC-Lua-5.1-tests/pm.lua
@@ -223,7 +223,11 @@ assert(string.gsub("a alo b hi", "%w%w+", t) == "a ALO b HI")
 
 
 -- tests for gmatch
-assert(string.gfind == string.gmatch)
+-- 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 builtin is removed from LuaJIT. Test is disabled.
+-- 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)
diff --git a/test/PUC-Lua-5.1-tests/strings.lua b/test/PUC-Lua-5.1-tests/strings.lua
index 237dbad..a97c888 100644
--- a/test/PUC-Lua-5.1-tests/strings.lua
+++ b/test/PUC-Lua-5.1-tests/strings.lua
@@ -102,7 +102,18 @@ print('+')
 
 x = '"ílo"\n\\'
 assert(string.format('%q%s', x, x) == '"\\"ílo\\"\\\n\\\\""ílo"\n\\')
-assert(string.format('%q', "\0") == [["\000"]])
+-- 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).).
+-- See also https://github.com/tarantool/tarantool/issues/5710.
+-- Test is disabled for LuaJIT for now.
+-- 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('') == "")
@@ -152,6 +163,9 @@ local function trylocale (w)
   return false
 end
 
+-- 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
@@ -166,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')
diff --git a/test/PUC-Lua-5.1-tests/vararg.lua b/test/PUC-Lua-5.1-tests/vararg.lua
index ae068fa..e2de1ad 100644
--- a/test/PUC-Lua-5.1-tests/vararg.lua
+++ b/test/PUC-Lua-5.1-tests/vararg.lua
@@ -21,9 +21,14 @@ 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)
+-- 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.
+-- Test is disabled for LuaJIT.
+-- 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}))
@@ -35,15 +40,18 @@ 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)
+-- Test is disabled for LuaJIT for now. See the comment above.
+-- 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)
+-- Test is disabled for LuaJIT for now. See the comment above.
+-- 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)
+-- Test is disabled for LuaJIT for now. See the comment above.
+-- assert(t:f(1,4) == 3 and t:f(2) == 11)
 print('+')
 
 lim = 20
-- 
2.28.0


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

* [Tarantool-patches] [WIP luajit 03/15] test: adapt Lua 5.1 test suite for Tarantool
  2021-03-04 10:23 [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites Sergey Kaplun via Tarantool-patches
  2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 01/15] test: add PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
  2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 02/15] test: adapt PUC-Rio Lua 5.1 test suite for LuaJIT Sergey Kaplun via Tarantool-patches
@ 2021-03-04 10:23 ` Sergey Kaplun via Tarantool-patches
  2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 04/15] test: add LuaJIT-test-cleanup test suite Sergey Kaplun via Tarantool-patches
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-04 10:23 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

In some insignificant details Tarantool's behaviour is not the same
as the behaviour of Lua 5.1.

This patch adds special LUAJIT_TEST_COMMAND variable to extend
`progname` from main.lua with ` -e require"strict".off()` to disable strict
for debug Tarantool build. Also, `progname` is not edged by '"' to be
able run other test suites.

Tests in the following files are disabled with corresponding comments:
* gc.lua
* main.lua
* pm.lua

Tests in the following files are adapted for testing with Tarantool's
out-of-source build:
* all.lua
* verybig.lua

Part of tarantool/tarantool#5845
Part of tarantool/tarantool#4473
---
 CMakeLists.txt                        |  8 ++++++++
 test/PUC-Lua-5.1-tests/CMakeLists.txt |  5 ++++-
 test/PUC-Lua-5.1-tests/all.lua        | 16 ++++++++++++----
 test/PUC-Lua-5.1-tests/gc.lua         |  9 ++++++---
 test/PUC-Lua-5.1-tests/main.lua       | 24 +++++++++++++++++-------
 test/PUC-Lua-5.1-tests/pm.lua         |  6 +++++-
 test/PUC-Lua-5.1-tests/verybig.lua    |  4 +++-
 7 files changed, 55 insertions(+), 17 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9486ca6..9917b50 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -288,6 +288,14 @@ set(LUAJIT_TEST_BINARY ${LUAJIT_BINARY} CACHE STRING
   "Lua implementation to be used for tests. Default is 'luajit'."
 )
 
+# Unfortunately we can't just use LUA_INIT enviroment variable.
+# See https://github.com/tarantool/tarantool/issues/5744 for
+# the details. This variable includes -e 'require"strict".off()'
+# for the Tarantool.
+set(LUAJIT_TEST_COMMAND ${LUAJIT_BINARY} CACHE STRING
+  "Lua implementation with -e command to be used for tests. Default is 'luajit'."
+)
+
 add_subdirectory(test)
 
 # --- Misc rules ---------------------------------------------------------------
diff --git a/test/PUC-Lua-5.1-tests/CMakeLists.txt b/test/PUC-Lua-5.1-tests/CMakeLists.txt
index ed32a84..1249cab 100644
--- a/test/PUC-Lua-5.1-tests/CMakeLists.txt
+++ b/test/PUC-Lua-5.1-tests/CMakeLists.txt
@@ -82,7 +82,10 @@ add_custom_command(TARGET PUC-Lua-5.1-tests
     # LUA_INIT="package.path='?\;'..package.path"
     # So use less preferable way for tests.
     LUA_PATH="${LUA_PATH}\;\;"
-    ${LUAJIT_TEST_BINARY} ${TEST_RUNNER}
+    # XXX: Adapt to run test on readonly file systems
+    # with loadfile(CUR_SOURCE_DIR..filename).
+    CUR_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}
+    ${LUAJIT_TEST_COMMAND} ${TEST_RUNNER}
   WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
 )
 
diff --git a/test/PUC-Lua-5.1-tests/all.lua b/test/PUC-Lua-5.1-tests/all.lua
index 8c4afac..52a6235 100755
--- a/test/PUC-Lua-5.1-tests/all.lua
+++ b/test/PUC-Lua-5.1-tests/all.lua
@@ -58,9 +58,13 @@ end
 --
 -- redefine dofile to run files through dump/undump
 --
-dofile = function (n)
+-- Adapt test for testing with Tarantool's out-of-source build
+-- on read only file system. CUR_SOURCE_DIR is set via CMake.
+local path_to_sources = os.getenv('CUR_SOURCE_DIR')..'/'
+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 +81,9 @@ do
   end
 end
 
-local f = assert(loadfile('gc.lua'))
+-- Adapt test for testing with Tarantool's out-of-source build
+-- on read only file system.
+local f = assert(loadfile(path_to_sources..'gc.lua'))
 f()
 dofile('db.lua')
 assert(dofile('calls.lua') == deep and deep)
@@ -88,7 +94,9 @@ assert(dofile('locals.lua') == 5)
 dofile('constructs.lua')
 dofile('code.lua')
 do
-  local f = coroutine.wrap(assert(loadfile('big.lua')))
+  -- Adapt test for testing with Tarantool's out-of-source build
+  -- on read only file system.
+  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/gc.lua b/test/PUC-Lua-5.1-tests/gc.lua
index b767104..6c4097a 100644
--- a/test/PUC-Lua-5.1-tests/gc.lua
+++ b/test/PUC-Lua-5.1-tests/gc.lua
@@ -128,9 +128,12 @@ do
     local a = {}
   until gcinfo() > 1000
   collectgarbage"restart"
-  repeat
-    local a = {}
-  until gcinfo() < 1000
+  -- Tarantool has too much objects at start.
+  -- gcinfo() is always greater than 1000.
+  -- Test is disabled for Tarantool binary.
+  -- repeat
+  --   local a = {}
+  -- until gcinfo() < 1000
 end
 
 lim = 15
diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua
index 12f3981..69eb5db 100644
--- a/test/PUC-Lua-5.1-tests/main.lua
+++ b/test/PUC-Lua-5.1-tests/main.lua
@@ -11,7 +11,7 @@ out = os.tmpname()
 do
   local i = 0
   while arg[i] do i=i-1 end
-  progname = '"'..arg[i+1]..'"'
+  progname = arg[i+1]
 end
 print(progname)
 
@@ -50,8 +50,10 @@ 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")
+-- Test is disabled for 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")
 
 local a = [[
   assert(table.getn(arg) == 3 and arg[1] == 'a' and
@@ -63,7 +65,10 @@ local a = [[
 ]]
 a = string.format(a, progname)
 prepfile(a)
-RUN('lua "-e " -- %s a b c', prog)
+-- Tarantool has different command line argument parsing.
+-- For example it always set itself as arg[-1].
+-- Test is disabled for Tarantool binary.
+-- RUN('lua "-e " -- %s a b c', prog)
 
 -- test 'arg' availability in libraries
 -- LuaJIT v2.1.0-beta3 has extension from Lua 5.3:
@@ -85,8 +90,10 @@ 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")
+-- Test is disabled for 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(
@@ -177,7 +184,10 @@ assert(not os.remove(out))
 
 RUN("lua -v")
 
-NoRun("lua -h")
+-- Tarantool returns zero status at exit with -h option, unlike
+-- Lua does.
+-- Test is disabled for Tarantool binary.
+-- NoRun("lua -h")
 NoRun("lua -e")
 NoRun("lua -e a")
 NoRun("lua -f")
diff --git a/test/PUC-Lua-5.1-tests/pm.lua b/test/PUC-Lua-5.1-tests/pm.lua
index 366a31c..6e1b403 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.
+-- Test is disabled for Tarantool binary.
+-- assert(rev(rev(x)) == x)
 
 
 -- gsub with tables
diff --git a/test/PUC-Lua-5.1-tests/verybig.lua b/test/PUC-Lua-5.1-tests/verybig.lua
index 59e0142..bfb95df 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)
+-- Adapt test for testing with Tarantool's out-of-source build
+-- on read only file system.
+result = dofile(file, "")
 assert(os.remove(file))
 print'OK'
 return result
-- 
2.28.0


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

* [Tarantool-patches] [WIP luajit 04/15] test: add LuaJIT-test-cleanup test suite
  2021-03-04 10:23 [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites Sergey Kaplun via Tarantool-patches
                   ` (2 preceding siblings ...)
  2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 03/15] test: adapt Lua 5.1 test suite for Tarantool Sergey Kaplun via Tarantool-patches
@ 2021-03-04 10:23 ` Sergey Kaplun via Tarantool-patches
  2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 05/15] test: change tests to match de5568e Sergey Kaplun via Tarantool-patches
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-04 10:23 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

This patch adds LuaJIT-test-cleanup test suite:
https://github.com/LuaJIT/LuaJIT-test-cleanup

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

Part of tarantool/tarantool#4064
Part of tarantool/tarantool#4473
---
Mergen Imeev <imeevma@gmail.com>: Author
Sergey Kaplun <skaplun@tarantool.org>: glanced commit message, made
commit consistence with the tarantool branch.

 .luacheckrc                                   |   1 +
 test/CMakeLists.txt                           |   2 +
 test/LuaJIT-tests/CMakeLists.txt              |  20 +
 test/LuaJIT-tests/README.md                   | 110 +++
 test/LuaJIT-tests/bc/constov.lua              |  16 +
 test/LuaJIT-tests/bc/index                    |   1 +
 test/LuaJIT-tests/common/expect_error.lua     |  16 +
 test/LuaJIT-tests/common/ffi_util.inc         |  41 +
 .../common/test_runner_canary.lua             |   1 +
 test/LuaJIT-tests/computations.lua            | 113 +++
 test/LuaJIT-tests/index                       |   6 +
 test/LuaJIT-tests/lang/andor.lua              |  61 ++
 test/LuaJIT-tests/lang/assignment.lua         |  46 +
 test/LuaJIT-tests/lang/compare.lua            | 323 +++++++
 test/LuaJIT-tests/lang/compare_nan.lua        |  99 +++
 test/LuaJIT-tests/lang/concat.lua             | 112 +++
 test/LuaJIT-tests/lang/constant/index         |   2 +
 test/LuaJIT-tests/lang/constant/number.lua    |  12 +
 test/LuaJIT-tests/lang/constant/table.lua     |  15 +
 test/LuaJIT-tests/lang/coroutine.lua          |   8 +
 test/LuaJIT-tests/lang/for.lua                |  45 +
 test/LuaJIT-tests/lang/gc.lua                 |  42 +
 test/LuaJIT-tests/lang/goto.lua               | 149 ++++
 test/LuaJIT-tests/lang/index                  |  18 +
 test/LuaJIT-tests/lang/length.lua             |  23 +
 test/LuaJIT-tests/lang/meta/arith.lua         | 118 +++
 test/LuaJIT-tests/lang/meta/arith_jit.lua     |  68 ++
 test/LuaJIT-tests/lang/meta/call.lua          |  81 ++
 test/LuaJIT-tests/lang/meta/cat.lua           |  61 ++
 test/LuaJIT-tests/lang/meta/comp.lua          | 120 +++
 test/LuaJIT-tests/lang/meta/comp_jit.lua      | 104 +++
 test/LuaJIT-tests/lang/meta/debuginfo.lua     |  81 ++
 test/LuaJIT-tests/lang/meta/eq.lua            |  30 +
 test/LuaJIT-tests/lang/meta/eq_jit.lua        |  35 +
 test/LuaJIT-tests/lang/meta/framegap.lua      |  24 +
 test/LuaJIT-tests/lang/meta/index             |  14 +
 test/LuaJIT-tests/lang/meta/index.lua         |  60 ++
 test/LuaJIT-tests/lang/meta/len.lua           |  42 +
 test/LuaJIT-tests/lang/meta/newindex.lua      |  69 ++
 test/LuaJIT-tests/lang/meta/nomm.lua          |  21 +
 test/LuaJIT-tests/lang/modulo.lua             |  46 +
 test/LuaJIT-tests/lang/self.lua               |  19 +
 test/LuaJIT-tests/lang/table.lua              |  32 +
 test/LuaJIT-tests/lang/tail_recursion.lua     |  20 +
 test/LuaJIT-tests/lang/upvalue/closure.lua    |  84 ++
 test/LuaJIT-tests/lang/upvalue/index          |   1 +
 test/LuaJIT-tests/lang/vararg_jit.lua         |  95 +++
 test/LuaJIT-tests/lib/base/assert.lua         |  33 +
 test/LuaJIT-tests/lib/base/error.lua          |  43 +
 test/LuaJIT-tests/lib/base/getfenv.lua        |  13 +
 .../LuaJIT-tests/lib/base/getsetmetatable.lua |  33 +
 test/LuaJIT-tests/lib/base/index              |  11 +
 test/LuaJIT-tests/lib/base/ipairs.lua         |  41 +
 test/LuaJIT-tests/lib/base/next.lua           |  17 +
 test/LuaJIT-tests/lib/base/pairs.lua          |  73 ++
 test/LuaJIT-tests/lib/base/pcall_jit.lua      |  74 ++
 test/LuaJIT-tests/lib/base/select.lua         | 105 +++
 .../lib/base/tonumber_tostring.lua            |  81 ++
 test/LuaJIT-tests/lib/base/xpcall_jit.lua     |  83 ++
 test/LuaJIT-tests/lib/bit.lua                 |  98 +++
 test/LuaJIT-tests/lib/contents.lua            | 155 ++++
 test/LuaJIT-tests/lib/coroutine/index         |   1 +
 test/LuaJIT-tests/lib/coroutine/yield.lua     | 109 +++
 test/LuaJIT-tests/lib/ffi/bit64.lua           | 130 +++
 test/LuaJIT-tests/lib/ffi/cdata_var.lua       |  47 ++
 test/LuaJIT-tests/lib/ffi/copy_fill.lua       |  64 ++
 test/LuaJIT-tests/lib/ffi/err.lua             |  35 +
 test/LuaJIT-tests/lib/ffi/ffi_arith_ptr.lua   | 106 +++
 test/LuaJIT-tests/lib/ffi/ffi_bitfield.lua    | 108 +++
 test/LuaJIT-tests/lib/ffi/ffi_call.lua        | 266 ++++++
 test/LuaJIT-tests/lib/ffi/ffi_callback.lua    | 158 ++++
 test/LuaJIT-tests/lib/ffi/ffi_const.lua       | 113 +++
 test/LuaJIT-tests/lib/ffi/ffi_convert.lua     | 787 ++++++++++++++++++
 test/LuaJIT-tests/lib/ffi/ffi_enum.lua        |  57 ++
 .../lib/ffi/ffi_gcstep_recursive.lua          |  66 ++
 test/LuaJIT-tests/lib/ffi/ffi_jit_arith.lua   | 155 ++++
 test/LuaJIT-tests/lib/ffi/ffi_jit_call.lua    | 154 ++++
 test/LuaJIT-tests/lib/ffi/ffi_jit_conv.lua    | 277 ++++++
 test/LuaJIT-tests/lib/ffi/ffi_lex_number.lua  |  51 ++
 test/LuaJIT-tests/lib/ffi/ffi_metatype.lua    | 245 ++++++
 test/LuaJIT-tests/lib/ffi/ffi_new.lua         | 106 +++
 test/LuaJIT-tests/lib/ffi/ffi_parse_array.lua |  78 ++
 test/LuaJIT-tests/lib/ffi/ffi_parse_basic.lua | 131 +++
 test/LuaJIT-tests/lib/ffi/ffi_parse_cdef.lua  |  77 ++
 .../LuaJIT-tests/lib/ffi/ffi_parse_struct.lua | 259 ++++++
 test/LuaJIT-tests/lib/ffi/ffi_tabov.lua       |  12 +
 test/LuaJIT-tests/lib/ffi/index               |  12 +
 test/LuaJIT-tests/lib/ffi/istype.lua          |  88 ++
 test/LuaJIT-tests/lib/ffi/jit_array.lua       | 104 +++
 test/LuaJIT-tests/lib/ffi/jit_complex.lua     | 109 +++
 test/LuaJIT-tests/lib/ffi/jit_misc.lua        | 109 +++
 test/LuaJIT-tests/lib/ffi/jit_struct.lua      | 201 +++++
 test/LuaJIT-tests/lib/ffi/meta_tostring.lua   |  55 ++
 test/LuaJIT-tests/lib/ffi/redir.lua           |  19 +
 test/LuaJIT-tests/lib/ffi/type_punning.lua    | 138 +++
 test/LuaJIT-tests/lib/index                   |   8 +
 test/LuaJIT-tests/lib/math/abs.lua            |  16 +
 test/LuaJIT-tests/lib/math/constants.lua      |   8 +
 test/LuaJIT-tests/lib/math/index              |   3 +
 test/LuaJIT-tests/lib/math/random.lua         |  47 ++
 test/LuaJIT-tests/lib/string/byte.lua         |  92 ++
 test/LuaJIT-tests/lib/string/char.lua         |  29 +
 test/LuaJIT-tests/lib/string/dump.lua         |  31 +
 test/LuaJIT-tests/lib/string/format/index     |   1 +
 test/LuaJIT-tests/lib/string/format/num.lua   | 184 ++++
 test/LuaJIT-tests/lib/string/index            |  11 +
 test/LuaJIT-tests/lib/string/len.lua          |  14 +
 test/LuaJIT-tests/lib/string/lower_upper.lua  |  51 ++
 test/LuaJIT-tests/lib/string/metatable.lua    |   3 +
 .../lib/string/multiple_functions.lua         |  16 +
 test/LuaJIT-tests/lib/string/rep.lua          |  68 ++
 test/LuaJIT-tests/lib/string/reverse.lua      |  13 +
 test/LuaJIT-tests/lib/string/sub.lua          | 189 +++++
 test/LuaJIT-tests/lib/table/concat.lua        |  55 ++
 test/LuaJIT-tests/lib/table/index             |   6 +
 test/LuaJIT-tests/lib/table/insert.lua        |  17 +
 test/LuaJIT-tests/lib/table/misc.lua          |  58 ++
 test/LuaJIT-tests/lib/table/new.lua           |  11 +
 test/LuaJIT-tests/lib/table/pack.lua          |   7 +
 test/LuaJIT-tests/lib/table/remove.lua        |  42 +
 test/LuaJIT-tests/lib/table/sort.lua          |  27 +
 test/LuaJIT-tests/misc/alias_alloc.lua        |  54 ++
 test/LuaJIT-tests/misc/api_call.lua           |  98 +++
 test/LuaJIT-tests/misc/catch_wrap.lua         |  45 +
 test/LuaJIT-tests/misc/coro_traceback.lua     |   8 +
 test/LuaJIT-tests/misc/coro_yield.lua         | 111 +++
 test/LuaJIT-tests/misc/debug_gc.lua           |  47 ++
 test/LuaJIT-tests/misc/dualnum.lua            |  47 ++
 test/LuaJIT-tests/misc/for_dir.lua            |  13 +
 test/LuaJIT-tests/misc/fori_coerce.lua        |  33 +
 test/LuaJIT-tests/misc/gc_rechain.lua         |  32 +
 test/LuaJIT-tests/misc/gc_trace.lua           |  37 +
 test/LuaJIT-tests/misc/gcstep.lua             |  33 +
 test/LuaJIT-tests/misc/hook_active.lua        |  95 +++
 test/LuaJIT-tests/misc/hook_line.lua          |  41 +
 test/LuaJIT-tests/misc/hook_norecord.lua      |  12 +
 test/LuaJIT-tests/misc/hook_record.lua        |   8 +
 test/LuaJIT-tests/misc/hook_top.lua           |  55 ++
 test/LuaJIT-tests/misc/jit_flush.lua          |  50 ++
 test/LuaJIT-tests/misc/lightud.lua            |  88 ++
 test/LuaJIT-tests/misc/loop_unroll.lua        |  35 +
 test/LuaJIT-tests/misc/parse_comp.lua         |  13 +
 test/LuaJIT-tests/misc/parse_esc.lua          |   7 +
 test/LuaJIT-tests/misc/parse_misc.lua         |  31 +
 test/LuaJIT-tests/misc/phi_conv.lua           |  53 ++
 test/LuaJIT-tests/misc/recurse_deep.lua       |  29 +
 test/LuaJIT-tests/misc/recurse_tail.lua       |  22 +
 test/LuaJIT-tests/misc/stack_gc.lua           |  15 +
 test/LuaJIT-tests/misc/stack_purge.lua        |  25 +
 test/LuaJIT-tests/misc/stackov.lua            |  40 +
 test/LuaJIT-tests/misc/stackovc.lua           |   4 +
 test/LuaJIT-tests/misc/tcall_base.lua         |  20 +
 test/LuaJIT-tests/misc/tcall_loop.lua         |   8 +
 test/LuaJIT-tests/misc/tonumber_scan.lua      | 180 ++++
 test/LuaJIT-tests/misc/uclo.lua               |  91 ++
 test/LuaJIT-tests/misc/unordered_jit.lua      |  96 +++
 test/LuaJIT-tests/misc/wbarrier.lua           |   7 +
 test/LuaJIT-tests/misc/wbarrier_jit.lua       |  18 +
 test/LuaJIT-tests/misc/wbarrier_obar.lua      |  22 +
 test/LuaJIT-tests/opt/dse/array.lua           | 197 +++++
 test/LuaJIT-tests/opt/dse/field.lua           |  70 ++
 test/LuaJIT-tests/opt/dse/index               |   2 +
 test/LuaJIT-tests/opt/fold/index              |   1 +
 test/LuaJIT-tests/opt/fold/kfold.lua          |  81 ++
 test/LuaJIT-tests/opt/fuse.lua                |   5 +
 test/LuaJIT-tests/opt/fwd/hrefk_rollback.lua  |  32 +
 test/LuaJIT-tests/opt/fwd/index               |   3 +
 test/LuaJIT-tests/opt/fwd/tnew_tdup.lua       |  69 ++
 test/LuaJIT-tests/opt/fwd/upval.lua           |  50 ++
 test/LuaJIT-tests/opt/index                   |   6 +
 test/LuaJIT-tests/opt/loop/index              |   1 +
 test/LuaJIT-tests/opt/loop/unroll.lua         |  32 +
 test/LuaJIT-tests/opt/sink/alloc.lua          | 126 +++
 test/LuaJIT-tests/opt/sink/ffi.lua            | 121 +++
 test/LuaJIT-tests/opt/sink/ffi_nosink.lua     |  45 +
 test/LuaJIT-tests/opt/sink/index              |   4 +
 test/LuaJIT-tests/opt/sink/nosink.lua         | 109 +++
 test/LuaJIT-tests/src/cpptest.cpp             | 129 +++
 test/LuaJIT-tests/src/ctest.c                 | 339 ++++++++
 test/LuaJIT-tests/sysdep/catch_cpp.lua        |  71 ++
 test/LuaJIT-tests/sysdep/ffi_include_gtk.lua  |   9 +
 test/LuaJIT-tests/sysdep/ffi_include_std.lua  |  36 +
 test/LuaJIT-tests/sysdep/ffi_lib_c.lua        |  87 ++
 test/LuaJIT-tests/sysdep/ffi_lib_z.lua        | 107 +++
 test/LuaJIT-tests/test.lua                    | 416 +++++++++
 test/LuaJIT-tests/trace/exit_frame.lua        |  79 ++
 test/LuaJIT-tests/trace/exit_growstack.lua    |  28 +
 test/LuaJIT-tests/trace/exit_jfuncf.lua       |  30 +
 test/LuaJIT-tests/trace/gc64_slot_revival.lua |  18 +
 test/LuaJIT-tests/trace/index                 |   7 +
 test/LuaJIT-tests/trace/phi/copyspill.lua     |  53 ++
 test/LuaJIT-tests/trace/phi/index             |   3 +
 test/LuaJIT-tests/trace/phi/ref.lua           | 131 +++
 test/LuaJIT-tests/trace/phi/rotate.lua        | 149 ++++
 test/LuaJIT-tests/trace/snap.lua              |  47 ++
 test/LuaJIT-tests/trace/stitch.lua            |  19 +
 .../unportable/ffi_arith_int64.lua            |  68 ++
 test/LuaJIT-tests/unportable/math_special.lua |  55 ++
 198 files changed, 13259 insertions(+)
 create mode 100644 test/LuaJIT-tests/CMakeLists.txt
 create mode 100644 test/LuaJIT-tests/README.md
 create mode 100644 test/LuaJIT-tests/bc/constov.lua
 create mode 100644 test/LuaJIT-tests/bc/index
 create mode 100644 test/LuaJIT-tests/common/expect_error.lua
 create mode 100644 test/LuaJIT-tests/common/ffi_util.inc
 create mode 100644 test/LuaJIT-tests/common/test_runner_canary.lua
 create mode 100644 test/LuaJIT-tests/computations.lua
 create mode 100644 test/LuaJIT-tests/index
 create mode 100644 test/LuaJIT-tests/lang/andor.lua
 create mode 100644 test/LuaJIT-tests/lang/assignment.lua
 create mode 100644 test/LuaJIT-tests/lang/compare.lua
 create mode 100644 test/LuaJIT-tests/lang/compare_nan.lua
 create mode 100644 test/LuaJIT-tests/lang/concat.lua
 create mode 100644 test/LuaJIT-tests/lang/constant/index
 create mode 100644 test/LuaJIT-tests/lang/constant/number.lua
 create mode 100644 test/LuaJIT-tests/lang/constant/table.lua
 create mode 100644 test/LuaJIT-tests/lang/coroutine.lua
 create mode 100644 test/LuaJIT-tests/lang/for.lua
 create mode 100644 test/LuaJIT-tests/lang/gc.lua
 create mode 100644 test/LuaJIT-tests/lang/goto.lua
 create mode 100644 test/LuaJIT-tests/lang/index
 create mode 100644 test/LuaJIT-tests/lang/length.lua
 create mode 100644 test/LuaJIT-tests/lang/meta/arith.lua
 create mode 100644 test/LuaJIT-tests/lang/meta/arith_jit.lua
 create mode 100644 test/LuaJIT-tests/lang/meta/call.lua
 create mode 100644 test/LuaJIT-tests/lang/meta/cat.lua
 create mode 100644 test/LuaJIT-tests/lang/meta/comp.lua
 create mode 100644 test/LuaJIT-tests/lang/meta/comp_jit.lua
 create mode 100644 test/LuaJIT-tests/lang/meta/debuginfo.lua
 create mode 100644 test/LuaJIT-tests/lang/meta/eq.lua
 create mode 100644 test/LuaJIT-tests/lang/meta/eq_jit.lua
 create mode 100644 test/LuaJIT-tests/lang/meta/framegap.lua
 create mode 100644 test/LuaJIT-tests/lang/meta/index
 create mode 100644 test/LuaJIT-tests/lang/meta/index.lua
 create mode 100644 test/LuaJIT-tests/lang/meta/len.lua
 create mode 100644 test/LuaJIT-tests/lang/meta/newindex.lua
 create mode 100644 test/LuaJIT-tests/lang/meta/nomm.lua
 create mode 100644 test/LuaJIT-tests/lang/modulo.lua
 create mode 100644 test/LuaJIT-tests/lang/self.lua
 create mode 100644 test/LuaJIT-tests/lang/table.lua
 create mode 100644 test/LuaJIT-tests/lang/tail_recursion.lua
 create mode 100644 test/LuaJIT-tests/lang/upvalue/closure.lua
 create mode 100644 test/LuaJIT-tests/lang/upvalue/index
 create mode 100644 test/LuaJIT-tests/lang/vararg_jit.lua
 create mode 100644 test/LuaJIT-tests/lib/base/assert.lua
 create mode 100644 test/LuaJIT-tests/lib/base/error.lua
 create mode 100644 test/LuaJIT-tests/lib/base/getfenv.lua
 create mode 100644 test/LuaJIT-tests/lib/base/getsetmetatable.lua
 create mode 100644 test/LuaJIT-tests/lib/base/index
 create mode 100644 test/LuaJIT-tests/lib/base/ipairs.lua
 create mode 100644 test/LuaJIT-tests/lib/base/next.lua
 create mode 100644 test/LuaJIT-tests/lib/base/pairs.lua
 create mode 100644 test/LuaJIT-tests/lib/base/pcall_jit.lua
 create mode 100644 test/LuaJIT-tests/lib/base/select.lua
 create mode 100644 test/LuaJIT-tests/lib/base/tonumber_tostring.lua
 create mode 100644 test/LuaJIT-tests/lib/base/xpcall_jit.lua
 create mode 100644 test/LuaJIT-tests/lib/bit.lua
 create mode 100644 test/LuaJIT-tests/lib/contents.lua
 create mode 100644 test/LuaJIT-tests/lib/coroutine/index
 create mode 100644 test/LuaJIT-tests/lib/coroutine/yield.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/bit64.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/cdata_var.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/copy_fill.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/err.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_arith_ptr.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_bitfield.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_call.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_callback.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_const.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_convert.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_enum.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_gcstep_recursive.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_jit_arith.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_jit_call.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_jit_conv.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_lex_number.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_metatype.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_new.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_parse_array.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_parse_basic.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_parse_cdef.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_parse_struct.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_tabov.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/index
 create mode 100644 test/LuaJIT-tests/lib/ffi/istype.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/jit_array.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/jit_complex.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/jit_misc.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/jit_struct.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/meta_tostring.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/redir.lua
 create mode 100644 test/LuaJIT-tests/lib/ffi/type_punning.lua
 create mode 100644 test/LuaJIT-tests/lib/index
 create mode 100644 test/LuaJIT-tests/lib/math/abs.lua
 create mode 100644 test/LuaJIT-tests/lib/math/constants.lua
 create mode 100644 test/LuaJIT-tests/lib/math/index
 create mode 100644 test/LuaJIT-tests/lib/math/random.lua
 create mode 100644 test/LuaJIT-tests/lib/string/byte.lua
 create mode 100644 test/LuaJIT-tests/lib/string/char.lua
 create mode 100644 test/LuaJIT-tests/lib/string/dump.lua
 create mode 100644 test/LuaJIT-tests/lib/string/format/index
 create mode 100644 test/LuaJIT-tests/lib/string/format/num.lua
 create mode 100644 test/LuaJIT-tests/lib/string/index
 create mode 100644 test/LuaJIT-tests/lib/string/len.lua
 create mode 100644 test/LuaJIT-tests/lib/string/lower_upper.lua
 create mode 100644 test/LuaJIT-tests/lib/string/metatable.lua
 create mode 100644 test/LuaJIT-tests/lib/string/multiple_functions.lua
 create mode 100644 test/LuaJIT-tests/lib/string/rep.lua
 create mode 100644 test/LuaJIT-tests/lib/string/reverse.lua
 create mode 100644 test/LuaJIT-tests/lib/string/sub.lua
 create mode 100644 test/LuaJIT-tests/lib/table/concat.lua
 create mode 100644 test/LuaJIT-tests/lib/table/index
 create mode 100644 test/LuaJIT-tests/lib/table/insert.lua
 create mode 100644 test/LuaJIT-tests/lib/table/misc.lua
 create mode 100644 test/LuaJIT-tests/lib/table/new.lua
 create mode 100644 test/LuaJIT-tests/lib/table/pack.lua
 create mode 100644 test/LuaJIT-tests/lib/table/remove.lua
 create mode 100644 test/LuaJIT-tests/lib/table/sort.lua
 create mode 100644 test/LuaJIT-tests/misc/alias_alloc.lua
 create mode 100644 test/LuaJIT-tests/misc/api_call.lua
 create mode 100644 test/LuaJIT-tests/misc/catch_wrap.lua
 create mode 100644 test/LuaJIT-tests/misc/coro_traceback.lua
 create mode 100644 test/LuaJIT-tests/misc/coro_yield.lua
 create mode 100644 test/LuaJIT-tests/misc/debug_gc.lua
 create mode 100644 test/LuaJIT-tests/misc/dualnum.lua
 create mode 100644 test/LuaJIT-tests/misc/for_dir.lua
 create mode 100644 test/LuaJIT-tests/misc/fori_coerce.lua
 create mode 100644 test/LuaJIT-tests/misc/gc_rechain.lua
 create mode 100644 test/LuaJIT-tests/misc/gc_trace.lua
 create mode 100644 test/LuaJIT-tests/misc/gcstep.lua
 create mode 100644 test/LuaJIT-tests/misc/hook_active.lua
 create mode 100644 test/LuaJIT-tests/misc/hook_line.lua
 create mode 100644 test/LuaJIT-tests/misc/hook_norecord.lua
 create mode 100644 test/LuaJIT-tests/misc/hook_record.lua
 create mode 100644 test/LuaJIT-tests/misc/hook_top.lua
 create mode 100644 test/LuaJIT-tests/misc/jit_flush.lua
 create mode 100644 test/LuaJIT-tests/misc/lightud.lua
 create mode 100644 test/LuaJIT-tests/misc/loop_unroll.lua
 create mode 100644 test/LuaJIT-tests/misc/parse_comp.lua
 create mode 100644 test/LuaJIT-tests/misc/parse_esc.lua
 create mode 100644 test/LuaJIT-tests/misc/parse_misc.lua
 create mode 100644 test/LuaJIT-tests/misc/phi_conv.lua
 create mode 100644 test/LuaJIT-tests/misc/recurse_deep.lua
 create mode 100644 test/LuaJIT-tests/misc/recurse_tail.lua
 create mode 100644 test/LuaJIT-tests/misc/stack_gc.lua
 create mode 100644 test/LuaJIT-tests/misc/stack_purge.lua
 create mode 100644 test/LuaJIT-tests/misc/stackov.lua
 create mode 100644 test/LuaJIT-tests/misc/stackovc.lua
 create mode 100644 test/LuaJIT-tests/misc/tcall_base.lua
 create mode 100644 test/LuaJIT-tests/misc/tcall_loop.lua
 create mode 100644 test/LuaJIT-tests/misc/tonumber_scan.lua
 create mode 100644 test/LuaJIT-tests/misc/uclo.lua
 create mode 100644 test/LuaJIT-tests/misc/unordered_jit.lua
 create mode 100644 test/LuaJIT-tests/misc/wbarrier.lua
 create mode 100644 test/LuaJIT-tests/misc/wbarrier_jit.lua
 create mode 100644 test/LuaJIT-tests/misc/wbarrier_obar.lua
 create mode 100644 test/LuaJIT-tests/opt/dse/array.lua
 create mode 100644 test/LuaJIT-tests/opt/dse/field.lua
 create mode 100644 test/LuaJIT-tests/opt/dse/index
 create mode 100644 test/LuaJIT-tests/opt/fold/index
 create mode 100644 test/LuaJIT-tests/opt/fold/kfold.lua
 create mode 100644 test/LuaJIT-tests/opt/fuse.lua
 create mode 100644 test/LuaJIT-tests/opt/fwd/hrefk_rollback.lua
 create mode 100644 test/LuaJIT-tests/opt/fwd/index
 create mode 100644 test/LuaJIT-tests/opt/fwd/tnew_tdup.lua
 create mode 100644 test/LuaJIT-tests/opt/fwd/upval.lua
 create mode 100644 test/LuaJIT-tests/opt/index
 create mode 100644 test/LuaJIT-tests/opt/loop/index
 create mode 100644 test/LuaJIT-tests/opt/loop/unroll.lua
 create mode 100644 test/LuaJIT-tests/opt/sink/alloc.lua
 create mode 100644 test/LuaJIT-tests/opt/sink/ffi.lua
 create mode 100644 test/LuaJIT-tests/opt/sink/ffi_nosink.lua
 create mode 100644 test/LuaJIT-tests/opt/sink/index
 create mode 100644 test/LuaJIT-tests/opt/sink/nosink.lua
 create mode 100644 test/LuaJIT-tests/src/cpptest.cpp
 create mode 100644 test/LuaJIT-tests/src/ctest.c
 create mode 100644 test/LuaJIT-tests/sysdep/catch_cpp.lua
 create mode 100644 test/LuaJIT-tests/sysdep/ffi_include_gtk.lua
 create mode 100644 test/LuaJIT-tests/sysdep/ffi_include_std.lua
 create mode 100644 test/LuaJIT-tests/sysdep/ffi_lib_c.lua
 create mode 100644 test/LuaJIT-tests/sysdep/ffi_lib_z.lua
 create mode 100644 test/LuaJIT-tests/test.lua
 create mode 100644 test/LuaJIT-tests/trace/exit_frame.lua
 create mode 100644 test/LuaJIT-tests/trace/exit_growstack.lua
 create mode 100644 test/LuaJIT-tests/trace/exit_jfuncf.lua
 create mode 100644 test/LuaJIT-tests/trace/gc64_slot_revival.lua
 create mode 100644 test/LuaJIT-tests/trace/index
 create mode 100644 test/LuaJIT-tests/trace/phi/copyspill.lua
 create mode 100644 test/LuaJIT-tests/trace/phi/index
 create mode 100644 test/LuaJIT-tests/trace/phi/ref.lua
 create mode 100644 test/LuaJIT-tests/trace/phi/rotate.lua
 create mode 100644 test/LuaJIT-tests/trace/snap.lua
 create mode 100644 test/LuaJIT-tests/trace/stitch.lua
 create mode 100644 test/LuaJIT-tests/unportable/ffi_arith_int64.lua
 create mode 100644 test/LuaJIT-tests/unportable/math_special.lua

diff --git a/.luacheckrc b/.luacheckrc
index d49301b..cbd2912 100644
--- a/.luacheckrc
+++ b/.luacheckrc
@@ -8,5 +8,6 @@ read_globals = { 'misc' }
 exclude_files = {
   'dynasm/',
   'src/',
+  'test/LuaJIT-tests/',
   'test/PUC-Lua-5.1-tests/',
 }
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 8e6b4f9..1f9a379 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -32,10 +32,12 @@ else()
   )
 endif()
 
+add_subdirectory(LuaJIT-tests)
 add_subdirectory(PUC-Lua-5.1-tests)
 add_subdirectory(tarantool-tests)
 
 add_custom_target(${PROJECT_NAME}-test DEPENDS
+  LuaJIT-tests
   PUC-Lua-5.1-tests
   tarantool-tests
 )
diff --git a/test/LuaJIT-tests/CMakeLists.txt b/test/LuaJIT-tests/CMakeLists.txt
new file mode 100644
index 0000000..51a72d1
--- /dev/null
+++ b/test/LuaJIT-tests/CMakeLists.txt
@@ -0,0 +1,20 @@
+# See the rationale in the root CMakeLists.txt
+cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
+
+add_custom_target(LuaJIT-tests DEPENDS ${LUAJIT_TEST_BINARY})
+
+add_custom_command(TARGET LuaJIT-tests
+  COMMENT "Running LuaJIT-tests"
+  COMMAND
+    # Tarantool doesn't support LUA_INIT and most likely it
+    # never will.
+    # See https://github.com/tarantool/tarantool/issues/5744
+    # for more info.
+    # So use less preferable way for tests.
+    # See the root CMakeLists.txt for more info.
+    ${LUAJIT_TEST_COMMAND} ${CMAKE_CURRENT_SOURCE_DIR}/test.lua
+    +slow +ffi +bit +jit
+  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+# vim: expandtab tabstop=2 shiftwidth=2
diff --git a/test/LuaJIT-tests/README.md b/test/LuaJIT-tests/README.md
new file mode 100644
index 0000000..ff16ac8
--- /dev/null
+++ b/test/LuaJIT-tests/README.md
@@ -0,0 +1,110 @@
+This directory contains the LuaJIT test suite, or at least something which
+will evolve into the LuaJIT test suite. Large chunks of the suite can also
+be run with any other Lua 5.1 or 5.2 interpreter.
+
+## Running the test suite ##
+
+To run the default test suite, run `test.lua` using the Lua interpreter you
+wish to test, for example:
+
+    $ ~/luajit-2.0/src/luajit test.lua
+
+If the test suite passes, the final line printed to stdout will be
+`NNN passed`, and the exit code of the process will be zero. If any tests
+fail, the exit code will be non-zero. If the failures caused catastrophic
+termination of the entire process (such as a segmentation fault or assertion
+failure), the last line of output will be number and name of the test which
+caused the catastrophe. If the failures weren't catastrophic, the penultimate
+line of output will be `NNN passed, MMM failed`, and the last line will say
+how to re-run just the failing tests.
+
+Various flags and options can be passed to `test.lua` to control which tests
+are run, and in which order. Run `lua test.lua --help` for details.
+
+## Structure of the test suite ##
+
+The test suite consists of a directory tree. Within said tree there are various
+`.lua` files, and within every `.lua` file there are one or more tests. Every
+directory in the tree contains a file called `index`, which enumerates the
+members of the directory which contribute to the test suite (this is done to
+avoid an external dependency for directory iteration, and to allow metadata to
+be specified at the file/directory level). Every `.lua` file is structured as:
+
+    << local definitions >>
+    << test 1 >>
+    ...
+    << test N >>
+
+Where `<< local definitions >>` consists of Lua code to act as a common prefix
+for every test in the file, and each `<< test >>` looks like:
+
+    do --- <<name>> <<metadata>>
+      << code >>
+    end
+
+Where `<<name>>` is (almost) free-form, and `<< code >>` is Lua code which
+performs some actions and probably calls `assert` alot. The `<<metadata>>`
+fragment can be used to specify the conditions under which the test should
+or should not run, to adjust the environment in which the test is run, and to
+allow key/value pairs to be specified in a standard place/format.
+
+Some common pieces of metadata are:
+  * `+luajit>=2.1` - The test requires LuaJIT 2.1 or later to run.
+  * `+lua<5.2` - The test requires Lua 5.1 or earlier to run (all versions of
+                 LuaJIT report themselves as 5.1).
+  * `+ffi` - The test requires the `ffi` library to be present.
+  * `+bit` - The test requires the `bit` library to be present.
+  * `+jit` - The test requires JIT compilation be available and turned on.
+  * `+slow` - The test is too slow to run as part of the default suite, and
+              thus requires `+slow` to be specified on the command line.
+  * `!private_G` - The test modifies globals, and thus needs to be run with a
+                   private (shallow) copy of `_G`.
+
+Lua code which is common across all (or some) tests in a single file can be
+written at the top of the file as part of `<< local definitions >>`. Code
+which is common across multiple files lives in the `common` directory, and
+is pulled into applicable tests by means of `local x = require"common.x"`.
+
+It is intended that most `.lua` files in the test suite can be exercised
+without the test runner by just passing them to a Lua interpreter. In such
+cases, metadata is ignored, the tests are executed from top to bottom, and
+any failure results in later tests not running. Also note that the test
+runner converts every test into a separate function, which causes references
+to local definitions to become upvalue accesses rather than local variable
+accesses - in some cases this can cause differences in behaviour.
+
+## Extending the test suite ##
+
+First of all, decide where your new test(s) should live. This might be within
+an existing `.lua` file, or might involve creating new files and/or directories.
+If new files are created, remember to add them to the `index` file of the
+enclosing directory. If new directories are created, remember to create an
+`index` file in said directory, and add the new directory to the `index` file
+in the parent directory.
+
+Once you've decided in which file the test(s) should live, you're ready to add
+your test(s) to said file. Each test should be wrapped in a `do`/`end` block,
+and given some kind of name (after the `do` keyword, as in `do --- <<name>>`).
+The test should call `assert` to confirm whether the thing under test is
+behaving, or otherwise raise an error if the thing under test is misbehaving.
+Your test(s) should not write to stdout or stderr, nor should they mutate
+global state. After your test(s) are written, you should be able to determine
+which features they require, and put on metadata appropriately.
+
+## Completing the tidy-up of the test suite ##
+
+Some files/directories in this directory need some thought:
+
+  * `common/ffi_util.inc` - Needs renaming and being made `require`-able.
+  * `lib/ffi` - Tests need converting to structure described in this document.
+  * `lib/table/misc.lua` - Tests need organising and converting to structure
+                           described in this document.
+  * `misc` - Tests need organising and converting to structure described in
+             this document.
+  * `src` - C/C++ source which needs to be compiled into a dynamic library and
+            loaded for certain tests. Need to figure out a good way of handling
+            C/C++ source.
+  * `sysdep` - Need to figure out a good way of handling these.
+  * `unportable` - Need to figure out a good way of handling these.
+
+After that, consult the README file by Mike in the directory above this one.
diff --git a/test/LuaJIT-tests/bc/constov.lua b/test/LuaJIT-tests/bc/constov.lua
new file mode 100644
index 0000000..5827840
--- /dev/null
+++ b/test/LuaJIT-tests/bc/constov.lua
@@ -0,0 +1,16 @@
+
+do --- float
+  local t = { "local x\n" }
+  for i=2,65537 do t[i] = "x="..i..".5\n" end
+  assert(loadstring(table.concat(t)) ~= nil)
+  t[65538] = "x=65538.5"
+  assert(loadstring(table.concat(t)) == nil)
+end
+
+do --- int
+  local t = { "local x\n" }
+  for i=2,65537 do t[i] = "x='"..i.."'\n" end
+  assert(loadstring(table.concat(t)) ~= nil)
+  t[65538] = "x='65538'"
+  assert(loadstring(table.concat(t)) == nil)
+end
diff --git a/test/LuaJIT-tests/bc/index b/test/LuaJIT-tests/bc/index
new file mode 100644
index 0000000..dead10f
--- /dev/null
+++ b/test/LuaJIT-tests/bc/index
@@ -0,0 +1 @@
+constov.lua +slow
diff --git a/test/LuaJIT-tests/common/expect_error.lua b/test/LuaJIT-tests/common/expect_error.lua
new file mode 100644
index 0000000..e155090
--- /dev/null
+++ b/test/LuaJIT-tests/common/expect_error.lua
@@ -0,0 +1,16 @@
+return function(f, msg)
+  local ok, err = pcall(f)
+  if ok then error("error check unexpectedly succeeded", 2) end
+  if msg then
+    if type(err) ~= "string" then
+      error("error check failed with "..tostring(err), 2)
+    end
+    local line, err2 = string.match(err, ":(%d*): (.*)")
+    if err2 ~= msg then
+      if err2:gsub(" got no value", " got nil") == msg then
+        return
+      end
+      error("error check failed with "..err, 2)
+    end
+  end
+end
diff --git a/test/LuaJIT-tests/common/ffi_util.inc b/test/LuaJIT-tests/common/ffi_util.inc
new file mode 100644
index 0000000..1eee8dd
--- /dev/null
+++ b/test/LuaJIT-tests/common/ffi_util.inc
@@ -0,0 +1,41 @@
+-- This should be turned into a proper module and not use globals.
+-- Or combined into a generiv test utility module. With FFI
+-- functionality turned off, if the FFI module is not built-in.
+
+local ffi = require("ffi")
+
+function checkfail(t, f)
+  f = f or ffi.typeof
+  for i=1,1e9 do
+    local tp = t[i]
+    if not tp then break end
+    assert(pcall(f, tp) == false, tp)
+  end
+end
+
+function checktypes(t)
+  for i=1,1e9,3 do
+    local tp = t[i+2]
+    if not tp then break end
+    local id = ffi.typeof(tp)
+    assert(ffi.sizeof(id) == t[i], tp)
+    assert(ffi.alignof(id) == t[i+1], tp)
+  end
+end
+
+function fails(f, ...)
+  if pcall(f, ...) ~= false then error("failure expected", 2) end
+end
+
+local incroot = os.getenv("INCROOT") or "/usr/include"
+local cdefs = os.getenv("CDEFS") or ""
+
+function include(name)
+  local flags = ffi.abi("32bit") and "-m32" or "-m64"
+  if string.sub(name, 1, 1) ~= "/" then name = incroot.."/"..name end
+  local fp = assert(io.popen("cc -E -P "..flags.." "..cdefs.." "..name))
+  local s = fp:read("*a")
+  fp:close()
+  ffi.cdef(s)
+end
+
diff --git a/test/LuaJIT-tests/common/test_runner_canary.lua b/test/LuaJIT-tests/common/test_runner_canary.lua
new file mode 100644
index 0000000..fc9cadc
--- /dev/null
+++ b/test/LuaJIT-tests/common/test_runner_canary.lua
@@ -0,0 +1 @@
+return "canary is alive"
diff --git a/test/LuaJIT-tests/computations.lua b/test/LuaJIT-tests/computations.lua
new file mode 100644
index 0000000..4fce7fc
--- /dev/null
+++ b/test/LuaJIT-tests/computations.lua
@@ -0,0 +1,113 @@
+do --- ack
+  local function Ack(m, n)
+    if m == 0 then return n+1 end
+    if n == 0 then return Ack(m-1, 1) end
+    return Ack(m-1, (Ack(m, n-1))) -- The parentheses are deliberate.
+  end
+  
+  assert(Ack(3,5) == 253)
+end
+
+do --- ack notail
+  local function Ack(m, n)
+    if m == 0 then return n+1 end
+    if n == 0 then return Ack(m-1, 1) end
+    return (Ack(m-1, (Ack(m, n-1)))) -- The parentheses are deliberate.
+  end
+  
+  assert(Ack(3,5) == 253)
+end
+
+do --- fac
+  local function fac(n)
+    local x = 1
+    for i=2,n do
+      x = x * i
+    end
+    return x
+  end
+  
+  assert(fac(10) == 3628800)
+end
+
+do --- ffib
+  local function ffib(n)
+    if n <= 2 then return n,1 end
+    if n % 2 == 1 then
+      local a,b = ffib((n-1)/2)
+      local aa = a*a
+      return aa+a*(b+b), aa+b*b
+    else
+      local a,b = ffib(n/2-1)
+      local ab = a+b
+      return ab*ab+a*a, (ab+b)*a
+    end
+  end
+
+  local function fib(n)
+    return (ffib(n))
+  end
+
+  assert(fib(40) == 165580141)
+  assert(fib(39) == 102334155)
+  assert(fib(77) == 8944394323791464)
+end
+
+do --- fib
+  local function fib(n)
+    if n < 2 then return 1 end
+    return fib(n-2) + fib(n-1)
+  end
+
+  assert(fib(27) == 317811)
+end
+
+do --- nsieve
+  local function nsieve(m)
+    local isPrime = {}
+    for i=2,m do isPrime[i] = true end
+    local count = 0
+    for i=2,m do
+      if isPrime[i] then
+        for k=i+i,m,i do isPrime[k] = false end
+        count = count + 1
+      end
+    end
+    return count
+  end
+  
+  assert(nsieve(100) == 25)
+  assert(nsieve(12345) == 1474)
+end
+
+do --- recsum
+  local function sum(n)
+    if n == 1 then return 1 end
+    return n + sum(n-1)
+  end
+  
+  for i=1, 100 do
+    assert(sum(i) == i*(i+1)/2)
+  end
+end
+
+do --- recsump
+  local abs = math.abs
+  local function sum(n)
+    if n == 1 then return 1 end
+    return abs(n + sum(n-1))
+  end
+  
+  for i=1, 100 do
+    assert(sum(i) == i*(i+1)/2)
+  end
+end
+
+do --- tak
+  local function tak(x, y, z)
+    if y >= x then return z end
+    return tak(tak(x-1, y, z), tak(y-1, z, x), (tak(z-1, x, y)))
+  end
+
+  assert(tak(21, 14, 7) == 14)
+end
diff --git a/test/LuaJIT-tests/index b/test/LuaJIT-tests/index
new file mode 100644
index 0000000..bd4081e
--- /dev/null
+++ b/test/LuaJIT-tests/index
@@ -0,0 +1,6 @@
+lang
+lib
+bc +luajit>=2
+computations.lua
+trace +jit
+opt +jit
diff --git a/test/LuaJIT-tests/lang/andor.lua b/test/LuaJIT-tests/lang/andor.lua
new file mode 100644
index 0000000..55b2c75
--- /dev/null
+++ b/test/LuaJIT-tests/lang/andor.lua
@@ -0,0 +1,61 @@
+do --- smoke
+  local x = ((1 or false) and true) or false
+  assert(x == true)
+end
+
+do --- allcases
+  local basiccases = {
+    {"nil", nil},
+    {"false", false},
+    {"true", true},
+    {"10", 10},
+  }
+
+  local mem = {basiccases}    -- for memoization
+
+  local function allcases (n)
+    if mem[n] then return mem[n] end
+    local res = {}
+    -- include all smaller cases
+    for _, v in ipairs(allcases(n - 1)) do
+      res[#res + 1] = v
+    end
+    for i = 1, n - 1 do
+      for _, v1 in ipairs(allcases(i)) do
+        for _, v2 in ipairs(allcases(n - i)) do
+    res[#res + 1] = {
+      "(" .. v1[1] .. " and " .. v2[1] .. ")",
+      v1[2] and v2[2]
+    }
+    res[#res + 1] = {
+      "(" .. v1[1] .. " or " .. v2[1] .. ")",
+      v1[2] or v2[2]
+    }
+        end
+      end
+    end
+    mem[n] = res   -- memoize
+    return res
+  end
+
+  for _, v in pairs(allcases(4)) do
+    local res = (loadstring or load)("return " .. v[1])()
+    if res ~= v[2] then
+      error(string.format("bad conditional eval\n%s\nexpected: %s\ngot: %s",
+        v[1], tostring(v[2]), tostring(res)))
+    end
+  end
+end
+
+do --- tracefib
+  -- 0001    KSHORT   1   2
+  -- 0002    ISGE     0   1
+  -- 0003    JMP      1 => 0006
+  -- 0004    KSHORT   1   1
+  -- 0005    JMP      1 => 0013
+  --                 ^^^ must be 2
+  -- fix in jmp_patchtestreg
+  local function fib(n) return (n < 2) and 1 or fib(n-1)+fib(n-2) end
+  assert(fib(5) == 8)
+  assert(fib(10) == 89)
+end
diff --git a/test/LuaJIT-tests/lang/assignment.lua b/test/LuaJIT-tests/lang/assignment.lua
new file mode 100644
index 0000000..e9745ef
--- /dev/null
+++ b/test/LuaJIT-tests/lang/assignment.lua
@@ -0,0 +1,46 @@
+local assert = assert
+
+do --- local
+  local a, b, c
+  a, b, c = 0, 1
+  assert(a == 0)
+  assert(b == 1)
+  assert(c == nil)
+  a, b = a+1, b+1, a+b
+  assert(a == 1)
+  assert(b == 2)
+  a, b, c = 0
+  assert(a == 0)
+  assert(b == nil)
+  assert(c == nil)
+end
+
+do --- global !private_G
+  a, b, c = 0, 1
+  assert(a == 0)
+  assert(b == 1)
+  assert(c == nil)
+  a, b = a+1, b+1, a+b
+  assert(a == 1)
+  assert(b == 2)
+  a, b, c = 0
+  assert(a == 0)
+  assert(b == nil)
+  assert(c == nil)
+end
+
+do --- local lhs in key on lhs
+  local a = {}
+  local i = 3
+  i, a[i] = i+1, 20
+  assert(i == 4)
+  assert(a[3] == 20)
+end
+
+do --- global lhs in key on lhs !private_G
+  a = {}
+  i = 3
+  i, a[i] = i+1, 20
+  assert(i == 4)
+  assert(a[3] == 20)
+end
diff --git a/test/LuaJIT-tests/lang/compare.lua b/test/LuaJIT-tests/lang/compare.lua
new file mode 100644
index 0000000..09c5488
--- /dev/null
+++ b/test/LuaJIT-tests/lang/compare.lua
@@ -0,0 +1,323 @@
+local function lt(x, y)
+  if x < y then return true else return false end
+end
+
+local function le(x, y)
+  if x <= y then return true else return false end
+end
+
+local function gt(x, y)
+  if x > y then return true else return false end
+end
+
+local function ge(x, y)
+  if x >= y then return true else return false end
+end
+
+local function eq(x, y)
+  if x == y then return true else return false end
+end
+
+local function ne(x, y)
+  if x ~= y then return true else return false end
+end
+
+
+local function ltx1(x)
+  if x < 1 then return true else return false end
+end
+
+local function lex1(x)
+  if x <= 1 then return true else return false end
+end
+
+local function gtx1(x)
+  if x > 1 then return true else return false end
+end
+
+local function gex1(x)
+  if x >= 1 then return true else return false end
+end
+
+local function eqx1(x)
+  if x == 1 then return true else return false end
+end
+
+local function nex1(x)
+  if x ~= 1 then return true else return false end
+end
+
+
+local function lt1x(x)
+  if 1 < x then return true else return false end
+end
+
+local function le1x(x)
+  if 1 <= x then return true else return false end
+end
+
+local function gt1x(x)
+  if 1 > x then return true else return false end
+end
+
+local function ge1x(x)
+  if 1 >= x then return true else return false end
+end
+
+local function eq1x(x)
+  if 1 == x then return true else return false end
+end
+
+local function ne1x(x)
+  if 1 ~= x then return true else return false end
+end
+
+local function check(a, b)
+  if a ~= b then
+    error("check failed with "..tostring(a).." ~= "..tostring(b), 2)
+  end
+end
+
+do --- 1,2
+  local x,y = 1,2
+
+  check(x<y,	true)
+  check(x<=y,	true)
+  check(x>y,	false)
+  check(x>=y,	false)
+  check(x==y,	false)
+  check(x~=y,	true)
+
+  check(1<y,	true)
+  check(1<=y,	true)
+  check(1>y,	false)
+  check(1>=y,	false)
+  check(1==y,	false)
+  check(1~=y,	true)
+
+  check(x<2,	true)
+  check(x<=2,	true)
+  check(x>2,	false)
+  check(x>=2,	false)
+  check(x==2,	false)
+  check(x~=2,	true)
+
+  check(lt(x,y),	true)
+  check(le(x,y),	true)
+  check(gt(x,y),	false)
+  check(ge(x,y),	false)
+  check(eq(y,x),	false)
+  check(ne(y,x),	true)
+end
+
+do --- 2,1
+  local x,y = 2,1
+
+  check(x<y,	false)
+  check(x<=y,	false)
+  check(x>y,	true)
+  check(x>=y,	true)
+  check(x==y,	false)
+  check(x~=y,	true)
+
+  check(2<y,	false)
+  check(2<=y,	false)
+  check(2>y,	true)
+  check(2>=y,	true)
+  check(2==y,	false)
+  check(2~=y,	true)
+
+  check(x<1,	false)
+  check(x<=1,	false)
+  check(x>1,	true)
+  check(x>=1,	true)
+  check(x==1,	false)
+  check(x~=1,	true)
+
+  check(lt(x,y),	false)
+  check(le(x,y),	false)
+  check(gt(x,y),	true)
+  check(ge(x,y),	true)
+  check(eq(y,x),	false)
+  check(ne(y,x),	true)
+end
+
+do --- 1,1
+  local x,y = 1,1
+
+  check(x<y,	false)
+  check(x<=y,	true)
+  check(x>y,	false)
+  check(x>=y,	true)
+  check(x==y,	true)
+  check(x~=y,	false)
+
+  check(1<y,	false)
+  check(1<=y,	true)
+  check(1>y,	false)
+  check(1>=y,	true)
+  check(1==y,	true)
+  check(1~=y,	false)
+
+  check(x<1,	false)
+  check(x<=1,	true)
+  check(x>1,	false)
+  check(x>=1,	true)
+  check(x==1,	true)
+  check(x~=1,	false)
+
+  check(lt(x,y),	false)
+  check(le(x,y),	true)
+  check(gt(x,y),	false)
+  check(ge(x,y),	true)
+  check(eq(y,x),	true)
+  check(ne(y,x),	false)
+end
+
+do --- 2
+  check(lt1x(2),	true)
+  check(le1x(2),	true)
+  check(gt1x(2),	false)
+  check(ge1x(2),	false)
+  check(eq1x(2),	false)
+  check(ne1x(2),	true)
+
+  check(ltx1(2),	false)
+  check(lex1(2),	false)
+  check(gtx1(2),	true)
+  check(gex1(2),	true)
+  check(eqx1(2),	false)
+  check(nex1(2),	true)
+end
+
+do --- 1
+  check(lt1x(1),	false)
+  check(le1x(1),	true)
+  check(gt1x(1),	false)
+  check(ge1x(1),	true)
+  check(eq1x(1),	true)
+  check(ne1x(1),	false)
+
+  check(ltx1(1),	false)
+  check(lex1(1),	true)
+  check(gtx1(1),	false)
+  check(gex1(1),	true)
+  check(eqx1(1),	true)
+  check(nex1(1),	false)
+end
+
+do --- 0
+  check(lt1x(0),	false)
+  check(le1x(0),	false)
+  check(gt1x(0),	true)
+  check(ge1x(0),	true)
+  check(eq1x(0),	false)
+  check(ne1x(0),	true)
+
+  check(ltx1(0),	true)
+  check(lex1(0),	true)
+  check(gtx1(0),	false)
+  check(gex1(0),	false)
+  check(eqx1(0),	false)
+  check(nex1(0),	true)
+end
+
+do --- pcall
+  assert(not pcall(function()
+    local a, b = 10.5, nil
+    return a < b
+  end))
+end
+
+do --- bit +bit
+  for i=1,100 do
+    assert(bit.tobit(i+0x7fffffff) < 0)
+  end
+  for i=1,100 do
+    assert(bit.tobit(i+0x7fffffff) <= 0)
+  end
+end
+
+do --- string 1 255
+  local a = "\255\255\255\255"
+  local b = "\1\1\1\1"
+
+  assert(a > b)
+  assert(a > b)
+  assert(a >= b)
+  assert(b <= a)
+end
+
+do --- String comparisons:
+  local function str_cmp(a, b, lt, gt, le, ge)
+    assert(a<b == lt)
+    assert(a>b == gt)
+    assert(a<=b == le)
+    assert(a>=b == ge)
+    assert((not (a<b)) == (not lt))
+    assert((not (a>b)) == (not gt))
+    assert((not (a<=b)) == (not le))
+    assert((not (a>=b)) == (not ge))
+  end
+
+  local function str_lo(a, b)
+    str_cmp(a, b, true, false, true, false)
+  end
+
+  local function str_eq(a, b)
+    str_cmp(a, b, false, false, true, true)
+  end
+
+  local function str_hi(a, b)
+    str_cmp(a, b, false, true, false, true)
+  end
+
+  str_lo("a", "b")
+  str_eq("a", "a")
+  str_hi("b", "a")
+
+  str_lo("a", "aa")
+  str_hi("aa", "a")
+
+  str_lo("a", "a\0")
+  str_hi("a\0", "a")
+end
+
+do --- obj_eq/ne
+  local function obj_eq(a, b)
+    assert(a==b == true)
+    assert(a~=b == false)
+  end
+
+  local function obj_ne(a, b)
+    assert(a==b == false)
+    assert(a~=b == true)
+  end
+
+  obj_eq(nil, nil)
+  obj_ne(nil, false)
+  obj_ne(nil, true)
+
+  obj_ne(false, nil)
+  obj_eq(false, false)
+  obj_ne(false, true)
+
+  obj_ne(true, nil)
+  obj_ne(true, false)
+  obj_eq(true, true)
+
+  obj_eq(1, 1)
+  obj_ne(1, 2)
+  obj_ne(2, 1)
+
+  obj_eq("a", "a")
+  obj_ne("a", "b")
+  obj_ne("a", 1)
+  obj_ne(1, "a")
+
+  local t, t2 = {}, {}
+  obj_eq(t, t)
+  obj_ne(t, t2)
+  obj_ne(t, 1)
+  obj_ne(t, "")
+end
diff --git a/test/LuaJIT-tests/lang/compare_nan.lua b/test/LuaJIT-tests/lang/compare_nan.lua
new file mode 100644
index 0000000..878f39a
--- /dev/null
+++ b/test/LuaJIT-tests/lang/compare_nan.lua
@@ -0,0 +1,99 @@
+
+local function check(a, b)
+  if a ~= b then
+    error("check failed with "..tostring(a).." ~= "..tostring(b), 2)
+  end
+end
+
+local nan, one = 0/0, 1
+
+do --- nan nan
+  check(nan<nan,	false)
+  check(nan<=nan,	false)
+  check(nan>nan,	false)
+  check(nan>=nan,	false)
+  check(nan==nan,	false)
+  check(nan~=nan,	true)
+end
+
+do --- nan one
+  check(nan<one,	false)
+  check(nan<=one,	false)
+  check(nan>one,	false)
+  check(nan>=one,	false)
+  check(nan==one,	false)
+  check(nan~=one,	true)
+end
+
+do --- one nan
+  check(one<nan,	false)
+  check(one<=nan,	false)
+  check(one>nan,	false)
+  check(one>=nan,	false)
+  check(one==nan,	false)
+  check(one~=nan,	true)
+end
+
+do --- nan 1
+  check(nan<1,	false)
+  check(nan<=1,	false)
+  check(nan>1,	false)
+  check(nan>=1,	false)
+  check(nan==1,	false)
+  check(nan~=1,	true)
+end
+
+do --- 1 nan
+  check(1<nan,	false)
+  check(1<=nan,	false)
+  check(1>nan,	false)
+  check(1>=nan,	false)
+  check(1==nan,	false)
+  check(1~=nan,	true)
+end
+
+do --- not nan nan
+  check(not (nan<nan),	true)
+  check(not (nan<=nan),	true)
+  check(not (nan>nan),	true)
+  check(not (nan>=nan),	true)
+  check(not (nan==nan),	true)
+  check(not (nan~=nan),	false)
+end
+
+do --- not nan one
+  check(not (nan<one),	true)
+  check(not (nan<=one),	true)
+  check(not (nan>one),	true)
+  check(not (nan>=one),	true)
+  check(not (nan==one),	true)
+  check(not (nan~=one),	false)
+end
+
+do --- not one nan
+  check(not (one<nan),	true)
+  check(not (one<=nan),	true)
+  check(not (one>nan),	true)
+  check(not (one>=nan),	true)
+  check(not (one==nan),	true)
+  check(not (one~=nan),	false)
+end
+
+do --- not nan 1
+  check(not (nan<1),	true)
+  check(not (nan<=1),	true)
+  check(not (nan>1),	true)
+  check(not (nan>=1),	true)
+  check(not (nan==1),	true)
+  check(not (nan~=1),	false)
+end
+
+do --- not 1 nan
+  check(not (1<nan),	true)
+  check(not (1<=nan),	true)
+  check(not (1>nan),	true)
+  check(not (1>=nan),	true)
+  check(not (1==nan),	true)
+  check(not (1~=nan),	false)
+end
+
diff --git a/test/LuaJIT-tests/lang/concat.lua b/test/LuaJIT-tests/lang/concat.lua
new file mode 100644
index 0000000..04d665b
--- /dev/null
+++ b/test/LuaJIT-tests/lang/concat.lua
@@ -0,0 +1,112 @@
+do --- Constant folding
+  local y
+  for i=1,100 do y = "a".."b" end
+  assert(y == "ab")
+  for i=1,100 do y = "ab"..(1).."cd"..(1.5) end
+  assert(y == "ab1cd1.5")
+end
+
+do --- Fuse conversions to strings
+  local y
+  local x = "a"
+  for i=1,100 do y = x..i end
+  assert(y == "a100")
+  x = "a"
+  for i=1.5,100.5 do y = x..i end
+  assert(y == "a100.5")
+end
+
+do --- Fuse string construction
+  local y
+  local x = "abc"
+  for i=1,100 do y = "x"..string.sub(x, 2) end
+  assert(y == "xbc")
+end
+
+do --- CSE, sink
+  local y
+  local x = "a"
+  for i=1,100 do y = x.."b" end
+  assert(y == "ab")
+end
+
+do --- CSE, two buffers in parallel, no sink
+  local y, z
+  local x1, x2 = "xx", "yy"
+  for i=1,100 do y = x1.."a"..x1; z = x1.."a"..x2 end
+  assert(y == "xxaxx")
+  assert(z == "xxayy")
+  x1 = "xx"
+  for i=1,100 do y = x1.."a"..x1; z = x1.."b"..x1 end
+  assert(y == "xxaxx")
+  assert(z == "xxbxx")
+end
+
+do --- Append, CSE
+  local y, z
+  local x = "a"
+  for i=1,100 do
+    y = x.."b"
+    y = y.."c"
+  end
+  assert(y == "abc")
+  x = "a"
+  for i=1,100 do
+    y = x.."b"
+    z = y.."c"
+  end
+  assert(y == "ab")
+  assert(z == "abc")
+  x = "a"
+  for i=1,100 do
+    y = x.."b"
+    z = y..i
+  end
+  assert(y == "ab")
+  assert(z == "ab100")
+end
+
+do --- Append, FOLD
+  local a, b = "x"
+  for i=1,100 do b = (a.."y").."" end
+  assert(b == "xy")
+end
+
+do --- Append to buffer, sink
+  local x = "a"
+  for i=1,100 do x = x.."b" end
+  assert(x == "a"..string.rep("b", 100))
+  x = "a"
+  for i=1,100 do x = x.."bc" end
+  assert(x == "a"..string.rep("bc", 100))
+end
+
+do --- Append to two buffers in parallel, no append, no sink
+  local y, z = "xx", "yy"
+  for i=1,100 do y = y.."a"; z = z.."b" end
+  assert(y == "xx"..string.rep("a", 100))
+  assert(z == "yy"..string.rep("b", 100))
+end
+
+do --- Sink into side-exit
+  local x = "a"
+  local z
+  for i=1,200 do
+    local y = x.."b"
+    if i > 100 then
+      z = y..i
+    end
+  end
+  assert(z == "ab200")
+end
+
+do --- Very long strings
+  for i, s in ipairs{"a", "bc", "def"} do
+    for n = 1, 20 do
+      s = s .. s
+    end
+    assert(#s == 2^20*i)
+    assert(s:sub(1, 6) == s:sub(7, 12))
+    assert(s:sub(1, 6) == s:sub(-6, -1))
+  end
+end
diff --git a/test/LuaJIT-tests/lang/constant/index b/test/LuaJIT-tests/lang/constant/index
new file mode 100644
index 0000000..e738357
--- /dev/null
+++ b/test/LuaJIT-tests/lang/constant/index
@@ -0,0 +1,2 @@
+number.lua
+table.lua
diff --git a/test/LuaJIT-tests/lang/constant/number.lua b/test/LuaJIT-tests/lang/constant/number.lua
new file mode 100644
index 0000000..fb67356
--- /dev/null
+++ b/test/LuaJIT-tests/lang/constant/number.lua
@@ -0,0 +1,12 @@
+do --- exp
+  assert(1e5 == 100000)
+  assert(1e+5 == 100000)
+  assert(1e-5 == 0.00001)
+end
+
+do --- hex exp +hexfloat !lex
+  assert(0xe+9 == 23)
+  assert(0xep9 == 7168)
+  assert(0xep+9 == 7168)
+  assert(0xep-9 == 0.02734375)
+end
diff --git a/test/LuaJIT-tests/lang/constant/table.lua b/test/LuaJIT-tests/lang/constant/table.lua
new file mode 100644
index 0000000..899d0f6
--- /dev/null
+++ b/test/LuaJIT-tests/lang/constant/table.lua
@@ -0,0 +1,15 @@
+
+do --- tnew
+  local a = nil
+  local b = {}
+  local t = {[true] = a, [false] = b or 1}
+  assert(t[true] == nil)
+  assert(t[false] == b)
+end
+
+do --- tdup
+  local b = {}
+  local t = {[true] = nil, [false] = b or 1}
+  assert(t[true] == nil)
+  assert(t[false] == b)
+end
diff --git a/test/LuaJIT-tests/lang/coroutine.lua b/test/LuaJIT-tests/lang/coroutine.lua
new file mode 100644
index 0000000..405135c
--- /dev/null
+++ b/test/LuaJIT-tests/lang/coroutine.lua
@@ -0,0 +1,8 @@
+do --- traceback
+  local co = coroutine.create(function()
+    local x = nil
+    local y = x.x
+  end)
+  assert(coroutine.resume(co) == false)
+  debug.traceback(co)
+end
diff --git a/test/LuaJIT-tests/lang/for.lua b/test/LuaJIT-tests/lang/for.lua
new file mode 100644
index 0000000..4982b32
--- /dev/null
+++ b/test/LuaJIT-tests/lang/for.lua
@@ -0,0 +1,45 @@
+do --- direction
+  local a,b,c = 10,1,-1
+  for i=1,20 do
+    if c == -1 then
+      a,b,c = 1,10,1
+    else
+      a,b,c = 10,1,-1
+    end
+    local x = 0
+    for i=a,b,c do for j=1,10 do end x=x+1 end
+    assert(x == 10)
+  end
+end
+
+do --- coerce to integer at 13
+  local n = 1
+  local x = 0
+  for i=1,20 do
+    for j=n,100 do x = x + 1 end
+    if i == 13 then n = "2" end
+  end
+  assert(x == 1993)
+end
+
+do --- coerce to integer at 10
+  local n = 1
+  local x = 0
+  for i=1,20 do
+    for j=n,100 do x = x + 1 end
+    if i == 10 then n = "2" end
+  end
+  assert(x == 1990)
+end
+
+do --- cannot coerce to integer at 10
+  local function f()
+    local n = 1
+    local x = 0
+    for i=1,20 do
+      for j=n,100 do x = x + 1 end
+      if i == 10 then n = "x" end
+    end
+  end
+  assert(not pcall(f))
+end
diff --git a/test/LuaJIT-tests/lang/gc.lua b/test/LuaJIT-tests/lang/gc.lua
new file mode 100644
index 0000000..35e6a1f
--- /dev/null
+++ b/test/LuaJIT-tests/lang/gc.lua
@@ -0,0 +1,42 @@
+do --- rechain
+  local k
+
+  collectgarbage()
+
+  local t = {}
+  t.ac = 1
+
+  t.nn = 1
+  t.mm = 1
+  t.nn = nil
+  t.mm = nil
+
+  k = "a".."i"
+  t[k] = 2
+
+  t.ad = 3
+
+  t[k] = nil
+  k = nil
+
+  collectgarbage()
+
+  k = "a".."f"
+  t[k] = 4
+
+  t.ak = 5
+
+  assert(t[k] == 4)
+end
+
+do --- TSETM gc
+  local function f()
+    collectgarbage()
+    return "a", "b"
+  end
+  for i = 1, 10 do
+    local t = {f()}
+    assert(t[1] == "a")
+    assert(t[2] == "b")
+  end
+end
diff --git a/test/LuaJIT-tests/lang/goto.lua b/test/LuaJIT-tests/lang/goto.lua
new file mode 100644
index 0000000..1563a23
--- /dev/null
+++ b/test/LuaJIT-tests/lang/goto.lua
@@ -0,0 +1,149 @@
+local loadstring = loadstring or load
+
+local function expect(src, msg)
+  local ok, err = loadstring(src)
+  if msg then
+    assert(not ok and string.find(err, msg), err)
+  else
+    assert(ok, err)
+  end
+end
+  
+do --- Basic goto and label semantics.
+  -- Error: duplicate label.
+  expect("::a:: ::a::", "'a'")
+  expect("::a:: ::b:: do ::b:: end ::a::", "'a'")
+
+  -- Error: undefined label.
+  expect("goto a", "'a'")
+  expect("goto a; ::b::", "'a'")
+  expect("do ::a:: end; goto a", "'a'")
+  expect("goto a; do ::a:: end", "'a'")
+  expect("break", "break")
+  expect("if x then break end", "break")
+
+  -- Error: goto into variable scope.
+  expect("goto a; local x; ::a:: local y", "'x'")
+  expect("do local v,w; goto a; end; local x; ::a:: local y", "'x'")
+  expect("repeat goto a; local x; ::a:: until x", "'x'")
+
+  ::a:: do goto a; ::a:: end -- Forward jump, not an infinite loop.
+end
+
+do --- Goto is not a keyword. -compat5.2 !lex !private_G
+  goto = 1
+end
+
+do --- Goto is a keyword. +compat5.2
+  expect("goto = 1", "<name>")
+end
+
+do --- Trailing label is considered to be out of scope.
+  local x = 11
+  do
+    goto a
+    goto a
+    local y = 22
+    x = y
+    ::a::
+    ::b::
+  end
+  assert(x == 11)
+end
+
+do --- Trailing labels and empty statements are considered to be out of scope. +compat5.2 !lex
+  local x = 11
+  do
+    goto a
+    goto a
+    local y = 22
+    x = y
+    ::a:: ;;
+    ::b:: ;;
+  end
+  assert(x == 11)
+end
+
+do --- Simple loop with cross-jumping.
+  local x = 1
+  while true do
+    goto b
+    ::a:: if x < 100 then goto c end
+    goto d
+    ::b:: x = x + 1; goto a
+    ::c::
+  end
+  ::d::
+  assert(x == 100)
+end
+
+do --- Backwards goto must close upval.
+  local t = {}
+  local i = 1
+  ::a::
+  local x
+  t[i] = function() return x end
+  x = i
+  i = i + 1
+  if i <= 2 then goto a end
+  assert(t[1]() == 1)
+  assert(t[2]() == 2)
+end
+
+do --- Break must close upval, even if closure is parsed after break.
+  local foo
+  repeat
+    local x
+    ::a::
+    if x then break end
+    function foo() return x end
+    x = true
+    goto a
+  until false
+  assert(foo() == true)
+end
+
+do --- Label prevents joining to KNIL. -lua==5.2
+  local k = 0
+  local x
+  ::foo::
+  local y
+  assert(y == nil)
+  y = true
+  k = k + 1
+  if k < 2 then goto foo end
+end
+
+do --- Break resolved from the right scope.
+  local function p(lvl)
+     lvl = lvl or 1
+     while true do
+	lvl = lvl + 1
+	if lvl == nil then break end
+	local idx = 1
+	while true do
+	   if key == nil then break end
+	   idx = idx + 1
+	end
+     end
+  end
+end
+
+do --- Do not join twice with UCLO.
+  while true do
+    do
+      local x
+      local function f() return x end
+    end
+    break
+  end
+
+  while true do
+    do
+      local x
+      local function f() return x end
+    end
+    goto foo
+  end
+  ::foo::
+end
diff --git a/test/LuaJIT-tests/lang/index b/test/LuaJIT-tests/lang/index
new file mode 100644
index 0000000..88e2edf
--- /dev/null
+++ b/test/LuaJIT-tests/lang/index
@@ -0,0 +1,18 @@
+andor.lua
+assignment.lua
+compare.lua
+compare_nan.lua
+constant
+for.lua
+length.lua
+modulo.lua
+concat.lua
+self.lua
+table.lua
+upvalue
+coroutine.lua
+tail_recursion.lua
+vararg_jit.lua
+gc.lua
+goto.lua +goto
+meta
diff --git a/test/LuaJIT-tests/lang/length.lua b/test/LuaJIT-tests/lang/length.lua
new file mode 100644
index 0000000..67c68ae
--- /dev/null
+++ b/test/LuaJIT-tests/lang/length.lua
@@ -0,0 +1,23 @@
+
+do --- length increasing and decreasing in loop
+  local t = {}
+  for i=1,100 do t[#t+1] = i end
+  assert(#t == 100)
+  for i=1,100 do t[#t] = nil end
+  assert(#t == 0)
+end
+
+do --- length increasing in loop with existing element
+  local t = {}
+  t[90] = 999
+  for i=1,100 do t[#t+1] = i end
+  assert(#t > 100 and t[#t] == 100)
+end
+
+do --- length decreasing in loop with erased element
+  local t = {}
+  for i=1,100 do t[i] = i end
+  t[10] = nil
+  for i=1,99 do t[#t] = nil end
+  assert(#t == 0)
+end
diff --git a/test/LuaJIT-tests/lang/meta/arith.lua b/test/LuaJIT-tests/lang/meta/arith.lua
new file mode 100644
index 0000000..17de4c8
--- /dev/null
+++ b/test/LuaJIT-tests/lang/meta/arith.lua
@@ -0,0 +1,118 @@
+local function create(arith, v1, v2)
+  local meta = {
+    __add=function(a,b) return arith("add", a, b) end,
+    __sub=function(a,b) return arith("sub", a, b) end,
+    __mul=function(a,b) return arith("mul", a, b) end,
+    __div=function(a,b) return arith("div", a, b) end,
+    __mod=function(a,b) return arith("mod", a, b) end,
+    __pow=function(a,b) return arith("pow", a, b) end,
+    __unm=function(a,b) return arith("unm", a, b) end,
+  }
+  return setmetatable({v1}, meta), setmetatable({v2}, meta)
+end
+
+do --- op
+  local a, b = create(function(op,a,b) return op end)
+  assert(a+b == "add")
+  assert(a-b == "sub")
+  assert(a*b == "mul")
+  assert(a/b == "div")
+  assert(a%b == "mod")
+  assert(a^b == "pow")
+  assert(-a == "unm")
+end
+
+do --- lhs
+  local a, b = create(function(op,a,b) return a[1] end, "foo", 42)
+  assert(a+b == "foo")
+  assert(a-b == "foo")
+  assert(a*b == "foo")
+  assert(a/b == "foo")
+  assert(a%b == "foo")
+  assert(a^b == "foo")
+  assert(-a == "foo")
+end
+
+do --- rhs
+  local a, b = create(function(op,a,b) return b[1] end, 42, "foo")
+  assert(a+b == "foo")
+  assert(a-b == "foo")
+  assert(a*b == "foo")
+  assert(a/b == "foo")
+  assert(a%b == "foo")
+  assert(a^b == "foo")
+  assert(-a == 42)
+end
+
+do --- meta only lhs
+  local a, b = create(function(op,a,b) return a[1]+b end, 39), 3
+  assert(a+b == 42)
+  assert(a-b == 42)
+  assert(a*b == 42)
+  assert(a/b == 42)
+  assert(a%b == 42)
+  assert(a^b == 42)
+end
+
+do --- meta only rhs
+  local a, b = 39, create(function(op,a,b) return a+b[1] end, 3)
+  assert(a+b == 42)
+  assert(a-b == 42)
+  assert(a*b == 42)
+  assert(a/b == 42)
+  assert(a%b == 42)
+  assert(a^b == 42)
+end
+
+do --- defaults string, int
+  local a, b = "39", 3
+  assert(a+b == 42)
+  assert(a-b == 36)
+  assert(a*b == 117)
+  assert(a/b == 13)
+  assert(a%b == 0)
+  assert(a^b == 59319)
+  assert(-a == -39)
+end
+
+do --- defaults int, string
+  local a, b = 39, "3"
+  assert(a+b == 42)
+  assert(a-b == 36)
+  assert(a*b == 117)
+  assert(a/b == 13)
+  assert(a%b == 0)
+  assert(a^b == 59319)
+  assert(-a == -39)
+end
+
+do --- defaults string, string
+  local a, b = "39", "3"
+  assert(a+b == 42)
+  assert(a-b == 36)
+  assert(a*b == 117)
+  assert(a/b == 13)
+  assert(a%b == 0)
+  assert(a^b == 59319)
+  assert(-a == -39)
+end
+
+do --- defaults string, kint
+  local a = "39"
+  assert(a+3 == 42)
+  assert(a-3 == 36)
+  assert(a*3 == 117)
+  assert(a/3 == 13)
+  assert(a%3 == 0)
+  assert(a^3 == 59319)
+end
+
+do --- defaults kint, string
+  local b = "3"
+  assert(39+b == 42)
+  assert(39-b == 36)
+  assert(39*b == 117)
+  assert(39/b == 13)
+  assert(39%b == 0)
+  assert(39^b == 59319)
+end
diff --git a/test/LuaJIT-tests/lang/meta/arith_jit.lua b/test/LuaJIT-tests/lang/meta/arith_jit.lua
new file mode 100644
index 0000000..2cb35db
--- /dev/null
+++ b/test/LuaJIT-tests/lang/meta/arith_jit.lua
@@ -0,0 +1,68 @@
+
+do --- assert rhs
+  local t = {}
+  local mt = {
+    __add = function(a, b) assert(b == t); return a+11 end,
+    __sub = function(a, b) assert(b == t); return a+12 end,
+    __mul = function(a, b) assert(b == t); return a+13 end,
+    __div = function(a, b) assert(b == t); return a+14 end,
+    __mod = function(a, b) assert(b == t); return a+15 end,
+    __pow = function(a, b) assert(b == t); return a+16 end,
+    __unm = function(a, b) assert(a == t and b == t); return 17 end,
+  }
+  t = setmetatable(t, mt)
+  do local x = 0; for i=1,100 do x = x + t end; assert(x == 1100); end
+  do local x = 0; for i=1,100 do x = x - t end; assert(x == 1200); end
+  do local x = 0; for i=1,100 do x = x * t end; assert(x == 1300); end
+  do local x = 0; for i=1,100 do x = x / t end; assert(x == 1400); end
+  do local x = 0; for i=1,100 do x = x % t end; assert(x == 1500); end
+  do local x = 0; for i=1,100 do x = x ^ t end; assert(x == 1600); end
+  do local x = 0; for i=1,100 do x = x + (-t) end; assert(x == 1700); end
+end
+
+do --- assert lhs
+  local t = {}
+  local mt = {
+    __add = function(a, b) assert(a == t); return b+11 end,
+    __sub = function(a, b) assert(a == t); return b+12 end,
+    __mul = function(a, b) assert(a == t); return b+13 end,
+    __div = function(a, b) assert(a == t); return b+14 end,
+    __mod = function(a, b) assert(a == t); return b+15 end,
+    __pow = function(a, b) assert(a == t); return b+16 end,
+  }
+  t = setmetatable(t, mt)
+  do local x = 0; for i=1,100 do x = t + x end; assert(x == 1100); end
+  do local x = 0; for i=1,100 do x = t - x end; assert(x == 1200); end
+  do local x = 0; for i=1,100 do x = t * x end; assert(x == 1300); end
+  do local x = 0; for i=1,100 do x = t / x end; assert(x == 1400); end
+  do local x = 0; for i=1,100 do x = t % x end; assert(x == 1500); end
+  do local x = 0; for i=1,100 do x = t ^ x end; assert(x == 1600); end
+end
+
+do --- assert both sides
+  local t = {}
+  local mt = {
+    __add = function(a, b) assert(a == t and b == t); return 11 end,
+    __sub = function(a, b) assert(a == t and b == t); return 12 end,
+    __mul = function(a, b) assert(a == t and b == t); return 13 end,
+    __div = function(a, b) assert(a == t and b == t); return 14 end,
+    __mod = function(a, b) assert(a == t and b == t); return 15 end,
+    __pow = function(a, b) assert(a == t and b == t); return 16 end,
+  }
+  t = setmetatable(t, mt)
+  do local x = 0; for i=1,100 do x = t + t end; assert(x == 11); end
+  do local x = 0; for i=1,100 do x = t - t end; assert(x == 12); end
+  do local x = 0; for i=1,100 do x = t * t end; assert(x == 13); end
+  do local x = 0; for i=1,100 do x = t / t end; assert(x == 14); end
+  do local x = 0; for i=1,100 do x = t % t end; assert(x == 15); end
+  do local x = 0; for i=1,100 do x = t ^ t end; assert(x == 16); end
+end
+
+do --- adjust no result to one result
+  local t = {}
+  local mt = { __add = function(a, b) end }
+  t = setmetatable(t, mt)
+  local x
+  for i=1,100 do x = t+t end
+  assert(x == nil)
+end
diff --git a/test/LuaJIT-tests/lang/meta/call.lua b/test/LuaJIT-tests/lang/meta/call.lua
new file mode 100644
index 0000000..c77c0dd
--- /dev/null
+++ b/test/LuaJIT-tests/lang/meta/call.lua
@@ -0,0 +1,81 @@
+
+local function callmeta(o, a, b)
+  return o, a, b
+end
+
+local meta = { __call = callmeta }
+
+do --- table
+  local t = setmetatable({}, meta)
+  local o,a,b = t()
+  assert(o == t and a == nil and b == nil)
+  local o,a,b = t("foo")
+  assert(o == t and a == "foo" and b == nil)
+  local o,a,b = t("foo", "bar")
+  assert(o == t and a == "foo" and b == "bar")
+end
+
+do --- userdata +lua<5.2
+  local u = newproxy(true)
+  getmetatable(u).__call = callmeta
+
+  local o,a,b = u()
+  assert(o == u and a == nil and b == nil)
+  local o,a,b = u("foo")
+  assert(o == u and a == "foo" and b == nil)
+  local o,a,b = u("foo", "bar")
+  assert(o == u and a == "foo" and b == "bar")
+end
+
+do --- number
+  debug.setmetatable(0, meta)
+  local o,a,b = (42)()
+  assert(o == 42 and a == nil and b == nil)
+  local o,a,b = (42)("foo")
+  assert(o == 42 and a == "foo" and b == nil)
+  local o,a,b = (42)("foo", "bar")
+  assert(o == 42 and a == "foo" and b == "bar")
+  debug.setmetatable(0, nil)
+end
+
+do --- table with changing metamethod
+  local tc = setmetatable({}, { __call = function(o,a,b) return o end})
+  local ta = setmetatable({}, { __add = tc})
+  local o,a = ta + ta
+  assert(o == tc and a == nil)
+
+  getmetatable(tc).__call = function(o,a,b) return a end
+  local o,a = ta + ta
+  assert(o == ta and a == nil)
+end
+
+do --- jit table
+  local t = setmetatable({}, { __call = function(t, a) return 100-a end })
+  for i=1,100 do assert(t(i) == 100-i) end
+end
+
+do --- jit table rawget as metamethod
+  local t = setmetatable({}, { __call = rawget })
+  for i=1,100 do t[i] = 100-i end
+  for i=1,100 do assert(t(i) == 100-i) end
+end
+
+do --- jit number
+  debug.setmetatable(0, { __call = function(n) return 100-n end })
+  for i=1,100 do assert((i)() == 100-i) end
+  debug.setmetatable(0, nil)
+end
+
+do --- jit newindex pcall
+  local t = setmetatable({}, { __newindex = pcall, __call = rawset })
+  for i=1,100 do t[i] = 100-i end
+  for i=1,100 do assert(t[i] == 100-i) end
+end
+
+do --- jit index pcall
+  local t = setmetatable({}, {
+    __index = pcall, __newindex = rawset,
+    __call = function(t, i) t[i] = 100-i end,
+  })
+  for i=1,100 do assert(t[i] == true and rawget(t, i) == 100-i) end
+end
diff --git a/test/LuaJIT-tests/lang/meta/cat.lua b/test/LuaJIT-tests/lang/meta/cat.lua
new file mode 100644
index 0000000..48a89e4
--- /dev/null
+++ b/test/LuaJIT-tests/lang/meta/cat.lua
@@ -0,0 +1,61 @@
+local function create(cat, v1, v2)
+  local meta = { __concat = cat }
+  return setmetatable({v1}, meta), setmetatable({v2}, meta)
+end
+
+do --- default
+  local a, b, c = "foo", "bar", "baz"
+  assert(a..b == "foobar")
+  assert(a..b..c == "foobarbaz")
+end
+
+do --- lhs
+  local a, b = create(function(a, b) return a end)
+  assert(a..b == a)
+  assert(b..a == b)
+  assert(a..b..b == a)
+  assert(a..a..b == a)
+  assert(a..b..a == a)
+  assert(a..b..b..b..b..b..b..b == a)
+end
+
+do --- rhs
+  local a, b = create(function(a, b) return b end)
+  assert(a..b == b)
+  assert(b..a == a)
+  assert(a..b..b == b)
+  assert(a..a..b == b)
+  assert(b..b..a == a)
+  assert(a..a..a..a..a..a..a..b == b)
+end
+
+do --- mixed types
+  local a, b = create(function(a, b)
+    return (type(a) == "string" and a or a[1])..
+	   (type(b) == "string" and b or b[1])
+  end, "a", "b")
+  assert(a..b == "ab")
+  assert(a..b == "ab")
+  assert(a..b..b == "abb")
+  assert(a..b..a == "aba")
+  assert(a..a..a..a..a..a..a..b == "aaaaaaab")
+  assert(a..a..a.."x".."x"..a..a..b == "aaaxxaab")
+  assert("x"..a..a..a..a..a..a..b == "xaaaaaab")
+  assert(a..b..a..b..a.."x".."x".."x" == "ababaxxx")
+end
+
+do --- jit mixed types
+  local a, b = create(function(a, b)
+    if a ~= b then local x = gg end
+    return (type(a) == "string" and a or a[1])..
+	   (type(b) == "string" and b or b[1])
+  end, "a", "b")
+  local y
+  for i=1,100 do y = a..b end
+  assert(y == "ab")
+  for i=1,100 do y = a..b.."x" end
+  assert(y == "abx")
+  for i=1,100 do y = a..b.. 1 .. "z" end
+  assert(y == "ab1z")
+end
+
diff --git a/test/LuaJIT-tests/lang/meta/comp.lua b/test/LuaJIT-tests/lang/meta/comp.lua
new file mode 100644
index 0000000..23f18b0
--- /dev/null
+++ b/test/LuaJIT-tests/lang/meta/comp.lua
@@ -0,0 +1,120 @@
+
+local function create(comp, v1, v2)
+  local meta = {
+    __lt=function(a,b) return comp("lt", a, b) end,
+    __le=function(a,b) return comp("le", a, b) end,
+  }
+  return setmetatable({v1}, meta), setmetatable({v2}, meta)
+end
+
+do --- __lt and __le xop
+  local xop
+  local a, b = create(function(op,a,b) xop = op; return "" end)
+  assert(a<b == true and xop == "lt"); xop = nil
+  assert(a>b == true and xop == "lt"); xop = nil
+  assert(a<=b == true and xop == "le"); xop = nil
+  assert(a>=b == true and xop == "le"); xop = nil
+
+  assert(not (a<b) == false and xop == "lt"); xop = nil
+  assert(not (a>b) == false and xop == "lt"); xop = nil
+  assert(not (a<=b) == false and xop == "le"); xop = nil
+  assert(not (a>=b) == false and xop == "le"); xop = nil
+
+  -- __le metamethod is optional and substituted with arg+res inverted __lt.
+  local f = getmetatable(a).__le
+  getmetatable(a).__le = nil
+  assert(a<b == true and xop == "lt"); xop = nil
+  assert(a>b == true and xop == "lt"); xop = nil
+  assert(a<=b == false and xop == "lt"); xop = nil
+  assert(a>=b == false and xop == "lt"); xop = nil
+
+  assert(not (a<b) == false and xop == "lt"); xop = nil
+  assert(not (a>b) == false and xop == "lt"); xop = nil
+  assert(not (a<=b) == true and xop == "lt"); xop = nil
+  assert(not (a>=b) == true and xop == "lt"); xop = nil
+  getmetatable(a).__le = f
+
+  -- Different metatable, but same metamethod works, too.
+  setmetatable(b, { __lt = getmetatable(b).__lt, __le = getmetatable(b).__le })
+  assert(a<b == true and xop == "lt"); xop = nil
+  assert(a>b == true and xop == "lt"); xop = nil
+  assert(a<=b == true and xop == "le"); xop = nil
+  assert(a>=b == true and xop == "le"); xop = nil
+
+  assert(not (a<b) == false and xop == "lt"); xop = nil
+  assert(not (a>b) == false and xop == "lt"); xop = nil
+  assert(not (a<=b) == false and xop == "le"); xop = nil
+  assert(not (a>=b) == false and xop == "le"); xop = nil
+end
+
+do --- __lt and __le values
+  local a, b = create(function(op,a,b)
+    if op == "lt" then return a[1]<b[1] else return a[1]<=b[1] end end, 1, 2)
+  assert(a<b == true)
+  assert(a>b == false)
+  assert(a<=b == true)
+  assert(a>=b == false)
+
+  assert(not (a<b) == false)
+  assert(not (a>b) == true)
+  assert(not (a<=b) == false)
+  assert(not (a>=b) == true)
+
+  b[1] = 1
+  assert(a<b == false)
+  assert(a>b == false)
+  assert(a<=b == true)
+  assert(a>=b == true)
+
+  assert(not (a<b) == true)
+  assert(not (a>b) == true)
+  assert(not (a<=b) == false)
+  assert(not (a>=b) == false)
+
+  a[1] = 2
+  assert(a<b == false)
+  assert(a>b == true)
+  assert(a<=b == false)
+  assert(a>=b == true)
+
+  assert(not (a<b) == true)
+  assert(not (a>b) == false)
+  assert(not (a<=b) == true)
+  assert(not (a>=b) == false)
+
+  -- __le metamethod is optional and substituted with arg+res inverted __lt.
+  getmetatable(a).__le = nil
+  a[1] = 1
+  b[1] = 2
+  assert(a<b == true)
+  assert(a>b == false)
+  assert(a<=b == true)
+  assert(a>=b == false)
+
+  assert(not (a<b) == false)
+  assert(not (a>b) == true)
+  assert(not (a<=b) == false)
+  assert(not (a>=b) == true)
+
+  b[1] = 1
+  assert(a<b == false)
+  assert(a>b == false)
+  assert(a<=b == true)
+  assert(a>=b == true)
+
+  assert(not (a<b) == true)
+  assert(not (a>b) == true)
+  assert(not (a<=b) == false)
+  assert(not (a>=b) == false)
+
+  a[1] = 2
+  assert(a<b == false)
+  assert(a>b == true)
+  assert(a<=b == false)
+  assert(a>=b == true)
+
+  assert(not (a<b) == true)
+  assert(not (a>b) == false)
+  assert(not (a<=b) == true)
+  assert(not (a>=b) == false)
+end
diff --git a/test/LuaJIT-tests/lang/meta/comp_jit.lua b/test/LuaJIT-tests/lang/meta/comp_jit.lua
new file mode 100644
index 0000000..d0a19d8
--- /dev/null
+++ b/test/LuaJIT-tests/lang/meta/comp_jit.lua
@@ -0,0 +1,104 @@
+do --- coverage
+  local lt, le = false, false
+  local t, u = {}, {}
+  local x, ax, bx
+  local function ck(xx, a, b)
+    if x ~= xx then error("bad x", 2) end
+    if ax ~= a then error("bad ax", 2) end
+    if bx ~= b then error("bad bx", 2) end
+  end
+  local mt = {
+    __lt = function(a, b) ax=a; bx=b; return lt end,
+    __le = function(a, b) ax=a; bx=b; return le end,
+  }
+  t = setmetatable(t, mt)
+  u = setmetatable(u, mt)
+  lt, le = false, false
+  x = 0; for i=1,100 do x = t < u and 2 or 1 end        ck(1, t, u)
+  x = 0; for i=1,100 do x = t <= u and 2 or 1 end       ck(1, t, u)
+  x = 0; for i=1,100 do x = t > u and 2 or 1 end        ck(1, u, t)
+  x = 0; for i=1,100 do x = t >= u and 2 or 1 end       ck(1, u, t)
+  x = 0; for i=1,100 do x = not (t < u) and 2 or 1 end  ck(2, t, u)
+  x = 0; for i=1,100 do x = not (t <= u) and 2 or 1 end ck(2, t, u)
+  x = 0; for i=1,100 do x = not (t > u) and 2 or 1 end  ck(2, u, t)
+  x = 0; for i=1,100 do x = not (t >= u) and 2 or 1 end ck(2, u, t)
+  lt, le = false, true
+  x = 0; for i=1,100 do x = t < u and 2 or 1 end        ck(1, t, u)
+  x = 0; for i=1,100 do x = t <= u and 2 or 1 end       ck(2, t, u)
+  x = 0; for i=1,100 do x = t > u and 2 or 1 end        ck(1, u, t)
+  x = 0; for i=1,100 do x = t >= u and 2 or 1 end       ck(2, u, t)
+  x = 0; for i=1,100 do x = not (t < u) and 2 or 1 end  ck(2, t, u)
+  x = 0; for i=1,100 do x = not (t <= u) and 2 or 1 end ck(1, t, u)
+  x = 0; for i=1,100 do x = not (t > u) and 2 or 1 end  ck(2, u, t)
+  x = 0; for i=1,100 do x = not (t >= u) and 2 or 1 end ck(1, u, t)
+  lt, le = true, false
+  x = 0; for i=1,100 do x = t < u and 2 or 1 end        ck(2, t, u)
+  x = 0; for i=1,100 do x = t <= u and 2 or 1 end       ck(1, t, u)
+  x = 0; for i=1,100 do x = t > u and 2 or 1 end        ck(2, u, t)
+  x = 0; for i=1,100 do x = t >= u and 2 or 1 end       ck(1, u, t)
+  x = 0; for i=1,100 do x = not (t < u) and 2 or 1 end  ck(1, t, u)
+  x = 0; for i=1,100 do x = not (t <= u) and 2 or 1 end ck(2, t, u)
+  x = 0; for i=1,100 do x = not (t > u) and 2 or 1 end  ck(1, u, t)
+  x = 0; for i=1,100 do x = not (t >= u) and 2 or 1 end ck(2, u, t)
+  lt, le = true, true
+  x = 0; for i=1,100 do x = t < u and 2 or 1 end        ck(2, t, u)
+  x = 0; for i=1,100 do x = t <= u and 2 or 1 end       ck(2, t, u)
+  x = 0; for i=1,100 do x = t > u and 2 or 1 end        ck(2, u, t)
+  x = 0; for i=1,100 do x = t >= u and 2 or 1 end       ck(2, u, t)
+  x = 0; for i=1,100 do x = not (t < u) and 2 or 1 end  ck(1, t, u)
+  x = 0; for i=1,100 do x = not (t <= u) and 2 or 1 end ck(1, t, u)
+  x = 0; for i=1,100 do x = not (t > u) and 2 or 1 end  ck(1, u, t)
+  x = 0; for i=1,100 do x = not (t >= u) and 2 or 1 end ck(1, u, t)
+  mt.__le = nil
+  lt = false
+  x = 0; for i=1,100 do x = t < u and 2 or 1 end        ck(1, t, u)
+  x = 0; for i=1,100 do x = t <= u and 2 or 1 end       ck(2, u, t)
+  x = 0; for i=1,100 do x = t > u and 2 or 1 end        ck(1, u, t)
+  x = 0; for i=1,100 do x = t >= u and 2 or 1 end       ck(2, t, u)
+  x = 0; for i=1,100 do x = not (t < u) and 2 or 1 end  ck(2, t, u)
+  x = 0; for i=1,100 do x = not (t <= u) and 2 or 1 end ck(1, u, t)
+  x = 0; for i=1,100 do x = not (t > u) and 2 or 1 end  ck(2, u, t)
+  x = 0; for i=1,100 do x = not (t >= u) and 2 or 1 end ck(1, t, u)
+  lt = true
+  x = 0; for i=1,100 do x = t < u and 2 or 1 end        ck(2, t, u)
+  x = 0; for i=1,100 do x = t <= u and 2 or 1 end       ck(1, u, t)
+  x = 0; for i=1,100 do x = t > u and 2 or 1 end        ck(2, u, t)
+  x = 0; for i=1,100 do x = t >= u and 2 or 1 end       ck(1, t, u)
+  x = 0; for i=1,100 do x = not (t < u) and 2 or 1 end  ck(1, t, u)
+  x = 0; for i=1,100 do x = not (t <= u) and 2 or 1 end ck(2, u, t)
+  x = 0; for i=1,100 do x = not (t > u) and 2 or 1 end  ck(1, u, t)
+  x = 0; for i=1,100 do x = not (t >= u) and 2 or 1 end ck(2, t, u)
+end
+
+do --- Mixed metamethods for ordered comparisons.
+  local mt1 = { __lt = function(a, b) return a[1] < b[1] end }
+  local mt2 = { __lt = function(a, b) return a[1] < b[1] end }
+  local t1 = setmetatable({1}, mt1)
+  local t2 = setmetatable({2}, mt2)
+  do
+    local x
+    for i=1,100 do x = t1 <= t1 end
+    assert(x == true)
+  end
+  local ok, ret = pcall(function()
+    local x
+    for i=1,100 do x = t1 < t2 end
+    return x
+  end)
+  if table.pack then
+    assert(ok and ret == true)
+  else
+    assert(not ok)
+  end
+  local ok, ret = pcall(function()
+    local x
+    for i=1,100 do x = t1 <= t2 end
+    return x
+  end)
+  if table.pack then
+    assert(ok and ret == true)
+  else
+    assert(not ok)
+  end
+end
+
diff --git a/test/LuaJIT-tests/lang/meta/debuginfo.lua b/test/LuaJIT-tests/lang/meta/debuginfo.lua
new file mode 100644
index 0000000..a99941f
--- /dev/null
+++ b/test/LuaJIT-tests/lang/meta/debuginfo.lua
@@ -0,0 +1,81 @@
+
+local what
+
+local function mm(a, b)
+  local dbg = debug.getinfo(1)
+  what = dbg.namewhat == "metamethod" and dbg.name or
+					  dbg.namewhat.." "..(dbg.name or "?")
+end
+
+local function ck(s)
+  assert(what == s, "bad debug info for metamethod "..s)
+end
+
+local mt = {
+  __index = mm,
+  __newindex = mm,
+  __eq = mm,
+  __add = mm,
+  __sub = mm,
+  __mul = mm,
+  __div = mm,
+  __mod = mm,
+  __pow = mm,
+  __unm = mm,
+  __len = mm,
+  __lt = mm,
+  __le = mm,
+  __concat = mm,
+  __call = mm,
+}
+
+do --- table metamethods +goto
+  local t = setmetatable({}, mt)
+  local t2 = setmetatable({}, mt)
+
+  local x = t.x;		ck("__index")
+  t.x = 1;		ck("__newindex")
+  local x = t + t;	ck("__add")
+  local x = t - t;	ck("__sub")
+  local x = t * t;	ck("__mul")
+  local x = t / t;	ck("__div")
+  local x = t % t;	ck("__mod")
+  local x = t ^ t;	ck("__pow")
+  local x = -t;		ck("__unm")
+  local x = t..t;		ck("__concat")
+  local x = t();		ck("local t")
+
+  local x = t == t2;	ck("__eq")
+  local x = t ~= t2;	ck("__eq")
+  local x = t < t2;	ck("__lt")
+  local x = t > t2;	ck("__lt")
+  local x = t <= t2;	ck("__le")
+  local x = t >= t2;	ck("__le")
+end
+
+do --- userdata metamethods +luajit
+  local u = newproxy()
+  local u2 = newproxy()
+  debug.setmetatable(u, mt)
+  debug.setmetatable(u2, mt)
+
+  local x = u.x;		ck("__index")
+  u.x = 1;		ck("__newindex")
+  local x = u + u;	ck("__add")
+  local x = u - u;	ck("__sub")
+  local x = u * u;	ck("__mul")
+  local x = u / u;	ck("__div")
+  local x = u % u;	ck("__mod")
+  local x = u ^ u;	ck("__pow")
+  local x = -u;		ck("__unm")
+  local x = #u;		ck("__len")
+  local x = u..u;		ck("__concat")
+  local x = u();		ck("local u")
+
+  local x = u == u2;	ck("__eq")
+  local x = u ~= u2;	ck("__eq")
+  local x = u < u2;	ck("__lt")
+  local x = u > u2;	ck("__lt")
+  local x = u <= u2;	ck("__le")
+  local x = u >= u2;	ck("__le")
+end
diff --git a/test/LuaJIT-tests/lang/meta/eq.lua b/test/LuaJIT-tests/lang/meta/eq.lua
new file mode 100644
index 0000000..ebf6043
--- /dev/null
+++ b/test/LuaJIT-tests/lang/meta/eq.lua
@@ -0,0 +1,30 @@
+local function create(equal, v1, v2)
+  local meta = { __eq = equal }
+  return setmetatable({v1}, meta), setmetatable({v2}, meta)
+end
+
+do --- __eq xop
+  local xop
+  local a, b = create(function(a,b) xop = "eq" return "" end)
+  assert(a==b == true and xop == "eq"); xop = nil
+  assert(a~=b == false and xop == "eq"); xop = nil
+
+  -- Different metatable, but same metamethod works, too.
+  setmetatable(b, { __eq = getmetatable(b).__eq })
+  assert(a==b == true and xop == "eq"); xop = nil
+  assert(a~=b == false and xop == "eq"); xop = nil
+end
+
+do --- __eq values
+  local a, b = create(function(a,b) return a[1] == b[1] end, 1, 2)
+  assert(a==b == false)
+  assert(a~=b == true)
+
+  b[1] = 1
+  assert(a==b == true)
+  assert(a~=b == false)
+
+  a[1] = 2
+  assert(a==b == false)
+  assert(a~=b == true)
+end
diff --git a/test/LuaJIT-tests/lang/meta/eq_jit.lua b/test/LuaJIT-tests/lang/meta/eq_jit.lua
new file mode 100644
index 0000000..47e1420
--- /dev/null
+++ b/test/LuaJIT-tests/lang/meta/eq_jit.lua
@@ -0,0 +1,35 @@
+
+do --- coverage
+  local eq = false
+  local t, u = {}, {}
+  local x, ax, bx
+  local function ck(xx, a, b)
+    if x ~= xx then error("bad x", 2) end
+    if ax ~= a then error("bad ax", 2) end
+    if bx ~= b then error("bad bx", 2) end
+  end
+  local mt = {
+    __eq = function(a, b) ax=a; bx=b; return eq end,
+  }
+  t = setmetatable(t, mt)
+  u = setmetatable(u, mt)
+  eq = false
+  x = 0; for i=1,100 do x = t == u and 2 or 1 end       ck(1, t, u)
+  x = 0; for i=1,100 do x = t ~= u and 2 or 1 end       ck(2, t, u)
+  x = 0; for i=1,100 do x = not (t == u) and 2 or 1 end ck(2, t, u)
+  x = 0; for i=1,100 do x = not (t ~= u) and 2 or 1 end ck(1, t, u)
+  eq = true
+  x = 0; for i=1,100 do x = t == u and 2 or 1 end       ck(2, t, u)
+  x = 0; for i=1,100 do x = t ~= u and 2 or 1 end       ck(1, t, u)
+  x = 0; for i=1,100 do x = not (t == u) and 2 or 1 end ck(1, t, u)
+  x = 0; for i=1,100 do x = not (t ~= u) and 2 or 1 end ck(2, t, u)
+end
+
+do --- non-constant objects +bit
+  local bit = require("bit")
+  local mt = { __eq = function(a, b) return true end }
+  local tt = { [0] = setmetatable({}, mt), setmetatable({}, mt) }
+  for i=0,100 do
+    assert(tt[0] == tt[bit.band(i, 1)])
+  end
+end
diff --git a/test/LuaJIT-tests/lang/meta/framegap.lua b/test/LuaJIT-tests/lang/meta/framegap.lua
new file mode 100644
index 0000000..0080633
--- /dev/null
+++ b/test/LuaJIT-tests/lang/meta/framegap.lua
@@ -0,0 +1,24 @@
+do --- untitled
+  local t = setmetatable({}, { __add = function(a, b)
+    if b > 200 then
+      for j=1,10 do end
+      return b+3
+    elseif b > 100 then
+      return b+2
+    else
+      return b+1
+    end
+  end })
+
+  local function f(t, i)
+    do return t+i end
+    -- Force large frame with unassigned slots below mm.
+    do local a,b,c,d,e,f,g,h,i,j,k end
+  end
+
+  local x = 0
+  for i=1,300 do
+    x = f(t, i)
+  end
+  assert(x == 303)
+end
diff --git a/test/LuaJIT-tests/lang/meta/index b/test/LuaJIT-tests/lang/meta/index
new file mode 100644
index 0000000..f114e78
--- /dev/null
+++ b/test/LuaJIT-tests/lang/meta/index
@@ -0,0 +1,14 @@
+arith.lua
+arith_jit.lua
+call.lua
+cat.lua
+comp.lua
+comp_jit.lua
+eq.lua
+eq_jit.lua
+framegap.lua
+index.lua
+len.lua
+newindex.lua
+nomm.lua
+debuginfo.lua
diff --git a/test/LuaJIT-tests/lang/meta/index.lua b/test/LuaJIT-tests/lang/meta/index.lua
new file mode 100644
index 0000000..4d6d0ff
--- /dev/null
+++ b/test/LuaJIT-tests/lang/meta/index.lua
@@ -0,0 +1,60 @@
+do --- table 1
+  local t=setmetatable({}, {__index=function(t,k)
+    return 100-k
+  end})
+
+  for i=1,100 do assert(t[i] == 100-i) end
+
+  for i=1,100 do t[i] = i end
+  for i=1,100 do assert(t[i] == i) end
+
+  for i=1,100 do t[i] = nil end
+  for i=1,100 do assert(t[i] == 100-i) end
+end
+
+do --- table 2
+  local x
+  local t2=setmetatable({}, {__index=function(t,k)
+    x = k
+  end})
+
+  assert(t2[1] == nil)
+  assert(x == 1)
+
+  assert(t2.foo == nil)
+  assert(x == "foo")
+end
+
+do --- userdata +lua<5.2
+  local u = newproxy(true)
+  getmetatable(u).__index = { foo = u, bar = 42 }
+
+  local x = 0
+  for i=1,100 do
+    x = x + u.bar
+    u = u.foo
+  end
+  assert(x == 4200)
+
+  x = 0
+  for i=1,100 do
+    u = u.foo
+    x = x + u.bar
+  end
+  assert(x == 4200)
+end
+
+do --- string
+  local s = "foo"
+  local mt = debug.getmetatable(s)
+  debug.setmetatable(s, {__index = {s = s, len = string.len}})
+  local x = 0
+  local t = {}
+  for i=1,100 do
+    x = x + s:len()
+    s = s.s
+    t[s] = t -- Hash store with same type prevents hoisting
+  end
+  debug.setmetatable(s, mt)
+  assert(x == 300)
+end
diff --git a/test/LuaJIT-tests/lang/meta/len.lua b/test/LuaJIT-tests/lang/meta/len.lua
new file mode 100644
index 0000000..2410daa
--- /dev/null
+++ b/test/LuaJIT-tests/lang/meta/len.lua
@@ -0,0 +1,42 @@
+local compat52 = table.pack
+local mt = { __len = function(o, o2)
+  if compat52 then
+    assert(o2 == o)
+  else
+    assert(o2 == nil)
+  end
+  return 42
+end }
+
+do --- table
+  local t = {1,2,3}
+  assert(#t == 3)
+  assert(#"abcdef" == 6)
+
+  setmetatable(t, { __foo = function() end })
+  assert(#t == 3)
+  assert(#t == 3)
+
+  setmetatable(t, mt)
+  if compat52 then
+    assert(#t == 42) -- __len DOES work on tables.
+    assert(rawlen(t) == 3)
+  else
+    assert(#t == 3) -- __len does NOT work on tables.
+  end
+end
+
+do --- userdata +lua<5.2
+  local u = newproxy(true)
+  getmetatable(u).__len = function(o) return 42 end
+  assert(#u == 42)
+  local x = 0
+  for i=1,100 do x = x + #u end
+  assert(x == 4200)
+end
+
+do --- number
+  debug.setmetatable(0, mt)
+  assert(#1 == 42)
+  debug.setmetatable(0, nil)
+end
diff --git a/test/LuaJIT-tests/lang/meta/newindex.lua b/test/LuaJIT-tests/lang/meta/newindex.lua
new file mode 100644
index 0000000..6c46b8c
--- /dev/null
+++ b/test/LuaJIT-tests/lang/meta/newindex.lua
@@ -0,0 +1,69 @@
+do --- table 1
+  local t=setmetatable({}, {__newindex=function(t,k,v)
+    rawset(t, k, 100-v)
+  end})
+
+  for i=1,100 do t[i] = i end
+  for i=1,100 do assert(t[i] == 100-i) end
+
+  for i=1,100 do t[i] = i end
+  for i=1,100 do assert(t[i] == i) end
+
+  for i=1,100 do t[i] = nil end
+  for i=1,100 do t[i] = i end
+  for i=1,100 do assert(t[i] == 100-i) end
+end
+
+do --- jit gaining href
+  local count = 0
+  local t = setmetatable({ foo = nil },
+    { __newindex=function() count = count + 1 end })
+  for j=1,2 do
+    for i=1,100 do t.foo = 1 end
+    rawset(t, "foo", 1)
+  end
+  assert(count == 100)
+end
+
+do --- jit gaining aref
+  local count = 0
+  local t = setmetatable({ nil },
+    { __newindex=function() count = count + 1 end })
+  for j=1,2 do
+    for i=1,100 do t[1] = 1 end
+    rawset(t, 1, 1)
+  end
+  assert(count == 100)
+end
+
+do --- resize
+  local grandparent = {}
+  grandparent.__newindex = function(s,_,_) tostring(s) end
+
+  local parent = {}
+  parent.__newindex = parent
+  parent.bar = 1
+  setmetatable(parent, grandparent)
+
+  local child = setmetatable({}, parent)
+  child.foo = _
+end
+
+do --- str
+  local t=setmetatable({}, {__newindex=function(t,k,v)
+    assert(v == "foo"..k)
+    rawset(t, k, "bar"..k)
+  end})
+
+  for i=1,100 do t[i]="foo"..i end
+  for i=1,100 do assert(t[i] == "bar"..i) end
+
+  for i=1,100 do t[i]="baz"..i end
+  for i=1,100 do assert(t[i] == "baz"..i) end
+
+  local t=setmetatable({foo=1,bar=1,baz=1},{})
+  t.baz=nil
+  t.baz=2
+  t.baz=nil
+  t.baz=2
+end
diff --git a/test/LuaJIT-tests/lang/meta/nomm.lua b/test/LuaJIT-tests/lang/meta/nomm.lua
new file mode 100644
index 0000000..2b3db86
--- /dev/null
+++ b/test/LuaJIT-tests/lang/meta/nomm.lua
@@ -0,0 +1,21 @@
+
+do --- untitled
+  local keys = {}
+  for i=1,100 do keys[i] = "foo" end
+  keys[95] = "__index"
+  local function fidx(t, k) return 12345 end
+  local mt = { foo = 1, __index = "" }
+  local t = setmetatable({ 1 }, mt)
+  t[1] = nil
+  mt.__index = nil
+  local x = nil
+  for i=1,100 do
+    mt[keys[i]] = fidx
+    if t[1] then
+      if not x then x = i end
+      assert(t[1] == 12345)
+    end
+  end
+  assert(x == 95)
+end
+
diff --git a/test/LuaJIT-tests/lang/modulo.lua b/test/LuaJIT-tests/lang/modulo.lua
new file mode 100644
index 0000000..eddaea7
--- /dev/null
+++ b/test/LuaJIT-tests/lang/modulo.lua
@@ -0,0 +1,46 @@
+local assert, floor = assert, math.floor
+
+do --- integer equivalence
+  for x=-5,5 do
+    for y=-5,5 do
+      if y ~= 0 then
+        assert(x%y == x-floor(x/y)*y)
+      end
+    end
+  end
+end
+
+do --- fractional equivalence
+  for x=-5,5,0.25 do
+    for y=-5,5,0.25 do
+      if y ~= 0 then
+        assert(x%y == x-floor(x/y)*y)
+      end
+    end
+  end
+end
+
+do --- jit constant RHS
+  local y = 0
+  for x=-100,123 do
+    y = y + x%17
+  end
+  assert(y == 1777)
+end
+
+do --- jit constant LHS, with exit
+  local y = 0
+  for x=-100,123 do
+    if x ~= 0 then
+      y = y + 85%x
+    end
+  end
+  assert(y == 2059)
+end
+
+do --- divide by zero
+  local x = 1%0
+  assert(x ~= x)
+  x = floor(0/0)
+  assert(x ~= x)
+end
diff --git a/test/LuaJIT-tests/lang/self.lua b/test/LuaJIT-tests/lang/self.lua
new file mode 100644
index 0000000..d374666
--- /dev/null
+++ b/test/LuaJIT-tests/lang/self.lua
@@ -0,0 +1,19 @@
+do --- trivial setget
+  local t = {}
+
+  function t:set(x)
+    self.a=x
+  end
+
+  function t:get()
+    return self.a
+  end
+
+  t:set("foo")
+  assert(t:get() == "foo")
+  assert(t.a == "foo")
+
+  t:set(42)
+  assert(t:get() == 42)
+  assert(t.a == 42)
+end
diff --git a/test/LuaJIT-tests/lang/table.lua b/test/LuaJIT-tests/lang/table.lua
new file mode 100644
index 0000000..3ff38cf
--- /dev/null
+++ b/test/LuaJIT-tests/lang/table.lua
@@ -0,0 +1,32 @@
+do --- tables as keys in tables
+  local fwd, bck = {}, {}
+  for i = 1,100 do
+    local v = {}
+    fwd[i] = v
+    bck[v] = i
+  end
+  for i = 1,100 do
+    local v = fwd[i]
+    assert(type(v) == "table")
+    assert(bck[v] == i)
+  end
+end
+
+do --- some tables as keys in tables
+  local fwd, bck = {}, {}
+  for i = 1,100 do
+    local v = {}
+    fwd[i] = v
+    if i > 90 then
+      bck[v] = i
+    end
+  end
+  local n = 0
+  for i = 1, 100 do
+    local v = fwd[i]
+    if bck[v] then
+      n = n + 1
+    end
+  end
+  assert(n == 10)
+end
diff --git a/test/LuaJIT-tests/lang/tail_recursion.lua b/test/LuaJIT-tests/lang/tail_recursion.lua
new file mode 100644
index 0000000..78f071f
--- /dev/null
+++ b/test/LuaJIT-tests/lang/tail_recursion.lua
@@ -0,0 +1,20 @@
+do --- self
+  local tr1
+  function tr1(n)
+    if n <= 0 then return 0 end
+    return tr1(n-1)
+  end
+  assert(tr1(200) == 0)
+end
+
+do --- mutual
+  local tr1, tr2
+  function tr1(n)
+    if n <= 0 then return 0 end
+    return tr2(n-1)
+  end
+  function tr2(n)
+    return tr1(n)
+  end
+  assert(tr2(200) == 0)
+end
diff --git a/test/LuaJIT-tests/lang/upvalue/closure.lua b/test/LuaJIT-tests/lang/upvalue/closure.lua
new file mode 100644
index 0000000..faa4de1
--- /dev/null
+++ b/test/LuaJIT-tests/lang/upvalue/closure.lua
@@ -0,0 +1,84 @@
+do --- for
+  local z1, z2
+  for i=1,10 do
+    local function f() return i end
+    if z1 then z2 = f else z1 = f end
+  end
+  assert(z1() == 1)
+  assert(z2() == 10)
+end
+
+do --- while
+  local z1, z2
+  local i = 1
+  while i <= 10 do
+    local j = i
+    local function f() return j end
+    if z1 then z2 = f else z1 = f end
+    i = i + 1
+  end
+  assert(z1() == 1)
+  assert(z2() == 10)
+end
+
+do --- repeat
+  local z1, z2
+  local i = 1
+  repeat
+    local j = i
+    local function f() return j end
+    if z1 then z2 = f else z1 = f end
+    i = i + 1
+  until i > 10
+  assert(z1() == 1)
+  assert(z2() == 10)
+end
+
+do --- func
+  local function ff(x)
+    return function() return x end
+  end
+  local z1, z2
+  for i=1,10 do
+    local f = ff(i)
+    if z1 then z2 = f else z1 = f end
+  end
+  assert(z1() == 1)
+  assert(z2() == 10)
+end
+
+do --- recursive type change
+  local function f1(a)
+    if a > 0 then
+      local b = f1(a - 1)
+      return function()
+	      if type(b) == "function" then
+	        return a + b()
+	      end
+	      return a + b
+      end
+    end
+    return a
+  end
+
+  local function f2(a)
+    return f1(a)()
+  end
+
+  for i = 1, 41 do
+    local r = f2(4) + f2(4)
+    assert(r == 20)
+  end
+end
+
+do --- Don't mark upvalue as immutable if written to after prototype definition
+  local x = 1
+  local function f()
+    local y = 0
+    for i=1,100 do y=y+x end
+    return y
+  end
+  assert(f() == 100)
+  x = 2
+  assert(f() == 200)
+end
diff --git a/test/LuaJIT-tests/lang/upvalue/index b/test/LuaJIT-tests/lang/upvalue/index
new file mode 100644
index 0000000..3c170db
--- /dev/null
+++ b/test/LuaJIT-tests/lang/upvalue/index
@@ -0,0 +1 @@
+closure.lua
diff --git a/test/LuaJIT-tests/lang/vararg_jit.lua b/test/LuaJIT-tests/lang/vararg_jit.lua
new file mode 100644
index 0000000..4e78f96
--- /dev/null
+++ b/test/LuaJIT-tests/lang/vararg_jit.lua
@@ -0,0 +1,95 @@
+
+do --- 1
+  local function f(a, b, c, ...)
+    assert(c == nil)
+    assert(a == 100-b)
+    return 100-a, 100-b
+  end
+  for i=1,100 do
+    local x, y = f(i, 100-i)
+    assert(x == 100-i)
+    assert(y == i)
+  end
+end
+
+do --- 2
+  local function f(a, b, ...)
+    if a > b then return b end
+    return a
+  end
+  local x = 0
+  for i=1,200 do
+    x = x + f(i, 100, 99, 88, 77)
+  end
+  assert(x == 15050)
+end
+
+do --- 3
+  local function f(a, b, ...)
+    local c, d = ...
+    if c > d then return d end
+    return c
+  end
+  local x = 0
+  for i=1,200 do
+    x = x + f(77, 88, i, 100)
+  end
+  assert(x == 15050)
+end
+
+do --- 4
+  local function f(a, b, ...)
+    if a > b then end
+    return ...
+  end
+  local x = 0
+  for i=1,200 do
+    x = x + f(i, 100, i, 100)
+    assert(f(i, 100) == nil)
+    assert(f(i, 100, 2) == 2)
+  end
+  assert(x == 20100)
+end
+
+do --- 5
+  local function f(a, ...)
+    local x, y = 0, 0
+    for i=1,100 do
+      local b, c = ...
+      x = x + b
+      y = y + c
+    end
+    assert(x == 200 and y == 300)
+  end
+  f(1, 2, 3)
+end
+
+do --- 6
+  local function f(a, ...)
+    local t = {[0]=9, 9}
+    local v, w, x, y = 0, 0, 0, 0
+    for i=1,100 do
+      v, w = ...
+      t[0] = 9; t[1] = 9;
+      x, y = ...
+    end
+    assert(v == 2 and w == 3 and x == 2 and y == 3)
+  end
+  f(1, 2, 3)
+end
+
+do --- 7
+  local function f(a, b, ...)
+    for i=1,100 do
+      local c, d = ...
+      assert(a == c);
+      assert(b == d);
+    end
+  end
+  f(2, 3, 2, 3)
+  f(2, nil, 2)
+  f(nil, nil)
+  f(nil)
+  f()
+end
+
diff --git a/test/LuaJIT-tests/lib/base/assert.lua b/test/LuaJIT-tests/lib/base/assert.lua
new file mode 100644
index 0000000..9c30ba0
--- /dev/null
+++ b/test/LuaJIT-tests/lib/base/assert.lua
@@ -0,0 +1,33 @@
+do --- pass through one
+  assert(assert(true) == true)
+  assert(assert(3) == 3)
+  assert(assert(1.5) == 1.5)
+  assert(assert("x") == "x")
+  local f = function() end
+  assert(assert(f) == f)
+  local t = {}
+  assert(assert(t) == t)
+end
+
+do --- pass through many
+  local b, c = assert("b", "c")
+  assert(b == "b")
+  assert(c == "c")
+  local d, e, f, g = assert("d", 5, true, false)
+  assert(d == "d")
+  assert(e == 5)
+  assert(f == true)
+  assert(g == false)
+end
+
+do --- raise on nil
+  local ok, err = pcall(assert, nil)
+  assert(ok == false)
+  assert(err == "assertion failed!")
+end
+
+do --- raise on false
+  local ok, err = pcall(assert, false, "msg")
+  assert(ok == false)
+  assert(err == "msg")
+end
diff --git a/test/LuaJIT-tests/lib/base/error.lua b/test/LuaJIT-tests/lib/base/error.lua
new file mode 100644
index 0000000..9193085
--- /dev/null
+++ b/test/LuaJIT-tests/lib/base/error.lua
@@ -0,0 +1,43 @@
+do --- no message
+  local ok, msg = pcall(error)
+  assert(ok == false)
+  assert(msg == nil)
+end
+
+do --- level 0
+  local ok, msg = pcall(error, "emsg", 0)
+  assert(ok == false)
+  assert(msg == "emsg")
+end
+
+do --- default level
+  local ok, msg = pcall(error, "emsg")
+  assert(ok == false)
+  assert(msg == "emsg")
+end
+
+do --- default level in xpcall
+  local line
+  local ok, msg = xpcall(function()
+    local x
+    line = debug.getinfo(1, "l").currentline; error("emsg")
+  end, function(m)
+    assert(debug.getlocal(3, 1) == "x")
+    return m .."xp"
+  end)
+  assert(ok == false)
+  assert(msg:find("^.-:".. line ..": emsgxp$"))
+end
+
+do --- level 2 in xpcall
+  local line
+  local ok, msg = xpcall(function()
+    local function f() error("emsg", 2) end
+    line = debug.getinfo(1, "l").currentline; f()
+  end, function(m)
+    assert(debug.getlocal(4, 1) == "f")
+    return m .."xp2"
+  end)
+  assert(ok == false)
+  assert(msg:find("^.-:".. line ..": emsgxp2$"))
+end
diff --git a/test/LuaJIT-tests/lib/base/getfenv.lua b/test/LuaJIT-tests/lib/base/getfenv.lua
new file mode 100644
index 0000000..9c00ed7
--- /dev/null
+++ b/test/LuaJIT-tests/lib/base/getfenv.lua
@@ -0,0 +1,13 @@
+do --- untitled
+  local x
+  local function f()
+    x = getfenv(0)
+  end
+  local co = coroutine.create(f)
+  local t = {}
+  debug.setfenv(co, t)
+  for i=1,50 do f() f() f() end
+  assert(x == getfenv(0))
+  coroutine.resume(co)
+  assert(x == t)
+end
diff --git a/test/LuaJIT-tests/lib/base/getsetmetatable.lua b/test/LuaJIT-tests/lib/base/getsetmetatable.lua
new file mode 100644
index 0000000..7d57343
--- /dev/null
+++ b/test/LuaJIT-tests/lib/base/getsetmetatable.lua
@@ -0,0 +1,33 @@
+
+do --- get __metatable
+  local t = setmetatable({}, { __metatable = "foo" })
+  for i=1,100 do assert(getmetatable(t) == "foo") end
+end
+
+do --- jit smoke
+  local mt = {}
+  local t = setmetatable({}, mt)
+  for i=1,100 do assert(getmetatable(t) == mt) end
+  for i=1,100 do assert(setmetatable(t, mt) == t) end
+end
+
+do --- jit assorted
+  local mt = {}
+  local t = {}
+  for i=1,200 do t[i] = setmetatable({}, mt) end
+  t[150] = setmetatable({}, { __metatable = "foo" })
+  for i=1,200 do
+    if not pcall(setmetatable, t[i], mt) then assert(i == 150) end
+  end
+  for i=1,200 do assert(getmetatable(t[i]) == mt or i == 150) end
+  for i=1,200 do
+    if not pcall(setmetatable, t[i], nil) then assert(i == 150) end
+  end
+  for i=1,200 do assert(getmetatable(t[i]) == nil or i == 150) end
+end
+
+do --- jit get primitive metatable
+  local x = true
+  for i=1,100 do x = getmetatable(i) end
+  assert(x == nil)
+end
diff --git a/test/LuaJIT-tests/lib/base/index b/test/LuaJIT-tests/lib/base/index
new file mode 100644
index 0000000..942c53c
--- /dev/null
+++ b/test/LuaJIT-tests/lib/base/index
@@ -0,0 +1,11 @@
+assert.lua
+error.lua
+getfenv.lua +lua<5.2
+getsetmetatable.lua
+ipairs.lua
+next.lua
+pairs.lua
+pcall_jit.lua
+select.lua
+tonumber_tostring.lua
+xpcall_jit.lua +compat5.2
diff --git a/test/LuaJIT-tests/lib/base/ipairs.lua b/test/LuaJIT-tests/lib/base/ipairs.lua
new file mode 100644
index 0000000..a9de087
--- /dev/null
+++ b/test/LuaJIT-tests/lib/base/ipairs.lua
@@ -0,0 +1,41 @@
+do --- small integer values
+  local t = { 4,5,6,7,8,9,10 }
+  local n = 0
+  for i,v in ipairs(t) do
+    assert(v == i+3)
+    n = n + 1
+  end
+  assert(n == 7)
+end
+
+do --- jit key=value
+  local t = {}
+  for i=1,100 do t[i]=i end
+  local n = 0
+  for i,v in ipairs(t) do
+    assert(i == v)
+    n = n + 1
+  end
+  assert(n == 100)
+end
+
+do --- untitled
+  local t = {}
+  local o = {{}, {}}
+  for i=1,100 do
+    local c = i..""
+    t[i] = c
+    o[1][c] = i
+    o[2][c] = i
+  end
+  o[1]["90"] = nil
+
+  local n = 0
+  for _, c in ipairs(t) do
+    for i = 1, 2 do
+      o[i][c] = o[i][c] or 1
+      n = n + 1
+    end
+  end
+  assert(n == 200)
+end
diff --git a/test/LuaJIT-tests/lib/base/next.lua b/test/LuaJIT-tests/lib/base/next.lua
new file mode 100644
index 0000000..0e40615
--- /dev/null
+++ b/test/LuaJIT-tests/lib/base/next.lua
@@ -0,0 +1,17 @@
+do --- _G 1
+  local ok, err = pcall(next, _G, 1)
+  assert(not ok)
+  local ok, err = pcall(function() next(_G, 1) end)
+  assert(not ok)
+end
+
+do --- as iterator
+  local t = { foo = 9, bar = 10, 4, 5, 6 }
+  local r = {}
+  local function dummy() end
+  local function f(next)
+    for k,v in next,t,nil do r[#r+1] = k; if v == 5 then f(dummy) end end
+  end
+  f(next)
+  assert(#r == 5)
+end
diff --git a/test/LuaJIT-tests/lib/base/pairs.lua b/test/LuaJIT-tests/lib/base/pairs.lua
new file mode 100644
index 0000000..4d89d42
--- /dev/null
+++ b/test/LuaJIT-tests/lib/base/pairs.lua
@@ -0,0 +1,73 @@
+
+do --- nometatable
+  local t = {}
+  for i=1,10 do t[i] = i+100 end
+  local a, b = 0, 0
+  for j=1,100 do for k,v in ipairs(t) do a = a + k; b = b + v end end
+  assert(a == 5500)
+  assert(b == 105500)
+  a, b = 0, 0
+  for j=1,100 do for k,v in pairs(t) do a = a + k; b = b + v end end
+  assert(a == 5500)
+  assert(b == 105500)
+end
+
+do --- empty metatable
+  local t = setmetatable({}, {})
+  for i=1,10 do t[i] = i+100 end
+  local a, b = 0, 0
+  for j=1,100 do for k,v in ipairs(t) do a = a + k; b = b + v end end
+  assert(a == 5500)
+  assert(b == 105500)
+  a, b = 0, 0
+  for j=1,100 do for k,v in pairs(t) do a = a + k; b = b + v end end
+  assert(a == 5500)
+  assert(b == 105500)
+end
+
+do --- metamethods +compat5.2
+  local function iter(t, i)
+    i = i + 1
+    if t[i] then return i, t[i]+2 end
+  end
+  local function itergen(t)
+    return iter, t, 0
+  end
+  local t = setmetatable({}, { __pairs = itergen, __ipairs = itergen })
+  for i=1,10 do t[i] = i+100 end
+  local a, b = 0, 0
+  for j=1,100 do for k,v in ipairs(t) do a = a + k; b = b + v end end
+  assert(a == 5500)
+  assert(b == 107500)
+  a, b = 0, 0
+  for j=1,100 do for k,v in pairs(t) do a = a + k; b = b + v end end
+  assert(a == 5500)
+  assert(b == 107500)
+end
+
+do --- _G
+  local n = 0
+  for k,v in pairs(_G) do
+    assert(_G[k] == v)
+    n = n + 1
+  end
+  assert(n >= 35)
+end
+
+do --- count
+  local function count(t)
+    local n = 0
+    for i,v in pairs(t) do
+      n = n + 1
+    end
+    return n;
+  end
+  assert(count({ 4,5,6,nil,8,nil,10}) == 5)
+  assert(count({ [0] = 3, 4,5,6,nil,8,nil,10}) == 6)
+  assert(count({ foo=1, bar=2, baz=3 }) == 3)
+  assert(count({ foo=1, bar=2, baz=3, boo=4 }) == 4)
+  assert(count({ 4,5,6,nil,8,nil,10, foo=1, bar=2, baz=3 }) == 8)
+  local t = { foo=1, bar=2, baz=3, boo=4 }
+  t.bar = nil; t.boo = nil
+  assert(count(t) == 2)
+end
diff --git a/test/LuaJIT-tests/lib/base/pcall_jit.lua b/test/LuaJIT-tests/lib/base/pcall_jit.lua
new file mode 100644
index 0000000..dc9cd5f
--- /dev/null
+++ b/test/LuaJIT-tests/lib/base/pcall_jit.lua
@@ -0,0 +1,74 @@
+
+do --- square sum
+  local function f(x) return x*x end
+  local x = 0
+  for i=1,100 do
+    local ok1, ok2, ok3, y = pcall(pcall, pcall, f, i)
+    if not ok1 or not ok2 or not ok3 then break end
+    x = x + y
+  end
+  assert(x == 338350)
+end
+
+do --- sqrt square sum
+  local x = 0
+  for i=1,100 do
+    local ok1, ok2, ok3, y = pcall(pcall, pcall, math.sqrt, i*i)
+    if not ok1 or not ok2 or not ok3 then break end
+    x = x + y
+  end
+  assert(x == 5050)
+end
+
+do --- sum with error
+  local function f(x)
+    if x >= 150 then error("test", 0) end
+    return x end
+  local x = 0
+  for i=1,200 do
+    local ok1, ok2, ok3, y = pcall(pcall, pcall, f, i)
+    if not ok1 or not ok2 or not ok3 then
+      assert(ok1 and ok2 and not ok3)
+      assert(y == "test")
+      break
+    end
+    x = x + y
+  end
+  assert(x == 11175)
+end
+
+do --- sum or square
+  local function f(x)
+    if x >= 150 then return x*x end
+    return x
+  end
+  local x = 0
+  for i=1,200 do
+    local ok1, ok2, ok3, y = pcall(pcall, pcall, f, i)
+    if not ok1 or not ok2 or not ok3 then break end
+    x = x + y
+  end
+  assert(x == 1584100)
+end
+
+do --- sum or square with error
+  local function f(x)
+    if x >= 150 then
+      if x >= 175 then error("test", 0) end
+      return x*x
+    end
+    return x
+  end
+  local x = 0
+  for i=1,200 do
+    local ok1, ok2, ok3, y = pcall(pcall, pcall, f, i)
+    if not ok1 or not ok2 or not ok3 then
+      assert(ok1 and ok2 and not ok3)
+      assert(y == "test")
+      -- note: no break, so we get an exit to interpreter
+    else
+      x = x + y
+    end
+  end
+  assert(x == 668575)
+end
diff --git a/test/LuaJIT-tests/lib/base/select.lua b/test/LuaJIT-tests/lib/base/select.lua
new file mode 100644
index 0000000..8278e5e
--- /dev/null
+++ b/test/LuaJIT-tests/lib/base/select.lua
@@ -0,0 +1,105 @@
+
+do --- select #
+-- Test whether select("#", 3, 4) returns the correct number of arguments. 
+  local x = 0
+  for i=1,100 do
+    x = x + select("#", 3, 4)
+  end
+  assert(x == 200)
+end
+
+do --- select modf
+-- Test whether select("#", func()) also works with func returning multiple values
+  local x = 0
+  math.frexp(3)
+  for i=1,100 do
+    x = x + select("#", math.modf(i))
+  end
+  assert(x == 200)
+end
+
+do --- select 1 
+  local x = 0
+  for i=1,100 do
+    x = x + select(1, i)
+  end
+  assert(x == 5050)
+end
+
+do --- select 2
+  local x, y = 0, 0
+  for i=1,100 do
+    local a, b = select(2, 1, i, i+10)
+    x = x + a
+    y = y + b
+  end
+  assert(x == 5050 and y == 6050)
+end
+
+do --- select vararg #
+  local function f(a, ...)
+    local x = 0
+    for i=1,select('#', ...) do
+      x = x + select(i, ...)
+    end
+    assert(x == a)
+  end
+  for i=1,100 do
+    f(1, 1)
+    f(3, 1, 2)
+    f(15, 1, 2, 3, 4, 5)
+    f(0)
+    f(3200, string.byte(string.rep(" ", 100), 1, 100))
+  end
+end
+
+do --- select vararg i
+  local function f(a, ...)
+    local x = 0
+    for i=1,20 do
+      local b = select(i, ...)
+      if b then x = x + b else x = x + 9 end
+    end
+    assert(x == a)
+  end
+  for i=1,100 do
+    f(172, 1)
+    f(165, 1, 2)
+    f(150, 1, 2, 3, 4, 5)
+    f(180)
+    f(640, string.byte(string.rep(" ", 100), 1, 100))
+  end
+end
+
+do --- select vararg 4
+  local function f(a, ...)
+    local x = 0
+    for i=1,20 do
+      local b = select(4, ...)
+      if b then x = x + b else x = x + 9 end
+    end
+    assert(x == a)
+  end
+  for i=1,100 do
+    f(180, 1)
+    f(180, 1, 2)
+    f(80, 1, 2, 3, 4, 5)
+    f(180)
+    f(640, string.byte(string.rep(" ", 100), 1, 100))
+  end
+end
+
+do --- varg-select specialisation requires guard against select
+  local select = select
+  local exptyp = "number"
+  local function f(...)
+    for i = 1, 100 do
+      assert(type((select('#', ...))) == exptyp)
+      if i == 75 then
+        select = function() return "" end
+        exptyp = "string"
+      end
+    end
+  end
+  f(1)
+end
diff --git a/test/LuaJIT-tests/lib/base/tonumber_tostring.lua b/test/LuaJIT-tests/lib/base/tonumber_tostring.lua
new file mode 100644
index 0000000..e7f576c
--- /dev/null
+++ b/test/LuaJIT-tests/lib/base/tonumber_tostring.lua
@@ -0,0 +1,81 @@
+
+do --- tonumber int
+  local x = 0
+  for i=1,100 do x = x + tonumber(i) end
+  assert(x == 5050)
+end
+
+do --- tonumber float
+  local x = 0
+  for i=1.5,100.5 do x = x + tonumber(i) end
+  assert(x == 5100)
+end
+
+do --- tostring int / tonumber
+  local t = {}
+  for i=1,100 do t[i] = tostring(i) end
+  local x = 0
+  for i=1,100 do assert(type(t[i]) == "string"); x = x + tonumber(t[i]) end
+  assert(x == 5050)
+end
+
+do --- tostring float / tonumber
+  local t = {}
+  for i=1,100 do t[i] = tostring(i+0.5) end
+  local x = 0
+  for i=1,100 do assert(type(t[i]) == "string"); x = x + tonumber(t[i]) end
+  assert(x == 5100)
+end
+
+do --- tonumber table
+  for i=1,100 do assert(tonumber({}) == nil) end
+end
+
+do --- tostring int / tostring
+  local t = {}
+  for i=1,100 do t[i] = tostring(i) end
+  for i=1,100 do t[i] = tostring(t[i]) end
+  local x = 0
+  for i=1,100 do assert(type(t[i]) == "string"); x = x + t[i] end
+  assert(x == 5050)
+end
+
+do --- tostring table __tostring
+  local mt = { __tostring = function(t) return tostring(t[1]) end }
+  local t = {}
+  for i=1,100 do t[i] = setmetatable({i}, mt) end
+  for i=1,100 do t[i] = tostring(t[i]) end
+  local x = 0
+  for i=1,100 do assert(type(t[i]) == "string"); x = x + t[i] end
+  assert(x == 5050)
+end
+
+do --- tostring table __tostring __call
+  local r = setmetatable({},
+			 { __call = function(x, t) return tostring(t[1]) end })
+  local mt = { __tostring = r }
+  local t = {}
+  for i=1,100 do t[i] = setmetatable({i}, mt) end
+  for i=1,100 do t[i] = tostring(t[i]) end
+  local x = 0
+  for i=1,100 do assert(type(t[i]) == "string"); x = x + t[i] end
+  assert(x == 5050)
+end
+
+do --- print calls overridden tostring +lua<5.2
+  local x = false
+  local co = coroutine.create(function() print(1) end)
+  debug.setfenv(co, setmetatable({}, { __index = {
+    tostring = function() x = true end }}))
+  coroutine.resume(co)
+  assert(x == true)
+end
+
+do --- tonumber base 2
+  assert(tonumber(111, 2) == 7)
+end
+
+do --- __tostring must be callable
+  local t = setmetatable({}, { __tostring = "" })
+  assert(pcall(function() tostring(t) end) == false)
+end
diff --git a/test/LuaJIT-tests/lib/base/xpcall_jit.lua b/test/LuaJIT-tests/lib/base/xpcall_jit.lua
new file mode 100644
index 0000000..f4993cc
--- /dev/null
+++ b/test/LuaJIT-tests/lib/base/xpcall_jit.lua
@@ -0,0 +1,83 @@
+local function tr(err) return "tr"..err end
+
+do --- square sum
+  local function f(x) return x*x end
+  local x = 0
+  for i=1,100 do
+    local ok1, ok2, ok3, y = xpcall(xpcall, tr, xpcall, tr, f, tr, i)
+    if not ok1 or not ok2 or not ok3 then break end
+    x = x + y
+  end
+  assert(x == 338350)
+end
+
+do --- sqrt square sum
+  local x = 0
+  for i=1,100 do
+    local ok1, ok2, ok3, y = xpcall(xpcall, tr, xpcall, tr, math.sqrt, tr, i*i)
+    if not ok1 or not ok2 or not ok3 then break end
+    x = x + y
+  end
+  assert(x == 5050)
+end
+
+do --- sum with error
+  local function f(x)
+    if x >= 150 then error("test", 0) end
+    return x end
+  local x = 0
+  for i=1,200 do
+    local ok1, ok2, ok3, y = xpcall(xpcall, tr, xpcall, tr, f, tr, i)
+    if not ok1 or not ok2 or not ok3 then
+      assert(ok1 and ok2 and not ok3)
+      assert(y == "trtest")
+      break
+    end
+    x = x + y
+  end
+  assert(x == 11175)
+end
+
+do --- square with error
+  local function f(x)
+    if x >= 150 then return x*x end
+    return x
+  end
+  local x = 0
+  for i=1,200 do
+    local ok1, ok2, ok3, y = xpcall(xpcall, tr, xpcall, tr, f, tr, i)
+    if not ok1 or not ok2 or not ok3 then break end
+    x = x + y
+  end
+  assert(x == 1584100)
+end
+
+do --- sum or square with error
+  local function f(x)
+    if x >= 150 then
+      if x >= 175 then error("test", 0) end
+      return x*x
+    end
+    return x
+  end
+  local x = 0
+  for i=1,200 do
+    local ok1, ok2, ok3, y = xpcall(xpcall, tr, xpcall, tr, f, tr, i)
+    if not ok1 or not ok2 or not ok3 then
+      assert(ok1 and ok2 and not ok3)
+      assert(y == "trtest")
+      -- note: no break, so we get an exit to interpreter
+    else
+      x = x + y
+    end
+  end
+  assert(x == 668575)
+end
+
+do --- xpcall swap after recorder error
+  local x = 0
+  for i=1,100 do
+    local ok1, ok2, ok3, err = xpcall(xpcall, tr, xpcall, tr, error, tr, "test", 0)
+    assert(ok1 and ok2 and not ok3 and err == "trtest")
+  end
+end
diff --git a/test/LuaJIT-tests/lib/bit.lua b/test/LuaJIT-tests/lib/bit.lua
new file mode 100644
index 0000000..1adf550
--- /dev/null
+++ b/test/LuaJIT-tests/lib/bit.lua
@@ -0,0 +1,98 @@
+local bit = require"bit"
+local byte, ipairs, tostring, pcall = string.byte, ipairs, tostring, pcall
+
+local vb = {
+  0, 1, -1, 2, -2, 0x12345678, 0x87654321,
+  0x33333333, 0x77777777, 0x55aa55aa, 0xaa55aa55,
+  0x7fffffff, 0x80000000, 0xffffffff
+}
+
+local function cksum(name, s, r)
+  local z = 0
+  for i=1,#s do z = (z + byte(s, i)*i) % 2147483629 end
+  if z ~= r then
+    error("bit."..name.." test failed (got "..z..", expected "..r..")", 0)
+  end
+end
+
+local function check_unop(name, r)
+  local f = bit[name]
+  local s = ""
+  if pcall(f) or pcall(f, "z") or pcall(f, true) then
+    error("bit."..name.." fails to detect argument errors", 0)
+  end
+  for _,x in ipairs(vb) do s = s..","..tostring(f(x)) end
+  cksum(name, s, r)
+end
+
+local function check_binop(name, r)
+  local f = bit[name]
+  local s = ""
+  if pcall(f) or pcall(f, "z") or pcall(f, true) then
+    error("bit."..name.." fails to detect argument errors", 0)
+  end
+  for _,x in ipairs(vb) do
+    for _2,y in ipairs(vb) do s = s..","..tostring(f(x, y)) --[[io.write(_, " ", _2, " ", x, " ", y, " ", f(x, y), "\n")]] end
+  end
+  cksum(name, s, r)
+end
+
+local function check_binop_range(name, r, yb, ye)
+  local f = bit[name]
+  local s = ""
+  if pcall(f) or pcall(f, "z") or pcall(f, true) or pcall(f, 1, true) then
+    error("bit."..name.." fails to detect argument errors", 0)
+  end
+  for _,x in ipairs(vb) do
+    for y=yb,ye do s = s..","..tostring(f(x, y)) end
+  end
+  cksum(name, s, r)
+end
+
+local function check_shift(name, r)
+  check_binop_range(name, r, 0, 31)
+end
+
+do --- Minimal sanity checks.
+  assert(0x7fffffff == 2147483647, "broken hex literals")
+  assert(0xffffffff == -1 or 0xffffffff == 2^32-1, "broken hex literals")
+  assert(tostring(-1) == "-1", "broken tostring()")
+  assert(tostring(0xffffffff) == "-1" or tostring(0xffffffff) == "4294967295", "broken tostring()")
+end
+
+do --- Basic argument processing.
+  assert(bit.tobit(1) == 1)
+  assert(bit.band(1) == 1)
+  assert(bit.bxor(1,2) == 3)
+  assert(bit.bor(1,2,4,8,16,32,64,128) == 255)
+end
+
+do --- unop test vectors
+  check_unop("tobit", 277312)
+  check_unop("bnot", 287870)
+  check_unop("bswap", 307611)
+end
+
+do --- binop test vectors
+  check_binop("band", 41206764)
+  check_binop("bor", 51253663)
+  check_binop("bxor", 79322427)
+end
+
+do --- shift test vectors
+  check_shift("lshift", 325260344)
+  check_shift("rshift", 139061800)
+  check_shift("arshift", 111364720)
+  check_shift("rol", 302401155)
+  check_shift("ror", 302316761)
+end
+
+do --- tohex test vectors
+  check_binop_range("tohex", 47880306, -8, 8)
+end
+
+do --- Don't propagate TOBIT narrowing across two conversions.
+  local tobit = bit.tobit
+  local k = 0x8000000000003
+  for i=1,100 do assert(tobit(k % (2^32)) == 3) end
+end
diff --git a/test/LuaJIT-tests/lib/contents.lua b/test/LuaJIT-tests/lib/contents.lua
new file mode 100644
index 0000000..a1d8b9b
--- /dev/null
+++ b/test/LuaJIT-tests/lib/contents.lua
@@ -0,0 +1,155 @@
+local function check(m, expected, exclude)
+  local t = {}
+  local ex = {}
+  if exclude then
+    for k in exclude:gmatch"[^:]+" do
+      ex[k] = true
+    end
+  end
+  for k in pairs(m) do
+    if not ex[k] then
+      t[#t+1] = tostring(k)
+    end
+  end
+  table.sort(t)
+  local got = table.concat(t, ":")
+  if got ~= expected then
+    error("got: \""..got.."\"\nexpected: \""..expected.."\"", 2)
+  end
+end
+
+do --- base
+  check(_G, "_G:_VERSION:arg:assert:collectgarbage:coroutine:debug:dofile:error:getmetatable:io:ipairs:load:loadfile:math:next:os:package:pairs:pcall:print:rawequal:rawget:rawset:require:select:setmetatable:string:table:tonumber:tostring:type:xpcall", "rawlen:bit:bit32:jit:gcinfo:setfenv:getfenv:loadstring:unpack:module:newproxy")
+end
+
+do --- pre-5.2 base +lua<5.2
+  assert(gcinfo)
+  assert(setfenv)
+  assert(getfenv)
+  assert(loadstring)
+  assert(unpack)
+  assert(module)
+  assert(newproxy)
+end
+
+do --- 5.2 base +lua>=5.2
+  assert(not gcinfo)
+  assert(not setfenv)
+  assert(not getfenv)
+  assert(not loadstring)
+  assert(not unpack)
+  assert(not module)
+  assert(not newproxy)
+end
+
+do --- pre-5.2 base rawlen -compat5.2
+  assert(not rawlen)
+end
+
+do --- 5.2 base rawlen +compat5.2
+  assert(rawlen)
+end
+
+do --- math
+  check(math, "abs:acos:asin:atan:atan2:ceil:cos:cosh:deg:exp:floor:fmod:frexp:huge:ldexp:log:max:min:modf:pi:pow:rad:random:randomseed:sin:sinh:sqrt:tan:tanh", "log10:mod")
+end
+
+do --- pre-5.2 math +lua<5.2 -compat5.2
+  assert(math.mod)
+  assert(math.log10)
+end
+
+do --- 5.2 math +lua>=5.2
+  assert(not math.mod)
+  assert(not math.log10)
+end
+
+do --- string
+  check(string, "byte:char:dump:find:format:gmatch:gsub:len:lower:match:rep:reverse:sub:upper", "gfind")
+end
+
+do --- pre-5.2 string +lua<5.2 -compat5.2
+  assert(string.gfind)
+end
+
+do --- 5.2 string +lua>=5.2
+  assert(not string.gfind)
+end
+
+do --- pre-5.2 table +lua<5.2
+  check(table, "concat:foreach:foreachi:getn:insert:maxn:remove:sort", "pack:unpack:setn:new")
+end
+
+do --- 5.2 table +lua>=5.2
+  check(table, "concat:insert:pack:remove:sort:unpack")
+end
+
+do --- pre-5.2 table.pack -compat5.2
+  assert(not table.pack)
+  assert(not table.unpack)
+end
+
+do --- 5.2 table.pack +compat5.2
+  assert(table.pack)
+  assert(table.unpack)
+end
+
+do --- io
+  check(io, "close:flush:input:lines:open:output:popen:read:stderr:stdin:stdout:tmpfile:type:write")
+end
+
+do --- io file
+  check(debug.getmetatable(io.stdin), "__gc:__index:__tostring:close:flush:lines:read:seek:setvbuf:write")
+end
+
+do --- os
+  check(os, "clock:date:difftime:execute:exit:getenv:remove:rename:setlocale:time:tmpname")
+end
+
+do --- debug
+  check(debug, "debug:gethook:getinfo:getlocal:getmetatable:getregistry:getupvalue:sethook:setlocal:setmetatable:setupvalue:traceback", "getfenv:setfenv:upvalueid:upvaluejoin:getuservalue:setuservalue")
+end
+
+-- TODO: Check versional differences in debug library
+
+do --- package
+  check(package, "config:cpath:loaded:loadlib:path:preload", "searchpath:loaders:searchers:seeall")
+end
+
+do --- pre-5.2 package +lua<5.2
+  assert(package.loaders)
+  assert(not package.searchers)
+  assert(package.seeall)
+end
+
+do --- 5.2 package +lua>=5.2
+  assert(not package.loaders)
+  assert(package.searchers)
+  assert(not package.seeall)
+end
+
+do --- package.loaders
+  check(package.loaders or package.searchers, "1:2:3:4")
+end
+
+do --- package.loaded
+  local loaded = {}
+  for k, v in pairs(package.loaded) do
+    if type(k) ~= "string" or (k:sub(1, 7) ~= "common." and k:sub(1, 4) ~= "jit.") then
+      loaded[k] = v
+    end
+  end
+  check(loaded, "_G:coroutine:debug:io:math:os:package:string:table", "bit:bit32:common:ffi:jit:table.new")
+end
+
+do --- bit +bit
+  check(bit, "arshift:band:bnot:bor:bswap:bxor:lshift:rol:ror:rshift:tobit:tohex")
+end
+
+do --- ffi +ffi
+  check(require"ffi", "C:abi:alignof:arch:cast:cdef:copy:errno:fill:gc:istype:load:metatype:new:offsetof:os:sizeof:string:typeof", "typeinfo")
+end
+
+do --- ffi 2.1 +fii +luajit>=2.1
+  assert(require"ffi".typeinfo)
+end
diff --git a/test/LuaJIT-tests/lib/coroutine/index b/test/LuaJIT-tests/lib/coroutine/index
new file mode 100644
index 0000000..9c5c17e
--- /dev/null
+++ b/test/LuaJIT-tests/lib/coroutine/index
@@ -0,0 +1 @@
+yield.lua
diff --git a/test/LuaJIT-tests/lib/coroutine/yield.lua b/test/LuaJIT-tests/lib/coroutine/yield.lua
new file mode 100644
index 0000000..d995bf8
--- /dev/null
+++ b/test/LuaJIT-tests/lib/coroutine/yield.lua
@@ -0,0 +1,109 @@
+local create = coroutine.create
+local wrap = coroutine.wrap
+local resume = coroutine.resume
+local yield = coroutine.yield
+
+do --- Stack overflow on return (create)
+  wrap(function()
+    local co = create(function()
+      yield(string.byte(string.rep(" ", 100), 1, 100))
+    end)
+    assert(select('#', resume(co)) == 101)
+  end)()
+end
+
+do --- Stack overflow on return (wrap)
+  wrap(function()
+    local f = wrap(function()
+      yield(string.byte(string.rep(" ", 100), 1, 100))
+    end)
+    assert(select('#', f()) == 100)
+  end)()
+end
+
+do --- cogen
+  local function cogen(x)
+    return wrap(function(n) repeat x = x+n; n = yield(x) until false end),
+	   wrap(function(n) repeat x = x*n; n = yield(x) until false end)
+  end
+
+  local a,b=cogen(3)
+  local c,d=cogen(5)
+  assert(d(b(c(a(d(b(c(a(1)))))))) == 168428160)
+end
+
+do --- cofunc +luajit
+  local function verify(what, expect, ...)
+    local got = {...}
+    for i=1,100 do
+      if expect[i] ~= got[i] then
+        error("FAIL " .. what)
+      end
+      if expect[i] == nil then
+        break
+      end
+    end
+  end
+
+  local function cofunc(...)
+    verify("call", { 1, "foo" }, ...)
+    verify("yield", { "bar" }, yield(2, "test"))
+    verify("pcall yield", { true, "again" }, pcall(yield, "from pcall"))
+    return "end"
+  end
+
+  local co = create(cofunc)
+  verify("resume", { true, 2, "test" }, resume(co, 1, "foo"))
+  verify("resume pcall", { true, "from pcall" }, resume(co, "bar"))
+  verify("resume end", { true, "end" }, resume(co, "again"))
+end
+
+do --- assorted +luajit
+  local function verify(expect, func, ...)
+    local co = create(func)
+    for i=1,100 do
+      local ok, res = resume(co, ...)
+      if not ok then
+        if expect[i] ~= nil then
+          error("too few results: ["..i.."] = "..tostring(expect[i]).." (got: "..tostring(res)..")")
+        end
+        break
+      end
+      if expect[i] ~= res then
+        error("bad result: ["..i.."] = "..tostring(res).." (should be: "..tostring(expect[i])..")")
+      end
+    end
+  end
+
+  verify({ 42, 99 },
+    function(x) pcall(yield, x) return 99 end,
+    42)
+
+  verify({ 42, 99 },
+    function(x) pcall(function(y) yield(y) end, x) return 99 end,
+    42)
+
+  verify({ 42, 99 },
+    function(x) xpcall(yield, debug.traceback, x) return 99 end,
+    42)
+
+  verify({ 45, 44, 43, 42, 99 },
+    function(x, y)
+      for i in
+        function(o, k)
+          yield(o+k)
+          if k ~= 0 then return k-1 end
+        end,x,y do
+      end
+      return 99
+    end,
+    42, 3)
+
+  verify({ 84, 99 },
+    function(x)
+      local o = setmetatable({ x },
+        {__add = function(a, b) yield(a[1]+b[1]) return 99 end })
+      return o+o
+    end,
+    42)
+end
diff --git a/test/LuaJIT-tests/lib/ffi/bit64.lua b/test/LuaJIT-tests/lib/ffi/bit64.lua
new file mode 100644
index 0000000..d1b47be
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/bit64.lua
@@ -0,0 +1,130 @@
+local ffi = require("ffi")
+local bit = require("bit")
+
+local tobit, bnot, bswap = bit.tobit, bit.bnot, bit.bswap
+local band, bor, bxor = bit.band, bit.bor, bit.bxor
+local shl, shr, sar = bit.lshift, bit.rshift, bit.arshift
+local rol, ror = bit.rol, bit.ror
+
+ffi.cdef[[
+typedef enum { ZZI = -1 } ienum_t;
+typedef enum { ZZU } uenum_t;
+]]
+
+do --- smoke tobit
+  assert(tobit(0xfedcba9876543210ll) == 0x76543210)
+  assert(tobit(0xfedcba9876543210ull) == 0x76543210)
+end
+
+do --- smoke band
+  assert(tostring(band(1ll, 1, 1ll, -1)) == "1LL")
+  assert(tostring(band(1ll, 1, 1ull, -1)) == "1ULL")
+end
+
+do --- smoke shl
+  assert(shl(10ll, 2) == 40)
+  assert(shl(10, 2ll) == 40)
+  assert(shl(10ll, 2ll) == 40)
+end
+
+do --- smoke tohex
+  assert(bit.tohex(0x123456789abcdef0LL) == "123456789abcdef0")
+end
+
+do --- tobit/band assorted C types
+  for _,tp in ipairs{"int", "ienum_t", "uenum_t", "int64_t", "uint64_t"} do
+    local x = ffi.new(tp, 10)
+    local y = tobit(x)
+    local z = band(x)
+    assert(type(y) == "number" and y == 10)
+    assert(type(z) == "cdata" and z == 10)
+  end
+end
+
+do --- tobit/band negative unsigned enum
+  local x = ffi.new("uenum_t", -10)
+  local y = tobit(x)
+  local z = band(x)
+  assert(type(y) == "number")
+  assert(y == -10)
+  assert(type(z) == "cdata")
+  assert(z == 2^32-10)
+end
+
+do --- jit band/bor/bxor
+  local a = 0x123456789abcdef0LL
+  local y1, y2, y3, y4, y5, y6
+  for i=1,100 do
+    y1 = band(a, 0x000000005a5a5a5aLL)
+    y2 = band(a, 0x5a5a5a5a00000000LL)
+    y3 = band(a, 0xffffffff5a5a5a5aLL)
+    y4 = band(a, 0x5a5a5a5affffffffLL)
+    y5 = band(a, 0xffffffff00000000LL)
+    y6 = band(a, 0x00000000ffffffffLL)
+  end
+  assert(y1 == 0x000000001a185a50LL)
+  assert(y2 == 0x1210525800000000LL)
+  assert(y3 == 0x123456781a185a50LL)
+  assert(y4 == 0x121052589abcdef0LL)
+  assert(y5 == 0x1234567800000000LL)
+  assert(y6 == 0x000000009abcdef0LL)
+  for i=1,100 do
+    y1 = bor(a, 0x000000005a5a5a5aLL)
+    y2 = bor(a, 0x5a5a5a5a00000000LL)
+    y3 = bor(a, 0xffffffff5a5a5a5aLL)
+    y4 = bor(a, 0x5a5a5a5affffffffLL)
+    y5 = bor(a, 0xffffffff00000000LL)
+    y6 = bor(a, 0x00000000ffffffffLL)
+  end
+  assert(y1 == 0x12345678dafedefaLL)
+  assert(y2 == 0x5a7e5e7a9abcdef0LL)
+  assert(y3 == 0xffffffffdafedefaLL)
+  assert(y4 == 0x5a7e5e7affffffffLL)
+  assert(y5 == 0xffffffff9abcdef0LL)
+  assert(y6 == 0x12345678ffffffffLL)
+  for i=1,100 do
+    y1 = bxor(a, 0x000000005a5a5a5aLL)
+    y2 = bxor(a, 0x5a5a5a5a00000000LL)
+    y3 = bxor(a, 0xffffffff5a5a5a5aLL)
+    y4 = bxor(a, 0x5a5a5a5affffffffLL)
+    y5 = bxor(a, 0xffffffff00000000LL)
+    y6 = bxor(a, 0x00000000ffffffffLL)
+  end
+  assert(y1 == 0x12345678c0e684aaLL)
+  assert(y2 == 0x486e0c229abcdef0LL)
+  assert(y3 == 0xedcba987c0e684aaLL)
+  assert(y4 == 0x486e0c226543210fLL)
+  assert(y5 == 0xedcba9879abcdef0LL)
+  assert(y6 == 0x123456786543210fLL)
+end
+
+do --- jit shift/xor
+  local a, b = 0x123456789abcdef0LL, 0x31415926535898LL
+  for i=1,200 do
+    a = bxor(a, b); b = sar(b, 14) + shl(b, 50)
+    a = a - b; b = shl(b, 5) + sar(b, 59)
+    b = bxor(a, b); b = b - shl(b, 13) - shr(b, 51)
+  end
+  assert(b == -7993764627526027113LL)
+end
+
+do --- jit rotate/xor
+  local a, b = 0x123456789abcdef0LL, 0x31415926535898LL
+  for i=1,200 do
+    a = bxor(a, b); b = rol(b, 14)
+    a = a - b; b = rol(b, 5)
+    b = bxor(a, b); b = b - rol(b, 13)
+  end
+  assert(b == -6199148037344061526LL)
+end
+
+do --- jit all ops
+  local a, b = 0x123456789abcdef0LL, 0x31415926535898LL
+  for i=1,200 do
+    a = bxor(a, b); b = rol(b, a)
+    a = a - b; b = shr(b, a) + shl(b, bnot(a))
+    b = bxor(a, b); b = b - bswap(b)
+  end
+  assert(b == -8881785180777266821LL)
+end
+
diff --git a/test/LuaJIT-tests/lib/ffi/cdata_var.lua b/test/LuaJIT-tests/lib/ffi/cdata_var.lua
new file mode 100644
index 0000000..42d6028
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/cdata_var.lua
@@ -0,0 +1,47 @@
+local ffi = require("ffi")
+
+do --- byte array allocations
+  local typ = ffi.typeof"uint8_t[?]"
+  for i = 4, 24 do
+    for d = -5, 5 do
+      local sz = 2^i + d
+      assert(ffi.sizeof(typ, sz) == sz)
+      local mem = ffi.new(typ, sz)
+      assert(ffi.sizeof(mem) == sz)
+      mem[0] = 0x21
+      mem[1] = 0x32
+      mem[2] = 0x43
+      mem[sz-3] = 0x54
+      mem[sz-2] = 0x65
+      mem[sz-1] = 0x76
+      assert(mem[0] == 0x21)
+      assert(mem[1] == 0x32)
+      assert(mem[2] == 0x43)
+      assert(mem[3] == 0)
+      assert(mem[sz-4] == 0)
+      assert(mem[sz-3] == 0x54)
+      assert(mem[sz-2] == 0x65)
+      assert(mem[sz-1] == 0x76)
+    end
+  end
+end
+
+do --- int array allocations
+  local typ = ffi.typeof"int32_t[?]"
+  for i = 2, 17 do
+    for d = -2, 2 do
+      local sz = 2^i + d
+      assert(ffi.sizeof(typ, sz) == sz*4)
+      local mem = ffi.new(typ, sz)
+      assert(ffi.sizeof(mem) == sz*4)
+      mem[0] = -3
+      mem[sz-1] = -4
+      assert(mem[0] == -3)
+      if sz ~= 2 then
+        assert(mem[1] == 0)
+        assert(mem[sz-2] == 0)
+      end
+      assert(mem[sz-1] == -4)
+    end
+  end
+end
diff --git a/test/LuaJIT-tests/lib/ffi/copy_fill.lua b/test/LuaJIT-tests/lib/ffi/copy_fill.lua
new file mode 100644
index 0000000..2956381
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/copy_fill.lua
@@ -0,0 +1,64 @@
+local ffi = require("ffi")
+
+do --- misc
+  local arr = ffi.typeof("char[11]")
+  local a = arr()
+  local b = arr()
+  local c = arr()
+
+  for i=0,9 do a[i] = 97+i; b[i] = 106-i end
+  a[10] = 0; b[10] = 0;
+
+  ffi.copy(c, a, 11)
+  for i=0,9 do assert(c[i] == 97+i) end
+  assert(ffi.string(c) == "abcdefghij")
+
+  ffi.copy(c, b, 5)
+  for i=0,4 do assert(c[i] == 106-i) end
+  for i=5,9 do assert(c[i] == 97+i) end
+  assert(ffi.string(c) == "jihgffghij")
+
+  c[7] = 0
+  assert(ffi.string(c) == "jihgffg")
+
+  c[10] = 1
+  ffi.copy(c, "ABCDEFGHIJ")
+  for i=0,9 do assert(c[i] == 65+i) end
+  assert(c[10] == 0)
+  assert(ffi.string(c) == "ABCDEFGHIJ")
+
+  ffi.copy(c, "abcdefghij", 5)
+  assert(ffi.string(c) == "abcdeFGHIJ")
+
+  ffi.fill(c, 10, 65)
+  assert(ffi.string(c) == "AAAAAAAAAA")
+  for i=10,0,-1 do ffi.fill(c, i, 96+i) end
+  assert(ffi.string(c) == "abcdefghij")
+  ffi.fill(c, 10)
+  assert(c[0] == 0)
+  assert(c[9] == 0)
+
+  -- test length parameter to ffi.string
+  ffi.fill(c, 10, 65)
+  assert(ffi.string(c, 5) == "AAAAA")
+end
+
+do --- jit char[10]
+  local a = ffi.new("char[10]", 64)
+  local x
+  for i=1,100 do a[0] = i; x = ffi.string(a, 10) end
+  assert(x == "d@@@@@@@@@")
+end
+
+do --- jit char[1]
+  local a = ffi.new("char[1]")
+  local x, y
+  for i=1,100 do
+    a[0] = i
+    x = ffi.string(a, 1)
+    a[0] = 126
+    y = ffi.string(a, 1)
+  end
+  assert(x == "d" and y == "~")
+end
+
diff --git a/test/LuaJIT-tests/lib/ffi/err.lua b/test/LuaJIT-tests/lib/ffi/err.lua
new file mode 100644
index 0000000..4472365
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/err.lua
@@ -0,0 +1,35 @@
+local ffi = require("ffi")
+
+do --- error in FFI metamethod: don't print metamethod frame.
+  local ok, err = xpcall(function()
+    local x = (1ll).foo
+  end, debug.traceback)
+  assert(ok == false)
+  assert(not string.find(err, "__index"))
+end
+
+do --- tailcall in regular metamethod: keep metamethod frame.
+  local ok, err = xpcall(function()
+    local t = setmetatable({}, {__index = function() return rawget("x") end })
+    local y = t[1]
+  end, debug.traceback)
+  assert(ok == false)
+  assert(string.find(err, "__index"))
+end
+
+do --- error in FFI metamethod: set correct PC.
+  ffi.cdef[[
+typedef struct { int x; int y; } ffi_err_point;
+ffi_err_point ffi_err_strchr(ffi_err_point* op1, ffi_err_point* op2) asm("strchr");
+]]
+  local point = ffi.metatype("ffi_err_point", { __add = ffi.C.ffi_err_strchr })
+  local function foo()
+    local p = point{ 3, 4 }
+    local r = p + p
+    local r = p + 5
+  end
+  local ok, err = xpcall(foo, debug.traceback)
+  local line = debug.getinfo(foo).linedefined+3
+  assert(string.match(err, "traceback:[^:]*:"..line..":"))
+end
+
diff --git a/test/LuaJIT-tests/lib/ffi/ffi_arith_ptr.lua b/test/LuaJIT-tests/lib/ffi/ffi_arith_ptr.lua
new file mode 100644
index 0000000..8cf890c
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/ffi_arith_ptr.lua
@@ -0,0 +1,106 @@
+local ffi = require("ffi")
+
+dofile("../common/ffi_util.inc")
+
+ffi.cdef[[
+typedef struct { int a,b,c; } foo1_t;
+void free(void *);
+void *malloc(size_t);
+struct incomplete;
+]]
+
+do
+  local a = ffi.new("int[10]")
+  local p1 = a+0
+  p1[0] = 1;
+  p1[1] = 2;
+  assert(a[0] == 1)
+  assert(a[1] == 2)
+  assert(a == p1)
+  assert(not (a ~= p1))
+  assert(p1 <= a)
+  assert(a <= p1)
+  assert(not (p1 < a))
+  assert(not (a < p1))
+  assert(a ~= nil)
+  assert(not (a == nil))
+  assert(p1 ~= nil)
+  assert(not (p1 == nil))
+
+  local p2 = a+2
+  p2[0] = 3;
+  p2[1] = 4;
+  assert(a[2] == 3)
+  assert(a[3] == 4)
+  assert(p2 - p1 == 2)
+  assert(p1 - p2 == -2)
+  assert(p1 ~= p2)
+  assert(not (p1 == p2))
+  assert(p1 < p2)
+  assert(p2 > p1)
+  assert(not (p1 > p2))
+  assert(not (p2 < p1))
+  assert(p1 <= p2)
+  assert(p2 >= p1)
+  assert(not (p1 >= p2))
+  assert(not (p2 <= p1))
+
+  local p3 = a-2
+  assert(p3[2] == 1)
+  assert(p3[3] == 2)
+  local p4 = a+(-3)
+  assert(p4[5] == 3)
+  assert(p4[6] == 4)
+  -- bad: adding two pointers or subtracting a pointer
+  fails(function(p1, p2) return p1 + p2 end, p1, p2)
+  fails(function(p1) return 1 - p1 end, p1)
+  -- bad: subtracting different pointer types
+  fails(function(p1) return p1 - ffi.new("char[1]") end, p1)
+  -- but different qualifiers are ok
+  local b = ffi.cast("const int *", a+5)
+  assert(b - a == 5)
+end
+
+do
+  local p1 = ffi.cast("void *", 0)
+  local p2 = ffi.cast("int *", 1)
+  assert(p1 == p1)
+  assert(p2 == p2)
+  assert(p1 ~= p2)
+  assert(p1 == nil)
+  assert(p2 ~= nil)
+end
+
+do
+  local f1 = ffi.C.free
+  local f2 = ffi.C.malloc
+  local p1 = ffi.cast("void *", f1)
+  assert(f1 == f1)
+  assert(f1 ~= nil)
+  assert(f1 ~= f2)
+  assert(p1 == f1)
+  assert(p1 ~= f2)
+  assert(f1 < f2 or f1 > f2)
+  fails(function(f1) return f1 + 1 end, f1)
+end
+
+do
+  local s = ffi.new("foo1_t[10]")
+  local p1 = s+3
+  p1.a = 1; p1.b = 2; p1.c = 3
+  p1[1].a = 4; p1[1].b = 5; p1[1].c = 6
+  assert(s[3].a == 1 and s[3].b == 2 and s[3].c == 3)
+  assert(s[4].a == 4 and s[4].b == 5 and s[4].c == 6)
+  local p2 = s+6
+  assert(p2 - p1 == 3)
+  assert(p1 - p2 == -3)
+end
+
+do
+  local mem = ffi.new("int[1]")
+  local p = ffi.cast("struct incomplete *", mem)
+  fails(function(p) return p+1 end, p)
+  local ok, err = pcall(function(p) return p[1] end, p)
+  assert(not ok and err:match("size.*unknown"))
+end
+
diff --git a/test/LuaJIT-tests/lib/ffi/ffi_bitfield.lua b/test/LuaJIT-tests/lib/ffi/ffi_bitfield.lua
new file mode 100644
index 0000000..cd0b181
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/ffi_bitfield.lua
@@ -0,0 +1,108 @@
+local ffi = require("ffi")
+
+dofile("../common/ffi_util.inc")
+
+do
+  local x = ffi.new([[
+    union {
+      uint32_t u;
+      struct { int a:10,b:10,c:11,d:1; };
+      struct { unsigned int e:10,f:10,g:11,h:1; };
+      struct { int8_t i:4,j:5,k:5,l:3; };
+      struct { _Bool b0:1,b1:1,b2:1,b3:1; };
+    }
+  ]])
+
+  -- bitfield access
+  x.u = 0xffffffff
+  assert(x.a == -1 and x.b == -1 and x.c == -1 and x.d == -1)
+  assert(x.e == 1023 and x.f == 1023 and x.g == 2047 and x.h == 1)
+  assert(x.i == -1 and x.j == -1 and x.k == -1 and x.l == -1)
+  assert(x.b0 == true and x.b1 == true and x.b2 == true and x.b3 == true)
+  x.u = 0x12345678
+  if ffi.abi("le") then
+    assert(x.a == -392 and x.b == 277 and x.c == 291 and x.d == 0)
+    assert(x.e == 632 and x.f == 277 and x.g == 291 and x.h == 0)
+    assert(x.i == -8 and x.j == -10 and x.k == -12 and x.l == 1)
+    assert(x.b0 == false and x.b1 == false and x.b2 == false and x.b3 == true)
+  else
+    assert(x.a == 72 and x.b == -187 and x.c == 828 and x.d == 0)
+    assert(x.e == 72 and x.f == 837 and x.g == 828 and x.h == 0)
+    assert(x.i == 1 and x.j == 6 and x.k == 10 and x.l == -2)
+    assert(x.b0 == false and x.b1 == false and x.b2 == false and x.b3 == true)
+  end
+  x.u = 0xe8d30edc
+  if ffi.abi("le") then
+    assert(x.a == -292 and x.b == 195 and x.c == -371 and x.d == -1)
+    assert(x.e == 732 and x.f == 195 and x.g == 1677 and x.h == 1)
+    assert(x.i == -4 and x.j == 14 and x.k == -13 and x.l == -2)
+    assert(x.b0 == false and x.b1 == false and x.b2 == true and x.b3 == true)
+  else
+    assert(x.a == -93 and x.b == 304 and x.c == -146 and x.d == 0)
+    assert(x.e == 931 and x.f == 304 and x.g == 1902 and x.h == 0)
+    assert(x.i == -2 and x.j == -6 and x.k == 1 and x.l == -2)
+    assert(x.b0 == true and x.b1 == true and x.b2 == true and x.b3 == false)
+  end
+
+  -- bitfield insert
+  x.u = 0xffffffff
+  x.a = 0
+  if ffi.abi("le") then
+    assert(x.u == 0xfffffc00)
+  else
+    assert(x.u == 0x003fffff)
+  end
+  x.u = 0
+  x.a = -1
+  if ffi.abi("le") then
+    assert(x.u == 0x3ff)
+  else
+    assert(x.u == 0xffc00000)
+  end
+  x.u = 0xffffffff
+  x.b = 0
+  if ffi.abi("le") then
+    assert(x.u == 0xfff003ff)
+  else
+    assert(x.u == 0xffc00fff)
+  end
+  x.u = 0
+  x.b = -1
+  if ffi.abi("le") then
+    assert(x.u == 0x000ffc00)
+  else
+    assert(x.u == 0x003ff000)
+  end
+
+  -- cumulative bitfield insert
+  x.u = 0xffffffff
+  if ffi.abi("le") then
+    x.a = -392; x.b = 277; x.c = 291; x.d = 0
+  else
+    x.a = 72; x.b = -187; x.c = 828; x.d = 0
+  end
+  assert(x.u == 0x12345678)
+  x.u = 0
+  if ffi.abi("le") then
+    x.a = -392; x.b = 277; x.c = 291; x.d = 0
+  else
+    x.a = 72; x.b = -187; x.c = 828; x.d = 0
+  end
+  assert(x.u == 0x12345678)
+  x.u = 0xffffffff
+  x.b0 = true; x.b1 = false; x.b2 = true; x.b3 = false
+  if ffi.abi("le") then
+    assert(x.u == 0xfffffff5)
+  else
+    assert(x.u == 0xafffffff)
+  end
+  x.u = 0
+  x.b0 = true; x.b1 = false; x.b2 = true; x.b3 = false
+  if ffi.abi("le") then
+    assert(x.u == 0x00000005)
+  else
+    assert(x.u == 0xa0000000)
+  end
+
+end
+
diff --git a/test/LuaJIT-tests/lib/ffi/ffi_call.lua b/test/LuaJIT-tests/lib/ffi/ffi_call.lua
new file mode 100644
index 0000000..1eb5e90
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/ffi_call.lua
@@ -0,0 +1,266 @@
+
+local ffi = require("ffi")
+
+dofile("../common/ffi_util.inc")
+
+local tonumber = tonumber
+
+ffi.cdef[[
+typedef struct s_ii { int x, y; } s_ii;
+typedef struct s_jj { int64_t x, y; } s_jj;
+typedef struct s_ff { float x, y; } s_ff;
+typedef struct s_dd { double x, y; } s_dd;
+typedef struct s_8i { int a,b,c,d,e,f,g,h; } s_8i;
+
+int call_i(int a);
+int call_ii(int a, int b);
+int call_10i(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j);
+
+typedef enum { XYZ } e_u;
+
+e_u call_ie(e_u a) asm("call_i");
+
+int64_t call_ji(int64_t a, int b);
+int64_t call_ij(int a, int64_t b);
+int64_t call_jj(int64_t a, int64_t b);
+
+double call_dd(double a, double b);
+double call_10d(double a, double b, double c, double d, double e, double f, double g, double h, double i, double j);
+
+float call_ff(float a, float b);
+float call_10f(float a, float b, float c, float d, float e, float f, float g, float h, float i, float j);
+
+double call_idifjd(int a, double b, int c, float d, int64_t e, double f);
+
+int call_p_i(int *a);
+int *call_p_p(int *a);
+int call_pp_i(int *a, int *b);
+
+double call_ividi(int a, ...);
+
+complex call_dd_cd(double a, double b);
+complex call_cd(complex a);
+complex call_cdcd(complex a, complex b);
+
+complex float call_ff_cf(float a, float b);
+complex float call_cf(complex float a);
+complex float call_cfcf(complex float a, complex float b);
+
+s_ii call_sii(s_ii a);
+s_jj call_sjj(s_jj a);
+s_ff call_sff(s_ff a);
+s_dd call_sdd(s_dd a);
+s_8i call_s8i(s_8i a);
+s_ii call_siisii(s_ii a, s_ii b);
+s_ff call_sffsff(s_ff a, s_ff b);
+s_dd call_sddsdd(s_dd a, s_dd b);
+s_8i call_s8is8i(s_8i a, s_8i b);
+s_8i call_is8ii(int a, s_8i b, int c);
+
+int __fastcall fastcall_void(void);
+int __fastcall fastcall_i(int a);
+int __fastcall fastcall_ii(int a, int b);
+int __fastcall fastcall_iii(int a, int b, int c);
+int64_t __fastcall fastcall_ji(int64_t a, int b);
+double __fastcall fastcall_dd(double a, double b);
+int __fastcall fastcall_pp_i(int *a, int *b);
+s_ii __fastcall fastcall_siisii(s_ii a, s_ii b);
+s_dd __fastcall fastcall_sddsdd(s_dd a, s_dd b);
+
+int __stdcall stdcall_i(int a);
+int __stdcall stdcall_ii(int a, int b);
+double __stdcall stdcall_dd(double a, double b);
+float __stdcall stdcall_ff(float a, float b);
+]]
+
+local C = ffi.load("../clib/ctest")
+
+assert(C.call_i(-42) == -41)
+assert(C.call_ii(-42, 17) == -42+17)
+assert(C.call_10i(-42, 17, 12345, 9987, -100, 11, 51, 0x12345678, 338, -78901234) == -42+17+12345+9987-100+11+51+0x12345678+338-78901234)
+
+assert(C.call_ie(123) == 124)
+
+assert(tonumber(C.call_ji(0x123456789LL, -17)) == tonumber(0x123456789LL-17))
+assert(tonumber(C.call_ij(-17, 0x123456789LL)) == tonumber(0x123456789LL-17))
+assert(tonumber(C.call_jj(-42, 17)) == -42+17)
+assert(tonumber(C.call_jj(0x123456789abcdef0LL, -0x789abcde99887766LL)) == tonumber(0x123456789abcdef0LL-0x789abcde99887766LL))
+
+assert(C.call_dd(12.5, -3.25) == 12.5-3.25)
+assert(C.call_10d(-42.5, 17.125, 12345.5, 9987, -100.625, 11, 51, 0x12345678, 338, -78901234.75) == -42.5+17.125+12345.5+9987-100.625+11+51+0x12345678+338-78901234.75)
+
+assert(C.call_ff(12.5, -3.25) == 12.5-3.25)
+assert(C.call_10f(-42.5, 17.125, 12345.5, 9987, -100.625, 11, 51, 0x123456, 338, -789012.75) == -42.5+17.125+12345.5+9987-100.625+11+51+0x123456+338-789012.75)
+
+assert(C.call_idifjd(-42, 17.125, 0x12345, -100.625, 12345678901234, -789012.75) == -42+17.125+0x12345-100.625+12345678901234-789012.75)
+
+do
+  local a = ffi.new("int[10]", -42)
+  assert(C.call_p_i(a) == -42+1)
+  assert(tonumber(ffi.cast("intptr_t", C.call_p_p(a+3))) == tonumber(ffi.cast("intptr_t", a+4)))
+  assert(C.call_pp_i(a+8, a+5) == 3)
+end
+
+-- vararg
+assert(C.call_ividi(-42, ffi.new("int", 17), 12.5, ffi.new("int", 131)) == -42+17+12.5+131)
+
+-- complex
+if pcall(function() return C.call_dd_cd end) then
+  do
+    local c = C.call_dd_cd(12.5, -3.25)
+    assert(c.re == 12.5 and c.im == -3.25*2)
+  end
+  do
+    local c1 = ffi.new("complex", 12.5, -3.25)
+    local cz = C.call_cd(c1)
+    assert(cz.re == 12.5+1 and cz.im == -3.25-2)
+  end
+  do
+    local c1 = ffi.new("complex", 12.5, -3.25)
+    local c2 = ffi.new("complex", -17.125, 100.625)
+    local cz = C.call_cdcd(c1, c2)
+    assert(cz.re == 12.5-17.125 and cz.im == -3.25+100.625)
+  end
+
+  do
+    local c = C.call_ff_cf(12.5, -3.25)
+    assert(c.re == 12.5 and c.im == -3.25*2)
+  end
+  do
+    local c1 = ffi.new("complex float", 12.5, -3.25)
+    local cz = C.call_cf(c1)
+    assert(cz.re == 12.5+1 and cz.im == -3.25-2)
+  end
+  do
+    local c1 = ffi.new("complex float", 12.5, -3.25)
+    local c2 = ffi.new("complex float", -17.125, 100.625)
+    local cz = C.call_cfcf(c1, c2)
+    assert(cz.re == 12.5-17.125 and cz.im == -3.25+100.625)
+  end
+end
+
+-- structs
+do
+  local s1 = ffi.new("s_ii", -42, 17)
+  local sz = C.call_sii(s1)
+  assert(s1.x == -42 and s1.y == 17)
+  assert(sz.x == -42 and sz.y == 17)
+end
+
+do
+  local s1 = ffi.new("s_jj", 0x123456789abcdef0LL, -0x789abcde99887766LL)
+  local sz = C.call_sjj(s1)
+  assert(s1.x == 0x123456789abcdef0LL)
+  assert(s1.y == -0x789abcde99887766LL)
+  assert(sz.x == 0x123456789abcdef0LL)
+  assert(sz.y == -0x789abcde99887766LL)
+end
+
+do
+  local s1 = ffi.new("s_ff", 12.5, -3.25)
+  local sz = C.call_sff(s1)
+  assert(s1.x == 12.5 and s1.y == -3.25)
+  assert(sz.x == 12.5 and sz.y == -3.25)
+end
+
+do
+  local s1 = ffi.new("s_dd", 12.5, -3.25)
+  local sz = C.call_sdd(s1)
+  assert(s1.x == 12.5 and s1.y == -3.25)
+  assert(sz.x == 12.5 and sz.y == -3.25)
+end
+
+do
+  local s1 = ffi.new("s_8i", -42, 17, 12345, 9987, -100, 11, 51, 0x12345678)
+  local sz = C.call_s8i(s1)
+  assert(s1.a+s1.b+s1.c+s1.d+s1.e+s1.f+s1.g+s1.h == -42+17+12345+9987-100+11+51+0x12345678)
+  assert(sz.a+sz.b+sz.c+sz.d+sz.e+sz.f+sz.g+sz.h == -42+17+12345+9987-100+11+51+0x12345678)
+end
+
+do
+  local s1 = ffi.new("s_ii", -42, 17)
+  local s2 = ffi.new("s_ii", 0x12345, -98765)
+  local sz = C.call_siisii(s1, s2)
+  assert(s1.x == -42 and s1.y == 17)
+  assert(s2.x == 0x12345 and s2.y == -98765)
+  assert(sz.x == -42+0x12345 and sz.y == 17-98765)
+end
+
+do
+  local s1 = ffi.new("s_ff", 12.5, -3.25)
+  local s2 = ffi.new("s_ff", -17.125, 100.625)
+  local sz = C.call_sffsff(s1, s2)
+  assert(s1.x == 12.5 and s1.y == -3.25)
+  assert(s2.x == -17.125 and s2.y == 100.625)
+  assert(sz.x == 12.5-17.125 and sz.y == -3.25+100.625)
+end
+
+do
+  local s1 = ffi.new("s_dd", 12.5, -3.25)
+  local s2 = ffi.new("s_dd", -17.125, 100.625)
+  local sz = C.call_sddsdd(s1, s2)
+  assert(s1.x == 12.5 and s1.y == -3.25)
+  assert(s2.x == -17.125 and s2.y == 100.625)
+  assert(sz.x == 12.5-17.125 and sz.y == -3.25+100.625)
+end
+
+do
+  local s1 = ffi.new("s_8i", -42, 17, 12345, 9987, -100, 11, 51, 0x12345678)
+  local s2 = ffi.new("s_8i", 99, 311, 98765, -51, 312, 97, 17, 0x44332211)
+  local sz = C.call_s8is8i(s1, s2)
+  assert(s1.a+s1.b+s1.c+s1.d+s1.e+s1.f+s1.g+s1.h == -42+17+12345+9987-100+11+51+0x12345678)
+  assert(s2.a+s2.b+s2.c+s2.d+s2.e+s2.f+s2.g+s2.h == 99+311+98765-51+312+97+17+0x44332211)
+  assert(sz.a+sz.b+sz.c+sz.d+sz.e+sz.f+sz.g+sz.h == -42+17+12345+9987-100+11+51+0x12345678 + 99+311+98765-51+312+97+17+0x44332211)
+  assert(sz.a == -42+99)
+  assert(sz.h == 0x12345678+0x44332211)
+end
+
+do
+  local s1 = ffi.new("s_8i", -42, 17, 12345, 9987, -100, 11, 51, 0x12345678)
+  local sz = C.call_is8ii(19, s1, -51)
+  assert(s1.a+s1.b+s1.c+s1.d+s1.e+s1.f+s1.g+s1.h == -42+17+12345+9987-100+11+51+0x12345678)
+  assert(sz.a+sz.b+sz.c+sz.d+sz.e+sz.f+sz.g+sz.h == -42+17+12345+9987-100+11+51+0x12345678 + 19-51)
+  assert(sz.a == -42+19)
+  assert(sz.c == 12345-51)
+end
+
+-- target-specific
+if jit.arch == "x86" then
+  assert(C.fastcall_void() == 1)
+  assert(C.fastcall_i(-42) == -41)
+  assert(C.fastcall_ii(-42, 17) == -42+17)
+  assert(C.fastcall_iii(-42, 17, 139) == -42+17+139)
+  assert(tonumber(C.fastcall_ji(0x123456789LL, -17)) == tonumber(0x123456789LL-17))
+  assert(C.fastcall_dd(12.5, -3.25) == 12.5-3.25)
+
+  do
+    local a = ffi.new("int[10]", -42)
+    assert(C.fastcall_pp_i(a+8, a+5) == 3)
+  end
+
+  do
+    local s1 = ffi.new("s_ii", -42, 17)
+    local s2 = ffi.new("s_ii", 0x12345, -98765)
+    local sz = C.fastcall_siisii(s1, s2)
+    assert(s1.x == -42 and s1.y == 17)
+    assert(s2.x == 0x12345 and s2.y == -98765)
+    assert(sz.x == -42+0x12345 and sz.y == 17-98765)
+  end
+
+  do
+    local s1 = ffi.new("s_dd", 12.5, -3.25)
+    local s2 = ffi.new("s_dd", -17.125, 100.625)
+    local sz = C.fastcall_sddsdd(s1, s2)
+    assert(s1.x == 12.5 and s1.y == -3.25)
+    assert(s2.x == -17.125 and s2.y == 100.625)
+    assert(sz.x == 12.5-17.125 and sz.y == -3.25+100.625)
+  end
+
+  if jit.os == "Windows" then
+    assert(C.stdcall_i(-42) == -41)
+    assert(C.stdcall_ii(-42, 17) == -42+17)
+    assert(C.stdcall_dd(12.5, -3.25) == 12.5-3.25)
+    assert(C.stdcall_ff(12.5, -3.25) == 12.5-3.25)
+  end
+end
+
diff --git a/test/LuaJIT-tests/lib/ffi/ffi_callback.lua b/test/LuaJIT-tests/lib/ffi/ffi_callback.lua
new file mode 100644
index 0000000..1fd14bd
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/ffi_callback.lua
@@ -0,0 +1,158 @@
+
+local ffi = require("ffi")
+
+ffi.cdef[[
+void qsort(void *base, size_t nmemb, size_t size,
+	   int (*compar)(const uint8_t *, const uint8_t *));
+]]
+
+do
+  local cb = ffi.cast("int (*)(int, int, int)", function(a, b, c)
+    return a+b+c
+  end)
+
+  assert(cb(10, 99, 13) == 122)
+
+  -- Don't compile call to blacklisted function.
+  for i=1,200 do
+    if i > 60 then assert(cb(10, 99, 13) == 122) end
+  end
+end
+
+do
+  assert(ffi.cast("int64_t (*)(int64_t, int64_t, int64_t)", function(a, b, c)
+      return a+b+c
+    end)(12345678901234567LL, 70000000000000001LL, 10000000909090904LL) ==
+    12345678901234567LL+70000000000000001LL+10000000909090904LL)
+
+  assert(ffi.cast("double (*)(double, float, double)", function(a, b, c)
+      return a+b+c
+    end)(7.125, -123.25, 9999.33) == 7.125-123.25+9999.33)
+
+  assert(ffi.cast("double (*)(int, double)", function(a, b)
+      return a+b
+    end)(12345, 7.125) == 12345 + 7.125)
+
+  assert(ffi.cast("float (*)(double, float, double)", function(a, b, c)
+      return a+b+c
+    end)(7.125, -123.25, 9999.33) == 9883.205078125)
+
+  assert(ffi.cast("int (*)(int, int, int, int, int, int, int, int, int, int)",
+    function(a, b, c, d, e, f, g, h, i, j)
+      return a+b+c+d+e+f+g+h+i+j
+    end)(-42, 17, 12345, 9987, -100, 11, 51, 0x12345678, 338, -78901234) ==
+    -42+17+12345+9987-100+11+51+0x12345678+338-78901234)
+
+  assert(ffi.cast("double (*)(double, double, double, double, double, double, double, double, double, double)",
+    function(a, b, c, d, e, f, g, h, i, j)
+      return a+b+c+d+e+f+g+h+i+j
+    end)(-42.5, 17.125, 12345.5, 9987, -100.625, 11, 51, 0x12345678, 338, -78901234.75) ==
+    -42.5+17.125+12345.5+9987-100.625+11+51+0x12345678+338-78901234.75)
+end
+
+-- Target-specific tests.
+if jit.arch == "x86" then
+  assert(ffi.cast("__fastcall int (*)(int, int, int)", function(a, b, c)
+      return a+b+c
+    end)(10, 99, 13) == 122)
+
+  assert(ffi.cast("__stdcall int (*)(int, int, int)", function(a, b, c)
+      return a+b+c
+    end)(10, 99, 13) == 122)
+
+  -- Test reordering.
+  assert(ffi.cast("int64_t __fastcall (*)(int64_t, int, int)", function(a, b, c)
+      return a+b+c
+    end)(12345678901234567LL, 12345, 989797123) ==
+    12345678901234567LL+12345+989797123)
+end
+
+-- Error handling.
+do
+  local function f()
+    return
+  end -- Error for result conversion triggered here.
+  local ok, err = pcall(ffi.cast("int (*)(void)", f))
+  assert(ok == false)
+  assert(string.match(err, ":"..debug.getinfo(f, "S").lastlinedefined..":"))
+
+  assert(pcall(ffi.cast("int (*)(void)", function() end)) == false)
+  assert(pcall(ffi.cast("int (*)(void)", function() error("test") end)) == false)
+  assert(pcall(ffi.cast("int (*)(void)", function(a) return a+1 end)) == false)
+
+  assert(pcall(ffi.cast("int (*)(int,int,int,int, int,int,int,int, int)", function() error("test") end), 1,1,1,1, 1,1,1,1, 1) == false)
+  assert(pcall(ffi.cast("int (*)(int,int,int,int, int,int,int,int, int)", function() error("test") end), 1,1,1,1, 1,1,1,1, 1) == false)
+end
+
+do
+  local function cmp(pa, pb)
+    local a, b = pa[0], pb[0]
+    if a < b then
+      return -1
+    elseif a > b then
+      return 1
+    else
+      return 0
+    end
+  end
+
+  local arr = ffi.new("uint8_t[?]", 256)
+  for i=0,255 do arr[i] = math.random(0, 255) end
+  ffi.C.qsort(arr, 256, 1, cmp)
+  for i=0,254 do assert(arr[i] <= arr[i+1]) end
+end
+
+if ffi.abi"win" then
+  ffi.cdef[[
+  typedef int (__stdcall *WNDENUMPROC)(void *hwnd, intptr_t l);
+  int EnumWindows(WNDENUMPROC func, intptr_t l);
+  int SendMessageA(void *hwnd, uint32_t msg, int w, intptr_t l);
+  enum { WM_GETTEXT = 13 };
+  ]]
+
+  local C = ffi.C
+  local buf = ffi.new("char[?]", 256)
+  local lbuf = ffi.cast("intptr_t", buf)
+  local count = 0
+  C.EnumWindows(function(hwnd, l)
+    if C.SendMessageA(hwnd, C.WM_GETTEXT, 255, lbuf) ~= 0 then
+      count = count + 1
+    end
+    return true
+  end, 0)
+  assert(count > 10)
+end
+
+do
+  local cb = ffi.cast("int(*)(void)", function() return 1 end)
+  assert(cb() == 1)
+  cb:free()
+  assert(pcall(cb) == false)
+  assert(pcall(cb.free, cb) == false)
+  assert(pcall(cb.set, cb, function() end) == false)
+  cb = ffi.cast("int(*)(void)", function() return 2 end)
+  assert(cb() == 2)
+  cb:set(function() return 3 end)
+  assert(cb() == 3)
+end
+
+do
+  local ft = ffi.typeof("void(*)(void)")
+  local function f() end
+  local t = {}
+  for i=1,4 do
+    for i=1,400 do t[i] = ft(f) end
+    for i=1,400 do t[i]:free() end
+  end
+end
+
+do
+  assert(ffi.cast("int (*)()", function() return string.byte"A" end)() == 65)
+end
+
+do
+  local f = ffi.cast("void (*)(void)", function() debug.traceback() end)
+  debug.sethook(function() debug.sethook(nil, "", 0); f() end, "", 1)
+  local x
+end
+
diff --git a/test/LuaJIT-tests/lib/ffi/ffi_const.lua b/test/LuaJIT-tests/lib/ffi/ffi_const.lua
new file mode 100644
index 0000000..d42133a
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/ffi_const.lua
@@ -0,0 +1,113 @@
+local ffi = require("ffi")
+
+dofile("../common/ffi_util.inc")
+
+ffi.cdef[[
+typedef struct s_t {
+  int v, w;
+} s_t;
+
+typedef const s_t cs_t;
+
+typedef enum en_t { EE } en_t;
+
+typedef struct pcs_t {
+  int v;
+  const int w;
+} pcs_t;
+
+typedef struct foo_t {
+  static const int cc = 17;
+  enum { CC = -37 };
+  int i;
+  const int ci;
+  int bi:8;
+  const int cbi:8;
+  en_t e;
+  const en_t ce;
+  int a[10];
+  const int ca[10];
+  const char cac[10];
+  s_t s;
+  cs_t cs;
+  pcs_t pcs1, pcs2;
+  const struct {
+    int ni;
+  };
+  complex cx;
+  const complex ccx;
+  complex *cp;
+  const complex *ccp;
+} foo_t;
+]]
+
+do
+  local foo_t = ffi.typeof("foo_t")
+  local x = foo_t()
+
+  -- constval
+  assert(x.cc == 17)
+  fails(function(x) x.cc = 1 end, x)
+  assert(x.CC == -37)
+  fails(function(x) x.CC = 1 end, x)
+
+  -- fields
+  x.i = 1
+  fails(function(x) x.ci = 1 end, x)
+  x.e = 1
+  fails(function(x) x.ce = 1 end, x)
+
+  -- bitfields
+  x.bi = 1
+  fails(function(x) x.cbi = 1 end, x)
+
+  -- arrays
+  do
+    local a = ffi.new("int[10]")
+    a[0] = 1
+    local ca = ffi.new("const int[10]")
+    fails(function(ca) ca[0] = 1 end, ca)
+  end
+  x.a[0] = 1
+  fails(function(x) x.ca[0] = 1 end, x)
+  fails(function(x) x.a = x.ca end, x) -- incompatible type
+  fails(function(x) x.ca = x.a end, x)
+  fails(function(x) x.ca = {} end, x)
+  fails(function(x) x.cac = "abc" end, x)
+
+  -- structs
+  do
+    local s = ffi.new("s_t")
+    s.v = 1
+    local cs = ffi.new("cs_t")
+    fails(function(cs) cs.v = 1 end, cs)
+  end
+  x.s.v = 1
+  fails(function(x) x.cs.v = 1 end, x)
+  x.s = x.cs
+  fails(function(x) x.cs = x.s end, x)
+  fails(function(x) x.cs = {} end, x)
+
+  -- pseudo-const structs
+  x.pcs1.v = 1
+  fails(function(x) x.pcs1.w = 1 end, x)
+  fails(function(x) x.pcs1 = x.pcs2 end, x)
+  fails(function(x) x.pcs1 = {} end, x)
+
+  -- transparent structs
+  local y = x.ni
+  fails(function(x) x.ni = 1 end, x)
+
+  -- complex subtype is implicitly const and doesn't inherit const attribute
+  x.cx = 1
+  fails(function(x) x.ccx = 1 end, x)
+  do
+    local cxa = ffi.new("complex[1]")
+    local ccxa = ffi.new("const complex[1]")
+    x.cp = cxa
+    x.ccp = cxa
+    fails(function(x) x.cp = ccxa end, x)
+    x.ccp = ccxa
+  end
+end
+
diff --git a/test/LuaJIT-tests/lib/ffi/ffi_convert.lua b/test/LuaJIT-tests/lib/ffi/ffi_convert.lua
new file mode 100644
index 0000000..bd3fb1f
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/ffi_convert.lua
@@ -0,0 +1,787 @@
+local ffi = require("ffi")
+
+local ctest = require("ctest")
+
+dofile("../common/ffi_util.inc")
+
+local tonumber = tonumber
+
+ffi.cdef[[
+typedef struct bar_t {
+  int v, w;
+} bar_t;
+// Same structure, but treated as different struct.
+typedef struct barx_t {
+  int v, w;
+} barx_t;
+
+typedef struct nest_t {
+  int a,b;
+  struct { int c,d; };
+  struct { int e1,e2; } e;
+  int f[2];
+} nest_t;
+
+typedef union uni_t {
+  int8_t a;
+  int16_t b;
+  int32_t c;
+} uni_t;
+
+typedef struct arrinc_t {
+  int a[];
+} arrinc_t;
+
+typedef enum uenum_t {
+  UE0, UE71 = 71, UE72
+} uenum_t;
+
+typedef enum ienum_t {
+  IE0, IEM12 = -12, IEM11
+} ienum_t;
+
+typedef struct foo_t {
+  bool b;
+  int8_t i8;
+  uint8_t u8;
+  int16_t i16;
+  uint16_t u16;
+  int32_t i32;
+  uint32_t u32;
+  int64_t i64;
+  uint64_t u64;
+  float f;
+  double d;
+  complex cf;
+  complex cd;
+  uint8_t __attribute__((mode(__V16QI__))) v16qi;
+  int __attribute__((mode(__V4SI__))) v4si;
+  double __attribute__((mode(__V2DF__))) v2df;
+  int *pi;
+  int *__ptr32 p32i;
+  const int *pci;
+  volatile int *pvi;
+  int **ppi;
+  const int **ppci;
+  void **ppv;
+  char *(*ppf)(char *, const char *);
+  int ai[10];
+  int ai_guard;
+  int ai2[10];
+  char ac[10];
+  char ac_guard;
+  bar_t s;
+  bar_t s2;
+  bar_t *ps;
+  const bar_t *pcs;
+  barx_t sx;
+  struct { int a,b,c; } si;
+  int si_guard;
+  nest_t sn;
+  uni_t ui;
+  uenum_t ue;
+  ienum_t ie;
+} foo_t;
+
+char *strcpy(char *dest, const char *src);
+typedef struct FILE FILE;
+int fileno(FILE *stream);
+int _fileno(FILE *stream);
+]]
+
+do
+  local foo_t = ffi.typeof("foo_t")
+  local sz = ffi.sizeof(foo_t)
+  local x = foo_t()
+  local y = foo_t()
+  ffi.fill(x, sz, 0xff)
+  ffi.fill(y, sz, 0xee)
+
+  -- unknown member
+  fails(function(x) local a = x.bad end, x)
+  fails(function(x) x.bad = 1 end, x)
+  -- too many initializers
+  fails(function(x) x.d = ffi.new("double", 1,2) end, x)
+
+  -- conversions to bool
+  x.b = false
+  assert(x.b == false)
+  x.b = true
+  assert(x.b == true)
+  x.b = 0
+  assert(x.b == false)
+  x.b = 10
+  assert(x.b == true)
+  y.b = false
+  x.b = y.b
+  assert(x.b == false)
+  x.b = ffi.new("bool", true)
+  assert(x.b == true)
+  x.b = ffi.cast("bool", false)
+  assert(x.b == false)
+  x.b = ffi.new("int32_t", 17)
+  assert(x.b == true)
+  x.b = ffi.new("int32_t", 0)
+  assert(x.b == false)
+
+  -- conversions from bool
+  x.i32 = true
+  assert(x.i32 == 1)
+  x.i32 = false
+  assert(x.i32 == 0)
+  x.i8 = ffi.new("bool", true)
+  assert(x.i8 == 1)
+  x.i8 = ffi.new("bool", false)
+  assert(x.i8 == 0)
+  x.d = true
+  assert(x.d == 1)
+  x.d = ffi.new("bool", false)
+  assert(x.d == 0)
+  -- assignment of bool to other types is not allowed
+  fails(function(x) x.cd = true end, x)
+  fails(function(x) x.v4si = true end, x)
+  fails(function(x) x.ai = true end, x)
+  fails(function(x) x.s = true end, x)
+
+  -- int to int conversions
+  x.i8 = 99
+  assert(x.i8 == 99)
+  x.i8 = -99
+  assert(x.i8 == -99)
+  x.i8 = 128
+  assert(x.i8 == -128)
+  x.i8 = 0xfffe
+  assert(x.i8 == -2)
+  y.i8 = 91
+  x.i8 = y.i8
+  assert(x.i8 == 91)
+  x.i8 = ffi.new("uint8_t", 0xb7)
+  assert(x.i8 == -73)
+  x.i8 = ffi.new("int16_t", 0x7fa0)
+  assert(x.i8 == -96)
+  x.i8 = ffi.new("int32_t", 0xff91)
+  assert(x.i8 == -111)
+  x.i8 = ffi.new("int64_t", 0xff81)
+  assert(x.i8 == -127)
+
+  x.u8 = 99
+  assert(x.u8 == 99)
+  x.u8 = -99
+  assert(x.u8 == 256-99)
+  x.u8 = 128
+  assert(x.u8 == 128)
+  x.u8 = 0xfffe
+  assert(x.u8 == 0xfe)
+  x.u8 = ffi.new("int8_t", -73)
+  assert(x.u8 == 0xb7)
+  x.u8 = ffi.new("int16_t", 0x7fa0)
+  assert(x.u8 == 0xa0)
+  x.u8 = ffi.new("int32_t", 0xff91)
+  assert(x.u8 == 0x91)
+  x.u8 = ffi.new("int64_t", 0xff81)
+  assert(x.u8 == 0x81)
+
+  x.i16 = 99
+  assert(x.i16 == 99)
+  x.i16 = -99
+  assert(x.i16 == -99)
+  x.i16 = 32768
+  assert(x.i16 == -32768)
+  x.i16 = 0xffffffe
+  assert(x.i16 == -2)
+  x.i16 = ffi.new("int8_t", -10)
+  assert(x.i16 == -10)
+  x.i16 = ffi.new("uint8_t", 254)
+  assert(x.i16 == 254)
+  x.i16 = ffi.new("uint16_t", 0xefa0)
+  assert(x.i16 == 0xefa0-65536)
+  x.i16 = ffi.new("int32_t", 0xffe291)
+  assert(x.i16 == 0xe291-65536)
+  x.i16 = ffi.new("int64_t", 0xffd481)
+  assert(x.i16 == 0xd481-65536)
+
+  x.u16 = 99
+  assert(x.u16 == 99)
+  x.u16 = -99
+  assert(x.u16 == 65536-99)
+  x.u16 = 32768
+  assert(x.u16 == 32768)
+  x.u16 = 0xffffffe
+  assert(x.u16 == 65534)
+  x.u16 = ffi.new("int8_t", -10)
+  assert(x.u16 == 65536-10)
+  x.u16 = ffi.new("uint8_t", 254)
+  assert(x.u16 == 254)
+  x.u16 = ffi.new("int16_t", 0xefa0-65536)
+  assert(x.u16 == 0xefa0)
+  x.u16 = ffi.new("int32_t", 0xffe291)
+  assert(x.u16 == 0xe291)
+  x.u16 = ffi.new("int64_t", 0xffd481)
+  assert(x.u16 == 0xd481)
+
+  x.i32 = 99
+  assert(x.i32 == 99)
+  x.i32 = -99
+  assert(x.i32 == -99)
+  -- double to int conversion for values >= 0x80000000 is undefined
+  x.i32 = ffi.new("int8_t", -10)
+  assert(x.i32 == -10)
+  x.i32 = ffi.new("uint8_t", 254)
+  assert(x.i32 == 254)
+  x.i32 = ffi.new("int16_t", -517)
+  assert(x.i32 == -517)
+  x.i32 = ffi.new("uint16_t", 35876)
+  assert(x.i32 == 35876)
+  x.i32 = ffi.new("uint32_t", 0xffffe291)
+  assert(x.i32 == 0xffffe291-2^32)
+  x.i32 = ffi.new("int64_t", 15*2^32-317)
+  assert(x.i32 == -317)
+
+  x.u32 = 99
+  assert(x.u32 == 99)
+  -- x.u32 = -99 -- this is undefined on some architectures
+  -- assert(x.u32 == 2^32-99)
+  x.u32 = 0x87654321
+  assert(x.u32 == 0x87654321)
+  x.u32 = ffi.new("int8_t", -10)
+  assert(x.u32 == 2^32-10)
+  x.u32 = ffi.new("uint8_t", 254)
+  assert(x.u32 == 254)
+  x.u32 = ffi.new("int16_t", -517)
+  assert(x.u32 == 2^32-517)
+  x.u32 = ffi.new("uint16_t", 35876)
+  assert(x.u32 == 35876)
+  x.u32 = ffi.new("int32_t", 0xffffe291-2^32)
+  assert(x.u32 == 0xffffe291)
+  x.u32 = ffi.new("int64_t", 15*2^32-317)
+  assert(x.u32 == 2^32-317)
+
+  x.i64 = 99
+  assert(tonumber(x.i64) == 99)
+  x.i64 = -99
+  assert(tonumber(x.i64) == -99)
+  x.i64 = 0x1234*2^32+0x87654321
+  assert(tonumber(x.i64) == 0x1234*2^32+0x87654321)
+  -- double to int64 conversion for values >= 2^63-1 is undefined
+  x.i64 = ffi.new("int8_t", -10)
+  assert(tonumber(x.i64) == -10)
+  x.i64 = ffi.new("uint8_t", 254)
+  assert(tonumber(x.i64) == 254)
+  x.i64 = ffi.new("int16_t", -517)
+  assert(tonumber(x.i64) == -517)
+  x.i64 = ffi.new("uint16_t", 35876)
+  assert(tonumber(x.i64) == 35876)
+  x.i64 = ffi.new("int32_t", -12345678)
+  assert(tonumber(x.i64) == -12345678)
+  x.i64 = ffi.new("uint32_t", 0xffeeddcc)
+  assert(tonumber(x.i64) == 0xffeeddcc)
+  x.i64 = ffi.new("uint64_t", 0xffeeddcc*2^32)
+  assert(tonumber(x.i64) == 0xffeeddcc*2^32-2^64)
+
+  x.u64 = 99
+  assert(tonumber(x.u64) == 99)
+  -- x.u64 = -99 -- this is undefined on some architectures
+  -- assert(tonumber(x.u64) == 2^64-99)
+  x.u64 = 0x1234*2^32+0x87654321
+  assert(tonumber(x.u64) == 0x1234*2^32+0x87654321)
+  -- double to int64 conversion for values >= 2^63-1 is undefined
+  x.u64 = ffi.new("int8_t", -10)
+  assert(tonumber(x.u64) == 2^64-10)
+  x.u64 = ffi.new("uint8_t", 254)
+  assert(tonumber(x.u64) == 254)
+  x.u64 = ffi.new("int16_t", -517)
+  assert(tonumber(x.u64) == 2^64-517)
+  x.u64 = ffi.new("uint16_t", 35876)
+  assert(tonumber(x.u64) == 35876)
+  x.u64 = ffi.new("int32_t", -12345678)
+  assert(tonumber(x.u64) == 2^64-12345678)
+  x.u64 = ffi.new("uint32_t", 0xffeeddcc)
+  assert(tonumber(x.u64) == 0xffeeddcc)
+  x.u64 = ffi.new("int64_t", -0x7feeddcc*2^32)
+  assert(tonumber(x.u64) == 2^64-0x7feeddcc*2^32)
+
+  -- FP to int conversions, test for truncation
+  x.i32 = 1.9
+  assert(x.i32 == 1)
+  x.i32 = 2.9
+  assert(x.i32 == 2)
+  x.i32 = -1.9
+  assert(x.i32 == -1)
+  x.i32 = -2.9
+  assert(x.i32 == -2)
+  x.i8 = 1.9
+  assert(x.i8 == 1)
+  x.u8 = 1.9
+  assert(x.u8 == 1)
+  x.i16 = 1.9
+  assert(x.i16 == 1)
+  x.u16 = 1.9
+  assert(x.u16 == 1)
+  x.u32 = 1.9
+  assert(x.u32 == 1)
+  x.u64 = 1.9
+  assert(tonumber(x.u64) == 1)
+
+  -- int to FP conversions (most tested above)
+  x.f = ffi.new("int32_t", -17)
+  assert(x.f == -17)
+  x.d = ffi.new("int32_t", -17)
+  assert(x.d == -17)
+  -- test for rounding due to precision loss
+  x.f = -1717986919
+  assert(x.f == -1717986944)
+  x.f = ffi.new("int32_t", 0x77777777)
+  assert(x.f == 0x77777780)
+  x.d = ffi.new("union { uint32_t u32[2]; uint64_t u64; }",
+		{{ 0x77777777, 0x77777777}}).u64
+  assert(x.d == 0x77777777*2^32 + 0x77777800)
+
+  -- complex initialization
+  x.cd = ffi.new("complex", 9.125, -78.5)
+  assert(x.cd.re == 9.125 and x.cd.im == -78.5)
+  x.cd = ffi.new("complex", {9.125, -78.5})
+  assert(x.cd.re == 9.125 and x.cd.im == -78.5)
+  -- too many initializers
+  fails(function(x) x.cd = ffi.new("complex", 1,2,3) end, x)
+
+  -- conversions between FP and complex
+  x.cf = -17.25
+  assert(x.cf.re == -17.25 and x.cf.im == 0)
+  x.cf = ffi.new("complex float", -57.5) -- missing initializer
+  assert(x.cf.re == -57.5 and x.cf.im == 0)
+  x.cf = ffi.new("complex float", 9.125, -78.5)
+  assert(x.cf.re == 9.125 and x.cf.im == -78.5)
+  x.cf = ffi.new("complex double", 9.125, -78.5)
+  assert(x.cf.re == 9.125 and x.cf.im == -78.5)
+
+  x.cd = -17.25
+  assert(x.cd.re == -17.25 and x.cd.im == 0)
+  x.cd = ffi.new("complex double", -57.5) -- missing initializer
+  assert(x.cd.re == -57.5 and x.cd.im == 0)
+  x.cd = ffi.new("complex float", 9.125, -78.5)
+  assert(x.cd.re == 9.125 and x.cd.im == -78.5)
+  x.cd = ffi.new("complex double", 9.125, -78.5)
+  assert(x.cd.re == 9.125 and x.cd.im == -78.5)
+
+  x.f = ffi.new("complex float", 9.125, -78.5)
+  assert(x.f == 9.125)
+  x.f = ffi.new("complex double", 9.125, -78.5)
+  assert(x.f == 9.125)
+
+  x.d = ffi.new("complex float", 9.125, -78.5)
+  assert(x.d == 9.125)
+  x.d = ffi.new("complex double", 9.125, -78.5)
+  assert(x.d == 9.125)
+
+  -- conversions between int and complex
+  x.cd = ffi.new("int32_t", -138)
+  assert(x.cd.re == -138 and x.cd.im == 0)
+  x.i32 = ffi.new("complex", 9.125, -78.5)
+  assert(x.i32 == 9)
+
+  -- vector initialization
+  x.v4si = ffi.new("int __attribute__((mode(__V4SI__)))", 1, 2, 3, 4)
+  assert(x.v4si[0] == 1 and x.v4si[1] == 2 and
+	 x.v4si[2] == 3 and x.v4si[3] == 4)
+  x.v2df = ffi.new("double __attribute__((mode(__V2DF__)))", {3.5, -6.75})
+  assert(x.v2df[0] == 3.5 and x.v2df[1] == -6.75)
+  -- too many initializers
+  fails(function(x)
+    x.v4si = ffi.new("int __attribute__((mode(__V4SI__)))", 1,2,3,4,5)
+  end, x)
+
+  -- conversions to vectors
+  x.v4si = -17
+  assert(x.v4si[0] == -17 and x.v4si[1] == -17 and
+	 x.v4si[2] == -17 and x.v4si[3] == -17)
+  x.v4si = ffi.new("int32_t", 712)
+  assert(x.v4si[0] == 712 and x.v4si[1] == 712 and
+	 x.v4si[2] == 712 and x.v4si[3] == 712)
+  x.v2df = 12.5
+  assert(x.v2df[0] == 12.5 and x.v2df[1] == 12.5)
+  x.v2df = ffi.new("complex", 9.125, -78.5)
+  assert(x.v2df[0] == 9.125 and x.v2df[1] == 9.125)
+
+  -- assignment of same-sized but differently-typed vectors
+  x.v16qi = 99
+  x.v4si = 0x33333333
+  x.v16qi = x.v4si
+  assert(x.v16qi[0] == 0x33 and x.v16qi[15] == 0x33)
+
+  -- string converted to enum
+  -- x.ue = -1 -- this is undefined on some architectures
+  -- assert(x.ue == 0xffffffff)
+  x.ue = "UE0"
+  assert(x.ue == 0)
+  x.ue = "UE72"
+  assert(x.ue == 72)
+  x.ie = -1
+  assert(x.ie == -1)
+  x.ie = "IE0"
+  assert(x.ie == 0)
+  x.ie = "IEM11"
+  assert(x.ie == -11)
+
+  x.pi = x.pi
+  -- assignment to pointer with higher qualifiers is ok
+  x.pci = x.pi
+  x.pvi = x.pi
+  -- assignment to pointer with lower qualifiers is not ok
+  fails(function(x) x.pi = x.pci end, x)
+  fails(function(x) x.pi = x.pvi end, x)
+  fails(function(x) x.pci = x.pvi end, x)
+  fails(function(x) x.pvi = x.pci end, x)
+  -- assignment of pointers with incompatible child types is not ok
+  fails(function(x) x.ppi = x.ai end, x)
+  fails(function(x) x.ppi = x.pi end, x)
+  fails(function(x) x.ppv = x.ppi end, x)
+  -- qualifiers of child types must match, higher qualifiers not ok
+  fails(function(x) x.ppci = x.ppi end, x)
+  fails(function(x) x.ppi = x.ppci end, x)
+
+  -- pointer/int conversions are not allowed by default
+  fails(function(x) x.pi = 1 end, x)
+  fails(function(x) x.i32 = x.pi end, x)
+  assert(tonumber(x.pi) == nil)
+  assert(tonumber(x.ai) == nil)
+  assert(tonumber(x.si) == nil)
+
+  -- but pointer/int casts are allowed
+  x.pi = ffi.cast("int *", ffi.new("int32_t", 0x12345678))
+  x.i32 = ffi.cast("int32_t", x.pi)
+  assert(x.i32 == 0x12345678)
+  x.pi = ffi.cast("int *", 1234560.3)
+  x.i32 = ffi.cast("int32_t", x.pi)
+  assert(x.i32 == 1234560)
+  -- bad cast from non-TValue double to pointer
+  fails(function(x)
+    ffi.cast("int *", ffi.new("double", 1.5))
+  end, x)
+
+  -- nil sets a pointer to NULL
+  x.pi = nil
+  assert(tonumber(ffi.cast("uintptr_t", x.pi)) == 0)
+
+  -- userdata and lightuserdata are treated as void *
+  do
+    local u = newproxy()
+    local uaddr = _G.tonumber(string.match(tostring(u), "(0x.*)"))
+    x.pi = u
+    assert(tonumber(ffi.cast("uintptr_t", x.pi)) == uaddr)
+    x.pi = ctest.lightud(12345678)
+    assert(tonumber(ffi.cast("uintptr_t", x.pi)) == 12345678)
+  end
+
+  -- io.* file converts to file handle (as a void *)
+  if ffi.abi("win") then
+    assert(ffi.C._fileno(io.stdout) == 1)
+    assert(ffi.C._fileno(io.stderr) == 2)
+    local x
+    for i=1,100 do x = ffi.C._fileno(io.stderr) end
+    assert(x == 2)
+  else
+    assert(ffi.C.fileno(io.stdout) == 1)
+    assert(ffi.C.fileno(io.stderr) == 2)
+    local x
+    for i=1,100 do x = ffi.C.fileno(io.stderr) end
+    assert(x == 2)
+  end
+
+  -- truncation/extension of __ptr32
+  if ffi.abi("64bit") then
+    x.pi = ffi.cast("int *", 15*2^32+0x12345678)
+    assert(tonumber(ffi.cast("uintptr_t", x.pi)) == 15*2^32+0x12345678)
+    x.p32i = x.pi
+    assert(tonumber(ffi.cast("uintptr_t", x.p32i)) == 0x12345678)
+    x.pi = ffi.cast("int *", 0x1234*2^32+0x56780000)
+    x.pi = x.p32i
+    assert(tonumber(ffi.cast("uintptr_t", x.pi)) == 0x12345678)
+  end
+
+  -- reference initialization
+  do
+    x.ai[0] = 712
+    local ri = ffi.new("int &", x.ai)
+    assert(tonumber(ri) == 712)
+    local ra = ffi.new("int (&)[10]", ffi.cast("int (*)[10]", x.ai))
+    assert(ra[0] == 712)
+  end
+
+  -- ffi.sizeof follows references
+  assert(ffi.sizeof(x.ai) == 4*10)
+  -- ffi.offsetof follows references
+  assert(ffi.offsetof(x.s, "v") == 0)
+  assert(ffi.offsetof(x.s, "w") == 4)
+
+  -- ffi.fill writes the right amount
+  ffi.fill(x.ai2, ffi.sizeof(x.ai2), 0x72)
+  ffi.fill(x.ai, ffi.sizeof(x.ai), 0x13)
+  assert(x.ai[0] == 0x13131313)
+  assert(x.ai[9] == 0x13131313)
+  assert(x.ai2[0] == 0x72727272)
+  assert(x.ai2[9] == 0x72727272)
+
+  -- array cannot be assigned a pointer
+  fails(function(x) x.ai = x.pi end, x)
+  -- but pointer can be assigned the address of an array
+  x.pi = x.ai2
+  assert(x.pi[0] == 0x72727272)
+  assert(x.pi[9] == 0x72727272)
+  x.pi = x.ai
+  assert(x.pi[0] == 0x13131313)
+  assert(x.pi[9] == 0x13131313)
+  x.ai = x.ai2 -- array copy
+  assert(x.ai[0] == 0x72727272)
+  assert(x.ai[9] == 0x72727272)
+  -- reflected via pointer, too
+  assert(x.pi[0] == 0x72727272)
+  assert(x.pi[9] == 0x72727272)
+  -- mismatched type or size in array copy
+  fails(function(x) x.ai = x.ac end, x)
+  fails(function(x) x.ai = ffi.new("int[20]") end, x)
+  fails(function(x) x.ai = ffi.new("arrinc_t").a end, x)
+  fails(function(x) ffi.new("arrinc_t").a = x.ai end, x)
+
+  ffi.fill(x.s2, ffi.sizeof(x.s2), 0x59)
+  x.s.v = 0x12345678
+  x.s.w = 0x789abcde
+  assert(x.s.v == 0x12345678)
+  assert(x.s.w == 0x789abcde)
+
+  -- struct cannot be assigned a pointer
+  fails(function(x) x.s = x.ps end, x)
+  -- but pointer can be assigned the address of a struct
+  x.ps = x.s
+  assert(x.ps.v == 0x12345678)
+  assert(x.ps.w == 0x789abcde)
+  x.pcs = x.s
+  assert(x.pcs.v == 0x12345678)
+  assert(x.pcs.w == 0x789abcde)
+  x.s = x.s2 -- struct copy
+  assert(x.s.v == 0x59595959)
+  assert(x.s.w == 0x59595959)
+  -- reflected via pointer, too
+  assert(x.ps.v == 0x59595959)
+  assert(x.ps.w == 0x59595959)
+
+  -- structs must be identical, structural equivalence is not enough
+  fails(function(x) x.ps = x.sx end, x)
+  fails(function(x) x.s = x.sx end, x)
+
+  -- string copy to arrays
+  x.ac_guard = 99
+  ffi.fill(x.ac, 10, 0x37)
+  x.ac = "ABCD"
+  assert(x.ac[0] == 65+0)
+  assert(x.ac[3] == 65+3)
+  assert(x.ac[4] == 0)
+  assert(x.ac[5] == 0x37)
+  x.ac = "ABCDEFGHI"
+  assert(x.ac[8] == 65+8)
+  assert(x.ac[9] == 0)
+  x.ac = "ABCDEFGHIJ" -- reduced size
+  assert(x.ac[8] == 65+8)
+  assert(x.ac[9] == 65+9)
+  x.ac = "ABCDEFGHIJKLM"
+  assert(x.ac[8] == 65+8)
+  assert(x.ac[9] == 65+9)
+  do -- copy to a[?]
+    local vx = ffi.new("struct { char ac[?]; }", 20)
+    ffi.fill(vx.ac, 20, 0x37)
+    vx.ac = "ABCDEFGHI"
+    assert(vx.ac[8] == 65+8)
+    assert(vx.ac[9] == 0)
+  end
+  do -- copy to a[0]
+    local vx = ffi.new("union { char ac[0]; char c[20]; }")
+    ffi.fill(vx.ac, 20, 0x37)
+    vx.ac = "ABCDEFGHI"
+    assert(vx.ac[8] == 65+8)
+    assert(vx.ac[9] == 0)
+  end
+  -- mismatched type or size in string copy
+  fails(function(x) x.i32 = "ABCD" end, x)
+  fails(function(x) x.ai = "ABCD" end, x)
+  assert(x.ac_guard == 99) -- Check guard
+
+  -- array initialization
+  x.ai = ffi.new("int[10]") -- zero fill
+  for i=0,9 do assert(x.ai[i] == 0) end
+  x.ai = ffi.new("int[10]", -67) -- replicate first element
+  for i=0,9 do assert(x.ai[i] == -67) end
+  x.ai = ffi.new("int[10]", 42, -27) -- remainder filled with zero
+  assert(x.ai[0] == 42)
+  assert(x.ai[1] == -27)
+  for i=2,9 do assert(x.ai[i] == 0) end
+  x.ai = ffi.new("int[10]", 1,2,3,4,5,6,7,8,9,10)
+  for i=0,9 do assert(x.ai[i] == i+1) end
+  x.ai = ffi.new("int[10]", {1,2,3,4,5,6,7,8,9,10})
+  for i=0,9 do assert(x.ai[i] == i+1) end
+  -- VLA initialization
+  do
+    local v = ffi.new("int[?]", 4)
+    for i=0,3 do assert(v[i] == 0) end
+    local v = ffi.new("int[?]", 4, 833)
+    for i=0,3 do assert(v[i] == 833) end
+    local v = ffi.new("int[?]", 4, 12, -9)
+    assert(v[0] == 12 and v[1] == -9 and v[2] == 0 and v[3] == 0)
+    local v = ffi.new("int[?]", 4, 1,2,3,4)
+    assert(v[0] == 1 and v[1] == 2 and v[2] == 3 and v[3] == 4)
+  end
+  -- too many initializers
+  fails(function(x) x.ai = {1,2,3,4,5,6,7,8,9,10,11} end, x)
+  for i=0,9 do assert(x.ai[i] == i+1) end -- but it's partially executed
+  fails(function(x)
+    local v = ffi.new("int[?]", 4, 1,2,3,4,5)
+  end, x)
+
+  -- struct initialization
+  x.sn = ffi.new("nest_t") -- zero fill
+  assert(x.sn.e.e2 == 0)
+  x.sn = ffi.new("nest_t", 1,2) -- remainder filled with zero
+  assert(x.sn.a == 1 and x.sn.b == 2 and x.sn.c == 0 and x.sn.d == 0)
+  assert(x.sn.e.e1 == 0 and x.sn.e.e2 == 0)
+  assert(x.sn.f[0] == 0 and x.sn.f[1] == 0)
+  x.sn = ffi.new("nest_t", 1,2,3,4,{5,6},{7,8}) -- multi-value init
+  assert(x.sn.a == 1 and x.sn.b == 2 and x.sn.c == 3 and x.sn.d == 4)
+  assert(x.sn.e.e1 == 5 and x.sn.e.e2 == 6)
+  assert(x.sn.f[0] == 7 and x.sn.f[1] == 8)
+  x.sn = ffi.new("nest_t", {1,2,3,4,{5,6},{7,8}}) -- single-value init
+  assert(x.sn.a == 1 and x.sn.b == 2 and x.sn.c == 3 and x.sn.d == 4)
+  assert(x.sn.e.e1 == 5 and x.sn.e.e2 == 6)
+  assert(x.sn.f[0] == 7 and x.sn.f[1] == 8)
+  -- VLS initialization
+  do
+    local v = ffi.new("struct { int x; int a[?]; }", 4)
+    assert(v.x == 0)
+    for i=0,3 do assert(v.a[i] == 0) end
+    local v = ffi.new("struct { int x; int a[?]; }", 4, 9, {833})
+    assert(v.x == 9)
+    -- NYI: fill up VLA in VLS. currently seen as indefinite length
+    -- for i=0,3 do assert(v.a[i] == 833) end
+    assert(v.a[0] == 833 and v.a[1] == 0 and v.a[2] == 0 and v.a[3] == 0)
+  end
+  -- no multi-value init beyond first level
+  fails(function(x)
+    x.sn = ffi.new("nest_t", 1,2,3,4,5,6,7,8)
+  end, x)
+  -- too many initializers
+  fails(function(x)
+    x.sn = ffi.new("nest_t", 1,2,3,4,{5,6},{7,8}, 9)
+  end, x)
+
+  -- union initialization
+  x.ui = ffi.new("uni_t") -- zero fill
+  assert(x.ui.a == 0 and x.ui.b == 0 and x.ui.c == 0)
+  x.ui = ffi.new("uni_t", 255) -- initialize first field, remainder is zero
+  if ffi.abi("le") then
+    assert(x.ui.a == -1 and x.ui.b == 255 and x.ui.c == 255)
+  else
+    assert(x.ui.a == -1 and x.ui.b == -256 and x.ui.c == -16777216)
+  end
+  -- too many initializers
+  fails(function(x)
+    x.sn = ffi.new("uni_t", 1,2)
+  end, x)
+  fails(function()
+    ffi.new("union { struct { int x; }; int y; }", 1,2)
+  end)
+
+  -- table converted to array
+  ffi.fill(x.ai, ffi.sizeof(x.ai), 0x13)
+  x.ai_guard = 99
+  x.ai = {} -- zero fill
+  for i=0,9 do assert(x.ai[i] == 0) end
+  x.ai = {42} -- replicate
+  for i=0,9 do assert(x.ai[i] == 42) end
+  x.ai = {[0] = -67} -- replicate from index 0
+  for i=0,9 do assert(x.ai[i] == -67) end
+  x.ai = {42, -27} -- remainder filled with zero
+  assert(x.ai[0] == 42)
+  assert(x.ai[1] == -27)
+  for i=2,9 do assert(x.ai[i] == 0) end
+  assert(x.ai_guard == 99) -- Check guard
+
+  -- table converted to struct
+  ffi.fill(x.si, ffi.sizeof(x.si), 0x74)
+  x.si_guard = 97
+  -- convert from array part
+  x.si = {} -- zero fill
+  assert(x.si.a == 0 and x.si.b == 0 and x.si.c == 0)
+  x.si = {42, 18} -- fill fields in order
+  assert(x.si.a == 42 and x.si.b == 18 and x.si.c == 0)
+  x.si = {[0] = -67, 12} -- fill fields in order from index 0
+  assert(x.si.a == -67 and x.si.b == 12 and x.si.c == 0)
+  x.si = {42, -27, 19, 8} -- too many initializers ignored
+  assert(x.si.a == 42 and x.si.b == -27 and x.si.c == 19)
+  -- convert from hash part
+  x.si = {b = 12}
+  assert(x.si.a == 0 and x.si.b == 12 and x.si.c == 0)
+  x.si = {b = 12, c = 85, a = 35}
+  assert(x.si.a == 35 and x.si.b == 12 and x.si.c == 85)
+  x.si = {b = 19, foo = 1, bar = 2} -- unknown initializers ignored
+  assert(x.si.a == 0 and x.si.b == 19 and x.si.c == 0)
+  x.si = {b = 12, 5, 6, 7} -- hash part ignored if array part exists
+  assert(x.si.a == 5 and x.si.b == 6 and x.si.c == 7)
+  assert(x.si_guard == 97) -- Check guard
+
+  -- table converted to struct with transparent/nested structs and arrays
+  ffi.fill(x.sn, ffi.sizeof(x.sn), 0x74)
+  x.sn = {} -- zero fill
+  assert(x.sn.e.e2 == 0)
+  x.sn = {1,2,3,4,{5,6},{7,8}}
+  assert(x.sn.a == 1 and x.sn.b == 2 and x.sn.c == 3 and x.sn.d == 4)
+  assert(x.sn.e.e1 == 5 and x.sn.e.e2 == 6)
+  assert(x.sn.f[0] == 7 and x.sn.f[1] == 8)
+  x.sn = {c = 10, e = {11,12}, f = {13,14}}
+  assert(x.sn.a == 0 and x.sn.b == 0 and x.sn.c == 10 and x.sn.d == 0)
+  assert(x.sn.e.e1 == 11 and x.sn.e.e2 == 12)
+  assert(x.sn.f[0] == 13 and x.sn.f[1] == 14)
+
+  -- table converted to union
+  ffi.fill(x.ui, ffi.sizeof(x.ui), 0x58)
+  x.ui = {} -- zero fill
+  assert(x.ui.a == 0 and x.ui.b == 0 and x.ui.c == 0)
+  x.ui = {255, -1, -1} -- only first initializer used
+  if ffi.abi("le") then
+    assert(x.ui.a == -1 and x.ui.b == 255 and x.ui.c == 255)
+  else
+    assert(x.ui.a == -1 and x.ui.b == -256 and x.ui.c == -16777216)
+  end
+  x.ui = {b = -1} -- initialize a specific element of the union
+  if ffi.abi("le") then
+    assert(x.ui.a == -1 and x.ui.b == -1 and x.ui.c == 65535)
+  else
+    assert(x.ui.a == -1 and x.ui.b == -1 and x.ui.c == -65536)
+  end
+
+  -- copy constructor
+  do
+    x.s.v = 1; x.s.w = 2
+    local s = ffi.new("bar_t", x.s)
+    assert(s.v == 1 and s.w == 2)
+    for i=0,9 do x.ai[i] = i end
+    local a = ffi.new("int[10]", x.ai)
+    for i=0,9 do assert(a[i] == i) end
+  end
+
+  -- assignment to function pointer
+  x.ppf = ffi.C.strcpy
+end
+
+do
+  collectgarbage()
+  local oc = collectgarbage("count")
+  local cd = ffi.new"struct { struct { int a; } x;}"
+  local function f(cd)
+    local x
+    for i=1,1e5 do x = cd.x end
+  end
+  for i=1,2 do
+    f(cd)
+    local nc = collectgarbage("count")
+    assert(nc < oc + 200, "GC step missing for cdata __index")
+    jit.off(f)
+  end
+end
+
diff --git a/test/LuaJIT-tests/lib/ffi/ffi_enum.lua b/test/LuaJIT-tests/lib/ffi/ffi_enum.lua
new file mode 100644
index 0000000..e8e40ad
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/ffi_enum.lua
@@ -0,0 +1,57 @@
+
+local ffi = require("ffi")
+
+dofile("../common/ffi_util.inc")
+
+ffi.cdef[[
+typedef enum enum_i { FOO_I = -1, II = 10 } enum_i;
+typedef enum enum_u { FOO_U = 1, UU = 10 } enum_u;
+
+enum_i call_ei_i(int a) asm("call_i");
+enum_u call_eu_i(int a) asm("call_i");
+int call_i_ei(enum_i a) asm("call_i");
+int call_i_eu(enum_u a) asm("call_i");
+]]
+
+local C = ffi.load("../clib/ctest")
+
+do
+
+  local t = ffi.new("enum_i[100]")
+  for i=0,99 do t[i] = "II" end
+  for i=0,99 do assert(t[i] == "II") end
+  for i=0,99 do assert(t[i] >= "II") end
+  for i=0,99 do t[i] = -10 end
+  for i=0,99 do assert(t[i] == -10) end
+  for i=0,99 do assert(t[i] ~= 2147483648) end
+  for i=1,99 do assert(t[i] == t[i-1]) end
+  assert(t[0]+1 == -9)
+  assert(t[0] ~= "BB")
+  fails(function() return t[0] > "BB" end)
+
+  local u = ffi.new("enum_u[100]")
+  for i=0,99 do u[i] = "UU" end
+  for i=0,99 do assert(u[i] == "UU") end
+  for i=0,99 do assert(u[i] >= "UU") end
+  for i=0,99 do u[i] = 4294967296-10 end
+  for i=0,99 do assert(u[i] == 4294967296-10) end
+  for i=0,99 do assert(u[i] ~= -10) end
+  for i=1,99 do assert(u[i] == u[i-1]) end
+  assert(u[0]+1 == 4294967296-9)
+
+  for i=0,99 do assert(t[i] ~= u[i]) end
+end
+
+do
+  for i=0,99 do assert(C.call_ei_i(9) == "II") end
+  for i=0,99 do assert(C.call_eu_i(9) == "UU") end
+  for i=0,99 do assert(C.call_i_ei("II") == 11) end
+  for i=0,99 do assert(C.call_i_eu("UU") == 11) end
+end
+
+do
+  local f = ffi.cast("bool (*)(enum_i)", function(e) return e == "II" end)
+  assert(f("II"))
+  assert(not f(0))
+end
+
diff --git a/test/LuaJIT-tests/lib/ffi/ffi_gcstep_recursive.lua b/test/LuaJIT-tests/lib/ffi/ffi_gcstep_recursive.lua
new file mode 100644
index 0000000..cb19df1
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/ffi_gcstep_recursive.lua
@@ -0,0 +1,66 @@
+-- From Robert G. Jakabosky, 2012-03-20
+
+local N=tonumber(arg[1] or 10000)
+
+local ffi=require"ffi"
+
+ffi.cdef[[
+struct Buffer { void *buf; };
+typedef struct Buffer Buffer;
+]]
+
+local Buffer_mt = { __index = {} }
+local Buffer = ffi.typeof("Buffer")
+
+-- used to track alive objects
+local nobj_obj_flags = {}
+
+local function obj_to_id(ptr)
+  return tonumber(ffi.cast('uintptr_t', ffi.cast('void *', ptr)))
+end
+
+function obj_type_Buffer_push(val)
+  local obj = Buffer(val)
+  local id = obj_to_id(obj)
+  nobj_obj_flags[id] = true
+  return obj
+end
+
+local function Buffer_new(len)
+  local buf = ffi.cast('void *', 0xdeadbeef)
+  return obj_type_Buffer_push(buf)
+end
+
+function obj_type_Buffer_delete(obj)
+  local id = obj_to_id(obj)
+  if not nobj_obj_flags[id] then return nil end
+  nobj_obj_flags[id] = nil
+  return obj.buf
+end
+
+local getmeta = debug.getmetatable
+
+local function Buffer_close(self)
+  local buf = obj_type_Buffer_delete(self)
+  getmeta("Buffer_close") -- cause trace to abort
+  if buf then
+    self.buf = nil
+  end
+end
+Buffer_mt.__gc = Buffer_close
+Buffer_mt.__index.close = Buffer_close
+
+ffi.metatype(Buffer, Buffer_mt)
+
+local cdata = {}
+for x=1,2 do
+  cdata = {}
+  for i=1,N do
+    cdata[i] = Buffer_new(1)
+  end
+  for i=1,N do
+    cdata[i]:close()
+  end
+  cdata = nil
+end
+
diff --git a/test/LuaJIT-tests/lib/ffi/ffi_jit_arith.lua b/test/LuaJIT-tests/lib/ffi/ffi_jit_arith.lua
new file mode 100644
index 0000000..0554fe6
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/ffi_jit_arith.lua
@@ -0,0 +1,155 @@
+local ffi = require("ffi")
+
+do
+  local a = ffi.new("int64_t[?]", 101)
+  for i=1,100 do a[i] = -2 end
+  for i=1,100 do a[i] = i end
+  local x, y, m = 0ll, 0ll, 0ll
+  for i=1,100 do x = x + a[i]; y = y - a[i]; m = -a[i] end
+  assert(x == 5050)
+  assert(y == -5050)
+  assert(m == -100)
+  local z, z0 = 1ll, 3ll
+  for i=1,100 do z = a[i] * z0 end
+  assert(z == 300)
+  for i=1,100 do z = a[i] * 4ll end -- test MUL -> BSHL rule
+  assert(z == 400)
+  z, z0 = 1ll, 0x123456789abcdef0ll
+  for i=1,100 do z = z0 / a[i] end
+  assert(z == 0x123456789abcdef0ll / 100)
+  z, z0 = 1ll, 0x123456789abcdef0ll
+  for i=1,100 do z = z0 % a[i] end
+  assert(z == 0x123456789abcdef0ll % 100)
+  -- use multiple 64 bit PHIs
+  local t, u, v, w = 0ll, 0ll, 0ll, 0ll
+  for i=1,100 do t = t + a[i]; u = u + a[i]; v = v + a[i]; w = w + a[i] end
+  assert(t == 5050)
+  assert(u == 5050)
+  assert(v == 5050)
+  assert(w == 5050)
+end
+
+do
+  local a = ffi.new("uint64_t[?]", 101)
+  for i=1,100 do a[i] = i end
+  local x, y, m = 0ull, 0ull, 0ull
+  for i=1,100 do x = x + a[i]; y = y - a[i]; m = -a[i] end
+  assert(x == 5050)
+  assert(y == 0ull-5050)
+  assert(m == -100ull)
+  local z, z0 = 1ull, 3ll
+  for i=1,100 do z = a[i] * z0 end
+  assert(z == 300)
+  z, z0 = 1ull, 0x123456789abcdef0ull
+  for i=1,100 do z = z0 / a[i] end
+  assert(z == 0x123456789abcdef0ull / 100)
+  z, z0 = 1ull, 0x123456789abcdef0ull
+  for i=1,100 do z = z0 % a[i] end
+  assert(z == 0x123456789abcdef0ull % 100)
+end
+
+do
+  local x = 0ll
+  for i=1,100 do x = x + (-2ll) ^ (bit.band(i, 15)+1ll) end
+  assert(x == 262120)
+end
+
+do
+  local x, a = 0ll, -2ll
+  for i=1,100 do x = x + a ^ (bit.band(i, 15)+1ll) end
+  assert(x == 262120)
+end
+
+do
+  local x = 0ull
+  for i=1,100 do x = x + (-2ll) ^ (bit.band(i, 15)+1ull) end
+  assert(x == 262120)
+end
+
+do
+  for i=1,200 do local j = bit.band(i, 7); assert((j == 0ll) == (j == 0)) end
+  for i=1,200 do assert((i < 100ll) == (i < 100)) end
+  for i=1,200 do assert((i <= 100ll) == (i <= 100)) end
+  for i=-100,100 do assert((i > 100ull) == (i < 0)) end
+end
+
+do
+  local a = ffi.new("int64_t[?]", 100)
+  for i=0,99 do
+    a[i] = math.random(0, 2^32)*0x100000000LL + math.random(0, 2^32)
+  end
+  a[92] = 0x10000000LL
+  a[93] = 0x10000001LL
+  a[94] = math.random(0, 2^32)
+  a[95] = a[94] + 0x100000000LL
+  a[96] = a[94] + 0x100000001LL
+  a[97] = a[20]
+  a[98] = 0
+  a[99] = -1
+
+  local function cksum(b)
+    local bxor, rol = bit.bxor, bit.rol
+    local x = 0
+    for i=0,#b do x = rol(bxor(x, (b[i] and i or 0)), 7) end
+    return x
+  end
+
+  local s = [[
+    local a, b = ...
+    local k = 0
+    for i=0,99 do
+      for j=0,99 do
+	b[k] = a[i] %s a[j]
+	k = k + 1
+      end
+    end
+  ]]
+
+  local ap = ffi.new("int64_t *", a)
+  local b = {}
+  for i=1,2 do
+    for _,cmp in ipairs{ "==", "~=", "<", "<=", ">", ">=" } do
+      local f = assert(loadstring(string.format(s, cmp), "operator"..cmp))
+      f(ap, b)
+      local r1 = cksum(b)
+      jit.off(f)
+      f(ap, b)
+      local r2 = cksum(b)
+      assert(r1 == r2)
+    end
+    ap = ffi.new("uint64_t *", a)
+  end
+end
+
+do
+  local a, b = ffi.new("char *"), ffi.new("char *")
+  local z
+  for i=1,100 do z = a-b end
+end
+
+do
+  local x = true
+  local abc = ffi.cast("const char *", "abc")
+  for i=1,100 do x = abc == "abc" end
+  assert(x == true)
+  for i=1,100 do x = abc == "xyz" end
+  assert(x == false)
+  for i=1,100 do x = 0LL == "" end
+  assert(x == false)
+  for i=1,100 do x = 0LL == false end
+  assert(x == false)
+  for i=1,100 do x = 0LL == nil end
+  assert(x == false)
+end
+
+-- ra_destpair
+do
+  local x, y = 0, 0
+  for i=1,100 do
+    x = x + i/3LL
+    y = y + i/5LL
+  end
+  assert(x == 1650)
+  assert(y == 970)
+end
+
diff --git a/test/LuaJIT-tests/lib/ffi/ffi_jit_call.lua b/test/LuaJIT-tests/lib/ffi/ffi_jit_call.lua
new file mode 100644
index 0000000..b79d60b
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/ffi_jit_call.lua
@@ -0,0 +1,154 @@
+
+local ffi = require("ffi")
+
+ffi.cdef[[
+int call_10i(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j);
+double call_10d(double a, double b, double c, double d, double e, double f, double g, double h, double i, double j);
+float call_10f(float a, float b, float c, float d, float e, float f, float g, float h, float i, float j);
+int64_t call_ij(int a, int64_t b);
+bool call_b(int a) asm("call_i");
+
+int64_t call_max(double,double,double,double,double,double,double,double,double,double,double,double,double,double,double,double,double) asm("call_10d");
+
+int64_t call_10j_p(int a, int b, int c, int d, int e, int f, int g, int h, int i, const char *p) asm("call_10j");
+
+int8_t call_i_i8(int a) asm("call_i");
+uint8_t call_i_u8(int a) asm("call_i");
+int16_t call_i_i16(int a) asm("call_i");
+uint16_t call_i_u16(int a) asm("call_i");
+int call_i8_i(int8_t a) asm("call_i");
+int call_u8_i(uint8_t a) asm("call_i");
+int call_i16_i(int16_t a) asm("call_i");
+int call_u16_i(uint16_t a) asm("call_i");
+
+int __fastcall fastcall_void(void);
+int __fastcall fastcall_i(int a);
+int __fastcall fastcall_ii(int a, int b);
+int __fastcall fastcall_iii(int a, int b, int c);
+int64_t __fastcall fastcall_ji(int64_t a, int b);
+double __fastcall fastcall_dd(double a, double b);
+int __fastcall fastcall_pp_i(int *a, int *b);
+
+int __stdcall stdcall_i(int a);
+int __stdcall stdcall_ii(int a, int b);
+double __stdcall stdcall_dd(double a, double b);
+float __stdcall stdcall_ff(float a, float b);
+]]
+
+local lib = ffi.load("../clib/ctest")
+
+do
+  local x
+  for i=1,100 do
+    x = lib.call_10i(-42, 17, 12345, 9987, -100, 11, 51, 0x12345678, 338, -78901234)
+  end
+  assert(x == -42+17+12345+9987-100+11+51+0x12345678+338-78901234)
+end
+
+do
+  for i=1,100 do
+    pcall(lib.call_max, i,i,i,i,i,i,i,i,i,i,i,i,i,i,i,i,i)
+  end
+end
+
+if ffi.abi("64bit") then
+  local y = ffi.cast("void *", 0x123456789abcdefLL)
+  local x
+  for i=1,100 do
+    lib.call_10j_p(0,0,0,0,0,0,0,0,0, y)
+    x = lib.call_10j_p(0,0,0,0,0,0,0,0,0, nil)
+  end
+  assert(x == 0)
+end
+
+do
+  local x = 0
+  for i=1,100 do
+    x = x + lib.call_ij(100+i, i*0x300000002LL)
+  end
+  assert(x == 0x3b2e0000623eLL)
+end
+
+do
+  local x
+  for i=1,100 do
+    x = lib.call_10d(-42.5, 17.125, 12345.5, 9987, -100.625, 11, 51, 0x12345678, 338, -78901234.75)
+  end
+  assert(x == -42.5+17.125+12345.5+9987-100.625+11+51+0x12345678+338-78901234.75)
+end
+
+do
+  local x
+  for i=1,100 do
+    x = lib.call_10f(-42.5, 17.125, 12345.5, 9987, -100.625, 11, 51, 0x123456, 338, -789012.75)
+  end
+  assert(x == -42.5+17.125+12345.5+9987-100.625+11+51+0x123456+338-789012.75)
+end
+
+do
+  local x
+  for i=-100,100 do
+    if not lib.call_b(i) then x = i end
+  end
+  assert(x == -1)
+  local t = {}
+  for i=1,100 do t[i] = -1 end
+  t[90] = 0
+  for i=1,100 do
+    if lib.call_b(t[i]) then x = i end
+  end
+  assert(x == 90)
+end
+
+do
+  local function tail(x)
+    return lib.call_b(x)
+  end
+  for i=1,100 do local a,b,c = tail(1), tail(1), tail(1) end
+end
+
+do
+  local x = 0
+  for i=0x01010080,0x010100ff do x = x + lib.call_i_i8(i) end
+  assert(x == -8128)
+  x = 0
+  for i=0x01010080,0x010100ff do x = x + lib.call_i_u8(i) end
+  assert(x == 24384)
+  x = 0
+  for i=0x0101ff80,0x0101ffff do x = x + lib.call_i_i16(i) end
+  assert(x == -8128)
+  x = 0
+  for i=0x0101ff80,0x0101ffff do x = x + lib.call_i_u16(i) end
+  assert(x == 8314944)
+  x = 0
+  for i=0x01010080,0x010100ff do x = x + lib.call_i8_i(i) end
+  assert(x == -8128)
+  x = 0
+  for i=0x01010080,0x010100ff do x = x + lib.call_u8_i(i) end
+  assert(x == 24640)
+  x = 0
+  for i=0x0101ff80,0x0101ffff do x = x + lib.call_i16_i(i) end
+  assert(x == -8128)
+  x = 0
+  for i=0x0101ff80,0x0101ffff do x = x + lib.call_u16_i(i) end
+  assert(x == 8380480)
+end
+
+-- target-specific
+if jit.arch == "x86" then
+  for i=1,100 do assert(lib.fastcall_i(-42) == -41) end
+  for i=1,100 do assert(lib.fastcall_ii(-42, 17) == -42+17) end
+  for i=1,100 do assert(lib.fastcall_iii(-42, 17, 139) == -42+17+139) end
+  for i=1,100 do assert(lib.fastcall_ji(0x123456789LL, -17) == 0x123456789LL-17) end
+  for i=1,100 do assert(lib.fastcall_dd(12.5, -3.25) == 12.5-3.25) end
+  local x = lib.fastcall_ji
+  for i=1,100 do assert(x(0x123456789LL, -17) == 0x123456789LL-17) end
+
+  if jit.os == "Windows" then
+    for i=1,100 do assert(lib.stdcall_i(-42) == -41) end
+    for i=1,100 do assert(lib.stdcall_ii(-42, 17) == -42+17) end
+    for i=1,100 do assert(lib.stdcall_dd(12.5, -3.25) == 12.5-3.25) end
+    for i=1,100 do assert(lib.stdcall_ff(12.5, -3.25) == 12.5-3.25) end
+  end
+end
+
diff --git a/test/LuaJIT-tests/lib/ffi/ffi_jit_conv.lua b/test/LuaJIT-tests/lib/ffi/ffi_jit_conv.lua
new file mode 100644
index 0000000..d4707db
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/ffi_jit_conv.lua
@@ -0,0 +1,277 @@
+local ffi = require("ffi")
+
+local ctest = require("ctest")
+
+do
+  local s = ffi.new("struct { int32_t x; }")
+  s.x = -0x12345678
+  for i=1,100 do
+    s.x = s.x + 1 -- narrowed
+  end
+  assert(s.x == -0x12345678+100)
+end
+
+do
+  local s = ffi.new("struct { uint32_t x; }")
+  s.x = 0x81234567
+  for i=1,100 do
+    s.x = s.x + 1 -- CONV.num.u32, CONV.u32.num (no narrowing yet)
+  end
+  assert(s.x == 0x81234567+100)
+end
+
+do
+  local s = ffi.new("struct { int8_t x; }")
+  s.x = 42
+  for i=1,100 do
+    s.x = s.x + 1
+    assert(s.x >= -128 and s.x <= 127) -- fwd -> CONV.int.i8
+  end
+  assert(s.x == 142-256)
+end
+
+do
+  local s = ffi.new("struct { uint8_t x; }")
+  s.x = 200
+  for i=1,100 do
+    s.x = s.x + 1
+    assert(s.x >= 0 and s.x <= 255) -- fwd -> CONV.int.u8
+  end
+  assert(s.x == 300-256)
+end
+
+do
+  local s = ffi.new("struct { int16_t x; }")
+  s.x = 32700
+  for i=1,100 do
+    s.x = s.x + 1
+    assert(s.x >= -32768 and s.x <= 32767) -- fwd -> CONV.int.i16
+  end
+  assert(s.x == 32800-65536)
+end
+
+do
+  local s = ffi.new("struct { uint16_t x; }")
+  s.x = 65450
+  for i=1,100 do
+    s.x = s.x + 1
+    assert(s.x >= 0 and s.x <= 65535) -- fwd -> CONV.int.u16
+  end
+  assert(s.x == 65550-65536)
+end
+
+do
+  local s = ffi.new("union { int32_t x; uint32_t y; }")
+  s.x = 0x7fffffff - 60
+  local x,y = 0,0
+  for i=1,100 do
+    if s.x == 0x7fffffff then s.x = -0x80000000 else s.x = s.x + 1 end
+    x = x + s.x -- fwd -> CONV.num.int
+    y = y + s.y -- fwd -> CONV.num.u32
+  end
+  assert(s.x == 0x7fffffff - 60 + 100 - 2^32)
+  assert(s.y == 0x7fffffff - 60 + 100)
+  assert(y == (0x7fffffff - 60) * 100 + 5050)
+  assert(x == y - 40*2^32)
+end
+
+do
+  local s = ffi.new("union { int32_t x; uint32_t y; }")
+  local x, z = 0, 2^31 + 42
+  for i=1,100 do
+    s.y = z
+    x = x + s.x -- fwd -> CONV.int.u32 (dummy)
+  end
+  assert(x == 100*(-2^31 + 42))
+end
+
+do
+  local s = ffi.new("union { int8_t x; uint8_t y; }")
+  s.x = 42
+  local x,y = 0,0
+  for i=1,100 do
+    s.x = s.x + 1
+    x = x + s.x -- fwd -> CONV.int.i8, CONV.num.int
+    y = y + s.y -- fwd -> CONV.int.u8, CONV.num.int
+  end
+  assert(s.x == 142 - 256)
+  assert(s.y == 142)
+  assert(y == 42 * 100 + 5050)
+  assert(x == y - (100-(127-42))*256)
+end
+
+do
+  local a = ffi.new("uint32_t[?]", 101)
+  for i=1,100 do a[i] = 0x80000000+i end
+  local x = 0
+  for i=1,100 do
+    x = bit.bxor(x, a[i]) -- FOLD TOBIT + CONV.num.u32
+  end
+  assert(x == 100)
+end
+
+do
+  local a = ffi.new("uint32_t[?]", 101)
+  for i=1,100 do a[i] = 0x80000000+i end
+  local x = 0
+  for i=1,100 do
+    x = bit.bxor(a[i], 0) -- FOLD TOBIT + CONV.num.u32
+  end
+  assert(x == -0x80000000+100)
+end
+
+do
+  local v = ffi.new("float", 12.5)
+  local x = 0
+  for i=1,100 do
+    x = x + tonumber(v) -- CONV.num.flt
+  end
+  assert(x == 100*12.5)
+end
+
+do
+  local v = ffi.new("uint32_t", 0x80000000)
+  local x = 0
+  for i=1,100 do
+    x = x + tonumber(v) -- CONV.num.u32
+  end
+  assert(x == 100*0x80000000)
+end
+
+do
+  local v = ffi.new("int64_t", 0x1234567800000000ll)
+  local x = 0
+  for i=1,100 do
+    x = x + tonumber(v) -- CONV.num.i64
+  end
+  assert(x == 100*0x12345678*2^32)
+end
+
+do
+  local v = ffi.new("uint64_t", 0x89abcdef00000000ull)
+  local x = 0
+  for i=1,100 do
+    x = x + tonumber(v) -- CONV.num.u64
+  end
+  assert(x == 100*0x89abcdef*2^32)
+end
+
+do
+  local a = ffi.new("int64_t[?]", 101)
+  for i=1,100 do a[i] = -i end
+  local x = 0
+  for i=1,100 do
+    x = x + tonumber(a[i]) -- CONV.num.i64
+  end
+  assert(x == -5050)
+end
+
+do
+  local a = ffi.new("uint64_t[?]", 101)
+  for i=1,100 do a[i] = 2^63+2^32*i end
+  local x = 0
+  for i=1,100 do
+    x = x + tonumber(a[i]) -- CONV.num.u64
+  end
+  assert(x == 2^63*100+2^32*5050)
+end
+
+do
+  local v = ffi.new("complex", 12.5, -3.25)
+  local x = 0
+  for i=1,100 do
+    x = x + tonumber(v)
+  end
+  assert(x == 100*12.5)
+end
+
+do
+  local s = ffi.new("struct { int64_t x;}")
+  for i=1,100 do
+    s.x = 0x123456789abcdef0LL
+  end
+  assert(tonumber(s.x) == tonumber(0x123456789abcdef0LL))
+end
+
+do
+  local s = ffi.new("struct { uint64_t x;}")
+  for i=1,100 do
+    s.x = 0x823456789abcdef0ULL
+  end
+  assert(tonumber(s.x) == tonumber(0x823456789abcdef0ULL))
+end
+
+do
+  ffi.cdef[[
+  typedef enum { AA, BB, CC = -42 } foo_i;
+  typedef enum { DD, EE, FF = 0x80000000u } foo_u;
+  ]]
+  local s = ffi.new("struct { foo_i x; foo_u y;}")
+  for i=1,100 do
+    s.x = "CC"
+    assert(s.x == -42)
+    s.x = "BB"
+    assert(s.x == 1)
+    s.y = "FF"
+    assert(s.y == 0x80000000)
+  end
+  local st = ffi.typeof(s)
+  for i=1,100 do s = st() end
+  assert(s.x == 0 and s.y == 0)
+  for i=1,100 do s = st("CC", "EE") end
+  assert(s.x == -42 and s.y == 1)
+  local ei = ffi.new("foo_i", "CC")
+  local eu = ffi.new("foo_u", "EE")
+  for i=1,100 do s = st(ei, eu) end
+  assert(s.x == -42 and s.y == 1)
+  local x
+  for i=1,100 do x = tonumber(ei) end
+  assert(x == -42)
+end
+
+do
+  local s = ffi.new("struct { const char *x; const char *y;}")
+  local a, tmp = "abcd", "ab"
+  for i=1,100 do
+    s.x = "abc"
+    s.y = string.sub(a, 1, 2)
+  end
+  assert(ffi.string(s.x) == "abc")
+  assert(ffi.string(s.y) == "ab")
+end
+
+do
+  local s = ffi.new("struct { bool b[200]; int i[200]; double d[200];}")
+  for i=0,199 do s.i[i] = i-100; s.d[i] = i-100 end
+  for i=0,99 do s.b[i] = 0 end
+  for i=100,199 do s.b[i] = 1 end
+  for i=0,99 do assert(s.b[i] == false) end
+  for i=100,199 do assert(s.b[i] == true) end
+  for i=0,199 do s.b[i] = s.i[i] end
+  for i=0,199 do assert(s.b[i] == (i ~= 100)) end
+  for i=0,199 do s.b[i] = s.d[i] end
+  for i=0,199 do assert(s.b[i] == (i ~= 100)) end
+end
+
+do
+  local a = ffi.new("int16_t[100]", 1)
+  for i=1,99 do a[i] = a[i] + a[i-1] end
+  assert(a[99] == 100)
+end
+
+do
+  local ud = ctest.lightud(12345678)
+  local s = ffi.new("struct { void *p; }")
+  for i=1,100 do
+    assert(ffi.cast("uintptr_t", ud) == 12345678)
+    s.p = ud
+  end
+  assert(ffi.cast("uintptr_t", s.p) == 12345678)
+end
+
+do
+  local x = ffi.new("struct { int & x;}", ffi.new("int[1]", 42))
+  local z
+  for i=1,100 do z = x.x end
+  assert(z == 42)
+end
diff --git a/test/LuaJIT-tests/lib/ffi/ffi_lex_number.lua b/test/LuaJIT-tests/lib/ffi/ffi_lex_number.lua
new file mode 100644
index 0000000..e26650e
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/ffi_lex_number.lua
@@ -0,0 +1,51 @@
+local ffi = require("ffi")
+
+dofile("../common/ffi_util.inc")
+
+local function checklex(t)
+  for i=1,1e9,2 do
+    local s = t[i+1]
+    if not s then break end
+    local s2 = assert(loadstring("return tostring("..s..")"))()
+    if s2 ~= t[i] then
+      print(s2)
+      error("lexer failed for '"..s.."'", 2)
+    end
+  end
+end
+
+checklex{
+  "0LL",			"0ll",
+  "0LL",			"0LL",
+  "0ULL",			"0ull",
+  "0ULL",			"0ULl",
+  "18446744073709551615ULL",	"18446744073709551615llu",
+  "9223372036854775807LL",	"0x7fffffffffffffffll",
+  "9223372036854775808ULL",	"0x8000000000000000ull",
+  "1311768467463790320LL",	"0x123456789abcdef0ll",
+  "-1LL",			"-1ll",
+  "18446744073709551615ULL",	"-1ull",
+  "-9223372036854775807LL",	"-0x7fffffffffffffffll",
+  "9223372036854775808ULL",	"-0x8000000000000000ull",
+  "0+0i",			"0i",
+  "0+0i",			"0I",
+  "0+12.5i",			"12.5i",
+  "0+4660i",			"0x1234i",
+  "0+infI",			"1e400i",
+  "0-infI",			"-1e400i",
+  "0-12.5i",			"-12.5i",
+  "0-0i",			"-0i",
+}
+
+checkfail({
+  "0l",
+  "0lll",
+  "0u",
+  "0ul",
+  "0ulll",
+  "0wll",
+  "0xll",
+  ".0ll",
+  "0ii",
+}, function(s) assert(loadstring("return "..s)) end)
+
diff --git a/test/LuaJIT-tests/lib/ffi/ffi_metatype.lua b/test/LuaJIT-tests/lib/ffi/ffi_metatype.lua
new file mode 100644
index 0000000..2db717f
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/ffi_metatype.lua
@@ -0,0 +1,245 @@
+local ffi = require("ffi")
+
+dofile("../common/ffi_util.inc")
+
+ffi.cdef[[
+typedef struct { int x; } idx1_t;
+typedef struct { int x; } idx2_t;
+typedef struct { int x; } idx3_t;
+typedef struct { int x,y; } arith_t;
+typedef struct { void *p; } gc_t;
+]]
+
+local function ptreq(a, b)
+  return ffi.cast("void *", a) == ffi.cast("void *", b)
+end
+
+do
+  local nidx = {}
+  local tp = ffi.metatype("idx1_t", {
+    __index = { foo = 99, method = function(c, v) return v end },
+    __newindex = nidx,
+  })
+
+  fails(function() ffi.metatype("idx1_t", {}) end)
+
+  local s = tp(1234)
+  assert(s.foo == 99)
+  assert(s.x == 1234)
+  -- bad field in __index metatable
+  fails(function(s) local x = s.bar end, s)
+  assert(s:method(123) == 123)
+  s.bar = 42
+  assert(nidx.bar == 42)
+
+  local cs = ffi.new("const idx1_t", 9876)
+  assert(cs.foo == 99)
+  assert(cs.x == 9876)
+  -- write to const struct
+  fails(function(cs) cs.bar = 42 end, cs)
+
+  local cp = ffi.new("const idx1_t *", cs)
+  assert(cp.foo == 99)
+  assert(cp.x == 9876)
+  -- write to const struct pointer
+  fails(function(cp) cp.bar = 42 end, cp)
+end
+
+do
+  local uc, uk, uv
+  local tp = ffi.metatype("idx2_t", {
+    __index = function(c, k, x, y)
+       assert(x == nil and y == nil)
+       uc, uk = c, k; return 99
+    end,
+    __newindex = function(c, k, v) uc, uk, uv = c, k, v end,
+  })
+
+  local s = tp(1234)
+  assert(s.foo == 99)
+  assert(ptreq(uc, s) and uk == "foo" and uv == nil); uc,uk,uv=nil,nil,nil
+  assert(s.x == 1234)
+  assert(uc == nil and uk == nil and uv == nil); uc,uk,uv=nil,nil,nil
+
+  s.bar = 42
+  assert(ptreq(uc, s) and uk == "bar" and uv == 42); uc,uk,uv=nil,nil,nil
+  s[10] = 11
+  assert(ptreq(uc, s) and uk == 10 and uv == 11); uc,uk,uv=nil,nil,nil
+
+  local p = ffi.new("idx2_t *", s)
+  assert(p.foo == 99)
+  assert(ptreq(uc, p) and uk == "foo" and uv == nil); uc,uk,uv=nil,nil,nil
+  assert(p.x == 1234)
+  assert(uc == nil and uk == nil and uv == nil); uc,uk,uv=nil,nil,nil
+  -- pointer dereference has precedence
+  assert(ptreq(p[0], p))
+  assert(uc == nil and uk == nil and uv == nil); uc,uk,uv=nil,nil,nil
+  -- pointer dereference has precedence
+  fails(function(p) p[0] = 11 end, p)
+end
+
+do
+  local uc, uk, uv
+  local ti, tn = {}, {}
+  local tp = ffi.metatype("idx3_t", {
+    __index = setmetatable(ti,
+      { __index = function(c, k) uc, uk = c, k; return 99 end }),
+    __newindex = setmetatable(tn,
+      { __newindex = function(c, k, v) uc, uk, uv = c, k, v end }),
+  })
+
+  local s = tp(1234)
+  assert(s.foo == 99)
+  assert(uc == ti and uk == "foo" and uv == nil)
+  uc, uk, uv = nil, nil, nil
+  assert(s.x == 1234)
+  assert(uc == nil and uk == nil and uv == nil)
+
+  s.bar = 42
+  assert(uc == tn and uk == "bar" and uv == 42)
+  uc, uk, uv = nil, nil, nil
+  s[10] = 11
+  assert(uc == tn and uk == 10 and uv == 11)
+  uc, uk, uv = nil, nil, nil
+end
+
+do
+  local tp
+  tp = ffi.metatype("arith_t", {
+    __add = function(a, b) return tp(a.x+b.x, a.y+b.y) end,
+    __sub = function(a, b) return tp(a.x-b.x, a.y-b.y) end,
+    __mul = function(a, z) return tp(a.x*z, a.y*z) end,
+    __div = function(z, a) return tp(a.x*z, a.y*z) end,
+    __concat = setmetatable({}, { __call = function(x) return 99 end }),
+    __len = function(x) return 2 end,
+    __call = function(a) return a.x+a.y end,
+    __tostring = function(a) return "foo" end,
+    __newindex = function(a, k, v) a.y = v end,
+    __index = {
+      diff = function(a) return a.x-a.y end,
+    },
+  })
+
+  local a = tp(10, 20)
+  local b = tp(1, 2)
+  local c = a + b
+  assert(c.x == 11 and c.y == 22)
+  assert(c:diff() == -11)
+  assert(c() == 33)
+  local d = a - b
+  assert(d.x == 9 and d.y == 18)
+  assert(d:diff() == -9)
+  assert(d() == 27)
+  local e = a * 3
+  assert(e.x == 30 and e.y == 60)
+  local f = 3LL / a
+  assert(f.x == 30 and f.y == 60)
+  assert(1 .. c == 99)
+  assert(c .. 1 == 99)
+  assert(c .. d == 99)
+  assert(tostring(c) == "foo")
+  assert(tostring(ffi.cast("arith_t *", c)) == "foo")
+  c.foo = 42
+  assert(c.y == 42)
+
+  local p = ffi.new("arith_t *", a)
+  local g1 = p + p
+  assert(g1.x == 20 and g1.y == 40)
+  local g2 = p[0] + p[0]
+  assert(g2.x == 20 and g2.y == 40)
+  assert(p() == 30)
+
+  local q = ffi.new("arith_t &", a)
+  fails(function(p) local y = q[0] + q[0] end, q)
+  local h = q + q
+  assert(h.x == 20 and h.y == 40)
+
+  local diff = 0
+  for i=1,100 do diff = a:diff() end
+  assert(diff == -10)
+
+  for i=1,100 do c.foo = i end
+  assert(c.y == 100)
+
+  local z = tp(1, 3)
+  for i=1,100 do z = z + a end
+  assert(z.x == 1001 and z.y == 2003)
+
+  local x = 0
+  for i=1,100 do x = x + #a end
+  assert(x == 200)
+
+  local x = 0
+  for i=1,100 do x = x + p() end
+  assert(x == 3000)
+end
+
+do
+  local count = 0
+  local tp = ffi.metatype("gc_t", {
+    __gc = function(x) count = count + 1 end,
+  })
+
+  local a = tp()
+  a = nil
+  collectgarbage()
+  assert(count == 1)
+  local b,c = tp(), tp()
+  b = nil
+  collectgarbage()
+  assert(count == 2)
+  c = nil
+  collectgarbage()
+  assert(count == 3)
+
+  local z
+  for i=1,100 do z = tp() end
+  z = nil
+  collectgarbage()
+  assert(count == 103)
+
+  local t = {}
+  for i=1,100 do t[i] = tp() end
+  for i=1,100 do ffi.gc(t[i], nil) end
+  t = nil
+  collectgarbage()
+  assert(count == 103)
+end
+
+do
+  local tp = ffi.metatype([[
+struct {
+  static const int Z42 = 42;
+  enum { Z39 = 39 };
+  int x;
+}]], {
+    __new = function(tp, x)
+      return ffi.new(tp, x or -1)
+    end,
+    __index = { test = function(x) return x+1 end, x = "hello" }
+  })
+  assert(tp.Z42 == 42)
+  assert(tp.Z39 == 39)
+  assert(tp.test(99) == 100)
+  fails(function() tp.Z42 = 1 end)
+  fails(function() tp.Z39 = 1 end)
+  assert(tp.x == "hello") -- Not sure this is a good idea to allow that.
+  fails(function() tp.x = 1 end)
+  local o = tp()
+  assert(o.Z42 == 42)
+  assert(o.Z39 == 39)
+  assert(o.test(55) == 56)
+  fails(function() o.Z42 = 1 end)
+  fails(function() o.Z39 = 1 end)
+  assert(o.x == -1)
+  o.x = 5
+  assert(o.x == 5)
+end
+
+do
+  local fb = ffi.new("struct { int x; }", 99)
+  local xt = ffi.metatype("struct { }", { __index = fb })
+  local o = xt()
+  assert(o.x == 99)
+end
+
diff --git a/test/LuaJIT-tests/lib/ffi/ffi_new.lua b/test/LuaJIT-tests/lib/ffi/ffi_new.lua
new file mode 100644
index 0000000..9cdbd53
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/ffi_new.lua
@@ -0,0 +1,106 @@
+local ffi = require("ffi")
+local bit = require("bit")
+
+dofile("../common/ffi_util.inc")
+
+ffi.cdef([[
+typedef struct { int a,b,c; } foo1_t;
+typedef int foo2_t[?];
+void *malloc(size_t size);
+void free(void *ptr);
+]])
+
+do
+  assert(ffi.sizeof("foo1_t") == 12)
+  local cd = ffi.new("foo1_t")
+  assert(ffi.sizeof(cd) == 12)
+  local foo1_t = ffi.typeof("foo1_t")
+  assert(ffi.sizeof(foo1_t) == 12)
+  cd = foo1_t()
+  assert(ffi.sizeof(cd) == 12)
+end
+
+do
+  assert(ffi.sizeof("foo2_t", 3) == 12)
+  local cd = ffi.new("foo2_t", 3)
+  assert(ffi.sizeof(cd) == 12)
+  local foo2_t = ffi.typeof("foo2_t")
+  fails(ffi.sizeof, foo2_t)
+  assert(ffi.sizeof(foo2_t, 3) == 12)
+  cd = foo2_t(3)
+  assert(ffi.sizeof(cd) == 12)
+end
+
+do
+  local tpi = ffi.typeof("int")
+  local tpb = ffi.typeof("uint8_t")
+  local t = {}
+  for i=1,200 do t[i] = tpi end
+  t[100] = tpb
+  local x = 0
+  for i=1,200 do x = x + tonumber(ffi.new(t[i], 257)) end
+  assert(x == 199*257 + 1)
+end
+
+do
+  local oc = collectgarbage("count")
+  for al=0,15 do
+    local align = 2^al -- 1, 2, 4, ..., 32768
+    local ct = ffi.typeof("struct { char __attribute__((aligned("..align.."))) a; }")
+    for i=1,100 do
+      local cd = ct()
+      local addr = tonumber(ffi.cast("intptr_t", ffi.cast("void *", cd)))
+      assert(bit.band(addr, align-1) == 0)
+    end
+  end
+  local nc = collectgarbage("count")
+  assert(nc < oc + 3000, "GC step missing for ffi.new")
+end
+
+do
+  local t = {}
+  for i=1,100 do t[i] = ffi.new("int[?]", i) end
+  assert(ffi.sizeof(t[100]) == 400)
+  for i=0,99 do assert(t[100][i] == 0) end
+end
+
+do
+  local t = {}
+  local ct = ffi.typeof("struct { double x; int y[?];}")
+  for i=1,100 do t[i] = ct(i) end
+  assert(ffi.sizeof(t[100]) == 408)
+  for i=0,99 do assert(t[100].y[i] == 0) end
+end
+
+do
+  local ct = ffi.typeof("struct __attribute__((aligned(16))) { int x; }")
+  local y
+  for i=1,200 do
+    local x = ct()
+    if i == 150 then y = x end
+  end
+  assert(bit.band(ffi.cast("intptr_t", ffi.cast("void *", y)), 15) == 0)
+end
+
+do
+  local q
+  local p = ffi.gc(ffi.new("int[1]"), function(x) q = x end)
+  p = nil
+  collectgarbage()
+  assert(type(q) == "cdata")
+  q = nil
+  collectgarbage()
+  assert(q == nil)
+end
+
+do
+  local p = ffi.gc(ffi.C.malloc(2^20), ffi.C.free)
+  p = nil
+  collectgarbage()
+end
+
+do
+  local p = ffi.gc(ffi.new("int[1]"), function(x) assert(type(x) == "cdata") end)
+  -- test for lua_close() cleanup.
+end
+
diff --git a/test/LuaJIT-tests/lib/ffi/ffi_parse_array.lua b/test/LuaJIT-tests/lib/ffi/ffi_parse_array.lua
new file mode 100644
index 0000000..3a9616d
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/ffi_parse_array.lua
@@ -0,0 +1,78 @@
+local ffi = require("ffi")
+
+dofile("../common/ffi_util.inc")
+
+checkfail{
+  "int [",
+  "int [-1]",
+  "int [[1]]",
+  "int [10][]",
+  "int [10][?]",
+  "int [][]",
+  "int [][?]",
+  "int [?][]",
+  "int [?][?]",
+  "int [0x10000][0x2000]",
+  "int [256][256][256][256]",
+  "int [10](void)",
+  "int (void)[10]",
+  "int &[10]",
+  "union { double x; int a[?]; }",
+}
+
+ffi.cdef([[
+  typedef int foo1_t[10];
+  typedef foo1_t foo2_t[5];
+]])
+assert(ffi.sizeof("foo1_t") == 40)
+assert(ffi.sizeof("foo2_t") == 200)
+
+local P = ffi.sizeof("void *")
+
+checktypes{
+  10,	1,	"char [10]",
+  4*10,	4,	"int [10]",
+  4*10,	4,	"int [10]",
+  4*10*5, 4,	"int [10][5]",
+  4*10*5*3*2*7, 4,	"int [10][5][3][2][7]",
+  4*10*5, 4,	"int ([10])[5]",
+  P*10,	P,	"int *[10]",
+  P,	P,	"int (*)[10]",
+  P*5,	P,	"int (*[5])[10]",
+  8*10,	4,	"struct { int x; char y; } [10]",
+  P*5*10, P,	"volatile int *(* const *[5][10])(void)",
+  nil,	4,	"int []",
+  4*10,	8,	"int __attribute__((aligned(8))) [10]",
+  4*10,	8,	"__attribute__((aligned(8))) int [10]",
+  4*10,	8,	"int [10] __attribute__((aligned(8)))",
+  97,	1,	"char ['a']",
+  83,	1,	"char ['\\123']",
+  79,	1,	"char ['\x4F']",
+  5,	1,	"char [sizeof(\"aa\" \"bb\")]",
+  80,	8,	"double [10]",
+}
+
+do
+  assert(ffi.sizeof("int [?]", 10) == 4*10)
+  local id = ffi.typeof("const short [?]")
+  assert(ffi.sizeof(id, 10) == 2*10)
+  assert(ffi.sizeof(id, 0) == 0*10)
+  fails(ffi.sizeof, id)
+  assert(ffi.sizeof(id, -1) == nil)
+  assert(ffi.sizeof(id, 0x80000000) == nil)
+  assert(ffi.sizeof(id, 0x40000000) == nil)
+  assert(ffi.sizeof(id, 0x3fffffff) == 2*0x3fffffff)
+end
+
+do
+  assert(ffi.sizeof("struct { double x; int a[?]; }", 10) == 8+4*10)
+  local id = ffi.typeof("struct { int x; short a[?]; }")
+  assert(ffi.sizeof(id, 10) == 4+2*10)
+  assert(ffi.sizeof(id, 0) == 4+0*10)
+  fails(ffi.sizeof, id)
+  assert(ffi.sizeof(id, -1) == nil)
+  assert(ffi.sizeof(id, 0x80000000) == nil)
+  assert(ffi.sizeof(id, 0x40000000) == nil)
+  assert(ffi.sizeof(id, 0x3ffffffd) == 4+2*0x3ffffffd)
+end
+
diff --git a/test/LuaJIT-tests/lib/ffi/ffi_parse_basic.lua b/test/LuaJIT-tests/lib/ffi/ffi_parse_basic.lua
new file mode 100644
index 0000000..c054bcf
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/ffi_parse_basic.lua
@@ -0,0 +1,131 @@
+local ffi = require("ffi")
+
+dofile("../common/ffi_util.inc")
+
+checkfail{
+  "",
+  " ",
+  "\n",
+  "1",
+  ".",
+  ";",
+  ",",
+  "*",
+  "[]",
+  "()",
+  "(*)",
+  "//",
+  "/*",
+  "xyz",
+  "const",
+  "volatile",
+  "typedef",
+  "extern",
+  "static",
+  "auto",
+  "register",
+  "struct",
+  "union",
+  "sizeof",
+  "int int",
+  "int char",
+  "int double",
+  "int;",
+}
+
+checktypes{
+  1,	1,	"char",
+  1,	1,	" \n\r\t\vchar \n\r\t\v",
+  1,	1,	"ch\\\nar",
+  1,	1,	"char /* abc */",
+  1,	1,	"char /* abc */ const",
+  1,	1,	"char // abc\n const",
+}
+
+checktypes{
+  nil,	1,	"void",
+  1,	1,	"bool",
+  1,	1,	"_Bool",
+  4,	4,	"_Bool int",
+  1,	1,	"char",
+  1,	1,	"signed char",
+  1,	1,	"unsigned char",
+  2,	2,	"short",
+  2,	2,	"signed short",
+  2,	2,	"unsigned short",
+  4,	4,	"int",
+  4,	4,	"signed int",
+  4,	4,	"unsigned int",
+  4,	4,	"signed",
+  4,	4,	"unsigned",
+  4,	4,	"float",
+  8,	8,	"long long",
+  8,	8,	"signed long long",
+  8,	8,	"unsigned long long",
+  8,	8,	"double",
+  -- NYI: long double is architecture- and compiler-specific.
+  8,	4,	"_Complex float",
+  16,	8,	"_Complex",
+  16,	8,	"_Complex double",
+}
+
+-- mode/vector_size attributes
+checktypes{
+  1,	1,	"int __attribute__((mode(QI)))",
+  2,	2,	"int __attribute__((mode(HI)))",
+  4,	4,	"int __attribute__((mode(SI)))",
+  8,	8,	"int __attribute__((mode(DI)))",
+  16,	16,	"int __attribute__((mode(TI)))",
+  32,	16,	"int __attribute__((mode(OI)))",
+  4,	4,	"float __attribute__((mode(SF)))",
+  8,	8,	"float __attribute__((mode(DF)))",
+  2,	2,	"int __attribute__((mode(V2QI)))",
+  16,	16,	"float __attribute__((mode(V4SF)))",
+  32,	16,	"double __attribute__((mode(V8SF)))",
+  8,	8,	"char __attribute__((vector_size(8)))",
+  16,	16,	"int __attribute__((vector_size(16)))",
+  32,	16,	"double __attribute__((vector_size(32)))",
+  64,	16,	"double __attribute__((vector_size(64)))",
+}
+
+-- ABI-specific types:
+local L = (ffi.abi("32bit") or ffi.abi("win")) and 4 or 8
+local P = ffi.abi("32bit") and 4 or 8
+local W = ffi.abi("win") and 2 or 4
+
+checktypes{
+  L,	L,	"long",
+  L,	L,	"signed long",
+  L,	L,	"unsigned long",
+  P,	P,	"int *",
+  P,	P,	"int **",
+  4,	4,	"int * __ptr32",
+}
+
+checktypes{
+  P,	P,	"ptrdiff_t",
+  P,	P,	"size_t",
+  W,	W,	"wchar_t",
+  1,	1,	"int8_t",
+  2,	2,	"int16_t",
+  4,	4,	"int32_t",
+  8,	8,	"int64_t",
+  1,	1,	"uint8_t",
+  2,	2,	"uint16_t",
+  4,	4,	"uint32_t",
+  8,	8,	"uint64_t",
+  P,	P,	"intptr_t",
+  P,	P,	"uintptr_t",
+}
+
+checktypes{
+  1,	8,	"char __attribute__((aligned(8)))",
+  1,	8,	"char __attribute((aligned(8)))",
+  1,	8,	"char __attribute__((__aligned__(8)))",
+  1,	8,	"__attribute__((aligned(8))) char",
+  1,	8,	"char __declspec(align(8))",
+  1,	8,	"__declspec(align(8)) char",
+  1,	2,	"char __attribute__((aligned(8))) const __attribute__((aligned(2)))",
+  1,	16,	"char __attribute__((aligned(8))) const __attribute__((aligned(16)))",
+}
+
diff --git a/test/LuaJIT-tests/lib/ffi/ffi_parse_cdef.lua b/test/LuaJIT-tests/lib/ffi/ffi_parse_cdef.lua
new file mode 100644
index 0000000..4bb5d90
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/ffi_parse_cdef.lua
@@ -0,0 +1,77 @@
+local ffi = require("ffi")
+
+dofile("../common/ffi_util.inc")
+
+checkfail({
+  "int",
+  "int aa1; int aa2 ",
+  "static int x;",
+  "static const long long x = 1;", -- NYI
+  "static const double x = 1;",	   -- NYI
+  "static const bool x = 1;",	   -- NYI (intentional, need true/false)
+  "struct { static int x = 1; };",
+  ";;static int y"
+}, ffi.cdef)
+
+ffi.cdef[[
+static const int K_42a = 42;
+static const char K_42b = 42+256;
+static const short K_M1a = 65535;
+static const unsigned short K_65535a = 65535;
+static const int K_1b = 0xffffffff >> 31;
+static const int K_1c = 0xffffffffu >> 31;
+static const int K_M1b = (int)0xffffffff >> 31;
+]]
+
+checktypes{
+  42,	1,	"char[K_42a]",
+  42,	1,	"char[K_42b]",
+  1,	1,	"char[-K_M1a]",
+  65535, 1,	"char[K_65535a]",
+  1,	1,	"char[K_1b]",
+  1,	1,	"char[K_1c]",
+  1,	1,	"char[-K_M1b]",
+}
+
+ffi.cdef[[
+struct str1 {
+  enum {
+    K_99 = 99
+  };
+  static const int K_55 = 55;
+} extk;
+]]
+
+checktypes{
+  99,	1,	"char[K_99]",
+  99,	1,	"char[extk.K_99]",
+  99,	1,	"char[((struct str1)0).K_99]",
+  99,	1,	"char[((struct str1 *)0)->K_99]",
+  55,	1,	"char[extk.K_55]",
+}
+
+checkfail{
+  "char[K_55]",
+}
+
+ffi.cdef[[
+extern int func1(void);
+extern int func2();
+static int func3();
+static inline int func4(int n)
+{
+  int i, k = 0;
+  float x = 1.0f;
+  for (i = 0; i < n; i++) {
+    k += i;
+  }
+  return k;
+}
+;;;
+]]
+
+ffi.cdef[[
+int ext1;
+extern int ext2;
+]]
+
diff --git a/test/LuaJIT-tests/lib/ffi/ffi_parse_struct.lua b/test/LuaJIT-tests/lib/ffi/ffi_parse_struct.lua
new file mode 100644
index 0000000..16a3d05
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/ffi_parse_struct.lua
@@ -0,0 +1,259 @@
+local ffi = require("ffi")
+
+dofile("../common/ffi_util.inc")
+
+checkfail{
+  "struct",
+  "struct {",
+  "struct xx xx {}",
+  "struct { int x  }",
+  "struct { int x,  }",
+  "struct { int x,y  }",
+  "struct { void x; }",
+  "struct { int x(void); }",
+  "struct recursive1 { struct recursive1 { } x; }",
+  "union",
+  "union {",
+  "union xx xx {}",
+  "union { int x  }",
+  "union { int x,  }",
+  "union { int x,y  }",
+  "union { void x; }",
+  "union { int x(void); }",
+  "union recursive1 { union recursive1 { } x; }",
+}
+
+-- NYI: rollback doesn't recover struct state
+-- ffi.cdef("struct zzz")
+-- fails(ffi.cdef, "struct zzz { int")
+-- ffi.cdef("struct zzz { int x; }")
+
+ffi.cdef("struct foo; typedef struct foo foo_t;")
+assert(ffi.sizeof("struct foo") == nil)
+assert(ffi.sizeof("foo_t") == nil)
+ffi.cdef("struct foo { int x,y; };")
+assert(ffi.sizeof("struct foo") == 8)
+assert(ffi.sizeof("foo_t") == 8)
+assert(ffi.sizeof(ffi.typeof("struct foo")) == 8)
+assert(ffi.sizeof(ffi.typeof("foo_t")) == 8)
+ffi.cdef("struct foo;")
+fails(ffi.cdef, "struct foo {};")
+fails(ffi.cdef, "union foo;")
+fails(ffi.cdef, "union foo {};")
+fails(ffi.cdef, "enum foo;")
+fails(ffi.cdef, "enum foo { ZZZ1 };")
+
+local P = ffi.sizeof("void *")
+local A = (ffi.arch == "x86" and not ffi.abi("win")) and 4 or 8
+
+checktypes{
+  0,	1,	"struct {}",
+  1,	1,	"struct { char x; }",
+  2,	1,	"struct { char x,y; }",
+  4,	1,	"struct { char x,y; char a,b; }",
+  4,	2,	"struct { char x; short y; }",
+  4,	2,	"struct { short x; char y; }",
+  8,	4,	"struct { char x; int y; }",
+  8,	4,	"struct { int x; char y; }",
+  12,	4,	"struct { char x; int y; char z; }",
+  P*4,	P,	"struct { char x,*y,**z,a,b,c,d; }",
+  64,	4,	"struct { struct { struct { struct { int x,y; } a,b; } a,b; } a,b; }",
+  4,	4,	"struct { struct { struct { struct { int x; }; }; }; }",
+  8,	4,	"struct { struct foo; }",
+  8,	4,	"struct { foo_t; }",
+  8,	8,	"struct __attribute__((aligned(sizeof(foo_t)))) { int a; }",
+  6,	2,	"struct { char a; char x; short y; char z; char c; }",
+  10,	2,	"struct { char a; struct { char x; short y; char z; } b; char c; }",
+  8,	A,	"struct { double a; }",
+  A+8,	A,	"struct { int a; double b; }",
+  8,	A,	"struct { long long a; }",
+  A+8,	A,	"struct { int a; long long b; }",
+  16,	A,	"struct { _Complex a; }",
+  A+16,	A,	"struct { int a; _Complex b; }",
+  8,	8,	"struct { float __attribute__((mode(__V2SF__))) a; }",
+  16,	8,	"struct { int a; float __attribute__((mode(__V2SF__))) b; }",
+  16,	8,	"struct { float __attribute__((mode(__V2SF__))) a[2]; }",
+  24,	8,	"struct { int a; float __attribute__((mode(__V2SF__))) b[2]; }",
+  16,	16,	"struct { float __attribute__((vector_size(16))) a; }",
+  32,	16,	"struct { int a; float __attribute__((vector_size(16))) b; }",
+}
+
+checktypes{
+  0,	1,	"union {}",
+  1,	1,	"union { char x; }",
+  1,	1,	"union { char x,y; }",
+  2,	2,	"union { char x; short y; }",
+  2,	2,	"union { short x; char y; }",
+  4,	4,	"union { char x; int y; }",
+  4,	4,	"union { int x; char y; }",
+  4,	4,	"union { char x; int y; short z; }",
+  P,	P,	"union { char x,*y,**z,a,b,c,d; }",
+  4,	4,	"union { union { union { union { int x,y; } a,b; } a,b; } a,b; }",
+  4,	4,	"union { union { union { union { int x; }; }; }; }",
+  2,	2,	"union { union { short x; }; char y; }",
+  2,	2,	"union { struct { short x; }; char y; }",
+  4,	2,	"struct { union { short x; }; char y; }",
+  2,	1,	"union { struct { char a,b; }; char y; }",
+  2,	1,	"struct { union { char a,b; }; char y; }",
+  8,	A,	"union { double a; }",
+  8,	A,	"union { int a; double b; }",
+  8,	A,	"union { long long a; }",
+  8,	A,	"union { int a; long long b; }",
+  16,	A,	"union { _Complex a; }",
+  16,	A,	"union { int a; _Complex b; }",
+  8,	8,	"union { float __attribute__((mode(__V2SF__))) a; }",
+  8,	8,	"union { int a; float __attribute__((mode(__V2SF__))) b; }",
+  16,	16,	"union { float __attribute__((vector_size(16))) a; }",
+  16,	16,	"union { int a; float __attribute__((vector_size(16))) b; }",
+}
+
+do
+  local ct
+  ct = ffi.typeof("struct { int a; char b; short c; int d; }")
+  assert(ffi.offsetof(ct, "a") == 0)
+  assert(ffi.offsetof(ct, "b") == 4)
+  assert(ffi.offsetof(ct, "c") == 6)
+  assert(ffi.offsetof(ct, "d") == 8)
+  ct = ffi.typeof("struct { char a; struct { char x; short y; char z; }; char c; }")
+  assert(ffi.offsetof(ct, "a") == 0)
+  assert(ffi.offsetof(ct, "x") == 2)
+  assert(ffi.offsetof(ct, "y") == 4)
+  assert(ffi.offsetof(ct, "z") == 6)
+  assert(ffi.offsetof(ct, "c") == 8)
+  ct = ffi.typeof("struct { char a; struct { short b; struct { int c; }; }; }")
+  assert(ffi.offsetof(ct, "a") == 0)
+  assert(ffi.offsetof(ct, "b") == 4)
+  assert(ffi.offsetof(ct, "c") == 8)
+  ct = ffi.typeof("struct { int a; double b; }")
+  assert(ffi.offsetof(ct, "a") == 0)
+  assert(ffi.offsetof(ct, "b") == A)
+end
+
+checkfail{
+  "struct { int :; }",
+  "struct { int a:; }",
+  "struct { int a:bad; }",
+  "struct { int a:0; }",
+  "struct { int a:33; }",
+  "struct { int a:-1; }",
+  "struct { _Bool a:2; }",
+  "struct { double a:2; }",
+  "struct { complex a:2; }",
+  "struct { int __attribute__((mode(__TI__))) a:2; }",
+  "struct { int __attribute__((vector_size(16))) a:2; }",
+  "struct { int a[2]:2; }",
+  "struct { void a:2; }",
+}
+
+checktypes{
+  4,	4,	"struct { unsigned a:1; }",
+  4,	4,	"struct { unsigned a:1, b:1, c:1; }",
+  1,	1,	"struct { _Bool a:1, b:1, c:1; }",
+  8,	4,	"struct { unsigned a:16, b:16, c:16; }",
+  8,	4,	"struct { unsigned a:17, b:16, c:16; }",
+  12,	4,	"struct { unsigned a:17, b:16, c:17; }",
+  12,	4,	"struct { unsigned a:16, b:17, c:16; }",
+  8,	4,	"struct { unsigned a:16, :16, c:16; }",
+  8,	4,	"struct { unsigned a:17, :16, c:16; }",
+  12,	4,	"struct { unsigned a:17, :16, c:17; }",
+  12,	4,	"struct { unsigned a:16, :17, c:16; }",
+  8,	4,	"struct { unsigned a:16, :0, c:16; }",
+  4,	4,	"struct { unsigned a:16, b:16, :0, :0; }",
+  8,	4,	"struct { unsigned a:16, :0, :0, :0, c:16; }",
+  1,	1,	"struct { char a:1; _Bool b:1; }",
+  1,	1,	"struct { char a:1; signed char b:1; unsigned char c:1; }",
+}
+
+-- NYI: bit fields > 32 bit
+-- local L = ffi.alignof("struct { long long a; }")
+-- checktypes{
+--   L,	L,	"struct { long long a:1; }",
+-- }
+
+-- Bit field packing.
+checktypes{
+  1,	1,	"struct { _Bool a:1, b:1, c:1; }",
+  4,	4,	"struct { short a:9; int b:9; char c; }",
+  4,	4,	"struct { char a; int b:7; }",
+  4,	4,	"struct { short a; char b; int c:7; }",
+  4,	4,	"struct { char a:7; int b:7; int c:7; int d:10; }",
+  4,	1,	"struct { char a:7; char b:7; char c:7; char d:7; }",
+  4,	4,	"struct { char a:7; int  b:7, c:7, d:7; int  e:4; }",
+  4,	4,	"struct { char a:7; int  b:7, c:7, d:7; char e:4; }",
+  5,	1,	"struct { char a:7; char b:7, c:7, d:7; char e:4; }",
+  4,	1,	"struct __attribute__((packed)) { char a:7; char b:7, c:7, d:7; char e:4; }",
+  4,	4,	"struct { char a:7; int b:7; int  c:7; int d:10; }",
+  8,	4,	"struct { char a:7; int b:7; char c:7; int d:10; }",
+  4,	1,	"struct __attribute__((packed)) { char a:7; int b:7; char c:7; int d:10; }",
+  4,	1,	"struct { char a:7; int b:7; char c:7; int d:10; } __attribute__((packed))",
+  2,	1,	"struct __attribute__((packed)) { char a:4; char b:8; }",
+  2,	1,	"struct __attribute__((packed)) { char a:4; char :0; char b:4; }",
+  1,	1,	"struct __attribute__((packed)) { _Bool a:1; _Bool b:1; }",
+  2,	1,	"struct __attribute__((packed)) { _Bool a:1; _Bool b:1 __attribute((aligned(1))); }",
+  4,	2,	"struct __attribute__((packed)) { _Bool a:1; _Bool b:1 __attribute((aligned(2))); }",
+  8,	4,	"struct { _Bool a:1; int b __attribute((aligned(2))); }",
+  16,	8,	"struct { _Bool a:1; int b __attribute((aligned(8))); }",
+  6,	2,	"struct { _Bool a:1; int b __attribute((aligned(2))) __attribute((packed)); }",
+  6,	2,	"struct __attribute__((packed)) { _Bool a:1; int b __attribute((aligned(2))); }",
+  6,	2,	"struct __attribute__((packed)) { _Bool a:1; int b __attribute((aligned(2))) __attribute((packed)); }",
+}
+
+do
+  ffi.cdef[[
+    struct foo_packorig { char a; int b; short c; };
+    #pragma pack(1)
+    struct foo_pack1 { char a; int b; short c; };
+    #pragma pack(2)
+    struct foo_pack2 { char a; int b; short c; };
+    #pragma pack(4)
+    struct foo_pack4 { char a; int b; short c; };
+    #pragma pack(8)
+    struct foo_pack8 { char a; int b; short c; };
+    #pragma pack()
+    struct foo_packdef { char a; int b; short c; };
+    #pragma pack(push)
+    struct foo_packpush { char a; int b; short c; };
+    #pragma pack(1)
+    struct foo_packpush1 { char a; int b; short c; };
+    #pragma pack(pop)
+    struct foo_packpop { char a; int b; short c; };
+    #pragma pack(push,2)
+    struct foo_packpush2 { char a; int b; short c; };
+    #pragma pack(pop)
+    struct foo_packpop2 { char a; int b; short c; };
+  ]]
+
+  assert(ffi.sizeof("struct foo_packorig") == 12)
+  assert(ffi.sizeof("struct foo_pack1") == 7)
+  assert(ffi.sizeof("struct foo_pack2") == 8)
+  assert(ffi.sizeof("struct foo_pack4") == 12)
+  assert(ffi.sizeof("struct foo_pack8") == 12)
+  assert(ffi.sizeof("struct foo_packdef") == 12)
+  assert(ffi.sizeof("struct foo_packpush") == 12)
+  assert(ffi.sizeof("struct foo_packpush1") == 7)
+  assert(ffi.sizeof("struct foo_packpop") == 12)
+  assert(ffi.sizeof("struct foo_packpush2") == 8)
+  assert(ffi.sizeof("struct foo_packpop2") == 12)
+end
+
+do
+  ffi.cdef[[
+    #pragma pack(2)
+    struct foo_packalign8 {
+      char a; int y __attribute((aligned(8)));
+    };
+    typedef int __attribute((aligned(8))) int_align8;
+    struct foo_packintalign8 {
+      char a; int_align8 y;
+    };
+    typedef int __attribute((aligned(1))) int_align1;
+    struct foo_packintalign1 {
+      char a; int_align1 y;
+    };
+  ]]
+
+  assert(ffi.sizeof("struct foo_packalign8") == 6)
+  assert(ffi.sizeof("struct foo_packintalign8") == 6)
+  assert(ffi.sizeof("struct foo_packintalign1") == 5)
+end
+
diff --git a/test/LuaJIT-tests/lib/ffi/ffi_tabov.lua b/test/LuaJIT-tests/lib/ffi/ffi_tabov.lua
new file mode 100644
index 0000000..ba62196
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/ffi_tabov.lua
@@ -0,0 +1,12 @@
+local ffi = require("ffi")
+
+local last = 0
+
+assert(pcall(function()
+  for i=1,65536 do
+    last = i
+    ffi.typeof"struct {}"
+  end
+end) == false)
+
+assert(last > 20000)
diff --git a/test/LuaJIT-tests/lib/ffi/index b/test/LuaJIT-tests/lib/ffi/index
new file mode 100644
index 0000000..59e36dd
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/index
@@ -0,0 +1,12 @@
+bit64.lua +luajit>=2.1
+cdata_var.lua
+copy_fill.lua
+err.lua
+istype.lua
+jit_array.lua
+jit_complex.lua
+jit_misc.lua
+jit_struct.lua
+meta_tostring.lua
+redir.lua
+type_punning.lua
diff --git a/test/LuaJIT-tests/lib/ffi/istype.lua b/test/LuaJIT-tests/lib/ffi/istype.lua
new file mode 100644
index 0000000..5aba775
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/istype.lua
@@ -0,0 +1,88 @@
+local ffi = require("ffi")
+
+do --- 1
+  local void_t = ffi.typeof("void")
+  assert(ffi.istype(void_t, void_t))
+  assert(ffi.istype("const void", void_t))
+
+  assert(ffi.istype("void", "void") == false) -- 2nd arg is a string.
+  assert(ffi.istype("double", 1.5) == false) -- 2nd arg is a number.
+end
+
+do --- 2
+  local i8_t = ffi.typeof("int8_t")
+  local u8_t = ffi.typeof("uint8_t")
+  local i32_t = ffi.typeof("int32_t")
+  assert(ffi.istype(i32_t, i32_t) == true)
+  assert(ffi.istype("const int32_t", i32_t) == true)
+
+  assert(ffi.istype("bool", u8_t) == false)
+  assert(ffi.istype(i8_t, u8_t) == false)
+  assert(ffi.istype(i32_t, u8_t) == false)
+  assert(ffi.istype(u8_t, i32_t) == false)
+  assert(ffi.istype("double", i32_t) == false)
+
+  assert(ffi.istype("int64_t", ffi.typeof("long long")))
+  assert(ffi.istype("long long", ffi.typeof("int64_t")))
+end
+
+do --- 3
+  local ptr_t = ffi.typeof("int *")
+  local p = ptr_t()
+  assert(ffi.istype(ptr_t, ptr_t) == true)
+  assert(ffi.istype(ptr_t, p) == true)
+  assert(ffi.istype(p, ptr_t) == true)
+  assert(ffi.istype("const int *", ptr_t) == true)
+  assert(ffi.istype("const int * const", ptr_t) == true)
+  assert(ffi.istype("unsigned int *", ptr_t) == true)
+
+  assert(ffi.istype("char *", ptr_t) == false)
+  assert(ffi.istype("void *", ptr_t) == false)
+end
+
+do --- 4
+  ffi.cdef[[
+typedef int istype_arr_t[10];
+typedef const istype_arr_t istype_carr_t;
+typedef struct { int x; } istype_struct_t;
+]]
+
+  local arr_t = ffi.typeof("istype_arr_t")
+  local carr_t = ffi.typeof("istype_carr_t")
+  assert(ffi.istype(arr_t, arr_t) == true)
+  assert(ffi.istype("int[10]", arr_t) == true)
+
+  assert(ffi.istype("int[11]", arr_t) == false)
+  assert(ffi.istype("int[]", arr_t) == false)
+  assert(ffi.istype("int *", arr_t) == false)
+
+  assert(ffi.istype("const int[10]", arr_t) == true)
+  assert(ffi.istype("volatile int[10]", arr_t) == true)
+  assert(ffi.istype(carr_t, arr_t) == true)
+
+  local struct_t = ffi.typeof("istype_struct_t")
+  local structp_t = ffi.typeof("istype_struct_t *")
+  assert(ffi.istype(struct_t, struct_t) == true)
+  assert(ffi.istype("const istype_struct_t", struct_t) == true)
+  assert(ffi.istype("struct { int x; }", struct_t) == false)
+  assert(ffi.istype(struct_t, structp_t) == true) -- struct ptr is ok for struct.
+  assert(ffi.istype(structp_t, struct_t) == false)
+end
+
+do --- 5
+  local int_t = ffi.typeof("int")
+  local t = {}
+  for i=1,200 do t[i] = int_t() end
+  t[100] = ffi.new("uint8_t")
+  local x = 0
+  for i=1,200 do if not ffi.istype("int", t[i]) then x = x + i end end
+  assert(x == 100)
+  x = 0
+  for i=1,200 do if not ffi.istype(int_t, t[i]) then x = x + i end end
+  assert(x == 100)
+  for i=1,200 do t[i] = int_t end
+  t[100] = ffi.typeof("uint8_t")
+  x = 0
+  for i=1,200 do if not ffi.istype(t[i], int_t) then x = x + i end end
+  assert(x == 100)
+end
diff --git a/test/LuaJIT-tests/lib/ffi/jit_array.lua b/test/LuaJIT-tests/lib/ffi/jit_array.lua
new file mode 100644
index 0000000..e8de4af
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/jit_array.lua
@@ -0,0 +1,104 @@
+local ffi = require("ffi")
+
+do --- smoke
+  local types = {
+    "int8_t", "uint8_t",
+    "int16_t", "uint16_t",
+    "int32_t", "uint32_t",
+    "int64_t", "uint64_t",
+    "float", "double",
+  }
+  for j,tp in ipairs(types) do
+    local t = ffi.new(tp.."[?]", 301)
+    for i=1,300 do t[i] = 1 end
+    for i=1,300 do assert(t[i] == 1) end
+    for i=1,300 do t[i] = t[i-1] end -- reassoc across PHIs, a[i-1] forwarding
+    for i=1,300 do assert(t[i] == 0) end
+    for i=1,300 do t[i] = i end
+    local x = 0
+    for i=1,300 do x = x + t[i] end
+    if tp == "int8_t" then assert(x == 862)
+    elseif tp == "uint8_t" then assert(x == 33630)
+    else assert(x == 45150) end
+  end
+end
+
+do --- int array pointer arithmetic
+  local a = ffi.new("int[?]", 101)
+  local p = a+1;
+  for i=1,100 do
+    p[0] = i
+    assert(p - a == i) -- pointer difference
+    p = p + 1 -- pointer increment by 4 bytes
+  end
+  for i=1,100 do assert(a[i] == i) end
+  for i=1,100 do assert((a+i)[0] == i) end -- pointer arithmetic
+  for i=1,100 do assert((i+a)[0] == i) end -- pointer arithmetic
+end
+
+do --- double array pointer arithmetic
+  local a = ffi.new("double[?]", 101)
+  local p = a+1;
+  for i=1,100 do
+    p[0] = i
+    p = p + 1 -- pointer increment by 8 bytes
+  end
+  for i=1,100 do assert(a[i] == i) end
+  for i=1,100 do assert((a+i)[0] == i) end -- pointer arithmetic
+end
+
+do --- double array pointer comparisons +bit
+  local a = ffi.new("double[?]", 201)
+  local p = a+3
+  for i=1,200 do local j = bit.band(i, 7); assert((a+j == p) == (j == 3)) end
+  p = a+100;
+  for i=1,200 do assert((a+i < p) == (i < 100)) end
+  for i=1,200 do assert((a+i <= p) == (i <= 100)) end
+end
+
+do --- constant offset in double array index
+  local a = ffi.new("double[?]", 100)
+  for i=1,100 do a[i-1LL] = i end
+  for i=1,100 do assert(a[100LL-i] == 101-i) end
+end
+
+do --- fixed index of minus one
+  local a = ffi.new("int[10]")
+  local p = a+1
+  local k = ffi.new("int", -1)
+  a[0] = 42
+  for i=1,100 do assert(p[-1] == 42); assert(p[k] == 42) end
+end
+
+do --- uint8_t array element comparisons
+  local a = ffi.new("uint8_t[?]", 256)
+  for i=0,255 do a[i] = i end
+  for i=1,255 do assert(a[i] >= 1) end
+  for i=0,254 do assert(a[i] <= 254) end
+end
+
+do --- int32_t array bit/bswap tricks +bit
+  local a = ffi.new("int32_t[?]", 256)
+  local tobit, bswap, shl = bit.tobit, bit.bswap, bit.lshift
+  for i=0,255 do a[i] = bswap(i+0x12345600) end
+  for i=0,255 do assert(a[i] == tobit(shl(i, 24)+0x00563412)) end
+  for i=0,255 do assert(bswap(a[i]) == tobit(i+0x12345600)) end
+end
+
+do --- int32_t shift/rotate/and +bit
+  local a = ffi.new("int32_t[?]", 256)
+  local shl, shr, rol, band = bit.lshift, bit.rshift, bit.rol, bit.band
+  for i=0,255 do a[i] = i + shl(i, 8) + shl(i, 16) end
+
+  for i=0,255 do assert(shl(band(a[i], 0xff), 8) == shl(i, 8)) end
+  for i=0,255 do assert(band(shl(a[i], 8), 0xff00) == shl(i, 8)) end
+
+  for i=0,255 do assert(shr(band(a[i], 0xff00), 8) == i) end
+  for i=0,255 do assert(band(shr(a[i], 8), 255) == i) end
+
+  for i=0,255 do assert(rol(band(a[i], 0xff), 8) == shl(i, 8)) end
+  for i=0,255 do assert(band(rol(a[i], 8), 0xff00) == shl(i, 8)) end
+
+  for i=0,255 do assert(shl(band(a[i], 0x000000ff), 24) == shl(i, 24)) end
+  for i=0,255 do assert(shr(band(a[i], 0xffff0000), 16) == i) end
+end
diff --git a/test/LuaJIT-tests/lib/ffi/jit_complex.lua b/test/LuaJIT-tests/lib/ffi/jit_complex.lua
new file mode 100644
index 0000000..3296f0c
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/jit_complex.lua
@@ -0,0 +1,109 @@
+local ffi = require("ffi")
+
+local cx = ffi.typeof("complex")
+local cxf = ffi.typeof("complex float")
+
+ffi.cdef[[
+typedef struct jit_complex_chain_t {
+  struct jit_complex_chain_t *next;
+  complex c;
+} jit_complex_chain_t;
+]]
+
+do --- field access
+  local c = cx(1, 2)
+  local x
+  for i=1,100 do
+    x = c.re + c.im
+  end
+  assert(x == 3)
+end
+
+do --- one element circular chain, named indexing
+  local cp = ffi.new("jit_complex_chain_t")
+  local p = cp
+  p.next = p
+  p.c = cx(1, 2)
+  local x,y = 0,0
+  for i=1,100 do
+    x = x + p.c.re
+    y = y + p.c.im
+    p = p.next
+  end
+  assert(x == 100)
+  assert(y == 200)
+end
+
+do --- one element circular chain, array indexing
+  local cp = ffi.new("jit_complex_chain_t")
+  local p = cp
+  p.next = p
+  p.c = cx(1, 2)
+  local x,y = 0,0
+  for i=1,100 do
+    x = x + p.c[0]
+    y = y + p.c[1]
+    p = p.next
+  end
+  assert(x == 100)
+  assert(y == 200)
+end
+
+do --- one-arg initialiser
+  local ca = ffi.new("complex[?]", 101)
+  for i=1,100 do
+    ca[i] = cx(i) -- handled as init single
+  end
+  local x,y = 0,0
+  for i=1,100 do
+    x = x + ca[i].re
+    y = y + ca[i].im
+  end
+  assert(x == 5050)
+  assert(y == 0)
+end
+
+do --- two-arg initialiser
+  local ca = ffi.new("complex[?]", 101)
+  for i=1,100 do
+    ca[i] = cx(i, -i)
+  end
+  local x,y = 0,0
+  for i=1,100 do
+    x = x + ca[i].re
+    y = y + ca[i].im
+  end
+  assert(x == 5050)
+  assert(y == -5050)
+end
+
+do --- float<>double conversions
+  local ca = ffi.new("complex[?]", 101)
+  local caf = ffi.new("complex float[?]", 101)
+  for i=1,100 do
+    ca[i] = cxf(i, -i)
+    caf[i] = cx(i, -i)
+  end
+  local x,y = 0,0
+  for i=1,100 do
+    x = x + caf[i].re + ca[i].re
+    y = y + caf[i].im + ca[i].im
+  end
+  assert(x == 2*5050)
+  assert(y == -2*5050)
+end
+
+do --- Complex struct field
+  local s = ffi.new("struct { complex x;}")
+  for i=1,100 do
+    s.x = 12.5i
+  end
+  assert(s.x.re == 0)
+  assert(s.x.im == 12.5)
+end
+
+do --- Index overflow for complex is ignored
+  local c = cx(1, 2)
+  local x
+  for i=1e7,1e7+100 do x = c[i] end
+end
diff --git a/test/LuaJIT-tests/lib/ffi/jit_misc.lua b/test/LuaJIT-tests/lib/ffi/jit_misc.lua
new file mode 100644
index 0000000..41e4737
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/jit_misc.lua
@@ -0,0 +1,109 @@
+local ffi = require("ffi")
+
+do --- errno
+  ffi.errno(42)
+  local x = 0
+  for i=1,100 do x = x + ffi.errno() end
+  assert(x == 4200)
+  ffi.errno(0)
+end
+
+do --- string
+  local a = ffi.new("uint8_t[?]", 101)
+  for i=0,99 do a[i] = i end
+  local s
+  for i=1,90 do s = ffi.string(a+i, 10) end
+  assert(s == "Z[\\]^_`abc")
+  for i=1,90 do s = ffi.string(a+i) end
+  assert(s == "Z[\\]^_`abc")
+end
+
+do --- fill
+  local a = ffi.new("uint8_t[?]", 100)
+  local x = 0
+  for i=0,90 do x = x + a[i]; ffi.fill(a+i, 10, i); x = x + a[i] end
+  assert(x == 8100)
+  for i=1,100 do ffi.fill(a, 15, 0x1234) end
+  assert(a[0] == 0x34 and a[14] == 0x34 and a[15] == 15)
+  local b = ffi.new("uint32_t[?]", 104)
+  for i=0,100 do ffi.fill(b+i, 15, 0x1234) end
+  assert(b[0] == 0x34343434)
+  assert(b[103] == (ffi.abi("le") and 0x343434 or 0x34343400))
+end
+
+do --- copy array elements
+  local a = ffi.new("uint8_t[?]", 100)
+  local b = ffi.new("uint8_t[?]", 100)
+  for i=0,99 do b[i] = i end
+  local x = 0
+  for i=0,90 do x = x + a[i]; ffi.copy(a+i, b+i, 1); x = x + a[i] end
+  assert(x == 4095)
+  local x = 0
+  for i=0,90 do ffi.copy(b+i, a+90-i, 10); x = x + b[i] end
+  assert(x == 4095)
+end
+
+do --- copy from string
+  local a = ffi.new("uint8_t[?]", 100, 42)
+  for i=0,90 do ffi.copy(a+i, "abc") end
+  local x = 0
+  for i=0,99 do x = x + a[i] end
+  assert(x == 9276)
+end
+
+do --- copy structures
+  local tp = ffi.typeof("struct { int x, y; }")
+  local a = tp(1, 2)
+  local b = tp(3, 4)
+  local x = 0
+  for i=1,100 do a.y = i; ffi.copy(b, a, 8); x = x + b.y end
+  assert(x == 5050)
+  local x = 0
+  for i=1,100 do a.y = i; local t = tp(a); x = x + t.y end
+  assert(x == 5050)
+end
+
+do --- init struct from first field, complex
+  local tp = ffi.typeof("struct { complex x, y; }")
+  local cx = ffi.typeof("complex")
+  local a = tp(cx(1, 2), cx(3, 4))
+  local x = 0
+  for i=1,100 do a.y = i; local t = tp(a); x = x + t.y.re end
+  assert(x == 5050)
+end
+
+do --- int array as parameterised type
+  local tp = ffi.typeof("int[10]")
+  local a = tp(42)
+  local b = ffi.new(ffi.typeof("struct { $ x; }", tp))
+  for i=1,100 do b.x = a end
+  assert(b.x[0] == 42 and b.x[9] == 42)
+end
+
+do --- double array as parameterised type
+  local tp = ffi.typeof("double[5]")
+  local a = tp(42)
+  local b = ffi.new(ffi.typeof("struct { $ x; }", tp))
+  for i=1,100 do b.x = a end
+  assert(b.x[0] == 42 and b.x[4] == 42)
+  b.x[0] = 0
+  for i=1,100 do ffi.copy(b.x, a, ffi.sizeof(a)) end
+  assert(b.x[0] == 42 and b.x[4] == 42)
+end
+
+do --- abi
+  local x, y
+  for i=1,100 do x = ffi.abi("32bit"); y = ffi.abi("64bit") end
+  assert(x == ffi.abi("32bit"))
+  assert(y == ffi.abi("64bit"))
+  for _,s in ipairs{"64bit", "32bit", "fpu", "softfp", "hardfp", "eabi", "win", "le", "be"} do
+    for i=1,100 do x = ffi.abi(s) end
+    assert(x == ffi.abi(s))
+  end
+end
+
+do --- typeof constructed typeof
+  local ct = ffi.typeof("struct { int x; }")
+  local cd = ct()
+  for i=1,100 do assert(ffi.typeof(cd) == ct) end
+end
diff --git a/test/LuaJIT-tests/lib/ffi/jit_struct.lua b/test/LuaJIT-tests/lib/ffi/jit_struct.lua
new file mode 100644
index 0000000..8aa64c1
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/jit_struct.lua
@@ -0,0 +1,201 @@
+local ffi = require("ffi")
+
+ffi.cdef[[
+typedef struct { int a, b, c; } jit_struct_foo_t;
+typedef struct { int a, b, c; } jit_struct_foo2_t;
+typedef struct { int a[10]; int b[10]; } jit_struct_sarr_t;
+typedef struct jit_struct_chain_t {
+  struct jit_struct_chain_t *next;
+  int v;
+} jit_struct_chain_t;
+]]
+
+do --- iteration variable as field name
+  local s = ffi.new("jit_struct_foo_t")
+  for j,k in ipairs{ "a", "b", "c" } do
+    for i=1,100 do s[k] = s[k] + j end
+  end
+  assert(s.a == 100)
+  assert(s.b == 200)
+  assert(s.c == 300)
+end
+
+do --- constant field names
+  local s = ffi.new("jit_struct_foo_t")
+  for i=1,100 do
+    s.a = s.a + 1
+    s.b = s.b + 2
+    s.c = s.c + 3
+  end
+  assert(s.a == 100)
+  assert(s.b == 200)
+  assert(s.c == 300)
+end
+
+do --- constants from structure
+  local s = ffi.new("jit_struct_foo_t")
+  local s2 = ffi.new("jit_struct_foo2_t", 1, 2, 3)
+  for i=1,100 do
+    s.a = s.a + s2.a
+    s.b = s.b + s2.b
+    s.c = s.c + s2.c
+  end
+  assert(s.a == 100)
+  assert(s.b == 200)
+  assert(s.c == 300)
+end
+
+do --- adding to array elements
+  local s = ffi.new("jit_struct_sarr_t")
+  for i=1,100 do
+    s.a[5] = s.a[5] + 1
+    s.b[5] = s.b[5] + 2
+  end
+  assert(s.a[5] == 100)
+  assert(s.b[5] == 200)
+end
+
+do --- double indexing
+  local s = ffi.new([[
+	struct {
+	  struct {
+	    int x;
+	    int b[10];
+	  } a[100];
+	}]])
+  s.a[10].b[4] = 10
+  s.a[95].b[4] = 95
+  local x = 0
+  for i=1,100 do
+    x = x + s.a[i-1].b[4] -- reassociate offsets for base and index
+  end
+  assert(x == 105)
+end
+
+do --- structurally identical
+  local s1 = ffi.new("struct { int a; }")
+  local s2 = ffi.new("struct { int a; }")
+  local x = 0
+  for j=1,2 do
+    for i=1,100 do
+      s2.a = i
+      s1.a = 1
+      x = x + s2.a -- cannot forward across aliasing store
+    end
+    if j == 1 then
+      assert(x == 5050)
+      s2 = s1
+      x = 0
+    else
+      assert(x == 100)
+    end
+  end
+end
+
+do --- structurally different
+  local s1 = ffi.new("struct { int a; }")
+  local s2 = ffi.new("struct { char a; }")
+  local x = 0
+  for j=1,2 do
+    for i=1,100 do
+      s2.a = i
+      s1.a = 1
+      x = x + s2.a -- can forward across aliasing store
+    end
+    if j == 1 then
+      assert(x == 5050)
+      s2 = s1 -- this will cause a side trace
+      x = 0
+    else
+      assert(x == 100)
+    end
+  end
+end
+
+do --- union
+  local s = ffi.new("union { uint8_t a; int8_t b; }")
+  local x = 0
+  for i=1,200 do
+    s.a = i
+    x = x + s.b -- same offset, but must not alias (except if sign-extended)
+  end
+  assert(x == 1412)
+end
+
+do --- circular chain
+  local s1 = ffi.new("jit_struct_chain_t")
+  local s2 = ffi.new("jit_struct_chain_t")
+  local s3 = ffi.new("jit_struct_chain_t")
+  s1.next = s2
+  s2.next = s3
+  s3.next = s1
+  local p = s1
+  for i=1,99 do
+    p.v = i
+    p = p.next
+  end
+  assert(s1.v == 97)
+  assert(s2.v == 98)
+  assert(s3.v == 99)
+end
+
+do --- int struct initialiser
+  local ct = ffi.typeof("struct { int a,b,c; }")
+  local x,y,z = 0,0,0
+  for i=1,100 do
+    local s = ct(i, i+1)
+    x = x + s.a
+    y = y + s.b
+    z = z + s.c
+  end
+  assert(x == 5050)
+  assert(y == 5150)
+  assert(z == 0)
+end
+
+do --- double struct initialiser
+  local ct = ffi.typeof("struct { double a,b,c; }")
+  local x,y,z = 0,0,0
+  for i=1,100 do
+    local s = ct(i, i+1)
+    x = x + s.a
+    y = y + s.b
+    z = z + s.c
+  end
+  assert(x == 5050)
+  assert(y == 5150)
+  assert(z == 0)
+end
+
+do --- pointer / int struct initialiser
+  local s1 = ffi.new("jit_struct_chain_t")
+  local s
+  for i=1,100 do
+    s = ffi.new("jit_struct_chain_t", s1, i)
+  end
+  assert(tonumber(ffi.cast("int", s.next)) ==
+	 tonumber(ffi.cast("int", ffi.cast("jit_struct_chain_t *", s1))))
+  assert(s.v == 100)
+end
+
+do --- unstable pointer/int type struct initialiser
+  local ct = ffi.typeof("struct { int *p; int y; }")
+  local s
+  for i=1,200 do
+    if i == 100 then ct = ffi.typeof("jit_struct_chain_t") end
+    s = ct(nil, 10)
+  end
+  assert(s.v == 10)
+end
+
+do --- upvalued int box
+  local s = ffi.new("struct { int x; }", 42)
+  local function f()
+    for i=1,100 do
+      s.x = i
+      assert(s.x == i)
+    end
+  end
+  f()
+end
+
diff --git a/test/LuaJIT-tests/lib/ffi/meta_tostring.lua b/test/LuaJIT-tests/lib/ffi/meta_tostring.lua
new file mode 100644
index 0000000..bb065e1
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/meta_tostring.lua
@@ -0,0 +1,55 @@
+local ffi = require("ffi")
+
+ffi.cdef[[
+typedef union meta_tostring_foo_t {
+  int64_t i64;
+  uint64_t u64;
+  complex cd;
+  double d[2];
+  complex float cf;
+  float f[2];
+} meta_tostring_foo_t;
+]]
+
+do --- tostring/typeof semi-roundtrip
+  assert(tostring(ffi.typeof("int (*(*[1][2])[3][4])[5][6]")) ==
+   "ctype<int (*(*[1][2])[3][4])[5][6]>")
+  assert(tostring(ffi.typeof("int (*const)(void)")) ==
+   "ctype<int (*const)()>")
+  assert(tostring(ffi.typeof("complex float(*(void))[2]")) ==
+   "ctype<complex float (*())[2]>")
+  assert(tostring(ffi.typeof("complex*")) == "ctype<complex *>")
+end
+
+do --- assorted union fields
+  local foo_t = ffi.typeof("meta_tostring_foo_t")
+  local x = foo_t()
+
+  assert(tostring(foo_t) == "ctype<union meta_tostring_foo_t>")
+  assert(string.find(tostring(x), "^cdata<union meta_tostring_foo_t>: "))
+
+  x.i64 = -1;
+  assert(tostring(x.i64) == "-1LL")
+  assert(tostring(x.u64) == "18446744073709551615ULL")
+
+  x.d[0] = 12.5
+  x.d[1] = -753.125
+  assert(tostring(x.cd) == "12.5-753.125i")
+  x.d[0] = -12.5
+  x.d[1] = 753.125
+  assert(tostring(x.cd) == "-12.5+753.125i")
+  x.d[0] = 0/-1
+  x.d[1] = 0/-1
+  assert(tostring(x.cd) == "-0-0i")
+  x.d[0] = 1/0
+  x.d[1] = -1/0
+  assert(tostring(x.cd) == "inf-infI")
+  x.d[0] = -1/0
+  x.d[1] = 0/0
+  assert(tostring(x.cd) == "-inf+nanI")
+
+  x.f[0] = 12.5
+  x.f[1] = -753.125
+  assert(tostring(x.cf) == "12.5-753.125i")
+end
+
diff --git a/test/LuaJIT-tests/lib/ffi/redir.lua b/test/LuaJIT-tests/lib/ffi/redir.lua
new file mode 100644
index 0000000..c492055
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/redir.lua
@@ -0,0 +1,19 @@
+local ffi = require("ffi")
+
+do --- function
+  ffi.cdef[[
+  int redir_foo(const char *s) asm("strlen");
+  ]]
+
+  assert(ffi.C.redir_foo("abcd") == 4)
+end
+
+do --- variable -windows
+  ffi.cdef[[
+  int redir_bar asm("errno");
+  ]]
+
+  ffi.C.redir_bar = 14
+  assert(ffi.C.redir_bar == 14)
+  ffi.C.redir_bar = 0
+end
diff --git a/test/LuaJIT-tests/lib/ffi/type_punning.lua b/test/LuaJIT-tests/lib/ffi/type_punning.lua
new file mode 100644
index 0000000..ac70b4b
--- /dev/null
+++ b/test/LuaJIT-tests/lib/ffi/type_punning.lua
@@ -0,0 +1,138 @@
+local ffi = require("ffi")
+
+local u = ffi.new([[
+union {
+  int8_t i8[8];
+  uint8_t u8[8];
+  int16_t i16[4];
+  uint16_t u16[4];
+  int32_t i32[2];
+  uint32_t u32[2];
+  int64_t i64[1];
+  uint64_t u64[1];
+  void *v[2];
+  float f[2];
+  double d[1];
+}
+]])
+
+do --- float -> u32 type punning at same offset
+  local x = 0LL
+  for i=1,100 do
+    u.f[0] = i
+    x = x + u.u32[0]
+  end
+  assert(x == 110888222720LL)
+end
+
+do --- double -> u64 type punning at same offset
+  local x = 0LL
+  for i=1,100 do
+    u.d[0] = i
+    x = x + u.u64[0]
+  end
+  assert(x == 1886586031403171840ULL)
+end
+
+do --- i8 -> u8 type punning at same offset (fwd -> CONV.int.u8)
+  local x = 0
+  for i=-100,100 do
+    u.i8[0] = i
+    x = x + u.u8[0]
+  end
+  assert(x == 25600)
+end
+
+do --- p32/p64 -> u64 type punning at same offset (32 bit: different size)
+  local x = 0LL
+  u.u64[0] = 0
+  for i=-100,150 do
+    u.v[0] = ffi.cast("void *", ffi.cast("ptrdiff_t", i))
+    x = x + u.u64[0]
+  end
+  assert(x == (ffi.abi"64bit" and 6275ULL or
+	       (ffi.abi"le" and 0x6400001883ULL or 0x188300000000ULL)))
+end
+
+do --- u16 -> u8 type punning at overlapping offsets [0]
+  local x = 0
+  for i=255,520 do
+    u.u16[0] = i
+    x = x + u.u8[0]
+  end
+  assert(x == (ffi.abi"be" and 274 or 32931))
+end
+
+do --- u16 -> u8 type punning at overlapping offsets [1]
+  local x = 0
+  for i=255,520 do
+    u.u16[0] = i
+    x = x + u.u8[1]
+  end
+  assert(x == (ffi.abi"le" and 274 or 32931))
+end
+
+do --- i16 -> i32 type punning at overlapping offsets [0]
+  local x = 0
+  u.i32[0] = 0
+  for i=-100,150 do
+    u.i16[0] = i
+    x = x + u.i32[0]
+  end
+  assert(x == (ffi.abi"be" and 411238400 or 6559875))
+end
+
+do --- i16 -> i32 type punning at overlapping offsets [1]
+  local x = 0
+  u.i32[0] = 0
+  for i=-100,150 do
+    u.i16[1] = i
+    x = x + u.i32[0]
+  end
+  assert(x == (ffi.abi"le" and 411238400 or 6559875))
+end
+
+do --- double -> i32 type punning at overlapping offsets [0]
+  local x = 0
+  for i=1.5,120,1.1 do
+    u.d[0] = i
+    x = x + u.i32[0]
+  end
+  assert(x == (ffi.abi"be" and 116468870297 or -858993573))
+end
+
+do --- double -> i32 type punning at overlapping offsets [1]
+  local x = 0
+  for i=1.5,120,1.1 do
+    u.d[0] = i
+    x = x + u.i32[1]
+  end
+  assert(x == (ffi.abi"le" and 116468870297 or -858993573))
+end
+
+do --- u32 -> u64 type punning, constify u, 32 bit SPLIT: fold KPTR
+  local u = ffi.new("union { struct { uint32_t lo, hi; }; uint64_t u64; }")
+
+  local function conv(lo, hi)
+    u.lo = lo
+    u.hi = hi
+    return u.u64
+  end
+
+  local x = 0ll
+  for i=1,100 do
+    x = x + conv(i, i)
+  end
+  assert(x == 21689584849850ULL)
+end
+
+do --- u64 -> u32 -> u64 type punning with KPTR
+  local s = ffi.new("union { int64_t q; int32_t i[2]; }")
+  local function f()
+    s.q = 0
+    s.i[1] = 1
+    return s.q
+  end
+  for i=1,50 do f() f() f() end
+  assert(f() ~= 0)
+end
diff --git a/test/LuaJIT-tests/lib/index b/test/LuaJIT-tests/lib/index
new file mode 100644
index 0000000..cc9d7d7
--- /dev/null
+++ b/test/LuaJIT-tests/lib/index
@@ -0,0 +1,8 @@
+base
+bit.lua +bit
+math
+string
+table
+coroutine
+ffi +ffi
+contents.lua
\ No newline at end of file
diff --git a/test/LuaJIT-tests/lib/math/abs.lua b/test/LuaJIT-tests/lib/math/abs.lua
new file mode 100644
index 0000000..4223a78
--- /dev/null
+++ b/test/LuaJIT-tests/lib/math/abs.lua
@@ -0,0 +1,16 @@
+local abs = math.abs
+local expect_error = require"common.expect_error"
+
+do --- smoke
+  assert(abs(-1.5) == 1.5)
+  assert(abs("-1.5") == 1.5)
+end
+
+do --- argcheck
+  expect_error(function() abs() end,
+      "bad argument #1 to 'abs' (number expected, got no value)")
+  expect_error(function() abs(false) end,
+      "bad argument #1 to 'abs' (number expected, got boolean)")
+  expect_error(function() abs("a") end,
+      "bad argument #1 to 'abs' (number expected, got string)")
+end
diff --git a/test/LuaJIT-tests/lib/math/constants.lua b/test/LuaJIT-tests/lib/math/constants.lua
new file mode 100644
index 0000000..ec35b4c
--- /dev/null
+++ b/test/LuaJIT-tests/lib/math/constants.lua
@@ -0,0 +1,8 @@
+do --- pi
+  assert(math.pi == 3.141592653589793)
+end
+
+do --- huge
+  assert(math.huge > 0)
+  assert(1/math.huge == 0)
+end
diff --git a/test/LuaJIT-tests/lib/math/index b/test/LuaJIT-tests/lib/math/index
new file mode 100644
index 0000000..944e1ae
--- /dev/null
+++ b/test/LuaJIT-tests/lib/math/index
@@ -0,0 +1,3 @@
+abs.lua
+constants.lua
+random.lua
diff --git a/test/LuaJIT-tests/lib/math/random.lua b/test/LuaJIT-tests/lib/math/random.lua
new file mode 100644
index 0000000..dc2ca00
--- /dev/null
+++ b/test/LuaJIT-tests/lib/math/random.lua
@@ -0,0 +1,47 @@
+local random = math.random
+local MAX_SEED = 10
+
+do --- generally uniform in range [0, 1)
+  local N = 100
+  local min, max = math.min, math.max
+  for j=1,MAX_SEED do
+    math.randomseed(j)
+    local lo, hi, sum = math.huge, -math.huge, 0
+    for i=1,N do
+      local x = random()
+      assert(0 <= x and x < 1)
+      sum = sum + x
+      lo = min(lo, x)
+      hi = max(hi, x)
+    end
+    assert(lo*N < 15 and (1-hi)*N < 15)
+    assert(sum > N*0.45 and sum < N*0.55)
+  end
+end
+
+do --- all in range [1, 10]
+  math.randomseed(1)
+  local counts = setmetatable({}, {__index = function() return 0 end})
+  for i = 1, 100 do
+    local n = random(10)
+    counts[n] = counts[n] + 1
+  end
+  for i = 1, 10 do
+    assert(counts[i])
+    counts[i] = nil
+  end
+  assert(not next(counts))
+end
+
+do --- all in range [-3, 11]
+  math.randomseed(1)
+  local seen = setmetatable({}, {__index = function() return false end})
+  for i = 1, 120 do
+    seen[random(-3, 11)] = true
+  end
+  for i = -3, 11 do
+    assert(seen[i])
+    seen[i] = nil
+  end
+  assert(not next(seen))
+end
diff --git a/test/LuaJIT-tests/lib/string/byte.lua b/test/LuaJIT-tests/lib/string/byte.lua
new file mode 100644
index 0000000..697a2c2
--- /dev/null
+++ b/test/LuaJIT-tests/lib/string/byte.lua
@@ -0,0 +1,92 @@
+local band, bor = bit and bit.band, bit and bit.bor
+local byte = string.byte
+
+do --- simple
+  local a, b = ("foo"):byte(1)
+  assert(type(a) == "number")
+  assert(b == nil)
+  local c, d = ("foo"):byte(2, 3)
+  assert(type(c) == "number")
+  assert(c == d)
+  assert(c ~= a)
+end
+
+do --- Fixed slice [i,i+k] or overflow +bit
+  local s = "abcdefg"
+  local x,y,z
+  for j=100,107 do
+    for i=1,j do x,y,z = byte("abcdefg", band(i, 7), band(i+2, 7)) end
+    local a,b,c = byte("abcdefg", band(j, 7), band(j+2, 7))
+    assert(x == a and y == b and z == c)
+  end
+  for j=100,107 do
+    for i=1,j do x,y,z = byte(s, band(i, 7), band(i+2, 7)) end
+    local a,b,c = byte(s, band(j, 7), band(j+2, 7))
+    assert(x == a and y == b and z == c)
+  end
+end
+
+do --- Positive slice [i,len] or overflow +bit
+  local s = "abc"
+  local x,y,z
+  for j=100,107 do
+    for i=1,j do x,y,z = byte("abc", band(i, 7), -1) end
+    local a,b,c = byte("abc", band(j, 7), -1)
+    assert(x == a and y == b and z == c)
+  end
+  for j=100,107 do
+    for i=1,j do x,y,z = byte(s, band(i, 7), -1) end
+    local a,b,c = byte(s, band(j, 7), -1)
+    assert(x == a and y == b and z == c)
+  end
+end
+
+do --- Negative slice [-i,len] or underflow +bit
+  local s = "abc"
+  local x,y,z
+  for j=-100,-107,-1 do
+    for i=-1,j,-1 do x,y,z = byte("abc", bor(i, -8), -1) end
+    local a,b,c = byte("abc", bor(j, -8), -1)
+    assert(x == a and y == b and z == c)
+  end
+  for j=-100,-107,-1 do
+    for i=-1,j,-1 do x,y,z = byte(s, bor(i, -8), -1) end
+    local a,b,c = byte(s, bor(j, -8), -1)
+    assert(x == a and y == b and z == c)
+  end
+end
+
+do --- Positive slice [1,i] or overflow +bit
+  local s = "abc"
+  local x,y,z
+  for j=100,107 do
+    for i=1,j do x,y,z = byte("abc", 1, band(i, 7)) end
+    local a,b,c = byte("abc", 1, band(j, 7))
+    assert(x == a and y == b and z == c)
+  end
+  for j=100,107 do
+    for i=1,j do x,y,z = byte(s, 1, band(i, 7)) end
+    local a,b,c = byte(s, 1, band(j, 7))
+    assert(x == a and y == b and z == c)
+  end
+end
+
+do --- Negative slice [1,-i] or underflow +bit
+  local s = "abc"
+  local x,y,z
+  for j=-100,-107,-1 do
+    for i=-1,j,-1 do x,y,z = byte("abc", 1, bor(i, -8)) end
+    local a,b,c = byte("abc", 1, bor(j, -8))
+    assert(x == a and y == b and z == c)
+  end
+  for j=-100,-107,-1 do
+    for i=-1,j,-1 do x,y,z = byte(s, 1, bor(i, -8)) end
+    local a,b,c = byte(s, 1, bor(j, -8))
+    assert(x == a and y == b and z == c)
+  end
+end
+
+do --- Check for slot stack overflow
+  local s = string.rep("x", 500)
+  for i=1,100 do byte(s, 1, 500) end
+end
diff --git a/test/LuaJIT-tests/lib/string/char.lua b/test/LuaJIT-tests/lib/string/char.lua
new file mode 100644
index 0000000..544767d
--- /dev/null
+++ b/test/LuaJIT-tests/lib/string/char.lua
@@ -0,0 +1,29 @@
+local char = string.char
+
+do --- jit one char
+  local y
+  for i=1,100 do y = char(65) end
+  assert(y == "A")
+  local x = 97
+  for i=1,100 do y = char(x) end
+  assert(y == "a")
+  x = "98"
+  for i=1,100 do y = char(x) end
+  assert(y == "b")
+  for i=1,100 do y = char(32+i) end
+  assert(y == "\132")
+end
+
+do --- jit until out of bounds
+  local y
+  assert(not pcall(function()
+    for i=1,200 do y = char(100+i) end
+  end))
+  assert(y == "\255")
+end
+
+do --- jit five chars
+  local y
+  for i=1,100 do y = char(65, 66, i, 67, 68) end
+  assert(y == "ABdCD")
+end
diff --git a/test/LuaJIT-tests/lib/string/dump.lua b/test/LuaJIT-tests/lib/string/dump.lua
new file mode 100644
index 0000000..216c6eb
--- /dev/null
+++ b/test/LuaJIT-tests/lib/string/dump.lua
@@ -0,0 +1,31 @@
+local loadstring = loadstring or load
+
+do --- Must unpatch modified bytecode with ILOOP/JLOOP etc.
+  local function foo()
+    local t = {}
+    for i=1,100 do t[i] = i end
+    for a,b in ipairs(t) do end
+    local m = 0
+    while m < 100 do m = m + 1 end
+  end
+
+  local d1 = string.dump(foo)
+  foo()
+  assert(string.dump(foo) == d1)
+  if jit then jit.off(foo) end
+  foo()
+  assert(string.dump(foo) == d1)
+  local d2 = string.dump(loadstring(d1, ""), true)
+  local d3 = string.dump(assert(loadstring(d2, "")), true)
+  assert(d2 == d3)
+  assert(loadstring(string.dump(assert(loadstring(d2, "")))))
+end
+
+do --- roundtrip constants
+  local function f1() return -0x80000000 end
+  local function f2() return 0.971234567 end
+  assert(f1() == -0x80000000)
+  assert(loadstring(string.dump(f1), "")() == -0x80000000)
+  assert(f2() == 0.971234567)
+  assert(loadstring(string.dump(f2), "")() == 0.971234567)
+end
diff --git a/test/LuaJIT-tests/lib/string/format/index b/test/LuaJIT-tests/lib/string/format/index
new file mode 100644
index 0000000..4408853
--- /dev/null
+++ b/test/LuaJIT-tests/lib/string/format/index
@@ -0,0 +1 @@
+num.lua
diff --git a/test/LuaJIT-tests/lib/string/format/num.lua b/test/LuaJIT-tests/lib/string/format/num.lua
new file mode 100644
index 0000000..e8cb33f
--- /dev/null
+++ b/test/LuaJIT-tests/lib/string/format/num.lua
@@ -0,0 +1,184 @@
+local format, type, tonumber = string.format, type, tonumber
+
+local function check(input, fstr, output, inputN)
+  local actual = format(fstr, inputN or tonumber(input))
+  if actual == output then return end
+  local t = type(output)
+  if t == "string" then
+    if output:find"[[%]]" then
+      local s, e = actual:find((output:gsub("%.", "%%.")))
+      if s == 1 and e == #actual then return end
+    end
+  end
+  error(format("expected string.format(%q, %q) == %q, but got %q",
+    fstr, input, output, actual))
+end
+
+do --- small denormals at low precision +hexfloat !lex
+  assert(("%.9e"):format(0x1.0E00D1p-1050) == "8.742456525e-317")
+  assert(("%.13e"):format(0x1.1Cp-1068) == "3.5078660854729e-322")
+end
+
+do --- smoke
+  local cases = {
+    --     input,             %e,                 %f,            %g
+    {        "0", "0.000000e+00",         "0.000000",           "0"},
+    {        "1", "1.000000e+00",         "1.000000",           "1"},
+    {      "0.5", "5.000000e-01",         "0.500000",         "0.5"},
+    {      "123", "1.230000e+02",       "123.000000",         "123"},
+    {"0.0078125", "7.812500e-03",      "0.00781[23]",   "0.0078125"},
+    { "1.109375", "1.109375e+00",         "1.109375",  "1.1093[78]"},
+    { "0.999995", "9.999950e-01",         "0.999995",    "0.999995"},
+    {"0.9999995", "9.999995e-01",         "1.000000",           "1"},
+    { "99999.95", "9.999995e+04",     "99999.950000",     "99999.9"},
+    {"999999.95", "9.999999e+05",    "999999.950000",       "1e+06"},
+    {"123456978", "1.234570e+08", "123456978.000000", "1.23457e+08"},
+    {     "33.3", "3.330000e+01",        "33.300000",        "33.3"},
+  }
+  for _, t in ipairs(cases) do
+    local n = tonumber(t[1])
+    check(t[1], "%e", t[2], n)
+    check(t[1], "%f", t[3], n)
+    check(t[1], "%g", t[4], n)
+  end
+end
+
+do --- easily enumerable cases of %a, %A +hexfloat
+  for i = 1, 16 do
+    check(1+(i-1)/16, "%.1a", "0x1.".. ("0123456789abcdef"):sub(i,i) .."p+0")
+    check(16+(i-1), "%.1A", "0X1.".. ("0123456789ABCDEF"):sub(i,i) .."P+4")
+  end
+end
+
+do --- easily enumerable cases of %f
+  for i = 1, 16 do
+    check(("1"):rep(i), "%#2.0f", ("1"):rep(i)..".")
+  end
+end
+
+do --- easily enumerable cases of %e
+  local z, f, c = ("0"):byte(), math.floor, string.char
+  for p = 0, 14 do
+    local head = "1.".. ("0"):rep(p)
+    local fmt = "%#.".. c(z + f(p / 10), z + (p % 10)) .."e"
+    for i = 1, 99 do
+      local istr = c(z + f(i / 10), z + (i % 10))
+      check("1e-".. istr, fmt, head .."e-".. istr)
+      check("1e+".. istr, fmt, head .."e+".. istr)
+    end
+    for i = 100, 308 do
+      local istr = c(z + f(i / 100), z + f(i / 10) % 10, z + (i % 10))
+      check("1e-".. istr, fmt, head .."e-".. istr)
+      check("1e+".. istr, fmt, head .."e+".. istr)
+    end
+  end
+end
+
+do --- assorted
+  check("0", "%.14g", "0")
+  check("1e-310", "%.0g", "1e-310")
+  check("1e8", "%010.5g", "000001e+08")
+  check("1e8", "% -10.5g", " 1e+08    ")
+  check("4e123", "%+#.0e", "+4.e+123")
+  check("1e49", "%.0f", "9999999999999999464902769475481793196872414789632")
+  check("1e50", "%.0f", "100000000000000007629769841091887003294964970946560")
+  check("1e50", "%.35g", "1.00000000000000007629769841091887e+50")
+  check("1e50", "%40.35g", "  1.00000000000000007629769841091887e+50")
+  check("1e50", "%#+40.34g", "+1.000000000000000076297698410918870e+50")
+  check("1e50", "%-40.35g", "1.00000000000000007629769841091887e+50  ")
+  check("0.5", "%.0f", "[01]")
+  check("0.25", "%.1f", "0.[23]")
+  check("999999.95", "%.7g", "999999.9")
+  check("999.99995", "%.7g", "1000")
+  check("6.9039613742e-314", "%.3e", "6.904e-314")
+
+  check(1e-323, "%.99g", "9.8813129168249308835313758573644274473011960522864"..
+    "9528851171365001351014540417503730599672723271985e-324")
+  check(1e308, "%.99f", "1000000000000000010979063629440455417404923096773118"..
+    "463368106829031575854049114915371633289784946888990612496697211725"..
+    "156115902837431400883283070091981460460312716645029330271856974896"..
+    "995885590433383844661650011784268976262129451776280911957867074581"..
+    "22783970171784415105291802893207873272974885715430223118336.000000"..
+    "000000000000000000000000000000000000000000000000000000000000000000"..
+    "000000000000000000000000000")
+  check("1", "%.99f", "1."..("0"):rep(99))
+  check("5", "%99g", (" "):rep(98).."5")
+  check("5", "%099g", ("0"):rep(98).."5")
+  check("5", "%-99g", "5".. (" "):rep(98))
+  check("5", "%0-99g", "5".. (" "):rep(98))
+
+  check((2^53-1)*2^971, "%e", "1.797693e+308")
+  check((2^53-1)*2^971, "%.0e", "2e+308")
+
+  check("0", "%.14g", "0")
+
+  check("0.15", "%.1f", "0.1")
+  check("0.45", "%.1f", "0.5")
+  check("0.55", "%.1f", "0.6")
+  check("0.85", "%.1f", "0.8")
+end
+
+do --- assorted %a +luajit>=2.1
+  check((2^53-1)*2^971, "%a", "0x1.fffffffffffffp+1023")
+  check((2^53-1)*2^971, "%.0a", "0x2p+1023")
+  check("0", "%a", "0x0p+0")
+  check("1.53173828125", "%1.8a", "0x1.88200000p+0")
+  check("1.53173828125", "%8.1a", "0x1.9p+0") -- libc on OSX gets this wrong
+  check("1.5317", "%8.1a", "0x1.9p+0")
+  check("1.53", "%8.1a", "0x1.8p+0")
+  check("-1.5", "%11.2a", " -0x1.80p+0")
+  check("3.14159265358", "%a", "0x1.921fb5443d6f4p+1")
+  check("3.14159265358", "%A", "0X1.921FB5443D6F4P+1")
+end
+
+do --- Cases where inprecision can easily affect rounding
+  check("2.28579528986935e-262", "%.14g", "2.2857952898694e-262")
+  check("4.86009084710405e+243", "%.14g", "4.8600908471041e+243")
+  check("6.28108398359615e+258", "%.14g", "6.2810839835962e+258")
+  check("4.29911075733405e+250", "%.14g", "4.2991107573341e+250")
+  check("8.5068432121065e+244", "% .13g", " 8.506843212107e+244")
+  check("8.1919113161235899e+233", "%.40g", "8.191911316123589934222156598061"..
+    "949037266e+233")
+  check("7.1022381748280933e+272", "%.40g", "7.102238174828093393858336547341"..
+    "897013319e+272")
+  check("5.8018368514358030e+261", "%.67g", "5.801836851435803025936253580958"..
+    "042578728799220447411839451694590343e+261")
+  check("7.9225909325493999e-199", "%.26g", "7.922590932549399935196127e-199")
+  check("2.4976643533685383e-153", "%.43g", "2.497664353368538321643894302495"..
+    "469512999562e-153")
+  check("9.796500001282779e+222", "%.4g", "9.797e+222")
+  check("7.7169235e-227", "%e", "7.716923e-227")
+  check("7.7169235000000044e-227", "%e", "7.716924e-227")
+  check("5.3996444915000004e+87", "%.9e", "5.399644492e+87")
+  check("2.03037546395e-49", "%.10e", "2.0303754640e-49")
+  check("3.38759425741500027e+65", "%.11e", "3.38759425742e+65")
+  check("1.013960434983135e-66", "%.0e", "1e-66")
+  check("1.32423054454835e-204", "%.13e", "1.3242305445484e-204")
+  check("5.9005060812045502e+100", "%.13e", "5.9005060812046e+100")
+end
+
+do --- ExploringBinary.com/print-precision-of-dyadic-fractions-varies-by-language/
+  check(5404319552844595/2^53, "%.53g", "0.5999999999999999777955395074968691"..
+	  "9152736663818359375")
+  check(2^-1074, "%.99e", "4.940656458412465441765687928682213723650598026143"..
+	  "247644255856825006755072702087518652998363616359924e-324")
+  check(1-2^-53, "%1.53f", "0.99999999999999988897769753748434595763683319091"..
+	  "796875")
+end
+
+do --- ExploringBinary.com/incorrect-floating-point-to-decimal-conversions/
+  check("1.0551955", "%.7g", "1.055195")
+  check("8.330400913327153", "%.15f", "8.330400913327153")
+  check("9194.25055964485", "%.14g", "9194.2505596449")
+  check("816.2665949149578", "%.16g", "816.2665949149578")
+  check("95.47149571505499", "%.16g", "95.47149571505498")
+end
+
+do --- big f +luajit>=2.1
+  check("9.522938016739373", "%.15F", "9.522938016739372")
+end
+
+do --- RandomASCII.wordpress.com/2013/02/07/
+  check("6.10351562e-05", "%1.8e", "6.1035156[23]e%-05")
+  check("4.3037358649999999e-15", "%1.8e", "4.30373586e-15")
+end
diff --git a/test/LuaJIT-tests/lib/string/index b/test/LuaJIT-tests/lib/string/index
new file mode 100644
index 0000000..c0638e9
--- /dev/null
+++ b/test/LuaJIT-tests/lib/string/index
@@ -0,0 +1,11 @@
+metatable.lua
+byte.lua
+char.lua
+dump.lua
+format
+len.lua
+lower_upper.lua
+multiple_functions.lua
+rep.lua
+reverse.lua
+sub.lua
diff --git a/test/LuaJIT-tests/lib/string/len.lua b/test/LuaJIT-tests/lib/string/len.lua
new file mode 100644
index 0000000..8ed7e8a
--- /dev/null
+++ b/test/LuaJIT-tests/lib/string/len.lua
@@ -0,0 +1,14 @@
+local len = string.len
+local expect_error = require"common.expect_error"
+
+do --- smoke
+  assert(len("abc") == 3)
+  assert(len(123) == 3)
+end
+
+do --- argcheck
+  expect_error(function() len() end,
+      "bad argument #1 to 'len' (string expected, got nil)")
+  expect_error(function() len(false) end,
+      "bad argument #1 to 'len' (string expected, got boolean)")
+end
diff --git a/test/LuaJIT-tests/lib/string/lower_upper.lua b/test/LuaJIT-tests/lib/string/lower_upper.lua
new file mode 100644
index 0000000..7370c44
--- /dev/null
+++ b/test/LuaJIT-tests/lib/string/lower_upper.lua
@@ -0,0 +1,51 @@
+do --- smoke
+  assert(("abc123DEF_<>"):lower() == "abc123def_<>")
+  assert(("abc123DEF_<>"):upper() == "ABC123DEF_<>")
+end
+
+do --- repeated
+  local l = "the quick brown fox..."
+  local u = "THE QUICK BROWN FOX..."
+  local s = l
+  for i = 1, 75 do
+    s = s:upper()
+    assert(s == u)
+    s = s:lower()
+    assert(s == l)
+  end
+end
+
+do --- repeated with growing string
+  local y, z
+  local x = "aBcDe"
+  for i=1,100 do
+    y = string.upper(x)
+    z = y.."fgh"
+  end
+  assert(y == "ABCDE")
+  assert(z == "ABCDEfgh")
+end
+
+do --- misc upper
+  local y
+  for i=1,100 do y = string.upper("aBc9") end
+  assert(y == "ABC9")
+  local x = ":abCd+"
+  for i=1,100 do y = string.upper(x) end
+  assert(y == ":ABCD+")
+  x = 1234
+  for i=1,100 do y = string.upper(x) end
+  assert(y == "1234")
+end
+
+do --- misc lower
+  local y
+  for i=1,100 do y = string.lower("aBc9") end
+  assert(y == "abc9")
+  local x = ":abcd+"
+  for i=1,100 do y = string.lower(x) end
+  assert(y == ":abcd+")
+  x = 1234
+  for i=1,100 do y = string.lower(x) end
+  assert(y == "1234")
+end
diff --git a/test/LuaJIT-tests/lib/string/metatable.lua b/test/LuaJIT-tests/lib/string/metatable.lua
new file mode 100644
index 0000000..d39ed43
--- /dev/null
+++ b/test/LuaJIT-tests/lib/string/metatable.lua
@@ -0,0 +1,3 @@
+do --- __index metamethod is string library
+  assert(debug.getmetatable("").__index == string)
+end
diff --git a/test/LuaJIT-tests/lib/string/multiple_functions.lua b/test/LuaJIT-tests/lib/string/multiple_functions.lua
new file mode 100644
index 0000000..7b9d0f1
--- /dev/null
+++ b/test/LuaJIT-tests/lib/string/multiple_functions.lua
@@ -0,0 +1,16 @@
+do --- string_op
+  local t, y = {}, {}
+  for i=1,100 do t[i] = string.char(i, 16+i, 32+i) end
+  for i=1,100 do t[i] = string.reverse(t[i]) end
+  assert(t[100] == "\132\116\100")
+  for i=1,100 do t[i] = string.reverse(t[i]) end
+  for i=1,100 do assert(t[i] == string.char(i, 16+i, 32+i)) end
+  for i=1,100 do y[i] = string.upper(t[i]) end
+  assert(y[65] == "AQA")
+  assert(y[97] == "AQ\129")
+  assert(y[100] == "DT\132")
+  for i=1,100 do y[i] = string.lower(t[i]) end
+  assert(y[65] == "aqa")
+  assert(y[97] == "aq\129")
+  assert(y[100] == "dt\132")
+end
diff --git a/test/LuaJIT-tests/lib/string/rep.lua b/test/LuaJIT-tests/lib/string/rep.lua
new file mode 100644
index 0000000..550c15b
--- /dev/null
+++ b/test/LuaJIT-tests/lib/string/rep.lua
@@ -0,0 +1,68 @@
+local rep = string.rep
+
+do --- smoke
+  assert(("p"):rep(0) == "")
+  assert(("a"):rep(3) == "aaa")
+  assert(("x\0z"):rep(4) == "x\0zx\0zx\0zx\0z")
+end
+
+do --- versus concat
+  local s = ""
+  for i = 1, 75 do
+    s = s .. "{}"
+    assert(s == ("{}"):rep(i))
+  end
+end
+
+do --- misc
+  local y
+  for i=1,100 do y = rep("a", 10) end
+  assert(y == "aaaaaaaaaa")
+  for i=1,100 do y = rep("ab", 10) end
+  assert(y == "abababababababababab")
+  local x = "a"
+  for i=1,100 do y = rep(x, 10) end
+  assert(y == "aaaaaaaaaa")
+  local n = 10
+  for i=1,100 do y = rep(x, n) end
+  assert(y == "aaaaaaaaaa")
+  x = "ab"
+  for i=1,100 do y = rep(x, n) end
+  assert(y == "abababababababababab")
+  x = 12
+  n = "10"
+  for i=1,100 do y = rep(x, n) end
+  assert(y == "12121212121212121212")
+end
+
+do --- separator +goto
+  local y
+  for i=1,100 do y = rep("ab", 10, "c") end
+  assert(y == "abcabcabcabcabcabcabcabcabcab")
+end
+
+do --- iterate to table
+  local t = {}
+  for i=1,100 do t[i] = rep("ab", i-85) end
+  assert(t[100] == "ababababababababababababababab")
+end
+
+do --- iterate to table with sep +goto
+  local t = {}
+  for i=1,100 do t[i] = rep("ab", i-85, "c") end
+  assert(t[85] == "")
+  assert(t[86] == "ab")
+  assert(t[87] == "abcab")
+  assert(t[100] == "abcabcabcabcabcabcabcabcabcabcabcabcabcabcab")
+end
+
+do --- iterate and concat
+  local y, z
+  local x = "ab"
+  for i=1,100 do
+    y = rep(x, i-90)
+    z = y.."fgh"
+  end
+  assert(y == "abababababababababab")
+  assert(z == "ababababababababababfgh")
+end
diff --git a/test/LuaJIT-tests/lib/string/reverse.lua b/test/LuaJIT-tests/lib/string/reverse.lua
new file mode 100644
index 0000000..deaade7
--- /dev/null
+++ b/test/LuaJIT-tests/lib/string/reverse.lua
@@ -0,0 +1,13 @@
+local reverse = string.reverse
+
+do --- misc
+  local y
+  for i=1,100 do y = reverse("abc") end
+  assert(y == "cba")
+  local x = "abcd"
+  for i=1,100 do y = reverse(x) end
+  assert(y == "dcba")
+  x = 1234
+  for i=1,100 do y = reverse(x) end
+  assert(y == "4321")
+end
diff --git a/test/LuaJIT-tests/lib/string/sub.lua b/test/LuaJIT-tests/lib/string/sub.lua
new file mode 100644
index 0000000..ecb8021
--- /dev/null
+++ b/test/LuaJIT-tests/lib/string/sub.lua
@@ -0,0 +1,189 @@
+local band, bor = bit and bit.band, bit and bit.bor
+local sub = string.sub
+local expect_error = require"common.expect_error"
+
+do --- smoke
+  assert(sub("abc", 2) == "bc")
+  assert(sub(123, "2") == "23")
+end
+
+do --- argcheck
+  expect_error(function() sub("abc", false) end,
+      "bad argument #2 to 'sub' (number expected, got boolean)")
+  expect_error(function() ("abc"):sub(false) end,
+      "bad argument #1 to 'sub' (number expected, got boolean)")
+end
+
+do --- all bar substrings
+  local subs = {
+    {"b", "ba", "bar"},
+    { "",  "a",  "ar"},
+    { "",   "",   "r"}
+  }
+  for i = 1, 3 do
+    for j = 1, 3 do
+      assert(sub("bar", i, j) == subs[i][j])
+      assert(sub("bar", -4+i, j) == subs[i][j])
+      assert(sub("bar", i, -4+j) == subs[i][j])
+      assert(sub("bar", -4+i, -4+j) == subs[i][j])
+    end
+  end
+end
+
+do --- Positive slice [i,len] or overflow +bit
+  local s = "abc"
+  local x
+  for j=100,107 do
+    for i=1,j do x = sub("abc", band(i, 7)) end
+    assert(x == sub("abc", band(j, 7)))
+  end
+  for j=100,107 do
+    for i=1,j do x = sub(s, band(i, 7)) end
+    assert(x == sub(s, band(j, 7)))
+  end
+end
+
+do --- Negative slice [-i,len] or underflow +bit
+  local s = "abc"
+  local x
+  for j=-100,-107,-1 do
+    for i=-1,j,-1 do x = sub("abc", bor(i, -8)) end
+    assert(x == sub("abc", bor(j, -8)))
+  end
+  for j=-100,-107,-1 do
+    for i=-1,j,-1 do x = sub(s, bor(i, -8)) end
+    assert(x == sub(s, bor(j, -8)))
+  end
+end
+
+do --- Positive slice [1,i] or overflow +bit
+  local s = "abc"
+  local x
+  for j=100,107 do
+    for i=1,j do x = sub("abc", 1, band(i, 7)) end
+    assert(x == sub("abc", 1, band(j, 7)))
+  end
+  for j=100,107 do
+    for i=1,j do x = sub(s, 1, band(i, 7)) end
+    assert(x == sub(s, 1, band(j, 7)))
+  end
+end
+
+do --- Negative slice [1,-i] or underflow +bit
+  local s = "abc"
+  local x
+  for j=-100,-107,-1 do
+    for i=-1,j,-1 do x = sub("abc", 1, bor(i, -8)) end
+    assert(x == sub("abc", 1, bor(j, -8)))
+  end
+  for j=-100,-107,-1 do
+    for i=-1,j,-1 do x = sub(s, 1, bor(i, -8)) end
+    assert(x == sub(s, 1, bor(j, -8)))
+  end
+end
+
+do --- jit sub 1 eq
+  local s = "abcde"
+  local x = 0
+  for i=1,100 do
+    if sub(s, 1, 1) == "a" then x = x + 1 end
+  end
+  assert(x == 100)
+end
+
+do --- jit sub 1 ne (contents)
+  local s = "abcde"
+  local x = 0
+  for i=1,100 do
+    if sub(s, 1, 1) == "b" then x = x + 1 end
+  end
+  assert(x == 0)
+end
+
+do --- jit sub 1 ne (rhs too long)
+  local s = "abcde"
+  local x = 0
+  for i=1,100 do
+    if sub(s, 1, 1) == "ab" then x = x + 1 end
+  end
+  assert(x == 0)
+end
+
+do --- jit sub 1,2 ne
+  local s = "abcde"
+  local x = 0
+  for i=1,100 do
+    if sub(s, 1, 2) == "a" then x = x + 1 end
+  end
+  assert(x == 0)
+end
+
+do --- jit sub 1,k eq
+  local s = "abcde"
+  local x = 0
+  local k = 1
+  for i=1,100 do
+    if sub(s, 1, k) == "a" then x = x + 1 end
+  end
+  assert(x == 100)
+end
+
+do --- jit sub 1,k ne (contents)
+  local s = "abcde"
+  local x = 0
+  local k = 1
+  for i=1,100 do
+    if sub(s, 1, k) == "b" then x = x + 1 end
+  end
+  assert(x == 0)
+end
+
+do --- jit sub 1,k ne (rhs too long)
+  local s = "abcde"
+  local x = 0
+  local k = 1
+  for i=1,100 do
+    if sub(s, 1, k) == "ab" then x = x + 1 end
+  end
+  assert(x == 0)
+end
+
+do --- jit sub 1,2 eq
+  local s = "abcde"
+  local x = 0
+  for i=1,100 do
+    if sub(s, 1, 2) == "ab" then x = x + 1 end
+  end
+  assert(x == 100)
+end
+
+do --- jit sub 1,3 eq
+  local s = "abcde"
+  local x = 0
+  for i=1,100 do
+    if sub(s, 1, 3) == "abc" then x = x + 1 end
+  end
+  assert(x == 100)
+end
+
+do --- jit sub 1,4 eq
+  local s = "abcde"
+  local x = 0
+  for i=1,100 do
+    if sub(s, 1, 4) == "abcd" then x = x + 1 end
+  end
+  assert(x == 100)
+end
+
+do --- jit sub i,i
+  local t = {}
+  local line = string.rep("..XX", 100)
+  local i = 1
+  local c = line:sub(i, i)
+  while c ~= "" and c ~= "Z" do
+    t[i] = c == "X" and "Y" or c
+    i = i + 1
+    c = line:sub(i, i)
+  end
+  assert(table.concat(t) == string.rep("..YY", 100))
+end
diff --git a/test/LuaJIT-tests/lib/table/concat.lua b/test/LuaJIT-tests/lib/table/concat.lua
new file mode 100644
index 0000000..1f2a2f9
--- /dev/null
+++ b/test/LuaJIT-tests/lib/table/concat.lua
@@ -0,0 +1,55 @@
+local concat, assert, pcall = table.concat, assert, pcall
+
+do --- table.concat
+  local t = {a=1,b=2,c=3,d=4,e=5}
+  t[1] = 4
+  t[3] = 6
+  local ok, err = pcall(concat, t, "", 1, 3)
+  assert(not ok and err:match("index 2 "))
+  local q = {}
+  for i=1,100 do q[i] = {9,8,7} end
+  q[90] = t
+  for i=1,100 do
+    assert(pcall(concat, q[i], "", 1, 3) == (i ~= 90))
+  end
+  t[2] = 5 -- index 1 - 3 in hash part
+  q[91] = {}
+  q[92] = {9}
+  for i=1,100 do q[i] = concat(q[i], "x") end
+  assert(q[90] == "4x5x6")
+  assert(q[91] == "")
+  assert(q[92] == "9")
+  assert(q[93] == "9x8x7")
+end
+
+do --- table.concat must inhibit CSE and DSE
+  local t = {1,2,3}
+  local y, z
+  for i=1,100 do
+    y = concat(t, "x", 1, 3)
+    t[2] = i
+    z = concat(t, "x", 1, 3)
+  end
+  assert(y == "1x99x3")
+  assert(z == "1x100x3")
+end
+
+do --- table.concat must inhibit CSE and DSE 2
+  local y
+  for i=1,100 do
+    local t = {1,2,3}
+    t[2] = 4
+    y = concat(t, "x")
+    t[2] = 9
+  end
+  assert(y == "1x4x3")
+end
+
+do --- table.concat must inhibit CSE and DSE 3
+  local t = {[0]={}, {}, {}, {}}
+  for i=1,30 do
+    for j=3,0,-1 do
+      t[j].x = t[j-1]
+    end
+  end
+end
diff --git a/test/LuaJIT-tests/lib/table/index b/test/LuaJIT-tests/lib/table/index
new file mode 100644
index 0000000..bd3af0b
--- /dev/null
+++ b/test/LuaJIT-tests/lib/table/index
@@ -0,0 +1,6 @@
+concat.lua
+insert.lua
+new.lua +table.new
+pack.lua +compat5.2
+remove.lua
+sort.lua
diff --git a/test/LuaJIT-tests/lib/table/insert.lua b/test/LuaJIT-tests/lib/table/insert.lua
new file mode 100644
index 0000000..91d4dd8
--- /dev/null
+++ b/test/LuaJIT-tests/lib/table/insert.lua
@@ -0,0 +1,17 @@
+local tinsert = table.insert
+local assert = assert
+
+do --- table.insert(t,i)
+  local t = {}
+  for i=1,100 do t[i] = i end
+  for i=1,100 do tinsert(t, i) end
+  assert(#t == 200 and t[100] == 100 and t[200] == 100)
+end
+
+do --- table.insert(t,i,i)
+  local t = {}
+  for i=1,200 do t[i] = i end
+  for i=101,200 do tinsert(t, i, i) end
+  assert(#t == 300 and t[101] == 101 and t[200] == 200 and t[300] == 200)
+end
+
diff --git a/test/LuaJIT-tests/lib/table/misc.lua b/test/LuaJIT-tests/lib/table/misc.lua
new file mode 100644
index 0000000..e0e2fc5
--- /dev/null
+++ b/test/LuaJIT-tests/lib/table/misc.lua
@@ -0,0 +1,58 @@
+-- TODO: Organise
+
+-- ABC elim
+-- +opt +abc
+do
+  local s, t = {}, {}
+  for i=1,100 do t[i] = 1 end
+  for i=1,100 do s[i] = t end
+  s[90] = {}
+  local n = 100
+  for i=1,n do s[i][i] = i end
+end
+
+--- TSETM
+-- Initialize table with multiple return values
+do
+  local function f(a,b,c)
+    return a,b,c
+  end
+
+  local t
+
+  t = {(f(1,2,3))}
+  assert(t[1] == 1 and t[2] == nil and t[3] == nil)
+
+  t = {f(1,2,3)}
+  assert(t[1] == 1 and t[2] == 2 and t[3] == 3 and t[4] == nil)
+  t = {f(1,2,3),}
+  assert(t[1] == 1 and t[2] == 2 and t[3] == 3 and t[4] == nil)
+
+  t = {f(1,2,3), f(4,5,6)}
+  assert(t[1] == 1 and t[2] == 4 and t[3] == 5 and t[4] == 6 and t[5] == nil)
+
+  t = {
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  f(2,3,4)}
+  assert(t[255] == 1 and t[256] == 2 and t[257] == 3 and t[258] == 4 and t[259] == nil)
+end
+
+--- TSETM 2
+-- Initialize table with function returning 2 constant return values
+do
+  local function f() return 9, 10 end
+  local t
+  for i=1,100 do t = { 1, 2, 3, f() } end
+  assert(t[1] == 1 and t[2] == 2 and t[3] == 3 and t[4] == 9 and t[5] == 10 and
+	 t[6] == nil)
+end
+
+
+
diff --git a/test/LuaJIT-tests/lib/table/new.lua b/test/LuaJIT-tests/lib/table/new.lua
new file mode 100644
index 0000000..483c129
--- /dev/null
+++ b/test/LuaJIT-tests/lib/table/new.lua
@@ -0,0 +1,11 @@
+local tnew = require"table.new"
+
+do --- table.new
+  local x, y
+  for i=1,100 do
+    x = tnew(100, 30)
+    assert(type(x) == "table")
+    if i == 90 then y = x end
+  end
+  assert(x ~= y)
+end
diff --git a/test/LuaJIT-tests/lib/table/pack.lua b/test/LuaJIT-tests/lib/table/pack.lua
new file mode 100644
index 0000000..5bd6ecb
--- /dev/null
+++ b/test/LuaJIT-tests/lib/table/pack.lua
@@ -0,0 +1,7 @@
+do --- empty
+  local t = table.pack()
+  assert(type(t) == "table")
+  assert(t.n == 0)
+  assert(t[0] == nil)
+  assert(t[1] == nil)
+end
diff --git a/test/LuaJIT-tests/lib/table/remove.lua b/test/LuaJIT-tests/lib/table/remove.lua
new file mode 100644
index 0000000..1b24a4f
--- /dev/null
+++ b/test/LuaJIT-tests/lib/table/remove.lua
@@ -0,0 +1,42 @@
+local tremove = table.remove
+local assert = assert
+
+do --- table.remove(t) removes correct entries
+  local t = {}
+  for i=1,200 do t[i] = i end
+  for i=1,100 do tremove(t) end
+  assert(#t == 100 and t[100] == 100)
+end
+
+do --- table.remove(t) returns the removed entry
+  local t = {}
+  for i=1,200 do t[i] = i end
+  for i=1,100 do assert(tremove(t) == 201-i) end
+  assert(#t == 100 and t[100] == 100)
+end
+
+do --- table.remove(t, 1) removes and returns the first entry
+  local t = {}
+  for i=1,200 do t[i] = i end
+  for i=1,100 do assert(tremove(t, 1) == i) end
+  assert(#t == 100 and t[100] == 200)
+end
+
+do --- TSETR hash part +table.new
+  local tnew = require"table.new"
+  local t = tnew(0, 16)
+  for i=10,1,-1 do t[i] = i+3 end
+  for i=10,1,-1 do assert(tremove(t) == i+3) end
+  assert(#t == 0)
+end
+
+do --- TSETR write barrier +table.new
+  local tnew = require"table.new"
+  for _, t in ipairs{{}, tnew(0, 16)} do
+    for i = 1, 10 do t[i] = {i} end
+    for i = 1, 10 do
+      collectgarbage()
+      assert(tremove(t, 1)[1] == i)
+    end
+  end
+end
diff --git a/test/LuaJIT-tests/lib/table/sort.lua b/test/LuaJIT-tests/lib/table/sort.lua
new file mode 100644
index 0000000..6a86fcf
--- /dev/null
+++ b/test/LuaJIT-tests/lib/table/sort.lua
@@ -0,0 +1,27 @@
+-- Really a test for lua_lessthan()
+local N = 1000
+
+do --- numbers
+  math.randomseed(42)
+  local t = {}
+  for i=1,N do t[i] = math.random(N) end
+  table.sort(t)
+  for i=2,N do assert(t[i-1] <= t[i]) end
+end
+
+do --- strings
+  math.randomseed(42)
+  local t = {}
+  for i=1,N do t[i] = math.random(1, N/10).."" end
+  table.sort(t)
+  for i=2,N do assert(t[i-1] <= t[i]) end
+end
+
+do --- tables
+  math.randomseed(42)
+  local mt = { __lt = function(a,b) return a[1] < b[1] end }
+  local t = {}
+  for i=1,N do t[i] = setmetatable({ math.random(N) }, mt) end
+  table.sort(t)
+  for i=2,N do assert(t[i-1][1] <= t[i][1]) end
+end
diff --git a/test/LuaJIT-tests/misc/alias_alloc.lua b/test/LuaJIT-tests/misc/alias_alloc.lua
new file mode 100644
index 0000000..02fe618
--- /dev/null
+++ b/test/LuaJIT-tests/misc/alias_alloc.lua
@@ -0,0 +1,54 @@
+
+do
+  local t = {1}
+  local x
+  for i=1,100 do
+    local v = {i}
+    t[1] = v[1]
+    x = v[1]
+  end
+  assert(x == 100 and t[1] == 100)
+end
+
+do
+  local t = {1}
+  local x,y
+  for i=1,100 do
+    local v = {i}
+    local w = {i+1}
+    x = v[1]
+    y = w[1]
+  end
+  assert(x == 100 and y == 101)
+end
+
+do
+  local mt = {}
+  local t = setmetatable({}, mt)
+  local x
+  for i=1,100 do
+    local v = {}
+    setmetatable(v, getmetatable(t))
+    assert(getmetatable(v) == mt)
+  end
+end
+
+-- See also sink_alloc.lua
+do
+  local x,k={1,2},{3,4}
+  for i=1,100 do x = {x[1]+k[1], x[2]+k[2]} end
+  assert(x[1] == 301)
+  assert(x[2] == 402)
+end
+
+-- FLOAD for tab.asize/tab.array crossing NEWREF.
+do
+  local t = {1}
+  for i=1,100 do
+    local v = {}
+    local w = {}
+    v[1] = t[1]
+    w[1] = t[1]
+  end
+end
+
diff --git a/test/LuaJIT-tests/misc/api_call.lua b/test/LuaJIT-tests/misc/api_call.lua
new file mode 100644
index 0000000..7dbd5e4
--- /dev/null
+++ b/test/LuaJIT-tests/misc/api_call.lua
@@ -0,0 +1,98 @@
+local ctest = require("ctest")
+
+local function ret0() end
+local function ret1() return 1 end
+local function ret2() return 1,2 end
+local function ret3() return 1,2,3 end
+local function retva(...) return ... end
+local function ret1va(...) return 1,... end
+
+local function pack(...)
+  return { n = select('#', ...), ... }
+end
+
+local function ck(res, ...)
+  local ok = pack(...)
+  if res.n ~= ok.n then error("nresults wrong: "..res.n.." ~= "..ok.n, 2) end
+  for i=1,res.n do
+    if res[i] ~= ok[i] then
+      error("result["..i.."] wrong: "..tostring(res[i]).." ~= "..tostring(ok[i]), 2)
+    end
+  end
+end
+
+local function test_adjust_results(testfunc)
+
+  local function cc(nres, f, ...)
+    return pack(testfunc(nres, f, ...))
+  end
+
+  ck(cc(0, ret0))
+  ck(cc(0, ret1))
+  ck(cc(0, ret2))
+  ck(cc(0, ret3))
+  ck(cc(0, retva))
+
+  ck(cc(1, ret0), nil)
+  ck(cc(1, ret1), 1)
+  ck(cc(1, ret2), 1)
+  ck(cc(1, ret3), 1)
+  ck(cc(1, retva), nil)
+  ck(cc(1, retva, 1), 1)
+
+  ck(cc(2, ret0), nil, nil)
+  ck(cc(2, ret1), 1, nil)
+  ck(cc(2, ret2), 1, 2)
+  ck(cc(2, ret3), 1, 2)
+  ck(cc(2, retva), nil, nil)
+  ck(cc(2, retva, 1), 1, nil)
+  ck(cc(2, retva, 1, 2), 1, 2)
+
+  ck(cc(-1, ret0))
+  ck(cc(-1, ret1), 1)
+  ck(cc(-1, ret2), 1, 2)
+  ck(cc(-1, ret3), 1, 2, 3)
+  ck(cc(-1, retva))
+  ck(cc(-1, retva, 1), 1)
+  ck(cc(-1, retva, 1, 2), 1, 2)
+end
+
+test_adjust_results(ctest.call)
+test_adjust_results(ctest.pcall_err)
+
+
+local function gcshrink()
+  for i=1,10 do collectgarbage() end
+end
+
+assert(select('#', ctest.call(2000, gcshrink)) == 2000)
+gcshrink()
+assert(select('#', ctest.call(7000, gcshrink)) == 7000)
+gcshrink()
+
+local function test_yield(resume, yield)
+  local function inpcall()
+    ck(pack(yield(6, 7)), 18, 19)
+  end
+  local co = coroutine.create(function(...)
+    ck(pack(...), 11, 12)
+    ck(pack(yield(1, 2)))
+    ck(pack(yield()), 13, 14, 15)
+    ck(pack(yield(3, 4, 5)), 16, 17)
+    assert(pcall(inpcall) == true)
+    return 8, 9
+  end)
+
+  ck(pack(resume(co, 11, 12)), true, 1, 2)
+  ck(pack(resume(co)), true)
+  ck(pack(resume(co, 13, 14, 15)), true, 3, 4, 5)
+  ck(pack(resume(co, 16, 17)), true, 6, 7)
+  ck(pack(resume(co, 18, 19)), true, 8, 9)
+  assert(resume(co) == false)
+end
+
+test_yield(coroutine.resume, coroutine.yield)
+test_yield(ctest.resume, coroutine.yield)
+test_yield(coroutine.resume, ctest.yield)
+test_yield(ctest.resume, ctest.yield)
+
diff --git a/test/LuaJIT-tests/misc/catch_wrap.lua b/test/LuaJIT-tests/misc/catch_wrap.lua
new file mode 100644
index 0000000..7f656bc
--- /dev/null
+++ b/test/LuaJIT-tests/misc/catch_wrap.lua
@@ -0,0 +1,45 @@
+
+local cp = require("cpptest")
+cp.wrapon()
+
+do
+  local a, b = pcall(cp.catch, function() return "x" end)
+  assert(a == true and b == "x")
+end
+
+do
+  local a, b = pcall(function() cp.throw("foo") end)
+  assert(a == false and b == "foo")
+end
+
+local unwind
+do
+  local a, b = pcall(cp.catch, function() cp.throw("foo") end)
+  unwind = a
+  assert((a == false and b == "foo") or (a == true and b == "catch ..."))
+end
+
+do
+  local st = cp.alloc(function() return cp.isalloc() end)
+  assert(st == true)
+  assert(cp.isalloc() == false)
+end
+
+do
+  local a, b = pcall(cp.alloc, function()
+    assert(cp.isalloc() == true)
+    return "foo", cp.throw
+  end)
+  assert(a == false and b == "foo")
+  assert(cp.isalloc() == false)
+end
+
+do
+  local a, b = pcall(cp.alloc, function()
+    assert(cp.isalloc() == true)
+    return "foo", error
+  end)
+  assert(a == false and b == "foo")
+  if unwind then assert(cp.isalloc() == false) end
+end
+
diff --git a/test/LuaJIT-tests/misc/coro_traceback.lua b/test/LuaJIT-tests/misc/coro_traceback.lua
new file mode 100644
index 0000000..2676d2c
--- /dev/null
+++ b/test/LuaJIT-tests/misc/coro_traceback.lua
@@ -0,0 +1,8 @@
+
+local co = coroutine.create(function()
+  local x = nil
+  local y = x.x
+end)
+assert(coroutine.resume(co) == false)
+debug.traceback(co)
+
diff --git a/test/LuaJIT-tests/misc/coro_yield.lua b/test/LuaJIT-tests/misc/coro_yield.lua
new file mode 100644
index 0000000..ae3206e
--- /dev/null
+++ b/test/LuaJIT-tests/misc/coro_yield.lua
@@ -0,0 +1,111 @@
+local create = coroutine.create
+local wrap = coroutine.wrap
+local resume = coroutine.resume
+local yield = coroutine.yield
+
+-- Test stack overflow handling on return from coroutine.
+do
+  wrap(function()
+    local co = create(function()
+      yield(string.byte(string.rep(" ", 100), 1, 100))
+    end)
+    assert(select('#', resume(co)) == 101)
+  end)()
+end
+
+do
+  wrap(function()
+    local f = wrap(function()
+      yield(string.byte(string.rep(" ", 100), 1, 100))
+    end)
+    assert(select('#', f()) == 100)
+  end)()
+end
+
+do
+  local function cogen(x)
+    return wrap(function(n) repeat x = x+n; n = yield(x) until false end),
+	   wrap(function(n) repeat x = x*n; n = yield(x) until false end)
+  end
+
+  local a,b=cogen(3)
+  local c,d=cogen(5)
+  assert(d(b(c(a(d(b(c(a(1)))))))) == 168428160)
+end
+
+do
+  local function verify(what, expect, ...)
+    local got = {...}
+    for i=1,100 do
+      if expect[i] ~= got[i] then
+	error("FAIL " .. what)
+      end
+      if expect[i] == nil then
+	break
+      end
+    end
+  end
+
+  local function cofunc(...)
+    verify("call", { 1, "foo" }, ...)
+    verify("yield", { "bar" }, yield(2, "test"))
+    verify("pcall yield", { true, "again" }, pcall(yield, "from pcall"))
+    return "end"
+  end
+
+  local co = create(cofunc)
+  verify("resume", { true, 2, "test" }, resume(co, 1, "foo"))
+  verify("resume pcall", { true, "from pcall" }, resume(co, "bar"))
+  verify("resume end", { true, "end" }, resume(co, "again"))
+end
+
+do
+  local function verify(expect, func, ...)
+    local co = create(func)
+    for i=1,100 do
+      local ok, res = resume(co, ...)
+      if not ok then
+	if expect[i] ~= nil then
+	  error("too few results: ["..i.."] = "..tostring(expect[i]).." (got: "..tostring(res)..")")
+	end
+	break
+      end
+      if expect[i] ~= res then
+	error("bad result: ["..i.."] = "..tostring(res).." (should be: "..tostring(expect[i])..")")
+      end
+    end
+  end
+
+  verify({ 42, 99 },
+    function(x) pcall(yield, x) return 99 end,
+    42)
+
+  verify({ 42, 99 },
+    function(x) pcall(function(y) yield(y) end, x) return 99 end,
+    42)
+
+  verify({ 42, 99 },
+    function(x) xpcall(yield, debug.traceback, x) return 99 end,
+    42)
+
+  verify({ 45, 44, 43, 42, 99 },
+    function(x, y)
+      for i in
+	function(o, k)
+	  yield(o+k)
+	  if k ~= 0 then return k-1 end
+	end,x,y do
+      end
+      return 99
+    end,
+    42, 3)
+
+  verify({ 84, 99 },
+    function(x)
+      local o = setmetatable({ x },
+	{__add = function(a, b) yield(a[1]+b[1]) return 99 end })
+      return o+o
+    end,
+    42)
+end
+
diff --git a/test/LuaJIT-tests/misc/debug_gc.lua b/test/LuaJIT-tests/misc/debug_gc.lua
new file mode 100644
index 0000000..30fb2b9
--- /dev/null
+++ b/test/LuaJIT-tests/misc/debug_gc.lua
@@ -0,0 +1,47 @@
+
+-- Do not run this test unless the JIT compiler is turned off.
+if jit and jit.status and jit.status() then return end
+
+local caught, caught_line, caught_mm
+
+local function gcmeta()
+  if caught ~= "end" then
+--    print(debug.traceback())
+    -- This may point to the wrong instruction if in a JIT trace.
+    -- But there's no guarantee if, when or where any GC steps occur.
+    local dbg = debug.getinfo(2)
+    caught_line = dbg.currentline
+    caught_mm = debug.getinfo(1).name
+    caught = true
+  end
+end
+
+local function testgc(mm, f)
+  collectgarbage()
+  caught = false
+  local u = newproxy(true)
+  getmetatable(u).__gc = gcmeta
+  u = nil
+  for i=1,100000 do
+    f(i)
+    -- This check may be hoisted. __gc is not supposed to have side-effects.
+    if caught then break end
+  end
+  if not caught then
+    error(mm.." metamethod not called", 2)
+  end
+  if type(caught_line) ~= "number" or caught_line < 0 then
+    error("bad linenumber in debug info", 2)
+  end
+  if caught_mm ~= mm then
+    error("bad name for metamethod in debug info", 2)
+  end
+end
+
+local x
+testgc("__gc", function(i) x = {} end)
+testgc("__gc", function(i) x = {1} end)
+testgc("__gc", function(i) x = function() end end)
+testgc("__concat", function(i) x = i.."" end)
+
+caught = "end"
diff --git a/test/LuaJIT-tests/misc/dualnum.lua b/test/LuaJIT-tests/misc/dualnum.lua
new file mode 100644
index 0000000..5f1288c
--- /dev/null
+++ b/test/LuaJIT-tests/misc/dualnum.lua
@@ -0,0 +1,47 @@
+
+-- Positive overflow
+do
+  local x = 0
+  for i=2147483446,2147483647,2 do x = x + 1 end
+  assert(x == 101)
+end
+
+-- Negative overflow
+do
+  local x = 0
+  for i=-2147483447,-2147483648,-2 do x = x + 1 end
+  assert(x == 101)
+end
+
+-- SLOAD with number to integer conversion.
+do
+  local k = 1
+  local a, b, c = 1/k, 20/k, 1/k
+  for i=1,20 do
+    for j=a,b,c do end
+  end
+end
+
+do
+  local function fmin(a, b)
+    for i=1,100 do a = math.min(a, b) end
+    return a
+  end
+  local function fmax(a, b)
+    for i=1,100 do a = math.max(a, b) end
+    return a
+  end
+  assert(fmin(1, 3) == 1)
+  assert(fmin(3, 1) == 1)
+  assert(fmin(-1, 3) == -1)
+  assert(fmin(3, -1) == -1)
+  assert(fmin(-1, -3) == -3)
+  assert(fmin(-3, -1) == -3)
+  assert(fmax(1, 3) == 3)
+  assert(fmax(3, 1) == 3)
+  assert(fmax(-1, 3) == 3)
+  assert(fmax(3, -1) == 3)
+  assert(fmax(-1, -3) == -1)
+  assert(fmax(-3, -1) == -1)
+end
+
diff --git a/test/LuaJIT-tests/misc/for_dir.lua b/test/LuaJIT-tests/misc/for_dir.lua
new file mode 100644
index 0000000..4dd38de
--- /dev/null
+++ b/test/LuaJIT-tests/misc/for_dir.lua
@@ -0,0 +1,13 @@
+
+local a,b,c = 10,1,-1
+for i=1,20 do
+  if c == -1 then
+    a,b,c = 1,10,1
+  else
+    a,b,c = 10,1,-1
+  end
+  local x = 0
+  for i=a,b,c do for j=1,10 do end x=x+1 end
+  assert(x == 10)
+end
+
diff --git a/test/LuaJIT-tests/misc/fori_coerce.lua b/test/LuaJIT-tests/misc/fori_coerce.lua
new file mode 100644
index 0000000..7330943
--- /dev/null
+++ b/test/LuaJIT-tests/misc/fori_coerce.lua
@@ -0,0 +1,33 @@
+
+do
+  local n = 1
+  local x = 0
+  for i=1,20 do
+    for j=n,100 do x = x + 1 end
+    if i == 13 then n = "2" end
+  end
+  assert(x == 1993)
+end
+
+do
+  local n = 1
+  local x = 0
+  for i=1,20 do
+    for j=n,100 do x = x + 1 end
+    if i == 10 then n = "2" end
+  end
+  assert(x == 1990)
+end
+
+do
+  local function f()
+    local n = 1
+    local x = 0
+    for i=1,20 do
+      for j=n,100 do x = x + 1 end
+      if i == 10 then n = "x" end
+    end
+  end
+  assert(not pcall(f))
+end
+
diff --git a/test/LuaJIT-tests/misc/gc_rechain.lua b/test/LuaJIT-tests/misc/gc_rechain.lua
new file mode 100644
index 0000000..285f408
--- /dev/null
+++ b/test/LuaJIT-tests/misc/gc_rechain.lua
@@ -0,0 +1,32 @@
+
+do
+  local k
+
+  collectgarbage()
+
+  local t = {}
+  t.ac = 1
+
+  t.nn = 1
+  t.mm = 1
+  t.nn = nil
+  t.mm = nil
+
+  k = "a".."i"
+  t[k] = 2
+
+  t.ad = 3
+
+  t[k] = nil
+  k = nil
+
+  collectgarbage()
+
+  k = "a".."f"
+  t[k] = 4
+
+  t.ak = 5
+
+  assert(t[k] == 4)
+end
+
diff --git a/test/LuaJIT-tests/misc/gc_trace.lua b/test/LuaJIT-tests/misc/gc_trace.lua
new file mode 100644
index 0000000..bc38ce0
--- /dev/null
+++ b/test/LuaJIT-tests/misc/gc_trace.lua
@@ -0,0 +1,37 @@
+
+if not jit or not jit.status or not jit.status() then return end
+
+collectgarbage()
+for j=1,100 do
+  loadstring("for i=1,100 do end")()
+end
+local jutil = require("jit.util")
+assert(jutil.traceinfo(90) == nil)
+collectgarbage()
+assert(jutil.traceinfo(1) == nil)
+assert(jutil.traceinfo(2) == nil)
+assert(jutil.traceinfo(3) == nil)
+
+do
+  local f
+  local function reccb(tr)
+    if f == nil then
+      collectgarbage()
+      local info = jutil.traceinfo(tr)
+      jutil.tracek(tr, -info.nk)
+      -- Error in lj_ir_kvalue() if KGC not marked.
+      -- Only caught with assertions or Valgrind.
+    end
+  end
+  jit.attach(reccb, "record")
+  for i=1,200 do
+    if i % 5 == 0 then
+      f = function() end
+    elseif f then
+      f()
+      f = nil
+    end
+  end
+  jit.attach(reccb)
+end
+
diff --git a/test/LuaJIT-tests/misc/gcstep.lua b/test/LuaJIT-tests/misc/gcstep.lua
new file mode 100644
index 0000000..533356b
--- /dev/null
+++ b/test/LuaJIT-tests/misc/gcstep.lua
@@ -0,0 +1,33 @@
+
+local function testgc(what, func)
+  collectgarbage()
+  local oc = gcinfo()
+  func()
+  local nc = gcinfo()
+  assert(nc < oc*4, "GC step missing for "..what)
+end
+
+testgc("TNEW", function()
+  for i=1,10000 do
+    local t = {}
+  end
+end)
+
+testgc("TDUP", function()
+  for i=1,10000 do
+    local t = {1}
+  end
+end)
+
+testgc("FNEW", function()
+  for i=1,10000 do
+    local function f() end
+  end
+end)
+
+testgc("CAT", function()
+  for i=1,10000 do
+    local s = "x"..i
+  end
+end)
+
diff --git a/test/LuaJIT-tests/misc/hook_active.lua b/test/LuaJIT-tests/misc/hook_active.lua
new file mode 100644
index 0000000..37dfc37
--- /dev/null
+++ b/test/LuaJIT-tests/misc/hook_active.lua
@@ -0,0 +1,95 @@
+local ctest = require("ctest")
+
+local called = 0
+local function clearhook() debug.sethook(nil, "", 0) end
+
+-- Return from pcall with active hook must prepend true. FF pcall.
+called = 0
+debug.sethook(function() called=called+1; assert(pcall(function() end) == true); clearhook() end, "", 1)
+do local x = 1 end
+assert(called == 1)
+
+-- Hook with special caught error must not unblock hooks. FF pcall.
+called = 0
+debug.sethook(function() called=called+1; pcall(nil); clearhook() end, "", 1)
+do local x = 1 end
+assert(called == 1)
+
+-- Hook with caught error must not unblock hooks. FF pcall.
+called = 0
+local function p2() error("") end
+debug.sethook(function() called=called+1; pcall(p2); clearhook() end, "", 1)
+do local x = 1 end
+assert(called == 1)
+
+-- Hook with special caught error must not unblock hooks. C pcall.
+called = 0
+debug.sethook(function() called=called+1; ctest.pcall(nil); clearhook() end, "", 1)
+do local x = 1 end
+assert(called == 1)
+
+-- Hook with caught error must not unblock hooks. C pcall
+called = 0
+local function p2() error("") end
+debug.sethook(function() called=called+1; ctest.pcall(p2); clearhook() end, "", 1)
+do local x = 1 end
+assert(called == 1)
+
+-- Regular pcall must not block hooks.
+debug.sethook(function() called=called+1 end, "", 1)
+pcall(function() end)
+called = 0
+do local x = 1 end
+assert(called > 0)
+pcall(function() error("") end)
+called = 0
+do local x = 1 end
+assert(called > 0)
+ctest.pcall(function() end)
+called = 0
+do local x = 1 end
+assert(called > 0)
+ctest.pcall(function() error("") end)
+called = 0
+do local x = 1 end
+assert(called > 0)
+clearhook()
+
+-- Hook with uncaught error must unblock hooks. FF pcall
+called = 0
+pcall(function()
+  debug.sethook(function()
+    local old = called
+    called = 1
+    if old == 0 then error("") end
+  end, "", 1)
+  do local x = 1 end
+end)
+assert(called == 1)
+called = 2
+do local x = 1 end
+assert(called == 1, "hook not unblocked after uncaught error")
+clearhook()
+called = 2
+do local x = 1 end
+assert(called == 2)
+
+-- Hook with uncaught error must unblock hooks. C pcall
+called = 0
+ctest.pcall(function()
+  debug.sethook(function()
+    local old = called
+    called = 1
+    if old == 0 then error("") end
+  end, "", 1)
+  do local x = 1 end
+end)
+assert(called == 1)
+called = 2
+do local x = 1 end
+assert(called == 1, "hook not unblocked after uncaught error")
+clearhook()
+called = 2
+do local x = 1 end
+assert(called == 2)
+
diff --git a/test/LuaJIT-tests/misc/hook_line.lua b/test/LuaJIT-tests/misc/hook_line.lua
new file mode 100644
index 0000000..36f7108
--- /dev/null
+++ b/test/LuaJIT-tests/misc/hook_line.lua
@@ -0,0 +1,41 @@
+local lines = {}
+local function hook()
+  lines[#lines+1] = debug.getinfo(2).currentline
+end
+
+local function dummy()
+end -- <-- line 7
+
+debug.sethook(hook, "l", 0)
+-- <-- line 10
+local x
+dummy()
+local y = 1
+dummy() dummy()
+local z = 2; local r = true
+while y < 4 do y = y + 1 end
+while z < 4 do
+  z = z + 1
+end
+-- <-- line 20
+local v
+debug.sethook(nil, "", 0)
+
+assert(#lines > 0)
+while lines[1] < 10 do table.remove(lines, 1) end
+while lines[#lines] > 20 do table.remove(lines) end
+
+local s = table.concat(lines, " ")
+assert(s == "11 12 7 13 14 7 7 15 16 16 16 16 17 18 17 18 17" or
+       s == "11 12 7 13 14 7 14 7 15 16 16 16 16 17 18 17 18 17")
+
+lines = {}
+local function f()
+  if true then return end
+  local function x() end
+end -- <-- line 36
+debug.sethook(hook, "l", 0)
+f()
+debug.sethook(nil, "", 0)
+for i=1,#lines do assert(lines[i] ~= 36) end
+
diff --git a/test/LuaJIT-tests/misc/hook_norecord.lua b/test/LuaJIT-tests/misc/hook_norecord.lua
new file mode 100644
index 0000000..8e7cba0
--- /dev/null
+++ b/test/LuaJIT-tests/misc/hook_norecord.lua
@@ -0,0 +1,12 @@
+
+if not jit or not jit.status or not jit.status() then return end
+
+local called = false
+local function f() local x = "wrong"; called = true end
+jit.off(f)
+debug.sethook(f, "", 5)
+for i=1,1000 do local a,b,c,d,e,f=1,2,3,4,5,6 end
+assert(called)
+-- Check that no trace was generated.
+assert(require("jit.util").traceinfo(1) == nil)
+
diff --git a/test/LuaJIT-tests/misc/hook_record.lua b/test/LuaJIT-tests/misc/hook_record.lua
new file mode 100644
index 0000000..6f1646d
--- /dev/null
+++ b/test/LuaJIT-tests/misc/hook_record.lua
@@ -0,0 +1,8 @@
+
+if not jit or not jit.status or not jit.status() then return end
+
+debug.sethook(function() for i=1,100 do end end, "", 10)
+for i=1,10 do end
+debug.sethook()
+assert((require("jit.util").traceinfo(1)))
+
diff --git a/test/LuaJIT-tests/misc/hook_top.lua b/test/LuaJIT-tests/misc/hook_top.lua
new file mode 100644
index 0000000..f809fce
--- /dev/null
+++ b/test/LuaJIT-tests/misc/hook_top.lua
@@ -0,0 +1,55 @@
+
+local t = {}
+for i=1,26 do t[i] = string.char(96+i) end
+
+local function tcheck(t1, t2)
+  assert(#t1 == #t2)
+  for i=1,#t1 do assert(t1[i] == t2[i]) end
+end
+
+local function foo1(...) -- VARG RETM
+  return ...
+end
+
+local function foo2(...) -- VARG UCLO RETM
+  local function dummy() end
+  return ...
+end
+
+local function foo3(...) -- VARG UCLO -> RETM
+  do return ... end
+  local function dummy() end
+end
+
+local function foo4() -- UCLO UCLO RET
+  do
+    local x
+    local function dummy() return x end
+  end
+end
+
+called = false
+debug.sethook(function() local x = "wrong"; called = true end, "", 1)
+tcheck(t, {foo1(unpack(t))}) -- CALLM TSETM
+assert(called)
+called = false
+tcheck(t, {foo2(unpack(t))})
+assert(called)
+called = false
+tcheck(t, {foo2(unpack(t))})
+assert(called)
+called = false
+foo4()
+assert(called)
+
+debug.sethook(function()
+  local name, val = debug.getlocal(2, 1)
+  assert(name == "a" and val == nil)
+  debug.setlocal(2, 1, "bar")
+  debug.sethook(nil)
+end, "c")
+local function foo5(a)
+  assert(a == "bar")
+end
+foo5()
+
diff --git a/test/LuaJIT-tests/misc/jit_flush.lua b/test/LuaJIT-tests/misc/jit_flush.lua
new file mode 100644
index 0000000..ead1e4e
--- /dev/null
+++ b/test/LuaJIT-tests/misc/jit_flush.lua
@@ -0,0 +1,50 @@
+
+if not jit or not jit.status or not jit.status() then return end
+
+for i=1,100 do
+  if i==50 then jit.flush(2) end
+  for j=1,100 do end
+  for j=1,100 do end
+end
+
+jit.flush()
+
+local function f() for i=1,100 do end end
+for i=1,100 do local x = gcinfo(); f() end
+
+jit.flush()
+
+local function fib(n)
+  if n < 2 then return 1 end
+  return fib(n-2) + fib(n-1)
+end
+
+fib(11)
+
+jit.flush()
+
+local names = {}
+for i=1,100 do names[i] = i end
+
+function f()
+  for k,v in ipairs(names) do end
+end
+
+f()
+
+for i=1,2 do
+  f()
+  f()
+  jit.flush()
+end
+
+jit.flush()
+
+jit.flush(1) -- ignored
+jit.flush(2) -- ignored
+for i=1,1e7 do end -- causes trace #1
+
+jit.flush(2) -- ignored
+jit.flush(1) -- ok
+jit.flush(1) -- crashes
+
diff --git a/test/LuaJIT-tests/misc/lightud.lua b/test/LuaJIT-tests/misc/lightud.lua
new file mode 100644
index 0000000..4974d50
--- /dev/null
+++ b/test/LuaJIT-tests/misc/lightud.lua
@@ -0,0 +1,88 @@
+local ctest = require("ctest")
+
+local lightud = ctest.lightud
+local assert = assert
+
+-- x64 lightud tests
+if jit and jit.arch == "x64" then
+  do
+    local ud1 = lightud(0x12345678)
+    local ud2 = lightud(0x12345678)
+    assert(ud1 == ud2)
+    assert(tostring(ud1) == "userdata: 0x12345678")
+  end
+  do
+    local ud1 = lightud(1)
+    local ud2 = lightud(2)
+    assert(ud1 ~= ud2)
+  end
+  do
+    local ud1 = lightud(2^47-1)
+    local ud2 = lightud(2^47-1)
+    assert(ud1 == ud2)
+    assert(tostring(ud1) == "userdata: 0x7fffffffffff")
+  end
+  do
+    local ud1 = lightud(0x12345678+123*2^32)
+    local ud2 = lightud(0x12345678+456*2^32)
+    for i=1,100 do assert(ud1 ~= ud2) end
+  end
+  assert(tostring(lightud(0x5abc*2^32 + 0xdef01234)) == "userdata: 0x5abcdef01234")
+  assert(pcall(lightud, 2^47) == false)
+  assert(pcall(lightud, 2^64-2048) == false)
+end
+
+assert(getmetatable(lightud(1)) == nil)
+
+-- lightuserdata SLOAD value and HREF key
+do
+  local ud = lightud(12345)
+  local t = {[ud] = 42}
+  for i=1,100 do
+    assert(t[ud] == 42)
+  end
+end
+
+-- lightuserdata NEWREF key
+do
+  local ud = lightud(12345)
+  for i=1,100 do
+    local t = {[ud] = 42}
+    assert(t[ud] == 42)
+  end
+end
+
+-- lightuserdata ASTORE/HSTORE value
+do
+  local ud = lightud(12345)
+  local t = {}
+  for i=1,100 do
+    t[i] = ud
+  end
+  assert(t[100] == ud)
+end
+
+-- lightuserdata sync to stack
+do
+  local ud = lightud(12345)
+  local x = nil
+  for j=1,20 do
+    for i=1,50 do
+      x = ud
+    end
+    assert(x == ud)
+  end
+end
+
+-- lightuserdata vs. number type check
+do
+  local t = {}
+  for i=1,200 do t[i] = i end
+  t[180] = lightud(12345)
+  local x = 0
+  assert(not pcall(function(t)
+    for i=1,200 do x = x + t[i] end
+  end, t))
+  assert(x == 16110)
+end
+
diff --git a/test/LuaJIT-tests/misc/loop_unroll.lua b/test/LuaJIT-tests/misc/loop_unroll.lua
new file mode 100644
index 0000000..1700fac
--- /dev/null
+++ b/test/LuaJIT-tests/misc/loop_unroll.lua
@@ -0,0 +1,35 @@
+
+-- type instability on loop unroll -> record unroll
+do
+  local flip = true
+  for i=1,100 do flip = not flip end
+  assert(flip == true)
+end
+
+do
+  local t = {}
+  local a, b, c = 1, "", t
+  for i=1,100 do a,b,c=b,c,a end
+  assert(c == 1 and a == "" and b == t)
+end
+
+-- FAILFOLD on loop unroll -> LJ_TRERR_GFAIL -> record unroll
+do
+  local t = { 1, 2 }
+  local k = 2
+  local x = 0
+  for i=1,200 do
+    x = x + t[k]
+    k = k == 1 and 2 or 1
+  end
+  assert(x == 300 and k == 2)
+end
+
+-- Unroll if inner loop aborts.
+local j = 0
+for i = 1,100 do
+  repeat
+    j = j+1
+  until true
+end
+
diff --git a/test/LuaJIT-tests/misc/parse_comp.lua b/test/LuaJIT-tests/misc/parse_comp.lua
new file mode 100644
index 0000000..5e1948d
--- /dev/null
+++ b/test/LuaJIT-tests/misc/parse_comp.lua
@@ -0,0 +1,13 @@
+
+do
+  local f = {{n=5}}
+  local a = f[1].n
+  assert(1 < a)
+  assert(1 < (f[1].n))
+  assert(1 < f[1].n)
+end
+
+do
+  tt = { a = 1 }
+  assert(not(0 >= tt.a))
+end
diff --git a/test/LuaJIT-tests/misc/parse_esc.lua b/test/LuaJIT-tests/misc/parse_esc.lua
new file mode 100644
index 0000000..4bcce0e
--- /dev/null
+++ b/test/LuaJIT-tests/misc/parse_esc.lua
@@ -0,0 +1,7 @@
+assert("\79\126" == "O~")
+assert("\x4f\x7e" == "O~")
+assert(loadstring[[return "\xxx"]] == nil)
+assert(loadstring[[return "\xxx"]] == nil)
+assert(assert(loadstring[[return "abc   \z
+
+   def"]])() == "abc   def")
diff --git a/test/LuaJIT-tests/misc/parse_misc.lua b/test/LuaJIT-tests/misc/parse_misc.lua
new file mode 100644
index 0000000..8031ec1
--- /dev/null
+++ b/test/LuaJIT-tests/misc/parse_misc.lua
@@ -0,0 +1,31 @@
+
+-- Ambiguous syntax: function call vs. new statement.
+if os.getenv("LUA52") then
+  assert(assert(loadstring([[
+local function f() return 99 end
+return f
+()
+]]))() == 99)
+else
+  assert(loadstring([[
+local function f() return 99 end
+return f
+()
+]]) == nil)
+end
+
+-- UTF-8 identifiers.
+assert(loadstring([[
+local ä = 1
+local aäa = 2
+local äöü·€晶 = 3
+
+assert(ä == 1)
+assert(aäa == 2)
+assert(äöü·€晶 == 3)
+
+assert(#"ä" == 2)
+assert(#"aäa" == 4)
+assert(#"äöü·€晶" == 14)
+]]))()
+
diff --git a/test/LuaJIT-tests/misc/phi_conv.lua b/test/LuaJIT-tests/misc/phi_conv.lua
new file mode 100644
index 0000000..8d7bea5
--- /dev/null
+++ b/test/LuaJIT-tests/misc/phi_conv.lua
@@ -0,0 +1,53 @@
+
+local bit = require("bit")
+
+local Rm = {}
+for i=0,16 do Rm[i] = 0 end
+
+for k=1,10 do
+  local seed = 1
+  for i=16,0,-1 do
+    seed = bit.band(seed*9069, 0x7fffffff)
+    Rm[i] = seed
+  end
+  assert(seed == 1952688301)
+end
+
+local retindex = 0
+local retdata = { 3, 1, 1, 1, 0, 3, 1, 0, 0, 2, 0, 2, 0, 0, 3, 1, 1, 1, 1 }
+
+local function get_bits()
+  retindex = retindex + 1
+  return retdata[retindex]
+end
+
+local hufcodes = { [0] = true, [4] = true, [11] = true, [36] = true, [68] = true }
+
+local maskhuf = { 0x0002, 0x0003, 0x0004, 0x0005, }
+
+local function decodeCode()
+  local lookup = get_bits()
+  local code = hufcodes[lookup]
+  local z = {1,1,1,1}
+  if not code then
+    for i = 1, 4 do
+      lookup = bit.bor(lookup, bit.lshift(get_bits(), i + 1))
+      -- need PHI for CONV num.int of lookup, used in snapshot
+      code = hufcodes[lookup + maskhuf[i]]
+      if code then break end
+    end
+  end
+  assert(code)
+  return code
+end
+
+local function test()
+  for i = 1, 6 do
+    decodeCode()
+  end
+end
+
+if jit and jit.status and jit.status() then jit.opt.start("hotloop=1") end
+
+test()
+
diff --git a/test/LuaJIT-tests/misc/recurse_deep.lua b/test/LuaJIT-tests/misc/recurse_deep.lua
new file mode 100644
index 0000000..9b9af29
--- /dev/null
+++ b/test/LuaJIT-tests/misc/recurse_deep.lua
@@ -0,0 +1,29 @@
+
+do
+  local function sum(n)
+    if n == 1 then return 1 end
+    return n + sum(n-1)
+  end
+  assert(sum(200) == 20100)
+end
+
+do
+  local pcall = pcall
+  local tr1
+  local x = 0
+  function tr1(n)
+    if n <= 0 then return end
+    x = x + 1
+    return pcall(tr1, n-1)
+  end
+  assert(tr1(200) == true and x == 200)
+end
+
+do
+  local function fib(n)
+    if n < 2 then return 1 end
+    return fib(n-2) + fib(n-1)
+  end
+  assert(fib(15) == 987)
+end
+
diff --git a/test/LuaJIT-tests/misc/recurse_tail.lua b/test/LuaJIT-tests/misc/recurse_tail.lua
new file mode 100644
index 0000000..ef76443
--- /dev/null
+++ b/test/LuaJIT-tests/misc/recurse_tail.lua
@@ -0,0 +1,22 @@
+
+do
+  local tr1
+  function tr1(n)
+    if n <= 0 then return 0 end
+    return tr1(n-1)
+  end
+  assert(tr1(200) == 0)
+end
+
+do
+  local tr1, tr2
+  function tr1(n)
+    if n <= 0 then return 0 end
+    return tr2(n-1)
+  end
+  function tr2(n)
+    return tr1(n)
+  end
+  assert(tr2(200) == 0)
+end
+
diff --git a/test/LuaJIT-tests/misc/stack_gc.lua b/test/LuaJIT-tests/misc/stack_gc.lua
new file mode 100644
index 0000000..656a06a
--- /dev/null
+++ b/test/LuaJIT-tests/misc/stack_gc.lua
@@ -0,0 +1,15 @@
+
+do
+  local t = setmetatable({}, { __index=function(t, k)
+    k = k - 1
+    if k == 0 then
+      collectgarbage() -- Mark stack, including holes.
+      return 0
+    else
+      return t[k] -- Leaves holes in each frame.
+    end
+    do local a,b,c,d,e,f,g,h,i,j,k,l,m,n end -- Ensure bigger frame size.
+  end})
+  local x = t[50]
+end
+
diff --git a/test/LuaJIT-tests/misc/stack_purge.lua b/test/LuaJIT-tests/misc/stack_purge.lua
new file mode 100644
index 0000000..bfaee0f
--- /dev/null
+++ b/test/LuaJIT-tests/misc/stack_purge.lua
@@ -0,0 +1,25 @@
+
+-- Must preserve the modified function slot in the RET snapshot.
+local function a()
+  local _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_
+  local _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_
+  local _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_
+  return 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+end
+
+local function b()
+  return a()
+end
+
+local function c()
+  for j=1,10 do
+    for i=1,50 do b() b() b() end
+    collectgarbage()
+    local t = {}
+    for i=1,50 do t = {t} end
+  end
+end
+
+jit.off(c)
+c()
+
diff --git a/test/LuaJIT-tests/misc/stackov.lua b/test/LuaJIT-tests/misc/stackov.lua
new file mode 100644
index 0000000..ef105af
--- /dev/null
+++ b/test/LuaJIT-tests/misc/stackov.lua
@@ -0,0 +1,40 @@
+
+local function f()
+  f()
+end
+
+local err, s = xpcall(f, debug.traceback)
+assert(err == false)
+
+local first = string.match(s, "[^\n]+")
+local line = debug.getinfo(f, "S").linedefined+1
+assert(string.match(first, ":"..line..": stack overflow$"))
+
+local n = 1
+for _ in string.gmatch(s, "\n") do n = n + 1 end
+assert(n == 1+1+11+1+10)
+
+local function g(i)
+  g(i)
+end
+
+local err, s = xpcall(g, debug.traceback, 1)
+assert(err == false)
+
+--[[
+-- too slow
+local function vtail(...)
+  return vtail(1, ...)
+end
+
+local err, s = xpcall(vtail, debug.traceback, 1)
+assert(err == false)
+--]]
+
+local function vcall(...)
+  vcall(1, ...)
+end
+
+local err, s = xpcall(vcall, debug.traceback, 1)
+assert(err == false)
+
diff --git a/test/LuaJIT-tests/misc/stackovc.lua b/test/LuaJIT-tests/misc/stackovc.lua
new file mode 100644
index 0000000..c00bcbd
--- /dev/null
+++ b/test/LuaJIT-tests/misc/stackovc.lua
@@ -0,0 +1,4 @@
+local j = 1e4
+local co = coroutine.create(function() t = {} for i = 1, j do t[i] = i end return unpack(t) end)
+local ok, err = coroutine.resume(co)
+assert(not ok and string.find(err, "unpack"))
diff --git a/test/LuaJIT-tests/misc/tcall_base.lua b/test/LuaJIT-tests/misc/tcall_base.lua
new file mode 100644
index 0000000..c6c4ae1
--- /dev/null
+++ b/test/LuaJIT-tests/misc/tcall_base.lua
@@ -0,0 +1,20 @@
+
+local r = 0
+local function g()
+  r = r + 1
+  for i=1,100 do end
+end
+
+local function f()
+  for j=1,20 do
+    if j > 19 then
+      return g() -- Tailcall at base.
+      -- Let this link to the already compiled loop in g().
+    end
+  end
+end
+
+g() -- Compile this loop first.
+for i=1,50 do f() end
+assert(r == 51)
+
diff --git a/test/LuaJIT-tests/misc/tcall_loop.lua b/test/LuaJIT-tests/misc/tcall_loop.lua
new file mode 100644
index 0000000..d3c6f1a
--- /dev/null
+++ b/test/LuaJIT-tests/misc/tcall_loop.lua
@@ -0,0 +1,8 @@
+local function f(i)
+  if i > 0 then return f(i-1) end
+  return 1
+end
+
+local x = 0
+for i=1,100 do x = x + f(1000) end
+assert(x == 100)
diff --git a/test/LuaJIT-tests/misc/tonumber_scan.lua b/test/LuaJIT-tests/misc/tonumber_scan.lua
new file mode 100644
index 0000000..78e1ca3
--- /dev/null
+++ b/test/LuaJIT-tests/misc/tonumber_scan.lua
@@ -0,0 +1,180 @@
+local ffi = require("ffi")
+local bit = require("bit")
+
+ffi.cdef[[
+double strtod(const char *, char **);
+]]
+
+local t = {
+  -- errors
+  false, "",
+  false, " ",
+  false, "+",
+  false, "z",
+  false, ".",
+  false, ".z",
+  false, "0.z",
+  false, ".0z",
+  false, "0xz",
+  false, "0x.z",
+  false, "0x0.z",
+  false, "0x.0z",
+  false, ".e5",
+  false, ".p4",
+  false, "1.p4",
+  false, "1.p+4",
+  false, "0x1.e+4",
+  false, "infi",
+  false, "+ 1",
+  false, "- 9",
+  -- misc
+  0x3ff0000000000000ULL, " \t\n\v\f\r 1",
+  -- inf/nan
+  0x7ff0000000000000ULL, "iNF",
+  0xfff0000000000000ULL, "-Inf",
+  0x7ff0000000000000ULL, "+iNfInItY",
+  0xfff0000000000000ULL, "-INFINITY",
+  0xfff8000000000000ULL, "naN",
+  0xfff8000000000000ULL, "+NaN",
+  0xfff8000000000000ULL, "-nAn",
+  -- smallest/largest numbers
+  0x0000000000000000ULL, "0e1000",
+  0x0000000000000000ULL, "0e-1000",
+  0x0000000000000000ULL, "0x0p2000",
+  0x0000000000000000ULL, "0x0p-2000",
+  0x7ff0000000000000ULL, "1e1000",
+  0x0000000000000000ULL, "1e-1000",
+  0xfff0000000000000ULL, "-1e1000",
+-- wrong for DUALNUM: 0x8000000000000000ULL, "-1e-1000",
+  0x7ff0000000000000ULL, "0x1p2000",
+  0x0000000000000000ULL, "0x1p-2000",
+  0xfff0000000000000ULL, "-0x1p2000",
+-- wrong for DUALNUM: 0x8000000000000000ULL, "-0x1p-2000",
+  0x0010000000000000ULL, "2.2250738585072014e-308",
+  0x7fefffffffffffffULL, "1.7976931348623158e+308",
+  0x8000b8157268fdafULL, "-1e-309",
+  0x000ac941b426dd3bULL, "1.5e-308",
+  0x000ac941b426dd3bULL, "0x0.ac941b426dd3b7p-1022",
+  0x0000000000000001ULL, "4.9406564584124654e-324",
+  0x000f9c7573d7fe52ULL, "2.171e-308",
+  0x241d21ecf36d4a22ULL, "1.0020284025808569e-134",
+  0x0000000000000001ULL, "0x1p-1074",
+  0x0000000000000000ULL, "0x1p-1075",
+  0x0000000000000000ULL, "0x1p-1076",
+  0x0000000000000000ULL, "0x0.ffffffffffffffffffffffffffp-1075",
+  0x0000000000000000ULL, "0x1.00000000000000000000000000p-1075",
+  0x0000000000000001ULL, "0x1.00000000000000000000000001p-1075",
+  0x7fe0000000000000ULL, "0x1p1023",
+  0x7ff0000000000000ULL, "0x1p1024",
+  0x7ff0000000000000ULL, "0x1p1025",
+  0x7ff0000000000000ULL, "0x3p1023",
+  0x7ff0000000000000ULL, "0x3.ffffffffffffecp1023",
+  0xfff0000000000000ULL, "-0xf7dcba98765432p969",
+  0x7fefffffffffffffULL, "0x1.fffffffffffff0000000000000p1023",
+  0x7fefffffffffffffULL, "0x1.fffffffffffff0000000000001p1023",
+  0x7fefffffffffffffULL, "0x1.fffffffffffff7ffffffffffffp1023",
+  0x7ff0000000000000ULL, "0x1.fffffffffffff8000000000000p1023",
+  0x7fefffffffffffffULL, "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0",
+  0x7fefffffffffffffULL, "179769313486231580793728971405303415079934132710037826936173778980444968292764750946649017977587207096330286416692887910946555547851940402630657488671505820681908902000708383676273854845817711531764475730270069855571366959622842914819860834936475292719074168444365510704342711559699508093042880177904174497791.999",
+  0x7ff0000000000000ULL, "179769313486231580793728971405303415079934132710037826936173778980444968292764750946649017977587207096330286416692887910946555547851940402630657488671505820681908902000708383676273854845817711531764475730270069855571366959622842914819860834936475292719074168444365510704342711559699508093042880177904174497792.0",
+  0x3ff0000000000000ULL, "0x100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000p-1028",
+  0x1214e2995454ee0bULL, "0."..string.rep("0", 220).."1"..string.rep("4", 800),
+  -- http://www.exploringbinary.com/15-digit-quick-and-dirty-conversions-dont-round-trip/
+  0x04409cf3929ffbc3ULL, "3.409452297963e-288",
+  0x7fe02b4782a6c378ULL, "9.08344e+307",
+  0x6e05e258a3929ee5ULL, "9.88819e+221",
+  -- http://www.exploringbinary.com/incorrectly-rounded-conversions-in-gcc-and-glibc/
+  0x3fe0000000000002ULL, "0.500000000000000166533453693773481063544750213623046875",
+  0x42c0000000000002ULL, "3.518437208883201171875e13",
+  0x404f44abd5aa7ca4ULL, "62.5364939768271845828",
+  0x3e0bd5cbaef0fd0cULL, "8.10109172351e-10",
+  0x3ff8000000000000ULL, "1.50000000000000011102230246251565404236316680908203125",
+  0x433fffffffffffffULL, "9007199254740991.4999999999999999999999999999999995",
+  0x7ecd2e77eb6e3fadULL, "6.253649397682718e+302",
+  0x7ecd2e77eb6e3fadULL, "6.2536493976827180e+302",
+  -- http://www.exploringbinary.com/incorrectly-rounded-conversions-in-visual-c-plus-plus/
+  0x43405e6cec57761aULL, "9214843084008499",
+  0x3fe0000000000002ULL, "0.500000000000000166533453693773481063544750213623046875",
+  0x44997a3c7271b021ULL, "30078505129381147446200",
+  0x4458180d5bad2e3eULL, "1777820000000000000001",
+  0x3fe0000000000002ULL, "0.500000000000000166547006220929549868969843373633921146392822265625",
+  0x3fe0000000000002ULL, "0.50000000000000016656055874808561867439493653364479541778564453125",
+  0x3fd92bb352c4623aULL, "0.3932922657273",
+  -- http://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
+  0x0010000000000000ULL, "2.2250738585072012e-308",
+  -- http://www.exploringbinary.com/incorrectly-rounded-subnormal-conversions-in-java/
+  0x0000000008000000ULL, "6.631236871469758276785396630275967243399099947355303144249971758736286630139265439618068200788048744105960420552601852889715006376325666595539603330361800519107591783233358492337208057849499360899425128640718856616503093444922854759159988160304439909868291973931426625698663157749836252274523485312442358651207051292453083278116143932569727918709786004497872322193856150225415211997283078496319412124640111777216148110752815101775295719811974338451936095907419622417538473679495148632480391435931767981122396703443803335529756003353209830071832230689201383015598792184172909927924176339315507402234836120730914783168400715462440053817592702766213559042115986763819482654128770595766806872783349146967171293949598850675682115696218943412532098591327667236328125e-316",
+  0x0000000000010000ULL, "3.237883913302901289588352412501532174863037669423108059901297049552301970670676565786835742587799557860615776559838283435514391084153169252689190564396459577394618038928365305143463955100356696665629202017331344031730044369360205258345803431471660032699580731300954848363975548690010751530018881758184174569652173110473696022749934638425380623369774736560008997404060967498028389191878963968575439222206416981462690113342524002724385941651051293552601421155333430225237291523843322331326138431477823591142408800030775170625915670728657003151953664260769822494937951845801530895238439819708403389937873241463484205608000027270531106827387907791444918534771598750162812548862768493201518991668028251730299953143924168545708663913273994694463908672332763671875e-319",
+  0x0000800000000100ULL, "6.953355807847677105972805215521891690222119817145950754416205607980030131549636688806115726399441880065386399864028691275539539414652831584795668560082999889551357784961446896042113198284213107935110217162654939802416034676213829409720583759540476786936413816541621287843248433202369209916612249676005573022703244799714622116542188837770376022371172079559125853382801396219552418839469770514904192657627060319372847562301074140442660237844114174497210955449896389180395827191602886654488182452409583981389442783377001505462015745017848754574668342161759496661766020028752888783387074850773192997102997936619876226688096314989645766000479009083731736585750335262099860150896718774401964796827166283225641992040747894382698751809812609536720628966577351093292236328125e-310",
+  0x0000000000010800ULL, "3.339068557571188581835713701280943911923401916998521771655656997328440314559615318168849149074662609099998113009465566426808170378434065722991659642619467706034884424989741080790766778456332168200464651593995817371782125010668346652995912233993254584461125868481633343674905074271064409763090708017856584019776878812425312008812326260363035474811532236853359905334625575404216060622858633280744301892470300555678734689978476870369853549413277156622170245846166991655321535529623870646888786637528995592800436177901746286272273374471701452991433047257863864601424252024791567368195056077320885329384322332391564645264143400798619665040608077549162173963649264049738362290606875883456826586710961041737908872035803481241600376705491726170293986797332763671875e-319",
+  -- EGLIBC 2.16 tests
+  0x4028b0a3d70a3d71ULL, "12.345",
+  0x441ac4da03bc47e4ULL, "12.345e19",
+  0xc197d78400000000ULL, "-.1e+9",
+  0x3fc0000000000000ULL, ".125",
+  0x4415af1d78b58c40ULL, "1e20",
+  0x0000000000000000ULL, "0e-19",
+  0x3051144f2d9a718bULL, "5.9e-76",
+  0x4024000000000000ULL, "0x1.4p+3",
+  0x4024000000000000ULL, "0xAp0",
+  0x4024000000000000ULL, "0x0Ap0",
+  0x4024000000000000ULL, "0x0A",
+  0x4064000000000000ULL, "0xA0",
+  0x4064000000000000ULL, "0x0.A0p8",
+  0x4064000000000000ULL, "0x0.50p9",
+  0x4064000000000000ULL, "0x0.28p10",
+  0x4064000000000000ULL, "0x0.14p11",
+  0x4064000000000000ULL, "0x0.0A0p12",
+  0x4064000000000000ULL, "0x0.050p13",
+  0x4064000000000000ULL, "0x0.028p14",
+  0x4064000000000000ULL, "0x0.014p15",
+  0x4064000000000000ULL, "0x00.00A0p16",
+  0x4064000000000000ULL, "0x00.0050p17",
+  0x4064000000000000ULL, "0x00.0028p18",
+  0x4064000000000000ULL, "0x00.0014p19",
+  0x0008000000000000ULL, "0x1p-1023",
+  0x0008000000000000ULL, "0x0.8p-1022",
+  0x3ff0000140000000ULL, "0x80000Ap-23",
+  0x0000000000000000ULL, "1e-324",
+  0x4370000000000000ULL, "0x100000000000008p0",
+  0x4370000000000000ULL, "0x100000000000008.p0",
+  0x4370000000000000ULL, "0x100000000000008.00p0",
+  0x43f0000000000000ULL, "0x10000000000000800p0",
+  0x43f0000000000001ULL, "0x10000000000000801p0",
+  -- Fuzzing
+  0x699783fbf2d24ea5ULL, "449999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999.9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999",
+  0x43f158e460913d00ULL, "2e19",
+}
+
+local function tohex64(x)
+  return "0x"..bit.tohex(tonumber(x/2LL^32))..bit.tohex(tonumber(x%2LL^32)).."ULL"
+end
+
+local conv = tonumber
+
+if arg and arg[1] == "strtod" then
+  local e = ffi.new("char *[1]")
+  function conv(s)
+    local d = ffi.C.strtod(s, e)
+    return (e[0][0] == 0 and #s ~= 0) and d or nil
+  end
+end
+
+local u = ffi.new("union { double d; uint64_t x; }")
+
+for i=1,#t,2 do
+  local y, s = t[i], t[i+1]
+  local d = conv(s)
+  local ok
+  if d == nil then
+    ok = (y == false)
+  else
+    u.d = d
+    ok = (y == u.x)
+  end
+  if not ok then
+    io.write('FAIL: "', s, '"\n GOT: ', d and tohex64(u.x) or "nil", "   OK: ", y and tohex64(y) or "nil", "\n\n")
+--      print("  "..tohex64(u.x)..", \""..s.."\",")
+  end
+end
+
diff --git a/test/LuaJIT-tests/misc/uclo.lua b/test/LuaJIT-tests/misc/uclo.lua
new file mode 100644
index 0000000..bd9bd24
--- /dev/null
+++ b/test/LuaJIT-tests/misc/uclo.lua
@@ -0,0 +1,91 @@
+
+local function test_for()
+  local z1, z2
+  for i=1,10 do
+    local function f() return i end
+    if z1 then z2 = f else z1 = f end
+  end
+  assert(z1() == 1)
+  assert(z2() == 10)
+end
+
+local function test_while()
+  local z1, z2
+  local i = 1
+  while i <= 10 do
+    local j = i
+    local function f() return j end
+    if z1 then z2 = f else z1 = f end
+    i = i + 1
+  end
+  assert(z1() == 1)
+  assert(z2() == 10)
+end
+
+local function test_repeat()
+  local z1, z2
+  local i = 1
+  repeat
+    local j = i
+    local function f() return j end
+    if z1 then z2 = f else z1 = f end
+    i = i + 1
+  until i > 10
+  assert(z1() == 1)
+  assert(z2() == 10)
+end
+
+local function test_func()
+  local function ff(x)
+    return function() return x end
+  end
+  local z1, z2
+  for i=1,10 do
+    local f = ff(i)
+    if z1 then z2 = f else z1 = f end
+  end
+  assert(z1() == 1)
+  assert(z2() == 10)
+end
+
+test_for()
+test_while()
+test_repeat()
+test_func()
+
+do
+  local function f1(a)
+    if a > 0 then
+      local b = f1(a - 1)
+      return function()
+	if type(b) == "function" then
+	  return a + b()
+	end
+	return a + b
+      end
+    end
+    return a
+  end
+
+  local function f2(a)
+    return f1(a)()
+  end
+
+  for i = 1, 41 do
+    local r = f2(4) + f2(4)
+  end
+end
+
+-- Don't mark upvalue as immutable if written to after prototype definition.
+do
+  local x = 1
+  local function f()
+    local y = 0
+    for i=1,100 do y=y+x end
+    return y
+  end
+  assert(f() == 100)
+  x = 2
+  assert(f() == 200)
+end
+
diff --git a/test/LuaJIT-tests/misc/unordered_jit.lua b/test/LuaJIT-tests/misc/unordered_jit.lua
new file mode 100644
index 0000000..5ff1a1b
--- /dev/null
+++ b/test/LuaJIT-tests/misc/unordered_jit.lua
@@ -0,0 +1,96 @@
+
+local nan = 0/0
+local t = {}
+for i=1,100 do t[i] = i+0.5 end
+for i=101,200 do t[i] = nan end
+
+do
+  local z = 0
+  for i=1,200 do if t[i] > 1000 then z=i end end
+  assert(z == 0)
+end
+
+do
+  local z = 0
+  for i=1,200 do if not (t[i] < 1000) then z=i end end
+  assert(z == 200)
+end
+
+do
+  local z = 0
+  for i=1,200 do if t[i] <= 1000 then z=i end end
+  assert(z == 100)
+end
+
+do
+  local z = 0
+  for i=1,200 do if not (t[i] >= 1000) then z=i end end
+  assert(z == 200)
+end
+
+do
+  local z = 0
+  for i=1,200 do if t[i] > 0 then z=i end end
+  assert(z == 100)
+end
+
+do
+  local z = 0
+  for i=1,200 do if not (t[i] < 0) then z=i end end
+  assert(z == 200)
+end
+
+do
+  local z = 0
+  for i=1,200 do if t[i] <= 0 then z=i end end
+  assert(z == 0)
+end
+
+do
+  local z = 0
+  for i=1,200 do if not (t[i] >= 0) then z=i end end
+  assert(z == 200)
+end
+
+do local z; for i=1,100 do z = 0/0 end; assert(z ~= z) end
+
+do local z; for i=1,100 do z = nan == nan end; assert(z == false) end
+do local z; for i=1,100 do z = nan == 1 end; assert(z == false) end
+do local z; for i=1,100 do z = 1 == nan end; assert(z == false) end
+
+do local z; for i=1,100 do z = nan ~= nan end; assert(z == true) end
+do local z; for i=1,100 do z = nan ~= 1 end; assert(z == true) end
+do local z; for i=1,100 do z = 1 ~= nan end; assert(z == true) end
+
+do local z; for i=1,100 do z = nan < nan end; assert(z == false) end
+do local z; for i=1,100 do z = nan < 1 end; assert(z == false) end
+do local z; for i=1,100 do z = 1 < nan end; assert(z == false) end
+
+do local z; for i=1,100 do z = not (nan < nan) end; assert(z == true) end
+do local z; for i=1,100 do z = not (nan < 1) end; assert(z == true) end
+do local z; for i=1,100 do z = not (1 < nan) end; assert(z == true) end
+
+do local z; for i=1,100 do z = nan > nan end; assert(z == false) end
+do local z; for i=1,100 do z = nan > 1 end; assert(z == false) end
+do local z; for i=1,100 do z = 1 > nan end; assert(z == false) end
+
+do local z; for i=1,100 do z = not (nan > nan) end; assert(z == true) end
+do local z; for i=1,100 do z = not (nan > 1) end; assert(z == true) end
+do local z; for i=1,100 do z = not (1 > nan) end; assert(z == true) end
+
+do local z; for i=1,100 do z = nan <= nan end; assert(z == false) end
+do local z; for i=1,100 do z = nan <= 1 end; assert(z == false) end
+do local z; for i=1,100 do z = 1 <= nan end; assert(z == false) end
+
+do local z; for i=1,100 do z = not (nan <= nan) end; assert(z == true) end
+do local z; for i=1,100 do z = not (nan <= 1) end; assert(z == true) end
+do local z; for i=1,100 do z = not (1 <= nan) end; assert(z == true) end
+
+do local z; for i=1,100 do z = nan >= nan end; assert(z == false) end
+do local z; for i=1,100 do z = nan >= 1 end; assert(z == false) end
+do local z; for i=1,100 do z = 1 >= nan end; assert(z == false) end
+
+do local z; for i=1,100 do z = not (nan >= nan) end; assert(z == true) end
+do local z; for i=1,100 do z = not (nan >= 1) end; assert(z == true) end
+do local z; for i=1,100 do z = not (1 >= nan) end; assert(z == true) end
+
diff --git a/test/LuaJIT-tests/misc/wbarrier.lua b/test/LuaJIT-tests/misc/wbarrier.lua
new file mode 100644
index 0000000..5536625
--- /dev/null
+++ b/test/LuaJIT-tests/misc/wbarrier.lua
@@ -0,0 +1,7 @@
+local t={}
+for i=1,20000 do
+  t[i] = tostring(i)
+end
+for i=1,#t do
+  assert(t[i] == tostring(i))
+end
diff --git a/test/LuaJIT-tests/misc/wbarrier_jit.lua b/test/LuaJIT-tests/misc/wbarrier_jit.lua
new file mode 100644
index 0000000..2c8dd7f
--- /dev/null
+++ b/test/LuaJIT-tests/misc/wbarrier_jit.lua
@@ -0,0 +1,18 @@
+
+do
+  local t = {[0]={}}
+  for i=1,1e5 do t[i] = {t[i-1]} end
+  for i=1,1e5 do assert(t[i][1] == t[i-1]) end
+end
+
+do
+  local f
+  do
+    local x = 0
+    function f()
+      for i=1,1e5 do x = {i} end
+    end
+  end
+  f()
+end
+
diff --git a/test/LuaJIT-tests/misc/wbarrier_obar.lua b/test/LuaJIT-tests/misc/wbarrier_obar.lua
new file mode 100644
index 0000000..258db21
--- /dev/null
+++ b/test/LuaJIT-tests/misc/wbarrier_obar.lua
@@ -0,0 +1,22 @@
+-- DSE of USTORE must eliminate OBAR, too.
+
+if jit and jit.opt then pcall(jit.opt.start, "-sink") end
+
+local f
+do
+  local x
+  f = function()
+    local y = 0
+    for i=1,10000 do
+      x = {1}
+      if y > 0 then end
+      x = 1
+    end
+  end
+end
+
+collectgarbage()
+collectgarbage("setstepmul", 1)
+collectgarbage("restart")
+f()
+
diff --git a/test/LuaJIT-tests/opt/dse/array.lua b/test/LuaJIT-tests/opt/dse/array.lua
new file mode 100644
index 0000000..8c76624
--- /dev/null
+++ b/test/LuaJIT-tests/opt/dse/array.lua
@@ -0,0 +1,197 @@
+local assert = assert
+
+-- Same value ----------------------------------------------------------------
+
+do --- 1
+-- Store with same ref and same value.
+-- 2nd store eliminated. All stores in loop eliminated.
+  local t = { 1, 2 }
+  for i=1,100 do
+    t[1] = 11
+    assert(t[1] == 11)
+    t[1] = 11
+    assert(t[1] == 11)
+  end
+  assert(t[1] == 11)
+end
+
+do --- 2
+-- Store with different tab, same idx and same value.
+-- All stores in loop eliminated.
+  local t1 = { 1, 2 }
+  local t2 = { 1, 2 }
+  for i=1,100 do
+    t1[1] = 11
+    assert(t1[1] == 11)
+    t2[1] = 11
+    assert(t2[1] == 11)
+  end
+  assert(t1[1] == 11)
+  assert(t2[1] == 11)
+end
+
+do --- 3
+-- Store with same tab, different const idx and same value.
+-- All stores in loop eliminated. Also disambiguated.
+  local t = { 1, 2 }
+  for i=1,100 do
+    t[1] = 11
+    assert(t[1] == 11)
+    t[2] = 11
+    assert(t[2] == 11)
+  end
+  assert(t[1] == 11)
+  assert(t[2] == 11)
+end
+
+do --- 4
+-- Store with different tab, different const idx and same value.
+-- All stores in loop eliminated. Also disambiguated.
+  local t1 = { 1, 2 }
+  local t2 = { 1, 2 }
+  for i=1,100 do
+    t1[1] = 11
+    assert(t1[1] == 11)
+    t2[2] = 11
+    assert(t2[2] == 11)
+  end
+  assert(t1[1] == 11)
+  assert(t2[2] == 11)
+end
+
+do --- 5
+-- Store with different tab, different non-const idx and same value.
+-- All stores in loop eliminated. Not disambiguated (but not needed).
+  local t1 = { 1, 2 }
+  local t2 = { 1, 2 }
+  local k = 1
+  for i=1,100 do
+    t1[k] = 11
+    assert(t1[k] == 11)
+    t2[2] = 11
+    assert(t2[2] == 11)
+  end
+  assert(t1[1] == 11)
+  assert(t2[2] == 11)
+end
+
+do --- 6
+-- Store with same ref, same value and aliased loads.
+-- 2nd store eliminated. Not disambiguated (but not needed).
+  local t1 = { 1, 2 }
+  local t2 = t1
+  for i=1,100 do
+    t1[1] = 11
+    assert(t2[1] == 11)
+    t1[1] = 11
+    assert(t2[1] == 11)
+  end
+  assert(t1[1] == 11)
+end
+
+-- Different value -----------------------------------------------------------
+
+do --- 7
+-- Store with same ref and different value.
+-- 1st store eliminated. All stores in loop eliminated.
+  local t = { 1, 2 }
+  for i=1,100 do
+    assert(true)
+    t[1] = 11
+    assert(t[1] == 11)
+    t[1] = 22
+    assert(t[1] == 22)
+  end
+  assert(t[1] == 22)
+end
+
+do --- 8
+-- Store with different tab, same idx and different value.
+-- Cannot eliminate any stores (would need dynamic disambiguation).
+  local t1 = { 1, 2 }
+  local t2 = { 1, 2 }
+  for i=1,100 do
+    assert(true)
+    t1[1] = 11
+    assert(t1[1] == 11)
+    t2[1] = 22
+    assert(t2[1] == 22)
+  end
+  assert(t1[1] == 11)
+  assert(t2[1] == 22)
+end
+
+do --- 9
+-- Store with same tab, different const idx and different value.
+-- Disambiguated. All stores in loop eliminated.
+  local t = { 1, 2 }
+  for i=1,100 do
+    assert(true)
+    t[1] = 11
+    assert(t[1] == 11)
+    t[2] = 22
+    assert(t[2] == 22)
+  end
+  assert(t[1] == 11)
+  assert(t[2] == 22)
+end
+
+do --- 10
+-- Store with different tab, different const idx and different value.
+-- Disambiguated. All stores in loop eliminated.
+  local t1 = { 1, 2 }
+  local t2 = { 1, 2 }
+  for i=1,100 do
+    assert(true)
+    t1[1] = 11
+    assert(t1[1] == 11)
+    t2[2] = 22
+    assert(t2[2] == 22)
+  end
+  assert(t1[1] == 11)
+  assert(t2[2] == 22)
+end
+
+do --- 11
+-- Store with different tab, different non-const idx and different value.
+-- Cannot eliminate any stores (would need dynamic disambiguation).
+  local t1 = { 1, 2 }
+  local t2 = { 1, 2 }
+  local k = 1
+  for i=1,100 do
+    assert(true)
+    t1[k] = 11
+    assert(t1[k] == 11)
+    t2[2] = 22
+    assert(t2[2] == 22)
+  end
+  assert(t1[1] == 11)
+  assert(t2[2] == 22)
+end
+
+do --- 12
+-- Store with same ref, different value and aliased loads.
+-- Cannot eliminate any stores (would need dynamic disambiguation).
+  local t1 = { 1, 2 }
+  local t2 = t1
+  for i=1,100 do
+    assert(true)
+    t1[1] = 11
+    assert(t2[1] == 11)
+    t1[1] = 22
+    assert(t2[1] == 22)
+  end
+  assert(t1[1] == 22)
+end
+
+do --- CALLL must inhibit DSE.
+  local a,b
+  local t = {1,2}
+  for i=1,100 do
+    t[2]=nil
+    a=#t
+    t[2]=2
+    b=#t
+  end
+  assert(a == 1 and b == 2)
+end
diff --git a/test/LuaJIT-tests/opt/dse/field.lua b/test/LuaJIT-tests/opt/dse/field.lua
new file mode 100644
index 0000000..d8a5411
--- /dev/null
+++ b/test/LuaJIT-tests/opt/dse/field.lua
@@ -0,0 +1,70 @@
+local getmetatable, setmetatable = getmetatable, setmetatable
+
+do --- 1. Store with same ref and same value. All stores in loop eliminated.
+  local mt = {}
+  local t = {}
+  for i=1,100 do
+    setmetatable(t, mt)
+    assert(getmetatable(t) == mt)
+    setmetatable(t, mt)
+    assert(getmetatable(t) == mt)
+  end
+  assert(getmetatable(t) == mt)
+end
+
+do --- 2. Store with different ref and same value. All stores in loop eliminated.
+  local mt = {}
+  local t1 = {}
+  local t2 = {}
+  for i=1,100 do
+    setmetatable(t1, mt)
+    assert(getmetatable(t1) == mt)
+    setmetatable(t2, mt)
+    assert(getmetatable(t2) == mt)
+  end
+  assert(getmetatable(t1) == mt)
+  assert(getmetatable(t2) == mt)
+end
+
+do --- 3. Store with different ref and different value. Cannot eliminate any stores.
+  local mt1 = {}
+  local mt2 = {}
+  local t1 = {}
+  local t2 = {}
+  for i=1,100 do
+    setmetatable(t1, mt1)
+    assert(getmetatable(t1) == mt1)
+    setmetatable(t2, mt2)
+    assert(getmetatable(t2) == mt2)
+  end
+  assert(getmetatable(t1) == mt1)
+  assert(getmetatable(t2) == mt2)
+end
+
+do --- 4. Store with same ref and different value. 2nd store remains in loop.
+  local mt1 = {}
+  local mt2 = {}
+  local t = {}
+  for i=1,100 do
+    setmetatable(t, mt1)
+    assert(getmetatable(t) == mt1)
+    setmetatable(t, mt2)
+    assert(getmetatable(t) == mt2)
+  end
+  assert(getmetatable(t) == mt2)
+end
+
+do --- 5. Store with same ref, different value and aliased loads.
+--        Cannot eliminate any stores.
+  local mt1 = {}
+  local mt2 = {}
+  local t1 = {}
+  local t2 = t1
+  for i=1,100 do
+    setmetatable(t1, mt1)
+    assert(getmetatable(t2) == mt1)
+    setmetatable(t1, mt2)
+    assert(getmetatable(t2) == mt2)
+  end
+  assert(getmetatable(t1) == mt2)
+end
diff --git a/test/LuaJIT-tests/opt/dse/index b/test/LuaJIT-tests/opt/dse/index
new file mode 100644
index 0000000..7b8ad1f
--- /dev/null
+++ b/test/LuaJIT-tests/opt/dse/index
@@ -0,0 +1,2 @@
+array.lua
+field.lua
diff --git a/test/LuaJIT-tests/opt/fold/index b/test/LuaJIT-tests/opt/fold/index
new file mode 100644
index 0000000..8b4648c
--- /dev/null
+++ b/test/LuaJIT-tests/opt/fold/index
@@ -0,0 +1 @@
+kfold.lua
diff --git a/test/LuaJIT-tests/opt/fold/kfold.lua b/test/LuaJIT-tests/opt/fold/kfold.lua
new file mode 100644
index 0000000..9cd3919
--- /dev/null
+++ b/test/LuaJIT-tests/opt/fold/kfold.lua
@@ -0,0 +1,81 @@
+do --- operators
+  local y = 0
+  for i=1,100 do local a, b = 23, 11; y = a+b end; assert(y == 23+11)
+  for i=1,100 do local a, b = 23, 11; y = a-b end; assert(y == 23-11)
+  for i=1,100 do local a, b = 23, 11; y = a*b end; assert(y == 23*11)
+  for i=1,100 do local a, b = 23, 11; y = a/b end; assert(y == 23/11)
+  for i=1,100 do local a, b = 23, 11; y = a%b end; assert(y == 23%11)
+  for i=1,100 do local a, b = 23, 11; y = a^b end; assert(y == 23^11)
+
+  for i=1,100 do local a, b = 23.5, 11.5; y = a+b end; assert(y == 23.5+11.5)
+  for i=1,100 do local a, b = 23.5, 11.5; y = a-b end; assert(y == 23.5-11.5)
+  for i=1,100 do local a, b = 23.5, 11.5; y = a*b end; assert(y == 23.5*11.5)
+  for i=1,100 do local a, b = 23.5, 11.5; y = a/b end; assert(y == 23.5/11.5)
+  for i=1,100 do local a, b = 23.5, 11.5; y = a%b end; assert(y == 23.5%11.5)
+end
+
+do --- abs
+  local y = 0
+  for i=1,100 do local a=23; y = math.abs(a) end; assert(y == math.abs(23))
+  for i=1,100 do local a=-23; y = math.abs(a) end; assert(y == math.abs(-23))
+  for i=1,100 do local a=23.5; y = math.abs(a) end; assert(y == math.abs(23.5))
+  for i=1,100 do local a=-23.5; y = math.abs(a) end; assert(y==math.abs(-23.5))
+  for i=1,100 do local a=-2^31; y = math.abs(a) end; assert(y==math.abs(-2^31))
+end
+
+do --- atan2 ldexp
+  local y = 0
+  for i=1,100 do local a, b = 23, 11; y = math.atan2(a, b) end
+  assert(y == math.atan2(23, 11))
+  for i=1,100 do local a, b = 23, 11; y = math.ldexp(a, b) end
+  assert(y == math.ldexp(23, 11))
+end
+
+do --- minmax
+  local y = 0
+  for i=1,100 do local a, b = 23, 11; y = math.min(a, b) end
+  assert(y == math.min(23, 11))
+  for i=1,100 do local a, b = 23, 11; y = math.max(a, b) end
+  assert(y == math.max(23, 11))
+  for i=1,100 do local a, b = 23.5, 11.5; y = math.min(a, b) end
+  assert(y == math.min(23.5, 11.5))
+  for i=1,100 do local a, b = 23.5, 11.5; y = math.max(a, b) end
+  assert(y == math.max(23.5, 11.5))
+  for i=1,100 do local a, b = 11, 23; y = math.min(a, b) end
+  assert(y == math.min(11, 23))
+  for i=1,100 do local a, b = 11, 23; y = math.max(a, b) end
+  assert(y == math.max(11, 23))
+  for i=1,100 do local a, b = 11.5, 23.5; y = math.min(a, b) end
+  assert(y == math.min(11.5, 23.5))
+  for i=1,100 do local a, b = 11.5, 23.5; y = math.max(a, b) end
+  assert(y == math.max(11.5, 23.5))
+end
+
+do --- floorceil
+  local y = 0
+  for i=1,100 do local a=23; y=math.floor(a) end assert(y==math.floor(23))
+  for i=1,100 do local a=23.5; y=math.floor(a) end assert(y==math.floor(23.5))
+  for i=1,100 do local a=-23; y=math.floor(a) end assert(y==math.floor(-23))
+  for i=1,100 do local a=-23.5; y=math.floor(a) end assert(y==math.floor(-23.5))
+  for i=1,100 do local a=-0; y=math.floor(a) end assert(y==math.floor(-0))
+  for i=1,100 do local a=23; y=math.ceil(a) end assert(y==math.ceil(23))
+  for i=1,100 do local a=23.5; y=math.ceil(a) end assert(y==math.ceil(23.5))
+  for i=1,100 do local a=-23; y=math.ceil(a) end assert(y==math.ceil(-23))
+  for i=1,100 do local a=-23.5; y=math.ceil(a) end assert(y==math.ceil(-23.5))
+  for i=1,100 do local a=-0; y=math.ceil(a) end assert(y==math.ceil(-0))
+end
+
+do --- sqrt exp log trig
+  local y = 0
+  for i=1,100 do local a=23; y=math.sqrt(a) end assert(y==math.sqrt(23))
+  for i=1,100 do local a=23; y=math.exp(a) end assert(y==math.exp(23))
+  for i=1,100 do local a=23; y=math.log(a) end assert(y==math.log(23))
+  for i=1,100 do local a=23; y=math.log10(a) end assert(y==math.log10(23))
+  for i=1,100 do local a=23; y=math.sin(a) end assert(y==math.sin(23))
+  for i=1,100 do local a=23; y=math.cos(a) end assert(y==math.cos(23))
+  for i=1,100 do local a=23; y=math.tan(a) end assert(y==math.tan(23))
+end
+
+do --- exp -luajit==2.0
+  assert((10^-2 - 0.01) == 0)
+end
diff --git a/test/LuaJIT-tests/opt/fuse.lua b/test/LuaJIT-tests/opt/fuse.lua
new file mode 100644
index 0000000..a68381e
--- /dev/null
+++ b/test/LuaJIT-tests/opt/fuse.lua
@@ -0,0 +1,5 @@
+do --- Don't fuse i+101 on x64.
+-- (except if i is sign-extended to 64 bit or addressing is limited to 32 bit)
+  local t = {}
+  for i=-100,-1 do t[i+101] = 1 end
+end
diff --git a/test/LuaJIT-tests/opt/fwd/hrefk_rollback.lua b/test/LuaJIT-tests/opt/fwd/hrefk_rollback.lua
new file mode 100644
index 0000000..5a6ad87
--- /dev/null
+++ b/test/LuaJIT-tests/opt/fwd/hrefk_rollback.lua
@@ -0,0 +1,32 @@
+do --- https://github.com/LuaJIT/LuaJIT/issues/124
+  local function foo(a, b, f)
+    return f and (a.f0 < b.f1 and
+                  b.f0 < a.f1 and
+                  a.f2 < b.f3 and
+                  b.f2 < a.f3)
+  end
+
+  local function bar(f0, f1, f2, f3, X, f)
+    for _, v in ipairs(X) do
+      local b = {}
+      b.f0 = 0
+      b.f2 = v
+      b.f1 = b.f0 + 1
+      b.f3 = b.f2 + 1
+
+      if foo({f0 = f0, f1 = f1, f2 = f2, f3 = f3}, b, f) then
+        return false
+      end
+    end
+
+    return true
+  end
+
+  local X = { 0, 1, 0, 0 }
+
+  for i = 1, 20 do
+    assert(bar(0, 1, 2, 3, X, true))
+  end
+
+  assert(not bar(0, 1, 1, 2, X, true))
+end
diff --git a/test/LuaJIT-tests/opt/fwd/index b/test/LuaJIT-tests/opt/fwd/index
new file mode 100644
index 0000000..5bb1537
--- /dev/null
+++ b/test/LuaJIT-tests/opt/fwd/index
@@ -0,0 +1,3 @@
+hrefk_rollback.lua
+tnew_tdup.lua
+upval.lua
diff --git a/test/LuaJIT-tests/opt/fwd/tnew_tdup.lua b/test/LuaJIT-tests/opt/fwd/tnew_tdup.lua
new file mode 100644
index 0000000..9e18fa3
--- /dev/null
+++ b/test/LuaJIT-tests/opt/fwd/tnew_tdup.lua
@@ -0,0 +1,69 @@
+do --- 1.
+  local x = 2
+  for i=1,100 do
+    local t = {}	-- TNEW: DCE
+    x = t.foo		-- HREF -> niltv: folded
+  end
+  assert(x == nil)
+end
+
+do --- 2.
+  local x = 2
+  for i=1,100 do
+    local t = {1}	-- TDUP: DCE
+    x = t.foo		-- HREF -> niltv: folded
+  end
+  assert(x == nil)
+end
+
+do --- 3.
+  local x = 2
+  for i=1,100 do
+    local t = {}
+    t[1] = 11		-- NEWREF + HSTORE
+    x = t[1]		-- AREF + ALOAD, no forwarding, no fold
+  end
+  assert(x == 11)
+end
+
+do --- 4. HREFK not eliminated. Ditto for the EQ(FLOAD(t, #tab.hmask), k).
+  local x = 2
+  for i=1,100 do
+    local t = {}
+    t.foo = 11		-- NEWREF + HSTORE
+    x = t.foo		-- HREFK + HLOAD: store forwarding
+  end
+  assert(x == 11)
+end
+
+do --- 5. HREFK not eliminated. Ditto for the EQ(FLOAD(t, #tab.hmask), k).
+  local x = 2
+  for i=1,100 do
+    local t = {foo=11}	-- TDUP
+    x = t.foo		-- HREFK + non-nil HLOAD: folded
+  end
+  assert(x == 11)
+end
+
+do --- 6.
+  local x = 2
+  local k = 1
+  for i=1,100 do
+    local t = {[0]=11}	-- TDUP
+    t[k] = 22		-- AREF + ASTORE aliasing
+    x = t[0]		-- AREF + ALOAD, no fold
+  end
+  assert(x == 11)
+end
+
+do --- 7.
+  local setmetatable = setmetatable
+  local mt = { __newindex = function(t, k, v)
+    assert(k == "foo")
+    assert(v == 11)
+  end }
+  for i=1,100 do
+    local t = setmetatable({}, mt)
+    t.foo = 11
+  end
+end
diff --git a/test/LuaJIT-tests/opt/fwd/upval.lua b/test/LuaJIT-tests/opt/fwd/upval.lua
new file mode 100644
index 0000000..a3e83df
--- /dev/null
+++ b/test/LuaJIT-tests/opt/fwd/upval.lua
@@ -0,0 +1,50 @@
+do --- 1. Open upvalue above base slot, aliasing an SSA value.
+  local x = 7
+  local function a() x = x + 1 end
+  local function b() x = x + 2 end
+  for i=1,100 do a(); b(); x = x + 5 end
+  assert(x == 807)
+end
+
+do --- 2. Open upvalue below base slot. UREFO CSE for a.x + b.x, but not x in loop.
+    --    ULOAD not disambiguated. 2x ULOAD + 2x USTORE (+ 1x DSE USTORE).
+  local x = 7
+  (function()
+    local function a() x = x + 1 end
+    local function b() x = x + 2 end
+    for i=1,100 do a(); b(); x = x + 5 end
+  end)()
+  assert(x == 807)
+end
+
+do --- 3. Closed upvalue. UREFC CSE for a.x + b.x, but not x in loop.
+    --    ULOAD not disambiguated. 2x ULOAD + 2x USTORE (+ 1x DSE for USTORE).
+  local xx = (function()
+    local x = 7
+    local function a() x = x + 1 end
+    local function b() x = x + 2 end
+    return function() for i=1,100 do a(); b(); x = x + 5 end; return x end
+  end)()()
+  assert(xx == 807)
+end
+
+do --- 4. Open upvalue below base slot. Forwarded. 1x USTORE (+ 1x DSE USTORE).
+  local x = 7
+  (function()
+    local function a() x = x + 1 end
+    for i=1,100 do a(); a() end
+  end)()
+  assert(x == 207)
+end
+
+do --- 5. Closed upvalue. Forwarded. 1x USTORE (+ 1x DSE USTORE).
+  local xx = (function()
+    local x = 7
+    return function()
+      local function a() x = x + 1 end
+      for i=1,100 do a(); a() end
+      return x
+    end
+  end)()()
+  assert(xx == 207)
+end
diff --git a/test/LuaJIT-tests/opt/index b/test/LuaJIT-tests/opt/index
new file mode 100644
index 0000000..94d50ae
--- /dev/null
+++ b/test/LuaJIT-tests/opt/index
@@ -0,0 +1,6 @@
+dse +dse
+fold +fold
+fwd +fwd
+fuse.lua +fuse
+loop +loop
+sink +sink
diff --git a/test/LuaJIT-tests/opt/loop/index b/test/LuaJIT-tests/opt/loop/index
new file mode 100644
index 0000000..e582023
--- /dev/null
+++ b/test/LuaJIT-tests/opt/loop/index
@@ -0,0 +1 @@
+unroll.lua
diff --git a/test/LuaJIT-tests/opt/loop/unroll.lua b/test/LuaJIT-tests/opt/loop/unroll.lua
new file mode 100644
index 0000000..6fbd565
--- /dev/null
+++ b/test/LuaJIT-tests/opt/loop/unroll.lua
@@ -0,0 +1,32 @@
+do --- type instability on loop unroll -> record unroll
+  local flip = true
+  for i=1,100 do flip = not flip end
+  assert(flip == true)
+end
+
+do --- untitled
+  local t = {}
+  local a, b, c = 1, "", t
+  for i=1,100 do a,b,c=b,c,a end
+  assert(c == 1 and a == "" and b == t)
+end
+
+do --- FAILFOLD on loop unroll -> LJ_TRERR_GFAIL -> record unroll
+  local t = { 1, 2 }
+  local k = 2
+  local x = 0
+  for i=1,200 do
+    x = x + t[k]
+    k = k == 1 and 2 or 1
+  end
+  assert(x == 300 and k == 2)
+end
+
+do --- Unroll if inner loop aborts.
+  local j = 0
+  for i = 1,100 do
+    repeat
+      j = j+1
+    until true
+  end
+end
diff --git a/test/LuaJIT-tests/opt/sink/alloc.lua b/test/LuaJIT-tests/opt/sink/alloc.lua
new file mode 100644
index 0000000..bb2a0f7
--- /dev/null
+++ b/test/LuaJIT-tests/opt/sink/alloc.lua
@@ -0,0 +1,126 @@
+local assert = assert
+
+do --- DCE or sink trivial TNEW or TDUP.
+  for i=1,100 do local t={} end
+  for i=1,100 do local t={1} end
+end
+
+do --- Sink TNEW/TDUP + ASTORE/HSTORE.
+  for i=1,100 do local t={i}; assert(t[1] == i) end
+  for i=1,100 do local t={foo=i}; assert(t.foo == i) end
+  for i=1,100 do local t={1,i}; assert(t[2] == i) end
+  for i=1,100 do local t={bar=1,foo=i}; assert(t.foo == i) end
+end
+
+do --- Sink outermost table of nested TNEW.
+  local x
+  for i=1,100 do
+    local t = {[0]={{1,i}}}
+    if i == 90 then x = t end
+    assert(t[0][1][2] == i)
+  end
+  assert(x[0][1][2] == 90)
+  for i=1,100 do
+    local t = {foo={bar={baz=i}}}
+    if i == 90 then x = t end
+    assert(t.foo.bar.baz == i)
+  end
+  assert(x.foo.bar.baz == 90)
+end
+
+do --- Sink one TNEW + FSTORE.
+  for i=1,100 do local t = setmetatable({}, {}) end
+end
+
+do --- Sink TDUP or TDUP + HSTORE. Guard of HREFK eliminated.
+  local x
+  for i=1,100 do local t = { foo = 1 }; x = t.foo; end
+  assert(x == 1)
+  for i=1,100 do local t = { foo = i }; x = t.foo; end
+  assert(x == 100)
+end
+
+do --- Sink of simplified complex add, unused in next iteration, drop PHI.
+  local x={1,2}
+  for i=1,100 do x = {x[1]+3, x[2]+4} end
+  assert(x[1] == 301)
+  assert(x[2] == 402)
+end
+
+do --- Sink of complex add, unused in next iteration, drop PHI.
+  local x,k={1.5,2.5},{3.5,4.5}
+  for i=1,100 do x = {x[1]+k[1], x[2]+k[2]} end
+  assert(x[1] == 351.5)
+  assert(x[2] == 452.5)
+end
+
+do --- Sink of TDUP with stored values that are both PHI and non-PHI.
+  local x,k={1,2},{3,4}
+  for i=1,100 do x = {x[1]+k[1], k[2]} end
+  assert(x[1] == 301)
+  assert(x[2] == 4)
+end
+
+do --- Sink of CONV.
+  local t = {1}
+  local x,y
+  for i=1,200 do
+    local v = {i}
+    local w = {i+1}
+    x = v[1]
+    y = w[1]
+    if i > 100 then end
+  end
+  assert(x == 200 and y == 201)
+end
+
+do --- Sink of stores with numbers.
+  local x = {1.5, 0}
+  for i=1,200 do x = {x[1]+1, 99.5}; x[2]=4.5; if i > 100 then end end
+  assert(x[1] == 201.5)
+  assert(x[2] == 4.5)
+end
+
+do --- Sink of stores with constants.
+  for i=1,100 do local t = {false}; t[1] = true; if i > 100 then g=t end end
+end
+
+do --- Sink with two references to the same table.
+  for i=1,200 do
+    local t = {i}
+    local q = t
+    if i > 100 then assert(t == q) end
+  end
+end
+
+do --- point
+  local point
+  point = {
+    new = function(self, x, y)
+      return setmetatable({x=x, y=y}, self)
+    end,
+    __add = function(a, b)
+     return point:new(a.x + b.x, a.y + b.y)
+    end,
+  }
+  point.__index = point
+  local a, b = point:new(1, 1), point:new(2, 2)
+  for i=1,100 do a = (a + b) + b end
+  assert(a.x == 401)
+  assert(a.y == 401)
+  assert(getmetatable(a) == point)
+  for i=1,200 do a = (a + b) + b; if i > 100 then end end
+  assert(a.x == 1201)
+  assert(a.y == 1201)
+  assert(getmetatable(a) == point)
+end
+
+do --- untitled
+  local t = {}
+  for i=1,20 do t[i] = 1 end
+  for i=1,20 do
+    for a,b in ipairs(t) do
+      local s = {i}
+    end
+  end
+end
diff --git a/test/LuaJIT-tests/opt/sink/ffi.lua b/test/LuaJIT-tests/opt/sink/ffi.lua
new file mode 100644
index 0000000..0bba097
--- /dev/null
+++ b/test/LuaJIT-tests/opt/sink/ffi.lua
@@ -0,0 +1,121 @@
+local ffi = require("ffi")
+
+do --- incrementing
+  local x = 10000000000000ll
+  for i=1,100 do x=x+1 end
+  assert(x == 10000000000100ll)
+end
+
+do --- hoistable increment !private_G
+  local x = 10000000000000ll
+  local z
+  for i=1,100 do z=x+1 end
+  assert(z == 10000000000001ll)
+  for i=1,100 do local y=x; z=x+1; g=y end
+  assert(z == 10000000000001ll)
+  assert(g == 10000000000000ll)
+end
+
+do --- escaping hoistable increment
+  local x = 10000000000000ll
+  for i=1,100 do local y=x+1; if i == 90 then x=y end end
+  assert(x == 10000000000001ll)
+end
+
+do --- escaping addition
+  local x = 10000000000000ll
+  for i=1,100 do local y=x+i; if i == 90 then x=y end end
+  assert(x == 10000000000090ll)
+end
+
+do --- conditional addition / incrementing
+  local x = 10000000000000ll
+  for i=1,200 do local y=x+i; if i > 100 then x=y end end
+  assert(x == 10000000015050ll)
+end
+
+do --- incrementing pointer
+  local a = ffi.new("int[?]", 100)
+  local p = a
+  for i=0,99 do p[0]=i; p=p+1 end
+  assert(p == a+100)
+  for i=0,99 do assert(a[i] == i) end
+end
+
+do --- mutating complex
+  local cx = ffi.typeof("complex")
+  local x = cx(1, 2)
+  local k = cx(3, 4)
+  for i=1,100 do x = cx(x.re+k.re, x.im+k.im) end
+  assert(x.re == 301)
+  assert(x.im == 402)
+end
+
+do --- mutating struct
+  local st = ffi.typeof("struct { int a; int64_t b; double c; }")
+  local x = st(1, 20000000000LL, 3.5)
+  local k = st(3, 4, 5.0)
+  for i=1,100 do x = st(x.a+k.a, x.b+k.b, x.c+k.c) end
+  assert(x.a == 301)
+  assert(x.b == 20000000400LL)
+  assert(x.c == 503.5)
+  local y, z
+  for i=1,100 do
+    local x = st(i, i, i)
+    if i == 90 then y = st(x.a, x.b, x.c) end
+    x.b = x.b + 20000000000LL
+    if i == 95 then z = st(x.a, x.b, x.c) end
+  end
+  assert(y.a == 90)
+  assert(y.b == 90)
+  assert(y.c == 90)
+  assert(z.a == 95)
+  assert(z.b == 20000000095LL)
+  assert(z.c == 95)
+  for i=1,200 do
+    local x = st(i, i, i)
+    if i > 100 then y = st(x.a, x.b, x.c) end
+    x.b = x.b + 20000000000LL
+    if i > 150 then z = st(x.a, x.b, x.c) end
+  end
+  assert(y.a == 200)
+  assert(y.b == 200)
+  assert(y.c == 200)
+  assert(z.a == 200)
+  assert(z.b == 20000000200LL)
+  assert(z.c == 200)
+end
+
+do --- mutating struct 2
+  local st = ffi.typeof("struct { int64_t a; double b; float c; }")
+  local x = st(1, 2.5, 3.25)
+  local k = st(3, 4, 5)
+  for i=1,100 do x = st(x.a+k.a, x.b+k.b, x.c+k.c) end
+  assert(x.a == 301)
+  assert(x.b == 402.5)
+  assert(x.c == 503.25)
+end
+
+do --- escaping loop counter to float
+  local st = ffi.typeof("struct { float a; }")
+  local x
+  for i=1,200 do
+    local y = st(i)
+    if i > 100 then x = y end
+  end
+  assert(x.a == 200)
+end
+
+do --- 64 bit crash bug !private_G
+  local t = {}
+  for i=1,200 do t[i] = "abcd" end
+  local r
+  for i=1,200 do
+    local a,b,c,d
+    local g = t[201-i]                                -- Non-zero stack slot above.
+    local v = ffi.cast("const char *", t[i])          -- Uses 32 bit stack slot!
+    a,b,c,d = {v[0]},{v[1]},{v[2]},{v[3]}             -- Force above to spill.
+    r = {{i}}                                         -- Spill due to call.
+    if i > 100 then z = v[0]+a[1]+b[1]+c[1]+d[1] end  -- Crash for 64 bit ptr v.
+  end
+end
diff --git a/test/LuaJIT-tests/opt/sink/ffi_nosink.lua b/test/LuaJIT-tests/opt/sink/ffi_nosink.lua
new file mode 100644
index 0000000..8f7cced
--- /dev/null
+++ b/test/LuaJIT-tests/opt/sink/ffi_nosink.lua
@@ -0,0 +1,45 @@
+local ffi = require("ffi")
+
+do --- escaping global !private_G
+  local x = 0ll
+  for i=1,100 do x=x+1; g=x end
+  assert(x == 100ll)
+  assert(g == 100ll)
+end
+
+do --- preincrement escaping global !private_G
+  local x = 0ll
+  for i=1,100 do local y=x; x=x+1; g=y end
+  assert(x == 100ll)
+  assert(g == 99ll)
+end
+
+do --- escaping global and local !private_G
+  local x = 0ll
+  local z
+  for i=1,100 do z=x+1; g=z end
+  assert(z == 1ll)
+  assert(g == 1ll)
+end
+
+do --- swapping
+  local x,y = 0ll, 0ll
+  for i=1,100 do y,x=x,x+1 end
+  assert(x == 100ll)
+  assert(y == 99ll)
+end
+
+do --- pointer to self
+  local st = ffi.typeof("struct { void *p; }")
+  local x
+  for i=1,100 do x = st(); x.p = x end
+  assert(x.p == ffi.cast("void *", x))
+end
+
+do --- strchr
+  ffi.cdef[[char *strchr(char *, int);]]
+  for i=1,100 do
+    local p = ffi.new("char[2]");
+    ffi.C.strchr(p, 32)
+  end
+end
diff --git a/test/LuaJIT-tests/opt/sink/index b/test/LuaJIT-tests/opt/sink/index
new file mode 100644
index 0000000..8bfa370
--- /dev/null
+++ b/test/LuaJIT-tests/opt/sink/index
@@ -0,0 +1,4 @@
+alloc.lua
+nosink.lua
+ffi.lua +ffi
+ffi_nosink.lua +ffi
diff --git a/test/LuaJIT-tests/opt/sink/nosink.lua b/test/LuaJIT-tests/opt/sink/nosink.lua
new file mode 100644
index 0000000..762aace
--- /dev/null
+++ b/test/LuaJIT-tests/opt/sink/nosink.lua
@@ -0,0 +1,109 @@
+local assert = assert
+
+do --- Cannot sink TNEW, aliased load.
+  local k = 1
+  for i=1,100 do local t={i}; assert(t[k]==i) end
+  for i=1,100 do local t={}; t[k]=i; assert(t[1]==i) end
+end
+
+do --- Cannot sink TNEW, escaping to upvalue.
+  (function()
+    local uv
+    return function()
+      for i=1,100 do uv = {i} end
+      assert(uv[1] == 100)
+    end
+  end)()()
+end
+
+do --- Cannot sink TNEW, escaping through a store.
+  local t = {}
+  for i=1,100 do t[1] = {i} end
+  for i=1,100 do t.foo = {i} end
+  for i=1,100 do setmetatable(t, {i}) end
+  assert(t[1][1] == 100)
+  assert(t.foo[1] == 100)
+  assert(getmetatable(t)[1] == 100)
+end
+
+do --- Cannot sink TNEW, iteratively escaping through a store.
+  local t = {}
+  for i=1,100 do t[1] = {i}; t[1][1] = {i} end
+  assert(t[1][1][1] == 100)
+end
+
+do --- Cannot sink TNEW, escaping to next iteration (unused in 1st variant).
+  local t;
+  for i=1,200 do t = {i} end
+  assert(t[1] == 200)
+  for i=1,200 do if i > 100 then assert(t[1] == i-1) end t = {i} end
+  assert(t[1] == 200)
+end
+
+do --- Cannot sink TNEW, escaping to next iteration (snapshot ref).
+  local t,x
+  for i=1,100 do x=t; t={i} end
+  assert(t[1] == 100)
+  assert(x[1] == 99)
+end
+
+do --- Cannot sink TNEW, escaping to next iteration (IR/snapshot ref).
+  local t
+  for i=1,100 do t={t} end
+  assert(type(t[1][1][1]) == "table")
+end
+
+do --- Cannot sink inner TNEW, escaping to next iteration (IR ref).
+  -- (Could sink outer TNEW, but the logic for stores to PHI allocs is too simple).
+  local t = {42, 43}
+  for i=1,100 do t={t[2], {i}} end
+  assert(t[2][1] == 100)
+  assert(t[1][1] == 99)
+end
+
+do --- Cannot sink TNEW, cross-PHI ref (and snapshot ref).
+  local x,y
+  for i=1,100 do x,y={i},x end
+  assert(x[1] == 100)
+  assert(y[1] == 99)
+end
+
+do --- Cannot sink TNEW, cross-PHI ref (and snapshot ref).
+  local x,y
+  for i=1,100 do x,y=y,{i} end
+  assert(x[1] == 99)
+  assert(y[1] == 100)
+end
+
+do --- Cannot sink TNEW, escaping to exit.
+  local function f(n, t)
+    if n == 0 then return t end
+    return (f(n-1, {t}))
+  end
+  local t = f(100, 42)
+  assert(type(t[1][1][1]) == "table")
+  t = f(3, 42)
+  assert(t[1][1][1] == 42)
+end
+
+do --- Cannot sink TNEW, escaping to exit.
+  local function f(n)
+    if n == 0 then return 42 end
+    local t = f(n-1)
+    return {t}
+  end
+  for i=1,20 do
+    local t = f(100)
+    assert(type(t[1][1][1]) == "table")
+  end
+  local t = f(3)
+  assert(t[1][1][1] == 42)
+end
+
+do --- Cannot sink, since nested inner table is non-PHI.
+  local a, b = {{1}}, {{1}}
+  for i=1,10000 do -- Need to force GC exit sometimes
+    a = {{a[1][1]+b[1][1]}}
+  end
+  assert(a[1][1] == 10001)
+end
diff --git a/test/LuaJIT-tests/src/cpptest.cpp b/test/LuaJIT-tests/src/cpptest.cpp
new file mode 100644
index 0000000..a5893ed
--- /dev/null
+++ b/test/LuaJIT-tests/src/cpptest.cpp
@@ -0,0 +1,129 @@
+
+#include <stdio.h>
+
+extern "C" {
+#define LUA_LIB
+#include "lua.h"
+#include "lauxlib.h"
+#include "luajit.h"
+}
+
+static int testobj_alloc;
+
+class TestObj {
+public:
+  TestObj(int x) { foo = x; testobj_alloc = 1; }
+  ~TestObj() { testobj_alloc = 0; }
+private:
+  int foo;
+};
+
+static int ct_alloc(lua_State *L)
+{
+  TestObj foo(1);
+  lua_pushlightuserdata(L, (void *)&foo);
+  lua_call(L, lua_gettop(L)-1, LUA_MULTRET);
+  if (lua_iscfunction(L, -1)) {
+    lua_CFunction f = lua_tocfunction(L, -1);
+    lua_pop(L, 1);
+    f(L);
+  }
+  return lua_gettop(L);
+}
+
+static int ct_isalloc(lua_State *L)
+{
+  lua_pushboolean(L, testobj_alloc);
+  return 1;
+}
+
+static int ct_usereg(lua_State *L)
+{
+  int n = luaL_checkint(L, 1);
+  int m = luaL_checkint(L, 2);
+  int i;
+  int a = 0, b = 0, c = 0, d = 0, e = 0, f = 0;
+  for (i = 0; i < n; i++) {
+    a = (a + 1) ^ 0x12345678;
+    b = (b + 2) ^ 0x12345678;
+    c = (c + 3) ^ 0x12345678;
+    d = (d + 4) ^ 0x12345678;
+    e = (e + 5) ^ 0x12345678;
+    f = (f + 5) ^ 0x12345678;
+    if (i == m) {
+      if (i & 1)
+	lua_pcall(L, 1, 0, 0);
+      else
+	lua_call(L, 1, 0);
+    }
+  }
+  lua_pushinteger(L, a);
+  lua_pushinteger(L, b);
+  lua_pushinteger(L, c);
+  lua_pushinteger(L, d);
+  lua_pushinteger(L, e);
+  lua_pushinteger(L, f);
+  return 6;
+}
+
+static int ct_catch(lua_State *L)
+{
+  try {
+    lua_call(L, lua_gettop(L)-1, LUA_MULTRET);
+    return lua_gettop(L);
+  } catch (const char *s) {
+    lua_pushstring(L, s);
+  } catch (...) {
+    lua_pushliteral(L, "catch ...");
+  }
+  return 1;
+}
+
+static int ct_throw(lua_State *L)
+{
+  const char *s = lua_tostring(L, 1);
+  throw(s);
+  return 0;
+}
+
+static int ct_wrap(lua_State *L, lua_CFunction f)
+{
+  try {
+    return f(L);
+  } catch (const char *s) {
+    lua_pushstring(L, s);
+  }
+  return lua_error(L);
+}
+
+static int ct_wrapon(lua_State *L)
+{
+  lua_pushlightuserdata(L, (void *)ct_wrap);
+  luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC|LUAJIT_MODE_ON);
+  return 0;
+}
+
+static int ct_wrapoff(lua_State *L)
+{
+  luaJIT_setmode(L, 0, LUAJIT_MODE_WRAPCFUNC|LUAJIT_MODE_OFF);
+  return 0;
+}
+
+static luaL_Reg ct_funcs[] = {
+  {"isalloc",	ct_isalloc },
+  {"alloc",	ct_alloc },
+  {"usereg",	ct_usereg },
+  {"catch",	ct_catch },
+  {"throw",	ct_throw },
+  {"wrapon",	ct_wrapon },
+  {"wrapoff",	ct_wrapoff },
+  {NULL, NULL}
+};
+
+extern "C" {
+LUA_API int luaopen_cpptest(lua_State *L)
+{
+  luaL_register(L, "cpptest", ct_funcs);
+  return 1;
+}
+}
diff --git a/test/LuaJIT-tests/src/ctest.c b/test/LuaJIT-tests/src/ctest.c
new file mode 100644
index 0000000..d257567
--- /dev/null
+++ b/test/LuaJIT-tests/src/ctest.c
@@ -0,0 +1,339 @@
+
+#define LUA_LIB
+#include "lua.h"
+#include "lauxlib.h"
+
+/* ------------------------------------------------------------------------ */
+
+#ifdef _MSC_VER
+typedef __int8 int8_t;
+typedef __int16 int16_t;
+typedef __int32 int32_t;
+typedef __int64 int64_t;
+typedef unsigned __int8 uint8_t;
+typedef unsigned __int16 uint16_t;
+typedef unsigned __int32 uint32_t;
+typedef unsigned __int64 uint64_t;
+#else
+#include <stdint.h>
+#define complex _Complex
+#endif
+
+#if defined(__i386) || defined(__i386__) || defined(_M_IX86)
+#ifdef _MSC_VER
+#define LJ_FASTCALL	__fastcall
+#define LJ_STDCALL	__stdcall
+#else
+#define LJ_FASTCALL	__attribute__((fastcall))
+#define LJ_STDCALL	__attribute__((stdcall))
+#endif
+#endif
+
+typedef struct s_ii { int x, y; } s_ii;
+typedef struct s_jj { int64_t x, y; } s_jj;
+typedef struct s_ff { float x, y; } s_ff;
+typedef struct s_dd { double x, y; } s_dd;
+typedef struct s_8i { int a,b,c,d,e,f,g,h; } s_8i;
+
+LUA_API int call_i(int a) { return a+1; }
+LUA_API int call_ii(int a, int b) { return a+b; }
+LUA_API int call_10i(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j) { return a+b+c+d+e+f+g+h+i+j; }
+
+LUA_API int64_t call_10j(int a, int b, int c, int d, int e, int f, int g, int h, int i, int64_t j) { return a+b+c+d+e+f+g+h+i+j; }
+
+LUA_API int64_t call_ji(int64_t a, int b) { return a+b; }
+LUA_API int64_t call_ij(int a, int64_t b) { return a+b; }
+LUA_API int64_t call_jj(int64_t a, int64_t b) { return a+b; }
+
+LUA_API double call_dd(double a, double b) { return a+b; }
+LUA_API double call_10d(double a, double b, double c, double d, double e, double f, double g, double h, double i, double j) { return a+b+c+d+e+f+g+h+i+j; }
+
+LUA_API float call_ff(float a, float b) { return a+b; }
+LUA_API float call_10f(float a, float b, float c, float d, float e, float f, float g, float h, float i, float j) { return a+b+c+d+e+f+g+h+i+j; }
+
+LUA_API double call_idifjd(int a, double b, int c, float d, int64_t e, double f) { return a+b+c+d+e+f; }
+
+LUA_API int call_p_i(int *a) { return *a+1; }
+LUA_API int *call_p_p(int *a) { return a+1; }
+LUA_API int call_pp_i(int *a, int *b) { return (int)(a-b); }
+
+#include <stdarg.h>
+
+LUA_API double call_ividi(int a, ...)
+{
+  double y;
+  va_list argp;
+  va_start(argp, a);
+  y = a;
+  y += va_arg(argp, int);
+  y += va_arg(argp, double);
+  y += va_arg(argp, int);
+  va_end(argp);
+  return y;
+}
+
+#ifdef complex
+LUA_API complex call_dd_cd(double a, double b) { return a+b*2i; }
+LUA_API complex call_cd(complex a) { return a+1-2i; }
+LUA_API complex call_cdcd(complex a, complex b) { return a+b; }
+
+LUA_API complex float call_ff_cf(float a, float b) { return a+b*2i; }
+LUA_API complex float call_cf(complex float a) { return a+1-2i; }
+LUA_API complex float call_cfcf(complex float a, complex float b) { return a+b; }
+#endif
+
+LUA_API s_ii call_sii(s_ii a) { return a; }
+LUA_API s_jj call_sjj(s_jj a) { return a; }
+LUA_API s_ff call_sff(s_ff a) { return a; }
+LUA_API s_dd call_sdd(s_dd a) { return a; }
+LUA_API s_8i call_s8i(s_8i a) { return a; }
+LUA_API s_ii call_siisii(s_ii a, s_ii b)
+{
+  s_ii c;
+  c.x = a.x + b.x;
+  c.y = a.y + b.y;
+  return c;
+}
+LUA_API s_ff call_sffsff(s_ff a, s_ff b)
+{
+  s_ff c;
+  c.x = a.x + b.x;
+  c.y = a.y + b.y;
+  return c;
+}
+LUA_API s_dd call_sddsdd(s_dd a, s_dd b)
+{
+  s_dd c;
+  c.x = a.x + b.x;
+  c.y = a.y + b.y;
+  return c;
+}
+LUA_API s_8i call_s8is8i(s_8i a, s_8i b)
+{
+  s_8i c;
+  c.a = a.a + b.a;
+  c.b = a.b + b.b;
+  c.c = a.c + b.c;
+  c.d = a.d + b.d;
+  c.e = a.e + b.e;
+  c.f = a.f + b.f;
+  c.g = a.g + b.g;
+  c.h = a.h + b.h;
+  return c;
+}
+LUA_API s_8i call_is8ii(int a, s_8i b, int c)
+{
+  b.a += a;
+  b.c += c;
+  return b;
+}
+
+#ifdef LJ_FASTCALL
+LUA_API int LJ_FASTCALL fastcall_void(void) { return 1; }
+LUA_API int LJ_FASTCALL fastcall_i(int a) { return a+1; }
+LUA_API int LJ_FASTCALL fastcall_ii(int a, int b) { return a+b; }
+LUA_API int LJ_FASTCALL fastcall_iii(int a, int b, int c) { return a+b+c; }
+LUA_API int64_t LJ_FASTCALL fastcall_ji(int64_t a, int b) { return a+b; }
+LUA_API double LJ_FASTCALL fastcall_dd(double a, double b) { return a+b; }
+LUA_API int LJ_FASTCALL fastcall_pp_i(int *a, int *b) { return (int)(a-b); }
+LUA_API s_ii LJ_FASTCALL fastcall_siisii(s_ii a, s_ii b)
+{
+  s_ii c;
+  c.x = a.x + b.x;
+  c.y = a.y + b.y;
+  return c;
+}
+LUA_API s_dd LJ_FASTCALL fastcall_sddsdd(s_dd a, s_dd b)
+{
+  s_dd c;
+  c.x = a.x + b.x;
+  c.y = a.y + b.y;
+  return c;
+}
+#endif
+
+#if defined(LJ_STDCALL) && defined(_WIN32)
+LUA_API int LJ_STDCALL stdcall_i(int a) { return a+1; }
+LUA_API int LJ_STDCALL stdcall_ii(int a, int b) { return a+b; }
+LUA_API double LJ_STDCALL stdcall_dd(double a, double b) { return a+b; }
+LUA_API float LJ_STDCALL stdcall_ff(float a, float b) { return a+b; }
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+static int ct_call(lua_State *L)
+{
+  int nresults = luaL_checkint(L, 1);
+  luaL_checkstack(L, nresults, "too many results");
+  lua_call(L, lua_gettop(L)-2, nresults);
+  return lua_gettop(L)-1;
+}
+
+static int ct_callon(lua_State *L)
+{
+  lua_State *co = lua_tothread(L, 1);
+  int nargs = lua_gettop(L)-1;
+  int nresults;
+  lua_xmove(L, co, nargs);
+  lua_call(co, nargs-1, LUA_MULTRET);
+  nresults = lua_gettop(co);
+  lua_xmove(co, L, nresults);
+  return nresults;
+}
+
+static int ct_pcall_err(lua_State *L)
+{
+  int nresults = luaL_checkint(L, 1);
+  luaL_checkstack(L, nresults, "too many results");
+  if (lua_pcall(L, lua_gettop(L)-2, nresults, 0))
+    lua_error(L);
+  return lua_gettop(L)-1;
+}
+
+static int ct_pcall(lua_State *L)
+{
+  int status;
+  luaL_checkany(L, 1);
+  status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0);
+  lua_pushboolean(L, (status == 0));
+  lua_insert(L, 1);
+  return lua_gettop(L);  /* return status + all results */
+}
+
+static int ct_xpcall(lua_State *L)
+{
+  int status;
+  luaL_checkany(L, 2);
+  lua_settop(L, 2);
+  lua_insert(L, 1);  /* put error function under function to be called */
+  status = lua_pcall(L, 0, LUA_MULTRET, 1);
+  lua_pushboolean(L, (status == 0));
+  lua_replace(L, 1);
+  return lua_gettop(L);  /* return status + all results */
+}
+
+#define CO_RUN	0	/* running */
+#define CO_SUS	1	/* suspended */
+#define CO_NOR	2	/* 'normal' (it resumed another coroutine) */
+#define CO_DEAD	3
+
+static const char *const statnames[] =
+    {"running", "suspended", "normal", "dead"};
+
+static int costatus(lua_State *L, lua_State *co) {
+  if (L == co) return CO_RUN;
+  switch (lua_status(co)) {
+    case LUA_YIELD:
+      return CO_SUS;
+    case 0: {
+      lua_Debug ar;
+      if (lua_getstack(co, 0, &ar) > 0)  /* does it have frames? */
+	return CO_NOR;  /* it is running */
+      else if (lua_gettop(co) == 0)
+	  return CO_DEAD;
+      else
+	return CO_SUS;  /* initial state */
+    }
+    default:  /* some error occured */
+      return CO_DEAD;
+  }
+}
+
+static int auxresume(lua_State *L, lua_State *co, int narg) {
+  int status = costatus(L, co);
+  if (!lua_checkstack(co, narg))
+    luaL_error(L, "too many arguments to resume");
+  if (status != CO_SUS) {
+    lua_pushfstring(L, "cannot resume %s coroutine", statnames[status]);
+    return -1;  /* error flag */
+  }
+  lua_xmove(L, co, narg);
+  status = lua_resume(co, narg);
+  if (status == 0 || status == LUA_YIELD) {
+    int nres = lua_gettop(co);
+    if (!lua_checkstack(L, nres + 1))
+      luaL_error(L, "too many results to resume");
+    lua_xmove(co, L, nres);  /* move yielded values */
+    return nres;
+  }
+  else {
+    lua_xmove(co, L, 1);  /* move error message */
+    return -1;  /* error flag */
+  }
+}
+
+static int ct_resume(lua_State *L) {
+  lua_State *co = lua_tothread(L, 1);
+  int r;
+  luaL_argcheck(L, co, 1, "coroutine expected");
+  r = auxresume(L, co, lua_gettop(L) - 1);
+  if (r < 0) {
+    lua_pushboolean(L, 0);
+    lua_insert(L, -2);
+    return 2;  /* return false + error message */
+  }
+  else {
+    lua_pushboolean(L, 1);
+    lua_insert(L, -(r + 1));
+    return r + 1;  /* return true + `resume' returns */
+  }
+}
+
+static int ct_auxwrap(lua_State *L) {
+  lua_State *co = lua_tothread(L, lua_upvalueindex(1));
+  int r = auxresume(L, co, lua_gettop(L));
+  if (r < 0) {
+    if (lua_isstring(L, -1)) {  /* error object is a string? */
+      luaL_where(L, 1);  /* add extra info */
+      lua_insert(L, -2);
+      lua_concat(L, 2);
+    }
+    lua_error(L);  /* propagate error */
+  }
+  return r;
+}
+
+static int ct_cocreate(lua_State *L) {
+  lua_State *NL = lua_newthread(L);
+  luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1,
+    "Lua function expected");
+  lua_pushvalue(L, 1);  /* move function to top */
+  lua_xmove(L, NL, 1);  /* move function from L to NL */
+  return 1;
+}
+
+
+static int ct_wrap(lua_State *L) {
+  ct_cocreate(L);
+  lua_pushcclosure(L, ct_auxwrap, 1);
+  return 1;
+}
+
+static int ct_yield(lua_State *L) {
+  return lua_yield(L, lua_gettop(L));
+}
+
+static int ct_lightud(lua_State *L)
+{
+  lua_pushlightuserdata(L, (void *)(ptrdiff_t)lua_tonumber(L, 1));
+  return 1;
+}
+
+static luaL_Reg ct_funcs[] = {
+  {"call",	ct_call },
+  {"callon",	ct_callon },
+  {"pcall",	ct_pcall },
+  {"xpcall",	ct_xpcall },
+  {"pcall_err",	ct_pcall_err },
+  {"resume",	ct_resume },
+  {"wrap",	ct_wrap },
+  {"yield",	ct_yield },
+  {"lightud",	ct_lightud },
+  {NULL, NULL}
+};
+
+LUA_API int luaopen_ctest(lua_State *L)
+{
+  luaL_register(L, "ctest", ct_funcs);
+  return 1;
+}
diff --git a/test/LuaJIT-tests/sysdep/catch_cpp.lua b/test/LuaJIT-tests/sysdep/catch_cpp.lua
new file mode 100644
index 0000000..b225100
--- /dev/null
+++ b/test/LuaJIT-tests/sysdep/catch_cpp.lua
@@ -0,0 +1,71 @@
+
+local cp = require("cpptest")
+
+do
+  local a, b = pcall(cp.catch, function() return "x" end)
+  assert(a == true and b == "x")
+end
+
+do
+  local a, b = pcall(function() cp.throw("foo") end)
+  assert(a == false and b == "C++ exception")
+end
+
+local unwind
+do
+  local a, b = pcall(cp.catch, function() cp.throw("foo") end)
+  unwind = a
+  assert((a == false and b == "C++ exception") or (a == true and b == "foo"))
+end
+
+do
+  local st = cp.alloc(function() return cp.isalloc() end)
+  assert(st == true)
+  assert(cp.isalloc() == false)
+end
+
+do
+  local a, b = pcall(cp.alloc, function()
+    assert(cp.isalloc() == true)
+    return "foo", cp.throw
+  end)
+  assert(a == false and b == "C++ exception")
+  assert(cp.isalloc() == false)
+end
+
+if unwind then
+  local a, b = pcall(cp.alloc, function()
+    assert(cp.isalloc() == true)
+    return "foo", error
+  end)
+  assert(a == false and b == "foo")
+  assert(cp.isalloc() == false)
+end
+
+do
+  local a,b,c,d,e,f = cp.usereg(100, 50, function() end, false)
+  assert(a==164 and b==312 and c==428 and d==3696 and e==404 and f==404)
+end
+
+do
+  local function test()
+    cp.usereg(100, 40, error, "foo")
+  end
+  local a,b,c,d,e,f = cp.usereg(100, 51, test, false)
+  assert(a==164 and b==312 and c==428 and d==3696 and e==404 and f==404)
+end
+
+do
+  local t = {};
+  t.t = t;
+  local function foo()
+    for i=1,100 do
+      local a,b,c,d,e,f = t, t.t, t.t.t, t.t.t.t, t.t.t.t.t, t.t.t.t.t.t
+      local g,h,j,k,l = f.t, f.t.t, f.t.t.t, f.t.t.t.t, f.t.t.t.t.t
+      local m = { a,b,c,d,e,f,g,h,j,k,l }
+    end
+  end
+  local a,b,c,d,e,f = cp.usereg(100, 50, foo, false)
+  assert(a==164 and b==312 and c==428 and d==3696 and e==404 and f==404)
+end
+
diff --git a/test/LuaJIT-tests/sysdep/ffi_include_gtk.lua b/test/LuaJIT-tests/sysdep/ffi_include_gtk.lua
new file mode 100644
index 0000000..a4bfcea
--- /dev/null
+++ b/test/LuaJIT-tests/sysdep/ffi_include_gtk.lua
@@ -0,0 +1,9 @@
+local ffi = require("ffi")
+
+dofile("../common/ffi_util.inc")
+
+if cdefs == "" then
+  cdefs = "-pthread -D_REENTRANT -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/directfb -I/usr/include/libpng12 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include -I/usr/include/gdk-pixbuf-2.0"
+end
+
+include"/usr/include/gtk-2.0/gtk/gtk.h"
diff --git a/test/LuaJIT-tests/sysdep/ffi_include_std.lua b/test/LuaJIT-tests/sysdep/ffi_include_std.lua
new file mode 100644
index 0000000..b88c82b
--- /dev/null
+++ b/test/LuaJIT-tests/sysdep/ffi_include_std.lua
@@ -0,0 +1,36 @@
+local ffi = require("ffi")
+
+dofile("../common/ffi_util.inc")
+
+do
+  local fp = assert(io.open("/tmp/__tmp.c", "w"))
+  fp:write[[
+#include <sqlite3.h>
+#include <thread_db.h>
+#include <resolv.h>
+#include <mpfr.h>
+#include <mpc.h>
+#include <curses.h>
+#include <form.h>
+#include <aio.h>
+#include <unistd.h>
+#include <zlib.h>
+#include <netdb.h>
+#include <math.h>
+#include <tgmath.h>
+#include <complex.h>
+#include <elf.h>
+#include <mqueue.h>
+#include <regex.h>
+#include <fcntl.h>
+]]
+  fp:close()
+
+  local flags = ffi.abi("32bit") and "-m32" or "-m64"
+  fp = assert(io.popen("cc -E -P -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE /tmp/__tmp.c "..flags))
+  local s = fp:read("*a")
+  fp:close()
+  os.remove("/tmp/__tmp.c")
+  ffi.cdef(s)
+end
+
diff --git a/test/LuaJIT-tests/sysdep/ffi_lib_c.lua b/test/LuaJIT-tests/sysdep/ffi_lib_c.lua
new file mode 100644
index 0000000..a368d75
--- /dev/null
+++ b/test/LuaJIT-tests/sysdep/ffi_lib_c.lua
@@ -0,0 +1,87 @@
+local ffi = require("ffi")
+
+ffi.cdef[[
+// libc/libm
+int sprintf(char *buf, const char *fmt, ...);
+double pow(double x, double y);
+int rmdir(const char *name);
+int errno;
+
+// Windows
+unsigned int GetSystemDirectoryA(char *buf, unsigned int sz);
+char *CharUpperA(char *str);
+int GdiFlush(void);
+int _rmdir(const char *name);
+static const int _O_TEXT = 0x4000;
+static const int _O_BINARY = 0x8000;
+int *_errno(void);
+int _fmode;
+
+// Lua/C API
+typedef struct lua_State lua_State;
+typedef double lua_Number;
+lua_State *luaL_newstate(void);
+void luaL_openlibs(lua_State *L);
+void lua_close(lua_State *L);
+int luaL_loadstring(lua_State *L, const char *s);
+int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc);
+lua_Number lua_tonumber(lua_State *L, int idx);
+]]
+
+local C = ffi.C
+
+do
+  local buf = ffi.new("char[?]", 100)
+  local n = C.sprintf(buf, "test %g %s", 12.5, "foo")
+  assert(ffi.string(buf, n) == "test 12.5 foo")
+end
+
+assert(ffi.C.pow(2.5, 5) == 97.65625)
+
+if ffi.abi("win") then
+  do
+    local buf = ffi.new("char[?]", 4, "abc")
+    C.CharUpperA(buf)
+    assert(ffi.string(buf) == "ABC")
+  end
+
+  do
+    local buf = ffi.new("char[?]", 256)
+    local len = C.GetSystemDirectoryA(buf, 255)
+    local s = ffi.string(buf, len)
+    assert(string.find(string.lower(s), "\\system32"))
+  end
+
+  assert(C.GdiFlush() == 1)
+
+  assert(ffi.C._rmdir("/tmp/does_not_exist") == -1)
+  assert(ffi.C._errno()[0] == 2)
+
+  ffi.C._fmode = ffi.C._O_BINARY
+  assert(ffi.C._fmode == ffi.C._O_BINARY)
+  ffi.C._fmode = ffi.C._O_TEXT
+else
+  assert(ffi.C.rmdir("/tmp/does_not_exist") == -1)
+  assert(ffi.C.errno == 2)
+
+  ffi.C.errno = 17
+  assert(ffi.C.errno == 17)
+  ffi.C.errno = 0
+end
+
+do
+  local L = C.luaL_newstate()
+  local s = "local x = 0; for i=1,100 do x=x+i end; return x"
+  C.luaL_openlibs(L)
+  assert(C.luaL_loadstring(L, s) == 0)
+  assert(C.lua_pcall(L, 0, 1, 0) == 0)
+  assert(C.lua_tonumber(L, -1) == 5050)
+  C.lua_close(L)
+end
+
+do
+  if not (ffi.os == "Windows" or ffi.os == "Other") then
+    ffi.load("pthread")
+  end
+end
+
diff --git a/test/LuaJIT-tests/sysdep/ffi_lib_z.lua b/test/LuaJIT-tests/sysdep/ffi_lib_z.lua
new file mode 100644
index 0000000..69a19ae
--- /dev/null
+++ b/test/LuaJIT-tests/sysdep/ffi_lib_z.lua
@@ -0,0 +1,107 @@
+local ffi = require("ffi")
+
+local compress, uncompress
+
+if ffi.abi("win") then
+
+  ffi.cdef[[
+  int RtlGetCompressionWorkSpaceSize(uint16_t fmt,
+    unsigned long *wsbufsz, unsigned long *wsfragsz);
+  int RtlCompressBuffer(uint16_t fmt,
+    const uint8_t *src, unsigned long srclen,
+    uint8_t *dst, unsigned long dstsz,
+    unsigned long chunk, unsigned long *dstlen, void *workspace);
+  int RtlDecompressBuffer(uint16_t fmt,
+    uint8_t *dst, unsigned long dstsz,
+    const uint8_t *src, unsigned long srclen,
+    unsigned long *dstlen);
+  ]]
+
+  local ntdll = ffi.load("ntdll")
+
+  local fmt = 0x0102
+  local workspace
+  do
+    local res = ffi.new("unsigned long[2]")
+    ntdll.RtlGetCompressionWorkSpaceSize(fmt, res, res+1)
+    workspace = ffi.new("uint8_t[?]", res[0])
+  end
+
+  function compress(txt)
+    local buf = ffi.new("uint8_t[?]", 4096)
+    local buflen = ffi.new("unsigned long[1]")
+    local res = ntdll.RtlCompressBuffer(fmt, txt, #txt, buf, 4096,
+					4096, buflen, workspace)
+    assert(res == 0)
+    return ffi.string(buf, buflen[0])
+  end
+
+  function uncompress(comp, n)
+    local buf = ffi.new("uint8_t[?]", n)
+    local buflen = ffi.new("unsigned long[1]")
+    local res = ntdll.RtlDecompressBuffer(fmt, buf, n, comp, #comp, buflen)
+    assert(res == 0)
+    return ffi.string(buf, buflen[0])
+  end
+
+else
+
+  ffi.cdef[[
+  unsigned long compressBound(unsigned long sourceLen);
+  int compress2(uint8_t *dest, unsigned long *destLen,
+		const uint8_t *source, unsigned long sourceLen, int level);
+  int uncompress(uint8_t *dest, unsigned long *destLen,
+		 const uint8_t *source, unsigned long sourceLen);
+  ]]
+
+  local zlib = ffi.load("z")
+
+  function compress(txt)
+    local n = tonumber(zlib.compressBound(#txt))
+    local buf = ffi.new("uint8_t[?]", n)
+    local buflen = ffi.new("unsigned long[1]", n)
+    local res = zlib.compress2(buf, buflen, txt, #txt, 9)
+    assert(res == 0)
+    return ffi.string(buf, tonumber(buflen[0]))
+  end
+
+  function uncompress(comp, n)
+    local buf = ffi.new("uint8_t[?]", n)
+    local buflen = ffi.new("unsigned long[1]", n)
+    local res = zlib.uncompress(buf, buflen, comp, #comp)
+    assert(res == 0)
+    return ffi.string(buf, tonumber(buflen[0]))
+  end
+
+end
+
+  local txt = [[Rebellious subjects, enemies to peace,
+Profaners of this neighbour-stained steel,--
+Will they not hear? What, ho! you men, you beasts,
+That quench the fire of your pernicious rage
+With purple fountains issuing from your veins,
+On pain of torture, from those bloody hands
+Throw your mistemper'd weapons to the ground,
+And hear the sentence of your moved prince.
+Three civil brawls, bred of an airy word,
+By thee, old Capulet, and Montague,
+Have thrice disturb'd the quiet of our streets,
+And made Verona's ancient citizens
+Cast by their grave beseeming ornaments,
+To wield old partisans, in hands as old,
+Canker'd with peace, to part your canker'd hate:
+If ever you disturb our streets again,
+Your lives shall pay the forfeit of the peace.
+For this time, all the rest depart away:
+You Capulet; shall go along with me:
+And, Montague, come you this afternoon,
+To know our further pleasure in this case,
+To old Free-town, our common judgment-place.
+Once more, on pain of death, all men depart.]]
+txt = txt..txt..txt..txt
+
+local c = compress(txt)
+assert(2*#c < #txt)
+local txt2 = uncompress(c, #txt)
+assert(txt2 == txt)
+
diff --git a/test/LuaJIT-tests/test.lua b/test/LuaJIT-tests/test.lua
new file mode 100644
index 0000000..b064eff
--- /dev/null
+++ b/test/LuaJIT-tests/test.lua
@@ -0,0 +1,416 @@
+local assert, io_open, io_lines, io_write, load, type, xpcall =
+      assert, io.open, io.lines, io.write, load, type, xpcall
+local debug_traceback, math_random, tonumber, loadstring =
+      debug.traceback, math.random, tonumber, loadstring or load
+
+local dirsep = package.config:match"^(.-)\n"
+local own_file = debug.getinfo(1, "S").source:match"^@(.*)" or arg[0]
+local own_dir = own_file:match("^.*[/".. dirsep .."]")
+
+local function default_tags()
+  local tags = {}
+  
+  -- Lua version and features
+  tags.lua = tonumber(_VERSION:match"%d+%.%d+")
+  if table.pack then
+    tags["compat5.2"] = true
+  end
+  if loadstring"return 0xep+9" then
+    tags.hexfloat = true
+  end
+  if loadstring"goto x ::x::" then
+    tags["goto"] = true
+  end
+
+  -- Libraries
+  for _, lib in ipairs{"bit", "ffi", "jit.profile", "table.new"} do
+    if pcall(require, lib) then
+      tags[lib] = true
+    end
+  end
+
+  -- LuaJIT-specific
+  if jit then
+    tags.luajit = tonumber(jit.version:match"%d+%.%d+")
+    tags[jit.arch:lower()] = true
+    if jit.os ~= "Other" then
+      tags[jit.os:lower()] = true
+    end
+    if jit.status() then
+      tags.jit = true
+    end
+    for _, flag in ipairs{select(2, jit.status())} do
+      tags[flag:lower()] = true
+    end
+  end
+  
+  -- Environment
+  if dirsep == "\\" then
+    tags.windows = true
+  end
+  if tags.ffi then
+    local abi = require"ffi".abi
+    for _, param in ipairs{"le", "be", "fpu", "softfp", "hardfp", "eabi"} do
+      if abi(param) then
+        tags[param] = true
+      end
+    end
+    if abi"win" then tags.winabi = true end
+    if abi"32bit" then tags.abi32 = true end
+    if abi"64bit" then tags.abi64 = true end
+  else
+    local bytecode = string.dump(function()end)
+    if bytecode:find"^\27Lua[\80-\89]" then
+      tags[bytecode:byte(7, 7) == 0 and "be" or "le"] = true
+      tags["abi".. (bytecode:byte(9, 9) * 8)] = true
+    end
+  end
+  
+  return tags
+end
+
+local function want_meta(opts, meta)
+  if not opts.want_meta_cache then
+    opts.want_meta_cache = setmetatable({}, {__index = function(t, meta)
+      local result = true
+      for polarity, tag, cond in meta:gmatch"([+-])([^ <>=]+)([<>=0-9.]*)" do
+        local tagval = opts.tags[tag]
+        local condresult
+        if cond == "" or not tagval then
+          condresult = tagval
+        else
+          condresult = assert(loadstring("return (...) ".. cond))(tagval)
+        end
+        if polarity == "-" then
+          condresult = not condresult
+        end
+        if not condresult then
+          result = false
+          break
+        end
+      end
+      t[meta] = result
+      return result
+    end})
+  end
+  return opts.want_meta_cache[meta]
+end
+
+local function parse_args(t)
+  local opts = {
+    tags = default_tags(),
+    want_meta = want_meta,
+  }
+  local result = opts
+  
+  local i, tlen = 1, #t
+  local joinedval = ""
+  local function flagval()
+    local val
+    if joinedval ~= "" then
+      val = joinedval:sub(2)
+      joinedval = ""
+    else
+      val = t[i]
+      if not val then error("Expected value after ".. t[i-1]) end
+      i = i + 1
+    end
+    return val
+  end
+  
+  while i <= tlen do
+    local arg = t[i]
+    i = i + 1
+    if arg:sub(1, 2) == "--" then
+      arg, joinedval = arg:match"^([^=]+)(=?.*)$"
+      if arg == "--quiet" then
+        opts.quiet = true
+      elseif arg == "--shuffle" then
+        local seed = tonumber(flagval())
+        if not seed then error("Expected numeric seed after --shuffle") end
+        opts.shuffle = seed
+      elseif arg == "--shard" then
+        local i, s = flagval():match"^(%d+)/(%d+)$"
+        if not s then error("Expected integer/integer after --shard") end
+        opts.shard = {initial = tonumber(i), step = tonumber(s)}
+      elseif arg == "--version" then
+        io_write("LuaJIT test-suite runner v0.1\n")
+        result = nil
+      elseif arg == "--help" then
+        io_write("Usage: ", _G and _G.arg and _G.arg[-1] or "luajit", " ")
+        io_write(own_file, " [flags] [tags] [root] [numbers]\n")
+        io_write"\n"
+        io_write"Root specifies either a directory of tests, or the name of\n"
+        io_write"a particular .lua test file, defaulting to all tests if not given.\n"
+        io_write"Tags are specified in the form +tag_name or -tag_name, and\n"
+        io_write"are used to turn on or off groups of tests. For example,\n"
+        io_write"pass -ffi to skip tests relating to the ffi library, or\n"
+        io_write"pass +slow to enable running of slow tests.\n"
+        io_write"Numbers can be passed to only run particular tests.\n"
+        io_write"The available flags are:\n"
+        io_write"  --quiet\n"
+        io_write"  --shuffle=SEED\n"
+        io_write"  --shard=INDEX/NUM_SHARDS\n"
+        io_write"  --version\n"
+        io_write"  --help\n"
+        result = nil
+      else
+        error("Unsupported flag: ".. arg)
+      end
+      if joinedval ~= "" then
+        error(arg .." does not expect an argument")
+      end
+    elseif arg:find"^[-+]" then
+      opts.tags[arg:sub(2)] = (arg:sub(1, 1) == "+")
+    elseif arg:find"^%d+$" then
+      if not opts.numbers_to_run then
+        opts.numbers_to_run = {}
+      end
+      opts.numbers_to_run[tonumber(arg)] = true
+    elseif not opts.root then
+      opts.root = arg
+    else
+      error("Unexpected argument ".. arg)
+    end
+  end
+  return result
+end
+
+local function scan_tests(path, opts)
+  if path:sub(-4, -4) == "." then
+    local f = assert(io_open(path, "rb"))
+    local contents = f:read"*a"
+    f:close()
+    local prefix = "return {"
+    local code =  contents:gsub("()(do +%-%-%- +)([^\r\n]+)",
+      function(pos, marker, info)
+        if pos ~= 1 then
+          pos = pos - 1
+          if contents:sub(pos, pos) ~= "\n" then
+            return marker .. info
+          end
+        end
+        local result = ("%s%q,function()"):format(prefix, info)
+        prefix = ","
+        if info:find" !lex" and not opts:want_meta(info:sub((info:find" +[-+@!]"))) then
+          result = result .."end--[========["
+          prefix = "]========]".. prefix
+        end
+        return result
+      end)
+    if prefix:sub(-1) ~= "," then
+      error("No tests found in ".. path)
+    end
+    prefix = prefix .."}"
+    return assert(load(function()
+      local result = code
+      code = code ~= prefix and prefix or nil
+      return result
+    end, "@".. path))()
+  else
+    if path ~= "" and path:sub(-1) ~= "/" and path:sub(-1) ~= dirsep then
+      path = path .. dirsep
+    end
+    local result = {}
+    local i = 1
+    for line in io_lines(path .."index") do
+      if line ~= "" then
+        local metaidx = line:find" +[-+@]"
+        local name = line
+        local want_these = true
+        if metaidx then
+          name = line:sub(1, metaidx - 1)
+          want_these = opts:want_meta(line:sub(metaidx))
+        end
+        if want_these then
+          result[i] = line
+          result[i+1] = scan_tests(path .. name, opts)
+          i = i + 2
+        end
+      end
+    end
+    return result
+  end
+end
+
+local function upvalue_iterator(f, i)
+  i = i + 1
+  local name, val = debug.getupvalue(f, i)
+  return name and i, name, val
+end
+
+local function upvalues_of(f)
+  return upvalue_iterator, f, 0
+end
+
+local function append_tree_to_plan(test_tree, opts, plan, prefix)
+  local prefi
+  for i = 1, #test_tree, 2 do
+    local info = test_tree[i]
+    local name = info
+    local want_these = true
+    local metaidx = info:find" +[-+@!]"
+    if metaidx then
+      name = info:sub(1, metaidx - 1)
+      want_these = opts:want_meta(info:sub(metaidx))
+    end
+    local planlen = #plan
+    if want_these then
+      local test = test_tree[i+1]
+      if type(test) == "table" then
+        append_tree_to_plan(test, opts, plan, prefix .. name .. dirsep)
+      else
+        if not prefi then
+          prefi = prefix:sub(1, -2)
+        end
+        plan[#plan+1] = {prefi, name, test}
+      end
+    end
+    if metaidx and info:find"!" then
+      for modifier in info:gmatch"!([^ ]+)" do
+        if modifier == "private_G" then
+          local G = setmetatable({}, {__index = _G})
+          G._G = G
+          local function Gfn() return G end
+          for i = planlen+1, #plan do
+            local test = plan[i][3]
+            if setfenv then
+              setfenv(test, G)
+            else
+              for i, name in upvalues_of(test) do
+                if name == "_ENV" then
+                  debug.upvaluejoin(test, i, Gfn, 1)
+                  break
+                end
+              end
+            end
+          end
+        elseif modifier == "lex" then
+          -- Handled during test scanning
+        else
+          error("Unsupported modifier \"".. modifier .."\" in ".. prefix)
+        end
+      end
+    end
+  end
+  return plan
+end
+
+local function seal_globals()
+  local sealed_mt = {__newindex = function()
+    error("Tests should not mutate global state", 3)
+  end}
+  local function seal(t)
+    if getmetatable(t) then return end
+    setmetatable(t, sealed_mt)
+    for k, v in pairs(t) do
+      if type(v) == "table" then seal(v) end
+    end
+  end
+  seal(_G)
+  
+  if getmetatable(package.loaded) == sealed_mt then
+    setmetatable(package.loaded, nil)
+  end
+end
+
+local function check_package_path()
+  local ok, res = pcall(require, "common.test_runner_canary")
+  if not ok then
+    if own_dir then
+      local _, psep, placeholder = package.config:match"^(.-)\n(.-)\n(.-)\n"
+      package.path = package.path .. psep .. own_dir .. placeholder ..".lua"
+      ok, res = pcall(require, "common.test_runner_canary")
+    end
+    if not ok then
+      error(res)
+    end
+  end
+  assert(res == "canary is alive")
+end
+
+local function mutate_plan(plan, opts)
+  if opts.shuffle then
+    math.randomseed(opts.shuffle)
+    for i = #plan, 2, -1 do
+      local n = math_random(1, i)
+      plan[i], plan[n] = plan[n], plan[i]
+    end
+  end
+  if opts.shard then
+    local shard_plan = {}
+    for i = opts.shard.initial, #plan, opts.shard.step do
+      shard_plan[#shard_plan + 1] = plan[i]
+    end
+    plan = shard_plan
+  end
+  if opts.numbers_to_run then
+    for i = 1, #plan do
+      if not opts.numbers_to_run[i] then
+        plan[i][3] = false
+      end
+    end
+    for k in pairs(opts.numbers_to_run) do
+      if not plan[k] then
+        error("Test number ".. k .." is not part of the plan")
+      end
+    end
+  end
+  return plan
+end
+
+local function execute_plan(plan, opts)
+  if #plan == 0 then
+    error("No tests selected")
+  end
+  local progress_format = ("[%%%dd/%d] "):format(#tostring(#plan), #plan)
+  local num_tests_run = 0
+  local fail_numbers = {}
+  for i = 1, #plan do
+    local plan_i = plan[i]
+    local test = plan_i[3]
+    if test then
+      local file, name = plan_i[1], plan_i[2]
+      if not opts.quiet then
+        io_write(progress_format:format(i), file)
+        io_write(file == "" and "" or " --- ", name, "\n")
+      end
+      local ok, err = xpcall(test, debug_traceback)
+      if not ok then
+        if opts.quiet then
+          io_write(progress_format:format(i), file)
+          io_write(file == "" and "" or " --- ", name, "\n")
+        end
+        fail_numbers[#fail_numbers + 1] = i
+        io_write(err, "\n")
+      end
+      num_tests_run = num_tests_run + 1
+    end
+  end
+  if #fail_numbers == 0 then
+    io_write(num_tests_run, " passed\n")
+    return true
+  else
+    io_write(num_tests_run - #fail_numbers, " passed, ")
+    io_write(#fail_numbers, " failed\n")
+    if not opts.quiet and num_tests_run ~= #fail_numbers then
+      io_write("to run just failing tests, pass command line arguments: ")
+      io_write(table.concat(fail_numbers, " "), "\n")
+    end
+    return false
+  end
+end
+
+local opts = parse_args{...}
+if not opts then
+  return
+end
+seal_globals()
+check_package_path()
+local test_tree = scan_tests(opts.root or own_dir or "", opts)
+local plan = append_tree_to_plan(test_tree, opts, {}, "")
+plan = mutate_plan(plan, opts)
+local all_good = execute_plan(plan, opts)
+if not all_good then
+  os.exit(1)
+end
diff --git a/test/LuaJIT-tests/trace/exit_frame.lua b/test/LuaJIT-tests/trace/exit_frame.lua
new file mode 100644
index 0000000..9537c56
--- /dev/null
+++ b/test/LuaJIT-tests/trace/exit_frame.lua
@@ -0,0 +1,79 @@
+do --- global assignments !private_G
+  g = 0
+  gf = 1
+  gz = 2
+
+  local function f(i)
+    if i == 90 then
+      gf = gf + 1
+      return true
+    end
+    g = g + 1
+  end
+
+  local function z(i)
+    if f(i) then
+      gz = gz + 1
+    end
+  end
+
+  for j=1,5 do
+    for i=1,100 do z(i) end
+  end
+
+  assert(g == 495)
+  assert(gf == 6)
+  assert(gz == 7)
+end
+
+do --- mutual recursion
+  local f, g
+  function f(j)
+    if j >= 0 then return g(j-1) end
+  end
+  function g(j)
+    for i=1,200 do
+      if i > 100 then return f(j) end
+    end
+  end
+  for k=1,20 do g(20) end
+end
+
+do --- multi-path mutual recursion
+  local f, g
+  function f(j, k)
+    if j >= 0 then return g(j-1, k) end
+    if k >= 0 then return g(20, k-1) end
+  end
+  function g(j, k)
+    for i=1,200 do
+      if i > 100 then return f(j, k) end
+    end
+  end
+  g(20, 20)
+end
+
+do --- late mutual recursion
+  local k = 0
+  local f, g
+
+  function g(a)
+    -- 'a' is an SLOAD #1 from f's frame and still at slot #1
+    -- Avoid losing a in exit if the SLOAD is ignored
+    if k > 10 then k = 0 end
+    k= k + 1
+    return f(a)
+  end
+
+  function f(a,b,c,d,e)
+    if not e then e =1 end
+    a=a+1
+    if a > 1000 then return end
+    for i=1,100 do
+      e=e+1
+      if i > 90 then return g(a) end
+    end
+  end
+
+  f(1,2,3,4,5)
+end
diff --git a/test/LuaJIT-tests/trace/exit_growstack.lua b/test/LuaJIT-tests/trace/exit_growstack.lua
new file mode 100644
index 0000000..658a31a
--- /dev/null
+++ b/test/LuaJIT-tests/trace/exit_growstack.lua
@@ -0,0 +1,28 @@
+do --- Exit needs to grow stack before slot fill.
+  local function f(i)
+    local a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a;
+    local a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a;
+    local a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a;
+    if i==90 then return end 
+  end
+  for j=1,5 do
+    collectgarbage() -- Shrink stack.
+    for i=1,100 do f(i) end
+  end
+end
+
+do --- Exit needs to grow stack after slot fill.
+  local function g(i)
+    if i==90 then return end
+    do return end
+    do
+    local a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a;
+    local a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a;
+    local a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a;
+    end
+  end
+  for j=1,5 do
+    collectgarbage() -- Shrink stack.
+    for i=1,100 do g(i) end
+  end
+end
diff --git a/test/LuaJIT-tests/trace/exit_jfuncf.lua b/test/LuaJIT-tests/trace/exit_jfuncf.lua
new file mode 100644
index 0000000..67ad7c3
--- /dev/null
+++ b/test/LuaJIT-tests/trace/exit_jfuncf.lua
@@ -0,0 +1,30 @@
+do --- everything
+  local assert = assert
+
+  local function rec(a, b, c, d, e, f)
+    assert(f == a+1)
+    if b == 0 then return 7 end
+    do local x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31, x32, x33, x34, x35, x36, x37, x38, x39, x40, x41, x42, x43, x44, x45, x46, x47, x48, x49, x50, x51, x52, x53, x54, x55, x56, x57, x58, x59, x60, x61, x62, x63, x64, x65, x66, x67, x68, x69, x70, x71, x72, x73, x74, x75, x76, x77, x78, x79, x80, x81, x82, x83, x84, x85, x86, x87, x88, x89, x90, x91, x92, x93, x94, x95, x96, x97, x98, x99, x100 end
+    return rec(a, b-1, c, d, e, f)+1
+  end
+
+  -- Compile recursive function.
+  assert(rec(42, 200, 1, 2, 3, 43) == 207)
+
+  local function trec()
+    return rec(42, 0, 1, 2, 3, 43)
+  end
+
+  -- Compile function jumping to JFUNCF.
+  for i=1,200 do
+    gcinfo()
+    assert(trec() == 7)
+  end
+
+  -- Shrink stack.
+  for j=1,10 do collectgarbage() end
+
+  -- Cause an exit due to stack growth with PC pointing to JFUNCF.
+  -- Needs to load RD with nres+1 and not with the bytecode RD.
+  assert(trec() == 7)
+end
diff --git a/test/LuaJIT-tests/trace/gc64_slot_revival.lua b/test/LuaJIT-tests/trace/gc64_slot_revival.lua
new file mode 100644
index 0000000..40b9d87
--- /dev/null
+++ b/test/LuaJIT-tests/trace/gc64_slot_revival.lua
@@ -0,0 +1,18 @@
+do --- BC_KNIL
+  local function f(x, y) end
+  for i = 1,100 do
+    f(i, i)
+    f(nil, nil)
+  end
+end
+
+do --- BC_VARG
+  local function f() end
+  local function g(...)
+    f()
+    f(...)
+  end
+  for i = 1,100 do
+    g()
+  end
+end
diff --git a/test/LuaJIT-tests/trace/index b/test/LuaJIT-tests/trace/index
new file mode 100644
index 0000000..ea7a22e
--- /dev/null
+++ b/test/LuaJIT-tests/trace/index
@@ -0,0 +1,7 @@
+exit_frame.lua
+exit_growstack.lua
+exit_jfuncf.lua
+gc64_slot_revival.lua
+phi
+snap.lua
+stitch.lua
diff --git a/test/LuaJIT-tests/trace/phi/copyspill.lua b/test/LuaJIT-tests/trace/phi/copyspill.lua
new file mode 100644
index 0000000..17a8698
--- /dev/null
+++ b/test/LuaJIT-tests/trace/phi/copyspill.lua
@@ -0,0 +1,53 @@
+do --- mat4mul !private_G
+function mat4mul(a11, a21, a31, a41,
+                 a12, a22, a32, a42,
+                 a13, a23, a33, a43,
+                 a14, a24, a34, a44,
+                 b11, b21, b31, b41,
+                 b12, b22, b32, b42,
+                 b13, b23, b33, b43,
+                 b14, b24, b34, b44)
+  return a11*b11+a21*b12+a31*b13+a41*b14,
+  a11*b21+a21*b22+a31*b23+a41*b24,
+  a11*b31+a21*b32+a31*b33+a41*b34,
+  a11*b41+a21*b42+a31*b43+a41*b44,
+  a12*b11+a22*b12+a32*b13+a42*b14,
+  a12*b21+a22*b22+a32*b23+a42*b24,
+  a12*b31+a22*b32+a32*b33+a42*b34,
+  a12*b41+a22*b42+a32*b43+a42*b44,
+  a13*b11+a23*b12+a33*b13+a43*b14,
+  a13*b21+a23*b22+a33*b23+a43*b24,
+  a13*b31+a23*b32+a33*b33+a43*b34,
+  a13*b41+a23*b42+a33*b43+a43*b44,
+  a14*b11+a24*b12+a34*b13+a44*b14,
+  a14*b21+a24*b22+a34*b23+a44*b24,
+  a14*b31+a24*b32+a34*b33+a44*b34,
+  a14*b41+a24*b42+a34*b43+a44*b44
+end
+
+local a11, a21, a31, a41 = 1, 0, 0, 0
+local a12, a22, a32, a42 = 0, 1, 0, 0
+local a13, a23, a33, a43 = 0, 0, 1, 0
+local a14, a24, a34, a44 = 0, 0, 0, 1
+
+local b11, b21, b31, b41 = 0,  0, -1,  0
+local b12, b22, b32, b42 = 0,  1,  0,  0
+local b13, b23, b33, b43 = 1,  0,  0,  0
+local b14, b24, b34, b44 = 0,  0,  0,  1
+
+for i = 1, 1000 do
+  a11, a21, a31, a41,
+  a12, a22, a32, a42,
+  a13, a23, a33, a43,
+  a14, a24, a34, a44 = mat4mul(a11, a21, a31, a41,
+                               a12, a22, a32, a42,
+                               a13, a23, a33, a43,
+                               a14, a24, a34, a44,
+                               b11, b21, b31, b41,
+                               b12, b22, b32, b42,
+                               b13, b23, b33, b43,
+                               b14, b24, b34, b44)
+end
+assert(a11 == 1)
+assert(a31 == 0)
+end
diff --git a/test/LuaJIT-tests/trace/phi/index b/test/LuaJIT-tests/trace/phi/index
new file mode 100644
index 0000000..74a0733
--- /dev/null
+++ b/test/LuaJIT-tests/trace/phi/index
@@ -0,0 +1,3 @@
+copyspill.lua
+ref.lua
+rotate.lua
diff --git a/test/LuaJIT-tests/trace/phi/ref.lua b/test/LuaJIT-tests/trace/phi/ref.lua
new file mode 100644
index 0000000..3662912
--- /dev/null
+++ b/test/LuaJIT-tests/trace/phi/ref.lua
@@ -0,0 +1,131 @@
+do --- rref points into invariant part 1
+  local x,y=1,2; for i=1,100 do x=x+y; y=i end
+  assert(y == 100)
+end
+
+do --- rref points into invariant part 2
+  local x,y=1,2; for i=1,100.5 do x=x+y; y=i end
+  assert(y == 100)
+end
+
+do --- rref points into invariant part 3
+  local x,y=1,2; for i=1,100 do x,y=y,x end
+  assert(x == 1)
+  assert(y == 2)
+end
+
+do --- rref points into invariant part 4
+  local x,y,z=1,2,3; for i=1,100 do x,y,z=y,z,x end
+  assert(x == 2)
+  assert(y == 3)
+  assert(z == 1)
+end
+
+do --- rref points into invariant part 5
+  local x,y,z=1,2,3; for i=1,100 do x,y,z=z,x,y end
+  assert(x == 3)
+  assert(y == 1)
+  assert(z == 2)
+end
+
+do --- rref points into invariant part 6
+  local a,x,y,z=0,1,2,3; for i=1,100 do a=a+x; x=y; y=z; z=i end
+  assert(a == 4759)
+  assert(x == 98)
+  assert(y == 99)
+  assert(z == 100)
+end
+
+do --- variant slot, but no corresponding SLOAD i-1
+  local x,y=1,2; for i=1,100 do x=i; y=i-1 end
+  assert(x == 100)
+  assert(y == 99)
+end
+
+do --- variant slot, but no corresponding SLOAD i+1
+  local x,y=1,2; for i=1,100 do x=i; y=i+1 end
+  assert(x == 100)
+  assert(y == 101)
+end
+
+do --- variant slot, but no corresponding SLOAD side exit
+  local x=0; for i=1,100 do if i==90 then break end x=i end
+  assert(x == 89)
+end
+
+do --- dup lref from variant slot (suppressed)
+  local x,y=1,2; for i=1,100 do x=i; y=i end
+  assert(x == 100)
+  assert(y == 100)
+end
+
+do --- const rref
+  local x,y=1,2 local bxor,tobit=bit.bxor,bit.tobit;
+  for i=1,100 do x=bxor(i,y); y=tobit(i+1) end
+  assert(x == 0)
+  assert(y == 101)
+end
+
+do --- dup rref (ok)
+  local x,y,z1,z2=1,2,3,4 local bxor,tobit=bit.bxor,bit.tobit;
+  for i=1,100 do x=bxor(i,y); z2=tobit(i+5); z1=bxor(x,i+5); y=tobit(i+1) end
+  assert(x == 0)
+  assert(y == 101)
+  assert(z1 == 105)
+  assert(z2 == 105)
+end
+
+do --- variant slot, no corresponding SLOAD
+  for i=1,5 do
+    local a, b = 1, 2
+    local bits = 0
+    while a ~= b do
+      bits = bits + 1
+      a = b
+      b = bit.lshift(b, 1)
+    end
+    assert(bits == 32)
+  end
+end
+
+do --- don't eliminate PHI if referenced from snapshot
+  local t = { 0 }
+  local a = 0
+  for i=1,100 do
+    local b = t[1]
+    t[1] = i + a
+    a = b
+  end
+  assert(a == 2500)
+  assert(t[1] == 2550)
+end
+
+do --- don't eliminate PHI if referenced from snapshot
+  local x = 1
+  local function f()
+    local t = {}
+    for i=1,200 do t[i] = i end
+    for i=1,200 do
+      local x1 = x
+      x = t[i]
+      if i > 100 then return x1 end
+    end
+  end
+  assert(f() == 100)
+end
+
+do --- don't eliminate PHI if referenced from another non-redundant PHI
+  local t = {}
+  for i=1,256 do
+    local a, b, k = i, math.floor(i/2), -i
+    while a > 1 and t[b] > k do
+      t[a] = t[b]
+      a = b
+      b = math.floor(a/2)
+    end
+    t[a] = k
+  end
+  local x = 0
+  for i=1,256 do x = x + bit.bxor(i, t[i]) end
+  assert(x == -41704)
+end
diff --git a/test/LuaJIT-tests/trace/phi/rotate.lua b/test/LuaJIT-tests/trace/phi/rotate.lua
new file mode 100644
index 0000000..cb751e0
--- /dev/null
+++ b/test/LuaJIT-tests/trace/phi/rotate.lua
@@ -0,0 +1,149 @@
+do --- rot8
+  local function rot8r(n)
+    local a,b,c,d,e,f,g,h=1,2,3,4,5,6,7,8
+    for x=1,n do
+      a,b,c,d,e,f,g,h=h,a,b,c,d,e,f,g
+    end
+    return table.concat{a,b,c,d,e,f,g,h}
+  end
+
+  local function rot8l(n)
+    local a,b,c,d,e,f,g,h=1,2,3,4,5,6,7,8
+    for x=1,n do
+      a,b,c,d,e,f,g,h=b,c,d,e,f,g,h,a
+    end
+    return table.concat{a,b,c,d,e,f,g,h}
+  end
+
+  assert(rot8r(0) == "12345678")
+  assert(rot8r(10) == "78123456")
+  assert(rot8r(105) == "81234567")
+  assert(rot8r(0) == "12345678")
+  assert(rot8r(1) == "81234567")
+  assert(rot8r(2) == "78123456")
+  assert(rot8r(0) == "12345678")
+  assert(rot8r(1) == "81234567")
+  assert(rot8r(2) == "78123456")
+  assert(rot8r(105) == "81234567")
+
+  assert(rot8l(0) == "12345678")
+  assert(rot8l(10) == "34567812")
+  assert(rot8l(105) == "23456781")
+  assert(rot8l(0) == "12345678")
+  assert(rot8l(1) == "23456781")
+  assert(rot8l(2) == "34567812")
+  assert(rot8l(0) == "12345678")
+  assert(rot8l(1) == "23456781")
+  assert(rot8l(2) == "34567812")
+
+  assert(rot8r(100) == "56781234")
+  assert(rot8l(100) == "56781234")
+end
+
+do --- rot9
+  local function rot9r(n)
+    local a,b,c,d,e,f,g,h,i=1,2,3,4,5,6,7,8,9
+    for x=1,n do
+      a,b,c,d,e,f,g,h,i=i,a,b,c,d,e,f,g,h
+    end
+    return table.concat{a,b,c,d,e,f,g,h,i}
+  end
+
+  local function rot9l(n)
+    local a,b,c,d,e,f,g,h,i=1,2,3,4,5,6,7,8,9
+    for x=1,n do
+      a,b,c,d,e,f,g,h,i=b,c,d,e,f,g,h,i,a
+    end
+    return table.concat{a,b,c,d,e,f,g,h,i}
+  end
+
+  assert(rot9r(0) == "123456789")
+  assert(rot9r(10) == "912345678")
+  assert(rot9r(105) == "456789123")
+  assert(rot9r(0) == "123456789")
+  assert(rot9r(1) == "912345678")
+  assert(rot9r(2) == "891234567")
+  assert(rot9r(0) == "123456789")
+  assert(rot9r(1) == "912345678")
+  assert(rot9r(2) == "891234567")
+  assert(rot9r(105) == "456789123")
+
+  assert(rot9l(0) == "123456789")
+  assert(rot9l(10) == "234567891")
+  assert(rot9l(105) == "789123456")
+  assert(rot9l(0) == "123456789")
+  assert(rot9l(1) == "234567891")
+  assert(rot9l(2) == "345678912")
+  assert(rot9l(0) == "123456789")
+  assert(rot9l(1) == "234567891")
+  assert(rot9l(2) == "345678912")
+
+  assert(rot9r(100) == "912345678")
+  assert(rot9l(100) == "234567891")
+end
+
+do --- rot18
+  local function rot18r(N)
+    local a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18
+    for x=1,N do
+      a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r=r,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q
+    end
+    return table.concat{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r}
+  end
+
+  local function rot18l(N)
+    local a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18
+    for x=1,N do
+      a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r=b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,a
+    end
+    return table.concat{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r}
+  end
+
+  assert(rot18r(0)	== "123456789101112131415161718")
+  assert(rot18r(10)	== "910111213141516171812345678")
+  assert(rot18r(105)	== "456789101112131415161718123")
+  assert(rot18r(0)	== "123456789101112131415161718")
+  assert(rot18r(1)	== "181234567891011121314151617")
+  assert(rot18r(2)	== "171812345678910111213141516")
+  assert(rot18r(0)	== "123456789101112131415161718")
+  assert(rot18r(1)	== "181234567891011121314151617")
+  assert(rot18r(2)	== "171812345678910111213141516")
+  assert(rot18r(105)	== "456789101112131415161718123")
+
+  assert(rot18l(0)	== "123456789101112131415161718")
+  assert(rot18l(10)	== "111213141516171812345678910")
+  assert(rot18l(105)	== "161718123456789101112131415")
+  assert(rot18l(0)	== "123456789101112131415161718")
+  assert(rot18l(1)	== "234567891011121314151617181")
+  assert(rot18l(2)	== "345678910111213141516171812")
+  assert(rot18l(0)	== "123456789101112131415161718")
+  assert(rot18l(1)	== "234567891011121314151617181")
+  assert(rot18l(2)	== "345678910111213141516171812")
+
+  assert(rot18r(100)	== "910111213141516171812345678")
+  assert(rot18l(100)	== "111213141516171812345678910")
+end
+
+do --- rotx
+  local function rot9r(n, m)
+    local a,b,c,d,e,f,g,h,i=1,2,3,4,5,6,7,8,9
+    local s = ""
+    for x=1,n do
+      a,b,c,d,e,f,g,h,i=i,a,b,c,d,e,f,g,h
+      if x == m then s = table.concat{a,b,c,d,e,f,g,h,i} end
+      c,d = d,c
+    end
+    return table.concat{a,b,c,d,e,f,g,h,i, s}
+  end
+
+  assert(rot9r(0,0) == "123456789")
+  assert(rot9r(10,0) == "893124567")
+  assert(rot9r(105,0) == "913245678")
+  assert(rot9r(105,90) == "913245678891324567")
+  assert(rot9r(0,0) == "123456789")
+  assert(rot9r(1,0) == "913245678")
+  assert(rot9r(2,0) == "893124567")
+  assert(rot9r(1,1) == "913245678912345678")
+  assert(rot9r(2,1) == "893124567912345678")
+  assert(rot9r(2,2) == "893124567891324567")
+end
diff --git a/test/LuaJIT-tests/trace/snap.lua b/test/LuaJIT-tests/trace/snap.lua
new file mode 100644
index 0000000..ba26326
--- /dev/null
+++ b/test/LuaJIT-tests/trace/snap.lua
@@ -0,0 +1,47 @@
+do --- gcexit
+  local x = 0
+  local t
+  for i=1,1000 do
+    if i >= 100 then
+      -- causes an exit for atomic phase
+      -- must not merge snapshot #0 with comparison since it has the wrong PC
+      if i < 150 then x=x+1 end
+      t = {i}
+    end
+  end
+  assert(x == 50)
+  assert(t[1] == 1000)
+end
+
+
+do --- top !private_G
+  function randomtable(entries, depth)
+    if depth == 0 then
+      return tostring(math.random(2)) -- snapshot between return and CALLMT
+    end
+    local t = {}
+    for k=1,entries do
+      t[k] = randomtable(entries, depth-1)
+    end
+    return t
+  end
+
+  local t = randomtable(10, 2)
+end
+
+do --- top2
+  local function f()
+    gcinfo()
+    local _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_
+    local _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_
+    local _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_
+    local _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_
+    local _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_
+    local _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_
+  end
+
+  for i=1,100 do
+    f()
+    if i % 3 == 0 then collectgarbage() end
+  end
+end
diff --git a/test/LuaJIT-tests/trace/stitch.lua b/test/LuaJIT-tests/trace/stitch.lua
new file mode 100644
index 0000000..3f7f973
--- /dev/null
+++ b/test/LuaJIT-tests/trace/stitch.lua
@@ -0,0 +1,19 @@
+do --- octal
+  local tonumber = tonumber
+  local function octal(s) return tonumber(s, 8) end
+  for i=1,100 do
+    octal("1")
+    octal("1")
+    octal("1")
+  end
+end
+
+do --- coroutines
+  local t = {
+    [0] = function() end,
+    coroutine.wrap(function() while true do coroutine.yield() end end),
+  }
+  for i=1,100 do
+    t[i % 2]()
+  end
+end
diff --git a/test/LuaJIT-tests/unportable/ffi_arith_int64.lua b/test/LuaJIT-tests/unportable/ffi_arith_int64.lua
new file mode 100644
index 0000000..c05e02a
--- /dev/null
+++ b/test/LuaJIT-tests/unportable/ffi_arith_int64.lua
@@ -0,0 +1,68 @@
+local ffi = require("ffi")
+
+local int = ffi.typeof("int")
+
+local inp = {
+  0, 0.5, -0.5, 1.5, -1.5, 1, -1, 2, -2, 37, -37, false,
+  int(0), int(1), int(-1), int(2), int(-2), int(37), int(-37), false,
+  0ll, 1ll, -1ll, 2ll, -2ll, 37ll, -37ll, false,
+  0ull, 1ull, -1ull, 2ull, -2ull, 37ull, -37ull,
+}
+
+local function cksum(s, r)
+  local z = 0
+  for i=1,#s do z = (z + string.byte(s, i)*i) % 2147483629 end
+  if z ~= r then
+    error("test failed (got "..z..", expected "..r..") for:\n"..s, 3)
+  end
+end
+
+local function tostr(n)
+  if type(n) == "cdata" then return tostring(n)
+  elseif n ~= n then return "nan"
+  else return string.format("%+1.5g", n) end
+end
+
+local function check(f, expected, y)
+  local inp = inp
+  local out = {}
+  for i=1,#inp do
+    if inp[i] then out[i] = tostr(f(inp[i], y)) else out[i] = "\n" end
+  end
+  local got = string.gsub(table.concat(out, " ").."\n", "\n ", "\n")
+  cksum(got, expected)
+end
+
+jit.off(check)
+
+local function check2(f, exparray)
+  local k = 1
+  for j=1,#inp do
+    local y = inp[j]
+    if y then
+      check(f, exparray[k], y)
+      k = k + 1
+    end
+  end
+end
+
+check(function(x) return -x end, 1174528)
+
+check2(function(x, y) return x+y end,
+{1171039,1239261,1239303,1011706,1490711,949996,1415869,756412,1682910,768883,2201023,1265370,1015700,1556902,807607,1862947,814710,2423097,1265370,1015700,1556902,807607,1862947,814710,2423097,4833809,2909723,7784653,1736671,10743770,1126700,13324037,})
+
+check2(function(x, y) return x-y end,
+{1171039,1239303,1239261,1490711,1011706,1415869,949996,1682910,756412,2201023,768883,1265370,1556902,1015700,1862947,807607,2423097,814710,1265370,1556902,1015700,1862947,807607,2423097,814710,4833809,7784653,2909723,10743770,1736671,13324037,1126700,})
+
+check2(function(x, y) return x*y end,
+{470257,637182,637132,1308150,1311627,1171039,1174528,1083877,1087553,1561321,1564869,564568,1265370,1269122,1265037,1268973,1643392,1647266,564568,1265370,1269122,1265037,1268973,1643392,1647266,827768,4833809,4847593,4823713,4838210,5230281,5244035,})
+
+check2(function(x, y) return x/y end,
+{7946210,7360895,7360865,1580465,927251,1171039,622069,1252901,704706,1542087,960011,14749620,1265370,695208,1188639,661058,1049280,587329,14749620,1265370,695208,1188639,661058,1049280,587329,15042810,4833809,828129,4559889,828509,4208862,828929,})
+
+
+check2(function(x, y) return x%y end,
+{7653740,7304160,7304160,527871,851988,527061,850910,556674,717022,610671,613599,14749620,564568,894526,618652,785052,641760,644574,14749620,564568,894526,618652,785052,641760,644574,15042810,827768,2913108,829285,1737261,951059,959905,})
+
+check2(function(x, y) return x^y end,
+{471871,702627,720692,1385612,1803393,1171039,1772007,763817,1583994,4486762,2380423,566647,1265370,2319256,770581,1990479,4566660,2319835,566647,1265370,2319256,770581,1990479,4566660,2319835,830322,4833809,4644705,1071753,2822313,7709069,4647021,})
diff --git a/test/LuaJIT-tests/unportable/math_special.lua b/test/LuaJIT-tests/unportable/math_special.lua
new file mode 100644
index 0000000..4916101
--- /dev/null
+++ b/test/LuaJIT-tests/unportable/math_special.lua
@@ -0,0 +1,55 @@
+
+local inp = { 0, -"0", 0.5, -0.5, 1, -1, 1/0, -1/0, 0/0 }
+
+local function tostr(n)
+  if n == 0 and 1/n < 0 then return "-0"
+  elseif 1/n == 0 then return n < 0 and "-inf" or "+inf"
+  elseif n ~= n then return "nan"
+  else return string.format("%+1.5g", n) end
+end
+
+local function check(f, expected)
+  local inp = inp
+  local out = {}
+  for i=1,#inp do out[i] = tostr(f(inp[i])) end
+  local got = table.concat(out, " ")
+  if got ~= expected then
+    error("got: \""..got.."\"\nexpected: \""..expected.."\"", 2)
+  end
+end
+
+check(function(x) return x end, "+0 -0 +0.5 -0.5 +1 -1 +inf -inf nan")
+
+local powcheck = {
+  "+1 +1 +1 +1 +1 +1 +1 +1 +1",
+  "+1 +1 +1 +1 +1 +1 +1 +1 +1",
+  "+0 +0 +0.70711 nan +1 nan +inf +inf nan",
+  "+inf +inf +1.4142 nan +1 nan +0 +0 nan",
+  "+0 -0 +0.5 -0.5 +1 -1 +inf -inf nan",
+  "+inf -inf +2 -2 +1 -1 +0 -0 nan",
+  "+0 +0 +0 +0 +1 +1 +inf +inf nan",
+  "+inf +inf +inf +inf +1 +1 +0 +0 nan",
+  "nan nan nan nan +1 nan nan nan nan",
+}
+for j=1,#inp do
+  local y = inp[j]
+  check(function(x) return x^y end, powcheck[j])
+end
+
+check(math.abs, "+0 +0 +0.5 +0.5 +1 +1 +inf +inf nan")
+check(math.floor, "+0 -0 +0 -1 +1 -1 +inf -inf nan")
+check(math.ceil, "+0 -0 +1 -0 +1 -1 +inf -inf nan")
+check(math.sqrt, "+0 -0 +0.70711 nan +1 nan +inf nan nan")
+check(math.sin, "+0 -0 +0.47943 -0.47943 +0.84147 -0.84147 nan nan nan")
+check(math.cos, "+1 +1 +0.87758 +0.87758 +0.5403 +0.5403 nan nan nan")
+check(math.tan, "+0 -0 +0.5463 -0.5463 +1.5574 -1.5574 nan nan nan")
+check(math.asin, "+0 -0 +0.5236 -0.5236 +1.5708 -1.5708 nan nan nan")
+check(math.acos, "+1.5708 +1.5708 +1.0472 +2.0944 +0 +3.1416 nan nan nan")
+check(math.atan, "+0 -0 +0.46365 -0.46365 +0.7854 -0.7854 +1.5708 -1.5708 nan")
+check(math.log, "-inf -inf -0.69315 nan +0 nan +inf nan nan")
+check(math.log10, "-inf -inf -0.30103 nan +0 nan +inf nan nan")
+check(math.exp, "+1 +1 +1.6487 +0.60653 +2.7183 +0.36788 +inf +0 nan")
+
+-- Pointless: deg, rad, min, max, pow
+-- LATER: %, fmod, frexp, ldexp, modf, sinh, cosh, tanh
+
-- 
2.28.0


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

* [Tarantool-patches] [WIP luajit 05/15] test: change tests to match de5568e
  2021-03-04 10:23 [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites Sergey Kaplun via Tarantool-patches
                   ` (3 preceding siblings ...)
  2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 04/15] test: add LuaJIT-test-cleanup test suite Sergey Kaplun via Tarantool-patches
@ 2021-03-04 10:23 ` Sergey Kaplun via Tarantool-patches
  2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 06/15] test: change tests to match c198167 Sergey Kaplun via Tarantool-patches
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-04 10:23 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

Functions math.mod() and string.gfind() were removed in commit de5568e
in original LuaJIT repository.

Part of tarantool/tarantool#4064
Part of tarantool/tarantool#4473
---
Author: Mergen Imeev <imeevma@gmail.com>
Sergey Kaplun <skaplun@tarantool.org>: glanced commit message

 test/LuaJIT-tests/lib/contents.lua | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/test/LuaJIT-tests/lib/contents.lua b/test/LuaJIT-tests/lib/contents.lua
index a1d8b9b..e9fc1bc 100644
--- a/test/LuaJIT-tests/lib/contents.lua
+++ b/test/LuaJIT-tests/lib/contents.lua
@@ -55,7 +55,7 @@ do --- math
 end
 
 do --- pre-5.2 math +lua<5.2 -compat5.2
-  assert(math.mod)
+  assert(not math.mod)
   assert(math.log10)
 end
 
@@ -69,7 +69,7 @@ do --- string
 end
 
 do --- pre-5.2 string +lua<5.2 -compat5.2
-  assert(string.gfind)
+  assert(not string.gfind)
 end
 
 do --- 5.2 string +lua>=5.2
-- 
2.28.0


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

* [Tarantool-patches] [WIP luajit 06/15] test: change tests to match c198167
  2021-03-04 10:23 [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites Sergey Kaplun via Tarantool-patches
                   ` (4 preceding siblings ...)
  2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 05/15] test: change tests to match de5568e Sergey Kaplun via Tarantool-patches
@ 2021-03-04 10:23 ` Sergey Kaplun via Tarantool-patches
  2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 07/15] test: change tests to match 5a61e1a Sergey Kaplun via Tarantool-patches
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-04 10:23 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

Function table.move() was introduced in commit c198167 in original
LuaJIT repository.

Part of tarantool/tarantool#4064
Part of tarantool/tarantool#4473
---
Author: Mergen Imeev <imeevma@gmail.com>
Sergey Kaplun <skaplun@tarantool.org>: glanced commit message

 test/LuaJIT-tests/lib/contents.lua | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/LuaJIT-tests/lib/contents.lua b/test/LuaJIT-tests/lib/contents.lua
index e9fc1bc..d4afa45 100644
--- a/test/LuaJIT-tests/lib/contents.lua
+++ b/test/LuaJIT-tests/lib/contents.lua
@@ -77,7 +77,7 @@ do --- 5.2 string +lua>=5.2
 end
 
 do --- pre-5.2 table +lua<5.2
-  check(table, "concat:foreach:foreachi:getn:insert:maxn:remove:sort", "pack:unpack:setn:new")
+  check(table, "concat:foreach:foreachi:getn:insert:maxn:move:remove:sort", "pack:unpack:setn:new")
 end
 
 do --- 5.2 table +lua>=5.2
-- 
2.28.0


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

* [Tarantool-patches] [WIP luajit 07/15] test: change tests to match 5a61e1a
  2021-03-04 10:23 [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites Sergey Kaplun via Tarantool-patches
                   ` (5 preceding siblings ...)
  2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 06/15] test: change tests to match c198167 Sergey Kaplun via Tarantool-patches
@ 2021-03-04 10:23 ` Sergey Kaplun via Tarantool-patches
  2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 08/15] test: change LuaJIT suite tests to match b4e6bf0 Sergey Kaplun via Tarantool-patches
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-04 10:23 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

Module misc was introduced in commit 5a61e1a in tarantool/LuaJIT
repository.

Part of tarantool/tarantool#4064
Part of tarantool/tarantool#4473
---
Author: Mergen Imeev <imeevma@gmail.com>
Sergey Kaplun <skaplun@tarantool.org>: glanced commit message

 test/LuaJIT-tests/lib/contents.lua | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/test/LuaJIT-tests/lib/contents.lua b/test/LuaJIT-tests/lib/contents.lua
index d4afa45..9671f0e 100644
--- a/test/LuaJIT-tests/lib/contents.lua
+++ b/test/LuaJIT-tests/lib/contents.lua
@@ -19,7 +19,7 @@ local function check(m, expected, exclude)
 end
 
 do --- base
-  check(_G, "_G:_VERSION:arg:assert:collectgarbage:coroutine:debug:dofile:error:getmetatable:io:ipairs:load:loadfile:math:next:os:package:pairs:pcall:print:rawequal:rawget:rawset:require:select:setmetatable:string:table:tonumber:tostring:type:xpcall", "rawlen:bit:bit32:jit:gcinfo:setfenv:getfenv:loadstring:unpack:module:newproxy")
+  check(_G, "_G:_VERSION:arg:assert:collectgarbage:coroutine:debug:dofile:error:getmetatable:io:ipairs:load:loadfile:math:misc:next:os:package:pairs:pcall:print:rawequal:rawget:rawset:require:select:setmetatable:string:table:tonumber:tostring:type:xpcall", "rawlen:bit:bit32:jit:gcinfo:setfenv:getfenv:loadstring:unpack:module:newproxy")
 end
 
 do --- pre-5.2 base +lua<5.2
@@ -139,7 +139,7 @@ do --- package.loaded
       loaded[k] = v
     end
   end
-  check(loaded, "_G:coroutine:debug:io:math:os:package:string:table", "bit:bit32:common:ffi:jit:table.new")
+  check(loaded, "_G:coroutine:debug:io:math:misc:os:package:string:table", "bit:bit32:common:ffi:jit:table.new")
 end
 
 do --- bit +bit
-- 
2.28.0


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

* [Tarantool-patches] [WIP luajit 08/15] test: change LuaJIT suite tests to match b4e6bf0
  2021-03-04 10:23 [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites Sergey Kaplun via Tarantool-patches
                   ` (6 preceding siblings ...)
  2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 07/15] test: change tests to match 5a61e1a Sergey Kaplun via Tarantool-patches
@ 2021-03-04 10:23 ` Sergey Kaplun via Tarantool-patches
  2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 09/15] test: adjust LuaJIT test suite for Tarantool Sergey Kaplun via Tarantool-patches
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-04 10:23 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

Module misc.memprof was introduced in commit b4e6bf0 in tarantool/LuaJIT
repository.

Part of tarantool/tarantool#4064
Part of tarantool/tarantool#4473
---
Author: Mergen Imeev <imeevma@gmail.com>
Sergey Kaplun <skaplun@tarantool.org>: glanced commit message

 test/LuaJIT-tests/lib/contents.lua | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/LuaJIT-tests/lib/contents.lua b/test/LuaJIT-tests/lib/contents.lua
index 9671f0e..45c07eb 100644
--- a/test/LuaJIT-tests/lib/contents.lua
+++ b/test/LuaJIT-tests/lib/contents.lua
@@ -139,7 +139,7 @@ do --- package.loaded
       loaded[k] = v
     end
   end
-  check(loaded, "_G:coroutine:debug:io:math:misc:os:package:string:table", "bit:bit32:common:ffi:jit:table.new")
+  check(loaded, "_G:coroutine:debug:io:math:misc:misc.memprof:os:package:string:table", "bit:bit32:common:ffi:jit:table.new")
 end
 
 do --- bit +bit
-- 
2.28.0


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

* [Tarantool-patches] [WIP luajit 09/15] test: adjust LuaJIT test suite for Tarantool
  2021-03-04 10:23 [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites Sergey Kaplun via Tarantool-patches
                   ` (7 preceding siblings ...)
  2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 08/15] test: change LuaJIT suite tests to match b4e6bf0 Sergey Kaplun via Tarantool-patches
@ 2021-03-04 10:23 ` Sergey Kaplun via Tarantool-patches
  2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 10/15] test: add lua-Harness test suite Sergey Kaplun via Tarantool-patches
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-04 10:23 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

This patch makes it possible to run LuaJIT test suite using
Tarantool.

It disables these tests from the LuaJIT test suite,
because _G and some modules in Tarantool are different from _G and
modules in LuaJIT:
* 359 lib/contents.lua --- base
* 364 lib/contents.lua --- string
* 366 lib/contents.lua --- pre-5.2 table
* 370 lib/contents.lua --- os
* 371 lib/contents.lua --- debug
* 372 lib/contents.lua --- package
* 374 lib/contents.lua --- package.loaders
* 375 lib/contents.lua --- package.loaded

Part of tarantool/tarantool#4064
Part of tarantool/tarantool#4473
---
Mergen Imeev <imeevma@gmail.com>: Author
Sergey Kaplun <skaplun@tarantool.org>: glanced commit message, made
commit consistence with the tarantool branch.

 test/LuaJIT-tests/lib/contents.lua | 78 ++++++++++++++++++------------
 1 file changed, 47 insertions(+), 31 deletions(-)

diff --git a/test/LuaJIT-tests/lib/contents.lua b/test/LuaJIT-tests/lib/contents.lua
index 45c07eb..eeced86 100644
--- a/test/LuaJIT-tests/lib/contents.lua
+++ b/test/LuaJIT-tests/lib/contents.lua
@@ -18,9 +18,11 @@ local function check(m, expected, exclude)
   end
 end
 
-do --- base
-  check(_G, "_G:_VERSION:arg:assert:collectgarbage:coroutine:debug:dofile:error:getmetatable:io:ipairs:load:loadfile:math:misc:next:os:package:pairs:pcall:print:rawequal:rawget:rawset:require:select:setmetatable:string:table:tonumber:tostring:type:xpcall", "rawlen:bit:bit32:jit:gcinfo:setfenv:getfenv:loadstring:unpack:module:newproxy")
-end
+-- Test is disabled, because _G and some modules in Tarantool
+-- are different from _G and modules in LuaJIT.
+-- do --- base
+--   check(_G, "_G:_VERSION:arg:assert:collectgarbage:coroutine:debug:dofile:error:getmetatable:io:ipairs:load:loadfile:math:misc:next:os:package:pairs:pcall:print:rawequal:rawget:rawset:require:select:setmetatable:string:table:tonumber:tostring:type:xpcall", "rawlen:bit:bit32:jit:gcinfo:setfenv:getfenv:loadstring:unpack:module:newproxy")
+-- end
 
 do --- pre-5.2 base +lua<5.2
   assert(gcinfo)
@@ -64,9 +66,11 @@ do --- 5.2 math +lua>=5.2
   assert(not math.log10)
 end
 
-do --- string
-  check(string, "byte:char:dump:find:format:gmatch:gsub:len:lower:match:rep:reverse:sub:upper", "gfind")
-end
+-- Test is disabled for the Tarantool's binary,
+-- see the comment above.
+-- do --- string
+--   check(string, "byte:char:dump:find:format:gmatch:gsub:len:lower:match:rep:reverse:sub:upper", "gfind")
+-- end
 
 do --- pre-5.2 string +lua<5.2 -compat5.2
   assert(not string.gfind)
@@ -76,9 +80,11 @@ do --- 5.2 string +lua>=5.2
   assert(not string.gfind)
 end
 
-do --- pre-5.2 table +lua<5.2
-  check(table, "concat:foreach:foreachi:getn:insert:maxn:move:remove:sort", "pack:unpack:setn:new")
-end
+-- Test is disabled for the Tarantool's binary,
+-- see the comment above.
+-- do --- pre-5.2 table +lua<5.2
+--   check(table, "concat:foreach:foreachi:getn:insert:maxn:move:remove:sort", "pack:unpack:setn:new")
+-- end
 
 do --- 5.2 table +lua>=5.2
   check(table, "concat:insert:pack:remove:sort:unpack")
@@ -102,19 +108,25 @@ do --- io file
   check(debug.getmetatable(io.stdin), "__gc:__index:__tostring:close:flush:lines:read:seek:setvbuf:write")
 end
 
-do --- os
-  check(os, "clock:date:difftime:execute:exit:getenv:remove:rename:setlocale:time:tmpname")
-end
+-- Test is disabled for the Tarantool's binary,
+-- see the comment above.
+-- do --- os
+--   check(os, "clock:date:difftime:execute:exit:getenv:remove:rename:setlocale:time:tmpname")
+-- end
 
-do --- debug
-  check(debug, "debug:gethook:getinfo:getlocal:getmetatable:getregistry:getupvalue:sethook:setlocal:setmetatable:setupvalue:traceback", "getfenv:setfenv:upvalueid:upvaluejoin:getuservalue:setuservalue")
-end
+-- Test is disabled for the Tarantool's binary,
+-- see the comment above.
+-- do --- debug
+--   check(debug, "debug:gethook:getinfo:getlocal:getmetatable:getregistry:getupvalue:sethook:setlocal:setmetatable:setupvalue:traceback", "getfenv:setfenv:upvalueid:upvaluejoin:getuservalue:setuservalue")
+-- end
 
 -- TODO: Check versional differences in debug library
 
-do --- package
-  check(package, "config:cpath:loaded:loadlib:path:preload", "searchpath:loaders:searchers:seeall")
-end
+-- Test is disabled for the Tarantool's binary,
+-- see the comment above.
+-- do --- package
+--   check(package, "config:cpath:loaded:loadlib:path:preload", "searchpath:loaders:searchers:seeall")
+-- end
 
 do --- pre-5.2 package +lua<5.2
   assert(package.loaders)
@@ -128,19 +140,23 @@ do --- 5.2 package +lua>=5.2
   assert(not package.seeall)
 end
 
-do --- package.loaders
-  check(package.loaders or package.searchers, "1:2:3:4")
-end
-
-do --- package.loaded
-  local loaded = {}
-  for k, v in pairs(package.loaded) do
-    if type(k) ~= "string" or (k:sub(1, 7) ~= "common." and k:sub(1, 4) ~= "jit.") then
-      loaded[k] = v
-    end
-  end
-  check(loaded, "_G:coroutine:debug:io:math:misc:misc.memprof:os:package:string:table", "bit:bit32:common:ffi:jit:table.new")
-end
+-- Test is disabled for the Tarantool's binary,
+-- see the comment above.
+-- do --- package.loaders
+--   check(package.loaders or package.searchers, "1:2:3:4")
+-- end
+
+-- Test is disabled for the Tarantool's binary,
+-- see the comment above.
+-- do --- package.loaded
+--   local loaded = {}
+--   for k, v in pairs(package.loaded) do
+--     if type(k) ~= "string" or (k:sub(1, 7) ~= "common." and k:sub(1, 4) ~= "jit.") then
+--       loaded[k] = v
+--     end
+--   end
+--   check(loaded, "_G:coroutine:debug:io:math:misc:misc.memprof:os:package:string:table", "bit:bit32:common:ffi:jit:table.new")
+-- end
 
 do --- bit +bit
   check(bit, "arshift:band:bnot:bor:bswap:bxor:lshift:rol:ror:rshift:tobit:tohex")
-- 
2.28.0


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

* [Tarantool-patches] [WIP luajit 10/15] test: add lua-Harness test suite
  2021-03-04 10:23 [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites Sergey Kaplun via Tarantool-patches
                   ` (8 preceding siblings ...)
  2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 09/15] test: adjust LuaJIT test suite for Tarantool Sergey Kaplun via Tarantool-patches
@ 2021-03-04 10:23 ` Sergey Kaplun via Tarantool-patches
  2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 11/15] test: adjust lua-Harness test suite for Tarantool Sergey Kaplun via Tarantool-patches
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-04 10:23 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

This patch adds lua-Harness test suite:
https://fperrad.frama.io/lua-Harness/

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

Part of tarantool/tarantool#5844
Part of tarantool/tarantool#4473
---
Mergen Imeev <imeevma@gmail.com>: Author
Sergey Kaplun <skaplun@tarantool.org>: glanced commit message, made
commit consistence with the tarantool branch.

 .luacheckrc                                   |   1 +
 test/CMakeLists.txt                           |   2 +
 test/lua-Harness-tests/000-sanity.t           |  54 ++
 test/lua-Harness-tests/001-if.t               |  88 ++
 test/lua-Harness-tests/002-table.t            |  67 ++
 test/lua-Harness-tests/011-while.t            |  89 ++
 test/lua-Harness-tests/012-repeat.t           |  85 ++
 test/lua-Harness-tests/014-fornum.t           | 151 +++
 test/lua-Harness-tests/015-forlist.t          | 111 +++
 test/lua-Harness-tests/090-tap.t              |  37 +
 test/lua-Harness-tests/091-profile.t          |  45 +
 test/lua-Harness-tests/101-boolean.t          | 127 +++
 test/lua-Harness-tests/102-function.t         | 206 +++++
 test/lua-Harness-tests/103-nil.t              | 127 +++
 test/lua-Harness-tests/104-number.t           | 246 +++++
 test/lua-Harness-tests/105-string.t           | 277 ++++++
 test/lua-Harness-tests/106-table.t            | 135 +++
 test/lua-Harness-tests/107-thread.t           | 135 +++
 test/lua-Harness-tests/108-userdata.t         | 132 +++
 test/lua-Harness-tests/200-examples.t         | 104 +++
 test/lua-Harness-tests/201-assign.t           | 150 +++
 test/lua-Harness-tests/202-expr.t             | 157 ++++
 test/lua-Harness-tests/203-lexico.t           | 143 +++
 test/lua-Harness-tests/204-grammar.t          | 233 +++++
 test/lua-Harness-tests/211-scope.t            |  86 ++
 test/lua-Harness-tests/212-function.t         | 288 ++++++
 test/lua-Harness-tests/213-closure.t          |  98 ++
 test/lua-Harness-tests/214-coroutine.t        | 244 +++++
 test/lua-Harness-tests/221-table.t            | 120 +++
 test/lua-Harness-tests/222-constructor.t      | 119 +++
 test/lua-Harness-tests/223-iterator.t         | 203 +++++
 test/lua-Harness-tests/231-metatable.t        | 602 ++++++++++++
 test/lua-Harness-tests/232-object.t           | 314 +++++++
 test/lua-Harness-tests/241-standalone.t       | 269 ++++++
 test/lua-Harness-tests/242-luac.t             | 341 +++++++
 test/lua-Harness-tests/301-basic.t            | 856 ++++++++++++++++++
 test/lua-Harness-tests/303-package.t          | 290 ++++++
 test/lua-Harness-tests/304-string.t           | 633 +++++++++++++
 test/lua-Harness-tests/305-utf8.t             |  55 ++
 test/lua-Harness-tests/306-table.t            | 372 ++++++++
 test/lua-Harness-tests/307-math.t             | 375 ++++++++
 test/lua-Harness-tests/308-io.t               | 397 ++++++++
 test/lua-Harness-tests/309-os.t               | 271 ++++++
 test/lua-Harness-tests/310-debug.t            | 322 +++++++
 test/lua-Harness-tests/311-bit32.t            | 127 +++
 test/lua-Harness-tests/314-regex.t            | 222 +++++
 test/lua-Harness-tests/320-stdin.t            | 133 +++
 test/lua-Harness-tests/401-bitop.t            | 106 +++
 test/lua-Harness-tests/402-ffi.t              | 142 +++
 test/lua-Harness-tests/403-jit.t              | 163 ++++
 test/lua-Harness-tests/404-ext.t              | 171 ++++
 test/lua-Harness-tests/411-luajit.t           | 211 +++++
 test/lua-Harness-tests/CMakeLists.txt         |  49 +
 test/lua-Harness-tests/lexico52/lexico.t      |  45 +
 test/lua-Harness-tests/lexico53/boolean.t     |  43 +
 test/lua-Harness-tests/lexico53/function.t    |  66 ++
 test/lua-Harness-tests/lexico53/lexico.t      |  30 +
 test/lua-Harness-tests/lexico53/nil.t         |  43 +
 test/lua-Harness-tests/lexico53/number.t      | 181 ++++
 test/lua-Harness-tests/lexico53/string.t      | 169 ++++
 test/lua-Harness-tests/lexico53/table.t       |  43 +
 test/lua-Harness-tests/lexico53/thread.t      |  45 +
 test/lua-Harness-tests/lexico53/userdata.t    |  45 +
 test/lua-Harness-tests/lexico53/utf8.t        | 179 ++++
 test/lua-Harness-tests/lexico54/lexico.t      |  19 +
 test/lua-Harness-tests/lexico54/metatable.t   |  38 +
 test/lua-Harness-tests/lexico54/utf8.t        |  54 ++
 test/lua-Harness-tests/lexicojit/basic.t      |  27 +
 test/lua-Harness-tests/lexicojit/ext.t        |  52 ++
 test/lua-Harness-tests/lexicojit/lexico.t     |  32 +
 test/lua-Harness-tests/profile.lua            |  53 ++
 test/lua-Harness-tests/profile_lua51.lua      |  46 +
 .../profile_lua51_strict.lua                  |  46 +
 test/lua-Harness-tests/profile_lua52.lua      |  46 +
 .../profile_lua52_strict.lua                  |  46 +
 test/lua-Harness-tests/profile_lua53.lua      |  52 ++
 .../profile_lua53_noconv.lua                  |  55 ++
 .../profile_lua53_strict.lua                  |  52 ++
 test/lua-Harness-tests/profile_lua54.lua      |  52 ++
 .../profile_lua54_noconv.lua                  |  55 ++
 .../profile_lua54_strict.lua                  |  53 ++
 test/lua-Harness-tests/profile_luajit20.lua   |  53 ++
 .../profile_luajit20_compat52.lua             |  53 ++
 test/lua-Harness-tests/profile_luajit21.lua   |  53 ++
 .../profile_luajit21_compat52.lua             |  53 ++
 test/lua-Harness-tests/profile_openresty.lua  |  53 ++
 test/lua-Harness-tests/profile_ravi.lua       |  58 ++
 test/lua-Harness-tests/profile_tiny_fork.lua  |  60 ++
 test/lua-Harness-tests/rx_captures            |  13 +
 test/lua-Harness-tests/rx_charclass           |  38 +
 test/lua-Harness-tests/rx_metachars           | 117 +++
 test/lua-Harness-tests/tap.lua                | 204 +++++
 92 files changed, 12903 insertions(+)
 create mode 100755 test/lua-Harness-tests/000-sanity.t
 create mode 100755 test/lua-Harness-tests/001-if.t
 create mode 100755 test/lua-Harness-tests/002-table.t
 create mode 100755 test/lua-Harness-tests/011-while.t
 create mode 100755 test/lua-Harness-tests/012-repeat.t
 create mode 100755 test/lua-Harness-tests/014-fornum.t
 create mode 100755 test/lua-Harness-tests/015-forlist.t
 create mode 100755 test/lua-Harness-tests/090-tap.t
 create mode 100755 test/lua-Harness-tests/091-profile.t
 create mode 100755 test/lua-Harness-tests/101-boolean.t
 create mode 100755 test/lua-Harness-tests/102-function.t
 create mode 100755 test/lua-Harness-tests/103-nil.t
 create mode 100755 test/lua-Harness-tests/104-number.t
 create mode 100755 test/lua-Harness-tests/105-string.t
 create mode 100755 test/lua-Harness-tests/106-table.t
 create mode 100755 test/lua-Harness-tests/107-thread.t
 create mode 100755 test/lua-Harness-tests/108-userdata.t
 create mode 100755 test/lua-Harness-tests/200-examples.t
 create mode 100755 test/lua-Harness-tests/201-assign.t
 create mode 100755 test/lua-Harness-tests/202-expr.t
 create mode 100755 test/lua-Harness-tests/203-lexico.t
 create mode 100755 test/lua-Harness-tests/204-grammar.t
 create mode 100755 test/lua-Harness-tests/211-scope.t
 create mode 100755 test/lua-Harness-tests/212-function.t
 create mode 100755 test/lua-Harness-tests/213-closure.t
 create mode 100755 test/lua-Harness-tests/214-coroutine.t
 create mode 100755 test/lua-Harness-tests/221-table.t
 create mode 100755 test/lua-Harness-tests/222-constructor.t
 create mode 100755 test/lua-Harness-tests/223-iterator.t
 create mode 100755 test/lua-Harness-tests/231-metatable.t
 create mode 100755 test/lua-Harness-tests/232-object.t
 create mode 100755 test/lua-Harness-tests/241-standalone.t
 create mode 100755 test/lua-Harness-tests/242-luac.t
 create mode 100755 test/lua-Harness-tests/301-basic.t
 create mode 100755 test/lua-Harness-tests/303-package.t
 create mode 100755 test/lua-Harness-tests/304-string.t
 create mode 100755 test/lua-Harness-tests/305-utf8.t
 create mode 100755 test/lua-Harness-tests/306-table.t
 create mode 100755 test/lua-Harness-tests/307-math.t
 create mode 100755 test/lua-Harness-tests/308-io.t
 create mode 100755 test/lua-Harness-tests/309-os.t
 create mode 100755 test/lua-Harness-tests/310-debug.t
 create mode 100755 test/lua-Harness-tests/311-bit32.t
 create mode 100755 test/lua-Harness-tests/314-regex.t
 create mode 100755 test/lua-Harness-tests/320-stdin.t
 create mode 100755 test/lua-Harness-tests/401-bitop.t
 create mode 100755 test/lua-Harness-tests/402-ffi.t
 create mode 100755 test/lua-Harness-tests/403-jit.t
 create mode 100755 test/lua-Harness-tests/404-ext.t
 create mode 100755 test/lua-Harness-tests/411-luajit.t
 create mode 100644 test/lua-Harness-tests/CMakeLists.txt
 create mode 100644 test/lua-Harness-tests/lexico52/lexico.t
 create mode 100644 test/lua-Harness-tests/lexico53/boolean.t
 create mode 100644 test/lua-Harness-tests/lexico53/function.t
 create mode 100644 test/lua-Harness-tests/lexico53/lexico.t
 create mode 100644 test/lua-Harness-tests/lexico53/nil.t
 create mode 100644 test/lua-Harness-tests/lexico53/number.t
 create mode 100644 test/lua-Harness-tests/lexico53/string.t
 create mode 100644 test/lua-Harness-tests/lexico53/table.t
 create mode 100644 test/lua-Harness-tests/lexico53/thread.t
 create mode 100644 test/lua-Harness-tests/lexico53/userdata.t
 create mode 100644 test/lua-Harness-tests/lexico53/utf8.t
 create mode 100644 test/lua-Harness-tests/lexico54/lexico.t
 create mode 100644 test/lua-Harness-tests/lexico54/metatable.t
 create mode 100644 test/lua-Harness-tests/lexico54/utf8.t
 create mode 100644 test/lua-Harness-tests/lexicojit/basic.t
 create mode 100644 test/lua-Harness-tests/lexicojit/ext.t
 create mode 100644 test/lua-Harness-tests/lexicojit/lexico.t
 create mode 100644 test/lua-Harness-tests/profile.lua
 create mode 100644 test/lua-Harness-tests/profile_lua51.lua
 create mode 100644 test/lua-Harness-tests/profile_lua51_strict.lua
 create mode 100644 test/lua-Harness-tests/profile_lua52.lua
 create mode 100644 test/lua-Harness-tests/profile_lua52_strict.lua
 create mode 100644 test/lua-Harness-tests/profile_lua53.lua
 create mode 100644 test/lua-Harness-tests/profile_lua53_noconv.lua
 create mode 100644 test/lua-Harness-tests/profile_lua53_strict.lua
 create mode 100644 test/lua-Harness-tests/profile_lua54.lua
 create mode 100644 test/lua-Harness-tests/profile_lua54_noconv.lua
 create mode 100644 test/lua-Harness-tests/profile_lua54_strict.lua
 create mode 100644 test/lua-Harness-tests/profile_luajit20.lua
 create mode 100644 test/lua-Harness-tests/profile_luajit20_compat52.lua
 create mode 100644 test/lua-Harness-tests/profile_luajit21.lua
 create mode 100644 test/lua-Harness-tests/profile_luajit21_compat52.lua
 create mode 100644 test/lua-Harness-tests/profile_openresty.lua
 create mode 100644 test/lua-Harness-tests/profile_ravi.lua
 create mode 100644 test/lua-Harness-tests/profile_tiny_fork.lua
 create mode 100644 test/lua-Harness-tests/rx_captures
 create mode 100644 test/lua-Harness-tests/rx_charclass
 create mode 100644 test/lua-Harness-tests/rx_metachars
 create mode 100644 test/lua-Harness-tests/tap.lua

diff --git a/.luacheckrc b/.luacheckrc
index cbd2912..359ca11 100644
--- a/.luacheckrc
+++ b/.luacheckrc
@@ -8,6 +8,7 @@ read_globals = { 'misc' }
 exclude_files = {
   'dynasm/',
   'src/',
+  'test/lua-Harness-tests/',
   'test/LuaJIT-tests/',
   'test/PUC-Lua-5.1-tests/',
 }
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 1f9a379..5a2b18d 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -32,11 +32,13 @@ else()
   )
 endif()
 
+add_subdirectory(lua-Harness-tests)
 add_subdirectory(LuaJIT-tests)
 add_subdirectory(PUC-Lua-5.1-tests)
 add_subdirectory(tarantool-tests)
 
 add_custom_target(${PROJECT_NAME}-test DEPENDS
+  lua-Harness-tests
   LuaJIT-tests
   PUC-Lua-5.1-tests
   tarantool-tests
diff --git a/test/lua-Harness-tests/000-sanity.t b/test/lua-Harness-tests/000-sanity.t
new file mode 100755
index 0000000..e039153
--- /dev/null
+++ b/test/lua-Harness-tests/000-sanity.t
@@ -0,0 +1,54 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2018, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua test suite
+
+=head2 Synopsis
+
+    % prove 000-sanity.t
+
+=head2 Description
+
+=cut
+
+]]
+
+function f (n)
+    return n + 1
+end
+
+function g (m, p)
+    return m + p
+end
+
+print('1..9')
+print("ok 1 -")
+print('ok', 2, "- list")
+print("ok " .. tostring(3) .. " - concatenation")
+i = 4
+print("ok " .. tostring(i) .. " - var")
+i = i + 1
+print("ok " .. tostring(i) .. " - var incr")
+print("ok " .. tostring(i+1) .. " - expr")
+j = f(i + 1)
+print("ok " .. tostring(j) .. " - call f")
+k = g(i, 3)
+print("ok " .. tostring(k) .. " - call g")
+local print = print
+print("ok 9 - local")
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/001-if.t b/test/lua-Harness-tests/001-if.t
new file mode 100755
index 0000000..b84e331
--- /dev/null
+++ b/test/lua-Harness-tests/001-if.t
@@ -0,0 +1,88 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2020, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua if statement
+
+=head2 Synopsis
+
+    % prove 001-if.t
+
+=head2 Description
+
+See section "Control Structures" in "Reference Manual"
+L<https://www.lua.org/manual/5.1/manual.html#2.4.4>,
+L<https://www.lua.org/manual/5.2/manual.html#3.3.4>,
+L<https://www.lua.org/manual/5.3/manual.html#3.3.4>,
+L<https://www.lua.org/manual/5.4/manual.html#3.3.4>
+
+=cut
+
+]]
+
+print("1..6")
+
+if true then
+    print("ok 1")
+else
+    print("not ok 1")
+end
+
+if not true then
+    print("not ok 2")
+else
+    print("ok 2")
+end
+
+a = 12
+b = 34
+if a < b then
+    print("ok 3")
+else
+    print("not ok 3")
+end
+
+a = 0
+b = 4
+if a < b then
+    print("ok 4")
+elseif a == b then
+    print("not ok 4")
+else
+    print("not ok 4")
+end
+
+a = 5
+b = 5
+if a < b then
+    print("not ok 5")
+elseif a == b then
+    print("ok 5")
+else
+    print("not ok 5")
+end
+
+a = 10
+b = 6
+if a < b then
+    print("not ok 6")
+elseif a == b then
+    print("not ok 6")
+else
+    print("ok 6")
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/002-table.t b/test/lua-Harness-tests/002-table.t
new file mode 100755
index 0000000..b84afd6
--- /dev/null
+++ b/test/lua-Harness-tests/002-table.t
@@ -0,0 +1,67 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2018, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua table
+
+=head2 Synopsis
+
+    % prove 002-table.t
+
+=head2 Description
+
+See section "Tables" in "Programming in Lua".
+
+=cut
+
+]]
+
+print("1..8")
+
+a = {"ok 1", "ok 2", "ok 3"}
+print(a[1])
+i = 2
+print(a[i])
+print(a[i+1])
+if #a == 3 then
+    print("ok 4 - len")
+else
+    print("not ok 4")
+end
+if a[7] == nil then
+    print("ok 5")
+else
+    print("not ok 5")
+end
+
+t = {a=10, b=100}
+if t['a'] == 10 then
+    print("ok 6")
+else
+    print("not ok 6")
+end
+if t.b == 100 then
+    print("ok 7")
+else
+    print("not ok 7")
+end
+if t.z == nil then
+    print("ok 8")
+else
+    print("not ok 8")
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/011-while.t b/test/lua-Harness-tests/011-while.t
new file mode 100755
index 0000000..8ba4c6b
--- /dev/null
+++ b/test/lua-Harness-tests/011-while.t
@@ -0,0 +1,89 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2020, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua while statement
+
+=head2 Synopsis
+
+    % prove 011-while.t
+
+=head2 Description
+
+See section "Control Structures" in "Reference Manual"
+L<https://www.lua.org/manual/5.1/manual.html#2.4.4>,
+L<https://www.lua.org/manual/5.2/manual.html#3.3.4>,
+L<https://www.lua.org/manual/5.3/manual.html#3.3.4>,
+L<https://www.lua.org/manual/5.4/manual.html#3.3.4>
+
+=cut
+
+]]
+
+print("1..11")
+
+do
+    local a = {}
+    local i = 1
+    while a[i] do
+        i = i + 1
+    end
+    if i == 1 then
+        print("ok 1 - while empty")
+    else
+        print("not ok 1 - " .. i)
+    end
+end
+
+do
+    local a = {"ok 2 - while ", "ok 3", "ok 4"}
+    local i = 1
+    while a[i] do
+        print(a[i])
+        i = i + 1
+    end
+end
+
+do
+    local a = {"ok 5 - with break", "ok 6", "stop", "more"}
+    local i = 1
+    while a[i] do
+        if a[i] == 'stop' then break end
+        print(a[i])
+        i = i + 1
+    end
+    if i == 3 then
+        print("ok 7 - break")
+    else
+        print("not ok 7 - " .. i)
+    end
+end
+
+do
+    local x = 3
+    local i = 1
+    while i<=x do
+        print("ok " .. tostring(7+i))
+        i = i + 1
+    end
+    if i == 4 then
+        print("ok 11")
+    else
+        print("not ok 11 - " .. tostring(i))
+    end
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/012-repeat.t b/test/lua-Harness-tests/012-repeat.t
new file mode 100755
index 0000000..527db63
--- /dev/null
+++ b/test/lua-Harness-tests/012-repeat.t
@@ -0,0 +1,85 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2020, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua repeat statement
+
+=head2 Synopsis
+
+    % prove 012-repeat.t
+
+=head2 Description
+
+See section "Control Structures" in "Reference Manual"
+L<https://www.lua.org/manual/5.1/manual.html#2.4.4>,
+L<https://www.lua.org/manual/5.2/manual.html#3.3.4>,
+L<https://www.lua.org/manual/5.3/manual.html#3.3.4>,
+L<https://www.lua.org/manual/5.4/manual.html#3.3.4>
+
+=cut
+
+]]
+
+print("1..8")
+
+do
+    local a = {"ok 1 - repeat", "ok 2", "ok 3"}
+    local i = 0
+    repeat
+        i = i + 1
+        if a[i] then
+            print(a[i])
+        end
+    until not a[i]
+    if i == 4 then
+        print("ok 4")
+    else
+        print("not ok 4 - " .. i)
+    end
+end
+
+do
+    local a = {"ok 5 - with break", "ok 6", 'stop', 'more'}
+    local i = 0
+    repeat
+        i = i + 1
+        if a[i] == 'stop' then break end
+        print(a[i])
+    until not a[i]
+    if a[i] == 'stop' then
+        print("ok 7 - break")
+    else
+        print("not ok 7 - " .. a[i])
+    end
+end
+
+do
+    local function f () return true end
+
+    local i = 1
+    repeat
+        local v = f()
+        if i == 1 then
+            print("ok 8 - scope")
+        else
+            print("not ok")
+            break
+        end
+        i = i + 1
+    until v
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/014-fornum.t b/test/lua-Harness-tests/014-fornum.t
new file mode 100755
index 0000000..3f6d1b1
--- /dev/null
+++ b/test/lua-Harness-tests/014-fornum.t
@@ -0,0 +1,151 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2020, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua for statement
+
+=head2 Synopsis
+
+    % prove 014-fornum.t
+
+=head2 Description
+
+See section "For Statement" in "Reference Manual"
+L<https://www.lua.org/manual/5.1/manual.html#2.4.5>,
+L<https://www.lua.org/manual/5.2/manual.html#3.3.5>,
+L<https://www.lua.org/manual/5.3/manual.html#3.3.5>,
+L<https://www.lua.org/manual/5.4/manual.html#3.3.5>
+
+=cut
+
+--]]
+
+print("1..36")
+
+for i = 1.0, 3.0, 0.5 do
+    print("ok " .. tostring(2*i-1) .. " - for 1.0, 3.0, 0.5")
+end
+
+for i = 1.0, 3.0, 0.5 do
+    local function f ()
+        print("ok " .. tostring(2*i+4) .. " - for 1.0, 3.0, 0.5 lex")
+    end
+    f()
+end
+
+local function f (i)
+    print("ok " .. tostring(2*i+9) .. " - for 1.0, 3.0, 0.5 !lex")
+end
+for i = 1.0, 3.0, 0.5 do
+    f(i)
+end
+
+for i = 3, 5 do
+    print("ok " .. tostring(13+i) .. " - for 3, 5")
+    i = i + 1
+end
+
+for i = 5, 1, -1 do
+    print("ok " .. tostring(24-i) .. " - for 5, 1, -1")
+end
+
+for i = 5, 5 do
+    print("ok " .. tostring(19+i) .. " - for 5, 5")
+end
+
+for i = 5, 5, -1 do
+    print("ok " .. tostring(20+i) .. " - for 5, 5, -1")
+end
+
+do
+    local v = false
+    for i = 5, 3 do
+        v = true
+    end
+    if v then
+        print("not ok 26 - for 5, 3")
+    else
+        print("ok 26 - for 5, 3")
+    end
+end
+
+do
+    local v = false
+    for i = 5, 7, -1 do
+        v = true
+    end
+    if v then
+        print("not ok 27 - for 5, 7, -1")
+    else
+        print("ok 27 - for 5, 7, -1")
+    end
+end
+
+do
+    local v = false
+    if _VERSION <= 'Lua 5.3' then
+        for i = 5, 7, 0 do
+            v = true
+            break -- avoid infinite loop with LuaJIT
+        end
+    end
+    if jit then
+        print("not ok 28 - for 5, 7, 0 # TODO # LuaJIT intentional.")
+    elseif v then
+        print("not ok 28 - for 5, 7, 0")
+    else
+        print("ok 28 - for 5, 7, 0")
+    end
+end
+
+do
+    local v = nil
+    for i = 1, 10, 2 do
+        if i > 4 then break end
+        print("ok " .. tostring((i+57)/2) .. " - for break")
+        v = i
+    end
+    if v == 3 then
+        print("ok 31 - break")
+    else
+        print("not ok 31 - " .. v)
+    end
+end
+
+do
+    local function first() return 1 end
+    local function limit() return 8 end
+    local function step()  return 2 end
+    for i = first(), limit(), step() do
+        print("ok " .. tostring((i+63)/2) .. " - with functions")
+    end
+end
+
+do
+    local a = {}
+    for i = 1, 10 do
+        a[i] = function () return i end
+    end
+    local v = a[5]()
+    if v == 5 then
+        print("ok 36 - for & upval")
+    else
+        print("not ok 36 - for & upval")
+        print("#", v)
+    end
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/015-forlist.t b/test/lua-Harness-tests/015-forlist.t
new file mode 100755
index 0000000..cd9db61
--- /dev/null
+++ b/test/lua-Harness-tests/015-forlist.t
@@ -0,0 +1,111 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2020, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua for statement
+
+=head2 Synopsis
+
+    % prove 015-forlist.t
+
+=head2 Description
+
+See section "For Statement" in "Reference Manual"
+L<https://www.lua.org/manual/5.1/manual.html#2.4.5>,
+L<https://www.lua.org/manual/5.2/manual.html#3.3.5>,
+L<https://www.lua.org/manual/5.3/manual.html#3.3.5>,
+L<https://www.lua.org/manual/5.4/manual.html#3.3.5>
+
+=cut
+
+--]]
+
+print("1..18")
+
+do
+    local a = {"ok 1 - for ipairs", "ok 2 - for ipairs", "ok 3 - for ipairs"}
+
+    for _, v in ipairs(a) do
+        print(v)
+    end
+
+    for i, v in ipairs(a) do
+        print("ok " .. tostring(3+i) .. " - for ipairs")
+    end
+
+    for k in pairs(a) do
+        print("ok " .. tostring(6+k) .. " - for pairs")
+    end
+end
+
+do
+    local r = false
+    local t = {a=10, b=100}
+
+    for i, v in ipairs(t) do
+        print(i, v)
+        r = true
+    end
+    if r then
+        print("not ok 10 - for ipairs (hash)")
+    else
+        print("ok 10 - for ipairs (hash)")
+    end
+
+    local i = 1
+    for k in pairs(t) do
+        if k == 'a' or k == 'b' then
+            print("ok " .. tostring(10+i) .. " - for pairs (hash)")
+        else
+            print("not ok " .. tostring(10+i) .. " - " .. k)
+        end
+        i = i + 1
+    end
+end
+
+do
+    local a = {"ok 13 - for break", "ok 14 - for break", "stop", "more"}
+    local i
+    for _, v in ipairs(a) do
+        if v == "stop" then break end
+        print(v)
+        i = _
+    end
+    if i == 2 then
+        print("ok 15 - break")
+    else
+        print("not ok 15 - " .. i)
+    end
+end
+
+do
+    local a = {"ok 16 - for & upval", "ok 17 - for & upval", "ok 18 - for & upval"}
+    local b = {}
+    for i, v in ipairs(a) do
+        b[i] = function () return v end
+    end
+    for i, v in ipairs(a) do
+        local r = b[i]()
+        if r == a[i] then
+            print(r)
+        else
+            print("not " .. a[i])
+            print("#", r)
+        end
+    end
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/090-tap.t b/test/lua-Harness-tests/090-tap.t
new file mode 100755
index 0000000..92f04d8
--- /dev/null
+++ b/test/lua-Harness-tests/090-tap.t
@@ -0,0 +1,37 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2018, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua test suite
+
+=head2 Synopsis
+
+    % prove 090-tap.t
+
+=head2 Description
+
+=cut
+
+]]
+
+require'tap'
+
+plan(3)
+ok( true, 'ok' )
+is( 42, 42, '42 == 42' )
+pass( 'pass' )
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/091-profile.t b/test/lua-Harness-tests/091-profile.t
new file mode 100755
index 0000000..db47438
--- /dev/null
+++ b/test/lua-Harness-tests/091-profile.t
@@ -0,0 +1,45 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2018, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua test suite
+
+=head2 Synopsis
+
+    % prove 091-profile.t
+
+=head2 Description
+
+=cut
+
+]]
+
+require'tap'
+
+plan'no_plan'
+
+type_ok(_VERSION, 'string', "variable _VERSION")
+like(_VERSION, '^Lua 5%.%d$')
+
+if jit then
+    type_ok(jit.version_num, 'number', "variable jit.version_num")
+end
+
+local profile = require_ok'profile'
+
+done_testing()
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/101-boolean.t b/test/lua-Harness-tests/101-boolean.t
new file mode 100755
index 0000000..0033eff
--- /dev/null
+++ b/test/lua-Harness-tests/101-boolean.t
@@ -0,0 +1,127 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2018, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1  Lua boolean & coercion
+
+=head2 Synopsis
+
+    % prove 101-boolean.t
+
+=head2 Description
+
+=cut
+
+]]
+
+require'tap'
+local has_op53 = _VERSION >= 'Lua 5.3'
+
+plan'no_plan'
+
+error_like(function () return -true end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a %w+ value",
+           "-true")
+
+error_like(function () return #true end,
+           "^[^:]+:%d+: attempt to get length of a boolean value",
+           "#true")
+
+is(not false, true, "not false")
+
+error_like(function () return true + 10 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a boolean value",
+           "true + 10")
+
+error_like(function () return true - 2 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a boolean value",
+           "true - 2")
+
+error_like(function () return true * 3.14 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a boolean value",
+           "true * 3.14")
+
+error_like(function () return true / -7 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a boolean value",
+           "true / -7")
+
+error_like(function () return true % 4 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a boolean value",
+           "true % 4")
+
+error_like(function () return true ^ 3 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a boolean value",
+           "true ^ 3")
+
+error_like(function () return true .. 'end' end,
+           "^[^:]+:%d+: attempt to concatenate a boolean value",
+           "true .. 'end'")
+
+is(true == true, true, "true == true")
+
+is(true ~= false, true, "true ~= false")
+
+is(true == 1, false, "true == 1")
+
+is(true ~= 1, true, "true ~= 1")
+
+error_like(function () return true < false end,
+           "^[^:]+:%d+: attempt to compare two boolean values",
+           "true < false")
+
+error_like(function () return true <= false end,
+           "^[^:]+:%d+: attempt to compare two boolean values",
+           "true <= false")
+
+error_like(function () return true > false end,
+           "^[^:]+:%d+: attempt to compare two boolean values",
+           "true > false")
+
+error_like(function () return true >= false end,
+           "^[^:]+:%d+: attempt to compare two boolean values",
+           "true >= false")
+
+error_like(function () return true < 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "true < 0")
+
+error_like(function () return true <= 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "true <= 0")
+
+error_like(function () return true > 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "true > 0")
+
+error_like(function () return true >= 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "true >= 0")
+
+error_like(function () local a = true; local b = a[1]; end,
+           "^[^:]+:%d+: attempt to index",
+           "index")
+
+error_like(function () local a = true; a[1] = 1; end,
+           "^[^:]+:%d+: attempt to index",
+           "index")
+
+if has_op53 then
+    dofile'lexico53/boolean.t'
+end
+
+done_testing()
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/102-function.t b/test/lua-Harness-tests/102-function.t
new file mode 100755
index 0000000..48ed814
--- /dev/null
+++ b/test/lua-Harness-tests/102-function.t
@@ -0,0 +1,206 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2018, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua function & coercion
+
+=head2 Synopsis
+
+    % prove 102-function.t
+
+=head2 Description
+
+=cut
+
+--]]
+
+require'tap'
+local has_op53 = _VERSION >= 'Lua 5.3'
+
+plan'no_plan'
+
+local f = function () return 1 end
+
+error_like(function () return -f end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "-f")
+
+error_like(function () f = print; return -f end,
+           "^[^:]+:%d+: attempt to perform arithmetic on")
+
+error_like(function () return #f end,
+           "^[^:]+:%d+: attempt to get length of",
+           "#f")
+
+error_like(function () f = print; return #f end,
+           "^[^:]+:%d+: attempt to get length of")
+
+is(not f, false, "not f")
+
+is(not print, false)
+
+error_like(function () return f + 10 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "f + 10")
+
+error_like(function () f = print; return f + 10 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on")
+
+error_like(function () return f - 2 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "f - 2")
+
+error_like(function () f = print; return f - 2 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on")
+
+error_like(function () return f * 3.14 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "f * 3.14")
+
+error_like(function () f = print; return f * 3.14 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on")
+
+error_like(function () return f / -7 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "f / -7")
+
+error_like(function () f = print; return f / -7 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on")
+
+error_like(function () return f % 4 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "f % 4")
+
+error_like(function () f = print; return f % 4 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on")
+
+error_like(function () return f ^ 3 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "f ^ 3")
+
+error_like(function () f = print; return f ^ 3 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on")
+
+error_like(function () return f .. 'end' end,
+           "^[^:]+:%d+: attempt to concatenate",
+           "f .. 'end'")
+
+error_like(function () f = print; return f .. 'end' end,
+           "^[^:]+:%d+: attempt to concatenate")
+
+local g = f
+is(f == g, true, "f == f")
+
+g = print
+is(g == print, true)
+
+g = function () return 2 end
+is(f ~= g, true, "f ~= g")
+local h = type
+is(f ~= h, true)
+
+is(print ~= g, true)
+is(print ~= h, true)
+
+is(f == 1, false, "f == 1")
+
+is(print == 1, false)
+
+is(f ~= 1, true, "f ~= 1")
+
+is(print ~= 1, true)
+
+error_like(function () return f < g end,
+           "^[^:]+:%d+: attempt to compare two function values",
+           "f < g")
+
+error_like(function () f = print; g = type; return f < g end,
+           "^[^:]+:%d+: attempt to compare two function values")
+
+error_like(function () return f <= g end,
+           "^[^:]+:%d+: attempt to compare two function values",
+           "f <= g")
+
+error_like(function () f = print; g = type; return f <= g end,
+           "^[^:]+:%d+: attempt to compare two function values")
+
+error_like(function () return f > g end,
+           "^[^:]+:%d+: attempt to compare two function values",
+           "f > g")
+
+error_like(function () f = print; g = type; return f > g end,
+           "^[^:]+:%d+: attempt to compare two function values")
+
+error_like(function () return f >= g end,
+           "^[^:]+:%d+: attempt to compare two function values",
+           "f >= g")
+
+error_like(function () f = print; g = type; return f >= g end,
+           "^[^:]+:%d+: attempt to compare two function values")
+
+error_like(function () return f < 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "f < 0")
+
+error_like(function () f = print; return f < 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+")
+
+error_like(function () return f <= 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "f <= 0")
+
+error_like(function () f = print; return f <= 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+")
+
+error_like(function () return f > 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "f > 0")
+
+error_like(function () f = print; return f > 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+")
+
+error_like(function () return f > 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "f >= 0")
+
+error_like(function () f = print; return f >= 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+")
+
+error_like(function () local a = f; local b = a[1]; end,
+           "^[^:]+:%d+: attempt to index",
+           "index")
+
+error_like(function () local a = print; local b = a[1]; end,
+           "^[^:]+:%d+: attempt to index")
+
+error_like(function () local a = f; a[1] = 1; end,
+           "^[^:]+:%d+: attempt to index",
+           "index")
+
+error_like(function () local a = print; a[1] = 1; end,
+           "^[^:]+:%d+: attempt to index")
+
+local t = {}
+t[print] = true
+ok(t[print])
+
+if has_op53 then
+    dofile'lexico53/function.t'
+end
+
+done_testing()
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/103-nil.t b/test/lua-Harness-tests/103-nil.t
new file mode 100755
index 0000000..561b101
--- /dev/null
+++ b/test/lua-Harness-tests/103-nil.t
@@ -0,0 +1,127 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2018, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua nil & coercion
+
+=head2 Synopsis
+
+    % prove 103-nil.t
+
+=head2 Description
+
+=cut
+
+--]]
+
+require'tap'
+local has_op53 = _VERSION >= 'Lua 5.3'
+
+plan'no_plan'
+
+error_like(function () return -nil end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a nil value",
+           "-nil")
+
+error_like(function () return #nil end,
+           "^[^:]+:%d+: attempt to get length of a nil value",
+           "#nil")
+
+is(not nil, true, "not nil")
+
+error_like(function () return nil + 10 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a nil value",
+           "nil + 10")
+
+error_like(function () return nil - 2 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a nil value",
+           "nil - 2")
+
+error_like(function () return nil * 3.14 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a nil value",
+           "nil * 3.14")
+
+error_like(function () return nil / -7 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a nil value",
+           "nil / -7")
+
+error_like(function () return nil % 4 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a nil value",
+           "nil % 4")
+
+error_like(function () return nil ^ 3 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a nil value",
+           "nil ^ 3")
+
+error_like(function () return nil .. 'end' end,
+           "^[^:]+:%d+: attempt to concatenate a nil value",
+           "nil .. 'end'")
+
+is(nil == nil, true, "nil == nil")
+
+is(nil ~= nil, false, "nil ~= nil")
+
+is(nil == 1, false, "nil == 1")
+
+is(nil ~= 1, true, "nil ~= 1")
+
+error_like(function () return nil < nil end,
+           "^[^:]+:%d+: attempt to compare two nil values",
+           "nil < nil")
+
+error_like(function () return nil <= nil end,
+           "^[^:]+:%d+: attempt to compare two nil values",
+           "nil <= nil")
+
+error_like(function () return nil > nil end,
+           "^[^:]+:%d+: attempt to compare two nil values",
+           "nil > nil")
+
+error_like(function () return nil > nil end,
+           "^[^:]+:%d+: attempt to compare two nil values",
+           "nil >= nil")
+
+error_like(function () return nil < 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "nil < 0")
+
+error_like(function () return nil <= 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "nil <= 0")
+
+error_like(function () return nil > 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "nil > 0")
+
+error_like(function () return nil >= 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "nil >= 0")
+
+error_like(function () local a = nil; local b = a[1]; end,
+           "^[^:]+:%d+: attempt to index",
+           "index")
+
+error_like(function () local a = nil; a[1] = 1; end,
+           "^[^:]+:%d+: attempt to index",
+           "index")
+
+if has_op53 then
+    dofile'lexico53/nil.t'
+end
+
+done_testing()
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/104-number.t b/test/lua-Harness-tests/104-number.t
new file mode 100755
index 0000000..0d4d3fd
--- /dev/null
+++ b/test/lua-Harness-tests/104-number.t
@@ -0,0 +1,246 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2019, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua number & coercion
+
+=head2 Synopsis
+
+    % prove 104-number.t
+
+=head2 Description
+
+=cut
+
+--]]
+
+require'tap'
+local profile = require'profile'
+local has_op53 = _VERSION >= 'Lua 5.3'
+
+plan'no_plan'
+
+is(-1, -(1), "-1")
+
+is(not 1, false, "not 1")
+
+is(10 + 2, 12, "10 + 2")
+
+is(2 - 10.5, -8.5, "2 - 10.5")
+
+is(2 * 3, 6, "2 * 3")
+
+is(3.14 * 1, 3.14, "3.14 * 1")
+
+is(-7 / 0.5, -14, "-7 / 0.5")
+
+type_ok(1.0 / 0.0, 'number', "1.0 / 0.0")
+
+is(-25 % 3, 2, "-25 % 3")
+
+if _VERSION >= 'Lua 5.3' then
+    error_like(function () return 1 % 0 end,
+               "^[^:]+:%d+: attempt to perform 'n%%0'",
+               "1 % 0")
+else
+    type_ok(1 % 0, 'number', "1 % 0")
+end
+
+error_like(function () return 10 + true end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a boolean value",
+           "10 + true")
+
+error_like(function () return 2 - nil end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a nil value",
+           "2 - nil")
+
+error_like(function () return 2 * {} end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a table value",
+           "2 * {}")
+
+error_like(function () return 3.14 * false end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a boolean value",
+           "3.14 * false")
+
+error_like(function () return -7 / {} end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a table value",
+           "-7 / {}")
+
+error_like(function () return 3 ^ true end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a boolean value",
+           "3 ^ true")
+
+error_like(function () return -25 % false end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a boolean value",
+           "-25 % false")
+
+error_like(function () return 10 + 'text' end,
+           "^[^:]+:%d+: attempt to",
+           "10 + 'text'")
+
+error_like(function () return 2 - 'text' end,
+           "^[^:]+:%d+: attempt to",
+           "2 - 'text'")
+
+error_like(function () return 2 * 'text' end,
+           "^[^:]+:%d+: attempt to",
+           "2 * 'text'")
+
+error_like(function () return 3.14 * 'text' end,
+           "^[^:]+:%d+: attempt to",
+           "3.14 * 'text'")
+
+error_like(function () return -7 / 'text' end,
+           "^[^:]+:%d+: attempt to",
+           "-7 / 'text'")
+
+error_like(function () return 25 % 'text' end,
+           "^[^:]+:%d+: attempt to",
+           "25 % 'text'")
+
+error_like(function () return 3 ^ 'text' end,
+           "^[^:]+:%d+: attempt to",
+           "3 ^ 'text'")
+
+if profile.nocvts2n then
+    error_like(function () return 10 + '2' end,
+               "^[^:]+:%d+: attempt to",
+               "10 + '2'")
+
+    error_like(function () return 2 - '10.5' end,
+               "^[^:]+:%d+: attempt to",
+               "2 - '10.5'")
+
+    error_like(function () return 2 * '3' end,
+               "^[^:]+:%d+: attempt to",
+               "2 * '3'")
+
+    error_like(function () return 3.14 * '1' end,
+               "^[^:]+:%d+: attempt to",
+               "3.14 * '1'")
+
+    error_like(function () return -7 / '0.5' end,
+               "^[^:]+:%d+: attempt to",
+               "-7 / '0.5'")
+
+    error_like(function () return -25 % '3' end,
+               "^[^:]+:%d+: attempt to",
+               "-25 % '3'")
+
+    error_like(function () return 3 ^ '3' end,
+               "^[^:]+:%d+: attempt to",
+               "3 ^ '3'")
+else
+    is(10 + '2', 12, "10 + '2'")
+
+    is(2 - '10.5', -8.5, "2 - '10.5'")
+
+    is(2 * '3', 6, "2 * '3'")
+
+    is(3.14 * '1', 3.14, "3.14 * '1'")
+
+    is(-7 / '0.5', -14, "-7 / '0.5'")
+
+    is(-25 % '3', 2, "-25 % '3'")
+
+    is(3 ^ '3', 27, "3 ^ '3'")
+end
+
+if profile.nocvtn2s then
+    error_like(function () return 1 .. 'end' end,
+               "^[^:]+:%d+: attempt to concatenate a number value",
+               "1 .. 'end'")
+
+    error_like(function () return 1 .. 2 end,
+               "^[^:]+:%d+: attempt to concatenate a number value",
+               "1 .. 2")
+else
+    is(1 .. 'end', '1end', "1 .. 'end'")
+
+    is(1 .. 2, '12', "1 .. 2")
+end
+
+error_like(function () return 1 .. true end,
+           "^[^:]+:%d+: attempt to concatenate a %w+ value",
+           "1 .. true")
+
+is(1.0 == 1, true, "1.0 == 1")
+
+is(1 ~= 2, true, "1 ~= 2")
+
+is(1 == true, false, "1 == true")
+
+is(1 ~= nil, true, "1 ~= nil")
+
+is(1 == '1', false, "1 == '1'")
+
+is(1 ~= '1', true, "1 ~= '1'")
+
+is(1 < 0, false, "1 < 0")
+
+is(1 <= 0, false, "1 <= 0")
+
+is(1 > 0, true, "1 > 0")
+
+is(1 >= 0, true, "1 >= 0")
+
+error_like(function () return 1 < false end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "1 < false")
+
+error_like(function () return 1 <= nil end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "1 <= nil")
+
+error_like(function () return 1 > true end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "1 > true")
+
+error_like(function () return 1 >= {} end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "1 >= {}")
+
+error_like(function () return 1 < '0' end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "1 < '0'")
+
+error_like(function () return 1 <= '0' end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "1 <= '0'")
+
+error_like(function () return 1 > '0' end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "1 > '0'")
+
+error_like(function () return 1 >= '0' end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "1 >= '0'")
+
+error_like(function () local a= 3.14; local b = a[1]; end,
+           "^[^:]+:%d+: attempt to index",
+           "index")
+
+error_like(function () local a = 3.14; a[1] = 1; end,
+           "^[^:]+:%d+: attempt to index",
+           "index")
+
+if has_op53 then
+    dofile'lexico53/number.t'
+end
+
+done_testing()
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/105-string.t b/test/lua-Harness-tests/105-string.t
new file mode 100755
index 0000000..cd8c88b
--- /dev/null
+++ b/test/lua-Harness-tests/105-string.t
@@ -0,0 +1,277 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2019, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua string & coercion
+
+=head2 Synopsis
+
+    % prove 105-string.t
+
+=head2 Description
+
+=cut
+
+--]]
+
+require'tap'
+local profile = require'profile'
+local has_op53 = _VERSION >= 'Lua 5.3'
+
+plan'no_plan'
+
+if profile.nocvts2n then
+    error_like(function () return - '1' end,
+               "^[^:]+:%d+: attempt to",
+               "-'1'")
+else
+    is(- '1', -1, "-'1'")
+end
+
+error_like(function () return - 'text' end,
+           "^[^:]+:%d+: attempt to",
+           "-'text'")
+
+is(# 'text', 4, "#'text'")
+
+is(not 'text', false, "not 'text'")
+
+if profile.nocvts2n then
+    error_like(function () return '10' + 2 end,
+               "^[^:]+:%d+: attempt to",
+               "'10' + 2")
+
+    error_like(function () return '2' - 10.5 end,
+               "^[^:]+:%d+: attempt to",
+               "'2' - 10.5")
+
+    error_like(function () return '2' * 3 end,
+               "^[^:]+:%d+: attempt to",
+               "'2' * 3")
+
+    error_like(function () return '3.14' * 1 end,
+               "^[^:]+:%d+: attempt to",
+               "'3.14' * 1")
+
+    error_like(function () return '-7' / 0.5 end,
+               "^[^:]+:%d+: attempt to",
+               "'-7' / 0.5")
+
+    error_like(function () return '-25' % 3 end,
+               "^[^:]+:%d+: attempt to",
+               "'-25' % 3")
+
+    error_like(function () return '3' ^ 3 end,
+               "^[^:]+:%d+: attempt to",
+               "'3' ^ 3")
+else
+    is('10' + 2, 12, "'10' + 2")
+
+    is('2' - 10.5, -8.5, "'2' - 10.5")
+
+    is('2' * 3, 6, "'2' * 3")
+
+    is('3.14' * 1, 3.14, "'3.14' * 1")
+
+    is('-7' / 0.5, -14, "'-7' / 0.5")
+
+    is('-25' % 3, 2, "'-25' % 3")
+
+    is('3' ^ 3, 27, "'3' ^ 3")
+end
+
+error_like(function () return '10' + true end,
+           "^[^:]+:%d+: attempt to",
+           "'10' + true")
+
+error_like(function () return '2' - nil end,
+           "^[^:]+:%d+: attempt to",
+           "'2' - nil")
+
+error_like(function () return '2' * {} end,
+           "^[^:]+:%d+: attempt to",
+           "'2' * {}")
+
+error_like(function () return '3.14' * false end,
+           "^[^:]+:%d+: attempt to",
+           "'3.14' * false")
+
+error_like(function () return '-7' / {} end,
+           "^[^:]+:%d+: attempt to",
+           "'-7' / {}")
+
+error_like(function () return '-25' % false end,
+           "^[^:]+:%d+: attempt to",
+           "'-25' % false")
+
+error_like(function () return '3' ^ true end,
+           "^[^:]+:%d+: attempt to",
+           "'3' ^ true")
+
+error_like(function () return '10' + 'text' end,
+           "^[^:]+:%d+: attempt to",
+           "'10' + 'text'")
+
+error_like(function () return '2' - 'text' end,
+           "^[^:]+:%d+: attempt to",
+           "'2' - 'text'")
+
+error_like(function () return '3.14' * 'text' end,
+           "^[^:]+:%d+: attempt to",
+           "'3.14' * 'text'")
+
+error_like(function () return '-7' / 'text' end,
+           "^[^:]+:%d+: attempt to",
+           "'-7' / 'text'")
+
+error_like(function () return '-25' % 'text' end,
+           "^[^:]+:%d+: attempt to",
+           "'-25' % 'text'")
+
+error_like(function () return '3' ^ 'text' end,
+           "^[^:]+:%d+: attempt to",
+           "'3' ^ 'text'")
+
+if profile.nocvts2n then
+    error_like(function () return '10' + '2' end,
+               "^[^:]+:%d+: attempt to",
+               "'10' + '2'")
+
+    error_like(function () return '2' - '10.5' end,
+               "^[^:]+:%d+: attempt to",
+               "'2' - '10.5'")
+
+    error_like(function () return '2' * '3' end,
+               "^[^:]+:%d+: attempt to",
+               "'2' * '3'")
+
+    error_like(function () return '3.14' * '1' end,
+               "^[^:]+:%d+: attempt to",
+               "'3.14' * '1'")
+
+    error_like(function () return '-7' / '0.5' end,
+               "^[^:]+:%d+: attempt to",
+               "'-7' / '0.5'")
+
+    error_like(function () return '-25' % '3' end,
+               "^[^:]+:%d+: attempt to",
+               "'-25' % '3'")
+
+    error_like(function () return '3' ^ '3' end,
+               "^[^:]+:%d+: attempt to",
+               "'3' ^ '3'")
+else
+    is('10' + '2', 12, "'10' + '2'")
+
+    is('2' - '10.5', -8.5, "'2' - '10.5'")
+
+    is('2' * '3', 6, "'2' * '3'")
+
+    is('3.14' * '1', 3.14, "'3.14' * '1'")
+
+    is('-7' / '0.5', -14, "'-7' / '0.5'")
+
+    is('-25' % '3', 2, "'-25' % '3'")
+
+    is('3' ^ '3', 27, "'3' ^ '3'")
+end
+
+is('1' .. 'end', '1end', "'1' .. 'end'")
+
+if profile.nocvtn2s then
+    error_like(function () return '1' .. 2 end,
+               "^[^:]+:%d+: attempt to concatenate a number value",
+               "'1' .. 2")
+else
+    is('1' .. 2, '12', "'1' .. 2")
+end
+
+error_like(function () return '1' .. true end,
+           "^[^:]+:%d+: attempt to concatenate a boolean value",
+           "'1' .. true")
+
+is('foo\0bar' <= 'foo\0baz', true, "'foo\\0bar' <= 'foo\\0baz'")
+
+is('foo\0bar' ~= 'foo', true, "'foo\\0bar' ~= 'foo'")
+
+is('foo\0bar' >= 'foo', true, "'foo\\0bar' >= 'foo'")
+
+is('1.0' == '1', false, "'1.0' == '1'")
+
+is('1' ~= '2', true, "'1' ~= '2'")
+
+is('1' == true, false, "'1' == true")
+
+is('1' ~= nil, true, "'1' ~= nil")
+
+is('1' == 1, false, "'1' == 1")
+
+is('1' ~= 1, true, "'1' ~= 1")
+
+is('1' < '0', false, "'1' < '0'")
+
+is('1' <= '0', false, "'1' <= '0'")
+
+is('1' > '0', true, "'1' > '0'")
+
+is('1' >= '0', true, "'1' >= '0'")
+
+error_like(function () return '1' < false end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "'1' < false")
+
+error_like(function () return '1' <= nil end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "'1' <= nil")
+
+error_like(function () return '1' > true end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "'1' > true")
+
+error_like(function () return '1' >= {} end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "'1' >= {}")
+
+error_like(function () return '1' < 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "'1' < 0")
+
+error_like(function () return '1' <= 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "'1' <= 0")
+
+error_like(function () return '1' > 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "'1' > 0")
+
+error_like(function () return '1' > 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "'1' >== 0")
+
+local a = 'text'
+is(a[1], nil, "index")
+
+error_like(function () a = 'text'; a[1] = 1; end,
+           "^[^:]+:%d+: attempt to index",
+           "index")
+
+if has_op53 then
+    dofile'lexico53/string.t'
+end
+
+done_testing()
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/106-table.t b/test/lua-Harness-tests/106-table.t
new file mode 100755
index 0000000..0c0ba49
--- /dev/null
+++ b/test/lua-Harness-tests/106-table.t
@@ -0,0 +1,135 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2018, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua table & coercion
+
+=head2 Synopsis
+
+    % prove 106-table.t
+
+=head2 Description
+
+=cut
+
+--]]
+
+require'tap'
+local has_op53 = _VERSION >= 'Lua 5.3'
+
+plan'no_plan'
+
+error_like(function () return -{} end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "-{}")
+
+is(# {}, 0, "#{}")
+is(# {4,5,6}, 3)
+
+is(not {}, false, "not {}")
+
+error_like(function () return {} + 10 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "{} + 10")
+
+error_like(function () return {} - 2 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "{} - 2")
+
+error_like(function () return {} * 3.14 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "{} * 3.14")
+
+error_like(function () return {} / 7 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "{} / 7")
+
+error_like(function () return {} % 4 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "{} % 4")
+
+error_like(function () return {} ^ 3 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "{} ^ 3")
+
+error_like(function () return {} .. 'end' end,
+           "^[^:]+:%d+: attempt to concatenate",
+           "{} .. 'end'")
+
+is({} == {}, false, "{} == {}")
+
+local t1 = {}
+local t2 = {}
+is(t1 == t1, true, "t1 == t1")
+is(t1 == t2, false, "t1 == t2")
+is(t1 ~= t2, true, "t1 ~= t2")
+
+is({} == 1, false, "{} == 1")
+
+is({} ~= 1, true, "{} ~= 1")
+
+error_like(function () return t1 < t2 end,
+           "^[^:]+:%d+: attempt to compare two table values",
+           "t1 < t2")
+
+error_like(function () return t1 <= t2 end,
+           "^[^:]+:%d+: attempt to compare two table values",
+           "t1 <= t2")
+
+error_like(function () return t1 > t2 end,
+           "^[^:]+:%d+: attempt to compare two table values",
+           "t1 > t2")
+
+error_like(function () return t1 >= t2 end,
+           "^[^:]+:%d+: attempt to compare two table values",
+           "t1 >= t2")
+
+error_like(function () return {} < 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "{} < 0")
+
+error_like(function () return {} <= 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "{} <= 0")
+
+error_like(function () return {} > 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "{} > 0")
+
+error_like(function () return {} >= 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "{} >= 0")
+
+local t = {}
+is( t[1], nil, "index" )
+t[1] = 42
+is( t[1], 42, "index" )
+
+error_like(function () t = {}; t[nil] = 42 end,
+           "^[^:]+:%d+: table index is nil",
+           "table index is nil")
+
+error_like(function () t = {}; t[0/0] = 42 end,
+           "^[^:]+:%d+: table index is NaN",
+           "table index is NaN")
+
+if has_op53 then
+    dofile'lexico53/table.t'
+end
+
+done_testing()
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/107-thread.t b/test/lua-Harness-tests/107-thread.t
new file mode 100755
index 0000000..3d4af18
--- /dev/null
+++ b/test/lua-Harness-tests/107-thread.t
@@ -0,0 +1,135 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2018, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua thread & coercion
+
+=head2 Synopsis
+
+    % prove 107-thread.t
+
+=head2 Description
+
+=cut
+
+--]]
+
+require'tap'
+local has_op53 = _VERSION >= 'Lua 5.3'
+
+plan'no_plan'
+
+local co = coroutine.create(function () return 1 end)
+
+error_like(function () return -co end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "-co")
+
+error_like(function () return #co end,
+           "^[^:]+:%d+: attempt to get length of",
+           "#co")
+
+is(not co, false, "not co")
+
+error_like(function () return co + 10 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "co + 10")
+
+error_like(function () return co - 2 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "co - 2")
+
+error_like(function () return co * 3.14 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "co * 3.14")
+
+error_like(function () return co / 7 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "co / 7")
+
+error_like(function () return co % 4 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "co % 4")
+
+error_like(function () return co ^ 3 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "co ^ 3")
+
+error_like(function () return co .. 'end' end,
+           "^[^:]+:%d+: attempt to concatenate",
+           "co .. 'end'")
+
+is(co == co, true, "co == co")
+
+local co1 = coroutine.create(function () return 1 end)
+local co2 = coroutine.create(function () return 2 end)
+is(co1 ~= co2, true, "co1 ~= co2")
+
+is(co == 1, false, "co == 1")
+
+is(co ~= 1, true, "co ~= 1")
+
+error_like(function () return co1 < co2 end,
+           "^[^:]+:%d+: attempt to compare two thread values",
+           "co1 < co2")
+
+error_like(function () return co1 <= co2 end,
+           "^[^:]+:%d+: attempt to compare two thread values",
+           "co1 <= co2")
+
+error_like(function () return co1 > co2 end,
+           "^[^:]+:%d+: attempt to compare two thread values",
+           "co1 > co2")
+
+error_like(function () return co1 >= co2 end,
+           "^[^:]+:%d+: attempt to compare two thread values",
+           "co1 >= co2")
+
+error_like(function () return co < 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "co < 0")
+
+error_like(function () return co <= 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "co <= 0")
+
+error_like(function () return co > 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "co > 0")
+
+error_like(function () return co > 0 end,
+           "^[^:]+:%d+: attempt to compare %w+ with %w+",
+           "co >= 0")
+
+error_like(function () local a = co[1] end,
+           "^[^:]+:%d+: attempt to index",
+           "index")
+
+error_like(function () co[1] = 1 end,
+           "^[^:]+:%d+: attempt to index",
+           "index")
+
+local t = {}
+t[co] = true
+ok(t[co])
+
+if has_op53 then
+    dofile'lexico53/thread.t'
+end
+
+done_testing()
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/108-userdata.t b/test/lua-Harness-tests/108-userdata.t
new file mode 100755
index 0000000..b1e3641
--- /dev/null
+++ b/test/lua-Harness-tests/108-userdata.t
@@ -0,0 +1,132 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2018, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua userdata & coercion
+
+=head2 Synopsis
+
+    % prove 108-userdata.t
+
+=head2 Description
+
+=cut
+
+--]]
+
+require'tap'
+local has_op53 = _VERSION >= 'Lua 5.3'
+
+plan'no_plan'
+
+local u = io.stdin
+
+error_like(function () return -u end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "-u")
+
+error_like(function () return #u end,
+           "^[^:]+:%d+: attempt to get length of",
+           "#u")
+
+is(not u, false, "not u")
+
+error_like(function () return u + 10 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "u + 10")
+
+error_like(function () return u - 2 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "u - 2")
+
+error_like(function () return u * 3.14 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "u * 3.14")
+
+error_like(function () return u / 7 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "u / 7")
+
+error_like(function () return u % 4 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "u % 4")
+
+error_like(function () return u ^ 3 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "u ^ 3")
+
+error_like(function () return u .. 'end' end,
+           "^[^:]+:%d+: attempt to concatenate",
+           "u .. 'end'")
+
+is(u == u, true, "u == u")
+
+local v = io.stdout
+is(u ~= v, true, "u ~= v")
+
+is(u == 1, false, "u == 1")
+
+is(u ~= 1, true, "u ~= 1")
+
+error_like(function () return u < v end,
+           "^[^:]+:%d+: attempt to compare two",
+           "u < v")
+
+error_like(function () return u <= v end,
+           "^[^:]+:%d+: attempt to compare two",
+           "u <= v")
+
+error_like(function () return u > v end,
+           "^[^:]+:%d+: attempt to compare two",
+           "u > v")
+
+error_like(function () return u >= v end,
+           "^[^:]+:%d+: attempt to compare two",
+           "u >= v")
+
+error_like(function () return u < 0 end,
+           "^[^:]+:%d+: attempt to compare",
+           "u < 0")
+
+error_like(function () return u <= 0 end,
+           "^[^:]+:%d+: attempt to compare",
+           "u <= 0")
+
+error_like(function () return u > 0 end,
+           "^[^:]+:%d+: attempt to compare",
+           "u > 0")
+
+error_like(function () return u > 0 end,
+           "^[^:]+:%d+: attempt to compare",
+           "u >= 0")
+
+is(u[1], nil, "index")
+
+error_like(function () u[1] = 1 end,
+           "^[^:]+:%d+: attempt to index",
+           "index")
+
+local t = {}
+t[u] = true
+ok(t[u])
+
+if has_op53 then
+    dofile'lexico53/userdata.t'
+end
+
+done_testing()
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/200-examples.t b/test/lua-Harness-tests/200-examples.t
new file mode 100755
index 0000000..362aae3
--- /dev/null
+++ b/test/lua-Harness-tests/200-examples.t
@@ -0,0 +1,104 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2018, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 some Lua code examples
+
+=head2 Synopsis
+
+    % prove 200-examples.t
+
+=head2 Description
+
+First tests in order to check infrastructure.
+
+=cut
+
+--]]
+
+require'tap'
+
+plan(5)
+
+function factorial (n)
+    if n == 0 then
+        return 1
+    else
+        return n * factorial(n-1)
+    end
+end
+is(factorial(7), 5040, "factorial (recursive)")
+
+local function local_factorial (n)
+    if n == 0 then
+        return 1
+    else
+        return n * local_factorial(n-1)
+    end
+end
+is(local_factorial(7), 5040, "factorial (recursive)")
+
+local function loop_factorial (n)
+    local a = 1
+    for i = 1, n, 1 do
+        a = a*i
+    end
+    return a
+end
+is(loop_factorial(7), 5040, "factorial (loop)")
+
+local function iter_factorial (n)
+    local function iter (product, counter)
+        if counter > n then
+            return product
+        else
+            return iter(counter*product, counter+1)
+        end
+    end
+    return iter(1, 1)
+end
+is(iter_factorial(7), 5040, "factorial (iter)")
+
+--[[
+
+  Knuth's "man or boy" test.
+  See http://en.wikipedia.org/wiki/Man_or_boy_test
+
+]]
+
+local function A (k, x1, x2, x3, x4, x5)
+    local function B ()
+        k = k - 1
+        return A(k, B, x1, x2, x3, x4)
+    end
+    if k <= 0 then
+        return x4() + x5()
+    else
+        return B()
+    end
+end
+
+is(A(10,
+        function () return 1 end,
+        function () return -1 end,
+        function () return -1 end,
+        function () return 1 end,
+        function () return 0 end),
+   -67,
+   "man or boy"
+)
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/201-assign.t b/test/lua-Harness-tests/201-assign.t
new file mode 100755
index 0000000..7d023d8
--- /dev/null
+++ b/test/lua-Harness-tests/201-assign.t
@@ -0,0 +1,150 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2020, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua assignment
+
+=head2 Synopsis
+
+    % prove 201-assign.t
+
+=head2 Description
+
+See section "Assignment" in "Reference Manual"
+L<https://www.lua.org/manual/5.1/manual.html#2.4.3>,
+L<https://www.lua.org/manual/5.2/manual.html#3.3.3>,
+L<https://www.lua.org/manual/5.3/manual.html#3.3.3>,
+L<https://www.lua.org/manual/5.4/manual.html#3.3.3>
+
+=cut
+
+--]]
+
+require'tap'
+local has_env = _VERSION >= 'Lua 5.2'
+
+plan'no_plan'
+
+do
+    is(b, nil, "global variable")
+    b = 10
+    is(b, 10)
+    if has_env then
+        is(_ENV.b, 10, "_ENV")
+        is(_G, _ENV, "_G")
+        error_like([[ _ENV = nil; b = 20 ]],
+                   "attempt to ")
+    else
+        is(_ENV, nil, "no _ENV");
+    end
+    b = nil
+    is(b, nil)
+end
+
+do
+    local a = {}
+    local i = 3
+    i, a[i] = i+1, 20
+    -- this behavior is undefined
+    -- see http://lua-users.org/lists/lua-l/2006-06/msg00378.html
+    is(i, 4, "check eval")
+    is(a[3], 20)
+end
+
+do
+    local x = 1.
+    local y = 2.
+    x, y = y, x -- swap
+    is(x, 2, "check swap")
+    is(y, 1)
+end
+
+do
+    local a, b, c = 0, 1
+    is(a, 0, "check padding")
+    is(b, 1)
+    is(c, nil)
+    a, b = a+1, b+1, a+b
+    is(a, 1)
+    is(b, 2)
+    a, b, c = 0
+    is(a, 0)
+    is(b, nil)
+    is(c, nil)
+end
+
+do
+    local function f() return 1, 2 end
+    local a, b, c, d = f()
+    is(a, 1, "adjust with function")
+    is(b, 2)
+    is(c, nil)
+    is(d, nil)
+end
+
+do
+    local function f() print('# f') end
+    local a = 2
+    local b, c
+    a, b, c = f(), 3
+    is(a, nil, "padding with function")
+    is(b, 3)
+    is(c, nil)
+end
+
+do
+    local my_i = 1
+    is(my_i, 1, "local variable")
+    local my_i = 2
+    is(my_i, 2)
+end
+
+do
+    local i = 1
+    local j = i
+    is(i, 1, "local variable")
+    is(j, 1)
+    j = 2
+    is(i, 1)
+    is(j, 2)
+end
+
+do
+    local function f(x) return 2*x end
+    is(f(2), 4, "param & result of function")
+    local a = 2
+    a = f(a)
+    is(a, 4)
+    local b = 2
+    b = f(b)
+    is(b, 4)
+end
+
+do
+    local n1 = 1
+    local n2 = 2
+    local n3 = 3
+    local n4 = 4
+    n1,n2,n3,n4 = n4,n3,n2,n1
+    is(n1, 4, "assignment list swap values")
+    is(n2, 3)
+    is(n3, 2)
+    is(n4, 1)
+end
+
+done_testing()
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/202-expr.t b/test/lua-Harness-tests/202-expr.t
new file mode 100755
index 0000000..2576750
--- /dev/null
+++ b/test/lua-Harness-tests/202-expr.t
@@ -0,0 +1,157 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2020, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua expression
+
+=head2 Synopsis
+
+    % prove 202-expr.t
+
+=head2 Description
+
+See section "Expressions" in "Reference Manual"
+L<https://www.lua.org/manual/5.1/manual.html#2.5>,
+L<https://www.lua.org/manual/5.2/manual.html#3.4>,
+L<https://www.lua.org/manual/5.3/manual.html#3.4>,
+L<https://www.lua.org/manual/5.4/manual.html#3.4>
+
+=cut
+
+--]]
+
+require'tap'
+local profile = require'profile'
+local nocvtn2s = profile.nocvtn2s
+local nocvts2n = profile.nocvts2n
+
+plan'no_plan'
+
+local x = math.pi
+is(tostring(x - x%0.0001), tostring(3.1415), "modulo")
+
+local a = {}; a.x = 1; a.y = 0;
+local b = {}; b.x = 1; b.y = 0;
+local c = a
+is(a == c, true, "relational op (by reference)")
+is(a ~= b, true)
+
+is('0' == 0, false, "relational op")
+is(2 < 15, true)
+is('2' < '15', false)
+
+error_like(function () return 2 < '15' end,
+           "compare",
+           "relational op")
+
+error_like(function () return '2' < 15 end,
+           "compare",
+           "relational op")
+
+is(4 and 5, 5, "logical op")
+is(nil and 13, nil)
+is(false and 13, false)
+is(4 or 5, 4)
+is(false or 5, 5)
+is(false or 'text', 'text')
+
+is(10 or 20, 10, "logical op")
+is(10 or error(), 10)
+is(nil or 'a', 'a')
+is(nil and 10, nil)
+is(false and error(), false)
+is(false and nil, false)
+is(false or nil, nil)
+is(10 and 20, 20)
+
+is(not nil, true, "logical not")
+is(not false, true)
+is(not 0, false)
+is(not not nil, false)
+is(not 'text', false)
+a = {}
+is(not a, false)
+is(not (a == a), false)
+is(not (a ~= a), true)
+
+is("Hello " .. "World", "Hello World", "concatenation")
+if not nocvtn2s then
+    is(0 .. 1, '01')
+end
+a = "Hello"
+is(a .. " World", "Hello World")
+is(a, "Hello")
+
+if not nocvts2n then
+    is('10' + 1, 11, "coercion")
+    is('-5.3' * '2', -10.6)
+end
+is(tostring(10), '10')
+if not nocvtn2s then
+    is(10 .. 20, '1020')
+    is(10 .. '', '10')
+end
+
+error_like(function () return 'hello' + 1 end,
+           ((not nocvts2n and _VERSION >= 'Lua 5.4') or ravi) and "attempt to add" or "perform arithmetic",
+           "no coercion")
+
+error_like(function ()
+                local function first() return end
+                local function limit() return 2 end
+                local function step()  return 1 end
+                for i = first(), limit(), step() do
+                    print(i)
+                end
+           end,
+           "^[^:]+:%d+:.- 'for' initial value",
+           "for tonumber")
+
+error_like(function ()
+                local function first() return 1 end
+                local function limit() return end
+                local function step()  return 2 end
+                for i = first(), limit(), step() do
+                    print(i)
+                end
+           end,
+           "^[^:]+:%d+:.- 'for' limit",
+           "for tonumber")
+
+error_like(function ()
+                local function first() return 1 end
+                local function limit() return 2 end
+                local function step()  return end
+                for i = first(), limit(), step() do
+                    print(i)
+                end
+           end,
+           "^[^:]+:%d+:.- 'for' step",
+           "for tonumber")
+
+if _VERSION >= 'Lua 5.4' then
+    error_like(function ()
+                    for i = 1, 10, 0 do
+                        print(i)
+                    end
+               end,
+               "^[^:]+:%d+: 'for' step is zero",
+               "for step zero")
+end
+
+done_testing()
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/203-lexico.t b/test/lua-Harness-tests/203-lexico.t
new file mode 100755
index 0000000..c1abebf
--- /dev/null
+++ b/test/lua-Harness-tests/203-lexico.t
@@ -0,0 +1,143 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2010-2020, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua Lexicography
+
+=head2 Synopsis
+
+    % prove 203-lexico.t
+
+=head2 Description
+
+See "Lua 5.3 Reference Manual", section 3.1 "Lexical Conventions",
+L<http://www.lua.org/manual/5.3/manual.html#3.1>.
+
+See section "Lexical Conventions"
+L<https://www.lua.org/manual/5.1/manual.html#2.1>,
+L<https://www.lua.org/manual/5.2/manual.html#3.1>,
+L<https://www.lua.org/manual/5.3/manual.html#3.1>,
+L<https://www.lua.org/manual/5.4/manual.html#3.1>
+
+=cut
+
+--]]
+
+require'tap'
+local loadstring = loadstring or load
+local luajit21 = jit and (jit.version_num >= 20100 or jit.version:match'^RaptorJIT')
+
+plan'no_plan'
+
+is("\65", "A")
+is("\065", "A")
+
+is(string.byte("\a"), 7)
+is(string.byte("\b"), 8)
+is(string.byte("\f"), 12)
+is(string.byte("\n"), 10)
+is(string.byte("\r"), 13)
+is(string.byte("\t"), 9)
+is(string.byte("\v"), 11)
+is(string.byte("\\"), 92)
+
+is(string.len("A\0B"), 3)
+
+do
+    local f, msg = loadstring [[a = "A\300"]]
+    if _VERSION == 'Lua 5.1' then
+        like(msg, "^[^:]+:%d+: .- near")
+    else
+        like(msg, "^[^:]+:%d+: .- escape .- near")
+    end
+
+    f, msg = loadstring [[a = " unfinished string ]]
+    like(msg, "^[^:]+:%d+: unfinished string near")
+
+    f, msg = loadstring [[a = " unfinished string
+]]
+    like(msg, "^[^:]+:%d+: unfinished string near")
+
+    f, msg = loadstring [[a = " unfinished string \
+]]
+    like(msg, "^[^:]+:%d+: unfinished string near")
+
+    f, msg = loadstring [[a = " unfinished string \]]
+    like(msg, "^[^:]+:%d+: unfinished string near")
+
+    f, msg = loadstring "a = [[ unfinished long string "
+    like(msg, "^[^:]+:%d+: unfinished long string .-near")
+
+    f, msg = loadstring "a = [== invalid long string delimiter "
+    like(msg, "^[^:]+:%d+: invalid long string delimiter near")
+end
+
+do
+    local a = 'alo\n123"'
+    is('alo\n123"', a)
+    is("alo\n123\"", a)
+    is('\97lo\10\04923"', a)
+    is([[alo
+123"]], a)
+    is([==[
+alo
+123"]==], a)
+end
+
+is(3.0, 3)
+is(314.16e-2, 3.1416)
+is(0.31416E1, 3.1416)
+is(.3, 0.3)
+is(0xff, 255)
+is(0x56, 86)
+
+do
+    local f, msg = loadstring [[a = 12e34e56]]
+    like(msg, "^[^:]+:%d+: malformed number near")
+end
+
+--[===[
+--[[
+--[=[
+    nested long comments
+--]=]
+--]]
+--]===]
+
+do
+    local f, msg = loadstring "  --[[ unfinished long comment "
+    like(msg, "^[^:]+:%d+: unfinished long comment .-near")
+end
+
+if _VERSION >= 'Lua 5.2' or jit then
+    dofile'lexico52/lexico.t'
+end
+
+if _VERSION >= 'Lua 5.3' or luajit21 then
+    dofile'lexico53/lexico.t'
+end
+
+if _VERSION >= 'Lua 5.4' then
+    dofile'lexico54/lexico.t'
+end
+
+if jit and pcall(require, 'ffi') then
+    dofile'lexicojit/lexico.t'
+end
+
+done_testing()
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/204-grammar.t b/test/lua-Harness-tests/204-grammar.t
new file mode 100755
index 0000000..d9ae3a6
--- /dev/null
+++ b/test/lua-Harness-tests/204-grammar.t
@@ -0,0 +1,233 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2010-2020, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua Grammar
+
+=head2 Synopsis
+
+    % prove 204-grammar.t
+
+=head2 Description
+
+See section "The Complete Syntax of Lua" in "Reference Manual"
+L<https://www.lua.org/manual/5.1/manual.html#8>,
+L<https://www.lua.org/manual/5.2/manual.html#9>,
+L<https://www.lua.org/manual/5.3/manual.html#9>,
+L<https://www.lua.org/manual/5.4/manual.html#9>
+
+=cut
+
+--]]
+
+require'tap'
+local profile = require'profile'
+local has_goto = _VERSION >= 'Lua 5.2' or jit
+local has_attr = _VERSION >= 'Lua 5.4'
+local loadstring = loadstring or load
+
+plan'no_plan'
+
+do --[[ empty statement ]]
+    local f, msg = loadstring [[; a = 1]]
+    if _VERSION == 'Lua 5.1' and not profile.luajit_compat52 then
+        like(msg, "^[^:]+:%d+: unexpected symbol near ';'", "empty statement")
+    else
+        type_ok(f, 'function', "empty statement")
+    end
+
+    f = loadstring [[a = 1; a = 2]]
+    type_ok(f, 'function')
+
+    f, msg = loadstring [[a = 1;;; a = 2]]
+    if _VERSION == 'Lua 5.1' and not profile.luajit_compat52 then
+        like(msg, "^[^:]+:%d+: unexpected symbol near ';'")
+    else
+        type_ok(f, 'function')
+    end
+end
+
+do --[[ orphan break ]]
+    local f, msg = loadstring [[
+function f()
+    print "before"
+    do
+        print "inner"
+        break
+    end
+    print "after"
+end
+]]
+    if _VERSION == 'Lua 5.1' then
+        like(msg, "^[^:]+:%d+: no loop to break", "orphan break")
+    elseif _VERSION <= 'Lua 5.3' then
+        like(msg, "^[^:]+:%d+: <break> at line 5 not inside a loop", "orphan break")
+    else
+        like(msg, "^[^:]+:%d+: break outside loop at line 5", "orphan break")
+    end
+end
+
+do --[[ break anywhere ]]
+    local f, msg = loadstring [[
+function f()
+    print "before"
+    while true do
+        print "inner"
+        break
+        print "break"
+    end
+    print "after"
+end
+]]
+    if _VERSION == 'Lua 5.1' and not profile.luajit_compat52 then
+        like(msg, "^[^:]+:%d+: 'end' expected %(to close 'while' at line 3%) near 'print'", "break anywhere")
+    else
+        type_ok(f, 'function', "break anywhere")
+    end
+
+    f, msg = loadstring [[
+function f()
+    print "before"
+    while true do
+        print "inner"
+        if cond then
+            break
+            print "break"
+        end
+    end
+    print "after"
+end
+]]
+    if _VERSION == 'Lua 5.1' and not profile.luajit_compat52 then
+        like(msg, "^[^:]+:%d+: 'end' expected %(to close 'if' at line 5%) near 'print'", "break anywhere")
+    else
+        type_ok(f, 'function', "break anywhere")
+    end
+end
+
+--[[ goto ]]
+if has_goto then
+    local f, msg = loadstring [[
+::label::
+    goto unknown
+]]
+    if jit then
+        like(msg, ":%d+: undefined label 'unknown'", "unknown goto")
+    else
+        like(msg, ":%d+: no visible label 'unknown' for <goto> at line %d+", "unknown goto")
+    end
+
+    f, msg = loadstring [[
+::label::
+    goto label
+::label::
+]]
+    if jit then
+        like(msg, ":%d+: duplicate label 'label'", "duplicate label")
+    else
+        like(msg, ":%d+: label 'label' already defined on line %d+", "duplicate label")
+    end
+
+    f, msg = loadstring [[
+::e::
+    goto f
+    local x
+::f::
+    goto e
+]]
+    if jit then
+        like(msg, ":%d+: <goto f> jumps into the scope of local 'x'", "bad goto")
+    else
+        like(msg, ":%d+: <goto f> at line %d+ jumps into the scope of local 'x'", "bad goto")
+    end
+
+    f= loadstring [[
+do
+::s1:: ;
+    goto s2
+
+::s2::
+    goto s3
+
+::s3::
+end
+]]
+    type_ok(f, 'function', "goto")
+else
+    diag("no goto")
+end
+
+do --[[ syntax error ]]
+    local f, msg = loadstring [[a = { 1, 2, 3)]]
+    like(msg, ":%d+: '}' expected near '%)'", "constructor { }")
+
+    f, msg = loadstring [[a = (1 + 2}]]
+    like(msg, ":%d+: '%)' expected near '}'", "expr ( )")
+
+    f, msg = loadstring [[a = f(1, 2}]]
+    like(msg, ":%d+: '%)' expected near '}'", "expr ( )")
+
+    f, msg = loadstring [[function f () return 1]]
+    like(msg, ":%d+: 'end' expected near '?<eof>'?", "function end")
+
+    f, msg = loadstring [[do local a = f()]]
+    like(msg, ":%d+: 'end' expected near '?<eof>'?", "do end")
+
+    f, msg = loadstring [[for i = 1, 2 do print(i)]]
+    like(msg, ":%d+: 'end' expected near '?<eof>'?", "for end")
+
+    f, msg = loadstring [[if true then f()]]
+    like(msg, ":%d+: 'end' expected near '?<eof>'?", "if end")
+
+    f, msg = loadstring [[while true do f()]]
+    like(msg, ":%d+: 'end' expected near '?<eof>'?", "while end")
+
+    f, msg = loadstring [[repeat f()]]
+    like(msg, ":%d+: 'until' expected near '?<eof>'?", "repeat until")
+
+    f, msg = loadstring [[function f (a, 2) return a * 2 end]]
+    like(msg, ":%d+: <name> or '...' expected near '2'", "function parameter list")
+
+    f, msg = loadstring [[a = o:m[1, 2)]]
+    like(msg, ":%d+: function arguments expected near '%['", "function argument list")
+
+    f, msg = loadstring [[for i do print(i) end]]
+    like(msg, ":%d+: '=' or 'in' expected near 'do'", "for init")
+
+    f, msg = loadstring [[for i = 1, 2 print(i) end]]
+    like(msg, ":%d+: 'do' expected near 'print'", "for do")
+
+    f, msg = loadstring [[if true f() end]]
+    like(msg, ":%d+: 'then' expected near 'f'", "if then")
+
+    f, msg = loadstring [[while true f() end]]
+    like(msg, ":%d+: 'do' expected near 'f", "while do")
+end
+
+if has_attr then
+    local f, msg = load [[local foo < bar > = 'bar']]
+    like(msg, "^[^:]+:%d+: unknown attribute 'bar'")
+
+    f, msg = load [[local foo <const> = 'bar'; foo = 'baz']]
+    like(msg, "^[^:]+:%d+: attempt to assign to const variable 'foo'")
+
+    f, msg = load [[local foo <close> = 'bar'; foo = 'baz']]
+    like(msg, "^[^:]+:%d+: attempt to assign to const variable 'foo'")
+end
+
+done_testing()
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/211-scope.t b/test/lua-Harness-tests/211-scope.t
new file mode 100755
index 0000000..64eed52
--- /dev/null
+++ b/test/lua-Harness-tests/211-scope.t
@@ -0,0 +1,86 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2020, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua scope
+
+=head2 Synopsis
+
+    % prove 211-scope.t
+
+=head2 Description
+
+See section "Visibility Rules" in "Reference Manual"
+L<https://www.lua.org/manual/5.1/manual.html#2.6>,
+L<https://www.lua.org/manual/5.2/manual.html#3.5>,
+L<https://www.lua.org/manual/5.3/manual.html#3.5>,
+L<https://www.lua.org/manual/5.4/manual.html#3.5>
+
+See section "Local Variables and Blocks" in "Programming in Lua".
+
+=cut
+
+--]]
+
+require'tap'
+
+plan(10)
+
+--[[ scope ]]
+x = 10
+do
+    local x = x
+    is(x, 10, "scope")
+    x = x + 1
+    do
+        local x = x + 1
+        is(x, 12)
+    end
+    is(x, 11)
+end
+is(x, 10)
+
+--[[ scope ]]
+x = 10
+local i = 1
+
+while i<=x do
+    local x = i*2
+--    print(x)
+    i = i + 1
+end
+
+if i > 20 then
+    local x
+    x = 20
+    nok("scope")
+else
+    is(x, 10, "scope")
+end
+
+is(x, 10)
+
+--[[ scope ]]
+local a, b = 1, 10
+if a < b then
+    is(a, 1, "scope")
+    local a
+    is(a, nil)
+end
+is(a, 1)
+is(b, 10)
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/212-function.t b/test/lua-Harness-tests/212-function.t
new file mode 100755
index 0000000..2851053
--- /dev/null
+++ b/test/lua-Harness-tests/212-function.t
@@ -0,0 +1,288 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2020, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua functions
+
+=head2 Synopsis
+
+    % prove 212-function.t
+
+=head2 Description
+
+See section "Function Definitions" in "Reference Manual"
+L<https://www.lua.org/manual/5.1/manual.html#2.5.9>,
+L<https://www.lua.org/manual/5.2/manual.html#3.4.10>,
+L<https://www.lua.org/manual/5.3/manual.html#3.4.11>,
+L<https://www.lua.org/manual/5.4/manual.html#3.4.11>
+
+See section "Functions" in "Programming in Lua".
+
+=cut
+
+--]]
+
+require'tap'
+local loadstring = loadstring or load
+
+plan(68)
+
+do --[[ add ]]
+    local function add (a)
+        local sum = 0
+        for i,v in ipairs(a) do
+            sum = sum + v
+        end
+        return sum
+    end
+
+    local t = { 10, 20, 30, 40 }
+    is(add(t), 100, "add")
+end
+
+do --[[ f ]]
+    local function f(a, b) return a or b end
+
+    is(f(3), 3, "f")
+    is(f(3, 4), 3)
+    is(f(3, 4, 5), 3)
+end
+
+do --[[ incCount ]]
+    local count = 0
+
+    local function incCount (n)
+        n = n or 1
+        count = count + n
+    end
+
+    is(count, 0, "inCount")
+    incCount()
+    is(count, 1)
+    incCount(2)
+    is(count, 3)
+    incCount(1)
+    is(count, 4)
+end
+
+do --[[ maximum ]]
+    local function maximum (a)
+        local mi = 1                -- maximum index
+        local m = a[mi]             -- maximum value
+        for i,val in ipairs(a) do
+            if val > m then
+                mi = i
+                m = val
+            end
+        end
+        return m, mi
+    end
+
+    local m, mi = maximum({8,10,23,12,5})
+    is(m, 23, "maximum")
+    is(mi, 3)
+end
+
+do --[[ call by value ]]
+    local function f (n)
+        n = n - 1
+        return n
+    end
+
+    local a = 12
+    is(a, 12, "call by value")
+    local b = f(a)
+    is(b, 11)
+    is(a, 12)
+    local c = f(12)
+    is(c, 11)
+    is(a, 12)
+end
+
+do --[[ call by ref ]]
+    local function f (t)
+        t[#t+1] = 'end'
+        return t
+    end
+
+    local a = { 'a', 'b', 'c' }
+    is(table.concat(a, ','), 'a,b,c', "call by ref")
+    local b = f(a)
+    is(table.concat(b, ','), 'a,b,c,end')
+    is(table.concat(a, ','), 'a,b,c,end')
+end
+
+do --[[ var args ]]
+    local function g1(a, b, ...)
+        local arg = {...}
+        is(a, 3, "vararg")
+        is(b, nil)
+        is(#arg, 0)
+        is(arg[1], nil)
+    end
+    g1(3)
+
+    local function g2(a, b, ...)
+        local arg = {...}
+        is(a, 3)
+        is(b, 4)
+        is(#arg, 0)
+        is(arg[1], nil)
+    end
+    g2(3, 4)
+
+    local function g3(a, b, ...)
+        local arg = {...}
+        is(a, 3)
+        is(b, 4)
+        is(#arg, 2)
+        is(arg[1], 5)
+        is(arg[2], 8)
+    end
+    g3(3, 4, 5, 8)
+end
+
+do --[[ var args ]]
+    local function g1(a, b, ...)
+        local c, d, e = ...
+        is(a, 3, "var args")
+        is(b, nil)
+        is(c, nil)
+        is(d, nil)
+        is(e, nil)
+    end
+    g1(3)
+
+    local function g2(a, b, ...)
+        local c, d, e = ...
+        is(a, 3)
+        is(b, 4)
+        is(c, nil)
+        is(d, nil)
+        is(e, nil)
+    end
+    g2(3, 4)
+
+    local function g3(a, b, ...)
+        local c, d, e = ...
+        is(a, 3)
+        is(b, 4)
+        is(c, 5)
+        is(d, 8)
+        is(e, nil)
+    end
+    g3(3, 4, 5, 8)
+end
+
+do --[[ var args ]]
+    local function g1(a, b, ...)
+        is(#{a, b, ...}, 1, "varargs")
+    end
+    g1(3)
+
+    local function g2(a, b, ...)
+        is(#{a, b, ...}, 2)
+    end
+    g2(3, 4)
+
+    local function g3(a, b, ...)
+        is(#{a, b, ...}, 4)
+    end
+    g3(3, 4, 5, 8)
+end
+
+do --[[ var args ]]
+    local function f() return 1, 2 end
+    local function g() return 'a', f() end
+    local function h() return f(), 'b' end
+    local function k() return 'c', (f()) end
+
+    local x, y = f()
+    is(x, 1, "var args")
+    is(y, 2)
+    local z
+    x, y, z = g()
+    is(x, 'a')
+    is(y, 1)
+    is(z, 2)
+    x, y = h()
+    is(x, 1)
+    is(y, 'b')
+    x, y, z = k()
+    is(x, 'c')
+    is(y, 1)
+    is(z, nil)
+end
+
+do --[[ invalid var args ]]
+    local f, msg = loadstring [[
+function f ()
+    print(...)
+end
+]]
+    like(msg, "^[^:]+:%d+: cannot use '...' outside a vararg function", "invalid var args")
+end
+
+do --[[ tail call ]]
+    local output = {}
+    local function foo (n)
+        output[#output+1] = n
+        if n > 0 then
+            return foo(n -1)
+        end
+        return 'end', 0
+    end
+
+    eq_array({foo(3)}, {'end', 0}, "tail call")
+    eq_array(output, {3, 2, 1, 0})
+end
+
+do --[[ no tail call ]]
+    local output = {}
+    local function foo (n)
+        output[#output+1] = n
+        if n > 0 then
+            return (foo(n -1))
+        end
+        return 'end', 0
+    end
+
+    is(foo(3), 'end', "no tail call")
+    eq_array(output, {3, 2, 1, 0})
+end
+
+do --[[ no tail call ]]
+    local output = {}
+    local function foo (n)
+        output[#output+1] = n
+        if n > 0 then
+            foo(n -1)
+        end
+    end
+
+    is(foo(3), nil, "no tail call")
+    eq_array(output, {3, 2, 1, 0})
+end
+
+do --[[ sub name ]]
+    local function f () return 1 end
+    is(f(), 1, "sub name")
+
+    function f () return 2 end
+    is(f(), 2)
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/213-closure.t b/test/lua-Harness-tests/213-closure.t
new file mode 100755
index 0000000..fc3bd29
--- /dev/null
+++ b/test/lua-Harness-tests/213-closure.t
@@ -0,0 +1,98 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2018, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua closures
+
+=head2 Synopsis
+
+    % prove 213-closure.t
+
+=head2 Description
+
+See section "Closures" in "Programming in Lua".
+
+=cut
+
+--]]
+
+require'tap'
+
+plan(15)
+
+do --[[ inc ]]
+    local counter = 0
+
+    local function inc (x)
+        counter = counter + x
+        return counter
+    end
+
+    is(inc(1), 1, "inc")
+    is(inc(2), 3)
+end
+
+do --[[ newCounter ]]
+    local function newCounter ()
+        local i = 0
+        return function ()  -- anonymous function
+                   i = i + 1
+                   return i
+               end
+    end
+
+    local c1 = newCounter()
+    is(c1(), 1, "newCounter")
+    is(c1(), 2)
+
+    local c2 = newCounter()
+    is(c2(), 1)
+    is(c1(), 3)
+    is(c2(), 2)
+end
+
+do --[[
+The loop creates ten closures (that is, ten instances of the anonymous
+function). Each of these closures uses a different y variable, while all
+of them share the same x.
+]]
+    local a = {}
+    local x = 20
+    for i=1,10 do
+        local y = 0
+        a[i] = function () y=y+1; return x+y end
+    end
+
+    is(a[1](), 21, "ten closures")
+    is(a[1](), 22)
+    is(a[2](), 21)
+end
+
+do --[[ add ]]
+    local function add(x)
+        return function (y) return (x + y) end
+    end
+
+    local f = add(2)
+    type_ok(f, 'function', "add")
+    is(f(10), 12)
+    local g = add(5)
+    is(g(1), 6)
+    is(g(10), 15)
+    is(f(1), 3)
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/214-coroutine.t b/test/lua-Harness-tests/214-coroutine.t
new file mode 100755
index 0000000..92929e1
--- /dev/null
+++ b/test/lua-Harness-tests/214-coroutine.t
@@ -0,0 +1,244 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2020, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua coroutines
+
+=head2 Synopsis
+
+    % prove 214-coroutine.t
+
+=head2 Description
+
+See section "Coroutines" in "Reference Manual"
+L<https://www.lua.org/manual/5.1/manual.html#2.11>,
+L<https://www.lua.org/manual/5.2/manual.html#2.6>,
+L<https://www.lua.org/manual/5.3/manual.html#2.6>,
+L<https://www.lua.org/manual/5.4/manual.html#2.6>
+
+See section "Coroutines" in "Programming in Lua".
+
+=cut
+
+--]]
+
+require'tap'
+local profile = require'profile'
+local luajit21 = jit and (jit.version_num >= 20100 or jit.version:match'^RaptorJIT')
+local has_coroutine52 = _VERSION >= 'Lua 5.2' or jit
+local has_running52 = _VERSION >= 'Lua 5.2' or (profile.luajit_compat52 and not ujit)
+local has_isyieldable = _VERSION >= 'Lua 5.3' or luajit21
+local has_close = _VERSION >= 'Lua 5.4'
+
+plan'no_plan'
+
+do
+    local output = {}
+
+    local function foo1 (a)
+        output[#output+1] = "foo " .. tostring(a)
+        return coroutine.yield(2*a)
+    end
+
+    local co = coroutine.create(function (a,b)
+        local r, s
+        output[#output+1] = "co-body " .. tostring(a) .." " .. tostring(b)
+        r = foo1(a+1)
+        output[#output+1] = "co-body " .. r
+        r, s = coroutine.yield(a+b, a-b)
+        output[#output+1] = "co-body " .. r .. " " .. s
+        return b, 'end'
+    end)
+
+    eq_array({coroutine.resume(co, 1, 10)}, {true, 4}, "foo1")
+    eq_array({coroutine.resume(co, 'r')}, {true, 11, -9})
+    eq_array({coroutine.resume(co, "x", "y")}, {true, 10, 'end'})
+    eq_array({coroutine.resume(co, "x", "y")}, {false, "cannot resume dead coroutine"})
+    eq_array(output, {
+        'co-body 1 10',
+        'foo 2',
+        'co-body r',
+        'co-body x y',
+    })
+end
+
+do
+    local output = ''
+    local co = coroutine.create(function ()
+        output = 'hi'
+    end)
+    like(co, '^thread: 0?[Xx]?%x+$', "basics")
+
+    is(coroutine.status(co), 'suspended')
+    coroutine.resume(co)
+    is(output, 'hi')
+    is(coroutine.status(co), 'dead')
+
+    error_like(function () coroutine.create(true) end,
+               "^[^:]+:%d+: bad argument #1 to 'create' %(.- expected")
+
+    error_like(function () coroutine.resume(true) end,
+               "^[^:]+:%d+: bad argument #1 to 'resume' %(.- expected")
+
+    error_like(function () coroutine.status(true) end,
+               "^[^:]+:%d+: bad argument #1 to 'status' %(.- expected")
+end
+
+do
+    local output = {}
+    local co = coroutine.create(function ()
+        for i=1,10 do
+            output[#output+1] = i
+            coroutine.yield()
+        end
+    end)
+
+    coroutine.resume(co)
+    if has_running52 then
+        local thr, ismain = coroutine.running()
+        type_ok(thr, 'thread', "running")
+        is(ismain, true, "running")
+    else
+        local thr = coroutine.running()
+        is(thr, nil, "main thread")
+    end
+    is(coroutine.status(co), 'suspended', "basics")
+    coroutine.resume(co)
+    coroutine.resume(co)
+    coroutine.resume(co)
+    coroutine.resume(co)
+    coroutine.resume(co)
+    coroutine.resume(co)
+    coroutine.resume(co)
+    coroutine.resume(co)
+    coroutine.resume(co)
+    coroutine.resume(co)
+    eq_array({coroutine.resume(co)}, {false, 'cannot resume dead coroutine'})
+    eq_array(output, {1,2,3,4,5,6,7,8,9,10})
+end
+
+do
+    local co = coroutine.create(function (a,b)
+        coroutine.yield(a + b, a - b)
+    end)
+
+    eq_array({coroutine.resume(co, 20, 10)}, {true, 30, 10}, "basics")
+end
+
+do
+    local co = coroutine.create(function ()
+        return 6, 7
+    end)
+
+    eq_array({coroutine.resume(co)}, {true, 6, 7}, "basics")
+end
+
+if has_coroutine52 then
+    local co = coroutine.wrap(function(...)
+        return pcall(function(...)
+            return coroutine.yield(...)
+        end, ...)
+    end)
+    eq_array({co("Hello")}, {"Hello"})
+    eq_array({co("World")}, {true, "World"})
+end
+
+if has_coroutine52 then
+    local co = coroutine.wrap(function(...)
+        local function backtrace ()
+            return 'not a back trace'
+        end
+        return xpcall(function(...)
+            return coroutine.yield(...)
+        end, backtrace, ...)
+    end)
+    eq_array({co("Hello")}, {"Hello"})
+    eq_array({co("World")}, {true, "World"})
+end
+
+if has_coroutine52 then
+    local output = {}
+    local co = coroutine.wrap(function()
+        while true do
+            local t = setmetatable({}, {
+                __eq = function(...)
+                    return coroutine.yield(...)
+                end}
+            )
+            local t2 = setmetatable({}, getmetatable(t))
+            output[#output+1] = t == t2
+        end
+    end)
+    co()
+    co(true)
+    co(false)
+    eq_array(output, {true, false})
+end
+
+if has_coroutine52 then
+    local co = coroutine.wrap(print)
+    type_ok(co, 'function')
+
+    error_like(function () coroutine.wrap(true) end,
+               "^[^:]+:%d+: bad argument #1 to 'wrap' %(function expected, got boolean%)")
+
+    co = coroutine.wrap(function () error"in coro" end)
+    error_like(function () co() end,
+               "^[^:]+:%d+: [^:]+:%d+: in coro$")
+end
+
+do
+    local co = coroutine.create(function ()
+        error "in coro"
+    end)
+    local r, msg = coroutine.resume(co)
+    is(r, false)
+    like(msg, "^[^:]+:%d+: in coro$")
+end
+
+do
+    error_like(function () coroutine.yield() end,
+               "attempt to yield")
+
+    if has_isyieldable then
+        is(coroutine.isyieldable(), false, "isyieldable")
+    else
+        is(coroutine.isyieldable, nil, "no coroutine.isyieldable")
+    end
+end
+
+-- close
+if has_close then
+    local output = ''
+    local co = coroutine.create(function ()
+        output = 'hi'
+    end)
+    is(coroutine.close(co), true, "close")
+    is(coroutine.status(co), 'dead')
+    is(coroutine.close(co), true, "close again")
+
+    error_like(function () coroutine.close(coroutine.running()) end,
+               "^[^:]+:%d+: cannot close a running coroutine")
+
+    error_like(function () coroutine.close(42) end,
+               "^[^:]+:%d+: bad argument #1 to 'close' %(thread expected, got number%)")
+else
+    is(coroutine.close, nil, "no coroutine.close")
+end
+
+done_testing()
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/221-table.t b/test/lua-Harness-tests/221-table.t
new file mode 100755
index 0000000..7ed6c65
--- /dev/null
+++ b/test/lua-Harness-tests/221-table.t
@@ -0,0 +1,120 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2018, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua tables
+
+=head2 Synopsis
+
+    % prove 221-table.t
+
+=head2 Description
+
+See section "Tables" in "Programming in Lua".
+
+=cut
+
+--]]
+
+require'tap'
+
+plan(25)
+
+do
+    local a = {}
+    local k = 'x'
+    a[k] = 10
+    a[20] = 'great'
+    is(a['x'], 10)
+    k = 20
+    is(a[k], 'great')
+    a['x'] = a ['x'] + 1
+    is(a['x'], 11)
+end
+
+do
+    local a = {}
+    a['x'] = 10
+    local b = a
+    is(b['x'], 10)
+    b['x'] = 20
+    is(a['x'], 20)
+    a = nil
+    b = nil
+end
+
+do
+    local a = {}
+    for i=1,1000 do a[i] = i*2 end
+    is(a[9], 18)
+    a['x'] = 10
+    is(a['x'], 10)
+    is(a['y'], nil)
+end
+
+do
+    local a = {}
+    local x = 'y'
+    a[x] = 10
+    is(a[x], 10)
+    is(a.x, nil)
+    is(a.y, 10)
+end
+
+do
+    local i = 10; local j = '10'; local k = '+10'
+    local a = {}
+    a[i] = "one value"
+    a[j] = "another value"
+    a[k] = "yet another value"
+    is(a[j], "another value")
+    is(a[k], "yet another value")
+    is(a[tonumber(j)], "one value")
+    is(a[tonumber(k)], "one value")
+end
+
+do
+    local t = { {'a','b','c'}, 10 }
+    is(t[2], 10)
+    is(t[1][3], 'c')
+    t[1][1] = 'A'
+    is(table.concat(t[1],','), 'A,b,c')
+end
+
+do
+    local tt = { {'a','b','c'}, 10 }
+    is(tt[2], 10)
+    is(tt[1][3], 'c')
+    tt[1][1] = 'A'
+    is(table.concat(tt[1],','), 'A,b,c')
+end
+
+do
+    local a = {}
+    error_like(function () a() end,
+               "^[^:]+:%d+: attempt to call")
+end
+
+do
+    local tt = { {'a','b','c'}, 10 }
+    is((tt)[2], 10)
+    is((tt[1])[3], 'c');
+    (tt)[1][2] = 'B'
+    (tt[1])[3] = 'C'
+    is(table.concat(tt[1],','), 'a,B,C')
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/222-constructor.t b/test/lua-Harness-tests/222-constructor.t
new file mode 100755
index 0000000..a01be2e
--- /dev/null
+++ b/test/lua-Harness-tests/222-constructor.t
@@ -0,0 +1,119 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2020, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua Table Constructors
+
+=head2 Synopsis
+
+    % prove 222-constructor.t
+
+=head2 Description
+
+See section "Table Constructors" in "Reference Manual"
+L<https://www.lua.org/manual/5.1/manual.html#2.5.7>,
+L<https://www.lua.org/manual/5.2/manual.html#3.4.8>,
+L<https://www.lua.org/manual/5.3/manual.html#3.4.9>,
+L<https://www.lua.org/manual/5.4/manual.html#3.4.9>
+
+See section "Table Constructors" in "Programming in Lua".
+
+=cut
+
+--]]
+
+require'tap'
+
+plan(16)
+
+do --[[ list-style init ]]
+    local days = {'Sunday', 'Monday', 'Tuesday', 'Wednesday',
+                  'Thursday', 'Friday', 'Saturday'}
+    is(days[4], 'Wednesday', "list-style init")
+    is(#days, 7)
+end
+
+do
+    local large = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+                    1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+                    1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+                    1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+                    1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+                    1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+                    1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+                    1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+                    1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+                    1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }
+    is(#large, 100)
+    large = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+              1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+              1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+              1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+              1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+              1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+              1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+              1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+              1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+              1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }
+    is(#large, 200)
+end
+
+do --[[ record-style init ]]
+    local a = {x=0, y=0}
+    is(a.x, 0, "record-style init")
+    is(a.y, 0)
+end
+
+do
+    local w = {x=0, y=0, label='console'}
+    local x = {0, 1, 2}
+    w[1] = "another field"
+    x.f = w
+    is(w['x'], 0, "ctor")
+    is(w[1], "another field")
+    is(x.f[1], "another field")
+    w.x = nil
+end
+
+do --[[ mix record-style and list-style init ]]
+    local polyline = {color='blue', thickness=2, npoints=4,
+                       {x=0,   y=0},
+                       {x=-10, y=0},
+                       {x=-10, y=1},
+                       {x=0,   y=1}
+                     }
+    is(polyline[2].x, -10, "mix record-style and list-style init")
+end
+
+do
+    local opnames = {['+'] = 'add', ['-'] = 'sub',
+                     ['*'] = 'mul', ['/'] = 'div'}
+    local i = 20; local s = '-'
+    local a = {[i+0] = s, [i+1] = s..s, [i+2] = s..s..s}
+    is(opnames[s], 'sub', "ctor")
+    is(a[22], '---')
+end
+
+do
+    local function f() return 10, 20 end
+
+    eq_array({f()}, {10, 20}, "ctor")
+    eq_array({'a', f()}, {'a', 10, 20})
+    eq_array({f(), 'b'}, {10, 'b'})
+    eq_array({'c', (f())}, {'c', 10})
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/223-iterator.t b/test/lua-Harness-tests/223-iterator.t
new file mode 100755
index 0000000..777ad73
--- /dev/null
+++ b/test/lua-Harness-tests/223-iterator.t
@@ -0,0 +1,203 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2018, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua iterators
+
+=head2 Synopsis
+
+    % prove 223-iterator.t
+
+=head2 Description
+
+See section "Iterators and the Generic for" and
+section "Coroutines as Iterators" in "Programming in Lua".
+
+=cut
+
+--]]
+
+require'tap'
+
+plan(8)
+
+do --[[ list_iter ]]
+    local function list_iter (t)
+        local i = 0
+        local n = #t
+        return function ()
+                   i = i + 1
+                   if i <= n then
+                       return t[i]
+                   else
+                       return nil
+                   end
+               end
+    end
+
+    local t = {10, 20, 30}
+    local output = {}
+    for element in list_iter(t) do
+        output[#output+1] = element
+    end
+    eq_array(output, t, "list_iter")
+end
+
+do --[[ values ]]
+    local function values (t)
+        local i = 0
+        return function ()
+                   i = i + 1
+                   return t[i]
+               end
+    end
+
+    local t = {10, 20, 30}
+    local output = {}
+    for element in values(t) do
+        output[#output+1] = element
+    end
+    eq_array(output, t, "values")
+end
+
+do --[[ emul ipairs ]]
+    local function iter (a, i)
+        i = i + 1
+        local v = a[i]
+        if v then
+            return i, v
+        end
+    end
+
+    local function my_ipairs (a)
+        return iter, a, 0
+    end
+
+    local a = {'one', 'two', 'three'}
+    local output = {}
+    for i, v in my_ipairs(a) do
+        output[#output+1] = i
+        output[#output+1] = v
+    end
+    eq_array(output, {1, 'one', 2, 'two', 3, 'three'}, "emul ipairs")
+end
+
+do --[[ emul pairs ]]
+    local function my_pairs (t)
+        return next, t, nil
+    end
+
+    local a = {'one', 'two', 'three'}
+    local output = {}
+    for k, v in my_pairs(a) do
+        output[#output+1] = k
+        output[#output+1] = v
+    end
+    eq_array(output, {1, 'one', 2, 'two', 3, 'three'}, "emul ipairs")
+end
+
+do --[[ with next ]]
+    local t = {'one', 'two', 'three'}
+    local output = {}
+    for k, v in next, t do
+        output[#output+1] = k
+        output[#output+1] = v
+    end
+    eq_array(output, {1, 'one', 2, 'two', 3, 'three'}, "with next")
+end
+
+do --[[ permutations ]]
+    local function permgen (a, n)
+        n = n or #a         -- default for 'n' is size of 'a'
+        if n <= 1 then      -- nothing to change?
+            coroutine.yield(a)
+        else
+            for i=1,n do
+                -- put i-th element as the last one
+                a[n], a[i] = a[i], a[n]
+                -- generate all permutations of the other elements
+                permgen(a, n - 1)
+                -- restore i-th element
+                a[n], a[i] = a[i], a[n]
+            end
+        end
+    end
+
+    local function permutations (a)
+        local co = coroutine.create(function () permgen(a) end)
+        return function ()  -- iterator
+                   local code, res = coroutine.resume(co)
+                   return res
+               end
+    end
+
+    local output = {}
+    for p in permutations{'a', 'b', 'c'} do
+        output[#output+1] = table.concat(p, ' ')
+    end
+    eq_array(output, {'b c a','c b a','c a b','a c b','b a c','a b c'}, "permutations")
+end
+
+do --[[ permutations with wrap ]]
+    local function permgen (a, n)
+        n = n or #a         -- default for 'n' is size of 'a'
+        if n <= 1 then      -- nothing to change?
+            coroutine.yield(a)
+        else
+            for i=1,n do
+                -- put i-th element as the last one
+                a[n], a[i] = a[i], a[n]
+                -- generate all permutations of the other elements
+                permgen(a, n - 1)
+                -- restore i-th element
+                a[n], a[i] = a[i], a[n]
+            end
+        end
+    end
+
+    local function permutations (a)
+        return coroutine.wrap(function () permgen(a) end)
+    end
+
+    local output = {}
+    for p in permutations{'a', 'b', 'c'} do
+        output[#output+1] = table.concat(p, ' ')
+    end
+    eq_array(output, {'b c a','c b a','c a b','a c b','b a c','a b c'}, "permutations with wrap")
+end
+
+do --[[ fibo ]]
+    local function fibogen ()
+        local x, y = 0, 1
+        while true do
+            coroutine.yield(x)
+            x, y = y, x + y
+        end
+    end
+
+    local function fibo ()
+        return coroutine.wrap(function () fibogen() end)
+    end
+
+    local output = {}
+    for n in fibo() do
+        output[#output+1] = n
+        if n > 30 then break end
+    end
+    eq_array(output, {0, 1, 1, 2, 3, 5, 8, 13, 21, 34}, "fibo")
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/231-metatable.t b/test/lua-Harness-tests/231-metatable.t
new file mode 100755
index 0000000..a2c6499
--- /dev/null
+++ b/test/lua-Harness-tests/231-metatable.t
@@ -0,0 +1,602 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2020, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua metatables
+
+=head2 Synopsis
+
+    % prove 231-metatable.t
+
+=head2 Description
+
+See section "Metatables and Metamethods" in "Reference Manual"
+L<https://www.lua.org/manual/5.1/manual.html#2.8>,
+L<https://www.lua.org/manual/5.2/manual.html#2.4>,
+L<https://www.lua.org/manual/5.3/manual.html#2.4>,
+L<https://www.lua.org/manual/5.4/manual.html#2.4>
+
+See section "Metatables and Metamethods" in "Programming in Lua".
+
+=cut
+
+--]]
+
+require'tap'
+local profile = require'profile'
+local has_metamethod52 = _VERSION >= 'Lua 5.2' or profile.luajit_compat52
+local has_metamethod_ipairs = _VERSION == 'Lua 5.2' or profile.compat52 or profile.luajit_compat52
+local has_metamethod_le_emulated = _VERSION <= 'Lua 5.3' or profile.compat53
+local has_metamethod_pairs = _VERSION >= 'Lua 5.2' or profile.luajit_compat52
+local has_metamethod_tostring53 = _VERSION >= 'Lua 5.3'
+local has_metamethod_tostring54 = _VERSION >= 'Lua 5.4'
+local has_anno_toclose = _VERSION >= 'Lua 5.4'
+
+plan'no_plan'
+
+do
+    local t = {}
+    is(getmetatable(t), nil, "metatable")
+    local t1 = {}
+    is(setmetatable(t, t1), t)
+    is(getmetatable(t), t1)
+    is(setmetatable(t, nil), t)
+    error_like(function () setmetatable(t, true) end,
+               "^[^:]+:%d+: bad argument #2 to 'setmetatable' %(nil or table expected")
+
+    local mt = {}
+    mt.__metatable = "not your business"
+    setmetatable(t, mt)
+    is(getmetatable(t), "not your business", "protected metatable")
+    error_like(function () setmetatable(t, {}) end,
+               "^[^:]+:%d+: cannot change a protected metatable")
+
+    is(getmetatable('').__index, string, "metatable for string")
+
+    is(getmetatable(nil), nil, "metatable for nil")
+    is(getmetatable(false), nil, "metatable for boolean")
+    is(getmetatable(2), nil, "metatable for number")
+    is(getmetatable(print), nil, "metatable for function")
+end
+
+do
+    local t = {}
+    local mt = { __tostring=function () return '__TABLE__' end }
+    setmetatable(t, mt)
+    is(tostring(t), '__TABLE__', "__tostring")
+end
+
+do
+    local t = {}
+    local mt = {}
+    local a = nil
+    function mt.__tostring () a = "return nothing" end
+    setmetatable(t, mt)
+    if has_metamethod_tostring53 then
+        error_like(function () tostring(t) end,
+                   "^[^:]+:%d+: '__tostring' must return a string")
+        is(a, "return nothing")
+        if has_metamethod_tostring54 then
+            error_like(function () print(t) end,
+                       "^[^:]+:%d+: '__tostring' must return a string")
+        else
+            error_is(function () print(t) end,
+                     "'__tostring' must return a string")
+        end
+    else
+        is(tostring(t), nil, "__tostring no-output")
+        is(a, "return nothing")
+        error_like(function () print(t) end,
+                   "^[^:]+:%d+: 'tostring' must return a string to 'print'")
+    end
+
+    mt.__tostring = function () return '__FIRST__', 2 end
+    setmetatable(t, mt)
+    is(tostring(t), '__FIRST__', "__tostring too-many-output")
+end
+
+do
+    local t = {}
+    t.mt = {}
+    setmetatable(t, t.mt)
+    t.mt.__tostring = "not a function"
+    error_like(function () tostring(t) end,
+               "attempt to call",
+               "__tostring invalid")
+end
+
+do
+    local t = {}
+    local mt = { __len=function () return 42 end }
+    setmetatable(t, mt)
+    if has_metamethod52 then
+        is(#t, 42, "__len")
+    else
+        is(#t, 0, "__len 5.1")
+    end
+end
+
+if has_metamethod52 then
+    local t = {}
+    local mt = { __len=function () return nil end }
+    setmetatable(t, mt)
+    if jit then
+        todo("not with LuaJIT")
+    end
+    error_like(function () print(table.concat(t)) end,
+               "object length is not a.-er",
+               "__len invalid")
+end
+
+do
+    local t = {}
+    local mt = {
+        __tostring=function () return 't' end,
+        __concat=function (op1, op2)
+            return tostring(op1) .. '|' .. tostring(op2)
+        end,
+    }
+    setmetatable(t, mt)
+    is(t .. t .. t ..'end' .. '.', "t|t|t|end.", "__concat")
+end
+
+do --[[ Cplx ]]
+    local Cplx = {}
+    Cplx.mt = {}
+    local tointeger = math.tointeger or math.floor
+
+    function Cplx.new (re, im)
+        local c = {}
+        setmetatable(c, Cplx.mt)
+        c.re = tonumber(re)
+        if im == nil then
+            c.im = 0.0
+        else
+            c.im = tonumber(im)
+        end
+        return c
+    end
+
+    function Cplx.mt.__tostring (c)
+        return '(' .. tostring(tointeger(c.re)) .. ',' .. tostring(tointeger(c.im)) .. ')'
+    end
+
+    function Cplx.mt.__add (a, b)
+        if type(a) ~= 'table' then
+            a = Cplx.new(a, 0)
+        end
+        if type(b) ~= 'table' then
+            b = Cplx.new(b, 0)
+        end
+        local r = Cplx.new(a.re + b.re, a.im + b.im)
+        return r
+    end
+
+    local c1 = Cplx.new(1, 3)
+    local c2 = Cplx.new(2, -1)
+
+    is(tostring(c1 + c2), '(3,2)', "cplx __add")
+    is(tostring(c1 + 3), '(4,3)')
+    is(tostring(-2 + c1), '(-1,3)')
+    is(tostring(c1 + '3'), '(4,3)')
+    is(tostring('-2' + c1), '(-1,3)')
+
+    function Cplx.mt.__sub (a, b)
+        if type(a) ~= 'table' then
+            a = Cplx.new(a, 0)
+        end
+        if type(b) ~= 'table' then
+            b = Cplx.new(b, 0)
+        end
+        local r = Cplx.new(a.re - b.re, a.im - b.im)
+        return r
+    end
+
+    is(tostring(c1 - c2), '(-1,4)', "cplx __sub")
+    is(tostring(c1 - 3), '(-2,3)')
+    is(tostring(-2 - c1), '(-3,-3)')
+    is(tostring(c1 - '3'), '(-2,3)')
+    is(tostring('-2' - c1), '(-3,-3)')
+
+    function Cplx.mt.__mul (a, b)
+        if type(a) ~= 'table' then
+            a = Cplx.new(a, 0)
+        end
+        if type(b) ~= 'table' then
+            b = Cplx.new(b, 0)
+        end
+        local r = Cplx.new(a.re*b.re - a.im*b.im,
+            a.re*b.im + a.im*b.re)
+        return r
+    end
+
+    is(tostring(c1 * c2), '(5,5)', "cplx __mul")
+    is(tostring(c1 * 3), '(3,9)')
+    is(tostring(-2 * c1), '(-2,-6)')
+    is(tostring(c1 * '3'), '(3,9)')
+    is(tostring('-2' * c1), '(-2,-6)')
+
+    function Cplx.mt.__div (a, b)
+        if type(a) ~= 'table' then
+            a = Cplx.new(a, 0)
+        end
+        if type(b) ~= 'table' then
+            b = Cplx.new(b, 0)
+        end
+        local n = b.re*b.re + b.im*b.im
+        local inv = Cplx.new(b.re/n, b.im/n)
+        local r = Cplx.new(a.re*inv.re - a.im*inv.im,
+                           a.re*inv.im + a.im*inv.re)
+        return r
+    end
+
+    c1 = Cplx.new(2, 6)
+    c2 = Cplx.new(2, 0)
+
+    is(tostring(c1 / c2), '(1,3)', "cplx __div")
+    is(tostring(c1 / 2), '(1,3)')
+    is(tostring(-4 / c2), '(-2,0)')
+    is(tostring(c1 / '2'), '(1,3)')
+    is(tostring('-4' / c2), '(-2,0)')
+
+    function Cplx.mt.__unm (a)
+        if type(a) ~= 'table' then
+            a = Cplx.new(a, 0)
+        end
+        local r = Cplx.new(-a.re, -a.im)
+        return r
+    end
+
+    c1 = Cplx.new(1, 3)
+    is(tostring(- c1), '(-1,-3)', "cplx __unm")
+
+    function Cplx.mt.__len (a)
+        return math.sqrt(a.re*a.re + a.im*a.im)
+    end
+
+    c1 = Cplx.new(3, 4)
+    if has_metamethod52 then
+        is( #c1, 5, "cplx __len")
+    else
+        is( #c1, 0, "__len 5.1")
+    end
+
+    function Cplx.mt.__eq (a, b)
+        if type(a) ~= 'table' then
+            a = Cplx.new(a, 0)
+        end
+        if type(b) ~= 'table' then
+            b = Cplx.new(b, 0)
+        end
+        return (a.re == b.re) and (b.im == b.im)
+    end
+
+    c1 = Cplx.new(2, 0)
+    c2 = Cplx.new(1, 3)
+    local c3 = Cplx.new(2, 0)
+
+    is(c1 ~= c2, true, "cplx __eq")
+    is(c1 == c3, true)
+    is(c1 == 2, false)
+    is(Cplx.mt.__eq(c1, 2), true)
+
+    function Cplx.mt.__lt (a, b)
+        if type(a) ~= 'table' then
+            a = Cplx.new(a, 0)
+        end
+        if type(b) ~= 'table' then
+            b = Cplx.new(b, 0)
+        end
+        local ra = a.re*a.re + a.im*a.im
+        local rb = b.re*b.re + b.im*b.im
+        return ra < rb
+    end
+
+    is(c1 < c2, true, "cplx __lt")
+    is(c1 < c3, false)
+    if has_metamethod_le_emulated then
+        is(c1 <= c3, true)
+    end
+    if has_metamethod52 then
+        is(c1 < 1, false)
+        is(c1 < 4, true)
+    end
+
+    function Cplx.mt.__le (a, b)
+        if type(a) ~= 'table' then
+            a = Cplx.new(a, 0)
+        end
+        if type(b) ~= 'table' then
+            b = Cplx.new(b, 0)
+        end
+        local ra = a.re*a.re + a.im*a.im
+        local rb = b.re*b.re + b.im*b.im
+        return ra <= rb
+    end
+
+    is(c1 < c2, true, "cplx __lt __le")
+    is(c1 < c3, false)
+    is(c1 <= c3, true)
+
+    local a = nil
+    function Cplx.mt.__call (obj)
+        a = "Cplx.__call " .. tostring(obj)
+        return true
+    end
+
+    c1 = Cplx.new(2, 0)
+    local r = c1()
+    is(r, true, "cplx __call (without args)")
+    is(a, "Cplx.__call (2,0)")
+
+    function Cplx.mt.__call (obj, ...)
+        a = "Cplx.__call " .. tostring(obj) .. ", " .. table.concat({...}, ", ")
+        return true
+    end
+
+    is(c1(), true, "cplx __call (with args)")
+    is(a, "Cplx.__call (2,0), ")
+    is(c1('a'), true)
+    is(a, "Cplx.__call (2,0), a")
+    is(c1('a', 'b', 'c'), true)
+    is(a, "Cplx.__call (2,0), a, b, c")
+end
+
+--[[ delegate ]]
+if has_metamethod_pairs then
+    local t = {
+        _VALUES = {
+            a = 1,
+            b = 'text',
+            c = true,
+        }
+    }
+    local mt = {
+        __pairs = function (op)
+            return next, op._VALUES
+        end
+    }
+    setmetatable(t, mt)
+
+    local r = {}
+    for k in pairs(t) do
+        r[#r+1] = k
+    end
+    table.sort(r)
+    is( table.concat(r, ','), 'a,b,c', "__pairs" )
+end
+if has_metamethod_ipairs then
+    local t = {
+        _VALUES = { 'a', 'b', 'c' }
+    }
+    local mt = {
+        __ipairs = function (op)
+            return ipairs(op._VALUES)
+        end
+    }
+    setmetatable(t, mt)
+
+    local r = ''
+    for i, v in ipairs(t) do
+        r = r .. v
+    end
+    is( r, 'abc', "__ipairs" )
+end
+
+do --[[ Window ]]
+    -- create a namespace
+    local Window = {}
+    -- create a prototype with default values
+    Window.prototype = {x=0, y=0, width=100, heigth=100, }
+    -- create a metatable
+    Window.mt = {}
+    -- declare the constructor function
+    function Window.new (o)
+        setmetatable(o, Window.mt)
+        return o
+    end
+
+    Window.mt.__index = function (table, key)
+        return Window.prototype[key]
+    end
+
+    local w = Window.new{x=10, y=20}
+    is(w.x, 10, "table-access")
+    is(w.width, 100)
+    is(rawget(w, 'x'), 10)
+    is(rawget(w, 'width'), nil)
+
+    Window.mt.__index = Window.prototype  -- just a table
+    w = Window.new{x=10, y=20}
+    is(w.x, 10, "table-access")
+    is(w.width, 100)
+    is(rawget(w, 'x'), 10)
+    is(rawget(w, 'width'), nil)
+end
+
+do --[[ tables with default values ]]
+    local function setDefault_1 (t, d)
+        local mt = {__index = function () return d end}
+        setmetatable (t, mt)
+    end
+
+    local tab = {x=10, y=20}
+    is(tab.x, 10, "tables with default values")
+    is(tab.z, nil)
+    setDefault_1(tab, 0)
+    is(tab.x, 10)
+    is(tab.z, 0)
+end
+
+do --[[ tables with default values ]]
+    local mt = {__index = function (t) return t.___ end}
+    local function setDefault_2 (t, d)
+        t.___ = d
+        setmetatable (t, mt)
+    end
+
+    local tab = {x=10, y=20}
+    is(tab.x, 10, "tables with default values")
+    is(tab.z, nil)
+    setDefault_2(tab, 0)
+    is(tab.x, 10)
+    is(tab.z, 0)
+end
+
+do --[[ tables with default values ]]
+    local key = {}
+    local mt = {__index = function (t) return t[key] end}
+    local function setDefault_3 (t, d)
+        t[key] = d
+        setmetatable (t, mt)
+    end
+
+    local tab = {x=10, y=20}
+    is(tab.x, 10, "tables with default values")
+    is(tab.z, nil)
+    setDefault_3(tab, 0)
+    is(tab.x, 10)
+    is(tab.z, 0)
+end
+
+do --[[ private access ]]
+    local t = {}  -- original table
+    -- keep a private access to original table
+    local _t = t
+    -- create proxy
+    t = {}
+
+    local w = nil
+    local r = nil
+    -- create metatable
+    local mt = {
+        __index = function (t,k)
+            r = "*access to element " .. tostring(k)
+            return _t[k]  -- access the original table
+        end,
+
+        __newindex = function (t,k,v)
+             w = "*update of element " .. tostring(k) ..
+                                " to " .. tostring(v)
+            _t[k] = v  -- update original table
+        end
+    }
+    setmetatable(t, mt)
+
+    t[2] = 'hello'
+    is(t[2], 'hello', "tracking table accesses")
+    is(w, "*update of element 2 to hello")
+    is(r, "*access to element 2")
+end
+
+do --[[ private access ]]
+    -- create private index
+    local index = {}
+
+    local w = nil
+    local r = nil
+    -- create metatable
+    local mt = {
+        __index = function (t,k)
+            r = "*access to element " .. tostring(k)
+            return t[index][k]  -- access the original table
+        end,
+
+        __newindex = function (t,k,v)
+            w = "*update of element " .. tostring(k) ..
+                               " to " .. tostring(v)
+            t[index][k] = v  -- update original table
+        end
+    }
+    local function track (t)
+        local proxy = {}
+        proxy[index] = t
+        setmetatable(proxy, mt)
+        return proxy
+    end
+
+    local t = {}
+    t = track(t)
+
+    t[2] = 'hello'
+    is(t[2], 'hello', "tracking table accesses")
+    is(w, "*update of element 2 to hello")
+    is(r, "*access to element 2")
+end
+
+do --[[ read-only table ]]
+    local function readOnly (t)
+        local proxy = {}
+        local mt = {
+            __index = t,
+            __newindex = function (_t,k,v)
+                error("attempt to update a read-only table", 2)
+            end
+        }
+        setmetatable(proxy, mt)
+        return proxy
+    end
+
+    local days = readOnly{'Sunday', 'Monday', 'Tuesday', 'Wednesday',
+                         'Thurday', 'Friday', 'Saturday'}
+
+    is(days[1], 'Sunday', "read-only tables")
+
+    error_like(function () days[2] = 'Noday' end,
+               "^[^:]+:%d+: attempt to update a read%-only table")
+end
+
+do --[[ declare global ]]
+    local function declare (name, initval)
+        rawset(_G, name, initval or false)
+    end
+
+    setmetatable(_G, {
+        __newindex = function (_, n)
+            error("attempt to write to undeclared variable " .. n, 2)
+        end,
+        __index = function (_, n)
+            error("attempt to read undeclared variable" .. n, 2)
+        end,
+    })
+
+    error_like(function () new_a = 1 end,
+               "^[^:]+:%d+: attempt to write to undeclared variable new_a",
+               "declaring global variables")
+
+    declare 'new_a'
+    new_a = 1
+    is(new_a, 1)
+end
+
+do
+    local newindex = {}
+    -- create metatable
+    local mt = {
+        __newindex = newindex
+    }
+    local t = setmetatable({}, mt)
+    t[1] = 42
+    is(newindex[1], 42, "__newindex")
+end
+
+if has_anno_toclose then
+    dofile'lexico54/metatable.t'
+end
+
+done_testing()
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/232-object.t b/test/lua-Harness-tests/232-object.t
new file mode 100755
index 0000000..0d87572
--- /dev/null
+++ b/test/lua-Harness-tests/232-object.t
@@ -0,0 +1,314 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2018, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua object
+
+=head2 Synopsis
+
+    % prove 232-object.t
+
+=head2 Description
+
+See section "Object-Oriented Programming" in "Programming in Lua".
+
+=cut
+
+--]]
+
+require'tap'
+
+plan(18)
+
+do --[[ object ]]
+    local Account = {balance = 0}
+
+    function Account.withdraw (self, v)
+        self.balance = self.balance - v
+    end
+
+    local a1 = Account; Account = nil
+    a1.withdraw(a1, 100.00)
+    is(a1.balance, -100, "object")
+
+    local a2 = {balance = 0, withdraw = a1.withdraw}
+    a2.withdraw(a2, 260.00)
+    is(a2.balance, -260)
+end
+
+do --[[ object ]]
+    local Account = {balance = 0}
+
+    function Account:withdraw (v)
+        self.balance = self.balance - v
+    end
+
+    local a = Account
+    a:withdraw(100.00)
+    is(a.balance, -100, "object")
+
+    Account = { balance = 0,
+                withdraw = function (self, v)
+                               self.balance = self.balance -v
+                           end
+              }
+    function Account:deposit (v)
+        self.balance = self.balance + v
+    end
+
+    Account.deposit(Account, 200.00)
+    is(Account.balance, 200, "object")
+    Account:withdraw(100.00)
+    is(Account.balance, 100)
+end
+
+do --[[ class ]]
+    local Account = {balance = 0}
+
+    function Account:new (o)
+        o = o or {}
+        setmetatable(o, self)
+        self.__index = self
+        return o
+    end
+
+    function Account:deposit (v)
+        self.balance = self.balance + v
+    end
+
+    function Account:withdraw (v)
+        self.balance = self.balance - v
+    end
+
+    local a = Account:new{balance = 0}
+    a:deposit(100.00)
+    is(a.balance, 100, "classe")
+
+    local b = Account:new()
+    is(b.balance, 0)
+    b:deposit(200.00)
+    is(b.balance, 200)
+end
+
+do --[[ inheritance ]]
+    local Account = {balance = 0}
+
+    function Account:new (o)
+    --    print "Account:new"
+        o = o or {}
+        setmetatable(o, self)
+        self.__index = self
+        return o
+    end
+
+    function Account:deposit (v)
+    --    print "Account:deposit"
+        self.balance = self.balance + v
+    end
+
+    function Account:withdraw (v)
+    --    print "Account:withdraw"
+        if v > self.balance then error"insuficient funds" end
+        self.balance = self.balance - v
+    end
+
+    local a = Account:new()
+    is(a.balance, 0, "inheritance")
+    -- r, msg = pcall(Account.withdraw, a, 100)
+    -- print(msg)
+
+    local SpecialAccount = Account:new()
+
+    function SpecialAccount:withdraw (v)
+    --    print "SpecialAccount:withdraw"
+        if self.balance - v <= -self:getLimit() then
+            error"insuficient funds"
+        end
+        self.balance = self.balance - v
+    end
+
+    function SpecialAccount:getLimit ()
+    --    print "SpecialAccount:getLimit"
+        return self.limit or 0
+    end
+
+    local s = SpecialAccount:new{limit=1000.00}
+
+    s:deposit(100.00)
+    is(s.balance, 100)
+
+    s:withdraw(200.00)
+    is(s.balance, -100)
+end
+
+do --[[ multiple inheritance ]]
+    -- look up for 'k' in list of tables 'plist'
+    local function search (k, plist)
+        for i=1, #plist do
+            local v = plist[i][k]  -- try 'i'-th superclass
+            if v then return v end
+        end
+    end
+
+    local function createClass (...)
+        local c = {}  -- new class
+        local arg = {...}
+
+        -- class will search for each method in the list of its
+        -- parents ('arg' is the list of parents)
+        setmetatable(c, {__index = function (t, k)
+            return search(k, arg)
+        end})
+
+        -- prepare 'c' to be the metatable of its instance
+        c.__index = c
+
+        -- define a new constructor for this new class
+        function c:new (o)
+            o = o or {}
+            setmetatable(o, c)
+            return o
+        end
+
+        -- return new class
+        return c
+    end
+
+    local Account = {balance = 0}
+    function Account:deposit (v)
+        self.balance = self.balance + v
+    end
+    function Account:withdraw (v)
+        self.balance = self.balance - v
+    end
+
+    local Named = {}
+    function Named:getname ()
+        return self.name
+    end
+    function Named:setname (n)
+        self.name = n
+    end
+
+    local NamedAccount = createClass(Account, Named)
+
+    local account = NamedAccount:new{name = "Paul"}
+    is(account:getname(), 'Paul', "multiple inheritance")
+    account:deposit(100.00)
+    is(account.balance, 100)
+end
+
+do --[[ multiple inheritance (patched) ]]
+    -- look up for 'k' in list of tables 'plist'
+    local function search (k, plist)
+        for i=1, #plist do
+            local v = plist[i][k]  -- try 'i'-th superclass
+            if v then return v end
+        end
+    end
+
+    local function createClass (...)
+        local c = {}  -- new class
+        local arg = {...}
+
+        -- class will search for each method in the list of its
+        -- parents ('arg' is the list of parents)
+        setmetatable(c, {__index = function (t, k)
+            -- return search(k, arg)
+            return (search(k, arg))
+        end})
+
+        -- prepare 'c' to be the metatable of its instance
+        c.__index = c
+
+        -- define a new constructor for this new class
+        function c:new (o)
+            o = o or {}
+            setmetatable(o, c)
+            return o
+        end
+
+        -- return new class
+        return c
+    end
+
+    local Account = {balance = 0}
+    function Account:deposit (v)
+        self.balance = self.balance + v
+    end
+    function Account:withdraw (v)
+        self.balance = self.balance - v
+    end
+
+    local Named = {}
+    function Named:getname ()
+        return self.name
+    end
+    function Named:setname (n)
+        self.name = n
+    end
+
+    local NamedAccount = createClass(Account, Named)
+
+    local account = NamedAccount:new{name = "Paul"}
+    is(account:getname(), 'Paul', "multiple inheritance (patched)")
+    account:deposit(100.00)
+    is(account.balance, 100)
+end
+
+do --[[ privacy ]]
+    local function newAccount (initialBalance)
+        local self = {balance = initialBalance}
+
+        local withdraw = function (v)
+                             self.balance = self.balance - v
+                         end
+
+        local deposit = function (v)
+                            self.balance = self.balance + v
+                        end
+
+        local getBalance = function () return self.balance end
+
+        return {
+            withdraw = withdraw,
+            deposit = deposit,
+            getBalance = getBalance
+        }
+    end
+
+    local acc1 = newAccount(100.00)
+    acc1.withdraw(40.00)
+    is(acc1.getBalance(), 60, "privacy")
+end
+
+do --[[ single-method approach ]]
+    local function newObject (value)
+        return function (action, v)
+            if action == 'get' then return value
+            elseif action == 'set' then value = v
+            else error("invalid action")
+            end
+        end
+    end
+
+    local d = newObject(0)
+    is(d('get'), 0, "single-method approach")
+    d('set', 10)
+    is(d('get'), 10)
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/241-standalone.t b/test/lua-Harness-tests/241-standalone.t
new file mode 100755
index 0000000..c99f324
--- /dev/null
+++ b/test/lua-Harness-tests/241-standalone.t
@@ -0,0 +1,269 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2020, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua Stand-alone
+
+=head2 Synopsis
+
+    % prove 241-standalone.t
+
+=head2 Description
+
+See section "Lua Stand-alone" in "Reference Manual"
+L<https://www.lua.org/manual/5.1/manual.html#6>,
+L<https://www.lua.org/manual/5.2/manual.html#7>,
+L<https://www.lua.org/manual/5.3/manual.html#7>,
+L<https://www.lua.org/manual/5.4/manual.html#7>
+
+=cut
+
+--]]
+
+require'tap'
+local has_bytecode = not ujit and not ravi
+local has_error52 = _VERSION >= 'Lua 5.2'
+local has_error53 = _VERSION >= 'Lua 5.3'
+local has_opt_E = _VERSION >= 'Lua 5.2' or jit
+local has_opt_W = _VERSION >= 'Lua 5.4'
+local banner = '^[%w%s%-%.]-Copyright %(C%) %d%d%d%d'
+if jit and jit.version:match'^RaptorJIT' then
+    banner = '^[%w%s%.]- %-%- '
+elseif ravi then
+    banner = '^Ravi %d%.%d%.%d'
+end
+
+local lua = arg[-3] or arg[-1]
+local luac = jit and lua or (lua .. 'c')
+
+if not pcall(io.popen, lua .. [[ -e "a=1"]]) then
+    skip_all "io.popen not supported"
+end
+
+plan'no_plan'
+diag(lua)
+
+local f = io.open('hello-241.lua', 'w')
+f:write([[
+print 'Hello World'
+]])
+f:close()
+
+local cmd = lua .. " hello-241.lua"
+f = io.popen(cmd)
+is(f:read'*l', 'Hello World', "file")
+f:close()
+
+cmd = lua .. " -- hello-241.lua"
+f = io.popen(cmd)
+is(f:read'*l', 'Hello World', "-- file")
+f:close()
+
+cmd = lua .. " no_file-241.lua 2>&1"
+f = io.popen(cmd)
+like(f:read'*l', "^[^:]+: cannot open no_file%-241%.lua", "no file")
+f:close()
+
+if has_bytecode then
+    if jit then
+        os.execute(lua .. " -b hello-241.lua hello-241.luac")
+    else
+        os.execute(luac .. " -s -o hello-241.luac hello-241.lua")
+    end
+    cmd = lua .. " hello-241.luac"
+    f = io.popen(cmd)
+    is(f:read'*l', 'Hello World', "bytecode")
+    f:close()
+    os.remove('hello-241.luac') -- clean up
+
+    if not jit then
+        os.execute(luac .. " -s -o hello-hello-241.luac hello-241.lua hello-241.lua")
+        cmd = lua .. " hello-hello-241.luac"
+        f = io.popen(cmd)
+        is(f:read'*l', 'Hello World', "combine 1")
+        is(f:read'*l', 'Hello World', "combine 2")
+        f:close()
+        os.remove('hello-hello-241.luac') -- clean up
+    end
+end
+
+cmd = lua .. " < hello-241.lua"
+f = io.popen(cmd)
+is(f:read'*l', 'Hello World', "redirect")
+f:close()
+
+cmd = lua .. " - < hello-241.lua"
+f = io.popen(cmd)
+is(f:read'*l', 'Hello World', "redirect")
+f:close()
+
+cmd = lua .. " -i hello-241.lua < hello-241.lua 2>&1"
+f = io.popen(cmd)
+like(f:read'*l', banner, "-i")
+if ujit then
+    like(f:read'*l', '^JIT:')
+end
+if ravi then
+    like(f:read'*l', '^Copyright %(C%)')
+    like(f:read'*l', '^Portions Copyright %(C%)')
+    like(f:read'*l', '^Options')
+end
+is(f:read'*l', 'Hello World')
+f:close()
+
+cmd = lua .. [[ -e"a=1" -e "print(a)"]]
+f = io.popen(cmd)
+is(f:read'*l', '1', "-e")
+f:close()
+
+cmd = lua .. [[ -e "error('msg')"  2>&1]]
+f = io.popen(cmd)
+is(f:read'*l', lua .. [[: (command line):1: msg]], "error")
+is(f:read'*l', "stack traceback:", "backtrace")
+f:close()
+
+cmd = lua .. [[ -e "error(setmetatable({}, {__tostring=function() return 'MSG' end}))"  2>&1]]
+f = io.popen(cmd)
+if has_error52 or jit then
+    is(f:read'*l', lua .. [[: MSG]], "error with object")
+else
+    is(f:read'*l', lua .. [[: (error object is not a string)]], "error with object")
+end
+if jit then
+    is(f:read'*l', "stack traceback:", "backtrace")
+else
+    is(f:read'*l', nil, "not backtrace")
+end
+f:close()
+
+cmd = lua .. [[ -e "error{}"  2>&1]]
+f = io.popen(cmd)
+if has_error53 then
+    is(f:read'l', lua .. [[: (error object is a table value)]], "error")
+    is(f:read'l', "stack traceback:", "backtrace")
+elseif has_error52 then
+    is(f:read'*l', lua .. [[: (no error message)]], "error")
+    is(f:read'*l', nil, "not backtrace")
+else
+    is(f:read'*l', lua .. [[: (error object is not a string)]], "error")
+    is(f:read'*l', nil, "not backtrace")
+end
+f:close()
+
+cmd = lua .. [[ -e"a=1" -e "print(a)" hello-241.lua]]
+f = io.popen(cmd)
+is(f:read'*l', '1', "-e & script")
+is(f:read'*l', 'Hello World')
+f:close()
+
+cmd = lua .. [[ -e"a=1" -i < hello-241.lua 2>&1]]
+f = io.popen(cmd)
+like(f:read'*l', banner, "-e & -i")
+f:close()
+
+cmd = lua .. [[ -e "?syntax error?" 2>&1]]
+f = io.popen(cmd)
+like(f:read'*l', "^.-%d: unexpected symbol near '%?'", "-e bad")
+f:close()
+
+cmd = lua .. [[ -e 2>&1]]
+f = io.popen(cmd)
+if _VERSION ~= 'Lua 5.1' then
+    like(f:read'*l', "^[^:]+: '%-e' needs argument", "no file")
+end
+like(f:read'*l', "^usage: ", "no file")
+f:close()
+
+cmd = lua .. [[ -v 2>&1]]
+f = io.popen(cmd)
+like(f:read'*l', banner, "-v")
+f:close()
+
+cmd = lua .. [[ -v hello-241.lua 2>&1]]
+f = io.popen(cmd)
+like(f:read'*l', banner, "-v & script")
+if ravi then
+    like(f:read'*l', '^Copyright %(C%)')
+    like(f:read'*l', '^Portions Copyright %(C%)')
+    like(f:read'*l', '^Options')
+end
+is(f:read'*l', 'Hello World')
+f:close()
+
+cmd = lua .. [[ -v -- 2>&1]]
+f = io.popen(cmd)
+like(f:read'*l', banner, "-v --")
+f:close()
+
+if has_opt_E then
+    cmd = lua .. [[ -E hello-241.lua 2>&1]]
+    f = io.popen(cmd)
+    is(f:read'*l', 'Hello World', "-E")
+    f:close()
+else
+    diag("no -E")
+end
+
+cmd = lua .. [[ -u 2>&1]]
+f = io.popen(cmd)
+if _VERSION ~= 'Lua 5.1' then
+    like(f:read'*l', "^[^:]+: unrecognized option '%-u'", "unknown option")
+end
+like(f:read'*l', "^usage: ", "no file")
+f:close()
+
+cmd = lua .. [[ --u 2>&1]]
+f = io.popen(cmd)
+if _VERSION ~= 'Lua 5.1' then
+    like(f:read'*l', "^[^:]+: unrecognized option '%-%-u'", "unknown option")
+end
+like(f:read'*l', "^usage: ", "no file")
+f:close()
+
+cmd = lua .. [[ -ltap -e "print(type(ok))"]]
+f = io.popen(cmd)
+is(f:read'*l', 'function', "-ltap")
+f:close()
+
+cmd = lua .. [[ -l tap -e "print(type(ok))"]]
+f = io.popen(cmd)
+is(f:read'*l', 'function', "-l tap")
+f:close()
+
+cmd = lua .. [[ -l lpeg -e "print(1)" 2>&1]]
+f = io.popen(cmd)
+isnt(f:read'*l', nil, "-l lpeg")
+f:close()
+
+cmd = lua .. [[ -l no_lib hello-241.lua 2>&1]]
+f = io.popen(cmd)
+like(f:read'*l', "^[^:]+: module 'no_lib' not found:", "-l no lib")
+f:close()
+
+if has_opt_W then
+    cmd = lua .. [[ -W -e "warn'foo'" 2>&1]]
+    f = io.popen(cmd)
+    is(f:read'*l', 'Lua warning: foo', "-W")
+    is(f:read'*l', nil)
+    f:close()
+else
+    diag("no -W")
+end
+
+os.remove('hello-241.lua') -- clean up
+done_testing()
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/242-luac.t b/test/lua-Harness-tests/242-luac.t
new file mode 100755
index 0000000..2d166e5
--- /dev/null
+++ b/test/lua-Harness-tests/242-luac.t
@@ -0,0 +1,341 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2010-2020, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua Stand-alone
+
+=head2 Synopsis
+
+    % prove t/242-luac.t
+
+=head2 Description
+
+See section "Lua Stand-alone" in "Reference Manual"
+L<https://www.lua.org/manual/5.1/manual.html#6>,
+L<https://www.lua.org/manual/5.2/manual.html#7>,
+L<https://www.lua.org/manual/5.3/manual.html#7>,
+L<https://www.lua.org/manual/5.4/manual.html#7>
+
+=cut
+
+--]]
+
+require'tap'
+
+if jit then
+    skip_all("LuaJIT")
+end
+
+if ravi then
+    skip_all("ravi")
+end
+
+local lua = arg[-3] or arg[-1]
+local luac = lua .. 'c'
+
+if not pcall(io.popen, lua .. [[ -e "a=1"]]) then
+    skip_all "io.popen not supported"
+end
+
+plan'no_plan'
+diag(luac)
+
+local signature = "\x1bLua"
+local bin_version
+if     _VERSION == 'Lua 5.1' then
+    bin_version = "\x51"
+elseif _VERSION == 'Lua 5.2' then
+    bin_version = "\x52"
+elseif _VERSION == 'Lua 5.3' then
+    bin_version = "\x53"
+elseif _VERSION == 'Lua 5.4' then
+    bin_version = "\x54"
+end
+local format = "\x00"
+local data = "\x19\x93\r\n\x1a\n"
+local size_i = string.char(string.packsize and string.packsize'i' or 0) -- int
+local size_T = string.char(string.packsize and string.packsize'T' or 0) -- size_t
+local size_I = string.char(string.packsize and string.packsize'I' or 0) -- Instruction
+local size_j = string.char(string.packsize and string.packsize'j' or 0) -- lua_Integer
+local size_n = string.char(string.packsize and string.packsize'n' or 0) -- lua_Number
+local sizes = size_i .. size_T .. size_I .. size_j .. size_n
+
+do -- hello.lua
+    local f = io.open('hello-242.lua', 'w')
+    f:write([[
+print 'Hello World'
+]])
+    f:close()
+end
+
+do -- luac -v
+    local cmd = luac .. [[ -v 2>&1]]
+    local f = io.popen(cmd)
+    like(f:read'*l', '^Lua', "-v")
+    f:close()
+end
+
+do -- luac -v --
+    local cmd = luac .. [[ -v -- 2>&1]]
+    local f = io.popen(cmd)
+    like(f:read'*l', '^Lua', "-v --")
+    f:close()
+end
+
+do -- luac -u
+    local cmd = luac .. [[ -u 2>&1]]
+    local f = io.popen(cmd)
+    like(f:read'*l', "^[^:]+: unrecognized option '%-u'", "unknown option")
+    like(f:read'*l', "^usage:")
+    f:close()
+end
+
+do -- luac --u
+    local cmd = luac .. [[ --u 2>&1]]
+    local f = io.popen(cmd)
+    like(f:read'*l', "^[^:]+: unrecognized option '%-%-u'", "unknown option")
+    like(f:read'*l', "^usage:")
+    f:close()
+end
+
+do -- luac -p hello-242.lua
+    local cmd = luac .. [[ -p hello-242.lua 2>&1]]
+    local f = io.popen(cmd)
+    is(f:read'*l', nil)
+    f:close()
+end
+
+do -- luac -p - < hello-242.lua
+    local cmd = luac .. [[ -p - < hello-242.lua 2>&1]]
+    local f = io.popen(cmd)
+    is(f:read'*l', nil)
+    f:close()
+end
+
+do -- luac -p no_file-242.lua
+    local cmd = luac .. [[ -p no_file-242.lua 2>&1]]
+    local f = io.popen(cmd)
+    like(f:read'*l', "^[^:]+: cannot open no_file%-242%.lua", "no file")
+    f:close()
+end
+
+do -- luac -o
+    local cmd = luac .. [[ -o 2>&1]]
+    local f = io.popen(cmd)
+    like(f:read'*l', "^[^:]+: '%-o' needs argument", "-o needs argument")
+    f:close()
+end
+
+do -- luac -v -l -l hello-242.lua
+    local cmd = luac .. [[ -v -l -l hello-242.lua]]
+    local f = io.popen(cmd)
+    like(f:read'*l', '^Lua', "-v -l -l")
+    is(f:read'*l', '')
+    like(f:read'*l', "^main")
+    f:close()
+end
+
+os.remove('hello-242.lua') -- clean up
+
+do -- luac -l luac.out
+    local cmd = luac .. [[ -l luac.out]]
+    local f = io.popen(cmd)
+    is(f:read'*l', '', "-l luac.out")
+    like(f:read'*l', "^main")
+    f:close()
+end
+
+do -- luac -l
+    local cmd = luac .. [[ -l]]
+    local f = io.popen(cmd)
+    is(f:read'*l', '', "-l")
+    like(f:read'*l', "^main")
+    f:close()
+end
+
+do -- luac -l - < luac.out
+    local cmd = luac .. [[ -l - < luac.out]]
+    local f = io.popen(cmd)
+    is(f:read'*l', '', "-l -")
+    like(f:read'*l', "^main")
+    f:close()
+end
+
+if _VERSION ~= 'Lua 5.1' then
+    local f = io.open('luac.out', 'w')
+    f:write(signature .. bin_version .. format)
+    f:close()
+    local cmd = luac .. [[ luac.out 2>&1]]
+    f = io.popen(cmd)
+    if _VERSION <= 'Lua 5.3' then
+        like(f:read'*l', "truncated precompiled chunk")
+    else
+        like(f:read'*l', "bad binary format %(truncated chunk%)")
+    end
+    f:close()
+end
+
+if _VERSION ~= 'Lua 5.1' then -- bad signature
+    local f = io.open('luac.out', 'w')
+    f:write("\x1bFoo" .. bin_version .. format .. data .. sizes .. "Foo")
+    f:close()
+    local cmd = luac .. [[ luac.out 2>&1]]
+    f = io.popen(cmd)
+    if _VERSION <= 'Lua 5.3' then
+        like(f:read'*l', "not a precompiled chunk", "bad signature")
+    else
+        like(f:read'*l', "bad binary format %(not a binary chunk%)", "bad signature")
+    end
+    f:close()
+end
+
+if _VERSION ~= 'Lua 5.1' then -- bad version
+    local f = io.open('luac.out', 'w')
+    f:write(signature .. "\x51" .. format .. data .. sizes .. "Foo")
+    f:close()
+    local cmd = luac .. [[ luac.out 2>&1]]
+    f = io.popen(cmd)
+    if _VERSION <= 'Lua 5.3' then
+        like(f:read'*l', "version mismatch in precompiled chunk", "bad version")
+    else
+        like(f:read'*l', "bad binary format %(version mismatch%)", "bad version")
+    end
+    f:close()
+end
+
+if _VERSION ~= 'Lua 5.1' then -- bad format
+    local f = io.open('luac.out', 'w')
+    f:write(signature .. bin_version .. "\x42" .. data .. sizes .. "Foo")
+    f:close()
+    local cmd = luac .. [[ luac.out 2>&1]]
+    f = io.popen(cmd)
+    if _VERSION == 'Lua 5.2' then
+        like(f:read'*l', "version mismatch in precompiled chunk", "bad format")
+    elseif _VERSION == 'Lua 5.3' then
+        like(f:read'*l', "format mismatch in precompiled chunk", "bad format")
+    else
+        like(f:read'*l', "bad binary format %(format mismatch%)", "bad format")
+    end
+    f:close()
+end
+
+if _VERSION == 'Lua 5.2' then -- bad sizes
+    local f = io.open('luac.out', 'w')
+    f:write(signature .. bin_version .. format .. "\xde\xad\xbe\xef\x00" .. data .. "Foo")
+    f:close()
+    local cmd = luac .. [[ luac.out 2>&1]]
+    f = io.popen(cmd)
+    like(f:read'*l', "incompatible precompiled chunk", "incompatible 5.2")
+    f:close()
+end
+
+if _VERSION == 'Lua 5.2' then -- bad data / tail
+    sizes = string.dump(load "a = 1"):sub(7, 12)
+    local f = io.open('luac.out', 'w')
+    f:write(signature .. bin_version .. format .. sizes .. "\x19\x99\r\n\x1a\n")
+    f:close()
+    local cmd = luac .. [[ luac.out 2>&1]]
+    f = io.popen(cmd)
+    like(f:read'*l', "corrupted precompiled chunk", "corrupted 5.2")
+    f:close()
+end
+
+if _VERSION == 'Lua 5.3' then -- bad data
+    local f = io.open('luac.out', 'w')
+    f:write(signature .. bin_version .. format .. "\x19\x99\r\n\x1a\n" .. sizes)
+    f:close()
+    local cmd = luac .. [[ luac.out 2>&1]]
+    f = io.popen(cmd)
+    like(f:read'*l', "corrupted precompiled chunk", "corrupted")
+    f:close()
+end
+
+if _VERSION == 'Lua 5.3' then -- bad sizes
+    local f = io.open('luac.out', 'w')
+    f:write(signature .. bin_version .. format .. data .. "\xde\xad\xbe\xef\x00")
+    f:close()
+    local cmd = luac .. [[ luac.out 2>&1]]
+    f = io.popen(cmd)
+    like(f:read'*l', "int size mismatch in precompiled chunk", "bad sizes")
+    f:close()
+end
+
+if _VERSION == 'Lua 5.3' then -- bad endianess
+    local f = io.open('luac.out', 'w')
+    f:write(signature .. bin_version .. format .. data .. sizes .. "\0\0\0\0\0\0\0\0")
+    f:close()
+    local cmd = luac .. [[ luac.out 2>&1]]
+    f = io.popen(cmd)
+    like(f:read'*l', "endianness mismatch in precompiled chunk", "bad endian")
+    f:close()
+end
+
+if _VERSION == 'Lua 5.3' then -- bad float format
+    local endian = string.dump(load "a = 1"):sub(18, 18 + string.packsize'n')
+    local f = io.open('luac.out', 'w')
+    f:write(signature .. bin_version .. format .. data .. sizes .. endian .. "\0\0\0\0\0\0\0\0")
+    f:close()
+    local cmd = luac .. [[ luac.out 2>&1]]
+    f = io.popen(cmd)
+    like(f:read'*l', "float format mismatch in precompiled chunk")
+    f:close()
+end
+
+do -- cover.lua
+    local f = io.open('cover-242.lua', 'w')
+    f:write([[
+local a = false
+b = a + 1
+pi = 3.14
+s = "all escaped \1\a\b\f\n\r\t\v\\\""
+local t = { "a", "b", "c", "d", [true] = 1 }
+local f = table.concat
+local function f ()
+    while true do
+        print(a)
+    end
+end
+local function g (...) -- segfault with Lua 5.4.0-beta
+    return {...}
+end
+s = nil
+]])
+    f:close()
+
+    local cmd = luac .. [[ -o cover-242.out cover-242.lua 2>&1]]
+    f = io.popen(cmd)
+    is(f:read'*l', nil, "-o cover-242.out cover-242.lua")
+    f:close()
+
+    cmd = luac .. [[ -l cover-242.out]]
+    f = io.popen(cmd)
+    is(f:read'*l', '', "-l cover-242.out")
+    like(f:read'*l', "^main")
+    f:close()
+
+    cmd = luac .. [[ -l -l cover-242.out]]
+    f = io.popen(cmd)
+    is(f:read'*l', '', "-l -l cover-242.out")
+    like(f:read'*l', "^main")
+    f:close()
+end
+
+os.remove('luac.out') -- clean up
+os.remove('cover-242.lua') -- clean up
+os.remove('cover-242.out') -- clean up
+done_testing()
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/301-basic.t b/test/lua-Harness-tests/301-basic.t
new file mode 100755
index 0000000..e45599e
--- /dev/null
+++ b/test/lua-Harness-tests/301-basic.t
@@ -0,0 +1,856 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2020, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua Basic Library
+
+=head2 Synopsis
+
+    % prove 301-basic.t
+
+=head2 Description
+
+Tests Lua Basic Library
+
+See section "Basic Functions" in "Reference Manual"
+L<https://www.lua.org/manual/5.1/manual.html#5.1>,
+L<https://www.lua.org/manual/5.2/manual.html#6.1>,
+L<https://www.lua.org/manual/5.3/manual.html#6.1>,
+L<https://www.lua.org/manual/5.4/manual.html#6.1>
+
+=cut
+
+--]]
+
+require'tap'
+local profile = require'profile'
+local has_error53 = _VERSION >= 'Lua 5.3'
+local has_gcinfo = _VERSION == 'Lua 5.1'
+local has_getfenv = _VERSION == 'Lua 5.1'
+local has_ipairs53 = _VERSION >= 'Lua 5.3'
+local has_load52 = _VERSION >= 'Lua 5.2' or profile.luajit_compat52
+local has_loadfile52 = _VERSION >= 'Lua 5.2' or profile.luajit_compat52
+local has_loadstring = _VERSION == 'Lua 5.1'
+local has_alias_loadstring = profile.compat51
+local has_newproxy = _VERSION == 'Lua 5.1'
+local has_rawlen = _VERSION >= 'Lua 5.2' or profile.luajit_compat52
+local has_unpack = _VERSION == 'Lua 5.1'
+local has_alias_unpack = profile.compat51
+local has_warn = _VERSION >= 'Lua 5.4'
+local has_xpcall52 = _VERSION >= 'Lua 5.2' or jit
+local has_xpcall53 = _VERSION >= 'Lua 5.3' or jit
+
+local lua = arg[-3] or arg[-1]
+
+plan'no_plan'
+
+do -- assert
+    local v, msg = assert('text', "assert string")
+    is(v, 'text', "function assert")
+    is(msg, "assert string")
+    v, msg = assert({}, "assert table")
+    is(msg, "assert table")
+
+    error_like(function () assert(false, "ASSERTION TEST") end,
+               "^[^:]+:%d+: ASSERTION TEST",
+               "function assert(false, msg)")
+
+    error_like(function () assert(false) end,
+               "^[^:]+:%d+: assertion failed!",
+               "function assert(false)")
+
+    if has_error53 then
+        v, msg = pcall(function() assert(false, 42) end)
+        is(msg, 42, "function assert(false, 42)")
+    else
+        error_like(function () assert(false, 42) end,
+                   "^[^:]+:%d+: 42",
+                   "function assert(false, 42)")
+    end
+
+    if has_error53 then
+        local obj = {}
+        v, msg = pcall(function() assert(false, obj) end)
+        is(msg, obj, "function assert(false, {})")
+    else
+        diag("no assert with table")
+    end
+end
+
+-- collectgarbage
+if jit then
+    is(collectgarbage('stop'), 0, "function collectgarbage 'stop/restart/collect'")
+    is(collectgarbage('step'), false)
+    is(collectgarbage('restart'), 0)
+    is(collectgarbage('step'), false)
+    is(collectgarbage('collect'), 0)
+    is(collectgarbage('setpause', 10), 200)
+    is(collectgarbage('setstepmul', 200), 200)
+    is(collectgarbage(), 0)
+elseif _VERSION == 'Lua 5.1' then
+    is(collectgarbage('stop'), 0, "function collectgarbage 'stop/restart/collect'")
+    is(collectgarbage('restart'), 0)
+    is(collectgarbage('step'), false)
+    is(collectgarbage('collect'), 0)
+    is(collectgarbage(), 0)
+elseif _VERSION == 'Lua 5.2' then
+    is(collectgarbage('stop'), 0, "function collectgarbage 'stop/restart/collect'")
+    is(collectgarbage('isrunning'), false)
+    is(collectgarbage('step'), false)
+    is(collectgarbage('restart'), 0)
+    is(collectgarbage('isrunning'), true)
+    is(collectgarbage('step'), false)
+    is(collectgarbage('collect'), 0)
+    is(collectgarbage('setpause', 10), 200)
+    is(collectgarbage('setstepmul', 200), 200)
+    is(collectgarbage(), 0)
+    is(collectgarbage('generational'), 0)
+    is(collectgarbage('step'), false)
+    is(collectgarbage('incremental'), 0)
+    is(collectgarbage('setmajorinc'), 200)
+elseif _VERSION == 'Lua 5.3' then
+    is(collectgarbage('stop'), 0, "function collectgarbage 'stop/restart/collect'")
+    is(collectgarbage('isrunning'), false)
+    --is(collectgarbage('step'), false)
+    type_ok(collectgarbage('step'), 'boolean')
+    is(collectgarbage('restart'), 0)
+    is(collectgarbage('isrunning'), true)
+    is(collectgarbage('step'), false)
+    is(collectgarbage('collect'), 0)
+    is(collectgarbage('setpause', 10), 200)
+    is(collectgarbage('setstepmul', 200), 200)
+    is(collectgarbage(), 0)
+    is(collectgarbage('step'), false)
+elseif _VERSION == 'Lua 5.4' then
+    is(collectgarbage('stop'), 0, "function collectgarbage 'stop/restart/collect'")
+    is(collectgarbage('isrunning'), false)
+    is(collectgarbage('generational'), 'generational')
+    is(collectgarbage('incremental'), 'generational')
+    is(collectgarbage('incremental'), 'incremental')
+    is(collectgarbage('generational'), 'incremental')
+    is(collectgarbage('step'), false)
+    is(collectgarbage('restart'), 0)
+    is(collectgarbage('isrunning'), true)
+    is(collectgarbage('step'), false)
+    is(collectgarbage('collect'), 0)
+    is(collectgarbage('setpause', 10), 200)
+    is(collectgarbage('setstepmul', 200), 100)
+    is(collectgarbage(), 0)
+    is(collectgarbage('step'), false)
+end
+
+type_ok(collectgarbage('count'), 'number', "function collectgarbage 'count'")
+
+error_like(function () collectgarbage('unknown') end,
+           "^[^:]+:%d+: bad argument #1 to 'collectgarbage' %(invalid option 'unknown'%)",
+           "function collectgarbage (invalid)")
+
+do -- dofile
+    local f = io.open('lib-301.lua', 'w')
+    f:write[[
+function norm (x, y)
+    return (x^2 + y^2)^0.5
+end
+
+function twice (x)
+    return 2*x
+end
+]]
+    f:close()
+    dofile('lib-301.lua')
+    local n = norm(3.4, 1.0)
+    like(twice(n), '^7%.088', "function dofile")
+
+    os.remove('lib-301.lua') -- clean up
+
+    error_like(function () dofile('no_file-301.lua') end,
+               "cannot open no_file%-301%.lua: No such file or directory",
+               "function dofile (no file)")
+
+    f = io.open('foo-301.lua', 'w')
+    f:write[[?syntax error?]]
+    f:close()
+    error_like(function () dofile('foo-301.lua') end,
+               "^foo%-301%.lua:%d+:",
+               "function dofile (syntax error)")
+
+    os.remove('foo-301.lua') -- clean up
+end
+
+do -- error
+    error_like(function () error("ERROR TEST") end,
+               "^[^:]+:%d+: ERROR TEST",
+               "function error(msg)")
+
+    error_is(function () error("ERROR TEST", 0) end,
+             "ERROR TEST",
+             "function error(msg, 0)")
+
+    if has_error53 then
+        local v, msg = pcall(function() error(42) end)
+        is(msg, 42, "function error(42)")
+    else
+        error_like(function () error(42) end,
+                   "^[^:]+:%d+: 42",
+                   "function error(42)")
+    end
+
+    local obj = {}
+    local v, msg = pcall(function() error(obj) end)
+    is(msg, obj, "function error({})")
+
+    v, msg = pcall(function() error() end)
+    is(msg, nil, "function error()")
+end
+
+-- gcinfo
+if has_gcinfo then
+    type_ok(gcinfo(), 'number', "function gcinfo")
+else
+    is(gcinfo, nil, "no gcinfo (removed)")
+end
+
+-- getfenv
+if has_getfenv then
+    type_ok(getfenv(0), 'table', "function getfenv")
+    is(getfenv(0), _G)
+    is(getfenv(1), _G)
+    is(getfenv(), _G)
+    local function f () end
+    type_ok(getfenv(f), 'table')
+    is(getfenv(f), _G)
+    type_ok(getfenv(print), 'table')
+    is(getfenv(print), _G)
+
+    error_like(function () getfenv(-3) end,
+               "^[^:]+:%d+: bad argument #1 to 'getfenv' %(.-level.-%)",
+              "function getfenv (negative)")
+
+    error_like(function () getfenv(12) end,
+               "^[^:]+:%d+: bad argument #1 to 'getfenv' %(invalid level%)",
+               "function getfenv (too depth)")
+else
+    is(getfenv, nil, "no getfenv")
+end
+
+do -- getmetatable
+    is(getmetatable(true), nil, "boolean has no metatable by default")
+    is(getmetatable(getmetatable), nil, "function has no metatable by default")
+    is(getmetatable(nil), nil, "nil has no metatable by default")
+    is(getmetatable(3.14), nil, "number has no metatable by default")
+    is(getmetatable({}), nil, "table has no metatable by default")
+    local co = coroutine.create(function () return 1 end)
+    is(getmetatable(co), nil, "thread has no metatable by default")
+
+    type_ok(getmetatable('ABC'), 'table', "string has a metatable")
+    is(getmetatable('ABC'), getmetatable('abc'), "string has a shared metatable")
+end
+
+do -- ipairs
+    local a = {'a','b','c'}
+    if has_ipairs53 then
+        a = setmetatable({
+            [1] = 'a',
+            [3] = 'c',
+        }, {
+            __index = {
+               [2] = 'b',
+            }
+        })
+    end
+    local f, v, s = ipairs(a)
+    type_ok(f, 'function', "function ipairs")
+    type_ok(v, 'table')
+    is(s, 0)
+    s, v = f(a, s)
+    is(s, 1)
+    is(v, 'a')
+    s, v = f(a, s)
+    is(s, 2)
+    is(v, 'b')
+    s, v = f(a, s)
+    is(s, 3)
+    is(v, 'c')
+    s, v = f(a, s)
+    is(s, nil)
+    is(v, nil)
+end
+
+do -- load
+    local t = { [[
+function bar (x)
+    return x
+end
+]] }
+    local i = 0
+    local function reader ()
+        i = i + 1
+        return t[i]
+    end
+    local f, msg = load(reader)
+    if msg then
+        diag(msg)
+    end
+    type_ok(f, 'function', "function load(reader)")
+    is(bar, nil)
+    f()
+    is(bar('ok'), 'ok')
+    bar = nil
+
+    t = { [[
+function baz (x)
+    return x
+end
+]] }
+    i = -1
+    function reader ()
+        i = i + 1
+        return t[i]
+    end
+    f, msg = load(reader)
+    if msg then
+        diag(msg)
+    end
+    type_ok(f, 'function', "function load(pathological reader)")
+    f()
+    if _VERSION == 'Lua 5.1' and not jit then
+        todo("not with 5.1")
+    end
+    is(baz, nil)
+
+    t = { [[?syntax error?]] }
+    i = 0
+    f, msg = load(reader, "errorchunk")
+    is(f, nil, "function load(syntax error)")
+    like(msg, "^%[string \"errorchunk\"%]:%d+:")
+
+    f = load(function () return nil end)
+    type_ok(f, 'function', "when reader returns nothing")
+
+    f, msg = load(function () return {} end)
+    is(f, nil, "reader function must return a string")
+    like(msg, "reader function must return a string")
+
+    if has_load52 then
+        f = load([[
+function bar (x)
+    return x
+end
+]])
+        is(bar, nil, "function load(str)")
+        f()
+        is(bar('ok'), 'ok')
+        bar = nil
+
+        local env = {}
+        f = load([[
+function bar (x)
+    return x
+end
+]], "from string", 't', env)
+        is(env.bar, nil, "function load(str)")
+        f()
+        is(env.bar('ok'), 'ok')
+
+        f, msg = load([[?syntax error?]], "errorchunk")
+        is(f, nil, "function load(syntax error)")
+        like(msg, "^%[string \"errorchunk\"%]:%d+:")
+
+        f, msg = load([[print 'ok']], "chunk txt", 'b')
+        like(msg, "attempt to load")
+        is(f, nil, "mode")
+
+        f, msg = load("\x1bLua", "chunk bin", 't')
+        like(msg, "attempt to load")
+        is(f, nil, "mode")
+    else
+       diag("no load with string")
+    end
+end
+
+do -- loadfile
+    local f = io.open('foo-301.lua', 'w')
+    if _VERSION ~= 'Lua 5.1' or jit then
+        f:write'\xEF\xBB\xBF' -- BOM
+    end
+    f:write[[
+function foo (x)
+    return x
+end
+]]
+    f:close()
+    f = loadfile('foo-301.lua')
+    is(foo, nil, "function loadfile")
+    f()
+    is(foo('ok'), 'ok')
+
+    if has_loadfile52 then
+        local msg
+        f, msg = loadfile('foo-301.lua', 'b')
+        like(msg, "attempt to load")
+        is(f, nil, "mode")
+
+        local env = {}
+        f = loadfile('foo-301.lua', 't', env)
+        is(env.foo, nil, "function loadfile")
+        f()
+        is(env.foo('ok'), 'ok')
+    else
+        diag("no loadfile with mode & env")
+    end
+
+    os.remove('foo-301.lua') -- clean up
+
+    local msg
+    f, msg = loadfile('no_file-301.lua')
+    is(f, nil, "function loadfile (no file)")
+    is(msg, "cannot open no_file-301.lua: No such file or directory")
+
+    f = io.open('foo-301.lua', 'w')
+    f:write[[?syntax error?]]
+    f:close()
+    f, msg = loadfile('foo-301.lua')
+    is(f, nil, "function loadfile (syntax error)")
+    like(msg, '^foo%-301%.lua:%d+:')
+    os.remove('foo-301.lua') -- clean up
+end
+
+-- loadstring
+if has_loadstring then
+    local f = loadstring([[i = i + 1]])
+    i = 0
+    f()
+    is(i, 1, "function loadstring")
+    f()
+    is(i, 2)
+
+    i = 32
+    local i = 0
+    f = loadstring([[i = i + 1; return i]])
+    local g = function () i = i + 1; return i end
+    is(f(), 33, "function loadstring")
+    is(g(), 1)
+
+    local msg
+    f, msg = loadstring([[?syntax error?]])
+    is(f, nil, "function loadstring (syntax error)")
+    like(msg, '^%[string "%?syntax error%?"%]:%d+:')
+elseif has_alias_loadstring then
+    is(loadstring, load, "alias loadstring")
+else
+    is(loadstring, nil, "no loadstring")
+end
+
+-- newproxy
+if has_newproxy then
+    local proxy = newproxy(false)
+    type_ok(proxy, 'userdata', "function newproxy(false)")
+    is(getmetatable(proxy), nil, "without metatable")
+    proxy = newproxy(true)
+    type_ok(proxy, 'userdata', "function newproxy(true)")
+    type_ok(getmetatable(proxy), 'table', "with metatable")
+
+    local proxy2 = newproxy(proxy)
+    type_ok(proxy, 'userdata', "function newproxy(proxy)")
+    is(getmetatable(proxy2), getmetatable(proxy))
+
+    error_like(function () newproxy({}) end,
+               "^[^:]+:%d+: bad argument #1 to 'newproxy' %(boolean or proxy expected%)",
+               "function newproxy({})")
+else
+    is(newproxy, nil, "no newproxy")
+end
+
+do -- next
+    local t = {'a','b','c'}
+    local a = next(t, nil)
+    is(a, 1, "function next (array)")
+    a = next(t, 1)
+    is(a, 2)
+    a = next(t, 2)
+    is(a, 3)
+    a = next(t, 3)
+    is(a, nil)
+
+    error_like(function () a = next() end,
+               "^[^:]+:%d+: bad argument #1 to 'next' %(table expected, got no value%)",
+               "function next (no arg)")
+
+    error_like(function () a = next(t, 6) end,
+               "invalid key to 'next'",
+               "function next (invalid key)")
+
+    t = {'a','b','c'}
+    a = next(t, 2)
+    is(a, 3, "function next (unorderer)")
+    a = next(t, 1)
+    is(a, 2)
+    a = next(t, 3)
+    is(a, nil)
+
+    t = {}
+    a = next(t, nil)
+    is(a, nil, "function next (empty table)")
+end
+
+do -- pairs
+    local a = {'a','b','c'}
+    local f, v, s = pairs(a)
+    type_ok(f, 'function', "function pairs")
+    type_ok(v, 'table')
+    is(s, nil)
+    s = f(v, s)
+    is(s, 1)
+    s = f(v, s)
+    is(s, 2)
+    s = f(v, s)
+    is(s, 3)
+    s = f(v, s)
+    is(s, nil)
+end
+
+do -- pcall
+    local status, result = pcall(assert, 1)
+    is(status, true, "function pcall")
+    is(result, 1)
+    status, result = pcall(assert, false, 'catched')
+    is(status, false)
+    is(result, 'catched')
+    status = pcall(assert)
+    is(status, false)
+end
+
+do -- rawequal
+    local t = {}
+    local a = t
+    is(rawequal(nil, nil), true, "function rawequal -> true")
+    is(rawequal(false, false), true)
+    is(rawequal(3, 3), true)
+    is(rawequal('text', 'text'), true)
+    is(rawequal(t, a), true)
+    is(rawequal(print, print), true)
+
+    is(rawequal(nil, 2), false, "function rawequal -> false")
+    is(rawequal(false, true), false)
+    is(rawequal(false, 2), false)
+    is(rawequal(3, 2), false)
+    is(rawequal(3, '2'), false)
+    is(rawequal('text', '2'), false)
+    is(rawequal('text', 2), false)
+    is(rawequal(t, {}), false)
+    is(rawequal(t, 2), false)
+    is(rawequal(print, type), false)
+    is(rawequal(print, 2), false)
+end
+
+-- rawlen
+if has_rawlen then
+    is(rawlen("text"), 4, "function rawlen (string)")
+    is(rawlen({ 'a', 'b', 'c'}), 3, "function rawlen (table)")
+    error_like(function () local a = rawlen(true) end,
+               "^[^:]+:%d+: bad argument #1 to 'rawlen' %(table ",
+               "function rawlen (bad arg)")
+else
+    is(rawlen, nil, "no rawlen")
+end
+
+do -- rawget
+    local t = {a = 'letter a', b = 'letter b'}
+    is(rawget(t, 'a'), 'letter a', "function rawget")
+end
+
+do -- rawset
+    local t = {}
+    is(rawset(t, 'a', 'letter a'), t, "function rawset")
+    is(t.a, 'letter a')
+
+    error_like(function () t = {}; rawset(t, nil, 42) end,
+               "^table index is nil",
+               "function rawset (table index is nil)")
+end
+
+do -- select
+    is(select('#'), 0, "function select")
+    is(select('#','a','b','c'), 3)
+    eq_array({select(1,'a','b','c')}, {'a','b','c'})
+    eq_array({select(3,'a','b','c')}, {'c'})
+    eq_array({select(5,'a','b','c')}, {})
+    eq_array({select(-1,'a','b','c')}, {'c'})
+    eq_array({select(-2,'a','b','c')}, {'b', 'c'})
+    eq_array({select(-3,'a','b','c')}, {'a', 'b', 'c'})
+
+    error_like(function () select(0,'a','b','c') end,
+               "^[^:]+:%d+: bad argument #1 to 'select' %(index out of range%)",
+               "function select (out of range)")
+
+    error_like(function () select(-4,'a','b','c') end,
+               "^[^:]+:%d+: bad argument #1 to 'select' %(index out of range%)",
+               "function select (out of range)")
+end
+
+-- setfenv
+if has_getfenv then
+    local t = {}
+    local function f () end
+    is(setfenv(f, t), f, "function setfenv")
+    type_ok(getfenv(f), 'table')
+    is(getfenv(f), t)
+
+    save = getfenv(1)
+    a = 1
+    setfenv(1, {g = _G})
+    g.is(a, nil, "function setfenv")
+    g.is(g.a, 1)
+    g.setfenv(1, g.save) -- restore
+
+    save = getfenv(1)
+    a = 1
+    local newgt = {}        -- create new environment
+    setmetatable(newgt, {__index = _G})
+    setfenv(1, newgt)       -- set it
+    is(a, 1, "function setfenv")
+    a = 10
+    is(a, 10)
+    is(_G.a, 1)
+    _G.a = 20
+    is(_G.a, 20)
+    setfenv(1, save) -- restore
+
+    save = getfenv(1)
+    local function factory ()
+        return function ()
+                   return a    -- "global" a
+               end
+    end
+    a = 3
+    local f1 = factory()
+    local f2 = factory()
+    is(f1(), 3, "function setfenv")
+    is(f2(), 3)
+    setfenv(f1, {a = 10})
+    is(f1(), 10)
+    is(f2(), 3)
+    setfenv(1, save) -- restore
+
+    is(setfenv(0, _G), nil, "function setfenv(0)")
+
+    error_like(function () setfenv(-3, {}) end,
+               "^[^:]+:%d+: bad argument #1 to 'setfenv' %(.-level.-%)",
+               "function setfenv (negative)")
+
+    error_like(function () setfenv(12, {}) end,
+               "^[^:]+:%d+: bad argument #1 to 'setfenv' %(invalid level%)",
+               "function setfenv (too depth)")
+
+    t = {}
+    error_like(function () setfenv(t, {}) end,
+               "^[^:]+:%d+: bad argument #1 to 'setfenv' %(number expected, got table%)",
+               "function setfenv (bad arg)")
+
+    error_like(function () setfenv(print, {}) end,
+               "^[^:]+:%d+: 'setfenv' cannot change environment of given object",
+               "function setfenv (forbidden)")
+else
+    is(setfenv, nil, "no setfenv")
+end
+
+do -- setmetatable
+    local mt = {}
+    local t = {}
+    is(t, setmetatable(t, mt), "setmetatable")
+    is(getmetatable(t), mt)
+    is(t, setmetatable(t, nil))
+    is(getmetatable(t), nil)
+
+    error_like(function () setmetatable(t, true) end,
+               "^[^:]+:%d+: bad argument #2 to 'setmetatable' %(nil or table expected",
+               "function setmetatable (bad arg)")
+    error_like(function () setmetatable(true, mt) end,
+               "^[^:]+:%d+: bad argument #1 to 'setmetatable' %(table expected, got boolean%)",
+               "function setmetatable (bad arg)")
+end
+
+do -- type
+    is(type("Hello world"), 'string', "function type")
+    is(type(10.4*3), 'number')
+    is(type(print), 'function')
+    is(type(type), 'function')
+    is(type(true), 'boolean')
+    is(type(nil), 'nil')
+    is(type(io.stdin), 'userdata')
+    is(type(type(X)), 'string')
+
+    local a = nil
+    is(type(a), 'nil', "function type")
+    a = 10
+    is(type(a), 'number')
+    a = "a string!!"
+    is(type(a), 'string')
+    a = print
+    is(type(a), 'function')
+    is(type(function () end), 'function')
+
+    error_like(function () type() end,
+               "^[^:]+:%d+: bad argument #1 to 'type' %(value expected%)",
+               "function type (no arg)")
+end
+
+do -- tonumber
+    is(tonumber('text12'), nil, "function tonumber")
+    is(tonumber('12text'), nil)
+    is(tonumber(3.14), 3.14)
+    is(tonumber('3.14'), 3.14)
+    is(tonumber('  3.14  '), 3.14)
+    is(tonumber(tostring(111), 2), 7)
+    is(tonumber('111', 2), 7)
+    is(tonumber('  111  ', 2), 7)
+    local a = {}
+    is(tonumber(a), nil)
+
+    error_like(function () tonumber() end,
+               "^[^:]+:%d+: bad argument #1 to 'tonumber' %(value expected%)",
+               "function tonumber (no arg)")
+
+    error_like(function () tonumber('111', 200) end,
+               "^[^:]+:%d+: bad argument #2 to 'tonumber' %(base out of range%)",
+               "function tonumber (bad base)")
+end
+
+do -- tostring
+    is(tostring('text'), 'text', "function tostring")
+    is(tostring(3.14), '3.14')
+    is(tostring(nil), 'nil')
+    is(tostring(true), 'true')
+    is(tostring(false), 'false')
+    like(tostring({}), '^table: 0?[Xx]?%x+$')
+    like(tostring(print), '^function: 0?[Xx]?[builtin]*#?%x+$')
+
+    error_like(function () tostring() end,
+               "^[^:]+:%d+: bad argument #1 to 'tostring' %(value expected%)",
+               "function tostring (no arg)")
+end
+
+-- unpack
+if has_unpack then
+    eq_array({unpack({})}, {}, "function unpack")
+    eq_array({unpack({'a'})}, {'a'})
+    eq_array({unpack({'a','b','c'})}, {'a','b','c'})
+    eq_array({(unpack({'a','b','c'}))}, {'a'})
+    eq_array({unpack({'a','b','c','d','e'},2,4)}, {'b','c','d'})
+    eq_array({unpack({'a','b','c'},2,4)}, {'b','c'})
+elseif has_alias_unpack then
+    is(unpack, table.unpack, "alias unpack")
+else
+    is(unpack, nil, "no unpack")
+end
+
+-- warn
+if has_warn then
+    is(warn('foo'), nil, "function warn")
+
+    local r, f = pcall(io.popen, lua .. [[ -W -e "warn'foo'" 2>&1]])
+    if r then
+        is(f:read'*l', 'Lua warning: foo', "warn called with popen")
+        is(f:read'*l', nil)
+        is(f:close(), true)
+    else
+        diag("io.popen not supported")
+    end
+
+    r, f = pcall(io.popen, lua .. [[ -e "warn'@on'; warn'foo'" 2>&1]])
+    if r then
+        is(f:read'*l', 'Lua warning: foo', "warn called with popen")
+        is(f:read'*l', nil)
+        is(f:close(), true)
+    else
+        diag("io.popen not supported")
+    end
+
+    r, f = pcall(io.popen, lua .. [[ -e "warn'@on'; warn('foo', 'bar')" 2>&1]])
+    if r then
+        is(f:read'*l', 'Lua warning: foobar', "warn called with popen")
+        is(f:read'*l', nil)
+        is(f:close(), true)
+    else
+        diag("io.popen not supported")
+    end
+
+    error_like(function () warn('foo', warn) end,
+               "^[^:]+:%d+: bad argument #2 to 'warn' %(string expected, got function%)",
+               "function warn (no arg)")
+
+    error_like(function () warn() end,
+               "^[^:]+:%d+: bad argument #1 to 'warn' %(string expected, got no value%)",
+               "function warn (no arg)")
+else
+    is(warn, nil, "no warn")
+end
+
+do -- xpcall
+    local function err (obj)
+        return obj
+    end
+
+    local function backtrace ()
+        return 'not a back trace'
+    end
+
+    local status, result = xpcall(function () return assert(1) end, err)
+    is(status, true, "function xpcall")
+    is(result, 1)
+    status, result = xpcall(function () return assert(false, 'catched') end, err)
+    is(status, false)
+    if jit then
+        is(result, 'catched')
+    else
+        like(result, ':%d+: catched')
+    end
+    status, result = xpcall(function () return assert(false, 'catched') end, backtrace)
+    is(status, false)
+    is(result, 'not a back trace')
+
+    if has_xpcall52 then
+        status, result = xpcall(assert, err, 1)
+        is(status, true, "function xpcall with args")
+        is(result, 1)
+        status, result = xpcall(assert, err, false, 'catched')
+        is(status, false)
+        is(result, 'catched')
+        status, result = xpcall(assert, backtrace, false, 'catched')
+        is(status, false)
+        is(result, 'not a back trace')
+    end
+
+    error_like(function () xpcall(assert) end,
+               "bad argument #2 to 'xpcall' %(.-",
+               "function xpcall")
+
+    if has_xpcall53 then
+        error_like(function () xpcall(assert, 1) end,
+                   "bad argument #2 to 'xpcall' %(function expected, got number%)",
+                  "function xpcall")
+    else
+        is(xpcall(assert, nil), false, "function xpcall")
+    end
+end
+
+if jit and pcall(require, 'ffi') then
+    dofile'lexicojit/basic.t'
+end
+
+done_testing()
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/303-package.t b/test/lua-Harness-tests/303-package.t
new file mode 100755
index 0000000..7e5216d
--- /dev/null
+++ b/test/lua-Harness-tests/303-package.t
@@ -0,0 +1,290 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2020, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua Package Library
+
+=head2 Synopsis
+
+    % prove 303-package.t
+
+=head2 Description
+
+Tests Lua Package Library
+
+See section "Modules" in "Reference Manual"
+L<https://www.lua.org/manual/5.1/manual.html#5.3>,
+L<https://www.lua.org/manual/5.2/manual.html#6.3>,
+L<https://www.lua.org/manual/5.3/manual.html#6.3>,
+L<https://www.lua.org/manual/5.4/manual.html#6.3>
+
+=cut
+
+--]]
+
+require'tap'
+local profile = require'profile'
+local luajit21 = jit and (jit.version_num >= 20100 or jit.version:match'^RaptorJIT')
+local has_loaders = _VERSION == 'Lua 5.1'
+local has_alias_loaders = profile.compat51
+local has_loadlib52 = _VERSION >= 'Lua 5.2' or jit
+local has_module = _VERSION == 'Lua 5.1' or profile.compat51
+local has_searchers = _VERSION >= 'Lua 5.2'
+local has_alias_searchers = luajit21 and profile.luajit_compat52
+local has_searcherpath = _VERSION >= 'Lua 5.2' or jit
+local has_require54 = _VERSION >= 'Lua 5.4'
+
+plan'no_plan'
+
+
+type_ok(package.config, 'string')
+
+type_ok(package.cpath, 'string')
+
+type_ok(package.path, 'string')
+
+if has_loaders then
+    type_ok(package.loaders, 'table', "table package.loaders")
+elseif has_alias_loaders then
+    is(package.loaders, package.searchers, "alias package.loaders")
+else
+    is(package.loaders, nil, "no package.loaders")
+end
+
+if has_searchers then
+    type_ok(package.searchers, 'table', "table package.searchers")
+elseif has_alias_searchers then
+    is(package.searchers, package.loaders, "alias package.searchers")
+else
+    is(package.searchers, nil, "no package.searchers")
+end
+
+do -- loaded
+    ok(package.loaded._G, "table package.loaded")
+    ok(package.loaded.coroutine)
+    ok(package.loaded.io)
+    ok(package.loaded.math)
+    ok(package.loaded.os)
+    ok(package.loaded.package)
+    ok(package.loaded.string)
+    ok(package.loaded.table)
+
+    local m = require'os'
+    is(m, package.loaded['os'])
+end
+
+do -- preload
+    type_ok(package.preload, 'table', "table package.preload")
+    is(# package.preload, 0)
+
+    local foo = {}
+    foo.bar = 1234
+    local function foo_loader ()
+       return foo
+    end
+    package.preload.foo = foo_loader
+    local m = require 'foo'
+    assert(m == foo)
+    is(m.bar, 1234, "function require & package.preload")
+end
+
+do -- loadlib
+    local path_lpeg = package.searchpath and package.searchpath('lpeg', package.cpath)
+
+    local f, msg = package.loadlib('libbar', 'baz')
+    is(f, nil, "loadlib")
+    type_ok(msg, 'string')
+
+    if path_lpeg then
+        f, msg = package.loadlib(path_lpeg, 'baz')
+        is(f, nil, "loadlib")
+        like(msg, 'undefined symbol')
+
+        f = package.loadlib(path_lpeg, 'luaopen_lpeg')
+        type_ok(f, 'function', "loadlib ok")
+    else
+        skip("no lpeg path")
+    end
+
+    if has_loadlib52 then
+        f, msg = package.loadlib('libbar', '*')
+        is(f, nil, "loadlib '*'")
+        type_ok(msg, 'string')
+
+        if path_lpeg then
+            f = package.loadlib(path_lpeg, '*')
+            is(f, true, "loadlib '*'")
+        else
+            skip("no lpeg path")
+        end
+    end
+end
+
+-- searchpath
+if has_searcherpath then
+    local p = package.searchpath('tap', package.path)
+    type_ok(p, 'string', "searchpath")
+    p = package.searchpath('tap', 'bad path')
+    is(p, nil)
+else
+    is(package.searchpath, nil, "no package.searchpath")
+end
+
+do -- require
+    local f = io.open('complex.lua', 'w')
+    f:write [[
+complex = {}
+
+function complex.new (r, i) return {r=r, i=i} end
+
+--defines a constant 'i'
+complex.i = complex.new(0, 1)
+
+function complex.add (c1, c2)
+    return complex.new(c1.r + c2.r, c1.i + c2.i)
+end
+
+function complex.sub (c1, c2)
+    return complex.new(c1.r - c2.r, c1.i - c2.i)
+end
+
+function complex.mul (c1, c2)
+    return complex.new(c1.r*c2.r - c1.i*c2.i,
+                       c1.r*c2.i + c1.i*c2.r)
+end
+
+local function inv (c)
+    local n = c.r^2 + c.i^2
+    return complex.new(c.r/n, -c.i/n)
+end
+
+function complex.div (c1, c2)
+    return complex.mul(c1, inv(c2))
+end
+
+return complex
+]]
+    f:close()
+    if has_require54 then
+        local m1, path1 = require 'complex'
+        is(m1, complex, "function require")
+        is(path1, './complex.lua')
+        local m2, path2 = require 'complex'
+        is(m1, m2)
+        is(path2, nil)
+    else
+        local m1 = require 'complex'
+        is(m1, complex, "function require")
+        local m2 = require 'complex'
+        is(m1, m2)
+    end
+    is(complex.i.r, 0)
+    is(complex.i.i, 1)
+    os.remove('complex.lua') -- clean up
+
+    error_like(function () require('no_module') end,
+               "^[^:]+:%d+: module 'no_module' not found:",
+               "function require (no module)")
+
+    f = io.open('syntax.lua', 'w')
+    f:write [[?syntax error?]]
+    f:close()
+    error_like(function () require('syntax') end,
+               "^error loading module 'syntax' from file '%.[/\\]syntax%.lua':",
+               "function require (syntax error)")
+    os.remove('syntax.lua') -- clean up
+
+    f = io.open('bar.lua', 'w')
+    f:write [[
+    print("    in bar.lua", ...)
+    a = ...
+]]
+    f:close()
+    a = nil
+    require 'bar'
+    is(a, 'bar', "function require (arg)")
+    os.remove('bar.lua') -- clean up
+
+    f = io.open('cplx.lua', 'w')
+    f:write [[
+-- print('cplx.lua', ...)
+local _G = _G
+_ENV = nil
+local cplx = {}
+
+local function new (r, i) return {r=r, i=i} end
+cplx.new = new
+
+--defines a constant 'i'
+cplx.i = new(0, 1)
+
+function cplx.add (c1, c2)
+    return new(c1.r + c2.r, c1.i + c2.i)
+end
+
+function cplx.sub (c1, c2)
+    return new(c1.r - c2.r, c1.i - c2.i)
+end
+
+function cplx.mul (c1, c2)
+    return new(c1.r*c2.r - c1.i*c2.i,
+               c1.r*c2.i + c1.i*c2.r)
+end
+
+local function inv (c)
+    local n = c.r^2 + c.i^2
+    return new(c.r/n, -c.i/n)
+end
+
+function cplx.div (c1, c2)
+    return mul(c1, inv(c2))
+end
+
+_G.cplx = cplx
+return cplx
+]]
+    f:close()
+    require 'cplx'
+    is(cplx.i.r, 0, "function require & module")
+    is(cplx.i.i, 1)
+    os.remove('cplx.lua') -- clean up
+end
+
+-- module & seeall
+local done_testing = done_testing
+if has_module then
+    m = {}
+    package.seeall(m)
+    m.pass("function package.seeall")
+
+    is(mod, nil, "function module & seeall")
+    module('mod', package.seeall)
+    type_ok(mod, 'table')
+    is(mod, package.loaded.mod)
+
+    is(modz, nil, "function module")
+    local _G = _G
+    module('modz')
+    _G.type_ok(_G.modz, 'table')
+    _G.is(_G.modz, _G.package.loaded.modz)
+else
+    is(package.seeall, nil, "package.seeall (removed)")
+    is(module, nil, "module (removed)")
+end
+
+done_testing()
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/304-string.t b/test/lua-Harness-tests/304-string.t
new file mode 100755
index 0000000..991600a
--- /dev/null
+++ b/test/lua-Harness-tests/304-string.t
@@ -0,0 +1,633 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2020, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua String Library
+
+=head2 Synopsis
+
+    % prove 304-string.t
+
+=head2 Description
+
+Tests Lua String Library
+
+See section "String Manipulation" in "Reference Manual"
+L<https://www.lua.org/manual/5.1/manual.html#5.4>,
+L<https://www.lua.org/manual/5.2/manual.html#6.4>,
+L<https://www.lua.org/manual/5.3/manual.html#6.4>,
+L<https://www.lua.org/manual/5.4/manual.html#6.4>
+
+=cut
+
+]]
+
+require'tap'
+local profile = require'profile'
+local luajit21 = jit and (jit.version_num >= 20100 or jit.version:match'^RaptorJIT')
+local has_dump53 = _VERSION >= 'Lua 5.3' or jit
+local has_format_a = _VERSION >= 'Lua 5.3' or profile.has_string_format_a or jit
+local has_format_p = _VERSION >= 'Lua 5.4'
+local has_format_q52 = _VERSION >= 'Lua 5.2' or jit
+local has_format_q53 = _VERSION >= 'Lua 5.3'
+local has_format_q54 = _VERSION >= 'Lua 5.4'
+local has_gmatch54 = _VERSION >= 'Lua 5.4'
+local has_pack = _VERSION >= 'Lua 5.3' or (jit and jit.version:match'moonjit') or profile.pack
+local has_rep52 = _VERSION >= 'Lua 5.2' or profile.luajit_compat52
+local has_class_g = _VERSION >= 'Lua 5.2' or profile.luajit_compat52
+local loadstring = loadstring or load
+
+plan'no_plan'
+
+do -- metatable
+    local mt = getmetatable('ABC')
+    type_ok(mt, 'table', "metatable")
+    type_ok(mt.__index, 'table')
+
+    if not profile.nocvts2n and _VERSION >= 'Lua 5.4' then
+        type_ok(mt.__add, 'function')
+        type_ok(mt.__div, 'function')
+        type_ok(mt.__idiv, 'function')
+        type_ok(mt.__mul, 'function')
+        type_ok(mt.__mod, 'function')
+        type_ok(mt.__pow, 'function')
+        type_ok(mt.__sub, 'function')
+        type_ok(mt.__unm, 'function')
+    else
+        is(mt.__add, nil)
+        is(mt.__div, nil)
+        is(mt.__idiv, nil)
+        is(mt.__mul, nil)
+        is(mt.__mod, nil)
+        is(mt.__pow, nil)
+        is(mt.__sub, nil)
+        is(mt.__unm, nil)
+    end
+
+    is(mt.__index.byte, string.byte)
+    is(mt.__index.char, string.char)
+    is(mt.__index.dump, string.dump)
+    is(mt.__index.find, string.find)
+    is(mt.__index.format, string.format)
+    is(mt.__index.gmatch, string.gmatch)
+    is(mt.__index.gsub, string.gsub)
+    is(mt.__index.len, string.len)
+    is(mt.__index.lower, string.lower)
+    is(mt.__index.match, string.match)
+    is(mt.__index.rep, string.rep)
+    is(mt.__index.reverse, string.reverse)
+    is(mt.__index.sub, string.sub)
+    is(mt.__index.upper, string.upper)
+
+    if has_pack then
+        is(mt.__index.pack, string.pack)
+        is(mt.__index.packsize, string.packsize)
+        is(mt.__index.unpack, string.unpack)
+    else
+        is(mt.__index.pack, nil)
+        is(mt.__index.packsize, nil)
+        is(mt.__index.unpack, nil)
+    end
+end
+
+do -- byte
+    is(string.byte('ABC'), 65, "function byte")
+    is(string.byte('ABC', 2), 66)
+    is(string.byte('ABC', -1), 67)
+    is(string.byte('ABC', 4), nil)
+    is(string.byte('ABC', 0), nil)
+    eq_array({string.byte('ABC', 1, 3)}, {65, 66, 67})
+    eq_array({string.byte('ABC', 1, 4)}, {65, 66, 67})
+
+    local s = "ABC"
+    is(s:byte(2), 66, "method s:byte")
+end
+
+do -- char
+    is(string.char(65, 66, 67), 'ABC', "function char")
+    is(string.char(), '')
+
+    error_like(function () string.char(0, 'bad') end,
+               "^[^:]+:%d+: bad argument #2 to 'char' %(number expected, got string%)",
+               "function char (bad arg)")
+
+    error_like(function () string.char(0, 9999) end,
+               "^[^:]+:%d+: bad argument #2 to 'char' %(.-value.-%)",
+               "function char (invalid)")
+end
+
+do -- dump
+    local signature
+    if jit then
+        signature = "\x1bLJ"
+    elseif ravi then
+        signature = "\x1bRavi"
+    elseif _VERSION >= 'Lua 5.2' then
+        signature = "\x1bLua"
+    end
+
+    local function add (a, b)
+        return a + b
+    end
+
+    local d = string.dump(add)
+    type_ok(d, 'string', "function dump")
+    local f = loadstring(d)
+    type_ok(f, 'function')
+    is(f(1, 2), 3)
+
+    if signature then
+        local sig = d:sub(1, #signature)
+        is(sig, signature)
+    end
+
+    if has_dump53 then
+        local d2 = string.dump(add, true)
+        type_ok(d2, 'string', "function dump with strip")
+        f = loadstring(d2)
+        type_ok(f, 'function')
+        is(f(1, 2), 3)
+        isnt(d2:len(), d:len())
+
+        if signature then
+            local sig = d2:sub(1, #signature)
+            is(sig, signature)
+        end
+    end
+
+    error_like(function () string.dump(print) end,
+               "^[^:]+:%d+: unable to dump given function",
+               "function dump (C function)")
+end
+
+do -- find
+    local s = "hello world"
+    eq_array({string.find(s, "hello")}, {1, 5}, "function find (mode plain)")
+    eq_array({string.find(s, "hello", 1, true)}, {1, 5})
+    eq_array({string.find(s, "hello", 1)}, {1, 5})
+    is(string.sub(s, 1, 5), "hello")
+    eq_array({string.find(s, "world")}, {7, 11})
+    eq_array({string.find(s, "l")}, {3, 3})
+    is(string.find(s, "lll"), nil)
+    is(string.find(s, "hello", 2, true), nil)
+    eq_array({string.find(s, "world", 2, true)}, {7, 11})
+    is(string.find(s, "hello", 20), nil)
+
+    s = "hello world"
+    eq_array({string.find(s, "^h.ll.")}, {1, 5}, "function find (with regex & captures)")
+    eq_array({string.find(s, "w.rld", 2)}, {7, 11})
+    is(string.find(s, "W.rld"), nil)
+    eq_array({string.find(s, "^(h.ll.)")}, {1, 5, 'hello'})
+    eq_array({string.find(s, "^(h.)l(l.)")}, {1, 5, 'he', 'lo'})
+    s = "Deadline is 30/05/1999, firm"
+    local date = "%d%d/%d%d/%d%d%d%d"
+    is(string.sub(s, string.find(s, date)), "30/05/1999")
+    date = "%f[%S]%d%d/%d%d/%d%d%d%d"
+    is(string.sub(s, string.find(s, date)), "30/05/1999")
+
+    error_like(function () string.find(s, '%f') end,
+               "^[^:]+:%d+: missing '%[' after '%%f' in pattern",
+               "function find (invalid frontier)")
+end
+
+do -- format
+    is(string.format("pi = %.4f", math.pi), 'pi = 3.1416', "function format")
+    local d = 5; local m = 11; local y = 1990
+    is(string.format("%02d/%02d/%04d", d, m, y), "05/11/1990")
+    is(string.format("%X %x", 126, 126), "7E 7e")
+    local tag, title = "h1", "a title"
+    is(string.format("<%s>%s</%s>", tag, title, tag), "<h1>a title</h1>")
+
+    is(string.format('%q', 'a string with "quotes" and \n new line'), [["a string with \"quotes\" and \
+ new line"]], "function format %q")
+
+    if has_format_q52 then
+        is(string.format('%q', 'a string with \0 and \r.'), [["a string with \0 and \13."]], "function format %q")
+        is(string.format('%q', 'a string with \b and \b2'), [["a string with \8 and \0082"]], "function format %q")
+    else
+        is(string.format('%q', 'a string with \0 and \r.'), [["a string with \000 and \r."]], "function format %q")
+        is(string.format('%q', 'a string with \b and \b2'), '"a string with \b and \b2"', "function format %q")
+    end
+
+    if has_format_q53 then
+        is(string.format('%q', 1.5), '0x1.8p+0', "function format %q")
+        is(string.format('%q', 7), '7', "function format %q")
+    else
+        is(string.format('%q', 1.5), [["1.5"]], "function format %q")
+        is(string.format('%q', 7), [["7"]], "function format %q")
+    end
+
+    if has_format_q53 then
+        is(string.format('%q', nil), 'nil', "function format ('%q', nil)")
+    elseif luajit21 then
+        is(string.format('%q', nil), [["nil"]], "function format ('%q', nil)")
+    else
+        error_like(function () string.format("%q", nil) end,
+                   "^[^:]+:%d+: bad argument #2 to 'format' %(",
+                   "function format ('%q', nil)")
+    end
+
+    if has_format_q54 then
+        is(string.format('%q', 0/0), '(0/0)', "function format ('%q', NaN)")
+        is(string.format('%q', 1/0), '1e9999', "function format ('%q', +Inf)")
+        is(string.format('%q', -1/0), '-1e9999', "function format ('%q', -Inf)")
+
+        error_like(function () string.format("%-q", 0) end,
+                   "^[^:]+:%d+: specifier '%%q' cannot have modifiers",
+                   "function format '%-q'")
+    end
+
+    if luajit21 then
+        like(string.format('%q', {}), [[^"table: ]], "function format ('%q', {})")
+    else
+        error_like(function () string.format("%q", {}) end,
+                   "^[^:]+:%d+: bad argument #2 to 'format' %(",
+                   "function format ('%q', {})")
+    end
+
+    if has_format_a then
+        is(string.format('%a', 1.5), '0x1.8p+0', "function format %a")
+    end
+
+    if has_format_p then
+        is(string.format('table: %p', string), tostring(string), "function format %p")
+    end
+
+    is(string.format("%5s", 'foo'), '  foo', "function format (%5s)")
+
+    if _VERSION >= 'Lua 5.3' then
+        error_like(function () string.format("%5s", "foo\0bar") end,
+                   "^[^:]+:%d+: bad argument #2 to 'format' %(string contains zeros%)",
+                   "function format format (%5s with \\0)")
+    end
+
+    is(string.format("%s %s", 1, 2, 3), '1 2', "function format (too many arg)")
+
+    is(string.format("%% %c %%", 65), '% A %', "function format (%%)")
+
+    local r = string.rep("ab", 100)
+    is(string.format("%s %d", r, r:len()), r .. " 200")
+
+    error_like(function () string.format("%s %s", 1) end,
+               "^[^:]+:%d+: bad argument #3 to 'format' %(.-no value%)",
+               "function format (too few arg)")
+
+    error_like(function () string.format('%d', 'toto') end,
+               "^[^:]+:%d+: bad argument #2 to 'format' %(number expected, got string%)",
+               "function format (bad arg)")
+
+    error_like(function () string.format('%k', 'toto') end,
+               "^[^:]+:%d+: invalid .- '%%k' to 'format'",
+               "function format (invalid conversion)")
+
+    if luajit21 then
+        error_like(function () string.format('%111s', 'toto') end,
+                   "^[^:]+:%d+: invalid option '%%111' to 'format'",
+                   "function format (invalid format)")
+    else
+        error_like(function () string.format('%111s', 'toto') end,
+                   "^[^:]+:%d+: invalid format %(width or precision too long%)",
+                   "function format (invalid format)")
+
+        error_like(function () string.format('%------s', 'toto') end,
+                   "^[^:]+:%d+: invalid format %(repeated flags%)",
+                   "function format (invalid format)")
+    end
+
+    error_like(function () string.format('pi = %.123f', math.pi) end,
+               "^[^:]+:%d+: invalid ",
+               "function format (invalid format)")
+
+    error_like(function () string.format('% 123s', 'toto') end,
+               "^[^:]+:%d+: invalid ",
+               "function format (invalid format)")
+end
+
+do -- gmatch
+    local s = "hello"
+    local output = {}
+    for c in string.gmatch(s, '..') do
+        table.insert(output, c)
+    end
+    eq_array(output, {'he', 'll'}, "function gmatch")
+    if has_gmatch54 then
+        output = {}
+        for c in string.gmatch(s, '..', 2) do
+            table.insert(output, c)
+        end
+        eq_array(output, {'el', 'lo'})
+    end
+    output = {}
+    for c1, c2 in string.gmatch(s, '(.)(.)') do
+        table.insert(output, c1)
+        table.insert(output, c2)
+    end
+    eq_array(output, {'h', 'e', 'l', 'l'})
+    s = "hello world from Lua"
+    output = {}
+    for w in string.gmatch(s, '%a+') do
+        table.insert(output, w)
+    end
+    eq_array(output, {'hello', 'world', 'from', 'Lua'})
+    s = "from=world, to=Lua"
+    output = {}
+    for k, v in string.gmatch(s, '(%w+)=(%w+)') do
+        table.insert(output, k)
+        table.insert(output, v)
+    end
+    eq_array(output, {'from', 'world', 'to', 'Lua'})
+end
+
+do -- gsub
+    is(string.gsub("hello world", "(%w+)", "%1 %1"), "hello hello world world", "function gsub")
+    is(string.gsub("hello world", "%w+", "%0 %0", 1), "hello hello world")
+    is(string.gsub("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1"), "world hello Lua from")
+    if _VERSION == 'Lua 5.1' then
+        todo("not with 5.1")
+    end
+    error_like(function () string.gsub("hello world", "%w+", "%e") end,
+               "^[^:]+:%d+: invalid use of '%%' in replacement string",
+               "function gsub (invalid replacement string)")
+    is(string.gsub("home = $HOME, user = $USER", "%$(%w+)", string.reverse), "home = EMOH, user = RESU")
+    is(string.gsub("4+5 = $return 4+5$", "%$(.-)%$", function (s) return tostring(loadstring(s)()) end), "4+5 = 9")
+    local t = {name='lua', version='5.1'}
+    is(string.gsub("$name-$version.tar.gz", "%$(%w+)", t), "lua-5.1.tar.gz")
+
+    is(string.gsub("Lua is cute", 'cute', 'great'), "Lua is great")
+    is(string.gsub("all lii", 'l', 'x'), "axx xii")
+    is(string.gsub("Lua is great", '^Sol', 'Sun'), "Lua is great")
+    is(string.gsub("all lii", 'l', 'x', 1), "axl lii")
+    is(string.gsub("all lii", 'l', 'x', 2), "axx lii")
+    is(select(2, string.gsub("string with 3 spaces", ' ', ' ')), 3)
+
+    eq_array({string.gsub("hello, up-down!", '%A', '.')}, {"hello..up.down.", 4})
+    eq_array({string.gsub("hello, up-down!", '%A', '%%')}, {"hello%%up%down%", 4})
+    local text = "hello world"
+    local nvow = select(2, string.gsub(text, '[AEIOUaeiou]', ''))
+    is(nvow, 3)
+    eq_array({string.gsub("one, and two; and three", '%a+', 'word')}, {"word, word word; word word", 5})
+    local test = "int x; /* x */  int y; /* y */"
+    eq_array({string.gsub(test, "/%*.*%*/", '<COMMENT>')}, {"int x; <COMMENT>", 1})
+    eq_array({string.gsub(test, "/%*.-%*/", '<COMMENT>')}, {"int x; <COMMENT>  int y; <COMMENT>", 2})
+    local s = "a (enclosed (in) parentheses) line"
+    eq_array({string.gsub(s, '%b()', '')}, {"a  line", 1})
+
+    error_like(function () string.gsub(s, '%b(', '') end,
+               "^[^:]+:%d+: .- pattern",
+               "function gsub (malformed pattern)")
+
+    eq_array({string.gsub("hello Lua!", "%a", "%0-%0")}, {"h-he-el-ll-lo-o L-Lu-ua-a!", 8})
+    eq_array({string.gsub("hello Lua", "(.)(.)", "%2%1")}, {"ehll ouLa", 4})
+
+    local function expand (str)
+        return (string.gsub(str, '$(%w+)', _G))
+    end
+    name = 'Lua'; status= 'great'
+    is(expand("$name is $status, isn't it?"), "Lua is great, isn't it?")
+    is(expand("$othername is $status, isn't it?"), "$othername is great, isn't it?")
+
+    function expand (str)
+        return (string.gsub(str, '$(%w+)', function (n)
+                                            return tostring(_G[n]), 1
+                                       end))
+    end
+    like(expand("print = $print; a = $a"), "^print = function: [0]?[Xx]?[builtin]*#?%x+; a = nil")
+
+    error_like(function () string.gsub("hello world", '(%w+)', '%2 %2') end,
+               "^[^:]+:%d+: invalid capture index",
+               "function gsub (invalid index)")
+
+    error_like(function () string.gsub("hello world", '(%w+)', true) end,
+               "^[^:]+:%d+: bad argument #3 to 'gsub' %(string/function/table expected",
+               "function gsub (bad type)")
+
+    error_like(function ()
+        function expand (str)
+           return (string.gsub(str, '$(%w+)', _G))
+        end
+
+        name = 'Lua'; status= true
+        expand("$name is $status, isn't it?")
+               end,
+               "^[^:]+:%d+: invalid replacement value %(a boolean%)",
+               "function gsub (invalid value)")
+
+    local function trim (str)
+        return (str:gsub('^%s*(.-)%s*$', '%1'))
+    end
+    is(trim('foo'), 'foo', "gsub trim")
+    is(trim('   foo  bar  '), 'foo  bar')
+end
+
+do -- len
+    is(string.len(''), 0, "function len")
+    is(string.len('test'), 4)
+    is(string.len("a\000b\000c"), 5)
+    is(string.len('"'), 1)
+end
+
+do -- lower
+    is(string.lower('Test'), 'test', "function lower")
+    is(string.lower('TeSt'), 'test')
+end
+
+do -- match
+    local s = "hello world"
+    is(string.match(s, '^hello'), 'hello', "function match")
+    is(string.match(s, 'world', 2), 'world')
+    is(string.match(s, 'World'), nil)
+    eq_array({string.match(s, '^(h.ll.)')}, {'hello'})
+    eq_array({string.match(s, '^(h.)l(l.)')}, {'he', 'lo'})
+    local date = "Today is 17/7/1990"
+    is(string.match(date, '%d+/%d+/%d+'), '17/7/1990')
+    eq_array({string.match(date, '(%d+)/(%d+)/(%d+)')}, {'17', '7', '1990'})
+    is(string.match("The number 1298 is even", '%d+'), '1298')
+    local pair = "name = Anna"
+    eq_array({string.match(pair, '(%a+)%s*=%s*(%a+)')}, {'name', 'Anna'})
+
+    s = [[then he said: "it's all right"!]]
+    eq_array({string.match(s, "([\"'])(.-)%1")}, {'"', "it's all right"}, "function match (back ref)")
+    local p = "%[(=*)%[(.-)%]%1%]"
+    s = "a = [=[[[ something ]] ]==]x]=]; print(a)"
+    eq_array({string.match(s, p)}, {'=', '[[ something ]] ]==]x'})
+
+    if has_class_g then
+        is(string.match(s, "%g"), "a", "match graphic char")
+    end
+
+    error_like(function () string.match("hello world", "%1") end,
+               "^[^:]+:%d+: invalid capture index",
+               "function match invalid capture")
+
+    error_like(function () string.match("hello world", "%w)") end,
+               "^[^:]+:%d+: invalid pattern capture",
+               "function match invalid capture")
+end
+
+-- pack
+if has_pack then
+    is(string.pack('b', 0x31), '\x31', "function pack")
+    is(string.pack('>b', 0x31), '\x31')
+    is(string.pack('=b', 0x31), '\x31')
+    is(string.pack('<b', 0x31), '\x31')
+    is(string.pack('>B', 0x91), '\x91')
+    is(string.pack('=B', 0x91), '\x91')
+    is(string.pack('<B', 0x91), '\x91')
+    is(string.byte(string.pack('<h', 1)), 1)
+    is(string.byte(string.pack('>h', 1):reverse()), 1)
+    is(string.byte(string.pack('<H', 1)), 1)
+    is(string.byte(string.pack('>H', 1):reverse()), 1)
+    is(string.byte(string.pack('<l', 1)), 1)
+    is(string.byte(string.pack('>l', 1):reverse()), 1)
+    is(string.byte(string.pack('<L', 1)), 1)
+    is(string.byte(string.pack('>L', 1):reverse()), 1)
+    is(string.byte(string.pack('<j', 1)), 1)
+    is(string.byte(string.pack('>j', 1):reverse()), 1)
+    is(string.byte(string.pack('<J', 1)), 1)
+    is(string.byte(string.pack('>J', 1):reverse()), 1)
+    is(string.byte(string.pack('<T', 1)), 1)
+    is(string.byte(string.pack('>T', 1):reverse()), 1)
+    is(string.byte(string.pack('<i', 1)), 1)
+    is(string.byte(string.pack('>i', 1):reverse()), 1)
+    is(string.byte(string.pack('<I', 1)), 1)
+    is(string.byte(string.pack('>I', 1):reverse()), 1)
+    is(string.pack('i1', 0):len(), 1)
+    is(string.pack('i2', 0):len(), 2)
+    is(string.pack('i4', 0):len(), 4)
+    is(string.pack('i8', 0):len(), 8)
+    is(string.pack('i16', 0):len(), 16)
+    error_like(function () string.pack('i20', 0) end,
+               "^[^:]+:%d+: integral size %(20%) out of limits %[1,16%]",
+               "function pack out limit")
+
+    is(string.pack('!2 i1 i4', 0, 0):len(), 6)
+    is(string.pack('i1 Xb i1', 0, 0):len(), 2)
+    is(string.pack('i1 x x i1', 0, 0):len(), 4)
+
+    is(string.pack('c3', 'foo'), 'foo')
+    is(string.pack('z', 'foo'), 'foo\0')
+    is(string.pack('c4', 'foo'), 'foo\0')   -- padding
+
+    error_like(function () string.pack('w', 0) end,
+               "^[^:]+:%d+: invalid format option 'w'",
+               "function pack invalid format")
+
+    error_like(function () string.pack('i1 Xz i1', 0, 0) end,
+               "^[^:]+:%d+: bad argument #1 to 'pack' %(invalid next option for option 'X'%)",
+               "function pack invalid next")
+
+    error_like(function () string.pack('i', 'foo') end,
+               "^[^:]+:%d+: bad argument #2 to 'pack' %(number expected, got string%)",
+              "function pack bad arg")
+else
+    is(string.pack, nil, "no string.pack");
+end
+
+-- packsize
+if has_pack then
+    is(string.packsize('b'), 1, "function packsize")
+
+    is(string.packsize(''), 0, "function packsize empty")
+
+    error_like(function () string.packsize('z') end,
+               "^[^:]+:%d+: bad argument #1 to 'packsize' %(variable%-length format%)",
+               "function packsize bad arg")
+else
+    is(string.packsize, nil, "no string.packsize");
+end
+
+do -- rep
+    is(string.rep('ab', 3), 'ababab', "function rep")
+    is(string.rep('ab', 0), '')
+    is(string.rep('ab', -1), '')
+    is(string.rep('', 5), '')
+    if has_rep52 then
+        is(string.rep('ab', 3, ','), 'ab,ab,ab', "with sep")
+        local n = 1e6
+        is(string.rep('a', n), string.rep('', n + 1, 'a'))
+    else
+        diag("no rep with separator")
+    end
+
+    if _VERSION >= 'Lua 5.3' then
+        error_like(function () string.rep('foo', 1e9) end,
+                   "^[^:]+:%d+: resulting string too large",
+                   "too large")
+    elseif luajit21 then
+        error_is(function () string.rep('foo', 1e9) end,
+                 "not enough memory",
+                 "too large")
+    end
+
+    if _VERSION >= 'Lua 5.4' or jit then
+        is(string.rep('', 1e8), '', "rep ''")
+    else
+        diag('too slow')
+    end
+end
+
+do -- reverse
+    is(string.reverse('abcde'), 'edcba', "function reverse")
+    is(string.reverse('abcd'), 'dcba')
+    is(string.reverse(''), '')
+end
+
+do -- sub
+    is(string.sub('abcde', 1, 2), 'ab', "function sub")
+    is(string.sub('abcde', 3, 4), 'cd')
+    is(string.sub('abcde', -2), 'de')
+    is(string.sub('abcde', 3, 2), '')
+end
+
+do -- upper
+    is(string.upper('Test'), 'TEST', "function upper")
+    is(string.upper('TeSt'), 'TEST')
+    is(string.upper(string.rep('Test', 10000)), string.rep('TEST', 10000))
+end
+
+-- unpack
+if has_pack then
+    is(string.unpack('<h', string.pack('>h', 1):reverse()), 1, "function unpack")
+    is(string.unpack('<H', string.pack('>H', 1):reverse()), 1)
+    is(string.unpack('<l', string.pack('>l', 1):reverse()), 1)
+    is(string.unpack('<L', string.pack('>L', 1):reverse()), 1)
+    is(string.unpack('<j', string.pack('>j', 1):reverse()), 1)
+    is(string.unpack('<J', string.pack('>J', 1):reverse()), 1)
+    is(string.unpack('<T', string.pack('>T', 1):reverse()), 1)
+    is(string.unpack('<i', string.pack('>i', 1):reverse()), 1)
+    is(string.unpack('<I', string.pack('>I', 1):reverse()), 1)
+    is(string.unpack('<f', string.pack('>f', 1.0):reverse()), 1.0)
+    is(string.unpack('<d', string.pack('>d', 1.0):reverse()), 1.0)
+    is(string.unpack('<n', string.pack('>n', 1.0):reverse()), 1.0)
+
+    is(string.unpack('c3', string.pack('c3', 'foo')), 'foo')
+    is(string.unpack('z', string.pack('z', 'foo')), 'foo')
+    is(string.unpack('s', string.pack('s', 'foo')), 'foo')
+
+    error_like(function () string.unpack('c4', 'foo') end,
+               "^[^:]+:%d+: bad argument #2 to 'unpack' %(data string too short%)",
+               "function unpack data too short")
+
+    error_like(function () string.unpack('c', 'foo') end,
+               "^[^:]+:%d+: missing size for format option 'c'",
+               "function unpack missing size")
+else
+    is(string.unpack, nil, "no string.unpack");
+end
+
+done_testing()
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/305-utf8.t b/test/lua-Harness-tests/305-utf8.t
new file mode 100755
index 0000000..4304b6c
--- /dev/null
+++ b/test/lua-Harness-tests/305-utf8.t
@@ -0,0 +1,55 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2014-2020, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua UTF-8 support Library
+
+=head2 Synopsis
+
+    % prove 305-utf8.t
+
+=head2 Description
+
+Tests Lua UTF-8 Library
+
+This library was introduced in Lua 5.3.
+
+See section "UTF-8 support" in "Reference Manual"
+L<https://www.lua.org/manual/5.3/manual.html#6.5>,
+L<https://www.lua.org/manual/5.4/manual.html#6.5>
+
+=cut
+
+--]]
+
+require 'tap'
+
+local profile = require'profile'
+local has_utf8 = _VERSION >= 'Lua 5.3' or (jit and jit.version:match'moonjit') or profile.utf8
+
+if not utf8 then
+    plan(1)
+    nok(has_utf8, "no has_utf8")
+else
+    plan'no_plan'
+    dofile'lexico53/utf8.t'
+    if _VERSION >= 'Lua 5.4' then
+        dofile'lexico54/utf8.t'
+    end
+    done_testing()
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/306-table.t b/test/lua-Harness-tests/306-table.t
new file mode 100755
index 0000000..9836655
--- /dev/null
+++ b/test/lua-Harness-tests/306-table.t
@@ -0,0 +1,372 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2020, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua Table Library
+
+=head2 Synopsis
+
+    % prove 305-table.t
+
+=head2 Description
+
+Tests Lua Table Library
+
+See section "Table Manipulation" in "Reference Manual"
+L<https://www.lua.org/manual/5.1/manual.html#5.5>,
+L<https://www.lua.org/manual/5.2/manual.html#6.5>,
+L<https://www.lua.org/manual/5.3/manual.html#6.6>,
+L<https://www.lua.org/manual/5.4/manual.html#6.6>
+
+=cut
+
+--]]
+
+require'tap'
+local profile = require'profile'
+local luajit21 = jit and (jit.version_num >= 20100 or jit.version:match'^RaptorJIT')
+local has_foreach = _VERSION == 'Lua 5.1'
+local has_foreachi = _VERSION == 'Lua 5.1'
+local has_getn = _VERSION == 'Lua 5.1'
+local has_setn_obsolete = _VERSION == 'Lua 5.1' and not jit
+local has_maxn = _VERSION == 'Lua 5.1' or profile.compat51 or profile.has_table_maxn
+local has_pack = _VERSION >= 'Lua 5.2' or profile.luajit_compat52
+local has_move = _VERSION >= 'Lua 5.3' or  luajit21
+local has_unpack = _VERSION >= 'Lua 5.2'
+local has_alias_unpack = profile.luajit_compat52
+local nocvtn2s = profile.nocvtn2s
+
+plan'no_plan'
+
+do -- concat
+    local t = {'a','b','c','d','e'}
+    is(table.concat(t), 'abcde', "function concat")
+    is(table.concat(t, ','), 'a,b,c,d,e')
+    is(table.concat(t, ',',2), 'b,c,d,e')
+    is(table.concat(t, ',', 2, 4), 'b,c,d')
+    is(table.concat(t, ',', 4, 2), '')
+
+    t = {'a','b',3,'d','e'}
+    if nocvtn2s then
+        error_like(function () table.concat(t,',') end,
+               "^[^:]+:%d+: invalid value %(number%) at index 3 in table for 'concat'",
+               "function concat (number no conv)")
+    else
+        is(table.concat(t,','), 'a,b,3,d,e', "function concat (number)")
+    end
+
+    t = {'a','b','c','d','e'}
+    error_like(function () table.concat(t, ',', 2, 7) end,
+               "^[^:]+:%d+: invalid value %(nil%) at index 6 in table for 'concat'",
+               "function concat (out of range)")
+
+    t = {'a','b',true,'d','e'}
+    error_like(function () table.concat(t, ',') end,
+               "^[^:]+:%d+: invalid value %(boolean%) at index 3 in table for 'concat'",
+               "function concat (non-string)")
+end
+
+do -- insert
+    local a = {'10', '20', '30'}
+    table.insert(a, 1, '15')
+    is(table.concat(a,','), '15,10,20,30', "function insert")
+    local t = {}
+    table.insert(t, 'a')
+    is(table.concat(t, ','), 'a')
+    table.insert(t, 'b')
+    is(table.concat(t, ','), 'a,b')
+    table.insert(t, 1, 'c')
+    is(table.concat(t, ','), 'c,a,b')
+    table.insert(t, 2, 'd')
+    is(table.concat(t, ','), 'c,d,a,b')
+    table.insert(t, 5, 'e')
+    is(table.concat(t, ','), 'c,d,a,b,e')
+
+    if _VERSION == 'Lua 5.1' then
+        todo("not with 5.1", 2)
+    end
+    error_like(function () table.insert(t, 7, 'f') end,
+               "^[^:]+:%d+: bad argument #2 to 'insert' %(position out of bounds%)",
+               "function insert (out of bounds)")
+
+    error_like(function () table.insert(t, -9, 'f') end,
+               "^[^:]+:%d+: bad argument #2 to 'insert' %(position out of bounds%)",
+               "function insert (out of bounds)")
+
+    error_like(function () table.insert(t, 2, 'g', 'h')  end,
+               "^[^:]+:%d+: wrong number of arguments to 'insert'",
+               "function insert (too many arg)")
+end
+
+-- foreach 5.0
+if has_foreach then
+    local t = {a=10, b=100}
+    local output = {}
+    table.foreach(t, function (k, v) output[k] = v end)
+    eq_array(output, t, "function foreach (hash)")
+
+    t = {'a','b','c'}
+    output = {}
+    table.foreach(t, function (k, v)
+        table.insert(output, k)
+        table.insert(output, v)
+    end)
+    eq_array(output, {1, 'a', 2, 'b', 3, 'c'}, "function foreach (array)")
+else
+    is(table.foreach, nil, "no table.foreach");
+end
+
+-- foreachi 5.0
+if has_foreachi then
+    local t = {'a','b','c'}
+    local output = {}
+    table.foreachi(t, function (i, v)
+        table.insert(output, i)
+        table.insert(output, v)
+    end)
+    eq_array(output, {1, 'a', 2, 'b', 3, 'c'}, "function foreachi")
+else
+    is(table.foreachi, nil, "no table.foreachi");
+end
+
+if has_getn then
+    is(table.getn{10,2,4}, 3, "function getn")
+    is(table.getn{10,2,nil}, 2)
+else
+    is(table.getn, nil, "no table.getn");
+end
+
+-- maxn
+if has_maxn then
+    local t = {}
+    is(table.maxn(t), 0, "function maxn")
+    t[1] = 'a'
+    t[2] = 'b'
+    is(table.maxn(t), 2)
+    t[6] = 'g'
+    is(table.maxn(t), 6)
+
+    local a = {}
+    a[10000] = 1
+    is(table.maxn(a), 10000)
+else
+    is(table.maxn, nil, "no table.maxn");
+end
+
+-- move
+if has_move then
+    local a = {'a', 'b', 'c'}
+    local t = { 1, 2, 3, 4}
+    table.move(a, 1, 3, 1, t)
+    eq_array(t, {'a', 'b', 'c', 4}, "function move")
+    table.move(a, 1, 3, 3, t)
+    eq_array(t, {'a', 'b', 'a', 'b', 'c'})
+
+    table.move(a, 1, 3, 1)
+    eq_array(a, {'a', 'b', 'c'})
+    table.move(a, 1, 3, 3)
+    eq_array(a, {'a', 'b', 'a', 'b', 'c'})
+
+    error_like(function () table.move(a, 1, 2, 1, 2) end,
+               "^[^:]+:%d+: bad argument #5 to 'move' %(table expected",
+               "function move (bad arg)")
+
+    error_like(function () table.move(a, 1, 2) end,
+               "^[^:]+:%d+: bad argument #4 to 'move' %(number expected, got .-%)",
+               "function move (bad arg)")
+
+    error_like(function () table.move(a, 1) end,
+               "^[^:]+:%d+: bad argument #3 to 'move' %(number expected, got .-%)",
+               "function move (bad arg)")
+else
+    is(table.move, nil, "no table.move");
+end
+
+-- pack
+if has_pack then
+    local t = table.pack("abc", "def", "ghi")
+    eq_array(t, {
+        "abc",
+        "def",
+        "ghi"
+    }, "function pack")
+    is(t.n, 3)
+
+    t = table.pack()
+    eq_array(t, {}, "function pack (no element)")
+    is(t.n, 0)
+else
+    is(table.pack, nil, "no table.pack");
+end
+
+do -- remove
+    local t = {}
+    local a = table.remove(t)
+    is(a, nil, "function remove")
+    t = {'a','b','c','d','e'}
+    a = table.remove(t)
+    is(a, 'e')
+    is(table.concat(t, ','), 'a,b,c,d')
+    a = table.remove(t,3)
+    is(a, 'c')
+    is(table.concat(t, ','), 'a,b,d')
+    a = table.remove(t,1)
+    is(a, 'a')
+    is(table.concat(t, ','), 'b,d')
+
+    if _VERSION == 'Lua 5.1' then
+        todo("not with 5.1", 1)
+    end
+    error_like(function () table.remove(t,7) end,
+               "^[^:]+:%d+: bad argument #1 to 'remove' %(position out of bounds%)",
+               "function remove (out of bounds)")
+end
+
+-- setn obsolete
+if has_setn_obsolete then
+    local a = {}
+    error_like(function () table.setn(a, 10000) end,
+               "^[^:]+:%d+: 'setn' is obsolete",
+               "function setn")
+else
+    is(table.setn, nil, "no table.setn");
+end
+
+do -- sort
+    local lines = {
+        luaH_set = 10,
+        luaH_get = 24,
+        luaH_present = 48,
+    }
+
+    do
+        local a = {}
+        for n in pairs(lines) do a[#a + 1] = n end
+        table.sort(a)
+        local output = {}
+        for _, n in ipairs(a) do
+            table.insert(output, n)
+        end
+        eq_array(output, {'luaH_get', 'luaH_present', 'luaH_set'}, "function sort")
+    end
+
+    do
+        local function pairsByKeys (t, f)
+            local a = {}
+            for n in pairs(t) do a[#a + 1] = n end
+            table.sort(a, f)
+            local i = 0     -- iterator variable
+            return function ()  -- iterator function
+                i = i + 1
+                return a[i], t[a[i]]
+            end
+        end
+
+        local output = {}
+        for name, line in pairsByKeys(lines) do
+            table.insert(output, name)
+            table.insert(output, line)
+        end
+        eq_array(output, {'luaH_get', 24, 'luaH_present', 48, 'luaH_set', 10}, "function sort")
+
+        output = {}
+        for name, line in pairsByKeys(lines, function (a, b) return a < b end) do
+            table.insert(output, name)
+            table.insert(output, line)
+        end
+        eq_array(output, {'luaH_get', 24, 'luaH_present', 48, 'luaH_set', 10}, "function sort")
+    end
+
+    do
+        local function permgen (a, n)
+            n = n or #a
+            if n <= 1 then
+                coroutine.yield(a)
+            else
+                for i=1,n do
+                    a[n], a[i] = a[i], a[n]
+                    permgen(a, n - 1)
+                    a[n], a[i] = a[i], a[n]
+                end
+            end
+        end
+
+        local function permutations (a)
+            local co = coroutine.create(function () permgen(a) end)
+            return function ()
+                       local code, res = coroutine.resume(co)
+                       return res
+                    end
+        end
+
+        local t = {}
+        local output = {}
+        for _, v in ipairs{'a', 'b', 'c', 'd', 'e', 'f', 'g'} do
+            table.insert(t, v)
+            local ref = table.concat(t, ' ')
+            table.insert(output, ref)
+            local n = 0
+            for p in permutations(t) do
+                local c = {}
+                for i, vv in ipairs(p) do
+                    c[i] = vv
+                end
+                table.sort(c)
+                assert(ref == table.concat(c, ' '), table.concat(p, ' '))
+                n = n + 1
+            end
+            table.insert(output, n)
+        end
+
+        eq_array(output, {
+            'a', 1,
+            'a b', 2,
+            'a b c', 6,
+            'a b c d', 24,
+            'a b c d e', 120,
+            'a b c d e f', 720,
+            'a b c d e f g', 5040,
+        }, "function sort (all permutations)")
+    end
+
+    if _VERSION == 'Lua 5.1' and not jit then
+        todo("not with 5.1")
+    end
+    error_like(function ()
+                   local t = { 1 }
+                   table.sort( { t, t, t, t, }, function (a, b) return a[1] == b[1] end )
+               end,
+               "^[^:]+:%d+: invalid order function for sorting",
+               "function sort (bad func)")
+end
+
+-- unpack
+if has_unpack then
+    eq_array({table.unpack({})}, {}, "function unpack")
+    eq_array({table.unpack({'a'})}, {'a'})
+    eq_array({table.unpack({'a','b','c'})}, {'a','b','c'})
+    eq_array({(table.unpack({'a','b','c'}))}, {'a'})
+    eq_array({table.unpack({'a','b','c','d','e'},2,4)}, {'b','c','d'})
+    eq_array({table.unpack({'a','b','c'},2,4)}, {'b','c'})
+elseif has_alias_unpack then
+    is(table.unpack, unpack, "alias table.unpack");
+else
+    is(table.unpack, nil, "no table.unpack");
+end
+
+done_testing()
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/307-math.t b/test/lua-Harness-tests/307-math.t
new file mode 100755
index 0000000..8b51ed1
--- /dev/null
+++ b/test/lua-Harness-tests/307-math.t
@@ -0,0 +1,375 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2020, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua Mathematic Library
+
+=head2 Synopsis
+
+    % prove 307-math.t
+
+=head2 Description
+
+Tests Lua Mathematic Library
+
+See section "Mathematical Functions" in "Reference Manual"
+L<https://www.lua.org/manual/5.1/manual.html#5.6>,
+L<https://www.lua.org/manual/5.2/manual.html#6.6>,
+L<https://www.lua.org/manual/5.3/manual.html#6.7>,
+L<https://www.lua.org/manual/5.4/manual.html#6.7>
+
+=cut
+
+--]]
+
+require'tap'
+local profile = require'profile'
+local has_integer = _VERSION >= 'Lua 5.3' or (jit and jit.version:match'moonjit') or profile.integer
+local has_mathx = _VERSION < 'Lua 5.3' or profile.compat52 or profile.compat53 or profile.has_mathx
+local has_log10 = _VERSION < 'Lua 5.2' or profile.compat51 or profile.has_math_log10 or
+                  profile.compat52 or profile.compat53 or profile.has_mathx
+local has_log_with_base = _VERSION >= 'Lua 5.2' or profile.compat52
+local has_mod = profile.has_math_mod or ujit
+local nocvts2n = profile.nocvts2n or jit
+
+plan'no_plan'
+
+do -- abs
+    is(math.abs(-12.34), 12.34, "function abs (float)")
+    is(math.abs(12.34), 12.34)
+    if math.type then
+        is(math.type(math.abs(-12.34)), 'float')
+    end
+    is(math.abs(-12), 12, "function abs (integer)")
+    is(math.abs(12), 12)
+    if math.type then
+        is(math.type(math.abs(-12)), 'integer')
+    end
+end
+
+do -- acos
+    like(math.acos(0.5), '^1%.047', "function acos")
+end
+
+do -- asin
+    like(math.asin(0.5), '^0%.523', "function asin")
+end
+
+do -- atan
+    like(math.atan(0.5), '^0%.463', "function atan")
+end
+
+-- atan2
+if has_mathx then
+    like(math.atan2(1.0, 2.0), '^0%.463', "function atan2")
+else
+    is(math.atan2, nil, "function atan2 (removed)")
+end
+
+do -- ceil
+    is(math.ceil(12.34), 13, "function ceil")
+    is(math.ceil(-12.34), -12)
+    is(math.ceil(-12), -12)
+    if math.type then
+        is(math.type(math.ceil(-12.34)), 'integer')
+    end
+end
+
+do -- cos
+    like(math.cos(1.0), '^0%.540', "function cos")
+end
+
+-- cosh
+if has_mathx then
+    like(math.cosh(1.0), '^1%.543', "function cosh")
+else
+    is(math.cosh, nil, "function cosh (removed)")
+end
+
+do -- deg
+    is(math.deg(math.pi), 180, "function deg")
+end
+
+do -- exp
+    like(math.exp(1.0), '^2%.718', "function exp")
+end
+
+do -- floor
+    is(math.floor(12.34), 12, "function floor")
+    is(math.floor(-12.34), -13)
+    is(math.floor(-12), -12)
+    if math.type then
+        is(math.type(math.floor(-12.34)), 'integer')
+    end
+end
+
+do -- fmod
+    like(math.fmod(7.0001, 0.3), '^0%.100', "function fmod (float)")
+    like(math.fmod(-7.0001, 0.3), '^-0%.100')
+    like(math.fmod(-7.0001, -0.3), '^-0%.100')
+    if math.type then
+        is(math.type(math.fmod(7.0, 0.3)), 'float')
+    end
+    is(math.fmod(7, 3), 1, "function fmod (integer)")
+    is(math.fmod(-7, 3), -1)
+    is(math.fmod(-7, -1), 0)
+    if math.type then
+        is(math.type(math.fmod(7, 3)), 'integer')
+    end
+    if _VERSION >= 'Lua 5.3' then
+        error_like(function () math.fmod(7, 0) end,
+                   "^[^:]+:%d+: bad argument #2 to 'fmod' %(zero%)",
+                   "function fmod 0")
+    else
+        diag"fmod by zero -> nan"
+    end
+end
+
+-- frexp
+if has_mathx then
+    eq_array({math.frexp(1.5)}, {0.75, 1}, "function frexp")
+else
+    is(math.frexp, nil, "function frexp (removed)")
+end
+
+do -- huge
+    type_ok(math.huge, 'number', "variable huge")
+    if math.type then
+        is(math.type(math.huge), 'float')
+    end
+end
+
+-- ldexp
+if has_mathx then
+    is(math.ldexp(1.2, 3), 9.6, "function ldexp")
+else
+    is(math.ldexp, nil, "function ldexp (removed)")
+end
+
+do -- log
+    like(math.log(47), '^3%.85', "function log")
+    if has_log_with_base then
+        like(math.log(47, math.exp(1)), '^3%.85', "function log (base e)")
+        like(math.log(47, 2), '^5%.554', "function log (base 2)")
+        like(math.log(47, 10), '^1%.672', "function log (base 10)")
+    end
+end
+
+-- log10
+if has_log10 then
+    like(math.log10(47.0), '^1%.672', "function log10")
+else
+    is(math.log10, nil, "function log10 (removed)")
+end
+
+do --max
+    is(math.max(1), 1, "function max")
+    is(math.max(1, 2), 2)
+    is(math.max(1, 2, 3, -4), 3)
+
+    error_like(function () math.max() end,
+               "^[^:]+:%d+: bad argument #1 to 'max' %(.- expected",
+               "function max 0")
+end
+
+-- maxinteger
+if has_integer then
+    type_ok(math.maxinteger, 'number', "variable maxinteger")
+    if math.type then
+        is(math.type(math.maxinteger), 'integer')
+    end
+else
+    is(math.maxinteger, nil, "no maxinteger")
+end
+
+do --min
+    is(math.min(1), 1, "function min")
+    is(math.min(1, 2), 1)
+    is(math.min(1, 2, 3, -4), -4)
+
+    error_like(function () math.min() end,
+               "^[^:]+:%d+: bad argument #1 to 'min' %(.- expected",
+               "function min 0")
+end
+
+-- mininteger
+if has_integer then
+    type_ok(math.mininteger, 'number', "variable mininteger")
+    if math.type then
+        is(math.type(math.mininteger), 'integer')
+    end
+else
+    is(math.mininteger, nil, "no mininteger")
+end
+
+-- mod (compat50)
+if has_mod then
+    is(math.mod, math.fmod, "function mod (alias fmod)")
+else
+    is(math.mod, nil, "function mod (alias removed)")
+end
+
+do -- modf
+    eq_array({math.modf(2.25)}, {2, 0.25}, "function modf")
+    eq_array({math.modf(2)}, {2, 0.0})
+end
+
+do -- pi
+    like(tostring(math.pi), '^3%.14', "variable pi")
+end
+
+-- pow
+if has_mathx then
+    is(math.pow(-2, 3), -8, "function pow")
+else
+    is(math.pow, nil, "function pow (removed)")
+end
+
+do -- rad
+    like(math.rad(180), '^3%.14', "function rad")
+end
+
+do -- random
+    like(math.random(), '^0%.%d+', "function random no arg")
+    if math.type then
+        is(math.type(math.random()), 'float')
+    end
+    like(math.random(9), '^%d$', "function random 1 arg")
+    if math.type then
+        is(math.type(math.random(9)), 'integer')
+    end
+    like(math.random(10, 19), '^1%d$', "function random 2 arg")
+    if math.type then
+        is(math.type(math.random(10, 19)), 'integer')
+    end
+    like(math.random(-19, -10), '^-1%d$', "function random 2 arg")
+
+    if _VERSION >= 'Lua 5.4' then
+        like(math.random(0), '^%-?%d+$', "function random 0")
+    else
+        if jit then
+            todo("LuaJIT intentional. Don't check empty interval.")
+        end
+        error_like(function () math.random(0) end,
+                   "^[^:]+:%d+: bad argument #1 to 'random' %(interval is empty%)",
+                  "function random empty interval")
+    end
+
+    if jit then
+        todo("LuaJIT intentional. Don't check empty interval.", 2)
+    end
+    error_like(function () math.random(-9) end,
+               "^[^:]+:%d+: bad argument #%d to 'random' %(interval is empty%)",
+               "function random empty interval")
+
+    error_like(function () math.random(19, 10) end,
+               "^[^:]+:%d+: bad argument #%d to 'random' %(interval is empty%)",
+               "function random empty interval")
+
+    if jit then
+        todo("LuaJIT intentional. Don't care about extra arguments.")
+    end
+    error_like(function () math.random(1, 2, 3) end,
+               "^[^:]+:%d+: wrong number of arguments",
+               "function random too many arg")
+end
+
+do -- randomseed
+    math.randomseed(42)
+    local a = math.random()
+    math.randomseed(42)
+    local b = math.random()
+    is(a, b, "function randomseed")
+end
+
+do -- sin
+    like(math.sin(1.0), '^0%.841', "function sin")
+end
+
+-- sinh
+if has_mathx then
+    like(math.sinh(1), '^1%.175', "function sinh")
+else
+    is(math.sinh, nil, "function sinh (removed)")
+end
+
+do -- sqrt
+    like(math.sqrt(2), '^1%.414', "function sqrt")
+end
+
+do -- tan
+    like(math.tan(1.0), '^1%.557', "function tan")
+end
+
+-- tanh
+if has_mathx then
+    like(math.tanh(1), '^0%.761', "function tanh")
+else
+    is(math.tanh, nil, "function tanh (removed)")
+end
+
+-- tointeger
+if has_integer then
+    is(math.tointeger(-12), -12, "function tointeger (number)")
+    is(math.tointeger(-12.0), -12)
+    is(math.tointeger(-12.34), nil)
+    if nocvts2n then
+        is(math.tointeger('-12'), nil, "function tointeger (string)")
+        is(math.tointeger('-12.0'), nil)
+    else
+        is(math.tointeger('-12'), -12, "function tointeger (string)")
+        is(math.tointeger('-12.0'), -12)
+    end
+    is(math.tointeger('-12.34'), nil)
+    is(math.tointeger('bad'), nil)
+    is(math.tointeger(true), nil, "function tointeger (boolean)")
+    is(math.tointeger({}), nil, "function tointeger (table)")
+else
+    is(math.tointeger, nil, "no math.tointeger")
+end
+
+-- type
+if has_integer then
+    is(math.type(3), 'integer', "function type")
+    is(math.type(3.14), 'float')
+    is(math.type('3.14'), nil)
+else
+    is(math.type, nil, "no math.type")
+end
+
+-- ult
+if has_integer then
+    is(math.ult(2, 3), true, "function ult")
+    is(math.ult(2, 2), false)
+    is(math.ult(2, 1), false)
+
+    error_like(function () math.ult(3.14) end,
+               "^%S+ bad argument #1 to 'ult' %(number has no integer representation%)",
+               "function ult (float)")
+    error_like(function () math.ult(2, 3.14) end,
+               "^%S+ bad argument #2 to 'ult' %(number has no integer representation%)")
+    error_like(function () math.ult(true) end,
+               "^[^:]+:%d+: bad argument #1 to 'ult' %(number expected, got boolean%)",
+               "function ult (boolean)")
+    error_like(function () math.ult(2, true) end,
+               "^[^:]+:%d+: bad argument #2 to 'ult' %(number expected, got boolean%)")
+else
+    is(math.ult, nil, "no math.ult")
+end
+
+done_testing()
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/308-io.t b/test/lua-Harness-tests/308-io.t
new file mode 100755
index 0000000..cdbcb83
--- /dev/null
+++ b/test/lua-Harness-tests/308-io.t
@@ -0,0 +1,397 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2020, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua Input/Output Library
+
+=head2 Synopsis
+
+    % prove 308-io.t
+
+=head2 Description
+
+Tests Lua Input/Output Library
+
+See section "Input and Output Facilities" in "Reference Manual"
+L<https://www.lua.org/manual/5.1/manual.html#5.7>,
+L<https://www.lua.org/manual/5.2/manual.html#6.8>,
+L<https://www.lua.org/manual/5.3/manual.html#6.8>,
+L<https://www.lua.org/manual/5.4/manual.html#6.8>
+
+=cut
+
+--]]
+
+require'tap'
+local profile = require'profile'
+local luajit21 = jit and (jit.version_num >= 20100 or jit.version:match'^RaptorJIT')
+local has_write51 = _VERSION == 'Lua 5.1' and (not profile.luajit_compat52 or ujit)
+local has_lines52 = _VERSION >= 'Lua 5.2' or profile.luajit_compat52
+local has_read52 = _VERSION >= 'Lua 5.2' or profile.luajit_compat52
+local has_read53 = _VERSION >= 'Lua 5.3' or luajit21
+local has_meta53 = _VERSION >= 'Lua 5.3'
+local has_meta54 = _VERSION >= 'Lua 5.4'
+
+local lua = arg[-3] or arg[-1]
+
+plan'no_plan'
+
+do -- stdin
+    like(io.stdin, '^file %(0?[Xx]?%x+%)$', "variable stdin")
+end
+
+do -- stdout
+    like(io.stdout, '^file %(0?[Xx]?%x+%)$', "variable stdout")
+end
+
+do -- stderr
+    like(io.stderr, '^file %(0?[Xx]?%x+%)$', "variable stderr")
+end
+
+do -- metatable
+    local f = io.tmpfile()
+    local mt = getmetatable(f)
+    type_ok(mt, 'table', "metatable")
+
+    type_ok(mt.__gc, 'function')
+    type_ok(mt.__tostring, 'function')
+    type_ok(mt.__index, 'table')
+
+    if has_meta53 then
+        is(mt.__name, 'FILE*')
+    else
+        is(mt.__name, nil)
+    end
+
+    if has_meta54 then
+        type_ok(mt.__close, 'function')
+        type_ok(mt.__index, 'table')
+        is(mt.close, nil)
+        is(mt.flush, nil)
+        is(mt.lines, nil)
+        is(mt.read, nil)
+        is(mt.seek, nil)
+        is(mt.setvbuf, nil)
+        is(mt.write, nil)
+    else
+        is(mt.__close, nil)
+        is(mt.__index, mt)
+        type_ok(mt.close, 'function')
+        type_ok(mt.flush, 'function')
+        type_ok(mt.lines, 'function')
+        type_ok(mt.read, 'function')
+        type_ok(mt.seek, 'function')
+        type_ok(mt.setvbuf, 'function')
+        type_ok(mt.write, 'function')
+    end
+
+    type_ok(mt.__index.close, 'function')
+    type_ok(mt.__index.flush, 'function')
+    type_ok(mt.__index.lines, 'function')
+    type_ok(mt.__index.read, 'function')
+    type_ok(mt.__index.seek, 'function')
+    type_ok(mt.__index.setvbuf, 'function')
+    type_ok(mt.__index.write, 'function')
+end
+
+do -- close
+    local r, msg = io.close(io.stderr)
+    is(r, nil, "close (std)")
+    is(msg, "cannot close standard file")
+end
+
+do -- flush
+    is(io.flush(), true, "function flush")
+end
+
+do -- open
+    os.remove('file-308.no')
+    local f, msg = io.open("file-308.no")
+    is(f, nil, "function open")
+    is(msg, "file-308.no: No such file or directory")
+
+    os.remove('file-308.txt')
+    f = io.open('file-308.txt', 'w')
+    f:write("file with text\n")
+    f:close()
+    f = io.open('file-308.txt')
+    like(f, '^file %(0?[Xx]?%x+%)$', "function open")
+
+    is(io.close(f), true, "function close")
+
+    error_like(function () io.close(f) end,
+               "^[^:]+:%d+: attempt to use a closed file",
+               "function close (closed)")
+
+    if _VERSION == 'Lua 5.1' then
+        todo("not with 5.1")
+    end
+    error_like(function () io.open('file-308.txt', 'baz') end,
+               "^[^:]+:%d+: bad argument #2 to 'open' %(invalid mode%)",
+               "function open (bad mode)")
+end
+
+do -- type
+    is(io.type("not a file"), nil, "function type")
+    local f = io.open('file-308.txt')
+    is(io.type(f), 'file')
+    like(tostring(f), '^file %(0?[Xx]?%x+%)$')
+    io.close(f)
+    is(io.type(f), 'closed file')
+    is(tostring(f), 'file (closed)')
+end
+
+do -- input
+    is(io.stdin, io.input(), "function input")
+    is(io.stdin, io.input(nil))
+    local f = io.stdin
+    like(io.input('file-308.txt'), '^file %(0?[Xx]?%x+%)$')
+    is(f, io.input(f))
+end
+
+do -- output
+    is(io.output(), io.stdout, "function output")
+    is(io.output(nil), io.stdout)
+    local f = io.stdout
+    like(io.output('output.new'), '^file %(0?[Xx]?%x+%)$')
+    is(f, io.output(f))
+    os.remove('output.new')
+end
+
+do -- popen
+    local r, f = pcall(io.popen, lua .. [[ -e "print 'standard output'"]])
+    if r then
+        is(io.type(f), 'file', "popen (read)")
+        is(f:read(), "standard output")
+        is(io.close(f), true)
+    else
+        diag("io.popen not supported")
+    end
+
+    r, f = pcall(io.popen, lua .. [[ -e "for line in io.lines() do print((line:gsub('e', 'a'))) end"]], 'w')
+    if r then
+        is(io.type(f), 'file', "popen (write)")
+        f:write("# hello\n") -- not tested : hallo
+        is(io.close(f), true)
+    else
+        diag("io.popen not supported")
+    end
+end
+
+do -- lines
+    for line in io.lines('file-308.txt') do
+        is(line, "file with text", "function lines(filename)")
+    end
+
+    error_like(function () io.lines('file-308.no') end,
+               "No such file or directory",
+               "function lines(no filename)")
+end
+
+do -- tmpfile
+    local  f = io.tmpfile()
+    is(io.type(f), 'file', "function tmpfile")
+    f:write("some text")
+    f:close()
+end
+
+do -- write
+    io.write() -- not tested
+    io.write('# text', 12, "\n") -- not tested :  # text12
+end
+
+do -- :close
+    local r, msg = io.stderr:close()
+    is(r, nil, "method close (std)")
+    is(msg, "cannot close standard file")
+
+    local f = io.open('file-308.txt')
+    is(f:close(), true, "method close")
+end
+
+do -- :flush
+    is(io.stderr:flush(), true, "method flush")
+
+    local f = io.open('file-308.txt')
+    f:close()
+    error_like(function () f:flush() end,
+               "^[^:]+:%d+: attempt to use a closed file",
+               "method flush (closed)")
+end
+
+do -- :read & :write
+    local f = io.open('file-308.txt')
+    f:close()
+    error_like(function () f:read() end,
+               "^[^:]+:%d+: attempt to use a closed file",
+               "method read (closed)")
+
+    f = io.open('file-308.txt')
+    local s = f:read()
+    is(s:len(), 14, "method read")
+    is(s, "file with text")
+    s = f:read()
+    is(s, nil)
+    f:close()
+
+    f = io.open('file-308.txt')
+    error_like(function () f:read('*z') end,
+               "^[^:]+:%d+: bad argument #1 to 'read' %(invalid %w+%)",
+               "method read (invalid)")
+    f:close()
+
+    f = io.open('file-308.txt')
+    local s1, s2 = f:read('*l', '*l')
+    is(s1:len(), 14, "method read *l")
+    is(s1, "file with text")
+    is(s2, nil)
+    f:close()
+
+    if has_read52 then
+        f = io.open('file-308.txt')
+        s1, s2 = f:read('*L', '*L')
+        is(s1:len(), 15, "method read *L")
+        is(s1, "file with text\n")
+        is(s2, nil)
+        f:close()
+    else
+        diag("no read *L")
+    end
+
+    f = io.open('file-308.txt')
+    local n1, n2 = f:read('*n', '*n')
+    is(n1, nil, "method read *n")
+    is(n2, nil)
+    f:close()
+
+    f = io.open('file-308.num', 'w')
+    f:write('1\n')
+    f:write('0xFF\n')
+    f:write(string.rep('012', 90) .. '\n')
+    f:close()
+
+    f = io.open('file-308.num')
+    n1, n2 = f:read('*n', '*n')
+    is(n1, 1, "method read *n")
+    is(n2, 255, "method read *n")
+    local n = f:read('*n')
+    if _VERSION < 'Lua 5.3' then
+        type_ok(n, 'number')
+    else
+        is(n, nil, "method read *n too long")
+    end
+    f:close()
+
+    os.remove('file-308.num') -- clean up
+
+    f = io.open('file-308.txt')
+    s = f:read('*a')
+    is(s:len(), 15, "method read *a")
+    is(s, "file with text\n")
+    f:close()
+
+    if has_read53 then
+        f = io.open('file-308.txt')
+        s = f:read('a')
+        is(s:len(), 15, "method read a")
+        is(s, "file with text\n")
+        f:close()
+    else
+        diag("* mandatory")
+    end
+
+    f = io.open('file-308.txt')
+    is(f:read(0), '', "method read number")
+    eq_array({f:read(5, 5, 15)}, {'file ', 'with ', "text\n"})
+    f:close()
+end
+
+do -- :lines
+    local f = io.open('file-308.txt')
+    for line in f:lines() do
+        is(line, "file with text", "method lines")
+    end
+    is(io.type(f), 'file')
+    f:close()
+    is(io.type(f), 'closed file')
+
+    if has_lines52 then
+        f = io.open('file-308.txt')
+        for two_char in f:lines(2) do
+            is(two_char, "fi", "method lines (with read option)")
+            break
+        end
+        f:close()
+    else
+        diag("no lines with option")
+    end
+end
+
+do -- :seek
+    local f = io.open('file-308.txt')
+    f:close()
+
+    error_like(function () f:seek('end', 0) end,
+               "^[^:]+:%d+: attempt to use a closed file",
+               "method seek (closed)")
+
+    f = io.open('file-308.txt')
+    error_like(function () f:seek('bad', 0) end,
+               "^[^:]+:%d+: bad argument #1 to 'seek' %(invalid option 'bad'%)",
+               "method seek (invalid)")
+
+    f = io.open('file-308.bin', 'w')
+    f:write('ABCDE')
+    f:close()
+    f = io.open('file-308.bin')
+    is(f:seek('end', 0), 5, "method seek")
+    f:close()
+    os.remove('file-308.bin') --clean up
+end
+
+do -- :setvbuf
+    local  f = io.open('file-308.txt')
+     is(f:setvbuf('no'), true, "method setvbuf 'no'")
+
+    is(f:setvbuf('full', 4096), true, "method setvbuf 'full'")
+
+    is(f:setvbuf('line', 132), true, "method setvbuf 'line'")
+    f:close()
+end
+
+os.remove('file-308.txt') -- clean up
+
+do -- :write
+    local  f = io.open('file-308.out', 'w')
+    f:close()
+    error_like(function () f:write('end') end,
+               "^[^:]+:%d+: attempt to use a closed file",
+               "method write (closed)")
+
+    f = io.open('file-308.out', 'w')
+    if has_write51 then
+        is(f:write('end'), true, "method write")
+    else
+        is(f:write('end'), f, "method write")
+    end
+    f:close()
+
+    os.remove('file-308.out') --clean up
+end
+
+done_testing()
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/309-os.t b/test/lua-Harness-tests/309-os.t
new file mode 100755
index 0000000..e42fb53
--- /dev/null
+++ b/test/lua-Harness-tests/309-os.t
@@ -0,0 +1,271 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2020, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua Operating System Library
+
+=head2 Synopsis
+
+    % prove 309-os.t
+
+=head2 Description
+
+Tests Lua Operating System Library
+
+See section "Operating System Facilities" in "Reference Manual"
+L<https://www.lua.org/manual/5.1/manual.html#5.8>,
+L<https://www.lua.org/manual/5.2/manual.html#6.9>,
+L<https://www.lua.org/manual/5.3/manual.html#6.9>,
+L<https://www.lua.org/manual/5.4/manual.html#6.9>
+
+=cut
+
+--]]
+
+require'tap'
+local profile = require'profile'
+local luajit20 = jit and (jit.version_num < 20100 and not jit.version:match'^RaptorJIT')
+local has_execute51 = _VERSION == 'Lua 5.1' and (not profile.luajit_compat52 or ujit)
+local lua = arg[-3] or arg[-1]
+
+plan'no_plan'
+
+do -- clock
+    local clk = os.clock()
+    type_ok(clk, 'number', "function clock")
+    ok(clk <= os.clock())
+end
+
+do -- date
+    local d = os.date('!*t', 0)
+    is(d.year, 1970, "function date")
+    is(d.month, 1)
+    is(d.day, 1)
+    is(d.hour, 0)
+    is(d.min, 0)
+    is(d.sec, 0)
+    is(d.wday, 5)
+    is(d.yday, 1)
+    is(d.isdst, false)
+
+    is(os.date('!%d/%m/%y %H:%M:%S', 0), '01/01/70 00:00:00', "function date")
+
+    like(os.date('%H:%M:%S'), '^%d%d:%d%d:%d%d', "function date")
+
+    if (_VERSION == 'Lua 5.1' and not jit) or luajit20 then
+        todo("not with 5.1")
+    end
+    is(os.date('%Oy', 0), '70')
+
+    if _VERSION == 'Lua 5.1' then
+        todo("not with 5.1")
+    end
+    error_like(function () os.date('%Ja', 0) end,
+               "^[^:]+:%d+: bad argument #1 to 'date' %(invalid conversion specifier '%%Ja'%)",
+               "function date (invalid)")
+end
+
+do -- difftime
+    is(os.difftime(1234, 1200), 34, "function difftime")
+end
+
+do -- execute
+    if has_execute51 then
+        local res = os.execute()
+        is(res, 1, "function execute -> shell is available")
+
+        ok(os.execute('__IMPROBABLE__') > 0, "function execute __IMPROBABLE__")
+
+        local cmd = lua .. [[ -e "print '# hello from external Lua'"]]
+        is(os.execute(cmd), 0, "function execute")
+    else
+        local res = os.execute()
+        is(res, true, "function execute -> shell is available")
+
+        local r, s, n = os.execute('__IMPROBABLE__')
+        is(r, nil, "function execute __IMPROBABLE__")
+        is(s, 'exit')
+        type_ok(n, 'number')
+
+        local cmd = lua .. [[ -e "print '# hello from external Lua'"]]
+        r, s, n = os.execute(cmd)
+        is(r, true, "function execute")
+        is(s, 'exit')
+        is(n, 0)
+    end
+end
+
+do -- exit called with execute
+    if has_execute51 then
+        local cmd = lua .. [[ -e "print '# hello from external Lua'; os.exit(2)"]]
+        ok(os.execute(cmd) > 0, "function exit called with execute")
+    else
+        local cmd = lua .. [[ -e "print '# hello from external Lua'; os.exit(2)"]]
+        local r, s, n = os.execute(cmd)
+        is(r, nil, "function exit called with execute")
+        is(s, 'exit')
+        is(n, 2, "exit value")
+
+        cmd = lua .. [[ -e "print '# hello from external Lua'; os.exit(false)"]]
+        r, s, n = os.execute(cmd)
+        is(r, nil, "function exit called with execute")
+        is(s, 'exit')
+        is(n, 1, "exit value")
+
+        cmd = lua .. [[ -e "print '# hello from external Lua'; os.exit(true, true)"]]
+        r, s, n = os.execute(cmd)
+        is(r, true, "exit called with execute")
+        is(s, 'exit')
+        is(n, 0, "exit value")
+    end
+end
+
+do -- exit called with popen
+    local cmd = lua .. [[ -e "print 'reached'; os.exit(); print 'not reached';"]]
+    local res, f = pcall(io.popen, cmd)
+    if res then
+        is(f:read'*l', 'reached', "exit called with popen")
+        is(f:read'*l', nil)
+        if has_execute51 then
+            local code = f:close()
+            is(code, true, "exit code")
+        else
+            local r, s, n = f:close()
+            is(r, true)
+            is(s, 'exit', "exit code")
+            is(n, 0, "exit value")
+        end
+    else
+        diag("io.popen not supported")
+    end
+
+    cmd = lua .. [[ -e "print 'reached'; os.exit(3); print 'not reached';"]]
+    res, f = pcall(io.popen, cmd)
+    if res then
+        is(f:read'*l', 'reached', "exit called with popen")
+        is(f:read'*l', nil)
+        if has_execute51 then
+            local code = f:close()
+            is(code, true, "exit code")
+        else
+            local r, s, n = f:close()
+            is(r, nil)
+            is(s, 'exit', "exit code")
+            is(n, 3, "exit value")
+        end
+    else
+        diag("io.popen not supported")
+    end
+end
+
+do -- getenv
+    is(os.getenv('__IMPROBABLE__'), nil, "function getenv")
+
+    local user = os.getenv('LOGNAME') or os.getenv('USERNAME')
+    type_ok(user, 'string', "function getenv")
+end
+
+do -- remove
+    local f = io.open('file-309.rm', 'w')
+    f:write("file to remove")
+    f:close()
+    local r = os.remove("file-309.rm")
+    is(r, true, "function remove")
+
+    local msg
+    r, msg = os.remove('file-309.rm')
+    is(r, nil, "function remove")
+    like(msg, '^file%-309%.rm: No such file or directory')
+end
+
+do -- rename
+    local f = io.open('file-309.old', 'w')
+    f:write("file to rename")
+    f:close()
+    os.remove('file-309.new')
+    local r = os.rename('file-309.old', 'file-309.new')
+    is(r, true, "function rename")
+    os.remove('file-309.new') -- clean up
+
+    local msg
+    r, msg = os.rename('file-309.old', 'file-309.new')
+    is(r, nil, "function rename")
+    like(msg, 'No such file or directory')
+end
+
+do -- setlocale
+    is(os.setlocale('C', 'all'), 'C', "function setlocale")
+    is(os.setlocale(), 'C')
+    is(os.setlocale('unk_loc', 'all'), nil, "function setlocale (unknown locale)")
+end
+
+do -- time
+    like(os.time(), '^%d+%.?%d*$', "function time")
+    like(os.time(nil), '^%d+%.?%d*$', "function time")
+    like(os.time({
+        sec = 0,
+        min = 0,
+        hour = 0,
+        day = 1,
+        month = 1,
+        year = 2000,
+        isdst = false,
+    }), '^946%d+$', "function time")
+
+    error_like(function () os.time{} end,
+               "^[^:]+:%d+: field '%w+' missing in date table",
+               "function time (missing field)")
+
+    error_like(function () os.time({ day = 'bad', year = 'bad' }) end,
+               "^[^:]+:%d+: field '%w+'",
+               "function time (bad field)")
+
+    if _VERSION < 'Lua 5.3' then
+        todo("only with integer")
+    end
+    error_like(function () os.time({ day = 1.5, year = 1.5 }) end,
+               "^[^:]+:%d+: field '%w+' is not an integer",
+               "function time (not integer)")
+
+    if string.packsize and string.packsize('l') == 8 then
+        skip('64bit platforms')
+    else
+        if _VERSION < 'Lua 5.3' then
+            todo"only with 5.3"
+        end
+        error_like(function () os.time({
+            sec = 0,
+            min = 0,
+            hour = 0,
+            day = 1,
+            month = 1,
+            year = 1000,
+            isdst = false,
+        }) end,
+                   "^[^:]+:%d+: time result cannot be represented in this installation",
+                   "function time (invalid)")
+    end
+end
+
+do -- tmpname
+    local fname = os.tmpname()
+    type_ok(fname, 'string', "function tmpname")
+    ok(fname ~= os.tmpname())
+end
+
+done_testing()
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/310-debug.t b/test/lua-Harness-tests/310-debug.t
new file mode 100755
index 0000000..f78af03
--- /dev/null
+++ b/test/lua-Harness-tests/310-debug.t
@@ -0,0 +1,322 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2020, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua Debug Library
+
+=head2 Synopsis
+
+    % prove 310-debug.t
+
+=head2 Description
+
+Tests Lua Debug Library
+
+See section "The Debug Library" in "Reference Manual"
+L<https://www.lua.org/manual/5.1/manual.html#5.9>,
+L<https://www.lua.org/manual/5.2/manual.html#6.10>,
+L<https://www.lua.org/manual/5.3/manual.html#6.10>,
+L<https://www.lua.org/manual/5.4/manual.html#6.10>
+
+=cut
+
+]]
+
+require 'tap'
+local profile = require'profile'
+local has_getfenv = _VERSION == 'Lua 5.1'
+local has_gethook54 = _VERSION >= 'Lua 5.4'
+local has_getlocal52 = _VERSION >= 'Lua 5.2' or profile.luajit_compat52
+local has_getuservalue = _VERSION >= 'Lua 5.2' or profile.luajit_compat52
+local has_getuservalue54 = _VERSION >= 'Lua 5.4'
+local has_setcstacklimit = _VERSION >= 'Lua 5.4'
+local has_setmetatable52 = _VERSION >= 'Lua 5.2' or (profile.luajit_compat52 and not ujit)
+local has_upvalueid = _VERSION >= 'Lua 5.2' or jit
+local has_upvaluejoin = _VERSION >= 'Lua 5.2' or jit
+
+local debug = require 'debug'
+
+if not debug then
+    skip_all("no debug")
+end
+
+plan'no_plan'
+
+-- getfenv
+if has_getfenv then
+    is(debug.getfenv(3.14), nil, "function getfenv")
+    local function f () end
+    type_ok(debug.getfenv(f), 'table')
+    is(debug.getfenv(f), _G)
+    type_ok(debug.getfenv(print), 'table')
+    is(debug.getfenv(print), _G)
+
+    local a = coroutine.create(function () return 1 end)
+    type_ok(debug.getfenv(a), 'table', "function getfenv (thread)")
+    is(debug.getfenv(a), _G)
+else
+    is(debug.getfenv, nil, "no debug.getfenv (removed)")
+end
+
+do -- getinfo
+    local info = debug.getinfo(is)
+    type_ok(info, 'table', "function getinfo (function)")
+    is(info.func, is, " .func")
+
+    info = debug.getinfo(is, 'L')
+    type_ok(info, 'table', "function getinfo (function, opt)")
+    type_ok(info.activelines, 'table')
+
+    info = debug.getinfo(1)
+    type_ok(info, 'table', "function getinfo (level)")
+    like(info.func, "^function: [0]?[Xx]?%x+", " .func")
+
+    is(debug.getinfo(12), nil, "function getinfo (too depth)")
+
+    error_like(function () debug.getinfo('bad') end,
+               "bad argument #1 to 'getinfo' %(.- expected",
+               "function getinfo (bad arg)")
+
+    error_like(function () debug.getinfo(is, 'X') end,
+               "bad argument #2 to 'getinfo' %(invalid option%)",
+               "function getinfo (bad opt)")
+end
+
+do -- getlocal
+    local name, value = debug.getlocal(0, 1)
+    type_ok(name, 'string', "function getlocal (level)")
+    is(value, 0)
+
+    error_like(function () debug.getlocal(42, 1) end,
+               "bad argument #1 to 'getlocal' %(level out of range%)",
+               "function getlocal (out of range)")
+
+    if has_getlocal52 then
+        name, value = debug.getlocal(like, 1)
+        type_ok(name, 'string', "function getlocal (func)")
+        is(value, nil)
+    else
+        diag("no getlocal with function")
+    end
+end
+
+do -- getmetatable
+    local t = {}
+    is(debug.getmetatable(t), nil, "function getmetatable")
+    local t1 = {}
+    debug.setmetatable(t, t1)
+    is(debug.getmetatable(t), t1)
+
+    local a = true
+    is(debug.getmetatable(a), nil)
+    debug.setmetatable(a, t1)
+    is(debug.getmetatable(t), t1)
+
+    a = 3.14
+    is(debug.getmetatable(a), nil)
+    debug.setmetatable(a, t1)
+    is(debug.getmetatable(t), t1)
+end
+
+do -- getregistry
+    local reg = debug.getregistry()
+    type_ok(reg, 'table', "function getregistry")
+    type_ok(reg._LOADED, 'table')
+end
+
+do -- getupvalue
+    local name = debug.getupvalue(plan, 1)
+    type_ok(name, 'string', "function getupvalue")
+end
+
+do -- gethook
+    debug.sethook()
+    local hook, mask, count
+    if has_gethook54 then
+        hook = debug.gethook()
+        is(hook, nil, "function gethook")
+    else
+        hook, mask, count = debug.gethook()
+        is(hook, nil, "function gethook")
+        is(mask, '')
+        is(count, 0)
+    end
+    local function f () end
+    debug.sethook(f, 'c', 42)
+    hook , mask, count = debug.gethook()
+    is(hook, f, "function gethook")
+    is(mask, 'c')
+    is(count, 42)
+
+    local co = coroutine.create(function () print "thread" end)
+    hook = debug.gethook(co)
+    if jit then
+        type_ok(hook, 'function', "function gethook(thread)")
+    else
+        is(hook, nil, "function gethook(thread)")
+    end
+end
+
+do -- setlocal
+    local name = debug.setlocal(0, 1, 0)
+    type_ok(name, 'string', "function setlocal (level)")
+
+    name = debug.setlocal(0, 42, 0)
+    is(name, nil, "function setlocal (level)")
+
+    error_like(function () debug.setlocal(42, 1, true) end,
+               "bad argument #1 to 'setlocal' %(level out of range%)",
+               "function setlocal (out of range)")
+end
+
+-- setcstacklimit
+if has_setcstacklimit then
+    type_ok(debug.setcstacklimit(200), 'number', "function setcstacklimit")
+    is(debug.setcstacklimit(1000), 200)
+
+    error_like(function () debug.setcstacklimit('bad') end,
+               "^[^:]+:%d+: bad argument #1 to 'setcstacklimit' %(number expected, got string%)",
+               "function setcstacklimit (bad arg)")
+else
+    is(debug.setcstacklimit, nil, "no debug.setcstacklimit")
+end
+
+-- setfenv
+if has_getfenv then
+    local t = {}
+    local function f () end
+    is(debug.setfenv(f, t), f, "function setfenv")
+    type_ok(debug.getfenv(f), 'table')
+    is(debug.getfenv(f), t)
+    is(debug.setfenv(print, t), print)
+    type_ok(debug.getfenv(print), 'table')
+    is(debug.getfenv(print), t)
+
+    t = {}
+    local a = coroutine.create(function () return 1 end)
+    is(debug.setfenv(a, t), a, "function setfenv (thread)")
+    type_ok(debug.getfenv(a), 'table')
+    is(debug.getfenv(a), t)
+
+    error_like(function () t = {}; debug.setfenv(t, t) end,
+               "^[^:]+:%d+: 'setfenv' cannot change environment of given object",
+               "function setfenv (forbidden)")
+else
+    is(debug.setfenv, nil, "no debug.setfenv (removed)")
+end
+
+do -- setmetatable
+    local t = {}
+    local t1 = {}
+    if has_setmetatable52 then
+        is(debug.setmetatable(t, t1), t, "function setmetatable")
+    else
+        is(debug.setmetatable(t, t1), true, "function setmetatable")
+    end
+    is(getmetatable(t), t1)
+
+    error_like(function () debug.setmetatable(t, true) end,
+               "^[^:]+:%d+: bad argument #2 to 'setmetatable' %(nil or table expected")
+end
+
+do -- setupvalue
+    local r, tb = pcall(require, 'Test.Builder')
+    local value = r and tb:new() or {}
+    local name = debug.setupvalue(plan, 1, value)
+    type_ok(name, 'string', "function setupvalue")
+
+    name = debug.setupvalue(plan, 42, true)
+    is(name, nil)
+end
+
+-- getuservalue / setuservalue
+if has_getuservalue54 then
+    local u = io.tmpfile()      -- lua_newuserdatauv(L, sizeof(LStream), 0);
+    is(debug.getuservalue(u, 0), nil, "function getuservalue")
+    is(debug.getuservalue(true), nil)
+
+    error_like(function () debug.getuservalue(u, 'foo') end,
+               "^[^:]+:%d+: bad argument #2 to 'getuservalue' %(number expected, got string%)")
+
+    local data = {}
+    is(debug.setuservalue(u, data, 42), nil, "function setuservalue")
+
+    error_like(function () debug.setuservalue({}, data) end,
+               "^[^:]+:%d+: bad argument #1 to 'setuservalue' %(userdata expected, got table%)")
+
+    error_like(function () debug.setuservalue(u, data, 'foo') end,
+               "^[^:]+:%d+: bad argument #3 to 'setuservalue' %(number expected, got string%)")
+elseif has_getuservalue then
+    local u = io.tmpfile()
+    local old = debug.getuservalue(u)
+    if jit then
+        type_ok(old, 'table', "function getuservalue")
+    else
+        is(old, nil, "function getuservalue")
+    end
+    is(debug.getuservalue(true), nil)
+
+    local data = {}
+    local r = debug.setuservalue(u, data)
+    is(r, u, "function setuservalue")
+    is(debug.getuservalue(u), data)
+    r = debug.setuservalue(u, old)
+    is(debug.getuservalue(u), old)
+
+    error_like(function () debug.setuservalue({}, data) end,
+               "^[^:]+:%d+: bad argument #1 to 'setuservalue' %(userdata expected, got table%)")
+else
+    is(debug.getuservalue, nil, "no getuservalue")
+    is(debug.setuservalue, nil, "no setuservalue")
+end
+
+do -- traceback
+    like(debug.traceback(), "^stack traceback:\n", "function traceback")
+
+    like(debug.traceback("message\n"), "^message\n\nstack traceback:\n", "function traceback with message")
+
+    like(debug.traceback(false), "false", "function traceback")
+end
+
+-- upvalueid
+if has_upvalueid then
+    local id = debug.upvalueid(plan, 1)
+    type_ok(id, 'userdata', "function upvalueid")
+else
+    is(debug.upvalueid, nil, "no upvalueid")
+end
+
+-- upvaluejoin
+if has_upvaluejoin and jit then
+    diag("jit upvaluejoin")
+    -- TODO
+elseif has_upvaluejoin then
+    debug.upvaluejoin(pass, 1, fail, 1)
+
+    error_like(function () debug.upvaluejoin(true, 1, nil, 1) end,
+               "bad argument #1 to 'upvaluejoin' %(function expected, got boolean%)",
+               "function upvaluejoin (bad arg)")
+
+    error_like(function () debug.upvaluejoin(pass, 1, true, 1) end,
+               "bad argument #3 to 'upvaluejoin' %(function expected, got boolean%)",
+               "function upvaluejoin (bad arg)")
+else
+    is(debug.upvaluejoin, nil, "no upvaluejoin")
+end
+
+done_testing()
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/311-bit32.t b/test/lua-Harness-tests/311-bit32.t
new file mode 100755
index 0000000..7023906
--- /dev/null
+++ b/test/lua-Harness-tests/311-bit32.t
@@ -0,0 +1,127 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2010-2018, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua Bitwise Library
+
+=head2 Synopsis
+
+    % prove 311-bit32.t
+
+=head2 Description
+
+Tests Lua Bitwise Library
+
+This library was introduced in Lua 5.2 and deprecated in Lua 5.3.
+
+See section "Bitwise Operations" in "Reference Manual"
+L<https://www.lua.org/manual/5.2/manual.html#6.7>
+
+=cut
+
+--]]
+
+require 'tap'
+local profile = require'profile'
+local has_bit32 = _VERSION == 'Lua 5.2' or profile.compat52 or profile.has_bit32
+
+if not bit32 then
+    plan(1)
+    nok(has_bit32, "no has_bit32")
+    os.exit(0)
+end
+
+plan(20)
+
+do -- arshift
+    is(bit32.arshift(0x06, 1), 0x03, "function arshift")
+    is(bit32.arshift(-3, 1), bit32.arshift(-6, 2), "function arshift")
+end
+
+do -- band
+    is(bit32.band(0x01, 0x03, 0x07), 0x01, "function band")
+end
+
+do -- bnot
+    if string.pack and #string.pack('n', 0) == 4 then
+        is(bit32.bnot(0x03), (-1 - 0x03), "function bnot")
+    else
+        is(bit32.bnot(0x03), (-1 - 0x03) % 2^32, "function bnot")
+    end
+end
+
+do -- bor
+    is(bit32.bor(0x01, 0x03, 0x07), 0x07, "function bor")
+end
+
+do -- btest
+    is(bit32.btest(0x01), true, "function btest")
+    is(bit32.btest(0x00), false, "function btest")
+end
+
+do -- bxor
+    is(bit32.bxor(0x01, 0x03, 0x07), 0x05, "function bxor")
+end
+
+do -- extract
+    is(bit32.extract(0xFFFF, 3, 3), 0x07, "function extract")
+
+    error_like(function () bit32.extract(0xFFFF, 99) end,
+               "^[^:]+:%d+: trying to access non%-existent bits",
+               "function extract (non-existent bits)")
+
+    error_like(function () bit32.extract(0xFFFF, -3) end,
+               "^[^:]+:%d+: bad argument #2 to 'extract' %(field cannot be negative%)",
+               "function extract (negatif field)")
+
+    error_like(function () bit32.extract(0xFFFF, 3, -3) end,
+               "^[^:]+:%d+: bad argument #3 to 'extract' %(width must be positive%)",
+               "function extract (negative width)")
+end
+
+do -- replace
+    is(bit32.replace(0x0000, 0xFFFF, 3, 3), 0x38, "function replace")
+
+    error_like(function () bit32.replace(0x0000, 0xFFFF, 99) end,
+               "^[^:]+:%d+: trying to access non%-existent bits",
+               "function replace (non-existent bits)")
+
+    error_like(function () bit32.replace(0x0000, 0xFFFF, -3) end,
+               "^[^:]+:%d+: bad argument #3 to 'replace' %(field cannot be negative%)",
+               "function replace (negatif field)")
+
+    error_like(function () bit32.replace(0x0000, 0xFFFF, 3, -3) end,
+               "^[^:]+:%d+: bad argument #4 to 'replace' %(width must be positive%)",
+               "function replace (negative width)")
+end
+
+do -- lrotate
+    is(bit32.lrotate(0x03, 2), 0x0C, "function lrotate")
+end
+
+do -- lshift
+    is(bit32.lshift(0x03, 2), 0x0C, "function lshift")
+end
+
+do -- rrotate
+    is(bit32.rrotate(0x06, 1), 0x03, "function rrotate")
+end
+
+do -- rshift
+    is(bit32.rshift(0x06, 1), 0x03, "function rshift")
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/314-regex.t b/test/lua-Harness-tests/314-regex.t
new file mode 100755
index 0000000..ad4554c
--- /dev/null
+++ b/test/lua-Harness-tests/314-regex.t
@@ -0,0 +1,222 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2018, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua Regex Compiler
+
+=head2 Synopsis
+
+    % prove 314-regex.t
+
+=head2 Description
+
+Tests Lua Regex
+
+Individual tests are stored in the C<rx_*> files in the same directory;
+There is one test per line: each test consists of the following
+columns (separated by one *or more* tabs):
+
+=over 4
+
+=item pattern
+
+The Lua regex to test.
+
+=item target
+
+The string that will be matched against the pattern. Use '' to indicate
+an empty string.
+
+=item result
+
+The expected result of the match.
+
+=item description
+
+Description of the test.
+
+=back
+
+=cut
+
+--]]
+
+require'tap'
+local loadstring = loadstring or load
+
+plan(162)
+
+local test_files = {
+    'rx_captures',
+    'rx_charclass',
+    'rx_metachars',
+}
+
+local todo_info = {}
+
+if _VERSION == 'Lua 5.1' then
+    if not jit then
+        todo_info[130] = "printable. %g"
+        --todo_info[131] = "printable. %g"
+        todo_info[132] = "not printable. %G"
+        --todo_info[133] = "not printable. %G"
+    end
+    todo_info[147] = "embedded nul. \\0"
+    todo_info[149] = "embedded nul. \\0"
+    todo_info[151] = "embedded nul. [^\\0]"
+    todo_info[153] = "embedded nul. [^\\0]"
+end
+
+local function split (line)
+    local pattern, target, result, desc = '', '', '', ''
+    local idx = 1
+    local c = line:sub(idx, idx)
+    while (c ~= '' and c ~= "\t") do
+        if (c == '"') then
+            pattern = pattern .. "\\\""
+        else
+            pattern = pattern .. c
+        end
+        idx = idx + 1
+        c = line:sub(idx, idx)
+    end
+    if pattern == "''" then
+        pattern = ''
+    end
+    while (c ~= '' and c == "\t") do
+        idx = idx + 1
+        c = line:sub(idx, idx)
+    end
+    while (c ~= '' and c ~= "\t") do
+        if (c == '"') then
+            target = target .. "\\\""
+        else
+            target = target .. c
+        end
+        idx = idx + 1
+        c = line:sub(idx, idx)
+    end
+    if target == "''" then
+        target = ''
+    end
+    while (c ~= '' and c == "\t") do
+        idx = idx + 1
+        c = line:sub(idx, idx)
+    end
+    while (c ~= '' and c ~= "\t") do
+        if c == "\\" then
+            idx = idx + 1
+            c = line:sub(idx, idx)
+            if     c == 'f' then
+                result = result .. "\f"
+            elseif c == 'n' then
+                result = result .. "\n"
+            elseif c == 'r' then
+                result = result .. "\r"
+            elseif c == 't' then
+                result = result .. "\t"
+            elseif c == '0' then
+                idx = idx + 1
+                c = line:sub(idx, idx)
+                if     c == '1' then
+                    result = result .. "\01"
+                elseif c == '2' then
+                    result = result .. "\02"
+                elseif c == '3' then
+                    result = result .. "\03"
+                elseif c == '4' then
+                    result = result .. "\04"
+                else
+                    result = result .. "\0" .. c
+                end
+            elseif c == "\t" then
+                result = result .. "\\"
+            else
+                result = result .. "\\" .. c
+            end
+        else
+            result = result .. c
+        end
+        idx = idx + 1
+        c = line:sub(idx, idx)
+    end
+    if result == "''" then
+        result = ''
+    end
+    while (c ~= '' and c == "\t") do
+        idx = idx + 1
+        c = line:sub(idx, idx)
+    end
+    while (c ~= '' and c ~= "\t") do
+        desc = desc .. c
+        idx = idx + 1
+        c = line:sub(idx, idx)
+    end
+    return pattern, target, result, desc
+end
+
+local test_number = 0
+local dirname = arg[0]:sub(1, arg[0]:find'314' -1)
+for _, filename in ipairs(test_files) do
+    local f, msg = io.open(dirname .. filename, 'r')
+    if f == nil then
+        diag(msg)
+        break
+    else
+        for line in f:lines() do
+            if line:len() == 0 then
+                break
+            end
+            local pattern, target, result, desc = split(line)
+            test_number = test_number + 1
+            if todo_info[test_number] then
+                todo(todo_info[test_number])
+            end
+            local code = [[
+                    local t = {string.match("]] .. target .. [[", "]] .. pattern .. [[")}
+                    if #t== 0 then
+                        return 'nil'
+                    else
+                        for i = 1, #t do
+                            t[i] = tostring(t[i])
+                        end
+                        return table.concat(t, "\t")
+                    end
+            ]]
+            local compiled
+            compiled, msg = loadstring(code)
+            if not compiled then
+                error("can't compile : " .. code .. "\n" .. msg)
+            end
+            if result:sub(1, 1) == '/' then
+                pattern = result:sub(2, result:len() - 1)
+                error_like(compiled, pattern, desc)
+            else
+                local r, out
+                r, msg = pcall(function () out = compiled() end)
+                if r then
+                    is(out, result, desc)
+                else
+                    fail(desc)
+                    diag(msg)
+                end
+            end
+        end
+        f:close()
+    end
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/320-stdin.t b/test/lua-Harness-tests/320-stdin.t
new file mode 100755
index 0000000..36528e8
--- /dev/null
+++ b/test/lua-Harness-tests/320-stdin.t
@@ -0,0 +1,133 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2018, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 Lua Library
+
+=head2 Synopsis
+
+    % prove 320-stdin.t
+
+=head2 Description
+
+Tests Lua Basic & IO Libraries with stdin
+
+=cut
+
+--]]
+
+require'tap'
+
+local lua = arg[-3] or arg[-1]
+
+if not pcall(io.popen, lua .. [[ -e "a=1"]]) then
+    skip_all "io.popen not supported"
+end
+
+plan(12)
+
+do
+    local f = io.open('lib-320.lua', 'w')
+    f:write[[
+function norm (x, y)
+    return (x^2 + y^2)^0.5
+end
+
+function twice (x)
+    return 2*x
+end
+]]
+    f:close()
+
+    local cmd = lua .. [[ -e "dofile(); n = norm(3.4, 1.0); print(twice(n))" < lib-320.lua]]
+    f = io.popen(cmd)
+    like(f:read'*l', '^7%.088', "function dofile (stdin)")
+    f:close()
+
+    os.remove('lib-320.lua') -- clean up
+end
+
+do
+    local f = io.open('foo-320.lua', 'w')
+    f:write[[
+function foo (x)
+    return x
+end
+]]
+    f:close()
+
+    local cmd = lua .. [[ -e "f = loadfile(); print(foo); f(); print(foo('ok'))" < foo-320.lua]]
+    f = io.popen(cmd)
+    is(f:read'*l', 'nil', "function loadfile (stdin)")
+    is(f:read'*l', 'ok')
+    f:close()
+
+    os.remove('foo-320.lua') -- clean up
+end
+
+do
+    local f = io.open('file-320.txt', 'w')
+    f:write("file with text\n")
+    f:close()
+
+    local cmd = lua .. [[ -e "print(io.read'*l'); print(io.read'*l'); print(io.type(io.stdin))" < file-320.txt]]
+    f = io.popen(cmd)
+    is(f:read'*l', 'file with text', "function io.read *l")
+    is(f:read'*l', 'nil')
+    is(f:read'*l', 'file')
+    f:close()
+
+    cmd = lua .. [[ -e "for line in io.lines() do print(line) end" < file-320.txt]]
+    f = io.popen(cmd)
+    is(f:read'*l', 'file with text', "function io.lines")
+    is(f:read'*l', nil)
+    f:close()
+
+    os.remove('file-320.txt') -- clean up
+end
+
+do
+    local f = io.open('number-320.txt', 'w')
+    f:write("6.0     -3.23   15e3\n")
+    f:write("4.3     234     1000001\n")
+    f:close()
+
+    local cmd = lua .. [[ -e "while true do local n1, n2, n3 = io.read('*number', '*number', '*number'); if not n1 then break end; print(math.max(n1, n2, n3)) end" < number-320.txt]]
+    f = io.popen(cmd)
+    like(f:read'*l', '15000%.?', "function io:read *number")
+    is(f:read'*l', '1000001')
+    f:close()
+
+    os.remove('number-320.txt') -- clean up
+end
+
+do
+    local f = io.open('dbg-320.txt', 'w')
+    f:write("print 'ok'\n")
+    f:write("error 'dbg'\n")
+    f:write("cont\n")
+    f:close()
+
+    local cmd = lua .. [[ -e "debug.debug()" < dbg-320.txt]]
+    f = io.popen(cmd)
+    is(f:read'*l', 'ok', "function debug.debug")
+    is(f:read'*l', nil)
+    f:close()
+
+    os.remove('dbg-320.txt') -- clean up
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/401-bitop.t b/test/lua-Harness-tests/401-bitop.t
new file mode 100755
index 0000000..f95aebf
--- /dev/null
+++ b/test/lua-Harness-tests/401-bitop.t
@@ -0,0 +1,106 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2018, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 BitOp Library
+
+=head2 Synopsis
+
+    % prove 401-bitop.t
+
+=head2 Description
+
+See L<http://bitop.luajit.org/>.
+
+=cut
+
+--]]
+
+require 'tap'
+
+if not jit then
+    skip_all("only with LuaJIT")
+end
+
+plan(29)
+
+is(package.loaded.bit, _G.bit, "package.loaded")
+is(require'bit', bit, "require")
+
+do -- arshift
+    is(bit.arshift(256, 8), 1, "function arshift")
+    is(bit.arshift(-256, 8), -1)
+end
+
+do -- band
+    is(bit.band(0x12345678, 0xff), 0x00000078, "function band")
+end
+
+do -- bnot
+    is(bit.bnot(0), -1, "function bnot")
+    is(bit.bnot(-1), 0)
+    is(bit.bnot(0xffffffff), 0)
+end
+
+do -- bor
+    is(bit.bor(1, 2, 4, 8), 15, "function bor")
+end
+
+do -- bswap
+    is(bit.bswap(0x12345678), 0x78563412, "function bswap")
+    is(bit.bswap(0x78563412), 0x12345678)
+end
+
+do -- bxor
+    is(bit.bxor(0xa5a5f0f0, 0xaa55ff00), 0x0ff00ff0, "function bxor")
+end
+
+do -- lshift
+    is(bit.lshift(1, 0), 1, "function lshift")
+    is(bit.lshift(1, 8), 256)
+    is(bit.lshift(1, 40), 256)
+    is(bit.lshift(0x87654321, 12), 0x54321000)
+end
+
+do -- rol
+    is(bit.rol(0x12345678, 12), 0x45678123, "function rol")
+end
+
+do -- ror
+    is(bit.ror(0x12345678, 12), 0x67812345, "function ror")
+end
+
+do -- rshift
+    is(bit.rshift(256, 8), 1, "function rshift")
+    is(bit.rshift(-256, 8), 16777215)
+    is(bit.rshift(0x87654321, 12), 0x00087654)
+end
+
+do -- tobit
+    is(bit.tobit(0xffffffff + 1), 0, "function tobit")
+    is(bit.tobit(2^40 + 1234), 1234)
+end
+
+do -- tohex
+    is(bit.tohex(1), '00000001', "function tohex")
+    is(bit.tohex(-1), 'ffffffff')
+    is(bit.tohex(0xffffffff), 'ffffffff')
+    is(bit.tohex(-1, -8), 'FFFFFFFF')
+    is(bit.tohex(0x21, 4), '0021')
+    is(bit.tohex(0x87654321, 4), '4321')
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/402-ffi.t b/test/lua-Harness-tests/402-ffi.t
new file mode 100755
index 0000000..a2e32a5
--- /dev/null
+++ b/test/lua-Harness-tests/402-ffi.t
@@ -0,0 +1,142 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2018, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 FFI Library
+
+=head2 Synopsis
+
+    % prove 402-ffi.t
+
+=head2 Description
+
+See L<http://luajit.org/ext_ffi.html>.
+
+=cut
+
+--]]
+
+require 'tap'
+
+if not jit then
+    skip_all("only with LuaJIT")
+end
+
+if not pcall(require, 'ffi') then
+    plan(2)
+    is(_G.ffi, nil, "no FFI")
+    is(package.loaded.ffi, nil)
+    os.exit(0)
+end
+
+plan(33)
+
+is(_G.ffi, nil, "ffi not loaded by default")
+ffi = require'ffi'
+is(package.loaded.ffi, ffi, "package.loaded")
+is(require'ffi', ffi, "require")
+
+do -- C
+    type_ok(ffi.C, 'userdata', 'C')
+end
+
+do -- abi
+    type_ok(ffi.abi('32bit'), 'boolean', "abi")
+    type_ok(ffi.abi('64bit'), 'boolean')
+    type_ok(ffi.abi('le'), 'boolean')
+    type_ok(ffi.abi('be'), 'boolean')
+    type_ok(ffi.abi('fpu'), 'boolean')
+    type_ok(ffi.abi('softfp'), 'boolean')
+    type_ok(ffi.abi('hardfp'), 'boolean')
+    type_ok(ffi.abi('eabi'), 'boolean')
+    type_ok(ffi.abi('win'), 'boolean')
+    is(ffi.abi('bad'), false)
+    is(ffi.abi(0), false)
+
+    error_like(function () ffi.abi(true) end,
+               "^[^:]+:%d+: bad argument #1 to 'abi' %(string expected, got boolean%)",
+               "function unpack missing size")
+end
+
+do -- alignof
+    type_ok(ffi.alignof, 'function', "alignof")
+end
+
+do -- arch
+    is(ffi.arch, jit.arch, "alias arch")
+end
+
+do -- cast
+    type_ok(ffi.cast, 'function', "cast")
+end
+
+do -- cdef
+    type_ok(ffi.cdef, 'function', "cdef")
+end
+
+do -- copy
+    type_ok(ffi.copy, 'function', "copy")
+end
+
+do -- errno
+    type_ok(ffi.errno, 'function', "errno")
+end
+
+do -- fill
+    type_ok(ffi.fill, 'function', "fill")
+end
+
+do -- gc
+    type_ok(ffi.gc, 'function', "gc")
+end
+
+do -- istype
+    type_ok(ffi.istype, 'function', "istype")
+end
+
+do -- load
+    type_ok(ffi.load, 'function', "load")
+end
+
+do -- metatype
+    type_ok(ffi.metatype, 'function', "metatype")
+end
+
+do -- new
+    type_ok(ffi.new, 'function', "new")
+end
+
+do -- offsetof
+    type_ok(ffi.offsetof, 'function', "offsetof")
+end
+
+do -- os
+    is(ffi.os, jit.os, "alias os")
+end
+
+do -- sizeof
+    type_ok(ffi.sizeof, 'function', "sizeof")
+end
+
+do -- string
+    type_ok(ffi.string, 'function', "string")
+end
+
+do -- typeof
+    type_ok(ffi.typeof, 'function', "typeof")
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/403-jit.t b/test/lua-Harness-tests/403-jit.t
new file mode 100755
index 0000000..0073c90
--- /dev/null
+++ b/test/lua-Harness-tests/403-jit.t
@@ -0,0 +1,163 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2018-2020, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 JIT Library
+
+=head2 Synopsis
+
+    % prove 403-jit.t
+
+=head2 Description
+
+See L<http://luajit.org/ext_jit.html>.
+
+=cut
+
+--]]
+
+require 'tap'
+local profile = require'profile'
+
+if not jit then
+    skip_all("only with LuaJIT")
+end
+
+local compiled_with_jit = jit.status()
+local luajit20 = jit.version_num < 20100 and not jit.version:match'RaptorJIT'
+local has_jit_opt = compiled_with_jit
+local has_jit_security = jit.security
+local has_jit_util = not ujit and not jit.version:match'RaptorJIT'
+
+plan'no_plan'
+
+is(package.loaded.jit, _G.jit, "package.loaded")
+is(require'jit', jit, "require")
+
+do -- arch
+    type_ok(jit.arch, 'string', "arch")
+end
+
+do -- flush
+    type_ok(jit.flush, 'function', "flush")
+end
+
+do -- off
+    jit.off()
+    is(jit.status(), false, "off")
+end
+
+-- on
+if compiled_with_jit then
+    jit.on()
+    is(jit.status(), true, "on")
+else
+    error_like(function () jit.on() end,
+               "^[^:]+:%d+: JIT compiler permanently disabled by build option",
+               "no jit.on")
+end
+
+-- opt
+if has_jit_opt then
+    type_ok(jit.opt, 'table', "opt.*")
+    type_ok(jit.opt.start, 'function', "opt.start")
+else
+    is(jit.opt, nil, "no jit.opt")
+end
+
+do -- os
+    type_ok(jit.os, 'string', "os")
+end
+
+-- prngstate
+if profile.openresty then
+    type_ok(jit.prngstate(), 'table', "prngstate")
+    local s1 = { 1, 2, 3, 4, 5, 6, 7, 8}
+    type_ok(jit.prngstate(s1), 'table')
+    local s2 = { 8, 7, 6, 5, 4, 3, 2, 1}
+    eq_array(jit.prngstate(s2), s1)
+    eq_array(jit.prngstate(), s2)
+
+    type_ok(jit.prngstate(32), 'table', "backward compat")
+    eq_array(jit.prngstate(5617), { 32, 0, 0, 0, 0, 0, 0, 0 })
+    eq_array(jit.prngstate(), { 5617, 0, 0, 0, 0, 0, 0, 0 })
+
+    error_like(function () jit.prngstate(-1) end,
+               "^[^:]+:%d+: bad argument #1 to 'prngstate' %(PRNG state must be an array with up to 8 integers or an integer%)")
+
+    error_like(function () jit.prngstate(false) end,
+               "^[^:]+:%d+: bad argument #1 to 'prngstate' %(table expected, got boolean%)")
+elseif jit.version:match'moonjit' then
+    is(jit.prngstate(), 0, "prngstate")
+else
+    is(jit.prngstate, nil, "no jit.prngstate");
+end
+
+-- security
+if has_jit_security then
+    type_ok(jit.security, 'function', "security")
+    type_ok(jit.security('prng'), 'number', "prng")
+    type_ok(jit.security('strhash'), 'number', "strhash")
+    type_ok(jit.security('strid'), 'number', "stdid")
+    type_ok(jit.security('mcode'), 'number', "mcode")
+
+    error_like(function () jit.security('foo') end,
+               "^[^:]+:%d+: bad argument #1 to 'security' %(invalid option 'foo'%)")
+else
+    is(jit.security, nil, "no jit.security")
+end
+
+do -- status
+    local status = { jit.status() }
+    type_ok(status[1], 'boolean', "status")
+    if compiled_with_jit then
+        for i = 2, #status do
+            type_ok(status[i], 'string', status[i])
+        end
+    else
+        is(#status, 1)
+    end
+end
+
+-- util
+if has_jit_util then
+    local jutil = require'jit.util'
+    type_ok(jutil, 'table', "util")
+    is(package.loaded['jit.util'], jutil)
+
+    if luajit20 then
+        is(jit.util, jutil, "util inside jit")
+    else
+        is(jit.util, nil, "no util inside jit")
+    end
+else
+    local r = pcall(require, 'jit.util')
+    is(r, false, "no jit.util")
+end
+
+do -- version
+    type_ok(jit.version, 'string', "version")
+    like(jit.version, '^%w+ %d%.%d%.%d')
+end
+
+do -- version_num
+    type_ok(jit.version_num, 'number', "version_num")
+    like(string.format("%06d", jit.version_num), '^0[12]0[012]%d%d$')
+end
+
+done_testing()
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/404-ext.t b/test/lua-Harness-tests/404-ext.t
new file mode 100755
index 0000000..22a52c7
--- /dev/null
+++ b/test/lua-Harness-tests/404-ext.t
@@ -0,0 +1,171 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2019-2020, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 JIT Library extensions
+
+=head2 Synopsis
+
+    % prove 404-ext.t
+
+=head2 Description
+
+See L<http://luajit.org/ext_jit.html>.
+
+=cut
+
+--]]
+
+require 'tap'
+local profile = require'profile'
+
+local luajit21 = jit and (jit.version_num >= 20100 or jit.version:match'^RaptorJIT')
+if not luajit21 then
+    skip_all("only with LuaJIT 2.1")
+end
+
+plan'no_plan'
+
+do -- table.new
+    local r, new = pcall(require, 'table.new')
+    is(r, true, 'table.new')
+    type_ok(new, 'function')
+    is(package.loaded['table.new'], new)
+
+    type_ok(new(100, 0), 'table')
+    type_ok(new(0, 100), 'table')
+    type_ok(new(200, 200), 'table')
+
+    error_like(function () new(42) end,
+               "^[^:]+:%d+: bad argument #2 to 'new' %(number expected, got no value%)")
+end
+
+do -- table.clear
+    local r, clear = pcall(require, 'table.clear')
+    is(r, true, 'table.clear')
+    type_ok(clear, 'function')
+    is(package.loaded['table.clear'], clear)
+
+    local t = { 'foo', bar = 42 }
+    is(t[1], 'foo')
+    is(t.bar, 42)
+    clear(t)
+    is(t[1], nil)
+    is(t.bar, nil)
+
+    error_like(function () clear(42) end,
+               "^[^:]+:%d+: bad argument #1 to 'clear' %(table expected, got number%)")
+end
+
+-- table.clone
+if profile.openresty then
+    local r, clone = pcall(require, 'table.clone')
+    is(r, true, 'table.clone')
+    type_ok(clone, 'function')
+    is(package.loaded['table.clone'], clone)
+
+    local mt = {}
+    local t = setmetatable({ 'foo', bar = 42 }, mt)
+    is(t[1], 'foo')
+    is(t.bar, 42)
+    local t2 = clone(t)
+    type_ok(t2, 'table')
+    isnt(t2, t)
+    is(getmetatable(t2), nil)
+    is(t2[1], 'foo')
+    is(t2.bar, 42)
+
+    error_like(function () clone(42) end,
+               "^[^:]+:%d+: bad argument #1 to 'clone' %(table expected, got number%)")
+else
+    is(pcall(require, 'table.clone'), false, 'no table.clone')
+end
+
+-- table.isarray
+if profile.openresty then
+    local r, isarray = pcall(require, 'table.isarray')
+    is(r, true, 'table.isarray')
+    type_ok(isarray, 'function')
+    is(package.loaded['table.isarray'], isarray)
+
+    is(isarray({ [3] = 3, [5.3] = 4 }), false)
+    is(isarray({ [3] = 'a', [5] = true }), true)
+    is(isarray({ 'a', nil, true, 3.14 }), true)
+    is(isarray({}), true)
+    is(isarray({ ['1'] = 3, ['2'] = 4 }), false)
+    is(isarray({ ['dog'] = 3, ['cat'] = 4 }), false)
+    is(isarray({ 'dog', 'cat', true, ['bird'] = 3 }), false)
+
+    error_like(function () isarray(42) end,
+               "^[^:]+:%d+: bad argument #1 to 'isarray' %(table expected, got number%)")
+else
+    is(pcall(require, 'table.isarray'), false, 'no table.isarray')
+end
+
+-- table.isempty
+if profile.openresty then
+    local r, isempty = pcall(require, 'table.isempty')
+    is(r, true, 'table.isempty')
+    type_ok(isempty, 'function')
+    is(package.loaded['table.isempty'], isempty)
+
+    is(isempty({}), true)
+    is(isempty({ nil }), true)
+    is(isempty({ dogs = nil }), true)
+    is(isempty({ 3.1 }), false)
+    is(isempty({ 'a', 'b' }), false)
+    is(isempty({ nil, false }), false)
+    is(isempty({ dogs = 3 }), false)
+    is(isempty({ dogs = 3, cats = 4 }), false)
+    is(isempty({ dogs = 3, 5 }), false)
+
+    error_like(function () isempty(42) end,
+               "^[^:]+:%d+: bad argument #1 to 'isempty' %(table expected, got number%)")
+else
+    is(pcall(require, 'table.isempty'), false, 'no table.isempty')
+end
+
+-- table.nkeys
+if profile.openresty then
+    local r, nkeys = pcall(require, 'table.nkeys')
+    is(r, true, 'table.nkeys')
+    type_ok(nkeys, 'function')
+    is(package.loaded['table.nkeys'], nkeys)
+
+    is(nkeys({}), 0)
+    is(nkeys({ cats = 4 }), 1)
+    is(nkeys({ dogs = 3, cats = 4 }), 2)
+    is(nkeys({ dogs = nil, cats = 4 }), 1)
+    is(nkeys({ 'cats' }), 1)
+    is(nkeys({ 'dogs', 3, 'cats', 4 }), 4)
+    is(nkeys({ 'dogs', nil, 'cats', 4 }), 3)
+    is(nkeys({ cats = 4, 5, 6 }), 3)
+    is(nkeys({ nil, 'foo', dogs = 3, cats = 4 }), 3)
+
+    error_like(function () nkeys(42) end,
+               "^[^:]+:%d+: bad argument #1 to 'nkeys' %(table expected, got number%)")
+else
+    is(pcall(require, 'table.nkeys'), false, 'no table.nkeys')
+end
+
+-- thread.exdata
+if pcall(require, 'ffi') and (profile.openresty or jit.version:match'moonjit') then
+    dofile'lexicojit/ext.t'
+end
+
+done_testing()
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/411-luajit.t b/test/lua-Harness-tests/411-luajit.t
new file mode 100755
index 0000000..05111be
--- /dev/null
+++ b/test/lua-Harness-tests/411-luajit.t
@@ -0,0 +1,211 @@
+#! /usr/bin/lua
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2018-2020, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+--[[
+
+=head1 LuaJIT Stand-alone
+
+=head2 Synopsis
+
+    % prove 411-luajit.t
+
+=head2 Description
+
+See L<http://luajit.org/running.html>
+
+=cut
+
+--]]
+
+require'tap'
+local profile = require'profile'
+
+if not jit or ujit then
+    skip_all("only with LuaJIT")
+end
+
+local lua = arg[-3] or arg[-1]
+
+if not pcall(io.popen, lua .. [[ -e "a=1"]]) then
+    skip_all("io.popen not supported")
+end
+
+local compiled_with_jit = jit.status()
+local has_jutil = pcall(require, 'jit.util')
+local has_openresty_listing = profile.openresty or jit.version:match'moonjit'
+
+plan'no_plan'
+diag(lua)
+
+local f = io.open('hello-404.lua', 'w')
+f:write([[
+print 'Hello World'
+]])
+f:close()
+
+os.execute(lua .. " -b hello-404.lua hello-404.out")
+local cmd = lua .. " hello-404.out"
+f = io.popen(cmd)
+is(f:read'*l', 'Hello World', "-b")
+f:close()
+
+os.execute(lua .. " -bg hello-404.lua hello-404.out")
+cmd = lua .. " hello-404.out"
+f = io.popen(cmd)
+is(f:read'*l', 'Hello World', "-bg")
+f:close()
+
+os.execute(lua .. " -be 'print[[Hello World]]' hello-404.out")
+cmd = lua .. " hello-404.out"
+f = io.popen(cmd)
+is(f:read'*l', 'Hello World', "-be")
+f:close()
+
+os.remove('hello-404.out') -- clean up
+
+if has_jutil then
+    cmd = lua .. " -bl hello-404.lua"
+    f = io.popen(cmd)
+    like(f:read'*l', '^%-%- BYTECODE %-%- hello%-404%.lua', "-bl hello.lua")
+    if has_openresty_listing then
+        like(f:read'*l', '^KGC    0')
+        like(f:read'*l', '^KGC    1')
+    end
+    like(f:read'*l', '^0001    %u[%u%d]+%s+')
+    like(f:read'*l', '^0002    %u[%u%d]+%s+')
+    like(f:read'*l', '^0003    %u[%u%d]+%s+')
+    f:close()
+
+    os.execute(lua .. " -bl hello-404.lua hello-404.txt")
+    f = io.open('hello-404.txt', 'r')
+    like(f:read'*l', '^%-%- BYTECODE %-%- hello%-404%.lua', "-bl hello.lua hello.txt")
+    if has_openresty_listing then
+        like(f:read'*l', '^KGC    0')
+        like(f:read'*l', '^KGC    1')
+    end
+    like(f:read'*l', '^0001    %u[%u%d]+%s+')
+    like(f:read'*l', '^0002    %u[%u%d]+%s+')
+    like(f:read'*l', '^0003    %u[%u%d]+%s+')
+    f:close()
+end
+
+if has_openresty_listing then
+    cmd = lua .. " -bL hello-404.lua"
+    f = io.popen(cmd)
+    like(f:read'*l', '^%-%- BYTECODE %-%- hello%-404%.lua', "-bL hello.lua")
+    like(f:read'*l', '^KGC    0')
+    like(f:read'*l', '^KGC    1')
+    like(f:read'*l', '^0001     %[1%]    %u[%u%d]+%s+')
+    like(f:read'*l', '^0002     %[1%]    %u[%u%d]+%s+')
+    like(f:read'*l', '^0003     %[1%]    %u[%u%d]+%s+')
+    f:close()
+
+    os.execute(lua .. " -bL hello-404.lua hello-404.txt")
+    f = io.open('hello-404.txt', 'r')
+    like(f:read'*l', '^%-%- BYTECODE %-%- hello%-404%.lua', "-bL hello.lua hello.txt")
+    like(f:read'*l', '^KGC    0')
+    like(f:read'*l', '^KGC    1')
+    like(f:read'*l', '^0001     %[1%]    %u[%u%d]+%s+')
+    like(f:read'*l', '^0002     %[1%]    %u[%u%d]+%s+')
+    like(f:read'*l', '^0003     %[1%]    %u[%u%d]+%s+')
+    f:close()
+end
+
+os.remove('hello-404.txt') -- clean up
+
+os.execute(lua .. " -b hello-404.lua hello-404.c")
+f = io.open('hello-404.c', 'r')
+like(f:read'*l', '^#ifdef __?cplusplus$', "-b hello.lua hello.c")
+like(f:read'*l', '^extern "C"$')
+like(f:read'*l', '^#endif$')
+like(f:read'*l', '^#ifdef _WIN32$')
+like(f:read'*l', '^__declspec%(dllexport%)$')
+like(f:read'*l', '^#endif$')
+like(f:read'*l', '^const.- char luaJIT_BC_hello_404%[%] = {$')
+like(f:read'*l', '^%d+,%d+,%d+,')
+f:close()
+
+os.remove('hello-404.c') -- clean up
+
+os.execute(lua .. " -b hello-404.lua hello-404.h")
+f = io.open('hello-404.h', 'r')
+like(f:read'*l', '^#define luaJIT_BC_hello_404_SIZE %d+$', "-b hello.lua hello.h")
+like(f:read'*l', '^static const.- char luaJIT_BC_hello_404%[%] = {$')
+like(f:read'*l', '^%d+,%d+,%d+,')
+f:close()
+
+os.remove('hello-404.h') -- clean up
+
+cmd = lua .. " -j flush hello-404.lua"
+f = io.popen(cmd)
+is(f:read'*l', 'Hello World', "-j flush")
+f:close()
+
+cmd = lua .. " -joff hello-404.lua"
+f = io.popen(cmd)
+is(f:read'*l', 'Hello World', "-joff")
+f:close()
+
+cmd = lua .. " -jon hello-404.lua 2>&1"
+f = io.popen(cmd)
+if compiled_with_jit then
+    is(f:read'*l', 'Hello World', "-jon")
+else
+    like(f:read'*l', "^[^:]+: JIT compiler permanently disabled by build option", "no jit")
+end
+f:close()
+
+cmd = lua .. " -j bad hello-404.lua 2>&1"
+f = io.popen(cmd)
+like(f:read'*l', "^[^:]+: unknown luaJIT command or jit%.%* modules not installed", "-j bad")
+f:close()
+
+if compiled_with_jit then
+    cmd = lua .. " -O hello-404.lua"
+    f = io.popen(cmd)
+    is(f:read'*l', 'Hello World', "-O")
+    f:close()
+
+    cmd = lua .. " -O3 hello-404.lua"
+    f = io.popen(cmd)
+    is(f:read'*l', 'Hello World', "-O3")
+    f:close()
+
+    cmd = lua .. " -Ocse -O-dce -Ohotloop=10 hello-404.lua"
+    f = io.popen(cmd)
+    is(f:read'*l', 'Hello World', "-Ocse -O-dce -Ohotloop=10")
+    f:close()
+
+    cmd = lua .. " -O+cse,-dce,hotloop=10 hello-404.lua"
+    f = io.popen(cmd)
+    is(f:read'*l', 'Hello World', "-O+cse,-dce,hotloop=10")
+    f:close()
+
+    cmd = lua .. " -O+bad hello-404.lua 2>&1"
+    f = io.popen(cmd)
+    like(f:read'*l', "^[^:]+: unknown or malformed optimization flag '%+bad'", "-O+bad")
+    f:close()
+else
+    cmd = lua .. " -O0 hello-404.lua 2>&1"
+    f = io.popen(cmd)
+    like(f:read'*l', "^[^:]+: attempt to index a nil value")
+    f:close()
+end
+
+os.remove('hello-404.lua') -- clean up
+
+done_testing()
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/CMakeLists.txt b/test/lua-Harness-tests/CMakeLists.txt
new file mode 100644
index 0000000..9b35e5a
--- /dev/null
+++ b/test/lua-Harness-tests/CMakeLists.txt
@@ -0,0 +1,49 @@
+# Test suite that has been added from lua-Harness test suite
+# in scope of https://github.com/tarantool/tarantool/issues/4473.
+
+# See the rationale in the root CMakeLists.txt
+cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
+
+find_program(PROVE prove)
+if(NOT PROVE)
+  message(WARNING "`prove' is not found, so lua-Harness-tests target is not generated")
+  return()
+endif()
+
+set(LUA_TEST_FLAGS --failures --shuffle)
+if(CMAKE_VERBOSE_MAKEFILE)
+  list(APPEND LUA_TEST_FLAGS --verbose)
+endif()
+
+string(CONCAT LUA_PATH
+  "./?.lua\;"
+  "${CMAKE_CURRENT_SOURCE_DIR}/?.lua\;"
+  "${LUAJIT_SOURCE_DIR}/?.lua\;"
+)
+
+string(CONCAT LUA_CPATH
+  "./?${CMAKE_SHARED_LIBRARY_SUFFIX}\;"
+  "${LUAJIT_SOURCE_DIR}/?${CMAKE_SHARED_LIBRARY_SUFFIX}\;"
+)
+
+add_custom_target(lua-Harness-tests DEPENDS ${LUAJIT_TEST_BINARY})
+
+add_custom_command(TARGET lua-Harness-tests
+  COMMENT "Running lua-Harness tests"
+  COMMAND
+  env
+    LUA_PATH="${LUA_PATH}\;"
+    LUA_CPATH="${LUA_CPATH}\;"
+    # Tarantool doesn't support LUA_INIT and most likely it
+    # never will.
+    # See https://github.com/tarantool/tarantool/issues/5744
+    # for more info.
+    # So use less preferable way for tests.
+    # See the root CMakeLists.txt for more info.
+    ${PROVE} ${CMAKE_CURRENT_SOURCE_DIR}
+      --exec '${LUAJIT_TEST_COMMAND} -l profile_luajit21'
+      ${LUA_TEST_FLAGS}
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+# vim: expandtab tabstop=2 shiftwidth=2
diff --git a/test/lua-Harness-tests/lexico52/lexico.t b/test/lua-Harness-tests/lexico52/lexico.t
new file mode 100644
index 0000000..ff6bb99
--- /dev/null
+++ b/test/lua-Harness-tests/lexico52/lexico.t
@@ -0,0 +1,45 @@
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2012-2018, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+is("\x41", "A")
+is("\x3d", "=")
+is("\x3D", "=")
+
+do
+    local f, msg = load [[a = "A\xyz"]]
+    like(msg, "^[^:]+:%d+: .- near")
+
+    f, msg = load [[a = "A\Z"]]
+    like(msg, "^[^:]+:%d+: .- escape .- near")
+end
+
+do
+    local a = 'alo\n123"'
+    is("alo\n\z
+    123\"", a)
+
+    local f, msg = load [[a = " escape \z unauthorized
+new line" ]]
+    like(msg, "^[^:]+:%d+: unfinished string near")
+end
+
+is(0x0.1E, 0x1E / 0x100)        -- 0.1171875
+is(0xA23p-4, 0xA23 / (2^4))     -- 162.1875
+if string.pack and #string.pack('n', 0) == 4 then
+    diag('Small Lua')
+else
+    is(0X1.921FB54442D18P+1, (1 + 0x921FB54442D18/0x10000000000000) * 2)
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/lexico53/boolean.t b/test/lua-Harness-tests/lexico53/boolean.t
new file mode 100644
index 0000000..693ac76
--- /dev/null
+++ b/test/lua-Harness-tests/lexico53/boolean.t
@@ -0,0 +1,43 @@
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2018, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+error_like(function () return ~true end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on a boolean value",
+           "~true")
+
+error_like(function () return true // 3 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a boolean value",
+           "true // 3")
+
+error_like(function () return true & 7 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on a boolean value",
+           "true & 7")
+
+error_like(function () return true | 1 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on a boolean value",
+           "true | 1")
+
+error_like(function () return true ~ 4 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on a boolean value",
+           "true ~ 4")
+
+error_like(function () return true >> 5 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on a boolean value",
+           "true >> 5")
+
+error_like(function () return true << 2 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on a boolean value",
+           "true << 2")
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/lexico53/function.t b/test/lua-Harness-tests/lexico53/function.t
new file mode 100644
index 0000000..2471be6
--- /dev/null
+++ b/test/lua-Harness-tests/lexico53/function.t
@@ -0,0 +1,66 @@
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2019, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+local f = function () return 1 end
+
+error_like(function () return ~f end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on",
+           "~f")
+
+error_like(function () f = print; return ~f end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on")
+
+error_like(function () return f // 3 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "f // 3")
+
+error_like(function () f = print; return f // 3 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on")
+
+error_like(function () return f & 7 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on",
+           "f & 7")
+
+error_like(function () f = print; return f & 7 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on")
+
+error_like(function () return f | 1 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on",
+           "f | 1")
+
+error_like(function () f = print; return f | 1 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on")
+
+error_like(function () return f ~ 4 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on",
+           "f ~ 4")
+
+error_like(function () f = print; return f ~ 4 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on")
+
+error_like(function () return f >> 5 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on",
+           "f >> 5")
+
+error_like(function () f = print; return f >> 5 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on")
+
+error_like(function () return f << 2 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on",
+           "f << 2")
+
+error_like(function () f = print; return f << 2 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on")
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/lexico53/lexico.t b/test/lua-Harness-tests/lexico53/lexico.t
new file mode 100644
index 0000000..41b0d89
--- /dev/null
+++ b/test/lua-Harness-tests/lexico53/lexico.t
@@ -0,0 +1,30 @@
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2015-2018, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+is("\u{41}", "A")
+is("\u{20AC}", "\xE2\x82\xAC")
+is("\u{20ac}", "\xe2\x82\xac")
+
+do
+    local f, msg = load [[a = "A\u{yz}"]]
+    like(msg, "^[^:]+:%d+: .- near")
+
+    f, msg = load [[a = "A\u{41"]]
+    like(msg, "^[^:]+:%d+: .- near")
+
+    f, msg = load [[a = "A\u{FFFFFFFFFF}"]]
+    like(msg, "^[^:]+:%d+: .- near")
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/lexico53/nil.t b/test/lua-Harness-tests/lexico53/nil.t
new file mode 100644
index 0000000..a6438e2
--- /dev/null
+++ b/test/lua-Harness-tests/lexico53/nil.t
@@ -0,0 +1,43 @@
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2018, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+error_like(function () return ~nil end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on a nil value",
+           "~nil")
+
+error_like(function () return  nil // 3 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a nil value",
+           "nil // 3")
+
+error_like(function () return nil & 7 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on a nil value",
+           "nil & 7")
+
+error_like(function () return nil | 1 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on a nil value",
+           "nil | 1")
+
+error_like(function () return nil ~ 4 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on a nil value",
+           "nil ~ 4")
+
+error_like(function () return nil >> 5 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on a nil value",
+           "nil >> 5")
+
+error_like(function () return nil << 2 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on a nil value",
+           "nil << 2")
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/lexico53/number.t b/test/lua-Harness-tests/lexico53/number.t
new file mode 100644
index 0000000..d205da3
--- /dev/null
+++ b/test/lua-Harness-tests/lexico53/number.t
@@ -0,0 +1,181 @@
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2019, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+local profile = require'profile'
+
+is(~4, -5, "~4")
+
+error_like(function () return ~3.14 end,
+           "^[^:]+:%d+: number has no integer representation",
+           "~3.14")
+
+is(25.5 // 3.5, 7.0, "25.5 // 3.5")
+
+is(25 // 3, 8, "25 // 3")
+
+is(25 // -3, -9, "25 // -3")
+
+is(1 // -1, -1, "1 // -1")
+
+type_ok(1.0 // 0, 'number', "1.0 // 0")
+
+error_like(function () return 1 // 0 end,
+           "^[^:]+:%d+: attempt to divide by zero",
+           "1 // 0")
+
+is(3 & 7, 3, "3 & 7")
+
+is(4 | 1, 5, "4 | 1")
+
+is(7 ~ 1, 6, "7 ~ 1")
+
+is(100 >> 5, 3, "100 >> 5")
+
+is(3 << 2, 12, "3 << 2")
+
+error_like(function () return 25 // {} end,
+           "^[^:]+:%d+: attempt to perform arithmetic on a table value",
+           "25 // {}")
+
+error_like(function () return 3 & true end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on a boolean value",
+           "3 & true")
+
+error_like(function () return 4 | true end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on a boolean value",
+           "4 | true")
+
+error_like(function () return 7 ~ true end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on a boolean value",
+           "7 ~ true")
+
+error_like(function () return 100 >> true end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on a boolean value",
+           "100 >> true")
+
+error_like(function () return 3 << true end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on a boolean value",
+           "3 << true")
+
+error_like(function () return 25 // 'text' end,
+           "^[^:]+:%d+: attempt to",
+           "25 // 'text'")
+
+error_like(function () return 3 & 'text' end,
+           "^[^:]+:%d+: attempt to",
+           "3 & 'text'")
+
+error_like(function () return 4 | 'text' end,
+           "^[^:]+:%d+: attempt to",
+           "4 | 'text'")
+
+error_like(function () return 7 ~ 'text' end,
+           "^[^:]+:%d+: attempt to",
+           "7 ~ 'text'")
+
+error_like(function () return 100 >> 'text' end,
+           "^[^:]+:%d+: attempt to",
+           "100 >> 'text'")
+
+error_like(function () return 3 << 'text' end,
+           "^[^:]+:%d+: attempt to",
+           "3 << 'text'")
+
+if profile.nocvts2n then
+    error_like(function () return 25.5 // '3.5' end,
+               "^[^:]+:%d+: attempt to",
+               "25.5 // '3.5'")
+
+    error_like(function () return 25 // '3' end,
+               "^[^:]+:%d+: attempt to",
+               "25 // '3'")
+else
+    is(25.5 // '3.5', 7.0, "25.5 // '3.5'")
+
+    is(25 // '3', 8, "25 // '3'")
+end
+
+if profile.nocvts2n or _VERSION >= 'Lua 5.4' then
+    error_like(function () return 3 & '7' end,
+               "^[^:]+:%d+: attempt to",
+               "3 & '7'")
+
+    error_like(function () return 4 | '1' end,
+               "^[^:]+:%d+: attempt to",
+               "4 | '1'")
+
+    error_like(function () return 7 ~ '1' end,
+               "^[^:]+:%d+: attempt to",
+               "7 ~ '1'")
+
+    error_like(function () return 100 >> '5' end,
+               "^[^:]+:%d+: attempt to",
+               "100 >> '5'")
+
+    error_like(function () return 3 << '2' end,
+               "^[^:]+:%d+: attempt to",
+               "3 << '2'")
+else
+    is(3 & '7', 3, "3 & '7'")
+
+    is(4 | '1', 5, "4 | '1'")
+
+    is(7 ~ '1', 6, "7 ~ '1'")
+
+    is(100 >> '5', 3, "100 >> '5'")
+
+    is(3 << '2', 12, "3 << '2'")
+end
+
+error_like(function () return 3.5 & 7 end,
+           "^[^:]+:%d+: number has no integer representation",
+           "3.5 & 7")
+
+error_like(function () return 3 & 7.5 end,
+           "^[^:]+:%d+: number has no integer representation",
+           "3 & 7.5")
+
+error_like(function () return 4.5 | 1 end,
+           "^[^:]+:%d+: number has no integer representation",
+           "4.5 | 1")
+
+error_like(function () return 4 | 1.5 end,
+           "^[^:]+:%d+: number has no integer representation",
+           "4 | 1.5")
+
+error_like(function () return 7.5 ~ 1 end,
+           "^[^:]+:%d+: number has no integer representation",
+           "7.5 ~ 1")
+
+error_like(function () return 7 ~ 1.5 end,
+           "^[^:]+:%d+: number has no integer representation",
+           "7 ~ 1.5")
+
+error_like(function () return 100.5 >> 5 end,
+           "^[^:]+:%d+: number has no integer representation",
+           "100.5 >> 5")
+
+error_like(function () return 100 >> 5.5 end,
+           "^[^:]+:%d+: number has no integer representation",
+           "100 >> 5.5")
+
+error_like(function () return 3.5 << 2 end,
+           "^[^:]+:%d+: number has no integer representation",
+           "3.5 << 2")
+
+error_like(function () return 3 << 2.5 end,
+           "^[^:]+:%d+: number has no integer representation",
+           "3 << 2.5")
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/lexico53/string.t b/test/lua-Harness-tests/lexico53/string.t
new file mode 100644
index 0000000..eb74064
--- /dev/null
+++ b/test/lua-Harness-tests/lexico53/string.t
@@ -0,0 +1,169 @@
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2019, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+local profile = require'profile'
+
+if profile.nocvts2n or _VERSION >= 'Lua 5.4' then
+    error_like(function () return ~'4' end,
+               "^[^:]+:%d+: attempt to",
+               "~'4'")
+else
+    is(~'4', -5, "~'4'")
+end
+
+error_like(function () return ~'text' end,
+           "^[^:]+:%d+: attempt to",
+           "~'text'")
+
+if profile.nocvts2n then
+    error_like(function () return '25.5' // 3.5 end,
+               "^[^:]+:%d+: attempt to",
+               "'25.5' // 3.5")
+
+    error_like(function () return '25' // 3 end,
+               "^[^:]+:%d+: attempt to",
+               "'25' // 3")
+else
+    is('25.5' // 3.5, 7.0, "'25.5' // 3.5")
+
+    is('25' // 3, 8, "'25' // 3")
+end
+
+if profile.nocvts2n or _VERSION >= 'Lua 5.4' then
+    error_like(function () return '3' & 7 end,
+               "^[^:]+:%d+: attempt to",
+               "'3' & 7")
+
+    error_like(function () return '4' | 1 end,
+               "^[^:]+:%d+: attempt to",
+               "'4' | 1")
+
+    error_like(function () return '7' ~ 1 end,
+               "^[^:]+:%d+: attempt to",
+               "'7' ~ 1")
+
+    error_like(function () return '100' >> 5 end,
+               "^[^:]+:%d+: attempt to",
+               "'100' >> 5")
+
+    error_like(function () return '3' << 2 end,
+               "^[^:]+:%d+: attempt to",
+               "'3' << 2")
+else
+    is('3' & 7, 3, "'3' & 7")
+
+    is('4' | 1, 5, "'4' | 1")
+
+    is('7' ~ 1, 6, "'7' ~ 1")
+
+    is('100' >> 5, 3, "'100' >> 5")
+
+    is('3' << 2, 12, "'3' << 2")
+end
+
+error_like(function () return '25' // {} end,
+           "^[^:]+:%d+: attempt to",
+           "'25' // {}")
+
+error_like(function () return '3' & true end,
+           "^[^:]+:%d+: attempt to",
+           "'3' & true")
+
+error_like(function () return '4' | true end,
+           "^[^:]+:%d+: attempt to",
+           "'4' | true")
+
+error_like(function () return '7' ~ true end,
+           "^[^:]+:%d+: attempt to",
+           "'7' ~ true")
+
+error_like(function () return '100' >> true end,
+           "^[^:]+:%d+: attempt to",
+           "'100' >> true")
+
+error_like(function () return '3' << true end,
+           "^[^:]+:%d+: attempt to",
+           "'3' << true")
+
+error_like(function () return '25' // 'text' end,
+           "^[^:]+:%d+: attempt to",
+           "'25' // 'text'")
+
+error_like(function () return '3' & 'text' end,
+           "^[^:]+:%d+: attempt to",
+           "'3' & 'text'")
+
+error_like(function () return '4' | 'text' end,
+           "^[^:]+:%d+: attempt to",
+           "'4' | 'text'")
+
+error_like(function () return '7' ~ 'text' end,
+           "^[^:]+:%d+: attempt to",
+           "'7' ~ 'text'")
+
+error_like(function () return '100' >> 'text' end,
+           "^[^:]+:%d+: attempt to",
+           "'100' >> 'text'")
+
+error_like(function () return '3' << 'text' end,
+           "^[^:]+:%d+: attempt to",
+           "'3' << 'text'")
+
+if profile.nocvts2n then
+    error_like(function () return '25.5' // '3.5' end,
+               "^[^:]+:%d+: attempt to",
+               "'25.5' // '3.5'")
+
+    error_like(function () return '25' // '3' end,
+               "^[^:]+:%d+: attempt to",
+               "'25' // '3'")
+else
+    is('25.5' // '3.5', 7.0, "'25.5' // '3.5'")
+
+     is('25' // '3', 8, "'25' // '3'")
+end
+
+if profile.nocvts2n or _VERSION >= 'Lua 5.4' then
+    error_like(function () return '3' & '7' end,
+               "^[^:]+:%d+: attempt to",
+               "'3' & '7'")
+
+    error_like(function () return '4' | '1' end,
+               "^[^:]+:%d+: attempt to",
+               "'4' | '1'")
+
+    error_like(function () return '7' ~ '1' end,
+               "^[^:]+:%d+: attempt to",
+               "'7' ~ '1'")
+
+    error_like(function () return '100' >> '5' end,
+               "^[^:]+:%d+: attempt to",
+               "'100' >> '5'")
+
+    error_like(function () return '3' << '2' end,
+               "^[^:]+:%d+: attempt to",
+               "'3' << '2'")
+else
+    is('3' & '7', 3, "'3' & '7'")
+
+    is('4' | '1', 5, "'4' | '1'")
+
+    is('7' ~ '1', 6, "'7' ~ '1'")
+
+    is('100' >> '5', 3, "'100' >> '5'")
+
+    is('3' << '2', 12, "'3' << 2")
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/lexico53/table.t b/test/lua-Harness-tests/lexico53/table.t
new file mode 100644
index 0000000..007232d
--- /dev/null
+++ b/test/lua-Harness-tests/lexico53/table.t
@@ -0,0 +1,43 @@
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2018, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+error_like(function () return ~{} end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on a table value",
+           "~{}")
+
+error_like(function () return {} // 3 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "{} // 3")
+
+error_like(function () return {} & 7 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on a table value",
+           "{} & 7")
+
+error_like(function () return {} | 1 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on a table value",
+           "{} | 1")
+
+error_like(function () return {} ~ 4 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on a table value",
+           "{} ~ 4")
+
+error_like(function () return {} >> 5 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on a table value",
+           "{} >> 5")
+
+error_like(function () return {} << 2 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on a table value",
+           "{} << 2")
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/lexico53/thread.t b/test/lua-Harness-tests/lexico53/thread.t
new file mode 100644
index 0000000..ef9e57b
--- /dev/null
+++ b/test/lua-Harness-tests/lexico53/thread.t
@@ -0,0 +1,45 @@
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2019, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+local co = coroutine.create(function () return 1 end)
+
+error_like(function () return ~co end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on",
+           "~co")
+
+error_like(function () return co // 3 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "co // 3")
+
+error_like(function () return co & 7 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on",
+           "co & 7")
+
+error_like(function () return co | 1 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on",
+           "co | 1")
+
+error_like(function () return co ~ 4 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on",
+           "co ~ 4")
+
+error_like(function () return co >> 5 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on",
+           "co >> 5")
+
+error_like(function () return co << 2 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on",
+           "co << 2")
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/lexico53/userdata.t b/test/lua-Harness-tests/lexico53/userdata.t
new file mode 100644
index 0000000..06b96f9
--- /dev/null
+++ b/test/lua-Harness-tests/lexico53/userdata.t
@@ -0,0 +1,45 @@
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2009-2019, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+local u = io.stdin
+
+error_like(function () return ~u end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on",
+           "~u")
+
+error_like(function () return u // 3 end,
+           "^[^:]+:%d+: attempt to perform arithmetic on",
+           "u // 3")
+
+error_like(function () return u & 7 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on",
+           "u & 7")
+
+error_like(function () return u | 1 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on",
+           "u | 1")
+
+error_like(function () return u ~ 4 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on",
+           "u ~ 4")
+
+error_like(function () return u >> 5 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on",
+           "u >> 5")
+
+error_like(function () return u << 2 end,
+           "^[^:]+:%d+: attempt to perform bitwise operation on",
+           "u << 2")
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/lexico53/utf8.t b/test/lua-Harness-tests/lexico53/utf8.t
new file mode 100644
index 0000000..87d3f6d
--- /dev/null
+++ b/test/lua-Harness-tests/lexico53/utf8.t
@@ -0,0 +1,179 @@
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2014-2020, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+local has_char54 = _VERSION >= 'Lua 5.4'
+local has_charpattern54 = _VERSION >= 'Lua 5.4'
+
+do -- char
+    is(utf8.char(65, 66, 67), 'ABC', "function char")
+    is(utf8.char(0x20AC), '\u{20AC}')
+    is(utf8.char(), '')
+
+    is(utf8.char(0):len(), 1)
+    is(utf8.char(0x7F):len(), 1)
+    is(utf8.char(0x80):len(), 2)
+    is(utf8.char(0x7FF):len(), 2)
+    is(utf8.char(0x800):len(), 3)
+    is(utf8.char(0xFFFF):len(), 3)
+    is(utf8.char(0x10000):len(), 4)
+    is(utf8.char(0x10FFFF):len(), 4)
+    if has_char54 then
+        is(utf8.char(0x1FFFFF):len(), 4)
+        is(utf8.char(0x200000):len(), 5)
+        is(utf8.char(0x3FFFFFF):len(), 5)
+        is(utf8.char(0x4000000):len(), 6)
+        is(utf8.char(0x7FFFFFFF):len(), 6)
+    else
+        error_like(function () utf8.char(0x110000) end,
+                   "^[^:]+:%d+: bad argument #1 to 'char' %(value out of ",
+                   "function char (out of range)")
+    end
+
+    error_like(function () utf8.char(0, -1) end,
+               "^[^:]+:%d+: bad argument #2 to 'char' %(value out of ",
+               "function char (out of range)")
+
+     error_like(function () utf8.char(0, 'bad') end,
+                "^[^:]+:%d+: bad argument #2 to 'char' %(number expected, got string%)",
+                "function char (bad)")
+end
+
+do -- charpattern
+    if has_charpattern54 then
+        is(utf8.charpattern, "[\0-\x7F\xC2-\xFD][\x80-\xBF]*", "charpattern")
+    else
+        is(utf8.charpattern, "[\0-\x7F\xC2-\xF4][\x80-\xBF]*", "charpattern")
+    end
+end
+
+do -- codes
+    local ap = {}
+    local ac = {}
+    for p, c in utf8.codes("A\u{20AC}3") do
+        ap[#ap+1] = p
+        ac[#ac+1] = c
+    end
+    eq_array(ap, {1, 2, 5}, "function codes")
+    eq_array(ac, {0x41, 0x20AC, 0x33})
+
+    local empty = true
+    for p, c in utf8.codes('') do
+        empty = false
+    end
+    ok(empty, "codes (empty)")
+
+    error_like(function () utf8.codes() end,
+               "^[^:]+:%d+: bad argument #1 to 'codes' %(string expected, got no value%)",
+               "function codes ()")
+
+    error_like(function () utf8.codes(true) end,
+               "^[^:]+:%d+: bad argument #1 to 'codes' %(string expected, got boolean%)",
+               "function codes (true)")
+
+    error_like(function () for p, c in utf8.codes('invalid\xFF') do end end,
+               "^[^:]+:%d+: invalid UTF%-8 code",
+               "function codes (invalid)")
+end
+
+do -- codepoints
+    is(utf8.codepoint("A\u{20AC}3"), 0x41, "function codepoint")
+    is(utf8.codepoint("A\u{20AC}3", 2), 0x20AC)
+    is(utf8.codepoint("A\u{20AC}3", -1), 0x33)
+    is(utf8.codepoint("A\u{20AC}3", 5), 0x33)
+    eq_array({utf8.codepoint("A\u{20AC}3", 1, 5)}, {0x41, 0x20AC, 0x33})
+    eq_array({utf8.codepoint("A\u{20AC}3", 1, 4)}, {0x41, 0x20AC})
+
+    error_like(function () utf8.codepoint("A\u{20AC}3", 6) end,
+               "^[^:]+:%d+: bad argument #3 to 'codepoint' %(out of ",
+               "function codepoint (out of range)")
+
+    error_like(function () utf8.codepoint("A\u{20AC}3", 8) end,
+               "^[^:]+:%d+: bad argument #3 to 'codepoint' %(out of ",
+               "function codepoint (out of range)")
+
+    error_like(function () utf8.codepoint("invalid\xFF", 8) end,
+               "^[^:]+:%d+: invalid UTF%-8 code",
+               "function codepoint (invalid)")
+end
+
+do -- len
+    is(utf8.len('A'), 1, "function len")
+    is(utf8.len(''), 0)
+    is(utf8.len("\u{41}\u{42}\u{43}"), 3)
+    is(utf8.len("A\u{20AC}3"), 3)
+
+    is(utf8.len('A', 1), 1)
+    is(utf8.len('A', 2), 0)
+    is(utf8.len('ABC', 1, 1), 1)
+    is(utf8.len('ABC', 2, 2), 1)
+    is(utf8.len('ABC', -1), 1)
+    is(utf8.len('ABC', -2), 2)
+
+    error_like(function () utf8.len('A', 3) end,
+               "^[^:]+:%d+: bad argument #2 to 'len' %(initial position out of ",
+               "function len (out of range)")
+
+    local len, pos = utf8.len('invalid\xFF')
+    is(len, nil, "function len (invalid)")
+    is(pos, 8)
+end
+
+do -- offset
+    is(utf8.offset("A\u{20AC}3", 1), 1, "function offset")
+    is(utf8.offset("A\u{20AC}3", 2), 2)
+    is(utf8.offset("A\u{20AC}3", 3), 5)
+    is(utf8.offset("A\u{20AC}3", 4), 6)
+    is(utf8.offset("A\u{20AC}3", 5), nil)
+    is(utf8.offset("A\u{20AC}3", 6), nil)
+    is(utf8.offset("A\u{20AC}3", -1), 5)
+    is(utf8.offset("A\u{20AC}3", 1, 2), 2)
+    is(utf8.offset("A\u{20AC}3", 2, 2), 5)
+    is(utf8.offset("A\u{20AC}3", 3, 2), 6)
+    is(utf8.offset("A\u{20AC}3", 4, 2), nil)
+    is(utf8.offset("A\u{20AC}3", -1, 2), 1)
+    is(utf8.offset("A\u{20AC}3", -2, 2), nil)
+    is(utf8.offset("A\u{20AC}3", 1, 5), 5)
+    is(utf8.offset("A\u{20AC}3", 2, 5), 6)
+    is(utf8.offset("A\u{20AC}3", 3, 5), nil)
+    is(utf8.offset("A\u{20AC}3", -1, 5), 2)
+    is(utf8.offset("A\u{20AC}3", -2, 5), 1)
+    is(utf8.offset("A\u{20AC}3", -3, 5), nil)
+    is(utf8.offset("A\u{20AC}3", 1, 6), 6)
+    is(utf8.offset("A\u{20AC}3", 2, 6), nil)
+    is(utf8.offset("A\u{20AC}3", 1, -1), 5)
+    is(utf8.offset("A\u{20AC}3", -1, -1), 2)
+    is(utf8.offset("A\u{20AC}3", -2, -1), 1)
+    is(utf8.offset("A\u{20AC}3", -3, -1), nil)
+    is(utf8.offset("A\u{20AC}3", 1, -4), 2)
+    is(utf8.offset("A\u{20AC}3", 2, -4), 5)
+    is(utf8.offset("A\u{20AC}3", -1, -4), 1)
+    is(utf8.offset("A\u{20AC}3", -2, -4), nil)
+
+    is(utf8.offset("A\u{20AC}3", 0, 1), 1)
+    is(utf8.offset("A\u{20AC}3", 0, 2), 2)
+    is(utf8.offset("A\u{20AC}3", 0, 3), 2)
+    is(utf8.offset("A\u{20AC}3", 0, 4), 2)
+    is(utf8.offset("A\u{20AC}3", 0, 5), 5)
+    is(utf8.offset("A\u{20AC}3", 0, 6), 6)
+
+    error_like(function () utf8.offset("A\u{20AC}3", 1, 7) end,
+               "^[^:]+:%d+: bad argument #3 to 'offset' %(position out of ",
+              "function offset (out of range)")
+
+    error_like(function () utf8.offset("\x80", 1) end,
+               "^[^:]+:%d+: initial position is a continuation byte",
+               "function offset (continuation byte)")
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/lexico54/lexico.t b/test/lua-Harness-tests/lexico54/lexico.t
new file mode 100644
index 0000000..4523a51
--- /dev/null
+++ b/test/lua-Harness-tests/lexico54/lexico.t
@@ -0,0 +1,19 @@
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2019, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+is("\u{10000}", "\xF0\x90\x80\x80")
+is("\u{200000}", "\xF8\x88\x80\x80\x80")
+is("\u{4000000}", "\xFC\x84\x80\x80\x80\x80")
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/lexico54/metatable.t b/test/lua-Harness-tests/lexico54/metatable.t
new file mode 100644
index 0000000..4685b34
--- /dev/null
+++ b/test/lua-Harness-tests/lexico54/metatable.t
@@ -0,0 +1,38 @@
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2019-2020, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+do -- toclose
+    local called = false
+    do
+        local foo <close> = setmetatable({}, { __close = function () called = true end })
+        type_ok(foo, 'table', "toclose")
+        is(called, false)
+    end
+    is(called, true)
+
+    error_like(function () do local foo <close> = {} end end,
+               "^[^:]+:%d+: variable 'foo' got a non%-closable value")
+
+    lives_ok(function ()
+        local var1 <const> = nil
+        local var2 <const> = nil
+        do
+            local var3 <close> = setmetatable({}, { __close = function () end })
+        end
+        local var4 = true
+        -- attempt to close non-closable variable 'var4'
+    end, "blocker bug 5.4.0-rc3")
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/lexico54/utf8.t b/test/lua-Harness-tests/lexico54/utf8.t
new file mode 100644
index 0000000..1aa70cc
--- /dev/null
+++ b/test/lua-Harness-tests/lexico54/utf8.t
@@ -0,0 +1,54 @@
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2019, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+do -- codes
+    local ap = {}
+    local ac = {}
+    for p, c in utf8.codes("A\u{200000}3", true) do
+        ap[#ap+1] = p
+        ac[#ac+1] = c
+    end
+    eq_array(ap, {1, 2, 7}, "function codes lax")
+    eq_array(ac, {0x41, 0x200000, 0x33})
+
+    error_like(function () for _ in utf8.codes("A\u{200000}3", false) do end end,
+               "^[^:]+:%d+: invalid UTF%-8 code")
+
+    error_like(function () for _ in utf8.codes("A\u{200000}3") do end end,
+               "^[^:]+:%d+: invalid UTF%-8 code")
+end
+
+do -- codepoints
+    eq_array({utf8.codepoint("A\u{200000}3", 1, 7, true)}, {0x41, 0x200000, 0x33}, "function codepoint lax")
+
+    error_like(function () utf8.codepoint("A\u{200000}3", 1, 7, false) end,
+               "^[^:]+:%d+: invalid UTF%-8 code")
+
+    error_like(function () utf8.codepoint("A\u{200000}3", 1, 7) end,
+               "^[^:]+:%d+: invalid UTF%-8 code")
+end
+
+do -- len
+    is(utf8.len('A\u{200000}C', 1, -1, true), 3, "function len lax")
+
+    local len, pos = utf8.len('A\u{200000}C')
+    is(len, nil)
+    is(pos, 2)
+
+    len, pos = utf8.len('A\u{200000}C', 1, -1, false)
+    is(len, nil)
+    is(pos, 2)
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/lexicojit/basic.t b/test/lua-Harness-tests/lexicojit/basic.t
new file mode 100644
index 0000000..8ad3a59
--- /dev/null
+++ b/test/lua-Harness-tests/lexicojit/basic.t
@@ -0,0 +1,27 @@
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2018, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+do -- tonumber
+    is(tonumber(42uLL), 42, "function tonumber (cdata)")
+    is(tonumber(42LL), 42)
+end
+
+do -- tostring
+    is(tostring(42uLL), '42ULL', "function tostring (cdata)")
+    is(tostring(42LL), '42LL')
+    is(tostring(1i), '0+1i')
+    is(tostring(12.5i), '0+12.5i')
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/lexicojit/ext.t b/test/lua-Harness-tests/lexicojit/ext.t
new file mode 100644
index 0000000..8c44b99
--- /dev/null
+++ b/test/lua-Harness-tests/lexicojit/ext.t
@@ -0,0 +1,52 @@
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2019-2020, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+local profile = require'profile'
+
+do -- thread.exdata
+    local r, exdata = pcall(require, 'thread.exdata')
+    is(r, true, 'thread.exdata')
+    type_ok(exdata, 'function')
+    is(package.loaded['thread.exdata'], exdata)
+
+    local ffi = require'ffi'
+    local u64 = ffi.new('uintptr_t', 0xefdeaddeadbeefLL)
+    local ptr = ffi.cast('void *', u64)
+    exdata(u64)  -- set
+    is(exdata(), ptr) -- get
+
+    error_like(function () exdata(42) end,
+               "^[^:]+:%d+: bad argument #1 to 'exdata' %(cdata expected, got number%)")
+end
+
+-- thread.exdata2
+if profile.openresty then
+    local r, exdata2 = pcall(require, 'thread.exdata2')
+    is(r, true, 'thread.exdata2')
+    type_ok(exdata2, 'function')
+    is(package.loaded['thread.exdata2'], exdata2)
+
+    local ffi = require'ffi'
+    local u64 = ffi.new('uintptr_t', 0xefdeaddeadbeefLL)
+    local ptr = ffi.cast('void *', u64)
+    exdata2(u64)  -- set
+    is(exdata2(), ptr) -- get
+
+    error_like(function () exdata2(42) end,
+               "^[^:]+:%d+: bad argument #1 to 'exdata2' %(cdata expected, got number%)")
+else
+    is(pcall(require, 'thread.exdata2'), false, 'no thread.exdata2')
+end
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/lexicojit/lexico.t b/test/lua-Harness-tests/lexicojit/lexico.t
new file mode 100644
index 0000000..1a973b5
--- /dev/null
+++ b/test/lua-Harness-tests/lexicojit/lexico.t
@@ -0,0 +1,32 @@
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+-- Copyright (C) 2018, Perrad Francois
+--
+-- This code is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
+
+type_ok(42LL, 'cdata', "42LL")
+type_ok(42ULL, 'cdata', "42ULL")
+type_ok(42uLL, 'cdata', "42uLL")
+type_ok(42ull, 'cdata', "42ull")
+
+type_ok(0x2aLL, 'cdata', "0x2aLL")
+type_ok(0x2aULL, 'cdata', "0x2aULL")
+type_ok(0x2auLL, 'cdata', "0x2auLL")
+type_ok(0x2aull, 'cdata', "0x2aull")
+
+type_ok(12.5i, 'cdata', '12.5i')
+type_ok(12.5I, 'cdata', '12.5I')
+type_ok(1i, 'cdata', '1i')
+type_ok(1I, 'cdata', '1I')
+type_ok(0i, 'cdata', '0i')
+type_ok(0I, 'cdata', '0I')
+
+-- Local Variables:
+--   mode: lua
+--   lua-indent-level: 4
+--   fill-column: 100
+-- End:
+-- vim: ft=lua expandtab shiftwidth=4:
diff --git a/test/lua-Harness-tests/profile.lua b/test/lua-Harness-tests/profile.lua
new file mode 100644
index 0000000..50c0c11
--- /dev/null
+++ b/test/lua-Harness-tests/profile.lua
@@ -0,0 +1,53 @@
+---
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+---
+
+local profile = {
+
+--[[ compat 5.0
+    has_string_gfind = true,
+    has_math_mod = true,
+--]]
+
+    compat51 = true,
+--[[
+    has_unpack = true,
+    has_package_loaders = true,
+    has_math_log10 = true,
+    has_loadstring = true,
+    has_table_maxn = true,
+    has_module = true,
+    has_package_seeall = true,
+--]]
+
+    compat52 = true,
+--[[
+    has_mathx = true,
+    has_bit32 = true,
+    has_metamethod_ipairs = true,
+--]]
+
+    compat53 = false,
+--[[
+    has_math_log10 = true,
+    has_mathx = true,
+    has_metamethod_ipairs = true,
+--]]
+
+--[[ luajit
+    luajit_compat52 = true,
+    openresty = false,
+--]]
+
+}
+
+package.loaded.profile = profile        -- prevents loading of default profile
+
+return profile
+
+--
+-- Copyright (c) 2018-2019 Francois Perrad
+--
+-- This library is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
diff --git a/test/lua-Harness-tests/profile_lua51.lua b/test/lua-Harness-tests/profile_lua51.lua
new file mode 100644
index 0000000..8625b23
--- /dev/null
+++ b/test/lua-Harness-tests/profile_lua51.lua
@@ -0,0 +1,46 @@
+---
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+---
+
+local profile = {
+
+-- [[ compat 5.0
+    has_string_gfind = true,
+    has_math_mod = true,
+--]]
+
+    compat51 = false,
+--[[
+    has_unpack = true,
+    has_package_loaders = true,
+    has_math_log10 = true,
+    has_loadstring = true,
+    has_table_maxn = true,
+    has_module = true,
+    has_package_seeall = true,
+--]]
+
+    compat52 = false,
+--[[
+    has_mathx = true,
+    has_bit32 = true,
+    has_metamethod_ipairs = true,
+--]]
+
+--[[ luajit
+    luajit_compat52 = true,
+    openresty = false,
+--]]
+
+}
+
+package.loaded.profile = profile        -- prevents loading of default profile
+
+return profile
+
+--
+-- Copyright (c) 2018-2019 Francois Perrad
+--
+-- This library is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
diff --git a/test/lua-Harness-tests/profile_lua51_strict.lua b/test/lua-Harness-tests/profile_lua51_strict.lua
new file mode 100644
index 0000000..d8d1efd
--- /dev/null
+++ b/test/lua-Harness-tests/profile_lua51_strict.lua
@@ -0,0 +1,46 @@
+---
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+---
+
+local profile = {
+
+--[[ compat 5.0
+    has_string_gfind = true,
+    has_math_mod = true,
+--]]
+
+    compat51 = false,
+--[[
+    has_unpack = true,
+    has_package_loaders = true,
+    has_math_log10 = true,
+    has_loadstring = true,
+    has_table_maxn = true,
+    has_module = true,
+    has_package_seeall = true,
+--]]
+
+    compat52 = false,
+--[[
+    has_mathx = true,
+    has_bit32 = true,
+    has_metamethod_ipairs = true,
+--]]
+
+--[[ luajit
+    luajit_compat52 = true,
+    openresty = false,
+--]]
+
+}
+
+package.loaded.profile = profile        -- prevents loading of default profile
+
+return profile
+
+--
+-- Copyright (c) 2018-2019 Francois Perrad
+--
+-- This library is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
diff --git a/test/lua-Harness-tests/profile_lua52.lua b/test/lua-Harness-tests/profile_lua52.lua
new file mode 100644
index 0000000..fbc2fc4
--- /dev/null
+++ b/test/lua-Harness-tests/profile_lua52.lua
@@ -0,0 +1,46 @@
+---
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+---
+
+local profile = {
+
+--[[ compat 5.0
+    has_string_gfind = true,
+    has_math_mod = true,
+--]]
+
+    compat51 = true,
+--[[
+    has_unpack = true,
+    has_package_loaders = true,
+    has_math_log10 = true,
+    has_loadstring = true,
+    has_table_maxn = true,
+    has_module = true,
+    has_package_seeall = true,
+--]]
+
+    compat52 = false,
+--[[
+    has_mathx = true,
+    has_bit32 = true,
+    has_metamethod_ipairs = true,
+--]]
+
+--[[ luajit
+    luajit_compat52 = true,
+    openresty = false,
+--]]
+
+}
+
+package.loaded.profile = profile        -- prevents loading of default profile
+
+return profile
+
+--
+-- Copyright (c) 2018-2019 Francois Perrad
+--
+-- This library is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
diff --git a/test/lua-Harness-tests/profile_lua52_strict.lua b/test/lua-Harness-tests/profile_lua52_strict.lua
new file mode 100644
index 0000000..d8d1efd
--- /dev/null
+++ b/test/lua-Harness-tests/profile_lua52_strict.lua
@@ -0,0 +1,46 @@
+---
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+---
+
+local profile = {
+
+--[[ compat 5.0
+    has_string_gfind = true,
+    has_math_mod = true,
+--]]
+
+    compat51 = false,
+--[[
+    has_unpack = true,
+    has_package_loaders = true,
+    has_math_log10 = true,
+    has_loadstring = true,
+    has_table_maxn = true,
+    has_module = true,
+    has_package_seeall = true,
+--]]
+
+    compat52 = false,
+--[[
+    has_mathx = true,
+    has_bit32 = true,
+    has_metamethod_ipairs = true,
+--]]
+
+--[[ luajit
+    luajit_compat52 = true,
+    openresty = false,
+--]]
+
+}
+
+package.loaded.profile = profile        -- prevents loading of default profile
+
+return profile
+
+--
+-- Copyright (c) 2018-2019 Francois Perrad
+--
+-- This library is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
diff --git a/test/lua-Harness-tests/profile_lua53.lua b/test/lua-Harness-tests/profile_lua53.lua
new file mode 100644
index 0000000..ed1b91f
--- /dev/null
+++ b/test/lua-Harness-tests/profile_lua53.lua
@@ -0,0 +1,52 @@
+---
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+---
+
+local profile = {
+
+--[[ compat 5.0
+    has_string_gfind = true,
+    has_math_mod = true,
+--]]
+
+    compat51 = false,
+--[[
+    has_unpack = true,
+    has_package_loaders = true,
+    has_math_log10 = true,
+    has_loadstring = true,
+    has_table_maxn = true,
+    has_module = true,
+    has_package_seeall = true,
+--]]
+
+    compat52 = true,
+--[[
+    has_mathx = true,
+    has_bit32 = true,
+    has_metamethod_ipairs = true,
+--]]
+
+    compat53 = false,
+--[[
+    has_mathx = true,
+    has_metamethod_ipairs = true,
+--]]
+
+--[[ luajit
+    luajit_compat52 = true,
+    openresty = false,
+--]]
+
+}
+
+package.loaded.profile = profile        -- prevents loading of default profile
+
+return profile
+
+--
+-- Copyright (c) 2018-2019 Francois Perrad
+--
+-- This library is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
diff --git a/test/lua-Harness-tests/profile_lua53_noconv.lua b/test/lua-Harness-tests/profile_lua53_noconv.lua
new file mode 100644
index 0000000..c4500b3
--- /dev/null
+++ b/test/lua-Harness-tests/profile_lua53_noconv.lua
@@ -0,0 +1,55 @@
+---
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+---
+
+local profile = {
+
+--[[ compat 5.0
+    has_string_gfind = true,
+    has_math_mod = true,
+--]]
+
+    compat51 = false,
+--[[
+    has_unpack = true,
+    has_package_loaders = true,
+    has_math_log10 = true,
+    has_loadstring = true,
+    has_table_maxn = true,
+    has_module = true,
+    has_package_seeall = true,
+--]]
+
+    compat52 = true,
+--[[
+    has_mathx = true,
+    has_bit32 = true,
+    has_metamethod_ipairs = true,
+--]]
+
+    nocvtn2s = true,
+    nocvts2n = true,
+
+    compat53 = false,
+--[[
+    has_mathx = true,
+    has_metamethod_ipairs = true,
+--]]
+
+--[[ luajit
+    luajit_compat52 = true,
+    openresty = false,
+--]]
+
+}
+
+package.loaded.profile = profile        -- prevents loading of default profile
+
+return profile
+
+--
+-- Copyright (c) 2018-2019 Francois Perrad
+--
+-- This library is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
diff --git a/test/lua-Harness-tests/profile_lua53_strict.lua b/test/lua-Harness-tests/profile_lua53_strict.lua
new file mode 100644
index 0000000..399282b
--- /dev/null
+++ b/test/lua-Harness-tests/profile_lua53_strict.lua
@@ -0,0 +1,52 @@
+---
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+---
+
+local profile = {
+
+--[[ compat 5.0
+    has_string_gfind = true,
+    has_math_mod = true,
+--]]
+
+    compat51 = false,
+--[[
+    has_unpack = true,
+    has_package_loaders = true,
+    has_math_log10 = true,
+    has_loadstring = true,
+    has_table_maxn = true,
+    has_module = true,
+    has_package_seeall = true,
+--]]
+
+    compat52 = false,
+--[[
+    has_mathx = true,
+    has_bit32 = true,
+    has_metamethod_ipairs = true,
+--]]
+
+    compat53 = false,
+--[[
+    has_mathx = true,
+    has_metamethod_ipairs = true,
+--]]
+
+--[[ luajit
+    luajit_compat52 = true,
+    openresty = false,
+--]]
+
+}
+
+package.loaded.profile = profile        -- prevents loading of default profile
+
+return profile
+
+--
+-- Copyright (c) 2018-2019 Francois Perrad
+--
+-- This library is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
diff --git a/test/lua-Harness-tests/profile_lua54.lua b/test/lua-Harness-tests/profile_lua54.lua
new file mode 100644
index 0000000..ef4daa3
--- /dev/null
+++ b/test/lua-Harness-tests/profile_lua54.lua
@@ -0,0 +1,52 @@
+---
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+---
+
+local profile = {
+
+--[[ compat 5.0
+    has_string_gfind = true,
+    has_math_mod = true,
+--]]
+
+    compat51 = false,
+--[[
+    has_unpack = true,
+    has_package_loaders = true,
+    has_math_log10 = true,
+    has_loadstring = true,
+    has_table_maxn = true,
+    has_module = true,
+    has_package_seeall = true,
+--]]
+
+    compat52 = false,
+--[[
+    has_mathx = true,
+    has_bit32 = true,
+    has_metamethod_ipairs = true,
+--]]
+
+    compat53 = true,
+--[[
+    has_mathx = true,
+    has_metamethod_ipairs = true,
+--]]
+
+--[[ luajit
+    luajit_compat52 = true,
+    openresty = false,
+--]]
+
+}
+
+package.loaded.profile = profile        -- prevents loading of default profile
+
+return profile
+
+--
+-- Copyright (c) 2018-2019 Francois Perrad
+--
+-- This library is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
diff --git a/test/lua-Harness-tests/profile_lua54_noconv.lua b/test/lua-Harness-tests/profile_lua54_noconv.lua
new file mode 100644
index 0000000..b9e17c3
--- /dev/null
+++ b/test/lua-Harness-tests/profile_lua54_noconv.lua
@@ -0,0 +1,55 @@
+---
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+---
+
+local profile = {
+
+--[[ compat 5.0
+    has_string_gfind = true,
+    has_math_mod = true,
+--]]
+
+    compat51 = false,
+--[[
+    has_unpack = true,
+    has_package_loaders = true,
+    has_math_log10 = true,
+    has_loadstring = true,
+    has_table_maxn = true,
+    has_module = true,
+    has_package_seeall = true,
+--]]
+
+    compat52 = false,
+--[[
+    has_mathx = true,
+    has_bit32 = true,
+    has_metamethod_ipairs = true,
+--]]
+
+    nocvtn2s = true,
+    nocvts2n = true,
+
+    compat53 = true,
+--[[
+    has_mathx = true,
+    has_metamethod_ipairs = true,
+--]]
+
+--[[ luajit
+    luajit_compat52 = true,
+    openresty = false,
+--]]
+
+}
+
+package.loaded.profile = profile        -- prevents loading of default profile
+
+return profile
+
+--
+-- Copyright (c) 2018-2019 Francois Perrad
+--
+-- This library is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
diff --git a/test/lua-Harness-tests/profile_lua54_strict.lua b/test/lua-Harness-tests/profile_lua54_strict.lua
new file mode 100644
index 0000000..9fcfb79
--- /dev/null
+++ b/test/lua-Harness-tests/profile_lua54_strict.lua
@@ -0,0 +1,53 @@
+---
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+---
+
+local profile = {
+
+--[[ compat 5.0
+    has_string_gfind = true,
+    has_math_mod = true,
+--]]
+
+    compat51 = false,
+--[[
+    has_unpack = true,
+    has_package_loaders = true,
+    has_math_log10 = true,
+    has_loadstring = true,
+    has_table_maxn = true,
+    has_module = true,
+    has_package_seeall = true,
+--]]
+
+    compat52 = false,
+--[[
+    has_mathx = true,
+    has_bit32 = true,
+    has_metamethod_ipairs = true,
+--]]
+
+    compat53 = false,
+--[[
+    has_math_log10 = true,
+    has_mathx = true,
+    has_metamethod_ipairs = true,
+--]]
+
+--[[ luajit
+    luajit_compat52 = true,
+    openresty = false,
+--]]
+
+}
+
+package.loaded.profile = profile        -- prevents loading of default profile
+
+return profile
+
+--
+-- Copyright (c) 2018-2019 Francois Perrad
+--
+-- This library is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
diff --git a/test/lua-Harness-tests/profile_luajit20.lua b/test/lua-Harness-tests/profile_luajit20.lua
new file mode 100644
index 0000000..75461c2
--- /dev/null
+++ b/test/lua-Harness-tests/profile_luajit20.lua
@@ -0,0 +1,53 @@
+---
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+---
+
+local profile = {
+
+-- [[ compat 5.0
+    has_string_gfind = true,
+    has_math_mod = true,
+--]]
+
+    compat51 = false,
+--[[
+    has_unpack = true,
+    has_package_loaders = true,
+    has_math_log10 = true,
+    has_loadstring = true,
+    has_table_maxn = true,
+    has_module = true,
+    has_package_seeall = true,
+--]]
+
+    compat52 = false,
+--[[
+    has_mathx = true,
+    has_bit32 = true,
+    has_metamethod_ipairs = true,
+--]]
+
+    compat53 = false,
+--[[
+    has_math_log10 = true,
+    has_mathx = true,
+    has_metamethod_ipairs = true,
+--]]
+
+-- [[ luajit
+    luajit_compat52 = false,
+    openresty = false,
+--]]
+
+}
+
+package.loaded.profile = profile        -- prevents loading of default profile
+
+return profile
+
+--
+-- Copyright (c) 2018-2019 Francois Perrad
+--
+-- This library is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
diff --git a/test/lua-Harness-tests/profile_luajit20_compat52.lua b/test/lua-Harness-tests/profile_luajit20_compat52.lua
new file mode 100644
index 0000000..7064470
--- /dev/null
+++ b/test/lua-Harness-tests/profile_luajit20_compat52.lua
@@ -0,0 +1,53 @@
+---
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+---
+
+local profile = {
+
+--[[ compat 5.0
+    has_string_gfind = true,
+    has_math_mod = true,
+--]]
+
+    compat51 = false,
+--[[
+    has_unpack = true,
+    has_package_loaders = true,
+    has_math_log10 = true,
+    has_loadstring = true,
+    has_table_maxn = true,
+    has_module = true,
+    has_package_seeall = true,
+--]]
+
+    compat52 = false,
+--[[
+    has_mathx = true,
+    has_bit32 = false,
+    has_metamethod_ipairs = true,
+--]]
+
+    compat53 = false,
+--[[
+    has_math_log10 = true,
+    has_mathx = true,
+    has_metamethod_ipairs = true,
+--]]
+
+-- [[ luajit
+    luajit_compat52 = true,
+    openresty = false,
+--]]
+
+}
+
+package.loaded.profile = profile        -- prevents loading of default profile
+
+return profile
+
+--
+-- Copyright (c) 2018-2019 Francois Perrad
+--
+-- This library is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
diff --git a/test/lua-Harness-tests/profile_luajit21.lua b/test/lua-Harness-tests/profile_luajit21.lua
new file mode 100644
index 0000000..f24e85e
--- /dev/null
+++ b/test/lua-Harness-tests/profile_luajit21.lua
@@ -0,0 +1,53 @@
+---
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+---
+
+local profile = {
+
+--[[ compat 5.0
+    has_string_gfind = true,
+    has_math_mod = true,
+--]]
+
+    compat51 = false,
+--[[
+    has_unpack = true,
+    has_package_loaders = true,
+    has_math_log10 = true,
+    has_loadstring = true,
+    has_table_maxn = true,
+    has_module = true,
+    has_package_seeall = true,
+--]]
+
+    compat52 = false,
+--[[
+    has_mathx = true,
+    has_bit32 = true,
+    has_metamethod_ipairs = true,
+--]]
+
+    compat53 = false,
+--[[
+    has_math_log10 = true,
+    has_mathx = true,
+    has_metamethod_ipairs = true,
+--]]
+
+-- [[ luajit
+    luajit_compat52 = false,
+    openresty = false,
+--]]
+
+}
+
+package.loaded.profile = profile        -- prevents loading of default profile
+
+return profile
+
+--
+-- Copyright (c) 2018-2019 Francois Perrad
+--
+-- This library is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
diff --git a/test/lua-Harness-tests/profile_luajit21_compat52.lua b/test/lua-Harness-tests/profile_luajit21_compat52.lua
new file mode 100644
index 0000000..7064470
--- /dev/null
+++ b/test/lua-Harness-tests/profile_luajit21_compat52.lua
@@ -0,0 +1,53 @@
+---
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+---
+
+local profile = {
+
+--[[ compat 5.0
+    has_string_gfind = true,
+    has_math_mod = true,
+--]]
+
+    compat51 = false,
+--[[
+    has_unpack = true,
+    has_package_loaders = true,
+    has_math_log10 = true,
+    has_loadstring = true,
+    has_table_maxn = true,
+    has_module = true,
+    has_package_seeall = true,
+--]]
+
+    compat52 = false,
+--[[
+    has_mathx = true,
+    has_bit32 = false,
+    has_metamethod_ipairs = true,
+--]]
+
+    compat53 = false,
+--[[
+    has_math_log10 = true,
+    has_mathx = true,
+    has_metamethod_ipairs = true,
+--]]
+
+-- [[ luajit
+    luajit_compat52 = true,
+    openresty = false,
+--]]
+
+}
+
+package.loaded.profile = profile        -- prevents loading of default profile
+
+return profile
+
+--
+-- Copyright (c) 2018-2019 Francois Perrad
+--
+-- This library is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
diff --git a/test/lua-Harness-tests/profile_openresty.lua b/test/lua-Harness-tests/profile_openresty.lua
new file mode 100644
index 0000000..c151a39
--- /dev/null
+++ b/test/lua-Harness-tests/profile_openresty.lua
@@ -0,0 +1,53 @@
+---
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+---
+
+local profile = {
+
+--[[ compat 5.0
+    has_string_gfind = true,
+    has_math_mod = true,
+--]]
+
+    compat51 = false,
+--[[
+    has_unpack = true,
+    has_package_loaders = true,
+    has_math_log10 = true,
+    has_loadstring = true,
+    has_table_maxn = true,
+    has_module = true,
+    has_package_seeall = true,
+--]]
+
+    compat52 = false,
+--[[
+    has_mathx = true,
+    has_bit32 = false,
+    has_metamethod_ipairs = true,
+--]]
+
+    compat53 = false,
+--[[
+    has_math_log10 = true,
+    has_mathx = true,
+    has_metamethod_ipairs = true,
+--]]
+
+-- [[ luajit
+    luajit_compat52 = true,
+    openresty = true,
+--]]
+
+}
+
+package.loaded.profile = profile        -- prevents loading of default profile
+
+return profile
+
+--
+-- Copyright (c) 2018-2019 Francois Perrad
+--
+-- This library is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
diff --git a/test/lua-Harness-tests/profile_ravi.lua b/test/lua-Harness-tests/profile_ravi.lua
new file mode 100644
index 0000000..8cd2464
--- /dev/null
+++ b/test/lua-Harness-tests/profile_ravi.lua
@@ -0,0 +1,58 @@
+---
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+---
+
+-- luacheck: globals _VERSION
+_VERSION = 'Lua 5.3'    -- instead of 'Ravi 5.3'
+
+local profile = {
+
+--[[ compat 5.0
+    has_string_gfind = true,
+    has_math_mod = true,
+--]]
+
+    compat51 = true,
+--[[
+    has_unpack = true,
+    has_package_loaders = true,
+    has_math_log10 = true,
+    has_loadstring = true,
+    has_table_maxn = true,
+    has_module = true,
+    has_package_seeall = true,
+--]]
+
+    compat52 = true,
+--[[
+    has_mathx = true,
+    has_bit32 = true,
+    has_metamethod_ipairs = true,
+--]]
+
+    nocvtn2s = false,
+    nocvts2n = false,
+
+    compat53 = false,
+--[[
+    has_mathx = true,
+    has_metamethod_ipairs = true,
+--]]
+
+--[[ luajit
+    luajit_compat52 = true,
+    openresty = false,
+--]]
+
+}
+
+package.loaded.profile = profile        -- prevents loading of default profile
+
+return profile
+
+--
+-- Copyright (c) 2018-2019 Francois Perrad
+--
+-- This library is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
diff --git a/test/lua-Harness-tests/profile_tiny_fork.lua b/test/lua-Harness-tests/profile_tiny_fork.lua
new file mode 100644
index 0000000..f0df77b
--- /dev/null
+++ b/test/lua-Harness-tests/profile_tiny_fork.lua
@@ -0,0 +1,60 @@
+---
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+---
+
+require'compat53.math'
+-- luacheck: globals utf8
+utf8 = require'compat53.utf8'
+
+local profile = {
+
+--[[ compat 5.0
+    has_string_gfind = true,
+    has_math_mod = true,
+--]]
+
+    compat51 = false,
+--[[
+    has_unpack = true,
+    has_package_loaders = true,
+    has_math_log10 = true,
+    has_loadstring = true,
+    has_table_maxn = true,
+    has_module = true,
+    has_package_seeall = true,
+--]]
+
+    compat52 = false,
+--[[
+    has_mathx = true,
+    has_bit32 = true,
+    has_metamethod_ipairs = true,
+--]]
+
+    compat53 = false,
+--[[
+    has_math_log10 = true,
+    has_mathx = true,
+    has_metamethod_ipairs = true,
+--]]
+
+-- [[ luajit
+    luajit_compat52 = false,
+    openresty = false,
+    pack = true,
+    integer = true,
+    utf8 = true,
+--]]
+
+}
+
+package.loaded.profile = profile        -- prevents loading of default profile
+
+return profile
+
+--
+-- Copyright (c) 2018-2019 Francois Perrad
+--
+-- This library is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
diff --git a/test/lua-Harness-tests/rx_captures b/test/lua-Harness-tests/rx_captures
new file mode 100644
index 0000000..e209d26
--- /dev/null
+++ b/test/lua-Harness-tests/rx_captures
@@ -0,0 +1,13 @@
+(a.)..(..)		zzzabcdefzzz	ab\tef			basic match
+(a(b(c))(d))		abcd		abcd\tbc\tc\td		nested match
+((%w+))			abcd		abcd\tabcd		nested match
+(a*(.)%w(%s*))		aa!b c		aa!b \t!\t 		nested match
+(a?)..			abcd		a			opt
+(A?)..			abcd		''			opt
+()aa()			flaaap		3\t5			empty capture
+(.)%1			bookkeeper	o			backreference
+(%w+)%s+%1		hello hello	hello			backreference
+(.*)x			123x		123			repeated dot capture
+$(%w+)			$abc=		abc			not escaped
+
+## vim: noexpandtab tabstop=4 shiftwidth=4
diff --git a/test/lua-Harness-tests/rx_charclass b/test/lua-Harness-tests/rx_charclass
new file mode 100644
index 0000000..af5cb45
--- /dev/null
+++ b/test/lua-Harness-tests/rx_charclass
@@ -0,0 +1,38 @@
+[c]			abcdef		c		character class
+^[a]			abcdef		a		anchored character class
+[^e]			abcdef		a		negated character class
+^[a]?			abcdef		a		anchored optional character class
+[^e]?			abcdef		a		negated optional character class
+^[^e]			abcdef		a		anchored negated character class
+^[^a]			abcdef		nil		anchored negated character class
+[b-d]			abcdef		b		character range
+[b-d]			abxxef		b		character range
+[b-d]			axcxef		c		character range
+[b-d]			axxdef		d		character range
+[b-d]			axxxef		nil		character range
+[^b-d]			abcdef		a		negated character range
+[^b-d]			bbccdd		nil		negated character range
+[-]			ab-def		-		unescaped hyphen
+[%-]			ab-def		-		escaped hyphen
+[%-]			abcdef		nil		escaped hyphen
+[^%-]			---x--		x		negated escaped hyphen
+[^%-]			------		nil		negated escaped hyphen
+[%-+]			ab-def		-		escaped hyphen in range
+[%-+]			ab+def		+		escaped hyphen in range
+[%-+]			abcdef		nil		escaped hyphen in range
+[+%-]			ab-def		-		escaped hyphen in range
+[+%-]			ab+def		+		escaped hyphen in range
+[+%-]			abcdef		nil		escaped hyphen in range
+[^%-+]			---x--		x		negated escaped hyphen in range
+[^%-+]			------		nil		negated escaped hyphen in range
+[^+%-]			---x--		x		negated escaped hyphen in range
+[^+%-]			------		nil		negated escaped hyphen in range
+["\\]			\\		\		escaped backslash
+[%]]			]		]		escaped close bracket
+[%]			\\]]		/malformed pattern %(missing ']'%)/	unescaped backslash (or no closing brace)
+ab\\cd			ab\092cd	ab\cd		literal match with backslash
+%?			ab<?		?		literal match with question mark
+[A-Z0-9]		abcdef		nil		two enumerated ranges
+[A-Z0-9]		abcDef		D		two enumerated ranges
+
+## vim: noexpandtab tabstop=4 shiftwidth=4
diff --git a/test/lua-Harness-tests/rx_metachars b/test/lua-Harness-tests/rx_metachars
new file mode 100644
index 0000000..8716ca1
--- /dev/null
+++ b/test/lua-Harness-tests/rx_metachars
@@ -0,0 +1,117 @@
+.			a		a		dot (.)
+.			\n		\n		dot (.)
+.			''		nil		dot (.)
+a%s+f			abcdef		nil		whitespace (%s)
+ab%s+cdef		ab  cdef	ab  cdef	whitespace (%s)
+a%S+f			abcdef		abcdef		not whitespace (%S)
+a%S+f			ab cdef		nil		not whitespace (%S)
+^abc			abcdef		abc		start and end of string (^)
+^abc			abc\ndef	abc		start and end of string (^)
+^abc			def\nabc	nil		start and end of string (^)
+def\n^abc		def\nabc	nil		start and end of string (^)
+def$			abcdef		def		start and end of string ($)
+def$			abc\ndef	def		start and end of string ($)
+def$			def\nabc	nil		start and end of string ($)
+def$\nabc		def\nabc	nil		start and end of string (^)
+abc\n$			abc\n		abc\n		end of string ($)
+abc$			abc\n		nil		end of string ($)
+c\nd			abc\ndef	c\nd		newline (\n)
+c\nd			abc\010def	c\nd		newline (\n)
+c\n+d			abc\n\ndef	c\n\nd		newline (\n)
+a\n+f			abcdef		nil		newline (\n)
+b\nc			abc\ndef	nil		newline (\n)
+c\td			abc\tdef	c\td		horizontal tab (\t)
+c\td			abc\09def	c\td		horizontal tab (\t)
+c\t+d			abc\t\tdef	c\t\td		horizontal tab (\t)
+a\t+f			abcdef		nil		horizontal tab (\t)
+b\tc			abc\tdef	nil		horizontal tab (\t)
+c\rd			abc\rdef	c\rd		return (\r)
+c\rd			abc\013def	c\rd		return (\r)
+c\r+d			abc\r\rdef	c\r\rd		return (\r)
+a\r+f			abcdef		nil		return (\r)
+b\rc			abc\rdef	nil		return (\r)
+c\fd			abc\fdef	c\fd		formfeed (\f)
+c\fd			abc\012def	c\fd		formfeed (\f)
+c\f+d			abc\f\fdef	c\f\fd		formfeed (\f)
+a\f+f			abcdef		nil		formfeed (\f)
+b\fc			abc\fdef	nil		formfeed (\f)
+c\033d			abc!def		c!d		dec (\0)
+c\033d			abc\033def	c!d		dec (\0)
+c\033+d			abc!!def	c!!d		dec (\0)
+a\033+f			abcdef		nil		dec (\0)
+b\033c			abc!def		nil		dec (\0)
+a%^d			a^d		a^d		escaped (useless)
+a^d			a^d		a^d		not escaped
+%^d			^d		^d		escaped
+a%$d			a$d		a$d		escaped (useless)
+a$d			a$d		a$d		not escaped
+a%$			a$		a$		escaped
+a%(d			a(d		a(d		escaped
+a%)d			a)d		a)d		escaped
+a%%d			a%d		a%d		escaped
+a%			a%		/malformed pattern %(ends with '%%'%)/	not escaped
+a%.d			a.d		a.d		escaped
+a%.d			abd		nil		escaped
+a%[d			a[d		a[d		escaped
+a%]d			a]d		a]d		escaped
+a%*d			a*d		a*d		escaped
+*ad			*ad		*ad		not escaped
+a%+d			a+d		a+d		escaped
+a%-d			a-d		a-d		escaped
+a%?d			a?d		a?d		escaped
+a%yd			ayd		ayd		escaped
+a%w+f			a=[ *f		nil		word character
+a%w+f			abcdef		abcdef		word character
+a%W+f			a&%- f		a&%- f		not word character
+a%W+f			abcdef		nil		not word character
+a%d+f			abcdef		nil		digit
+ab%d+cdef		ab42cdef	ab42cdef	digit
+a%D+f			abcdef		abcdef		not digit
+a%D+f			ab0cdef		nil		not digit
+a%l+f			aBCDEf		nil		lowercase letter
+a%l+f			abcdef		abcdef		lowercase letter
+a%L+f			a&2D f		a&2D f		not lowercase letter
+a%L+f			aBCdEf		nil		not lowercase letter
+a%u+f			abcdef		nil		uppercase letter
+a%u+f			aBCDEf		aBCDEf		uppercase letter
+a%U+f			a&2d f		a&2d f		not uppercase letter
+a%U+f			a&2D f		nil		not uppercase letter
+a%a+f			aBcDef		aBcDef		all letter
+a%a+f			a=[ *f		nil		all letter
+a%A+f			a&%- f		a&%- f		not all letter
+a%A+f			abcdef		nil		not all letter
+a%g+f			aBcDef		aBcDef		printable
+a%g+f			a=[ *f		nil		printable
+a%G+f			a \nf		a \nf		not printable
+a%G+f			abcdef		nil		not printable
+a%p+f			abcdef		nil		ponctuation
+a%p+f			a,;:!f		a,;:!f		ponctuation
+a%P+f			abcdef		abcdef		not ponctuation
+a%P+f			adc:ef		nil		not ponctuation
+a%c+f			abcdef		nil		control character
+a%c+f			a\04\03\02f	a\04\03\02f	control character
+a%C+f			abcdef		abcdef		not control character
+a%C+f			abc\01ef	nil		not control character
+a%x+f			axyzef		nil		hexadecimal
+a%x+f			ab3Def		ab3Def		hexadecimal
+a%X+f			abcdef		nil		not hexadecimal
+a%X+f			axy;Zf		axy;Zf		not hexadecimal
+a%z+f			abcdef		nil		zero (deprecated)
+a\0+f			abcdef		nil		zero
+a%z+f			a\0f		a\0f		zero (deprecated)
+a\0+f			a\0f		a\0f		zero
+a%Z+f			abcdef		abcdef		not zero (deprecated)
+a[^\0]+f		abcdef		abcdef		not zero
+a%Z+f			abc\0ef		nil		not zero (deprecated)
+a[^\0]+f		abc\0ef		nil		not zero
+a%b()f			a(bcde)f	a(bcde)f	balanced
+a%b()f			a(b(de)f	nil		balanced
+a%b()f			a(b(d)e)f	a(b(d)e)f	balanced
+a%b''f			a'bcde'f	a'bcde'f	balanced
+a%b""f			a"bcde"f	a"bcde"f	balanced
+%f[b]bc			abcdef		bc		frontier
+%f[b]c			abcdef		nil		frontier
+%f[^ab]c		abacdef		c		frontier
+%f[^ab]d		abacdef		nil		frontier
+
+## vim: noexpandtab tabstop=4 shiftwidth=4
diff --git a/test/lua-Harness-tests/tap.lua b/test/lua-Harness-tests/tap.lua
new file mode 100644
index 0000000..96afec7
--- /dev/null
+++ b/test/lua-Harness-tests/tap.lua
@@ -0,0 +1,204 @@
+
+--
+-- lua-Harness : <https://fperrad.frama.io/lua-Harness/>
+--
+
+--[[
+
+        Test Anything Protocol : minimalist version
+
+]]
+
+if pcall(require, 'Test.More') then
+    diag 'Test.More loaded'
+    return
+end
+
+local _G = _G
+local os = os
+local pcall = pcall
+local print = print
+local require = require
+local tostring = tostring
+local type = type
+
+local curr_test = 0
+local expected_tests = 0
+local todo_upto = 0
+local todo_reason
+
+function plan (arg)
+    if arg ~= 'no_plan' then
+        expected_tests = arg
+        print("1.." .. tostring(arg))
+    end
+end
+
+function done_testing ()
+    print("1.." .. tostring(curr_test))
+end
+
+function skip_all (reason)
+    out = "1..0"
+    if reason then
+        out = out .. " # SKIP " .. reason
+    end
+    print(out)
+    os.exit(0)
+end
+
+function ok (test, name)
+    curr_test = curr_test + 1
+    local out = ''
+    if not test then
+        out = "not "
+    end
+    out = out .. "ok " .. tostring(curr_test)
+    if name then
+        out = out .. " - " .. name
+    end
+    if todo_reason and todo_upto >= curr_test then
+        out = out .. " # TODO # " .. todo_reason
+    end
+    print(out)
+end
+
+function nok (test, name)
+    ok(not test, name)
+end
+
+function is (got, expected, name)
+    local pass = got == expected
+    ok(pass, name)
+    if not pass then
+        diag("         got: " .. tostring(got))
+        diag("    expected: " .. tostring(expected))
+    end
+end
+
+function isnt (got, not_expected, name)
+    local pass = got ~= not_expected
+    ok(pass, name)
+    if not pass then
+        diag("         got: " .. tostring(got))
+        diag("    expected: anything else")
+    end
+end
+
+function like (got, pattern, name)
+    local pass = tostring(got):match(pattern)
+    ok(pass, name)
+    if not pass then
+        diag("                  " .. tostring(got))
+        diag("    doesn't match '" .. tostring(pattern) .. "'")
+    end
+end
+
+function type_ok (val, t, name)
+    if type(val) == t then
+        ok(true, name)
+    else
+        ok(false, name)
+        diag("    " .. tostring(val) .. " isn't a '" .. t .."' it's '" .. type(val) .. "'")
+    end
+end
+
+function pass (name)
+    ok(true, name)
+end
+
+function fail (name)
+    ok(false, name)
+end
+
+function require_ok (mod)
+    local r, msg = pcall(require, mod)
+    ok(r, "require '" .. mod .. "'")
+    if not r then
+        diag("    " .. msg)
+    end
+    return r
+end
+
+function eq_array (got, expected, name)
+    for i = 1, #expected do
+        local v = expected[i]
+        local val = got[i]
+        if val ~= v then
+            ok(false, name)
+            diag("    at index: " .. tostring(i))
+            diag("         got: " .. tostring(val))
+            diag("    expected: " .. tostring(v))
+            return
+        end
+    end
+    local extra = #got - #expected
+    if extra ~= 0 then
+        ok(false, name)
+        diag("    " .. tostring(extra) .. " unexpected item(s)")
+    else
+        ok(true, name)
+    end
+end
+
+function error_is (code, expected, name)
+    local r, msg = pcall(code)
+    if r then
+        ok(false, name)
+        diag("    unexpected success")
+        diag("    expected: " .. tostring(pattern))
+    else
+        is(msg, expected, name)
+    end
+end
+
+function error_like (code, pattern, name)
+    local r, msg = pcall(code)
+    if r then
+        ok(false, name)
+        diag("    unexpected success")
+        diag("    expected: " .. tostring(pattern))
+    else
+        like(msg, pattern, name)
+    end
+end
+
+function lives_ok (code, name)
+    local r, msg = pcall(code)
+    ok(r, name)
+    if not r then
+        diag("    " .. msg)
+    end
+end
+
+function diag (msg)
+    print("# " .. msg)
+end
+
+function skip (reason, count)
+    count = count or 1
+    local name = "# skip"
+    if reason then
+        name = name .. " " ..reason
+    end
+    for i = 1, count do
+        ok(true, name)
+    end
+end
+
+function skip_rest (reason)
+    skip(reason, expected_tests - curr_test)
+end
+
+function todo (reason, count)
+    count = count or 1
+    todo_upto = curr_test + count
+    todo_reason = reason
+end
+
+--
+-- Copyright (c) 2009-2018 Francois Perrad
+--
+-- This library is licensed under the terms of the MIT/X11 license,
+-- like Lua itself.
+--
-- 
2.28.0


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

* [Tarantool-patches] [WIP luajit 11/15] test: adjust lua-Harness test suite for Tarantool
  2021-03-04 10:23 [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites Sergey Kaplun via Tarantool-patches
                   ` (9 preceding siblings ...)
  2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 10/15] test: add lua-Harness test suite Sergey Kaplun via Tarantool-patches
@ 2021-03-04 10:23 ` Sergey Kaplun via Tarantool-patches
  2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 12/15] test: disable 305-utf8 of lua-Harness suite Sergey Kaplun via Tarantool-patches
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-04 10:23 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

This patch makes it possible to run lua-Harness test suite using
Tarantool.

Tarantool has its own loaded tap built in so need to change name to
another one.

203-lexico.t and 301-basic.t is adjusted to valid working with
out-of-source build in Tarantool CI.

Also creates additional list of files provided to prove via stdin.
This is required to avoid tests hungs via Tarantool's binary.
Partially this problem is descripted in tarantool/tarantool#5040.

Part of tarantool/tarantool#5844
Part of tarantool/tarantool#4473
---
Mergen Imeev <imeevma@gmail.com>: Author
Sergey Kaplun <skaplun@tarantool.org>: glanced commit message, made
commit consistence with the tarantool branch.

 .gitignore                                      |  1 +
 test/lua-Harness-tests/090-tap.t                |  2 +-
 test/lua-Harness-tests/091-profile.t            |  2 +-
 test/lua-Harness-tests/101-boolean.t            |  2 +-
 test/lua-Harness-tests/102-function.t           |  2 +-
 test/lua-Harness-tests/103-nil.t                |  2 +-
 test/lua-Harness-tests/104-number.t             |  2 +-
 test/lua-Harness-tests/105-string.t             |  2 +-
 test/lua-Harness-tests/106-table.t              |  2 +-
 test/lua-Harness-tests/107-thread.t             |  2 +-
 test/lua-Harness-tests/108-userdata.t           |  2 +-
 test/lua-Harness-tests/200-examples.t           |  2 +-
 test/lua-Harness-tests/201-assign.t             |  2 +-
 test/lua-Harness-tests/202-expr.t               |  2 +-
 test/lua-Harness-tests/203-lexico.t             | 14 +++++++++-----
 test/lua-Harness-tests/204-grammar.t            |  2 +-
 test/lua-Harness-tests/211-scope.t              |  2 +-
 test/lua-Harness-tests/212-function.t           |  2 +-
 test/lua-Harness-tests/213-closure.t            |  2 +-
 test/lua-Harness-tests/214-coroutine.t          |  2 +-
 test/lua-Harness-tests/221-table.t              |  2 +-
 test/lua-Harness-tests/222-constructor.t        |  2 +-
 test/lua-Harness-tests/223-iterator.t           |  2 +-
 test/lua-Harness-tests/231-metatable.t          |  2 +-
 test/lua-Harness-tests/232-object.t             |  2 +-
 test/lua-Harness-tests/241-standalone.t         | 10 +++++-----
 test/lua-Harness-tests/242-luac.t               |  2 +-
 test/lua-Harness-tests/301-basic.t              |  7 +++++--
 test/lua-Harness-tests/303-package.t            |  6 +++---
 test/lua-Harness-tests/304-string.t             |  2 +-
 test/lua-Harness-tests/305-utf8.t               |  2 +-
 test/lua-Harness-tests/306-table.t              |  2 +-
 test/lua-Harness-tests/307-math.t               |  2 +-
 test/lua-Harness-tests/308-io.t                 |  2 +-
 test/lua-Harness-tests/309-os.t                 |  2 +-
 test/lua-Harness-tests/310-debug.t              |  2 +-
 test/lua-Harness-tests/311-bit32.t              |  2 +-
 test/lua-Harness-tests/314-regex.t              |  2 +-
 test/lua-Harness-tests/320-stdin.t              |  2 +-
 test/lua-Harness-tests/401-bitop.t              |  2 +-
 test/lua-Harness-tests/402-ffi.t                |  2 +-
 test/lua-Harness-tests/403-jit.t                |  2 +-
 test/lua-Harness-tests/404-ext.t                |  2 +-
 test/lua-Harness-tests/411-luajit.t             |  2 +-
 test/lua-Harness-tests/CMakeLists.txt           | 17 +++++++++++++++--
 .../{tap.lua => tap_harness.lua}                |  0
 46 files changed, 77 insertions(+), 56 deletions(-)
 rename test/lua-Harness-tests/{tap.lua => tap_harness.lua} (100%)

diff --git a/.gitignore b/.gitignore
index 2103a30..1fb81bc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,3 +20,4 @@ compile_commands.json
 install_manifest.txt
 luajit-parse-memprof
 luajit.pc
+tests_list
diff --git a/test/lua-Harness-tests/090-tap.t b/test/lua-Harness-tests/090-tap.t
index 92f04d8..99932f2 100755
--- a/test/lua-Harness-tests/090-tap.t
+++ b/test/lua-Harness-tests/090-tap.t
@@ -22,7 +22,7 @@
 
 ]]
 
-require'tap'
+require'tap_harness'
 
 plan(3)
 ok( true, 'ok' )
diff --git a/test/lua-Harness-tests/091-profile.t b/test/lua-Harness-tests/091-profile.t
index db47438..ebc142d 100755
--- a/test/lua-Harness-tests/091-profile.t
+++ b/test/lua-Harness-tests/091-profile.t
@@ -22,7 +22,7 @@
 
 ]]
 
-require'tap'
+require'tap_harness'
 
 plan'no_plan'
 
diff --git a/test/lua-Harness-tests/101-boolean.t b/test/lua-Harness-tests/101-boolean.t
index 0033eff..653509f 100755
--- a/test/lua-Harness-tests/101-boolean.t
+++ b/test/lua-Harness-tests/101-boolean.t
@@ -22,7 +22,7 @@
 
 ]]
 
-require'tap'
+require'tap_harness'
 local has_op53 = _VERSION >= 'Lua 5.3'
 
 plan'no_plan'
diff --git a/test/lua-Harness-tests/102-function.t b/test/lua-Harness-tests/102-function.t
index 48ed814..cb7e9d0 100755
--- a/test/lua-Harness-tests/102-function.t
+++ b/test/lua-Harness-tests/102-function.t
@@ -22,7 +22,7 @@
 
 --]]
 
-require'tap'
+require'tap_harness'
 local has_op53 = _VERSION >= 'Lua 5.3'
 
 plan'no_plan'
diff --git a/test/lua-Harness-tests/103-nil.t b/test/lua-Harness-tests/103-nil.t
index 561b101..a74c491 100755
--- a/test/lua-Harness-tests/103-nil.t
+++ b/test/lua-Harness-tests/103-nil.t
@@ -22,7 +22,7 @@
 
 --]]
 
-require'tap'
+require'tap_harness'
 local has_op53 = _VERSION >= 'Lua 5.3'
 
 plan'no_plan'
diff --git a/test/lua-Harness-tests/104-number.t b/test/lua-Harness-tests/104-number.t
index 0d4d3fd..634d22a 100755
--- a/test/lua-Harness-tests/104-number.t
+++ b/test/lua-Harness-tests/104-number.t
@@ -22,7 +22,7 @@
 
 --]]
 
-require'tap'
+require'tap_harness'
 local profile = require'profile'
 local has_op53 = _VERSION >= 'Lua 5.3'
 
diff --git a/test/lua-Harness-tests/105-string.t b/test/lua-Harness-tests/105-string.t
index cd8c88b..f2ea067 100755
--- a/test/lua-Harness-tests/105-string.t
+++ b/test/lua-Harness-tests/105-string.t
@@ -22,7 +22,7 @@
 
 --]]
 
-require'tap'
+require'tap_harness'
 local profile = require'profile'
 local has_op53 = _VERSION >= 'Lua 5.3'
 
diff --git a/test/lua-Harness-tests/106-table.t b/test/lua-Harness-tests/106-table.t
index 0c0ba49..4a66f69 100755
--- a/test/lua-Harness-tests/106-table.t
+++ b/test/lua-Harness-tests/106-table.t
@@ -22,7 +22,7 @@
 
 --]]
 
-require'tap'
+require'tap_harness'
 local has_op53 = _VERSION >= 'Lua 5.3'
 
 plan'no_plan'
diff --git a/test/lua-Harness-tests/107-thread.t b/test/lua-Harness-tests/107-thread.t
index 3d4af18..e67ef36 100755
--- a/test/lua-Harness-tests/107-thread.t
+++ b/test/lua-Harness-tests/107-thread.t
@@ -22,7 +22,7 @@
 
 --]]
 
-require'tap'
+require'tap_harness'
 local has_op53 = _VERSION >= 'Lua 5.3'
 
 plan'no_plan'
diff --git a/test/lua-Harness-tests/108-userdata.t b/test/lua-Harness-tests/108-userdata.t
index b1e3641..687b1b8 100755
--- a/test/lua-Harness-tests/108-userdata.t
+++ b/test/lua-Harness-tests/108-userdata.t
@@ -22,7 +22,7 @@
 
 --]]
 
-require'tap'
+require'tap_harness'
 local has_op53 = _VERSION >= 'Lua 5.3'
 
 plan'no_plan'
diff --git a/test/lua-Harness-tests/200-examples.t b/test/lua-Harness-tests/200-examples.t
index 362aae3..cb06a80 100755
--- a/test/lua-Harness-tests/200-examples.t
+++ b/test/lua-Harness-tests/200-examples.t
@@ -24,7 +24,7 @@ First tests in order to check infrastructure.
 
 --]]
 
-require'tap'
+require'tap_harness'
 
 plan(5)
 
diff --git a/test/lua-Harness-tests/201-assign.t b/test/lua-Harness-tests/201-assign.t
index 7d023d8..f7ed472 100755
--- a/test/lua-Harness-tests/201-assign.t
+++ b/test/lua-Harness-tests/201-assign.t
@@ -28,7 +28,7 @@ L<https://www.lua.org/manual/5.4/manual.html#3.3.3>
 
 --]]
 
-require'tap'
+require'tap_harness'
 local has_env = _VERSION >= 'Lua 5.2'
 
 plan'no_plan'
diff --git a/test/lua-Harness-tests/202-expr.t b/test/lua-Harness-tests/202-expr.t
index 2576750..f03d5ea 100755
--- a/test/lua-Harness-tests/202-expr.t
+++ b/test/lua-Harness-tests/202-expr.t
@@ -28,7 +28,7 @@ L<https://www.lua.org/manual/5.4/manual.html#3.4>
 
 --]]
 
-require'tap'
+require'tap_harness'
 local profile = require'profile'
 local nocvtn2s = profile.nocvtn2s
 local nocvts2n = profile.nocvts2n
diff --git a/test/lua-Harness-tests/203-lexico.t b/test/lua-Harness-tests/203-lexico.t
index c1abebf..0a73f8c 100755
--- a/test/lua-Harness-tests/203-lexico.t
+++ b/test/lua-Harness-tests/203-lexico.t
@@ -31,7 +31,7 @@ L<https://www.lua.org/manual/5.4/manual.html#3.1>
 
 --]]
 
-require'tap'
+require'tap_harness'
 local loadstring = loadstring or load
 local luajit21 = jit and (jit.version_num >= 20100 or jit.version:match'^RaptorJIT')
 
@@ -117,20 +117,24 @@ do
     like(msg, "^[^:]+:%d+: unfinished long comment .-near")
 end
 
+-- Adapt tests for testing with Tarantool's out of source build
+-- on read only file system. CUR_SOURCE_DIR is set via CMake.
+local path_to_sources = os.getenv('CUR_SOURCE_DIR') .. '/'
+
 if _VERSION >= 'Lua 5.2' or jit then
-    dofile'lexico52/lexico.t'
+    dofile(path_to_sources .. 'lexico52/lexico.t')
 end
 
 if _VERSION >= 'Lua 5.3' or luajit21 then
-    dofile'lexico53/lexico.t'
+    dofile(path_to_sources .. 'lexico53/lexico.t')
 end
 
 if _VERSION >= 'Lua 5.4' then
-    dofile'lexico54/lexico.t'
+    dofile(path_to_sources .. 'lexico54/lexico.t')
 end
 
 if jit and pcall(require, 'ffi') then
-    dofile'lexicojit/lexico.t'
+    dofile(path_to_sources .. 'lexicojit/lexico.t')
 end
 
 done_testing()
diff --git a/test/lua-Harness-tests/204-grammar.t b/test/lua-Harness-tests/204-grammar.t
index d9ae3a6..03580f4 100755
--- a/test/lua-Harness-tests/204-grammar.t
+++ b/test/lua-Harness-tests/204-grammar.t
@@ -28,7 +28,7 @@ L<https://www.lua.org/manual/5.4/manual.html#9>
 
 --]]
 
-require'tap'
+require'tap_harness'
 local profile = require'profile'
 local has_goto = _VERSION >= 'Lua 5.2' or jit
 local has_attr = _VERSION >= 'Lua 5.4'
diff --git a/test/lua-Harness-tests/211-scope.t b/test/lua-Harness-tests/211-scope.t
index 64eed52..8e26a6f 100755
--- a/test/lua-Harness-tests/211-scope.t
+++ b/test/lua-Harness-tests/211-scope.t
@@ -30,7 +30,7 @@ See section "Local Variables and Blocks" in "Programming in Lua".
 
 --]]
 
-require'tap'
+require'tap_harness'
 
 plan(10)
 
diff --git a/test/lua-Harness-tests/212-function.t b/test/lua-Harness-tests/212-function.t
index 2851053..405035e 100755
--- a/test/lua-Harness-tests/212-function.t
+++ b/test/lua-Harness-tests/212-function.t
@@ -30,7 +30,7 @@ See section "Functions" in "Programming in Lua".
 
 --]]
 
-require'tap'
+require'tap_harness'
 local loadstring = loadstring or load
 
 plan(68)
diff --git a/test/lua-Harness-tests/213-closure.t b/test/lua-Harness-tests/213-closure.t
index fc3bd29..16a8a21 100755
--- a/test/lua-Harness-tests/213-closure.t
+++ b/test/lua-Harness-tests/213-closure.t
@@ -24,7 +24,7 @@ See section "Closures" in "Programming in Lua".
 
 --]]
 
-require'tap'
+require'tap_harness'
 
 plan(15)
 
diff --git a/test/lua-Harness-tests/214-coroutine.t b/test/lua-Harness-tests/214-coroutine.t
index 92929e1..1ca1cb5 100755
--- a/test/lua-Harness-tests/214-coroutine.t
+++ b/test/lua-Harness-tests/214-coroutine.t
@@ -30,7 +30,7 @@ See section "Coroutines" in "Programming in Lua".
 
 --]]
 
-require'tap'
+require'tap_harness'
 local profile = require'profile'
 local luajit21 = jit and (jit.version_num >= 20100 or jit.version:match'^RaptorJIT')
 local has_coroutine52 = _VERSION >= 'Lua 5.2' or jit
diff --git a/test/lua-Harness-tests/221-table.t b/test/lua-Harness-tests/221-table.t
index 7ed6c65..0caf037 100755
--- a/test/lua-Harness-tests/221-table.t
+++ b/test/lua-Harness-tests/221-table.t
@@ -24,7 +24,7 @@ See section "Tables" in "Programming in Lua".
 
 --]]
 
-require'tap'
+require'tap_harness'
 
 plan(25)
 
diff --git a/test/lua-Harness-tests/222-constructor.t b/test/lua-Harness-tests/222-constructor.t
index a01be2e..28037bf 100755
--- a/test/lua-Harness-tests/222-constructor.t
+++ b/test/lua-Harness-tests/222-constructor.t
@@ -30,7 +30,7 @@ See section "Table Constructors" in "Programming in Lua".
 
 --]]
 
-require'tap'
+require'tap_harness'
 
 plan(16)
 
diff --git a/test/lua-Harness-tests/223-iterator.t b/test/lua-Harness-tests/223-iterator.t
index 777ad73..073f3cd 100755
--- a/test/lua-Harness-tests/223-iterator.t
+++ b/test/lua-Harness-tests/223-iterator.t
@@ -25,7 +25,7 @@ section "Coroutines as Iterators" in "Programming in Lua".
 
 --]]
 
-require'tap'
+require'tap_harness'
 
 plan(8)
 
diff --git a/test/lua-Harness-tests/231-metatable.t b/test/lua-Harness-tests/231-metatable.t
index a2c6499..b94f608 100755
--- a/test/lua-Harness-tests/231-metatable.t
+++ b/test/lua-Harness-tests/231-metatable.t
@@ -30,7 +30,7 @@ See section "Metatables and Metamethods" in "Programming in Lua".
 
 --]]
 
-require'tap'
+require'tap_harness'
 local profile = require'profile'
 local has_metamethod52 = _VERSION >= 'Lua 5.2' or profile.luajit_compat52
 local has_metamethod_ipairs = _VERSION == 'Lua 5.2' or profile.compat52 or profile.luajit_compat52
diff --git a/test/lua-Harness-tests/232-object.t b/test/lua-Harness-tests/232-object.t
index 0d87572..0d22232 100755
--- a/test/lua-Harness-tests/232-object.t
+++ b/test/lua-Harness-tests/232-object.t
@@ -24,7 +24,7 @@ See section "Object-Oriented Programming" in "Programming in Lua".
 
 --]]
 
-require'tap'
+require'tap_harness'
 
 plan(18)
 
diff --git a/test/lua-Harness-tests/241-standalone.t b/test/lua-Harness-tests/241-standalone.t
index c99f324..4916ccc 100755
--- a/test/lua-Harness-tests/241-standalone.t
+++ b/test/lua-Harness-tests/241-standalone.t
@@ -28,7 +28,7 @@ L<https://www.lua.org/manual/5.4/manual.html#7>
 
 --]]
 
-require'tap'
+require'tap_harness'
 local has_bytecode = not ujit and not ravi
 local has_error52 = _VERSION >= 'Lua 5.2'
 local has_error53 = _VERSION >= 'Lua 5.3'
@@ -228,14 +228,14 @@ end
 like(f:read'*l', "^usage: ", "no file")
 f:close()
 
-cmd = lua .. [[ -ltap -e "print(type(ok))"]]
+cmd = lua .. [[ -ltap_harness -e "print(type(ok))"]]
 f = io.popen(cmd)
-is(f:read'*l', 'function', "-ltap")
+is(f:read'*l', 'function', "-ltap_harness")
 f:close()
 
-cmd = lua .. [[ -l tap -e "print(type(ok))"]]
+cmd = lua .. [[ -l tap_harness -e "print(type(ok))"]]
 f = io.popen(cmd)
-is(f:read'*l', 'function', "-l tap")
+is(f:read'*l', 'function', "-l tap_harness")
 f:close()
 
 cmd = lua .. [[ -l lpeg -e "print(1)" 2>&1]]
diff --git a/test/lua-Harness-tests/242-luac.t b/test/lua-Harness-tests/242-luac.t
index 2d166e5..da54f68 100755
--- a/test/lua-Harness-tests/242-luac.t
+++ b/test/lua-Harness-tests/242-luac.t
@@ -28,7 +28,7 @@ L<https://www.lua.org/manual/5.4/manual.html#7>
 
 --]]
 
-require'tap'
+require'tap_harness'
 
 if jit then
     skip_all("LuaJIT")
diff --git a/test/lua-Harness-tests/301-basic.t b/test/lua-Harness-tests/301-basic.t
index e45599e..e119933 100755
--- a/test/lua-Harness-tests/301-basic.t
+++ b/test/lua-Harness-tests/301-basic.t
@@ -30,7 +30,7 @@ L<https://www.lua.org/manual/5.4/manual.html#6.1>
 
 --]]
 
-require'tap'
+require'tap_harness'
 local profile = require'profile'
 local has_error53 = _VERSION >= 'Lua 5.3'
 local has_gcinfo = _VERSION == 'Lua 5.1'
@@ -843,7 +843,10 @@ do -- xpcall
 end
 
 if jit and pcall(require, 'ffi') then
-    dofile'lexicojit/basic.t'
+    -- Adapt test for testing with Tarantool's out of source build
+    -- on read only file system. CUR_SOURCE_DIR is set via CMake.
+    local path_to_sources = os.getenv('CUR_SOURCE_DIR')
+    dofile(path_to_sources .. '/lexicojit/basic.t')
 end
 
 done_testing()
diff --git a/test/lua-Harness-tests/303-package.t b/test/lua-Harness-tests/303-package.t
index 7e5216d..996ce22 100755
--- a/test/lua-Harness-tests/303-package.t
+++ b/test/lua-Harness-tests/303-package.t
@@ -30,7 +30,7 @@ L<https://www.lua.org/manual/5.4/manual.html#6.3>
 
 --]]
 
-require'tap'
+require'tap_harness'
 local profile = require'profile'
 local luajit21 = jit and (jit.version_num >= 20100 or jit.version:match'^RaptorJIT')
 local has_loaders = _VERSION == 'Lua 5.1'
@@ -130,9 +130,9 @@ end
 
 -- searchpath
 if has_searcherpath then
-    local p = package.searchpath('tap', package.path)
+    local p = package.searchpath('tap_harness', package.path)
     type_ok(p, 'string', "searchpath")
-    p = package.searchpath('tap', 'bad path')
+    p = package.searchpath('tap_harness', 'bad path')
     is(p, nil)
 else
     is(package.searchpath, nil, "no package.searchpath")
diff --git a/test/lua-Harness-tests/304-string.t b/test/lua-Harness-tests/304-string.t
index 991600a..293fd8e 100755
--- a/test/lua-Harness-tests/304-string.t
+++ b/test/lua-Harness-tests/304-string.t
@@ -30,7 +30,7 @@ L<https://www.lua.org/manual/5.4/manual.html#6.4>
 
 ]]
 
-require'tap'
+require'tap_harness'
 local profile = require'profile'
 local luajit21 = jit and (jit.version_num >= 20100 or jit.version:match'^RaptorJIT')
 local has_dump53 = _VERSION >= 'Lua 5.3' or jit
diff --git a/test/lua-Harness-tests/305-utf8.t b/test/lua-Harness-tests/305-utf8.t
index 4304b6c..59a2e6b 100755
--- a/test/lua-Harness-tests/305-utf8.t
+++ b/test/lua-Harness-tests/305-utf8.t
@@ -30,7 +30,7 @@ L<https://www.lua.org/manual/5.4/manual.html#6.5>
 
 --]]
 
-require 'tap'
+require'tap_harness'
 
 local profile = require'profile'
 local has_utf8 = _VERSION >= 'Lua 5.3' or (jit and jit.version:match'moonjit') or profile.utf8
diff --git a/test/lua-Harness-tests/306-table.t b/test/lua-Harness-tests/306-table.t
index 9836655..6e76492 100755
--- a/test/lua-Harness-tests/306-table.t
+++ b/test/lua-Harness-tests/306-table.t
@@ -30,7 +30,7 @@ L<https://www.lua.org/manual/5.4/manual.html#6.6>
 
 --]]
 
-require'tap'
+require'tap_harness'
 local profile = require'profile'
 local luajit21 = jit and (jit.version_num >= 20100 or jit.version:match'^RaptorJIT')
 local has_foreach = _VERSION == 'Lua 5.1'
diff --git a/test/lua-Harness-tests/307-math.t b/test/lua-Harness-tests/307-math.t
index 8b51ed1..762567f 100755
--- a/test/lua-Harness-tests/307-math.t
+++ b/test/lua-Harness-tests/307-math.t
@@ -30,7 +30,7 @@ L<https://www.lua.org/manual/5.4/manual.html#6.7>
 
 --]]
 
-require'tap'
+require'tap_harness'
 local profile = require'profile'
 local has_integer = _VERSION >= 'Lua 5.3' or (jit and jit.version:match'moonjit') or profile.integer
 local has_mathx = _VERSION < 'Lua 5.3' or profile.compat52 or profile.compat53 or profile.has_mathx
diff --git a/test/lua-Harness-tests/308-io.t b/test/lua-Harness-tests/308-io.t
index cdbcb83..ec6ac9d 100755
--- a/test/lua-Harness-tests/308-io.t
+++ b/test/lua-Harness-tests/308-io.t
@@ -30,7 +30,7 @@ L<https://www.lua.org/manual/5.4/manual.html#6.8>
 
 --]]
 
-require'tap'
+require'tap_harness'
 local profile = require'profile'
 local luajit21 = jit and (jit.version_num >= 20100 or jit.version:match'^RaptorJIT')
 local has_write51 = _VERSION == 'Lua 5.1' and (not profile.luajit_compat52 or ujit)
diff --git a/test/lua-Harness-tests/309-os.t b/test/lua-Harness-tests/309-os.t
index e42fb53..b34ade5 100755
--- a/test/lua-Harness-tests/309-os.t
+++ b/test/lua-Harness-tests/309-os.t
@@ -30,7 +30,7 @@ L<https://www.lua.org/manual/5.4/manual.html#6.9>
 
 --]]
 
-require'tap'
+require'tap_harness'
 local profile = require'profile'
 local luajit20 = jit and (jit.version_num < 20100 and not jit.version:match'^RaptorJIT')
 local has_execute51 = _VERSION == 'Lua 5.1' and (not profile.luajit_compat52 or ujit)
diff --git a/test/lua-Harness-tests/310-debug.t b/test/lua-Harness-tests/310-debug.t
index f78af03..63194ac 100755
--- a/test/lua-Harness-tests/310-debug.t
+++ b/test/lua-Harness-tests/310-debug.t
@@ -30,7 +30,7 @@ L<https://www.lua.org/manual/5.4/manual.html#6.10>
 
 ]]
 
-require 'tap'
+require'tap_harness'
 local profile = require'profile'
 local has_getfenv = _VERSION == 'Lua 5.1'
 local has_gethook54 = _VERSION >= 'Lua 5.4'
diff --git a/test/lua-Harness-tests/311-bit32.t b/test/lua-Harness-tests/311-bit32.t
index 7023906..a314f47 100755
--- a/test/lua-Harness-tests/311-bit32.t
+++ b/test/lua-Harness-tests/311-bit32.t
@@ -29,7 +29,7 @@ L<https://www.lua.org/manual/5.2/manual.html#6.7>
 
 --]]
 
-require 'tap'
+require'tap_harness'
 local profile = require'profile'
 local has_bit32 = _VERSION == 'Lua 5.2' or profile.compat52 or profile.has_bit32
 
diff --git a/test/lua-Harness-tests/314-regex.t b/test/lua-Harness-tests/314-regex.t
index ad4554c..ac7ad80 100755
--- a/test/lua-Harness-tests/314-regex.t
+++ b/test/lua-Harness-tests/314-regex.t
@@ -49,7 +49,7 @@ Description of the test.
 
 --]]
 
-require'tap'
+require'tap_harness'
 local loadstring = loadstring or load
 
 plan(162)
diff --git a/test/lua-Harness-tests/320-stdin.t b/test/lua-Harness-tests/320-stdin.t
index 36528e8..0c348d7 100755
--- a/test/lua-Harness-tests/320-stdin.t
+++ b/test/lua-Harness-tests/320-stdin.t
@@ -24,7 +24,7 @@ Tests Lua Basic & IO Libraries with stdin
 
 --]]
 
-require'tap'
+require'tap_harness'
 
 local lua = arg[-3] or arg[-1]
 
diff --git a/test/lua-Harness-tests/401-bitop.t b/test/lua-Harness-tests/401-bitop.t
index f95aebf..d1225bd 100755
--- a/test/lua-Harness-tests/401-bitop.t
+++ b/test/lua-Harness-tests/401-bitop.t
@@ -24,7 +24,7 @@ See L<http://bitop.luajit.org/>.
 
 --]]
 
-require 'tap'
+require'tap_harness'
 
 if not jit then
     skip_all("only with LuaJIT")
diff --git a/test/lua-Harness-tests/402-ffi.t b/test/lua-Harness-tests/402-ffi.t
index a2e32a5..2423b2e 100755
--- a/test/lua-Harness-tests/402-ffi.t
+++ b/test/lua-Harness-tests/402-ffi.t
@@ -24,7 +24,7 @@ See L<http://luajit.org/ext_ffi.html>.
 
 --]]
 
-require 'tap'
+require'tap_harness'
 
 if not jit then
     skip_all("only with LuaJIT")
diff --git a/test/lua-Harness-tests/403-jit.t b/test/lua-Harness-tests/403-jit.t
index 0073c90..6c0870a 100755
--- a/test/lua-Harness-tests/403-jit.t
+++ b/test/lua-Harness-tests/403-jit.t
@@ -24,7 +24,7 @@ See L<http://luajit.org/ext_jit.html>.
 
 --]]
 
-require 'tap'
+require'tap_harness'
 local profile = require'profile'
 
 if not jit then
diff --git a/test/lua-Harness-tests/404-ext.t b/test/lua-Harness-tests/404-ext.t
index 22a52c7..906ed51 100755
--- a/test/lua-Harness-tests/404-ext.t
+++ b/test/lua-Harness-tests/404-ext.t
@@ -24,7 +24,7 @@ See L<http://luajit.org/ext_jit.html>.
 
 --]]
 
-require 'tap'
+require'tap_harness'
 local profile = require'profile'
 
 local luajit21 = jit and (jit.version_num >= 20100 or jit.version:match'^RaptorJIT')
diff --git a/test/lua-Harness-tests/411-luajit.t b/test/lua-Harness-tests/411-luajit.t
index 05111be..e6bf031 100755
--- a/test/lua-Harness-tests/411-luajit.t
+++ b/test/lua-Harness-tests/411-luajit.t
@@ -24,7 +24,7 @@ See L<http://luajit.org/running.html>
 
 --]]
 
-require'tap'
+require'tap_harness'
 local profile = require'profile'
 
 if not jit or ujit then
diff --git a/test/lua-Harness-tests/CMakeLists.txt b/test/lua-Harness-tests/CMakeLists.txt
index 9b35e5a..e28cadd 100644
--- a/test/lua-Harness-tests/CMakeLists.txt
+++ b/test/lua-Harness-tests/CMakeLists.txt
@@ -26,7 +26,17 @@ string(CONCAT LUA_CPATH
   "${LUAJIT_SOURCE_DIR}/?${CMAKE_SHARED_LIBRARY_SUFFIX}\;"
 )
 
-add_custom_target(lua-Harness-tests DEPENDS ${LUAJIT_TEST_BINARY})
+# FIXME: Until https://github.com/tarantool/tarantool/issues/5040
+# is resolved, Tarantool enters interactive mode if prove input
+# is not stdin. As a result test hungs and not run at all.
+# This part should be dropped, and argument to prove is passed
+# as directory.
+file(GLOB TESTS_LIST ${CMAKE_CURRENT_SOURCE_DIR}/*.t)
+string(REPLACE ";" "\n" TESTS_LIST "${TESTS_LIST}")
+set(LIST_FILE ${CMAKE_CURRENT_BINARY_DIR}/tests_list)
+file(WRITE ${LIST_FILE} ${TESTS_LIST})
+
+add_custom_target(lua-Harness-tests DEPENDS ${LUAJIT_TEST_BINARY} ${LIST_FILE})
 
 add_custom_command(TARGET lua-Harness-tests
   COMMENT "Running lua-Harness tests"
@@ -40,7 +50,10 @@ add_custom_command(TARGET lua-Harness-tests
     # for more info.
     # So use less preferable way for tests.
     # See the root CMakeLists.txt for more info.
-    ${PROVE} ${CMAKE_CURRENT_SOURCE_DIR}
+    # XXX: Adapt to run test witht Tarantool on read-only
+    # file systems with dofile(CUR_SOURCE_DIR..filename).
+    CUR_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}
+    ${PROVE} - < ${LIST_FILE}
       --exec '${LUAJIT_TEST_COMMAND} -l profile_luajit21'
       ${LUA_TEST_FLAGS}
   WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
diff --git a/test/lua-Harness-tests/tap.lua b/test/lua-Harness-tests/tap_harness.lua
similarity index 100%
rename from test/lua-Harness-tests/tap.lua
rename to test/lua-Harness-tests/tap_harness.lua
-- 
2.28.0


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

* [Tarantool-patches] [WIP luajit 12/15] test: disable 305-utf8 of lua-Harness suite
  2021-03-04 10:23 [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites Sergey Kaplun via Tarantool-patches
                   ` (10 preceding siblings ...)
  2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 11/15] test: adjust lua-Harness test suite for Tarantool Sergey Kaplun via Tarantool-patches
@ 2021-03-04 10:23 ` Sergey Kaplun via Tarantool-patches
  2021-03-04 10:24 ` [Tarantool-patches] [WIP luajit 13/15] test: disable 241-standalone " Sergey Kaplun via Tarantool-patches
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-04 10:23 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

This patch disables 305-utf8.t from the lua-Harness test suite, because
the built-in utf8 module in Tarantool does not work as expected in the
test.

Partially the problem mentioned in tarantool/tarantool#5241.

Part of tarantool/tarantool#5844
Part of tarantool/tarantool#4473
---
 test/lua-Harness-tests/{305-utf8.t => 305-utf8.t.disabled} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename test/lua-Harness-tests/{305-utf8.t => 305-utf8.t.disabled} (100%)

diff --git a/test/lua-Harness-tests/305-utf8.t b/test/lua-Harness-tests/305-utf8.t.disabled
similarity index 100%
rename from test/lua-Harness-tests/305-utf8.t
rename to test/lua-Harness-tests/305-utf8.t.disabled
-- 
2.28.0


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

* [Tarantool-patches] [WIP luajit 13/15] test: disable 241-standalone of lua-Harness suite
  2021-03-04 10:23 [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites Sergey Kaplun via Tarantool-patches
                   ` (11 preceding siblings ...)
  2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 12/15] test: disable 305-utf8 of lua-Harness suite Sergey Kaplun via Tarantool-patches
@ 2021-03-04 10:24 ` Sergey Kaplun via Tarantool-patches
  2021-03-04 10:24 ` [Tarantool-patches] [WIP luajit 14/15] test: disable 411-luajit " Sergey Kaplun via Tarantool-patches
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-04 10:24 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

This patch disables 241-standalone.t from the lua-Harness test suite,
because some flags in Tarantool and LuaJIT work differently, or they are
not present at all in Tarantool. For example, -i, -b, -j.
See tarantool/tarantool#5541.

Part of tarantool/tarantool#5844
Part of tarantool/tarantool#4473
---
 .../{241-standalone.t => 241-standalone.t.disabled}               | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename test/lua-Harness-tests/{241-standalone.t => 241-standalone.t.disabled} (100%)

diff --git a/test/lua-Harness-tests/241-standalone.t b/test/lua-Harness-tests/241-standalone.t.disabled
similarity index 100%
rename from test/lua-Harness-tests/241-standalone.t
rename to test/lua-Harness-tests/241-standalone.t.disabled
-- 
2.28.0


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

* [Tarantool-patches] [WIP luajit 14/15] test: disable 411-luajit of lua-Harness suite
  2021-03-04 10:23 [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites Sergey Kaplun via Tarantool-patches
                   ` (12 preceding siblings ...)
  2021-03-04 10:24 ` [Tarantool-patches] [WIP luajit 13/15] test: disable 241-standalone " Sergey Kaplun via Tarantool-patches
@ 2021-03-04 10:24 ` Sergey Kaplun via Tarantool-patches
  2021-03-04 10:24 ` [Tarantool-patches] [WIP luajit 15/15] test: skip test for getenv in 309-os.t Sergey Kaplun via Tarantool-patches
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-04 10:24 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

This patch disables 411-luajit.t from the lua-Harness test suite,
because Tarantool does not support -b and -j flags.
See tarantool/tarantool#5541.

Part of tarantool/tarantool#5844
Part of tarantool/tarantool#4473
---
 test/lua-Harness-tests/{411-luajit.t => 411-luajit.t.disabled} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename test/lua-Harness-tests/{411-luajit.t => 411-luajit.t.disabled} (100%)

diff --git a/test/lua-Harness-tests/411-luajit.t b/test/lua-Harness-tests/411-luajit.t.disabled
similarity index 100%
rename from test/lua-Harness-tests/411-luajit.t
rename to test/lua-Harness-tests/411-luajit.t.disabled
-- 
2.28.0


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

* [Tarantool-patches] [WIP luajit 15/15] test: skip test for getenv in 309-os.t
  2021-03-04 10:23 [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites Sergey Kaplun via Tarantool-patches
                   ` (13 preceding siblings ...)
  2021-03-04 10:24 ` [Tarantool-patches] [WIP luajit 14/15] test: disable 411-luajit " Sergey Kaplun via Tarantool-patches
@ 2021-03-04 10:24 ` Sergey Kaplun via Tarantool-patches
  2021-03-04 16:24 ` [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites Sergey Ostanevich via Tarantool-patches
  2021-03-09 23:59 ` Igor Munkin via Tarantool-patches
  16 siblings, 0 replies; 26+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-04 10:24 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

Inside Tarantool's GiHub-CI there is not defined variable LOGNAME nor
USERNAME. This leads to failed test inside CI, because a string is
expected.

This test is skipped when this variable is `nil`.

Part of tarantool/tarantool#5844
Part of tarantool/tarantool#4473
---
 test/lua-Harness-tests/309-os.t | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/test/lua-Harness-tests/309-os.t b/test/lua-Harness-tests/309-os.t
index b34ade5..0a7dfec 100755
--- a/test/lua-Harness-tests/309-os.t
+++ b/test/lua-Harness-tests/309-os.t
@@ -170,7 +170,11 @@ do -- getenv
     is(os.getenv('__IMPROBABLE__'), nil, "function getenv")
 
     local user = os.getenv('LOGNAME') or os.getenv('USERNAME')
-    type_ok(user, 'string', "function getenv")
+    if not user then
+        skip("no LOGNAME and USERNAME")
+    else
+        type_ok(user, 'string', "function getenv")
+    end
 end
 
 do -- remove
-- 
2.28.0


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

* Re: [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites
  2021-03-04 10:23 [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites Sergey Kaplun via Tarantool-patches
                   ` (14 preceding siblings ...)
  2021-03-04 10:24 ` [Tarantool-patches] [WIP luajit 15/15] test: skip test for getenv in 309-os.t Sergey Kaplun via Tarantool-patches
@ 2021-03-04 16:24 ` Sergey Ostanevich via Tarantool-patches
  2021-03-04 19:58   ` Sergey Kaplun via Tarantool-patches
  2021-03-09 23:59 ` Igor Munkin via Tarantool-patches
  16 siblings, 1 reply; 26+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-04 16:24 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Hi!

Thanks for the patchset - brief review

part 1 - obvious, LGTM.

part 2 - LGTM, good to have all follow-ups set.

part 3 - should have a follow-up ticket to cover all suppressions, if we plan to fix them.

part 4-8 are LGTM

part 9 (_G and some modules in Tarantool are different): Are we plan to fix it in some way? There should be a follow-up then.

parts 10-15 are LGTM

Regards,
Sergos

> On 4 Mar 2021, at 13:23, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> WARNING: This patch doesn't require full and precise review now.
> 
> This draft should be structured (commits at least) from test
> suite to test suite if necessary.
> 
> You can complain test suites with the following command, for example:
> | $ diff --color -urZ test/PUC-Lua-5.1-tests/ ~/Downloads/lua5.1-tests/
> 
> Branch: https://github.com/tarantool/luajit/tree/skaplun/gh-4473-adopt-luavela-test-suites
> Tarantool's branch: https://github.com/tarantool/tarantool/tree/skaplun/gh-4473-adopt-luavela-test-suites
> Epic: https://github.com/tarantool/tarantool/issues/4473
> Issues:
> * https://github.com/tarantool/tarantool/issues/5845
> * https://github.com/tarantool/tarantool/issues/4064
> * https://github.com/tarantool/tarantool/issues/5844
> 
> CI is red due to ASan failure [0] for PUC-Lua-5.1 test suite.
> Looks related to https://github.com/tarantool/tarantool/issues/5747,
> but it is hard to tell without backtrace.
> 
> Locally, I get tons of errors like this for each of newly added test
> suites:
> | ==31930==WARNING: ASan is ignoring requested __asan_handle_no_return: stack top: 0x7fffbb603000; bottom 0x7f4e271fd000; size: 0x00b194406000 (762696458240)
> | False positive error reports may follow
> | For details see https://github.com/google/sanitizers/issues/189
> 
> After that there are failures like:
> 
> | ==24658==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7f6b741fefa8 at pc 0x000000c91926 bp 0x7f6b741fec90 sp 0x7f6b741fec88
> | READ of size 8 at 0x7f6b741fefa8 thread T0
> |     #0 0xc91925 in lj_strfmt_pushvf /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_strfmt.c:438:23
> |     #1 0xc6f8fe in lj_err_lex /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_err.c:651:9
> |     #2 0xce0fa1 in lj_lex_error /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_lex.c:495:3
> |     #3 0xce3285 in err_token /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_parse.c:175:3
> |     #4 0xcf27bc in parse_stmt /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_parse.c
> |     #5 0xce3ceb in parse_chunk /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_parse.c:2684:14
> |     #6 0xce3ceb in lj_parse /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_parse.c:2717:3
> |     #7 0xc7eeaa in cpparser /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_load.c:41:29
> |     #8 0xd8a6b7 in lj_vm_cpcall /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/build/third_party/luajit/src/lj_vm.S:1191
> |     #9 0xc7fed6 in lua_loadx /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_load.c:58:12
> |     #10 0xc7fed6 in luaL_loadbufferx /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_load.c:143:10
> |     #11 0xca9b12 in lj_cf_load /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lib_base.c:401:14
> |     #12 0xd8a2fa in lj_BC_FUNCC /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/build/third_party/luajit/src/lj_vm.S:811
> |     #13 0xc5be1f in lua_pcall /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_api.c:1158:12
> |     #14 0xb2ad71 in luaT_call /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/src/lua/utils.c:1022:6
> |     #15 0xb1532c in lua_main /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/src/lua/init.c:559:11
> |     #16 0xb14c9a in run_script_f /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/src/lua/init.c:634:7
> |     #17 0x526d96 in fiber_cxx_invoke(int (*)(__va_list_tag*), __va_list_tag*) /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/src/lib/core/fiber.h:882:10
> |     #18 0xb7f688 in fiber_loop /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/src/lib/core/fiber.c:879:18
> |     #19 0x14b3b10 in coro_init /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/coro/coro.c:110:3
> |
> | Address 0x7f6b741fefa8 is a wild pointer.
> | SUMMARY: AddressSanitizer: stack-buffer-overflow /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_strfmt.c:438:23 in lj_strfmt_pushvf
> | Shadow bytes around the buggy address:
> |   0x0fedee837da0: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
> |   0x0fedee837db0: 00 00 00 f3 f3 f3 f3 f3 00 00 00 00 00 00 00 00
> |   0x0fedee837dc0: f1 f1 f1 f1 00 00 00 00 00 00 00 04 f3 f3 f3 f3
> |   0x0fedee837dd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> |   0x0fedee837de0: f1 f1 f1 f1 00 00 00 f3 f3 f3 f3 f3 f2 f2 f2 f2
> | =>0x0fedee837df0: f8 f8 f8 f8 f3[f3]f3 f3 00 00 00 00 00 00 00 00
> |   0x0fedee837e00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> |   0x0fedee837e10: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 f8 f8 f8 f2
> |   0x0fedee837e20: f2 f2 f2 f2 f8 f8 f8 f2 f2 f2 f2 f2 f8 f8 f8 f8
> |   0x0fedee837e30: f2 f2 f2 f2 f8 f8 f8 f2 f2 f2 f2 f2 f8 f8 f8 f2
> |   0x0fedee837e40: f2 f2 f2 f2 f8 f8 f8 f2 f2 f2 f2 f2 f8 f8 f8 f2
> | Shadow byte legend (one shadow byte represents 8 application bytes):
> |   Addressable:           00
> |   Partially addressable: 01 02 03 04 05 06 07 
> |   Heap left redzone:       fa
> |   Freed heap region:       fd
> |   Stack left redzone:      f1
> |   Stack mid redzone:       f2
> |   Stack right redzone:     f3
> |   Stack after return:      f5
> |   Stack use after scope:   f8
> 
> It can be simply reproduce locally with:
> | $ ASAN=ON LSAN_OPTIONS=suppressions=asan/lsan.supp ASAN_OPTIONS=heap_profile=0:unmap_shadow_on_exit=1:detect_invalid_pointer_pairs=1:symbolize=1:detect_leaks=1:dump_instruction_bytes=1:print_suppressions=0:asan_stack=0 src/tarantool -e 'prog = [[ do]] for _=1,3 do pcall(loadstring(string.sub(prog, 1, _))) end'
> 
> It may be the reason of failures too, see [1][2].
> 
> According to [3], there is no any way except to compile with -asan-stack
> flag, but it looks like overkill. So I propose to exclude PUC-Lua-5.1
> test suite from ASan job for now (at least this is out of scoupe of the
> original issue).
> 
> Mergen Imeev (8):
>  test: add LuaJIT-test-cleanup test suite
>  test: change tests to match de5568e
>  test: change tests to match c198167
>  test: change tests to match 5a61e1a
>  test: change LuaJIT suite tests to match b4e6bf0
>  test: adjust LuaJIT test suite for Tarantool
>  test: add lua-Harness test suite
>  test: adjust lua-Harness test suite for Tarantool
> 
> Sergey Kaplun (7):
>  test: add PUC-Rio Lua 5.1 test suite
>  test: adapt PUC-Rio Lua 5.1 test suite for LuaJIT
>  test: adapt Lua 5.1 test suite for Tarantool
>  test: disable 305-utf8 of lua-Harness suite
>  test: disable 241-standalone of lua-Harness suite
>  test: disable 411-luajit of lua-Harness suite
>  test: skip test for getenv in 309-os.t
> 
> .gitignore                                    |    1 +
> .luacheckrc                                   |    7 +-
> CMakeLists.txt                                |    8 +
> test/CMakeLists.txt                           |    6 +
> test/LuaJIT-tests/CMakeLists.txt              |   20 +
> test/LuaJIT-tests/README.md                   |  110 ++
> test/LuaJIT-tests/bc/constov.lua              |   16 +
> test/LuaJIT-tests/bc/index                    |    1 +
> test/LuaJIT-tests/common/expect_error.lua     |   16 +
> test/LuaJIT-tests/common/ffi_util.inc         |   41 +
> .../common/test_runner_canary.lua             |    1 +
> test/LuaJIT-tests/computations.lua            |  113 ++
> test/LuaJIT-tests/index                       |    6 +
> test/LuaJIT-tests/lang/andor.lua              |   61 +
> test/LuaJIT-tests/lang/assignment.lua         |   46 +
> test/LuaJIT-tests/lang/compare.lua            |  323 +++++
> test/LuaJIT-tests/lang/compare_nan.lua        |   99 ++
> test/LuaJIT-tests/lang/concat.lua             |  112 ++
> test/LuaJIT-tests/lang/constant/index         |    2 +
> test/LuaJIT-tests/lang/constant/number.lua    |   12 +
> test/LuaJIT-tests/lang/constant/table.lua     |   15 +
> test/LuaJIT-tests/lang/coroutine.lua          |    8 +
> test/LuaJIT-tests/lang/for.lua                |   45 +
> test/LuaJIT-tests/lang/gc.lua                 |   42 +
> test/LuaJIT-tests/lang/goto.lua               |  149 +++
> test/LuaJIT-tests/lang/index                  |   18 +
> test/LuaJIT-tests/lang/length.lua             |   23 +
> test/LuaJIT-tests/lang/meta/arith.lua         |  118 ++
> test/LuaJIT-tests/lang/meta/arith_jit.lua     |   68 +
> test/LuaJIT-tests/lang/meta/call.lua          |   81 ++
> test/LuaJIT-tests/lang/meta/cat.lua           |   61 +
> test/LuaJIT-tests/lang/meta/comp.lua          |  120 ++
> test/LuaJIT-tests/lang/meta/comp_jit.lua      |  104 ++
> test/LuaJIT-tests/lang/meta/debuginfo.lua     |   81 ++
> test/LuaJIT-tests/lang/meta/eq.lua            |   30 +
> test/LuaJIT-tests/lang/meta/eq_jit.lua        |   35 +
> test/LuaJIT-tests/lang/meta/framegap.lua      |   24 +
> test/LuaJIT-tests/lang/meta/index             |   14 +
> test/LuaJIT-tests/lang/meta/index.lua         |   60 +
> test/LuaJIT-tests/lang/meta/len.lua           |   42 +
> test/LuaJIT-tests/lang/meta/newindex.lua      |   69 +
> test/LuaJIT-tests/lang/meta/nomm.lua          |   21 +
> test/LuaJIT-tests/lang/modulo.lua             |   46 +
> test/LuaJIT-tests/lang/self.lua               |   19 +
> test/LuaJIT-tests/lang/table.lua              |   32 +
> test/LuaJIT-tests/lang/tail_recursion.lua     |   20 +
> test/LuaJIT-tests/lang/upvalue/closure.lua    |   84 ++
> test/LuaJIT-tests/lang/upvalue/index          |    1 +
> test/LuaJIT-tests/lang/vararg_jit.lua         |   95 ++
> test/LuaJIT-tests/lib/base/assert.lua         |   33 +
> test/LuaJIT-tests/lib/base/error.lua          |   43 +
> test/LuaJIT-tests/lib/base/getfenv.lua        |   13 +
> .../LuaJIT-tests/lib/base/getsetmetatable.lua |   33 +
> test/LuaJIT-tests/lib/base/index              |   11 +
> test/LuaJIT-tests/lib/base/ipairs.lua         |   41 +
> test/LuaJIT-tests/lib/base/next.lua           |   17 +
> test/LuaJIT-tests/lib/base/pairs.lua          |   73 ++
> test/LuaJIT-tests/lib/base/pcall_jit.lua      |   74 ++
> test/LuaJIT-tests/lib/base/select.lua         |  105 ++
> .../lib/base/tonumber_tostring.lua            |   81 ++
> test/LuaJIT-tests/lib/base/xpcall_jit.lua     |   83 ++
> test/LuaJIT-tests/lib/bit.lua                 |   98 ++
> test/LuaJIT-tests/lib/contents.lua            |  171 +++
> test/LuaJIT-tests/lib/coroutine/index         |    1 +
> test/LuaJIT-tests/lib/coroutine/yield.lua     |  109 ++
> test/LuaJIT-tests/lib/ffi/bit64.lua           |  130 ++
> test/LuaJIT-tests/lib/ffi/cdata_var.lua       |   47 +
> test/LuaJIT-tests/lib/ffi/copy_fill.lua       |   64 +
> test/LuaJIT-tests/lib/ffi/err.lua             |   35 +
> test/LuaJIT-tests/lib/ffi/ffi_arith_ptr.lua   |  106 ++
> test/LuaJIT-tests/lib/ffi/ffi_bitfield.lua    |  108 ++
> test/LuaJIT-tests/lib/ffi/ffi_call.lua        |  266 ++++
> test/LuaJIT-tests/lib/ffi/ffi_callback.lua    |  158 +++
> test/LuaJIT-tests/lib/ffi/ffi_const.lua       |  113 ++
> test/LuaJIT-tests/lib/ffi/ffi_convert.lua     |  787 +++++++++++
> test/LuaJIT-tests/lib/ffi/ffi_enum.lua        |   57 +
> .../lib/ffi/ffi_gcstep_recursive.lua          |   66 +
> test/LuaJIT-tests/lib/ffi/ffi_jit_arith.lua   |  155 +++
> test/LuaJIT-tests/lib/ffi/ffi_jit_call.lua    |  154 +++
> test/LuaJIT-tests/lib/ffi/ffi_jit_conv.lua    |  277 ++++
> test/LuaJIT-tests/lib/ffi/ffi_lex_number.lua  |   51 +
> test/LuaJIT-tests/lib/ffi/ffi_metatype.lua    |  245 ++++
> test/LuaJIT-tests/lib/ffi/ffi_new.lua         |  106 ++
> test/LuaJIT-tests/lib/ffi/ffi_parse_array.lua |   78 ++
> test/LuaJIT-tests/lib/ffi/ffi_parse_basic.lua |  131 ++
> test/LuaJIT-tests/lib/ffi/ffi_parse_cdef.lua  |   77 ++
> .../LuaJIT-tests/lib/ffi/ffi_parse_struct.lua |  259 ++++
> test/LuaJIT-tests/lib/ffi/ffi_tabov.lua       |   12 +
> test/LuaJIT-tests/lib/ffi/index               |   12 +
> test/LuaJIT-tests/lib/ffi/istype.lua          |   88 ++
> test/LuaJIT-tests/lib/ffi/jit_array.lua       |  104 ++
> test/LuaJIT-tests/lib/ffi/jit_complex.lua     |  109 ++
> test/LuaJIT-tests/lib/ffi/jit_misc.lua        |  109 ++
> test/LuaJIT-tests/lib/ffi/jit_struct.lua      |  201 +++
> test/LuaJIT-tests/lib/ffi/meta_tostring.lua   |   55 +
> test/LuaJIT-tests/lib/ffi/redir.lua           |   19 +
> test/LuaJIT-tests/lib/ffi/type_punning.lua    |  138 ++
> test/LuaJIT-tests/lib/index                   |    8 +
> test/LuaJIT-tests/lib/math/abs.lua            |   16 +
> test/LuaJIT-tests/lib/math/constants.lua      |    8 +
> test/LuaJIT-tests/lib/math/index              |    3 +
> test/LuaJIT-tests/lib/math/random.lua         |   47 +
> test/LuaJIT-tests/lib/string/byte.lua         |   92 ++
> test/LuaJIT-tests/lib/string/char.lua         |   29 +
> test/LuaJIT-tests/lib/string/dump.lua         |   31 +
> test/LuaJIT-tests/lib/string/format/index     |    1 +
> test/LuaJIT-tests/lib/string/format/num.lua   |  184 +++
> test/LuaJIT-tests/lib/string/index            |   11 +
> test/LuaJIT-tests/lib/string/len.lua          |   14 +
> test/LuaJIT-tests/lib/string/lower_upper.lua  |   51 +
> test/LuaJIT-tests/lib/string/metatable.lua    |    3 +
> .../lib/string/multiple_functions.lua         |   16 +
> test/LuaJIT-tests/lib/string/rep.lua          |   68 +
> test/LuaJIT-tests/lib/string/reverse.lua      |   13 +
> test/LuaJIT-tests/lib/string/sub.lua          |  189 +++
> test/LuaJIT-tests/lib/table/concat.lua        |   55 +
> test/LuaJIT-tests/lib/table/index             |    6 +
> test/LuaJIT-tests/lib/table/insert.lua        |   17 +
> test/LuaJIT-tests/lib/table/misc.lua          |   58 +
> test/LuaJIT-tests/lib/table/new.lua           |   11 +
> test/LuaJIT-tests/lib/table/pack.lua          |    7 +
> test/LuaJIT-tests/lib/table/remove.lua        |   42 +
> test/LuaJIT-tests/lib/table/sort.lua          |   27 +
> test/LuaJIT-tests/misc/alias_alloc.lua        |   54 +
> test/LuaJIT-tests/misc/api_call.lua           |   98 ++
> test/LuaJIT-tests/misc/catch_wrap.lua         |   45 +
> test/LuaJIT-tests/misc/coro_traceback.lua     |    8 +
> test/LuaJIT-tests/misc/coro_yield.lua         |  111 ++
> test/LuaJIT-tests/misc/debug_gc.lua           |   47 +
> test/LuaJIT-tests/misc/dualnum.lua            |   47 +
> test/LuaJIT-tests/misc/for_dir.lua            |   13 +
> test/LuaJIT-tests/misc/fori_coerce.lua        |   33 +
> test/LuaJIT-tests/misc/gc_rechain.lua         |   32 +
> test/LuaJIT-tests/misc/gc_trace.lua           |   37 +
> test/LuaJIT-tests/misc/gcstep.lua             |   33 +
> test/LuaJIT-tests/misc/hook_active.lua        |   95 ++
> test/LuaJIT-tests/misc/hook_line.lua          |   41 +
> test/LuaJIT-tests/misc/hook_norecord.lua      |   12 +
> test/LuaJIT-tests/misc/hook_record.lua        |    8 +
> test/LuaJIT-tests/misc/hook_top.lua           |   55 +
> test/LuaJIT-tests/misc/jit_flush.lua          |   50 +
> test/LuaJIT-tests/misc/lightud.lua            |   88 ++
> test/LuaJIT-tests/misc/loop_unroll.lua        |   35 +
> test/LuaJIT-tests/misc/parse_comp.lua         |   13 +
> test/LuaJIT-tests/misc/parse_esc.lua          |    7 +
> test/LuaJIT-tests/misc/parse_misc.lua         |   31 +
> test/LuaJIT-tests/misc/phi_conv.lua           |   53 +
> test/LuaJIT-tests/misc/recurse_deep.lua       |   29 +
> test/LuaJIT-tests/misc/recurse_tail.lua       |   22 +
> test/LuaJIT-tests/misc/stack_gc.lua           |   15 +
> test/LuaJIT-tests/misc/stack_purge.lua        |   25 +
> test/LuaJIT-tests/misc/stackov.lua            |   40 +
> test/LuaJIT-tests/misc/stackovc.lua           |    4 +
> test/LuaJIT-tests/misc/tcall_base.lua         |   20 +
> test/LuaJIT-tests/misc/tcall_loop.lua         |    8 +
> test/LuaJIT-tests/misc/tonumber_scan.lua      |  180 +++
> test/LuaJIT-tests/misc/uclo.lua               |   91 ++
> test/LuaJIT-tests/misc/unordered_jit.lua      |   96 ++
> test/LuaJIT-tests/misc/wbarrier.lua           |    7 +
> test/LuaJIT-tests/misc/wbarrier_jit.lua       |   18 +
> test/LuaJIT-tests/misc/wbarrier_obar.lua      |   22 +
> test/LuaJIT-tests/opt/dse/array.lua           |  197 +++
> test/LuaJIT-tests/opt/dse/field.lua           |   70 +
> test/LuaJIT-tests/opt/dse/index               |    2 +
> test/LuaJIT-tests/opt/fold/index              |    1 +
> test/LuaJIT-tests/opt/fold/kfold.lua          |   81 ++
> test/LuaJIT-tests/opt/fuse.lua                |    5 +
> test/LuaJIT-tests/opt/fwd/hrefk_rollback.lua  |   32 +
> test/LuaJIT-tests/opt/fwd/index               |    3 +
> test/LuaJIT-tests/opt/fwd/tnew_tdup.lua       |   69 +
> test/LuaJIT-tests/opt/fwd/upval.lua           |   50 +
> test/LuaJIT-tests/opt/index                   |    6 +
> test/LuaJIT-tests/opt/loop/index              |    1 +
> test/LuaJIT-tests/opt/loop/unroll.lua         |   32 +
> test/LuaJIT-tests/opt/sink/alloc.lua          |  126 ++
> test/LuaJIT-tests/opt/sink/ffi.lua            |  121 ++
> test/LuaJIT-tests/opt/sink/ffi_nosink.lua     |   45 +
> test/LuaJIT-tests/opt/sink/index              |    4 +
> test/LuaJIT-tests/opt/sink/nosink.lua         |  109 ++
> test/LuaJIT-tests/src/cpptest.cpp             |  129 ++
> test/LuaJIT-tests/src/ctest.c                 |  339 +++++
> test/LuaJIT-tests/sysdep/catch_cpp.lua        |   71 +
> test/LuaJIT-tests/sysdep/ffi_include_gtk.lua  |    9 +
> test/LuaJIT-tests/sysdep/ffi_include_std.lua  |   36 +
> test/LuaJIT-tests/sysdep/ffi_lib_c.lua        |   87 ++
> test/LuaJIT-tests/sysdep/ffi_lib_z.lua        |  107 ++
> test/LuaJIT-tests/test.lua                    |  416 ++++++
> test/LuaJIT-tests/trace/exit_frame.lua        |   79 ++
> test/LuaJIT-tests/trace/exit_growstack.lua    |   28 +
> test/LuaJIT-tests/trace/exit_jfuncf.lua       |   30 +
> test/LuaJIT-tests/trace/gc64_slot_revival.lua |   18 +
> test/LuaJIT-tests/trace/index                 |    7 +
> test/LuaJIT-tests/trace/phi/copyspill.lua     |   53 +
> test/LuaJIT-tests/trace/phi/index             |    3 +
> test/LuaJIT-tests/trace/phi/ref.lua           |  131 ++
> test/LuaJIT-tests/trace/phi/rotate.lua        |  149 +++
> test/LuaJIT-tests/trace/snap.lua              |   47 +
> test/LuaJIT-tests/trace/stitch.lua            |   19 +
> .../unportable/ffi_arith_int64.lua            |   68 +
> test/LuaJIT-tests/unportable/math_special.lua |   55 +
> test/PUC-Lua-5.1-tests/CMakeLists.txt         |   92 ++
> test/PUC-Lua-5.1-tests/README                 |   41 +
> test/PUC-Lua-5.1-tests/all.lua                |  145 +++
> 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            |  432 +++++++
> test/PUC-Lua-5.1-tests/code.lua               |  143 ++
> test/PUC-Lua-5.1-tests/constructs.lua         |  247 ++++
> test/PUC-Lua-5.1-tests/db.lua                 |  538 ++++++++
> test/PUC-Lua-5.1-tests/errors.lua             |  264 ++++
> 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                 |  320 +++++
> 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               |  195 +++
> test/PUC-Lua-5.1-tests/math.lua               |  213 +++
> test/PUC-Lua-5.1-tests/nextvar.lua            |  403 ++++++
> test/PUC-Lua-5.1-tests/pm.lua                 |  281 ++++
> 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 ++
> test/lua-Harness-tests/000-sanity.t           |   54 +
> test/lua-Harness-tests/001-if.t               |   88 ++
> test/lua-Harness-tests/002-table.t            |   67 +
> test/lua-Harness-tests/011-while.t            |   89 ++
> test/lua-Harness-tests/012-repeat.t           |   85 ++
> test/lua-Harness-tests/014-fornum.t           |  151 +++
> test/lua-Harness-tests/015-forlist.t          |  111 ++
> test/lua-Harness-tests/090-tap.t              |   37 +
> test/lua-Harness-tests/091-profile.t          |   45 +
> test/lua-Harness-tests/101-boolean.t          |  127 ++
> test/lua-Harness-tests/102-function.t         |  206 +++
> test/lua-Harness-tests/103-nil.t              |  127 ++
> test/lua-Harness-tests/104-number.t           |  246 ++++
> test/lua-Harness-tests/105-string.t           |  277 ++++
> test/lua-Harness-tests/106-table.t            |  135 ++
> test/lua-Harness-tests/107-thread.t           |  135 ++
> test/lua-Harness-tests/108-userdata.t         |  132 ++
> test/lua-Harness-tests/200-examples.t         |  104 ++
> test/lua-Harness-tests/201-assign.t           |  150 +++
> test/lua-Harness-tests/202-expr.t             |  157 +++
> test/lua-Harness-tests/203-lexico.t           |  147 +++
> test/lua-Harness-tests/204-grammar.t          |  233 ++++
> test/lua-Harness-tests/211-scope.t            |   86 ++
> test/lua-Harness-tests/212-function.t         |  288 +++++
> test/lua-Harness-tests/213-closure.t          |   98 ++
> test/lua-Harness-tests/214-coroutine.t        |  244 ++++
> test/lua-Harness-tests/221-table.t            |  120 ++
> test/lua-Harness-tests/222-constructor.t      |  119 ++
> test/lua-Harness-tests/223-iterator.t         |  203 +++
> test/lua-Harness-tests/231-metatable.t        |  602 +++++++++
> test/lua-Harness-tests/232-object.t           |  314 +++++
> .../241-standalone.t.disabled                 |  269 ++++
> test/lua-Harness-tests/242-luac.t             |  341 +++++
> test/lua-Harness-tests/301-basic.t            |  859 ++++++++++++
> test/lua-Harness-tests/303-package.t          |  290 +++++
> test/lua-Harness-tests/304-string.t           |  633 +++++++++
> test/lua-Harness-tests/305-utf8.t.disabled    |   55 +
> test/lua-Harness-tests/306-table.t            |  372 ++++++
> test/lua-Harness-tests/307-math.t             |  375 ++++++
> test/lua-Harness-tests/308-io.t               |  397 ++++++
> test/lua-Harness-tests/309-os.t               |  275 ++++
> test/lua-Harness-tests/310-debug.t            |  322 +++++
> test/lua-Harness-tests/311-bit32.t            |  127 ++
> test/lua-Harness-tests/314-regex.t            |  222 ++++
> test/lua-Harness-tests/320-stdin.t            |  133 ++
> test/lua-Harness-tests/401-bitop.t            |  106 ++
> test/lua-Harness-tests/402-ffi.t              |  142 ++
> test/lua-Harness-tests/403-jit.t              |  163 +++
> test/lua-Harness-tests/404-ext.t              |  171 +++
> test/lua-Harness-tests/411-luajit.t.disabled  |  211 +++
> test/lua-Harness-tests/CMakeLists.txt         |   62 +
> test/lua-Harness-tests/lexico52/lexico.t      |   45 +
> test/lua-Harness-tests/lexico53/boolean.t     |   43 +
> test/lua-Harness-tests/lexico53/function.t    |   66 +
> test/lua-Harness-tests/lexico53/lexico.t      |   30 +
> test/lua-Harness-tests/lexico53/nil.t         |   43 +
> test/lua-Harness-tests/lexico53/number.t      |  181 +++
> test/lua-Harness-tests/lexico53/string.t      |  169 +++
> test/lua-Harness-tests/lexico53/table.t       |   43 +
> test/lua-Harness-tests/lexico53/thread.t      |   45 +
> test/lua-Harness-tests/lexico53/userdata.t    |   45 +
> test/lua-Harness-tests/lexico53/utf8.t        |  179 +++
> test/lua-Harness-tests/lexico54/lexico.t      |   19 +
> test/lua-Harness-tests/lexico54/metatable.t   |   38 +
> test/lua-Harness-tests/lexico54/utf8.t        |   54 +
> test/lua-Harness-tests/lexicojit/basic.t      |   27 +
> test/lua-Harness-tests/lexicojit/ext.t        |   52 +
> test/lua-Harness-tests/lexicojit/lexico.t     |   32 +
> test/lua-Harness-tests/profile.lua            |   53 +
> test/lua-Harness-tests/profile_lua51.lua      |   46 +
> .../profile_lua51_strict.lua                  |   46 +
> test/lua-Harness-tests/profile_lua52.lua      |   46 +
> .../profile_lua52_strict.lua                  |   46 +
> test/lua-Harness-tests/profile_lua53.lua      |   52 +
> .../profile_lua53_noconv.lua                  |   55 +
> .../profile_lua53_strict.lua                  |   52 +
> test/lua-Harness-tests/profile_lua54.lua      |   52 +
> .../profile_lua54_noconv.lua                  |   55 +
> .../profile_lua54_strict.lua                  |   53 +
> test/lua-Harness-tests/profile_luajit20.lua   |   53 +
> .../profile_luajit20_compat52.lua             |   53 +
> test/lua-Harness-tests/profile_luajit21.lua   |   53 +
> .../profile_luajit21_compat52.lua             |   53 +
> test/lua-Harness-tests/profile_openresty.lua  |   53 +
> test/lua-Harness-tests/profile_ravi.lua       |   58 +
> test/lua-Harness-tests/profile_tiny_fork.lua  |   60 +
> test/lua-Harness-tests/rx_captures            |   13 +
> test/lua-Harness-tests/rx_charclass           |   38 +
> test/lua-Harness-tests/rx_metachars           |  117 ++
> test/lua-Harness-tests/tap_harness.lua        |  204 +++
> 322 files changed, 34168 insertions(+), 2 deletions(-)
> create mode 100644 test/LuaJIT-tests/CMakeLists.txt
> create mode 100644 test/LuaJIT-tests/README.md
> create mode 100644 test/LuaJIT-tests/bc/constov.lua
> create mode 100644 test/LuaJIT-tests/bc/index
> create mode 100644 test/LuaJIT-tests/common/expect_error.lua
> create mode 100644 test/LuaJIT-tests/common/ffi_util.inc
> create mode 100644 test/LuaJIT-tests/common/test_runner_canary.lua
> create mode 100644 test/LuaJIT-tests/computations.lua
> create mode 100644 test/LuaJIT-tests/index
> create mode 100644 test/LuaJIT-tests/lang/andor.lua
> create mode 100644 test/LuaJIT-tests/lang/assignment.lua
> create mode 100644 test/LuaJIT-tests/lang/compare.lua
> create mode 100644 test/LuaJIT-tests/lang/compare_nan.lua
> create mode 100644 test/LuaJIT-tests/lang/concat.lua
> create mode 100644 test/LuaJIT-tests/lang/constant/index
> create mode 100644 test/LuaJIT-tests/lang/constant/number.lua
> create mode 100644 test/LuaJIT-tests/lang/constant/table.lua
> create mode 100644 test/LuaJIT-tests/lang/coroutine.lua
> create mode 100644 test/LuaJIT-tests/lang/for.lua
> create mode 100644 test/LuaJIT-tests/lang/gc.lua
> create mode 100644 test/LuaJIT-tests/lang/goto.lua
> create mode 100644 test/LuaJIT-tests/lang/index
> create mode 100644 test/LuaJIT-tests/lang/length.lua
> create mode 100644 test/LuaJIT-tests/lang/meta/arith.lua
> create mode 100644 test/LuaJIT-tests/lang/meta/arith_jit.lua
> create mode 100644 test/LuaJIT-tests/lang/meta/call.lua
> create mode 100644 test/LuaJIT-tests/lang/meta/cat.lua
> create mode 100644 test/LuaJIT-tests/lang/meta/comp.lua
> create mode 100644 test/LuaJIT-tests/lang/meta/comp_jit.lua
> create mode 100644 test/LuaJIT-tests/lang/meta/debuginfo.lua
> create mode 100644 test/LuaJIT-tests/lang/meta/eq.lua
> create mode 100644 test/LuaJIT-tests/lang/meta/eq_jit.lua
> create mode 100644 test/LuaJIT-tests/lang/meta/framegap.lua
> create mode 100644 test/LuaJIT-tests/lang/meta/index
> create mode 100644 test/LuaJIT-tests/lang/meta/index.lua
> create mode 100644 test/LuaJIT-tests/lang/meta/len.lua
> create mode 100644 test/LuaJIT-tests/lang/meta/newindex.lua
> create mode 100644 test/LuaJIT-tests/lang/meta/nomm.lua
> create mode 100644 test/LuaJIT-tests/lang/modulo.lua
> create mode 100644 test/LuaJIT-tests/lang/self.lua
> create mode 100644 test/LuaJIT-tests/lang/table.lua
> create mode 100644 test/LuaJIT-tests/lang/tail_recursion.lua
> create mode 100644 test/LuaJIT-tests/lang/upvalue/closure.lua
> create mode 100644 test/LuaJIT-tests/lang/upvalue/index
> create mode 100644 test/LuaJIT-tests/lang/vararg_jit.lua
> create mode 100644 test/LuaJIT-tests/lib/base/assert.lua
> create mode 100644 test/LuaJIT-tests/lib/base/error.lua
> create mode 100644 test/LuaJIT-tests/lib/base/getfenv.lua
> create mode 100644 test/LuaJIT-tests/lib/base/getsetmetatable.lua
> create mode 100644 test/LuaJIT-tests/lib/base/index
> create mode 100644 test/LuaJIT-tests/lib/base/ipairs.lua
> create mode 100644 test/LuaJIT-tests/lib/base/next.lua
> create mode 100644 test/LuaJIT-tests/lib/base/pairs.lua
> create mode 100644 test/LuaJIT-tests/lib/base/pcall_jit.lua
> create mode 100644 test/LuaJIT-tests/lib/base/select.lua
> create mode 100644 test/LuaJIT-tests/lib/base/tonumber_tostring.lua
> create mode 100644 test/LuaJIT-tests/lib/base/xpcall_jit.lua
> create mode 100644 test/LuaJIT-tests/lib/bit.lua
> create mode 100644 test/LuaJIT-tests/lib/contents.lua
> create mode 100644 test/LuaJIT-tests/lib/coroutine/index
> create mode 100644 test/LuaJIT-tests/lib/coroutine/yield.lua
> create mode 100644 test/LuaJIT-tests/lib/ffi/bit64.lua
> create mode 100644 test/LuaJIT-tests/lib/ffi/cdata_var.lua
> create mode 100644 test/LuaJIT-tests/lib/ffi/copy_fill.lua
> create mode 100644 test/LuaJIT-tests/lib/ffi/err.lua
> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_arith_ptr.lua
> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_bitfield.lua
> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_call.lua
> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_callback.lua
> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_const.lua
> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_convert.lua
> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_enum.lua
> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_gcstep_recursive.lua
> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_jit_arith.lua
> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_jit_call.lua
> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_jit_conv.lua
> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_lex_number.lua
> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_metatype.lua
> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_new.lua
> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_parse_array.lua
> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_parse_basic.lua
> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_parse_cdef.lua
> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_parse_struct.lua
> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_tabov.lua
> create mode 100644 test/LuaJIT-tests/lib/ffi/index
> create mode 100644 test/LuaJIT-tests/lib/ffi/istype.lua
> create mode 100644 test/LuaJIT-tests/lib/ffi/jit_array.lua
> create mode 100644 test/LuaJIT-tests/lib/ffi/jit_complex.lua
> create mode 100644 test/LuaJIT-tests/lib/ffi/jit_misc.lua
> create mode 100644 test/LuaJIT-tests/lib/ffi/jit_struct.lua
> create mode 100644 test/LuaJIT-tests/lib/ffi/meta_tostring.lua
> create mode 100644 test/LuaJIT-tests/lib/ffi/redir.lua
> create mode 100644 test/LuaJIT-tests/lib/ffi/type_punning.lua
> create mode 100644 test/LuaJIT-tests/lib/index
> create mode 100644 test/LuaJIT-tests/lib/math/abs.lua
> create mode 100644 test/LuaJIT-tests/lib/math/constants.lua
> create mode 100644 test/LuaJIT-tests/lib/math/index
> create mode 100644 test/LuaJIT-tests/lib/math/random.lua
> create mode 100644 test/LuaJIT-tests/lib/string/byte.lua
> create mode 100644 test/LuaJIT-tests/lib/string/char.lua
> create mode 100644 test/LuaJIT-tests/lib/string/dump.lua
> create mode 100644 test/LuaJIT-tests/lib/string/format/index
> create mode 100644 test/LuaJIT-tests/lib/string/format/num.lua
> create mode 100644 test/LuaJIT-tests/lib/string/index
> create mode 100644 test/LuaJIT-tests/lib/string/len.lua
> create mode 100644 test/LuaJIT-tests/lib/string/lower_upper.lua
> create mode 100644 test/LuaJIT-tests/lib/string/metatable.lua
> create mode 100644 test/LuaJIT-tests/lib/string/multiple_functions.lua
> create mode 100644 test/LuaJIT-tests/lib/string/rep.lua
> create mode 100644 test/LuaJIT-tests/lib/string/reverse.lua
> create mode 100644 test/LuaJIT-tests/lib/string/sub.lua
> create mode 100644 test/LuaJIT-tests/lib/table/concat.lua
> create mode 100644 test/LuaJIT-tests/lib/table/index
> create mode 100644 test/LuaJIT-tests/lib/table/insert.lua
> create mode 100644 test/LuaJIT-tests/lib/table/misc.lua
> create mode 100644 test/LuaJIT-tests/lib/table/new.lua
> create mode 100644 test/LuaJIT-tests/lib/table/pack.lua
> create mode 100644 test/LuaJIT-tests/lib/table/remove.lua
> create mode 100644 test/LuaJIT-tests/lib/table/sort.lua
> create mode 100644 test/LuaJIT-tests/misc/alias_alloc.lua
> create mode 100644 test/LuaJIT-tests/misc/api_call.lua
> create mode 100644 test/LuaJIT-tests/misc/catch_wrap.lua
> create mode 100644 test/LuaJIT-tests/misc/coro_traceback.lua
> create mode 100644 test/LuaJIT-tests/misc/coro_yield.lua
> create mode 100644 test/LuaJIT-tests/misc/debug_gc.lua
> create mode 100644 test/LuaJIT-tests/misc/dualnum.lua
> create mode 100644 test/LuaJIT-tests/misc/for_dir.lua
> create mode 100644 test/LuaJIT-tests/misc/fori_coerce.lua
> create mode 100644 test/LuaJIT-tests/misc/gc_rechain.lua
> create mode 100644 test/LuaJIT-tests/misc/gc_trace.lua
> create mode 100644 test/LuaJIT-tests/misc/gcstep.lua
> create mode 100644 test/LuaJIT-tests/misc/hook_active.lua
> create mode 100644 test/LuaJIT-tests/misc/hook_line.lua
> create mode 100644 test/LuaJIT-tests/misc/hook_norecord.lua
> create mode 100644 test/LuaJIT-tests/misc/hook_record.lua
> create mode 100644 test/LuaJIT-tests/misc/hook_top.lua
> create mode 100644 test/LuaJIT-tests/misc/jit_flush.lua
> create mode 100644 test/LuaJIT-tests/misc/lightud.lua
> create mode 100644 test/LuaJIT-tests/misc/loop_unroll.lua
> create mode 100644 test/LuaJIT-tests/misc/parse_comp.lua
> create mode 100644 test/LuaJIT-tests/misc/parse_esc.lua
> create mode 100644 test/LuaJIT-tests/misc/parse_misc.lua
> create mode 100644 test/LuaJIT-tests/misc/phi_conv.lua
> create mode 100644 test/LuaJIT-tests/misc/recurse_deep.lua
> create mode 100644 test/LuaJIT-tests/misc/recurse_tail.lua
> create mode 100644 test/LuaJIT-tests/misc/stack_gc.lua
> create mode 100644 test/LuaJIT-tests/misc/stack_purge.lua
> create mode 100644 test/LuaJIT-tests/misc/stackov.lua
> create mode 100644 test/LuaJIT-tests/misc/stackovc.lua
> create mode 100644 test/LuaJIT-tests/misc/tcall_base.lua
> create mode 100644 test/LuaJIT-tests/misc/tcall_loop.lua
> create mode 100644 test/LuaJIT-tests/misc/tonumber_scan.lua
> create mode 100644 test/LuaJIT-tests/misc/uclo.lua
> create mode 100644 test/LuaJIT-tests/misc/unordered_jit.lua
> create mode 100644 test/LuaJIT-tests/misc/wbarrier.lua
> create mode 100644 test/LuaJIT-tests/misc/wbarrier_jit.lua
> create mode 100644 test/LuaJIT-tests/misc/wbarrier_obar.lua
> create mode 100644 test/LuaJIT-tests/opt/dse/array.lua
> create mode 100644 test/LuaJIT-tests/opt/dse/field.lua
> create mode 100644 test/LuaJIT-tests/opt/dse/index
> create mode 100644 test/LuaJIT-tests/opt/fold/index
> create mode 100644 test/LuaJIT-tests/opt/fold/kfold.lua
> create mode 100644 test/LuaJIT-tests/opt/fuse.lua
> create mode 100644 test/LuaJIT-tests/opt/fwd/hrefk_rollback.lua
> create mode 100644 test/LuaJIT-tests/opt/fwd/index
> create mode 100644 test/LuaJIT-tests/opt/fwd/tnew_tdup.lua
> create mode 100644 test/LuaJIT-tests/opt/fwd/upval.lua
> create mode 100644 test/LuaJIT-tests/opt/index
> create mode 100644 test/LuaJIT-tests/opt/loop/index
> create mode 100644 test/LuaJIT-tests/opt/loop/unroll.lua
> create mode 100644 test/LuaJIT-tests/opt/sink/alloc.lua
> create mode 100644 test/LuaJIT-tests/opt/sink/ffi.lua
> create mode 100644 test/LuaJIT-tests/opt/sink/ffi_nosink.lua
> create mode 100644 test/LuaJIT-tests/opt/sink/index
> create mode 100644 test/LuaJIT-tests/opt/sink/nosink.lua
> create mode 100644 test/LuaJIT-tests/src/cpptest.cpp
> create mode 100644 test/LuaJIT-tests/src/ctest.c
> create mode 100644 test/LuaJIT-tests/sysdep/catch_cpp.lua
> create mode 100644 test/LuaJIT-tests/sysdep/ffi_include_gtk.lua
> create mode 100644 test/LuaJIT-tests/sysdep/ffi_include_std.lua
> create mode 100644 test/LuaJIT-tests/sysdep/ffi_lib_c.lua
> create mode 100644 test/LuaJIT-tests/sysdep/ffi_lib_z.lua
> create mode 100644 test/LuaJIT-tests/test.lua
> create mode 100644 test/LuaJIT-tests/trace/exit_frame.lua
> create mode 100644 test/LuaJIT-tests/trace/exit_growstack.lua
> create mode 100644 test/LuaJIT-tests/trace/exit_jfuncf.lua
> create mode 100644 test/LuaJIT-tests/trace/gc64_slot_revival.lua
> create mode 100644 test/LuaJIT-tests/trace/index
> create mode 100644 test/LuaJIT-tests/trace/phi/copyspill.lua
> create mode 100644 test/LuaJIT-tests/trace/phi/index
> create mode 100644 test/LuaJIT-tests/trace/phi/ref.lua
> create mode 100644 test/LuaJIT-tests/trace/phi/rotate.lua
> create mode 100644 test/LuaJIT-tests/trace/snap.lua
> create mode 100644 test/LuaJIT-tests/trace/stitch.lua
> create mode 100644 test/LuaJIT-tests/unportable/ffi_arith_int64.lua
> create mode 100644 test/LuaJIT-tests/unportable/math_special.lua
> 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/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
> create mode 100755 test/lua-Harness-tests/000-sanity.t
> create mode 100755 test/lua-Harness-tests/001-if.t
> create mode 100755 test/lua-Harness-tests/002-table.t
> create mode 100755 test/lua-Harness-tests/011-while.t
> create mode 100755 test/lua-Harness-tests/012-repeat.t
> create mode 100755 test/lua-Harness-tests/014-fornum.t
> create mode 100755 test/lua-Harness-tests/015-forlist.t
> create mode 100755 test/lua-Harness-tests/090-tap.t
> create mode 100755 test/lua-Harness-tests/091-profile.t
> create mode 100755 test/lua-Harness-tests/101-boolean.t
> create mode 100755 test/lua-Harness-tests/102-function.t
> create mode 100755 test/lua-Harness-tests/103-nil.t
> create mode 100755 test/lua-Harness-tests/104-number.t
> create mode 100755 test/lua-Harness-tests/105-string.t
> create mode 100755 test/lua-Harness-tests/106-table.t
> create mode 100755 test/lua-Harness-tests/107-thread.t
> create mode 100755 test/lua-Harness-tests/108-userdata.t
> create mode 100755 test/lua-Harness-tests/200-examples.t
> create mode 100755 test/lua-Harness-tests/201-assign.t
> create mode 100755 test/lua-Harness-tests/202-expr.t
> create mode 100755 test/lua-Harness-tests/203-lexico.t
> create mode 100755 test/lua-Harness-tests/204-grammar.t
> create mode 100755 test/lua-Harness-tests/211-scope.t
> create mode 100755 test/lua-Harness-tests/212-function.t
> create mode 100755 test/lua-Harness-tests/213-closure.t
> create mode 100755 test/lua-Harness-tests/214-coroutine.t
> create mode 100755 test/lua-Harness-tests/221-table.t
> create mode 100755 test/lua-Harness-tests/222-constructor.t
> create mode 100755 test/lua-Harness-tests/223-iterator.t
> create mode 100755 test/lua-Harness-tests/231-metatable.t
> create mode 100755 test/lua-Harness-tests/232-object.t
> create mode 100755 test/lua-Harness-tests/241-standalone.t.disabled
> create mode 100755 test/lua-Harness-tests/242-luac.t
> create mode 100755 test/lua-Harness-tests/301-basic.t
> create mode 100755 test/lua-Harness-tests/303-package.t
> create mode 100755 test/lua-Harness-tests/304-string.t
> create mode 100755 test/lua-Harness-tests/305-utf8.t.disabled
> create mode 100755 test/lua-Harness-tests/306-table.t
> create mode 100755 test/lua-Harness-tests/307-math.t
> create mode 100755 test/lua-Harness-tests/308-io.t
> create mode 100755 test/lua-Harness-tests/309-os.t
> create mode 100755 test/lua-Harness-tests/310-debug.t
> create mode 100755 test/lua-Harness-tests/311-bit32.t
> create mode 100755 test/lua-Harness-tests/314-regex.t
> create mode 100755 test/lua-Harness-tests/320-stdin.t
> create mode 100755 test/lua-Harness-tests/401-bitop.t
> create mode 100755 test/lua-Harness-tests/402-ffi.t
> create mode 100755 test/lua-Harness-tests/403-jit.t
> create mode 100755 test/lua-Harness-tests/404-ext.t
> create mode 100755 test/lua-Harness-tests/411-luajit.t.disabled
> create mode 100644 test/lua-Harness-tests/CMakeLists.txt
> create mode 100644 test/lua-Harness-tests/lexico52/lexico.t
> create mode 100644 test/lua-Harness-tests/lexico53/boolean.t
> create mode 100644 test/lua-Harness-tests/lexico53/function.t
> create mode 100644 test/lua-Harness-tests/lexico53/lexico.t
> create mode 100644 test/lua-Harness-tests/lexico53/nil.t
> create mode 100644 test/lua-Harness-tests/lexico53/number.t
> create mode 100644 test/lua-Harness-tests/lexico53/string.t
> create mode 100644 test/lua-Harness-tests/lexico53/table.t
> create mode 100644 test/lua-Harness-tests/lexico53/thread.t
> create mode 100644 test/lua-Harness-tests/lexico53/userdata.t
> create mode 100644 test/lua-Harness-tests/lexico53/utf8.t
> create mode 100644 test/lua-Harness-tests/lexico54/lexico.t
> create mode 100644 test/lua-Harness-tests/lexico54/metatable.t
> create mode 100644 test/lua-Harness-tests/lexico54/utf8.t
> create mode 100644 test/lua-Harness-tests/lexicojit/basic.t
> create mode 100644 test/lua-Harness-tests/lexicojit/ext.t
> create mode 100644 test/lua-Harness-tests/lexicojit/lexico.t
> create mode 100644 test/lua-Harness-tests/profile.lua
> create mode 100644 test/lua-Harness-tests/profile_lua51.lua
> create mode 100644 test/lua-Harness-tests/profile_lua51_strict.lua
> create mode 100644 test/lua-Harness-tests/profile_lua52.lua
> create mode 100644 test/lua-Harness-tests/profile_lua52_strict.lua
> create mode 100644 test/lua-Harness-tests/profile_lua53.lua
> create mode 100644 test/lua-Harness-tests/profile_lua53_noconv.lua
> create mode 100644 test/lua-Harness-tests/profile_lua53_strict.lua
> create mode 100644 test/lua-Harness-tests/profile_lua54.lua
> create mode 100644 test/lua-Harness-tests/profile_lua54_noconv.lua
> create mode 100644 test/lua-Harness-tests/profile_lua54_strict.lua
> create mode 100644 test/lua-Harness-tests/profile_luajit20.lua
> create mode 100644 test/lua-Harness-tests/profile_luajit20_compat52.lua
> create mode 100644 test/lua-Harness-tests/profile_luajit21.lua
> create mode 100644 test/lua-Harness-tests/profile_luajit21_compat52.lua
> create mode 100644 test/lua-Harness-tests/profile_openresty.lua
> create mode 100644 test/lua-Harness-tests/profile_ravi.lua
> create mode 100644 test/lua-Harness-tests/profile_tiny_fork.lua
> create mode 100644 test/lua-Harness-tests/rx_captures
> create mode 100644 test/lua-Harness-tests/rx_charclass
> create mode 100644 test/lua-Harness-tests/rx_metachars
> create mode 100644 test/lua-Harness-tests/tap_harness.lua
> 
> -- 
> 2.28.0
> 
> [0]: https://github.com/tarantool/tarantool/runs/2029452344
> [1]: https://github.com/google/sanitizers/issues/980
> [2]: https://github.com/google/sanitizers/issues/189
> [3]: https://github.com/google/sanitizers/wiki/AddressSanitizerFlags


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

* Re: [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites
  2021-03-04 16:24 ` [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites Sergey Ostanevich via Tarantool-patches
@ 2021-03-04 19:58   ` Sergey Kaplun via Tarantool-patches
  2021-03-05 10:48     ` Sergey Ostanevich via Tarantool-patches
  0 siblings, 1 reply; 26+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-04 19:58 UTC (permalink / raw)
  To: Sergey Ostanevich; +Cc: tarantool-patches

On 04.03.21, Sergey Ostanevich wrote:
> Hi!
> 
> Thanks for the patchset - brief review
> 
> part 1 - obvious, LGTM.
> 
> part 2 - LGTM, good to have all follow-ups set.

Do you mean to reference all follow-ups inside commit message?

> 
> part 3 - should have a follow-up ticket to cover all suppressions, if we plan to fix them.

Ditto.
There are some follow ups that can be grepped by qa and luajit labels.

> 
> part 4-8 are LGTM
> 
> part 9 (_G and some modules in Tarantool are different): Are we plan to fix it in some way? There should be a follow-up then.

For now I can't see any good solution, except ignoring them by special
option like slow tests.

> 
> parts 10-15 are LGTM
> 
> Regards,
> Sergos
> 
> > On 4 Mar 2021, at 13:23, Sergey Kaplun <skaplun@tarantool.org> wrote:
> > 
> > WARNING: This patch doesn't require full and precise review now.
> > 
> > This draft should be structured (commits at least) from test
> > suite to test suite if necessary.
> > 
> > You can complain test suites with the following command, for example:
> > | $ diff --color -urZ test/PUC-Lua-5.1-tests/ ~/Downloads/lua5.1-tests/
> > 
> > Branch: https://github.com/tarantool/luajit/tree/skaplun/gh-4473-adopt-luavela-test-suites
> > Tarantool's branch: https://github.com/tarantool/tarantool/tree/skaplun/gh-4473-adopt-luavela-test-suites
> > Epic: https://github.com/tarantool/tarantool/issues/4473
> > Issues:
> > * https://github.com/tarantool/tarantool/issues/5845
> > * https://github.com/tarantool/tarantool/issues/4064
> > * https://github.com/tarantool/tarantool/issues/5844
> > 
> > CI is red due to ASan failure [0] for PUC-Lua-5.1 test suite.
> > Looks related to https://github.com/tarantool/tarantool/issues/5747,
> > but it is hard to tell without backtrace.
> > 
> > Locally, I get tons of errors like this for each of newly added test
> > suites:
> > | ==31930==WARNING: ASan is ignoring requested __asan_handle_no_return: stack top: 0x7fffbb603000; bottom 0x7f4e271fd000; size: 0x00b194406000 (762696458240)
> > | False positive error reports may follow
> > | For details see https://github.com/google/sanitizers/issues/189
> > 
> > After that there are failures like:
> > 
> > | ==24658==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7f6b741fefa8 at pc 0x000000c91926 bp 0x7f6b741fec90 sp 0x7f6b741fec88
> > | READ of size 8 at 0x7f6b741fefa8 thread T0
> > |     #0 0xc91925 in lj_strfmt_pushvf /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_strfmt.c:438:23
> > |     #1 0xc6f8fe in lj_err_lex /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_err.c:651:9
> > |     #2 0xce0fa1 in lj_lex_error /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_lex.c:495:3
> > |     #3 0xce3285 in err_token /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_parse.c:175:3
> > |     #4 0xcf27bc in parse_stmt /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_parse.c
> > |     #5 0xce3ceb in parse_chunk /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_parse.c:2684:14
> > |     #6 0xce3ceb in lj_parse /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_parse.c:2717:3
> > |     #7 0xc7eeaa in cpparser /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_load.c:41:29
> > |     #8 0xd8a6b7 in lj_vm_cpcall /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/build/third_party/luajit/src/lj_vm.S:1191
> > |     #9 0xc7fed6 in lua_loadx /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_load.c:58:12
> > |     #10 0xc7fed6 in luaL_loadbufferx /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_load.c:143:10
> > |     #11 0xca9b12 in lj_cf_load /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lib_base.c:401:14
> > |     #12 0xd8a2fa in lj_BC_FUNCC /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/build/third_party/luajit/src/lj_vm.S:811
> > |     #13 0xc5be1f in lua_pcall /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_api.c:1158:12
> > |     #14 0xb2ad71 in luaT_call /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/src/lua/utils.c:1022:6
> > |     #15 0xb1532c in lua_main /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/src/lua/init.c:559:11
> > |     #16 0xb14c9a in run_script_f /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/src/lua/init.c:634:7
> > |     #17 0x526d96 in fiber_cxx_invoke(int (*)(__va_list_tag*), __va_list_tag*) /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/src/lib/core/fiber.h:882:10
> > |     #18 0xb7f688 in fiber_loop /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/src/lib/core/fiber.c:879:18
> > |     #19 0x14b3b10 in coro_init /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/coro/coro.c:110:3
> > |
> > | Address 0x7f6b741fefa8 is a wild pointer.
> > | SUMMARY: AddressSanitizer: stack-buffer-overflow /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_strfmt.c:438:23 in lj_strfmt_pushvf
> > | Shadow bytes around the buggy address:
> > |   0x0fedee837da0: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
> > |   0x0fedee837db0: 00 00 00 f3 f3 f3 f3 f3 00 00 00 00 00 00 00 00
> > |   0x0fedee837dc0: f1 f1 f1 f1 00 00 00 00 00 00 00 04 f3 f3 f3 f3
> > |   0x0fedee837dd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> > |   0x0fedee837de0: f1 f1 f1 f1 00 00 00 f3 f3 f3 f3 f3 f2 f2 f2 f2
> > | =>0x0fedee837df0: f8 f8 f8 f8 f3[f3]f3 f3 00 00 00 00 00 00 00 00
> > |   0x0fedee837e00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> > |   0x0fedee837e10: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 f8 f8 f8 f2
> > |   0x0fedee837e20: f2 f2 f2 f2 f8 f8 f8 f2 f2 f2 f2 f2 f8 f8 f8 f8
> > |   0x0fedee837e30: f2 f2 f2 f2 f8 f8 f8 f2 f2 f2 f2 f2 f8 f8 f8 f2
> > |   0x0fedee837e40: f2 f2 f2 f2 f8 f8 f8 f2 f2 f2 f2 f2 f8 f8 f8 f2
> > | Shadow byte legend (one shadow byte represents 8 application bytes):
> > |   Addressable:           00
> > |   Partially addressable: 01 02 03 04 05 06 07 
> > |   Heap left redzone:       fa
> > |   Freed heap region:       fd
> > |   Stack left redzone:      f1
> > |   Stack mid redzone:       f2
> > |   Stack right redzone:     f3
> > |   Stack after return:      f5
> > |   Stack use after scope:   f8
> > 
> > It can be simply reproduce locally with:
> > | $ ASAN=ON LSAN_OPTIONS=suppressions=asan/lsan.supp ASAN_OPTIONS=heap_profile=0:unmap_shadow_on_exit=1:detect_invalid_pointer_pairs=1:symbolize=1:detect_leaks=1:dump_instruction_bytes=1:print_suppressions=0:asan_stack=0 src/tarantool -e 'prog = [[ do]] for _=1,3 do pcall(loadstring(string.sub(prog, 1, _))) end'
> > 
> > It may be the reason of failures too, see [1][2].
> > 
> > According to [3], there is no any way except to compile with -asan-stack
> > flag, but it looks like overkill. So I propose to exclude PUC-Lua-5.1
> > test suite from ASan job for now (at least this is out of scoupe of the
> > original issue).
> > 
> > Mergen Imeev (8):
> >  test: add LuaJIT-test-cleanup test suite
> >  test: change tests to match de5568e
> >  test: change tests to match c198167
> >  test: change tests to match 5a61e1a
> >  test: change LuaJIT suite tests to match b4e6bf0
> >  test: adjust LuaJIT test suite for Tarantool
> >  test: add lua-Harness test suite
> >  test: adjust lua-Harness test suite for Tarantool
> > 
> > Sergey Kaplun (7):
> >  test: add PUC-Rio Lua 5.1 test suite
> >  test: adapt PUC-Rio Lua 5.1 test suite for LuaJIT
> >  test: adapt Lua 5.1 test suite for Tarantool
> >  test: disable 305-utf8 of lua-Harness suite
> >  test: disable 241-standalone of lua-Harness suite
> >  test: disable 411-luajit of lua-Harness suite
> >  test: skip test for getenv in 309-os.t
> > 
> > .gitignore                                    |    1 +
> > .luacheckrc                                   |    7 +-
> > CMakeLists.txt                                |    8 +
> > test/CMakeLists.txt                           |    6 +
> > test/LuaJIT-tests/CMakeLists.txt              |   20 +
> > test/LuaJIT-tests/README.md                   |  110 ++
> > test/LuaJIT-tests/bc/constov.lua              |   16 +
> > test/LuaJIT-tests/bc/index                    |    1 +
> > test/LuaJIT-tests/common/expect_error.lua     |   16 +
> > test/LuaJIT-tests/common/ffi_util.inc         |   41 +
> > .../common/test_runner_canary.lua             |    1 +
> > test/LuaJIT-tests/computations.lua            |  113 ++
> > test/LuaJIT-tests/index                       |    6 +
> > test/LuaJIT-tests/lang/andor.lua              |   61 +
> > test/LuaJIT-tests/lang/assignment.lua         |   46 +
> > test/LuaJIT-tests/lang/compare.lua            |  323 +++++
> > test/LuaJIT-tests/lang/compare_nan.lua        |   99 ++
> > test/LuaJIT-tests/lang/concat.lua             |  112 ++
> > test/LuaJIT-tests/lang/constant/index         |    2 +
> > test/LuaJIT-tests/lang/constant/number.lua    |   12 +
> > test/LuaJIT-tests/lang/constant/table.lua     |   15 +
> > test/LuaJIT-tests/lang/coroutine.lua          |    8 +
> > test/LuaJIT-tests/lang/for.lua                |   45 +
> > test/LuaJIT-tests/lang/gc.lua                 |   42 +
> > test/LuaJIT-tests/lang/goto.lua               |  149 +++
> > test/LuaJIT-tests/lang/index                  |   18 +
> > test/LuaJIT-tests/lang/length.lua             |   23 +
> > test/LuaJIT-tests/lang/meta/arith.lua         |  118 ++
> > test/LuaJIT-tests/lang/meta/arith_jit.lua     |   68 +
> > test/LuaJIT-tests/lang/meta/call.lua          |   81 ++
> > test/LuaJIT-tests/lang/meta/cat.lua           |   61 +
> > test/LuaJIT-tests/lang/meta/comp.lua          |  120 ++
> > test/LuaJIT-tests/lang/meta/comp_jit.lua      |  104 ++
> > test/LuaJIT-tests/lang/meta/debuginfo.lua     |   81 ++
> > test/LuaJIT-tests/lang/meta/eq.lua            |   30 +
> > test/LuaJIT-tests/lang/meta/eq_jit.lua        |   35 +
> > test/LuaJIT-tests/lang/meta/framegap.lua      |   24 +
> > test/LuaJIT-tests/lang/meta/index             |   14 +
> > test/LuaJIT-tests/lang/meta/index.lua         |   60 +
> > test/LuaJIT-tests/lang/meta/len.lua           |   42 +
> > test/LuaJIT-tests/lang/meta/newindex.lua      |   69 +
> > test/LuaJIT-tests/lang/meta/nomm.lua          |   21 +
> > test/LuaJIT-tests/lang/modulo.lua             |   46 +
> > test/LuaJIT-tests/lang/self.lua               |   19 +
> > test/LuaJIT-tests/lang/table.lua              |   32 +
> > test/LuaJIT-tests/lang/tail_recursion.lua     |   20 +
> > test/LuaJIT-tests/lang/upvalue/closure.lua    |   84 ++
> > test/LuaJIT-tests/lang/upvalue/index          |    1 +
> > test/LuaJIT-tests/lang/vararg_jit.lua         |   95 ++
> > test/LuaJIT-tests/lib/base/assert.lua         |   33 +
> > test/LuaJIT-tests/lib/base/error.lua          |   43 +
> > test/LuaJIT-tests/lib/base/getfenv.lua        |   13 +
> > .../LuaJIT-tests/lib/base/getsetmetatable.lua |   33 +
> > test/LuaJIT-tests/lib/base/index              |   11 +
> > test/LuaJIT-tests/lib/base/ipairs.lua         |   41 +
> > test/LuaJIT-tests/lib/base/next.lua           |   17 +
> > test/LuaJIT-tests/lib/base/pairs.lua          |   73 ++
> > test/LuaJIT-tests/lib/base/pcall_jit.lua      |   74 ++
> > test/LuaJIT-tests/lib/base/select.lua         |  105 ++
> > .../lib/base/tonumber_tostring.lua            |   81 ++
> > test/LuaJIT-tests/lib/base/xpcall_jit.lua     |   83 ++
> > test/LuaJIT-tests/lib/bit.lua                 |   98 ++
> > test/LuaJIT-tests/lib/contents.lua            |  171 +++
> > test/LuaJIT-tests/lib/coroutine/index         |    1 +
> > test/LuaJIT-tests/lib/coroutine/yield.lua     |  109 ++
> > test/LuaJIT-tests/lib/ffi/bit64.lua           |  130 ++
> > test/LuaJIT-tests/lib/ffi/cdata_var.lua       |   47 +
> > test/LuaJIT-tests/lib/ffi/copy_fill.lua       |   64 +
> > test/LuaJIT-tests/lib/ffi/err.lua             |   35 +
> > test/LuaJIT-tests/lib/ffi/ffi_arith_ptr.lua   |  106 ++
> > test/LuaJIT-tests/lib/ffi/ffi_bitfield.lua    |  108 ++
> > test/LuaJIT-tests/lib/ffi/ffi_call.lua        |  266 ++++
> > test/LuaJIT-tests/lib/ffi/ffi_callback.lua    |  158 +++
> > test/LuaJIT-tests/lib/ffi/ffi_const.lua       |  113 ++
> > test/LuaJIT-tests/lib/ffi/ffi_convert.lua     |  787 +++++++++++
> > test/LuaJIT-tests/lib/ffi/ffi_enum.lua        |   57 +
> > .../lib/ffi/ffi_gcstep_recursive.lua          |   66 +
> > test/LuaJIT-tests/lib/ffi/ffi_jit_arith.lua   |  155 +++
> > test/LuaJIT-tests/lib/ffi/ffi_jit_call.lua    |  154 +++
> > test/LuaJIT-tests/lib/ffi/ffi_jit_conv.lua    |  277 ++++
> > test/LuaJIT-tests/lib/ffi/ffi_lex_number.lua  |   51 +
> > test/LuaJIT-tests/lib/ffi/ffi_metatype.lua    |  245 ++++
> > test/LuaJIT-tests/lib/ffi/ffi_new.lua         |  106 ++
> > test/LuaJIT-tests/lib/ffi/ffi_parse_array.lua |   78 ++
> > test/LuaJIT-tests/lib/ffi/ffi_parse_basic.lua |  131 ++
> > test/LuaJIT-tests/lib/ffi/ffi_parse_cdef.lua  |   77 ++
> > .../LuaJIT-tests/lib/ffi/ffi_parse_struct.lua |  259 ++++
> > test/LuaJIT-tests/lib/ffi/ffi_tabov.lua       |   12 +
> > test/LuaJIT-tests/lib/ffi/index               |   12 +
> > test/LuaJIT-tests/lib/ffi/istype.lua          |   88 ++
> > test/LuaJIT-tests/lib/ffi/jit_array.lua       |  104 ++
> > test/LuaJIT-tests/lib/ffi/jit_complex.lua     |  109 ++
> > test/LuaJIT-tests/lib/ffi/jit_misc.lua        |  109 ++
> > test/LuaJIT-tests/lib/ffi/jit_struct.lua      |  201 +++
> > test/LuaJIT-tests/lib/ffi/meta_tostring.lua   |   55 +
> > test/LuaJIT-tests/lib/ffi/redir.lua           |   19 +
> > test/LuaJIT-tests/lib/ffi/type_punning.lua    |  138 ++
> > test/LuaJIT-tests/lib/index                   |    8 +
> > test/LuaJIT-tests/lib/math/abs.lua            |   16 +
> > test/LuaJIT-tests/lib/math/constants.lua      |    8 +
> > test/LuaJIT-tests/lib/math/index              |    3 +
> > test/LuaJIT-tests/lib/math/random.lua         |   47 +
> > test/LuaJIT-tests/lib/string/byte.lua         |   92 ++
> > test/LuaJIT-tests/lib/string/char.lua         |   29 +
> > test/LuaJIT-tests/lib/string/dump.lua         |   31 +
> > test/LuaJIT-tests/lib/string/format/index     |    1 +
> > test/LuaJIT-tests/lib/string/format/num.lua   |  184 +++
> > test/LuaJIT-tests/lib/string/index            |   11 +
> > test/LuaJIT-tests/lib/string/len.lua          |   14 +
> > test/LuaJIT-tests/lib/string/lower_upper.lua  |   51 +
> > test/LuaJIT-tests/lib/string/metatable.lua    |    3 +
> > .../lib/string/multiple_functions.lua         |   16 +
> > test/LuaJIT-tests/lib/string/rep.lua          |   68 +
> > test/LuaJIT-tests/lib/string/reverse.lua      |   13 +
> > test/LuaJIT-tests/lib/string/sub.lua          |  189 +++
> > test/LuaJIT-tests/lib/table/concat.lua        |   55 +
> > test/LuaJIT-tests/lib/table/index             |    6 +
> > test/LuaJIT-tests/lib/table/insert.lua        |   17 +
> > test/LuaJIT-tests/lib/table/misc.lua          |   58 +
> > test/LuaJIT-tests/lib/table/new.lua           |   11 +
> > test/LuaJIT-tests/lib/table/pack.lua          |    7 +
> > test/LuaJIT-tests/lib/table/remove.lua        |   42 +
> > test/LuaJIT-tests/lib/table/sort.lua          |   27 +
> > test/LuaJIT-tests/misc/alias_alloc.lua        |   54 +
> > test/LuaJIT-tests/misc/api_call.lua           |   98 ++
> > test/LuaJIT-tests/misc/catch_wrap.lua         |   45 +
> > test/LuaJIT-tests/misc/coro_traceback.lua     |    8 +
> > test/LuaJIT-tests/misc/coro_yield.lua         |  111 ++
> > test/LuaJIT-tests/misc/debug_gc.lua           |   47 +
> > test/LuaJIT-tests/misc/dualnum.lua            |   47 +
> > test/LuaJIT-tests/misc/for_dir.lua            |   13 +
> > test/LuaJIT-tests/misc/fori_coerce.lua        |   33 +
> > test/LuaJIT-tests/misc/gc_rechain.lua         |   32 +
> > test/LuaJIT-tests/misc/gc_trace.lua           |   37 +
> > test/LuaJIT-tests/misc/gcstep.lua             |   33 +
> > test/LuaJIT-tests/misc/hook_active.lua        |   95 ++
> > test/LuaJIT-tests/misc/hook_line.lua          |   41 +
> > test/LuaJIT-tests/misc/hook_norecord.lua      |   12 +
> > test/LuaJIT-tests/misc/hook_record.lua        |    8 +
> > test/LuaJIT-tests/misc/hook_top.lua           |   55 +
> > test/LuaJIT-tests/misc/jit_flush.lua          |   50 +
> > test/LuaJIT-tests/misc/lightud.lua            |   88 ++
> > test/LuaJIT-tests/misc/loop_unroll.lua        |   35 +
> > test/LuaJIT-tests/misc/parse_comp.lua         |   13 +
> > test/LuaJIT-tests/misc/parse_esc.lua          |    7 +
> > test/LuaJIT-tests/misc/parse_misc.lua         |   31 +
> > test/LuaJIT-tests/misc/phi_conv.lua           |   53 +
> > test/LuaJIT-tests/misc/recurse_deep.lua       |   29 +
> > test/LuaJIT-tests/misc/recurse_tail.lua       |   22 +
> > test/LuaJIT-tests/misc/stack_gc.lua           |   15 +
> > test/LuaJIT-tests/misc/stack_purge.lua        |   25 +
> > test/LuaJIT-tests/misc/stackov.lua            |   40 +
> > test/LuaJIT-tests/misc/stackovc.lua           |    4 +
> > test/LuaJIT-tests/misc/tcall_base.lua         |   20 +
> > test/LuaJIT-tests/misc/tcall_loop.lua         |    8 +
> > test/LuaJIT-tests/misc/tonumber_scan.lua      |  180 +++
> > test/LuaJIT-tests/misc/uclo.lua               |   91 ++
> > test/LuaJIT-tests/misc/unordered_jit.lua      |   96 ++
> > test/LuaJIT-tests/misc/wbarrier.lua           |    7 +
> > test/LuaJIT-tests/misc/wbarrier_jit.lua       |   18 +
> > test/LuaJIT-tests/misc/wbarrier_obar.lua      |   22 +
> > test/LuaJIT-tests/opt/dse/array.lua           |  197 +++
> > test/LuaJIT-tests/opt/dse/field.lua           |   70 +
> > test/LuaJIT-tests/opt/dse/index               |    2 +
> > test/LuaJIT-tests/opt/fold/index              |    1 +
> > test/LuaJIT-tests/opt/fold/kfold.lua          |   81 ++
> > test/LuaJIT-tests/opt/fuse.lua                |    5 +
> > test/LuaJIT-tests/opt/fwd/hrefk_rollback.lua  |   32 +
> > test/LuaJIT-tests/opt/fwd/index               |    3 +
> > test/LuaJIT-tests/opt/fwd/tnew_tdup.lua       |   69 +
> > test/LuaJIT-tests/opt/fwd/upval.lua           |   50 +
> > test/LuaJIT-tests/opt/index                   |    6 +
> > test/LuaJIT-tests/opt/loop/index              |    1 +
> > test/LuaJIT-tests/opt/loop/unroll.lua         |   32 +
> > test/LuaJIT-tests/opt/sink/alloc.lua          |  126 ++
> > test/LuaJIT-tests/opt/sink/ffi.lua            |  121 ++
> > test/LuaJIT-tests/opt/sink/ffi_nosink.lua     |   45 +
> > test/LuaJIT-tests/opt/sink/index              |    4 +
> > test/LuaJIT-tests/opt/sink/nosink.lua         |  109 ++
> > test/LuaJIT-tests/src/cpptest.cpp             |  129 ++
> > test/LuaJIT-tests/src/ctest.c                 |  339 +++++
> > test/LuaJIT-tests/sysdep/catch_cpp.lua        |   71 +
> > test/LuaJIT-tests/sysdep/ffi_include_gtk.lua  |    9 +
> > test/LuaJIT-tests/sysdep/ffi_include_std.lua  |   36 +
> > test/LuaJIT-tests/sysdep/ffi_lib_c.lua        |   87 ++
> > test/LuaJIT-tests/sysdep/ffi_lib_z.lua        |  107 ++
> > test/LuaJIT-tests/test.lua                    |  416 ++++++
> > test/LuaJIT-tests/trace/exit_frame.lua        |   79 ++
> > test/LuaJIT-tests/trace/exit_growstack.lua    |   28 +
> > test/LuaJIT-tests/trace/exit_jfuncf.lua       |   30 +
> > test/LuaJIT-tests/trace/gc64_slot_revival.lua |   18 +
> > test/LuaJIT-tests/trace/index                 |    7 +
> > test/LuaJIT-tests/trace/phi/copyspill.lua     |   53 +
> > test/LuaJIT-tests/trace/phi/index             |    3 +
> > test/LuaJIT-tests/trace/phi/ref.lua           |  131 ++
> > test/LuaJIT-tests/trace/phi/rotate.lua        |  149 +++
> > test/LuaJIT-tests/trace/snap.lua              |   47 +
> > test/LuaJIT-tests/trace/stitch.lua            |   19 +
> > .../unportable/ffi_arith_int64.lua            |   68 +
> > test/LuaJIT-tests/unportable/math_special.lua |   55 +
> > test/PUC-Lua-5.1-tests/CMakeLists.txt         |   92 ++
> > test/PUC-Lua-5.1-tests/README                 |   41 +
> > test/PUC-Lua-5.1-tests/all.lua                |  145 +++
> > 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            |  432 +++++++
> > test/PUC-Lua-5.1-tests/code.lua               |  143 ++
> > test/PUC-Lua-5.1-tests/constructs.lua         |  247 ++++
> > test/PUC-Lua-5.1-tests/db.lua                 |  538 ++++++++
> > test/PUC-Lua-5.1-tests/errors.lua             |  264 ++++
> > 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                 |  320 +++++
> > 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               |  195 +++
> > test/PUC-Lua-5.1-tests/math.lua               |  213 +++
> > test/PUC-Lua-5.1-tests/nextvar.lua            |  403 ++++++
> > test/PUC-Lua-5.1-tests/pm.lua                 |  281 ++++
> > 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 ++
> > test/lua-Harness-tests/000-sanity.t           |   54 +
> > test/lua-Harness-tests/001-if.t               |   88 ++
> > test/lua-Harness-tests/002-table.t            |   67 +
> > test/lua-Harness-tests/011-while.t            |   89 ++
> > test/lua-Harness-tests/012-repeat.t           |   85 ++
> > test/lua-Harness-tests/014-fornum.t           |  151 +++
> > test/lua-Harness-tests/015-forlist.t          |  111 ++
> > test/lua-Harness-tests/090-tap.t              |   37 +
> > test/lua-Harness-tests/091-profile.t          |   45 +
> > test/lua-Harness-tests/101-boolean.t          |  127 ++
> > test/lua-Harness-tests/102-function.t         |  206 +++
> > test/lua-Harness-tests/103-nil.t              |  127 ++
> > test/lua-Harness-tests/104-number.t           |  246 ++++
> > test/lua-Harness-tests/105-string.t           |  277 ++++
> > test/lua-Harness-tests/106-table.t            |  135 ++
> > test/lua-Harness-tests/107-thread.t           |  135 ++
> > test/lua-Harness-tests/108-userdata.t         |  132 ++
> > test/lua-Harness-tests/200-examples.t         |  104 ++
> > test/lua-Harness-tests/201-assign.t           |  150 +++
> > test/lua-Harness-tests/202-expr.t             |  157 +++
> > test/lua-Harness-tests/203-lexico.t           |  147 +++
> > test/lua-Harness-tests/204-grammar.t          |  233 ++++
> > test/lua-Harness-tests/211-scope.t            |   86 ++
> > test/lua-Harness-tests/212-function.t         |  288 +++++
> > test/lua-Harness-tests/213-closure.t          |   98 ++
> > test/lua-Harness-tests/214-coroutine.t        |  244 ++++
> > test/lua-Harness-tests/221-table.t            |  120 ++
> > test/lua-Harness-tests/222-constructor.t      |  119 ++
> > test/lua-Harness-tests/223-iterator.t         |  203 +++
> > test/lua-Harness-tests/231-metatable.t        |  602 +++++++++
> > test/lua-Harness-tests/232-object.t           |  314 +++++
> > .../241-standalone.t.disabled                 |  269 ++++
> > test/lua-Harness-tests/242-luac.t             |  341 +++++
> > test/lua-Harness-tests/301-basic.t            |  859 ++++++++++++
> > test/lua-Harness-tests/303-package.t          |  290 +++++
> > test/lua-Harness-tests/304-string.t           |  633 +++++++++
> > test/lua-Harness-tests/305-utf8.t.disabled    |   55 +
> > test/lua-Harness-tests/306-table.t            |  372 ++++++
> > test/lua-Harness-tests/307-math.t             |  375 ++++++
> > test/lua-Harness-tests/308-io.t               |  397 ++++++
> > test/lua-Harness-tests/309-os.t               |  275 ++++
> > test/lua-Harness-tests/310-debug.t            |  322 +++++
> > test/lua-Harness-tests/311-bit32.t            |  127 ++
> > test/lua-Harness-tests/314-regex.t            |  222 ++++
> > test/lua-Harness-tests/320-stdin.t            |  133 ++
> > test/lua-Harness-tests/401-bitop.t            |  106 ++
> > test/lua-Harness-tests/402-ffi.t              |  142 ++
> > test/lua-Harness-tests/403-jit.t              |  163 +++
> > test/lua-Harness-tests/404-ext.t              |  171 +++
> > test/lua-Harness-tests/411-luajit.t.disabled  |  211 +++
> > test/lua-Harness-tests/CMakeLists.txt         |   62 +
> > test/lua-Harness-tests/lexico52/lexico.t      |   45 +
> > test/lua-Harness-tests/lexico53/boolean.t     |   43 +
> > test/lua-Harness-tests/lexico53/function.t    |   66 +
> > test/lua-Harness-tests/lexico53/lexico.t      |   30 +
> > test/lua-Harness-tests/lexico53/nil.t         |   43 +
> > test/lua-Harness-tests/lexico53/number.t      |  181 +++
> > test/lua-Harness-tests/lexico53/string.t      |  169 +++
> > test/lua-Harness-tests/lexico53/table.t       |   43 +
> > test/lua-Harness-tests/lexico53/thread.t      |   45 +
> > test/lua-Harness-tests/lexico53/userdata.t    |   45 +
> > test/lua-Harness-tests/lexico53/utf8.t        |  179 +++
> > test/lua-Harness-tests/lexico54/lexico.t      |   19 +
> > test/lua-Harness-tests/lexico54/metatable.t   |   38 +
> > test/lua-Harness-tests/lexico54/utf8.t        |   54 +
> > test/lua-Harness-tests/lexicojit/basic.t      |   27 +
> > test/lua-Harness-tests/lexicojit/ext.t        |   52 +
> > test/lua-Harness-tests/lexicojit/lexico.t     |   32 +
> > test/lua-Harness-tests/profile.lua            |   53 +
> > test/lua-Harness-tests/profile_lua51.lua      |   46 +
> > .../profile_lua51_strict.lua                  |   46 +
> > test/lua-Harness-tests/profile_lua52.lua      |   46 +
> > .../profile_lua52_strict.lua                  |   46 +
> > test/lua-Harness-tests/profile_lua53.lua      |   52 +
> > .../profile_lua53_noconv.lua                  |   55 +
> > .../profile_lua53_strict.lua                  |   52 +
> > test/lua-Harness-tests/profile_lua54.lua      |   52 +
> > .../profile_lua54_noconv.lua                  |   55 +
> > .../profile_lua54_strict.lua                  |   53 +
> > test/lua-Harness-tests/profile_luajit20.lua   |   53 +
> > .../profile_luajit20_compat52.lua             |   53 +
> > test/lua-Harness-tests/profile_luajit21.lua   |   53 +
> > .../profile_luajit21_compat52.lua             |   53 +
> > test/lua-Harness-tests/profile_openresty.lua  |   53 +
> > test/lua-Harness-tests/profile_ravi.lua       |   58 +
> > test/lua-Harness-tests/profile_tiny_fork.lua  |   60 +
> > test/lua-Harness-tests/rx_captures            |   13 +
> > test/lua-Harness-tests/rx_charclass           |   38 +
> > test/lua-Harness-tests/rx_metachars           |  117 ++
> > test/lua-Harness-tests/tap_harness.lua        |  204 +++
> > 322 files changed, 34168 insertions(+), 2 deletions(-)
> > create mode 100644 test/LuaJIT-tests/CMakeLists.txt
> > create mode 100644 test/LuaJIT-tests/README.md
> > create mode 100644 test/LuaJIT-tests/bc/constov.lua
> > create mode 100644 test/LuaJIT-tests/bc/index
> > create mode 100644 test/LuaJIT-tests/common/expect_error.lua
> > create mode 100644 test/LuaJIT-tests/common/ffi_util.inc
> > create mode 100644 test/LuaJIT-tests/common/test_runner_canary.lua
> > create mode 100644 test/LuaJIT-tests/computations.lua
> > create mode 100644 test/LuaJIT-tests/index
> > create mode 100644 test/LuaJIT-tests/lang/andor.lua
> > create mode 100644 test/LuaJIT-tests/lang/assignment.lua
> > create mode 100644 test/LuaJIT-tests/lang/compare.lua
> > create mode 100644 test/LuaJIT-tests/lang/compare_nan.lua
> > create mode 100644 test/LuaJIT-tests/lang/concat.lua
> > create mode 100644 test/LuaJIT-tests/lang/constant/index
> > create mode 100644 test/LuaJIT-tests/lang/constant/number.lua
> > create mode 100644 test/LuaJIT-tests/lang/constant/table.lua
> > create mode 100644 test/LuaJIT-tests/lang/coroutine.lua
> > create mode 100644 test/LuaJIT-tests/lang/for.lua
> > create mode 100644 test/LuaJIT-tests/lang/gc.lua
> > create mode 100644 test/LuaJIT-tests/lang/goto.lua
> > create mode 100644 test/LuaJIT-tests/lang/index
> > create mode 100644 test/LuaJIT-tests/lang/length.lua
> > create mode 100644 test/LuaJIT-tests/lang/meta/arith.lua
> > create mode 100644 test/LuaJIT-tests/lang/meta/arith_jit.lua
> > create mode 100644 test/LuaJIT-tests/lang/meta/call.lua
> > create mode 100644 test/LuaJIT-tests/lang/meta/cat.lua
> > create mode 100644 test/LuaJIT-tests/lang/meta/comp.lua
> > create mode 100644 test/LuaJIT-tests/lang/meta/comp_jit.lua
> > create mode 100644 test/LuaJIT-tests/lang/meta/debuginfo.lua
> > create mode 100644 test/LuaJIT-tests/lang/meta/eq.lua
> > create mode 100644 test/LuaJIT-tests/lang/meta/eq_jit.lua
> > create mode 100644 test/LuaJIT-tests/lang/meta/framegap.lua
> > create mode 100644 test/LuaJIT-tests/lang/meta/index
> > create mode 100644 test/LuaJIT-tests/lang/meta/index.lua
> > create mode 100644 test/LuaJIT-tests/lang/meta/len.lua
> > create mode 100644 test/LuaJIT-tests/lang/meta/newindex.lua
> > create mode 100644 test/LuaJIT-tests/lang/meta/nomm.lua
> > create mode 100644 test/LuaJIT-tests/lang/modulo.lua
> > create mode 100644 test/LuaJIT-tests/lang/self.lua
> > create mode 100644 test/LuaJIT-tests/lang/table.lua
> > create mode 100644 test/LuaJIT-tests/lang/tail_recursion.lua
> > create mode 100644 test/LuaJIT-tests/lang/upvalue/closure.lua
> > create mode 100644 test/LuaJIT-tests/lang/upvalue/index
> > create mode 100644 test/LuaJIT-tests/lang/vararg_jit.lua
> > create mode 100644 test/LuaJIT-tests/lib/base/assert.lua
> > create mode 100644 test/LuaJIT-tests/lib/base/error.lua
> > create mode 100644 test/LuaJIT-tests/lib/base/getfenv.lua
> > create mode 100644 test/LuaJIT-tests/lib/base/getsetmetatable.lua
> > create mode 100644 test/LuaJIT-tests/lib/base/index
> > create mode 100644 test/LuaJIT-tests/lib/base/ipairs.lua
> > create mode 100644 test/LuaJIT-tests/lib/base/next.lua
> > create mode 100644 test/LuaJIT-tests/lib/base/pairs.lua
> > create mode 100644 test/LuaJIT-tests/lib/base/pcall_jit.lua
> > create mode 100644 test/LuaJIT-tests/lib/base/select.lua
> > create mode 100644 test/LuaJIT-tests/lib/base/tonumber_tostring.lua
> > create mode 100644 test/LuaJIT-tests/lib/base/xpcall_jit.lua
> > create mode 100644 test/LuaJIT-tests/lib/bit.lua
> > create mode 100644 test/LuaJIT-tests/lib/contents.lua
> > create mode 100644 test/LuaJIT-tests/lib/coroutine/index
> > create mode 100644 test/LuaJIT-tests/lib/coroutine/yield.lua
> > create mode 100644 test/LuaJIT-tests/lib/ffi/bit64.lua
> > create mode 100644 test/LuaJIT-tests/lib/ffi/cdata_var.lua
> > create mode 100644 test/LuaJIT-tests/lib/ffi/copy_fill.lua
> > create mode 100644 test/LuaJIT-tests/lib/ffi/err.lua
> > create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_arith_ptr.lua
> > create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_bitfield.lua
> > create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_call.lua
> > create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_callback.lua
> > create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_const.lua
> > create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_convert.lua
> > create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_enum.lua
> > create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_gcstep_recursive.lua
> > create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_jit_arith.lua
> > create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_jit_call.lua
> > create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_jit_conv.lua
> > create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_lex_number.lua
> > create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_metatype.lua
> > create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_new.lua
> > create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_parse_array.lua
> > create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_parse_basic.lua
> > create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_parse_cdef.lua
> > create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_parse_struct.lua
> > create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_tabov.lua
> > create mode 100644 test/LuaJIT-tests/lib/ffi/index
> > create mode 100644 test/LuaJIT-tests/lib/ffi/istype.lua
> > create mode 100644 test/LuaJIT-tests/lib/ffi/jit_array.lua
> > create mode 100644 test/LuaJIT-tests/lib/ffi/jit_complex.lua
> > create mode 100644 test/LuaJIT-tests/lib/ffi/jit_misc.lua
> > create mode 100644 test/LuaJIT-tests/lib/ffi/jit_struct.lua
> > create mode 100644 test/LuaJIT-tests/lib/ffi/meta_tostring.lua
> > create mode 100644 test/LuaJIT-tests/lib/ffi/redir.lua
> > create mode 100644 test/LuaJIT-tests/lib/ffi/type_punning.lua
> > create mode 100644 test/LuaJIT-tests/lib/index
> > create mode 100644 test/LuaJIT-tests/lib/math/abs.lua
> > create mode 100644 test/LuaJIT-tests/lib/math/constants.lua
> > create mode 100644 test/LuaJIT-tests/lib/math/index
> > create mode 100644 test/LuaJIT-tests/lib/math/random.lua
> > create mode 100644 test/LuaJIT-tests/lib/string/byte.lua
> > create mode 100644 test/LuaJIT-tests/lib/string/char.lua
> > create mode 100644 test/LuaJIT-tests/lib/string/dump.lua
> > create mode 100644 test/LuaJIT-tests/lib/string/format/index
> > create mode 100644 test/LuaJIT-tests/lib/string/format/num.lua
> > create mode 100644 test/LuaJIT-tests/lib/string/index
> > create mode 100644 test/LuaJIT-tests/lib/string/len.lua
> > create mode 100644 test/LuaJIT-tests/lib/string/lower_upper.lua
> > create mode 100644 test/LuaJIT-tests/lib/string/metatable.lua
> > create mode 100644 test/LuaJIT-tests/lib/string/multiple_functions.lua
> > create mode 100644 test/LuaJIT-tests/lib/string/rep.lua
> > create mode 100644 test/LuaJIT-tests/lib/string/reverse.lua
> > create mode 100644 test/LuaJIT-tests/lib/string/sub.lua
> > create mode 100644 test/LuaJIT-tests/lib/table/concat.lua
> > create mode 100644 test/LuaJIT-tests/lib/table/index
> > create mode 100644 test/LuaJIT-tests/lib/table/insert.lua
> > create mode 100644 test/LuaJIT-tests/lib/table/misc.lua
> > create mode 100644 test/LuaJIT-tests/lib/table/new.lua
> > create mode 100644 test/LuaJIT-tests/lib/table/pack.lua
> > create mode 100644 test/LuaJIT-tests/lib/table/remove.lua
> > create mode 100644 test/LuaJIT-tests/lib/table/sort.lua
> > create mode 100644 test/LuaJIT-tests/misc/alias_alloc.lua
> > create mode 100644 test/LuaJIT-tests/misc/api_call.lua
> > create mode 100644 test/LuaJIT-tests/misc/catch_wrap.lua
> > create mode 100644 test/LuaJIT-tests/misc/coro_traceback.lua
> > create mode 100644 test/LuaJIT-tests/misc/coro_yield.lua
> > create mode 100644 test/LuaJIT-tests/misc/debug_gc.lua
> > create mode 100644 test/LuaJIT-tests/misc/dualnum.lua
> > create mode 100644 test/LuaJIT-tests/misc/for_dir.lua
> > create mode 100644 test/LuaJIT-tests/misc/fori_coerce.lua
> > create mode 100644 test/LuaJIT-tests/misc/gc_rechain.lua
> > create mode 100644 test/LuaJIT-tests/misc/gc_trace.lua
> > create mode 100644 test/LuaJIT-tests/misc/gcstep.lua
> > create mode 100644 test/LuaJIT-tests/misc/hook_active.lua
> > create mode 100644 test/LuaJIT-tests/misc/hook_line.lua
> > create mode 100644 test/LuaJIT-tests/misc/hook_norecord.lua
> > create mode 100644 test/LuaJIT-tests/misc/hook_record.lua
> > create mode 100644 test/LuaJIT-tests/misc/hook_top.lua
> > create mode 100644 test/LuaJIT-tests/misc/jit_flush.lua
> > create mode 100644 test/LuaJIT-tests/misc/lightud.lua
> > create mode 100644 test/LuaJIT-tests/misc/loop_unroll.lua
> > create mode 100644 test/LuaJIT-tests/misc/parse_comp.lua
> > create mode 100644 test/LuaJIT-tests/misc/parse_esc.lua
> > create mode 100644 test/LuaJIT-tests/misc/parse_misc.lua
> > create mode 100644 test/LuaJIT-tests/misc/phi_conv.lua
> > create mode 100644 test/LuaJIT-tests/misc/recurse_deep.lua
> > create mode 100644 test/LuaJIT-tests/misc/recurse_tail.lua
> > create mode 100644 test/LuaJIT-tests/misc/stack_gc.lua
> > create mode 100644 test/LuaJIT-tests/misc/stack_purge.lua
> > create mode 100644 test/LuaJIT-tests/misc/stackov.lua
> > create mode 100644 test/LuaJIT-tests/misc/stackovc.lua
> > create mode 100644 test/LuaJIT-tests/misc/tcall_base.lua
> > create mode 100644 test/LuaJIT-tests/misc/tcall_loop.lua
> > create mode 100644 test/LuaJIT-tests/misc/tonumber_scan.lua
> > create mode 100644 test/LuaJIT-tests/misc/uclo.lua
> > create mode 100644 test/LuaJIT-tests/misc/unordered_jit.lua
> > create mode 100644 test/LuaJIT-tests/misc/wbarrier.lua
> > create mode 100644 test/LuaJIT-tests/misc/wbarrier_jit.lua
> > create mode 100644 test/LuaJIT-tests/misc/wbarrier_obar.lua
> > create mode 100644 test/LuaJIT-tests/opt/dse/array.lua
> > create mode 100644 test/LuaJIT-tests/opt/dse/field.lua
> > create mode 100644 test/LuaJIT-tests/opt/dse/index
> > create mode 100644 test/LuaJIT-tests/opt/fold/index
> > create mode 100644 test/LuaJIT-tests/opt/fold/kfold.lua
> > create mode 100644 test/LuaJIT-tests/opt/fuse.lua
> > create mode 100644 test/LuaJIT-tests/opt/fwd/hrefk_rollback.lua
> > create mode 100644 test/LuaJIT-tests/opt/fwd/index
> > create mode 100644 test/LuaJIT-tests/opt/fwd/tnew_tdup.lua
> > create mode 100644 test/LuaJIT-tests/opt/fwd/upval.lua
> > create mode 100644 test/LuaJIT-tests/opt/index
> > create mode 100644 test/LuaJIT-tests/opt/loop/index
> > create mode 100644 test/LuaJIT-tests/opt/loop/unroll.lua
> > create mode 100644 test/LuaJIT-tests/opt/sink/alloc.lua
> > create mode 100644 test/LuaJIT-tests/opt/sink/ffi.lua
> > create mode 100644 test/LuaJIT-tests/opt/sink/ffi_nosink.lua
> > create mode 100644 test/LuaJIT-tests/opt/sink/index
> > create mode 100644 test/LuaJIT-tests/opt/sink/nosink.lua
> > create mode 100644 test/LuaJIT-tests/src/cpptest.cpp
> > create mode 100644 test/LuaJIT-tests/src/ctest.c
> > create mode 100644 test/LuaJIT-tests/sysdep/catch_cpp.lua
> > create mode 100644 test/LuaJIT-tests/sysdep/ffi_include_gtk.lua
> > create mode 100644 test/LuaJIT-tests/sysdep/ffi_include_std.lua
> > create mode 100644 test/LuaJIT-tests/sysdep/ffi_lib_c.lua
> > create mode 100644 test/LuaJIT-tests/sysdep/ffi_lib_z.lua
> > create mode 100644 test/LuaJIT-tests/test.lua
> > create mode 100644 test/LuaJIT-tests/trace/exit_frame.lua
> > create mode 100644 test/LuaJIT-tests/trace/exit_growstack.lua
> > create mode 100644 test/LuaJIT-tests/trace/exit_jfuncf.lua
> > create mode 100644 test/LuaJIT-tests/trace/gc64_slot_revival.lua
> > create mode 100644 test/LuaJIT-tests/trace/index
> > create mode 100644 test/LuaJIT-tests/trace/phi/copyspill.lua
> > create mode 100644 test/LuaJIT-tests/trace/phi/index
> > create mode 100644 test/LuaJIT-tests/trace/phi/ref.lua
> > create mode 100644 test/LuaJIT-tests/trace/phi/rotate.lua
> > create mode 100644 test/LuaJIT-tests/trace/snap.lua
> > create mode 100644 test/LuaJIT-tests/trace/stitch.lua
> > create mode 100644 test/LuaJIT-tests/unportable/ffi_arith_int64.lua
> > create mode 100644 test/LuaJIT-tests/unportable/math_special.lua
> > 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/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
> > create mode 100755 test/lua-Harness-tests/000-sanity.t
> > create mode 100755 test/lua-Harness-tests/001-if.t
> > create mode 100755 test/lua-Harness-tests/002-table.t
> > create mode 100755 test/lua-Harness-tests/011-while.t
> > create mode 100755 test/lua-Harness-tests/012-repeat.t
> > create mode 100755 test/lua-Harness-tests/014-fornum.t
> > create mode 100755 test/lua-Harness-tests/015-forlist.t
> > create mode 100755 test/lua-Harness-tests/090-tap.t
> > create mode 100755 test/lua-Harness-tests/091-profile.t
> > create mode 100755 test/lua-Harness-tests/101-boolean.t
> > create mode 100755 test/lua-Harness-tests/102-function.t
> > create mode 100755 test/lua-Harness-tests/103-nil.t
> > create mode 100755 test/lua-Harness-tests/104-number.t
> > create mode 100755 test/lua-Harness-tests/105-string.t
> > create mode 100755 test/lua-Harness-tests/106-table.t
> > create mode 100755 test/lua-Harness-tests/107-thread.t
> > create mode 100755 test/lua-Harness-tests/108-userdata.t
> > create mode 100755 test/lua-Harness-tests/200-examples.t
> > create mode 100755 test/lua-Harness-tests/201-assign.t
> > create mode 100755 test/lua-Harness-tests/202-expr.t
> > create mode 100755 test/lua-Harness-tests/203-lexico.t
> > create mode 100755 test/lua-Harness-tests/204-grammar.t
> > create mode 100755 test/lua-Harness-tests/211-scope.t
> > create mode 100755 test/lua-Harness-tests/212-function.t
> > create mode 100755 test/lua-Harness-tests/213-closure.t
> > create mode 100755 test/lua-Harness-tests/214-coroutine.t
> > create mode 100755 test/lua-Harness-tests/221-table.t
> > create mode 100755 test/lua-Harness-tests/222-constructor.t
> > create mode 100755 test/lua-Harness-tests/223-iterator.t
> > create mode 100755 test/lua-Harness-tests/231-metatable.t
> > create mode 100755 test/lua-Harness-tests/232-object.t
> > create mode 100755 test/lua-Harness-tests/241-standalone.t.disabled
> > create mode 100755 test/lua-Harness-tests/242-luac.t
> > create mode 100755 test/lua-Harness-tests/301-basic.t
> > create mode 100755 test/lua-Harness-tests/303-package.t
> > create mode 100755 test/lua-Harness-tests/304-string.t
> > create mode 100755 test/lua-Harness-tests/305-utf8.t.disabled
> > create mode 100755 test/lua-Harness-tests/306-table.t
> > create mode 100755 test/lua-Harness-tests/307-math.t
> > create mode 100755 test/lua-Harness-tests/308-io.t
> > create mode 100755 test/lua-Harness-tests/309-os.t
> > create mode 100755 test/lua-Harness-tests/310-debug.t
> > create mode 100755 test/lua-Harness-tests/311-bit32.t
> > create mode 100755 test/lua-Harness-tests/314-regex.t
> > create mode 100755 test/lua-Harness-tests/320-stdin.t
> > create mode 100755 test/lua-Harness-tests/401-bitop.t
> > create mode 100755 test/lua-Harness-tests/402-ffi.t
> > create mode 100755 test/lua-Harness-tests/403-jit.t
> > create mode 100755 test/lua-Harness-tests/404-ext.t
> > create mode 100755 test/lua-Harness-tests/411-luajit.t.disabled
> > create mode 100644 test/lua-Harness-tests/CMakeLists.txt
> > create mode 100644 test/lua-Harness-tests/lexico52/lexico.t
> > create mode 100644 test/lua-Harness-tests/lexico53/boolean.t
> > create mode 100644 test/lua-Harness-tests/lexico53/function.t
> > create mode 100644 test/lua-Harness-tests/lexico53/lexico.t
> > create mode 100644 test/lua-Harness-tests/lexico53/nil.t
> > create mode 100644 test/lua-Harness-tests/lexico53/number.t
> > create mode 100644 test/lua-Harness-tests/lexico53/string.t
> > create mode 100644 test/lua-Harness-tests/lexico53/table.t
> > create mode 100644 test/lua-Harness-tests/lexico53/thread.t
> > create mode 100644 test/lua-Harness-tests/lexico53/userdata.t
> > create mode 100644 test/lua-Harness-tests/lexico53/utf8.t
> > create mode 100644 test/lua-Harness-tests/lexico54/lexico.t
> > create mode 100644 test/lua-Harness-tests/lexico54/metatable.t
> > create mode 100644 test/lua-Harness-tests/lexico54/utf8.t
> > create mode 100644 test/lua-Harness-tests/lexicojit/basic.t
> > create mode 100644 test/lua-Harness-tests/lexicojit/ext.t
> > create mode 100644 test/lua-Harness-tests/lexicojit/lexico.t
> > create mode 100644 test/lua-Harness-tests/profile.lua
> > create mode 100644 test/lua-Harness-tests/profile_lua51.lua
> > create mode 100644 test/lua-Harness-tests/profile_lua51_strict.lua
> > create mode 100644 test/lua-Harness-tests/profile_lua52.lua
> > create mode 100644 test/lua-Harness-tests/profile_lua52_strict.lua
> > create mode 100644 test/lua-Harness-tests/profile_lua53.lua
> > create mode 100644 test/lua-Harness-tests/profile_lua53_noconv.lua
> > create mode 100644 test/lua-Harness-tests/profile_lua53_strict.lua
> > create mode 100644 test/lua-Harness-tests/profile_lua54.lua
> > create mode 100644 test/lua-Harness-tests/profile_lua54_noconv.lua
> > create mode 100644 test/lua-Harness-tests/profile_lua54_strict.lua
> > create mode 100644 test/lua-Harness-tests/profile_luajit20.lua
> > create mode 100644 test/lua-Harness-tests/profile_luajit20_compat52.lua
> > create mode 100644 test/lua-Harness-tests/profile_luajit21.lua
> > create mode 100644 test/lua-Harness-tests/profile_luajit21_compat52.lua
> > create mode 100644 test/lua-Harness-tests/profile_openresty.lua
> > create mode 100644 test/lua-Harness-tests/profile_ravi.lua
> > create mode 100644 test/lua-Harness-tests/profile_tiny_fork.lua
> > create mode 100644 test/lua-Harness-tests/rx_captures
> > create mode 100644 test/lua-Harness-tests/rx_charclass
> > create mode 100644 test/lua-Harness-tests/rx_metachars
> > create mode 100644 test/lua-Harness-tests/tap_harness.lua
> > 
> > -- 
> > 2.28.0
> > 
> > [0]: https://github.com/tarantool/tarantool/runs/2029452344
> > [1]: https://github.com/google/sanitizers/issues/980
> > [2]: https://github.com/google/sanitizers/issues/189
> > [3]: https://github.com/google/sanitizers/wiki/AddressSanitizerFlags
> 

-- 
Best regards,
Sergey Kaplun

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

* Re: [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites
  2021-03-04 19:58   ` Sergey Kaplun via Tarantool-patches
@ 2021-03-05 10:48     ` Sergey Ostanevich via Tarantool-patches
  2021-03-16 11:21       ` Igor Munkin via Tarantool-patches
  0 siblings, 1 reply; 26+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-05 10:48 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

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

Hi!


> On 4 Mar 2021, at 22:58, Sergey Kaplun <skaplun@tarantool.org> wrote:
> 
> On 04.03.21, Sergey Ostanevich wrote:
>> Hi!
>> 
>> Thanks for the patchset - brief review
>> 
>> part 1 - obvious, LGTM.
>> 
>> part 2 - LGTM, good to have all follow-ups set.
> 
> Do you mean to reference all follow-ups inside commit message?
> 

There could be just one - if no specific GH created.

>> 
>> part 3 - should have a follow-up ticket to cover all suppressions, if we plan to fix them.
> 
> Ditto.
> There are some follow ups that can be grepped by qa and luajit labels.
> 

And this is something I don’t want to do - to grep using lables. The patch should
have reference, so I can see all links at once.

>> 
>> part 4-8 are LGTM
>> 
>> part 9 (_G and some modules in Tarantool are different): Are we plan to fix it in some way? There should be a follow-up then.
> 
> For now I can't see any good solution, except ignoring them by special
> option like slow tests.
> 

I don’t object to ignore them. My question if we plan to tweak the tests to align
with Tarantool? What will happen to the test if Tarantool will change preloaded
modules?

>> 
>> parts 10-15 are LGTM
>> 
>> Regards,
>> Sergos



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

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

* Re: [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites
  2021-03-04 10:23 [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites Sergey Kaplun via Tarantool-patches
                   ` (15 preceding siblings ...)
  2021-03-04 16:24 ` [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites Sergey Ostanevich via Tarantool-patches
@ 2021-03-09 23:59 ` Igor Munkin via Tarantool-patches
  2021-03-10  8:09   ` Sergey Kaplun via Tarantool-patches
                     ` (2 more replies)
  16 siblings, 3 replies; 26+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-09 23:59 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

I've precisely reviewed patches 04-09 and they look good. I've polished
a bit[1] the series, so it can be applied to the trunk out of the order.
CI[2] is green.

BTW, I would like to leave some major points related to my review.

1. The suite has been taken intact. To check this I used the following
recipe:
| $ pwd
| /LuaJIT-test-cleanup/test
| $ git remote -v
| origin  https://github.com/LuaJIT/LuaJIT-test-cleanup.git (fetch)
| origin  https://github.com/LuaJIT/LuaJIT-test-cleanup.git (push)
| $ git lo -1
| 014708b (HEAD -> master, origin/master, origin/HEAD) Add test for BC_VARG slot revival
| $ find . -type f | sort | xargs md5sum > ~/vanilla
| <...>
| $ pwd
| /tarantool-luajit/test/LuaJIT-test
| $ git remote -v
| origin  git@github.com:tarantool/luajit (fetch)
| origin  git@github.com:tarantool/luajit (push)
| $ git lo -1
| cc0967c (HEAD) test: add LuaJIT-test-cleanup test suite
| $ find . -type f | sort | xargs md5sum > ~/tarantool
| $ diff ~/vanilla ~/tarantool
| > 91cb30f369b83d7626a8ae852781ebb5  ./CMakeLists.txt

2. I've introduced a new CMake option: LUAJIT_TEST_INIT. You can read
the description here[3]. It allows to enclose the partial LUA_INIT
emulation, implemented via '-e dofile[[${LUAJIT_TEST_INIT}]]' and
obliges user to set the name of the Lua script to be run prior to the
testing suite[4]. By default it does nothing by reading from /dev/null.

3. Since CLI flags can be used for LuaJIT testing now, <utils.selfrun>
need to be adjusted[5] to respect the passed flags in child process.

This part LGTM, so if nobody is against the version I've checked to the
branch[1], then I apply it to the trunk after your and Sergos approval.

On 04.03.21, Sergey Kaplun wrote:
> WARNING: This patch doesn't require full and precise review now.
> 
> This draft should be structured (commits at least) from test
> suite to test suite if necessary.
> 
> You can complain test suites with the following command, for example:
> | $ diff --color -urZ test/PUC-Lua-5.1-tests/ ~/Downloads/lua5.1-tests/
> 
> Branch: https://github.com/tarantool/luajit/tree/skaplun/gh-4473-adopt-luavela-test-suites
> Tarantool's branch: https://github.com/tarantool/tarantool/tree/skaplun/gh-4473-adopt-luavela-test-suites
> Epic: https://github.com/tarantool/tarantool/issues/4473
> Issues:
> * https://github.com/tarantool/tarantool/issues/5845
> * https://github.com/tarantool/tarantool/issues/4064
> * https://github.com/tarantool/tarantool/issues/5844
> 
> CI is red due to ASan failure [0] for PUC-Lua-5.1 test suite.
> Looks related to https://github.com/tarantool/tarantool/issues/5747,
> but it is hard to tell without backtrace.
> 
> Locally, I get tons of errors like this for each of newly added test
> suites:
> | ==31930==WARNING: ASan is ignoring requested __asan_handle_no_return: stack top: 0x7fffbb603000; bottom 0x7f4e271fd000; size: 0x00b194406000 (762696458240)
> | False positive error reports may follow
> | For details see https://github.com/google/sanitizers/issues/189
> 
> After that there are failures like:
> 
> | ==24658==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7f6b741fefa8 at pc 0x000000c91926 bp 0x7f6b741fec90 sp 0x7f6b741fec88
> | READ of size 8 at 0x7f6b741fefa8 thread T0
> |     #0 0xc91925 in lj_strfmt_pushvf /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_strfmt.c:438:23
> |     #1 0xc6f8fe in lj_err_lex /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_err.c:651:9
> |     #2 0xce0fa1 in lj_lex_error /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_lex.c:495:3
> |     #3 0xce3285 in err_token /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_parse.c:175:3
> |     #4 0xcf27bc in parse_stmt /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_parse.c
> |     #5 0xce3ceb in parse_chunk /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_parse.c:2684:14
> |     #6 0xce3ceb in lj_parse /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_parse.c:2717:3
> |     #7 0xc7eeaa in cpparser /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_load.c:41:29
> |     #8 0xd8a6b7 in lj_vm_cpcall /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/build/third_party/luajit/src/lj_vm.S:1191
> |     #9 0xc7fed6 in lua_loadx /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_load.c:58:12
> |     #10 0xc7fed6 in luaL_loadbufferx /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_load.c:143:10
> |     #11 0xca9b12 in lj_cf_load /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lib_base.c:401:14
> |     #12 0xd8a2fa in lj_BC_FUNCC /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/build/third_party/luajit/src/lj_vm.S:811
> |     #13 0xc5be1f in lua_pcall /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_api.c:1158:12
> |     #14 0xb2ad71 in luaT_call /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/src/lua/utils.c:1022:6
> |     #15 0xb1532c in lua_main /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/src/lua/init.c:559:11
> |     #16 0xb14c9a in run_script_f /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/src/lua/init.c:634:7
> |     #17 0x526d96 in fiber_cxx_invoke(int (*)(__va_list_tag*), __va_list_tag*) /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/src/lib/core/fiber.h:882:10
> |     #18 0xb7f688 in fiber_loop /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/src/lib/core/fiber.c:879:18
> |     #19 0x14b3b10 in coro_init /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/coro/coro.c:110:3
> |
> | Address 0x7f6b741fefa8 is a wild pointer.
> | SUMMARY: AddressSanitizer: stack-buffer-overflow /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_strfmt.c:438:23 in lj_strfmt_pushvf
> | Shadow bytes around the buggy address:
> |   0x0fedee837da0: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
> |   0x0fedee837db0: 00 00 00 f3 f3 f3 f3 f3 00 00 00 00 00 00 00 00
> |   0x0fedee837dc0: f1 f1 f1 f1 00 00 00 00 00 00 00 04 f3 f3 f3 f3
> |   0x0fedee837dd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> |   0x0fedee837de0: f1 f1 f1 f1 00 00 00 f3 f3 f3 f3 f3 f2 f2 f2 f2
> | =>0x0fedee837df0: f8 f8 f8 f8 f3[f3]f3 f3 00 00 00 00 00 00 00 00
> |   0x0fedee837e00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> |   0x0fedee837e10: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 f8 f8 f8 f2
> |   0x0fedee837e20: f2 f2 f2 f2 f8 f8 f8 f2 f2 f2 f2 f2 f8 f8 f8 f8
> |   0x0fedee837e30: f2 f2 f2 f2 f8 f8 f8 f2 f2 f2 f2 f2 f8 f8 f8 f2
> |   0x0fedee837e40: f2 f2 f2 f2 f8 f8 f8 f2 f2 f2 f2 f2 f8 f8 f8 f2
> | Shadow byte legend (one shadow byte represents 8 application bytes):
> |   Addressable:           00
> |   Partially addressable: 01 02 03 04 05 06 07 
> |   Heap left redzone:       fa
> |   Freed heap region:       fd
> |   Stack left redzone:      f1
> |   Stack mid redzone:       f2
> |   Stack right redzone:     f3
> |   Stack after return:      f5
> |   Stack use after scope:   f8
> 
> It can be simply reproduce locally with:
> | $ ASAN=ON LSAN_OPTIONS=suppressions=asan/lsan.supp ASAN_OPTIONS=heap_profile=0:unmap_shadow_on_exit=1:detect_invalid_pointer_pairs=1:symbolize=1:detect_leaks=1:dump_instruction_bytes=1:print_suppressions=0:asan_stack=0 src/tarantool -e 'prog = [[ do]] for _=1,3 do pcall(loadstring(string.sub(prog, 1, _))) end'
> 
> It may be the reason of failures too, see [1][2].
> 
> According to [3], there is no any way except to compile with -asan-stack
> flag, but it looks like overkill. So I propose to exclude PUC-Lua-5.1
> test suite from ASan job for now (at least this is out of scoupe of the
> original issue).
> 
> Mergen Imeev (8):
>   test: add LuaJIT-test-cleanup test suite
>   test: change tests to match de5568e
>   test: change tests to match c198167
>   test: change tests to match 5a61e1a
>   test: change LuaJIT suite tests to match b4e6bf0
>   test: adjust LuaJIT test suite for Tarantool
>   test: add lua-Harness test suite
>   test: adjust lua-Harness test suite for Tarantool
> 
> Sergey Kaplun (7):
>   test: add PUC-Rio Lua 5.1 test suite
>   test: adapt PUC-Rio Lua 5.1 test suite for LuaJIT
>   test: adapt Lua 5.1 test suite for Tarantool
>   test: disable 305-utf8 of lua-Harness suite
>   test: disable 241-standalone of lua-Harness suite
>   test: disable 411-luajit of lua-Harness suite
>   test: skip test for getenv in 309-os.t
> 
>  .gitignore                                    |    1 +
>  .luacheckrc                                   |    7 +-
>  CMakeLists.txt                                |    8 +
>  test/CMakeLists.txt                           |    6 +
>  test/LuaJIT-tests/CMakeLists.txt              |   20 +
>  test/LuaJIT-tests/README.md                   |  110 ++
>  test/LuaJIT-tests/bc/constov.lua              |   16 +
>  test/LuaJIT-tests/bc/index                    |    1 +
>  test/LuaJIT-tests/common/expect_error.lua     |   16 +
>  test/LuaJIT-tests/common/ffi_util.inc         |   41 +
>  .../common/test_runner_canary.lua             |    1 +
>  test/LuaJIT-tests/computations.lua            |  113 ++
>  test/LuaJIT-tests/index                       |    6 +
>  test/LuaJIT-tests/lang/andor.lua              |   61 +
>  test/LuaJIT-tests/lang/assignment.lua         |   46 +
>  test/LuaJIT-tests/lang/compare.lua            |  323 +++++
>  test/LuaJIT-tests/lang/compare_nan.lua        |   99 ++
>  test/LuaJIT-tests/lang/concat.lua             |  112 ++
>  test/LuaJIT-tests/lang/constant/index         |    2 +
>  test/LuaJIT-tests/lang/constant/number.lua    |   12 +
>  test/LuaJIT-tests/lang/constant/table.lua     |   15 +
>  test/LuaJIT-tests/lang/coroutine.lua          |    8 +
>  test/LuaJIT-tests/lang/for.lua                |   45 +
>  test/LuaJIT-tests/lang/gc.lua                 |   42 +
>  test/LuaJIT-tests/lang/goto.lua               |  149 +++
>  test/LuaJIT-tests/lang/index                  |   18 +
>  test/LuaJIT-tests/lang/length.lua             |   23 +
>  test/LuaJIT-tests/lang/meta/arith.lua         |  118 ++
>  test/LuaJIT-tests/lang/meta/arith_jit.lua     |   68 +
>  test/LuaJIT-tests/lang/meta/call.lua          |   81 ++
>  test/LuaJIT-tests/lang/meta/cat.lua           |   61 +
>  test/LuaJIT-tests/lang/meta/comp.lua          |  120 ++
>  test/LuaJIT-tests/lang/meta/comp_jit.lua      |  104 ++
>  test/LuaJIT-tests/lang/meta/debuginfo.lua     |   81 ++
>  test/LuaJIT-tests/lang/meta/eq.lua            |   30 +
>  test/LuaJIT-tests/lang/meta/eq_jit.lua        |   35 +
>  test/LuaJIT-tests/lang/meta/framegap.lua      |   24 +
>  test/LuaJIT-tests/lang/meta/index             |   14 +
>  test/LuaJIT-tests/lang/meta/index.lua         |   60 +
>  test/LuaJIT-tests/lang/meta/len.lua           |   42 +
>  test/LuaJIT-tests/lang/meta/newindex.lua      |   69 +
>  test/LuaJIT-tests/lang/meta/nomm.lua          |   21 +
>  test/LuaJIT-tests/lang/modulo.lua             |   46 +
>  test/LuaJIT-tests/lang/self.lua               |   19 +
>  test/LuaJIT-tests/lang/table.lua              |   32 +
>  test/LuaJIT-tests/lang/tail_recursion.lua     |   20 +
>  test/LuaJIT-tests/lang/upvalue/closure.lua    |   84 ++
>  test/LuaJIT-tests/lang/upvalue/index          |    1 +
>  test/LuaJIT-tests/lang/vararg_jit.lua         |   95 ++
>  test/LuaJIT-tests/lib/base/assert.lua         |   33 +
>  test/LuaJIT-tests/lib/base/error.lua          |   43 +
>  test/LuaJIT-tests/lib/base/getfenv.lua        |   13 +
>  .../LuaJIT-tests/lib/base/getsetmetatable.lua |   33 +
>  test/LuaJIT-tests/lib/base/index              |   11 +
>  test/LuaJIT-tests/lib/base/ipairs.lua         |   41 +
>  test/LuaJIT-tests/lib/base/next.lua           |   17 +
>  test/LuaJIT-tests/lib/base/pairs.lua          |   73 ++
>  test/LuaJIT-tests/lib/base/pcall_jit.lua      |   74 ++
>  test/LuaJIT-tests/lib/base/select.lua         |  105 ++
>  .../lib/base/tonumber_tostring.lua            |   81 ++
>  test/LuaJIT-tests/lib/base/xpcall_jit.lua     |   83 ++
>  test/LuaJIT-tests/lib/bit.lua                 |   98 ++
>  test/LuaJIT-tests/lib/contents.lua            |  171 +++
>  test/LuaJIT-tests/lib/coroutine/index         |    1 +
>  test/LuaJIT-tests/lib/coroutine/yield.lua     |  109 ++
>  test/LuaJIT-tests/lib/ffi/bit64.lua           |  130 ++
>  test/LuaJIT-tests/lib/ffi/cdata_var.lua       |   47 +
>  test/LuaJIT-tests/lib/ffi/copy_fill.lua       |   64 +
>  test/LuaJIT-tests/lib/ffi/err.lua             |   35 +
>  test/LuaJIT-tests/lib/ffi/ffi_arith_ptr.lua   |  106 ++
>  test/LuaJIT-tests/lib/ffi/ffi_bitfield.lua    |  108 ++
>  test/LuaJIT-tests/lib/ffi/ffi_call.lua        |  266 ++++
>  test/LuaJIT-tests/lib/ffi/ffi_callback.lua    |  158 +++
>  test/LuaJIT-tests/lib/ffi/ffi_const.lua       |  113 ++
>  test/LuaJIT-tests/lib/ffi/ffi_convert.lua     |  787 +++++++++++
>  test/LuaJIT-tests/lib/ffi/ffi_enum.lua        |   57 +
>  .../lib/ffi/ffi_gcstep_recursive.lua          |   66 +
>  test/LuaJIT-tests/lib/ffi/ffi_jit_arith.lua   |  155 +++
>  test/LuaJIT-tests/lib/ffi/ffi_jit_call.lua    |  154 +++
>  test/LuaJIT-tests/lib/ffi/ffi_jit_conv.lua    |  277 ++++
>  test/LuaJIT-tests/lib/ffi/ffi_lex_number.lua  |   51 +
>  test/LuaJIT-tests/lib/ffi/ffi_metatype.lua    |  245 ++++
>  test/LuaJIT-tests/lib/ffi/ffi_new.lua         |  106 ++
>  test/LuaJIT-tests/lib/ffi/ffi_parse_array.lua |   78 ++
>  test/LuaJIT-tests/lib/ffi/ffi_parse_basic.lua |  131 ++
>  test/LuaJIT-tests/lib/ffi/ffi_parse_cdef.lua  |   77 ++
>  .../LuaJIT-tests/lib/ffi/ffi_parse_struct.lua |  259 ++++
>  test/LuaJIT-tests/lib/ffi/ffi_tabov.lua       |   12 +
>  test/LuaJIT-tests/lib/ffi/index               |   12 +
>  test/LuaJIT-tests/lib/ffi/istype.lua          |   88 ++
>  test/LuaJIT-tests/lib/ffi/jit_array.lua       |  104 ++
>  test/LuaJIT-tests/lib/ffi/jit_complex.lua     |  109 ++
>  test/LuaJIT-tests/lib/ffi/jit_misc.lua        |  109 ++
>  test/LuaJIT-tests/lib/ffi/jit_struct.lua      |  201 +++
>  test/LuaJIT-tests/lib/ffi/meta_tostring.lua   |   55 +
>  test/LuaJIT-tests/lib/ffi/redir.lua           |   19 +
>  test/LuaJIT-tests/lib/ffi/type_punning.lua    |  138 ++
>  test/LuaJIT-tests/lib/index                   |    8 +
>  test/LuaJIT-tests/lib/math/abs.lua            |   16 +
>  test/LuaJIT-tests/lib/math/constants.lua      |    8 +
>  test/LuaJIT-tests/lib/math/index              |    3 +
>  test/LuaJIT-tests/lib/math/random.lua         |   47 +
>  test/LuaJIT-tests/lib/string/byte.lua         |   92 ++
>  test/LuaJIT-tests/lib/string/char.lua         |   29 +
>  test/LuaJIT-tests/lib/string/dump.lua         |   31 +
>  test/LuaJIT-tests/lib/string/format/index     |    1 +
>  test/LuaJIT-tests/lib/string/format/num.lua   |  184 +++
>  test/LuaJIT-tests/lib/string/index            |   11 +
>  test/LuaJIT-tests/lib/string/len.lua          |   14 +
>  test/LuaJIT-tests/lib/string/lower_upper.lua  |   51 +
>  test/LuaJIT-tests/lib/string/metatable.lua    |    3 +
>  .../lib/string/multiple_functions.lua         |   16 +
>  test/LuaJIT-tests/lib/string/rep.lua          |   68 +
>  test/LuaJIT-tests/lib/string/reverse.lua      |   13 +
>  test/LuaJIT-tests/lib/string/sub.lua          |  189 +++
>  test/LuaJIT-tests/lib/table/concat.lua        |   55 +
>  test/LuaJIT-tests/lib/table/index             |    6 +
>  test/LuaJIT-tests/lib/table/insert.lua        |   17 +
>  test/LuaJIT-tests/lib/table/misc.lua          |   58 +
>  test/LuaJIT-tests/lib/table/new.lua           |   11 +
>  test/LuaJIT-tests/lib/table/pack.lua          |    7 +
>  test/LuaJIT-tests/lib/table/remove.lua        |   42 +
>  test/LuaJIT-tests/lib/table/sort.lua          |   27 +
>  test/LuaJIT-tests/misc/alias_alloc.lua        |   54 +
>  test/LuaJIT-tests/misc/api_call.lua           |   98 ++
>  test/LuaJIT-tests/misc/catch_wrap.lua         |   45 +
>  test/LuaJIT-tests/misc/coro_traceback.lua     |    8 +
>  test/LuaJIT-tests/misc/coro_yield.lua         |  111 ++
>  test/LuaJIT-tests/misc/debug_gc.lua           |   47 +
>  test/LuaJIT-tests/misc/dualnum.lua            |   47 +
>  test/LuaJIT-tests/misc/for_dir.lua            |   13 +
>  test/LuaJIT-tests/misc/fori_coerce.lua        |   33 +
>  test/LuaJIT-tests/misc/gc_rechain.lua         |   32 +
>  test/LuaJIT-tests/misc/gc_trace.lua           |   37 +
>  test/LuaJIT-tests/misc/gcstep.lua             |   33 +
>  test/LuaJIT-tests/misc/hook_active.lua        |   95 ++
>  test/LuaJIT-tests/misc/hook_line.lua          |   41 +
>  test/LuaJIT-tests/misc/hook_norecord.lua      |   12 +
>  test/LuaJIT-tests/misc/hook_record.lua        |    8 +
>  test/LuaJIT-tests/misc/hook_top.lua           |   55 +
>  test/LuaJIT-tests/misc/jit_flush.lua          |   50 +
>  test/LuaJIT-tests/misc/lightud.lua            |   88 ++
>  test/LuaJIT-tests/misc/loop_unroll.lua        |   35 +
>  test/LuaJIT-tests/misc/parse_comp.lua         |   13 +
>  test/LuaJIT-tests/misc/parse_esc.lua          |    7 +
>  test/LuaJIT-tests/misc/parse_misc.lua         |   31 +
>  test/LuaJIT-tests/misc/phi_conv.lua           |   53 +
>  test/LuaJIT-tests/misc/recurse_deep.lua       |   29 +
>  test/LuaJIT-tests/misc/recurse_tail.lua       |   22 +
>  test/LuaJIT-tests/misc/stack_gc.lua           |   15 +
>  test/LuaJIT-tests/misc/stack_purge.lua        |   25 +
>  test/LuaJIT-tests/misc/stackov.lua            |   40 +
>  test/LuaJIT-tests/misc/stackovc.lua           |    4 +
>  test/LuaJIT-tests/misc/tcall_base.lua         |   20 +
>  test/LuaJIT-tests/misc/tcall_loop.lua         |    8 +
>  test/LuaJIT-tests/misc/tonumber_scan.lua      |  180 +++
>  test/LuaJIT-tests/misc/uclo.lua               |   91 ++
>  test/LuaJIT-tests/misc/unordered_jit.lua      |   96 ++
>  test/LuaJIT-tests/misc/wbarrier.lua           |    7 +
>  test/LuaJIT-tests/misc/wbarrier_jit.lua       |   18 +
>  test/LuaJIT-tests/misc/wbarrier_obar.lua      |   22 +
>  test/LuaJIT-tests/opt/dse/array.lua           |  197 +++
>  test/LuaJIT-tests/opt/dse/field.lua           |   70 +
>  test/LuaJIT-tests/opt/dse/index               |    2 +
>  test/LuaJIT-tests/opt/fold/index              |    1 +
>  test/LuaJIT-tests/opt/fold/kfold.lua          |   81 ++
>  test/LuaJIT-tests/opt/fuse.lua                |    5 +
>  test/LuaJIT-tests/opt/fwd/hrefk_rollback.lua  |   32 +
>  test/LuaJIT-tests/opt/fwd/index               |    3 +
>  test/LuaJIT-tests/opt/fwd/tnew_tdup.lua       |   69 +
>  test/LuaJIT-tests/opt/fwd/upval.lua           |   50 +
>  test/LuaJIT-tests/opt/index                   |    6 +
>  test/LuaJIT-tests/opt/loop/index              |    1 +
>  test/LuaJIT-tests/opt/loop/unroll.lua         |   32 +
>  test/LuaJIT-tests/opt/sink/alloc.lua          |  126 ++
>  test/LuaJIT-tests/opt/sink/ffi.lua            |  121 ++
>  test/LuaJIT-tests/opt/sink/ffi_nosink.lua     |   45 +
>  test/LuaJIT-tests/opt/sink/index              |    4 +
>  test/LuaJIT-tests/opt/sink/nosink.lua         |  109 ++
>  test/LuaJIT-tests/src/cpptest.cpp             |  129 ++
>  test/LuaJIT-tests/src/ctest.c                 |  339 +++++
>  test/LuaJIT-tests/sysdep/catch_cpp.lua        |   71 +
>  test/LuaJIT-tests/sysdep/ffi_include_gtk.lua  |    9 +
>  test/LuaJIT-tests/sysdep/ffi_include_std.lua  |   36 +
>  test/LuaJIT-tests/sysdep/ffi_lib_c.lua        |   87 ++
>  test/LuaJIT-tests/sysdep/ffi_lib_z.lua        |  107 ++
>  test/LuaJIT-tests/test.lua                    |  416 ++++++
>  test/LuaJIT-tests/trace/exit_frame.lua        |   79 ++
>  test/LuaJIT-tests/trace/exit_growstack.lua    |   28 +
>  test/LuaJIT-tests/trace/exit_jfuncf.lua       |   30 +
>  test/LuaJIT-tests/trace/gc64_slot_revival.lua |   18 +
>  test/LuaJIT-tests/trace/index                 |    7 +
>  test/LuaJIT-tests/trace/phi/copyspill.lua     |   53 +
>  test/LuaJIT-tests/trace/phi/index             |    3 +
>  test/LuaJIT-tests/trace/phi/ref.lua           |  131 ++
>  test/LuaJIT-tests/trace/phi/rotate.lua        |  149 +++
>  test/LuaJIT-tests/trace/snap.lua              |   47 +
>  test/LuaJIT-tests/trace/stitch.lua            |   19 +
>  .../unportable/ffi_arith_int64.lua            |   68 +
>  test/LuaJIT-tests/unportable/math_special.lua |   55 +
>  test/PUC-Lua-5.1-tests/CMakeLists.txt         |   92 ++
>  test/PUC-Lua-5.1-tests/README                 |   41 +
>  test/PUC-Lua-5.1-tests/all.lua                |  145 +++
>  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            |  432 +++++++
>  test/PUC-Lua-5.1-tests/code.lua               |  143 ++
>  test/PUC-Lua-5.1-tests/constructs.lua         |  247 ++++
>  test/PUC-Lua-5.1-tests/db.lua                 |  538 ++++++++
>  test/PUC-Lua-5.1-tests/errors.lua             |  264 ++++
>  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                 |  320 +++++
>  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               |  195 +++
>  test/PUC-Lua-5.1-tests/math.lua               |  213 +++
>  test/PUC-Lua-5.1-tests/nextvar.lua            |  403 ++++++
>  test/PUC-Lua-5.1-tests/pm.lua                 |  281 ++++
>  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 ++
>  test/lua-Harness-tests/000-sanity.t           |   54 +
>  test/lua-Harness-tests/001-if.t               |   88 ++
>  test/lua-Harness-tests/002-table.t            |   67 +
>  test/lua-Harness-tests/011-while.t            |   89 ++
>  test/lua-Harness-tests/012-repeat.t           |   85 ++
>  test/lua-Harness-tests/014-fornum.t           |  151 +++
>  test/lua-Harness-tests/015-forlist.t          |  111 ++
>  test/lua-Harness-tests/090-tap.t              |   37 +
>  test/lua-Harness-tests/091-profile.t          |   45 +
>  test/lua-Harness-tests/101-boolean.t          |  127 ++
>  test/lua-Harness-tests/102-function.t         |  206 +++
>  test/lua-Harness-tests/103-nil.t              |  127 ++
>  test/lua-Harness-tests/104-number.t           |  246 ++++
>  test/lua-Harness-tests/105-string.t           |  277 ++++
>  test/lua-Harness-tests/106-table.t            |  135 ++
>  test/lua-Harness-tests/107-thread.t           |  135 ++
>  test/lua-Harness-tests/108-userdata.t         |  132 ++
>  test/lua-Harness-tests/200-examples.t         |  104 ++
>  test/lua-Harness-tests/201-assign.t           |  150 +++
>  test/lua-Harness-tests/202-expr.t             |  157 +++
>  test/lua-Harness-tests/203-lexico.t           |  147 +++
>  test/lua-Harness-tests/204-grammar.t          |  233 ++++
>  test/lua-Harness-tests/211-scope.t            |   86 ++
>  test/lua-Harness-tests/212-function.t         |  288 +++++
>  test/lua-Harness-tests/213-closure.t          |   98 ++
>  test/lua-Harness-tests/214-coroutine.t        |  244 ++++
>  test/lua-Harness-tests/221-table.t            |  120 ++
>  test/lua-Harness-tests/222-constructor.t      |  119 ++
>  test/lua-Harness-tests/223-iterator.t         |  203 +++
>  test/lua-Harness-tests/231-metatable.t        |  602 +++++++++
>  test/lua-Harness-tests/232-object.t           |  314 +++++
>  .../241-standalone.t.disabled                 |  269 ++++
>  test/lua-Harness-tests/242-luac.t             |  341 +++++
>  test/lua-Harness-tests/301-basic.t            |  859 ++++++++++++
>  test/lua-Harness-tests/303-package.t          |  290 +++++
>  test/lua-Harness-tests/304-string.t           |  633 +++++++++
>  test/lua-Harness-tests/305-utf8.t.disabled    |   55 +
>  test/lua-Harness-tests/306-table.t            |  372 ++++++
>  test/lua-Harness-tests/307-math.t             |  375 ++++++
>  test/lua-Harness-tests/308-io.t               |  397 ++++++
>  test/lua-Harness-tests/309-os.t               |  275 ++++
>  test/lua-Harness-tests/310-debug.t            |  322 +++++
>  test/lua-Harness-tests/311-bit32.t            |  127 ++
>  test/lua-Harness-tests/314-regex.t            |  222 ++++
>  test/lua-Harness-tests/320-stdin.t            |  133 ++
>  test/lua-Harness-tests/401-bitop.t            |  106 ++
>  test/lua-Harness-tests/402-ffi.t              |  142 ++
>  test/lua-Harness-tests/403-jit.t              |  163 +++
>  test/lua-Harness-tests/404-ext.t              |  171 +++
>  test/lua-Harness-tests/411-luajit.t.disabled  |  211 +++
>  test/lua-Harness-tests/CMakeLists.txt         |   62 +
>  test/lua-Harness-tests/lexico52/lexico.t      |   45 +
>  test/lua-Harness-tests/lexico53/boolean.t     |   43 +
>  test/lua-Harness-tests/lexico53/function.t    |   66 +
>  test/lua-Harness-tests/lexico53/lexico.t      |   30 +
>  test/lua-Harness-tests/lexico53/nil.t         |   43 +
>  test/lua-Harness-tests/lexico53/number.t      |  181 +++
>  test/lua-Harness-tests/lexico53/string.t      |  169 +++
>  test/lua-Harness-tests/lexico53/table.t       |   43 +
>  test/lua-Harness-tests/lexico53/thread.t      |   45 +
>  test/lua-Harness-tests/lexico53/userdata.t    |   45 +
>  test/lua-Harness-tests/lexico53/utf8.t        |  179 +++
>  test/lua-Harness-tests/lexico54/lexico.t      |   19 +
>  test/lua-Harness-tests/lexico54/metatable.t   |   38 +
>  test/lua-Harness-tests/lexico54/utf8.t        |   54 +
>  test/lua-Harness-tests/lexicojit/basic.t      |   27 +
>  test/lua-Harness-tests/lexicojit/ext.t        |   52 +
>  test/lua-Harness-tests/lexicojit/lexico.t     |   32 +
>  test/lua-Harness-tests/profile.lua            |   53 +
>  test/lua-Harness-tests/profile_lua51.lua      |   46 +
>  .../profile_lua51_strict.lua                  |   46 +
>  test/lua-Harness-tests/profile_lua52.lua      |   46 +
>  .../profile_lua52_strict.lua                  |   46 +
>  test/lua-Harness-tests/profile_lua53.lua      |   52 +
>  .../profile_lua53_noconv.lua                  |   55 +
>  .../profile_lua53_strict.lua                  |   52 +
>  test/lua-Harness-tests/profile_lua54.lua      |   52 +
>  .../profile_lua54_noconv.lua                  |   55 +
>  .../profile_lua54_strict.lua                  |   53 +
>  test/lua-Harness-tests/profile_luajit20.lua   |   53 +
>  .../profile_luajit20_compat52.lua             |   53 +
>  test/lua-Harness-tests/profile_luajit21.lua   |   53 +
>  .../profile_luajit21_compat52.lua             |   53 +
>  test/lua-Harness-tests/profile_openresty.lua  |   53 +
>  test/lua-Harness-tests/profile_ravi.lua       |   58 +
>  test/lua-Harness-tests/profile_tiny_fork.lua  |   60 +
>  test/lua-Harness-tests/rx_captures            |   13 +
>  test/lua-Harness-tests/rx_charclass           |   38 +
>  test/lua-Harness-tests/rx_metachars           |  117 ++
>  test/lua-Harness-tests/tap_harness.lua        |  204 +++
>  322 files changed, 34168 insertions(+), 2 deletions(-)
>  create mode 100644 test/LuaJIT-tests/CMakeLists.txt
>  create mode 100644 test/LuaJIT-tests/README.md
>  create mode 100644 test/LuaJIT-tests/bc/constov.lua
>  create mode 100644 test/LuaJIT-tests/bc/index
>  create mode 100644 test/LuaJIT-tests/common/expect_error.lua
>  create mode 100644 test/LuaJIT-tests/common/ffi_util.inc
>  create mode 100644 test/LuaJIT-tests/common/test_runner_canary.lua
>  create mode 100644 test/LuaJIT-tests/computations.lua
>  create mode 100644 test/LuaJIT-tests/index
>  create mode 100644 test/LuaJIT-tests/lang/andor.lua
>  create mode 100644 test/LuaJIT-tests/lang/assignment.lua
>  create mode 100644 test/LuaJIT-tests/lang/compare.lua
>  create mode 100644 test/LuaJIT-tests/lang/compare_nan.lua
>  create mode 100644 test/LuaJIT-tests/lang/concat.lua
>  create mode 100644 test/LuaJIT-tests/lang/constant/index
>  create mode 100644 test/LuaJIT-tests/lang/constant/number.lua
>  create mode 100644 test/LuaJIT-tests/lang/constant/table.lua
>  create mode 100644 test/LuaJIT-tests/lang/coroutine.lua
>  create mode 100644 test/LuaJIT-tests/lang/for.lua
>  create mode 100644 test/LuaJIT-tests/lang/gc.lua
>  create mode 100644 test/LuaJIT-tests/lang/goto.lua
>  create mode 100644 test/LuaJIT-tests/lang/index
>  create mode 100644 test/LuaJIT-tests/lang/length.lua
>  create mode 100644 test/LuaJIT-tests/lang/meta/arith.lua
>  create mode 100644 test/LuaJIT-tests/lang/meta/arith_jit.lua
>  create mode 100644 test/LuaJIT-tests/lang/meta/call.lua
>  create mode 100644 test/LuaJIT-tests/lang/meta/cat.lua
>  create mode 100644 test/LuaJIT-tests/lang/meta/comp.lua
>  create mode 100644 test/LuaJIT-tests/lang/meta/comp_jit.lua
>  create mode 100644 test/LuaJIT-tests/lang/meta/debuginfo.lua
>  create mode 100644 test/LuaJIT-tests/lang/meta/eq.lua
>  create mode 100644 test/LuaJIT-tests/lang/meta/eq_jit.lua
>  create mode 100644 test/LuaJIT-tests/lang/meta/framegap.lua
>  create mode 100644 test/LuaJIT-tests/lang/meta/index
>  create mode 100644 test/LuaJIT-tests/lang/meta/index.lua
>  create mode 100644 test/LuaJIT-tests/lang/meta/len.lua
>  create mode 100644 test/LuaJIT-tests/lang/meta/newindex.lua
>  create mode 100644 test/LuaJIT-tests/lang/meta/nomm.lua
>  create mode 100644 test/LuaJIT-tests/lang/modulo.lua
>  create mode 100644 test/LuaJIT-tests/lang/self.lua
>  create mode 100644 test/LuaJIT-tests/lang/table.lua
>  create mode 100644 test/LuaJIT-tests/lang/tail_recursion.lua
>  create mode 100644 test/LuaJIT-tests/lang/upvalue/closure.lua
>  create mode 100644 test/LuaJIT-tests/lang/upvalue/index
>  create mode 100644 test/LuaJIT-tests/lang/vararg_jit.lua
>  create mode 100644 test/LuaJIT-tests/lib/base/assert.lua
>  create mode 100644 test/LuaJIT-tests/lib/base/error.lua
>  create mode 100644 test/LuaJIT-tests/lib/base/getfenv.lua
>  create mode 100644 test/LuaJIT-tests/lib/base/getsetmetatable.lua
>  create mode 100644 test/LuaJIT-tests/lib/base/index
>  create mode 100644 test/LuaJIT-tests/lib/base/ipairs.lua
>  create mode 100644 test/LuaJIT-tests/lib/base/next.lua
>  create mode 100644 test/LuaJIT-tests/lib/base/pairs.lua
>  create mode 100644 test/LuaJIT-tests/lib/base/pcall_jit.lua
>  create mode 100644 test/LuaJIT-tests/lib/base/select.lua
>  create mode 100644 test/LuaJIT-tests/lib/base/tonumber_tostring.lua
>  create mode 100644 test/LuaJIT-tests/lib/base/xpcall_jit.lua
>  create mode 100644 test/LuaJIT-tests/lib/bit.lua
>  create mode 100644 test/LuaJIT-tests/lib/contents.lua
>  create mode 100644 test/LuaJIT-tests/lib/coroutine/index
>  create mode 100644 test/LuaJIT-tests/lib/coroutine/yield.lua
>  create mode 100644 test/LuaJIT-tests/lib/ffi/bit64.lua
>  create mode 100644 test/LuaJIT-tests/lib/ffi/cdata_var.lua
>  create mode 100644 test/LuaJIT-tests/lib/ffi/copy_fill.lua
>  create mode 100644 test/LuaJIT-tests/lib/ffi/err.lua
>  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_arith_ptr.lua
>  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_bitfield.lua
>  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_call.lua
>  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_callback.lua
>  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_const.lua
>  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_convert.lua
>  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_enum.lua
>  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_gcstep_recursive.lua
>  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_jit_arith.lua
>  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_jit_call.lua
>  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_jit_conv.lua
>  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_lex_number.lua
>  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_metatype.lua
>  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_new.lua
>  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_parse_array.lua
>  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_parse_basic.lua
>  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_parse_cdef.lua
>  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_parse_struct.lua
>  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_tabov.lua
>  create mode 100644 test/LuaJIT-tests/lib/ffi/index
>  create mode 100644 test/LuaJIT-tests/lib/ffi/istype.lua
>  create mode 100644 test/LuaJIT-tests/lib/ffi/jit_array.lua
>  create mode 100644 test/LuaJIT-tests/lib/ffi/jit_complex.lua
>  create mode 100644 test/LuaJIT-tests/lib/ffi/jit_misc.lua
>  create mode 100644 test/LuaJIT-tests/lib/ffi/jit_struct.lua
>  create mode 100644 test/LuaJIT-tests/lib/ffi/meta_tostring.lua
>  create mode 100644 test/LuaJIT-tests/lib/ffi/redir.lua
>  create mode 100644 test/LuaJIT-tests/lib/ffi/type_punning.lua
>  create mode 100644 test/LuaJIT-tests/lib/index
>  create mode 100644 test/LuaJIT-tests/lib/math/abs.lua
>  create mode 100644 test/LuaJIT-tests/lib/math/constants.lua
>  create mode 100644 test/LuaJIT-tests/lib/math/index
>  create mode 100644 test/LuaJIT-tests/lib/math/random.lua
>  create mode 100644 test/LuaJIT-tests/lib/string/byte.lua
>  create mode 100644 test/LuaJIT-tests/lib/string/char.lua
>  create mode 100644 test/LuaJIT-tests/lib/string/dump.lua
>  create mode 100644 test/LuaJIT-tests/lib/string/format/index
>  create mode 100644 test/LuaJIT-tests/lib/string/format/num.lua
>  create mode 100644 test/LuaJIT-tests/lib/string/index
>  create mode 100644 test/LuaJIT-tests/lib/string/len.lua
>  create mode 100644 test/LuaJIT-tests/lib/string/lower_upper.lua
>  create mode 100644 test/LuaJIT-tests/lib/string/metatable.lua
>  create mode 100644 test/LuaJIT-tests/lib/string/multiple_functions.lua
>  create mode 100644 test/LuaJIT-tests/lib/string/rep.lua
>  create mode 100644 test/LuaJIT-tests/lib/string/reverse.lua
>  create mode 100644 test/LuaJIT-tests/lib/string/sub.lua
>  create mode 100644 test/LuaJIT-tests/lib/table/concat.lua
>  create mode 100644 test/LuaJIT-tests/lib/table/index
>  create mode 100644 test/LuaJIT-tests/lib/table/insert.lua
>  create mode 100644 test/LuaJIT-tests/lib/table/misc.lua
>  create mode 100644 test/LuaJIT-tests/lib/table/new.lua
>  create mode 100644 test/LuaJIT-tests/lib/table/pack.lua
>  create mode 100644 test/LuaJIT-tests/lib/table/remove.lua
>  create mode 100644 test/LuaJIT-tests/lib/table/sort.lua
>  create mode 100644 test/LuaJIT-tests/misc/alias_alloc.lua
>  create mode 100644 test/LuaJIT-tests/misc/api_call.lua
>  create mode 100644 test/LuaJIT-tests/misc/catch_wrap.lua
>  create mode 100644 test/LuaJIT-tests/misc/coro_traceback.lua
>  create mode 100644 test/LuaJIT-tests/misc/coro_yield.lua
>  create mode 100644 test/LuaJIT-tests/misc/debug_gc.lua
>  create mode 100644 test/LuaJIT-tests/misc/dualnum.lua
>  create mode 100644 test/LuaJIT-tests/misc/for_dir.lua
>  create mode 100644 test/LuaJIT-tests/misc/fori_coerce.lua
>  create mode 100644 test/LuaJIT-tests/misc/gc_rechain.lua
>  create mode 100644 test/LuaJIT-tests/misc/gc_trace.lua
>  create mode 100644 test/LuaJIT-tests/misc/gcstep.lua
>  create mode 100644 test/LuaJIT-tests/misc/hook_active.lua
>  create mode 100644 test/LuaJIT-tests/misc/hook_line.lua
>  create mode 100644 test/LuaJIT-tests/misc/hook_norecord.lua
>  create mode 100644 test/LuaJIT-tests/misc/hook_record.lua
>  create mode 100644 test/LuaJIT-tests/misc/hook_top.lua
>  create mode 100644 test/LuaJIT-tests/misc/jit_flush.lua
>  create mode 100644 test/LuaJIT-tests/misc/lightud.lua
>  create mode 100644 test/LuaJIT-tests/misc/loop_unroll.lua
>  create mode 100644 test/LuaJIT-tests/misc/parse_comp.lua
>  create mode 100644 test/LuaJIT-tests/misc/parse_esc.lua
>  create mode 100644 test/LuaJIT-tests/misc/parse_misc.lua
>  create mode 100644 test/LuaJIT-tests/misc/phi_conv.lua
>  create mode 100644 test/LuaJIT-tests/misc/recurse_deep.lua
>  create mode 100644 test/LuaJIT-tests/misc/recurse_tail.lua
>  create mode 100644 test/LuaJIT-tests/misc/stack_gc.lua
>  create mode 100644 test/LuaJIT-tests/misc/stack_purge.lua
>  create mode 100644 test/LuaJIT-tests/misc/stackov.lua
>  create mode 100644 test/LuaJIT-tests/misc/stackovc.lua
>  create mode 100644 test/LuaJIT-tests/misc/tcall_base.lua
>  create mode 100644 test/LuaJIT-tests/misc/tcall_loop.lua
>  create mode 100644 test/LuaJIT-tests/misc/tonumber_scan.lua
>  create mode 100644 test/LuaJIT-tests/misc/uclo.lua
>  create mode 100644 test/LuaJIT-tests/misc/unordered_jit.lua
>  create mode 100644 test/LuaJIT-tests/misc/wbarrier.lua
>  create mode 100644 test/LuaJIT-tests/misc/wbarrier_jit.lua
>  create mode 100644 test/LuaJIT-tests/misc/wbarrier_obar.lua
>  create mode 100644 test/LuaJIT-tests/opt/dse/array.lua
>  create mode 100644 test/LuaJIT-tests/opt/dse/field.lua
>  create mode 100644 test/LuaJIT-tests/opt/dse/index
>  create mode 100644 test/LuaJIT-tests/opt/fold/index
>  create mode 100644 test/LuaJIT-tests/opt/fold/kfold.lua
>  create mode 100644 test/LuaJIT-tests/opt/fuse.lua
>  create mode 100644 test/LuaJIT-tests/opt/fwd/hrefk_rollback.lua
>  create mode 100644 test/LuaJIT-tests/opt/fwd/index
>  create mode 100644 test/LuaJIT-tests/opt/fwd/tnew_tdup.lua
>  create mode 100644 test/LuaJIT-tests/opt/fwd/upval.lua
>  create mode 100644 test/LuaJIT-tests/opt/index
>  create mode 100644 test/LuaJIT-tests/opt/loop/index
>  create mode 100644 test/LuaJIT-tests/opt/loop/unroll.lua
>  create mode 100644 test/LuaJIT-tests/opt/sink/alloc.lua
>  create mode 100644 test/LuaJIT-tests/opt/sink/ffi.lua
>  create mode 100644 test/LuaJIT-tests/opt/sink/ffi_nosink.lua
>  create mode 100644 test/LuaJIT-tests/opt/sink/index
>  create mode 100644 test/LuaJIT-tests/opt/sink/nosink.lua
>  create mode 100644 test/LuaJIT-tests/src/cpptest.cpp
>  create mode 100644 test/LuaJIT-tests/src/ctest.c
>  create mode 100644 test/LuaJIT-tests/sysdep/catch_cpp.lua
>  create mode 100644 test/LuaJIT-tests/sysdep/ffi_include_gtk.lua
>  create mode 100644 test/LuaJIT-tests/sysdep/ffi_include_std.lua
>  create mode 100644 test/LuaJIT-tests/sysdep/ffi_lib_c.lua
>  create mode 100644 test/LuaJIT-tests/sysdep/ffi_lib_z.lua
>  create mode 100644 test/LuaJIT-tests/test.lua
>  create mode 100644 test/LuaJIT-tests/trace/exit_frame.lua
>  create mode 100644 test/LuaJIT-tests/trace/exit_growstack.lua
>  create mode 100644 test/LuaJIT-tests/trace/exit_jfuncf.lua
>  create mode 100644 test/LuaJIT-tests/trace/gc64_slot_revival.lua
>  create mode 100644 test/LuaJIT-tests/trace/index
>  create mode 100644 test/LuaJIT-tests/trace/phi/copyspill.lua
>  create mode 100644 test/LuaJIT-tests/trace/phi/index
>  create mode 100644 test/LuaJIT-tests/trace/phi/ref.lua
>  create mode 100644 test/LuaJIT-tests/trace/phi/rotate.lua
>  create mode 100644 test/LuaJIT-tests/trace/snap.lua
>  create mode 100644 test/LuaJIT-tests/trace/stitch.lua
>  create mode 100644 test/LuaJIT-tests/unportable/ffi_arith_int64.lua
>  create mode 100644 test/LuaJIT-tests/unportable/math_special.lua
>  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/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
>  create mode 100755 test/lua-Harness-tests/000-sanity.t
>  create mode 100755 test/lua-Harness-tests/001-if.t
>  create mode 100755 test/lua-Harness-tests/002-table.t
>  create mode 100755 test/lua-Harness-tests/011-while.t
>  create mode 100755 test/lua-Harness-tests/012-repeat.t
>  create mode 100755 test/lua-Harness-tests/014-fornum.t
>  create mode 100755 test/lua-Harness-tests/015-forlist.t
>  create mode 100755 test/lua-Harness-tests/090-tap.t
>  create mode 100755 test/lua-Harness-tests/091-profile.t
>  create mode 100755 test/lua-Harness-tests/101-boolean.t
>  create mode 100755 test/lua-Harness-tests/102-function.t
>  create mode 100755 test/lua-Harness-tests/103-nil.t
>  create mode 100755 test/lua-Harness-tests/104-number.t
>  create mode 100755 test/lua-Harness-tests/105-string.t
>  create mode 100755 test/lua-Harness-tests/106-table.t
>  create mode 100755 test/lua-Harness-tests/107-thread.t
>  create mode 100755 test/lua-Harness-tests/108-userdata.t
>  create mode 100755 test/lua-Harness-tests/200-examples.t
>  create mode 100755 test/lua-Harness-tests/201-assign.t
>  create mode 100755 test/lua-Harness-tests/202-expr.t
>  create mode 100755 test/lua-Harness-tests/203-lexico.t
>  create mode 100755 test/lua-Harness-tests/204-grammar.t
>  create mode 100755 test/lua-Harness-tests/211-scope.t
>  create mode 100755 test/lua-Harness-tests/212-function.t
>  create mode 100755 test/lua-Harness-tests/213-closure.t
>  create mode 100755 test/lua-Harness-tests/214-coroutine.t
>  create mode 100755 test/lua-Harness-tests/221-table.t
>  create mode 100755 test/lua-Harness-tests/222-constructor.t
>  create mode 100755 test/lua-Harness-tests/223-iterator.t
>  create mode 100755 test/lua-Harness-tests/231-metatable.t
>  create mode 100755 test/lua-Harness-tests/232-object.t
>  create mode 100755 test/lua-Harness-tests/241-standalone.t.disabled
>  create mode 100755 test/lua-Harness-tests/242-luac.t
>  create mode 100755 test/lua-Harness-tests/301-basic.t
>  create mode 100755 test/lua-Harness-tests/303-package.t
>  create mode 100755 test/lua-Harness-tests/304-string.t
>  create mode 100755 test/lua-Harness-tests/305-utf8.t.disabled
>  create mode 100755 test/lua-Harness-tests/306-table.t
>  create mode 100755 test/lua-Harness-tests/307-math.t
>  create mode 100755 test/lua-Harness-tests/308-io.t
>  create mode 100755 test/lua-Harness-tests/309-os.t
>  create mode 100755 test/lua-Harness-tests/310-debug.t
>  create mode 100755 test/lua-Harness-tests/311-bit32.t
>  create mode 100755 test/lua-Harness-tests/314-regex.t
>  create mode 100755 test/lua-Harness-tests/320-stdin.t
>  create mode 100755 test/lua-Harness-tests/401-bitop.t
>  create mode 100755 test/lua-Harness-tests/402-ffi.t
>  create mode 100755 test/lua-Harness-tests/403-jit.t
>  create mode 100755 test/lua-Harness-tests/404-ext.t
>  create mode 100755 test/lua-Harness-tests/411-luajit.t.disabled
>  create mode 100644 test/lua-Harness-tests/CMakeLists.txt
>  create mode 100644 test/lua-Harness-tests/lexico52/lexico.t
>  create mode 100644 test/lua-Harness-tests/lexico53/boolean.t
>  create mode 100644 test/lua-Harness-tests/lexico53/function.t
>  create mode 100644 test/lua-Harness-tests/lexico53/lexico.t
>  create mode 100644 test/lua-Harness-tests/lexico53/nil.t
>  create mode 100644 test/lua-Harness-tests/lexico53/number.t
>  create mode 100644 test/lua-Harness-tests/lexico53/string.t
>  create mode 100644 test/lua-Harness-tests/lexico53/table.t
>  create mode 100644 test/lua-Harness-tests/lexico53/thread.t
>  create mode 100644 test/lua-Harness-tests/lexico53/userdata.t
>  create mode 100644 test/lua-Harness-tests/lexico53/utf8.t
>  create mode 100644 test/lua-Harness-tests/lexico54/lexico.t
>  create mode 100644 test/lua-Harness-tests/lexico54/metatable.t
>  create mode 100644 test/lua-Harness-tests/lexico54/utf8.t
>  create mode 100644 test/lua-Harness-tests/lexicojit/basic.t
>  create mode 100644 test/lua-Harness-tests/lexicojit/ext.t
>  create mode 100644 test/lua-Harness-tests/lexicojit/lexico.t
>  create mode 100644 test/lua-Harness-tests/profile.lua
>  create mode 100644 test/lua-Harness-tests/profile_lua51.lua
>  create mode 100644 test/lua-Harness-tests/profile_lua51_strict.lua
>  create mode 100644 test/lua-Harness-tests/profile_lua52.lua
>  create mode 100644 test/lua-Harness-tests/profile_lua52_strict.lua
>  create mode 100644 test/lua-Harness-tests/profile_lua53.lua
>  create mode 100644 test/lua-Harness-tests/profile_lua53_noconv.lua
>  create mode 100644 test/lua-Harness-tests/profile_lua53_strict.lua
>  create mode 100644 test/lua-Harness-tests/profile_lua54.lua
>  create mode 100644 test/lua-Harness-tests/profile_lua54_noconv.lua
>  create mode 100644 test/lua-Harness-tests/profile_lua54_strict.lua
>  create mode 100644 test/lua-Harness-tests/profile_luajit20.lua
>  create mode 100644 test/lua-Harness-tests/profile_luajit20_compat52.lua
>  create mode 100644 test/lua-Harness-tests/profile_luajit21.lua
>  create mode 100644 test/lua-Harness-tests/profile_luajit21_compat52.lua
>  create mode 100644 test/lua-Harness-tests/profile_openresty.lua
>  create mode 100644 test/lua-Harness-tests/profile_ravi.lua
>  create mode 100644 test/lua-Harness-tests/profile_tiny_fork.lua
>  create mode 100644 test/lua-Harness-tests/rx_captures
>  create mode 100644 test/lua-Harness-tests/rx_charclass
>  create mode 100644 test/lua-Harness-tests/rx_metachars
>  create mode 100644 test/lua-Harness-tests/tap_harness.lua
> 
> -- 
> 2.28.0
> 
> [0]: https://github.com/tarantool/tarantool/runs/2029452344
> [1]: https://github.com/google/sanitizers/issues/980
> [2]: https://github.com/google/sanitizers/issues/189
> [3]: https://github.com/google/sanitizers/wiki/AddressSanitizerFlags

[1]: https://github.com/tarantool/luajit/tree/imun/tarantool-test
[2]: https://github.com/tarantool/tarantool/tree/imun/luajit-test
[3]: https://github.com/tarantool/luajit/commit/9712cc9#diff-1e7de1ae2d059d21e1dd75d5812d5a34b0222cef273b7c3a2af62eb747f9d20aR291-R307
[4]: https://github.com/tarantool/tarantool/commit/03b04a7
[5]: https://github.com/tarantool/luajit/commit/72f87b2

-- 
Best regards,
IM

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

* Re: [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites
  2021-03-09 23:59 ` Igor Munkin via Tarantool-patches
@ 2021-03-10  8:09   ` Sergey Kaplun via Tarantool-patches
  2021-03-10 10:39     ` Igor Munkin via Tarantool-patches
  2021-03-10  9:46   ` Sergey Ostanevich via Tarantool-patches
  2021-03-10 16:25   ` Igor Munkin via Tarantool-patches
  2 siblings, 1 reply; 26+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-03-10  8:09 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Igor,

On 10.03.21, Igor Munkin wrote:
> Sergey,
> 
> I've precisely reviewed patches 04-09 and they look good. I've polished
> a bit[1] the series, so it can be applied to the trunk out of the order.
> CI[2] is green.

I hardly wait for the other series.
I've assembled all issues related to PUC-Rio-Lua-5.1 test suite inside
this [1] epic.

> 
> BTW, I would like to leave some major points related to my review.
> 

<snipped>

> 2. I've introduced a new CMake option: LUAJIT_TEST_INIT. You can read
> the description here[3]. It allows to enclose the partial LUA_INIT
> emulation, implemented via '-e dofile[[${LUAJIT_TEST_INIT}]]' and
> obliges user to set the name of the Lua script to be run prior to the
> testing suite[4]. By default it does nothing by reading from /dev/null.

This part is good. Why do you omit +slow flag for this test suite?

> 
> 3. Since CLI flags can be used for LuaJIT testing now, <utils.selfrun>
> need to be adjusted[5] to respect the passed flags in child process.
> 
> This part LGTM, so if nobody is against the version I've checked to the
> branch[1], then I apply it to the trunk after your and Sergos approval.

As I see on the branch there is no check of CMAKE_BUILD_TYPE variable.
We need to disable strict only for debug build, IINM.
Feel free to ignore.

Otherwise, LGTM.

> 
> On 04.03.21, Sergey Kaplun wrote:
> > WARNING: This patch doesn't require full and precise review now.
> > 
> > This draft should be structured (commits at least) from test
> > suite to test suite if necessary.
> > 
> > You can complain test suites with the following command, for example:
> > | $ diff --color -urZ test/PUC-Lua-5.1-tests/ ~/Downloads/lua5.1-tests/
> > 
> > Branch: https://github.com/tarantool/luajit/tree/skaplun/gh-4473-adopt-luavela-test-suites
> > Tarantool's branch: https://github.com/tarantool/tarantool/tree/skaplun/gh-4473-adopt-luavela-test-suites
> > Epic: https://github.com/tarantool/tarantool/issues/4473
> > Issues:
> > * https://github.com/tarantool/tarantool/issues/5845
> > * https://github.com/tarantool/tarantool/issues/4064
> > * https://github.com/tarantool/tarantool/issues/5844
> > 
> > CI is red due to ASan failure [0] for PUC-Lua-5.1 test suite.
> > Looks related to https://github.com/tarantool/tarantool/issues/5747,
> > but it is hard to tell without backtrace.
> > 
> > Locally, I get tons of errors like this for each of newly added test
> > suites:
> > | ==31930==WARNING: ASan is ignoring requested __asan_handle_no_return: stack top: 0x7fffbb603000; bottom 0x7f4e271fd000; size: 0x00b194406000 (762696458240)
> > | False positive error reports may follow
> > | For details see https://github.com/google/sanitizers/issues/189
> > 
> > After that there are failures like:
> > 
> > | ==24658==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7f6b741fefa8 at pc 0x000000c91926 bp 0x7f6b741fec90 sp 0x7f6b741fec88
> > | READ of size 8 at 0x7f6b741fefa8 thread T0
> > |     #0 0xc91925 in lj_strfmt_pushvf /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_strfmt.c:438:23
> > |     #1 0xc6f8fe in lj_err_lex /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_err.c:651:9
> > |     #2 0xce0fa1 in lj_lex_error /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_lex.c:495:3
> > |     #3 0xce3285 in err_token /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_parse.c:175:3
> > |     #4 0xcf27bc in parse_stmt /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_parse.c
> > |     #5 0xce3ceb in parse_chunk /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_parse.c:2684:14
> > |     #6 0xce3ceb in lj_parse /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_parse.c:2717:3
> > |     #7 0xc7eeaa in cpparser /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_load.c:41:29
> > |     #8 0xd8a6b7 in lj_vm_cpcall /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/build/third_party/luajit/src/lj_vm.S:1191
> > |     #9 0xc7fed6 in lua_loadx /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_load.c:58:12
> > |     #10 0xc7fed6 in luaL_loadbufferx /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_load.c:143:10
> > |     #11 0xca9b12 in lj_cf_load /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lib_base.c:401:14
> > |     #12 0xd8a2fa in lj_BC_FUNCC /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/build/third_party/luajit/src/lj_vm.S:811
> > |     #13 0xc5be1f in lua_pcall /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_api.c:1158:12
> > |     #14 0xb2ad71 in luaT_call /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/src/lua/utils.c:1022:6
> > |     #15 0xb1532c in lua_main /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/src/lua/init.c:559:11
> > |     #16 0xb14c9a in run_script_f /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/src/lua/init.c:634:7
> > |     #17 0x526d96 in fiber_cxx_invoke(int (*)(__va_list_tag*), __va_list_tag*) /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/src/lib/core/fiber.h:882:10
> > |     #18 0xb7f688 in fiber_loop /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/src/lib/core/fiber.c:879:18
> > |     #19 0x14b3b10 in coro_init /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/coro/coro.c:110:3
> > |
> > | Address 0x7f6b741fefa8 is a wild pointer.
> > | SUMMARY: AddressSanitizer: stack-buffer-overflow /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_strfmt.c:438:23 in lj_strfmt_pushvf
> > | Shadow bytes around the buggy address:
> > |   0x0fedee837da0: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
> > |   0x0fedee837db0: 00 00 00 f3 f3 f3 f3 f3 00 00 00 00 00 00 00 00
> > |   0x0fedee837dc0: f1 f1 f1 f1 00 00 00 00 00 00 00 04 f3 f3 f3 f3
> > |   0x0fedee837dd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> > |   0x0fedee837de0: f1 f1 f1 f1 00 00 00 f3 f3 f3 f3 f3 f2 f2 f2 f2
> > | =>0x0fedee837df0: f8 f8 f8 f8 f3[f3]f3 f3 00 00 00 00 00 00 00 00
> > |   0x0fedee837e00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> > |   0x0fedee837e10: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 f8 f8 f8 f2
> > |   0x0fedee837e20: f2 f2 f2 f2 f8 f8 f8 f2 f2 f2 f2 f2 f8 f8 f8 f8
> > |   0x0fedee837e30: f2 f2 f2 f2 f8 f8 f8 f2 f2 f2 f2 f2 f8 f8 f8 f2
> > |   0x0fedee837e40: f2 f2 f2 f2 f8 f8 f8 f2 f2 f2 f2 f2 f8 f8 f8 f2
> > | Shadow byte legend (one shadow byte represents 8 application bytes):
> > |   Addressable:           00
> > |   Partially addressable: 01 02 03 04 05 06 07 
> > |   Heap left redzone:       fa
> > |   Freed heap region:       fd
> > |   Stack left redzone:      f1
> > |   Stack mid redzone:       f2
> > |   Stack right redzone:     f3
> > |   Stack after return:      f5
> > |   Stack use after scope:   f8
> > 
> > It can be simply reproduce locally with:
> > | $ ASAN=ON LSAN_OPTIONS=suppressions=asan/lsan.supp ASAN_OPTIONS=heap_profile=0:unmap_shadow_on_exit=1:detect_invalid_pointer_pairs=1:symbolize=1:detect_leaks=1:dump_instruction_bytes=1:print_suppressions=0:asan_stack=0 src/tarantool -e 'prog = [[ do]] for _=1,3 do pcall(loadstring(string.sub(prog, 1, _))) end'
> > 
> > It may be the reason of failures too, see [1][2].
> > 
> > According to [3], there is no any way except to compile with -asan-stack
> > flag, but it looks like overkill. So I propose to exclude PUC-Lua-5.1
> > test suite from ASan job for now (at least this is out of scoupe of the
> > original issue).
> > 
> > Mergen Imeev (8):
> >   test: add LuaJIT-test-cleanup test suite
> >   test: change tests to match de5568e
> >   test: change tests to match c198167
> >   test: change tests to match 5a61e1a
> >   test: change LuaJIT suite tests to match b4e6bf0
> >   test: adjust LuaJIT test suite for Tarantool
> >   test: add lua-Harness test suite
> >   test: adjust lua-Harness test suite for Tarantool
> > 
> > Sergey Kaplun (7):
> >   test: add PUC-Rio Lua 5.1 test suite
> >   test: adapt PUC-Rio Lua 5.1 test suite for LuaJIT
> >   test: adapt Lua 5.1 test suite for Tarantool
> >   test: disable 305-utf8 of lua-Harness suite
> >   test: disable 241-standalone of lua-Harness suite
> >   test: disable 411-luajit of lua-Harness suite
> >   test: skip test for getenv in 309-os.t
> > 
> >  .gitignore                                    |    1 +
> >  .luacheckrc                                   |    7 +-
> >  CMakeLists.txt                                |    8 +
> >  test/CMakeLists.txt                           |    6 +
> >  test/LuaJIT-tests/CMakeLists.txt              |   20 +
> >  test/LuaJIT-tests/README.md                   |  110 ++
> >  test/LuaJIT-tests/bc/constov.lua              |   16 +
> >  test/LuaJIT-tests/bc/index                    |    1 +
> >  test/LuaJIT-tests/common/expect_error.lua     |   16 +
> >  test/LuaJIT-tests/common/ffi_util.inc         |   41 +
> >  .../common/test_runner_canary.lua             |    1 +
> >  test/LuaJIT-tests/computations.lua            |  113 ++
> >  test/LuaJIT-tests/index                       |    6 +
> >  test/LuaJIT-tests/lang/andor.lua              |   61 +
> >  test/LuaJIT-tests/lang/assignment.lua         |   46 +
> >  test/LuaJIT-tests/lang/compare.lua            |  323 +++++
> >  test/LuaJIT-tests/lang/compare_nan.lua        |   99 ++
> >  test/LuaJIT-tests/lang/concat.lua             |  112 ++
> >  test/LuaJIT-tests/lang/constant/index         |    2 +
> >  test/LuaJIT-tests/lang/constant/number.lua    |   12 +
> >  test/LuaJIT-tests/lang/constant/table.lua     |   15 +
> >  test/LuaJIT-tests/lang/coroutine.lua          |    8 +
> >  test/LuaJIT-tests/lang/for.lua                |   45 +
> >  test/LuaJIT-tests/lang/gc.lua                 |   42 +
> >  test/LuaJIT-tests/lang/goto.lua               |  149 +++
> >  test/LuaJIT-tests/lang/index                  |   18 +
> >  test/LuaJIT-tests/lang/length.lua             |   23 +
> >  test/LuaJIT-tests/lang/meta/arith.lua         |  118 ++
> >  test/LuaJIT-tests/lang/meta/arith_jit.lua     |   68 +
> >  test/LuaJIT-tests/lang/meta/call.lua          |   81 ++
> >  test/LuaJIT-tests/lang/meta/cat.lua           |   61 +
> >  test/LuaJIT-tests/lang/meta/comp.lua          |  120 ++
> >  test/LuaJIT-tests/lang/meta/comp_jit.lua      |  104 ++
> >  test/LuaJIT-tests/lang/meta/debuginfo.lua     |   81 ++
> >  test/LuaJIT-tests/lang/meta/eq.lua            |   30 +
> >  test/LuaJIT-tests/lang/meta/eq_jit.lua        |   35 +
> >  test/LuaJIT-tests/lang/meta/framegap.lua      |   24 +
> >  test/LuaJIT-tests/lang/meta/index             |   14 +
> >  test/LuaJIT-tests/lang/meta/index.lua         |   60 +
> >  test/LuaJIT-tests/lang/meta/len.lua           |   42 +
> >  test/LuaJIT-tests/lang/meta/newindex.lua      |   69 +
> >  test/LuaJIT-tests/lang/meta/nomm.lua          |   21 +
> >  test/LuaJIT-tests/lang/modulo.lua             |   46 +
> >  test/LuaJIT-tests/lang/self.lua               |   19 +
> >  test/LuaJIT-tests/lang/table.lua              |   32 +
> >  test/LuaJIT-tests/lang/tail_recursion.lua     |   20 +
> >  test/LuaJIT-tests/lang/upvalue/closure.lua    |   84 ++
> >  test/LuaJIT-tests/lang/upvalue/index          |    1 +
> >  test/LuaJIT-tests/lang/vararg_jit.lua         |   95 ++
> >  test/LuaJIT-tests/lib/base/assert.lua         |   33 +
> >  test/LuaJIT-tests/lib/base/error.lua          |   43 +
> >  test/LuaJIT-tests/lib/base/getfenv.lua        |   13 +
> >  .../LuaJIT-tests/lib/base/getsetmetatable.lua |   33 +
> >  test/LuaJIT-tests/lib/base/index              |   11 +
> >  test/LuaJIT-tests/lib/base/ipairs.lua         |   41 +
> >  test/LuaJIT-tests/lib/base/next.lua           |   17 +
> >  test/LuaJIT-tests/lib/base/pairs.lua          |   73 ++
> >  test/LuaJIT-tests/lib/base/pcall_jit.lua      |   74 ++
> >  test/LuaJIT-tests/lib/base/select.lua         |  105 ++
> >  .../lib/base/tonumber_tostring.lua            |   81 ++
> >  test/LuaJIT-tests/lib/base/xpcall_jit.lua     |   83 ++
> >  test/LuaJIT-tests/lib/bit.lua                 |   98 ++
> >  test/LuaJIT-tests/lib/contents.lua            |  171 +++
> >  test/LuaJIT-tests/lib/coroutine/index         |    1 +
> >  test/LuaJIT-tests/lib/coroutine/yield.lua     |  109 ++
> >  test/LuaJIT-tests/lib/ffi/bit64.lua           |  130 ++
> >  test/LuaJIT-tests/lib/ffi/cdata_var.lua       |   47 +
> >  test/LuaJIT-tests/lib/ffi/copy_fill.lua       |   64 +
> >  test/LuaJIT-tests/lib/ffi/err.lua             |   35 +
> >  test/LuaJIT-tests/lib/ffi/ffi_arith_ptr.lua   |  106 ++
> >  test/LuaJIT-tests/lib/ffi/ffi_bitfield.lua    |  108 ++
> >  test/LuaJIT-tests/lib/ffi/ffi_call.lua        |  266 ++++
> >  test/LuaJIT-tests/lib/ffi/ffi_callback.lua    |  158 +++
> >  test/LuaJIT-tests/lib/ffi/ffi_const.lua       |  113 ++
> >  test/LuaJIT-tests/lib/ffi/ffi_convert.lua     |  787 +++++++++++
> >  test/LuaJIT-tests/lib/ffi/ffi_enum.lua        |   57 +
> >  .../lib/ffi/ffi_gcstep_recursive.lua          |   66 +
> >  test/LuaJIT-tests/lib/ffi/ffi_jit_arith.lua   |  155 +++
> >  test/LuaJIT-tests/lib/ffi/ffi_jit_call.lua    |  154 +++
> >  test/LuaJIT-tests/lib/ffi/ffi_jit_conv.lua    |  277 ++++
> >  test/LuaJIT-tests/lib/ffi/ffi_lex_number.lua  |   51 +
> >  test/LuaJIT-tests/lib/ffi/ffi_metatype.lua    |  245 ++++
> >  test/LuaJIT-tests/lib/ffi/ffi_new.lua         |  106 ++
> >  test/LuaJIT-tests/lib/ffi/ffi_parse_array.lua |   78 ++
> >  test/LuaJIT-tests/lib/ffi/ffi_parse_basic.lua |  131 ++
> >  test/LuaJIT-tests/lib/ffi/ffi_parse_cdef.lua  |   77 ++
> >  .../LuaJIT-tests/lib/ffi/ffi_parse_struct.lua |  259 ++++
> >  test/LuaJIT-tests/lib/ffi/ffi_tabov.lua       |   12 +
> >  test/LuaJIT-tests/lib/ffi/index               |   12 +
> >  test/LuaJIT-tests/lib/ffi/istype.lua          |   88 ++
> >  test/LuaJIT-tests/lib/ffi/jit_array.lua       |  104 ++
> >  test/LuaJIT-tests/lib/ffi/jit_complex.lua     |  109 ++
> >  test/LuaJIT-tests/lib/ffi/jit_misc.lua        |  109 ++
> >  test/LuaJIT-tests/lib/ffi/jit_struct.lua      |  201 +++
> >  test/LuaJIT-tests/lib/ffi/meta_tostring.lua   |   55 +
> >  test/LuaJIT-tests/lib/ffi/redir.lua           |   19 +
> >  test/LuaJIT-tests/lib/ffi/type_punning.lua    |  138 ++
> >  test/LuaJIT-tests/lib/index                   |    8 +
> >  test/LuaJIT-tests/lib/math/abs.lua            |   16 +
> >  test/LuaJIT-tests/lib/math/constants.lua      |    8 +
> >  test/LuaJIT-tests/lib/math/index              |    3 +
> >  test/LuaJIT-tests/lib/math/random.lua         |   47 +
> >  test/LuaJIT-tests/lib/string/byte.lua         |   92 ++
> >  test/LuaJIT-tests/lib/string/char.lua         |   29 +
> >  test/LuaJIT-tests/lib/string/dump.lua         |   31 +
> >  test/LuaJIT-tests/lib/string/format/index     |    1 +
> >  test/LuaJIT-tests/lib/string/format/num.lua   |  184 +++
> >  test/LuaJIT-tests/lib/string/index            |   11 +
> >  test/LuaJIT-tests/lib/string/len.lua          |   14 +
> >  test/LuaJIT-tests/lib/string/lower_upper.lua  |   51 +
> >  test/LuaJIT-tests/lib/string/metatable.lua    |    3 +
> >  .../lib/string/multiple_functions.lua         |   16 +
> >  test/LuaJIT-tests/lib/string/rep.lua          |   68 +
> >  test/LuaJIT-tests/lib/string/reverse.lua      |   13 +
> >  test/LuaJIT-tests/lib/string/sub.lua          |  189 +++
> >  test/LuaJIT-tests/lib/table/concat.lua        |   55 +
> >  test/LuaJIT-tests/lib/table/index             |    6 +
> >  test/LuaJIT-tests/lib/table/insert.lua        |   17 +
> >  test/LuaJIT-tests/lib/table/misc.lua          |   58 +
> >  test/LuaJIT-tests/lib/table/new.lua           |   11 +
> >  test/LuaJIT-tests/lib/table/pack.lua          |    7 +
> >  test/LuaJIT-tests/lib/table/remove.lua        |   42 +
> >  test/LuaJIT-tests/lib/table/sort.lua          |   27 +
> >  test/LuaJIT-tests/misc/alias_alloc.lua        |   54 +
> >  test/LuaJIT-tests/misc/api_call.lua           |   98 ++
> >  test/LuaJIT-tests/misc/catch_wrap.lua         |   45 +
> >  test/LuaJIT-tests/misc/coro_traceback.lua     |    8 +
> >  test/LuaJIT-tests/misc/coro_yield.lua         |  111 ++
> >  test/LuaJIT-tests/misc/debug_gc.lua           |   47 +
> >  test/LuaJIT-tests/misc/dualnum.lua            |   47 +
> >  test/LuaJIT-tests/misc/for_dir.lua            |   13 +
> >  test/LuaJIT-tests/misc/fori_coerce.lua        |   33 +
> >  test/LuaJIT-tests/misc/gc_rechain.lua         |   32 +
> >  test/LuaJIT-tests/misc/gc_trace.lua           |   37 +
> >  test/LuaJIT-tests/misc/gcstep.lua             |   33 +
> >  test/LuaJIT-tests/misc/hook_active.lua        |   95 ++
> >  test/LuaJIT-tests/misc/hook_line.lua          |   41 +
> >  test/LuaJIT-tests/misc/hook_norecord.lua      |   12 +
> >  test/LuaJIT-tests/misc/hook_record.lua        |    8 +
> >  test/LuaJIT-tests/misc/hook_top.lua           |   55 +
> >  test/LuaJIT-tests/misc/jit_flush.lua          |   50 +
> >  test/LuaJIT-tests/misc/lightud.lua            |   88 ++
> >  test/LuaJIT-tests/misc/loop_unroll.lua        |   35 +
> >  test/LuaJIT-tests/misc/parse_comp.lua         |   13 +
> >  test/LuaJIT-tests/misc/parse_esc.lua          |    7 +
> >  test/LuaJIT-tests/misc/parse_misc.lua         |   31 +
> >  test/LuaJIT-tests/misc/phi_conv.lua           |   53 +
> >  test/LuaJIT-tests/misc/recurse_deep.lua       |   29 +
> >  test/LuaJIT-tests/misc/recurse_tail.lua       |   22 +
> >  test/LuaJIT-tests/misc/stack_gc.lua           |   15 +
> >  test/LuaJIT-tests/misc/stack_purge.lua        |   25 +
> >  test/LuaJIT-tests/misc/stackov.lua            |   40 +
> >  test/LuaJIT-tests/misc/stackovc.lua           |    4 +
> >  test/LuaJIT-tests/misc/tcall_base.lua         |   20 +
> >  test/LuaJIT-tests/misc/tcall_loop.lua         |    8 +
> >  test/LuaJIT-tests/misc/tonumber_scan.lua      |  180 +++
> >  test/LuaJIT-tests/misc/uclo.lua               |   91 ++
> >  test/LuaJIT-tests/misc/unordered_jit.lua      |   96 ++
> >  test/LuaJIT-tests/misc/wbarrier.lua           |    7 +
> >  test/LuaJIT-tests/misc/wbarrier_jit.lua       |   18 +
> >  test/LuaJIT-tests/misc/wbarrier_obar.lua      |   22 +
> >  test/LuaJIT-tests/opt/dse/array.lua           |  197 +++
> >  test/LuaJIT-tests/opt/dse/field.lua           |   70 +
> >  test/LuaJIT-tests/opt/dse/index               |    2 +
> >  test/LuaJIT-tests/opt/fold/index              |    1 +
> >  test/LuaJIT-tests/opt/fold/kfold.lua          |   81 ++
> >  test/LuaJIT-tests/opt/fuse.lua                |    5 +
> >  test/LuaJIT-tests/opt/fwd/hrefk_rollback.lua  |   32 +
> >  test/LuaJIT-tests/opt/fwd/index               |    3 +
> >  test/LuaJIT-tests/opt/fwd/tnew_tdup.lua       |   69 +
> >  test/LuaJIT-tests/opt/fwd/upval.lua           |   50 +
> >  test/LuaJIT-tests/opt/index                   |    6 +
> >  test/LuaJIT-tests/opt/loop/index              |    1 +
> >  test/LuaJIT-tests/opt/loop/unroll.lua         |   32 +
> >  test/LuaJIT-tests/opt/sink/alloc.lua          |  126 ++
> >  test/LuaJIT-tests/opt/sink/ffi.lua            |  121 ++
> >  test/LuaJIT-tests/opt/sink/ffi_nosink.lua     |   45 +
> >  test/LuaJIT-tests/opt/sink/index              |    4 +
> >  test/LuaJIT-tests/opt/sink/nosink.lua         |  109 ++
> >  test/LuaJIT-tests/src/cpptest.cpp             |  129 ++
> >  test/LuaJIT-tests/src/ctest.c                 |  339 +++++
> >  test/LuaJIT-tests/sysdep/catch_cpp.lua        |   71 +
> >  test/LuaJIT-tests/sysdep/ffi_include_gtk.lua  |    9 +
> >  test/LuaJIT-tests/sysdep/ffi_include_std.lua  |   36 +
> >  test/LuaJIT-tests/sysdep/ffi_lib_c.lua        |   87 ++
> >  test/LuaJIT-tests/sysdep/ffi_lib_z.lua        |  107 ++
> >  test/LuaJIT-tests/test.lua                    |  416 ++++++
> >  test/LuaJIT-tests/trace/exit_frame.lua        |   79 ++
> >  test/LuaJIT-tests/trace/exit_growstack.lua    |   28 +
> >  test/LuaJIT-tests/trace/exit_jfuncf.lua       |   30 +
> >  test/LuaJIT-tests/trace/gc64_slot_revival.lua |   18 +
> >  test/LuaJIT-tests/trace/index                 |    7 +
> >  test/LuaJIT-tests/trace/phi/copyspill.lua     |   53 +
> >  test/LuaJIT-tests/trace/phi/index             |    3 +
> >  test/LuaJIT-tests/trace/phi/ref.lua           |  131 ++
> >  test/LuaJIT-tests/trace/phi/rotate.lua        |  149 +++
> >  test/LuaJIT-tests/trace/snap.lua              |   47 +
> >  test/LuaJIT-tests/trace/stitch.lua            |   19 +
> >  .../unportable/ffi_arith_int64.lua            |   68 +
> >  test/LuaJIT-tests/unportable/math_special.lua |   55 +
> >  test/PUC-Lua-5.1-tests/CMakeLists.txt         |   92 ++
> >  test/PUC-Lua-5.1-tests/README                 |   41 +
> >  test/PUC-Lua-5.1-tests/all.lua                |  145 +++
> >  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            |  432 +++++++
> >  test/PUC-Lua-5.1-tests/code.lua               |  143 ++
> >  test/PUC-Lua-5.1-tests/constructs.lua         |  247 ++++
> >  test/PUC-Lua-5.1-tests/db.lua                 |  538 ++++++++
> >  test/PUC-Lua-5.1-tests/errors.lua             |  264 ++++
> >  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                 |  320 +++++
> >  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               |  195 +++
> >  test/PUC-Lua-5.1-tests/math.lua               |  213 +++
> >  test/PUC-Lua-5.1-tests/nextvar.lua            |  403 ++++++
> >  test/PUC-Lua-5.1-tests/pm.lua                 |  281 ++++
> >  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 ++
> >  test/lua-Harness-tests/000-sanity.t           |   54 +
> >  test/lua-Harness-tests/001-if.t               |   88 ++
> >  test/lua-Harness-tests/002-table.t            |   67 +
> >  test/lua-Harness-tests/011-while.t            |   89 ++
> >  test/lua-Harness-tests/012-repeat.t           |   85 ++
> >  test/lua-Harness-tests/014-fornum.t           |  151 +++
> >  test/lua-Harness-tests/015-forlist.t          |  111 ++
> >  test/lua-Harness-tests/090-tap.t              |   37 +
> >  test/lua-Harness-tests/091-profile.t          |   45 +
> >  test/lua-Harness-tests/101-boolean.t          |  127 ++
> >  test/lua-Harness-tests/102-function.t         |  206 +++
> >  test/lua-Harness-tests/103-nil.t              |  127 ++
> >  test/lua-Harness-tests/104-number.t           |  246 ++++
> >  test/lua-Harness-tests/105-string.t           |  277 ++++
> >  test/lua-Harness-tests/106-table.t            |  135 ++
> >  test/lua-Harness-tests/107-thread.t           |  135 ++
> >  test/lua-Harness-tests/108-userdata.t         |  132 ++
> >  test/lua-Harness-tests/200-examples.t         |  104 ++
> >  test/lua-Harness-tests/201-assign.t           |  150 +++
> >  test/lua-Harness-tests/202-expr.t             |  157 +++
> >  test/lua-Harness-tests/203-lexico.t           |  147 +++
> >  test/lua-Harness-tests/204-grammar.t          |  233 ++++
> >  test/lua-Harness-tests/211-scope.t            |   86 ++
> >  test/lua-Harness-tests/212-function.t         |  288 +++++
> >  test/lua-Harness-tests/213-closure.t          |   98 ++
> >  test/lua-Harness-tests/214-coroutine.t        |  244 ++++
> >  test/lua-Harness-tests/221-table.t            |  120 ++
> >  test/lua-Harness-tests/222-constructor.t      |  119 ++
> >  test/lua-Harness-tests/223-iterator.t         |  203 +++
> >  test/lua-Harness-tests/231-metatable.t        |  602 +++++++++
> >  test/lua-Harness-tests/232-object.t           |  314 +++++
> >  .../241-standalone.t.disabled                 |  269 ++++
> >  test/lua-Harness-tests/242-luac.t             |  341 +++++
> >  test/lua-Harness-tests/301-basic.t            |  859 ++++++++++++
> >  test/lua-Harness-tests/303-package.t          |  290 +++++
> >  test/lua-Harness-tests/304-string.t           |  633 +++++++++
> >  test/lua-Harness-tests/305-utf8.t.disabled    |   55 +
> >  test/lua-Harness-tests/306-table.t            |  372 ++++++
> >  test/lua-Harness-tests/307-math.t             |  375 ++++++
> >  test/lua-Harness-tests/308-io.t               |  397 ++++++
> >  test/lua-Harness-tests/309-os.t               |  275 ++++
> >  test/lua-Harness-tests/310-debug.t            |  322 +++++
> >  test/lua-Harness-tests/311-bit32.t            |  127 ++
> >  test/lua-Harness-tests/314-regex.t            |  222 ++++
> >  test/lua-Harness-tests/320-stdin.t            |  133 ++
> >  test/lua-Harness-tests/401-bitop.t            |  106 ++
> >  test/lua-Harness-tests/402-ffi.t              |  142 ++
> >  test/lua-Harness-tests/403-jit.t              |  163 +++
> >  test/lua-Harness-tests/404-ext.t              |  171 +++
> >  test/lua-Harness-tests/411-luajit.t.disabled  |  211 +++
> >  test/lua-Harness-tests/CMakeLists.txt         |   62 +
> >  test/lua-Harness-tests/lexico52/lexico.t      |   45 +
> >  test/lua-Harness-tests/lexico53/boolean.t     |   43 +
> >  test/lua-Harness-tests/lexico53/function.t    |   66 +
> >  test/lua-Harness-tests/lexico53/lexico.t      |   30 +
> >  test/lua-Harness-tests/lexico53/nil.t         |   43 +
> >  test/lua-Harness-tests/lexico53/number.t      |  181 +++
> >  test/lua-Harness-tests/lexico53/string.t      |  169 +++
> >  test/lua-Harness-tests/lexico53/table.t       |   43 +
> >  test/lua-Harness-tests/lexico53/thread.t      |   45 +
> >  test/lua-Harness-tests/lexico53/userdata.t    |   45 +
> >  test/lua-Harness-tests/lexico53/utf8.t        |  179 +++
> >  test/lua-Harness-tests/lexico54/lexico.t      |   19 +
> >  test/lua-Harness-tests/lexico54/metatable.t   |   38 +
> >  test/lua-Harness-tests/lexico54/utf8.t        |   54 +
> >  test/lua-Harness-tests/lexicojit/basic.t      |   27 +
> >  test/lua-Harness-tests/lexicojit/ext.t        |   52 +
> >  test/lua-Harness-tests/lexicojit/lexico.t     |   32 +
> >  test/lua-Harness-tests/profile.lua            |   53 +
> >  test/lua-Harness-tests/profile_lua51.lua      |   46 +
> >  .../profile_lua51_strict.lua                  |   46 +
> >  test/lua-Harness-tests/profile_lua52.lua      |   46 +
> >  .../profile_lua52_strict.lua                  |   46 +
> >  test/lua-Harness-tests/profile_lua53.lua      |   52 +
> >  .../profile_lua53_noconv.lua                  |   55 +
> >  .../profile_lua53_strict.lua                  |   52 +
> >  test/lua-Harness-tests/profile_lua54.lua      |   52 +
> >  .../profile_lua54_noconv.lua                  |   55 +
> >  .../profile_lua54_strict.lua                  |   53 +
> >  test/lua-Harness-tests/profile_luajit20.lua   |   53 +
> >  .../profile_luajit20_compat52.lua             |   53 +
> >  test/lua-Harness-tests/profile_luajit21.lua   |   53 +
> >  .../profile_luajit21_compat52.lua             |   53 +
> >  test/lua-Harness-tests/profile_openresty.lua  |   53 +
> >  test/lua-Harness-tests/profile_ravi.lua       |   58 +
> >  test/lua-Harness-tests/profile_tiny_fork.lua  |   60 +
> >  test/lua-Harness-tests/rx_captures            |   13 +
> >  test/lua-Harness-tests/rx_charclass           |   38 +
> >  test/lua-Harness-tests/rx_metachars           |  117 ++
> >  test/lua-Harness-tests/tap_harness.lua        |  204 +++
> >  322 files changed, 34168 insertions(+), 2 deletions(-)
> >  create mode 100644 test/LuaJIT-tests/CMakeLists.txt
> >  create mode 100644 test/LuaJIT-tests/README.md
> >  create mode 100644 test/LuaJIT-tests/bc/constov.lua
> >  create mode 100644 test/LuaJIT-tests/bc/index
> >  create mode 100644 test/LuaJIT-tests/common/expect_error.lua
> >  create mode 100644 test/LuaJIT-tests/common/ffi_util.inc
> >  create mode 100644 test/LuaJIT-tests/common/test_runner_canary.lua
> >  create mode 100644 test/LuaJIT-tests/computations.lua
> >  create mode 100644 test/LuaJIT-tests/index
> >  create mode 100644 test/LuaJIT-tests/lang/andor.lua
> >  create mode 100644 test/LuaJIT-tests/lang/assignment.lua
> >  create mode 100644 test/LuaJIT-tests/lang/compare.lua
> >  create mode 100644 test/LuaJIT-tests/lang/compare_nan.lua
> >  create mode 100644 test/LuaJIT-tests/lang/concat.lua
> >  create mode 100644 test/LuaJIT-tests/lang/constant/index
> >  create mode 100644 test/LuaJIT-tests/lang/constant/number.lua
> >  create mode 100644 test/LuaJIT-tests/lang/constant/table.lua
> >  create mode 100644 test/LuaJIT-tests/lang/coroutine.lua
> >  create mode 100644 test/LuaJIT-tests/lang/for.lua
> >  create mode 100644 test/LuaJIT-tests/lang/gc.lua
> >  create mode 100644 test/LuaJIT-tests/lang/goto.lua
> >  create mode 100644 test/LuaJIT-tests/lang/index
> >  create mode 100644 test/LuaJIT-tests/lang/length.lua
> >  create mode 100644 test/LuaJIT-tests/lang/meta/arith.lua
> >  create mode 100644 test/LuaJIT-tests/lang/meta/arith_jit.lua
> >  create mode 100644 test/LuaJIT-tests/lang/meta/call.lua
> >  create mode 100644 test/LuaJIT-tests/lang/meta/cat.lua
> >  create mode 100644 test/LuaJIT-tests/lang/meta/comp.lua
> >  create mode 100644 test/LuaJIT-tests/lang/meta/comp_jit.lua
> >  create mode 100644 test/LuaJIT-tests/lang/meta/debuginfo.lua
> >  create mode 100644 test/LuaJIT-tests/lang/meta/eq.lua
> >  create mode 100644 test/LuaJIT-tests/lang/meta/eq_jit.lua
> >  create mode 100644 test/LuaJIT-tests/lang/meta/framegap.lua
> >  create mode 100644 test/LuaJIT-tests/lang/meta/index
> >  create mode 100644 test/LuaJIT-tests/lang/meta/index.lua
> >  create mode 100644 test/LuaJIT-tests/lang/meta/len.lua
> >  create mode 100644 test/LuaJIT-tests/lang/meta/newindex.lua
> >  create mode 100644 test/LuaJIT-tests/lang/meta/nomm.lua
> >  create mode 100644 test/LuaJIT-tests/lang/modulo.lua
> >  create mode 100644 test/LuaJIT-tests/lang/self.lua
> >  create mode 100644 test/LuaJIT-tests/lang/table.lua
> >  create mode 100644 test/LuaJIT-tests/lang/tail_recursion.lua
> >  create mode 100644 test/LuaJIT-tests/lang/upvalue/closure.lua
> >  create mode 100644 test/LuaJIT-tests/lang/upvalue/index
> >  create mode 100644 test/LuaJIT-tests/lang/vararg_jit.lua
> >  create mode 100644 test/LuaJIT-tests/lib/base/assert.lua
> >  create mode 100644 test/LuaJIT-tests/lib/base/error.lua
> >  create mode 100644 test/LuaJIT-tests/lib/base/getfenv.lua
> >  create mode 100644 test/LuaJIT-tests/lib/base/getsetmetatable.lua
> >  create mode 100644 test/LuaJIT-tests/lib/base/index
> >  create mode 100644 test/LuaJIT-tests/lib/base/ipairs.lua
> >  create mode 100644 test/LuaJIT-tests/lib/base/next.lua
> >  create mode 100644 test/LuaJIT-tests/lib/base/pairs.lua
> >  create mode 100644 test/LuaJIT-tests/lib/base/pcall_jit.lua
> >  create mode 100644 test/LuaJIT-tests/lib/base/select.lua
> >  create mode 100644 test/LuaJIT-tests/lib/base/tonumber_tostring.lua
> >  create mode 100644 test/LuaJIT-tests/lib/base/xpcall_jit.lua
> >  create mode 100644 test/LuaJIT-tests/lib/bit.lua
> >  create mode 100644 test/LuaJIT-tests/lib/contents.lua
> >  create mode 100644 test/LuaJIT-tests/lib/coroutine/index
> >  create mode 100644 test/LuaJIT-tests/lib/coroutine/yield.lua
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/bit64.lua
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/cdata_var.lua
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/copy_fill.lua
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/err.lua
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_arith_ptr.lua
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_bitfield.lua
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_call.lua
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_callback.lua
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_const.lua
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_convert.lua
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_enum.lua
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_gcstep_recursive.lua
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_jit_arith.lua
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_jit_call.lua
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_jit_conv.lua
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_lex_number.lua
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_metatype.lua
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_new.lua
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_parse_array.lua
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_parse_basic.lua
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_parse_cdef.lua
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_parse_struct.lua
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_tabov.lua
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/index
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/istype.lua
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/jit_array.lua
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/jit_complex.lua
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/jit_misc.lua
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/jit_struct.lua
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/meta_tostring.lua
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/redir.lua
> >  create mode 100644 test/LuaJIT-tests/lib/ffi/type_punning.lua
> >  create mode 100644 test/LuaJIT-tests/lib/index
> >  create mode 100644 test/LuaJIT-tests/lib/math/abs.lua
> >  create mode 100644 test/LuaJIT-tests/lib/math/constants.lua
> >  create mode 100644 test/LuaJIT-tests/lib/math/index
> >  create mode 100644 test/LuaJIT-tests/lib/math/random.lua
> >  create mode 100644 test/LuaJIT-tests/lib/string/byte.lua
> >  create mode 100644 test/LuaJIT-tests/lib/string/char.lua
> >  create mode 100644 test/LuaJIT-tests/lib/string/dump.lua
> >  create mode 100644 test/LuaJIT-tests/lib/string/format/index
> >  create mode 100644 test/LuaJIT-tests/lib/string/format/num.lua
> >  create mode 100644 test/LuaJIT-tests/lib/string/index
> >  create mode 100644 test/LuaJIT-tests/lib/string/len.lua
> >  create mode 100644 test/LuaJIT-tests/lib/string/lower_upper.lua
> >  create mode 100644 test/LuaJIT-tests/lib/string/metatable.lua
> >  create mode 100644 test/LuaJIT-tests/lib/string/multiple_functions.lua
> >  create mode 100644 test/LuaJIT-tests/lib/string/rep.lua
> >  create mode 100644 test/LuaJIT-tests/lib/string/reverse.lua
> >  create mode 100644 test/LuaJIT-tests/lib/string/sub.lua
> >  create mode 100644 test/LuaJIT-tests/lib/table/concat.lua
> >  create mode 100644 test/LuaJIT-tests/lib/table/index
> >  create mode 100644 test/LuaJIT-tests/lib/table/insert.lua
> >  create mode 100644 test/LuaJIT-tests/lib/table/misc.lua
> >  create mode 100644 test/LuaJIT-tests/lib/table/new.lua
> >  create mode 100644 test/LuaJIT-tests/lib/table/pack.lua
> >  create mode 100644 test/LuaJIT-tests/lib/table/remove.lua
> >  create mode 100644 test/LuaJIT-tests/lib/table/sort.lua
> >  create mode 100644 test/LuaJIT-tests/misc/alias_alloc.lua
> >  create mode 100644 test/LuaJIT-tests/misc/api_call.lua
> >  create mode 100644 test/LuaJIT-tests/misc/catch_wrap.lua
> >  create mode 100644 test/LuaJIT-tests/misc/coro_traceback.lua
> >  create mode 100644 test/LuaJIT-tests/misc/coro_yield.lua
> >  create mode 100644 test/LuaJIT-tests/misc/debug_gc.lua
> >  create mode 100644 test/LuaJIT-tests/misc/dualnum.lua
> >  create mode 100644 test/LuaJIT-tests/misc/for_dir.lua
> >  create mode 100644 test/LuaJIT-tests/misc/fori_coerce.lua
> >  create mode 100644 test/LuaJIT-tests/misc/gc_rechain.lua
> >  create mode 100644 test/LuaJIT-tests/misc/gc_trace.lua
> >  create mode 100644 test/LuaJIT-tests/misc/gcstep.lua
> >  create mode 100644 test/LuaJIT-tests/misc/hook_active.lua
> >  create mode 100644 test/LuaJIT-tests/misc/hook_line.lua
> >  create mode 100644 test/LuaJIT-tests/misc/hook_norecord.lua
> >  create mode 100644 test/LuaJIT-tests/misc/hook_record.lua
> >  create mode 100644 test/LuaJIT-tests/misc/hook_top.lua
> >  create mode 100644 test/LuaJIT-tests/misc/jit_flush.lua
> >  create mode 100644 test/LuaJIT-tests/misc/lightud.lua
> >  create mode 100644 test/LuaJIT-tests/misc/loop_unroll.lua
> >  create mode 100644 test/LuaJIT-tests/misc/parse_comp.lua
> >  create mode 100644 test/LuaJIT-tests/misc/parse_esc.lua
> >  create mode 100644 test/LuaJIT-tests/misc/parse_misc.lua
> >  create mode 100644 test/LuaJIT-tests/misc/phi_conv.lua
> >  create mode 100644 test/LuaJIT-tests/misc/recurse_deep.lua
> >  create mode 100644 test/LuaJIT-tests/misc/recurse_tail.lua
> >  create mode 100644 test/LuaJIT-tests/misc/stack_gc.lua
> >  create mode 100644 test/LuaJIT-tests/misc/stack_purge.lua
> >  create mode 100644 test/LuaJIT-tests/misc/stackov.lua
> >  create mode 100644 test/LuaJIT-tests/misc/stackovc.lua
> >  create mode 100644 test/LuaJIT-tests/misc/tcall_base.lua
> >  create mode 100644 test/LuaJIT-tests/misc/tcall_loop.lua
> >  create mode 100644 test/LuaJIT-tests/misc/tonumber_scan.lua
> >  create mode 100644 test/LuaJIT-tests/misc/uclo.lua
> >  create mode 100644 test/LuaJIT-tests/misc/unordered_jit.lua
> >  create mode 100644 test/LuaJIT-tests/misc/wbarrier.lua
> >  create mode 100644 test/LuaJIT-tests/misc/wbarrier_jit.lua
> >  create mode 100644 test/LuaJIT-tests/misc/wbarrier_obar.lua
> >  create mode 100644 test/LuaJIT-tests/opt/dse/array.lua
> >  create mode 100644 test/LuaJIT-tests/opt/dse/field.lua
> >  create mode 100644 test/LuaJIT-tests/opt/dse/index
> >  create mode 100644 test/LuaJIT-tests/opt/fold/index
> >  create mode 100644 test/LuaJIT-tests/opt/fold/kfold.lua
> >  create mode 100644 test/LuaJIT-tests/opt/fuse.lua
> >  create mode 100644 test/LuaJIT-tests/opt/fwd/hrefk_rollback.lua
> >  create mode 100644 test/LuaJIT-tests/opt/fwd/index
> >  create mode 100644 test/LuaJIT-tests/opt/fwd/tnew_tdup.lua
> >  create mode 100644 test/LuaJIT-tests/opt/fwd/upval.lua
> >  create mode 100644 test/LuaJIT-tests/opt/index
> >  create mode 100644 test/LuaJIT-tests/opt/loop/index
> >  create mode 100644 test/LuaJIT-tests/opt/loop/unroll.lua
> >  create mode 100644 test/LuaJIT-tests/opt/sink/alloc.lua
> >  create mode 100644 test/LuaJIT-tests/opt/sink/ffi.lua
> >  create mode 100644 test/LuaJIT-tests/opt/sink/ffi_nosink.lua
> >  create mode 100644 test/LuaJIT-tests/opt/sink/index
> >  create mode 100644 test/LuaJIT-tests/opt/sink/nosink.lua
> >  create mode 100644 test/LuaJIT-tests/src/cpptest.cpp
> >  create mode 100644 test/LuaJIT-tests/src/ctest.c
> >  create mode 100644 test/LuaJIT-tests/sysdep/catch_cpp.lua
> >  create mode 100644 test/LuaJIT-tests/sysdep/ffi_include_gtk.lua
> >  create mode 100644 test/LuaJIT-tests/sysdep/ffi_include_std.lua
> >  create mode 100644 test/LuaJIT-tests/sysdep/ffi_lib_c.lua
> >  create mode 100644 test/LuaJIT-tests/sysdep/ffi_lib_z.lua
> >  create mode 100644 test/LuaJIT-tests/test.lua
> >  create mode 100644 test/LuaJIT-tests/trace/exit_frame.lua
> >  create mode 100644 test/LuaJIT-tests/trace/exit_growstack.lua
> >  create mode 100644 test/LuaJIT-tests/trace/exit_jfuncf.lua
> >  create mode 100644 test/LuaJIT-tests/trace/gc64_slot_revival.lua
> >  create mode 100644 test/LuaJIT-tests/trace/index
> >  create mode 100644 test/LuaJIT-tests/trace/phi/copyspill.lua
> >  create mode 100644 test/LuaJIT-tests/trace/phi/index
> >  create mode 100644 test/LuaJIT-tests/trace/phi/ref.lua
> >  create mode 100644 test/LuaJIT-tests/trace/phi/rotate.lua
> >  create mode 100644 test/LuaJIT-tests/trace/snap.lua
> >  create mode 100644 test/LuaJIT-tests/trace/stitch.lua
> >  create mode 100644 test/LuaJIT-tests/unportable/ffi_arith_int64.lua
> >  create mode 100644 test/LuaJIT-tests/unportable/math_special.lua
> >  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/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
> >  create mode 100755 test/lua-Harness-tests/000-sanity.t
> >  create mode 100755 test/lua-Harness-tests/001-if.t
> >  create mode 100755 test/lua-Harness-tests/002-table.t
> >  create mode 100755 test/lua-Harness-tests/011-while.t
> >  create mode 100755 test/lua-Harness-tests/012-repeat.t
> >  create mode 100755 test/lua-Harness-tests/014-fornum.t
> >  create mode 100755 test/lua-Harness-tests/015-forlist.t
> >  create mode 100755 test/lua-Harness-tests/090-tap.t
> >  create mode 100755 test/lua-Harness-tests/091-profile.t
> >  create mode 100755 test/lua-Harness-tests/101-boolean.t
> >  create mode 100755 test/lua-Harness-tests/102-function.t
> >  create mode 100755 test/lua-Harness-tests/103-nil.t
> >  create mode 100755 test/lua-Harness-tests/104-number.t
> >  create mode 100755 test/lua-Harness-tests/105-string.t
> >  create mode 100755 test/lua-Harness-tests/106-table.t
> >  create mode 100755 test/lua-Harness-tests/107-thread.t
> >  create mode 100755 test/lua-Harness-tests/108-userdata.t
> >  create mode 100755 test/lua-Harness-tests/200-examples.t
> >  create mode 100755 test/lua-Harness-tests/201-assign.t
> >  create mode 100755 test/lua-Harness-tests/202-expr.t
> >  create mode 100755 test/lua-Harness-tests/203-lexico.t
> >  create mode 100755 test/lua-Harness-tests/204-grammar.t
> >  create mode 100755 test/lua-Harness-tests/211-scope.t
> >  create mode 100755 test/lua-Harness-tests/212-function.t
> >  create mode 100755 test/lua-Harness-tests/213-closure.t
> >  create mode 100755 test/lua-Harness-tests/214-coroutine.t
> >  create mode 100755 test/lua-Harness-tests/221-table.t
> >  create mode 100755 test/lua-Harness-tests/222-constructor.t
> >  create mode 100755 test/lua-Harness-tests/223-iterator.t
> >  create mode 100755 test/lua-Harness-tests/231-metatable.t
> >  create mode 100755 test/lua-Harness-tests/232-object.t
> >  create mode 100755 test/lua-Harness-tests/241-standalone.t.disabled
> >  create mode 100755 test/lua-Harness-tests/242-luac.t
> >  create mode 100755 test/lua-Harness-tests/301-basic.t
> >  create mode 100755 test/lua-Harness-tests/303-package.t
> >  create mode 100755 test/lua-Harness-tests/304-string.t
> >  create mode 100755 test/lua-Harness-tests/305-utf8.t.disabled
> >  create mode 100755 test/lua-Harness-tests/306-table.t
> >  create mode 100755 test/lua-Harness-tests/307-math.t
> >  create mode 100755 test/lua-Harness-tests/308-io.t
> >  create mode 100755 test/lua-Harness-tests/309-os.t
> >  create mode 100755 test/lua-Harness-tests/310-debug.t
> >  create mode 100755 test/lua-Harness-tests/311-bit32.t
> >  create mode 100755 test/lua-Harness-tests/314-regex.t
> >  create mode 100755 test/lua-Harness-tests/320-stdin.t
> >  create mode 100755 test/lua-Harness-tests/401-bitop.t
> >  create mode 100755 test/lua-Harness-tests/402-ffi.t
> >  create mode 100755 test/lua-Harness-tests/403-jit.t
> >  create mode 100755 test/lua-Harness-tests/404-ext.t
> >  create mode 100755 test/lua-Harness-tests/411-luajit.t.disabled
> >  create mode 100644 test/lua-Harness-tests/CMakeLists.txt
> >  create mode 100644 test/lua-Harness-tests/lexico52/lexico.t
> >  create mode 100644 test/lua-Harness-tests/lexico53/boolean.t
> >  create mode 100644 test/lua-Harness-tests/lexico53/function.t
> >  create mode 100644 test/lua-Harness-tests/lexico53/lexico.t
> >  create mode 100644 test/lua-Harness-tests/lexico53/nil.t
> >  create mode 100644 test/lua-Harness-tests/lexico53/number.t
> >  create mode 100644 test/lua-Harness-tests/lexico53/string.t
> >  create mode 100644 test/lua-Harness-tests/lexico53/table.t
> >  create mode 100644 test/lua-Harness-tests/lexico53/thread.t
> >  create mode 100644 test/lua-Harness-tests/lexico53/userdata.t
> >  create mode 100644 test/lua-Harness-tests/lexico53/utf8.t
> >  create mode 100644 test/lua-Harness-tests/lexico54/lexico.t
> >  create mode 100644 test/lua-Harness-tests/lexico54/metatable.t
> >  create mode 100644 test/lua-Harness-tests/lexico54/utf8.t
> >  create mode 100644 test/lua-Harness-tests/lexicojit/basic.t
> >  create mode 100644 test/lua-Harness-tests/lexicojit/ext.t
> >  create mode 100644 test/lua-Harness-tests/lexicojit/lexico.t
> >  create mode 100644 test/lua-Harness-tests/profile.lua
> >  create mode 100644 test/lua-Harness-tests/profile_lua51.lua
> >  create mode 100644 test/lua-Harness-tests/profile_lua51_strict.lua
> >  create mode 100644 test/lua-Harness-tests/profile_lua52.lua
> >  create mode 100644 test/lua-Harness-tests/profile_lua52_strict.lua
> >  create mode 100644 test/lua-Harness-tests/profile_lua53.lua
> >  create mode 100644 test/lua-Harness-tests/profile_lua53_noconv.lua
> >  create mode 100644 test/lua-Harness-tests/profile_lua53_strict.lua
> >  create mode 100644 test/lua-Harness-tests/profile_lua54.lua
> >  create mode 100644 test/lua-Harness-tests/profile_lua54_noconv.lua
> >  create mode 100644 test/lua-Harness-tests/profile_lua54_strict.lua
> >  create mode 100644 test/lua-Harness-tests/profile_luajit20.lua
> >  create mode 100644 test/lua-Harness-tests/profile_luajit20_compat52.lua
> >  create mode 100644 test/lua-Harness-tests/profile_luajit21.lua
> >  create mode 100644 test/lua-Harness-tests/profile_luajit21_compat52.lua
> >  create mode 100644 test/lua-Harness-tests/profile_openresty.lua
> >  create mode 100644 test/lua-Harness-tests/profile_ravi.lua
> >  create mode 100644 test/lua-Harness-tests/profile_tiny_fork.lua
> >  create mode 100644 test/lua-Harness-tests/rx_captures
> >  create mode 100644 test/lua-Harness-tests/rx_charclass
> >  create mode 100644 test/lua-Harness-tests/rx_metachars
> >  create mode 100644 test/lua-Harness-tests/tap_harness.lua
> > 
> > -- 
> > 2.28.0
> > 
> > [0]: https://github.com/tarantool/tarantool/runs/2029452344
> > [1]: https://github.com/google/sanitizers/issues/980
> > [2]: https://github.com/google/sanitizers/issues/189
> > [3]: https://github.com/google/sanitizers/wiki/AddressSanitizerFlags
> 
> [1]: https://github.com/tarantool/luajit/tree/imun/tarantool-test
> [2]: https://github.com/tarantool/tarantool/tree/imun/luajit-test
> [3]: https://github.com/tarantool/luajit/commit/9712cc9#diff-1e7de1ae2d059d21e1dd75d5812d5a34b0222cef273b7c3a2af62eb747f9d20aR291-R307
> [4]: https://github.com/tarantool/tarantool/commit/03b04a7
> [5]: https://github.com/tarantool/luajit/commit/72f87b2
> 
> -- 
> Best regards,
> IM

[1]: https://github.com/tarantool/tarantool/issues/5870

-- 
Best regards,
Sergey Kaplun

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

* Re: [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites
  2021-03-09 23:59 ` Igor Munkin via Tarantool-patches
  2021-03-10  8:09   ` Sergey Kaplun via Tarantool-patches
@ 2021-03-10  9:46   ` Sergey Ostanevich via Tarantool-patches
  2021-03-10 10:43     ` Igor Munkin via Tarantool-patches
  2021-03-10 16:25   ` Igor Munkin via Tarantool-patches
  2 siblings, 1 reply; 26+ messages in thread
From: Sergey Ostanevich via Tarantool-patches @ 2021-03-10  9:46 UTC (permalink / raw)
  To: Igor Munkin; +Cc: tarantool-patches

Hi!

Thanks for the patch!

> On 10 Mar 2021, at 02:59, Igor Munkin <imun@tarantool.org> wrote:
> 
> Sergey,
> 
> I've precisely reviewed patches 04-09 and they look good. I've polished
> a bit[1] the series, so it can be applied to the trunk out of the order.
> CI[2] is green.
> 
> BTW, I would like to leave some major points related to my review.
> 
> 1. The suite has been taken intact. To check this I used the following
> recipe:
> | $ pwd
> | /LuaJIT-test-cleanup/test
> | $ git remote -v
> | origin  https://github.com/LuaJIT/LuaJIT-test-cleanup.git (fetch)
> | origin  https://github.com/LuaJIT/LuaJIT-test-cleanup.git (push)
> | $ git lo -1
> | 014708b (HEAD -> master, origin/master, origin/HEAD) Add test for BC_VARG slot revival
> | $ find . -type f | sort | xargs md5sum > ~/vanilla

Why did you use sort here? I recall using sort -u to remove duplicates, but it is not…

> | <...>
> | $ pwd
> | /tarantool-luajit/test/LuaJIT-test
> | $ git remote -v
> | origin  git@github.com:tarantool/luajit (fetch)
> | origin  git@github.com:tarantool/luajit (push)
> | $ git lo -1
> | cc0967c (HEAD) test: add LuaJIT-test-cleanup test suite
> | $ find . -type f | sort | xargs md5sum > ~/tarantool
> | $ diff ~/vanilla ~/tarantool
> | > 91cb30f369b83d7626a8ae852781ebb5  ./CMakeLists.txt
> 
> 2. I've introduced a new CMake option: LUAJIT_TEST_INIT. You can read
> the description here[3]. It allows to enclose the partial LUA_INIT
> emulation, implemented via '-e dofile[[${LUAJIT_TEST_INIT}]]' and
> obliges user to set the name of the Lua script to be run prior to the
> testing suite[4]. By default it does nothing by reading from /dev/null.
> 
I would like to complain that you’re open extra file each test run,
but there are only 500 tests and AFAIU it is a temporary solution. 
What is the plan for the final one?

> 3. Since CLI flags can be used for LuaJIT testing now, <utils.selfrun>
> need to be adjusted[5] to respect the passed flags in child process.
> 
> This part LGTM, so if nobody is against the version I've checked to the
> branch[1], then I apply it to the trunk after your and Sergos approval.
> 

LGTM.
Sergos


> On 04.03.21, Sergey Kaplun wrote:
>> WARNING: This patch doesn't require full and precise review now.
>> 
>> This draft should be structured (commits at least) from test
>> suite to test suite if necessary.
>> 
>> You can complain test suites with the following command, for example:
>> | $ diff --color -urZ test/PUC-Lua-5.1-tests/ ~/Downloads/lua5.1-tests/
>> 
>> Branch: https://github.com/tarantool/luajit/tree/skaplun/gh-4473-adopt-luavela-test-suites
>> Tarantool's branch: https://github.com/tarantool/tarantool/tree/skaplun/gh-4473-adopt-luavela-test-suites
>> Epic: https://github.com/tarantool/tarantool/issues/4473
>> Issues:
>> * https://github.com/tarantool/tarantool/issues/5845
>> * https://github.com/tarantool/tarantool/issues/4064
>> * https://github.com/tarantool/tarantool/issues/5844
>> 
>> CI is red due to ASan failure [0] for PUC-Lua-5.1 test suite.
>> Looks related to https://github.com/tarantool/tarantool/issues/5747,
>> but it is hard to tell without backtrace.
>> 
>> Locally, I get tons of errors like this for each of newly added test
>> suites:
>> | ==31930==WARNING: ASan is ignoring requested __asan_handle_no_return: stack top: 0x7fffbb603000; bottom 0x7f4e271fd000; size: 0x00b194406000 (762696458240)
>> | False positive error reports may follow
>> | For details see https://github.com/google/sanitizers/issues/189
>> 
>> After that there are failures like:
>> 
>> | ==24658==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7f6b741fefa8 at pc 0x000000c91926 bp 0x7f6b741fec90 sp 0x7f6b741fec88
>> | READ of size 8 at 0x7f6b741fefa8 thread T0
>> |     #0 0xc91925 in lj_strfmt_pushvf /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_strfmt.c:438:23
>> |     #1 0xc6f8fe in lj_err_lex /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_err.c:651:9
>> |     #2 0xce0fa1 in lj_lex_error /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_lex.c:495:3
>> |     #3 0xce3285 in err_token /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_parse.c:175:3
>> |     #4 0xcf27bc in parse_stmt /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_parse.c
>> |     #5 0xce3ceb in parse_chunk /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_parse.c:2684:14
>> |     #6 0xce3ceb in lj_parse /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_parse.c:2717:3
>> |     #7 0xc7eeaa in cpparser /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_load.c:41:29
>> |     #8 0xd8a6b7 in lj_vm_cpcall /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/build/third_party/luajit/src/lj_vm.S:1191
>> |     #9 0xc7fed6 in lua_loadx /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_load.c:58:12
>> |     #10 0xc7fed6 in luaL_loadbufferx /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_load.c:143:10
>> |     #11 0xca9b12 in lj_cf_load /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lib_base.c:401:14
>> |     #12 0xd8a2fa in lj_BC_FUNCC /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/build/third_party/luajit/src/lj_vm.S:811
>> |     #13 0xc5be1f in lua_pcall /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_api.c:1158:12
>> |     #14 0xb2ad71 in luaT_call /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/src/lua/utils.c:1022:6
>> |     #15 0xb1532c in lua_main /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/src/lua/init.c:559:11
>> |     #16 0xb14c9a in run_script_f /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/src/lua/init.c:634:7
>> |     #17 0x526d96 in fiber_cxx_invoke(int (*)(__va_list_tag*), __va_list_tag*) /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/src/lib/core/fiber.h:882:10
>> |     #18 0xb7f688 in fiber_loop /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/src/lib/core/fiber.c:879:18
>> |     #19 0x14b3b10 in coro_init /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/coro/coro.c:110:3
>> |
>> | Address 0x7f6b741fefa8 is a wild pointer.
>> | SUMMARY: AddressSanitizer: stack-buffer-overflow /home/burii/builds_workspace/tarantool/gh-4473-adopt-luavela-test-suites/third_party/luajit/src/lj_strfmt.c:438:23 in lj_strfmt_pushvf
>> | Shadow bytes around the buggy address:
>> |   0x0fedee837da0: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
>> |   0x0fedee837db0: 00 00 00 f3 f3 f3 f3 f3 00 00 00 00 00 00 00 00
>> |   0x0fedee837dc0: f1 f1 f1 f1 00 00 00 00 00 00 00 04 f3 f3 f3 f3
>> |   0x0fedee837dd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> |   0x0fedee837de0: f1 f1 f1 f1 00 00 00 f3 f3 f3 f3 f3 f2 f2 f2 f2
>> | =>0x0fedee837df0: f8 f8 f8 f8 f3[f3]f3 f3 00 00 00 00 00 00 00 00
>> |   0x0fedee837e00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> |   0x0fedee837e10: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 f8 f8 f8 f2
>> |   0x0fedee837e20: f2 f2 f2 f2 f8 f8 f8 f2 f2 f2 f2 f2 f8 f8 f8 f8
>> |   0x0fedee837e30: f2 f2 f2 f2 f8 f8 f8 f2 f2 f2 f2 f2 f8 f8 f8 f2
>> |   0x0fedee837e40: f2 f2 f2 f2 f8 f8 f8 f2 f2 f2 f2 f2 f8 f8 f8 f2
>> | Shadow byte legend (one shadow byte represents 8 application bytes):
>> |   Addressable:           00
>> |   Partially addressable: 01 02 03 04 05 06 07 
>> |   Heap left redzone:       fa
>> |   Freed heap region:       fd
>> |   Stack left redzone:      f1
>> |   Stack mid redzone:       f2
>> |   Stack right redzone:     f3
>> |   Stack after return:      f5
>> |   Stack use after scope:   f8
>> 
>> It can be simply reproduce locally with:
>> | $ ASAN=ON LSAN_OPTIONS=suppressions=asan/lsan.supp ASAN_OPTIONS=heap_profile=0:unmap_shadow_on_exit=1:detect_invalid_pointer_pairs=1:symbolize=1:detect_leaks=1:dump_instruction_bytes=1:print_suppressions=0:asan_stack=0 src/tarantool -e 'prog = [[ do]] for _=1,3 do pcall(loadstring(string.sub(prog, 1, _))) end'
>> 
>> It may be the reason of failures too, see [1][2].
>> 
>> According to [3], there is no any way except to compile with -asan-stack
>> flag, but it looks like overkill. So I propose to exclude PUC-Lua-5.1
>> test suite from ASan job for now (at least this is out of scoupe of the
>> original issue).
>> 
>> Mergen Imeev (8):
>>  test: add LuaJIT-test-cleanup test suite
>>  test: change tests to match de5568e
>>  test: change tests to match c198167
>>  test: change tests to match 5a61e1a
>>  test: change LuaJIT suite tests to match b4e6bf0
>>  test: adjust LuaJIT test suite for Tarantool
>>  test: add lua-Harness test suite
>>  test: adjust lua-Harness test suite for Tarantool
>> 
>> Sergey Kaplun (7):
>>  test: add PUC-Rio Lua 5.1 test suite
>>  test: adapt PUC-Rio Lua 5.1 test suite for LuaJIT
>>  test: adapt Lua 5.1 test suite for Tarantool
>>  test: disable 305-utf8 of lua-Harness suite
>>  test: disable 241-standalone of lua-Harness suite
>>  test: disable 411-luajit of lua-Harness suite
>>  test: skip test for getenv in 309-os.t
>> 
>> .gitignore                                    |    1 +
>> .luacheckrc                                   |    7 +-
>> CMakeLists.txt                                |    8 +
>> test/CMakeLists.txt                           |    6 +
>> test/LuaJIT-tests/CMakeLists.txt              |   20 +
>> test/LuaJIT-tests/README.md                   |  110 ++
>> test/LuaJIT-tests/bc/constov.lua              |   16 +
>> test/LuaJIT-tests/bc/index                    |    1 +
>> test/LuaJIT-tests/common/expect_error.lua     |   16 +
>> test/LuaJIT-tests/common/ffi_util.inc         |   41 +
>> .../common/test_runner_canary.lua             |    1 +
>> test/LuaJIT-tests/computations.lua            |  113 ++
>> test/LuaJIT-tests/index                       |    6 +
>> test/LuaJIT-tests/lang/andor.lua              |   61 +
>> test/LuaJIT-tests/lang/assignment.lua         |   46 +
>> test/LuaJIT-tests/lang/compare.lua            |  323 +++++
>> test/LuaJIT-tests/lang/compare_nan.lua        |   99 ++
>> test/LuaJIT-tests/lang/concat.lua             |  112 ++
>> test/LuaJIT-tests/lang/constant/index         |    2 +
>> test/LuaJIT-tests/lang/constant/number.lua    |   12 +
>> test/LuaJIT-tests/lang/constant/table.lua     |   15 +
>> test/LuaJIT-tests/lang/coroutine.lua          |    8 +
>> test/LuaJIT-tests/lang/for.lua                |   45 +
>> test/LuaJIT-tests/lang/gc.lua                 |   42 +
>> test/LuaJIT-tests/lang/goto.lua               |  149 +++
>> test/LuaJIT-tests/lang/index                  |   18 +
>> test/LuaJIT-tests/lang/length.lua             |   23 +
>> test/LuaJIT-tests/lang/meta/arith.lua         |  118 ++
>> test/LuaJIT-tests/lang/meta/arith_jit.lua     |   68 +
>> test/LuaJIT-tests/lang/meta/call.lua          |   81 ++
>> test/LuaJIT-tests/lang/meta/cat.lua           |   61 +
>> test/LuaJIT-tests/lang/meta/comp.lua          |  120 ++
>> test/LuaJIT-tests/lang/meta/comp_jit.lua      |  104 ++
>> test/LuaJIT-tests/lang/meta/debuginfo.lua     |   81 ++
>> test/LuaJIT-tests/lang/meta/eq.lua            |   30 +
>> test/LuaJIT-tests/lang/meta/eq_jit.lua        |   35 +
>> test/LuaJIT-tests/lang/meta/framegap.lua      |   24 +
>> test/LuaJIT-tests/lang/meta/index             |   14 +
>> test/LuaJIT-tests/lang/meta/index.lua         |   60 +
>> test/LuaJIT-tests/lang/meta/len.lua           |   42 +
>> test/LuaJIT-tests/lang/meta/newindex.lua      |   69 +
>> test/LuaJIT-tests/lang/meta/nomm.lua          |   21 +
>> test/LuaJIT-tests/lang/modulo.lua             |   46 +
>> test/LuaJIT-tests/lang/self.lua               |   19 +
>> test/LuaJIT-tests/lang/table.lua              |   32 +
>> test/LuaJIT-tests/lang/tail_recursion.lua     |   20 +
>> test/LuaJIT-tests/lang/upvalue/closure.lua    |   84 ++
>> test/LuaJIT-tests/lang/upvalue/index          |    1 +
>> test/LuaJIT-tests/lang/vararg_jit.lua         |   95 ++
>> test/LuaJIT-tests/lib/base/assert.lua         |   33 +
>> test/LuaJIT-tests/lib/base/error.lua          |   43 +
>> test/LuaJIT-tests/lib/base/getfenv.lua        |   13 +
>> .../LuaJIT-tests/lib/base/getsetmetatable.lua |   33 +
>> test/LuaJIT-tests/lib/base/index              |   11 +
>> test/LuaJIT-tests/lib/base/ipairs.lua         |   41 +
>> test/LuaJIT-tests/lib/base/next.lua           |   17 +
>> test/LuaJIT-tests/lib/base/pairs.lua          |   73 ++
>> test/LuaJIT-tests/lib/base/pcall_jit.lua      |   74 ++
>> test/LuaJIT-tests/lib/base/select.lua         |  105 ++
>> .../lib/base/tonumber_tostring.lua            |   81 ++
>> test/LuaJIT-tests/lib/base/xpcall_jit.lua     |   83 ++
>> test/LuaJIT-tests/lib/bit.lua                 |   98 ++
>> test/LuaJIT-tests/lib/contents.lua            |  171 +++
>> test/LuaJIT-tests/lib/coroutine/index         |    1 +
>> test/LuaJIT-tests/lib/coroutine/yield.lua     |  109 ++
>> test/LuaJIT-tests/lib/ffi/bit64.lua           |  130 ++
>> test/LuaJIT-tests/lib/ffi/cdata_var.lua       |   47 +
>> test/LuaJIT-tests/lib/ffi/copy_fill.lua       |   64 +
>> test/LuaJIT-tests/lib/ffi/err.lua             |   35 +
>> test/LuaJIT-tests/lib/ffi/ffi_arith_ptr.lua   |  106 ++
>> test/LuaJIT-tests/lib/ffi/ffi_bitfield.lua    |  108 ++
>> test/LuaJIT-tests/lib/ffi/ffi_call.lua        |  266 ++++
>> test/LuaJIT-tests/lib/ffi/ffi_callback.lua    |  158 +++
>> test/LuaJIT-tests/lib/ffi/ffi_const.lua       |  113 ++
>> test/LuaJIT-tests/lib/ffi/ffi_convert.lua     |  787 +++++++++++
>> test/LuaJIT-tests/lib/ffi/ffi_enum.lua        |   57 +
>> .../lib/ffi/ffi_gcstep_recursive.lua          |   66 +
>> test/LuaJIT-tests/lib/ffi/ffi_jit_arith.lua   |  155 +++
>> test/LuaJIT-tests/lib/ffi/ffi_jit_call.lua    |  154 +++
>> test/LuaJIT-tests/lib/ffi/ffi_jit_conv.lua    |  277 ++++
>> test/LuaJIT-tests/lib/ffi/ffi_lex_number.lua  |   51 +
>> test/LuaJIT-tests/lib/ffi/ffi_metatype.lua    |  245 ++++
>> test/LuaJIT-tests/lib/ffi/ffi_new.lua         |  106 ++
>> test/LuaJIT-tests/lib/ffi/ffi_parse_array.lua |   78 ++
>> test/LuaJIT-tests/lib/ffi/ffi_parse_basic.lua |  131 ++
>> test/LuaJIT-tests/lib/ffi/ffi_parse_cdef.lua  |   77 ++
>> .../LuaJIT-tests/lib/ffi/ffi_parse_struct.lua |  259 ++++
>> test/LuaJIT-tests/lib/ffi/ffi_tabov.lua       |   12 +
>> test/LuaJIT-tests/lib/ffi/index               |   12 +
>> test/LuaJIT-tests/lib/ffi/istype.lua          |   88 ++
>> test/LuaJIT-tests/lib/ffi/jit_array.lua       |  104 ++
>> test/LuaJIT-tests/lib/ffi/jit_complex.lua     |  109 ++
>> test/LuaJIT-tests/lib/ffi/jit_misc.lua        |  109 ++
>> test/LuaJIT-tests/lib/ffi/jit_struct.lua      |  201 +++
>> test/LuaJIT-tests/lib/ffi/meta_tostring.lua   |   55 +
>> test/LuaJIT-tests/lib/ffi/redir.lua           |   19 +
>> test/LuaJIT-tests/lib/ffi/type_punning.lua    |  138 ++
>> test/LuaJIT-tests/lib/index                   |    8 +
>> test/LuaJIT-tests/lib/math/abs.lua            |   16 +
>> test/LuaJIT-tests/lib/math/constants.lua      |    8 +
>> test/LuaJIT-tests/lib/math/index              |    3 +
>> test/LuaJIT-tests/lib/math/random.lua         |   47 +
>> test/LuaJIT-tests/lib/string/byte.lua         |   92 ++
>> test/LuaJIT-tests/lib/string/char.lua         |   29 +
>> test/LuaJIT-tests/lib/string/dump.lua         |   31 +
>> test/LuaJIT-tests/lib/string/format/index     |    1 +
>> test/LuaJIT-tests/lib/string/format/num.lua   |  184 +++
>> test/LuaJIT-tests/lib/string/index            |   11 +
>> test/LuaJIT-tests/lib/string/len.lua          |   14 +
>> test/LuaJIT-tests/lib/string/lower_upper.lua  |   51 +
>> test/LuaJIT-tests/lib/string/metatable.lua    |    3 +
>> .../lib/string/multiple_functions.lua         |   16 +
>> test/LuaJIT-tests/lib/string/rep.lua          |   68 +
>> test/LuaJIT-tests/lib/string/reverse.lua      |   13 +
>> test/LuaJIT-tests/lib/string/sub.lua          |  189 +++
>> test/LuaJIT-tests/lib/table/concat.lua        |   55 +
>> test/LuaJIT-tests/lib/table/index             |    6 +
>> test/LuaJIT-tests/lib/table/insert.lua        |   17 +
>> test/LuaJIT-tests/lib/table/misc.lua          |   58 +
>> test/LuaJIT-tests/lib/table/new.lua           |   11 +
>> test/LuaJIT-tests/lib/table/pack.lua          |    7 +
>> test/LuaJIT-tests/lib/table/remove.lua        |   42 +
>> test/LuaJIT-tests/lib/table/sort.lua          |   27 +
>> test/LuaJIT-tests/misc/alias_alloc.lua        |   54 +
>> test/LuaJIT-tests/misc/api_call.lua           |   98 ++
>> test/LuaJIT-tests/misc/catch_wrap.lua         |   45 +
>> test/LuaJIT-tests/misc/coro_traceback.lua     |    8 +
>> test/LuaJIT-tests/misc/coro_yield.lua         |  111 ++
>> test/LuaJIT-tests/misc/debug_gc.lua           |   47 +
>> test/LuaJIT-tests/misc/dualnum.lua            |   47 +
>> test/LuaJIT-tests/misc/for_dir.lua            |   13 +
>> test/LuaJIT-tests/misc/fori_coerce.lua        |   33 +
>> test/LuaJIT-tests/misc/gc_rechain.lua         |   32 +
>> test/LuaJIT-tests/misc/gc_trace.lua           |   37 +
>> test/LuaJIT-tests/misc/gcstep.lua             |   33 +
>> test/LuaJIT-tests/misc/hook_active.lua        |   95 ++
>> test/LuaJIT-tests/misc/hook_line.lua          |   41 +
>> test/LuaJIT-tests/misc/hook_norecord.lua      |   12 +
>> test/LuaJIT-tests/misc/hook_record.lua        |    8 +
>> test/LuaJIT-tests/misc/hook_top.lua           |   55 +
>> test/LuaJIT-tests/misc/jit_flush.lua          |   50 +
>> test/LuaJIT-tests/misc/lightud.lua            |   88 ++
>> test/LuaJIT-tests/misc/loop_unroll.lua        |   35 +
>> test/LuaJIT-tests/misc/parse_comp.lua         |   13 +
>> test/LuaJIT-tests/misc/parse_esc.lua          |    7 +
>> test/LuaJIT-tests/misc/parse_misc.lua         |   31 +
>> test/LuaJIT-tests/misc/phi_conv.lua           |   53 +
>> test/LuaJIT-tests/misc/recurse_deep.lua       |   29 +
>> test/LuaJIT-tests/misc/recurse_tail.lua       |   22 +
>> test/LuaJIT-tests/misc/stack_gc.lua           |   15 +
>> test/LuaJIT-tests/misc/stack_purge.lua        |   25 +
>> test/LuaJIT-tests/misc/stackov.lua            |   40 +
>> test/LuaJIT-tests/misc/stackovc.lua           |    4 +
>> test/LuaJIT-tests/misc/tcall_base.lua         |   20 +
>> test/LuaJIT-tests/misc/tcall_loop.lua         |    8 +
>> test/LuaJIT-tests/misc/tonumber_scan.lua      |  180 +++
>> test/LuaJIT-tests/misc/uclo.lua               |   91 ++
>> test/LuaJIT-tests/misc/unordered_jit.lua      |   96 ++
>> test/LuaJIT-tests/misc/wbarrier.lua           |    7 +
>> test/LuaJIT-tests/misc/wbarrier_jit.lua       |   18 +
>> test/LuaJIT-tests/misc/wbarrier_obar.lua      |   22 +
>> test/LuaJIT-tests/opt/dse/array.lua           |  197 +++
>> test/LuaJIT-tests/opt/dse/field.lua           |   70 +
>> test/LuaJIT-tests/opt/dse/index               |    2 +
>> test/LuaJIT-tests/opt/fold/index              |    1 +
>> test/LuaJIT-tests/opt/fold/kfold.lua          |   81 ++
>> test/LuaJIT-tests/opt/fuse.lua                |    5 +
>> test/LuaJIT-tests/opt/fwd/hrefk_rollback.lua  |   32 +
>> test/LuaJIT-tests/opt/fwd/index               |    3 +
>> test/LuaJIT-tests/opt/fwd/tnew_tdup.lua       |   69 +
>> test/LuaJIT-tests/opt/fwd/upval.lua           |   50 +
>> test/LuaJIT-tests/opt/index                   |    6 +
>> test/LuaJIT-tests/opt/loop/index              |    1 +
>> test/LuaJIT-tests/opt/loop/unroll.lua         |   32 +
>> test/LuaJIT-tests/opt/sink/alloc.lua          |  126 ++
>> test/LuaJIT-tests/opt/sink/ffi.lua            |  121 ++
>> test/LuaJIT-tests/opt/sink/ffi_nosink.lua     |   45 +
>> test/LuaJIT-tests/opt/sink/index              |    4 +
>> test/LuaJIT-tests/opt/sink/nosink.lua         |  109 ++
>> test/LuaJIT-tests/src/cpptest.cpp             |  129 ++
>> test/LuaJIT-tests/src/ctest.c                 |  339 +++++
>> test/LuaJIT-tests/sysdep/catch_cpp.lua        |   71 +
>> test/LuaJIT-tests/sysdep/ffi_include_gtk.lua  |    9 +
>> test/LuaJIT-tests/sysdep/ffi_include_std.lua  |   36 +
>> test/LuaJIT-tests/sysdep/ffi_lib_c.lua        |   87 ++
>> test/LuaJIT-tests/sysdep/ffi_lib_z.lua        |  107 ++
>> test/LuaJIT-tests/test.lua                    |  416 ++++++
>> test/LuaJIT-tests/trace/exit_frame.lua        |   79 ++
>> test/LuaJIT-tests/trace/exit_growstack.lua    |   28 +
>> test/LuaJIT-tests/trace/exit_jfuncf.lua       |   30 +
>> test/LuaJIT-tests/trace/gc64_slot_revival.lua |   18 +
>> test/LuaJIT-tests/trace/index                 |    7 +
>> test/LuaJIT-tests/trace/phi/copyspill.lua     |   53 +
>> test/LuaJIT-tests/trace/phi/index             |    3 +
>> test/LuaJIT-tests/trace/phi/ref.lua           |  131 ++
>> test/LuaJIT-tests/trace/phi/rotate.lua        |  149 +++
>> test/LuaJIT-tests/trace/snap.lua              |   47 +
>> test/LuaJIT-tests/trace/stitch.lua            |   19 +
>> .../unportable/ffi_arith_int64.lua            |   68 +
>> test/LuaJIT-tests/unportable/math_special.lua |   55 +
>> test/PUC-Lua-5.1-tests/CMakeLists.txt         |   92 ++
>> test/PUC-Lua-5.1-tests/README                 |   41 +
>> test/PUC-Lua-5.1-tests/all.lua                |  145 +++
>> 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            |  432 +++++++
>> test/PUC-Lua-5.1-tests/code.lua               |  143 ++
>> test/PUC-Lua-5.1-tests/constructs.lua         |  247 ++++
>> test/PUC-Lua-5.1-tests/db.lua                 |  538 ++++++++
>> test/PUC-Lua-5.1-tests/errors.lua             |  264 ++++
>> 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                 |  320 +++++
>> 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               |  195 +++
>> test/PUC-Lua-5.1-tests/math.lua               |  213 +++
>> test/PUC-Lua-5.1-tests/nextvar.lua            |  403 ++++++
>> test/PUC-Lua-5.1-tests/pm.lua                 |  281 ++++
>> 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 ++
>> test/lua-Harness-tests/000-sanity.t           |   54 +
>> test/lua-Harness-tests/001-if.t               |   88 ++
>> test/lua-Harness-tests/002-table.t            |   67 +
>> test/lua-Harness-tests/011-while.t            |   89 ++
>> test/lua-Harness-tests/012-repeat.t           |   85 ++
>> test/lua-Harness-tests/014-fornum.t           |  151 +++
>> test/lua-Harness-tests/015-forlist.t          |  111 ++
>> test/lua-Harness-tests/090-tap.t              |   37 +
>> test/lua-Harness-tests/091-profile.t          |   45 +
>> test/lua-Harness-tests/101-boolean.t          |  127 ++
>> test/lua-Harness-tests/102-function.t         |  206 +++
>> test/lua-Harness-tests/103-nil.t              |  127 ++
>> test/lua-Harness-tests/104-number.t           |  246 ++++
>> test/lua-Harness-tests/105-string.t           |  277 ++++
>> test/lua-Harness-tests/106-table.t            |  135 ++
>> test/lua-Harness-tests/107-thread.t           |  135 ++
>> test/lua-Harness-tests/108-userdata.t         |  132 ++
>> test/lua-Harness-tests/200-examples.t         |  104 ++
>> test/lua-Harness-tests/201-assign.t           |  150 +++
>> test/lua-Harness-tests/202-expr.t             |  157 +++
>> test/lua-Harness-tests/203-lexico.t           |  147 +++
>> test/lua-Harness-tests/204-grammar.t          |  233 ++++
>> test/lua-Harness-tests/211-scope.t            |   86 ++
>> test/lua-Harness-tests/212-function.t         |  288 +++++
>> test/lua-Harness-tests/213-closure.t          |   98 ++
>> test/lua-Harness-tests/214-coroutine.t        |  244 ++++
>> test/lua-Harness-tests/221-table.t            |  120 ++
>> test/lua-Harness-tests/222-constructor.t      |  119 ++
>> test/lua-Harness-tests/223-iterator.t         |  203 +++
>> test/lua-Harness-tests/231-metatable.t        |  602 +++++++++
>> test/lua-Harness-tests/232-object.t           |  314 +++++
>> .../241-standalone.t.disabled                 |  269 ++++
>> test/lua-Harness-tests/242-luac.t             |  341 +++++
>> test/lua-Harness-tests/301-basic.t            |  859 ++++++++++++
>> test/lua-Harness-tests/303-package.t          |  290 +++++
>> test/lua-Harness-tests/304-string.t           |  633 +++++++++
>> test/lua-Harness-tests/305-utf8.t.disabled    |   55 +
>> test/lua-Harness-tests/306-table.t            |  372 ++++++
>> test/lua-Harness-tests/307-math.t             |  375 ++++++
>> test/lua-Harness-tests/308-io.t               |  397 ++++++
>> test/lua-Harness-tests/309-os.t               |  275 ++++
>> test/lua-Harness-tests/310-debug.t            |  322 +++++
>> test/lua-Harness-tests/311-bit32.t            |  127 ++
>> test/lua-Harness-tests/314-regex.t            |  222 ++++
>> test/lua-Harness-tests/320-stdin.t            |  133 ++
>> test/lua-Harness-tests/401-bitop.t            |  106 ++
>> test/lua-Harness-tests/402-ffi.t              |  142 ++
>> test/lua-Harness-tests/403-jit.t              |  163 +++
>> test/lua-Harness-tests/404-ext.t              |  171 +++
>> test/lua-Harness-tests/411-luajit.t.disabled  |  211 +++
>> test/lua-Harness-tests/CMakeLists.txt         |   62 +
>> test/lua-Harness-tests/lexico52/lexico.t      |   45 +
>> test/lua-Harness-tests/lexico53/boolean.t     |   43 +
>> test/lua-Harness-tests/lexico53/function.t    |   66 +
>> test/lua-Harness-tests/lexico53/lexico.t      |   30 +
>> test/lua-Harness-tests/lexico53/nil.t         |   43 +
>> test/lua-Harness-tests/lexico53/number.t      |  181 +++
>> test/lua-Harness-tests/lexico53/string.t      |  169 +++
>> test/lua-Harness-tests/lexico53/table.t       |   43 +
>> test/lua-Harness-tests/lexico53/thread.t      |   45 +
>> test/lua-Harness-tests/lexico53/userdata.t    |   45 +
>> test/lua-Harness-tests/lexico53/utf8.t        |  179 +++
>> test/lua-Harness-tests/lexico54/lexico.t      |   19 +
>> test/lua-Harness-tests/lexico54/metatable.t   |   38 +
>> test/lua-Harness-tests/lexico54/utf8.t        |   54 +
>> test/lua-Harness-tests/lexicojit/basic.t      |   27 +
>> test/lua-Harness-tests/lexicojit/ext.t        |   52 +
>> test/lua-Harness-tests/lexicojit/lexico.t     |   32 +
>> test/lua-Harness-tests/profile.lua            |   53 +
>> test/lua-Harness-tests/profile_lua51.lua      |   46 +
>> .../profile_lua51_strict.lua                  |   46 +
>> test/lua-Harness-tests/profile_lua52.lua      |   46 +
>> .../profile_lua52_strict.lua                  |   46 +
>> test/lua-Harness-tests/profile_lua53.lua      |   52 +
>> .../profile_lua53_noconv.lua                  |   55 +
>> .../profile_lua53_strict.lua                  |   52 +
>> test/lua-Harness-tests/profile_lua54.lua      |   52 +
>> .../profile_lua54_noconv.lua                  |   55 +
>> .../profile_lua54_strict.lua                  |   53 +
>> test/lua-Harness-tests/profile_luajit20.lua   |   53 +
>> .../profile_luajit20_compat52.lua             |   53 +
>> test/lua-Harness-tests/profile_luajit21.lua   |   53 +
>> .../profile_luajit21_compat52.lua             |   53 +
>> test/lua-Harness-tests/profile_openresty.lua  |   53 +
>> test/lua-Harness-tests/profile_ravi.lua       |   58 +
>> test/lua-Harness-tests/profile_tiny_fork.lua  |   60 +
>> test/lua-Harness-tests/rx_captures            |   13 +
>> test/lua-Harness-tests/rx_charclass           |   38 +
>> test/lua-Harness-tests/rx_metachars           |  117 ++
>> test/lua-Harness-tests/tap_harness.lua        |  204 +++
>> 322 files changed, 34168 insertions(+), 2 deletions(-)
>> create mode 100644 test/LuaJIT-tests/CMakeLists.txt
>> create mode 100644 test/LuaJIT-tests/README.md
>> create mode 100644 test/LuaJIT-tests/bc/constov.lua
>> create mode 100644 test/LuaJIT-tests/bc/index
>> create mode 100644 test/LuaJIT-tests/common/expect_error.lua
>> create mode 100644 test/LuaJIT-tests/common/ffi_util.inc
>> create mode 100644 test/LuaJIT-tests/common/test_runner_canary.lua
>> create mode 100644 test/LuaJIT-tests/computations.lua
>> create mode 100644 test/LuaJIT-tests/index
>> create mode 100644 test/LuaJIT-tests/lang/andor.lua
>> create mode 100644 test/LuaJIT-tests/lang/assignment.lua
>> create mode 100644 test/LuaJIT-tests/lang/compare.lua
>> create mode 100644 test/LuaJIT-tests/lang/compare_nan.lua
>> create mode 100644 test/LuaJIT-tests/lang/concat.lua
>> create mode 100644 test/LuaJIT-tests/lang/constant/index
>> create mode 100644 test/LuaJIT-tests/lang/constant/number.lua
>> create mode 100644 test/LuaJIT-tests/lang/constant/table.lua
>> create mode 100644 test/LuaJIT-tests/lang/coroutine.lua
>> create mode 100644 test/LuaJIT-tests/lang/for.lua
>> create mode 100644 test/LuaJIT-tests/lang/gc.lua
>> create mode 100644 test/LuaJIT-tests/lang/goto.lua
>> create mode 100644 test/LuaJIT-tests/lang/index
>> create mode 100644 test/LuaJIT-tests/lang/length.lua
>> create mode 100644 test/LuaJIT-tests/lang/meta/arith.lua
>> create mode 100644 test/LuaJIT-tests/lang/meta/arith_jit.lua
>> create mode 100644 test/LuaJIT-tests/lang/meta/call.lua
>> create mode 100644 test/LuaJIT-tests/lang/meta/cat.lua
>> create mode 100644 test/LuaJIT-tests/lang/meta/comp.lua
>> create mode 100644 test/LuaJIT-tests/lang/meta/comp_jit.lua
>> create mode 100644 test/LuaJIT-tests/lang/meta/debuginfo.lua
>> create mode 100644 test/LuaJIT-tests/lang/meta/eq.lua
>> create mode 100644 test/LuaJIT-tests/lang/meta/eq_jit.lua
>> create mode 100644 test/LuaJIT-tests/lang/meta/framegap.lua
>> create mode 100644 test/LuaJIT-tests/lang/meta/index
>> create mode 100644 test/LuaJIT-tests/lang/meta/index.lua
>> create mode 100644 test/LuaJIT-tests/lang/meta/len.lua
>> create mode 100644 test/LuaJIT-tests/lang/meta/newindex.lua
>> create mode 100644 test/LuaJIT-tests/lang/meta/nomm.lua
>> create mode 100644 test/LuaJIT-tests/lang/modulo.lua
>> create mode 100644 test/LuaJIT-tests/lang/self.lua
>> create mode 100644 test/LuaJIT-tests/lang/table.lua
>> create mode 100644 test/LuaJIT-tests/lang/tail_recursion.lua
>> create mode 100644 test/LuaJIT-tests/lang/upvalue/closure.lua
>> create mode 100644 test/LuaJIT-tests/lang/upvalue/index
>> create mode 100644 test/LuaJIT-tests/lang/vararg_jit.lua
>> create mode 100644 test/LuaJIT-tests/lib/base/assert.lua
>> create mode 100644 test/LuaJIT-tests/lib/base/error.lua
>> create mode 100644 test/LuaJIT-tests/lib/base/getfenv.lua
>> create mode 100644 test/LuaJIT-tests/lib/base/getsetmetatable.lua
>> create mode 100644 test/LuaJIT-tests/lib/base/index
>> create mode 100644 test/LuaJIT-tests/lib/base/ipairs.lua
>> create mode 100644 test/LuaJIT-tests/lib/base/next.lua
>> create mode 100644 test/LuaJIT-tests/lib/base/pairs.lua
>> create mode 100644 test/LuaJIT-tests/lib/base/pcall_jit.lua
>> create mode 100644 test/LuaJIT-tests/lib/base/select.lua
>> create mode 100644 test/LuaJIT-tests/lib/base/tonumber_tostring.lua
>> create mode 100644 test/LuaJIT-tests/lib/base/xpcall_jit.lua
>> create mode 100644 test/LuaJIT-tests/lib/bit.lua
>> create mode 100644 test/LuaJIT-tests/lib/contents.lua
>> create mode 100644 test/LuaJIT-tests/lib/coroutine/index
>> create mode 100644 test/LuaJIT-tests/lib/coroutine/yield.lua
>> create mode 100644 test/LuaJIT-tests/lib/ffi/bit64.lua
>> create mode 100644 test/LuaJIT-tests/lib/ffi/cdata_var.lua
>> create mode 100644 test/LuaJIT-tests/lib/ffi/copy_fill.lua
>> create mode 100644 test/LuaJIT-tests/lib/ffi/err.lua
>> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_arith_ptr.lua
>> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_bitfield.lua
>> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_call.lua
>> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_callback.lua
>> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_const.lua
>> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_convert.lua
>> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_enum.lua
>> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_gcstep_recursive.lua
>> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_jit_arith.lua
>> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_jit_call.lua
>> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_jit_conv.lua
>> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_lex_number.lua
>> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_metatype.lua
>> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_new.lua
>> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_parse_array.lua
>> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_parse_basic.lua
>> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_parse_cdef.lua
>> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_parse_struct.lua
>> create mode 100644 test/LuaJIT-tests/lib/ffi/ffi_tabov.lua
>> create mode 100644 test/LuaJIT-tests/lib/ffi/index
>> create mode 100644 test/LuaJIT-tests/lib/ffi/istype.lua
>> create mode 100644 test/LuaJIT-tests/lib/ffi/jit_array.lua
>> create mode 100644 test/LuaJIT-tests/lib/ffi/jit_complex.lua
>> create mode 100644 test/LuaJIT-tests/lib/ffi/jit_misc.lua
>> create mode 100644 test/LuaJIT-tests/lib/ffi/jit_struct.lua
>> create mode 100644 test/LuaJIT-tests/lib/ffi/meta_tostring.lua
>> create mode 100644 test/LuaJIT-tests/lib/ffi/redir.lua
>> create mode 100644 test/LuaJIT-tests/lib/ffi/type_punning.lua
>> create mode 100644 test/LuaJIT-tests/lib/index
>> create mode 100644 test/LuaJIT-tests/lib/math/abs.lua
>> create mode 100644 test/LuaJIT-tests/lib/math/constants.lua
>> create mode 100644 test/LuaJIT-tests/lib/math/index
>> create mode 100644 test/LuaJIT-tests/lib/math/random.lua
>> create mode 100644 test/LuaJIT-tests/lib/string/byte.lua
>> create mode 100644 test/LuaJIT-tests/lib/string/char.lua
>> create mode 100644 test/LuaJIT-tests/lib/string/dump.lua
>> create mode 100644 test/LuaJIT-tests/lib/string/format/index
>> create mode 100644 test/LuaJIT-tests/lib/string/format/num.lua
>> create mode 100644 test/LuaJIT-tests/lib/string/index
>> create mode 100644 test/LuaJIT-tests/lib/string/len.lua
>> create mode 100644 test/LuaJIT-tests/lib/string/lower_upper.lua
>> create mode 100644 test/LuaJIT-tests/lib/string/metatable.lua
>> create mode 100644 test/LuaJIT-tests/lib/string/multiple_functions.lua
>> create mode 100644 test/LuaJIT-tests/lib/string/rep.lua
>> create mode 100644 test/LuaJIT-tests/lib/string/reverse.lua
>> create mode 100644 test/LuaJIT-tests/lib/string/sub.lua
>> create mode 100644 test/LuaJIT-tests/lib/table/concat.lua
>> create mode 100644 test/LuaJIT-tests/lib/table/index
>> create mode 100644 test/LuaJIT-tests/lib/table/insert.lua
>> create mode 100644 test/LuaJIT-tests/lib/table/misc.lua
>> create mode 100644 test/LuaJIT-tests/lib/table/new.lua
>> create mode 100644 test/LuaJIT-tests/lib/table/pack.lua
>> create mode 100644 test/LuaJIT-tests/lib/table/remove.lua
>> create mode 100644 test/LuaJIT-tests/lib/table/sort.lua
>> create mode 100644 test/LuaJIT-tests/misc/alias_alloc.lua
>> create mode 100644 test/LuaJIT-tests/misc/api_call.lua
>> create mode 100644 test/LuaJIT-tests/misc/catch_wrap.lua
>> create mode 100644 test/LuaJIT-tests/misc/coro_traceback.lua
>> create mode 100644 test/LuaJIT-tests/misc/coro_yield.lua
>> create mode 100644 test/LuaJIT-tests/misc/debug_gc.lua
>> create mode 100644 test/LuaJIT-tests/misc/dualnum.lua
>> create mode 100644 test/LuaJIT-tests/misc/for_dir.lua
>> create mode 100644 test/LuaJIT-tests/misc/fori_coerce.lua
>> create mode 100644 test/LuaJIT-tests/misc/gc_rechain.lua
>> create mode 100644 test/LuaJIT-tests/misc/gc_trace.lua
>> create mode 100644 test/LuaJIT-tests/misc/gcstep.lua
>> create mode 100644 test/LuaJIT-tests/misc/hook_active.lua
>> create mode 100644 test/LuaJIT-tests/misc/hook_line.lua
>> create mode 100644 test/LuaJIT-tests/misc/hook_norecord.lua
>> create mode 100644 test/LuaJIT-tests/misc/hook_record.lua
>> create mode 100644 test/LuaJIT-tests/misc/hook_top.lua
>> create mode 100644 test/LuaJIT-tests/misc/jit_flush.lua
>> create mode 100644 test/LuaJIT-tests/misc/lightud.lua
>> create mode 100644 test/LuaJIT-tests/misc/loop_unroll.lua
>> create mode 100644 test/LuaJIT-tests/misc/parse_comp.lua
>> create mode 100644 test/LuaJIT-tests/misc/parse_esc.lua
>> create mode 100644 test/LuaJIT-tests/misc/parse_misc.lua
>> create mode 100644 test/LuaJIT-tests/misc/phi_conv.lua
>> create mode 100644 test/LuaJIT-tests/misc/recurse_deep.lua
>> create mode 100644 test/LuaJIT-tests/misc/recurse_tail.lua
>> create mode 100644 test/LuaJIT-tests/misc/stack_gc.lua
>> create mode 100644 test/LuaJIT-tests/misc/stack_purge.lua
>> create mode 100644 test/LuaJIT-tests/misc/stackov.lua
>> create mode 100644 test/LuaJIT-tests/misc/stackovc.lua
>> create mode 100644 test/LuaJIT-tests/misc/tcall_base.lua
>> create mode 100644 test/LuaJIT-tests/misc/tcall_loop.lua
>> create mode 100644 test/LuaJIT-tests/misc/tonumber_scan.lua
>> create mode 100644 test/LuaJIT-tests/misc/uclo.lua
>> create mode 100644 test/LuaJIT-tests/misc/unordered_jit.lua
>> create mode 100644 test/LuaJIT-tests/misc/wbarrier.lua
>> create mode 100644 test/LuaJIT-tests/misc/wbarrier_jit.lua
>> create mode 100644 test/LuaJIT-tests/misc/wbarrier_obar.lua
>> create mode 100644 test/LuaJIT-tests/opt/dse/array.lua
>> create mode 100644 test/LuaJIT-tests/opt/dse/field.lua
>> create mode 100644 test/LuaJIT-tests/opt/dse/index
>> create mode 100644 test/LuaJIT-tests/opt/fold/index
>> create mode 100644 test/LuaJIT-tests/opt/fold/kfold.lua
>> create mode 100644 test/LuaJIT-tests/opt/fuse.lua
>> create mode 100644 test/LuaJIT-tests/opt/fwd/hrefk_rollback.lua
>> create mode 100644 test/LuaJIT-tests/opt/fwd/index
>> create mode 100644 test/LuaJIT-tests/opt/fwd/tnew_tdup.lua
>> create mode 100644 test/LuaJIT-tests/opt/fwd/upval.lua
>> create mode 100644 test/LuaJIT-tests/opt/index
>> create mode 100644 test/LuaJIT-tests/opt/loop/index
>> create mode 100644 test/LuaJIT-tests/opt/loop/unroll.lua
>> create mode 100644 test/LuaJIT-tests/opt/sink/alloc.lua
>> create mode 100644 test/LuaJIT-tests/opt/sink/ffi.lua
>> create mode 100644 test/LuaJIT-tests/opt/sink/ffi_nosink.lua
>> create mode 100644 test/LuaJIT-tests/opt/sink/index
>> create mode 100644 test/LuaJIT-tests/opt/sink/nosink.lua
>> create mode 100644 test/LuaJIT-tests/src/cpptest.cpp
>> create mode 100644 test/LuaJIT-tests/src/ctest.c
>> create mode 100644 test/LuaJIT-tests/sysdep/catch_cpp.lua
>> create mode 100644 test/LuaJIT-tests/sysdep/ffi_include_gtk.lua
>> create mode 100644 test/LuaJIT-tests/sysdep/ffi_include_std.lua
>> create mode 100644 test/LuaJIT-tests/sysdep/ffi_lib_c.lua
>> create mode 100644 test/LuaJIT-tests/sysdep/ffi_lib_z.lua
>> create mode 100644 test/LuaJIT-tests/test.lua
>> create mode 100644 test/LuaJIT-tests/trace/exit_frame.lua
>> create mode 100644 test/LuaJIT-tests/trace/exit_growstack.lua
>> create mode 100644 test/LuaJIT-tests/trace/exit_jfuncf.lua
>> create mode 100644 test/LuaJIT-tests/trace/gc64_slot_revival.lua
>> create mode 100644 test/LuaJIT-tests/trace/index
>> create mode 100644 test/LuaJIT-tests/trace/phi/copyspill.lua
>> create mode 100644 test/LuaJIT-tests/trace/phi/index
>> create mode 100644 test/LuaJIT-tests/trace/phi/ref.lua
>> create mode 100644 test/LuaJIT-tests/trace/phi/rotate.lua
>> create mode 100644 test/LuaJIT-tests/trace/snap.lua
>> create mode 100644 test/LuaJIT-tests/trace/stitch.lua
>> create mode 100644 test/LuaJIT-tests/unportable/ffi_arith_int64.lua
>> create mode 100644 test/LuaJIT-tests/unportable/math_special.lua
>> 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/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
>> create mode 100755 test/lua-Harness-tests/000-sanity.t
>> create mode 100755 test/lua-Harness-tests/001-if.t
>> create mode 100755 test/lua-Harness-tests/002-table.t
>> create mode 100755 test/lua-Harness-tests/011-while.t
>> create mode 100755 test/lua-Harness-tests/012-repeat.t
>> create mode 100755 test/lua-Harness-tests/014-fornum.t
>> create mode 100755 test/lua-Harness-tests/015-forlist.t
>> create mode 100755 test/lua-Harness-tests/090-tap.t
>> create mode 100755 test/lua-Harness-tests/091-profile.t
>> create mode 100755 test/lua-Harness-tests/101-boolean.t
>> create mode 100755 test/lua-Harness-tests/102-function.t
>> create mode 100755 test/lua-Harness-tests/103-nil.t
>> create mode 100755 test/lua-Harness-tests/104-number.t
>> create mode 100755 test/lua-Harness-tests/105-string.t
>> create mode 100755 test/lua-Harness-tests/106-table.t
>> create mode 100755 test/lua-Harness-tests/107-thread.t
>> create mode 100755 test/lua-Harness-tests/108-userdata.t
>> create mode 100755 test/lua-Harness-tests/200-examples.t
>> create mode 100755 test/lua-Harness-tests/201-assign.t
>> create mode 100755 test/lua-Harness-tests/202-expr.t
>> create mode 100755 test/lua-Harness-tests/203-lexico.t
>> create mode 100755 test/lua-Harness-tests/204-grammar.t
>> create mode 100755 test/lua-Harness-tests/211-scope.t
>> create mode 100755 test/lua-Harness-tests/212-function.t
>> create mode 100755 test/lua-Harness-tests/213-closure.t
>> create mode 100755 test/lua-Harness-tests/214-coroutine.t
>> create mode 100755 test/lua-Harness-tests/221-table.t
>> create mode 100755 test/lua-Harness-tests/222-constructor.t
>> create mode 100755 test/lua-Harness-tests/223-iterator.t
>> create mode 100755 test/lua-Harness-tests/231-metatable.t
>> create mode 100755 test/lua-Harness-tests/232-object.t
>> create mode 100755 test/lua-Harness-tests/241-standalone.t.disabled
>> create mode 100755 test/lua-Harness-tests/242-luac.t
>> create mode 100755 test/lua-Harness-tests/301-basic.t
>> create mode 100755 test/lua-Harness-tests/303-package.t
>> create mode 100755 test/lua-Harness-tests/304-string.t
>> create mode 100755 test/lua-Harness-tests/305-utf8.t.disabled
>> create mode 100755 test/lua-Harness-tests/306-table.t
>> create mode 100755 test/lua-Harness-tests/307-math.t
>> create mode 100755 test/lua-Harness-tests/308-io.t
>> create mode 100755 test/lua-Harness-tests/309-os.t
>> create mode 100755 test/lua-Harness-tests/310-debug.t
>> create mode 100755 test/lua-Harness-tests/311-bit32.t
>> create mode 100755 test/lua-Harness-tests/314-regex.t
>> create mode 100755 test/lua-Harness-tests/320-stdin.t
>> create mode 100755 test/lua-Harness-tests/401-bitop.t
>> create mode 100755 test/lua-Harness-tests/402-ffi.t
>> create mode 100755 test/lua-Harness-tests/403-jit.t
>> create mode 100755 test/lua-Harness-tests/404-ext.t
>> create mode 100755 test/lua-Harness-tests/411-luajit.t.disabled
>> create mode 100644 test/lua-Harness-tests/CMakeLists.txt
>> create mode 100644 test/lua-Harness-tests/lexico52/lexico.t
>> create mode 100644 test/lua-Harness-tests/lexico53/boolean.t
>> create mode 100644 test/lua-Harness-tests/lexico53/function.t
>> create mode 100644 test/lua-Harness-tests/lexico53/lexico.t
>> create mode 100644 test/lua-Harness-tests/lexico53/nil.t
>> create mode 100644 test/lua-Harness-tests/lexico53/number.t
>> create mode 100644 test/lua-Harness-tests/lexico53/string.t
>> create mode 100644 test/lua-Harness-tests/lexico53/table.t
>> create mode 100644 test/lua-Harness-tests/lexico53/thread.t
>> create mode 100644 test/lua-Harness-tests/lexico53/userdata.t
>> create mode 100644 test/lua-Harness-tests/lexico53/utf8.t
>> create mode 100644 test/lua-Harness-tests/lexico54/lexico.t
>> create mode 100644 test/lua-Harness-tests/lexico54/metatable.t
>> create mode 100644 test/lua-Harness-tests/lexico54/utf8.t
>> create mode 100644 test/lua-Harness-tests/lexicojit/basic.t
>> create mode 100644 test/lua-Harness-tests/lexicojit/ext.t
>> create mode 100644 test/lua-Harness-tests/lexicojit/lexico.t
>> create mode 100644 test/lua-Harness-tests/profile.lua
>> create mode 100644 test/lua-Harness-tests/profile_lua51.lua
>> create mode 100644 test/lua-Harness-tests/profile_lua51_strict.lua
>> create mode 100644 test/lua-Harness-tests/profile_lua52.lua
>> create mode 100644 test/lua-Harness-tests/profile_lua52_strict.lua
>> create mode 100644 test/lua-Harness-tests/profile_lua53.lua
>> create mode 100644 test/lua-Harness-tests/profile_lua53_noconv.lua
>> create mode 100644 test/lua-Harness-tests/profile_lua53_strict.lua
>> create mode 100644 test/lua-Harness-tests/profile_lua54.lua
>> create mode 100644 test/lua-Harness-tests/profile_lua54_noconv.lua
>> create mode 100644 test/lua-Harness-tests/profile_lua54_strict.lua
>> create mode 100644 test/lua-Harness-tests/profile_luajit20.lua
>> create mode 100644 test/lua-Harness-tests/profile_luajit20_compat52.lua
>> create mode 100644 test/lua-Harness-tests/profile_luajit21.lua
>> create mode 100644 test/lua-Harness-tests/profile_luajit21_compat52.lua
>> create mode 100644 test/lua-Harness-tests/profile_openresty.lua
>> create mode 100644 test/lua-Harness-tests/profile_ravi.lua
>> create mode 100644 test/lua-Harness-tests/profile_tiny_fork.lua
>> create mode 100644 test/lua-Harness-tests/rx_captures
>> create mode 100644 test/lua-Harness-tests/rx_charclass
>> create mode 100644 test/lua-Harness-tests/rx_metachars
>> create mode 100644 test/lua-Harness-tests/tap_harness.lua
>> 
>> -- 
>> 2.28.0
>> 
>> [0]: https://github.com/tarantool/tarantool/runs/2029452344
>> [1]: https://github.com/google/sanitizers/issues/980
>> [2]: https://github.com/google/sanitizers/issues/189
>> [3]: https://github.com/google/sanitizers/wiki/AddressSanitizerFlags
> 
> [1]: https://github.com/tarantool/luajit/tree/imun/tarantool-test
> [2]: https://github.com/tarantool/tarantool/tree/imun/luajit-test
> [3]: https://github.com/tarantool/luajit/commit/9712cc9#diff-1e7de1ae2d059d21e1dd75d5812d5a34b0222cef273b7c3a2af62eb747f9d20aR291-R307
> [4]: https://github.com/tarantool/tarantool/commit/03b04a7
> [5]: https://github.com/tarantool/luajit/commit/72f87b2
> 
> -- 
> Best regards,
> IM


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

* Re: [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites
  2021-03-10  8:09   ` Sergey Kaplun via Tarantool-patches
@ 2021-03-10 10:39     ` Igor Munkin via Tarantool-patches
  0 siblings, 0 replies; 26+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-10 10:39 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

On 10.03.21, Sergey Kaplun wrote:
> Igor,
> 
> On 10.03.21, Igor Munkin wrote:
> > Sergey,
> > 
> > I've precisely reviewed patches 04-09 and they look good. I've polished
> > a bit[1] the series, so it can be applied to the trunk out of the order.
> > CI[2] is green.
> 
> I hardly wait for the other series.
> I've assembled all issues related to PUC-Rio-Lua-5.1 test suite inside
> this [1] epic.
> 
> > 
> > BTW, I would like to leave some major points related to my review.
> > 
> 
> <snipped>
> 
> > 2. I've introduced a new CMake option: LUAJIT_TEST_INIT. You can read
> > the description here[3]. It allows to enclose the partial LUA_INIT
> > emulation, implemented via '-e dofile[[${LUAJIT_TEST_INIT}]]' and
> > obliges user to set the name of the Lua script to be run prior to the
> > testing suite[4]. By default it does nothing by reading from /dev/null.
> 
> This part is good. Why do you omit +slow flag for this test suite?

I'm too bad in copy-pasting... Thanks for catching! Added all necessary
flags, squashed, force-pushed to the branch. Diff is below.

================================================================================

diff --git a/test/LuaJIT-tests/CMakeLists.txt b/test/LuaJIT-tests/CMakeLists.txt
index d4886a4..9cd76ee 100644
--- a/test/LuaJIT-tests/CMakeLists.txt
+++ b/test/LuaJIT-tests/CMakeLists.txt
@@ -7,5 +7,6 @@ add_custom_command(TARGET LuaJIT-tests
   COMMENT "Running LuaJIT-tests"
   COMMAND
     ${LUAJIT_TEST_COMMAND} ${CMAKE_CURRENT_SOURCE_DIR}/test.lua
+    +slow +ffi +bit +jit
   WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
 )

================================================================================

> 
> > 
> > 3. Since CLI flags can be used for LuaJIT testing now, <utils.selfrun>
> > need to be adjusted[5] to respect the passed flags in child process.
> > 
> > This part LGTM, so if nobody is against the version I've checked to the
> > branch[1], then I apply it to the trunk after your and Sergos approval.
> 
> As I see on the branch there is no check of CMAKE_BUILD_TYPE variable.
> We need to disable strict only for debug build, IINM.
> Feel free to ignore.

Agree. BTW, it allows to check that Tarantool is not built with <strict>
enabled by default in Release. Fixed, squashed, force-pushed to the
branch. Diff is below.

================================================================================

diff --git a/cmake/luajit.cmake b/cmake/luajit.cmake
index e25eeb3dd..1c05e085b 100644
--- a/cmake/luajit.cmake
+++ b/cmake/luajit.cmake
@@ -37,17 +37,19 @@ set(LUAJIT_SMART_STRINGS ON CACHE BOOL
     "Harder string hashing function" FORCE)
 set(LUAJIT_TEST_BINARY $<TARGET_FILE:tarantool> CACHE STRING
     "Lua implementation to be used for tests (tarantool)" FORCE)
-set(LUAJIT_TEST_INIT "${PROJECT_SOURCE_DIR}/test/luajit-test-init.lua"
-    CACHE STRING "Lua code need to be run before tests are started" FORCE)
 set(LUAJIT_USE_TEST OFF CACHE BOOL
     "Generate <test> target" FORCE)
 
 # Enable internal LuaJIT assertions for Tarantool Debug build.
+# XXX: There is <strict> module enabled by default in Tarantool
+# built in Debug, so we need to tweak LuaJIT testing environment.
 if(CMAKE_BUILD_TYPE STREQUAL "Debug")
     set(LUAJIT_USE_APICHECK ON CACHE BOOL
         "Assertions for the Lua/C API" FORCE)
     set(LUAJIT_USE_ASSERT ON CACHE BOOL
         "Assertions for the whole LuaJIT VM" FORCE)
+    set(LUAJIT_TEST_INIT "${PROJECT_SOURCE_DIR}/test/luajit-test-init.lua"
+        CACHE STRING "Lua code need to be run before tests are started" FORCE)
 endif()
 
 # Valgrind can be used only with the system allocator. For more

================================================================================

> 
> Otherwise, LGTM.

Added your tags to all patches:
| Reviewed-by: Sergey Kaplun <skaplun@tarantool.org>

Furthermore, I believe it is worth to mention your origin in
LUAJIT_TEST_INIT idea, so I've added you as a co-author to the last
patch on the branch.

> 
> > 

<snipped>

> > 
> > [1]: https://github.com/tarantool/luajit/tree/imun/tarantool-test
> > [2]: https://github.com/tarantool/tarantool/tree/imun/luajit-test
> > [3]: https://github.com/tarantool/luajit/commit/9712cc9#diff-1e7de1ae2d059d21e1dd75d5812d5a34b0222cef273b7c3a2af62eb747f9d20aR291-R307
> > [4]: https://github.com/tarantool/tarantool/commit/03b04a7
> > [5]: https://github.com/tarantool/luajit/commit/72f87b2
> > 
> > -- 
> > Best regards,
> > IM
> 
> [1]: https://github.com/tarantool/tarantool/issues/5870
> 
> -- 
> Best regards,
> Sergey Kaplun

-- 
Best regards,
IM

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

* Re: [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites
  2021-03-10  9:46   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-10 10:43     ` Igor Munkin via Tarantool-patches
  0 siblings, 0 replies; 26+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-10 10:43 UTC (permalink / raw)
  To: Sergey Ostanevich; +Cc: tarantool-patches

Sergos,

On 10.03.21, Sergey Ostanevich wrote:
> Hi!
> 
> Thanks for the patch!
> 
> > On 10 Mar 2021, at 02:59, Igor Munkin <imun@tarantool.org> wrote:
> > 
> > Sergey,
> > 
> > I've precisely reviewed patches 04-09 and they look good. I've polished
> > a bit[1] the series, so it can be applied to the trunk out of the order.
> > CI[2] is green.
> > 
> > BTW, I would like to leave some major points related to my review.
> > 
> > 1. The suite has been taken intact. To check this I used the following
> > recipe:
> > | $ pwd
> > | /LuaJIT-test-cleanup/test
> > | $ git remote -v
> > | origin  https://github.com/LuaJIT/LuaJIT-test-cleanup.git (fetch)
> > | origin  https://github.com/LuaJIT/LuaJIT-test-cleanup.git (push)
> > | $ git lo -1
> > | 014708b (HEAD -> master, origin/master, origin/HEAD) Add test for BC_VARG slot revival
> > | $ find . -type f | sort | xargs md5sum > ~/vanilla
> 
> Why did you use sort here? I recall using sort -u to remove duplicates, but it is not…

For the same reason people run tests several times in a row: to be
*more* sure I do everything right... If find yields the same order every
time, sort can be omitted.

> 
> > | <...>
> > | $ pwd
> > | /tarantool-luajit/test/LuaJIT-test
> > | $ git remote -v
> > | origin  git@github.com:tarantool/luajit (fetch)
> > | origin  git@github.com:tarantool/luajit (push)
> > | $ git lo -1
> > | cc0967c (HEAD) test: add LuaJIT-test-cleanup test suite
> > | $ find . -type f | sort | xargs md5sum > ~/tarantool
> > | $ diff ~/vanilla ~/tarantool
> > | > 91cb30f369b83d7626a8ae852781ebb5  ./CMakeLists.txt
> > 
> > 2. I've introduced a new CMake option: LUAJIT_TEST_INIT. You can read
> > the description here[3]. It allows to enclose the partial LUA_INIT
> > emulation, implemented via '-e dofile[[${LUAJIT_TEST_INIT}]]' and
> > obliges user to set the name of the Lua script to be run prior to the
> > testing suite[4]. By default it does nothing by reading from /dev/null.
> > 
> I would like to complain that you’re open extra file each test run,
> but there are only 500 tests and AFAIU it is a temporary solution. 
> What is the plan for the final one?

Well... There is nothing more permanent than temporary solution, isn't
it?. In "nop" case these manipulations can be omitted in CMake, *but*
this doesn't make the situation better for Tarantool CI. So, let's see
if there are issues with such extra activity and measure its impact on
Tarantool testing and then decide whether LuaJIT testing machinery need
to be boosted.

Anyway, here are some numbers for the test target (`cmake . && make -j`
is already finished before measures):
* HEAD^ (with no extra files)
| $ time make -j test
| real    0m0.842s
| user    0m1.018s
| sys     0m0.255s
* HEAD (with /dev/null access)
| $ time make -j test
| real    0m0.844s
| user    0m1.021s
| sys     0m0.235s

> 
> > 3. Since CLI flags can be used for LuaJIT testing now, <utils.selfrun>
> > need to be adjusted[5] to respect the passed flags in child process.
> > 
> > This part LGTM, so if nobody is against the version I've checked to the
> > branch[1], then I apply it to the trunk after your and Sergos approval.
> > 
> 
> LGTM.

Added your tags to all patches:
| Reviewed-by: Sergey Ostanevich <sergos@tarantool.org>

> Sergos
> 
> 

<snipped>

> > 
> > [1]: https://github.com/tarantool/luajit/tree/imun/tarantool-test
> > [2]: https://github.com/tarantool/tarantool/tree/imun/luajit-test
> > [3]: https://github.com/tarantool/luajit/commit/9712cc9#diff-1e7de1ae2d059d21e1dd75d5812d5a34b0222cef273b7c3a2af62eb747f9d20aR291-R307
> > [4]: https://github.com/tarantool/tarantool/commit/03b04a7
> > [5]: https://github.com/tarantool/luajit/commit/72f87b2
> > 
> > -- 
> > Best regards,
> > IM
> 

-- 
Best regards,
IM

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

* Re: [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites
  2021-03-09 23:59 ` Igor Munkin via Tarantool-patches
  2021-03-10  8:09   ` Sergey Kaplun via Tarantool-patches
  2021-03-10  9:46   ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-10 16:25   ` Igor Munkin via Tarantool-patches
  2 siblings, 0 replies; 26+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-10 16:25 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

I've checked the mentioned patchset into all long-term branches in
tarantool/luajit and bumped a new version in 1.10, 2.6, 2.7 and master.

On 10.03.21, Igor Munkin wrote:
> Sergey,
> 
> I've precisely reviewed patches 04-09 and they look good. I've polished
> a bit[1] the series, so it can be applied to the trunk out of the order.
> CI[2] is green.
> 
> BTW, I would like to leave some major points related to my review.
> 
> 1. The suite has been taken intact. To check this I used the following
> recipe:
> | $ pwd
> | /LuaJIT-test-cleanup/test
> | $ git remote -v
> | origin  https://github.com/LuaJIT/LuaJIT-test-cleanup.git (fetch)
> | origin  https://github.com/LuaJIT/LuaJIT-test-cleanup.git (push)
> | $ git lo -1
> | 014708b (HEAD -> master, origin/master, origin/HEAD) Add test for BC_VARG slot revival
> | $ find . -type f | sort | xargs md5sum > ~/vanilla
> | <...>
> | $ pwd
> | /tarantool-luajit/test/LuaJIT-test
> | $ git remote -v
> | origin  git@github.com:tarantool/luajit (fetch)
> | origin  git@github.com:tarantool/luajit (push)
> | $ git lo -1
> | cc0967c (HEAD) test: add LuaJIT-test-cleanup test suite
> | $ find . -type f | sort | xargs md5sum > ~/tarantool
> | $ diff ~/vanilla ~/tarantool
> | > 91cb30f369b83d7626a8ae852781ebb5  ./CMakeLists.txt
> 
> 2. I've introduced a new CMake option: LUAJIT_TEST_INIT. You can read
> the description here[3]. It allows to enclose the partial LUA_INIT
> emulation, implemented via '-e dofile[[${LUAJIT_TEST_INIT}]]' and
> obliges user to set the name of the Lua script to be run prior to the
> testing suite[4]. By default it does nothing by reading from /dev/null.
> 
> 3. Since CLI flags can be used for LuaJIT testing now, <utils.selfrun>
> need to be adjusted[5] to respect the passed flags in child process.
> 
> This part LGTM, so if nobody is against the version I've checked to the
> branch[1], then I apply it to the trunk after your and Sergos approval.
> 
> On 04.03.21, Sergey Kaplun wrote:

<snipped>

> 
> [1]: https://github.com/tarantool/luajit/tree/imun/tarantool-test
> [2]: https://github.com/tarantool/tarantool/tree/imun/luajit-test
> [3]: https://github.com/tarantool/luajit/commit/9712cc9#diff-1e7de1ae2d059d21e1dd75d5812d5a34b0222cef273b7c3a2af62eb747f9d20aR291-R307
> [4]: https://github.com/tarantool/tarantool/commit/03b04a7
> [5]: https://github.com/tarantool/luajit/commit/72f87b2
> 
> -- 
> Best regards,
> IM

-- 
Best regards,
IM

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

* Re: [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites
  2021-03-05 10:48     ` Sergey Ostanevich via Tarantool-patches
@ 2021-03-16 11:21       ` Igor Munkin via Tarantool-patches
  0 siblings, 0 replies; 26+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2021-03-16 11:21 UTC (permalink / raw)
  To: Sergey Ostanevich; +Cc: tarantool-patches

Sergos,

Looks like I'm too late here, but I still want to share some thoughts.

On 05.03.21, Sergey Ostanevich wrote:
> Hi!
> 
> 
> > On 4 Mar 2021, at 22:58, Sergey Kaplun <skaplun@tarantool.org> wrote:
> > 
> > On 04.03.21, Sergey Ostanevich wrote:
> >> Hi!
> >> 
> >> Thanks for the patchset - brief review
> >> 
> >> part 1 - obvious, LGTM.
> >> 
> >> part 2 - LGTM, good to have all follow-ups set.
> > 
> > Do you mean to reference all follow-ups inside commit message?
> > 
> 
> There could be just one - if no specific GH created.

Well... In this case the tickets should be mentioned near the changes at
least, but I still think all of them should be referenced in the commit
message. IMHO, it makes the maintenance and software archeology easier.

> 
> >> 
> >> part 3 - should have a follow-up ticket to cover all suppressions, if we plan to fix them.
> > 
> > Ditto.
> > There are some follow ups that can be grepped by qa and luajit labels.
> > 
> 
> And this is something I don’t want to do - to grep using lables. The patch should
> have reference, so I can see all links at once.

Totally agree with you here.

> 
> >> 
> >> part 4-8 are LGTM
> >> 
> >> part 9 (_G and some modules in Tarantool are different): Are we plan to fix it in some way? There should be a follow-up then.
> > 
> > For now I can't see any good solution, except ignoring them by special
> > option like slow tests.
> > 
> 
> I don’t object to ignore them. My question if we plan to tweak the tests to align
> with Tarantool? What will happen to the test if Tarantool will change preloaded
> modules?

It can be tweaked via LUAJIT_TEST_INIT CMake option. I hope most of the
issues will be resolved by it.

> 
> >> 
> >> parts 10-15 are LGTM
> >> 
> >> Regards,
> >> Sergos
> 
> 

-- 
Best regards,
IM

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

end of thread, other threads:[~2021-03-16 11:21 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-04 10:23 [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites Sergey Kaplun via Tarantool-patches
2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 01/15] test: add PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches
2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 02/15] test: adapt PUC-Rio Lua 5.1 test suite for LuaJIT Sergey Kaplun via Tarantool-patches
2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 03/15] test: adapt Lua 5.1 test suite for Tarantool Sergey Kaplun via Tarantool-patches
2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 04/15] test: add LuaJIT-test-cleanup test suite Sergey Kaplun via Tarantool-patches
2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 05/15] test: change tests to match de5568e Sergey Kaplun via Tarantool-patches
2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 06/15] test: change tests to match c198167 Sergey Kaplun via Tarantool-patches
2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 07/15] test: change tests to match 5a61e1a Sergey Kaplun via Tarantool-patches
2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 08/15] test: change LuaJIT suite tests to match b4e6bf0 Sergey Kaplun via Tarantool-patches
2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 09/15] test: adjust LuaJIT test suite for Tarantool Sergey Kaplun via Tarantool-patches
2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 10/15] test: add lua-Harness test suite Sergey Kaplun via Tarantool-patches
2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 11/15] test: adjust lua-Harness test suite for Tarantool Sergey Kaplun via Tarantool-patches
2021-03-04 10:23 ` [Tarantool-patches] [WIP luajit 12/15] test: disable 305-utf8 of lua-Harness suite Sergey Kaplun via Tarantool-patches
2021-03-04 10:24 ` [Tarantool-patches] [WIP luajit 13/15] test: disable 241-standalone " Sergey Kaplun via Tarantool-patches
2021-03-04 10:24 ` [Tarantool-patches] [WIP luajit 14/15] test: disable 411-luajit " Sergey Kaplun via Tarantool-patches
2021-03-04 10:24 ` [Tarantool-patches] [WIP luajit 15/15] test: skip test for getenv in 309-os.t Sergey Kaplun via Tarantool-patches
2021-03-04 16:24 ` [Tarantool-patches] [WIP luajit 00/15] Adapt LuaVela test suites Sergey Ostanevich via Tarantool-patches
2021-03-04 19:58   ` Sergey Kaplun via Tarantool-patches
2021-03-05 10:48     ` Sergey Ostanevich via Tarantool-patches
2021-03-16 11:21       ` Igor Munkin via Tarantool-patches
2021-03-09 23:59 ` Igor Munkin via Tarantool-patches
2021-03-10  8:09   ` Sergey Kaplun via Tarantool-patches
2021-03-10 10:39     ` Igor Munkin via Tarantool-patches
2021-03-10  9:46   ` Sergey Ostanevich via Tarantool-patches
2021-03-10 10:43     ` Igor Munkin via Tarantool-patches
2021-03-10 16:25   ` 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