cosmopolitan/third_party/lua/luac.main.c

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

747 lines
18 KiB
C
Raw Normal View History

/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Lua
Bring Lua to 5.4.6. (#1214) This essentially re-does the work of #875 on top of master. This is what I did to check that Cosmo's Lua extensions still worked: ``` $ build/bootstrap/make MODE=aarch64 o/aarch64/third_party/lua/lua $ ape o/aarch64/third_party/lua/lua >: 10 10 >: 010 8 >: 0b10 2 >: string.byte("\e") 27 >: "Hello, %s" % {"world"} Hello, world >: "*" * 3 *** ``` `luaL_traceback2` was used to show the stack trace with parameter values; it's used in `LuaCallWithTrace`, which is used in Redbean to run Lua code. You should be able to see the extended stack trace by running something like this: `redbean -e "function a(b)c()end a(2)"` (with "params" indicating the extended stack trace): ``` stack traceback: [string "function a(b)c()end a(2)"]:1: in function 'a', params: b = 2; [string "function a(b)c()end a(2)"]:1: in main chunk ``` @pkulchenko confirmed that I get the expected result with the updated code. This is what I did to check that Lua itself still worked: ``` $ cd third_party/lua/test/ $ ape ../../../o/aarch64/third_party/lua/lua all.lua ``` There's one test failure, in `files.lua`: ``` ***** FILE 'files.lua'***** testing i/o ../../../o/aarch64/third_party/lua/lua: files.lua:84: assertion failed! stack traceback: [C]: in function 'assert' files.lua:84: in main chunk (...tail calls...) all.lua:195: in main chunk [C]: in ? .>>> closing state <<< ``` That isn't a result of these changes; the same test is failing in master. The failure is here: ```lua if not _port then -- invalid seek local status, msg, code = io.stdin:seek("set", 1000) assert(not status and type(msg) == "string" and type(code) == "number") end ``` The test expects a seek to offset 1,000 on stdin to fail — but it doesn't. `status` ends up being the new offset rather than `nil`. If I comment out that one test, the remaining tests succeed.
2024-06-16 00:13:08 +00:00
Copyright © 2004-2023 Lua.org, PUC-Rio.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#define luac_c
#define LUA_CORE
Bring Lua to 5.4.6. (#1214) This essentially re-does the work of #875 on top of master. This is what I did to check that Cosmo's Lua extensions still worked: ``` $ build/bootstrap/make MODE=aarch64 o/aarch64/third_party/lua/lua $ ape o/aarch64/third_party/lua/lua >: 10 10 >: 010 8 >: 0b10 2 >: string.byte("\e") 27 >: "Hello, %s" % {"world"} Hello, world >: "*" * 3 *** ``` `luaL_traceback2` was used to show the stack trace with parameter values; it's used in `LuaCallWithTrace`, which is used in Redbean to run Lua code. You should be able to see the extended stack trace by running something like this: `redbean -e "function a(b)c()end a(2)"` (with "params" indicating the extended stack trace): ``` stack traceback: [string "function a(b)c()end a(2)"]:1: in function 'a', params: b = 2; [string "function a(b)c()end a(2)"]:1: in main chunk ``` @pkulchenko confirmed that I get the expected result with the updated code. This is what I did to check that Lua itself still worked: ``` $ cd third_party/lua/test/ $ ape ../../../o/aarch64/third_party/lua/lua all.lua ``` There's one test failure, in `files.lua`: ``` ***** FILE 'files.lua'***** testing i/o ../../../o/aarch64/third_party/lua/lua: files.lua:84: assertion failed! stack traceback: [C]: in function 'assert' files.lua:84: in main chunk (...tail calls...) all.lua:195: in main chunk [C]: in ? .>>> closing state <<< ``` That isn't a result of these changes; the same test is failing in master. The failure is here: ```lua if not _port then -- invalid seek local status, msg, code = io.stdin:seek("set", 1000) assert(not status and type(msg) == "string" and type(code) == "number") end ``` The test expects a seek to offset 1,000 on stdin to fail — but it doesn't. `status` ends up being the new offset rather than `nil`. If I comment out that one test, the remaining tests succeed.
2024-06-16 00:13:08 +00:00
#include "libc/calls/calls.h"
#include "libc/calls/struct/sigaction.h"
#include "libc/errno.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/exit.h"
#include "third_party/lua/lauxlib.h"
#include "third_party/lua/ldebug.h"
#include "third_party/lua/lobject.h"
#include "third_party/lua/lopcodes.h"
#include "third_party/lua/lopnames.inc"
#include "third_party/lua/lprefix.h"
#include "third_party/lua/lstate.h"
#include "third_party/lua/lua.h"
#include "third_party/lua/lualib.h"
2024-07-21 22:54:17 +00:00
#include "libc/ctype.h"
#include "third_party/lua/lundump.h"
Release Cosmopolitan v3.3 This change upgrades to GCC 12.3 and GNU binutils 2.42. The GNU linker appears to have changed things so that only a single de-duplicated str table is present in the binary, and it gets placed wherever the linker wants, regardless of what the linker script says. To cope with that we need to stop using .ident to embed licenses. As such, this change does significant work to revamp how third party licenses are defined in the codebase, using `.section .notice,"aR",@progbits`. This new GCC 12.3 toolchain has support for GNU indirect functions. It lets us support __target_clones__ for the first time. This is used for optimizing the performance of libc string functions such as strlen and friends so far on x86, by ensuring AVX systems favor a second codepath that uses VEX encoding. It shaves some latency off certain operations. It's a useful feature to have for scientific computing for the reasons explained by the test/libcxx/openmp_test.cc example which compiles for fifteen different microarchitectures. Thanks to the upgrades, it's now also possible to use newer instruction sets, such as AVX512FP16, VNNI. Cosmo now uses the %gs register on x86 by default for TLS. Doing it is helpful for any program that links `cosmo_dlopen()`. Such programs had to recompile their binaries at startup to change the TLS instructions. That's not great, since it means every page in the executable needs to be faulted. The work of rewriting TLS-related x86 opcodes, is moved to fixupobj.com instead. This is great news for MacOS x86 users, since we previously needed to morph the binary every time for that platform but now that's no longer necessary. The only platforms where we need fixup of TLS x86 opcodes at runtime are now Windows, OpenBSD, and NetBSD. On Windows we morph TLS to point deeper into the TIB, based on a TlsAlloc assignment, and on OpenBSD/NetBSD we morph %gs back into %fs since the kernels do not allow us to specify a value for the %gs register. OpenBSD users are now required to use APE Loader to run Cosmo binaries and assimilation is no longer possible. OpenBSD kernel needs to change to allow programs to specify a value for the %gs register, or it needs to stop marking executable pages loaded by the kernel as mimmutable(). This release fixes __constructor__, .ctor, .init_array, and lastly the .preinit_array so they behave the exact same way as glibc. We no longer use hex constants to define math.h symbols like M_PI.
2024-02-20 19:12:09 +00:00
__static_yoink("lua_notice");
Bring Lua to 5.4.6. (#1214) This essentially re-does the work of #875 on top of master. This is what I did to check that Cosmo's Lua extensions still worked: ``` $ build/bootstrap/make MODE=aarch64 o/aarch64/third_party/lua/lua $ ape o/aarch64/third_party/lua/lua >: 10 10 >: 010 8 >: 0b10 2 >: string.byte("\e") 27 >: "Hello, %s" % {"world"} Hello, world >: "*" * 3 *** ``` `luaL_traceback2` was used to show the stack trace with parameter values; it's used in `LuaCallWithTrace`, which is used in Redbean to run Lua code. You should be able to see the extended stack trace by running something like this: `redbean -e "function a(b)c()end a(2)"` (with "params" indicating the extended stack trace): ``` stack traceback: [string "function a(b)c()end a(2)"]:1: in function 'a', params: b = 2; [string "function a(b)c()end a(2)"]:1: in main chunk ``` @pkulchenko confirmed that I get the expected result with the updated code. This is what I did to check that Lua itself still worked: ``` $ cd third_party/lua/test/ $ ape ../../../o/aarch64/third_party/lua/lua all.lua ``` There's one test failure, in `files.lua`: ``` ***** FILE 'files.lua'***** testing i/o ../../../o/aarch64/third_party/lua/lua: files.lua:84: assertion failed! stack traceback: [C]: in function 'assert' files.lua:84: in main chunk (...tail calls...) all.lua:195: in main chunk [C]: in ? .>>> closing state <<< ``` That isn't a result of these changes; the same test is failing in master. The failure is here: ```lua if not _port then -- invalid seek local status, msg, code = io.stdin:seek("set", 1000) assert(not status and type(msg) == "string" and type(code) == "number") end ``` The test expects a seek to offset 1,000 on stdin to fail — but it doesn't. `status` ends up being the new offset rather than `nil`. If I comment out that one test, the remaining tests succeed.
2024-06-16 00:13:08 +00:00
static void PrintFunction(const Proto* f, int full);
#define luaU_print PrintFunction
#define PROGNAME "luac" /* default program name */
#define OUTPUT PROGNAME ".out" /* default output file */
static int listing=0; /* list bytecodes? */
static int dumping=1; /* dump bytecodes? */
static int stripping=0; /* strip debug information? */
static char Output[]={ OUTPUT }; /* default output file name */
static const char* output=Output; /* actual output file name */
static const char* progname=PROGNAME; /* actual program name */
static TString **tmname;
static void fatal(const char* message)
{
fprintf(stderr,"%s: %s\n",progname,message);
exit(EXIT_FAILURE);
}
static void cannot(const char* what)
{
fprintf(stderr,"%s: cannot %s %s: %s\n",progname,what,output,strerror(errno));
exit(EXIT_FAILURE);
}
static void usage(const char* message)
{
if (*message=='-')
fprintf(stderr,"%s: unrecognized option '%s'\n",progname,message);
else
fprintf(stderr,"%s: %s\n",progname,message);
fprintf(stderr,
"usage: %s [options] [filenames]\n"
"Available options are:\n"
" -l list (use -l -l for full listing)\n"
" -o name output to file 'name' (default is \"%s\")\n"
" -p parse only\n"
" -s strip debug information\n"
" -v show version information\n"
" -- stop handling options\n"
" - stop handling options and process stdin\n"
,progname,Output);
exit(EXIT_FAILURE);
}
#define IS(s) (strcmp(argv[i],s)==0)
static int doargs(int argc, char* argv[])
{
int i;
int version=0;
if (argv[0]!=NULL && *argv[0]!=0) progname=argv[0];
for (i=1; i<argc; i++)
{
if (*argv[i]!='-') /* end of options; keep it */
break;
else if (IS("--")) /* end of options; skip it */
{
++i;
if (version) ++version;
break;
}
else if (IS("-")) /* end of options; use stdin */
break;
else if (IS("-l")) /* list */
++listing;
else if (IS("-o")) /* output file */
{
output=argv[++i];
if (output==NULL || *output==0 || (*output=='-' && output[1]!=0))
usage("'-o' needs argument");
if (IS("-")) output=NULL;
}
else if (IS("-p")) /* parse only */
dumping=0;
else if (IS("-s")) /* strip debug information */
stripping=1;
else if (IS("-v")) /* show version */
++version;
else /* unknown option */
usage(argv[i]);
}
if (i==argc && (listing || !dumping))
{
dumping=0;
argv[--i]=Output;
}
if (version)
{
printf("%s\n",LUA_COPYRIGHT);
if (version==argc-1) exit(EXIT_SUCCESS);
}
return i;
}
Bring Lua to 5.4.6. (#1214) This essentially re-does the work of #875 on top of master. This is what I did to check that Cosmo's Lua extensions still worked: ``` $ build/bootstrap/make MODE=aarch64 o/aarch64/third_party/lua/lua $ ape o/aarch64/third_party/lua/lua >: 10 10 >: 010 8 >: 0b10 2 >: string.byte("\e") 27 >: "Hello, %s" % {"world"} Hello, world >: "*" * 3 *** ``` `luaL_traceback2` was used to show the stack trace with parameter values; it's used in `LuaCallWithTrace`, which is used in Redbean to run Lua code. You should be able to see the extended stack trace by running something like this: `redbean -e "function a(b)c()end a(2)"` (with "params" indicating the extended stack trace): ``` stack traceback: [string "function a(b)c()end a(2)"]:1: in function 'a', params: b = 2; [string "function a(b)c()end a(2)"]:1: in main chunk ``` @pkulchenko confirmed that I get the expected result with the updated code. This is what I did to check that Lua itself still worked: ``` $ cd third_party/lua/test/ $ ape ../../../o/aarch64/third_party/lua/lua all.lua ``` There's one test failure, in `files.lua`: ``` ***** FILE 'files.lua'***** testing i/o ../../../o/aarch64/third_party/lua/lua: files.lua:84: assertion failed! stack traceback: [C]: in function 'assert' files.lua:84: in main chunk (...tail calls...) all.lua:195: in main chunk [C]: in ? .>>> closing state <<< ``` That isn't a result of these changes; the same test is failing in master. The failure is here: ```lua if not _port then -- invalid seek local status, msg, code = io.stdin:seek("set", 1000) assert(not status and type(msg) == "string" and type(code) == "number") end ``` The test expects a seek to offset 1,000 on stdin to fail — but it doesn't. `status` ends up being the new offset rather than `nil`. If I comment out that one test, the remaining tests succeed.
2024-06-16 00:13:08 +00:00
#define FUNCTION "(function()end)();\n"
static const char* reader(lua_State* L, void* ud, size_t* size)
{
UNUSED(L);
if ((*(int*)ud)--)
{
*size=sizeof(FUNCTION)-1;
return FUNCTION;
}
else
{
*size=0;
return NULL;
}
}
Bring Lua to 5.4.6. (#1214) This essentially re-does the work of #875 on top of master. This is what I did to check that Cosmo's Lua extensions still worked: ``` $ build/bootstrap/make MODE=aarch64 o/aarch64/third_party/lua/lua $ ape o/aarch64/third_party/lua/lua >: 10 10 >: 010 8 >: 0b10 2 >: string.byte("\e") 27 >: "Hello, %s" % {"world"} Hello, world >: "*" * 3 *** ``` `luaL_traceback2` was used to show the stack trace with parameter values; it's used in `LuaCallWithTrace`, which is used in Redbean to run Lua code. You should be able to see the extended stack trace by running something like this: `redbean -e "function a(b)c()end a(2)"` (with "params" indicating the extended stack trace): ``` stack traceback: [string "function a(b)c()end a(2)"]:1: in function 'a', params: b = 2; [string "function a(b)c()end a(2)"]:1: in main chunk ``` @pkulchenko confirmed that I get the expected result with the updated code. This is what I did to check that Lua itself still worked: ``` $ cd third_party/lua/test/ $ ape ../../../o/aarch64/third_party/lua/lua all.lua ``` There's one test failure, in `files.lua`: ``` ***** FILE 'files.lua'***** testing i/o ../../../o/aarch64/third_party/lua/lua: files.lua:84: assertion failed! stack traceback: [C]: in function 'assert' files.lua:84: in main chunk (...tail calls...) all.lua:195: in main chunk [C]: in ? .>>> closing state <<< ``` That isn't a result of these changes; the same test is failing in master. The failure is here: ```lua if not _port then -- invalid seek local status, msg, code = io.stdin:seek("set", 1000) assert(not status and type(msg) == "string" and type(code) == "number") end ``` The test expects a seek to offset 1,000 on stdin to fail — but it doesn't. `status` ends up being the new offset rather than `nil`. If I comment out that one test, the remaining tests succeed.
2024-06-16 00:13:08 +00:00
#define toproto(L,i) getproto(s2v(L->top.p+(i)))
static const Proto* combine(lua_State* L, int n)
{
if (n==1)
return toproto(L,-1);
else
{
Proto* f;
int i=n;
if (lua_load(L,reader,&i,"=(" PROGNAME ")",NULL)!=LUA_OK) fatal(lua_tostring(L,-1));
f=toproto(L,-1);
for (i=0; i<n; i++)
{
f->p[i]=toproto(L,i-n-1);
if (f->p[i]->sizeupvalues>0) f->p[i]->upvalues[0].instack=0;
}
return f;
}
}
static int writer(lua_State* L, const void* p, size_t size, void* u)
{
UNUSED(L);
return (fwrite(p,size,1,(FILE*)u)!=1) && (size!=0);
}
static int pmain(lua_State* L)
{
int argc=(int)lua_tointeger(L,1);
char** argv=(char**)lua_touserdata(L,2);
const Proto* f;
int i;
tmname=G(L)->tmname;
if (!lua_checkstack(L,argc)) fatal("too many input files");
for (i=0; i<argc; i++)
{
const char* filename=IS("-") ? NULL : argv[i];
if (luaL_loadfile(L,filename)!=LUA_OK) fatal(lua_tostring(L,-1));
}
f=combine(L,argc);
if (listing) luaU_print(f,listing>1);
if (dumping)
{
FILE* D= (output==NULL) ? stdout : fopen(output,"wb");
if (D==NULL) cannot("open");
lua_lock(L);
luaU_dump(L,f,writer,D,stripping);
lua_unlock(L);
if (ferror(D)) cannot("write");
if (fclose(D)) cannot("close");
}
return 0;
}
int main(int argc, char* argv[])
{
lua_State* L;
int i=doargs(argc,argv);
argc-=i; argv+=i;
if (argc<=0) usage("no input files given");
L=luaL_newstate();
if (L==NULL) fatal("cannot create state: not enough memory");
lua_pushcfunction(L,&pmain);
lua_pushinteger(L,argc);
lua_pushlightuserdata(L,argv);
if (lua_pcall(L,2,0,0)!=LUA_OK) fatal(lua_tostring(L,-1));
lua_close(L);
return EXIT_SUCCESS;
}
/*
** print bytecodes
*/
#define UPVALNAME(x) ((f->upvalues[x].name) ? getstr(f->upvalues[x].name) : "-")
#define VOID(p) ((const void*)(p))
#define eventname(i) (getstr(tmname[i]))
static void PrintString(const TString* ts)
{
const char* s=getstr(ts);
size_t i,n=tsslen(ts);
printf("\"");
for (i=0; i<n; i++)
{
int c=(int)(unsigned char)s[i];
switch (c)
{
case '"':
printf("\\\"");
break;
case '\\':
printf("\\\\");
break;
case '\a':
printf("\\a");
break;
case '\b':
printf("\\b");
break;
case '\f':
printf("\\f");
break;
case '\n':
printf("\\n");
break;
case '\r':
printf("\\r");
break;
case '\t':
printf("\\t");
break;
case '\v':
printf("\\v");
break;
default:
if (isprint(c)) printf("%c",c); else printf("\\%03d",c);
break;
}
}
printf("\"");
}
static void PrintType(const Proto* f, int i)
{
const TValue* o=&f->k[i];
switch (ttypetag(o))
{
case LUA_VNIL:
printf("N");
break;
case LUA_VFALSE:
case LUA_VTRUE:
printf("B");
break;
case LUA_VNUMFLT:
printf("F");
break;
case LUA_VNUMINT:
printf("I");
break;
case LUA_VSHRSTR:
case LUA_VLNGSTR:
printf("S");
break;
default: /* cannot happen */
printf("?%d",ttypetag(o));
break;
}
printf("\t");
}
static void PrintConstant(const Proto* f, int i)
{
const TValue* o=&f->k[i];
switch (ttypetag(o))
{
case LUA_VNIL:
printf("nil");
break;
case LUA_VFALSE:
printf("false");
break;
case LUA_VTRUE:
printf("true");
break;
case LUA_VNUMFLT:
{
char buff[100];
sprintf(buff,LUA_NUMBER_FMT,fltvalue(o));
printf("%s",buff);
if (buff[strspn(buff,"-0123456789")]=='\0') printf(".0");
break;
}
case LUA_VNUMINT:
printf(LUA_INTEGER_FMT,ivalue(o));
break;
case LUA_VSHRSTR:
case LUA_VLNGSTR:
PrintString(tsvalue(o));
break;
default: /* cannot happen */
printf("?%d",ttypetag(o));
break;
}
}
#define COMMENT "\t; "
#define EXTRAARG GETARG_Ax(code[pc+1])
#define EXTRAARGC (EXTRAARG*(MAXARG_C+1))
#define ISK (isk ? "k" : "")
static void PrintCode(const Proto* f)
{
const Instruction* code=f->code;
int pc,n=f->sizecode;
for (pc=0; pc<n; pc++)
{
Instruction i=code[pc];
OpCode o=GET_OPCODE(i);
int a=GETARG_A(i);
int b=GETARG_B(i);
int c=GETARG_C(i);
int ax=GETARG_Ax(i);
int bx=GETARG_Bx(i);
int sb=GETARG_sB(i);
int sc=GETARG_sC(i);
int sbx=GETARG_sBx(i);
int isk=GETARG_k(i);
int line=luaG_getfuncline(f,pc);
printf("\t%d\t",pc+1);
if (line>0) printf("[%d]\t",line); else printf("[-]\t");
printf("%-9s\t",opnames[o]);
switch (o)
{
case OP_MOVE:
printf("%d %d",a,b);
break;
case OP_LOADI:
printf("%d %d",a,sbx);
break;
case OP_LOADF:
printf("%d %d",a,sbx);
break;
case OP_LOADK:
printf("%d %d",a,bx);
printf(COMMENT); PrintConstant(f,bx);
break;
case OP_LOADKX:
printf("%d",a);
printf(COMMENT); PrintConstant(f,EXTRAARG);
break;
case OP_LOADFALSE:
printf("%d",a);
break;
case OP_LFALSESKIP:
printf("%d",a);
break;
case OP_LOADTRUE:
printf("%d",a);
break;
case OP_LOADNIL:
printf("%d %d",a,b);
printf(COMMENT "%d out",b+1);
break;
case OP_GETUPVAL:
printf("%d %d",a,b);
printf(COMMENT "%s",UPVALNAME(b));
break;
case OP_SETUPVAL:
printf("%d %d",a,b);
printf(COMMENT "%s",UPVALNAME(b));
break;
case OP_GETTABUP:
printf("%d %d %d",a,b,c);
printf(COMMENT "%s",UPVALNAME(b));
printf(" "); PrintConstant(f,c);
break;
case OP_GETTABLE:
printf("%d %d %d",a,b,c);
break;
case OP_GETI:
printf("%d %d %d",a,b,c);
break;
case OP_GETFIELD:
printf("%d %d %d",a,b,c);
printf(COMMENT); PrintConstant(f,c);
break;
case OP_SETTABUP:
printf("%d %d %d%s",a,b,c,ISK);
printf(COMMENT "%s",UPVALNAME(a));
printf(" "); PrintConstant(f,b);
if (isk) { printf(" "); PrintConstant(f,c); }
break;
case OP_SETTABLE:
printf("%d %d %d%s",a,b,c,ISK);
if (isk) { printf(COMMENT); PrintConstant(f,c); }
break;
case OP_SETI:
printf("%d %d %d%s",a,b,c,ISK);
if (isk) { printf(COMMENT); PrintConstant(f,c); }
break;
case OP_SETFIELD:
printf("%d %d %d%s",a,b,c,ISK);
printf(COMMENT); PrintConstant(f,b);
if (isk) { printf(" "); PrintConstant(f,c); }
break;
case OP_NEWTABLE:
printf("%d %d %d",a,b,c);
printf(COMMENT "%d",c+EXTRAARGC);
break;
case OP_SELF:
printf("%d %d %d%s",a,b,c,ISK);
if (isk) { printf(COMMENT); PrintConstant(f,c); }
break;
case OP_ADDI:
printf("%d %d %d",a,b,sc);
break;
case OP_ADDK:
printf("%d %d %d",a,b,c);
printf(COMMENT); PrintConstant(f,c);
break;
case OP_SUBK:
printf("%d %d %d",a,b,c);
printf(COMMENT); PrintConstant(f,c);
break;
case OP_MULK:
printf("%d %d %d",a,b,c);
printf(COMMENT); PrintConstant(f,c);
break;
case OP_MODK:
printf("%d %d %d",a,b,c);
printf(COMMENT); PrintConstant(f,c);
break;
case OP_POWK:
printf("%d %d %d",a,b,c);
printf(COMMENT); PrintConstant(f,c);
break;
case OP_DIVK:
printf("%d %d %d",a,b,c);
printf(COMMENT); PrintConstant(f,c);
break;
case OP_IDIVK:
printf("%d %d %d",a,b,c);
printf(COMMENT); PrintConstant(f,c);
break;
case OP_BANDK:
printf("%d %d %d",a,b,c);
printf(COMMENT); PrintConstant(f,c);
break;
case OP_BORK:
printf("%d %d %d",a,b,c);
printf(COMMENT); PrintConstant(f,c);
break;
case OP_BXORK:
printf("%d %d %d",a,b,c);
printf(COMMENT); PrintConstant(f,c);
break;
case OP_SHRI:
printf("%d %d %d",a,b,sc);
break;
case OP_SHLI:
printf("%d %d %d",a,b,sc);
break;
case OP_ADD:
printf("%d %d %d",a,b,c);
break;
case OP_SUB:
printf("%d %d %d",a,b,c);
break;
case OP_MUL:
printf("%d %d %d",a,b,c);
break;
case OP_MOD:
printf("%d %d %d",a,b,c);
break;
case OP_POW:
printf("%d %d %d",a,b,c);
break;
case OP_DIV:
printf("%d %d %d",a,b,c);
break;
case OP_IDIV:
printf("%d %d %d",a,b,c);
break;
case OP_BAND:
printf("%d %d %d",a,b,c);
break;
case OP_BOR:
printf("%d %d %d",a,b,c);
break;
case OP_BXOR:
printf("%d %d %d",a,b,c);
break;
case OP_SHL:
printf("%d %d %d",a,b,c);
break;
case OP_SHR:
printf("%d %d %d",a,b,c);
break;
case OP_MMBIN:
printf("%d %d %d",a,b,c);
printf(COMMENT "%s",eventname(c));
break;
case OP_MMBINI:
printf("%d %d %d %d",a,sb,c,isk);
printf(COMMENT "%s",eventname(c));
if (isk) printf(" flip");
break;
case OP_MMBINK:
printf("%d %d %d %d",a,b,c,isk);
printf(COMMENT "%s ",eventname(c)); PrintConstant(f,b);
if (isk) printf(" flip");
break;
case OP_UNM:
printf("%d %d",a,b);
break;
case OP_BNOT:
printf("%d %d",a,b);
break;
case OP_NOT:
printf("%d %d",a,b);
break;
case OP_LEN:
printf("%d %d",a,b);
break;
case OP_CONCAT:
printf("%d %d",a,b);
break;
case OP_CLOSE:
printf("%d",a);
break;
case OP_TBC:
printf("%d",a);
break;
case OP_JMP:
printf("%d",GETARG_sJ(i));
printf(COMMENT "to %d",GETARG_sJ(i)+pc+2);
break;
case OP_EQ:
printf("%d %d %d",a,b,isk);
break;
case OP_LT:
printf("%d %d %d",a,b,isk);
break;
case OP_LE:
printf("%d %d %d",a,b,isk);
break;
case OP_EQK:
printf("%d %d %d",a,b,isk);
printf(COMMENT); PrintConstant(f,b);
break;
case OP_EQI:
printf("%d %d %d",a,sb,isk);
break;
case OP_LTI:
printf("%d %d %d",a,sb,isk);
break;
case OP_LEI:
printf("%d %d %d",a,sb,isk);
break;
case OP_GTI:
printf("%d %d %d",a,sb,isk);
break;
case OP_GEI:
printf("%d %d %d",a,sb,isk);
break;
case OP_TEST:
printf("%d %d",a,isk);
break;
case OP_TESTSET:
printf("%d %d %d",a,b,isk);
break;
case OP_CALL:
printf("%d %d %d",a,b,c);
printf(COMMENT);
if (b==0) printf("all in "); else printf("%d in ",b-1);
if (c==0) printf("all out"); else printf("%d out",c-1);
break;
case OP_TAILCALL:
Bring Lua to 5.4.6. (#1214) This essentially re-does the work of #875 on top of master. This is what I did to check that Cosmo's Lua extensions still worked: ``` $ build/bootstrap/make MODE=aarch64 o/aarch64/third_party/lua/lua $ ape o/aarch64/third_party/lua/lua >: 10 10 >: 010 8 >: 0b10 2 >: string.byte("\e") 27 >: "Hello, %s" % {"world"} Hello, world >: "*" * 3 *** ``` `luaL_traceback2` was used to show the stack trace with parameter values; it's used in `LuaCallWithTrace`, which is used in Redbean to run Lua code. You should be able to see the extended stack trace by running something like this: `redbean -e "function a(b)c()end a(2)"` (with "params" indicating the extended stack trace): ``` stack traceback: [string "function a(b)c()end a(2)"]:1: in function 'a', params: b = 2; [string "function a(b)c()end a(2)"]:1: in main chunk ``` @pkulchenko confirmed that I get the expected result with the updated code. This is what I did to check that Lua itself still worked: ``` $ cd third_party/lua/test/ $ ape ../../../o/aarch64/third_party/lua/lua all.lua ``` There's one test failure, in `files.lua`: ``` ***** FILE 'files.lua'***** testing i/o ../../../o/aarch64/third_party/lua/lua: files.lua:84: assertion failed! stack traceback: [C]: in function 'assert' files.lua:84: in main chunk (...tail calls...) all.lua:195: in main chunk [C]: in ? .>>> closing state <<< ``` That isn't a result of these changes; the same test is failing in master. The failure is here: ```lua if not _port then -- invalid seek local status, msg, code = io.stdin:seek("set", 1000) assert(not status and type(msg) == "string" and type(code) == "number") end ``` The test expects a seek to offset 1,000 on stdin to fail — but it doesn't. `status` ends up being the new offset rather than `nil`. If I comment out that one test, the remaining tests succeed.
2024-06-16 00:13:08 +00:00
printf("%d %d %d%s",a,b,c,ISK);
printf(COMMENT "%d in",b-1);
break;
case OP_RETURN:
Bring Lua to 5.4.6. (#1214) This essentially re-does the work of #875 on top of master. This is what I did to check that Cosmo's Lua extensions still worked: ``` $ build/bootstrap/make MODE=aarch64 o/aarch64/third_party/lua/lua $ ape o/aarch64/third_party/lua/lua >: 10 10 >: 010 8 >: 0b10 2 >: string.byte("\e") 27 >: "Hello, %s" % {"world"} Hello, world >: "*" * 3 *** ``` `luaL_traceback2` was used to show the stack trace with parameter values; it's used in `LuaCallWithTrace`, which is used in Redbean to run Lua code. You should be able to see the extended stack trace by running something like this: `redbean -e "function a(b)c()end a(2)"` (with "params" indicating the extended stack trace): ``` stack traceback: [string "function a(b)c()end a(2)"]:1: in function 'a', params: b = 2; [string "function a(b)c()end a(2)"]:1: in main chunk ``` @pkulchenko confirmed that I get the expected result with the updated code. This is what I did to check that Lua itself still worked: ``` $ cd third_party/lua/test/ $ ape ../../../o/aarch64/third_party/lua/lua all.lua ``` There's one test failure, in `files.lua`: ``` ***** FILE 'files.lua'***** testing i/o ../../../o/aarch64/third_party/lua/lua: files.lua:84: assertion failed! stack traceback: [C]: in function 'assert' files.lua:84: in main chunk (...tail calls...) all.lua:195: in main chunk [C]: in ? .>>> closing state <<< ``` That isn't a result of these changes; the same test is failing in master. The failure is here: ```lua if not _port then -- invalid seek local status, msg, code = io.stdin:seek("set", 1000) assert(not status and type(msg) == "string" and type(code) == "number") end ``` The test expects a seek to offset 1,000 on stdin to fail — but it doesn't. `status` ends up being the new offset rather than `nil`. If I comment out that one test, the remaining tests succeed.
2024-06-16 00:13:08 +00:00
printf("%d %d %d%s",a,b,c,ISK);
printf(COMMENT);
if (b==0) printf("all out"); else printf("%d out",b-1);
break;
case OP_RETURN0:
break;
case OP_RETURN1:
printf("%d",a);
break;
case OP_FORLOOP:
printf("%d %d",a,bx);
printf(COMMENT "to %d",pc-bx+2);
break;
case OP_FORPREP:
printf("%d %d",a,bx);
Bring Lua to 5.4.6. (#1214) This essentially re-does the work of #875 on top of master. This is what I did to check that Cosmo's Lua extensions still worked: ``` $ build/bootstrap/make MODE=aarch64 o/aarch64/third_party/lua/lua $ ape o/aarch64/third_party/lua/lua >: 10 10 >: 010 8 >: 0b10 2 >: string.byte("\e") 27 >: "Hello, %s" % {"world"} Hello, world >: "*" * 3 *** ``` `luaL_traceback2` was used to show the stack trace with parameter values; it's used in `LuaCallWithTrace`, which is used in Redbean to run Lua code. You should be able to see the extended stack trace by running something like this: `redbean -e "function a(b)c()end a(2)"` (with "params" indicating the extended stack trace): ``` stack traceback: [string "function a(b)c()end a(2)"]:1: in function 'a', params: b = 2; [string "function a(b)c()end a(2)"]:1: in main chunk ``` @pkulchenko confirmed that I get the expected result with the updated code. This is what I did to check that Lua itself still worked: ``` $ cd third_party/lua/test/ $ ape ../../../o/aarch64/third_party/lua/lua all.lua ``` There's one test failure, in `files.lua`: ``` ***** FILE 'files.lua'***** testing i/o ../../../o/aarch64/third_party/lua/lua: files.lua:84: assertion failed! stack traceback: [C]: in function 'assert' files.lua:84: in main chunk (...tail calls...) all.lua:195: in main chunk [C]: in ? .>>> closing state <<< ``` That isn't a result of these changes; the same test is failing in master. The failure is here: ```lua if not _port then -- invalid seek local status, msg, code = io.stdin:seek("set", 1000) assert(not status and type(msg) == "string" and type(code) == "number") end ``` The test expects a seek to offset 1,000 on stdin to fail — but it doesn't. `status` ends up being the new offset rather than `nil`. If I comment out that one test, the remaining tests succeed.
2024-06-16 00:13:08 +00:00
printf(COMMENT "exit to %d",pc+bx+3);
break;
case OP_TFORPREP:
printf("%d %d",a,bx);
printf(COMMENT "to %d",pc+bx+2);
break;
case OP_TFORCALL:
printf("%d %d",a,c);
break;
case OP_TFORLOOP:
printf("%d %d",a,bx);
printf(COMMENT "to %d",pc-bx+2);
break;
case OP_SETLIST:
printf("%d %d %d",a,b,c);
if (isk) printf(COMMENT "%d",c+EXTRAARGC);
break;
case OP_CLOSURE:
printf("%d %d",a,bx);
printf(COMMENT "%p",VOID(f->p[bx]));
break;
case OP_VARARG:
printf("%d %d",a,c);
printf(COMMENT);
if (c==0) printf("all out"); else printf("%d out",c-1);
break;
case OP_VARARGPREP:
printf("%d",a);
break;
case OP_EXTRAARG:
printf("%d",ax);
break;
#if 0
default:
printf("%d %d %d",a,b,c);
printf(COMMENT "not handled");
break;
#endif
}
printf("\n");
}
}
#define SS(x) ((x==1)?"":"s")
#define S(x) (int)(x),SS(x)
static void PrintHeader(const Proto* f)
{
const char* s=f->source ? getstr(f->source) : "=?";
if (*s=='@' || *s=='=')
s++;
else if (*s==LUA_SIGNATURE[0])
s="(bstring)";
else
s="(string)";
printf("\n%s <%s:%d,%d> (%d instruction%s at %p)\n",
(f->linedefined==0)?"main":"function",s,
f->linedefined,f->lastlinedefined,
S(f->sizecode),VOID(f));
printf("%d%s param%s, %d slot%s, %d upvalue%s, ",
(int)(f->numparams),f->is_vararg?"+":"",SS(f->numparams),
S(f->maxstacksize),S(f->sizeupvalues));
printf("%d local%s, %d constant%s, %d function%s\n",
S(f->sizelocvars),S(f->sizek),S(f->sizep));
}
static void PrintDebug(const Proto* f)
{
int i,n;
n=f->sizek;
printf("constants (%d) for %p:\n",n,VOID(f));
for (i=0; i<n; i++)
{
printf("\t%d\t",i);
PrintType(f,i);
PrintConstant(f,i);
printf("\n");
}
n=f->sizelocvars;
printf("locals (%d) for %p:\n",n,VOID(f));
for (i=0; i<n; i++)
{
printf("\t%d\t%s\t%d\t%d\n",
i,getstr(f->locvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1);
}
n=f->sizeupvalues;
printf("upvalues (%d) for %p:\n",n,VOID(f));
for (i=0; i<n; i++)
{
printf("\t%d\t%s\t%d\t%d\n",
i,UPVALNAME(i),f->upvalues[i].instack,f->upvalues[i].idx);
}
}
static void PrintFunction(const Proto* f, int full)
{
int i,n=f->sizep;
PrintHeader(f);
PrintCode(f);
if (full) PrintDebug(f);
for (i=0; i<n; i++) PrintFunction(f->p[i],full);
}