This commit is contained in:
Bill Niblock 2024-10-29 19:44:41 -04:00
parent 1ef93799d1
commit 2df9b96765
98 changed files with 30423 additions and 0 deletions

Binary file not shown.

166
buildtools/appimage/build.sh Executable file
View file

@ -0,0 +1,166 @@
#!/bin/bash
set -eo >/dev/null
CURRENT_APPIMAGEKIT_RELEASE=9
ARCH="$(uname -m)"
if [[ $# -lt 1 ]]; then
echo "Usage: $0 <version>"
exit 0
fi
VERSION="$1"
LOVEFILE="$2"
USERNAME=$3
TOKEN=$4
# https://github.com/love2d/love/releases/download/11.5/love-11.5-x86_64.AppImage
# https://github.com/love2d/love/releases/download/11.4/love-11.4-x86_64.AppImage
# https://github.com/love2d/love/releases/download/11.3/love-11.3-x86_64.AppImage
# https://github.com/love2d/love/releases/download/11.2/love-11.2-x86_64.AppImage
# https://github.com/love2d/love/releases/download/11.1/love-11.1-linux-x86_64.AppImage
LOVE_AppImage_URL=https://github.com/love2d/love/releases/download/${VERSION}/love-${VERSION}-${ARCH}.AppImage
if [ $VERSION == "11.1" ]
then
LOVE_AppImage_URL=https://github.com/love2d/love/releases/download/${VERSION}/love-${VERSION}-linux-${ARCH}.AppImage
fi
CACHE_DIR=${HOME}/.cache/love-release/love
LOVE_AppImage=$CACHE_DIR/love-${VERSION}-${ARCH}.AppImage
if ! test -d ${CACHE_DIR}; then
mkdir -p ${CACHE_DIR}
fi
get-development-artifact(){
owner=love2d
repo=love
branch="12.0-development"
artifact="love-x86_64.AppImage" # love-windows-x64 love-macos
token=$2
username=$1
list_run_url="https://api.github.com/repos/${owner}/${repo}/actions/runs"
echo "find latest run of branch 12.0"
latest_run=$(curl -v --silent \
-H "Accept: application/vnd.github.v3+json" \
-H "Authorization token ${token}" "${list_run_url}" \
--stderr - |\
grep -B 4 "\"head_branch\": \"12.0-development\"" |\
grep "id" |\
head -1 |\
sed 's/^.* \(.*\),$/\1/g')
list_artifacts_url="https://api.github.com/repos/${owner}/${repo}/actions/runs/${latest_run}/artifacts"
echo "get artifact_url"
artifact_url=$(curl --silent \
-H "Accept: application/vnd.github.v3+json" \
-H "Authorization token ${token}" \
"${list_artifacts_url}" \
--stderr - |\
grep -A 5 "\"name\": \"${artifact}\"," |\
grep "archive_download_url" |\
head -1 |\
sed 's/^.* \"\(.*\)\",$/\1/g')
echo "download target"
echo curl -L -u ${username}:${token} ${artifact_url} -o love.zip
echo $(pwd)
rm -f love.zip love-*.AppImage && \
curl -L -u ${username}:${token} ${artifact_url} -o love.zip \
&& unzip love.zip && \
rm -f love.zip ${artifact} && \
mv love-*.AppImage ${artifact}
}
if ! test -f ${LOVE_AppImage}; then
if [ $VERSION != "12.0" ]
then
curl -L -C - -o ${LOVE_AppImage} ${LOVE_AppImage_URL}
else
get-development-artifact $USERNAME $TOKEN
mv love-x86_64.AppImage ${LOVE_AppImage}
fi
chmod +x ${LOVE_AppImage}
fi
echo $CACHE_DIR
if ! test -f ${LOVE_AppImage}; then
echo "No tarball found for $VERSION in $LOVE_AppImage"
exit 1
fi
download_if_needed() {
if ! test -f "$1"; then
if ! curl -L -o "$1" "https://github.com/AppImage/AppImageKit/releases/download/${CURRENT_APPIMAGEKIT_RELEASE}/$1"; then
echo "Failed to download appimagetool"
echo "Please supply it manually"
exit 1
fi
chmod +x "$1"
fi
}
main() {
download_if_needed appimagetool-${ARCH}.AppImage
# Extract the tarball build into a folder
rm -rf love-prepared
mkdir -p love-prepared
cd love-prepared
$LOVE_AppImage --appimage-extract 1> /dev/null 2> /dev/null
mv squashfs-root/* .
rm squashfs-root/.DirIcon
rmdir squashfs-root
# Add our small wrapper script (yay, more wrappers), and AppRun
local desktopfile="love.desktop"
local icon="love"
local target="love-${VERSION}"
if test -f ../../game.desktop.in; then
desktopfile="game.desktop"
cp ../../game.desktop.in .
fi
if test -f ../../game.svg; then
icon="game"
cp ../../game.svg .
fi
if test -f ${LOVEFILE}; then
if [[ $VERSION == "11.4" || $VERSION == "11.5" || $VERSION == "12.0" ]]
then
dir="bin"
else
dir="usr/bin"
fi
target="game"
cat $dir/love ${LOVEFILE} > $dir/love-fused
mv $dir/love-fused $dir/love
chmod +x $dir/love
else
echo "Love file ${LOVEFILE} not found"
fi
# Add our desktop file
mv ${desktopfile} ${desktopfile}.in
sed -e "s/%ICON%/${icon}/" "${desktopfile}.in" > "$desktopfile"
rm "${desktopfile}.in"
# Add a DirIcon
cp "${icon}.svg" .DirIcon
# Clean up
if test -f ../../game.desktop.in; then
rm love.desktop.in
fi
if test -f ../../game.svg; then
rm love.svg
fi
# Now build the final AppImage
cd ..
# ./love-prepared/AppRun -n love-prepared "${target}-${ARCH}.AppImage"
# Work around missing FUSE/docker
./appimagetool-${ARCH}.AppImage --appimage-extract 1> /dev/null 2> /dev/null
./squashfs-root/AppRun -n love-prepared "${target}-${ARCH}.AppImage" 1> /dev/null 2> /dev/null
## rm -rf love-prepared/
}
main "$@"

View file

@ -0,0 +1,962 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="141.73px" height="141.73px" viewBox="0 0 141.73 141.73" enable-background="new 0 0 141.73 141.73" xml:space="preserve">
<g>
<g opacity="0.3">
<path d="M117.726,21.413c-0.016-0.017-0.035-0.027-0.053-0.042C96.307,3.014,66.118-0.243,41.136,12.523
C16.168,25.282,1.956,53.733,5.382,81.306c2.392,19.268,13.129,36.165,28.466,47.021c0,0,42.277-37.776,53.504-51.181
c10.53-12.582,33.52-52.764,33.52-52.764C119.861,23.365,118.814,22.374,117.726,21.413z"/>
</g>
<g>
<path fill="#E74A99" d="M115.726,18.413c-0.016-0.017-0.035-0.027-0.053-0.042C94.307,0.014,64.118-3.243,39.136,9.523
C14.168,22.282-0.044,50.733,3.382,78.306c2.392,19.268,13.129,36.165,28.466,47.021c0,0,42.277-37.776,53.504-51.181
c10.53-12.582,33.52-52.764,33.52-52.764C117.861,20.365,116.814,19.374,115.726,18.413z"/>
</g>
</g>
<g>
<g opacity="0.3">
<path d="M33.849,128.327c7.067,5.001,15.11,8.726,23.765,10.801c27.076,6.487,56.27-5.293,71.759-28.261
c18.256-27.077,14.241-63.649-8.5-86.485c0,0-32.464,38.778-43.287,51.706C66.65,89.146,33.849,128.327,33.849,128.327z"/>
</g>
<g>
<path fill="#27AAE1" d="M31.849,125.327c7.067,5.001,15.11,8.726,23.765,10.801c27.076,6.487,56.27-5.293,71.759-28.261
c18.256-27.077,14.241-63.649-8.5-86.485c0,0-32.464,38.778-43.287,51.706C64.65,86.146,31.849,125.327,31.849,125.327z"/>
</g>
</g>
<g>
<image overflow="visible" opacity="0.3" width="354" height="324" xlink:href="data:image/png;base64,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
rkJggg==" transform="matrix(0.24 0 0 0.24 28.4971 38.3643)">
</image>
<g>
<path fill="#FFFFFF" d="M73.043,52.8c0,0-6.48-14.187-19.968-10.958c-13.486,3.23-41.652,30.792,17.853,65.083H70.88
c59.504-34.291,31.34-61.852,17.853-65.083C75.245,38.613,68.766,52.8,68.766,52.8H73.043z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 72 KiB

View file

@ -0,0 +1,33 @@
#!/bin/sh
if [ -z "$APPDIR" ]; then
APPDIR="$(dirname "$(readlink -f "$0")")"
fi
export LD_LIBRARY_PATH="$APPDIR/lib/:$LD_LIBRARY_PATH"
if [ -z "$XDG_DATA_DIRS" ]; then #unset or empty
XDG_DATA_DIRS="/usr/local/share/:/usr/share/"
fi
export XDG_DATA_DIRS="$APPDIR/share/:$XDG_DATA_DIRS"
if [ -z "$LUA_PATH" ]; then
LUA_PATH=";" # so ends with ;;
fi
# if user's LUA_PATH does not end with ;; then user doesn't want the default path ?
export LUA_PATH="$APPDIR/share/luajit-2.1.0-beta3/?.lua;$APPDIR/share/lua/5.1/?.lua;$LUA_PATH"
if [ -z "$LUA_CPATH" ]; then
LUA_CPATH=";"
fi
export LUA_CPATH="$APPDIR/lib/lua/5.1/?.so;$LUA_CPATH"
# uncomment and edit to add your own game
#FUSE_PATH="$APPDIR/my_game.love"
#FUSE_PATH="$APPDIR/my_game"
if [ -z "$FUSE_PATH" ]; then
exec "$APPDIR/bin/love" "$@"
else
exec "$APPDIR/bin/love" --fused "$FUSE_PATH" "$@"
fi

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,10 @@
[Desktop Entry]
Name=LÖVE
Comment=The unquestionably awesome 2D game engine
MimeType=application/x-love-game;
Exec=love %f
Type=Application
Categories=Development;Game;
Terminal=false
Icon=love
NoDisplay=true

View file

@ -0,0 +1,962 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="141.73px" height="141.73px" viewBox="0 0 141.73 141.73" enable-background="new 0 0 141.73 141.73" xml:space="preserve">
<g>
<g opacity="0.3">
<path d="M117.726,21.413c-0.016-0.017-0.035-0.027-0.053-0.042C96.307,3.014,66.118-0.243,41.136,12.523
C16.168,25.282,1.956,53.733,5.382,81.306c2.392,19.268,13.129,36.165,28.466,47.021c0,0,42.277-37.776,53.504-51.181
c10.53-12.582,33.52-52.764,33.52-52.764C119.861,23.365,118.814,22.374,117.726,21.413z"/>
</g>
<g>
<path fill="#E74A99" d="M115.726,18.413c-0.016-0.017-0.035-0.027-0.053-0.042C94.307,0.014,64.118-3.243,39.136,9.523
C14.168,22.282-0.044,50.733,3.382,78.306c2.392,19.268,13.129,36.165,28.466,47.021c0,0,42.277-37.776,53.504-51.181
c10.53-12.582,33.52-52.764,33.52-52.764C117.861,20.365,116.814,19.374,115.726,18.413z"/>
</g>
</g>
<g>
<g opacity="0.3">
<path d="M33.849,128.327c7.067,5.001,15.11,8.726,23.765,10.801c27.076,6.487,56.27-5.293,71.759-28.261
c18.256-27.077,14.241-63.649-8.5-86.485c0,0-32.464,38.778-43.287,51.706C66.65,89.146,33.849,128.327,33.849,128.327z"/>
</g>
<g>
<path fill="#27AAE1" d="M31.849,125.327c7.067,5.001,15.11,8.726,23.765,10.801c27.076,6.487,56.27-5.293,71.759-28.261
c18.256-27.077,14.241-63.649-8.5-86.485c0,0-32.464,38.778-43.287,51.706C64.65,86.146,31.849,125.327,31.849,125.327z"/>
</g>
</g>
<g>
<image overflow="visible" opacity="0.3" width="354" height="324" xlink:href="data:image/png;base64,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
rkJggg==" transform="matrix(0.24 0 0 0.24 28.4971 38.3643)">
</image>
<g>
<path fill="#FFFFFF" d="M73.043,52.8c0,0-6.48-14.187-19.968-10.958c-13.486,3.23-41.652,30.792,17.853,65.083H70.88
c59.504-34.291,31.34-61.852,17.853-65.083C75.245,38.613,68.766,52.8,68.766,52.8H73.043z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 72 KiB

View file

@ -0,0 +1,10 @@
[Desktop Entry]
Name=LÖVE
Comment=The unquestionably awesome 2D game engine
MimeType=application/x-love-game;
Exec=/home/runner/work/love-appimage-source/love-appimage-source/installdir/bin/love %f
Type=Application
Categories=Development;Game;
Terminal=false
Icon=love
NoDisplay=true

View file

@ -0,0 +1,793 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="141.73px" height="141.73px" viewBox="0 0 141.73 141.73" enable-background="new 0 0 141.73 141.73" xml:space="preserve">
<path fill="#E74A99" d="M110.456,34.395C94.143,17.801,75.931,1.834,70.867,1.834c-7.744,0-68.033,60.968-68.033,68.031
c0,3.348,15.677,21.163,32.088,37.719c1.32-0.855,2.613-1.82,3.864-2.911C63.332,81.653,92.103,62.389,110.456,34.395z"/>
<g>
<g opacity="0.3">
<path d="M112.456,37.395c-18.354,27.994-47.125,47.258-71.67,70.278c-1.251,1.091-2.544,2.056-3.864,2.911
c15.575,15.732,31.811,30.313,35.945,30.313c9.35,0,68.029-61.892,68.029-68.031C140.896,68.501,127.492,52.679,112.456,37.395z"
/>
</g>
<g>
<path fill="#27AAE1" d="M110.456,34.395c-18.354,27.994-47.125,47.258-71.67,70.278c-1.251,1.091-2.544,2.056-3.864,2.911
c15.575,15.732,31.811,30.313,35.946,30.313c9.349,0,68.029-61.892,68.029-68.032C138.896,65.501,125.492,49.679,110.456,34.395z"
/>
</g>
</g>
<g>
<image overflow="visible" opacity="0.3" width="331" height="303" xlink:href="data:image/png;base64,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
RK5CYII=" transform="matrix(0.24 0 0 0.24 31.3364 40.5913)">
</image>
<g>
<path fill="#FFFFFF" d="M72.998,54.174c0,0-5.988-13.127-18.474-10.141c-12.477,2.991-38.536,28.483,16.517,60.218h-0.043
c55.057-31.734,28.998-57.227,16.525-60.218c-12.483-2.986-18.476,10.141-18.476,10.141H72.998z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 59 KiB

View file

@ -0,0 +1,189 @@
----------------------------------------------------------------------------
-- LuaJIT bytecode listing module.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
--
-- This module lists the bytecode of a Lua function. If it's loaded by -jbc
-- it hooks into the parser and lists all functions of a chunk as they
-- are parsed.
--
-- Example usage:
--
-- luajit -jbc -e 'local x=0; for i=1,1e6 do x=x+i end; print(x)'
-- luajit -jbc=- foo.lua
-- luajit -jbc=foo.list foo.lua
--
-- Default output is to stderr. To redirect the output to a file, pass a
-- filename as an argument (use '-' for stdout) or set the environment
-- variable LUAJIT_LISTFILE. The file is overwritten every time the module
-- is started.
--
-- This module can also be used programmatically:
--
-- local bc = require("jit.bc")
--
-- local function foo() print("hello") end
--
-- bc.dump(foo) --> -- BYTECODE -- [...]
-- print(bc.line(foo, 2)) --> 0002 KSTR 1 1 ; "hello"
--
-- local out = {
-- -- Do something with each line:
-- write = function(t, ...) io.write(...) end,
-- close = function(t) end,
-- flush = function(t) end,
-- }
-- bc.dump(foo, out)
--
------------------------------------------------------------------------------
-- Cache some library functions and objects.
local jit = require("jit")
local jutil = require("jit.util")
local vmdef = require("jit.vmdef")
local bit = require("bit")
local sub, gsub, format = string.sub, string.gsub, string.format
local byte, band, shr = string.byte, bit.band, bit.rshift
local funcinfo, funcbc, funck = jutil.funcinfo, jutil.funcbc, jutil.funck
local funcuvname = jutil.funcuvname
local bcnames = vmdef.bcnames
local stdout, stderr = io.stdout, io.stderr
------------------------------------------------------------------------------
local function ctlsub(c)
if c == "\n" then return "\\n"
elseif c == "\r" then return "\\r"
elseif c == "\t" then return "\\t"
else return format("\\%03d", byte(c))
end
end
-- Return one bytecode line.
local function bcline(func, pc, prefix)
local ins, m = funcbc(func, pc)
if not ins then return end
local ma, mb, mc = band(m, 7), band(m, 15*8), band(m, 15*128)
local a = band(shr(ins, 8), 0xff)
local oidx = 6*band(ins, 0xff)
local op = sub(bcnames, oidx+1, oidx+6)
local s = format("%04d %s %-6s %3s ",
pc, prefix or " ", op, ma == 0 and "" or a)
local d = shr(ins, 16)
if mc == 13*128 then -- BCMjump
return format("%s=> %04d\n", s, pc+d-0x7fff)
end
if mb ~= 0 then
d = band(d, 0xff)
elseif mc == 0 then
return s.."\n"
end
local kc
if mc == 10*128 then -- BCMstr
kc = funck(func, -d-1)
kc = format(#kc > 40 and '"%.40s"~' or '"%s"', gsub(kc, "%c", ctlsub))
elseif mc == 9*128 then -- BCMnum
kc = funck(func, d)
if op == "TSETM " then kc = kc - 2^52 end
elseif mc == 12*128 then -- BCMfunc
local fi = funcinfo(funck(func, -d-1))
if fi.ffid then
kc = vmdef.ffnames[fi.ffid]
else
kc = fi.loc
end
elseif mc == 5*128 then -- BCMuv
kc = funcuvname(func, d)
end
if ma == 5 then -- BCMuv
local ka = funcuvname(func, a)
if kc then kc = ka.." ; "..kc else kc = ka end
end
if mb ~= 0 then
local b = shr(ins, 24)
if kc then return format("%s%3d %3d ; %s\n", s, b, d, kc) end
return format("%s%3d %3d\n", s, b, d)
end
if kc then return format("%s%3d ; %s\n", s, d, kc) end
if mc == 7*128 and d > 32767 then d = d - 65536 end -- BCMlits
return format("%s%3d\n", s, d)
end
-- Collect branch targets of a function.
local function bctargets(func)
local target = {}
for pc=1,1000000000 do
local ins, m = funcbc(func, pc)
if not ins then break end
if band(m, 15*128) == 13*128 then target[pc+shr(ins, 16)-0x7fff] = true end
end
return target
end
-- Dump bytecode instructions of a function.
local function bcdump(func, out, all)
if not out then out = stdout end
local fi = funcinfo(func)
if all and fi.children then
for n=-1,-1000000000,-1 do
local k = funck(func, n)
if not k then break end
if type(k) == "proto" then bcdump(k, out, true) end
end
end
out:write(format("-- BYTECODE -- %s-%d\n", fi.loc, fi.lastlinedefined))
local target = bctargets(func)
for pc=1,1000000000 do
local s = bcline(func, pc, target[pc] and "=>")
if not s then break end
out:write(s)
end
out:write("\n")
out:flush()
end
------------------------------------------------------------------------------
-- Active flag and output file handle.
local active, out
-- List handler.
local function h_list(func)
return bcdump(func, out)
end
-- Detach list handler.
local function bclistoff()
if active then
active = false
jit.attach(h_list)
if out and out ~= stdout and out ~= stderr then out:close() end
out = nil
end
end
-- Open the output file and attach list handler.
local function bcliston(outfile)
if active then bclistoff() end
if not outfile then outfile = os.getenv("LUAJIT_LISTFILE") end
if outfile then
out = outfile == "-" and stdout or assert(io.open(outfile, "w"))
else
out = stderr
end
jit.attach(h_list, "bc")
active = true
end
-- Public module functions.
return {
line = bcline,
dump = bcdump,
targets = bctargets,
on = bcliston,
off = bclistoff,
start = bcliston -- For -j command line option.
}

View file

@ -0,0 +1,705 @@
----------------------------------------------------------------------------
-- LuaJIT module to save/list bytecode.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
--
-- This module saves or lists the bytecode for an input file.
-- It's run by the -b command line option.
--
------------------------------------------------------------------------------
local jit = require("jit")
assert(jit.version_num == 20199, "LuaJIT core/library version mismatch")
local bit = require("bit")
-- Symbol name prefix for LuaJIT bytecode.
local LJBC_PREFIX = "luaJIT_BC_"
local type, assert = type, assert
local format = string.format
local tremove, tconcat = table.remove, table.concat
------------------------------------------------------------------------------
local function usage()
io.stderr:write[[
Save LuaJIT bytecode: luajit -b[options] input output
-l Only list bytecode.
-s Strip debug info (default).
-g Keep debug info.
-n name Set module name (default: auto-detect from input name).
-t type Set output file type (default: auto-detect from output name).
-a arch Override architecture for object files (default: native).
-o os Override OS for object files (default: native).
-F name Override filename (default: input filename).
-e chunk Use chunk string as input.
-- Stop handling options.
- Use stdin as input and/or stdout as output.
File types: c cc h obj o raw (default)
]]
os.exit(1)
end
local function check(ok, ...)
if ok then return ok, ... end
io.stderr:write("luajit: ", ...)
io.stderr:write("\n")
os.exit(1)
end
local function readfile(ctx, input)
if type(input) == "function" then return input end
if ctx.filename then
local data
if input == "-" then
data = io.stdin:read("*a")
else
local fp = assert(io.open(input, "rb"))
data = assert(fp:read("*a"))
assert(fp:close())
end
return check(load(data, ctx.filename))
else
if input == "-" then input = nil end
return check(loadfile(input))
end
end
local function savefile(name, mode)
if name == "-" then return io.stdout end
return check(io.open(name, mode))
end
local function set_stdout_binary(ffi)
ffi.cdef[[int _setmode(int fd, int mode);]]
ffi.C._setmode(1, 0x8000)
end
------------------------------------------------------------------------------
local map_type = {
raw = "raw", c = "c", cc = "c", h = "h", o = "obj", obj = "obj",
}
local map_arch = {
x86 = { e = "le", b = 32, m = 3, p = 0x14c, },
x64 = { e = "le", b = 64, m = 62, p = 0x8664, },
arm = { e = "le", b = 32, m = 40, p = 0x1c0, },
arm64 = { e = "le", b = 64, m = 183, p = 0xaa64, },
arm64be = { e = "be", b = 64, m = 183, },
ppc = { e = "be", b = 32, m = 20, },
mips = { e = "be", b = 32, m = 8, f = 0x50001006, },
mipsel = { e = "le", b = 32, m = 8, f = 0x50001006, },
mips64 = { e = "be", b = 64, m = 8, f = 0x80000007, },
mips64el = { e = "le", b = 64, m = 8, f = 0x80000007, },
mips64r6 = { e = "be", b = 64, m = 8, f = 0xa0000407, },
mips64r6el = { e = "le", b = 64, m = 8, f = 0xa0000407, },
}
local map_os = {
linux = true, windows = true, osx = true, freebsd = true, netbsd = true,
openbsd = true, dragonfly = true, solaris = true,
}
local function checkarg(str, map, err)
str = str:lower()
local s = check(map[str], "unknown ", err)
return type(s) == "string" and s or str
end
local function detecttype(str)
local ext = str:lower():match("%.(%a+)$")
return map_type[ext] or "raw"
end
local function checkmodname(str)
check(str:match("^[%w_.%-]+$"), "bad module name")
return str:gsub("[%.%-]", "_")
end
local function detectmodname(str)
if type(str) == "string" then
local tail = str:match("[^/\\]+$")
if tail then str = tail end
local head = str:match("^(.*)%.[^.]*$")
if head then str = head end
str = str:match("^[%w_.%-]+")
else
str = nil
end
check(str, "cannot derive module name, use -n name")
return str:gsub("[%.%-]", "_")
end
------------------------------------------------------------------------------
local function bcsave_tail(fp, output, s)
local ok, err = fp:write(s)
if ok and output ~= "-" then ok, err = fp:close() end
check(ok, "cannot write ", output, ": ", err)
end
local function bcsave_raw(output, s)
if output == "-" and jit.os == "Windows" then
local ok, ffi = pcall(require, "ffi")
check(ok, "FFI library required to write binary file to stdout")
set_stdout_binary(ffi)
end
local fp = savefile(output, "wb")
bcsave_tail(fp, output, s)
end
local function bcsave_c(ctx, output, s)
local fp = savefile(output, "w")
if ctx.type == "c" then
fp:write(format([[
#ifdef __cplusplus
extern "C"
#endif
#ifdef _WIN32
__declspec(dllexport)
#endif
const unsigned char %s%s[] = {
]], LJBC_PREFIX, ctx.modname))
else
fp:write(format([[
#define %s%s_SIZE %d
static const unsigned char %s%s[] = {
]], LJBC_PREFIX, ctx.modname, #s, LJBC_PREFIX, ctx.modname))
end
local t, n, m = {}, 0, 0
for i=1,#s do
local b = tostring(string.byte(s, i))
m = m + #b + 1
if m > 78 then
fp:write(tconcat(t, ",", 1, n), ",\n")
n, m = 0, #b + 1
end
n = n + 1
t[n] = b
end
bcsave_tail(fp, output, tconcat(t, ",", 1, n).."\n};\n")
end
local function bcsave_elfobj(ctx, output, s, ffi)
ffi.cdef[[
typedef struct {
uint8_t emagic[4], eclass, eendian, eversion, eosabi, eabiversion, epad[7];
uint16_t type, machine;
uint32_t version;
uint32_t entry, phofs, shofs;
uint32_t flags;
uint16_t ehsize, phentsize, phnum, shentsize, shnum, shstridx;
} ELF32header;
typedef struct {
uint8_t emagic[4], eclass, eendian, eversion, eosabi, eabiversion, epad[7];
uint16_t type, machine;
uint32_t version;
uint64_t entry, phofs, shofs;
uint32_t flags;
uint16_t ehsize, phentsize, phnum, shentsize, shnum, shstridx;
} ELF64header;
typedef struct {
uint32_t name, type, flags, addr, ofs, size, link, info, align, entsize;
} ELF32sectheader;
typedef struct {
uint32_t name, type;
uint64_t flags, addr, ofs, size;
uint32_t link, info;
uint64_t align, entsize;
} ELF64sectheader;
typedef struct {
uint32_t name, value, size;
uint8_t info, other;
uint16_t sectidx;
} ELF32symbol;
typedef struct {
uint32_t name;
uint8_t info, other;
uint16_t sectidx;
uint64_t value, size;
} ELF64symbol;
typedef struct {
ELF32header hdr;
ELF32sectheader sect[6];
ELF32symbol sym[2];
uint8_t space[4096];
} ELF32obj;
typedef struct {
ELF64header hdr;
ELF64sectheader sect[6];
ELF64symbol sym[2];
uint8_t space[4096];
} ELF64obj;
]]
local symname = LJBC_PREFIX..ctx.modname
local ai = assert(map_arch[ctx.arch])
local is64, isbe = ai.b == 64, ai.e == "be"
-- Handle different host/target endianess.
local function f32(x) return x end
local f16, fofs = f32, f32
if ffi.abi("be") ~= isbe then
f32 = bit.bswap
function f16(x) return bit.rshift(bit.bswap(x), 16) end
if is64 then
local two32 = ffi.cast("int64_t", 2^32)
function fofs(x) return bit.bswap(x)*two32 end
else
fofs = f32
end
end
-- Create ELF object and fill in header.
local o = ffi.new(is64 and "ELF64obj" or "ELF32obj")
local hdr = o.hdr
if ctx.os == "bsd" or ctx.os == "other" then -- Determine native hdr.eosabi.
local bf = assert(io.open("/bin/ls", "rb"))
local bs = bf:read(9)
bf:close()
ffi.copy(o, bs, 9)
check(hdr.emagic[0] == 127, "no support for writing native object files")
else
hdr.emagic = "\127ELF"
hdr.eosabi = ({ freebsd=9, netbsd=2, openbsd=12, solaris=6 })[ctx.os] or 0
end
hdr.eclass = is64 and 2 or 1
hdr.eendian = isbe and 2 or 1
hdr.eversion = 1
hdr.type = f16(1)
hdr.machine = f16(ai.m)
hdr.flags = f32(ai.f or 0)
hdr.version = f32(1)
hdr.shofs = fofs(ffi.offsetof(o, "sect"))
hdr.ehsize = f16(ffi.sizeof(hdr))
hdr.shentsize = f16(ffi.sizeof(o.sect[0]))
hdr.shnum = f16(6)
hdr.shstridx = f16(2)
-- Fill in sections and symbols.
local sofs, ofs = ffi.offsetof(o, "space"), 1
for i,name in ipairs{
".symtab", ".shstrtab", ".strtab", ".rodata", ".note.GNU-stack",
} do
local sect = o.sect[i]
sect.align = fofs(1)
sect.name = f32(ofs)
ffi.copy(o.space+ofs, name)
ofs = ofs + #name+1
end
o.sect[1].type = f32(2) -- .symtab
o.sect[1].link = f32(3)
o.sect[1].info = f32(1)
o.sect[1].align = fofs(8)
o.sect[1].ofs = fofs(ffi.offsetof(o, "sym"))
o.sect[1].entsize = fofs(ffi.sizeof(o.sym[0]))
o.sect[1].size = fofs(ffi.sizeof(o.sym))
o.sym[1].name = f32(1)
o.sym[1].sectidx = f16(4)
o.sym[1].size = fofs(#s)
o.sym[1].info = 17
o.sect[2].type = f32(3) -- .shstrtab
o.sect[2].ofs = fofs(sofs)
o.sect[2].size = fofs(ofs)
o.sect[3].type = f32(3) -- .strtab
o.sect[3].ofs = fofs(sofs + ofs)
o.sect[3].size = fofs(#symname+2)
ffi.copy(o.space+ofs+1, symname)
ofs = ofs + #symname + 2
o.sect[4].type = f32(1) -- .rodata
o.sect[4].flags = fofs(2)
o.sect[4].ofs = fofs(sofs + ofs)
o.sect[4].size = fofs(#s)
o.sect[5].type = f32(1) -- .note.GNU-stack
o.sect[5].ofs = fofs(sofs + ofs + #s)
-- Write ELF object file.
local fp = savefile(output, "wb")
fp:write(ffi.string(o, ffi.sizeof(o)-4096+ofs))
bcsave_tail(fp, output, s)
end
local function bcsave_peobj(ctx, output, s, ffi)
ffi.cdef[[
typedef struct {
uint16_t arch, nsects;
uint32_t time, symtabofs, nsyms;
uint16_t opthdrsz, flags;
} PEheader;
typedef struct {
char name[8];
uint32_t vsize, vaddr, size, ofs, relocofs, lineofs;
uint16_t nreloc, nline;
uint32_t flags;
} PEsection;
typedef struct __attribute((packed)) {
union {
char name[8];
uint32_t nameref[2];
};
uint32_t value;
int16_t sect;
uint16_t type;
uint8_t scl, naux;
} PEsym;
typedef struct __attribute((packed)) {
uint32_t size;
uint16_t nreloc, nline;
uint32_t cksum;
uint16_t assoc;
uint8_t comdatsel, unused[3];
} PEsymaux;
typedef struct {
PEheader hdr;
PEsection sect[2];
// Must be an even number of symbol structs.
PEsym sym0;
PEsymaux sym0aux;
PEsym sym1;
PEsymaux sym1aux;
PEsym sym2;
PEsym sym3;
uint32_t strtabsize;
uint8_t space[4096];
} PEobj;
]]
local symname = LJBC_PREFIX..ctx.modname
local ai = assert(map_arch[ctx.arch])
local is64 = ai.b == 64
local symexport = " /EXPORT:"..symname..",DATA "
-- The file format is always little-endian. Swap if the host is big-endian.
local function f32(x) return x end
local f16 = f32
if ffi.abi("be") then
f32 = bit.bswap
function f16(x) return bit.rshift(bit.bswap(x), 16) end
end
-- Create PE object and fill in header.
local o = ffi.new("PEobj")
local hdr = o.hdr
hdr.arch = f16(assert(ai.p))
hdr.nsects = f16(2)
hdr.symtabofs = f32(ffi.offsetof(o, "sym0"))
hdr.nsyms = f32(6)
-- Fill in sections and symbols.
o.sect[0].name = ".drectve"
o.sect[0].size = f32(#symexport)
o.sect[0].flags = f32(0x00100a00)
o.sym0.sect = f16(1)
o.sym0.scl = 3
o.sym0.name = ".drectve"
o.sym0.naux = 1
o.sym0aux.size = f32(#symexport)
o.sect[1].name = ".rdata"
o.sect[1].size = f32(#s)
o.sect[1].flags = f32(0x40300040)
o.sym1.sect = f16(2)
o.sym1.scl = 3
o.sym1.name = ".rdata"
o.sym1.naux = 1
o.sym1aux.size = f32(#s)
o.sym2.sect = f16(2)
o.sym2.scl = 2
o.sym2.nameref[1] = f32(4)
o.sym3.sect = f16(-1)
o.sym3.scl = 2
o.sym3.value = f32(1)
o.sym3.name = "@feat.00" -- Mark as SafeSEH compliant.
ffi.copy(o.space, symname)
local ofs = #symname + 1
o.strtabsize = f32(ofs + 4)
o.sect[0].ofs = f32(ffi.offsetof(o, "space") + ofs)
ffi.copy(o.space + ofs, symexport)
ofs = ofs + #symexport
o.sect[1].ofs = f32(ffi.offsetof(o, "space") + ofs)
-- Write PE object file.
local fp = savefile(output, "wb")
fp:write(ffi.string(o, ffi.sizeof(o)-4096+ofs))
bcsave_tail(fp, output, s)
end
local function bcsave_machobj(ctx, output, s, ffi)
ffi.cdef[[
typedef struct
{
uint32_t magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags;
} mach_header;
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;
uint32_t offset, align, reloff, nreloc, flags;
uint32_t reserved1, reserved2, reserved3;
} mach_section_64;
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_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")
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
-- 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.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.
local fp = savefile(output, "wb")
fp:write(ffi.string(o, mach_size))
bcsave_tail(fp, output, s)
end
local function bcsave_obj(ctx, output, s)
local ok, ffi = pcall(require, "ffi")
check(ok, "FFI library required to write this file type")
if output == "-" and jit.os == "Windows" then
set_stdout_binary(ffi)
end
if ctx.os == "windows" then
return bcsave_peobj(ctx, output, s, ffi)
elseif ctx.os == "osx" then
return bcsave_machobj(ctx, output, s, ffi)
else
return bcsave_elfobj(ctx, output, s, ffi)
end
end
------------------------------------------------------------------------------
local function bclist(ctx, input, output)
local f = readfile(ctx, input)
require("jit.bc").dump(f, savefile(output, "w"), true)
end
local function bcsave(ctx, input, output)
local f = readfile(ctx, input)
local s = string.dump(f, ctx.strip)
local t = ctx.type
if not t then
t = detecttype(output)
ctx.type = t
end
if t == "raw" then
bcsave_raw(output, s)
else
if not ctx.modname then ctx.modname = detectmodname(input) end
if t == "obj" then
bcsave_obj(ctx, output, s)
else
bcsave_c(ctx, output, s)
end
end
end
local function docmd(...)
local arg = {...}
local n = 1
local list = false
local ctx = {
strip = true, arch = jit.arch, os = jit.os:lower(),
type = false, modname = false,
}
while n <= #arg do
local a = arg[n]
if type(a) == "string" and a:sub(1, 1) == "-" and a ~= "-" then
tremove(arg, n)
if a == "--" then break end
for m=2,#a do
local opt = a:sub(m, m)
if opt == "l" then
list = true
elseif opt == "s" then
ctx.strip = true
elseif opt == "g" then
ctx.strip = false
else
if arg[n] == nil or m ~= #a then usage() end
if opt == "e" then
if n ~= 1 then usage() end
arg[1] = check(loadstring(arg[1]))
elseif opt == "n" then
ctx.modname = checkmodname(tremove(arg, n))
elseif opt == "t" then
ctx.type = checkarg(tremove(arg, n), map_type, "file type")
elseif opt == "a" then
ctx.arch = checkarg(tremove(arg, n), map_arch, "architecture")
elseif opt == "o" then
ctx.os = checkarg(tremove(arg, n), map_os, "OS name")
elseif opt == "F" then
ctx.filename = "@"..tremove(arg, n)
else
usage()
end
end
end
else
n = n + 1
end
end
if list then
if #arg == 0 or #arg > 2 then usage() end
bclist(ctx, arg[1], arg[2] or "-")
else
if #arg ~= 2 then usage() end
bcsave(ctx, arg[1], arg[2])
end
end
------------------------------------------------------------------------------
-- Public module functions.
return {
start = docmd -- Process -b command line option.
}

View file

@ -0,0 +1,689 @@
----------------------------------------------------------------------------
-- LuaJIT ARM disassembler module.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- This is a helper module used by the LuaJIT machine code dumper module.
--
-- It disassembles most user-mode ARMv7 instructions
-- NYI: Advanced SIMD and VFP instructions.
------------------------------------------------------------------------------
local type = type
local sub, byte, format = string.sub, string.byte, string.format
local match, gmatch = string.match, string.gmatch
local concat = table.concat
local bit = require("bit")
local band, bor, ror, tohex = bit.band, bit.bor, bit.ror, bit.tohex
local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift
------------------------------------------------------------------------------
-- Opcode maps
------------------------------------------------------------------------------
local map_loadc = {
shift = 8, mask = 15,
[10] = {
shift = 20, mask = 1,
[0] = {
shift = 23, mask = 3,
[0] = "vmovFmDN", "vstmFNdr",
_ = {
shift = 21, mask = 1,
[0] = "vstrFdl",
{ shift = 16, mask = 15, [13] = "vpushFdr", _ = "vstmdbFNdr", }
},
},
{
shift = 23, mask = 3,
[0] = "vmovFDNm",
{ shift = 16, mask = 15, [13] = "vpopFdr", _ = "vldmFNdr", },
_ = {
shift = 21, mask = 1,
[0] = "vldrFdl", "vldmdbFNdr",
},
},
},
[11] = {
shift = 20, mask = 1,
[0] = {
shift = 23, mask = 3,
[0] = "vmovGmDN", "vstmGNdr",
_ = {
shift = 21, mask = 1,
[0] = "vstrGdl",
{ shift = 16, mask = 15, [13] = "vpushGdr", _ = "vstmdbGNdr", }
},
},
{
shift = 23, mask = 3,
[0] = "vmovGDNm",
{ shift = 16, mask = 15, [13] = "vpopGdr", _ = "vldmGNdr", },
_ = {
shift = 21, mask = 1,
[0] = "vldrGdl", "vldmdbGNdr",
},
},
},
_ = {
shift = 0, mask = 0 -- NYI ldc, mcrr, mrrc.
},
}
local map_vfps = {
shift = 6, mask = 0x2c001,
[0] = "vmlaF.dnm", "vmlsF.dnm",
[0x04000] = "vnmlsF.dnm", [0x04001] = "vnmlaF.dnm",
[0x08000] = "vmulF.dnm", [0x08001] = "vnmulF.dnm",
[0x0c000] = "vaddF.dnm", [0x0c001] = "vsubF.dnm",
[0x20000] = "vdivF.dnm",
[0x24000] = "vfnmsF.dnm", [0x24001] = "vfnmaF.dnm",
[0x28000] = "vfmaF.dnm", [0x28001] = "vfmsF.dnm",
[0x2c000] = "vmovF.dY",
[0x2c001] = {
shift = 7, mask = 0x1e01,
[0] = "vmovF.dm", "vabsF.dm",
[0x0200] = "vnegF.dm", [0x0201] = "vsqrtF.dm",
[0x0800] = "vcmpF.dm", [0x0801] = "vcmpeF.dm",
[0x0a00] = "vcmpzF.d", [0x0a01] = "vcmpzeF.d",
[0x0e01] = "vcvtG.dF.m",
[0x1000] = "vcvt.f32.u32Fdm", [0x1001] = "vcvt.f32.s32Fdm",
[0x1800] = "vcvtr.u32F.dm", [0x1801] = "vcvt.u32F.dm",
[0x1a00] = "vcvtr.s32F.dm", [0x1a01] = "vcvt.s32F.dm",
},
}
local map_vfpd = {
shift = 6, mask = 0x2c001,
[0] = "vmlaG.dnm", "vmlsG.dnm",
[0x04000] = "vnmlsG.dnm", [0x04001] = "vnmlaG.dnm",
[0x08000] = "vmulG.dnm", [0x08001] = "vnmulG.dnm",
[0x0c000] = "vaddG.dnm", [0x0c001] = "vsubG.dnm",
[0x20000] = "vdivG.dnm",
[0x24000] = "vfnmsG.dnm", [0x24001] = "vfnmaG.dnm",
[0x28000] = "vfmaG.dnm", [0x28001] = "vfmsG.dnm",
[0x2c000] = "vmovG.dY",
[0x2c001] = {
shift = 7, mask = 0x1e01,
[0] = "vmovG.dm", "vabsG.dm",
[0x0200] = "vnegG.dm", [0x0201] = "vsqrtG.dm",
[0x0800] = "vcmpG.dm", [0x0801] = "vcmpeG.dm",
[0x0a00] = "vcmpzG.d", [0x0a01] = "vcmpzeG.d",
[0x0e01] = "vcvtF.dG.m",
[0x1000] = "vcvt.f64.u32GdFm", [0x1001] = "vcvt.f64.s32GdFm",
[0x1800] = "vcvtr.u32FdG.m", [0x1801] = "vcvt.u32FdG.m",
[0x1a00] = "vcvtr.s32FdG.m", [0x1a01] = "vcvt.s32FdG.m",
},
}
local map_datac = {
shift = 24, mask = 1,
[0] = {
shift = 4, mask = 1,
[0] = {
shift = 8, mask = 15,
[10] = map_vfps,
[11] = map_vfpd,
-- NYI cdp, mcr, mrc.
},
{
shift = 8, mask = 15,
[10] = {
shift = 20, mask = 15,
[0] = "vmovFnD", "vmovFDn",
[14] = "vmsrD",
[15] = { shift = 12, mask = 15, [15] = "vmrs", _ = "vmrsD", },
},
},
},
"svcT",
}
local map_loadcu = {
shift = 0, mask = 0, -- NYI unconditional CP load/store.
}
local map_datacu = {
shift = 0, mask = 0, -- NYI unconditional CP data.
}
local map_simddata = {
shift = 0, mask = 0, -- NYI SIMD data.
}
local map_simdload = {
shift = 0, mask = 0, -- NYI SIMD load/store, preload.
}
local map_preload = {
shift = 0, mask = 0, -- NYI preload.
}
local map_media = {
shift = 20, mask = 31,
[0] = false,
{ --01
shift = 5, mask = 7,
[0] = "sadd16DNM", "sasxDNM", "ssaxDNM", "ssub16DNM",
"sadd8DNM", false, false, "ssub8DNM",
},
{ --02
shift = 5, mask = 7,
[0] = "qadd16DNM", "qasxDNM", "qsaxDNM", "qsub16DNM",
"qadd8DNM", false, false, "qsub8DNM",
},
{ --03
shift = 5, mask = 7,
[0] = "shadd16DNM", "shasxDNM", "shsaxDNM", "shsub16DNM",
"shadd8DNM", false, false, "shsub8DNM",
},
false,
{ --05
shift = 5, mask = 7,
[0] = "uadd16DNM", "uasxDNM", "usaxDNM", "usub16DNM",
"uadd8DNM", false, false, "usub8DNM",
},
{ --06
shift = 5, mask = 7,
[0] = "uqadd16DNM", "uqasxDNM", "uqsaxDNM", "uqsub16DNM",
"uqadd8DNM", false, false, "uqsub8DNM",
},
{ --07
shift = 5, mask = 7,
[0] = "uhadd16DNM", "uhasxDNM", "uhsaxDNM", "uhsub16DNM",
"uhadd8DNM", false, false, "uhsub8DNM",
},
{ --08
shift = 5, mask = 7,
[0] = "pkhbtDNMU", false, "pkhtbDNMU",
{ shift = 16, mask = 15, [15] = "sxtb16DMU", _ = "sxtab16DNMU", },
"pkhbtDNMU", "selDNM", "pkhtbDNMU",
},
false,
{ --0a
shift = 5, mask = 7,
[0] = "ssatDxMu", "ssat16DxM", "ssatDxMu",
{ shift = 16, mask = 15, [15] = "sxtbDMU", _ = "sxtabDNMU", },
"ssatDxMu", false, "ssatDxMu",
},
{ --0b
shift = 5, mask = 7,
[0] = "ssatDxMu", "revDM", "ssatDxMu",
{ shift = 16, mask = 15, [15] = "sxthDMU", _ = "sxtahDNMU", },
"ssatDxMu", "rev16DM", "ssatDxMu",
},
{ --0c
shift = 5, mask = 7,
[3] = { shift = 16, mask = 15, [15] = "uxtb16DMU", _ = "uxtab16DNMU", },
},
false,
{ --0e
shift = 5, mask = 7,
[0] = "usatDwMu", "usat16DwM", "usatDwMu",
{ shift = 16, mask = 15, [15] = "uxtbDMU", _ = "uxtabDNMU", },
"usatDwMu", false, "usatDwMu",
},
{ --0f
shift = 5, mask = 7,
[0] = "usatDwMu", "rbitDM", "usatDwMu",
{ shift = 16, mask = 15, [15] = "uxthDMU", _ = "uxtahDNMU", },
"usatDwMu", "revshDM", "usatDwMu",
},
{ --10
shift = 12, mask = 15,
[15] = {
shift = 5, mask = 7,
"smuadNMS", "smuadxNMS", "smusdNMS", "smusdxNMS",
},
_ = {
shift = 5, mask = 7,
[0] = "smladNMSD", "smladxNMSD", "smlsdNMSD", "smlsdxNMSD",
},
},
false, false, false,
{ --14
shift = 5, mask = 7,
[0] = "smlaldDNMS", "smlaldxDNMS", "smlsldDNMS", "smlsldxDNMS",
},
{ --15
shift = 5, mask = 7,
[0] = { shift = 12, mask = 15, [15] = "smmulNMS", _ = "smmlaNMSD", },
{ shift = 12, mask = 15, [15] = "smmulrNMS", _ = "smmlarNMSD", },
false, false, false, false,
"smmlsNMSD", "smmlsrNMSD",
},
false, false,
{ --18
shift = 5, mask = 7,
[0] = { shift = 12, mask = 15, [15] = "usad8NMS", _ = "usada8NMSD", },
},
false,
{ --1a
shift = 5, mask = 3, [2] = "sbfxDMvw",
},
{ --1b
shift = 5, mask = 3, [2] = "sbfxDMvw",
},
{ --1c
shift = 5, mask = 3,
[0] = { shift = 0, mask = 15, [15] = "bfcDvX", _ = "bfiDMvX", },
},
{ --1d
shift = 5, mask = 3,
[0] = { shift = 0, mask = 15, [15] = "bfcDvX", _ = "bfiDMvX", },
},
{ --1e
shift = 5, mask = 3, [2] = "ubfxDMvw",
},
{ --1f
shift = 5, mask = 3, [2] = "ubfxDMvw",
},
}
local map_load = {
shift = 21, mask = 9,
{
shift = 20, mask = 5,
[0] = "strtDL", "ldrtDL", [4] = "strbtDL", [5] = "ldrbtDL",
},
_ = {
shift = 20, mask = 5,
[0] = "strDL", "ldrDL", [4] = "strbDL", [5] = "ldrbDL",
}
}
local map_load1 = {
shift = 4, mask = 1,
[0] = map_load, map_media,
}
local map_loadm = {
shift = 20, mask = 1,
[0] = {
shift = 23, mask = 3,
[0] = "stmdaNR", "stmNR",
{ shift = 16, mask = 63, [45] = "pushR", _ = "stmdbNR", }, "stmibNR",
},
{
shift = 23, mask = 3,
[0] = "ldmdaNR", { shift = 16, mask = 63, [61] = "popR", _ = "ldmNR", },
"ldmdbNR", "ldmibNR",
},
}
local map_data = {
shift = 21, mask = 15,
[0] = "andDNPs", "eorDNPs", "subDNPs", "rsbDNPs",
"addDNPs", "adcDNPs", "sbcDNPs", "rscDNPs",
"tstNP", "teqNP", "cmpNP", "cmnNP",
"orrDNPs", "movDPs", "bicDNPs", "mvnDPs",
}
local map_mul = {
shift = 21, mask = 7,
[0] = "mulNMSs", "mlaNMSDs", "umaalDNMS", "mlsDNMS",
"umullDNMSs", "umlalDNMSs", "smullDNMSs", "smlalDNMSs",
}
local map_sync = {
shift = 20, mask = 15, -- NYI: brackets around N. R(D+1) for ldrexd/strexd.
[0] = "swpDMN", false, false, false,
"swpbDMN", false, false, false,
"strexDMN", "ldrexDN", "strexdDN", "ldrexdDN",
"strexbDMN", "ldrexbDN", "strexhDN", "ldrexhDN",
}
local map_mulh = {
shift = 21, mask = 3,
[0] = { shift = 5, mask = 3,
[0] = "smlabbNMSD", "smlatbNMSD", "smlabtNMSD", "smlattNMSD", },
{ shift = 5, mask = 3,
[0] = "smlawbNMSD", "smulwbNMS", "smlawtNMSD", "smulwtNMS", },
{ shift = 5, mask = 3,
[0] = "smlalbbDNMS", "smlaltbDNMS", "smlalbtDNMS", "smlalttDNMS", },
{ shift = 5, mask = 3,
[0] = "smulbbNMS", "smultbNMS", "smulbtNMS", "smulttNMS", },
}
local map_misc = {
shift = 4, mask = 7,
-- NYI: decode PSR bits of msr.
[0] = { shift = 21, mask = 1, [0] = "mrsD", "msrM", },
{ shift = 21, mask = 3, "bxM", false, "clzDM", },
{ shift = 21, mask = 3, "bxjM", },
{ shift = 21, mask = 3, "blxM", },
false,
{ shift = 21, mask = 3, [0] = "qaddDMN", "qsubDMN", "qdaddDMN", "qdsubDMN", },
false,
{ shift = 21, mask = 3, "bkptK", },
}
local map_datar = {
shift = 4, mask = 9,
[9] = {
shift = 5, mask = 3,
[0] = { shift = 24, mask = 1, [0] = map_mul, map_sync, },
{ shift = 20, mask = 1, [0] = "strhDL", "ldrhDL", },
{ shift = 20, mask = 1, [0] = "ldrdDL", "ldrsbDL", },
{ shift = 20, mask = 1, [0] = "strdDL", "ldrshDL", },
},
_ = {
shift = 20, mask = 25,
[16] = { shift = 7, mask = 1, [0] = map_misc, map_mulh, },
_ = {
shift = 0, mask = 0xffffffff,
[bor(0xe1a00000)] = "nop",
_ = map_data,
}
},
}
local map_datai = {
shift = 20, mask = 31, -- NYI: decode PSR bits of msr. Decode imm12.
[16] = "movwDW", [20] = "movtDW",
[18] = { shift = 0, mask = 0xf00ff, [0] = "nopv6", _ = "msrNW", },
[22] = "msrNW",
_ = map_data,
}
local map_branch = {
shift = 24, mask = 1,
[0] = "bB", "blB"
}
local map_condins = {
[0] = map_datar, map_datai, map_load, map_load1,
map_loadm, map_branch, map_loadc, map_datac
}
-- NYI: setend.
local map_uncondins = {
[0] = false, map_simddata, map_simdload, map_preload,
false, "blxB", map_loadcu, map_datacu,
}
------------------------------------------------------------------------------
local map_gpr = {
[0] = "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc",
}
local map_cond = {
[0] = "eq", "ne", "hs", "lo", "mi", "pl", "vs", "vc",
"hi", "ls", "ge", "lt", "gt", "le", "al",
}
local map_shift = { [0] = "lsl", "lsr", "asr", "ror", }
------------------------------------------------------------------------------
-- Output a nicely formatted line with an opcode and operands.
local function putop(ctx, text, operands)
local pos = ctx.pos
local extra = ""
if ctx.rel then
local sym = ctx.symtab[ctx.rel]
if sym then
extra = "\t->"..sym
elseif band(ctx.op, 0x0e000000) ~= 0x0a000000 then
extra = "\t; 0x"..tohex(ctx.rel)
end
end
if ctx.hexdump > 0 then
ctx.out(format("%08x %s %-5s %s%s\n",
ctx.addr+pos, tohex(ctx.op), text, concat(operands, ", "), extra))
else
ctx.out(format("%08x %-5s %s%s\n",
ctx.addr+pos, text, concat(operands, ", "), extra))
end
ctx.pos = pos + 4
end
-- Fallback for unknown opcodes.
local function unknown(ctx)
return putop(ctx, ".long", { "0x"..tohex(ctx.op) })
end
-- Format operand 2 of load/store opcodes.
local function fmtload(ctx, op, pos)
local base = map_gpr[band(rshift(op, 16), 15)]
local x, ofs
local ext = (band(op, 0x04000000) == 0)
if not ext and band(op, 0x02000000) == 0 then
ofs = band(op, 4095)
if band(op, 0x00800000) == 0 then ofs = -ofs end
if base == "pc" then ctx.rel = ctx.addr + pos + 8 + ofs end
ofs = "#"..ofs
elseif ext and band(op, 0x00400000) ~= 0 then
ofs = band(op, 15) + band(rshift(op, 4), 0xf0)
if band(op, 0x00800000) == 0 then ofs = -ofs end
if base == "pc" then ctx.rel = ctx.addr + pos + 8 + ofs end
ofs = "#"..ofs
else
ofs = map_gpr[band(op, 15)]
if ext or band(op, 0xfe0) == 0 then
elseif band(op, 0xfe0) == 0x60 then
ofs = format("%s, rrx", ofs)
else
local sh = band(rshift(op, 7), 31)
if sh == 0 then sh = 32 end
ofs = format("%s, %s #%d", ofs, map_shift[band(rshift(op, 5), 3)], sh)
end
if band(op, 0x00800000) == 0 then ofs = "-"..ofs end
end
if ofs == "#0" then
x = format("[%s]", base)
elseif band(op, 0x01000000) == 0 then
x = format("[%s], %s", base, ofs)
else
x = format("[%s, %s]", base, ofs)
end
if band(op, 0x01200000) == 0x01200000 then x = x.."!" end
return x
end
-- Format operand 2 of vector load/store opcodes.
local function fmtvload(ctx, op, pos)
local base = map_gpr[band(rshift(op, 16), 15)]
local ofs = band(op, 255)*4
if band(op, 0x00800000) == 0 then ofs = -ofs end
if base == "pc" then ctx.rel = ctx.addr + pos + 8 + ofs end
if ofs == 0 then
return format("[%s]", base)
else
return format("[%s, #%d]", base, ofs)
end
end
local function fmtvr(op, vr, sh0, sh1)
if vr == "s" then
return format("s%d", 2*band(rshift(op, sh0), 15)+band(rshift(op, sh1), 1))
else
return format("d%d", band(rshift(op, sh0), 15)+band(rshift(op, sh1-4), 16))
end
end
-- Disassemble a single instruction.
local function disass_ins(ctx)
local pos = ctx.pos
local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4)
local op = bor(lshift(b3, 24), lshift(b2, 16), lshift(b1, 8), b0)
local operands = {}
local suffix = ""
local last, name, pat
local vr
ctx.op = op
ctx.rel = nil
local cond = rshift(op, 28)
local opat
if cond == 15 then
opat = map_uncondins[band(rshift(op, 25), 7)]
else
if cond ~= 14 then suffix = map_cond[cond] end
opat = map_condins[band(rshift(op, 25), 7)]
end
while type(opat) ~= "string" do
if not opat then return unknown(ctx) end
opat = opat[band(rshift(op, opat.shift), opat.mask)] or opat._
end
name, pat = match(opat, "^([a-z0-9]*)(.*)")
if sub(pat, 1, 1) == "." then
local s2, p2 = match(pat, "^([a-z0-9.]*)(.*)")
suffix = suffix..s2
pat = p2
end
for p in gmatch(pat, ".") do
local x = nil
if p == "D" then
x = map_gpr[band(rshift(op, 12), 15)]
elseif p == "N" then
x = map_gpr[band(rshift(op, 16), 15)]
elseif p == "S" then
x = map_gpr[band(rshift(op, 8), 15)]
elseif p == "M" then
x = map_gpr[band(op, 15)]
elseif p == "d" then
x = fmtvr(op, vr, 12, 22)
elseif p == "n" then
x = fmtvr(op, vr, 16, 7)
elseif p == "m" then
x = fmtvr(op, vr, 0, 5)
elseif p == "P" then
if band(op, 0x02000000) ~= 0 then
x = ror(band(op, 255), 2*band(rshift(op, 8), 15))
else
x = map_gpr[band(op, 15)]
if band(op, 0xff0) ~= 0 then
operands[#operands+1] = x
local s = map_shift[band(rshift(op, 5), 3)]
local r = nil
if band(op, 0xf90) == 0 then
if s == "ror" then s = "rrx" else r = "#32" end
elseif band(op, 0x10) == 0 then
r = "#"..band(rshift(op, 7), 31)
else
r = map_gpr[band(rshift(op, 8), 15)]
end
if name == "mov" then name = s; x = r
elseif r then x = format("%s %s", s, r)
else x = s end
end
end
elseif p == "L" then
x = fmtload(ctx, op, pos)
elseif p == "l" then
x = fmtvload(ctx, op, pos)
elseif p == "B" then
local addr = ctx.addr + pos + 8 + arshift(lshift(op, 8), 6)
if cond == 15 then addr = addr + band(rshift(op, 23), 2) end
ctx.rel = addr
x = "0x"..tohex(addr)
elseif p == "F" then
vr = "s"
elseif p == "G" then
vr = "d"
elseif p == "." then
suffix = suffix..(vr == "s" and ".f32" or ".f64")
elseif p == "R" then
if band(op, 0x00200000) ~= 0 and #operands == 1 then
operands[1] = operands[1].."!"
end
local t = {}
for i=0,15 do
if band(rshift(op, i), 1) == 1 then t[#t+1] = map_gpr[i] end
end
x = "{"..concat(t, ", ").."}"
elseif p == "r" then
if band(op, 0x00200000) ~= 0 and #operands == 2 then
operands[1] = operands[1].."!"
end
local s = tonumber(sub(last, 2))
local n = band(op, 255)
if vr == "d" then n = rshift(n, 1) end
operands[#operands] = format("{%s-%s%d}", last, vr, s+n-1)
elseif p == "W" then
x = band(op, 0x0fff) + band(rshift(op, 4), 0xf000)
elseif p == "T" then
x = "#0x"..tohex(band(op, 0x00ffffff), 6)
elseif p == "U" then
x = band(rshift(op, 7), 31)
if x == 0 then x = nil end
elseif p == "u" then
x = band(rshift(op, 7), 31)
if band(op, 0x40) == 0 then
if x == 0 then x = nil else x = "lsl #"..x end
else
if x == 0 then x = "asr #32" else x = "asr #"..x end
end
elseif p == "v" then
x = band(rshift(op, 7), 31)
elseif p == "w" then
x = band(rshift(op, 16), 31)
elseif p == "x" then
x = band(rshift(op, 16), 31) + 1
elseif p == "X" then
x = band(rshift(op, 16), 31) - last + 1
elseif p == "Y" then
x = band(rshift(op, 12), 0xf0) + band(op, 0x0f)
elseif p == "K" then
x = "#0x"..tohex(band(rshift(op, 4), 0x0000fff0) + band(op, 15), 4)
elseif p == "s" then
if band(op, 0x00100000) ~= 0 then suffix = "s"..suffix end
else
assert(false)
end
if x then
last = x
if type(x) == "number" then x = "#"..x end
operands[#operands+1] = x
end
end
return putop(ctx, name..suffix, operands)
end
------------------------------------------------------------------------------
-- Disassemble a block of code.
local function disass_block(ctx, ofs, len)
if not ofs then ofs = 0 end
local stop = len and ofs+len or #ctx.code
ctx.pos = ofs
ctx.rel = nil
while ctx.pos < stop do disass_ins(ctx) end
end
-- Extended API: create a disassembler context. Then call ctx:disass(ofs, len).
local function create(code, addr, out)
local ctx = {}
ctx.code = code
ctx.addr = addr or 0
ctx.out = out or io.write
ctx.symtab = {}
ctx.disass = disass_block
ctx.hexdump = 8
return ctx
end
-- Simple API: disassemble code (a string) at address and output via out.
local function disass(code, addr, out)
create(code, addr, out):disass()
end
-- Return register name for RID.
local function regname(r)
if r < 16 then return map_gpr[r] end
return "d"..(r-16)
end
-- Public module functions.
return {
create = create,
disass = disass,
regname = regname
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,12 @@
----------------------------------------------------------------------------
-- LuaJIT ARM64BE disassembler wrapper module.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- ARM64 instructions are always little-endian. So just forward to the
-- common ARM64 disassembler module. All the interesting stuff is there.
------------------------------------------------------------------------------
return require((string.match(..., ".*%.") or "").."dis_arm64")

View file

@ -0,0 +1,694 @@
----------------------------------------------------------------------------
-- LuaJIT MIPS disassembler module.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT/X license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- This is a helper module used by the LuaJIT machine code dumper module.
--
-- It disassembles all standard MIPS32R1/R2 instructions.
-- Default mode is big-endian, but see: dis_mipsel.lua
------------------------------------------------------------------------------
local type = type
local byte, format = string.byte, string.format
local match, gmatch = string.match, string.gmatch
local concat = table.concat
local bit = require("bit")
local band, bor, tohex = bit.band, bit.bor, bit.tohex
local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift
------------------------------------------------------------------------------
-- Extended opcode maps common to all MIPS releases
------------------------------------------------------------------------------
local map_srl = { shift = 21, mask = 1, [0] = "srlDTA", "rotrDTA", }
local map_srlv = { shift = 6, mask = 1, [0] = "srlvDTS", "rotrvDTS", }
local map_cop0 = {
shift = 25, mask = 1,
[0] = {
shift = 21, mask = 15,
[0] = "mfc0TDW", [4] = "mtc0TDW",
[10] = "rdpgprDT",
[11] = { shift = 5, mask = 1, [0] = "diT0", "eiT0", },
[14] = "wrpgprDT",
}, {
shift = 0, mask = 63,
[1] = "tlbr", [2] = "tlbwi", [6] = "tlbwr", [8] = "tlbp",
[24] = "eret", [31] = "deret",
[32] = "wait",
},
}
------------------------------------------------------------------------------
-- Primary and extended opcode maps for MIPS R1-R5
------------------------------------------------------------------------------
local map_movci = { shift = 16, mask = 1, [0] = "movfDSC", "movtDSC", }
local map_special = {
shift = 0, mask = 63,
[0] = { shift = 0, mask = -1, [0] = "nop", _ = "sllDTA" },
map_movci, map_srl, "sraDTA",
"sllvDTS", false, map_srlv, "sravDTS",
"jrS", "jalrD1S", "movzDST", "movnDST",
"syscallY", "breakY", false, "sync",
"mfhiD", "mthiS", "mfloD", "mtloS",
"dsllvDST", false, "dsrlvDST", "dsravDST",
"multST", "multuST", "divST", "divuST",
"dmultST", "dmultuST", "ddivST", "ddivuST",
"addDST", "addu|moveDST0", "subDST", "subu|neguDS0T",
"andDST", "or|moveDST0", "xorDST", "nor|notDST0",
false, false, "sltDST", "sltuDST",
"daddDST", "dadduDST", "dsubDST", "dsubuDST",
"tgeSTZ", "tgeuSTZ", "tltSTZ", "tltuSTZ",
"teqSTZ", false, "tneSTZ", false,
"dsllDTA", false, "dsrlDTA", "dsraDTA",
"dsll32DTA", false, "dsrl32DTA", "dsra32DTA",
}
local map_special2 = {
shift = 0, mask = 63,
[0] = "maddST", "madduST", "mulDST", false,
"msubST", "msubuST",
[32] = "clzDS", [33] = "cloDS",
[63] = "sdbbpY",
}
local map_bshfl = {
shift = 6, mask = 31,
[2] = "wsbhDT",
[16] = "sebDT",
[24] = "sehDT",
}
local map_dbshfl = {
shift = 6, mask = 31,
[2] = "dsbhDT",
[5] = "dshdDT",
}
local map_special3 = {
shift = 0, mask = 63,
[0] = "extTSAK", [1] = "dextmTSAP", [3] = "dextTSAK",
[4] = "insTSAL", [6] = "dinsuTSEQ", [7] = "dinsTSAL",
[32] = map_bshfl, [36] = map_dbshfl, [59] = "rdhwrTD",
}
local map_regimm = {
shift = 16, mask = 31,
[0] = "bltzSB", "bgezSB", "bltzlSB", "bgezlSB",
false, false, false, false,
"tgeiSI", "tgeiuSI", "tltiSI", "tltiuSI",
"teqiSI", false, "tneiSI", false,
"bltzalSB", "bgezalSB", "bltzallSB", "bgezallSB",
false, false, false, false,
false, false, false, false,
false, false, false, "synciSO",
}
local map_cop1s = {
shift = 0, mask = 63,
[0] = "add.sFGH", "sub.sFGH", "mul.sFGH", "div.sFGH",
"sqrt.sFG", "abs.sFG", "mov.sFG", "neg.sFG",
"round.l.sFG", "trunc.l.sFG", "ceil.l.sFG", "floor.l.sFG",
"round.w.sFG", "trunc.w.sFG", "ceil.w.sFG", "floor.w.sFG",
false,
{ shift = 16, mask = 1, [0] = "movf.sFGC", "movt.sFGC" },
"movz.sFGT", "movn.sFGT",
false, "recip.sFG", "rsqrt.sFG", false,
false, false, false, false,
false, false, false, false,
false, "cvt.d.sFG", false, false,
"cvt.w.sFG", "cvt.l.sFG", "cvt.ps.sFGH", false,
false, false, false, false,
false, false, false, false,
"c.f.sVGH", "c.un.sVGH", "c.eq.sVGH", "c.ueq.sVGH",
"c.olt.sVGH", "c.ult.sVGH", "c.ole.sVGH", "c.ule.sVGH",
"c.sf.sVGH", "c.ngle.sVGH", "c.seq.sVGH", "c.ngl.sVGH",
"c.lt.sVGH", "c.nge.sVGH", "c.le.sVGH", "c.ngt.sVGH",
}
local map_cop1d = {
shift = 0, mask = 63,
[0] = "add.dFGH", "sub.dFGH", "mul.dFGH", "div.dFGH",
"sqrt.dFG", "abs.dFG", "mov.dFG", "neg.dFG",
"round.l.dFG", "trunc.l.dFG", "ceil.l.dFG", "floor.l.dFG",
"round.w.dFG", "trunc.w.dFG", "ceil.w.dFG", "floor.w.dFG",
false,
{ shift = 16, mask = 1, [0] = "movf.dFGC", "movt.dFGC" },
"movz.dFGT", "movn.dFGT",
false, "recip.dFG", "rsqrt.dFG", false,
false, false, false, false,
false, false, false, false,
"cvt.s.dFG", false, false, false,
"cvt.w.dFG", "cvt.l.dFG", false, false,
false, false, false, false,
false, false, false, false,
"c.f.dVGH", "c.un.dVGH", "c.eq.dVGH", "c.ueq.dVGH",
"c.olt.dVGH", "c.ult.dVGH", "c.ole.dVGH", "c.ule.dVGH",
"c.df.dVGH", "c.ngle.dVGH", "c.deq.dVGH", "c.ngl.dVGH",
"c.lt.dVGH", "c.nge.dVGH", "c.le.dVGH", "c.ngt.dVGH",
}
local map_cop1ps = {
shift = 0, mask = 63,
[0] = "add.psFGH", "sub.psFGH", "mul.psFGH", false,
false, "abs.psFG", "mov.psFG", "neg.psFG",
false, false, false, false,
false, false, false, false,
false,
{ shift = 16, mask = 1, [0] = "movf.psFGC", "movt.psFGC" },
"movz.psFGT", "movn.psFGT",
false, false, false, false,
false, false, false, false,
false, false, false, false,
"cvt.s.puFG", false, false, false,
false, false, false, false,
"cvt.s.plFG", false, false, false,
"pll.psFGH", "plu.psFGH", "pul.psFGH", "puu.psFGH",
"c.f.psVGH", "c.un.psVGH", "c.eq.psVGH", "c.ueq.psVGH",
"c.olt.psVGH", "c.ult.psVGH", "c.ole.psVGH", "c.ule.psVGH",
"c.psf.psVGH", "c.ngle.psVGH", "c.pseq.psVGH", "c.ngl.psVGH",
"c.lt.psVGH", "c.nge.psVGH", "c.le.psVGH", "c.ngt.psVGH",
}
local map_cop1w = {
shift = 0, mask = 63,
[32] = "cvt.s.wFG", [33] = "cvt.d.wFG",
}
local map_cop1l = {
shift = 0, mask = 63,
[32] = "cvt.s.lFG", [33] = "cvt.d.lFG",
}
local map_cop1bc = {
shift = 16, mask = 3,
[0] = "bc1fCB", "bc1tCB", "bc1flCB", "bc1tlCB",
}
local map_cop1 = {
shift = 21, mask = 31,
[0] = "mfc1TG", "dmfc1TG", "cfc1TG", "mfhc1TG",
"mtc1TG", "dmtc1TG", "ctc1TG", "mthc1TG",
map_cop1bc, false, false, false,
false, false, false, false,
map_cop1s, map_cop1d, false, false,
map_cop1w, map_cop1l, map_cop1ps,
}
local map_cop1x = {
shift = 0, mask = 63,
[0] = "lwxc1FSX", "ldxc1FSX", false, false,
false, "luxc1FSX", false, false,
"swxc1FSX", "sdxc1FSX", false, false,
false, "suxc1FSX", false, "prefxMSX",
false, false, false, false,
false, false, false, false,
false, false, false, false,
false, false, "alnv.psFGHS", false,
"madd.sFRGH", "madd.dFRGH", false, false,
false, false, "madd.psFRGH", false,
"msub.sFRGH", "msub.dFRGH", false, false,
false, false, "msub.psFRGH", false,
"nmadd.sFRGH", "nmadd.dFRGH", false, false,
false, false, "nmadd.psFRGH", false,
"nmsub.sFRGH", "nmsub.dFRGH", false, false,
false, false, "nmsub.psFRGH", false,
}
local map_pri = {
[0] = map_special, map_regimm, "jJ", "jalJ",
"beq|beqz|bST00B", "bne|bnezST0B", "blezSB", "bgtzSB",
"addiTSI", "addiu|liTS0I", "sltiTSI", "sltiuTSI",
"andiTSU", "ori|liTS0U", "xoriTSU", "luiTU",
map_cop0, map_cop1, false, map_cop1x,
"beql|beqzlST0B", "bnel|bnezlST0B", "blezlSB", "bgtzlSB",
"daddiTSI", "daddiuTSI", false, false,
map_special2, "jalxJ", false, map_special3,
"lbTSO", "lhTSO", "lwlTSO", "lwTSO",
"lbuTSO", "lhuTSO", "lwrTSO", false,
"sbTSO", "shTSO", "swlTSO", "swTSO",
false, false, "swrTSO", "cacheNSO",
"llTSO", "lwc1HSO", "lwc2TSO", "prefNSO",
false, "ldc1HSO", "ldc2TSO", "ldTSO",
"scTSO", "swc1HSO", "swc2TSO", false,
false, "sdc1HSO", "sdc2TSO", "sdTSO",
}
------------------------------------------------------------------------------
-- Primary and extended opcode maps for MIPS R6
------------------------------------------------------------------------------
local map_mul_r6 = { shift = 6, mask = 3, [2] = "mulDST", [3] = "muhDST" }
local map_mulu_r6 = { shift = 6, mask = 3, [2] = "muluDST", [3] = "muhuDST" }
local map_div_r6 = { shift = 6, mask = 3, [2] = "divDST", [3] = "modDST" }
local map_divu_r6 = { shift = 6, mask = 3, [2] = "divuDST", [3] = "moduDST" }
local map_dmul_r6 = { shift = 6, mask = 3, [2] = "dmulDST", [3] = "dmuhDST" }
local map_dmulu_r6 = { shift = 6, mask = 3, [2] = "dmuluDST", [3] = "dmuhuDST" }
local map_ddiv_r6 = { shift = 6, mask = 3, [2] = "ddivDST", [3] = "dmodDST" }
local map_ddivu_r6 = { shift = 6, mask = 3, [2] = "ddivuDST", [3] = "dmoduDST" }
local map_special_r6 = {
shift = 0, mask = 63,
[0] = { shift = 0, mask = -1, [0] = "nop", _ = "sllDTA" },
false, map_srl, "sraDTA",
"sllvDTS", false, map_srlv, "sravDTS",
"jrS", "jalrD1S", false, false,
"syscallY", "breakY", false, "sync",
"clzDS", "cloDS", "dclzDS", "dcloDS",
"dsllvDST", "dlsaDSTA", "dsrlvDST", "dsravDST",
map_mul_r6, map_mulu_r6, map_div_r6, map_divu_r6,
map_dmul_r6, map_dmulu_r6, map_ddiv_r6, map_ddivu_r6,
"addDST", "addu|moveDST0", "subDST", "subu|neguDS0T",
"andDST", "or|moveDST0", "xorDST", "nor|notDST0",
false, false, "sltDST", "sltuDST",
"daddDST", "dadduDST", "dsubDST", "dsubuDST",
"tgeSTZ", "tgeuSTZ", "tltSTZ", "tltuSTZ",
"teqSTZ", "seleqzDST", "tneSTZ", "selnezDST",
"dsllDTA", false, "dsrlDTA", "dsraDTA",
"dsll32DTA", false, "dsrl32DTA", "dsra32DTA",
}
local map_bshfl_r6 = {
shift = 9, mask = 3,
[1] = "alignDSTa",
_ = {
shift = 6, mask = 31,
[0] = "bitswapDT",
[2] = "wsbhDT",
[16] = "sebDT",
[24] = "sehDT",
}
}
local map_dbshfl_r6 = {
shift = 9, mask = 3,
[1] = "dalignDSTa",
_ = {
shift = 6, mask = 31,
[0] = "dbitswapDT",
[2] = "dsbhDT",
[5] = "dshdDT",
}
}
local map_special3_r6 = {
shift = 0, mask = 63,
[0] = "extTSAK", [1] = "dextmTSAP", [3] = "dextTSAK",
[4] = "insTSAL", [6] = "dinsuTSEQ", [7] = "dinsTSAL",
[32] = map_bshfl_r6, [36] = map_dbshfl_r6, [59] = "rdhwrTD",
}
local map_regimm_r6 = {
shift = 16, mask = 31,
[0] = "bltzSB", [1] = "bgezSB",
[6] = "dahiSI", [30] = "datiSI",
[23] = "sigrieI", [31] = "synciSO",
}
local map_pcrel_r6 = {
shift = 19, mask = 3,
[0] = "addiupcS2", "lwpcS2", "lwupcS2", {
shift = 18, mask = 1,
[0] = "ldpcS3", { shift = 16, mask = 3, [2] = "auipcSI", [3] = "aluipcSI" }
}
}
local map_cop1s_r6 = {
shift = 0, mask = 63,
[0] = "add.sFGH", "sub.sFGH", "mul.sFGH", "div.sFGH",
"sqrt.sFG", "abs.sFG", "mov.sFG", "neg.sFG",
"round.l.sFG", "trunc.l.sFG", "ceil.l.sFG", "floor.l.sFG",
"round.w.sFG", "trunc.w.sFG", "ceil.w.sFG", "floor.w.sFG",
"sel.sFGH", false, false, false,
"seleqz.sFGH", "recip.sFG", "rsqrt.sFG", "selnez.sFGH",
"maddf.sFGH", "msubf.sFGH", "rint.sFG", "class.sFG",
"min.sFGH", "mina.sFGH", "max.sFGH", "maxa.sFGH",
false, "cvt.d.sFG", false, false,
"cvt.w.sFG", "cvt.l.sFG",
}
local map_cop1d_r6 = {
shift = 0, mask = 63,
[0] = "add.dFGH", "sub.dFGH", "mul.dFGH", "div.dFGH",
"sqrt.dFG", "abs.dFG", "mov.dFG", "neg.dFG",
"round.l.dFG", "trunc.l.dFG", "ceil.l.dFG", "floor.l.dFG",
"round.w.dFG", "trunc.w.dFG", "ceil.w.dFG", "floor.w.dFG",
"sel.dFGH", false, false, false,
"seleqz.dFGH", "recip.dFG", "rsqrt.dFG", "selnez.dFGH",
"maddf.dFGH", "msubf.dFGH", "rint.dFG", "class.dFG",
"min.dFGH", "mina.dFGH", "max.dFGH", "maxa.dFGH",
"cvt.s.dFG", false, false, false,
"cvt.w.dFG", "cvt.l.dFG",
}
local map_cop1w_r6 = {
shift = 0, mask = 63,
[0] = "cmp.af.sFGH", "cmp.un.sFGH", "cmp.eq.sFGH", "cmp.ueq.sFGH",
"cmp.lt.sFGH", "cmp.ult.sFGH", "cmp.le.sFGH", "cmp.ule.sFGH",
"cmp.saf.sFGH", "cmp.sun.sFGH", "cmp.seq.sFGH", "cmp.sueq.sFGH",
"cmp.slt.sFGH", "cmp.sult.sFGH", "cmp.sle.sFGH", "cmp.sule.sFGH",
false, "cmp.or.sFGH", "cmp.une.sFGH", "cmp.ne.sFGH",
false, false, false, false,
false, "cmp.sor.sFGH", "cmp.sune.sFGH", "cmp.sne.sFGH",
false, false, false, false,
"cvt.s.wFG", "cvt.d.wFG",
}
local map_cop1l_r6 = {
shift = 0, mask = 63,
[0] = "cmp.af.dFGH", "cmp.un.dFGH", "cmp.eq.dFGH", "cmp.ueq.dFGH",
"cmp.lt.dFGH", "cmp.ult.dFGH", "cmp.le.dFGH", "cmp.ule.dFGH",
"cmp.saf.dFGH", "cmp.sun.dFGH", "cmp.seq.dFGH", "cmp.sueq.dFGH",
"cmp.slt.dFGH", "cmp.sult.dFGH", "cmp.sle.dFGH", "cmp.sule.dFGH",
false, "cmp.or.dFGH", "cmp.une.dFGH", "cmp.ne.dFGH",
false, false, false, false,
false, "cmp.sor.dFGH", "cmp.sune.dFGH", "cmp.sne.dFGH",
false, false, false, false,
"cvt.s.lFG", "cvt.d.lFG",
}
local map_cop1_r6 = {
shift = 21, mask = 31,
[0] = "mfc1TG", "dmfc1TG", "cfc1TG", "mfhc1TG",
"mtc1TG", "dmtc1TG", "ctc1TG", "mthc1TG",
false, "bc1eqzHB", false, false,
false, "bc1nezHB", false, false,
map_cop1s_r6, map_cop1d_r6, false, false,
map_cop1w_r6, map_cop1l_r6,
}
local function maprs_popTS(rs, rt)
if rt == 0 then return 0 elseif rs == 0 then return 1
elseif rs == rt then return 2 else return 3 end
end
local map_pop06_r6 = {
maprs = maprs_popTS, [0] = "blezSB", "blezalcTB", "bgezalcTB", "bgeucSTB"
}
local map_pop07_r6 = {
maprs = maprs_popTS, [0] = "bgtzSB", "bgtzalcTB", "bltzalcTB", "bltucSTB"
}
local map_pop26_r6 = {
maprs = maprs_popTS, "blezcTB", "bgezcTB", "bgecSTB"
}
local map_pop27_r6 = {
maprs = maprs_popTS, "bgtzcTB", "bltzcTB", "bltcSTB"
}
local function maprs_popS(rs, rt)
if rs == 0 then return 0 else return 1 end
end
local map_pop66_r6 = {
maprs = maprs_popS, [0] = "jicTI", "beqzcSb"
}
local map_pop76_r6 = {
maprs = maprs_popS, [0] = "jialcTI", "bnezcSb"
}
local function maprs_popST(rs, rt)
if rs >= rt then return 0 elseif rs == 0 then return 1 else return 2 end
end
local map_pop10_r6 = {
maprs = maprs_popST, [0] = "bovcSTB", "beqzalcTB", "beqcSTB"
}
local map_pop30_r6 = {
maprs = maprs_popST, [0] = "bnvcSTB", "bnezalcTB", "bnecSTB"
}
local map_pri_r6 = {
[0] = map_special_r6, map_regimm_r6, "jJ", "jalJ",
"beq|beqz|bST00B", "bne|bnezST0B", map_pop06_r6, map_pop07_r6,
map_pop10_r6, "addiu|liTS0I", "sltiTSI", "sltiuTSI",
"andiTSU", "ori|liTS0U", "xoriTSU", "aui|luiTS0U",
map_cop0, map_cop1_r6, false, false,
false, false, map_pop26_r6, map_pop27_r6,
map_pop30_r6, "daddiuTSI", false, false,
false, "dauiTSI", false, map_special3_r6,
"lbTSO", "lhTSO", false, "lwTSO",
"lbuTSO", "lhuTSO", false, false,
"sbTSO", "shTSO", false, "swTSO",
false, false, false, false,
false, "lwc1HSO", "bc#", false,
false, "ldc1HSO", map_pop66_r6, "ldTSO",
false, "swc1HSO", "balc#", map_pcrel_r6,
false, "sdc1HSO", map_pop76_r6, "sdTSO",
}
------------------------------------------------------------------------------
local map_gpr = {
[0] = "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
"r24", "r25", "r26", "r27", "r28", "sp", "r30", "ra",
}
------------------------------------------------------------------------------
-- Output a nicely formatted line with an opcode and operands.
local function putop(ctx, text, operands)
local pos = ctx.pos
local extra = ""
if ctx.rel then
local sym = ctx.symtab[ctx.rel]
if sym then extra = "\t->"..sym end
end
if ctx.hexdump > 0 then
ctx.out(format("%08x %s %-7s %s%s\n",
ctx.addr+pos, tohex(ctx.op), text, concat(operands, ", "), extra))
else
ctx.out(format("%08x %-7s %s%s\n",
ctx.addr+pos, text, concat(operands, ", "), extra))
end
ctx.pos = pos + 4
end
-- Fallback for unknown opcodes.
local function unknown(ctx)
return putop(ctx, ".long", { "0x"..tohex(ctx.op) })
end
local function get_be(ctx)
local pos = ctx.pos
local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4)
return bor(lshift(b0, 24), lshift(b1, 16), lshift(b2, 8), b3)
end
local function get_le(ctx)
local pos = ctx.pos
local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4)
return bor(lshift(b3, 24), lshift(b2, 16), lshift(b1, 8), b0)
end
-- Disassemble a single instruction.
local function disass_ins(ctx)
local op = ctx:get()
local operands = {}
local last = nil
ctx.op = op
ctx.rel = nil
local opat = ctx.map_pri[rshift(op, 26)]
while type(opat) ~= "string" do
if not opat then return unknown(ctx) end
if opat.maprs then
opat = opat[opat.maprs(band(rshift(op,21),31), band(rshift(op,16),31))]
else
opat = opat[band(rshift(op, opat.shift), opat.mask)] or opat._
end
end
local name, pat = match(opat, "^([a-z0-9_.]*)(.*)")
local altname, pat2 = match(pat, "|([a-z0-9_.|]*)(.*)")
if altname then pat = pat2 end
for p in gmatch(pat, ".") do
local x = nil
if p == "S" then
x = map_gpr[band(rshift(op, 21), 31)]
elseif p == "T" then
x = map_gpr[band(rshift(op, 16), 31)]
elseif p == "D" then
x = map_gpr[band(rshift(op, 11), 31)]
elseif p == "F" then
x = "f"..band(rshift(op, 6), 31)
elseif p == "G" then
x = "f"..band(rshift(op, 11), 31)
elseif p == "H" then
x = "f"..band(rshift(op, 16), 31)
elseif p == "R" then
x = "f"..band(rshift(op, 21), 31)
elseif p == "A" then
x = band(rshift(op, 6), 31)
elseif p == "a" then
x = band(rshift(op, 6), 7)
elseif p == "E" then
x = band(rshift(op, 6), 31) + 32
elseif p == "M" then
x = band(rshift(op, 11), 31)
elseif p == "N" then
x = band(rshift(op, 16), 31)
elseif p == "C" then
x = band(rshift(op, 18), 7)
if x == 0 then x = nil end
elseif p == "K" then
x = band(rshift(op, 11), 31) + 1
elseif p == "P" then
x = band(rshift(op, 11), 31) + 33
elseif p == "L" then
x = band(rshift(op, 11), 31) - last + 1
elseif p == "Q" then
x = band(rshift(op, 11), 31) - last + 33
elseif p == "I" then
x = arshift(lshift(op, 16), 16)
elseif p == "2" then
x = arshift(lshift(op, 13), 11)
elseif p == "3" then
x = arshift(lshift(op, 14), 11)
elseif p == "U" then
x = band(op, 0xffff)
elseif p == "O" then
local disp = arshift(lshift(op, 16), 16)
operands[#operands] = format("%d(%s)", disp, last)
elseif p == "X" then
local index = map_gpr[band(rshift(op, 16), 31)]
operands[#operands] = format("%s(%s)", index, last)
elseif p == "B" then
x = ctx.addr + ctx.pos + arshift(lshift(op, 16), 14) + 4
ctx.rel = x
x = format("0x%08x", x)
elseif p == "b" then
x = ctx.addr + ctx.pos + arshift(lshift(op, 11), 9) + 4
ctx.rel = x
x = format("0x%08x", x)
elseif p == "#" then
x = ctx.addr + ctx.pos + arshift(lshift(op, 6), 4) + 4
ctx.rel = x
x = format("0x%08x", x)
elseif p == "J" then
local a = ctx.addr + ctx.pos
x = a - band(a, 0x0fffffff) + band(op, 0x03ffffff)*4
ctx.rel = x
x = format("0x%08x", x)
elseif p == "V" then
x = band(rshift(op, 8), 7)
if x == 0 then x = nil end
elseif p == "W" then
x = band(op, 7)
if x == 0 then x = nil end
elseif p == "Y" then
x = band(rshift(op, 6), 0x000fffff)
if x == 0 then x = nil end
elseif p == "Z" then
x = band(rshift(op, 6), 1023)
if x == 0 then x = nil end
elseif p == "0" then
if last == "r0" or last == 0 then
local n = #operands
operands[n] = nil
last = operands[n-1]
if altname then
local a1, a2 = match(altname, "([^|]*)|(.*)")
if a1 then name, altname = a1, a2
else name = altname end
end
end
elseif p == "1" then
if last == "ra" then
operands[#operands] = nil
end
else
assert(false)
end
if x then operands[#operands+1] = x; last = x end
end
return putop(ctx, name, operands)
end
------------------------------------------------------------------------------
-- Disassemble a block of code.
local function disass_block(ctx, ofs, len)
if not ofs then ofs = 0 end
local stop = len and ofs+len or #ctx.code
stop = stop - stop % 4
ctx.pos = ofs - ofs % 4
ctx.rel = nil
while ctx.pos < stop do disass_ins(ctx) end
end
-- Extended API: create a disassembler context. Then call ctx:disass(ofs, len).
local function create(code, addr, out)
local ctx = {}
ctx.code = code
ctx.addr = addr or 0
ctx.out = out or io.write
ctx.symtab = {}
ctx.disass = disass_block
ctx.hexdump = 8
ctx.get = get_be
ctx.map_pri = map_pri
return ctx
end
local function create_el(code, addr, out)
local ctx = create(code, addr, out)
ctx.get = get_le
return ctx
end
local function create_r6(code, addr, out)
local ctx = create(code, addr, out)
ctx.map_pri = map_pri_r6
return ctx
end
local function create_r6_el(code, addr, out)
local ctx = create(code, addr, out)
ctx.get = get_le
ctx.map_pri = map_pri_r6
return ctx
end
-- Simple API: disassemble code (a string) at address and output via out.
local function disass(code, addr, out)
create(code, addr, out):disass()
end
local function disass_el(code, addr, out)
create_el(code, addr, out):disass()
end
local function disass_r6(code, addr, out)
create_r6(code, addr, out):disass()
end
local function disass_r6_el(code, addr, out)
create_r6_el(code, addr, out):disass()
end
-- Return register name for RID.
local function regname(r)
if r < 32 then return map_gpr[r] end
return "f"..(r-32)
end
-- Public module functions.
return {
create = create,
create_el = create_el,
create_r6 = create_r6,
create_r6_el = create_r6_el,
disass = disass,
disass_el = disass_el,
disass_r6 = disass_r6,
disass_r6_el = disass_r6_el,
regname = regname
}

View file

@ -0,0 +1,17 @@
----------------------------------------------------------------------------
-- LuaJIT MIPS64 disassembler wrapper module.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- This module just exports the big-endian functions from the
-- MIPS disassembler module. All the interesting stuff is there.
------------------------------------------------------------------------------
local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips")
return {
create = dis_mips.create,
disass = dis_mips.disass,
regname = dis_mips.regname
}

View file

@ -0,0 +1,17 @@
----------------------------------------------------------------------------
-- LuaJIT MIPS64EL disassembler wrapper module.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- This module just exports the little-endian functions from the
-- MIPS disassembler module. All the interesting stuff is there.
------------------------------------------------------------------------------
local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips")
return {
create = dis_mips.create_el,
disass = dis_mips.disass_el,
regname = dis_mips.regname
}

View file

@ -0,0 +1,17 @@
----------------------------------------------------------------------------
-- LuaJIT MIPS64R6 disassembler wrapper module.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- This module just exports the r6 big-endian functions from the
-- MIPS disassembler module. All the interesting stuff is there.
------------------------------------------------------------------------------
local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips")
return {
create = dis_mips.create_r6,
disass = dis_mips.disass_r6,
regname = dis_mips.regname
}

View file

@ -0,0 +1,17 @@
----------------------------------------------------------------------------
-- LuaJIT MIPS64R6EL disassembler wrapper module.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- This module just exports the r6 little-endian functions from the
-- MIPS disassembler module. All the interesting stuff is there.
------------------------------------------------------------------------------
local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips")
return {
create = dis_mips.create_r6_el,
disass = dis_mips.disass_r6_el,
regname = dis_mips.regname
}

View file

@ -0,0 +1,17 @@
----------------------------------------------------------------------------
-- LuaJIT MIPSEL disassembler wrapper module.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- This module just exports the little-endian functions from the
-- MIPS disassembler module. All the interesting stuff is there.
------------------------------------------------------------------------------
local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips")
return {
create = dis_mips.create_el,
disass = dis_mips.disass_el,
regname = dis_mips.regname
}

View file

@ -0,0 +1,591 @@
----------------------------------------------------------------------------
-- LuaJIT PPC disassembler module.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT/X license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- This is a helper module used by the LuaJIT machine code dumper module.
--
-- It disassembles all common, non-privileged 32/64 bit PowerPC instructions
-- plus the e500 SPE instructions and some Cell/Xenon extensions.
--
-- NYI: VMX, VMX128
------------------------------------------------------------------------------
local type = type
local byte, format = string.byte, string.format
local match, gmatch, gsub = string.match, string.gmatch, string.gsub
local concat = table.concat
local bit = require("bit")
local band, bor, tohex = bit.band, bit.bor, bit.tohex
local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift
------------------------------------------------------------------------------
-- Primary and extended opcode maps
------------------------------------------------------------------------------
local map_crops = {
shift = 1, mask = 1023,
[0] = "mcrfXX",
[33] = "crnor|crnotCCC=", [129] = "crandcCCC",
[193] = "crxor|crclrCCC%", [225] = "crnandCCC",
[257] = "crandCCC", [289] = "creqv|crsetCCC%",
[417] = "crorcCCC", [449] = "cror|crmoveCCC=",
[16] = "b_lrKB", [528] = "b_ctrKB",
[150] = "isync",
}
local map_rlwinm = setmetatable({
shift = 0, mask = -1,
},
{ __index = function(t, x)
local rot = band(rshift(x, 11), 31)
local mb = band(rshift(x, 6), 31)
local me = band(rshift(x, 1), 31)
if mb == 0 and me == 31-rot then
return "slwiRR~A."
elseif me == 31 and mb == 32-rot then
return "srwiRR~-A."
else
return "rlwinmRR~AAA."
end
end
})
local map_rld = {
shift = 2, mask = 7,
[0] = "rldiclRR~HM.", "rldicrRR~HM.", "rldicRR~HM.", "rldimiRR~HM.",
{
shift = 1, mask = 1,
[0] = "rldclRR~RM.", "rldcrRR~RM.",
},
}
local map_ext = setmetatable({
shift = 1, mask = 1023,
[0] = "cmp_YLRR", [32] = "cmpl_YLRR",
[4] = "twARR", [68] = "tdARR",
[8] = "subfcRRR.", [40] = "subfRRR.",
[104] = "negRR.", [136] = "subfeRRR.",
[200] = "subfzeRR.", [232] = "subfmeRR.",
[520] = "subfcoRRR.", [552] = "subfoRRR.",
[616] = "negoRR.", [648] = "subfeoRRR.",
[712] = "subfzeoRR.", [744] = "subfmeoRR.",
[9] = "mulhduRRR.", [73] = "mulhdRRR.", [233] = "mulldRRR.",
[457] = "divduRRR.", [489] = "divdRRR.",
[745] = "mulldoRRR.",
[969] = "divduoRRR.", [1001] = "divdoRRR.",
[10] = "addcRRR.", [138] = "addeRRR.",
[202] = "addzeRR.", [234] = "addmeRR.", [266] = "addRRR.",
[522] = "addcoRRR.", [650] = "addeoRRR.",
[714] = "addzeoRR.", [746] = "addmeoRR.", [778] = "addoRRR.",
[11] = "mulhwuRRR.", [75] = "mulhwRRR.", [235] = "mullwRRR.",
[459] = "divwuRRR.", [491] = "divwRRR.",
[747] = "mullwoRRR.",
[971] = "divwouRRR.", [1003] = "divwoRRR.",
[15] = "iselltRRR", [47] = "iselgtRRR", [79] = "iseleqRRR",
[144] = { shift = 20, mask = 1, [0] = "mtcrfRZ~", "mtocrfRZ~", },
[19] = { shift = 20, mask = 1, [0] = "mfcrR", "mfocrfRZ", },
[371] = { shift = 11, mask = 1023, [392] = "mftbR", [424] = "mftbuR", },
[339] = {
shift = 11, mask = 1023,
[32] = "mferR", [256] = "mflrR", [288] = "mfctrR", [16] = "mfspefscrR",
},
[467] = {
shift = 11, mask = 1023,
[32] = "mtxerR", [256] = "mtlrR", [288] = "mtctrR", [16] = "mtspefscrR",
},
[20] = "lwarxRR0R", [84] = "ldarxRR0R",
[21] = "ldxRR0R", [53] = "lduxRRR",
[149] = "stdxRR0R", [181] = "stduxRRR",
[341] = "lwaxRR0R", [373] = "lwauxRRR",
[23] = "lwzxRR0R", [55] = "lwzuxRRR",
[87] = "lbzxRR0R", [119] = "lbzuxRRR",
[151] = "stwxRR0R", [183] = "stwuxRRR",
[215] = "stbxRR0R", [247] = "stbuxRRR",
[279] = "lhzxRR0R", [311] = "lhzuxRRR",
[343] = "lhaxRR0R", [375] = "lhauxRRR",
[407] = "sthxRR0R", [439] = "sthuxRRR",
[54] = "dcbst-R0R", [86] = "dcbf-R0R",
[150] = "stwcxRR0R.", [214] = "stdcxRR0R.",
[246] = "dcbtst-R0R", [278] = "dcbt-R0R",
[310] = "eciwxRR0R", [438] = "ecowxRR0R",
[470] = "dcbi-RR",
[598] = {
shift = 21, mask = 3,
[0] = "sync", "lwsync", "ptesync",
},
[758] = "dcba-RR",
[854] = "eieio", [982] = "icbi-R0R", [1014] = "dcbz-R0R",
[26] = "cntlzwRR~", [58] = "cntlzdRR~",
[122] = "popcntbRR~",
[154] = "prtywRR~", [186] = "prtydRR~",
[28] = "andRR~R.", [60] = "andcRR~R.", [124] = "nor|notRR~R=.",
[284] = "eqvRR~R.", [316] = "xorRR~R.",
[412] = "orcRR~R.", [444] = "or|mrRR~R=.", [476] = "nandRR~R.",
[508] = "cmpbRR~R",
[512] = "mcrxrX",
[532] = "ldbrxRR0R", [660] = "stdbrxRR0R",
[533] = "lswxRR0R", [597] = "lswiRR0A",
[661] = "stswxRR0R", [725] = "stswiRR0A",
[534] = "lwbrxRR0R", [662] = "stwbrxRR0R",
[790] = "lhbrxRR0R", [918] = "sthbrxRR0R",
[535] = "lfsxFR0R", [567] = "lfsuxFRR",
[599] = "lfdxFR0R", [631] = "lfduxFRR",
[663] = "stfsxFR0R", [695] = "stfsuxFRR",
[727] = "stfdxFR0R", [759] = "stfduxFR0R",
[855] = "lfiwaxFR0R",
[983] = "stfiwxFR0R",
[24] = "slwRR~R.",
[27] = "sldRR~R.", [536] = "srwRR~R.",
[792] = "srawRR~R.", [824] = "srawiRR~A.",
[794] = "sradRR~R.", [826] = "sradiRR~H.", [827] = "sradiRR~H.",
[922] = "extshRR~.", [954] = "extsbRR~.", [986] = "extswRR~.",
[539] = "srdRR~R.",
},
{ __index = function(t, x)
if band(x, 31) == 15 then return "iselRRRC" end
end
})
local map_ld = {
shift = 0, mask = 3,
[0] = "ldRRE", "lduRRE", "lwaRRE",
}
local map_std = {
shift = 0, mask = 3,
[0] = "stdRRE", "stduRRE",
}
local map_fps = {
shift = 5, mask = 1,
{
shift = 1, mask = 15,
[0] = false, false, "fdivsFFF.", false,
"fsubsFFF.", "faddsFFF.", "fsqrtsF-F.", false,
"fresF-F.", "fmulsFF-F.", "frsqrtesF-F.", false,
"fmsubsFFFF~.", "fmaddsFFFF~.", "fnmsubsFFFF~.", "fnmaddsFFFF~.",
}
}
local map_fpd = {
shift = 5, mask = 1,
[0] = {
shift = 1, mask = 1023,
[0] = "fcmpuXFF", [32] = "fcmpoXFF", [64] = "mcrfsXX",
[38] = "mtfsb1A.", [70] = "mtfsb0A.", [134] = "mtfsfiA>>-A>",
[8] = "fcpsgnFFF.", [40] = "fnegF-F.", [72] = "fmrF-F.",
[136] = "fnabsF-F.", [264] = "fabsF-F.",
[12] = "frspF-F.",
[14] = "fctiwF-F.", [15] = "fctiwzF-F.",
[583] = "mffsF.", [711] = "mtfsfZF.",
[392] = "frinF-F.", [424] = "frizF-F.",
[456] = "fripF-F.", [488] = "frimF-F.",
[814] = "fctidF-F.", [815] = "fctidzF-F.", [846] = "fcfidF-F.",
},
{
shift = 1, mask = 15,
[0] = false, false, "fdivFFF.", false,
"fsubFFF.", "faddFFF.", "fsqrtF-F.", "fselFFFF~.",
"freF-F.", "fmulFF-F.", "frsqrteF-F.", false,
"fmsubFFFF~.", "fmaddFFFF~.", "fnmsubFFFF~.", "fnmaddFFFF~.",
}
}
local map_spe = {
shift = 0, mask = 2047,
[512] = "evaddwRRR", [514] = "evaddiwRAR~",
[516] = "evsubwRRR~", [518] = "evsubiwRAR~",
[520] = "evabsRR", [521] = "evnegRR",
[522] = "evextsbRR", [523] = "evextshRR", [524] = "evrndwRR",
[525] = "evcntlzwRR", [526] = "evcntlswRR",
[527] = "brincRRR",
[529] = "evandRRR", [530] = "evandcRRR", [534] = "evxorRRR",
[535] = "evor|evmrRRR=", [536] = "evnor|evnotRRR=",
[537] = "eveqvRRR", [539] = "evorcRRR", [542] = "evnandRRR",
[544] = "evsrwuRRR", [545] = "evsrwsRRR",
[546] = "evsrwiuRRA", [547] = "evsrwisRRA",
[548] = "evslwRRR", [550] = "evslwiRRA",
[552] = "evrlwRRR", [553] = "evsplatiRS",
[554] = "evrlwiRRA", [555] = "evsplatfiRS",
[556] = "evmergehiRRR", [557] = "evmergeloRRR",
[558] = "evmergehiloRRR", [559] = "evmergelohiRRR",
[560] = "evcmpgtuYRR", [561] = "evcmpgtsYRR",
[562] = "evcmpltuYRR", [563] = "evcmpltsYRR",
[564] = "evcmpeqYRR",
[632] = "evselRRR", [633] = "evselRRRW",
[634] = "evselRRRW", [635] = "evselRRRW",
[636] = "evselRRRW", [637] = "evselRRRW",
[638] = "evselRRRW", [639] = "evselRRRW",
[640] = "evfsaddRRR", [641] = "evfssubRRR",
[644] = "evfsabsRR", [645] = "evfsnabsRR", [646] = "evfsnegRR",
[648] = "evfsmulRRR", [649] = "evfsdivRRR",
[652] = "evfscmpgtYRR", [653] = "evfscmpltYRR", [654] = "evfscmpeqYRR",
[656] = "evfscfuiR-R", [657] = "evfscfsiR-R",
[658] = "evfscfufR-R", [659] = "evfscfsfR-R",
[660] = "evfsctuiR-R", [661] = "evfsctsiR-R",
[662] = "evfsctufR-R", [663] = "evfsctsfR-R",
[664] = "evfsctuizR-R", [666] = "evfsctsizR-R",
[668] = "evfststgtYRR", [669] = "evfststltYRR", [670] = "evfststeqYRR",
[704] = "efsaddRRR", [705] = "efssubRRR",
[708] = "efsabsRR", [709] = "efsnabsRR", [710] = "efsnegRR",
[712] = "efsmulRRR", [713] = "efsdivRRR",
[716] = "efscmpgtYRR", [717] = "efscmpltYRR", [718] = "efscmpeqYRR",
[719] = "efscfdR-R",
[720] = "efscfuiR-R", [721] = "efscfsiR-R",
[722] = "efscfufR-R", [723] = "efscfsfR-R",
[724] = "efsctuiR-R", [725] = "efsctsiR-R",
[726] = "efsctufR-R", [727] = "efsctsfR-R",
[728] = "efsctuizR-R", [730] = "efsctsizR-R",
[732] = "efststgtYRR", [733] = "efststltYRR", [734] = "efststeqYRR",
[736] = "efdaddRRR", [737] = "efdsubRRR",
[738] = "efdcfuidR-R", [739] = "efdcfsidR-R",
[740] = "efdabsRR", [741] = "efdnabsRR", [742] = "efdnegRR",
[744] = "efdmulRRR", [745] = "efddivRRR",
[746] = "efdctuidzR-R", [747] = "efdctsidzR-R",
[748] = "efdcmpgtYRR", [749] = "efdcmpltYRR", [750] = "efdcmpeqYRR",
[751] = "efdcfsR-R",
[752] = "efdcfuiR-R", [753] = "efdcfsiR-R",
[754] = "efdcfufR-R", [755] = "efdcfsfR-R",
[756] = "efdctuiR-R", [757] = "efdctsiR-R",
[758] = "efdctufR-R", [759] = "efdctsfR-R",
[760] = "efdctuizR-R", [762] = "efdctsizR-R",
[764] = "efdtstgtYRR", [765] = "efdtstltYRR", [766] = "efdtsteqYRR",
[768] = "evlddxRR0R", [769] = "evlddRR8",
[770] = "evldwxRR0R", [771] = "evldwRR8",
[772] = "evldhxRR0R", [773] = "evldhRR8",
[776] = "evlhhesplatxRR0R", [777] = "evlhhesplatRR2",
[780] = "evlhhousplatxRR0R", [781] = "evlhhousplatRR2",
[782] = "evlhhossplatxRR0R", [783] = "evlhhossplatRR2",
[784] = "evlwhexRR0R", [785] = "evlwheRR4",
[788] = "evlwhouxRR0R", [789] = "evlwhouRR4",
[790] = "evlwhosxRR0R", [791] = "evlwhosRR4",
[792] = "evlwwsplatxRR0R", [793] = "evlwwsplatRR4",
[796] = "evlwhsplatxRR0R", [797] = "evlwhsplatRR4",
[800] = "evstddxRR0R", [801] = "evstddRR8",
[802] = "evstdwxRR0R", [803] = "evstdwRR8",
[804] = "evstdhxRR0R", [805] = "evstdhRR8",
[816] = "evstwhexRR0R", [817] = "evstwheRR4",
[820] = "evstwhoxRR0R", [821] = "evstwhoRR4",
[824] = "evstwwexRR0R", [825] = "evstwweRR4",
[828] = "evstwwoxRR0R", [829] = "evstwwoRR4",
[1027] = "evmhessfRRR", [1031] = "evmhossfRRR", [1032] = "evmheumiRRR",
[1033] = "evmhesmiRRR", [1035] = "evmhesmfRRR", [1036] = "evmhoumiRRR",
[1037] = "evmhosmiRRR", [1039] = "evmhosmfRRR", [1059] = "evmhessfaRRR",
[1063] = "evmhossfaRRR", [1064] = "evmheumiaRRR", [1065] = "evmhesmiaRRR",
[1067] = "evmhesmfaRRR", [1068] = "evmhoumiaRRR", [1069] = "evmhosmiaRRR",
[1071] = "evmhosmfaRRR", [1095] = "evmwhssfRRR", [1096] = "evmwlumiRRR",
[1100] = "evmwhumiRRR", [1101] = "evmwhsmiRRR", [1103] = "evmwhsmfRRR",
[1107] = "evmwssfRRR", [1112] = "evmwumiRRR", [1113] = "evmwsmiRRR",
[1115] = "evmwsmfRRR", [1127] = "evmwhssfaRRR", [1128] = "evmwlumiaRRR",
[1132] = "evmwhumiaRRR", [1133] = "evmwhsmiaRRR", [1135] = "evmwhsmfaRRR",
[1139] = "evmwssfaRRR", [1144] = "evmwumiaRRR", [1145] = "evmwsmiaRRR",
[1147] = "evmwsmfaRRR",
[1216] = "evaddusiaawRR", [1217] = "evaddssiaawRR",
[1218] = "evsubfusiaawRR", [1219] = "evsubfssiaawRR",
[1220] = "evmraRR",
[1222] = "evdivwsRRR", [1223] = "evdivwuRRR",
[1224] = "evaddumiaawRR", [1225] = "evaddsmiaawRR",
[1226] = "evsubfumiaawRR", [1227] = "evsubfsmiaawRR",
[1280] = "evmheusiaawRRR", [1281] = "evmhessiaawRRR",
[1283] = "evmhessfaawRRR", [1284] = "evmhousiaawRRR",
[1285] = "evmhossiaawRRR", [1287] = "evmhossfaawRRR",
[1288] = "evmheumiaawRRR", [1289] = "evmhesmiaawRRR",
[1291] = "evmhesmfaawRRR", [1292] = "evmhoumiaawRRR",
[1293] = "evmhosmiaawRRR", [1295] = "evmhosmfaawRRR",
[1320] = "evmhegumiaaRRR", [1321] = "evmhegsmiaaRRR",
[1323] = "evmhegsmfaaRRR", [1324] = "evmhogumiaaRRR",
[1325] = "evmhogsmiaaRRR", [1327] = "evmhogsmfaaRRR",
[1344] = "evmwlusiaawRRR", [1345] = "evmwlssiaawRRR",
[1352] = "evmwlumiaawRRR", [1353] = "evmwlsmiaawRRR",
[1363] = "evmwssfaaRRR", [1368] = "evmwumiaaRRR",
[1369] = "evmwsmiaaRRR", [1371] = "evmwsmfaaRRR",
[1408] = "evmheusianwRRR", [1409] = "evmhessianwRRR",
[1411] = "evmhessfanwRRR", [1412] = "evmhousianwRRR",
[1413] = "evmhossianwRRR", [1415] = "evmhossfanwRRR",
[1416] = "evmheumianwRRR", [1417] = "evmhesmianwRRR",
[1419] = "evmhesmfanwRRR", [1420] = "evmhoumianwRRR",
[1421] = "evmhosmianwRRR", [1423] = "evmhosmfanwRRR",
[1448] = "evmhegumianRRR", [1449] = "evmhegsmianRRR",
[1451] = "evmhegsmfanRRR", [1452] = "evmhogumianRRR",
[1453] = "evmhogsmianRRR", [1455] = "evmhogsmfanRRR",
[1472] = "evmwlusianwRRR", [1473] = "evmwlssianwRRR",
[1480] = "evmwlumianwRRR", [1481] = "evmwlsmianwRRR",
[1491] = "evmwssfanRRR", [1496] = "evmwumianRRR",
[1497] = "evmwsmianRRR", [1499] = "evmwsmfanRRR",
}
local map_pri = {
[0] = false, false, "tdiARI", "twiARI",
map_spe, false, false, "mulliRRI",
"subficRRI", false, "cmpl_iYLRU", "cmp_iYLRI",
"addicRRI", "addic.RRI", "addi|liRR0I", "addis|lisRR0I",
"b_KBJ", "sc", "bKJ", map_crops,
"rlwimiRR~AAA.", map_rlwinm, false, "rlwnmRR~RAA.",
"oriNRR~U", "orisRR~U", "xoriRR~U", "xorisRR~U",
"andi.RR~U", "andis.RR~U", map_rld, map_ext,
"lwzRRD", "lwzuRRD", "lbzRRD", "lbzuRRD",
"stwRRD", "stwuRRD", "stbRRD", "stbuRRD",
"lhzRRD", "lhzuRRD", "lhaRRD", "lhauRRD",
"sthRRD", "sthuRRD", "lmwRRD", "stmwRRD",
"lfsFRD", "lfsuFRD", "lfdFRD", "lfduFRD",
"stfsFRD", "stfsuFRD", "stfdFRD", "stfduFRD",
false, false, map_ld, map_fps,
false, false, map_std, map_fpd,
}
------------------------------------------------------------------------------
local map_gpr = {
[0] = "r0", "sp", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
}
local map_cond = { [0] = "lt", "gt", "eq", "so", "ge", "le", "ne", "ns", }
-- Format a condition bit.
local function condfmt(cond)
if cond <= 3 then
return map_cond[band(cond, 3)]
else
return format("4*cr%d+%s", rshift(cond, 2), map_cond[band(cond, 3)])
end
end
------------------------------------------------------------------------------
-- Output a nicely formatted line with an opcode and operands.
local function putop(ctx, text, operands)
local pos = ctx.pos
local extra = ""
if ctx.rel then
local sym = ctx.symtab[ctx.rel]
if sym then extra = "\t->"..sym end
end
if ctx.hexdump > 0 then
ctx.out(format("%08x %s %-7s %s%s\n",
ctx.addr+pos, tohex(ctx.op), text, concat(operands, ", "), extra))
else
ctx.out(format("%08x %-7s %s%s\n",
ctx.addr+pos, text, concat(operands, ", "), extra))
end
ctx.pos = pos + 4
end
-- Fallback for unknown opcodes.
local function unknown(ctx)
return putop(ctx, ".long", { "0x"..tohex(ctx.op) })
end
-- Disassemble a single instruction.
local function disass_ins(ctx)
local pos = ctx.pos
local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4)
local op = bor(lshift(b0, 24), lshift(b1, 16), lshift(b2, 8), b3)
local operands = {}
local last = nil
local rs = 21
ctx.op = op
ctx.rel = nil
local opat = map_pri[rshift(b0, 2)]
while type(opat) ~= "string" do
if not opat then return unknown(ctx) end
opat = opat[band(rshift(op, opat.shift), opat.mask)]
end
local name, pat = match(opat, "^([a-z0-9_.]*)(.*)")
local altname, pat2 = match(pat, "|([a-z0-9_.]*)(.*)")
if altname then pat = pat2 end
for p in gmatch(pat, ".") do
local x = nil
if p == "R" then
x = map_gpr[band(rshift(op, rs), 31)]
rs = rs - 5
elseif p == "F" then
x = "f"..band(rshift(op, rs), 31)
rs = rs - 5
elseif p == "A" then
x = band(rshift(op, rs), 31)
rs = rs - 5
elseif p == "S" then
x = arshift(lshift(op, 27-rs), 27)
rs = rs - 5
elseif p == "I" then
x = arshift(lshift(op, 16), 16)
elseif p == "U" then
x = band(op, 0xffff)
elseif p == "D" or p == "E" then
local disp = arshift(lshift(op, 16), 16)
if p == "E" then disp = band(disp, -4) end
if last == "r0" then last = "0" end
operands[#operands] = format("%d(%s)", disp, last)
elseif p >= "2" and p <= "8" then
local disp = band(rshift(op, rs), 31) * p
if last == "r0" then last = "0" end
operands[#operands] = format("%d(%s)", disp, last)
elseif p == "H" then
x = band(rshift(op, rs), 31) + lshift(band(op, 2), 4)
rs = rs - 5
elseif p == "M" then
x = band(rshift(op, rs), 31) + band(op, 0x20)
elseif p == "C" then
x = condfmt(band(rshift(op, rs), 31))
rs = rs - 5
elseif p == "B" then
local bo = rshift(op, 21)
local cond = band(rshift(op, 16), 31)
local cn = ""
rs = rs - 10
if band(bo, 4) == 0 then
cn = band(bo, 2) == 0 and "dnz" or "dz"
if band(bo, 0x10) == 0 then
cn = cn..(band(bo, 8) == 0 and "f" or "t")
end
if band(bo, 0x10) == 0 then x = condfmt(cond) end
name = name..(band(bo, 1) == band(rshift(op, 15), 1) and "-" or "+")
elseif band(bo, 0x10) == 0 then
cn = map_cond[band(cond, 3) + (band(bo, 8) == 0 and 4 or 0)]
if cond > 3 then x = "cr"..rshift(cond, 2) end
name = name..(band(bo, 1) == band(rshift(op, 15), 1) and "-" or "+")
end
name = gsub(name, "_", cn)
elseif p == "J" then
x = arshift(lshift(op, 27-rs), 29-rs)*4
if band(op, 2) == 0 then x = ctx.addr + pos + x end
ctx.rel = x
x = "0x"..tohex(x)
elseif p == "K" then
if band(op, 1) ~= 0 then name = name.."l" end
if band(op, 2) ~= 0 then name = name.."a" end
elseif p == "X" or p == "Y" then
x = band(rshift(op, rs+2), 7)
if x == 0 and p == "Y" then x = nil else x = "cr"..x end
rs = rs - 5
elseif p == "W" then
x = "cr"..band(op, 7)
elseif p == "Z" then
x = band(rshift(op, rs-4), 255)
rs = rs - 10
elseif p == ">" then
operands[#operands] = rshift(operands[#operands], 1)
elseif p == "0" then
if last == "r0" then
operands[#operands] = nil
if altname then name = altname end
end
elseif p == "L" then
name = gsub(name, "_", band(op, 0x00200000) ~= 0 and "d" or "w")
elseif p == "." then
if band(op, 1) == 1 then name = name.."." end
elseif p == "N" then
if op == 0x60000000 then name = "nop"; break end
elseif p == "~" then
local n = #operands
operands[n-1], operands[n] = operands[n], operands[n-1]
elseif p == "=" then
local n = #operands
if last == operands[n-1] then
operands[n] = nil
name = altname
end
elseif p == "%" then
local n = #operands
if last == operands[n-1] and last == operands[n-2] then
operands[n] = nil
operands[n-1] = nil
name = altname
end
elseif p == "-" then
rs = rs - 5
else
assert(false)
end
if x then operands[#operands+1] = x; last = x end
end
return putop(ctx, name, operands)
end
------------------------------------------------------------------------------
-- Disassemble a block of code.
local function disass_block(ctx, ofs, len)
if not ofs then ofs = 0 end
local stop = len and ofs+len or #ctx.code
stop = stop - stop % 4
ctx.pos = ofs - ofs % 4
ctx.rel = nil
while ctx.pos < stop do disass_ins(ctx) end
end
-- Extended API: create a disassembler context. Then call ctx:disass(ofs, len).
local function create(code, addr, out)
local ctx = {}
ctx.code = code
ctx.addr = addr or 0
ctx.out = out or io.write
ctx.symtab = {}
ctx.disass = disass_block
ctx.hexdump = 8
return ctx
end
-- Simple API: disassemble code (a string) at address and output via out.
local function disass(code, addr, out)
create(code, addr, out):disass()
end
-- Return register name for RID.
local function regname(r)
if r < 32 then return map_gpr[r] end
return "f"..(r-32)
end
-- Public module functions.
return {
create = create,
disass = disass,
regname = regname
}

View file

@ -0,0 +1,17 @@
----------------------------------------------------------------------------
-- LuaJIT x64 disassembler wrapper module.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- This module just exports the 64 bit functions from the combined
-- x86/x64 disassembler module. All the interesting stuff is there.
------------------------------------------------------------------------------
local dis_x86 = require((string.match(..., ".*%.") or "").."dis_x86")
return {
create = dis_x86.create64,
disass = dis_x86.disass64,
regname = dis_x86.regname64
}

View file

@ -0,0 +1,953 @@
----------------------------------------------------------------------------
-- LuaJIT x86/x64 disassembler module.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- This is a helper module used by the LuaJIT machine code dumper module.
--
-- Sending small code snippets to an external disassembler and mixing the
-- output with our own stuff was too fragile. So I had to bite the bullet
-- and write yet another x86 disassembler. Oh well ...
--
-- The output format is very similar to what ndisasm generates. But it has
-- been developed independently by looking at the opcode tables from the
-- Intel and AMD manuals. The supported instruction set is quite extensive
-- and reflects what a current generation Intel or AMD CPU implements in
-- 32 bit and 64 bit mode. Yes, this includes MMX, SSE, SSE2, SSE3, SSSE3,
-- SSE4.1, SSE4.2, SSE4a, AVX, AVX2 and even privileged and hypervisor
-- (VMX/SVM) instructions.
--
-- Notes:
-- * The (useless) a16 prefix, 3DNow and pre-586 opcodes are unsupported.
-- * No attempt at optimization has been made -- it's fast enough for my needs.
------------------------------------------------------------------------------
local type = type
local sub, byte, format = string.sub, string.byte, string.format
local match, gmatch, gsub = string.match, string.gmatch, string.gsub
local lower, rep = string.lower, string.rep
local bit = require("bit")
local tohex = bit.tohex
-- Map for 1st opcode byte in 32 bit mode. Ugly? Well ... read on.
local map_opc1_32 = {
--0x
[0]="addBmr","addVmr","addBrm","addVrm","addBai","addVai","push es","pop es",
"orBmr","orVmr","orBrm","orVrm","orBai","orVai","push cs","opc2*",
--1x
"adcBmr","adcVmr","adcBrm","adcVrm","adcBai","adcVai","push ss","pop ss",
"sbbBmr","sbbVmr","sbbBrm","sbbVrm","sbbBai","sbbVai","push ds","pop ds",
--2x
"andBmr","andVmr","andBrm","andVrm","andBai","andVai","es:seg","daa",
"subBmr","subVmr","subBrm","subVrm","subBai","subVai","cs:seg","das",
--3x
"xorBmr","xorVmr","xorBrm","xorVrm","xorBai","xorVai","ss:seg","aaa",
"cmpBmr","cmpVmr","cmpBrm","cmpVrm","cmpBai","cmpVai","ds:seg","aas",
--4x
"incVR","incVR","incVR","incVR","incVR","incVR","incVR","incVR",
"decVR","decVR","decVR","decVR","decVR","decVR","decVR","decVR",
--5x
"pushUR","pushUR","pushUR","pushUR","pushUR","pushUR","pushUR","pushUR",
"popUR","popUR","popUR","popUR","popUR","popUR","popUR","popUR",
--6x
"sz*pushaw,pusha","sz*popaw,popa","boundVrm","arplWmr",
"fs:seg","gs:seg","o16:","a16",
"pushUi","imulVrmi","pushBs","imulVrms",
"insb","insVS","outsb","outsVS",
--7x
"joBj","jnoBj","jbBj","jnbBj","jzBj","jnzBj","jbeBj","jaBj",
"jsBj","jnsBj","jpeBj","jpoBj","jlBj","jgeBj","jleBj","jgBj",
--8x
"arith!Bmi","arith!Vmi","arith!Bmi","arith!Vms",
"testBmr","testVmr","xchgBrm","xchgVrm",
"movBmr","movVmr","movBrm","movVrm",
"movVmg","leaVrm","movWgm","popUm",
--9x
"nop*xchgVaR|pause|xchgWaR|repne nop","xchgVaR","xchgVaR","xchgVaR",
"xchgVaR","xchgVaR","xchgVaR","xchgVaR",
"sz*cbw,cwde,cdqe","sz*cwd,cdq,cqo","call farViw","wait",
"sz*pushfw,pushf","sz*popfw,popf","sahf","lahf",
--Ax
"movBao","movVao","movBoa","movVoa",
"movsb","movsVS","cmpsb","cmpsVS",
"testBai","testVai","stosb","stosVS",
"lodsb","lodsVS","scasb","scasVS",
--Bx
"movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi",
"movVRI","movVRI","movVRI","movVRI","movVRI","movVRI","movVRI","movVRI",
--Cx
"shift!Bmu","shift!Vmu","retBw","ret","vex*3$lesVrm","vex*2$ldsVrm","movBmi","movVmi",
"enterBwu","leave","retfBw","retf","int3","intBu","into","iretVS",
--Dx
"shift!Bm1","shift!Vm1","shift!Bmc","shift!Vmc","aamBu","aadBu","salc","xlatb",
"fp*0","fp*1","fp*2","fp*3","fp*4","fp*5","fp*6","fp*7",
--Ex
"loopneBj","loopeBj","loopBj","sz*jcxzBj,jecxzBj,jrcxzBj",
"inBau","inVau","outBua","outVua",
"callVj","jmpVj","jmp farViw","jmpBj","inBad","inVad","outBda","outVda",
--Fx
"lock:","int1","repne:rep","rep:","hlt","cmc","testb!Bm","testv!Vm",
"clc","stc","cli","sti","cld","std","incb!Bm","incd!Vm",
}
assert(#map_opc1_32 == 255)
-- Map for 1st opcode byte in 64 bit mode (overrides only).
local map_opc1_64 = setmetatable({
[0x06]=false, [0x07]=false, [0x0e]=false,
[0x16]=false, [0x17]=false, [0x1e]=false, [0x1f]=false,
[0x27]=false, [0x2f]=false, [0x37]=false, [0x3f]=false,
[0x60]=false, [0x61]=false, [0x62]=false, [0x63]="movsxdVrDmt", [0x67]="a32:",
[0x40]="rex*", [0x41]="rex*b", [0x42]="rex*x", [0x43]="rex*xb",
[0x44]="rex*r", [0x45]="rex*rb", [0x46]="rex*rx", [0x47]="rex*rxb",
[0x48]="rex*w", [0x49]="rex*wb", [0x4a]="rex*wx", [0x4b]="rex*wxb",
[0x4c]="rex*wr", [0x4d]="rex*wrb", [0x4e]="rex*wrx", [0x4f]="rex*wrxb",
[0x82]=false, [0x9a]=false, [0xc4]="vex*3", [0xc5]="vex*2", [0xce]=false,
[0xd4]=false, [0xd5]=false, [0xd6]=false, [0xea]=false,
}, { __index = map_opc1_32 })
-- Map for 2nd opcode byte (0F xx). True CISC hell. Hey, I told you.
-- Prefix dependent MMX/SSE opcodes: (none)|rep|o16|repne, -|F3|66|F2
local map_opc2 = {
--0x
[0]="sldt!Dmp","sgdt!Ump","larVrm","lslVrm",nil,"syscall","clts","sysret",
"invd","wbinvd",nil,"ud1",nil,"$prefetch!Bm","femms","3dnowMrmu",
--1x
"movupsXrm|movssXrvm|movupdXrm|movsdXrvm",
"movupsXmr|movssXmvr|movupdXmr|movsdXmvr",
"movhlpsXrm$movlpsXrm|movsldupXrm|movlpdXrm|movddupXrm",
"movlpsXmr||movlpdXmr",
"unpcklpsXrvm||unpcklpdXrvm",
"unpckhpsXrvm||unpckhpdXrvm",
"movlhpsXrm$movhpsXrm|movshdupXrm|movhpdXrm",
"movhpsXmr||movhpdXmr",
"$prefetcht!Bm","hintnopVm","hintnopVm","hintnopVm",
"hintnopVm","hintnopVm","hintnopVm","hintnopVm",
--2x
"movUmx$","movUmy$","movUxm$","movUym$","movUmz$",nil,"movUzm$",nil,
"movapsXrm||movapdXrm",
"movapsXmr||movapdXmr",
"cvtpi2psXrMm|cvtsi2ssXrvVmt|cvtpi2pdXrMm|cvtsi2sdXrvVmt",
"movntpsXmr|movntssXmr|movntpdXmr|movntsdXmr",
"cvttps2piMrXm|cvttss2siVrXm|cvttpd2piMrXm|cvttsd2siVrXm",
"cvtps2piMrXm|cvtss2siVrXm|cvtpd2piMrXm|cvtsd2siVrXm",
"ucomissXrm||ucomisdXrm",
"comissXrm||comisdXrm",
--3x
"wrmsr","rdtsc","rdmsr","rdpmc","sysenter","sysexit",nil,"getsec",
"opc3*38",nil,"opc3*3a",nil,nil,nil,nil,nil,
--4x
"cmovoVrm","cmovnoVrm","cmovbVrm","cmovnbVrm",
"cmovzVrm","cmovnzVrm","cmovbeVrm","cmovaVrm",
"cmovsVrm","cmovnsVrm","cmovpeVrm","cmovpoVrm",
"cmovlVrm","cmovgeVrm","cmovleVrm","cmovgVrm",
--5x
"movmskpsVrXm$||movmskpdVrXm$","sqrtpsXrm|sqrtssXrm|sqrtpdXrm|sqrtsdXrm",
"rsqrtpsXrm|rsqrtssXrvm","rcppsXrm|rcpssXrvm",
"andpsXrvm||andpdXrvm","andnpsXrvm||andnpdXrvm",
"orpsXrvm||orpdXrvm","xorpsXrvm||xorpdXrvm",
"addpsXrvm|addssXrvm|addpdXrvm|addsdXrvm","mulpsXrvm|mulssXrvm|mulpdXrvm|mulsdXrvm",
"cvtps2pdXrm|cvtss2sdXrvm|cvtpd2psXrm|cvtsd2ssXrvm",
"cvtdq2psXrm|cvttps2dqXrm|cvtps2dqXrm",
"subpsXrvm|subssXrvm|subpdXrvm|subsdXrvm","minpsXrvm|minssXrvm|minpdXrvm|minsdXrvm",
"divpsXrvm|divssXrvm|divpdXrvm|divsdXrvm","maxpsXrvm|maxssXrvm|maxpdXrvm|maxsdXrvm",
--6x
"punpcklbwPrvm","punpcklwdPrvm","punpckldqPrvm","packsswbPrvm",
"pcmpgtbPrvm","pcmpgtwPrvm","pcmpgtdPrvm","packuswbPrvm",
"punpckhbwPrvm","punpckhwdPrvm","punpckhdqPrvm","packssdwPrvm",
"||punpcklqdqXrvm","||punpckhqdqXrvm",
"movPrVSm","movqMrm|movdquXrm|movdqaXrm",
--7x
"pshufwMrmu|pshufhwXrmu|pshufdXrmu|pshuflwXrmu","pshiftw!Pvmu",
"pshiftd!Pvmu","pshiftq!Mvmu||pshiftdq!Xvmu",
"pcmpeqbPrvm","pcmpeqwPrvm","pcmpeqdPrvm","emms*|",
"vmreadUmr||extrqXmuu$|insertqXrmuu$","vmwriteUrm||extrqXrm$|insertqXrm$",
nil,nil,
"||haddpdXrvm|haddpsXrvm","||hsubpdXrvm|hsubpsXrvm",
"movVSmMr|movqXrm|movVSmXr","movqMmr|movdquXmr|movdqaXmr",
--8x
"joVj","jnoVj","jbVj","jnbVj","jzVj","jnzVj","jbeVj","jaVj",
"jsVj","jnsVj","jpeVj","jpoVj","jlVj","jgeVj","jleVj","jgVj",
--9x
"setoBm","setnoBm","setbBm","setnbBm","setzBm","setnzBm","setbeBm","setaBm",
"setsBm","setnsBm","setpeBm","setpoBm","setlBm","setgeBm","setleBm","setgBm",
--Ax
"push fs","pop fs","cpuid","btVmr","shldVmru","shldVmrc",nil,nil,
"push gs","pop gs","rsm","btsVmr","shrdVmru","shrdVmrc","fxsave!Dmp","imulVrm",
--Bx
"cmpxchgBmr","cmpxchgVmr","$lssVrm","btrVmr",
"$lfsVrm","$lgsVrm","movzxVrBmt","movzxVrWmt",
"|popcntVrm","ud2Dp","bt!Vmu","btcVmr",
"bsfVrm","bsrVrm|lzcntVrm|bsrWrm","movsxVrBmt","movsxVrWmt",
--Cx
"xaddBmr","xaddVmr",
"cmppsXrvmu|cmpssXrvmu|cmppdXrvmu|cmpsdXrvmu","$movntiVmr|",
"pinsrwPrvWmu","pextrwDrPmu",
"shufpsXrvmu||shufpdXrvmu","$cmpxchg!Qmp",
"bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR",
--Dx
"||addsubpdXrvm|addsubpsXrvm","psrlwPrvm","psrldPrvm","psrlqPrvm",
"paddqPrvm","pmullwPrvm",
"|movq2dqXrMm|movqXmr|movdq2qMrXm$","pmovmskbVrMm||pmovmskbVrXm",
"psubusbPrvm","psubuswPrvm","pminubPrvm","pandPrvm",
"paddusbPrvm","padduswPrvm","pmaxubPrvm","pandnPrvm",
--Ex
"pavgbPrvm","psrawPrvm","psradPrvm","pavgwPrvm",
"pmulhuwPrvm","pmulhwPrvm",
"|cvtdq2pdXrm|cvttpd2dqXrm|cvtpd2dqXrm","$movntqMmr||$movntdqXmr",
"psubsbPrvm","psubswPrvm","pminswPrvm","porPrvm",
"paddsbPrvm","paddswPrvm","pmaxswPrvm","pxorPrvm",
--Fx
"|||lddquXrm","psllwPrvm","pslldPrvm","psllqPrvm",
"pmuludqPrvm","pmaddwdPrvm","psadbwPrvm","maskmovqMrm||maskmovdquXrm$",
"psubbPrvm","psubwPrvm","psubdPrvm","psubqPrvm",
"paddbPrvm","paddwPrvm","padddPrvm","ud",
}
assert(map_opc2[255] == "ud")
-- Map for three-byte opcodes. Can't wait for their next invention.
local map_opc3 = {
["38"] = { -- [66] 0f 38 xx
--0x
[0]="pshufbPrvm","phaddwPrvm","phadddPrvm","phaddswPrvm",
"pmaddubswPrvm","phsubwPrvm","phsubdPrvm","phsubswPrvm",
"psignbPrvm","psignwPrvm","psigndPrvm","pmulhrswPrvm",
"||permilpsXrvm","||permilpdXrvm",nil,nil,
--1x
"||pblendvbXrma",nil,nil,nil,
"||blendvpsXrma","||blendvpdXrma","||permpsXrvm","||ptestXrm",
"||broadcastssXrm","||broadcastsdXrm","||broadcastf128XrlXm",nil,
"pabsbPrm","pabswPrm","pabsdPrm",nil,
--2x
"||pmovsxbwXrm","||pmovsxbdXrm","||pmovsxbqXrm","||pmovsxwdXrm",
"||pmovsxwqXrm","||pmovsxdqXrm",nil,nil,
"||pmuldqXrvm","||pcmpeqqXrvm","||$movntdqaXrm","||packusdwXrvm",
"||maskmovpsXrvm","||maskmovpdXrvm","||maskmovpsXmvr","||maskmovpdXmvr",
--3x
"||pmovzxbwXrm","||pmovzxbdXrm","||pmovzxbqXrm","||pmovzxwdXrm",
"||pmovzxwqXrm","||pmovzxdqXrm","||permdXrvm","||pcmpgtqXrvm",
"||pminsbXrvm","||pminsdXrvm","||pminuwXrvm","||pminudXrvm",
"||pmaxsbXrvm","||pmaxsdXrvm","||pmaxuwXrvm","||pmaxudXrvm",
--4x
"||pmulddXrvm","||phminposuwXrm",nil,nil,
nil,"||psrlvVSXrvm","||psravdXrvm","||psllvVSXrvm",
--5x
[0x58] = "||pbroadcastdXrlXm",[0x59] = "||pbroadcastqXrlXm",
[0x5a] = "||broadcasti128XrlXm",
--7x
[0x78] = "||pbroadcastbXrlXm",[0x79] = "||pbroadcastwXrlXm",
--8x
[0x8c] = "||pmaskmovXrvVSm",
[0x8e] = "||pmaskmovVSmXvr",
--9x
[0x96] = "||fmaddsub132pHXrvm",[0x97] = "||fmsubadd132pHXrvm",
[0x98] = "||fmadd132pHXrvm",[0x99] = "||fmadd132sHXrvm",
[0x9a] = "||fmsub132pHXrvm",[0x9b] = "||fmsub132sHXrvm",
[0x9c] = "||fnmadd132pHXrvm",[0x9d] = "||fnmadd132sHXrvm",
[0x9e] = "||fnmsub132pHXrvm",[0x9f] = "||fnmsub132sHXrvm",
--Ax
[0xa6] = "||fmaddsub213pHXrvm",[0xa7] = "||fmsubadd213pHXrvm",
[0xa8] = "||fmadd213pHXrvm",[0xa9] = "||fmadd213sHXrvm",
[0xaa] = "||fmsub213pHXrvm",[0xab] = "||fmsub213sHXrvm",
[0xac] = "||fnmadd213pHXrvm",[0xad] = "||fnmadd213sHXrvm",
[0xae] = "||fnmsub213pHXrvm",[0xaf] = "||fnmsub213sHXrvm",
--Bx
[0xb6] = "||fmaddsub231pHXrvm",[0xb7] = "||fmsubadd231pHXrvm",
[0xb8] = "||fmadd231pHXrvm",[0xb9] = "||fmadd231sHXrvm",
[0xba] = "||fmsub231pHXrvm",[0xbb] = "||fmsub231sHXrvm",
[0xbc] = "||fnmadd231pHXrvm",[0xbd] = "||fnmadd231sHXrvm",
[0xbe] = "||fnmsub231pHXrvm",[0xbf] = "||fnmsub231sHXrvm",
--Dx
[0xdc] = "||aesencXrvm", [0xdd] = "||aesenclastXrvm",
[0xde] = "||aesdecXrvm", [0xdf] = "||aesdeclastXrvm",
--Fx
[0xf0] = "|||crc32TrBmt",[0xf1] = "|||crc32TrVmt",
[0xf7] = "| sarxVrmv| shlxVrmv| shrxVrmv",
},
["3a"] = { -- [66] 0f 3a xx
--0x
[0x00]="||permqXrmu","||permpdXrmu","||pblenddXrvmu",nil,
"||permilpsXrmu","||permilpdXrmu","||perm2f128Xrvmu",nil,
"||roundpsXrmu","||roundpdXrmu","||roundssXrvmu","||roundsdXrvmu",
"||blendpsXrvmu","||blendpdXrvmu","||pblendwXrvmu","palignrPrvmu",
--1x
nil,nil,nil,nil,
"||pextrbVmXru","||pextrwVmXru","||pextrVmSXru","||extractpsVmXru",
"||insertf128XrvlXmu","||extractf128XlXmYru",nil,nil,
nil,nil,nil,nil,
--2x
"||pinsrbXrvVmu","||insertpsXrvmu","||pinsrXrvVmuS",nil,
--3x
[0x38] = "||inserti128Xrvmu",[0x39] = "||extracti128XlXmYru",
--4x
[0x40] = "||dppsXrvmu",
[0x41] = "||dppdXrvmu",
[0x42] = "||mpsadbwXrvmu",
[0x44] = "||pclmulqdqXrvmu",
[0x46] = "||perm2i128Xrvmu",
[0x4a] = "||blendvpsXrvmb",[0x4b] = "||blendvpdXrvmb",
[0x4c] = "||pblendvbXrvmb",
--6x
[0x60] = "||pcmpestrmXrmu",[0x61] = "||pcmpestriXrmu",
[0x62] = "||pcmpistrmXrmu",[0x63] = "||pcmpistriXrmu",
[0xdf] = "||aeskeygenassistXrmu",
--Fx
[0xf0] = "||| rorxVrmu",
},
}
-- Map for VMX/SVM opcodes 0F 01 C0-FF (sgdt group with register operands).
local map_opcvm = {
[0xc1]="vmcall",[0xc2]="vmlaunch",[0xc3]="vmresume",[0xc4]="vmxoff",
[0xc8]="monitor",[0xc9]="mwait",
[0xd8]="vmrun",[0xd9]="vmmcall",[0xda]="vmload",[0xdb]="vmsave",
[0xdc]="stgi",[0xdd]="clgi",[0xde]="skinit",[0xdf]="invlpga",
[0xf8]="swapgs",[0xf9]="rdtscp",
}
-- Map for FP opcodes. And you thought stack machines are simple?
local map_opcfp = {
-- D8-DF 00-BF: opcodes with a memory operand.
-- D8
[0]="faddFm","fmulFm","fcomFm","fcompFm","fsubFm","fsubrFm","fdivFm","fdivrFm",
"fldFm",nil,"fstFm","fstpFm","fldenvVm","fldcwWm","fnstenvVm","fnstcwWm",
-- DA
"fiaddDm","fimulDm","ficomDm","ficompDm",
"fisubDm","fisubrDm","fidivDm","fidivrDm",
-- DB
"fildDm","fisttpDm","fistDm","fistpDm",nil,"fld twordFmp",nil,"fstp twordFmp",
-- DC
"faddGm","fmulGm","fcomGm","fcompGm","fsubGm","fsubrGm","fdivGm","fdivrGm",
-- DD
"fldGm","fisttpQm","fstGm","fstpGm","frstorDmp",nil,"fnsaveDmp","fnstswWm",
-- DE
"fiaddWm","fimulWm","ficomWm","ficompWm",
"fisubWm","fisubrWm","fidivWm","fidivrWm",
-- DF
"fildWm","fisttpWm","fistWm","fistpWm",
"fbld twordFmp","fildQm","fbstp twordFmp","fistpQm",
-- xx C0-FF: opcodes with a pseudo-register operand.
-- D8
"faddFf","fmulFf","fcomFf","fcompFf","fsubFf","fsubrFf","fdivFf","fdivrFf",
-- D9
"fldFf","fxchFf",{"fnop"},nil,
{"fchs","fabs",nil,nil,"ftst","fxam"},
{"fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz"},
{"f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp"},
{"fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos"},
-- DA
"fcmovbFf","fcmoveFf","fcmovbeFf","fcmovuFf",nil,{nil,"fucompp"},nil,nil,
-- DB
"fcmovnbFf","fcmovneFf","fcmovnbeFf","fcmovnuFf",
{nil,nil,"fnclex","fninit"},"fucomiFf","fcomiFf",nil,
-- DC
"fadd toFf","fmul toFf",nil,nil,
"fsub toFf","fsubr toFf","fdivr toFf","fdiv toFf",
-- DD
"ffreeFf",nil,"fstFf","fstpFf","fucomFf","fucompFf",nil,nil,
-- DE
"faddpFf","fmulpFf",nil,{nil,"fcompp"},
"fsubrpFf","fsubpFf","fdivrpFf","fdivpFf",
-- DF
nil,nil,nil,nil,{"fnstsw ax"},"fucomipFf","fcomipFf",nil,
}
assert(map_opcfp[126] == "fcomipFf")
-- Map for opcode groups. The subkey is sp from the ModRM byte.
local map_opcgroup = {
arith = { "add", "or", "adc", "sbb", "and", "sub", "xor", "cmp" },
shift = { "rol", "ror", "rcl", "rcr", "shl", "shr", "sal", "sar" },
testb = { "testBmi", "testBmi", "not", "neg", "mul", "imul", "div", "idiv" },
testv = { "testVmi", "testVmi", "not", "neg", "mul", "imul", "div", "idiv" },
incb = { "inc", "dec" },
incd = { "inc", "dec", "callUmp", "$call farDmp",
"jmpUmp", "$jmp farDmp", "pushUm" },
sldt = { "sldt", "str", "lldt", "ltr", "verr", "verw" },
sgdt = { "vm*$sgdt", "vm*$sidt", "$lgdt", "vm*$lidt",
"smsw", nil, "lmsw", "vm*$invlpg" },
bt = { nil, nil, nil, nil, "bt", "bts", "btr", "btc" },
cmpxchg = { nil, "sz*,cmpxchg8bQmp,cmpxchg16bXmp", nil, nil,
nil, nil, "vmptrld|vmxon|vmclear", "vmptrst" },
pshiftw = { nil, nil, "psrlw", nil, "psraw", nil, "psllw" },
pshiftd = { nil, nil, "psrld", nil, "psrad", nil, "pslld" },
pshiftq = { nil, nil, "psrlq", nil, nil, nil, "psllq" },
pshiftdq = { nil, nil, "psrlq", "psrldq", nil, nil, "psllq", "pslldq" },
fxsave = { "$fxsave", "$fxrstor", "$ldmxcsr", "$stmxcsr",
nil, "lfenceDp$", "mfenceDp$", "sfenceDp$clflush" },
prefetch = { "prefetch", "prefetchw" },
prefetcht = { "prefetchnta", "prefetcht0", "prefetcht1", "prefetcht2" },
}
------------------------------------------------------------------------------
-- Maps for register names.
local map_regs = {
B = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
"r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b" },
B64 = { "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
"r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b" },
W = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
"r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w" },
D = { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
"r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d" },
Q = { "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" },
M = { "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
"mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7" }, -- No x64 ext!
X = { "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
"xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15" },
Y = { "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7",
"ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15" },
}
local map_segregs = { "es", "cs", "ss", "ds", "fs", "gs", "segr6", "segr7" }
-- Maps for size names.
local map_sz2n = {
B = 1, W = 2, D = 4, Q = 8, M = 8, X = 16, Y = 32,
}
local map_sz2prefix = {
B = "byte", W = "word", D = "dword",
Q = "qword",
M = "qword", X = "xword", Y = "yword",
F = "dword", G = "qword", -- No need for sizes/register names for these two.
}
------------------------------------------------------------------------------
-- Output a nicely formatted line with an opcode and operands.
local function putop(ctx, text, operands)
local code, pos, hex = ctx.code, ctx.pos, ""
local hmax = ctx.hexdump
if hmax > 0 then
for i=ctx.start,pos-1 do
hex = hex..format("%02X", byte(code, i, i))
end
if #hex > hmax then hex = sub(hex, 1, hmax)..". "
else hex = hex..rep(" ", hmax-#hex+2) end
end
if operands then text = text.." "..operands end
if ctx.o16 then text = "o16 "..text; ctx.o16 = false end
if ctx.a32 then text = "a32 "..text; ctx.a32 = false end
if ctx.rep then text = ctx.rep.." "..text; ctx.rep = false end
if ctx.rex then
local t = (ctx.rexw and "w" or "")..(ctx.rexr and "r" or "")..
(ctx.rexx and "x" or "")..(ctx.rexb and "b" or "")..
(ctx.vexl and "l" or "")
if ctx.vexv and ctx.vexv ~= 0 then t = t.."v"..ctx.vexv end
if t ~= "" then text = ctx.rex.."."..t.." "..gsub(text, "^ ", "")
elseif ctx.rex == "vex" then text = gsub("v"..text, "^v ", "") end
ctx.rexw = false; ctx.rexr = false; ctx.rexx = false; ctx.rexb = false
ctx.rex = false; ctx.vexl = false; ctx.vexv = false
end
if ctx.seg then
local text2, n = gsub(text, "%[", "["..ctx.seg..":")
if n == 0 then text = ctx.seg.." "..text else text = text2 end
ctx.seg = false
end
if ctx.lock then text = "lock "..text; ctx.lock = false end
local imm = ctx.imm
if imm then
local sym = ctx.symtab[imm]
if sym then text = text.."\t->"..sym end
end
ctx.out(format("%08x %s%s\n", ctx.addr+ctx.start, hex, text))
ctx.mrm = false
ctx.vexv = false
ctx.start = pos
ctx.imm = nil
end
-- Clear all prefix flags.
local function clearprefixes(ctx)
ctx.o16 = false; ctx.seg = false; ctx.lock = false; ctx.rep = false
ctx.rexw = false; ctx.rexr = false; ctx.rexx = false; ctx.rexb = false
ctx.rex = false; ctx.a32 = false; ctx.vexl = false
end
-- Fallback for incomplete opcodes at the end.
local function incomplete(ctx)
ctx.pos = ctx.stop+1
clearprefixes(ctx)
return putop(ctx, "(incomplete)")
end
-- Fallback for unknown opcodes.
local function unknown(ctx)
clearprefixes(ctx)
return putop(ctx, "(unknown)")
end
-- Return an immediate of the specified size.
local function getimm(ctx, pos, n)
if pos+n-1 > ctx.stop then return incomplete(ctx) end
local code = ctx.code
if n == 1 then
local b1 = byte(code, pos, pos)
return b1
elseif n == 2 then
local b1, b2 = byte(code, pos, pos+1)
return b1+b2*256
else
local b1, b2, b3, b4 = byte(code, pos, pos+3)
local imm = b1+b2*256+b3*65536+b4*16777216
ctx.imm = imm
return imm
end
end
-- Process pattern string and generate the operands.
local function putpat(ctx, name, pat)
local operands, regs, sz, mode, sp, rm, sc, rx, sdisp
local code, pos, stop, vexl = ctx.code, ctx.pos, ctx.stop, ctx.vexl
-- Chars used: 1DFGHIMPQRSTUVWXYabcdfgijlmoprstuvwxyz
for p in gmatch(pat, ".") do
local x = nil
if p == "V" or p == "U" then
if ctx.rexw then sz = "Q"; ctx.rexw = false
elseif ctx.o16 then sz = "W"; ctx.o16 = false
elseif p == "U" and ctx.x64 then sz = "Q"
else sz = "D" end
regs = map_regs[sz]
elseif p == "T" then
if ctx.rexw then sz = "Q"; ctx.rexw = false else sz = "D" end
regs = map_regs[sz]
elseif p == "B" then
sz = "B"
regs = ctx.rex and map_regs.B64 or map_regs.B
elseif match(p, "[WDQMXYFG]") then
sz = p
if sz == "X" and vexl then sz = "Y"; ctx.vexl = false end
regs = map_regs[sz]
elseif p == "P" then
sz = ctx.o16 and "X" or "M"; ctx.o16 = false
if sz == "X" and vexl then sz = "Y"; ctx.vexl = false end
regs = map_regs[sz]
elseif p == "H" then
name = name..(ctx.rexw and "d" or "s")
ctx.rexw = false
elseif p == "S" then
name = name..lower(sz)
elseif p == "s" then
local imm = getimm(ctx, pos, 1); if not imm then return end
x = imm <= 127 and format("+0x%02x", imm)
or format("-0x%02x", 256-imm)
pos = pos+1
elseif p == "u" then
local imm = getimm(ctx, pos, 1); if not imm then return end
x = format("0x%02x", imm)
pos = pos+1
elseif p == "b" then
local imm = getimm(ctx, pos, 1); if not imm then return end
x = regs[imm/16+1]
pos = pos+1
elseif p == "w" then
local imm = getimm(ctx, pos, 2); if not imm then return end
x = format("0x%x", imm)
pos = pos+2
elseif p == "o" then -- [offset]
if ctx.x64 then
local imm1 = getimm(ctx, pos, 4); if not imm1 then return end
local imm2 = getimm(ctx, pos+4, 4); if not imm2 then return end
x = format("[0x%08x%08x]", imm2, imm1)
pos = pos+8
else
local imm = getimm(ctx, pos, 4); if not imm then return end
x = format("[0x%08x]", imm)
pos = pos+4
end
elseif p == "i" or p == "I" then
local n = map_sz2n[sz]
if n == 8 and ctx.x64 and p == "I" then
local imm1 = getimm(ctx, pos, 4); if not imm1 then return end
local imm2 = getimm(ctx, pos+4, 4); if not imm2 then return end
x = format("0x%08x%08x", imm2, imm1)
else
if n == 8 then n = 4 end
local imm = getimm(ctx, pos, n); if not imm then return end
if sz == "Q" and (imm < 0 or imm > 0x7fffffff) then
imm = (0xffffffff+1)-imm
x = format(imm > 65535 and "-0x%08x" or "-0x%x", imm)
else
x = format(imm > 65535 and "0x%08x" or "0x%x", imm)
end
end
pos = pos+n
elseif p == "j" then
local n = map_sz2n[sz]
if n == 8 then n = 4 end
local imm = getimm(ctx, pos, n); if not imm then return end
if sz == "B" and imm > 127 then imm = imm-256
elseif imm > 2147483647 then imm = imm-4294967296 end
pos = pos+n
imm = imm + pos + ctx.addr
if imm > 4294967295 and not ctx.x64 then imm = imm-4294967296 end
ctx.imm = imm
if sz == "W" then
x = format("word 0x%04x", imm%65536)
elseif ctx.x64 then
local lo = imm % 0x1000000
x = format("0x%02x%06x", (imm-lo) / 0x1000000, lo)
else
x = "0x"..tohex(imm)
end
elseif p == "R" then
local r = byte(code, pos-1, pos-1)%8
if ctx.rexb then r = r + 8; ctx.rexb = false end
x = regs[r+1]
elseif p == "a" then x = regs[1]
elseif p == "c" then x = "cl"
elseif p == "d" then x = "dx"
elseif p == "1" then x = "1"
else
if not mode then
mode = ctx.mrm
if not mode then
if pos > stop then return incomplete(ctx) end
mode = byte(code, pos, pos)
pos = pos+1
end
rm = mode%8; mode = (mode-rm)/8
sp = mode%8; mode = (mode-sp)/8
sdisp = ""
if mode < 3 then
if rm == 4 then
if pos > stop then return incomplete(ctx) end
sc = byte(code, pos, pos)
pos = pos+1
rm = sc%8; sc = (sc-rm)/8
rx = sc%8; sc = (sc-rx)/8
if ctx.rexx then rx = rx + 8; ctx.rexx = false end
if rx == 4 then rx = nil end
end
if mode > 0 or rm == 5 then
local dsz = mode
if dsz ~= 1 then dsz = 4 end
local disp = getimm(ctx, pos, dsz); if not disp then return end
if mode == 0 then rm = nil end
if rm or rx or (not sc and ctx.x64 and not ctx.a32) then
if dsz == 1 and disp > 127 then
sdisp = format("-0x%x", 256-disp)
elseif disp >= 0 and disp <= 0x7fffffff then
sdisp = format("+0x%x", disp)
else
sdisp = format("-0x%x", (0xffffffff+1)-disp)
end
else
sdisp = format(ctx.x64 and not ctx.a32 and
not (disp >= 0 and disp <= 0x7fffffff)
and "0xffffffff%08x" or "0x%08x", disp)
end
pos = pos+dsz
end
end
if rm and ctx.rexb then rm = rm + 8; ctx.rexb = false end
if ctx.rexr then sp = sp + 8; ctx.rexr = false end
end
if p == "m" then
if mode == 3 then x = regs[rm+1]
else
local aregs = ctx.a32 and map_regs.D or ctx.aregs
local srm, srx = "", ""
if rm then srm = aregs[rm+1]
elseif not sc and ctx.x64 and not ctx.a32 then srm = "rip" end
ctx.a32 = false
if rx then
if rm then srm = srm.."+" end
srx = aregs[rx+1]
if sc > 0 then srx = srx.."*"..(2^sc) end
end
x = format("[%s%s%s]", srm, srx, sdisp)
end
if mode < 3 and
(not match(pat, "[aRrgp]") or match(pat, "t")) then -- Yuck.
x = map_sz2prefix[sz].." "..x
end
elseif p == "r" then x = regs[sp+1]
elseif p == "g" then x = map_segregs[sp+1]
elseif p == "p" then -- Suppress prefix.
elseif p == "f" then x = "st"..rm
elseif p == "x" then
if sp == 0 and ctx.lock and not ctx.x64 then
x = "CR8"; ctx.lock = false
else
x = "CR"..sp
end
elseif p == "v" then
if ctx.vexv then
x = regs[ctx.vexv+1]; ctx.vexv = false
end
elseif p == "y" then x = "DR"..sp
elseif p == "z" then x = "TR"..sp
elseif p == "l" then vexl = false
elseif p == "t" then
else
error("bad pattern `"..pat.."'")
end
end
if x then operands = operands and operands..", "..x or x end
end
ctx.pos = pos
return putop(ctx, name, operands)
end
-- Forward declaration.
local map_act
-- Fetch and cache MRM byte.
local function getmrm(ctx)
local mrm = ctx.mrm
if not mrm then
local pos = ctx.pos
if pos > ctx.stop then return nil end
mrm = byte(ctx.code, pos, pos)
ctx.pos = pos+1
ctx.mrm = mrm
end
return mrm
end
-- Dispatch to handler depending on pattern.
local function dispatch(ctx, opat, patgrp)
if not opat then return unknown(ctx) end
if match(opat, "%|") then -- MMX/SSE variants depending on prefix.
local p
if ctx.rep then
p = ctx.rep=="rep" and "%|([^%|]*)" or "%|[^%|]*%|[^%|]*%|([^%|]*)"
ctx.rep = false
elseif ctx.o16 then p = "%|[^%|]*%|([^%|]*)"; ctx.o16 = false
else p = "^[^%|]*" end
opat = match(opat, p)
if not opat then return unknown(ctx) end
-- ctx.rep = false; ctx.o16 = false
--XXX fails for 66 f2 0f 38 f1 06 crc32 eax,WORD PTR [esi]
--XXX remove in branches?
end
if match(opat, "%$") then -- reg$mem variants.
local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end
opat = match(opat, mrm >= 192 and "^[^%$]*" or "%$(.*)")
if opat == "" then return unknown(ctx) end
end
if opat == "" then return unknown(ctx) end
local name, pat = match(opat, "^([a-z0-9 ]*)(.*)")
if pat == "" and patgrp then pat = patgrp end
return map_act[sub(pat, 1, 1)](ctx, name, pat)
end
-- Get a pattern from an opcode map and dispatch to handler.
local function dispatchmap(ctx, opcmap)
local pos = ctx.pos
local opat = opcmap[byte(ctx.code, pos, pos)]
pos = pos + 1
ctx.pos = pos
return dispatch(ctx, opat)
end
-- Map for action codes. The key is the first char after the name.
map_act = {
-- Simple opcodes without operands.
[""] = function(ctx, name, pat)
return putop(ctx, name)
end,
-- Operand size chars fall right through.
B = putpat, W = putpat, D = putpat, Q = putpat,
V = putpat, U = putpat, T = putpat,
M = putpat, X = putpat, P = putpat,
F = putpat, G = putpat, Y = putpat,
H = putpat,
-- Collect prefixes.
[":"] = function(ctx, name, pat)
ctx[pat == ":" and name or sub(pat, 2)] = name
if ctx.pos - ctx.start > 5 then return unknown(ctx) end -- Limit #prefixes.
end,
-- Chain to special handler specified by name.
["*"] = function(ctx, name, pat)
return map_act[name](ctx, name, sub(pat, 2))
end,
-- Use named subtable for opcode group.
["!"] = function(ctx, name, pat)
local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end
return dispatch(ctx, map_opcgroup[name][((mrm-(mrm%8))/8)%8+1], sub(pat, 2))
end,
-- o16,o32[,o64] variants.
sz = function(ctx, name, pat)
if ctx.o16 then ctx.o16 = false
else
pat = match(pat, ",(.*)")
if ctx.rexw then
local p = match(pat, ",(.*)")
if p then pat = p; ctx.rexw = false end
end
end
pat = match(pat, "^[^,]*")
return dispatch(ctx, pat)
end,
-- Two-byte opcode dispatch.
opc2 = function(ctx, name, pat)
return dispatchmap(ctx, map_opc2)
end,
-- Three-byte opcode dispatch.
opc3 = function(ctx, name, pat)
return dispatchmap(ctx, map_opc3[pat])
end,
-- VMX/SVM dispatch.
vm = function(ctx, name, pat)
return dispatch(ctx, map_opcvm[ctx.mrm])
end,
-- Floating point opcode dispatch.
fp = function(ctx, name, pat)
local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end
local rm = mrm%8
local idx = pat*8 + ((mrm-rm)/8)%8
if mrm >= 192 then idx = idx + 64 end
local opat = map_opcfp[idx]
if type(opat) == "table" then opat = opat[rm+1] end
return dispatch(ctx, opat)
end,
-- REX prefix.
rex = function(ctx, name, pat)
if ctx.rex then return unknown(ctx) end -- Only 1 REX or VEX prefix allowed.
for p in gmatch(pat, ".") do ctx["rex"..p] = true end
ctx.rex = "rex"
end,
-- VEX prefix.
vex = function(ctx, name, pat)
if ctx.rex then return unknown(ctx) end -- Only 1 REX or VEX prefix allowed.
ctx.rex = "vex"
local pos = ctx.pos
if ctx.mrm then
ctx.mrm = nil
pos = pos-1
end
local b = byte(ctx.code, pos, pos)
if not b then return incomplete(ctx) end
pos = pos+1
if b < 128 then ctx.rexr = true end
local m = 1
if pat == "3" then
m = b%32; b = (b-m)/32
local nb = b%2; b = (b-nb)/2
if nb == 0 then ctx.rexb = true end
local nx = b%2
if nx == 0 then ctx.rexx = true end
b = byte(ctx.code, pos, pos)
if not b then return incomplete(ctx) end
pos = pos+1
if b >= 128 then ctx.rexw = true end
end
ctx.pos = pos
local map
if m == 1 then map = map_opc2
elseif m == 2 then map = map_opc3["38"]
elseif m == 3 then map = map_opc3["3a"]
else return unknown(ctx) end
local p = b%4; b = (b-p)/4
if p == 1 then ctx.o16 = "o16"
elseif p == 2 then ctx.rep = "rep"
elseif p == 3 then ctx.rep = "repne" end
local l = b%2; b = (b-l)/2
if l ~= 0 then ctx.vexl = true end
ctx.vexv = (-1-b)%16
return dispatchmap(ctx, map)
end,
-- Special case for nop with REX prefix.
nop = function(ctx, name, pat)
return dispatch(ctx, ctx.rex and pat or "nop")
end,
-- Special case for 0F 77.
emms = function(ctx, name, pat)
if ctx.rex ~= "vex" then
return putop(ctx, "emms")
elseif ctx.vexl then
ctx.vexl = false
return putop(ctx, "zeroall")
else
return putop(ctx, "zeroupper")
end
end,
}
------------------------------------------------------------------------------
-- Disassemble a block of code.
local function disass_block(ctx, ofs, len)
if not ofs then ofs = 0 end
local stop = len and ofs+len or #ctx.code
ofs = ofs + 1
ctx.start = ofs
ctx.pos = ofs
ctx.stop = stop
ctx.imm = nil
ctx.mrm = false
clearprefixes(ctx)
while ctx.pos <= stop do dispatchmap(ctx, ctx.map1) end
if ctx.pos ~= ctx.start then incomplete(ctx) end
end
-- Extended API: create a disassembler context. Then call ctx:disass(ofs, len).
local function create(code, addr, out)
local ctx = {}
ctx.code = code
ctx.addr = (addr or 0) - 1
ctx.out = out or io.write
ctx.symtab = {}
ctx.disass = disass_block
ctx.hexdump = 16
ctx.x64 = false
ctx.map1 = map_opc1_32
ctx.aregs = map_regs.D
return ctx
end
local function create64(code, addr, out)
local ctx = create(code, addr, out)
ctx.x64 = true
ctx.map1 = map_opc1_64
ctx.aregs = map_regs.Q
return ctx
end
-- Simple API: disassemble code (a string) at address and output via out.
local function disass(code, addr, out)
create(code, addr, out):disass()
end
local function disass64(code, addr, out)
create64(code, addr, out):disass()
end
-- Return register name for RID.
local function regname(r)
if r < 8 then return map_regs.D[r+1] end
return map_regs.X[r-7]
end
local function regname64(r)
if r < 16 then return map_regs.Q[r+1] end
return map_regs.X[r-15]
end
-- Public module functions.
return {
create = create,
create64 = create64,
disass = disass,
disass64 = disass64,
regname = regname,
regname64 = regname64
}

View file

@ -0,0 +1,725 @@
----------------------------------------------------------------------------
-- LuaJIT compiler dump module.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
--
-- This module can be used to debug the JIT compiler itself. It dumps the
-- code representations and structures used in various compiler stages.
--
-- Example usage:
--
-- luajit -jdump -e "local x=0; for i=1,1e6 do x=x+i end; print(x)"
-- luajit -jdump=im -e "for i=1,1000 do for j=1,1000 do end end" | less -R
-- luajit -jdump=is myapp.lua | less -R
-- luajit -jdump=-b myapp.lua
-- luajit -jdump=+aH,myapp.html myapp.lua
-- luajit -jdump=ixT,myapp.dump myapp.lua
--
-- The first argument specifies the dump mode. The second argument gives
-- the output file name. Default output is to stdout, unless the environment
-- variable LUAJIT_DUMPFILE is set. The file is overwritten every time the
-- module is started.
--
-- Different features can be turned on or off with the dump mode. If the
-- mode starts with a '+', the following features are added to the default
-- set of features; a '-' removes them. Otherwise the features are replaced.
--
-- The following dump features are available (* marks the default):
--
-- * t Print a line for each started, ended or aborted trace (see also -jv).
-- * b Dump the traced bytecode.
-- * i Dump the IR (intermediate representation).
-- r Augment the IR with register/stack slots.
-- s Dump the snapshot map.
-- * m Dump the generated machine code.
-- x Print each taken trace exit.
-- X Print each taken trace exit and the contents of all registers.
-- a Print the IR of aborted traces, too.
--
-- The output format can be set with the following characters:
--
-- T Plain text output.
-- A ANSI-colored text output
-- H Colorized HTML + CSS output.
--
-- The default output format is plain text. It's set to ANSI-colored text
-- if the COLORTERM variable is set. Note: this is independent of any output
-- redirection, which is actually considered a feature.
--
-- You probably want to use less -R to enjoy viewing ANSI-colored text from
-- a pipe or a file. Add this to your ~/.bashrc: export LESS="-R"
--
------------------------------------------------------------------------------
-- Cache some library functions and objects.
local jit = require("jit")
local jutil = require("jit.util")
local vmdef = require("jit.vmdef")
local funcinfo, funcbc = jutil.funcinfo, jutil.funcbc
local traceinfo, traceir, tracek = jutil.traceinfo, jutil.traceir, jutil.tracek
local tracemc, tracesnap = jutil.tracemc, jutil.tracesnap
local traceexitstub, ircalladdr = jutil.traceexitstub, jutil.ircalladdr
local bit = require("bit")
local band, shr, tohex = bit.band, bit.rshift, bit.tohex
local sub, gsub, format = string.sub, string.gsub, string.format
local byte, rep = string.byte, string.rep
local type, tostring = type, tostring
local stdout, stderr = io.stdout, io.stderr
-- Load other modules on-demand.
local bcline, disass
-- Active flag, output file handle and dump mode.
local active, out, dumpmode
------------------------------------------------------------------------------
local symtabmt = { __index = false }
local symtab = {}
local nexitsym = 0
-- Fill nested symbol table with per-trace exit stub addresses.
local function fillsymtab_tr(tr, nexit)
local t = {}
symtabmt.__index = t
if jit.arch:sub(1, 4) == "mips" then
t[traceexitstub(tr, 0)] = "exit"
return
end
for i=0,nexit-1 do
local addr = traceexitstub(tr, i)
if addr < 0 then addr = addr + 2^32 end
t[addr] = tostring(i)
end
local addr = traceexitstub(tr, nexit)
if addr then t[addr] = "stack_check" end
end
-- Fill symbol table with trace exit stub addresses.
local function fillsymtab(tr, nexit)
local t = symtab
if nexitsym == 0 then
local maskaddr = jit.arch == "arm" and -2
local ircall = vmdef.ircall
for i=0,#ircall do
local addr = ircalladdr(i)
if addr ~= 0 then
if maskaddr then addr = band(addr, maskaddr) end
if addr < 0 then addr = addr + 2^32 end
t[addr] = ircall[i]
end
end
end
if nexitsym == 1000000 then -- Per-trace exit stubs.
fillsymtab_tr(tr, nexit)
elseif nexit > nexitsym then -- Shared exit stubs.
for i=nexitsym,nexit-1 do
local addr = traceexitstub(i)
if addr == nil then -- Fall back to per-trace exit stubs.
fillsymtab_tr(tr, nexit)
setmetatable(symtab, symtabmt)
nexit = 1000000
break
end
if addr < 0 then addr = addr + 2^32 end
t[addr] = tostring(i)
end
nexitsym = nexit
end
return t
end
local function dumpwrite(s)
out:write(s)
end
-- Disassemble machine code.
local function dump_mcode(tr)
local info = traceinfo(tr)
if not info then return end
local mcode, addr, loop = tracemc(tr)
if not mcode then return end
if not disass then disass = require("jit.dis_"..jit.arch) end
if addr < 0 then addr = addr + 2^32 end
out:write("---- TRACE ", tr, " mcode ", #mcode, "\n")
local ctx = disass.create(mcode, addr, dumpwrite)
ctx.hexdump = 0
ctx.symtab = fillsymtab(tr, info.nexit)
if loop ~= 0 then
symtab[addr+loop] = "LOOP"
ctx:disass(0, loop)
out:write("->LOOP:\n")
ctx:disass(loop, #mcode-loop)
symtab[addr+loop] = nil
else
ctx:disass(0, #mcode)
end
end
------------------------------------------------------------------------------
local irtype_text = {
[0] = "nil",
"fal",
"tru",
"lud",
"str",
"p32",
"thr",
"pro",
"fun",
"p64",
"cdt",
"tab",
"udt",
"flt",
"num",
"i8 ",
"u8 ",
"i16",
"u16",
"int",
"u32",
"i64",
"u64",
"sfp",
}
local colortype_ansi = {
[0] = "%s",
"%s",
"%s",
"\027[36m%s\027[m",
"\027[32m%s\027[m",
"%s",
"\027[1m%s\027[m",
"%s",
"\027[1m%s\027[m",
"%s",
"\027[33m%s\027[m",
"\027[31m%s\027[m",
"\027[36m%s\027[m",
"\027[34m%s\027[m",
"\027[34m%s\027[m",
"\027[35m%s\027[m",
"\027[35m%s\027[m",
"\027[35m%s\027[m",
"\027[35m%s\027[m",
"\027[35m%s\027[m",
"\027[35m%s\027[m",
"\027[35m%s\027[m",
"\027[35m%s\027[m",
"\027[35m%s\027[m",
}
local function colorize_text(s)
return s
end
local function colorize_ansi(s, t, extra)
local out = format(colortype_ansi[t], s)
if extra then out = "\027[3m"..out end
return out
end
local irtype_ansi = setmetatable({},
{ __index = function(tab, t)
local s = colorize_ansi(irtype_text[t], t); tab[t] = s; return s; end })
local html_escape = { ["<"] = "&lt;", [">"] = "&gt;", ["&"] = "&amp;", }
local function colorize_html(s, t, extra)
s = gsub(s, "[<>&]", html_escape)
return format('<span class="irt_%s%s">%s</span>',
irtype_text[t], extra and " irt_extra" or "", s)
end
local irtype_html = setmetatable({},
{ __index = function(tab, t)
local s = colorize_html(irtype_text[t], t); tab[t] = s; return s; end })
local header_html = [[
<style type="text/css">
background { background: #ffffff; color: #000000; }
pre.ljdump {
font-size: 10pt;
background: #f0f4ff;
color: #000000;
border: 1px solid #bfcfff;
padding: 0.5em;
margin-left: 2em;
margin-right: 2em;
}
span.irt_str { color: #00a000; }
span.irt_thr, span.irt_fun { color: #404040; font-weight: bold; }
span.irt_tab { color: #c00000; }
span.irt_udt, span.irt_lud { color: #00c0c0; }
span.irt_num { color: #4040c0; }
span.irt_int, span.irt_i8, span.irt_u8, span.irt_i16, span.irt_u16 { color: #b040b0; }
span.irt_extra { font-style: italic; }
</style>
]]
local colorize, irtype
-- Lookup tables to convert some literals into names.
local litname = {
["SLOAD "] = setmetatable({}, { __index = function(t, mode)
local s = ""
if band(mode, 1) ~= 0 then s = s.."P" end
if band(mode, 2) ~= 0 then s = s.."F" end
if band(mode, 4) ~= 0 then s = s.."T" end
if band(mode, 8) ~= 0 then s = s.."C" end
if band(mode, 16) ~= 0 then s = s.."R" end
if band(mode, 32) ~= 0 then s = s.."I" end
if band(mode, 64) ~= 0 then s = s.."K" end
t[mode] = s
return s
end}),
["XLOAD "] = { [0] = "", "R", "V", "RV", "U", "RU", "VU", "RVU", },
["CONV "] = setmetatable({}, { __index = function(t, mode)
local s = irtype[band(mode, 31)]
s = irtype[band(shr(mode, 5), 31)].."."..s
if band(mode, 0x800) ~= 0 then s = s.." sext" end
local c = shr(mode, 12)
if c == 1 then s = s.." none"
elseif c == 2 then s = s.." index"
elseif c == 3 then s = s.." check" end
t[mode] = s
return s
end}),
["FLOAD "] = vmdef.irfield,
["FREF "] = vmdef.irfield,
["FPMATH"] = vmdef.irfpm,
["TMPREF"] = { [0] = "", "IN", "OUT", "INOUT", "", "", "OUT2", "INOUT2" },
["BUFHDR"] = { [0] = "RESET", "APPEND", "WRITE" },
["TOSTR "] = { [0] = "INT", "NUM", "CHAR" },
}
local function ctlsub(c)
if c == "\n" then return "\\n"
elseif c == "\r" then return "\\r"
elseif c == "\t" then return "\\t"
else return format("\\%03d", byte(c))
end
end
local function fmtfunc(func, pc)
local fi = funcinfo(func, pc)
if fi.loc then
return fi.loc
elseif fi.ffid then
return vmdef.ffnames[fi.ffid]
elseif fi.addr then
return format("C:%x", fi.addr)
else
return "(?)"
end
end
local function formatk(tr, idx, sn)
local k, t, slot = tracek(tr, idx)
local tn = type(k)
local s
if tn == "number" then
if t < 12 then
s = k == 0 and "NULL" or format("[0x%08x]", k)
elseif band(sn or 0, 0x30000) ~= 0 then
s = band(sn, 0x20000) ~= 0 and "contpc" or "ftsz"
elseif k == 2^52+2^51 then
s = "bias"
else
s = format(0 < k and k < 0x1p-1026 and "%+a" or "%+.14g", k)
end
elseif tn == "string" then
s = format(#k > 20 and '"%.20s"~' or '"%s"', gsub(k, "%c", ctlsub))
elseif tn == "function" then
s = fmtfunc(k)
elseif tn == "table" then
s = format("{%p}", k)
elseif tn == "userdata" then
if t == 12 then
s = format("userdata:%p", k)
else
s = format("[%p]", k)
if s == "[NULL]" then s = "NULL" end
end
elseif t == 21 then -- int64_t
s = sub(tostring(k), 1, -3)
if sub(s, 1, 1) ~= "-" then s = "+"..s end
elseif sn == 0x1057fff then -- SNAP(1, SNAP_FRAME | SNAP_NORESTORE, REF_NIL)
return "----" -- Special case for LJ_FR2 slot 1.
else
s = tostring(k) -- For primitives.
end
s = colorize(format("%-4s", s), t, band(sn or 0, 0x100000) ~= 0)
if slot then
s = format("%s @%d", s, slot)
end
return s
end
local function printsnap(tr, snap)
local n = 2
for s=0,snap[1]-1 do
local sn = snap[n]
if shr(sn, 24) == s then
n = n + 1
local ref = band(sn, 0xffff) - 0x8000 -- REF_BIAS
if ref < 0 then
out:write(formatk(tr, ref, sn))
elseif band(sn, 0x80000) ~= 0 then -- SNAP_SOFTFPNUM
out:write(colorize(format("%04d/%04d", ref, ref+1), 14))
else
local m, ot, op1, op2 = traceir(tr, ref)
out:write(colorize(format("%04d", ref), band(ot, 31), band(sn, 0x100000) ~= 0))
end
out:write(band(sn, 0x10000) == 0 and " " or "|") -- SNAP_FRAME
else
out:write("---- ")
end
end
out:write("]\n")
end
-- Dump snapshots (not interleaved with IR).
local function dump_snap(tr)
out:write("---- TRACE ", tr, " snapshots\n")
for i=0,1000000000 do
local snap = tracesnap(tr, i)
if not snap then break end
out:write(format("#%-3d %04d [ ", i, snap[0]))
printsnap(tr, snap)
end
end
-- Return a register name or stack slot for a rid/sp location.
local function ridsp_name(ridsp, ins)
if not disass then disass = require("jit.dis_"..jit.arch) end
local rid, slot = band(ridsp, 0xff), shr(ridsp, 8)
if rid == 253 or rid == 254 then
return (slot == 0 or slot == 255) and " {sink" or format(" {%04d", ins-slot)
end
if ridsp > 255 then return format("[%x]", slot*4) end
if rid < 128 then return disass.regname(rid) end
return ""
end
-- Dump CALL* function ref and return optional ctype.
local function dumpcallfunc(tr, ins)
local ctype
if ins > 0 then
local m, ot, op1, op2 = traceir(tr, ins)
if band(ot, 31) == 0 then -- nil type means CARG(func, ctype).
ins = op1
ctype = formatk(tr, op2)
end
end
if ins < 0 then
out:write(format("[0x%x](", tonumber((tracek(tr, ins)))))
else
out:write(format("%04d (", ins))
end
return ctype
end
-- Recursively gather CALL* args and dump them.
local function dumpcallargs(tr, ins)
if ins < 0 then
out:write(formatk(tr, ins))
else
local m, ot, op1, op2 = traceir(tr, ins)
local oidx = 6*shr(ot, 8)
local op = sub(vmdef.irnames, oidx+1, oidx+6)
if op == "CARG " then
dumpcallargs(tr, op1)
if op2 < 0 then
out:write(" ", formatk(tr, op2))
else
out:write(" ", format("%04d", op2))
end
else
out:write(format("%04d", ins))
end
end
end
-- Dump IR and interleaved snapshots.
local function dump_ir(tr, dumpsnap, dumpreg)
local info = traceinfo(tr)
if not info then return end
local nins = info.nins
out:write("---- TRACE ", tr, " IR\n")
local irnames = vmdef.irnames
local snapref = 65536
local snap, snapno
if dumpsnap then
snap = tracesnap(tr, 0)
snapref = snap[0]
snapno = 0
end
for ins=1,nins do
if ins >= snapref then
if dumpreg then
out:write(format(".... SNAP #%-3d [ ", snapno))
else
out:write(format(".... SNAP #%-3d [ ", snapno))
end
printsnap(tr, snap)
snapno = snapno + 1
snap = tracesnap(tr, snapno)
snapref = snap and snap[0] or 65536
end
local m, ot, op1, op2, ridsp = traceir(tr, ins)
local oidx, t = 6*shr(ot, 8), band(ot, 31)
local op = sub(irnames, oidx+1, oidx+6)
if op == "LOOP " then
if dumpreg then
out:write(format("%04d ------------ LOOP ------------\n", ins))
else
out:write(format("%04d ------ LOOP ------------\n", ins))
end
elseif op ~= "NOP " and op ~= "CARG " and
(dumpreg or op ~= "RENAME") then
local rid = band(ridsp, 255)
if dumpreg then
out:write(format("%04d %-6s", ins, ridsp_name(ridsp, ins)))
else
out:write(format("%04d ", ins))
end
out:write(format("%s%s %s %s ",
(rid == 254 or rid == 253) and "}" or
(band(ot, 128) == 0 and " " or ">"),
band(ot, 64) == 0 and " " or "+",
irtype[t], op))
local m1, m2 = band(m, 3), band(m, 3*4)
if sub(op, 1, 4) == "CALL" then
local ctype
if m2 == 1*4 then -- op2 == IRMlit
out:write(format("%-10s (", vmdef.ircall[op2]))
else
ctype = dumpcallfunc(tr, op2)
end
if op1 ~= -1 then dumpcallargs(tr, op1) end
out:write(")")
if ctype then out:write(" ctype ", ctype) end
elseif op == "CNEW " and op2 == -1 then
out:write(formatk(tr, op1))
elseif m1 ~= 3 then -- op1 != IRMnone
if op1 < 0 then
out:write(formatk(tr, op1))
else
out:write(format(m1 == 0 and "%04d" or "#%-3d", op1))
end
if m2 ~= 3*4 then -- op2 != IRMnone
if m2 == 1*4 then -- op2 == IRMlit
local litn = litname[op]
if litn and litn[op2] then
out:write(" ", litn[op2])
elseif op == "UREFO " or op == "UREFC " then
out:write(format(" #%-3d", shr(op2, 8)))
else
out:write(format(" #%-3d", op2))
end
elseif op2 < 0 then
out:write(" ", formatk(tr, op2))
else
out:write(format(" %04d", op2))
end
end
end
out:write("\n")
end
end
if snap then
if dumpreg then
out:write(format(".... SNAP #%-3d [ ", snapno))
else
out:write(format(".... SNAP #%-3d [ ", snapno))
end
printsnap(tr, snap)
end
end
------------------------------------------------------------------------------
local recprefix = ""
local recdepth = 0
-- Format trace error message.
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)
end
return err
end
-- Dump trace states.
local function dump_trace(what, tr, func, pc, otr, oex)
if what == "stop" or (what == "abort" and dumpmode.a) then
if dumpmode.i then dump_ir(tr, dumpmode.s, dumpmode.r and what == "stop")
elseif dumpmode.s then dump_snap(tr) end
if dumpmode.m then dump_mcode(tr) end
end
if what == "start" then
if dumpmode.H then out:write('<pre class="ljdump">\n') end
out:write("---- TRACE ", tr, " ", what)
if otr then out:write(" ", otr, "/", oex == -1 and "stitch" or oex) end
out:write(" ", fmtfunc(func, pc), "\n")
elseif what == "stop" or what == "abort" then
out:write("---- TRACE ", tr, " ", what)
if what == "abort" then
out:write(" ", fmtfunc(func, pc), " -- ", fmterr(otr, oex), "\n")
else
local info = traceinfo(tr)
local link, ltype = info.link, info.linktype
if link == tr or link == 0 then
out:write(" -> ", ltype, "\n")
elseif ltype == "root" then
out:write(" -> ", link, "\n")
else
out:write(" -> ", link, " ", ltype, "\n")
end
end
if dumpmode.H then out:write("</pre>\n\n") else out:write("\n") end
else
if what == "flush" then symtab, nexitsym = {}, 0 end
out:write("---- TRACE ", what, "\n\n")
end
out:flush()
end
-- Dump recorded bytecode.
local function dump_record(tr, func, pc, depth)
if depth ~= recdepth then
recdepth = depth
recprefix = rep(" .", depth)
end
local line
if pc >= 0 then
line = bcline(func, pc, recprefix)
if dumpmode.H then line = gsub(line, "[<>&]", html_escape) end
else
line = "0000 "..recprefix.." FUNCC \n"
end
if pc <= 0 then
out:write(sub(line, 1, -2), " ; ", fmtfunc(func), "\n")
else
out:write(line)
end
if pc >= 0 and band(funcbc(func, pc), 0xff) < 16 then -- ORDER BC
out:write(bcline(func, pc+1, recprefix)) -- Write JMP for cond.
end
end
------------------------------------------------------------------------------
local gpr64 = jit.arch:match("64")
local fprmips32 = jit.arch == "mips" or jit.arch == "mipsel"
-- Dump taken trace exits.
local function dump_texit(tr, ex, ngpr, nfpr, ...)
out:write("---- TRACE ", tr, " exit ", ex, "\n")
if dumpmode.X then
local regs = {...}
if gpr64 then
for i=1,ngpr do
out:write(format(" %016x", regs[i]))
if i % 4 == 0 then out:write("\n") end
end
else
for i=1,ngpr do
out:write(" ", tohex(regs[i]))
if i % 8 == 0 then out:write("\n") end
end
end
if fprmips32 then
for i=1,nfpr,2 do
out:write(format(" %+17.14g", regs[ngpr+i]))
if i % 8 == 7 then out:write("\n") end
end
else
for i=1,nfpr do
out:write(format(" %+17.14g", regs[ngpr+i]))
if i % 4 == 0 then out:write("\n") end
end
end
end
end
------------------------------------------------------------------------------
-- Detach dump handlers.
local function dumpoff()
if active then
active = false
jit.attach(dump_texit)
jit.attach(dump_record)
jit.attach(dump_trace)
if out and out ~= stdout and out ~= stderr then out:close() end
out = nil
end
end
-- Open the output file and attach dump handlers.
local function dumpon(opt, outfile)
if active then dumpoff() end
local term = os.getenv("TERM")
local colormode = (term and term:match("color") or os.getenv("COLORTERM")) and "A" or "T"
if opt then
opt = gsub(opt, "[TAH]", function(mode) colormode = mode; return ""; end)
end
local m = { t=true, b=true, i=true, m=true, }
if opt and opt ~= "" then
local o = sub(opt, 1, 1)
if o ~= "+" and o ~= "-" then m = {} end
for i=1,#opt do m[sub(opt, i, i)] = (o ~= "-") end
end
dumpmode = m
if m.t or m.b or m.i or m.s or m.m then
jit.attach(dump_trace, "trace")
end
if m.b then
jit.attach(dump_record, "record")
if not bcline then bcline = require("jit.bc").line end
end
if m.x or m.X then
jit.attach(dump_texit, "texit")
end
if not outfile then outfile = os.getenv("LUAJIT_DUMPFILE") end
if outfile then
out = outfile == "-" and stdout or assert(io.open(outfile, "w"))
else
out = stdout
end
m[colormode] = true
if colormode == "A" then
colorize = colorize_ansi
irtype = irtype_ansi
elseif colormode == "H" then
colorize = colorize_html
irtype = irtype_html
out:write(header_html)
else
colorize = colorize_text
irtype = irtype_text
end
active = true
end
-- Public module functions.
return {
on = dumpon,
off = dumpoff,
start = dumpon -- For -j command line option.
}

View file

@ -0,0 +1,311 @@
----------------------------------------------------------------------------
-- LuaJIT profiler.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
--
-- This module is a simple command line interface to the built-in
-- low-overhead profiler of LuaJIT.
--
-- The lower-level API of the profiler is accessible via the "jit.profile"
-- module or the luaJIT_profile_* C API.
--
-- Example usage:
--
-- luajit -jp myapp.lua
-- luajit -jp=s myapp.lua
-- luajit -jp=-s myapp.lua
-- luajit -jp=vl myapp.lua
-- luajit -jp=G,profile.txt myapp.lua
--
-- The following dump features are available:
--
-- f Stack dump: function name, otherwise module:line. Default mode.
-- F Stack dump: ditto, but always prepend module.
-- l Stack dump: module:line.
-- <number> stack dump depth (callee < caller). Default: 1.
-- -<number> Inverse stack dump depth (caller > callee).
-- s Split stack dump after first stack level. Implies abs(depth) >= 2.
-- p Show full path for module names.
-- v Show VM states. Can be combined with stack dumps, e.g. vf or fv.
-- z Show zones. Can be combined with stack dumps, e.g. zf or fz.
-- r Show raw sample counts. Default: show percentages.
-- a Annotate excerpts from source code files.
-- A Annotate complete source code files.
-- G Produce raw output suitable for graphical tools (e.g. flame graphs).
-- m<number> Minimum sample percentage to be shown. Default: 3.
-- i<number> Sampling interval in milliseconds. Default: 10.
--
----------------------------------------------------------------------------
-- Cache some library functions and objects.
local jit = require("jit")
local profile = require("jit.profile")
local vmdef = require("jit.vmdef")
local math = math
local pairs, ipairs, tonumber, floor = pairs, ipairs, tonumber, math.floor
local sort, format = table.sort, string.format
local stdout = io.stdout
local zone -- Load jit.zone module on demand.
-- Output file handle.
local out
------------------------------------------------------------------------------
local prof_ud
local prof_states, prof_split, prof_min, prof_raw, prof_fmt, prof_depth
local prof_ann, prof_count1, prof_count2, prof_samples
local map_vmmode = {
N = "Compiled",
I = "Interpreted",
C = "C code",
G = "Garbage Collector",
J = "JIT Compiler",
}
-- Profiler callback.
local function prof_cb(th, samples, vmmode)
prof_samples = prof_samples + samples
local key_stack, key_stack2, key_state
-- Collect keys for sample.
if prof_states then
if prof_states == "v" then
key_state = map_vmmode[vmmode] or vmmode
else
key_state = zone:get() or "(none)"
end
end
if prof_fmt then
key_stack = profile.dumpstack(th, prof_fmt, prof_depth)
key_stack = key_stack:gsub("%[builtin#(%d+)%]", function(x)
return vmdef.ffnames[tonumber(x)]
end)
if prof_split == 2 then
local k1, k2 = key_stack:match("(.-) [<>] (.*)")
if k2 then key_stack, key_stack2 = k1, k2 end
elseif prof_split == 3 then
key_stack2 = profile.dumpstack(th, "l", 1)
end
end
-- Order keys.
local k1, k2
if prof_split == 1 then
if key_state then
k1 = key_state
if key_stack then k2 = key_stack end
end
elseif key_stack then
k1 = key_stack
if key_stack2 then k2 = key_stack2 elseif key_state then k2 = key_state end
end
-- Coalesce samples in one or two levels.
if k1 then
local t1 = prof_count1
t1[k1] = (t1[k1] or 0) + samples
if k2 then
local t2 = prof_count2
local t3 = t2[k1]
if not t3 then t3 = {}; t2[k1] = t3 end
t3[k2] = (t3[k2] or 0) + samples
end
end
end
------------------------------------------------------------------------------
-- Show top N list.
local function prof_top(count1, count2, samples, indent)
local t, n = {}, 0
for k in pairs(count1) do
n = n + 1
t[n] = k
end
sort(t, function(a, b) return count1[a] > count1[b] end)
for i=1,n do
local k = t[i]
local v = count1[k]
local pct = floor(v*100/samples + 0.5)
if pct < prof_min then break end
if not prof_raw then
out:write(format("%s%2d%% %s\n", indent, pct, k))
elseif prof_raw == "r" then
out:write(format("%s%5d %s\n", indent, v, k))
else
out:write(format("%s %d\n", k, v))
end
if count2 then
local r = count2[k]
if r then
prof_top(r, nil, v, (prof_split == 3 or prof_split == 1) and " -- " or
(prof_depth < 0 and " -> " or " <- "))
end
end
end
end
-- Annotate source code
local function prof_annotate(count1, samples)
local files = {}
local ms = 0
for k, v in pairs(count1) do
local pct = floor(v*100/samples + 0.5)
ms = math.max(ms, v)
if pct >= prof_min then
local file, line = k:match("^(.*):(%d+)$")
if not file then file = k; line = 0 end
local fl = files[file]
if not fl then fl = {}; files[file] = fl; files[#files+1] = file end
line = tonumber(line)
fl[line] = prof_raw and v or pct
end
end
sort(files)
local fmtv, fmtn = " %3d%% | %s\n", " | %s\n"
if prof_raw then
local n = math.max(5, math.ceil(math.log10(ms)))
fmtv = "%"..n.."d | %s\n"
fmtn = (" "):rep(n).." | %s\n"
end
local ann = prof_ann
for _, file in ipairs(files) do
local f0 = file:byte()
if f0 == 40 or f0 == 91 then
out:write(format("\n====== %s ======\n[Cannot annotate non-file]\n", file))
break
end
local fp, err = io.open(file)
if not fp then
out:write(format("====== ERROR: %s: %s\n", file, err))
break
end
out:write(format("\n====== %s ======\n", file))
local fl = files[file]
local n, show = 1, false
if ann ~= 0 then
for i=1,ann do
if fl[i] then show = true; out:write("@@ 1 @@\n"); break end
end
end
for line in fp:lines() do
if line:byte() == 27 then
out:write("[Cannot annotate bytecode file]\n")
break
end
local v = fl[n]
if ann ~= 0 then
local v2 = fl[n+ann]
if show then
if v2 then show = n+ann elseif v then show = n
elseif show+ann < n then show = false end
elseif v2 then
show = n+ann
out:write(format("@@ %d @@\n", n))
end
if not show then goto next end
end
if v then
out:write(format(fmtv, v, line))
else
out:write(format(fmtn, line))
end
::next::
n = n + 1
end
fp:close()
end
end
------------------------------------------------------------------------------
-- Finish profiling and dump result.
local function prof_finish()
if prof_ud then
profile.stop()
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
prof_annotate(prof_count1, samples)
else
prof_top(prof_count1, prof_count2, samples, "")
end
prof_count1 = nil
prof_count2 = nil
prof_ud = nil
if out ~= stdout then out:close() end
end
end
-- Start profiling.
local function prof_start(mode)
local interval = ""
mode = mode:gsub("i%d*", function(s) interval = s; return "" end)
prof_min = 3
mode = mode:gsub("m(%d+)", function(s) prof_min = tonumber(s); return "" end)
prof_depth = 1
mode = mode:gsub("%-?%d+", function(s) prof_depth = tonumber(s); return "" end)
local m = {}
for c in mode:gmatch(".") do m[c] = c end
prof_states = m.z or m.v
if prof_states == "z" then zone = require("jit.zone") end
local scope = m.l or m.f or m.F or (prof_states and "" or "f")
local flags = (m.p or "")
prof_raw = m.r
if m.s then
prof_split = 2
if prof_depth == -1 or m["-"] then prof_depth = -2
elseif prof_depth == 1 then prof_depth = 2 end
elseif mode:find("[fF].*l") then
scope = "l"
prof_split = 3
else
prof_split = (scope == "" or mode:find("[zv].*[lfF]")) and 1 or 0
end
prof_ann = m.A and 0 or (m.a and 3)
if prof_ann then
scope = "l"
prof_fmt = "pl"
prof_split = 0
prof_depth = 1
elseif m.G and scope ~= "" then
prof_fmt = flags..scope.."Z;"
prof_depth = -100
prof_raw = true
prof_min = 0
elseif scope == "" then
prof_fmt = false
else
local sc = prof_split == 3 and m.f or m.F or scope
prof_fmt = flags..sc..(prof_depth >= 0 and "Z < " or "Z > ")
end
prof_count1 = {}
prof_count2 = {}
prof_samples = 0
profile.start(scope:lower()..interval, prof_cb)
prof_ud = newproxy(true)
getmetatable(prof_ud).__gc = prof_finish
end
------------------------------------------------------------------------------
local function start(mode, outfile)
if not outfile then outfile = os.getenv("LUAJIT_PROFILEFILE") end
if outfile then
out = outfile == "-" and stdout or assert(io.open(outfile, "w"))
else
out = stdout
end
prof_start(mode or "f")
end
-- Public module functions.
return {
start = start, -- For -j command line option.
stop = prof_finish
}

View file

@ -0,0 +1,169 @@
----------------------------------------------------------------------------
-- Verbose mode of the LuaJIT compiler.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
--
-- This module shows verbose information about the progress of the
-- JIT compiler. It prints one line for each generated trace. This module
-- is useful to see which code has been compiled or where the compiler
-- punts and falls back to the interpreter.
--
-- Example usage:
--
-- luajit -jv -e "for i=1,1000 do for j=1,1000 do end end"
-- luajit -jv=myapp.out myapp.lua
--
-- Default output is to stderr. To redirect the output to a file, pass a
-- filename as an argument (use '-' for stdout) or set the environment
-- variable LUAJIT_VERBOSEFILE. The file is overwritten every time the
-- module is started.
--
-- The output from the first example should look like this:
--
-- [TRACE 1 (command line):1 loop]
-- [TRACE 2 (1/3) (command line):1 -> 1]
--
-- The first number in each line is the internal trace number. Next are
-- the file name ('(command line)') and the line number (':1') where the
-- trace has started. Side traces also show the parent trace number and
-- the exit number where they are attached to in parentheses ('(1/3)').
-- An arrow at the end shows where the trace links to ('-> 1'), unless
-- it loops to itself.
--
-- In this case the inner loop gets hot and is traced first, generating
-- a root trace. Then the last exit from the 1st trace gets hot, too,
-- and triggers generation of the 2nd trace. The side trace follows the
-- path along the outer loop and *around* the inner loop, back to its
-- start, and then links to the 1st trace. Yes, this may seem unusual,
-- if you know how traditional compilers work. Trace compilers are full
-- of surprises like this -- have fun! :-)
--
-- Aborted traces are shown like this:
--
-- [TRACE --- foo.lua:44 -- leaving loop in root trace at foo:lua:50]
--
-- Don't worry -- trace aborts are quite common, even in programs which
-- can be fully compiled. The compiler may retry several times until it
-- finds a suitable trace.
--
-- Of course this doesn't work with features that are not-yet-implemented
-- (NYI error messages). The VM simply falls back to the interpreter. This
-- may not matter at all if the particular trace is not very high up in
-- the CPU usage profile. Oh, and the interpreter is quite fast, too.
--
-- Also check out the -jdump module, which prints all the gory details.
--
------------------------------------------------------------------------------
-- Cache some library functions and objects.
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 stdout, stderr = io.stdout, io.stderr
-- Active flag and output file handle.
local active, out
------------------------------------------------------------------------------
local startloc, startex
local function fmtfunc(func, pc)
local fi = funcinfo(func, pc)
if fi.loc then
return fi.loc
elseif fi.ffid then
return vmdef.ffnames[fi.ffid]
elseif fi.addr then
return format("C:%x", fi.addr)
else
return "(?)"
end
end
-- Format trace error message.
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)
end
return err
end
-- Dump trace states.
local function dump_trace(what, tr, func, pc, otr, oex)
if what == "start" then
startloc = fmtfunc(func, pc)
startex = otr and "("..otr.."/"..(oex == -1 and "stitch" or oex)..") " or ""
else
if what == "abort" then
local loc = fmtfunc(func, pc)
if loc ~= startloc then
out:write(format("[TRACE --- %s%s -- %s at %s]\n",
startex, startloc, fmterr(otr, oex), loc))
else
out:write(format("[TRACE --- %s%s -- %s]\n",
startex, startloc, fmterr(otr, oex)))
end
elseif what == "stop" then
local info = traceinfo(tr)
local link, ltype = info.link, info.linktype
if ltype == "interpreter" then
out:write(format("[TRACE %3s %s%s -- fallback to interpreter]\n",
tr, startex, startloc))
elseif ltype == "stitch" then
out:write(format("[TRACE %3s %s%s %s %s]\n",
tr, startex, startloc, ltype, fmtfunc(func, pc)))
elseif link == tr or link == 0 then
out:write(format("[TRACE %3s %s%s %s]\n",
tr, startex, startloc, ltype))
elseif ltype == "root" then
out:write(format("[TRACE %3s %s%s -> %d]\n",
tr, startex, startloc, link))
else
out:write(format("[TRACE %3s %s%s -> %d %s]\n",
tr, startex, startloc, link, ltype))
end
else
out:write(format("[TRACE %s]\n", what))
end
out:flush()
end
end
------------------------------------------------------------------------------
-- Detach dump handlers.
local function dumpoff()
if active then
active = false
jit.attach(dump_trace)
if out and out ~= stdout and out ~= stderr then out:close() end
out = nil
end
end
-- Open the output file and attach dump handlers.
local function dumpon(outfile)
if active then dumpoff() end
if not outfile then outfile = os.getenv("LUAJIT_VERBOSEFILE") end
if outfile then
out = outfile == "-" and stdout or assert(io.open(outfile, "w"))
else
out = stderr
end
jit.attach(dump_trace, "trace")
active = true
end
-- Public module functions.
return {
on = dumpon,
off = dumpoff,
start = dumpon -- For -j command line option.
}

View file

@ -0,0 +1,396 @@
-- This is a generated file. DO NOT EDIT!
assert(require("jit").version == "LuaJIT 2.1.1700008891", "LuaJIT core/library version mismatch")
return {
bcnames = "ISLT ISGE ISLE ISGT ISEQV ISNEV ISEQS ISNES ISEQN ISNEN ISEQP ISNEP ISTC ISFC IST ISF ISTYPEISNUM MOV NOT UNM LEN ADDVN SUBVN MULVN DIVVN MODVN ADDNV SUBNV MULNV DIVNV MODNV ADDVV SUBVV MULVV DIVVV MODVV POW CAT KSTR KCDATAKSHORTKNUM KPRI KNIL UGET USETV USETS USETN USETP UCLO FNEW TNEW TDUP GGET GSET TGETV TGETS TGETB TGETR TSETV TSETS TSETB TSETM TSETR CALLM CALL CALLMTCALLT ITERC ITERN VARG ISNEXTRETM RET RET0 RET1 FORI JFORI FORL IFORL JFORL ITERL IITERLJITERLLOOP ILOOP JLOOP JMP FUNCF IFUNCFJFUNCFFUNCV IFUNCVJFUNCVFUNCC FUNCCW",
irnames = "LT GE LE GT ULT UGE ULE UGT EQ NE ABC RETF NOP BASE PVAL GCSTEPHIOP LOOP USE PHI RENAMEPROF KPRI KINT KGC KPTR KKPTR KNULL KNUM KINT64KSLOT BNOT BSWAP BAND BOR BXOR BSHL BSHR BSAR BROL BROR ADD SUB MUL DIV MOD POW NEG ABS LDEXP MIN MAX FPMATHADDOV SUBOV MULOV AREF HREFK HREF NEWREFUREFO UREFC FREF TMPREFSTRREFLREF ALOAD HLOAD ULOAD FLOAD XLOAD SLOAD VLOAD ALEN ASTOREHSTOREUSTOREFSTOREXSTORESNEW XSNEW TNEW TDUP CNEW CNEWI BUFHDRBUFPUTBUFSTRTBAR OBAR XBAR CONV TOBIT TOSTR STRTO CALLN CALLA CALLL CALLS CALLXSCARG ",
irfpm = { [0]="floor", "ceil", "trunc", "sqrt", "log", "log2", "other", },
irfield = { [0]="str.len", "func.env", "func.pc", "func.ffid", "thread.env", "tab.meta", "tab.array", "tab.node", "tab.asize", "tab.hmask", "tab.nomm", "udata.meta", "udata.udtype", "udata.file", "sbuf.w", "sbuf.e", "sbuf.b", "sbuf.l", "sbuf.ref", "sbuf.r", "cdata.ctypeid", "cdata.ptr", "cdata.int", "cdata.int64", "cdata.int64_4", },
ircall = {
[0]="lj_str_cmp",
"lj_str_find",
"lj_str_new",
"lj_strscan_num",
"lj_strfmt_int",
"lj_strfmt_num",
"lj_strfmt_char",
"lj_strfmt_putint",
"lj_strfmt_putnum",
"lj_strfmt_putquoted",
"lj_strfmt_putfxint",
"lj_strfmt_putfnum_int",
"lj_strfmt_putfnum_uint",
"lj_strfmt_putfnum",
"lj_strfmt_putfstr",
"lj_strfmt_putfchar",
"lj_buf_putmem",
"lj_buf_putstr",
"lj_buf_putchar",
"lj_buf_putstr_reverse",
"lj_buf_putstr_lower",
"lj_buf_putstr_upper",
"lj_buf_putstr_rep",
"lj_buf_puttab",
"lj_bufx_set",
"lj_bufx_more",
"lj_serialize_put",
"lj_serialize_get",
"lj_serialize_encode",
"lj_serialize_decode",
"lj_buf_tostr",
"lj_tab_new_ah",
"lj_tab_new1",
"lj_tab_dup",
"lj_tab_clear",
"lj_tab_newkey",
"lj_tab_keyindex",
"lj_vm_next",
"lj_tab_len",
"lj_tab_len_hint",
"lj_gc_step_jit",
"lj_gc_barrieruv",
"lj_mem_newgco",
"lj_prng_u64d",
"lj_vm_modi",
"log10",
"exp",
"sin",
"cos",
"tan",
"asin",
"acos",
"atan",
"sinh",
"cosh",
"tanh",
"fputc",
"fwrite",
"fflush",
"lj_vm_floor",
"lj_vm_ceil",
"lj_vm_trunc",
"sqrt",
"log",
"lj_vm_log2",
"pow",
"atan2",
"ldexp",
"lj_vm_tobit",
"softfp_add",
"softfp_sub",
"softfp_mul",
"softfp_div",
"softfp_cmp",
"softfp_i2d",
"softfp_d2i",
"lj_vm_sfmin",
"lj_vm_sfmax",
"lj_vm_tointg",
"softfp_ui2d",
"softfp_f2d",
"softfp_d2ui",
"softfp_d2f",
"softfp_i2f",
"softfp_ui2f",
"softfp_f2i",
"softfp_f2ui",
"fp64_l2d",
"fp64_ul2d",
"fp64_l2f",
"fp64_ul2f",
"fp64_d2l",
"fp64_d2ul",
"fp64_f2l",
"fp64_f2ul",
"lj_carith_divi64",
"lj_carith_divu64",
"lj_carith_modi64",
"lj_carith_modu64",
"lj_carith_powi64",
"lj_carith_powu64",
"lj_cdata_newv",
"lj_cdata_setfin",
"strlen",
"memcpy",
"memset",
"lj_vm_errno",
"lj_carith_mul64",
"lj_carith_shl64",
"lj_carith_shr64",
"lj_carith_sar64",
"lj_carith_rol64",
"lj_carith_ror64",
},
traceerr = {
[0]="error thrown or hook called during recording",
"trace too short",
"trace too long",
"trace too deep",
"too many snapshots",
"blacklisted",
"retry recording",
"NYI: bytecode %d",
"leaving loop in root trace",
"inner loop in root trace",
"loop unroll limit reached",
"bad argument type",
"JIT compilation disabled for function",
"call unroll limit reached",
"down-recursion, restarting",
"NYI: unsupported variant of FastFunc %s",
"NYI: return to lower frame",
"store with nil or NaN key",
"missing metamethod",
"looping index lookup",
"NYI: mixed sparse/dense table",
"symbol not in cache",
"NYI: unsupported C type conversion",
"NYI: unsupported C function type",
"guard would always fail",
"too many PHIs",
"persistent type instability",
"failed to allocate mcode memory",
"machine code too long",
"hit mcode limit (retrying)",
"too many spill slots",
"inconsistent register allocation",
"NYI: cannot assemble IR instruction %d",
"NYI: PHI shuffling too complex",
"NYI: register coalescing too complex",
},
ffnames = {
[0]="Lua",
"C",
"assert",
"type",
"next",
"pairs",
"ipairs_aux",
"ipairs",
"getmetatable",
"setmetatable",
"getfenv",
"setfenv",
"rawget",
"rawset",
"rawequal",
"unpack",
"select",
"tonumber",
"tostring",
"error",
"pcall",
"xpcall",
"loadfile",
"load",
"loadstring",
"dofile",
"gcinfo",
"collectgarbage",
"newproxy",
"print",
"coroutine.status",
"coroutine.running",
"coroutine.isyieldable",
"coroutine.create",
"coroutine.yield",
"coroutine.resume",
"coroutine.wrap_aux",
"coroutine.wrap",
"math.abs",
"math.floor",
"math.ceil",
"math.sqrt",
"math.log10",
"math.exp",
"math.sin",
"math.cos",
"math.tan",
"math.asin",
"math.acos",
"math.atan",
"math.sinh",
"math.cosh",
"math.tanh",
"math.frexp",
"math.modf",
"math.log",
"math.atan2",
"math.pow",
"math.fmod",
"math.ldexp",
"math.min",
"math.max",
"math.random",
"math.randomseed",
"bit.tobit",
"bit.bnot",
"bit.bswap",
"bit.lshift",
"bit.rshift",
"bit.arshift",
"bit.rol",
"bit.ror",
"bit.band",
"bit.bor",
"bit.bxor",
"bit.tohex",
"string.byte",
"string.char",
"string.sub",
"string.rep",
"string.reverse",
"string.lower",
"string.upper",
"string.dump",
"string.find",
"string.match",
"string.gmatch_aux",
"string.gmatch",
"string.gsub",
"string.format",
"table.maxn",
"table.insert",
"table.concat",
"table.sort",
"table.new",
"table.clear",
"io.method.close",
"io.method.read",
"io.method.write",
"io.method.flush",
"io.method.seek",
"io.method.setvbuf",
"io.method.lines",
"io.method.__gc",
"io.method.__tostring",
"io.open",
"io.popen",
"io.tmpfile",
"io.close",
"io.read",
"io.write",
"io.flush",
"io.input",
"io.output",
"io.lines",
"io.type",
"os.execute",
"os.remove",
"os.rename",
"os.tmpname",
"os.getenv",
"os.exit",
"os.clock",
"os.date",
"os.time",
"os.difftime",
"os.setlocale",
"debug.getregistry",
"debug.getmetatable",
"debug.setmetatable",
"debug.getfenv",
"debug.setfenv",
"debug.getinfo",
"debug.getlocal",
"debug.setlocal",
"debug.getupvalue",
"debug.setupvalue",
"debug.upvalueid",
"debug.upvaluejoin",
"debug.sethook",
"debug.gethook",
"debug.debug",
"debug.traceback",
"jit.on",
"jit.off",
"jit.flush",
"jit.status",
"jit.security",
"jit.attach",
"jit.util.funcinfo",
"jit.util.funcbc",
"jit.util.funck",
"jit.util.funcuvname",
"jit.util.traceinfo",
"jit.util.traceir",
"jit.util.tracek",
"jit.util.tracesnap",
"jit.util.tracemc",
"jit.util.traceexitstub",
"jit.util.ircalladdr",
"jit.opt.start",
"jit.profile.start",
"jit.profile.stop",
"jit.profile.dumpstack",
"ffi.meta.__index",
"ffi.meta.__newindex",
"ffi.meta.__eq",
"ffi.meta.__len",
"ffi.meta.__lt",
"ffi.meta.__le",
"ffi.meta.__concat",
"ffi.meta.__call",
"ffi.meta.__add",
"ffi.meta.__sub",
"ffi.meta.__mul",
"ffi.meta.__div",
"ffi.meta.__mod",
"ffi.meta.__pow",
"ffi.meta.__unm",
"ffi.meta.__tostring",
"ffi.meta.__pairs",
"ffi.meta.__ipairs",
"ffi.clib.__index",
"ffi.clib.__newindex",
"ffi.clib.__gc",
"ffi.callback.free",
"ffi.callback.set",
"ffi.cdef",
"ffi.new",
"ffi.cast",
"ffi.typeof",
"ffi.typeinfo",
"ffi.istype",
"ffi.sizeof",
"ffi.alignof",
"ffi.offsetof",
"ffi.errno",
"ffi.string",
"ffi.copy",
"ffi.fill",
"ffi.abi",
"ffi.metatype",
"ffi.gc",
"ffi.load",
"buffer.method.free",
"buffer.method.reset",
"buffer.method.skip",
"buffer.method.set",
"buffer.method.put",
"buffer.method.putf",
"buffer.method.get",
"buffer.method.putcdata",
"buffer.method.reserve",
"buffer.method.commit",
"buffer.method.ref",
"buffer.method.encode",
"buffer.method.decode",
"buffer.method.__gc",
"buffer.method.__tostring",
"buffer.method.__len",
"buffer.new",
"buffer.encode",
"buffer.decode",
},
}

View file

@ -0,0 +1,45 @@
----------------------------------------------------------------------------
-- LuaJIT profiler zones.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
--
-- This module implements a simple hierarchical zone model.
--
-- Example usage:
--
-- local zone = require("jit.zone")
-- zone("AI")
-- ...
-- zone("A*")
-- ...
-- print(zone:get()) --> "A*"
-- ...
-- zone()
-- ...
-- print(zone:get()) --> "AI"
-- ...
-- zone()
--
----------------------------------------------------------------------------
local remove = table.remove
return setmetatable({
flush = function(t)
for i=#t,1,-1 do t[i] = nil end
end,
get = function(t)
return t[#t]
end
}, {
__call = function(t, zone)
if zone then
t[#t+1] = zone
else
return (assert(remove(t), "empty zone stack"))
end
end
})

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
<mime-type type="application/x-love-game">
<comment>LÖVE game</comment>
<glob pattern="*.love"/>
</mime-type>
</mime-info>

View file

@ -0,0 +1,962 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="141.73px" height="141.73px" viewBox="0 0 141.73 141.73" enable-background="new 0 0 141.73 141.73" xml:space="preserve">
<g>
<g opacity="0.3">
<path d="M117.726,21.413c-0.016-0.017-0.035-0.027-0.053-0.042C96.307,3.014,66.118-0.243,41.136,12.523
C16.168,25.282,1.956,53.733,5.382,81.306c2.392,19.268,13.129,36.165,28.466,47.021c0,0,42.277-37.776,53.504-51.181
c10.53-12.582,33.52-52.764,33.52-52.764C119.861,23.365,118.814,22.374,117.726,21.413z"/>
</g>
<g>
<path fill="#E74A99" d="M115.726,18.413c-0.016-0.017-0.035-0.027-0.053-0.042C94.307,0.014,64.118-3.243,39.136,9.523
C14.168,22.282-0.044,50.733,3.382,78.306c2.392,19.268,13.129,36.165,28.466,47.021c0,0,42.277-37.776,53.504-51.181
c10.53-12.582,33.52-52.764,33.52-52.764C117.861,20.365,116.814,19.374,115.726,18.413z"/>
</g>
</g>
<g>
<g opacity="0.3">
<path d="M33.849,128.327c7.067,5.001,15.11,8.726,23.765,10.801c27.076,6.487,56.27-5.293,71.759-28.261
c18.256-27.077,14.241-63.649-8.5-86.485c0,0-32.464,38.778-43.287,51.706C66.65,89.146,33.849,128.327,33.849,128.327z"/>
</g>
<g>
<path fill="#27AAE1" d="M31.849,125.327c7.067,5.001,15.11,8.726,23.765,10.801c27.076,6.487,56.27-5.293,71.759-28.261
c18.256-27.077,14.241-63.649-8.5-86.485c0,0-32.464,38.778-43.287,51.706C64.65,86.146,31.849,125.327,31.849,125.327z"/>
</g>
</g>
<g>
<image overflow="visible" opacity="0.3" width="354" height="324" xlink:href="data:image/png;base64,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
rkJggg==" transform="matrix(0.24 0 0 0.24 28.4971 38.3643)">
</image>
<g>
<path fill="#FFFFFF" d="M73.043,52.8c0,0-6.48-14.187-19.968-10.958c-13.486,3.23-41.652,30.792,17.853,65.083H70.88
c59.504-34.291,31.34-61.852,17.853-65.083C75.245,38.613,68.766,52.8,68.766,52.8H73.043z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 72 KiB

View file

@ -0,0 +1 @@
appimagetool.svg

View file

@ -0,0 +1,11 @@
#!/bin/sh
HERE="$(dirname "$(readlink -f "${0}")")"
export PATH="${HERE}"/usr/bin/:"${HERE}"/usr/sbin/:"${HERE}"/usr/games/:"${HERE}"/bin/:"${HERE}"/sbin/:"${PATH}"
export LD_LIBRARY_PATH="${HERE}"/usr/lib/:"${HERE}"/usr/lib/i386-linux-gnu/:"${HERE}"/usr/lib/x86_64-linux-gnu/:"${HERE}"/usr/lib32/:"${HERE}"/usr/lib64/:"${HERE}"/lib/:"${HERE}"/lib/i386-linux-gnu/:"${HERE}"/lib/x86_64-linux-gnu/:"${HERE}"/lib32/:"${HERE}"/lib64/:"${LD_LIBRARY_PATH}"
export PYTHONPATH="${HERE}"/usr/share/pyshared/:"${PYTHONPATH}"
export XDG_DATA_DIRS="${HERE}"/usr/share/:"${XDG_DATA_DIRS}"
export PERLLIB="${HERE}"/usr/share/perl5/:"${HERE}"/usr/lib/perl5/:"${PERLLIB}"
export GSETTINGS_SCHEMA_DIR="${HERE}"/usr/share/glib-2.0/schemas/:"${GSETTINGS_SCHEMA_DIR}"
export QT_PLUGIN_PATH="${HERE}"/usr/lib/qt4/plugins/:"${HERE}"/usr/lib/i386-linux-gnu/qt4/plugins/:"${HERE}"/usr/lib/x86_64-linux-gnu/qt4/plugins/:"${HERE}"/usr/lib32/qt4/plugins/:"${HERE}"/usr/lib64/qt4/plugins/:"${HERE}"/usr/lib/qt5/plugins/:"${HERE}"/usr/lib/i386-linux-gnu/qt5/plugins/:"${HERE}"/usr/lib/x86_64-linux-gnu/qt5/plugins/:"${HERE}"/usr/lib32/qt5/plugins/:"${HERE}"/usr/lib64/qt5/plugins/:"${QT_PLUGIN_PATH}"
EXEC=$(grep -e '^Exec=.*' "${HERE}"/*.desktop | head -n 1 | cut -d "=" -f 2 | cut -d " " -f 1)
exec "${EXEC}" $@

View file

@ -0,0 +1,9 @@
[Desktop Entry]
Type=Application
Name=appimagetool
Exec=appimagetool
Comment=Tool to generate AppImages from AppDirs
Icon=appimagetool
Categories=Development;
Terminal=true

View file

@ -0,0 +1,320 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="48px"
height="48px"
id="svg3832"
version="1.1"
inkscape:version="0.47 r22583"
sodipodi:docname="appimage-assistant_alt3.svg">
<defs
id="defs3834">
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3308-4-6-931-761-0"
id="linearGradient2975"
gradientUnits="userSpaceOnUse"
x1="24.3125"
y1="22.96875"
x2="24.3125"
y2="41.03125" />
<linearGradient
id="linearGradient3308-4-6-931-761-0">
<stop
id="stop2919-2"
style="stop-color:#ffffff;stop-opacity:1"
offset="0" />
<stop
id="stop2921-76"
style="stop-color:#ffffff;stop-opacity:0"
offset="1" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4222"
id="linearGradient2979"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0,0.3704967,-0.3617496,0,33.508315,6.1670925)"
x1="7.6485429"
y1="26.437023"
x2="41.861729"
y2="26.437023" />
<linearGradient
id="linearGradient4222">
<stop
id="stop4224"
style="stop-color:#ffffff;stop-opacity:1"
offset="0" />
<stop
id="stop4226"
style="stop-color:#ffffff;stop-opacity:0"
offset="1" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3308-4-6-931-761"
id="linearGradient2982"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(0,0.9999987)"
x1="23.99999"
y1="4.999989"
x2="23.99999"
y2="43" />
<linearGradient
id="linearGradient3308-4-6-931-761">
<stop
id="stop2919"
style="stop-color:#ffffff;stop-opacity:1"
offset="0" />
<stop
id="stop2921"
style="stop-color:#ffffff;stop-opacity:0"
offset="1" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3575"
id="radialGradient2985"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0,1.0262008,-1.6561124,9.4072203e-4,-56.097482,-45.332325)"
cx="48.42384"
cy="-48.027504"
fx="48.42384"
fy="-48.027504"
r="38.212933" />
<linearGradient
id="linearGradient3575">
<stop
id="stop3577"
style="stop-color:#fafafa;stop-opacity:1"
offset="0" />
<stop
id="stop3579"
style="stop-color:#e6e6e6;stop-opacity:1"
offset="1" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3993"
id="radialGradient2990"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0,2.0478765,-2.7410544,-8.6412258e-8,47.161382,-8.837436)"
cx="9.3330879"
cy="8.4497671"
fx="9.3330879"
fy="8.4497671"
r="19.99999" />
<linearGradient
id="linearGradient3993">
<stop
offset="0"
style="stop-color:#a3c0d0;stop-opacity:1"
id="stop3995" />
<stop
offset="1"
style="stop-color:#427da1;stop-opacity:1"
id="stop4001" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2508"
id="linearGradient2992"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(0,0.9674382)"
x1="14.048676"
y1="44.137306"
x2="14.048676"
y2="4.0000005" />
<linearGradient
id="linearGradient2508">
<stop
offset="0"
style="stop-color:#2e4a5a;stop-opacity:1"
id="stop2510" />
<stop
offset="1"
style="stop-color:#6e8796;stop-opacity:1"
id="stop2512" />
</linearGradient>
<radialGradient
cx="4.9929786"
cy="43.5"
r="2.5"
fx="4.9929786"
fy="43.5"
id="radialGradient2873-966-168"
xlink:href="#linearGradient3688-166-749"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.003784,0,0,1.4,27.98813,-17.4)" />
<linearGradient
id="linearGradient3688-166-749">
<stop
id="stop2883"
style="stop-color:#181818;stop-opacity:1"
offset="0" />
<stop
id="stop2885"
style="stop-color:#181818;stop-opacity:0"
offset="1" />
</linearGradient>
<radialGradient
cx="4.9929786"
cy="43.5"
r="2.5"
fx="4.9929786"
fy="43.5"
id="radialGradient2875-742-326"
xlink:href="#linearGradient3688-464-309"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.003784,0,0,1.4,-20.01187,-104.4)" />
<linearGradient
id="linearGradient3688-464-309">
<stop
id="stop2889"
style="stop-color:#181818;stop-opacity:1"
offset="0" />
<stop
id="stop2891"
style="stop-color:#181818;stop-opacity:0"
offset="1" />
</linearGradient>
<linearGradient
x1="25.058096"
y1="47.027729"
x2="25.058096"
y2="39.999443"
id="linearGradient2877-634-617"
xlink:href="#linearGradient3702-501-757"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient3702-501-757">
<stop
id="stop2895"
style="stop-color:#181818;stop-opacity:0"
offset="0" />
<stop
id="stop2897"
style="stop-color:#181818;stop-opacity:1"
offset="0.5" />
<stop
id="stop2899"
style="stop-color:#181818;stop-opacity:0"
offset="1" />
</linearGradient>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="7"
inkscape:cx="24"
inkscape:cy="24"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="603"
inkscape:window-height="484"
inkscape:window-x="417"
inkscape:window-y="162"
inkscape:window-maximized="0" />
<metadata
id="metadata3837">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<g
style="display:inline"
id="g2036"
transform="matrix(1.1,0,0,0.4444449,-2.4000022,25.11107)">
<g
style="opacity:0.4"
id="g3712"
transform="matrix(1.052632,0,0,1.285713,-1.263158,-13.42854)">
<rect
style="fill:url(#radialGradient2873-966-168);fill-opacity:1;stroke:none"
id="rect2801"
y="40"
x="38"
height="7"
width="5" />
<rect
style="fill:url(#radialGradient2875-742-326);fill-opacity:1;stroke:none"
id="rect3696"
transform="scale(-1,-1)"
y="-47"
x="-10"
height="7"
width="5" />
<rect
style="fill:url(#linearGradient2877-634-617);fill-opacity:1;stroke:none"
id="rect3700"
y="40"
x="10"
height="7.0000005"
width="28" />
</g>
</g>
<rect
style="fill:url(#radialGradient2990);fill-opacity:1;stroke:url(#linearGradient2992);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="rect5505"
y="5.4674392"
x="4.5"
ry="2.2322156"
rx="2.2322156"
height="39"
width="39" />
<path
style="opacity:0.05;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00178742;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path4294-1"
d="m 21,6.9687498 a 2.0165107,2.0165107 0 0 0 -2.03125,2.03125 l 0,3.9687502 -1.15625,0 a 2.0165107,2.0165107 0 0 0 -1.5,3.375 l 5.0625,5.75 c -0.06312,0.110777 -0.178724,0.246032 -0.21875,0.34375 -0.195898,0.478256 -0.25,0.83653 -0.25,1.21875 l 0,0.125 L 20.8125,23.6875 C 20.534322,23.409323 20.213169,23.162739 19.71875,22.96875 19.47154,22.87176 19.185456,22.791748 18.75,22.8125 c -0.435456,0.02075 -1.054055,0.210302 -1.46875,0.625 L 15.75,24.96875 c -0.414689,0.414689 -0.604245,1.033294 -0.625,1.46875 -0.02075,0.435456 0.05925,0.721537 0.15625,0.96875 C 15.475241,27.900677 15.721817,28.221821 16,28.5 l 0.09375,0.09375 -0.125,0 c -0.382218,0 -0.740493,0.0541 -1.21875,0.25 -0.239128,0.09795 -0.538285,0.214988 -0.84375,0.53125 -0.305465,0.316262 -0.625,0.914788 -0.625,1.53125 l 0,2.1875 c 0,0.616465 0.319536,1.214989 0.625,1.53125 0.305464,0.316261 0.604622,0.433301 0.84375,0.53125 0.478256,0.195898 0.83653,0.25 1.21875,0.25 l 0.125,0 L 16,35.5 c -0.278175,0.278176 -0.52476,0.599329 -0.71875,1.09375 -0.09699,0.24721 -0.177003,0.533292 -0.15625,0.96875 0.02075,0.435458 0.210304,1.054058 0.625,1.46875 l 1.53125,1.53125 c 0.414691,0.414697 1.033292,0.604245 1.46875,0.625 0.435458,0.02076 0.721537,-0.05926 0.96875,-0.15625 0.494425,-0.19399 0.81557,-0.440568 1.09375,-0.71875 l 0.09375,-0.09375 0,0.125 c 0,0.38222 0.0541,0.740495 0.25,1.21875 0.09795,0.239127 0.214989,0.538285 0.53125,0.84375 0.316261,0.305465 0.914783,0.625 1.53125,0.625 l 2.1875,0 c 0.616466,0 1.214989,-0.319534 1.53125,-0.625 0.316261,-0.305466 0.433302,-0.604622 0.53125,-0.84375 0.195896,-0.478255 0.25,-0.836532 0.25,-1.21875 l 0,-0.125 0.09375,0.09375 c 0.278176,0.278175 0.599329,0.52476 1.09375,0.71875 0.24721,0.09699 0.533292,0.177003 0.96875,0.15625 0.435458,-0.02075 1.054058,-0.210304 1.46875,-0.625 L 32.875,39.03125 C 33.289697,38.616559 33.479245,37.997958 33.5,37.5625 33.52076,37.127042 33.44074,36.840963 33.34375,36.59375 33.14976,36.099325 32.903182,35.77818 32.625,35.5 l -0.09375,-0.09375 0.125,0 c 0.38222,0 0.740494,-0.0541 1.21875,-0.25 0.239128,-0.09795 0.538286,-0.214988 0.84375,-0.53125 0.305464,-0.316262 0.625,-0.914787 0.625,-1.53125 l 0,-2.1875 c 0,-0.61646 -0.319535,-1.214987 -0.625,-1.53125 -0.305465,-0.316263 -0.604621,-0.433301 -0.84375,-0.53125 -0.478257,-0.195898 -0.836532,-0.25 -1.21875,-0.25 l -0.125,0 L 32.625,28.5 c 0.278177,-0.278177 0.52476,-0.599329 0.71875,-1.09375 C 33.44074,27.15904 33.520753,26.872957 33.5,26.4375 33.47925,26.002043 33.289697,25.383443 32.875,24.96875 L 31.34375,23.4375 c -0.414688,-0.414694 -1.03329,-0.604245 -1.46875,-0.625 -0.43546,-0.02076 -0.721537,0.05925 -0.96875,0.15625 -0.494426,0.193991 -0.815572,0.44057 -1.09375,0.71875 l -0.09375,0.09375 0,-0.125 c 0,-0.382218 -0.0541,-0.740493 -0.25,-1.21875 -0.09112,-0.22245 -0.228127,-0.500183 -0.5,-0.78125 l 4.71875,-5.3125 a 2.0165107,2.0165107 0 0 0 -1.5,-3.375 l -1.15625,0 0,-3.9687502 A 2.0165107,2.0165107 0 0 0 27,6.9687498 l -6,0 z M 24.3125,31.25 c 0.427097,0 0.75,0.322904 0.75,0.75 0,0.427096 -0.322903,0.75 -0.75,0.75 -0.427094,0 -0.75,-0.322906 -0.75,-0.75 0,-0.427094 0.322906,-0.75 0.75,-0.75 z" />
<path
style="opacity:0.05;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00178742;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path4294"
d="m 20.90625,8.0312498 a 0.96385067,0.96385067 0 0 0 -0.875,0.96875 l 0,5.0312502 -2.21875,0 A 0.96385067,0.96385067 0 0 0 17.09375,15.625 l 5.78125,6.53125 c -0.158814,0.0616 -0.341836,0.0951 -0.4375,0.1875 -0.169161,0.163386 -0.252971,0.323419 -0.3125,0.46875 -0.119058,0.290663 -0.15625,0.566746 -0.15625,0.84375 l 0,1.65625 C 21.718163,25.40233 21.485871,25.509772 21.25,25.625 l -1.1875,-1.1875 c -0.199651,-0.19965 -0.421433,-0.352095 -0.71875,-0.46875 -0.148659,-0.05833 -0.329673,-0.104846 -0.5625,-0.09375 -0.232827,0.0111 -0.53583,0.09833 -0.75,0.3125 L 16.5,25.71875 c -0.214168,0.214168 -0.301403,0.517173 -0.3125,0.75 -0.0111,0.232827 0.03542,0.41384 0.09375,0.5625 0.116655,0.297321 0.269096,0.519099 0.46875,0.71875 l 1.1875,1.1875 c -0.115228,0.235871 -0.222668,0.468163 -0.3125,0.71875 l -1.65625,0 c -0.277003,0 -0.553087,0.03719 -0.84375,0.15625 -0.145332,0.05953 -0.305363,0.143338 -0.46875,0.3125 -0.163387,0.169162 -0.3125,0.46403 -0.3125,0.78125 l 0,2.1875 c 0,0.317221 0.149114,0.612089 0.3125,0.78125 0.163386,0.169161 0.323419,0.252971 0.46875,0.3125 0.290663,0.119058 0.566746,0.15625 0.84375,0.15625 l 1.65625,0 c 0.08983,0.250587 0.197272,0.482879 0.3125,0.71875 L 16.75,36.25 c -0.199649,0.19965 -0.352095,0.421432 -0.46875,0.71875 -0.05833,0.148659 -0.104846,0.329672 -0.09375,0.5625 0.0111,0.232828 0.09833,0.535831 0.3125,0.75 l 1.53125,1.53125 c 0.214168,0.214172 0.517172,0.301403 0.75,0.3125 0.232828,0.0111 0.41384,-0.03542 0.5625,-0.09375 0.29732,-0.116655 0.519098,-0.269096 0.71875,-0.46875 L 21.25,38.375 c 0.235871,0.115228 0.468164,0.222668 0.71875,0.3125 l 0,1.65625 c 0,0.277003 0.03719,0.553087 0.15625,0.84375 0.05953,0.145331 0.143339,0.305364 0.3125,0.46875 0.169161,0.163386 0.464028,0.3125 0.78125,0.3125 l 2.1875,0 c 0.317221,0 0.612089,-0.149113 0.78125,-0.3125 0.169161,-0.163387 0.252971,-0.323419 0.3125,-0.46875 0.119057,-0.290663 0.15625,-0.566748 0.15625,-0.84375 l 0,-1.65625 c 0.250586,-0.08983 0.482879,-0.197272 0.71875,-0.3125 l 1.1875,1.1875 c 0.19965,0.199649 0.421432,0.352095 0.71875,0.46875 0.148659,0.05833 0.329672,0.104846 0.5625,0.09375 0.232828,-0.0111 0.535831,-0.09833 0.75,-0.3125 L 32.125,38.28125 c 0.214172,-0.214168 0.301403,-0.517172 0.3125,-0.75 0.0111,-0.232828 -0.03542,-0.41384 -0.09375,-0.5625 C 32.227095,36.67143 32.074654,36.449652 31.875,36.25 L 30.6875,35.0625 C 30.802728,34.82663 30.910168,34.594337 31,34.34375 l 1.65625,0 c 0.277004,0 0.553087,-0.03719 0.84375,-0.15625 0.145332,-0.05953 0.305364,-0.143339 0.46875,-0.3125 0.163386,-0.169161 0.3125,-0.46403 0.3125,-0.78125 l 0,-2.1875 c 0,-0.317219 -0.149114,-0.612088 -0.3125,-0.78125 C 33.805364,29.955838 33.645332,29.872029 33.5,29.8125 33.209336,29.693442 32.933253,29.65625 32.65625,29.65625 l -1.65625,0 C 30.91017,29.405663 30.802728,29.17337 30.6875,28.9375 L 31.875,27.75 c 0.19965,-0.19965 0.352095,-0.421432 0.46875,-0.71875 0.05833,-0.148659 0.104846,-0.329672 0.09375,-0.5625 -0.0111,-0.232828 -0.09833,-0.535831 -0.3125,-0.75 L 30.59375,24.1875 c -0.214167,-0.21417 -0.517171,-0.301403 -0.75,-0.3125 -0.232829,-0.0111 -0.41384,0.03542 -0.5625,0.09375 -0.29732,0.116656 -0.519099,0.269097 -0.71875,0.46875 L 27.375,25.625 c -0.235871,-0.115228 -0.468163,-0.222668 -0.71875,-0.3125 l 0,-1.65625 c 0,-0.277003 -0.03719,-0.553087 -0.15625,-0.84375 -0.05953,-0.145332 -0.143338,-0.305363 -0.3125,-0.46875 -0.169162,-0.163387 -0.46403,-0.3125 -0.78125,-0.3125 l -0.15625,0 5.65625,-6.40625 A 0.96385067,0.96385067 0 0 0 30.1875,14.03125 l -2.21875,0 0,-5.0312502 A 0.96385067,0.96385067 0 0 0 27,8.0312498 l -6,0 a 0.96385067,0.96385067 0 0 0 -0.09375,0 z M 24.3125,30.1875 c 1.002113,0 1.8125,0.810388 1.8125,1.8125 0,1.002112 -0.810387,1.8125 -1.8125,1.8125 C 23.31039,33.8125 22.5,33.002111 22.5,32 c 0,-1.002111 0.81039,-1.8125 1.8125,-1.8125 z" />
<path
style="fill:url(#radialGradient2985);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00178742;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path2317"
d="M 21,8.9999996 21,15 17.8125,15 24,22 30.1875,15 27,15 l 0,-6.0000004 -6,0 z M 23.21875,23 c -0.172892,0 -0.28125,0.294922 -0.28125,0.65625 l 0,2.28125 C 22.24145,26.095996 21.585954,26.379869 21,26.75 l -1.625,-1.625 c -0.255498,-0.255497 -0.533998,-0.372253 -0.65625,-0.25 l -1.53125,1.53125 c -0.122254,0.122254 -0.0055,0.400753 0.25,0.65625 l 1.625,1.625 c -0.37013,0.585953 -0.654003,1.24145 -0.8125,1.9375 l -2.28125,0 c -0.361328,0 -0.65625,0.108357 -0.65625,0.28125 l 0,2.1875 c 0,0.172892 0.294922,0.28125 0.65625,0.28125 l 2.28125,0 c 0.158497,0.69605 0.44237,1.351546 0.8125,1.9375 l -1.625,1.625 c -0.255497,0.255498 -0.372254,0.533997 -0.25,0.65625 l 1.53125,1.53125 c 0.122252,0.122254 0.400752,0.0055 0.65625,-0.25 L 21,37.25 c 0.585954,0.37013 1.24145,0.654002 1.9375,0.8125 l 0,2.28125 C 22.9375,40.705077 23.045858,41 23.21875,41 l 2.1875,0 c 0.172893,0 0.28125,-0.294924 0.28125,-0.65625 l 0,-2.28125 c 0.69605,-0.158498 1.351546,-0.44237 1.9375,-0.8125 l 1.625,1.625 c 0.255498,0.255497 0.533997,0.372254 0.65625,0.25 l 1.53125,-1.53125 c 0.122254,-0.122252 0.0055,-0.400752 -0.25,-0.65625 l -1.625,-1.625 c 0.370129,-0.585954 0.654003,-1.24145 0.8125,-1.9375 l 2.28125,0 c 0.361329,0 0.65625,-0.108358 0.65625,-0.28125 l 0,-2.1875 c 0,-0.172893 -0.294921,-0.28125 -0.65625,-0.28125 l -2.28125,0 c -0.158497,-0.69605 -0.442371,-1.351547 -0.8125,-1.9375 l 1.625,-1.625 c 0.255497,-0.255497 0.372254,-0.533997 0.25,-0.65625 L 29.90625,24.875 C 29.783997,24.752745 29.505498,24.8695 29.25,25.125 l -1.625,1.625 c -0.585954,-0.370131 -1.24145,-0.654004 -1.9375,-0.8125 l 0,-2.28125 C 25.6875,23.294922 25.579143,23 25.40625,23 l -2.1875,0 z m 1.09375,6.21875 c 1.528616,0 2.78125,1.252635 2.78125,2.78125 0,1.528615 -1.252634,2.78125 -2.78125,2.78125 -1.528614,0 -2.78125,-1.252635 -2.78125,-2.78125 0,-1.528615 1.252636,-2.78125 2.78125,-2.78125 z" />
<rect
style="opacity:0.4;fill:none;stroke:url(#linearGradient2982);stroke-width:0.99999976;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="rect6741"
y="6.4999886"
x="5.4999981"
ry="1.365193"
rx="1.365193"
height="37.000011"
width="36.999985" />
<path
style="fill:none;stroke:url(#linearGradient2979);stroke-width:0.99829447;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
id="path2777"
d="M 28.926376,15.466668 24,21.177578 18.963089,15.5 21.5,15.5 l 0,-6.0000004 5,0 0,6.0000004 2.426376,-0.03333 z" />
<path
style="fill:none;stroke:url(#linearGradient2975);stroke-width:1;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path4243"
d="m 23.4375,23.46875 c -0.01166,0.05381 -0.03125,0.100205 -0.03125,0.1875 l 0,2.28125 a 0.48185467,0.48185467 0 0 1 -0.375,0.46875 c -0.638467,0.145384 -1.238423,0.407111 -1.78125,0.75 a 0.48185467,0.48185467 0 0 1 -0.59375,-0.0625 l -1.625,-1.625 C 18.9779,25.4154 18.9477,25.40242 18.90625,25.375 l -1.21875,1.21875 c 0.02742,0.04145 0.0404,0.07165 0.09375,0.125 l 1.625,1.625 a 0.48185467,0.48185467 0 0 1 0.0625,0.59375 c -0.342888,0.542826 -0.604615,1.142782 -0.75,1.78125 a 0.48185467,0.48185467 0 0 1 -0.46875,0.375 l -2.28125,0 c -0.08729,0 -0.133695,0.01959 -0.1875,0.03125 l 0,1.75 c 0.05381,0.01166 0.100205,0.03125 0.1875,0.03125 l 2.28125,0 a 0.48185467,0.48185467 0 0 1 0.46875,0.375 c 0.145385,0.638468 0.407112,1.238423 0.75,1.78125 a 0.48185467,0.48185467 0 0 1 -0.0625,0.59375 l -1.625,1.625 c -0.05335,0.05335 -0.06633,0.08355 -0.09375,0.125 l 1.21875,1.21875 c 0.04145,-0.02742 0.07165,-0.0404 0.125,-0.09375 l 1.625,-1.625 A 0.48185467,0.48185467 0 0 1 21.25,36.84375 c 0.542827,0.342888 1.142781,0.604614 1.78125,0.75 a 0.48185467,0.48185467 0 0 1 0.375,0.46875 l 0,2.28125 c 0,0.08729 0.01959,0.133695 0.03125,0.1875 l 1.75,0 c 0.01166,-0.0538 0.03125,-0.100206 0.03125,-0.1875 l 0,-2.28125 a 0.48185467,0.48185467 0 0 1 0.375,-0.46875 c 0.638469,-0.145386 1.238423,-0.407112 1.78125,-0.75 a 0.48185467,0.48185467 0 0 1 0.59375,0.0625 l 1.625,1.625 c 0.05335,0.05335 0.08355,0.06633 0.125,0.09375 l 1.21875,-1.21875 c -0.02742,-0.04145 -0.0404,-0.07165 -0.09375,-0.125 l -1.625,-1.625 a 0.48185467,0.48185467 0 0 1 -0.0625,-0.59375 c 0.342888,-0.542828 0.604615,-1.142783 0.75,-1.78125 a 0.48185467,0.48185467 0 0 1 0.46875,-0.375 l 2.28125,0 c 0.08729,0 0.133695,-0.01959 0.1875,-0.03125 l 0,-1.75 c -0.0538,-0.01166 -0.100204,-0.03125 -0.1875,-0.03125 l -2.28125,0 a 0.48185467,0.48185467 0 0 1 -0.46875,-0.375 c -0.145385,-0.638467 -0.407113,-1.238424 -0.75,-1.78125 a 0.48185467,0.48185467 0 0 1 0.0625,-0.59375 l 1.625,-1.625 c 0.05335,-0.05335 0.06633,-0.08355 0.09375,-0.125 L 29.71875,25.375 c -0.04145,0.02742 -0.07165,0.0404 -0.125,0.09375 l -1.625,1.625 a 0.48185467,0.48185467 0 0 1 -0.59375,0.0625 c -0.542827,-0.342889 -1.142783,-0.604616 -1.78125,-0.75 a 0.48185467,0.48185467 0 0 1 -0.375,-0.46875 l 0,-2.28125 c 0,-0.0873 -0.01959,-0.133695 -0.03125,-0.1875 l -1.75,0 z m 0.875,5.28125 c 1.791829,0 3.25,1.458172 3.25,3.25 0,1.791828 -1.458171,3.25 -3.25,3.25 -1.791827,0 -3.25,-1.458172 -3.25,-3.25 0,-1.791828 1.458173,-3.25 3.25,-3.25 z" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

216
buildtools/love-js/love-js.sh Executable file
View file

@ -0,0 +1,216 @@
#!/bin/bash
help="love-js.sh: \n
A tool for assembling love.js projects without relying on npm / node. \n\
For the full project please see https://github.com/Davidobot/love.js \n\
\n\
usage: \n\
./love-js.sh [love-file] [project-name] [opts]\n\
\n
opts:\n
-v= (--version=) Version of the Game. Will be included in file name.\n
-o= (--output-directory=) Target directory. Defaults to PWD\n
-t= (--text-colour=) Text Colour. Defaults to \"240,234,214\"\n
-c= (--canvas-colour=) Canvas Colour. Defaults to \"54,69,79\"\n
-a= (--author=) Author (Shows up on loading page).\n
-w= (--width=) Canvas Width (game width in conf). Defaults to 800\n
-h= (--height=) Canvas Height (game height in conf). Defaults to 600\n
-r (--run) Set flag if you want to run a local copy on port 8000\n
-d (--debug) Set flag for debug info\n
-h (--help) Display this text\n
\n
eg: \n\
Pack up sample.love\n
\t./love-js.sh sample.love sample\n
\t> sample-web.zip\n
\n
Pack up sample.love version 0.1.0\n
\t./love-js.sh sample-0.1.0.love sample -v=0.1.0\n
\t> sample-0.1.0-web.zip\n
\n
Pack up sample.love and set the background colour to black\n
\t./love-js.sh sample-0.1.0.love sample -v=0.1.0 -c=\"0,0,0\"\n
\t> sample-0.1.0-web.zip\n
\n
Pack up sample.love and set the author to \"Sample Name\"\n
\t./love-js.sh sample-0.1.0.love sample -a=\"Sample Name\"\n
\t> sample-web.zip"
if [ "$#" -lt "2" ]
then
echo "ERROR! love-js.sh expects at least two arguments."
echo -e $help
exit 1
fi
# use gdu on macOS, fixes 'invalid option -b' error
if [ "$(uname -s)" = "Darwin" ]; then
DU_CMD=gdu
else
DU_CMD=du
fi
love_file=$1
name=$2
## confirm that $release_dir/$name-$version.love exists
if [ ! -f $love_file ]; then
echo "love file not found!"
echo $love_file
exit 1
fi
if [ -f /proc/sys/kernel/random/uuid ]; then
uuid=$(cat /proc/sys/kernel/random/uuid)
else
uuid="2fd99e56-5455-45dd-86dd-7af724874d65"
fi
author="";
run=false;
debug=false;
gethelp=false;
width=800
height=600
release="compat"
love_version="11.5"
canvas_colour="54,69,79"
text_colour="240,234,214"
initial_memory=0
module_size=$($DU_CMD -b $love_file | awk '{print $1}')
title=$(echo $name | sed -r 's/\<./\U&/g' | sed -r 's/-/\ /g')
version=""
dash_version=""
output_dir=$(pwd)
cachemodule="true"
for i in "$@"
do
case $i in
-v=*|--version=*)
version="${i#*=}"
dash_version="-${i#*=}"
;;
-o=*|--output-directory=*)
output_dir="${i#*=}"
;;
-w=*|--width=*)
width="${i#*=}"
;;
-h=*|--height=*)
height="${i#*=}"
;;
-t=*|--text-colour=*)
text_colour="${i#*=}"
;;
-c=*|--canvas-colour=*)
canvas_colour="${i#*=}"
;;
-a=*|--author=*)
author="${i#*=}"
;;
-r|--run)
run=true
;;
-d|--debug)
debug=true
;;
-h|--help)
gethelp=true
;;
-n|--no-cache)
cachemodule="false"
;;
*)
# unknown option
;;
esac
done
page_colour=$canvas_colour
file_name=$output_dir/$name$dash_version-web
debug (){
if [ $debug = true ]
then
echo ""
echo "Debug: love-js.sh"
echo "love file: ${love_file}"
echo "output file: $file_name"
echo "author: $author"
echo "version: $version"
echo "text colour: $text_colour"
echo "canvas colour: $canvas_colour"
echo "canvas size: ${height}, ${width}"
echo "run: ${run}"
echo "use cache: $cachemodule"
fi
}
call_dir=$(pwd)
root="$(dirname "$0")"
build(){
rm -fr $file_name
mkdir -p $file_name && mkdir -p $file_name/theme
cat $root/src/index.html | \
sed "s/{{title}}/${title}/g" | \
sed "s/{{version}}/${version}/g" | \
sed "s/{{author}}/${author}/g" | \
sed "s/{{width}}/${width}/g" | \
sed "s/{{height}}/${height}/g" | \
sed "s/{{initial-memory}}/${initial_memory}/g" | \
sed "s/{{canvas-colour}}/${canvas_colour}/g" | \
sed "s/{{text-colour}}/${text_colour}/g" > \
$file_name/index.html
cat $root/src/love.css | \
sed "s/{{page-colour}}/${page_colour}/g" > \
$file_name/theme/love.css
cat $root/src/game.js | \
sed "s/{{{cachemodule}}}/${cachemodule}/g" | \
sed "s/{{{metadata}}}/{\"package_uuid\":\"${uuid}\",\"remote_package_size\":$module_size,\"files\":[{\"filename\":\"\/game.love\",\"crunched\":0,\"start\":0,\"end\":$module_size,\"audio\":false}]}/" > \
$file_name/game.js
cp $root/src/serve.py $file_name
cp $root/src/consolewrapper.js $file_name
cp $love_file $file_name/game.love
cp $root/src/love-$love_version/$release/love.js $file_name
cp $root/src/love-$love_version/$release/love.wasm $file_name
if [ $release == "release" ]; then
cp $root/src/release/love.worker.js $file_name
fi
}
clean(){
rm -rf $file_name
}
release (){
rm -fr $file_name
build
debug
zip -r -q tmp $file_name
rm -f $file_name.zip
mv tmp.zip $file_name.zip
clean
}
run (){
debug
build
cd $file_name
python3 serve.py
}
if [ $gethelp = true ]
then
echo -e $help
elif [ $run = false ]
then
release
else
run
fi

View file

@ -0,0 +1,99 @@
var newConsole = (function(oldConsole)
{
return {
log : function()
{
var data = [];
for (var _i = 0; _i < arguments.length; _i++) {
data[_i] = arguments[_i];
}
if(data.length == 1) //Start looking for api's (And dont show anything)
{
if(typeof(data[0]) == "string" && data[0].indexOf("callJavascriptFunction") != -1) //Contains function
{
// oldConsole.log(data[0]);
try
{
return eval(data[0].split("callJavascriptFunction ")[1]);
}
catch(e)
{
oldConsole.error("Something went wrong with your callJS: \nCode: " + data[0].split("callJavascriptFunction ")[1] + "\nError: '" + e.message + "'");
return null;
}
}
else
{
oldConsole.log(data[0]);
return null;
}
}
else
oldConsole.log(data[0], data.splice(1));
return null;
},
warn : function()
{
var data = [];
for (var _i = 0; _i < arguments.length; _i++) {
data[_i] = arguments[_i];
}
if(data.length == 1)
oldConsole.warn(data[0]);
else
oldConsole.warn(data[0], data.splice(1));
},
error : function()
{
var data = [];
for (var _i = 0; _i < arguments.length; _i++) {
data[_i] = arguments[_i];
}
if(data.length == 1)
oldConsole.error(data[0]);
else
oldConsole.error(data[0], data.splice(1));
},
info : function()
{
var data = [];
for (var _i = 0; _i < arguments.length; _i++) {
data[_i] = arguments[_i];
}
if(data.length == 1)
oldConsole.info(data[0]);
else
oldConsole.info(data[0], data.splice(1));
},
clear : function()
{
oldConsole.clear()
},
assert : function()
{
for (var _i = 0; _i < arguments.length; _i++) {
data[_i] = arguments[_i];
}
oldConsole.assert(data[0], data[1], data.splice(2));
},
group : function()
{
for (var _i = 0; _i < arguments.length; _i++) {
data[_i] = arguments[_i];
}
oldConsole.group(data[0], data.splice(1));
},
groupCollapsed : function()
{
for (var _i = 0; _i < arguments.length; _i++) {
data[_i] = arguments[_i];
}
oldConsole.groupCollapsed(data[0], data.splice(1));
},
groupEnd : function()
{
oldConsole.groupEnd()
}
}
}(window.console));
window.console = newConsole;

View file

@ -0,0 +1,295 @@
var Module;
var CACHEMODULE = {{{cachemodule}}};
if (typeof Module === 'undefined') Module = eval('(function() { try { return Module || {} } catch(e) { return {} } })()');
if (!Module.expectedDataFileDownloads) {
Module.expectedDataFileDownloads = 0;
Module.finishedDataFileDownloads = 0;
}
Module.expectedDataFileDownloads++;
(function() {
var loadPackage = function(metadata) {
var PACKAGE_PATH;
if (typeof window === 'object') {
PACKAGE_PATH = window['encodeURIComponent'](window.location.pathname.toString().substring(0, window.location.pathname.toString().lastIndexOf('/')) + '/');
} else if (typeof location !== 'undefined') {
// worker
PACKAGE_PATH = encodeURIComponent(location.pathname.toString().substring(0, location.pathname.toString().lastIndexOf('/')) + '/');
} else {
throw 'using preloaded data can only be done on a web page or in a web worker';
}
var PACKAGE_NAME = 'game.love';
var REMOTE_PACKAGE_BASE = 'game.love';
if (typeof Module['locateFilePackage'] === 'function' && !Module['locateFile']) {
Module['locateFile'] = Module['locateFilePackage'];
Module.printErr('warning: you defined Module.locateFilePackage, that has been renamed to Module.locateFile (using your locateFilePackage for now)');
}
var REMOTE_PACKAGE_NAME = typeof Module['locateFile'] === 'function' ?
Module['locateFile'](REMOTE_PACKAGE_BASE) :
((Module['filePackagePrefixURL'] || '') + REMOTE_PACKAGE_BASE);
var REMOTE_PACKAGE_SIZE = metadata.remote_package_size;
var PACKAGE_UUID = metadata.package_uuid;
function fetchRemotePackage(packageName, packageSize, callback, errback) {
var xhr = new XMLHttpRequest();
xhr.open('GET', packageName, true);
xhr.responseType = 'arraybuffer';
xhr.onprogress = function(event) {
var url = packageName;
var size = packageSize;
if (event.total) size = event.total;
if (event.loaded) {
if (!xhr.addedTotal) {
xhr.addedTotal = true;
if (!Module.dataFileDownloads) Module.dataFileDownloads = {};
Module.dataFileDownloads[url] = {
loaded: event.loaded,
total: size
};
} else {
Module.dataFileDownloads[url].loaded = event.loaded;
}
var total = 0;
var loaded = 0;
var num = 0;
for (var download in Module.dataFileDownloads) {
var data = Module.dataFileDownloads[download];
total += data.total;
loaded += data.loaded;
num++;
}
total = Math.ceil(total * Module.expectedDataFileDownloads/num);
if (Module['setStatus']) Module['setStatus']('Downloading data... (' + loaded + '/' + total + ')');
} else if (!Module.dataFileDownloads) {
if (Module['setStatus']) Module['setStatus']('Downloading data...');
}
};
xhr.onerror = function(event) {
throw new Error("NetworkError for: " + packageName);
}
xhr.onload = function(event) {
if (xhr.status == 200 || xhr.status == 304 || xhr.status == 206 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0
var packageData = xhr.response;
callback(packageData);
} else {
throw new Error(xhr.statusText + " : " + xhr.responseURL);
}
};
xhr.send(null);
};
function handleError(error) {
console.error('package error:', error);
};
function runWithFS() {
function assert(check, msg) {
if (!check) throw msg + new Error().stack;
}
// {{{create_file_paths}}}
function DataRequest(start, end, crunched, audio) {
this.start = start;
this.end = end;
this.crunched = crunched;
this.audio = audio;
}
DataRequest.prototype = {
requests: {},
open: function(mode, name) {
this.name = name;
this.requests[name] = this;
Module['addRunDependency']('fp ' + this.name);
},
send: function() {},
onload: function() {
var byteArray = this.byteArray.subarray(this.start, this.end);
this.finish(byteArray);
},
finish: function(byteArray) {
var that = this;
Module['FS_createDataFile'](this.name, null, byteArray, true, true, true); // canOwn this data in the filesystem, it is a slide into the heap that will never change
Module['removeRunDependency']('fp ' + that.name);
this.requests[this.name] = null;
}
};
var files = metadata.files;
for (i = 0; i < files.length; ++i) {
new DataRequest(files[i].start, files[i].end, files[i].crunched, files[i].audio).open('GET', files[i].filename);
}
var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
var IDB_RO = "readonly";
var IDB_RW = "readwrite";
var DB_NAME = "EM_PRELOAD_CACHE";
var DB_VERSION = 1;
var METADATA_STORE_NAME = 'METADATA';
var PACKAGE_STORE_NAME = 'PACKAGES';
function openDatabase(callback, errback) {
try {
var openRequest = indexedDB.open(DB_NAME, DB_VERSION);
} catch (e) {
return errback(e);
}
openRequest.onupgradeneeded = function(event) {
var db = event.target.result;
if(db.objectStoreNames.contains(PACKAGE_STORE_NAME)) {
db.deleteObjectStore(PACKAGE_STORE_NAME);
}
var packages = db.createObjectStore(PACKAGE_STORE_NAME);
if(db.objectStoreNames.contains(METADATA_STORE_NAME)) {
db.deleteObjectStore(METADATA_STORE_NAME);
}
var metadata = db.createObjectStore(METADATA_STORE_NAME);
};
openRequest.onsuccess = function(event) {
var db = event.target.result;
callback(db);
};
openRequest.onerror = function(error) {
errback(error);
};
};
/* Check if there's a cached package, and if so whether it's the latest available */
function checkCachedPackage(db, packageName, callback, errback) {
var transaction = db.transaction([METADATA_STORE_NAME], IDB_RO);
var metadata = transaction.objectStore(METADATA_STORE_NAME);
var getRequest = metadata.get("metadata/" + packageName);
getRequest.onsuccess = function(event) {
var result = event.target.result;
if (!result) {
return callback(false);
} else {
return callback(PACKAGE_UUID === result.uuid);
}
};
getRequest.onerror = function(error) {
errback(error);
};
};
function fetchCachedPackage(db, packageName, callback, errback) {
var transaction = db.transaction([PACKAGE_STORE_NAME], IDB_RO);
var packages = transaction.objectStore(PACKAGE_STORE_NAME);
var getRequest = packages.get("package/" + packageName);
getRequest.onsuccess = function(event) {
var result = event.target.result;
callback(result);
};
getRequest.onerror = function(error) {
errback(error);
};
};
function cacheRemotePackage(db, packageName, packageData, packageMeta, callback, errback) {
var transaction_packages = db.transaction([PACKAGE_STORE_NAME], IDB_RW);
var packages = transaction_packages.objectStore(PACKAGE_STORE_NAME);
var putPackageRequest = packages.put(packageData, "package/" + packageName);
putPackageRequest.onsuccess = function(event) {
var transaction_metadata = db.transaction([METADATA_STORE_NAME], IDB_RW);
var metadata = transaction_metadata.objectStore(METADATA_STORE_NAME);
var putMetadataRequest = metadata.put(packageMeta, "metadata/" + packageName);
putMetadataRequest.onsuccess = function(event) {
callback(packageData);
};
putMetadataRequest.onerror = function(error) {
errback(error);
};
};
putPackageRequest.onerror = function(error) {
errback(error);
};
};
function processPackageData(arrayBuffer) {
Module.finishedDataFileDownloads++;
assert(arrayBuffer, 'Loading data file failed.');
assert(arrayBuffer instanceof ArrayBuffer, 'bad input to processPackageData');
var byteArray = new Uint8Array(arrayBuffer);
var curr;
// copy the entire loaded file into a spot in the heap. Files will refer to slices in that. They cannot be freed though
// (we may be allocating before malloc is ready, during startup).
if (Module['SPLIT_MEMORY']) Module.printErr('warning: you should run the file packager with --no-heap-copy when SPLIT_MEMORY is used, otherwise copying into the heap may fail due to the splitting');
var ptr = Module['getMemory'](byteArray.length);
Module['HEAPU8'].set(byteArray, ptr);
DataRequest.prototype.byteArray = Module['HEAPU8'].subarray(ptr, ptr+byteArray.length);
var files = metadata.files;
for (i = 0; i < files.length; ++i) {
DataRequest.prototype.requests[files[i].filename].onload();
}
Module['removeRunDependency']('datafile_game.data');
};
Module['addRunDependency']('datafile_game.data');
if (!Module.preloadResults) Module.preloadResults = {};
function preloadFallback(error) {
console.error(error);
console.error('falling back to default preload behavior');
fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE, processPackageData, handleError);
};
openDatabase(
function(db) {
checkCachedPackage(db, PACKAGE_PATH + PACKAGE_NAME,
function(useCached) {
Module.preloadResults[PACKAGE_NAME] = {fromCache: useCached};
if (useCached && CACHEMODULE) {
console.info('loading ' + PACKAGE_NAME + ' from cache');
fetchCachedPackage(db, PACKAGE_PATH + PACKAGE_NAME, processPackageData, preloadFallback);
} else {
console.info('loading ' + PACKAGE_NAME + ' from remote');
fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE,
function(packageData) {
if(CACHEMODULE){
cacheRemotePackage(db, PACKAGE_PATH + PACKAGE_NAME, packageData, {uuid:PACKAGE_UUID}, processPackageData,
function(error) {
console.error(error);
processPackageData(packageData);
});}
else {
processPackageData(packageData);
}
}
, preloadFallback);
}
}
, preloadFallback);
}
, preloadFallback);
if (Module['setStatus']) Module['setStatus']('Downloading...');
}
if (Module['calledRun']) {
runWithFS();
} else {
if (!Module['preRun']) Module['preRun'] = [];
Module["preRun"].push(runWithFS); // FS is not initialized yet, wait for it
}
}
loadPackage({{{metadata}}});
})();

View file

@ -0,0 +1,162 @@
<!doctype html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>{{title}}</title>
<script src = "consolewrapper.js"></script>
<!-- Load custom style sheet -->
<link rel="stylesheet" type="text/css" href="theme/love.css">
</head>
<body>
<center>
<div>
<canvas id="canvas" oncontextmenu="event.preventDefault()"></canvas>
<canvas id="loadingCanvas" oncontextmenu="event.preventDefault()"
width="{{width}}" height="{{height}}"></canvas>
</div>
</center>
<script type='text/javascript'>
function goFullScreen(){
var canvas = document.getElementById("canvas");
if(canvas.requestFullScreen)
canvas.requestFullScreen();
else if(canvas.webkitRequestFullScreen)
canvas.webkitRequestFullScreen();
else if(canvas.mozRequestFullScreen)
canvas.mozRequestFullScreen();
}
function closeFullScreen() {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.webkitExitFullscreen) { /* Safari */
document.webkitExitFullscreen();
} else if (document.msExitFullscreen) { /* IE11 */
document.msExitFullscreen();
}
}
function toggleFullScreen(){
if((window.fullScreen) || /* firefox */
(window.innerWidth == screen.width && /* everything else */
window.innerHeight == screen.height)) {
closeFullScreen();
} else {
goFullScreen();
}
}
var loadingContext = document.getElementById('loadingCanvas').getContext('2d');
var complete = false;
function drawLoadingText(text, soFar, total) {
var canvas = loadingContext.canvas;
var ratio = complete ? 1 : 0;
if (soFar && total){
ratio = soFar / total
}
if (ratio == 1){
complete = true
}
//
loadingContext.fillStyle = "rgb({{canvas-colour}})";
loadingContext.fillRect(0, 0, canvas.scrollWidth, canvas.scrollHeight);
loadingContext.font = '2em arial';
loadingContext.textAlign = 'center'
//
loadingContext.fillStyle = "rgb({{text-colour}})";
loadingContext.fillText(text, canvas.scrollWidth / 2, (canvas.scrollHeight / 2) - 40);
//
loadingContext.beginPath();
loadingContext.strokeStyle = "rgb({{text-colour}})";
loadingContext.rect((canvas.scrollWidth / 2) - 200,
( canvas.scrollHeight / 2) - 20,
400,
40
);
loadingContext.stroke();
loadingContext.beginPath();
loadingContext.rect((canvas.scrollWidth / 2) - 200,
( canvas.scrollHeight / 2) - 20,
400 * ratio,
40
);
loadingContext.fill();
loadingContext.font = '4em arial';
loadingContext.fillText("{{title}}", canvas.scrollWidth / 2, canvas.scrollHeight / 4);
loadingContext.font = '2em arial';
loadingContext.fillText("{{version}}", canvas.scrollWidth / 2, (canvas.scrollHeight / 4 + 45));
loadingContext.font = '1em arial';
loadingContext.textAlign = 'left'
loadingContext.fillText("Powered By LÖVE", canvas.scrollWidth / 2 - 300, canvas.scrollHeight / 4 * 3);
loadingContext.textAlign = 'right'
loadingContext.fillText("Game By: {{author}}", canvas.scrollWidth / 2 + 300, canvas.scrollHeight / 4 * 3);
}
window.onload = function () { window.focus(); };
window.onclick = function () { window.focus(); };
window.addEventListener("keydown", function(e) {
// space and arrow keys
if([32, 37, 38, 39, 40].indexOf(e.keyCode) > -1) {
e.preventDefault();
}
}, false);
var Module = {
arguments: ["game.love","web"],
INITIAL_MEMORY: {{initial-memory}},
printErr: console.error.bind(console),
canvas: (function() {
var canvas = document.getElementById('canvas');
// As a default initial behavior, pop up an alert when webgl context is lost. To make your
// application robust, you may want to override this behavior before shipping!
// See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
canvas.addEventListener("webglcontextlost", function(e) { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false);
return canvas;
})(),
setStatus: function(text, soFar, total) {
if (text) {
drawLoadingText(text, soFar, total);
} else if (Module.remainingDependencies === 0) {
document.getElementById('loadingCanvas').style.display = 'none';
document.getElementById('canvas').style.display = 'block';
}
},
totalDependencies: 0,
remainingDependencies: 0,
monitorRunDependencies: function(left) {
this.remainingDependencies = left;
this.totalDependencies = Math.max(this.totalDependencies, left);
Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.',
this.totalDependencies-left,
this.totalDependencies);
}
};
Module.setStatus('Downloading...');
window.onerror = function(event) {
// TODO: do not warn on ok events like simulating an infinite loop or exitStatus
Module.setStatus('Exception thrown, see JavaScript console');
Module.setStatus = function(text) {
if (text) Module.printErr('[post-exception status] ' + text);
};
};
var applicationLoad = function(e) {
Love(Module);
}
</script>
<script type="text/javascript" src="game.js"></script>
<script async type="text/javascript" src="love.js" onload="applicationLoad(this)"></script>
<!-- <footer> -->
<!-- <button onclick="goFullScreen();">Go Fullscreen</button> -->
<!-- </footer> -->
</body>
</html>

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

View file

@ -0,0 +1 @@
var threadInfoStruct=0;var selfThreadId=0;var parentThreadId=0;var Module={};function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(" ");console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(" ");postMessage({cmd:"alert",text:text,threadId:selfThreadId})}var err=threadPrintErr;this.alert=threadAlert;Module["instantiateWasm"]=function(info,receiveInstance){var instance=new WebAssembly.Instance(Module["wasmModule"],info);Module["wasmModule"]=null;receiveInstance(instance);return instance.exports};this.onmessage=function(e){try{if(e.data.cmd==="load"){Module["DYNAMIC_BASE"]=e.data.DYNAMIC_BASE;Module["DYNAMICTOP_PTR"]=e.data.DYNAMICTOP_PTR;Module["wasmModule"]=e.data.wasmModule;Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;if(typeof e.data.urlOrBlob==="string"){importScripts(e.data.urlOrBlob)}else{var objectUrl=URL.createObjectURL(e.data.urlOrBlob);importScripts(objectUrl);URL.revokeObjectURL(objectUrl)}Love(Module).then(function(instance){Module=instance;postMessage({"cmd":"loaded"})})}else if(e.data.cmd==="objectTransfer"){Module["PThread"].receiveObjectTransfer(e.data)}else if(e.data.cmd==="run"){Module["__performance_now_clock_drift"]=performance.now()-e.data.time;threadInfoStruct=e.data.threadInfoStruct;Module["registerPthreadPtr"](threadInfoStruct,0,0);selfThreadId=e.data.selfThreadId;parentThreadId=e.data.parentThreadId;var max=e.data.stackBase;var top=e.data.stackBase+e.data.stackSize;Module["establishStackSpace"](top,max);Module["_emscripten_tls_init"]();Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].setThreadStatus(Module["_pthread_self"](),1);try{var result=Module["dynCall"]("ii",e.data.start_routine,[e.data.arg]);if(!Module["getNoExitRuntime"]())Module["PThread"].threadExit(result)}catch(ex){if(ex==="Canceled!"){Module["PThread"].threadCancel()}else if(ex!="unwind"){Atomics.store(Module["HEAPU32"],threadInfoStruct+4>>2,ex instanceof Module["ExitStatus"]?ex.status:-2);Atomics.store(Module["HEAPU32"],threadInfoStruct+0>>2,1);Module["_emscripten_futex_wake"](threadInfoStruct+0,2147483647);if(!(ex instanceof Module["ExitStatus"]))throw ex}}}else if(e.data.cmd==="cancel"){if(threadInfoStruct){Module["PThread"].threadCancel()}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="processThreadQueue"){if(threadInfoStruct){Module["_emscripten_current_thread_process_queued_calls"]()}}else{err("worker.js received unknown command "+e.data.cmd);err(e.data)}}catch(ex){err("worker.js onmessage() captured an uncaught exception: "+ex);if(ex.stack)err(ex.stack);throw ex}};if(typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string"){self={location:{href:__filename}};var onmessage=this.onmessage;var nodeWorkerThreads=require("worker_threads");global.Worker=nodeWorkerThreads.Worker;var parentPort=nodeWorkerThreads.parentPort;parentPort.on("message",function(data){onmessage({data:data})});var nodeFS=require("fs");var nodeRead=function(filename){return nodeFS.readFileSync(filename,"utf8")};function globalEval(x){global.require=require;global.Module=Module;eval.call(null,x)}importScripts=function(f){globalEval(nodeRead(f))};postMessage=function(msg){parentPort.postMessage(msg)};if(typeof performance==="undefined"){performance={now:function(){return Date.now()}}}}

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

View file

@ -0,0 +1 @@
var threadInfoStruct=0;var selfThreadId=0;var parentThreadId=0;var Module={};function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(" ");console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(" ");postMessage({cmd:"alert",text:text,threadId:selfThreadId})}var err=threadPrintErr;this.alert=threadAlert;Module["instantiateWasm"]=function(info,receiveInstance){var instance=new WebAssembly.Instance(Module["wasmModule"],info);Module["wasmModule"]=null;receiveInstance(instance);return instance.exports};this.onmessage=function(e){try{if(e.data.cmd==="load"){Module["DYNAMIC_BASE"]=e.data.DYNAMIC_BASE;Module["DYNAMICTOP_PTR"]=e.data.DYNAMICTOP_PTR;Module["wasmModule"]=e.data.wasmModule;Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;if(typeof e.data.urlOrBlob==="string"){importScripts(e.data.urlOrBlob)}else{var objectUrl=URL.createObjectURL(e.data.urlOrBlob);importScripts(objectUrl);URL.revokeObjectURL(objectUrl)}Love(Module).then(function(instance){Module=instance;postMessage({"cmd":"loaded"})})}else if(e.data.cmd==="objectTransfer"){Module["PThread"].receiveObjectTransfer(e.data)}else if(e.data.cmd==="run"){Module["__performance_now_clock_drift"]=performance.now()-e.data.time;threadInfoStruct=e.data.threadInfoStruct;Module["registerPthreadPtr"](threadInfoStruct,0,0);selfThreadId=e.data.selfThreadId;parentThreadId=e.data.parentThreadId;var max=e.data.stackBase;var top=e.data.stackBase+e.data.stackSize;Module["establishStackSpace"](top,max);Module["_emscripten_tls_init"]();Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].setThreadStatus(Module["_pthread_self"](),1);try{var result=Module["dynCall_ii"](e.data.start_routine,e.data.arg);if(!Module["getNoExitRuntime"]())Module["PThread"].threadExit(result)}catch(ex){if(ex==="Canceled!"){Module["PThread"].threadCancel()}else if(ex!="unwind"){Atomics.store(Module["HEAPU32"],threadInfoStruct+4>>2,ex instanceof Module["ExitStatus"]?ex.status:-2);Atomics.store(Module["HEAPU32"],threadInfoStruct+0>>2,1);Module["_emscripten_futex_wake"](threadInfoStruct+0,2147483647);if(!(ex instanceof Module["ExitStatus"]))throw ex}}}else if(e.data.cmd==="cancel"){if(threadInfoStruct){Module["PThread"].threadCancel()}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="processThreadQueue"){if(threadInfoStruct){Module["_emscripten_current_thread_process_queued_calls"]()}}else{err("worker.js received unknown command "+e.data.cmd);err(e.data)}}catch(ex){err("worker.js onmessage() captured an uncaught exception: "+ex);if(ex.stack)err(ex.stack);throw ex}};if(typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string"){self={location:{href:__filename}};var onmessage=this.onmessage;var nodeWorkerThreads=require("worker_threads");global.Worker=nodeWorkerThreads.Worker;var parentPort=nodeWorkerThreads.parentPort;parentPort.on("message",function(data){onmessage({data:data})});var nodeFS=require("fs");var nodeRead=function(filename){return nodeFS.readFileSync(filename,"utf8")};function globalEval(x){global.require=require;global.Module=Module;eval.call(null,x)}importScripts=function(f){globalEval(nodeRead(f))};postMessage=function(msg){parentPort.postMessage(msg)};if(typeof performance==="undefined"){performance={now:function(){return Date.now()}}}}

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

View file

@ -0,0 +1 @@
"use strict";var Module={};var ENVIRONMENT_IS_NODE=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string";if(ENVIRONMENT_IS_NODE){var nodeWorkerThreads=require("worker_threads");var parentPort=nodeWorkerThreads.parentPort;parentPort.on("message",data=>onmessage({data:data}));var fs=require("fs");var vm=require("vm");Object.assign(global,{self:global,require:require,Module:Module,location:{href:__filename},Worker:nodeWorkerThreads.Worker,importScripts:f=>vm.runInThisContext(fs.readFileSync(f,"utf8"),{filename:f}),postMessage:msg=>parentPort.postMessage(msg),performance:global.performance||{now:Date.now}})}var initializedJS=false;function threadPrintErr(...args){var text=args.join(" ");if(ENVIRONMENT_IS_NODE){fs.writeSync(2,text+"\n");return}console.error(text)}function threadAlert(...args){var text=args.join(" ");postMessage({cmd:"alert",text:text,threadId:Module["_pthread_self"]()})}var err=threadPrintErr;self.alert=threadAlert;Module["instantiateWasm"]=(info,receiveInstance)=>{var module=Module["wasmModule"];Module["wasmModule"]=null;var instance=new WebAssembly.Instance(module,info);return receiveInstance(instance,module)};self.onunhandledrejection=e=>{throw e.reason||e};function handleMessage(e){try{if(e.data.cmd==="load"){let messageQueue=[];self.onmessage=e=>messageQueue.push(e);self.startWorker=instance=>{Module=instance;postMessage({"cmd":"loaded"});for(let msg of messageQueue){handleMessage(msg)}self.onmessage=handleMessage};Module["wasmModule"]=e.data.wasmModule;for(const handler of e.data.handlers){Module[handler]=(...args)=>{postMessage({cmd:"callHandler",handler:handler,args:args})}}Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;if(typeof e.data.urlOrBlob=="string"){importScripts(e.data.urlOrBlob)}else{var objectUrl=URL.createObjectURL(e.data.urlOrBlob);importScripts(objectUrl);URL.revokeObjectURL(objectUrl)}Love(Module)}else if(e.data.cmd==="run"){Module["__emscripten_thread_init"](e.data.pthread_ptr,0,0,1);Module["__emscripten_thread_mailbox_await"](e.data.pthread_ptr);Module["establishStackSpace"]();Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].threadInitTLS();if(!initializedJS){initializedJS=true}try{Module["invokeEntryPoint"](e.data.start_routine,e.data.arg)}catch(ex){if(ex!="unwind"){throw ex}}}else if(e.data.cmd==="cancel"){if(Module["_pthread_self"]()){Module["__emscripten_thread_exit"](-1)}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="checkMailbox"){if(initializedJS){Module["checkMailbox"]()}}else if(e.data.cmd){err(`worker.js received unknown command ${e.data.cmd}`);err(e.data)}}catch(ex){Module["__emscripten_thread_crashed"]?.();throw ex}}self.onmessage=handleMessage;

View file

@ -0,0 +1,48 @@
* {
box-sizing: border-box;
}
h1 {
font-family: arial;
color: rgb( 11, 86, 117 );
}
body {
background-repeat: no-repeat;
font-family: arial;
margin: 0;
padding: none;
background-color: rgb({{page-colour}});
color: rgb( 28, 78, 104 );
}
footer {
font-family: arial;
font-size: 12px;
padding-left: 10px;
padding-bottom: 10px;
position:absolute;
bottom: 0;
width: 100%;
}
/* Links */
a {
text-decoration: none;
}
a:link {
color: rgb( 233, 73, 154 );
}
a:visited {
color: rgb( 110, 30, 71 );
}
a:hover {
color: rgb( 252, 207, 230 );
}
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
#canvas {
padding-right: 0;
display: none;
border: 0px none;
}

View file

@ -0,0 +1,22 @@
#!/usr/bin/env python
# Attribution: https://stackoverflow.com/questions/21956683/enable-access-control-on-simple-http-server
try:
# Python 3
from http.server import HTTPServer, SimpleHTTPRequestHandler, test as test_orig
import sys
def test (*args):
test_orig(*args, port=int(sys.argv[1]) if len(sys.argv) > 1 else 8000)
except ImportError: # Python 2
from BaseHTTPServer import HTTPServer, test
from SimpleHTTPServer import SimpleHTTPRequestHandler
class CORSRequestHandler (SimpleHTTPRequestHandler):
def end_headers (self):
self.send_header('Cross-Origin-Opener-Policy', 'same-origin')
self.send_header('Cross-Origin-Embedder-Policy', 'require-corp')
SimpleHTTPRequestHandler.end_headers(self)
if __name__ == '__main__':
test(CORSRequestHandler, HTTPServer)

1053
buildtools/love-release.sh Executable file

File diff suppressed because it is too large Load diff