OpenResty's Branch of LuaJIT 2
Branch: v2.1-agentzh
Clone or download
agentzh feature: implemented the new table.nkeys Lua API.
This Lua builtin returns the number of elements in a Lua table, i.e.,
the number of non-nil array elements plus the number of non-nil key-value
pairs in a single Lua table.

It can be used like this:

  local nkeys = require "table.nkeys"

  print(nkeys({}))  -- 0
  print(nkeys({ "a", nil, "b" }))  -- 2
  print(nkeys({ dog = 3, cat = 4, bird = nil }))  -- 2
  print(nkeys({ "a", dog = 3, cat = 4 }))  -- 3

This Lua API can be JIT compiled.

Signed-off-by: Yichun Zhang (agentzh) <agentzh@gmail.com>
Latest commit 0e646b5 Jun 23, 2018

README

README for LuaJIT 2.1.0-beta3
-----------------------------

LuaJIT is a Just-In-Time (JIT) compiler for the Lua programming language.

Project Homepage: http://luajit.org/

LuaJIT is Copyright (C) 2005-2017 Mike Pall.

Additional patches for OpenResty are copyrighted by Yichun Zhang and OpenResty
Inc.:

Copyright (C) 2017-2018 Yichun Zhang. All rights reserved.

Copyright (C) 2017-2018 OpenResty Inc. All rights reserved.

LuaJIT is free software, released under the MIT license.
See full Copyright Notice in the COPYRIGHT file or in luajit.h.

Documentation for LuaJIT is available in HTML format.
Please point your favorite browser to:

 doc/luajit.html

About this branch
-----------------

This is the official OpenResty branch for LuaJIT. This is not really a fork
since we still synchronize any upstream changes all the time.

We introduce our own changes which will never merge or haven't yet merged into
the upstream LuaJIT (https://github.com/LuaJIT/LuaJIT), which are

* feature: implemented the table.isempty() Lua API.

    This Lua API can be JIT compiled.

    Returns true when the table contains non-nil array elements or non-nil
    key-value pairs.

    Usage:

    ```lua
        local isempty = require "table.isempty"
        print(isempty({}))  -- true
        print(isempty({nil, dog = nil}))  -- true
        print(isempty({"a", "b"}))  -- false
        print(isempty({nil, 3}))  -- false
        print(isempty({cat = 3}))  -- false
    ```
* feature: implemented the new table.isarray() builtin function which returns true
  for purely array-like Lua tables and false otherwise.

    Empty Lua tables are treated as arrays.

    Use it like this:

        isarr = require "table.isarray"
        print(isarr{"a", true, 3.14})  -- true
        print(isarr{"dog" = 3})  -- false
        print(isarr{})  -- true

* feature: implemented the new table.nkeys Lua API.

    This Lua builtin returns the number of elements in a Lua table, i.e.,
    the number of non-nil array elements plus the number of non-nil key-value
    pairs in a single Lua table.

    It can be used like this:

      local nkeys = require "table.nkeys"

      print(nkeys({}))  -- 0
      print(nkeys({ "a", nil, "b" }))  -- 2
      print(nkeys({ dog = 3, cat = 4, bird = nil }))  -- 2
      print(nkeys({ "a", dog = 3, cat = 4 }))  -- 3

    This Lua API can be JIT compiled.

* feature: implemented the new Lua and C API functions for thread exdata.

    The Lua API can be used like below:

      local exdata = require "thread.exdata"
      exdata(0xdeadbeefLL)  -- set the exdata of the current Lua thread
      local ptr = exdata()  -- fetch the exdata of the current Lua thread

    The exdata value on the Lua land is represented as a cdata object of the
    ctype "void*".

    Right now the reading API, i.e., `exdata()` calls without any arguments,
    can be JIT compiled.

    Also exposed the following public C API functions for manipulating
    exdata on the C land:

      void lua_setexdata(lua_State *L, void *exdata);
      void *lua_getexdata(lua_State *L);

    The exdata pointer is initialized to NULL when the main thread is
    created. Any child Lua threads created will inherit the parent's exdata
    but still have their own exdata storage. So child Lua threads can always
    override the inherited parent exdata pointer values.

    This API is used internally by the OpenResty core so never ever mess
    with it yourself in the context of OpenResty.

* feature: luajit.h: defined the macro OPENRESTY_LUAJIT for our branch of
  LuaJIT.

* feature: implemented the table.clone() builtin Lua API.

    This change only support shallow clone. e.g

      local tab_clone = require "table.clone"
      local x = {x=12, y={5, 6, 7}}
      local y = tab_clone(x)
      ... use y ...

    Deep clone will be supported by adding 'true' as the 2nd argument to table.clone

    We observe 7% over-all speedup in the edgelang-fan compiler's compiling
    speed whose Lua is generated by the fanlang compiler.

* feature: implemented new API function jit.prngstate() for reading or setting
  the current PRNG state number used in the JIT compiler.

* optimize: use more appressive JIT compiler parameters as the default to help
  large OpenResty Lua apps.

    We now use the following jit.opt defaults:

    maxtrace=8000
    maxrecord=16000
    minstitch=3
    maxmcode=40960  -- in KB

* optimize: lj_str_new: uses randomized hash functions based on crc32 when
  -msse4.2 is specified for Intel CPUs supporting SSE 4.2 instruction set.

    security wise:
    -------------
    o. crc32 up to 128 bytes, so it is difficult to attach with len <= 128.
    o. for len >= 128, random 128 bytes are crc32-ed, so it is vulnerable.

    performance wise:
    -----------------
    o. performance is measured by 'make -C src/x64/test benchmark'
    o. new hash function is realtively computationally cheaper if len < 120
        and about 1.8x as slow if len >= 120.
    o. for len in [1-3], original hash function has better distribution.
       need to understand why it is so.

* optimize: lj_str_new: tests the full hash value before doing the full string
  comparison on hash collisions.

* feature: added the bytecode option `L` to display lua source line numbers.
  For example, `luajit -bL -e 'print(1)'` now produces bytecode dump like
  below:

    -- BYTECODE -- "print(1)":0-1
    0001     [1]    GGET     0   0      ; "print"
    0002     [1]    KSHORT   1   1
    0003     [1]    CALL     0   1   2
    0004     [1]    RET0     0   1

  The column `[N]` is the Lua source line number. For example, `[1]` means on
  the first source line.

* feature: removed the GCC 4 requirement for x86 for older systems like
  Solaris i386.

* Makefile: make sure we always install the symlink for "luajit" even for
  alpha or beta versions.

* feature: jit.dump: output Lua source location after every BC.

* feature: added internal memory-buffer-based trace entry/exit/start-recording
  event logging, mainly for debugging bugs in the JIT compiler. it requires
  -DLUA_USE_TRACE_LOGS when building LuaJIT.

* feature: save g->jit_base to g->saved_jit_base before lj_err_throw clears
  g->jit_base which makes it impossible to get Lua backtrace in such states.

* applied a patch to fix DragonFlyBSD compatibility. Note: this is not an
  officially supported target.

* turned off string comparison optimizations for 64-bit architectures when
  the build option LUAJIT_USE_VALGRIND is specified. now LuaJIT is (almost)
  valgrind clean.

These new API functions introduced in this branch may get changed in the future
and there is no guarentee for backward compatibility.