diff --git a/README.md b/README.md index 5529599..673bc04 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,11 @@ Simple Device Model (SDM) is an open source instrument control and data acquisition framework for Windows and Linux. It provides interactive GUI tools for operating devices and visualizing the received data. It is also fully scriptable with [Lua](https://www.lua.org). -A device is represented by SDM as a set of control channels and data sources, hence the “model”. SDM interacts with devices by writing and reading registers and memory blocks in the device’s virtual address space, and by reading data streams from the device. The actual code that communicates with hardware is encapsulated within a plugin. SDM framework is [well documented](https://github.com/SimpleDeviceModel/sdm/raw/develop/doc/manual.pdf) and includes an SDK which contains headers and libraries to develop plugins in C and C++ as well as a few example plugins. +A device is represented in SDM as a set of control channels and data sources, hence the “model”. SDM interacts with devices by writing and reading registers and memory blocks in the device’s virtual address space, and by reading data streams from the device. The actual code that communicates with hardware is encapsulated within a plugin. SDM framework is [well documented](https://github.com/SimpleDeviceModel/sdm/raw/develop/doc/manual.pdf) and includes an SDK which contains headers and libraries to develop plugins in C and C++ as well as a few example plugins. SDM is most useful for prototyping, allowing the developer to quickly create virtual control panels and dashboards. Scriptability makes it also well suited for test and measurement automation. -[Project Website](https://simpledevicemodel.github.io) +[**Project Website**](https://simpledevicemodel.github.io) + +![Screenshot](https://simpledevicemodel.github.io/assets/mainwindow.png) + diff --git a/doc/changelog.txt b/doc/changelog.txt index 37806da..bc01a28 100644 --- a/doc/changelog.txt +++ b/doc/changelog.txt @@ -1,3 +1,12 @@ +======================== +SDM 1.0.3 +------------------------ +Released on 2022-02-02 +======================== + +* bundled Lua interpreter updated to 5.4.4 +* pluginprovider: SDMAbstractQueuedSource class redesigned + ======================== SDM 1.0.2 ------------------------ diff --git a/doc/manual.pdf b/doc/manual.pdf index 7883f80..3e484e3 100644 Binary files a/doc/manual.pdf and b/doc/manual.pdf differ diff --git a/src/3rdparty/lua/CMakeLists.txt b/src/3rdparty/lua/CMakeLists.txt index d9467d2..b61d3ea 100644 --- a/src/3rdparty/lua/CMakeLists.txt +++ b/src/3rdparty/lua/CMakeLists.txt @@ -31,7 +31,7 @@ endif() # LIBRARY ########################### -set(LUA_SRC_PATH "lua-5.4.3/src") +set(LUA_SRC_PATH "lua-5.4.4/src") set(LUA_SRC_LIST "${LUA_SRC_PATH}/lapi.c" "${LUA_SRC_PATH}/lauxlib.c" "${LUA_SRC_PATH}/lbaselib.c" "${LUA_SRC_PATH}/lcode.c" "${LUA_SRC_PATH}/lcorolib.c" "${LUA_SRC_PATH}/lctype.c" "${LUA_SRC_PATH}/ldblib.c" "${LUA_SRC_PATH}/ldebug.c" "${LUA_SRC_PATH}/ldo.c" "${LUA_SRC_PATH}/ldump.c" "${LUA_SRC_PATH}/lfunc.c" "${LUA_SRC_PATH}/lgc.c" "${LUA_SRC_PATH}/linit.c" "${LUA_SRC_PATH}/liolib.c" "${LUA_SRC_PATH}/llex.c" "${LUA_SRC_PATH}/lmathlib.c" "${LUA_SRC_PATH}/lmem.c" "${LUA_SRC_PATH}/loadlib.c" "${LUA_SRC_PATH}/lobject.c" "${LUA_SRC_PATH}/lopcodes.c" "${LUA_SRC_PATH}/loslib.c" "${LUA_SRC_PATH}/lparser.c" "${LUA_SRC_PATH}/lstate.c" "${LUA_SRC_PATH}/lstring.c" "${LUA_SRC_PATH}/lstrlib.c" "${LUA_SRC_PATH}/ltable.c" "${LUA_SRC_PATH}/ltablib.c" "${LUA_SRC_PATH}/ltm.c" "${LUA_SRC_PATH}/lundump.c" "${LUA_SRC_PATH}/lutf8lib.c" "${LUA_SRC_PATH}/lvm.c" "${LUA_SRC_PATH}/lzio.c") diff --git a/src/3rdparty/lua/lua-5.4.3/Makefile b/src/3rdparty/lua/lua-5.4.4/Makefile similarity index 99% rename from src/3rdparty/lua/lua-5.4.3/Makefile rename to src/3rdparty/lua/lua-5.4.4/Makefile index fed75b3..fef1af4 100644 --- a/src/3rdparty/lua/lua-5.4.3/Makefile +++ b/src/3rdparty/lua/lua-5.4.4/Makefile @@ -46,7 +46,7 @@ TO_MAN= lua.1 luac.1 # Lua version and release. V= 5.4 -R= $V.3 +R= $V.4 # Targets start here. all: $(PLAT) diff --git a/src/3rdparty/lua/lua-5.4.3/README b/src/3rdparty/lua/lua-5.4.4/README similarity index 70% rename from src/3rdparty/lua/lua-5.4.3/README rename to src/3rdparty/lua/lua-5.4.4/README index ebd4db0..c394c69 100644 --- a/src/3rdparty/lua/lua-5.4.3/README +++ b/src/3rdparty/lua/lua-5.4.4/README @@ -1,5 +1,5 @@ -This is Lua 5.4.3, released on 15 Mar 2021. +This is Lua 5.4.4, released on 13 Jan 2022. For installation instructions, license details, and further information about Lua, see doc/readme.html. diff --git a/src/3rdparty/lua/lua-5.4.3/doc/contents.html b/src/3rdparty/lua/lua-5.4.4/doc/contents.html similarity index 99% rename from src/3rdparty/lua/lua-5.4.3/doc/contents.html rename to src/3rdparty/lua/lua-5.4.4/doc/contents.html index 7ecf1c7..ab82eb4 100644 --- a/src/3rdparty/lua/lua-5.4.3/doc/contents.html +++ b/src/3rdparty/lua/lua-5.4.4/doc/contents.html @@ -32,7 +32,7 @@

-Copyright © 2020–2021 Lua.org, PUC-Rio. +Copyright © 2020–2022 Lua.org, PUC-Rio. Freely available under the terms of the Lua license. @@ -664,10 +664,10 @@

constants

diff --git a/src/3rdparty/lua/lua-5.4.3/doc/index.css b/src/3rdparty/lua/lua-5.4.4/doc/index.css similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/doc/index.css rename to src/3rdparty/lua/lua-5.4.4/doc/index.css diff --git a/src/3rdparty/lua/lua-5.4.3/doc/logo.gif b/src/3rdparty/lua/lua-5.4.4/doc/logo.gif similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/doc/logo.gif rename to src/3rdparty/lua/lua-5.4.4/doc/logo.gif diff --git a/src/3rdparty/lua/lua-5.4.3/doc/lua.1 b/src/3rdparty/lua/lua-5.4.4/doc/lua.1 similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/doc/lua.1 rename to src/3rdparty/lua/lua-5.4.4/doc/lua.1 diff --git a/src/3rdparty/lua/lua-5.4.3/doc/lua.css b/src/3rdparty/lua/lua-5.4.4/doc/lua.css similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/doc/lua.css rename to src/3rdparty/lua/lua-5.4.4/doc/lua.css diff --git a/src/3rdparty/lua/lua-5.4.3/doc/luac.1 b/src/3rdparty/lua/lua-5.4.4/doc/luac.1 similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/doc/luac.1 rename to src/3rdparty/lua/lua-5.4.4/doc/luac.1 diff --git a/src/3rdparty/lua/lua-5.4.3/doc/manual.css b/src/3rdparty/lua/lua-5.4.4/doc/manual.css similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/doc/manual.css rename to src/3rdparty/lua/lua-5.4.4/doc/manual.css diff --git a/src/3rdparty/lua/lua-5.4.3/doc/manual.html b/src/3rdparty/lua/lua-5.4.4/doc/manual.html similarity index 99% rename from src/3rdparty/lua/lua-5.4.3/doc/manual.html rename to src/3rdparty/lua/lua-5.4.4/doc/manual.html index b7f5d71..61a8220 100644 --- a/src/3rdparty/lua/lua-5.4.3/doc/manual.html +++ b/src/3rdparty/lua/lua-5.4.4/doc/manual.html @@ -19,7 +19,7 @@

-Copyright © 2020–2021 Lua.org, PUC-Rio. +Copyright © 2020–2022 Lua.org, PUC-Rio. Freely available under the terms of the Lua license. @@ -961,11 +961,8 @@

2.5.3 – Garbage-Collection Metamethods

-Finalizers cannot yield. -Except for that, they can do anything, -such as raise errors, create new objects, -or even run the garbage collector. -However, because they can run in unpredictable times, +Finalizers cannot yield nor run the garbage collector. +Because they can run in unpredictable times, it is good practice to restrict each finalizer to the minimum necessary to properly release its associated resource. @@ -1636,8 +1633,10 @@

3.3.3 – Assignment

-The assignment statement first evaluates all its expressions -and only then the assignments are performed. +If a variable is both assigned and read +inside a multiple assignment, +Lua ensures all reads get the value of the variable +before the assignment. Thus the code

@@ -1661,6 +1660,14 @@ 

3.3.3 – Assignment

cyclically permutes the values of x, y, and z. +

+Note that this guarantee covers only accesses +syntactically inside the assignment statement. +If a function or a metamethod called during the assignment +changes the value of a variable, +Lua gives no guarantees about the order of that access. + +

An assignment to a global name x = val is equivalent to the assignment @@ -2416,16 +2423,21 @@

3.4.7 – The Length Operator

The length operator applied on a table returns a border in that table. -A border in a table t is any natural number +A border in a table t is any non-negative integer that satisfies the following condition:

-     (border == 0 or t[border] ~= nil) and t[border + 1] == nil
+     (border == 0 or t[border] ~= nil) and
+     (t[border + 1] == nil or border == math.maxinteger)
 

In words, -a border is any (natural) index present in the table -that is followed by an absent index -(or zero, when index 1 is absent). +a border is any positive integer index present in the table +that is followed by an absent index, +plus two limit cases: +zero, when index 1 is absent; +and the maximum value for an integer, when that index is present. +Note that keys that are not positive integers +do not interfere with borders.

@@ -2436,12 +2448,9 @@

3.4.7 – The Length Operator

and therefore it is not a sequence. (The nil at index 4 is called a hole.) The table {nil, 20, 30, nil, nil, 60, nil} -has three borders (0, 3, and 6) and three holes -(at indices 1, 4, and 5), +has three borders (0, 3, and 6), so it is not a sequence, too. The table {} is a sequence with border 0. -Note that non-natural keys do not interfere -with whether a table is a sequence.

@@ -2459,7 +2468,7 @@

3.4.7 – The Length Operator

The computation of the length of a table has a guaranteed worst time of O(log n), -where n is the largest natural key in the table. +where n is the largest integer key in the table.

@@ -3979,6 +3988,10 @@

4.6 – Functions and Types

see collectgarbage. +

+This function should not be called by a finalizer. + + @@ -5933,7 +5946,10 @@

4.7 – The Debug Interface

lua_getstack fills only the private part of this structure, for later use. To fill the other fields of lua_Debug with useful information, -you must call lua_getinfo. +you must call lua_getinfo with an appropriate parameter. +(Specifically, to get a field, +you must add the letter between parentheses in the field's comment +to the parameter what of lua_getinfo.)

@@ -6110,11 +6126,25 @@

4.7 – The Debug Interface

Each character in the string what selects some fields of the structure ar to be filled or -a value to be pushed on the stack: +a value to be pushed on the stack. +(These characters are also documented in the declaration of +the structure lua_Debug, +between parentheses in the comments following each field.)

-This specifier does not support modifiers (flags, width, length). +This specifier does not support modifiers (flags, width, precision).

@@ -10362,7 +10387,7 @@

6.7 – Mathematical Functions

Returns a boolean, -true if and only if integer m is below integer n when +true if and only if integer m is below integer n when they are compared as unsigned integers. @@ -11924,10 +11949,10 @@

9 – The Complete Syntax of Lua

diff --git a/src/3rdparty/lua/lua-5.4.3/doc/osi-certified-72x60.png b/src/3rdparty/lua/lua-5.4.4/doc/osi-certified-72x60.png similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/doc/osi-certified-72x60.png rename to src/3rdparty/lua/lua-5.4.4/doc/osi-certified-72x60.png diff --git a/src/3rdparty/lua/lua-5.4.3/doc/readme.html b/src/3rdparty/lua/lua-5.4.4/doc/readme.html similarity index 98% rename from src/3rdparty/lua/lua-5.4.3/doc/readme.html rename to src/3rdparty/lua/lua-5.4.4/doc/readme.html index f9aef58..8afe38d 100644 --- a/src/3rdparty/lua/lua-5.4.3/doc/readme.html +++ b/src/3rdparty/lua/lua-5.4.4/doc/readme.html @@ -110,7 +110,7 @@

Building Lua

  1. Open a terminal window and move to -the top-level directory, which is named lua-5.4.3. +the top-level directory, which is named lua-5.4.4. The Makefile there controls both the build process and the installation process.

  2. @@ -303,7 +303,7 @@

    License

    this.
    -Copyright © 1994–2021 Lua.org, PUC-Rio. +Copyright © 1994–2022 Lua.org, PUC-Rio.

    Permission is hereby granted, free of charge, to any person obtaining a copy @@ -330,10 +330,10 @@

    License

    diff --git a/src/3rdparty/lua/lua-5.4.3/src/Makefile b/src/3rdparty/lua/lua-5.4.4/src/Makefile similarity index 99% rename from src/3rdparty/lua/lua-5.4.3/src/Makefile rename to src/3rdparty/lua/lua-5.4.4/src/Makefile index f78c0b8..1907381 100644 --- a/src/3rdparty/lua/lua-5.4.3/src/Makefile +++ b/src/3rdparty/lua/lua-5.4.4/src/Makefile @@ -79,7 +79,7 @@ echo: @echo "PLAT= $(PLAT)" @echo "CC= $(CC)" @echo "CFLAGS= $(CFLAGS)" - @echo "LDFLAGS= $(SYSLDFLAGS)" + @echo "LDFLAGS= $(LDFLAGS)" @echo "LIBS= $(LIBS)" @echo "AR= $(AR)" @echo "RANLIB= $(RANLIB)" diff --git a/src/3rdparty/lua/lua-5.4.3/src/lapi.c b/src/3rdparty/lua/lua-5.4.4/src/lapi.c similarity index 96% rename from src/3rdparty/lua/lua-5.4.3/src/lapi.c rename to src/3rdparty/lua/lua-5.4.4/src/lapi.c index f8f70cd..5ee6579 100644 --- a/src/3rdparty/lua/lua-5.4.3/src/lapi.c +++ b/src/3rdparty/lua/lua-5.4.4/src/lapi.c @@ -53,6 +53,10 @@ const char lua_ident[] = #define isupvalue(i) ((i) < LUA_REGISTRYINDEX) +/* +** Convert an acceptable index to a pointer to its respective value. +** Non-valid indices return the special nil value 'G(L)->nilvalue'. +*/ static TValue *index2value (lua_State *L, int idx) { CallInfo *ci = L->ci; if (idx > 0) { @@ -70,22 +74,28 @@ static TValue *index2value (lua_State *L, int idx) { else { /* upvalues */ idx = LUA_REGISTRYINDEX - idx; api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large"); - if (ttislcf(s2v(ci->func))) /* light C function? */ - return &G(L)->nilvalue; /* it has no upvalues */ - else { + if (ttisCclosure(s2v(ci->func))) { /* C closure? */ CClosure *func = clCvalue(s2v(ci->func)); return (idx <= func->nupvalues) ? &func->upvalue[idx-1] : &G(L)->nilvalue; } + else { /* light C function or Lua function (through a hook)?) */ + api_check(L, ttislcf(s2v(ci->func)), "caller not a C function"); + return &G(L)->nilvalue; /* no upvalues */ + } } } -static StkId index2stack (lua_State *L, int idx) { + +/* +** Convert a valid actual index (not a pseudo-index) to its address. +*/ +l_sinline StkId index2stack (lua_State *L, int idx) { CallInfo *ci = L->ci; if (idx > 0) { StkId o = ci->func + idx; - api_check(L, o < L->top, "unacceptable index"); + api_check(L, o < L->top, "invalid index"); return o; } else { /* non-positive index */ @@ -218,7 +228,7 @@ LUA_API void lua_closeslot (lua_State *L, int idx) { ** Note that we move(copy) only the value inside the stack. ** (We do not move additional fields that may exist.) */ -static void reverse (lua_State *L, StkId from, StkId to) { +l_sinline void reverse (lua_State *L, StkId from, StkId to) { for (; from < to; from++, to--) { TValue temp; setobj(L, &temp, s2v(from)); @@ -438,7 +448,7 @@ LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { } -static void *touserdata (const TValue *o) { +l_sinline void *touserdata (const TValue *o) { switch (ttype(o)) { case LUA_TUSERDATA: return getudatamem(uvalue(o)); case LUA_TLIGHTUSERDATA: return pvalue(o); @@ -630,7 +640,7 @@ LUA_API int lua_pushthread (lua_State *L) { */ -static int auxgetstr (lua_State *L, const TValue *t, const char *k) { +l_sinline int auxgetstr (lua_State *L, const TValue *t, const char *k) { const TValue *slot; TString *str = luaS_new(L, k); if (luaV_fastget(L, t, str, slot, luaH_getstr)) { @@ -705,7 +715,7 @@ LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) { } -static int finishrawget (lua_State *L, const TValue *val) { +l_sinline int finishrawget (lua_State *L, const TValue *val) { if (isempty(val)) /* avoid copying empty items to the stack */ setnilvalue(s2v(L->top)); else @@ -1126,18 +1136,19 @@ LUA_API int lua_status (lua_State *L) { LUA_API int lua_gc (lua_State *L, int what, ...) { va_list argp; int res = 0; - global_State *g; + global_State *g = G(L); + if (g->gcstp & GCSTPGC) /* internal stop? */ + return -1; /* all options are invalid when stopped */ lua_lock(L); - g = G(L); va_start(argp, what); switch (what) { case LUA_GCSTOP: { - g->gcrunning = 0; + g->gcstp = GCSTPUSR; /* stopped by the user */ break; } case LUA_GCRESTART: { luaE_setdebt(g, 0); - g->gcrunning = 1; + g->gcstp = 0; /* (GCSTPGC must be already zero here) */ break; } case LUA_GCCOLLECT: { @@ -1156,8 +1167,8 @@ LUA_API int lua_gc (lua_State *L, int what, ...) { case LUA_GCSTEP: { int data = va_arg(argp, int); l_mem debt = 1; /* =1 to signal that it did an actual step */ - lu_byte oldrunning = g->gcrunning; - g->gcrunning = 1; /* allow GC to run */ + lu_byte oldstp = g->gcstp; + g->gcstp = 0; /* allow GC to run (GCSTPGC must be zero here) */ if (data == 0) { luaE_setdebt(g, 0); /* do a basic step */ luaC_step(L); @@ -1167,7 +1178,7 @@ LUA_API int lua_gc (lua_State *L, int what, ...) { luaE_setdebt(g, debt); luaC_checkGC(L); } - g->gcrunning = oldrunning; /* restore previous state */ + g->gcstp = oldstp; /* restore previous state */ if (debt > 0 && g->gcstate == GCSpause) /* end of cycle? */ res = 1; /* signal it */ break; @@ -1185,7 +1196,7 @@ LUA_API int lua_gc (lua_State *L, int what, ...) { break; } case LUA_GCISRUNNING: { - res = g->gcrunning; + res = gcrunning(g); break; } case LUA_GCGEN: { diff --git a/src/3rdparty/lua/lua-5.4.3/src/lapi.h b/src/3rdparty/lua/lua-5.4.4/src/lapi.h similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/lapi.h rename to src/3rdparty/lua/lua-5.4.4/src/lapi.h diff --git a/src/3rdparty/lua/lua-5.4.3/src/lauxlib.c b/src/3rdparty/lua/lua-5.4.4/src/lauxlib.c similarity index 99% rename from src/3rdparty/lua/lua-5.4.3/src/lauxlib.c rename to src/3rdparty/lua/lua-5.4.4/src/lauxlib.c index 94835ef..8ed1da1 100644 --- a/src/3rdparty/lua/lua-5.4.3/src/lauxlib.c +++ b/src/3rdparty/lua/lua-5.4.4/src/lauxlib.c @@ -881,6 +881,7 @@ LUALIB_API lua_Integer luaL_len (lua_State *L, int idx) { LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) { + idx = lua_absindex(L,idx); if (luaL_callmeta(L, idx, "__tostring")) { /* metafield? */ if (!lua_isstring(L, -1)) luaL_error(L, "'__tostring' must return a string"); diff --git a/src/3rdparty/lua/lua-5.4.3/src/lauxlib.h b/src/3rdparty/lua/lua-5.4.4/src/lauxlib.h similarity index 97% rename from src/3rdparty/lua/lua-5.4.3/src/lauxlib.h rename to src/3rdparty/lua/lua-5.4.4/src/lauxlib.h index 72f70e7..5b977e2 100644 --- a/src/3rdparty/lua/lua-5.4.3/src/lauxlib.h +++ b/src/3rdparty/lua/lua-5.4.4/src/lauxlib.h @@ -102,7 +102,7 @@ LUALIB_API lua_State *(luaL_newstate) (void); LUALIB_API lua_Integer (luaL_len) (lua_State *L, int idx); -LUALIB_API void luaL_addgsub (luaL_Buffer *b, const char *s, +LUALIB_API void (luaL_addgsub) (luaL_Buffer *b, const char *s, const char *p, const char *r); LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, const char *r); @@ -154,6 +154,14 @@ LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname, #define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL) +/* +** Perform arithmetic operations on lua_Integer values with wrap-around +** semantics, as the Lua core does. +*/ +#define luaL_intop(op,v1,v2) \ + ((lua_Integer)((lua_Unsigned)(v1) op (lua_Unsigned)(v2))) + + /* push the value used to represent failure/error */ #define luaL_pushfail(L) lua_pushnil(L) diff --git a/src/3rdparty/lua/lua-5.4.3/src/lbaselib.c b/src/3rdparty/lua/lua-5.4.4/src/lbaselib.c similarity index 94% rename from src/3rdparty/lua/lua-5.4.3/src/lbaselib.c rename to src/3rdparty/lua/lua-5.4.4/src/lbaselib.c index 83ad306..1d60c9d 100644 --- a/src/3rdparty/lua/lua-5.4.3/src/lbaselib.c +++ b/src/3rdparty/lua/lua-5.4.4/src/lbaselib.c @@ -182,12 +182,20 @@ static int luaB_rawset (lua_State *L) { static int pushmode (lua_State *L, int oldmode) { - lua_pushstring(L, (oldmode == LUA_GCINC) ? "incremental" - : "generational"); + if (oldmode == -1) + luaL_pushfail(L); /* invalid call to 'lua_gc' */ + else + lua_pushstring(L, (oldmode == LUA_GCINC) ? "incremental" + : "generational"); return 1; } +/* +** check whether call to 'lua_gc' was valid (not inside a finalizer) +*/ +#define checkvalres(res) { if (res == -1) break; } + static int luaB_collectgarbage (lua_State *L) { static const char *const opts[] = {"stop", "restart", "collect", "count", "step", "setpause", "setstepmul", @@ -200,12 +208,14 @@ static int luaB_collectgarbage (lua_State *L) { case LUA_GCCOUNT: { int k = lua_gc(L, o); int b = lua_gc(L, LUA_GCCOUNTB); + checkvalres(k); lua_pushnumber(L, (lua_Number)k + ((lua_Number)b/1024)); return 1; } case LUA_GCSTEP: { int step = (int)luaL_optinteger(L, 2, 0); int res = lua_gc(L, o, step); + checkvalres(res); lua_pushboolean(L, res); return 1; } @@ -213,11 +223,13 @@ static int luaB_collectgarbage (lua_State *L) { case LUA_GCSETSTEPMUL: { int p = (int)luaL_optinteger(L, 2, 0); int previous = lua_gc(L, o, p); + checkvalres(previous); lua_pushinteger(L, previous); return 1; } case LUA_GCISRUNNING: { int res = lua_gc(L, o); + checkvalres(res); lua_pushboolean(L, res); return 1; } @@ -234,10 +246,13 @@ static int luaB_collectgarbage (lua_State *L) { } default: { int res = lua_gc(L, o); + checkvalres(res); lua_pushinteger(L, res); return 1; } } + luaL_pushfail(L); /* invalid call (inside a finalizer) */ + return 1; } @@ -261,6 +276,11 @@ static int luaB_next (lua_State *L) { } +static int pairscont (lua_State *L, int status, lua_KContext k) { + (void)L; (void)status; (void)k; /* unused */ + return 3; +} + static int luaB_pairs (lua_State *L) { luaL_checkany(L, 1); if (luaL_getmetafield(L, 1, "__pairs") == LUA_TNIL) { /* no metamethod? */ @@ -270,7 +290,7 @@ static int luaB_pairs (lua_State *L) { } else { lua_pushvalue(L, 1); /* argument 'self' to metamethod */ - lua_call(L, 1, 3); /* get 3 values from metamethod */ + lua_callk(L, 1, 3, 0, pairscont); /* get 3 values from metamethod */ } return 3; } @@ -280,7 +300,8 @@ static int luaB_pairs (lua_State *L) { ** Traversal function for 'ipairs' */ static int ipairsaux (lua_State *L) { - lua_Integer i = luaL_checkinteger(L, 2) + 1; + lua_Integer i = luaL_checkinteger(L, 2); + i = luaL_intop(+, i, 1); lua_pushinteger(L, i); return (lua_geti(L, 1, i) == LUA_TNIL) ? 1 : 2; } diff --git a/src/3rdparty/lua/lua-5.4.3/src/lcode.c b/src/3rdparty/lua/lua-5.4.4/src/lcode.c similarity index 97% rename from src/3rdparty/lua/lua-5.4.3/src/lcode.c rename to src/3rdparty/lua/lua-5.4.4/src/lcode.c index 80d975c..06425a1 100644 --- a/src/3rdparty/lua/lua-5.4.3/src/lcode.c +++ b/src/3rdparty/lua/lua-5.4.4/src/lcode.c @@ -10,6 +10,7 @@ #include "lprefix.h" +#include #include #include #include @@ -580,24 +581,41 @@ static int stringK (FuncState *fs, TString *s) { /* ** Add an integer to list of constants and return its index. -** Integers use userdata as keys to avoid collision with floats with -** same value; conversion to 'void*' is used only for hashing, so there -** are no "precision" problems. */ static int luaK_intK (FuncState *fs, lua_Integer n) { - TValue k, o; - setpvalue(&k, cast_voidp(cast_sizet(n))); + TValue o; setivalue(&o, n); - return addk(fs, &k, &o); + return addk(fs, &o, &o); /* use integer itself as key */ } /* -** Add a float to list of constants and return its index. +** Add a float to list of constants and return its index. Floats +** with integral values need a different key, to avoid collision +** with actual integers. To that, we add to the number its smaller +** power-of-two fraction that is still significant in its scale. +** For doubles, that would be 1/2^52. +** (This method is not bulletproof: there may be another float +** with that value, and for floats larger than 2^53 the result is +** still an integer. At worst, this only wastes an entry with +** a duplicate.) */ static int luaK_numberK (FuncState *fs, lua_Number r) { TValue o; + lua_Integer ik; setfltvalue(&o, r); - return addk(fs, &o, &o); /* use number itself as key */ + if (!luaV_flttointeger(r, &ik, F2Ieq)) /* not an integral value? */ + return addk(fs, &o, &o); /* use number itself as key */ + else { /* must build an alternative key */ + const int nbm = l_floatatt(MANT_DIG); + const lua_Number q = l_mathop(ldexp)(l_mathop(1.0), -nbm + 1); + const lua_Number k = (ik == 0) ? q : r + r*q; /* new key */ + TValue kv; + setfltvalue(&kv, k); + /* result is not an integral value, unless value is too large */ + lua_assert(!luaV_flttointeger(k, &ik, F2Ieq) || + l_mathop(fabs)(r) >= l_mathop(1e6)); + return addk(fs, &kv, &o); + } } diff --git a/src/3rdparty/lua/lua-5.4.3/src/lcode.h b/src/3rdparty/lua/lua-5.4.4/src/lcode.h similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/lcode.h rename to src/3rdparty/lua/lua-5.4.4/src/lcode.h diff --git a/src/3rdparty/lua/lua-5.4.3/src/lcorolib.c b/src/3rdparty/lua/lua-5.4.4/src/lcorolib.c similarity index 97% rename from src/3rdparty/lua/lua-5.4.3/src/lcorolib.c rename to src/3rdparty/lua/lua-5.4.4/src/lcorolib.c index fedbebe..785a1e8 100644 --- a/src/3rdparty/lua/lua-5.4.3/src/lcorolib.c +++ b/src/3rdparty/lua/lua-5.4.4/src/lcorolib.c @@ -78,7 +78,7 @@ static int luaB_auxwrap (lua_State *L) { if (stat != LUA_OK && stat != LUA_YIELD) { /* error in the coroutine? */ stat = lua_resetthread(co); /* close its tbc variables */ lua_assert(stat != LUA_OK); - lua_xmove(co, L, 1); /* copy error message */ + lua_xmove(co, L, 1); /* move error message to the caller */ } if (stat != LUA_ERRMEM && /* not a memory error and ... */ lua_type(L, -1) == LUA_TSTRING) { /* ... error object is a string? */ @@ -179,7 +179,7 @@ static int luaB_close (lua_State *L) { } else { lua_pushboolean(L, 0); - lua_xmove(co, L, 1); /* copy error message */ + lua_xmove(co, L, 1); /* move error message */ return 2; } } diff --git a/src/3rdparty/lua/lua-5.4.3/src/lctype.c b/src/3rdparty/lua/lua-5.4.4/src/lctype.c similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/lctype.c rename to src/3rdparty/lua/lua-5.4.4/src/lctype.c diff --git a/src/3rdparty/lua/lua-5.4.3/src/lctype.h b/src/3rdparty/lua/lua-5.4.4/src/lctype.h similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/lctype.h rename to src/3rdparty/lua/lua-5.4.4/src/lctype.h diff --git a/src/3rdparty/lua/lua-5.4.3/src/ldblib.c b/src/3rdparty/lua/lua-5.4.4/src/ldblib.c similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/ldblib.c rename to src/3rdparty/lua/lua-5.4.4/src/ldblib.c diff --git a/src/3rdparty/lua/lua-5.4.3/src/ldebug.c b/src/3rdparty/lua/lua-5.4.4/src/ldebug.c similarity index 91% rename from src/3rdparty/lua/lua-5.4.3/src/ldebug.c rename to src/3rdparty/lua/lua-5.4.4/src/ldebug.c index 1feaab2..a716d95 100644 --- a/src/3rdparty/lua/lua-5.4.3/src/ldebug.c +++ b/src/3rdparty/lua/lua-5.4.4/src/ldebug.c @@ -34,8 +34,8 @@ #define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_VCCL) -static const char *funcnamefromcode (lua_State *L, CallInfo *ci, - const char **name); +static const char *funcnamefromcall (lua_State *L, CallInfo *ci, + const char **name); static int currentpc (CallInfo *ci) { @@ -64,7 +64,7 @@ static int getbaseline (const Proto *f, int pc, int *basepc) { } else { int i = cast_uint(pc) / MAXIWTHABS - 1; /* get an estimate */ - /* estimate must be a lower bond of the correct base */ + /* estimate must be a lower bound of the correct base */ lua_assert(i < 0 || (i < f->sizeabslineinfo && f->abslineinfo[i].pc <= pc)); while (i + 1 < f->sizeabslineinfo && pc >= f->abslineinfo[i + 1].pc) @@ -301,7 +301,14 @@ static void collectvalidlines (lua_State *L, Closure *f) { sethvalue2s(L, L->top, t); /* push it on stack */ api_incr_top(L); setbtvalue(&v); /* boolean 'true' to be the value of all indices */ - for (i = 0; i < p->sizelineinfo; i++) { /* for all instructions */ + if (!p->is_vararg) /* regular function? */ + i = 0; /* consider all instructions */ + else { /* vararg function */ + lua_assert(GET_OPCODE(p->code[0]) == OP_VARARGPREP); + currentline = nextline(p, currentline, 0); + i = 1; /* skip first instruction (OP_VARARGPREP) */ + } + for (; i < p->sizelineinfo; i++) { /* for each instruction */ currentline = nextline(p, currentline, i); /* get its line */ luaH_setint(L, t, currentline, &v); /* table[line] = true */ } @@ -310,15 +317,9 @@ static void collectvalidlines (lua_State *L, Closure *f) { static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { - if (ci == NULL) /* no 'ci'? */ - return NULL; /* no info */ - else if (ci->callstatus & CIST_FIN) { /* is this a finalizer? */ - *name = "__gc"; - return "metamethod"; /* report it as such */ - } - /* calling function is a known Lua function? */ - else if (!(ci->callstatus & CIST_TAIL) && isLua(ci->previous)) - return funcnamefromcode(L, ci->previous, name); + /* calling function is a known function? */ + if (ci != NULL && !(ci->callstatus & CIST_TAIL)) + return funcnamefromcall(L, ci->previous, name); else return NULL; /* no way to find a name */ } @@ -590,16 +591,10 @@ static const char *getobjname (const Proto *p, int lastpc, int reg, ** Returns what the name is (e.g., "for iterator", "method", ** "metamethod") and sets '*name' to point to the name. */ -static const char *funcnamefromcode (lua_State *L, CallInfo *ci, - const char **name) { +static const char *funcnamefromcode (lua_State *L, const Proto *p, + int pc, const char **name) { TMS tm = (TMS)0; /* (initial value avoids warnings) */ - const Proto *p = ci_func(ci)->p; /* calling function */ - int pc = currentpc(ci); /* calling instruction index */ Instruction i = p->code[pc]; /* calling instruction */ - if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */ - *name = "?"; - return "hook"; - } switch (GET_OPCODE(i)) { case OP_CALL: case OP_TAILCALL: @@ -636,6 +631,26 @@ static const char *funcnamefromcode (lua_State *L, CallInfo *ci, return "metamethod"; } + +/* +** Try to find a name for a function based on how it was called. +*/ +static const char *funcnamefromcall (lua_State *L, CallInfo *ci, + const char **name) { + if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */ + *name = "?"; + return "hook"; + } + else if (ci->callstatus & CIST_FIN) { /* was it called as a finalizer? */ + *name = "__gc"; + return "metamethod"; /* report it as such */ + } + else if (isLua(ci)) + return funcnamefromcode(L, ci_func(ci)->p, currentpc(ci), name); + else + return NULL; +} + /* }====================================================== */ @@ -675,9 +690,21 @@ static const char *getupvalname (CallInfo *ci, const TValue *o, } +static const char *formatvarinfo (lua_State *L, const char *kind, + const char *name) { + if (kind == NULL) + return ""; /* no information */ + else + return luaO_pushfstring(L, " (%s '%s')", kind, name); +} + +/* +** Build a string with a "description" for the value 'o', such as +** "variable 'x'" or "upvalue 'y'". +*/ static const char *varinfo (lua_State *L, const TValue *o) { - const char *name = NULL; /* to avoid warnings */ CallInfo *ci = L->ci; + const char *name = NULL; /* to avoid warnings */ const char *kind = NULL; if (isLua(ci)) { kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */ @@ -685,26 +712,40 @@ static const char *varinfo (lua_State *L, const TValue *o) { kind = getobjname(ci_func(ci)->p, currentpc(ci), cast_int(cast(StkId, o) - (ci->func + 1)), &name); } - return (kind) ? luaO_pushfstring(L, " (%s '%s')", kind, name) : ""; + return formatvarinfo(L, kind, name); } -l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) { +/* +** Raise a type error +*/ +static l_noret typeerror (lua_State *L, const TValue *o, const char *op, + const char *extra) { const char *t = luaT_objtypename(L, o); - luaG_runerror(L, "attempt to %s a %s value%s", op, t, varinfo(L, o)); + luaG_runerror(L, "attempt to %s a %s value%s", op, t, extra); } +/* +** Raise a type error with "standard" information about the faulty +** object 'o' (using 'varinfo'). +*/ +l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) { + typeerror(L, o, op, varinfo(L, o)); +} + + +/* +** Raise an error for calling a non-callable object. Try to find a name +** for the object based on how it was called ('funcnamefromcall'); if it +** cannot get a name there, try 'varinfo'. +*/ l_noret luaG_callerror (lua_State *L, const TValue *o) { CallInfo *ci = L->ci; const char *name = NULL; /* to avoid warnings */ - const char *what = (isLua(ci)) ? funcnamefromcode(L, ci, &name) : NULL; - if (what != NULL) { - const char *t = luaT_objtypename(L, o); - luaG_runerror(L, "%s '%s' is not callable (a %s value)", what, name, t); - } - else - luaG_typeerror(L, o, "call"); + const char *kind = funcnamefromcall(L, ci, &name); + const char *extra = kind ? formatvarinfo(L, kind, name) : varinfo(L, o); + typeerror(L, o, "call", extra); } diff --git a/src/3rdparty/lua/lua-5.4.3/src/ldebug.h b/src/3rdparty/lua/lua-5.4.4/src/ldebug.h similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/ldebug.h rename to src/3rdparty/lua/lua-5.4.4/src/ldebug.h diff --git a/src/3rdparty/lua/lua-5.4.3/src/ldo.c b/src/3rdparty/lua/lua-5.4.4/src/ldo.c similarity index 90% rename from src/3rdparty/lua/lua-5.4.3/src/ldo.c rename to src/3rdparty/lua/lua-5.4.4/src/ldo.c index 7135079..a48e35f 100644 --- a/src/3rdparty/lua/lua-5.4.3/src/ldo.c +++ b/src/3rdparty/lua/lua-5.4.4/src/ldo.c @@ -387,15 +387,18 @@ static void rethook (lua_State *L, CallInfo *ci, int nres) { ** stack, below original 'func', so that 'luaD_precall' can call it. Raise ** an error if there is no '__call' metafield. */ -void luaD_tryfuncTM (lua_State *L, StkId func) { - const TValue *tm = luaT_gettmbyobj(L, s2v(func), TM_CALL); +StkId luaD_tryfuncTM (lua_State *L, StkId func) { + const TValue *tm; StkId p; + checkstackGCp(L, 1, func); /* space for metamethod */ + tm = luaT_gettmbyobj(L, s2v(func), TM_CALL); /* (after previous GC) */ if (l_unlikely(ttisnil(tm))) luaG_callerror(L, s2v(func)); /* nothing to call */ for (p = L->top; p > func; p--) /* open space for metamethod */ setobjs2s(L, p, p-1); L->top++; /* stack space pre-allocated by the caller */ setobj2s(L, func, tm); /* metamethod is the new function to be called */ + return func; } @@ -405,7 +408,7 @@ void luaD_tryfuncTM (lua_State *L, StkId func) { ** expressions, multiple results for tail calls/single parameters) ** separated. */ -static void moveresults (lua_State *L, StkId res, int nres, int wanted) { +l_sinline void moveresults (lua_State *L, StkId res, int nres, int wanted) { StkId firstresult; int i; switch (wanted) { /* handle typical cases separately */ @@ -473,27 +476,81 @@ void luaD_poscall (lua_State *L, CallInfo *ci, int nres) { #define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L)) +l_sinline CallInfo *prepCallInfo (lua_State *L, StkId func, int nret, + int mask, StkId top) { + CallInfo *ci = L->ci = next_ci(L); /* new frame */ + ci->func = func; + ci->nresults = nret; + ci->callstatus = mask; + ci->top = top; + return ci; +} + + +/* +** precall for C functions +*/ +l_sinline int precallC (lua_State *L, StkId func, int nresults, + lua_CFunction f) { + int n; /* number of returns */ + CallInfo *ci; + checkstackGCp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ + L->ci = ci = prepCallInfo(L, func, nresults, CIST_C, + L->top + LUA_MINSTACK); + lua_assert(ci->top <= L->stack_last); + if (l_unlikely(L->hookmask & LUA_MASKCALL)) { + int narg = cast_int(L->top - func) - 1; + luaD_hook(L, LUA_HOOKCALL, -1, 1, narg); + } + lua_unlock(L); + n = (*f)(L); /* do the actual call */ + lua_lock(L); + api_checknelems(L, n); + luaD_poscall(L, ci, n); + return n; +} + + /* ** Prepare a function for a tail call, building its call info on top ** of the current call info. 'narg1' is the number of arguments plus 1 -** (so that it includes the function itself). +** (so that it includes the function itself). Return the number of +** results, if it was a C function, or -1 for a Lua function. */ -void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int narg1) { - Proto *p = clLvalue(s2v(func))->p; - int fsize = p->maxstacksize; /* frame size */ - int nfixparams = p->numparams; - int i; - for (i = 0; i < narg1; i++) /* move down function and arguments */ - setobjs2s(L, ci->func + i, func + i); - checkstackGC(L, fsize); - func = ci->func; /* moved-down function */ - for (; narg1 <= nfixparams; narg1++) - setnilvalue(s2v(func + narg1)); /* complete missing arguments */ - ci->top = func + 1 + fsize; /* top for new function */ - lua_assert(ci->top <= L->stack_last); - ci->u.l.savedpc = p->code; /* starting point */ - ci->callstatus |= CIST_TAIL; - L->top = func + narg1; /* set top */ +int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, + int narg1, int delta) { + retry: + switch (ttypetag(s2v(func))) { + case LUA_VCCL: /* C closure */ + return precallC(L, func, LUA_MULTRET, clCvalue(s2v(func))->f); + case LUA_VLCF: /* light C function */ + return precallC(L, func, LUA_MULTRET, fvalue(s2v(func))); + case LUA_VLCL: { /* Lua function */ + Proto *p = clLvalue(s2v(func))->p; + int fsize = p->maxstacksize; /* frame size */ + int nfixparams = p->numparams; + int i; + checkstackGCp(L, fsize - delta, func); + ci->func -= delta; /* restore 'func' (if vararg) */ + for (i = 0; i < narg1; i++) /* move down function and arguments */ + setobjs2s(L, ci->func + i, func + i); + func = ci->func; /* moved-down function */ + for (; narg1 <= nfixparams; narg1++) + setnilvalue(s2v(func + narg1)); /* complete missing arguments */ + ci->top = func + 1 + fsize; /* top for new function */ + lua_assert(ci->top <= L->stack_last); + ci->u.l.savedpc = p->code; /* starting point */ + ci->callstatus |= CIST_TAIL; + L->top = func + narg1; /* set top */ + return -1; + } + default: { /* not a function */ + func = luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */ + /* return luaD_pretailcall(L, ci, func, narg1 + 1, delta); */ + narg1++; + goto retry; /* try again */ + } + } } @@ -506,35 +563,14 @@ void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int narg1) { ** original function position. */ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) { - lua_CFunction f; retry: switch (ttypetag(s2v(func))) { case LUA_VCCL: /* C closure */ - f = clCvalue(s2v(func))->f; - goto Cfunc; + precallC(L, func, nresults, clCvalue(s2v(func))->f); + return NULL; case LUA_VLCF: /* light C function */ - f = fvalue(s2v(func)); - Cfunc: { - int n; /* number of returns */ - CallInfo *ci; - checkstackGCp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ - L->ci = ci = next_ci(L); - ci->nresults = nresults; - ci->callstatus = CIST_C; - ci->top = L->top + LUA_MINSTACK; - ci->func = func; - lua_assert(ci->top <= L->stack_last); - if (l_unlikely(L->hookmask & LUA_MASKCALL)) { - int narg = cast_int(L->top - func) - 1; - luaD_hook(L, LUA_HOOKCALL, -1, 1, narg); - } - lua_unlock(L); - n = (*f)(L); /* do the actual call */ - lua_lock(L); - api_checknelems(L, n); - luaD_poscall(L, ci, n); + precallC(L, func, nresults, fvalue(s2v(func))); return NULL; - } case LUA_VLCL: { /* Lua function */ CallInfo *ci; Proto *p = clLvalue(s2v(func))->p; @@ -542,20 +578,16 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) { int nfixparams = p->numparams; int fsize = p->maxstacksize; /* frame size */ checkstackGCp(L, fsize, func); - L->ci = ci = next_ci(L); - ci->nresults = nresults; + L->ci = ci = prepCallInfo(L, func, nresults, 0, func + 1 + fsize); ci->u.l.savedpc = p->code; /* starting point */ - ci->top = func + 1 + fsize; - ci->func = func; - L->ci = ci; for (; narg < nfixparams; narg++) setnilvalue(s2v(L->top++)); /* complete missing arguments */ lua_assert(ci->top <= L->stack_last); return ci; } default: { /* not a function */ - checkstackGCp(L, 1, func); /* space for metamethod */ - luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */ + func = luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */ + /* return luaD_precall(L, func, nresults); */ goto retry; /* try again with metamethod */ } } @@ -567,7 +599,7 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) { ** number of recursive invocations in the C stack) or nyci (the same ** plus increment number of non-yieldable calls). */ -static void ccall (lua_State *L, StkId func, int nResults, int inc) { +l_sinline void ccall (lua_State *L, StkId func, int nResults, int inc) { CallInfo *ci; L->nCcalls += inc; if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) @@ -728,11 +760,10 @@ static void resume (lua_State *L, void *ud) { StkId firstArg = L->top - n; /* first argument */ CallInfo *ci = L->ci; if (L->status == LUA_OK) /* starting a coroutine? */ - ccall(L, firstArg - 1, LUA_MULTRET, 1); /* just call its body */ + ccall(L, firstArg - 1, LUA_MULTRET, 0); /* just call its body */ else { /* resuming from previous yield */ lua_assert(L->status == LUA_YIELD); L->status = LUA_OK; /* mark that it is running (again) */ - luaE_incCstack(L); /* control the C stack */ if (isLua(ci)) { /* yielded inside a hook? */ L->top = firstArg; /* discard arguments */ luaV_execute(L, ci); /* just continue running Lua code */ @@ -783,6 +814,9 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs, else if (L->status != LUA_YIELD) /* ended with errors? */ return resume_error(L, "cannot resume dead coroutine", nargs); L->nCcalls = (from) ? getCcalls(from) : 0; + if (getCcalls(L) >= LUAI_MAXCCALLS) + return resume_error(L, "C stack overflow", nargs); + L->nCcalls++; luai_userstateresume(L, nargs); api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); status = luaD_rawrunprotected(L, resume, &nargs); diff --git a/src/3rdparty/lua/lua-5.4.3/src/ldo.h b/src/3rdparty/lua/lua-5.4.4/src/ldo.h similarity index 93% rename from src/3rdparty/lua/lua-5.4.3/src/ldo.h rename to src/3rdparty/lua/lua-5.4.4/src/ldo.h index 6bf0ed8..911e67f 100644 --- a/src/3rdparty/lua/lua-5.4.3/src/ldo.h +++ b/src/3rdparty/lua/lua-5.4.4/src/ldo.h @@ -58,11 +58,11 @@ LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, LUAI_FUNC void luaD_hook (lua_State *L, int event, int line, int fTransfer, int nTransfer); LUAI_FUNC void luaD_hookcall (lua_State *L, CallInfo *ci); -LUAI_FUNC void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int n); +LUAI_FUNC int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int narg1, int delta); LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nResults); LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); -LUAI_FUNC void luaD_tryfuncTM (lua_State *L, StkId func); +LUAI_FUNC StkId luaD_tryfuncTM (lua_State *L, StkId func); LUAI_FUNC int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status); LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, ptrdiff_t oldtop, ptrdiff_t ef); diff --git a/src/3rdparty/lua/lua-5.4.3/src/ldump.c b/src/3rdparty/lua/lua-5.4.4/src/ldump.c similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/ldump.c rename to src/3rdparty/lua/lua-5.4.4/src/ldump.c diff --git a/src/3rdparty/lua/lua-5.4.3/src/lfunc.c b/src/3rdparty/lua/lua-5.4.4/src/lfunc.c similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/lfunc.c rename to src/3rdparty/lua/lua-5.4.4/src/lfunc.c diff --git a/src/3rdparty/lua/lua-5.4.3/src/lfunc.h b/src/3rdparty/lua/lua-5.4.4/src/lfunc.h similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/lfunc.h rename to src/3rdparty/lua/lua-5.4.4/src/lfunc.h diff --git a/src/3rdparty/lua/lua-5.4.3/src/lgc.c b/src/3rdparty/lua/lua-5.4.4/src/lgc.c similarity index 99% rename from src/3rdparty/lua/lua-5.4.3/src/lgc.c rename to src/3rdparty/lua/lua-5.4.4/src/lgc.c index b360eed..42a73d8 100644 --- a/src/3rdparty/lua/lua-5.4.3/src/lgc.c +++ b/src/3rdparty/lua/lua-5.4.4/src/lgc.c @@ -906,18 +906,18 @@ static void GCTM (lua_State *L) { if (!notm(tm)) { /* is there a finalizer? */ int status; lu_byte oldah = L->allowhook; - int running = g->gcrunning; + int oldgcstp = g->gcstp; + g->gcstp |= GCSTPGC; /* avoid GC steps */ L->allowhook = 0; /* stop debug hooks during GC metamethod */ - g->gcrunning = 0; /* avoid GC steps */ setobj2s(L, L->top++, tm); /* push finalizer... */ setobj2s(L, L->top++, &v); /* ... and its argument */ L->ci->callstatus |= CIST_FIN; /* will run a finalizer */ status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0); L->ci->callstatus &= ~CIST_FIN; /* not running a finalizer anymore */ L->allowhook = oldah; /* restore hooks */ - g->gcrunning = running; /* restore state */ + g->gcstp = oldgcstp; /* restore state */ if (l_unlikely(status != LUA_OK)) { /* error while running __gc? */ - luaE_warnerror(L, "__gc metamethod"); + luaE_warnerror(L, "__gc"); L->top--; /* pops error object */ } } @@ -1011,7 +1011,8 @@ static void correctpointers (global_State *g, GCObject *o) { void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { global_State *g = G(L); if (tofinalize(o) || /* obj. is already marked... */ - gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */ + gfasttm(g, mt, TM_GC) == NULL || /* or has no finalizer... */ + (g->gcstp & GCSTPCLS)) /* or closing state? */ return; /* nothing to be done */ else { /* move 'o' to 'finobj' list */ GCObject **p; @@ -1502,12 +1503,13 @@ static void deletelist (lua_State *L, GCObject *p, GCObject *limit) { */ void luaC_freeallobjects (lua_State *L) { global_State *g = G(L); + g->gcstp = GCSTPCLS; /* no extra finalizers after here */ luaC_changemode(L, KGC_INC); separatetobefnz(g, 1); /* separate all objects with finalizers */ lua_assert(g->finobj == NULL); callallpendingfinalizers(L); deletelist(L, g->allgc, obj2gco(g->mainthread)); - deletelist(L, g->finobj, NULL); + lua_assert(g->finobj == NULL); /* no new finalizers */ deletelist(L, g->fixedgc, NULL); /* collect fixed objects */ lua_assert(g->strt.nuse == 0); } @@ -1647,6 +1649,7 @@ void luaC_runtilstate (lua_State *L, int statesmask) { } + /* ** Performs a basic incremental step. The debt and step size are ** converted from bytes to "units of work"; then the function loops @@ -1678,7 +1681,7 @@ static void incstep (lua_State *L, global_State *g) { void luaC_step (lua_State *L) { global_State *g = G(L); lua_assert(!g->gcemergency); - if (g->gcrunning) { /* running? */ + if (gcrunning(g)) { /* running? */ if(isdecGCmodegen(g)) genstep(L, g); else diff --git a/src/3rdparty/lua/lua-5.4.3/src/lgc.h b/src/3rdparty/lua/lua-5.4.4/src/lgc.h similarity index 95% rename from src/3rdparty/lua/lua-5.4.3/src/lgc.h rename to src/3rdparty/lua/lua-5.4.4/src/lgc.h index 073e2a4..4a12563 100644 --- a/src/3rdparty/lua/lua-5.4.3/src/lgc.h +++ b/src/3rdparty/lua/lua-5.4.4/src/lgc.h @@ -148,6 +148,16 @@ */ #define isdecGCmodegen(g) (g->gckind == KGC_GEN || g->lastatomic != 0) + +/* +** Control when GC is running: +*/ +#define GCSTPUSR 1 /* bit true when GC stopped by user */ +#define GCSTPGC 2 /* bit true when GC stopped by itself */ +#define GCSTPCLS 4 /* bit true when closing Lua state */ +#define gcrunning(g) ((g)->gcstp == 0) + + /* ** Does one step of collection when debt becomes positive. 'pre'/'pos' ** allows some adjustments to be done only when needed. macro diff --git a/src/3rdparty/lua/lua-5.4.3/src/linit.c b/src/3rdparty/lua/lua-5.4.4/src/linit.c similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/linit.c rename to src/3rdparty/lua/lua-5.4.4/src/linit.c diff --git a/src/3rdparty/lua/lua-5.4.3/src/liolib.c b/src/3rdparty/lua/lua-5.4.4/src/liolib.c similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/liolib.c rename to src/3rdparty/lua/lua-5.4.4/src/liolib.c diff --git a/src/3rdparty/lua/lua-5.4.3/src/ljumptab.h b/src/3rdparty/lua/lua-5.4.4/src/ljumptab.h similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/ljumptab.h rename to src/3rdparty/lua/lua-5.4.4/src/ljumptab.h diff --git a/src/3rdparty/lua/lua-5.4.3/src/llex.c b/src/3rdparty/lua/lua-5.4.4/src/llex.c similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/llex.c rename to src/3rdparty/lua/lua-5.4.4/src/llex.c diff --git a/src/3rdparty/lua/lua-5.4.3/src/llex.h b/src/3rdparty/lua/lua-5.4.4/src/llex.h similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/llex.h rename to src/3rdparty/lua/lua-5.4.4/src/llex.h diff --git a/src/3rdparty/lua/lua-5.4.3/src/llimits.h b/src/3rdparty/lua/lua-5.4.4/src/llimits.h similarity index 96% rename from src/3rdparty/lua/lua-5.4.3/src/llimits.h rename to src/3rdparty/lua/lua-5.4.4/src/llimits.h index 025f1c8..52a32f9 100644 --- a/src/3rdparty/lua/lua-5.4.3/src/llimits.h +++ b/src/3rdparty/lua/lua-5.4.4/src/llimits.h @@ -165,6 +165,20 @@ typedef LUAI_UACINT l_uacInt; #endif +/* +** Inline functions +*/ +#if !defined(LUA_USE_C89) +#define l_inline inline +#elif defined(__GNUC__) +#define l_inline __inline__ +#else +#define l_inline /* empty */ +#endif + +#define l_sinline static l_inline + + /* ** type for virtual-machine instructions; ** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) @@ -347,7 +361,7 @@ typedef l_uint32 Instruction; #define condchangemem(L,pre,pos) ((void)0) #else #define condchangemem(L,pre,pos) \ - { if (G(L)->gcrunning) { pre; luaC_fullgc(L, 0); pos; } } + { if (gcrunning(G(L))) { pre; luaC_fullgc(L, 0); pos; } } #endif #endif diff --git a/src/3rdparty/lua/lua-5.4.3/src/lmathlib.c b/src/3rdparty/lua/lua-5.4.4/src/lmathlib.c similarity index 99% rename from src/3rdparty/lua/lua-5.4.3/src/lmathlib.c rename to src/3rdparty/lua/lua-5.4.4/src/lmathlib.c index 5f5983a..e0c61a1 100644 --- a/src/3rdparty/lua/lua-5.4.3/src/lmathlib.c +++ b/src/3rdparty/lua/lua-5.4.4/src/lmathlib.c @@ -475,7 +475,7 @@ static lua_Number I2d (Rand64 x) { /* 2^(-FIGS) = 1.0 / 2^30 / 2^3 / 2^(FIGS-33) */ #define scaleFIG \ - ((lua_Number)1.0 / (UONE << 30) / 8.0 / (UONE << (FIGS - 33))) + (l_mathop(1.0) / (UONE << 30) / l_mathop(8.0) / (UONE << (FIGS - 33))) /* ** use FIGS - 32 bits from lower half, throwing out the other @@ -486,7 +486,7 @@ static lua_Number I2d (Rand64 x) { /* ** higher 32 bits go after those (FIGS - 32) bits: shiftHI = 2^(FIGS - 32) */ -#define shiftHI ((lua_Number)(UONE << (FIGS - 33)) * 2.0) +#define shiftHI ((lua_Number)(UONE << (FIGS - 33)) * l_mathop(2.0)) static lua_Number I2d (Rand64 x) { diff --git a/src/3rdparty/lua/lua-5.4.3/src/lmem.c b/src/3rdparty/lua/lua-5.4.4/src/lmem.c similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/lmem.c rename to src/3rdparty/lua/lua-5.4.4/src/lmem.c diff --git a/src/3rdparty/lua/lua-5.4.3/src/lmem.h b/src/3rdparty/lua/lua-5.4.4/src/lmem.h similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/lmem.h rename to src/3rdparty/lua/lua-5.4.4/src/lmem.h diff --git a/src/3rdparty/lua/lua-5.4.3/src/loadlib.c b/src/3rdparty/lua/lua-5.4.4/src/loadlib.c similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/loadlib.c rename to src/3rdparty/lua/lua-5.4.4/src/loadlib.c diff --git a/src/3rdparty/lua/lua-5.4.3/src/lobject.c b/src/3rdparty/lua/lua-5.4.4/src/lobject.c similarity index 98% rename from src/3rdparty/lua/lua-5.4.3/src/lobject.c rename to src/3rdparty/lua/lua-5.4.4/src/lobject.c index 0e504be..301aa90 100644 --- a/src/3rdparty/lua/lua-5.4.3/src/lobject.c +++ b/src/3rdparty/lua/lua-5.4.4/src/lobject.c @@ -164,7 +164,7 @@ static int isneg (const char **s) { */ static lua_Number lua_strx2number (const char *s, char **endptr) { int dot = lua_getlocaledecpoint(); - lua_Number r = 0.0; /* result (accumulator) */ + lua_Number r = l_mathop(0.0); /* result (accumulator) */ int sigdig = 0; /* number of significant digits */ int nosigdig = 0; /* number of non-significant digits */ int e = 0; /* exponent correction */ @@ -174,7 +174,7 @@ static lua_Number lua_strx2number (const char *s, char **endptr) { while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */ neg = isneg(&s); /* check sign */ if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */ - return 0.0; /* invalid format (no '0x') */ + return l_mathop(0.0); /* invalid format (no '0x') */ for (s += 2; ; s++) { /* skip '0x' and read numeral */ if (*s == dot) { if (hasdot) break; /* second dot? stop loop */ @@ -184,14 +184,14 @@ static lua_Number lua_strx2number (const char *s, char **endptr) { if (sigdig == 0 && *s == '0') /* non-significant digit (zero)? */ nosigdig++; else if (++sigdig <= MAXSIGDIG) /* can read it without overflow? */ - r = (r * cast_num(16.0)) + luaO_hexavalue(*s); + r = (r * l_mathop(16.0)) + luaO_hexavalue(*s); else e++; /* too many digits; ignore, but still count for exponent */ if (hasdot) e--; /* decimal digit? correct exponent */ } else break; /* neither a dot nor a digit */ } if (nosigdig + sigdig == 0) /* no digits? */ - return 0.0; /* invalid format */ + return l_mathop(0.0); /* invalid format */ *endptr = cast_charp(s); /* valid up to here */ e *= 4; /* each digit multiplies/divides value by 2^4 */ if (*s == 'p' || *s == 'P') { /* exponent part? */ @@ -200,7 +200,7 @@ static lua_Number lua_strx2number (const char *s, char **endptr) { s++; /* skip 'p' */ neg1 = isneg(&s); /* sign */ if (!lisdigit(cast_uchar(*s))) - return 0.0; /* invalid; must have at least one digit */ + return l_mathop(0.0); /* invalid; must have at least one digit */ while (lisdigit(cast_uchar(*s))) /* read exponent */ exp1 = exp1 * 10 + *(s++) - '0'; if (neg1) exp1 = -exp1; diff --git a/src/3rdparty/lua/lua-5.4.3/src/lobject.h b/src/3rdparty/lua/lua-5.4.4/src/lobject.h similarity index 99% rename from src/3rdparty/lua/lua-5.4.3/src/lobject.h rename to src/3rdparty/lua/lua-5.4.4/src/lobject.h index 950bebb..0e05b3e 100644 --- a/src/3rdparty/lua/lua-5.4.3/src/lobject.h +++ b/src/3rdparty/lua/lua-5.4.4/src/lobject.h @@ -68,7 +68,7 @@ typedef struct TValue { #define val_(o) ((o)->value_) -#define valraw(o) (&val_(o)) +#define valraw(o) (val_(o)) /* raw type tag of a TValue */ @@ -112,7 +112,7 @@ typedef struct TValue { #define settt_(o,t) ((o)->tt_=(t)) -/* main macro to copy values (from 'obj1' to 'obj2') */ +/* main macro to copy values (from 'obj2' to 'obj1') */ #define setobj(L,obj1,obj2) \ { TValue *io1=(obj1); const TValue *io2=(obj2); \ io1->value_ = io2->value_; settt_(io1, io2->tt_); \ diff --git a/src/3rdparty/lua/lua-5.4.3/src/lopcodes.c b/src/3rdparty/lua/lua-5.4.4/src/lopcodes.c similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/lopcodes.c rename to src/3rdparty/lua/lua-5.4.4/src/lopcodes.c diff --git a/src/3rdparty/lua/lua-5.4.3/src/lopcodes.h b/src/3rdparty/lua/lua-5.4.4/src/lopcodes.h similarity index 94% rename from src/3rdparty/lua/lua-5.4.3/src/lopcodes.h rename to src/3rdparty/lua/lua-5.4.4/src/lopcodes.h index d6a47e5..7c27451 100644 --- a/src/3rdparty/lua/lua-5.4.3/src/lopcodes.h +++ b/src/3rdparty/lua/lua-5.4.4/src/lopcodes.h @@ -190,7 +190,8 @@ enum OpMode {iABC, iABx, iAsBx, iAx, isJ}; /* basic instruction formats */ /* -** grep "ORDER OP" if you change these enums +** Grep "ORDER OP" if you change these enums. Opcodes marked with a (*) +** has extra descriptions in the notes after the enumeration. */ typedef enum { @@ -203,7 +204,7 @@ OP_LOADF,/* A sBx R[A] := (lua_Number)sBx */ OP_LOADK,/* A Bx R[A] := K[Bx] */ OP_LOADKX,/* A R[A] := K[extra arg] */ OP_LOADFALSE,/* A R[A] := false */ -OP_LFALSESKIP,/*A R[A] := false; pc++ */ +OP_LFALSESKIP,/*A R[A] := false; pc++ (*) */ OP_LOADTRUE,/* A R[A] := true */ OP_LOADNIL,/* A B R[A], R[A+1], ..., R[A+B] := nil */ OP_GETUPVAL,/* A B R[A] := UpValue[B] */ @@ -254,7 +255,7 @@ OP_BXOR,/* A B C R[A] := R[B] ~ R[C] */ OP_SHL,/* A B C R[A] := R[B] << R[C] */ OP_SHR,/* A B C R[A] := R[B] >> R[C] */ -OP_MMBIN,/* A B C call C metamethod over R[A] and R[B] */ +OP_MMBIN,/* A B C call C metamethod over R[A] and R[B] (*) */ OP_MMBINI,/* A sB C k call C metamethod over R[A] and sB */ OP_MMBINK,/* A B C k call C metamethod over R[A] and K[B] */ @@ -280,7 +281,7 @@ OP_GTI,/* A sB k if ((R[A] > sB) ~= k) then pc++ */ OP_GEI,/* A sB k if ((R[A] >= sB) ~= k) then pc++ */ OP_TEST,/* A k if (not R[A] == k) then pc++ */ -OP_TESTSET,/* A B k if (not R[B] == k) then pc++ else R[A] := R[B] */ +OP_TESTSET,/* A B k if (not R[B] == k) then pc++ else R[A] := R[B] (*) */ OP_CALL,/* A B C R[A], ... ,R[A+C-2] := R[A](R[A+1], ... ,R[A+B-1]) */ OP_TAILCALL,/* A B C k return R[A](R[A+1], ... ,R[A+B-1]) */ @@ -315,6 +316,18 @@ OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */ /*=========================================================================== Notes: + + (*) Opcode OP_LFALSESKIP is used to convert a condition to a boolean + value, in a code equivalent to (not cond ? false : true). (It + produces false and skips the next instruction producing true.) + + (*) Opcodes OP_MMBIN and variants follow each arithmetic and + bitwise opcode. If the operation succeeds, it skips this next + opcode. Otherwise, this opcode calls the corresponding metamethod. + + (*) Opcode OP_TESTSET is used in short-circuit expressions that need + both to jump and to produce a value, such as (a = b or c). + (*) In OP_CALL, if (B == 0) then B = top - A. If (C == 0), then 'top' is set to last_result+1, so next open instruction (OP_CALL, OP_RETURN*, OP_SETLIST) may use 'top'. diff --git a/src/3rdparty/lua/lua-5.4.3/src/lopnames.h b/src/3rdparty/lua/lua-5.4.4/src/lopnames.h similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/lopnames.h rename to src/3rdparty/lua/lua-5.4.4/src/lopnames.h diff --git a/src/3rdparty/lua/lua-5.4.3/src/loslib.c b/src/3rdparty/lua/lua-5.4.4/src/loslib.c similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/loslib.c rename to src/3rdparty/lua/lua-5.4.4/src/loslib.c diff --git a/src/3rdparty/lua/lua-5.4.3/src/lparser.c b/src/3rdparty/lua/lua-5.4.4/src/lparser.c similarity index 99% rename from src/3rdparty/lua/lua-5.4.3/src/lparser.c rename to src/3rdparty/lua/lua-5.4.4/src/lparser.c index 284ef1f..3abe3d7 100644 --- a/src/3rdparty/lua/lua-5.4.3/src/lparser.c +++ b/src/3rdparty/lua/lua-5.4.4/src/lparser.c @@ -416,6 +416,17 @@ static void markupval (FuncState *fs, int level) { } +/* +** Mark that current block has a to-be-closed variable. +*/ +static void marktobeclosed (FuncState *fs) { + BlockCnt *bl = fs->bl; + bl->upval = 1; + bl->insidetbc = 1; + fs->needclose = 1; +} + + /* ** Find a variable with the given name 'n'. If it is an upvalue, add ** this upvalue into all intermediate functions. If it is a global, set @@ -1599,7 +1610,7 @@ static void forlist (LexState *ls, TString *indexname) { line = ls->linenumber; adjust_assign(ls, 4, explist(ls, &e), &e); adjustlocalvars(ls, 4); /* control variables */ - markupval(fs, fs->nactvar); /* last control var. must be closed */ + marktobeclosed(fs); /* last control var. must be closed */ luaK_checkstack(fs, 3); /* extra space to call generator */ forbody(ls, base, line, nvars - 4, 1); } @@ -1703,11 +1714,9 @@ static int getlocalattribute (LexState *ls) { } -static void checktoclose (LexState *ls, int level) { +static void checktoclose (FuncState *fs, int level) { if (level != -1) { /* is there a to-be-closed variable? */ - FuncState *fs = ls->fs; - markupval(fs, level + 1); - fs->bl->insidetbc = 1; /* in the scope of a to-be-closed variable */ + marktobeclosed(fs); luaK_codeABC(fs, OP_TBC, reglevel(fs, level), 0, 0); } } @@ -1751,7 +1760,7 @@ static void localstat (LexState *ls) { adjust_assign(ls, nvars, nexps, &e); adjustlocalvars(ls, nvars); } - checktoclose(ls, toclose); + checktoclose(fs, toclose); } @@ -1776,6 +1785,7 @@ static void funcstat (LexState *ls, int line) { luaX_next(ls); /* skip FUNCTION */ ismethod = funcname(ls, &v); body(ls, &b, ismethod, line); + check_readonly(ls, &v); luaK_storevar(ls->fs, &v, &b); luaK_fixline(ls->fs, line); /* definition "happens" in the first line */ } diff --git a/src/3rdparty/lua/lua-5.4.3/src/lparser.h b/src/3rdparty/lua/lua-5.4.4/src/lparser.h similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/lparser.h rename to src/3rdparty/lua/lua-5.4.4/src/lparser.h diff --git a/src/3rdparty/lua/lua-5.4.3/src/lprefix.h b/src/3rdparty/lua/lua-5.4.4/src/lprefix.h similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/lprefix.h rename to src/3rdparty/lua/lua-5.4.4/src/lprefix.h diff --git a/src/3rdparty/lua/lua-5.4.3/src/lstate.c b/src/3rdparty/lua/lua-5.4.4/src/lstate.c similarity index 97% rename from src/3rdparty/lua/lua-5.4.3/src/lstate.c rename to src/3rdparty/lua/lua-5.4.4/src/lstate.c index c5e3b43..1ffe1a0 100644 --- a/src/3rdparty/lua/lua-5.4.3/src/lstate.c +++ b/src/3rdparty/lua/lua-5.4.4/src/lstate.c @@ -166,7 +166,7 @@ void luaE_checkcstack (lua_State *L) { if (getCcalls(L) == LUAI_MAXCCALLS) luaG_runerror(L, "C stack overflow"); else if (getCcalls(L) >= (LUAI_MAXCCALLS / 10 * 11)) - luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ + luaD_throw(L, LUA_ERRERR); /* error while handling stack error */ } @@ -236,7 +236,7 @@ static void f_luaopen (lua_State *L, void *ud) { luaS_init(L); luaT_init(L); luaX_init(L); - g->gcrunning = 1; /* allow gc */ + g->gcstp = 0; /* allow gc */ setnilvalue(&g->nilvalue); /* now state is complete */ luai_userstateopen(L); } @@ -269,8 +269,9 @@ static void preinit_thread (lua_State *L, global_State *g) { static void close_state (lua_State *L) { global_State *g = G(L); if (!completestate(g)) /* closing a partially built state? */ - luaC_freeallobjects(L); /* jucst collect its objects */ + luaC_freeallobjects(L); /* just collect its objects */ else { /* closing a fully built state */ + L->ci = &L->base_ci; /* unwind CallInfo list */ luaD_closeprotected(L, 1, LUA_OK); /* close all upvalues */ luaC_freeallobjects(L); /* collect all objects */ luai_userstateclose(L); @@ -330,13 +331,13 @@ int luaE_resetthread (lua_State *L, int status) { ci->callstatus = CIST_C; if (status == LUA_YIELD) status = LUA_OK; + L->status = LUA_OK; /* so it can run __close metamethods */ status = luaD_closeprotected(L, 1, status); if (status != LUA_OK) /* errors? */ luaD_seterrorobj(L, status, L->stack + 1); else L->top = L->stack + 1; ci->top = L->top + LUA_MINSTACK; - L->status = cast_byte(status); luaD_reallocstack(L, cast_int(ci->top - L->stack), 0); return status; } @@ -372,7 +373,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { g->ud_warn = NULL; g->mainthread = L; g->seed = luai_makeseed(L); - g->gcrunning = 0; /* no GC while building state */ + g->gcstp = GCSTPGC; /* no GC while building state */ g->strt.size = g->strt.nuse = 0; g->strt.hash = NULL; setnilvalue(&g->l_registry); diff --git a/src/3rdparty/lua/lua-5.4.3/src/lstate.h b/src/3rdparty/lua/lua-5.4.4/src/lstate.h similarity index 99% rename from src/3rdparty/lua/lua-5.4.3/src/lstate.h rename to src/3rdparty/lua/lua-5.4.4/src/lstate.h index c1283bb..61e82cd 100644 --- a/src/3rdparty/lua/lua-5.4.3/src/lstate.h +++ b/src/3rdparty/lua/lua-5.4.4/src/lstate.h @@ -165,7 +165,7 @@ typedef struct stringtable { ** - field 'nyield' is used only while a function is "doing" an ** yield (from the yield until the next resume); ** - field 'nres' is used only while closing tbc variables when -** returning from a C function; +** returning from a function; ** - field 'transferinfo' is used only during call/returnhooks, ** before the function starts or after it ends. */ @@ -209,7 +209,7 @@ typedef struct CallInfo { #define CIST_YPCALL (1<<4) /* doing a yieldable protected call */ #define CIST_TAIL (1<<5) /* call was tail called */ #define CIST_HOOKYIELD (1<<6) /* last hook called yielded */ -#define CIST_FIN (1<<7) /* call is running a finalizer */ +#define CIST_FIN (1<<7) /* function "called" a finalizer */ #define CIST_TRAN (1<<8) /* 'ci' has transfer information */ #define CIST_CLSRET (1<<9) /* function is closing tbc variables */ /* Bits 10-12 are used for CIST_RECST (see below) */ @@ -263,7 +263,7 @@ typedef struct global_State { lu_byte gcstopem; /* stops emergency collections */ lu_byte genminormul; /* control for minor generational collections */ lu_byte genmajormul; /* control for major generational collections */ - lu_byte gcrunning; /* true if GC is running */ + lu_byte gcstp; /* control whether GC is running */ lu_byte gcemergency; /* true if this is an emergency collection */ lu_byte gcpause; /* size of pause between successive GCs */ lu_byte gcstepmul; /* GC "speed" */ diff --git a/src/3rdparty/lua/lua-5.4.3/src/lstring.c b/src/3rdparty/lua/lua-5.4.4/src/lstring.c similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/lstring.c rename to src/3rdparty/lua/lua-5.4.4/src/lstring.c diff --git a/src/3rdparty/lua/lua-5.4.3/src/lstring.h b/src/3rdparty/lua/lua-5.4.4/src/lstring.h similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/lstring.h rename to src/3rdparty/lua/lua-5.4.4/src/lstring.h diff --git a/src/3rdparty/lua/lua-5.4.3/src/lstrlib.c b/src/3rdparty/lua/lua-5.4.4/src/lstrlib.c similarity index 94% rename from src/3rdparty/lua/lua-5.4.3/src/lstrlib.c rename to src/3rdparty/lua/lua-5.4.4/src/lstrlib.c index 47e5b27..0b4fdbb 100644 --- a/src/3rdparty/lua/lua-5.4.3/src/lstrlib.c +++ b/src/3rdparty/lua/lua-5.4.4/src/lstrlib.c @@ -1090,13 +1090,31 @@ static int lua_number2strx (lua_State *L, char *buff, int sz, /* valid flags in a format specification */ -#if !defined(L_FMTFLAGS) -#define L_FMTFLAGS "-+ #0" +#if !defined(L_FMTFLAGSF) + +/* valid flags for a, A, e, E, f, F, g, and G conversions */ +#define L_FMTFLAGSF "-+#0 " + +/* valid flags for o, x, and X conversions */ +#define L_FMTFLAGSX "-#0" + +/* valid flags for d and i conversions */ +#define L_FMTFLAGSI "-+0 " + +/* valid flags for u conversions */ +#define L_FMTFLAGSU "-0" + +/* valid flags for c, p, and s conversions */ +#define L_FMTFLAGSC "-" + #endif /* -** maximum size of each format specification (such as "%-099.99d") +** Maximum size of each format specification (such as "%-099.99d"): +** Initial '%', flags (up to 5), width (2), period, precision (2), +** length modifier (8), conversion specifier, and final '\0', plus some +** extra. */ #define MAX_FORMAT 32 @@ -1189,25 +1207,53 @@ static void addliteral (lua_State *L, luaL_Buffer *b, int arg) { } -static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { - const char *p = strfrmt; - while (*p != '\0' && strchr(L_FMTFLAGS, *p) != NULL) p++; /* skip flags */ - if ((size_t)(p - strfrmt) >= sizeof(L_FMTFLAGS)/sizeof(char)) - luaL_error(L, "invalid format (repeated flags)"); - if (isdigit(uchar(*p))) p++; /* skip width */ - if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ - if (*p == '.') { - p++; - if (isdigit(uchar(*p))) p++; /* skip precision */ - if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ +static const char *get2digits (const char *s) { + if (isdigit(uchar(*s))) { + s++; + if (isdigit(uchar(*s))) s++; /* (2 digits at most) */ + } + return s; +} + + +/* +** Check whether a conversion specification is valid. When called, +** first character in 'form' must be '%' and last character must +** be a valid conversion specifier. 'flags' are the accepted flags; +** 'precision' signals whether to accept a precision. +*/ +static void checkformat (lua_State *L, const char *form, const char *flags, + int precision) { + const char *spec = form + 1; /* skip '%' */ + spec += strspn(spec, flags); /* skip flags */ + if (*spec != '0') { /* a width cannot start with '0' */ + spec = get2digits(spec); /* skip width */ + if (*spec == '.' && precision) { + spec++; + spec = get2digits(spec); /* skip precision */ + } } - if (isdigit(uchar(*p))) - luaL_error(L, "invalid format (width or precision too long)"); + if (!isalpha(uchar(*spec))) /* did not go to the end? */ + luaL_error(L, "invalid conversion specification: '%s'", form); +} + + +/* +** Get a conversion specification and copy it to 'form'. +** Return the address of its last character. +*/ +static const char *getformat (lua_State *L, const char *strfrmt, + char *form) { + /* spans flags, width, and precision ('0' is included as a flag) */ + size_t len = strspn(strfrmt, L_FMTFLAGSF "123456789."); + len++; /* adds following character (should be the specifier) */ + /* still needs space for '%', '\0', plus a length modifier */ + if (len >= MAX_FORMAT - 10) + luaL_error(L, "invalid format (too long)"); *(form++) = '%'; - memcpy(form, strfrmt, ((p - strfrmt) + 1) * sizeof(char)); - form += (p - strfrmt) + 1; - *form = '\0'; - return p; + memcpy(form, strfrmt, len * sizeof(char)); + *(form + len) = '\0'; + return strfrmt + len - 1; } @@ -1230,6 +1276,7 @@ static int str_format (lua_State *L) { size_t sfl; const char *strfrmt = luaL_checklstring(L, arg, &sfl); const char *strfrmt_end = strfrmt+sfl; + const char *flags; luaL_Buffer b; luaL_buffinit(L, &b); while (strfrmt < strfrmt_end) { @@ -1239,25 +1286,35 @@ static int str_format (lua_State *L) { luaL_addchar(&b, *strfrmt++); /* %% */ else { /* format item */ char form[MAX_FORMAT]; /* to store the format ('%...') */ - int maxitem = MAX_ITEM; - char *buff = luaL_prepbuffsize(&b, maxitem); /* to put formatted item */ - int nb = 0; /* number of bytes in added item */ + int maxitem = MAX_ITEM; /* maximum length for the result */ + char *buff = luaL_prepbuffsize(&b, maxitem); /* to put result */ + int nb = 0; /* number of bytes in result */ if (++arg > top) return luaL_argerror(L, arg, "no value"); - strfrmt = scanformat(L, strfrmt, form); + strfrmt = getformat(L, strfrmt, form); switch (*strfrmt++) { case 'c': { + checkformat(L, form, L_FMTFLAGSC, 0); nb = l_sprintf(buff, maxitem, form, (int)luaL_checkinteger(L, arg)); break; } case 'd': case 'i': - case 'o': case 'u': case 'x': case 'X': { + flags = L_FMTFLAGSI; + goto intcase; + case 'u': + flags = L_FMTFLAGSU; + goto intcase; + case 'o': case 'x': case 'X': + flags = L_FMTFLAGSX; + intcase: { lua_Integer n = luaL_checkinteger(L, arg); + checkformat(L, form, flags, 1); addlenmod(form, LUA_INTEGER_FRMLEN); nb = l_sprintf(buff, maxitem, form, (LUAI_UACINT)n); break; } case 'a': case 'A': + checkformat(L, form, L_FMTFLAGSF, 1); addlenmod(form, LUA_NUMBER_FRMLEN); nb = lua_number2strx(L, buff, maxitem, form, luaL_checknumber(L, arg)); @@ -1268,12 +1325,14 @@ static int str_format (lua_State *L) { /* FALLTHROUGH */ case 'e': case 'E': case 'g': case 'G': { lua_Number n = luaL_checknumber(L, arg); + checkformat(L, form, L_FMTFLAGSF, 1); addlenmod(form, LUA_NUMBER_FRMLEN); nb = l_sprintf(buff, maxitem, form, (LUAI_UACNUMBER)n); break; } case 'p': { const void *p = lua_topointer(L, arg); + checkformat(L, form, L_FMTFLAGSC, 0); if (p == NULL) { /* avoid calling 'printf' with argument NULL */ p = "(null)"; /* result */ form[strlen(form) - 1] = 's'; /* format it as a string */ @@ -1294,7 +1353,8 @@ static int str_format (lua_State *L) { luaL_addvalue(&b); /* keep entire string */ else { luaL_argcheck(L, l == strlen(s), arg, "string contains zeros"); - if (!strchr(form, '.') && l >= 100) { + checkformat(L, form, L_FMTFLAGSC, 1); + if (strchr(form, '.') == NULL && l >= 100) { /* no precision and string is too long to be formatted */ luaL_addvalue(&b); /* keep entire string */ } @@ -1352,15 +1412,6 @@ static const union { } nativeendian = {1}; -/* dummy structure to get native alignment requirements */ -struct cD { - char c; - union { double d; void *p; lua_Integer i; lua_Number n; } u; -}; - -#define MAXALIGN (offsetof(struct cD, u)) - - /* ** information to pack/unpack stuff */ @@ -1435,6 +1486,8 @@ static void initheader (lua_State *L, Header *h) { ** Read and classify next option. 'size' is filled with option's size. */ static KOption getoption (Header *h, const char **fmt, int *size) { + /* dummy structure to get native alignment requirements */ + struct cD { char c; union { LUAI_MAXALIGN; } u; }; int opt = *((*fmt)++); *size = 0; /* default */ switch (opt) { @@ -1465,7 +1518,11 @@ static KOption getoption (Header *h, const char **fmt, int *size) { case '<': h->islittle = 1; break; case '>': h->islittle = 0; break; case '=': h->islittle = nativeendian.little; break; - case '!': h->maxalign = getnumlimit(h, fmt, MAXALIGN); break; + case '!': { + const int maxalign = offsetof(struct cD, u); + h->maxalign = getnumlimit(h, fmt, maxalign); + break; + } default: luaL_error(h->L, "invalid format option '%c'", opt); } return Knop; diff --git a/src/3rdparty/lua/lua-5.4.3/src/ltable.c b/src/3rdparty/lua/lua-5.4.4/src/ltable.c similarity index 96% rename from src/3rdparty/lua/lua-5.4.3/src/ltable.c rename to src/3rdparty/lua/lua-5.4.4/src/ltable.c index 33c1ab3..1b1cd24 100644 --- a/src/3rdparty/lua/lua-5.4.3/src/ltable.c +++ b/src/3rdparty/lua/lua-5.4.4/src/ltable.c @@ -84,8 +84,6 @@ #define hashstr(t,str) hashpow2(t, (str)->hash) #define hashboolean(t,p) hashpow2(t, p) -#define hashint(t,i) hashpow2(t, i) - #define hashpointer(t,p) hashmod(t, point2uint(p)) @@ -101,6 +99,20 @@ static const Node dummynode_ = { static const TValue absentkey = {ABSTKEYCONSTANT}; +/* +** Hash for integers. To allow a good hash, use the remainder operator +** ('%'). If integer fits as a non-negative int, compute an int +** remainder, which is faster. Otherwise, use an unsigned-integer +** remainder, which uses all bits and ensures a non-negative result. +*/ +static Node *hashint (const Table *t, lua_Integer i) { + lua_Unsigned ui = l_castS2U(i); + if (ui <= (unsigned int)INT_MAX) + return hashmod(t, cast_int(ui)); + else + return hashmod(t, ui); +} + /* ** Hash for floating-point numbers. @@ -134,26 +146,24 @@ static int l_hashfloat (lua_Number n) { /* ** returns the 'main' position of an element in a table (that is, -** the index of its hash value). The key comes broken (tag in 'ktt' -** and value in 'vkl') so that we can call it on keys inserted into -** nodes. +** the index of its hash value). */ -static Node *mainposition (const Table *t, int ktt, const Value *kvl) { - switch (withvariant(ktt)) { +static Node *mainpositionTV (const Table *t, const TValue *key) { + switch (ttypetag(key)) { case LUA_VNUMINT: { - lua_Integer key = ivalueraw(*kvl); - return hashint(t, key); + lua_Integer i = ivalue(key); + return hashint(t, i); } case LUA_VNUMFLT: { - lua_Number n = fltvalueraw(*kvl); + lua_Number n = fltvalue(key); return hashmod(t, l_hashfloat(n)); } case LUA_VSHRSTR: { - TString *ts = tsvalueraw(*kvl); + TString *ts = tsvalue(key); return hashstr(t, ts); } case LUA_VLNGSTR: { - TString *ts = tsvalueraw(*kvl); + TString *ts = tsvalue(key); return hashpow2(t, luaS_hashlongstr(ts)); } case LUA_VFALSE: @@ -161,26 +171,25 @@ static Node *mainposition (const Table *t, int ktt, const Value *kvl) { case LUA_VTRUE: return hashboolean(t, 1); case LUA_VLIGHTUSERDATA: { - void *p = pvalueraw(*kvl); + void *p = pvalue(key); return hashpointer(t, p); } case LUA_VLCF: { - lua_CFunction f = fvalueraw(*kvl); + lua_CFunction f = fvalue(key); return hashpointer(t, f); } default: { - GCObject *o = gcvalueraw(*kvl); + GCObject *o = gcvalue(key); return hashpointer(t, o); } } } -/* -** Returns the main position of an element given as a 'TValue' -*/ -static Node *mainpositionTV (const Table *t, const TValue *key) { - return mainposition(t, rawtt(key), valraw(key)); +l_sinline Node *mainpositionfromnode (const Table *t, Node *nd) { + TValue key; + getnodekey(cast(lua_State *, NULL), &key, nd); + return mainpositionTV(t, &key); } @@ -679,7 +688,7 @@ void luaH_newkey (lua_State *L, Table *t, const TValue *key, TValue *value) { return; } lua_assert(!isdummy(t)); - othern = mainposition(t, keytt(mp), &keyval(mp)); + othern = mainpositionfromnode(t, mp); if (othern != mp) { /* is colliding node out of its main position? */ /* yes; move colliding node into free position */ while (othern + gnext(othern) != mp) /* find previous */ diff --git a/src/3rdparty/lua/lua-5.4.3/src/ltable.h b/src/3rdparty/lua/lua-5.4.4/src/ltable.h similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/ltable.h rename to src/3rdparty/lua/lua-5.4.4/src/ltable.h diff --git a/src/3rdparty/lua/lua-5.4.3/src/ltablib.c b/src/3rdparty/lua/lua-5.4.4/src/ltablib.c similarity index 98% rename from src/3rdparty/lua/lua-5.4.3/src/ltablib.c rename to src/3rdparty/lua/lua-5.4.4/src/ltablib.c index d80eb80..868d78f 100644 --- a/src/3rdparty/lua/lua-5.4.3/src/ltablib.c +++ b/src/3rdparty/lua/lua-5.4.4/src/ltablib.c @@ -59,8 +59,9 @@ static void checktab (lua_State *L, int arg, int what) { static int tinsert (lua_State *L) { - lua_Integer e = aux_getn(L, 1, TAB_RW) + 1; /* first empty element */ lua_Integer pos; /* where to insert new element */ + lua_Integer e = aux_getn(L, 1, TAB_RW); + e = luaL_intop(+, e, 1); /* first empty element */ switch (lua_gettop(L)) { case 2: { /* called with only 2 arguments */ pos = e; /* insert new element at the end */ @@ -147,7 +148,7 @@ static void addfield (lua_State *L, luaL_Buffer *b, lua_Integer i) { lua_geti(L, 1, i); if (l_unlikely(!lua_isstring(L, -1))) luaL_error(L, "invalid value (%s) at index %I in table for 'concat'", - luaL_typename(L, -1), i); + luaL_typename(L, -1), (LUAI_UACINT)i); luaL_addvalue(b); } diff --git a/src/3rdparty/lua/lua-5.4.3/src/ltm.c b/src/3rdparty/lua/lua-5.4.4/src/ltm.c similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/ltm.c rename to src/3rdparty/lua/lua-5.4.4/src/ltm.c diff --git a/src/3rdparty/lua/lua-5.4.3/src/ltm.h b/src/3rdparty/lua/lua-5.4.4/src/ltm.h similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/ltm.h rename to src/3rdparty/lua/lua-5.4.4/src/ltm.h diff --git a/src/3rdparty/lua/lua-5.4.3/src/lua.c b/src/3rdparty/lua/lua-5.4.4/src/lua.c similarity index 94% rename from src/3rdparty/lua/lua-5.4.3/src/lua.c rename to src/3rdparty/lua/lua-5.4.4/src/lua.c index 46b48db..0f19004 100644 --- a/src/3rdparty/lua/lua-5.4.3/src/lua.c +++ b/src/3rdparty/lua/lua-5.4.4/src/lua.c @@ -89,14 +89,15 @@ static void print_usage (const char *badoption) { lua_writestringerror( "usage: %s [options] [script [args]]\n" "Available options are:\n" - " -e stat execute string 'stat'\n" - " -i enter interactive mode after executing 'script'\n" - " -l name require library 'name' into global 'name'\n" - " -v show version information\n" - " -E ignore environment variables\n" - " -W turn warnings on\n" - " -- stop handling options\n" - " - stop handling options and execute stdin\n" + " -e stat execute string 'stat'\n" + " -i enter interactive mode after executing 'script'\n" + " -l mod require library 'mod' into global 'mod'\n" + " -l g=mod require library 'mod' into global 'g'\n" + " -v show version information\n" + " -E ignore environment variables\n" + " -W turn warnings on\n" + " -- stop handling options\n" + " - stop handling options and execute stdin\n" , progname); } @@ -207,16 +208,22 @@ static int dostring (lua_State *L, const char *s, const char *name) { /* -** Calls 'require(name)' and stores the result in a global variable -** with the given name. +** Receives 'globname[=modname]' and runs 'globname = require(modname)'. */ -static int dolibrary (lua_State *L, const char *name) { +static int dolibrary (lua_State *L, char *globname) { int status; + char *modname = strchr(globname, '='); + if (modname == NULL) /* no explicit name? */ + modname = globname; /* module name is equal to global name */ + else { + *modname = '\0'; /* global name ends here */ + modname++; /* module name starts after the '=' */ + } lua_getglobal(L, "require"); - lua_pushstring(L, name); - status = docall(L, 1, 1); /* call 'require(name)' */ + lua_pushstring(L, modname); + status = docall(L, 1, 1); /* call 'require(modname)' */ if (status == LUA_OK) - lua_setglobal(L, name); /* global[name] = require return */ + lua_setglobal(L, globname); /* globname = require(modname) */ return report(L, status); } @@ -327,7 +334,7 @@ static int runargs (lua_State *L, char **argv, int n) { switch (option) { case 'e': case 'l': { int status; - const char *extra = argv[i] + 2; /* both options need an argument */ + char *extra = argv[i] + 2; /* both options need an argument */ if (*extra == '\0') extra = argv[++i]; lua_assert(extra != NULL); status = (option == 'e') diff --git a/src/3rdparty/lua/lua-5.4.3/src/lua.h b/src/3rdparty/lua/lua-5.4.4/src/lua.h similarity index 98% rename from src/3rdparty/lua/lua-5.4.3/src/lua.h rename to src/3rdparty/lua/lua-5.4.4/src/lua.h index 820535b..e661839 100644 --- a/src/3rdparty/lua/lua-5.4.3/src/lua.h +++ b/src/3rdparty/lua/lua-5.4.4/src/lua.h @@ -18,14 +18,14 @@ #define LUA_VERSION_MAJOR "5" #define LUA_VERSION_MINOR "4" -#define LUA_VERSION_RELEASE "3" +#define LUA_VERSION_RELEASE "4" #define LUA_VERSION_NUM 504 -#define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + 0) +#define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + 4) #define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR #define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE -#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2021 Lua.org, PUC-Rio" +#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2022 Lua.org, PUC-Rio" #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" @@ -492,7 +492,7 @@ struct lua_Debug { /****************************************************************************** -* Copyright (C) 1994-2021 Lua.org, PUC-Rio. +* Copyright (C) 1994-2022 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 diff --git a/src/3rdparty/lua/lua-5.4.3/src/lua.hpp b/src/3rdparty/lua/lua-5.4.4/src/lua.hpp similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/lua.hpp rename to src/3rdparty/lua/lua-5.4.4/src/lua.hpp diff --git a/src/3rdparty/lua/lua-5.4.3/src/luac.c b/src/3rdparty/lua/lua-5.4.4/src/luac.c similarity index 98% rename from src/3rdparty/lua/lua-5.4.3/src/luac.c rename to src/3rdparty/lua/lua-5.4.4/src/luac.c index 56ddc41..f6db9cf 100644 --- a/src/3rdparty/lua/lua-5.4.3/src/luac.c +++ b/src/3rdparty/lua/lua-5.4.4/src/luac.c @@ -155,6 +155,7 @@ static const Proto* combine(lua_State* L, int n) f->p[i]=toproto(L,i-n-1); if (f->p[i]->sizeupvalues>0) f->p[i]->upvalues[0].instack=0; } + luaM_freearray(L,f->lineinfo,f->sizelineinfo); f->sizelineinfo=0; return f; } @@ -600,11 +601,11 @@ static void PrintCode(const Proto* f) if (c==0) printf("all out"); else printf("%d out",c-1); break; case OP_TAILCALL: - printf("%d %d %d",a,b,c); + printf("%d %d %d%s",a,b,c,ISK); printf(COMMENT "%d in",b-1); break; case OP_RETURN: - printf("%d %d %d",a,b,c); + printf("%d %d %d%s",a,b,c,ISK); printf(COMMENT); if (b==0) printf("all out"); else printf("%d out",b-1); break; @@ -619,7 +620,7 @@ static void PrintCode(const Proto* f) break; case OP_FORPREP: printf("%d %d",a,bx); - printf(COMMENT "to %d",pc+bx+2); + printf(COMMENT "exit to %d",pc+bx+3); break; case OP_TFORPREP: printf("%d %d",a,bx); diff --git a/src/3rdparty/lua/lua-5.4.3/src/luaconf.h b/src/3rdparty/lua/lua-5.4.4/src/luaconf.h similarity index 99% rename from src/3rdparty/lua/lua-5.4.3/src/luaconf.h rename to src/3rdparty/lua/lua-5.4.4/src/luaconf.h index e64d2ee..d42d14b 100644 --- a/src/3rdparty/lua/lua-5.4.3/src/luaconf.h +++ b/src/3rdparty/lua/lua-5.4.4/src/luaconf.h @@ -485,7 +485,6 @@ @@ LUA_MAXINTEGER is the maximum value for a LUA_INTEGER. @@ LUA_MININTEGER is the minimum value for a LUA_INTEGER. @@ LUA_MAXUNSIGNED is the maximum value for a LUA_UNSIGNED. -@@ LUA_UNSIGNEDBITS is the number of bits in a LUA_UNSIGNED. @@ lua_integer2str converts an integer to a string. */ @@ -506,9 +505,6 @@ #define LUA_UNSIGNED unsigned LUAI_UACINT -#define LUA_UNSIGNEDBITS (sizeof(LUA_UNSIGNED) * CHAR_BIT) - - /* now the variable definitions */ #if LUA_INT_TYPE == LUA_INT_INT /* { int */ diff --git a/src/3rdparty/lua/lua-5.4.3/src/lualib.h b/src/3rdparty/lua/lua-5.4.4/src/lualib.h similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/lualib.h rename to src/3rdparty/lua/lua-5.4.4/src/lualib.h diff --git a/src/3rdparty/lua/lua-5.4.3/src/lundump.c b/src/3rdparty/lua/lua-5.4.4/src/lundump.c similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/lundump.c rename to src/3rdparty/lua/lua-5.4.4/src/lundump.c diff --git a/src/3rdparty/lua/lua-5.4.3/src/lundump.h b/src/3rdparty/lua/lua-5.4.4/src/lundump.h similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/lundump.h rename to src/3rdparty/lua/lua-5.4.4/src/lundump.h diff --git a/src/3rdparty/lua/lua-5.4.3/src/lutf8lib.c b/src/3rdparty/lua/lua-5.4.4/src/lutf8lib.c similarity index 96% rename from src/3rdparty/lua/lua-5.4.3/src/lutf8lib.c rename to src/3rdparty/lua/lua-5.4.4/src/lutf8lib.c index 901d985..e7bf098 100644 --- a/src/3rdparty/lua/lua-5.4.3/src/lutf8lib.c +++ b/src/3rdparty/lua/lua-5.4.4/src/lutf8lib.c @@ -224,14 +224,11 @@ static int byteoffset (lua_State *L) { static int iter_aux (lua_State *L, int strict) { size_t len; const char *s = luaL_checklstring(L, 1, &len); - lua_Integer n = lua_tointeger(L, 2) - 1; - if (n < 0) /* first iteration? */ - n = 0; /* start from here */ - else if (n < (lua_Integer)len) { - n++; /* skip current byte */ - while (iscont(s + n)) n++; /* and its continuations */ + lua_Unsigned n = (lua_Unsigned)lua_tointeger(L, 2); + if (n < len) { + while (iscont(s + n)) n++; /* skip continuation bytes */ } - if (n >= (lua_Integer)len) + if (n >= len) /* (also handles original 'n' being negative) */ return 0; /* no more codepoints */ else { utfint code; diff --git a/src/3rdparty/lua/lua-5.4.3/src/lvm.c b/src/3rdparty/lua/lua-5.4.4/src/lvm.c similarity index 97% rename from src/3rdparty/lua/lua-5.4.3/src/lvm.c rename to src/3rdparty/lua/lua-5.4.4/src/lvm.c index c9729bc..2ec3440 100644 --- a/src/3rdparty/lua/lua-5.4.3/src/lvm.c +++ b/src/3rdparty/lua/lua-5.4.4/src/lvm.c @@ -406,7 +406,7 @@ static int l_strcmp (const TString *ls, const TString *rs) { ** from float to int.) ** When 'f' is NaN, comparisons must result in false. */ -static int LTintfloat (lua_Integer i, lua_Number f) { +l_sinline int LTintfloat (lua_Integer i, lua_Number f) { if (l_intfitsf(i)) return luai_numlt(cast_num(i), f); /* compare them as floats */ else { /* i < f <=> i < ceil(f) */ @@ -423,7 +423,7 @@ static int LTintfloat (lua_Integer i, lua_Number f) { ** Check whether integer 'i' is less than or equal to float 'f'. ** See comments on previous function. */ -static int LEintfloat (lua_Integer i, lua_Number f) { +l_sinline int LEintfloat (lua_Integer i, lua_Number f) { if (l_intfitsf(i)) return luai_numle(cast_num(i), f); /* compare them as floats */ else { /* i <= f <=> i <= floor(f) */ @@ -440,7 +440,7 @@ static int LEintfloat (lua_Integer i, lua_Number f) { ** Check whether float 'f' is less than integer 'i'. ** See comments on previous function. */ -static int LTfloatint (lua_Number f, lua_Integer i) { +l_sinline int LTfloatint (lua_Number f, lua_Integer i) { if (l_intfitsf(i)) return luai_numlt(f, cast_num(i)); /* compare them as floats */ else { /* f < i <=> floor(f) < i */ @@ -457,7 +457,7 @@ static int LTfloatint (lua_Number f, lua_Integer i) { ** Check whether float 'f' is less than or equal to integer 'i'. ** See comments on previous function. */ -static int LEfloatint (lua_Number f, lua_Integer i) { +l_sinline int LEfloatint (lua_Number f, lua_Integer i) { if (l_intfitsf(i)) return luai_numle(f, cast_num(i)); /* compare them as floats */ else { /* f <= i <=> ceil(f) <= i */ @@ -473,7 +473,7 @@ static int LEfloatint (lua_Number f, lua_Integer i) { /* ** Return 'l < r', for numbers. */ -static int LTnum (const TValue *l, const TValue *r) { +l_sinline int LTnum (const TValue *l, const TValue *r) { lua_assert(ttisnumber(l) && ttisnumber(r)); if (ttisinteger(l)) { lua_Integer li = ivalue(l); @@ -495,7 +495,7 @@ static int LTnum (const TValue *l, const TValue *r) { /* ** Return 'l <= r', for numbers. */ -static int LEnum (const TValue *l, const TValue *r) { +l_sinline int LEnum (const TValue *l, const TValue *r) { lua_assert(ttisnumber(l) && ttisnumber(r)); if (ttisinteger(l)) { lua_Integer li = ivalue(l); @@ -766,7 +766,8 @@ lua_Number luaV_modf (lua_State *L, lua_Number m, lua_Number n) { /* ** Shift left operation. (Shift right just negates 'y'.) */ -#define luaV_shiftr(x,y) luaV_shiftl(x,-(y)) +#define luaV_shiftr(x,y) luaV_shiftl(x,intop(-, 0, y)) + lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) { if (y < 0) { /* shift right? */ @@ -847,10 +848,19 @@ void luaV_finishOp (lua_State *L) { luaV_concat(L, total); /* concat them (may yield again) */ break; } - case OP_CLOSE: case OP_RETURN: { /* yielded closing variables */ + case OP_CLOSE: { /* yielded closing variables */ ci->u.l.savedpc--; /* repeat instruction to close other vars. */ break; } + case OP_RETURN: { /* yielded closing variables */ + StkId ra = base + GETARG_A(inst); + /* adjust top to signal correct number of returns, in case the + return is "up to top" ('isIT') */ + L->top = ra + ci->u2.nres; + /* repeat instruction to close other vars. and complete the return */ + ci->u.l.savedpc--; + break; + } default: { /* only these other opcodes can yield */ lua_assert(op == OP_TFORCALL || op == OP_CALL || @@ -1099,7 +1109,7 @@ void luaV_finishOp (lua_State *L) { #define ProtectNT(exp) (savepc(L), (exp), updatetrap(ci)) /* -** Protect code that can only raise errors. (That is, it cannnot change +** Protect code that can only raise errors. (That is, it cannot change ** the stack or hooks.) */ #define halfProtect(exp) (savestate(L,ci), (exp)) @@ -1156,8 +1166,10 @@ void luaV_execute (lua_State *L, CallInfo *ci) { Instruction i; /* instruction being executed */ StkId ra; /* instruction's A register */ vmfetch(); -// low-level line tracing for debugging Lua -// printf("line: %d\n", luaG_getfuncline(cl->p, pcRel(pc, cl->p))); + #if 0 + /* low-level line tracing for debugging Lua */ + printf("line: %d\n", luaG_getfuncline(cl->p, pcRel(pc, cl->p))); + #endif lua_assert(base == ci->func + 1); lua_assert(base <= L->top && L->top < L->stack_last); /* invalidate top for instructions not expecting it */ @@ -1625,13 +1637,13 @@ void luaV_execute (lua_State *L, CallInfo *ci) { updatetrap(ci); /* C call; nothing else to be done */ else { /* Lua call: run function in this same C frame */ ci = newci; - ci->callstatus = 0; /* call re-uses 'luaV_execute' */ goto startfunc; } vmbreak; } vmcase(OP_TAILCALL) { int b = GETARG_B(i); /* number of arguments + 1 (function) */ + int n; /* number of results when calling a C function */ int nparams1 = GETARG_C(i); /* delta is virtual 'func' - real 'func' (vararg functions) */ int delta = (nparams1) ? ci->u.l.nextraargs + nparams1 : 0; @@ -1645,23 +1657,14 @@ void luaV_execute (lua_State *L, CallInfo *ci) { lua_assert(L->tbclist < base); /* no pending tbc variables */ lua_assert(base == ci->func + 1); } - while (!ttisfunction(s2v(ra))) { /* not a function? */ - luaD_tryfuncTM(L, ra); /* try '__call' metamethod */ - b++; /* there is now one extra argument */ - checkstackGCp(L, 1, ra); - } - if (!ttisLclosure(s2v(ra))) { /* C function? */ - luaD_precall(L, ra, LUA_MULTRET); /* call it */ - updatetrap(ci); - updatestack(ci); /* stack may have been relocated */ + if ((n = luaD_pretailcall(L, ci, ra, b, delta)) < 0) /* Lua function? */ + goto startfunc; /* execute the callee */ + else { /* C function? */ ci->func -= delta; /* restore 'func' (if vararg) */ - luaD_poscall(L, ci, cast_int(L->top - ra)); /* finish caller */ + luaD_poscall(L, ci, n); /* finish caller */ updatetrap(ci); /* 'luaD_poscall' can change hooks */ goto ret; /* caller returns after the tail call */ } - ci->func -= delta; /* restore 'func' (if vararg) */ - luaD_pretailcall(L, ci, ra, b); /* prepare call frame */ - goto startfunc; /* execute the callee */ } vmcase(OP_RETURN) { int n = GETARG_B(i) - 1; /* number of results */ @@ -1670,6 +1673,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { n = cast_int(L->top - ra); /* get what is available */ savepc(ci); if (TESTARG_k(i)) { /* may there be open upvalues? */ + ci->u2.nres = n; /* save number of returns */ if (L->top < ci->top) L->top = ci->top; luaF_close(L, base, CLOSEKTOP, 1); diff --git a/src/3rdparty/lua/lua-5.4.3/src/lvm.h b/src/3rdparty/lua/lua-5.4.4/src/lvm.h similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/lvm.h rename to src/3rdparty/lua/lua-5.4.4/src/lvm.h diff --git a/src/3rdparty/lua/lua-5.4.3/src/lzio.c b/src/3rdparty/lua/lua-5.4.4/src/lzio.c similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/lzio.c rename to src/3rdparty/lua/lua-5.4.4/src/lzio.c diff --git a/src/3rdparty/lua/lua-5.4.3/src/lzio.h b/src/3rdparty/lua/lua-5.4.4/src/lzio.h similarity index 100% rename from src/3rdparty/lua/lua-5.4.3/src/lzio.h rename to src/3rdparty/lua/lua-5.4.4/src/lzio.h diff --git a/src/cmake/Version.cmake b/src/cmake/Version.cmake index e169a83..fd96ec6 100644 --- a/src/cmake/Version.cmake +++ b/src/cmake/Version.cmake @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.3.0) set(PRODUCT_VERSION_MAJOR 1) set(PRODUCT_VERSION_MINOR 0) -set(PRODUCT_VERSION_PATCH 2) +set(PRODUCT_VERSION_PATCH 3) try_compile(CPU_DETECTED "${CMAKE_CURRENT_BINARY_DIR}/try_compile/DetectCPU" "${CMAKE_CURRENT_LIST_DIR}/DetectCPU.c" COPY_FILE "${CMAKE_CURRENT_BINARY_DIR}/try_compile/DetectCPU.bin") diff --git a/src/doc/manual/images/pluginprovider.pdf b/src/doc/manual/images/pluginprovider.pdf index cf8dec0..653550e 100644 Binary files a/src/doc/manual/images/pluginprovider.pdf and b/src/doc/manual/images/pluginprovider.pdf differ diff --git a/src/doc/manual/images/pluginprovider.svg b/src/doc/manual/images/pluginprovider.svg index a7d7b9a..977caf3 100644 --- a/src/doc/manual/images/pluginprovider.svg +++ b/src/doc/manual/images/pluginprovider.svg @@ -13,7 +13,7 @@ height="619.0625" id="svg2" version="1.1" - inkscape:version="0.91 r13725" + inkscape:version="0.92.3 (2405546, 2018-03-11)" sodipodi:docname="pluginprovider.svg"> @@ -40,8 +40,8 @@ inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="1.0000001" - inkscape:cx="655.04725" - inkscape:cy="303.54382" + inkscape:cx="501.06191" + inkscape:cy="270.4397" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="true" @@ -50,9 +50,9 @@ fit-margin-right="15" fit-margin-bottom="15" inkscape:window-width="1920" - inkscape:window-height="1003" - inkscape:window-x="-9" - inkscape:window-y="-9" + inkscape:window-height="991" + inkscape:window-x="0" + inkscape:window-y="28" inkscape:window-maximized="1"> image/svg+xml - + @@ -84,7 +84,7 @@   SDMPropertyManager()~SDMPropertyManager() [virtual]clear()addProperty()addConstProperty()addListItem()getProperty() [clear()addProperty()addConstProperty()addListItem()getProperty() [virtual, 2 overloads]setProperty() [setProperty() [virtual] SDMAbstractDeviceProvider + sodipodi:role="line">SDMAbstractDevice SDMAbstractDeviceProvider()~SDMAbstractDeviceProvider() [virtual]close() [virtual]openChannel() [openChannel() [virtual]openSource() [openSource() [virtual]connect() [virtual]disconnect() [virtual]getConnectionStatus() [ SDMAbstractPluginProvider + style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:16px;line-height:1.25;font-family:'DejaVu Sans Mono';-inkscape-font-specification:'DejaVu Sans Mono'">SDMAbstractPlugin SDMAbstractPluginProvider()~SDMAbstractPluginProvider() [virtual]openDeviceopenDevice() [virtual]instance() [defined by the user] instance() [defined by the user]  SDMAbstractChannelProvider + style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:16px;line-height:1.25;font-family:'DejaVu Sans Mono';-inkscape-font-specification:'DejaVu Sans Mono'">SDMAbstractChannel SDMAbstractChannelProvider()~SDMAbstractChannelProvider() [virtual]close() [virtual]writeReg() [virtual]readReg() [virtual]writeFIFO() [writeFIFO() [virtual]readFIFO() [readFIFO() [virtual]writeMem() [writeMem() [virtual]readMem() [readMem() [virtual] @@ -357,17 +354,16 @@ id="rect2987-19-8-8" style="fill:none;stroke:#000000;stroke-width:0.99999994;stroke-opacity:1" /> SDMAbstractSourceProvider + sodipodi:role="line">SDMAbstractSource SDMAbstractSourceProvider()~SDMAbstractSourceProvider() [virtual]close() [virtual]selectReadStreams() [virtual]readStream() [virtual]readNextPacket() [virtual]discardPackets() [virtual]readStreamErrors() [readStreamErrors() [virtual] + +int main() { +// Open plugin objects + SDMPlugin plugin("./testplugin"); + SDMDevice dev(plugin,0); + SDMChannel ch(dev,0); + SDMSource src(dev,0); + +// Connect the device + dev.setProperty("Setting1","10.0.0.1"); + dev.setProperty("Setting2","9999"); + dev.connect(); + +// Write/read a register + std::cout<<"Writing register..."< streams {0}; + src.selectReadStreams(streams,0,1); + sdm_sample_t buf[10000]; + for(int i=0;i<5;i++) { + auto samples=src.readStream(0,buf,10000); + std::cout<<"Reading stream 0 data: "; + std::cout< $) -install(TARGETS api EXPORT sdm) - -install(DIRECTORY include/ - DESTINATION "${INCLUDE_INSTALL_DIR}/sdk/api") +if(INCLUDE_INSTALL_DIR) + install(TARGETS api EXPORT sdm) + install(DIRECTORY include/ DESTINATION "${INCLUDE_INSTALL_DIR}/sdk/api") +endif() diff --git a/src/sdk/examples/testplugin/testplugin.cpp b/src/sdk/examples/testplugin/testplugin.cpp index eeb19b4..4fdfa8e 100644 --- a/src/sdk/examples/testplugin/testplugin.cpp +++ b/src/sdk/examples/testplugin/testplugin.cpp @@ -38,7 +38,7 @@ * TestPlugin instance */ -SDMAbstractPluginProvider *SDMAbstractPluginProvider::instance() { +SDMAbstractPlugin *SDMAbstractPlugin::instance() { static TestPlugin plugin; return &plugin; } @@ -59,7 +59,7 @@ TestPlugin::TestPlugin() { addProperty("DisableChildProperties","false"); } -SDMAbstractDeviceProvider *TestPlugin::openDevice(int id) { +SDMAbstractDevice *TestPlugin::openDevice(int id) { if(getProperty("Verbosity")!="Quiet") std::cout<<"testplugin: entered sdmOpenDevice()"<getProperty("DisableChildProperties")=="true") return; + if(SDMAbstractPlugin::instance()->getProperty("DisableChildProperties")=="true") return; addConstProperty("Name","Test device "+std::to_string(id+1)); - auto const &aom=SDMAbstractPluginProvider::instance()->getProperty("AutoOpenMode"); + auto const &aom=SDMAbstractPlugin::instance()->getProperty("AutoOpenMode"); addConstProperty("AutoOpenChannels",aom); addConstProperty("AutoOpenSources",aom); @@ -97,14 +97,14 @@ TestDevice::TestDevice(int id) { } int TestDevice::close() { - if(SDMAbstractPluginProvider::instance()->getProperty("Verbosity")!="Quiet") + if(SDMAbstractPlugin::instance()->getProperty("Verbosity")!="Quiet") std::cout<<"testplugin: entered sdmCloseDevice()"<getProperty("Verbosity")!="Quiet") +SDMAbstractChannel *TestDevice::openChannel(int id) { + if(SDMAbstractPlugin::instance()->getProperty("Verbosity")!="Quiet") std::cout<<"testplugin: entered sdmOpenChannel()"<getProperty("Verbosity")!="Quiet") +SDMAbstractSource *TestDevice::openSource(int id) { + if(SDMAbstractPlugin::instance()->getProperty("Verbosity")!="Quiet") std::cout<<"testplugin: entered sdmOpenSource()"<getProperty("Verbosity")!="Quiet") { + if(SDMAbstractPlugin::instance()->getProperty("Verbosity")!="Quiet") { std::cout<<"testplugin: entered sdmConnect()"<getProperty("DisableChildProperties")!="true") { + if(SDMAbstractPlugin::instance()->getProperty("DisableChildProperties")!="true") { std::cout<<"testplugin: connection parameters are: "<< "Setting1=\""<getProperty("Verbosity")!="Quiet") + if(SDMAbstractPlugin::instance()->getProperty("Verbosity")!="Quiet") std::cout<<"testplugin: entered sdmDisconnect()"<getProperty("Verbosity")=="Verbose") + if(SDMAbstractPlugin::instance()->getProperty("Verbosity")=="Verbose") std::cout<<"testplugin: entered sdmGetConnectionStatus()"<getProperty("DisableChildProperties")=="true") return; + if(SDMAbstractPlugin::instance()->getProperty("DisableChildProperties")=="true") return; if(_id==0) { addConstProperty("Name","Measurement equipment"); addConstProperty("RegisterMapFile","testplugin/map.srm"); @@ -184,7 +184,7 @@ TestChannel::TestChannel(int id,const bool &connected): } int TestChannel::close() { - if(SDMAbstractPluginProvider::instance()->getProperty("Verbosity")!="Quiet") + if(SDMAbstractPlugin::instance()->getProperty("Verbosity")!="Quiet") std::cout<<"testplugin: entered sdmCloseChannel()"<getProperty("Verbosity")=="Verbose") { + if(SDMAbstractPlugin::instance()->getProperty("Verbosity")=="Verbose") { std::cout<<"testplugin: entered sdmWriteReg()"<getProperty("Verbosity")=="Verbose") { + if(SDMAbstractPlugin::instance()->getProperty("Verbosity")=="Verbose") { std::cout<<"testplugin: entered sdmReadReg()"<getProperty("Verbosity")=="Verbose") { + if(SDMAbstractPlugin::instance()->getProperty("Verbosity")=="Verbose") { std::cout<<"testplugin: entered sdmWriteFIFO()"<getProperty("Verbosity")=="Verbose") { + if(SDMAbstractPlugin::instance()->getProperty("Verbosity")=="Verbose") { std::cout<<"testplugin: entered sdmReadFIFO()"<getProperty("Verbosity")=="Verbose") { + if(SDMAbstractPlugin::instance()->getProperty("Verbosity")=="Verbose") { std::cout<<"testplugin: entered sdmWriteMem()"<getProperty("Verbosity")=="Verbose") { + if(SDMAbstractPlugin::instance()->getProperty("Verbosity")=="Verbose") { std::cout<<"testplugin: entered sdmReadMem()"<getProperty("DisableChildProperties")=="true") return; + if(SDMAbstractPlugin::instance()->getProperty("DisableChildProperties")=="true") return; if(_id==0) addConstProperty("Name","Source 1"); else if(_id==1) addConstProperty("Name","Source 2"); if(_id==0) addConstProperty("ShowStreams","0,1"); @@ -396,7 +396,7 @@ TestSource::TestSource(int id,const bool &connected): } int TestSource::close() { - if(SDMAbstractPluginProvider::instance()->getProperty("Verbosity")!="Quiet") + if(SDMAbstractPlugin::instance()->getProperty("Verbosity")!="Quiet") std::cout<<"testplugin: entered sdmCloseSource()"<getProperty("Verbosity")!="Quiet") { + if(SDMAbstractPlugin::instance()->getProperty("Verbosity")!="Quiet") { std::cout<<"testplugin: entered sdmSelectReadStreams()"<getProperty("Verbosity")=="Verbose") { - std::cout<<"testplugin: entered sdmReadStream()"<INT_MAX) n=INT_MAX; @@ -485,7 +479,7 @@ int TestSource::readStream(int stream,sdm_sample_t *data,std::size_t n,int nb) { } int TestSource::readNextPacket() { - if(SDMAbstractPluginProvider::instance()->getProperty("Verbosity")=="Verbose") + if(SDMAbstractPlugin::instance()->getProperty("Verbosity")=="Verbose") std::cout<<"testplugin: entered sdmReadNextPacket()"<getProperty("Verbosity")=="Verbose") + if(SDMAbstractPlugin::instance()->getProperty("Verbosity")=="Verbose") std::cout<<"testplugin: entered sdmDiscardPackets()"<getProperty("Verbosity")=="Verbose") + if(SDMAbstractPlugin::instance()->getProperty("Verbosity")=="Verbose") std::cout<<"testplugin: entered sdmSelectReadStreams()"<getProperty("Verbosity")!="Quiet") + if(SDMAbstractPlugin::instance()->getProperty("Verbosity")!="Quiet") std::cout<<"testplugin: entered sdmCloseSource()"<getProperty("Verbosity")!="Quiet") { + if(SDMAbstractPlugin::instance()->getProperty("Verbosity")!="Quiet") { std::cout<<"testplugin: entered sdmSelectReadStreams()"<getProperty("Verbosity")=="Verbose") { + if(SDMAbstractPlugin::instance()->getProperty("Verbosity")=="Verbose") { std::cout<<"testplugin: entered sdmReadStream()"<getProperty("Verbosity")=="Verbose") + if(SDMAbstractPlugin::instance()->getProperty("Verbosity")=="Verbose") std::cout<<"testplugin: entered sdmReadNextPacket()"<getProperty("Verbosity")=="Verbose") + if(SDMAbstractPlugin::instance()->getProperty("Verbosity")=="Verbose") std::cout<<"testplugin: entered sdmDiscardPackets()"<getProperty("Verbosity")=="Verbose") + if(SDMAbstractPlugin::instance()->getProperty("Verbosity")=="Verbose") std::cout<<"testplugin: entered sdmSelectReadStreams()"< #include #include +#include #define MAXBUFSIZE 65536 @@ -42,7 +43,7 @@ * initialization order fiasco". */ -SDMAbstractPluginProvider *SDMAbstractPluginProvider::instance() { +SDMAbstractPlugin *SDMAbstractPlugin::instance() { static UartPlugin plugin; return &plugin; } @@ -57,7 +58,7 @@ UartPlugin::UartPlugin() { addListItem("Devices","Arduino Uno"); } -SDMAbstractDeviceProvider *UartPlugin::openDevice(int id) { +SDMAbstractDevice *UartPlugin::openDevice(int id) { if(id!=0) throw std::runtime_error("No device with such ID"); return new UartDevice(); } @@ -94,12 +95,12 @@ int UartDevice::close() { return 0; } -SDMAbstractChannelProvider *UartDevice::openChannel(int id) { +SDMAbstractChannel *UartDevice::openChannel(int id) { if(id!=0) throw std::runtime_error("No channel with such ID"); return new UartChannel(_port,_q); } -SDMAbstractSourceProvider *UartDevice::openSource(int id) { +SDMAbstractSource *UartDevice::openSource(int id) { if(id!=0) throw std::runtime_error("No source with such ID"); return new UartSource(_port,_q); } @@ -198,93 +199,54 @@ int UartSource::close() { return 0; } -int UartSource::selectReadStreams(const int *streams,std::size_t n,std::size_t packets,int df) { -// In this example we don't need to do anything specific when streams -// are selected since the device is always transmitting data. -// Nevertheless, reading stream data before selecting the stream is an error -// per SDM API spec, so we check for that. -// Here we have only one stream, so the user can select either it or nothing. - if(n==0) _selected=false; - else if(n==1&&streams[0]==0) _selected=true; - else throw std::runtime_error("Bad stream set"); - UartSource::discardPackets(); - return 0; -} - -int UartSource::readStream(int stream,sdm_sample_t *data,std::size_t n,int nb) { -// Reading stream data before selecting the stream is an error - if(!_selected) throw std::runtime_error("Stream not selected"); -// We have only one stream - if(stream!=0) throw std::runtime_error("Bad stream ID"); -// Exit immediately if no data has been requested - if(n==0) return 0; - -// Process data from the queue - std::size_t loaded=loadFromQueue(data,n); +void UartSource::addDataToQueue(std::size_t samples,bool nonBlocking) { +// Add data to the raw queue + if(_q.size() buf(toread); + auto r=_port.read(buf.data(),toread,nonBlocking?0:-1); + _q.insert(_q.end(),buf.begin(),buf.begin()+r); + } - do { -// Read new data from the serial port - if(_q.size()0||(_cnt>0&&endOfFrame())); - std::vector buf(toread); - auto r=_port.read(buf.data(),toread,nonBlocking?0:-1); // will read "toread" bytes or fewer - _q.insert(_q.end(),buf.begin(),buf.begin()+r); +// Update processed packets queue + while(!_q.empty()) { + if((_q.front()&0xC0)!=0xC0) { // Not a stream data packet, skip + _q.pop_front(); + continue; } - - if(loaded0&&endOfFrame())); - - if(loaded==0&&endOfFrame()&&_cnt>0) return 0; // end of frame - if(loaded==0) { - if(nb==0) throw std::runtime_error("Blocking read operation failed to return data"); - return SDM_WOULDBLOCK; + if(_q.size()<2) break; // packet size is 2 bytes + int sample=((_q[0]&0x1F)<<5)|(_q[1]&0x1F); + if((_q.front()&0xE0)==0xE0) { // new packet + _packets.push_back(std::vector()); + _packets.back().push_back(sample); + } + else if(!_packets.empty()) { + _packets.back().push_back(sample); + } + _q.erase(_q.begin(),_q.begin()+2); } - return static_cast(loaded); } -int UartSource::readNextPacket() { - _cnt=0; - return 0; +std::size_t UartSource::getSamplesFromQueue(int stream,std::size_t pos,sdm_sample_t *data,std::size_t n,bool &eop) { + if(_packets.empty()) return 0; + auto const &p=_packets.front(); + if(pos>=p.size()) pos=p.size(); + auto toread=std::min(n,p.size()-pos); + if(toread>0) std::copy(p.begin()+pos,p.begin()+pos+toread,data); + else if(_packets.size()>1) eop=true; + return toread; +} + +void UartSource::next() { + if(!_packets.empty()) _packets.pop_front(); } -void UartSource::discardPackets() { +void UartSource::clear() { + _packets.clear(); _q.clear(); // Note: after the first readAll() there may still be some out-of-sequence // data in the serial port buffer. Wait a bit and repeat. _port.readAll(); std::this_thread::sleep_for(std::chrono::milliseconds(50)); _port.readAll(); - readNextPacket(); -} - -std::size_t UartSource::loadFromQueue(sdm_sample_t *data,std::size_t n) { - if(n==0) return 0; - - std::size_t current=0; - - while(current(sample); - current++; - _cnt++; - _q.erase(_q.begin(),_q.begin()+2); - } - else break; - } - - return current; // number of samples loaded from the queue -} - -bool UartSource::endOfFrame() const { - if(_q.empty()) return false; - if((_q.front()&0xE0)==0xE0) return true; - return false; } diff --git a/src/sdk/examples/uartdemo/uartdemo.h b/src/sdk/examples/uartdemo/uartdemo.h index 66f41eb..e160651 100644 --- a/src/sdk/examples/uartdemo/uartdemo.h +++ b/src/sdk/examples/uartdemo/uartdemo.h @@ -35,15 +35,15 @@ // Plugin class -class UartPlugin : public SDMAbstractPluginProvider { +class UartPlugin : public SDMAbstractPlugin { public: UartPlugin(); - virtual SDMAbstractDeviceProvider *openDevice(int id) override; + virtual SDMAbstractDevice *openDevice(int id) override; }; // Device class -class UartDevice : public SDMAbstractDeviceProvider { +class UartDevice : public SDMAbstractDevice { Uart _port; // serial port used to communicate std::deque _q; // stream data buffer public: @@ -51,8 +51,8 @@ class UartDevice : public SDMAbstractDeviceProvider { virtual int close() override; - virtual SDMAbstractChannelProvider *openChannel(int id) override; - virtual SDMAbstractSourceProvider *openSource(int id) override; + virtual SDMAbstractChannel *openChannel(int id) override; + virtual SDMAbstractSource *openSource(int id) override; virtual int connect() override; virtual int disconnect() override; @@ -61,7 +61,7 @@ class UartDevice : public SDMAbstractDeviceProvider { // Channel class -class UartChannel : public SDMAbstractChannelProvider { +class UartChannel : public SDMAbstractChannel { Uart &_port; std::deque &_q; public: @@ -73,7 +73,7 @@ class UartChannel : public SDMAbstractChannelProvider { virtual sdm_reg_t readReg(sdm_addr_t addr,int *status) override; /* * Note: Default implementations of writeFIFO(), readFIFO(), writeMem() - * and readMem() provided by SDMAbstractChannelProvider work by repeatedly + * and readMem() provided by SDMAbstractChannel work by repeatedly * calling writeReg and readReg. If the communication protocol supported * block transactions, these methods should have been overriden for better * performance. @@ -84,24 +84,20 @@ class UartChannel : public SDMAbstractChannelProvider { // Source class -class UartSource : public SDMAbstractSourceProvider { +class UartSource : public SDMAbstractQueuedSource { Uart &_port; std::deque &_q; - std::size_t _cnt=0; // number of samples delivered for the current packet - bool _selected=false; + std::deque > _packets; + public: UartSource(Uart &port,std::deque &q); - virtual int close() override; - - virtual int selectReadStreams(const int *streams,std::size_t n,std::size_t packets,int df) override; - virtual int readStream(int stream,sdm_sample_t *data,std::size_t n,int nb) override; - virtual int readNextPacket() override; - virtual void discardPackets() override; - -private: - std::size_t loadFromQueue(sdm_sample_t *data,std::size_t n); - bool endOfFrame() const; + +protected: + virtual void addDataToQueue(std::size_t samples,bool nonBlocking) override; + virtual std::size_t getSamplesFromQueue(int stream,std::size_t pos,sdm_sample_t *data,std::size_t n,bool &eop) override; + virtual void next() override; + virtual void clear() override; }; #endif diff --git a/src/sdk/lib/pluginprovider/include/sdmprovider.h b/src/sdk/lib/pluginprovider/include/sdmprovider.h index f25bc40..84fcba3 100644 --- a/src/sdk/lib/pluginprovider/include/sdmprovider.h +++ b/src/sdk/lib/pluginprovider/include/sdmprovider.h @@ -31,36 +31,30 @@ #include "sdmproperty.h" #include "sdmtypes.h" -class SDMAbstractDeviceProvider; -class SDMAbstractChannelProvider; -class SDMAbstractSourceProvider; +#include -class SDMAbstractPluginProvider : public SDMPropertyManager { +class SDMAbstractDevice; +class SDMAbstractChannel; +class SDMAbstractSource; + +class SDMAbstractPlugin : public SDMPropertyManager { public: - SDMAbstractPluginProvider(); - virtual ~SDMAbstractPluginProvider(); + virtual ~SDMAbstractPlugin() {} - virtual SDMAbstractDeviceProvider *openDevice(int id)=0; + virtual SDMAbstractDevice *openDevice(int id)=0; // Note: instance() function must be defined by the user - static SDMAbstractPluginProvider *instance(); + static SDMAbstractPlugin *instance(); }; -/* - * Note: default implementations of SDMAbstractDeviceProvider::openChannel() - * and SDMAbstractDeviceProvider::openSource() return NULL, indicating that - * the device doesn't support channels/sources. - */ - -class SDMAbstractDeviceProvider : public SDMPropertyManager { +class SDMAbstractDevice : public SDMPropertyManager { public: - SDMAbstractDeviceProvider(); - virtual ~SDMAbstractDeviceProvider(); + virtual ~SDMAbstractDevice() {} virtual int close()=0; - virtual SDMAbstractChannelProvider *openChannel(int id); - virtual SDMAbstractSourceProvider *openSource(int id); + virtual SDMAbstractChannel *openChannel(int id) {return NULL;} + virtual SDMAbstractSource *openSource(int id) {return NULL;} virtual int connect()=0; virtual int disconnect()=0; @@ -85,10 +79,9 @@ class SDMAbstractDeviceProvider : public SDMPropertyManager { * incrementing address each time. */ -class SDMAbstractChannelProvider : public SDMPropertyManager { +class SDMAbstractChannel : public SDMPropertyManager { public: - SDMAbstractChannelProvider(); - virtual ~SDMAbstractChannelProvider(); + virtual ~SDMAbstractChannel() {} virtual int close()=0; @@ -100,15 +93,9 @@ class SDMAbstractChannelProvider : public SDMPropertyManager { virtual int readMem(sdm_addr_t addr,sdm_reg_t *data,std::size_t n); }; -/* - * Note: default implementation of SDMAbstractSourceProvider::readStreamErrors() - * returns 0. - */ - -class SDMAbstractSourceProvider : public SDMPropertyManager { +class SDMAbstractSource : public SDMPropertyManager { public: - SDMAbstractSourceProvider(); - virtual ~SDMAbstractSourceProvider(); + virtual ~SDMAbstractSource() {} virtual int close()=0; @@ -116,7 +103,69 @@ class SDMAbstractSourceProvider : public SDMPropertyManager { virtual int readStream(int stream,sdm_sample_t *data,std::size_t n,int nb)=0; virtual int readNextPacket()=0; virtual void discardPackets()=0; + virtual int readStreamErrors() {return 0;} +}; + +/* + * When deriving source classes from SDMAbstractSource, implementing + * readStream() can be tricky since it is necessary to account for many + * conditions (start/continuation of packet, blocking/non-blocking etc.) + * which leads to mistakes. The SDMAbstractQueuedSource class is designed + * to make implementing source classes easier by separating communication + * with the device and packet queue management. Its interface is not + * considered stable yet. + * + * Derivatives of this class should implement some kind of queue to store + * unprocessed data from the device. + * + * addDataToQueue() reads some data from the device and adds them to the + * queue. "samples" can be used as a hint on how much data to request, but + * can be ignored. If "nonBlocking" is false, the function must not return + * until it read at least 1 byte from the device. If the queue is currently + * empty, addDataToQueue() should start adding data from the start of the + * packet. + * + * getSamplesFromQueue() fills the provided buffer ("data") with up to "n" + * samples from the current packet in the queue, starting with "pos". + * Returns the number of samples added to the buffer. If no samples have been + * returned because of the end of the current packet (pos >= size of + * the current packet), "eop" must be set to true. + * + * next() removes the current packet from queue. This affects all streams. + * + * clear() clears the queue. It should also try to clear data stored in + * OS and hardware buffers if possible. This affects all streams. + * + * isError() returns true when the last call to getSamplesFromQueue() resulted + * in broken stream continuity. + * + */ + +class SDMAbstractQueuedSource : public SDMAbstractSource { + std::map _pos; + int _errors; +public: + SDMAbstractQueuedSource(); + virtual int selectReadStreams(const int *streams,std::size_t n,std::size_t packets,int df); + virtual int readStream(int stream,sdm_sample_t *data,std::size_t n,int nb); + virtual int readNextPacket(); + virtual void discardPackets(); virtual int readStreamErrors(); +protected: + virtual void addDataToQueue(std::size_t samples,bool nonBlocking)=0; + virtual std::size_t getSamplesFromQueue(int stream,std::size_t pos,sdm_sample_t *data,std::size_t n,bool &eop)=0; + virtual void next()=0; + virtual void clear()=0; + virtual bool isError() const {return false;} }; +/* + * The following typedefs are deprecated and provided to support old code. + */ + +typedef SDMAbstractPlugin SDMAbstractPluginProvider; +typedef SDMAbstractDevice SDMAbstractDeviceProvider; +typedef SDMAbstractChannel SDMAbstractChannelProvider; +typedef SDMAbstractSource SDMAbstractSourceProvider; + #endif diff --git a/src/sdk/lib/pluginprovider/src/sdmexport.cpp b/src/sdk/lib/pluginprovider/src/sdmexport.cpp index fca8a92..48e606a 100644 --- a/src/sdk/lib/pluginprovider/src/sdmexport.cpp +++ b/src/sdk/lib/pluginprovider/src/sdmexport.cpp @@ -73,7 +73,7 @@ namespace { SDMAPI int SDMCALL sdmGetPluginProperty(const char *name,char *buf,std::size_t n) { try { - return getProperty(SDMAbstractPluginProvider::instance(),name,buf,n); + return getProperty(SDMAbstractPlugin::instance(),name,buf,n); } catch(std::exception &ex) { displayErrorMessage(ex.what()); @@ -83,7 +83,7 @@ SDMAPI int SDMCALL sdmGetPluginProperty(const char *name,char *buf,std::size_t n SDMAPI int SDMCALL sdmSetPluginProperty(const char *name,const char *value) { try { - return setProperty(SDMAbstractPluginProvider::instance(),name,value); + return setProperty(SDMAbstractPlugin::instance(),name,value); } catch(std::exception &ex) { displayErrorMessage(ex.what()); @@ -97,7 +97,7 @@ SDMAPI int SDMCALL sdmSetPluginProperty(const char *name,const char *value) { SDMAPI void * SDMCALL sdmOpenDevice(int id) { try { - return SDMAbstractPluginProvider::instance()->openDevice(id); + return SDMAbstractPlugin::instance()->openDevice(id); } catch(std::exception &ex) { displayErrorMessage(ex.what()); @@ -107,7 +107,7 @@ SDMAPI void * SDMCALL sdmOpenDevice(int id) { SDMAPI int SDMCALL sdmCloseDevice(void *h) { try { - return static_cast(h)->close(); + return static_cast(h)->close(); } catch(std::exception &ex) { displayErrorMessage(ex.what()); @@ -117,7 +117,7 @@ SDMAPI int SDMCALL sdmCloseDevice(void *h) { SDMAPI int SDMCALL sdmGetDeviceProperty(void *h,const char *name,char *buf,std::size_t n) { try { - return getProperty(static_cast(h),name,buf,n); + return getProperty(static_cast(h),name,buf,n); } catch(std::exception &ex) { displayErrorMessage(ex.what()); @@ -127,7 +127,7 @@ SDMAPI int SDMCALL sdmGetDeviceProperty(void *h,const char *name,char *buf,std:: SDMAPI int SDMCALL sdmSetDeviceProperty(void *h,const char *name,const char *value) { try { - return setProperty(static_cast(h),name,value); + return setProperty(static_cast(h),name,value); } catch(std::exception &ex) { displayErrorMessage(ex.what()); @@ -137,7 +137,7 @@ SDMAPI int SDMCALL sdmSetDeviceProperty(void *h,const char *name,const char *val SDMAPI int SDMCALL sdmConnect(void *h) { try { - return static_cast(h)->connect(); + return static_cast(h)->connect(); } catch(std::exception &ex) { displayErrorMessage(ex.what()); @@ -147,7 +147,7 @@ SDMAPI int SDMCALL sdmConnect(void *h) { SDMAPI int SDMCALL sdmDisconnect(void *h) { try { - return static_cast(h)->disconnect(); + return static_cast(h)->disconnect(); } catch(std::exception &ex) { displayErrorMessage(ex.what()); @@ -157,7 +157,7 @@ SDMAPI int SDMCALL sdmDisconnect(void *h) { SDMAPI int SDMCALL sdmGetConnectionStatus(void *h) { try { - return static_cast(h)->getConnectionStatus(); + return static_cast(h)->getConnectionStatus(); } catch(std::exception &ex) { displayErrorMessage(ex.what()); @@ -171,7 +171,7 @@ SDMAPI int SDMCALL sdmGetConnectionStatus(void *h) { SDMAPI void * SDMCALL sdmOpenChannel(void *hdev,int id) { try { - return static_cast(hdev)->openChannel(id); + return static_cast(hdev)->openChannel(id); } catch(std::exception &ex) { displayErrorMessage(ex.what()); @@ -181,7 +181,7 @@ SDMAPI void * SDMCALL sdmOpenChannel(void *hdev,int id) { SDMAPI int SDMCALL sdmCloseChannel(void *h) { try { - return static_cast(h)->close(); + return static_cast(h)->close(); } catch(std::exception &ex) { displayErrorMessage(ex.what()); @@ -191,7 +191,7 @@ SDMAPI int SDMCALL sdmCloseChannel(void *h) { SDMAPI int SDMCALL sdmGetChannelProperty(void *h,const char *name,char *buf,std::size_t n) { try { - return getProperty(static_cast(h),name,buf,n); + return getProperty(static_cast(h),name,buf,n); } catch(std::exception &ex) { displayErrorMessage(ex.what()); @@ -201,7 +201,7 @@ SDMAPI int SDMCALL sdmGetChannelProperty(void *h,const char *name,char *buf,std: SDMAPI int SDMCALL sdmSetChannelProperty(void *h,const char *name,const char *value) { try { - return setProperty(static_cast(h),name,value); + return setProperty(static_cast(h),name,value); } catch(std::exception &ex) { displayErrorMessage(ex.what()); @@ -211,7 +211,7 @@ SDMAPI int SDMCALL sdmSetChannelProperty(void *h,const char *name,const char *va SDMAPI int SDMCALL sdmWriteReg(void *h,sdm_addr_t addr,sdm_reg_t data) { try { - return static_cast(h)->writeReg(addr,data); + return static_cast(h)->writeReg(addr,data); } catch(std::exception &ex) { displayErrorMessage(ex.what()); @@ -221,18 +221,19 @@ SDMAPI int SDMCALL sdmWriteReg(void *h,sdm_addr_t addr,sdm_reg_t data) { SDMAPI sdm_reg_t SDMCALL sdmReadReg(void *h,sdm_addr_t addr,int *status) { try { - return static_cast(h)->readReg(addr,status); + if(status) *status=0; + return static_cast(h)->readReg(addr,status); } catch(std::exception &ex) { displayErrorMessage(ex.what()); - if(status) *status=-1; + if(status&&*status==0) *status=-1; return 0; } } SDMAPI int SDMCALL sdmWriteFIFO(void *h,sdm_addr_t addr,const sdm_reg_t *data,std::size_t n,int flags) { try { - return static_cast(h)->writeFIFO(addr,data,n,flags); + return static_cast(h)->writeFIFO(addr,data,n,flags); } catch(std::exception &ex) { displayErrorMessage(ex.what()); @@ -242,7 +243,7 @@ SDMAPI int SDMCALL sdmWriteFIFO(void *h,sdm_addr_t addr,const sdm_reg_t *data,st SDMAPI int SDMCALL sdmReadFIFO(void *h,sdm_addr_t addr,sdm_reg_t *data,std::size_t n,int flags) { try { - return static_cast(h)->readFIFO(addr,data,n,flags); + return static_cast(h)->readFIFO(addr,data,n,flags); } catch(std::exception &ex) { displayErrorMessage(ex.what()); @@ -252,7 +253,7 @@ SDMAPI int SDMCALL sdmReadFIFO(void *h,sdm_addr_t addr,sdm_reg_t *data,std::size SDMAPI int SDMCALL sdmWriteMem(void *h,sdm_addr_t addr,const sdm_reg_t *data,std::size_t n) { try { - return static_cast(h)->writeMem(addr,data,n); + return static_cast(h)->writeMem(addr,data,n); } catch(std::exception &ex) { displayErrorMessage(ex.what()); @@ -262,7 +263,7 @@ SDMAPI int SDMCALL sdmWriteMem(void *h,sdm_addr_t addr,const sdm_reg_t *data,std SDMAPI int SDMCALL sdmReadMem(void *h,sdm_addr_t addr,sdm_reg_t *data,std::size_t n) { try { - return static_cast(h)->readMem(addr,data,n); + return static_cast(h)->readMem(addr,data,n); } catch(std::exception &ex) { displayErrorMessage(ex.what()); @@ -276,7 +277,7 @@ SDMAPI int SDMCALL sdmReadMem(void *h,sdm_addr_t addr,sdm_reg_t *data,std::size_ SDMAPI void * SDMCALL sdmOpenSource(void *hdev,int id) { try { - return static_cast(hdev)->openSource(id); + return static_cast(hdev)->openSource(id); } catch(std::exception &ex) { displayErrorMessage(ex.what()); @@ -286,7 +287,7 @@ SDMAPI void * SDMCALL sdmOpenSource(void *hdev,int id) { SDMAPI int SDMCALL sdmCloseSource(void *h) { try { - return static_cast(h)->close(); + return static_cast(h)->close(); } catch(std::exception &ex) { displayErrorMessage(ex.what()); @@ -296,7 +297,7 @@ SDMAPI int SDMCALL sdmCloseSource(void *h) { SDMAPI int SDMCALL sdmGetSourceProperty(void *h,const char *name,char *buf,std::size_t n) { try { - return getProperty(static_cast(h),name,buf,n); + return getProperty(static_cast(h),name,buf,n); } catch(std::exception &ex) { displayErrorMessage(ex.what()); @@ -306,7 +307,7 @@ SDMAPI int SDMCALL sdmGetSourceProperty(void *h,const char *name,char *buf,std:: SDMAPI int SDMCALL sdmSetSourceProperty(void *h,const char *name,const char *value) { try { - return setProperty(static_cast(h),name,value); + return setProperty(static_cast(h),name,value); } catch(std::exception &ex) { displayErrorMessage(ex.what()); @@ -316,7 +317,7 @@ SDMAPI int SDMCALL sdmSetSourceProperty(void *h,const char *name,const char *val SDMAPI int SDMCALL sdmSelectReadStreams(void *h,const int *streams,std::size_t n,std::size_t packets,int df) { try { - return static_cast(h)->selectReadStreams(streams,n,packets,df); + return static_cast(h)->selectReadStreams(streams,n,packets,df); } catch(std::exception &ex) { displayErrorMessage(ex.what()); @@ -326,7 +327,7 @@ SDMAPI int SDMCALL sdmSelectReadStreams(void *h,const int *streams,std::size_t n SDMAPI int SDMCALL sdmReadStream(void *h,int stream,sdm_sample_t *data,std::size_t n,int nb) { try { - return static_cast(h)->readStream(stream,data,n,nb); + return static_cast(h)->readStream(stream,data,n,nb); } catch(std::exception &ex) { displayErrorMessage(ex.what()); @@ -336,7 +337,7 @@ SDMAPI int SDMCALL sdmReadStream(void *h,int stream,sdm_sample_t *data,std::size SDMAPI int SDMCALL sdmReadNextPacket(void *h) { try { - return static_cast(h)->readNextPacket(); + return static_cast(h)->readNextPacket(); } catch(std::exception &ex) { displayErrorMessage(ex.what()); @@ -346,7 +347,7 @@ SDMAPI int SDMCALL sdmReadNextPacket(void *h) { SDMAPI void SDMCALL sdmDiscardPackets(void *h) { try { - static_cast(h)->discardPackets(); + static_cast(h)->discardPackets(); } catch(std::exception &ex) { displayErrorMessage(ex.what()); @@ -355,7 +356,7 @@ SDMAPI void SDMCALL sdmDiscardPackets(void *h) { SDMAPI int SDMCALL sdmReadStreamErrors(void *h) { try { - return static_cast(h)->readStreamErrors(); + return static_cast(h)->readStreamErrors(); } catch(std::exception &ex) { displayErrorMessage(ex.what()); diff --git a/src/sdk/lib/pluginprovider/src/sdmprovider.cpp b/src/sdk/lib/pluginprovider/src/sdmprovider.cpp index 918c085..c50e0e1 100644 --- a/src/sdk/lib/pluginprovider/src/sdmprovider.cpp +++ b/src/sdk/lib/pluginprovider/src/sdmprovider.cpp @@ -30,38 +30,10 @@ #include /* - * SDMAbstractPluginProvider members - */ - -SDMAbstractPluginProvider::SDMAbstractPluginProvider() {} - -SDMAbstractPluginProvider::~SDMAbstractPluginProvider() {} - -/* - * SDMAbstractDeviceProvider members - */ - -SDMAbstractDeviceProvider::SDMAbstractDeviceProvider() {} - -SDMAbstractDeviceProvider::~SDMAbstractDeviceProvider() {} - -SDMAbstractChannelProvider *SDMAbstractDeviceProvider::openChannel(int) { - return NULL; -} - -SDMAbstractSourceProvider *SDMAbstractDeviceProvider::openSource(int) { - return NULL; -} - -/* - * SDMAbstractChannelProvider members + * SDMAbstractChannel members */ -SDMAbstractChannelProvider::SDMAbstractChannelProvider() {} - -SDMAbstractChannelProvider::~SDMAbstractChannelProvider() {} - -int SDMAbstractChannelProvider::writeFIFO(sdm_addr_t addr,const sdm_reg_t *data,std::size_t n,int) { +int SDMAbstractChannel::writeFIFO(sdm_addr_t addr,const sdm_reg_t *data,std::size_t n,int) { if(n>INT_MAX) n=INT_MAX; for(std::size_t i=0;i(n); } -int SDMAbstractChannelProvider::readFIFO(sdm_addr_t addr,sdm_reg_t *data,std::size_t n,int) { +int SDMAbstractChannel::readFIFO(sdm_addr_t addr,sdm_reg_t *data,std::size_t n,int) { if(n>INT_MAX) n=INT_MAX; for(std::size_t i=0;i(n); } -int SDMAbstractChannelProvider::writeMem(sdm_addr_t addr,const sdm_reg_t *data,std::size_t n) { +int SDMAbstractChannel::writeMem(sdm_addr_t addr,const sdm_reg_t *data,std::size_t n) { for(std::size_t i=0;i::iterator it=_pos.find(stream); + if(it==_pos.end()) return SDM_ERROR; + std::size_t ¤tPos=it->second; + +// Process data from the queue + bool eop=false; + std::size_t loaded=getSamplesFromQueue(stream,currentPos,data,n,eop); + if(isError()) _errors++; + currentPos+=loaded; + + for(;;) { +// Read new data from the device + std::size_t suggestToRead=n-loaded; + bool nonBlocking=false; + if(nb!=0) nonBlocking=true; // don't block if non-blocking read is requested + if(loaded>0) nonBlocking=true; // don't block if we have already produced some data + if(eop) nonBlocking=true; // don't block if the packet has been already finished + addDataToQueue(suggestToRead,nonBlocking); +// Put new samples to the buffer + if(loaded0) break; + if(eop) break; + } + + if(nb!=0&&loaded==0&&!eop) return SDM_WOULDBLOCK; + return static_cast(loaded); +} -int SDMAbstractSourceProvider::readStreamErrors() { +int SDMAbstractQueuedSource::readNextPacket() { + next(); + for(std::map::iterator it=_pos.begin();it!=_pos.end();++it) it->second=0; return 0; } + +void SDMAbstractQueuedSource::discardPackets() { + clear(); + for(std::map::iterator it=_pos.begin();it!=_pos.end();++it) it->second=0; + _errors=0; +} + +int SDMAbstractQueuedSource::readStreamErrors() { + return _errors; +} diff --git a/src/sdmplug/CMakeLists.txt b/src/sdmplug/CMakeLists.txt index c2a5fe9..1a08480 100644 --- a/src/sdmplug/CMakeLists.txt +++ b/src/sdmplug/CMakeLists.txt @@ -4,7 +4,7 @@ add_library(sdmplug STATIC src/sdmplugbase.cpp src/sdmplugin.cpp src/sdmdevice.c target_include_directories(sdmplug PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) -target_link_libraries(sdmplug config utils u8e api) +target_link_libraries(sdmplug utils api) if(CMAKE_SYSTEM_NAME STREQUAL "Linux") target_link_libraries(sdmplug dl) diff --git a/src/sdmplug/include/sdmplug.h b/src/sdmplug/include/sdmplug.h index cc5d0d5..b64dafb 100644 --- a/src/sdmplug/include/sdmplug.h +++ b/src/sdmplug/include/sdmplug.h @@ -199,8 +199,8 @@ class SDMChannel : virtual public SDMBase { virtual void writeReg(sdm_addr_t addr,sdm_reg_t data); virtual sdm_reg_t readReg(sdm_addr_t addr); - virtual int writeFIFO(sdm_addr_t addr,const sdm_reg_t *data,std::size_t n,Flags flags); - virtual int readFIFO(sdm_addr_t addr,sdm_reg_t *data,std::size_t n,Flags flags); + virtual int writeFIFO(sdm_addr_t addr,const sdm_reg_t *data,std::size_t n,Flags flags=Normal); + virtual int readFIFO(sdm_addr_t addr,sdm_reg_t *data,std::size_t n,Flags flags=Normal); virtual void writeMem(sdm_addr_t addr,const sdm_reg_t *data,std::size_t n); virtual void readMem(sdm_addr_t addr,sdm_reg_t *data,std::size_t n); @@ -242,7 +242,7 @@ class SDMSource : virtual public SDMBase { virtual void close(); virtual void selectReadStreams(const std::vector &streams,std::size_t packets,int df); - virtual int readStream(int stream,sdm_sample_t *data,std::size_t n,Flags flags); + virtual int readStream(int stream,sdm_sample_t *data,std::size_t n,Flags flags=Normal); virtual void readNextPacket(); virtual void discardPackets(); virtual int readStreamErrors(); diff --git a/src/sdmplug/src/sdmplugin.cpp b/src/sdmplug/src/sdmplugin.cpp index 48e2ae6..59f5d8e 100644 --- a/src/sdmplug/src/sdmplugin.cpp +++ b/src/sdmplug/src/sdmplugin.cpp @@ -20,8 +20,7 @@ */ #include "sdmplug.h" -#include "sdmconfig.h" -#include "stringutils.h" +#include "dirutil.h" #include "loadablemodule.h" #include @@ -158,10 +157,6 @@ void SDMPlugin::open(const std::string &strFileName) { else { _impl=std::make_shared(strFileName); } - - auto requiredVersion=getProperty("MinimumSDMVersion",""); - if(StringUtils::compareVersions(Config::version(),requiredVersion)<0) - throw std::runtime_error("The plugin requires SDM "+requiredVersion+" or later"); } void SDMPlugin::close() {