Polish redbean serialization

This commit is contained in:
Justine Tunney 2022-04-29 06:06:23 -07:00
parent 7aafa64ab3
commit 2d1731b995
24 changed files with 828 additions and 158 deletions

View file

@ -464,6 +464,7 @@ int main(int argc, char *argv[]) {
/* __log_level = kLogDebug; */
GetOpts(argc, argv);
for (i = 3; i < 16; ++i) close(i);
errno = 0;
// poll()'ing /dev/null stdin file descriptor on xnu returns POLLNVAL?!
if (IsWindows()) {
CHECK_EQ(3, (g_bogusfd = open("/dev/null", O_RDONLY | O_CLOEXEC)));

View file

@ -357,6 +357,10 @@ LUA ENHANCEMENTS
`0644 == 420` is the case in redbean, whereas in upstream Lua
`0644 == 644` would be the case.
- redbean supports binary (base 2) integer literals. For example
`0b1010 == 10` is the case in redbean, whereas in upstream Lua
`0b1010` would result in an error.
- redbean supports the GNU syntax for the ASCII ESC character in
string literals. For example, `"\e"` is the same as `"\x1b"`.
@ -1284,6 +1288,31 @@ FUNCTIONS
possibly because your system is under load and the benchmark was
preempted by the operating system, or moved to a different core.
oct(int)
└─→ str
Formats string as octal integer literal string. If the provided
value is zero, the result will be `"0"`. Otherwise the resulting
value will be the zero-prefixed octal string. The result is
currently modulo 2^64. Negative numbers are converted to unsigned.
hex(int)
└─→ str
Formats string as hexadecimal integer literal string. If the
provided value is zero, the result will be `"0"`. Otherwise the
resulting value will be the `"0x"`-prefixed hex string. The result
is currently modulo 2^64. Negative numbers are converted to
unsigned.
bin(int)
└─→ str
Formats string as binary integer literal string. If the provided
value is zero, the result will be `"0"`. Otherwise the resulting
value will be the `"0b"`-prefixed binary str. The result is
currently modulo 2^64. Negative numbers are converted to unsigned.
────────────────────────────────────────────────────────────────────────────────
@ -1745,6 +1774,27 @@ UNIX MODULE
end
end
unix.WIFEXITED(wstatus:int)
└─→ bool
Returns true if process exited cleanly.
unix.WEXITSTATUS(wstatus:int)
└─→ exitcode:uint8
Returns code passed to exit() assuming `WIFEXITED(wstatus)` is true.
unix.WIFSIGNALED(wstatus:int)
└─→ bool
Returns true if process terminated due to a signal.
unix.WTERMSIG(wstatus:int)
└─→ sig:uint8
Returns signal that caused process to terminate assuming
`WIFSIGNALED(wstatus)` is true.
unix.getpid()
└─→ pid:int

View file

@ -20,6 +20,7 @@
#include "libc/bits/popcnt.h"
#include "libc/calls/calls.h"
#include "libc/calls/struct/rusage.h"
#include "libc/fmt/itoa.h"
#include "libc/intrin/kprintf.h"
#include "libc/log/check.h"
#include "libc/log/log.h"
@ -60,6 +61,33 @@ static int Rdpid(void) {
return rdpid();
}
int LuaHex(lua_State *L) {
char b[19];
uint64_t x;
x = luaL_checkinteger(L, 1);
FormatHex64(b, x, true);
lua_pushstring(L, b);
return 1;
}
int LuaOct(lua_State *L) {
char b[24];
uint64_t x;
x = luaL_checkinteger(L, 1);
FormatOctal64(b, x, true);
lua_pushstring(L, b);
return 1;
}
int LuaBin(lua_State *L) {
char b[67];
uint64_t x;
x = luaL_checkinteger(L, 1);
FormatBinary64(b, x, 2);
lua_pushstring(L, b);
return 1;
}
int LuaGetTime(lua_State *L) {
lua_pushnumber(L, nowl());
return 1;
@ -258,7 +286,7 @@ int LuaPopcnt(lua_State *L) {
int LuaBsr(lua_State *L) {
long x;
if ((x = luaL_checkinteger(L, 1))) {
lua_pushinteger(L, bsr(x));
lua_pushinteger(L, bsrl(x));
return 1;
} else {
luaL_argerror(L, 1, "zero");
@ -269,7 +297,7 @@ int LuaBsr(lua_State *L) {
int LuaBsf(lua_State *L) {
long x;
if ((x = luaL_checkinteger(L, 1))) {
lua_pushinteger(L, bsf(x));
lua_pushinteger(L, bsfl(x));
return 1;
} else {
luaL_argerror(L, 1, "zero");

View file

@ -12,6 +12,7 @@ int luaopen_argon2(lua_State *);
int luaopen_lsqlite3(lua_State *);
int LuaBenchmark(lua_State *);
int LuaBin(lua_State *);
int LuaBsf(lua_State *);
int LuaBsr(lua_State *);
int LuaCategorizeIp(lua_State *);
@ -45,6 +46,7 @@ int LuaGetMonospaceWidth(lua_State *);
int LuaGetRandomBytes(lua_State *);
int LuaGetTime(lua_State *);
int LuaHasControlCodes(lua_State *);
int LuaHex(lua_State *);
int LuaIndentLines(lua_State *);
int LuaIsAcceptableHost(lua_State *);
int LuaIsAcceptablePath(lua_State *);
@ -58,6 +60,7 @@ int LuaIsValidHttpToken(lua_State *);
int LuaLemur64(lua_State *);
int LuaMd5(lua_State *);
int LuaMeasureEntropy(lua_State *);
int LuaOct(lua_State *);
int LuaParseHost(lua_State *);
int LuaParseHttpDateTime(lua_State *);
int LuaParseIp(lua_State *);

View file

@ -192,6 +192,22 @@ STATIC_YOINK("zip_uri_support");
#define HeaderEqualCase(H, S) \
SlicesEqualCase(S, strlen(S), HeaderData(H), HeaderLength(H))
#define TRACE_BEGIN \
do { \
if (!IsTiny()) { \
if (funtrace) ++g_ftrace; \
if (systrace) ++__strace; \
} \
} while (0)
#define TRACE_END \
do { \
if (!IsTiny()) { \
if (funtrace) --g_ftrace; \
if (systrace) --__strace; \
} \
} while (0)
// letters not used: EIJNOQWXYnoqwxy
// digits not used: 0123456789
// puncts not used: !"#$%&'()*+,-./;<=>@[\]^_`{|}~
@ -5066,6 +5082,9 @@ static const luaL_Reg kLuaFuncs[] = {
{"Underlong", LuaUnderlong}, //
{"VisualizeControlCodes", LuaVisualizeControlCodes}, //
{"Write", LuaWrite}, //
{"bin", LuaBin}, //
{"hex", LuaHex}, //
{"oct", LuaOct}, //
#ifndef UNSECURE
{"Fetch", LuaFetch}, //
{"EvadeDragnetSurveillance", LuaEvadeDragnetSurveillance}, //
@ -5196,7 +5215,6 @@ static void LuaPrint(lua_State *L) {
static void LuaInterpreter(lua_State *L) {
int i, n, sig, status;
const char *script;
if (funtrace) ftrace_install();
if (optind < __argc) {
script = __argv[optind];
if (!strcmp(script, "-")) script = 0;
@ -5206,11 +5224,9 @@ static void LuaInterpreter(lua_State *L) {
luaL_checkstack(L, n + 3, "too many script args");
for (i = 1; i <= n; i++) lua_rawgeti(L, -i, i);
lua_remove(L, -i); // remove arg table from stack
if (funtrace) ++g_ftrace;
if (systrace) ++__strace;
TRACE_BEGIN;
status = lua_runchunk(L, n, LUA_MULTRET);
if (systrace) --__strace;
if (funtrace) --g_ftrace;
TRACE_END;
}
lua_report(L, status);
} else {
@ -5233,9 +5249,9 @@ static void LuaInterpreter(lua_State *L) {
exit(1);
}
if (status == LUA_OK) {
if (funtrace) ++g_ftrace;
TRACE_BEGIN;
status = lua_runchunk(GL, 0, LUA_MULTRET);
if (funtrace) --g_ftrace;
TRACE_END;
}
if (status == LUA_OK) {
LuaPrint(GL);
@ -6365,19 +6381,10 @@ static int HandleConnection(size_t i) {
meltdown = false;
__isworker = true;
connectionclose = false;
if (!IsTiny()) {
if (systrace) {
__strace = 1;
__kbirth = rdtsc();
}
if (funtrace) {
if (ftrace_install() != -1) {
g_ftrace = 1;
} else {
WARNF("ftrace failed to install %m");
}
}
if (!IsTiny() && systrace) {
__kbirth = rdtsc();
}
TRACE_BEGIN;
if (sandboxed) {
CHECK_NE(-1, EnableSandbox());
}
@ -6850,7 +6857,6 @@ static void GetOpts(int argc, char *argv[]) {
CASE('S', ++sandboxed);
CASE('v', ++__log_level);
CASE('s', --__log_level);
CASE('f', funtrace = true);
CASE('Z', systrace = true);
CASE('b', logbodies = true);
CASE('z', printport = true);
@ -6889,6 +6895,12 @@ static void GetOpts(int argc, char *argv[]) {
CASE('C', ProgramFile(optarg, ProgramCertificate));
CASE('K', ProgramFile(optarg, ProgramPrivateKey));
#endif
case 'f':
funtrace = true;
if (ftrace_install() == -1) {
WARNF("ftrace failed to install %m");
}
break;
default:
PrintUsage(2, EX_USAGE);
}