mirror of
https://github.com/love2d/megasource.git
synced 2026-08-12 08:30:59 +02:00
Update LuaJIT to LuaJIT/LuaJIT@f73e649.
This commit is contained in:
+1
-1
@@ -221,7 +221,7 @@ endif()
|
||||
|
||||
set(MEGA_ZLIB_VER "1.3.1")
|
||||
set(MEGA_LUA51_VER "5.1.5")
|
||||
set(MEGA_LUAJIT_VER "2.1.1710088188")
|
||||
set(MEGA_LUAJIT_VER "2.1.1734355927")
|
||||
set(MEGA_LIBOGG_VER "1.3.2")
|
||||
set(MEGA_LIBVORBIS_VER "1.3.5")
|
||||
set(MEGA_LIBTHEORA_VER "1.1.1")
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
1710088188
|
||||
1734355927
|
||||
|
||||
@@ -37,12 +37,13 @@ export MULTILIB= lib
|
||||
DPREFIX= $(DESTDIR)$(PREFIX)
|
||||
INSTALL_BIN= $(DPREFIX)/bin
|
||||
INSTALL_LIB= $(DPREFIX)/$(MULTILIB)
|
||||
INSTALL_SHARE= $(DPREFIX)/share
|
||||
INSTALL_SHARE_= $(PREFIX)/share
|
||||
INSTALL_SHARE= $(DESTDIR)$(INSTALL_SHARE_)
|
||||
INSTALL_DEFINC= $(DPREFIX)/include/luajit-$(MMVERSION)
|
||||
INSTALL_INC= $(INSTALL_DEFINC)
|
||||
|
||||
INSTALL_LJLIBD= $(INSTALL_SHARE)/luajit-$(MMVERSION)
|
||||
INSTALL_JITLIB= $(INSTALL_LJLIBD)/jit
|
||||
export INSTALL_LJLIBD= $(INSTALL_SHARE_)/luajit-$(MMVERSION)
|
||||
INSTALL_JITLIB= $(DESTDIR)$(INSTALL_LJLIBD)/jit
|
||||
INSTALL_LMODD= $(INSTALL_SHARE)/lua
|
||||
INSTALL_LMOD= $(INSTALL_LMODD)/$(ABIVER)
|
||||
INSTALL_CMODD= $(INSTALL_LIB)/lua
|
||||
@@ -71,7 +72,7 @@ INSTALL_PC= $(INSTALL_PKGCONFIG)/$(INSTALL_PCNAME)
|
||||
|
||||
INSTALL_DIRS= $(INSTALL_BIN) $(INSTALL_LIB) $(INSTALL_INC) $(INSTALL_MAN) \
|
||||
$(INSTALL_PKGCONFIG) $(INSTALL_JITLIB) $(INSTALL_LMOD) $(INSTALL_CMOD)
|
||||
UNINSTALL_DIRS= $(INSTALL_JITLIB) $(INSTALL_LJLIBD) $(INSTALL_INC) \
|
||||
UNINSTALL_DIRS= $(INSTALL_JITLIB) $(DESTDIR)$(INSTALL_LJLIBD) $(INSTALL_INC) \
|
||||
$(INSTALL_LMOD) $(INSTALL_LMODD) $(INSTALL_CMOD) $(INSTALL_CMODD)
|
||||
|
||||
RM= rm -f
|
||||
@@ -114,6 +115,7 @@ ifeq (Darwin,$(TARGET_SYS))
|
||||
INSTALL_SOSHORT1= $(INSTALL_DYLIBSHORT1)
|
||||
INSTALL_SOSHORT2= $(INSTALL_DYLIBSHORT2)
|
||||
LDCONFIG= :
|
||||
SED_PC+= -e "s| -Wl,-E||"
|
||||
endif
|
||||
|
||||
##############################################################################
|
||||
|
||||
@@ -439,24 +439,12 @@ typedef struct
|
||||
{
|
||||
mach_header; uint32_t reserved;
|
||||
} mach_header_64;
|
||||
typedef struct {
|
||||
uint32_t cmd, cmdsize;
|
||||
char segname[16];
|
||||
uint32_t vmaddr, vmsize, fileoff, filesize;
|
||||
uint32_t maxprot, initprot, nsects, flags;
|
||||
} mach_segment_command;
|
||||
typedef struct {
|
||||
uint32_t cmd, cmdsize;
|
||||
char segname[16];
|
||||
uint64_t vmaddr, vmsize, fileoff, filesize;
|
||||
uint32_t maxprot, initprot, nsects, flags;
|
||||
} mach_segment_command_64;
|
||||
typedef struct {
|
||||
char sectname[16], segname[16];
|
||||
uint32_t addr, size;
|
||||
uint32_t offset, align, reloff, nreloc, flags;
|
||||
uint32_t reserved1, reserved2;
|
||||
} mach_section;
|
||||
typedef struct {
|
||||
char sectname[16], segname[16];
|
||||
uint64_t addr, size;
|
||||
@@ -466,139 +454,64 @@ typedef struct {
|
||||
typedef struct {
|
||||
uint32_t cmd, cmdsize, symoff, nsyms, stroff, strsize;
|
||||
} mach_symtab_command;
|
||||
typedef struct {
|
||||
int32_t strx;
|
||||
uint8_t type, sect;
|
||||
int16_t desc;
|
||||
uint32_t value;
|
||||
} mach_nlist;
|
||||
typedef struct {
|
||||
int32_t strx;
|
||||
uint8_t type, sect;
|
||||
uint16_t desc;
|
||||
uint64_t value;
|
||||
} mach_nlist_64;
|
||||
typedef struct
|
||||
{
|
||||
int32_t magic, nfat_arch;
|
||||
} mach_fat_header;
|
||||
typedef struct
|
||||
{
|
||||
int32_t cputype, cpusubtype, offset, size, align;
|
||||
} mach_fat_arch;
|
||||
typedef struct {
|
||||
struct {
|
||||
mach_header hdr;
|
||||
mach_segment_command seg;
|
||||
mach_section sec;
|
||||
mach_symtab_command sym;
|
||||
} arch[1];
|
||||
mach_nlist sym_entry;
|
||||
uint8_t space[4096];
|
||||
} mach_obj;
|
||||
typedef struct {
|
||||
struct {
|
||||
mach_header_64 hdr;
|
||||
mach_segment_command_64 seg;
|
||||
mach_section_64 sec;
|
||||
mach_symtab_command sym;
|
||||
} arch[1];
|
||||
mach_header_64 hdr;
|
||||
mach_segment_command_64 seg;
|
||||
mach_section_64 sec;
|
||||
mach_symtab_command sym;
|
||||
mach_nlist_64 sym_entry;
|
||||
uint8_t space[4096];
|
||||
} mach_obj_64;
|
||||
typedef struct {
|
||||
mach_fat_header fat;
|
||||
mach_fat_arch fat_arch[2];
|
||||
struct {
|
||||
mach_header hdr;
|
||||
mach_segment_command seg;
|
||||
mach_section sec;
|
||||
mach_symtab_command sym;
|
||||
} arch[2];
|
||||
mach_nlist sym_entry;
|
||||
uint8_t space[4096];
|
||||
} mach_fat_obj;
|
||||
typedef struct {
|
||||
mach_fat_header fat;
|
||||
mach_fat_arch fat_arch[2];
|
||||
struct {
|
||||
mach_header_64 hdr;
|
||||
mach_segment_command_64 seg;
|
||||
mach_section_64 sec;
|
||||
mach_symtab_command sym;
|
||||
} arch[2];
|
||||
mach_nlist_64 sym_entry;
|
||||
uint8_t space[4096];
|
||||
} mach_fat_obj_64;
|
||||
]]
|
||||
local symname = '_'..LJBC_PREFIX..ctx.modname
|
||||
local isfat, is64, align, mobj = false, false, 4, "mach_obj"
|
||||
if ctx.arch == "x64" then
|
||||
is64, align, mobj = true, 8, "mach_obj_64"
|
||||
elseif ctx.arch == "arm" then
|
||||
isfat, mobj = true, "mach_fat_obj"
|
||||
elseif ctx.arch == "arm64" then
|
||||
is64, align, isfat, mobj = true, 8, true, "mach_fat_obj_64"
|
||||
else
|
||||
check(ctx.arch == "x86", "unsupported architecture for OSX")
|
||||
local cputype, cpusubtype = 0x01000007, 3
|
||||
if ctx.arch ~= "x64" then
|
||||
check(ctx.arch == "arm64", "unsupported architecture for OSX")
|
||||
cputype, cpusubtype = 0x0100000c, 0
|
||||
end
|
||||
local function aligned(v, a) return bit.band(v+a-1, -a) end
|
||||
local be32 = bit.bswap -- Mach-O FAT is BE, supported archs are LE.
|
||||
|
||||
-- Create Mach-O object and fill in header.
|
||||
local o = ffi.new(mobj)
|
||||
local mach_size = aligned(ffi.offsetof(o, "space")+#symname+2, align)
|
||||
local cputype = ({ x86={7}, x64={0x01000007}, arm={7,12}, arm64={0x01000007,0x0100000c} })[ctx.arch]
|
||||
local cpusubtype = ({ x86={3}, x64={3}, arm={3,9}, arm64={3,0} })[ctx.arch]
|
||||
if isfat then
|
||||
o.fat.magic = be32(0xcafebabe)
|
||||
o.fat.nfat_arch = be32(#cpusubtype)
|
||||
end
|
||||
local o = ffi.new("mach_obj_64")
|
||||
local mach_size = aligned(ffi.offsetof(o, "space")+#symname+2, 8)
|
||||
|
||||
-- Fill in sections and symbols.
|
||||
for i=0,#cpusubtype-1 do
|
||||
local ofs = 0
|
||||
if isfat then
|
||||
local a = o.fat_arch[i]
|
||||
a.cputype = be32(cputype[i+1])
|
||||
a.cpusubtype = be32(cpusubtype[i+1])
|
||||
-- Subsequent slices overlap each other to share data.
|
||||
ofs = ffi.offsetof(o, "arch") + i*ffi.sizeof(o.arch[0])
|
||||
a.offset = be32(ofs)
|
||||
a.size = be32(mach_size-ofs+#s)
|
||||
end
|
||||
local a = o.arch[i]
|
||||
a.hdr.magic = is64 and 0xfeedfacf or 0xfeedface
|
||||
a.hdr.cputype = cputype[i+1]
|
||||
a.hdr.cpusubtype = cpusubtype[i+1]
|
||||
a.hdr.filetype = 1
|
||||
a.hdr.ncmds = 2
|
||||
a.hdr.sizeofcmds = ffi.sizeof(a.seg)+ffi.sizeof(a.sec)+ffi.sizeof(a.sym)
|
||||
a.seg.cmd = is64 and 0x19 or 0x1
|
||||
a.seg.cmdsize = ffi.sizeof(a.seg)+ffi.sizeof(a.sec)
|
||||
a.seg.vmsize = #s
|
||||
a.seg.fileoff = mach_size-ofs
|
||||
a.seg.filesize = #s
|
||||
a.seg.maxprot = 1
|
||||
a.seg.initprot = 1
|
||||
a.seg.nsects = 1
|
||||
ffi.copy(a.sec.sectname, "__data")
|
||||
ffi.copy(a.sec.segname, "__DATA")
|
||||
a.sec.size = #s
|
||||
a.sec.offset = mach_size-ofs
|
||||
a.sym.cmd = 2
|
||||
a.sym.cmdsize = ffi.sizeof(a.sym)
|
||||
a.sym.symoff = ffi.offsetof(o, "sym_entry")-ofs
|
||||
a.sym.nsyms = 1
|
||||
a.sym.stroff = ffi.offsetof(o, "sym_entry")+ffi.sizeof(o.sym_entry)-ofs
|
||||
a.sym.strsize = aligned(#symname+2, align)
|
||||
end
|
||||
o.hdr.magic = 0xfeedfacf
|
||||
o.hdr.cputype = cputype
|
||||
o.hdr.cpusubtype = cpusubtype
|
||||
o.hdr.filetype = 1
|
||||
o.hdr.ncmds = 2
|
||||
o.hdr.sizeofcmds = ffi.sizeof(o.seg)+ffi.sizeof(o.sec)+ffi.sizeof(o.sym)
|
||||
o.seg.cmd = 0x19
|
||||
o.seg.cmdsize = ffi.sizeof(o.seg)+ffi.sizeof(o.sec)
|
||||
o.seg.vmsize = #s
|
||||
o.seg.fileoff = mach_size
|
||||
o.seg.filesize = #s
|
||||
o.seg.maxprot = 1
|
||||
o.seg.initprot = 1
|
||||
o.seg.nsects = 1
|
||||
ffi.copy(o.sec.sectname, "__data")
|
||||
ffi.copy(o.sec.segname, "__DATA")
|
||||
o.sec.size = #s
|
||||
o.sec.offset = mach_size
|
||||
o.sym.cmd = 2
|
||||
o.sym.cmdsize = ffi.sizeof(o.sym)
|
||||
o.sym.symoff = ffi.offsetof(o, "sym_entry")
|
||||
o.sym.nsyms = 1
|
||||
o.sym.stroff = ffi.offsetof(o, "sym_entry")+ffi.sizeof(o.sym_entry)
|
||||
o.sym.strsize = aligned(#symname+2, 8)
|
||||
o.sym_entry.type = 0xf
|
||||
o.sym_entry.sect = 1
|
||||
o.sym_entry.strx = 1
|
||||
ffi.copy(o.space+1, symname)
|
||||
|
||||
-- Write Macho-O object file.
|
||||
-- Write Mach-O object file.
|
||||
local fp = savefile(output, "wb")
|
||||
fp:write(ffi.string(o, mach_size))
|
||||
bcsave_tail(fp, output, s)
|
||||
|
||||
@@ -658,6 +658,10 @@ local map_datafp = { -- Data processing, SIMD and FP.
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{ -- 010
|
||||
shift = 0, mask = 0x81f8fc00,
|
||||
[0x100e400] = "moviDdG"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -832,6 +836,20 @@ local function parse_fpimm8(op)
|
||||
return sign * frac * 2^exp
|
||||
end
|
||||
|
||||
local function decode_fpmovi(op)
|
||||
local lo = rshift(op, 5)
|
||||
local hi = rshift(op, 9)
|
||||
lo = bor(band(lo, 1) * 0xff, band(lo, 2) * 0x7f80, band(lo, 4) * 0x3fc000,
|
||||
band(lo, 8) * 0x1fe00000)
|
||||
hi = bor(band(hi, 1) * 0xff, band(hi, 0x80) * 0x1fe,
|
||||
band(hi, 0x100) * 0xff00, band(hi, 0x200) * 0x7f8000)
|
||||
if hi ~= 0 then
|
||||
return fmt_hex32(hi)..tohex(lo)
|
||||
else
|
||||
return fmt_hex32(lo)
|
||||
end
|
||||
end
|
||||
|
||||
local function prefer_bfx(sf, uns, imms, immr)
|
||||
if imms < immr or imms == 31 or imms == 63 then
|
||||
return false
|
||||
@@ -1131,6 +1149,8 @@ local function disass_ins(ctx)
|
||||
x = 0
|
||||
elseif p == "F" then
|
||||
x = parse_fpimm8(op)
|
||||
elseif p == "G" then
|
||||
x = "#0x"..decode_fpmovi(op)
|
||||
elseif p == "g" or p == "f" or p == "x" or p == "w" or
|
||||
p == "d" or p == "s" then
|
||||
-- These are handled in D/N/M/A.
|
||||
|
||||
@@ -552,7 +552,12 @@ local recdepth = 0
|
||||
local function fmterr(err, info)
|
||||
if type(err) == "number" then
|
||||
if type(info) == "function" then info = fmtfunc(info) end
|
||||
err = format(vmdef.traceerr[err], info)
|
||||
local fmt = vmdef.traceerr[err]
|
||||
if fmt == "NYI: bytecode %s" then
|
||||
local oidx = 6 * info
|
||||
info = sub(vmdef.bcnames, oidx+1, oidx+6)
|
||||
end
|
||||
err = format(fmt, info)
|
||||
end
|
||||
return err
|
||||
end
|
||||
|
||||
@@ -227,9 +227,7 @@ local function prof_finish()
|
||||
local samples = prof_samples
|
||||
if samples == 0 then
|
||||
if prof_raw ~= true then out:write("[No samples collected]\n") end
|
||||
return
|
||||
end
|
||||
if prof_ann then
|
||||
elseif prof_ann then
|
||||
prof_annotate(prof_count1, samples)
|
||||
else
|
||||
prof_top(prof_count1, prof_count2, samples, "")
|
||||
|
||||
@@ -62,7 +62,7 @@ local jit = require("jit")
|
||||
local jutil = require("jit.util")
|
||||
local vmdef = require("jit.vmdef")
|
||||
local funcinfo, traceinfo = jutil.funcinfo, jutil.traceinfo
|
||||
local type, format = type, string.format
|
||||
local type, sub, format = type, string.sub, string.format
|
||||
local stdout, stderr = io.stdout, io.stderr
|
||||
|
||||
-- Active flag and output file handle.
|
||||
@@ -89,7 +89,12 @@ end
|
||||
local function fmterr(err, info)
|
||||
if type(err) == "number" then
|
||||
if type(info) == "function" then info = fmtfunc(info) end
|
||||
err = format(vmdef.traceerr[err], info)
|
||||
local fmt = vmdef.traceerr[err]
|
||||
if fmt == "NYI: bytecode %s" then
|
||||
local oidx = 6 * info
|
||||
info = sub(vmdef.bcnames, oidx+1, oidx+6)
|
||||
end
|
||||
err = format(fmt, info)
|
||||
end
|
||||
return err
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-- This is a generated file. DO NOT EDIT!
|
||||
|
||||
assert(require("jit").version == "LuaJIT 2.1.1710088188", "LuaJIT core/library version mismatch")
|
||||
assert(require("jit").version == "LuaJIT 2.1.1734355927", "LuaJIT core/library version mismatch")
|
||||
|
||||
return {
|
||||
|
||||
@@ -136,7 +136,7 @@ traceerr = {
|
||||
"too many snapshots",
|
||||
"blacklisted",
|
||||
"retry recording",
|
||||
"NYI: bytecode %d",
|
||||
"NYI: bytecode %s",
|
||||
"leaving loop in root trace",
|
||||
"inner loop in root trace",
|
||||
"loop unroll limit reached",
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -30,9 +30,9 @@
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#define LUAJIT_VERSION "LuaJIT 2.1.1710088188"
|
||||
#define LUAJIT_VERSION "LuaJIT 2.1.1734355927"
|
||||
#define LUAJIT_VERSION_NUM 20199 /* Deprecated. */
|
||||
#define LUAJIT_VERSION_SYM luaJIT_version_2_1_1710088188
|
||||
#define LUAJIT_VERSION_SYM luaJIT_version_2_1_1734355927
|
||||
#define LUAJIT_COPYRIGHT "Copyright (C) 2005-2023 Mike Pall"
|
||||
#define LUAJIT_URL "https://luajit.org/"
|
||||
|
||||
|
||||
@@ -439,24 +439,12 @@ typedef struct
|
||||
{
|
||||
mach_header; uint32_t reserved;
|
||||
} mach_header_64;
|
||||
typedef struct {
|
||||
uint32_t cmd, cmdsize;
|
||||
char segname[16];
|
||||
uint32_t vmaddr, vmsize, fileoff, filesize;
|
||||
uint32_t maxprot, initprot, nsects, flags;
|
||||
} mach_segment_command;
|
||||
typedef struct {
|
||||
uint32_t cmd, cmdsize;
|
||||
char segname[16];
|
||||
uint64_t vmaddr, vmsize, fileoff, filesize;
|
||||
uint32_t maxprot, initprot, nsects, flags;
|
||||
} mach_segment_command_64;
|
||||
typedef struct {
|
||||
char sectname[16], segname[16];
|
||||
uint32_t addr, size;
|
||||
uint32_t offset, align, reloff, nreloc, flags;
|
||||
uint32_t reserved1, reserved2;
|
||||
} mach_section;
|
||||
typedef struct {
|
||||
char sectname[16], segname[16];
|
||||
uint64_t addr, size;
|
||||
@@ -466,139 +454,64 @@ typedef struct {
|
||||
typedef struct {
|
||||
uint32_t cmd, cmdsize, symoff, nsyms, stroff, strsize;
|
||||
} mach_symtab_command;
|
||||
typedef struct {
|
||||
int32_t strx;
|
||||
uint8_t type, sect;
|
||||
int16_t desc;
|
||||
uint32_t value;
|
||||
} mach_nlist;
|
||||
typedef struct {
|
||||
int32_t strx;
|
||||
uint8_t type, sect;
|
||||
uint16_t desc;
|
||||
uint64_t value;
|
||||
} mach_nlist_64;
|
||||
typedef struct
|
||||
{
|
||||
int32_t magic, nfat_arch;
|
||||
} mach_fat_header;
|
||||
typedef struct
|
||||
{
|
||||
int32_t cputype, cpusubtype, offset, size, align;
|
||||
} mach_fat_arch;
|
||||
typedef struct {
|
||||
struct {
|
||||
mach_header hdr;
|
||||
mach_segment_command seg;
|
||||
mach_section sec;
|
||||
mach_symtab_command sym;
|
||||
} arch[1];
|
||||
mach_nlist sym_entry;
|
||||
uint8_t space[4096];
|
||||
} mach_obj;
|
||||
typedef struct {
|
||||
struct {
|
||||
mach_header_64 hdr;
|
||||
mach_segment_command_64 seg;
|
||||
mach_section_64 sec;
|
||||
mach_symtab_command sym;
|
||||
} arch[1];
|
||||
mach_header_64 hdr;
|
||||
mach_segment_command_64 seg;
|
||||
mach_section_64 sec;
|
||||
mach_symtab_command sym;
|
||||
mach_nlist_64 sym_entry;
|
||||
uint8_t space[4096];
|
||||
} mach_obj_64;
|
||||
typedef struct {
|
||||
mach_fat_header fat;
|
||||
mach_fat_arch fat_arch[2];
|
||||
struct {
|
||||
mach_header hdr;
|
||||
mach_segment_command seg;
|
||||
mach_section sec;
|
||||
mach_symtab_command sym;
|
||||
} arch[2];
|
||||
mach_nlist sym_entry;
|
||||
uint8_t space[4096];
|
||||
} mach_fat_obj;
|
||||
typedef struct {
|
||||
mach_fat_header fat;
|
||||
mach_fat_arch fat_arch[2];
|
||||
struct {
|
||||
mach_header_64 hdr;
|
||||
mach_segment_command_64 seg;
|
||||
mach_section_64 sec;
|
||||
mach_symtab_command sym;
|
||||
} arch[2];
|
||||
mach_nlist_64 sym_entry;
|
||||
uint8_t space[4096];
|
||||
} mach_fat_obj_64;
|
||||
]]
|
||||
local symname = '_'..LJBC_PREFIX..ctx.modname
|
||||
local isfat, is64, align, mobj = false, false, 4, "mach_obj"
|
||||
if ctx.arch == "x64" then
|
||||
is64, align, mobj = true, 8, "mach_obj_64"
|
||||
elseif ctx.arch == "arm" then
|
||||
isfat, mobj = true, "mach_fat_obj"
|
||||
elseif ctx.arch == "arm64" then
|
||||
is64, align, isfat, mobj = true, 8, true, "mach_fat_obj_64"
|
||||
else
|
||||
check(ctx.arch == "x86", "unsupported architecture for OSX")
|
||||
local cputype, cpusubtype = 0x01000007, 3
|
||||
if ctx.arch ~= "x64" then
|
||||
check(ctx.arch == "arm64", "unsupported architecture for OSX")
|
||||
cputype, cpusubtype = 0x0100000c, 0
|
||||
end
|
||||
local function aligned(v, a) return bit.band(v+a-1, -a) end
|
||||
local be32 = bit.bswap -- Mach-O FAT is BE, supported archs are LE.
|
||||
|
||||
-- Create Mach-O object and fill in header.
|
||||
local o = ffi.new(mobj)
|
||||
local mach_size = aligned(ffi.offsetof(o, "space")+#symname+2, align)
|
||||
local cputype = ({ x86={7}, x64={0x01000007}, arm={7,12}, arm64={0x01000007,0x0100000c} })[ctx.arch]
|
||||
local cpusubtype = ({ x86={3}, x64={3}, arm={3,9}, arm64={3,0} })[ctx.arch]
|
||||
if isfat then
|
||||
o.fat.magic = be32(0xcafebabe)
|
||||
o.fat.nfat_arch = be32(#cpusubtype)
|
||||
end
|
||||
local o = ffi.new("mach_obj_64")
|
||||
local mach_size = aligned(ffi.offsetof(o, "space")+#symname+2, 8)
|
||||
|
||||
-- Fill in sections and symbols.
|
||||
for i=0,#cpusubtype-1 do
|
||||
local ofs = 0
|
||||
if isfat then
|
||||
local a = o.fat_arch[i]
|
||||
a.cputype = be32(cputype[i+1])
|
||||
a.cpusubtype = be32(cpusubtype[i+1])
|
||||
-- Subsequent slices overlap each other to share data.
|
||||
ofs = ffi.offsetof(o, "arch") + i*ffi.sizeof(o.arch[0])
|
||||
a.offset = be32(ofs)
|
||||
a.size = be32(mach_size-ofs+#s)
|
||||
end
|
||||
local a = o.arch[i]
|
||||
a.hdr.magic = is64 and 0xfeedfacf or 0xfeedface
|
||||
a.hdr.cputype = cputype[i+1]
|
||||
a.hdr.cpusubtype = cpusubtype[i+1]
|
||||
a.hdr.filetype = 1
|
||||
a.hdr.ncmds = 2
|
||||
a.hdr.sizeofcmds = ffi.sizeof(a.seg)+ffi.sizeof(a.sec)+ffi.sizeof(a.sym)
|
||||
a.seg.cmd = is64 and 0x19 or 0x1
|
||||
a.seg.cmdsize = ffi.sizeof(a.seg)+ffi.sizeof(a.sec)
|
||||
a.seg.vmsize = #s
|
||||
a.seg.fileoff = mach_size-ofs
|
||||
a.seg.filesize = #s
|
||||
a.seg.maxprot = 1
|
||||
a.seg.initprot = 1
|
||||
a.seg.nsects = 1
|
||||
ffi.copy(a.sec.sectname, "__data")
|
||||
ffi.copy(a.sec.segname, "__DATA")
|
||||
a.sec.size = #s
|
||||
a.sec.offset = mach_size-ofs
|
||||
a.sym.cmd = 2
|
||||
a.sym.cmdsize = ffi.sizeof(a.sym)
|
||||
a.sym.symoff = ffi.offsetof(o, "sym_entry")-ofs
|
||||
a.sym.nsyms = 1
|
||||
a.sym.stroff = ffi.offsetof(o, "sym_entry")+ffi.sizeof(o.sym_entry)-ofs
|
||||
a.sym.strsize = aligned(#symname+2, align)
|
||||
end
|
||||
o.hdr.magic = 0xfeedfacf
|
||||
o.hdr.cputype = cputype
|
||||
o.hdr.cpusubtype = cpusubtype
|
||||
o.hdr.filetype = 1
|
||||
o.hdr.ncmds = 2
|
||||
o.hdr.sizeofcmds = ffi.sizeof(o.seg)+ffi.sizeof(o.sec)+ffi.sizeof(o.sym)
|
||||
o.seg.cmd = 0x19
|
||||
o.seg.cmdsize = ffi.sizeof(o.seg)+ffi.sizeof(o.sec)
|
||||
o.seg.vmsize = #s
|
||||
o.seg.fileoff = mach_size
|
||||
o.seg.filesize = #s
|
||||
o.seg.maxprot = 1
|
||||
o.seg.initprot = 1
|
||||
o.seg.nsects = 1
|
||||
ffi.copy(o.sec.sectname, "__data")
|
||||
ffi.copy(o.sec.segname, "__DATA")
|
||||
o.sec.size = #s
|
||||
o.sec.offset = mach_size
|
||||
o.sym.cmd = 2
|
||||
o.sym.cmdsize = ffi.sizeof(o.sym)
|
||||
o.sym.symoff = ffi.offsetof(o, "sym_entry")
|
||||
o.sym.nsyms = 1
|
||||
o.sym.stroff = ffi.offsetof(o, "sym_entry")+ffi.sizeof(o.sym_entry)
|
||||
o.sym.strsize = aligned(#symname+2, 8)
|
||||
o.sym_entry.type = 0xf
|
||||
o.sym_entry.sect = 1
|
||||
o.sym_entry.strx = 1
|
||||
ffi.copy(o.space+1, symname)
|
||||
|
||||
-- Write Macho-O object file.
|
||||
-- Write Mach-O object file.
|
||||
local fp = savefile(output, "wb")
|
||||
fp:write(ffi.string(o, mach_size))
|
||||
bcsave_tail(fp, output, s)
|
||||
|
||||
@@ -658,6 +658,10 @@ local map_datafp = { -- Data processing, SIMD and FP.
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{ -- 010
|
||||
shift = 0, mask = 0x81f8fc00,
|
||||
[0x100e400] = "moviDdG"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -832,6 +836,20 @@ local function parse_fpimm8(op)
|
||||
return sign * frac * 2^exp
|
||||
end
|
||||
|
||||
local function decode_fpmovi(op)
|
||||
local lo = rshift(op, 5)
|
||||
local hi = rshift(op, 9)
|
||||
lo = bor(band(lo, 1) * 0xff, band(lo, 2) * 0x7f80, band(lo, 4) * 0x3fc000,
|
||||
band(lo, 8) * 0x1fe00000)
|
||||
hi = bor(band(hi, 1) * 0xff, band(hi, 0x80) * 0x1fe,
|
||||
band(hi, 0x100) * 0xff00, band(hi, 0x200) * 0x7f8000)
|
||||
if hi ~= 0 then
|
||||
return fmt_hex32(hi)..tohex(lo)
|
||||
else
|
||||
return fmt_hex32(lo)
|
||||
end
|
||||
end
|
||||
|
||||
local function prefer_bfx(sf, uns, imms, immr)
|
||||
if imms < immr or imms == 31 or imms == 63 then
|
||||
return false
|
||||
@@ -1131,6 +1149,8 @@ local function disass_ins(ctx)
|
||||
x = 0
|
||||
elseif p == "F" then
|
||||
x = parse_fpimm8(op)
|
||||
elseif p == "G" then
|
||||
x = "#0x"..decode_fpmovi(op)
|
||||
elseif p == "g" or p == "f" or p == "x" or p == "w" or
|
||||
p == "d" or p == "s" then
|
||||
-- These are handled in D/N/M/A.
|
||||
|
||||
@@ -552,7 +552,12 @@ local recdepth = 0
|
||||
local function fmterr(err, info)
|
||||
if type(err) == "number" then
|
||||
if type(info) == "function" then info = fmtfunc(info) end
|
||||
err = format(vmdef.traceerr[err], info)
|
||||
local fmt = vmdef.traceerr[err]
|
||||
if fmt == "NYI: bytecode %s" then
|
||||
local oidx = 6 * info
|
||||
info = sub(vmdef.bcnames, oidx+1, oidx+6)
|
||||
end
|
||||
err = format(fmt, info)
|
||||
end
|
||||
return err
|
||||
end
|
||||
|
||||
@@ -227,9 +227,7 @@ local function prof_finish()
|
||||
local samples = prof_samples
|
||||
if samples == 0 then
|
||||
if prof_raw ~= true then out:write("[No samples collected]\n") end
|
||||
return
|
||||
end
|
||||
if prof_ann then
|
||||
elseif prof_ann then
|
||||
prof_annotate(prof_count1, samples)
|
||||
else
|
||||
prof_top(prof_count1, prof_count2, samples, "")
|
||||
|
||||
@@ -62,7 +62,7 @@ local jit = require("jit")
|
||||
local jutil = require("jit.util")
|
||||
local vmdef = require("jit.vmdef")
|
||||
local funcinfo, traceinfo = jutil.funcinfo, jutil.traceinfo
|
||||
local type, format = type, string.format
|
||||
local type, sub, format = type, string.sub, string.format
|
||||
local stdout, stderr = io.stdout, io.stderr
|
||||
|
||||
-- Active flag and output file handle.
|
||||
@@ -89,7 +89,12 @@ end
|
||||
local function fmterr(err, info)
|
||||
if type(err) == "number" then
|
||||
if type(info) == "function" then info = fmtfunc(info) end
|
||||
err = format(vmdef.traceerr[err], info)
|
||||
local fmt = vmdef.traceerr[err]
|
||||
if fmt == "NYI: bytecode %s" then
|
||||
local oidx = 6 * info
|
||||
info = sub(vmdef.bcnames, oidx+1, oidx+6)
|
||||
end
|
||||
err = format(fmt, info)
|
||||
end
|
||||
return err
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-- This is a generated file. DO NOT EDIT!
|
||||
|
||||
assert(require("jit").version == "LuaJIT 2.1.1710088188", "LuaJIT core/library version mismatch")
|
||||
assert(require("jit").version == "LuaJIT 2.1.1734355927", "LuaJIT core/library version mismatch")
|
||||
|
||||
return {
|
||||
|
||||
@@ -136,7 +136,7 @@ traceerr = {
|
||||
"too many snapshots",
|
||||
"blacklisted",
|
||||
"retry recording",
|
||||
"NYI: bytecode %d",
|
||||
"NYI: bytecode %s",
|
||||
"leaving loop in root trace",
|
||||
"inner loop in root trace",
|
||||
"loop unroll limit reached",
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -30,9 +30,9 @@
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#define LUAJIT_VERSION "LuaJIT 2.1.1710088188"
|
||||
#define LUAJIT_VERSION "LuaJIT 2.1.1734355927"
|
||||
#define LUAJIT_VERSION_NUM 20199 /* Deprecated. */
|
||||
#define LUAJIT_VERSION_SYM luaJIT_version_2_1_1710088188
|
||||
#define LUAJIT_VERSION_SYM luaJIT_version_2_1_1734355927
|
||||
#define LUAJIT_COPYRIGHT "Copyright (C) 2005-2023 Mike Pall"
|
||||
#define LUAJIT_URL "https://luajit.org/"
|
||||
|
||||
|
||||
@@ -439,24 +439,12 @@ typedef struct
|
||||
{
|
||||
mach_header; uint32_t reserved;
|
||||
} mach_header_64;
|
||||
typedef struct {
|
||||
uint32_t cmd, cmdsize;
|
||||
char segname[16];
|
||||
uint32_t vmaddr, vmsize, fileoff, filesize;
|
||||
uint32_t maxprot, initprot, nsects, flags;
|
||||
} mach_segment_command;
|
||||
typedef struct {
|
||||
uint32_t cmd, cmdsize;
|
||||
char segname[16];
|
||||
uint64_t vmaddr, vmsize, fileoff, filesize;
|
||||
uint32_t maxprot, initprot, nsects, flags;
|
||||
} mach_segment_command_64;
|
||||
typedef struct {
|
||||
char sectname[16], segname[16];
|
||||
uint32_t addr, size;
|
||||
uint32_t offset, align, reloff, nreloc, flags;
|
||||
uint32_t reserved1, reserved2;
|
||||
} mach_section;
|
||||
typedef struct {
|
||||
char sectname[16], segname[16];
|
||||
uint64_t addr, size;
|
||||
@@ -466,139 +454,64 @@ typedef struct {
|
||||
typedef struct {
|
||||
uint32_t cmd, cmdsize, symoff, nsyms, stroff, strsize;
|
||||
} mach_symtab_command;
|
||||
typedef struct {
|
||||
int32_t strx;
|
||||
uint8_t type, sect;
|
||||
int16_t desc;
|
||||
uint32_t value;
|
||||
} mach_nlist;
|
||||
typedef struct {
|
||||
int32_t strx;
|
||||
uint8_t type, sect;
|
||||
uint16_t desc;
|
||||
uint64_t value;
|
||||
} mach_nlist_64;
|
||||
typedef struct
|
||||
{
|
||||
int32_t magic, nfat_arch;
|
||||
} mach_fat_header;
|
||||
typedef struct
|
||||
{
|
||||
int32_t cputype, cpusubtype, offset, size, align;
|
||||
} mach_fat_arch;
|
||||
typedef struct {
|
||||
struct {
|
||||
mach_header hdr;
|
||||
mach_segment_command seg;
|
||||
mach_section sec;
|
||||
mach_symtab_command sym;
|
||||
} arch[1];
|
||||
mach_nlist sym_entry;
|
||||
uint8_t space[4096];
|
||||
} mach_obj;
|
||||
typedef struct {
|
||||
struct {
|
||||
mach_header_64 hdr;
|
||||
mach_segment_command_64 seg;
|
||||
mach_section_64 sec;
|
||||
mach_symtab_command sym;
|
||||
} arch[1];
|
||||
mach_header_64 hdr;
|
||||
mach_segment_command_64 seg;
|
||||
mach_section_64 sec;
|
||||
mach_symtab_command sym;
|
||||
mach_nlist_64 sym_entry;
|
||||
uint8_t space[4096];
|
||||
} mach_obj_64;
|
||||
typedef struct {
|
||||
mach_fat_header fat;
|
||||
mach_fat_arch fat_arch[2];
|
||||
struct {
|
||||
mach_header hdr;
|
||||
mach_segment_command seg;
|
||||
mach_section sec;
|
||||
mach_symtab_command sym;
|
||||
} arch[2];
|
||||
mach_nlist sym_entry;
|
||||
uint8_t space[4096];
|
||||
} mach_fat_obj;
|
||||
typedef struct {
|
||||
mach_fat_header fat;
|
||||
mach_fat_arch fat_arch[2];
|
||||
struct {
|
||||
mach_header_64 hdr;
|
||||
mach_segment_command_64 seg;
|
||||
mach_section_64 sec;
|
||||
mach_symtab_command sym;
|
||||
} arch[2];
|
||||
mach_nlist_64 sym_entry;
|
||||
uint8_t space[4096];
|
||||
} mach_fat_obj_64;
|
||||
]]
|
||||
local symname = '_'..LJBC_PREFIX..ctx.modname
|
||||
local isfat, is64, align, mobj = false, false, 4, "mach_obj"
|
||||
if ctx.arch == "x64" then
|
||||
is64, align, mobj = true, 8, "mach_obj_64"
|
||||
elseif ctx.arch == "arm" then
|
||||
isfat, mobj = true, "mach_fat_obj"
|
||||
elseif ctx.arch == "arm64" then
|
||||
is64, align, isfat, mobj = true, 8, true, "mach_fat_obj_64"
|
||||
else
|
||||
check(ctx.arch == "x86", "unsupported architecture for OSX")
|
||||
local cputype, cpusubtype = 0x01000007, 3
|
||||
if ctx.arch ~= "x64" then
|
||||
check(ctx.arch == "arm64", "unsupported architecture for OSX")
|
||||
cputype, cpusubtype = 0x0100000c, 0
|
||||
end
|
||||
local function aligned(v, a) return bit.band(v+a-1, -a) end
|
||||
local be32 = bit.bswap -- Mach-O FAT is BE, supported archs are LE.
|
||||
|
||||
-- Create Mach-O object and fill in header.
|
||||
local o = ffi.new(mobj)
|
||||
local mach_size = aligned(ffi.offsetof(o, "space")+#symname+2, align)
|
||||
local cputype = ({ x86={7}, x64={0x01000007}, arm={7,12}, arm64={0x01000007,0x0100000c} })[ctx.arch]
|
||||
local cpusubtype = ({ x86={3}, x64={3}, arm={3,9}, arm64={3,0} })[ctx.arch]
|
||||
if isfat then
|
||||
o.fat.magic = be32(0xcafebabe)
|
||||
o.fat.nfat_arch = be32(#cpusubtype)
|
||||
end
|
||||
local o = ffi.new("mach_obj_64")
|
||||
local mach_size = aligned(ffi.offsetof(o, "space")+#symname+2, 8)
|
||||
|
||||
-- Fill in sections and symbols.
|
||||
for i=0,#cpusubtype-1 do
|
||||
local ofs = 0
|
||||
if isfat then
|
||||
local a = o.fat_arch[i]
|
||||
a.cputype = be32(cputype[i+1])
|
||||
a.cpusubtype = be32(cpusubtype[i+1])
|
||||
-- Subsequent slices overlap each other to share data.
|
||||
ofs = ffi.offsetof(o, "arch") + i*ffi.sizeof(o.arch[0])
|
||||
a.offset = be32(ofs)
|
||||
a.size = be32(mach_size-ofs+#s)
|
||||
end
|
||||
local a = o.arch[i]
|
||||
a.hdr.magic = is64 and 0xfeedfacf or 0xfeedface
|
||||
a.hdr.cputype = cputype[i+1]
|
||||
a.hdr.cpusubtype = cpusubtype[i+1]
|
||||
a.hdr.filetype = 1
|
||||
a.hdr.ncmds = 2
|
||||
a.hdr.sizeofcmds = ffi.sizeof(a.seg)+ffi.sizeof(a.sec)+ffi.sizeof(a.sym)
|
||||
a.seg.cmd = is64 and 0x19 or 0x1
|
||||
a.seg.cmdsize = ffi.sizeof(a.seg)+ffi.sizeof(a.sec)
|
||||
a.seg.vmsize = #s
|
||||
a.seg.fileoff = mach_size-ofs
|
||||
a.seg.filesize = #s
|
||||
a.seg.maxprot = 1
|
||||
a.seg.initprot = 1
|
||||
a.seg.nsects = 1
|
||||
ffi.copy(a.sec.sectname, "__data")
|
||||
ffi.copy(a.sec.segname, "__DATA")
|
||||
a.sec.size = #s
|
||||
a.sec.offset = mach_size-ofs
|
||||
a.sym.cmd = 2
|
||||
a.sym.cmdsize = ffi.sizeof(a.sym)
|
||||
a.sym.symoff = ffi.offsetof(o, "sym_entry")-ofs
|
||||
a.sym.nsyms = 1
|
||||
a.sym.stroff = ffi.offsetof(o, "sym_entry")+ffi.sizeof(o.sym_entry)-ofs
|
||||
a.sym.strsize = aligned(#symname+2, align)
|
||||
end
|
||||
o.hdr.magic = 0xfeedfacf
|
||||
o.hdr.cputype = cputype
|
||||
o.hdr.cpusubtype = cpusubtype
|
||||
o.hdr.filetype = 1
|
||||
o.hdr.ncmds = 2
|
||||
o.hdr.sizeofcmds = ffi.sizeof(o.seg)+ffi.sizeof(o.sec)+ffi.sizeof(o.sym)
|
||||
o.seg.cmd = 0x19
|
||||
o.seg.cmdsize = ffi.sizeof(o.seg)+ffi.sizeof(o.sec)
|
||||
o.seg.vmsize = #s
|
||||
o.seg.fileoff = mach_size
|
||||
o.seg.filesize = #s
|
||||
o.seg.maxprot = 1
|
||||
o.seg.initprot = 1
|
||||
o.seg.nsects = 1
|
||||
ffi.copy(o.sec.sectname, "__data")
|
||||
ffi.copy(o.sec.segname, "__DATA")
|
||||
o.sec.size = #s
|
||||
o.sec.offset = mach_size
|
||||
o.sym.cmd = 2
|
||||
o.sym.cmdsize = ffi.sizeof(o.sym)
|
||||
o.sym.symoff = ffi.offsetof(o, "sym_entry")
|
||||
o.sym.nsyms = 1
|
||||
o.sym.stroff = ffi.offsetof(o, "sym_entry")+ffi.sizeof(o.sym_entry)
|
||||
o.sym.strsize = aligned(#symname+2, 8)
|
||||
o.sym_entry.type = 0xf
|
||||
o.sym_entry.sect = 1
|
||||
o.sym_entry.strx = 1
|
||||
ffi.copy(o.space+1, symname)
|
||||
|
||||
-- Write Macho-O object file.
|
||||
-- Write Mach-O object file.
|
||||
local fp = savefile(output, "wb")
|
||||
fp:write(ffi.string(o, mach_size))
|
||||
bcsave_tail(fp, output, s)
|
||||
|
||||
@@ -658,6 +658,10 @@ local map_datafp = { -- Data processing, SIMD and FP.
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{ -- 010
|
||||
shift = 0, mask = 0x81f8fc00,
|
||||
[0x100e400] = "moviDdG"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -832,6 +836,20 @@ local function parse_fpimm8(op)
|
||||
return sign * frac * 2^exp
|
||||
end
|
||||
|
||||
local function decode_fpmovi(op)
|
||||
local lo = rshift(op, 5)
|
||||
local hi = rshift(op, 9)
|
||||
lo = bor(band(lo, 1) * 0xff, band(lo, 2) * 0x7f80, band(lo, 4) * 0x3fc000,
|
||||
band(lo, 8) * 0x1fe00000)
|
||||
hi = bor(band(hi, 1) * 0xff, band(hi, 0x80) * 0x1fe,
|
||||
band(hi, 0x100) * 0xff00, band(hi, 0x200) * 0x7f8000)
|
||||
if hi ~= 0 then
|
||||
return fmt_hex32(hi)..tohex(lo)
|
||||
else
|
||||
return fmt_hex32(lo)
|
||||
end
|
||||
end
|
||||
|
||||
local function prefer_bfx(sf, uns, imms, immr)
|
||||
if imms < immr or imms == 31 or imms == 63 then
|
||||
return false
|
||||
@@ -1131,6 +1149,8 @@ local function disass_ins(ctx)
|
||||
x = 0
|
||||
elseif p == "F" then
|
||||
x = parse_fpimm8(op)
|
||||
elseif p == "G" then
|
||||
x = "#0x"..decode_fpmovi(op)
|
||||
elseif p == "g" or p == "f" or p == "x" or p == "w" or
|
||||
p == "d" or p == "s" then
|
||||
-- These are handled in D/N/M/A.
|
||||
|
||||
@@ -552,7 +552,12 @@ local recdepth = 0
|
||||
local function fmterr(err, info)
|
||||
if type(err) == "number" then
|
||||
if type(info) == "function" then info = fmtfunc(info) end
|
||||
err = format(vmdef.traceerr[err], info)
|
||||
local fmt = vmdef.traceerr[err]
|
||||
if fmt == "NYI: bytecode %s" then
|
||||
local oidx = 6 * info
|
||||
info = sub(vmdef.bcnames, oidx+1, oidx+6)
|
||||
end
|
||||
err = format(fmt, info)
|
||||
end
|
||||
return err
|
||||
end
|
||||
|
||||
@@ -227,9 +227,7 @@ local function prof_finish()
|
||||
local samples = prof_samples
|
||||
if samples == 0 then
|
||||
if prof_raw ~= true then out:write("[No samples collected]\n") end
|
||||
return
|
||||
end
|
||||
if prof_ann then
|
||||
elseif prof_ann then
|
||||
prof_annotate(prof_count1, samples)
|
||||
else
|
||||
prof_top(prof_count1, prof_count2, samples, "")
|
||||
|
||||
@@ -62,7 +62,7 @@ local jit = require("jit")
|
||||
local jutil = require("jit.util")
|
||||
local vmdef = require("jit.vmdef")
|
||||
local funcinfo, traceinfo = jutil.funcinfo, jutil.traceinfo
|
||||
local type, format = type, string.format
|
||||
local type, sub, format = type, string.sub, string.format
|
||||
local stdout, stderr = io.stdout, io.stderr
|
||||
|
||||
-- Active flag and output file handle.
|
||||
@@ -89,7 +89,12 @@ end
|
||||
local function fmterr(err, info)
|
||||
if type(err) == "number" then
|
||||
if type(info) == "function" then info = fmtfunc(info) end
|
||||
err = format(vmdef.traceerr[err], info)
|
||||
local fmt = vmdef.traceerr[err]
|
||||
if fmt == "NYI: bytecode %s" then
|
||||
local oidx = 6 * info
|
||||
info = sub(vmdef.bcnames, oidx+1, oidx+6)
|
||||
end
|
||||
err = format(fmt, info)
|
||||
end
|
||||
return err
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-- This is a generated file. DO NOT EDIT!
|
||||
|
||||
assert(require("jit").version == "LuaJIT 2.1.1710088188", "LuaJIT core/library version mismatch")
|
||||
assert(require("jit").version == "LuaJIT 2.1.1734355927", "LuaJIT core/library version mismatch")
|
||||
|
||||
return {
|
||||
|
||||
@@ -136,7 +136,7 @@ traceerr = {
|
||||
"too many snapshots",
|
||||
"blacklisted",
|
||||
"retry recording",
|
||||
"NYI: bytecode %d",
|
||||
"NYI: bytecode %s",
|
||||
"leaving loop in root trace",
|
||||
"inner loop in root trace",
|
||||
"loop unroll limit reached",
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -30,9 +30,9 @@
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#define LUAJIT_VERSION "LuaJIT 2.1.1710088188"
|
||||
#define LUAJIT_VERSION "LuaJIT 2.1.1734355927"
|
||||
#define LUAJIT_VERSION_NUM 20199 /* Deprecated. */
|
||||
#define LUAJIT_VERSION_SYM luaJIT_version_2_1_1710088188
|
||||
#define LUAJIT_VERSION_SYM luaJIT_version_2_1_1734355927
|
||||
#define LUAJIT_COPYRIGHT "Copyright (C) 2005-2023 Mike Pall"
|
||||
#define LUAJIT_URL "https://luajit.org/"
|
||||
|
||||
|
||||
@@ -439,24 +439,12 @@ typedef struct
|
||||
{
|
||||
mach_header; uint32_t reserved;
|
||||
} mach_header_64;
|
||||
typedef struct {
|
||||
uint32_t cmd, cmdsize;
|
||||
char segname[16];
|
||||
uint32_t vmaddr, vmsize, fileoff, filesize;
|
||||
uint32_t maxprot, initprot, nsects, flags;
|
||||
} mach_segment_command;
|
||||
typedef struct {
|
||||
uint32_t cmd, cmdsize;
|
||||
char segname[16];
|
||||
uint64_t vmaddr, vmsize, fileoff, filesize;
|
||||
uint32_t maxprot, initprot, nsects, flags;
|
||||
} mach_segment_command_64;
|
||||
typedef struct {
|
||||
char sectname[16], segname[16];
|
||||
uint32_t addr, size;
|
||||
uint32_t offset, align, reloff, nreloc, flags;
|
||||
uint32_t reserved1, reserved2;
|
||||
} mach_section;
|
||||
typedef struct {
|
||||
char sectname[16], segname[16];
|
||||
uint64_t addr, size;
|
||||
@@ -466,139 +454,64 @@ typedef struct {
|
||||
typedef struct {
|
||||
uint32_t cmd, cmdsize, symoff, nsyms, stroff, strsize;
|
||||
} mach_symtab_command;
|
||||
typedef struct {
|
||||
int32_t strx;
|
||||
uint8_t type, sect;
|
||||
int16_t desc;
|
||||
uint32_t value;
|
||||
} mach_nlist;
|
||||
typedef struct {
|
||||
int32_t strx;
|
||||
uint8_t type, sect;
|
||||
uint16_t desc;
|
||||
uint64_t value;
|
||||
} mach_nlist_64;
|
||||
typedef struct
|
||||
{
|
||||
int32_t magic, nfat_arch;
|
||||
} mach_fat_header;
|
||||
typedef struct
|
||||
{
|
||||
int32_t cputype, cpusubtype, offset, size, align;
|
||||
} mach_fat_arch;
|
||||
typedef struct {
|
||||
struct {
|
||||
mach_header hdr;
|
||||
mach_segment_command seg;
|
||||
mach_section sec;
|
||||
mach_symtab_command sym;
|
||||
} arch[1];
|
||||
mach_nlist sym_entry;
|
||||
uint8_t space[4096];
|
||||
} mach_obj;
|
||||
typedef struct {
|
||||
struct {
|
||||
mach_header_64 hdr;
|
||||
mach_segment_command_64 seg;
|
||||
mach_section_64 sec;
|
||||
mach_symtab_command sym;
|
||||
} arch[1];
|
||||
mach_header_64 hdr;
|
||||
mach_segment_command_64 seg;
|
||||
mach_section_64 sec;
|
||||
mach_symtab_command sym;
|
||||
mach_nlist_64 sym_entry;
|
||||
uint8_t space[4096];
|
||||
} mach_obj_64;
|
||||
typedef struct {
|
||||
mach_fat_header fat;
|
||||
mach_fat_arch fat_arch[2];
|
||||
struct {
|
||||
mach_header hdr;
|
||||
mach_segment_command seg;
|
||||
mach_section sec;
|
||||
mach_symtab_command sym;
|
||||
} arch[2];
|
||||
mach_nlist sym_entry;
|
||||
uint8_t space[4096];
|
||||
} mach_fat_obj;
|
||||
typedef struct {
|
||||
mach_fat_header fat;
|
||||
mach_fat_arch fat_arch[2];
|
||||
struct {
|
||||
mach_header_64 hdr;
|
||||
mach_segment_command_64 seg;
|
||||
mach_section_64 sec;
|
||||
mach_symtab_command sym;
|
||||
} arch[2];
|
||||
mach_nlist_64 sym_entry;
|
||||
uint8_t space[4096];
|
||||
} mach_fat_obj_64;
|
||||
]]
|
||||
local symname = '_'..LJBC_PREFIX..ctx.modname
|
||||
local isfat, is64, align, mobj = false, false, 4, "mach_obj"
|
||||
if ctx.arch == "x64" then
|
||||
is64, align, mobj = true, 8, "mach_obj_64"
|
||||
elseif ctx.arch == "arm" then
|
||||
isfat, mobj = true, "mach_fat_obj"
|
||||
elseif ctx.arch == "arm64" then
|
||||
is64, align, isfat, mobj = true, 8, true, "mach_fat_obj_64"
|
||||
else
|
||||
check(ctx.arch == "x86", "unsupported architecture for OSX")
|
||||
local cputype, cpusubtype = 0x01000007, 3
|
||||
if ctx.arch ~= "x64" then
|
||||
check(ctx.arch == "arm64", "unsupported architecture for OSX")
|
||||
cputype, cpusubtype = 0x0100000c, 0
|
||||
end
|
||||
local function aligned(v, a) return bit.band(v+a-1, -a) end
|
||||
local be32 = bit.bswap -- Mach-O FAT is BE, supported archs are LE.
|
||||
|
||||
-- Create Mach-O object and fill in header.
|
||||
local o = ffi.new(mobj)
|
||||
local mach_size = aligned(ffi.offsetof(o, "space")+#symname+2, align)
|
||||
local cputype = ({ x86={7}, x64={0x01000007}, arm={7,12}, arm64={0x01000007,0x0100000c} })[ctx.arch]
|
||||
local cpusubtype = ({ x86={3}, x64={3}, arm={3,9}, arm64={3,0} })[ctx.arch]
|
||||
if isfat then
|
||||
o.fat.magic = be32(0xcafebabe)
|
||||
o.fat.nfat_arch = be32(#cpusubtype)
|
||||
end
|
||||
local o = ffi.new("mach_obj_64")
|
||||
local mach_size = aligned(ffi.offsetof(o, "space")+#symname+2, 8)
|
||||
|
||||
-- Fill in sections and symbols.
|
||||
for i=0,#cpusubtype-1 do
|
||||
local ofs = 0
|
||||
if isfat then
|
||||
local a = o.fat_arch[i]
|
||||
a.cputype = be32(cputype[i+1])
|
||||
a.cpusubtype = be32(cpusubtype[i+1])
|
||||
-- Subsequent slices overlap each other to share data.
|
||||
ofs = ffi.offsetof(o, "arch") + i*ffi.sizeof(o.arch[0])
|
||||
a.offset = be32(ofs)
|
||||
a.size = be32(mach_size-ofs+#s)
|
||||
end
|
||||
local a = o.arch[i]
|
||||
a.hdr.magic = is64 and 0xfeedfacf or 0xfeedface
|
||||
a.hdr.cputype = cputype[i+1]
|
||||
a.hdr.cpusubtype = cpusubtype[i+1]
|
||||
a.hdr.filetype = 1
|
||||
a.hdr.ncmds = 2
|
||||
a.hdr.sizeofcmds = ffi.sizeof(a.seg)+ffi.sizeof(a.sec)+ffi.sizeof(a.sym)
|
||||
a.seg.cmd = is64 and 0x19 or 0x1
|
||||
a.seg.cmdsize = ffi.sizeof(a.seg)+ffi.sizeof(a.sec)
|
||||
a.seg.vmsize = #s
|
||||
a.seg.fileoff = mach_size-ofs
|
||||
a.seg.filesize = #s
|
||||
a.seg.maxprot = 1
|
||||
a.seg.initprot = 1
|
||||
a.seg.nsects = 1
|
||||
ffi.copy(a.sec.sectname, "__data")
|
||||
ffi.copy(a.sec.segname, "__DATA")
|
||||
a.sec.size = #s
|
||||
a.sec.offset = mach_size-ofs
|
||||
a.sym.cmd = 2
|
||||
a.sym.cmdsize = ffi.sizeof(a.sym)
|
||||
a.sym.symoff = ffi.offsetof(o, "sym_entry")-ofs
|
||||
a.sym.nsyms = 1
|
||||
a.sym.stroff = ffi.offsetof(o, "sym_entry")+ffi.sizeof(o.sym_entry)-ofs
|
||||
a.sym.strsize = aligned(#symname+2, align)
|
||||
end
|
||||
o.hdr.magic = 0xfeedfacf
|
||||
o.hdr.cputype = cputype
|
||||
o.hdr.cpusubtype = cpusubtype
|
||||
o.hdr.filetype = 1
|
||||
o.hdr.ncmds = 2
|
||||
o.hdr.sizeofcmds = ffi.sizeof(o.seg)+ffi.sizeof(o.sec)+ffi.sizeof(o.sym)
|
||||
o.seg.cmd = 0x19
|
||||
o.seg.cmdsize = ffi.sizeof(o.seg)+ffi.sizeof(o.sec)
|
||||
o.seg.vmsize = #s
|
||||
o.seg.fileoff = mach_size
|
||||
o.seg.filesize = #s
|
||||
o.seg.maxprot = 1
|
||||
o.seg.initprot = 1
|
||||
o.seg.nsects = 1
|
||||
ffi.copy(o.sec.sectname, "__data")
|
||||
ffi.copy(o.sec.segname, "__DATA")
|
||||
o.sec.size = #s
|
||||
o.sec.offset = mach_size
|
||||
o.sym.cmd = 2
|
||||
o.sym.cmdsize = ffi.sizeof(o.sym)
|
||||
o.sym.symoff = ffi.offsetof(o, "sym_entry")
|
||||
o.sym.nsyms = 1
|
||||
o.sym.stroff = ffi.offsetof(o, "sym_entry")+ffi.sizeof(o.sym_entry)
|
||||
o.sym.strsize = aligned(#symname+2, 8)
|
||||
o.sym_entry.type = 0xf
|
||||
o.sym_entry.sect = 1
|
||||
o.sym_entry.strx = 1
|
||||
ffi.copy(o.space+1, symname)
|
||||
|
||||
-- Write Macho-O object file.
|
||||
-- Write Mach-O object file.
|
||||
local fp = savefile(output, "wb")
|
||||
fp:write(ffi.string(o, mach_size))
|
||||
bcsave_tail(fp, output, s)
|
||||
|
||||
@@ -658,6 +658,10 @@ local map_datafp = { -- Data processing, SIMD and FP.
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{ -- 010
|
||||
shift = 0, mask = 0x81f8fc00,
|
||||
[0x100e400] = "moviDdG"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -832,6 +836,20 @@ local function parse_fpimm8(op)
|
||||
return sign * frac * 2^exp
|
||||
end
|
||||
|
||||
local function decode_fpmovi(op)
|
||||
local lo = rshift(op, 5)
|
||||
local hi = rshift(op, 9)
|
||||
lo = bor(band(lo, 1) * 0xff, band(lo, 2) * 0x7f80, band(lo, 4) * 0x3fc000,
|
||||
band(lo, 8) * 0x1fe00000)
|
||||
hi = bor(band(hi, 1) * 0xff, band(hi, 0x80) * 0x1fe,
|
||||
band(hi, 0x100) * 0xff00, band(hi, 0x200) * 0x7f8000)
|
||||
if hi ~= 0 then
|
||||
return fmt_hex32(hi)..tohex(lo)
|
||||
else
|
||||
return fmt_hex32(lo)
|
||||
end
|
||||
end
|
||||
|
||||
local function prefer_bfx(sf, uns, imms, immr)
|
||||
if imms < immr or imms == 31 or imms == 63 then
|
||||
return false
|
||||
@@ -1131,6 +1149,8 @@ local function disass_ins(ctx)
|
||||
x = 0
|
||||
elseif p == "F" then
|
||||
x = parse_fpimm8(op)
|
||||
elseif p == "G" then
|
||||
x = "#0x"..decode_fpmovi(op)
|
||||
elseif p == "g" or p == "f" or p == "x" or p == "w" or
|
||||
p == "d" or p == "s" then
|
||||
-- These are handled in D/N/M/A.
|
||||
|
||||
@@ -552,7 +552,12 @@ local recdepth = 0
|
||||
local function fmterr(err, info)
|
||||
if type(err) == "number" then
|
||||
if type(info) == "function" then info = fmtfunc(info) end
|
||||
err = format(vmdef.traceerr[err], info)
|
||||
local fmt = vmdef.traceerr[err]
|
||||
if fmt == "NYI: bytecode %s" then
|
||||
local oidx = 6 * info
|
||||
info = sub(vmdef.bcnames, oidx+1, oidx+6)
|
||||
end
|
||||
err = format(fmt, info)
|
||||
end
|
||||
return err
|
||||
end
|
||||
|
||||
@@ -227,9 +227,7 @@ local function prof_finish()
|
||||
local samples = prof_samples
|
||||
if samples == 0 then
|
||||
if prof_raw ~= true then out:write("[No samples collected]\n") end
|
||||
return
|
||||
end
|
||||
if prof_ann then
|
||||
elseif prof_ann then
|
||||
prof_annotate(prof_count1, samples)
|
||||
else
|
||||
prof_top(prof_count1, prof_count2, samples, "")
|
||||
|
||||
@@ -62,7 +62,7 @@ local jit = require("jit")
|
||||
local jutil = require("jit.util")
|
||||
local vmdef = require("jit.vmdef")
|
||||
local funcinfo, traceinfo = jutil.funcinfo, jutil.traceinfo
|
||||
local type, format = type, string.format
|
||||
local type, sub, format = type, string.sub, string.format
|
||||
local stdout, stderr = io.stdout, io.stderr
|
||||
|
||||
-- Active flag and output file handle.
|
||||
@@ -89,7 +89,12 @@ end
|
||||
local function fmterr(err, info)
|
||||
if type(err) == "number" then
|
||||
if type(info) == "function" then info = fmtfunc(info) end
|
||||
err = format(vmdef.traceerr[err], info)
|
||||
local fmt = vmdef.traceerr[err]
|
||||
if fmt == "NYI: bytecode %s" then
|
||||
local oidx = 6 * info
|
||||
info = sub(vmdef.bcnames, oidx+1, oidx+6)
|
||||
end
|
||||
err = format(fmt, info)
|
||||
end
|
||||
return err
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-- This is a generated file. DO NOT EDIT!
|
||||
|
||||
assert(require("jit").version == "LuaJIT 2.1.1710088188", "LuaJIT core/library version mismatch")
|
||||
assert(require("jit").version == "LuaJIT 2.1.1734355927", "LuaJIT core/library version mismatch")
|
||||
|
||||
return {
|
||||
|
||||
@@ -136,7 +136,7 @@ traceerr = {
|
||||
"too many snapshots",
|
||||
"blacklisted",
|
||||
"retry recording",
|
||||
"NYI: bytecode %d",
|
||||
"NYI: bytecode %s",
|
||||
"leaving loop in root trace",
|
||||
"inner loop in root trace",
|
||||
"loop unroll limit reached",
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -30,9 +30,9 @@
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#define LUAJIT_VERSION "LuaJIT 2.1.1710088188"
|
||||
#define LUAJIT_VERSION "LuaJIT 2.1.1734355927"
|
||||
#define LUAJIT_VERSION_NUM 20199 /* Deprecated. */
|
||||
#define LUAJIT_VERSION_SYM luaJIT_version_2_1_1710088188
|
||||
#define LUAJIT_VERSION_SYM luaJIT_version_2_1_1734355927
|
||||
#define LUAJIT_COPYRIGHT "Copyright (C) 2005-2023 Mike Pall"
|
||||
#define LUAJIT_URL "https://luajit.org/"
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ operations.
|
||||
</p>
|
||||
<p>
|
||||
The string buffer library also includes a high-performance
|
||||
<a href="serialize">serializer</a> for Lua objects.
|
||||
<a href="#serialize">serializer</a> for Lua objects.
|
||||
</p>
|
||||
|
||||
<h2 id="use">Using the String Buffer Library</h2>
|
||||
@@ -588,9 +588,9 @@ num → 0x07 double.L
|
||||
tab → 0x08 // Empty table
|
||||
| 0x09 h.U h*{object object} // Key/value hash
|
||||
| 0x0a a.U a*object // 0-based array
|
||||
| 0x0b a.U a*object h.U h*{object object} // Mixed
|
||||
| 0x0b a.U h.U a*object h*{object object} // Mixed
|
||||
| 0x0c a.U (a-1)*object // 1-based array
|
||||
| 0x0d a.U (a-1)*object h.U h*{object object} // Mixed
|
||||
| 0x0d a.U h.U (a-1)*object h*{object object} // Mixed
|
||||
tab_mt → 0x0e (index-1).U tab // Metatable dict entry
|
||||
|
||||
int64 → 0x10 int.L // FFI int64_t
|
||||
|
||||
@@ -440,6 +440,19 @@ If you don't do this, the default Lua number → <tt>double</tt>
|
||||
conversion rule applies. A vararg C function expecting an integer
|
||||
will see a garbled or uninitialized value.
|
||||
</p>
|
||||
<p>
|
||||
Note: this is the only place where creating a boxed scalar number type is
|
||||
actually useful. <b>Never use <tt>ffi.new("int")</tt>, <tt>ffi.new("float")</tt>
|
||||
etc. anywhere else!</b>
|
||||
</p>
|
||||
<p style="font-size: 8pt;">
|
||||
Ditto for <tt>ffi.cast()</tt>. Explicitly boxing scalars <b>does not</b>
|
||||
improve performance or force <tt>int</tt> or <tt>float</tt> arithmetic! It
|
||||
just adds costly boxing, unboxing and conversions steps. And it may lead
|
||||
to surprise results, because
|
||||
<a href="#cdata_arith">cdata arithmetic on scalar numbers</a>
|
||||
is always performed on 64 bit integers.
|
||||
</p>
|
||||
|
||||
<h2 id="init">Initializers</h2>
|
||||
<p>
|
||||
|
||||
@@ -265,7 +265,7 @@ and let the GC do its work.
|
||||
LuaJIT uses a Tausworthe PRNG with period 2^223 to implement
|
||||
<tt>math.random()</tt> and <tt>math.randomseed()</tt>. The quality of
|
||||
the PRNG results is much superior compared to the standard Lua
|
||||
implementation, which uses the platform-specific ANSI rand().
|
||||
implementation, which uses the platform-specific ANSI <tt>rand()</tt>.
|
||||
</p>
|
||||
<p>
|
||||
The PRNG generates the same sequences from the same seeds on all
|
||||
@@ -276,6 +276,10 @@ It's correctly scaled up and rounded for <tt>math.random(n [,m])</tt> to
|
||||
preserve uniformity.
|
||||
</p>
|
||||
<p>
|
||||
Call <tt>math.randomseed()</tt> without any arguments to seed it from
|
||||
system entropy.
|
||||
</p>
|
||||
<p>
|
||||
Important: Neither this nor any other PRNG based on the simplistic
|
||||
<tt>math.random()</tt> API is suitable for cryptographic use.
|
||||
</p>
|
||||
|
||||
@@ -299,6 +299,9 @@ endif
|
||||
ifneq (,$(LMULTILIB))
|
||||
TARGET_XCFLAGS+= -DLUA_LMULTILIB=\"$(LMULTILIB)\"
|
||||
endif
|
||||
ifneq (,$(INSTALL_LJLIBD))
|
||||
TARGET_XCFLAGS+= -DLUA_LJDIR=\"$(INSTALL_LJLIBD)\"
|
||||
endif
|
||||
|
||||
##############################################################################
|
||||
# Target system detection.
|
||||
@@ -320,13 +323,13 @@ ifeq (Darwin,$(TARGET_SYS))
|
||||
endif
|
||||
TARGET_STRIP+= -x
|
||||
TARGET_XCFLAGS+= -DLUAJIT_UNWIND_EXTERNAL
|
||||
TARGET_XSHLDFLAGS= -dynamiclib -single_module -undefined dynamic_lookup -fPIC
|
||||
TARGET_XSHLDFLAGS= -dynamiclib -undefined dynamic_lookup -fPIC
|
||||
TARGET_DYNXLDOPTS=
|
||||
TARGET_XSHLDFLAGS+= -install_name $(TARGET_DYLIBPATH) -compatibility_version $(MAJVER).$(MINVER) -current_version $(MAJVER).$(MINVER).255
|
||||
else
|
||||
ifeq (iOS,$(TARGET_SYS))
|
||||
TARGET_STRIP+= -x
|
||||
TARGET_XSHLDFLAGS= -dynamiclib -single_module -undefined dynamic_lookup -fPIC
|
||||
TARGET_XSHLDFLAGS= -dynamiclib -undefined dynamic_lookup -fPIC
|
||||
TARGET_DYNXLDOPTS=
|
||||
TARGET_XSHLDFLAGS+= -install_name $(TARGET_DYLIBPATH) -compatibility_version $(MAJVER).$(MINVER) -current_version $(MAJVER).$(MINVER).255
|
||||
ifeq (arm64,$(TARGET_LJARCH))
|
||||
|
||||
@@ -32,7 +32,8 @@ lib_jit.o: lib_jit.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
|
||||
lj_target.h lj_target_*.h lj_trace.h lj_dispatch.h lj_traceerr.h \
|
||||
lj_vm.h lj_vmevent.h lj_lib.h luajit.h lj_libdef.h
|
||||
lib_math.o: lib_math.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
|
||||
lj_def.h lj_arch.h lj_lib.h lj_vm.h lj_prng.h lj_libdef.h
|
||||
lj_def.h lj_arch.h lj_err.h lj_errmsg.h lj_lib.h lj_vm.h lj_prng.h \
|
||||
lj_libdef.h
|
||||
lib_os.o: lib_os.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
|
||||
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_lib.h \
|
||||
lj_libdef.h
|
||||
@@ -97,7 +98,7 @@ lj_crecord.o: lj_crecord.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_cdata.h lj_cparse.h lj_cconv.h lj_carith.h lj_clib.h lj_ccall.h \
|
||||
lj_ff.h lj_ffdef.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \
|
||||
lj_dispatch.h lj_traceerr.h lj_record.h lj_ffrecord.h lj_snap.h \
|
||||
lj_crecord.h lj_strfmt.h
|
||||
lj_crecord.h lj_strfmt.h lj_strscan.h
|
||||
lj_ctype.o: lj_ctype.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_strfmt.h lj_ctype.h \
|
||||
lj_ccallback.h lj_buf.h
|
||||
|
||||
@@ -339,6 +339,10 @@ void emit_asm(BuildCtx *ctx)
|
||||
fprintf(ctx->fp, "\t.ident \"%s\"\n", ctx->dasm_ident);
|
||||
break;
|
||||
case BUILD_machasm:
|
||||
#if defined(__apple_build_version__) && __apple_build_version__ >= 15000000 && __apple_build_version__ < 15000300
|
||||
/* Workaround for XCode 15.0 - 15.2. */
|
||||
fprintf(ctx->fp, "\t.subsections_via_symbols\n");
|
||||
#endif
|
||||
fprintf(ctx->fp,
|
||||
"\t.cstring\n"
|
||||
"\t.ascii \"%s\\0\"\n", ctx->dasm_ident);
|
||||
|
||||
+35
-122
@@ -439,24 +439,12 @@ typedef struct
|
||||
{
|
||||
mach_header; uint32_t reserved;
|
||||
} mach_header_64;
|
||||
typedef struct {
|
||||
uint32_t cmd, cmdsize;
|
||||
char segname[16];
|
||||
uint32_t vmaddr, vmsize, fileoff, filesize;
|
||||
uint32_t maxprot, initprot, nsects, flags;
|
||||
} mach_segment_command;
|
||||
typedef struct {
|
||||
uint32_t cmd, cmdsize;
|
||||
char segname[16];
|
||||
uint64_t vmaddr, vmsize, fileoff, filesize;
|
||||
uint32_t maxprot, initprot, nsects, flags;
|
||||
} mach_segment_command_64;
|
||||
typedef struct {
|
||||
char sectname[16], segname[16];
|
||||
uint32_t addr, size;
|
||||
uint32_t offset, align, reloff, nreloc, flags;
|
||||
uint32_t reserved1, reserved2;
|
||||
} mach_section;
|
||||
typedef struct {
|
||||
char sectname[16], segname[16];
|
||||
uint64_t addr, size;
|
||||
@@ -466,139 +454,64 @@ typedef struct {
|
||||
typedef struct {
|
||||
uint32_t cmd, cmdsize, symoff, nsyms, stroff, strsize;
|
||||
} mach_symtab_command;
|
||||
typedef struct {
|
||||
int32_t strx;
|
||||
uint8_t type, sect;
|
||||
int16_t desc;
|
||||
uint32_t value;
|
||||
} mach_nlist;
|
||||
typedef struct {
|
||||
int32_t strx;
|
||||
uint8_t type, sect;
|
||||
uint16_t desc;
|
||||
uint64_t value;
|
||||
} mach_nlist_64;
|
||||
typedef struct
|
||||
{
|
||||
int32_t magic, nfat_arch;
|
||||
} mach_fat_header;
|
||||
typedef struct
|
||||
{
|
||||
int32_t cputype, cpusubtype, offset, size, align;
|
||||
} mach_fat_arch;
|
||||
typedef struct {
|
||||
struct {
|
||||
mach_header hdr;
|
||||
mach_segment_command seg;
|
||||
mach_section sec;
|
||||
mach_symtab_command sym;
|
||||
} arch[1];
|
||||
mach_nlist sym_entry;
|
||||
uint8_t space[4096];
|
||||
} mach_obj;
|
||||
typedef struct {
|
||||
struct {
|
||||
mach_header_64 hdr;
|
||||
mach_segment_command_64 seg;
|
||||
mach_section_64 sec;
|
||||
mach_symtab_command sym;
|
||||
} arch[1];
|
||||
mach_header_64 hdr;
|
||||
mach_segment_command_64 seg;
|
||||
mach_section_64 sec;
|
||||
mach_symtab_command sym;
|
||||
mach_nlist_64 sym_entry;
|
||||
uint8_t space[4096];
|
||||
} mach_obj_64;
|
||||
typedef struct {
|
||||
mach_fat_header fat;
|
||||
mach_fat_arch fat_arch[2];
|
||||
struct {
|
||||
mach_header hdr;
|
||||
mach_segment_command seg;
|
||||
mach_section sec;
|
||||
mach_symtab_command sym;
|
||||
} arch[2];
|
||||
mach_nlist sym_entry;
|
||||
uint8_t space[4096];
|
||||
} mach_fat_obj;
|
||||
typedef struct {
|
||||
mach_fat_header fat;
|
||||
mach_fat_arch fat_arch[2];
|
||||
struct {
|
||||
mach_header_64 hdr;
|
||||
mach_segment_command_64 seg;
|
||||
mach_section_64 sec;
|
||||
mach_symtab_command sym;
|
||||
} arch[2];
|
||||
mach_nlist_64 sym_entry;
|
||||
uint8_t space[4096];
|
||||
} mach_fat_obj_64;
|
||||
]]
|
||||
local symname = '_'..LJBC_PREFIX..ctx.modname
|
||||
local isfat, is64, align, mobj = false, false, 4, "mach_obj"
|
||||
if ctx.arch == "x64" then
|
||||
is64, align, mobj = true, 8, "mach_obj_64"
|
||||
elseif ctx.arch == "arm" then
|
||||
isfat, mobj = true, "mach_fat_obj"
|
||||
elseif ctx.arch == "arm64" then
|
||||
is64, align, isfat, mobj = true, 8, true, "mach_fat_obj_64"
|
||||
else
|
||||
check(ctx.arch == "x86", "unsupported architecture for OSX")
|
||||
local cputype, cpusubtype = 0x01000007, 3
|
||||
if ctx.arch ~= "x64" then
|
||||
check(ctx.arch == "arm64", "unsupported architecture for OSX")
|
||||
cputype, cpusubtype = 0x0100000c, 0
|
||||
end
|
||||
local function aligned(v, a) return bit.band(v+a-1, -a) end
|
||||
local be32 = bit.bswap -- Mach-O FAT is BE, supported archs are LE.
|
||||
|
||||
-- Create Mach-O object and fill in header.
|
||||
local o = ffi.new(mobj)
|
||||
local mach_size = aligned(ffi.offsetof(o, "space")+#symname+2, align)
|
||||
local cputype = ({ x86={7}, x64={0x01000007}, arm={7,12}, arm64={0x01000007,0x0100000c} })[ctx.arch]
|
||||
local cpusubtype = ({ x86={3}, x64={3}, arm={3,9}, arm64={3,0} })[ctx.arch]
|
||||
if isfat then
|
||||
o.fat.magic = be32(0xcafebabe)
|
||||
o.fat.nfat_arch = be32(#cpusubtype)
|
||||
end
|
||||
local o = ffi.new("mach_obj_64")
|
||||
local mach_size = aligned(ffi.offsetof(o, "space")+#symname+2, 8)
|
||||
|
||||
-- Fill in sections and symbols.
|
||||
for i=0,#cpusubtype-1 do
|
||||
local ofs = 0
|
||||
if isfat then
|
||||
local a = o.fat_arch[i]
|
||||
a.cputype = be32(cputype[i+1])
|
||||
a.cpusubtype = be32(cpusubtype[i+1])
|
||||
-- Subsequent slices overlap each other to share data.
|
||||
ofs = ffi.offsetof(o, "arch") + i*ffi.sizeof(o.arch[0])
|
||||
a.offset = be32(ofs)
|
||||
a.size = be32(mach_size-ofs+#s)
|
||||
end
|
||||
local a = o.arch[i]
|
||||
a.hdr.magic = is64 and 0xfeedfacf or 0xfeedface
|
||||
a.hdr.cputype = cputype[i+1]
|
||||
a.hdr.cpusubtype = cpusubtype[i+1]
|
||||
a.hdr.filetype = 1
|
||||
a.hdr.ncmds = 2
|
||||
a.hdr.sizeofcmds = ffi.sizeof(a.seg)+ffi.sizeof(a.sec)+ffi.sizeof(a.sym)
|
||||
a.seg.cmd = is64 and 0x19 or 0x1
|
||||
a.seg.cmdsize = ffi.sizeof(a.seg)+ffi.sizeof(a.sec)
|
||||
a.seg.vmsize = #s
|
||||
a.seg.fileoff = mach_size-ofs
|
||||
a.seg.filesize = #s
|
||||
a.seg.maxprot = 1
|
||||
a.seg.initprot = 1
|
||||
a.seg.nsects = 1
|
||||
ffi.copy(a.sec.sectname, "__data")
|
||||
ffi.copy(a.sec.segname, "__DATA")
|
||||
a.sec.size = #s
|
||||
a.sec.offset = mach_size-ofs
|
||||
a.sym.cmd = 2
|
||||
a.sym.cmdsize = ffi.sizeof(a.sym)
|
||||
a.sym.symoff = ffi.offsetof(o, "sym_entry")-ofs
|
||||
a.sym.nsyms = 1
|
||||
a.sym.stroff = ffi.offsetof(o, "sym_entry")+ffi.sizeof(o.sym_entry)-ofs
|
||||
a.sym.strsize = aligned(#symname+2, align)
|
||||
end
|
||||
o.hdr.magic = 0xfeedfacf
|
||||
o.hdr.cputype = cputype
|
||||
o.hdr.cpusubtype = cpusubtype
|
||||
o.hdr.filetype = 1
|
||||
o.hdr.ncmds = 2
|
||||
o.hdr.sizeofcmds = ffi.sizeof(o.seg)+ffi.sizeof(o.sec)+ffi.sizeof(o.sym)
|
||||
o.seg.cmd = 0x19
|
||||
o.seg.cmdsize = ffi.sizeof(o.seg)+ffi.sizeof(o.sec)
|
||||
o.seg.vmsize = #s
|
||||
o.seg.fileoff = mach_size
|
||||
o.seg.filesize = #s
|
||||
o.seg.maxprot = 1
|
||||
o.seg.initprot = 1
|
||||
o.seg.nsects = 1
|
||||
ffi.copy(o.sec.sectname, "__data")
|
||||
ffi.copy(o.sec.segname, "__DATA")
|
||||
o.sec.size = #s
|
||||
o.sec.offset = mach_size
|
||||
o.sym.cmd = 2
|
||||
o.sym.cmdsize = ffi.sizeof(o.sym)
|
||||
o.sym.symoff = ffi.offsetof(o, "sym_entry")
|
||||
o.sym.nsyms = 1
|
||||
o.sym.stroff = ffi.offsetof(o, "sym_entry")+ffi.sizeof(o.sym_entry)
|
||||
o.sym.strsize = aligned(#symname+2, 8)
|
||||
o.sym_entry.type = 0xf
|
||||
o.sym_entry.sect = 1
|
||||
o.sym_entry.strx = 1
|
||||
ffi.copy(o.space+1, symname)
|
||||
|
||||
-- Write Macho-O object file.
|
||||
-- Write Mach-O object file.
|
||||
local fp = savefile(output, "wb")
|
||||
fp:write(ffi.string(o, mach_size))
|
||||
bcsave_tail(fp, output, s)
|
||||
|
||||
@@ -658,6 +658,10 @@ local map_datafp = { -- Data processing, SIMD and FP.
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{ -- 010
|
||||
shift = 0, mask = 0x81f8fc00,
|
||||
[0x100e400] = "moviDdG"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -832,6 +836,20 @@ local function parse_fpimm8(op)
|
||||
return sign * frac * 2^exp
|
||||
end
|
||||
|
||||
local function decode_fpmovi(op)
|
||||
local lo = rshift(op, 5)
|
||||
local hi = rshift(op, 9)
|
||||
lo = bor(band(lo, 1) * 0xff, band(lo, 2) * 0x7f80, band(lo, 4) * 0x3fc000,
|
||||
band(lo, 8) * 0x1fe00000)
|
||||
hi = bor(band(hi, 1) * 0xff, band(hi, 0x80) * 0x1fe,
|
||||
band(hi, 0x100) * 0xff00, band(hi, 0x200) * 0x7f8000)
|
||||
if hi ~= 0 then
|
||||
return fmt_hex32(hi)..tohex(lo)
|
||||
else
|
||||
return fmt_hex32(lo)
|
||||
end
|
||||
end
|
||||
|
||||
local function prefer_bfx(sf, uns, imms, immr)
|
||||
if imms < immr or imms == 31 or imms == 63 then
|
||||
return false
|
||||
@@ -1131,6 +1149,8 @@ local function disass_ins(ctx)
|
||||
x = 0
|
||||
elseif p == "F" then
|
||||
x = parse_fpimm8(op)
|
||||
elseif p == "G" then
|
||||
x = "#0x"..decode_fpmovi(op)
|
||||
elseif p == "g" or p == "f" or p == "x" or p == "w" or
|
||||
p == "d" or p == "s" then
|
||||
-- These are handled in D/N/M/A.
|
||||
|
||||
@@ -552,7 +552,12 @@ local recdepth = 0
|
||||
local function fmterr(err, info)
|
||||
if type(err) == "number" then
|
||||
if type(info) == "function" then info = fmtfunc(info) end
|
||||
err = format(vmdef.traceerr[err], info)
|
||||
local fmt = vmdef.traceerr[err]
|
||||
if fmt == "NYI: bytecode %s" then
|
||||
local oidx = 6 * info
|
||||
info = sub(vmdef.bcnames, oidx+1, oidx+6)
|
||||
end
|
||||
err = format(fmt, info)
|
||||
end
|
||||
return err
|
||||
end
|
||||
|
||||
@@ -227,9 +227,7 @@ local function prof_finish()
|
||||
local samples = prof_samples
|
||||
if samples == 0 then
|
||||
if prof_raw ~= true then out:write("[No samples collected]\n") end
|
||||
return
|
||||
end
|
||||
if prof_ann then
|
||||
elseif prof_ann then
|
||||
prof_annotate(prof_count1, samples)
|
||||
else
|
||||
prof_top(prof_count1, prof_count2, samples, "")
|
||||
|
||||
@@ -62,7 +62,7 @@ local jit = require("jit")
|
||||
local jutil = require("jit.util")
|
||||
local vmdef = require("jit.vmdef")
|
||||
local funcinfo, traceinfo = jutil.funcinfo, jutil.traceinfo
|
||||
local type, format = type, string.format
|
||||
local type, sub, format = type, string.sub, string.format
|
||||
local stdout, stderr = io.stdout, io.stderr
|
||||
|
||||
-- Active flag and output file handle.
|
||||
@@ -89,7 +89,12 @@ end
|
||||
local function fmterr(err, info)
|
||||
if type(err) == "number" then
|
||||
if type(info) == "function" then info = fmtfunc(info) end
|
||||
err = format(vmdef.traceerr[err], info)
|
||||
local fmt = vmdef.traceerr[err]
|
||||
if fmt == "NYI: bytecode %s" then
|
||||
local oidx = 6 * info
|
||||
info = sub(vmdef.bcnames, oidx+1, oidx+6)
|
||||
end
|
||||
err = format(fmt, info)
|
||||
end
|
||||
return err
|
||||
end
|
||||
|
||||
@@ -98,7 +98,7 @@ LJLIB_ASM(bit_lshift) LJLIB_REC(bit_shift IR_BSHL)
|
||||
x = lj_carith_shift64(x, sh, curr_func(L)->c.ffid - (int)FF_bit_lshift);
|
||||
return bit_result64(L, id, x);
|
||||
}
|
||||
if (id2) setintV(L->base+1, sh);
|
||||
setintV(L->base+1, sh);
|
||||
return FFH_RETRY;
|
||||
#else
|
||||
lj_lib_checknumber(L, 1);
|
||||
|
||||
@@ -305,7 +305,7 @@ LJLIB_CF(ffi_meta___tostring)
|
||||
p = *(void **)p;
|
||||
} else if (ctype_isenum(ct->info)) {
|
||||
msg = "cdata<%s>: %d";
|
||||
p = (void *)(uintptr_t)*(uint32_t **)p;
|
||||
p = (void *)(uintptr_t)*(uint32_t *)p;
|
||||
} else {
|
||||
if (ctype_isptr(ct->info)) {
|
||||
p = cdata_getptr(p, ct->size);
|
||||
@@ -513,7 +513,7 @@ LJLIB_CF(ffi_new) LJLIB_REC(.)
|
||||
/* Handle ctype __gc metamethod. Use the fast lookup here. */
|
||||
cTValue *tv = lj_tab_getinth(cts->miscmap, -(int32_t)id);
|
||||
if (tv && tvistab(tv) && (tv = lj_meta_fast(L, tabV(tv), MM_gc))) {
|
||||
GCtab *t = cts->finalizer;
|
||||
GCtab *t = tabref(G(L)->gcroot[GCROOT_FFI_FIN]);
|
||||
if (gcref(t->metatable)) {
|
||||
/* Add to finalizer table, if still enabled. */
|
||||
copyTV(L, lj_tab_set(L, t, o-1), tv);
|
||||
@@ -765,7 +765,7 @@ LJLIB_CF(ffi_abi) LJLIB_REC(.)
|
||||
return 1;
|
||||
}
|
||||
|
||||
LJLIB_PUSH(top-8) LJLIB_SET(!) /* Store reference to miscmap table. */
|
||||
LJLIB_PUSH(top-7) LJLIB_SET(!) /* Store reference to miscmap table. */
|
||||
|
||||
LJLIB_CF(ffi_metatype)
|
||||
{
|
||||
@@ -791,8 +791,6 @@ LJLIB_CF(ffi_metatype)
|
||||
return 1;
|
||||
}
|
||||
|
||||
LJLIB_PUSH(top-7) LJLIB_SET(!) /* Store reference to finalizer table. */
|
||||
|
||||
LJLIB_CF(ffi_gc) LJLIB_REC(.)
|
||||
{
|
||||
GCcdata *cd = ffi_checkcdata(L, 1);
|
||||
@@ -825,19 +823,6 @@ LJLIB_PUSH(top-2) LJLIB_SET(arch)
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
/* Create special weak-keyed finalizer table. */
|
||||
static GCtab *ffi_finalizer(lua_State *L)
|
||||
{
|
||||
/* NOBARRIER: The table is new (marked white). */
|
||||
GCtab *t = lj_tab_new(L, 0, 1);
|
||||
settabV(L, L->top++, t);
|
||||
setgcref(t->metatable, obj2gco(t));
|
||||
setstrV(L, lj_tab_setstr(L, t, lj_str_newlit(L, "__mode")),
|
||||
lj_str_newlit(L, "k"));
|
||||
t->nomm = (uint8_t)(~(1u<<MM_mode));
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Register FFI module as loaded. */
|
||||
static void ffi_register_module(lua_State *L)
|
||||
{
|
||||
@@ -853,7 +838,6 @@ LUALIB_API int luaopen_ffi(lua_State *L)
|
||||
{
|
||||
CTState *cts = lj_ctype_init(L);
|
||||
settabV(L, L->top++, (cts->miscmap = lj_tab_new(L, 0, 1)));
|
||||
cts->finalizer = ffi_finalizer(L);
|
||||
LJ_LIB_REG(L, NULL, ffi_meta);
|
||||
/* NOBARRIER: basemt is a GC root. */
|
||||
setgcref(basemt_it(G(L), LJ_TCDATA), obj2gco(tabV(L->top-1)));
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "lualib.h"
|
||||
|
||||
#include "lj_obj.h"
|
||||
#include "lj_err.h"
|
||||
#include "lj_lib.h"
|
||||
#include "lj_vm.h"
|
||||
#include "lj_prng.h"
|
||||
@@ -183,7 +184,10 @@ LJLIB_PUSH(top-2) /* Upvalue holds userdata with PRNGState. */
|
||||
LJLIB_CF(math_randomseed)
|
||||
{
|
||||
PRNGState *rs = (PRNGState *)(uddata(udataV(lj_lib_upvalue(L, 1))));
|
||||
random_seed(rs, lj_lib_checknum(L, 1));
|
||||
if (L->base != L->top)
|
||||
random_seed(rs, lj_lib_checknum(L, 1));
|
||||
else if (!lj_prng_seed_secure(rs))
|
||||
lj_err_caller(L, LJ_ERR_PRNGSD);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1057,7 +1057,7 @@ static size_t release_unused_segments(mstate m)
|
||||
mchunkptr p = align_as_chunk(base);
|
||||
size_t psize = chunksize(p);
|
||||
/* Can unmap if first chunk holds entire segment and not pinned */
|
||||
if (!cinuse(p) && (char *)p + psize >= base + size - TOP_FOOT_SIZE) {
|
||||
if (!cinuse(p) && (char *)p + psize == (char *)mem2chunk(sp)) {
|
||||
tchunkptr tp = (tchunkptr)p;
|
||||
if (p == m->dv) {
|
||||
m->dv = 0;
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
#define LJ_TARGET_POSIX (LUAJIT_OS > LUAJIT_OS_WINDOWS)
|
||||
#define LJ_TARGET_DLOPEN LJ_TARGET_POSIX
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
|
||||
#define LJ_TARGET_IOS 1
|
||||
#else
|
||||
#define LJ_TARGET_IOS 0
|
||||
|
||||
@@ -949,11 +949,11 @@ static int asm_sunk_store(ASMState *as, IRIns *ira, IRIns *irs)
|
||||
static void asm_snap_alloc1(ASMState *as, IRRef ref)
|
||||
{
|
||||
IRIns *ir = IR(ref);
|
||||
if (!irref_isk(ref) && ir->r != RID_SUNK) {
|
||||
if (!irref_isk(ref)) {
|
||||
bloomset(as->snapfilt1, ref);
|
||||
bloomset(as->snapfilt2, hashrot(ref, ref + HASH_BIAS));
|
||||
if (ra_used(ir)) return;
|
||||
if (ir->r == RID_SINK) {
|
||||
if (ir->r == RID_SINK || ir->r == RID_SUNK) {
|
||||
ir->r = RID_SUNK;
|
||||
#if LJ_HASFFI
|
||||
if (ir->o == IR_CNEWI) { /* Allocate CNEWI value. */
|
||||
|
||||
@@ -787,7 +787,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
|
||||
int destused = ra_used(ir);
|
||||
Reg dest = ra_dest(as, ir, allow);
|
||||
Reg tab = ra_alloc1(as, ir->op1, rset_clear(allow, dest));
|
||||
Reg tmp = RID_TMP, type = RID_NONE, key, tkey;
|
||||
Reg tmp = RID_TMP, type = RID_NONE, key = RID_NONE, tkey;
|
||||
IRRef refkey = ir->op2;
|
||||
IRIns *irkey = IR(refkey);
|
||||
int isk = irref_isk(refkey);
|
||||
|
||||
@@ -456,7 +456,7 @@ static void asm_retf(ASMState *as, IRIns *ir)
|
||||
emit_addptr(as, base, -8*delta);
|
||||
asm_guard(as, MIPSI_BNE, RID_TMP,
|
||||
ra_allock(as, igcptr(pc), rset_exclude(RSET_GPR, base)));
|
||||
emit_tsi(as, MIPSI_AL, RID_TMP, base, -8);
|
||||
emit_tsi(as, MIPSI_AL, RID_TMP, base, (LJ_BE || LJ_FR2) ? -8 : -4);
|
||||
}
|
||||
|
||||
/* -- Buffer operations --------------------------------------------------- */
|
||||
|
||||
@@ -408,7 +408,7 @@ static int bcread_header(LexState *ls)
|
||||
#endif
|
||||
}
|
||||
if ((flags & BCDUMP_F_STRIP)) {
|
||||
ls->chunkname = lj_str_newz(ls->L, ls->chunkarg);
|
||||
ls->chunkname = lj_str_newz(ls->L, *ls->chunkarg == BCDUMP_HEAD1 ? "=?" : ls->chunkarg);
|
||||
} else {
|
||||
MSize len = bcread_uleb128(ls);
|
||||
bcread_need(ls, len);
|
||||
|
||||
@@ -92,10 +92,8 @@ void LJ_FASTCALL lj_buf_shrink(lua_State *L, SBuf *sb)
|
||||
char *b = sb->b;
|
||||
MSize osz = (MSize)(sb->e - b);
|
||||
if (osz > 2*LJ_MIN_SBUF) {
|
||||
MSize n = (MSize)(sb->w - b);
|
||||
b = lj_mem_realloc(L, b, osz, (osz >> 1));
|
||||
sb->b = b;
|
||||
sb->w = b + n;
|
||||
sb->w = sb->b = b; /* Not supposed to keep data across shrinks. */
|
||||
sb->e = b + (osz >> 1);
|
||||
}
|
||||
lj_assertG_(G(sbufL(sb)), !sbufisext(sb), "YAGNI shrink SBufExt");
|
||||
|
||||
@@ -349,9 +349,7 @@ uint64_t lj_carith_check64(lua_State *L, int narg, CTypeID *id)
|
||||
if (LJ_LIKELY(tvisint(o))) {
|
||||
return (uint32_t)intV(o);
|
||||
} else {
|
||||
int32_t i = lj_num2bit(numV(o));
|
||||
if (LJ_DUALNUM) setintV(o, i);
|
||||
return (uint32_t)i;
|
||||
return (uint32_t)lj_num2bit(numV(o));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ void LJ_FASTCALL lj_cdata_free(global_State *g, GCcdata *cd)
|
||||
|
||||
void lj_cdata_setfin(lua_State *L, GCcdata *cd, GCobj *obj, uint32_t it)
|
||||
{
|
||||
GCtab *t = ctype_ctsG(G(L))->finalizer;
|
||||
GCtab *t = tabref(G(L)->gcroot[GCROOT_FFI_FIN]);
|
||||
if (gcref(t->metatable)) {
|
||||
/* Add cdata to finalizer table, if still enabled. */
|
||||
TValue *tv, tmp;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "lj_crecord.h"
|
||||
#include "lj_dispatch.h"
|
||||
#include "lj_strfmt.h"
|
||||
#include "lj_strscan.h"
|
||||
|
||||
/* Some local macros to save typing. Undef'd at the end. */
|
||||
#define IR(ref) (&J->cur.ir[(ref)])
|
||||
@@ -1498,7 +1499,8 @@ static TRef crec_arith_meta(jit_State *J, TRef *sp, CType **s, CTState *cts,
|
||||
|
||||
void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd)
|
||||
{
|
||||
CTState *cts = ctype_ctsG(J2G(J));
|
||||
CTState *cts = ctype_cts(J->L);
|
||||
MMS mm = (MMS)rd->data;
|
||||
TRef sp[2];
|
||||
CType *s[2];
|
||||
MSize i;
|
||||
@@ -1548,6 +1550,8 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd)
|
||||
}
|
||||
}
|
||||
} else if (tref_isnil(tr)) {
|
||||
if (!(mm == MM_len || mm == MM_eq || mm == MM_lt || mm == MM_le))
|
||||
lj_trace_err(J, LJ_TRERR_BADTYPE);
|
||||
tr = lj_ir_kptr(J, NULL);
|
||||
ct = ctype_get(cts, CTID_P_VOID);
|
||||
} else if (tref_isinteger(tr)) {
|
||||
@@ -1566,12 +1570,12 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd)
|
||||
ct = ctype_child(cts, cct);
|
||||
tr = lj_ir_kint(J, (int32_t)ofs);
|
||||
} else { /* Interpreter will throw or return false. */
|
||||
ct = ctype_get(cts, CTID_P_VOID);
|
||||
lj_trace_err(J, LJ_TRERR_BADTYPE);
|
||||
}
|
||||
} else if (ctype_isptr(ct->info)) {
|
||||
tr = emitir(IRT(IR_ADD, IRT_PTR), tr, lj_ir_kintp(J, sizeof(GCstr)));
|
||||
} else {
|
||||
ct = ctype_get(cts, CTID_P_VOID);
|
||||
lj_trace_err(J, LJ_TRERR_BADTYPE);
|
||||
}
|
||||
} else if (!tref_isnum(tr)) {
|
||||
tr = 0;
|
||||
@@ -1583,7 +1587,6 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd)
|
||||
}
|
||||
{
|
||||
TRef tr;
|
||||
MMS mm = (MMS)rd->data;
|
||||
if ((mm == MM_len || mm == MM_concat ||
|
||||
(!(tr = crec_arith_int64(J, sp, s, mm)) &&
|
||||
!(tr = crec_arith_ptr(J, sp, s, mm)))) &&
|
||||
@@ -1805,11 +1808,21 @@ static CTypeID crec_bit64_type(CTState *cts, cTValue *tv)
|
||||
return 0; /* Use regular 32 bit ops. */
|
||||
}
|
||||
|
||||
static TRef crec_bit64_arg(jit_State *J, CType *d, TRef sp, TValue *sval)
|
||||
{
|
||||
if (LJ_UNLIKELY(tref_isstr(sp))) {
|
||||
if (lj_strscan_num(strV(sval), sval)) {
|
||||
sp = emitir(IRTG(IR_STRTO, IRT_NUM), sp, 0);
|
||||
} /* else: interpreter will throw. */
|
||||
}
|
||||
return crec_ct_tv(J, d, 0, sp, sval);
|
||||
}
|
||||
|
||||
void LJ_FASTCALL recff_bit64_tobit(jit_State *J, RecordFFData *rd)
|
||||
{
|
||||
CTState *cts = ctype_ctsG(J2G(J));
|
||||
TRef tr = crec_ct_tv(J, ctype_get(cts, CTID_INT64), 0,
|
||||
J->base[0], &rd->argv[0]);
|
||||
TRef tr = crec_bit64_arg(J, ctype_get(cts, CTID_INT64),
|
||||
J->base[0], &rd->argv[0]);
|
||||
if (!tref_isinteger(tr))
|
||||
tr = emitconv(tr, IRT_INT, tref_type(tr), 0);
|
||||
J->base[0] = tr;
|
||||
@@ -1820,7 +1833,7 @@ int LJ_FASTCALL recff_bit64_unary(jit_State *J, RecordFFData *rd)
|
||||
CTState *cts = ctype_ctsG(J2G(J));
|
||||
CTypeID id = crec_bit64_type(cts, &rd->argv[0]);
|
||||
if (id) {
|
||||
TRef tr = crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]);
|
||||
TRef tr = crec_bit64_arg(J, ctype_get(cts, id), J->base[0], &rd->argv[0]);
|
||||
tr = emitir(IRT(rd->data, id-CTID_INT64+IRT_I64), tr, 0);
|
||||
J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
|
||||
return 1;
|
||||
@@ -1840,9 +1853,9 @@ int LJ_FASTCALL recff_bit64_nary(jit_State *J, RecordFFData *rd)
|
||||
if (id) {
|
||||
CType *ct = ctype_get(cts, id);
|
||||
uint32_t ot = IRT(rd->data, id-CTID_INT64+IRT_I64);
|
||||
TRef tr = crec_ct_tv(J, ct, 0, J->base[0], &rd->argv[0]);
|
||||
TRef tr = crec_bit64_arg(J, ct, J->base[0], &rd->argv[0]);
|
||||
for (i = 1; J->base[i] != 0; i++) {
|
||||
TRef tr2 = crec_ct_tv(J, ct, 0, J->base[i], &rd->argv[i]);
|
||||
TRef tr2 = crec_bit64_arg(J, ct, J->base[i], &rd->argv[i]);
|
||||
tr = emitir(ot, tr, tr2);
|
||||
}
|
||||
J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
|
||||
@@ -1857,15 +1870,15 @@ int LJ_FASTCALL recff_bit64_shift(jit_State *J, RecordFFData *rd)
|
||||
CTypeID id;
|
||||
TRef tsh = 0;
|
||||
if (J->base[0] && tref_iscdata(J->base[1])) {
|
||||
tsh = crec_ct_tv(J, ctype_get(cts, CTID_INT64), 0,
|
||||
J->base[1], &rd->argv[1]);
|
||||
tsh = crec_bit64_arg(J, ctype_get(cts, CTID_INT64),
|
||||
J->base[1], &rd->argv[1]);
|
||||
if (!tref_isinteger(tsh))
|
||||
tsh = emitconv(tsh, IRT_INT, tref_type(tsh), 0);
|
||||
J->base[1] = tsh;
|
||||
}
|
||||
id = crec_bit64_type(cts, &rd->argv[0]);
|
||||
if (id) {
|
||||
TRef tr = crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]);
|
||||
TRef tr = crec_bit64_arg(J, ctype_get(cts, id), J->base[0], &rd->argv[0]);
|
||||
uint32_t op = rd->data;
|
||||
if (!tsh) tsh = lj_opt_narrow_tobit(J, J->base[1]);
|
||||
if (!(op < IR_BROL ? LJ_TARGET_MASKSHIFT : LJ_TARGET_MASKROT) &&
|
||||
@@ -1895,7 +1908,7 @@ TRef recff_bit64_tohex(jit_State *J, RecordFFData *rd, TRef hdr)
|
||||
CTypeID id2 = 0;
|
||||
n = (int32_t)lj_carith_check64(J->L, 2, &id2);
|
||||
if (id2)
|
||||
trsf = crec_ct_tv(J, ctype_get(cts, CTID_INT32), 0, trsf, &rd->argv[1]);
|
||||
trsf = crec_bit64_arg(J, ctype_get(cts, CTID_INT32), trsf, &rd->argv[1]);
|
||||
else
|
||||
trsf = lj_opt_narrow_tobit(J, trsf);
|
||||
emitir(IRTGI(IR_EQ), trsf, lj_ir_kint(J, n)); /* Specialize to n. */
|
||||
@@ -1906,7 +1919,7 @@ TRef recff_bit64_tohex(jit_State *J, RecordFFData *rd, TRef hdr)
|
||||
if ((uint32_t)n > 254) n = 254;
|
||||
sf |= ((SFormat)((n+1)&255) << STRFMT_SH_PREC);
|
||||
if (id) {
|
||||
tr = crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]);
|
||||
tr = crec_bit64_arg(J, ctype_get(cts, id), J->base[0], &rd->argv[0]);
|
||||
if (n < 16)
|
||||
tr = emitir(IRT(IR_BAND, IRT_U64), tr,
|
||||
lj_ir_kint64(J, ((uint64_t)1 << 4*n)-1));
|
||||
|
||||
@@ -643,6 +643,18 @@ CTState *lj_ctype_init(lua_State *L)
|
||||
return cts;
|
||||
}
|
||||
|
||||
/* Create special weak-keyed finalizer table. */
|
||||
void lj_ctype_initfin(lua_State *L)
|
||||
{
|
||||
/* NOBARRIER: The table is new (marked white). */
|
||||
GCtab *t = lj_tab_new(L, 0, 1);
|
||||
setgcref(t->metatable, obj2gco(t));
|
||||
setstrV(L, lj_tab_setstr(L, t, lj_str_newlit(L, "__mode")),
|
||||
lj_str_newlit(L, "k"));
|
||||
t->nomm = (uint8_t)(~(1u<<MM_mode));
|
||||
setgcref(G(L)->gcroot[GCROOT_FFI_FIN], obj2gco(t));
|
||||
}
|
||||
|
||||
/* Free C type table and state. */
|
||||
void lj_ctype_freestate(global_State *g)
|
||||
{
|
||||
|
||||
@@ -177,7 +177,6 @@ typedef struct CTState {
|
||||
MSize sizetab; /* Size of C type table. */
|
||||
lua_State *L; /* Lua state (needed for errors and allocations). */
|
||||
global_State *g; /* Global state. */
|
||||
GCtab *finalizer; /* Map of cdata to finalizer. */
|
||||
GCtab *miscmap; /* Map of -CTypeID to metatable and cb slot to func. */
|
||||
CCallback cb; /* Temporary callback state. */
|
||||
CTypeID1 hash[CTHASH_SIZE]; /* Hash anchors for C type table. */
|
||||
@@ -476,6 +475,7 @@ LJ_FUNC GCstr *lj_ctype_repr(lua_State *L, CTypeID id, GCstr *name);
|
||||
LJ_FUNC GCstr *lj_ctype_repr_int64(lua_State *L, uint64_t n, int isunsigned);
|
||||
LJ_FUNC GCstr *lj_ctype_repr_complex(lua_State *L, void *sp, CTSize size);
|
||||
LJ_FUNC CTState *lj_ctype_init(lua_State *L);
|
||||
LJ_FUNC void lj_ctype_initfin(lua_State *L);
|
||||
LJ_FUNC void lj_ctype_freestate(global_State *g);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -66,6 +66,17 @@ static uint32_t emit_isfpk64(uint64_t n)
|
||||
return ~0u;
|
||||
}
|
||||
|
||||
static uint32_t emit_isfpmovi(uint64_t n)
|
||||
{
|
||||
/* Is every byte either 0x00 or 0xff? */
|
||||
if ((n & U64x(01010101,01010101)) * 0xff != n) return 0;
|
||||
/* Form 8-bit value by taking one bit from each byte. */
|
||||
n &= U64x(80402010,08040201);
|
||||
n = (n * U64x(01010101,01010101)) >> 56;
|
||||
/* Split into the format expected by movi. */
|
||||
return ((n & 0xe0) << 6) | 0x700 | (n & 0x1f);
|
||||
}
|
||||
|
||||
/* -- Emit basic instructions --------------------------------------------- */
|
||||
|
||||
static void emit_dnma(ASMState *as, A64Ins ai, Reg rd, Reg rn, Reg rm, Reg ra)
|
||||
@@ -98,6 +109,11 @@ static void emit_d(ASMState *as, A64Ins ai, Reg rd)
|
||||
*--as->mcp = ai | A64F_D(rd);
|
||||
}
|
||||
|
||||
static void emit_dl(ASMState *as, A64Ins ai, Reg rd, uint32_t l)
|
||||
{
|
||||
*--as->mcp = ai | A64F_D(rd) | A64F_S19(l >> 2);
|
||||
}
|
||||
|
||||
static void emit_n(ASMState *as, A64Ins ai, Reg rn)
|
||||
{
|
||||
*--as->mcp = ai | A64F_N(rn);
|
||||
@@ -215,7 +231,7 @@ static int emit_kadrp(ASMState *as, Reg rd, uint64_t k)
|
||||
emit_dn(as, (A64I_ADDx^A64I_K12)|A64F_U12(k - kpage), rd, rd);
|
||||
ai = A64I_ADRP;
|
||||
}
|
||||
emit_d(as, ai|(((uint32_t)ofs&3)<<29)|A64F_S19(ofs>>2), rd);
|
||||
emit_dl(as, ai|(((uint32_t)ofs&3)<<29), rd, ofs);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -280,7 +296,7 @@ static void emit_lsptr(ASMState *as, A64Ins ai, Reg r, void *p)
|
||||
/* GL + offset, might subsequently fuse to LDP/STP. */
|
||||
} else if (ai == A64I_LDRx && checkmcpofs(as, p)) {
|
||||
/* IP + offset is cheaper than allock, but address must be in range. */
|
||||
emit_d(as, A64I_LDRLx | A64F_S19(mcpofs(as, p)>>2), r);
|
||||
emit_dl(as, A64I_LDRLx, r, mcpofs(as, p));
|
||||
return;
|
||||
} else { /* Split up into base reg + offset. */
|
||||
int64_t i64 = i64ptr(p);
|
||||
@@ -300,21 +316,24 @@ static void emit_loadk64(ASMState *as, Reg r, IRIns *ir)
|
||||
if (fpk != ~0u) {
|
||||
emit_d(as, A64I_FMOV_DI | A64F_FP8(fpk), (r & 31));
|
||||
return;
|
||||
} else if ((fpk = emit_isfpmovi(*k))) {
|
||||
emit_d(as, A64I_MOVI_DI | (fpk << 5), (r & 31));
|
||||
return;
|
||||
}
|
||||
}
|
||||
ofs = glofs(as, k);
|
||||
if (emit_checkofs(A64I_LDRx, ofs)) {
|
||||
emit_lso(as, r >= RID_MAX_GPR ? A64I_LDRd : A64I_LDRx,
|
||||
(r & 31), RID_GL, ofs);
|
||||
} else if (checkmcpofs(as, k)) {
|
||||
emit_dl(as, r >= RID_MAX_GPR ? A64I_LDRLd : A64I_LDRLx,
|
||||
(r & 31), mcpofs(as, k));
|
||||
} else {
|
||||
if (r >= RID_MAX_GPR) {
|
||||
emit_dn(as, A64I_FMOV_D_R, (r & 31), RID_TMP);
|
||||
r = RID_TMP;
|
||||
}
|
||||
if (checkmcpofs(as, k))
|
||||
emit_d(as, A64I_LDRLx | A64F_S19(mcpofs(as, k)>>2), r);
|
||||
else
|
||||
emit_loadu64(as, r, *k);
|
||||
emit_loadu64(as, r, *k);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -239,12 +239,6 @@ typedef struct UndocumentedDispatcherContext {
|
||||
/* Another wild guess. */
|
||||
extern void __DestructExceptionObject(EXCEPTION_RECORD *rec, int nothrow);
|
||||
|
||||
#if LJ_TARGET_X64 && defined(MINGW_SDK_INIT)
|
||||
/* Workaround for broken MinGW64 declaration. */
|
||||
VOID RtlUnwindEx_FIXED(PVOID,PVOID,PVOID,PVOID,PVOID,PVOID) asm("RtlUnwindEx");
|
||||
#define RtlUnwindEx RtlUnwindEx_FIXED
|
||||
#endif
|
||||
|
||||
#define LJ_MSVC_EXCODE ((DWORD)0xe06d7363)
|
||||
#define LJ_GCC_EXCODE ((DWORD)0x20474343)
|
||||
|
||||
|
||||
@@ -79,6 +79,7 @@ ERRDEF(SETFENV, LUA_QL("setfenv") " cannot change environment of given object")
|
||||
ERRDEF(CORUN, "cannot resume running coroutine")
|
||||
ERRDEF(CODEAD, "cannot resume dead coroutine")
|
||||
ERRDEF(COSUSP, "cannot resume non-suspended coroutine")
|
||||
ERRDEF(PRNGSD, "PRNG seeding failed")
|
||||
ERRDEF(TABINS, "wrong number of arguments to " LUA_QL("insert"))
|
||||
ERRDEF(TABCAT, "invalid value (%s) at index %d in table for " LUA_QL("concat"))
|
||||
ERRDEF(TABSORT, "invalid order function for sorting")
|
||||
|
||||
@@ -152,6 +152,8 @@ static void recff_stitch(jit_State *J)
|
||||
if (errcode) {
|
||||
if (errcode == LUA_ERRRUN)
|
||||
copyTV(L, L->top-1, L->top + (1 + LJ_FR2));
|
||||
else
|
||||
setintV(L->top-1, (int32_t)LJ_TRERR_RECERR);
|
||||
lj_err_throw(L, errcode); /* Propagate errors. */
|
||||
}
|
||||
}
|
||||
@@ -257,7 +259,7 @@ static void LJ_FASTCALL recff_setmetatable(jit_State *J, RecordFFData *rd)
|
||||
mtref = tref_isnil(mt) ? lj_ir_knull(J, IRT_TAB) : mt;
|
||||
emitir(IRT(IR_FSTORE, IRT_TAB), fref, mtref);
|
||||
if (!tref_isnil(mt))
|
||||
emitir(IRT(IR_TBAR, IRT_TAB), tr, 0);
|
||||
emitir(IRT(IR_TBAR, IRT_NIL), tr, 0);
|
||||
J->base[0] = tr;
|
||||
J->needsnap = 1;
|
||||
} /* else: Interpreter will throw. */
|
||||
@@ -1003,6 +1005,7 @@ static void recff_format(jit_State *J, RecordFFData *rd, TRef hdr, int sbufx)
|
||||
GCstr *fmt = argv2str(J, &rd->argv[arg]);
|
||||
FormatState fs;
|
||||
SFormat sf;
|
||||
int nfmt = 0;
|
||||
/* Specialize to the format string. */
|
||||
emitir(IRTG(IR_EQ, IRT_STR), trfmt, lj_ir_kstr(J, fmt));
|
||||
lj_strfmt_init(&fs, strdata(fmt), fmt->len);
|
||||
@@ -1080,6 +1083,7 @@ static void recff_format(jit_State *J, RecordFFData *rd, TRef hdr, int sbufx)
|
||||
recff_nyiu(J, rd);
|
||||
return;
|
||||
}
|
||||
if (++nfmt > 100) lj_trace_err(J, LJ_TRERR_TRACEOV);
|
||||
}
|
||||
if (sbufx) {
|
||||
emitir(IRT(IR_USE, IRT_NIL), tr, 0);
|
||||
|
||||
+18
-33
@@ -108,9 +108,6 @@ static void gc_mark_start(global_State *g)
|
||||
gc_markobj(g, tabref(mainthread(g)->env));
|
||||
gc_marktv(g, &g->registrytv);
|
||||
gc_mark_gcroot(g);
|
||||
#if LJ_HASFFI
|
||||
if (ctype_ctsG(g)) gc_markobj(g, ctype_ctsG(g)->finalizer);
|
||||
#endif
|
||||
g->gc.state = GCSpropagate;
|
||||
}
|
||||
|
||||
@@ -190,8 +187,7 @@ static int gc_traverse_tab(global_State *g, GCtab *t)
|
||||
}
|
||||
if (weak) { /* Weak tables are cleared in the atomic phase. */
|
||||
#if LJ_HASFFI
|
||||
CTState *cts = ctype_ctsG(g);
|
||||
if (cts && cts->finalizer == t) {
|
||||
if (gcref(g->gcroot[GCROOT_FFI_FIN]) == obj2gco(t)) {
|
||||
weak = (int)(~0u & ~LJ_GC_WEAKVAL);
|
||||
} else
|
||||
#endif
|
||||
@@ -556,9 +552,8 @@ static void gc_finalize(lua_State *L)
|
||||
o->gch.marked &= (uint8_t)~LJ_GC_CDATA_FIN;
|
||||
/* Resolve finalizer. */
|
||||
setcdataV(L, &tmp, gco2cd(o));
|
||||
tv = lj_tab_set(L, ctype_ctsG(g)->finalizer, &tmp);
|
||||
tv = lj_tab_set(L, tabref(g->gcroot[GCROOT_FFI_FIN]), &tmp);
|
||||
if (!tvisnil(tv)) {
|
||||
g->gc.nocdatafin = 0;
|
||||
copyTV(L, &tmp, tv);
|
||||
setnilV(tv); /* Clear entry in finalizer table. */
|
||||
gc_call_finalizer(g, L, &tmp, o);
|
||||
@@ -588,35 +583,31 @@ void lj_gc_finalize_udata(lua_State *L)
|
||||
void lj_gc_finalize_cdata(lua_State *L)
|
||||
{
|
||||
global_State *g = G(L);
|
||||
CTState *cts = ctype_ctsG(g);
|
||||
if (cts) {
|
||||
GCtab *t = cts->finalizer;
|
||||
Node *node = noderef(t->node);
|
||||
ptrdiff_t i;
|
||||
setgcrefnull(t->metatable); /* Mark finalizer table as disabled. */
|
||||
for (i = (ptrdiff_t)t->hmask; i >= 0; i--)
|
||||
if (!tvisnil(&node[i].val) && tviscdata(&node[i].key)) {
|
||||
GCobj *o = gcV(&node[i].key);
|
||||
TValue tmp;
|
||||
makewhite(g, o);
|
||||
o->gch.marked &= (uint8_t)~LJ_GC_CDATA_FIN;
|
||||
copyTV(L, &tmp, &node[i].val);
|
||||
setnilV(&node[i].val);
|
||||
gc_call_finalizer(g, L, &tmp, o);
|
||||
}
|
||||
}
|
||||
GCtab *t = tabref(g->gcroot[GCROOT_FFI_FIN]);
|
||||
Node *node = noderef(t->node);
|
||||
ptrdiff_t i;
|
||||
setgcrefnull(t->metatable); /* Mark finalizer table as disabled. */
|
||||
for (i = (ptrdiff_t)t->hmask; i >= 0; i--)
|
||||
if (!tvisnil(&node[i].val) && tviscdata(&node[i].key)) {
|
||||
GCobj *o = gcV(&node[i].key);
|
||||
TValue tmp;
|
||||
makewhite(g, o);
|
||||
o->gch.marked &= (uint8_t)~LJ_GC_CDATA_FIN;
|
||||
copyTV(L, &tmp, &node[i].val);
|
||||
setnilV(&node[i].val);
|
||||
gc_call_finalizer(g, L, &tmp, o);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Free all remaining GC objects. */
|
||||
void lj_gc_freeall(global_State *g)
|
||||
{
|
||||
MSize i, strmask;
|
||||
MSize i;
|
||||
/* Free everything, except super-fixed objects (the main thread). */
|
||||
g->gc.currentwhite = LJ_GC_WHITES | LJ_GC_SFIXED;
|
||||
gc_fullsweep(g, &g->gc.root);
|
||||
strmask = g->str.mask;
|
||||
for (i = 0; i <= strmask; i++) /* Free all string hash chains. */
|
||||
for (i = g->str.mask; i != ~(MSize)0; i--) /* Free all string hash chains. */
|
||||
gc_sweepstr(g, &g->str.tab[i]);
|
||||
}
|
||||
|
||||
@@ -697,9 +688,6 @@ static size_t gc_onestep(lua_State *L)
|
||||
lj_str_resize(L, g->str.mask >> 1); /* Shrink string table. */
|
||||
if (gcref(g->gc.mmudata)) { /* Need any finalizations? */
|
||||
g->gc.state = GCSfinalize;
|
||||
#if LJ_HASFFI
|
||||
g->gc.nocdatafin = 1;
|
||||
#endif
|
||||
} else { /* Otherwise skip this phase to help the JIT. */
|
||||
g->gc.state = GCSpause; /* End of GC cycle. */
|
||||
g->gc.debt = 0;
|
||||
@@ -719,9 +707,6 @@ static size_t gc_onestep(lua_State *L)
|
||||
g->gc.estimate -= GCFINALIZECOST;
|
||||
return GCFINALIZECOST;
|
||||
}
|
||||
#if LJ_HASFFI
|
||||
if (!g->gc.nocdatafin) lj_tab_rehash(L, ctype_ctsG(g)->finalizer);
|
||||
#endif
|
||||
g->gc.state = GCSpause; /* End of GC cycle. */
|
||||
g->gc.debt = 0;
|
||||
return 0;
|
||||
|
||||
@@ -460,8 +460,8 @@ typedef struct jit_State {
|
||||
#endif
|
||||
|
||||
IRIns *irbuf; /* Temp. IR instruction buffer. Biased with REF_BIAS. */
|
||||
IRRef irtoplim; /* Upper limit of instuction buffer (biased). */
|
||||
IRRef irbotlim; /* Lower limit of instuction buffer (biased). */
|
||||
IRRef irtoplim; /* Upper limit of instruction buffer (biased). */
|
||||
IRRef irbotlim; /* Lower limit of instruction buffer (biased). */
|
||||
IRRef loopref; /* Last loop reference or ref of final LOOP (or 0). */
|
||||
|
||||
MSize sizesnap; /* Size of temp. snapshot buffer. */
|
||||
|
||||
@@ -101,29 +101,30 @@ LUALIB_API int luaL_loadfilex(lua_State *L, const char *filename,
|
||||
FileReaderCtx ctx;
|
||||
int status;
|
||||
const char *chunkname;
|
||||
int err = 0;
|
||||
if (filename) {
|
||||
chunkname = lua_pushfstring(L, "@%s", filename);
|
||||
ctx.fp = fopen(filename, "rb");
|
||||
if (ctx.fp == NULL) {
|
||||
L->top--;
|
||||
lua_pushfstring(L, "cannot open %s: %s", filename, strerror(errno));
|
||||
return LUA_ERRFILE;
|
||||
}
|
||||
chunkname = lua_pushfstring(L, "@%s", filename);
|
||||
} else {
|
||||
ctx.fp = stdin;
|
||||
chunkname = "=stdin";
|
||||
}
|
||||
status = lua_loadx(L, reader_file, &ctx, chunkname, mode);
|
||||
if (ferror(ctx.fp)) {
|
||||
L->top -= filename ? 2 : 1;
|
||||
lua_pushfstring(L, "cannot read %s: %s", chunkname+1, strerror(errno));
|
||||
if (filename)
|
||||
fclose(ctx.fp);
|
||||
return LUA_ERRFILE;
|
||||
}
|
||||
if (ferror(ctx.fp)) err = errno;
|
||||
if (filename) {
|
||||
fclose(ctx.fp);
|
||||
L->top--;
|
||||
copyTV(L, L->top-1, L->top);
|
||||
fclose(ctx.fp);
|
||||
}
|
||||
if (err) {
|
||||
L->top--;
|
||||
lua_pushfstring(L, "cannot read %s: %s", chunkname+1, strerror(err));
|
||||
return LUA_ERRFILE;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -579,6 +579,9 @@ typedef enum {
|
||||
GCROOT_BASEMT_NUM = GCROOT_BASEMT + ~LJ_TNUMX,
|
||||
GCROOT_IO_INPUT, /* Userdata for default I/O input file. */
|
||||
GCROOT_IO_OUTPUT, /* Userdata for default I/O output file. */
|
||||
#if LJ_HASFFI
|
||||
GCROOT_FFI_FIN, /* FFI finalizer table. */
|
||||
#endif
|
||||
GCROOT_MAX
|
||||
} GCRootID;
|
||||
|
||||
@@ -592,7 +595,7 @@ typedef struct GCState {
|
||||
GCSize threshold; /* Memory threshold. */
|
||||
uint8_t currentwhite; /* Current white color. */
|
||||
uint8_t state; /* GC state. */
|
||||
uint8_t nocdatafin; /* No cdata finalizer called. */
|
||||
uint8_t unused0;
|
||||
#if LJ_64
|
||||
uint8_t lightudnum; /* Number of lightuserdata segments - 1. */
|
||||
#else
|
||||
|
||||
@@ -1135,7 +1135,7 @@ LJFOLDF(shortcut_conv_num_int)
|
||||
}
|
||||
|
||||
LJFOLD(CONV CONV IRCONV_INT_NUM) /* _INT */
|
||||
LJFOLD(CONV CONV IRCONV_U32_NUM) /* _U32*/
|
||||
LJFOLD(CONV CONV IRCONV_U32_NUM) /* _U32 */
|
||||
LJFOLDF(simplify_conv_int_num)
|
||||
{
|
||||
/* Fold even across PHI to avoid expensive num->int conversions in loop. */
|
||||
@@ -1170,8 +1170,10 @@ LJFOLDF(simplify_conv_i64_num)
|
||||
|
||||
LJFOLD(CONV CONV IRCONV_INT_I64) /* _INT or _U32 */
|
||||
LJFOLD(CONV CONV IRCONV_INT_U64) /* _INT or _U32 */
|
||||
LJFOLD(CONV CONV IRCONV_INT_U32) /* _INT or _U32 */
|
||||
LJFOLD(CONV CONV IRCONV_U32_I64) /* _INT or _U32 */
|
||||
LJFOLD(CONV CONV IRCONV_U32_U64) /* _INT or _U32 */
|
||||
LJFOLD(CONV CONV IRCONV_U32_INT) /* _INT or _U32 */
|
||||
LJFOLDF(simplify_conv_int_i64)
|
||||
{
|
||||
int src;
|
||||
@@ -1216,14 +1218,13 @@ LJFOLDF(simplify_tobit_conv)
|
||||
return NEXTFOLD;
|
||||
}
|
||||
|
||||
/* Shortcut floor/ceil/round + IRT_NUM <- IRT_INT/IRT_U32 conversion. */
|
||||
/* Shortcut floor/ceil/trunc + IRT_NUM <- integer conversion. */
|
||||
LJFOLD(FPMATH CONV IRFPM_FLOOR)
|
||||
LJFOLD(FPMATH CONV IRFPM_CEIL)
|
||||
LJFOLD(FPMATH CONV IRFPM_TRUNC)
|
||||
LJFOLDF(simplify_floor_conv)
|
||||
{
|
||||
if ((fleft->op2 & IRCONV_SRCMASK) == IRT_INT ||
|
||||
(fleft->op2 & IRCONV_SRCMASK) == IRT_U32)
|
||||
if ((uint32_t)(fleft->op2 & IRCONV_SRCMASK) - (uint32_t)IRT_I8 <= (uint32_t)(IRT_U64 - IRT_U8))
|
||||
return LEFTFOLD;
|
||||
return NEXTFOLD;
|
||||
}
|
||||
@@ -1935,9 +1936,10 @@ LJFOLDF(abc_k)
|
||||
LJFOLD(ABC any any)
|
||||
LJFOLDF(abc_invar)
|
||||
{
|
||||
/* Invariant ABC marked as PTR. Drop if op1 is invariant, too. */
|
||||
/* Invariant ABC marked as P32 or U32. Drop if op1 is invariant too. */
|
||||
if (!irt_isint(fins->t) && fins->op1 < J->chain[IR_LOOP] &&
|
||||
!irt_isphi(IR(fins->op1)->t))
|
||||
(irt_isu32(fins->t) ||
|
||||
(!irref_isk(fins->op1) && !irt_isphi(IR(fins->op1)->t))))
|
||||
return DROPFOLD;
|
||||
return NEXTFOLD;
|
||||
}
|
||||
@@ -2485,6 +2487,17 @@ LJFOLD(CNEW any any)
|
||||
LJFOLD(XSNEW any any)
|
||||
LJFOLDX(lj_ir_emit)
|
||||
|
||||
/* -- Miscellaneous ------------------------------------------------------- */
|
||||
|
||||
LJFOLD(CARG any any)
|
||||
LJFOLDF(cse_carg)
|
||||
{
|
||||
TRef tr = lj_opt_cse(J);
|
||||
if (tref_ref(tr) < J->chain[IR_LOOP]) /* CSE across loop? */
|
||||
return EMITFOLD; /* Raw emit. Assumes fins is left intact by CSE. */
|
||||
return tr;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
/* Every entry in the generated hash table is a 32 bit pattern:
|
||||
|
||||
@@ -341,7 +341,8 @@ static int narrow_conv_backprop(NarrowConv *nc, IRRef ref, int depth)
|
||||
NarrowIns *savesp = nc->sp;
|
||||
int count = narrow_conv_backprop(nc, ir->op1, depth);
|
||||
count += narrow_conv_backprop(nc, ir->op2, depth);
|
||||
if (count <= 1) { /* Limit total number of conversions. */
|
||||
/* Limit total number of conversions. */
|
||||
if (count <= 1 && nc->sp < nc->maxsp) {
|
||||
*nc->sp++ = NARROWINS(IRT(ir->o, nc->t), ref);
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -2339,11 +2339,15 @@ static void parse_return(LexState *ls)
|
||||
BCReg nret = expr_list(ls, &e);
|
||||
if (nret == 1) { /* Return one result. */
|
||||
if (e.k == VCALL) { /* Check for tail call. */
|
||||
#ifdef LUAJIT_DISABLE_TAILCALL
|
||||
goto notailcall;
|
||||
#else
|
||||
BCIns *ip = bcptr(fs, &e);
|
||||
/* It doesn't pay off to add BC_VARGT just for 'return ...'. */
|
||||
if (bc_op(*ip) == BC_VARG) goto notailcall;
|
||||
fs->pc--;
|
||||
ins = BCINS_AD(bc_op(*ip)-BC_CALL+BC_CALLT, bc_a(*ip), bc_c(*ip));
|
||||
#endif
|
||||
} else { /* Can return the result from any register. */
|
||||
ins = BCINS_AD(BC_RET1, expr_toanyreg(fs, &e), 2);
|
||||
}
|
||||
@@ -2517,11 +2521,9 @@ static void parse_for_num(LexState *ls, GCstr *varname, BCLine line)
|
||||
*/
|
||||
static int predict_next(LexState *ls, FuncState *fs, BCPos pc)
|
||||
{
|
||||
BCIns ins;
|
||||
BCIns ins = fs->bcbase[pc].ins;
|
||||
GCstr *name;
|
||||
cTValue *o;
|
||||
if (pc >= fs->bclim) return 0;
|
||||
ins = fs->bcbase[pc].ins;
|
||||
switch (bc_op(ins)) {
|
||||
case BC_MOV:
|
||||
if (bc_d(ins) >= fs->nactvar) return 0;
|
||||
@@ -2570,7 +2572,7 @@ static void parse_for_iter(LexState *ls, GCstr *indexname)
|
||||
assign_adjust(ls, 3, expr_list(ls, &e), &e);
|
||||
/* The iterator needs another 3 [4] slots (func [pc] | state ctl). */
|
||||
bcreg_bump(fs, 3+ls->fr2);
|
||||
isnext = (nvars <= 5 && predict_next(ls, fs, exprpc));
|
||||
isnext = (nvars <= 5 && fs->pc > exprpc && predict_next(ls, fs, exprpc));
|
||||
var_add(ls, 3); /* Hidden control variables. */
|
||||
lex_check(ls, TK_do);
|
||||
loop = bcemit_AJ(fs, isnext ? BC_ISNEXT : BC_JMP, base, NO_JMP);
|
||||
|
||||
+50
-12
@@ -1025,7 +1025,9 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults)
|
||||
J->L->base = b + baseadj;
|
||||
copyTV(J->L, b-(2<<LJ_FR2), &save);
|
||||
}
|
||||
if (tr) { /* Store final result. */
|
||||
if (tr >= 0xffffff00) {
|
||||
lj_err_throw(J->L, -(int32_t)tr); /* Propagate errors. */
|
||||
} else if (tr) { /* Store final result. */
|
||||
BCReg dst = bc_a(*(frame_contpc(frame)-1));
|
||||
J->base[dst] = tr;
|
||||
if (dst >= J->maxslot) {
|
||||
@@ -1072,6 +1074,7 @@ int lj_record_mm_lookup(jit_State *J, RecordIndex *ix, MMS mm)
|
||||
} else if (tref_isudata(ix->tab)) {
|
||||
int udtype = udataV(&ix->tabv)->udtype;
|
||||
mt = tabref(udataV(&ix->tabv)->metatable);
|
||||
mix.tab = emitir(IRT(IR_FLOAD, IRT_TAB), ix->tab, IRFL_UDATA_META);
|
||||
/* The metatables of special userdata objects are treated as immutable. */
|
||||
if (udtype != UDTYPE_USERDATA) {
|
||||
cTValue *mo;
|
||||
@@ -1085,6 +1088,8 @@ int lj_record_mm_lookup(jit_State *J, RecordIndex *ix, MMS mm)
|
||||
}
|
||||
immutable_mt:
|
||||
mo = lj_tab_getstr(mt, mmname_str(J2G(J), mm));
|
||||
ix->mt = mix.tab;
|
||||
ix->mtv = mt;
|
||||
if (!mo || tvisnil(mo))
|
||||
return 0; /* No metamethod. */
|
||||
/* Treat metamethod or index table as immutable, too. */
|
||||
@@ -1092,11 +1097,8 @@ int lj_record_mm_lookup(jit_State *J, RecordIndex *ix, MMS mm)
|
||||
lj_trace_err(J, LJ_TRERR_BADTYPE);
|
||||
copyTV(J->L, &ix->mobjv, mo);
|
||||
ix->mobj = lj_ir_kgc(J, gcV(mo), tvisfunc(mo) ? IRT_FUNC : IRT_TAB);
|
||||
ix->mtv = mt;
|
||||
ix->mt = TREF_NIL; /* Dummy value for comparison semantics. */
|
||||
return 1; /* Got metamethod or index table. */
|
||||
}
|
||||
mix.tab = emitir(IRT(IR_FLOAD, IRT_TAB), ix->tab, IRFL_UDATA_META);
|
||||
} else {
|
||||
/* Specialize to base metatable. Must flush mcode in lua_setmetatable(). */
|
||||
mt = tabref(basemt_obj(J2G(J), &ix->tabv));
|
||||
@@ -1393,12 +1395,13 @@ static void rec_idx_abc(jit_State *J, TRef asizeref, TRef ikey, uint32_t asize)
|
||||
/* Runtime value for stop of loop is within bounds? */
|
||||
if ((uint64_t)stop + ofs < (uint64_t)asize) {
|
||||
/* Emit invariant bounds check for stop. */
|
||||
emitir(IRTG(IR_ABC, IRT_P32), asizeref, ofs == 0 ? J->scev.stop :
|
||||
uint32_t abc = IRTG(IR_ABC, tref_isk(asizeref) ? IRT_U32 : IRT_P32);
|
||||
emitir(abc, asizeref, ofs == 0 ? J->scev.stop :
|
||||
emitir(IRTI(IR_ADD), J->scev.stop, ofsref));
|
||||
/* Emit invariant bounds check for start, if not const or negative. */
|
||||
if (!(J->scev.dir && J->scev.start &&
|
||||
(int64_t)IR(J->scev.start)->i + ofs >= 0))
|
||||
emitir(IRTG(IR_ABC, IRT_P32), asizeref, ikey);
|
||||
emitir(abc, asizeref, ikey);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -2075,12 +2078,21 @@ static TRef rec_tnew(jit_State *J, uint32_t ah)
|
||||
|
||||
/* -- Concatenation ------------------------------------------------------- */
|
||||
|
||||
static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot)
|
||||
typedef struct RecCatDataCP {
|
||||
jit_State *J;
|
||||
BCReg baseslot, topslot;
|
||||
TRef tr;
|
||||
} RecCatDataCP;
|
||||
|
||||
static TValue *rec_mm_concat_cp(lua_State *L, lua_CFunction dummy, void *ud)
|
||||
{
|
||||
RecCatDataCP *rcd = (RecCatDataCP *)ud;
|
||||
jit_State *J = rcd->J;
|
||||
BCReg baseslot = rcd->baseslot, topslot = rcd->topslot;
|
||||
TRef *top = &J->base[topslot];
|
||||
TValue savetv[5+LJ_FR2];
|
||||
BCReg s;
|
||||
RecordIndex ix;
|
||||
UNUSED(L); UNUSED(dummy);
|
||||
lj_assertJ(baseslot < topslot, "bad CAT arg");
|
||||
for (s = baseslot; s <= topslot; s++)
|
||||
(void)getslot(J, s); /* Ensure all arguments have a reference. */
|
||||
@@ -2102,7 +2114,10 @@ static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot)
|
||||
} while (trp <= top);
|
||||
tr = emitir(IRTG(IR_BUFSTR, IRT_STR), tr, hdr);
|
||||
J->maxslot = (BCReg)(xbase - J->base);
|
||||
if (xbase == base) return tr; /* Return simple concatenation result. */
|
||||
if (xbase == base) {
|
||||
rcd->tr = tr; /* Return simple concatenation result. */
|
||||
return NULL;
|
||||
}
|
||||
/* Pass partial result. */
|
||||
topslot = J->maxslot--;
|
||||
*xbase = tr;
|
||||
@@ -2115,10 +2130,31 @@ static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot)
|
||||
copyTV(J->L, &ix.tabv, &J->L->base[topslot-1]);
|
||||
ix.tab = top[-1];
|
||||
ix.key = top[0];
|
||||
memcpy(savetv, &J->L->base[topslot-1], sizeof(savetv)); /* Save slots. */
|
||||
rec_mm_arith(J, &ix, MM_concat); /* Call __concat metamethod. */
|
||||
memcpy(&J->L->base[topslot-1], savetv, sizeof(savetv)); /* Restore slots. */
|
||||
return 0; /* No result yet. */
|
||||
rcd->tr = 0; /* No result yet. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot)
|
||||
{
|
||||
lua_State *L = J->L;
|
||||
ptrdiff_t delta = L->top - L->base;
|
||||
TValue savetv[5+LJ_FR2], errobj;
|
||||
RecCatDataCP rcd;
|
||||
int errcode;
|
||||
rcd.J = J;
|
||||
rcd.baseslot = baseslot;
|
||||
rcd.topslot = topslot;
|
||||
memcpy(savetv, &L->base[topslot-1], sizeof(savetv)); /* Save slots. */
|
||||
errcode = lj_vm_cpcall(L, NULL, &rcd, rec_mm_concat_cp);
|
||||
if (errcode) copyTV(L, &errobj, L->top-1);
|
||||
memcpy(&L->base[topslot-1], savetv, sizeof(savetv)); /* Restore slots. */
|
||||
if (errcode) {
|
||||
L->top = L->base + delta;
|
||||
copyTV(L, L->top++, &errobj);
|
||||
return (TRef)(-errcode);
|
||||
}
|
||||
return rcd.tr;
|
||||
}
|
||||
|
||||
/* -- Record bytecode ops ------------------------------------------------- */
|
||||
@@ -2440,6 +2476,8 @@ void lj_record_ins(jit_State *J)
|
||||
|
||||
case BC_CAT:
|
||||
rc = rec_cat(J, rb, rc);
|
||||
if (rc >= 0xffffff00)
|
||||
lj_err_throw(J->L, -(int32_t)rc); /* Propagate errors. */
|
||||
break;
|
||||
|
||||
/* -- Constant and move ops --------------------------------------------- */
|
||||
|
||||
@@ -801,7 +801,6 @@ static void snap_restoredata(jit_State *J, GCtrace *T, ExitState *ex,
|
||||
*(lua_Number *)dst = (lua_Number)*(int32_t *)dst;
|
||||
return;
|
||||
}
|
||||
src = (int32_t *)&ex->gpr[r-RID_MIN_GPR];
|
||||
#if !LJ_SOFTFP
|
||||
if (r >= RID_MAX_GPR) {
|
||||
src = (int32_t *)&ex->fpr[r-RID_MIN_FPR];
|
||||
@@ -815,7 +814,10 @@ static void snap_restoredata(jit_State *J, GCtrace *T, ExitState *ex,
|
||||
#endif
|
||||
} else
|
||||
#endif
|
||||
if (LJ_64 && LJ_BE && sz == 4) src++;
|
||||
{
|
||||
src = (int32_t *)&ex->gpr[r-RID_MIN_GPR];
|
||||
if (LJ_64 && LJ_BE && sz == 4) src++;
|
||||
}
|
||||
}
|
||||
}
|
||||
lj_assertJ(sz == 1 || sz == 2 || sz == 4 || sz == 8,
|
||||
@@ -955,7 +957,8 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr)
|
||||
lua_State *L = J->L;
|
||||
|
||||
/* Set interpreter PC to the next PC to get correct error messages. */
|
||||
setcframe_pc(cframe_raw(L->cframe), pc+1);
|
||||
setcframe_pc(L->cframe, pc+1);
|
||||
setcframe_pc(cframe_raw(cframe_prev(L->cframe)), pc);
|
||||
|
||||
/* Make sure the stack is big enough for the slots from the snapshot. */
|
||||
if (LJ_UNLIKELY(L->base + snap->topslot >= tvref(L->maxstack))) {
|
||||
|
||||
@@ -196,6 +196,9 @@ static TValue *cpluaopen(lua_State *L, lua_CFunction dummy, void *ud)
|
||||
lj_lex_init(L);
|
||||
fixstring(lj_err_str(L, LJ_ERR_ERRMEM)); /* Preallocate memory error msg. */
|
||||
g->gc.threshold = 4*g->gc.total;
|
||||
#if LJ_HASFFI
|
||||
lj_ctype_initfin(L);
|
||||
#endif
|
||||
lj_trace_initstate(g);
|
||||
lj_err_verify();
|
||||
return NULL;
|
||||
|
||||
@@ -367,13 +367,6 @@ static void rehashtab(lua_State *L, GCtab *t, cTValue *ek)
|
||||
lj_tab_resize(L, t, asize, hsize2hbits(total));
|
||||
}
|
||||
|
||||
#if LJ_HASFFI
|
||||
void lj_tab_rehash(lua_State *L, GCtab *t)
|
||||
{
|
||||
rehashtab(L, t, niltv(L));
|
||||
}
|
||||
#endif
|
||||
|
||||
void lj_tab_reasize(lua_State *L, GCtab *t, uint32_t nasize)
|
||||
{
|
||||
lj_tab_resize(L, t, nasize+1, t->hmask > 0 ? lj_fls(t->hmask)+1 : 0);
|
||||
@@ -642,7 +635,7 @@ LJ_NOINLINE static MSize tab_len_slow(GCtab *t, size_t hi)
|
||||
while ((tv = lj_tab_getint(t, (int32_t)hi)) && !tvisnil(tv)) {
|
||||
lo = hi;
|
||||
hi += hi;
|
||||
if (hi > (size_t)(INT_MAX-2)) { /* Punt and do a linear search. */
|
||||
if (hi > (size_t)(0x7fffffff - 2)) { /* Punt and do a linear search. */
|
||||
lo = 1;
|
||||
while ((tv = lj_tab_getint(t, (int32_t)lo)) && !tvisnil(tv)) lo++;
|
||||
return (MSize)(lo - 1);
|
||||
|
||||
@@ -60,9 +60,6 @@ LJ_FUNC GCtab * LJ_FASTCALL lj_tab_new1(lua_State *L, uint32_t ahsize);
|
||||
LJ_FUNCA GCtab * LJ_FASTCALL lj_tab_dup(lua_State *L, const GCtab *kt);
|
||||
LJ_FUNC void LJ_FASTCALL lj_tab_clear(GCtab *t);
|
||||
LJ_FUNC void LJ_FASTCALL lj_tab_free(global_State *g, GCtab *t);
|
||||
#if LJ_HASFFI
|
||||
LJ_FUNC void lj_tab_rehash(lua_State *L, GCtab *t);
|
||||
#endif
|
||||
LJ_FUNC void lj_tab_resize(lua_State *L, GCtab *t, uint32_t asize, uint32_t hbits);
|
||||
LJ_FUNCA void lj_tab_reasize(lua_State *L, GCtab *t, uint32_t nasize);
|
||||
|
||||
|
||||
@@ -281,6 +281,7 @@ typedef enum A64Ins {
|
||||
A64I_FSQRTd = 0x1e61c000,
|
||||
A64I_LDRs = 0xbd400000,
|
||||
A64I_LDRd = 0xfd400000,
|
||||
A64I_LDRLd = 0x5c000000,
|
||||
A64I_STRs = 0xbd000000,
|
||||
A64I_STRd = 0xfd000000,
|
||||
A64I_LDPs = 0x2d400000,
|
||||
@@ -320,6 +321,7 @@ typedef enum A64Ins {
|
||||
A64I_FMOV_R_D = 0x9e660000,
|
||||
A64I_FMOV_D_R = 0x9e670000,
|
||||
A64I_FMOV_DI = 0x1e601000,
|
||||
A64I_MOVI_DI = 0x2f000400,
|
||||
} A64Ins;
|
||||
|
||||
#define A64I_BR_AUTH (LJ_ABI_PAUTH ? A64I_BRAAZ : A64I_BR)
|
||||
|
||||
@@ -13,7 +13,7 @@ TREDEF(STACKOV, "trace too deep")
|
||||
TREDEF(SNAPOV, "too many snapshots")
|
||||
TREDEF(BLACKL, "blacklisted")
|
||||
TREDEF(RETRY, "retry recording")
|
||||
TREDEF(NYIBC, "NYI: bytecode %d")
|
||||
TREDEF(NYIBC, "NYI: bytecode %s")
|
||||
|
||||
/* Recording loop ops. */
|
||||
TREDEF(LLEAVE, "leaving loop in root trace")
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#ifndef WINVER
|
||||
#define WINVER 0x0501
|
||||
#endif
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/* Default path for loading Lua and C modules with require(). */
|
||||
@@ -37,7 +36,6 @@
|
||||
#endif
|
||||
#define LUA_LROOT "/usr/local"
|
||||
#define LUA_LUADIR "/lua/5.1/"
|
||||
#define LUA_LJDIR "/luajit-2.1/"
|
||||
|
||||
#ifdef LUA_ROOT
|
||||
#define LUA_JROOT LUA_ROOT
|
||||
@@ -51,7 +49,11 @@
|
||||
#define LUA_RCPATH
|
||||
#endif
|
||||
|
||||
#define LUA_JPATH ";" LUA_JROOT "/share" LUA_LJDIR "?.lua"
|
||||
#ifndef LUA_LJDIR
|
||||
#define LUA_LJDIR LUA_JROOT "/share/luajit-2.1"
|
||||
#endif
|
||||
|
||||
#define LUA_JPATH ";" LUA_LJDIR "/?.lua"
|
||||
#define LUA_LLDIR LUA_LROOT "/share" LUA_LUADIR
|
||||
#define LUA_LCDIR LUA_LROOT "/" LUA_LMULTILIB LUA_LUADIR
|
||||
#define LUA_LLPATH ";" LUA_LLDIR "?.lua;" LUA_LLDIR "?/init.lua"
|
||||
|
||||
@@ -13,10 +13,15 @@
|
||||
@if not defined INCLUDE goto :FAIL
|
||||
|
||||
@setlocal
|
||||
@rem Add more debug flags here, e.g. DEBUGCFLAGS=/DLUA_USE_APICHECK
|
||||
@rem Add more debug flags here, e.g. DEBUGCFLAGS=/DLUA_USE_ASSERT
|
||||
@set DEBUGCFLAGS=
|
||||
@set LJCOMPILE=cl /nologo /c /O2 /W3 /D_CRT_SECURE_NO_DEPRECATE /D_CRT_STDIO_INLINE=__declspec(dllexport)__inline
|
||||
@set LJDYNBUILD=/MD /DLUA_BUILD_AS_DLL
|
||||
@set LJDYNBUILD=/DLUA_BUILD_AS_DLL /MD
|
||||
@set LJDYNBUILD_DEBUG=/DLUA_BUILD_AS_DLL /MDd
|
||||
@set LJCOMPILETARGET=/Zi
|
||||
@set LJLINKTYPE=/DEBUG /RELEASE
|
||||
@set LJLINKTYPE_DEBUG=/DEBUG
|
||||
@set LJLINKTARGET=/OPT:REF /OPT:ICF /INCREMENTAL:NO
|
||||
@set LJLINK=link /nologo
|
||||
@set LJMT=mt /nologo
|
||||
@set LJLIB=lib /nologo /nodefaultlib
|
||||
@@ -25,7 +30,6 @@
|
||||
@set DASC=vm_x64.dasc
|
||||
@set LJDLLNAME=lua51.dll
|
||||
@set LJLIBNAME=lua51.lib
|
||||
@set BUILDTYPE=release
|
||||
@set ALL_LIB=lib_base.c lib_math.c lib_bit.c lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c lib_jit.c lib_ffi.c lib_buffer.c
|
||||
|
||||
@setlocal
|
||||
@@ -92,17 +96,17 @@ buildvm -m folddef -o lj_folddef.h lj_opt_fold.c
|
||||
|
||||
@if "%1" neq "debug" goto :NODEBUG
|
||||
@shift
|
||||
@set BUILDTYPE=debug
|
||||
@set LJCOMPILE=%LJCOMPILE% /Zi %DEBUGCFLAGS%
|
||||
@set LJDYNBUILD=/MD /DLUA_BUILD_AS_DLL
|
||||
@set LJLINK=%LJLINK% /opt:ref /opt:icf /incremental:no
|
||||
@set LJCOMPILE=%LJCOMPILE% %DEBUGCFLAGS%
|
||||
@set LJDYNBUILD=%LJDYNBUILD_DEBUG%
|
||||
@set LJLINKTYPE=%LJLINKTYPE_DEBUG%
|
||||
:NODEBUG
|
||||
@set LJLINK=%LJLINK% /%BUILDTYPE%
|
||||
@set LJCOMPILE=%LJCOMPILE% %LJCOMPILETARGET%
|
||||
@set LJLINK=%LJLINK% %LJLINKTYPE% %LJLINKTARGET%
|
||||
@if "%1"=="amalg" goto :AMALGDLL
|
||||
@if "%1"=="static" goto :STATIC
|
||||
%LJCOMPILE% %LJDYNBUILD% lj_*.c lib_*.c
|
||||
@if errorlevel 1 goto :BAD
|
||||
%LJLINK% /DLL /out:%LJDLLNAME% lj_*.obj lib_*.obj
|
||||
%LJLINK% /DLL /OUT:%LJDLLNAME% lj_*.obj lib_*.obj
|
||||
@if errorlevel 1 goto :BAD
|
||||
@goto :MTDLL
|
||||
:STATIC
|
||||
@@ -112,9 +116,16 @@ buildvm -m folddef -o lj_folddef.h lj_opt_fold.c
|
||||
@if errorlevel 1 goto :BAD
|
||||
@goto :MTDLL
|
||||
:AMALGDLL
|
||||
@if "%2"=="static" goto :AMALGSTATIC
|
||||
%LJCOMPILE% %LJDYNBUILD% ljamalg.c
|
||||
@if errorlevel 1 goto :BAD
|
||||
%LJLINK% /DLL /out:%LJDLLNAME% ljamalg.obj lj_vm.obj
|
||||
%LJLINK% /DLL /OUT:%LJDLLNAME% ljamalg.obj lj_vm.obj
|
||||
@if errorlevel 1 goto :BAD
|
||||
@goto :MTDLL
|
||||
:AMALGSTATIC
|
||||
%LJCOMPILE% ljamalg.c
|
||||
@if errorlevel 1 goto :BAD
|
||||
%LJLINK% /OUT:%LJDLLNAME% ljamalg.obj lj_vm.obj
|
||||
@if errorlevel 1 goto :BAD
|
||||
:MTDLL
|
||||
if exist %LJDLLNAME%.manifest^
|
||||
@@ -122,7 +133,7 @@ if exist %LJDLLNAME%.manifest^
|
||||
|
||||
%LJCOMPILE% luajit.c
|
||||
@if errorlevel 1 goto :BAD
|
||||
%LJLINK% /out:luajit.exe luajit.obj %LJLIBNAME%
|
||||
%LJLINK% /OUT:luajit.exe luajit.obj %LJLIBNAME%
|
||||
@if errorlevel 1 goto :BAD
|
||||
if exist luajit.exe.manifest^
|
||||
%LJMT% -manifest luajit.exe.manifest -outputresource:luajit.exe
|
||||
|
||||
@@ -99,20 +99,21 @@ buildvm -m folddef -o lj_folddef.h lj_opt_fold.c
|
||||
@if errorlevel 1 goto :BAD
|
||||
|
||||
@rem ---- Cross compiler ----
|
||||
@set NXCOMPILER_ROOT="%NINTENDO_SDK_ROOT%\Compilers\NintendoClang"
|
||||
@if "%platform%" neq "x64" goto :NX32_CROSSBUILD
|
||||
@set LJCOMPILE="%NINTENDO_SDK_ROOT%\Compilers\NX\nx\aarch64\bin\clang" -Wall -I%NINTENDO_SDK_ROOT%\Include %DASMTARGET% -DLUAJIT_OS=LUAJIT_OS_OTHER -DLUAJIT_DISABLE_JIT -DLUAJIT_DISABLE_FFI -DLUAJIT_USE_SYSMALLOC -c
|
||||
@set LJLIB="%NINTENDO_SDK_ROOT%\Compilers\NX\nx\aarch64\bin\aarch64-nintendo-nx-elf-ar" rc
|
||||
@set LJCOMPILE="%NXCOMPILER_ROOT%\bin\clang" --target=aarch64-nintendo-nx-elf -Wall -I%NINTENDO_SDK_ROOT%\Include %DASMTARGET% -DLUAJIT_OS=LUAJIT_OS_OTHER -DLUAJIT_DISABLE_JIT -DLUAJIT_DISABLE_FFI -DLUAJIT_USE_SYSMALLOC -c
|
||||
@set LJLIB="%NXCOMPILER_ROOT%\bin\llvm-ar" rc
|
||||
@set TARGETLIB_SUFFIX=nx64
|
||||
|
||||
%NINTENDO_SDK_ROOT%\Compilers\NX\nx\aarch64\bin\aarch64-nintendo-nx-elf-as -o lj_vm.o lj_vm.s
|
||||
%NXCOMPILER_ROOT%\bin\clang --target=aarch64-nintendo-nx-elf -o lj_vm.o -c lj_vm.s
|
||||
goto :DEBUGCHECK
|
||||
|
||||
:NX32_CROSSBUILD
|
||||
@set LJCOMPILE="%NINTENDO_SDK_ROOT%\Compilers\NX\nx\armv7l\bin\clang" -Wall -I%NINTENDO_SDK_ROOT%\Include %DASMTARGET% -DLUAJIT_OS=LUAJIT_OS_OTHER -DLUAJIT_DISABLE_JIT -DLUAJIT_DISABLE_FFI -DLUAJIT_USE_SYSMALLOC -c
|
||||
@set LJLIB="%NINTENDO_SDK_ROOT%\Compilers\NX\nx\armv7l\bin\armv7l-nintendo-nx-eabihf-ar" rc
|
||||
@set LJCOMPILE="%NXCOMPILER_ROOT%\bin\clang" --target=armv7l-nintendo-nx-eabihf -Wall -I%NINTENDO_SDK_ROOT%\Include %DASMTARGET% -DLUAJIT_OS=LUAJIT_OS_OTHER -DLUAJIT_DISABLE_JIT -DLUAJIT_DISABLE_FFI -DLUAJIT_USE_SYSMALLOC -c
|
||||
@set LJLIB="%NXCOMPILER_ROOT%\bin\llvm-ar" rc
|
||||
@set TARGETLIB_SUFFIX=nx32
|
||||
|
||||
%NINTENDO_SDK_ROOT%\Compilers\NX\nx\armv7l\bin\armv7l-nintendo-nx-eabihf-as -o lj_vm.o lj_vm.s
|
||||
%NXCOMPILER_ROOT%\bin\clang --target=armv7l-nintendo-nx-eabihf -o lj_vm.o -c lj_vm.s
|
||||
:DEBUGCHECK
|
||||
|
||||
@if "%1" neq "debug" goto :NODEBUG
|
||||
|
||||
@@ -1823,9 +1823,19 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
|
|
||||
|//-- Bit library --------------------------------------------------------
|
||||
|
|
||||
|// FP number to bit conversion for soft-float. Clobbers r0-r3.
|
||||
|->vm_tobit_fb:
|
||||
| bhi ->fff_fallback
|
||||
|.if FPU
|
||||
|// FP number to bit conversion for hard-float. Clobbers r0, d0-d1.
|
||||
| vldr d1, >9
|
||||
| vmov d0, CARG1, CARG2
|
||||
| vadd.f64 d0, d0, d1
|
||||
| vmov CARG1, s0
|
||||
| bx lr
|
||||
|9:
|
||||
| .long 0, 0x43380000 // (double)(2^52 + 2^51).
|
||||
|.else
|
||||
|// FP number to bit conversion for soft-float. Clobbers r0-r3.
|
||||
|->vm_tobit:
|
||||
| lsl RB, CARG2, #1
|
||||
| adds RB, RB, #0x00200000
|
||||
@@ -1850,6 +1860,7 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
| orr CARG1, CARG4, CARG1, lsl RB
|
||||
| rsblt CARG1, CARG1, #0
|
||||
| bx lr
|
||||
|.endif
|
||||
|
|
||||
|.macro .ffunc_bit, name
|
||||
| .ffunc_1 bit_..name
|
||||
|
||||
@@ -1658,22 +1658,14 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
|
|
||||
|//-- Bit library --------------------------------------------------------
|
||||
|
|
||||
|// FP number to bit conversion for soft-float. Clobbers CARG1-CARG3
|
||||
|// FP number to bit conversion. Clobbers CARG1-CARG2, FARG1-FARG2.
|
||||
|->vm_tobit_fb:
|
||||
| bls ->fff_fallback
|
||||
| add CARG2, CARG1, CARG1
|
||||
| mov CARG3, #1076
|
||||
| sub CARG3, CARG3, CARG2, lsr #53
|
||||
| cmp CARG3, #53
|
||||
| bhi >1
|
||||
| and CARG2, CARG2, #U64x(001fffff,ffffffff)
|
||||
| orr CARG2, CARG2, #U64x(00200000,00000000)
|
||||
| cmp CARG1, #0
|
||||
| lsr CARG2, CARG2, CARG3
|
||||
| cneg CARG1w, CARG2w, mi
|
||||
| br lr
|
||||
|1:
|
||||
| mov CARG1w, #0
|
||||
| fmov FARG1, CARG1
|
||||
| movz CARG2, #0x4338, lsl #48
|
||||
| fmov FARG2, CARG2
|
||||
| fadd FARG1, FARG1, FARG2
|
||||
| fmov CARG1w, s0
|
||||
| br lr
|
||||
|
|
||||
|.macro .ffunc_bit, name
|
||||
@@ -4220,7 +4212,6 @@ static void emit_asm_debug(BuildCtx *ctx)
|
||||
"LEFDEY:\n\n", fcsize);
|
||||
}
|
||||
#endif
|
||||
fprintf(ctx->fp, ".subsections_via_symbols\n");
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
@@ -1420,9 +1420,10 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
| sltu AT, TMP1, TMP2
|
||||
| bnez AT, ->fff_fallback
|
||||
|. lbu TMP3, DISPATCH_GL(hookmask)(DISPATCH)
|
||||
| daddiu NARGS8:RC, NARGS8:RC, -8
|
||||
| bltz NARGS8:RC, ->fff_fallback
|
||||
| daddiu NARGS8:TMP0, NARGS8:RC, -8
|
||||
| bltz NARGS8:TMP0, ->fff_fallback
|
||||
|. move TMP2, BASE
|
||||
| move NARGS8:RC, NARGS8:TMP0
|
||||
| daddiu BASE, BASE, 16
|
||||
| // Remember active hook before pcall.
|
||||
| srl TMP3, TMP3, HOOK_ACTIVE_SHIFT
|
||||
|
||||
@@ -4941,7 +4941,6 @@ static void emit_asm_debug(BuildCtx *ctx)
|
||||
"LEFDEY:\n\n", fcsize);
|
||||
}
|
||||
#endif
|
||||
fprintf(ctx->fp, ".subsections_via_symbols\n");
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
@@ -5841,7 +5841,6 @@ static void emit_asm_debug(BuildCtx *ctx)
|
||||
fprintf(ctx->fp, "L_%s$stub:\n\t.indirect_symbol _%s\n\t.ascii \"\\364\\364\\364\\364\\364\"\n", *xn, *xn);
|
||||
}
|
||||
#endif
|
||||
fprintf(ctx->fp, ".subsections_via_symbols\n");
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user