summaryrefslogtreecommitdiff
path: root/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2021-11-08 01:17:11 +0800
committerchai <chaifix@163.com>2021-11-08 01:17:11 +0800
commitefce5b6bd5c9d4f8214a71e0f7a7c35751710a4c (patch)
tree0789475ded5c377667165a3ddb047ca6703bcf33 /ThirdParty/tolua_runtime/luajit-2.1/src/x64/test
parented78df90944bbe6b7de7308bda2bf3a7f1bc3de6 (diff)
+ tolua
+ lpeg
Diffstat (limited to 'ThirdParty/tolua_runtime/luajit-2.1/src/x64/test')
-rw-r--r--ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/Makefile48
-rw-r--r--ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/benchmark.cxx278
-rw-r--r--ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/test.cpp73
-rw-r--r--ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/test_str_comp.lua67
-rw-r--r--ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/test_util.cxx21
-rw-r--r--ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/test_util.hpp57
-rw-r--r--ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/unit/ffi/test_abi.lua10
-rw-r--r--ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/unit/ffi/test_line_directive.lua15
-rw-r--r--ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/unit/ffi/test_pragma_pack_pushpop.lua12
-rw-r--r--ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/unit/ffi/test_var_attribute.lua22
-rw-r--r--ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/unit_test.sh22
11 files changed, 625 insertions, 0 deletions
diff --git a/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/Makefile b/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/Makefile
new file mode 100644
index 0000000..3ec44ea
--- /dev/null
+++ b/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/Makefile
@@ -0,0 +1,48 @@
+.PHONY: default test benchmark
+
+default: test benchmark
+
+COMMON_OBJ := test_util.o
+
+TEST_PROGRAM := ht_test
+BENCHMARK_PROGRAM := ht_benchmark
+
+TEST_PROGRAM_OBJ := $(COMMON_OBJ) test.o
+BENCHMARK_PROGRAM_OBJ := $(COMMON_OBJ) benchmark.o
+
+ifeq ($(WITH_VALGRIND), 1)
+ VALGRIND := valgrind --leak-check=full
+else
+ VALGRIND :=
+endif
+
+CXXFLAGS := -O3 -MD -g -msse4.2 -Wall -I../src -I../../../src
+
+%.o: %.cxx
+ $(CXX) $(CXXFLAGS) -MD -c $<
+
+test: $(TEST_PROGRAM)
+ @echo "some unit test"
+ $(VALGRIND) ./$(TEST_PROGRAM)
+ ./unit_test.sh
+
+ @echo "smoke test"
+ ../../luajit test_str_comp.lua
+
+benchmark: $(BENCHMARK_PROGRAM)
+ # micro benchmark
+ ./$(BENCHMARK_PROGRAM)
+
+$(TEST_PROGRAM) : $(TEST_PROGRAM_OBJ)
+ cat $(TEST_PROGRAM_OBJ:.o=.d) > dep1.txt
+ $(CXX) $+ $(CXXFLAGS) -lm -o $@
+
+$(BENCHMARK_PROGRAM): $(BENCHMARK_PROGRAM_OBJ)
+ cat $(BENCHMARK_PROGRAM_OBJ:.o=.d) > dep2.txt
+ $(CXX) $+ $(CXXFLAGS) -o $@
+
+-include dep1.txt
+-include dep2.txt
+
+clean:
+ -rm -f *.o *.d dep*.txt $(BENCHMARK_PROGRAM) $(TEST_PROGRAM)
diff --git a/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/benchmark.cxx b/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/benchmark.cxx
new file mode 100644
index 0000000..e37edb0
--- /dev/null
+++ b/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/benchmark.cxx
@@ -0,0 +1,278 @@
+#include <sys/time.h> // for gettimeofday()
+extern "C" {
+#include "lj_str_hash_x64.h"
+}
+#include <string>
+#include <vector>
+#include <utility>
+#include <algorithm>
+#include "test_util.hpp"
+#include <stdio.h>
+#include <math.h>
+
+using namespace std;
+
+#define lj_rol(x, n) (((x)<<(n)) | ((x)>>(-(int)(n)&(8*sizeof(x)-1))))
+#define lj_ror(x, n) (((x)<<(-(int)(n)&(8*sizeof(x)-1))) | ((x)>>(n)))
+
+const char* separator = "-------------------------------------------";
+
+static uint32_t LJ_AINLINE
+lj_original_hash(const char *str, size_t len)
+{
+ uint32_t a, b, h = len;
+ if (len >= 4) {
+ a = lj_getu32(str); h ^= lj_getu32(str+len-4);
+ b = lj_getu32(str+(len>>1)-2);
+ h ^= b; h -= lj_rol(b, 14);
+ b += lj_getu32(str+(len>>2)-1);
+ a ^= h; a -= lj_rol(h, 11);
+ b ^= a; b -= lj_rol(a, 25);
+ h ^= b; h -= lj_rol(b, 16);
+ } else {
+ a = *(const uint8_t *)str;
+ h ^= *(const uint8_t *)(str+len-1);
+ b = *(const uint8_t *)(str+(len>>1));
+ h ^= b; h -= lj_rol(b, 14);
+ }
+
+ a ^= h; a -= lj_rol(h, 11);
+ b ^= a; b -= lj_rol(a, 25);
+ h ^= b; h -= lj_rol(b, 16);
+
+ return h;
+}
+
+template<class T> double
+BenchmarkHashTmpl(T func, char* buf, size_t len)
+{
+ TestClock timer;
+ uint32_t h = 0;
+
+ timer.start();
+ for(int i = 1; i < 1000000 * 100; i++) {
+ // So the buf is not loop invariant, hence the F(...)
+ buf[i % 4096] = i;
+ h += func(buf, len) ^ i;
+ }
+ timer.stop();
+
+ // make h alive
+ test_printf("%x", h);
+ return timer.getElapseInSecond();
+}
+
+struct TestFuncWas
+{
+ uint32_t operator()(const char* buf, uint32_t len) {
+ return lj_original_hash(buf, len);
+ }
+};
+
+struct TestFuncIs
+{
+ uint32_t operator()(const char* buf, uint32_t len) {
+ return lj_str_hash(buf, len);
+ }
+};
+
+static void
+benchmarkIndividual(char* buf)
+{
+ fprintf(stdout,"\n\nCompare performance of particular len (in second)\n");
+ fprintf(stdout, "%-12s%-8s%-8s%s\n", "len", "was", "is", "diff");
+ fprintf(stdout, "-------------------------------------------\n");
+
+ uint32_t lens[] = {3, 4, 7, 10, 15, 16, 20, 32, 36, 63, 80, 100,
+ 120, 127, 280, 290, 400};
+ for (unsigned i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) {
+ uint32_t len = lens[i];
+ double e1 = BenchmarkHashTmpl(TestFuncWas(), buf, len);
+ double e2 = BenchmarkHashTmpl(TestFuncIs(), buf, len);
+ fprintf(stdout, "len = %4d: %-7.3lf %-7.3lf %.2f\n", len, e1, e2, (e1-e2)/e1);
+ }
+}
+
+template<class T> double
+BenchmarkChangeLenTmpl(T func, char* buf, uint32_t* len_vect, uint32_t len_num)
+{
+ TestClock timer;
+ uint32_t h = 0;
+
+ timer.start();
+ for(int i = 1; i < 1000000 * 100; i++) {
+ for (int j = 0; j < (int)len_num; j++) {
+ // So the buf is not loop invariant, hence the F(...)
+ buf[(i + j) % 4096] = i;
+ h += func(buf, len_vect[j]) ^ j;
+ }
+ }
+ timer.stop();
+
+ // make h alive
+ test_printf("%x", h);
+ return timer.getElapseInSecond();
+}
+
+// It is to measure the performance when length is changing.
+// The purpose is to see how balanced branches impact the performance.
+//
+static void
+benchmarkToggleLens(char* buf)
+{
+ double e1, e2;
+ fprintf(stdout,"\nChanging length (in second):");
+ fprintf(stdout, "\n%-20s%-8s%-8s%s\n%s\n", "len", "was", "is", "diff",
+ separator);
+
+ uint32_t lens1[] = {4, 9};
+ e1 = BenchmarkChangeLenTmpl(TestFuncWas(), buf, lens1, 2);
+ e2 = BenchmarkChangeLenTmpl(TestFuncIs(), buf, lens1, 2);
+ fprintf(stdout, "%-20s%-7.3lf %-7.3lf %.2f\n", "4,9", e1, e2, (e1-e2)/e1);
+
+ uint32_t lens2[] = {1, 4, 9};
+ e1 = BenchmarkChangeLenTmpl(TestFuncWas(), buf, lens2, 3);
+ e2 = BenchmarkChangeLenTmpl(TestFuncIs(), buf, lens2, 3);
+ fprintf(stdout, "%-20s%-7.3lf %-7.3lf %.2f\n", "1,4,9", e1, e2, (e1-e2)/e1);
+
+ uint32_t lens3[] = {1, 33, 4, 9};
+ e1 = BenchmarkChangeLenTmpl(TestFuncWas(), buf, lens3, 4);
+ e2 = BenchmarkChangeLenTmpl(TestFuncIs(), buf, lens3, 4);
+ fprintf(stdout, "%-20s%-7.3lf %-7.3lf %.2f\n", "1,33,4,9",
+ e1, e2, (e1-e2)/e1);
+}
+
+static void
+genRandomString(uint32_t min, uint32_t max,
+ uint32_t num, vector<string>& result)
+{
+ double scale = (max - min) / (RAND_MAX + 1.0);
+ result.clear();
+ result.reserve(num);
+ for (uint32_t i = 0; i < num; i++) {
+ uint32_t len = (rand() * scale) + min;
+
+ char* buf = new char[len];
+ for (uint32_t l = 0; l < len; l++) {
+ buf[l] = rand() % 255;
+ }
+ result.push_back(string(buf, len));
+ delete[] buf;
+ }
+}
+
+// Return the standard deviation of given array of number
+static double
+standarDeviation(const vector<uint32_t>& v)
+{
+ uint64_t total = 0;
+ for (vector<uint32_t>::const_iterator i = v.begin(), e = v.end();
+ i != e; ++i) {
+ total += *i;
+ }
+
+ double avg = total / (double)v.size();
+ double sd = 0;
+
+ for (vector<uint32_t>::const_iterator i = v.begin(), e = v.end();
+ i != e; ++i) {
+ double t = avg - *i;
+ sd = sd + t*t;
+ }
+
+ return sqrt(sd/v.size());
+}
+
+static pair<double, double>
+benchmarkConflictHelper(uint32_t bucketNum, const vector<string>& strs)
+{
+ if (bucketNum & (bucketNum - 1)) {
+ bucketNum = (1L << (log2_floor(bucketNum) + 1));
+ }
+ uint32_t mask = bucketNum - 1;
+
+ vector<uint32_t> conflictWas(bucketNum);
+ vector<uint32_t> conflictIs(bucketNum);
+
+ conflictWas.resize(bucketNum);
+ conflictIs.resize(bucketNum);
+
+ for (vector<string>::const_iterator i = strs.begin(), e = strs.end();
+ i != e; ++i) {
+ uint32_t h1 = lj_original_hash(i->c_str(), i->size());
+ uint32_t h2 = lj_str_hash(i->c_str(), i->size());
+
+ conflictWas[h1 & mask]++;
+ conflictIs[h2 & mask]++;
+ }
+
+#if 0
+ std::sort(conflictWas.begin(), conflictWas.end(), std::greater<int>());
+ std::sort(conflictIs.begin(), conflictIs.end(), std::greater<int>());
+
+ fprintf(stderr, "%d %d %d %d vs %d %d %d %d\n",
+ conflictWas[0], conflictWas[1], conflictWas[2], conflictWas[3],
+ conflictIs[0], conflictIs[1], conflictIs[2], conflictIs[3]);
+#endif
+
+ return pair<double, double>(standarDeviation(conflictWas),
+ standarDeviation(conflictIs));
+}
+
+static void
+benchmarkConflict()
+{
+ srand(time(0));
+
+ float loadFactor[] = { 0.5f, 1.0f, 2.0f, 4.0f, 8.0f };
+ int bucketNum[] = { 512, 1024, 2048, 4096, 8192, 16384};
+ int lenRange[][2] = { {1,3}, {4, 15}, {16, 127}, {128, 1024}, {1, 1024}};
+
+ fprintf(stdout,
+ "\nBechmarking conflict (stand deviation of conflict)\n%s\n",
+ separator);
+
+ for (uint32_t k = 0; k < sizeof(lenRange)/sizeof(lenRange[0]); k++) {
+ fprintf(stdout, "\nlen range from %d - %d\n", lenRange[k][0],
+ lenRange[k][1]);
+ fprintf(stdout, "%-10s %-12s %-10s %-10s diff\n%s\n",
+ "bucket", "load-factor", "was", "is", separator);
+ for (uint32_t i = 0; i < sizeof(bucketNum)/sizeof(bucketNum[0]); ++i) {
+ for (uint32_t j = 0;
+ j < sizeof(loadFactor)/sizeof(loadFactor[0]);
+ ++j) {
+ int strNum = bucketNum[i] * loadFactor[j];
+ vector<string> strs(strNum);
+ genRandomString(lenRange[k][0], lenRange[k][1], strNum, strs);
+
+ pair<double, double> p;
+ p = benchmarkConflictHelper(bucketNum[i], strs);
+ fprintf(stdout, "%-10d %-12.2f %-10.2f %-10.2f %.2f\n",
+ bucketNum[i], loadFactor[j], p.first, p.second,
+ p.first - p.second);
+ }
+ }
+ }
+}
+
+static void
+benchmarkHashFunc()
+{
+ char buf[4096];
+ char c = getpid() % 'a';
+ for (int i = 0; i < (int)sizeof(buf); i++) {
+ buf[i] = (c + i) % 255;
+ }
+
+ benchmarkConflict();
+ benchmarkIndividual(buf);
+ benchmarkToggleLens(buf);
+}
+
+int
+main(int argc, char** argv)
+{
+ fprintf(stdout, "========================\nMicro benchmark...\n");
+ benchmarkHashFunc();
+ return 0;
+}
diff --git a/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/test.cpp b/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/test.cpp
new file mode 100644
index 0000000..bc92acb
--- /dev/null
+++ b/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/test.cpp
@@ -0,0 +1,73 @@
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <map>
+#include "test_util.hpp"
+#include "lj_str_hash_x64.h"
+
+using namespace std;
+
+static bool
+smoke_test()
+{
+ fprintf(stdout, "running smoke tests...\n");
+ char buf[1024];
+ char c = getpid() % 'a';
+
+ for (int i = 0; i < (int)sizeof(buf); i++) {
+ buf[i] = (c + i) % 255;
+ }
+
+ uint32_t lens[] = {3, 4, 5, 7, 8, 16, 17, 24, 25, 32, 33, 127, 128,
+ 255, 256, 257};
+ for (unsigned i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) {
+ string s(buf, lens[i]);
+ test_printf("%d", lj_str_hash(s.c_str(), lens[i]));
+ }
+
+ return true;
+}
+
+static bool
+verify_log2()
+{
+ fprintf(stdout, "verify log2...\n");
+ bool err = false;
+ std::map<uint32_t, uint32_t> lm;
+ lm[0] =(uint32_t)-1;
+ lm[1] = 0;
+ lm[2] = 1;
+ for (int i = 2; i < 31; i++) {
+ lm[(1<<i) - 2] = i - 1;
+ lm[(1<<i) - 1] = i - 1;
+ lm[1<<i] = i;
+ lm[(1<<i) + 1] = i;
+ }
+ lm[(uint32_t)-1] = 31;
+
+ for (map<uint32_t, uint32_t>::iterator iter = lm.begin(), iter_e = lm.end();
+ iter != iter_e; ++iter) {
+ uint32_t v = (*iter).first;
+ uint32_t log2_expect = (*iter).second;
+ uint32_t log2_get = log2_floor(v);
+ if (log2_expect != log2_get) {
+ err = true;
+ fprintf(stderr, "log2(%u) expect %u, get %u\n", v, log2_expect, log2_get);
+ exit(1);
+ }
+ }
+ return !err;
+}
+
+int
+main(int argc, char** argv)
+{
+ fprintf(stdout, "=======================\nRun unit testing...\n");
+
+ ASSERT(smoke_test(), "smoke_test test failed");
+ ASSERT(verify_log2(), "log2 failed");
+
+ fprintf(stdout, TestErrMsgMgr::noError() ? "succ\n\n" : "fail\n\n");
+
+ return TestErrMsgMgr::noError() ? 0 : -1;
+}
diff --git a/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/test_str_comp.lua b/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/test_str_comp.lua
new file mode 100644
index 0000000..3a5c3e6
--- /dev/null
+++ b/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/test_str_comp.lua
@@ -0,0 +1,67 @@
+--[[
+ Given two content-idental string s1, s2, test if they end up to be the
+ same string object. The purpose of this test is to make sure hash function
+ do not accidently include extraneous bytes before and after the string in
+ question.
+]]
+
+local ffi = require("ffi")
+local C = ffi.C
+
+ffi.cdef[[
+ void free(void*);
+ char* malloc(size_t);
+ void *memset(void*, int, size_t);
+ void *memcpy(void*, void*, size_t);
+ long time(void*);
+ void srandom(unsigned);
+ long random(void);
+]]
+
+
+local function test_equal(len_min, len_max)
+ -- source string is wrapped by 16-byte-junk both before and after the
+ -- string
+ local x = C.random()
+ local l = len_min + x % (len_max - len_min);
+ local buf_len = tonumber(l + 16 * 2)
+
+ local src_buf = C.malloc(buf_len)
+ for i = 0, buf_len - 1 do
+ src_buf[i] = C.random() % 255
+ end
+
+ -- dest string is the clone of the source string, but it is sandwiched
+ -- by different junk bytes
+ local dest_buf = C.malloc(buf_len)
+ C.memset(dest_buf, 0x5a, buf_len)
+
+ local ofst = 8 + (C.random() % 8)
+ C.memcpy(dest_buf + ofst, src_buf + 16, l);
+
+ local str1 = ffi.string(src_buf + 16, l)
+ local str2 = ffi.string(dest_buf + ofst, l)
+
+ C.free(src_buf)
+ C.free(dest_buf)
+
+ if str1 ~= str2 then
+ -- Oops, look like hash function mistakenly include extraneous bytes
+ -- close to the string
+ return 1 -- wtf
+ end
+end
+
+--local lens = {1, 4, 16, 128, 1024}
+local lens = {128, 1024}
+local iter = 1000
+
+for i = 1, #lens - 1 do
+ for j = 1, iter do
+ if test_equal(lens[i], lens[i+1]) ~= nil then
+ os.exit(1)
+ end
+ end
+end
+
+os.exit(0)
diff --git a/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/test_util.cxx b/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/test_util.cxx
new file mode 100644
index 0000000..34b7d67
--- /dev/null
+++ b/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/test_util.cxx
@@ -0,0 +1,21 @@
+#include <stdarg.h>
+#include <stdio.h>
+#include "test_util.hpp"
+
+using namespace std;
+
+std::vector<TestErrMsg> TestErrMsgMgr::_errMsg;
+
+void
+test_printf(const char* format, ...)
+{
+ va_list args;
+ va_start (args, format);
+
+ FILE* devNull = fopen("/dev/null", "w");
+ if (devNull != 0) {
+ (void)vfprintf (devNull, format, args);
+ }
+ fclose(devNull);
+ va_end (args);
+}
diff --git a/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/test_util.hpp b/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/test_util.hpp
new file mode 100644
index 0000000..6cc2ea2
--- /dev/null
+++ b/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/test_util.hpp
@@ -0,0 +1,57 @@
+#ifndef _TEST_UTIL_HPP_
+#define _TEST_UTIL_HPP_
+
+#include <sys/time.h> // gettimeofday()
+#include <string>
+#include <vector>
+
+struct TestErrMsg
+{
+ const char* fileName;
+ unsigned lineNo;
+ std::string errMsg;
+
+ TestErrMsg(const char* FN, unsigned LN, const char* Err):
+ fileName(FN), lineNo(LN), errMsg(Err) {}
+};
+
+class TestErrMsgMgr
+{
+public:
+ static std::vector<TestErrMsg> getError();
+ static void
+ addError(const char* fileName, unsigned lineNo, const char* Err) {
+ _errMsg.push_back(TestErrMsg(fileName, lineNo, Err));
+ }
+
+ static bool noError() {
+ return _errMsg.empty();
+ }
+
+private:
+ static std::vector<TestErrMsg> _errMsg;
+};
+
+#define ASSERT(c, e) \
+ if (!(c)) { TestErrMsgMgr::addError(__FILE__, __LINE__, (e)); }
+
+class TestClock
+{
+public:
+ void start() { gettimeofday(&_start, 0); }
+ void stop() { gettimeofday(&_end, 0); }
+ double getElapseInSecond() {
+ return (_end.tv_sec - _start.tv_sec)
+ + ((long)_end.tv_usec - (long)_start.tv_usec) / 1000000.0;
+ }
+
+private:
+ struct timeval _start, _end;
+};
+
+// write to /dev/null, the only purpose is to make the data fed to the
+// function alive.
+extern void test_printf(const char* format, ...)
+ __attribute__ ((format (printf, 1, 2)));
+
+#endif //_TEST_UTIL_HPP_
diff --git a/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/unit/ffi/test_abi.lua b/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/unit/ffi/test_abi.lua
new file mode 100644
index 0000000..9fafcf5
--- /dev/null
+++ b/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/unit/ffi/test_abi.lua
@@ -0,0 +1,10 @@
+local ffi = require "ffi"
+
+-- TODO: test "gc64" and "win" parameters
+assert((ffi.abi("32bit") or ffi.abi("64bit"))
+ and ffi.abi("le")
+ and not ffi.abi("be")
+ and ffi.abi("fpu")
+ and not ffi.abi("softfp")
+ and ffi.abi("hardfp")
+ and not ffi.abi("eabi"))
diff --git a/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/unit/ffi/test_line_directive.lua b/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/unit/ffi/test_line_directive.lua
new file mode 100644
index 0000000..a8b0403
--- /dev/null
+++ b/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/unit/ffi/test_line_directive.lua
@@ -0,0 +1,15 @@
+local x = [=[
+local ffi = require "ffi"
+
+ffi.cdef [[
+ #line 100
+ typedef Int xxx
+]]
+]=]
+
+local function foo()
+ loadstring(x)()
+end
+
+local r, e = pcall(foo)
+assert(string.find(e, "declaration specifier expected near 'Int' at line 100") ~= nil)
diff --git a/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/unit/ffi/test_pragma_pack_pushpop.lua b/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/unit/ffi/test_pragma_pack_pushpop.lua
new file mode 100644
index 0000000..5f1bdd3
--- /dev/null
+++ b/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/unit/ffi/test_pragma_pack_pushpop.lua
@@ -0,0 +1,12 @@
+local ffi = require "ffi"
+
+ffi.cdef[[
+#pragma pack(push, 1)
+typedef struct {
+ char x;
+ double y;
+} foo;
+#pragma pack(pop)
+]]
+
+assert(ffi.sizeof("foo") == 9)
diff --git a/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/unit/ffi/test_var_attribute.lua b/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/unit/ffi/test_var_attribute.lua
new file mode 100644
index 0000000..11252bb
--- /dev/null
+++ b/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/unit/ffi/test_var_attribute.lua
@@ -0,0 +1,22 @@
+local ffi = require "ffi"
+
+ffi.cdef[[
+typedef struct { int a; char b; } __attribute__((packed)) myty1;
+typedef struct { int a; char b; } __attribute__((__packed__)) myty1_a;
+
+typedef struct { int a; char b; } __attribute__((aligned(16))) myty2_a;
+typedef struct { int a; char b; } __attribute__((__aligned__(16))) myty2;
+
+typedef int __attribute__ ((vector_size (32))) myty3;
+typedef int __attribute__ ((__vector_size__ (32))) myty3_a;
+
+typedef int __attribute__ ((mode(DI))) myty4;
+]]
+
+assert(ffi.sizeof("myty1") == 5 and
+ ffi.sizeof("myty1_a") == 5 and
+ ffi.alignof("myty2") == 16 and
+ ffi.alignof("myty2_a") == 16 and
+ ffi.sizeof("myty3") == 32 and
+ ffi.sizeof("myty3_a") == 32 and
+ ffi.sizeof("myty4") == 8)
diff --git a/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/unit_test.sh b/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/unit_test.sh
new file mode 100644
index 0000000..c6633ca
--- /dev/null
+++ b/ThirdParty/tolua_runtime/luajit-2.1/src/x64/test/unit_test.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+DIR=$(cd $(dirname $0); pwd)
+cd $DIR
+
+LUAJIT=$DIR/../../luajit
+HASERR=0
+
+find $DIR/unit -name "*.lua" -print | while read x; do
+ $LUAJIT $x >/dev/null 2>/dev/null
+ if [ $? -eq 0 ]; then
+ echo "$x ok"
+ else
+ HASERR=1
+ echo "$x failed"
+ fi
+done
+
+if [ $HASERR -eq 0 ]; then
+ exit 0
+fi
+
+exit 1