Skip to content

Commit 2d33927

Browse files
Shuxin Yangagentzh
authored andcommitted
bugfix: FFI C parsers could not parse some C constructs like __attribute((aligned(N))) and #pragma.
Decoupled hash functions used in comparison (hardcoded) and string table. This bug had first appeared in v2.1-20170405 (or OpenResty 1.11.2.3). Signed-off-by: Yichun Zhang (agentzh) <[email protected]>
1 parent 1ac77b4 commit 2d33927

File tree

10 files changed

+103
-13
lines changed

10 files changed

+103
-13
lines changed

src/lib_ffi.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -727,7 +727,7 @@ LJLIB_CF(ffi_abi) LJLIB_REC(.)
727727
{
728728
GCstr *s = lj_lib_checkstr(L, 1);
729729
int b = 0;
730-
switch (s->hash) {
730+
switch (lj_str_indep_hash(s)) {
731731
#if LJ_64
732732
case H_(849858eb,ad35fd06): b = 1; break; /* 64bit */
733733
#else

src/lj_cparse.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,7 +1059,7 @@ static void cp_decl_gccattribute(CPState *cp, CPDecl *decl)
10591059
if (cp->tok == CTOK_IDENT) {
10601060
GCstr *attrstr = cp->str;
10611061
cp_next(cp);
1062-
switch (attrstr->hash) {
1062+
switch (lj_str_indep_hash(attrstr)) {
10631063
case H_(64a9208e,8ce14319): case H_(8e6331b2,95a282af): /* aligned */
10641064
cp_decl_align(cp, decl);
10651065
break;
@@ -1128,7 +1128,7 @@ static void cp_decl_msvcattribute(CPState *cp, CPDecl *decl)
11281128
while (cp->tok == CTOK_IDENT) {
11291129
GCstr *attrstr = cp->str;
11301130
cp_next(cp);
1131-
switch (attrstr->hash) {
1131+
switch (lj_str_indep_hash(attrstr)) {
11321132
case H_(bc2395fa,98f267f8): /* align */
11331133
cp_decl_align(cp, decl);
11341134
break;
@@ -1718,16 +1718,16 @@ static void cp_pragma(CPState *cp, BCLine pragmaline)
17181718
{
17191719
cp_next(cp);
17201720
if (cp->tok == CTOK_IDENT &&
1721-
cp->str->hash == H_(e79b999f,42ca3e85)) { /* pack */
1721+
(lj_str_indep_hash(cp->str)) == H_(e79b999f,42ca3e85)) { /* pack */
17221722
cp_next(cp);
17231723
cp_check(cp, '(');
17241724
if (cp->tok == CTOK_IDENT) {
1725-
if (cp->str->hash == H_(738e923c,a1b65954)) { /* push */
1725+
if (lj_str_indep_hash(cp->str) == H_(738e923c,a1b65954)) { /* push */
17261726
if (cp->curpack < CPARSE_MAX_PACKSTACK) {
17271727
cp->packstack[cp->curpack+1] = cp->packstack[cp->curpack];
17281728
cp->curpack++;
17291729
}
1730-
} else if (cp->str->hash == H_(6c71cf27,6c71cf27)) { /* pop */
1730+
} else if (lj_str_indep_hash(cp->str) == H_(6c71cf27,6c71cf27)) { /* pop */
17311731
if (cp->curpack > 0) cp->curpack--;
17321732
} else {
17331733
cp_errmsg(cp, cp->tok, LJ_ERR_XSYMBOL);
@@ -1777,12 +1777,12 @@ static void cp_decl_multi(CPState *cp)
17771777
cp_line(cp, hashline);
17781778
continue;
17791779
} else if (tok == CTOK_IDENT &&
1780-
cp->str->hash == H_(187aab88,fcb60b42)) { /* line */
1780+
lj_str_indep_hash(cp->str) == H_(187aab88,fcb60b42)) { /* line */
17811781
if (cp_next(cp) != CTOK_INTEGER) cp_err_token(cp, tok);
17821782
cp_line(cp, hashline);
17831783
continue;
17841784
} else if (tok == CTOK_IDENT &&
1785-
cp->str->hash == H_(f5e6b4f8,1d509107)) { /* pragma */
1785+
lj_str_indep_hash(cp->str) == H_(f5e6b4f8,1d509107)) { /* pragma */
17861786
cp_pragma(cp, hashline);
17871787
continue;
17881788
} else {

src/lj_str.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -128,11 +128,6 @@ void lj_str_resize(lua_State *L, MSize newmask)
128128
g->strhash = newhash;
129129
}
130130

131-
#include "x64/src/lj_str_hash_x64.h"
132-
133-
#if defined(LJ_ARCH_STR_HASH)
134-
#define LJ_STR_HASH LJ_ARCH_STR_HASH
135-
#else
136131
static MSize
137132
lj_str_original_hash(const char *str, size_t lenx) {
138133
MSize len = (MSize)lenx;
@@ -160,6 +155,17 @@ lj_str_original_hash(const char *str, size_t lenx) {
160155

161156
return h;
162157
}
158+
159+
MSize
160+
lj_str_indep_hash(GCstr *str) {
161+
return lj_str_original_hash(strdata(str), str->len);
162+
}
163+
164+
#include "x64/src/lj_str_hash_x64.h"
165+
166+
#if defined(LJ_ARCH_STR_HASH)
167+
#define LJ_STR_HASH LJ_ARCH_STR_HASH
168+
#else
163169
#define LJ_STR_HASH lj_str_original_hash
164170
#endif
165171

src/lj_str.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,6 @@ LJ_FUNC void LJ_FASTCALL lj_str_free(global_State *g, GCstr *s);
2424
#define lj_str_newz(L, s) (lj_str_new(L, s, strlen(s)))
2525
#define lj_str_newlit(L, s) (lj_str_new(L, "" s, sizeof(s)-1))
2626

27+
MSize lj_str_indep_hash(GCstr *str);
28+
2729
#endif

src/x64/test/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ CXXFLAGS := -O3 -MD -g -msse4.2 -Wall -I../src -I../../../src
2424
test: $(TEST_PROGRAM)
2525
@echo "some unit test"
2626
$(VALGRIND) ./$(TEST_PROGRAM)
27+
./unit_test.sh
2728

2829
@echo "smoke test"
2930
../../luajit test_str_comp.lua

src/x64/test/unit/ffi/test_abi.lua

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
local ffi = require "ffi"
2+
3+
-- TODO: test "gc64" and "win" parameters
4+
assert((ffi.abi("32bit") or ffi.abi("64bit"))
5+
and ffi.abi("le")
6+
and not ffi.abi("be")
7+
and ffi.abi("fpu")
8+
and not ffi.abi("softfp")
9+
and ffi.abi("hardfp")
10+
and not ffi.abi("eabi"))
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
local x = [=[
2+
local ffi = require "ffi"
3+
4+
ffi.cdef [[
5+
#line 100
6+
typedef Int xxx
7+
]]
8+
]=]
9+
10+
local function foo()
11+
loadstring(x)()
12+
end
13+
14+
local r, e = pcall(foo)
15+
assert(string.find(e, "declaration specifier expected near 'Int' at line 100") ~= nil)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
local ffi = require "ffi"
2+
3+
ffi.cdef[[
4+
#pragma pack(push, 1)
5+
typedef struct {
6+
char x;
7+
double y;
8+
} foo;
9+
#pragma pack(pop)
10+
]]
11+
12+
assert(ffi.sizeof("foo") == 9)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
local ffi = require "ffi"
2+
3+
ffi.cdef[[
4+
typedef struct { int a; char b; } __attribute__((packed)) myty1;
5+
typedef struct { int a; char b; } __attribute__((__packed__)) myty1_a;
6+
7+
typedef struct { int a; char b; } __attribute__((aligned(16))) myty2_a;
8+
typedef struct { int a; char b; } __attribute__((__aligned__(16))) myty2;
9+
10+
typedef int __attribute__ ((vector_size (32))) myty3;
11+
typedef int __attribute__ ((__vector_size__ (32))) myty3_a;
12+
13+
typedef int __attribute__ ((mode(DI))) myty4;
14+
]]
15+
16+
assert(ffi.sizeof("myty1") == 5 and
17+
ffi.sizeof("myty1_a") == 5 and
18+
ffi.alignof("myty2") == 16 and
19+
ffi.alignof("myty2_a") == 16 and
20+
ffi.sizeof("myty3") == 32 and
21+
ffi.sizeof("myty3_a") == 32 and
22+
ffi.sizeof("myty4") == 8)

src/x64/test/unit_test.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/bin/sh
2+
DIR=$(cd $(dirname $0); pwd)
3+
cd $DIR
4+
5+
LUAJIT=$DIR/../../luajit
6+
HASERR=0
7+
8+
find $DIR/unit -name "*.lua" -print | while read x; do
9+
$LUAJIT $x >/dev/null 2>/dev/null
10+
if [ $? -eq 0 ]; then
11+
echo "$x ok"
12+
else
13+
HASERR=1
14+
echo "$x failed"
15+
fi
16+
done
17+
18+
if [ $HASERR -eq 0 ]; then
19+
exit 0
20+
fi
21+
22+
exit 1

0 commit comments

Comments
 (0)