diff options
-rw-r--r-- | lib/libzpool/Makefile.am | 3 | ||||
-rw-r--r-- | module/lua/Makefile.in | 3 | ||||
-rw-r--r-- | module/lua/lapi.c | 5 | ||||
-rw-r--r-- | module/lua/lbitlib.c | 213 | ||||
-rw-r--r-- | module/lua/lcorolib.c | 2 | ||||
-rw-r--r-- | module/lua/ldo.c | 12 | ||||
-rw-r--r-- | module/lua/ldump.c | 173 | ||||
-rw-r--r-- | module/lua/lstrlib.c | 5 | ||||
-rw-r--r-- | module/lua/lundump.c | 258 | ||||
-rw-r--r-- | module/lua/lundump.h | 30 | ||||
-rw-r--r-- | tests/runfiles/linux.run | 4 | ||||
-rw-r--r-- | tests/zfs-tests/tests/functional/channel_program/lua_core/Makefile.am | 5 | ||||
-rw-r--r-- | tests/zfs-tests/tests/functional/channel_program/lua_core/tst.lib_base.lua | 469 | ||||
-rw-r--r-- | tests/zfs-tests/tests/functional/channel_program/lua_core/tst.lib_coroutine.lua | 362 | ||||
-rw-r--r-- | tests/zfs-tests/tests/functional/channel_program/lua_core/tst.lib_strings.lua | 241 | ||||
-rw-r--r-- | tests/zfs-tests/tests/functional/channel_program/lua_core/tst.lib_table.lua | 252 | ||||
-rwxr-xr-x | tests/zfs-tests/tests/functional/channel_program/lua_core/tst.libraries.ksh | 31 |
17 files changed, 1372 insertions, 696 deletions
diff --git a/lib/libzpool/Makefile.am b/lib/libzpool/Makefile.am index 4ea7961f9..4edc60cb0 100644 --- a/lib/libzpool/Makefile.am +++ b/lib/libzpool/Makefile.am @@ -149,14 +149,12 @@ LUA_C = \ lapi.c \ lauxlib.c \ lbaselib.c \ - lbitlib.c \ lcode.c \ lcompat.c \ lcorolib.c \ lctype.c \ ldebug.c \ ldo.c \ - ldump.c \ lfunc.c \ lgc.c \ llex.c \ @@ -170,7 +168,6 @@ LUA_C = \ ltable.c \ ltablib.c \ ltm.c \ - lundump.c \ lvm.c \ lzio.c diff --git a/module/lua/Makefile.in b/module/lua/Makefile.in index 6728a5aae..d49065fbe 100644 --- a/module/lua/Makefile.in +++ b/module/lua/Makefile.in @@ -15,14 +15,12 @@ ccflags-y += $(NO_UNUSED_BUT_SET_VARIABLE) $(MODULE)-objs += lapi.o $(MODULE)-objs += lauxlib.o $(MODULE)-objs += lbaselib.o -$(MODULE)-objs += lbitlib.o $(MODULE)-objs += lcode.o $(MODULE)-objs += lcompat.o $(MODULE)-objs += lcorolib.o $(MODULE)-objs += lctype.o $(MODULE)-objs += ldebug.o $(MODULE)-objs += ldo.o -$(MODULE)-objs += ldump.o $(MODULE)-objs += lfunc.o $(MODULE)-objs += lgc.o $(MODULE)-objs += llex.o @@ -36,7 +34,6 @@ $(MODULE)-objs += lstrlib.o $(MODULE)-objs += ltable.o $(MODULE)-objs += ltablib.o $(MODULE)-objs += ltm.o -$(MODULE)-objs += lundump.o $(MODULE)-objs += lvm.o $(MODULE)-objs += lzio.o $(MODULE)-objs += setjmp/setjmp.o diff --git a/module/lua/lapi.c b/module/lua/lapi.c index cd2cc42ae..c8b49dc63 100644 --- a/module/lua/lapi.c +++ b/module/lua/lapi.c @@ -22,7 +22,6 @@ #include "lstring.h" #include "ltable.h" #include "ltm.h" -#include "lundump.h" #include "lvm.h" @@ -991,7 +990,7 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, return status; } - +#if defined(LUA_USE_DUMP) LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) { int status; TValue *o; @@ -1005,7 +1004,7 @@ LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) { lua_unlock(L); return status; } - +#endif LUA_API int lua_status (lua_State *L) { return L->status; diff --git a/module/lua/lbitlib.c b/module/lua/lbitlib.c deleted file mode 100644 index 1294e45fc..000000000 --- a/module/lua/lbitlib.c +++ /dev/null @@ -1,213 +0,0 @@ -/* BEGIN CSTYLED */ -/* -** $Id: lbitlib.c,v 1.18.1.2 2013/07/09 18:01:41 roberto Exp $ -** Standard library for bitwise operations -** See Copyright Notice in lua.h -*/ - -#define lbitlib_c -#define LUA_LIB - -#include <sys/lua/lua.h> - -#include <sys/lua/lauxlib.h> -#include <sys/lua/lualib.h> - - -/* number of bits to consider in a number */ -#if !defined(LUA_NBITS) -#define LUA_NBITS 32 -#endif - - -#define ALLONES (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1)) - -/* macro to trim extra bits */ -#define trim(x) ((x) & ALLONES) - - -/* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */ -#define mask(n) (~((ALLONES << 1) << ((n) - 1))) - - -typedef lua_Unsigned b_uint; - - - -static b_uint andaux (lua_State *L) { - int i, n = lua_gettop(L); - b_uint r = ~(b_uint)0; - for (i = 1; i <= n; i++) - r &= luaL_checkunsigned(L, i); - return trim(r); -} - - -static int b_and (lua_State *L) { - b_uint r = andaux(L); - lua_pushunsigned(L, r); - return 1; -} - - -static int b_test (lua_State *L) { - b_uint r = andaux(L); - lua_pushboolean(L, r != 0); - return 1; -} - - -static int b_or (lua_State *L) { - int i, n = lua_gettop(L); - b_uint r = 0; - for (i = 1; i <= n; i++) - r |= luaL_checkunsigned(L, i); - lua_pushunsigned(L, trim(r)); - return 1; -} - - -static int b_xor (lua_State *L) { - int i, n = lua_gettop(L); - b_uint r = 0; - for (i = 1; i <= n; i++) - r ^= luaL_checkunsigned(L, i); - lua_pushunsigned(L, trim(r)); - return 1; -} - - -static int b_not (lua_State *L) { - b_uint r = ~luaL_checkunsigned(L, 1); - lua_pushunsigned(L, trim(r)); - return 1; -} - - -static int b_shift (lua_State *L, b_uint r, int i) { - if (i < 0) { /* shift right? */ - i = -i; - r = trim(r); - if (i >= LUA_NBITS) r = 0; - else r >>= i; - } - else { /* shift left */ - if (i >= LUA_NBITS) r = 0; - else r <<= i; - r = trim(r); - } - lua_pushunsigned(L, r); - return 1; -} - - -static int b_lshift (lua_State *L) { - return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkint(L, 2)); -} - - -static int b_rshift (lua_State *L) { - return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkint(L, 2)); -} - - -static int b_arshift (lua_State *L) { - b_uint r = luaL_checkunsigned(L, 1); - int i = luaL_checkint(L, 2); - if (i < 0 || !(r & ((b_uint)1 << (LUA_NBITS - 1)))) - return b_shift(L, r, -i); - else { /* arithmetic shift for 'negative' number */ - if (i >= LUA_NBITS) r = ALLONES; - else - r = trim((r >> i) | ~(~(b_uint)0 >> i)); /* add signal bit */ - lua_pushunsigned(L, r); - return 1; - } -} - - -static int b_rot (lua_State *L, int i) { - b_uint r = luaL_checkunsigned(L, 1); - i &= (LUA_NBITS - 1); /* i = i % NBITS */ - r = trim(r); - if (i != 0) /* avoid undefined shift of LUA_NBITS when i == 0 */ - r = (r << i) | (r >> (LUA_NBITS - i)); - lua_pushunsigned(L, trim(r)); - return 1; -} - - -static int b_lrot (lua_State *L) { - return b_rot(L, luaL_checkint(L, 2)); -} - - -static int b_rrot (lua_State *L) { - return b_rot(L, -luaL_checkint(L, 2)); -} - - -/* -** get field and width arguments for field-manipulation functions, -** checking whether they are valid. -** ('luaL_error' called without 'return' to avoid later warnings about -** 'width' being used uninitialized.) -*/ -static int fieldargs (lua_State *L, int farg, int *width) { - int f = luaL_checkint(L, farg); - int w = luaL_optint(L, farg + 1, 1); - luaL_argcheck(L, 0 <= f, farg, "field cannot be negative"); - luaL_argcheck(L, 0 < w, farg + 1, "width must be positive"); - if (f + w > LUA_NBITS) - luaL_error(L, "trying to access non-existent bits"); - *width = w; - return f; -} - - -static int b_extract (lua_State *L) { - int w; - b_uint r = luaL_checkunsigned(L, 1); - int f = fieldargs(L, 2, &w); - r = (r >> f) & mask(w); - lua_pushunsigned(L, r); - return 1; -} - - -static int b_replace (lua_State *L) { - int w; - b_uint r = luaL_checkunsigned(L, 1); - b_uint v = luaL_checkunsigned(L, 2); - int f = fieldargs(L, 3, &w); - int m = mask(w); - v &= m; /* erase bits outside given width */ - r = (r & ~(m << f)) | (v << f); - lua_pushunsigned(L, r); - return 1; -} - - -static const luaL_Reg bitlib[] = { - {"arshift", b_arshift}, - {"band", b_and}, - {"bnot", b_not}, - {"bor", b_or}, - {"bxor", b_xor}, - {"btest", b_test}, - {"extract", b_extract}, - {"lrotate", b_lrot}, - {"lshift", b_lshift}, - {"replace", b_replace}, - {"rrotate", b_rrot}, - {"rshift", b_rshift}, - {NULL, NULL} -}; - - - -LUAMOD_API int luaopen_bit32 (lua_State *L) { - luaL_newlib(L, bitlib); - return 1; -} -/* END CSTYLED */ diff --git a/module/lua/lcorolib.c b/module/lua/lcorolib.c index 1e96a9aeb..af8bea695 100644 --- a/module/lua/lcorolib.c +++ b/module/lua/lcorolib.c @@ -57,7 +57,7 @@ static int luaB_coresume (lua_State *L) { else { lua_pushboolean(L, 1); lua_insert(L, -(r + 1)); - return r + 1; /* return true + `resume' returns */ + return r + 1; /* return true + 'resume' returns */ } } diff --git a/module/lua/ldo.c b/module/lua/ldo.c index ead29427e..aca02b234 100644 --- a/module/lua/ldo.c +++ b/module/lua/ldo.c @@ -24,7 +24,6 @@ #include "lstring.h" #include "ltable.h" #include "ltm.h" -#include "lundump.h" #include "lvm.h" #include "lzio.h" @@ -684,14 +683,9 @@ static void f_parser (lua_State *L, void *ud) { Closure *cl; struct SParser *p = cast(struct SParser *, ud); int c = zgetc(p->z); /* read first character */ - if (c == LUA_SIGNATURE[0]) { - checkmode(L, p->mode, "binary"); - cl = luaU_undump(L, p->z, &p->buff, p->name); - } - else { - checkmode(L, p->mode, "text"); - cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c); - } + lua_assert(c != LUA_SIGNATURE[0]); /* binary not supported */ + checkmode(L, p->mode, "text"); + cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c); lua_assert(cl->l.nupvalues == cl->l.p->sizeupvalues); for (i = 0; i < cl->l.nupvalues; i++) { /* initialize upvalues */ UpVal *up = luaF_newupval(L); diff --git a/module/lua/ldump.c b/module/lua/ldump.c deleted file mode 100644 index b448869ff..000000000 --- a/module/lua/ldump.c +++ /dev/null @@ -1,173 +0,0 @@ -/* BEGIN CSTYLED */ -/* -** $Id: ldump.c,v 2.17.1.1 2013/04/12 18:48:47 roberto Exp $ -** save precompiled Lua chunks -** See Copyright Notice in lua.h -*/ - -#define ldump_c -#define LUA_CORE - -#include <sys/lua/lua.h> - -#include "lobject.h" -#include "lstate.h" -#include "lundump.h" - -typedef struct { - lua_State* L; - lua_Writer writer; - void* data; - int strip; - int status; -} DumpState; - -#define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D) -#define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D) - -static void DumpBlock(const void* b, size_t size, DumpState* D) -{ - if (D->status==0) - { - lua_unlock(D->L); - D->status=(*D->writer)(D->L,b,size,D->data); - lua_lock(D->L); - } -} - -static void DumpChar(int y, DumpState* D) -{ - char x=(char)y; - DumpVar(x,D); -} - -static void DumpInt(int x, DumpState* D) -{ - DumpVar(x,D); -} - -static void DumpNumber(lua_Number x, DumpState* D) -{ - DumpVar(x,D); -} - -static void DumpVector(const void* b, int n, size_t size, DumpState* D) -{ - DumpInt(n,D); - DumpMem(b,n,size,D); -} - -static void DumpString(const TString* s, DumpState* D) -{ - if (s==NULL) - { - size_t size=0; - DumpVar(size,D); - } - else - { - size_t size=s->tsv.len+1; /* include trailing '\0' */ - DumpVar(size,D); - DumpBlock(getstr(s),size*sizeof(char),D); - } -} - -#define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D) - -static void DumpFunction(const Proto* f, DumpState* D); - -static void DumpConstants(const Proto* f, DumpState* D) -{ - int i,n=f->sizek; - DumpInt(n,D); - for (i=0; i<n; i++) - { - const TValue* o=&f->k[i]; - DumpChar(ttypenv(o),D); - switch (ttypenv(o)) - { - case LUA_TNIL: - break; - case LUA_TBOOLEAN: - DumpChar(bvalue(o),D); - break; - case LUA_TNUMBER: - DumpNumber(nvalue(o),D); - break; - case LUA_TSTRING: - DumpString(rawtsvalue(o),D); - break; - default: lua_assert(0); - } - } - n=f->sizep; - DumpInt(n,D); - for (i=0; i<n; i++) DumpFunction(f->p[i],D); -} - -static void DumpUpvalues(const Proto* f, DumpState* D) -{ - int i,n=f->sizeupvalues; - DumpInt(n,D); - for (i=0; i<n; i++) - { - DumpChar(f->upvalues[i].instack,D); - DumpChar(f->upvalues[i].idx,D); - } -} - -static void DumpDebug(const Proto* f, DumpState* D) -{ - int i,n; - DumpString((D->strip) ? NULL : f->source,D); - n= (D->strip) ? 0 : f->sizelineinfo; - DumpVector(f->lineinfo,n,sizeof(int),D); - n= (D->strip) ? 0 : f->sizelocvars; - DumpInt(n,D); - for (i=0; i<n; i++) - { - DumpString(f->locvars[i].varname,D); - DumpInt(f->locvars[i].startpc,D); - DumpInt(f->locvars[i].endpc,D); - } - n= (D->strip) ? 0 : f->sizeupvalues; - DumpInt(n,D); - for (i=0; i<n; i++) DumpString(f->upvalues[i].name,D); -} - -static void DumpFunction(const Proto* f, DumpState* D) -{ - DumpInt(f->linedefined,D); - DumpInt(f->lastlinedefined,D); - DumpChar(f->numparams,D); - DumpChar(f->is_vararg,D); - DumpChar(f->maxstacksize,D); - DumpCode(f,D); - DumpConstants(f,D); - DumpUpvalues(f,D); - DumpDebug(f,D); -} - -static void DumpHeader(DumpState* D) -{ - lu_byte h[LUAC_HEADERSIZE]; - luaU_header(h); - DumpBlock(h,LUAC_HEADERSIZE,D); -} - -/* -** dump Lua function as precompiled chunk -*/ -int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip) -{ - DumpState D; - D.L=L; - D.writer=w; - D.data=data; - D.strip=strip; - D.status=0; - DumpHeader(&D); - DumpFunction(f,&D); - return D.status; -} -/* END CSTYLED */ diff --git a/module/lua/lstrlib.c b/module/lua/lstrlib.c index 7020f1bb7..cff5e894d 100644 --- a/module/lua/lstrlib.c +++ b/module/lua/lstrlib.c @@ -174,6 +174,7 @@ static int str_char (lua_State *L) { } +#if defined(LUA_USE_DUMP) static int writer (lua_State *L, const void* b, size_t size, void* B) { (void)L; luaL_addlstring((luaL_Buffer*) B, (const char *)b, size); @@ -191,7 +192,7 @@ static int str_dump (lua_State *L) { luaL_pushresult(&b); return 1; } - +#endif /* @@ -992,7 +993,9 @@ static int str_format (lua_State *L) { static const luaL_Reg strlib[] = { {"byte", str_byte}, {"char", str_char}, +#if defined(LUA_USE_DUMP) {"dump", str_dump}, +#endif {"find", str_find}, {"format", str_format}, {"gmatch", str_gmatch}, diff --git a/module/lua/lundump.c b/module/lua/lundump.c deleted file mode 100644 index 66efc5469..000000000 --- a/module/lua/lundump.c +++ /dev/null @@ -1,258 +0,0 @@ -/* BEGIN CSTYLED */ -/* -** $Id: lundump.c,v 2.22.1.1 2013/04/12 18:48:47 roberto Exp $ -** load precompiled Lua chunks -** See Copyright Notice in lua.h -*/ - -#define lundump_c -#define LUA_CORE - -#include <sys/lua/lua.h> - -#include "ldebug.h" -#include "ldo.h" -#include "lfunc.h" -#include "lmem.h" -#include "lobject.h" -#include "lstring.h" -#include "lundump.h" -#include "lzio.h" - -typedef struct { - lua_State* L; - ZIO* Z; - Mbuffer* b; - const char* name; -} LoadState; - -static l_noret error(LoadState* S, const char* why) -{ - luaO_pushfstring(S->L,"%s: %s precompiled chunk",S->name,why); - luaD_throw(S->L,LUA_ERRSYNTAX); -} - -#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size)) -#define LoadByte(S) (lu_byte)LoadChar(S) -#define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x)) -#define LoadVector(S,b,n,size) LoadMem(S,b,n,size) - -#if !defined(luai_verifycode) -#define luai_verifycode(L,b,f) /* empty */ -#endif - -static void LoadBlock(LoadState* S, void* b, size_t size) -{ - if (luaZ_read(S->Z,b,size)!=0) error(S,"truncated"); -} - -static int LoadChar(LoadState* S) -{ - char x; - LoadVar(S,x); - return x; -} - -static int LoadInt(LoadState* S) -{ - int x; - LoadVar(S,x); - if (x<0) error(S,"corrupted"); - return x; -} - -static lua_Number LoadNumber(LoadState* S) -{ - lua_Number x; - LoadVar(S,x); - return x; -} - -static TString* LoadString(LoadState* S) -{ - size_t size; - LoadVar(S,size); - if (size==0) - return NULL; - else - { - char* s=luaZ_openspace(S->L,S->b,size); - LoadBlock(S,s,size*sizeof(char)); - return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ - } -} - -static void LoadCode(LoadState* S, Proto* f) -{ - int n=LoadInt(S); - f->code=luaM_newvector(S->L,n,Instruction); - f->sizecode=n; - LoadVector(S,f->code,n,sizeof(Instruction)); -} - -static void LoadFunction(LoadState* S, Proto* f); - -static void LoadConstants(LoadState* S, Proto* f) -{ - int i,n; - n=LoadInt(S); - f->k=luaM_newvector(S->L,n,TValue); - f->sizek=n; - for (i=0; i<n; i++) setnilvalue(&f->k[i]); - for (i=0; i<n; i++) - { - TValue* o=&f->k[i]; - int t=LoadChar(S); - switch (t) - { - case LUA_TNIL: - setnilvalue(o); - break; - case LUA_TBOOLEAN: - setbvalue(o,LoadChar(S)); - break; - case LUA_TNUMBER: - setnvalue(o,LoadNumber(S)); - break; - case LUA_TSTRING: - setsvalue2n(S->L,o,LoadString(S)); - break; - default: lua_assert(0); - } - } - n=LoadInt(S); - f->p=luaM_newvector(S->L,n,Proto*); - f->sizep=n; - for (i=0; i<n; i++) f->p[i]=NULL; - for (i=0; i<n; i++) - { - f->p[i]=luaF_newproto(S->L); - LoadFunction(S,f->p[i]); - } -} - -static void LoadUpvalues(LoadState* S, Proto* f) -{ - int i,n; - n=LoadInt(S); - f->upvalues=luaM_newvector(S->L,n,Upvaldesc); - f->sizeupvalues=n; - for (i=0; i<n; i++) f->upvalues[i].name=NULL; - for (i=0; i<n; i++) - { - f->upvalues[i].instack=LoadByte(S); - f->upvalues[i].idx=LoadByte(S); - } -} - -static void LoadDebug(LoadState* S, Proto* f) -{ - int i,n; - f->source=LoadString(S); - n=LoadInt(S); - f->lineinfo=luaM_newvector(S->L,n,int); - f->sizelineinfo=n; - LoadVector(S,f->lineinfo,n,sizeof(int)); - n=LoadInt(S); - f->locvars=luaM_newvector(S->L,n,LocVar); - f->sizelocvars=n; - for (i=0; i<n; i++) f->locvars[i].varname=NULL; - for (i=0; i<n; i++) - { - f->locvars[i].varname=LoadString(S); - f->locvars[i].startpc=LoadInt(S); - f->locvars[i].endpc=LoadInt(S); - } - n=LoadInt(S); - for (i=0; i<n; i++) f->upvalues[i].name=LoadString(S); -} - -static void LoadFunction(LoadState* S, Proto* f) -{ - f->linedefined=LoadInt(S); - f->lastlinedefined=LoadInt(S); - f->numparams=LoadByte(S); - f->is_vararg=LoadByte(S); - f->maxstacksize=LoadByte(S); - LoadCode(S,f); - LoadConstants(S,f); - LoadUpvalues(S,f); - LoadDebug(S,f); -} - -/* the code below must be consistent with the code in luaU_header */ -#define N0 LUAC_HEADERSIZE -#define N1 (sizeof(LUA_SIGNATURE)-sizeof(char)) -#define N2 N1+2 -#define N3 N2+6 - -static void LoadHeader(LoadState* S) -{ - lu_byte h[LUAC_HEADERSIZE]; - lu_byte s[LUAC_HEADERSIZE]; - luaU_header(h); - memcpy(s,h,sizeof(char)); /* first char already read */ - LoadBlock(S,s+sizeof(char),LUAC_HEADERSIZE-sizeof(char)); - if (memcmp(h,s,N0)==0) return; - if (memcmp(h,s,N1)!=0) error(S,"not a"); - if (memcmp(h,s,N2)!=0) error(S,"version mismatch in"); - if (memcmp(h,s,N3)!=0) error(S,"incompatible"); else error(S,"corrupted"); -} - -/* -** load precompiled chunk -*/ -Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name) -{ - LoadState S; - Closure* cl; - if (*name=='@' || *name=='=') - S.name=name+1; - else if (*name==LUA_SIGNATURE[0]) - S.name="binary string"; - else - S.name=name; - S.L=L; - S.Z=Z; - S.b=buff; - LoadHeader(&S); - cl=luaF_newLclosure(L,1); - setclLvalue(L,L->top,cl); incr_top(L); - cl->l.p=luaF_newproto(L); - LoadFunction(&S,cl->l.p); - if (cl->l.p->sizeupvalues != 1) - { - Proto* p=cl->l.p; - cl=luaF_newLclosure(L,cl->l.p->sizeupvalues); - cl->l.p=p; - setclLvalue(L,L->top-1,cl); - } - luai_verifycode(L,buff,cl->l.p); - return cl; -} - -#define MYINT(s) (s[0]-'0') -#define VERSION MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR) -#define FORMAT 0 /* this is the official format */ - -/* -* make header for precompiled chunks -* if you change the code below be sure to update LoadHeader and FORMAT above -* and LUAC_HEADERSIZE in lundump.h -*/ -void luaU_header (lu_byte* h) -{ - int x=1; - memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-sizeof(char)); - h+=sizeof(LUA_SIGNATURE)-sizeof(char); - *h++=cast_byte(VERSION); - *h++=cast_byte(FORMAT); - *h++=cast_byte(*(char*)&x); /* endianness */ - *h++=cast_byte(sizeof(int)); - *h++=cast_byte(sizeof(size_t)); - *h++=cast_byte(sizeof(Instruction)); - *h++=cast_byte(sizeof(lua_Number)); - *h++=cast_byte(((lua_Number)0.5)==0); /* is lua_Number integral? */ - memcpy(h,LUAC_TAIL,sizeof(LUAC_TAIL)-sizeof(char)); -} -/* END CSTYLED */ diff --git a/module/lua/lundump.h b/module/lua/lundump.h deleted file mode 100644 index dc8b0d817..000000000 --- a/module/lua/lundump.h +++ /dev/null @@ -1,30 +0,0 @@ -/* BEGIN CSTYLED */ -/* -** $Id: lundump.h,v 1.39.1.1 2013/04/12 18:48:47 roberto Exp $ -** load precompiled Lua chunks -** See Copyright Notice in lua.h -*/ - -#ifndef lundump_h -#define lundump_h - -#include "lobject.h" -#include "lzio.h" - -/* load one chunk; from lundump.c */ -LUAI_FUNC Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name); - -/* make header; from lundump.c */ -LUAI_FUNC void luaU_header (lu_byte* h); - -/* dump one chunk; from ldump.c */ -LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip); - -/* data to catch conversion errors */ -#define LUAC_TAIL "\x19\x93\r\n\x1a\n" - -/* size in bytes of header of binary files */ -#define LUAC_HEADERSIZE (sizeof(LUA_SIGNATURE)-sizeof(char)+2+6+sizeof(LUAC_TAIL)-sizeof(char)) - -#endif -/* END CSTYLED */ diff --git a/tests/runfiles/linux.run b/tests/runfiles/linux.run index 1bd3fd605..6bbc3a6b6 100644 --- a/tests/runfiles/linux.run +++ b/tests/runfiles/linux.run @@ -65,8 +65,8 @@ tags = ['functional', 'casenorm'] [tests/functional/channel_program/lua_core] tests = ['tst.args_to_lua', 'tst.divide_by_zero', 'tst.exists', 'tst.integer_illegal', 'tst.integer_overflow', 'tst.language_functions_neg', - 'tst.language_functions_pos', 'tst.large_prog', 'tst.memory_limit', - 'tst.nested_neg', 'tst.nested_pos', 'tst.nvlist_to_lua', + 'tst.language_functions_pos', 'tst.large_prog', 'tst.libraries', + 'tst.memory_limit', 'tst.nested_neg', 'tst.nested_pos', 'tst.nvlist_to_lua', 'tst.recursive_neg', 'tst.recursive_pos', 'tst.return_large', 'tst.return_nvlist_neg', 'tst.return_nvlist_pos', 'tst.return_recursive_table', 'tst.timeout'] diff --git a/tests/zfs-tests/tests/functional/channel_program/lua_core/Makefile.am b/tests/zfs-tests/tests/functional/channel_program/lua_core/Makefile.am index dba3da0f1..6de88d723 100644 --- a/tests/zfs-tests/tests/functional/channel_program/lua_core/Makefile.am +++ b/tests/zfs-tests/tests/functional/channel_program/lua_core/Makefile.am @@ -17,6 +17,11 @@ dist_pkgdata_SCRIPTS = \ tst.large_prog.ksh \ tst.large_prog.out \ tst.large_prog.zcp \ + tst.lib_base.lua \ + tst.lib_coroutine.lua \ + tst.lib_strings.lua \ + tst.lib_table.lua \ + tst.libraries.ksh \ tst.memory_limit.ksh \ tst.nested_neg.ksh \ tst.nested_neg.zcp \ diff --git a/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.lib_base.lua b/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.lib_base.lua new file mode 100644 index 000000000..c39144959 --- /dev/null +++ b/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.lib_base.lua @@ -0,0 +1,469 @@ +--[[ +--***************************************************************************** +--* Copyright (C) 1994-2016 Lua.org, PUC-Rio. +--* +--* Permission is hereby granted, free of charge, to any person obtaining +--* a copy of this software and associated documentation files (the +--* "Software"), to deal in the Software without restriction, including +--* without limitation the rights to use, copy, modify, merge, publish, +--* distribute, sublicense, and/or sell copies of the Software, and to +--* permit persons to whom the Software is furnished to do so, subject to +--* the following conditions: +--* +--* The above copyright notice and this permission notice shall be +--* included in all copies or substantial portions of the Software. +--* +--* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +--* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +--* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +--* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +--* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +--* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +--* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +--***************************************************************************** +--]] + +-- testing metatables + +X = 20; B = 30 + +_ENV = 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={name = "NAME"}; setmetatable(a, {__metatable = "xuxu", + __tostring=function(x) return x.name end}) +assert(getmetatable(a) == "xuxu") +assert(tostring(a) == "NAME") + +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 +setmetatable(t, t) -- causes a bug in 5.1 ! +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 + + +setmetatable(t, nil) +function f (t, ...) return t, {...} end +t.__call = f + +do + local x,y = a(table.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") +t.__len = f("len") + +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) +assert(#a == a) +assert(cap[0] == "len" and cap[1] == a) + + +-- test for rawlen +t = setmetatable({1,2,3}, {__len = function () return 10 end}) +assert(#t == 10 and rawlen(t) == 3) +assert(rawlen"abc" == 3) +assert(rawlen(string.rep('a', 1000)) == 1000) + +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(1 < Op(1)) and (Op(1) < 2) and not(2 < Op(1))) + assert(not(Op('a')<Op('a')) and (Op('a')<Op('b')) and not(Op('b')<Op('a'))) + assert(not('a' < Op('a')) and (Op('a') < '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((1 >= Op(1)) and not(1 >= Op(2)) and (Op(2) >= 1)) + assert((Op('a')>=Op('a')) and not(Op('a')>=Op('b')) and (Op('b')>=Op('a'))) + assert(('a' >= Op('a')) and not(Op('a') >= '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 +assert((c..d..c..d).val == 'cdcd') +x = c..d +assert(getmetatable(x) == t and x.val == 'cd') +x = 0 .."a".."b"..c..d.."e".."f".."g" +assert(x.val == "0abcdefg") + + +-- concat metamethod x numbers (bug in 5.1.1) +c = {} +local x +setmetatable(c, {__concat = function (a,b) + assert(type(a) == "number" and b == c or type(b) == "number" and a == c) + return c +end}) +assert(c..5 == c and 5 .. c == c) +assert(4 .. c .. 5 == c and 4 .. 5 .. 6 .. 7 .. c == c) + + +-- 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 +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) + + +local _g = _G +_ENV = setmetatable({}, {__index=function (_,k) return _g[k] end}) + + +a = {} +rawset(a, "x", 1, 2, 3) +assert(a.x == 1 and rawget(a, "x", 3) == 1) + + +-- bug in 5.1 +T, K, V = nil +grandparent = {} +grandparent.__newindex = function(t,k,v) T=t; K=k; V=v end + +parent = {} +parent.__newindex = parent +setmetatable(parent, grandparent) + +child = setmetatable({}, parent) +child.foo = 10 --> CRASH (on some machines) +assert(T == parent and K == "foo" and V == 10) + + +-- testing 'tonumber' +assert(tonumber{} == nil) +assert(tonumber('-012') == -010-2) +assert(tonumber("0xffffffffffff") == 2^(4*12) - 1) +assert(tonumber("0x"..string.rep("f", 150)) == 2^(4*150) - 1) + +-- testing 'tonumber' with base +assert(tonumber(' 001010 ', 2) == 10) +assert(tonumber(' 001010 ', 10) == 1010) +assert(tonumber(' -1010 ', 2) == -10) +assert(tonumber('10', 36) == 36) +assert(tonumber(' -10 ', 36) == -36) +assert(tonumber(' +1Z ', 36) == 36 + 35) +assert(tonumber(' -1z ', 36) == -36 + -35) +assert(tonumber('-fFfa', 16) == -(10+(16*(15+(16*(15+(16*15))))))) +assert(tonumber(string.rep('1', 42), 2) + 1 == 2^42) +assert(tonumber(string.rep('1', 34), 2) + 1 == 2^34) +assert(tonumber('ffffFFFF', 16)+1 == 2^32) +assert(tonumber('0ffffFFFF', 16)+1 == 2^32) +assert(tonumber('-0ffffffFFFF', 16) - 1 == -2^40) +for i = 2,36 do + assert(tonumber('\t10000000000\t', i) == i^10) +end + +-- testing 'tonumber' for invalid formats +function f(...) + if select('#', ...) == 1 then + return (...) + else + return "***" + end +end + +assert(f(tonumber('fFfa', 15)) == nil) +assert(f(tonumber('099', 8)) == nil) +assert(f(tonumber('1\0', 2)) == nil) +assert(f(tonumber('', 8)) == nil) +assert(f(tonumber(' ', 9)) == nil) +assert(f(tonumber('0xf', 10)) == nil) + +assert(f(tonumber('inf')) == nil) +assert(f(tonumber(' INF ')) == nil) +assert(f(tonumber('Nan')) == nil) +assert(f(tonumber('nan')) == nil) + +assert(f(tonumber('')) == nil) +assert(f(tonumber('1 a')) == nil) +assert(f(tonumber('1\0')) == nil) +assert(f(tonumber('1 \0')) == nil) +assert(f(tonumber('1\0 ')) == nil) +assert(f(tonumber('e1')) == nil) +assert(f(tonumber('e 1')) == nil) + + +-- testing 'tonumber' for invalid hexadecimal formats +assert(tonumber('0x') == nil) +assert(tonumber('x') == nil) +assert(tonumber('x3') == nil) +assert(tonumber('00x2') == nil) +assert(tonumber('0x 2') == nil) +assert(tonumber('0 x2') == nil) +assert(tonumber('23x') == nil) +assert(tonumber('- 0xaa') == nil) + + +-- testing hexadecimal numerals +assert(tonumber('+0x2') == 2) +assert(tonumber('-0xaA') == -170) +assert(tonumber('-0xffFFFfff') == -2^32 + 1) + + +-- testing 'tostring' +assert(tostring("alo") == "alo") +assert(tostring(12) == "12") +assert(tostring(1234567890123) == '1234567890123') +assert(type(tostring("hello")) == "string") +assert(tostring(true) == "true") +assert(tostring(false) == "false") +assert(string.find(tostring{}, 'table:')) +assert(string.find(tostring(select), 'function:')) +assert(#tostring('\0') == 1) + + +-- testing ipairs +local x = 0 +for k,v in ipairs{10,20,30;x=12} do + x = x + 1 + assert(k == x and v == x * 10) +end + +for _ in ipairs{x=12, y=24} do assert(nil) end + +-- test for 'false' x ipair +x = false +local i = 0 +for k,v in ipairs{true,false,true,false} do + i = i + 1 + x = not x + assert(x == v) +end +assert(i == 4) + + +return "OK" diff --git a/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.lib_coroutine.lua b/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.lib_coroutine.lua new file mode 100644 index 000000000..e0e9e2a64 --- /dev/null +++ b/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.lib_coroutine.lua @@ -0,0 +1,362 @@ +--[[ +--***************************************************************************** +--* Copyright (C) 1994-2016 Lua.org, PUC-Rio. +--* +--* Permission is hereby granted, free of charge, to any person obtaining +--* a copy of this software and associated documentation files (the +--* "Software"), to deal in the Software without restriction, including +--* without limitation the rights to use, copy, modify, merge, publish, +--* distribute, sublicense, and/or sell copies of the Software, and to +--* permit persons to whom the Software is furnished to do so, subject to +--* the following conditions: +--* +--* The above copyright notice and this permission notice shall be +--* included in all copies or substantial portions of the Software. +--* +--* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +--* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +--* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +--* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +--* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +--* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +--* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +--***************************************************************************** +--]] + +local f + +local main, ismain = coroutine.running() +assert(type(main) == "thread" and ismain) +assert(not coroutine.resume(main)) + + +-- tests for multiple yield/resume arguments + +local function eqtab (t1, t2) + assert(#t1 == #t2) + for i = 1, #t1 do + local v = t1[i] + assert(t2[i] == v) + end +end + +_G.x = nil -- declare x +function foo (a, ...) + local x, y = coroutine.running() + assert(x == f and y == false) + -- next call should not corrupt coroutine (but must fail, + -- as it attempts to resume the running coroutine) + assert(coroutine.resume(f) == false) + assert(coroutine.status(f) == "running") + local arg = {...} + for i=1,#arg do + _G.x = {coroutine.yield(table.unpack(arg[i]))} + end + return table.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 implemented with co-routines + +-- generate all the numbers from 2 to n +function gen (n) + return coroutine.wrap(function () + for i=2,n do coroutine.yield(i) end + end) +end + +-- filter the numbers generated by 'g', removing multiples of 'p' +function filter (p, g) + return coroutine.wrap(function () + for n in g do + if n%p ~= 0 then coroutine.yield(n) end + end + end) +end + +-- generate primes up to 20 +local x = gen(20) +local a = {} +while 1 do + local n = x() + if n == nil then break end + table.insert(a, n) + x = filter(n, x) +end + +-- expect 8 primes and last one is 19 +assert(#a == 8 and a[#a] == 19) +x, a = nil + + +-- yielding across C boundaries + +co = coroutine.wrap(function() + coroutine.yield(20) + return 30 + end) + +assert(co() == 20) +assert(co() == 30) + + +local f = function (s, i) return coroutine.yield(i) end +function f (a, b) a = coroutine.yield(a); error{a + b} end +function g(x) return x[1]*2 end + + +-- unyieldable C call +do + local function f (c) + return c .. c + end + + local co = coroutine.wrap(function (c) + local s = string.gsub("a", ".", f) + return s + end) + assert(co() == "aa") +end + + +-- errors in coroutines +function foo () + coroutine.yield(3) + error(foo) +end + +function goo() foo() end +x = coroutine.wrap(goo) +assert(x() == 3) +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) + coroutine.yield(10, 20) + assert(coroutine.resume(current_co) == false) + coroutine.yield(23) + return 10 +end + +local co = coroutine.create(co_func) +local a,b,c = coroutine.resume(co, co) +assert(a == true and b == 10 and c == 20) +a,b = coroutine.resume(co, co) +assert(a == true and b == 23) +a,b = coroutine.resume(co, co) +assert(a == true and b == 10) +assert(coroutine.resume(co, co) == false) +assert(coroutine.resume(co, co) == false) + + +-- attempt to resume 'normal' coroutine +local co1, co2 +co1 = coroutine.create(function () return co2() end) +co2 = coroutine.wrap(function () + assert(coroutine.status(co1) == 'normal') + assert(not coroutine.resume(co1)) + coroutine.yield(3) + end) + +a,b = coroutine.resume(co1) +assert(a and b == 3) +assert(coroutine.status(co1) == 'dead') + + +-- 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) + + +-- leaving a pending coroutine open +_X = coroutine.wrap(function () + local a = 10 + local x = function () a = a+1 end + coroutine.yield() + end) + +_X() + +assert(coroutine.running() == main) + + + +-- testing yields inside metamethods + +local mt = { + __eq = function(a,b) coroutine.yield(nil, "eq"); return a.x == b.x end, + __lt = function(a,b) coroutine.yield(nil, "lt"); return a.x < b.x end, + __le = function(a,b) coroutine.yield(nil, "le"); return a - b <= 0 end, + __add = function(a,b) coroutine.yield(nil, "add"); return a.x + b.x end, + __sub = function(a,b) coroutine.yield(nil, "sub"); return a.x - b.x end, + __mod = function(a,b) coroutine.yield(nil, "mod"); return a.x % b.x end, + __unm = function(a,b) coroutine.yield(nil, "unm"); return -a.x end, + + __concat = function(a,b) + coroutine.yield(nil, "concat"); + a = type(a) == "table" and a.x or a + b = type(b) == "table" and b.x or b + return a .. b + end, + __index = function (t,k) coroutine.yield(nil, "idx"); return t.k[k] end, + __newindex = function (t,k,v) coroutine.yield(nil, "nidx"); t.k[k] = v end, +} + + +local function new (x) + return setmetatable({x = x, k = {}}, mt) +end + + +local a = new(10) +local b = new(12) +local c = new"hello" + +local function run (f, t) + local i = 1 + local c = coroutine.wrap(f) + while true do + local res, stat = c() + if res then assert(t[i] == nil); return res, t end + assert(stat == t[i]) + i = i + 1 + end +end + + +assert(run(function () if (a>=b) then return '>=' else return '<' end end, + {"le", "sub"}) == "<") +-- '<=' using '<' +mt.__le = nil +assert(run(function () if (a<=b) then return '<=' else return '>' end end, + {"lt"}) == "<=") +assert(run(function () if (a==b) then return '==' else return '~=' end end, + {"eq"}) == "~=") + +assert(run(function () return a % b end, {"mod"}) == 10) + +assert(run(function () return a..b end, {"concat"}) == "1012") + +assert(run(function() return a .. b .. c .. a end, + {"concat", "concat", "concat"}) == "1012hello10") + +assert(run(function() return "a" .. "b" .. a .. "c" .. c .. b .. "x" end, + {"concat", "concat", "concat"}) == "ab10chello12x") + + +-- testing yields inside 'for' iterators + +local f = function (s, i) + if i%2 == 0 then coroutine.yield(nil, "for") end + if i < s then return i + 1 end + end + +assert(run(function () + local s = 0 + for i in f, 4, 0 do s = s + i end + return s + end, {"for", "for", "for"}) == 10) + + +return "OK" diff --git a/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.lib_strings.lua b/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.lib_strings.lua new file mode 100644 index 000000000..1725fd123 --- /dev/null +++ b/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.lib_strings.lua @@ -0,0 +1,241 @@ +--[[ +--***************************************************************************** +--* Copyright (C) 1994-2016 Lua.org, PUC-Rio. +--* +--* Permission is hereby granted, free of charge, to any person obtaining +--* a copy of this software and associated documentation files (the +--* "Software"), to deal in the Software without restriction, including +--* without limitation the rights to use, copy, modify, merge, publish, +--* distribute, sublicense, and/or sell copies of the Software, and to +--* permit persons to whom the Software is furnished to do so, subject to +--* the following conditions: +--* +--* The above copyright notice and this permission notice shall be +--* included in all copies or substantial portions of the Software. +--* +--* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +--* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +--* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +--* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +--* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +--* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +--* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +--***************************************************************************** +--]] + +-- testing string library + +local maxi, mini = 0x7fffffffffffffff, 0x8000000000000000 + +-- testing string.sub +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("123456789", mini, -4) == "123456") +assert(string.sub("123456789", mini, maxi) == "123456789") +assert(string.sub("123456789", mini, mini) == "") +assert(string.sub("\000123456789",3,5) == "234") +assert(("\000123456789"):sub(8) == "789") + +-- testing string.find +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("", "", 1) == 1) +assert(not string.find("", "", 2)) +assert(string.find('', 'aaa', 1) == nil) +assert(('alo(.)alo'):find('(.)', 1, 1) == 4) + +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) + +-- testing string.byte/string.char +assert(string.byte("a") == 97) +assert(string.byte("\xe4") > 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("\xe4"), 0) == "\0\xe4\0") +assert(string.char(string.byte("\xe4l\0\195\179u", 1, -1)) == "\xe4l\0\195\179u") +assert(string.char(string.byte("\xe4l\0\195\179u", 1, 0)) == "") +assert(string.char(string.byte("\xe4l\0\195\179u", -10, 100)) == "\xe4l\0\195\179u") + +assert(string.upper("ab\0c") == "AB\0C") +assert(string.lower("\0ABCc%$") == "\0abcc%$") +assert(string.rep('teste', 0) == '') +assert(string.rep('t\195\169s\00t\195\170', 2) == 't\195\169s\0t\195\170t\195\169s\000t\195\170') +assert(string.rep('', 10) == '') + +-- repetitions with separator +assert(string.rep('teste', 0, 'xuxu') == '') +assert(string.rep('teste', 1, 'xuxu') == 'teste') +assert(string.rep('\1\0\1', 2, '\0\0') == '\1\0\1\0\0\1\0\1') +assert(string.rep('', 10, '.') == string.rep('.', 9)) + +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 + + +x = '"\195\174lo"\n\\' +assert(string.format('%q%s', x, x) == '"\\"\195\174lo\\"\\\n\\\\""\195\174lo"\n\\') +assert(string.format('%q', "\0") == [["\0"]]) +x = "\0\1\0023\5\0009" +assert(string.format("\0%c\0%c%x\0", string.byte("\xe4"), string.byte("b"), 140) == + "\0\xe4\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") +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")) + +-- format x tostring +assert(string.format("%s %s", nil, true) == "nil true") +assert(string.format("%s %.4s", false, true) == "false true") +assert(string.format("%.3s %.3s", false, true) == "fal tru") + + +-- testing large numbers for format +do + local max, min = 0x7fffffff, -0x80000000 -- "large" for 32 bits + assert(string.sub(string.format("%8x", -1), -8) == "ffffffff") + assert(string.format("%x", max) == "7fffffff") + assert(string.sub(string.format("%x", min), -8) == "80000000") + assert(string.format("%d", max) == "2147483647") + assert(string.format("%d", min) == "-2147483648") + assert(string.format("%u", 0xffffffff) == "4294967295") + assert(string.format("%o", 0xABCD) == "125715") + + max, min = 0x7fffffffffffffff, -0x8000000000000000 + assert(string.format("0x%8X", 0x8f000003) == "0x8F000003") + assert(string.format("%d", 2^53) == "9007199254740992") + assert(string.format("%x", max) == "7fffffffffffffff") + assert(string.format("%x", min) == "8000000000000000") + assert(string.format("%d", max) == "9223372036854775807") + assert(string.format("%d", min) == "-9223372036854775808") +end + + +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,300 do a[i] = "xuxu" end +assert(table.concat(a, "123").."123" == string.rep("xuxu123", 300)) +assert(table.concat(a, "b", 20, 20) == "xuxu") +assert(table.concat(a, "", 20, 21) == "xuxuxuxu") +assert(table.concat(a, "x", 22, 21) == "") +assert(table.concat(a, "3", 299) == "xuxu3xuxu") +assert(table.concat({}, "x", 2^31-1, 2^31-2) == "") +assert(table.concat({}, "x", -2^31+1, -2^31) == "") +assert(table.concat({}, "x", 2^31-1, -2^31) == "") +assert(table.concat({[2^31-1] = "alo"}, "x", 2^31-1, 2^31-1) == "alo") + +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) == "") + + +-- tests for 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(#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 gsub +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 + +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$') == '=======') + +-- 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 match +assert(string.match('==========', '^([=]*)=%1$') == nil) +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.match("ab\0\1\2c", "[\0-\2]+") == "\0\1\2") + +return "OK" diff --git a/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.lib_table.lua b/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.lib_table.lua new file mode 100644 index 000000000..500117b19 --- /dev/null +++ b/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.lib_table.lua @@ -0,0 +1,252 @@ +--[[ +--***************************************************************************** +--* Copyright (C) 1994-2016 Lua.org, PUC-Rio. +--* +--* Permission is hereby granted, free of charge, to any person obtaining +--* a copy of this software and associated documentation files (the +--* "Software"), to deal in the Software without restriction, including +--* without limitation the rights to use, copy, modify, merge, publish, +--* distribute, sublicense, and/or sell copies of the Software, and to +--* permit persons to whom the Software is furnished to do so, subject to +--* the following conditions: +--* +--* The above copyright notice and this permission notice shall be +--* included in all copies or substantial portions of the Software. +--* +--* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +--* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +--* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +--* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +--* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +--* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +--* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +--***************************************************************************** +--]] + +-- testing table library + +-- workaround missing pcall in zfs lua implementation +local function tuple(...) + return {n=select('#', ...), ...} +end + +function pcall(f, ...) + local co = coroutine.create(f) + local res = tuple(coroutine.resume(co, ...)) + if res[1] and coroutine.status(co) == "suspended" then + res[1] = false + end + return table.unpack(res, 1, res.n) +end + + +-- workaround missing math lib in zfs lua implementation +local A1, A2 = 727595, 798405 -- 5^17=D20*A1+A2 +local D20, D40 = 1048576, 1099511627776 -- 2^20, 2^40 +local X1, X2 = 0, 1 +function rand() + local U = X2*A2 + local V = (X1*A2 + X2*A1) % D20 + V = (V*D20 + U) % D40 + X1 = V/D20 + X2 = V - X1*D20 + return V*100/D40 +end + + +-- testing unpack + +local unpack = table.unpack + +local x,y,z,a,n +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(#x == lim and x[1] == 1 and x[lim] == lim) +x = {unpack(a, lim-2)} +assert(#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) + +if not _no32 then + assert(not pcall(unpack, {}, 0, 2^31-1)) + assert(not pcall(unpack, {}, 1, 2^31-1)) + assert(not pcall(unpack, {}, -(2^31), 2^31-1)) + assert(not pcall(unpack, {}, -(2^31 - 1), 2^31-1)) + assert(pcall(unpack, {}, 2^31-1, 0)) + assert(pcall(unpack, {}, 2^31-1, 1)) + pcall(unpack, {}, 1, 2^31) + a, b = unpack({[2^31-1] = 20}, 2^31-1, 2^31-1) + assert(a == 20 and b == nil) + a, b = unpack({[2^31-1] = 20}, 2^31-2, 2^31-1) + assert(a == nil and b == 20) +end + +-- testing pack + +a = table.pack() +assert(a[1] == nil and a.n == 0) + +a = table.pack(table) +assert(a[1] == table and a.n == 1) + +a = table.pack(nil, nil, nil, nil) +assert(a[1] == nil and a.n == 4) + + +-- testing sort + + +-- test checks for invalid order functions +local function check (t) + local function f(a, b) assert(a and b); return true end + local s, e = pcall(table.sort, t, f) + assert(not s and e:find("invalid order function")) +end + +check{1,2,3,4} +check{1,2,3,4,5} +check{1,2,3,4,5,6} + + +function check (a, f) + f = f or function (x,y) return x<y end; + for n = #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) + +function perm (s, n) + n = n or #s + if n == 1 then + local t = {unpack(s)} + table.sort(t) + check(t) + else + for i = 1, n do + s[i], s[n] = s[n], s[i] + perm(s, n - 1) + s[i], s[n] = s[n], s[i] + end + end +end + +perm{} +perm{1} +perm{1,2} +perm{1,2,3} +perm{1,2,3,4} +perm{2,2,3,4} +perm{1,2,3,4,5} +perm{1,2,3,3,5} +perm{1,2,3,4,5,6} +perm{2,2,3,3,5,6} + +limit = 5000 + +a = {} +for i=1,limit do + a[i] = rand() +end + +table.sort(a) +check(a) + +table.sort(a) +check(a) + +a = {} +for i=1,limit do + a[i] = rand() +end + +i=0 +table.sort(a, function(x,y) i=i+1; return y<x end) +check(a, function(x,y) return y<x end) + + +table.sort{} -- empty array + +for i=1,limit do a[i] = false end +table.sort(a, function(x,y) return nil end) +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) + +tt = {__lt = function (a,b) return a.val < b.val end} +a = {} +for i=1,10 do a[i] = {val=rand(100)}; setmetatable(a[i], tt); end +table.sort(a) +check(a, tt.__lt) +check(a) + + +-- test remove +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, #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 #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(#a == 0 and a.n == nil) + +a = {10,20,30,40} +assert(a[#a] == 40) +assert(table.remove(a, #a) == 40) +assert(a[#a] == 30) +assert(table.remove(a, 2) == 20) +assert(a[#a] == 30 and #a == 2) + + +return "OK" diff --git a/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.libraries.ksh b/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.libraries.ksh new file mode 100755 index 000000000..71afabdbe --- /dev/null +++ b/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.libraries.ksh @@ -0,0 +1,31 @@ +#!/bin/ksh -p +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2017 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib + +verify_runnable "global" +arch=$(uname -m) + +if [[ "$arch" == "sparc64" ]]; then + log_note "Skipping lib_base and lib_coroutine on sparc64 to avoid stack overflow" +else + log_must_program $TESTPOOL $ZCP_ROOT/lua_core/tst.lib_base.lua + log_must_program $TESTPOOL $ZCP_ROOT/lua_core/tst.lib_coroutine.lua +fi +log_must_program $TESTPOOL $ZCP_ROOT/lua_core/tst.lib_strings.lua +log_must_program -m 40000000 $TESTPOOL $ZCP_ROOT/lua_core/tst.lib_table.lua + +log_pass "lua libraries work correctly." |